Skip to content
Vitaly Tomilov edited this page Aug 28, 2020 · 118 revisions

How to use special symbols for user name or password?

User name, password, path or parameter names - all need to be URL-encoded. When in doubt, just run this:

console.log(encodeURIComponent('my-password'));

Most popular special symbols that need to be encoded:

  • # = %23
  • @ = %40
  • % = %25
  • ^ = %5E
  • ? = %3F
  • + = %2B
  • = = %3D
  • , = %2C
  • / = %2F
  • < = %3C
  • > = `%3E

Other special symbols, such as ~ or $, for example, can be, but do not need to be encoded.

Is there a simpler way to access the first host name + port?

The library supports hostname, port + type for that, as documented within Virtual Properties.

// when supporting multiple hosts:
const host = cs.hosts?.[0].name;
const port = cs.hosts?.[0].port;
const type = cs.hosts?.[0].type;

// when supporting only one host, the above code can be simplified to this:
const host = cs.hostname; // = cs.hosts?.[0].name;
const port = cs.port; // = cs.hosts?.[0].port;
const type = cs.type; // = cs.hosts?.[0].type;

How to get the full host name properly?

When hosts is set, each element in the array is an object that has method toString, to generate the full host name:

const cs = new ConnectionString('test://first,second:123');

const firstHost = cs.hosts?.[0].toString(); // = first = cs.host

const secondHost = cs.hosts?.[1].toString(); // = second:123

And for the first host, there is even simpler approach - property host.

Do not use something like ${cs.hostname}:${cs.port}, which would incorrectly produce first:undefined.

See also the encoding options that method toString can accept.

How to use a file path in URL directly?

If your protocol allows an alternative syntax of a file path, in place of regular connection details, the recommended approach is to make the distinction via an optional extension (sub-protocol), like -file, for example, and then use the path section of the URL for the file path:

const cs = new ConnectionString('protocol-file:///some/file/path/file-name.txt');

// cs.protocol = 'protocol-file'

const [protocol, ext] = cs.protocol?.split('-') ?? []; // split protocol from extension

if(ext === 'file') {
    console.log(cs.path?.join('/'));
    //=> some/file/path/file-name.txt
}

And it will work the same for a relative path:

const cs = new ConnectionString('protocol-file:///../..some/file/path/file-name.txt');

console.log(cs.path?.join('/'));
//=> ../..some/file/path/file-name.txt
  • Protocol can also contain +, : and . as alternative separators.
  • Any space in the file path must be encoded either as %20 or as +.

How can I specify a Unix-socket host?

Any host name that either ends with .sock or contains /, after decoding, is recognized as a Unix socket, with the host's type property set to socket after parsing.

Note that in a socket name inside URL, every symbol / must be encoded as %2F.

// cs - our ConnectionString

// check if the first host is a Unix socket:
const isSocket = cs.type === HostType.socket; // checking type of the first host
// full syntax:
// const isSocket = cs.hosts?.[0].type === HostType.socket;

// or you can compare it to a string:
const isSocket = cs.type === 'socket';
// full syntax:
// const isSocket = cs.hosts?.[0].type === 'socket';

How to access user name + password as URL-encoded?

Q: The type of server that I'm using, natively supports URL-encoded user and password, so I don't want those decoded, I want them exactly as they are in the connection string. How can I do this?

A: URL encoding/decoding is a symmetric operation, i.e. you can simply re-encode those parameters when needed, using the global encodeURIComponent function:

const cs = new ConnectionString(/* your connection string here */);

const encodedUser = cs.user ? encodeURIComponent(cs.user) : '';
const encodedPassword = cs.password ? encodeURIComponent(cs.password) : '';

Alternatively, you can double-encode those, and then no extra work will be needed.


Can I pass in a complex type as a URL parameter?

Yes, you can pass in anything, but after parsing such value will be a string, so you need to apply JSON.parse to it, as shown in the example below.

import {ConnectionString} from 'connection-string';

const s1 = new ConnectionString('test://', {
    params: {
        // passing in a complex value:
        value: [123, true, 'hello', {hi: 'there'}]
    }
});

const connection = s1.toString();
//=> test://?value=%5B123%2Ctrue%2C%22hello%22%2C%7B%22hi%22%3A%22there%22%7D%5D

// the reverse operation:
const s2 = new ConnectionString(connection);

JSON.parse(s2.params?.value);
//=> [123, true, 'hello', {hi: 'there'}]
Clone this wiki locally