trousse 2.12.0 → 2.14.0

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/index.d.ts CHANGED
@@ -9,5 +9,5 @@ import { anyWordMatchesAnyOf, endsWithAnyOf, escapeRegex, getAnyOf, includesAnyO
9
9
  import { createAcceptHeader, feedMimeTypes, genericFeedMimeTypes, genericHtmlMimeTypes, htmlMimeTypes } from "./mimes.js";
10
10
  import { omit, pick, toMap, trimObject } from "./objects.js";
11
11
  import { sleep } from "./timers.js";
12
- import { addMissingProtocol, addMissingScheme, createUrlVariants, decodeSegment, fixMalformedProtocol, fixMalformedQuery, fixMalformedScheme, getPathSegments, getQueryParam, getQueryParams, getRegistrableDomain, getSubdomain, isHostOf, isHostOrSubdomainOf, isHttpUrl, isIpAddress, isSubdomainOf, normalizeUrl, parseUrl, resolveFeedProtocol, resolveFeedScheme, resolveUrl, stripWww, upgradeProtocol, upgradeScheme } from "./urls.js";
13
- export { type AnyOf, type DeepOmit, type IsPlainObject, type MaybePromise, type NormalizeOptions, type Nullish, type PartialNullish, type Pattern, type RegistrableDomainOptions, type WeightedMimeType, addMissingProtocol, addMissingScheme, anyWordMatchesAnyOf, archiveExtensions, audioExtensions, codeExtensions, coerceArray, coerceBoolean, coerceDate, coerceNumber, coerceSingular, coerceString, createAcceptHeader, createUrlVariants, decodeSegment, documentExtensions, endsWithAnyOf, escapeHtml, escapeRegex, feedMimeTypes, fixMalformedProtocol, fixMalformedQuery, fixMalformedScheme, flashExtensions, fontExtensions, genericFeedMimeTypes, genericHtmlMimeTypes, getAnyOf, getPathSegments, getQueryParam, getQueryParams, getRegistrableDomain, getSubdomain, htmlMimeTypes, imageExtensions, includesAnyOf, installerExtensions, isAnyOf, isBoolean, isFunction, isHostOf, isHostOrSubdomainOf, isHttpUrl, isIpAddress, isJsonLike, isNonEmptyString, isNullish, isNumber, isObject, isParseableJson, isPlainObject, isPresent, isString, isSubdomainOf, isValidDate, normalizeUrl, omit, omitEmpty, parseUrl, pick, resolveFeedProtocol, resolveFeedScheme, resolveUrl, sleep, startsWithAnyOf, stripWww, subtitleExtensions, t, toMap, trimObject, tx, upgradeProtocol, upgradeScheme, videoExtensions };
12
+ import { addMissingProtocol, addMissingScheme, composeQuery, createUrlSpellings, createUrlVariants, decodeSegment, encodePathSegment, fixMalformedProtocol, fixMalformedQuery, fixMalformedScheme, getPathSegments, getQueryParam, getQueryParams, getRegistrableDomain, getSubdomain, isHostOf, isHostOrSubdomainOf, isHttpUrl, isIpAddress, isSubdomainOf, normalizeUrl, parseUrl, resolveFeedProtocol, resolveFeedScheme, resolveUrl, stripWww, trimUrlValues, upgradeProtocol, upgradeScheme } from "./urls.js";
13
+ export { type AnyOf, type DeepOmit, type IsPlainObject, type MaybePromise, type NormalizeOptions, type Nullish, type PartialNullish, type Pattern, type RegistrableDomainOptions, type WeightedMimeType, addMissingProtocol, addMissingScheme, anyWordMatchesAnyOf, archiveExtensions, audioExtensions, codeExtensions, coerceArray, coerceBoolean, coerceDate, coerceNumber, coerceSingular, coerceString, composeQuery, createAcceptHeader, createUrlSpellings, createUrlVariants, decodeSegment, documentExtensions, encodePathSegment, endsWithAnyOf, escapeHtml, escapeRegex, feedMimeTypes, fixMalformedProtocol, fixMalformedQuery, fixMalformedScheme, flashExtensions, fontExtensions, genericFeedMimeTypes, genericHtmlMimeTypes, getAnyOf, getPathSegments, getQueryParam, getQueryParams, getRegistrableDomain, getSubdomain, htmlMimeTypes, imageExtensions, includesAnyOf, installerExtensions, isAnyOf, isBoolean, isFunction, isHostOf, isHostOrSubdomainOf, isHttpUrl, isIpAddress, isJsonLike, isNonEmptyString, isNullish, isNumber, isObject, isParseableJson, isPlainObject, isPresent, isString, isSubdomainOf, isValidDate, normalizeUrl, omit, omitEmpty, parseUrl, pick, resolveFeedProtocol, resolveFeedScheme, resolveUrl, sleep, startsWithAnyOf, stripWww, subtitleExtensions, t, toMap, trimObject, trimUrlValues, tx, upgradeProtocol, upgradeScheme, videoExtensions };
package/dist/index.js CHANGED
@@ -8,5 +8,5 @@ import { anyWordMatchesAnyOf, endsWithAnyOf, escapeRegex, getAnyOf, includesAnyO
8
8
  import { createAcceptHeader, feedMimeTypes, genericFeedMimeTypes, genericHtmlMimeTypes, htmlMimeTypes } from "./mimes.js";
9
9
  import { omit, pick, toMap, trimObject } from "./objects.js";
10
10
  import { sleep } from "./timers.js";
11
- import { addMissingProtocol, addMissingScheme, createUrlVariants, decodeSegment, fixMalformedProtocol, fixMalformedQuery, fixMalformedScheme, getPathSegments, getQueryParam, getQueryParams, getRegistrableDomain, getSubdomain, isHostOf, isHostOrSubdomainOf, isHttpUrl, isIpAddress, isSubdomainOf, normalizeUrl, parseUrl, resolveFeedProtocol, resolveFeedScheme, resolveUrl, stripWww, upgradeProtocol, upgradeScheme } from "./urls.js";
12
- export { addMissingProtocol, addMissingScheme, anyWordMatchesAnyOf, archiveExtensions, audioExtensions, codeExtensions, coerceArray, coerceBoolean, coerceDate, coerceNumber, coerceSingular, coerceString, createAcceptHeader, createUrlVariants, decodeSegment, documentExtensions, endsWithAnyOf, escapeHtml, escapeRegex, feedMimeTypes, fixMalformedProtocol, fixMalformedQuery, fixMalformedScheme, flashExtensions, fontExtensions, genericFeedMimeTypes, genericHtmlMimeTypes, getAnyOf, getPathSegments, getQueryParam, getQueryParams, getRegistrableDomain, getSubdomain, htmlMimeTypes, imageExtensions, includesAnyOf, installerExtensions, isAnyOf, isBoolean, isFunction, isHostOf, isHostOrSubdomainOf, isHttpUrl, isIpAddress, isJsonLike, isNonEmptyString, isNullish, isNumber, isObject, isParseableJson, isPlainObject, isPresent, isString, isSubdomainOf, isValidDate, normalizeUrl, omit, omitEmpty, parseUrl, pick, resolveFeedProtocol, resolveFeedScheme, resolveUrl, sleep, startsWithAnyOf, stripWww, subtitleExtensions, t, toMap, trimObject, tx, upgradeProtocol, upgradeScheme, videoExtensions };
11
+ import { addMissingProtocol, addMissingScheme, composeQuery, createUrlSpellings, createUrlVariants, decodeSegment, encodePathSegment, fixMalformedProtocol, fixMalformedQuery, fixMalformedScheme, getPathSegments, getQueryParam, getQueryParams, getRegistrableDomain, getSubdomain, isHostOf, isHostOrSubdomainOf, isHttpUrl, isIpAddress, isSubdomainOf, normalizeUrl, parseUrl, resolveFeedProtocol, resolveFeedScheme, resolveUrl, stripWww, trimUrlValues, upgradeProtocol, upgradeScheme } from "./urls.js";
12
+ export { addMissingProtocol, addMissingScheme, anyWordMatchesAnyOf, archiveExtensions, audioExtensions, codeExtensions, coerceArray, coerceBoolean, coerceDate, coerceNumber, coerceSingular, coerceString, composeQuery, createAcceptHeader, createUrlSpellings, createUrlVariants, decodeSegment, documentExtensions, encodePathSegment, endsWithAnyOf, escapeHtml, escapeRegex, feedMimeTypes, fixMalformedProtocol, fixMalformedQuery, fixMalformedScheme, flashExtensions, fontExtensions, genericFeedMimeTypes, genericHtmlMimeTypes, getAnyOf, getPathSegments, getQueryParam, getQueryParams, getRegistrableDomain, getSubdomain, htmlMimeTypes, imageExtensions, includesAnyOf, installerExtensions, isAnyOf, isBoolean, isFunction, isHostOf, isHostOrSubdomainOf, isHttpUrl, isIpAddress, isJsonLike, isNonEmptyString, isNullish, isNumber, isObject, isParseableJson, isPlainObject, isPresent, isString, isSubdomainOf, isValidDate, normalizeUrl, omit, omitEmpty, parseUrl, pick, resolveFeedProtocol, resolveFeedScheme, resolveUrl, sleep, startsWithAnyOf, stripWww, subtitleExtensions, t, toMap, trimObject, trimUrlValues, tx, upgradeProtocol, upgradeScheme, videoExtensions };
package/dist/urls.d.ts CHANGED
@@ -8,10 +8,13 @@ export declare const isHttpUrl: (url: string | URL) => boolean;
8
8
  export declare const isHostOrSubdomainOf: (url: string | URL, domains: string | ReadonlyArray<string>) => boolean;
9
9
  export declare const getSubdomain: (url: string | URL, domains: string | ReadonlyArray<string>) => string | undefined;
10
10
  export declare const decodeSegment: (segment: string | undefined) => string | undefined;
11
+ export declare const encodePathSegment: (value: string) => string;
11
12
  export declare const getQueryParams: (params: URLSearchParams | undefined, name: string) => Array<string>;
12
13
  export declare const getQueryParam: (params: URLSearchParams | undefined, name: string) => string | undefined;
14
+ export declare const composeQuery: (params?: Record<string, string>) => string;
13
15
  export declare const fixMalformedScheme: (url: string) => string;
14
16
  export declare const fixMalformedQuery: (url: string) => string;
17
+ export declare const trimUrlValues: (url: string) => string;
15
18
  export declare const resolveFeedScheme: (url: string, scheme?: 'http' | 'https') => string;
16
19
  export declare const addMissingScheme: (url: string, scheme?: 'http' | 'https') => string;
17
20
  export declare const upgradeScheme: (url: string, scheme?: 'http' | 'https') => string;
@@ -20,6 +23,7 @@ export declare const normalizeUrl: (url: string, options: NormalizeOptions) => s
20
23
  export declare const stripWww: (hostname: string) => string;
21
24
  export declare const isIpAddress: (hostname: string) => boolean;
22
25
  export declare const createUrlVariants: (url: string) => Array<string>;
26
+ export declare const createUrlSpellings: (url: string) => Array<string>;
23
27
  export declare const getRegistrableDomain: (url: string | URL, options?: RegistrableDomainOptions) => string | undefined;
24
28
  /** @deprecated Use `fixMalformedScheme` instead. */
25
29
  export declare const fixMalformedProtocol: typeof fixMalformedScheme;
package/dist/urls.js CHANGED
@@ -57,6 +57,10 @@ const decodeSegment = (segment) => {
57
57
  return decodeURIComponent(segment);
58
58
  } catch {}
59
59
  };
60
+ const pathSegmentEscapeRegex = /[/?#\\\s]/g;
61
+ const encodePathSegment = (value) => {
62
+ return value.replace(pathSegmentEscapeRegex, (character) => encodeURIComponent(character));
63
+ };
60
64
  const getQueryParams = (params, name) => {
61
65
  const values = [];
62
66
  if (!params) return values;
@@ -67,6 +71,16 @@ const getQueryParams = (params, name) => {
67
71
  const getQueryParam = (params, name) => {
68
72
  return getQueryParams(params, name)[0];
69
73
  };
74
+ const queryPartEscapeRegex = /[&#%+\s]/g;
75
+ const composeQuery = (params) => {
76
+ const escapePart = (part) => {
77
+ return part.replace(queryPartEscapeRegex, (character) => encodeURIComponent(character));
78
+ };
79
+ const pairs = Object.entries(params ?? {}).map(([name, value]) => {
80
+ return `${escapePart(name)}=${escapePart(value)}`;
81
+ });
82
+ return pairs.length > 0 ? `?${pairs.join("&")}` : "";
83
+ };
70
84
  const strippedParamsCache = /* @__PURE__ */ new WeakMap();
71
85
  const getStrippedParamsSet = (params) => {
72
86
  let cached = strippedParamsCache.get(params);
@@ -169,6 +183,32 @@ const fixMalformedQuery = (url) => {
169
183
  if (!hasNestedUrl) query = query.replace(lostSeparatorRegex, "&").replace(slashClosedValueRegex, "$1");
170
184
  return `${head.slice(0, queryIndex)}?${query}${head.slice(ownEnd)}${fragment}`;
171
185
  };
186
+ const segmentEdgeSpace = "(?:\\s|%(?:09|0A|0D|20))";
187
+ const valueEdgeSpace = "(?:\\s|\\+|%(?:09|0A|0D|20))";
188
+ const segmentEdgeSpaceRegex = new RegExp(`^${segmentEdgeSpace}+|(?<!${segmentEdgeSpace})${segmentEdgeSpace}+$`, "gi");
189
+ const valueEdgeSpaceRegex = new RegExp(`^${valueEdgeSpace}+|(?<!${valueEdgeSpace})${valueEdgeSpace}+$`, "gi");
190
+ const trimEdgeSpace = (value, regex) => {
191
+ return value.replace(regex, "") || value;
192
+ };
193
+ const trimPairValue = (pair) => {
194
+ const equalsIndex = pair.indexOf("=");
195
+ if (equalsIndex === -1) return pair;
196
+ const value = trimEdgeSpace(pair.slice(equalsIndex + 1), valueEdgeSpaceRegex);
197
+ return `${pair.slice(0, equalsIndex + 1)}${value}`;
198
+ };
199
+ const trimUrlValues = (url) => {
200
+ if (!httpOrSchemeRelativeRegex.test(url)) return url;
201
+ const hashIndex = url.indexOf("#");
202
+ const head = hashIndex === -1 ? url : url.slice(0, hashIndex);
203
+ const fragment = hashIndex === -1 ? "" : url.slice(hashIndex);
204
+ const markIndex = head.indexOf("?");
205
+ const beforeQuery = markIndex === -1 ? head : head.slice(0, markIndex);
206
+ const pathIndex = beforeQuery.indexOf("/", beforeQuery.indexOf("//") + 2);
207
+ const authority = pathIndex === -1 ? beforeQuery : beforeQuery.slice(0, pathIndex);
208
+ const path = (pathIndex === -1 ? [] : beforeQuery.slice(pathIndex).split("/")).map((segment) => trimEdgeSpace(segment, segmentEdgeSpaceRegex)).join("/");
209
+ const pairs = markIndex === -1 ? [] : head.slice(markIndex + 1).split("&");
210
+ return `${authority}${path}${markIndex === -1 ? "" : `?${pairs.map(trimPairValue).join("&")}`}${fragment}`;
211
+ };
172
212
  const feedSchemes = [
173
213
  "feed:",
174
214
  "rss:",
@@ -336,6 +376,27 @@ const createUrlVariants = (url) => {
336
376
  }
337
377
  return variants;
338
378
  };
379
+ const sameQuerySpellings = [
380
+ ["+", "%20"],
381
+ [":", "%3A"],
382
+ ["@", "%40"]
383
+ ];
384
+ const percentEscapeRegex = /%[0-9a-f]{2}/gi;
385
+ const createUrlSpellings = (url) => {
386
+ const spellings = [url, url.replace(percentEscapeRegex, (hex) => hex.toUpperCase())];
387
+ const hashIndex = url.indexOf("#");
388
+ const queryEnd = hashIndex === -1 ? url.length : hashIndex;
389
+ const queryIndex = url.indexOf("?");
390
+ if (queryIndex === -1 || queryIndex > queryEnd) return [...new Set(spellings)];
391
+ const head = url.slice(0, queryIndex);
392
+ const query = url.slice(queryIndex, queryEnd);
393
+ const fragment = url.slice(queryEnd);
394
+ for (const [written, encoded] of sameQuerySpellings) {
395
+ spellings.push(`${head}${query.replaceAll(written, encoded)}${fragment}`);
396
+ spellings.push(`${head}${query.replaceAll(encoded, written)}${fragment}`);
397
+ }
398
+ return [...new Set(spellings)];
399
+ };
339
400
  const genericSecondLevels = [
340
401
  "ac",
341
402
  "co",
@@ -405,4 +466,4 @@ const addMissingProtocol = addMissingScheme;
405
466
  /** @deprecated Use `upgradeScheme` instead. */
406
467
  const upgradeProtocol = upgradeScheme;
407
468
  //#endregion
408
- export { addMissingProtocol, addMissingScheme, createUrlVariants, decodeSegment, fixMalformedProtocol, fixMalformedQuery, fixMalformedScheme, getPathSegments, getQueryParam, getQueryParams, getRegistrableDomain, getSubdomain, isHostOf, isHostOrSubdomainOf, isHttpUrl, isIpAddress, isSubdomainOf, normalizeUrl, parseUrl, resolveFeedProtocol, resolveFeedScheme, resolveUrl, stripWww, upgradeProtocol, upgradeScheme };
469
+ export { addMissingProtocol, addMissingScheme, composeQuery, createUrlSpellings, createUrlVariants, decodeSegment, encodePathSegment, fixMalformedProtocol, fixMalformedQuery, fixMalformedScheme, getPathSegments, getQueryParam, getQueryParams, getRegistrableDomain, getSubdomain, isHostOf, isHostOrSubdomainOf, isHttpUrl, isIpAddress, isSubdomainOf, normalizeUrl, parseUrl, resolveFeedProtocol, resolveFeedScheme, resolveUrl, stripWww, trimUrlValues, upgradeProtocol, upgradeScheme };
package/package.json CHANGED
@@ -46,5 +46,5 @@
46
46
  "dependencies": {
47
47
  "entities": "^8.1.0"
48
48
  },
49
- "version": "2.12.0"
49
+ "version": "2.14.0"
50
50
  }