@hexclave/next 1.0.70 → 1.0.72

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 (122) hide show
  1. package/dist/{admin-app-impl-DFjllAVr.d.ts → admin-app-impl-DLqm4Zqy.d.ts} +42 -2
  2. package/dist/admin-app-impl-DLqm4Zqy.d.ts.map +1 -0
  3. package/dist/clickmap/clickmap-core.d.ts +1 -1
  4. package/dist/clickmap/index.d.ts +1 -1
  5. package/dist/{client-app-CE8FTKgO.d.ts → client-app-DlKeB4SB.d.ts} +41 -2
  6. package/dist/client-app-DlKeB4SB.d.ts.map +1 -0
  7. package/dist/components/selected-team-switcher.d.ts +1 -1
  8. package/dist/components/team-icon.d.ts +1 -1
  9. package/dist/components/team-switcher.d.ts +1 -1
  10. package/dist/components-page/account-settings/payments/payments-page.d.ts +1 -1
  11. package/dist/components-page/account-settings/teams/leave-team-section.d.ts +1 -1
  12. package/dist/components-page/account-settings/teams/team-api-keys-section.d.ts +1 -1
  13. package/dist/components-page/account-settings/teams/team-display-name-section.d.ts +1 -1
  14. package/dist/components-page/account-settings/teams/team-member-invitation-section.d.ts +1 -1
  15. package/dist/components-page/account-settings/teams/team-member-list-section.d.ts +1 -1
  16. package/dist/components-page/account-settings/teams/team-page.d.ts +1 -1
  17. package/dist/components-page/account-settings/teams/team-profile-image-section.d.ts +1 -1
  18. package/dist/components-page/account-settings/teams/team-profile-user-section.d.ts +1 -1
  19. package/dist/components-page/hexclave-handler-client.d.ts +1 -1
  20. package/dist/components-page/hexclave-handler.d.ts +1 -1
  21. package/dist/dev-tool/dev-tool-core.d.ts +1 -1
  22. package/dist/dev-tool/index.d.ts +1 -1
  23. package/dist/esm/generated/quetzal-translations.d.ts +2 -2
  24. package/dist/esm/lib/hexclave-app/apps/implementations/admin-app-impl.d.ts +40 -0
  25. package/dist/esm/lib/hexclave-app/apps/implementations/admin-app-impl.d.ts.map +1 -1
  26. package/dist/esm/lib/hexclave-app/apps/implementations/admin-app-impl.js +102 -0
  27. package/dist/esm/lib/hexclave-app/apps/implementations/admin-app-impl.js.map +1 -1
  28. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.cross-domain.test.js +3 -3
  29. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.cross-domain.test.js.map +1 -1
  30. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.d.ts.map +1 -1
  31. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.js +3 -4
  32. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.js.map +1 -1
  33. package/dist/esm/lib/hexclave-app/apps/implementations/common.js +2 -2
  34. package/dist/esm/lib/hexclave-app/apps/implementations/server-app-impl.d.ts.map +1 -1
  35. package/dist/esm/lib/hexclave-app/apps/implementations/server-app-impl.js +2 -2
  36. package/dist/esm/lib/hexclave-app/apps/implementations/server-app-impl.js.map +1 -1
  37. package/dist/esm/lib/hexclave-app/apps/interfaces/admin-app.d.ts +41 -2
  38. package/dist/esm/lib/hexclave-app/apps/interfaces/admin-app.d.ts.map +1 -1
  39. package/dist/esm/lib/hexclave-app/apps/interfaces/admin-app.js.map +1 -1
  40. package/dist/esm/lib/hexclave-app/index.d.ts +2 -1
  41. package/dist/esm/lib/hexclave-app/passkey-rp-id.d.ts +12 -0
  42. package/dist/esm/lib/hexclave-app/passkey-rp-id.d.ts.map +1 -0
  43. package/dist/esm/lib/hexclave-app/passkey-rp-id.js +15 -0
  44. package/dist/esm/lib/hexclave-app/passkey-rp-id.js.map +1 -0
  45. package/dist/esm/lib/hexclave-app/passkey-rp-id.test.d.ts +1 -0
  46. package/dist/esm/lib/hexclave-app/passkey-rp-id.test.js +26 -0
  47. package/dist/esm/lib/hexclave-app/passkey-rp-id.test.js.map +1 -0
  48. package/dist/esm/lib/hexclave-app/workflows.d.ts +125 -0
  49. package/dist/esm/lib/hexclave-app/workflows.d.ts.map +1 -0
  50. package/dist/esm/lib/hexclave-app/workflows.js +110 -0
  51. package/dist/esm/lib/hexclave-app/workflows.js.map +1 -0
  52. package/dist/esm/lib/hexclave-app/workflows.test.d.ts +1 -0
  53. package/dist/esm/lib/hexclave-app/workflows.test.js +25 -0
  54. package/dist/esm/lib/hexclave-app/workflows.test.js.map +1 -0
  55. package/dist/generated/quetzal-translations.d.ts +1 -1
  56. package/dist/{hexclave-provider-CVCzN4xG.d.ts → hexclave-provider-B_KtSfuf.d.ts} +3 -3
  57. package/dist/{hexclave-provider-CVCzN4xG.d.ts.map → hexclave-provider-B_KtSfuf.d.ts.map} +1 -1
  58. package/dist/{hooks-BNF4UvGF.d.ts → hooks-nHRIrxA9.d.ts} +2 -2
  59. package/dist/{hooks-BNF4UvGF.d.ts.map → hooks-nHRIrxA9.d.ts.map} +1 -1
  60. package/dist/{index-g1JoVgIu.d.ts → index-CsExJ_pK.d.ts} +2 -2
  61. package/dist/{index-g1JoVgIu.d.ts.map → index-CsExJ_pK.d.ts.map} +1 -1
  62. package/dist/index.d.ts +6 -5
  63. package/dist/lib/hexclave-app/apps/implementations/admin-app-impl.d.ts +1 -1
  64. package/dist/lib/hexclave-app/apps/implementations/admin-app-impl.js +102 -0
  65. package/dist/lib/hexclave-app/apps/implementations/admin-app-impl.js.map +1 -1
  66. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.cross-domain.test.js +3 -3
  67. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.cross-domain.test.js.map +1 -1
  68. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.d.ts +1 -1
  69. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.js +3 -4
  70. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.js.map +1 -1
  71. package/dist/lib/hexclave-app/apps/implementations/common.js +2 -2
  72. package/dist/lib/hexclave-app/apps/implementations/index.d.ts +1 -1
  73. package/dist/lib/hexclave-app/apps/implementations/server-app-impl.d.ts +1 -1
  74. package/dist/lib/hexclave-app/apps/implementations/server-app-impl.js +2 -2
  75. package/dist/lib/hexclave-app/apps/implementations/server-app-impl.js.map +1 -1
  76. package/dist/lib/hexclave-app/apps/index.d.ts +1 -1
  77. package/dist/lib/hexclave-app/apps/interfaces/admin-app.d.ts +3 -2
  78. package/dist/lib/hexclave-app/apps/interfaces/admin-app.js.map +1 -1
  79. package/dist/lib/hexclave-app/apps/interfaces/client-app.d.ts +1 -1
  80. package/dist/lib/hexclave-app/apps/interfaces/server-app.d.ts +1 -1
  81. package/dist/lib/hexclave-app/index.d.ts +3 -2
  82. package/dist/lib/hexclave-app/passkey-rp-id.d.ts +12 -0
  83. package/dist/lib/hexclave-app/passkey-rp-id.d.ts.map +1 -0
  84. package/dist/lib/hexclave-app/passkey-rp-id.js +17 -0
  85. package/dist/lib/hexclave-app/passkey-rp-id.js.map +1 -0
  86. package/dist/lib/hexclave-app/passkey-rp-id.test.d.ts +1 -0
  87. package/dist/lib/hexclave-app/passkey-rp-id.test.js +25 -0
  88. package/dist/lib/hexclave-app/passkey-rp-id.test.js.map +1 -0
  89. package/dist/lib/hexclave-app/projects/index.d.ts +1 -1
  90. package/dist/lib/hexclave-app/teams/index.d.ts +1 -1
  91. package/dist/lib/hexclave-app/users/index.d.ts +1 -1
  92. package/dist/lib/hexclave-app/workflows.d.ts +2 -0
  93. package/dist/lib/hexclave-app/workflows.js +116 -0
  94. package/dist/lib/hexclave-app/workflows.js.map +1 -0
  95. package/dist/lib/hexclave-app/workflows.test.d.ts +1 -0
  96. package/dist/lib/hexclave-app/workflows.test.js +24 -0
  97. package/dist/lib/hexclave-app/workflows.test.js.map +1 -0
  98. package/dist/lib/hooks.d.ts +1 -1
  99. package/dist/providers/hexclave-context.d.ts +1 -1
  100. package/dist/providers/hexclave-provider-client.d.ts +1 -1
  101. package/dist/providers/hexclave-provider.d.ts +1 -1
  102. package/dist/providers/translation-provider.d.ts +1 -1
  103. package/dist/pushed-config-error-overlay/index.d.ts +1 -1
  104. package/dist/{quetzal-translations-DVNj-zsr.d.ts → quetzal-translations-XeH3zQ9l.d.ts} +3 -3
  105. package/dist/{quetzal-translations-DVNj-zsr.d.ts.map → quetzal-translations-XeH3zQ9l.d.ts.map} +1 -1
  106. package/dist/{translation-provider-DPFkLbrw.d.ts → translation-provider-WOaZXqAz.d.ts} +2 -2
  107. package/dist/{translation-provider-DPFkLbrw.d.ts.map → translation-provider-WOaZXqAz.d.ts.map} +1 -1
  108. package/dist/workflows-DEb7pIuQ.d.ts +125 -0
  109. package/dist/workflows-DEb7pIuQ.d.ts.map +1 -0
  110. package/package.json +4 -4
  111. package/src/lib/hexclave-app/apps/implementations/admin-app-impl.ts +123 -0
  112. package/src/lib/hexclave-app/apps/implementations/client-app-impl.cross-domain.test.ts +3 -3
  113. package/src/lib/hexclave-app/apps/implementations/client-app-impl.ts +10 -11
  114. package/src/lib/hexclave-app/apps/implementations/server-app-impl.ts +2 -7
  115. package/src/lib/hexclave-app/apps/interfaces/admin-app.ts +19 -0
  116. package/src/lib/hexclave-app/index.ts +15 -0
  117. package/src/lib/hexclave-app/passkey-rp-id.test.ts +43 -0
  118. package/src/lib/hexclave-app/passkey-rp-id.ts +27 -0
  119. package/src/lib/hexclave-app/workflows.test.ts +28 -0
  120. package/src/lib/hexclave-app/workflows.ts +245 -0
  121. package/dist/admin-app-impl-DFjllAVr.d.ts.map +0 -1
  122. package/dist/client-app-CE8FTKgO.d.ts.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"quetzal-translations-DVNj-zsr.d.ts","names":[],"sources":["../src/generated/quetzal-translations.ts"],"mappings":";cAUa,WAAA,EAAW,GAAA;AAAA,cAqTX,cAAA,EAAc,GAAA,mIAAA,GAAA,66qBAAA,GAAA,usnBAAA,GAAA,iyrBAAA,GAAA,g+qBAAA,GAAA,8srBAAA,GAAA,2trBAAA,GAAA,41pBAAA,GAAA,m3eAAA,GAAA,oreAAA,GAAA,swpBAAA,GAAA,+0qBAAA,GAAA,8wbAAA,GAAA"}
