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