@pactflow/openapi-pact-comparator 1.5.1 → 1.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.cjs +490 -309
- package/dist/cli.cjs.map +1 -1
- package/dist/index.cjs +489 -308
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +489 -308
- package/dist/index.mjs.map +1 -1
- package/dist/src/compare/utils/statusCodes.d.ts +1 -0
- package/package.json +10 -10
package/dist/index.mjs
CHANGED
|
@@ -3669,6 +3669,15 @@ const convertExclusiveMinMax = (s) => {
|
|
|
3669
3669
|
delete s.exclusiveMinimum;
|
|
3670
3670
|
}
|
|
3671
3671
|
};
|
|
3672
|
+
const cleanupDiscriminators = (s) => {
|
|
3673
|
+
// no-op from a validation perspective
|
|
3674
|
+
if (s.discriminator?.mapping) {
|
|
3675
|
+
delete s.discriminator.mapping;
|
|
3676
|
+
}
|
|
3677
|
+
if (s.discriminator && !s.oneOf) {
|
|
3678
|
+
delete s.discriminator;
|
|
3679
|
+
}
|
|
3680
|
+
};
|
|
3672
3681
|
const minimumSchema = (originalSchema, oas) => {
|
|
3673
3682
|
const refToAdd = [];
|
|
3674
3683
|
const refAdded = [];
|
|
@@ -3676,10 +3685,6 @@ const minimumSchema = (originalSchema, oas) => {
|
|
|
3676
3685
|
if (s.$ref && !refToAdd.includes(s.$ref) && !refAdded.includes(s.$ref)) {
|
|
3677
3686
|
refToAdd.push(s.$ref);
|
|
3678
3687
|
}
|
|
3679
|
-
// no-op from a validation perspective
|
|
3680
|
-
if (s.discriminator?.mapping) {
|
|
3681
|
-
delete s.discriminator.mapping;
|
|
3682
|
-
}
|
|
3683
3688
|
};
|
|
3684
3689
|
const handleNullableSchema = (s) => {
|
|
3685
3690
|
if (s.$ref) {
|
|
@@ -3698,6 +3703,7 @@ const minimumSchema = (originalSchema, oas) => {
|
|
|
3698
3703
|
const schema = cloneDeep(originalSchema);
|
|
3699
3704
|
delete schema.description;
|
|
3700
3705
|
delete schema.example;
|
|
3706
|
+
traverse(schema, cleanupDiscriminators);
|
|
3701
3707
|
traverse(schema, collectReferences);
|
|
3702
3708
|
traverse(schema, handleNullableSchema);
|
|
3703
3709
|
traverse(schema, convertExclusiveMinMax);
|
|
@@ -3708,6 +3714,7 @@ const minimumSchema = (originalSchema, oas) => {
|
|
|
3708
3714
|
const subschema = cloneDeep(get$1(oas, path, {}));
|
|
3709
3715
|
delete subschema.description;
|
|
3710
3716
|
delete subschema.example;
|
|
3717
|
+
traverse(schema, cleanupDiscriminators);
|
|
3711
3718
|
traverse(subschema, collectReferences);
|
|
3712
3719
|
traverse(subschema, handleNullableSchema);
|
|
3713
3720
|
traverse(subschema, convertExclusiveMinMax);
|
|
@@ -7763,6 +7770,8 @@ function* compareReqSecurity(ajv, route, interaction, index, config) {
|
|
|
7763
7770
|
}
|
|
7764
7771
|
}
|
|
7765
7772
|
|
|
7773
|
+
const patternedStatus = (status) => `${Math.floor(status / 100)}XX`;
|
|
7774
|
+
|
|
7766
7775
|
const canValidate = (contentType = "") => {
|
|
7767
7776
|
return !!findMatchingType(contentType, ["application/json"]);
|
|
7768
7777
|
};
|
|
@@ -7772,9 +7781,9 @@ function* compareResBody(ajv, route, interaction, index, config) {
|
|
|
7772
7781
|
const { body, status } = interaction.response;
|
|
7773
7782
|
const requestHeaders = new Headers(interaction.request.headers);
|
|
7774
7783
|
const statusResponse = operation.responses?.[status];
|
|
7775
|
-
const
|
|
7776
|
-
|
|
7777
|
-
const response = statusResponse || defaultResponse;
|
|
7784
|
+
const patternedResponse = operation.responses?.[patternedStatus(status)];
|
|
7785
|
+
const defaultResponse = operation.responses?.["default"];
|
|
7786
|
+
const response = statusResponse || patternedResponse || defaultResponse;
|
|
7778
7787
|
if (!response) {
|
|
7779
7788
|
yield {
|
|
7780
7789
|
code: "response.status.unknown",
|
|
@@ -7802,7 +7811,7 @@ function* compareResBody(ajv, route, interaction, index, config) {
|
|
|
7802
7811
|
const schema = dereferencedResponse?.schema ||
|
|
7803
7812
|
getByContentType(dereferencedResponse.content || {}, contentType)?.schema;
|
|
7804
7813
|
const value = body;
|
|
7805
|
-
if (!statusResponse) {
|
|
7814
|
+
if (!statusResponse && !patternedResponse) {
|
|
7806
7815
|
yield {
|
|
7807
7816
|
code: "response.status.default",
|
|
7808
7817
|
message: `Response status code matched default response in spec file: ${status}`,
|
|
@@ -7869,7 +7878,9 @@ function* compareResBody(ajv, route, interaction, index, config) {
|
|
|
7869
7878
|
|
|
7870
7879
|
function* compareResHeader(ajv, route, interaction, index, _config) {
|
|
7871
7880
|
const { method, oas, operation, path } = route.store;
|
|
7872
|
-
const
|
|
7881
|
+
const { status } = interaction.response;
|
|
7882
|
+
const response = operation.responses[status] ||
|
|
7883
|
+
operation.responses[patternedStatus(status)] ||
|
|
7873
7884
|
operation.responses["default"];
|
|
7874
7885
|
// no response found
|
|
7875
7886
|
// -----------------
|
|
@@ -15156,44 +15167,6 @@ var uri = {};
|
|
|
15156
15167
|
|
|
15157
15168
|
var fastUri = {exports: {}};
|
|
15158
15169
|
|
|
15159
|
-
var scopedChars;
|
|
15160
|
-
var hasRequiredScopedChars;
|
|
15161
|
-
|
|
15162
|
-
function requireScopedChars () {
|
|
15163
|
-
if (hasRequiredScopedChars) return scopedChars;
|
|
15164
|
-
hasRequiredScopedChars = 1;
|
|
15165
|
-
|
|
15166
|
-
const HEX = {
|
|
15167
|
-
0: 0,
|
|
15168
|
-
1: 1,
|
|
15169
|
-
2: 2,
|
|
15170
|
-
3: 3,
|
|
15171
|
-
4: 4,
|
|
15172
|
-
5: 5,
|
|
15173
|
-
6: 6,
|
|
15174
|
-
7: 7,
|
|
15175
|
-
8: 8,
|
|
15176
|
-
9: 9,
|
|
15177
|
-
a: 10,
|
|
15178
|
-
A: 10,
|
|
15179
|
-
b: 11,
|
|
15180
|
-
B: 11,
|
|
15181
|
-
c: 12,
|
|
15182
|
-
C: 12,
|
|
15183
|
-
d: 13,
|
|
15184
|
-
D: 13,
|
|
15185
|
-
e: 14,
|
|
15186
|
-
E: 14,
|
|
15187
|
-
f: 15,
|
|
15188
|
-
F: 15
|
|
15189
|
-
};
|
|
15190
|
-
|
|
15191
|
-
scopedChars = {
|
|
15192
|
-
HEX
|
|
15193
|
-
};
|
|
15194
|
-
return scopedChars;
|
|
15195
|
-
}
|
|
15196
|
-
|
|
15197
15170
|
var utils;
|
|
15198
15171
|
var hasRequiredUtils;
|
|
15199
15172
|
|
|
@@ -15201,62 +15174,100 @@ function requireUtils () {
|
|
|
15201
15174
|
if (hasRequiredUtils) return utils;
|
|
15202
15175
|
hasRequiredUtils = 1;
|
|
15203
15176
|
|
|
15204
|
-
|
|
15177
|
+
/** @type {(value: string) => boolean} */
|
|
15178
|
+
const isUUID = RegExp.prototype.test.bind(/^[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}$/iu);
|
|
15205
15179
|
|
|
15206
|
-
|
|
15180
|
+
/** @type {(value: string) => boolean} */
|
|
15181
|
+
const isIPv4 = RegExp.prototype.test.bind(/^(?:(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)$/u);
|
|
15207
15182
|
|
|
15208
|
-
|
|
15209
|
-
|
|
15210
|
-
|
|
15211
|
-
|
|
15212
|
-
|
|
15213
|
-
|
|
15214
|
-
|
|
15215
|
-
|
|
15183
|
+
/**
|
|
15184
|
+
* @param {Array<string>} input
|
|
15185
|
+
* @returns {string}
|
|
15186
|
+
*/
|
|
15187
|
+
function stringArrayToHexStripped (input) {
|
|
15188
|
+
let acc = '';
|
|
15189
|
+
let code = 0;
|
|
15190
|
+
let i = 0;
|
|
15191
|
+
|
|
15192
|
+
for (i = 0; i < input.length; i++) {
|
|
15193
|
+
code = input[i].charCodeAt(0);
|
|
15194
|
+
if (code === 48) {
|
|
15195
|
+
continue
|
|
15196
|
+
}
|
|
15197
|
+
if (!((code >= 48 && code <= 57) || (code >= 65 && code <= 70) || (code >= 97 && code <= 102))) {
|
|
15198
|
+
return ''
|
|
15199
|
+
}
|
|
15200
|
+
acc += input[i];
|
|
15201
|
+
break
|
|
15202
|
+
}
|
|
15203
|
+
|
|
15204
|
+
for (i += 1; i < input.length; i++) {
|
|
15205
|
+
code = input[i].charCodeAt(0);
|
|
15206
|
+
if (!((code >= 48 && code <= 57) || (code >= 65 && code <= 70) || (code >= 97 && code <= 102))) {
|
|
15207
|
+
return ''
|
|
15208
|
+
}
|
|
15209
|
+
acc += input[i];
|
|
15216
15210
|
}
|
|
15211
|
+
return acc
|
|
15217
15212
|
}
|
|
15218
15213
|
|
|
15219
15214
|
/**
|
|
15220
|
-
* @
|
|
15221
|
-
* @
|
|
15222
|
-
* @
|
|
15215
|
+
* @typedef {Object} GetIPV6Result
|
|
15216
|
+
* @property {boolean} error - Indicates if there was an error parsing the IPv6 address.
|
|
15217
|
+
* @property {string} address - The parsed IPv6 address.
|
|
15218
|
+
* @property {string} [zone] - The zone identifier, if present.
|
|
15223
15219
|
*/
|
|
15224
|
-
|
|
15225
|
-
|
|
15226
|
-
|
|
15227
|
-
|
|
15228
|
-
|
|
15229
|
-
|
|
15230
|
-
|
|
15220
|
+
|
|
15221
|
+
/**
|
|
15222
|
+
* @param {string} value
|
|
15223
|
+
* @returns {boolean}
|
|
15224
|
+
*/
|
|
15225
|
+
const nonSimpleDomain = RegExp.prototype.test.bind(/[^!"$&'()*+,\-.;=_`a-z{}~]/u);
|
|
15226
|
+
|
|
15227
|
+
/**
|
|
15228
|
+
* @param {Array<string>} buffer
|
|
15229
|
+
* @returns {boolean}
|
|
15230
|
+
*/
|
|
15231
|
+
function consumeIsZone (buffer) {
|
|
15232
|
+
buffer.length = 0;
|
|
15233
|
+
return true
|
|
15234
|
+
}
|
|
15235
|
+
|
|
15236
|
+
/**
|
|
15237
|
+
* @param {Array<string>} buffer
|
|
15238
|
+
* @param {Array<string>} address
|
|
15239
|
+
* @param {GetIPV6Result} output
|
|
15240
|
+
* @returns {boolean}
|
|
15241
|
+
*/
|
|
15242
|
+
function consumeHextets (buffer, address, output) {
|
|
15243
|
+
if (buffer.length) {
|
|
15244
|
+
const hex = stringArrayToHexStripped(buffer);
|
|
15245
|
+
if (hex !== '') {
|
|
15246
|
+
address.push(hex);
|
|
15247
|
+
} else {
|
|
15248
|
+
output.error = true;
|
|
15249
|
+
return false
|
|
15250
|
+
}
|
|
15251
|
+
buffer.length = 0;
|
|
15231
15252
|
}
|
|
15232
|
-
|
|
15233
|
-
return acc
|
|
15253
|
+
return true
|
|
15234
15254
|
}
|
|
15235
15255
|
|
|
15256
|
+
/**
|
|
15257
|
+
* @param {string} input
|
|
15258
|
+
* @returns {GetIPV6Result}
|
|
15259
|
+
*/
|
|
15236
15260
|
function getIPV6 (input) {
|
|
15237
15261
|
let tokenCount = 0;
|
|
15238
15262
|
const output = { error: false, address: '', zone: '' };
|
|
15263
|
+
/** @type {Array<string>} */
|
|
15239
15264
|
const address = [];
|
|
15265
|
+
/** @type {Array<string>} */
|
|
15240
15266
|
const buffer = [];
|
|
15241
|
-
let isZone = false;
|
|
15242
15267
|
let endipv6Encountered = false;
|
|
15243
15268
|
let endIpv6 = false;
|
|
15244
15269
|
|
|
15245
|
-
|
|
15246
|
-
if (buffer.length) {
|
|
15247
|
-
if (isZone === false) {
|
|
15248
|
-
const hex = stringArrayToHexStripped(buffer);
|
|
15249
|
-
if (hex !== undefined) {
|
|
15250
|
-
address.push(hex);
|
|
15251
|
-
} else {
|
|
15252
|
-
output.error = true;
|
|
15253
|
-
return false
|
|
15254
|
-
}
|
|
15255
|
-
}
|
|
15256
|
-
buffer.length = 0;
|
|
15257
|
-
}
|
|
15258
|
-
return true
|
|
15259
|
-
}
|
|
15270
|
+
let consume = consumeHextets;
|
|
15260
15271
|
|
|
15261
15272
|
for (let i = 0; i < input.length; i++) {
|
|
15262
15273
|
const cursor = input[i];
|
|
@@ -15265,29 +15276,28 @@ function requireUtils () {
|
|
|
15265
15276
|
if (endipv6Encountered === true) {
|
|
15266
15277
|
endIpv6 = true;
|
|
15267
15278
|
}
|
|
15268
|
-
if (!consume()) { break }
|
|
15269
|
-
tokenCount
|
|
15270
|
-
address.push(':');
|
|
15271
|
-
if (tokenCount > 7) {
|
|
15279
|
+
if (!consume(buffer, address, output)) { break }
|
|
15280
|
+
if (++tokenCount > 7) {
|
|
15272
15281
|
// not valid
|
|
15273
15282
|
output.error = true;
|
|
15274
15283
|
break
|
|
15275
15284
|
}
|
|
15276
|
-
if (i
|
|
15285
|
+
if (i > 0 && input[i - 1] === ':') {
|
|
15277
15286
|
endipv6Encountered = true;
|
|
15278
15287
|
}
|
|
15288
|
+
address.push(':');
|
|
15279
15289
|
continue
|
|
15280
15290
|
} else if (cursor === '%') {
|
|
15281
|
-
if (!consume()) { break }
|
|
15291
|
+
if (!consume(buffer, address, output)) { break }
|
|
15282
15292
|
// switch to zone detection
|
|
15283
|
-
|
|
15293
|
+
consume = consumeIsZone;
|
|
15284
15294
|
} else {
|
|
15285
15295
|
buffer.push(cursor);
|
|
15286
15296
|
continue
|
|
15287
15297
|
}
|
|
15288
15298
|
}
|
|
15289
15299
|
if (buffer.length) {
|
|
15290
|
-
if (
|
|
15300
|
+
if (consume === consumeIsZone) {
|
|
15291
15301
|
output.zone = buffer.join('');
|
|
15292
15302
|
} else if (endIpv6) {
|
|
15293
15303
|
address.push(buffer.join(''));
|
|
@@ -15299,6 +15309,17 @@ function requireUtils () {
|
|
|
15299
15309
|
return output
|
|
15300
15310
|
}
|
|
15301
15311
|
|
|
15312
|
+
/**
|
|
15313
|
+
* @typedef {Object} NormalizeIPv6Result
|
|
15314
|
+
* @property {string} host - The normalized host.
|
|
15315
|
+
* @property {string} [escapedHost] - The escaped host.
|
|
15316
|
+
* @property {boolean} isIPV6 - Indicates if the host is an IPv6 address.
|
|
15317
|
+
*/
|
|
15318
|
+
|
|
15319
|
+
/**
|
|
15320
|
+
* @param {string} host
|
|
15321
|
+
* @returns {NormalizeIPv6Result}
|
|
15322
|
+
*/
|
|
15302
15323
|
function normalizeIPv6 (host) {
|
|
15303
15324
|
if (findToken(host, ':') < 2) { return { host, isIPV6: false } }
|
|
15304
15325
|
const ipv6 = getIPV6(host);
|
|
@@ -15310,35 +15331,17 @@ function requireUtils () {
|
|
|
15310
15331
|
newHost += '%' + ipv6.zone;
|
|
15311
15332
|
escapedHost += '%25' + ipv6.zone;
|
|
15312
15333
|
}
|
|
15313
|
-
return { host: newHost,
|
|
15334
|
+
return { host: newHost, isIPV6: true, escapedHost }
|
|
15314
15335
|
} else {
|
|
15315
15336
|
return { host, isIPV6: false }
|
|
15316
15337
|
}
|
|
15317
15338
|
}
|
|
15318
15339
|
|
|
15319
|
-
|
|
15320
|
-
|
|
15321
|
-
|
|
15322
|
-
|
|
15323
|
-
|
|
15324
|
-
const c = str[i];
|
|
15325
|
-
if (c === '0' && skip) {
|
|
15326
|
-
if ((i + 1 <= l && str[i + 1] === token) || i + 1 === l) {
|
|
15327
|
-
out += c;
|
|
15328
|
-
skip = false;
|
|
15329
|
-
}
|
|
15330
|
-
} else {
|
|
15331
|
-
if (c === token) {
|
|
15332
|
-
skip = true;
|
|
15333
|
-
} else {
|
|
15334
|
-
skip = false;
|
|
15335
|
-
}
|
|
15336
|
-
out += c;
|
|
15337
|
-
}
|
|
15338
|
-
}
|
|
15339
|
-
return out
|
|
15340
|
-
}
|
|
15341
|
-
|
|
15340
|
+
/**
|
|
15341
|
+
* @param {string} str
|
|
15342
|
+
* @param {string} token
|
|
15343
|
+
* @returns {number}
|
|
15344
|
+
*/
|
|
15342
15345
|
function findToken (str, token) {
|
|
15343
15346
|
let ind = 0;
|
|
15344
15347
|
for (let i = 0; i < str.length; i++) {
|
|
@@ -15347,98 +15350,160 @@ function requireUtils () {
|
|
|
15347
15350
|
return ind
|
|
15348
15351
|
}
|
|
15349
15352
|
|
|
15350
|
-
|
|
15351
|
-
|
|
15352
|
-
|
|
15353
|
-
|
|
15354
|
-
|
|
15355
|
-
|
|
15353
|
+
/**
|
|
15354
|
+
* @param {string} path
|
|
15355
|
+
* @returns {string}
|
|
15356
|
+
*
|
|
15357
|
+
* @see https://datatracker.ietf.org/doc/html/rfc3986#section-5.2.4
|
|
15358
|
+
*/
|
|
15359
|
+
function removeDotSegments (path) {
|
|
15360
|
+
let input = path;
|
|
15356
15361
|
const output = [];
|
|
15362
|
+
let nextSlash = -1;
|
|
15363
|
+
let len = 0;
|
|
15357
15364
|
|
|
15358
|
-
|
|
15359
|
-
|
|
15360
|
-
|
|
15361
|
-
|
|
15362
|
-
|
|
15363
|
-
|
|
15364
|
-
|
|
15365
|
-
|
|
15366
|
-
} else if (input === '.' || input === '..') {
|
|
15367
|
-
input = '';
|
|
15368
|
-
} else {
|
|
15369
|
-
const im = input.match(RDS5);
|
|
15370
|
-
if (im) {
|
|
15371
|
-
const s = im[0];
|
|
15372
|
-
input = input.slice(s.length);
|
|
15373
|
-
output.push(s);
|
|
15365
|
+
// eslint-disable-next-line no-cond-assign
|
|
15366
|
+
while (len = input.length) {
|
|
15367
|
+
if (len === 1) {
|
|
15368
|
+
if (input === '.') {
|
|
15369
|
+
break
|
|
15370
|
+
} else if (input === '/') {
|
|
15371
|
+
output.push('/');
|
|
15372
|
+
break
|
|
15374
15373
|
} else {
|
|
15375
|
-
|
|
15374
|
+
output.push(input);
|
|
15375
|
+
break
|
|
15376
|
+
}
|
|
15377
|
+
} else if (len === 2) {
|
|
15378
|
+
if (input[0] === '.') {
|
|
15379
|
+
if (input[1] === '.') {
|
|
15380
|
+
break
|
|
15381
|
+
} else if (input[1] === '/') {
|
|
15382
|
+
input = input.slice(2);
|
|
15383
|
+
continue
|
|
15384
|
+
}
|
|
15385
|
+
} else if (input[0] === '/') {
|
|
15386
|
+
if (input[1] === '.' || input[1] === '/') {
|
|
15387
|
+
output.push('/');
|
|
15388
|
+
break
|
|
15389
|
+
}
|
|
15390
|
+
}
|
|
15391
|
+
} else if (len === 3) {
|
|
15392
|
+
if (input === '/..') {
|
|
15393
|
+
if (output.length !== 0) {
|
|
15394
|
+
output.pop();
|
|
15395
|
+
}
|
|
15396
|
+
output.push('/');
|
|
15397
|
+
break
|
|
15398
|
+
}
|
|
15399
|
+
}
|
|
15400
|
+
if (input[0] === '.') {
|
|
15401
|
+
if (input[1] === '.') {
|
|
15402
|
+
if (input[2] === '/') {
|
|
15403
|
+
input = input.slice(3);
|
|
15404
|
+
continue
|
|
15405
|
+
}
|
|
15406
|
+
} else if (input[1] === '/') {
|
|
15407
|
+
input = input.slice(2);
|
|
15408
|
+
continue
|
|
15409
|
+
}
|
|
15410
|
+
} else if (input[0] === '/') {
|
|
15411
|
+
if (input[1] === '.') {
|
|
15412
|
+
if (input[2] === '/') {
|
|
15413
|
+
input = input.slice(2);
|
|
15414
|
+
continue
|
|
15415
|
+
} else if (input[2] === '.') {
|
|
15416
|
+
if (input[3] === '/') {
|
|
15417
|
+
input = input.slice(3);
|
|
15418
|
+
if (output.length !== 0) {
|
|
15419
|
+
output.pop();
|
|
15420
|
+
}
|
|
15421
|
+
continue
|
|
15422
|
+
}
|
|
15423
|
+
}
|
|
15376
15424
|
}
|
|
15377
15425
|
}
|
|
15426
|
+
|
|
15427
|
+
// Rule 2E: Move normal path segment to output
|
|
15428
|
+
if ((nextSlash = input.indexOf('/', 1)) === -1) {
|
|
15429
|
+
output.push(input);
|
|
15430
|
+
break
|
|
15431
|
+
} else {
|
|
15432
|
+
output.push(input.slice(0, nextSlash));
|
|
15433
|
+
input = input.slice(nextSlash);
|
|
15434
|
+
}
|
|
15378
15435
|
}
|
|
15436
|
+
|
|
15379
15437
|
return output.join('')
|
|
15380
15438
|
}
|
|
15381
15439
|
|
|
15382
|
-
|
|
15440
|
+
/**
|
|
15441
|
+
* @param {import('../types/index').URIComponent} component
|
|
15442
|
+
* @param {boolean} esc
|
|
15443
|
+
* @returns {import('../types/index').URIComponent}
|
|
15444
|
+
*/
|
|
15445
|
+
function normalizeComponentEncoding (component, esc) {
|
|
15383
15446
|
const func = esc !== true ? escape : unescape;
|
|
15384
|
-
if (
|
|
15385
|
-
|
|
15447
|
+
if (component.scheme !== undefined) {
|
|
15448
|
+
component.scheme = func(component.scheme);
|
|
15386
15449
|
}
|
|
15387
|
-
if (
|
|
15388
|
-
|
|
15450
|
+
if (component.userinfo !== undefined) {
|
|
15451
|
+
component.userinfo = func(component.userinfo);
|
|
15389
15452
|
}
|
|
15390
|
-
if (
|
|
15391
|
-
|
|
15453
|
+
if (component.host !== undefined) {
|
|
15454
|
+
component.host = func(component.host);
|
|
15392
15455
|
}
|
|
15393
|
-
if (
|
|
15394
|
-
|
|
15456
|
+
if (component.path !== undefined) {
|
|
15457
|
+
component.path = func(component.path);
|
|
15395
15458
|
}
|
|
15396
|
-
if (
|
|
15397
|
-
|
|
15459
|
+
if (component.query !== undefined) {
|
|
15460
|
+
component.query = func(component.query);
|
|
15398
15461
|
}
|
|
15399
|
-
if (
|
|
15400
|
-
|
|
15462
|
+
if (component.fragment !== undefined) {
|
|
15463
|
+
component.fragment = func(component.fragment);
|
|
15401
15464
|
}
|
|
15402
|
-
return
|
|
15465
|
+
return component
|
|
15403
15466
|
}
|
|
15404
15467
|
|
|
15405
|
-
|
|
15468
|
+
/**
|
|
15469
|
+
* @param {import('../types/index').URIComponent} component
|
|
15470
|
+
* @returns {string|undefined}
|
|
15471
|
+
*/
|
|
15472
|
+
function recomposeAuthority (component) {
|
|
15406
15473
|
const uriTokens = [];
|
|
15407
15474
|
|
|
15408
|
-
if (
|
|
15409
|
-
uriTokens.push(
|
|
15475
|
+
if (component.userinfo !== undefined) {
|
|
15476
|
+
uriTokens.push(component.userinfo);
|
|
15410
15477
|
uriTokens.push('@');
|
|
15411
15478
|
}
|
|
15412
15479
|
|
|
15413
|
-
if (
|
|
15414
|
-
let host = unescape(
|
|
15415
|
-
|
|
15416
|
-
|
|
15417
|
-
if (ipV4res.isIPV4) {
|
|
15418
|
-
host = ipV4res.host;
|
|
15419
|
-
} else {
|
|
15420
|
-
const ipV6res = normalizeIPv6(ipV4res.host);
|
|
15480
|
+
if (component.host !== undefined) {
|
|
15481
|
+
let host = unescape(component.host);
|
|
15482
|
+
if (!isIPv4(host)) {
|
|
15483
|
+
const ipV6res = normalizeIPv6(host);
|
|
15421
15484
|
if (ipV6res.isIPV6 === true) {
|
|
15422
15485
|
host = `[${ipV6res.escapedHost}]`;
|
|
15423
15486
|
} else {
|
|
15424
|
-
host =
|
|
15487
|
+
host = component.host;
|
|
15425
15488
|
}
|
|
15426
15489
|
}
|
|
15427
15490
|
uriTokens.push(host);
|
|
15428
15491
|
}
|
|
15429
15492
|
|
|
15430
|
-
if (typeof
|
|
15493
|
+
if (typeof component.port === 'number' || typeof component.port === 'string') {
|
|
15431
15494
|
uriTokens.push(':');
|
|
15432
|
-
uriTokens.push(String(
|
|
15495
|
+
uriTokens.push(String(component.port));
|
|
15433
15496
|
}
|
|
15434
15497
|
|
|
15435
15498
|
return uriTokens.length ? uriTokens.join('') : undefined
|
|
15436
15499
|
}
|
|
15437
15500
|
utils = {
|
|
15501
|
+
nonSimpleDomain,
|
|
15438
15502
|
recomposeAuthority,
|
|
15439
15503
|
normalizeComponentEncoding,
|
|
15440
15504
|
removeDotSegments,
|
|
15441
|
-
|
|
15505
|
+
isIPv4,
|
|
15506
|
+
isUUID,
|
|
15442
15507
|
normalizeIPv6,
|
|
15443
15508
|
stringArrayToHexStripped
|
|
15444
15509
|
};
|
|
@@ -15452,192 +15517,271 @@ function requireSchemes () {
|
|
|
15452
15517
|
if (hasRequiredSchemes) return schemes;
|
|
15453
15518
|
hasRequiredSchemes = 1;
|
|
15454
15519
|
|
|
15455
|
-
const
|
|
15520
|
+
const { isUUID } = requireUtils();
|
|
15456
15521
|
const URN_REG = /([\da-z][\d\-a-z]{0,31}):((?:[\w!$'()*+,\-.:;=@]|%[\da-f]{2})+)/iu;
|
|
15457
15522
|
|
|
15458
|
-
|
|
15459
|
-
|
|
15523
|
+
const supportedSchemeNames = /** @type {const} */ (['http', 'https', 'ws',
|
|
15524
|
+
'wss', 'urn', 'urn:uuid']);
|
|
15525
|
+
|
|
15526
|
+
/** @typedef {supportedSchemeNames[number]} SchemeName */
|
|
15527
|
+
|
|
15528
|
+
/**
|
|
15529
|
+
* @param {string} name
|
|
15530
|
+
* @returns {name is SchemeName}
|
|
15531
|
+
*/
|
|
15532
|
+
function isValidSchemeName (name) {
|
|
15533
|
+
return supportedSchemeNames.indexOf(/** @type {*} */ (name)) !== -1
|
|
15534
|
+
}
|
|
15535
|
+
|
|
15536
|
+
/**
|
|
15537
|
+
* @callback SchemeFn
|
|
15538
|
+
* @param {import('../types/index').URIComponent} component
|
|
15539
|
+
* @param {import('../types/index').Options} options
|
|
15540
|
+
* @returns {import('../types/index').URIComponent}
|
|
15541
|
+
*/
|
|
15542
|
+
|
|
15543
|
+
/**
|
|
15544
|
+
* @typedef {Object} SchemeHandler
|
|
15545
|
+
* @property {SchemeName} scheme - The scheme name.
|
|
15546
|
+
* @property {boolean} [domainHost] - Indicates if the scheme supports domain hosts.
|
|
15547
|
+
* @property {SchemeFn} parse - Function to parse the URI component for this scheme.
|
|
15548
|
+
* @property {SchemeFn} serialize - Function to serialize the URI component for this scheme.
|
|
15549
|
+
* @property {boolean} [skipNormalize] - Indicates if normalization should be skipped for this scheme.
|
|
15550
|
+
* @property {boolean} [absolutePath] - Indicates if the scheme uses absolute paths.
|
|
15551
|
+
* @property {boolean} [unicodeSupport] - Indicates if the scheme supports Unicode.
|
|
15552
|
+
*/
|
|
15553
|
+
|
|
15554
|
+
/**
|
|
15555
|
+
* @param {import('../types/index').URIComponent} wsComponent
|
|
15556
|
+
* @returns {boolean}
|
|
15557
|
+
*/
|
|
15558
|
+
function wsIsSecure (wsComponent) {
|
|
15559
|
+
if (wsComponent.secure === true) {
|
|
15560
|
+
return true
|
|
15561
|
+
} else if (wsComponent.secure === false) {
|
|
15562
|
+
return false
|
|
15563
|
+
} else if (wsComponent.scheme) {
|
|
15564
|
+
return (
|
|
15565
|
+
wsComponent.scheme.length === 3 &&
|
|
15566
|
+
(wsComponent.scheme[0] === 'w' || wsComponent.scheme[0] === 'W') &&
|
|
15567
|
+
(wsComponent.scheme[1] === 's' || wsComponent.scheme[1] === 'S') &&
|
|
15568
|
+
(wsComponent.scheme[2] === 's' || wsComponent.scheme[2] === 'S')
|
|
15569
|
+
)
|
|
15570
|
+
} else {
|
|
15571
|
+
return false
|
|
15572
|
+
}
|
|
15460
15573
|
}
|
|
15461
15574
|
|
|
15462
|
-
|
|
15463
|
-
|
|
15464
|
-
|
|
15575
|
+
/** @type {SchemeFn} */
|
|
15576
|
+
function httpParse (component) {
|
|
15577
|
+
if (!component.host) {
|
|
15578
|
+
component.error = component.error || 'HTTP URIs must have a host.';
|
|
15465
15579
|
}
|
|
15466
15580
|
|
|
15467
|
-
return
|
|
15581
|
+
return component
|
|
15468
15582
|
}
|
|
15469
15583
|
|
|
15470
|
-
|
|
15471
|
-
|
|
15584
|
+
/** @type {SchemeFn} */
|
|
15585
|
+
function httpSerialize (component) {
|
|
15586
|
+
const secure = String(component.scheme).toLowerCase() === 'https';
|
|
15472
15587
|
|
|
15473
15588
|
// normalize the default port
|
|
15474
|
-
if (
|
|
15475
|
-
|
|
15589
|
+
if (component.port === (secure ? 443 : 80) || component.port === '') {
|
|
15590
|
+
component.port = undefined;
|
|
15476
15591
|
}
|
|
15477
15592
|
|
|
15478
15593
|
// normalize the empty path
|
|
15479
|
-
if (!
|
|
15480
|
-
|
|
15594
|
+
if (!component.path) {
|
|
15595
|
+
component.path = '/';
|
|
15481
15596
|
}
|
|
15482
15597
|
|
|
15483
15598
|
// NOTE: We do not parse query strings for HTTP URIs
|
|
15484
15599
|
// as WWW Form Url Encoded query strings are part of the HTML4+ spec,
|
|
15485
15600
|
// and not the HTTP spec.
|
|
15486
15601
|
|
|
15487
|
-
return
|
|
15602
|
+
return component
|
|
15488
15603
|
}
|
|
15489
15604
|
|
|
15490
|
-
|
|
15605
|
+
/** @type {SchemeFn} */
|
|
15606
|
+
function wsParse (wsComponent) {
|
|
15491
15607
|
// indicate if the secure flag is set
|
|
15492
|
-
|
|
15608
|
+
wsComponent.secure = wsIsSecure(wsComponent);
|
|
15493
15609
|
|
|
15494
15610
|
// construct resouce name
|
|
15495
|
-
|
|
15496
|
-
|
|
15497
|
-
|
|
15611
|
+
wsComponent.resourceName = (wsComponent.path || '/') + (wsComponent.query ? '?' + wsComponent.query : '');
|
|
15612
|
+
wsComponent.path = undefined;
|
|
15613
|
+
wsComponent.query = undefined;
|
|
15498
15614
|
|
|
15499
|
-
return
|
|
15615
|
+
return wsComponent
|
|
15500
15616
|
}
|
|
15501
15617
|
|
|
15502
|
-
|
|
15618
|
+
/** @type {SchemeFn} */
|
|
15619
|
+
function wsSerialize (wsComponent) {
|
|
15503
15620
|
// normalize the default port
|
|
15504
|
-
if (
|
|
15505
|
-
|
|
15621
|
+
if (wsComponent.port === (wsIsSecure(wsComponent) ? 443 : 80) || wsComponent.port === '') {
|
|
15622
|
+
wsComponent.port = undefined;
|
|
15506
15623
|
}
|
|
15507
15624
|
|
|
15508
15625
|
// ensure scheme matches secure flag
|
|
15509
|
-
if (typeof
|
|
15510
|
-
|
|
15511
|
-
|
|
15626
|
+
if (typeof wsComponent.secure === 'boolean') {
|
|
15627
|
+
wsComponent.scheme = (wsComponent.secure ? 'wss' : 'ws');
|
|
15628
|
+
wsComponent.secure = undefined;
|
|
15512
15629
|
}
|
|
15513
15630
|
|
|
15514
15631
|
// reconstruct path from resource name
|
|
15515
|
-
if (
|
|
15516
|
-
const [path, query] =
|
|
15517
|
-
|
|
15518
|
-
|
|
15519
|
-
|
|
15632
|
+
if (wsComponent.resourceName) {
|
|
15633
|
+
const [path, query] = wsComponent.resourceName.split('?');
|
|
15634
|
+
wsComponent.path = (path && path !== '/' ? path : undefined);
|
|
15635
|
+
wsComponent.query = query;
|
|
15636
|
+
wsComponent.resourceName = undefined;
|
|
15520
15637
|
}
|
|
15521
15638
|
|
|
15522
15639
|
// forbid fragment component
|
|
15523
|
-
|
|
15640
|
+
wsComponent.fragment = undefined;
|
|
15524
15641
|
|
|
15525
|
-
return
|
|
15642
|
+
return wsComponent
|
|
15526
15643
|
}
|
|
15527
15644
|
|
|
15528
|
-
|
|
15529
|
-
|
|
15530
|
-
|
|
15531
|
-
|
|
15645
|
+
/** @type {SchemeFn} */
|
|
15646
|
+
function urnParse (urnComponent, options) {
|
|
15647
|
+
if (!urnComponent.path) {
|
|
15648
|
+
urnComponent.error = 'URN can not be parsed';
|
|
15649
|
+
return urnComponent
|
|
15532
15650
|
}
|
|
15533
|
-
const matches =
|
|
15651
|
+
const matches = urnComponent.path.match(URN_REG);
|
|
15534
15652
|
if (matches) {
|
|
15535
|
-
const scheme = options.scheme ||
|
|
15536
|
-
|
|
15537
|
-
|
|
15538
|
-
const urnScheme = `${scheme}:${options.nid ||
|
|
15539
|
-
const schemeHandler =
|
|
15540
|
-
|
|
15653
|
+
const scheme = options.scheme || urnComponent.scheme || 'urn';
|
|
15654
|
+
urnComponent.nid = matches[1].toLowerCase();
|
|
15655
|
+
urnComponent.nss = matches[2];
|
|
15656
|
+
const urnScheme = `${scheme}:${options.nid || urnComponent.nid}`;
|
|
15657
|
+
const schemeHandler = getSchemeHandler(urnScheme);
|
|
15658
|
+
urnComponent.path = undefined;
|
|
15541
15659
|
|
|
15542
15660
|
if (schemeHandler) {
|
|
15543
|
-
|
|
15661
|
+
urnComponent = schemeHandler.parse(urnComponent, options);
|
|
15544
15662
|
}
|
|
15545
15663
|
} else {
|
|
15546
|
-
|
|
15664
|
+
urnComponent.error = urnComponent.error || 'URN can not be parsed.';
|
|
15547
15665
|
}
|
|
15548
15666
|
|
|
15549
|
-
return
|
|
15667
|
+
return urnComponent
|
|
15550
15668
|
}
|
|
15551
15669
|
|
|
15552
|
-
|
|
15553
|
-
|
|
15554
|
-
|
|
15670
|
+
/** @type {SchemeFn} */
|
|
15671
|
+
function urnSerialize (urnComponent, options) {
|
|
15672
|
+
if (urnComponent.nid === undefined) {
|
|
15673
|
+
throw new Error('URN without nid cannot be serialized')
|
|
15674
|
+
}
|
|
15675
|
+
const scheme = options.scheme || urnComponent.scheme || 'urn';
|
|
15676
|
+
const nid = urnComponent.nid.toLowerCase();
|
|
15555
15677
|
const urnScheme = `${scheme}:${options.nid || nid}`;
|
|
15556
|
-
const schemeHandler =
|
|
15678
|
+
const schemeHandler = getSchemeHandler(urnScheme);
|
|
15557
15679
|
|
|
15558
15680
|
if (schemeHandler) {
|
|
15559
|
-
|
|
15681
|
+
urnComponent = schemeHandler.serialize(urnComponent, options);
|
|
15560
15682
|
}
|
|
15561
15683
|
|
|
15562
|
-
const
|
|
15563
|
-
const nss =
|
|
15564
|
-
|
|
15684
|
+
const uriComponent = urnComponent;
|
|
15685
|
+
const nss = urnComponent.nss;
|
|
15686
|
+
uriComponent.path = `${nid || options.nid}:${nss}`;
|
|
15565
15687
|
|
|
15566
15688
|
options.skipEscape = true;
|
|
15567
|
-
return
|
|
15689
|
+
return uriComponent
|
|
15568
15690
|
}
|
|
15569
15691
|
|
|
15570
|
-
|
|
15571
|
-
|
|
15572
|
-
|
|
15573
|
-
|
|
15692
|
+
/** @type {SchemeFn} */
|
|
15693
|
+
function urnuuidParse (urnComponent, options) {
|
|
15694
|
+
const uuidComponent = urnComponent;
|
|
15695
|
+
uuidComponent.uuid = uuidComponent.nss;
|
|
15696
|
+
uuidComponent.nss = undefined;
|
|
15574
15697
|
|
|
15575
|
-
if (!options.tolerant && (!
|
|
15576
|
-
|
|
15698
|
+
if (!options.tolerant && (!uuidComponent.uuid || !isUUID(uuidComponent.uuid))) {
|
|
15699
|
+
uuidComponent.error = uuidComponent.error || 'UUID is not valid.';
|
|
15577
15700
|
}
|
|
15578
15701
|
|
|
15579
|
-
return
|
|
15702
|
+
return uuidComponent
|
|
15580
15703
|
}
|
|
15581
15704
|
|
|
15582
|
-
|
|
15583
|
-
|
|
15705
|
+
/** @type {SchemeFn} */
|
|
15706
|
+
function urnuuidSerialize (uuidComponent) {
|
|
15707
|
+
const urnComponent = uuidComponent;
|
|
15584
15708
|
// normalize UUID
|
|
15585
|
-
|
|
15586
|
-
return
|
|
15709
|
+
urnComponent.nss = (uuidComponent.uuid || '').toLowerCase();
|
|
15710
|
+
return urnComponent
|
|
15587
15711
|
}
|
|
15588
15712
|
|
|
15589
|
-
const http = {
|
|
15713
|
+
const http = /** @type {SchemeHandler} */ ({
|
|
15590
15714
|
scheme: 'http',
|
|
15591
15715
|
domainHost: true,
|
|
15592
15716
|
parse: httpParse,
|
|
15593
15717
|
serialize: httpSerialize
|
|
15594
|
-
};
|
|
15718
|
+
});
|
|
15595
15719
|
|
|
15596
|
-
const https = {
|
|
15720
|
+
const https = /** @type {SchemeHandler} */ ({
|
|
15597
15721
|
scheme: 'https',
|
|
15598
15722
|
domainHost: http.domainHost,
|
|
15599
15723
|
parse: httpParse,
|
|
15600
15724
|
serialize: httpSerialize
|
|
15601
|
-
};
|
|
15725
|
+
});
|
|
15602
15726
|
|
|
15603
|
-
const ws = {
|
|
15727
|
+
const ws = /** @type {SchemeHandler} */ ({
|
|
15604
15728
|
scheme: 'ws',
|
|
15605
15729
|
domainHost: true,
|
|
15606
15730
|
parse: wsParse,
|
|
15607
15731
|
serialize: wsSerialize
|
|
15608
|
-
};
|
|
15732
|
+
});
|
|
15609
15733
|
|
|
15610
|
-
const wss = {
|
|
15734
|
+
const wss = /** @type {SchemeHandler} */ ({
|
|
15611
15735
|
scheme: 'wss',
|
|
15612
15736
|
domainHost: ws.domainHost,
|
|
15613
15737
|
parse: ws.parse,
|
|
15614
15738
|
serialize: ws.serialize
|
|
15615
|
-
};
|
|
15739
|
+
});
|
|
15616
15740
|
|
|
15617
|
-
const urn = {
|
|
15741
|
+
const urn = /** @type {SchemeHandler} */ ({
|
|
15618
15742
|
scheme: 'urn',
|
|
15619
15743
|
parse: urnParse,
|
|
15620
15744
|
serialize: urnSerialize,
|
|
15621
15745
|
skipNormalize: true
|
|
15622
|
-
};
|
|
15746
|
+
});
|
|
15623
15747
|
|
|
15624
|
-
const urnuuid = {
|
|
15748
|
+
const urnuuid = /** @type {SchemeHandler} */ ({
|
|
15625
15749
|
scheme: 'urn:uuid',
|
|
15626
15750
|
parse: urnuuidParse,
|
|
15627
15751
|
serialize: urnuuidSerialize,
|
|
15628
15752
|
skipNormalize: true
|
|
15629
|
-
};
|
|
15753
|
+
});
|
|
15630
15754
|
|
|
15631
|
-
const SCHEMES = {
|
|
15755
|
+
const SCHEMES = /** @type {Record<SchemeName, SchemeHandler>} */ ({
|
|
15632
15756
|
http,
|
|
15633
15757
|
https,
|
|
15634
15758
|
ws,
|
|
15635
15759
|
wss,
|
|
15636
15760
|
urn,
|
|
15637
15761
|
'urn:uuid': urnuuid
|
|
15638
|
-
};
|
|
15762
|
+
});
|
|
15763
|
+
|
|
15764
|
+
Object.setPrototypeOf(SCHEMES, null);
|
|
15765
|
+
|
|
15766
|
+
/**
|
|
15767
|
+
* @param {string|undefined} scheme
|
|
15768
|
+
* @returns {SchemeHandler|undefined}
|
|
15769
|
+
*/
|
|
15770
|
+
function getSchemeHandler (scheme) {
|
|
15771
|
+
return (
|
|
15772
|
+
scheme && (
|
|
15773
|
+
SCHEMES[/** @type {SchemeName} */ (scheme)] ||
|
|
15774
|
+
SCHEMES[/** @type {SchemeName} */(scheme.toLowerCase())])
|
|
15775
|
+
) ||
|
|
15776
|
+
undefined
|
|
15777
|
+
}
|
|
15639
15778
|
|
|
15640
|
-
schemes =
|
|
15779
|
+
schemes = {
|
|
15780
|
+
wsIsSecure,
|
|
15781
|
+
SCHEMES,
|
|
15782
|
+
isValidSchemeName,
|
|
15783
|
+
getSchemeHandler,
|
|
15784
|
+
};
|
|
15641
15785
|
return schemes;
|
|
15642
15786
|
}
|
|
15643
15787
|
|
|
@@ -15647,29 +15791,50 @@ function requireFastUri () {
|
|
|
15647
15791
|
if (hasRequiredFastUri) return fastUri.exports;
|
|
15648
15792
|
hasRequiredFastUri = 1;
|
|
15649
15793
|
|
|
15650
|
-
const { normalizeIPv6,
|
|
15651
|
-
const SCHEMES = requireSchemes();
|
|
15794
|
+
const { normalizeIPv6, removeDotSegments, recomposeAuthority, normalizeComponentEncoding, isIPv4, nonSimpleDomain } = requireUtils();
|
|
15795
|
+
const { SCHEMES, getSchemeHandler } = requireSchemes();
|
|
15652
15796
|
|
|
15797
|
+
/**
|
|
15798
|
+
* @template {import('./types/index').URIComponent|string} T
|
|
15799
|
+
* @param {T} uri
|
|
15800
|
+
* @param {import('./types/index').Options} [options]
|
|
15801
|
+
* @returns {T}
|
|
15802
|
+
*/
|
|
15653
15803
|
function normalize (uri, options) {
|
|
15654
15804
|
if (typeof uri === 'string') {
|
|
15655
|
-
uri = serialize(parse(uri, options), options);
|
|
15805
|
+
uri = /** @type {T} */ (serialize(parse(uri, options), options));
|
|
15656
15806
|
} else if (typeof uri === 'object') {
|
|
15657
|
-
uri = parse(serialize(uri, options), options);
|
|
15807
|
+
uri = /** @type {T} */ (parse(serialize(uri, options), options));
|
|
15658
15808
|
}
|
|
15659
15809
|
return uri
|
|
15660
15810
|
}
|
|
15661
15811
|
|
|
15812
|
+
/**
|
|
15813
|
+
* @param {string} baseURI
|
|
15814
|
+
* @param {string} relativeURI
|
|
15815
|
+
* @param {import('./types/index').Options} [options]
|
|
15816
|
+
* @returns {string}
|
|
15817
|
+
*/
|
|
15662
15818
|
function resolve (baseURI, relativeURI, options) {
|
|
15663
|
-
const schemelessOptions = Object.assign({ scheme: 'null' }, options);
|
|
15664
|
-
const resolved =
|
|
15665
|
-
|
|
15819
|
+
const schemelessOptions = options ? Object.assign({ scheme: 'null' }, options) : { scheme: 'null' };
|
|
15820
|
+
const resolved = resolveComponent(parse(baseURI, schemelessOptions), parse(relativeURI, schemelessOptions), schemelessOptions, true);
|
|
15821
|
+
schemelessOptions.skipEscape = true;
|
|
15822
|
+
return serialize(resolved, schemelessOptions)
|
|
15666
15823
|
}
|
|
15667
15824
|
|
|
15668
|
-
|
|
15825
|
+
/**
|
|
15826
|
+
* @param {import ('./types/index').URIComponent} base
|
|
15827
|
+
* @param {import ('./types/index').URIComponent} relative
|
|
15828
|
+
* @param {import('./types/index').Options} [options]
|
|
15829
|
+
* @param {boolean} [skipNormalization=false]
|
|
15830
|
+
* @returns {import ('./types/index').URIComponent}
|
|
15831
|
+
*/
|
|
15832
|
+
function resolveComponent (base, relative, options, skipNormalization) {
|
|
15833
|
+
/** @type {import('./types/index').URIComponent} */
|
|
15669
15834
|
const target = {};
|
|
15670
15835
|
if (!skipNormalization) {
|
|
15671
|
-
base = parse(serialize(base, options), options); // normalize base
|
|
15672
|
-
relative = parse(serialize(relative, options), options); // normalize relative
|
|
15836
|
+
base = parse(serialize(base, options), options); // normalize base component
|
|
15837
|
+
relative = parse(serialize(relative, options), options); // normalize relative component
|
|
15673
15838
|
}
|
|
15674
15839
|
options = options || {};
|
|
15675
15840
|
|
|
@@ -15698,7 +15863,7 @@ function requireFastUri () {
|
|
|
15698
15863
|
target.query = base.query;
|
|
15699
15864
|
}
|
|
15700
15865
|
} else {
|
|
15701
|
-
if (relative.path
|
|
15866
|
+
if (relative.path[0] === '/') {
|
|
15702
15867
|
target.path = removeDotSegments(relative.path);
|
|
15703
15868
|
} else {
|
|
15704
15869
|
if ((base.userinfo !== undefined || base.host !== undefined || base.port !== undefined) && !base.path) {
|
|
@@ -15725,6 +15890,12 @@ function requireFastUri () {
|
|
|
15725
15890
|
return target
|
|
15726
15891
|
}
|
|
15727
15892
|
|
|
15893
|
+
/**
|
|
15894
|
+
* @param {import ('./types/index').URIComponent|string} uriA
|
|
15895
|
+
* @param {import ('./types/index').URIComponent|string} uriB
|
|
15896
|
+
* @param {import ('./types/index').Options} options
|
|
15897
|
+
* @returns {boolean}
|
|
15898
|
+
*/
|
|
15728
15899
|
function equal (uriA, uriB, options) {
|
|
15729
15900
|
if (typeof uriA === 'string') {
|
|
15730
15901
|
uriA = unescape(uriA);
|
|
@@ -15743,8 +15914,13 @@ function requireFastUri () {
|
|
|
15743
15914
|
return uriA.toLowerCase() === uriB.toLowerCase()
|
|
15744
15915
|
}
|
|
15745
15916
|
|
|
15917
|
+
/**
|
|
15918
|
+
* @param {Readonly<import('./types/index').URIComponent>} cmpts
|
|
15919
|
+
* @param {import('./types/index').Options} [opts]
|
|
15920
|
+
* @returns {string}
|
|
15921
|
+
*/
|
|
15746
15922
|
function serialize (cmpts, opts) {
|
|
15747
|
-
const
|
|
15923
|
+
const component = {
|
|
15748
15924
|
host: cmpts.host,
|
|
15749
15925
|
scheme: cmpts.scheme,
|
|
15750
15926
|
userinfo: cmpts.userinfo,
|
|
@@ -15764,28 +15940,28 @@ function requireFastUri () {
|
|
|
15764
15940
|
const uriTokens = [];
|
|
15765
15941
|
|
|
15766
15942
|
// find scheme handler
|
|
15767
|
-
const schemeHandler =
|
|
15943
|
+
const schemeHandler = getSchemeHandler(options.scheme || component.scheme);
|
|
15768
15944
|
|
|
15769
15945
|
// perform scheme specific serialization
|
|
15770
|
-
if (schemeHandler && schemeHandler.serialize) schemeHandler.serialize(
|
|
15946
|
+
if (schemeHandler && schemeHandler.serialize) schemeHandler.serialize(component, options);
|
|
15771
15947
|
|
|
15772
|
-
if (
|
|
15948
|
+
if (component.path !== undefined) {
|
|
15773
15949
|
if (!options.skipEscape) {
|
|
15774
|
-
|
|
15950
|
+
component.path = escape(component.path);
|
|
15775
15951
|
|
|
15776
|
-
if (
|
|
15777
|
-
|
|
15952
|
+
if (component.scheme !== undefined) {
|
|
15953
|
+
component.path = component.path.split('%3A').join(':');
|
|
15778
15954
|
}
|
|
15779
15955
|
} else {
|
|
15780
|
-
|
|
15956
|
+
component.path = unescape(component.path);
|
|
15781
15957
|
}
|
|
15782
15958
|
}
|
|
15783
15959
|
|
|
15784
|
-
if (options.reference !== 'suffix' &&
|
|
15785
|
-
uriTokens.push(
|
|
15960
|
+
if (options.reference !== 'suffix' && component.scheme) {
|
|
15961
|
+
uriTokens.push(component.scheme, ':');
|
|
15786
15962
|
}
|
|
15787
15963
|
|
|
15788
|
-
const authority = recomposeAuthority(
|
|
15964
|
+
const authority = recomposeAuthority(component);
|
|
15789
15965
|
if (authority !== undefined) {
|
|
15790
15966
|
if (options.reference !== 'suffix') {
|
|
15791
15967
|
uriTokens.push('//');
|
|
@@ -15793,51 +15969,49 @@ function requireFastUri () {
|
|
|
15793
15969
|
|
|
15794
15970
|
uriTokens.push(authority);
|
|
15795
15971
|
|
|
15796
|
-
if (
|
|
15972
|
+
if (component.path && component.path[0] !== '/') {
|
|
15797
15973
|
uriTokens.push('/');
|
|
15798
15974
|
}
|
|
15799
15975
|
}
|
|
15800
|
-
if (
|
|
15801
|
-
let s =
|
|
15976
|
+
if (component.path !== undefined) {
|
|
15977
|
+
let s = component.path;
|
|
15802
15978
|
|
|
15803
15979
|
if (!options.absolutePath && (!schemeHandler || !schemeHandler.absolutePath)) {
|
|
15804
15980
|
s = removeDotSegments(s);
|
|
15805
15981
|
}
|
|
15806
15982
|
|
|
15807
|
-
if (
|
|
15808
|
-
|
|
15983
|
+
if (
|
|
15984
|
+
authority === undefined &&
|
|
15985
|
+
s[0] === '/' &&
|
|
15986
|
+
s[1] === '/'
|
|
15987
|
+
) {
|
|
15988
|
+
// don't allow the path to start with "//"
|
|
15989
|
+
s = '/%2F' + s.slice(2);
|
|
15809
15990
|
}
|
|
15810
15991
|
|
|
15811
15992
|
uriTokens.push(s);
|
|
15812
15993
|
}
|
|
15813
15994
|
|
|
15814
|
-
if (
|
|
15815
|
-
uriTokens.push('?',
|
|
15995
|
+
if (component.query !== undefined) {
|
|
15996
|
+
uriTokens.push('?', component.query);
|
|
15816
15997
|
}
|
|
15817
15998
|
|
|
15818
|
-
if (
|
|
15819
|
-
uriTokens.push('#',
|
|
15999
|
+
if (component.fragment !== undefined) {
|
|
16000
|
+
uriTokens.push('#', component.fragment);
|
|
15820
16001
|
}
|
|
15821
16002
|
return uriTokens.join('')
|
|
15822
16003
|
}
|
|
15823
16004
|
|
|
15824
|
-
const hexLookUp = Array.from({ length: 127 }, (_v, k) => /[^!"$&'()*+,\-.;=_`a-z{}~]/u.test(String.fromCharCode(k)));
|
|
15825
|
-
|
|
15826
|
-
function nonSimpleDomain (value) {
|
|
15827
|
-
let code = 0;
|
|
15828
|
-
for (let i = 0, len = value.length; i < len; ++i) {
|
|
15829
|
-
code = value.charCodeAt(i);
|
|
15830
|
-
if (code > 126 || hexLookUp[code]) {
|
|
15831
|
-
return true
|
|
15832
|
-
}
|
|
15833
|
-
}
|
|
15834
|
-
return false
|
|
15835
|
-
}
|
|
15836
|
-
|
|
15837
16005
|
const URI_PARSE = /^(?:([^#/:?]+):)?(?:\/\/((?:([^#/?@]*)@)?(\[[^#/?\]]+\]|[^#/:?]*)(?::(\d*))?))?([^#?]*)(?:\?([^#]*))?(?:#((?:.|[\n\r])*))?/u;
|
|
15838
16006
|
|
|
16007
|
+
/**
|
|
16008
|
+
* @param {string} uri
|
|
16009
|
+
* @param {import('./types/index').Options} [opts]
|
|
16010
|
+
* @returns
|
|
16011
|
+
*/
|
|
15839
16012
|
function parse (uri, opts) {
|
|
15840
16013
|
const options = Object.assign({}, opts);
|
|
16014
|
+
/** @type {import('./types/index').URIComponent} */
|
|
15841
16015
|
const parsed = {
|
|
15842
16016
|
scheme: undefined,
|
|
15843
16017
|
userinfo: undefined,
|
|
@@ -15847,9 +16021,15 @@ function requireFastUri () {
|
|
|
15847
16021
|
query: undefined,
|
|
15848
16022
|
fragment: undefined
|
|
15849
16023
|
};
|
|
15850
|
-
|
|
16024
|
+
|
|
15851
16025
|
let isIP = false;
|
|
15852
|
-
if (options.reference === 'suffix')
|
|
16026
|
+
if (options.reference === 'suffix') {
|
|
16027
|
+
if (options.scheme) {
|
|
16028
|
+
uri = options.scheme + ':' + uri;
|
|
16029
|
+
} else {
|
|
16030
|
+
uri = '//' + uri;
|
|
16031
|
+
}
|
|
16032
|
+
}
|
|
15853
16033
|
|
|
15854
16034
|
const matches = uri.match(URI_PARSE);
|
|
15855
16035
|
|
|
@@ -15868,13 +16048,12 @@ function requireFastUri () {
|
|
|
15868
16048
|
parsed.port = matches[5];
|
|
15869
16049
|
}
|
|
15870
16050
|
if (parsed.host) {
|
|
15871
|
-
const ipv4result =
|
|
15872
|
-
if (ipv4result
|
|
15873
|
-
const ipv6result = normalizeIPv6(
|
|
16051
|
+
const ipv4result = isIPv4(parsed.host);
|
|
16052
|
+
if (ipv4result === false) {
|
|
16053
|
+
const ipv6result = normalizeIPv6(parsed.host);
|
|
15874
16054
|
parsed.host = ipv6result.host.toLowerCase();
|
|
15875
16055
|
isIP = ipv6result.isIPV6;
|
|
15876
16056
|
} else {
|
|
15877
|
-
parsed.host = ipv4result.host;
|
|
15878
16057
|
isIP = true;
|
|
15879
16058
|
}
|
|
15880
16059
|
}
|
|
@@ -15894,7 +16073,7 @@ function requireFastUri () {
|
|
|
15894
16073
|
}
|
|
15895
16074
|
|
|
15896
16075
|
// find scheme handler
|
|
15897
|
-
const schemeHandler =
|
|
16076
|
+
const schemeHandler = getSchemeHandler(options.scheme || parsed.scheme);
|
|
15898
16077
|
|
|
15899
16078
|
// check if scheme can't handle IRIs
|
|
15900
16079
|
if (!options.unicodeSupport && (!schemeHandler || !schemeHandler.unicodeSupport)) {
|
|
@@ -15911,11 +16090,13 @@ function requireFastUri () {
|
|
|
15911
16090
|
}
|
|
15912
16091
|
|
|
15913
16092
|
if (!schemeHandler || (schemeHandler && !schemeHandler.skipNormalize)) {
|
|
15914
|
-
if (
|
|
15915
|
-
parsed.scheme
|
|
15916
|
-
|
|
15917
|
-
|
|
15918
|
-
parsed.host
|
|
16093
|
+
if (uri.indexOf('%') !== -1) {
|
|
16094
|
+
if (parsed.scheme !== undefined) {
|
|
16095
|
+
parsed.scheme = unescape(parsed.scheme);
|
|
16096
|
+
}
|
|
16097
|
+
if (parsed.host !== undefined) {
|
|
16098
|
+
parsed.host = unescape(parsed.host);
|
|
16099
|
+
}
|
|
15919
16100
|
}
|
|
15920
16101
|
if (parsed.path) {
|
|
15921
16102
|
parsed.path = escape(unescape(parsed.path));
|
|
@@ -15939,7 +16120,7 @@ function requireFastUri () {
|
|
|
15939
16120
|
SCHEMES,
|
|
15940
16121
|
normalize,
|
|
15941
16122
|
resolve,
|
|
15942
|
-
|
|
16123
|
+
resolveComponent,
|
|
15943
16124
|
equal,
|
|
15944
16125
|
serialize,
|
|
15945
16126
|
parse
|