1
+ {"version":3,"file":"quetzal-translations-XeH3zQ9l.d.ts","names":[],"sources":["../src/generated/quetzal-translations.ts"],"mappings":";cAUa,WAAA,EAAW,GAAA;AAAA,cAqTX,cAAA,EAAc,GAAA,mIAAA,GAAA,66qBAAA,GAAA,usnBAAA,GAAA,iyrBAAA,GAAA,g+qBAAA,GAAA,8srBAAA,GAAA,2trBAAA,GAAA,41pBAAA,GAAA,m3eAAA,GAAA,oreAAA,GAAA,swpBAAA,GAAA,+0qBAAA,GAAA,8wbAAA,GAAA"}
@@ -1,4 +1,4 @@
1
- import { n as quetzalLocales } from "./quetzal-translations-DVNj-zsr.js";
1
+ import { n as quetzalLocales } from "./quetzal-translations-XeH3zQ9l.js";
2
2
 
3
3
  //#region src/providers/translation-provider.d.ts
4
4
  declare function TranslationProvider({
@@ -12,4 +12,4 @@ declare function TranslationProvider({
12
12
  }): import("react/jsx-runtime").JSX.Element;
13
13
  //#endregion
14
14
  export { TranslationProvider as t };
15
- //# sourceMappingURL=translation-provider-DPFkLbrw.d.ts.map
15
+ //# sourceMappingURL=translation-provider-WOaZXqAz.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"translation-provider-DPFkLbrw.d.ts","names":[],"sources":["../src/providers/translation-provider.tsx"],"mappings":";;;iBAQgB,mBAAA;EAAsB,IAAA;EAAM,oBAAA;EAAsB;AAAA;EAChE,IAAA,EAAM,UAAA,QAAkB,cAAA,CAAe,GAAA;EACvC,oBAAA,GAAuB,MAAA;EACvB,QAAA,EAAU,KAAA,CAAM,SAAA;AAAA,gCACjB,GAAA,CAAA,OAAA"}
1
+ {"version":3,"file":"translation-provider-WOaZXqAz.d.ts","names":[],"sources":["../src/providers/translation-provider.tsx"],"mappings":";;;iBAQgB,mBAAA;EAAsB,IAAA;EAAM,oBAAA;EAAsB;AAAA;EAChE,IAAA,EAAM,UAAA,QAAkB,cAAA,CAAe,GAAA;EACvC,oBAAA,GAAuB,MAAA;EACvB,QAAA,EAAU,KAAA,CAAM,SAAA;AAAA,gCACjB,GAAA,CAAA,OAAA"}
@@ -0,0 +1,125 @@
1
+ import { WorkflowDivergenceDiagnosticJson, WorkflowRunDetailsJson, WorkflowRunJson, WorkflowSummaryJson, WorkflowSyncResultJson, WorkflowVersionJson } from "@hexclave/shared/dist/interface/workflows";
2
+
3
+ //#region src/lib/hexclave-app/workflows.d.ts
4
+ type AdminWorkflowTrigger = {
5
+ type: "event";
6
+ eventType: string;
7
+ } | {
8
+ type: "schedule";
9
+ cron: string;
10
+ timezone: string;
11
+ };
12
+ type AdminWorkflow = {
13
+ id: string;
14
+ displayName: string;
15
+ latestVersion: number;
16
+ triggers: AdminWorkflowTrigger[];
17
+ stats: {
18
+ activeRuns: number;
19
+ sleepingRuns: number;
20
+ failed7d: number;
21
+ runVolume14d: number[];
22
+ };
23
+ createdAtMillis: number;
24
+ lastDeployedAtMillis: number;
25
+ };
26
+ type AdminWorkflowRunState = "queued" | "running" | "sleeping" | "completed" | "failed" | "canceled";
27
+ type AdminWorkflowDivergenceDiagnostic = {
28
+ reason: WorkflowDivergenceDiagnosticJson["reason"];
29
+ suspendedStepKey: string | null;
30
+ foundStepKey: string | null;
31
+ consumedStepKeys: string[];
32
+ unconsumedStepKeys: string[];
33
+ details: string;
34
+ };
35
+ type AdminWorkflowRun = {
36
+ id: string;
37
+ workflowId: string;
38
+ runKey: string | null;
39
+ state: AdminWorkflowRunState;
40
+ version: number;
41
+ triggerType: string;
42
+ triggerSummary: string;
43
+ currentStepId: string | null;
44
+ stepsRecorded: number;
45
+ errorSummary: string | null;
46
+ failureKind: "user" | "platform" | null;
47
+ lastUpgradeDivergence: AdminWorkflowDivergenceDiagnostic | null;
48
+ createdAtMillis: number;
49
+ completedAtMillis: number | null;
50
+ nextWakeAtMillis: number | null;
51
+ };
52
+ type AdminWorkflowStep = {
53
+ stepKey: string;
54
+ stepId: string;
55
+ kind: "run" | "sleep";
56
+ result: unknown;
57
+ resultSizeBytes: number;
58
+ attempts: number;
59
+ executedAtVersion: number;
60
+ elapsedMs: number | null;
61
+ createdAtMillis: number;
62
+ };
63
+ type AdminWorkflowStepAttempt = {
64
+ stepKey: string;
65
+ stepId: string; /** 0 for the original execution; incremented by each manual retry of the run. */
66
+ retryEpoch: number;
67
+ attempt: number;
68
+ outcome: "succeeded" | "failed";
69
+ error: {
70
+ name: string;
71
+ message: string;
72
+ stack?: string;
73
+ } | null;
74
+ failureKind: "user" | "platform" | null;
75
+ logs: string | null;
76
+ startedAtMillis: number;
77
+ finishedAtMillis: number;
78
+ };
79
+ type AdminWorkflowRunDetails = AdminWorkflowRun & {
80
+ triggerPayload: unknown;
81
+ steps: AdminWorkflowStep[];
82
+ stepAttempts: AdminWorkflowStepAttempt[];
83
+ };
84
+ type AdminWorkflowVersion = {
85
+ workflowId: string;
86
+ version: number;
87
+ sourceHash: string;
88
+ source: string;
89
+ runtimeEnvVersion: string;
90
+ isLatest: boolean;
91
+ inFlightRuns: number;
92
+ createdAtMillis: number;
93
+ };
94
+ type AdminWorkflowSyncResult = {
95
+ workflowId: string;
96
+ version: number;
97
+ created: boolean;
98
+ inFlightRunsOnOlderVersions: number;
99
+ };
100
+ type AdminWorkflowUpgradeResult = {
101
+ upgradedCount: number;
102
+ skipped: {
103
+ runId: string;
104
+ runKey: string | null;
105
+ fromVersion: number;
106
+ diagnostic: AdminWorkflowDivergenceDiagnostic;
107
+ }[];
108
+ };
109
+ type AdminWorkflowRunsFilter = {
110
+ state?: AdminWorkflowRunState;
111
+ version?: number;
112
+ runKey?: string;
113
+ cursor?: string;
114
+ limit?: number; /** Include each run's memoized steps and attempt history. */
115
+ includeState?: boolean;
116
+ };
117
+ declare function adminWorkflowFromCrud(crud: WorkflowSummaryJson): AdminWorkflow;
118
+ declare function adminWorkflowRunFromCrud(crud: WorkflowRunJson): AdminWorkflowRun;
119
+ declare function isWorkflowRunDetailsJson(crud: WorkflowRunJson): crud is WorkflowRunDetailsJson;
120
+ declare function adminWorkflowRunDetailsFromCrud(crud: WorkflowRunDetailsJson): AdminWorkflowRunDetails;
121
+ declare function adminWorkflowVersionFromCrud(crud: WorkflowVersionJson): AdminWorkflowVersion;
122
+ declare function adminWorkflowSyncResultFromCrud(crud: WorkflowSyncResultJson): AdminWorkflowSyncResult;
123
+ //#endregion
124
+ export { adminWorkflowVersionFromCrud as _, AdminWorkflowRunState as a, AdminWorkflowStepAttempt as c, AdminWorkflowUpgradeResult as d, AdminWorkflowVersion as f, adminWorkflowSyncResultFromCrud as g, adminWorkflowRunFromCrud as h, AdminWorkflowRunDetails as i, AdminWorkflowSyncResult as l, adminWorkflowRunDetailsFromCrud as m, AdminWorkflowDivergenceDiagnostic as n, AdminWorkflowRunsFilter as o, adminWorkflowFromCrud as p, AdminWorkflowRun as r, AdminWorkflowStep as s, AdminWorkflow as t, AdminWorkflowTrigger as u, isWorkflowRunDetailsJson as v };
125
+ //# sourceMappingURL=workflows-DEb7pIuQ.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workflows-DEb7pIuQ.d.ts","names":[],"sources":["../src/lib/hexclave-app/workflows.ts"],"mappings":";;;KAiBY,oBAAA;EACN,IAAA;EAAe,SAAA;AAAA;EACf,IAAA;EAAkB,IAAA;EAAc,QAAA;AAAA;AAAA,KAE1B,aAAA;EACV,EAAA;EACA,WAAA;EACA,aAAA;EACA,QAAA,EAAU,oBAAoB;EAC9B,KAAA;IACE,UAAA;IACA,YAAA;IACA,QAAA;IACA,YAAA;EAAA;EAEF,eAAA;EACA,oBAAA;AAAA;AAAA,KAGU,qBAAA;AAAA,KAEA,iCAAA;EACV,MAAA,EAAQ,gCAAgC;EACxC,gBAAA;EACA,YAAA;EACA,gBAAA;EACA,kBAAA;EACA,OAAA;AAAA;AAAA,KAGU,gBAAA;EACV,EAAA;EACA,UAAA;EACA,MAAA;EACA,KAAA,EAAO,qBAAA;EACP,OAAA;EACA,WAAA;EACA,cAAA;EACA,aAAA;EACA,aAAA;EACA,YAAA;EACA,WAAA;EACA,qBAAA,EAAuB,iCAAiC;EACxD,eAAA;EACA,iBAAA;EACA,gBAAA;AAAA;AAAA,KAGU,iBAAA;EACV,OAAA;EACA,MAAA;EACA,IAAA;EACA,MAAA;EACA,eAAA;EACA,QAAA;EACA,iBAAA;EACA,SAAA;EACA,eAAA;AAAA;AAAA,KAGU,wBAAA;EACV,OAAA;EACA,MAAA,UAvBA;EAyBA,UAAA;EACA,OAAA;EACA,OAAA;EACA,KAAA;IAAS,IAAA;IAAc,OAAA;IAAiB,KAAA;EAAA;EACxC,WAAA;EACA,IAAA;EACA,eAAA;EACA,gBAAA;AAAA;AAAA,KAGU,uBAAA,GAA0B,gBAAA;EACpC,cAAA;EACA,KAAA,EAAO,iBAAA;EACP,YAAA,EAAc,wBAAA;AAAA;AAAA,KAGJ,oBAAA;EACV,UAAA;EACA,OAAA;EACA,UAAA;EACA,MAAA;EACA,iBAAA;EACA,QAAA;EACA,YAAA;EACA,eAAA;AAAA;AAAA,KAGU,uBAAA;EACV,UAAA;EACA,OAAA;EACA,OAAA;EACA,2BAAA;AAAA;AAAA,KAGU,0BAAA;EACV,aAAA;EACA,OAAA;IACE,KAAA;IACA,MAAA;IACA,WAAA;IACA,UAAA,EAAY,iCAAiC;EAAA;AAAA;AAAA,KAIrC,uBAAA;EACV,KAAA,GAAQ,qBAAqB;EAC7B,OAAA;EACA,MAAA;EACA,MAAA;EACA,KAAA,WApCsC;EAsCtC,YAAA;AAAA;AAAA,iBAGc,qBAAA,CAAsB,IAAA,EAAM,mBAAA,GAAsB,aAAa;AAAA,iBA+B/D,wBAAA,CAAyB,IAAA,EAAM,eAAA,GAAkB,gBAAgB;AAAA,iBAoBjE,wBAAA,CAAyB,IAAA,EAAM,eAAA,GAAkB,IAAA,IAAQ,sBAAsB;AAAA,iBAQ/E,+BAAA,CAAgC,IAAA,EAAM,sBAAA,GAAyB,uBAAuB;AAAA,iBA8BtF,4BAAA,CAA6B,IAAA,EAAM,mBAAA,GAAsB,oBAAoB;AAAA,iBAa7E,+BAAA,CAAgC,IAAA,EAAM,sBAAA,GAAyB,uBAAuB"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "//": "THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY UNLESS YOU ALSO EDIT THE CORRESPONDING FILE IN packages/template (FOR package.json FILES, PLEASE EDIT package-template.json)",
3
3
  "name": "@hexclave/next",
4
- "version": "1.0.70",
4
+ "version": "1.0.72",
5
5
  "repository": "https://github.com/hexclave/hexclave",
6
6
  "sideEffects": false,
7
7
  "main": "./dist/index.js",
@@ -74,9 +74,9 @@
74
74
  "tailwindcss-animate": "^1.0.7",
75
75
  "rrweb": "^1.1.3",
76
76
  "yup": "^1.7.1",
77
- "@hexclave/sc": "1.0.70",
78
- "@hexclave/shared": "1.0.70",
79
- "@hexclave/ui": "1.0.70"
77
+ "@hexclave/sc": "1.0.72",
78
+ "@hexclave/shared": "1.0.72",
79
+ "@hexclave/ui": "1.0.72"
80
80
  },
81
81
  "peerDependencies": {
82
82
  "@types/react": ">=18.0.0",
@@ -26,6 +26,7 @@ import { AdminProjectPermission, AdminProjectPermissionDefinition, AdminProjectP
26
26
  import type { PlanUsage } from "../../plan-usage";
27
27
  import { AdminOwnedProject, AdminProject, AdminProjectUpdateOptions, PushConfigOptions, adminProjectUpdateOptionsToCrud } from "../../projects";
28
28
  import type { AdminSessionReplay, AdminSessionReplayChunk, ListSessionReplayChunksOptions, ListSessionReplayChunksResult, ListSessionReplaysOptions, ListSessionReplaysResult, SessionReplayAllEventsResult } from "../../session-replays";
29
+ import { AdminWorkflow, AdminWorkflowRun, AdminWorkflowRunDetails, AdminWorkflowRunsFilter, AdminWorkflowSyncResult, AdminWorkflowUpgradeResult, AdminWorkflowVersion, adminWorkflowFromCrud, adminWorkflowRunDetailsFromCrud, adminWorkflowRunFromCrud, adminWorkflowSyncResultFromCrud, adminWorkflowVersionFromCrud, isWorkflowRunDetailsJson } from "../../workflows";
29
30
  import { ManagedEmailProviderListItem, ManagedEmailProviderSetupResult, ManagedEmailProviderStatus, EmailOutboxUpdateOptions, StackAdminApp, StackAdminAppConstructorOptions } from "../interfaces/admin-app";
30
31
  import { clientVersion, createCache, getDefaultExtraRequestHeaders, getDefaultProjectId, getDefaultPublishableClientKey, getDefaultSecretServerKey, getDefaultSuperSecretAdminKey, resolveApiUrls, resolveConstructorOptions } from "./common";
31
32
  import { _HexclaveServerAppImplIncomplete } from "./server-app-impl";
@@ -99,6 +100,9 @@ export class _HexclaveAdminAppImplIncomplete<HasTokenStore extends boolean, Proj
99
100
  private readonly _adminEmailDraftsCache = createCache(async () => {
100
101
  return await this._interface.listInternalEmailDrafts();
101
102
  });
103
+ private readonly _adminWorkflowsCache = createCache(async () => {
104
+ return await this._interface.listWorkflows();
105
+ });
102
106
  private readonly _adminTeamPermissionDefinitionsCache = createCache(async () => {
103
107
  return await this._interface.listTeamPermissionDefinitions();
104
108
  });
@@ -517,6 +521,10 @@ export class _HexclaveAdminAppImplIncomplete<HasTokenStore extends boolean, Proj
517
521
  }));
