@workos-inc/node 8.0.0-rc.2 → 8.0.0-rc.3
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/lib/cjs/client/sso.cjs +2 -2
- package/lib/cjs/client/sso.cjs.map +1 -1
- package/lib/cjs/client/user-management.cjs +2 -2
- package/lib/cjs/client/user-management.cjs.map +1 -1
- package/lib/cjs/common/exceptions/unprocessable-entity.exception.cjs +1 -12
- package/lib/cjs/common/exceptions/unprocessable-entity.exception.cjs.map +1 -1
- package/lib/cjs/common/net/fetch-client.cjs +4 -4
- package/lib/cjs/common/net/fetch-client.cjs.map +1 -1
- package/lib/cjs/common/net/http-client.cjs +4 -1
- package/lib/cjs/common/net/http-client.cjs.map +1 -1
- package/lib/cjs/common/net/http-client.d.cts +1 -0
- package/lib/cjs/common/utils/leb128.cjs +101 -0
- package/lib/cjs/common/utils/leb128.cjs.map +1 -0
- package/lib/cjs/common/utils/leb128.d.cts +24 -0
- package/lib/cjs/common/utils/query-string.cjs +66 -0
- package/lib/cjs/common/utils/query-string.cjs.map +1 -0
- package/lib/cjs/common/utils/query-string.d.cts +11 -0
- package/lib/cjs/vault/vault.cjs +3 -3
- package/lib/cjs/vault/vault.cjs.map +1 -1
- package/lib/cjs/widgets/interfaces/get-token.cjs.map +1 -1
- package/lib/cjs/widgets/interfaces/get-token.d.cts +1 -1
- package/lib/cjs/workos.cjs +1 -1
- package/lib/cjs/workos.cjs.map +1 -1
- package/lib/esm/client/sso.js +1 -1
- package/lib/esm/client/sso.js.map +1 -1
- package/lib/esm/client/user-management.js +1 -1
- package/lib/esm/client/user-management.js.map +1 -1
- package/lib/esm/common/exceptions/unprocessable-entity.exception.js +1 -2
- package/lib/esm/common/exceptions/unprocessable-entity.exception.js.map +1 -1
- package/lib/esm/common/net/fetch-client.js +4 -4
- package/lib/esm/common/net/fetch-client.js.map +1 -1
- package/lib/esm/common/net/http-client.d.ts +1 -0
- package/lib/esm/common/net/http-client.js +4 -1
- package/lib/esm/common/net/http-client.js.map +1 -1
- package/lib/esm/common/utils/leb128.d.ts +24 -0
- package/lib/esm/common/utils/leb128.js +77 -0
- package/lib/esm/common/utils/leb128.js.map +1 -0
- package/lib/esm/common/utils/query-string.d.ts +11 -0
- package/lib/esm/common/utils/query-string.js +43 -0
- package/lib/esm/common/utils/query-string.js.map +1 -0
- package/lib/esm/vault/vault.js +1 -1
- package/lib/esm/vault/vault.js.map +1 -1
- package/lib/esm/widgets/interfaces/get-token.d.ts +1 -1
- package/lib/esm/widgets/interfaces/get-token.js.map +1 -1
- package/lib/esm/workos.js +1 -1
- package/lib/esm/workos.js.map +1 -1
- package/package.json +2 -6
- package/lib/cjs/client/utils.cjs +0 -49
- package/lib/cjs/client/utils.cjs.map +0 -1
- package/lib/cjs/client/utils.d.cts +0 -7
- package/lib/cjs/common/interfaces/delete-options.interface.cjs +0 -17
- package/lib/cjs/common/interfaces/delete-options.interface.cjs.map +0 -1
- package/lib/cjs/common/interfaces/delete-options.interface.d.cts +0 -8
- package/lib/cjs/workos-BcNRiAbw.d.cts +0 -398
- package/lib/cjs/workos-BjsIEalN.d.cts +0 -399
- package/lib/cjs/workos-ZPbUKdml.d.cts +0 -397
- package/lib/esm/client/utils.d.ts +0 -7
- package/lib/esm/client/utils.js +0 -16
- package/lib/esm/client/utils.js.map +0 -1
package/lib/cjs/client/sso.cjs
CHANGED
|
@@ -22,7 +22,7 @@ __export(sso_exports, {
|
|
|
22
22
|
getAuthorizationUrl: () => getAuthorizationUrl
|
|
23
23
|
});
|
|
24
24
|
module.exports = __toCommonJS(sso_exports);
|
|
25
|
-
var
|
|
25
|
+
var import_query_string = require('../common/utils/query-string.cjs');
|
|
26
26
|
function getAuthorizationUrl(options) {
|
|
27
27
|
const {
|
|
28
28
|
connection,
|
|
@@ -42,7 +42,7 @@ function getAuthorizationUrl(options) {
|
|
|
42
42
|
`Incomplete arguments. Need to specify either a 'connection', 'organization', or 'provider'.`
|
|
43
43
|
);
|
|
44
44
|
}
|
|
45
|
-
const query = (0,
|
|
45
|
+
const query = (0, import_query_string.toQueryString)({
|
|
46
46
|
connection,
|
|
47
47
|
organization,
|
|
48
48
|
domain_hint: domainHint,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/client/sso.ts"],"sourcesContent":["import { toQueryString } from '
|
|
1
|
+
{"version":3,"sources":["../../../src/client/sso.ts"],"sourcesContent":["import { toQueryString } from '../common/utils/query-string';\nimport type { SSOAuthorizationURLOptions as BaseSSOAuthorizationURLOptions } from '../sso/interfaces';\n\n// Extend the base options to include baseURL for internal use\nexport type SSOAuthorizationURLOptions = BaseSSOAuthorizationURLOptions & {\n baseURL?: string;\n};\n\n/**\n * Generates the authorization URL for SSO authentication.\n * Does not require an API key, suitable for OAuth client operations.\n *\n * @param options - SSO authorization URL options\n * @returns The authorization URL as a string\n * @throws Error if required arguments are missing\n */\nexport function getAuthorizationUrl(\n options: SSOAuthorizationURLOptions,\n): string {\n const {\n connection,\n clientId,\n domainHint,\n loginHint,\n organization,\n provider,\n providerQueryParams,\n providerScopes,\n redirectUri,\n state,\n baseURL = 'https://api.workos.com',\n } = options;\n\n if (!provider && !connection && !organization) {\n throw new Error(\n `Incomplete arguments. Need to specify either a 'connection', 'organization', or 'provider'.`,\n );\n }\n\n const query = toQueryString({\n connection,\n organization,\n domain_hint: domainHint,\n login_hint: loginHint,\n provider,\n provider_query_params: providerQueryParams,\n provider_scopes: providerScopes,\n client_id: clientId,\n redirect_uri: redirectUri,\n response_type: 'code',\n state,\n });\n\n return `${baseURL}/sso/authorize?${query}`;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,0BAA8B;AAgBvB,SAAS,oBACd,SACQ;AACR,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,UAAU;AAAA,EACZ,IAAI;AAEJ,MAAI,CAAC,YAAY,CAAC,cAAc,CAAC,cAAc;AAC7C,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,QAAM,YAAQ,mCAAc;AAAA,IAC1B;AAAA,IACA;AAAA,IACA,aAAa;AAAA,IACb,YAAY;AAAA,IACZ;AAAA,IACA,uBAAuB;AAAA,IACvB,iBAAiB;AAAA,IACjB,WAAW;AAAA,IACX,cAAc;AAAA,IACd,eAAe;AAAA,IACf;AAAA,EACF,CAAC;AAED,SAAO,GAAG,OAAO,kBAAkB,KAAK;AAC1C;AAtCgB;","names":[]}
|
|
@@ -24,7 +24,7 @@ __export(user_management_exports, {
|
|
|
24
24
|
getLogoutUrl: () => getLogoutUrl
|
|
25
25
|
});
|
|
26
26
|
module.exports = __toCommonJS(user_management_exports);
|
|
27
|
-
var
|
|
27
|
+
var import_query_string = require('../common/utils/query-string.cjs');
|
|
28
28
|
function getAuthorizationUrl(options) {
|
|
29
29
|
const {
|
|
30
30
|
connectionId,
|
|
@@ -53,7 +53,7 @@ function getAuthorizationUrl(options) {
|
|
|
53
53
|
`'screenHint' is only supported for 'authkit' provider`
|
|
54
54
|
);
|
|
55
55
|
}
|
|
56
|
-
const query = (0,
|
|
56
|
+
const query = (0, import_query_string.toQueryString)({
|
|
57
57
|
connection_id: connectionId,
|
|
58
58
|
code_challenge: codeChallenge,
|
|
59
59
|
code_challenge_method: codeChallengeMethod,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/client/user-management.ts"],"sourcesContent":["import { toQueryString } from '
|
|
1
|
+
{"version":3,"sources":["../../../src/client/user-management.ts"],"sourcesContent":["import { toQueryString } from '../common/utils/query-string';\n\n// Re-export necessary interfaces for client use\nexport interface AuthorizationURLOptions {\n clientId: string;\n codeChallenge?: string;\n codeChallengeMethod?: 'S256';\n connectionId?: string;\n organizationId?: string;\n domainHint?: string;\n loginHint?: string;\n provider?: string;\n providerQueryParams?: Record<string, string | boolean | number>;\n providerScopes?: string[];\n prompt?: string;\n redirectUri: string;\n state?: string;\n screenHint?: 'sign-up' | 'sign-in';\n}\n\nexport interface LogoutURLOptions {\n sessionId: string;\n returnTo?: string;\n}\n\n/**\n * Generates the authorization URL for OAuth client authentication.\n * Suitable for PKCE flows and other OAuth client operations that don't require an API key.\n *\n * @param options - Authorization URL options\n * @returns The authorization URL as a string\n * @throws TypeError if required arguments are missing\n */\nexport function getAuthorizationUrl(\n options: AuthorizationURLOptions & { baseURL?: string },\n): string {\n const {\n connectionId,\n codeChallenge,\n codeChallengeMethod,\n clientId,\n domainHint,\n loginHint,\n organizationId,\n provider,\n providerQueryParams,\n providerScopes,\n prompt,\n redirectUri,\n state,\n screenHint,\n baseURL = 'https://api.workos.com',\n } = options;\n\n if (!provider && !connectionId && !organizationId) {\n throw new TypeError(\n `Incomplete arguments. Need to specify either a 'connectionId', 'organizationId', or 'provider'.`,\n );\n }\n\n if (provider !== 'authkit' && screenHint) {\n throw new TypeError(\n `'screenHint' is only supported for 'authkit' provider`,\n );\n }\n\n const query = toQueryString({\n connection_id: connectionId,\n code_challenge: codeChallenge,\n code_challenge_method: codeChallengeMethod,\n organization_id: organizationId,\n domain_hint: domainHint,\n login_hint: loginHint,\n provider,\n provider_query_params: providerQueryParams,\n provider_scopes: providerScopes,\n prompt,\n client_id: clientId,\n redirect_uri: redirectUri,\n response_type: 'code',\n state,\n screen_hint: screenHint,\n });\n\n return `${baseURL}/user_management/authorize?${query}`;\n}\n\n/**\n * Generates the logout URL for ending a user session.\n * This method is safe to use in browser environments as it doesn't require an API key.\n *\n * @param options - Logout URL options\n * @returns The logout URL as a string\n * @throws TypeError if sessionId is not provided\n */\nexport function getLogoutUrl(\n options: LogoutURLOptions & { baseURL?: string },\n): string {\n const { sessionId, returnTo, baseURL = 'https://api.workos.com' } = options;\n\n if (!sessionId) {\n throw new TypeError(`Incomplete arguments. Need to specify 'sessionId'.`);\n }\n\n const url = new URL('/user_management/sessions/logout', baseURL);\n\n url.searchParams.set('session_id', sessionId);\n if (returnTo) {\n url.searchParams.set('return_to', returnTo);\n }\n\n return url.toString();\n}\n\n/**\n * Gets the JWKS (JSON Web Key Set) URL for a given client ID.\n * Does not require an API key, returns the public JWKS endpoint.\n *\n * @param clientId - The WorkOS client ID\n * @param baseURL - Optional base URL for the API (defaults to https://api.workos.com)\n * @returns The JWKS URL as a string\n * @throws TypeError if clientId is not provided\n */\nexport function getJwksUrl(\n clientId: string,\n baseURL = 'https://api.workos.com',\n): string {\n if (!clientId) {\n throw new TypeError('clientId must be a valid clientId');\n }\n\n return `${baseURL}/sso/jwks/${clientId}`;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,0BAA8B;AAiCvB,SAAS,oBACd,SACQ;AACR,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,UAAU;AAAA,EACZ,IAAI;AAEJ,MAAI,CAAC,YAAY,CAAC,gBAAgB,CAAC,gBAAgB;AACjD,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,MAAI,aAAa,aAAa,YAAY;AACxC,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,QAAM,YAAQ,mCAAc;AAAA,IAC1B,eAAe;AAAA,IACf,gBAAgB;AAAA,IAChB,uBAAuB;AAAA,IACvB,iBAAiB;AAAA,IACjB,aAAa;AAAA,IACb,YAAY;AAAA,IACZ;AAAA,IACA,uBAAuB;AAAA,IACvB,iBAAiB;AAAA,IACjB;AAAA,IACA,WAAW;AAAA,IACX,cAAc;AAAA,IACd,eAAe;AAAA,IACf;AAAA,IACA,aAAa;AAAA,EACf,CAAC;AAED,SAAO,GAAG,OAAO,8BAA8B,KAAK;AACtD;AApDgB;AA8DT,SAAS,aACd,SACQ;AACR,QAAM,EAAE,WAAW,UAAU,UAAU,yBAAyB,IAAI;AAEpE,MAAI,CAAC,WAAW;AACd,UAAM,IAAI,UAAU,oDAAoD;AAAA,EAC1E;AAEA,QAAM,MAAM,IAAI,IAAI,oCAAoC,OAAO;AAE/D,MAAI,aAAa,IAAI,cAAc,SAAS;AAC5C,MAAI,UAAU;AACZ,QAAI,aAAa,IAAI,aAAa,QAAQ;AAAA,EAC5C;AAEA,SAAO,IAAI,SAAS;AACtB;AAjBgB;AA4BT,SAAS,WACd,UACA,UAAU,0BACF;AACR,MAAI,CAAC,UAAU;AACb,UAAM,IAAI,UAAU,mCAAmC;AAAA,EACzD;AAEA,SAAO,GAAG,OAAO,aAAa,QAAQ;AACxC;AATgB;","names":[]}
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __create = Object.create;
|
|
3
2
|
var __defProp = Object.defineProperty;
|
|
4
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
7
5
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
6
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
9
7
|
var __export = (target, all) => {
|
|
@@ -18,21 +16,12 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
18
16
|
}
|
|
19
17
|
return to;
|
|
20
18
|
};
|
|
21
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
22
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
23
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
24
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
25
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
26
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
27
|
-
mod
|
|
28
|
-
));
|
|
29
19
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
30
20
|
var unprocessable_entity_exception_exports = {};
|
|
31
21
|
__export(unprocessable_entity_exception_exports, {
|
|
32
22
|
UnprocessableEntityException: () => UnprocessableEntityException
|
|
33
23
|
});
|
|
34
24
|
module.exports = __toCommonJS(unprocessable_entity_exception_exports);
|
|
35
|
-
var import_pluralize = __toESM(require("pluralize"), 1);
|
|
36
25
|
class UnprocessableEntityException extends Error {
|
|
37
26
|
static {
|
|
38
27
|
__name(this, "UnprocessableEntityException");
|
|
@@ -57,7 +46,7 @@ class UnprocessableEntityException extends Error {
|
|
|
57
46
|
this.code = code;
|
|
58
47
|
}
|
|
59
48
|
if (errors) {
|
|
60
|
-
const requirement =
|
|
49
|
+
const requirement = errors.length === 1 ? "requirement" : "requirements";
|
|
61
50
|
this.message = `The following ${requirement} must be met:
|
|
62
51
|
`;
|
|
63
52
|
for (const { code: code2 } of errors) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/common/exceptions/unprocessable-entity.exception.ts"],"sourcesContent":["import
|
|
1
|
+
{"version":3,"sources":["../../../../src/common/exceptions/unprocessable-entity.exception.ts"],"sourcesContent":["import { UnprocessableEntityError } from '../interfaces';\nimport { RequestException } from '../interfaces/request-exception.interface';\n\nexport class UnprocessableEntityException\n extends Error\n implements RequestException\n{\n readonly status = 422;\n readonly name = 'UnprocessableEntityException';\n readonly message: string = 'Unprocessable entity';\n readonly code?: string;\n readonly requestID: string;\n\n constructor({\n code,\n errors,\n message,\n requestID,\n }: {\n code?: string;\n errors?: UnprocessableEntityError[];\n message?: string;\n requestID: string;\n }) {\n super();\n\n this.requestID = requestID;\n\n if (message) {\n this.message = message;\n }\n\n if (code) {\n this.code = code;\n }\n\n if (errors) {\n const requirement = errors.length === 1 ? 'requirement' : 'requirements';\n\n this.message = `The following ${requirement} must be met:\\n`;\n\n for (const { code } of errors) {\n this.message = this.message.concat(`\\t${code}\\n`);\n }\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAGO,MAAM,qCACH,MAEV;AAAA,EANA,OAMA;AAAA;AAAA;AAAA,EACW,SAAS;AAAA,EACT,OAAO;AAAA,EACP,UAAkB;AAAA,EAClB;AAAA,EACA;AAAA,EAET,YAAY;AAAA,IACV;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,GAKG;AACD,UAAM;AAEN,SAAK,YAAY;AAEjB,QAAI,SAAS;AACX,WAAK,UAAU;AAAA,IACjB;AAEA,QAAI,MAAM;AACR,WAAK,OAAO;AAAA,IACd;AAEA,QAAI,QAAQ;AACV,YAAM,cAAc,OAAO,WAAW,IAAI,gBAAgB;AAE1D,WAAK,UAAU,iBAAiB,WAAW;AAAA;AAE3C,iBAAW,EAAE,MAAAA,MAAK,KAAK,QAAQ;AAC7B,aAAK,UAAU,KAAK,QAAQ,OAAO,IAAKA,KAAI;AAAA,CAAI;AAAA,MAClD;AAAA,IACF;AAAA,EACF;AACF;","names":["code"]}
|
|
@@ -55,7 +55,7 @@ class FetchHttpClient extends import_http_client2.HttpClient {
|
|
|
55
55
|
path,
|
|
56
56
|
options.params
|
|
57
57
|
);
|
|
58
|
-
if (
|
|
58
|
+
if (import_http_client2.HttpClient.isPathRetryable(path)) {
|
|
59
59
|
return await this.fetchRequestWithRetry(
|
|
60
60
|
resourceURL,
|
|
61
61
|
"GET",
|
|
@@ -72,7 +72,7 @@ class FetchHttpClient extends import_http_client2.HttpClient {
|
|
|
72
72
|
path,
|
|
73
73
|
options.params
|
|
74
74
|
);
|
|
75
|
-
if (
|
|
75
|
+
if (import_http_client2.HttpClient.isPathRetryable(path)) {
|
|
76
76
|
return await this.fetchRequestWithRetry(
|
|
77
77
|
resourceURL,
|
|
78
78
|
"POST",
|
|
@@ -100,7 +100,7 @@ class FetchHttpClient extends import_http_client2.HttpClient {
|
|
|
100
100
|
path,
|
|
101
101
|
options.params
|
|
102
102
|
);
|
|
103
|
-
if (
|
|
103
|
+
if (import_http_client2.HttpClient.isPathRetryable(path)) {
|
|
104
104
|
return await this.fetchRequestWithRetry(
|
|
105
105
|
resourceURL,
|
|
106
106
|
"PUT",
|
|
@@ -128,7 +128,7 @@ class FetchHttpClient extends import_http_client2.HttpClient {
|
|
|
128
128
|
path,
|
|
129
129
|
options.params
|
|
130
130
|
);
|
|
131
|
-
if (
|
|
131
|
+
if (import_http_client2.HttpClient.isPathRetryable(path)) {
|
|
132
132
|
return await this.fetchRequestWithRetry(
|
|
133
133
|
resourceURL,
|
|
134
134
|
"DELETE",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/common/net/fetch-client.ts"],"sourcesContent":["import {\n HttpClientInterface,\n HttpClientResponseInterface,\n RequestHeaders,\n RequestOptions,\n ResponseHeaders,\n} from '../interfaces/http-client.interface';\nimport { HttpClient, HttpClientError, HttpClientResponse } from './http-client';\nimport { ParseError } from '../exceptions/parse-error';\n\ninterface FetchHttpClientOptions extends RequestInit {\n timeout?: number;\n}\n\nconst DEFAULT_FETCH_TIMEOUT = 60_000; // 60 seconds\nexport class FetchHttpClient extends HttpClient implements HttpClientInterface {\n private readonly _fetchFn;\n\n constructor(\n readonly baseURL: string,\n readonly options?: FetchHttpClientOptions,\n fetchFn?: typeof fetch,\n ) {\n super(baseURL, options);\n\n // Default to global fetch if available\n if (!fetchFn) {\n if (!globalThis.fetch) {\n throw new Error(\n 'Fetch function not defined in the global scope and no replacement was provided.',\n );\n }\n fetchFn = globalThis.fetch;\n }\n\n this._fetchFn = fetchFn.bind(globalThis);\n }\n\n /** @override */\n getClientName(): string {\n return 'fetch';\n }\n\n async get(\n path: string,\n options: RequestOptions,\n ): Promise<HttpClientResponseInterface> {\n const resourceURL = HttpClient.getResourceURL(\n this.baseURL,\n path,\n options.params,\n );\n\n if (path.startsWith('/fga/')) {\n return await this.fetchRequestWithRetry(\n resourceURL,\n 'GET',\n null,\n options.headers,\n );\n } else {\n return await this.fetchRequest(resourceURL, 'GET', null, options.headers);\n }\n }\n\n async post<Entity = any>(\n path: string,\n entity: Entity,\n options: RequestOptions,\n ): Promise<HttpClientResponseInterface> {\n const resourceURL = HttpClient.getResourceURL(\n this.baseURL,\n path,\n options.params,\n );\n\n if (path.startsWith('/fga/')) {\n return await this.fetchRequestWithRetry(\n resourceURL,\n 'POST',\n HttpClient.getBody(entity),\n {\n ...HttpClient.getContentTypeHeader(entity),\n ...options.headers,\n },\n );\n } else {\n return await this.fetchRequest(\n resourceURL,\n 'POST',\n HttpClient.getBody(entity),\n {\n ...HttpClient.getContentTypeHeader(entity),\n ...options.headers,\n },\n );\n }\n }\n\n async put<Entity = any>(\n path: string,\n entity: Entity,\n options: RequestOptions,\n ): Promise<HttpClientResponseInterface> {\n const resourceURL = HttpClient.getResourceURL(\n this.baseURL,\n path,\n options.params,\n );\n\n if (path.startsWith('/fga/')) {\n return await this.fetchRequestWithRetry(\n resourceURL,\n 'PUT',\n HttpClient.getBody(entity),\n {\n ...HttpClient.getContentTypeHeader(entity),\n ...options.headers,\n },\n );\n } else {\n return await this.fetchRequest(\n resourceURL,\n 'PUT',\n HttpClient.getBody(entity),\n {\n ...HttpClient.getContentTypeHeader(entity),\n ...options.headers,\n },\n );\n }\n }\n\n async delete(\n path: string,\n options: RequestOptions,\n ): Promise<HttpClientResponseInterface> {\n const resourceURL = HttpClient.getResourceURL(\n this.baseURL,\n path,\n options.params,\n );\n\n if (path.startsWith('/fga/')) {\n return await this.fetchRequestWithRetry(\n resourceURL,\n 'DELETE',\n null,\n options.headers,\n );\n } else {\n return await this.fetchRequest(\n resourceURL,\n 'DELETE',\n null,\n options.headers,\n );\n }\n }\n\n private async fetchRequest(\n url: string,\n method: string,\n body?: any,\n headers?: RequestHeaders,\n ): Promise<HttpClientResponseInterface> {\n // For methods which expect payloads, we should always pass a body value\n // even when it is empty. Without this, some JS runtimes (eg. Deno) will\n // inject a second Content-Length header.\n const methodHasPayload =\n method === 'POST' || method === 'PUT' || method === 'PATCH';\n\n const requestBody = body || (methodHasPayload ? '' : undefined);\n\n const { 'User-Agent': userAgent } = (this.options?.headers ||\n {}) as RequestHeaders;\n\n // Access timeout from the options with default of 60 seconds\n const timeout = this.options?.timeout ?? DEFAULT_FETCH_TIMEOUT; // Default 60 seconds\n const abortController = new AbortController();\n const timeoutId = setTimeout(() => {\n abortController?.abort();\n }, timeout);\n\n try {\n const res = await this._fetchFn(url, {\n method,\n headers: {\n Accept: 'application/json, text/plain, */*',\n 'Content-Type': 'application/json',\n ...this.options?.headers,\n ...headers,\n 'User-Agent': this.addClientToUserAgent(\n (userAgent || 'workos-node').toString(),\n ),\n },\n body: requestBody,\n signal: abortController?.signal,\n });\n\n // Clear timeout if request completed successfully\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n\n if (!res.ok) {\n const requestID = res.headers.get('X-Request-ID') ?? '';\n const rawBody = await res.text();\n\n let responseJson: any;\n\n try {\n responseJson = JSON.parse(rawBody);\n } catch (error) {\n if (error instanceof SyntaxError) {\n throw new ParseError({\n message: error.message,\n rawBody,\n requestID,\n rawStatus: res.status,\n });\n }\n throw error;\n }\n\n throw new HttpClientError({\n message: res.statusText,\n response: {\n status: res.status,\n headers: res.headers,\n data: responseJson,\n },\n });\n }\n return new FetchHttpClientResponse(res);\n } catch (error) {\n // Clear timeout if request failed\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n\n // Handle timeout errors\n if (error instanceof Error && error.name === 'AbortError') {\n throw new HttpClientError({\n message: `Request timeout after ${timeout}ms`,\n response: {\n status: 408,\n headers: {},\n data: { error: 'Request timeout' },\n },\n });\n }\n\n throw error;\n }\n }\n\n private async fetchRequestWithRetry(\n url: string,\n method: string,\n body?: any,\n headers?: RequestHeaders,\n ): Promise<HttpClientResponseInterface> {\n let response: HttpClientResponseInterface;\n let retryAttempts = 1;\n\n const makeRequest = async (): Promise<HttpClientResponseInterface> => {\n let requestError: any = null;\n\n try {\n response = await this.fetchRequest(url, method, body, headers);\n } catch (e) {\n requestError = e;\n }\n\n if (this.shouldRetryRequest(requestError, retryAttempts)) {\n retryAttempts++;\n await this.sleep(retryAttempts);\n return makeRequest();\n }\n\n if (requestError != null) {\n throw requestError;\n }\n\n return response;\n };\n\n return makeRequest();\n }\n\n private shouldRetryRequest(requestError: any, retryAttempt: number): boolean {\n if (retryAttempt > this.MAX_RETRY_ATTEMPTS) {\n return false;\n }\n\n if (requestError != null) {\n if (requestError instanceof TypeError) {\n return true;\n }\n\n if (\n requestError instanceof HttpClientError &&\n this.RETRY_STATUS_CODES.includes(requestError.response.status)\n ) {\n return true;\n }\n }\n\n return false;\n }\n}\n\n// tslint:disable-next-line\nexport class FetchHttpClientResponse\n extends HttpClientResponse\n implements HttpClientResponseInterface\n{\n _res: Response;\n\n constructor(res: Response) {\n super(\n res.status,\n FetchHttpClientResponse._transformHeadersToObject(res.headers),\n );\n this._res = res;\n }\n\n getRawResponse(): Response {\n return this._res;\n }\n\n toJSON(): Promise<any> | null {\n const contentType = this._res.headers.get('content-type');\n const isJsonResponse = contentType?.includes('application/json');\n\n return isJsonResponse ? this._res.json() : null;\n }\n\n static _transformHeadersToObject(headers: Headers): ResponseHeaders {\n // Fetch uses a Headers instance so this must be converted to a barebones\n // JS object to meet the HttpClient interface.\n const headersObj: ResponseHeaders = {};\n for (const entry of Object.entries(headers)) {\n if (!Array.isArray(entry) || entry.length !== 2) {\n throw new Error(\n 'Response objects produced by the fetch function given to FetchHttpClient do not have an iterable headers map. Response#headers should be an iterable object.',\n );\n }\n\n headersObj[entry[0]] = entry[1];\n }\n\n return headersObj;\n }\n}\n"],"mappings":"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","names":["import_http_client"]}
|
|
1
|
+
{"version":3,"sources":["../../../../src/common/net/fetch-client.ts"],"sourcesContent":["import {\n HttpClientInterface,\n HttpClientResponseInterface,\n RequestHeaders,\n RequestOptions,\n ResponseHeaders,\n} from '../interfaces/http-client.interface';\nimport { HttpClient, HttpClientError, HttpClientResponse } from './http-client';\nimport { ParseError } from '../exceptions/parse-error';\n\ninterface FetchHttpClientOptions extends RequestInit {\n timeout?: number;\n}\n\nconst DEFAULT_FETCH_TIMEOUT = 60_000; // 60 seconds\nexport class FetchHttpClient extends HttpClient implements HttpClientInterface {\n private readonly _fetchFn;\n\n constructor(\n readonly baseURL: string,\n readonly options?: FetchHttpClientOptions,\n fetchFn?: typeof fetch,\n ) {\n super(baseURL, options);\n\n // Default to global fetch if available\n if (!fetchFn) {\n if (!globalThis.fetch) {\n throw new Error(\n 'Fetch function not defined in the global scope and no replacement was provided.',\n );\n }\n fetchFn = globalThis.fetch;\n }\n\n this._fetchFn = fetchFn.bind(globalThis);\n }\n\n /** @override */\n getClientName(): string {\n return 'fetch';\n }\n\n async get(\n path: string,\n options: RequestOptions,\n ): Promise<HttpClientResponseInterface> {\n const resourceURL = HttpClient.getResourceURL(\n this.baseURL,\n path,\n options.params,\n );\n\n if (HttpClient.isPathRetryable(path)) {\n return await this.fetchRequestWithRetry(\n resourceURL,\n 'GET',\n null,\n options.headers,\n );\n } else {\n return await this.fetchRequest(resourceURL, 'GET', null, options.headers);\n }\n }\n\n async post<Entity = any>(\n path: string,\n entity: Entity,\n options: RequestOptions,\n ): Promise<HttpClientResponseInterface> {\n const resourceURL = HttpClient.getResourceURL(\n this.baseURL,\n path,\n options.params,\n );\n\n if (HttpClient.isPathRetryable(path)) {\n return await this.fetchRequestWithRetry(\n resourceURL,\n 'POST',\n HttpClient.getBody(entity),\n {\n ...HttpClient.getContentTypeHeader(entity),\n ...options.headers,\n },\n );\n } else {\n return await this.fetchRequest(\n resourceURL,\n 'POST',\n HttpClient.getBody(entity),\n {\n ...HttpClient.getContentTypeHeader(entity),\n ...options.headers,\n },\n );\n }\n }\n\n async put<Entity = any>(\n path: string,\n entity: Entity,\n options: RequestOptions,\n ): Promise<HttpClientResponseInterface> {\n const resourceURL = HttpClient.getResourceURL(\n this.baseURL,\n path,\n options.params,\n );\n\n if (HttpClient.isPathRetryable(path)) {\n return await this.fetchRequestWithRetry(\n resourceURL,\n 'PUT',\n HttpClient.getBody(entity),\n {\n ...HttpClient.getContentTypeHeader(entity),\n ...options.headers,\n },\n );\n } else {\n return await this.fetchRequest(\n resourceURL,\n 'PUT',\n HttpClient.getBody(entity),\n {\n ...HttpClient.getContentTypeHeader(entity),\n ...options.headers,\n },\n );\n }\n }\n\n async delete(\n path: string,\n options: RequestOptions,\n ): Promise<HttpClientResponseInterface> {\n const resourceURL = HttpClient.getResourceURL(\n this.baseURL,\n path,\n options.params,\n );\n\n if (HttpClient.isPathRetryable(path)) {\n return await this.fetchRequestWithRetry(\n resourceURL,\n 'DELETE',\n null,\n options.headers,\n );\n } else {\n return await this.fetchRequest(\n resourceURL,\n 'DELETE',\n null,\n options.headers,\n );\n }\n }\n\n private async fetchRequest(\n url: string,\n method: string,\n body?: any,\n headers?: RequestHeaders,\n ): Promise<HttpClientResponseInterface> {\n // For methods which expect payloads, we should always pass a body value\n // even when it is empty. Without this, some JS runtimes (eg. Deno) will\n // inject a second Content-Length header.\n const methodHasPayload =\n method === 'POST' || method === 'PUT' || method === 'PATCH';\n\n const requestBody = body || (methodHasPayload ? '' : undefined);\n\n const { 'User-Agent': userAgent } = (this.options?.headers ||\n {}) as RequestHeaders;\n\n // Access timeout from the options with default of 60 seconds\n const timeout = this.options?.timeout ?? DEFAULT_FETCH_TIMEOUT; // Default 60 seconds\n const abortController = new AbortController();\n const timeoutId = setTimeout(() => {\n abortController?.abort();\n }, timeout);\n\n try {\n const res = await this._fetchFn(url, {\n method,\n headers: {\n Accept: 'application/json, text/plain, */*',\n 'Content-Type': 'application/json',\n ...this.options?.headers,\n ...headers,\n 'User-Agent': this.addClientToUserAgent(\n (userAgent || 'workos-node').toString(),\n ),\n },\n body: requestBody,\n signal: abortController?.signal,\n });\n\n // Clear timeout if request completed successfully\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n\n if (!res.ok) {\n const requestID = res.headers.get('X-Request-ID') ?? '';\n const rawBody = await res.text();\n\n let responseJson: any;\n\n try {\n responseJson = JSON.parse(rawBody);\n } catch (error) {\n if (error instanceof SyntaxError) {\n throw new ParseError({\n message: error.message,\n rawBody,\n requestID,\n rawStatus: res.status,\n });\n }\n throw error;\n }\n\n throw new HttpClientError({\n message: res.statusText,\n response: {\n status: res.status,\n headers: res.headers,\n data: responseJson,\n },\n });\n }\n return new FetchHttpClientResponse(res);\n } catch (error) {\n // Clear timeout if request failed\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n\n // Handle timeout errors\n if (error instanceof Error && error.name === 'AbortError') {\n throw new HttpClientError({\n message: `Request timeout after ${timeout}ms`,\n response: {\n status: 408,\n headers: {},\n data: { error: 'Request timeout' },\n },\n });\n }\n\n throw error;\n }\n }\n\n private async fetchRequestWithRetry(\n url: string,\n method: string,\n body?: any,\n headers?: RequestHeaders,\n ): Promise<HttpClientResponseInterface> {\n let response: HttpClientResponseInterface;\n let retryAttempts = 1;\n\n const makeRequest = async (): Promise<HttpClientResponseInterface> => {\n let requestError: any = null;\n\n try {\n response = await this.fetchRequest(url, method, body, headers);\n } catch (e) {\n requestError = e;\n }\n\n if (this.shouldRetryRequest(requestError, retryAttempts)) {\n retryAttempts++;\n await this.sleep(retryAttempts);\n return makeRequest();\n }\n\n if (requestError != null) {\n throw requestError;\n }\n\n return response;\n };\n\n return makeRequest();\n }\n\n private shouldRetryRequest(requestError: any, retryAttempt: number): boolean {\n if (retryAttempt > this.MAX_RETRY_ATTEMPTS) {\n return false;\n }\n\n if (requestError != null) {\n if (requestError instanceof TypeError) {\n return true;\n }\n\n if (\n requestError instanceof HttpClientError &&\n this.RETRY_STATUS_CODES.includes(requestError.response.status)\n ) {\n return true;\n }\n }\n\n return false;\n }\n}\n\n// tslint:disable-next-line\nexport class FetchHttpClientResponse\n extends HttpClientResponse\n implements HttpClientResponseInterface\n{\n _res: Response;\n\n constructor(res: Response) {\n super(\n res.status,\n FetchHttpClientResponse._transformHeadersToObject(res.headers),\n );\n this._res = res;\n }\n\n getRawResponse(): Response {\n return this._res;\n }\n\n toJSON(): Promise<any> | null {\n const contentType = this._res.headers.get('content-type');\n const isJsonResponse = contentType?.includes('application/json');\n\n return isJsonResponse ? this._res.json() : null;\n }\n\n static _transformHeadersToObject(headers: Headers): ResponseHeaders {\n // Fetch uses a Headers instance so this must be converted to a barebones\n // JS object to meet the HttpClient interface.\n const headersObj: ResponseHeaders = {};\n for (const entry of Object.entries(headers)) {\n if (!Array.isArray(entry) || entry.length !== 2) {\n throw new Error(\n 'Response objects produced by the fetch function given to FetchHttpClient do not have an iterable headers map. Response#headers should be an iterable object.',\n );\n }\n\n headersObj[entry[0]] = entry[1];\n }\n\n return headersObj;\n }\n}\n"],"mappings":"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","names":["import_http_client"]}
|
|
@@ -35,7 +35,7 @@ class HttpClient {
|
|
|
35
35
|
MAX_RETRY_ATTEMPTS = 3;
|
|
36
36
|
BACKOFF_MULTIPLIER = 1.5;
|
|
37
37
|
MINIMUM_SLEEP_TIME_IN_MILLISECONDS = 500;
|
|
38
|
-
RETRY_STATUS_CODES = [500, 502, 504];
|
|
38
|
+
RETRY_STATUS_CODES = [408, 500, 502, 504];
|
|
39
39
|
/** The HTTP client name used for diagnostics */
|
|
40
40
|
getClientName() {
|
|
41
41
|
throw new Error("getClientName not implemented");
|
|
@@ -74,6 +74,9 @@ class HttpClient {
|
|
|
74
74
|
}
|
|
75
75
|
return JSON.stringify(entity);
|
|
76
76
|
}
|
|
77
|
+
static isPathRetryable(path) {
|
|
78
|
+
return path.startsWith("/fga/") || path.startsWith("/vault/");
|
|
79
|
+
}
|
|
77
80
|
getSleepTimeInMilliseconds(retryAttempt) {
|
|
78
81
|
const sleepTime = this.MINIMUM_SLEEP_TIME_IN_MILLISECONDS * Math.pow(this.BACKOFF_MULTIPLIER, retryAttempt);
|
|
79
82
|
const jitter = Math.random() + 0.5;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/common/net/http-client.ts"],"sourcesContent":["import {\n HttpClientInterface,\n HttpClientResponseInterface,\n RequestHeaders,\n RequestOptions,\n ResponseHeaders,\n} from '../interfaces/http-client.interface';\n\nexport abstract class HttpClient implements HttpClientInterface {\n readonly MAX_RETRY_ATTEMPTS = 3;\n readonly BACKOFF_MULTIPLIER = 1.5;\n readonly MINIMUM_SLEEP_TIME_IN_MILLISECONDS = 500;\n readonly RETRY_STATUS_CODES = [500, 502, 504];\n\n constructor(\n readonly baseURL: string,\n readonly options?: RequestInit,\n ) {}\n\n /** The HTTP client name used for diagnostics */\n getClientName(): string {\n throw new Error('getClientName not implemented');\n }\n\n abstract get(\n path: string,\n options: RequestOptions,\n ): Promise<HttpClientResponseInterface>;\n\n abstract post<Entity = any>(\n path: string,\n entity: Entity,\n options: RequestOptions,\n ): Promise<HttpClientResponseInterface>;\n\n abstract put<Entity = any>(\n path: string,\n entity: Entity,\n options: RequestOptions,\n ): Promise<HttpClientResponseInterface>;\n\n abstract delete(\n path: string,\n options: RequestOptions,\n ): Promise<HttpClientResponseInterface>;\n\n addClientToUserAgent(userAgent: string): string {\n if (userAgent.indexOf(' ') > -1) {\n return userAgent.replace(/\\b\\s/, `/${this.getClientName()} `);\n } else {\n return (userAgent += `/${this.getClientName()}`);\n }\n }\n\n static getResourceURL(\n baseURL: string,\n path: string,\n params?: Record<string, any>,\n ) {\n const queryString = HttpClient.getQueryString(params);\n const url = new URL([path, queryString].filter(Boolean).join('?'), baseURL);\n return url.toString();\n }\n\n static getQueryString(queryObj?: Record<string, any>) {\n if (!queryObj) return undefined;\n\n const sanitizedQueryObj: Record<string, any> = {};\n\n Object.entries(queryObj).forEach(([param, value]) => {\n if (value !== '' && value !== undefined) sanitizedQueryObj[param] = value;\n });\n\n return new URLSearchParams(sanitizedQueryObj).toString();\n }\n\n static getContentTypeHeader(entity: any): RequestHeaders | undefined {\n if (entity instanceof URLSearchParams) {\n return {\n 'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8',\n };\n }\n return undefined;\n }\n\n static getBody(entity: any): BodyInit | null | undefined {\n if (entity === null || entity instanceof URLSearchParams) {\n return entity;\n }\n\n return JSON.stringify(entity);\n }\n\n private getSleepTimeInMilliseconds(retryAttempt: number): number {\n const sleepTime =\n this.MINIMUM_SLEEP_TIME_IN_MILLISECONDS *\n Math.pow(this.BACKOFF_MULTIPLIER, retryAttempt);\n const jitter = Math.random() + 0.5;\n return sleepTime * jitter;\n }\n\n sleep = (retryAttempt: number) =>\n new Promise((resolve) =>\n setTimeout(resolve, this.getSleepTimeInMilliseconds(retryAttempt)),\n );\n}\n\n// tslint:disable-next-line\nexport abstract class HttpClientResponse\n implements HttpClientResponseInterface\n{\n _statusCode: number;\n _headers: ResponseHeaders;\n\n constructor(statusCode: number, headers: ResponseHeaders) {\n this._statusCode = statusCode;\n this._headers = headers;\n }\n\n getStatusCode(): number {\n return this._statusCode;\n }\n\n getHeaders(): ResponseHeaders {\n return this._headers;\n }\n\n abstract getRawResponse(): unknown;\n\n abstract toJSON(): any | null;\n}\n\n// tslint:disable-next-line\nexport class HttpClientError<T> extends Error {\n readonly name: string = 'HttpClientError';\n readonly message: string = 'The request could not be completed.';\n readonly response: { status: number; headers: any; data: T };\n\n constructor({\n message,\n response,\n }: {\n message: string;\n readonly response: HttpClientError<T>['response'];\n }) {\n super(message);\n this.message = message;\n this.response = response;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAQO,MAAe,WAA0C;AAAA,EAM9D,YACW,SACA,SACT;AAFS;AACA;AAAA,EACR;AAAA,EAjBL,OAQgE;AAAA;AAAA;AAAA,EACrD,qBAAqB;AAAA,EACrB,qBAAqB;AAAA,EACrB,qCAAqC;AAAA,EACrC,qBAAqB,CAAC,KAAK,KAAK,GAAG;AAAA;AAAA,
|
|
1
|
+
{"version":3,"sources":["../../../../src/common/net/http-client.ts"],"sourcesContent":["import {\n HttpClientInterface,\n HttpClientResponseInterface,\n RequestHeaders,\n RequestOptions,\n ResponseHeaders,\n} from '../interfaces/http-client.interface';\n\nexport abstract class HttpClient implements HttpClientInterface {\n readonly MAX_RETRY_ATTEMPTS = 3;\n readonly BACKOFF_MULTIPLIER = 1.5;\n readonly MINIMUM_SLEEP_TIME_IN_MILLISECONDS = 500;\n readonly RETRY_STATUS_CODES = [408, 500, 502, 504];\n\n constructor(\n readonly baseURL: string,\n readonly options?: RequestInit,\n ) {}\n\n /** The HTTP client name used for diagnostics */\n getClientName(): string {\n throw new Error('getClientName not implemented');\n }\n\n abstract get(\n path: string,\n options: RequestOptions,\n ): Promise<HttpClientResponseInterface>;\n\n abstract post<Entity = any>(\n path: string,\n entity: Entity,\n options: RequestOptions,\n ): Promise<HttpClientResponseInterface>;\n\n abstract put<Entity = any>(\n path: string,\n entity: Entity,\n options: RequestOptions,\n ): Promise<HttpClientResponseInterface>;\n\n abstract delete(\n path: string,\n options: RequestOptions,\n ): Promise<HttpClientResponseInterface>;\n\n addClientToUserAgent(userAgent: string): string {\n if (userAgent.indexOf(' ') > -1) {\n return userAgent.replace(/\\b\\s/, `/${this.getClientName()} `);\n } else {\n return (userAgent += `/${this.getClientName()}`);\n }\n }\n\n static getResourceURL(\n baseURL: string,\n path: string,\n params?: Record<string, any>,\n ) {\n const queryString = HttpClient.getQueryString(params);\n const url = new URL([path, queryString].filter(Boolean).join('?'), baseURL);\n return url.toString();\n }\n\n static getQueryString(queryObj?: Record<string, any>) {\n if (!queryObj) return undefined;\n\n const sanitizedQueryObj: Record<string, any> = {};\n\n Object.entries(queryObj).forEach(([param, value]) => {\n if (value !== '' && value !== undefined) sanitizedQueryObj[param] = value;\n });\n\n return new URLSearchParams(sanitizedQueryObj).toString();\n }\n\n static getContentTypeHeader(entity: any): RequestHeaders | undefined {\n if (entity instanceof URLSearchParams) {\n return {\n 'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8',\n };\n }\n return undefined;\n }\n\n static getBody(entity: any): BodyInit | null | undefined {\n if (entity === null || entity instanceof URLSearchParams) {\n return entity;\n }\n\n return JSON.stringify(entity);\n }\n\n static isPathRetryable(path: string): boolean {\n return path.startsWith('/fga/') || path.startsWith('/vault/');\n }\n\n private getSleepTimeInMilliseconds(retryAttempt: number): number {\n const sleepTime =\n this.MINIMUM_SLEEP_TIME_IN_MILLISECONDS *\n Math.pow(this.BACKOFF_MULTIPLIER, retryAttempt);\n const jitter = Math.random() + 0.5;\n return sleepTime * jitter;\n }\n\n sleep = (retryAttempt: number) =>\n new Promise((resolve) =>\n setTimeout(resolve, this.getSleepTimeInMilliseconds(retryAttempt)),\n );\n}\n\n// tslint:disable-next-line\nexport abstract class HttpClientResponse\n implements HttpClientResponseInterface\n{\n _statusCode: number;\n _headers: ResponseHeaders;\n\n constructor(statusCode: number, headers: ResponseHeaders) {\n this._statusCode = statusCode;\n this._headers = headers;\n }\n\n getStatusCode(): number {\n return this._statusCode;\n }\n\n getHeaders(): ResponseHeaders {\n return this._headers;\n }\n\n abstract getRawResponse(): unknown;\n\n abstract toJSON(): any | null;\n}\n\n// tslint:disable-next-line\nexport class HttpClientError<T> extends Error {\n readonly name: string = 'HttpClientError';\n readonly message: string = 'The request could not be completed.';\n readonly response: { status: number; headers: any; data: T };\n\n constructor({\n message,\n response,\n }: {\n message: string;\n readonly response: HttpClientError<T>['response'];\n }) {\n super(message);\n this.message = message;\n this.response = response;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAQO,MAAe,WAA0C;AAAA,EAM9D,YACW,SACA,SACT;AAFS;AACA;AAAA,EACR;AAAA,EAjBL,OAQgE;AAAA;AAAA;AAAA,EACrD,qBAAqB;AAAA,EACrB,qBAAqB;AAAA,EACrB,qCAAqC;AAAA,EACrC,qBAAqB,CAAC,KAAK,KAAK,KAAK,GAAG;AAAA;AAAA,EAQjD,gBAAwB;AACtB,UAAM,IAAI,MAAM,+BAA+B;AAAA,EACjD;AAAA,EAwBA,qBAAqB,WAA2B;AAC9C,QAAI,UAAU,QAAQ,GAAG,IAAI,IAAI;AAC/B,aAAO,UAAU,QAAQ,QAAQ,IAAI,KAAK,cAAc,CAAC,GAAG;AAAA,IAC9D,OAAO;AACL,aAAQ,aAAa,IAAI,KAAK,cAAc,CAAC;AAAA,IAC/C;AAAA,EACF;AAAA,EAEA,OAAO,eACL,SACA,MACA,QACA;AACA,UAAM,cAAc,WAAW,eAAe,MAAM;AACpD,UAAM,MAAM,IAAI,IAAI,CAAC,MAAM,WAAW,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GAAG,OAAO;AAC1E,WAAO,IAAI,SAAS;AAAA,EACtB;AAAA,EAEA,OAAO,eAAe,UAAgC;AACpD,QAAI,CAAC,SAAU,QAAO;AAEtB,UAAM,oBAAyC,CAAC;AAEhD,WAAO,QAAQ,QAAQ,EAAE,QAAQ,CAAC,CAAC,OAAO,KAAK,MAAM;AACnD,UAAI,UAAU,MAAM,UAAU,OAAW,mBAAkB,KAAK,IAAI;AAAA,IACtE,CAAC;AAED,WAAO,IAAI,gBAAgB,iBAAiB,EAAE,SAAS;AAAA,EACzD;AAAA,EAEA,OAAO,qBAAqB,QAAyC;AACnE,QAAI,kBAAkB,iBAAiB;AACrC,aAAO;AAAA,QACL,gBAAgB;AAAA,MAClB;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA,EAEA,OAAO,QAAQ,QAA0C;AACvD,QAAI,WAAW,QAAQ,kBAAkB,iBAAiB;AACxD,aAAO;AAAA,IACT;AAEA,WAAO,KAAK,UAAU,MAAM;AAAA,EAC9B;AAAA,EAEA,OAAO,gBAAgB,MAAuB;AAC5C,WAAO,KAAK,WAAW,OAAO,KAAK,KAAK,WAAW,SAAS;AAAA,EAC9D;AAAA,EAEQ,2BAA2B,cAA8B;AAC/D,UAAM,YACJ,KAAK,qCACL,KAAK,IAAI,KAAK,oBAAoB,YAAY;AAChD,UAAM,SAAS,KAAK,OAAO,IAAI;AAC/B,WAAO,YAAY;AAAA,EACrB;AAAA,EAEA,QAAQ,wBAAC,iBACP,IAAI;AAAA,IAAQ,CAAC,YACX,WAAW,SAAS,KAAK,2BAA2B,YAAY,CAAC;AAAA,EACnE,GAHM;AAIV;AAGO,MAAe,mBAEtB;AAAA,EAlHA,OAkHA;AAAA;AAAA;AAAA,EACE;AAAA,EACA;AAAA,EAEA,YAAY,YAAoB,SAA0B;AACxD,SAAK,cAAc;AACnB,SAAK,WAAW;AAAA,EAClB;AAAA,EAEA,gBAAwB;AACtB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,aAA8B;AAC5B,WAAO,KAAK;AAAA,EACd;AAKF;AAGO,MAAM,wBAA2B,MAAM;AAAA,EAzI9C,OAyI8C;AAAA;AAAA;AAAA,EACnC,OAAe;AAAA,EACf,UAAkB;AAAA,EAClB;AAAA,EAET,YAAY;AAAA,IACV;AAAA,IACA;AAAA,EACF,GAGG;AACD,UAAM,OAAO;AACb,SAAK,UAAU;AACf,SAAK,WAAW;AAAA,EAClB;AACF;","names":[]}
|
|
@@ -19,6 +19,7 @@ declare abstract class HttpClient implements HttpClientInterface {
|
|
|
19
19
|
static getQueryString(queryObj?: Record<string, any>): string | undefined;
|
|
20
20
|
static getContentTypeHeader(entity: any): RequestHeaders | undefined;
|
|
21
21
|
static getBody(entity: any): BodyInit | null | undefined;
|
|
22
|
+
static isPathRetryable(path: string): boolean;
|
|
22
23
|
private getSleepTimeInMilliseconds;
|
|
23
24
|
sleep: (retryAttempt: number) => Promise<unknown>;
|
|
24
25
|
}
|
|
@@ -0,0 +1,101 @@
|
|
|
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 __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
20
|
+
var leb128_exports = {};
|
|
21
|
+
__export(leb128_exports, {
|
|
22
|
+
decodeUInt32: () => decodeUInt32,
|
|
23
|
+
encodeUInt32: () => encodeUInt32
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(leb128_exports);
|
|
26
|
+
const MAX_UINT32 = 4294967295;
|
|
27
|
+
const CONTINUATION_BIT = 128;
|
|
28
|
+
const DATA_BITS_MASK = 127;
|
|
29
|
+
const DATA_BITS_PER_BYTE = 7;
|
|
30
|
+
const MAX_BYTES_FOR_UINT32 = 5;
|
|
31
|
+
function encodeUInt32(value) {
|
|
32
|
+
validateUInt32(value);
|
|
33
|
+
if (value === 0) {
|
|
34
|
+
return new Uint8Array([0]);
|
|
35
|
+
}
|
|
36
|
+
const bytes = [];
|
|
37
|
+
do {
|
|
38
|
+
let byte = value & DATA_BITS_MASK;
|
|
39
|
+
value >>>= DATA_BITS_PER_BYTE;
|
|
40
|
+
if (value !== 0) {
|
|
41
|
+
byte |= CONTINUATION_BIT;
|
|
42
|
+
}
|
|
43
|
+
bytes.push(byte);
|
|
44
|
+
} while (value !== 0);
|
|
45
|
+
return new Uint8Array(bytes);
|
|
46
|
+
}
|
|
47
|
+
__name(encodeUInt32, "encodeUInt32");
|
|
48
|
+
function decodeUInt32(data, offset = 0) {
|
|
49
|
+
validateOffset(data, offset);
|
|
50
|
+
let result = 0;
|
|
51
|
+
let shift = 0;
|
|
52
|
+
let index = offset;
|
|
53
|
+
let bytesRead = 0;
|
|
54
|
+
while (index < data.length) {
|
|
55
|
+
const byte = data[index++];
|
|
56
|
+
bytesRead++;
|
|
57
|
+
if (bytesRead > MAX_BYTES_FOR_UINT32) {
|
|
58
|
+
throw new Error("LEB128 sequence exceeds maximum length for uint32");
|
|
59
|
+
}
|
|
60
|
+
result |= (byte & DATA_BITS_MASK) << shift;
|
|
61
|
+
if (!hasContinuationBit(byte)) {
|
|
62
|
+
return { value: result >>> 0, nextIndex: index };
|
|
63
|
+
}
|
|
64
|
+
shift += DATA_BITS_PER_BYTE;
|
|
65
|
+
}
|
|
66
|
+
throw new Error("Truncated LEB128 encoding");
|
|
67
|
+
}
|
|
68
|
+
__name(decodeUInt32, "decodeUInt32");
|
|
69
|
+
function validateUInt32(value) {
|
|
70
|
+
if (!Number.isFinite(value)) {
|
|
71
|
+
throw new Error("Value must be a finite number");
|
|
72
|
+
}
|
|
73
|
+
if (!Number.isInteger(value)) {
|
|
74
|
+
throw new Error("Value must be an integer");
|
|
75
|
+
}
|
|
76
|
+
if (value < 0) {
|
|
77
|
+
throw new Error("Value must be non-negative");
|
|
78
|
+
}
|
|
79
|
+
if (value > MAX_UINT32) {
|
|
80
|
+
throw new Error(`Value must not exceed ${MAX_UINT32} (MAX_UINT32)`);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
__name(validateUInt32, "validateUInt32");
|
|
84
|
+
function validateOffset(data, offset) {
|
|
85
|
+
if (offset < 0 || offset >= data.length) {
|
|
86
|
+
throw new Error(
|
|
87
|
+
`Offset ${offset} is out of bounds (buffer length: ${data.length})`
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
__name(validateOffset, "validateOffset");
|
|
92
|
+
function hasContinuationBit(byte) {
|
|
93
|
+
return (byte & CONTINUATION_BIT) !== 0;
|
|
94
|
+
}
|
|
95
|
+
__name(hasContinuationBit, "hasContinuationBit");
|
|
96
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
97
|
+
0 && (module.exports = {
|
|
98
|
+
decodeUInt32,
|
|
99
|
+
encodeUInt32
|
|
100
|
+
});
|
|
101
|
+
//# sourceMappingURL=leb128.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/common/utils/leb128.ts"],"sourcesContent":["/**\n * LEB128 (Little Endian Base 128) encoding for unsigned 32-bit integers.\n * Variable-length encoding: each byte stores 7 bits of data, bit 7 is continuation flag.\n */\n\nconst MAX_UINT32 = 0xffffffff;\nconst CONTINUATION_BIT = 0x80;\nconst DATA_BITS_MASK = 0x7f;\nconst DATA_BITS_PER_BYTE = 7;\nconst MAX_BYTES_FOR_UINT32 = 5;\n\n/**\n * Encodes an unsigned 32-bit integer into LEB128 format.\n *\n * @param value - Unsigned 32-bit integer (0 to 4,294,967,295)\n * @returns Encoded bytes (1-5 bytes depending on value)\n */\nexport function encodeUInt32(value: number): Uint8Array {\n validateUInt32(value);\n\n if (value === 0) {\n return new Uint8Array([0]);\n }\n\n const bytes: number[] = [];\n\n do {\n let byte = value & DATA_BITS_MASK;\n value >>>= DATA_BITS_PER_BYTE;\n\n if (value !== 0) {\n byte |= CONTINUATION_BIT;\n }\n\n bytes.push(byte);\n } while (value !== 0);\n\n return new Uint8Array(bytes);\n}\n\n/**\n * Decodes an unsigned 32-bit integer from LEB128 format.\n *\n * @param data - Buffer containing LEB128 encoded data\n * @param offset - Starting position in buffer (default: 0)\n * @returns Decoded value and index after last byte read\n */\nexport function decodeUInt32(\n data: Uint8Array,\n offset = 0,\n): { value: number; nextIndex: number } {\n validateOffset(data, offset);\n\n let result = 0;\n let shift = 0;\n let index = offset;\n let bytesRead = 0;\n\n while (index < data.length) {\n const byte = data[index++];\n bytesRead++;\n\n if (bytesRead > MAX_BYTES_FOR_UINT32) {\n throw new Error('LEB128 sequence exceeds maximum length for uint32');\n }\n\n result |= (byte & DATA_BITS_MASK) << shift;\n\n if (!hasContinuationBit(byte)) {\n return { value: result >>> 0, nextIndex: index };\n }\n\n shift += DATA_BITS_PER_BYTE;\n }\n\n throw new Error('Truncated LEB128 encoding');\n}\n\nfunction validateUInt32(value: number): void {\n if (!Number.isFinite(value)) {\n throw new Error('Value must be a finite number');\n }\n if (!Number.isInteger(value)) {\n throw new Error('Value must be an integer');\n }\n if (value < 0) {\n throw new Error('Value must be non-negative');\n }\n if (value > MAX_UINT32) {\n throw new Error(`Value must not exceed ${MAX_UINT32} (MAX_UINT32)`);\n }\n}\n\nfunction validateOffset(data: Uint8Array, offset: number): void {\n if (offset < 0 || offset >= data.length) {\n throw new Error(\n `Offset ${offset} is out of bounds (buffer length: ${data.length})`,\n );\n }\n}\n\nfunction hasContinuationBit(byte: number): boolean {\n return (byte & CONTINUATION_BIT) !== 0;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAKA,MAAM,aAAa;AACnB,MAAM,mBAAmB;AACzB,MAAM,iBAAiB;AACvB,MAAM,qBAAqB;AAC3B,MAAM,uBAAuB;AAQtB,SAAS,aAAa,OAA2B;AACtD,iBAAe,KAAK;AAEpB,MAAI,UAAU,GAAG;AACf,WAAO,IAAI,WAAW,CAAC,CAAC,CAAC;AAAA,EAC3B;AAEA,QAAM,QAAkB,CAAC;AAEzB,KAAG;AACD,QAAI,OAAO,QAAQ;AACnB,eAAW;AAEX,QAAI,UAAU,GAAG;AACf,cAAQ;AAAA,IACV;AAEA,UAAM,KAAK,IAAI;AAAA,EACjB,SAAS,UAAU;AAEnB,SAAO,IAAI,WAAW,KAAK;AAC7B;AArBgB;AA8BT,SAAS,aACd,MACA,SAAS,GAC6B;AACtC,iBAAe,MAAM,MAAM;AAE3B,MAAI,SAAS;AACb,MAAI,QAAQ;AACZ,MAAI,QAAQ;AACZ,MAAI,YAAY;AAEhB,SAAO,QAAQ,KAAK,QAAQ;AAC1B,UAAM,OAAO,KAAK,OAAO;AACzB;AAEA,QAAI,YAAY,sBAAsB;AACpC,YAAM,IAAI,MAAM,mDAAmD;AAAA,IACrE;AAEA,eAAW,OAAO,mBAAmB;AAErC,QAAI,CAAC,mBAAmB,IAAI,GAAG;AAC7B,aAAO,EAAE,OAAO,WAAW,GAAG,WAAW,MAAM;AAAA,IACjD;AAEA,aAAS;AAAA,EACX;AAEA,QAAM,IAAI,MAAM,2BAA2B;AAC7C;AA7BgB;AA+BhB,SAAS,eAAe,OAAqB;AAC3C,MAAI,CAAC,OAAO,SAAS,KAAK,GAAG;AAC3B,UAAM,IAAI,MAAM,+BAA+B;AAAA,EACjD;AACA,MAAI,CAAC,OAAO,UAAU,KAAK,GAAG;AAC5B,UAAM,IAAI,MAAM,0BAA0B;AAAA,EAC5C;AACA,MAAI,QAAQ,GAAG;AACb,UAAM,IAAI,MAAM,4BAA4B;AAAA,EAC9C;AACA,MAAI,QAAQ,YAAY;AACtB,UAAM,IAAI,MAAM,yBAAyB,UAAU,eAAe;AAAA,EACpE;AACF;AAbS;AAeT,SAAS,eAAe,MAAkB,QAAsB;AAC9D,MAAI,SAAS,KAAK,UAAU,KAAK,QAAQ;AACvC,UAAM,IAAI;AAAA,MACR,UAAU,MAAM,qCAAqC,KAAK,MAAM;AAAA,IAClE;AAAA,EACF;AACF;AANS;AAQT,SAAS,mBAAmB,MAAuB;AACjD,UAAQ,OAAO,sBAAsB;AACvC;AAFS;","names":[]}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LEB128 (Little Endian Base 128) encoding for unsigned 32-bit integers.
|
|
3
|
+
* Variable-length encoding: each byte stores 7 bits of data, bit 7 is continuation flag.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Encodes an unsigned 32-bit integer into LEB128 format.
|
|
7
|
+
*
|
|
8
|
+
* @param value - Unsigned 32-bit integer (0 to 4,294,967,295)
|
|
9
|
+
* @returns Encoded bytes (1-5 bytes depending on value)
|
|
10
|
+
*/
|
|
11
|
+
declare function encodeUInt32(value: number): Uint8Array;
|
|
12
|
+
/**
|
|
13
|
+
* Decodes an unsigned 32-bit integer from LEB128 format.
|
|
14
|
+
*
|
|
15
|
+
* @param data - Buffer containing LEB128 encoded data
|
|
16
|
+
* @param offset - Starting position in buffer (default: 0)
|
|
17
|
+
* @returns Decoded value and index after last byte read
|
|
18
|
+
*/
|
|
19
|
+
declare function decodeUInt32(data: Uint8Array, offset?: number): {
|
|
20
|
+
value: number;
|
|
21
|
+
nextIndex: number;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export { decodeUInt32, encodeUInt32 };
|
|
@@ -0,0 +1,66 @@
|
|
|
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 __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
20
|
+
var query_string_exports = {};
|
|
21
|
+
__export(query_string_exports, {
|
|
22
|
+
toQueryString: () => toQueryString
|
|
23
|
+
});
|
|
24
|
+
module.exports = __toCommonJS(query_string_exports);
|
|
25
|
+
function toQueryString(options) {
|
|
26
|
+
const params = [];
|
|
27
|
+
const sortedKeys = Object.keys(options).sort((a, b) => a.localeCompare(b));
|
|
28
|
+
for (const key of sortedKeys) {
|
|
29
|
+
const value = options[key];
|
|
30
|
+
if (value === void 0) {
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
if (Array.isArray(value)) {
|
|
34
|
+
for (const item of value) {
|
|
35
|
+
params.push([key, String(item)]);
|
|
36
|
+
}
|
|
37
|
+
} else if (typeof value === "object" && value !== null) {
|
|
38
|
+
const sortedSubKeys = Object.keys(value).sort(
|
|
39
|
+
(a, b) => a.localeCompare(b)
|
|
40
|
+
);
|
|
41
|
+
for (const subKey of sortedSubKeys) {
|
|
42
|
+
const subValue = value[subKey];
|
|
43
|
+
if (subValue !== void 0) {
|
|
44
|
+
params.push([`${key}[${subKey}]`, String(subValue)]);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
} else {
|
|
48
|
+
params.push([key, String(value)]);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return params.map(([key, value]) => {
|
|
52
|
+
const encodedKey = encodeRFC1738(key);
|
|
53
|
+
const encodedValue = encodeRFC1738(value);
|
|
54
|
+
return `${encodedKey}=${encodedValue}`;
|
|
55
|
+
}).join("&");
|
|
56
|
+
}
|
|
57
|
+
__name(toQueryString, "toQueryString");
|
|
58
|
+
function encodeRFC1738(str) {
|
|
59
|
+
return encodeURIComponent(str).replace(/%20/g, "+").replace(/[!'*]/g, (c) => "%" + c.charCodeAt(0).toString(16).toUpperCase());
|
|
60
|
+
}
|
|
61
|
+
__name(encodeRFC1738, "encodeRFC1738");
|
|
62
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
63
|
+
0 && (module.exports = {
|
|
64
|
+
toQueryString
|
|
65
|
+
});
|
|
66
|
+
//# sourceMappingURL=query-string.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/common/utils/query-string.ts"],"sourcesContent":["type QueryValue =\n | string\n | string[]\n | Record<string, string | boolean | number>\n | undefined;\n\n/**\n * Converts options to a query string.\n * - Arrays: scope=read&scope=write (repeat format)\n * - Objects: params[key]=value (bracket notation)\n * - Encoding: RFC1738 (space as +)\n * - Keys sorted alphabetically\n */\nexport function toQueryString(options: Record<string, QueryValue>): string {\n const params: Array<[string, string]> = [];\n const sortedKeys = Object.keys(options).sort((a, b) => a.localeCompare(b));\n\n for (const key of sortedKeys) {\n const value = options[key];\n\n if (value === undefined) {\n continue;\n }\n\n if (Array.isArray(value)) {\n for (const item of value) {\n params.push([key, String(item)]);\n }\n } else if (typeof value === 'object' && value !== null) {\n const sortedSubKeys = Object.keys(value).sort((a, b) =>\n a.localeCompare(b),\n );\n for (const subKey of sortedSubKeys) {\n const subValue = value[subKey];\n if (subValue !== undefined) {\n params.push([`${key}[${subKey}]`, String(subValue)]);\n }\n }\n } else {\n params.push([key, String(value)]);\n }\n }\n\n return params\n .map(([key, value]) => {\n const encodedKey = encodeRFC1738(key);\n const encodedValue = encodeRFC1738(value);\n return `${encodedKey}=${encodedValue}`;\n })\n .join('&');\n}\n\nfunction encodeRFC1738(str: string): string {\n return encodeURIComponent(str)\n .replace(/%20/g, '+')\n .replace(/[!'*]/g, (c) => '%' + c.charCodeAt(0).toString(16).toUpperCase());\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAaO,SAAS,cAAc,SAA6C;AACzE,QAAM,SAAkC,CAAC;AACzC,QAAM,aAAa,OAAO,KAAK,OAAO,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,cAAc,CAAC,CAAC;AAEzE,aAAW,OAAO,YAAY;AAC5B,UAAM,QAAQ,QAAQ,GAAG;AAEzB,QAAI,UAAU,QAAW;AACvB;AAAA,IACF;AAEA,QAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,iBAAW,QAAQ,OAAO;AACxB,eAAO,KAAK,CAAC,KAAK,OAAO,IAAI,CAAC,CAAC;AAAA,MACjC;AAAA,IACF,WAAW,OAAO,UAAU,YAAY,UAAU,MAAM;AACtD,YAAM,gBAAgB,OAAO,KAAK,KAAK,EAAE;AAAA,QAAK,CAAC,GAAG,MAChD,EAAE,cAAc,CAAC;AAAA,MACnB;AACA,iBAAW,UAAU,eAAe;AAClC,cAAM,WAAW,MAAM,MAAM;AAC7B,YAAI,aAAa,QAAW;AAC1B,iBAAO,KAAK,CAAC,GAAG,GAAG,IAAI,MAAM,KAAK,OAAO,QAAQ,CAAC,CAAC;AAAA,QACrD;AAAA,MACF;AAAA,IACF,OAAO;AACL,aAAO,KAAK,CAAC,KAAK,OAAO,KAAK,CAAC,CAAC;AAAA,IAClC;AAAA,EACF;AAEA,SAAO,OACJ,IAAI,CAAC,CAAC,KAAK,KAAK,MAAM;AACrB,UAAM,aAAa,cAAc,GAAG;AACpC,UAAM,eAAe,cAAc,KAAK;AACxC,WAAO,GAAG,UAAU,IAAI,YAAY;AAAA,EACtC,CAAC,EACA,KAAK,GAAG;AACb;AArCgB;AAuChB,SAAS,cAAc,KAAqB;AAC1C,SAAO,mBAAmB,GAAG,EAC1B,QAAQ,QAAQ,GAAG,EACnB,QAAQ,UAAU,CAAC,MAAM,MAAM,EAAE,WAAW,CAAC,EAAE,SAAS,EAAE,EAAE,YAAY,CAAC;AAC9E;AAJS;","names":[]}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
type QueryValue = string | string[] | Record<string, string | boolean | number> | undefined;
|
|
2
|
+
/**
|
|
3
|
+
* Converts options to a query string.
|
|
4
|
+
* - Arrays: scope=read&scope=write (repeat format)
|
|
5
|
+
* - Objects: params[key]=value (bracket notation)
|
|
6
|
+
* - Encoding: RFC1738 (space as +)
|
|
7
|
+
* - Keys sorted alphabetically
|
|
8
|
+
*/
|
|
9
|
+
declare function toQueryString(options: Record<string, QueryValue>): string;
|
|
10
|
+
|
|
11
|
+
export { toQueryString };
|
package/lib/cjs/vault/vault.cjs
CHANGED
|
@@ -22,7 +22,7 @@ __export(vault_exports, {
|
|
|
22
22
|
Vault: () => Vault
|
|
23
23
|
});
|
|
24
24
|
module.exports = __toCommonJS(vault_exports);
|
|
25
|
-
var
|
|
25
|
+
var import_leb128 = require('../common/utils/leb128.cjs');
|
|
26
26
|
var import_base64 = require('../common/utils/base64.cjs');
|
|
27
27
|
var import_vault_key = require('./serializers/vault-key.serializer.cjs');
|
|
28
28
|
var import_vault_object = require('./serializers/vault-object.serializer.cjs');
|
|
@@ -39,7 +39,7 @@ class Vault {
|
|
|
39
39
|
const inputData = (0, import_base64.base64ToUint8Array)(payload);
|
|
40
40
|
const iv = new Uint8Array(inputData.subarray(0, 12));
|
|
41
41
|
const tag = new Uint8Array(inputData.subarray(12, 28));
|
|
42
|
-
const { value: keyLen, nextIndex } = (0,
|
|
42
|
+
const { value: keyLen, nextIndex } = (0, import_leb128.decodeUInt32)(inputData, 28);
|
|
43
43
|
const keysBuffer = inputData.subarray(nextIndex, nextIndex + keyLen);
|
|
44
44
|
const keys = (0, import_base64.uint8ArrayToBase64)(keysBuffer);
|
|
45
45
|
const ciphertext = new Uint8Array(inputData.subarray(nextIndex + keyLen));
|
|
@@ -119,7 +119,7 @@ class Vault {
|
|
|
119
119
|
const encoder = new TextEncoder();
|
|
120
120
|
const key = (0, import_base64.base64ToUint8Array)(keyPair.dataKey.key);
|
|
121
121
|
const keyBlob = (0, import_base64.base64ToUint8Array)(keyPair.encryptedKeys);
|
|
122
|
-
const prefixLenBuffer = (0,
|
|
122
|
+
const prefixLenBuffer = (0, import_leb128.encodeUInt32)(keyBlob.length);
|
|
123
123
|
const aadBuffer = associatedData ? encoder.encode(associatedData) : void 0;
|
|
124
124
|
const iv = this.cryptoProvider.randomBytes(12);
|
|
125
125
|
const {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/vault/vault.ts"],"sourcesContent":["import { decodeUInt32, encodeUInt32 } from 'leb';\nimport { CryptoProvider } from '../common/crypto/crypto-provider';\nimport { List, ListResponse } from '../common/interfaces';\nimport { PaginationOptions } from '../index.worker';\nimport { base64ToUint8Array, uint8ArrayToBase64 } from '../common/utils/base64';\nimport type { WorkOS } from '../workos';\nimport {\n CreateDataKeyOptions,\n CreateDataKeyResponse,\n CreateObjectOptions,\n DataKey,\n DataKeyPair,\n DecryptDataKeyOptions,\n DecryptDataKeyResponse,\n DeleteObjectOptions,\n KeyContext,\n ListObjectVersionsResponse,\n ObjectDigest,\n ObjectDigestResponse,\n ObjectMetadata,\n ObjectVersion,\n ReadObjectMetadataResponse,\n ReadObjectOptions,\n ReadObjectResponse,\n UpdateObjectOptions,\n VaultObject,\n} from './interfaces';\nimport {\n deserializeCreateDataKeyResponse,\n deserializeDecryptDataKeyResponse,\n} from './serializers/vault-key.serializer';\nimport {\n deserializeListObjects,\n deserializeObject,\n deserializeObjectMetadata,\n desrializeListObjectVersions,\n serializeCreateObjectEntity,\n serializeUpdateObjectEntity,\n} from './serializers/vault-object.serializer';\n\ninterface Decoded {\n iv: Uint8Array;\n tag: Uint8Array;\n keys: string;\n ciphertext: Uint8Array;\n}\n\nexport class Vault {\n private cryptoProvider: CryptoProvider;\n\n constructor(private readonly workos: WorkOS) {\n this.cryptoProvider = workos.getCryptoProvider();\n }\n\n private decode(payload: string): Decoded {\n const inputData = base64ToUint8Array(payload);\n // Use 12 bytes for IV (standard for AES-GCM)\n const iv = new Uint8Array(inputData.subarray(0, 12));\n const tag = new Uint8Array(inputData.subarray(12, 28));\n const { value: keyLen, nextIndex } = decodeUInt32(inputData, 28);\n\n // Use subarray instead of slice and convert directly to base64\n const keysBuffer = inputData.subarray(nextIndex, nextIndex + keyLen);\n const keys = uint8ArrayToBase64(keysBuffer);\n\n const ciphertext = new Uint8Array(inputData.subarray(nextIndex + keyLen));\n\n return {\n iv,\n tag,\n keys,\n ciphertext,\n };\n }\n\n async createObject(options: CreateObjectOptions): Promise<ObjectMetadata> {\n const { data } = await this.workos.post<ReadObjectMetadataResponse>(\n `/vault/v1/kv`,\n serializeCreateObjectEntity(options),\n );\n return deserializeObjectMetadata(data);\n }\n\n async listObjects(\n options?: PaginationOptions | undefined,\n ): Promise<List<ObjectDigest>> {\n const url = new URL('/vault/v1/kv', this.workos.baseURL);\n if (options?.after) {\n url.searchParams.set('after', options.after);\n }\n if (options?.limit) {\n url.searchParams.set('limit', options.limit.toString());\n }\n\n const { data } = await this.workos.get<ListResponse<ObjectDigestResponse>>(\n url.toString(),\n );\n return deserializeListObjects(data);\n }\n\n async listObjectVersions(\n options: ReadObjectOptions,\n ): Promise<ObjectVersion[]> {\n const { data } = await this.workos.get<ListObjectVersionsResponse>(\n `/vault/v1/kv/${encodeURIComponent(options.id)}/versions`,\n );\n return desrializeListObjectVersions(data);\n }\n\n async readObject(options: ReadObjectOptions): Promise<VaultObject> {\n const { data } = await this.workos.get<ReadObjectResponse>(\n `/vault/v1/kv/${encodeURIComponent(options.id)}`,\n );\n return deserializeObject(data);\n }\n\n async describeObject(options: ReadObjectOptions): Promise<VaultObject> {\n const { data } = await this.workos.get<ReadObjectResponse>(\n `/vault/v1/kv/${encodeURIComponent(options.id)}/metadata`,\n );\n return deserializeObject(data);\n }\n\n async updateObject(options: UpdateObjectOptions): Promise<VaultObject> {\n const { data } = await this.workos.put<ReadObjectResponse>(\n `/vault/v1/kv/${encodeURIComponent(options.id)}`,\n serializeUpdateObjectEntity(options),\n );\n return deserializeObject(data);\n }\n\n async deleteObject(options: DeleteObjectOptions): Promise<void> {\n return this.workos.delete(`/vault/v1/kv/${encodeURIComponent(options.id)}`);\n }\n\n async createDataKey(options: CreateDataKeyOptions): Promise<DataKeyPair> {\n const { data } = await this.workos.post<CreateDataKeyResponse>(\n `/vault/v1/keys/data-key`,\n options,\n );\n return deserializeCreateDataKeyResponse(data);\n }\n\n async decryptDataKey(options: DecryptDataKeyOptions): Promise<DataKey> {\n const { data } = await this.workos.post<DecryptDataKeyResponse>(\n `/vault/v1/keys/decrypt`,\n options,\n );\n return deserializeDecryptDataKeyResponse(data);\n }\n\n async encrypt(\n data: string,\n context: KeyContext,\n associatedData?: string,\n ): Promise<string> {\n const keyPair = await this.createDataKey({\n context,\n });\n\n // Convert base64 key to Uint8Array\n const encoder = new TextEncoder();\n\n // Use our cross-runtime base64 utility\n const key = base64ToUint8Array(keyPair.dataKey.key);\n const keyBlob = base64ToUint8Array(keyPair.encryptedKeys);\n\n const prefixLenBuffer = encodeUInt32(keyBlob.length);\n const aadBuffer = associatedData\n ? encoder.encode(associatedData)\n : undefined;\n\n // Use a 12-byte IV for AES-GCM (industry standard)\n const iv = this.cryptoProvider.randomBytes(12);\n\n const {\n ciphertext,\n iv: resultIv,\n tag,\n } = await this.cryptoProvider.encrypt(\n encoder.encode(data),\n key,\n iv,\n aadBuffer,\n );\n\n // Concatenate all parts into a single array\n const resultArray = new Uint8Array(\n resultIv.length +\n tag.length +\n prefixLenBuffer.length +\n keyBlob.length +\n ciphertext.length,\n );\n\n let offset = 0;\n resultArray.set(resultIv, offset);\n offset += resultIv.length;\n\n resultArray.set(tag, offset);\n offset += tag.length;\n\n resultArray.set(new Uint8Array(prefixLenBuffer), offset);\n offset += prefixLenBuffer.length;\n\n resultArray.set(keyBlob, offset);\n offset += keyBlob.length;\n\n resultArray.set(ciphertext, offset);\n\n // Convert to base64 using our cross-runtime utility\n return uint8ArrayToBase64(resultArray);\n }\n\n async decrypt(\n encryptedData: string,\n associatedData?: string,\n ): Promise<string> {\n const decoded = this.decode(encryptedData);\n const dataKey = await this.decryptDataKey({ keys: decoded.keys });\n\n // Convert base64 key to Uint8Array using our cross-runtime utility\n const key = base64ToUint8Array(dataKey.key);\n\n const encoder = new TextEncoder();\n const aadBuffer = associatedData\n ? encoder.encode(associatedData)\n : undefined;\n\n const decrypted = await this.cryptoProvider.decrypt(\n decoded.ciphertext,\n key,\n decoded.iv,\n decoded.tag,\n aadBuffer,\n );\n\n return new TextDecoder().decode(decrypted);\n }\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../src/vault/vault.ts"],"sourcesContent":["import { decodeUInt32, encodeUInt32 } from '../common/utils/leb128';\nimport { CryptoProvider } from '../common/crypto/crypto-provider';\nimport { List, ListResponse } from '../common/interfaces';\nimport { PaginationOptions } from '../index.worker';\nimport { base64ToUint8Array, uint8ArrayToBase64 } from '../common/utils/base64';\nimport type { WorkOS } from '../workos';\nimport {\n CreateDataKeyOptions,\n CreateDataKeyResponse,\n CreateObjectOptions,\n DataKey,\n DataKeyPair,\n DecryptDataKeyOptions,\n DecryptDataKeyResponse,\n DeleteObjectOptions,\n KeyContext,\n ListObjectVersionsResponse,\n ObjectDigest,\n ObjectDigestResponse,\n ObjectMetadata,\n ObjectVersion,\n ReadObjectMetadataResponse,\n ReadObjectOptions,\n ReadObjectResponse,\n UpdateObjectOptions,\n VaultObject,\n} from './interfaces';\nimport {\n deserializeCreateDataKeyResponse,\n deserializeDecryptDataKeyResponse,\n} from './serializers/vault-key.serializer';\nimport {\n deserializeListObjects,\n deserializeObject,\n deserializeObjectMetadata,\n desrializeListObjectVersions,\n serializeCreateObjectEntity,\n serializeUpdateObjectEntity,\n} from './serializers/vault-object.serializer';\n\ninterface Decoded {\n iv: Uint8Array;\n tag: Uint8Array;\n keys: string;\n ciphertext: Uint8Array;\n}\n\nexport class Vault {\n private cryptoProvider: CryptoProvider;\n\n constructor(private readonly workos: WorkOS) {\n this.cryptoProvider = workos.getCryptoProvider();\n }\n\n private decode(payload: string): Decoded {\n const inputData = base64ToUint8Array(payload);\n // Use 12 bytes for IV (standard for AES-GCM)\n const iv = new Uint8Array(inputData.subarray(0, 12));\n const tag = new Uint8Array(inputData.subarray(12, 28));\n const { value: keyLen, nextIndex } = decodeUInt32(inputData, 28);\n\n // Use subarray instead of slice and convert directly to base64\n const keysBuffer = inputData.subarray(nextIndex, nextIndex + keyLen);\n const keys = uint8ArrayToBase64(keysBuffer);\n\n const ciphertext = new Uint8Array(inputData.subarray(nextIndex + keyLen));\n\n return {\n iv,\n tag,\n keys,\n ciphertext,\n };\n }\n\n async createObject(options: CreateObjectOptions): Promise<ObjectMetadata> {\n const { data } = await this.workos.post<ReadObjectMetadataResponse>(\n `/vault/v1/kv`,\n serializeCreateObjectEntity(options),\n );\n return deserializeObjectMetadata(data);\n }\n\n async listObjects(\n options?: PaginationOptions | undefined,\n ): Promise<List<ObjectDigest>> {\n const url = new URL('/vault/v1/kv', this.workos.baseURL);\n if (options?.after) {\n url.searchParams.set('after', options.after);\n }\n if (options?.limit) {\n url.searchParams.set('limit', options.limit.toString());\n }\n\n const { data } = await this.workos.get<ListResponse<ObjectDigestResponse>>(\n url.toString(),\n );\n return deserializeListObjects(data);\n }\n\n async listObjectVersions(\n options: ReadObjectOptions,\n ): Promise<ObjectVersion[]> {\n const { data } = await this.workos.get<ListObjectVersionsResponse>(\n `/vault/v1/kv/${encodeURIComponent(options.id)}/versions`,\n );\n return desrializeListObjectVersions(data);\n }\n\n async readObject(options: ReadObjectOptions): Promise<VaultObject> {\n const { data } = await this.workos.get<ReadObjectResponse>(\n `/vault/v1/kv/${encodeURIComponent(options.id)}`,\n );\n return deserializeObject(data);\n }\n\n async describeObject(options: ReadObjectOptions): Promise<VaultObject> {\n const { data } = await this.workos.get<ReadObjectResponse>(\n `/vault/v1/kv/${encodeURIComponent(options.id)}/metadata`,\n );\n return deserializeObject(data);\n }\n\n async updateObject(options: UpdateObjectOptions): Promise<VaultObject> {\n const { data } = await this.workos.put<ReadObjectResponse>(\n `/vault/v1/kv/${encodeURIComponent(options.id)}`,\n serializeUpdateObjectEntity(options),\n );\n return deserializeObject(data);\n }\n\n async deleteObject(options: DeleteObjectOptions): Promise<void> {\n return this.workos.delete(`/vault/v1/kv/${encodeURIComponent(options.id)}`);\n }\n\n async createDataKey(options: CreateDataKeyOptions): Promise<DataKeyPair> {\n const { data } = await this.workos.post<CreateDataKeyResponse>(\n `/vault/v1/keys/data-key`,\n options,\n );\n return deserializeCreateDataKeyResponse(data);\n }\n\n async decryptDataKey(options: DecryptDataKeyOptions): Promise<DataKey> {\n const { data } = await this.workos.post<DecryptDataKeyResponse>(\n `/vault/v1/keys/decrypt`,\n options,\n );\n return deserializeDecryptDataKeyResponse(data);\n }\n\n async encrypt(\n data: string,\n context: KeyContext,\n associatedData?: string,\n ): Promise<string> {\n const keyPair = await this.createDataKey({\n context,\n });\n\n // Convert base64 key to Uint8Array\n const encoder = new TextEncoder();\n\n // Use our cross-runtime base64 utility\n const key = base64ToUint8Array(keyPair.dataKey.key);\n const keyBlob = base64ToUint8Array(keyPair.encryptedKeys);\n\n const prefixLenBuffer = encodeUInt32(keyBlob.length);\n const aadBuffer = associatedData\n ? encoder.encode(associatedData)\n : undefined;\n\n // Use a 12-byte IV for AES-GCM (industry standard)\n const iv = this.cryptoProvider.randomBytes(12);\n\n const {\n ciphertext,\n iv: resultIv,\n tag,\n } = await this.cryptoProvider.encrypt(\n encoder.encode(data),\n key,\n iv,\n aadBuffer,\n );\n\n // Concatenate all parts into a single array\n const resultArray = new Uint8Array(\n resultIv.length +\n tag.length +\n prefixLenBuffer.length +\n keyBlob.length +\n ciphertext.length,\n );\n\n let offset = 0;\n resultArray.set(resultIv, offset);\n offset += resultIv.length;\n\n resultArray.set(tag, offset);\n offset += tag.length;\n\n resultArray.set(new Uint8Array(prefixLenBuffer), offset);\n offset += prefixLenBuffer.length;\n\n resultArray.set(keyBlob, offset);\n offset += keyBlob.length;\n\n resultArray.set(ciphertext, offset);\n\n // Convert to base64 using our cross-runtime utility\n return uint8ArrayToBase64(resultArray);\n }\n\n async decrypt(\n encryptedData: string,\n associatedData?: string,\n ): Promise<string> {\n const decoded = this.decode(encryptedData);\n const dataKey = await this.decryptDataKey({ keys: decoded.keys });\n\n // Convert base64 key to Uint8Array using our cross-runtime utility\n const key = base64ToUint8Array(dataKey.key);\n\n const encoder = new TextEncoder();\n const aadBuffer = associatedData\n ? encoder.encode(associatedData)\n : undefined;\n\n const decrypted = await this.cryptoProvider.decrypt(\n decoded.ciphertext,\n key,\n decoded.iv,\n decoded.tag,\n aadBuffer,\n );\n\n return new TextDecoder().decode(decrypted);\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAA2C;AAI3C,oBAAuD;AAuBvD,uBAGO;AACP,0BAOO;AASA,MAAM,MAAM;AAAA,EAGjB,YAA6B,QAAgB;AAAhB;AAC3B,SAAK,iBAAiB,OAAO,kBAAkB;AAAA,EACjD;AAAA,EApDF,OA+CmB;AAAA;AAAA;AAAA,EACT;AAAA,EAMA,OAAO,SAA0B;AACvC,UAAM,gBAAY,kCAAmB,OAAO;AAE5C,UAAM,KAAK,IAAI,WAAW,UAAU,SAAS,GAAG,EAAE,CAAC;AACnD,UAAM,MAAM,IAAI,WAAW,UAAU,SAAS,IAAI,EAAE,CAAC;AACrD,UAAM,EAAE,OAAO,QAAQ,UAAU,QAAI,4BAAa,WAAW,EAAE;AAG/D,UAAM,aAAa,UAAU,SAAS,WAAW,YAAY,MAAM;AACnE,UAAM,WAAO,kCAAmB,UAAU;AAE1C,UAAM,aAAa,IAAI,WAAW,UAAU,SAAS,YAAY,MAAM,CAAC;AAExE,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,aAAa,SAAuD;AACxE,UAAM,EAAE,KAAK,IAAI,MAAM,KAAK,OAAO;AAAA,MACjC;AAAA,UACA,iDAA4B,OAAO;AAAA,IACrC;AACA,eAAO,+CAA0B,IAAI;AAAA,EACvC;AAAA,EAEA,MAAM,YACJ,SAC6B;AAC7B,UAAM,MAAM,IAAI,IAAI,gBAAgB,KAAK,OAAO,OAAO;AACvD,QAAI,SAAS,OAAO;AAClB,UAAI,aAAa,IAAI,SAAS,QAAQ,KAAK;AAAA,IAC7C;AACA,QAAI,SAAS,OAAO;AAClB,UAAI,aAAa,IAAI,SAAS,QAAQ,MAAM,SAAS,CAAC;AAAA,IACxD;AAEA,UAAM,EAAE,KAAK,IAAI,MAAM,KAAK,OAAO;AAAA,MACjC,IAAI,SAAS;AAAA,IACf;AACA,eAAO,4CAAuB,IAAI;AAAA,EACpC;AAAA,EAEA,MAAM,mBACJ,SAC0B;AAC1B,UAAM,EAAE,KAAK,IAAI,MAAM,KAAK,OAAO;AAAA,MACjC,gBAAgB,mBAAmB,QAAQ,EAAE,CAAC;AAAA,IAChD;AACA,eAAO,kDAA6B,IAAI;AAAA,EAC1C;AAAA,EAEA,MAAM,WAAW,SAAkD;AACjE,UAAM,EAAE,KAAK,IAAI,MAAM,KAAK,OAAO;AAAA,MACjC,gBAAgB,mBAAmB,QAAQ,EAAE,CAAC;AAAA,IAChD;AACA,eAAO,uCAAkB,IAAI;AAAA,EAC/B;AAAA,EAEA,MAAM,eAAe,SAAkD;AACrE,UAAM,EAAE,KAAK,IAAI,MAAM,KAAK,OAAO;AAAA,MACjC,gBAAgB,mBAAmB,QAAQ,EAAE,CAAC;AAAA,IAChD;AACA,eAAO,uCAAkB,IAAI;AAAA,EAC/B;AAAA,EAEA,MAAM,aAAa,SAAoD;AACrE,UAAM,EAAE,KAAK,IAAI,MAAM,KAAK,OAAO;AAAA,MACjC,gBAAgB,mBAAmB,QAAQ,EAAE,CAAC;AAAA,UAC9C,iDAA4B,OAAO;AAAA,IACrC;AACA,eAAO,uCAAkB,IAAI;AAAA,EAC/B;AAAA,EAEA,MAAM,aAAa,SAA6C;AAC9D,WAAO,KAAK,OAAO,OAAO,gBAAgB,mBAAmB,QAAQ,EAAE,CAAC,EAAE;AAAA,EAC5E;AAAA,EAEA,MAAM,cAAc,SAAqD;AACvE,UAAM,EAAE,KAAK,IAAI,MAAM,KAAK,OAAO;AAAA,MACjC;AAAA,MACA;AAAA,IACF;AACA,eAAO,mDAAiC,IAAI;AAAA,EAC9C;AAAA,EAEA,MAAM,eAAe,SAAkD;AACrE,UAAM,EAAE,KAAK,IAAI,MAAM,KAAK,OAAO;AAAA,MACjC;AAAA,MACA;AAAA,IACF;AACA,eAAO,oDAAkC,IAAI;AAAA,EAC/C;AAAA,EAEA,MAAM,QACJ,MACA,SACA,gBACiB;AACjB,UAAM,UAAU,MAAM,KAAK,cAAc;AAAA,MACvC;AAAA,IACF,CAAC;AAGD,UAAM,UAAU,IAAI,YAAY;AAGhC,UAAM,UAAM,kCAAmB,QAAQ,QAAQ,GAAG;AAClD,UAAM,cAAU,kCAAmB,QAAQ,aAAa;AAExD,UAAM,sBAAkB,4BAAa,QAAQ,MAAM;AACnD,UAAM,YAAY,iBACd,QAAQ,OAAO,cAAc,IAC7B;AAGJ,UAAM,KAAK,KAAK,eAAe,YAAY,EAAE;AAE7C,UAAM;AAAA,MACJ;AAAA,MACA,IAAI;AAAA,MACJ;AAAA,IACF,IAAI,MAAM,KAAK,eAAe;AAAA,MAC5B,QAAQ,OAAO,IAAI;AAAA,MACnB;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAGA,UAAM,cAAc,IAAI;AAAA,MACtB,SAAS,SACP,IAAI,SACJ,gBAAgB,SAChB,QAAQ,SACR,WAAW;AAAA,IACf;AAEA,QAAI,SAAS;AACb,gBAAY,IAAI,UAAU,MAAM;AAChC,cAAU,SAAS;AAEnB,gBAAY,IAAI,KAAK,MAAM;AAC3B,cAAU,IAAI;AAEd,gBAAY,IAAI,IAAI,WAAW,eAAe,GAAG,MAAM;AACvD,cAAU,gBAAgB;AAE1B,gBAAY,IAAI,SAAS,MAAM;AAC/B,cAAU,QAAQ;AAElB,gBAAY,IAAI,YAAY,MAAM;AAGlC,eAAO,kCAAmB,WAAW;AAAA,EACvC;AAAA,EAEA,MAAM,QACJ,eACA,gBACiB;AACjB,UAAM,UAAU,KAAK,OAAO,aAAa;AACzC,UAAM,UAAU,MAAM,KAAK,eAAe,EAAE,MAAM,QAAQ,KAAK,CAAC;AAGhE,UAAM,UAAM,kCAAmB,QAAQ,GAAG;AAE1C,UAAM,UAAU,IAAI,YAAY;AAChC,UAAM,YAAY,iBACd,QAAQ,OAAO,cAAc,IAC7B;AAEJ,UAAM,YAAY,MAAM,KAAK,eAAe;AAAA,MAC1C,QAAQ;AAAA,MACR;AAAA,MACA,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR;AAAA,IACF;AAEA,WAAO,IAAI,YAAY,EAAE,OAAO,SAAS;AAAA,EAC3C;AACF;","names":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/widgets/interfaces/get-token.ts"],"sourcesContent":["export type WidgetScope =\n | 'widgets:users-table:manage'\n | 'widgets:sso:manage'\n | 'widgets:domain-verification:manage';\
|
|
1
|
+
{"version":3,"sources":["../../../../src/widgets/interfaces/get-token.ts"],"sourcesContent":["export type WidgetScope =\n | 'widgets:users-table:manage'\n | 'widgets:sso:manage'\n | 'widgets:domain-verification:manage'\n | 'widgets:api-keys:manage';\nexport interface GetTokenOptions {\n organizationId: string;\n userId?: string;\n scopes?: WidgetScope[];\n}\n\nexport interface SerializedGetTokenOptions {\n organization_id: string;\n user_id?: string;\n scopes?: WidgetScope[];\n}\n\nexport const serializeGetTokenOptions = (\n options: GetTokenOptions,\n): SerializedGetTokenOptions => ({\n organization_id: options.organizationId,\n user_id: options.userId,\n scopes: options.scopes,\n});\n\nexport interface GetTokenResponse {\n token: string;\n}\n\nexport interface GetTokenResponseResponse {\n token: string;\n}\n\nexport const deserializeGetTokenResponse = (\n data: GetTokenResponseResponse,\n): GetTokenResponse => ({\n token: data.token,\n});\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAiBO,MAAM,2BAA2B,wBACtC,aAC+B;AAAA,EAC/B,iBAAiB,QAAQ;AAAA,EACzB,SAAS,QAAQ;AAAA,EACjB,QAAQ,QAAQ;AAClB,IANwC;AAgBjC,MAAM,8BAA8B,wBACzC,UACsB;AAAA,EACtB,OAAO,KAAK;AACd,IAJ2C;","names":[]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
type WidgetScope = 'widgets:users-table:manage' | 'widgets:sso:manage' | 'widgets:domain-verification:manage';
|
|
1
|
+
type WidgetScope = 'widgets:users-table:manage' | 'widgets:sso:manage' | 'widgets:domain-verification:manage' | 'widgets:api-keys:manage';
|
|
2
2
|
interface GetTokenOptions {
|
|
3
3
|
organizationId: string;
|
|
4
4
|
userId?: string;
|