@hexclave/shared 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +7 -0
- package/dist/ai/image-limits.d.ts +24 -0
- package/dist/ai/image-limits.d.ts.map +1 -0
- package/dist/ai/image-limits.js +61 -0
- package/dist/ai/image-limits.js.map +1 -0
- package/dist/ai/unified-prompts/reminders.d.ts +5 -0
- package/dist/ai/unified-prompts/reminders.d.ts.map +1 -0
- package/dist/ai/unified-prompts/reminders.js +33 -0
- package/dist/ai/unified-prompts/reminders.js.map +1 -0
- package/dist/ai/unified-prompts/skill-site-prompt-parts/ai-setup-prompt.d.ts +11 -0
- package/dist/ai/unified-prompts/skill-site-prompt-parts/ai-setup-prompt.d.ts.map +1 -0
- package/dist/ai/unified-prompts/skill-site-prompt-parts/ai-setup-prompt.js +851 -0
- package/dist/ai/unified-prompts/skill-site-prompt-parts/ai-setup-prompt.js.map +1 -0
- package/dist/ai/unified-prompts/skill-site-prompt-parts/brain.d.ts +5 -0
- package/dist/ai/unified-prompts/skill-site-prompt-parts/brain.d.ts.map +1 -0
- package/dist/ai/unified-prompts/skill-site-prompt-parts/brain.js +12 -0
- package/dist/ai/unified-prompts/skill-site-prompt-parts/brain.js.map +1 -0
- package/dist/ai/unified-prompts/skill-site-prompt-parts/cli-help.d.ts +5 -0
- package/dist/ai/unified-prompts/skill-site-prompt-parts/cli-help.d.ts.map +1 -0
- package/dist/ai/unified-prompts/skill-site-prompt-parts/cli-help.js +12 -0
- package/dist/ai/unified-prompts/skill-site-prompt-parts/cli-help.js.map +1 -0
- package/dist/ai/unified-prompts/skill-site-prompt-parts/config-docs.d.ts +5 -0
- package/dist/ai/unified-prompts/skill-site-prompt-parts/config-docs.d.ts.map +1 -0
- package/dist/ai/unified-prompts/skill-site-prompt-parts/config-docs.js +12 -0
- package/dist/ai/unified-prompts/skill-site-prompt-parts/config-docs.js.map +1 -0
- package/dist/ai/unified-prompts/skill-site-prompt-parts/custom-components-instructions.d.ts +5 -0
- package/dist/ai/unified-prompts/skill-site-prompt-parts/custom-components-instructions.d.ts.map +1 -0
- package/dist/ai/unified-prompts/skill-site-prompt-parts/custom-components-instructions.js +12 -0
- package/dist/ai/unified-prompts/skill-site-prompt-parts/custom-components-instructions.js.map +1 -0
- package/dist/ai/unified-prompts/skill-site-prompt-parts/dashboard-instructions.d.ts +5 -0
- package/dist/ai/unified-prompts/skill-site-prompt-parts/dashboard-instructions.d.ts.map +1 -0
- package/dist/ai/unified-prompts/skill-site-prompt-parts/dashboard-instructions.js +12 -0
- package/dist/ai/unified-prompts/skill-site-prompt-parts/dashboard-instructions.js.map +1 -0
- package/dist/ai/unified-prompts/skill-site-prompt-parts/docs-index.d.ts +5 -0
- package/dist/ai/unified-prompts/skill-site-prompt-parts/docs-index.d.ts.map +1 -0
- package/dist/ai/unified-prompts/skill-site-prompt-parts/docs-index.js +64 -0
- package/dist/ai/unified-prompts/skill-site-prompt-parts/docs-index.js.map +1 -0
- package/dist/ai/unified-prompts/skill-site-prompt-parts/openapi-specs.d.ts +5 -0
- package/dist/ai/unified-prompts/skill-site-prompt-parts/openapi-specs.d.ts.map +1 -0
- package/dist/ai/unified-prompts/skill-site-prompt-parts/openapi-specs.js +12 -0
- package/dist/ai/unified-prompts/skill-site-prompt-parts/openapi-specs.js.map +1 -0
- package/dist/ai/unified-prompts/skill-site-prompt-parts/sdk-interface-source.d.ts +5 -0
- package/dist/ai/unified-prompts/skill-site-prompt-parts/sdk-interface-source.d.ts.map +1 -0
- package/dist/ai/unified-prompts/skill-site-prompt-parts/sdk-interface-source.js +12 -0
- package/dist/ai/unified-prompts/skill-site-prompt-parts/sdk-interface-source.js.map +1 -0
- package/dist/ai/unified-prompts/skill-site-prompt.d.ts +5 -0
- package/dist/ai/unified-prompts/skill-site-prompt.d.ts.map +1 -0
- package/dist/ai/unified-prompts/skill-site-prompt.js +75 -0
- package/dist/ai/unified-prompts/skill-site-prompt.js.map +1 -0
- package/dist/apps/apps-config.d.ts +168 -0
- package/dist/apps/apps-config.d.ts.map +1 -0
- package/dist/apps/apps-config.js +157 -0
- package/dist/apps/apps-config.js.map +1 -0
- package/dist/apps/apps-ui.d.ts +45 -0
- package/dist/apps/apps-ui.d.ts.map +1 -0
- package/dist/apps/apps-ui.js +109 -0
- package/dist/apps/apps-ui.js.map +1 -0
- package/dist/chunk-BE-pF4vm.js +34 -0
- package/dist/config/db-sync-mappings.d.ts +193 -0
- package/dist/config/db-sync-mappings.d.ts.map +1 -0
- package/dist/config/db-sync-mappings.js +2255 -0
- package/dist/config/db-sync-mappings.js.map +1 -0
- package/dist/config/format.d.ts +61 -0
- package/dist/config/format.d.ts.map +1 -0
- package/dist/config/format.js +337 -0
- package/dist/config/format.js.map +1 -0
- package/dist/config/migrate-catalogs-to-product-lines.d.ts +14 -0
- package/dist/config/migrate-catalogs-to-product-lines.d.ts.map +1 -0
- package/dist/config/migrate-catalogs-to-product-lines.js +379 -0
- package/dist/config/migrate-catalogs-to-product-lines.js.map +1 -0
- package/dist/config/schema-fuzzer.test.d.ts +1 -0
- package/dist/config/schema-fuzzer.test.js +401 -0
- package/dist/config/schema-fuzzer.test.js.map +1 -0
- package/dist/config/schema.d.ts +2315 -0
- package/dist/config/schema.d.ts.map +1 -0
- package/dist/config/schema.js +1085 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/config-authoring.d.ts +12 -0
- package/dist/config-authoring.d.ts.map +1 -0
- package/dist/config-authoring.js +12 -0
- package/dist/config-authoring.js.map +1 -0
- package/dist/config-authoring.test.d.ts +1 -0
- package/dist/config-authoring.test.js +29 -0
- package/dist/config-authoring.test.js.map +1 -0
- package/dist/config-rendering.d.ts +17 -0
- package/dist/config-rendering.d.ts.map +1 -0
- package/dist/config-rendering.js +114 -0
- package/dist/config-rendering.js.map +1 -0
- package/dist/crud.d.ts +98 -0
- package/dist/crud.d.ts.map +1 -0
- package/dist/crud.js +129 -0
- package/dist/crud.js.map +1 -0
- package/dist/esm/ai/image-limits.d.ts +24 -0
- package/dist/esm/ai/image-limits.d.ts.map +1 -0
- package/dist/esm/ai/image-limits.js +53 -0
- package/dist/esm/ai/image-limits.js.map +1 -0
- package/dist/esm/ai/unified-prompts/reminders.d.ts +5 -0
- package/dist/esm/ai/unified-prompts/reminders.d.ts.map +1 -0
- package/dist/esm/ai/unified-prompts/reminders.js +31 -0
- package/dist/esm/ai/unified-prompts/reminders.js.map +1 -0
- package/dist/esm/ai/unified-prompts/skill-site-prompt-parts/ai-setup-prompt.d.ts +11 -0
- package/dist/esm/ai/unified-prompts/skill-site-prompt-parts/ai-setup-prompt.d.ts.map +1 -0
- package/dist/esm/ai/unified-prompts/skill-site-prompt-parts/ai-setup-prompt.js +843 -0
- package/dist/esm/ai/unified-prompts/skill-site-prompt-parts/ai-setup-prompt.js.map +1 -0
- package/dist/esm/ai/unified-prompts/skill-site-prompt-parts/brain.d.ts +5 -0
- package/dist/esm/ai/unified-prompts/skill-site-prompt-parts/brain.d.ts.map +1 -0
- package/dist/esm/ai/unified-prompts/skill-site-prompt-parts/brain.js +10 -0
- package/dist/esm/ai/unified-prompts/skill-site-prompt-parts/brain.js.map +1 -0
- package/dist/esm/ai/unified-prompts/skill-site-prompt-parts/cli-help.d.ts +5 -0
- package/dist/esm/ai/unified-prompts/skill-site-prompt-parts/cli-help.d.ts.map +1 -0
- package/dist/esm/ai/unified-prompts/skill-site-prompt-parts/cli-help.js +10 -0
- package/dist/esm/ai/unified-prompts/skill-site-prompt-parts/cli-help.js.map +1 -0
- package/dist/esm/ai/unified-prompts/skill-site-prompt-parts/config-docs.d.ts +5 -0
- package/dist/esm/ai/unified-prompts/skill-site-prompt-parts/config-docs.d.ts.map +1 -0
- package/dist/esm/ai/unified-prompts/skill-site-prompt-parts/config-docs.js +10 -0
- package/dist/esm/ai/unified-prompts/skill-site-prompt-parts/config-docs.js.map +1 -0
- package/dist/esm/ai/unified-prompts/skill-site-prompt-parts/custom-components-instructions.d.ts +5 -0
- package/dist/esm/ai/unified-prompts/skill-site-prompt-parts/custom-components-instructions.d.ts.map +1 -0
- package/dist/esm/ai/unified-prompts/skill-site-prompt-parts/custom-components-instructions.js +10 -0
- package/dist/esm/ai/unified-prompts/skill-site-prompt-parts/custom-components-instructions.js.map +1 -0
- package/dist/esm/ai/unified-prompts/skill-site-prompt-parts/dashboard-instructions.d.ts +5 -0
- package/dist/esm/ai/unified-prompts/skill-site-prompt-parts/dashboard-instructions.d.ts.map +1 -0
- package/dist/esm/ai/unified-prompts/skill-site-prompt-parts/dashboard-instructions.js +10 -0
- package/dist/esm/ai/unified-prompts/skill-site-prompt-parts/dashboard-instructions.js.map +1 -0
- package/dist/esm/ai/unified-prompts/skill-site-prompt-parts/docs-index.d.ts +5 -0
- package/dist/esm/ai/unified-prompts/skill-site-prompt-parts/docs-index.d.ts.map +1 -0
- package/dist/esm/ai/unified-prompts/skill-site-prompt-parts/docs-index.js +61 -0
- package/dist/esm/ai/unified-prompts/skill-site-prompt-parts/docs-index.js.map +1 -0
- package/dist/esm/ai/unified-prompts/skill-site-prompt-parts/openapi-specs.d.ts +5 -0
- package/dist/esm/ai/unified-prompts/skill-site-prompt-parts/openapi-specs.d.ts.map +1 -0
- package/dist/esm/ai/unified-prompts/skill-site-prompt-parts/openapi-specs.js +10 -0
- package/dist/esm/ai/unified-prompts/skill-site-prompt-parts/openapi-specs.js.map +1 -0
- package/dist/esm/ai/unified-prompts/skill-site-prompt-parts/sdk-interface-source.d.ts +5 -0
- package/dist/esm/ai/unified-prompts/skill-site-prompt-parts/sdk-interface-source.d.ts.map +1 -0
- package/dist/esm/ai/unified-prompts/skill-site-prompt-parts/sdk-interface-source.js +10 -0
- package/dist/esm/ai/unified-prompts/skill-site-prompt-parts/sdk-interface-source.js.map +1 -0
- package/dist/esm/ai/unified-prompts/skill-site-prompt.d.ts +5 -0
- package/dist/esm/ai/unified-prompts/skill-site-prompt.d.ts.map +1 -0
- package/dist/esm/ai/unified-prompts/skill-site-prompt.js +73 -0
- package/dist/esm/ai/unified-prompts/skill-site-prompt.js.map +1 -0
- package/dist/esm/apps/apps-config.d.ts +168 -0
- package/dist/esm/apps/apps-config.d.ts.map +1 -0
- package/dist/esm/apps/apps-config.js +154 -0
- package/dist/esm/apps/apps-config.js.map +1 -0
- package/dist/esm/apps/apps-ui.d.ts +45 -0
- package/dist/esm/apps/apps-ui.d.ts.map +1 -0
- package/dist/esm/apps/apps-ui.js +104 -0
- package/dist/esm/apps/apps-ui.js.map +1 -0
- package/dist/esm/config/db-sync-mappings.d.ts +193 -0
- package/dist/esm/config/db-sync-mappings.d.ts.map +1 -0
- package/dist/esm/config/db-sync-mappings.js +2253 -0
- package/dist/esm/config/db-sync-mappings.js.map +1 -0
- package/dist/esm/config/format.d.ts +61 -0
- package/dist/esm/config/format.d.ts.map +1 -0
- package/dist/esm/config/format.js +327 -0
- package/dist/esm/config/format.js.map +1 -0
- package/dist/esm/config/migrate-catalogs-to-product-lines.d.ts +14 -0
- package/dist/esm/config/migrate-catalogs-to-product-lines.d.ts.map +1 -0
- package/dist/esm/config/migrate-catalogs-to-product-lines.js +377 -0
- package/dist/esm/config/migrate-catalogs-to-product-lines.js.map +1 -0
- package/dist/esm/config/schema-fuzzer.test.d.ts +1 -0
- package/dist/esm/config/schema-fuzzer.test.js +401 -0
- package/dist/esm/config/schema-fuzzer.test.js.map +1 -0
- package/dist/esm/config/schema.d.ts +2315 -0
- package/dist/esm/config/schema.d.ts.map +1 -0
- package/dist/esm/config/schema.js +1065 -0
- package/dist/esm/config/schema.js.map +1 -0
- package/dist/esm/config-authoring.d.ts +12 -0
- package/dist/esm/config-authoring.d.ts.map +1 -0
- package/dist/esm/config-authoring.js +9 -0
- package/dist/esm/config-authoring.js.map +1 -0
- package/dist/esm/config-authoring.test.d.ts +1 -0
- package/dist/esm/config-authoring.test.js +29 -0
- package/dist/esm/config-authoring.test.js.map +1 -0
- package/dist/esm/config-rendering.d.ts +17 -0
- package/dist/esm/config-rendering.d.ts.map +1 -0
- package/dist/esm/config-rendering.js +108 -0
- package/dist/esm/config-rendering.js.map +1 -0
- package/dist/esm/crud.d.ts +98 -0
- package/dist/esm/crud.d.ts.map +1 -0
- package/dist/esm/crud.js +127 -0
- package/dist/esm/crud.js.map +1 -0
- package/dist/esm/global.d.ts +1 -0
- package/dist/esm/helpers/emails.d.ts +69 -0
- package/dist/esm/helpers/emails.d.ts.map +1 -0
- package/dist/esm/helpers/emails.js +243 -0
- package/dist/esm/helpers/emails.js.map +1 -0
- package/dist/esm/helpers/init-prompt.d.ts +5 -0
- package/dist/esm/helpers/init-prompt.d.ts.map +1 -0
- package/dist/esm/helpers/init-prompt.js +40 -0
- package/dist/esm/helpers/init-prompt.js.map +1 -0
- package/dist/esm/helpers/password.d.ts +7 -0
- package/dist/esm/helpers/password.d.ts.map +1 -0
- package/dist/esm/helpers/password.js +13 -0
- package/dist/esm/helpers/password.js.map +1 -0
- package/dist/esm/helpers/production-mode.d.ts +11 -0
- package/dist/esm/helpers/production-mode.d.ts.map +1 -0
- package/dist/esm/helpers/production-mode.js +46 -0
- package/dist/esm/helpers/production-mode.js.map +1 -0
- package/dist/esm/helpers/support-sla.d.ts +48 -0
- package/dist/esm/helpers/support-sla.d.ts.map +1 -0
- package/dist/esm/helpers/support-sla.js +65 -0
- package/dist/esm/helpers/support-sla.js.map +1 -0
- package/dist/esm/helpers/support-sla.test.d.ts +1 -0
- package/dist/esm/helpers/support-sla.test.js +102 -0
- package/dist/esm/helpers/support-sla.test.js.map +1 -0
- package/dist/esm/helpers/vault/client-side.d.ts +16 -0
- package/dist/esm/helpers/vault/client-side.d.ts.map +1 -0
- package/dist/esm/helpers/vault/client-side.js +69 -0
- package/dist/esm/helpers/vault/client-side.js.map +1 -0
- package/dist/esm/helpers/vault/server-side.d.ts +9 -0
- package/dist/esm/helpers/vault/server-side.d.ts.map +1 -0
- package/dist/esm/helpers/vault/server-side.js +123 -0
- package/dist/esm/helpers/vault/server-side.js.map +1 -0
- package/dist/esm/hooks/use-async-callback.d.ts +8 -0
- package/dist/esm/hooks/use-async-callback.d.ts.map +1 -0
- package/dist/esm/hooks/use-async-callback.js +38 -0
- package/dist/esm/hooks/use-async-callback.js.map +1 -0
- package/dist/esm/hooks/use-async-external-store.d.ts +9 -0
- package/dist/esm/hooks/use-async-external-store.d.ts.map +1 -0
- package/dist/esm/hooks/use-async-external-store.js +20 -0
- package/dist/esm/hooks/use-async-external-store.js.map +1 -0
- package/dist/esm/hooks/use-hash.d.ts +5 -0
- package/dist/esm/hooks/use-hash.d.ts.map +1 -0
- package/dist/esm/hooks/use-hash.js +15 -0
- package/dist/esm/hooks/use-hash.js.map +1 -0
- package/dist/esm/hooks/use-hover.d.ts +8 -0
- package/dist/esm/hooks/use-hover.d.ts.map +1 -0
- package/dist/esm/hooks/use-hover.js +59 -0
- package/dist/esm/hooks/use-hover.js.map +1 -0
- package/dist/esm/hooks/use-strict-memo.d.ts +10 -0
- package/dist/esm/hooks/use-strict-memo.d.ts.map +1 -0
- package/dist/esm/hooks/use-strict-memo.js +119 -0
- package/dist/esm/hooks/use-strict-memo.js.map +1 -0
- package/dist/esm/index.d.ts +5 -0
- package/dist/esm/index.js +6 -0
- package/dist/esm/interface/admin-interface.d.ts +308 -0
- package/dist/esm/interface/admin-interface.d.ts.map +1 -0
- package/dist/esm/interface/admin-interface.js +463 -0
- package/dist/esm/interface/admin-interface.js.map +1 -0
- package/dist/esm/interface/admin-metrics.d.ts +597 -0
- package/dist/esm/interface/admin-metrics.d.ts.map +1 -0
- package/dist/esm/interface/admin-metrics.js +134 -0
- package/dist/esm/interface/admin-metrics.js.map +1 -0
- package/dist/esm/interface/client-interface.d.ts +447 -0
- package/dist/esm/interface/client-interface.d.ts.map +1 -0
- package/dist/esm/interface/client-interface.js +1946 -0
- package/dist/esm/interface/client-interface.js.map +1 -0
- package/dist/esm/interface/client-interface.test.d.ts +1 -0
- package/dist/esm/interface/client-interface.test.js +559 -0
- package/dist/esm/interface/client-interface.test.js.map +1 -0
- package/dist/esm/interface/conversations.d.ts +314 -0
- package/dist/esm/interface/conversations.d.ts.map +1 -0
- package/dist/esm/interface/conversations.js +108 -0
- package/dist/esm/interface/conversations.js.map +1 -0
- package/dist/esm/interface/crud/analytics.d.ts +14 -0
- package/dist/esm/interface/crud/analytics.d.ts.map +1 -0
- package/dist/esm/interface/crud/analytics.js +1 -0
- package/dist/esm/interface/crud/connected-accounts.d.ts +69 -0
- package/dist/esm/interface/crud/connected-accounts.d.ts.map +1 -0
- package/dist/esm/interface/crud/connected-accounts.js +35 -0
- package/dist/esm/interface/crud/connected-accounts.js.map +1 -0
- package/dist/esm/interface/crud/contact-channels.d.ts +182 -0
- package/dist/esm/interface/crud/contact-channels.d.ts.map +1 -0
- package/dist/esm/interface/crud/contact-channels.js +68 -0
- package/dist/esm/interface/crud/contact-channels.js.map +1 -0
- package/dist/esm/interface/crud/current-user.d.ts +286 -0
- package/dist/esm/interface/crud/current-user.d.ts.map +1 -0
- package/dist/esm/interface/crud/current-user.js +69 -0
- package/dist/esm/interface/crud/current-user.js.map +1 -0
- package/dist/esm/interface/crud/email-outbox.d.ts +1466 -0
- package/dist/esm/interface/crud/email-outbox.d.ts.map +1 -0
- package/dist/esm/interface/crud/email-outbox.js +190 -0
- package/dist/esm/interface/crud/email-outbox.js.map +1 -0
- package/dist/esm/interface/crud/email-templates.d.ts +86 -0
- package/dist/esm/interface/crud/email-templates.d.ts.map +1 -0
- package/dist/esm/interface/crud/email-templates.js +46 -0
- package/dist/esm/interface/crud/email-templates.js.map +1 -0
- package/dist/esm/interface/crud/emails.d.ts +42 -0
- package/dist/esm/interface/crud/emails.d.ts.map +1 -0
- package/dist/esm/interface/crud/emails.js +19 -0
- package/dist/esm/interface/crud/emails.js.map +1 -0
- package/dist/esm/interface/crud/internal-api-keys.d.ts +141 -0
- package/dist/esm/interface/crud/internal-api-keys.d.ts.map +1 -0
- package/dist/esm/interface/crud/internal-api-keys.js +49 -0
- package/dist/esm/interface/crud/internal-api-keys.js.map +1 -0
- package/dist/esm/interface/crud/invoices.d.ts +43 -0
- package/dist/esm/interface/crud/invoices.d.ts.map +1 -0
- package/dist/esm/interface/crud/invoices.js +25 -0
- package/dist/esm/interface/crud/invoices.js.map +1 -0
- package/dist/esm/interface/crud/items.d.ts +31 -0
- package/dist/esm/interface/crud/items.d.ts.map +1 -0
- package/dist/esm/interface/crud/items.js +23 -0
- package/dist/esm/interface/crud/items.js.map +1 -0
- package/dist/esm/interface/crud/notification-preferences.d.ts +39 -0
- package/dist/esm/interface/crud/notification-preferences.d.ts.map +1 -0
- package/dist/esm/interface/crud/notification-preferences.js +31 -0
- package/dist/esm/interface/crud/notification-preferences.js.map +1 -0
- package/dist/esm/interface/crud/oauth-providers.d.ts +187 -0
- package/dist/esm/interface/crud/oauth-providers.d.ts.map +1 -0
- package/dist/esm/interface/crud/oauth-providers.js +75 -0
- package/dist/esm/interface/crud/oauth-providers.js.map +1 -0
- package/dist/esm/interface/crud/products.d.ts +182 -0
- package/dist/esm/interface/crud/products.d.ts.map +1 -0
- package/dist/esm/interface/crud/products.js +29 -0
- package/dist/esm/interface/crud/products.js.map +1 -0
- package/dist/esm/interface/crud/project-api-keys.d.ts +204 -0
- package/dist/esm/interface/crud/project-api-keys.d.ts.map +1 -0
- package/dist/esm/interface/crud/project-api-keys.js +72 -0
- package/dist/esm/interface/crud/project-api-keys.js.map +1 -0
- package/dist/esm/interface/crud/project-permissions.d.ts +162 -0
- package/dist/esm/interface/crud/project-permissions.d.ts.map +1 -0
- package/dist/esm/interface/crud/project-permissions.js +104 -0
- package/dist/esm/interface/crud/project-permissions.js.map +1 -0
- package/dist/esm/interface/crud/projects.d.ts +852 -0
- package/dist/esm/interface/crud/projects.d.ts.map +1 -0
- package/dist/esm/interface/crud/projects.js +193 -0
- package/dist/esm/interface/crud/projects.js.map +1 -0
- package/dist/esm/interface/crud/session-replays.d.ts +83 -0
- package/dist/esm/interface/crud/session-replays.d.ts.map +1 -0
- package/dist/esm/interface/crud/session-replays.js +1 -0
- package/dist/esm/interface/crud/sessions.d.ts +151 -0
- package/dist/esm/interface/crud/sessions.d.ts.map +1 -0
- package/dist/esm/interface/crud/sessions.js +56 -0
- package/dist/esm/interface/crud/sessions.js.map +1 -0
- package/dist/esm/interface/crud/sign-up-rules.d.ts +15 -0
- package/dist/esm/interface/crud/sign-up-rules.d.ts.map +1 -0
- package/dist/esm/interface/crud/sign-up-rules.js +1 -0
- package/dist/esm/interface/crud/svix-token.d.ts +32 -0
- package/dist/esm/interface/crud/svix-token.d.ts.map +1 -0
- package/dist/esm/interface/crud/svix-token.js +18 -0
- package/dist/esm/interface/crud/svix-token.js.map +1 -0
- package/dist/esm/interface/crud/team-invitation-details.d.ts +32 -0
- package/dist/esm/interface/crud/team-invitation-details.d.ts.map +1 -0
- package/dist/esm/interface/crud/team-invitation-details.js +21 -0
- package/dist/esm/interface/crud/team-invitation-details.js.map +1 -0
- package/dist/esm/interface/crud/team-invitation.d.ts +55 -0
- package/dist/esm/interface/crud/team-invitation.d.ts.map +1 -0
- package/dist/esm/interface/crud/team-invitation.js +37 -0
- package/dist/esm/interface/crud/team-invitation.js.map +1 -0
- package/dist/esm/interface/crud/team-member-profiles.d.ts +287 -0
- package/dist/esm/interface/crud/team-member-profiles.d.ts.map +1 -0
- package/dist/esm/interface/crud/team-member-profiles.js +58 -0
- package/dist/esm/interface/crud/team-member-profiles.js.map +1 -0
- package/dist/esm/interface/crud/team-memberships.d.ts +76 -0
- package/dist/esm/interface/crud/team-memberships.d.ts.map +1 -0
- package/dist/esm/interface/crud/team-memberships.js +54 -0
- package/dist/esm/interface/crud/team-memberships.js.map +1 -0
- package/dist/esm/interface/crud/team-permissions.d.ts +170 -0
- package/dist/esm/interface/crud/team-permissions.d.ts.map +1 -0
- package/dist/esm/interface/crud/team-permissions.js +105 -0
- package/dist/esm/interface/crud/team-permissions.js.map +1 -0
- package/dist/esm/interface/crud/teams.d.ts +300 -0
- package/dist/esm/interface/crud/teams.d.ts.map +1 -0
- package/dist/esm/interface/crud/teams.js +129 -0
- package/dist/esm/interface/crud/teams.js.map +1 -0
- package/dist/esm/interface/crud/transactions.d.ts +183 -0
- package/dist/esm/interface/crud/transactions.d.ts.map +1 -0
- package/dist/esm/interface/crud/transactions.js +85 -0
- package/dist/esm/interface/crud/transactions.js.map +1 -0
- package/dist/esm/interface/crud/users.d.ts +654 -0
- package/dist/esm/interface/crud/users.d.ts.map +1 -0
- package/dist/esm/interface/crud/users.js +181 -0
- package/dist/esm/interface/crud/users.js.map +1 -0
- package/dist/esm/interface/handler-urls.d.ts +51 -0
- package/dist/esm/interface/handler-urls.d.ts.map +1 -0
- package/dist/esm/interface/handler-urls.js +3 -0
- package/dist/esm/interface/page-component-versions.d.ts +25 -0
- package/dist/esm/interface/page-component-versions.d.ts.map +1 -0
- package/dist/esm/interface/page-component-versions.js +1661 -0
- package/dist/esm/interface/page-component-versions.js.map +1 -0
- package/dist/esm/interface/server-interface.d.ts +255 -0
- package/dist/esm/interface/server-interface.d.ts.map +1 -0
- package/dist/esm/interface/server-interface.js +459 -0
- package/dist/esm/interface/server-interface.js.map +1 -0
- package/dist/esm/interface/webhooks.d.ts +326 -0
- package/dist/esm/interface/webhooks.d.ts.map +1 -0
- package/dist/esm/interface/webhooks.js +22 -0
- package/dist/esm/interface/webhooks.js.map +1 -0
- package/dist/esm/known-errors.d.ts +575 -0
- package/dist/esm/known-errors.d.ts.map +1 -0
- package/dist/esm/known-errors.js +791 -0
- package/dist/esm/known-errors.js.map +1 -0
- package/dist/esm/local-emulator.d.ts +6 -0
- package/dist/esm/local-emulator.d.ts.map +1 -0
- package/dist/esm/local-emulator.js +7 -0
- package/dist/esm/local-emulator.js.map +1 -0
- package/dist/esm/payments/payment-methods.d.ts +64 -0
- package/dist/esm/payments/payment-methods.d.ts.map +1 -0
- package/dist/esm/payments/payment-methods.js +205 -0
- package/dist/esm/payments/payment-methods.js.map +1 -0
- package/dist/esm/payments/stripe-limits.d.ts +17 -0
- package/dist/esm/payments/stripe-limits.d.ts.map +1 -0
- package/dist/esm/payments/stripe-limits.js +17 -0
- package/dist/esm/payments/stripe-limits.js.map +1 -0
- package/dist/esm/plans.d.ts +72 -0
- package/dist/esm/plans.d.ts.map +1 -0
- package/dist/esm/plans.js +81 -0
- package/dist/esm/plans.js.map +1 -0
- package/dist/esm/schema-fields.d.ts +472 -0
- package/dist/esm/schema-fields.d.ts.map +1 -0
- package/dist/esm/schema-fields.js +1009 -0
- package/dist/esm/schema-fields.js.map +1 -0
- package/dist/esm/sessions.d.ts +165 -0
- package/dist/esm/sessions.d.ts.map +1 -0
- package/dist/esm/sessions.js +226 -0
- package/dist/esm/sessions.js.map +1 -0
- package/dist/esm/stack-config-file.d.ts +15 -0
- package/dist/esm/stack-config-file.d.ts.map +1 -0
- package/dist/esm/stack-config-file.js +76 -0
- package/dist/esm/stack-config-file.js.map +1 -0
- package/dist/esm/utils/api-keys.d.ts +26 -0
- package/dist/esm/utils/api-keys.d.ts.map +1 -0
- package/dist/esm/utils/api-keys.js +77 -0
- package/dist/esm/utils/api-keys.js.map +1 -0
- package/dist/esm/utils/arrays.d.ts +25 -0
- package/dist/esm/utils/arrays.d.ts.map +1 -0
- package/dist/esm/utils/arrays.js +552 -0
- package/dist/esm/utils/arrays.js.map +1 -0
- package/dist/esm/utils/auth-methods.d.ts +6 -0
- package/dist/esm/utils/auth-methods.d.ts.map +1 -0
- package/dist/esm/utils/auth-methods.js +11 -0
- package/dist/esm/utils/auth-methods.js.map +1 -0
- package/dist/esm/utils/base64.d.ts +6 -0
- package/dist/esm/utils/base64.d.ts.map +1 -0
- package/dist/esm/utils/base64.js +25 -0
- package/dist/esm/utils/base64.js.map +1 -0
- package/dist/esm/utils/booleans.d.ts +8 -0
- package/dist/esm/utils/booleans.d.ts.map +1 -0
- package/dist/esm/utils/booleans.js +35 -0
- package/dist/esm/utils/booleans.js.map +1 -0
- package/dist/esm/utils/browser-compat.d.ts +10 -0
- package/dist/esm/utils/browser-compat.d.ts.map +1 -0
- package/dist/esm/utils/browser-compat.js +21 -0
- package/dist/esm/utils/browser-compat.js.map +1 -0
- package/dist/esm/utils/bytes.d.ts +17 -0
- package/dist/esm/utils/bytes.d.ts.map +1 -0
- package/dist/esm/utils/bytes.js +290 -0
- package/dist/esm/utils/bytes.js.map +1 -0
- package/dist/esm/utils/caches.d.ts +102 -0
- package/dist/esm/utils/caches.d.ts.map +1 -0
- package/dist/esm/utils/caches.js +185 -0
- package/dist/esm/utils/caches.js.map +1 -0
- package/dist/esm/utils/cel-fields.d.ts +23 -0
- package/dist/esm/utils/cel-fields.d.ts.map +1 -0
- package/dist/esm/utils/cel-fields.js +99 -0
- package/dist/esm/utils/cel-fields.js.map +1 -0
- package/dist/esm/utils/compile-time.d.ts +10 -0
- package/dist/esm/utils/compile-time.d.ts.map +1 -0
- package/dist/esm/utils/compile-time.js +14 -0
- package/dist/esm/utils/compile-time.js.map +1 -0
- package/dist/esm/utils/country-codes.d.ts +11 -0
- package/dist/esm/utils/country-codes.d.ts.map +1 -0
- package/dist/esm/utils/country-codes.js +36 -0
- package/dist/esm/utils/country-codes.js.map +1 -0
- package/dist/esm/utils/crypto.d.ts +48 -0
- package/dist/esm/utils/crypto.d.ts.map +1 -0
- package/dist/esm/utils/crypto.js +208 -0
- package/dist/esm/utils/crypto.js.map +1 -0
- package/dist/esm/utils/currencies.d.ts +8 -0
- package/dist/esm/utils/currencies.d.ts.map +1 -0
- package/dist/esm/utils/currencies.js +50 -0
- package/dist/esm/utils/currencies.js.map +1 -0
- package/dist/esm/utils/currency-constants.d.ts +39 -0
- package/dist/esm/utils/currency-constants.d.ts.map +1 -0
- package/dist/esm/utils/currency-constants.js +42 -0
- package/dist/esm/utils/currency-constants.js.map +1 -0
- package/dist/esm/utils/dates.d.ts +23 -0
- package/dist/esm/utils/dates.d.ts.map +1 -0
- package/dist/esm/utils/dates.js +167 -0
- package/dist/esm/utils/dates.js.map +1 -0
- package/dist/esm/utils/dev-env-state-path.d.ts +6 -0
- package/dist/esm/utils/dev-env-state-path.d.ts.map +1 -0
- package/dist/esm/utils/dev-env-state-path.js +15 -0
- package/dist/esm/utils/dev-env-state-path.js.map +1 -0
- package/dist/esm/utils/dom.d.ts +5 -0
- package/dist/esm/utils/dom.d.ts.map +1 -0
- package/dist/esm/utils/dom.js +11 -0
- package/dist/esm/utils/dom.js.map +1 -0
- package/dist/esm/utils/env.d.ts +25 -0
- package/dist/esm/utils/env.d.ts.map +1 -0
- package/dist/esm/utils/env.js +78 -0
- package/dist/esm/utils/env.js.map +1 -0
- package/dist/esm/utils/errors.d.ts +231 -0
- package/dist/esm/utils/errors.d.ts.map +1 -0
- package/dist/esm/utils/errors.js +385 -0
- package/dist/esm/utils/errors.js.map +1 -0
- package/dist/esm/utils/esbuild.d.ts +16 -0
- package/dist/esm/utils/esbuild.d.ts.map +1 -0
- package/dist/esm/utils/esbuild.js +182 -0
- package/dist/esm/utils/esbuild.js.map +1 -0
- package/dist/esm/utils/featurebase.d.ts +30 -0
- package/dist/esm/utils/featurebase.d.ts.map +1 -0
- package/dist/esm/utils/featurebase.js +166 -0
- package/dist/esm/utils/featurebase.js.map +1 -0
- package/dist/esm/utils/fs.d.ts +9 -0
- package/dist/esm/utils/fs.d.ts.map +1 -0
- package/dist/esm/utils/fs.js +25 -0
- package/dist/esm/utils/fs.js.map +1 -0
- package/dist/esm/utils/functions.d.ts +6 -0
- package/dist/esm/utils/functions.d.ts.map +1 -0
- package/dist/esm/utils/functions.js +34 -0
- package/dist/esm/utils/functions.js.map +1 -0
- package/dist/esm/utils/geo.d.ts +24 -0
- package/dist/esm/utils/geo.d.ts.map +1 -0
- package/dist/esm/utils/geo.js +16 -0
- package/dist/esm/utils/geo.js.map +1 -0
- package/dist/esm/utils/globals.d.ts +13 -0
- package/dist/esm/utils/globals.d.ts.map +1 -0
- package/dist/esm/utils/globals.js +34 -0
- package/dist/esm/utils/globals.js.map +1 -0
- package/dist/esm/utils/hashes.d.ts +9 -0
- package/dist/esm/utils/hashes.d.ts.map +1 -0
- package/dist/esm/utils/hashes.js +40 -0
- package/dist/esm/utils/hashes.js.map +1 -0
- package/dist/esm/utils/html.d.ts +7 -0
- package/dist/esm/utils/html.d.ts.map +1 -0
- package/dist/esm/utils/html.js +33 -0
- package/dist/esm/utils/html.js.map +1 -0
- package/dist/esm/utils/http.d.ts +45 -0
- package/dist/esm/utils/http.d.ts.map +1 -0
- package/dist/esm/utils/http.js +75 -0
- package/dist/esm/utils/http.js.map +1 -0
- package/dist/esm/utils/ips.d.ts +8 -0
- package/dist/esm/utils/ips.d.ts.map +1 -0
- package/dist/esm/utils/ips.js +36 -0
- package/dist/esm/utils/ips.js.map +1 -0
- package/dist/esm/utils/json.d.ts +15 -0
- package/dist/esm/utils/json.d.ts.map +1 -0
- package/dist/esm/utils/json.js +178 -0
- package/dist/esm/utils/json.js.map +1 -0
- package/dist/esm/utils/jsx-editable-transpiler.d.ts +68 -0
- package/dist/esm/utils/jsx-editable-transpiler.d.ts.map +1 -0
- package/dist/esm/utils/jsx-editable-transpiler.js +216 -0
- package/dist/esm/utils/jsx-editable-transpiler.js.map +1 -0
- package/dist/esm/utils/jsx-editable-transpiler.test.d.ts +1 -0
- package/dist/esm/utils/jsx-editable-transpiler.test.js +122 -0
- package/dist/esm/utils/jsx-editable-transpiler.test.js.map +1 -0
- package/dist/esm/utils/jwt.d.ts +79 -0
- package/dist/esm/utils/jwt.d.ts.map +1 -0
- package/dist/esm/utils/jwt.js +102 -0
- package/dist/esm/utils/jwt.js.map +1 -0
- package/dist/esm/utils/locks.d.ts +17 -0
- package/dist/esm/utils/locks.d.ts.map +1 -0
- package/dist/esm/utils/locks.js +54 -0
- package/dist/esm/utils/locks.js.map +1 -0
- package/dist/esm/utils/maps.d.ts +61 -0
- package/dist/esm/utils/maps.d.ts.map +1 -0
- package/dist/esm/utils/maps.js +297 -0
- package/dist/esm/utils/maps.js.map +1 -0
- package/dist/esm/utils/math.d.ts +8 -0
- package/dist/esm/utils/math.d.ts.map +1 -0
- package/dist/esm/utils/math.js +21 -0
- package/dist/esm/utils/math.js.map +1 -0
- package/dist/esm/utils/monkey-patch.d.ts +7 -0
- package/dist/esm/utils/monkey-patch.d.ts.map +1 -0
- package/dist/esm/utils/monkey-patch.js +21 -0
- package/dist/esm/utils/monkey-patch.js.map +1 -0
- package/dist/esm/utils/node-http.d.ts +17 -0
- package/dist/esm/utils/node-http.d.ts.map +1 -0
- package/dist/esm/utils/node-http.js +38 -0
- package/dist/esm/utils/node-http.js.map +1 -0
- package/dist/esm/utils/numbers.d.ts +7 -0
- package/dist/esm/utils/numbers.d.ts.map +1 -0
- package/dist/esm/utils/numbers.js +75 -0
- package/dist/esm/utils/numbers.js.map +1 -0
- package/dist/esm/utils/oauth.d.ts +11 -0
- package/dist/esm/utils/oauth.d.ts.map +1 -0
- package/dist/esm/utils/oauth.js +27 -0
- package/dist/esm/utils/oauth.js.map +1 -0
- package/dist/esm/utils/objects.d.ts +59 -0
- package/dist/esm/utils/objects.d.ts.map +1 -0
- package/dist/esm/utils/objects.js +818 -0
- package/dist/esm/utils/objects.js.map +1 -0
- package/dist/esm/utils/paginated-lists.d.ts +442 -0
- package/dist/esm/utils/paginated-lists.d.ts.map +1 -0
- package/dist/esm/utils/paginated-lists.js +411 -0
- package/dist/esm/utils/paginated-lists.js.map +1 -0
- package/dist/esm/utils/paginated-lists.test.d.ts +1 -0
- package/dist/esm/utils/paginated-lists.test.js +1304 -0
- package/dist/esm/utils/paginated-lists.test.js.map +1 -0
- package/dist/esm/utils/passkey.d.ts +2 -0
- package/dist/esm/utils/passkey.js +1 -0
- package/dist/esm/utils/promises.d.ts +80 -0
- package/dist/esm/utils/promises.d.ts.map +1 -0
- package/dist/esm/utils/promises.js +333 -0
- package/dist/esm/utils/promises.js.map +1 -0
- package/dist/esm/utils/proxies.d.ts +13 -0
- package/dist/esm/utils/proxies.d.ts.map +1 -0
- package/dist/esm/utils/proxies.js +197 -0
- package/dist/esm/utils/proxies.js.map +1 -0
- package/dist/esm/utils/react.d.ts +61 -0
- package/dist/esm/utils/react.d.ts.map +1 -0
- package/dist/esm/utils/react.js +229 -0
- package/dist/esm/utils/react.js.map +1 -0
- package/dist/esm/utils/redirect-urls.d.ts +30 -0
- package/dist/esm/utils/redirect-urls.d.ts.map +1 -0
- package/dist/esm/utils/redirect-urls.js +215 -0
- package/dist/esm/utils/redirect-urls.js.map +1 -0
- package/dist/esm/utils/regex.d.ts +5 -0
- package/dist/esm/utils/regex.d.ts.map +1 -0
- package/dist/esm/utils/regex.js +13 -0
- package/dist/esm/utils/regex.js.map +1 -0
- package/dist/esm/utils/results.d.ts +70 -0
- package/dist/esm/utils/results.d.ts.map +1 -0
- package/dist/esm/utils/results.js +339 -0
- package/dist/esm/utils/results.js.map +1 -0
- package/dist/esm/utils/sentry.d.ts +13 -0
- package/dist/esm/utils/sentry.d.ts.map +1 -0
- package/dist/esm/utils/sentry.js +14 -0
- package/dist/esm/utils/sentry.js.map +1 -0
- package/dist/esm/utils/stores.d.ts +104 -0
- package/dist/esm/utils/stores.d.ts.map +1 -0
- package/dist/esm/utils/stores.js +175 -0
- package/dist/esm/utils/stores.js.map +1 -0
- package/dist/esm/utils/strings.d.ts +76 -0
- package/dist/esm/utils/strings.d.ts.map +1 -0
- package/dist/esm/utils/strings.js +530 -0
- package/dist/esm/utils/strings.js.map +1 -0
- package/dist/esm/utils/strings.nicify.test.d.ts +1 -0
- package/dist/esm/utils/strings.nicify.test.js +243 -0
- package/dist/esm/utils/strings.nicify.test.js.map +1 -0
- package/dist/esm/utils/telemetry.d.ts +15 -0
- package/dist/esm/utils/telemetry.d.ts.map +1 -0
- package/dist/esm/utils/telemetry.js +31 -0
- package/dist/esm/utils/telemetry.js.map +1 -0
- package/dist/esm/utils/turnstile-browser.d.ts +32 -0
- package/dist/esm/utils/turnstile-browser.d.ts.map +1 -0
- package/dist/esm/utils/turnstile-browser.js +61 -0
- package/dist/esm/utils/turnstile-browser.js.map +1 -0
- package/dist/esm/utils/turnstile-flow.d.ts +29 -0
- package/dist/esm/utils/turnstile-flow.d.ts.map +1 -0
- package/dist/esm/utils/turnstile-flow.js +219 -0
- package/dist/esm/utils/turnstile-flow.js.map +1 -0
- package/dist/esm/utils/turnstile-flow.test.d.ts +1 -0
- package/dist/esm/utils/turnstile-flow.test.js +75 -0
- package/dist/esm/utils/turnstile-flow.test.js.map +1 -0
- package/dist/esm/utils/turnstile.d.ts +17 -0
- package/dist/esm/utils/turnstile.d.ts.map +1 -0
- package/dist/esm/utils/turnstile.js +25 -0
- package/dist/esm/utils/turnstile.js.map +1 -0
- package/dist/esm/utils/typed-arrays.d.ts +14 -0
- package/dist/esm/utils/typed-arrays.d.ts.map +1 -0
- package/dist/esm/utils/typed-arrays.js +20 -0
- package/dist/esm/utils/typed-arrays.js.map +1 -0
- package/dist/esm/utils/types.d.ts +77 -0
- package/dist/esm/utils/types.d.ts.map +1 -0
- package/dist/esm/utils/types.js +55 -0
- package/dist/esm/utils/types.js.map +1 -0
- package/dist/esm/utils/unicode.d.ts +5 -0
- package/dist/esm/utils/unicode.d.ts.map +1 -0
- package/dist/esm/utils/unicode.js +24 -0
- package/dist/esm/utils/unicode.js.map +1 -0
- package/dist/esm/utils/urls.d.ts +28 -0
- package/dist/esm/utils/urls.d.ts.map +1 -0
- package/dist/esm/utils/urls.js +259 -0
- package/dist/esm/utils/urls.js.map +1 -0
- package/dist/esm/utils/uuids.d.ts +6 -0
- package/dist/esm/utils/uuids.d.ts.map +1 -0
- package/dist/esm/utils/uuids.js +36 -0
- package/dist/esm/utils/uuids.js.map +1 -0
- package/dist/global.d.d.ts +0 -0
- package/dist/global.d.ts +1 -0
- package/dist/helpers/emails.d.ts +69 -0
- package/dist/helpers/emails.d.ts.map +1 -0
- package/dist/helpers/emails.js +252 -0
- package/dist/helpers/emails.js.map +1 -0
- package/dist/helpers/init-prompt.d.ts +5 -0
- package/dist/helpers/init-prompt.d.ts.map +1 -0
- package/dist/helpers/init-prompt.js +42 -0
- package/dist/helpers/init-prompt.js.map +1 -0
- package/dist/helpers/password.d.ts +6 -0
- package/dist/helpers/password.d.ts.map +1 -0
- package/dist/helpers/password.js +15 -0
- package/dist/helpers/password.js.map +1 -0
- package/dist/helpers/production-mode.d.ts +11 -0
- package/dist/helpers/production-mode.d.ts.map +1 -0
- package/dist/helpers/production-mode.js +48 -0
- package/dist/helpers/production-mode.js.map +1 -0
- package/dist/helpers/support-sla.d.ts +48 -0
- package/dist/helpers/support-sla.d.ts.map +1 -0
- package/dist/helpers/support-sla.js +72 -0
- package/dist/helpers/support-sla.js.map +1 -0
- package/dist/helpers/support-sla.test.d.ts +1 -0
- package/dist/helpers/support-sla.test.js +102 -0
- package/dist/helpers/support-sla.test.js.map +1 -0
- package/dist/helpers/vault/client-side.d.ts +16 -0
- package/dist/helpers/vault/client-side.d.ts.map +1 -0
- package/dist/helpers/vault/client-side.js +73 -0
- package/dist/helpers/vault/client-side.js.map +1 -0
- package/dist/helpers/vault/server-side.d.ts +9 -0
- package/dist/helpers/vault/server-side.d.ts.map +1 -0
- package/dist/helpers/vault/server-side.js +126 -0
- package/dist/helpers/vault/server-side.js.map +1 -0
- package/dist/hooks/use-async-callback.d.ts +8 -0
- package/dist/hooks/use-async-callback.d.ts.map +1 -0
- package/dist/hooks/use-async-callback.js +42 -0
- package/dist/hooks/use-async-callback.js.map +1 -0
- package/dist/hooks/use-async-external-store.d.ts +9 -0
- package/dist/hooks/use-async-external-store.d.ts.map +1 -0
- package/dist/hooks/use-async-external-store.js +22 -0
- package/dist/hooks/use-async-external-store.js.map +1 -0
- package/dist/hooks/use-hash.d.ts +5 -0
- package/dist/hooks/use-hash.d.ts.map +1 -0
- package/dist/hooks/use-hash.js +17 -0
- package/dist/hooks/use-hash.js.map +1 -0
- package/dist/hooks/use-hover.d.ts +8 -0
- package/dist/hooks/use-hover.d.ts.map +1 -0
- package/dist/hooks/use-hover.js +61 -0
- package/dist/hooks/use-hover.js.map +1 -0
- package/dist/hooks/use-strict-memo.d.ts +10 -0
- package/dist/hooks/use-strict-memo.d.ts.map +1 -0
- package/dist/hooks/use-strict-memo.js +121 -0
- package/dist/hooks/use-strict-memo.js.map +1 -0
- package/dist/index-D9ysacya.d.ts +153 -0
- package/dist/index-D9ysacya.d.ts.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +37 -0
- package/dist/interface/admin-interface.d.ts +308 -0
- package/dist/interface/admin-interface.d.ts.map +1 -0
- package/dist/interface/admin-interface.js +465 -0
- package/dist/interface/admin-interface.js.map +1 -0
- package/dist/interface/admin-metrics.d.ts +597 -0
- package/dist/interface/admin-metrics.d.ts.map +1 -0
- package/dist/interface/admin-metrics.js +153 -0
- package/dist/interface/admin-metrics.js.map +1 -0
- package/dist/interface/client-interface.d.ts +447 -0
- package/dist/interface/client-interface.d.ts.map +1 -0
- package/dist/interface/client-interface.js +1948 -0
- package/dist/interface/client-interface.js.map +1 -0
- package/dist/interface/client-interface.test.d.ts +1 -0
- package/dist/interface/client-interface.test.js +559 -0
- package/dist/interface/client-interface.test.js.map +1 -0
- package/dist/interface/conversations.d.ts +314 -0
- package/dist/interface/conversations.d.ts.map +1 -0
- package/dist/interface/conversations.js +121 -0
- package/dist/interface/conversations.js.map +1 -0
- package/dist/interface/crud/analytics.d.ts +14 -0
- package/dist/interface/crud/analytics.d.ts.map +1 -0
- package/dist/interface/crud/analytics.js +0 -0
- package/dist/interface/crud/connected-accounts.d.ts +68 -0
- package/dist/interface/crud/connected-accounts.d.ts.map +1 -0
- package/dist/interface/crud/connected-accounts.js +41 -0
- package/dist/interface/crud/connected-accounts.js.map +1 -0
- package/dist/interface/crud/contact-channels.d.ts +181 -0
- package/dist/interface/crud/contact-channels.d.ts.map +1 -0
- package/dist/interface/crud/contact-channels.js +76 -0
- package/dist/interface/crud/contact-channels.js.map +1 -0
- package/dist/interface/crud/current-user.d.ts +285 -0
- package/dist/interface/crud/current-user.d.ts.map +1 -0
- package/dist/interface/crud/current-user.js +71 -0
- package/dist/interface/crud/current-user.js.map +1 -0
- package/dist/interface/crud/email-outbox.d.ts +1465 -0
- package/dist/interface/crud/email-outbox.d.ts.map +1 -0
- package/dist/interface/crud/email-outbox.js +195 -0
- package/dist/interface/crud/email-outbox.js.map +1 -0
- package/dist/interface/crud/email-templates.d.ts +85 -0
- package/dist/interface/crud/email-templates.d.ts.map +1 -0
- package/dist/interface/crud/email-templates.js +53 -0
- package/dist/interface/crud/email-templates.js.map +1 -0
- package/dist/interface/crud/emails.d.ts +41 -0
- package/dist/interface/crud/emails.d.ts.map +1 -0
- package/dist/interface/crud/emails.js +23 -0
- package/dist/interface/crud/emails.js.map +1 -0
- package/dist/interface/crud/internal-api-keys.d.ts +140 -0
- package/dist/interface/crud/internal-api-keys.d.ts.map +1 -0
- package/dist/interface/crud/internal-api-keys.js +56 -0
- package/dist/interface/crud/internal-api-keys.js.map +1 -0
- package/dist/interface/crud/invoices.d.ts +43 -0
- package/dist/interface/crud/invoices.d.ts.map +1 -0
- package/dist/interface/crud/invoices.js +28 -0
- package/dist/interface/crud/invoices.js.map +1 -0
- package/dist/interface/crud/items.d.ts +30 -0
- package/dist/interface/crud/items.d.ts.map +1 -0
- package/dist/interface/crud/items.js +25 -0
- package/dist/interface/crud/items.js.map +1 -0
- package/dist/interface/crud/notification-preferences.d.ts +38 -0
- package/dist/interface/crud/notification-preferences.d.ts.map +1 -0
- package/dist/interface/crud/notification-preferences.js +33 -0
- package/dist/interface/crud/notification-preferences.js.map +1 -0
- package/dist/interface/crud/oauth-providers.d.ts +186 -0
- package/dist/interface/crud/oauth-providers.d.ts.map +1 -0
- package/dist/interface/crud/oauth-providers.js +83 -0
- package/dist/interface/crud/oauth-providers.js.map +1 -0
- package/dist/interface/crud/products.d.ts +182 -0
- package/dist/interface/crud/products.d.ts.map +1 -0
- package/dist/interface/crud/products.js +32 -0
- package/dist/interface/crud/products.js.map +1 -0
- package/dist/interface/crud/project-api-keys.d.ts +203 -0
- package/dist/interface/crud/project-api-keys.d.ts.map +1 -0
- package/dist/interface/crud/project-api-keys.js +79 -0
- package/dist/interface/crud/project-api-keys.js.map +1 -0
- package/dist/interface/crud/project-permissions.d.ts +161 -0
- package/dist/interface/crud/project-permissions.d.ts.map +1 -0
- package/dist/interface/crud/project-permissions.js +116 -0
- package/dist/interface/crud/project-permissions.js.map +1 -0
- package/dist/interface/crud/projects.d.ts +851 -0
- package/dist/interface/crud/projects.d.ts.map +1 -0
- package/dist/interface/crud/projects.js +204 -0
- package/dist/interface/crud/projects.js.map +1 -0
- package/dist/interface/crud/session-replays.d.ts +83 -0
- package/dist/interface/crud/session-replays.d.ts.map +1 -0
- package/dist/interface/crud/session-replays.js +0 -0
- package/dist/interface/crud/sessions.d.ts +150 -0
- package/dist/interface/crud/sessions.d.ts.map +1 -0
- package/dist/interface/crud/sessions.js +62 -0
- package/dist/interface/crud/sessions.js.map +1 -0
- package/dist/interface/crud/sign-up-rules.d.ts +15 -0
- package/dist/interface/crud/sign-up-rules.d.ts.map +1 -0
- package/dist/interface/crud/sign-up-rules.js +0 -0
- package/dist/interface/crud/svix-token.d.ts +31 -0
- package/dist/interface/crud/svix-token.d.ts.map +1 -0
- package/dist/interface/crud/svix-token.js +22 -0
- package/dist/interface/crud/svix-token.js.map +1 -0
- package/dist/interface/crud/team-invitation-details.d.ts +31 -0
- package/dist/interface/crud/team-invitation-details.d.ts.map +1 -0
- package/dist/interface/crud/team-invitation-details.js +24 -0
- package/dist/interface/crud/team-invitation-details.js.map +1 -0
- package/dist/interface/crud/team-invitation.d.ts +54 -0
- package/dist/interface/crud/team-invitation.d.ts.map +1 -0
- package/dist/interface/crud/team-invitation.js +40 -0
- package/dist/interface/crud/team-invitation.js.map +1 -0
- package/dist/interface/crud/team-member-profiles.d.ts +286 -0
- package/dist/interface/crud/team-member-profiles.d.ts.map +1 -0
- package/dist/interface/crud/team-member-profiles.js +63 -0
- package/dist/interface/crud/team-member-profiles.js.map +1 -0
- package/dist/interface/crud/team-memberships.d.ts +75 -0
- package/dist/interface/crud/team-memberships.d.ts.map +1 -0
- package/dist/interface/crud/team-memberships.js +61 -0
- package/dist/interface/crud/team-memberships.js.map +1 -0
- package/dist/interface/crud/team-permissions.d.ts +169 -0
- package/dist/interface/crud/team-permissions.d.ts.map +1 -0
- package/dist/interface/crud/team-permissions.js +117 -0
- package/dist/interface/crud/team-permissions.js.map +1 -0
- package/dist/interface/crud/teams.d.ts +299 -0
- package/dist/interface/crud/teams.d.ts.map +1 -0
- package/dist/interface/crud/teams.js +142 -0
- package/dist/interface/crud/teams.js.map +1 -0
- package/dist/interface/crud/transactions.d.ts +183 -0
- package/dist/interface/crud/transactions.d.ts.map +1 -0
- package/dist/interface/crud/transactions.js +89 -0
- package/dist/interface/crud/transactions.js.map +1 -0
- package/dist/interface/crud/users.d.ts +653 -0
- package/dist/interface/crud/users.d.ts.map +1 -0
- package/dist/interface/crud/users.js +193 -0
- package/dist/interface/crud/users.js.map +1 -0
- package/dist/interface/handler-urls.d.ts +51 -0
- package/dist/interface/handler-urls.d.ts.map +1 -0
- package/dist/interface/handler-urls.js +16 -0
- package/dist/interface/page-component-versions.d.ts +25 -0
- package/dist/interface/page-component-versions.d.ts.map +1 -0
- package/dist/interface/page-component-versions.js +1664 -0
- package/dist/interface/page-component-versions.js.map +1 -0
- package/dist/interface/server-interface.d.ts +255 -0
- package/dist/interface/server-interface.d.ts.map +1 -0
- package/dist/interface/server-interface.js +461 -0
- package/dist/interface/server-interface.js.map +1 -0
- package/dist/interface/webhooks.d.ts +326 -0
- package/dist/interface/webhooks.d.ts.map +1 -0
- package/dist/interface/webhooks.js +24 -0
- package/dist/interface/webhooks.js.map +1 -0
- package/dist/known-errors.d.ts +575 -0
- package/dist/known-errors.d.ts.map +1 -0
- package/dist/known-errors.js +794 -0
- package/dist/known-errors.js.map +1 -0
- package/dist/local-emulator.d.ts +6 -0
- package/dist/local-emulator.d.ts.map +1 -0
- package/dist/local-emulator.js +10 -0
- package/dist/local-emulator.js.map +1 -0
- package/dist/payments/payment-methods.d.ts +64 -0
- package/dist/payments/payment-methods.d.ts.map +1 -0
- package/dist/payments/payment-methods.js +216 -0
- package/dist/payments/payment-methods.js.map +1 -0
- package/dist/payments/stripe-limits.d.ts +17 -0
- package/dist/payments/stripe-limits.d.ts.map +1 -0
- package/dist/payments/stripe-limits.js +20 -0
- package/dist/payments/stripe-limits.js.map +1 -0
- package/dist/plans.d.ts +72 -0
- package/dist/plans.d.ts.map +1 -0
- package/dist/plans.js +88 -0
- package/dist/plans.js.map +1 -0
- package/dist/schema-fields.d.ts +472 -0
- package/dist/schema-fields.d.ts.map +1 -0
- package/dist/schema-fields.js +1188 -0
- package/dist/schema-fields.js.map +1 -0
- package/dist/sessions.d.ts +165 -0
- package/dist/sessions.d.ts.map +1 -0
- package/dist/sessions.js +231 -0
- package/dist/sessions.js.map +1 -0
- package/dist/stack-config-file.d.ts +15 -0
- package/dist/stack-config-file.d.ts.map +1 -0
- package/dist/stack-config-file.js +82 -0
- package/dist/stack-config-file.js.map +1 -0
- package/dist/utils/api-keys.d.ts +26 -0
- package/dist/utils/api-keys.d.ts.map +1 -0
- package/dist/utils/api-keys.js +82 -0
- package/dist/utils/api-keys.js.map +1 -0
- package/dist/utils/arrays.d.ts +25 -0
- package/dist/utils/arrays.d.ts.map +1 -0
- package/dist/utils/arrays.js +569 -0
- package/dist/utils/arrays.js.map +1 -0
- package/dist/utils/auth-methods.d.ts +6 -0
- package/dist/utils/auth-methods.d.ts.map +1 -0
- package/dist/utils/auth-methods.js +13 -0
- package/dist/utils/auth-methods.js.map +1 -0
- package/dist/utils/base64.d.ts +6 -0
- package/dist/utils/base64.d.ts.map +1 -0
- package/dist/utils/base64.js +28 -0
- package/dist/utils/base64.js.map +1 -0
- package/dist/utils/booleans.d.ts +8 -0
- package/dist/utils/booleans.d.ts.map +1 -0
- package/dist/utils/booleans.js +38 -0
- package/dist/utils/booleans.js.map +1 -0
- package/dist/utils/browser-compat.d.ts +10 -0
- package/dist/utils/browser-compat.d.ts.map +1 -0
- package/dist/utils/browser-compat.js +23 -0
- package/dist/utils/browser-compat.js.map +1 -0
- package/dist/utils/bytes.d.ts +17 -0
- package/dist/utils/bytes.d.ts.map +1 -0
- package/dist/utils/bytes.js +304 -0
- package/dist/utils/bytes.js.map +1 -0
- package/dist/utils/caches.d.ts +102 -0
- package/dist/utils/caches.d.ts.map +1 -0
- package/dist/utils/caches.js +188 -0
- package/dist/utils/caches.js.map +1 -0
- package/dist/utils/cel-fields.d.ts +23 -0
- package/dist/utils/cel-fields.d.ts.map +1 -0
- package/dist/utils/cel-fields.js +108 -0
- package/dist/utils/cel-fields.js.map +1 -0
- package/dist/utils/compile-time.d.ts +10 -0
- package/dist/utils/compile-time.d.ts.map +1 -0
- package/dist/utils/compile-time.js +16 -0
- package/dist/utils/compile-time.js.map +1 -0
- package/dist/utils/country-codes.d.ts +11 -0
- package/dist/utils/country-codes.d.ts.map +1 -0
- package/dist/utils/country-codes.js +40 -0
- package/dist/utils/country-codes.js.map +1 -0
- package/dist/utils/crypto.d.ts +48 -0
- package/dist/utils/crypto.d.ts.map +1 -0
- package/dist/utils/crypto.js +215 -0
- package/dist/utils/crypto.js.map +1 -0
- package/dist/utils/currencies.d.ts +8 -0
- package/dist/utils/currencies.d.ts.map +1 -0
- package/dist/utils/currencies.js +52 -0
- package/dist/utils/currencies.js.map +1 -0
- package/dist/utils/currency-constants.d.ts +39 -0
- package/dist/utils/currency-constants.d.ts.map +1 -0
- package/dist/utils/currency-constants.js +44 -0
- package/dist/utils/currency-constants.js.map +1 -0
- package/dist/utils/dates.d.ts +23 -0
- package/dist/utils/dates.d.ts.map +1 -0
- package/dist/utils/dates.js +176 -0
- package/dist/utils/dates.js.map +1 -0
- package/dist/utils/dev-env-state-path.d.ts +6 -0
- package/dist/utils/dev-env-state-path.d.ts.map +1 -0
- package/dist/utils/dev-env-state-path.js +18 -0
- package/dist/utils/dev-env-state-path.js.map +1 -0
- package/dist/utils/dom.d.ts +5 -0
- package/dist/utils/dom.d.ts.map +1 -0
- package/dist/utils/dom.js +13 -0
- package/dist/utils/dom.js.map +1 -0
- package/dist/utils/env.d.ts +25 -0
- package/dist/utils/env.d.ts.map +1 -0
- package/dist/utils/env.js +85 -0
- package/dist/utils/env.js.map +1 -0
- package/dist/utils/errors.d.ts +231 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +393 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/esbuild.d.ts +16 -0
- package/dist/utils/esbuild.d.ts.map +1 -0
- package/dist/utils/esbuild.js +186 -0
- package/dist/utils/esbuild.js.map +1 -0
- package/dist/utils/featurebase.d.ts +30 -0
- package/dist/utils/featurebase.d.ts.map +1 -0
- package/dist/utils/featurebase.js +168 -0
- package/dist/utils/featurebase.js.map +1 -0
- package/dist/utils/fs.d.ts +9 -0
- package/dist/utils/fs.d.ts.map +1 -0
- package/dist/utils/fs.js +31 -0
- package/dist/utils/fs.js.map +1 -0
- package/dist/utils/functions.d.ts +6 -0
- package/dist/utils/functions.d.ts.map +1 -0
- package/dist/utils/functions.js +37 -0
- package/dist/utils/functions.js.map +1 -0
- package/dist/utils/geo.d.ts +24 -0
- package/dist/utils/geo.d.ts.map +1 -0
- package/dist/utils/geo.js +18 -0
- package/dist/utils/geo.js.map +1 -0
- package/dist/utils/globals.d.ts +13 -0
- package/dist/utils/globals.d.ts.map +1 -0
- package/dist/utils/globals.js +40 -0
- package/dist/utils/globals.js.map +1 -0
- package/dist/utils/hashes.d.ts +9 -0
- package/dist/utils/hashes.d.ts.map +1 -0
- package/dist/utils/hashes.js +47 -0
- package/dist/utils/hashes.js.map +1 -0
- package/dist/utils/html.d.ts +7 -0
- package/dist/utils/html.d.ts.map +1 -0
- package/dist/utils/html.js +37 -0
- package/dist/utils/html.js.map +1 -0
- package/dist/utils/http.d.ts +45 -0
- package/dist/utils/http.d.ts.map +1 -0
- package/dist/utils/http.js +79 -0
- package/dist/utils/http.js.map +1 -0
- package/dist/utils/ips.d.ts +8 -0
- package/dist/utils/ips.d.ts.map +1 -0
- package/dist/utils/ips.js +40 -0
- package/dist/utils/ips.js.map +1 -0
- package/dist/utils/json.d.ts +15 -0
- package/dist/utils/json.d.ts.map +1 -0
- package/dist/utils/json.js +182 -0
- package/dist/utils/json.js.map +1 -0
- package/dist/utils/jsx-editable-transpiler.d.ts +68 -0
- package/dist/utils/jsx-editable-transpiler.d.ts.map +1 -0
- package/dist/utils/jsx-editable-transpiler.js +223 -0
- package/dist/utils/jsx-editable-transpiler.js.map +1 -0
- package/dist/utils/jsx-editable-transpiler.test.d.ts +1 -0
- package/dist/utils/jsx-editable-transpiler.test.js +122 -0
- package/dist/utils/jsx-editable-transpiler.test.js.map +1 -0
- package/dist/utils/jwt.d.ts +79 -0
- package/dist/utils/jwt.d.ts.map +1 -0
- package/dist/utils/jwt.js +112 -0
- package/dist/utils/jwt.js.map +1 -0
- package/dist/utils/locks.d.ts +17 -0
- package/dist/utils/locks.d.ts.map +1 -0
- package/dist/utils/locks.js +56 -0
- package/dist/utils/locks.js.map +1 -0
- package/dist/utils/maps.d.ts +61 -0
- package/dist/utils/maps.d.ts.map +1 -0
- package/dist/utils/maps.js +302 -0
- package/dist/utils/maps.js.map +1 -0
- package/dist/utils/math.d.ts +8 -0
- package/dist/utils/math.d.ts.map +1 -0
- package/dist/utils/math.js +23 -0
- package/dist/utils/math.js.map +1 -0
- package/dist/utils/monkey-patch.d.ts +7 -0
- package/dist/utils/monkey-patch.d.ts.map +1 -0
- package/dist/utils/monkey-patch.js +25 -0
- package/dist/utils/monkey-patch.js.map +1 -0
- package/dist/utils/node-http.d.ts +17 -0
- package/dist/utils/node-http.d.ts.map +1 -0
- package/dist/utils/node-http.js +40 -0
- package/dist/utils/node-http.js.map +1 -0
- package/dist/utils/numbers.d.ts +7 -0
- package/dist/utils/numbers.d.ts.map +1 -0
- package/dist/utils/numbers.js +79 -0
- package/dist/utils/numbers.js.map +1 -0
- package/dist/utils/oauth.d.ts +11 -0
- package/dist/utils/oauth.d.ts.map +1 -0
- package/dist/utils/oauth.js +32 -0
- package/dist/utils/oauth.js.map +1 -0
- package/dist/utils/objects.d.ts +59 -0
- package/dist/utils/objects.d.ts.map +1 -0
- package/dist/utils/objects.js +846 -0
- package/dist/utils/objects.js.map +1 -0
- package/dist/utils/paginated-lists.d.ts +442 -0
- package/dist/utils/paginated-lists.d.ts.map +1 -0
- package/dist/utils/paginated-lists.js +414 -0
- package/dist/utils/paginated-lists.js.map +1 -0
- package/dist/utils/paginated-lists.test.d.ts +1 -0
- package/dist/utils/paginated-lists.test.js +1304 -0
- package/dist/utils/paginated-lists.test.js.map +1 -0
- package/dist/utils/passkey.d.ts +2 -0
- package/dist/utils/passkey.js +0 -0
- package/dist/utils/promises.d.ts +80 -0
- package/dist/utils/promises.d.ts.map +1 -0
- package/dist/utils/promises.js +349 -0
- package/dist/utils/promises.js.map +1 -0
- package/dist/utils/proxies.d.ts +13 -0
- package/dist/utils/proxies.d.ts.map +1 -0
- package/dist/utils/proxies.js +201 -0
- package/dist/utils/proxies.js.map +1 -0
- package/dist/utils/react.d.ts +61 -0
- package/dist/utils/react.d.ts.map +1 -0
- package/dist/utils/react.js +243 -0
- package/dist/utils/react.js.map +1 -0
- package/dist/utils/redirect-urls.d.ts +30 -0
- package/dist/utils/redirect-urls.d.ts.map +1 -0
- package/dist/utils/redirect-urls.js +222 -0
- package/dist/utils/redirect-urls.js.map +1 -0
- package/dist/utils/regex.d.ts +5 -0
- package/dist/utils/regex.d.ts.map +1 -0
- package/dist/utils/regex.js +15 -0
- package/dist/utils/regex.js.map +1 -0
- package/dist/utils/results.d.ts +70 -0
- package/dist/utils/results.d.ts.map +1 -0
- package/dist/utils/results.js +342 -0
- package/dist/utils/results.js.map +1 -0
- package/dist/utils/sentry.d.ts +13 -0
- package/dist/utils/sentry.d.ts.map +1 -0
- package/dist/utils/sentry.js +16 -0
- package/dist/utils/sentry.js.map +1 -0
- package/dist/utils/stores.d.ts +104 -0
- package/dist/utils/stores.d.ts.map +1 -0
- package/dist/utils/stores.js +179 -0
- package/dist/utils/stores.js.map +1 -0
- package/dist/utils/strings.d.ts +76 -0
- package/dist/utils/strings.d.ts.map +1 -0
- package/dist/utils/strings.js +549 -0
- package/dist/utils/strings.js.map +1 -0
- package/dist/utils/strings.nicify.test.d.ts +1 -0
- package/dist/utils/strings.nicify.test.js +243 -0
- package/dist/utils/strings.nicify.test.js.map +1 -0
- package/dist/utils/telemetry.d.ts +15 -0
- package/dist/utils/telemetry.d.ts.map +1 -0
- package/dist/utils/telemetry.js +35 -0
- package/dist/utils/telemetry.js.map +1 -0
- package/dist/utils/turnstile-browser.d.ts +32 -0
- package/dist/utils/turnstile-browser.d.ts.map +1 -0
- package/dist/utils/turnstile-browser.js +65 -0
- package/dist/utils/turnstile-browser.js.map +1 -0
- package/dist/utils/turnstile-flow.d.ts +29 -0
- package/dist/utils/turnstile-flow.d.ts.map +1 -0
- package/dist/utils/turnstile-flow.js +225 -0
- package/dist/utils/turnstile-flow.js.map +1 -0
- package/dist/utils/turnstile-flow.test.d.ts +1 -0
- package/dist/utils/turnstile-flow.test.js +75 -0
- package/dist/utils/turnstile-flow.test.js.map +1 -0
- package/dist/utils/turnstile.d.ts +17 -0
- package/dist/utils/turnstile.d.ts.map +1 -0
- package/dist/utils/turnstile.js +31 -0
- package/dist/utils/turnstile.js.map +1 -0
- package/dist/utils/typed-arrays.d.ts +14 -0
- package/dist/utils/typed-arrays.d.ts.map +1 -0
- package/dist/utils/typed-arrays.js +22 -0
- package/dist/utils/typed-arrays.js.map +1 -0
- package/dist/utils/types.d.ts +77 -0
- package/dist/utils/types.d.ts.map +1 -0
- package/dist/utils/types.js +59 -0
- package/dist/utils/types.js.map +1 -0
- package/dist/utils/unicode.d.ts +5 -0
- package/dist/utils/unicode.d.ts.map +1 -0
- package/dist/utils/unicode.js +26 -0
- package/dist/utils/unicode.js.map +1 -0
- package/dist/utils/urls.d.ts +28 -0
- package/dist/utils/urls.d.ts.map +1 -0
- package/dist/utils/urls.js +274 -0
- package/dist/utils/urls.js.map +1 -0
- package/dist/utils/uuids.d.ts +6 -0
- package/dist/utils/uuids.d.ts.map +1 -0
- package/dist/utils/uuids.js +39 -0
- package/dist/utils/uuids.js.map +1 -0
- package/package.json +99 -0
|
@@ -0,0 +1,1946 @@
|
|
|
1
|
+
import { HexclaveAssertionError, throwErr } from "../utils/errors.js";
|
|
2
|
+
import { filterUndefined, filterUndefinedOrNull } from "../utils/objects.js";
|
|
3
|
+
import { deindent } from "../utils/strings.js";
|
|
4
|
+
import { publishableClientKeyNotNecessarySentinel } from "../utils/oauth.js";
|
|
5
|
+
import { Result } from "../utils/results.js";
|
|
6
|
+
import { KnownError, KnownErrors } from "../known-errors.js";
|
|
7
|
+
import { urlString } from "../utils/urls.js";
|
|
8
|
+
import { AccessToken, InternalSession } from "../sessions.js";
|
|
9
|
+
import { generateSecureRandomString } from "../utils/crypto.js";
|
|
10
|
+
import { globalVar } from "../utils/globals.js";
|
|
11
|
+
import { HTTP_METHODS } from "../utils/http.js";
|
|
12
|
+
import { wait } from "../utils/promises.js";
|
|
13
|
+
|
|
14
|
+
//#region ../../node_modules/.pnpm/oauth4webapi@3.8.3/node_modules/oauth4webapi/build/index.js
|
|
15
|
+
let USER_AGENT;
|
|
16
|
+
if (typeof navigator === "undefined" || !navigator.userAgent?.startsWith?.("Mozilla/5.0 ")) USER_AGENT = `oauth4webapi/v3.8.3`;
|
|
17
|
+
function looseInstanceOf(input, expected) {
|
|
18
|
+
if (input == null) return false;
|
|
19
|
+
try {
|
|
20
|
+
return input instanceof expected || Object.getPrototypeOf(input)[Symbol.toStringTag] === expected.prototype[Symbol.toStringTag];
|
|
21
|
+
} catch {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
const ERR_INVALID_ARG_VALUE = "ERR_INVALID_ARG_VALUE";
|
|
26
|
+
const ERR_INVALID_ARG_TYPE = "ERR_INVALID_ARG_TYPE";
|
|
27
|
+
function CodedTypeError(message, code, cause) {
|
|
28
|
+
const err = new TypeError(message, { cause });
|
|
29
|
+
Object.assign(err, { code });
|
|
30
|
+
return err;
|
|
31
|
+
}
|
|
32
|
+
const allowInsecureRequests = Symbol();
|
|
33
|
+
const clockSkew = Symbol();
|
|
34
|
+
const clockTolerance = Symbol();
|
|
35
|
+
const customFetch = Symbol();
|
|
36
|
+
const jweDecrypt = Symbol();
|
|
37
|
+
const encoder = new TextEncoder();
|
|
38
|
+
const decoder = new TextDecoder();
|
|
39
|
+
function buf(input) {
|
|
40
|
+
if (typeof input === "string") return encoder.encode(input);
|
|
41
|
+
return decoder.decode(input);
|
|
42
|
+
}
|
|
43
|
+
let encodeBase64Url;
|
|
44
|
+
if (Uint8Array.prototype.toBase64) encodeBase64Url = (input) => {
|
|
45
|
+
if (input instanceof ArrayBuffer) input = new Uint8Array(input);
|
|
46
|
+
return input.toBase64({
|
|
47
|
+
alphabet: "base64url",
|
|
48
|
+
omitPadding: true
|
|
49
|
+
});
|
|
50
|
+
};
|
|
51
|
+
else {
|
|
52
|
+
const CHUNK_SIZE = 32768;
|
|
53
|
+
encodeBase64Url = (input) => {
|
|
54
|
+
if (input instanceof ArrayBuffer) input = new Uint8Array(input);
|
|
55
|
+
const arr = [];
|
|
56
|
+
for (let i = 0; i < input.byteLength; i += CHUNK_SIZE) arr.push(String.fromCharCode.apply(null, input.subarray(i, i + CHUNK_SIZE)));
|
|
57
|
+
return btoa(arr.join("")).replace(/=/g, "").replace(/\+/g, "-").replace(/\//g, "_");
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
let decodeBase64Url;
|
|
61
|
+
if (Uint8Array.fromBase64) decodeBase64Url = (input) => {
|
|
62
|
+
try {
|
|
63
|
+
return Uint8Array.fromBase64(input, { alphabet: "base64url" });
|
|
64
|
+
} catch (cause) {
|
|
65
|
+
throw CodedTypeError("The input to be decoded is not correctly encoded.", ERR_INVALID_ARG_VALUE, cause);
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
else decodeBase64Url = (input) => {
|
|
69
|
+
try {
|
|
70
|
+
const binary = atob(input.replace(/-/g, "+").replace(/_/g, "/").replace(/\s/g, ""));
|
|
71
|
+
const bytes = new Uint8Array(binary.length);
|
|
72
|
+
for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);
|
|
73
|
+
return bytes;
|
|
74
|
+
} catch (cause) {
|
|
75
|
+
throw CodedTypeError("The input to be decoded is not correctly encoded.", ERR_INVALID_ARG_VALUE, cause);
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
function b64u(input) {
|
|
79
|
+
if (typeof input === "string") return decodeBase64Url(input);
|
|
80
|
+
return encodeBase64Url(input);
|
|
81
|
+
}
|
|
82
|
+
var UnsupportedOperationError = class extends Error {
|
|
83
|
+
code;
|
|
84
|
+
constructor(message, options) {
|
|
85
|
+
super(message, options);
|
|
86
|
+
this.name = this.constructor.name;
|
|
87
|
+
this.code = UNSUPPORTED_OPERATION;
|
|
88
|
+
Error.captureStackTrace?.(this, this.constructor);
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
var OperationProcessingError = class extends Error {
|
|
92
|
+
code;
|
|
93
|
+
constructor(message, options) {
|
|
94
|
+
super(message, options);
|
|
95
|
+
this.name = this.constructor.name;
|
|
96
|
+
if (options?.code) this.code = options?.code;
|
|
97
|
+
Error.captureStackTrace?.(this, this.constructor);
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
function OPE(message, code, cause) {
|
|
101
|
+
return new OperationProcessingError(message, {
|
|
102
|
+
code,
|
|
103
|
+
cause
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
function isJsonObject(input) {
|
|
107
|
+
if (input === null || typeof input !== "object" || Array.isArray(input)) return false;
|
|
108
|
+
return true;
|
|
109
|
+
}
|
|
110
|
+
function prepareHeaders(input) {
|
|
111
|
+
if (looseInstanceOf(input, Headers)) input = Object.fromEntries(input.entries());
|
|
112
|
+
const headers = new Headers(input ?? {});
|
|
113
|
+
if (USER_AGENT && !headers.has("user-agent")) headers.set("user-agent", USER_AGENT);
|
|
114
|
+
if (headers.has("authorization")) throw CodedTypeError("\"options.headers\" must not include the \"authorization\" header name", ERR_INVALID_ARG_VALUE);
|
|
115
|
+
return headers;
|
|
116
|
+
}
|
|
117
|
+
function signal(url, value) {
|
|
118
|
+
if (value !== void 0) {
|
|
119
|
+
if (typeof value === "function") value = value(url.href);
|
|
120
|
+
if (!(value instanceof AbortSignal)) throw CodedTypeError("\"options.signal\" must return or be an instance of AbortSignal", ERR_INVALID_ARG_TYPE);
|
|
121
|
+
return value;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
function assertNumber(input, allow0, it, code, cause) {
|
|
125
|
+
try {
|
|
126
|
+
if (typeof input !== "number" || !Number.isFinite(input)) throw CodedTypeError(`${it} must be a number`, ERR_INVALID_ARG_TYPE, cause);
|
|
127
|
+
if (input > 0) return;
|
|
128
|
+
if (allow0) {
|
|
129
|
+
if (input !== 0) throw CodedTypeError(`${it} must be a non-negative number`, ERR_INVALID_ARG_VALUE, cause);
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
throw CodedTypeError(`${it} must be a positive number`, ERR_INVALID_ARG_VALUE, cause);
|
|
133
|
+
} catch (err) {
|
|
134
|
+
if (code) throw OPE(err.message, code, cause);
|
|
135
|
+
throw err;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
function assertString(input, it, code, cause) {
|
|
139
|
+
try {
|
|
140
|
+
if (typeof input !== "string") throw CodedTypeError(`${it} must be a string`, ERR_INVALID_ARG_TYPE, cause);
|
|
141
|
+
if (input.length === 0) throw CodedTypeError(`${it} must not be empty`, ERR_INVALID_ARG_VALUE, cause);
|
|
142
|
+
} catch (err) {
|
|
143
|
+
if (code) throw OPE(err.message, code, cause);
|
|
144
|
+
throw err;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
function assertApplicationJson(response) {
|
|
148
|
+
assertContentType(response, "application/json");
|
|
149
|
+
}
|
|
150
|
+
function notJson(response, ...types) {
|
|
151
|
+
let msg = "\"response\" content-type must be ";
|
|
152
|
+
if (types.length > 2) {
|
|
153
|
+
const last = types.pop();
|
|
154
|
+
msg += `${types.join(", ")}, or ${last}`;
|
|
155
|
+
} else if (types.length === 2) msg += `${types[0]} or ${types[1]}`;
|
|
156
|
+
else msg += types[0];
|
|
157
|
+
return OPE(msg, RESPONSE_IS_NOT_JSON, response);
|
|
158
|
+
}
|
|
159
|
+
function assertContentType(response, contentType) {
|
|
160
|
+
if (getContentType(response) !== contentType) throw notJson(response, contentType);
|
|
161
|
+
}
|
|
162
|
+
function getClockSkew(client) {
|
|
163
|
+
const skew = client?.[clockSkew];
|
|
164
|
+
return typeof skew === "number" && Number.isFinite(skew) ? skew : 0;
|
|
165
|
+
}
|
|
166
|
+
function getClockTolerance(client) {
|
|
167
|
+
const tolerance = client?.[clockTolerance];
|
|
168
|
+
return typeof tolerance === "number" && Number.isFinite(tolerance) && Math.sign(tolerance) !== -1 ? tolerance : 30;
|
|
169
|
+
}
|
|
170
|
+
function epochTime() {
|
|
171
|
+
return Math.floor(Date.now() / 1e3);
|
|
172
|
+
}
|
|
173
|
+
function assertAs(as) {
|
|
174
|
+
if (typeof as !== "object" || as === null) throw CodedTypeError("\"as\" must be an object", ERR_INVALID_ARG_TYPE);
|
|
175
|
+
assertString(as.issuer, "\"as.issuer\"");
|
|
176
|
+
}
|
|
177
|
+
function assertClient(client) {
|
|
178
|
+
if (typeof client !== "object" || client === null) throw CodedTypeError("\"client\" must be an object", ERR_INVALID_ARG_TYPE);
|
|
179
|
+
assertString(client.client_id, "\"client.client_id\"");
|
|
180
|
+
}
|
|
181
|
+
function ClientSecretPost(clientSecret) {
|
|
182
|
+
assertString(clientSecret, "\"clientSecret\"");
|
|
183
|
+
return (_as, client, body, _headers) => {
|
|
184
|
+
body.set("client_id", client.client_id);
|
|
185
|
+
body.set("client_secret", clientSecret);
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
const URLParse = URL.parse ? (url, base) => URL.parse(url, base) : (url, base) => {
|
|
189
|
+
try {
|
|
190
|
+
return new URL(url, base);
|
|
191
|
+
} catch {
|
|
192
|
+
return null;
|
|
193
|
+
}
|
|
194
|
+
};
|
|
195
|
+
function checkProtocol(url, enforceHttps) {
|
|
196
|
+
if (enforceHttps && url.protocol !== "https:") throw OPE("only requests to HTTPS are allowed", HTTP_REQUEST_FORBIDDEN, url);
|
|
197
|
+
if (url.protocol !== "https:" && url.protocol !== "http:") throw OPE("only HTTP and HTTPS requests are allowed", REQUEST_PROTOCOL_FORBIDDEN, url);
|
|
198
|
+
}
|
|
199
|
+
function validateEndpoint(value, endpoint, useMtlsAlias, enforceHttps) {
|
|
200
|
+
let url;
|
|
201
|
+
if (typeof value !== "string" || !(url = URLParse(value))) throw OPE(`authorization server metadata does not contain a valid ${useMtlsAlias ? `"as.mtls_endpoint_aliases.${endpoint}"` : `"as.${endpoint}"`}`, value === void 0 ? MISSING_SERVER_METADATA : INVALID_SERVER_METADATA, { attribute: useMtlsAlias ? `mtls_endpoint_aliases.${endpoint}` : endpoint });
|
|
202
|
+
checkProtocol(url, enforceHttps);
|
|
203
|
+
return url;
|
|
204
|
+
}
|
|
205
|
+
function resolveEndpoint(as, endpoint, useMtlsAlias, enforceHttps) {
|
|
206
|
+
if (useMtlsAlias && as.mtls_endpoint_aliases && endpoint in as.mtls_endpoint_aliases) return validateEndpoint(as.mtls_endpoint_aliases[endpoint], endpoint, useMtlsAlias, enforceHttps);
|
|
207
|
+
return validateEndpoint(as[endpoint], endpoint, useMtlsAlias, enforceHttps);
|
|
208
|
+
}
|
|
209
|
+
var ResponseBodyError = class extends Error {
|
|
210
|
+
cause;
|
|
211
|
+
code;
|
|
212
|
+
error;
|
|
213
|
+
status;
|
|
214
|
+
error_description;
|
|
215
|
+
response;
|
|
216
|
+
constructor(message, options) {
|
|
217
|
+
super(message, options);
|
|
218
|
+
this.name = this.constructor.name;
|
|
219
|
+
this.code = RESPONSE_BODY_ERROR;
|
|
220
|
+
this.cause = options.cause;
|
|
221
|
+
this.error = options.cause.error;
|
|
222
|
+
this.status = options.response.status;
|
|
223
|
+
this.error_description = options.cause.error_description;
|
|
224
|
+
Object.defineProperty(this, "response", {
|
|
225
|
+
enumerable: false,
|
|
226
|
+
value: options.response
|
|
227
|
+
});
|
|
228
|
+
Error.captureStackTrace?.(this, this.constructor);
|
|
229
|
+
}
|
|
230
|
+
};
|
|
231
|
+
var AuthorizationResponseError = class extends Error {
|
|
232
|
+
cause;
|
|
233
|
+
code;
|
|
234
|
+
error;
|
|
235
|
+
error_description;
|
|
236
|
+
constructor(message, options) {
|
|
237
|
+
super(message, options);
|
|
238
|
+
this.name = this.constructor.name;
|
|
239
|
+
this.code = AUTHORIZATION_RESPONSE_ERROR;
|
|
240
|
+
this.cause = options.cause;
|
|
241
|
+
this.error = options.cause.get("error");
|
|
242
|
+
this.error_description = options.cause.get("error_description") ?? void 0;
|
|
243
|
+
Error.captureStackTrace?.(this, this.constructor);
|
|
244
|
+
}
|
|
245
|
+
};
|
|
246
|
+
var WWWAuthenticateChallengeError = class extends Error {
|
|
247
|
+
cause;
|
|
248
|
+
code;
|
|
249
|
+
response;
|
|
250
|
+
status;
|
|
251
|
+
constructor(message, options) {
|
|
252
|
+
super(message, options);
|
|
253
|
+
this.name = this.constructor.name;
|
|
254
|
+
this.code = WWW_AUTHENTICATE_CHALLENGE;
|
|
255
|
+
this.cause = options.cause;
|
|
256
|
+
this.status = options.response.status;
|
|
257
|
+
this.response = options.response;
|
|
258
|
+
Object.defineProperty(this, "response", { enumerable: false });
|
|
259
|
+
Error.captureStackTrace?.(this, this.constructor);
|
|
260
|
+
}
|
|
261
|
+
};
|
|
262
|
+
const tokenMatch = "[a-zA-Z0-9!#$%&\\'\\*\\+\\-\\.\\^_`\\|~]+";
|
|
263
|
+
const token68Match = "[a-zA-Z0-9\\-\\._\\~\\+\\/]+={0,2}";
|
|
264
|
+
const quotedParamMatcher = "(" + tokenMatch + ")\\s*=\\s*\"((?:[^\"\\\\]|\\\\[\\s\\S])*)\"";
|
|
265
|
+
const paramMatcher = "(" + tokenMatch + ")\\s*=\\s*([a-zA-Z0-9!#$%&\\'\\*\\+\\-\\.\\^_`\\|~]+)";
|
|
266
|
+
const schemeRE = new RegExp("^[,\\s]*(" + tokenMatch + ")");
|
|
267
|
+
const quotedParamRE = new RegExp("^[,\\s]*" + quotedParamMatcher + "[,\\s]*(.*)");
|
|
268
|
+
const unquotedParamRE = new RegExp("^[,\\s]*" + paramMatcher + "[,\\s]*(.*)");
|
|
269
|
+
const token68ParamRE = new RegExp("^(" + token68Match + ")(?:$|[,\\s])(.*)");
|
|
270
|
+
function parseWwwAuthenticateChallenges(response) {
|
|
271
|
+
if (!looseInstanceOf(response, Response)) throw CodedTypeError("\"response\" must be an instance of Response", ERR_INVALID_ARG_TYPE);
|
|
272
|
+
const header = response.headers.get("www-authenticate");
|
|
273
|
+
if (header === null) return;
|
|
274
|
+
const challenges = [];
|
|
275
|
+
let rest = header;
|
|
276
|
+
while (rest) {
|
|
277
|
+
let match = rest.match(schemeRE);
|
|
278
|
+
const scheme = match?.["1"].toLowerCase();
|
|
279
|
+
if (!scheme) return;
|
|
280
|
+
const afterScheme = rest.substring(match[0].length);
|
|
281
|
+
if (afterScheme && !afterScheme.match(/^[\s,]/)) return;
|
|
282
|
+
const spaceMatch = afterScheme.match(/^\s+(.*)$/);
|
|
283
|
+
const hasParameters = !!spaceMatch;
|
|
284
|
+
rest = spaceMatch ? spaceMatch[1] : void 0;
|
|
285
|
+
const parameters = {};
|
|
286
|
+
let token68;
|
|
287
|
+
if (hasParameters) while (rest) {
|
|
288
|
+
let key;
|
|
289
|
+
let value;
|
|
290
|
+
if (match = rest.match(quotedParamRE)) {
|
|
291
|
+
[, key, value, rest] = match;
|
|
292
|
+
if (value.includes("\\")) try {
|
|
293
|
+
value = JSON.parse(`"${value}"`);
|
|
294
|
+
} catch {}
|
|
295
|
+
parameters[key.toLowerCase()] = value;
|
|
296
|
+
continue;
|
|
297
|
+
}
|
|
298
|
+
if (match = rest.match(unquotedParamRE)) {
|
|
299
|
+
[, key, value, rest] = match;
|
|
300
|
+
parameters[key.toLowerCase()] = value;
|
|
301
|
+
continue;
|
|
302
|
+
}
|
|
303
|
+
if (match = rest.match(token68ParamRE)) {
|
|
304
|
+
if (Object.keys(parameters).length) break;
|
|
305
|
+
[, token68, rest] = match;
|
|
306
|
+
break;
|
|
307
|
+
}
|
|
308
|
+
return;
|
|
309
|
+
}
|
|
310
|
+
else rest = afterScheme || void 0;
|
|
311
|
+
const challenge = {
|
|
312
|
+
scheme,
|
|
313
|
+
parameters
|
|
314
|
+
};
|
|
315
|
+
if (token68) challenge.token68 = token68;
|
|
316
|
+
challenges.push(challenge);
|
|
317
|
+
}
|
|
318
|
+
if (!challenges.length) return;
|
|
319
|
+
return challenges;
|
|
320
|
+
}
|
|
321
|
+
async function parseOAuthResponseErrorBody(response) {
|
|
322
|
+
if (response.status > 399 && response.status < 500) {
|
|
323
|
+
assertReadableResponse(response);
|
|
324
|
+
assertApplicationJson(response);
|
|
325
|
+
try {
|
|
326
|
+
const json = await response.clone().json();
|
|
327
|
+
if (isJsonObject(json) && typeof json.error === "string" && json.error.length) return json;
|
|
328
|
+
} catch {}
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
async function checkOAuthBodyError(response, expected, label) {
|
|
332
|
+
if (response.status !== expected) {
|
|
333
|
+
checkAuthenticationChallenges(response);
|
|
334
|
+
let err;
|
|
335
|
+
if (err = await parseOAuthResponseErrorBody(response)) {
|
|
336
|
+
await response.body?.cancel();
|
|
337
|
+
throw new ResponseBodyError("server responded with an error in the response body", {
|
|
338
|
+
cause: err,
|
|
339
|
+
response
|
|
340
|
+
});
|
|
341
|
+
}
|
|
342
|
+
throw OPE(`"response" is not a conform ${label} response (unexpected HTTP status code)`, RESPONSE_IS_NOT_CONFORM, response);
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
function assertDPoP(option) {
|
|
346
|
+
if (!branded.has(option)) throw CodedTypeError("\"options.DPoP\" is not a valid DPoPHandle", ERR_INVALID_ARG_VALUE);
|
|
347
|
+
}
|
|
348
|
+
function getContentType(input) {
|
|
349
|
+
return input.headers.get("content-type")?.split(";")[0];
|
|
350
|
+
}
|
|
351
|
+
async function authenticatedRequest(as, client, clientAuthentication, url, body, headers, options) {
|
|
352
|
+
await clientAuthentication(as, client, body, headers);
|
|
353
|
+
headers.set("content-type", "application/x-www-form-urlencoded;charset=UTF-8");
|
|
354
|
+
return (options?.[customFetch] || fetch)(url.href, {
|
|
355
|
+
body,
|
|
356
|
+
headers: Object.fromEntries(headers.entries()),
|
|
357
|
+
method: "POST",
|
|
358
|
+
redirect: "manual",
|
|
359
|
+
signal: signal(url, options?.signal)
|
|
360
|
+
});
|
|
361
|
+
}
|
|
362
|
+
async function tokenEndpointRequest(as, client, clientAuthentication, grantType, parameters, options) {
|
|
363
|
+
const url = resolveEndpoint(as, "token_endpoint", client.use_mtls_endpoint_aliases, options?.[allowInsecureRequests] !== true);
|
|
364
|
+
parameters.set("grant_type", grantType);
|
|
365
|
+
const headers = prepareHeaders(options?.headers);
|
|
366
|
+
headers.set("accept", "application/json");
|
|
367
|
+
if (options?.DPoP !== void 0) {
|
|
368
|
+
assertDPoP(options.DPoP);
|
|
369
|
+
await options.DPoP.addProof(url, headers, "POST");
|
|
370
|
+
}
|
|
371
|
+
const response = await authenticatedRequest(as, client, clientAuthentication, url, parameters, headers, options);
|
|
372
|
+
options?.DPoP?.cacheNonce(response, url);
|
|
373
|
+
return response;
|
|
374
|
+
}
|
|
375
|
+
async function refreshTokenGrantRequest(as, client, clientAuthentication, refreshToken, options) {
|
|
376
|
+
assertAs(as);
|
|
377
|
+
assertClient(client);
|
|
378
|
+
assertString(refreshToken, "\"refreshToken\"");
|
|
379
|
+
const parameters = new URLSearchParams(options?.additionalParameters);
|
|
380
|
+
parameters.set("refresh_token", refreshToken);
|
|
381
|
+
return tokenEndpointRequest(as, client, clientAuthentication, "refresh_token", parameters, options);
|
|
382
|
+
}
|
|
383
|
+
const idTokenClaims = /* @__PURE__ */ new WeakMap();
|
|
384
|
+
const jwtRefs = /* @__PURE__ */ new WeakMap();
|
|
385
|
+
function getValidatedIdTokenClaims(ref) {
|
|
386
|
+
if (!ref.id_token) return;
|
|
387
|
+
const claims = idTokenClaims.get(ref);
|
|
388
|
+
if (!claims) throw CodedTypeError("\"ref\" was already garbage collected or did not resolve from the proper sources", ERR_INVALID_ARG_VALUE);
|
|
389
|
+
return claims;
|
|
390
|
+
}
|
|
391
|
+
async function processGenericAccessTokenResponse(as, client, response, additionalRequiredIdTokenClaims, decryptFn, recognizedTokenTypes) {
|
|
392
|
+
assertAs(as);
|
|
393
|
+
assertClient(client);
|
|
394
|
+
if (!looseInstanceOf(response, Response)) throw CodedTypeError("\"response\" must be an instance of Response", ERR_INVALID_ARG_TYPE);
|
|
395
|
+
await checkOAuthBodyError(response, 200, "Token Endpoint");
|
|
396
|
+
assertReadableResponse(response);
|
|
397
|
+
const json = await getResponseJsonBody(response);
|
|
398
|
+
assertString(json.access_token, "\"response\" body \"access_token\" property", INVALID_RESPONSE, { body: json });
|
|
399
|
+
assertString(json.token_type, "\"response\" body \"token_type\" property", INVALID_RESPONSE, { body: json });
|
|
400
|
+
json.token_type = json.token_type.toLowerCase();
|
|
401
|
+
if (json.expires_in !== void 0) {
|
|
402
|
+
let expiresIn = typeof json.expires_in !== "number" ? parseFloat(json.expires_in) : json.expires_in;
|
|
403
|
+
assertNumber(expiresIn, true, "\"response\" body \"expires_in\" property", INVALID_RESPONSE, { body: json });
|
|
404
|
+
json.expires_in = expiresIn;
|
|
405
|
+
}
|
|
406
|
+
if (json.refresh_token !== void 0) assertString(json.refresh_token, "\"response\" body \"refresh_token\" property", INVALID_RESPONSE, { body: json });
|
|
407
|
+
if (json.scope !== void 0 && typeof json.scope !== "string") throw OPE("\"response\" body \"scope\" property must be a string", INVALID_RESPONSE, { body: json });
|
|
408
|
+
if (json.id_token !== void 0) {
|
|
409
|
+
assertString(json.id_token, "\"response\" body \"id_token\" property", INVALID_RESPONSE, { body: json });
|
|
410
|
+
const requiredClaims = [
|
|
411
|
+
"aud",
|
|
412
|
+
"exp",
|
|
413
|
+
"iat",
|
|
414
|
+
"iss",
|
|
415
|
+
"sub"
|
|
416
|
+
];
|
|
417
|
+
if (client.require_auth_time === true) requiredClaims.push("auth_time");
|
|
418
|
+
if (client.default_max_age !== void 0) {
|
|
419
|
+
assertNumber(client.default_max_age, true, "\"client.default_max_age\"");
|
|
420
|
+
requiredClaims.push("auth_time");
|
|
421
|
+
}
|
|
422
|
+
if (additionalRequiredIdTokenClaims?.length) requiredClaims.push(...additionalRequiredIdTokenClaims);
|
|
423
|
+
const { claims, jwt } = await validateJwt(json.id_token, checkSigningAlgorithm.bind(void 0, client.id_token_signed_response_alg, as.id_token_signing_alg_values_supported, "RS256"), getClockSkew(client), getClockTolerance(client), decryptFn).then(validatePresence.bind(void 0, requiredClaims)).then(validateIssuer.bind(void 0, as)).then(validateAudience.bind(void 0, client.client_id));
|
|
424
|
+
if (Array.isArray(claims.aud) && claims.aud.length !== 1) {
|
|
425
|
+
if (claims.azp === void 0) throw OPE("ID Token \"aud\" (audience) claim includes additional untrusted audiences", JWT_CLAIM_COMPARISON, {
|
|
426
|
+
claims,
|
|
427
|
+
claim: "aud"
|
|
428
|
+
});
|
|
429
|
+
if (claims.azp !== client.client_id) throw OPE("unexpected ID Token \"azp\" (authorized party) claim value", JWT_CLAIM_COMPARISON, {
|
|
430
|
+
expected: client.client_id,
|
|
431
|
+
claims,
|
|
432
|
+
claim: "azp"
|
|
433
|
+
});
|
|
434
|
+
}
|
|
435
|
+
if (claims.auth_time !== void 0) assertNumber(claims.auth_time, true, "ID Token \"auth_time\" (authentication time)", INVALID_RESPONSE, { claims });
|
|
436
|
+
jwtRefs.set(response, jwt);
|
|
437
|
+
idTokenClaims.set(json, claims);
|
|
438
|
+
}
|
|
439
|
+
if (recognizedTokenTypes?.[json.token_type] !== void 0) recognizedTokenTypes[json.token_type](response, json);
|
|
440
|
+
else if (json.token_type !== "dpop" && json.token_type !== "bearer") throw new UnsupportedOperationError("unsupported `token_type` value", { cause: { body: json } });
|
|
441
|
+
return json;
|
|
442
|
+
}
|
|
443
|
+
function checkAuthenticationChallenges(response) {
|
|
444
|
+
let challenges;
|
|
445
|
+
if (challenges = parseWwwAuthenticateChallenges(response)) throw new WWWAuthenticateChallengeError("server responded with a challenge in the WWW-Authenticate HTTP Header", {
|
|
446
|
+
cause: challenges,
|
|
447
|
+
response
|
|
448
|
+
});
|
|
449
|
+
}
|
|
450
|
+
async function processRefreshTokenResponse(as, client, response, options) {
|
|
451
|
+
return processGenericAccessTokenResponse(as, client, response, void 0, options?.[jweDecrypt], options?.recognizedTokenTypes);
|
|
452
|
+
}
|
|
453
|
+
function validateAudience(expected, result) {
|
|
454
|
+
if (Array.isArray(result.claims.aud)) {
|
|
455
|
+
if (!result.claims.aud.includes(expected)) throw OPE("unexpected JWT \"aud\" (audience) claim value", JWT_CLAIM_COMPARISON, {
|
|
456
|
+
expected,
|
|
457
|
+
claims: result.claims,
|
|
458
|
+
claim: "aud"
|
|
459
|
+
});
|
|
460
|
+
} else if (result.claims.aud !== expected) throw OPE("unexpected JWT \"aud\" (audience) claim value", JWT_CLAIM_COMPARISON, {
|
|
461
|
+
expected,
|
|
462
|
+
claims: result.claims,
|
|
463
|
+
claim: "aud"
|
|
464
|
+
});
|
|
465
|
+
return result;
|
|
466
|
+
}
|
|
467
|
+
function validateIssuer(as, result) {
|
|
468
|
+
const expected = as[_expectedIssuer]?.(result) ?? as.issuer;
|
|
469
|
+
if (result.claims.iss !== expected) throw OPE("unexpected JWT \"iss\" (issuer) claim value", JWT_CLAIM_COMPARISON, {
|
|
470
|
+
expected,
|
|
471
|
+
claims: result.claims,
|
|
472
|
+
claim: "iss"
|
|
473
|
+
});
|
|
474
|
+
return result;
|
|
475
|
+
}
|
|
476
|
+
const branded = /* @__PURE__ */ new WeakSet();
|
|
477
|
+
function brand(searchParams) {
|
|
478
|
+
branded.add(searchParams);
|
|
479
|
+
return searchParams;
|
|
480
|
+
}
|
|
481
|
+
const nopkce = Symbol();
|
|
482
|
+
async function authorizationCodeGrantRequest(as, client, clientAuthentication, callbackParameters, redirectUri, codeVerifier, options) {
|
|
483
|
+
assertAs(as);
|
|
484
|
+
assertClient(client);
|
|
485
|
+
if (!branded.has(callbackParameters)) throw CodedTypeError("\"callbackParameters\" must be an instance of URLSearchParams obtained from \"validateAuthResponse()\", or \"validateJwtAuthResponse()", ERR_INVALID_ARG_VALUE);
|
|
486
|
+
assertString(redirectUri, "\"redirectUri\"");
|
|
487
|
+
const code = getURLSearchParameter(callbackParameters, "code");
|
|
488
|
+
if (!code) throw OPE("no authorization code in \"callbackParameters\"", INVALID_RESPONSE);
|
|
489
|
+
const parameters = new URLSearchParams(options?.additionalParameters);
|
|
490
|
+
parameters.set("redirect_uri", redirectUri);
|
|
491
|
+
parameters.set("code", code);
|
|
492
|
+
if (codeVerifier !== nopkce) {
|
|
493
|
+
assertString(codeVerifier, "\"codeVerifier\"");
|
|
494
|
+
parameters.set("code_verifier", codeVerifier);
|
|
495
|
+
}
|
|
496
|
+
return tokenEndpointRequest(as, client, clientAuthentication, "authorization_code", parameters, options);
|
|
497
|
+
}
|
|
498
|
+
const jwtClaimNames = {
|
|
499
|
+
aud: "audience",
|
|
500
|
+
c_hash: "code hash",
|
|
501
|
+
client_id: "client id",
|
|
502
|
+
exp: "expiration time",
|
|
503
|
+
iat: "issued at",
|
|
504
|
+
iss: "issuer",
|
|
505
|
+
jti: "jwt id",
|
|
506
|
+
nonce: "nonce",
|
|
507
|
+
s_hash: "state hash",
|
|
508
|
+
sub: "subject",
|
|
509
|
+
ath: "access token hash",
|
|
510
|
+
htm: "http method",
|
|
511
|
+
htu: "http uri",
|
|
512
|
+
cnf: "confirmation",
|
|
513
|
+
auth_time: "authentication time"
|
|
514
|
+
};
|
|
515
|
+
function validatePresence(required, result) {
|
|
516
|
+
for (const claim of required) if (result.claims[claim] === void 0) throw OPE(`JWT "${claim}" (${jwtClaimNames[claim]}) claim missing`, INVALID_RESPONSE, { claims: result.claims });
|
|
517
|
+
return result;
|
|
518
|
+
}
|
|
519
|
+
const expectNoNonce = Symbol();
|
|
520
|
+
const skipAuthTimeCheck = Symbol();
|
|
521
|
+
async function processAuthorizationCodeResponse(as, client, response, options) {
|
|
522
|
+
if (typeof options?.expectedNonce === "string" || typeof options?.maxAge === "number" || options?.requireIdToken) return processAuthorizationCodeOpenIDResponse(as, client, response, options.expectedNonce, options.maxAge, options[jweDecrypt], options.recognizedTokenTypes);
|
|
523
|
+
return processAuthorizationCodeOAuth2Response(as, client, response, options?.[jweDecrypt], options?.recognizedTokenTypes);
|
|
524
|
+
}
|
|
525
|
+
async function processAuthorizationCodeOpenIDResponse(as, client, response, expectedNonce, maxAge, decryptFn, recognizedTokenTypes) {
|
|
526
|
+
const additionalRequiredClaims = [];
|
|
527
|
+
switch (expectedNonce) {
|
|
528
|
+
case void 0:
|
|
529
|
+
expectedNonce = expectNoNonce;
|
|
530
|
+
break;
|
|
531
|
+
case expectNoNonce: break;
|
|
532
|
+
default:
|
|
533
|
+
assertString(expectedNonce, "\"expectedNonce\" argument");
|
|
534
|
+
additionalRequiredClaims.push("nonce");
|
|
535
|
+
}
|
|
536
|
+
maxAge ??= client.default_max_age;
|
|
537
|
+
switch (maxAge) {
|
|
538
|
+
case void 0:
|
|
539
|
+
maxAge = skipAuthTimeCheck;
|
|
540
|
+
break;
|
|
541
|
+
case skipAuthTimeCheck: break;
|
|
542
|
+
default:
|
|
543
|
+
assertNumber(maxAge, true, "\"maxAge\" argument");
|
|
544
|
+
additionalRequiredClaims.push("auth_time");
|
|
545
|
+
}
|
|
546
|
+
const result = await processGenericAccessTokenResponse(as, client, response, additionalRequiredClaims, decryptFn, recognizedTokenTypes);
|
|
547
|
+
assertString(result.id_token, "\"response\" body \"id_token\" property", INVALID_RESPONSE, { body: result });
|
|
548
|
+
const claims = getValidatedIdTokenClaims(result);
|
|
549
|
+
if (maxAge !== skipAuthTimeCheck) {
|
|
550
|
+
const now = epochTime() + getClockSkew(client);
|
|
551
|
+
const tolerance = getClockTolerance(client);
|
|
552
|
+
if (claims.auth_time + maxAge < now - tolerance) throw OPE("too much time has elapsed since the last End-User authentication", JWT_TIMESTAMP_CHECK, {
|
|
553
|
+
claims,
|
|
554
|
+
now,
|
|
555
|
+
tolerance,
|
|
556
|
+
claim: "auth_time"
|
|
557
|
+
});
|
|
558
|
+
}
|
|
559
|
+
if (expectedNonce === expectNoNonce) {
|
|
560
|
+
if (claims.nonce !== void 0) throw OPE("unexpected ID Token \"nonce\" claim value", JWT_CLAIM_COMPARISON, {
|
|
561
|
+
expected: void 0,
|
|
562
|
+
claims,
|
|
563
|
+
claim: "nonce"
|
|
564
|
+
});
|
|
565
|
+
} else if (claims.nonce !== expectedNonce) throw OPE("unexpected ID Token \"nonce\" claim value", JWT_CLAIM_COMPARISON, {
|
|
566
|
+
expected: expectedNonce,
|
|
567
|
+
claims,
|
|
568
|
+
claim: "nonce"
|
|
569
|
+
});
|
|
570
|
+
return result;
|
|
571
|
+
}
|
|
572
|
+
async function processAuthorizationCodeOAuth2Response(as, client, response, decryptFn, recognizedTokenTypes) {
|
|
573
|
+
const result = await processGenericAccessTokenResponse(as, client, response, void 0, decryptFn, recognizedTokenTypes);
|
|
574
|
+
const claims = getValidatedIdTokenClaims(result);
|
|
575
|
+
if (claims) {
|
|
576
|
+
if (client.default_max_age !== void 0) {
|
|
577
|
+
assertNumber(client.default_max_age, true, "\"client.default_max_age\"");
|
|
578
|
+
const now = epochTime() + getClockSkew(client);
|
|
579
|
+
const tolerance = getClockTolerance(client);
|
|
580
|
+
if (claims.auth_time + client.default_max_age < now - tolerance) throw OPE("too much time has elapsed since the last End-User authentication", JWT_TIMESTAMP_CHECK, {
|
|
581
|
+
claims,
|
|
582
|
+
now,
|
|
583
|
+
tolerance,
|
|
584
|
+
claim: "auth_time"
|
|
585
|
+
});
|
|
586
|
+
}
|
|
587
|
+
if (claims.nonce !== void 0) throw OPE("unexpected ID Token \"nonce\" claim value", JWT_CLAIM_COMPARISON, {
|
|
588
|
+
expected: void 0,
|
|
589
|
+
claims,
|
|
590
|
+
claim: "nonce"
|
|
591
|
+
});
|
|
592
|
+
}
|
|
593
|
+
return result;
|
|
594
|
+
}
|
|
595
|
+
const WWW_AUTHENTICATE_CHALLENGE = "OAUTH_WWW_AUTHENTICATE_CHALLENGE";
|
|
596
|
+
const RESPONSE_BODY_ERROR = "OAUTH_RESPONSE_BODY_ERROR";
|
|
597
|
+
const UNSUPPORTED_OPERATION = "OAUTH_UNSUPPORTED_OPERATION";
|
|
598
|
+
const AUTHORIZATION_RESPONSE_ERROR = "OAUTH_AUTHORIZATION_RESPONSE_ERROR";
|
|
599
|
+
const PARSE_ERROR = "OAUTH_PARSE_ERROR";
|
|
600
|
+
const INVALID_RESPONSE = "OAUTH_INVALID_RESPONSE";
|
|
601
|
+
const RESPONSE_IS_NOT_JSON = "OAUTH_RESPONSE_IS_NOT_JSON";
|
|
602
|
+
const RESPONSE_IS_NOT_CONFORM = "OAUTH_RESPONSE_IS_NOT_CONFORM";
|
|
603
|
+
const HTTP_REQUEST_FORBIDDEN = "OAUTH_HTTP_REQUEST_FORBIDDEN";
|
|
604
|
+
const REQUEST_PROTOCOL_FORBIDDEN = "OAUTH_REQUEST_PROTOCOL_FORBIDDEN";
|
|
605
|
+
const JWT_TIMESTAMP_CHECK = "OAUTH_JWT_TIMESTAMP_CHECK_FAILED";
|
|
606
|
+
const JWT_CLAIM_COMPARISON = "OAUTH_JWT_CLAIM_COMPARISON_FAILED";
|
|
607
|
+
const MISSING_SERVER_METADATA = "OAUTH_MISSING_SERVER_METADATA";
|
|
608
|
+
const INVALID_SERVER_METADATA = "OAUTH_INVALID_SERVER_METADATA";
|
|
609
|
+
function assertReadableResponse(response) {
|
|
610
|
+
if (response.bodyUsed) throw CodedTypeError("\"response\" body has been used already", ERR_INVALID_ARG_VALUE);
|
|
611
|
+
}
|
|
612
|
+
async function validateJwt(jws, checkAlg, clockSkew, clockTolerance, decryptJwt) {
|
|
613
|
+
let { 0: protectedHeader, 1: payload, length } = jws.split(".");
|
|
614
|
+
if (length === 5) if (decryptJwt !== void 0) {
|
|
615
|
+
jws = await decryptJwt(jws);
|
|
616
|
+
({0: protectedHeader, 1: payload, length} = jws.split("."));
|
|
617
|
+
} else throw new UnsupportedOperationError("JWE decryption is not configured", { cause: jws });
|
|
618
|
+
if (length !== 3) throw OPE("Invalid JWT", INVALID_RESPONSE, jws);
|
|
619
|
+
let header;
|
|
620
|
+
try {
|
|
621
|
+
header = JSON.parse(buf(b64u(protectedHeader)));
|
|
622
|
+
} catch (cause) {
|
|
623
|
+
throw OPE("failed to parse JWT Header body as base64url encoded JSON", PARSE_ERROR, cause);
|
|
624
|
+
}
|
|
625
|
+
if (!isJsonObject(header)) throw OPE("JWT Header must be a top level object", INVALID_RESPONSE, jws);
|
|
626
|
+
checkAlg(header);
|
|
627
|
+
if (header.crit !== void 0) throw new UnsupportedOperationError("no JWT \"crit\" header parameter extensions are supported", { cause: { header } });
|
|
628
|
+
let claims;
|
|
629
|
+
try {
|
|
630
|
+
claims = JSON.parse(buf(b64u(payload)));
|
|
631
|
+
} catch (cause) {
|
|
632
|
+
throw OPE("failed to parse JWT Payload body as base64url encoded JSON", PARSE_ERROR, cause);
|
|
633
|
+
}
|
|
634
|
+
if (!isJsonObject(claims)) throw OPE("JWT Payload must be a top level object", INVALID_RESPONSE, jws);
|
|
635
|
+
const now = epochTime() + clockSkew;
|
|
636
|
+
if (claims.exp !== void 0) {
|
|
637
|
+
if (typeof claims.exp !== "number") throw OPE("unexpected JWT \"exp\" (expiration time) claim type", INVALID_RESPONSE, { claims });
|
|
638
|
+
if (claims.exp <= now - clockTolerance) throw OPE("unexpected JWT \"exp\" (expiration time) claim value, expiration is past current timestamp", JWT_TIMESTAMP_CHECK, {
|
|
639
|
+
claims,
|
|
640
|
+
now,
|
|
641
|
+
tolerance: clockTolerance,
|
|
642
|
+
claim: "exp"
|
|
643
|
+
});
|
|
644
|
+
}
|
|
645
|
+
if (claims.iat !== void 0) {
|
|
646
|
+
if (typeof claims.iat !== "number") throw OPE("unexpected JWT \"iat\" (issued at) claim type", INVALID_RESPONSE, { claims });
|
|
647
|
+
}
|
|
648
|
+
if (claims.iss !== void 0) {
|
|
649
|
+
if (typeof claims.iss !== "string") throw OPE("unexpected JWT \"iss\" (issuer) claim type", INVALID_RESPONSE, { claims });
|
|
650
|
+
}
|
|
651
|
+
if (claims.nbf !== void 0) {
|
|
652
|
+
if (typeof claims.nbf !== "number") throw OPE("unexpected JWT \"nbf\" (not before) claim type", INVALID_RESPONSE, { claims });
|
|
653
|
+
if (claims.nbf > now + clockTolerance) throw OPE("unexpected JWT \"nbf\" (not before) claim value", JWT_TIMESTAMP_CHECK, {
|
|
654
|
+
claims,
|
|
655
|
+
now,
|
|
656
|
+
tolerance: clockTolerance,
|
|
657
|
+
claim: "nbf"
|
|
658
|
+
});
|
|
659
|
+
}
|
|
660
|
+
if (claims.aud !== void 0) {
|
|
661
|
+
if (typeof claims.aud !== "string" && !Array.isArray(claims.aud)) throw OPE("unexpected JWT \"aud\" (audience) claim type", INVALID_RESPONSE, { claims });
|
|
662
|
+
}
|
|
663
|
+
return {
|
|
664
|
+
header,
|
|
665
|
+
claims,
|
|
666
|
+
jwt: jws
|
|
667
|
+
};
|
|
668
|
+
}
|
|
669
|
+
function checkSigningAlgorithm(client, issuer, fallback, header) {
|
|
670
|
+
if (client !== void 0) {
|
|
671
|
+
if (typeof client === "string" ? header.alg !== client : !client.includes(header.alg)) throw OPE("unexpected JWT \"alg\" header parameter", INVALID_RESPONSE, {
|
|
672
|
+
header,
|
|
673
|
+
expected: client,
|
|
674
|
+
reason: "client configuration"
|
|
675
|
+
});
|
|
676
|
+
return;
|
|
677
|
+
}
|
|
678
|
+
if (Array.isArray(issuer)) {
|
|
679
|
+
if (!issuer.includes(header.alg)) throw OPE("unexpected JWT \"alg\" header parameter", INVALID_RESPONSE, {
|
|
680
|
+
header,
|
|
681
|
+
expected: issuer,
|
|
682
|
+
reason: "authorization server metadata"
|
|
683
|
+
});
|
|
684
|
+
return;
|
|
685
|
+
}
|
|
686
|
+
if (fallback !== void 0) {
|
|
687
|
+
if (typeof fallback === "string" ? header.alg !== fallback : typeof fallback === "function" ? !fallback(header.alg) : !fallback.includes(header.alg)) throw OPE("unexpected JWT \"alg\" header parameter", INVALID_RESPONSE, {
|
|
688
|
+
header,
|
|
689
|
+
expected: fallback,
|
|
690
|
+
reason: "default value"
|
|
691
|
+
});
|
|
692
|
+
return;
|
|
693
|
+
}
|
|
694
|
+
throw OPE("missing client or server configuration to verify used JWT \"alg\" header parameter", void 0, {
|
|
695
|
+
client,
|
|
696
|
+
issuer,
|
|
697
|
+
fallback
|
|
698
|
+
});
|
|
699
|
+
}
|
|
700
|
+
function getURLSearchParameter(parameters, name) {
|
|
701
|
+
const { 0: value, length } = parameters.getAll(name);
|
|
702
|
+
if (length > 1) throw OPE(`"${name}" parameter must be provided only once`, INVALID_RESPONSE);
|
|
703
|
+
return value;
|
|
704
|
+
}
|
|
705
|
+
const skipStateCheck = Symbol();
|
|
706
|
+
const expectNoState = Symbol();
|
|
707
|
+
function validateAuthResponse(as, client, parameters, expectedState) {
|
|
708
|
+
assertAs(as);
|
|
709
|
+
assertClient(client);
|
|
710
|
+
if (parameters instanceof URL) parameters = parameters.searchParams;
|
|
711
|
+
if (!(parameters instanceof URLSearchParams)) throw CodedTypeError("\"parameters\" must be an instance of URLSearchParams, or URL", ERR_INVALID_ARG_TYPE);
|
|
712
|
+
if (getURLSearchParameter(parameters, "response")) throw OPE("\"parameters\" contains a JARM response, use validateJwtAuthResponse() instead of validateAuthResponse()", INVALID_RESPONSE, { parameters });
|
|
713
|
+
const iss = getURLSearchParameter(parameters, "iss");
|
|
714
|
+
const state = getURLSearchParameter(parameters, "state");
|
|
715
|
+
if (!iss && as.authorization_response_iss_parameter_supported) throw OPE("response parameter \"iss\" (issuer) missing", INVALID_RESPONSE, { parameters });
|
|
716
|
+
if (iss && iss !== as.issuer) throw OPE("unexpected \"iss\" (issuer) response parameter value", INVALID_RESPONSE, {
|
|
717
|
+
expected: as.issuer,
|
|
718
|
+
parameters
|
|
719
|
+
});
|
|
720
|
+
switch (expectedState) {
|
|
721
|
+
case void 0:
|
|
722
|
+
case expectNoState:
|
|
723
|
+
if (state !== void 0) throw OPE("unexpected \"state\" response parameter encountered", INVALID_RESPONSE, {
|
|
724
|
+
expected: void 0,
|
|
725
|
+
parameters
|
|
726
|
+
});
|
|
727
|
+
break;
|
|
728
|
+
case skipStateCheck: break;
|
|
729
|
+
default:
|
|
730
|
+
assertString(expectedState, "\"expectedState\" argument");
|
|
731
|
+
if (state !== expectedState) throw OPE(state === void 0 ? "response parameter \"state\" missing" : "unexpected \"state\" response parameter value", INVALID_RESPONSE, {
|
|
732
|
+
expected: expectedState,
|
|
733
|
+
parameters
|
|
734
|
+
});
|
|
735
|
+
}
|
|
736
|
+
if (getURLSearchParameter(parameters, "error")) throw new AuthorizationResponseError("authorization response from the server is an error", { cause: parameters });
|
|
737
|
+
const id_token = getURLSearchParameter(parameters, "id_token");
|
|
738
|
+
const token = getURLSearchParameter(parameters, "token");
|
|
739
|
+
if (id_token !== void 0 || token !== void 0) throw new UnsupportedOperationError("implicit and hybrid flows are not supported");
|
|
740
|
+
return brand(new URLSearchParams(parameters));
|
|
741
|
+
}
|
|
742
|
+
async function getResponseJsonBody(response, check = assertApplicationJson) {
|
|
743
|
+
let json;
|
|
744
|
+
try {
|
|
745
|
+
json = await response.json();
|
|
746
|
+
} catch (cause) {
|
|
747
|
+
check(response);
|
|
748
|
+
throw OPE("failed to parse \"response\" body as JSON", PARSE_ERROR, cause);
|
|
749
|
+
}
|
|
750
|
+
if (!isJsonObject(json)) throw OPE("\"response\" body must be a top level object", INVALID_RESPONSE, { body: json });
|
|
751
|
+
return json;
|
|
752
|
+
}
|
|
753
|
+
const _expectedIssuer = Symbol();
|
|
754
|
+
|
|
755
|
+
//#endregion
|
|
756
|
+
//#region src/interface/client-interface.ts
|
|
757
|
+
const botChallengeKnownErrors = [KnownErrors.BotChallengeRequired, KnownErrors.BotChallengeFailed];
|
|
758
|
+
function isBotChallengeKnownError(error) {
|
|
759
|
+
return KnownErrors.BotChallengeRequired.isInstance(error) || KnownErrors.BotChallengeFailed.isInstance(error);
|
|
760
|
+
}
|
|
761
|
+
function getBotChallengeRequestFields(botChallenge, context) {
|
|
762
|
+
if (botChallenge?.unavailable) {
|
|
763
|
+
if (botChallenge.token != null || botChallenge.phase != null) throw new HexclaveAssertionError(`${context} bot challenge unavailability cannot be combined with a token or phase.`);
|
|
764
|
+
return { bot_challenge_unavailable: "true" };
|
|
765
|
+
}
|
|
766
|
+
const challengeToken = botChallenge?.token?.trim() || void 0;
|
|
767
|
+
if (botChallenge?.phase === "visible") {
|
|
768
|
+
if (challengeToken == null) return { bot_challenge_unavailable: "true" };
|
|
769
|
+
return {
|
|
770
|
+
bot_challenge_token: challengeToken,
|
|
771
|
+
bot_challenge_phase: "visible"
|
|
772
|
+
};
|
|
773
|
+
}
|
|
774
|
+
if (challengeToken == null) {
|
|
775
|
+
if (botChallenge?.phase != null) throw new HexclaveAssertionError(`${context} bot challenge phase options require a token.`);
|
|
776
|
+
return {};
|
|
777
|
+
}
|
|
778
|
+
if (botChallenge?.phase == null) return { bot_challenge_token: challengeToken };
|
|
779
|
+
return {
|
|
780
|
+
bot_challenge_token: challengeToken,
|
|
781
|
+
bot_challenge_phase: "invisible"
|
|
782
|
+
};
|
|
783
|
+
}
|
|
784
|
+
async function encodeAnalyticsBody(jsonBody, options) {
|
|
785
|
+
if (options.keepalive) return {
|
|
786
|
+
body: jsonBody,
|
|
787
|
+
contentType: "application/json"
|
|
788
|
+
};
|
|
789
|
+
const CompressionStreamCtor = globalVar.CompressionStream;
|
|
790
|
+
if (typeof CompressionStreamCtor !== "function" || typeof Blob === "undefined" || typeof Response === "undefined") return {
|
|
791
|
+
body: jsonBody,
|
|
792
|
+
contentType: "application/json"
|
|
793
|
+
};
|
|
794
|
+
try {
|
|
795
|
+
const stream = new Blob([jsonBody]).stream().pipeThrough(new CompressionStreamCtor("gzip"));
|
|
796
|
+
const buffer = await new Response(stream).arrayBuffer();
|
|
797
|
+
return {
|
|
798
|
+
body: new Uint8Array(buffer),
|
|
799
|
+
contentType: "application/octet-stream"
|
|
800
|
+
};
|
|
801
|
+
} catch {
|
|
802
|
+
return {
|
|
803
|
+
body: jsonBody,
|
|
804
|
+
contentType: "application/json"
|
|
805
|
+
};
|
|
806
|
+
}
|
|
807
|
+
}
|
|
808
|
+
var HexclaveClientInterface = class {
|
|
809
|
+
constructor(options) {
|
|
810
|
+
this.options = options;
|
|
811
|
+
this._requestListeners = /* @__PURE__ */ new Set();
|
|
812
|
+
this._sticky = null;
|
|
813
|
+
this._initialProbeRate = options.probeRate ?? .3;
|
|
814
|
+
}
|
|
815
|
+
addRequestListener(listener) {
|
|
816
|
+
this._requestListeners.add(listener);
|
|
817
|
+
return () => {
|
|
818
|
+
this._requestListeners.delete(listener);
|
|
819
|
+
};
|
|
820
|
+
}
|
|
821
|
+
get projectId() {
|
|
822
|
+
return this.options.projectId;
|
|
823
|
+
}
|
|
824
|
+
getApiUrl() {
|
|
825
|
+
return this.options.getBaseUrl() + "/api/v1";
|
|
826
|
+
}
|
|
827
|
+
getApiUrls() {
|
|
828
|
+
return this.options.getApiUrls().map((u) => u + "/api/v1");
|
|
829
|
+
}
|
|
830
|
+
/**
|
|
831
|
+
* Returns the best-known-good API URL: the sticky fallback if we're in
|
|
832
|
+
* fallback mode, otherwise the primary. Use for browser-navigated URLs
|
|
833
|
+
* (e.g. OAuth authorize) where _withFallback can't help.
|
|
834
|
+
*/
|
|
835
|
+
getBestApiUrl() {
|
|
836
|
+
const apiUrls = this.getApiUrls();
|
|
837
|
+
if (this._sticky && apiUrls[this._sticky.index]) return apiUrls[this._sticky.index];
|
|
838
|
+
return apiUrls[0];
|
|
839
|
+
}
|
|
840
|
+
/**
|
|
841
|
+
* Routes a request through an ordered URL list with automatic failover.
|
|
842
|
+
*
|
|
843
|
+
* The URL list is [primary, ...fallbacks]. The logic has two modes:
|
|
844
|
+
*
|
|
845
|
+
* **Normal mode** (`_sticky` is null) — try each URL in order. If a
|
|
846
|
+
* non-primary URL succeeds, enter sticky mode on that index.
|
|
847
|
+
*
|
|
848
|
+
* **Sticky mode** — a previous request already failed over. We remember
|
|
849
|
+
* which URL worked and go there directly. Occasionally (controlled by a
|
|
850
|
+
* decaying probe rate) we probe the primary to see if it recovered:
|
|
851
|
+
* - Probe succeeds → exit sticky mode, use result.
|
|
852
|
+
* - Probe fails → halve probe rate, use sticky URL.
|
|
853
|
+
* - Sticky URL fails → exit sticky mode, do a full iteration.
|
|
854
|
+
*
|
|
855
|
+
* In both modes, a full iteration tries every URL once per pass for 2
|
|
856
|
+
* passes before giving up. KnownErrors and 4xx API responses (except 429)
|
|
857
|
+
* are never retried (they're application-level, not network-level).
|
|
858
|
+
*
|
|
859
|
+
* Single-URL lists skip all of this and use 5-retry behavior directly.
|
|
860
|
+
*/
|
|
861
|
+
async _withFallback(cb) {
|
|
862
|
+
const apiUrls = this.getApiUrls();
|
|
863
|
+
if (apiUrls.length <= 1) return await cb(apiUrls[0], {
|
|
864
|
+
maxAttempts: 5,
|
|
865
|
+
skipDiagnostics: false
|
|
866
|
+
});
|
|
867
|
+
if (this._sticky) {
|
|
868
|
+
const result = await this._tryStickyUrl(apiUrls, cb);
|
|
869
|
+
if (result !== void 0) return result;
|
|
870
|
+
}
|
|
871
|
+
return await this._iterateUrls(apiUrls, cb);
|
|
872
|
+
}
|
|
873
|
+
_shouldSkipFallback(error) {
|
|
874
|
+
return error instanceof KnownError || this._isNonRetryableApiResponseError(error);
|
|
875
|
+
}
|
|
876
|
+
_isNonRetryableApiResponseError(error) {
|
|
877
|
+
const response = this._getApiResponseFromError(error);
|
|
878
|
+
return response != null && response.status >= 400 && response.status < 500;
|
|
879
|
+
}
|
|
880
|
+
_getApiResponseFromError(error, seenErrors = /* @__PURE__ */ new Set()) {
|
|
881
|
+
if (error instanceof Response) return error;
|
|
882
|
+
if (!(error instanceof Error) || seenErrors.has(error)) return null;
|
|
883
|
+
seenErrors.add(error);
|
|
884
|
+
return this._getApiResponseFromError(error.cause, seenErrors);
|
|
885
|
+
}
|
|
886
|
+
/**
|
|
887
|
+
* Attempts the sticky URL, optionally probing primary first.
|
|
888
|
+
* Returns the result on success, or `undefined` if we should fall through to full iteration.
|
|
889
|
+
*/
|
|
890
|
+
async _tryStickyUrl(apiUrls, cb) {
|
|
891
|
+
const sticky = this._sticky;
|
|
892
|
+
if (Math.random() < sticky.probeRate) try {
|
|
893
|
+
const result = await cb(apiUrls[0], {
|
|
894
|
+
maxAttempts: 1,
|
|
895
|
+
skipDiagnostics: true
|
|
896
|
+
});
|
|
897
|
+
this._sticky = null;
|
|
898
|
+
return result;
|
|
899
|
+
} catch (e) {
|
|
900
|
+
if (this._shouldSkipFallback(e)) throw e;
|
|
901
|
+
sticky.probeRate = Math.max(sticky.probeRate * .5, .01);
|
|
902
|
+
}
|
|
903
|
+
try {
|
|
904
|
+
return await cb(apiUrls[sticky.index], {
|
|
905
|
+
maxAttempts: 1,
|
|
906
|
+
skipDiagnostics: true
|
|
907
|
+
});
|
|
908
|
+
} catch (e) {
|
|
909
|
+
if (this._shouldSkipFallback(e)) throw e;
|
|
910
|
+
this._sticky = null;
|
|
911
|
+
return;
|
|
912
|
+
}
|
|
913
|
+
}
|
|
914
|
+
/**
|
|
915
|
+
* Tries every URL in order for up to 2 passes.
|
|
916
|
+
* If a non-primary URL (index > 0) succeeds, enters sticky mode on it.
|
|
917
|
+
*/
|
|
918
|
+
async _iterateUrls(apiUrls, cb) {
|
|
919
|
+
let lastError;
|
|
920
|
+
for (let pass = 0; pass < 2; pass++) for (let i = 0; i < apiUrls.length; i++) try {
|
|
921
|
+
const result = await cb(apiUrls[i], {
|
|
922
|
+
maxAttempts: 1,
|
|
923
|
+
skipDiagnostics: true
|
|
924
|
+
});
|
|
925
|
+
if (i > 0) this._sticky = {
|
|
926
|
+
index: i,
|
|
927
|
+
probeRate: this._initialProbeRate
|
|
928
|
+
};
|
|
929
|
+
return result;
|
|
930
|
+
} catch (e) {
|
|
931
|
+
if (this._shouldSkipFallback(e)) throw e;
|
|
932
|
+
lastError = e instanceof Error ? e : new Error(String(e));
|
|
933
|
+
}
|
|
934
|
+
throw lastError;
|
|
935
|
+
}
|
|
936
|
+
getAnalyticsApiUrl() {
|
|
937
|
+
return (this.options.getAnalyticsBaseUrl ?? this.options.getBaseUrl)() + "/api/v1";
|
|
938
|
+
}
|
|
939
|
+
async runNetworkDiagnostics(session, requestType) {
|
|
940
|
+
if (this.pendingNetworkDiagnostics) return await this.pendingNetworkDiagnostics;
|
|
941
|
+
this.pendingNetworkDiagnostics = this._runNetworkDiagnosticsInner(session, requestType);
|
|
942
|
+
try {
|
|
943
|
+
return await this.pendingNetworkDiagnostics;
|
|
944
|
+
} finally {
|
|
945
|
+
this.pendingNetworkDiagnostics = void 0;
|
|
946
|
+
}
|
|
947
|
+
}
|
|
948
|
+
async _runNetworkDiagnosticsInner(session, requestType) {
|
|
949
|
+
const tryRequest = async (cb) => {
|
|
950
|
+
try {
|
|
951
|
+
await cb();
|
|
952
|
+
return "OK";
|
|
953
|
+
} catch (e) {
|
|
954
|
+
return `${e}`;
|
|
955
|
+
}
|
|
956
|
+
};
|
|
957
|
+
const cfTrace = await tryRequest(async () => {
|
|
958
|
+
const res = await fetch("https://1.1.1.1/cdn-cgi/trace");
|
|
959
|
+
if (!res.ok) throw new Error(`${res.status} ${res.statusText}: ${await res.text()}`);
|
|
960
|
+
});
|
|
961
|
+
const baseUrlBackend = await tryRequest(async () => {
|
|
962
|
+
const res = await fetch(new URL("/health", this.getApiUrl()));
|
|
963
|
+
if (!res.ok) throw new Error(`${res.status} ${res.statusText}: ${await res.text()}`);
|
|
964
|
+
});
|
|
965
|
+
const prodDashboard = await tryRequest(async () => {
|
|
966
|
+
const res = await fetch("https://app.hexclave.com/health");
|
|
967
|
+
if (!res.ok) throw new Error(`${res.status} ${res.statusText}: ${await res.text()}`);
|
|
968
|
+
});
|
|
969
|
+
const prodBackend = await tryRequest(async () => {
|
|
970
|
+
const res = await fetch("https://api.hexclave.com/health");
|
|
971
|
+
if (!res.ok) throw new Error(`${res.status} ${res.statusText}: ${await res.text()}`);
|
|
972
|
+
});
|
|
973
|
+
return {
|
|
974
|
+
"navigator?.onLine": globalVar.navigator?.onLine,
|
|
975
|
+
cfTrace,
|
|
976
|
+
baseUrlBackend,
|
|
977
|
+
prodDashboard,
|
|
978
|
+
prodBackend
|
|
979
|
+
};
|
|
980
|
+
}
|
|
981
|
+
async _createNetworkError(cause, session, requestType) {
|
|
982
|
+
return new Error(deindent`
|
|
983
|
+
Hexclave is unable to connect to the server. Please check your internet connection and try again.
|
|
984
|
+
|
|
985
|
+
If the problem persists, please contact support and provide a screenshot of your entire browser console.
|
|
986
|
+
|
|
987
|
+
${cause}
|
|
988
|
+
|
|
989
|
+
${JSON.stringify(await this.runNetworkDiagnostics(session, requestType), null, 2)}
|
|
990
|
+
`, { cause });
|
|
991
|
+
}
|
|
992
|
+
async _networkRetry(cb, session, requestType, options) {
|
|
993
|
+
const retriedResult = await Result.retry(cb, options?.maxAttempts ?? 5, { exponentialDelayBase: 1e3 });
|
|
994
|
+
if (retriedResult.status === "error") {
|
|
995
|
+
if (globalVar.navigator && globalVar.navigator.onLine === false) throw new Error("You are offline. Please check your internet connection and try again. (window.navigator.onLine is false)", { cause: retriedResult.error });
|
|
996
|
+
if (options?.skipDiagnostics) throw retriedResult.error;
|
|
997
|
+
throw await this._createNetworkError(retriedResult.error, session, requestType);
|
|
998
|
+
}
|
|
999
|
+
return retriedResult.data;
|
|
1000
|
+
}
|
|
1001
|
+
async _networkRetryException(cb, session, requestType, options) {
|
|
1002
|
+
return await this._networkRetry(async () => await Result.fromThrowingAsync(cb), session, requestType, options);
|
|
1003
|
+
}
|
|
1004
|
+
async fetchNewAccessToken(refreshToken) {
|
|
1005
|
+
if ("projectOwnerSession" in this.options) throw new Error("Admin session token is currently not supported for fetching new access token. Did you try to log in on a StackApp initiated with the admin session?");
|
|
1006
|
+
const clientSecret = this.options.publishableClientKey ?? publishableClientKeyNotNecessarySentinel;
|
|
1007
|
+
return await this._withFallback(async (apiUrl, retryOptions) => {
|
|
1008
|
+
return await this._fetchNewAccessTokenInner(refreshToken, clientSecret, apiUrl, retryOptions);
|
|
1009
|
+
});
|
|
1010
|
+
}
|
|
1011
|
+
async _fetchNewAccessTokenInner(refreshToken, clientSecret, apiUrl, retryOptions) {
|
|
1012
|
+
const tokenEndpoint = apiUrl + "/auth/oauth/token";
|
|
1013
|
+
const as = {
|
|
1014
|
+
issuer: this.options.getBaseUrl(),
|
|
1015
|
+
algorithm: "oauth2",
|
|
1016
|
+
token_endpoint: tokenEndpoint
|
|
1017
|
+
};
|
|
1018
|
+
const client = {
|
|
1019
|
+
client_id: this.projectId,
|
|
1020
|
+
client_secret: clientSecret
|
|
1021
|
+
};
|
|
1022
|
+
const clientAuthentication = ClientSecretPost(clientSecret);
|
|
1023
|
+
const allowInsecure = tokenEndpoint.startsWith("http://");
|
|
1024
|
+
const response = await this._networkRetryException(async () => {
|
|
1025
|
+
const rawResponse = await refreshTokenGrantRequest(as, client, clientAuthentication, refreshToken.token, allowInsecure ? { [allowInsecureRequests]: true } : void 0);
|
|
1026
|
+
const response = await this._processResponse(rawResponse);
|
|
1027
|
+
if (response.status === "error") {
|
|
1028
|
+
const error = response.error;
|
|
1029
|
+
if (KnownErrors.RefreshTokenError.isInstance(error)) return null;
|
|
1030
|
+
throw error;
|
|
1031
|
+
}
|
|
1032
|
+
if (!response.data.ok) {
|
|
1033
|
+
const body = await response.data.text();
|
|
1034
|
+
throw new Error(`Failed to send refresh token request: ${response.status} ${body}`, { cause: response.data });
|
|
1035
|
+
}
|
|
1036
|
+
return response.data;
|
|
1037
|
+
}, void 0, void 0, retryOptions);
|
|
1038
|
+
if (!response) return null;
|
|
1039
|
+
let result;
|
|
1040
|
+
try {
|
|
1041
|
+
result = await processRefreshTokenResponse(as, client, response);
|
|
1042
|
+
} catch (e) {
|
|
1043
|
+
if (e instanceof ResponseBodyError) throw new HexclaveAssertionError("ResponseBodyError when processing refresh token response", {
|
|
1044
|
+
cause: e.cause,
|
|
1045
|
+
code: e.code,
|
|
1046
|
+
error: e.error
|
|
1047
|
+
});
|
|
1048
|
+
throw new HexclaveAssertionError("Unexpected error when processing refresh token response", { cause: e });
|
|
1049
|
+
}
|
|
1050
|
+
if (!result.access_token) throw new HexclaveAssertionError("Access token not found in token endpoint response, this is weird!");
|
|
1051
|
+
return AccessToken.createIfValid(result.access_token) ?? throwErr("Access token in fetchNewAccessToken is invalid, looks like the backend is returning an invalid token!", { result });
|
|
1052
|
+
}
|
|
1053
|
+
async sendClientRequest(path, requestOptions, session, requestType = "client", apiUrlOverride, retryOptions) {
|
|
1054
|
+
session ??= this.createSession({ refreshToken: null });
|
|
1055
|
+
if (apiUrlOverride) return await this._networkRetry(() => this.sendClientRequestInner(path, requestOptions, session, requestType, apiUrlOverride, retryOptions), session, requestType, retryOptions);
|
|
1056
|
+
return await this._withFallback(async (apiUrl, fallbackRetryOptions) => {
|
|
1057
|
+
return await this._networkRetry(() => this.sendClientRequestInner(path, requestOptions, session, requestType, apiUrl, retryOptions), session, requestType, {
|
|
1058
|
+
...fallbackRetryOptions,
|
|
1059
|
+
...retryOptions
|
|
1060
|
+
});
|
|
1061
|
+
});
|
|
1062
|
+
}
|
|
1063
|
+
createSession(options) {
|
|
1064
|
+
return new InternalSession({
|
|
1065
|
+
refreshAccessTokenCallback: async (refreshToken) => await this.fetchNewAccessToken(refreshToken),
|
|
1066
|
+
...options
|
|
1067
|
+
});
|
|
1068
|
+
}
|
|
1069
|
+
async sendSessionReplayBatch(body, session, options) {
|
|
1070
|
+
try {
|
|
1071
|
+
const response = await this.sendClientRequest("/session-replays/batch", {
|
|
1072
|
+
method: "POST",
|
|
1073
|
+
headers: { "Content-Type": "application/json" },
|
|
1074
|
+
body,
|
|
1075
|
+
keepalive: options.keepalive
|
|
1076
|
+
}, session, "client", this.getAnalyticsApiUrl(), {
|
|
1077
|
+
maxAttempts: 1,
|
|
1078
|
+
skipDiagnostics: true
|
|
1079
|
+
});
|
|
1080
|
+
return Result.ok(response);
|
|
1081
|
+
} catch (e) {
|
|
1082
|
+
return Result.error(e instanceof Error ? e : new Error(String(e)));
|
|
1083
|
+
}
|
|
1084
|
+
}
|
|
1085
|
+
async sendAnalyticsEventBatch(body, session, options) {
|
|
1086
|
+
try {
|
|
1087
|
+
const encoded = await encodeAnalyticsBody(body, { keepalive: options.keepalive });
|
|
1088
|
+
const response = await this.sendClientRequest("/analytics/events/batch", {
|
|
1089
|
+
method: "POST",
|
|
1090
|
+
headers: { "Content-Type": encoded.contentType },
|
|
1091
|
+
body: encoded.body,
|
|
1092
|
+
keepalive: options.keepalive
|
|
1093
|
+
}, session, "client", this.getAnalyticsApiUrl(), {
|
|
1094
|
+
maxAttempts: 1,
|
|
1095
|
+
skipDiagnostics: true
|
|
1096
|
+
});
|
|
1097
|
+
return Result.ok(response);
|
|
1098
|
+
} catch (e) {
|
|
1099
|
+
return Result.error(e instanceof Error ? e : new Error(String(e)));
|
|
1100
|
+
}
|
|
1101
|
+
}
|
|
1102
|
+
async sendClientRequestAndCatchKnownError(path, requestOptions, tokenStoreOrNull, errorsToCatch) {
|
|
1103
|
+
try {
|
|
1104
|
+
return Result.ok(await this.sendClientRequest(path, requestOptions, tokenStoreOrNull));
|
|
1105
|
+
} catch (e) {
|
|
1106
|
+
for (const errorType of errorsToCatch) if (errorType.isInstance(e)) return Result.error(e);
|
|
1107
|
+
throw e;
|
|
1108
|
+
}
|
|
1109
|
+
}
|
|
1110
|
+
async sendClientRequestInner(path, options, session, requestType, apiUrlOverride, innerOptions) {
|
|
1111
|
+
/**
|
|
1112
|
+
* `tokenObj === null` means the session is invalid/not logged in
|
|
1113
|
+
*/
|
|
1114
|
+
let tokenObj = await session.getOrFetchLikelyValidTokens(2e4, null);
|
|
1115
|
+
let adminSession = null;
|
|
1116
|
+
let adminTokenObj = null;
|
|
1117
|
+
if ("projectOwnerSession" in this.options) {
|
|
1118
|
+
const projectOwnerSession = this.options.projectOwnerSession;
|
|
1119
|
+
if (typeof projectOwnerSession === "function") {
|
|
1120
|
+
const accessTokenString = await projectOwnerSession();
|
|
1121
|
+
if (accessTokenString) {
|
|
1122
|
+
const accessToken = AccessToken.createIfValid(accessTokenString);
|
|
1123
|
+
if (accessToken) adminTokenObj = {
|
|
1124
|
+
accessToken,
|
|
1125
|
+
refreshToken: null
|
|
1126
|
+
};
|
|
1127
|
+
}
|
|
1128
|
+
} else {
|
|
1129
|
+
adminSession = projectOwnerSession;
|
|
1130
|
+
adminTokenObj = await projectOwnerSession.getOrFetchLikelyValidTokens(2e4, null);
|
|
1131
|
+
}
|
|
1132
|
+
}
|
|
1133
|
+
await this.options.prepareRequest?.();
|
|
1134
|
+
let url = (apiUrlOverride ?? this.getApiUrl()) + path;
|
|
1135
|
+
if (url.endsWith("/")) url = url.slice(0, -1);
|
|
1136
|
+
const params = {
|
|
1137
|
+
..."WebSocketPair" in globalVar ? {} : { credentials: "omit" },
|
|
1138
|
+
...options,
|
|
1139
|
+
headers: {
|
|
1140
|
+
"X-Hexclave-Override-Error-Status": "true",
|
|
1141
|
+
"X-Hexclave-Project-Id": this.projectId,
|
|
1142
|
+
"X-Hexclave-Access-Type": requestType,
|
|
1143
|
+
"X-Hexclave-Client-Version": this.options.clientVersion,
|
|
1144
|
+
...tokenObj ? { "X-Hexclave-Access-Token": tokenObj.accessToken.token } : {},
|
|
1145
|
+
...tokenObj?.refreshToken ? { "X-Hexclave-Refresh-Token": tokenObj.refreshToken.token } : {},
|
|
1146
|
+
"X-Hexclave-Allow-Anonymous-User": "true",
|
|
1147
|
+
..."publishableClientKey" in this.options && this.options.publishableClientKey ? { "X-Hexclave-Publishable-Client-Key": this.options.publishableClientKey } : {},
|
|
1148
|
+
...adminTokenObj ? { "X-Hexclave-Admin-Access-Token": adminTokenObj.accessToken.token } : {},
|
|
1149
|
+
"X-Hexclave-Random-Nonce": generateSecureRandomString(),
|
|
1150
|
+
"ngrok-skip-browser-warning": "true",
|
|
1151
|
+
...this.options.extraRequestHeaders,
|
|
1152
|
+
...options.headers
|
|
1153
|
+
},
|
|
1154
|
+
..."WebSocketPair" in globalVar ? {} : { cache: "no-store" }
|
|
1155
|
+
};
|
|
1156
|
+
const startTime = performance.now();
|
|
1157
|
+
let rawRes;
|
|
1158
|
+
try {
|
|
1159
|
+
rawRes = await fetch(url, params);
|
|
1160
|
+
} catch (e) {
|
|
1161
|
+
if (this._requestListeners.size > 0) {
|
|
1162
|
+
const entry = {
|
|
1163
|
+
path,
|
|
1164
|
+
method: (params.method ?? "GET").toUpperCase(),
|
|
1165
|
+
duration: Math.round(performance.now() - startTime),
|
|
1166
|
+
error: e instanceof Error ? e.message : "Network error"
|
|
1167
|
+
};
|
|
1168
|
+
this._requestListeners.forEach((l) => l(entry));
|
|
1169
|
+
}
|
|
1170
|
+
if (e instanceof TypeError) if (HTTP_METHODS[params.method ?? "GET"].idempotent) return Result.error(e);
|
|
1171
|
+
else if (innerOptions?.skipDiagnostics) throw e;
|
|
1172
|
+
else throw await this._createNetworkError(e, session, requestType);
|
|
1173
|
+
throw e;
|
|
1174
|
+
}
|
|
1175
|
+
const preprocessedRes = await this._preprocessResponse(rawRes);
|
|
1176
|
+
if (this._requestListeners.size > 0) {
|
|
1177
|
+
const entry = {
|
|
1178
|
+
path,
|
|
1179
|
+
method: (params.method ?? "GET").toUpperCase(),
|
|
1180
|
+
status: preprocessedRes.status,
|
|
1181
|
+
duration: Math.round(performance.now() - startTime)
|
|
1182
|
+
};
|
|
1183
|
+
this._requestListeners.forEach((l) => l(entry));
|
|
1184
|
+
}
|
|
1185
|
+
const processedRes = await this._processResponse(preprocessedRes);
|
|
1186
|
+
if (processedRes.status === "error") {
|
|
1187
|
+
if (KnownErrors.InvalidAccessToken.isInstance(processedRes.error)) {
|
|
1188
|
+
if (!tokenObj) throw new HexclaveAssertionError("Received invalid access token, but session is not logged in", {
|
|
1189
|
+
tokenObj,
|
|
1190
|
+
processedRes
|
|
1191
|
+
});
|
|
1192
|
+
session.markAccessTokenExpired(tokenObj.accessToken);
|
|
1193
|
+
return Result.error(processedRes.error);
|
|
1194
|
+
}
|
|
1195
|
+
if (adminSession && (KnownErrors.InvalidAdminAccessToken.isInstance(processedRes.error) || KnownErrors.ApiKeyNotFound.isInstance(processedRes.error))) {
|
|
1196
|
+
if (!adminTokenObj) throw new HexclaveAssertionError("Received invalid admin access token, but admin session is not logged in", {
|
|
1197
|
+
adminTokenObj,
|
|
1198
|
+
processedRes
|
|
1199
|
+
});
|
|
1200
|
+
adminSession.markAccessTokenExpired(adminTokenObj.accessToken);
|
|
1201
|
+
return Result.error(processedRes.error);
|
|
1202
|
+
}
|
|
1203
|
+
throw processedRes.error;
|
|
1204
|
+
}
|
|
1205
|
+
const res = Object.assign(processedRes.data, { usedTokens: tokenObj });
|
|
1206
|
+
if (res.ok) return Result.ok(res);
|
|
1207
|
+
else if (res.status === 429) {
|
|
1208
|
+
const retryAfter = res.headers.get("Retry-After");
|
|
1209
|
+
if (retryAfter !== null) {
|
|
1210
|
+
console.log(`Rate limited while sending request to ${url}. Will retry after ${retryAfter} seconds...`);
|
|
1211
|
+
await wait(Number(retryAfter) * 1e3);
|
|
1212
|
+
return Result.error(/* @__PURE__ */ new Error(`Rate limited, retrying after ${retryAfter} seconds`));
|
|
1213
|
+
}
|
|
1214
|
+
console.log(`Rate limited while sending request to ${url}, no retry-after header received. Retrying...`);
|
|
1215
|
+
return Result.error(/* @__PURE__ */ new Error("Rate limited, no retry-after header received"));
|
|
1216
|
+
} else {
|
|
1217
|
+
const error = await res.text();
|
|
1218
|
+
if (res.status >= 400 && res.status < 500) throw new Error(`Failed to send request to ${url}: ${res.status} ${error}`, { cause: res });
|
|
1219
|
+
const errorObj = new HexclaveAssertionError(`Failed to send request to ${url}: ${res.status} ${error}`, {
|
|
1220
|
+
request: params,
|
|
1221
|
+
res,
|
|
1222
|
+
path
|
|
1223
|
+
});
|
|
1224
|
+
if (res.status === 508 && error.includes("INFINITE_LOOP_DETECTED")) return Result.error(errorObj);
|
|
1225
|
+
throw errorObj;
|
|
1226
|
+
}
|
|
1227
|
+
}
|
|
1228
|
+
async _preprocessResponse(rawRes) {
|
|
1229
|
+
let res = rawRes;
|
|
1230
|
+
if (rawRes.headers.has("x-hexclave-actual-status") || rawRes.headers.has("x-stack-actual-status")) {
|
|
1231
|
+
const actualStatus = Number(rawRes.headers.get("x-hexclave-actual-status") ?? rawRes.headers.get("x-stack-actual-status"));
|
|
1232
|
+
res = new Response(rawRes.body, {
|
|
1233
|
+
status: actualStatus,
|
|
1234
|
+
statusText: rawRes.statusText,
|
|
1235
|
+
headers: rawRes.headers
|
|
1236
|
+
});
|
|
1237
|
+
}
|
|
1238
|
+
return res;
|
|
1239
|
+
}
|
|
1240
|
+
async _processResponse(res) {
|
|
1241
|
+
if (res.headers.has("x-hexclave-known-error") || res.headers.has("x-stack-known-error")) {
|
|
1242
|
+
const errorJson = await res.json();
|
|
1243
|
+
if ((res.headers.get("x-hexclave-known-error") ?? res.headers.get("x-stack-known-error")) !== errorJson.code) throw new HexclaveAssertionError("Mismatch between x-hexclave-known-error/x-stack-known-error header and error code in body; the server's response is invalid");
|
|
1244
|
+
const error = KnownError.fromJson(errorJson);
|
|
1245
|
+
return Result.error(error);
|
|
1246
|
+
}
|
|
1247
|
+
return Result.ok(res);
|
|
1248
|
+
}
|
|
1249
|
+
async checkFeatureSupport(options) {
|
|
1250
|
+
throw new HexclaveAssertionError(await (await this.sendClientRequest("/check-feature-support", {
|
|
1251
|
+
method: "POST",
|
|
1252
|
+
headers: { "Content-Type": "application/json" },
|
|
1253
|
+
body: JSON.stringify(options)
|
|
1254
|
+
}, null)).text());
|
|
1255
|
+
}
|
|
1256
|
+
async sendForgotPasswordEmail(email, callbackUrl) {
|
|
1257
|
+
const res = await this.sendClientRequestAndCatchKnownError("/auth/password/send-reset-code", {
|
|
1258
|
+
method: "POST",
|
|
1259
|
+
headers: { "Content-Type": "application/json" },
|
|
1260
|
+
body: JSON.stringify({
|
|
1261
|
+
email,
|
|
1262
|
+
callback_url: callbackUrl
|
|
1263
|
+
})
|
|
1264
|
+
}, null, [KnownErrors.UserNotFound]);
|
|
1265
|
+
if (res.status === "error") return Result.error(res.error);
|
|
1266
|
+
else return Result.ok(void 0);
|
|
1267
|
+
}
|
|
1268
|
+
async sendVerificationEmail(email, callbackUrl, session) {
|
|
1269
|
+
const res = await this.sendClientRequestAndCatchKnownError("/contact-channels/send-verification-code", {
|
|
1270
|
+
method: "POST",
|
|
1271
|
+
headers: { "Content-Type": "application/json" },
|
|
1272
|
+
body: JSON.stringify({
|
|
1273
|
+
email,
|
|
1274
|
+
callback_url: callbackUrl
|
|
1275
|
+
})
|
|
1276
|
+
}, session, [KnownErrors.EmailAlreadyVerified]);
|
|
1277
|
+
if (res.status === "error") return res.error;
|
|
1278
|
+
}
|
|
1279
|
+
async sendMagicLinkEmail(email, callbackUrl, botChallenge) {
|
|
1280
|
+
const res = await this.sendClientRequestAndCatchKnownError("/auth/otp/send-sign-in-code", {
|
|
1281
|
+
method: "POST",
|
|
1282
|
+
headers: { "Content-Type": "application/json" },
|
|
1283
|
+
body: JSON.stringify({
|
|
1284
|
+
email,
|
|
1285
|
+
callback_url: callbackUrl,
|
|
1286
|
+
...getBotChallengeRequestFields(botChallenge, "Magic link sign-in")
|
|
1287
|
+
})
|
|
1288
|
+
}, null, [KnownErrors.RedirectUrlNotWhitelisted, ...botChallengeKnownErrors]);
|
|
1289
|
+
if (res.status === "error") return Result.error(res.error);
|
|
1290
|
+
else return Result.ok(await res.data.json());
|
|
1291
|
+
}
|
|
1292
|
+
async resetPassword(options) {
|
|
1293
|
+
const res = await this.sendClientRequestAndCatchKnownError("onlyVerifyCode" in options ? "/auth/password/reset/check-code" : "/auth/password/reset", {
|
|
1294
|
+
method: "POST",
|
|
1295
|
+
headers: { "Content-Type": "application/json" },
|
|
1296
|
+
body: JSON.stringify({
|
|
1297
|
+
code: options.code,
|
|
1298
|
+
..."password" in options ? { password: options.password } : {}
|
|
1299
|
+
})
|
|
1300
|
+
}, null, [KnownErrors.VerificationCodeError]);
|
|
1301
|
+
if (res.status === "error") return Result.error(res.error);
|
|
1302
|
+
else return Result.ok(void 0);
|
|
1303
|
+
}
|
|
1304
|
+
async updatePassword(options, session) {
|
|
1305
|
+
const res = await this.sendClientRequestAndCatchKnownError("/auth/password/update", {
|
|
1306
|
+
method: "POST",
|
|
1307
|
+
headers: { "Content-Type": "application/json" },
|
|
1308
|
+
body: JSON.stringify({
|
|
1309
|
+
old_password: options.oldPassword,
|
|
1310
|
+
new_password: options.newPassword
|
|
1311
|
+
})
|
|
1312
|
+
}, session, [KnownErrors.PasswordConfirmationMismatch, KnownErrors.PasswordRequirementsNotMet]);
|
|
1313
|
+
if (res.status === "error") return res.error;
|
|
1314
|
+
}
|
|
1315
|
+
async setPassword(options, session) {
|
|
1316
|
+
const res = await this.sendClientRequestAndCatchKnownError("/auth/password/set", {
|
|
1317
|
+
method: "POST",
|
|
1318
|
+
headers: { "Content-Type": "application/json" },
|
|
1319
|
+
body: JSON.stringify(options)
|
|
1320
|
+
}, session, [KnownErrors.PasswordRequirementsNotMet]);
|
|
1321
|
+
if (res.status === "error") return res.error;
|
|
1322
|
+
}
|
|
1323
|
+
async verifyPasswordResetCode(code) {
|
|
1324
|
+
const res = await this.resetPassword({
|
|
1325
|
+
code,
|
|
1326
|
+
onlyVerifyCode: true
|
|
1327
|
+
});
|
|
1328
|
+
if (res.status === "error") return Result.error(res.error);
|
|
1329
|
+
else return Result.ok(void 0);
|
|
1330
|
+
}
|
|
1331
|
+
async verifyEmail(code) {
|
|
1332
|
+
const res = await this.sendClientRequestAndCatchKnownError("/contact-channels/verify", {
|
|
1333
|
+
method: "POST",
|
|
1334
|
+
headers: { "Content-Type": "application/json" },
|
|
1335
|
+
body: JSON.stringify({ code })
|
|
1336
|
+
}, null, [KnownErrors.VerificationCodeError]);
|
|
1337
|
+
if (res.status === "error") return Result.error(res.error);
|
|
1338
|
+
else return Result.ok(void 0);
|
|
1339
|
+
}
|
|
1340
|
+
async initiatePasskeyRegistration(options, session) {
|
|
1341
|
+
const res = await this.sendClientRequestAndCatchKnownError("/auth/passkey/initiate-passkey-registration", {
|
|
1342
|
+
method: "POST",
|
|
1343
|
+
headers: { "Content-Type": "application/json" },
|
|
1344
|
+
body: JSON.stringify(options)
|
|
1345
|
+
}, session, []);
|
|
1346
|
+
if (res.status === "error") return Result.error(res.error);
|
|
1347
|
+
return Result.ok(await res.data.json());
|
|
1348
|
+
}
|
|
1349
|
+
async registerPasskey(options, session) {
|
|
1350
|
+
const res = await this.sendClientRequestAndCatchKnownError("/auth/passkey/register", {
|
|
1351
|
+
method: "POST",
|
|
1352
|
+
headers: { "Content-Type": "application/json" },
|
|
1353
|
+
body: JSON.stringify(options)
|
|
1354
|
+
}, session, [KnownErrors.PasskeyRegistrationFailed]);
|
|
1355
|
+
if (res.status === "error") return Result.error(res.error);
|
|
1356
|
+
return Result.ok(void 0);
|
|
1357
|
+
}
|
|
1358
|
+
async initiatePasskeyAuthentication(options, session) {
|
|
1359
|
+
const res = await this.sendClientRequestAndCatchKnownError("/auth/passkey/initiate-passkey-authentication", {
|
|
1360
|
+
method: "POST",
|
|
1361
|
+
headers: { "Content-Type": "application/json" },
|
|
1362
|
+
body: JSON.stringify(options)
|
|
1363
|
+
}, session, []);
|
|
1364
|
+
if (res.status === "error") return Result.error(res.error);
|
|
1365
|
+
return Result.ok(await res.data.json());
|
|
1366
|
+
}
|
|
1367
|
+
async sendTeamInvitation(options) {
|
|
1368
|
+
await this.sendClientRequest("/team-invitations/send-code", {
|
|
1369
|
+
method: "POST",
|
|
1370
|
+
headers: { "Content-Type": "application/json" },
|
|
1371
|
+
body: JSON.stringify({
|
|
1372
|
+
email: options.email,
|
|
1373
|
+
team_id: options.teamId,
|
|
1374
|
+
callback_url: options.callbackUrl
|
|
1375
|
+
})
|
|
1376
|
+
}, options.session);
|
|
1377
|
+
}
|
|
1378
|
+
async acceptTeamInvitation(options) {
|
|
1379
|
+
const res = await this.sendClientRequestAndCatchKnownError(options.type === "check" ? "/team-invitations/accept/check-code" : options.type === "details" ? "/team-invitations/accept/details" : "/team-invitations/accept", {
|
|
1380
|
+
method: "POST",
|
|
1381
|
+
headers: { "Content-Type": "application/json" },
|
|
1382
|
+
body: JSON.stringify({ code: options.code })
|
|
1383
|
+
}, options.session, [KnownErrors.VerificationCodeError, KnownErrors.TeamInvitationEmailMismatch]);
|
|
1384
|
+
if (res.status === "error") return Result.error(res.error);
|
|
1385
|
+
else return Result.ok(await res.data.json());
|
|
1386
|
+
}
|
|
1387
|
+
async totpMfa(attemptCode, totp, session) {
|
|
1388
|
+
const result = await (await this.sendClientRequest("/auth/mfa/sign-in", {
|
|
1389
|
+
method: "POST",
|
|
1390
|
+
headers: { "Content-Type": "application/json" },
|
|
1391
|
+
body: JSON.stringify({
|
|
1392
|
+
code: attemptCode,
|
|
1393
|
+
type: "totp",
|
|
1394
|
+
totp
|
|
1395
|
+
})
|
|
1396
|
+
}, session)).json();
|
|
1397
|
+
return {
|
|
1398
|
+
accessToken: result.access_token,
|
|
1399
|
+
refreshToken: result.refresh_token,
|
|
1400
|
+
newUser: result.is_new_user
|
|
1401
|
+
};
|
|
1402
|
+
}
|
|
1403
|
+
async signInWithCredential(email, password, session) {
|
|
1404
|
+
const res = await this.sendClientRequestAndCatchKnownError("/auth/password/sign-in", {
|
|
1405
|
+
method: "POST",
|
|
1406
|
+
headers: { "Content-Type": "application/json" },
|
|
1407
|
+
body: JSON.stringify({
|
|
1408
|
+
email,
|
|
1409
|
+
password
|
|
1410
|
+
})
|
|
1411
|
+
}, session, [KnownErrors.EmailPasswordMismatch]);
|
|
1412
|
+
if (res.status === "error") return Result.error(res.error);
|
|
1413
|
+
const result = await res.data.json();
|
|
1414
|
+
return Result.ok({
|
|
1415
|
+
accessToken: result.access_token,
|
|
1416
|
+
refreshToken: result.refresh_token
|
|
1417
|
+
});
|
|
1418
|
+
}
|
|
1419
|
+
async signUpWithCredential(email, password, emailVerificationRedirectUrl, session, botChallenge) {
|
|
1420
|
+
const res = await this.sendClientRequestAndCatchKnownError("/auth/password/sign-up", {
|
|
1421
|
+
headers: { "Content-Type": "application/json" },
|
|
1422
|
+
method: "POST",
|
|
1423
|
+
body: JSON.stringify({
|
|
1424
|
+
email,
|
|
1425
|
+
password,
|
|
1426
|
+
verification_callback_url: emailVerificationRedirectUrl,
|
|
1427
|
+
...getBotChallengeRequestFields(botChallenge, "Credential sign-up")
|
|
1428
|
+
})
|
|
1429
|
+
}, session, [
|
|
1430
|
+
KnownErrors.UserWithEmailAlreadyExists,
|
|
1431
|
+
KnownErrors.PasswordRequirementsNotMet,
|
|
1432
|
+
...botChallengeKnownErrors
|
|
1433
|
+
]);
|
|
1434
|
+
if (res.status === "error") return Result.error(res.error);
|
|
1435
|
+
const result = await res.data.json();
|
|
1436
|
+
return Result.ok({
|
|
1437
|
+
accessToken: result.access_token,
|
|
1438
|
+
refreshToken: result.refresh_token
|
|
1439
|
+
});
|
|
1440
|
+
}
|
|
1441
|
+
async signUpAnonymously(session) {
|
|
1442
|
+
const res = await this.sendClientRequestAndCatchKnownError("/auth/anonymous/sign-up", { method: "POST" }, session, []);
|
|
1443
|
+
if (res.status === "error") return Result.error(res.error);
|
|
1444
|
+
const result = await res.data.json();
|
|
1445
|
+
return Result.ok({
|
|
1446
|
+
accessToken: result.access_token,
|
|
1447
|
+
refreshToken: result.refresh_token
|
|
1448
|
+
});
|
|
1449
|
+
}
|
|
1450
|
+
async signInWithMagicLink(code, session) {
|
|
1451
|
+
const res = await this.sendClientRequestAndCatchKnownError("/auth/otp/sign-in", {
|
|
1452
|
+
method: "POST",
|
|
1453
|
+
headers: { "Content-Type": "application/json" },
|
|
1454
|
+
body: JSON.stringify({ code })
|
|
1455
|
+
}, session, [KnownErrors.VerificationCodeError]);
|
|
1456
|
+
if (res.status === "error") return Result.error(res.error);
|
|
1457
|
+
const result = await res.data.json();
|
|
1458
|
+
return Result.ok({
|
|
1459
|
+
accessToken: result.access_token,
|
|
1460
|
+
refreshToken: result.refresh_token,
|
|
1461
|
+
newUser: result.is_new_user
|
|
1462
|
+
});
|
|
1463
|
+
}
|
|
1464
|
+
async signInWithMfa(totp, code, session) {
|
|
1465
|
+
const res = await this.sendClientRequestAndCatchKnownError("/auth/mfa/sign-in", {
|
|
1466
|
+
method: "POST",
|
|
1467
|
+
headers: { "Content-Type": "application/json" },
|
|
1468
|
+
body: JSON.stringify({
|
|
1469
|
+
type: "totp",
|
|
1470
|
+
totp,
|
|
1471
|
+
code
|
|
1472
|
+
})
|
|
1473
|
+
}, session, [KnownErrors.VerificationCodeError]);
|
|
1474
|
+
if (res.status === "error") return Result.error(res.error);
|
|
1475
|
+
const result = await res.data.json();
|
|
1476
|
+
return Result.ok({
|
|
1477
|
+
accessToken: result.access_token,
|
|
1478
|
+
refreshToken: result.refresh_token,
|
|
1479
|
+
newUser: result.is_new_user
|
|
1480
|
+
});
|
|
1481
|
+
}
|
|
1482
|
+
async signInWithPasskey(body, session) {
|
|
1483
|
+
const res = await this.sendClientRequestAndCatchKnownError("/auth/passkey/sign-in", {
|
|
1484
|
+
method: "POST",
|
|
1485
|
+
headers: { "Content-Type": "application/json" },
|
|
1486
|
+
body: JSON.stringify(body)
|
|
1487
|
+
}, session, [KnownErrors.PasskeyAuthenticationFailed]);
|
|
1488
|
+
if (res.status === "error") return Result.error(res.error);
|
|
1489
|
+
const result = await res.data.json();
|
|
1490
|
+
return Result.ok({
|
|
1491
|
+
accessToken: result.access_token,
|
|
1492
|
+
refreshToken: result.refresh_token
|
|
1493
|
+
});
|
|
1494
|
+
}
|
|
1495
|
+
async getOAuthUrl(options) {
|
|
1496
|
+
const updatedRedirectUrl = new URL(options.redirectUrl);
|
|
1497
|
+
for (const key of ["code", "state"]) {
|
|
1498
|
+
if (updatedRedirectUrl.searchParams.has(key)) console.warn("Redirect URL already contains " + key + " parameter, removing it as it will be overwritten by the OAuth callback");
|
|
1499
|
+
updatedRedirectUrl.searchParams.delete(key);
|
|
1500
|
+
}
|
|
1501
|
+
if ("projectOwnerSession" in this.options) throw new Error("Admin session token is currently not supported for OAuth");
|
|
1502
|
+
const clientSecret = this.options.publishableClientKey ?? publishableClientKeyNotNecessarySentinel;
|
|
1503
|
+
const url = new URL(this.getBestApiUrl() + "/auth/oauth/authorize/" + options.provider.toLowerCase());
|
|
1504
|
+
url.searchParams.set("client_id", this.projectId);
|
|
1505
|
+
url.searchParams.set("client_secret", clientSecret);
|
|
1506
|
+
url.searchParams.set("redirect_uri", updatedRedirectUrl.toString());
|
|
1507
|
+
url.searchParams.set("scope", "legacy");
|
|
1508
|
+
url.searchParams.set("state", options.state);
|
|
1509
|
+
url.searchParams.set("grant_type", "authorization_code");
|
|
1510
|
+
url.searchParams.set("code_challenge", options.codeChallenge);
|
|
1511
|
+
url.searchParams.set("code_challenge_method", "S256");
|
|
1512
|
+
url.searchParams.set("response_type", "code");
|
|
1513
|
+
url.searchParams.set("type", options.type);
|
|
1514
|
+
url.searchParams.set("error_redirect_url", options.errorRedirectUrl);
|
|
1515
|
+
const tokens = await options.session.getOrFetchLikelyValidTokens(45e3, 6e4);
|
|
1516
|
+
if (tokens) url.searchParams.set("token", tokens.accessToken.token);
|
|
1517
|
+
if (options.afterCallbackRedirectUrl) url.searchParams.set("after_callback_redirect_url", options.afterCallbackRedirectUrl);
|
|
1518
|
+
if (options.providerScope) url.searchParams.set("provider_scope", options.providerScope);
|
|
1519
|
+
for (const [key, value] of Object.entries(getBotChallengeRequestFields(options.botChallenge, `OAuth ${options.type}`))) url.searchParams.set(key, value);
|
|
1520
|
+
return url.toString();
|
|
1521
|
+
}
|
|
1522
|
+
async authorizeOAuth(options) {
|
|
1523
|
+
if (typeof window === "undefined") throw new HexclaveAssertionError("authorizeOAuth can currently only be called in a browser environment");
|
|
1524
|
+
await this.options.prepareRequest?.();
|
|
1525
|
+
const url = new URL(await this.getOAuthUrl(options));
|
|
1526
|
+
url.searchParams.set("hexclave_response_mode", "json");
|
|
1527
|
+
url.searchParams.set("stack_response_mode", "json");
|
|
1528
|
+
let rawRes;
|
|
1529
|
+
try {
|
|
1530
|
+
rawRes = await fetch(url, { method: "GET" });
|
|
1531
|
+
} catch (error) {
|
|
1532
|
+
if (error instanceof TypeError) throw await this._createNetworkError(error, options.session, "client");
|
|
1533
|
+
throw error;
|
|
1534
|
+
}
|
|
1535
|
+
const processedResponse = await this._processResponse(rawRes);
|
|
1536
|
+
if (processedResponse.status === "error") {
|
|
1537
|
+
if (isBotChallengeKnownError(processedResponse.error)) return Result.error(processedResponse.error);
|
|
1538
|
+
throw processedResponse.error;
|
|
1539
|
+
}
|
|
1540
|
+
if (processedResponse.data.status !== 200) throw new HexclaveAssertionError(`OAuth authorize returned an unexpected status: ${processedResponse.data.status}`);
|
|
1541
|
+
const body = await processedResponse.data.json();
|
|
1542
|
+
if (body == null || typeof body !== "object" || Array.isArray(body)) throw new HexclaveAssertionError("OAuth authorize response body must be an object", { body });
|
|
1543
|
+
const location = body.location;
|
|
1544
|
+
if (typeof location !== "string") throw new HexclaveAssertionError("OAuth authorize response is missing a redirect location", { body });
|
|
1545
|
+
return Result.ok(location);
|
|
1546
|
+
}
|
|
1547
|
+
async callOAuthCallback(options) {
|
|
1548
|
+
if ("projectOwnerSession" in this.options) throw new Error("Admin session token is currently not supported for OAuth");
|
|
1549
|
+
const clientSecret = this.options.publishableClientKey ?? publishableClientKeyNotNecessarySentinel;
|
|
1550
|
+
return await this._withFallback(async (apiUrl) => {
|
|
1551
|
+
return await this._callOAuthCallbackInner(options, clientSecret, apiUrl);
|
|
1552
|
+
});
|
|
1553
|
+
}
|
|
1554
|
+
async _callOAuthCallbackInner(options, clientSecret, apiUrl) {
|
|
1555
|
+
const tokenEndpoint = apiUrl + "/auth/oauth/token";
|
|
1556
|
+
const as = {
|
|
1557
|
+
issuer: this.options.getBaseUrl(),
|
|
1558
|
+
algorithm: "oauth2",
|
|
1559
|
+
token_endpoint: tokenEndpoint
|
|
1560
|
+
};
|
|
1561
|
+
const client = {
|
|
1562
|
+
client_id: this.projectId,
|
|
1563
|
+
client_secret: clientSecret
|
|
1564
|
+
};
|
|
1565
|
+
const clientAuthentication = ClientSecretPost(clientSecret);
|
|
1566
|
+
const allowInsecure = tokenEndpoint.startsWith("http://");
|
|
1567
|
+
let params;
|
|
1568
|
+
try {
|
|
1569
|
+
params = validateAuthResponse(as, client, options.oauthParams, options.state);
|
|
1570
|
+
} catch (e) {
|
|
1571
|
+
if (e instanceof AuthorizationResponseError) throw new HexclaveAssertionError("Authorization response error when validating outer OAuth response", {
|
|
1572
|
+
cause: Object.fromEntries(e.cause),
|
|
1573
|
+
code: e.code,
|
|
1574
|
+
error: e.error
|
|
1575
|
+
});
|
|
1576
|
+
throw new HexclaveAssertionError("Unexpected error when validating outer OAuth response", { cause: e });
|
|
1577
|
+
}
|
|
1578
|
+
const response = await authorizationCodeGrantRequest(as, client, clientAuthentication, params, options.redirectUri, options.codeVerifier, allowInsecure ? { [allowInsecureRequests]: true } : void 0);
|
|
1579
|
+
let result;
|
|
1580
|
+
try {
|
|
1581
|
+
result = await processAuthorizationCodeResponse(as, client, response);
|
|
1582
|
+
} catch (e) {
|
|
1583
|
+
if (e instanceof ResponseBodyError) {
|
|
1584
|
+
if (e.cause.code === "MULTI_FACTOR_AUTHENTICATION_REQUIRED") throw new KnownErrors.MultiFactorAuthenticationRequired(e.cause.details.attempt_code);
|
|
1585
|
+
throw new HexclaveAssertionError("Outer OAuth error during authorization code response", {
|
|
1586
|
+
cause: e.cause,
|
|
1587
|
+
code: e.code,
|
|
1588
|
+
error: e.error
|
|
1589
|
+
});
|
|
1590
|
+
}
|
|
1591
|
+
throw new HexclaveAssertionError("Unexpected error when processing authorization code response", { cause: e });
|
|
1592
|
+
}
|
|
1593
|
+
return {
|
|
1594
|
+
newUser: result.is_new_user,
|
|
1595
|
+
afterCallbackRedirectUrl: result.after_callback_redirect_url,
|
|
1596
|
+
accessToken: result.access_token,
|
|
1597
|
+
refreshToken: result.refresh_token ?? throwErr("Refresh token not found in outer OAuth response")
|
|
1598
|
+
};
|
|
1599
|
+
}
|
|
1600
|
+
async signOut(session) {
|
|
1601
|
+
if (await session.getOrFetchLikelyValidTokens(2e4, null)) {
|
|
1602
|
+
const resOrError = await this.sendClientRequestAndCatchKnownError("/auth/sessions/current", {
|
|
1603
|
+
method: "DELETE",
|
|
1604
|
+
headers: { "Content-Type": "application/json" },
|
|
1605
|
+
body: JSON.stringify({})
|
|
1606
|
+
}, session, [KnownErrors.RefreshTokenError]);
|
|
1607
|
+
if (resOrError.status === "error") if (KnownErrors.RefreshTokenError.isInstance(resOrError.error)) {} else throw new HexclaveAssertionError("Unexpected error", { cause: resOrError.error });
|
|
1608
|
+
}
|
|
1609
|
+
session.markInvalid();
|
|
1610
|
+
}
|
|
1611
|
+
async getClientUserByToken(session) {
|
|
1612
|
+
const responseOrError = await this.sendClientRequestAndCatchKnownError("/users/me", {}, session, [KnownErrors.CannotGetOwnUserWithoutUser]);
|
|
1613
|
+
if (responseOrError.status === "error") if (KnownErrors.CannotGetOwnUserWithoutUser.isInstance(responseOrError.error)) return null;
|
|
1614
|
+
else throw new HexclaveAssertionError("Unexpected uncaught error", { cause: responseOrError.error });
|
|
1615
|
+
const user = await responseOrError.data.json();
|
|
1616
|
+
if (!user) throw new HexclaveAssertionError("User endpoint returned null; this should never happen");
|
|
1617
|
+
return user;
|
|
1618
|
+
}
|
|
1619
|
+
async listTeamInvitations(options, session) {
|
|
1620
|
+
return (await (await this.sendClientRequest("/team-invitations?" + new URLSearchParams({ team_id: options.teamId }), {}, session)).json()).items;
|
|
1621
|
+
}
|
|
1622
|
+
async listCurrentUserTeamInvitations(session) {
|
|
1623
|
+
return (await (await this.sendClientRequest("/team-invitations?" + new URLSearchParams({ user_id: "me" }), {}, session)).json()).items;
|
|
1624
|
+
}
|
|
1625
|
+
async acceptTeamInvitationById(invitationId, session) {
|
|
1626
|
+
await this.sendClientRequest(urlString`/team-invitations/${invitationId}/accept` + "?" + new URLSearchParams({ user_id: "me" }), { method: "POST" }, session);
|
|
1627
|
+
}
|
|
1628
|
+
async revokeTeamInvitation(invitationId, teamId, session) {
|
|
1629
|
+
await this.sendClientRequest(`/team-invitations/${invitationId}?team_id=${teamId}`, { method: "DELETE" }, session);
|
|
1630
|
+
}
|
|
1631
|
+
async listTeamMemberProfiles(options, session) {
|
|
1632
|
+
return (await (await this.sendClientRequest("/team-member-profiles?" + new URLSearchParams(filterUndefined({
|
|
1633
|
+
team_id: options.teamId,
|
|
1634
|
+
user_id: options.userId
|
|
1635
|
+
})), {}, session)).json()).items;
|
|
1636
|
+
}
|
|
1637
|
+
async getTeamMemberProfile(options, session) {
|
|
1638
|
+
return await (await this.sendClientRequest(`/team-member-profiles/${options.teamId}/${options.userId}`, {}, session)).json();
|
|
1639
|
+
}
|
|
1640
|
+
async leaveTeam(teamId, session) {
|
|
1641
|
+
await this.sendClientRequest(`/team-memberships/${teamId}/me`, {
|
|
1642
|
+
method: "DELETE",
|
|
1643
|
+
headers: { "content-type": "application/json" },
|
|
1644
|
+
body: JSON.stringify({})
|
|
1645
|
+
}, session);
|
|
1646
|
+
}
|
|
1647
|
+
async updateTeamMemberProfile(options, session) {
|
|
1648
|
+
await this.sendClientRequest(`/team-member-profiles/${options.teamId}/${options.userId}`, {
|
|
1649
|
+
method: "PATCH",
|
|
1650
|
+
headers: { "content-type": "application/json" },
|
|
1651
|
+
body: JSON.stringify(options.profile)
|
|
1652
|
+
}, session);
|
|
1653
|
+
}
|
|
1654
|
+
async updateTeam(options, session) {
|
|
1655
|
+
await this.sendClientRequest(`/teams/${options.teamId}`, {
|
|
1656
|
+
method: "PATCH",
|
|
1657
|
+
headers: { "content-type": "application/json" },
|
|
1658
|
+
body: JSON.stringify(options.data)
|
|
1659
|
+
}, session);
|
|
1660
|
+
}
|
|
1661
|
+
async listCurrentUserTeamPermissions(options, session) {
|
|
1662
|
+
return (await (await this.sendClientRequest(`/team-permissions?team_id=${options.teamId}&user_id=me&recursive=${options.recursive}`, {}, session)).json()).items;
|
|
1663
|
+
}
|
|
1664
|
+
async listCurrentUserProjectPermissions(options, session) {
|
|
1665
|
+
return (await (await this.sendClientRequest(`/project-permissions?user_id=me&recursive=${options.recursive}`, {}, session)).json()).items;
|
|
1666
|
+
}
|
|
1667
|
+
async listCurrentUserTeams(session) {
|
|
1668
|
+
return (await (await this.sendClientRequest("/teams?user_id=me", {}, session)).json()).items;
|
|
1669
|
+
}
|
|
1670
|
+
async getClientProject() {
|
|
1671
|
+
const responseOrError = await this.sendClientRequestAndCatchKnownError("/projects/current", {}, null, [KnownErrors.ProjectNotFound]);
|
|
1672
|
+
if (responseOrError.status === "error") return Result.error(responseOrError.error);
|
|
1673
|
+
const project = await responseOrError.data.json();
|
|
1674
|
+
return Result.ok(project);
|
|
1675
|
+
}
|
|
1676
|
+
async updateClientUser(update, session) {
|
|
1677
|
+
await this.sendClientRequest("/users/me", {
|
|
1678
|
+
method: "PATCH",
|
|
1679
|
+
headers: { "content-type": "application/json" },
|
|
1680
|
+
body: JSON.stringify(update)
|
|
1681
|
+
}, session);
|
|
1682
|
+
}
|
|
1683
|
+
async listProjects(session) {
|
|
1684
|
+
const response = await this.sendClientRequest("/internal/projects", {}, session);
|
|
1685
|
+
if (!response.ok) throw new Error("Failed to list projects: " + response.status + " " + await response.text());
|
|
1686
|
+
return (await response.json()).items;
|
|
1687
|
+
}
|
|
1688
|
+
async createProject(project, session) {
|
|
1689
|
+
const fetchResponse = await this.sendClientRequest("/internal/projects", {
|
|
1690
|
+
method: "POST",
|
|
1691
|
+
headers: { "content-type": "application/json" },
|
|
1692
|
+
body: JSON.stringify(project)
|
|
1693
|
+
}, session);
|
|
1694
|
+
if (!fetchResponse.ok) throw new Error("Failed to create project: " + fetchResponse.status + " " + await fetchResponse.text());
|
|
1695
|
+
return await fetchResponse.json();
|
|
1696
|
+
}
|
|
1697
|
+
async createProviderAccessToken(provider, scope, session) {
|
|
1698
|
+
return await (await this.sendClientRequest(`/connected-accounts/me/${provider}/access-token`, {
|
|
1699
|
+
method: "POST",
|
|
1700
|
+
headers: { "content-type": "application/json" },
|
|
1701
|
+
body: JSON.stringify({ scope })
|
|
1702
|
+
}, session)).json();
|
|
1703
|
+
}
|
|
1704
|
+
/**
|
|
1705
|
+
* Get access token for a specific connected account by provider ID and provider account ID.
|
|
1706
|
+
* This is the preferred method when dealing with multiple accounts of the same provider.
|
|
1707
|
+
*/
|
|
1708
|
+
async createProviderAccessTokenByAccount(providerId, providerAccountId, scope, session) {
|
|
1709
|
+
return await (await this.sendClientRequest(`/connected-accounts/me/${encodeURIComponent(providerId)}/${encodeURIComponent(providerAccountId)}/access-token`, {
|
|
1710
|
+
method: "POST",
|
|
1711
|
+
headers: { "content-type": "application/json" },
|
|
1712
|
+
body: JSON.stringify({ scope })
|
|
1713
|
+
}, session)).json();
|
|
1714
|
+
}
|
|
1715
|
+
/**
|
|
1716
|
+
* List all connected accounts for the current user.
|
|
1717
|
+
*/
|
|
1718
|
+
async listConnectedAccounts(session) {
|
|
1719
|
+
return await (await this.sendClientRequest(`/connected-accounts/me`, { method: "GET" }, session)).json();
|
|
1720
|
+
}
|
|
1721
|
+
async createClientTeam(data, session) {
|
|
1722
|
+
return await (await this.sendClientRequest("/teams", {
|
|
1723
|
+
method: "POST",
|
|
1724
|
+
headers: { "content-type": "application/json" },
|
|
1725
|
+
body: JSON.stringify(data)
|
|
1726
|
+
}, session)).json();
|
|
1727
|
+
}
|
|
1728
|
+
async deleteTeam(teamId, session) {
|
|
1729
|
+
await this.sendClientRequest(`/teams/${teamId}`, { method: "DELETE" }, session);
|
|
1730
|
+
}
|
|
1731
|
+
async deleteCurrentUser(session) {
|
|
1732
|
+
await this.sendClientRequest("/users/me", { method: "DELETE" }, session);
|
|
1733
|
+
}
|
|
1734
|
+
async createClientContactChannel(data, session) {
|
|
1735
|
+
return await (await this.sendClientRequest("/contact-channels", {
|
|
1736
|
+
method: "POST",
|
|
1737
|
+
headers: { "content-type": "application/json" },
|
|
1738
|
+
body: JSON.stringify(data)
|
|
1739
|
+
}, session)).json();
|
|
1740
|
+
}
|
|
1741
|
+
async updateClientContactChannel(id, data, session) {
|
|
1742
|
+
return await (await this.sendClientRequest(`/contact-channels/me/${id}`, {
|
|
1743
|
+
method: "PATCH",
|
|
1744
|
+
headers: { "content-type": "application/json" },
|
|
1745
|
+
body: JSON.stringify(data)
|
|
1746
|
+
}, session)).json();
|
|
1747
|
+
}
|
|
1748
|
+
async deleteClientContactChannel(id, session) {
|
|
1749
|
+
await this.sendClientRequest(`/contact-channels/me/${id}`, { method: "DELETE" }, session);
|
|
1750
|
+
}
|
|
1751
|
+
async deleteSession(sessionId, session) {
|
|
1752
|
+
await this.sendClientRequest(`/auth/sessions/${sessionId}?user_id=me`, { method: "DELETE" }, session);
|
|
1753
|
+
}
|
|
1754
|
+
async listSessions(session) {
|
|
1755
|
+
return await (await this.sendClientRequest("/auth/sessions?user_id=me", { method: "GET" }, session)).json();
|
|
1756
|
+
}
|
|
1757
|
+
async listClientContactChannels(session) {
|
|
1758
|
+
return (await (await this.sendClientRequest("/contact-channels?user_id=me", { method: "GET" }, session)).json()).items;
|
|
1759
|
+
}
|
|
1760
|
+
async sendCurrentUserContactChannelVerificationEmail(contactChannelId, callbackUrl, session) {
|
|
1761
|
+
const responseOrError = await this.sendClientRequestAndCatchKnownError(`/contact-channels/me/${contactChannelId}/send-verification-code`, {
|
|
1762
|
+
method: "POST",
|
|
1763
|
+
headers: { "content-type": "application/json" },
|
|
1764
|
+
body: JSON.stringify({ callback_url: callbackUrl })
|
|
1765
|
+
}, session, [KnownErrors.EmailAlreadyVerified]);
|
|
1766
|
+
if (responseOrError.status === "error") return Result.error(responseOrError.error);
|
|
1767
|
+
return Result.ok(void 0);
|
|
1768
|
+
}
|
|
1769
|
+
async cliLogin(loginCode, refreshToken, session) {
|
|
1770
|
+
const responseOrError = await this.sendClientRequestAndCatchKnownError("/auth/cli/complete", {
|
|
1771
|
+
method: "POST",
|
|
1772
|
+
headers: { "Content-Type": "application/json" },
|
|
1773
|
+
body: JSON.stringify({
|
|
1774
|
+
login_code: loginCode,
|
|
1775
|
+
refresh_token: refreshToken
|
|
1776
|
+
})
|
|
1777
|
+
}, session, [KnownErrors.SchemaError]);
|
|
1778
|
+
if (responseOrError.status === "error") return Result.error(responseOrError.error);
|
|
1779
|
+
return Result.ok(void 0);
|
|
1780
|
+
}
|
|
1781
|
+
async _getApiKeyRequestInfo(options) {
|
|
1782
|
+
if ("user_id" in options && "team_id" in options) throw new HexclaveAssertionError("Cannot specify both user_id and team_id in _getApiKeyRequestInfo");
|
|
1783
|
+
return {
|
|
1784
|
+
endpoint: "team_id" in options ? "/team-api-keys" : "/user-api-keys",
|
|
1785
|
+
queryParams: new URLSearchParams(filterUndefinedOrNull(options))
|
|
1786
|
+
};
|
|
1787
|
+
}
|
|
1788
|
+
async listProjectApiKeys(options, session, requestType) {
|
|
1789
|
+
const sendRequest = (requestType === "client" ? this.sendClientRequest : this.sendServerRequest).bind(this);
|
|
1790
|
+
const { endpoint, queryParams } = await this._getApiKeyRequestInfo(options);
|
|
1791
|
+
return (await (await sendRequest(`${endpoint}?${queryParams.toString()}`, { method: "GET" }, session, requestType)).json()).items;
|
|
1792
|
+
}
|
|
1793
|
+
async createProjectApiKey(data, session, requestType) {
|
|
1794
|
+
const sendRequest = (requestType === "client" ? this.sendClientRequest : this.sendServerRequest).bind(this);
|
|
1795
|
+
const { endpoint } = await this._getApiKeyRequestInfo(data);
|
|
1796
|
+
return await (await sendRequest(`${endpoint}`, {
|
|
1797
|
+
method: "POST",
|
|
1798
|
+
headers: { "content-type": "application/json" },
|
|
1799
|
+
body: JSON.stringify(data)
|
|
1800
|
+
}, session, requestType)).json();
|
|
1801
|
+
}
|
|
1802
|
+
async getProjectApiKey(options, keyId, session, requestType) {
|
|
1803
|
+
const sendRequest = (requestType === "client" ? this.sendClientRequest : this.sendServerRequest).bind(this);
|
|
1804
|
+
const { endpoint, queryParams } = await this._getApiKeyRequestInfo(options);
|
|
1805
|
+
return await (await sendRequest(`${endpoint}/${keyId}?${queryParams.toString()}`, { method: "GET" }, session, requestType)).json();
|
|
1806
|
+
}
|
|
1807
|
+
async updateProjectApiKey(options, keyId, data, session, requestType) {
|
|
1808
|
+
const sendRequest = (requestType === "client" ? this.sendClientRequest : this.sendServerRequest).bind(this);
|
|
1809
|
+
const { endpoint, queryParams } = await this._getApiKeyRequestInfo(options);
|
|
1810
|
+
return await (await sendRequest(`${endpoint}/${keyId}?${queryParams.toString()}`, {
|
|
1811
|
+
method: "PATCH",
|
|
1812
|
+
headers: { "content-type": "application/json" },
|
|
1813
|
+
body: JSON.stringify(data)
|
|
1814
|
+
}, session, requestType)).json();
|
|
1815
|
+
}
|
|
1816
|
+
async checkProjectApiKey(type, apiKey, session, requestType) {
|
|
1817
|
+
const result = await (requestType === "client" ? this.sendClientRequestAndCatchKnownError : this.sendServerRequestAndCatchKnownError).bind(this)(`/${type}-api-keys/check`, {
|
|
1818
|
+
method: "POST",
|
|
1819
|
+
headers: { "content-type": "application/json" },
|
|
1820
|
+
body: JSON.stringify({ api_key: apiKey })
|
|
1821
|
+
}, session, [KnownErrors.ApiKeyNotValid]);
|
|
1822
|
+
if (result.status === "error") return null;
|
|
1823
|
+
return await result.data.json();
|
|
1824
|
+
}
|
|
1825
|
+
async listNotificationCategories(session) {
|
|
1826
|
+
return (await (await this.sendClientRequest(`/emails/notification-preference/me`, {}, session)).json()).items;
|
|
1827
|
+
}
|
|
1828
|
+
async setNotificationsEnabled(notificationCategoryId, enabled, session) {
|
|
1829
|
+
await this.sendClientRequest(`/emails/notification-preference/me/${notificationCategoryId}`, {
|
|
1830
|
+
method: "PATCH",
|
|
1831
|
+
headers: { "content-type": "application/json" },
|
|
1832
|
+
body: JSON.stringify({ enabled })
|
|
1833
|
+
}, session);
|
|
1834
|
+
}
|
|
1835
|
+
async getOAuthProvider(userId, providerId, session) {
|
|
1836
|
+
return await (await this.sendClientRequest(`/oauth-providers/${userId}/${providerId}`, { method: "GET" }, session)).json();
|
|
1837
|
+
}
|
|
1838
|
+
async updateOAuthProvider(userId, providerId, data, session) {
|
|
1839
|
+
return await (await this.sendClientRequest(`/oauth-providers/${userId}/${providerId}`, {
|
|
1840
|
+
method: "PATCH",
|
|
1841
|
+
headers: { "content-type": "application/json" },
|
|
1842
|
+
body: JSON.stringify(data)
|
|
1843
|
+
}, session)).json();
|
|
1844
|
+
}
|
|
1845
|
+
async listOAuthProviders(options = {}, session) {
|
|
1846
|
+
const queryParams = new URLSearchParams(filterUndefined(options));
|
|
1847
|
+
return (await (await this.sendClientRequest(`/oauth-providers${queryParams.toString() ? `?${queryParams.toString()}` : ""}`, { method: "GET" }, session)).json()).items;
|
|
1848
|
+
}
|
|
1849
|
+
async deleteOAuthProvider(userId, providerId, session) {
|
|
1850
|
+
return await (await this.sendClientRequest(`/oauth-providers/${userId}/${providerId}`, { method: "DELETE" }, session)).json();
|
|
1851
|
+
}
|
|
1852
|
+
async getItem(options, session, requestType = "client") {
|
|
1853
|
+
let customerType;
|
|
1854
|
+
let customerId;
|
|
1855
|
+
if ("userId" in options) {
|
|
1856
|
+
customerType = "user";
|
|
1857
|
+
customerId = options.userId;
|
|
1858
|
+
} else if ("teamId" in options) {
|
|
1859
|
+
customerType = "team";
|
|
1860
|
+
customerId = options.teamId;
|
|
1861
|
+
} else if ("customCustomerId" in options) {
|
|
1862
|
+
customerType = "custom";
|
|
1863
|
+
customerId = options.customCustomerId;
|
|
1864
|
+
} else throw new HexclaveAssertionError("getItem requires one of userId, teamId, or customCustomerId");
|
|
1865
|
+
return await (await (requestType === "client" ? this.sendClientRequest : this.sendServerRequest).bind(this)(urlString`/payments/items/${customerType}/${customerId}/${options.itemId}`, {}, session, requestType)).json();
|
|
1866
|
+
}
|
|
1867
|
+
async listProducts(options, session, requestType = "client") {
|
|
1868
|
+
const queryParams = new URLSearchParams(filterUndefined({
|
|
1869
|
+
cursor: options.cursor,
|
|
1870
|
+
limit: options.limit !== void 0 ? options.limit.toString() : void 0
|
|
1871
|
+
}));
|
|
1872
|
+
const path = urlString`/payments/products/${options.customer_type}/${options.customer_id}`;
|
|
1873
|
+
return await (await (requestType === "client" ? this.sendClientRequest : this.sendServerRequest).bind(this)(`${path}${queryParams.toString() ? `?${queryParams.toString()}` : ""}`, {}, session, requestType)).json();
|
|
1874
|
+
}
|
|
1875
|
+
async listInvoices(options, session) {
|
|
1876
|
+
const queryParams = new URLSearchParams(filterUndefined({
|
|
1877
|
+
cursor: options.cursor,
|
|
1878
|
+
limit: options.limit !== void 0 ? options.limit.toString() : void 0
|
|
1879
|
+
}));
|
|
1880
|
+
const path = urlString`/payments/invoices/${options.customer_type}/${options.customer_id}`;
|
|
1881
|
+
return await (await this.sendClientRequest(`${path}${queryParams.toString() ? `?${queryParams.toString()}` : ""}`, {}, session)).json();
|
|
1882
|
+
}
|
|
1883
|
+
async cancelSubscription(options, session) {
|
|
1884
|
+
const queryParams = new URLSearchParams(filterUndefined({ subscription_id: options.subscription_id }));
|
|
1885
|
+
const path = urlString`/payments/products/${options.customer_type}/${options.customer_id}/${options.product_id}`;
|
|
1886
|
+
await this.sendClientRequest(`${path}${queryParams.toString() ? `?${queryParams.toString()}` : ""}`, { method: "DELETE" }, session);
|
|
1887
|
+
}
|
|
1888
|
+
async switchSubscription(options, session) {
|
|
1889
|
+
await this.sendClientRequest(urlString`/payments/products/${options.customer_type}/${options.customer_id}/switch`, {
|
|
1890
|
+
method: "POST",
|
|
1891
|
+
headers: { "content-type": "application/json" },
|
|
1892
|
+
body: JSON.stringify({
|
|
1893
|
+
from_product_id: options.from_product_id,
|
|
1894
|
+
to_product_id: options.to_product_id,
|
|
1895
|
+
price_id: options.price_id,
|
|
1896
|
+
quantity: options.quantity
|
|
1897
|
+
})
|
|
1898
|
+
}, session);
|
|
1899
|
+
}
|
|
1900
|
+
async createCheckoutUrl(customer_type, customer_id, productIdOrInline, session, returnUrl, requestType = "client") {
|
|
1901
|
+
const productBody = typeof productIdOrInline === "string" ? { product_id: productIdOrInline } : { product_inline: productIdOrInline };
|
|
1902
|
+
const { url } = await (await (requestType === "client" ? this.sendClientRequest : this.sendServerRequest).bind(this)("/payments/purchases/create-purchase-url", {
|
|
1903
|
+
method: "POST",
|
|
1904
|
+
headers: { "content-type": "application/json" },
|
|
1905
|
+
body: JSON.stringify({
|
|
1906
|
+
customer_type,
|
|
1907
|
+
customer_id,
|
|
1908
|
+
...productBody,
|
|
1909
|
+
return_url: returnUrl
|
|
1910
|
+
})
|
|
1911
|
+
}, session, requestType)).json();
|
|
1912
|
+
return url;
|
|
1913
|
+
}
|
|
1914
|
+
async getCustomerBilling(customerType, customerId, session) {
|
|
1915
|
+
return await (await this.sendClientRequest(urlString`/payments/billing/${customerType}/${customerId}`, {}, session)).json();
|
|
1916
|
+
}
|
|
1917
|
+
async createCustomerPaymentMethodSetupIntent(customerType, customerId, session) {
|
|
1918
|
+
return await (await this.sendClientRequest(urlString`/payments/payment-method/${customerType}/${customerId}/setup-intent`, {
|
|
1919
|
+
method: "POST",
|
|
1920
|
+
headers: { "content-type": "application/json" },
|
|
1921
|
+
body: JSON.stringify({})
|
|
1922
|
+
}, session)).json();
|
|
1923
|
+
}
|
|
1924
|
+
async setDefaultCustomerPaymentMethodFromSetupIntent(customerType, customerId, setupIntentId, session) {
|
|
1925
|
+
return await (await this.sendClientRequest(urlString`/payments/payment-method/${customerType}/${customerId}/set-default`, {
|
|
1926
|
+
method: "POST",
|
|
1927
|
+
headers: { "content-type": "application/json" },
|
|
1928
|
+
body: JSON.stringify({ setup_intent_id: setupIntentId })
|
|
1929
|
+
}, session)).json();
|
|
1930
|
+
}
|
|
1931
|
+
async transferProject(internalProjectSession, projectIdToTransfer, newTeamId) {
|
|
1932
|
+
if (this.options.projectId !== "internal") throw new HexclaveAssertionError("HexclaveClientInterface.transferProject() is only available for internal projects (please specify the project ID in the constructor)");
|
|
1933
|
+
await this.sendClientRequest("/internal/projects/transfer", {
|
|
1934
|
+
method: "POST",
|
|
1935
|
+
headers: { "content-type": "application/json" },
|
|
1936
|
+
body: JSON.stringify({
|
|
1937
|
+
project_id: projectIdToTransfer,
|
|
1938
|
+
new_team_id: newTeamId
|
|
1939
|
+
})
|
|
1940
|
+
}, internalProjectSession);
|
|
1941
|
+
}
|
|
1942
|
+
};
|
|
1943
|
+
|
|
1944
|
+
//#endregion
|
|
1945
|
+
export { HexclaveClientInterface };
|
|
1946
|
+
//# sourceMappingURL=client-interface.js.map
|