@hexclave/shared 1.0.53 → 1.0.55

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/dist/{admin-interface-D9wMduWc.d.ts → admin-interface-DIt0PvhC.d.ts} +4 -4
  2. package/dist/{admin-interface-D9wMduWc.d.ts.map → admin-interface-DIt0PvhC.d.ts.map} +1 -1
  3. package/dist/ai/unified-prompts/reminders.js +1 -1
  4. package/dist/ai/unified-prompts/reminders.js.map +1 -1
  5. package/dist/ai/unified-prompts/skill-site-prompt-parts/ai-setup-prompt.js +4 -4
  6. package/dist/ai/unified-prompts/skill-site-prompt-parts/ai-setup-prompt.js.map +1 -1
  7. package/dist/config/schema-fuzzer.test.js +1 -1
  8. package/dist/config/schema.d.ts +1 -1
  9. package/dist/config/schema.js +1 -1
  10. package/dist/config-authoring.d.ts +1 -1
  11. package/dist/config-rendering.d.ts +9 -1
  12. package/dist/config-rendering.d.ts.map +1 -1
  13. package/dist/config-rendering.js +2 -2
  14. package/dist/config-rendering.js.map +1 -1
  15. package/dist/dates-BRAvSk6L.d.ts.map +1 -1
  16. package/dist/{email-outbox-B1wmVPRG.d.ts → email-outbox-CqzwInBL.d.ts} +91 -91
  17. package/dist/{email-outbox-B1wmVPRG.d.ts.map → email-outbox-CqzwInBL.d.ts.map} +1 -1
  18. package/dist/esm/ai/unified-prompts/reminders.js +1 -1
  19. package/dist/esm/ai/unified-prompts/reminders.js.map +1 -1
  20. package/dist/esm/ai/unified-prompts/skill-site-prompt-parts/ai-setup-prompt.js +4 -4
  21. package/dist/esm/ai/unified-prompts/skill-site-prompt-parts/ai-setup-prompt.js.map +1 -1
  22. package/dist/esm/config/schema-fuzzer.test.js +1 -1
  23. package/dist/esm/config/schema.d.ts +28 -28
  24. package/dist/esm/config/schema.js +1 -1
  25. package/dist/esm/config-rendering.d.ts +9 -1
  26. package/dist/esm/config-rendering.d.ts.map +1 -1
  27. package/dist/esm/config-rendering.js +2 -3
  28. package/dist/esm/config-rendering.js.map +1 -1
  29. package/dist/esm/interface/admin-interface.js +1 -1
  30. package/dist/esm/interface/client-interface.js +2 -2
  31. package/dist/esm/interface/crud/email-outbox.d.ts +90 -90
  32. package/dist/esm/interface/plan-usage.d.ts +1 -1
  33. package/dist/esm/interface/server-interface.js +1 -1
  34. package/dist/esm/package.json +18 -0
  35. package/dist/esm/utils/dates.d.ts.map +1 -1
  36. package/dist/esm/utils/dates.js +2 -1
  37. package/dist/esm/utils/dates.js.map +1 -1
  38. package/dist/index.d.ts +1 -1
  39. package/dist/interface/admin-interface.d.ts +2 -2
  40. package/dist/interface/admin-interface.js +1 -1
  41. package/dist/interface/client-interface.js +2 -2
  42. package/dist/interface/crud/email-outbox.d.ts +1 -1
  43. package/dist/interface/plan-usage.d.ts +1 -1
  44. package/dist/interface/server-interface.js +1 -1
  45. package/dist/{plan-usage-BaDxcLZ1.d.ts → plan-usage-BO2GsKlN.d.ts} +2 -2
  46. package/dist/{plan-usage-BaDxcLZ1.d.ts.map → plan-usage-BO2GsKlN.d.ts.map} +1 -1
  47. package/dist/{schema-DV0SQUbY.d.ts → schema-CLmaZetm.d.ts} +29 -29
  48. package/dist/{schema-DV0SQUbY.d.ts.map → schema-CLmaZetm.d.ts.map} +1 -1
  49. package/dist/utils/dates.js +2 -1
  50. package/dist/utils/dates.js.map +1 -1
  51. package/package.json +1 -1
  52. package/src/ai/unified-prompts/reminders.ts +1 -1
  53. package/src/ai/unified-prompts/skill-site-prompt-parts/ai-setup-prompt.ts +4 -4
  54. package/src/config-rendering.ts +5 -6
  55. package/src/utils/dates.tsx +22 -1
