@tern-secure/shared 1.3.0-canary.v20251030165007 → 1.3.0-canary.v20251125170702

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.
Files changed (56) hide show
  1. package/dist/chunk-B2SN66XE.mjs +25 -0
  2. package/dist/chunk-B2SN66XE.mjs.map +1 -0
  3. package/dist/{chunk-33U3M4YY.mjs → chunk-IGYBIQYE.mjs} +14 -7
  4. package/dist/chunk-IGYBIQYE.mjs.map +1 -0
  5. package/dist/chunk-N2V3PKFE.mjs +61 -0
  6. package/dist/chunk-N2V3PKFE.mjs.map +1 -0
  7. package/dist/cookie.js.map +1 -1
  8. package/dist/cookie.mjs.map +1 -1
  9. package/dist/date.d.mts +18 -0
  10. package/dist/date.d.ts +18 -0
  11. package/dist/date.js +98 -0
  12. package/dist/date.js.map +1 -0
  13. package/dist/date.mjs +69 -0
  14. package/dist/date.mjs.map +1 -0
  15. package/dist/errors.js +1 -1
  16. package/dist/errors.js.map +1 -1
  17. package/dist/errors.mjs +1 -1
  18. package/dist/errors.mjs.map +1 -1
  19. package/dist/loadScript.js +68 -6
  20. package/dist/loadScript.js.map +1 -1
  21. package/dist/loadScript.mjs +2 -1
  22. package/dist/loadTernUIScript.d.mts +14 -6
  23. package/dist/loadTernUIScript.d.ts +14 -6
  24. package/dist/loadTernUIScript.js +122 -29
  25. package/dist/loadTernUIScript.js.map +1 -1
  26. package/dist/loadTernUIScript.mjs +45 -25
  27. package/dist/loadTernUIScript.mjs.map +1 -1
  28. package/dist/ms.d.mts +52 -0
  29. package/dist/ms.d.ts +52 -0
  30. package/dist/ms.js +181 -0
  31. package/dist/ms.js.map +1 -0
  32. package/dist/ms.mjs +153 -0
  33. package/dist/ms.mjs.map +1 -0
  34. package/dist/react/index.d.mts +19 -1
  35. package/dist/react/index.d.ts +19 -1
  36. package/dist/react/index.js +26 -1
  37. package/dist/react/index.js.map +1 -1
  38. package/dist/react/index.mjs +23 -1
  39. package/dist/react/index.mjs.map +1 -1
  40. package/dist/resolveVersion.d.mts +2 -1
  41. package/dist/resolveVersion.d.ts +2 -1
  42. package/dist/resolveVersion.js +16 -2
  43. package/dist/resolveVersion.js.map +1 -1
  44. package/dist/resolveVersion.mjs +3 -1
  45. package/dist/retry.mjs +3 -56
  46. package/dist/retry.mjs.map +1 -1
  47. package/dist/url.d.mts +2 -1
  48. package/dist/url.d.ts +2 -1
  49. package/dist/url.js +4 -0
  50. package/dist/url.js.map +1 -1
  51. package/dist/url.mjs +3 -0
  52. package/dist/url.mjs.map +1 -1
  53. package/package.json +4 -3
  54. package/dist/chunk-33U3M4YY.mjs.map +0 -1
  55. package/dist/chunk-PHCVLVZY.mjs +0 -12
  56. package/dist/chunk-PHCVLVZY.mjs.map +0 -1
@@ -0,0 +1,25 @@
1
+ // src/resolveVersion.ts
2
+ var resolveVersion = (ternUIVersion, packageVersion = "1.1.0-canary.v20251125170702") => {
3
+ if (ternUIVersion) {
4
+ return ternUIVersion;
5
+ }
6
+ const prereleaseTag = getPrereleaseTag(packageVersion);
7
+ if (prereleaseTag) {
8
+ if (prereleaseTag === "snapshot") {
9
+ return "1.1.0-canary.v20251125170702";
10
+ }
11
+ return prereleaseTag;
12
+ }
13
+ return getMajorVersion(packageVersion);
14
+ };
15
+ var getPrereleaseTag = (packageVersion) => {
16
+ var _a;
17
+ return (_a = packageVersion.trim().replace(/^v/, "").match(/-(.+?)(\.|$)/)) == null ? void 0 : _a[1];
18
+ };
19
+ var getMajorVersion = (packageVersion) => packageVersion.trim().replace(/^v/, "").split(".")[0];
20
+
21
+ export {
22
+ resolveVersion,
23
+ getMajorVersion
24
+ };
25
+ //# sourceMappingURL=chunk-B2SN66XE.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/resolveVersion.ts"],"sourcesContent":["\nexport const resolveVersion = (ternUIVersion: string | undefined, packageVersion = TERN_UI_VERSION) => {\n if (ternUIVersion) {\n return ternUIVersion\n }\n\n const prereleaseTag = getPrereleaseTag(packageVersion);\n if (prereleaseTag) {\n if (prereleaseTag === 'snapshot') {\n return TERN_UI_VERSION;\n }\n\n return prereleaseTag;\n }\n\n return getMajorVersion(packageVersion);\n}\n\nconst getPrereleaseTag = (packageVersion: string) =>\n packageVersion\n .trim()\n .replace(/^v/, '')\n .match(/-(.+?)(\\.|$)/)?.[1];\n\nexport const getMajorVersion = (packageVersion: string) => packageVersion.trim().replace(/^v/, '').split('.')[0];"],"mappings":";AACO,IAAM,iBAAiB,CAAC,eAAmC,iBAAiB,mCAAoB;AACrG,MAAI,eAAe;AACjB,WAAO;AAAA,EACT;AAEA,QAAM,gBAAgB,iBAAiB,cAAc;AACrD,MAAI,eAAe;AACjB,QAAI,kBAAkB,YAAY;AAChC,aAAO;AAAA,IACT;AAEA,WAAO;AAAA,EACT;AAEA,SAAO,gBAAgB,cAAc;AACvC;AAEA,IAAM,mBAAmB,CAAC,mBAAwB;AAlBlD;AAmBE,8BACG,KAAK,EACL,QAAQ,MAAM,EAAE,EAChB,MAAM,cAAc,MAHvB,mBAG2B;AAAA;AAEtB,IAAM,kBAAkB,CAAC,mBAA2B,eAAe,KAAK,EAAE,QAAQ,MAAM,EAAE,EAAE,MAAM,GAAG,EAAE,CAAC;","names":[]}
@@ -1,3 +1,7 @@
1
+ import {
2
+ retry
3
+ } from "./chunk-N2V3PKFE.mjs";
4
+
1
5
  // src/loadScript.ts
2
6
  async function loadScript(src = "", options) {
3
7
  const { async, defer, crossOrigin, nonce, beforeLoad } = options;
@@ -25,7 +29,6 @@ async function loadScript(src = "", options) {
25
29
  };
26
30
  const handleLoad = () => {
27
31
  if (resolved) return;
28
- console.log(`[loadScript] Script loaded successfully: ${src}`);
29
32
  resolved = true;
30
33
  cleanup();
31
34
  resolve(script);
@@ -35,22 +38,26 @@ async function loadScript(src = "", options) {
35
38
  resolved = true;
36
39
  cleanup();
37
40
  script.remove();
38
- console.error(`[loadScript] Failed to load script: ${src}`, error);
39
41
  reject(new Error(`Failed to load script: ${src}, Error: ${error.message}`));
40
42
  };
41
- script.addEventListener("load", handleLoad);
42
- script.addEventListener("error", handleError);
43
+ script.addEventListener("load", () => {
44
+ script.remove();
45
+ resolve(script);
46
+ });
47
+ script.addEventListener("error", () => {
48
+ script.remove();
49
+ reject();
50
+ });
43
51
  script.src = src;
44
52
  script.nonce = nonce;
45
53
  beforeLoad == null ? void 0 : beforeLoad(script);
46
- console.log(`[loadScript] Appending script to document body: ${src}`);
47
54
  document.body.appendChild(script);
48
55
  });
49
56
  };
50
- return load();
57
+ return retry(load, { shouldRetry: (_, iterations) => iterations <= 5 });
51
58
  }
52
59
 
53
60
  export {
54
61
  loadScript
55
62
  };
