1 var __extends = (this && this.__extends) || (function () {
2 var extendStatics = function (d, b) {
3 extendStatics = Object.setPrototypeOf ||
4 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
5 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
6 return extendStatics(d, b);
8 return function (d, b) {
10 function __() { this.constructor = d; }
11 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
15 if (typeof module === "object" && typeof module.exports === "object") {
16 var v = factory(require, exports);
17 if (v !== undefined) module.exports = v;
19 else if (typeof define === "function" && define.amd) {
20 define(["require", "exports"], factory);
22 })(function (require, exports) {
23 /*---------------------------------------------------------------------------------------------
24 * Copyright (c) Microsoft Corporation. All rights reserved.
25 * Licensed under the MIT License. See License.txt in the project root for license information.
26 *--------------------------------------------------------------------------------------------*/
29 Object.defineProperty(exports, "__esModule", { value: true });
31 if (typeof process === 'object') {
32 isWindows = process.platform === 'win32';
34 else if (typeof navigator === 'object') {
35 var userAgent = navigator.userAgent;
36 isWindows = userAgent.indexOf('Windows') >= 0;
38 function isHighSurrogate(charCode) {
39 return (0xD800 <= charCode && charCode <= 0xDBFF);
41 function isLowSurrogate(charCode) {
42 return (0xDC00 <= charCode && charCode <= 0xDFFF);
44 function isLowerAsciiHex(code) {
45 return code >= 97 /* a */ && code <= 102 /* f */;
47 function isLowerAsciiLetter(code) {
48 return code >= 97 /* a */ && code <= 122 /* z */;
50 function isUpperAsciiLetter(code) {
51 return code >= 65 /* A */ && code <= 90 /* Z */;
53 function isAsciiLetter(code) {
54 return isLowerAsciiLetter(code) || isUpperAsciiLetter(code);
57 var _schemePattern = /^\w[\w\d+.-]*$/;
58 var _singleSlashStart = /^\//;
59 var _doubleSlashStart = /^\/\//;
60 function _validateUri(ret, _strict) {
61 // scheme, must be set
62 if (!ret.scheme && _strict) {
63 throw new Error("[UriError]: Scheme is missing: {scheme: \"\", authority: \"" + ret.authority + "\", path: \"" + ret.path + "\", query: \"" + ret.query + "\", fragment: \"" + ret.fragment + "\"}");
65 // scheme, https://tools.ietf.org/html/rfc3986#section-3.1
66 // ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
67 if (ret.scheme && !_schemePattern.test(ret.scheme)) {
68 throw new Error('[UriError]: Scheme contains illegal characters.');
70 // path, http://tools.ietf.org/html/rfc3986#section-3.3
71 // If a URI contains an authority component, then the path component
72 // must either be empty or begin with a slash ("/") character. If a URI
73 // does not contain an authority component, then the path cannot begin
74 // with two slash characters ("//").
77 if (!_singleSlashStart.test(ret.path)) {
78 throw new Error('[UriError]: If a URI contains an authority component, then the path component must either be empty or begin with a slash ("/") character');
82 if (_doubleSlashStart.test(ret.path)) {
83 throw new Error('[UriError]: If a URI does not contain an authority component, then the path cannot begin with two slash characters ("//")');
88 // for a while we allowed uris *without* schemes and this is the migration
89 // for them, e.g. an uri without scheme and without strict-mode warns and falls
90 // back to the file-scheme. that should cause the least carnage and still be a
92 function _schemeFix(scheme, _strict) {
93 if (!scheme && !_strict) {
98 // implements a bit of https://tools.ietf.org/html/rfc3986#section-5
99 function _referenceResolution(scheme, path) {
100 // the slash-character is our 'default base' as we don't
101 // support constructing URIs relative to other URIs. This
102 // also means that we alter and potentially break paths.
103 // see https://tools.ietf.org/html/rfc3986#section-5.1.4
111 else if (path[0] !== _slash) {
112 path = _slash + path;
120 var _regexp = /^(([^:/?#]+?):)?(\/\/([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?/;
122 * Uniform Resource Identifier (URI) http://tools.ietf.org/html/rfc3986.
123 * This class is a simple parser which creates the basic component parts
124 * (http://tools.ietf.org/html/rfc3986#section-3) with minimal validation
128 * foo://example.com:8042/over/there?name=ferret#nose
129 * \_/ \______________/\_________/ \_________/ \__/
131 * scheme authority path query fragment
132 * | _____________________|__
134 * urn:example:animal:ferret:nose
137 var URI = /** @class */ (function () {
141 function URI(schemeOrData, authority, path, query, fragment, _strict) {
142 if (_strict === void 0) { _strict = false; }
143 if (typeof schemeOrData === 'object') {
144 this.scheme = schemeOrData.scheme || _empty;
145 this.authority = schemeOrData.authority || _empty;
146 this.path = schemeOrData.path || _empty;
147 this.query = schemeOrData.query || _empty;
148 this.fragment = schemeOrData.fragment || _empty;
149 // no validation because it's this URI
150 // that creates uri components.
151 // _validateUri(this);
154 this.scheme = _schemeFix(schemeOrData, _strict);
155 this.authority = authority || _empty;
156 this.path = _referenceResolution(this.scheme, path || _empty);
157 this.query = query || _empty;
158 this.fragment = fragment || _empty;
159 _validateUri(this, _strict);
162 URI.isUri = function (thing) {
163 if (thing instanceof URI) {
169 return typeof thing.authority === 'string'
170 && typeof thing.fragment === 'string'
171 && typeof thing.path === 'string'
172 && typeof thing.query === 'string'
173 && typeof thing.scheme === 'string'
174 && typeof thing.fsPath === 'function'
175 && typeof thing.with === 'function'
176 && typeof thing.toString === 'function';
178 Object.defineProperty(URI.prototype, "fsPath", {
179 // ---- filesystem path -----------------------
181 * Returns a string representing the corresponding file system path of this URI.
182 * Will handle UNC paths, normalizes windows drive letters to lower-case, and uses the
183 * platform specific path separator.
185 * * Will *not* validate the path for invalid characters and semantics.
186 * * Will *not* look at the scheme of this URI.
187 * * The result shall *not* be used for display purposes but for accessing a file on disk.
190 * The *difference* to `URI#path` is the use of the platform specific separator and the handling
191 * of UNC paths. See the below sample of a file-uri with an authority (UNC path).
194 const u = URI.parse('file://server/c$/folder/file.txt')
195 u.authority === 'server'
196 u.path === '/shares/c$/file.txt'
197 u.fsPath === '\\server\c$\folder\file.txt'
200 * Using `URI#path` to read a file (using fs-apis) would not be enough because parts of the path,
201 * namely the server name, would be missing. Therefore `URI#fsPath` exists - it's sugar to ease working
202 * with URIs that represent files on disk (`file` scheme).
205 // if (this.scheme !== 'file') {
206 // console.warn(`[UriError] calling fsPath with scheme ${this.scheme}`);
208 return uriToFsPath(this, false);
213 // ---- modify to new -------------------------
214 URI.prototype.with = function (change) {
218 var scheme = change.scheme, authority = change.authority, path = change.path, query = change.query, fragment = change.fragment;
219 if (scheme === undefined) {
220 scheme = this.scheme;
222 else if (scheme === null) {
225 if (authority === undefined) {
226 authority = this.authority;
228 else if (authority === null) {
231 if (path === undefined) {
234 else if (path === null) {
237 if (query === undefined) {
240 else if (query === null) {
243 if (fragment === undefined) {
244 fragment = this.fragment;
246 else if (fragment === null) {
249 if (scheme === this.scheme
250 && authority === this.authority
251 && path === this.path
252 && query === this.query
253 && fragment === this.fragment) {
256 return new _URI(scheme, authority, path, query, fragment);
258 // ---- parse & validate ------------------------
260 * Creates a new URI from a string, e.g. `http://www.msft.com/some/path`,
261 * `file:///usr/home`, or `scheme:with/path`.
263 * @param value A string which represents an URI (see `URI#toString`).
265 URI.parse = function (value, _strict) {
266 if (_strict === void 0) { _strict = false; }
267 var match = _regexp.exec(value);
269 return new _URI(_empty, _empty, _empty, _empty, _empty);
271 return new _URI(match[2] || _empty, percentDecode(match[4] || _empty), percentDecode(match[5] || _empty), percentDecode(match[7] || _empty), percentDecode(match[9] || _empty), _strict);
274 * Creates a new URI from a file system path, e.g. `c:\my\files`,
275 * `/usr/home`, or `\\server\share\some\path`.
277 * The *difference* between `URI#parse` and `URI#file` is that the latter treats the argument
278 * as path, not as stringified-uri. E.g. `URI.file(path)` is **not the same as**
279 * `URI.parse('file://' + path)` because the path might contain characters that are
280 * interpreted (# and ?). See the following sample:
282 const good = URI.file('/coding/c#/project1');
283 good.scheme === 'file';
284 good.path === '/coding/c#/project1';
285 good.fragment === '';
286 const bad = URI.parse('file://' + '/coding/c#/project1');
287 bad.scheme === 'file';
288 bad.path === '/coding/c'; // path is now broken
289 bad.fragment === '/project1';
292 * @param path A file system path (see `URI#fsPath`)
294 URI.file = function (path) {
295 var authority = _empty;
296 // normalize to fwd-slashes on windows,
297 // on other systems bwd-slashes are valid
298 // filename character, eg /f\oo/ba\r.txt
300 path = path.replace(/\\/g, _slash);
302 // check for authority as used in UNC shares
303 // or use the path as given
304 if (path[0] === _slash && path[1] === _slash) {
305 var idx = path.indexOf(_slash, 2);
307 authority = path.substring(2);
311 authority = path.substring(2, idx);
312 path = path.substring(idx) || _slash;
315 return new _URI('file', authority, path, _empty, _empty);
317 URI.from = function (components) {
318 return new _URI(components.scheme, components.authority, components.path, components.query, components.fragment);
321 // * Join a URI path with path fragments and normalizes the resulting path.
323 // * @param uri The input URI.
324 // * @param pathFragment The path fragment to add to the URI path.
325 // * @returns The resulting URI.
327 // static joinPath(uri: URI, ...pathFragment: string[]): URI {
329 // throw new Error(`[UriError]: cannot call joinPaths on URI without path`);
331 // let newPath: string;
332 // if (isWindows && uri.scheme === 'file') {
333 // newPath = URI.file(paths.win32.join(uriToFsPath(uri, true), ...pathFragment)).path;
335 // newPath = paths.posix.join(uri.path, ...pathFragment);
337 // return uri.with({ path: newPath });
339 // ---- printing/externalize ---------------------------
341 * Creates a string representation for this URI. It's guaranteed that calling
342 * `URI.parse` with the result of this function creates an URI which is equal
345 * * The result shall *not* be used for display purposes but for externalization or transport.
346 * * The result will be encoded using the percentage encoding and encoding happens mostly
347 * ignore the scheme-specific encoding rules.
349 * @param skipEncoding Do not encode the result, default is `false`
351 URI.prototype.toString = function (skipEncoding) {
352 if (skipEncoding === void 0) { skipEncoding = false; }
353 return _asFormatted(this, skipEncoding);
355 URI.prototype.toJSON = function () {
358 URI.revive = function (data) {
362 else if (data instanceof URI) {
366 var result = new _URI(data);
367 result._formatted = data.external;
368 result._fsPath = data._sep === _pathSepMarker ? data.fsPath : null;
375 var _pathSepMarker = isWindows ? 1 : undefined;
376 // eslint-disable-next-line @typescript-eslint/class-name-casing
377 var _URI = /** @class */ (function (_super) {
378 __extends(_URI, _super);
380 var _this = _super !== null && _super.apply(this, arguments) || this;
381 _this._formatted = null;
382 _this._fsPath = null;
385 Object.defineProperty(_URI.prototype, "fsPath", {
388 this._fsPath = uriToFsPath(this, false);
395 _URI.prototype.toString = function (skipEncoding) {
396 if (skipEncoding === void 0) { skipEncoding = false; }
398 if (!this._formatted) {
399 this._formatted = _asFormatted(this, false);
401 return this._formatted;
404 // we don't cache that
405 return _asFormatted(this, true);
408 _URI.prototype.toJSON = function () {
414 res.fsPath = this._fsPath;
415 res._sep = _pathSepMarker;
417 if (this._formatted) {
418 res.external = this._formatted;
422 res.path = this.path;
425 res.scheme = this.scheme;
427 if (this.authority) {
428 res.authority = this.authority;
431 res.query = this.query;
434 res.fragment = this.fragment;
440 // reserved characters: https://tools.ietf.org/html/rfc3986#section-2.2
441 var encodeTable = (_a = {},
442 _a[58 /* Colon */] = '%3A',
443 _a[47 /* Slash */] = '%2F',
444 _a[63 /* QuestionMark */] = '%3F',
445 _a[35 /* Hash */] = '%23',
446 _a[91 /* OpenSquareBracket */] = '%5B',
447 _a[93 /* CloseSquareBracket */] = '%5D',
448 _a[64 /* AtSign */] = '%40',
449 _a[33 /* ExclamationMark */] = '%21',
450 _a[36 /* DollarSign */] = '%24',
451 _a[38 /* Ampersand */] = '%26',
452 _a[39 /* SingleQuote */] = '%27',
453 _a[40 /* OpenParen */] = '%28',
454 _a[41 /* CloseParen */] = '%29',
455 _a[42 /* Asterisk */] = '%2A',
456 _a[43 /* Plus */] = '%2B',
457 _a[44 /* Comma */] = '%2C',
458 _a[59 /* Semicolon */] = '%3B',
459 _a[61 /* Equals */] = '%3D',
460 _a[32 /* Space */] = '%20',
462 function encodeURIComponentFast(uriComponent, allowSlash) {
464 var nativeEncodePos = -1;
465 for (var pos = 0; pos < uriComponent.length; pos++) {
466 var code = uriComponent.charCodeAt(pos);
467 // unreserved characters: https://tools.ietf.org/html/rfc3986#section-2.3
468 if ((code >= 97 /* a */ && code <= 122 /* z */)
469 || (code >= 65 /* A */ && code <= 90 /* Z */)
470 || (code >= 48 /* Digit0 */ && code <= 57 /* Digit9 */)
471 || code === 45 /* Dash */
472 || code === 46 /* Period */
473 || code === 95 /* Underline */
474 || code === 126 /* Tilde */
475 || (allowSlash && code === 47 /* Slash */)) {
476 // check if we are delaying native encode
477 if (nativeEncodePos !== -1) {
478 res += encodeURIComponent(uriComponent.substring(nativeEncodePos, pos));
479 nativeEncodePos = -1;
481 // check if we write into a new string (by default we try to return the param)
482 if (res !== undefined) {
483 res += uriComponent.charAt(pos);
487 // encoding needed, we need to allocate a new string
488 if (res === undefined) {
489 res = uriComponent.substr(0, pos);
491 // check with default table first
492 var escaped = encodeTable[code];
493 if (escaped !== undefined) {
494 // check if we are delaying native encode
495 if (nativeEncodePos !== -1) {
496 res += encodeURIComponent(uriComponent.substring(nativeEncodePos, pos));
497 nativeEncodePos = -1;
499 // append escaped variant to result
502 else if (nativeEncodePos === -1) {
503 // use native encode only when needed
504 nativeEncodePos = pos;
508 if (nativeEncodePos !== -1) {
509 res += encodeURIComponent(uriComponent.substring(nativeEncodePos));
511 return res !== undefined ? res : uriComponent;
513 function encodeURIComponentMinimal(path) {
515 for (var pos = 0; pos < path.length; pos++) {
516 var code = path.charCodeAt(pos);
517 if (code === 35 /* Hash */ || code === 63 /* QuestionMark */) {
518 if (res === undefined) {
519 res = path.substr(0, pos);
521 res += encodeTable[code];
524 if (res !== undefined) {
529 return res !== undefined ? res : path;
532 * Compute `fsPath` for the given uri
534 function uriToFsPath(uri, keepDriveLetterCasing) {
536 if (uri.authority && uri.path.length > 1 && uri.scheme === 'file') {
537 // unc path: file://shares/c$/far/boo
538 value = "//" + uri.authority + uri.path;
540 else if (uri.path.charCodeAt(0) === 47 /* Slash */
541 && (uri.path.charCodeAt(1) >= 65 /* A */ && uri.path.charCodeAt(1) <= 90 /* Z */ || uri.path.charCodeAt(1) >= 97 /* a */ && uri.path.charCodeAt(1) <= 122 /* z */)
542 && uri.path.charCodeAt(2) === 58 /* Colon */) {
543 if (!keepDriveLetterCasing) {
544 // windows drive letter: file:///c:/far/boo
545 value = uri.path[1].toLowerCase() + uri.path.substr(2);
548 value = uri.path.substr(1);
556 value = value.replace(/\//g, '\\');
560 exports.uriToFsPath = uriToFsPath;
562 * Create the external version of a uri
564 function _asFormatted(uri, skipEncoding) {
565 var encoder = !skipEncoding
566 ? encodeURIComponentFast
567 : encodeURIComponentMinimal;
569 var scheme = uri.scheme, authority = uri.authority, path = uri.path, query = uri.query, fragment = uri.fragment;
574 if (authority || scheme === 'file') {
579 var idx = authority.indexOf('@');
582 var userinfo = authority.substr(0, idx);
583 authority = authority.substr(idx + 1);
584 idx = userinfo.indexOf(':');
586 res += encoder(userinfo, false);
589 // <user>:<pass>@<auth>
590 res += encoder(userinfo.substr(0, idx), false);
592 res += encoder(userinfo.substr(idx + 1), false);
596 authority = authority.toLowerCase();
597 idx = authority.indexOf(':');
599 res += encoder(authority, false);
603 res += encoder(authority.substr(0, idx), false);
604 res += authority.substr(idx);
608 // lower-case windows drive letters in /C:/fff or C:/fff
609 if (path.length >= 3 && path.charCodeAt(0) === 47 /* Slash */ && path.charCodeAt(2) === 58 /* Colon */) {
610 var code = path.charCodeAt(1);
611 if (code >= 65 /* A */ && code <= 90 /* Z */) {
612 path = "/" + String.fromCharCode(code + 32) + ":" + path.substr(3); // "/c:".length === 3
615 else if (path.length >= 2 && path.charCodeAt(1) === 58 /* Colon */) {
616 var code = path.charCodeAt(0);
617 if (code >= 65 /* A */ && code <= 90 /* Z */) {
618 path = String.fromCharCode(code + 32) + ":" + path.substr(2); // "/c:".length === 3
621 // encode the rest of the path
622 res += encoder(path, true);
626 res += encoder(query, false);
630 res += !skipEncoding ? encodeURIComponentFast(fragment, false) : fragment;
635 function decodeURIComponentGraceful(str) {
637 return decodeURIComponent(str);
640 if (str.length > 3) {
641 return str.substr(0, 3) + decodeURIComponentGraceful(str.substr(3));
648 var _rEncodedAsHex = /(%[0-9A-Za-z][0-9A-Za-z])+/g;
649 function percentDecode(str) {
650 if (!str.match(_rEncodedAsHex)) {
653 return str.replace(_rEncodedAsHex, function (match) { return decodeURIComponentGraceful(match); });