@tern-secure/auth 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/cjs/global.d.js +2 -0
- package/dist/cjs/global.d.js.map +1 -0
- package/dist/cjs/index.js +42 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/instance/TernAuth.js +471 -0
- package/dist/cjs/instance/TernAuth.js.map +1 -0
- package/dist/cjs/instance/TernAuthServer.js +95 -0
- package/dist/cjs/instance/TernAuthServer.js.map +1 -0
- package/dist/cjs/instance/coreApiClient.example.js +96 -0
- package/dist/cjs/instance/coreApiClient.example.js.map +1 -0
- package/dist/cjs/instance/coreApiClient.js +255 -0
- package/dist/cjs/instance/coreApiClient.js.map +1 -0
- package/dist/cjs/instance/events.js +38 -0
- package/dist/cjs/instance/events.js.map +1 -0
- package/dist/cjs/resources/AuthCookieManager.js +89 -0
- package/dist/cjs/resources/AuthCookieManager.js.map +1 -0
- package/dist/cjs/resources/Base.js +125 -0
- package/dist/cjs/resources/Base.js.map +1 -0
- package/dist/cjs/resources/Error.js +31 -0
- package/dist/cjs/resources/Error.js.map +1 -0
- package/dist/cjs/resources/SignIn.js +224 -0
- package/dist/cjs/resources/SignIn.js.map +1 -0
- package/dist/cjs/resources/SignUp.js +43 -0
- package/dist/cjs/resources/SignUp.js.map +1 -0
- package/dist/cjs/resources/index.js +23 -0
- package/dist/cjs/resources/index.js.map +1 -0
- package/dist/cjs/resources/internal.js +33 -0
- package/dist/cjs/resources/internal.js.map +1 -0
- package/dist/cjs/utils/construct.js +174 -0
- package/dist/cjs/utils/construct.js.map +1 -0
- package/dist/cjs/utils/index.js +25 -0
- package/dist/cjs/utils/index.js.map +1 -0
- package/dist/cjs/utils/querystring.js +70 -0
- package/dist/cjs/utils/querystring.js.map +1 -0
- package/dist/esm/global.d.js +1 -0
- package/dist/esm/global.d.js.map +1 -0
- package/dist/esm/index.js +13 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/instance/TernAuth.js +455 -0
- package/dist/esm/instance/TernAuth.js.map +1 -0
- package/dist/esm/instance/TernAuthServer.js +73 -0
- package/dist/esm/instance/TernAuthServer.js.map +1 -0
- package/dist/esm/instance/coreApiClient.example.js +70 -0
- package/dist/esm/instance/coreApiClient.example.js.map +1 -0
- package/dist/esm/instance/coreApiClient.js +226 -0
- package/dist/esm/instance/coreApiClient.js.map +1 -0
- package/dist/esm/instance/events.js +13 -0
- package/dist/esm/instance/events.js.map +1 -0
- package/dist/esm/resources/AuthCookieManager.js +67 -0
- package/dist/esm/resources/AuthCookieManager.js.map +1 -0
- package/dist/esm/resources/Base.js +101 -0
- package/dist/esm/resources/Base.js.map +1 -0
- package/dist/esm/resources/Error.js +9 -0
- package/dist/esm/resources/Error.js.map +1 -0
- package/dist/esm/resources/SignIn.js +208 -0
- package/dist/esm/resources/SignIn.js.map +1 -0
- package/dist/esm/resources/SignUp.js +19 -0
- package/dist/esm/resources/SignUp.js.map +1 -0
- package/dist/esm/resources/index.js +2 -0
- package/dist/esm/resources/index.js.map +1 -0
- package/dist/esm/resources/internal.js +7 -0
- package/dist/esm/resources/internal.js.map +1 -0
- package/dist/esm/utils/construct.js +143 -0
- package/dist/esm/utils/construct.js.map +1 -0
- package/dist/esm/utils/index.js +3 -0
- package/dist/esm/utils/index.js.map +1 -0
- package/dist/esm/utils/querystring.js +45 -0
- package/dist/esm/utils/querystring.js.map +1 -0
- package/dist/types/index.d.ts +9 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/instance/TernAuth.d.ts +62 -0
- package/dist/types/instance/TernAuth.d.ts.map +1 -0
- package/dist/types/instance/TernAuthServer.d.ts +32 -0
- package/dist/types/instance/TernAuthServer.d.ts.map +1 -0
- package/dist/types/instance/coreApiClient.d.ts +65 -0
- package/dist/types/instance/coreApiClient.d.ts.map +1 -0
- package/dist/types/instance/coreApiClient.example.d.ts +8 -0
- package/dist/types/instance/coreApiClient.example.d.ts.map +1 -0
- package/dist/types/instance/events.d.ts +27 -0
- package/dist/types/instance/events.d.ts.map +1 -0
- package/dist/types/resources/AuthCookieManager.d.ts +26 -0
- package/dist/types/resources/AuthCookieManager.d.ts.map +1 -0
- package/dist/types/resources/Base.d.ts +40 -0
- package/dist/types/resources/Base.d.ts.map +1 -0
- package/dist/types/resources/Error.d.ts +2 -0
- package/dist/types/resources/Error.d.ts.map +1 -0
- package/dist/types/resources/SignIn.d.ts +32 -0
- package/dist/types/resources/SignIn.d.ts.map +1 -0
- package/dist/types/resources/SignUp.d.ts +14 -0
- package/dist/types/resources/SignUp.d.ts.map +1 -0
- package/dist/types/resources/index.d.ts +2 -0
- package/dist/types/resources/index.d.ts.map +1 -0
- package/dist/types/resources/internal.d.ts +8 -0
- package/dist/types/resources/internal.d.ts.map +1 -0
- package/dist/types/utils/construct.d.ts +67 -0
- package/dist/types/utils/construct.d.ts.map +1 -0
- package/dist/types/utils/index.d.ts +3 -0
- package/dist/types/utils/index.d.ts.map +1 -0
- package/dist/types/utils/querystring.d.ts +7 -0
- package/dist/types/utils/querystring.d.ts.map +1 -0
- package/package.json +50 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/instance/TernAuthServer.ts"],"sourcesContent":["import type { TernSecureConfig, TernSecureUser } from \"@tern-secure/types\";\nimport type {\n FirebaseServerApp,\n FirebaseServerAppSettings} from \"firebase/app\";\nimport {\n initializeServerApp\n} from \"firebase/app\";\nimport type { Auth} from \"firebase/auth\";\nimport { getAuth, getIdToken } from \"firebase/auth\";\n\ntype TernSecureServerConfig = {\n apiKey: string;\n};\nexport interface TernServerAuthOptions {\n firebaseConfig?: TernSecureConfig;\n firebaseServerConfig?: TernSecureServerConfig;\n authIdToken?: string;\n}\n\nexport interface AuthenticatedApp {\n firebaseServerApp: FirebaseServerApp;\n auth: Auth;\n currentUser?: TernSecureUser | null;\n}\n\nexport class TernServerAuth {\n private static instance: TernServerAuth | null = null;\n private auth!: Auth;\n #options: TernServerAuthOptions = {};\n\n public constructor() {}\n\n static getInstance(): TernServerAuth {\n if (!this.instance) {\n this.instance = new TernServerAuth();\n }\n return this.instance;\n }\n\n public static initialize(options: TernServerAuthOptions): TernServerAuth {\n const instance = this.getInstance();\n instance.#initialize(options);\n return instance;\n }\n\n #initialize(options: TernServerAuthOptions): void {\n this.#options = this.#initOptions(options);\n }\n\n static clearInstance(): void {\n this.instance = null;\n }\n\n getAuthIdToken = async (): Promise<string | undefined> => {\n await this.auth.authStateReady();\n if (!this.auth.currentUser) return;\n return await getIdToken(this.auth.currentUser);\n };\n\n getAuthenticatedAppFromHeaders = async (headers: {\n get: (key: string) => string | null;\n }): Promise<AuthenticatedApp> => {\n const authHeader = headers.get(\"Authorization\");\n const idToken = authHeader?.split(\"Bearer \")[1];\n\n let appSettings: FirebaseServerAppSettings = {};\n\n appSettings = {\n releaseOnDeref: headers,\n };\n\n if (idToken && idToken.trim()) {\n appSettings.authIdToken = idToken;\n }\n\n return this.getServerApp(appSettings);\n };\n\n getServerApp = async (\n appSettings?: FirebaseServerAppSettings\n ): Promise<AuthenticatedApp> => {\n const firebaseServerConfig = this.#options.firebaseServerConfig;\n if (!firebaseServerConfig) {\n throw new Error(\n \"Firebase server configuration is required to initialize the server app\"\n );\n }\n\n const firebaseServerApp = initializeServerApp(\n firebaseServerConfig,\n appSettings || {}\n );\n\n this.auth = getAuth(firebaseServerApp);\n await this.auth.authStateReady();\n\n return {\n firebaseServerApp,\n currentUser: this.auth.currentUser,\n auth: this.auth,\n };\n };\n\n #initOptions = (options?: TernServerAuthOptions): TernServerAuthOptions => {\n return {\n ...options,\n };\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAIA,iBAEO;AAEP,kBAAoC;AAiB7B,MAAM,eAAe;AAAA,EAC1B,OAAe,WAAkC;AAAA,EACzC;AAAA,EACR,WAAkC,CAAC;AAAA,EAE5B,cAAc;AAAA,EAAC;AAAA,EAEtB,OAAO,cAA8B;AACnC,QAAI,CAAC,KAAK,UAAU;AAClB,WAAK,WAAW,IAAI,eAAe;AAAA,IACrC;AACA,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,OAAc,WAAW,SAAgD;AACvE,UAAM,WAAW,KAAK,YAAY;AAClC,aAAS,YAAY,OAAO;AAC5B,WAAO;AAAA,EACT;AAAA,EAEA,YAAY,SAAsC;AAChD,SAAK,WAAW,KAAK,aAAa,OAAO;AAAA,EAC3C;AAAA,EAEA,OAAO,gBAAsB;AAC3B,SAAK,WAAW;AAAA,EAClB;AAAA,EAEA,iBAAiB,YAAyC;AACxD,UAAM,KAAK,KAAK,eAAe;AAC/B,QAAI,CAAC,KAAK,KAAK,YAAa;AAC5B,WAAO,UAAM,wBAAW,KAAK,KAAK,WAAW;AAAA,EAC/C;AAAA,EAEA,iCAAiC,OAAO,YAEP;AAC/B,UAAM,aAAa,QAAQ,IAAI,eAAe;AAC9C,UAAM,UAAU,yCAAY,MAAM,WAAW;AAE7C,QAAI,cAAyC,CAAC;AAE9C,kBAAc;AAAA,MACZ,gBAAgB;AAAA,IAClB;AAEA,QAAI,WAAW,QAAQ,KAAK,GAAG;AAC7B,kBAAY,cAAc;AAAA,IAC5B;AAEA,WAAO,KAAK,aAAa,WAAW;AAAA,EACtC;AAAA,EAEA,eAAe,OACb,gBAC8B;AAC9B,UAAM,uBAAuB,KAAK,SAAS;AAC3C,QAAI,CAAC,sBAAsB;AACzB,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAEA,UAAM,wBAAoB;AAAA,MACxB;AAAA,MACA,eAAe,CAAC;AAAA,IAClB;AAEA,SAAK,WAAO,qBAAQ,iBAAiB;AACrC,UAAM,KAAK,KAAK,eAAe;AAE/B,WAAO;AAAA,MACL;AAAA,MACA,aAAa,KAAK,KAAK;AAAA,MACvB,MAAM,KAAK;AAAA,IACb;AAAA,EACF;AAAA,EAEA,eAAe,CAAC,YAA2D;AACzE,WAAO;AAAA,MACL,GAAG;AAAA,IACL;AAAA,EACF;AACF;","names":[]}
|
|
@@ -0,0 +1,96 @@
|
|
|
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
|
+
var coreApiClient_example_exports = {};
|
|
20
|
+
__export(coreApiClient_example_exports, {
|
|
21
|
+
basicExample: () => basicExample,
|
|
22
|
+
clientWithHooksExample: () => clientWithHooksExample,
|
|
23
|
+
postExample: () => postExample
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(coreApiClient_example_exports);
|
|
26
|
+
var import_coreApiClient = require("./coreApiClient");
|
|
27
|
+
async function basicExample() {
|
|
28
|
+
var _a;
|
|
29
|
+
try {
|
|
30
|
+
const response = await import_coreApiClient.coreApiClient.request({
|
|
31
|
+
path: "/users",
|
|
32
|
+
method: "GET"
|
|
33
|
+
//search: { limit: 10, offset: 0 }
|
|
34
|
+
}, {
|
|
35
|
+
apiUrl: "https://api.example.com",
|
|
36
|
+
timeoutMs: 5e3
|
|
37
|
+
});
|
|
38
|
+
console.log("Users:", (_a = response.payload) == null ? void 0 : _a.response.users);
|
|
39
|
+
} catch (error) {
|
|
40
|
+
console.error("Failed to fetch users:", error);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
async function clientWithHooksExample() {
|
|
44
|
+
var _a;
|
|
45
|
+
const client = new import_coreApiClient.CoreApiClient({
|
|
46
|
+
apiUrl: "https://api.example.com",
|
|
47
|
+
timeoutMs: 1e4,
|
|
48
|
+
failureThreshold: 3,
|
|
49
|
+
maxTries: 5
|
|
50
|
+
});
|
|
51
|
+
client.onBeforeRequest(() => {
|
|
52
|
+
const token = localStorage.getItem("auth_token");
|
|
53
|
+
return !!token;
|
|
54
|
+
});
|
|
55
|
+
client.onAfterResponse((response) => {
|
|
56
|
+
console.log(`Response: ${response.status}`);
|
|
57
|
+
return true;
|
|
58
|
+
});
|
|
59
|
+
try {
|
|
60
|
+
const response = await client.request({
|
|
61
|
+
path: "/protected-resource",
|
|
62
|
+
method: "GET",
|
|
63
|
+
sessionId: "user-session-123"
|
|
64
|
+
});
|
|
65
|
+
console.log("Protected data:", (_a = response.payload) == null ? void 0 : _a.response);
|
|
66
|
+
} catch (error) {
|
|
67
|
+
console.error("Request failed:", error);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
async function postExample() {
|
|
71
|
+
var _a;
|
|
72
|
+
try {
|
|
73
|
+
const response = await import_coreApiClient.coreApiClient.request({
|
|
74
|
+
path: "/users",
|
|
75
|
+
method: "POST",
|
|
76
|
+
body: {
|
|
77
|
+
firstName: "John",
|
|
78
|
+
lastName: "Doe",
|
|
79
|
+
emailAddress: "john.doe@example.com"
|
|
80
|
+
}
|
|
81
|
+
// Cast to any since our implementation handles object-to-form conversion
|
|
82
|
+
}, {
|
|
83
|
+
apiUrl: "https://api.example.com"
|
|
84
|
+
});
|
|
85
|
+
console.log("Created user:", (_a = response.payload) == null ? void 0 : _a.response);
|
|
86
|
+
} catch (error) {
|
|
87
|
+
console.error("Failed to create user:", error);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
91
|
+
0 && (module.exports = {
|
|
92
|
+
basicExample,
|
|
93
|
+
clientWithHooksExample,
|
|
94
|
+
postExample
|
|
95
|
+
});
|
|
96
|
+
//# sourceMappingURL=coreApiClient.example.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/instance/coreApiClient.example.ts"],"sourcesContent":["/**\n * Example usage of CoreApiClient\n */\n\nimport { CoreApiClient, coreApiClient } from './coreApiClient';\n\n// Example 1: Basic usage with default instance\nasync function basicExample() {\n try {\n const response = await coreApiClient.request<{ users: any[] }>({\n path: '/users',\n method: 'GET',\n //search: { limit: 10, offset: 0 }\n }, {\n apiUrl: 'https://api.example.com',\n timeoutMs: 5000\n });\n\n console.log('Users:', response.payload?.response.users);\n } catch (error) {\n console.error('Failed to fetch users:', error);\n }\n}\n\n// Example 2: Custom client with hooks\nasync function clientWithHooksExample() {\n const client = new CoreApiClient({\n apiUrl: 'https://api.example.com',\n timeoutMs: 10000,\n failureThreshold: 3,\n maxTries: 5\n });\n\n // Add authentication hook\n client.onBeforeRequest(() => {\n const token = localStorage.getItem('auth_token');\n return !!token; // Only proceed if token exists\n });\n\n // Add logging hook\n client.onAfterResponse((response) => {\n console.log(`Response: ${response.status}`);\n return true;\n });\n\n try {\n const response = await client.request({\n path: '/protected-resource',\n method: 'GET',\n sessionId: 'user-session-123'\n });\n\n console.log('Protected data:', response.payload?.response);\n } catch (error) {\n console.error('Request failed:', error);\n }\n}\n\n// Example 3: POST request with form data\nasync function postExample() {\n try {\n const response = await coreApiClient.request({\n path: '/users',\n method: 'POST',\n body: {\n firstName: 'John',\n lastName: 'Doe',\n emailAddress: 'john.doe@example.com'\n } as any // Cast to any since our implementation handles object-to-form conversion\n }, {\n apiUrl: 'https://api.example.com'\n });\n\n console.log('Created user:', response.payload?.response);\n } catch (error) {\n console.error('Failed to create user:', error);\n }\n}\n\nexport { basicExample, clientWithHooksExample, postExample };\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAIA,2BAA6C;AAG7C,eAAe,eAAe;AAP9B;AAQE,MAAI;AACF,UAAM,WAAW,MAAM,mCAAc,QAA0B;AAAA,MAC7D,MAAM;AAAA,MACN,QAAQ;AAAA;AAAA,IAEV,GAAG;AAAA,MACD,QAAQ;AAAA,MACR,WAAW;AAAA,IACb,CAAC;AAED,YAAQ,IAAI,WAAU,cAAS,YAAT,mBAAkB,SAAS,KAAK;AAAA,EACxD,SAAS,OAAO;AACd,YAAQ,MAAM,0BAA0B,KAAK;AAAA,EAC/C;AACF;AAGA,eAAe,yBAAyB;AAzBxC;AA0BE,QAAM,SAAS,IAAI,mCAAc;AAAA,IAC/B,QAAQ;AAAA,IACR,WAAW;AAAA,IACX,kBAAkB;AAAA,IAClB,UAAU;AAAA,EACZ,CAAC;AAGD,SAAO,gBAAgB,MAAM;AAC3B,UAAM,QAAQ,aAAa,QAAQ,YAAY;AAC/C,WAAO,CAAC,CAAC;AAAA,EACX,CAAC;AAGD,SAAO,gBAAgB,CAAC,aAAa;AACnC,YAAQ,IAAI,aAAa,SAAS,MAAM,EAAE;AAC1C,WAAO;AAAA,EACT,CAAC;AAED,MAAI;AACF,UAAM,WAAW,MAAM,OAAO,QAAQ;AAAA,MACpC,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,WAAW;AAAA,IACb,CAAC;AAED,YAAQ,IAAI,oBAAmB,cAAS,YAAT,mBAAkB,QAAQ;AAAA,EAC3D,SAAS,OAAO;AACd,YAAQ,MAAM,mBAAmB,KAAK;AAAA,EACxC;AACF;AAGA,eAAe,cAAc;AA3D7B;AA4DE,MAAI;AACF,UAAM,WAAW,MAAM,mCAAc,QAAQ;AAAA,MAC3C,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,MAAM;AAAA,QACJ,WAAW;AAAA,QACX,UAAU;AAAA,QACV,cAAc;AAAA,MAChB;AAAA;AAAA,IACF,GAAG;AAAA,MACD,QAAQ;AAAA,IACV,CAAC;AAED,YAAQ,IAAI,kBAAiB,cAAS,YAAT,mBAAkB,QAAQ;AAAA,EACzD,SAAS,OAAO;AACd,YAAQ,MAAM,0BAA0B,KAAK;AAAA,EAC/C;AACF;","names":[]}
|
|
@@ -0,0 +1,255 @@
|
|
|
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
|
+
var coreApiClient_exports = {};
|
|
20
|
+
__export(coreApiClient_exports, {
|
|
21
|
+
CircuitOpenError: () => CircuitOpenError,
|
|
22
|
+
CoreApiClient: () => CoreApiClient,
|
|
23
|
+
HTTPError: () => HTTPError,
|
|
24
|
+
NetworkError: () => NetworkError,
|
|
25
|
+
TimeoutError: () => TimeoutError,
|
|
26
|
+
coreApiClient: () => coreApiClient
|
|
27
|
+
});
|
|
28
|
+
module.exports = __toCommonJS(coreApiClient_exports);
|
|
29
|
+
var import_utils = require("../utils");
|
|
30
|
+
class NetworkError extends Error {
|
|
31
|
+
constructor(url, original) {
|
|
32
|
+
super(`Network error for ${url}: ${original.message}`);
|
|
33
|
+
this.url = url;
|
|
34
|
+
this.original = original;
|
|
35
|
+
this.name = "NetworkError";
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
class TimeoutError extends Error {
|
|
39
|
+
constructor() {
|
|
40
|
+
super("Request timed out");
|
|
41
|
+
this.name = "TimeoutError";
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
class CircuitOpenError extends Error {
|
|
45
|
+
constructor() {
|
|
46
|
+
super("Circuit breaker is open");
|
|
47
|
+
this.name = "CircuitOpenError";
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
class HTTPError extends Error {
|
|
51
|
+
constructor(status, url, body) {
|
|
52
|
+
super(`HTTP ${status} error for ${url}`);
|
|
53
|
+
this.status = status;
|
|
54
|
+
this.url = url;
|
|
55
|
+
this.body = body;
|
|
56
|
+
this.name = "HTTPError";
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
function camelToSnake(str) {
|
|
60
|
+
return str.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);
|
|
61
|
+
}
|
|
62
|
+
function jitteredDelay(delay) {
|
|
63
|
+
return delay * Math.random();
|
|
64
|
+
}
|
|
65
|
+
function buildUrl(requestInit, options) {
|
|
66
|
+
const { path } = requestInit;
|
|
67
|
+
const baseUrl = options.apiUrl;
|
|
68
|
+
if (!baseUrl) {
|
|
69
|
+
throw new Error("API URL is required");
|
|
70
|
+
}
|
|
71
|
+
const fullPath = path ? path.startsWith("/") ? path : `/${path}` : "";
|
|
72
|
+
const fullUrl = baseUrl.replace(/\/$/, "") + fullPath;
|
|
73
|
+
return (0, import_utils.buildURL)(
|
|
74
|
+
{
|
|
75
|
+
base: fullUrl,
|
|
76
|
+
searchParams: requestInit.search ? new URLSearchParams(requestInit.search) : void 0
|
|
77
|
+
},
|
|
78
|
+
{ stringify: false }
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
class CoreApiClient {
|
|
82
|
+
constructor(options = {}) {
|
|
83
|
+
this.options = options;
|
|
84
|
+
}
|
|
85
|
+
circuitBreaker = {
|
|
86
|
+
failures: 0,
|
|
87
|
+
lastFailureTime: 0,
|
|
88
|
+
state: "closed"
|
|
89
|
+
};
|
|
90
|
+
beforeRequestHooks = [];
|
|
91
|
+
afterResponseHooks = [];
|
|
92
|
+
onBeforeRequest(hook) {
|
|
93
|
+
this.beforeRequestHooks.push(hook);
|
|
94
|
+
}
|
|
95
|
+
onAfterResponse(hook) {
|
|
96
|
+
this.afterResponseHooks.push(hook);
|
|
97
|
+
}
|
|
98
|
+
async runBeforeRequestHooks() {
|
|
99
|
+
for (const hook of this.beforeRequestHooks) {
|
|
100
|
+
const result = await hook();
|
|
101
|
+
if (result === false) return false;
|
|
102
|
+
}
|
|
103
|
+
return true;
|
|
104
|
+
}
|
|
105
|
+
async runAfterResponseHooks(response) {
|
|
106
|
+
for (const hook of this.afterResponseHooks) {
|
|
107
|
+
await hook(response);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
checkCircuitBreaker() {
|
|
111
|
+
const { recoveryTimeoutMs = 6e4 } = this.options;
|
|
112
|
+
const now = Date.now();
|
|
113
|
+
if (this.circuitBreaker.state === "open") {
|
|
114
|
+
if (now - this.circuitBreaker.lastFailureTime >= recoveryTimeoutMs) {
|
|
115
|
+
this.circuitBreaker.state = "half-open";
|
|
116
|
+
} else {
|
|
117
|
+
throw new CircuitOpenError();
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
recordSuccess() {
|
|
122
|
+
this.circuitBreaker.failures = 0;
|
|
123
|
+
this.circuitBreaker.state = "closed";
|
|
124
|
+
}
|
|
125
|
+
recordFailure() {
|
|
126
|
+
const { failureThreshold = 5 } = this.options;
|
|
127
|
+
this.circuitBreaker.failures++;
|
|
128
|
+
this.circuitBreaker.lastFailureTime = Date.now();
|
|
129
|
+
if (this.circuitBreaker.failures >= failureThreshold) {
|
|
130
|
+
this.circuitBreaker.state = "open";
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
shouldRetry(error, method, attempt, maxTries) {
|
|
134
|
+
const isRetryable = error instanceof NetworkError && method.toUpperCase() === "GET" && attempt < maxTries;
|
|
135
|
+
if (!isRetryable) {
|
|
136
|
+
this.recordFailure();
|
|
137
|
+
}
|
|
138
|
+
return isRetryable;
|
|
139
|
+
}
|
|
140
|
+
async retryWithBackoff(attemptFn, shouldRetry) {
|
|
141
|
+
const {
|
|
142
|
+
initialDelay = 700,
|
|
143
|
+
factor = 2,
|
|
144
|
+
maxDelay = 5e3,
|
|
145
|
+
maxTries = typeof navigator !== "undefined" && navigator.onLine ? 4 : 11
|
|
146
|
+
} = this.options;
|
|
147
|
+
let lastError;
|
|
148
|
+
for (let attempt = 1; attempt <= maxTries; attempt++) {
|
|
149
|
+
try {
|
|
150
|
+
const result = await attemptFn();
|
|
151
|
+
this.recordSuccess();
|
|
152
|
+
return result;
|
|
153
|
+
} catch (error) {
|
|
154
|
+
lastError = error;
|
|
155
|
+
if (!shouldRetry(error, attempt)) {
|
|
156
|
+
throw error;
|
|
157
|
+
}
|
|
158
|
+
this.recordFailure();
|
|
159
|
+
if (attempt < maxTries) {
|
|
160
|
+
const delay = Math.min(initialDelay * Math.pow(factor, attempt - 1), maxDelay);
|
|
161
|
+
await new Promise((resolve) => setTimeout(resolve, jitteredDelay(delay)));
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
throw lastError;
|
|
166
|
+
}
|
|
167
|
+
async request(init, opts = {}) {
|
|
168
|
+
const requestInit = { ...init };
|
|
169
|
+
const { method = "GET", body } = requestInit;
|
|
170
|
+
requestInit.url = buildUrl({ ...init }, { ...opts });
|
|
171
|
+
this.checkCircuitBreaker();
|
|
172
|
+
const shouldContinue = await this.runBeforeRequestHooks();
|
|
173
|
+
if (!shouldContinue) {
|
|
174
|
+
const mockResponse = new Response("{}", {
|
|
175
|
+
status: 200
|
|
176
|
+
});
|
|
177
|
+
mockResponse.payload = { response: {} };
|
|
178
|
+
await this.runAfterResponseHooks(mockResponse);
|
|
179
|
+
return mockResponse;
|
|
180
|
+
}
|
|
181
|
+
const mergedOptions = { ...opts };
|
|
182
|
+
const { timeoutMs } = mergedOptions;
|
|
183
|
+
const overwrittenRequestMethod = method === "GET" ? "GET" : "POST";
|
|
184
|
+
const url = requestInit.url.toString();
|
|
185
|
+
console.log("Request URL:", url);
|
|
186
|
+
requestInit.headers = new Headers(requestInit.headers);
|
|
187
|
+
if (method !== "GET" && !(body instanceof FormData) && !requestInit.headers.has("content-type")) {
|
|
188
|
+
requestInit.headers.set("content-type", "application/json");
|
|
189
|
+
}
|
|
190
|
+
if (requestInit.headers.get("content-type") === "application/x-www-form-urlencoded") {
|
|
191
|
+
requestInit.body = body ? (0, import_utils.stringifyQueryParams)(body, {
|
|
192
|
+
keyEncoder: camelToSnake
|
|
193
|
+
}) : body;
|
|
194
|
+
} else if (requestInit.headers.get("content-type") === "application/json" && body) {
|
|
195
|
+
requestInit.body = typeof body === "string" ? body : JSON.stringify(body);
|
|
196
|
+
}
|
|
197
|
+
const attemptRequest = async () => {
|
|
198
|
+
const controller = new AbortController();
|
|
199
|
+
const timeoutId = timeoutMs ? setTimeout(() => {
|
|
200
|
+
controller.abort();
|
|
201
|
+
}, timeoutMs) : null;
|
|
202
|
+
let response;
|
|
203
|
+
const fetchOpts = {
|
|
204
|
+
...requestInit,
|
|
205
|
+
credentials: "include",
|
|
206
|
+
method: overwrittenRequestMethod
|
|
207
|
+
};
|
|
208
|
+
try {
|
|
209
|
+
response = await fetch(url, fetchOpts);
|
|
210
|
+
if (timeoutId) clearTimeout(timeoutId);
|
|
211
|
+
let payload = null;
|
|
212
|
+
if (response.status === 204) {
|
|
213
|
+
payload = null;
|
|
214
|
+
} else {
|
|
215
|
+
try {
|
|
216
|
+
const json = await response.json();
|
|
217
|
+
payload = json;
|
|
218
|
+
} catch {
|
|
219
|
+
payload = { response: {} };
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
const apiResponse = response;
|
|
223
|
+
apiResponse.payload = payload;
|
|
224
|
+
await this.runAfterResponseHooks(apiResponse);
|
|
225
|
+
return apiResponse;
|
|
226
|
+
} catch (error) {
|
|
227
|
+
if (timeoutId) clearTimeout(timeoutId);
|
|
228
|
+
if (error.name === "AbortError") {
|
|
229
|
+
throw new TimeoutError();
|
|
230
|
+
}
|
|
231
|
+
throw new NetworkError(url, error);
|
|
232
|
+
}
|
|
233
|
+
};
|
|
234
|
+
return this.retryWithBackoff(
|
|
235
|
+
attemptRequest,
|
|
236
|
+
(error, attempt) => this.shouldRetry(
|
|
237
|
+
error,
|
|
238
|
+
overwrittenRequestMethod,
|
|
239
|
+
attempt,
|
|
240
|
+
mergedOptions.maxTries || (typeof navigator !== "undefined" && navigator.onLine ? 4 : 11)
|
|
241
|
+
)
|
|
242
|
+
);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
const coreApiClient = new CoreApiClient();
|
|
246
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
247
|
+
0 && (module.exports = {
|
|
248
|
+
CircuitOpenError,
|
|
249
|
+
CoreApiClient,
|
|
250
|
+
HTTPError,
|
|
251
|
+
NetworkError,
|
|
252
|
+
TimeoutError,
|
|
253
|
+
coreApiClient
|
|
254
|
+
});
|
|
255
|
+
//# sourceMappingURL=coreApiClient.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/instance/coreApiClient.ts"],"sourcesContent":["import type { TernSecureApiErrorJSON } from '@tern-secure/types';\n\nimport { buildURL as buildUrlUtil,stringifyQueryParams } from '../utils';\n\nexport type HTTPMethod =\n | 'CONNECT'\n | 'DELETE'\n | 'GET'\n | 'HEAD'\n | 'OPTIONS'\n | 'PATCH'\n | 'POST'\n | 'PUT'\n | 'TRACE';\n\nexport type ApiRequestInit = RequestInit & {\n path?: string;\n search?: ConstructorParameters<typeof URLSearchParams>[0];\n sessionId?: string;\n url?: URL;\n};\n\nexport interface ApiResponseJSON<T> {\n response: T;\n errors?: TernSecureApiErrorJSON[];\n}\n\nexport type ApiResponse<T> = Response & { payload: ApiResponseJSON<T> | null };\n\nexport type ApiRequestCallback<T> = (request: ApiRequestInit, response?: ApiResponse<T>) => unknown;\n\nexport interface RequestOptions {\n timeoutMs?: number;\n maxTries?: number;\n initialDelay?: number;\n factor?: number;\n maxDelay?: number;\n failureThreshold?: number;\n recoveryTimeoutMs?: number;\n apiUrl?: string;\n frontendApi?: string;\n}\n\nexport type BeforeRequestHook = () => boolean | Promise<boolean>;\nexport type AfterResponseHook = (response: ApiResponse<any>) => boolean | Promise<boolean>;\n\n// Error classes\nexport class NetworkError extends Error {\n constructor(\n public url: string,\n public original: Error,\n ) {\n super(`Network error for ${url}: ${original.message}`);\n this.name = 'NetworkError';\n }\n}\n\nexport class TimeoutError extends Error {\n constructor() {\n super('Request timed out');\n this.name = 'TimeoutError';\n }\n}\n\nexport class CircuitOpenError extends Error {\n constructor() {\n super('Circuit breaker is open');\n this.name = 'CircuitOpenError';\n }\n}\n\nexport class HTTPError extends Error {\n constructor(\n public status: number,\n public url: string,\n public body?: any,\n ) {\n super(`HTTP ${status} error for ${url}`);\n this.name = 'HTTPError';\n }\n}\n\n// Circuit breaker state\ninterface CircuitBreakerState {\n failures: number;\n lastFailureTime: number;\n state: 'closed' | 'open' | 'half-open';\n}\n\n// Utility functions\nfunction camelToSnake(str: string): string {\n return str.replace(/[A-Z]/g, letter => `_${letter.toLowerCase()}`);\n}\n\nfunction jitteredDelay(delay: number): number {\n return delay * Math.random();\n}\n\nfunction buildUrl(requestInit: ApiRequestInit, options: RequestOptions): URL {\n const { path } = requestInit;\n const baseUrl = options.apiUrl;\n\n if (!baseUrl) {\n throw new Error('API URL is required');\n }\n\n // Ensure proper URL construction by joining baseUrl and path\n const fullPath = path ? (path.startsWith('/') ? path : `/${path}`) : '';\n const fullUrl = baseUrl.replace(/\\/$/, '') + fullPath;\n\n return buildUrlUtil(\n {\n base: fullUrl,\n searchParams: requestInit.search ? new URLSearchParams(requestInit.search) : undefined,\n },\n { stringify: false },\n );\n}\n\nexport class CoreApiClient {\n private circuitBreaker: CircuitBreakerState = {\n failures: 0,\n lastFailureTime: 0,\n state: 'closed',\n };\n\n private beforeRequestHooks: BeforeRequestHook[] = [];\n private afterResponseHooks: AfterResponseHook[] = [];\n\n constructor(private options: RequestOptions = {}) {}\n\n onBeforeRequest(hook: BeforeRequestHook): void {\n this.beforeRequestHooks.push(hook);\n }\n\n onAfterResponse(hook: AfterResponseHook): void {\n this.afterResponseHooks.push(hook);\n }\n\n private async runBeforeRequestHooks(): Promise<boolean> {\n for (const hook of this.beforeRequestHooks) {\n const result = await hook();\n if (result === false) return false;\n }\n return true;\n }\n\n private async runAfterResponseHooks(response: ApiResponse<any>): Promise<void> {\n for (const hook of this.afterResponseHooks) {\n await hook(response);\n }\n }\n\n private checkCircuitBreaker(): void {\n const { recoveryTimeoutMs = 60000 } = this.options;\n const now = Date.now();\n\n if (this.circuitBreaker.state === 'open') {\n if (now - this.circuitBreaker.lastFailureTime >= recoveryTimeoutMs) {\n this.circuitBreaker.state = 'half-open';\n } else {\n throw new CircuitOpenError();\n }\n }\n }\n\n private recordSuccess(): void {\n this.circuitBreaker.failures = 0;\n this.circuitBreaker.state = 'closed';\n }\n\n private recordFailure(): void {\n const { failureThreshold = 5 } = this.options;\n this.circuitBreaker.failures++;\n this.circuitBreaker.lastFailureTime = Date.now();\n\n if (this.circuitBreaker.failures >= failureThreshold) {\n this.circuitBreaker.state = 'open';\n }\n }\n\n private shouldRetry(error: any, method: string, attempt: number, maxTries: number): boolean {\n // Only retry on network errors for GET requests\n const isRetryable =\n error instanceof NetworkError && method.toUpperCase() === 'GET' && attempt < maxTries;\n\n // If not retrying, we should still record the failure for circuit breaker\n if (!isRetryable) {\n this.recordFailure();\n }\n\n return isRetryable;\n }\n\n private async retryWithBackoff<T>(\n attemptFn: () => Promise<T>,\n shouldRetry: (error: any, attempt: number) => boolean,\n ): Promise<T> {\n const {\n initialDelay = 700,\n factor = 2,\n maxDelay = 5000,\n maxTries = typeof navigator !== 'undefined' && navigator.onLine ? 4 : 11,\n } = this.options;\n\n let lastError: any;\n\n for (let attempt = 1; attempt <= maxTries; attempt++) {\n try {\n const result = await attemptFn();\n this.recordSuccess();\n return result;\n } catch (error) {\n lastError = error;\n\n if (!shouldRetry(error, attempt)) {\n // shouldRetry already recorded the failure, so just throw\n throw error;\n }\n\n // This is a retryable error, record failure for circuit breaker\n this.recordFailure();\n\n if (attempt < maxTries) {\n const delay = Math.min(initialDelay * Math.pow(factor, attempt - 1), maxDelay);\n await new Promise(resolve => setTimeout(resolve, jitteredDelay(delay)));\n }\n }\n }\n\n throw lastError;\n }\n\n async request<T>(init: ApiRequestInit, opts: RequestOptions = {}): Promise<ApiResponse<T>> {\n const requestInit = { ...init };\n const { method = 'GET', body } = requestInit;\n\n requestInit.url = buildUrl({ ...init }, { ...opts });\n // Check circuit breaker\n this.checkCircuitBreaker();\n\n // Run before request hooks\n const shouldContinue = await this.runBeforeRequestHooks();\n if (!shouldContinue) {\n const mockResponse = new Response('{}', {\n status: 200,\n }) as ApiResponse<T>;\n mockResponse.payload = { response: {} as T };\n await this.runAfterResponseHooks(mockResponse);\n return mockResponse;\n }\n\n const mergedOptions = { ...opts };\n const { timeoutMs } = mergedOptions;\n\n // Safari workaround - only use GET/POST\n const overwrittenRequestMethod = method === 'GET' ? 'GET' : 'POST';\n\n const url = requestInit.url.toString();\n\n console.log('Request URL:', url);\n\n requestInit.headers = new Headers(requestInit.headers);\n\n // Set the default content type for non-GET requests.\n if (\n method !== 'GET' &&\n !(body instanceof FormData) &&\n !requestInit.headers.has('content-type')\n ) {\n requestInit.headers.set('content-type', 'application/json');\n }\n\n if (requestInit.headers.get('content-type') === 'application/x-www-form-urlencoded') {\n requestInit.body = body\n ? stringifyQueryParams(body as any as Record<string, string>, {\n keyEncoder: camelToSnake,\n })\n : body;\n } else if (requestInit.headers.get('content-type') === 'application/json' && body) {\n requestInit.body = typeof body === 'string' ? body : JSON.stringify(body);\n }\n\n const attemptRequest = async (): Promise<ApiResponse<T>> => {\n const controller = new AbortController();\n const timeoutId = timeoutMs\n ? setTimeout(() => {\n controller.abort();\n }, timeoutMs)\n : null;\n\n let response: Response;\n const fetchOpts: ApiRequestInit = {\n ...requestInit,\n credentials: 'include',\n method: overwrittenRequestMethod,\n };\n try {\n response = await fetch(url, fetchOpts);\n\n if (timeoutId) clearTimeout(timeoutId);\n\n // Parse response\n let payload: ApiResponseJSON<T> | null = null;\n\n if (response.status === 204) {\n payload = null;\n } else {\n try {\n const json = await response.json();\n payload = json;\n } catch {\n // If JSON parsing fails, create default payload\n payload = { response: {} as T };\n }\n }\n\n const apiResponse = response as ApiResponse<T>;\n apiResponse.payload = payload;\n\n // Run after response hooks\n await this.runAfterResponseHooks(apiResponse);\n\n return apiResponse;\n } catch (error: any) {\n if (timeoutId) clearTimeout(timeoutId);\n\n if (error.name === 'AbortError') {\n throw new TimeoutError();\n }\n\n throw new NetworkError(url, error);\n }\n };\n\n return this.retryWithBackoff(attemptRequest, (error, attempt) =>\n this.shouldRetry(\n error,\n overwrittenRequestMethod,\n attempt,\n mergedOptions.maxTries || (typeof navigator !== 'undefined' && navigator.onLine ? 4 : 11),\n ),\n );\n }\n}\n\nexport const coreApiClient = new CoreApiClient();\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,mBAA8D;AA6CvD,MAAM,qBAAqB,MAAM;AAAA,EACtC,YACS,KACA,UACP;AACA,UAAM,qBAAqB,GAAG,KAAK,SAAS,OAAO,EAAE;AAH9C;AACA;AAGP,SAAK,OAAO;AAAA,EACd;AACF;AAEO,MAAM,qBAAqB,MAAM;AAAA,EACtC,cAAc;AACZ,UAAM,mBAAmB;AACzB,SAAK,OAAO;AAAA,EACd;AACF;AAEO,MAAM,yBAAyB,MAAM;AAAA,EAC1C,cAAc;AACZ,UAAM,yBAAyB;AAC/B,SAAK,OAAO;AAAA,EACd;AACF;AAEO,MAAM,kBAAkB,MAAM;AAAA,EACnC,YACS,QACA,KACA,MACP;AACA,UAAM,QAAQ,MAAM,cAAc,GAAG,EAAE;AAJhC;AACA;AACA;AAGP,SAAK,OAAO;AAAA,EACd;AACF;AAUA,SAAS,aAAa,KAAqB;AACzC,SAAO,IAAI,QAAQ,UAAU,YAAU,IAAI,OAAO,YAAY,CAAC,EAAE;AACnE;AAEA,SAAS,cAAc,OAAuB;AAC5C,SAAO,QAAQ,KAAK,OAAO;AAC7B;AAEA,SAAS,SAAS,aAA6B,SAA8B;AAC3E,QAAM,EAAE,KAAK,IAAI;AACjB,QAAM,UAAU,QAAQ;AAExB,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,MAAM,qBAAqB;AAAA,EACvC;AAGA,QAAM,WAAW,OAAQ,KAAK,WAAW,GAAG,IAAI,OAAO,IAAI,IAAI,KAAM;AACrE,QAAM,UAAU,QAAQ,QAAQ,OAAO,EAAE,IAAI;AAE7C,aAAO,aAAAA;AAAA,IACL;AAAA,MACE,MAAM;AAAA,MACN,cAAc,YAAY,SAAS,IAAI,gBAAgB,YAAY,MAAM,IAAI;AAAA,IAC/E;AAAA,IACA,EAAE,WAAW,MAAM;AAAA,EACrB;AACF;AAEO,MAAM,cAAc;AAAA,EAUzB,YAAoB,UAA0B,CAAC,GAAG;AAA9B;AAAA,EAA+B;AAAA,EAT3C,iBAAsC;AAAA,IAC5C,UAAU;AAAA,IACV,iBAAiB;AAAA,IACjB,OAAO;AAAA,EACT;AAAA,EAEQ,qBAA0C,CAAC;AAAA,EAC3C,qBAA0C,CAAC;AAAA,EAInD,gBAAgB,MAA+B;AAC7C,SAAK,mBAAmB,KAAK,IAAI;AAAA,EACnC;AAAA,EAEA,gBAAgB,MAA+B;AAC7C,SAAK,mBAAmB,KAAK,IAAI;AAAA,EACnC;AAAA,EAEA,MAAc,wBAA0C;AACtD,eAAW,QAAQ,KAAK,oBAAoB;AAC1C,YAAM,SAAS,MAAM,KAAK;AAC1B,UAAI,WAAW,MAAO,QAAO;AAAA,IAC/B;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,sBAAsB,UAA2C;AAC7E,eAAW,QAAQ,KAAK,oBAAoB;AAC1C,YAAM,KAAK,QAAQ;AAAA,IACrB;AAAA,EACF;AAAA,EAEQ,sBAA4B;AAClC,UAAM,EAAE,oBAAoB,IAAM,IAAI,KAAK;AAC3C,UAAM,MAAM,KAAK,IAAI;AAErB,QAAI,KAAK,eAAe,UAAU,QAAQ;AACxC,UAAI,MAAM,KAAK,eAAe,mBAAmB,mBAAmB;AAClE,aAAK,eAAe,QAAQ;AAAA,MAC9B,OAAO;AACL,cAAM,IAAI,iBAAiB;AAAA,MAC7B;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,gBAAsB;AAC5B,SAAK,eAAe,WAAW;AAC/B,SAAK,eAAe,QAAQ;AAAA,EAC9B;AAAA,EAEQ,gBAAsB;AAC5B,UAAM,EAAE,mBAAmB,EAAE,IAAI,KAAK;AACtC,SAAK,eAAe;AACpB,SAAK,eAAe,kBAAkB,KAAK,IAAI;AAE/C,QAAI,KAAK,eAAe,YAAY,kBAAkB;AACpD,WAAK,eAAe,QAAQ;AAAA,IAC9B;AAAA,EACF;AAAA,EAEQ,YAAY,OAAY,QAAgB,SAAiB,UAA2B;AAE1F,UAAM,cACJ,iBAAiB,gBAAgB,OAAO,YAAY,MAAM,SAAS,UAAU;AAG/E,QAAI,CAAC,aAAa;AAChB,WAAK,cAAc;AAAA,IACrB;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,iBACZ,WACA,aACY;AACZ,UAAM;AAAA,MACJ,eAAe;AAAA,MACf,SAAS;AAAA,MACT,WAAW;AAAA,MACX,WAAW,OAAO,cAAc,eAAe,UAAU,SAAS,IAAI;AAAA,IACxE,IAAI,KAAK;AAET,QAAI;AAEJ,aAAS,UAAU,GAAG,WAAW,UAAU,WAAW;AACpD,UAAI;AACF,cAAM,SAAS,MAAM,UAAU;AAC/B,aAAK,cAAc;AACnB,eAAO;AAAA,MACT,SAAS,OAAO;AACd,oBAAY;AAEZ,YAAI,CAAC,YAAY,OAAO,OAAO,GAAG;AAEhC,gBAAM;AAAA,QACR;AAGA,aAAK,cAAc;AAEnB,YAAI,UAAU,UAAU;AACtB,gBAAM,QAAQ,KAAK,IAAI,eAAe,KAAK,IAAI,QAAQ,UAAU,CAAC,GAAG,QAAQ;AAC7E,gBAAM,IAAI,QAAQ,aAAW,WAAW,SAAS,cAAc,KAAK,CAAC,CAAC;AAAA,QACxE;AAAA,MACF;AAAA,IACF;AAEA,UAAM;AAAA,EACR;AAAA,EAEA,MAAM,QAAW,MAAsB,OAAuB,CAAC,GAA4B;AACzF,UAAM,cAAc,EAAE,GAAG,KAAK;AAC9B,UAAM,EAAE,SAAS,OAAO,KAAK,IAAI;AAEjC,gBAAY,MAAM,SAAS,EAAE,GAAG,KAAK,GAAG,EAAE,GAAG,KAAK,CAAC;AAEnD,SAAK,oBAAoB;AAGzB,UAAM,iBAAiB,MAAM,KAAK,sBAAsB;AACxD,QAAI,CAAC,gBAAgB;AACnB,YAAM,eAAe,IAAI,SAAS,MAAM;AAAA,QACtC,QAAQ;AAAA,MACV,CAAC;AACD,mBAAa,UAAU,EAAE,UAAU,CAAC,EAAO;AAC3C,YAAM,KAAK,sBAAsB,YAAY;AAC7C,aAAO;AAAA,IACT;AAEA,UAAM,gBAAgB,EAAE,GAAG,KAAK;AAChC,UAAM,EAAE,UAAU,IAAI;AAGtB,UAAM,2BAA2B,WAAW,QAAQ,QAAQ;AAE5D,UAAM,MAAM,YAAY,IAAI,SAAS;AAErC,YAAQ,IAAI,gBAAgB,GAAG;AAE/B,gBAAY,UAAU,IAAI,QAAQ,YAAY,OAAO;AAGrD,QACE,WAAW,SACX,EAAE,gBAAgB,aAClB,CAAC,YAAY,QAAQ,IAAI,cAAc,GACvC;AACA,kBAAY,QAAQ,IAAI,gBAAgB,kBAAkB;AAAA,IAC5D;AAEA,QAAI,YAAY,QAAQ,IAAI,cAAc,MAAM,qCAAqC;AACnF,kBAAY,OAAO,WACf,mCAAqB,MAAuC;AAAA,QAC1D,YAAY;AAAA,MACd,CAAC,IACD;AAAA,IACN,WAAW,YAAY,QAAQ,IAAI,cAAc,MAAM,sBAAsB,MAAM;AACjF,kBAAY,OAAO,OAAO,SAAS,WAAW,OAAO,KAAK,UAAU,IAAI;AAAA,IAC1E;AAEA,UAAM,iBAAiB,YAAqC;AAC1D,YAAM,aAAa,IAAI,gBAAgB;AACvC,YAAM,YAAY,YACd,WAAW,MAAM;AACf,mBAAW,MAAM;AAAA,MACnB,GAAG,SAAS,IACZ;AAEJ,UAAI;AACJ,YAAM,YAA4B;AAAA,QAChC,GAAG;AAAA,QACH,aAAa;AAAA,QACb,QAAQ;AAAA,MACV;AACA,UAAI;AACF,mBAAW,MAAM,MAAM,KAAK,SAAS;AAErC,YAAI,UAAW,cAAa,SAAS;AAGrC,YAAI,UAAqC;AAEzC,YAAI,SAAS,WAAW,KAAK;AAC3B,oBAAU;AAAA,QACZ,OAAO;AACL,cAAI;AACF,kBAAM,OAAO,MAAM,SAAS,KAAK;AACjC,sBAAU;AAAA,UACZ,QAAQ;AAEN,sBAAU,EAAE,UAAU,CAAC,EAAO;AAAA,UAChC;AAAA,QACF;AAEA,cAAM,cAAc;AACpB,oBAAY,UAAU;AAGtB,cAAM,KAAK,sBAAsB,WAAW;AAE5C,eAAO;AAAA,MACT,SAAS,OAAY;AACnB,YAAI,UAAW,cAAa,SAAS;AAErC,YAAI,MAAM,SAAS,cAAc;AAC/B,gBAAM,IAAI,aAAa;AAAA,QACzB;AAEA,cAAM,IAAI,aAAa,KAAK,KAAK;AAAA,MACnC;AAAA,IACF;AAEA,WAAO,KAAK;AAAA,MAAiB;AAAA,MAAgB,CAAC,OAAO,YACnD,KAAK;AAAA,QACH;AAAA,QACA;AAAA,QACA;AAAA,QACA,cAAc,aAAa,OAAO,cAAc,eAAe,UAAU,SAAS,IAAI;AAAA,MACxF;AAAA,IACF;AAAA,EACF;AACF;AAEO,MAAM,gBAAgB,IAAI,cAAc;","names":["buildUrlUtil"]}
|
|
@@ -0,0 +1,38 @@
|
|
|
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
|
+
var events_exports = {};
|
|
20
|
+
__export(events_exports, {
|
|
21
|
+
eventBus: () => eventBus,
|
|
22
|
+
events: () => events
|
|
23
|
+
});
|
|
24
|
+
module.exports = __toCommonJS(events_exports);
|
|
25
|
+
var import_eventBus = require("@tern-secure/shared/eventBus");
|
|
26
|
+
const events = {
|
|
27
|
+
UserChanged: "user:userChanged",
|
|
28
|
+
UserSignOut: "user:userSignOut",
|
|
29
|
+
SessionChanged: "session:sessionChanged",
|
|
30
|
+
TokenRefreshed: "token:tokenRefreshed"
|
|
31
|
+
};
|
|
32
|
+
const eventBus = (0, import_eventBus.createEventBus)();
|
|
33
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
34
|
+
0 && (module.exports = {
|
|
35
|
+
eventBus,
|
|
36
|
+
events
|
|
37
|
+
});
|
|
38
|
+
//# sourceMappingURL=events.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/instance/events.ts"],"sourcesContent":["import { createEventBus } from \"@tern-secure/shared/eventBus\";\nimport type { TernSecureUser } from \"@tern-secure/types\";\nimport type { IdTokenResult } from \"firebase/auth\";\n\nexport const events = {\n UserChanged: \"user:userChanged\",\n UserSignOut: \"user:userSignOut\",\n SessionChanged: \"session:sessionChanged\",\n TokenRefreshed: \"token:tokenRefreshed\",\n} as const;\n\ntype TokenUpdatePayload = { token: IdTokenResult | null };\n\n\ntype InternalEvents = {\n [events.UserChanged]: TernSecureUser | null;\n [events.UserSignOut]: null;\n [events.SessionChanged]: null;\n [events.TokenRefreshed]: TokenUpdatePayload;\n};\n\nexport const eventBus = createEventBus<InternalEvents>();\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,sBAA+B;AAIxB,MAAM,SAAS;AAAA,EACpB,aAAa;AAAA,EACb,aAAa;AAAA,EACb,gBAAgB;AAAA,EAChB,gBAAgB;AAClB;AAYO,MAAM,eAAW,gCAA+B;","names":[]}
|
|
@@ -0,0 +1,89 @@
|
|
|
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
|
+
var AuthCookieManager_exports = {};
|
|
20
|
+
__export(AuthCookieManager_exports, {
|
|
21
|
+
AuthCookieManager: () => AuthCookieManager
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(AuthCookieManager_exports);
|
|
24
|
+
var import_cookie = require("@tern-secure/shared/cookie");
|
|
25
|
+
const CSRF_COOKIE_NAME = "_session_terncf";
|
|
26
|
+
const CSRF_COOKIE_OPTIONS = {
|
|
27
|
+
secure: true,
|
|
28
|
+
sameSite: "strict",
|
|
29
|
+
expires: 1 / 24
|
|
30
|
+
//1 hour
|
|
31
|
+
};
|
|
32
|
+
class AuthCookieManager {
|
|
33
|
+
csrfCookieHandler = (0, import_cookie.cookieHandler)(CSRF_COOKIE_NAME);
|
|
34
|
+
constructor() {
|
|
35
|
+
this.ensureCSRFToken();
|
|
36
|
+
}
|
|
37
|
+
generateCSRFToken() {
|
|
38
|
+
const array = new Uint8Array(32);
|
|
39
|
+
crypto.getRandomValues(array);
|
|
40
|
+
return Array.from(array, (byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
41
|
+
}
|
|
42
|
+
ensureCSRFToken() {
|
|
43
|
+
let ctoken = this.getCSRFToken();
|
|
44
|
+
if (!ctoken) {
|
|
45
|
+
ctoken = this.generateCSRFToken();
|
|
46
|
+
this.setCSRFToken({ token: ctoken });
|
|
47
|
+
}
|
|
48
|
+
return ctoken;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Set CSRFcookie
|
|
52
|
+
*/
|
|
53
|
+
setCSRFToken(token) {
|
|
54
|
+
try {
|
|
55
|
+
if (token.token) {
|
|
56
|
+
this.csrfCookieHandler.set(token.token, CSRF_COOKIE_OPTIONS);
|
|
57
|
+
}
|
|
58
|
+
} catch (error) {
|
|
59
|
+
console.error("Failed to set CSRF token:", error);
|
|
60
|
+
throw new Error("Unable to store CSRF token");
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Get CSRF token from cookies
|
|
65
|
+
*/
|
|
66
|
+
getCSRFToken() {
|
|
67
|
+
try {
|
|
68
|
+
return this.csrfCookieHandler.get();
|
|
69
|
+
} catch (error) {
|
|
70
|
+
console.error("Failed to get CSRF token:", error);
|
|
71
|
+
return void 0;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Clear all authentication cookies
|
|
76
|
+
*/
|
|
77
|
+
clearAuth() {
|
|
78
|
+
try {
|
|
79
|
+
this.csrfCookieHandler.remove();
|
|
80
|
+
} catch (error) {
|
|
81
|
+
console.error("Failed to clear auth cookies:", error);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
86
|
+
0 && (module.exports = {
|
|
87
|
+
AuthCookieManager
|
|
88
|
+
});
|
|
89
|
+
//# sourceMappingURL=AuthCookieManager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/resources/AuthCookieManager.ts"],"sourcesContent":["import { \n type CookieAttributes,\n cookieHandler} from '@tern-secure/shared/cookie';\n\nconst CSRF_COOKIE_NAME = '_session_terncf';\n\ntype CSRFToken = {\n token: string | null;\n}\n\ntype CookieOptions = CookieAttributes\n\nconst CSRF_COOKIE_OPTIONS: CookieOptions = {\n secure: true,\n sameSite: 'strict',\n expires: 1 / 24 //1 hour\n};\n\n/**\n * AuthCookieManger class for managing authentication state and cookies\n */\nexport class AuthCookieManager {\n private readonly csrfCookieHandler = cookieHandler(CSRF_COOKIE_NAME);\n\n constructor() {\n this.ensureCSRFToken();\n }\n\n \n private generateCSRFToken(): string {\n const array = new Uint8Array(32);\n crypto.getRandomValues(array);\n return Array.from(array, (byte) => byte.toString(16).padStart(2, '0')).join('');\n }\n\n private ensureCSRFToken(): string {\n let ctoken = this.getCSRFToken();\n if (!ctoken) {\n ctoken = this.generateCSRFToken();\n this.setCSRFToken({ token: ctoken });\n }\n return ctoken;\n }\n \n\n /**\n * Set CSRFcookie\n */\n\n setCSRFToken(token: CSRFToken): void {\n try {\n if (token.token) {\n this.csrfCookieHandler.set(token.token, CSRF_COOKIE_OPTIONS);\n }\n } catch (error) {\n console.error('Failed to set CSRF token:', error);\n throw new Error('Unable to store CSRF token');\n }\n }\n \n\n /**\n * Get CSRF token from cookies\n */\n getCSRFToken(): string | undefined {\n try {\n return this.csrfCookieHandler.get();\n } catch (error) {\n console.error('Failed to get CSRF token:', error);\n return undefined;\n }\n }\n\n\n /**\n * Clear all authentication cookies\n */\n clearAuth(): void {\n try {\n this.csrfCookieHandler.remove();\n } catch (error) {\n console.error('Failed to clear auth cookies:', error);\n }\n }\n}"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAEsB;AAEtB,MAAM,mBAAmB;AAQzB,MAAM,sBAAqC;AAAA,EACzC,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,SAAS,IAAI;AAAA;AACf;AAKO,MAAM,kBAAkB;AAAA,EACZ,wBAAoB,6BAAc,gBAAgB;AAAA,EAEnE,cAAc;AACZ,SAAK,gBAAgB;AAAA,EACvB;AAAA,EAGQ,oBAA4B;AAClC,UAAM,QAAQ,IAAI,WAAW,EAAE;AAC/B,WAAO,gBAAgB,KAAK;AAC5B,WAAO,MAAM,KAAK,OAAO,CAAC,SAAS,KAAK,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG,CAAC,EAAE,KAAK,EAAE;AAAA,EAChF;AAAA,EAEQ,kBAA0B;AAChC,QAAI,SAAS,KAAK,aAAa;AAC/B,QAAI,CAAC,QAAQ;AACX,eAAS,KAAK,kBAAkB;AAChC,WAAK,aAAa,EAAE,OAAO,OAAO,CAAC;AAAA,IACrC;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAOA,aAAa,OAAwB;AACnC,QAAI;AACF,UAAI,MAAM,OAAO;AACf,aAAK,kBAAkB,IAAI,MAAM,OAAO,mBAAmB;AAAA,MAC7D;AAAA,IACF,SAAS,OAAO;AACd,cAAQ,MAAM,6BAA6B,KAAK;AAChD,YAAM,IAAI,MAAM,4BAA4B;AAAA,IAC9C;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAMA,eAAmC;AACjC,QAAI;AACF,aAAO,KAAK,kBAAkB,IAAI;AAAA,IACpC,SAAS,OAAO;AACd,cAAQ,MAAM,6BAA6B,KAAK;AAChD,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAMA,YAAkB;AAChB,QAAI;AACF,WAAK,kBAAkB,OAAO;AAAA,IAChC,SAAS,OAAO;AACd,cAAQ,MAAM,iCAAiC,KAAK;AAAA,IACtD;AAAA,EACF;AACF;","names":[]}
|
|
@@ -0,0 +1,125 @@
|
|
|
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
|
+
var Base_exports = {};
|
|
20
|
+
__export(Base_exports, {
|
|
21
|
+
TernSecureBase: () => TernSecureBase
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(Base_exports);
|
|
24
|
+
var import_browser = require("@tern-secure/shared/browser");
|
|
25
|
+
var import_coreApiClient = require("../instance/coreApiClient");
|
|
26
|
+
var import_Error = require("./Error");
|
|
27
|
+
class TernSecureBase {
|
|
28
|
+
static ternsecure;
|
|
29
|
+
static get apiUrl() {
|
|
30
|
+
return TernSecureBase.ternsecure.getApiUrl();
|
|
31
|
+
}
|
|
32
|
+
static get authCookieManager() {
|
|
33
|
+
return this.ternsecure.authCookieManager();
|
|
34
|
+
}
|
|
35
|
+
get authCookieManager() {
|
|
36
|
+
return TernSecureBase.authCookieManager;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Core method to fetch data from API endpoints using coreApiClient
|
|
40
|
+
* This method handles the complete request lifecycle including error handling
|
|
41
|
+
*/
|
|
42
|
+
static async fetchFromCoreApi(requestInit) {
|
|
43
|
+
var _a;
|
|
44
|
+
if (!TernSecureBase.apiUrl) {
|
|
45
|
+
throw new Error("API URL is not defined. Make sure TernSecureAuth is properly initialized.");
|
|
46
|
+
}
|
|
47
|
+
const apiUrl = this.ternsecure.apiUrl;
|
|
48
|
+
let apiResponse;
|
|
49
|
+
try {
|
|
50
|
+
apiResponse = await import_coreApiClient.coreApiClient.request(requestInit, { apiUrl });
|
|
51
|
+
} catch (error) {
|
|
52
|
+
if (!(0, import_browser.isValidBrowserOnline)()) {
|
|
53
|
+
console.warn(error);
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
throw error;
|
|
57
|
+
}
|
|
58
|
+
const { payload, status, statusText, headers } = apiResponse;
|
|
59
|
+
if (headers) {
|
|
60
|
+
const country = headers.get("x-country");
|
|
61
|
+
this.ternsecure.__internal_setCountry(country ? country.toLowerCase() : null);
|
|
62
|
+
}
|
|
63
|
+
if (status >= 200 && status <= 299) {
|
|
64
|
+
return payload;
|
|
65
|
+
}
|
|
66
|
+
if (status >= 400) {
|
|
67
|
+
const errors = payload == null ? void 0 : payload.errors;
|
|
68
|
+
const message = (_a = errors == null ? void 0 : errors[0]) == null ? void 0 : _a.message;
|
|
69
|
+
const apiResponseOptions = {
|
|
70
|
+
data: errors,
|
|
71
|
+
status
|
|
72
|
+
};
|
|
73
|
+
if (status === 429 && headers) {
|
|
74
|
+
const retryAfter = headers.get("retry-After");
|
|
75
|
+
if (retryAfter) {
|
|
76
|
+
const value = parseInt(retryAfter, 10);
|
|
77
|
+
if (!isNaN(value)) {
|
|
78
|
+
apiResponseOptions.retryAfter = value;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
throw new import_Error.TernSecureAPIResponseError(message || statusText, apiResponseOptions);
|
|
83
|
+
}
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Convenience method for making POST requests
|
|
88
|
+
*/
|
|
89
|
+
static async basePost(params) {
|
|
90
|
+
return this.fetchFromCoreApi({ ...params, method: "POST" });
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Instance method to fetch data from API endpoints
|
|
94
|
+
*/
|
|
95
|
+
async fetchFromCoreApi(requestInit) {
|
|
96
|
+
return TernSecureBase.fetchFromCoreApi(requestInit);
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Instance method for making POST requests
|
|
100
|
+
*/
|
|
101
|
+
async basePost(params) {
|
|
102
|
+
return TernSecureBase.basePost(params);
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Protected instance method for making POST requests with specific path and body
|
|
106
|
+
* This is designed to be used by child classes like SignIn
|
|
107
|
+
*/
|
|
108
|
+
async _post(params) {
|
|
109
|
+
return this.basePost({
|
|
110
|
+
path: params.path,
|
|
111
|
+
body: params.body
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
static async makeApiRequest(requestInit) {
|
|
115
|
+
return this.fetchFromCoreApi(requestInit);
|
|
116
|
+
}
|
|
117
|
+
async makeApiRequest(requestInit) {
|
|
118
|
+
return this.fetchFromCoreApi(requestInit);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
122
|
+
0 && (module.exports = {
|
|
123
|
+
TernSecureBase
|
|
124
|
+
});
|
|
125
|
+
//# sourceMappingURL=Base.js.map
|