@hexclave/shared 1.0.3 → 1.0.6

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 (335) hide show
  1. package/dist/ai/unified-prompts/reminders.js +4 -3
  2. package/dist/ai/unified-prompts/reminders.js.map +1 -1
  3. package/dist/ai/unified-prompts/skill-site-prompt-parts/ai-setup-prompt.d.ts +3 -1
  4. package/dist/ai/unified-prompts/skill-site-prompt-parts/ai-setup-prompt.d.ts.map +1 -1
  5. package/dist/ai/unified-prompts/skill-site-prompt-parts/ai-setup-prompt.js +216 -29
  6. package/dist/ai/unified-prompts/skill-site-prompt-parts/ai-setup-prompt.js.map +1 -1
  7. package/dist/ai/unified-prompts/skill-site-prompt-parts/docs-index.d.ts.map +1 -1
  8. package/dist/ai/unified-prompts/skill-site-prompt-parts/docs-index.js +1 -0
  9. package/dist/ai/unified-prompts/skill-site-prompt-parts/docs-index.js.map +1 -1
  10. package/dist/ai/unified-prompts/skill-site-prompt-parts/docs-json.generated.d.ts +18 -6
  11. package/dist/ai/unified-prompts/skill-site-prompt-parts/docs-json.generated.js +23 -8
  12. package/dist/ai/unified-prompts/skill-site-prompt-parts/docs-json.generated.js.map +1 -1
  13. package/dist/ai/unified-prompts/skill-site-prompt-parts/openapi-specs.js +1 -1
  14. package/dist/ai/unified-prompts/skill-site-prompt-parts/openapi-specs.js.map +1 -1
  15. package/dist/config/schema.d.ts +1 -1
  16. package/dist/config/schema.d.ts.map +1 -1
  17. package/dist/config/schema.js +5 -5
  18. package/dist/config/schema.js.map +1 -1
  19. package/dist/config-authoring.d.ts +4 -4
  20. package/dist/config-authoring.d.ts.map +1 -1
  21. package/dist/config-authoring.js +2 -2
  22. package/dist/config-authoring.js.map +1 -1
  23. package/dist/config-rendering.d.ts +4 -4
  24. package/dist/config-rendering.d.ts.map +1 -1
  25. package/dist/config-rendering.js +19 -18
  26. package/dist/config-rendering.js.map +1 -1
  27. package/dist/esm/ai/unified-prompts/reminders.js +4 -3
  28. package/dist/esm/ai/unified-prompts/reminders.js.map +1 -1
  29. package/dist/esm/ai/unified-prompts/skill-site-prompt-parts/ai-setup-prompt.d.ts +3 -1
  30. package/dist/esm/ai/unified-prompts/skill-site-prompt-parts/ai-setup-prompt.d.ts.map +1 -1
  31. package/dist/esm/ai/unified-prompts/skill-site-prompt-parts/ai-setup-prompt.js +215 -30
  32. package/dist/esm/ai/unified-prompts/skill-site-prompt-parts/ai-setup-prompt.js.map +1 -1
  33. package/dist/esm/ai/unified-prompts/skill-site-prompt-parts/docs-index.d.ts.map +1 -1
  34. package/dist/esm/ai/unified-prompts/skill-site-prompt-parts/docs-index.js +1 -0
  35. package/dist/esm/ai/unified-prompts/skill-site-prompt-parts/docs-index.js.map +1 -1
  36. package/dist/esm/ai/unified-prompts/skill-site-prompt-parts/docs-json.generated.d.ts +18 -6
  37. package/dist/esm/ai/unified-prompts/skill-site-prompt-parts/docs-json.generated.js +23 -8
  38. package/dist/esm/ai/unified-prompts/skill-site-prompt-parts/docs-json.generated.js.map +1 -1
  39. package/dist/esm/ai/unified-prompts/skill-site-prompt-parts/openapi-specs.js +1 -1
  40. package/dist/esm/ai/unified-prompts/skill-site-prompt-parts/openapi-specs.js.map +1 -1
  41. package/dist/esm/config/schema.d.ts +1 -1
  42. package/dist/esm/config/schema.d.ts.map +1 -1
  43. package/dist/esm/config/schema.js +5 -5
  44. package/dist/esm/config/schema.js.map +1 -1
  45. package/dist/esm/config-authoring.d.ts +4 -4
  46. package/dist/esm/config-authoring.d.ts.map +1 -1
  47. package/dist/esm/config-authoring.js +2 -2
  48. package/dist/esm/config-authoring.js.map +1 -1
  49. package/dist/esm/config-rendering.d.ts +4 -4
  50. package/dist/esm/config-rendering.d.ts.map +1 -1
  51. package/dist/esm/config-rendering.js +15 -14
  52. package/dist/esm/config-rendering.js.map +1 -1
  53. package/dist/esm/helpers/vault/client-side.d.ts.map +1 -1
  54. package/dist/esm/helpers/vault/client-side.js.map +1 -1
  55. package/dist/esm/helpers/vault/server-side.d.ts.map +1 -1
  56. package/dist/esm/helpers/vault/server-side.js.map +1 -1
  57. package/dist/esm/hexclave-config-file.d.ts +15 -0
  58. package/dist/esm/hexclave-config-file.d.ts.map +1 -0
  59. package/dist/esm/{stack-config-file.js → hexclave-config-file.js} +7 -7
  60. package/dist/esm/hexclave-config-file.js.map +1 -0
  61. package/dist/esm/interface/admin-metrics.d.ts +2 -2
  62. package/dist/esm/interface/admin-metrics.js.map +1 -1
  63. package/dist/esm/interface/client-interface.js +2 -2
  64. package/dist/esm/interface/client-interface.js.map +1 -1
  65. package/dist/esm/interface/conversations.d.ts +32 -32
  66. package/dist/esm/interface/crud/current-user.d.ts +7 -7
  67. package/dist/esm/interface/crud/email-outbox.d.ts +42 -42
  68. package/dist/esm/interface/crud/project-permissions.js +5 -5
  69. package/dist/esm/interface/crud/project-permissions.js.map +1 -1
  70. package/dist/esm/interface/crud/team-member-profiles.d.ts +18 -18
  71. package/dist/esm/interface/crud/team-permissions.js +5 -5
  72. package/dist/esm/interface/crud/team-permissions.js.map +1 -1
  73. package/dist/esm/interface/crud/users.d.ts +10 -10
  74. package/dist/esm/interface/page-component-versions.js +107 -107
  75. package/dist/esm/interface/page-component-versions.js.map +1 -1
  76. package/dist/esm/interface/webhooks.d.ts +2 -2
  77. package/dist/esm/known-errors.d.ts +1 -1
  78. package/dist/esm/known-errors.d.ts.map +1 -1
  79. package/dist/esm/known-errors.js +9 -5
  80. package/dist/esm/known-errors.js.map +1 -1
  81. package/dist/esm/schema-fields.d.ts +15 -5
  82. package/dist/esm/schema-fields.d.ts.map +1 -1
  83. package/dist/esm/schema-fields.js +26 -16
  84. package/dist/esm/schema-fields.js.map +1 -1
  85. package/dist/esm/utils/crypto.d.ts.map +1 -1
  86. package/dist/esm/utils/crypto.js.map +1 -1
  87. package/dist/esm/utils/currency-constants.d.ts +6 -0
  88. package/dist/esm/utils/currency-constants.d.ts.map +1 -1
  89. package/dist/esm/utils/currency-constants.js.map +1 -1
  90. package/dist/esm/utils/dev-env-state-path.d.ts +3 -3
  91. package/dist/esm/utils/dev-env-state-path.d.ts.map +1 -1
  92. package/dist/esm/utils/dev-env-state-path.js +4 -4
  93. package/dist/esm/utils/dev-env-state-path.js.map +1 -1
  94. package/dist/esm/utils/errors.js +2 -2
  95. package/dist/esm/utils/errors.js.map +1 -1
  96. package/dist/esm/utils/esbuild.d.ts.map +1 -1
  97. package/dist/esm/utils/esbuild.js +0 -1
  98. package/dist/esm/utils/esbuild.js.map +1 -1
  99. package/dist/esm/utils/featurebase.d.ts +3 -3
  100. package/dist/esm/utils/featurebase.d.ts.map +1 -1
  101. package/dist/esm/utils/featurebase.js +15 -15
  102. package/dist/esm/utils/featurebase.js.map +1 -1
  103. package/dist/esm/utils/fs.js +6 -6
  104. package/dist/esm/utils/fs.js.map +1 -1
  105. package/dist/esm/utils/globals.d.ts.map +1 -1
  106. package/dist/esm/utils/globals.js +10 -10
  107. package/dist/esm/utils/globals.js.map +1 -1
  108. package/dist/esm/utils/jwt.d.ts.map +1 -1
  109. package/dist/esm/utils/jwt.js +3 -3
  110. package/dist/esm/utils/jwt.js.map +1 -1
  111. package/dist/esm/utils/redirect-urls.d.ts +3 -3
  112. package/dist/esm/utils/redirect-urls.d.ts.map +1 -1
  113. package/dist/esm/utils/redirect-urls.js +5 -5
  114. package/dist/esm/utils/redirect-urls.js.map +1 -1
  115. package/dist/esm/utils/urls.js.map +1 -1
  116. package/dist/helpers/vault/client-side.d.ts.map +1 -1
  117. package/dist/helpers/vault/client-side.js.map +1 -1
  118. package/dist/helpers/vault/server-side.d.ts.map +1 -1
  119. package/dist/helpers/vault/server-side.js.map +1 -1
  120. package/dist/hexclave-config-file.d.ts +15 -0
  121. package/dist/hexclave-config-file.d.ts.map +1 -0
  122. package/dist/{stack-config-file.js → hexclave-config-file.js} +8 -8
  123. package/dist/hexclave-config-file.js.map +1 -0
  124. package/dist/interface/admin-metrics.d.ts +12 -12
  125. package/dist/interface/admin-metrics.js.map +1 -1
  126. package/dist/interface/client-interface.js +2 -2
  127. package/dist/interface/client-interface.js.map +1 -1
  128. package/dist/interface/conversations.d.ts +32 -32
  129. package/dist/interface/crud/current-user.d.ts +7 -7
  130. package/dist/interface/crud/email-outbox.d.ts +42 -42
  131. package/dist/interface/crud/project-permissions.js +5 -5
  132. package/dist/interface/crud/project-permissions.js.map +1 -1
  133. package/dist/interface/crud/team-member-profiles.d.ts +18 -18
  134. package/dist/interface/crud/team-permissions.js +5 -5
  135. package/dist/interface/crud/team-permissions.js.map +1 -1
  136. package/dist/interface/crud/users.d.ts +10 -10
  137. package/dist/interface/page-component-versions.js +107 -107
  138. package/dist/interface/page-component-versions.js.map +1 -1
  139. package/dist/interface/webhooks.d.ts +2 -2
  140. package/dist/known-errors.d.ts +1 -1
  141. package/dist/known-errors.d.ts.map +1 -1
  142. package/dist/known-errors.js +9 -5
  143. package/dist/known-errors.js.map +1 -1
  144. package/dist/schema-fields.d.ts +15 -5
  145. package/dist/schema-fields.d.ts.map +1 -1
  146. package/dist/schema-fields.js +26 -16
  147. package/dist/schema-fields.js.map +1 -1
  148. package/dist/utils/crypto.d.ts.map +1 -1
  149. package/dist/utils/crypto.js.map +1 -1
  150. package/dist/utils/currency-constants.d.ts +6 -0
  151. package/dist/utils/currency-constants.d.ts.map +1 -1
  152. package/dist/utils/currency-constants.js.map +1 -1
  153. package/dist/utils/dev-env-state-path.d.ts +3 -3
  154. package/dist/utils/dev-env-state-path.d.ts.map +1 -1
  155. package/dist/utils/dev-env-state-path.js +5 -5
  156. package/dist/utils/dev-env-state-path.js.map +1 -1
  157. package/dist/utils/errors.js +2 -2
  158. package/dist/utils/errors.js.map +1 -1
  159. package/dist/utils/esbuild.d.ts.map +1 -1
  160. package/dist/utils/esbuild.js +0 -1
  161. package/dist/utils/esbuild.js.map +1 -1
  162. package/dist/utils/featurebase.d.ts +3 -3
  163. package/dist/utils/featurebase.d.ts.map +1 -1
  164. package/dist/utils/featurebase.js +15 -15
  165. package/dist/utils/featurebase.js.map +1 -1
  166. package/dist/utils/fs.js.map +1 -1
  167. package/dist/utils/globals.d.ts.map +1 -1
  168. package/dist/utils/globals.js +10 -10
  169. package/dist/utils/globals.js.map +1 -1
  170. package/dist/utils/jwt.d.ts.map +1 -1
  171. package/dist/utils/jwt.js +3 -3
  172. package/dist/utils/jwt.js.map +1 -1
  173. package/dist/utils/redirect-urls.d.ts +3 -3
  174. package/dist/utils/redirect-urls.d.ts.map +1 -1
  175. package/dist/utils/redirect-urls.js +5 -5
  176. package/dist/utils/redirect-urls.js.map +1 -1
  177. package/dist/utils/urls.js.map +1 -1
  178. package/package.json +2 -1
  179. package/src/ai/image-limits.ts +62 -0
  180. package/src/ai/llms/llms.ts +36 -0
  181. package/src/ai/unified-prompts/reminders.ts +27 -0
  182. package/src/ai/unified-prompts/skill-site-prompt-parts/ai-setup-prompt.ts +1047 -0
  183. package/src/ai/unified-prompts/skill-site-prompt-parts/brain.ts +5 -0
  184. package/src/ai/unified-prompts/skill-site-prompt-parts/cli-help.ts +5 -0
  185. package/src/ai/unified-prompts/skill-site-prompt-parts/config-docs.ts +5 -0
  186. package/src/ai/unified-prompts/skill-site-prompt-parts/custom-components-instructions.ts +5 -0
  187. package/src/ai/unified-prompts/skill-site-prompt-parts/dashboard-instructions.ts +5 -0
  188. package/src/ai/unified-prompts/skill-site-prompt-parts/docs-index.ts +80 -0
  189. package/src/ai/unified-prompts/skill-site-prompt-parts/docs-json.generated.ts +322 -0
  190. package/src/ai/unified-prompts/skill-site-prompt-parts/openapi-specs.ts +5 -0
  191. package/src/ai/unified-prompts/skill-site-prompt-parts/sdk-interface-source.ts +5 -0
  192. package/src/ai/unified-prompts/skill-site-prompt.ts +72 -0
  193. package/src/apps/apps-config.ts +177 -0
  194. package/src/apps/apps-ui.tsx +112 -0
  195. package/src/config/README.md +154 -0
  196. package/src/config/db-sync-mappings.ts +2293 -0
  197. package/src/config/format.ts +388 -0
  198. package/src/config/migrate-catalogs-to-product-lines.ts +475 -0
  199. package/src/config/schema-fuzzer.test.ts +377 -0
  200. package/src/config/schema.ts +1507 -0
  201. package/src/config-authoring.test.ts +52 -0
  202. package/src/config-authoring.ts +37 -0
  203. package/src/config-rendering.ts +142 -0
  204. package/src/crud.tsx +275 -0
  205. package/src/global.d.ts +1 -0
  206. package/src/helpers/emails.ts +250 -0
  207. package/src/helpers/init-prompt.ts +39 -0
  208. package/src/helpers/password.ts +16 -0
  209. package/src/helpers/production-mode.ts +58 -0
  210. package/src/helpers/support-sla.test.ts +124 -0
  211. package/src/helpers/support-sla.ts +93 -0
  212. package/src/helpers/vault/client-side.ts +92 -0
  213. package/src/helpers/vault/server-side.ts +153 -0
  214. package/src/hexclave-config-file.ts +120 -0
  215. package/src/hooks/use-async-callback.tsx +43 -0
  216. package/src/hooks/use-async-external-store.tsx +24 -0
  217. package/src/hooks/use-hash.tsx +14 -0
  218. package/src/hooks/use-hover.tsx +88 -0
  219. package/src/hooks/use-strict-memo.tsx +157 -0
  220. package/src/index.ts +17 -0
  221. package/src/interface/admin-interface.ts +1043 -0
  222. package/src/interface/admin-metrics.ts +214 -0
  223. package/src/interface/client-interface.test.ts +765 -0
  224. package/src/interface/client-interface.ts +2586 -0
  225. package/src/interface/conversations.ts +109 -0
  226. package/src/interface/crud/analytics.ts +11 -0
  227. package/src/interface/crud/connected-accounts.ts +52 -0
  228. package/src/interface/crud/contact-channels.ts +74 -0
  229. package/src/interface/crud/current-user.ts +72 -0
  230. package/src/interface/crud/email-outbox.ts +263 -0
  231. package/src/interface/crud/email-templates.ts +50 -0
  232. package/src/interface/crud/emails.ts +22 -0
  233. package/src/interface/crud/internal-api-keys.ts +69 -0
  234. package/src/interface/crud/invoices.ts +36 -0
  235. package/src/interface/crud/items.ts +24 -0
  236. package/src/interface/crud/notification-preferences.ts +33 -0
  237. package/src/interface/crud/oauth-providers.ts +91 -0
  238. package/src/interface/crud/products.ts +42 -0
  239. package/src/interface/crud/project-api-keys.ts +100 -0
  240. package/src/interface/crud/project-permissions.ts +118 -0
  241. package/src/interface/crud/projects.ts +229 -0
  242. package/src/interface/crud/session-replays.ts +85 -0
  243. package/src/interface/crud/sessions.ts +66 -0
  244. package/src/interface/crud/sign-up-rules.ts +12 -0
  245. package/src/interface/crud/svix-token.ts +20 -0
  246. package/src/interface/crud/team-invitation-details.ts +22 -0
  247. package/src/interface/crud/team-invitation.ts +35 -0
  248. package/src/interface/crud/team-member-profiles.ts +61 -0
  249. package/src/interface/crud/team-memberships.ts +56 -0
  250. package/src/interface/crud/team-permissions.ts +119 -0
  251. package/src/interface/crud/teams.ts +142 -0
  252. package/src/interface/crud/transactions.ts +131 -0
  253. package/src/interface/crud/users.ts +185 -0
  254. package/src/interface/handler-urls.ts +74 -0
  255. package/src/interface/page-component-versions.ts +1702 -0
  256. package/src/interface/server-interface.ts +1146 -0
  257. package/src/interface/webhooks.ts +28 -0
  258. package/src/known-errors.tsx +2034 -0
  259. package/src/local-emulator.ts +5 -0
  260. package/src/payments/payment-methods.ts +167 -0
  261. package/src/payments/stripe-limits.ts +18 -0
  262. package/src/plans.ts +107 -0
  263. package/src/schema-fields.ts +944 -0
  264. package/src/sessions.ts +310 -0
  265. package/src/utils/api-keys.tsx +122 -0
  266. package/src/utils/arrays.tsx +248 -0
  267. package/src/utils/auth-methods.ts +8 -0
  268. package/src/utils/base64.tsx +24 -0
  269. package/src/utils/booleans.tsx +34 -0
  270. package/src/utils/browser-compat.tsx +17 -0
  271. package/src/utils/bytes.tsx +280 -0
  272. package/src/utils/caches.tsx +280 -0
  273. package/src/utils/cel-fields.ts +92 -0
  274. package/src/utils/cloud-hosts.tsx +92 -0
  275. package/src/utils/compile-time.tsx +11 -0
  276. package/src/utils/country-codes.ts +39 -0
  277. package/src/utils/crypto.tsx +174 -0
  278. package/src/utils/currencies.tsx +53 -0
  279. package/src/utils/currency-constants.tsx +51 -0
  280. package/src/utils/dates.tsx +246 -0
  281. package/src/utils/dev-env-state-path.ts +14 -0
  282. package/src/utils/dom.tsx +7 -0
  283. package/src/utils/env.tsx +117 -0
  284. package/src/utils/errors.tsx +284 -0
  285. package/src/utils/esbuild.tsx +235 -0
  286. package/src/utils/featurebase.tsx +247 -0
  287. package/src/utils/fs.tsx +33 -0
  288. package/src/utils/functions.tsx +22 -0
  289. package/src/utils/geo.tsx +16 -0
  290. package/src/utils/globals.tsx +48 -0
  291. package/src/utils/hashes.tsx +52 -0
  292. package/src/utils/html.tsx +60 -0
  293. package/src/utils/http.tsx +91 -0
  294. package/src/utils/ips.tsx +47 -0
  295. package/src/utils/json.tsx +200 -0
  296. package/src/utils/jsx-editable-transpiler.test.ts +156 -0
  297. package/src/utils/jsx-editable-transpiler.tsx +401 -0
  298. package/src/utils/jwt.tsx +170 -0
  299. package/src/utils/locks.tsx +71 -0
  300. package/src/utils/maps.tsx +407 -0
  301. package/src/utils/math.tsx +18 -0
  302. package/src/utils/monkey-patch.tsx +29 -0
  303. package/src/utils/node-http.tsx +47 -0
  304. package/src/utils/numbers.tsx +82 -0
  305. package/src/utils/oauth.tsx +9 -0
  306. package/src/utils/objects.tsx +581 -0
  307. package/src/utils/paginated-lists.test.ts +1039 -0
  308. package/src/utils/paginated-lists.tsx +479 -0
  309. package/src/utils/passkey.tsx +1 -0
  310. package/src/utils/promises.tsx +540 -0
  311. package/src/utils/proxies.tsx +212 -0
  312. package/src/utils/react.tsx +308 -0
  313. package/src/utils/redirect-urls.tsx +299 -0
  314. package/src/utils/regex.tsx +10 -0
  315. package/src/utils/results.tsx +411 -0
  316. package/src/utils/sentry.tsx +20 -0
  317. package/src/utils/stores.tsx +238 -0
  318. package/src/utils/strings.nicify.test.ts +253 -0
  319. package/src/utils/strings.tsx +723 -0
  320. package/src/utils/telemetry.tsx +37 -0
  321. package/src/utils/turnstile-browser.ts +106 -0
  322. package/src/utils/turnstile-flow.test.ts +101 -0
  323. package/src/utils/turnstile-flow.ts +266 -0
  324. package/src/utils/turnstile.ts +34 -0
  325. package/src/utils/typed-arrays.tsx +17 -0
  326. package/src/utils/types.tsx +208 -0
  327. package/src/utils/unicode.tsx +24 -0
  328. package/src/utils/urls.tsx +411 -0
  329. package/src/utils/uuids.tsx +47 -0
  330. package/dist/esm/stack-config-file.d.ts +0 -15
  331. package/dist/esm/stack-config-file.d.ts.map +0 -1
  332. package/dist/esm/stack-config-file.js.map +0 -1
  333. package/dist/stack-config-file.d.ts +0 -15
  334. package/dist/stack-config-file.d.ts.map +0 -1
  335. package/dist/stack-config-file.js.map +0 -1
