Skip to content

Commit

Permalink
major rewrite.
Browse files Browse the repository at this point in the history
  • Loading branch information
vitaly-t committed Jul 15, 2017
1 parent 236e765 commit 7b57525
Show file tree
Hide file tree
Showing 6 changed files with 142 additions and 40 deletions.
27 changes: 23 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,26 +60,45 @@ var parse = require('connection-string');
var obj = parse('my-server:12345');
```

or as a class:

```js
var ConnectionString = require('connection-string');
var obj = new ConnectionString('my-server:12345');
```

* **Browsers**

```html
<script src="./connection-string/src"></script>

<script>
var obj = parseConnectionString('my-server:12345');
var obj = new ConnectionString('my-server:12345');
</script>
```

* **TypeScript**

```ts
import * as parse from 'connection-string'
import {ConnectionOptions} from 'connection-string'
import {ConnectionString} from 'connection-string'

var a: ConnectionOptions = parse('my-server:12345');
var a = new ConnectionString('my-server:12345');
```

For details and examples see the [WiKi Pages].

## API

After parsing you always get a class instance with all the properties, plus method `build`,
which can construct a new the connection string from the current properties.

Example:

```js
var a = new ConnectionString('abc://');
a.host = a.host || 'localhost'; // set a default host
a.build(); //=> 'abc://localhost'
```

[WiKi Pages]:https://github.com/vitaly-t/connection-string/wiki
[Optional Format]:https://github.com/vitaly-t/connection-string/wiki#optional-format
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "connection-string",
"version": "0.1.6",
"version": "0.2.0",
"description": "URL Connection String Parser.",
"main": "src/index.js",
"typings": "src/index.d.ts",
Expand Down
27 changes: 12 additions & 15 deletions src/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
declare namespace ConnectionString {
export class ConnectionString {
constructor(cd: string)

interface ConnectionOptions {
protocol: string
user: string
password: string
host: string
hostname: string
port: number
segments: string[]
params: { [name: string]: string }
}
}

declare function ConnectionString(cs: string): ConnectionString.ConnectionOptions;
protocol: string;
user: string;
password: string;
host: string;
hostname: string;
port: number;
segments: string[];
params: { [name: string]: string };

export = ConnectionString;
build(): string;
}
69 changes: 54 additions & 15 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
(function (window) {
'use strict';

function parseConnectionString(cs) {
function ConnectionString(cs) {

if (!(this instanceof ConnectionString)) {
return new ConnectionString(cs);
}

if (typeof cs !== 'string') {
throw new TypeError('Invalid connection string!');
Expand All @@ -16,14 +20,12 @@
throw new Error('Invalid URL character at position ' + idx);
}

var result = {};

// extract the protocol:
var m = cs.match(/^[\w-_.+!*'()$%]*:\/\//);
if (m) {
var protocol = decodeURI(m[0].replace(/:\/\//, ''));
if (protocol) {
result.protocol = protocol;
this.protocol = protocol;
}
cs = cs.substr(m[0].length);
}
Expand All @@ -32,10 +34,10 @@
m = cs.match(/^([\w-_.+!*'()$%]*):?([\w-_.+!*'()$%]*)@/);
if (m) {
if (m[1]) {
result.user = decodeURI(m[1]);
this.user = decodeURI(m[1]);
}
if (m[2]) {
result.password = decodeURI(m[2]);
this.password = decodeURI(m[2]);
}
cs = cs.substr(m[0].length);
}
Expand All @@ -52,13 +54,13 @@
}
if (m) {
if (m[1]) {
result.host = m[1];
this.host = m[1];
}
if (m[2]) {
result.hostname = m[2];
this.hostname = m[2];
}
if (m[3]) {
result.port = parseInt(m[3]);
this.port = parseInt(m[3]);
}
cs = cs.substr(m[0].length);
}
Expand All @@ -67,7 +69,7 @@
// extract segments:
m = cs.match(/\/([\w-_.+!*'()$%]+)/g);
if (m) {
result.segments = m.map(function (s) {
this.segments = m.map(function (s) {
return decodeURI(s.substr(1));
});
}
Expand All @@ -78,22 +80,59 @@
cs = cs.substr(idx + 1);
m = cs.match(/([\w-_.+!*'()$%]+)=([\w-_.+!*'()$%]+)/g);
if (m) {
result.params = {};
var params = {};
m.forEach(function (s) {
var a = s.split('=');
result.params[decodeURI(a[0])] = decodeURI(a[1]);
params[decodeURI(a[0])] = decodeURI(a[1]);
});
this.params = params;
}
}
}

return result;
function build() {
var s = '';
if (this.protocol) {
s += encodeURI(this.protocol) + '://';
}
if (this.user) {
s += encodeURI(this.user);
if (this.password) {
s += ':' + encodeURI(this.password);
}
s += '@';
} else {
if (this.password) {
s += ':' + encodeURI(this.password) + '@';
}
}
if (this.host) {
s += this.host;
}
if (Array.isArray(this.segments) && this.segments.length) {
this.segments.forEach(function (seg) {
s += '/' + encodeURI(seg);
});
}
if (this.params) {
var params = [];
for (var a in this.params) {
params.push(encodeURI(a) + '=' + encodeURI(this.params[a]));
}
if (params.length) {
s += '?' + params.join('&');
}
}
return s;
}

Object.defineProperty(ConnectionString.prototype, 'build', {value: build});

/* istanbul ignore else */
if (typeof module === 'object' && module && typeof module.exports === 'object') {
module.exports = parseConnectionString;
module.exports = ConnectionString;
}
else {
window.parseConnectionString = parseConnectionString;
window.ConnectionString = ConnectionString;
}
})(this);
7 changes: 4 additions & 3 deletions test/main.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import * as parse from '../src'
import {ConnectionOptions} from '../src'
import {ConnectionString} from '../src'

var a: ConnectionOptions = parse('protocol://');
var a = new ConnectionString('protocol://');

if ('protocol' in a) {
var protocol = a.protocol;
}

var segment1: string = a.segments[0];
var param1: string = a.params['first'];

var cs = a.build();
50 changes: 48 additions & 2 deletions test/mainSpec.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
'use strict';

var parse = require('../src');
var ConnectionString = require('../src');

function parse(cs) {
return new ConnectionString(cs);
}

describe('init', function () {
it('must throw on a non-string', function () {
Expand All @@ -20,10 +24,13 @@ describe('init', function () {
parse('ab\tc');
}).toThrow(new Error('Invalid URL character at position 2'));
});

it('must allow an empty string', function () {
expect(parse('')).toEqual({});
});
it('must support function-style calls', function () {
// eslint-disable-next-line
expect(ConnectionString('abc://')).toEqual({protocol: 'abc'});
});
});

describe('protocol', function () {
Expand Down Expand Up @@ -252,3 +259,42 @@ describe('complex', function () {
expect(parse(':123/one')).toEqual({host: ':123', port: 123, segments: ['one']});
});
});

describe('build', function () {
it('must encode protocol', function () {
expect(parse('abc%20123://').build()).toBe('abc%20123://');
});
it('must encode user', function () {
expect(parse('user%20123@').build()).toBe('user%20123@');
});
it('must encode password', function () {
expect(parse(':pass%20123@').build()).toBe(':pass%20123@');
});
it('must support user + password', function () {
expect(parse('user:pass@').build()).toBe('user:pass@');
});
it('must support solo hostname', function () {
expect(parse('server').build()).toBe('server');
});
it('must support hostname + port', function () {
expect(parse('server:123').build()).toBe('server:123');
});
it('must encode segments', function () {
expect(parse('/a%20b').build()).toBe('/a%20b');
expect(parse('/a/b%20/c').build()).toBe('/a/b%20/c');
});
it('must ignore empty segment list', function () {
var a = parse('');
a.segments = [];
expect(a.build()).toBe('');
});
it('must encode params', function () {
expect(parse('?a%20b=1').build()).toBe('?a%20b=1');
expect(parse('?a=1&b%20=2').build()).toBe('?a=1&b%20=2');
});
it('must ignore empty parameter list', function () {
var a = parse('');
a.params = {};
expect(a.build()).toBe('');
});
});

0 comments on commit 7b57525

Please sign in to comment.