56
- //# sourceMappingURL=chunk-33U3M4YY.mjs.map
63
+ //# sourceMappingURL=chunk-IGYBIQYE.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/loadScript.ts"],"sourcesContent":["import { retry } from './retry';\n\ntype LoadScriptOptions = {\n async?: boolean;\n defer?: boolean;\n crossOrigin?: 'anonymous' | 'use-credentials';\n nonce?: string;\n beforeLoad?: (script: HTMLScriptElement) => void;\n};\n\nexport async function loadScript(src = '', options: LoadScriptOptions): Promise<HTMLScriptElement> {\n const { async, defer, crossOrigin, nonce, beforeLoad } = options;\n\n const load = () => {\n return new Promise<HTMLScriptElement>((resolve, reject) => {\n if (!src) {\n reject(new Error('Script src is required'));\n }\n\n if (!document || !document.body) {\n reject(new Error('Document body is not available'));\n }\n\n const script = document.createElement('script');\n\n if (crossOrigin) script.setAttribute('crossorigin', crossOrigin);\n script.async = async || false;\n script.defer = defer || false;\n\n let resolved = false;\n let timeoutId: NodeJS.Timeout | null = null;\n\n /**\n * @deprecated\n */\n const cleanup = () => {\n script.removeEventListener('load', handleLoad);\n script.removeEventListener('error', handleError);\n if (timeoutId) {\n clearTimeout(timeoutId);\n timeoutId = null;\n }\n };\n\n /**\n * @deprecated\n */\n const handleLoad = () => {\n if (resolved) return;\n\n resolved = true;\n cleanup();\n resolve(script);\n };\n /**\n * @deprecated\n */\n const handleError = (error: ErrorEvent) => {\n if (resolved) return;\n resolved = true;\n cleanup();\n script.remove();\n reject(new Error(`Failed to load script: ${src}, Error: ${error.message}`));\n };\n\n script.addEventListener('load', () => {\n script.remove()\n resolve(script);\n });\n\n script.addEventListener('error', () => {\n script.remove()\n reject()\n });\n\n script.src = src;\n script.nonce = nonce;\n beforeLoad?.(script);\n document.body.appendChild(script)\n });\n };\n\n //return load()\n\n return retry(load, { shouldRetry: (_, iterations) => iterations <= 5 });\n}"],"mappings":";;;;;AAUA,eAAsB,WAAW,MAAM,IAAI,SAAwD;AACjG,QAAM,EAAE,OAAO,OAAO,aAAa,OAAO,WAAW,IAAI;AAEzD,QAAM,OAAO,MAAM;AACjB,WAAO,IAAI,QAA2B,CAAC,SAAS,WAAW;AACzD,UAAI,CAAC,KAAK;AACR,eAAO,IAAI,MAAM,wBAAwB,CAAC;AAAA,MAC5C;AAEA,UAAI,CAAC,YAAY,CAAC,SAAS,MAAM;AAC/B,eAAO,IAAI,MAAM,gCAAgC,CAAC;AAAA,MACpD;AAEA,YAAM,SAAS,SAAS,cAAc,QAAQ;AAE9C,UAAI,YAAa,QAAO,aAAa,eAAe,WAAW;AAC/D,aAAO,QAAQ,SAAS;AACxB,aAAO,QAAQ,SAAS;AAExB,UAAI,WAAW;AACf,UAAI,YAAmC;AAKvC,YAAM,UAAU,MAAM;AACpB,eAAO,oBAAoB,QAAQ,UAAU;AAC7C,eAAO,oBAAoB,SAAS,WAAW;AAC/C,YAAI,WAAW;AACb,uBAAa,SAAS;AACtB,sBAAY;AAAA,QACd;AAAA,MACF;AAKA,YAAM,aAAa,MAAM;AACvB,YAAI,SAAU;AAEd,mBAAW;AACX,gBAAQ;AACR,gBAAQ,MAAM;AAAA,MAChB;AAIA,YAAM,cAAc,CAAC,UAAsB;AACzC,YAAI,SAAU;AACd,mBAAW;AACX,gBAAQ;AACR,eAAO,OAAO;AACd,eAAO,IAAI,MAAM,0BAA0B,GAAG,YAAY,MAAM,OAAO,EAAE,CAAC;AAAA,MAC5E;AAEA,aAAO,iBAAiB,QAAQ,MAAM;AACpC,eAAO,OAAO;AACd,gBAAQ,MAAM;AAAA,MAChB,CAAC;AAED,aAAO,iBAAiB,SAAS,MAAM;AACrC,eAAO,OAAO;AACd,eAAO;AAAA,MACT,CAAC;AAED,aAAO,MAAM;AACb,aAAO,QAAQ;AACf,+CAAa;AACb,eAAS,KAAK,YAAY,MAAM;AAAA,IAClC,CAAC;AAAA,EACH;AAIA,SAAO,MAAM,MAAM,EAAE,aAAa,CAAC,GAAG,eAAe,cAAc,EAAE,CAAC;AACxE;","names":[]}
@@ -0,0 +1,61 @@
1
+ // src/retry.ts
2
+ var defaultOptions = {
3
+ initialDelay: 125,
4
+ maxDelayBetweenRetries: 0,
5
+ factor: 2,
6
+ shouldRetry: (_, iteration) => iteration < 5,
7
+ retryImmediately: false,
8
+ jitter: true
9
+ };
10
+ var RETRY_IMMEDIATELY_DELAY = 100;
11
+ var sleep = async (ms) => new Promise((s) => setTimeout(s, ms));
12
+ var applyJitter = (delay, jitter) => {
13
+ return jitter ? delay * (1 + Math.random()) : delay;
14
+ };
15
+ var createExponentialDelayAsyncFn = (opts) => {
16
+ let timesCalled = 0;
17
+ const calculateDelayInMs = () => {
18
+ const constant = opts.initialDelay;
19
+ const base = opts.factor;
20
+ let delay = constant * Math.pow(base, timesCalled);
21
+ delay = applyJitter(delay, opts.jitter);
22
+ return Math.min(opts.maxDelayBetweenRetries || delay, delay);
23
+ };
24
+ return async () => {
25
+ await sleep(calculateDelayInMs());
26
+ timesCalled++;
27
+ };
28
+ };
29
+ var retry = async (callback, options = {}) => {
30
+ let iterations = 0;
31
+ const { shouldRetry, initialDelay, maxDelayBetweenRetries, factor, retryImmediately, jitter } = {
32
+ ...defaultOptions,
33
+ ...options
34
+ };
35
+ const delay = createExponentialDelayAsyncFn({
36
+ initialDelay,
37
+ maxDelayBetweenRetries,
38
+ factor,
39
+ jitter
40
+ });
41
+ while (true) {
42
+ try {
43
+ return await callback();
44
+ } catch (e) {
45
+ iterations++;
46
+ if (!shouldRetry(e, iterations)) {
47
+ throw e;
48
+ }
49
+ if (retryImmediately && iterations === 1) {
50
+ await sleep(applyJitter(RETRY_IMMEDIATELY_DELAY, jitter));
51
+ } else {
52
+ await delay();
53
+ }
54
+ }
55
+ }
56
+ };
57
+
58
+ export {
59
+ retry
60
+ };
61
+ //# sourceMappingURL=chunk-N2V3PKFE.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/retry.ts"],"sourcesContent":["type Milliseconds = number;\n\ntype RetryOptions = Partial<{\n /**\n * The initial delay before the first retry.\n * @default 125\n */\n initialDelay: Milliseconds;\n /**\n * The maximum delay between retries.\n * The delay between retries will never exceed this value.\n * If set to 0, the delay will increase indefinitely.\n * @default 0\n */\n maxDelayBetweenRetries: Milliseconds;\n /**\n * The multiplier for the exponential backoff.\n * @default 2\n */\n factor: number;\n /**\n * A function to determine if the operation should be retried.\n * The callback accepts the error that was thrown and the number of iterations.\n * The iterations variable references the number of retries AFTER attempt\n * that caused the error and starts at 1 (as in, this is the 1st, 2nd, nth retry).\n * @default (error, iterations) => iterations < 5\n */\n shouldRetry: (error: unknown, iterations: number) => boolean;\n /**\n * Controls whether the helper should retry the operation immediately once before applying exponential backoff.\n * The delay for the immediate retry is 100ms.\n * @default false\n */\n retryImmediately: boolean;\n /**\n * If true, the intervals will be multiplied by a factor in the range of [1,2].\n * @default true\n */\n jitter: boolean;\n}>;\n\nconst defaultOptions: Required<RetryOptions> = {\n initialDelay: 125,\n maxDelayBetweenRetries: 0,\n factor: 2,\n shouldRetry: (_: unknown, iteration: number) => iteration < 5,\n retryImmediately: false,\n jitter: true,\n};\n\nconst RETRY_IMMEDIATELY_DELAY = 100;\n\nconst sleep = async (ms: Milliseconds) => new Promise(s => setTimeout(s, ms));\n\nconst applyJitter = (delay: Milliseconds, jitter: boolean) => {\n return jitter ? delay * (1 + Math.random()) : delay;\n};\n\nconst createExponentialDelayAsyncFn = (\n opts: Required<Pick<RetryOptions, 'initialDelay' | 'maxDelayBetweenRetries' | 'factor' | 'jitter'>>,\n) => {\n let timesCalled = 0;\n\n const calculateDelayInMs = () => {\n const constant = opts.initialDelay;\n const base = opts.factor;\n let delay = constant * Math.pow(base, timesCalled);\n delay = applyJitter(delay, opts.jitter);\n return Math.min(opts.maxDelayBetweenRetries || delay, delay);\n };\n\n return async (): Promise<void> => {\n await sleep(calculateDelayInMs());\n timesCalled++;\n };\n};\n\n/**\n * Retries a callback until it succeeds or the shouldRetry function returns false.\n * See {@link RetryOptions} for the available options.\n */\nexport const retry = async <T>(callback: () => T | Promise<T>, options: RetryOptions = {}): Promise<T> => {\n let iterations = 0;\n const { shouldRetry, initialDelay, maxDelayBetweenRetries, factor, retryImmediately, jitter } = {\n ...defaultOptions,\n ...options,\n };\n\n const delay = createExponentialDelayAsyncFn({\n initialDelay,\n maxDelayBetweenRetries,\n factor,\n jitter,\n });\n\n while (true) {\n try {\n return await callback();\n } catch (e) {\n iterations++;\n if (!shouldRetry(e, iterations)) {\n throw e;\n }\n if (retryImmediately && iterations === 1) {\n await sleep(applyJitter(RETRY_IMMEDIATELY_DELAY, jitter));\n } else {\n await delay();\n }\n }\n }\n};\n"],"mappings":";AAyCA,IAAM,iBAAyC;AAAA,EAC7C,cAAc;AAAA,EACd,wBAAwB;AAAA,EACxB,QAAQ;AAAA,EACR,aAAa,CAAC,GAAY,cAAsB,YAAY;AAAA,EAC5D,kBAAkB;AAAA,EAClB,QAAQ;AACV;AAEA,IAAM,0BAA0B;AAEhC,IAAM,QAAQ,OAAO,OAAqB,IAAI,QAAQ,OAAK,WAAW,GAAG,EAAE,CAAC;AAE5E,IAAM,cAAc,CAAC,OAAqB,WAAoB;AAC5D,SAAO,SAAS,SAAS,IAAI,KAAK,OAAO,KAAK;AAChD;AAEA,IAAM,gCAAgC,CACpC,SACG;AACH,MAAI,cAAc;AAElB,QAAM,qBAAqB,MAAM;AAC/B,UAAM,WAAW,KAAK;AACtB,UAAM,OAAO,KAAK;AAClB,QAAI,QAAQ,WAAW,KAAK,IAAI,MAAM,WAAW;AACjD,YAAQ,YAAY,OAAO,KAAK,MAAM;AACtC,WAAO,KAAK,IAAI,KAAK,0BAA0B,OAAO,KAAK;AAAA,EAC7D;AAEA,SAAO,YAA2B;AAChC,UAAM,MAAM,mBAAmB,CAAC;AAChC;AAAA,EACF;AACF;AAMO,IAAM,QAAQ,OAAU,UAAgC,UAAwB,CAAC,MAAkB;AACxG,MAAI,aAAa;AACjB,QAAM,EAAE,aAAa,cAAc,wBAAwB,QAAQ,kBAAkB,OAAO,IAAI;AAAA,IAC9F,GAAG;AAAA,IACH,GAAG;AAAA,EACL;AAEA,QAAM,QAAQ,8BAA8B;AAAA,IAC1C;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAED,SAAO,MAAM;AACX,QAAI;AACF,aAAO,MAAM,SAAS;AAAA,IACxB,SAAS,GAAG;AACV;AACA,UAAI,CAAC,YAAY,GAAG,UAAU,GAAG;AAC/B,cAAM;AAAA,MACR;AACA,UAAI,oBAAoB,eAAe,GAAG;AACxC,cAAM,MAAM,YAAY,yBAAyB,MAAM,CAAC;AAAA,MAC1D,OAAO;AACL,cAAM,MAAM;AAAA,MACd;AAAA,IACF;AAAA,EACF;AACF;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cookie.ts"],"sourcesContent":["import type { CookieOptions, CookieStore } from '@tern-secure/types';\nimport Cookies from 'js-cookie';\n\ntype removeCookieParams = {\n path?: string;\n domain?: string;\n};\n\nexport function cookieHandler(cookieNanme: string) {\n return {\n set(value: string, options: Cookies.CookieAttributes = {}): void {\n Cookies.set(cookieNanme, value, options);\n },\n get() {\n return Cookies.get(cookieNanme);\n },\n remove(removeCookieParams?: removeCookieParams) {\n Cookies.remove(cookieNanme, removeCookieParams);\n },\n };\n}\n\nexport type CookieAttributes = Cookies.CookieAttributes;\n\nexport function serverCookieHandler(response: Response): CookieStore {\n const getCookie = async (name: string): Promise<{ value: string | undefined }> => {\n const cookies = response.headers.get('cookie');\n if (!cookies) return { value: undefined };\n\n const match = cookies.match(new RegExp(`${name}=([^;]+)`));\n return { value: match ? decodeURIComponent(match[1]) : undefined };\n };\n\n const setCookie = async (\n name: string,\n value: string,\n options: CookieOptions = {},\n ): Promise<void> => {\n const { maxAge, httpOnly = true, secure = true, sameSite = 'strict', path = '/' } = options;\n\n let cookieString = `${name}=${encodeURIComponent(value)}`;\n\n if (maxAge) cookieString += `; Max-Age=${maxAge}`;\n if (httpOnly) cookieString += '; HttpOnly';\n if (secure) cookieString += '; Secure';\n if (sameSite) cookieString += `; SameSite=${sameSite}`;\n if (path) cookieString += `; Path=${path}`;\n\n response.headers.append('Set-Cookie', cookieString);\n };\n\n const deleteCookie = async (name: string): Promise<void> => {\n await setCookie(name, '', {\n maxAge: 0,\n httpOnly: true,\n secure: true,\n path: '/',\n });\n };\n\n return {\n get: getCookie,\n set: setCookie,\n delete: deleteCookie,\n };\n}\n\nexport const getCookiePrefix = (): string => {\n const isProduction = process.env.NODE_ENV === 'production';\n return isProduction ? '__HOST-' : '__dev_';\n};\n\nexport const getCookieName = (baseName: string, prefix?: string): string => {\n return prefix ? `${prefix}${baseName}` : baseName;\n};\n\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,uBAAoB;AAOb,SAAS,cAAc,aAAqB;AACjD,SAAO;AAAA,IACL,IAAI,OAAe,UAAoC,CAAC,GAAS;AAC/D,uBAAAA,QAAQ,IAAI,aAAa,OAAO,OAAO;AAAA,IACzC;AAAA,IACA,MAAM;AACJ,aAAO,iBAAAA,QAAQ,IAAI,WAAW;AAAA,IAChC;AAAA,IACA,OAAO,oBAAyC;AAC9C,uBAAAA,QAAQ,OAAO,aAAa,kBAAkB;AAAA,IAChD;AAAA,EACF;AACF;AAIO,SAAS,oBAAoB,UAAiC;AACnE,QAAM,YAAY,OAAO,SAAyD;AAChF,UAAM,UAAU,SAAS,QAAQ,IAAI,QAAQ;AAC7C,QAAI,CAAC,QAAS,QAAO,EAAE,OAAO,OAAU;AAExC,UAAM,QAAQ,QAAQ,MAAM,IAAI,OAAO,GAAG,IAAI,UAAU,CAAC;AACzD,WAAO,EAAE,OAAO,QAAQ,mBAAmB,MAAM,CAAC,CAAC,IAAI,OAAU;AAAA,EACnE;AAEA,QAAM,YAAY,OAChB,MACA,OACA,UAAyB,CAAC,MACR;AAClB,UAAM,EAAE,QAAQ,WAAW,MAAM,SAAS,MAAM,WAAW,UAAU,OAAO,IAAI,IAAI;AAEpF,QAAI,eAAe,GAAG,IAAI,IAAI,mBAAmB,KAAK,CAAC;AAEvD,QAAI,OAAQ,iBAAgB,aAAa,MAAM;AAC/C,QAAI,SAAU,iBAAgB;AAC9B,QAAI,OAAQ,iBAAgB;AAC5B,QAAI,SAAU,iBAAgB,cAAc,QAAQ;AACpD,QAAI,KAAM,iBAAgB,UAAU,IAAI;AAExC,aAAS,QAAQ,OAAO,cAAc,YAAY;AAAA,EACpD;AAEA,QAAM,eAAe,OAAO,SAAgC;AAC1D,UAAM,UAAU,MAAM,IAAI;AAAA,MACxB,QAAQ;AAAA,MACR,UAAU;AAAA,MACV,QAAQ;AAAA,MACR,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAEA,SAAO;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,QAAQ;AAAA,EACV;AACF;AAEO,IAAM,kBAAkB,MAAc;AAC3C,QAAM,eAAe,QAAQ,IAAI,aAAa;AAC9C,SAAO,eAAe,YAAY;AACpC;AAEO,IAAM,gBAAgB,CAAC,UAAkB,WAA4B;AAC1E,SAAO,SAAS,GAAG,MAAM,GAAG,QAAQ,KAAK;AAC3C;","names":["Cookies"]}
1
+ {"version":3,"sources":["../src/cookie.ts"],"sourcesContent":["import type { CookieOptions, CookieStore } from '@tern-secure/types';\nimport Cookies from 'js-cookie';\n\ntype removeCookieParams = {\n path?: string;\n domain?: string;\n};\n\nexport function cookieHandler(cookieNanme: string) {\n return {\n set(value: string, options: Cookies.CookieAttributes = {}): void {\n Cookies.set(cookieNanme, value, options);\n },\n get() {\n return Cookies.get(cookieNanme);\n },\n remove(removeCookieParams?: removeCookieParams) {\n Cookies.remove(cookieNanme, removeCookieParams);\n },\n };\n}\n\nexport type CookieAttributes = Cookies.CookieAttributes;\n\nexport function serverCookieHandler(response: Response): CookieStore {\n const getCookie = async (name: string): Promise<{ value: string | undefined }> => {\n const cookies = response.headers.get('cookie');\n if (!cookies) return { value: undefined };\n\n const match = cookies.match(new RegExp(`${name}=([^;]+)`));\n return { value: match ? decodeURIComponent(match[1]) : undefined };\n };\n\n const setCookie = async (\n name: string,\n value: string,\n options: CookieOptions = {},\n ): Promise<void> => {\n const { maxAge, httpOnly = true, secure = true, sameSite = 'strict', path = '/' } = options;\n\n let cookieString = `${name}=${encodeURIComponent(value)}`;\n\n if (maxAge) cookieString += `; Max-Age=${maxAge}`;\n if (httpOnly) cookieString += '; HttpOnly';\n if (secure) cookieString += '; Secure';\n if (sameSite) cookieString += `; SameSite=${sameSite}`;\n if (path) cookieString += `; Path=${path}`;\n\n response.headers.append('Set-Cookie', cookieString);\n };\n\n const deleteCookie = async (name: string): Promise<void> => {\n await setCookie(name, '', {\n maxAge: 0,\n httpOnly: true,\n secure: true,\n path: '/',\n });\n };\n\n return {\n get: getCookie,\n set: setCookie,\n delete: deleteCookie,\n };\n}\n\nexport const getCookiePrefix = (): string => {\n const isProduction = process.env.NODE_ENV === 'production';\n return isProduction ? '__HOST-' : '__dev_';\n};\n\nexport const getCookieName = (baseName: string, prefix?: string): string => {\n return prefix ? `${prefix}${baseName}` : baseName;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,uBAAoB;AAOb,SAAS,cAAc,aAAqB;AACjD,SAAO;AAAA,IACL,IAAI,OAAe,UAAoC,CAAC,GAAS;AAC/D,uBAAAA,QAAQ,IAAI,aAAa,OAAO,OAAO;AAAA,IACzC;AAAA,IACA,MAAM;AACJ,aAAO,iBAAAA,QAAQ,IAAI,WAAW;AAAA,IAChC;AAAA,IACA,OAAO,oBAAyC;AAC9C,uBAAAA,QAAQ,OAAO,aAAa,kBAAkB;AAAA,IAChD;AAAA,EACF;AACF;AAIO,SAAS,oBAAoB,UAAiC;AACnE,QAAM,YAAY,OAAO,SAAyD;AAChF,UAAM,UAAU,SAAS,QAAQ,IAAI,QAAQ;AAC7C,QAAI,CAAC,QAAS,QAAO,EAAE,OAAO,OAAU;AAExC,UAAM,QAAQ,QAAQ,MAAM,IAAI,OAAO,GAAG,IAAI,UAAU,CAAC;AACzD,WAAO,EAAE,OAAO,QAAQ,mBAAmB,MAAM,CAAC,CAAC,IAAI,OAAU;AAAA,EACnE;AAEA,QAAM,YAAY,OAChB,MACA,OACA,UAAyB,CAAC,MACR;AAClB,UAAM,EAAE,QAAQ,WAAW,MAAM,SAAS,MAAM,WAAW,UAAU,OAAO,IAAI,IAAI;AAEpF,QAAI,eAAe,GAAG,IAAI,IAAI,mBAAmB,KAAK,CAAC;AAEvD,QAAI,OAAQ,iBAAgB,aAAa,MAAM;AAC/C,QAAI,SAAU,iBAAgB;AAC9B,QAAI,OAAQ,iBAAgB;AAC5B,QAAI,SAAU,iBAAgB,cAAc,QAAQ;AACpD,QAAI,KAAM,iBAAgB,UAAU,IAAI;AAExC,aAAS,QAAQ,OAAO,cAAc,YAAY;AAAA,EACpD;AAEA,QAAM,eAAe,OAAO,SAAgC;AAC1D,UAAM,UAAU,MAAM,IAAI;AAAA,MACxB,QAAQ;AAAA,MACR,UAAU;AAAA,MACV,QAAQ;AAAA,MACR,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAEA,SAAO;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,QAAQ;AAAA,EACV;AACF;AAEO,IAAM,kBAAkB,MAAc;AAC3C,QAAM,eAAe,QAAQ,IAAI,aAAa;AAC9C,SAAO,eAAe,YAAY;AACpC;AAEO,IAAM,gBAAgB,CAAC,UAAkB,WAA4B;AAC1E,SAAO,SAAS,GAAG,MAAM,GAAG,QAAQ,KAAK;AAC3C;","names":["Cookies"]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cookie.ts"],"sourcesContent":["import type { CookieOptions, CookieStore } from '@tern-secure/types';\nimport Cookies from 'js-cookie';\n\ntype removeCookieParams = {\n path?: string;\n domain?: string;\n};\n\nexport function cookieHandler(cookieNanme: string) {\n return {\n set(value: string, options: Cookies.CookieAttributes = {}): void {\n Cookies.set(cookieNanme, value, options);\n },\n get() {\n return Cookies.get(cookieNanme);\n },\n remove(removeCookieParams?: removeCookieParams) {\n Cookies.remove(cookieNanme, removeCookieParams);\n },\n };\n}\n\nexport type CookieAttributes = Cookies.CookieAttributes;\n\nexport function serverCookieHandler(response: Response): CookieStore {\n const getCookie = async (name: string): Promise<{ value: string | undefined }> => {\n const cookies = response.headers.get('cookie');\n if (!cookies) return { value: undefined };\n\n const match = cookies.match(new RegExp(`${name}=([^;]+)`));\n return { value: match ? decodeURIComponent(match[1]) : undefined };\n };\n\n const setCookie = async (\n name: string,\n value: string,\n options: CookieOptions = {},\n ): Promise<void> => {\n const { maxAge, httpOnly = true, secure = true, sameSite = 'strict', path = '/' } = options;\n\n let cookieString = `${name}=${encodeURIComponent(value)}`;\n\n if (maxAge) cookieString += `; Max-Age=${maxAge}`;\n if (httpOnly) cookieString += '; HttpOnly';\n if (secure) cookieString += '; Secure';\n if (sameSite) cookieString += `; SameSite=${sameSite}`;\n if (path) cookieString += `; Path=${path}`;\n\n response.headers.append('Set-Cookie', cookieString);\n };\n\n const deleteCookie = async (name: string): Promise<void> => {\n await setCookie(name, '', {\n maxAge: 0,\n httpOnly: true,\n secure: true,\n path: '/',\n });\n };\n\n return {\n get: getCookie,\n set: setCookie,\n delete: deleteCookie,\n };\n}\n\nexport const getCookiePrefix = (): string => {\n const isProduction = process.env.NODE_ENV === 'production';\n return isProduction ? '__HOST-' : '__dev_';\n};\n\nexport const getCookieName = (baseName: string, prefix?: string): string => {\n return prefix ? `${prefix}${baseName}` : baseName;\n};\n\n"],"mappings":";AACA,OAAO,aAAa;AAOb,SAAS,cAAc,aAAqB;AACjD,SAAO;AAAA,IACL,IAAI,OAAe,UAAoC,CAAC,GAAS;AAC/D,cAAQ,IAAI,aAAa,OAAO,OAAO;AAAA,IACzC;AAAA,IACA,MAAM;AACJ,aAAO,QAAQ,IAAI,WAAW;AAAA,IAChC;AAAA,IACA,OAAO,oBAAyC;AAC9C,cAAQ,OAAO,aAAa,kBAAkB;AAAA,IAChD;AAAA,EACF;AACF;AAIO,SAAS,oBAAoB,UAAiC;AACnE,QAAM,YAAY,OAAO,SAAyD;AAChF,UAAM,UAAU,SAAS,QAAQ,IAAI,QAAQ;AAC7C,QAAI,CAAC,QAAS,QAAO,EAAE,OAAO,OAAU;AAExC,UAAM,QAAQ,QAAQ,MAAM,IAAI,OAAO,GAAG,IAAI,UAAU,CAAC;AACzD,WAAO,EAAE,OAAO,QAAQ,mBAAmB,MAAM,CAAC,CAAC,IAAI,OAAU;AAAA,EACnE;AAEA,QAAM,YAAY,OAChB,MACA,OACA,UAAyB,CAAC,MACR;AAClB,UAAM,EAAE,QAAQ,WAAW,MAAM,SAAS,MAAM,WAAW,UAAU,OAAO,IAAI,IAAI;AAEpF,QAAI,eAAe,GAAG,IAAI,IAAI,mBAAmB,KAAK,CAAC;AAEvD,QAAI,OAAQ,iBAAgB,aAAa,MAAM;AAC/C,QAAI,SAAU,iBAAgB;AAC9B,QAAI,OAAQ,iBAAgB;AAC5B,QAAI,SAAU,iBAAgB,cAAc,QAAQ;AACpD,QAAI,KAAM,iBAAgB,UAAU,IAAI;AAExC,aAAS,QAAQ,OAAO,cAAc,YAAY;AAAA,EACpD;AAEA,QAAM,eAAe,OAAO,SAAgC;AAC1D,UAAM,UAAU,MAAM,IAAI;AAAA,MACxB,QAAQ;AAAA,MACR,UAAU;AAAA,MACV,QAAQ;AAAA,MACR,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAEA,SAAO;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,QAAQ;AAAA,EACV;AACF;AAEO,IAAM,kBAAkB,MAAc;AAC3C,QAAM,eAAe,QAAQ,IAAI,aAAa;AAC9C,SAAO,eAAe,YAAY;AACpC;AAEO,IAAM,gBAAgB,CAAC,UAAkB,WAA4B;AAC1E,SAAO,SAAS,GAAG,MAAM,GAAG,QAAQ,KAAK;AAC3C;","names":[]}
1
+ {"version":3,"sources":["../src/cookie.ts"],"sourcesContent":["import type { CookieOptions, CookieStore } from '@tern-secure/types';\nimport Cookies from 'js-cookie';\n\ntype removeCookieParams = {\n path?: string;\n domain?: string;\n};\n\nexport function cookieHandler(cookieNanme: string) {\n return {\n set(value: string, options: Cookies.CookieAttributes = {}): void {\n Cookies.set(cookieNanme, value, options);\n },\n get() {\n return Cookies.get(cookieNanme);\n },\n remove(removeCookieParams?: removeCookieParams) {\n Cookies.remove(cookieNanme, removeCookieParams);\n },\n };\n}\n\nexport type CookieAttributes = Cookies.CookieAttributes;\n\nexport function serverCookieHandler(response: Response): CookieStore {\n const getCookie = async (name: string): Promise<{ value: string | undefined }> => {\n const cookies = response.headers.get('cookie');\n if (!cookies) return { value: undefined };\n\n const match = cookies.match(new RegExp(`${name}=([^;]+)`));\n return { value: match ? decodeURIComponent(match[1]) : undefined };\n };\n\n const setCookie = async (\n name: string,\n value: string,\n options: CookieOptions = {},\n ): Promise<void> => {\n const { maxAge, httpOnly = true, secure = true, sameSite = 'strict', path = '/' } = options;\n\n let cookieString = `${name}=${encodeURIComponent(value)}`;\n\n if (maxAge) cookieString += `; Max-Age=${maxAge}`;\n if (httpOnly) cookieString += '; HttpOnly';\n if (secure) cookieString += '; Secure';\n if (sameSite) cookieString += `; SameSite=${sameSite}`;\n if (path) cookieString += `; Path=${path}`;\n\n response.headers.append('Set-Cookie', cookieString);\n };\n\n const deleteCookie = async (name: string): Promise<void> => {\n await setCookie(name, '', {\n maxAge: 0,\n httpOnly: true,\n secure: true,\n path: '/',\n });\n };\n\n return {\n get: getCookie,\n set: setCookie,\n delete: deleteCookie,\n };\n}\n\nexport const getCookiePrefix = (): string => {\n const isProduction = process.env.NODE_ENV === 'production';\n return isProduction ? '__HOST-' : '__dev_';\n};\n\nexport const getCookieName = (baseName: string, prefix?: string): string => {\n return prefix ? `${prefix}${baseName}` : baseName;\n};\n"],"mappings":";AACA,OAAO,aAAa;AAOb,SAAS,cAAc,aAAqB;AACjD,SAAO;AAAA,IACL,IAAI,OAAe,UAAoC,CAAC,GAAS;AAC/D,cAAQ,IAAI,aAAa,OAAO,OAAO;AAAA,IACzC;AAAA,IACA,MAAM;AACJ,aAAO,QAAQ,IAAI,WAAW;AAAA,IAChC;AAAA,IACA,OAAO,oBAAyC;AAC9C,cAAQ,OAAO,aAAa,kBAAkB;AAAA,IAChD;AAAA,EACF;AACF;AAIO,SAAS,oBAAoB,UAAiC;AACnE,QAAM,YAAY,OAAO,SAAyD;AAChF,UAAM,UAAU,SAAS,QAAQ,IAAI,QAAQ;AAC7C,QAAI,CAAC,QAAS,QAAO,EAAE,OAAO,OAAU;AAExC,UAAM,QAAQ,QAAQ,MAAM,IAAI,OAAO,GAAG,IAAI,UAAU,CAAC;AACzD,WAAO,EAAE,OAAO,QAAQ,mBAAmB,MAAM,CAAC,CAAC,IAAI,OAAU;AAAA,EACnE;AAEA,QAAM,YAAY,OAChB,MACA,OACA,UAAyB,CAAC,MACR;AAClB,UAAM,EAAE,QAAQ,WAAW,MAAM,SAAS,MAAM,WAAW,UAAU,OAAO,IAAI,IAAI;AAEpF,QAAI,eAAe,GAAG,IAAI,IAAI,mBAAmB,KAAK,CAAC;AAEvD,QAAI,OAAQ,iBAAgB,aAAa,MAAM;AAC/C,QAAI,SAAU,iBAAgB;AAC9B,QAAI,OAAQ,iBAAgB;AAC5B,QAAI,SAAU,iBAAgB,cAAc,QAAQ;AACpD,QAAI,KAAM,iBAAgB,UAAU,IAAI;AAExC,aAAS,QAAQ,OAAO,cAAc,YAAY;AAAA,EACpD;AAEA,QAAM,eAAe,OAAO,SAAgC;AAC1D,UAAM,UAAU,MAAM,IAAI;AAAA,MACxB,QAAQ;AAAA,MACR,UAAU;AAAA,MACV,QAAQ;AAAA,MACR,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAEA,SAAO;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,QAAQ;AAAA,EACV;AACF;AAEO,IAAM,kBAAkB,MAAc;AAC3C,QAAM,eAAe,QAAQ,IAAI,aAAa;AAC9C,SAAO,eAAe,YAAY;AACpC;AAEO,IAAM,gBAAgB,CAAC,UAAkB,WAA4B;AAC1E,SAAO,SAAS,GAAG,MAAM,GAAG,QAAQ,KAAK;AAC3C;","names":[]}
@@ -0,0 +1,18 @@
1
+ declare function dateTo12HourTime(date: Date): string;
2
+ declare function differenceInCalendarDays(a: Date, b: Date, { absolute }?: {
3
+ absolute?: boolean | undefined;
4
+ }): number;
5
+ declare function normalizeDate(d: Date | string | number): Date;
6
+ type DateFormatRelativeParams = {
7
+ date: Date | string | number;
8
+ relativeTo: Date | string | number;
9
+ };
10
+ type RelativeDateCase = 'previous6Days' | 'lastDay' | 'sameDay' | 'nextDay' | 'next6Days' | 'other';
11
+ type RelativeDateReturn = {
12
+ relativeDateCase: RelativeDateCase;
13
+ date: Date;
14
+ } | null;
15
+ declare function formatRelative(props: DateFormatRelativeParams): RelativeDateReturn;
16
+ declare function addYears(initialDate: Date | number | string, yearsToAdd: number): Date;
17
+
18
+ export { type RelativeDateCase, addYears, dateTo12HourTime, differenceInCalendarDays, formatRelative, normalizeDate };
package/dist/date.d.ts ADDED
@@ -0,0 +1,18 @@
1
+ declare function dateTo12HourTime(date: Date): string;
2
+ declare function differenceInCalendarDays(a: Date, b: Date, { absolute }?: {
3
+ absolute?: boolean | undefined;
4
+ }): number;
5
+ declare function normalizeDate(d: Date | string | number): Date;
6
+ type DateFormatRelativeParams = {
7
+ date: Date | string | number;
8
+ relativeTo: Date | string | number;
9
+ };
10
+ type RelativeDateCase = 'previous6Days' | 'lastDay' | 'sameDay' | 'nextDay' | 'next6Days' | 'other';
11
+ type RelativeDateReturn = {
12
+ relativeDateCase: RelativeDateCase;
13
+ date: Date;
14
+ } | null;
15
+ declare function formatRelative(props: DateFormatRelativeParams): RelativeDateReturn;
16
+ declare function addYears(initialDate: Date | number | string, yearsToAdd: number): Date;
17
+
18
+ export { type RelativeDateCase, addYears, dateTo12HourTime, differenceInCalendarDays, formatRelative, normalizeDate };
package/dist/date.js ADDED
@@ -0,0 +1,98 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/date.ts
21
+ var date_exports = {};
22
+ __export(date_exports, {
23
+ addYears: () => addYears,
24
+ dateTo12HourTime: () => dateTo12HourTime,
25
+ differenceInCalendarDays: () => differenceInCalendarDays,
26
+ formatRelative: () => formatRelative,
27
+ normalizeDate: () => normalizeDate
28
+ });
29
+ module.exports = __toCommonJS(date_exports);
30
+ var MILLISECONDS_IN_DAY = 864e5;
31
+ function dateTo12HourTime(date) {
32
+ if (!date) {
33
+ return "";
34
+ }
35
+ return date.toLocaleString("en-US", {
36
+ hour: "2-digit",
37
+ minute: "numeric",
38
+ hour12: true
39
+ });
40
+ }
41
+ function differenceInCalendarDays(a, b, { absolute = true } = {}) {
42
+ if (!a || !b) {
43
+ return 0;
44
+ }
45
+ const utcA = Date.UTC(a.getFullYear(), a.getMonth(), a.getDate());
46
+ const utcB = Date.UTC(b.getFullYear(), b.getMonth(), b.getDate());
47
+ const diff = Math.floor((utcB - utcA) / MILLISECONDS_IN_DAY);
48
+ return absolute ? Math.abs(diff) : diff;
49
+ }
50
+ function normalizeDate(d) {
51
+ try {
52
+ return new Date(d || /* @__PURE__ */ new Date());
53
+ } catch {
54
+ return /* @__PURE__ */ new Date();
55
+ }
56
+ }
57
+ function formatRelative(props) {
58
+ const { date, relativeTo } = props;
59
+ if (!date || !relativeTo) {
60
+ return null;
61
+ }
62
+ const a = normalizeDate(date);
63
+ const b = normalizeDate(relativeTo);
64
+ const differenceInDays = differenceInCalendarDays(b, a, { absolute: false });
65
+ if (differenceInDays < -6) {
66
+ return { relativeDateCase: "other", date: a };
67
+ }
68
+ if (differenceInDays < -1) {
69
+ return { relativeDateCase: "previous6Days", date: a };
70
+ }
71
+ if (differenceInDays === -1) {
72
+ return { relativeDateCase: "lastDay", date: a };
73
+ }
74
+ if (differenceInDays === 0) {
75
+ return { relativeDateCase: "sameDay", date: a };
76
+ }
77
+ if (differenceInDays === 1) {
78
+ return { relativeDateCase: "nextDay", date: a };
79
+ }
80
+ if (differenceInDays < 7) {
81
+ return { relativeDateCase: "next6Days", date: a };
82
+ }
83
+ return { relativeDateCase: "other", date: a };
84
+ }
85
+ function addYears(initialDate, yearsToAdd) {
86
+ const date = normalizeDate(initialDate);
87
+ date.setFullYear(date.getFullYear() + yearsToAdd);
88
+ return date;
89
+ }
90
+ // Annotate the CommonJS export names for ESM import in node:
91
+ 0 && (module.exports = {
92
+ addYears,
93
+ dateTo12HourTime,
94
+ differenceInCalendarDays,
95
+ formatRelative,
96
+ normalizeDate
97
+ });
98
+ //# sourceMappingURL=date.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/date.ts"],"sourcesContent":["const MILLISECONDS_IN_DAY = 86400000;\n\nexport function dateTo12HourTime(date: Date): string {\n if (!date) {\n return '';\n }\n return date.toLocaleString('en-US', {\n hour: '2-digit',\n minute: 'numeric',\n hour12: true,\n });\n}\n\nexport function differenceInCalendarDays(a: Date, b: Date, { absolute = true } = {}): number {\n if (!a || !b) {\n return 0;\n }\n const utcA = Date.UTC(a.getFullYear(), a.getMonth(), a.getDate());\n const utcB = Date.UTC(b.getFullYear(), b.getMonth(), b.getDate());\n const diff = Math.floor((utcB - utcA) / MILLISECONDS_IN_DAY);\n return absolute ? Math.abs(diff) : diff;\n}\n\nexport function normalizeDate(d: Date | string | number): Date {\n try {\n return new Date(d || new Date());\n } catch {\n return new Date();\n }\n}\n\ntype DateFormatRelativeParams = {\n date: Date | string | number;\n relativeTo: Date | string | number;\n};\n\nexport type RelativeDateCase = 'previous6Days' | 'lastDay' | 'sameDay' | 'nextDay' | 'next6Days' | 'other';\ntype RelativeDateReturn = { relativeDateCase: RelativeDateCase; date: Date } | null;\n\nexport function formatRelative(props: DateFormatRelativeParams): RelativeDateReturn {\n const { date, relativeTo } = props;\n if (!date || !relativeTo) {\n return null;\n }\n const a = normalizeDate(date);\n const b = normalizeDate(relativeTo);\n const differenceInDays = differenceInCalendarDays(b, a, { absolute: false });\n\n if (differenceInDays < -6) {\n return { relativeDateCase: 'other', date: a };\n }\n if (differenceInDays < -1) {\n return { relativeDateCase: 'previous6Days', date: a };\n }\n if (differenceInDays === -1) {\n return { relativeDateCase: 'lastDay', date: a };\n }\n if (differenceInDays === 0) {\n return { relativeDateCase: 'sameDay', date: a };\n }\n if (differenceInDays === 1) {\n return { relativeDateCase: 'nextDay', date: a };\n }\n if (differenceInDays < 7) {\n return { relativeDateCase: 'next6Days', date: a };\n }\n return { relativeDateCase: 'other', date: a };\n}\n\nexport function addYears(initialDate: Date | number | string, yearsToAdd: number): Date {\n const date = normalizeDate(initialDate);\n date.setFullYear(date.getFullYear() + yearsToAdd);\n return date;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAAM,sBAAsB;AAErB,SAAS,iBAAiB,MAAoB;AACnD,MAAI,CAAC,MAAM;AACT,WAAO;AAAA,EACT;AACA,SAAO,KAAK,eAAe,SAAS;AAAA,IAClC,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,QAAQ;AAAA,EACV,CAAC;AACH;AAEO,SAAS,yBAAyB,GAAS,GAAS,EAAE,WAAW,KAAK,IAAI,CAAC,GAAW;AAC3F,MAAI,CAAC,KAAK,CAAC,GAAG;AACZ,WAAO;AAAA,EACT;AACA,QAAM,OAAO,KAAK,IAAI,EAAE,YAAY,GAAG,EAAE,SAAS,GAAG,EAAE,QAAQ,CAAC;AAChE,QAAM,OAAO,KAAK,IAAI,EAAE,YAAY,GAAG,EAAE,SAAS,GAAG,EAAE,QAAQ,CAAC;AAChE,QAAM,OAAO,KAAK,OAAO,OAAO,QAAQ,mBAAmB;AAC3D,SAAO,WAAW,KAAK,IAAI,IAAI,IAAI;AACrC;AAEO,SAAS,cAAc,GAAiC;AAC7D,MAAI;AACF,WAAO,IAAI,KAAK,KAAK,oBAAI,KAAK,CAAC;AAAA,EACjC,QAAQ;AACN,WAAO,oBAAI,KAAK;AAAA,EAClB;AACF;AAUO,SAAS,eAAe,OAAqD;AAClF,QAAM,EAAE,MAAM,WAAW,IAAI;AAC7B,MAAI,CAAC,QAAQ,CAAC,YAAY;AACxB,WAAO;AAAA,EACT;AACA,QAAM,IAAI,cAAc,IAAI;AAC5B,QAAM,IAAI,cAAc,UAAU;AAClC,QAAM,mBAAmB,yBAAyB,GAAG,GAAG,EAAE,UAAU,MAAM,CAAC;AAE3E,MAAI,mBAAmB,IAAI;AACzB,WAAO,EAAE,kBAAkB,SAAS,MAAM,EAAE;AAAA,EAC9C;AACA,MAAI,mBAAmB,IAAI;AACzB,WAAO,EAAE,kBAAkB,iBAAiB,MAAM,EAAE;AAAA,EACtD;AACA,MAAI,qBAAqB,IAAI;AAC3B,WAAO,EAAE,kBAAkB,WAAW,MAAM,EAAE;AAAA,EAChD;AACA,MAAI,qBAAqB,GAAG;AAC1B,WAAO,EAAE,kBAAkB,WAAW,MAAM,EAAE;AAAA,EAChD;AACA,MAAI,qBAAqB,GAAG;AAC1B,WAAO,EAAE,kBAAkB,WAAW,MAAM,EAAE;AAAA,EAChD;AACA,MAAI,mBAAmB,GAAG;AACxB,WAAO,EAAE,kBAAkB,aAAa,MAAM,EAAE;AAAA,EAClD;AACA,SAAO,EAAE,kBAAkB,SAAS,MAAM,EAAE;AAC9C;AAEO,SAAS,SAAS,aAAqC,YAA0B;AACtF,QAAM,OAAO,cAAc,WAAW;AACtC,OAAK,YAAY,KAAK,YAAY,IAAI,UAAU;AAChD,SAAO;AACT;","names":[]}
package/dist/date.mjs ADDED
@@ -0,0 +1,69 @@
1
+ // src/date.ts
2
+ var MILLISECONDS_IN_DAY = 864e5;
3
+ function dateTo12HourTime(date) {
4
+ if (!date) {
5
+ return "";
6
+ }
7
+ return date.toLocaleString("en-US", {
8
+ hour: "2-digit",
9
+ minute: "numeric",
10
+ hour12: true
11
+ });
12
+ }
13
+ function differenceInCalendarDays(a, b, { absolute = true } = {}) {
14
+ if (!a || !b) {
15
+ return 0;
16
+ }
17
+ const utcA = Date.UTC(a.getFullYear(), a.getMonth(), a.getDate());
18
+ const utcB = Date.UTC(b.getFullYear(), b.getMonth(), b.getDate());
19
+ const diff = Math.floor((utcB - utcA) / MILLISECONDS_IN_DAY);
20
+ return absolute ? Math.abs(diff) : diff;
21
+ }
22
+ function normalizeDate(d) {
23
+ try {
24
+ return new Date(d || /* @__PURE__ */ new Date());
25
+ } catch {
26
+ return /* @__PURE__ */ new Date();
27
+ }
28
+ }
29
+ function formatRelative(props) {
30
+ const { date, relativeTo } = props;
31
+ if (!date || !relativeTo) {
32
+ return null;
33
+ }
34
+ const a = normalizeDate(date);
35
+ const b = normalizeDate(relativeTo);
36
+ const differenceInDays = differenceInCalendarDays(b, a, { absolute: false });
37
+ if (differenceInDays < -6) {
38
+ return { relativeDateCase: "other", date: a };
39
+ }
40
+ if (differenceInDays < -1) {
41
+ return { relativeDateCase: "previous6Days", date: a };
42
+ }
43
+ if (differenceInDays === -1) {
44
+ return { relativeDateCase: "lastDay", date: a };
45
+ }
46
+ if (differenceInDays === 0) {
47
+ return { relativeDateCase: "sameDay", date: a };
48
+ }
49
+ if (differenceInDays === 1) {
50
+ return { relativeDateCase: "nextDay", date: a };
51
+ }
52
+ if (differenceInDays < 7) {
53
+ return { relativeDateCase: "next6Days", date: a };
54
+ }
55
+ return { relativeDateCase: "other", date: a };
56
+ }
57
+ function addYears(initialDate, yearsToAdd) {
58
+ const date = normalizeDate(initialDate);
59
+ date.setFullYear(date.getFullYear() + yearsToAdd);
60
+ return date;
61
+ }
62
+ export {
63
+ addYears,
64
+ dateTo12HourTime,
65
+ differenceInCalendarDays,
66
+ formatRelative,
67
+ normalizeDate
68
+ };
69
+ //# sourceMappingURL=date.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/date.ts"],"sourcesContent":["const MILLISECONDS_IN_DAY = 86400000;\n\nexport function dateTo12HourTime(date: Date): string {\n if (!date) {\n return '';\n }\n return date.toLocaleString('en-US', {\n hour: '2-digit',\n minute: 'numeric',\n hour12: true,\n });\n}\n\nexport function differenceInCalendarDays(a: Date, b: Date, { absolute = true } = {}): number {\n if (!a || !b) {\n return 0;\n }\n const utcA = Date.UTC(a.getFullYear(), a.getMonth(), a.getDate());\n const utcB = Date.UTC(b.getFullYear(), b.getMonth(), b.getDate());\n const diff = Math.floor((utcB - utcA) / MILLISECONDS_IN_DAY);\n return absolute ? Math.abs(diff) : diff;\n}\n\nexport function normalizeDate(d: Date | string | number): Date {\n try {\n return new Date(d || new Date());\n } catch {\n return new Date();\n }\n}\n\ntype DateFormatRelativeParams = {\n date: Date | string | number;\n relativeTo: Date | string | number;\n};\n\nexport type RelativeDateCase = 'previous6Days' | 'lastDay' | 'sameDay' | 'nextDay' | 'next6Days' | 'other';\ntype RelativeDateReturn = { relativeDateCase: RelativeDateCase; date: Date } | null;\n\nexport function formatRelative(props: DateFormatRelativeParams): RelativeDateReturn {\n const { date, relativeTo } = props;\n if (!date || !relativeTo) {\n return null;\n }\n const a = normalizeDate(date);\n const b = normalizeDate(relativeTo);\n const differenceInDays = differenceInCalendarDays(b, a, { absolute: false });\n\n if (differenceInDays < -6) {\n return { relativeDateCase: 'other', date: a };\n }\n if (differenceInDays < -1) {\n return { relativeDateCase: 'previous6Days', date: a };\n }\n if (differenceInDays === -1) {\n return { relativeDateCase: 'lastDay', date: a };\n }\n if (differenceInDays === 0) {\n return { relativeDateCase: 'sameDay', date: a };\n }\n if (differenceInDays === 1) {\n return { relativeDateCase: 'nextDay', date: a };\n }\n if (differenceInDays < 7) {\n return { relativeDateCase: 'next6Days', date: a };\n }\n return { relativeDateCase: 'other', date: a };\n}\n\nexport function addYears(initialDate: Date | number | string, yearsToAdd: number): Date {\n const date = normalizeDate(initialDate);\n date.setFullYear(date.getFullYear() + yearsToAdd);\n return date;\n}\n"],"mappings":";AAAA,IAAM,sBAAsB;AAErB,SAAS,iBAAiB,MAAoB;AACnD,MAAI,CAAC,MAAM;AACT,WAAO;AAAA,EACT;AACA,SAAO,KAAK,eAAe,SAAS;AAAA,IAClC,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,QAAQ;AAAA,EACV,CAAC;AACH;AAEO,SAAS,yBAAyB,GAAS,GAAS,EAAE,WAAW,KAAK,IAAI,CAAC,GAAW;AAC3F,MAAI,CAAC,KAAK,CAAC,GAAG;AACZ,WAAO;AAAA,EACT;AACA,QAAM,OAAO,KAAK,IAAI,EAAE,YAAY,GAAG,EAAE,SAAS,GAAG,EAAE,QAAQ,CAAC;AAChE,QAAM,OAAO,KAAK,IAAI,EAAE,YAAY,GAAG,EAAE,SAAS,GAAG,EAAE,QAAQ,CAAC;AAChE,QAAM,OAAO,KAAK,OAAO,OAAO,QAAQ,mBAAmB;AAC3D,SAAO,WAAW,KAAK,IAAI,IAAI,IAAI;AACrC;AAEO,SAAS,cAAc,GAAiC;AAC7D,MAAI;AACF,WAAO,IAAI,KAAK,KAAK,oBAAI,KAAK,CAAC;AAAA,EACjC,QAAQ;AACN,WAAO,oBAAI,KAAK;AAAA,EAClB;AACF;AAUO,SAAS,eAAe,OAAqD;AAClF,QAAM,EAAE,MAAM,WAAW,IAAI;AAC7B,MAAI,CAAC,QAAQ,CAAC,YAAY;AACxB,WAAO;AAAA,EACT;AACA,QAAM,IAAI,cAAc,IAAI;AAC5B,QAAM,IAAI,cAAc,UAAU;AAClC,QAAM,mBAAmB,yBAAyB,GAAG,GAAG,EAAE,UAAU,MAAM,CAAC;AAE3E,MAAI,mBAAmB,IAAI;AACzB,WAAO,EAAE,kBAAkB,SAAS,MAAM,EAAE;AAAA,EAC9C;AACA,MAAI,mBAAmB,IAAI;AACzB,WAAO,EAAE,kBAAkB,iBAAiB,MAAM,EAAE;AAAA,EACtD;AACA,MAAI,qBAAqB,IAAI;AAC3B,WAAO,EAAE,kBAAkB,WAAW,MAAM,EAAE;AAAA,EAChD;AACA,MAAI,qBAAqB,GAAG;AAC1B,WAAO,EAAE,kBAAkB,WAAW,MAAM,EAAE;AAAA,EAChD;AACA,MAAI,qBAAqB,GAAG;AAC1B,WAAO,EAAE,kBAAkB,WAAW,MAAM,EAAE;AAAA,EAChD;AACA,MAAI,mBAAmB,GAAG;AACxB,WAAO,EAAE,kBAAkB,aAAa,MAAM,EAAE;AAAA,EAClD;AACA,SAAO,EAAE,kBAAkB,SAAS,MAAM,EAAE;AAC9C;AAEO,SAAS,SAAS,aAAqC,YAA0B;AACtF,QAAM,OAAO,cAAc,WAAW;AACtC,OAAK,YAAY,KAAK,YAAY,IAAI,UAAU;AAChD,SAAO;AACT;","names":[]}
package/dist/errors.js CHANGED
@@ -65,7 +65,7 @@ function handleFirebaseAuthError(error) {
65
65
  "invalid-credential": { message: "Invalid email or password", code: "INVALID_CREDENTIALS" },
66
66
  "invalid-login-credentials": { message: "Invalid email or password", code: "INVALID_CREDENTIALS" },
67
67
  "wrong-password": { message: "Invalid email or password", code: "INVALID_CREDENTIALS" },
68
- "user-not-found": { message: "Invalid email or password", code: "INVALID_CREDENTIALS" },
68
+ "user-not-found": { message: "User not found", code: "USER_NOT_FOUND" },
69
69
  "user-disabled": { message: "This account has been disabled", code: "USER_DISABLED" },
70
70
  "too-many-requests": { message: "Too many attempts. Please try again later", code: "TOO_MANY_ATTEMPTS" },
71
71
  "network-request-failed": { message: "Network error. Please check your connection", code: "NETWORK_ERROR" },
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/errors.ts"],"sourcesContent":["import type { AuthErrorResponse, ErrorCode } from \"@tern-secure/types\";\n\n\nexport class TernSecureError extends Error {\n code: ErrorCode\n\n constructor(code: ErrorCode, message?: string) {\n super(message || code)\n this.name = \"TernSecureError\"\n this.code = code\n }\n}\n\n\n/**\n * Handles Firebase authentication errors with multiple fallback mechanisms\n */\nexport function handleFirebaseAuthError(error: unknown): AuthErrorResponse {\n function extractErrorInfo(input: unknown): { code: string; message: string } | null {\n // Case 1: String input (direct Firebase error message)\n if (typeof input === 'string') {\n const match = input.match(/Firebase:\\s*Error\\s*\\(auth\\/([^)]+)\\)/);\n if (match) {\n return { code: match[1], message: input };\n }\n }\n\n // Case 2: Error object\n if (input && typeof input === 'object') {\n const err = input as { code?: string; message?: string };\n \n // Check for bundled message format first\n if (err.message) {\n const match = err.message.match(/Firebase:\\s*Error\\s*\\(auth\\/([^)]+)\\)/);\n if (match) {\n return { code: match[1], message: err.message };\n }\n }\n\n // Check for direct code\n if (err.code) {\n return {\n code: err.code.replace('auth/', ''),\n message: err.message || ''\n };\n }\n }\n\n return null;\n }\n\n // Map error codes to user-friendly messages\n const ERROR_MESSAGES: Record<string, { message: string; code: ErrorCode }> = {\n 'argument-error': { message: 'Method called with incorrect arguments', code: 'INCORRECT_ARGUMENT' },\n 'invalid-email': { message: 'Invalid email format', code: 'INVALID_EMAIL' },\n 'invalid-tenant-id': { message: 'Invalid tenant ID', code: 'INVALID_ARGUMENT' },\n 'invalid-credential': { message: 'Invalid email or password', code: 'INVALID_CREDENTIALS' },\n 'invalid-login-credentials': { message: 'Invalid email or password', code: 'INVALID_CREDENTIALS' },\n 'wrong-password': { message: 'Invalid email or password', code: 'INVALID_CREDENTIALS' },\n 'user-not-found': { message: 'Invalid email or password', code: 'INVALID_CREDENTIALS' },\n 'user-disabled': { message: 'This account has been disabled', code: 'USER_DISABLED' },\n 'too-many-requests': { message: 'Too many attempts. Please try again later', code: 'TOO_MANY_ATTEMPTS' },\n 'network-request-failed': { message: 'Network error. Please check your connection', code: 'NETWORK_ERROR' },\n 'email-already-in-use': { message: 'This email is already in use', code: 'EMAIL_EXISTS' },\n 'weak-password': { message: 'Password is too weak', code: 'WEAK_PASSWORD' },\n 'operation-not-allowed': { message: 'This login method is not enabled', code: 'OPERATION_NOT_ALLOWED' },\n 'popup-blocked': { message: 'Login popup was blocked. Please enable popups', code: 'POPUP_BLOCKED' },\n 'expired-action-code': { message: 'Your session has expired. Please login again', code: 'EXPIRED_TOKEN' },\n 'user-token-expired': { message: 'Your session has expired. Please login again', code: 'EXPIRED_TOKEN' },\n 'tenant-not-found': { message: 'There is no tenant corresponding to the provided identifier.', code: 'INVALID_ARGUMENT' },\n };\n\n try {\n // Extract error information\n const errorInfo = extractErrorInfo(error);\n \n if (errorInfo) {\n const mappedError = ERROR_MESSAGES[errorInfo.code];\n if (mappedError) {\n return {\n success: false,\n message: mappedError.message,\n code: mappedError.code\n };\n }\n }\n\n // If we couldn't extract or map the error, try one last time with string conversion\n const errorString = String(error);\n const lastMatch = errorString.match(/Firebase:\\s*Error\\s*\\(auth\\/([^)]+)\\)/);\n if (lastMatch && ERROR_MESSAGES[lastMatch[1]]) {\n return {\n success: false,\n ...ERROR_MESSAGES[lastMatch[1]]\n };\n }\n\n } catch (e) {\n // Silent catch - we'll return the default error\n }\n\n // Default fallback\n return {\n success: false,\n message: 'An unexpected error occurred. Please try again later',\n code: 'INTERNAL_ERROR'\n };\n}\n\n/**\n * Type guard to check if a response is an AuthErrorResponse\n */\nexport function isAuthErrorResponse(response: unknown): response is AuthErrorResponse {\n return (\n typeof response === \"object\" &&\n response !== null &&\n \"success\" in response &&\n (response as { success: boolean }).success === false &&\n \"code\" in response &&\n \"message\" in response\n )\n}\n\nexport function getErrorAlertVariant(error: any | undefined) {\n if (!error) return \"destructive\"\n\n switch (error.error) {\n case \"AUTHENTICATED\":\n return \"default\"\n case \"EMAIL_EXISTS\":\n case \"UNAUTHENTICATED\":\n case \"UNVERIFIED\":\n case \"REQUIRES_VERIFICATION\":\n case \"INVALID_EMAIL\":\n case \"INVALID_TOKEN\":\n case \"INTERNAL_ERROR\":\n case \"USER_DISABLED\":\n case \"TOO_MANY_ATTEMPTS\":\n case \"NETWORK_ERROR\":\n case \"SESSION_EXPIRED\":\n case \"EXPIRED_TOKEN\":\n case \"INVALID_CREDENTIALS\":\n default:\n return \"destructive\"\n }\n}"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/errors.ts"],"sourcesContent":["import type { AuthErrorResponse, ErrorCode } from \"@tern-secure/types\";\n\n\nexport class TernSecureError extends Error {\n code: ErrorCode\n\n constructor(code: ErrorCode, message?: string) {\n super(message || code)\n this.name = \"TernSecureError\"\n this.code = code\n }\n}\n\n\n/**\n * Handles Firebase authentication errors with multiple fallback mechanisms\n */\nexport function handleFirebaseAuthError(error: unknown): AuthErrorResponse {\n function extractErrorInfo(input: unknown): { code: string; message: string } | null {\n // Case 1: String input (direct Firebase error message)\n if (typeof input === 'string') {\n const match = input.match(/Firebase:\\s*Error\\s*\\(auth\\/([^)]+)\\)/);\n if (match) {\n return { code: match[1], message: input };\n }\n }\n\n // Case 2: Error object\n if (input && typeof input === 'object') {\n const err = input as { code?: string; message?: string };\n \n // Check for bundled message format first\n if (err.message) {\n const match = err.message.match(/Firebase:\\s*Error\\s*\\(auth\\/([^)]+)\\)/);\n if (match) {\n return { code: match[1], message: err.message };\n }\n }\n\n // Check for direct code\n if (err.code) {\n return {\n code: err.code.replace('auth/', ''),\n message: err.message || ''\n };\n }\n }\n\n return null;\n }\n\n // Map error codes to user-friendly messages\n const ERROR_MESSAGES: Record<string, { message: string; code: ErrorCode }> = {\n 'argument-error': { message: 'Method called with incorrect arguments', code: 'INCORRECT_ARGUMENT' },\n 'invalid-email': { message: 'Invalid email format', code: 'INVALID_EMAIL' },\n 'invalid-tenant-id': { message: 'Invalid tenant ID', code: 'INVALID_ARGUMENT' },\n 'invalid-credential': { message: 'Invalid email or password', code: 'INVALID_CREDENTIALS' },\n 'invalid-login-credentials': { message: 'Invalid email or password', code: 'INVALID_CREDENTIALS' },\n 'wrong-password': { message: 'Invalid email or password', code: 'INVALID_CREDENTIALS' },\n 'user-not-found': { message: 'User not found', code: 'USER_NOT_FOUND' },\n 'user-disabled': { message: 'This account has been disabled', code: 'USER_DISABLED' },\n 'too-many-requests': { message: 'Too many attempts. Please try again later', code: 'TOO_MANY_ATTEMPTS' },\n 'network-request-failed': { message: 'Network error. Please check your connection', code: 'NETWORK_ERROR' },\n 'email-already-in-use': { message: 'This email is already in use', code: 'EMAIL_EXISTS' },\n 'weak-password': { message: 'Password is too weak', code: 'WEAK_PASSWORD' },\n 'operation-not-allowed': { message: 'This login method is not enabled', code: 'OPERATION_NOT_ALLOWED' },\n 'popup-blocked': { message: 'Login popup was blocked. Please enable popups', code: 'POPUP_BLOCKED' },\n 'expired-action-code': { message: 'Your session has expired. Please login again', code: 'EXPIRED_TOKEN' },\n 'user-token-expired': { message: 'Your session has expired. Please login again', code: 'EXPIRED_TOKEN' },\n 'tenant-not-found': { message: 'There is no tenant corresponding to the provided identifier.', code: 'INVALID_ARGUMENT' },\n };\n\n try {\n // Extract error information\n const errorInfo = extractErrorInfo(error);\n \n if (errorInfo) {\n const mappedError = ERROR_MESSAGES[errorInfo.code];\n if (mappedError) {\n return {\n success: false,\n message: mappedError.message,\n code: mappedError.code\n };\n }\n }\n\n // If we couldn't extract or map the error, try one last time with string conversion\n const errorString = String(error);\n const lastMatch = errorString.match(/Firebase:\\s*Error\\s*\\(auth\\/([^)]+)\\)/);\n if (lastMatch && ERROR_MESSAGES[lastMatch[1]]) {\n return {\n success: false,\n ...ERROR_MESSAGES[lastMatch[1]]\n };\n }\n\n } catch (e) {\n // Silent catch - we'll return the default error\n }\n\n // Default fallback\n return {\n success: false,\n message: 'An unexpected error occurred. Please try again later',\n code: 'INTERNAL_ERROR'\n };\n}\n\n/**\n * Type guard to check if a response is an AuthErrorResponse\n */\nexport function isAuthErrorResponse(response: unknown): response is AuthErrorResponse {\n return (\n typeof response === \"object\" &&\n response !== null &&\n \"success\" in response &&\n (response as { success: boolean }).success === false &&\n \"code\" in response &&\n \"message\" in response\n )\n}\n\nexport function getErrorAlertVariant(error: any | undefined) {\n if (!error) return \"destructive\"\n\n switch (error.error) {\n case \"AUTHENTICATED\":\n return \"default\"\n case \"EMAIL_EXISTS\":\n case \"UNAUTHENTICATED\":\n case \"UNVERIFIED\":\n case \"REQUIRES_VERIFICATION\":\n case \"INVALID_EMAIL\":\n case \"INVALID_TOKEN\":\n case \"INTERNAL_ERROR\":\n case \"USER_DISABLED\":\n case \"TOO_MANY_ATTEMPTS\":\n case \"NETWORK_ERROR\":\n case \"SESSION_EXPIRED\":\n case \"EXPIRED_TOKEN\":\n case \"INVALID_CREDENTIALS\":\n default:\n return \"destructive\"\n }\n}"],"mappings":"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","names":[]}
package/dist/errors.mjs CHANGED
@@ -38,7 +38,7 @@ function handleFirebaseAuthError(error) {
38
38
  "invalid-credential": { message: "Invalid email or password", code: "INVALID_CREDENTIALS" },
39
39
  "invalid-login-credentials": { message: "Invalid email or password", code: "INVALID_CREDENTIALS" },
40
40
  "wrong-password": { message: "Invalid email or password", code: "INVALID_CREDENTIALS" },
41
- "user-not-found": { message: "Invalid email or password", code: "INVALID_CREDENTIALS" },
41
+ "user-not-found": { message: "User not found", code: "USER_NOT_FOUND" },
42
42
  "user-disabled": { message: "This account has been disabled", code: "USER_DISABLED" },
43
43
  "too-many-requests": { message: "Too many attempts. Please try again later", code: "TOO_MANY_ATTEMPTS" },
44
44
  "network-request-failed": { message: "Network error. Please check your connection", code: "NETWORK_ERROR" },
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/errors.ts"],"sourcesContent":["import type { AuthErrorResponse, ErrorCode } from \"@tern-secure/types\";\n\n\nexport class TernSecureError extends Error {\n code: ErrorCode\n\n constructor(code: ErrorCode, message?: string) {\n super(message || code)\n this.name = \"TernSecureError\"\n this.code = code\n }\n}\n\n\n/**\n * Handles Firebase authentication errors with multiple fallback mechanisms\n */\nexport function handleFirebaseAuthError(error: unknown): AuthErrorResponse {\n function extractErrorInfo(input: unknown): { code: string; message: string } | null {\n // Case 1: String input (direct Firebase error message)\n if (typeof input === 'string') {\n const match = input.match(/Firebase:\\s*Error\\s*\\(auth\\/([^)]+)\\)/);\n if (match) {\n return { code: match[1], message: input };\n }\n }\n\n // Case 2: Error object\n if (input && typeof input === 'object') {\n const err = input as { code?: string; message?: string };\n \n // Check for bundled message format first\n if (err.message) {\n const match = err.message.match(/Firebase:\\s*Error\\s*\\(auth\\/([^)]+)\\)/);\n if (match) {\n return { code: match[1], message: err.message };\n }\n }\n\n // Check for direct code\n if (err.code) {\n return {\n code: err.code.replace('auth/', ''),\n message: err.message || ''\n };\n }\n }\n\n return null;\n }\n\n // Map error codes to user-friendly messages\n const ERROR_MESSAGES: Record<string, { message: string; code: ErrorCode }> = {\n 'argument-error': { message: 'Method called with incorrect arguments', code: 'INCORRECT_ARGUMENT' },\n 'invalid-email': { message: 'Invalid email format', code: 'INVALID_EMAIL' },\n 'invalid-tenant-id': { message: 'Invalid tenant ID', code: 'INVALID_ARGUMENT' },\n 'invalid-credential': { message: 'Invalid email or password', code: 'INVALID_CREDENTIALS' },\n 'invalid-login-credentials': { message: 'Invalid email or password', code: 'INVALID_CREDENTIALS' },\n 'wrong-password': { message: 'Invalid email or password', code: 'INVALID_CREDENTIALS' },\n 'user-not-found': { message: 'Invalid email or password', code: 'INVALID_CREDENTIALS' },\n 'user-disabled': { message: 'This account has been disabled', code: 'USER_DISABLED' },\n 'too-many-requests': { message: 'Too many attempts. Please try again later', code: 'TOO_MANY_ATTEMPTS' },\n 'network-request-failed': { message: 'Network error. Please check your connection', code: 'NETWORK_ERROR' },\n 'email-already-in-use': { message: 'This email is already in use', code: 'EMAIL_EXISTS' },\n 'weak-password': { message: 'Password is too weak', code: 'WEAK_PASSWORD' },\n 'operation-not-allowed': { message: 'This login method is not enabled', code: 'OPERATION_NOT_ALLOWED' },\n 'popup-blocked': { message: 'Login popup was blocked. Please enable popups', code: 'POPUP_BLOCKED' },\n 'expired-action-code': { message: 'Your session has expired. Please login again', code: 'EXPIRED_TOKEN' },\n 'user-token-expired': { message: 'Your session has expired. Please login again', code: 'EXPIRED_TOKEN' },\n 'tenant-not-found': { message: 'There is no tenant corresponding to the provided identifier.', code: 'INVALID_ARGUMENT' },\n };\n\n try {\n // Extract error information\n const errorInfo = extractErrorInfo(error);\n \n if (errorInfo) {\n const mappedError = ERROR_MESSAGES[errorInfo.code];\n if (mappedError) {\n return {\n success: false,\n message: mappedError.message,\n code: mappedError.code\n };\n }\n }\n\n // If we couldn't extract or map the error, try one last time with string conversion\n const errorString = String(error);\n const lastMatch = errorString.match(/Firebase:\\s*Error\\s*\\(auth\\/([^)]+)\\)/);\n if (lastMatch && ERROR_MESSAGES[lastMatch[1]]) {\n return {\n success: false,\n ...ERROR_MESSAGES[lastMatch[1]]\n };\n }\n\n } catch (e) {\n // Silent catch - we'll return the default error\n }\n\n // Default fallback\n return {\n success: false,\n message: 'An unexpected error occurred. Please try again later',\n code: 'INTERNAL_ERROR'\n };\n}\n\n/**\n * Type guard to check if a response is an AuthErrorResponse\n */\nexport function isAuthErrorResponse(response: unknown): response is AuthErrorResponse {\n return (\n typeof response === \"object\" &&\n response !== null &&\n \"success\" in response &&\n (response as { success: boolean }).success === false &&\n \"code\" in response &&\n \"message\" in response\n )\n}\n\nexport function getErrorAlertVariant(error: any | undefined) {\n if (!error) return \"destructive\"\n\n switch (error.error) {\n case \"AUTHENTICATED\":\n return \"default\"\n case \"EMAIL_EXISTS\":\n case \"UNAUTHENTICATED\":\n case \"UNVERIFIED\":\n case \"REQUIRES_VERIFICATION\":\n case \"INVALID_EMAIL\":\n case \"INVALID_TOKEN\":\n case \"INTERNAL_ERROR\":\n case \"USER_DISABLED\":\n case \"TOO_MANY_ATTEMPTS\":\n case \"NETWORK_ERROR\":\n case \"SESSION_EXPIRED\":\n case \"EXPIRED_TOKEN\":\n case \"INVALID_CREDENTIALS\":\n default:\n return \"destructive\"\n }\n}"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/errors.ts"],"sourcesContent":["import type { AuthErrorResponse, ErrorCode } from \"@tern-secure/types\";\n\n\nexport class TernSecureError extends Error {\n code: ErrorCode\n\n constructor(code: ErrorCode, message?: string) {\n super(message || code)\n this.name = \"TernSecureError\"\n this.code = code\n }\n}\n\n\n/**\n * Handles Firebase authentication errors with multiple fallback mechanisms\n */\nexport function handleFirebaseAuthError(error: unknown): AuthErrorResponse {\n function extractErrorInfo(input: unknown): { code: string; message: string } | null {\n // Case 1: String input (direct Firebase error message)\n if (typeof input === 'string') {\n const match = input.match(/Firebase:\\s*Error\\s*\\(auth\\/([^)]+)\\)/);\n if (match) {\n return { code: match[1], message: input };\n }\n }\n\n // Case 2: Error object\n if (input && typeof input === 'object') {\n const err = input as { code?: string; message?: string };\n \n // Check for bundled message format first\n if (err.message) {\n const match = err.message.match(/Firebase:\\s*Error\\s*\\(auth\\/([^)]+)\\)/);\n if (match) {\n return { code: match[1], message: err.message };\n }\n }\n\n // Check for direct code\n if (err.code) {\n return {\n code: err.code.replace('auth/', ''),\n message: err.message || ''\n };\n }\n }\n\n return null;\n }\n\n // Map error codes to user-friendly messages\n const ERROR_MESSAGES: Record<string, { message: string; code: ErrorCode }> = {\n 'argument-error': { message: 'Method called with incorrect arguments', code: 'INCORRECT_ARGUMENT' },\n 'invalid-email': { message: 'Invalid email format', code: 'INVALID_EMAIL' },\n 'invalid-tenant-id': { message: 'Invalid tenant ID', code: 'INVALID_ARGUMENT' },\n 'invalid-credential': { message: 'Invalid email or password', code: 'INVALID_CREDENTIALS' },\n 'invalid-login-credentials': { message: 'Invalid email or password', code: 'INVALID_CREDENTIALS' },\n 'wrong-password': { message: 'Invalid email or password', code: 'INVALID_CREDENTIALS' },\n 'user-not-found': { message: 'User not found', code: 'USER_NOT_FOUND' },\n 'user-disabled': { message: 'This account has been disabled', code: 'USER_DISABLED' },\n 'too-many-requests': { message: 'Too many attempts. Please try again later', code: 'TOO_MANY_ATTEMPTS' },\n 'network-request-failed': { message: 'Network error. Please check your connection', code: 'NETWORK_ERROR' },\n 'email-already-in-use': { message: 'This email is already in use', code: 'EMAIL_EXISTS' },\n 'weak-password': { message: 'Password is too weak', code: 'WEAK_PASSWORD' },\n 'operation-not-allowed': { message: 'This login method is not enabled', code: 'OPERATION_NOT_ALLOWED' },\n 'popup-blocked': { message: 'Login popup was blocked. Please enable popups', code: 'POPUP_BLOCKED' },\n 'expired-action-code': { message: 'Your session has expired. Please login again', code: 'EXPIRED_TOKEN' },\n 'user-token-expired': { message: 'Your session has expired. Please login again', code: 'EXPIRED_TOKEN' },\n 'tenant-not-found': { message: 'There is no tenant corresponding to the provided identifier.', code: 'INVALID_ARGUMENT' },\n };\n\n try {\n // Extract error information\n const errorInfo = extractErrorInfo(error);\n \n if (errorInfo) {\n const mappedError = ERROR_MESSAGES[errorInfo.code];\n if (mappedError) {\n return {\n success: false,\n message: mappedError.message,\n code: mappedError.code\n };\n }\n }\n\n // If we couldn't extract or map the error, try one last time with string conversion\n const errorString = String(error);\n const lastMatch = errorString.match(/Firebase:\\s*Error\\s*\\(auth\\/([^)]+)\\)/);\n if (lastMatch && ERROR_MESSAGES[lastMatch[1]]) {\n return {\n success: false,\n ...ERROR_MESSAGES[lastMatch[1]]\n };\n }\n\n } catch (e) {\n // Silent catch - we'll return the default error\n }\n\n // Default fallback\n return {\n success: false,\n message: 'An unexpected error occurred. Please try again later',\n code: 'INTERNAL_ERROR'\n };\n}\n\n/**\n * Type guard to check if a response is an AuthErrorResponse\n */\nexport function isAuthErrorResponse(response: unknown): response is AuthErrorResponse {\n return (\n typeof response === \"object\" &&\n response !== null &&\n \"success\" in response &&\n (response as { success: boolean }).success === false &&\n \"code\" in response &&\n \"message\" in response\n )\n}\n\nexport function getErrorAlertVariant(error: any | undefined) {\n if (!error) return \"destructive\"\n\n switch (error.error) {\n case \"AUTHENTICATED\":\n return \"default\"\n case \"EMAIL_EXISTS\":\n case \"UNAUTHENTICATED\":\n case \"UNVERIFIED\":\n case \"REQUIRES_VERIFICATION\":\n case \"INVALID_EMAIL\":\n case \"INVALID_TOKEN\":\n case \"INTERNAL_ERROR\":\n case \"USER_DISABLED\":\n case \"TOO_MANY_ATTEMPTS\":\n case \"NETWORK_ERROR\":\n case \"SESSION_EXPIRED\":\n case \"EXPIRED_TOKEN\":\n case \"INVALID_CREDENTIALS\":\n default:\n return \"destructive\"\n }\n}"],"mappings":"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","names":[]}
@@ -23,6 +23,65 @@ __export(loadScript_exports, {
23
23
  loadScript: () => loadScript
24
24
  });