@@ -20,11 +20,11 @@ function createCustomPagePrompt(options) {
20
20
  const latestPageVersion = Math.max(1, ...Object.keys(options.versions).map(Number));
21
21
  const latestSdkVersion = latestPageVersion === 1 ? options.minSdkVersion : options.versions[latestPageVersion].minSdkVersion;
22
22
  const fullPrompt = deindent`
23
- This prompt explains how to implement a custom ${options.title} page for Stack Auth. The version of this page that you are implementing is v${latestPageVersion}. It can be found in Stack Auth's documentation, and in the Stack Auth devtool indicator.
23
+ This prompt explains how to implement a custom ${options.title} page for Hexclave. The version of this page that you are implementing is v${latestPageVersion}. It can be found in Hexclave's documentation, and in the Hexclave devtool indicator.
24
24
 
25
- First, make sure to upgrade the Stack Auth SDK to a recent version. The minimum supported SDK version for this walkthrough is v${latestSdkVersion}.
25
+ First, make sure to upgrade the Hexclave SDK to a recent version. The minimum supported SDK version for this walkthrough is v${latestSdkVersion}.
26
26
 
27
- The user's codebase may already have a ${options.title} page that could be suitable (eg. from an earlier version of Stack Auth, a template, another auth provider before migrating to Stack Auth, etc.). Use your critical thinking skills to determine what the user's intent is; it is likely that instead of creating a new page, you can just modify the existing page to use Stack Auth & support the logic/structure below.
27
+ The user's codebase may already have a ${options.title} page that could be suitable (eg. from an earlier version of Hexclave, a template, another auth provider before migrating to Hexclave, etc.). Use your critical thinking skills to determine what the user's intent is; it is likely that instead of creating a new page, you can just modify the existing page to use Hexclave & support the logic/structure below.
28
28
 
29
29
  Below is a description of the logical structure of what this page should contain (note that the visual structure and layout may be different, and up to you). The page can have more content than this, but it should always contain at least what's described below.
30
30
 
@@ -41,10 +41,10 @@ function createCustomPagePrompt(options) {
41
41
  ${options.reactExample}
42
42
  \`\`\`
43
43
 
44
- When you're done, please update the file where the Stack app is configured with its URLs, to make sure it points to this page. For example, you may have an object declared like this:
44
+ When you're done, please update the file where the Hexclave app is configured with its URLs, to make sure it points to this page. For example, you may have an object declared like this:
45
45
 
46
46
  \`\`\`tsx
47
- export const stackServerApp = new StackServerApp({
47
+ export const hexclaveServerApp = new HexclaveServerApp({
48
48
  tokenStore: "nextjs-cookie",
49
49
  urls: {
50
50
  default: {
@@ -87,49 +87,49 @@ function createAuthPagePrompt(type) {
87
87
  const authVerb = isSignIn ? "sign in" : "sign up";
88
88
  const authVerbCapitalized = isSignIn ? "Sign in" : "Sign up";
89
89
  const otherAuthVerb = isSignIn ? "sign up" : "sign in";
90
- const credentialMethodCall = isSignIn ? "stackApp.signInWithCredential({ email: form.email, password: form.password })" : "stackApp.signUpWithCredential({ email: form.email, password: form.password })";
90
+ const credentialMethodCall = isSignIn ? "hexclaveApp.signInWithCredential({ email: form.email, password: form.password })" : "hexclaveApp.signUpWithCredential({ email: form.email, password: form.password })";
91
91
  return createCustomPagePrompt({
92
92
  key: type,
93
93
  title,
94
94
  minSdkVersion: "0.0.1",
95
95
  structure: deindent`
96
- - If user is already signed in, regardless of whether restricted or not (ie. \`await stackApp.getUser({ includeRestricted: true }) !== null\`):
97
- - If user is restricted, \`await stackApp.redirectToOnboarding({ replace: true })\`
98
- - Otherwise, \`await stackApp.redirectToAfterSign${isSignIn ? "In" : "Up"}({ replace: true })\`
99
- - While the redirect is happening, you may display a loading indicator, or a note that the user is being redirected. If necessary, or if preferable, you can also render a message card that shows a link to \`await stackApp.redirectToHome()\` and a sign out button.
96
+ - If user is already signed in, regardless of whether restricted or not (ie. \`await hexclaveApp.getUser({ includeRestricted: true }) !== null\`):
97
+ - If user is restricted, \`await hexclaveApp.redirectToOnboarding({ replace: true })\`
98
+ - Otherwise, \`await hexclaveApp.redirectToAfterSign${isSignIn ? "In" : "Up"}({ replace: true })\`
99
+ - While the redirect is happening, you may display a loading indicator, or a note that the user is being redirected. If necessary, or if preferable, you can also render a message card that shows a link to \`await hexclaveApp.redirectToHome()\` and a sign out button.
100
100
  - If user is not signed in:
101
- ${isSignIn ? "- If sign-ups are enabled (\\`project = await stackApp.getProject(); project.config.signUpEnabled\\`), show a link to the sign-up page." : "- If sign-ups are disabled (\\`project = await stackApp.getProject(); !project.config.signUpEnabled\\`), show a message that sign-up is disabled."}
101
+ ${isSignIn ? "- If sign-ups are enabled (\\`project = await hexclaveApp.getProject(); project.config.signUpEnabled\\`), show a link to the sign-up page." : "- If sign-ups are disabled (\\`project = await hexclaveApp.getProject(); !project.config.signUpEnabled\\`), show a message that sign-up is disabled."}
102
102
  - Show a ${authVerb} screen. The auth methods that should render:
103
- - For each OAuth provider (\`project.config.oauthProviders: { readonly id: string }[]\`), render an OAuth button. Clicking the button calls \`await stackApp.signInWithOAuth("<providerId>")\`.
104
- ${isSignIn ? "- If \\`project.config.passkeyEnabled\\`, render a passkey button. Clicking the button calls \\`await stackApp.signInWithPasskey()\\`." : ""}
103
+ - For each OAuth provider (\`project.config.oauthProviders: { readonly id: string }[]\`), render an OAuth button. Clicking the button calls \`await hexclaveApp.signInWithOAuth("<providerId>")\`.
104
+ ${isSignIn ? "- If \\`project.config.passkeyEnabled\\`, render a passkey button. Clicking the button calls \\`await hexclaveApp.signInWithPasskey()\\`." : ""}
105
105
  - If \`project.config.credentialEnabled\`, render a credential ${authVerb} form:
106
106
  - Email + password${isSignIn ? "" : " + repeat password"}
107
107
  ${isSignIn ? "" : "- Validate password strength with \\`getPasswordError()\\` and ensure repeated password matches"}
108
- ${isSignIn ? "- \"Forgot password?\" link calling \\`await stackApp.redirectToForgotPassword()\\`" : ""}
108
+ ${isSignIn ? "- \"Forgot password?\" link calling \\`await hexclaveApp.redirectToForgotPassword()\\`" : ""}
109
109
  - Submit calls \`${credentialMethodCall}: ${isSignIn ? "Promise<Result<undefined, KnownErrors[\"EmailPasswordMismatch\"] | KnownErrors[\"InvalidTotpCode\"]>>" : "Promise<Result<undefined, KnownErrors[\"UserWithEmailAlreadyExists\"] | KnownErrors[\"PasswordRequirementsNotMet\"] | KnownErrors[\"BotChallengeFailed\"]>>"}\`
110
110
  - On error, display the error message on the email field
111
111
  - If \`project.config.magicLinkEnabled\`, render a magic link form:
112
112
  - Email input (validated to be a correct email address) + "Send email" button
113
- - Calls \`stackApp.sendMagicLinkEmail(email): Promise<Result<{ nonce: string }, KnownErrors["RedirectUrlNotWhitelisted"] | KnownErrors["BotChallengeFailed"]>>\`
113
+ - Calls \`hexclaveApp.sendMagicLinkEmail(email): Promise<Result<{ nonce: string }, KnownErrors["RedirectUrlNotWhitelisted"] | KnownErrors["BotChallengeFailed"]>>\`
114
114
  - After sending, switch to a 6-digit OTP input. User enters the code from their email
115
- - Submit the OTP + nonce via \`stackApp.signInWithMagicLink(otp + nonce): Promise<Result<undefined, KnownErrors["VerificationCodeError"] | KnownErrors["InvalidTotpCode"]>>\` (string concatenation)
115
+ - Submit the OTP + nonce via \`hexclaveApp.signInWithMagicLink(otp + nonce): Promise<Result<undefined, KnownErrors["VerificationCodeError"] | KnownErrors["InvalidTotpCode"]>>\` (string concatenation)
116
116
  - If both credential and magic-link are enabled, allow the user to choose which flow to use.
117
117
  - If none of the above auth methods are enabled, show a message explaining that no authentication methods are enabled.
118
- - Show a link to the ${otherAuthVerb} page that calls \`await stackApp.redirectTo${isSignIn ? "SignUp" : "SignIn"}()\`.
118
+ - Show a link to the ${otherAuthVerb} page that calls \`await hexclaveApp.redirectTo${isSignIn ? "SignUp" : "SignIn"}()\`.
119
119
  `,
120
120
  reactExample: deindent`
121
121
  export default function Custom${isSignIn ? "SignIn" : "SignUp"}Page() {
122
- const stackApp = useStackApp();
122
+ const hexclaveApp = useHexclaveApp();
123
123
  const user = useUser({ includeRestricted: true });
124
- const project = stackApp.useProject();
124
+ const project = hexclaveApp.useProject();
125
125
  const [otpState, setOtpState] = useState<null | { nonce: string }>(null);
126
126
 
127
127
  useEffect(() => {
128
128
  if (user) {
129
129
  if (user.isRestricted) {
130
- void stackApp.redirectToOnboarding();
130
+ void hexclaveApp.redirectToOnboarding();
131
131
  } else {
132
- void stackApp.redirectToAfterSign${isSignIn ? "In" : "Up"}();
132
+ void hexclaveApp.redirectToAfterSign${isSignIn ? "In" : "Up"}();
133
133
  }
134
134
  }
135
135
  }, [user]);
@@ -138,8 +138,8 @@ function createAuthPagePrompt(type) {
138
138
  return (
139
139
  <div>
140
140
  <Typography>You are already signed in.</Typography>
141
- <Button onClick={async () => await stackApp.redirectToSignOut()}>Sign out</Button>
142
- <Button onClick={async () => await stackApp.redirectToHome()}>Go home</Button>
141
+ <Button onClick={async () => await hexclaveApp.redirectToSignOut()}>Sign out</Button>
142
+ <Button onClick={async () => await hexclaveApp.redirectToHome()}>Go home</Button>
143
143
  </div>
144
144
  );
145
145
  }
@@ -152,7 +152,7 @@ function createAuthPagePrompt(type) {
152
152
  if (otpState) {
153
153
  return (
154
154
  <Form onSubmit={async (form) => {
155
- const result = await stackApp.signInWithMagicLink(form.otp + otpState.nonce);
155
+ const result = await hexclaveApp.signInWithMagicLink(form.otp + otpState.nonce);
156
156
  if (result.status === "error") handleErrorNicely(...);
157
157
  }}>
158
158
  <Typography>Enter the code from your email</Typography>
@@ -178,10 +178,10 @@ function createAuthPagePrompt(type) {
178
178
  <Typography>
179
179
  {"Don't have an account? "}
180
180
  <a
181
- href={stackApp.urls.signUp}
181
+ href={hexclaveApp.urls.signUp}
182
182
  onClick={async (e) => {
183
183
  e.preventDefault();
184
- await stackApp.redirectToSignUp();
184
+ await hexclaveApp.redirectToSignUp();
185
185
  }}
186
186
  >
187
187
  Sign up
@@ -191,10 +191,10 @@ function createAuthPagePrompt(type) {
191
191
  }` : `<Typography>
192
192
  {"Already have an account? "}
193
193
  <a
194
- href={stackApp.urls.signIn}
194
+ href={hexclaveApp.urls.signIn}
195
195
  onClick={async (e) => {
196
196
  e.preventDefault();
197
- await stackApp.redirectToSignIn();
197
+ await hexclaveApp.redirectToSignIn();
198
198
  }}
199
199
  >
200
200
  Sign in
@@ -207,14 +207,14 @@ function createAuthPagePrompt(type) {
207
207
  <Button
208
208
  key={provider.id}
209
209
  onClick={async () => {
210
- await stackApp.signInWithOAuth(provider.id);
210
+ await hexclaveApp.signInWithOAuth(provider.id);
211
211
  }}
212
212
  >
213
213
  ${authVerbCapitalized} with {provider.id}
214
214
  </Button>
215
215
  ))}
216
216
  ${isSignIn ? `{hasPasskey && (
217
- <Button onClick={async () => await stackApp.signInWithPasskey()}>
217
+ <Button onClick={async () => await hexclaveApp.signInWithPasskey()}>
218
218
  Sign in with passkey
219
219
  </Button>
220
220
  )}` : ""}
@@ -235,7 +235,7 @@ function createAuthPagePrompt(type) {
235
235
  </TabsList>
236
236
  {hasMagicLink && <TabsContent value="magic-link">
237
237
  <Form onSubmit={async (form) => {
238
- const result = await stackApp.sendMagicLinkEmail(form.email);
238
+ const result = await hexclaveApp.sendMagicLinkEmail(form.email);
239
239
  if (result.status === "error") handleErrorNicely(...);
240
240
  else setOtpState({ nonce: result.data.nonce });
241
241
  }}>
@@ -260,7 +260,7 @@ function createAuthPagePrompt(type) {
260
260
  <Label htmlFor="password">Password</Label>
261
261
  <PasswordInput id="password" />
262
262
 
263
- ${isSignIn ? `<Button type="button" variant="link" onClick={async () => await stackApp.redirectToForgotPassword()}>
263
+ ${isSignIn ? `<Button type="button" variant="link" onClick={async () => await hexclaveApp.redirectToForgotPassword()}>
264
264
  Forgot password?
265
265
  </Button>` : `<Label htmlFor="password-repeat">Repeat password</Label>
266
266
  <PasswordInput id="password-repeat" />`}
@@ -306,7 +306,7 @@ function getCustomPagePrompts() {
306
306
 
307
307
  export default function CustomSignOutPage() {
308
308
  const user = useUser({ or: "return-null" });
309
- const stackApp = useStackApp();
309
+ const hexclaveApp = useHexclaveApp();
310
310
 
311
311
  if (user) {
312
312
  use(cacheSignOut(user));
@@ -317,7 +317,7 @@ function getCustomPagePrompts() {
317
317
  title="Signed out"
318
318
  primaryButtonText="Go home"
319
319
  primaryAction={async () => {
320
- await stackApp.redirectToHome();
320
+ await hexclaveApp.redirectToHome();
321
321
  }}
322
322
  >
323
323
  You have been signed out successfully.
@@ -338,8 +338,8 @@ function getCustomPagePrompts() {
338
338
  - Read the verification code from URL params.
339
339
  - If the code is missing, show an invalid-link state.
340
340
  - If the code exists, show a confirmation step:
341
- - Verify action calls \`stackApp.verifyEmail(code)\`.
342
- - Cancel action calls \`stackApp.redirectToHome()\`.
341
+ - Verify action calls \`hexclaveApp.verifyEmail(code)\`.
342
+ - Cancel action calls \`hexclaveApp.redirectToHome()\`.
343
343
  - Handle verification result:
344
344
  - \`VerificationCodeNotFound\` => invalid-link state.
345
345
  - \`VerificationCodeExpired\` => expired-link state.
@@ -349,8 +349,8 @@ function getCustomPagePrompts() {
349
349
  `,
350
350
  reactExample: deindent`
351
351
  export default function CustomEmailVerificationPage(props: { searchParams?: Record<string, string> }) {
352
- const stackApp = useStackApp();
353
- const [result, setResult] = useState<Awaited<ReturnType<typeof stackApp.verifyEmail>> | null>(null);
352
+ const hexclaveApp = useHexclaveApp();
353
+ const [result, setResult] = useState<Awaited<ReturnType<typeof hexclaveApp.verifyEmail>> | null>(null);
354
354
  const code = props.searchParams?.code;
355
355
 
356
356
  if (!code) {
@@ -363,11 +363,11 @@ function getCustomPagePrompts() {
363
363
  title="Do you want to verify your email?"
364
364
  primaryButtonText="Verify"
365
365
  primaryAction={async () => {
366
- setResult(await stackApp.verifyEmail(code));
366
+ setResult(await hexclaveApp.verifyEmail(code));
367
367
  }}
368
368
  secondaryButtonText="Cancel"
369
369
  secondaryAction={async () => {
370
- await stackApp.redirectToHome();
370
+ await hexclaveApp.redirectToHome();
371
371
  }}
372
372
  />
373
373
  );
@@ -388,7 +388,7 @@ function getCustomPagePrompts() {
388
388
  title="Your email has been verified!"
389
389
  primaryButtonText="Go home"
390
390
  primaryAction={async () => {
391
- await stackApp.redirectToHome();
391
+ await hexclaveApp.redirectToHome();
392
392
  }}
393
393
  />
394
394
  );
@@ -406,7 +406,7 @@ function getCustomPagePrompts() {
406
406
  structure: deindent`
407
407
  - Read the reset code from URL params.
408
408
  - If code is missing, show an invalid-link state.
409
- - Before rendering the form, verify the code via \`stackApp.verifyPasswordResetCode(code)\`.
409
+ - Before rendering the form, verify the code via \`hexclaveApp.verifyPasswordResetCode(code)\`.
410
410
  - \`VerificationCodeNotFound\` => invalid-link state.
411
411
  - \`VerificationCodeExpired\` => expired-link state.
412
412
  - \`VerificationCodeAlreadyUsed\` => used-link state.
@@ -414,13 +414,13 @@ function getCustomPagePrompts() {
414
414
  - If code is valid, render reset form:
415
415
  - New password + repeated password.
416
416
  - Validate password strength and ensure repeated password matches.
417
- - Submit calls \`stackApp.resetPassword({ password, code })\`.
417
+ - Submit calls \`hexclaveApp.resetPassword({ password, code })\`.
418
418
  - If reset succeeds, show success state.
419
419
  - If reset fails, show error state with guidance to request a new link.
420
420
  `,
421
421
  reactExample: deindent`
422
422
  export default function CustomPasswordResetPage(props: { searchParams: Record<string, string> }) {
423
- const stackApp = useStackApp();
423
+ const hexclaveApp = useHexclaveApp();
424
424
  const code = props.searchParams.code;
425
425
  const [password, setPassword] = useState("");
426
426
  const [passwordRepeat, setPasswordRepeat] = useState("");
@@ -428,7 +428,7 @@ function getCustomPagePrompts() {
428
428
  const [failed, setFailed] = useState(false);
429
429
  const [formError, setFormError] = useState<string | null>(null);
430
430
 
431
- const cachedVerifyPasswordResetCode = cacheFunction(async (app: StackClientApp<true>, codeToVerify: string) => {
431
+ const cachedVerifyPasswordResetCode = cacheFunction(async (app: HexclaveClientApp<true>, codeToVerify: string) => {
432
432
  return await app.verifyPasswordResetCode(codeToVerify);
433
433
  });
434
434
 
@@ -436,7 +436,7 @@ function getCustomPagePrompts() {
436
436
  return <MessageCard title="Invalid Password Reset Link" />;
437
437
  }
438
438
 
439
- const verificationResult = use(cachedVerifyPasswordResetCode(stackApp, code));
439
+ const verificationResult = use(cachedVerifyPasswordResetCode(hexclaveApp, code));
440
440
  if (verificationResult.status === "error") {
441
441
  if (KnownErrors.VerificationCodeNotFound.isInstance(verificationResult.error)) return <MessageCard title="Invalid Password Reset Link" />;
442
442
  if (KnownErrors.VerificationCodeExpired.isInstance(verificationResult.error)) return <MessageCard title="Expired Password Reset Link" />;
@@ -457,7 +457,7 @@ function getCustomPagePrompts() {
457
457
  return;
458
458
  }
459
459
 
460
- const result = await stackApp.resetPassword({ password, code });
460
+ const result = await hexclaveApp.resetPassword({ password, code });
461
461
  if (result.status === "error") setFailed(true);
462
462
  else setDone(true);
463
463
  }}>
@@ -486,13 +486,13 @@ function getCustomPagePrompts() {
486
486
  - If a user is already signed in, show a signed-in state instead of the reset form.
487
487
  - If user is signed out:
488
488
  - Render a forgot-password form with email input.
489
- - Submit calls \`stackApp.sendForgotPasswordEmail(email)\`.
489
+ - Submit calls \`hexclaveApp.sendForgotPasswordEmail(email)\`.
490
490
  - On success, switch to an email-sent confirmation state.
491
491
  - Provide a link back to sign-in.
492
492
  `,
493
493
  reactExample: deindent`
494
494
  export default function CustomForgotPasswordPage() {
495
- const stackApp = useStackApp();
495
+ const hexclaveApp = useHexclaveApp();
496
496
  const user = useUser({ or: "return-null" });
497
497
  const [email, setEmail] = useState("");
498
498
  const [sent, setSent] = useState(false);
@@ -511,7 +511,7 @@ function getCustomPagePrompts() {
511
511
  <Typography type="h2">Reset Your Password</Typography>
512
512
  <Typography>
513
513
  {"Don't need to reset? "}
514
- <a href={stackApp.urls.signIn}>Sign in</a>
514
+ <a href={hexclaveApp.urls.signIn}>Sign in</a>
515
515
  </Typography>
516
516
 
517
517
  <form onSubmit={async (e) => {
@@ -521,7 +521,7 @@ function getCustomPagePrompts() {
521
521
  setError("Please enter your email");
522
522
  return;
523
523
  }
524
- await stackApp.sendForgotPasswordEmail(email);
524
+ await hexclaveApp.sendForgotPasswordEmail(email);
525
525
  setSent(true);
526
526
  }}>
527
527
  <Label htmlFor="email">Your Email</Label>
@@ -543,15 +543,15 @@ function getCustomPagePrompts() {
543
543
  title: "OAuth Callback",
544
544
  minSdkVersion: "0.0.1",
545
545
  structure: deindent`
546
- - Trigger OAuth callback handling once when the page loads by calling \`stackApp.callOAuthCallback()\`.
546
+ - Trigger OAuth callback handling once when the page loads by calling \`hexclaveApp.callOAuthCallback()\`.
547
547
  - If callback handler already redirected, keep a neutral loading state.
548
- - If callback handler did not redirect, redirect to sign-in with \`stackApp.redirectToSignIn({ noRedirectBack: true })\`.
548
+ - If callback handler did not redirect, redirect to sign-in with \`hexclaveApp.redirectToSignIn({ noRedirectBack: true })\`.
549
549
  - If callback processing throws, capture/show a useful error state.
550
550
  - Provide a fallback "click here" link in case automatic redirect does not happen.
551
551
  `,
552
552
  reactExample: deindent`
553
553
  export default function CustomOAuthCallbackPage() {
554
- const stackApp = useStackApp();
554
+ const hexclaveApp = useHexclaveApp();
555
555
  const called = useRef(false);
556
556
  const [error, setError] = useState<unknown>(null);
557
557
  const [showRedirectLink, setShowRedirectLink] = useState(false);
@@ -561,9 +561,9 @@ function getCustomPagePrompts() {
561
561
  void runAsynchronously(async () => {
562
562
  setTimeout(() => setShowRedirectLink(true), 3000);
563
563
  try {
564
- const hasRedirected = await stackApp.callOAuthCallback();
564
+ const hasRedirected = await hexclaveApp.callOAuthCallback();
565
565
  if (!hasRedirected) {
566
- await stackApp.redirectToSignIn({ noRedirectBack: true });
566
+ await hexclaveApp.redirectToSignIn({ noRedirectBack: true });
567
567
  }
568
568
  } catch (e) {
569
569
  setError(e);
@@ -577,7 +577,7 @@ function getCustomPagePrompts() {
577
577
  {showRedirectLink ? (
578
578
  <Typography>
579
579
  {"If you are not redirected automatically, "}
580
- <a href={stackApp.urls.home}>click here</a>
580
+ <a href={hexclaveApp.urls.home}>click here</a>
581
581
  </Typography>
582
582
  ) : null}
583
583
  {error ? <pre>{JSON.stringify(error, null, 2)}</pre> : null}
@@ -599,8 +599,8 @@ function getCustomPagePrompts() {
599
599
  - Read the magic-link code from URL params.
600
600
  - If code is missing, show invalid-link state.
601
601
  - If code exists, show a confirmation step:
602
- - Confirm action calls \`stackApp.signInWithMagicLink(code)\`.
603
- - Cancel action calls \`stackApp.redirectToHome()\`.
602
+ - Confirm action calls \`hexclaveApp.signInWithMagicLink(code)\`.
603
+ - Cancel action calls \`hexclaveApp.redirectToHome()\`.
604
604
  - Handle callback result:
605
605
  - \`VerificationCodeNotFound\` => invalid-link state.
606
606
  - \`VerificationCodeExpired\` => expired-link state.
@@ -610,9 +610,9 @@ function getCustomPagePrompts() {
610
610
  `,
611
611
  reactExample: deindent`
612
612
  export default function CustomMagicLinkCallbackPage(props: { searchParams?: Record<string, string> }) {
613
- const stackApp = useStackApp();
613
+ const hexclaveApp = useHexclaveApp();
614
614
  const user = useUser({ or: "return-null" });
615
- const [result, setResult] = useState<Awaited<ReturnType<typeof stackApp.signInWithMagicLink>> | null>(null);
615
+ const [result, setResult] = useState<Awaited<ReturnType<typeof hexclaveApp.signInWithMagicLink>> | null>(null);
616
616
  const code = props.searchParams?.code;
617
617
 
618
618
  if (user) return <MessageCard title="You are already signed in." />;
@@ -623,9 +623,9 @@ function getCustomPagePrompts() {
623
623
  <MessageCard
624
624
  title="Do you want to sign in?"
625
625
  primaryButtonText="Sign in"
626
- primaryAction={async () => setResult(await stackApp.signInWithMagicLink(code))}
626
+ primaryAction={async () => setResult(await hexclaveApp.signInWithMagicLink(code))}
627
627
  secondaryButtonText="Cancel"
628
- secondaryAction={async () => await stackApp.redirectToHome()}
628
+ secondaryAction={async () => await hexclaveApp.redirectToHome()}
629
629
  />
630
630
  );
631
631
  }
@@ -641,7 +641,7 @@ function getCustomPagePrompts() {
641
641
  <MessageCard
642
642
  title="Signed in successfully!"
643
643
  primaryButtonText="Go home"
644
- primaryAction={async () => await stackApp.redirectToHome()}
644
+ primaryAction={async () => await hexclaveApp.redirectToHome()}
645
645
  />
646
646
  );
647
647
  }
@@ -656,7 +656,7 @@ function getCustomPagePrompts() {
656
656
  title: "Account Settings",
657
657
  minSdkVersion: "0.0.1",
658
658
  structure: deindent`
659
- - Require an authenticated user (\`useUser({ or: "redirect" })\`) and project config (\`stackApp.useProject()\`).
659
+ - Require an authenticated user (\`useUser({ or: "redirect" })\`) and project config (\`hexclaveApp.useProject()\`).
660
660
  - Render top-level pages in this order:
661
661
  - **My Profile**
662
662
  - **Emails & Auth**
@@ -789,9 +789,9 @@ function getCustomPagePrompts() {
789
789
  }
790
790
 
791
791
  function PasswordSection() {
792
- const stackApp = useStackApp();
792
+ const hexclaveApp = useHexclaveApp();
793
793
  const user = useUser({ or: "redirect" });
794
- const project = stackApp.useProject();
794
+ const project = hexclaveApp.useProject();
795
795
  const [oldPassword, setOldPassword] = useState("");
796
796
  const [newPassword, setNewPassword] = useState("");
797
797
  const [newPasswordRepeat, setNewPasswordRepeat] = useState("");
@@ -820,9 +820,9 @@ function getCustomPagePrompts() {
820
820
  }
821
821
 
822
822
  function PasskeySection() {
823
- const stackApp = useStackApp();
823
+ const hexclaveApp = useHexclaveApp();
824
824
  const user = useUser({ or: "redirect" });
825
- const project = stackApp.useProject();
825
+ const project = hexclaveApp.useProject();
826
826
  const hasVerifiedAuthEmail = user.useContactChannels().some((x) => x.type === "email" && x.isVerified && x.usedForAuth);
827
827
  const isOnlyAuthMethod = user.passkeyAuthEnabled && !user.hasPassword && user.oauthProviders.length === 0 && !user.otpAuthEnabled;
828
828
 
@@ -847,9 +847,9 @@ function getCustomPagePrompts() {
847
847
  }
848
848
 
849
849
  function OtpSection() {
850
- const stackApp = useStackApp();
850
+ const hexclaveApp = useHexclaveApp();
851
851
  const user = useUser({ or: "redirect" });
852
- const project = stackApp.useProject();
852
+ const project = hexclaveApp.useProject();
853
853
  const hasVerifiedAuthEmail = user.useContactChannels().some((x) => x.type === "email" && x.isVerified && x.usedForAuth);
854
854
  const isOnlyAuthMethod = user.otpAuthEnabled && !user.hasPassword && user.oauthProviders.length === 0 && !user.passkeyAuthEnabled;
855
855
 
@@ -998,7 +998,7 @@ function getCustomPagePrompts() {
998
998
  <Typography>{product.displayName}</Typography>
999
999
  {product.subscription?.isCancelable ? (
1000
1000
  <Button variant="secondary" onClick={async () => {
1001
- await useStackApp().cancelSubscription({
1001
+ await useHexclaveApp().cancelSubscription({
1002
1002
  ...(props.customerType === "team" ? { teamId: props.customer.id } : {}),
1003
1003
  productId: product.id ?? "",
1004
1004
  subscriptionId: product.subscription?.subscriptionId ?? undefined,
@@ -1023,8 +1023,8 @@ function getCustomPagePrompts() {
1023
1023
 
1024
1024
  function TeamSection(props: { team: { displayName: string } }) {
1025
1025
  const user = useUser({ or: "redirect" });
1026
- const stackApp = useStackApp();
1027
- const project = stackApp.useProject();
1026
+ const hexclaveApp = useHexclaveApp();
1027
+ const project = hexclaveApp.useProject();
1028
1028
  const team = user.useTeam((props.team as any).id);
1029
1029
 
1030
1030
  if (!team) return null;
@@ -1107,10 +1107,10 @@ function getCustomPagePrompts() {
1107
1107
  }
1108
1108
 
1109
1109
  function CreateTeamSection() {
1110
- const stackApp = useStackApp();
1110
+ const hexclaveApp = useHexclaveApp();
1111
1111
  const user = useUser({ or: "redirect" });
1112
- const project = stackApp.useProject();
1113
- const navigate = stackApp.useNavigate();
1112
+ const project = hexclaveApp.useProject();
1113
+ const navigate = hexclaveApp.useNavigate();
1114
1114
  const [displayName, setDisplayName] = useState("");
1115
1115
 
1116
1116
  if (!project.config.clientTeamCreationEnabled) {
@@ -1139,7 +1139,7 @@ function getCustomPagePrompts() {
1139
1139
  <Button onClick={async () => await user.signOut()}>Sign out</Button>
1140
1140
  <Button variant="destructive" onClick={async () => {
1141
1141
  await user.delete();
1142
- await useStackApp().redirectToHome();
1142
+ await useHexclaveApp().redirectToHome();
1143
1143
  }}>
1144
1144
  Delete account
1145
1145
  </Button>
@@ -1148,9 +1148,9 @@ function getCustomPagePrompts() {
1148
1148
  }
1149
1149
 
1150
1150
  export default function CustomAccountSettingsPage(props: { extraItems?: { id: string, title: string, content: React.ReactNode }[] }) {
1151
- const stackApp = useStackApp();
1151
+ const hexclaveApp = useHexclaveApp();
1152
1152
  const user = useUser({ or: "redirect" });
1153
- const project = stackApp.useProject();
1153
+ const project = hexclaveApp.useProject();
1154
1154
  const teams = user.useTeams();
1155
1155
  const [activeId, setActiveId] = useState("profile");
1156
1156
  const [selectedPaymentTeamId, setSelectedPaymentTeamId] = useState<string | null>(null);
@@ -1249,20 +1249,20 @@ function getCustomPagePrompts() {
1249
1249
  - Resolve current user with \`includeRestricted: true\`.
1250
1250
  - If user is signed out, show a sign-in prompt with cancel path.
1251
1251
  - If user is restricted, route user to onboarding first.
1252
- - Verify invitation code via \`stackApp.verifyTeamInvitationCode(code)\`:
1252
+ - Verify invitation code via \`hexclaveApp.verifyTeamInvitationCode(code)\`:
1253
1253
  - Not found => invalid-link state.
1254
1254
  - Expired => expired-link state.
1255
1255
  - Already used => used-link state.
1256
1256
  - Other errors => throw.
1257
- - If code is valid, load invitation details via \`stackApp.getTeamInvitationDetails(code)\`.
1257
+ - If code is valid, load invitation details via \`hexclaveApp.getTeamInvitationDetails(code)\`.
1258
1258
  - Render invitation actions:
1259
- - Join => \`stackApp.acceptTeamInvitation(code)\`.
1260
- - Ignore => \`stackApp.redirectToHome()\`.
1259
+ - Join => \`hexclaveApp.acceptTeamInvitation(code)\`.
1260
+ - Ignore => \`hexclaveApp.redirectToHome()\`.
1261
1261
  - On successful join, show success state and allow navigation home.
1262
1262
  `,
1263
1263
  reactExample: deindent`
1264
1264
  export default function CustomTeamInvitationPage(props: { searchParams: Record<string, string> }) {
1265
- const stackApp = useStackApp();
1265
+ const hexclaveApp = useHexclaveApp();
1266
1266
  const user = useUser({ or: "return-null", includeRestricted: true });
1267
1267
  const code = props.searchParams.code;
1268
1268
  const [accepted, setAccepted] = useState(false);
@@ -1276,9 +1276,9 @@ function getCustomPagePrompts() {
1276
1276
  <MessageCard
1277
1277
  title="Team invitation"
1278
1278
  primaryButtonText="Sign in"
1279
- primaryAction={async () => await stackApp.redirectToSignIn()}
1279
+ primaryAction={async () => await hexclaveApp.redirectToSignIn()}
1280
1280
  secondaryButtonText="Cancel"
1281
- secondaryAction={async () => await stackApp.redirectToHome()}
1281
+ secondaryAction={async () => await hexclaveApp.redirectToHome()}
1282
1282
  />
1283
1283
  );
1284
1284
  }
@@ -1288,7 +1288,7 @@ function getCustomPagePrompts() {
1288
1288
  <MessageCard
1289
1289
  title="Complete your account setup"
1290
1290
  primaryButtonText="Complete setup"
1291
- primaryAction={async () => await stackApp.redirectToOnboarding()}
1291
+ primaryAction={async () => await hexclaveApp.redirectToOnboarding()}
1292
1292
  />
1293
1293
  );
1294
1294
  }
@@ -1304,7 +1304,7 @@ function getCustomPagePrompts() {
1304
1304
  title="Team invitation"
1305
1305
  primaryButtonText="Check invitation"
1306
1306
  primaryAction={async () => {
1307
- const verification = await stackApp.verifyTeamInvitationCode(code);
1307
+ const verification = await hexclaveApp.verifyTeamInvitationCode(code);
1308
1308
  if (verification.status === "error") {
1309
1309
  if (KnownErrors.VerificationCodeNotFound.isInstance(verification.error)) {
1310
1310
  setPageError("invalid");
@@ -1321,7 +1321,7 @@ function getCustomPagePrompts() {
1321
1321
  throw verification.error;
1322
1322
  }
1323
1323
 
1324
- const invitationDetails = await stackApp.getTeamInvitationDetails(code);
1324
+ const invitationDetails = await hexclaveApp.getTeamInvitationDetails(code);
1325
1325
  if (invitationDetails.status === "error") {
1326
1326
  setPageError("unknown");
1327
1327
  return;
@@ -1330,7 +1330,7 @@ function getCustomPagePrompts() {
1330
1330
  setDetails(invitationDetails.data);
1331
1331
  }}
1332
1332
  secondaryButtonText="Cancel"
1333
- secondaryAction={async () => await stackApp.redirectToHome()}
1333
+ secondaryAction={async () => await hexclaveApp.redirectToHome()}
1334
1334
  >
1335
1335
  We will verify your invitation before showing the join action.
1336
1336
  </MessageCard>
@@ -1346,12 +1346,12 @@ function getCustomPagePrompts() {
1346
1346
  title="Team invitation"
1347
1347
  primaryButtonText="Join"
1348
1348
  primaryAction={async () => {
1349
- const result = await stackApp.acceptTeamInvitation(code);
1349
+ const result = await hexclaveApp.acceptTeamInvitation(code);
1350
1350
  if (result.status === "ok") setAccepted(true);
1351
1351
  else setPageError("unknown");
1352
1352
  }}
1353
1353
  secondaryButtonText="Ignore"
1354
- secondaryAction={async () => await stackApp.redirectToHome()}
1354
+ secondaryAction={async () => await hexclaveApp.redirectToHome()}
1355
1355
  >
1356
1356
  You are invited to join {details.teamDisplayName}
1357
1357
  </MessageCard>
@@ -1423,7 +1423,7 @@ function getCustomPagePrompts() {
1423
1423
  structure: deindent`
1424
1424
  - Read the MFA attempt code from session storage.
1425
1425
  - Render OTP input for the one-time code.
1426
- - When OTP is complete, submit \`stackApp.signInWithMfa(otp, attemptCode, { noRedirect: true })\`.
1426
+ - When OTP is complete, submit \`hexclaveApp.signInWithMfa(otp, attemptCode, { noRedirect: true })\`.
1427
1427
  - Handle result:
1428
1428
  - Success => clear stored attempt code, show success state, then redirect after sign-in.
1429
1429
  - \`InvalidTotpCode\` => show invalid-code error and allow retry.
@@ -1445,7 +1445,7 @@ function getCustomPagePrompts() {
1445
1445
  }
1446
1446
 
1447
1447
  export default function CustomMfaPage() {
1448
- const stackApp = useStackApp();
1448
+ const hexclaveApp = useHexclaveApp();
1449
1449
  const [otp, setOtp] = useState("");
1450
1450
  const [submitting, setSubmitting] = useState(false);
1451
1451
  const [error, setError] = useState<string | null>(null);
@@ -1459,13 +1459,13 @@ function getCustomPagePrompts() {
1459
1459
  if (!attemptCode || otp.length !== 6 || submitting) return;
1460
1460
  setSubmitting(true);
1461
1461
  setError(null);
1462
- const result = await stackApp.signInWithMfa(otp, attemptCode, { noRedirect: true });
1462
+ const result = await hexclaveApp.signInWithMfa(otp, attemptCode, { noRedirect: true });
1463
1463
  if (result.status === "ok") {
1464
1464
  // Hexclave rebrand: remove both the new and legacy MFA attempt code keys.
1465
1465
  window.sessionStorage.removeItem("hexclave_mfa_attempt_code");
1466
1466
  window.sessionStorage.removeItem("stack_mfa_attempt_code");
1467
1467
  setVerified(true);
1468
- await stackApp.redirectToAfterSignIn();
1468
+ await hexclaveApp.redirectToAfterSignIn();
1469
1469
  } else if (KnownErrors.InvalidTotpCode.isInstance(result.error)) {
1470
1470
  setError("Invalid TOTP code");
1471
1471
  setOtp("");
@@ -1517,7 +1517,7 @@ function getCustomPagePrompts() {
1517
1517
  `,
1518
1518
  reactExample: deindent`
1519
1519
  export default function CustomErrorPage(props: { searchParams: Record<string, string> }) {
1520
- const stackApp = useStackApp();
1520
+ const hexclaveApp = useHexclaveApp();
1521
1521
  const errorCode = props.searchParams.errorCode;
1522
1522
  const message = props.searchParams.message;
1523
1523
  const details = props.searchParams.details;
@@ -1538,11 +1538,11 @@ function getCustomPagePrompts() {
1538
1538
  }
1539
1539
 
1540
1540
  if (KnownErrors.OAuthConnectionAlreadyConnectedToAnotherUser.isInstance(error)) {
1541
- return <MessageCard title="Failed to connect account" primaryButtonText="Go Home" primaryAction={() => stackApp.redirectToHome()} />;
1541
+ return <MessageCard title="Failed to connect account" primaryButtonText="Go Home" primaryAction={() => hexclaveApp.redirectToHome()} />;
1542
1542
  }
1543
1543
 
1544
1544
  if (KnownErrors.UserAlreadyConnectedToAnotherOAuthConnection.isInstance(error)) {
1545
- return <MessageCard title="Failed to connect account" primaryButtonText="Go Home" primaryAction={() => stackApp.redirectToHome()} />;
1545
+ return <MessageCard title="Failed to connect account" primaryButtonText="Go Home" primaryAction={() => hexclaveApp.redirectToHome()} />;
1546
1546
  }
1547
1547
 
1548
1548
  if (KnownErrors.OAuthProviderAccessDenied.isInstance(error)) {
@@ -1550,9 +1550,9 @@ function getCustomPagePrompts() {
1550
1550
  <MessageCard
1551
1551
  title="OAuth provider access denied"
1552
1552
  primaryButtonText="Sign in again"
1553
- primaryAction={() => stackApp.redirectToSignIn()}
1553
+ primaryAction={() => hexclaveApp.redirectToSignIn()}
1554
1554
  secondaryButtonText="Go Home"
1555
- secondaryAction={() => stackApp.redirectToHome()}
1555
+ secondaryAction={() => hexclaveApp.redirectToHome()}
1556
1556
  />
1557
1557
  );
1558
1558
  }
@@ -1572,8 +1572,8 @@ function getCustomPagePrompts() {
1572
1572
  structure: deindent`
1573
1573
  - Resolve user with \`useUser({ or: "return-null", includeRestricted: true })\`.
1574
1574
  - Route by user state:
1575
- - Restricted user resolved to unrestricted => redirect to \`stackApp.redirectToAfterSignIn()\`.
1576
- - Missing/anonymous user => redirect to \`stackApp.redirectToSignIn()\`.
1575
+ - Restricted user resolved to unrestricted => redirect to \`hexclaveApp.redirectToAfterSignIn()\`.
1576
+ - Missing/anonymous user => redirect to \`hexclaveApp.redirectToSignIn()\`.
1577
1577
  - Restricted user => continue onboarding flow.
1578
1578
  - Handle restricted reasons:
1579
1579
  - \`email_not_verified\` and no primary email => ask user for email and call \`user.update({ primaryEmail })\`.
@@ -1583,18 +1583,18 @@ function getCustomPagePrompts() {
1583
1583
  `,
1584
1584
  reactExample: deindent`
1585
1585
  export default function CustomOnboardingPage() {
1586
- const stackApp = useStackApp();
1586
+ const hexclaveApp = useHexclaveApp();
1587
1587
  const user = useUser({ or: "return-null", includeRestricted: true });
1588
1588
  const [email, setEmail] = useState("");
1589
1589
  const [changeEmail, setChangeEmail] = useState(false);
1590
1590
 
1591
1591
  if (user && !user.isRestricted) {
1592
- void runAsynchronously(stackApp.redirectToAfterSignIn());
1592
+ void runAsynchronously(hexclaveApp.redirectToAfterSignIn());
1593
1593
  return null;
1594
1594
  }
1595
1595
 
1596
1596
  if (!user || user.isAnonymous) {
1597
- void runAsynchronously(stackApp.redirectToSignIn());
1597
+ void runAsynchronously(hexclaveApp.redirectToSignIn());
1598
1598
  return null;
1599
1599
  }
1600
1600