@hexclave/shared 1.0.23 → 1.0.25
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/ai/unified-prompts/reminders.js +1 -0
- package/dist/ai/unified-prompts/reminders.js.map +1 -1
- package/dist/ai/unified-prompts/skill-site-prompt-parts/ai-setup-prompt.d.ts.map +1 -1
- package/dist/ai/unified-prompts/skill-site-prompt-parts/ai-setup-prompt.js +15 -0
- package/dist/ai/unified-prompts/skill-site-prompt-parts/ai-setup-prompt.js.map +1 -1
- package/dist/ai/unified-prompts/skill-site-prompt-parts/docs-json.generated.d.ts +1 -46
- package/dist/ai/unified-prompts/skill-site-prompt-parts/docs-json.generated.js +1 -62
- package/dist/ai/unified-prompts/skill-site-prompt-parts/docs-json.generated.js.map +1 -1
- package/dist/config/schema.d.ts +30 -30
- package/dist/config-authoring.d.ts +2 -2
- package/dist/config-authoring.d.ts.map +1 -1
- package/dist/config-authoring.js.map +1 -1
- package/dist/esm/ai/unified-prompts/reminders.js +1 -0
- package/dist/esm/ai/unified-prompts/reminders.js.map +1 -1
- package/dist/esm/ai/unified-prompts/skill-site-prompt-parts/ai-setup-prompt.d.ts.map +1 -1
- package/dist/esm/ai/unified-prompts/skill-site-prompt-parts/ai-setup-prompt.js +15 -0
- package/dist/esm/ai/unified-prompts/skill-site-prompt-parts/ai-setup-prompt.js.map +1 -1
- package/dist/esm/ai/unified-prompts/skill-site-prompt-parts/docs-json.generated.d.ts +1 -46
- package/dist/esm/ai/unified-prompts/skill-site-prompt-parts/docs-json.generated.js +1 -62
- package/dist/esm/ai/unified-prompts/skill-site-prompt-parts/docs-json.generated.js.map +1 -1
- package/dist/esm/config/schema.d.ts +30 -30
- package/dist/esm/config-authoring.d.ts +2 -2
- package/dist/esm/config-authoring.d.ts.map +1 -1
- package/dist/esm/config-authoring.js.map +1 -1
- package/dist/esm/interface/admin-metrics.d.ts +10 -10
- package/dist/esm/interface/conversations.d.ts +11 -11
- package/dist/esm/interface/crud/current-user.d.ts +8 -8
- package/dist/esm/interface/crud/email-outbox.d.ts +184 -184
- package/dist/esm/interface/crud/invoices.d.ts +2 -2
- package/dist/esm/interface/crud/products.d.ts +15 -15
- package/dist/esm/interface/crud/products.d.ts.map +1 -1
- package/dist/esm/interface/crud/project-api-keys.d.ts +4 -4
- package/dist/esm/interface/crud/projects.d.ts +50 -0
- package/dist/esm/interface/crud/projects.d.ts.map +1 -1
- package/dist/esm/interface/crud/projects.js +6 -0
- package/dist/esm/interface/crud/projects.js.map +1 -1
- package/dist/esm/interface/crud/team-member-profiles.d.ts +12 -12
- package/dist/esm/interface/crud/transactions.d.ts +20 -20
- package/dist/esm/interface/crud/transactions.d.ts.map +1 -1
- package/dist/esm/interface/crud/users.d.ts +8 -8
- package/dist/esm/interface/webhooks.d.ts +2 -2
- package/dist/esm/known-errors.d.ts +1 -1
- package/dist/esm/schema-fields.d.ts +1 -1
- package/dist/esm/sessions.d.ts +7 -7
- package/dist/esm/utils/env.d.ts +2 -1
- package/dist/esm/utils/env.d.ts.map +1 -1
- package/dist/esm/utils/env.js +29 -17
- package/dist/esm/utils/env.js.map +1 -1
- package/dist/esm/utils/env.test.d.ts +1 -0
- package/dist/esm/utils/env.test.js +49 -0
- package/dist/esm/utils/env.test.js.map +1 -0
- package/dist/esm/utils/errors.d.ts.map +1 -1
- package/dist/esm/utils/errors.js +4 -1
- package/dist/esm/utils/errors.js.map +1 -1
- package/dist/interface/admin-metrics.d.ts +10 -10
- package/dist/interface/conversations.d.ts +11 -11
- package/dist/interface/crud/current-user.d.ts +8 -8
- package/dist/interface/crud/email-outbox.d.ts +184 -184
- package/dist/interface/crud/invoices.d.ts +2 -2
- package/dist/interface/crud/products.d.ts +15 -15
- package/dist/interface/crud/products.d.ts.map +1 -1
- package/dist/interface/crud/project-api-keys.d.ts +4 -4
- package/dist/interface/crud/projects.d.ts +50 -0
- package/dist/interface/crud/projects.d.ts.map +1 -1
- package/dist/interface/crud/projects.js +6 -0
- package/dist/interface/crud/projects.js.map +1 -1
- package/dist/interface/crud/team-member-profiles.d.ts +12 -12
- package/dist/interface/crud/transactions.d.ts +20 -20
- package/dist/interface/crud/transactions.d.ts.map +1 -1
- package/dist/interface/crud/users.d.ts +8 -8
- package/dist/interface/webhooks.d.ts +2 -2
- package/dist/known-errors.d.ts +1 -1
- package/dist/schema-fields.d.ts +1 -1
- package/dist/sessions.d.ts +7 -7
- package/dist/utils/env.d.ts +2 -1
- package/dist/utils/env.d.ts.map +1 -1
- package/dist/utils/env.js +29 -16
- package/dist/utils/env.js.map +1 -1
- package/dist/utils/env.test.d.ts +1 -0
- package/dist/utils/env.test.js +49 -0
- package/dist/utils/env.test.js.map +1 -0
- package/dist/utils/errors.d.ts.map +1 -1
- package/dist/utils/errors.js +4 -1
- package/dist/utils/errors.js.map +1 -1
- package/package.json +1 -1
- package/src/ai/unified-prompts/reminders.ts +1 -0
- package/src/ai/unified-prompts/skill-site-prompt-parts/ai-setup-prompt.ts +15 -0
- package/src/ai/unified-prompts/skill-site-prompt-parts/docs-json.generated.ts +1 -62
- package/src/config-authoring.ts +2 -2
- package/src/interface/crud/projects.ts +12 -0
- package/src/utils/env.test.tsx +58 -0
- package/src/utils/env.tsx +36 -20
- package/src/utils/errors.tsx +6 -1
|
@@ -83,8 +83,8 @@ declare const usersCrudServerReadSchema: yup$1.ObjectSchema<{
|
|
|
83
83
|
server_metadata?: {} | null | undefined;
|
|
84
84
|
display_name: string;
|
|
85
85
|
id: string;
|
|
86
|
-
created_at_millis: number;
|
|
87
86
|
profile_image_url: string | null;
|
|
87
|
+
created_at_millis: number;
|
|
88
88
|
} | null;
|
|
89
89
|
selected_team_id: string | null;
|
|
90
90
|
profile_image_url: string | null;
|
|
@@ -163,12 +163,12 @@ declare const usersCrudServerReadSchema: yup$1.ObjectSchema<{
|
|
|
163
163
|
requires_totp_mfa: undefined;
|
|
164
164
|
}, "">;
|
|
165
165
|
declare const usersCrudServerCreateSchema: yup$1.ObjectSchema<{
|
|
166
|
-
|
|
166
|
+
is_anonymous: boolean | undefined;
|
|
167
167
|
display_name: string | null | undefined;
|
|
168
168
|
client_metadata: {} | null | undefined;
|
|
169
169
|
client_read_only_metadata: {} | null | undefined;
|
|
170
170
|
server_metadata: {} | null | undefined;
|
|
171
|
-
|
|
171
|
+
primary_email: string | null | undefined;
|
|
172
172
|
password: string | null | undefined;
|
|
173
173
|
primary_email_verified: boolean | undefined;
|
|
174
174
|
primary_email_auth_enabled: boolean | undefined;
|
|
@@ -236,8 +236,8 @@ declare const usersCrud: ______crud0.CrudSchemaFromOptions<{
|
|
|
236
236
|
server_metadata?: {} | null | undefined;
|
|
237
237
|
display_name: string;
|
|
238
238
|
id: string;
|
|
239
|
-
created_at_millis: number;
|
|
240
239
|
profile_image_url: string | null;
|
|
240
|
+
created_at_millis: number;
|
|
241
241
|
} | null;
|
|
242
242
|
selected_team_id: string | null;
|
|
243
243
|
profile_image_url: string | null;
|
|
@@ -369,12 +369,12 @@ declare const usersCrud: ______crud0.CrudSchemaFromOptions<{
|
|
|
369
369
|
};
|
|
370
370
|
}, "">;
|
|
371
371
|
serverCreateSchema: yup$1.ObjectSchema<{
|
|
372
|
-
|
|
372
|
+
is_anonymous: boolean | undefined;
|
|
373
373
|
display_name: string | null | undefined;
|
|
374
374
|
client_metadata: {} | null | undefined;
|
|
375
375
|
client_read_only_metadata: {} | null | undefined;
|
|
376
376
|
server_metadata: {} | null | undefined;
|
|
377
|
-
|
|
377
|
+
primary_email: string | null | undefined;
|
|
378
378
|
password: string | null | undefined;
|
|
379
379
|
primary_email_verified: boolean | undefined;
|
|
380
380
|
primary_email_auth_enabled: boolean | undefined;
|
|
@@ -470,8 +470,8 @@ declare const userCreatedWebhookEvent: WebhookEvent<yup$1.ObjectSchema<{
|
|
|
470
470
|
server_metadata?: {} | null | undefined;
|
|
471
471
|
display_name: string;
|
|
472
472
|
id: string;
|
|
473
|
-
created_at_millis: number;
|
|
474
473
|
profile_image_url: string | null;
|
|
474
|
+
created_at_millis: number;
|
|
475
475
|
} | null;
|
|
476
476
|
selected_team_id: string | null;
|
|
477
477
|
profile_image_url: string | null;
|
|
@@ -561,8 +561,8 @@ declare const userUpdatedWebhookEvent: WebhookEvent<yup$1.ObjectSchema<{
|
|
|
561
561
|
server_metadata?: {} | null | undefined;
|
|
562
562
|
display_name: string;
|
|
563
563
|
id: string;
|
|
564
|
-
created_at_millis: number;
|
|
565
564
|
profile_image_url: string | null;
|
|
565
|
+
created_at_millis: number;
|
|
566
566
|
} | null;
|
|
567
567
|
selected_team_id: string | null;
|
|
568
568
|
profile_image_url: string | null;
|
|
@@ -22,8 +22,8 @@ declare const webhookEvents: readonly [WebhookEvent<yup$1.ObjectSchema<{
|
|
|
22
22
|
server_metadata?: {} | null | undefined;
|
|
23
23
|
display_name: string;
|
|
24
24
|
id: string;
|
|
25
|
-
created_at_millis: number;
|
|
26
25
|
profile_image_url: string | null;
|
|
26
|
+
created_at_millis: number;
|
|
27
27
|
} | null;
|
|
28
28
|
selected_team_id: string | null;
|
|
29
29
|
profile_image_url: string | null;
|
|
@@ -112,8 +112,8 @@ declare const webhookEvents: readonly [WebhookEvent<yup$1.ObjectSchema<{
|
|
|
112
112
|
server_metadata?: {} | null | undefined;
|
|
113
113
|
display_name: string;
|
|
114
114
|
id: string;
|
|
115
|
-
created_at_millis: number;
|
|
116
115
|
profile_image_url: string | null;
|
|
116
|
+
created_at_millis: number;
|
|
117
117
|
} | null;
|
|
118
118
|
selected_team_id: string | null;
|
|
119
119
|
profile_image_url: string | null;
|
|
@@ -518,7 +518,7 @@ declare const KnownErrors: {
|
|
|
518
518
|
CustomerDoesNotExist: KnownErrorConstructor<KnownError & KnownErrorBrand<"CUSTOMER_DOES_NOT_EXIST">, [customerId: string]> & {
|
|
519
519
|
errorCode: "CUSTOMER_DOES_NOT_EXIST";
|
|
520
520
|
};
|
|
521
|
-
ProductDoesNotExist: KnownErrorConstructor<KnownError & KnownErrorBrand<"PRODUCT_DOES_NOT_EXIST">, [productId: string, context: "
|
|
521
|
+
ProductDoesNotExist: KnownErrorConstructor<KnownError & KnownErrorBrand<"PRODUCT_DOES_NOT_EXIST">, [productId: string, context: "server_only" | "item_exists" | null]> & {
|
|
522
522
|
errorCode: "PRODUCT_DOES_NOT_EXIST";
|
|
523
523
|
};
|
|
524
524
|
ProductCustomerTypeDoesNotMatch: KnownErrorConstructor<KnownError & KnownErrorBrand<"PRODUCT_CUSTOMER_TYPE_DOES_NOT_MATCH">, [productId: string | undefined, customerId: string, productCustomerType: "team" | "user" | "custom" | undefined, actualCustomerType: "team" | "user" | "custom"]> & {
|
|
@@ -314,8 +314,8 @@ declare const inlineProductSchema: yup$1.ObjectSchema<{
|
|
|
314
314
|
free_trial?: DayInterval | undefined;
|
|
315
315
|
}>;
|
|
316
316
|
included_items: Record<string, {
|
|
317
|
-
quantity?: number | undefined;
|
|
318
317
|
repeat?: "never" | DayInterval | undefined;
|
|
318
|
+
quantity?: number | undefined;
|
|
319
319
|
expires?: "never" | "when-purchase-expires" | "when-repeated" | undefined;
|
|
320
320
|
}>;
|
|
321
321
|
client_metadata: {} | null | undefined;
|
package/dist/esm/sessions.d.ts
CHANGED
|
@@ -9,24 +9,24 @@ declare class AccessToken {
|
|
|
9
9
|
private constructor();
|
|
10
10
|
get payload(): {
|
|
11
11
|
exp?: number | undefined;
|
|
12
|
-
project_id: string;
|
|
13
|
-
refresh_token_id: string;
|
|
14
|
-
email: string | null;
|
|
15
|
-
restricted_reason: {
|
|
16
|
-
type: "anonymous" | "email_not_verified" | "restricted_by_administrator";
|
|
17
|
-
} | null;
|
|
18
|
-
branch_id: string;
|
|
19
12
|
sub: string;
|
|
20
13
|
iat: number;
|
|
21
14
|
iss: string;
|
|
22
15
|
aud: string;
|
|
16
|
+
project_id: string;
|
|
17
|
+
branch_id: string;
|
|
18
|
+
refresh_token_id: string;
|
|
23
19
|
role: "authenticated";
|
|
24
20
|
name: string | null;
|
|
21
|
+
email: string | null;
|
|
25
22
|
email_verified: boolean;
|
|
26
23
|
selected_team_id: string | null;
|
|
27
24
|
signed_up_at: number;
|
|
28
25
|
is_anonymous: boolean;
|
|
29
26
|
is_restricted: boolean;
|
|
27
|
+
restricted_reason: {
|
|
28
|
+
type: "anonymous" | "email_not_verified" | "restricted_by_administrator";
|
|
29
|
+
} | null;
|
|
30
30
|
requires_totp_mfa: boolean;
|
|
31
31
|
};
|
|
32
32
|
get expiresAt(): Date;
|
package/dist/esm/utils/env.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
//#region src/utils/env.d.ts
|
|
2
2
|
declare function isBrowserLike(): boolean;
|
|
3
|
+
declare function resolveHexclaveStackEnvVarValue(hexclaveName: string, stackName: string, hexclaveValue: string | undefined, stackValue: string | undefined): string | undefined;
|
|
3
4
|
/**
|
|
4
5
|
* Returns the environment variable with the given name, returning the default (if given) or throwing an error (otherwise) if it's undefined or the empty string.
|
|
5
6
|
*/
|
|
@@ -21,5 +22,5 @@ declare function getNodeEnvironment(): string;
|
|
|
21
22
|
*/
|
|
22
23
|
declare function getProcessEnv(name: string): string | undefined;
|
|
23
24
|
//#endregion
|
|
24
|
-
export { getEnvBoolean, getEnvVariable, getNextRuntime, getNodeEnvironment, getProcessEnv, isBrowserLike };
|
|
25
|
+
export { getEnvBoolean, getEnvVariable, getNextRuntime, getNodeEnvironment, getProcessEnv, isBrowserLike, resolveHexclaveStackEnvVarValue };
|
|
25
26
|
//# sourceMappingURL=env.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"env.d.ts","names":[],"sources":["../../../src/utils/env.tsx"],"mappings":";iBAGgB,aAAA,CAAA;
|
|
1
|
+
{"version":3,"file":"env.d.ts","names":[],"sources":["../../../src/utils/env.tsx"],"mappings":";iBAGgB,aAAA,CAAA;AAAA,iBASA,+BAAA,CAAgC,YAAA,UAAsB,SAAA,UAAmB,aAAA,sBAAmC,UAAA;;;;iBAgC5G,cAAA,CAAe,IAAA,UAAc,YAAA;AAAA,iBAgD7B,aAAA,CAAc,IAAA;AAAA,iBAWd,cAAA,CAAA;AAAA,iBAKA,kBAAA,CAAA;;;;;;;;AAhEhB;;;;;iBAgFgB,aAAA,CAAc,IAAA"}
|
package/dist/esm/utils/env.js
CHANGED
|
@@ -6,16 +6,30 @@ function isBrowserLike() {
|
|
|
6
6
|
return typeof window !== "undefined" && typeof document !== "undefined" && typeof document.createElement !== "undefined";
|
|
7
7
|
}
|
|
8
8
|
const ENV_VAR_RENAME = { NEXT_PUBLIC_STACK_API_URL: ["STACK_BASE_URL", "NEXT_PUBLIC_STACK_URL"] };
|
|
9
|
+
function resolveHexclaveStackEnvVarValue(hexclaveName, stackName, hexclaveValue, stackValue) {
|
|
10
|
+
if (hexclaveValue && stackValue && hexclaveValue !== stackValue) throw new Error(`Environment variables ${hexclaveName} and ${stackName} are both set to different values. Remove one of them or set them to the same value.`);
|
|
11
|
+
return hexclaveValue || stackValue || void 0;
|
|
12
|
+
}
|
|
9
13
|
/**
|
|
10
|
-
* Hexclave rebrand:
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
14
|
+
* Hexclave rebrand: resolve an env var by reading both the `HEXCLAVE_*` and
|
|
15
|
+
* `STACK_*` spellings, preferring the canonical Hexclave value and falling back
|
|
16
|
+
* to the legacy Stack value (empty counts as unset). Works in BOTH directions —
|
|
17
|
+
* whether the caller passes the legacy `STACK_FOO` name or the canonical
|
|
18
|
+
* `HEXCLAVE_FOO` name, the other spelling is still honored. Covers `STACK_FOO`,
|
|
19
|
+
* `NEXT_PUBLIC_STACK_FOO`, `NEXT_PUBLIC_BROWSER_STACK_FOO`,
|
|
20
|
+
* `NEXT_PUBLIC_SERVER_STACK_FOO`, `VITE_STACK_FOO` and their HEXCLAVE_ twins.
|
|
21
|
+
* Names with neither segment behave exactly as before.
|
|
15
22
|
*/
|
|
16
|
-
function
|
|
17
|
-
if (
|
|
18
|
-
|
|
23
|
+
function getEnvVarWithHexclaveFallback(name) {
|
|
24
|
+
if (name.includes("STACK_")) {
|
|
25
|
+
const hexclaveName = name.replace("STACK_", "HEXCLAVE_");
|
|
26
|
+
return resolveHexclaveStackEnvVarValue(hexclaveName, name, process.env[hexclaveName], process.env[name]);
|
|
27
|
+
}
|
|
28
|
+
if (name.includes("HEXCLAVE_")) {
|
|
29
|
+
const stackName = name.replace("HEXCLAVE_", "STACK_");
|
|
30
|
+
return resolveHexclaveStackEnvVarValue(name, stackName, process.env[name], process.env[stackName]);
|
|
31
|
+
}
|
|
32
|
+
return process.env[name];
|
|
19
33
|
}
|
|
20
34
|
/**
|
|
21
35
|
* Returns the environment variable with the given name, returning the default (if given) or throwing an error (otherwise) if it's undefined or the empty string.
|
|
@@ -31,12 +45,11 @@ function getEnvVariable(name, defaultValue) {
|
|
|
31
45
|
|
|
32
46
|
Use getNextRuntime() instead.
|
|
33
47
|
`);
|
|
34
|
-
for (const [newName, oldNames] of Object.entries(ENV_VAR_RENAME)) if (oldNames
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
if (!value &&
|
|
38
|
-
|
|
39
|
-
value = (hexclaveOldName ? process.env[hexclaveOldName] : void 0) ?? process.env[oldName];
|
|
48
|
+
for (const [newName, oldNames] of Object.entries(ENV_VAR_RENAME)) if (oldNames?.includes(name)) throwErr(`Environment variable ${name} has been renamed to ${newName}. Please update your configuration to use the new name.`);
|
|
49
|
+
let value = getEnvVarWithHexclaveFallback(name);
|
|
50
|
+
const renamedNames = ENV_VAR_RENAME[name];
|
|
51
|
+
if (!value && renamedNames != null) for (const oldName of renamedNames) {
|
|
52
|
+
value = getEnvVarWithHexclaveFallback(oldName);
|
|
40
53
|
if (value) break;
|
|
41
54
|
}
|
|
42
55
|
if (!value) if (defaultValue !== void 0) value = defaultValue;
|
|
@@ -69,10 +82,9 @@ function getNodeEnvironment() {
|
|
|
69
82
|
*/
|
|
70
83
|
function getProcessEnv(name) {
|
|
71
84
|
if (typeof process === "undefined" || typeof process.env === "undefined") return;
|
|
72
|
-
|
|
73
|
-
return (hexclaveName ? process.env[hexclaveName] : void 0) ?? process.env[name];
|
|
85
|
+
return getEnvVarWithHexclaveFallback(name);
|
|
74
86
|
}
|
|
75
87
|
|
|
76
88
|
//#endregion
|
|
77
|
-
export { getEnvBoolean, getEnvVariable, getNextRuntime, getNodeEnvironment, getProcessEnv, isBrowserLike };
|
|
89
|
+
export { getEnvBoolean, getEnvVariable, getNextRuntime, getNodeEnvironment, getProcessEnv, isBrowserLike, resolveHexclaveStackEnvVarValue };
|
|
78
90
|
//# sourceMappingURL=env.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"env.js","names":[],"sources":["../../../src/utils/env.tsx"],"sourcesContent":["import { HexclaveAssertionError, throwErr } from \"./errors\";\nimport { deindent } from \"./strings\";\n\nexport function isBrowserLike() {\n return typeof window !== \"undefined\" && typeof document !== \"undefined\" && typeof document.createElement !== \"undefined\";\n}\n\n// newName: oldName\nconst ENV_VAR_RENAME: Record<string, string[]> = {\n NEXT_PUBLIC_STACK_API_URL: ['STACK_BASE_URL', 'NEXT_PUBLIC_STACK_URL'],\n};\n\n/**\n * Hexclave rebrand:
|
|
1
|
+
{"version":3,"file":"env.js","names":[],"sources":["../../../src/utils/env.tsx"],"sourcesContent":["import { HexclaveAssertionError, throwErr } from \"./errors\";\nimport { deindent } from \"./strings\";\n\nexport function isBrowserLike() {\n return typeof window !== \"undefined\" && typeof document !== \"undefined\" && typeof document.createElement !== \"undefined\";\n}\n\n// newName: oldName\nconst ENV_VAR_RENAME: Record<string, string[] | undefined> = {\n NEXT_PUBLIC_STACK_API_URL: ['STACK_BASE_URL', 'NEXT_PUBLIC_STACK_URL'],\n};\n\nexport function resolveHexclaveStackEnvVarValue(hexclaveName: string, stackName: string, hexclaveValue: string | undefined, stackValue: string | undefined): string | undefined {\n if (hexclaveValue && stackValue && hexclaveValue !== stackValue) {\n throw new Error(`Environment variables ${hexclaveName} and ${stackName} are both set to different values. Remove one of them or set them to the same value.`);\n }\n return hexclaveValue || stackValue || undefined;\n}\n\n/**\n * Hexclave rebrand: resolve an env var by reading both the `HEXCLAVE_*` and\n * `STACK_*` spellings, preferring the canonical Hexclave value and falling back\n * to the legacy Stack value (empty counts as unset). Works in BOTH directions —\n * whether the caller passes the legacy `STACK_FOO` name or the canonical\n * `HEXCLAVE_FOO` name, the other spelling is still honored. Covers `STACK_FOO`,\n * `NEXT_PUBLIC_STACK_FOO`, `NEXT_PUBLIC_BROWSER_STACK_FOO`,\n * `NEXT_PUBLIC_SERVER_STACK_FOO`, `VITE_STACK_FOO` and their HEXCLAVE_ twins.\n * Names with neither segment behave exactly as before.\n */\nfunction getEnvVarWithHexclaveFallback(name: string): string | undefined {\n if (name.includes(\"STACK_\")) {\n const hexclaveName = name.replace(\"STACK_\", \"HEXCLAVE_\");\n return resolveHexclaveStackEnvVarValue(hexclaveName, name, process.env[hexclaveName], process.env[name]);\n }\n if (name.includes(\"HEXCLAVE_\")) {\n const stackName = name.replace(\"HEXCLAVE_\", \"STACK_\");\n return resolveHexclaveStackEnvVarValue(name, stackName, process.env[name], process.env[stackName]);\n }\n return process.env[name];\n}\n\n/**\n * Returns the environment variable with the given name, returning the default (if given) or throwing an error (otherwise) if it's undefined or the empty string.\n */\nexport function getEnvVariable(name: string, defaultValue?: string | undefined): string {\n if (isBrowserLike()) {\n throw new Error(deindent`\n Can't use getEnvVariable on the client because Next.js transpiles expressions of the kind process.env.XYZ at build-time on the client.\n \n Use process.env.XYZ directly instead.\n `);\n }\n if (name === \"NEXT_RUNTIME\") {\n throw new Error(deindent`\n Can't use getEnvVariable to access the NEXT_RUNTIME environment variable because it's compiled into the client bundle.\n \n Use getNextRuntime() instead.\n `);\n }\n\n // throw error if the old name is used as the retrieve key\n for (const [newName, oldNames] of Object.entries(ENV_VAR_RENAME)) {\n if (oldNames?.includes(name)) {\n throwErr(`Environment variable ${name} has been renamed to ${newName}. Please update your configuration to use the new name.`);\n }\n }\n\n // Hexclave rebrand: prefer the HEXCLAVE_*-prefixed equivalent, fall back to the STACK_* name.\n // Treat the empty string as unset — the checked-in .env templates define empty\n // HEXCLAVE_* placeholders, which must not shadow a real value under the legacy name.\n let value = getEnvVarWithHexclaveFallback(name);\n\n // check the key under the old name if the new name is not found\n const renamedNames = ENV_VAR_RENAME[name];\n if (!value && renamedNames != null) {\n for (const oldName of renamedNames) {\n value = getEnvVarWithHexclaveFallback(oldName);\n if (value) break;\n }\n }\n\n if (!value) {\n if (defaultValue !== undefined) {\n value = defaultValue;\n } else {\n throwErr(`Missing environment variable: ${name}`);\n }\n }\n\n return value;\n}\n\nexport function getEnvBoolean(name: string): boolean {\n const value = getEnvVariable(name, \"false\");\n if (value === \"true\") {\n return true;\n } else if (value === \"false\") {\n return false;\n } else {\n throw new HexclaveAssertionError(`Environment variable ${name} must be either \"true\" or \"false\": found ${JSON.stringify(value)}`);\n }\n}\n\nexport function getNextRuntime() {\n // This variable is compiled into the client bundle, so we can't use getEnvVariable here.\n return process.env.NEXT_RUNTIME || throwErr(\"Missing environment variable: NEXT_RUNTIME\");\n}\n\nexport function getNodeEnvironment() {\n return getEnvVariable(\"NODE_ENV\", \"\");\n}\n\n/**\n * Browser-safe access to `process.env` for server-only or genuinely dynamic\n * env-var lookups. Returns `undefined` when `process` is not defined (e.g. in\n * a Vite browser bundle without a `process` shim).\n *\n * Note: uses `process.env[name]` (bracket form), which is NOT recognized by\n * Next.js / webpack DefinePlugin for compile-time inlining. If you need\n * build-time inlining for a `NEXT_PUBLIC_*` var, use the literal dot-form at\n * the call site, guarded with `typeof process`:\n *\n * const value = (typeof process !== \"undefined\" ? process.env.NEXT_PUBLIC_FOO : undefined);\n */\nexport function getProcessEnv(name: string): string | undefined {\n if (typeof process === \"undefined\" || typeof process.env === \"undefined\") {\n return undefined;\n }\n // Hexclave rebrand: prefer the HEXCLAVE_*-prefixed equivalent, fall back to the STACK_* name.\n // Empty counts as unset — the checked-in .env templates define empty HEXCLAVE_* placeholders,\n // which must not shadow a real value under the legacy name.\n return getEnvVarWithHexclaveFallback(name);\n}\n"],"mappings":";;;;AAGA,SAAgB,gBAAgB;AAC9B,QAAO,OAAO,WAAW,eAAe,OAAO,aAAa,eAAe,OAAO,SAAS,kBAAkB;;AAI/G,MAAM,iBAAuD,EAC3D,2BAA2B,CAAC,kBAAkB,wBAAwB,EACvE;AAED,SAAgB,gCAAgC,cAAsB,WAAmB,eAAmC,YAAoD;AAC9K,KAAI,iBAAiB,cAAc,kBAAkB,WACnD,OAAM,IAAI,MAAM,yBAAyB,aAAa,OAAO,UAAU,sFAAsF;AAE/J,QAAO,iBAAiB,cAAc;;;;;;;;;;;;AAaxC,SAAS,8BAA8B,MAAkC;AACvE,KAAI,KAAK,SAAS,SAAS,EAAE;EAC3B,MAAM,eAAe,KAAK,QAAQ,UAAU,YAAY;AACxD,SAAO,gCAAgC,cAAc,MAAM,QAAQ,IAAI,eAAe,QAAQ,IAAI,MAAM;;AAE1G,KAAI,KAAK,SAAS,YAAY,EAAE;EAC9B,MAAM,YAAY,KAAK,QAAQ,aAAa,SAAS;AACrD,SAAO,gCAAgC,MAAM,WAAW,QAAQ,IAAI,OAAO,QAAQ,IAAI,WAAW;;AAEpG,QAAO,QAAQ,IAAI;;;;;AAMrB,SAAgB,eAAe,MAAc,cAA2C;AACtF,KAAI,eAAe,CACjB,OAAM,IAAI,MAAM,QAAQ;;;;MAItB;AAEJ,KAAI,SAAS,eACX,OAAM,IAAI,MAAM,QAAQ;;;;MAItB;AAIJ,MAAK,MAAM,CAAC,SAAS,aAAa,OAAO,QAAQ,eAAe,CAC9D,KAAI,UAAU,SAAS,KAAK,CAC1B,UAAS,wBAAwB,KAAK,uBAAuB,QAAQ,yDAAyD;CAOlI,IAAI,QAAQ,8BAA8B,KAAK;CAG/C,MAAM,eAAe,eAAe;AACpC,KAAI,CAAC,SAAS,gBAAgB,KAC5B,MAAK,MAAM,WAAW,cAAc;AAClC,UAAQ,8BAA8B,QAAQ;AAC9C,MAAI,MAAO;;AAIf,KAAI,CAAC,MACH,KAAI,iBAAiB,OACnB,SAAQ;KAER,UAAS,iCAAiC,OAAO;AAIrD,QAAO;;AAGT,SAAgB,cAAc,MAAuB;CACnD,MAAM,QAAQ,eAAe,MAAM,QAAQ;AAC3C,KAAI,UAAU,OACZ,QAAO;UACE,UAAU,QACnB,QAAO;KAEP,OAAM,IAAI,uBAAuB,wBAAwB,KAAK,2CAA2C,KAAK,UAAU,MAAM,GAAG;;AAIrI,SAAgB,iBAAiB;AAE/B,QAAO,QAAQ,IAAI,gBAAgB,SAAS,6CAA6C;;AAG3F,SAAgB,qBAAqB;AACnC,QAAO,eAAe,YAAY,GAAG;;;;;;;;;;;;;;AAevC,SAAgB,cAAc,MAAkC;AAC9D,KAAI,OAAO,YAAY,eAAe,OAAO,QAAQ,QAAQ,YAC3D;AAKF,QAAO,8BAA8B,KAAK"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { };
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
2
|
+
import { getEnvVariable, getProcessEnv, resolveHexclaveStackEnvVarValue } from "./env.js";
|
|
3
|
+
|
|
4
|
+
//#region src/utils/env.test.tsx
|
|
5
|
+
afterEach(() => {
|
|
6
|
+
vi.unstubAllEnvs();
|
|
7
|
+
});
|
|
8
|
+
describe("Hexclave/Stack env var dual-read", () => {
|
|
9
|
+
it("falls back to the legacy Stack name when the Hexclave value is empty", () => {
|
|
10
|
+
vi.stubEnv("NEXT_PUBLIC_HEXCLAVE_API_URL", "");
|
|
11
|
+
vi.stubEnv("NEXT_PUBLIC_STACK_API_URL", "https://stack.example.test");
|
|
12
|
+
expect(getEnvVariable("NEXT_PUBLIC_STACK_API_URL")).toBe("https://stack.example.test");
|
|
13
|
+
expect(getProcessEnv("NEXT_PUBLIC_STACK_API_URL")).toBe("https://stack.example.test");
|
|
14
|
+
});
|
|
15
|
+
it("allows both names when they have the same non-empty value", () => {
|
|
16
|
+
vi.stubEnv("NEXT_PUBLIC_HEXCLAVE_API_URL", "https://api.example.test");
|
|
17
|
+
vi.stubEnv("NEXT_PUBLIC_STACK_API_URL", "https://api.example.test");
|
|
18
|
+
expect(getEnvVariable("NEXT_PUBLIC_STACK_API_URL")).toBe("https://api.example.test");
|
|
19
|
+
expect(getProcessEnv("NEXT_PUBLIC_STACK_API_URL")).toBe("https://api.example.test");
|
|
20
|
+
});
|
|
21
|
+
it("throws when both names are non-empty and different", () => {
|
|
22
|
+
vi.stubEnv("NEXT_PUBLIC_HEXCLAVE_API_URL", "https://hexclave.example.test");
|
|
23
|
+
vi.stubEnv("NEXT_PUBLIC_STACK_API_URL", "https://stack.example.test");
|
|
24
|
+
expect(() => getEnvVariable("NEXT_PUBLIC_STACK_API_URL")).toThrow(/NEXT_PUBLIC_HEXCLAVE_API_URL.*NEXT_PUBLIC_STACK_API_URL.*different values/);
|
|
25
|
+
expect(() => getProcessEnv("NEXT_PUBLIC_STACK_API_URL")).toThrow(/NEXT_PUBLIC_HEXCLAVE_API_URL.*NEXT_PUBLIC_STACK_API_URL.*different values/);
|
|
26
|
+
});
|
|
27
|
+
it("checks renamed legacy aliases when falling back", () => {
|
|
28
|
+
vi.stubEnv("NEXT_PUBLIC_HEXCLAVE_URL", "https://hexclave-url.example.test");
|
|
29
|
+
vi.stubEnv("NEXT_PUBLIC_STACK_URL", "https://stack-url.example.test");
|
|
30
|
+
expect(() => getEnvVariable("NEXT_PUBLIC_STACK_API_URL")).toThrow(/NEXT_PUBLIC_HEXCLAVE_URL.*NEXT_PUBLIC_STACK_URL.*different values/);
|
|
31
|
+
});
|
|
32
|
+
it("returns undefined when both names are empty", () => {
|
|
33
|
+
expect(resolveHexclaveStackEnvVarValue("HEXCLAVE_FOO", "STACK_FOO", "", "")).toBeUndefined();
|
|
34
|
+
});
|
|
35
|
+
it("falls back to the legacy Stack name when a canonical Hexclave name is looked up", () => {
|
|
36
|
+
vi.stubEnv("NEXT_PUBLIC_STACK_API_URL", "https://stack.example.test");
|
|
37
|
+
expect(getEnvVariable("NEXT_PUBLIC_HEXCLAVE_API_URL")).toBe("https://stack.example.test");
|
|
38
|
+
expect(getProcessEnv("NEXT_PUBLIC_HEXCLAVE_API_URL")).toBe("https://stack.example.test");
|
|
39
|
+
});
|
|
40
|
+
it("throws on a conflict when a canonical Hexclave name is looked up", () => {
|
|
41
|
+
vi.stubEnv("NEXT_PUBLIC_HEXCLAVE_API_URL", "https://hexclave.example.test");
|
|
42
|
+
vi.stubEnv("NEXT_PUBLIC_STACK_API_URL", "https://stack.example.test");
|
|
43
|
+
expect(() => getEnvVariable("NEXT_PUBLIC_HEXCLAVE_API_URL")).toThrow(/NEXT_PUBLIC_HEXCLAVE_API_URL.*NEXT_PUBLIC_STACK_API_URL.*different values/);
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
//#endregion
|
|
48
|
+
export { };
|
|
49
|
+
//# sourceMappingURL=env.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env.test.js","names":[],"sources":["../../../src/utils/env.test.tsx"],"sourcesContent":["import { afterEach, describe, expect, it, vi } from \"vitest\";\nimport { getEnvVariable, getProcessEnv, resolveHexclaveStackEnvVarValue } from \"./env\";\n\nafterEach(() => {\n vi.unstubAllEnvs();\n});\n\ndescribe(\"Hexclave/Stack env var dual-read\", () => {\n it(\"falls back to the legacy Stack name when the Hexclave value is empty\", () => {\n vi.stubEnv(\"NEXT_PUBLIC_HEXCLAVE_API_URL\", \"\");\n vi.stubEnv(\"NEXT_PUBLIC_STACK_API_URL\", \"https://stack.example.test\");\n\n expect(getEnvVariable(\"NEXT_PUBLIC_STACK_API_URL\")).toBe(\"https://stack.example.test\");\n expect(getProcessEnv(\"NEXT_PUBLIC_STACK_API_URL\")).toBe(\"https://stack.example.test\");\n });\n\n it(\"allows both names when they have the same non-empty value\", () => {\n vi.stubEnv(\"NEXT_PUBLIC_HEXCLAVE_API_URL\", \"https://api.example.test\");\n vi.stubEnv(\"NEXT_PUBLIC_STACK_API_URL\", \"https://api.example.test\");\n\n expect(getEnvVariable(\"NEXT_PUBLIC_STACK_API_URL\")).toBe(\"https://api.example.test\");\n expect(getProcessEnv(\"NEXT_PUBLIC_STACK_API_URL\")).toBe(\"https://api.example.test\");\n });\n\n it(\"throws when both names are non-empty and different\", () => {\n vi.stubEnv(\"NEXT_PUBLIC_HEXCLAVE_API_URL\", \"https://hexclave.example.test\");\n vi.stubEnv(\"NEXT_PUBLIC_STACK_API_URL\", \"https://stack.example.test\");\n\n expect(() => getEnvVariable(\"NEXT_PUBLIC_STACK_API_URL\")).toThrow(/NEXT_PUBLIC_HEXCLAVE_API_URL.*NEXT_PUBLIC_STACK_API_URL.*different values/);\n expect(() => getProcessEnv(\"NEXT_PUBLIC_STACK_API_URL\")).toThrow(/NEXT_PUBLIC_HEXCLAVE_API_URL.*NEXT_PUBLIC_STACK_API_URL.*different values/);\n });\n\n it(\"checks renamed legacy aliases when falling back\", () => {\n vi.stubEnv(\"NEXT_PUBLIC_HEXCLAVE_URL\", \"https://hexclave-url.example.test\");\n vi.stubEnv(\"NEXT_PUBLIC_STACK_URL\", \"https://stack-url.example.test\");\n\n expect(() => getEnvVariable(\"NEXT_PUBLIC_STACK_API_URL\")).toThrow(/NEXT_PUBLIC_HEXCLAVE_URL.*NEXT_PUBLIC_STACK_URL.*different values/);\n });\n\n it(\"returns undefined when both names are empty\", () => {\n expect(resolveHexclaveStackEnvVarValue(\"HEXCLAVE_FOO\", \"STACK_FOO\", \"\", \"\")).toBeUndefined();\n });\n\n it(\"falls back to the legacy Stack name when a canonical Hexclave name is looked up\", () => {\n vi.stubEnv(\"NEXT_PUBLIC_STACK_API_URL\", \"https://stack.example.test\");\n\n // Caller passes the canonical HEXCLAVE_ name but only the legacy value is set.\n expect(getEnvVariable(\"NEXT_PUBLIC_HEXCLAVE_API_URL\")).toBe(\"https://stack.example.test\");\n expect(getProcessEnv(\"NEXT_PUBLIC_HEXCLAVE_API_URL\")).toBe(\"https://stack.example.test\");\n });\n\n it(\"throws on a conflict when a canonical Hexclave name is looked up\", () => {\n vi.stubEnv(\"NEXT_PUBLIC_HEXCLAVE_API_URL\", \"https://hexclave.example.test\");\n vi.stubEnv(\"NEXT_PUBLIC_STACK_API_URL\", \"https://stack.example.test\");\n\n expect(() => getEnvVariable(\"NEXT_PUBLIC_HEXCLAVE_API_URL\")).toThrow(/NEXT_PUBLIC_HEXCLAVE_API_URL.*NEXT_PUBLIC_STACK_API_URL.*different values/);\n });\n});\n"],"mappings":";;;;AAGA,gBAAgB;AACd,IAAG,eAAe;EAClB;AAEF,SAAS,0CAA0C;AACjD,IAAG,8EAA8E;AAC/E,KAAG,QAAQ,gCAAgC,GAAG;AAC9C,KAAG,QAAQ,6BAA6B,6BAA6B;AAErE,SAAO,eAAe,4BAA4B,CAAC,CAAC,KAAK,6BAA6B;AACtF,SAAO,cAAc,4BAA4B,CAAC,CAAC,KAAK,6BAA6B;GACrF;AAEF,IAAG,mEAAmE;AACpE,KAAG,QAAQ,gCAAgC,2BAA2B;AACtE,KAAG,QAAQ,6BAA6B,2BAA2B;AAEnE,SAAO,eAAe,4BAA4B,CAAC,CAAC,KAAK,2BAA2B;AACpF,SAAO,cAAc,4BAA4B,CAAC,CAAC,KAAK,2BAA2B;GACnF;AAEF,IAAG,4DAA4D;AAC7D,KAAG,QAAQ,gCAAgC,gCAAgC;AAC3E,KAAG,QAAQ,6BAA6B,6BAA6B;AAErE,eAAa,eAAe,4BAA4B,CAAC,CAAC,QAAQ,4EAA4E;AAC9I,eAAa,cAAc,4BAA4B,CAAC,CAAC,QAAQ,4EAA4E;GAC7I;AAEF,IAAG,yDAAyD;AAC1D,KAAG,QAAQ,4BAA4B,oCAAoC;AAC3E,KAAG,QAAQ,yBAAyB,iCAAiC;AAErE,eAAa,eAAe,4BAA4B,CAAC,CAAC,QAAQ,oEAAoE;GACtI;AAEF,IAAG,qDAAqD;AACtD,SAAO,gCAAgC,gBAAgB,aAAa,IAAI,GAAG,CAAC,CAAC,eAAe;GAC5F;AAEF,IAAG,yFAAyF;AAC1F,KAAG,QAAQ,6BAA6B,6BAA6B;AAGrE,SAAO,eAAe,+BAA+B,CAAC,CAAC,KAAK,6BAA6B;AACzF,SAAO,cAAc,+BAA+B,CAAC,CAAC,KAAK,6BAA6B;GACxF;AAEF,IAAG,0EAA0E;AAC3E,KAAG,QAAQ,gCAAgC,gCAAgC;AAC3E,KAAG,QAAQ,6BAA6B,6BAA6B;AAErE,eAAa,eAAe,+BAA+B,CAAC,CAAC,QAAQ,4EAA4E;GACjJ;EACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","names":[],"sources":["../../../src/utils/errors.tsx"],"mappings":";;;iBAMgB,QAAA,CAAS,YAAA,UAAsB,SAAA;AAAA,iBAC/B,QAAA,CAAS,KAAA,EAAO,KAAA;AAAA,iBAChB,QAAA,CAAA,GAAY,IAAA,EAAM,gCAAA;;;;;AADlC;;;;;AACA;;;;;AA0CA;;;;;;;;;iBAAgB,iBAAA,CAAkB,KAAA,EAAO,KAAA,KAAU,MAAA,EAAQ,KAAA;AAAA,cAkB9C,sBAAA,SAA+B,KAAA;EAAA,SACG,SAAA,IAAY,MAAA,gBAAsB,YAAA;cAAnE,OAAA,UAAiC,SAAA,IAAY,MAAA,gBAAsB,YAAA;AAAA;AAAA,
|
|
1
|
+
{"version":3,"file":"errors.d.ts","names":[],"sources":["../../../src/utils/errors.tsx"],"mappings":";;;iBAMgB,QAAA,CAAS,YAAA,UAAsB,SAAA;AAAA,iBAC/B,QAAA,CAAS,KAAA,EAAO,KAAA;AAAA,iBAChB,QAAA,CAAA,GAAY,IAAA,EAAM,gCAAA;;;;;AADlC;;;;;AACA;;;;;AA0CA;;;;;;;;;iBAAgB,iBAAA,CAAkB,KAAA,EAAO,KAAA,KAAU,MAAA,EAAQ,KAAA;AAAA,cAkB9C,sBAAA,SAA+B,KAAA;EAAA,SACG,SAAA,IAAY,MAAA,gBAAsB,YAAA;cAAnE,OAAA,UAAiC,SAAA,IAAY,MAAA,gBAAsB,YAAA;AAAA;AAAA,iBA0BjE,iBAAA,CAAkB,KAAA;AAAA,KAMtB,YAAA;AAAA,KAEP,SAAA,IAAa,QAAA,UAAkB,KAAA,WAAgB,KAAA,EAAO,YAAA,KAAiB,SAAA;AAAA,iBAG5D,iBAAA,CAAkB,IAAA,EAAM,SAAA;;;;;;;;;;iBA4CxB,YAAA,CAAa,QAAA,UAAkB,KAAA;;;;AAvD/C;iBA+DgB,cAAA,CAAe,QAAA,UAAkB,KAAA;AAAA,KAK5C,MAAA;EACH,UAAA;EACA,OAAA;AAAA;AAAA,KAGG,gCAAA,IAEH,MAAA,EAAQ,MAAA,EACR,OAAA,cAGA,UAAA,WAAqB,MAAA,EACrB,OAAA;AAAA,cAGW,WAAA,SAAoB,KAAA;EAAA,iBACd,uBAAA;EACV,IAAA;EAAA,SACS,UAAA;EAAA,OAEF,UAAA;;;;SACA,YAAA;;;;SACA,eAAA;;;;SACA,SAAA;;;;SACA,QAAA;;;;SACA,gBAAA;;;;SACA,aAAA;;;;SACA,2BAAA;;;;SACA,cAAA;;;;SACA,QAAA;;;;SACA,IAAA;;;;SACA,cAAA;;;;SACA,kBAAA;;;;SACA,eAAA;;;;SACA,UAAA;;;;SACA,oBAAA;;;;SACA,mBAAA;;;;SACA,iBAAA;;;;SACA,SAAA;;;;SACA,kBAAA;;;;SACA,mBAAA;;;;SACA,MAAA;;;;SACA,gBAAA;;;;SACA,QAAA;;;;SACA,eAAA;;;;SACA,oBAAA;;;;SACA,eAAA;;;;SACA,2BAAA;;;;SACA,0BAAA;;;;SAEA,mBAAA;;;;SACA,cAAA;;;;SACA,UAAA;;;;SACA,kBAAA;;;;SACA,cAAA;;;;SACA,uBAAA;;;;SACA,qBAAA;;;;SACA,mBAAA;;;;SACA,YAAA;;;;SACA,WAAA;;;;SACA,6BAAA;;;;iBAGC,IAAA,EAAM,gCAAA;EAAA,OAgBP,aAAA,CAAc,KAAA,YAAiB,KAAA,IAAS,WAAA;EAK/C,aAAA,CAAA;EAIA,aAAA,CAAA;EAIA,aAAA,CAAA;EAIA,OAAA,CAAA,GAAW,UAAA;EAIX,UAAA,CAAA,GAAc,MAAA;EAMd,iBAAA,CAAA,GAAqB,IAAA;;;;EAWrB,UAAA,CAAA,GAAc,IAAA;AAAA"}
|
package/dist/esm/utils/errors.js
CHANGED
|
@@ -54,7 +54,10 @@ var HexclaveAssertionError = class extends Error {
|
|
|
54
54
|
},
|
|
55
55
|
enumerable: false
|
|
56
56
|
});
|
|
57
|
-
|
|
57
|
+
const hexclaveDebuggerValue = typeof process !== "undefined" ? process.env.NEXT_PUBLIC_HEXCLAVE_DEBUGGER_ON_ASSERTION_ERROR : void 0;
|
|
58
|
+
const stackDebuggerValue = typeof process !== "undefined" ? process.env.NEXT_PUBLIC_STACK_DEBUGGER_ON_ASSERTION_ERROR : void 0;
|
|
59
|
+
if (hexclaveDebuggerValue && stackDebuggerValue && hexclaveDebuggerValue !== stackDebuggerValue) throw new Error("Environment variables NEXT_PUBLIC_HEXCLAVE_DEBUGGER_ON_ASSERTION_ERROR and NEXT_PUBLIC_STACK_DEBUGGER_ON_ASSERTION_ERROR are both set to different values. Remove one of them or set them to the same value.");
|
|
60
|
+
if ((hexclaveDebuggerValue || stackDebuggerValue) === "true") debugger;
|
|
58
61
|
}
|
|
59
62
|
};
|
|
60
63
|
HexclaveAssertionError.prototype.name = "HexclaveAssertionError";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","names":[],"sources":["../../../src/utils/errors.tsx"],"sourcesContent":["import { globalVar } from \"./globals\";\nimport { Json } from \"./json\";\nimport { pick } from \"./objects\";\nimport { nicify } from \"./strings\";\n\n\nexport function throwErr(errorMessage: string, extraData?: any): never;\nexport function throwErr(error: Error): never;\nexport function throwErr(...args: StatusErrorConstructorParameters): never;\nexport function throwErr(...args: any[]): never {\n if (typeof args[0] === \"string\") {\n throw new HexclaveAssertionError(args[0], args[1]);\n } else if (args[0] instanceof Error) {\n throw args[0];\n } else {\n // @ts-expect-error\n throw new StatusError(...args);\n }\n}\n\nfunction removeStacktraceNameLine(stack: string): string {\n // some browsers (eg. Chrome) prepend the stack with an extra line with the error name\n const addsNameLine = new Error().stack?.startsWith(\"Error\\n\");\n return stack.split(\"\\n\").slice(addsNameLine ? 1 : 0).join(\"\\n\");\n}\n\n\n/**\n * Concatenates the (original) stacktraces of the given errors onto the first.\n *\n * Note: Very often, the concatStacktracesIfRejected function in promises.tsx is an easier way to use this function.\n *\n * Useful when you invoke an async function to receive a promise without awaiting it immediately. Browsers are smart\n * enough to keep track of the call stack in async function calls when you invoke `.then` within the same async tick,\n * but if you don't, the stacktrace will be lost.\n *\n * Here's an example of the unwanted behavior:\n *\n * ```tsx\n * async function log() {\n * await wait(0); // put the task on the event loop\n * console.log(new Error().stack);\n * }\n *\n * async function main() {\n * await log(); // good; prints both \"log\" and \"main\" on the stacktrace\n * log(); // bad; prints only \"log\" on the stacktrace\n * }\n * ```\n */\nexport function concatStacktraces(first: Error, ...errors: Error[]): void {\n // some browsers (eg. Firefox) add an extra empty line at the end\n const addsEmptyLineAtEnd = first.stack?.endsWith(\"\\n\");\n\n\n // Add a reference to this function itself so that we know that stacktraces were concatenated\n // If you are coming here from a stacktrace, please know that the two parts before and after this line are different\n // stacktraces that were concatenated with concatStacktraces\n const separator = removeStacktraceNameLine(new Error().stack ?? \"\").split(\"\\n\")[0];\n\n\n for (const error of errors) {\n const toAppend = removeStacktraceNameLine(error.stack ?? \"\");\n first.stack += (addsEmptyLineAtEnd ? \"\" : \"\\n\") + separator + \"\\n\" + toAppend;\n }\n}\n\n\nexport class HexclaveAssertionError extends Error {\n constructor(message: string, public readonly extraData?: Record<string, any> & ErrorOptions) {\n const disclaimer = `\\n\\nThis is likely an error in Hexclave. Please make sure you are running the newest version and report it.`;\n super(`${message}${message.endsWith(disclaimer) ? \"\" : disclaimer}`, pick(extraData ?? {}, [\"cause\"]));\n\n Object.defineProperty(this, \"customCaptureExtraArgs\", {\n get() {\n return [this.extraData];\n },\n enumerable: false,\n });\n\n // Use literal dot-form (guarded with `typeof process`) so Next.js / webpack\n // DefinePlugin can inline the value at build time. See getProcessEnv in ./env.\n if ((typeof process !== \"undefined\" ? process.env.NEXT_PUBLIC_STACK_DEBUGGER_ON_ASSERTION_ERROR : undefined) === \"true\") {\n debugger;\n }\n }\n}\nHexclaveAssertionError.prototype.name = \"HexclaveAssertionError\";\n\n\nexport function errorToNiceString(error: unknown): string {\n if (!(error instanceof Error)) return `${typeof error}<${nicify(error)}>`;\n return nicify(error, { maxDepth: 8 });\n}\n\n\nexport type CaptureLevel = \"error\" | \"warning\";\n\ntype ErrorSink = (location: string, error: unknown, level: CaptureLevel, ...extraArgs: unknown[]) => void;\n\nconst errorSinks = new Set<ErrorSink>();\nexport function registerErrorSink(sink: ErrorSink): void {\n if (errorSinks.has(sink)) {\n return;\n }\n errorSinks.add(sink);\n}\nregisterErrorSink((location, error, level, ...extraArgs) => {\n const logger = level === \"warning\" ? console.warn : console.error;\n const colorCode = level === \"warning\" ? \"\\x1b[43m\" : \"\\x1b[41m\";\n const label = level === \"warning\" ? \"warning\" : \"error\";\n logger(\n `${colorCode}Captured ${label} in ${location}:`,\n // HACK: Log a nicified version of the error to get around buggy Next.js pretty-printing\n // https://www.reddit.com/r/nextjs/comments/1gkxdqe/comment/m19kxgn/?utm_source=share&utm_medium=web3x&utm_name=web3xcss&utm_term=1&utm_content=share_button\n errorToNiceString(error),\n ...extraArgs,\n \"\\x1b[0m\",\n );\n});\nregisterErrorSink((location, error, level, ...extraArgs) => {\n globalVar.hexclaveCapturedErrors = globalVar.hexclaveCapturedErrors ?? [];\n globalVar.hexclaveCapturedErrors.push({ location, error, level, extraArgs });\n});\n\nfunction dispatchToSinks(location: string, error: unknown, level: CaptureLevel): void {\n for (const sink of errorSinks) {\n sink(\n location,\n error,\n level,\n ...error && (typeof error === 'object' || typeof error === 'function') && \"customCaptureExtraArgs\" in error && Array.isArray(error.customCaptureExtraArgs) ? (error.customCaptureExtraArgs as any[]) : [],\n );\n }\n}\n\n/**\n * Captures an error and sends it to the error sinks (most notably, Sentry). Errors caught with captureError are\n * supposed to be seen by an engineer, so they should be actionable and important.\n *\n * The location string is a machine-readable ID, and should hence not contain spaces or anything like that. Good\n * examples are: \"api-route-handler\", \"renderPart()\", etc.\n *\n * Errors that bubble up to the top of runAsynchronously or a route handler are already captured with captureError.\n */\nexport function captureError(location: string, error: unknown): void {\n dispatchToSinks(location, error, \"error\");\n}\n\n/**\n * Like captureError, but logs at warning level. Use for issues that an engineer should know about but that aren't\n * severe enough to be treated as an error (e.g. recoverable failures in background tasks).\n */\nexport function captureWarning(location: string, error: unknown): void {\n dispatchToSinks(location, error, \"warning\");\n}\n\n\ntype Status = {\n statusCode: number,\n message: string,\n};\n\ntype StatusErrorConstructorParameters =\n| [\n status: Status,\n message?: string\n]\n| [\n statusCode: number | Status,\n message: string,\n];\n\nexport class StatusError extends Error {\n private readonly __stackStatusErrorBrand = \"stack-status-error-brand-sentinel\" as const;\n public name = \"StatusError\";\n public readonly statusCode: number;\n\n public static BadRequest = { statusCode: 400, message: \"Bad Request\" };\n public static Unauthorized = { statusCode: 401, message: \"Unauthorized\" };\n public static PaymentRequired = { statusCode: 402, message: \"Payment Required\" };\n public static Forbidden = { statusCode: 403, message: \"Forbidden\" };\n public static NotFound = { statusCode: 404, message: \"Not Found\" };\n public static MethodNotAllowed = { statusCode: 405, message: \"Method Not Allowed\" };\n public static NotAcceptable = { statusCode: 406, message: \"Not Acceptable\" };\n public static ProxyAuthenticationRequired = { statusCode: 407, message: \"Proxy Authentication Required\" };\n public static RequestTimeout = { statusCode: 408, message: \"Request Timeout\" };\n public static Conflict = { statusCode: 409, message: \"Conflict\" };\n public static Gone = { statusCode: 410, message: \"Gone\" };\n public static LengthRequired = { statusCode: 411, message: \"Length Required\" };\n public static PreconditionFailed = { statusCode: 412, message: \"Precondition Failed\" };\n public static PayloadTooLarge = { statusCode: 413, message: \"Payload Too Large\" };\n public static URITooLong = { statusCode: 414, message: \"URI Too Long\" };\n public static UnsupportedMediaType = { statusCode: 415, message: \"Unsupported Media Type\" };\n public static RangeNotSatisfiable = { statusCode: 416, message: \"Range Not Satisfiable\" };\n public static ExpectationFailed = { statusCode: 417, message: \"Expectation Failed\" };\n public static ImATeapot = { statusCode: 418, message: \"I'm a teapot\" };\n public static MisdirectedRequest = { statusCode: 421, message: \"Misdirected Request\" };\n public static UnprocessableEntity = { statusCode: 422, message: \"Unprocessable Entity\" };\n public static Locked = { statusCode: 423, message: \"Locked\" };\n public static FailedDependency = { statusCode: 424, message: \"Failed Dependency\" };\n public static TooEarly = { statusCode: 425, message: \"Too Early\" };\n public static UpgradeRequired = { statusCode: 426, message: \"Upgrade Required\" };\n public static PreconditionRequired = { statusCode: 428, message: \"Precondition Required\" };\n public static TooManyRequests = { statusCode: 429, message: \"Too Many Requests\" };\n public static RequestHeaderFieldsTooLarge = { statusCode: 431, message: \"Request Header Fields Too Large\" };\n public static UnavailableForLegalReasons = { statusCode: 451, message: \"Unavailable For Legal Reasons\" };\n\n public static InternalServerError = { statusCode: 500, message: \"Internal Server Error\" };\n public static NotImplemented = { statusCode: 501, message: \"Not Implemented\" };\n public static BadGateway = { statusCode: 502, message: \"Bad Gateway\" };\n public static ServiceUnavailable = { statusCode: 503, message: \"Service Unavailable\" };\n public static GatewayTimeout = { statusCode: 504, message: \"Gateway Timeout\" };\n public static HTTPVersionNotSupported = { statusCode: 505, message: \"HTTP Version Not Supported\" };\n public static VariantAlsoNegotiates = { statusCode: 506, message: \"Variant Also Negotiates\" };\n public static InsufficientStorage = { statusCode: 507, message: \"Insufficient Storage\" };\n public static LoopDetected = { statusCode: 508, message: \"Loop Detected\" };\n public static NotExtended = { statusCode: 510, message: \"Not Extended\" };\n public static NetworkAuthenticationRequired = { statusCode: 511, message: \"Network Authentication Required\" };\n\n\n constructor(...args: StatusErrorConstructorParameters);\n constructor(\n status: number | Status,\n message?: string,\n ) {\n if (typeof status === \"object\") {\n message ??= status.message;\n status = status.statusCode;\n }\n super(message);\n this.statusCode = status;\n if (!message) {\n throw new HexclaveAssertionError(\"StatusError always requires a message unless a Status object is passed\", { cause: this });\n }\n }\n\n public static isStatusError(error: unknown): error is StatusError {\n // like instanceof, but also works for errors thrown in other realms or by different versions of the same package\n return typeof error === \"object\" && error !== null && \"__stackStatusErrorBrand\" in error && error.__stackStatusErrorBrand === \"stack-status-error-brand-sentinel\";\n }\n\n public isClientError() {\n return this.statusCode >= 400 && this.statusCode < 500;\n }\n\n public isServerError() {\n return !this.isClientError();\n }\n\n public getStatusCode(): number {\n return this.statusCode;\n }\n\n public getBody(): Uint8Array {\n return new TextEncoder().encode(this.message);\n }\n\n public getHeaders(): Record<string, string[]> {\n return {\n \"Content-Type\": [\"text/plain; charset=utf-8\"],\n };\n }\n\n public toDescriptiveJson(): Json {\n return {\n status_code: this.getStatusCode(),\n message: this.message,\n headers: this.getHeaders(),\n };\n }\n\n /**\n * @deprecated this is not a good way to make status errors human-readable, use toDescriptiveJson instead\n */\n public toHttpJson(): Json {\n return {\n status_code: this.statusCode,\n body: this.message,\n headers: this.getHeaders(),\n };\n }\n}\nStatusError.prototype.name = \"StatusError\";\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"errors.js","names":[],"sources":["../../../src/utils/errors.tsx"],"sourcesContent":["import { globalVar } from \"./globals\";\nimport { Json } from \"./json\";\nimport { pick } from \"./objects\";\nimport { nicify } from \"./strings\";\n\n\nexport function throwErr(errorMessage: string, extraData?: any): never;\nexport function throwErr(error: Error): never;\nexport function throwErr(...args: StatusErrorConstructorParameters): never;\nexport function throwErr(...args: any[]): never {\n if (typeof args[0] === \"string\") {\n throw new HexclaveAssertionError(args[0], args[1]);\n } else if (args[0] instanceof Error) {\n throw args[0];\n } else {\n // @ts-expect-error\n throw new StatusError(...args);\n }\n}\n\nfunction removeStacktraceNameLine(stack: string): string {\n // some browsers (eg. Chrome) prepend the stack with an extra line with the error name\n const addsNameLine = new Error().stack?.startsWith(\"Error\\n\");\n return stack.split(\"\\n\").slice(addsNameLine ? 1 : 0).join(\"\\n\");\n}\n\n\n/**\n * Concatenates the (original) stacktraces of the given errors onto the first.\n *\n * Note: Very often, the concatStacktracesIfRejected function in promises.tsx is an easier way to use this function.\n *\n * Useful when you invoke an async function to receive a promise without awaiting it immediately. Browsers are smart\n * enough to keep track of the call stack in async function calls when you invoke `.then` within the same async tick,\n * but if you don't, the stacktrace will be lost.\n *\n * Here's an example of the unwanted behavior:\n *\n * ```tsx\n * async function log() {\n * await wait(0); // put the task on the event loop\n * console.log(new Error().stack);\n * }\n *\n * async function main() {\n * await log(); // good; prints both \"log\" and \"main\" on the stacktrace\n * log(); // bad; prints only \"log\" on the stacktrace\n * }\n * ```\n */\nexport function concatStacktraces(first: Error, ...errors: Error[]): void {\n // some browsers (eg. Firefox) add an extra empty line at the end\n const addsEmptyLineAtEnd = first.stack?.endsWith(\"\\n\");\n\n\n // Add a reference to this function itself so that we know that stacktraces were concatenated\n // If you are coming here from a stacktrace, please know that the two parts before and after this line are different\n // stacktraces that were concatenated with concatStacktraces\n const separator = removeStacktraceNameLine(new Error().stack ?? \"\").split(\"\\n\")[0];\n\n\n for (const error of errors) {\n const toAppend = removeStacktraceNameLine(error.stack ?? \"\");\n first.stack += (addsEmptyLineAtEnd ? \"\" : \"\\n\") + separator + \"\\n\" + toAppend;\n }\n}\n\n\nexport class HexclaveAssertionError extends Error {\n constructor(message: string, public readonly extraData?: Record<string, any> & ErrorOptions) {\n const disclaimer = `\\n\\nThis is likely an error in Hexclave. Please make sure you are running the newest version and report it.`;\n super(`${message}${message.endsWith(disclaimer) ? \"\" : disclaimer}`, pick(extraData ?? {}, [\"cause\"]));\n\n Object.defineProperty(this, \"customCaptureExtraArgs\", {\n get() {\n return [this.extraData];\n },\n enumerable: false,\n });\n\n // Use literal dot-form (guarded with `typeof process`) so Next.js / webpack\n // DefinePlugin can inline the value at build time. See getProcessEnv in ./env.\n const hexclaveDebuggerValue = typeof process !== \"undefined\" ? process.env.NEXT_PUBLIC_HEXCLAVE_DEBUGGER_ON_ASSERTION_ERROR : undefined;\n const stackDebuggerValue = typeof process !== \"undefined\" ? process.env.NEXT_PUBLIC_STACK_DEBUGGER_ON_ASSERTION_ERROR : undefined;\n if (hexclaveDebuggerValue && stackDebuggerValue && hexclaveDebuggerValue !== stackDebuggerValue) {\n throw new Error(\"Environment variables NEXT_PUBLIC_HEXCLAVE_DEBUGGER_ON_ASSERTION_ERROR and NEXT_PUBLIC_STACK_DEBUGGER_ON_ASSERTION_ERROR are both set to different values. Remove one of them or set them to the same value.\");\n }\n if ((hexclaveDebuggerValue || stackDebuggerValue) === \"true\") {\n debugger;\n }\n }\n}\nHexclaveAssertionError.prototype.name = \"HexclaveAssertionError\";\n\n\nexport function errorToNiceString(error: unknown): string {\n if (!(error instanceof Error)) return `${typeof error}<${nicify(error)}>`;\n return nicify(error, { maxDepth: 8 });\n}\n\n\nexport type CaptureLevel = \"error\" | \"warning\";\n\ntype ErrorSink = (location: string, error: unknown, level: CaptureLevel, ...extraArgs: unknown[]) => void;\n\nconst errorSinks = new Set<ErrorSink>();\nexport function registerErrorSink(sink: ErrorSink): void {\n if (errorSinks.has(sink)) {\n return;\n }\n errorSinks.add(sink);\n}\nregisterErrorSink((location, error, level, ...extraArgs) => {\n const logger = level === \"warning\" ? console.warn : console.error;\n const colorCode = level === \"warning\" ? \"\\x1b[43m\" : \"\\x1b[41m\";\n const label = level === \"warning\" ? \"warning\" : \"error\";\n logger(\n `${colorCode}Captured ${label} in ${location}:`,\n // HACK: Log a nicified version of the error to get around buggy Next.js pretty-printing\n // https://www.reddit.com/r/nextjs/comments/1gkxdqe/comment/m19kxgn/?utm_source=share&utm_medium=web3x&utm_name=web3xcss&utm_term=1&utm_content=share_button\n errorToNiceString(error),\n ...extraArgs,\n \"\\x1b[0m\",\n );\n});\nregisterErrorSink((location, error, level, ...extraArgs) => {\n globalVar.hexclaveCapturedErrors = globalVar.hexclaveCapturedErrors ?? [];\n globalVar.hexclaveCapturedErrors.push({ location, error, level, extraArgs });\n});\n\nfunction dispatchToSinks(location: string, error: unknown, level: CaptureLevel): void {\n for (const sink of errorSinks) {\n sink(\n location,\n error,\n level,\n ...error && (typeof error === 'object' || typeof error === 'function') && \"customCaptureExtraArgs\" in error && Array.isArray(error.customCaptureExtraArgs) ? (error.customCaptureExtraArgs as any[]) : [],\n );\n }\n}\n\n/**\n * Captures an error and sends it to the error sinks (most notably, Sentry). Errors caught with captureError are\n * supposed to be seen by an engineer, so they should be actionable and important.\n *\n * The location string is a machine-readable ID, and should hence not contain spaces or anything like that. Good\n * examples are: \"api-route-handler\", \"renderPart()\", etc.\n *\n * Errors that bubble up to the top of runAsynchronously or a route handler are already captured with captureError.\n */\nexport function captureError(location: string, error: unknown): void {\n dispatchToSinks(location, error, \"error\");\n}\n\n/**\n * Like captureError, but logs at warning level. Use for issues that an engineer should know about but that aren't\n * severe enough to be treated as an error (e.g. recoverable failures in background tasks).\n */\nexport function captureWarning(location: string, error: unknown): void {\n dispatchToSinks(location, error, \"warning\");\n}\n\n\ntype Status = {\n statusCode: number,\n message: string,\n};\n\ntype StatusErrorConstructorParameters =\n| [\n status: Status,\n message?: string\n]\n| [\n statusCode: number | Status,\n message: string,\n];\n\nexport class StatusError extends Error {\n private readonly __stackStatusErrorBrand = \"stack-status-error-brand-sentinel\" as const;\n public name = \"StatusError\";\n public readonly statusCode: number;\n\n public static BadRequest = { statusCode: 400, message: \"Bad Request\" };\n public static Unauthorized = { statusCode: 401, message: \"Unauthorized\" };\n public static PaymentRequired = { statusCode: 402, message: \"Payment Required\" };\n public static Forbidden = { statusCode: 403, message: \"Forbidden\" };\n public static NotFound = { statusCode: 404, message: \"Not Found\" };\n public static MethodNotAllowed = { statusCode: 405, message: \"Method Not Allowed\" };\n public static NotAcceptable = { statusCode: 406, message: \"Not Acceptable\" };\n public static ProxyAuthenticationRequired = { statusCode: 407, message: \"Proxy Authentication Required\" };\n public static RequestTimeout = { statusCode: 408, message: \"Request Timeout\" };\n public static Conflict = { statusCode: 409, message: \"Conflict\" };\n public static Gone = { statusCode: 410, message: \"Gone\" };\n public static LengthRequired = { statusCode: 411, message: \"Length Required\" };\n public static PreconditionFailed = { statusCode: 412, message: \"Precondition Failed\" };\n public static PayloadTooLarge = { statusCode: 413, message: \"Payload Too Large\" };\n public static URITooLong = { statusCode: 414, message: \"URI Too Long\" };\n public static UnsupportedMediaType = { statusCode: 415, message: \"Unsupported Media Type\" };\n public static RangeNotSatisfiable = { statusCode: 416, message: \"Range Not Satisfiable\" };\n public static ExpectationFailed = { statusCode: 417, message: \"Expectation Failed\" };\n public static ImATeapot = { statusCode: 418, message: \"I'm a teapot\" };\n public static MisdirectedRequest = { statusCode: 421, message: \"Misdirected Request\" };\n public static UnprocessableEntity = { statusCode: 422, message: \"Unprocessable Entity\" };\n public static Locked = { statusCode: 423, message: \"Locked\" };\n public static FailedDependency = { statusCode: 424, message: \"Failed Dependency\" };\n public static TooEarly = { statusCode: 425, message: \"Too Early\" };\n public static UpgradeRequired = { statusCode: 426, message: \"Upgrade Required\" };\n public static PreconditionRequired = { statusCode: 428, message: \"Precondition Required\" };\n public static TooManyRequests = { statusCode: 429, message: \"Too Many Requests\" };\n public static RequestHeaderFieldsTooLarge = { statusCode: 431, message: \"Request Header Fields Too Large\" };\n public static UnavailableForLegalReasons = { statusCode: 451, message: \"Unavailable For Legal Reasons\" };\n\n public static InternalServerError = { statusCode: 500, message: \"Internal Server Error\" };\n public static NotImplemented = { statusCode: 501, message: \"Not Implemented\" };\n public static BadGateway = { statusCode: 502, message: \"Bad Gateway\" };\n public static ServiceUnavailable = { statusCode: 503, message: \"Service Unavailable\" };\n public static GatewayTimeout = { statusCode: 504, message: \"Gateway Timeout\" };\n public static HTTPVersionNotSupported = { statusCode: 505, message: \"HTTP Version Not Supported\" };\n public static VariantAlsoNegotiates = { statusCode: 506, message: \"Variant Also Negotiates\" };\n public static InsufficientStorage = { statusCode: 507, message: \"Insufficient Storage\" };\n public static LoopDetected = { statusCode: 508, message: \"Loop Detected\" };\n public static NotExtended = { statusCode: 510, message: \"Not Extended\" };\n public static NetworkAuthenticationRequired = { statusCode: 511, message: \"Network Authentication Required\" };\n\n\n constructor(...args: StatusErrorConstructorParameters);\n constructor(\n status: number | Status,\n message?: string,\n ) {\n if (typeof status === \"object\") {\n message ??= status.message;\n status = status.statusCode;\n }\n super(message);\n this.statusCode = status;\n if (!message) {\n throw new HexclaveAssertionError(\"StatusError always requires a message unless a Status object is passed\", { cause: this });\n }\n }\n\n public static isStatusError(error: unknown): error is StatusError {\n // like instanceof, but also works for errors thrown in other realms or by different versions of the same package\n return typeof error === \"object\" && error !== null && \"__stackStatusErrorBrand\" in error && error.__stackStatusErrorBrand === \"stack-status-error-brand-sentinel\";\n }\n\n public isClientError() {\n return this.statusCode >= 400 && this.statusCode < 500;\n }\n\n public isServerError() {\n return !this.isClientError();\n }\n\n public getStatusCode(): number {\n return this.statusCode;\n }\n\n public getBody(): Uint8Array {\n return new TextEncoder().encode(this.message);\n }\n\n public getHeaders(): Record<string, string[]> {\n return {\n \"Content-Type\": [\"text/plain; charset=utf-8\"],\n };\n }\n\n public toDescriptiveJson(): Json {\n return {\n status_code: this.getStatusCode(),\n message: this.message,\n headers: this.getHeaders(),\n };\n }\n\n /**\n * @deprecated this is not a good way to make status errors human-readable, use toDescriptiveJson instead\n */\n public toHttpJson(): Json {\n return {\n status_code: this.statusCode,\n body: this.message,\n headers: this.getHeaders(),\n };\n }\n}\nStatusError.prototype.name = \"StatusError\";\n"],"mappings":"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"}
|
|
@@ -150,15 +150,15 @@ declare const MetricsEmailOverviewSchema: yup.ObjectSchema<{
|
|
|
150
150
|
activity: number;
|
|
151
151
|
}[];
|
|
152
152
|
daily_emails_by_status: {
|
|
153
|
-
error: number;
|
|
154
153
|
date: string;
|
|
154
|
+
error: number;
|
|
155
155
|
ok: number;
|
|
156
156
|
in_progress: number;
|
|
157
157
|
}[];
|
|
158
158
|
emails_sent: number;
|
|
159
159
|
recent_emails: {
|
|
160
|
-
status: string;
|
|
161
160
|
id: string;
|
|
161
|
+
status: string;
|
|
162
162
|
created_at_millis: number;
|
|
163
163
|
subject: string;
|
|
164
164
|
}[];
|
|
@@ -403,17 +403,17 @@ declare const AnalyticsClickmapResponseBodySchema: yup.ObjectSchema<{
|
|
|
403
403
|
replays: number;
|
|
404
404
|
}[];
|
|
405
405
|
users: {
|
|
406
|
-
primary_email: string | null;
|
|
407
406
|
display_name: string | null;
|
|
408
407
|
id: string;
|
|
408
|
+
primary_email: string | null;
|
|
409
409
|
profile_image_url: string | null;
|
|
410
410
|
clicks: number;
|
|
411
411
|
replays: number;
|
|
412
412
|
last_event_at_millis: number;
|
|
413
413
|
}[];
|
|
414
414
|
replays: {
|
|
415
|
-
user_id: string | null;
|
|
416
415
|
id: string;
|
|
416
|
+
user_id: string | null;
|
|
417
417
|
clicks: number;
|
|
418
418
|
last_event_at_millis: number;
|
|
419
419
|
route_path: string | null;
|
|
@@ -443,9 +443,9 @@ declare const AnalyticsClickmapResponseBodySchema: yup.ObjectSchema<{
|
|
|
443
443
|
elements: never[];
|
|
444
444
|
}, "">;
|
|
445
445
|
declare const MetricsActiveUsersByCountrySchema: yup.MixedSchema<Record<string, {
|
|
446
|
-
primary_email: string | null;
|
|
447
446
|
display_name: string | null;
|
|
448
447
|
id: string;
|
|
448
|
+
primary_email: string | null;
|
|
449
449
|
profile_image_url: string | null;
|
|
450
450
|
signed_up_at_millis: number;
|
|
451
451
|
last_active_at_millis: number | null;
|
|
@@ -471,25 +471,25 @@ declare const MetricsResponseBodySchema: yup.ObjectSchema<{
|
|
|
471
471
|
}[];
|
|
472
472
|
users_by_country: Record<string, number>;
|
|
473
473
|
active_users_by_country: Record<string, {
|
|
474
|
-
primary_email: string | null;
|
|
475
474
|
display_name: string | null;
|
|
476
475
|
id: string;
|
|
476
|
+
primary_email: string | null;
|
|
477
477
|
profile_image_url: string | null;
|
|
478
478
|
signed_up_at_millis: number;
|
|
479
479
|
last_active_at_millis: number | null;
|
|
480
480
|
}[]>;
|
|
481
481
|
recently_registered: {
|
|
482
|
-
primary_email: string | null;
|
|
483
482
|
display_name: string | null;
|
|
484
483
|
id: string;
|
|
484
|
+
primary_email: string | null;
|
|
485
485
|
profile_image_url: string | null;
|
|
486
486
|
signed_up_at_millis: number;
|
|
487
487
|
last_active_at_millis: number | null;
|
|
488
488
|
}[];
|
|
489
489
|
recently_active: {
|
|
490
|
-
primary_email: string | null;
|
|
491
490
|
display_name: string | null;
|
|
492
491
|
id: string;
|
|
492
|
+
primary_email: string | null;
|
|
493
493
|
profile_image_url: string | null;
|
|
494
494
|
signed_up_at_millis: number;
|
|
495
495
|
last_active_at_millis: number | null;
|
|
@@ -563,15 +563,15 @@ declare const MetricsResponseBodySchema: yup.ObjectSchema<{
|
|
|
563
563
|
emails_by_status: Record<string, number>;
|
|
564
564
|
total_emails: number;
|
|
565
565
|
daily_emails_by_status: {
|
|
566
|
-
error: number;
|
|
567
566
|
date: string;
|
|
567
|
+
error: number;
|
|
568
568
|
ok: number;
|
|
569
569
|
in_progress: number;
|
|
570
570
|
}[];
|
|
571
571
|
emails_sent: number;
|
|
572
572
|
recent_emails: {
|
|
573
|
-
status: string;
|
|
574
573
|
id: string;
|
|
574
|
+
status: string;
|
|
575
575
|
created_at_millis: number;
|
|
576
576
|
subject: string;
|
|
577
577
|
}[];
|
|
@@ -49,7 +49,7 @@ declare const conversationSummarySchema: yup$1.ObjectSchema<{
|
|
|
49
49
|
userPrimaryEmail: string | null;
|
|
50
50
|
userProfileImageUrl: string | null;
|
|
51
51
|
subject: string;
|
|
52
|
-
status: "
|
|
52
|
+
status: "pending" | "open" | "closed";
|
|
53
53
|
priority: "low" | "normal" | "high" | "urgent";
|
|
54
54
|
source: "email" | "manual" | "chat" | "api";
|
|
55
55
|
lastMessageType: "message" | "internal-note" | "status-change";
|
|
@@ -129,7 +129,7 @@ declare const conversationMessageSchema: yup$1.ObjectSchema<{
|
|
|
129
129
|
userId: string | null;
|
|
130
130
|
teamId: string | null;
|
|
131
131
|
subject: string;
|
|
132
|
-
status: "
|
|
132
|
+
status: "pending" | "open" | "closed";
|
|
133
133
|
priority: "low" | "normal" | "high" | "urgent";
|
|
134
134
|
source: "email" | "manual" | "chat" | "api";
|
|
135
135
|
messageType: "message" | "internal-note" | "status-change";
|
|
@@ -173,8 +173,6 @@ declare const conversationListResponseSchema: yup$1.ObjectSchema<{
|
|
|
173
173
|
lastOutboundAt?: string | null | undefined;
|
|
174
174
|
closedAt?: string | null | undefined;
|
|
175
175
|
recordMetadata?: {} | null | undefined;
|
|
176
|
-
status: "open" | "pending" | "closed";
|
|
177
|
-
priority: "low" | "normal" | "high" | "urgent";
|
|
178
176
|
source: "email" | "manual" | "chat" | "api";
|
|
179
177
|
metadata: {
|
|
180
178
|
tags: string[];
|
|
@@ -186,13 +184,15 @@ declare const conversationListResponseSchema: yup$1.ObjectSchema<{
|
|
|
186
184
|
lastCustomerReplyAt: string | null;
|
|
187
185
|
lastAgentReplyAt: string | null;
|
|
188
186
|
};
|
|
187
|
+
status: "pending" | "open" | "closed";
|
|
188
|
+
priority: "low" | "normal" | "high" | "urgent";
|
|
189
|
+
subject: string;
|
|
189
190
|
conversationId: string;
|
|
190
191
|
userId: string | null;
|
|
191
192
|
teamId: string | null;
|
|
192
193
|
userDisplayName: string | null;
|
|
193
194
|
userPrimaryEmail: string | null;
|
|
194
195
|
userProfileImageUrl: string | null;
|
|
195
|
-
subject: string;
|
|
196
196
|
lastMessageType: "message" | "internal-note" | "status-change";
|
|
197
197
|
preview: string | null;
|
|
198
198
|
lastActivityAt: string;
|
|
@@ -211,8 +211,6 @@ declare const conversationDetailResponseSchema: yup$1.ObjectSchema<{
|
|
|
211
211
|
lastOutboundAt?: string | null | undefined;
|
|
212
212
|
closedAt?: string | null | undefined;
|
|
213
213
|
recordMetadata?: {} | null | undefined;
|
|
214
|
-
status: "open" | "pending" | "closed";
|
|
215
|
-
priority: "low" | "normal" | "high" | "urgent";
|
|
216
214
|
source: "email" | "manual" | "chat" | "api";
|
|
217
215
|
metadata: {
|
|
218
216
|
tags: string[];
|
|
@@ -224,28 +222,30 @@ declare const conversationDetailResponseSchema: yup$1.ObjectSchema<{
|
|
|
224
222
|
lastCustomerReplyAt: string | null;
|
|
225
223
|
lastAgentReplyAt: string | null;
|
|
226
224
|
};
|
|
225
|
+
status: "pending" | "open" | "closed";
|
|
226
|
+
priority: "low" | "normal" | "high" | "urgent";
|
|
227
|
+
subject: string;
|
|
227
228
|
conversationId: string;
|
|
228
229
|
userId: string | null;
|
|
229
230
|
teamId: string | null;
|
|
230
231
|
userDisplayName: string | null;
|
|
231
232
|
userPrimaryEmail: string | null;
|
|
232
233
|
userProfileImageUrl: string | null;
|
|
233
|
-
subject: string;
|
|
234
234
|
lastMessageType: "message" | "internal-note" | "status-change";
|
|
235
235
|
preview: string | null;
|
|
236
236
|
lastActivityAt: string;
|
|
237
237
|
};
|
|
238
238
|
messages: {
|
|
239
|
-
status: "open" | "pending" | "closed";
|
|
240
239
|
id: string;
|
|
241
|
-
priority: "low" | "normal" | "high" | "urgent";
|
|
242
240
|
body: string | null;
|
|
243
241
|
source: "email" | "manual" | "chat" | "api";
|
|
244
242
|
metadata: {} | null;
|
|
243
|
+
status: "pending" | "open" | "closed";
|
|
244
|
+
priority: "low" | "normal" | "high" | "urgent";
|
|
245
|
+
subject: string;
|
|
245
246
|
conversationId: string;
|
|
246
247
|
userId: string | null;
|
|
247
248
|
teamId: string | null;
|
|
248
|
-
subject: string;
|
|
249
249
|
createdAt: string;
|
|
250
250
|
messageType: "message" | "internal-note" | "status-change";
|
|
251
251
|
attachments: {}[];
|