@etohq/utils 1.5.1-alpha.3 → 1.5.1-alpha.4
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/access-link/case-sensitivity.d.ts +14 -0
- package/dist/access-link/case-sensitivity.d.ts.map +1 -0
- package/dist/access-link/case-sensitivity.js +57 -0
- package/dist/access-link/case-sensitivity.js.map +1 -0
- package/dist/access-link/check-if-key-exists.d.ts +7 -0
- package/dist/access-link/check-if-key-exists.d.ts.map +1 -0
- package/dist/access-link/check-if-key-exists.js +36 -0
- package/dist/access-link/check-if-key-exists.js.map +1 -0
- package/dist/access-link/index.d.ts +11 -0
- package/dist/access-link/index.d.ts.map +1 -0
- package/dist/access-link/index.js +27 -0
- package/dist/access-link/index.js.map +1 -0
- package/dist/access-link/key-checks.d.ts +12 -0
- package/dist/access-link/key-checks.d.ts.map +1 -0
- package/dist/access-link/key-checks.js +78 -0
- package/dist/access-link/key-checks.js.map +1 -0
- package/dist/access-link/link-resolution.d.ts +26 -0
- package/dist/access-link/link-resolution.d.ts.map +1 -0
- package/dist/access-link/link-resolution.js +111 -0
- package/dist/access-link/link-resolution.js.map +1 -0
- package/dist/access-link/link-utils.d.ts +23 -0
- package/dist/access-link/link-utils.d.ts.map +1 -0
- package/dist/access-link/link-utils.js +61 -0
- package/dist/access-link/link-utils.js.map +1 -0
- package/dist/access-link/process-key.d.ts +5 -0
- package/dist/access-link/process-key.d.ts.map +1 -0
- package/dist/access-link/process-key.js +58 -0
- package/dist/access-link/process-key.js.map +1 -0
- package/dist/access-link/process-utils.d.ts +19 -0
- package/dist/access-link/process-utils.d.ts.map +1 -0
- package/dist/access-link/process-utils.js +52 -0
- package/dist/access-link/process-utils.js.map +1 -0
- package/dist/access-link/transform-link.d.ts +47 -0
- package/dist/access-link/transform-link.d.ts.map +1 -0
- package/dist/access-link/transform-link.js +25 -0
- package/dist/access-link/transform-link.js.map +1 -0
- package/dist/access-link/url-detection.d.ts +10 -0
- package/dist/access-link/url-detection.d.ts.map +1 -0
- package/dist/access-link/url-detection.js +63 -0
- package/dist/access-link/url-detection.js.map +1 -0
- package/dist/access-link/validation-utils.d.ts +23 -0
- package/dist/access-link/validation-utils.d.ts.map +1 -0
- package/dist/access-link/validation-utils.js +57 -0
- package/dist/access-link/validation-utils.js.map +1 -0
- package/dist/analytics/detect-bot.d.ts +2 -0
- package/dist/analytics/detect-bot.d.ts.map +1 -0
- package/dist/analytics/detect-bot.js +21 -0
- package/dist/analytics/detect-bot.js.map +1 -0
- package/dist/analytics/detect-qr.d.ts +2 -0
- package/dist/analytics/detect-qr.d.ts.map +1 -0
- package/dist/analytics/detect-qr.js +10 -0
- package/dist/analytics/detect-qr.js.map +1 -0
- package/dist/analytics/get-click-event.d.ts +8 -0
- package/dist/analytics/get-click-event.d.ts.map +1 -0
- package/dist/analytics/get-click-event.js +24 -0
- package/dist/analytics/get-click-event.js.map +1 -0
- package/dist/analytics/get-geolocation.d.ts +12 -0
- package/dist/analytics/get-geolocation.d.ts.map +1 -0
- package/dist/analytics/get-geolocation.js +51 -0
- package/dist/analytics/get-geolocation.js.map +1 -0
- package/dist/analytics/get-grant-event.d.ts +8 -0
- package/dist/analytics/get-grant-event.d.ts.map +1 -0
- package/dist/analytics/get-grant-event.js +24 -0
- package/dist/analytics/get-grant-event.js.map +1 -0
- package/dist/analytics/get-import-error-logs.d.ts +17 -0
- package/dist/analytics/get-import-error-logs.d.ts.map +1 -0
- package/dist/analytics/get-import-error-logs.js +23 -0
- package/dist/analytics/get-import-error-logs.js.map +1 -0
- package/dist/analytics/get-lead-events.d.ts +17 -0
- package/dist/analytics/get-lead-events.d.ts.map +1 -0
- package/dist/analytics/get-lead-events.js +17 -0
- package/dist/analytics/get-lead-events.js.map +1 -0
- package/dist/analytics/get-webhook-events.d.ts +17 -0
- package/dist/analytics/get-webhook-events.d.ts.map +1 -0
- package/dist/analytics/get-webhook-events.js +22 -0
- package/dist/analytics/get-webhook-events.js.map +1 -0
- package/dist/analytics/index.d.ts +18 -0
- package/dist/analytics/index.d.ts.map +1 -1
- package/dist/analytics/index.js +18 -0
- package/dist/analytics/index.js.map +1 -1
- package/dist/analytics/log-conversion-events.d.ts +6 -0
- package/dist/analytics/log-conversion-events.d.ts.map +1 -0
- package/dist/analytics/log-conversion-events.js +20 -0
- package/dist/analytics/log-conversion-events.js.map +1 -0
- package/dist/analytics/log-import-error.d.ts +6 -0
- package/dist/analytics/log-import-error.d.ts.map +1 -0
- package/dist/analytics/log-import-error.js +18 -0
- package/dist/analytics/log-import-error.js.map +1 -0
- package/dist/analytics/parse-user-agent.d.ts +13 -0
- package/dist/analytics/parse-user-agent.d.ts.map +1 -0
- package/dist/analytics/parse-user-agent.js +174 -0
- package/dist/analytics/parse-user-agent.js.map +1 -0
- package/dist/analytics/record-approval.d.ts +56 -0
- package/dist/analytics/record-approval.d.ts.map +1 -0
- package/dist/analytics/record-approval.js +32 -0
- package/dist/analytics/record-approval.js.map +1 -0
- package/dist/analytics/record-click.d.ts +32 -0
- package/dist/analytics/record-click.d.ts.map +1 -0
- package/dist/analytics/record-click.js +136 -0
- package/dist/analytics/record-click.js.map +1 -0
- package/dist/analytics/record-lead.d.ts +24 -0
- package/dist/analytics/record-lead.d.ts.map +1 -0
- package/dist/analytics/record-lead.js +72 -0
- package/dist/analytics/record-lead.js.map +1 -0
- package/dist/analytics/record-link.d.ts +106 -0
- package/dist/analytics/record-link.d.ts.map +1 -0
- package/dist/analytics/record-link.js +78 -0
- package/dist/analytics/record-link.js.map +1 -0
- package/dist/analytics/record-sale.d.ts +10 -0
- package/dist/analytics/record-sale.d.ts.map +1 -0
- package/dist/analytics/record-sale.js +35 -0
- package/dist/analytics/record-sale.js.map +1 -0
- package/dist/analytics/record-webhook-event.d.ts +26 -0
- package/dist/analytics/record-webhook-event.d.ts.map +1 -0
- package/dist/analytics/record-webhook-event.js +22 -0
- package/dist/analytics/record-webhook-event.js.map +1 -0
- package/dist/analytics/schemas.d.ts +257 -0
- package/dist/analytics/schemas.d.ts.map +1 -0
- package/dist/analytics/schemas.js +99 -0
- package/dist/analytics/schemas.js.map +1 -0
- package/dist/analytics/tinybird-client.d.ts +6 -0
- package/dist/analytics/tinybird-client.d.ts.map +1 -0
- package/dist/analytics/tinybird-client.js +11 -0
- package/dist/analytics/tinybird-client.js.map +1 -0
- package/dist/common/constants.d.ts +24 -0
- package/dist/common/constants.d.ts.map +1 -0
- package/dist/common/constants.js +196 -0
- package/dist/common/constants.js.map +1 -0
- package/dist/common/domains.d.ts +8 -0
- package/dist/common/domains.d.ts.map +1 -0
- package/dist/common/domains.js +88 -0
- package/dist/common/domains.js.map +1 -0
- package/dist/common/dynamic-import.d.ts.map +1 -1
- package/dist/common/dynamic-import.js +24 -1
- package/dist/common/dynamic-import.js.map +1 -1
- package/dist/common/fetch-with-retry.d.ts +6 -0
- package/dist/common/fetch-with-retry.d.ts.map +1 -0
- package/dist/common/fetch-with-retry.js +63 -0
- package/dist/common/fetch-with-retry.js.map +1 -0
- package/dist/common/get-identity-hash.d.ts +2 -0
- package/dist/common/get-identity-hash.d.ts.map +1 -0
- package/dist/common/get-identity-hash.js +19 -0
- package/dist/common/get-identity-hash.js.map +1 -0
- package/dist/common/index.d.ts +3 -0
- package/dist/common/index.d.ts.map +1 -1
- package/dist/common/index.js +3 -0
- package/dist/common/index.js.map +1 -1
- package/dist/common/is-valid-url.d.ts +2 -0
- package/dist/common/is-valid-url.d.ts.map +1 -0
- package/dist/common/is-valid-url.js +14 -0
- package/dist/common/is-valid-url.js.map +1 -0
- package/dist/common/reserved-slugs.d.ts +7 -0
- package/dist/common/reserved-slugs.d.ts.map +1 -0
- package/dist/common/reserved-slugs.js +64 -0
- package/dist/common/reserved-slugs.js.map +1 -0
- package/dist/common/to-snake-case.d.ts +5 -0
- package/dist/common/to-snake-case.d.ts.map +1 -0
- package/dist/common/to-snake-case.js +14 -0
- package/dist/common/to-snake-case.js.map +1 -0
- package/dist/dml/entity-builder.d.ts +68 -0
- package/dist/dml/entity-builder.d.ts.map +1 -1
- package/dist/dml/entity-builder.js +76 -0
- package/dist/dml/entity-builder.js.map +1 -1
- package/dist/dml/helpers/entity-builder/define-property.d.ts.map +1 -1
- package/dist/dml/helpers/entity-builder/define-property.js +77 -0
- package/dist/dml/helpers/entity-builder/define-property.js.map +1 -1
- package/dist/dml/helpers/mikro-orm/custom-type/geo-json-geometry.d.ts +10 -0
- package/dist/dml/helpers/mikro-orm/custom-type/geo-json-geometry.d.ts.map +1 -0
- package/dist/dml/helpers/mikro-orm/custom-type/geo-json-geometry.js +31 -0
- package/dist/dml/helpers/mikro-orm/custom-type/geo-json-geometry.js.map +1 -0
- package/dist/dml/properties/enum.d.ts.map +1 -1
- package/dist/dml/properties/enum.js +0 -1
- package/dist/dml/properties/enum.js.map +1 -1
- package/dist/dml/properties/geometry.d.ts +8 -0
- package/dist/dml/properties/geometry.d.ts.map +1 -0
- package/dist/dml/properties/geometry.js +14 -0
- package/dist/dml/properties/geometry.js.map +1 -0
- package/dist/dml/properties/index.d.ts +4 -0
- package/dist/dml/properties/index.d.ts.map +1 -1
- package/dist/dml/properties/index.js +4 -0
- package/dist/dml/properties/index.js.map +1 -1
- package/dist/dml/properties/multipolygon.d.ts +8 -0
- package/dist/dml/properties/multipolygon.d.ts.map +1 -0
- package/dist/dml/properties/multipolygon.js +14 -0
- package/dist/dml/properties/multipolygon.js.map +1 -0
- package/dist/dml/properties/point.d.ts +8 -0
- package/dist/dml/properties/point.d.ts.map +1 -0
- package/dist/dml/properties/point.js +14 -0
- package/dist/dml/properties/point.js.map +1 -0
- package/dist/dml/properties/polygon.d.ts +8 -0
- package/dist/dml/properties/polygon.d.ts.map +1 -0
- package/dist/dml/properties/polygon.js +14 -0
- package/dist/dml/properties/polygon.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/modules-sdk/build-query.d.ts.map +1 -1
- package/dist/modules-sdk/build-query.js +3 -1
- package/dist/modules-sdk/build-query.js.map +1 -1
- package/dist/modules-sdk/definition.d.ts +18 -0
- package/dist/modules-sdk/definition.d.ts.map +1 -1
- package/dist/modules-sdk/definition.js +12 -0
- package/dist/modules-sdk/definition.js.map +1 -1
- package/dist/modules-sdk/spatial-query-processor.d.ts +2 -0
- package/dist/modules-sdk/spatial-query-processor.d.ts.map +1 -0
- package/dist/modules-sdk/spatial-query-processor.js +105 -0
- package/dist/modules-sdk/spatial-query-processor.js.map +1 -0
- package/dist/permissions/ability.d.ts +39 -0
- package/dist/permissions/ability.d.ts.map +1 -0
- package/dist/permissions/ability.js +51 -0
- package/dist/permissions/ability.js.map +1 -0
- package/dist/permissions/context-builder.d.ts +24 -0
- package/dist/permissions/context-builder.d.ts.map +1 -0
- package/dist/permissions/context-builder.js +30 -0
- package/dist/permissions/context-builder.js.map +1 -0
- package/dist/permissions/index.d.ts +4 -0
- package/dist/permissions/index.d.ts.map +1 -0
- package/dist/permissions/index.js +20 -0
- package/dist/permissions/index.js.map +1 -0
- package/dist/permissions/permission-service.d.ts +8 -0
- package/dist/permissions/permission-service.d.ts.map +1 -0
- package/dist/permissions/permission-service.js +20 -0
- package/dist/permissions/permission-service.js.map +1 -0
- package/dist/permissions/types.d.ts +17 -0
- package/dist/permissions/types.d.ts.map +1 -0
- package/dist/permissions/types.js +11 -0
- package/dist/permissions/types.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/zod/schemas/approvals.d.ts +91 -0
- package/dist/zod/schemas/approvals.d.ts.map +1 -0
- package/dist/zod/schemas/approvals.js +38 -0
- package/dist/zod/schemas/approvals.js.map +1 -0
- package/dist/zod/schemas/clicks.d.ts +394 -0
- package/dist/zod/schemas/clicks.d.ts.map +1 -0
- package/dist/zod/schemas/clicks.js +85 -0
- package/dist/zod/schemas/clicks.js.map +1 -0
- package/dist/zod/schemas/leads.d.ts +423 -0
- package/dist/zod/schemas/leads.d.ts.map +1 -0
- package/dist/zod/schemas/leads.js +58 -0
- package/dist/zod/schemas/leads.js.map +1 -0
- package/package.json +8 -2
- package/dist/feature-flags/eto-v2.d.ts +0 -3
- package/dist/feature-flags/eto-v2.d.ts.map +0 -1
- package/dist/feature-flags/eto-v2.js +0 -10
- package/dist/feature-flags/eto-v2.js.map +0 -1
- package/dist/feature-flags/order-editing.d.ts +0 -3
- package/dist/feature-flags/order-editing.d.ts.map +0 -1
- package/dist/feature-flags/order-editing.js +0 -10
- package/dist/feature-flags/order-editing.js.map +0 -1
- package/dist/feature-flags/product-categories.d.ts +0 -3
- package/dist/feature-flags/product-categories.d.ts.map +0 -1
- package/dist/feature-flags/product-categories.js +0 -10
- package/dist/feature-flags/product-categories.js.map +0 -1
- package/dist/feature-flags/sales-channels.d.ts +0 -3
- package/dist/feature-flags/sales-channels.d.ts.map +0 -1
- package/dist/feature-flags/sales-channels.js +0 -10
- package/dist/feature-flags/sales-channels.js.map +0 -1
- package/dist/feature-flags/tax-inclusive-pricing.d.ts +0 -3
- package/dist/feature-flags/tax-inclusive-pricing.d.ts.map +0 -1
- package/dist/feature-flags/tax-inclusive-pricing.js +0 -10
- package/dist/feature-flags/tax-inclusive-pricing.js.map +0 -1
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export declare const CASE_SENSITIVE_DOMAINS: string[];
|
|
2
|
+
export declare const encodeKey: (text: string) => string;
|
|
3
|
+
export declare const decodeKey: (hash: string) => string;
|
|
4
|
+
export declare const isCaseSensitiveDomain: (domain: string) => boolean;
|
|
5
|
+
export declare const encodeKeyIfCaseSensitive: ({ domain, key, }: {
|
|
6
|
+
domain: string;
|
|
7
|
+
key: string;
|
|
8
|
+
}) => string;
|
|
9
|
+
export declare const decodeKeyIfCaseSensitive: ({ domain, key, }: {
|
|
10
|
+
domain: string;
|
|
11
|
+
key: string;
|
|
12
|
+
}) => string;
|
|
13
|
+
export declare const decodeLinkIfCaseSensitive: (link: any) => any;
|
|
14
|
+
//# sourceMappingURL=case-sensitivity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"case-sensitivity.d.ts","sourceRoot":"","sources":["../../src/access-link/case-sensitivity.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,sBAAsB,UAElC,CAAA;AAED,eAAO,MAAM,SAAS,GAAI,MAAM,MAAM,KAAG,MAcxC,CAAA;AAED,eAAO,MAAM,SAAS,GAAI,MAAM,MAAM,KAAG,MAcxC,CAAA;AAED,eAAO,MAAM,qBAAqB,GAAI,QAAQ,MAAM,YAEnD,CAAA;AAED,eAAO,MAAM,wBAAwB,GAAI,kBAGtC;IACD,MAAM,EAAE,MAAM,CAAA;IACd,GAAG,EAAE,MAAM,CAAA;CACZ,WAEA,CAAA;AAED,eAAO,MAAM,wBAAwB,GAAI,kBAGtC;IACD,MAAM,EAAE,MAAM,CAAA;IACd,GAAG,EAAE,MAAM,CAAA;CACZ,WAEA,CAAA;AAED,eAAO,MAAM,yBAAyB,GAAI,MAAM,GAAG,QAclD,CAAA"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Case sensitivity utilities for access links (following Dub's pattern)
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.decodeLinkIfCaseSensitive = exports.decodeKeyIfCaseSensitive = exports.encodeKeyIfCaseSensitive = exports.isCaseSensitiveDomain = exports.decodeKey = exports.encodeKey = exports.CASE_SENSITIVE_DOMAINS = void 0;
|
|
5
|
+
const XOR_SECRET_KEY = "58ff90c0dc372ded858cbf8fb2306066";
|
|
6
|
+
exports.CASE_SENSITIVE_DOMAINS = [
|
|
7
|
+
"invite.app.com", // Add your case-sensitive domains here
|
|
8
|
+
];
|
|
9
|
+
const encodeKey = (text) => {
|
|
10
|
+
if (!text)
|
|
11
|
+
return "";
|
|
12
|
+
const xored = text
|
|
13
|
+
.split("")
|
|
14
|
+
.map((char, i) => String.fromCharCode(char.charCodeAt(0) ^
|
|
15
|
+
XOR_SECRET_KEY.charCodeAt(i % XOR_SECRET_KEY.length)))
|
|
16
|
+
.join("");
|
|
17
|
+
return Buffer.from(xored).toString("base64");
|
|
18
|
+
};
|
|
19
|
+
exports.encodeKey = encodeKey;
|
|
20
|
+
const decodeKey = (hash) => {
|
|
21
|
+
if (!hash)
|
|
22
|
+
return "";
|
|
23
|
+
const xored = Buffer.from(hash, "base64").toString();
|
|
24
|
+
return xored
|
|
25
|
+
.split("")
|
|
26
|
+
.map((char, i) => String.fromCharCode(char.charCodeAt(0) ^
|
|
27
|
+
XOR_SECRET_KEY.charCodeAt(i % XOR_SECRET_KEY.length)))
|
|
28
|
+
.join("");
|
|
29
|
+
};
|
|
30
|
+
exports.decodeKey = decodeKey;
|
|
31
|
+
const isCaseSensitiveDomain = (domain) => {
|
|
32
|
+
return exports.CASE_SENSITIVE_DOMAINS.includes(domain);
|
|
33
|
+
};
|
|
34
|
+
exports.isCaseSensitiveDomain = isCaseSensitiveDomain;
|
|
35
|
+
const encodeKeyIfCaseSensitive = ({ domain, key, }) => {
|
|
36
|
+
return (0, exports.isCaseSensitiveDomain)(domain) ? (0, exports.encodeKey)(key) : key;
|
|
37
|
+
};
|
|
38
|
+
exports.encodeKeyIfCaseSensitive = encodeKeyIfCaseSensitive;
|
|
39
|
+
const decodeKeyIfCaseSensitive = ({ domain, key, }) => {
|
|
40
|
+
return (0, exports.isCaseSensitiveDomain)(domain) ? (0, exports.decodeKey)(key) : key;
|
|
41
|
+
};
|
|
42
|
+
exports.decodeKeyIfCaseSensitive = decodeKeyIfCaseSensitive;
|
|
43
|
+
const decodeLinkIfCaseSensitive = (link) => {
|
|
44
|
+
if ((0, exports.isCaseSensitiveDomain)(link.domain)) {
|
|
45
|
+
const originalKey = (0, exports.decodeKey)(link.key);
|
|
46
|
+
return {
|
|
47
|
+
...link,
|
|
48
|
+
key: originalKey,
|
|
49
|
+
...(link.short_link && {
|
|
50
|
+
short_link: `https://${link.domain}${originalKey === "_root" ? "" : `/${originalKey}`}`,
|
|
51
|
+
}),
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
return link;
|
|
55
|
+
};
|
|
56
|
+
exports.decodeLinkIfCaseSensitive = decodeLinkIfCaseSensitive;
|
|
57
|
+
//# sourceMappingURL=case-sensitivity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"case-sensitivity.js","sourceRoot":"","sources":["../../src/access-link/case-sensitivity.ts"],"names":[],"mappings":";AAAA,wEAAwE;;;AAExE,MAAM,cAAc,GAAG,kCAAkC,CAAA;AAE5C,QAAA,sBAAsB,GAAG;IACpC,gBAAgB,EAAE,uCAAuC;CAC1D,CAAA;AAEM,MAAM,SAAS,GAAG,CAAC,IAAY,EAAU,EAAE;IAChD,IAAI,CAAC,IAAI;QAAE,OAAO,EAAE,CAAA;IAEpB,MAAM,KAAK,GAAG,IAAI;SACf,KAAK,CAAC,EAAE,CAAC;SACT,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CACf,MAAM,CAAC,YAAY,CACjB,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;QAChB,cAAc,CAAC,UAAU,CAAC,CAAC,GAAG,cAAc,CAAC,MAAM,CAAC,CACvD,CACF;SACA,IAAI,CAAC,EAAE,CAAC,CAAA;IAEX,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAA;AAC9C,CAAC,CAAA;AAdY,QAAA,SAAS,aAcrB;AAEM,MAAM,SAAS,GAAG,CAAC,IAAY,EAAU,EAAE;IAChD,IAAI,CAAC,IAAI;QAAE,OAAO,EAAE,CAAA;IAEpB,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,QAAQ,EAAE,CAAA;IAEpD,OAAO,KAAK;SACT,KAAK,CAAC,EAAE,CAAC;SACT,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CACf,MAAM,CAAC,YAAY,CACjB,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;QAChB,cAAc,CAAC,UAAU,CAAC,CAAC,GAAG,cAAc,CAAC,MAAM,CAAC,CACvD,CACF;SACA,IAAI,CAAC,EAAE,CAAC,CAAA;AACb,CAAC,CAAA;AAdY,QAAA,SAAS,aAcrB;AAEM,MAAM,qBAAqB,GAAG,CAAC,MAAc,EAAE,EAAE;IACtD,OAAO,8BAAsB,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAA;AAChD,CAAC,CAAA;AAFY,QAAA,qBAAqB,yBAEjC;AAEM,MAAM,wBAAwB,GAAG,CAAC,EACvC,MAAM,EACN,GAAG,GAIJ,EAAE,EAAE;IACH,OAAO,IAAA,6BAAqB,EAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAA,iBAAS,EAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAA;AAC7D,CAAC,CAAA;AARY,QAAA,wBAAwB,4BAQpC;AAEM,MAAM,wBAAwB,GAAG,CAAC,EACvC,MAAM,EACN,GAAG,GAIJ,EAAE,EAAE;IACH,OAAO,IAAA,6BAAqB,EAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAA,iBAAS,EAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAA;AAC7D,CAAC,CAAA;AARY,QAAA,wBAAwB,4BAQpC;AAEM,MAAM,yBAAyB,GAAG,CAAC,IAAS,EAAE,EAAE;IACrD,IAAI,IAAA,6BAAqB,EAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QACvC,MAAM,WAAW,GAAG,IAAA,iBAAS,EAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QAEvC,OAAO;YACL,GAAG,IAAI;YACP,GAAG,EAAE,WAAW;YAChB,GAAG,CAAC,IAAI,CAAC,UAAU,IAAI;gBACrB,UAAU,EAAE,WAAW,IAAI,CAAC,MAAM,GAAG,WAAW,KAAK,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,WAAW,EAAE,EAAE;aACxF,CAAC;SACH,CAAA;IACH,CAAC;IAED,OAAO,IAAI,CAAA;AACb,CAAC,CAAA;AAdY,QAAA,yBAAyB,6BAcrC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check-if-key-exists.d.ts","sourceRoot":"","sources":["../../src/access-link/check-if-key-exists.ts"],"names":[],"mappings":"AAWA,eAAO,MAAM,gBAAgB,GAAU,yCAKpC;IACD,MAAM,EAAE,MAAM,CAAA;IACd,GAAG,EAAE,MAAM,CAAA;IACX,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,GAAG,CAAA;CAChB,iBAsBA,CAAA"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.checkIfKeyExists = void 0;
|
|
4
|
+
const case_sensitivity_1 = require("./case-sensitivity");
|
|
5
|
+
// Punycode encoding for international characters
|
|
6
|
+
const punyEncode = (key) => {
|
|
7
|
+
try {
|
|
8
|
+
return new URL(`http://${key}`).hostname;
|
|
9
|
+
}
|
|
10
|
+
catch {
|
|
11
|
+
return key;
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
const checkIfKeyExists = async ({ domain, key, projectId, dataSource, }) => {
|
|
15
|
+
const isCaseSensitive = (0, case_sensitivity_1.isCaseSensitiveDomain)(domain);
|
|
16
|
+
const keyToQuery = isCaseSensitive
|
|
17
|
+
? // for case sensitive domains, we need to encode the key
|
|
18
|
+
(0, case_sensitivity_1.encodeKey)(key)
|
|
19
|
+
: // for non-case sensitive domains, we need to make sure that the key is always URI-decoded + punycode-encoded
|
|
20
|
+
punyEncode(decodeURIComponent(key));
|
|
21
|
+
// Query ETO access_link table
|
|
22
|
+
const query = projectId
|
|
23
|
+
? "SELECT 1 FROM access_link WHERE domain = ? AND key = ? AND project_id = ? AND deleted_at IS NULL LIMIT 1"
|
|
24
|
+
: "SELECT 1 FROM access_link WHERE domain = ? AND key = ? AND deleted_at IS NULL LIMIT 1";
|
|
25
|
+
const params = projectId ? [domain, keyToQuery, projectId] : [domain, keyToQuery];
|
|
26
|
+
try {
|
|
27
|
+
const result = await dataSource.query(query, params);
|
|
28
|
+
return result && Array.isArray(result) && result.length > 0;
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
console.error("Error checking key existence:", error);
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
exports.checkIfKeyExists = checkIfKeyExists;
|
|
36
|
+
//# sourceMappingURL=check-if-key-exists.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check-if-key-exists.js","sourceRoot":"","sources":["../../src/access-link/check-if-key-exists.ts"],"names":[],"mappings":";;;AAAA,yDAAqE;AAErE,iDAAiD;AACjD,MAAM,UAAU,GAAG,CAAC,GAAW,EAAU,EAAE;IACzC,IAAI,CAAC;QACH,OAAO,IAAI,GAAG,CAAC,UAAU,GAAG,EAAE,CAAC,CAAC,QAAQ,CAAA;IAC1C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,GAAG,CAAA;IACZ,CAAC;AACH,CAAC,CAAA;AAEM,MAAM,gBAAgB,GAAG,KAAK,EAAE,EACrC,MAAM,EACN,GAAG,EACH,SAAS,EACT,UAAU,GAMX,EAAE,EAAE;IACH,MAAM,eAAe,GAAG,IAAA,wCAAqB,EAAC,MAAM,CAAC,CAAA;IACrD,MAAM,UAAU,GAAG,eAAe;QAChC,CAAC,CAAC,wDAAwD;YACxD,IAAA,4BAAS,EAAC,GAAG,CAAC;QAChB,CAAC,CAAC,6GAA6G;YAC7G,UAAU,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,CAAA;IAEvC,8BAA8B;IAC9B,MAAM,KAAK,GAAG,SAAS;QACrB,CAAC,CAAC,0GAA0G;QAC5G,CAAC,CAAC,uFAAuF,CAAA;IAE3F,MAAM,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;IAEjF,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC,CAAA;QACpD,OAAO,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,CAAA;IAC7D,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,+BAA+B,EAAE,KAAK,CAAC,CAAA;QACrD,OAAO,KAAK,CAAA;IACd,CAAC;AACH,CAAC,CAAA;AAhCY,QAAA,gBAAgB,oBAgC5B"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export * from "./link-utils";
|
|
2
|
+
export * from "./case-sensitivity";
|
|
3
|
+
export * from "./transform-link";
|
|
4
|
+
export * from "./validation-utils";
|
|
5
|
+
export * from "./process-utils";
|
|
6
|
+
export * from "./process-key";
|
|
7
|
+
export * from "./key-checks";
|
|
8
|
+
export * from "./check-if-key-exists";
|
|
9
|
+
export * from "./url-detection";
|
|
10
|
+
export * from "./link-resolution";
|
|
11
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/access-link/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAA;AAC5B,cAAc,oBAAoB,CAAA;AAClC,cAAc,kBAAkB,CAAA;AAChC,cAAc,oBAAoB,CAAA;AAClC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,eAAe,CAAA;AAC7B,cAAc,cAAc,CAAA;AAC5B,cAAc,uBAAuB,CAAA;AACrC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,mBAAmB,CAAA"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./link-utils"), exports);
|
|
18
|
+
__exportStar(require("./case-sensitivity"), exports);
|
|
19
|
+
__exportStar(require("./transform-link"), exports);
|
|
20
|
+
__exportStar(require("./validation-utils"), exports);
|
|
21
|
+
__exportStar(require("./process-utils"), exports);
|
|
22
|
+
__exportStar(require("./process-key"), exports);
|
|
23
|
+
__exportStar(require("./key-checks"), exports);
|
|
24
|
+
__exportStar(require("./check-if-key-exists"), exports);
|
|
25
|
+
__exportStar(require("./url-detection"), exports);
|
|
26
|
+
__exportStar(require("./link-resolution"), exports);
|
|
27
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/access-link/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,+CAA4B;AAC5B,qDAAkC;AAClC,mDAAgC;AAChC,qDAAkC;AAClC,kDAA+B;AAC/B,gDAA6B;AAC7B,+CAA4B;AAC5B,wDAAqC;AACrC,kDAA+B;AAC/B,oDAAiC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export interface KeyCheckResult {
|
|
2
|
+
error: string | null;
|
|
3
|
+
code?: 'forbidden' | 'conflict' | 'invalid';
|
|
4
|
+
}
|
|
5
|
+
export declare function keyChecks({ domain, key, projectId, dataSource, checkExisting, }: {
|
|
6
|
+
domain: string;
|
|
7
|
+
key: string;
|
|
8
|
+
projectId?: string;
|
|
9
|
+
dataSource?: any;
|
|
10
|
+
checkExisting?: boolean;
|
|
11
|
+
}): Promise<KeyCheckResult>;
|
|
12
|
+
//# sourceMappingURL=key-checks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"key-checks.d.ts","sourceRoot":"","sources":["../../src/access-link/key-checks.ts"],"names":[],"mappings":"AAgCA,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,IAAI,CAAC,EAAE,WAAW,GAAG,UAAU,GAAG,SAAS,CAAA;CAC5C;AAED,wBAAsB,SAAS,CAAC,EAC9B,MAAM,EACN,GAAG,EACH,SAAS,EACT,UAAU,EACV,aAAoB,GACrB,EAAE;IACD,MAAM,EAAE,MAAM,CAAA;IACd,GAAG,EAAE,MAAM,CAAA;IACX,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,UAAU,CAAC,EAAE,GAAG,CAAA;IAChB,aAAa,CAAC,EAAE,OAAO,CAAA;CACxB,GAAG,OAAO,CAAC,cAAc,CAAC,CAoD1B"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.keyChecks = keyChecks;
|
|
4
|
+
const check_if_key_exists_1 = require("./check-if-key-exists");
|
|
5
|
+
// Key validation checks for ETO access links (following Dub's key-checks pattern)
|
|
6
|
+
// Reserved keys that cannot be used globally
|
|
7
|
+
const RESERVED_KEYS_GLOBAL = new Set([
|
|
8
|
+
'api', 'app', 'www', 'mail', 'ftp', 'admin', 'root', 'dashboard',
|
|
9
|
+
'analytics', 'settings', 'billing', 'support', 'help', 'docs', 'blog',
|
|
10
|
+
'status', 'legal', 'privacy', 'terms', 'security', 'contact', 'about',
|
|
11
|
+
'login', 'signup', 'register', 'auth', 'oauth', 'callback', 'webhook',
|
|
12
|
+
'health', 'ping', 'metrics', 'monitoring', 'logs', 'debug'
|
|
13
|
+
]);
|
|
14
|
+
// ETO-specific reserved keys
|
|
15
|
+
const RESERVED_KEYS_ETO = new Set([
|
|
16
|
+
'access', 'grant', 'approve', 'reject', 'invite', 'join', 'share',
|
|
17
|
+
'link', 'links', 'project', 'projects', 'workspace', 'workspaces',
|
|
18
|
+
'tenant', 'tenants', 'resource', 'resources', 'permission', 'permissions'
|
|
19
|
+
]);
|
|
20
|
+
const isReservedKeyGlobal = (key) => {
|
|
21
|
+
return RESERVED_KEYS_GLOBAL.has(key.toLowerCase());
|
|
22
|
+
};
|
|
23
|
+
const isReservedKeyETO = (key) => {
|
|
24
|
+
return RESERVED_KEYS_ETO.has(key.toLowerCase());
|
|
25
|
+
};
|
|
26
|
+
const isETODomain = (domain) => {
|
|
27
|
+
return domain.includes('eto.') || domain.includes('shopabox.');
|
|
28
|
+
};
|
|
29
|
+
async function keyChecks({ domain, key, projectId, dataSource, checkExisting = true, }) {
|
|
30
|
+
// Root domain check - always allowed for ETO (no plan restrictions)
|
|
31
|
+
if (key.length === 0 || key === "_root") {
|
|
32
|
+
return { error: null };
|
|
33
|
+
}
|
|
34
|
+
// Global reserved key check
|
|
35
|
+
if (isReservedKeyGlobal(key)) {
|
|
36
|
+
return {
|
|
37
|
+
error: `"${key}" is a reserved keyword and cannot be used.`,
|
|
38
|
+
code: 'forbidden'
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
// ETO domain specific checks
|
|
42
|
+
if (isETODomain(domain) && isReservedKeyETO(key)) {
|
|
43
|
+
return {
|
|
44
|
+
error: `"${key}" is reserved for ETO system use and cannot be used.`,
|
|
45
|
+
code: 'forbidden'
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
// Key length validation
|
|
49
|
+
if (key.length > 100) {
|
|
50
|
+
return {
|
|
51
|
+
error: 'Key cannot be longer than 100 characters.',
|
|
52
|
+
code: 'invalid'
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
// Database check for existing keys
|
|
56
|
+
if (checkExisting && dataSource) {
|
|
57
|
+
try {
|
|
58
|
+
const exists = await (0, check_if_key_exists_1.checkIfKeyExists)({
|
|
59
|
+
domain,
|
|
60
|
+
key,
|
|
61
|
+
projectId,
|
|
62
|
+
dataSource
|
|
63
|
+
});
|
|
64
|
+
if (exists) {
|
|
65
|
+
return {
|
|
66
|
+
error: `Key "${key}" already exists for this domain.`,
|
|
67
|
+
code: 'conflict'
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
console.error("Error checking key existence:", error);
|
|
73
|
+
// Don't fail the validation if DB check fails
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return { error: null };
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=key-checks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"key-checks.js","sourceRoot":"","sources":["../../src/access-link/key-checks.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A/B test variant resolution following Dub's resolveABTestURL exact implementation
|
|
3
|
+
*/
|
|
4
|
+
export declare function resolveABTestVariant(testVariants?: Array<{
|
|
5
|
+
url: string;
|
|
6
|
+
percentage: number;
|
|
7
|
+
}>, testCompletedAt?: Date): string | null;
|
|
8
|
+
/**
|
|
9
|
+
* Get final URL following Dub's getFinalUrl exact pattern
|
|
10
|
+
*/
|
|
11
|
+
export declare function getFinalUrl(originalUrl: string, options: {
|
|
12
|
+
clickId?: string;
|
|
13
|
+
via?: string;
|
|
14
|
+
userAgent?: string;
|
|
15
|
+
ip?: string;
|
|
16
|
+
noTrack?: boolean;
|
|
17
|
+
shortLink?: string;
|
|
18
|
+
}): string;
|
|
19
|
+
/**
|
|
20
|
+
* Device targeting resolution following Dub's iOS/Android redirect exact pattern
|
|
21
|
+
*/
|
|
22
|
+
export declare function resolveDeviceTargeting(iosUrl?: string, androidUrl?: string, userAgent?: string): {
|
|
23
|
+
url: string;
|
|
24
|
+
isAppStore: boolean;
|
|
25
|
+
} | null;
|
|
26
|
+
//# sourceMappingURL=link-resolution.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"link-resolution.d.ts","sourceRoot":"","sources":["../../src/access-link/link-resolution.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,YAAY,CAAC,EAAE,KAAK,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC,EACzD,eAAe,CAAC,EAAE,IAAI,GACrB,MAAM,GAAG,IAAI,CAuCf;AAED;;GAEG;AACH,wBAAgB,WAAW,CACzB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE;IACP,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB,GACA,MAAM,CA4CR;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,CAAC,EAAE,MAAM,EACf,UAAU,CAAC,EAAE,MAAM,EACnB,SAAS,CAAC,EAAE,MAAM,GACjB;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,OAAO,CAAA;CAAE,GAAG,IAAI,CAwB7C"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.resolveABTestVariant = resolveABTestVariant;
|
|
4
|
+
exports.getFinalUrl = getFinalUrl;
|
|
5
|
+
exports.resolveDeviceTargeting = resolveDeviceTargeting;
|
|
6
|
+
const url_detection_1 = require("./url-detection");
|
|
7
|
+
/**
|
|
8
|
+
* A/B test variant resolution following Dub's resolveABTestURL exact implementation
|
|
9
|
+
*/
|
|
10
|
+
function resolveABTestVariant(testVariants, testCompletedAt) {
|
|
11
|
+
try {
|
|
12
|
+
// Following Dub's exact validation logic
|
|
13
|
+
if (!testVariants || !testCompletedAt || !(new Date(testCompletedAt) > new Date())) {
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
// Following Dub's MAX_TEST_COUNT = 4, min 2 variants
|
|
17
|
+
if (testVariants.length < 2 || testVariants.length > 4) {
|
|
18
|
+
console.error(`Invalid test count: ${testVariants.length} for link.`);
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
// Following Dub's weighted random selection algorithm exactly
|
|
22
|
+
let i = 0;
|
|
23
|
+
const weights = [testVariants[0].percentage];
|
|
24
|
+
// Calculate cumulative weights
|
|
25
|
+
for (i = 1; i < testVariants.length; ++i) {
|
|
26
|
+
weights[i] = testVariants[i].percentage + weights[i - 1];
|
|
27
|
+
}
|
|
28
|
+
// Generate a random number between 0 and the total cumulative weight
|
|
29
|
+
const random = Math.random() * weights[weights.length - 1];
|
|
30
|
+
// Loop through cumulative weights and stop when we've found the first one greater than `random`
|
|
31
|
+
for (i = 0; i < weights.length; ++i) {
|
|
32
|
+
if (weights[i] > random) {
|
|
33
|
+
break;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
console.log("Found test variant", testVariants[i]);
|
|
37
|
+
return testVariants[i].url;
|
|
38
|
+
}
|
|
39
|
+
catch (e) {
|
|
40
|
+
console.error("Error resolving AB test URL.", e);
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Get final URL following Dub's getFinalUrl exact pattern
|
|
46
|
+
*/
|
|
47
|
+
function getFinalUrl(originalUrl, options) {
|
|
48
|
+
try {
|
|
49
|
+
const urlObj = new URL(originalUrl);
|
|
50
|
+
// Add via parameter (following Dub's pattern)
|
|
51
|
+
if (options.via) {
|
|
52
|
+
urlObj.searchParams.set("via", options.via);
|
|
53
|
+
}
|
|
54
|
+
// Add click ID for tracking (following Dub's exact logic)
|
|
55
|
+
if (options.clickId) {
|
|
56
|
+
// ETO equivalent of Dub's Stripe integration check
|
|
57
|
+
if (urlObj.searchParams.get("eto_client_reference_id") === "1") {
|
|
58
|
+
urlObj.searchParams.set("client_reference_id", `eto_id_${options.clickId}`);
|
|
59
|
+
urlObj.searchParams.delete("eto_client_reference_id");
|
|
60
|
+
}
|
|
61
|
+
else if (!options.noTrack) {
|
|
62
|
+
// Following Dub's dub-no-track pattern
|
|
63
|
+
urlObj.searchParams.set("eto_id", options.clickId);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
// For Singular tracking links (following Dub's exact pattern)
|
|
67
|
+
if ((0, url_detection_1.isSingularTrackingUrl)(originalUrl)) {
|
|
68
|
+
urlObj.searchParams.set("cl", options.clickId || "");
|
|
69
|
+
urlObj.searchParams.set("ua", options.userAgent || "");
|
|
70
|
+
urlObj.searchParams.set("ip", options.ip || "");
|
|
71
|
+
}
|
|
72
|
+
// For Google Play Store links (following Dub's exact pattern)
|
|
73
|
+
if ((0, url_detection_1.isGooglePlayStoreUrl)(originalUrl) && options.shortLink) {
|
|
74
|
+
const existingReferrer = urlObj.searchParams.get("referrer");
|
|
75
|
+
const referrerSearchParam = new URLSearchParams(existingReferrer ? decodeURIComponent(existingReferrer) : "");
|
|
76
|
+
referrerSearchParam.set("deepLink", options.shortLink);
|
|
77
|
+
urlObj.searchParams.set("referrer", referrerSearchParam.toString());
|
|
78
|
+
}
|
|
79
|
+
return urlObj.toString();
|
|
80
|
+
}
|
|
81
|
+
catch (error) {
|
|
82
|
+
console.error("Error constructing final URL:", error);
|
|
83
|
+
return originalUrl;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Device targeting resolution following Dub's iOS/Android redirect exact pattern
|
|
88
|
+
*/
|
|
89
|
+
function resolveDeviceTargeting(iosUrl, androidUrl, userAgent) {
|
|
90
|
+
if (!userAgent)
|
|
91
|
+
return null;
|
|
92
|
+
// Following Dub's exact OS detection from userAgent(req)
|
|
93
|
+
const isIOS = /iPhone|iPad|iPod/i.test(userAgent);
|
|
94
|
+
const isAndroid = /Android/i.test(userAgent);
|
|
95
|
+
// iOS targeting (following Dub's ios && ua.os?.name === "iOS" pattern)
|
|
96
|
+
if (isIOS && iosUrl) {
|
|
97
|
+
return {
|
|
98
|
+
url: iosUrl,
|
|
99
|
+
isAppStore: (0, url_detection_1.isIosAppStoreUrl)(iosUrl)
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
// Android targeting (following Dub's android && ua.os?.name === "Android" pattern)
|
|
103
|
+
if (isAndroid && androidUrl) {
|
|
104
|
+
return {
|
|
105
|
+
url: androidUrl,
|
|
106
|
+
isAppStore: (0, url_detection_1.isGooglePlayStoreUrl)(androidUrl)
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
return null;
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=link-resolution.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"link-resolution.js","sourceRoot":"","sources":["../../src/access-link/link-resolution.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export declare const nanoid: (chars?: number) => Promise<any>;
|
|
2
|
+
export declare function getRandomKey({ domain, length, prefix, checkExists, }: {
|
|
3
|
+
domain: string;
|
|
4
|
+
length?: number;
|
|
5
|
+
prefix?: string;
|
|
6
|
+
checkExists: (domain: string, key: string) => Promise<boolean>;
|
|
7
|
+
}): Promise<string>;
|
|
8
|
+
export declare function extractUTMParams(url?: string): {
|
|
9
|
+
utm_source?: undefined;
|
|
10
|
+
utm_medium?: undefined;
|
|
11
|
+
utm_campaign?: undefined;
|
|
12
|
+
utm_term?: undefined;
|
|
13
|
+
utm_content?: undefined;
|
|
14
|
+
} | {
|
|
15
|
+
utm_source: string | undefined;
|
|
16
|
+
utm_medium: string | undefined;
|
|
17
|
+
utm_campaign: string | undefined;
|
|
18
|
+
utm_term: string | undefined;
|
|
19
|
+
utm_content: string | undefined;
|
|
20
|
+
};
|
|
21
|
+
export declare function buildShortLink(domain: string, key: string): string;
|
|
22
|
+
export declare function hashPassword(password: string): Promise<string>;
|
|
23
|
+
//# sourceMappingURL=link-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"link-utils.d.ts","sourceRoot":"","sources":["../../src/access-link/link-utils.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,MAAM,GAAU,QAAQ,MAAM,iBAO1C,CAAA;AAGD,wBAAsB,YAAY,CAAC,EACjC,MAAM,EACN,MAAU,EACV,MAAM,EACN,WAAW,GACZ,EAAE;IACD,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,WAAW,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;CAC/D,GAAG,OAAO,CAAC,MAAM,CAAC,CAelB;AAED,wBAAgB,gBAAgB,CAAC,GAAG,CAAC,EAAE,MAAM;;;;;;;;;;;;EAe5C;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAElE;AAED,wBAAsB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAOpE"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.nanoid = void 0;
|
|
4
|
+
exports.getRandomKey = getRandomKey;
|
|
5
|
+
exports.extractUTMParams = extractUTMParams;
|
|
6
|
+
exports.buildShortLink = buildShortLink;
|
|
7
|
+
exports.hashPassword = hashPassword;
|
|
8
|
+
let customAlphabet;
|
|
9
|
+
// Dub's exact nanoid implementation
|
|
10
|
+
const nanoid = async (chars) => {
|
|
11
|
+
if (!customAlphabet)
|
|
12
|
+
({ customAlphabet } = await import("nanoid"));
|
|
13
|
+
return customAlphabet("customAlphabet", chars || 7 // 7-character random string by default
|
|
14
|
+
)();
|
|
15
|
+
};
|
|
16
|
+
exports.nanoid = nanoid;
|
|
17
|
+
// Dub's exact getRandomKey pattern
|
|
18
|
+
async function getRandomKey({ domain, length = 7, prefix, checkExists, }) {
|
|
19
|
+
/* recursively get random key till it gets one that's available */
|
|
20
|
+
let key = await (0, exports.nanoid)(length);
|
|
21
|
+
if (prefix) {
|
|
22
|
+
key = `${prefix.replace(/^\/|\/$/g, "")}/${key}`;
|
|
23
|
+
}
|
|
24
|
+
const exists = await checkExists(domain, key);
|
|
25
|
+
if (exists) {
|
|
26
|
+
// by the off chance that key already exists
|
|
27
|
+
return getRandomKey({ domain, length, prefix, checkExists });
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
return key;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
function extractUTMParams(url) {
|
|
34
|
+
if (!url)
|
|
35
|
+
return {};
|
|
36
|
+
try {
|
|
37
|
+
const urlObj = new URL(url);
|
|
38
|
+
return {
|
|
39
|
+
utm_source: urlObj.searchParams.get("utm_source") || undefined,
|
|
40
|
+
utm_medium: urlObj.searchParams.get("utm_medium") || undefined,
|
|
41
|
+
utm_campaign: urlObj.searchParams.get("utm_campaign") || undefined,
|
|
42
|
+
utm_term: urlObj.searchParams.get("utm_term") || undefined,
|
|
43
|
+
utm_content: urlObj.searchParams.get("utm_content") || undefined,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
return {};
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
function buildShortLink(domain, key) {
|
|
51
|
+
return `${domain}/${key}`;
|
|
52
|
+
}
|
|
53
|
+
async function hashPassword(password) {
|
|
54
|
+
// Simple hash for now - in production use bcrypt
|
|
55
|
+
const encoder = new TextEncoder();
|
|
56
|
+
const data = encoder.encode(password);
|
|
57
|
+
const hashBuffer = await crypto.subtle.digest("SHA-256", data);
|
|
58
|
+
const hashArray = Array.from(new Uint8Array(hashBuffer));
|
|
59
|
+
return hashArray.map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=link-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"link-utils.js","sourceRoot":"","sources":["../../src/access-link/link-utils.ts"],"names":[],"mappings":";;;AAaA,oCAyBC;AAED,4CAeC;AAED,wCAEC;AAED,oCAOC;AApED,IAAI,cAAc,CAAA;AAElB,oCAAoC;AAC7B,MAAM,MAAM,GAAG,KAAK,EAAE,KAAc,EAAE,EAAE;IAC3C,IAAI,CAAC,cAAc;QACnB,CAAC,EAAE,cAAc,EAAE,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAA;IAC/C,OAAO,cAAc,CACnB,gBAAgB,EAChB,KAAK,IAAI,CAAC,CAAC,uCAAuC;KACnD,EAAE,CAAA;AACL,CAAC,CAAA;AAPY,QAAA,MAAM,UAOlB;AAED,mCAAmC;AAC5B,KAAK,UAAU,YAAY,CAAC,EACjC,MAAM,EACN,MAAM,GAAG,CAAC,EACV,MAAM,EACN,WAAW,GAMZ;IACC,kEAAkE;IAClE,IAAI,GAAG,GAAG,MAAM,IAAA,cAAM,EAAC,MAAM,CAAC,CAAA;IAC9B,IAAI,MAAM,EAAE,CAAC;QACX,GAAG,GAAG,GAAG,MAAM,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,IAAI,GAAG,EAAE,CAAA;IAClD,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAE7C,IAAI,MAAM,EAAE,CAAC;QACX,4CAA4C;QAC5C,OAAO,YAAY,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC,CAAA;IAC9D,CAAC;SAAM,CAAC;QACN,OAAO,GAAG,CAAA;IACZ,CAAC;AACH,CAAC;AAED,SAAgB,gBAAgB,CAAC,GAAY;IAC3C,IAAI,CAAC,GAAG;QAAE,OAAO,EAAE,CAAA;IAEnB,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAA;QAC3B,OAAO;YACL,UAAU,EAAE,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,SAAS;YAC9D,UAAU,EAAE,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,SAAS;YAC9D,YAAY,EAAE,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,SAAS;YAClE,QAAQ,EAAE,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,SAAS;YAC1D,WAAW,EAAE,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,aAAa,CAAC,IAAI,SAAS;SACjE,CAAA;IACH,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAA;IACX,CAAC;AACH,CAAC;AAED,SAAgB,cAAc,CAAC,MAAc,EAAE,GAAW;IACxD,OAAO,GAAG,MAAM,IAAI,GAAG,EAAE,CAAA;AAC3B,CAAC;AAEM,KAAK,UAAU,YAAY,CAAC,QAAgB;IACjD,iDAAiD;IACjD,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAA;IACjC,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;IACrC,MAAM,UAAU,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,CAAA;IAC9D,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,UAAU,CAAC,UAAU,CAAC,CAAC,CAAA;IACxD,OAAO,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;AACvE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process-key.d.ts","sourceRoot":"","sources":["../../src/access-link/process-key.ts"],"names":[],"mappings":"AA6BA,wBAAgB,UAAU,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,GAAG,IAAI,CAoC1F"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Process and validate access link keys (following Dub's process-key pattern)
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.processKey = processKey;
|
|
5
|
+
const validKeyRegex = /^[a-zA-Z0-9\-_.~:/?#[\]@!$&'()*+,;=%]+$/;
|
|
6
|
+
// ETO domains that require stricter key validation
|
|
7
|
+
const isETODomain = (domain) => {
|
|
8
|
+
return domain.includes('eto.') || domain.includes('shopabox.');
|
|
9
|
+
};
|
|
10
|
+
// Keys that are reserved/unsupported
|
|
11
|
+
const unsupportedKeys = new Set([
|
|
12
|
+
'api', 'app', 'admin', 'www', 'mail', 'ftp', 'localhost', 'dashboard',
|
|
13
|
+
'analytics', 'settings', 'billing', 'support', 'help', 'docs', 'blog',
|
|
14
|
+
'status', 'legal', 'privacy', 'terms', 'security', 'contact'
|
|
15
|
+
]);
|
|
16
|
+
const isUnsupportedKey = (key) => {
|
|
17
|
+
return unsupportedKeys.has(key.toLowerCase());
|
|
18
|
+
};
|
|
19
|
+
// Punycode encoding for international characters
|
|
20
|
+
const punyEncode = (key) => {
|
|
21
|
+
try {
|
|
22
|
+
return new URL(`http://${key}`).hostname;
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
return key;
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
function processKey({ domain, key }) {
|
|
29
|
+
// Skip if root domain
|
|
30
|
+
if (key === "_root") {
|
|
31
|
+
return key;
|
|
32
|
+
}
|
|
33
|
+
if (!validKeyRegex.test(key)) {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
// if key starts with _, return null (reserved route for ETO internals)
|
|
37
|
+
if (key.startsWith("_")) {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
// check if key is supported
|
|
41
|
+
if (isUnsupportedKey(key)) {
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
// remove all leading and trailing slashes from key
|
|
45
|
+
key = key.replace(/^\/+|\/+$/g, "");
|
|
46
|
+
/*
|
|
47
|
+
for ETO domains, remove all special characters + unicode normalization
|
|
48
|
+
to remove accents / diacritical marks. this is to prevent phishing/typo squatting
|
|
49
|
+
for custom domains this is fine, since only the project can set the key
|
|
50
|
+
*/
|
|
51
|
+
if (isETODomain(domain)) {
|
|
52
|
+
key = key.normalize("NFD").replace(/[\u0300-\u036f]/g, "");
|
|
53
|
+
}
|
|
54
|
+
// encode the key to ascii
|
|
55
|
+
key = punyEncode(key);
|
|
56
|
+
return key;
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=process-key.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process-key.js","sourceRoot":"","sources":["../../src/access-link/process-key.ts"],"names":[],"mappings":";AAAA,8EAA8E;;AA6B9E,gCAoCC;AA/DD,MAAM,aAAa,GAAG,yCAAyC,CAAA;AAE/D,mDAAmD;AACnD,MAAM,WAAW,GAAG,CAAC,MAAc,EAAW,EAAE;IAC9C,OAAO,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAA;AAChE,CAAC,CAAA;AAED,qCAAqC;AACrC,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC;IAC9B,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,WAAW;IACrE,WAAW,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IACrE,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,SAAS;CAC7D,CAAC,CAAA;AAEF,MAAM,gBAAgB,GAAG,CAAC,GAAW,EAAW,EAAE;IAChD,OAAO,eAAe,CAAC,GAAG,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,CAAA;AAC/C,CAAC,CAAA;AAED,iDAAiD;AACjD,MAAM,UAAU,GAAG,CAAC,GAAW,EAAU,EAAE;IACzC,IAAI,CAAC;QACH,OAAO,IAAI,GAAG,CAAC,UAAU,GAAG,EAAE,CAAC,CAAC,QAAQ,CAAA;IAC1C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,GAAG,CAAA;IACZ,CAAC;AACH,CAAC,CAAA;AAED,SAAgB,UAAU,CAAC,EAAE,MAAM,EAAE,GAAG,EAAmC;IACzE,sBAAsB;IACtB,IAAI,GAAG,KAAK,OAAO,EAAE,CAAC;QACpB,OAAO,GAAG,CAAA;IACZ,CAAC;IAED,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QAC7B,OAAO,IAAI,CAAA;IACb,CAAC;IAED,uEAAuE;IACvE,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACxB,OAAO,IAAI,CAAA;IACb,CAAC;IAED,4BAA4B;IAC5B,IAAI,gBAAgB,CAAC,GAAG,CAAC,EAAE,CAAC;QAC1B,OAAO,IAAI,CAAA;IACb,CAAC;IAED,mDAAmD;IACnD,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAA;IAEnC;;;;MAIE;IACF,IAAI,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC;QACxB,GAAG,GAAG,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,kBAAkB,EAAE,EAAE,CAAC,CAAA;IAC5D,CAAC;IAED,0BAA0B;IAC1B,GAAG,GAAG,UAAU,CAAC,GAAG,CAAC,CAAA;IAErB,OAAO,GAAG,CAAA;AACZ,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export interface ProcessAccessLinkOptions {
|
|
2
|
+
domain?: string;
|
|
3
|
+
key?: string;
|
|
4
|
+
url?: string;
|
|
5
|
+
target_resource_type?: string;
|
|
6
|
+
target_resource_id?: string;
|
|
7
|
+
access_role?: string;
|
|
8
|
+
purpose?: string;
|
|
9
|
+
max_uses?: number;
|
|
10
|
+
expires_at?: Date;
|
|
11
|
+
auto_approve?: boolean;
|
|
12
|
+
requires_approval?: boolean;
|
|
13
|
+
password_protected?: boolean;
|
|
14
|
+
}
|
|
15
|
+
export declare function processAccessLink(data: ProcessAccessLinkOptions, options?: {
|
|
16
|
+
skipKeyValidation?: boolean;
|
|
17
|
+
skipUrlValidation?: boolean;
|
|
18
|
+
}): Promise<any>;
|
|
19
|
+
//# sourceMappingURL=process-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process-utils.d.ts","sourceRoot":"","sources":["../../src/access-link/process-utils.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,wBAAwB;IACvC,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,oBAAoB,CAAC,EAAE,MAAM,CAAA;IAC7B,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,UAAU,CAAC,EAAE,IAAI,CAAA;IACjB,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAC3B,kBAAkB,CAAC,EAAE,OAAO,CAAA;CAC7B;AAED,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,wBAAwB,EAC9B,OAAO,GAAE;IACP,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAC3B,iBAAiB,CAAC,EAAE,OAAO,CAAA;CACvB,gBAsDP"}
|