25
25
  module.exports = __toCommonJS(loadScript_exports);
26
+
27
+ // src/retry.ts
28
+ var defaultOptions = {
29
+ initialDelay: 125,
30
+ maxDelayBetweenRetries: 0,
31
+ factor: 2,
32
+ shouldRetry: (_, iteration) => iteration < 5,
33
+ retryImmediately: false,
34
+ jitter: true
35
+ };
36
+ var RETRY_IMMEDIATELY_DELAY = 100;
37
+ var sleep = async (ms) => new Promise((s) => setTimeout(s, ms));
38
+ var applyJitter = (delay, jitter) => {
39
+ return jitter ? delay * (1 + Math.random()) : delay;
40
+ };
41
+ var createExponentialDelayAsyncFn = (opts) => {
42
+ let timesCalled = 0;
43
+ const calculateDelayInMs = () => {
44
+ const constant = opts.initialDelay;
45
+ const base = opts.factor;
46
+ let delay = constant * Math.pow(base, timesCalled);
47
+ delay = applyJitter(delay, opts.jitter);
48
+ return Math.min(opts.maxDelayBetweenRetries || delay, delay);
49
+ };
50
+ return async () => {
51
+ await sleep(calculateDelayInMs());
52
+ timesCalled++;
53
+ };
54
+ };
55
+ var retry = async (callback, options = {}) => {
56
+ let iterations = 0;
57
+ const { shouldRetry, initialDelay, maxDelayBetweenRetries, factor, retryImmediately, jitter } = {
58
+ ...defaultOptions,
59
+ ...options
60
+ };
61
+ const delay = createExponentialDelayAsyncFn({
62
+ initialDelay,
63
+ maxDelayBetweenRetries,
64
+ factor,
65
+ jitter
66
+ });
67
+ while (true) {
68
+ try {
69
+ return await callback();
70
+ } catch (e) {
71
+ iterations++;
72
+ if (!shouldRetry(e, iterations)) {
73
+ throw e;
74
+ }
75
+ if (retryImmediately && iterations === 1) {
76
+ await sleep(applyJitter(RETRY_IMMEDIATELY_DELAY, jitter));
77
+ } else {
78
+ await delay();
79
+ }
80
+ }
81
+ }
82
+ };
83
+
84
+ // src/loadScript.ts
26
85
  async function loadScript(src = "", options) {
27
86
  const { async, defer, crossOrigin, nonce, beforeLoad } = options;
28
87
  const load = () => {
@@ -49,7 +108,6 @@ async function loadScript(src = "", options) {
49
108
  };
50
109
  const handleLoad = () => {
51
110
  if (resolved) return;
52
- console.log(`[loadScript] Script loaded successfully: ${src}`);
53
111
  resolved = true;
54
112
  cleanup();
55
113
  resolve(script);
@@ -59,19 +117,23 @@ async function loadScript(src = "", options) {
59
117
  resolved = true;
60
118
  cleanup();
61
119
  script.remove();
62
- console.error(`[loadScript] Failed to load script: ${src}`, error);
63
120
  reject(new Error(`Failed to load script: ${src}, Error: ${error.message}`));
64
121
  };
65
- script.addEventListener("load", handleLoad);
66
- script.addEventListener("error", handleError);
122
+ script.addEventListener("load", () => {
123
+ script.remove();
124
+ resolve(script);
125
+ });
126
+ script.addEventListener("error", () => {
127
+ script.remove();
128
+ reject();
129
+ });
67
130
  script.src = src;
68
131
  script.nonce = nonce;
69
132
  beforeLoad == null ? void 0 : beforeLoad(script);
70
- console.log(`[loadScript] Appending script to document body: ${src}`);
71
133
  document.body.appendChild(script);
72
134
  });
73
135
  };
74
- return load();
136
+ return retry(load, { shouldRetry: (_, iterations) => iterations <= 5 });
75
137
  }
76
138
  // Annotate the CommonJS export names for ESM import in node:
77
139
  0 && (module.exports = {