518
522
  }, [crud]);
519
523
  }
524
+ useWorkflows(): AdminWorkflow[] {
525
+ const crud = useAsyncCache(this._adminWorkflowsCache, [], "adminApp.useWorkflows()");
526
+ return useMemo(() => crud.map(adminWorkflowFromCrud), [crud]);
527
+ }
520
528
  async listEmailThemes(): Promise<{ id: string, displayName: string }[]> {
521
529
  const crud = Result.orThrow(await this._adminEmailThemesCache.getOrWait([], "write-only"));
522
530
  return crud.map((theme) => ({
@@ -535,6 +543,121 @@ export class _HexclaveAdminAppImplIncomplete<HasTokenStore extends boolean, Proj
535
543
  }));
536
544
  }
537
545
 
546
+ // ─── Workflows (internal-project gated; see the Workflows v1 spec) ───────
547
+
548
+ async listWorkflows(): Promise<AdminWorkflow[]> {
549
+ const crud = Result.orThrow(await this._adminWorkflowsCache.getOrWait([], "write-only"));
550
+ return crud.map(adminWorkflowFromCrud);
551
+ }
552
+
553
+ async createWorkflow(options: { id: string, displayName?: string, source: string }): Promise<AdminWorkflowSyncResult> {
554
+ const result = await this._interface.createWorkflow({
555
+ id: options.id,
556
+ display_name: options.displayName,
557
+ source: options.source,
558
+ });
559
+ await this._adminWorkflowsCache.refresh([]);
560
+ return adminWorkflowSyncResultFromCrud(result);
561
+ }
562
+
563
+ async updateWorkflowSource(workflowId: string, source: string): Promise<AdminWorkflowSyncResult> {
564
+ const result = await this._interface.updateWorkflowSource(workflowId, source);
565
+ await this._adminWorkflowsCache.refresh([]);
566
+ return adminWorkflowSyncResultFromCrud(result);
567
+ }
568
+
569
+ async deleteWorkflow(workflowId: string): Promise<void> {
570
+ await this._interface.deleteWorkflow(workflowId);
571
+ await this._adminWorkflowsCache.refresh([]);
572
+ }
573
+
574
+ async listWorkflowVersions(workflowId: string): Promise<AdminWorkflowVersion[]> {
575
+ return (await this._interface.listWorkflowVersions(workflowId)).map(adminWorkflowVersionFromCrud);
576
+ }
577
+
578
+ async listWorkflowRuns(workflowId: string, filter: AdminWorkflowRunsFilter & { includeState: true }): Promise<{ runs: AdminWorkflowRunDetails[], nextCursor: string | null }>;
579
+ async listWorkflowRuns(workflowId: string, filter?: AdminWorkflowRunsFilter): Promise<{ runs: AdminWorkflowRun[], nextCursor: string | null }>;
580
+ async listWorkflowRuns(workflowId: string, filter: AdminWorkflowRunsFilter = {}): Promise<{ runs: AdminWorkflowRun[], nextCursor: string | null }> {
581
+ if (filter.includeState === true) {
582
+ const result = await this._interface.listWorkflowRuns(workflowId, {
583
+ state: filter.state,
584
+ version: filter.version,
585
+ run_key: filter.runKey,
586
+ cursor: filter.cursor,
587
+ limit: filter.limit,
588
+ include_state: true,
589
+ });
590
+ return {
591
+ runs: result.runs.map((run) => adminWorkflowRunDetailsFromCrud(
592
+ isWorkflowRunDetailsJson(run)
593
+ ? run
594
+ : throwErr("Workflow runs response omitted state after include_state=true"),
595
+ )),
596
+ nextCursor: result.next_cursor,
597
+ };
598
+ }
599
+ const result = await this._interface.listWorkflowRuns(workflowId, {
600
+ state: filter.state,
601
+ version: filter.version,
602
+ run_key: filter.runKey,
603
+ cursor: filter.cursor,
604
+ limit: filter.limit,
605
+ });
606
+ return {
607
+ runs: result.runs.map(adminWorkflowRunFromCrud),
608
+ nextCursor: result.next_cursor,
609
+ };
610
+ }
611
+
612
+ async getWorkflowRun(runId: string): Promise<AdminWorkflowRunDetails> {
613
+ return adminWorkflowRunDetailsFromCrud(await this._interface.getWorkflowRun(runId));
614
+ }
615
+
616
+ async cancelWorkflowRuns(workflowId: string, filter: { runKey?: string, runId?: string, state?: "queued" | "running" | "sleeping", version?: number } = {}): Promise<{ canceledCount: number }> {
617
+ const result = await this._interface.cancelWorkflowRuns(workflowId, {
618
+ run_key: filter.runKey,
619
+ run_id: filter.runId,
620
+ state: filter.state,
621
+ version: filter.version,
622
+ });
623
+ await this._adminWorkflowsCache.refresh([]);
624
+ return { canceledCount: result.canceled_count };
625
+ }
626
+
627
+ async upgradeWorkflowRuns(workflowId: string, options: { toVersion: number, runKey?: string, fromVersion?: number }): Promise<AdminWorkflowUpgradeResult> {
628
+ const result = await this._interface.upgradeWorkflowRuns(workflowId, {
629
+ to_version: options.toVersion,
630
+ run_key: options.runKey,
631
+ from_version: options.fromVersion,
632
+ });
633
+ return {
634
+ upgradedCount: result.upgraded_count,
635
+ skipped: result.skipped.map((skip) => ({
636
+ runId: skip.run_id,
637
+ runKey: skip.run_key,
638
+ fromVersion: skip.from_version,
639
+ diagnostic: {
640
+ reason: skip.diagnostic.reason,
641
+ suspendedStepKey: skip.diagnostic.suspended_step_key,
642
+ foundStepKey: skip.diagnostic.found_step_key,
643
+ consumedStepKeys: skip.diagnostic.consumed_step_keys,
644
+ unconsumedStepKeys: skip.diagnostic.unconsumed_step_keys,
645
+ details: skip.diagnostic.details,
646
+ },
647
+ })),
648
+ };
649
+ }
650
+
651
+ async retryWorkflowRun(runId: string): Promise<void> {
652
+ await this._interface.retryWorkflowRun(runId);
653
+ await this._adminWorkflowsCache.refresh([]);
654
+ }
655
+
656
+ async sendWorkflowEvent(name: string, data?: unknown): Promise<{ eventId: string }> {
657
+ const result = await this._interface.sendWorkflowEvent(name, data ?? null);
658
+ return { eventId: result.event_id };
659
+ }
660
+
538
661
  async listEmailDrafts(): Promise<{ id: string, displayName: string, themeId: string | undefined | false, tsxSource: string, sentAt: Date | null }[]> {
539
662
  const crud = Result.orThrow(await this._adminEmailDraftsCache.getOrWait([], "write-only"));
540
663
  return crud.map((draft) => ({
@@ -535,7 +535,7 @@ describe("StackClientApp cross-domain auth", () => {
535
535
  }
536
536
 
537
537
  const errorUrl = new URL(redirectedUrl);
538
- expect(errorUrl.origin).toBe(`https://${projectId}.built-with-stack-auth.com`);
538
+ expect(errorUrl.origin).toBe(`https://${projectId}.built-with-hexclave.com`);
539
539
  expect(errorUrl.pathname).toBe("/handler/error");
540
540
  expect(errorUrl.searchParams.get("errorCode")).toBe("SIGN_UP_REJECTED");
541
541
  expect(errorUrl.searchParams.get("message")).toBe("Your sign up was rejected by an administrator's sign-up rule.");
@@ -715,7 +715,7 @@ describe("StackClientApp cross-domain auth", () => {
715
715
  redirectBackUrl.searchParams.set("hexclave_cross_domain_code_challenge", handoffCodeChallenge);
716
716
  redirectBackUrl.searchParams.set("hexclave_cross_domain_after_callback_redirect_url", handoffAfterCallbackRedirect);
717
717
 
718
- const arrivalUrl = new URL(`https://${projectId}.built-with-stack-auth.com/handler/sign-in`);
718
+ const arrivalUrl = new URL(`https://${projectId}.built-with-hexclave.com/handler/sign-in`);
719
719
  arrivalUrl.searchParams.set("after_auth_return_to", redirectBackUrl.toString());
720
720
  arrivalUrl.searchParams.set("hexclave_cross_domain_state", handoffState);
721
721
  arrivalUrl.searchParams.set("hexclave_cross_domain_code_challenge", handoffCodeChallenge);
@@ -754,7 +754,7 @@ describe("StackClientApp cross-domain auth", () => {
754
754
  .mockResolvedValue(crossDomainAuthorizeRedirect);
755
755
 
756
756
  // All redirect-back query params were dropped before the after-sign-in redirect.
757
- windowMock.location.href = `https://${projectId}.built-with-stack-auth.com/handler/sign-in`;
757
+ windowMock.location.href = `https://${projectId}.built-with-hexclave.com/handler/sign-in`;
758
758
 
759
759
  const redirectUrl = await clientApp[hexclaveAppInternalsSymbol].getRedirectToHandlerUrl("afterSignIn");
760
760
 
@@ -61,6 +61,7 @@ import { EditableTeamMemberProfile, ReceivedTeamInvitation, SentTeamInvitation,
61
61
  import { buildCliAuthConfirmUrl, getHostedHandlerUrl, isHostedHandlerUrlForProject, resolveHandlerUrls } from "../../url-targets";
62
62
  import { augmentUrlWithPersistedRedirectBackState, saveRedirectBackStateFromUrl } from "./redirect-back-state";
63
63
  import { recordRedirectAndThrowIfLoopDetected } from "./redirect-loop-breaker";
64
+ import { scopePasskeyAuthenticationToHostname, scopePasskeyRegistrationToHostname } from "../../passkey-rp-id";
64
65
  import { ActiveSession, Auth, BaseUser, CurrentUser, InternalUserExtra, OAuthProvider, ProjectCurrentUser, SyncedPartialUser, TokenPartialUser, UserExtra, UserUpdateOptions, userUpdateOptionsToCrud, withUserDestructureGuard } from "../../users";
65
66
  import { StackClientApp, StackClientAppConstructorOptions, StackClientAppJson } from "../interfaces/client-app";
66
67
  import { _HexclaveAdminAppImplIncomplete } from "./admin-app-impl";
@@ -2446,12 +2447,11 @@ export class _HexclaveClientAppImplIncomplete<HasTokenStore extends boolean, Pro
2446
2447
 
2447
2448
  const { options_json, code } = initiationResult.data;
2448
2449
 
2449
- // HACK: Override the rpID to be the actual domain
2450
- if (options_json.rp.id !== "THIS_VALUE_WILL_BE_REPLACED.example.com") {
2451
- throw new HexclaveAssertionError(`Expected returned RP ID from server to equal sentinel, but found ${options_json.rp.id}`);
2452
- }
2453
-
2454
- options_json.rp.id = hostname;
2450
+ // Passkeys intentionally stay scoped to the hostname where they were
2451
+ // registered. In particular, passkeys created on the legacy hosted
2452
+ // components domain continue to work there but are not carried over to
2453
+ // a replacement hosted domain.
2454
+ scopePasskeyRegistrationToHostname(options_json, hostname);
2455
2455
 
2456
2456
  let attResp;
2457
2457
  try {
@@ -3771,11 +3771,10 @@ export class _HexclaveClientAppImplIncomplete<HasTokenStore extends boolean, Pro
3771
3771
 
3772
3772
  const { options_json, code } = initiationResult.data;
3773
3773
 
3774
- // HACK: Override the rpID to be the actual domain
3775
- if (options_json.rpId !== "THIS_VALUE_WILL_BE_REPLACED.example.com") {
3776
- throw new HexclaveAssertionError(`Expected returned RP ID from server to equal sentinel, but found ${options_json.rpId}`);
3777
- }
3778
- options_json.rpId = window.location.hostname;
3774
+ // Keep authentication scoped to the current hostname. This deliberately
3775
+ // does not add cross-domain compatibility for passkeys created on a
3776
+ // previous hosted components domain.
3777
+ scopePasskeyAuthenticationToHostname(options_json, window.location.hostname);
3779
3778
 
3780
3779
  const authentication_response = await startAuthentication({ optionsJSON: options_json });
3781
3780
  return await this._interface.signInWithPasskey({ authentication_response, code }, session);
@@ -36,6 +36,7 @@ import { Customer, CustomerProductsList, CustomerProductsRequestOptions, InlineP
36
36
  import { DataVaultStore } from "../../data-vault";
37
37
  import { EmailDeliveryInfo, SendEmailOptions } from "../../email";
38
38
  import { NotificationCategory } from "../../notification-categories";
39
+ import { scopePasskeyRegistrationToHostname } from "../../passkey-rp-id";
39
40
  import { AdminProjectPermissionDefinition, AdminTeamPermission, AdminTeamPermissionDefinition } from "../../permissions";
40
41
  import { EditableTeamMemberProfile, ReceivedTeamInvitation, SentTeamInvitation, ServerListTeamsOptions, ServerListUsersOptions, ServerTeam, ServerTeamCreateOptions, ServerTeamUpdateOptions, ServerTeamUser, Team, serverTeamCreateOptionsToCrud, serverTeamUpdateOptionsToCrud } from "../../teams";
41
42
  import { ProjectCurrentServerUser, ServerOAuthProvider, ServerUser, ServerUserCreateOptions, ServerUserUpdateOptions, serverUserCreateOptionsToCrud, serverUserUpdateOptionsToCrud, withUserDestructureGuard } from "../../users";
@@ -896,7 +897,6 @@ export class _HexclaveServerAppImplIncomplete<HasTokenStore extends boolean, Pro
896
897
  return providers.find((p) => p.id === id) ?? null;
897
898
  },
898
899
  async registerPasskey(options?: { hostname?: string }): Promise<Result<undefined, KnownErrors["PasskeyRegistrationFailed"] | KnownErrors["PasskeyWebAuthnError"]>> {
899
- // TODO remove duplicated code between this and the function in client-app-impl.ts
900
900
  const hostname = options?.hostname || (await app._getCurrentUrl())?.hostname;
901
901
  if (!hostname) {
902
902
  throw new HexclaveAssertionError("hostname must be provided if the Stack App does not have a redirect method");
@@ -911,12 +911,7 @@ export class _HexclaveServerAppImplIncomplete<HasTokenStore extends boolean, Pro
911
911
 
912
912
  const { options_json, code } = initiationResult.data;
913
913
 
914
- // HACK: Override the rpID to be the actual domain
915
- if (options_json.rp.id !== "THIS_VALUE_WILL_BE_REPLACED.example.com") {
916
- throw new HexclaveAssertionError(`Expected returned RP ID from server to equal sentinel, but found ${options_json.rp.id}`);
917
- }
918
-
919
- options_json.rp.id = hostname;
914
+ scopePasskeyRegistrationToHostname(options_json, hostname);
920
915
 
921
916
  let attResp;
922
917
  try {
@@ -14,6 +14,7 @@ import { InternalApiKey, InternalApiKeyCreateOptions, InternalApiKeyFirstView }
14
14
  import { AdminProjectPermission, AdminProjectPermissionDefinition, AdminProjectPermissionDefinitionCreateOptions, AdminProjectPermissionDefinitionUpdateOptions, AdminTeamPermission, AdminTeamPermissionDefinition, AdminTeamPermissionDefinitionCreateOptions, AdminTeamPermissionDefinitionUpdateOptions } from "../../permissions";
15
15
  import type { PlanUsage } from "../../plan-usage";
16
16
  import { AdminProject } from "../../projects";
17
+ import type { AdminWorkflow, AdminWorkflowRun, AdminWorkflowRunDetails, AdminWorkflowRunsFilter, AdminWorkflowSyncResult, AdminWorkflowUpgradeResult, AdminWorkflowVersion } from "../../workflows";
17
18
  import { _HexclaveAdminAppImpl } from "../implementations";
18
19
  import { StackServerApp, StackServerAppConstructorOptions } from "./server-app";
19
20
 
@@ -60,6 +61,7 @@ export type ManagedEmailProviderListItem = {
60
61
 
61
62
  import type { AdminSessionReplay, ListSessionReplayChunksOptions, ListSessionReplayChunksResult, ListSessionReplaysOptions, ListSessionReplaysResult, SessionReplayAllEventsResult } from "../../session-replays";
62
63
  export type { AdminSessionReplay, AdminSessionReplayChunk, ListSessionReplaysOptions, ListSessionReplaysResult, ListSessionReplayChunksOptions, ListSessionReplayChunksResult, SessionReplayAllEventsResult } from "../../session-replays";
64
+ export type { AdminWorkflow, AdminWorkflowDivergenceDiagnostic, AdminWorkflowRun, AdminWorkflowRunDetails, AdminWorkflowRunsFilter, AdminWorkflowRunState, AdminWorkflowStep, AdminWorkflowStepAttempt, AdminWorkflowSyncResult, AdminWorkflowTrigger, AdminWorkflowUpgradeResult, AdminWorkflowVersion } from "../../workflows";
63
65
 
64
66
 
65
67
  /** @deprecated Use `HexclaveAdminAppConstructorOptions` from the `@hexclave/*` package instead — same symbol, new brand name. See https://docs.hexclave.com/migration. */
@@ -84,6 +86,7 @@ export type StackAdminApp<HasTokenStore extends boolean = boolean, ProjectId ext
84
86
  & AsyncStoreProperty<"emailPreviewWithEditableMarkers", [{ themeId?: string | null | false, themeTsxSource?: string, templateId?: string, templateTsxSource?: string, editableSource?: 'template' | 'theme' | 'both' }], { html: string, editableRegions?: Record<string, unknown> }, false> // THIS_LINE_PLATFORM react-like
85
87
  & AsyncStoreProperty<"emailTemplates", [], { id: string, displayName: string, themeId?: string, tsxSource: string }[], true>
86
88
  & AsyncStoreProperty<"emailDrafts", [], { id: string, displayName: string, themeId: string | undefined | false, tsxSource: string, sentAt: Date | null }[], true>
89
+ & AsyncStoreProperty<"workflows", [], AdminWorkflow[], true>
87
90
  & AsyncStoreProperty<"stripeAccountInfo", [], { account_id: string, charges_enabled: boolean, details_submitted: boolean, payouts_enabled: boolean } | null, false>
88
91
  & AsyncStoreProperty<
89
92
  "transactions",
@@ -141,6 +144,22 @@ export type StackAdminApp<HasTokenStore extends boolean = boolean, ProjectId ext
141
144
  createEmailTemplate(displayName: string): Promise<{ id: string }>,
142
145
  deleteEmailTemplate(id: string): Promise<void>,
143
146
 
147
+ // Workflows (internal-project gated; see the Workflows v1 spec). The
148
+ // management verbs live on the admin app only in v1.
149
+ createWorkflow(options: { id: string, displayName?: string, source: string }): Promise<AdminWorkflowSyncResult>,
150
+ updateWorkflowSource(workflowId: string, source: string): Promise<AdminWorkflowSyncResult>,
151
+ deleteWorkflow(workflowId: string): Promise<void>,
152
+ listWorkflowVersions(workflowId: string): Promise<AdminWorkflowVersion[]>,
153
+ listWorkflowRuns: {
154
+ (workflowId: string, filter: AdminWorkflowRunsFilter & { includeState: true }): Promise<{ runs: AdminWorkflowRunDetails[], nextCursor: string | null }>,
155
+ (workflowId: string, filter?: AdminWorkflowRunsFilter): Promise<{ runs: AdminWorkflowRun[], nextCursor: string | null }>,
156
+ },
157
+ getWorkflowRun(runId: string): Promise<AdminWorkflowRunDetails>,
158
+ cancelWorkflowRuns(workflowId: string, filter?: { runKey?: string, runId?: string, state?: "queued" | "running" | "sleeping", version?: number }): Promise<{ canceledCount: number }>,
159
+ upgradeWorkflowRuns(workflowId: string, options: { toVersion: number, runKey?: string, fromVersion?: number }): Promise<AdminWorkflowUpgradeResult>,
160
+ retryWorkflowRun(runId: string): Promise<void>,
161
+ sendWorkflowEvent(name: string, data?: unknown): Promise<{ eventId: string }>,
162
+
144
163
  setupPayments(): Promise<{ url: string }>,
145
164
  createStripeWidgetAccountSession(): Promise<{ client_secret: string }>,
146
165
  getPaymentMethodConfigs(): Promise<{ configId: string, methods: Array<{ id: string, name: string, enabled: boolean, available: boolean, overridable: boolean }> } | null>,
@@ -45,6 +45,21 @@ export type {
45
45
  EmailOutboxUpdateOptions
46
46
  } from "./apps/interfaces/admin-app";
47
47
 
48
+ export type {
49
+ AdminWorkflow,
50
+ AdminWorkflowDivergenceDiagnostic,
51
+ AdminWorkflowRun,
52
+ AdminWorkflowRunDetails,
53
+ AdminWorkflowRunsFilter,
54
+ AdminWorkflowRunState,
55
+ AdminWorkflowStep,
56
+ AdminWorkflowStepAttempt,
57
+ AdminWorkflowSyncResult,
58
+ AdminWorkflowTrigger,
59
+ AdminWorkflowUpgradeResult,
60
+ AdminWorkflowVersion
61
+ } from "./workflows";
62
+
48
63
  export type {
49
64
  ProjectConfig
50
65
  } from "./project-configs";
@@ -0,0 +1,43 @@
1
+
2
+ //===========================================
3
+ // THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY UNLESS YOU ALSO EDIT THE CORRESPONDING FILE IN packages/template
4
+ //===========================================
5
+ import { describe, expect, it } from "vitest";
6
+ import { scopePasskeyAuthenticationToHostname, scopePasskeyRegistrationToHostname } from "./passkey-rp-id";
7
+
8
+ const passkeyRpIdSentinel = "THIS_VALUE_WILL_BE_REPLACED.example.com";
9
+
10
+ describe.each([
11
+ "project-id.built-with-hexclave.com",
12
+ "project-id.built-with-stack-auth.com",
13
+ ])("passkeys on %s", (hostname) => {
14
+ it("scopes registration to the current hostname", () => {
15
+ const options = { rp: { id: passkeyRpIdSentinel } };
16
+
17
+ scopePasskeyRegistrationToHostname(options, hostname);
18
+
19
+ expect(options.rp.id).toBe(hostname);
20
+ });
21
+
22
+ it("scopes authentication to the current hostname", () => {
23
+ const options = { rpId: passkeyRpIdSentinel };
24
+
25
+ scopePasskeyAuthenticationToHostname(options, hostname);
26
+
27
+ expect(options.rpId).toBe(hostname);
28
+ });
29
+ });
30
+
31
+ it("rejects registration options without the server sentinel", () => {
32
+ expect(() => scopePasskeyRegistrationToHostname(
33
+ { rp: { id: "unexpected.example.com" } },
34
+ "project-id.built-with-hexclave.com",
35
+ )).toThrow("Expected returned RP ID from server to equal sentinel");
36
+ });
37
+
38
+ it("rejects authentication options without the server sentinel", () => {
39
+ expect(() => scopePasskeyAuthenticationToHostname(
40
+ { rpId: "unexpected.example.com" },
41
+ "project-id.built-with-hexclave.com",
42
+ )).toThrow("Expected returned RP ID from server to equal sentinel");
43
+ });
@@ -0,0 +1,27 @@
1
+
2
+ //===========================================
3
+ // THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY UNLESS YOU ALSO EDIT THE CORRESPONDING FILE IN packages/template
4
+ //===========================================
5
+ import { HexclaveAssertionError } from "@hexclave/shared/dist/utils/errors";
6
+
7
+ const passkeyRpIdSentinel = "THIS_VALUE_WILL_BE_REPLACED.example.com";
8
+
9
+ export function scopePasskeyRegistrationToHostname(
10
+ options: { rp: { id?: string } },
11
+ hostname: string,
12
+ ): void {
13
+ if (options.rp.id !== passkeyRpIdSentinel) {
14
+ throw new HexclaveAssertionError(`Expected returned RP ID from server to equal sentinel, but found ${options.rp.id}`);
15
+ }
16
+ options.rp.id = hostname;
17
+ }
18
+
19
+ export function scopePasskeyAuthenticationToHostname(
20
+ options: { rpId?: string },
21
+ hostname: string,
22
+ ): void {
23
+ if (options.rpId !== passkeyRpIdSentinel) {
24
+ throw new HexclaveAssertionError(`Expected returned RP ID from server to equal sentinel, but found ${options.rpId}`);
25
+ }
26
+ options.rpId = hostname;
27
+ }
@@ -0,0 +1,28 @@
1
+
2
+ //===========================================
3
+ // THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY UNLESS YOU ALSO EDIT THE CORRESPONDING FILE IN packages/template
4
+ //===========================================
5
+ import type { WorkflowVersionJson } from "@hexclave/shared/dist/interface/workflows";
6
+ import { describe, expect, it } from "vitest";
7
+ import { adminWorkflowVersionFromCrud } from "./workflows";
8
+
9
+ describe("adminWorkflowVersionFromCrud", () => {
10
+ it("preserves the deployment source hash", () => {
11
+ const version: WorkflowVersionJson = {
12
+ workflow_id: "daily-report",
13
+ version: 3,
14
+ source: "export default 1",
15
+ source_hash: "0123456789abcdef",
16
+ runtime_env_version: "v1",
17
+ is_latest: true,
18
+ in_flight_runs: 2,
19
+ created_at_millis: 1234,
20
+ };
21
+
22
+ expect(adminWorkflowVersionFromCrud(version)).toMatchObject({
23
+ workflowId: "daily-report",
24
+ version: 3,
25
+ sourceHash: "0123456789abcdef",
26
+ });
27
+ });
28
+ });