This commit is contained in:
Gilles Soulier
2026-01-17 15:58:01 +01:00
parent 1f7f7da0c3
commit dc19315e5d
5616 changed files with 1609815 additions and 18 deletions
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+415
View File
@@ -0,0 +1,415 @@
/**
* An inlined enum containing useful character codes (to be used with String.charCodeAt).
* Please leave the const keyword such that it gets inlined when compiled to JavaScript!
*/
export declare const enum CharCode {
Null = 0,
/**
* The `\b` character.
*/
Backspace = 8,
/**
* The `\t` character.
*/
Tab = 9,
/**
* The `\n` character.
*/
LineFeed = 10,
/**
* The `\r` character.
*/
CarriageReturn = 13,
Space = 32,
/**
* The `!` character.
*/
ExclamationMark = 33,
/**
* The `"` character.
*/
DoubleQuote = 34,
/**
* The `#` character.
*/
Hash = 35,
/**
* The `$` character.
*/
DollarSign = 36,
/**
* The `%` character.
*/
PercentSign = 37,
/**
* The `&` character.
*/
Ampersand = 38,
/**
* The `'` character.
*/
SingleQuote = 39,
/**
* The `(` character.
*/
OpenParen = 40,
/**
* The `)` character.
*/
CloseParen = 41,
/**
* The `*` character.
*/
Asterisk = 42,
/**
* The `+` character.
*/
Plus = 43,
/**
* The `,` character.
*/
Comma = 44,
/**
* The `-` character.
*/
Dash = 45,
/**
* The `.` character.
*/
Period = 46,
/**
* The `/` character.
*/
Slash = 47,
Digit0 = 48,
Digit1 = 49,
Digit2 = 50,
Digit3 = 51,
Digit4 = 52,
Digit5 = 53,
Digit6 = 54,
Digit7 = 55,
Digit8 = 56,
Digit9 = 57,
/**
* The `:` character.
*/
Colon = 58,
/**
* The `;` character.
*/
Semicolon = 59,
/**
* The `<` character.
*/
LessThan = 60,
/**
* The `=` character.
*/
Equals = 61,
/**
* The `>` character.
*/
GreaterThan = 62,
/**
* The `?` character.
*/
QuestionMark = 63,
/**
* The `@` character.
*/
AtSign = 64,
A = 65,
B = 66,
C = 67,
D = 68,
E = 69,
F = 70,
G = 71,
H = 72,
I = 73,
J = 74,
K = 75,
L = 76,
M = 77,
N = 78,
O = 79,
P = 80,
Q = 81,
R = 82,
S = 83,
T = 84,
U = 85,
V = 86,
W = 87,
X = 88,
Y = 89,
Z = 90,
/**
* The `[` character.
*/
OpenSquareBracket = 91,
/**
* The `\` character.
*/
Backslash = 92,
/**
* The `]` character.
*/
CloseSquareBracket = 93,
/**
* The `^` character.
*/
Caret = 94,
/**
* The `_` character.
*/
Underline = 95,
/**
* The ``(`)`` character.
*/
BackTick = 96,
a = 97,
b = 98,
c = 99,
d = 100,
e = 101,
f = 102,
g = 103,
h = 104,
i = 105,
j = 106,
k = 107,
l = 108,
m = 109,
n = 110,
o = 111,
p = 112,
q = 113,
r = 114,
s = 115,
t = 116,
u = 117,
v = 118,
w = 119,
x = 120,
y = 121,
z = 122,
/**
* The `{` character.
*/
OpenCurlyBrace = 123,
/**
* The `|` character.
*/
Pipe = 124,
/**
* The `}` character.
*/
CloseCurlyBrace = 125,
/**
* The `~` character.
*/
Tilde = 126,
U_Combining_Grave_Accent = 768,
U_Combining_Acute_Accent = 769,
U_Combining_Circumflex_Accent = 770,
U_Combining_Tilde = 771,
U_Combining_Macron = 772,
U_Combining_Overline = 773,
U_Combining_Breve = 774,
U_Combining_Dot_Above = 775,
U_Combining_Diaeresis = 776,
U_Combining_Hook_Above = 777,
U_Combining_Ring_Above = 778,
U_Combining_Double_Acute_Accent = 779,
U_Combining_Caron = 780,
U_Combining_Vertical_Line_Above = 781,
U_Combining_Double_Vertical_Line_Above = 782,
U_Combining_Double_Grave_Accent = 783,
U_Combining_Candrabindu = 784,
U_Combining_Inverted_Breve = 785,
U_Combining_Turned_Comma_Above = 786,
U_Combining_Comma_Above = 787,
U_Combining_Reversed_Comma_Above = 788,
U_Combining_Comma_Above_Right = 789,
U_Combining_Grave_Accent_Below = 790,
U_Combining_Acute_Accent_Below = 791,
U_Combining_Left_Tack_Below = 792,
U_Combining_Right_Tack_Below = 793,
U_Combining_Left_Angle_Above = 794,
U_Combining_Horn = 795,
U_Combining_Left_Half_Ring_Below = 796,
U_Combining_Up_Tack_Below = 797,
U_Combining_Down_Tack_Below = 798,
U_Combining_Plus_Sign_Below = 799,
U_Combining_Minus_Sign_Below = 800,
U_Combining_Palatalized_Hook_Below = 801,
U_Combining_Retroflex_Hook_Below = 802,
U_Combining_Dot_Below = 803,
U_Combining_Diaeresis_Below = 804,
U_Combining_Ring_Below = 805,
U_Combining_Comma_Below = 806,
U_Combining_Cedilla = 807,
U_Combining_Ogonek = 808,
U_Combining_Vertical_Line_Below = 809,
U_Combining_Bridge_Below = 810,
U_Combining_Inverted_Double_Arch_Below = 811,
U_Combining_Caron_Below = 812,
U_Combining_Circumflex_Accent_Below = 813,
U_Combining_Breve_Below = 814,
U_Combining_Inverted_Breve_Below = 815,
U_Combining_Tilde_Below = 816,
U_Combining_Macron_Below = 817,
U_Combining_Low_Line = 818,
U_Combining_Double_Low_Line = 819,
U_Combining_Tilde_Overlay = 820,
U_Combining_Short_Stroke_Overlay = 821,
U_Combining_Long_Stroke_Overlay = 822,
U_Combining_Short_Solidus_Overlay = 823,
U_Combining_Long_Solidus_Overlay = 824,
U_Combining_Right_Half_Ring_Below = 825,
U_Combining_Inverted_Bridge_Below = 826,
U_Combining_Square_Below = 827,
U_Combining_Seagull_Below = 828,
U_Combining_X_Above = 829,
U_Combining_Vertical_Tilde = 830,
U_Combining_Double_Overline = 831,
U_Combining_Grave_Tone_Mark = 832,
U_Combining_Acute_Tone_Mark = 833,
U_Combining_Greek_Perispomeni = 834,
U_Combining_Greek_Koronis = 835,
U_Combining_Greek_Dialytika_Tonos = 836,
U_Combining_Greek_Ypogegrammeni = 837,
U_Combining_Bridge_Above = 838,
U_Combining_Equals_Sign_Below = 839,
U_Combining_Double_Vertical_Line_Below = 840,
U_Combining_Left_Angle_Below = 841,
U_Combining_Not_Tilde_Above = 842,
U_Combining_Homothetic_Above = 843,
U_Combining_Almost_Equal_To_Above = 844,
U_Combining_Left_Right_Arrow_Below = 845,
U_Combining_Upwards_Arrow_Below = 846,
U_Combining_Grapheme_Joiner = 847,
U_Combining_Right_Arrowhead_Above = 848,
U_Combining_Left_Half_Ring_Above = 849,
U_Combining_Fermata = 850,
U_Combining_X_Below = 851,
U_Combining_Left_Arrowhead_Below = 852,
U_Combining_Right_Arrowhead_Below = 853,
U_Combining_Right_Arrowhead_And_Up_Arrowhead_Below = 854,
U_Combining_Right_Half_Ring_Above = 855,
U_Combining_Dot_Above_Right = 856,
U_Combining_Asterisk_Below = 857,
U_Combining_Double_Ring_Below = 858,
U_Combining_Zigzag_Above = 859,
U_Combining_Double_Breve_Below = 860,
U_Combining_Double_Breve = 861,
U_Combining_Double_Macron = 862,
U_Combining_Double_Macron_Below = 863,
U_Combining_Double_Tilde = 864,
U_Combining_Double_Inverted_Breve = 865,
U_Combining_Double_Rightwards_Arrow_Below = 866,
U_Combining_Latin_Small_Letter_A = 867,
U_Combining_Latin_Small_Letter_E = 868,
U_Combining_Latin_Small_Letter_I = 869,
U_Combining_Latin_Small_Letter_O = 870,
U_Combining_Latin_Small_Letter_U = 871,
U_Combining_Latin_Small_Letter_C = 872,
U_Combining_Latin_Small_Letter_D = 873,
U_Combining_Latin_Small_Letter_H = 874,
U_Combining_Latin_Small_Letter_M = 875,
U_Combining_Latin_Small_Letter_R = 876,
U_Combining_Latin_Small_Letter_T = 877,
U_Combining_Latin_Small_Letter_V = 878,
U_Combining_Latin_Small_Letter_X = 879,
/**
* Unicode Character 'LINE SEPARATOR' (U+2028)
* http://www.fileformat.info/info/unicode/char/2028/index.htm
*/
LINE_SEPARATOR = 8232,
/**
* Unicode Character 'PARAGRAPH SEPARATOR' (U+2029)
* http://www.fileformat.info/info/unicode/char/2029/index.htm
*/
PARAGRAPH_SEPARATOR = 8233,
/**
* Unicode Character 'NEXT LINE' (U+0085)
* http://www.fileformat.info/info/unicode/char/0085/index.htm
*/
NEXT_LINE = 133,
U_CIRCUMFLEX = 94,
U_GRAVE_ACCENT = 96,
U_DIAERESIS = 168,
U_MACRON = 175,
U_ACUTE_ACCENT = 180,
U_CEDILLA = 184,
U_MODIFIER_LETTER_LEFT_ARROWHEAD = 706,
U_MODIFIER_LETTER_RIGHT_ARROWHEAD = 707,
U_MODIFIER_LETTER_UP_ARROWHEAD = 708,
U_MODIFIER_LETTER_DOWN_ARROWHEAD = 709,
U_MODIFIER_LETTER_CENTRED_RIGHT_HALF_RING = 722,
U_MODIFIER_LETTER_CENTRED_LEFT_HALF_RING = 723,
U_MODIFIER_LETTER_UP_TACK = 724,
U_MODIFIER_LETTER_DOWN_TACK = 725,
U_MODIFIER_LETTER_PLUS_SIGN = 726,
U_MODIFIER_LETTER_MINUS_SIGN = 727,
U_BREVE = 728,
U_DOT_ABOVE = 729,
U_RING_ABOVE = 730,
U_OGONEK = 731,
U_SMALL_TILDE = 732,
U_DOUBLE_ACUTE_ACCENT = 733,
U_MODIFIER_LETTER_RHOTIC_HOOK = 734,
U_MODIFIER_LETTER_CROSS_ACCENT = 735,
U_MODIFIER_LETTER_EXTRA_HIGH_TONE_BAR = 741,
U_MODIFIER_LETTER_HIGH_TONE_BAR = 742,
U_MODIFIER_LETTER_MID_TONE_BAR = 743,
U_MODIFIER_LETTER_LOW_TONE_BAR = 744,
U_MODIFIER_LETTER_EXTRA_LOW_TONE_BAR = 745,
U_MODIFIER_LETTER_YIN_DEPARTING_TONE_MARK = 746,
U_MODIFIER_LETTER_YANG_DEPARTING_TONE_MARK = 747,
U_MODIFIER_LETTER_UNASPIRATED = 749,
U_MODIFIER_LETTER_LOW_DOWN_ARROWHEAD = 751,
U_MODIFIER_LETTER_LOW_UP_ARROWHEAD = 752,
U_MODIFIER_LETTER_LOW_LEFT_ARROWHEAD = 753,
U_MODIFIER_LETTER_LOW_RIGHT_ARROWHEAD = 754,
U_MODIFIER_LETTER_LOW_RING = 755,
U_MODIFIER_LETTER_MIDDLE_GRAVE_ACCENT = 756,
U_MODIFIER_LETTER_MIDDLE_DOUBLE_GRAVE_ACCENT = 757,
U_MODIFIER_LETTER_MIDDLE_DOUBLE_ACUTE_ACCENT = 758,
U_MODIFIER_LETTER_LOW_TILDE = 759,
U_MODIFIER_LETTER_RAISED_COLON = 760,
U_MODIFIER_LETTER_BEGIN_HIGH_TONE = 761,
U_MODIFIER_LETTER_END_HIGH_TONE = 762,
U_MODIFIER_LETTER_BEGIN_LOW_TONE = 763,
U_MODIFIER_LETTER_END_LOW_TONE = 764,
U_MODIFIER_LETTER_SHELF = 765,
U_MODIFIER_LETTER_OPEN_SHELF = 766,
U_MODIFIER_LETTER_LOW_LEFT_ARROW = 767,
U_GREEK_LOWER_NUMERAL_SIGN = 885,
U_GREEK_TONOS = 900,
U_GREEK_DIALYTIKA_TONOS = 901,
U_GREEK_KORONIS = 8125,
U_GREEK_PSILI = 8127,
U_GREEK_PERISPOMENI = 8128,
U_GREEK_DIALYTIKA_AND_PERISPOMENI = 8129,
U_GREEK_PSILI_AND_VARIA = 8141,
U_GREEK_PSILI_AND_OXIA = 8142,
U_GREEK_PSILI_AND_PERISPOMENI = 8143,
U_GREEK_DASIA_AND_VARIA = 8157,
U_GREEK_DASIA_AND_OXIA = 8158,
U_GREEK_DASIA_AND_PERISPOMENI = 8159,
U_GREEK_DIALYTIKA_AND_VARIA = 8173,
U_GREEK_DIALYTIKA_AND_OXIA = 8174,
U_GREEK_VARIA = 8175,
U_GREEK_OXIA = 8189,
U_GREEK_DASIA = 8190,
U_OVERLINE = 8254,
/**
* UTF-8 BOM
* Unicode Character 'ZERO WIDTH NO-BREAK SPACE' (U+FEFF)
* http://www.fileformat.info/info/unicode/char/feff/index.htm
*/
UTF8_BOM = 65279
}
+6
View File
@@ -0,0 +1,6 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
+3
View File
@@ -0,0 +1,3 @@
import { URI } from './uri';
import { Utils } from './utils';
export { URI, Utils };
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
export declare let isWindows: boolean;
+14
View File
@@ -0,0 +1,14 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
exports.isWindows = void 0;
if (typeof process === 'object') {
exports.isWindows = process.platform === 'win32';
}
else if (typeof navigator === 'object') {
let userAgent = navigator.userAgent;
exports.isWindows = userAgent.indexOf('Windows') >= 0;
}
+151
View File
@@ -0,0 +1,151 @@
/**
* Uniform Resource Identifier (URI) http://tools.ietf.org/html/rfc3986.
* This class is a simple parser which creates the basic component parts
* (http://tools.ietf.org/html/rfc3986#section-3) with minimal validation
* and encoding.
*
* ```txt
* foo://example.com:8042/over/there?name=ferret#nose
* \_/ \______________/\_________/ \_________/ \__/
* | | | | |
* scheme authority path query fragment
* | _____________________|__
* / \ / \
* urn:example:animal:ferret:nose
* ```
*/
export declare class URI implements UriComponents {
static isUri(thing: any): thing is URI;
/**
* scheme is the 'http' part of 'http://www.example.com/some/path?query#fragment'.
* The part before the first colon.
*/
readonly scheme: string;
/**
* authority is the 'www.example.com' part of 'http://www.example.com/some/path?query#fragment'.
* The part between the first double slashes and the next slash.
*/
readonly authority: string;
/**
* path is the '/some/path' part of 'http://www.example.com/some/path?query#fragment'.
*/
readonly path: string;
/**
* query is the 'query' part of 'http://www.example.com/some/path?query#fragment'.
*/
readonly query: string;
/**
* fragment is the 'fragment' part of 'http://www.example.com/some/path?query#fragment'.
*/
readonly fragment: string;
/**
* @internal
*/
protected constructor(scheme: string, authority?: string, path?: string, query?: string, fragment?: string, _strict?: boolean);
/**
* @internal
*/
protected constructor(components: UriComponents);
/**
* Returns a string representing the corresponding file system path of this URI.
* Will handle UNC paths, normalizes windows drive letters to lower-case, and uses the
* platform specific path separator.
*
* * Will *not* validate the path for invalid characters and semantics.
* * Will *not* look at the scheme of this URI.
* * The result shall *not* be used for display purposes but for accessing a file on disk.
*
*
* The *difference* to `URI#path` is the use of the platform specific separator and the handling
* of UNC paths. See the below sample of a file-uri with an authority (UNC path).
*
* ```ts
const u = URI.parse('file://server/c$/folder/file.txt')
u.authority === 'server'
u.path === '/shares/c$/file.txt'
u.fsPath === '\\server\c$\folder\file.txt'
```
*
* Using `URI#path` to read a file (using fs-apis) would not be enough because parts of the path,
* namely the server name, would be missing. Therefore `URI#fsPath` exists - it's sugar to ease working
* with URIs that represent files on disk (`file` scheme).
*/
get fsPath(): string;
with(change: {
scheme?: string;
authority?: string | null;
path?: string | null;
query?: string | null;
fragment?: string | null;
}): URI;
/**
* Creates a new URI from a string, e.g. `http://www.example.com/some/path`,
* `file:///usr/home`, or `scheme:with/path`.
*
* @param value A string which represents an URI (see `URI#toString`).
*/
static parse(value: string, _strict?: boolean): URI;
/**
* Creates a new URI from a file system path, e.g. `c:\my\files`,
* `/usr/home`, or `\\server\share\some\path`.
*
* The *difference* between `URI#parse` and `URI#file` is that the latter treats the argument
* as path, not as stringified-uri. E.g. `URI.file(path)` is **not the same as**
* `URI.parse('file://' + path)` because the path might contain characters that are
* interpreted (# and ?). See the following sample:
* ```ts
const good = URI.file('/coding/c#/project1');
good.scheme === 'file';
good.path === '/coding/c#/project1';
good.fragment === '';
const bad = URI.parse('file://' + '/coding/c#/project1');
bad.scheme === 'file';
bad.path === '/coding/c'; // path is now broken
bad.fragment === '/project1';
```
*
* @param path A file system path (see `URI#fsPath`)
*/
static file(path: string): URI;
static from(components: {
scheme: string;
authority?: string;
path?: string;
query?: string;
fragment?: string;
}): URI;
/**
* Creates a string representation for this URI. It's guaranteed that calling
* `URI.parse` with the result of this function creates an URI which is equal
* to this URI.
*
* * The result shall *not* be used for display purposes but for externalization or transport.
* * The result will be encoded using the percentage encoding and encoding happens mostly
* ignore the scheme-specific encoding rules.
*
* @param skipEncoding Do not encode the result, default is `false`
*/
toString(skipEncoding?: boolean): string;
toJSON(): UriComponents;
static revive(data: UriComponents | URI): URI;
static revive(data: UriComponents | URI | undefined): URI | undefined;
static revive(data: UriComponents | URI | null): URI | null;
static revive(data: UriComponents | URI | undefined | null): URI | undefined | null;
}
export interface UriComponents {
scheme: string;
authority: string;
path: string;
query: string;
fragment: string;
}
/**
* Compute `fsPath` for the given uri
*/
export declare function uriToFsPath(uri: URI, keepDriveLetterCasing: boolean): string;
/**
* Mapped-type that replaces all occurrences of URI with UriComponents
*/
export type UriDto<T> = {
[K in keyof T]: T[K] extends URI ? UriComponents : UriDto<T[K]>;
};
+595
View File
@@ -0,0 +1,595 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
exports.uriToFsPath = exports.URI = void 0;
const platform_1 = require("./platform");
const _schemePattern = /^\w[\w\d+.-]*$/;
const _singleSlashStart = /^\//;
const _doubleSlashStart = /^\/\//;
function _validateUri(ret, _strict) {
// scheme, must be set
if (!ret.scheme && _strict) {
throw new Error(`[UriError]: Scheme is missing: {scheme: "", authority: "${ret.authority}", path: "${ret.path}", query: "${ret.query}", fragment: "${ret.fragment}"}`);
}
// scheme, https://tools.ietf.org/html/rfc3986#section-3.1
// ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
if (ret.scheme && !_schemePattern.test(ret.scheme)) {
throw new Error('[UriError]: Scheme contains illegal characters.');
}
// path, http://tools.ietf.org/html/rfc3986#section-3.3
// If a URI contains an authority component, then the path component
// must either be empty or begin with a slash ("/") character. If a URI
// does not contain an authority component, then the path cannot begin
// with two slash characters ("//").
if (ret.path) {
if (ret.authority) {
if (!_singleSlashStart.test(ret.path)) {
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');
}
}
else {
if (_doubleSlashStart.test(ret.path)) {
throw new Error('[UriError]: If a URI does not contain an authority component, then the path cannot begin with two slash characters ("//")');
}
}
}
}
// for a while we allowed uris *without* schemes and this is the migration
// for them, e.g. an uri without scheme and without strict-mode warns and falls
// back to the file-scheme. that should cause the least carnage and still be a
// clear warning
function _schemeFix(scheme, _strict) {
if (!scheme && !_strict) {
return 'file';
}
return scheme;
}
// implements a bit of https://tools.ietf.org/html/rfc3986#section-5
function _referenceResolution(scheme, path) {
// the slash-character is our 'default base' as we don't
// support constructing URIs relative to other URIs. This
// also means that we alter and potentially break paths.
// see https://tools.ietf.org/html/rfc3986#section-5.1.4
switch (scheme) {
case 'https':
case 'http':
case 'file':
if (!path) {
path = _slash;
}
else if (path[0] !== _slash) {
path = _slash + path;
}
break;
}
return path;
}
const _empty = '';
const _slash = '/';
const _regexp = /^(([^:/?#]+?):)?(\/\/([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?/;
/**
* Uniform Resource Identifier (URI) http://tools.ietf.org/html/rfc3986.
* This class is a simple parser which creates the basic component parts
* (http://tools.ietf.org/html/rfc3986#section-3) with minimal validation
* and encoding.
*
* ```txt
* foo://example.com:8042/over/there?name=ferret#nose
* \_/ \______________/\_________/ \_________/ \__/
* | | | | |
* scheme authority path query fragment
* | _____________________|__
* / \ / \
* urn:example:animal:ferret:nose
* ```
*/
class URI {
static isUri(thing) {
if (thing instanceof URI) {
return true;
}
if (!thing) {
return false;
}
return typeof thing.authority === 'string'
&& typeof thing.fragment === 'string'
&& typeof thing.path === 'string'
&& typeof thing.query === 'string'
&& typeof thing.scheme === 'string'
&& typeof thing.fsPath === 'string'
&& typeof thing.with === 'function'
&& typeof thing.toString === 'function';
}
/**
* scheme is the 'http' part of 'http://www.example.com/some/path?query#fragment'.
* The part before the first colon.
*/
scheme;
/**
* authority is the 'www.example.com' part of 'http://www.example.com/some/path?query#fragment'.
* The part between the first double slashes and the next slash.
*/
authority;
/**
* path is the '/some/path' part of 'http://www.example.com/some/path?query#fragment'.
*/
path;
/**
* query is the 'query' part of 'http://www.example.com/some/path?query#fragment'.
*/
query;
/**
* fragment is the 'fragment' part of 'http://www.example.com/some/path?query#fragment'.
*/
fragment;
/**
* @internal
*/
constructor(schemeOrData, authority, path, query, fragment, _strict = false) {
if (typeof schemeOrData === 'object') {
this.scheme = schemeOrData.scheme || _empty;
this.authority = schemeOrData.authority || _empty;
this.path = schemeOrData.path || _empty;
this.query = schemeOrData.query || _empty;
this.fragment = schemeOrData.fragment || _empty;
// no validation because it's this URI
// that creates uri components.
// _validateUri(this);
}
else {
this.scheme = _schemeFix(schemeOrData, _strict);
this.authority = authority || _empty;
this.path = _referenceResolution(this.scheme, path || _empty);
this.query = query || _empty;
this.fragment = fragment || _empty;
_validateUri(this, _strict);
}
}
// ---- filesystem path -----------------------
/**
* Returns a string representing the corresponding file system path of this URI.
* Will handle UNC paths, normalizes windows drive letters to lower-case, and uses the
* platform specific path separator.
*
* * Will *not* validate the path for invalid characters and semantics.
* * Will *not* look at the scheme of this URI.
* * The result shall *not* be used for display purposes but for accessing a file on disk.
*
*
* The *difference* to `URI#path` is the use of the platform specific separator and the handling
* of UNC paths. See the below sample of a file-uri with an authority (UNC path).
*
* ```ts
const u = URI.parse('file://server/c$/folder/file.txt')
u.authority === 'server'
u.path === '/shares/c$/file.txt'
u.fsPath === '\\server\c$\folder\file.txt'
```
*
* Using `URI#path` to read a file (using fs-apis) would not be enough because parts of the path,
* namely the server name, would be missing. Therefore `URI#fsPath` exists - it's sugar to ease working
* with URIs that represent files on disk (`file` scheme).
*/
get fsPath() {
// if (this.scheme !== 'file') {
// console.warn(`[UriError] calling fsPath with scheme ${this.scheme}`);
// }
return uriToFsPath(this, false);
}
// ---- modify to new -------------------------
with(change) {
if (!change) {
return this;
}
let { scheme, authority, path, query, fragment } = change;
if (scheme === undefined) {
scheme = this.scheme;
}
else if (scheme === null) {
scheme = _empty;
}
if (authority === undefined) {
authority = this.authority;
}
else if (authority === null) {
authority = _empty;
}
if (path === undefined) {
path = this.path;
}
else if (path === null) {
path = _empty;
}
if (query === undefined) {
query = this.query;
}
else if (query === null) {
query = _empty;
}
if (fragment === undefined) {
fragment = this.fragment;
}
else if (fragment === null) {
fragment = _empty;
}
if (scheme === this.scheme
&& authority === this.authority
&& path === this.path
&& query === this.query
&& fragment === this.fragment) {
return this;
}
return new Uri(scheme, authority, path, query, fragment);
}
// ---- parse & validate ------------------------
/**
* Creates a new URI from a string, e.g. `http://www.example.com/some/path`,
* `file:///usr/home`, or `scheme:with/path`.
*
* @param value A string which represents an URI (see `URI#toString`).
*/
static parse(value, _strict = false) {
const match = _regexp.exec(value);
if (!match) {
return new Uri(_empty, _empty, _empty, _empty, _empty);
}
return new Uri(match[2] || _empty, percentDecode(match[4] || _empty), percentDecode(match[5] || _empty), percentDecode(match[7] || _empty), percentDecode(match[9] || _empty), _strict);
}
/**
* Creates a new URI from a file system path, e.g. `c:\my\files`,
* `/usr/home`, or `\\server\share\some\path`.
*
* The *difference* between `URI#parse` and `URI#file` is that the latter treats the argument
* as path, not as stringified-uri. E.g. `URI.file(path)` is **not the same as**
* `URI.parse('file://' + path)` because the path might contain characters that are
* interpreted (# and ?). See the following sample:
* ```ts
const good = URI.file('/coding/c#/project1');
good.scheme === 'file';
good.path === '/coding/c#/project1';
good.fragment === '';
const bad = URI.parse('file://' + '/coding/c#/project1');
bad.scheme === 'file';
bad.path === '/coding/c'; // path is now broken
bad.fragment === '/project1';
```
*
* @param path A file system path (see `URI#fsPath`)
*/
static file(path) {
let authority = _empty;
// normalize to fwd-slashes on windows,
// on other systems bwd-slashes are valid
// filename character, eg /f\oo/ba\r.txt
if (platform_1.isWindows) {
path = path.replace(/\\/g, _slash);
}
// check for authority as used in UNC shares
// or use the path as given
if (path[0] === _slash && path[1] === _slash) {
const idx = path.indexOf(_slash, 2);
if (idx === -1) {
authority = path.substring(2);
path = _slash;
}
else {
authority = path.substring(2, idx);
path = path.substring(idx) || _slash;
}
}
return new Uri('file', authority, path, _empty, _empty);
}
static from(components) {
const result = new Uri(components.scheme, components.authority, components.path, components.query, components.fragment);
_validateUri(result, true);
return result;
}
// ---- printing/externalize ---------------------------
/**
* Creates a string representation for this URI. It's guaranteed that calling
* `URI.parse` with the result of this function creates an URI which is equal
* to this URI.
*
* * The result shall *not* be used for display purposes but for externalization or transport.
* * The result will be encoded using the percentage encoding and encoding happens mostly
* ignore the scheme-specific encoding rules.
*
* @param skipEncoding Do not encode the result, default is `false`
*/
toString(skipEncoding = false) {
return _asFormatted(this, skipEncoding);
}
toJSON() {
return this;
}
static revive(data) {
if (!data) {
return data;
}
else if (data instanceof URI) {
return data;
}
else {
const result = new Uri(data);
result._formatted = data.external;
result._fsPath = data._sep === _pathSepMarker ? data.fsPath : null;
return result;
}
}
}
exports.URI = URI;
const _pathSepMarker = platform_1.isWindows ? 1 : undefined;
// This class exists so that URI is compatible with vscode.Uri (API).
class Uri extends URI {
_formatted = null;
_fsPath = null;
get fsPath() {
if (!this._fsPath) {
this._fsPath = uriToFsPath(this, false);
}
return this._fsPath;
}
toString(skipEncoding = false) {
if (!skipEncoding) {
if (!this._formatted) {
this._formatted = _asFormatted(this, false);
}
return this._formatted;
}
else {
// we don't cache that
return _asFormatted(this, true);
}
}
toJSON() {
const res = {
$mid: 1
};
// cached state
if (this._fsPath) {
res.fsPath = this._fsPath;
res._sep = _pathSepMarker;
}
if (this._formatted) {
res.external = this._formatted;
}
// uri components
if (this.path) {
res.path = this.path;
}
if (this.scheme) {
res.scheme = this.scheme;
}
if (this.authority) {
res.authority = this.authority;
}
if (this.query) {
res.query = this.query;
}
if (this.fragment) {
res.fragment = this.fragment;
}
return res;
}
}
// reserved characters: https://tools.ietf.org/html/rfc3986#section-2.2
const encodeTable = {
[58 /* CharCode.Colon */]: '%3A',
[47 /* CharCode.Slash */]: '%2F',
[63 /* CharCode.QuestionMark */]: '%3F',
[35 /* CharCode.Hash */]: '%23',
[91 /* CharCode.OpenSquareBracket */]: '%5B',
[93 /* CharCode.CloseSquareBracket */]: '%5D',
[64 /* CharCode.AtSign */]: '%40',
[33 /* CharCode.ExclamationMark */]: '%21',
[36 /* CharCode.DollarSign */]: '%24',
[38 /* CharCode.Ampersand */]: '%26',
[39 /* CharCode.SingleQuote */]: '%27',
[40 /* CharCode.OpenParen */]: '%28',
[41 /* CharCode.CloseParen */]: '%29',
[42 /* CharCode.Asterisk */]: '%2A',
[43 /* CharCode.Plus */]: '%2B',
[44 /* CharCode.Comma */]: '%2C',
[59 /* CharCode.Semicolon */]: '%3B',
[61 /* CharCode.Equals */]: '%3D',
[32 /* CharCode.Space */]: '%20',
};
function encodeURIComponentFast(uriComponent, isPath, isAuthority) {
let res = undefined;
let nativeEncodePos = -1;
for (let pos = 0; pos < uriComponent.length; pos++) {
const code = uriComponent.charCodeAt(pos);
// unreserved characters: https://tools.ietf.org/html/rfc3986#section-2.3
if ((code >= 97 /* CharCode.a */ && code <= 122 /* CharCode.z */)
|| (code >= 65 /* CharCode.A */ && code <= 90 /* CharCode.Z */)
|| (code >= 48 /* CharCode.Digit0 */ && code <= 57 /* CharCode.Digit9 */)
|| code === 45 /* CharCode.Dash */
|| code === 46 /* CharCode.Period */
|| code === 95 /* CharCode.Underline */
|| code === 126 /* CharCode.Tilde */
|| (isPath && code === 47 /* CharCode.Slash */)
|| (isAuthority && code === 91 /* CharCode.OpenSquareBracket */)
|| (isAuthority && code === 93 /* CharCode.CloseSquareBracket */)
|| (isAuthority && code === 58 /* CharCode.Colon */)) {
// check if we are delaying native encode
if (nativeEncodePos !== -1) {
res += encodeURIComponent(uriComponent.substring(nativeEncodePos, pos));
nativeEncodePos = -1;
}
// check if we write into a new string (by default we try to return the param)
if (res !== undefined) {
res += uriComponent.charAt(pos);
}
}
else {
// encoding needed, we need to allocate a new string
if (res === undefined) {
res = uriComponent.substr(0, pos);
}
// check with default table first
const escaped = encodeTable[code];
if (escaped !== undefined) {
// check if we are delaying native encode
if (nativeEncodePos !== -1) {
res += encodeURIComponent(uriComponent.substring(nativeEncodePos, pos));
nativeEncodePos = -1;
}
// append escaped variant to result
res += escaped;
}
else if (nativeEncodePos === -1) {
// use native encode only when needed
nativeEncodePos = pos;
}
}
}
if (nativeEncodePos !== -1) {
res += encodeURIComponent(uriComponent.substring(nativeEncodePos));
}
return res !== undefined ? res : uriComponent;
}
function encodeURIComponentMinimal(path) {
let res = undefined;
for (let pos = 0; pos < path.length; pos++) {
const code = path.charCodeAt(pos);
if (code === 35 /* CharCode.Hash */ || code === 63 /* CharCode.QuestionMark */) {
if (res === undefined) {
res = path.substr(0, pos);
}
res += encodeTable[code];
}
else {
if (res !== undefined) {
res += path[pos];
}
}
}
return res !== undefined ? res : path;
}
/**
* Compute `fsPath` for the given uri
*/
function uriToFsPath(uri, keepDriveLetterCasing) {
let value;
if (uri.authority && uri.path.length > 1 && uri.scheme === 'file') {
// unc path: file://shares/c$/far/boo
value = `//${uri.authority}${uri.path}`;
}
else if (uri.path.charCodeAt(0) === 47 /* CharCode.Slash */
&& (uri.path.charCodeAt(1) >= 65 /* CharCode.A */ && uri.path.charCodeAt(1) <= 90 /* CharCode.Z */ || uri.path.charCodeAt(1) >= 97 /* CharCode.a */ && uri.path.charCodeAt(1) <= 122 /* CharCode.z */)
&& uri.path.charCodeAt(2) === 58 /* CharCode.Colon */) {
if (!keepDriveLetterCasing) {
// windows drive letter: file:///c:/far/boo
value = uri.path[1].toLowerCase() + uri.path.substr(2);
}
else {
value = uri.path.substr(1);
}
}
else {
// other path
value = uri.path;
}
if (platform_1.isWindows) {
value = value.replace(/\//g, '\\');
}
return value;
}
exports.uriToFsPath = uriToFsPath;
/**
* Create the external version of a uri
*/
function _asFormatted(uri, skipEncoding) {
const encoder = !skipEncoding
? encodeURIComponentFast
: encodeURIComponentMinimal;
let res = '';
let { scheme, authority, path, query, fragment } = uri;
if (scheme) {
res += scheme;
res += ':';
}
if (authority || scheme === 'file') {
res += _slash;
res += _slash;
}
if (authority) {
let idx = authority.indexOf('@');
if (idx !== -1) {
// <user>@<auth>
const userinfo = authority.substr(0, idx);
authority = authority.substr(idx + 1);
idx = userinfo.lastIndexOf(':');
if (idx === -1) {
res += encoder(userinfo, false, false);
}
else {
// <user>:<pass>@<auth>
res += encoder(userinfo.substr(0, idx), false, false);
res += ':';
res += encoder(userinfo.substr(idx + 1), false, true);
}
res += '@';
}
authority = authority.toLowerCase();
idx = authority.lastIndexOf(':');
if (idx === -1) {
res += encoder(authority, false, true);
}
else {
// <auth>:<port>
res += encoder(authority.substr(0, idx), false, true);
res += authority.substr(idx);
}
}
if (path) {
// lower-case windows drive letters in /C:/fff or C:/fff
if (path.length >= 3 && path.charCodeAt(0) === 47 /* CharCode.Slash */ && path.charCodeAt(2) === 58 /* CharCode.Colon */) {
const code = path.charCodeAt(1);
if (code >= 65 /* CharCode.A */ && code <= 90 /* CharCode.Z */) {
path = `/${String.fromCharCode(code + 32)}:${path.substr(3)}`; // "/c:".length === 3
}
}
else if (path.length >= 2 && path.charCodeAt(1) === 58 /* CharCode.Colon */) {
const code = path.charCodeAt(0);
if (code >= 65 /* CharCode.A */ && code <= 90 /* CharCode.Z */) {
path = `${String.fromCharCode(code + 32)}:${path.substr(2)}`; // "/c:".length === 3
}
}
// encode the rest of the path
res += encoder(path, true, false);
}
if (query) {
res += '?';
res += encoder(query, false, false);
}
if (fragment) {
res += '#';
res += !skipEncoding ? encodeURIComponentFast(fragment, false, false) : fragment;
}
return res;
}
// --- decode
function decodeURIComponentGraceful(str) {
try {
return decodeURIComponent(str);
}
catch {
if (str.length > 3) {
return str.substr(0, 3) + decodeURIComponentGraceful(str.substr(3));
}
else {
return str;
}
}
}
const _rEncodedAsHex = /(%[0-9A-Za-z][0-9A-Za-z])+/g;
function percentDecode(str) {
if (!str.match(_rEncodedAsHex)) {
return str;
}
return str.replace(_rEncodedAsHex, (match) => decodeURIComponentGraceful(match));
}
+58
View File
@@ -0,0 +1,58 @@
import { URI } from './uri';
export declare namespace Utils {
/**
* Joins one or more input paths to the path of URI.
* '/' is used as the directory separation character.
*
* The resolved path will be normalized. That means:
* - all '..' and '.' segments are resolved.
* - multiple, sequential occurences of '/' are replaced by a single instance of '/'.
* - trailing separators are preserved.
*
* @param uri The input URI.
* @param paths The paths to be joined with the path of URI.
* @returns A URI with the joined path. All other properties of the URI (scheme, authority, query, fragments, ...) will be taken from the input URI.
*/
function joinPath(uri: URI, ...paths: string[]): URI;
/**
* Resolves one or more paths against the path of a URI.
* '/' is used as the directory separation character.
*
* The resolved path will be normalized. That means:
* - all '..' and '.' segments are resolved.
* - multiple, sequential occurences of '/' are replaced by a single instance of '/'.
* - trailing separators are removed.
*
* @param uri The input URI.
* @param paths The paths to resolve against the path of URI.
* @returns A URI with the resolved path. All other properties of the URI (scheme, authority, query, fragments, ...) will be taken from the input URI.
*/
function resolvePath(uri: URI, ...paths: string[]): URI;
/**
* Returns a URI where the path is the directory name of the input uri, similar to the Unix dirname command.
* In the path, '/' is recognized as the directory separation character. Trailing directory separators are ignored.
* The orignal URI is returned if the URIs path is empty or does not contain any path segments.
*
* @param uri The input URI.
* @return The last segment of the URIs path.
*/
function dirname(uri: URI): URI;
/**
* Returns the last segment of the path of a URI, similar to the Unix basename command.
* In the path, '/' is recognized as the directory separation character. Trailing directory separators are ignored.
* The empty string is returned if the URIs path is empty or does not contain any path segments.
*
* @param uri The input URI.
* @return The base name of the URIs path.
*/
function basename(uri: URI): string;
/**
* Returns the extension name of the path of a URI, similar to the Unix extname command.
* In the path, '/' is recognized as the directory separation character. Trailing directory separators are ignored.
* The empty string is returned if the URIs path is empty or does not contain any path segments.
*
* @param uri The input URI.
* @return The extension name of the URIs path.
*/
function extname(uri: URI): string;
}
+123
View File
@@ -0,0 +1,123 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Utils = void 0;
const nodePath = __importStar(require("path"));
const posixPath = nodePath.posix || nodePath;
const slash = '/';
var Utils;
(function (Utils) {
/**
* Joins one or more input paths to the path of URI.
* '/' is used as the directory separation character.
*
* The resolved path will be normalized. That means:
* - all '..' and '.' segments are resolved.
* - multiple, sequential occurences of '/' are replaced by a single instance of '/'.
* - trailing separators are preserved.
*
* @param uri The input URI.
* @param paths The paths to be joined with the path of URI.
* @returns A URI with the joined path. All other properties of the URI (scheme, authority, query, fragments, ...) will be taken from the input URI.
*/
function joinPath(uri, ...paths) {
return uri.with({ path: posixPath.join(uri.path, ...paths) });
}
Utils.joinPath = joinPath;
/**
* Resolves one or more paths against the path of a URI.
* '/' is used as the directory separation character.
*
* The resolved path will be normalized. That means:
* - all '..' and '.' segments are resolved.
* - multiple, sequential occurences of '/' are replaced by a single instance of '/'.
* - trailing separators are removed.
*
* @param uri The input URI.
* @param paths The paths to resolve against the path of URI.
* @returns A URI with the resolved path. All other properties of the URI (scheme, authority, query, fragments, ...) will be taken from the input URI.
*/
function resolvePath(uri, ...paths) {
let path = uri.path;
let slashAdded = false;
if (path[0] !== slash) {
path = slash + path; // make the path abstract: for posixPath.resolve the first segments has to be absolute or cwd is used.
slashAdded = true;
}
let resolvedPath = posixPath.resolve(path, ...paths);
if (slashAdded && resolvedPath[0] === slash && !uri.authority) {
resolvedPath = resolvedPath.substring(1);
}
return uri.with({ path: resolvedPath });
}
Utils.resolvePath = resolvePath;
/**
* Returns a URI where the path is the directory name of the input uri, similar to the Unix dirname command.
* In the path, '/' is recognized as the directory separation character. Trailing directory separators are ignored.
* The orignal URI is returned if the URIs path is empty or does not contain any path segments.
*
* @param uri The input URI.
* @return The last segment of the URIs path.
*/
function dirname(uri) {
if (uri.path.length === 0 || uri.path === slash) {
return uri;
}
let path = posixPath.dirname(uri.path);
if (path.length === 1 && path.charCodeAt(0) === 46 /* CharCode.Period */) {
path = '';
}
return uri.with({ path });
}
Utils.dirname = dirname;
/**
* Returns the last segment of the path of a URI, similar to the Unix basename command.
* In the path, '/' is recognized as the directory separation character. Trailing directory separators are ignored.
* The empty string is returned if the URIs path is empty or does not contain any path segments.
*
* @param uri The input URI.
* @return The base name of the URIs path.
*/
function basename(uri) {
return posixPath.basename(uri.path);
}
Utils.basename = basename;
/**
* Returns the extension name of the path of a URI, similar to the Unix extname command.
* In the path, '/' is recognized as the directory separation character. Trailing directory separators are ignored.
* The empty string is returned if the URIs path is empty or does not contain any path segments.
*
* @param uri The input URI.
* @return The extension name of the URIs path.
*/
function extname(uri) {
return posixPath.extname(uri.path);
}
Utils.extname = extname;
})(Utils || (exports.Utils = Utils = {}));