@@ -83,7 +83,7 @@ declare const branchConfigSchema: yup$1.Schema<Omit<Omit<{
83
83
  sourceOfTruth: {
84
84
  type: "hosted";
85
85
  };
86
- }, string>, "auth" | "onboarding" | "teams" | "rbac" | "payments" | "emails" | "users" | "apiKeys" | "apps" | "domains" | "dataVault"> & {
86
+ }, string>, "auth" | "onboarding" | "teams" | "rbac" | "payments" | "emails" | "apiKeys" | "apps" | "domains" | "users" | "dataVault"> & {
87
87
  payments?: {
88
88
  blockNewPurchases?: boolean | undefined;
89
89
  autoPay?: {
@@ -186,9 +186,6 @@ declare const branchConfigSchema: yup$1.Schema<Omit<Omit<{
186
186
  tsxSource: string;
187
187
  }>;
188
188
  };
189
- users: {
190
- allowClientUserDeletion?: boolean | undefined;
191
- };
192
189
  apiKeys: {
193
190
  enabled: {
194
191
  team?: boolean | undefined;
@@ -201,6 +198,9 @@ declare const branchConfigSchema: yup$1.Schema<Omit<Omit<{
201
198
  }>;
202
199
  };
203
200
  domains: {};
201
+ users: {
202
+ allowClientUserDeletion?: boolean | undefined;
203
+ };
204
204
  dataVault: {
205
205
  stores: Record<string, {
206
206
  displayName?: string | undefined;
@@ -211,7 +211,7 @@ declare const branchConfigSchema: yup$1.Schema<Omit<Omit<{
211
211
  project: {
212
212
  requirePublishableClientKey: undefined;
213
213
  };
214
- }, string>, "auth" | "onboarding" | "teams" | "rbac" | "payments" | "emails" | "users" | "apiKeys" | "apps" | "domains" | "dataVault"> & {
214
+ }, string>, "auth" | "onboarding" | "teams" | "rbac" | "payments" | "emails" | "apiKeys" | "apps" | "domains" | "users" | "dataVault"> & {
215
215
  rbac: {
216
216
  permissions: undefined;
217
217
  defaultPermissions: {
@@ -283,7 +283,7 @@ declare const environmentConfigSchema: yup$1.Schema<Omit<NonNullable<Omit<Omit<{
283
283
  sourceOfTruth: {
284
284
  type: "hosted";
285
285
  };
286
- }, string>, "auth" | "onboarding" | "teams" | "rbac" | "payments" | "emails" | "users" | "apiKeys" | "apps" | "domains" | "dataVault"> & {
286
+ }, string>, "auth" | "onboarding" | "teams" | "rbac" | "payments" | "emails" | "apiKeys" | "apps" | "domains" | "users" | "dataVault"> & {
287
287
  payments?: {
288
288
  blockNewPurchases?: boolean | undefined;
289
289
  autoPay?: {
@@ -386,9 +386,6 @@ declare const environmentConfigSchema: yup$1.Schema<Omit<NonNullable<Omit<Omit<{
386
386
  tsxSource: string;
387
387
  }>;
388
388
  };
389
- users: {
390
- allowClientUserDeletion?: boolean | undefined;
391
- };
392
389
  apiKeys: {
393
390
  enabled: {
394
391
  team?: boolean | undefined;
@@ -401,6 +398,9 @@ declare const environmentConfigSchema: yup$1.Schema<Omit<NonNullable<Omit<Omit<{
401
398
  }>;
402
399
  };
403
400
  domains: {};
401
+ users: {
402
+ allowClientUserDeletion?: boolean | undefined;
403
+ };
404
404
  dataVault: {
405
405
  stores: Record<string, {
406
406
  displayName?: string | undefined;
@@ -565,7 +565,7 @@ declare const environmentConfigSchema: yup$1.Schema<Omit<NonNullable<Omit<Omit<{
565
565
  project: {
566
566
  requirePublishableClientKey: undefined;
567
567
  };
568
- }, string>, "auth" | "onboarding" | "teams" | "rbac" | "payments" | "emails" | "users" | "apiKeys" | "apps" | "domains" | "dataVault"> & {
568
+ }, string>, "auth" | "onboarding" | "teams" | "rbac" | "payments" | "emails" | "apiKeys" | "apps" | "domains" | "users" | "dataVault"> & {
569
569
  rbac: {
570
570
  permissions: undefined;
571
571
  defaultPermissions: {
@@ -635,7 +635,7 @@ declare const environmentConfigSchema: yup$1.Schema<Omit<NonNullable<Omit<Omit<{
635
635
  project: {
636
636
  requirePublishableClientKey: undefined;
637
637
  };
638
- }, string>, "auth" | "onboarding" | "teams" | "rbac" | "payments" | "emails" | "users" | "apiKeys" | "apps" | "domains" | "dataVault"> & {
638
+ }, string>, "auth" | "onboarding" | "teams" | "rbac" | "payments" | "emails" | "apiKeys" | "apps" | "domains" | "users" | "dataVault"> & {
639
639
  rbac: {
640
640
  permissions: undefined;
641
641
  defaultPermissions: {
@@ -705,7 +705,7 @@ declare const environmentConfigSchema: yup$1.Schema<Omit<NonNullable<Omit<Omit<{
705
705
  project: {
706
706
  requirePublishableClientKey: undefined;
707
707
  };
708
- }, string>, "auth" | "onboarding" | "teams" | "rbac" | "payments" | "emails" | "users" | "apiKeys" | "apps" | "domains" | "dataVault"> & {
708
+ }, string>, "auth" | "onboarding" | "teams" | "rbac" | "payments" | "emails" | "apiKeys" | "apps" | "domains" | "users" | "dataVault"> & {
709
709
  rbac: {
710
710
  permissions: undefined;
711
711
  defaultPermissions: {
@@ -778,7 +778,7 @@ declare const environmentConfigSchema: yup$1.Schema<Omit<NonNullable<Omit<Omit<{
778
778
  project: {
779
779
  requirePublishableClientKey: undefined;
780
780
  };
781
- }, string>, "auth" | "onboarding" | "teams" | "rbac" | "payments" | "emails" | "users" | "apiKeys" | "apps" | "domains" | "dataVault"> & {
781
+ }, string>, "auth" | "onboarding" | "teams" | "rbac" | "payments" | "emails" | "apiKeys" | "apps" | "domains" | "users" | "dataVault"> & {
782
782
  rbac: {
783
783
  permissions: undefined;
784
784
  defaultPermissions: {
@@ -861,7 +861,7 @@ declare const environmentConfigSchema: yup$1.Schema<Omit<NonNullable<Omit<Omit<{
861
861
  project: {
862
862
  requirePublishableClientKey: undefined;
863
863
  };
864
- }, string>, "auth" | "onboarding" | "teams" | "rbac" | "payments" | "emails" | "users" | "apiKeys" | "apps" | "domains" | "dataVault"> & {
864
+ }, string>, "auth" | "onboarding" | "teams" | "rbac" | "payments" | "emails" | "apiKeys" | "apps" | "domains" | "users" | "dataVault"> & {
865
865
  rbac: {
866
866
  permissions: undefined;
867
867
  defaultPermissions: {
@@ -934,7 +934,7 @@ declare const environmentConfigSchema: yup$1.Schema<Omit<NonNullable<Omit<Omit<{
934
934
  project: {
935
935
  requirePublishableClientKey: undefined;
936
936
  };
937
- }, string>, "auth" | "onboarding" | "teams" | "rbac" | "payments" | "emails" | "users" | "apiKeys" | "apps" | "domains" | "dataVault"> & {
937
+ }, string>, "auth" | "onboarding" | "teams" | "rbac" | "payments" | "emails" | "apiKeys" | "apps" | "domains" | "users" | "dataVault"> & {
938
938
  rbac: {
939
939
  permissions: undefined;
940
940
  defaultPermissions: {
@@ -1016,7 +1016,7 @@ declare const organizationConfigSchema: yup$1.Schema<Omit<NonNullable<Omit<NonNu
1016
1016
  sourceOfTruth: {
1017
1017
  type: "hosted";
1018
1018
  };
1019
- }, string>, "auth" | "onboarding" | "teams" | "rbac" | "payments" | "emails" | "users" | "apiKeys" | "apps" | "domains" | "dataVault"> & {
1019
+ }, string>, "auth" | "onboarding" | "teams" | "rbac" | "payments" | "emails" | "apiKeys" | "apps" | "domains" | "users" | "dataVault"> & {
1020
1020
  payments?: {
1021
1021
  blockNewPurchases?: boolean | undefined;
1022
1022
  autoPay?: {
@@ -1119,9 +1119,6 @@ declare const organizationConfigSchema: yup$1.Schema<Omit<NonNullable<Omit<NonNu
1119
1119
  tsxSource: string;
1120
1120
  }>;
1121
1121
  };
1122
- users: {
1123
- allowClientUserDeletion?: boolean | undefined;
1124
- };
1125
1122
  apiKeys: {
1126
1123
  enabled: {
1127
1124
  team?: boolean | undefined;
@@ -1134,6 +1131,9 @@ declare const organizationConfigSchema: yup$1.Schema<Omit<NonNullable<Omit<NonNu
1134
1131
  }>;
1135
1132
  };
1136
1133
  domains: {};
1134
+ users: {
1135
+ allowClientUserDeletion?: boolean | undefined;
1136
+ };
1137
1137
  dataVault: {
1138
1138
  stores: Record<string, {
1139
1139
  displayName?: string | undefined;
@@ -1298,7 +1298,7 @@ declare const organizationConfigSchema: yup$1.Schema<Omit<NonNullable<Omit<NonNu
1298
1298
  project: {
1299
1299
  requirePublishableClientKey: undefined;
1300
1300
  };
1301
- }, string>, "auth" | "onboarding" | "teams" | "rbac" | "payments" | "emails" | "users" | "apiKeys" | "apps" | "domains" | "dataVault"> & {
1301
+ }, string>, "auth" | "onboarding" | "teams" | "rbac" | "payments" | "emails" | "apiKeys" | "apps" | "domains" | "users" | "dataVault"> & {
1302
1302
  rbac: {
1303
1303
  permissions: undefined;
1304
1304
  defaultPermissions: {
@@ -1368,7 +1368,7 @@ declare const organizationConfigSchema: yup$1.Schema<Omit<NonNullable<Omit<NonNu
1368
1368
  project: {
1369
1369
  requirePublishableClientKey: undefined;
1370
1370
  };
1371
- }, string>, "auth" | "onboarding" | "teams" | "rbac" | "payments" | "emails" | "users" | "apiKeys" | "apps" | "domains" | "dataVault"> & {
1371
+ }, string>, "auth" | "onboarding" | "teams" | "rbac" | "payments" | "emails" | "apiKeys" | "apps" | "domains" | "users" | "dataVault"> & {
1372
1372
  rbac: {
1373
1373
  permissions: undefined;
1374
1374
  defaultPermissions: {
@@ -1438,7 +1438,7 @@ declare const organizationConfigSchema: yup$1.Schema<Omit<NonNullable<Omit<NonNu
1438
1438
  project: {
1439
1439
  requirePublishableClientKey: undefined;
1440
1440
  };
1441
- }, string>, "auth" | "onboarding" | "teams" | "rbac" | "payments" | "emails" | "users" | "apiKeys" | "apps" | "domains" | "dataVault"> & {
1441
+ }, string>, "auth" | "onboarding" | "teams" | "rbac" | "payments" | "emails" | "apiKeys" | "apps" | "domains" | "users" | "dataVault"> & {
1442
1442
  rbac: {
1443
1443
  permissions: undefined;
1444
1444
  defaultPermissions: {
@@ -1511,7 +1511,7 @@ declare const organizationConfigSchema: yup$1.Schema<Omit<NonNullable<Omit<NonNu
1511
1511
  project: {
1512
1512
  requirePublishableClientKey: undefined;
1513
1513
  };
1514
- }, string>, "auth" | "onboarding" | "teams" | "rbac" | "payments" | "emails" | "users" | "apiKeys" | "apps" | "domains" | "dataVault"> & {
1514
+ }, string>, "auth" | "onboarding" | "teams" | "rbac" | "payments" | "emails" | "apiKeys" | "apps" | "domains" | "users" | "dataVault"> & {
1515
1515
  rbac: {
1516
1516
  permissions: undefined;
1517
1517
  defaultPermissions: {
@@ -1594,7 +1594,7 @@ declare const organizationConfigSchema: yup$1.Schema<Omit<NonNullable<Omit<NonNu
1594
1594
  project: {
1595
1595
  requirePublishableClientKey: undefined;
1596
1596
  };
1597
- }, string>, "auth" | "onboarding" | "teams" | "rbac" | "payments" | "emails" | "users" | "apiKeys" | "apps" | "domains" | "dataVault"> & {
1597
+ }, string>, "auth" | "onboarding" | "teams" | "rbac" | "payments" | "emails" | "apiKeys" | "apps" | "domains" | "users" | "dataVault"> & {
1598
1598
  rbac: {
1599
1599
  permissions: undefined;
1600
1600
  defaultPermissions: {
@@ -1667,7 +1667,7 @@ declare const organizationConfigSchema: yup$1.Schema<Omit<NonNullable<Omit<NonNu
1667
1667
  project: {
1668
1668
  requirePublishableClientKey: undefined;
1669
1669
  };
1670
- }, string>, "auth" | "onboarding" | "teams" | "rbac" | "payments" | "emails" | "users" | "apiKeys" | "apps" | "domains" | "dataVault"> & {
1670
+ }, string>, "auth" | "onboarding" | "teams" | "rbac" | "payments" | "emails" | "apiKeys" | "apps" | "domains" | "users" | "dataVault"> & {
1671
1671
  rbac: {
1672
1672
  permissions: undefined;
1673
1673
  defaultPermissions: {
@@ -2187,9 +2187,6 @@ declare function sanitizeOrganizationConfig(config: OrganizationRenderedConfigBe
2187
2187
  };
2188
2188
  };
2189
2189
  };
2190
- users: {
2191
- allowClientUserDeletion: boolean;
2192
- };
2193
2190
  apiKeys: {
2194
2191
  enabled: {
2195
2192
  team: boolean;
@@ -2205,6 +2202,9 @@ declare function sanitizeOrganizationConfig(config: OrganizationRenderedConfigBe
2205
2202
  };
2206
2203
  };
2207
2204
  };
2205
+ users: {
2206
+ allowClientUserDeletion: boolean;
2207
+ };
2208
2208
  dataVault: {
2209
2209
  stores: {
2210
2210
  [x: string]: {
@@ -1,9 +1,9 @@
1
1
  import * as yup$1 from "yup";
2
+ import { stringCompare } from "../utils/strings.js";
2
3
  import { HexclaveAssertionError } from "../utils/errors.js";
3
4
  import { filterUndefined, get, getOrUndefined, has, isObjectLike, mapValues, set, typedAssign, typedEntries, typedFromEntries } from "../utils/objects.js";
4
5
  import { ALL_APPS } from "../apps/apps-config.js";
5
6
  import { SUPPORTED_CURRENCIES } from "../utils/currency-constants.js";
6
- import { stringCompare } from "../utils/strings.js";
7
7
  import { NormalizationError, assertNormalized, getInvalidConfigReason, normalize } from "./format.js";
8
8
  import { DEFAULT_EMAIL_TEMPLATES, DEFAULT_EMAIL_THEMES, DEFAULT_EMAIL_THEME_ID } from "../helpers/emails.js";
9
9
  import * as schemaFields from "../schema-fields.js";
@@ -1,4 +1,12 @@
1
1
  //#region src/config-rendering.d.ts
2
+ /**
3
+ * Packages that export the `HexclaveConfig` type, in priority order.
4
+ * The first match found in a project's dependencies wins. Hexclave-branded
5
+ * packages come first (canonical); the legacy `@stackframe/*` names remain
6
+ * so projects pinned to the last legacy release still render a config file
7
+ * that compiles against their installed SDK.
8
+ */
9
+ declare const CONFIG_IMPORT_PACKAGES: readonly ["@hexclave/next", "@hexclave/react", "@hexclave/tanstack-start", "@hexclave/js", "@hexclave/template", "@stackframe/stack", "@stackframe/react", "@stackframe/js", "@stackframe/template"];
2
10
  /**
3
11
  * Given a list of dependency names (from package.json), returns the SDK
4
12
  * package that should be used for the `HexclaveConfig` import, or `undefined`
@@ -10,5 +18,5 @@ declare function detectConfigImportPackage(dependencies: string[]): string | und
10
18
  */
11
19
  declare function renderConfigFileContent(config: unknown, importPackage?: string): string;
12
20
  //#endregion
13
- export { detectConfigImportPackage, renderConfigFileContent };
21
+ export { CONFIG_IMPORT_PACKAGES, detectConfigImportPackage, renderConfigFileContent };
14
22
  //# sourceMappingURL=config-rendering.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"config-rendering.d.ts","names":[],"sources":["../../src/config-rendering.ts"],"mappings":";;AA4BA;;;;iBAAgB,yBAAA,CAA0B,YAAsB;AAYhE;;;AAAA,iBAAgB,uBAAA,CAAwB,MAAA,WAAiB,aAAsB"}
1
+ {"version":3,"file":"config-rendering.d.ts","names":[],"sources":["../../src/config-rendering.ts"],"mappings":";;AAWA;;;;AAUU;AAOV;cAjBa,sBAAA;;;AAiBmD;AAYhE;;iBAZgB,yBAAA,CAA0B,YAAsB;;AAYe;;iBAA/D,uBAAA,CAAwB,MAAA,WAAiB,aAAsB"}
@@ -39,10 +39,9 @@ function renderConfigFileContent(config, importPackage) {
39
39
  droppedKeys
40
40
  });
41
41
  if (droppedKeys.length > 0) throw new Error(`Config has conflicting keys that would be dropped during normalization: ${droppedKeys.map((k) => JSON.stringify(k)).join(", ")}`);
42
- const pkg = importPackage ?? DEFAULT_CONFIG_IMPORT_PACKAGE;
43
- return `${`import type { HexclaveConfig } from "${pkg.startsWith("@hexclave/") ? `${pkg}/config` : pkg}";`}\n\nexport const config: HexclaveConfig = ${JSON.stringify(normalizedConfig, null, 2)};\n`;
42
+ return `${`import type { HexclaveConfig } from "${importPackage ?? DEFAULT_CONFIG_IMPORT_PACKAGE}";`}\n\nexport const config: HexclaveConfig = ${JSON.stringify(normalizedConfig, null, 2)};\n`;
44
43
  }
45
44
  //#endregion
46
- export { detectConfigImportPackage, renderConfigFileContent };
45
+ export { CONFIG_IMPORT_PACKAGES, detectConfigImportPackage, renderConfigFileContent };
47
46
 
48
47
  //# sourceMappingURL=config-rendering.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"config-rendering.js","names":[],"sources":["../../src/config-rendering.ts"],"sourcesContent":["import { isValidConfig, normalize } from \"./config/format\";\n\nconst DEFAULT_CONFIG_IMPORT_PACKAGE = \"@hexclave/js\";\n\n/**\n * Packages that export the `HexclaveConfig` type, in priority order.\n * The first match found in a project's dependencies wins. Hexclave-branded\n * packages come first (canonical); the legacy `@stackframe/*` names remain\n * so projects pinned to the last legacy release still render a config file\n * that compiles against their installed SDK.\n */\nconst CONFIG_IMPORT_PACKAGES = [\n \"@hexclave/next\",\n \"@hexclave/react\",\n \"@hexclave/tanstack-start\",\n \"@hexclave/js\",\n \"@hexclave/template\",\n \"@stackframe/stack\",\n \"@stackframe/react\",\n \"@stackframe/js\",\n \"@stackframe/template\",\n] as const;\n\n/**\n * Given a list of dependency names (from package.json), returns the SDK\n * package that should be used for the `HexclaveConfig` import, or `undefined`\n * if none of the known packages are installed.\n */\nexport function detectConfigImportPackage(dependencies: string[]): string | undefined {\n for (const pkg of CONFIG_IMPORT_PACKAGES) {\n if (dependencies.includes(pkg)) {\n return pkg;\n }\n }\n return undefined;\n}\n\n/**\n * Renders a config object into the source text of a `stack.config.ts` file.\n */\nexport function renderConfigFileContent(config: unknown, importPackage?: string): string {\n if (!isValidConfig(config)) {\n throw new Error(\"Invalid config: expected a plain object.\");\n }\n\n const droppedKeys: string[] = [];\n const normalizedConfig = normalize(config, {\n onDotIntoNonObject: \"ignore\",\n onDotIntoNull: \"empty-object\",\n droppedKeys,\n });\n if (droppedKeys.length > 0) {\n throw new Error(`Config has conflicting keys that would be dropped during normalization: ${droppedKeys.map(k => JSON.stringify(k)).join(\", \")}`);\n }\n const pkg = importPackage ?? DEFAULT_CONFIG_IMPORT_PACKAGE;\n const importSpecifier = pkg.startsWith(\"@hexclave/\") ? `${pkg}/config` : pkg;\n const importLine = `import type { HexclaveConfig } from \"${importSpecifier}\";`;\n return `${importLine}\\n\\nexport const config: HexclaveConfig = ${JSON.stringify(normalizedConfig, null, 2)};\\n`;\n}\n\n// --- inline vitest tests ---\n\nimport.meta.vitest?.test(\"renderConfigFileContent normalizes config exports\", ({ expect }) => {\n expect(renderConfigFileContent({\n \"payments.items.todos.displayName\": \"Todo Slots\",\n \"payments.items.todos.customerType\": \"user\",\n })).toContain(`export const config: HexclaveConfig = {\n \"payments\": {\n \"items\": {\n \"todos\": {\n \"displayName\": \"Todo Slots\",\n \"customerType\": \"user\"\n }\n }\n }\n};`);\n});\n\nimport.meta.vitest?.test(\"renderConfigFileContent rejects conflicting dotted keys\", ({ expect }) => {\n expect(() => renderConfigFileContent({\n \"a.b\": 1,\n \"a.b.c\": 2,\n })).toThrowError(/conflicting keys.*\"a\\.b\\.c\"/);\n});\n\nimport.meta.vitest?.test(\"renderConfigFileContent rejects invalid config exports\", ({ expect }) => {\n expect(() => renderConfigFileContent(null)).toThrowErrorMatchingInlineSnapshot(\n `[Error: Invalid config: expected a plain object.]`,\n );\n});\n\nimport.meta.vitest?.test(\"renderConfigFileContent uses custom import package\", ({ expect }) => {\n const content = renderConfigFileContent({}, \"@hexclave/next\");\n expect(content).toContain('import type { HexclaveConfig } from \"@hexclave/next/config\";');\n});\n\nimport.meta.vitest?.test(\"renderConfigFileContent defaults to @hexclave/js\", ({ expect }) => {\n const content = renderConfigFileContent({});\n expect(content).toContain('import type { HexclaveConfig } from \"@hexclave/js/config\";');\n});\n\nimport.meta.vitest?.test(\"renderConfigFileContent keeps legacy @stackframe packages on their root entrypoint\", ({ expect }) => {\n const content = renderConfigFileContent({}, \"@stackframe/next\");\n expect(content).toContain('import type { HexclaveConfig } from \"@stackframe/next\";');\n});\n\nimport.meta.vitest?.test(\"detectConfigImportPackage picks first matching package by priority\", ({ expect }) => {\n expect(detectConfigImportPackage([\"@hexclave/next\", \"@hexclave/js\"])).toBe(\"@hexclave/next\");\n expect(detectConfigImportPackage([\"@hexclave/react\", \"@hexclave/js\"])).toBe(\"@hexclave/react\");\n expect(detectConfigImportPackage([\"@hexclave/js\"])).toBe(\"@hexclave/js\");\n expect(detectConfigImportPackage([\"@hexclave/tanstack-start\"])).toBe(\"@hexclave/tanstack-start\");\n expect(detectConfigImportPackage([\"@stackframe/stack\", \"@hexclave/next\"])).toBe(\"@hexclave/next\");\n expect(detectConfigImportPackage([\"@stackframe/stack\"])).toBe(\"@stackframe/stack\");\n expect(detectConfigImportPackage([\"@stackframe/template\"])).toBe(\"@stackframe/template\");\n expect(detectConfigImportPackage([\"lodash\", \"express\"])).toBeUndefined();\n expect(detectConfigImportPackage([])).toBeUndefined();\n});\n"],"mappings":";;AAEA,MAAM,gCAAgC;;;;;;;;AAStC,MAAM,yBAAyB;CAC7B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;;;;;;AAOA,SAAgB,0BAA0B,cAA4C;CACpF,KAAK,MAAM,OAAO,wBAChB,IAAI,aAAa,SAAS,GAAG,GAC3B,OAAO;AAIb;;;;AAKA,SAAgB,wBAAwB,QAAiB,eAAgC;CACvF,IAAI,CAAC,cAAc,MAAM,GACvB,MAAM,IAAI,MAAM,0CAA0C;CAG5D,MAAM,cAAwB,CAAC;CAC/B,MAAM,mBAAmB,UAAU,QAAQ;EACzC,oBAAoB;EACpB,eAAe;EACf;CACF,CAAC;CACD,IAAI,YAAY,SAAS,GACvB,MAAM,IAAI,MAAM,2EAA2E,YAAY,KAAI,MAAK,KAAK,UAAU,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG;CAEjJ,MAAM,MAAM,iBAAiB;CAG7B,OAAO,GAAG,wCAFc,IAAI,WAAW,YAAY,IAAI,GAAG,IAAI,WAAW,IACE,IACtD,4CAA4C,KAAK,UAAU,kBAAkB,MAAM,CAAC,EAAE;AAC7G"}
1
+ {"version":3,"file":"config-rendering.js","names":[],"sources":["../../src/config-rendering.ts"],"sourcesContent":["import { isValidConfig, normalize } from \"./config/format\";\n\nconst DEFAULT_CONFIG_IMPORT_PACKAGE = \"@hexclave/js\";\n\n/**\n * Packages that export the `HexclaveConfig` type, in priority order.\n * The first match found in a project's dependencies wins. Hexclave-branded\n * packages come first (canonical); the legacy `@stackframe/*` names remain\n * so projects pinned to the last legacy release still render a config file\n * that compiles against their installed SDK.\n */\nexport const CONFIG_IMPORT_PACKAGES = [\n \"@hexclave/next\",\n \"@hexclave/react\",\n \"@hexclave/tanstack-start\",\n \"@hexclave/js\",\n \"@hexclave/template\",\n \"@stackframe/stack\",\n \"@stackframe/react\",\n \"@stackframe/js\",\n \"@stackframe/template\",\n] as const;\n\n/**\n * Given a list of dependency names (from package.json), returns the SDK\n * package that should be used for the `HexclaveConfig` import, or `undefined`\n * if none of the known packages are installed.\n */\nexport function detectConfigImportPackage(dependencies: string[]): string | undefined {\n for (const pkg of CONFIG_IMPORT_PACKAGES) {\n if (dependencies.includes(pkg)) {\n return pkg;\n }\n }\n return undefined;\n}\n\n/**\n * Renders a config object into the source text of a `stack.config.ts` file.\n */\nexport function renderConfigFileContent(config: unknown, importPackage?: string): string {\n if (!isValidConfig(config)) {\n throw new Error(\"Invalid config: expected a plain object.\");\n }\n\n const droppedKeys: string[] = [];\n const normalizedConfig = normalize(config, {\n onDotIntoNonObject: \"ignore\",\n onDotIntoNull: \"empty-object\",\n droppedKeys,\n });\n if (droppedKeys.length > 0) {\n throw new Error(`Config has conflicting keys that would be dropped during normalization: ${droppedKeys.map(k => JSON.stringify(k)).join(\", \")}`);\n }\n const pkg = importPackage ?? DEFAULT_CONFIG_IMPORT_PACKAGE;\n const importLine = `import type { HexclaveConfig } from \"${pkg}\";`;\n return `${importLine}\\n\\nexport const config: HexclaveConfig = ${JSON.stringify(normalizedConfig, null, 2)};\\n`;\n}\n\n// --- inline vitest tests ---\n\nimport.meta.vitest?.test(\"renderConfigFileContent normalizes config exports\", ({ expect }) => {\n expect(renderConfigFileContent({\n \"payments.items.todos.displayName\": \"Todo Slots\",\n \"payments.items.todos.customerType\": \"user\",\n })).toContain(`export const config: HexclaveConfig = {\n \"payments\": {\n \"items\": {\n \"todos\": {\n \"displayName\": \"Todo Slots\",\n \"customerType\": \"user\"\n }\n }\n }\n};`);\n});\n\nimport.meta.vitest?.test(\"renderConfigFileContent rejects conflicting dotted keys\", ({ expect }) => {\n expect(() => renderConfigFileContent({\n \"a.b\": 1,\n \"a.b.c\": 2,\n })).toThrowError(/conflicting keys.*\"a\\.b\\.c\"/);\n});\n\nimport.meta.vitest?.test(\"renderConfigFileContent rejects invalid config exports\", ({ expect }) => {\n expect(() => renderConfigFileContent(null)).toThrowErrorMatchingInlineSnapshot(\n `[Error: Invalid config: expected a plain object.]`,\n );\n});\n\nimport.meta.vitest?.test(\"renderConfigFileContent uses custom import package\", ({ expect }) => {\n const content = renderConfigFileContent({}, \"@hexclave/next\");\n expect(content).toContain('import type { HexclaveConfig } from \"@hexclave/next\";');\n});\n\nimport.meta.vitest?.test(\"renderConfigFileContent defaults to @hexclave/js\", ({ expect }) => {\n const content = renderConfigFileContent({});\n expect(content).toContain('import type { HexclaveConfig } from \"@hexclave/js\";');\n});\n\nimport.meta.vitest?.test(\"renderConfigFileContent imports from the SDK package root\", ({ expect }) => {\n const content = renderConfigFileContent({}, \"@stackframe/next\");\n expect(content).toContain('import type { HexclaveConfig } from \"@stackframe/next\";');\n});\n\nimport.meta.vitest?.test(\"detectConfigImportPackage picks first matching package by priority\", ({ expect }) => {\n expect(detectConfigImportPackage([\"@hexclave/next\", \"@hexclave/js\"])).toBe(\"@hexclave/next\");\n expect(detectConfigImportPackage([\"@hexclave/react\", \"@hexclave/js\"])).toBe(\"@hexclave/react\");\n expect(detectConfigImportPackage([\"@hexclave/js\"])).toBe(\"@hexclave/js\");\n expect(detectConfigImportPackage([\"@hexclave/tanstack-start\"])).toBe(\"@hexclave/tanstack-start\");\n expect(detectConfigImportPackage([\"@stackframe/stack\", \"@hexclave/next\"])).toBe(\"@hexclave/next\");\n expect(detectConfigImportPackage([\"@stackframe/stack\"])).toBe(\"@stackframe/stack\");\n expect(detectConfigImportPackage([\"@stackframe/template\"])).toBe(\"@stackframe/template\");\n expect(detectConfigImportPackage([\"lodash\", \"express\"])).toBeUndefined();\n expect(detectConfigImportPackage([])).toBeUndefined();\n});\n"],"mappings":";;AAEA,MAAM,gCAAgC;;;;;;;;AAStC,MAAa,yBAAyB;CACpC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;;;;;;AAOA,SAAgB,0BAA0B,cAA4C;CACpF,KAAK,MAAM,OAAO,wBAChB,IAAI,aAAa,SAAS,GAAG,GAC3B,OAAO;AAIb;;;;AAKA,SAAgB,wBAAwB,QAAiB,eAAgC;CACvF,IAAI,CAAC,cAAc,MAAM,GACvB,MAAM,IAAI,MAAM,0CAA0C;CAG5D,MAAM,cAAwB,CAAC;CAC/B,MAAM,mBAAmB,UAAU,QAAQ;EACzC,oBAAoB;EACpB,eAAe;EACf;CACF,CAAC;CACD,IAAI,YAAY,SAAS,GACvB,MAAM,IAAI,MAAM,2EAA2E,YAAY,KAAI,MAAK,KAAK,UAAU,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG;CAIjJ,OAAO,GAAG,wCAFE,iBAAiB,8BACkC,IAC1C,4CAA4C,KAAK,UAAU,kBAAkB,MAAM,CAAC,EAAE;AAC7G"}
@@ -1,5 +1,5 @@
1
- import { Result } from "../utils/results.js";
2
1
  import { urlString } from "../utils/urls.js";
2
+ import { Result } from "../utils/results.js";
3
3
  import { KnownErrors } from "../known-errors.js";
4
4
  import { HexclaveServerInterface } from "./server-interface.js";
5
5
  //#region src/interface/admin-interface.ts
@@ -1,9 +1,9 @@
1
+ import { deindent } from "../utils/strings.js";
1
2
  import { HexclaveAssertionError, throwErr } from "../utils/errors.js";
3
+ import { urlString } from "../utils/urls.js";
2
4
  import { filterUndefined, filterUndefinedOrNull } from "../utils/objects.js";
3
- import { deindent } from "../utils/strings.js";
4
5
  import { publishableClientKeyNotNecessarySentinel } from "../utils/oauth.js";
5
6
  import { Result } from "../utils/results.js";
6
- import { urlString } from "../utils/urls.js";
7
7
  import { KnownError, KnownErrors } from "../known-errors.js";
8
8
  import { AccessToken, InternalSession } from "../sessions.js";
9
9
  import { generateSecureRandomString } from "../utils/crypto.js";