urlpurify 2.2.0 → 2.2.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/clean.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import { isAnyOf } from "./node_modules/trousse/dist/matching.mjs";
2
- import { fixMalformedScheme, isHttpUrl, isIpAddress, normalizeUrl, parseUrl, stripWww } from "./node_modules/trousse/dist/urls.mjs";
2
+ import { fixMalformedScheme, isHostOf, isHttpUrl, isIpAddress, normalizeUrl, parseUrl, stripWww } from "./node_modules/trousse/dist/urls.mjs";
3
3
  import { defaultTrackingParams, defaultUnwrappers } from "./defaults.mjs";
4
4
  // src/clean.ts
5
5
  const refDelimitersRegex = /[\s/?#\\:@]/;
@@ -32,7 +32,7 @@ const deleteTrackingParams = (url, trackingParams) => {
32
32
  for (const entry of entries) if (entry && isAnyOf(entry[0], signatureParams)) return;
33
33
  const matcher = getTrackingMatcher(trackingParams);
34
34
  const host = stripWww(url.hostname);
35
- const keepsTs = url.hostname === "dm-cn.aliyuncs.com" && url.pathname === "/trace/v1/report";
35
+ const keepsTs = isHostOf(url, "dm-cn.aliyuncs.com") && url.pathname === "/trace/v1/report";
36
36
  const keptPairs = pairs.filter((_pair, index) => {
37
37
  const entry = entries[index];
38
38
  if (!entry) return true;
@@ -41,10 +41,9 @@ const deleteTrackingParams = (url, trackingParams) => {
41
41
  if (keepsTs && name === "ts") return true;
42
42
  if (matcher.literals.has(name) || matcher.patterns.some((pattern) => name.search(pattern) !== -1)) return false;
43
43
  if (name !== "ref" || refDelimitersRegex.test(value)) return true;
44
- try {
45
- return stripWww(new URL(`http://${value}`).hostname) !== host;
46
- } catch {}
47
- return true;
44
+ const refUrl = parseUrl(`http://${value}`);
45
+ if (!refUrl) return true;
46
+ return stripWww(refUrl.hostname) !== host;
48
47
  });
49
48
  if (keptPairs.length === pairs.length) return;
50
49
  url.search = keptPairs.join("&");
@@ -19,6 +19,14 @@ const isAnyOf = (value, patterns, parser) => {
19
19
  return parsedValue === (parser ? pattern : pattern.toLowerCase().trim());
20
20
  });
21
21
  };
22
+ const startsWithAnyOf = (value, patterns) => {
23
+ if (isNullish(value)) return false;
24
+ const lowerValue = value.toLowerCase();
25
+ return toPatternList(patterns).some((pattern) => {
26
+ if (pattern instanceof RegExp) return testRegexAnyCase(pattern, lowerValue, value);
27
+ return pattern && lowerValue.startsWith(pattern.toLowerCase());
28
+ });
29
+ };
22
30
  const endsWithAnyOf = (value, patterns) => {
23
31
  if (isNullish(value)) return false;
24
32
  const lowerValue = value.toLowerCase();
@@ -27,4 +35,4 @@ const endsWithAnyOf = (value, patterns) => {
27
35
  return pattern && lowerValue.endsWith(pattern.toLowerCase());
28
36
  });
29
37
  };
