@tern-secure/shared 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunk-HATJQ74R.mjs +56 -0
- package/dist/chunk-HATJQ74R.mjs.map +1 -0
- package/dist/derivedAuthState.d.mts +9 -0
- package/dist/derivedAuthState.d.ts +9 -0
- package/dist/derivedAuthState.js +75 -0
- package/dist/derivedAuthState.js.map +1 -0
- package/dist/derivedAuthState.mjs +49 -0
- package/dist/derivedAuthState.mjs.map +1 -0
- package/dist/eventBus.d.mts +8 -0
- package/dist/eventBus.d.ts +8 -0
- package/dist/eventBus.js +54 -0
- package/dist/eventBus.js.map +1 -0
- package/dist/eventBus.mjs +29 -0
- package/dist/eventBus.mjs.map +1 -0
- package/dist/loadScript.d.mts +10 -0
- package/dist/loadScript.d.ts +10 -0
- package/dist/loadScript.js +80 -0
- package/dist/loadScript.js.map +1 -0
- package/dist/loadScript.mjs +7 -0
- package/dist/loadScript.mjs.map +1 -0
- package/dist/loadTernUIScript.d.mts +24 -0
- package/dist/loadTernUIScript.d.ts +24 -0
- package/dist/loadTernUIScript.js +140 -0
- package/dist/loadTernUIScript.js.map +1 -0
- package/dist/loadTernUIScript.mjs +63 -0
- package/dist/loadTernUIScript.mjs.map +1 -0
- package/dist/react/index.d.mts +54 -0
- package/dist/react/index.d.ts +54 -0
- package/dist/react/index.js +116 -0
- package/dist/react/index.js.map +1 -0
- package/dist/react/index.mjs +68 -0
- package/dist/react/index.mjs.map +1 -0
- package/dist/retry.d.mts +46 -0
- package/dist/retry.d.ts +46 -0
- package/dist/retry.js +85 -0
- package/dist/retry.js.map +1 -0
- package/dist/retry.mjs +60 -0
- package/dist/retry.mjs.map +1 -0
- package/dist/types/derivedAuthState.d.ts +7 -0
- package/dist/types/derivedAuthState.d.ts.map +1 -0
- package/dist/types/eventBus.d.ts +7 -0
- package/dist/types/eventBus.d.ts.map +1 -0
- package/dist/types/loadScript.d.ts +10 -0
- package/dist/types/loadScript.d.ts.map +1 -0
- package/dist/types/loadTernUIScript.d.ts +22 -0
- package/dist/types/loadTernUIScript.d.ts.map +1 -0
- package/dist/types/nextjs/client/auth-actions.d.ts +1 -0
- package/dist/types/nextjs/client/auth-actions.d.ts.map +1 -0
- package/dist/types/react/hooks/index.d.ts +2 -0
- package/dist/types/react/hooks/index.d.ts.map +1 -0
- package/dist/types/react/hooks/useTernSecure.d.ts +3 -0
- package/dist/types/react/hooks/useTernSecure.d.ts.map +1 -0
- package/dist/types/react/index.d.ts +4 -0
- package/dist/types/react/index.d.ts.map +1 -0
- package/dist/types/react/ternsecureCtx.d.ts +26 -0
- package/dist/types/react/ternsecureCtx.d.ts.map +1 -0
- package/dist/types/react/ternsecureProvider.d.ts +20 -0
- package/dist/types/react/ternsecureProvider.d.ts.map +1 -0
- package/dist/types/retry.d.ts +46 -0
- package/dist/types/retry.d.ts.map +1 -0
- package/package.json +88 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/loadTernUIScript.ts","../src/loadScript.ts"],"sourcesContent":["import type { TernSecureInstanceTreeOptions } from \"@tern-secure/types\";\nimport { loadScript } from \"./loadScript\";\n\n\nexport type LoadTernUISCriptOptions = TernSecureInstanceTreeOptions & {\n apiKey?: string;\n customDomain?: string;\n proxyUrl?: string;\n version?: string;\n isLocalDev?: boolean;\n scriptHost?: string;\n localPort?: string;\n nonce?: string;\n}\n\nexport const loadTernUIScript = async (options?: LoadTernUISCriptOptions) => {\n const existingScript = document.querySelector<HTMLScriptElement>('script[data-ternui-script]');\n console.log('[TernSecure-shared] Existing script:', existingScript);\n\n if (existingScript) {\n return new Promise((resolve, reject) => {\n existingScript.addEventListener('load', () => {\n resolve(existingScript);\n });\n\n existingScript.addEventListener('error', (error) => {\n reject(error);\n });\n });\n }\n\n if (!options?.customDomain) {\n throw new Error('TernUI script requires a custom domain or proxy URL to be specified in options.');\n }\n \n return loadScript(ternUIgetScriptUrl(options), {\n async: true,\n //crossOrigin: undefined,\n beforeLoad: beforeLoadWithOptions(options)\n }).catch((error) => {\n console.error('[TernSecure] Failed to load TernUI script:', error);\n throw new Error('Failed to load TernUI script');\n });\n }\n\nexport const ternUIgetScriptUrl = (options?: LoadTernUISCriptOptions) => {\n const isDevelopment = process.env.NODE_ENV === 'development';\n const version = options?.version || process.env.TERN_UI_VERSION || 'latest';\n\n if ( isDevelopment) {\n const localHost = process.env.TERN_UI_HOST || 'localhost';\n const localPort = options?.localPort || process.env.TERN_UI_PORT || '4000';\n return `http://${localHost}:${localPort}/ternsecure.browser.js`;\n //return `http://cdn.lifesprintcare.ca/dist/ternsecure.browser.js`\n }\n return `http://cdn.lifesprintcare.ca/dist/ternsecure.browser.js`\n\n //const ternsecureCDN = options?.customDomain || \n //(options?.proxyUrl && new URL(options.proxyUrl).host) || 'cdn.tern-secure.com';\n //return `${ternsecureCDN}/ternsecure.browser.js`;\n //return `https://${ternsecureCDN}/npm/@ternsecure/tern-ui@${version}/dist/ternsecure.browser.js`;\n\n}\n\n \nconst beforeLoadWithOptions = (options?: LoadTernUISCriptOptions) => (script: HTMLScriptElement) => {\n const attributes = constructScriptAttributes(options);\n Object.entries(attributes).forEach(([key, value]) => {\n if (value) script.setAttribute(key, String(value));\n });\n console.log('[TernSecure-shared] Script attributes set:', attributes);\n};\n\nexport const constructScriptAttributes = (options?: LoadTernUISCriptOptions) => {\n return {\n 'data-domain': options?.customDomain || '',\n 'data-apikey': options?.apiKey || '',\n 'data-environment': process.env.NODE_ENV || 'development',\n 'data-proxyUrl': options?.proxyUrl || '',\n 'data-version': options?.version || process.env.TERN_UI_VERSION || 'latest',\n ...(options?.nonce ? { nonce: options.nonce } : {})\n };\n};"," import { retry } from './retry'\n\n type LoadScriptOptions = {\n async?: boolean;\n defer?: boolean;\n crossOrigin?: 'anonymous' | 'use-credentials';\n nonce?: string;\n beforeLoad?: (script: HTMLScriptElement) => void;\n };\n\n export 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 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 const handleLoad = () => {\n if (resolved) return;\n console.log(`[loadScript] Script loaded successfully: ${src}`);\n\n resolved = true;\n cleanup();\n resolve(script);\n };\n \n const handleError = (error: ErrorEvent) => {\n if (resolved) return;\n resolved = true;\n cleanup();\n script.remove();\n console.error(`[loadScript] Failed to load script: ${src}`, error);\n reject(new Error(`Failed to load script: ${src}, Error: ${error.message || error}`));\n };\n \n script.addEventListener('load', handleLoad);\n script.addEventListener('error', handleError);\n\n script.src = src;\n script.nonce = nonce;\n beforeLoad?.(script);\n\n console.log(`[loadScript] Appending script to document body: ${src}`);\n document.body.appendChild(script)\n });\n };\n\n return load()\n\n //return retry(load, { shouldRetry: (_, iterations) => iterations <=5 });\n }"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import {
|
|
2
|
+
loadScript
|
|
3
|
+
} from "./chunk-HATJQ74R.mjs";
|
|
4
|
+
|
|
5
|
+
// src/loadTernUIScript.ts
|
|
6
|
+
var loadTernUIScript = async (options) => {
|
|
7
|
+
const existingScript = document.querySelector("script[data-ternui-script]");
|
|
8
|
+
console.log("[TernSecure-shared] Existing script:", existingScript);
|
|
9
|
+
if (existingScript) {
|
|
10
|
+
return new Promise((resolve, reject) => {
|
|
11
|
+
existingScript.addEventListener("load", () => {
|
|
12
|
+
resolve(existingScript);
|
|
13
|
+
});
|
|
14
|
+
existingScript.addEventListener("error", (error) => {
|
|
15
|
+
reject(error);
|
|
16
|
+
});
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
if (!(options == null ? void 0 : options.customDomain)) {
|
|
20
|
+
throw new Error("TernUI script requires a custom domain or proxy URL to be specified in options.");
|
|
21
|
+
}
|
|
22
|
+
return loadScript(ternUIgetScriptUrl(options), {
|
|
23
|
+
async: true,
|
|
24
|
+
//crossOrigin: undefined,
|
|
25
|
+
beforeLoad: beforeLoadWithOptions(options)
|
|
26
|
+
}).catch((error) => {
|
|
27
|
+
console.error("[TernSecure] Failed to load TernUI script:", error);
|
|
28
|
+
throw new Error("Failed to load TernUI script");
|
|
29
|
+
});
|
|
30
|
+
};
|
|
31
|
+
var ternUIgetScriptUrl = (options) => {
|
|
32
|
+
const isDevelopment = process.env.NODE_ENV === "development";
|
|
33
|
+
const version = (options == null ? void 0 : options.version) || process.env.TERN_UI_VERSION || "latest";
|
|
34
|
+
if (isDevelopment) {
|
|
35
|
+
const localHost = process.env.TERN_UI_HOST || "localhost";
|
|
36
|
+
const localPort = (options == null ? void 0 : options.localPort) || process.env.TERN_UI_PORT || "4000";
|
|
37
|
+
return `http://${localHost}:${localPort}/ternsecure.browser.js`;
|
|
38
|
+
}
|
|
39
|
+
return `http://cdn.lifesprintcare.ca/dist/ternsecure.browser.js`;
|
|
40
|
+
};
|
|
41
|
+
var beforeLoadWithOptions = (options) => (script) => {
|
|
42
|
+
const attributes = constructScriptAttributes(options);
|
|
43
|
+
Object.entries(attributes).forEach(([key, value]) => {
|
|
44
|
+
if (value) script.setAttribute(key, String(value));
|
|
45
|
+
});
|
|
46
|
+
console.log("[TernSecure-shared] Script attributes set:", attributes);
|
|
47
|
+
};
|
|
48
|
+
var constructScriptAttributes = (options) => {
|
|
49
|
+
return {
|
|
50
|
+
"data-domain": (options == null ? void 0 : options.customDomain) || "",
|
|
51
|
+
"data-apikey": (options == null ? void 0 : options.apiKey) || "",
|
|
52
|
+
"data-environment": process.env.NODE_ENV || "development",
|
|
53
|
+
"data-proxyUrl": (options == null ? void 0 : options.proxyUrl) || "",
|
|
54
|
+
"data-version": (options == null ? void 0 : options.version) || process.env.TERN_UI_VERSION || "latest",
|
|
55
|
+
...(options == null ? void 0 : options.nonce) ? { nonce: options.nonce } : {}
|
|
56
|
+
};
|
|
57
|
+
};
|
|
58
|
+
export {
|
|
59
|
+
constructScriptAttributes,
|
|
60
|
+
loadTernUIScript,
|
|
61
|
+
ternUIgetScriptUrl
|
|
62
|
+
};
|
|
63
|
+
//# sourceMappingURL=loadTernUIScript.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/loadTernUIScript.ts"],"sourcesContent":["import type { TernSecureInstanceTreeOptions } from \"@tern-secure/types\";\nimport { loadScript } from \"./loadScript\";\n\n\nexport type LoadTernUISCriptOptions = TernSecureInstanceTreeOptions & {\n apiKey?: string;\n customDomain?: string;\n proxyUrl?: string;\n version?: string;\n isLocalDev?: boolean;\n scriptHost?: string;\n localPort?: string;\n nonce?: string;\n}\n\nexport const loadTernUIScript = async (options?: LoadTernUISCriptOptions) => {\n const existingScript = document.querySelector<HTMLScriptElement>('script[data-ternui-script]');\n console.log('[TernSecure-shared] Existing script:', existingScript);\n\n if (existingScript) {\n return new Promise((resolve, reject) => {\n existingScript.addEventListener('load', () => {\n resolve(existingScript);\n });\n\n existingScript.addEventListener('error', (error) => {\n reject(error);\n });\n });\n }\n\n if (!options?.customDomain) {\n throw new Error('TernUI script requires a custom domain or proxy URL to be specified in options.');\n }\n \n return loadScript(ternUIgetScriptUrl(options), {\n async: true,\n //crossOrigin: undefined,\n beforeLoad: beforeLoadWithOptions(options)\n }).catch((error) => {\n console.error('[TernSecure] Failed to load TernUI script:', error);\n throw new Error('Failed to load TernUI script');\n });\n }\n\nexport const ternUIgetScriptUrl = (options?: LoadTernUISCriptOptions) => {\n const isDevelopment = process.env.NODE_ENV === 'development';\n const version = options?.version || process.env.TERN_UI_VERSION || 'latest';\n\n if ( isDevelopment) {\n const localHost = process.env.TERN_UI_HOST || 'localhost';\n const localPort = options?.localPort || process.env.TERN_UI_PORT || '4000';\n return `http://${localHost}:${localPort}/ternsecure.browser.js`;\n //return `http://cdn.lifesprintcare.ca/dist/ternsecure.browser.js`\n }\n return `http://cdn.lifesprintcare.ca/dist/ternsecure.browser.js`\n\n //const ternsecureCDN = options?.customDomain || \n //(options?.proxyUrl && new URL(options.proxyUrl).host) || 'cdn.tern-secure.com';\n //return `${ternsecureCDN}/ternsecure.browser.js`;\n //return `https://${ternsecureCDN}/npm/@ternsecure/tern-ui@${version}/dist/ternsecure.browser.js`;\n\n}\n\n \nconst beforeLoadWithOptions = (options?: LoadTernUISCriptOptions) => (script: HTMLScriptElement) => {\n const attributes = constructScriptAttributes(options);\n Object.entries(attributes).forEach(([key, value]) => {\n if (value) script.setAttribute(key, String(value));\n });\n console.log('[TernSecure-shared] Script attributes set:', attributes);\n};\n\nexport const constructScriptAttributes = (options?: LoadTernUISCriptOptions) => {\n return {\n 'data-domain': options?.customDomain || '',\n 'data-apikey': options?.apiKey || '',\n 'data-environment': process.env.NODE_ENV || 'development',\n 'data-proxyUrl': options?.proxyUrl || '',\n 'data-version': options?.version || process.env.TERN_UI_VERSION || 'latest',\n ...(options?.nonce ? { nonce: options.nonce } : {})\n };\n};"],"mappings":";;;;;AAeO,IAAM,mBAAmB,OAAO,YAAsC;AAC3E,QAAM,iBAAkB,SAAS,cAAiC,4BAA4B;AAC9F,UAAQ,IAAI,wCAAwC,cAAc;AAElE,MAAI,gBAAgB;AAClB,WAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,qBAAe,iBAAiB,QAAQ,MAAM;AAC5C,gBAAQ,cAAc;AAAA,MACxB,CAAC;AAED,qBAAe,iBAAiB,SAAS,CAAC,UAAU;AAClD,eAAO,KAAK;AAAA,MACd,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAEA,MAAI,EAAC,mCAAS,eAAc;AAC1B,UAAM,IAAI,MAAM,iFAAiF;AAAA,EACnG;AAEA,SAAO,WAAW,mBAAmB,OAAO,GAAG;AAAA,IAC7C,OAAO;AAAA;AAAA,IAEN,YAAY,sBAAsB,OAAO;AAAA,EAC1C,CAAC,EAAE,MAAM,CAAC,UAAU;AAClB,YAAQ,MAAM,8CAA8C,KAAK;AACjE,UAAM,IAAI,MAAM,8BAA8B;AAAA,EAChD,CAAC;AACH;AAEK,IAAM,qBAAqB,CAAC,YAAsC;AACrE,QAAM,gBAAgB,QAAQ,IAAI,aAAa;AAC/C,QAAM,WAAU,mCAAS,YAAW,QAAQ,IAAI,mBAAmB;AAEnE,MAAK,eAAe;AAChB,UAAM,YAAY,QAAQ,IAAI,gBAAgB;AAC9C,UAAM,aAAY,mCAAS,cAAa,QAAQ,IAAI,gBAAgB;AACpE,WAAO,UAAU,SAAS,IAAI,SAAS;AAAA,EAE3C;AACA,SAAO;AAOX;AAGA,IAAM,wBAAwB,CAAC,YAAsC,CAAC,WAA8B;AAClG,QAAM,aAAa,0BAA0B,OAAO;AACpD,SAAO,QAAQ,UAAU,EAAE,QAAQ,CAAC,CAAC,KAAK,KAAK,MAAM;AACnD,QAAI,MAAO,QAAO,aAAa,KAAK,OAAO,KAAK,CAAC;AAAA,EACnD,CAAC;AACD,UAAQ,IAAI,8CAA8C,UAAU;AACtE;AAEO,IAAM,4BAA4B,CAAC,YAAsC;AAC9E,SAAO;AAAA,IACL,gBAAe,mCAAS,iBAAgB;AAAA,IACxC,gBAAe,mCAAS,WAAU;AAAA,IAClC,oBAAoB,QAAQ,IAAI,YAAY;AAAA,IAC5C,kBAAiB,mCAAS,aAAY;AAAA,IACtC,iBAAgB,mCAAS,YAAW,QAAQ,IAAI,mBAAmB;AAAA,IACnE,IAAI,mCAAS,SAAQ,EAAE,OAAO,QAAQ,MAAM,IAAI,CAAC;AAAA,EACnD;AACF;","names":[]}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import * as _tern_secure_types from '@tern-secure/types';
|
|
2
|
+
import { TernSecureInstanceTree, TernSecureAuthProvider, TernSecureState } from '@tern-secure/types';
|
|
3
|
+
import * as react from 'react';
|
|
4
|
+
import react__default from 'react';
|
|
5
|
+
|
|
6
|
+
declare const useTernSecure: () => TernSecureInstanceTree;
|
|
7
|
+
|
|
8
|
+
type TernSecureAuthContextType = {
|
|
9
|
+
authProvider: TernSecureAuthProvider | null | undefined;
|
|
10
|
+
authState: TernSecureState;
|
|
11
|
+
};
|
|
12
|
+
declare const TernSecureInstanceContext: react.Context<{
|
|
13
|
+
value: TernSecureInstanceTree;
|
|
14
|
+
} | undefined>;
|
|
15
|
+
declare const useTernSecureInstanceContext: () => TernSecureInstanceTree;
|
|
16
|
+
declare const TernSecureAuthContext: react.Context<{
|
|
17
|
+
value: TernSecureAuthContextType;
|
|
18
|
+
} | undefined>;
|
|
19
|
+
declare const useTernSecureAuthContext: () => TernSecureAuthContextType;
|
|
20
|
+
declare const SessionContext: react.Context<{
|
|
21
|
+
value: _tern_secure_types.SignedInSession | null;
|
|
22
|
+
} | undefined>;
|
|
23
|
+
declare const useSessionContext: () => _tern_secure_types.SignedInSession | null;
|
|
24
|
+
declare const UserContext: react.Context<{
|
|
25
|
+
value: _tern_secure_types.TernSecureUser | null;
|
|
26
|
+
} | undefined>;
|
|
27
|
+
declare const useUserContext: () => _tern_secure_types.TernSecureUser | null;
|
|
28
|
+
declare function useAssertWrappedByTernSecureProvider(displayNameOrFn: string | (() => void)): void;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Assert that the context value exists, otherwise throw an error.
|
|
32
|
+
*
|
|
33
|
+
* @internal
|
|
34
|
+
*/
|
|
35
|
+
declare function assertContextExists(contextVal: unknown, msgOrCtx: string | react__default.Context<any>): asserts contextVal;
|
|
36
|
+
type Options = {
|
|
37
|
+
assertCtxFn?: (v: unknown, msg: string) => void;
|
|
38
|
+
};
|
|
39
|
+
type ContextAndHook<T> = react__default.Context<{
|
|
40
|
+
value: T;
|
|
41
|
+
} | undefined>;
|
|
42
|
+
type UseCtxFn<T> = () => T;
|
|
43
|
+
/**
|
|
44
|
+
* Create and return a Context and two hooks that return the context value.
|
|
45
|
+
* The Context type is derived from the type passed in by the user.
|
|
46
|
+
*
|
|
47
|
+
* The first hook returned guarantees that the context exists so the returned value is always `CtxValue`
|
|
48
|
+
* The second hook makes no guarantees, so the returned value can be `CtxValue | undefined`
|
|
49
|
+
*
|
|
50
|
+
* @internal
|
|
51
|
+
*/
|
|
52
|
+
declare const createContextAndHook: <CtxValue>(displayName: string, options?: Options) => [ContextAndHook<CtxValue>, UseCtxFn<CtxValue>, UseCtxFn<CtxValue | Partial<CtxValue>>];
|
|
53
|
+
|
|
54
|
+
export { SessionContext, TernSecureAuthContext, TernSecureInstanceContext, UserContext, assertContextExists, createContextAndHook, useAssertWrappedByTernSecureProvider, useSessionContext, useTernSecure, useTernSecureAuthContext, useTernSecureInstanceContext, useUserContext };
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import * as _tern_secure_types from '@tern-secure/types';
|
|
2
|
+
import { TernSecureInstanceTree, TernSecureAuthProvider, TernSecureState } from '@tern-secure/types';
|
|
3
|
+
import * as react from 'react';
|
|
4
|
+
import react__default from 'react';
|
|
5
|
+
|
|
6
|
+
declare const useTernSecure: () => TernSecureInstanceTree;
|
|
7
|
+
|
|
8
|
+
type TernSecureAuthContextType = {
|
|
9
|
+
authProvider: TernSecureAuthProvider | null | undefined;
|
|
10
|
+
authState: TernSecureState;
|
|
11
|
+
};
|
|
12
|
+
declare const TernSecureInstanceContext: react.Context<{
|
|
13
|
+
value: TernSecureInstanceTree;
|
|
14
|
+
} | undefined>;
|
|
15
|
+
declare const useTernSecureInstanceContext: () => TernSecureInstanceTree;
|
|
16
|
+
declare const TernSecureAuthContext: react.Context<{
|
|
17
|
+
value: TernSecureAuthContextType;
|
|
18
|
+
} | undefined>;
|
|
19
|
+
declare const useTernSecureAuthContext: () => TernSecureAuthContextType;
|
|
20
|
+
declare const SessionContext: react.Context<{
|
|
21
|
+
value: _tern_secure_types.SignedInSession | null;
|
|
22
|
+
} | undefined>;
|
|
23
|
+
declare const useSessionContext: () => _tern_secure_types.SignedInSession | null;
|
|
24
|
+
declare const UserContext: react.Context<{
|
|
25
|
+
value: _tern_secure_types.TernSecureUser | null;
|
|
26
|
+
} | undefined>;
|
|
27
|
+
declare const useUserContext: () => _tern_secure_types.TernSecureUser | null;
|
|
28
|
+
declare function useAssertWrappedByTernSecureProvider(displayNameOrFn: string | (() => void)): void;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Assert that the context value exists, otherwise throw an error.
|
|
32
|
+
*
|
|
33
|
+
* @internal
|
|
34
|
+
*/
|
|
35
|
+
declare function assertContextExists(contextVal: unknown, msgOrCtx: string | react__default.Context<any>): asserts contextVal;
|
|
36
|
+
type Options = {
|
|
37
|
+
assertCtxFn?: (v: unknown, msg: string) => void;
|
|
38
|
+
};
|
|
39
|
+
type ContextAndHook<T> = react__default.Context<{
|
|
40
|
+
value: T;
|
|
41
|
+
} | undefined>;
|
|
42
|
+
type UseCtxFn<T> = () => T;
|
|
43
|
+
/**
|
|
44
|
+
* Create and return a Context and two hooks that return the context value.
|
|
45
|
+
* The Context type is derived from the type passed in by the user.
|
|
46
|
+
*
|
|
47
|
+
* The first hook returned guarantees that the context exists so the returned value is always `CtxValue`
|
|
48
|
+
* The second hook makes no guarantees, so the returned value can be `CtxValue | undefined`
|
|
49
|
+
*
|
|
50
|
+
* @internal
|
|
51
|
+
*/
|
|
52
|
+
declare const createContextAndHook: <CtxValue>(displayName: string, options?: Options) => [ContextAndHook<CtxValue>, UseCtxFn<CtxValue>, UseCtxFn<CtxValue | Partial<CtxValue>>];
|
|
53
|
+
|
|
54
|
+
export { SessionContext, TernSecureAuthContext, TernSecureInstanceContext, UserContext, assertContextExists, createContextAndHook, useAssertWrappedByTernSecureProvider, useSessionContext, useTernSecure, useTernSecureAuthContext, useTernSecureInstanceContext, useUserContext };
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/react/index.ts
|
|
31
|
+
var react_exports = {};
|
|
32
|
+
__export(react_exports, {
|
|
33
|
+
SessionContext: () => SessionContext,
|
|
34
|
+
TernSecureAuthContext: () => TernSecureAuthContext,
|
|
35
|
+
TernSecureInstanceContext: () => TernSecureInstanceContext,
|
|
36
|
+
UserContext: () => UserContext,
|
|
37
|
+
assertContextExists: () => assertContextExists,
|
|
38
|
+
createContextAndHook: () => createContextAndHook,
|
|
39
|
+
useAssertWrappedByTernSecureProvider: () => useAssertWrappedByTernSecureProvider,
|
|
40
|
+
useSessionContext: () => useSessionContext,
|
|
41
|
+
useTernSecure: () => useTernSecure,
|
|
42
|
+
useTernSecureAuthContext: () => useTernSecureAuthContext,
|
|
43
|
+
useTernSecureInstanceContext: () => useTernSecureInstanceContext,
|
|
44
|
+
useUserContext: () => useUserContext
|
|
45
|
+
});
|
|
46
|
+
module.exports = __toCommonJS(react_exports);
|
|
47
|
+
|
|
48
|
+
// src/react/ternsecureProvider.tsx
|
|
49
|
+
var import_react2 = require("react");
|
|
50
|
+
|
|
51
|
+
// src/react/ternsecureCtx.ts
|
|
52
|
+
var import_react = __toESM(require("react"));
|
|
53
|
+
function assertContextExists(contextVal, msgOrCtx) {
|
|
54
|
+
if (!contextVal) {
|
|
55
|
+
throw typeof msgOrCtx === "string" ? new Error(msgOrCtx) : new Error(`${msgOrCtx.displayName} not found`);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
var createContextAndHook = (displayName, options) => {
|
|
59
|
+
const { assertCtxFn = assertContextExists } = options || {};
|
|
60
|
+
const Ctx = import_react.default.createContext(void 0);
|
|
61
|
+
Ctx.displayName = displayName;
|
|
62
|
+
const useCtx = () => {
|
|
63
|
+
const ctx = import_react.default.useContext(Ctx);
|
|
64
|
+
assertCtxFn(ctx, `${displayName} not found`);
|
|
65
|
+
return ctx.value;
|
|
66
|
+
};
|
|
67
|
+
const useCtxWithoutGuarantee = () => {
|
|
68
|
+
const ctx = import_react.default.useContext(Ctx);
|
|
69
|
+
return ctx ? ctx.value : {};
|
|
70
|
+
};
|
|
71
|
+
return [Ctx, useCtx, useCtxWithoutGuarantee];
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
// src/react/ternsecureProvider.tsx
|
|
75
|
+
var [TernSecureInstanceContext, useTernSecureInstanceContext] = createContextAndHook("TernSecureInstanceContext");
|
|
76
|
+
var [TernSecureAuthContext, useTernSecureAuthContext] = createContextAndHook("TernSecureAuthContext");
|
|
77
|
+
var [SessionContext, useSessionContext] = createContextAndHook("SessionContext");
|
|
78
|
+
var [UserContext, useUserContext] = createContextAndHook("UserContext");
|
|
79
|
+
function useAssertWrappedByTernSecureProvider(displayNameOrFn) {
|
|
80
|
+
const ctx = (0, import_react2.useContext)(TernSecureInstanceContext);
|
|
81
|
+
if (!ctx) {
|
|
82
|
+
if (typeof displayNameOrFn === "function") {
|
|
83
|
+
displayNameOrFn();
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
throw new Error(
|
|
87
|
+
`${displayNameOrFn} can only be used within the <TernSecureProvider /> component.
|
|
88
|
+
|
|
89
|
+
Possible fixes:
|
|
90
|
+
1. Ensure that the <TernSecureProvider /> is correctly wrapping your application
|
|
91
|
+
2. Check for multiple versions of @tern-secure packages in your project`
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// src/react/hooks/useTernSecure.ts
|
|
97
|
+
var useTernSecure = () => {
|
|
98
|
+
useAssertWrappedByTernSecureProvider("useTernSecure");
|
|
99
|
+
return useTernSecureInstanceContext();
|
|
100
|
+
};
|
|
101
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
102
|
+
0 && (module.exports = {
|
|
103
|
+
SessionContext,
|
|
104
|
+
TernSecureAuthContext,
|
|
105
|
+
TernSecureInstanceContext,
|
|
106
|
+
UserContext,
|
|
107
|
+
assertContextExists,
|
|
108
|
+
createContextAndHook,
|
|
109
|
+
useAssertWrappedByTernSecureProvider,
|
|
110
|
+
useSessionContext,
|
|
111
|
+
useTernSecure,
|
|
112
|
+
useTernSecureAuthContext,
|
|
113
|
+
useTernSecureInstanceContext,
|
|
114
|
+
useUserContext
|
|
115
|
+
});
|
|
116
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/react/index.ts","../../src/react/ternsecureProvider.tsx","../../src/react/ternsecureCtx.ts","../../src/react/hooks/useTernSecure.ts"],"sourcesContent":["export * from './hooks'\n\nexport {\n useAssertWrappedByTernSecureProvider,\n useTernSecureInstanceContext,\n useTernSecureAuthContext,\n useSessionContext,\n useUserContext,\n SessionContext,\n UserContext,\n TernSecureAuthContext,\n TernSecureInstanceContext\n} from './ternsecureProvider'\n\nexport {\n assertContextExists,\n createContextAndHook\n} from './ternsecureCtx'","'use client'\n\nimport { useContext } from 'react';\nimport type { \n TernSecureAuthProvider,\n TernSecureInstanceTree,\n TernSecureState,\n} from '@tern-secure/types';\nimport { createContextAndHook } from './ternsecureCtx';\n\nexport type TernSecureAuthContextType = {\n authProvider: TernSecureAuthProvider | null | undefined;\n authState: TernSecureState;\n}\n\n\n// Create TernSecure instance context\nconst [TernSecureInstanceContext, useTernSecureInstanceContext] = \n createContextAndHook<TernSecureInstanceTree>('TernSecureInstanceContext');\n\nconst [TernSecureAuthContext, useTernSecureAuthContext] =\n createContextAndHook<TernSecureAuthContextType>('TernSecureAuthContext');\n\nconst [SessionContext, useSessionContext] = \ncreateContextAndHook<TernSecureInstanceTree['auth']['session']>('SessionContext');\n\nconst [UserContext, useUserContext] = \ncreateContextAndHook<TernSecureInstanceTree['auth']['user']>('UserContext');\n\n// Assert helper\nfunction useAssertWrappedByTernSecureProvider(displayNameOrFn: string | (() => void)): void {\n //const ctx = useTernSecureInstanceContext();\n const ctx = useContext(TernSecureInstanceContext);\n \n if (!ctx) {\n if (typeof displayNameOrFn === 'function') {\n displayNameOrFn();\n return;\n }\n\n throw new Error(\n `${displayNameOrFn} can only be used within the <TernSecureProvider /> component.\n \nPossible fixes:\n1. Ensure that the <TernSecureProvider /> is correctly wrapping your application\n2. Check for multiple versions of @tern-secure packages in your project`\n );\n }\n}\n\n\nexport {\n TernSecureInstanceContext,\n TernSecureAuthContext,\n SessionContext,\n UserContext,\n useTernSecureAuthContext,\n useSessionContext,\n useUserContext,\n useTernSecureInstanceContext,\n useAssertWrappedByTernSecureProvider\n};","'use client'\n\nimport React from 'react';\n\n/**\n * Assert that the context value exists, otherwise throw an error.\n *\n * @internal\n */\nexport function assertContextExists(contextVal: unknown, msgOrCtx: string | React.Context<any>): asserts contextVal {\n if (!contextVal) {\n throw typeof msgOrCtx === 'string' ? new Error(msgOrCtx) : new Error(`${msgOrCtx.displayName} not found`);\n }\n}\ntype Options = { assertCtxFn?: (v: unknown, msg: string) => void };\ntype ContextAndHook<T> = React.Context<{ value: T } | undefined>;\ntype UseCtxFn<T> = () => T;\n\n/**\n * Create and return a Context and two hooks that return the context value.\n * The Context type is derived from the type passed in by the user.\n *\n * The first hook returned guarantees that the context exists so the returned value is always `CtxValue`\n * The second hook makes no guarantees, so the returned value can be `CtxValue | undefined`\n *\n * @internal\n */\n\nexport const createContextAndHook = <CtxValue>(\n displayName: string,\n options?: Options,\n): [ContextAndHook<CtxValue>, UseCtxFn<CtxValue>, UseCtxFn<CtxValue | Partial<CtxValue>>] => {\n const { assertCtxFn = assertContextExists } = options || {};\n const Ctx = React.createContext<{ value: CtxValue } | undefined >(undefined);\n Ctx.displayName = displayName;\n\n const useCtx = () => {\n const ctx = React.useContext(Ctx);\n assertCtxFn(ctx, `${displayName} not found`);\n return (ctx as any).value as CtxValue;\n };\n\n const useCtxWithoutGuarantee = () => {\n const ctx = React.useContext(Ctx);\n return ctx ? ctx.value : {}\n };\n\n /**\n * Assert that the context value exists, otherwise throw an error.\n if (ctx === undefined) {\n throw new Error(`use${name} must be used within a ${name}Provider`);\n }\n return ctx.value;\n */\n\n return [Ctx, useCtx, useCtxWithoutGuarantee];\n}","import type { \n TernSecureInstanceTree\n} from \"@tern-secure/types\";\nimport { \n useAssertWrappedByTernSecureProvider, \n useTernSecureInstanceContext \n} from \"../ternsecureProvider\";\n\nexport const useTernSecure = (): TernSecureInstanceTree => {\n /**\n * if no assertion is needed, you can use the following:\n * const instance = useTernSecureInstanceContext();\n * if (!instance) {\n * throw new Error('useTernSecure must be used within a TernSecureProvider');\n * }\n * return instance;\n */\n \n useAssertWrappedByTernSecureProvider('useTernSecure');\n return useTernSecureInstanceContext();\n}"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACEA,IAAAA,gBAA2B;;;ACA3B,mBAAkB;AAOX,SAAS,oBAAoB,YAAqB,UAA2D;AAClH,MAAI,CAAC,YAAY;AACf,UAAM,OAAO,aAAa,WAAW,IAAI,MAAM,QAAQ,IAAI,IAAI,MAAM,GAAG,SAAS,WAAW,YAAY;AAAA,EAC1G;AACF;AAeO,IAAM,uBAAuB,CAClC,aACA,YAC2F;AAC3F,QAAM,EAAE,cAAc,oBAAoB,IAAI,WAAW,CAAC;AAC1D,QAAM,MAAM,aAAAC,QAAM,cAAgD,MAAS;AAC3E,MAAI,cAAc;AAElB,QAAM,SAAS,MAAM;AACnB,UAAM,MAAM,aAAAA,QAAM,WAAW,GAAG;AAChC,gBAAY,KAAK,GAAG,WAAW,YAAY;AAC3C,WAAQ,IAAY;AAAA,EACtB;AAEA,QAAM,yBAAyB,MAAM;AACnC,UAAM,MAAM,aAAAA,QAAM,WAAW,GAAG;AAChC,WAAO,MAAM,IAAI,QAAQ,CAAC;AAAA,EAC5B;AAUA,SAAO,CAAC,KAAK,QAAQ,sBAAsB;AAC7C;;;ADvCA,IAAM,CAAC,2BAA2B,4BAA4B,IAC5D,qBAA6C,2BAA2B;AAE1E,IAAM,CAAC,uBAAuB,wBAAwB,IACpD,qBAAgD,uBAAuB;AAEzE,IAAM,CAAC,gBAAgB,iBAAiB,IACxC,qBAAgE,gBAAgB;AAEhF,IAAM,CAAC,aAAa,cAAc,IAClC,qBAA6D,aAAa;AAG1E,SAAS,qCAAqC,iBAA8C;AAE1F,QAAM,UAAM,0BAAW,yBAAyB;AAEhD,MAAI,CAAC,KAAK;AACR,QAAI,OAAO,oBAAoB,YAAY;AACzC,sBAAgB;AAChB;AAAA,IACF;AAEA,UAAM,IAAI;AAAA,MACR,GAAG,eAAe;AAAA;AAAA;AAAA;AAAA;AAAA,IAKpB;AAAA,EACF;AACF;;;AExCO,IAAM,gBAAgB,MAA8B;AAUvD,uCAAqC,eAAe;AACpD,SAAO,6BAA6B;AACxC;","names":["import_react","React"]}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
// src/react/ternsecureProvider.tsx
|
|
2
|
+
import { useContext } from "react";
|
|
3
|
+
|
|
4
|
+
// src/react/ternsecureCtx.ts
|
|
5
|
+
import React from "react";
|
|
6
|
+
function assertContextExists(contextVal, msgOrCtx) {
|
|
7
|
+
if (!contextVal) {
|
|
8
|
+
throw typeof msgOrCtx === "string" ? new Error(msgOrCtx) : new Error(`${msgOrCtx.displayName} not found`);
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
var createContextAndHook = (displayName, options) => {
|
|
12
|
+
const { assertCtxFn = assertContextExists } = options || {};
|
|
13
|
+
const Ctx = React.createContext(void 0);
|
|
14
|
+
Ctx.displayName = displayName;
|
|
15
|
+
const useCtx = () => {
|
|
16
|
+
const ctx = React.useContext(Ctx);
|
|
17
|
+
assertCtxFn(ctx, `${displayName} not found`);
|
|
18
|
+
return ctx.value;
|
|
19
|
+
};
|
|
20
|
+
const useCtxWithoutGuarantee = () => {
|
|
21
|
+
const ctx = React.useContext(Ctx);
|
|
22
|
+
return ctx ? ctx.value : {};
|
|
23
|
+
};
|
|
24
|
+
return [Ctx, useCtx, useCtxWithoutGuarantee];
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
// src/react/ternsecureProvider.tsx
|
|
28
|
+
var [TernSecureInstanceContext, useTernSecureInstanceContext] = createContextAndHook("TernSecureInstanceContext");
|
|
29
|
+
var [TernSecureAuthContext, useTernSecureAuthContext] = createContextAndHook("TernSecureAuthContext");
|
|
30
|
+
var [SessionContext, useSessionContext] = createContextAndHook("SessionContext");
|
|
31
|
+
var [UserContext, useUserContext] = createContextAndHook("UserContext");
|
|
32
|
+
function useAssertWrappedByTernSecureProvider(displayNameOrFn) {
|
|
33
|
+
const ctx = useContext(TernSecureInstanceContext);
|
|
34
|
+
if (!ctx) {
|
|
35
|
+
if (typeof displayNameOrFn === "function") {
|
|
36
|
+
displayNameOrFn();
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
throw new Error(
|
|
40
|
+
`${displayNameOrFn} can only be used within the <TernSecureProvider /> component.
|
|
41
|
+
|
|
42
|
+
Possible fixes:
|
|
43
|
+
1. Ensure that the <TernSecureProvider /> is correctly wrapping your application
|
|
44
|
+
2. Check for multiple versions of @tern-secure packages in your project`
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// src/react/hooks/useTernSecure.ts
|
|
50
|
+
var useTernSecure = () => {
|
|
51
|
+
useAssertWrappedByTernSecureProvider("useTernSecure");
|
|
52
|
+
return useTernSecureInstanceContext();
|
|
53
|
+
};
|
|
54
|
+
export {
|
|
55
|
+
SessionContext,
|
|
56
|
+
TernSecureAuthContext,
|
|
57
|
+
TernSecureInstanceContext,
|
|
58
|
+
UserContext,
|
|
59
|
+
assertContextExists,
|
|
60
|
+
createContextAndHook,
|
|
61
|
+
useAssertWrappedByTernSecureProvider,
|
|
62
|
+
useSessionContext,
|
|
63
|
+
useTernSecure,
|
|
64
|
+
useTernSecureAuthContext,
|
|
65
|
+
useTernSecureInstanceContext,
|
|
66
|
+
useUserContext
|
|
67
|
+
};
|
|
68
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/react/ternsecureProvider.tsx","../../src/react/ternsecureCtx.ts","../../src/react/hooks/useTernSecure.ts"],"sourcesContent":["'use client'\n\nimport { useContext } from 'react';\nimport type { \n TernSecureAuthProvider,\n TernSecureInstanceTree,\n TernSecureState,\n} from '@tern-secure/types';\nimport { createContextAndHook } from './ternsecureCtx';\n\nexport type TernSecureAuthContextType = {\n authProvider: TernSecureAuthProvider | null | undefined;\n authState: TernSecureState;\n}\n\n\n// Create TernSecure instance context\nconst [TernSecureInstanceContext, useTernSecureInstanceContext] = \n createContextAndHook<TernSecureInstanceTree>('TernSecureInstanceContext');\n\nconst [TernSecureAuthContext, useTernSecureAuthContext] =\n createContextAndHook<TernSecureAuthContextType>('TernSecureAuthContext');\n\nconst [SessionContext, useSessionContext] = \ncreateContextAndHook<TernSecureInstanceTree['auth']['session']>('SessionContext');\n\nconst [UserContext, useUserContext] = \ncreateContextAndHook<TernSecureInstanceTree['auth']['user']>('UserContext');\n\n// Assert helper\nfunction useAssertWrappedByTernSecureProvider(displayNameOrFn: string | (() => void)): void {\n //const ctx = useTernSecureInstanceContext();\n const ctx = useContext(TernSecureInstanceContext);\n \n if (!ctx) {\n if (typeof displayNameOrFn === 'function') {\n displayNameOrFn();\n return;\n }\n\n throw new Error(\n `${displayNameOrFn} can only be used within the <TernSecureProvider /> component.\n \nPossible fixes:\n1. Ensure that the <TernSecureProvider /> is correctly wrapping your application\n2. Check for multiple versions of @tern-secure packages in your project`\n );\n }\n}\n\n\nexport {\n TernSecureInstanceContext,\n TernSecureAuthContext,\n SessionContext,\n UserContext,\n useTernSecureAuthContext,\n useSessionContext,\n useUserContext,\n useTernSecureInstanceContext,\n useAssertWrappedByTernSecureProvider\n};","'use client'\n\nimport React from 'react';\n\n/**\n * Assert that the context value exists, otherwise throw an error.\n *\n * @internal\n */\nexport function assertContextExists(contextVal: unknown, msgOrCtx: string | React.Context<any>): asserts contextVal {\n if (!contextVal) {\n throw typeof msgOrCtx === 'string' ? new Error(msgOrCtx) : new Error(`${msgOrCtx.displayName} not found`);\n }\n}\ntype Options = { assertCtxFn?: (v: unknown, msg: string) => void };\ntype ContextAndHook<T> = React.Context<{ value: T } | undefined>;\ntype UseCtxFn<T> = () => T;\n\n/**\n * Create and return a Context and two hooks that return the context value.\n * The Context type is derived from the type passed in by the user.\n *\n * The first hook returned guarantees that the context exists so the returned value is always `CtxValue`\n * The second hook makes no guarantees, so the returned value can be `CtxValue | undefined`\n *\n * @internal\n */\n\nexport const createContextAndHook = <CtxValue>(\n displayName: string,\n options?: Options,\n): [ContextAndHook<CtxValue>, UseCtxFn<CtxValue>, UseCtxFn<CtxValue | Partial<CtxValue>>] => {\n const { assertCtxFn = assertContextExists } = options || {};\n const Ctx = React.createContext<{ value: CtxValue } | undefined >(undefined);\n Ctx.displayName = displayName;\n\n const useCtx = () => {\n const ctx = React.useContext(Ctx);\n assertCtxFn(ctx, `${displayName} not found`);\n return (ctx as any).value as CtxValue;\n };\n\n const useCtxWithoutGuarantee = () => {\n const ctx = React.useContext(Ctx);\n return ctx ? ctx.value : {}\n };\n\n /**\n * Assert that the context value exists, otherwise throw an error.\n if (ctx === undefined) {\n throw new Error(`use${name} must be used within a ${name}Provider`);\n }\n return ctx.value;\n */\n\n return [Ctx, useCtx, useCtxWithoutGuarantee];\n}","import type { \n TernSecureInstanceTree\n} from \"@tern-secure/types\";\nimport { \n useAssertWrappedByTernSecureProvider, \n useTernSecureInstanceContext \n} from \"../ternsecureProvider\";\n\nexport const useTernSecure = (): TernSecureInstanceTree => {\n /**\n * if no assertion is needed, you can use the following:\n * const instance = useTernSecureInstanceContext();\n * if (!instance) {\n * throw new Error('useTernSecure must be used within a TernSecureProvider');\n * }\n * return instance;\n */\n \n useAssertWrappedByTernSecureProvider('useTernSecure');\n return useTernSecureInstanceContext();\n}"],"mappings":";AAEA,SAAS,kBAAkB;;;ACA3B,OAAO,WAAW;AAOX,SAAS,oBAAoB,YAAqB,UAA2D;AAClH,MAAI,CAAC,YAAY;AACf,UAAM,OAAO,aAAa,WAAW,IAAI,MAAM,QAAQ,IAAI,IAAI,MAAM,GAAG,SAAS,WAAW,YAAY;AAAA,EAC1G;AACF;AAeO,IAAM,uBAAuB,CAClC,aACA,YAC2F;AAC3F,QAAM,EAAE,cAAc,oBAAoB,IAAI,WAAW,CAAC;AAC1D,QAAM,MAAM,MAAM,cAAgD,MAAS;AAC3E,MAAI,cAAc;AAElB,QAAM,SAAS,MAAM;AACnB,UAAM,MAAM,MAAM,WAAW,GAAG;AAChC,gBAAY,KAAK,GAAG,WAAW,YAAY;AAC3C,WAAQ,IAAY;AAAA,EACtB;AAEA,QAAM,yBAAyB,MAAM;AACnC,UAAM,MAAM,MAAM,WAAW,GAAG;AAChC,WAAO,MAAM,IAAI,QAAQ,CAAC;AAAA,EAC5B;AAUA,SAAO,CAAC,KAAK,QAAQ,sBAAsB;AAC7C;;;ADvCA,IAAM,CAAC,2BAA2B,4BAA4B,IAC5D,qBAA6C,2BAA2B;AAE1E,IAAM,CAAC,uBAAuB,wBAAwB,IACpD,qBAAgD,uBAAuB;AAEzE,IAAM,CAAC,gBAAgB,iBAAiB,IACxC,qBAAgE,gBAAgB;AAEhF,IAAM,CAAC,aAAa,cAAc,IAClC,qBAA6D,aAAa;AAG1E,SAAS,qCAAqC,iBAA8C;AAE1F,QAAM,MAAM,WAAW,yBAAyB;AAEhD,MAAI,CAAC,KAAK;AACR,QAAI,OAAO,oBAAoB,YAAY;AACzC,sBAAgB;AAChB;AAAA,IACF;AAEA,UAAM,IAAI;AAAA,MACR,GAAG,eAAe;AAAA;AAAA;AAAA;AAAA;AAAA,IAKpB;AAAA,EACF;AACF;;;AExCO,IAAM,gBAAgB,MAA8B;AAUvD,uCAAqC,eAAe;AACpD,SAAO,6BAA6B;AACxC;","names":[]}
|
package/dist/retry.d.mts
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
type Milliseconds = number;
|
|
2
|
+
type RetryOptions = Partial<{
|
|
3
|
+
/**
|
|
4
|
+
* The initial delay before the first retry.
|
|
5
|
+
* @default 125
|
|
6
|
+
*/
|
|
7
|
+
initialDelay: Milliseconds;
|
|
8
|
+
/**
|
|
9
|
+
* The maximum delay between retries.
|
|
10
|
+
* The delay between retries will never exceed this value.
|
|
11
|
+
* If set to 0, the delay will increase indefinitely.
|
|
12
|
+
* @default 0
|
|
13
|
+
*/
|
|
14
|
+
maxDelayBetweenRetries: Milliseconds;
|
|
15
|
+
/**
|
|
16
|
+
* The multiplier for the exponential backoff.
|
|
17
|
+
* @default 2
|
|
18
|
+
*/
|
|
19
|
+
factor: number;
|
|
20
|
+
/**
|
|
21
|
+
* A function to determine if the operation should be retried.
|
|
22
|
+
* The callback accepts the error that was thrown and the number of iterations.
|
|
23
|
+
* The iterations variable references the number of retries AFTER attempt
|
|
24
|
+
* that caused the error and starts at 1 (as in, this is the 1st, 2nd, nth retry).
|
|
25
|
+
* @default (error, iterations) => iterations < 5
|
|
26
|
+
*/
|
|
27
|
+
shouldRetry: (error: unknown, iterations: number) => boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Controls whether the helper should retry the operation immediately once before applying exponential backoff.
|
|
30
|
+
* The delay for the immediate retry is 100ms.
|
|
31
|
+
* @default false
|
|
32
|
+
*/
|
|
33
|
+
retryImmediately: boolean;
|
|
34
|
+
/**
|
|
35
|
+
* If true, the intervals will be multiplied by a factor in the range of [1,2].
|
|
36
|
+
* @default true
|
|
37
|
+
*/
|
|
38
|
+
jitter: boolean;
|
|
39
|
+
}>;
|
|
40
|
+
/**
|
|
41
|
+
* Retries a callback until it succeeds or the shouldRetry function returns false.
|
|
42
|
+
* See {@link RetryOptions} for the available options.
|
|
43
|
+
*/
|
|
44
|
+
declare const retry: <T>(callback: () => T | Promise<T>, options?: RetryOptions) => Promise<T>;
|
|
45
|
+
|
|
46
|
+
export { retry };
|
package/dist/retry.d.ts
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
type Milliseconds = number;
|
|
2
|
+
type RetryOptions = Partial<{
|
|
3
|
+
/**
|
|
4
|
+
* The initial delay before the first retry.
|
|
5
|
+
* @default 125
|
|
6
|
+
*/
|
|
7
|
+
initialDelay: Milliseconds;
|
|
8
|
+
/**
|
|
9
|
+
* The maximum delay between retries.
|
|
10
|
+
* The delay between retries will never exceed this value.
|
|
11
|
+
* If set to 0, the delay will increase indefinitely.
|
|
12
|
+
* @default 0
|
|
13
|
+
*/
|
|
14
|
+
maxDelayBetweenRetries: Milliseconds;
|
|
15
|
+
/**
|
|
16
|
+
* The multiplier for the exponential backoff.
|
|
17
|
+
* @default 2
|
|
18
|
+
*/
|
|
19
|
+
factor: number;
|
|
20
|
+
/**
|
|
21
|
+
* A function to determine if the operation should be retried.
|
|
22
|
+
* The callback accepts the error that was thrown and the number of iterations.
|
|
23
|
+
* The iterations variable references the number of retries AFTER attempt
|
|
24
|
+
* that caused the error and starts at 1 (as in, this is the 1st, 2nd, nth retry).
|
|
25
|
+
* @default (error, iterations) => iterations < 5
|
|
26
|
+
*/
|
|
27
|
+
shouldRetry: (error: unknown, iterations: number) => boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Controls whether the helper should retry the operation immediately once before applying exponential backoff.
|
|
30
|
+
* The delay for the immediate retry is 100ms.
|
|
31
|
+
* @default false
|
|
32
|
+
*/
|
|
33
|
+
retryImmediately: boolean;
|
|
34
|
+
/**
|
|
35
|
+
* If true, the intervals will be multiplied by a factor in the range of [1,2].
|
|
36
|
+
* @default true
|
|
37
|
+
*/
|
|
38
|
+
jitter: boolean;
|
|
39
|
+
}>;
|
|
40
|
+
/**
|
|
41
|
+
* Retries a callback until it succeeds or the shouldRetry function returns false.
|
|
42
|
+
* See {@link RetryOptions} for the available options.
|
|
43
|
+
*/
|
|
44
|
+
declare const retry: <T>(callback: () => T | Promise<T>, options?: RetryOptions) => Promise<T>;
|
|
45
|
+
|
|
46
|
+
export { retry };
|
package/dist/retry.js
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
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/retry.ts
|
|
21
|
+
var retry_exports = {};
|
|
22
|
+
__export(retry_exports, {
|
|
23
|
+
retry: () => retry
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(retry_exports);
|
|
26
|
+
var defaultOptions = {
|
|
27
|
+
initialDelay: 125,
|
|
28
|
+
maxDelayBetweenRetries: 0,
|
|
29
|
+
factor: 2,
|
|
30
|
+
shouldRetry: (_, iteration) => iteration < 5,
|
|
31
|
+
retryImmediately: false,
|
|
32
|
+
jitter: true
|
|
33
|
+
};
|
|
34
|
+
var RETRY_IMMEDIATELY_DELAY = 100;
|
|
35
|
+
var sleep = async (ms) => new Promise((s) => setTimeout(s, ms));
|
|
36
|
+
var applyJitter = (delay, jitter) => {
|
|
37
|
+
return jitter ? delay * (1 + Math.random()) : delay;
|
|
38
|
+
};
|
|
39
|
+
var createExponentialDelayAsyncFn = (opts) => {
|
|
40
|
+
let timesCalled = 0;
|
|
41
|
+
const calculateDelayInMs = () => {
|
|
42
|
+
const constant = opts.initialDelay;
|
|
43
|
+
const base = opts.factor;
|
|
44
|
+
let delay = constant * Math.pow(base, timesCalled);
|
|
45
|
+
delay = applyJitter(delay, opts.jitter);
|
|
46
|
+
return Math.min(opts.maxDelayBetweenRetries || delay, delay);
|
|
47
|
+
};
|
|
48
|
+
return async () => {
|
|
49
|
+
await sleep(calculateDelayInMs());
|
|
50
|
+
timesCalled++;
|
|
51
|
+
};
|
|
52
|
+
};
|
|
53
|
+
var retry = async (callback, options = {}) => {
|
|
54
|
+
let iterations = 0;
|
|
55
|
+
const { shouldRetry, initialDelay, maxDelayBetweenRetries, factor, retryImmediately, jitter } = {
|
|
56
|
+
...defaultOptions,
|
|
57
|
+
...options
|
|
58
|
+
};
|
|
59
|
+
const delay = createExponentialDelayAsyncFn({
|
|
60
|
+
initialDelay,
|
|
61
|
+
maxDelayBetweenRetries,
|
|
62
|
+
factor,
|
|
63
|
+
jitter
|
|
64
|
+
});
|
|
65
|
+
while (true) {
|
|
66
|
+
try {
|
|
67
|
+
return await callback();
|
|
68
|
+
} catch (e) {
|
|
69
|
+
iterations++;
|
|
70
|
+
if (!shouldRetry(e, iterations)) {
|
|
71
|
+
throw e;
|
|
72
|
+
}
|
|
73
|
+
if (retryImmediately && iterations === 1) {
|
|
74
|
+
await sleep(applyJitter(RETRY_IMMEDIATELY_DELAY, jitter));
|
|
75
|
+
} else {
|
|
76
|
+
await delay();
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
82
|
+
0 && (module.exports = {
|
|
83
|
+
retry
|
|
84
|
+
});
|
|
85
|
+
//# sourceMappingURL=retry.js.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":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;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":[]}
|