30
- export { endsWithAnyOf, isAnyOf };
38
+ export { endsWithAnyOf, isAnyOf, startsWithAnyOf };
@@ -41,6 +41,15 @@ const isHttpUrl = (url) => {
41
41
  const isHostOrSubdomainOf = (url, domains) => {
42
42
  return isHostOf(url, domains) || isSubdomainOf(url, domains);
43
43
  };
44
+ const getSubdomain = (url, domains) => {
45
+ const hostname = getHostname(url)?.toLowerCase();
46
+ if (!hostname) return;
47
+ const list = typeof domains === "string" ? [domains] : domains;
48
+ for (const domain of list) {
49
+ const suffix = `.${normalizeDomain(domain).toLowerCase()}`;
50
+ if (hostname.endsWith(suffix) && hostname.length > suffix.length) return hostname.slice(0, -suffix.length);
51
+ }
52
+ };
44
53
  const escapeRunRegex = /(?:%[0-9A-Fa-f]{2})+/g;
45
54
  const getSequenceLength = (byte) => {
46
55
  if (byte < 128) return 1;
@@ -105,9 +114,21 @@ const readParamValues = (params, name, options) => {
105
114
  }
106
115
  return values;
107
116
  };
117
+ const hasParam = (params, name) => {
118
+ if (!params) return false;
119
+ const lowercaseName = name.toLowerCase();
120
+ for (const [key] of params) if (key.toLowerCase() === lowercaseName) return true;
121
+ return false;
122
+ };
123
+ const hasQueryParam = (source, name) => {
124
+ return hasParam(readQuerySource(source), name);
125
+ };
108
126
  const getQueryParamValues = (source, name, options) => {
109
127
  return readParamValues(readQuerySource(source, options), name, options);
110
128
  };
129
+ const getQueryParam = (source, name, options) => {
130
+ return getQueryParamValues(source, name, options)[0];
131
+ };
111
132
  const strippedParamsCache = /* @__PURE__ */ new WeakMap();
112
133
  const getStrippedParamsSet = (params) => {
113
134
  let cached = strippedParamsCache.get(params);
@@ -310,6 +331,4 @@ const stripWww = (hostname) => {
310
331
  const isIpAddress = (hostname) => {
311
332
  return ipv4Regex.test(hostname) || ipv6Regex.test(hostname.replace(ipv6BracketsRegex, ""));
312
333
  };
313
- /** @deprecated Use `addMissingScheme` instead. */
314
- const addMissingProtocol = addMissingScheme;
315
- export { addMissingProtocol, addMissingScheme, decodePercent, fixMalformedScheme, getQueryParamValues, isHostOf, isHostOrSubdomainOf, isHttpUrl, isIpAddress, isSubdomainOf, normalizeUrl, parseUrl, resolveFeedScheme, resolveUrl, stripWww };
334
+ export { addMissingScheme, decodePercent, fixMalformedScheme, getQueryParam, getQueryParamValues, getSubdomain, hasQueryParam, isHostOf, isHostOrSubdomainOf, isHttpUrl, isIpAddress, isSubdomainOf, normalizeUrl, parseUrl, resolveFeedScheme, resolveUrl, stripWww };
@@ -1,7 +1,8 @@
1
+ import { isHostOf } from "../node_modules/trousse/dist/urls.mjs";
1
2
  import { getParamTarget } from "../utils.mjs";
2
3
  // src/unwraps/affilae.ts
3
4
  const unwrapAffilae = (url) => {
4
- if (url.hostname !== "lb.affilae.com" || url.pathname !== "/r/") return;
5
+ if (!isHostOf(url, "lb.affilae.com") || url.pathname !== "/r/") return;
5
6
  return getParamTarget(url, "lp", -1);
6
7
  };
7
8
  export { unwrapAffilae };
@@ -1,9 +1,9 @@
1
- import { decodePercent, isHttpUrl } from "../node_modules/trousse/dist/urls.mjs";
1
+ import { decodePercent, isHostOf, isHttpUrl } from "../node_modules/trousse/dist/urls.mjs";
2
2
  import { getParamValues } from "../utils.mjs";
3
3
  // src/unwraps/apptrkr.ts
4
4
  const encodedSchemeRegex = /^https?%3A/i;
5
5
  const unwrapApptrkr = (url) => {
6
- if (url.hostname !== "apptrkr.com" || url.pathname !== "/get_redirect.php") return;
6
+ if (!isHostOf(url, "apptrkr.com") || url.pathname !== "/get_redirect.php") return;
7
7
  let target = getParamValues(url, "targetURL").at(-1);
8
8
  if (!target) return;
9
9
  if (encodedSchemeRegex.test(target)) target = decodePercent(target);
@@ -1,8 +1,8 @@
1
- import { isHttpUrl } from "../node_modules/trousse/dist/urls.mjs";
1
+ import { hasQueryParam, isHttpUrl } from "../node_modules/trousse/dist/urls.mjs";
2
2
  import { getParamTarget } from "../utils.mjs";
3
3
  // src/unwraps/cake.ts
4
4
  const unwrapCake = (url) => {
5
- if (url.pathname !== "/" || !url.searchParams.has("a") || !url.searchParams.has("c")) return;
5
+ if (url.pathname !== "/" || !hasQueryParam(url, "a") || !hasQueryParam(url, "c")) return;
6
6
  const target = getParamTarget(url, "ckmrdr");
7
7
  if (!target || !isHttpUrl(target)) return;
8
8
  return target;
@@ -1,9 +1,9 @@
1
- import { isHttpUrl } from "../node_modules/trousse/dist/urls.mjs";
1
+ import { hasQueryParam, isHttpUrl } from "../node_modules/trousse/dist/urls.mjs";
2
2
  import { getParamTarget } from "../utils.mjs";
3
3
  // src/unwraps/cleverbridge.ts
4
4
  const pathRegex = /^\/\d+\/cookie$/;
5
5
  const unwrapCleverbridge = (url) => {
6
- if (!pathRegex.test(url.pathname) || !url.searchParams.has("affiliate")) return;
6
+ if (!pathRegex.test(url.pathname) || !hasQueryParam(url, "affiliate")) return;
7
7
  const target = getParamTarget(url, "redirectto");
8
8
  if (!target || !isHttpUrl(target)) return;
9
9
  return target;
@@ -1,9 +1,9 @@
1
- import { isHttpUrl } from "../node_modules/trousse/dist/urls.mjs";
1
+ import { getQueryParam, isHttpUrl } from "../node_modules/trousse/dist/urls.mjs";
2
2
  import { decodeBase64, getParamValues } from "../utils.mjs";
3
3
  // src/unwraps/datalifeEngine.ts
4
4
  const unwrapDatalifeEngine = (url) => {
5
5
  const isEngineGo = url.pathname === "/engine/go.php";
6
- const isIndexGo = url.pathname === "/index.php" && url.searchParams.get("do") === "go";
6
+ const isIndexGo = url.pathname === "/index.php" && getQueryParam(url, "do") === "go";
7
7
  if (!isEngineGo && !isIndexGo) return;
8
8
  const raw = getParamValues(url, "url").at(0);
9
9
  if (!raw) return;
@@ -1,4 +1,4 @@
1
- import { isHostOf, isHttpUrl } from "../node_modules/trousse/dist/urls.mjs";
1
+ import { hasQueryParam, isHostOf, isHttpUrl } from "../node_modules/trousse/dist/urls.mjs";
2
2
  import { decodeBase64, getParamValues } from "../utils.mjs";
3
3
  // src/unwraps/deployer.ts
4
4
  const hosts = [
@@ -8,7 +8,7 @@ const hosts = [
8
8
  ];
9
9
  const paths = ["/link.php", "/wta/link.php"];
10
10
  const unwrapDeployer = (url) => {
11
- if (!isHostOf(url, hosts) || !paths.includes(url.pathname) || !url.searchParams.has("AGENCY")) return;
11
+ if (!isHostOf(url, hosts) || !paths.includes(url.pathname) || !hasQueryParam(url, "AGENCY")) return;
12
12
  const value = getParamValues(url, "drurl").at(0)?.replaceAll(" ", "+");
13
13
  if (!value) return;
14
14
  const target = decodeBase64(value);
@@ -1,12 +1,10 @@
1
- import { isHttpUrl } from "../node_modules/trousse/dist/urls.mjs";
1
+ import { getQueryParam, isHttpUrl } from "../node_modules/trousse/dist/urls.mjs";
2
2
  import { getParamValues } from "../utils.mjs";
3
3
  // src/unwraps/drupalOembed.ts
4
- const pathRegex = /^(?:\/[^/]+)*\/media\/oembed$/;
5
- const hashRegex = /^[\w-]{43}$/;
4
+ const pathRegex = /^(?:\/[^/]+)*\/media\/oembed$/i;
6
5
  const unwrapDrupalOembed = (url) => {
7
6
  if (!pathRegex.test(url.pathname)) return;
8
- const hash = url.searchParams.get("hash");
9
- if (!hash || !hashRegex.test(hash)) return;
7
+ if (!getQueryParam(url, "hash")) return;
10
8
  const target = getParamValues(url, "url").at(-1);
11
9
  if (!target || !isHttpUrl(target)) return;
12
10
  return target;
@@ -1,8 +1,8 @@
1
- import { isHttpUrl } from "../node_modules/trousse/dist/urls.mjs";
1
+ import { hasQueryParam, isHttpUrl } from "../node_modules/trousse/dist/urls.mjs";
2
2
  import { getParamTarget } from "../utils.mjs";
3
3
  // src/unwraps/elasticEmail.ts
4
4
  const unwrapElasticEmail = (url) => {
5
- if (url.pathname !== "/tracking/click" || !url.searchParams.has("msgid")) return;
5
+ if (url.pathname !== "/tracking/click" || !hasQueryParam(url, "msgid")) return;
6
6
  const target = getParamTarget(url, "target");
7
7
  if (!target || !isHttpUrl(target)) return;
8
8
  return target;
@@ -1,11 +1,10 @@
1
- import { addMissingProtocol, isHttpUrl } from "../node_modules/trousse/dist/urls.mjs";
1
+ import { isHostOf } from "../node_modules/trousse/dist/urls.mjs";
2
2
  // src/unwraps/feedblitz.ts
3
3
  const pathRegex = /^\/~\/t\/0\/[0_]\/[^/]+(?:\/full)?\/~(.+)$/;
4
4
  const unwrapFeedblitz = (url) => {
5
- if (url.hostname !== "feeds.feedblitz.com") return;
5
+ if (!isHostOf(url, "feeds.feedblitz.com")) return;
6
6
  const match = pathRegex.exec(url.pathname);
7
7
  if (!match?.[1]) return;
8
- const target = addMissingProtocol(`${match[1]}${url.search}${url.hash}`);
9
- if (isHttpUrl(target)) return target;
8
+ return `${match[1]}${url.search}${url.hash}`;
10
9
  };
11
10
  export { unwrapFeedblitz };
@@ -1,9 +1,9 @@
1
- import { isHttpUrl } from "../node_modules/trousse/dist/urls.mjs";
1
+ import { hasQueryParam, isHttpUrl } from "../node_modules/trousse/dist/urls.mjs";
2
2
  import { getParamTarget } from "../utils.mjs";
3
3
  // src/unwraps/finalsite.ts
4
4
  const paths = ["/forward.cfm", "/cf_news/forward.cfm"];
5
5
  const unwrapFinalsite = (url) => {
6
- if (!paths.includes(url.pathname) || !url.searchParams.has("destkey")) return;
6
+ if (!paths.includes(url.pathname) || !hasQueryParam(url, "destkey")) return;
7
7
  const target = getParamTarget(url, "dest", -1);
8
8
  if (!target || !isHttpUrl(target)) return;
9
9
  return target;
@@ -1,3 +1,4 @@
1
+ import { isHostOf } from "../node_modules/trousse/dist/urls.mjs";
1
2
  import { createParamExtractor } from "../utils.mjs";
2
3
  // src/unwraps/firebaseDynamicLinks.ts
3
4
  const appPathRegex = /^\/app\/[\w-]+$/;
@@ -12,7 +13,7 @@ const extractGooGlTarget = createParamExtractor({
12
13
  params
13
14
  });
14
15
  const unwrapFirebaseDynamicLinks = (url) => {
15
- if (url.hostname !== "goo.gl") return extractTarget(url);
16
+ if (!isHostOf(url, "goo.gl")) return extractTarget(url);
16
17
  if (!appPathRegex.test(url.pathname)) return;
17
18
  return extractGooGlTarget(url);
18
19
  };
@@ -1,8 +1,8 @@
1
- import { isHttpUrl } from "../node_modules/trousse/dist/urls.mjs";
1
+ import { hasQueryParam, isHttpUrl } from "../node_modules/trousse/dist/urls.mjs";
2
2
  import { getParamTarget } from "../utils.mjs";
3
3
  // src/unwraps/fortimail.ts
4
4
  const unwrapFortimail = (url) => {
5
- if (url.pathname !== "/fmlurlsvc/" || !url.searchParams.has("fewReq")) return;
5
+ if (url.pathname !== "/fmlurlsvc/" || !hasQueryParam(url, "fewReq")) return;
6
6
  const target = getParamTarget(url, "url");
7
7
  if (!target || !isHttpUrl(target)) return;
8
8
  return target;
@@ -1,25 +1,25 @@
1
- import { isAnyOf } from "../node_modules/trousse/dist/matching.mjs";
2
- import { isHostOf } from "../node_modules/trousse/dist/urls.mjs";
1
+ import { isAnyOf, startsWithAnyOf } from "../node_modules/trousse/dist/matching.mjs";
2
+ import { getQueryParam, getSubdomain, isHostOf } from "../node_modules/trousse/dist/urls.mjs";
3
3
  import { getParamValues } from "../utils.mjs";
4
4
  // src/unwraps/googleTranslate.ts
5
5
  const googleTranslateHostRegex = /^(?:www\.)?translate\.google\.(?:com|[a-z]{2,3}(?:\.[a-z]{2,3})?)$/;
6
6
  const googleTranslatePaths = ["/translate", "/website"];
7
- const proxyHostSuffix = ".translate.goog";
7
+ const proxyDomain = "translate.goog";
8
8
  const proxyLabelRegex = /^[a-z0-9-]+$/;
9
9
  const hashedLabelRegex = /^[a-z2-7]{26}-[a-z0-9]{15}-/;
10
10
  const proxyParamPrefix = "_x_tr_";
11
+ const singleDashRegex = /\b-\b/g;
11
12
  const unwrapWebsiteProxy = (url) => {
12
- if (!url.hostname.endsWith(proxyHostSuffix)) return;
13
- const label = url.hostname.slice(0, -15);
14
- if (!proxyLabelRegex.test(label) || hashedLabelRegex.test(label)) return;
15
- const encodings = url.searchParams.get(`${proxyParamPrefix}enc`)?.split(",") ?? [];
16
- let prefix = `${url.searchParams.get(`${proxyParamPrefix}hp`) ?? ""}${label}`;
13
+ const label = getSubdomain(url, proxyDomain);
14
+ if (!label || !proxyLabelRegex.test(label) || hashedLabelRegex.test(label)) return;
15
+ const encodings = getQueryParam(url, `${proxyParamPrefix}enc`)?.split(",") ?? [];
16
+ let prefix = `${getQueryParam(url, `${proxyParamPrefix}hp`) ?? ""}${label}`;
17
17
  if (encodings.includes("1") && prefix.startsWith("1-")) prefix = prefix.slice(2);
18
18
  const isIdn = encodings.includes("0") && prefix.startsWith("0-");
19
19
  if (isIdn) prefix = prefix.slice(2);
20
- const host = `${isIdn ? "xn--" : ""}${prefix.replaceAll(/\b-\b/g, ".").replaceAll("--", "-")}`;
21
- const scheme = url.searchParams.get(`${proxyParamPrefix}sch`) === "http" ? "http" : "https";
22
- const query = url.search.slice(1).split("&").filter((part) => part && !part.startsWith(proxyParamPrefix)).join("&");
20
+ const host = `${isIdn ? "xn--" : ""}${prefix.replaceAll(singleDashRegex, ".").replaceAll("--", "-")}`;
21
+ const scheme = getQueryParam(url, `${proxyParamPrefix}sch`) === "http" ? "http" : "https";
22
+ const query = url.search.slice(1).split("&").filter((part) => part && !startsWithAnyOf(part, proxyParamPrefix)).join("&");
23
23
  return `${scheme}://${host}${url.pathname}${query ? `?${query}` : ""}${url.hash}`;
24
24
  };
25
25
  const unwrapGoogleTranslate = (url) => {
@@ -1,8 +1,8 @@
1
- import { isHttpUrl } from "../node_modules/trousse/dist/urls.mjs";
1
+ import { hasQueryParam, isHttpUrl } from "../node_modules/trousse/dist/urls.mjs";
2
2
  import { getParamTarget } from "../utils.mjs";
3
3
  // src/unwraps/hasoffers.ts
4
4
  const unwrapHasoffers = (url) => {
5
- if (url.pathname !== "/aff_c" || !url.searchParams.has("offer_id")) return;
5
+ if (url.pathname !== "/aff_c" || !hasQueryParam(url, "offer_id")) return;
6
6
  const target = getParamTarget(url, "url");
7
7
  if (!target || !isHttpUrl(target)) return;
8
8
  return target;
@@ -1,8 +1,9 @@
1
+ import { getQueryParam } from "../node_modules/trousse/dist/urls.mjs";
1
2
  import { getParamValues } from "../utils.mjs";
2
3
  // src/unwraps/locaweb.ts
3
4
  const idRegex = /^T?H\|(?:\d+|teste)\|\d+\|\d+$/;
4
5
  const unwrapLocaweb = (url) => {
5
- if (url.pathname !== "/registra_clique.php" || !idRegex.test(url.searchParams.get("id") ?? "")) return;
6
+ if (url.pathname !== "/registra_clique.php" || !idRegex.test(getQueryParam(url, "id") ?? "")) return;
6
7
  return getParamValues(url, "url").at(0);
7
8
  };
8
9
  export { unwrapLocaweb };
@@ -1,8 +1,8 @@
1
- import { isHttpUrl } from "../node_modules/trousse/dist/urls.mjs";
1
+ import { getQueryParam, isHttpUrl } from "../node_modules/trousse/dist/urls.mjs";
2
2
  import { getParamTarget } from "../utils.mjs";
3
3
  // src/unwraps/mintFeeder.ts
4
4
  const unwrapMintFeeder = (url) => {
5
- if (url.pathname !== "/feeder/" || url.searchParams.get("FeederAction") !== "clicked") return;
5
+ if (url.pathname !== "/feeder/" || getQueryParam(url, "FeederAction") !== "clicked") return;
6
6
  const target = getParamTarget(url, "seed");
7
7
  if (target && isHttpUrl(target)) return target;
8
8
  };
@@ -1,3 +1,4 @@
1
+ import { getQueryParam } from "../node_modules/trousse/dist/urls.mjs";
1
2
  import { createParamExtractor } from "../utils.mjs";
2
3
  // src/unwraps/okRu.ts
3
4
  const extractLogExternalLink = createParamExtractor({
@@ -16,7 +17,7 @@ const extractOutLinkWarningTarget = createParamExtractor({
16
17
  params: ["st.rfn"]
17
18
  });
18
19
  const unwrapOkRu = (url) => {
19
- if (url.searchParams.get("cmd") === "logExternal") return extractLogExternalLink(url);
20
- if (url.searchParams.get("st.cmd") === "outLinkWarning") return extractOutLinkWarningTarget(url);
20
+ if (getQueryParam(url, "cmd") === "logExternal") return extractLogExternalLink(url);
21
+ if (getQueryParam(url, "st.cmd") === "outLinkWarning") return extractOutLinkWarningTarget(url);
21
22
  };
22
23
  export { unwrapOkRu };
@@ -9,6 +9,6 @@ const extractTarget = createParamExtractor({
9
9
  const unwrapProofpointV2 = (url) => {
10
10
  const raw = extractTarget(url);
11
11
  if (!raw) return;
12
- return decodePercent(raw.replace(/-/g, "%").replace(/_/g, "/"));
12
+ return decodePercent(raw.replaceAll("-", "%").replaceAll("_", "/"));
13
13
  };
14
14
  export { unwrapProofpointV2 };
@@ -1,10 +1,10 @@
1
- import { decodePercent, isHttpUrl } from "../node_modules/trousse/dist/urls.mjs";
1
+ import { decodePercent, hasQueryParam, isHttpUrl } from "../node_modules/trousse/dist/urls.mjs";
2
2
  import { getParamValues } from "../utils.mjs";
3
3
  // src/unwraps/qualityClick.ts
4
4
  const encodedSchemeRegex = /^https?%3A/i;
5
5
  const unwrapQualityClick = (url) => {
6
6
  if (url.pathname !== "/go.cgi") return;
7
- if (!url.searchParams.has("pid") || !url.searchParams.has("wmid")) return;
7
+ if (!hasQueryParam(url, "pid") || !hasQueryParam(url, "wmid")) return;
8
8
  let target = getParamValues(url, "target").at(0);
9
9
  if (target && encodedSchemeRegex.test(target)) target = decodePercent(target);
10
10
  if (target && isHttpUrl(target)) return target;
@@ -1,4 +1,4 @@
1
- import { decodePercent, isHttpUrl } from "../node_modules/trousse/dist/urls.mjs";
1
+ import { decodePercent, hasQueryParam, isHttpUrl } from "../node_modules/trousse/dist/urls.mjs";
2
2
  import { getParamTarget } from "../utils.mjs";
3
3
  // src/unwraps/reviveAdserver.ts
4
4
  const clickPathRegex = /^(?:\/[^/]+)*\/c[kl]\.php$/;
@@ -18,7 +18,7 @@ const unwrapReviveAdserver = (url) => {
18
18
  if (isHttpUrl(target)) return target;
19
19
  return;
20
20
  }
21
- if (!legacyClickPathRegex.test(url.pathname) || !url.searchParams.has("bannerid")) return;
21
+ if (!legacyClickPathRegex.test(url.pathname) || !hasQueryParam(url, "bannerid")) return;
22
22
  const target = getParamTarget(url, "dest");
23
23
  if (!target || !isHttpUrl(target)) return;
24
24
  return target;
@@ -1,9 +1,9 @@
1
- import { isHttpUrl } from "../node_modules/trousse/dist/urls.mjs";
1
+ import { hasQueryParam, isHttpUrl } from "../node_modules/trousse/dist/urls.mjs";
2
2
  import { decodeBase64, getParamValues } from "../utils.mjs";
3
3
  // src/unwraps/serendipity.ts
4
4
  const pathRegex = /^(?:\/[^/]+)?\/exit\.php$/;
5
5
  const unwrapSerendipity = (url) => {
6
- if (!pathRegex.test(url.pathname) || !url.searchParams.has("entry_id")) return;
6
+ if (!pathRegex.test(url.pathname) || !hasQueryParam(url, "entry_id")) return;
7
7
  const raw = getParamValues(url, "url").at(0);
8
8
  if (!raw) return;
9
9
  const decoded = decodeBase64(raw);
@@ -1,3 +1,4 @@
1
+ import { getQueryParam } from "../node_modules/trousse/dist/urls.mjs";
1
2
  import { createParamExtractor } from "../utils.mjs";
2
3
  // src/unwraps/teacup.ts
3
4
  const hostRegex = /^\d+\.teacup\.com$/;
@@ -7,7 +8,7 @@ const extractTarget = createParamExtractor({
7
8
  params: ["JUR"]
8
9
  });
9
10
  const unwrapTeacup = (url) => {
10
- if (!pathRegex.test(url.pathname) || url.searchParams.get("M") !== "JU") return;
11
+ if (!pathRegex.test(url.pathname) || getQueryParam(url, "M") !== "JU") return;
11
12
  return extractTarget(url);
12
13
  };
13
14
  export { unwrapTeacup };
@@ -1,3 +1,4 @@
1
+ import { isHostOf } from "../node_modules/trousse/dist/urls.mjs";
1
2
  import { createParamExtractor } from "../utils.mjs";
2
3
  // src/unwraps/tracdelight.ts
3
4
  const pathLinkRegex = /^\/cl\/aaid=.*?&link=(.+)$/;
@@ -9,7 +10,7 @@ const extractQueryLink = createParamExtractor({
9
10
  const unwrapTracdelight = (url) => {
10
11
  const target = extractQueryLink(url);
11
12
  if (target) return target;
12
- if (url.hostname !== "td.oo34.net") return;
13
+ if (!isHostOf(url, "td.oo34.net")) return;
13
14
  const match = pathLinkRegex.exec(url.pathname);
14
15
  if (!match?.[1]) return;
15
16
  return `${match[1]}${url.search}${url.hash}`;
@@ -1,9 +1,9 @@
1
- import { isHttpUrl } from "../node_modules/trousse/dist/urls.mjs";
1
+ import { getQueryParam, isHttpUrl } from "../node_modules/trousse/dist/urls.mjs";
2
2
  import { getParamTarget } from "../utils.mjs";
3
3
  // src/unwraps/twoCheckout.ts
4
4
  const unwrapTwoCheckout = (url) => {
5
5
  if (url.pathname !== "/affiliate.php") return;
6
- if (!url.searchParams.get("ACCOUNT") || !url.searchParams.get("AFFILIATE")) return;
6
+ if (!getQueryParam(url, "ACCOUNT") || !getQueryParam(url, "AFFILIATE")) return;
7
7
  const target = getParamTarget(url, "PATH");
8
8
  if (!target || !isHttpUrl(target)) return;
9
9
  return target;
@@ -26,7 +26,7 @@ const unwrapUnisender = (url) => {
26
26
  const value = getParamTarget(url, "url", -1);
27
27
  if (!value) return;
28
28
  if (isHttpUrl(value)) return value;
29
- const decoded = decodeBase64Url(value.replace(/~/g, "="));
29
+ const decoded = decodeBase64Url(value.replaceAll("~", "="));
30
30
  if (decoded && isHttpUrl(decoded)) return decoded;
31
31
  };
32
32
  export { unwrapUnisender };
@@ -1,8 +1,9 @@
1
+ import { isHostOf } from "../node_modules/trousse/dist/urls.mjs";
1
2
  import { getParamTarget } from "../utils.mjs";
2
3
  // src/unwraps/worldNomads.ts
3
4
  const affiliatePaths = ["/Turnstile/AffiliateLink", "/af.aspx"];
4
5
  const unwrapWorldNomads = (url) => {
5
- if (url.hostname !== "www.worldnomads.com" || !affiliatePaths.includes(url.pathname)) return;
6
+ if (!isHostOf(url, "www.worldnomads.com") || !affiliatePaths.includes(url.pathname)) return;
6
7
  return getParamTarget(url, "path", -1);
7
8
  };
8
9
  export { unwrapWorldNomads };
@@ -1,10 +1,10 @@
1
- import { decodePercent, isHttpUrl } from "../node_modules/trousse/dist/urls.mjs";
1
+ import { decodePercent, getQueryParam, isHttpUrl } from "../node_modules/trousse/dist/urls.mjs";
2
2
  import { getParamValues } from "../utils.mjs";
3
3
  // src/unwraps/yourMembership.ts
4
4
  const ymlinkRegex = /^\d+$/;
5
5
  const encodedSchemeRegex = /^https?%3A/i;
6
6
  const unwrapYourMembership = (url) => {
7
- if (url.pathname !== "/link.asp" || !ymlinkRegex.test(url.searchParams.get("ymlink") ?? "")) return;
7
+ if (url.pathname !== "/link.asp" || !ymlinkRegex.test(getQueryParam(url, "ymlink") ?? "")) return;
8
8
  let target = getParamValues(url, "finalurl").at(0);
9
9
  if (target && encodedSchemeRegex.test(target)) target = decodePercent(target);
10
10
  if (target && isHttpUrl(target)) return target;
package/dist/utils.mjs CHANGED
@@ -62,7 +62,7 @@ const decodeBase64 = (value) => {
62
62
  return decodePercent(encoded);
63
63
  };
64
64
  const toBase64 = (base64Url) => {
65
- return base64Url.replace(/-/g, "+").replace(/_/g, "/");
65
+ return base64Url.replaceAll("-", "+").replaceAll("_", "/");
66
66
  };
67
67
  const decodeBase64Url = (value) => {
68
68
  return decodeBase64(toBase64(value));
package/package.json CHANGED
@@ -42,8 +42,8 @@
42
42
  "devDependencies": {
43
43
  "@types/bun": "^1.4.4",
44
44
  "kvalita": "^1.30.0",
45
- "trousse": "^3.2.0",
45
+ "trousse": "^3.3.0",
46
46
  "tsdown": "0.23.4"
47
47
  },
48
- "version": "2.2.0"
48
+ "version": "2.2.1"
49
49
  }