@estifanos-sh/convex-auth 0.0.3 → 0.0.4
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/README.md +24 -1
- package/dist/bin.js +1 -32
- package/dist/browser/index.js +15 -9
- package/dist/browser/index.js.map +1 -1
- package/dist/client/core/types.d.ts +35 -25
- package/dist/client/core/types.d.ts.map +1 -1
- package/dist/client/core/types.js.map +1 -1
- package/dist/client/factors/device.js +4 -4
- package/dist/client/factors/device.js.map +1 -1
- package/dist/client/factors/totp.js +20 -12
- package/dist/client/factors/totp.js.map +1 -1
- package/dist/client/factors/webauthn.js +6 -2
- package/dist/client/factors/webauthn.js.map +1 -1
- package/dist/client/index.js +10 -8
- package/dist/client/index.js.map +1 -1
- package/dist/component/_generated/api.d.ts +13 -3
- package/dist/component/_generated/api.d.ts.map +1 -1
- package/dist/component/_generated/api.js.map +1 -1
- package/dist/component/_generated/component.d.ts +255 -33
- package/dist/component/_generated/component.d.ts.map +1 -1
- package/dist/component/_generated/dataModel.d.ts +3 -3
- package/dist/component/_generated/dataModel.d.ts.map +1 -1
- package/dist/component/_generated/server.d.ts +13 -2
- package/dist/component/_generated/server.d.ts.map +1 -1
- package/dist/component/_generated/server.js +2 -1
- package/dist/component/_generated/server.js.map +1 -1
- package/dist/component/account.d.ts +39 -31
- package/dist/component/account.d.ts.map +1 -1
- package/dist/component/account.js +28 -7
- package/dist/component/account.js.map +1 -1
- package/dist/component/batch.d.ts +3 -0
- package/dist/component/batch.d.ts.map +1 -0
- package/dist/component/batch.js +17 -0
- package/dist/component/batch.js.map +1 -0
- package/dist/component/connection/audit.d.ts +19 -16
- package/dist/component/connection/audit.d.ts.map +1 -1
- package/dist/component/connection/audit.js +14 -22
- package/dist/component/connection/audit.js.map +1 -1
- package/dist/component/connection/cache.d.ts +6 -6
- package/dist/component/connection/cache.js +0 -1
- package/dist/component/connection/cache.js.map +1 -1
- package/dist/component/connection/domain/verification.d.ts +15 -15
- package/dist/component/connection/domain/verification.js +1 -2
- package/dist/component/connection/domain/verification.js.map +1 -1
- package/dist/component/connection/domain.d.ts +18 -18
- package/dist/component/connection/domain.js +1 -2
- package/dist/component/connection/domain.js.map +1 -1
- package/dist/component/connection/saml/assertion.d.ts +4 -4
- package/dist/component/connection/saml/assertion.js +0 -1
- package/dist/component/connection/saml/assertion.js.map +1 -1
- package/dist/component/connection/saml/request.d.ts +7 -8
- package/dist/component/connection/saml/request.d.ts.map +1 -1
- package/dist/component/connection/saml/request.js +0 -2
- package/dist/component/connection/saml/request.js.map +1 -1
- package/dist/component/connection/scim/config.d.ts +11 -11
- package/dist/component/connection/scim/config.d.ts.map +1 -1
- package/dist/component/connection/scim/config.js +2 -2
- package/dist/component/connection/scim/config.js.map +1 -1
- package/dist/component/connection/scim/identity.d.ts +75 -57
- package/dist/component/connection/scim/identity.d.ts.map +1 -1
- package/dist/component/connection/scim/identity.js +79 -32
- package/dist/component/connection/scim/identity.js.map +1 -1
- package/dist/component/connection/secret.d.ts +13 -13
- package/dist/component/connection/secret.d.ts.map +1 -1
- package/dist/component/connection/secret.js +2 -2
- package/dist/component/connection/secret.js.map +1 -1
- package/dist/component/connection/webhook/delivery.d.ts +33 -33
- package/dist/component/connection/webhook/delivery.d.ts.map +1 -1
- package/dist/component/connection/webhook/delivery.js +3 -3
- package/dist/component/connection/webhook/delivery.js.map +1 -1
- package/dist/component/connection/webhook/endpoint.d.ts +21 -21
- package/dist/component/connection/webhook/endpoint.d.ts.map +1 -1
- package/dist/component/connection/webhook/endpoint.js +2 -2
- package/dist/component/connection/webhook/endpoint.js.map +1 -1
- package/dist/component/connection.d.ts +26 -26
- package/dist/component/connection.d.ts.map +1 -1
- package/dist/component/connection.js +9 -9
- package/dist/component/connection.js.map +1 -1
- package/dist/component/context.d.ts +19 -19
- package/dist/component/context.js +1 -2
- package/dist/component/context.js.map +1 -1
- package/dist/component/convex.config.d.ts +2 -2
- package/dist/component/crons.d.ts +2 -2
- package/dist/component/documents.d.ts +1244 -0
- package/dist/component/documents.d.ts.map +1 -0
- package/dist/component/documents.js +44 -0
- package/dist/component/documents.js.map +1 -0
- package/dist/component/event.d.ts +65 -60
- package/dist/component/event.d.ts.map +1 -1
- package/dist/component/event.js +6 -6
- package/dist/component/event.js.map +1 -1
- package/dist/component/eventstream.d.ts +6 -6
- package/dist/component/eventstream.d.ts.map +1 -1
- package/dist/component/eventstream.js +17 -8
- package/dist/component/eventstream.js.map +1 -1
- package/dist/component/factor/device.d.ts +21 -21
- package/dist/component/factor/device.d.ts.map +1 -1
- package/dist/component/factor/device.js +2 -2
- package/dist/component/factor/device.js.map +1 -1
- package/dist/component/factor/passkey.d.ts +153 -74
- package/dist/component/factor/passkey.d.ts.map +1 -1
- package/dist/component/factor/passkey.js +132 -21
- package/dist/component/factor/passkey.js.map +1 -1
- package/dist/component/factor/totp.d.ts +48 -47
- package/dist/component/factor/totp.d.ts.map +1 -1
- package/dist/component/factor/totp.js +3 -2
- package/dist/component/factor/totp.js.map +1 -1
- package/dist/component/group/active.d.ts +89 -89
- package/dist/component/group/active.d.ts.map +1 -1
- package/dist/component/group/active.js +1 -2
- package/dist/component/group/active.js.map +1 -1
- package/dist/component/group/invite.d.ts +30 -30
- package/dist/component/group/invite.d.ts.map +1 -1
- package/dist/component/group/invite.js +2 -2
- package/dist/component/group/invite.js.map +1 -1
- package/dist/component/group/member.d.ts +36 -36
- package/dist/component/group/member.d.ts.map +1 -1
- package/dist/component/group/member.js +5 -3
- package/dist/component/group/member.js.map +1 -1
- package/dist/component/group.d.ts +36 -36
- package/dist/component/group.d.ts.map +1 -1
- package/dist/component/group.js +5 -3
- package/dist/component/group.js.map +1 -1
- package/dist/component/http.d.ts +2 -2
- package/dist/component/index.d.ts +0 -10
- package/dist/component/index.js +1 -3
- package/dist/component/limits.d.ts +5 -4
- package/dist/component/limits.d.ts.map +1 -1
- package/dist/component/limits.js +7 -4
- package/dist/component/limits.js.map +1 -1
- package/dist/component/maintenance.d.ts +6 -3
- package/dist/component/maintenance.d.ts.map +1 -1
- package/dist/component/maintenance.js +45 -6
- package/dist/component/maintenance.js.map +1 -1
- package/dist/component/model.d.ts +518 -1729
- package/dist/component/model.d.ts.map +1 -1
- package/dist/component/model.js +10 -316
- package/dist/component/model.js.map +1 -1
- package/dist/component/modules.d.ts +9 -9
- package/dist/component/modules.js +1 -1
- package/dist/component/modules.js.map +1 -1
- package/dist/component/oauth/client.d.ts +18 -18
- package/dist/component/oauth/client.d.ts.map +1 -1
- package/dist/component/oauth/client.js +2 -2
- package/dist/component/oauth/client.js.map +1 -1
- package/dist/component/oauth/code.d.ts +11 -11
- package/dist/component/oauth/code.js +1 -2
- package/dist/component/oauth/code.js.map +1 -1
- package/dist/component/oauth/refresh.d.ts +17 -17
- package/dist/component/oauth/refresh.js +1 -2
- package/dist/component/oauth/refresh.js.map +1 -1
- package/dist/component/schema.d.ts +716 -664
- package/dist/component/schema.d.ts.map +1 -1
- package/dist/component/schema.js +29 -14
- package/dist/component/schema.js.map +1 -1
- package/dist/component/session.d.ts +36 -40
- package/dist/component/session.d.ts.map +1 -1
- package/dist/component/session.js +19 -23
- package/dist/component/session.js.map +1 -1
- package/dist/component/token/continuation.d.ts +24 -17
- package/dist/component/token/continuation.d.ts.map +1 -1
- package/dist/component/token/continuation.js +21 -9
- package/dist/component/token/continuation.js.map +1 -1
- package/dist/component/token/enrollment.d.ts +42 -0
- package/dist/component/token/enrollment.d.ts.map +1 -0
- package/dist/component/token/enrollment.js +57 -0
- package/dist/component/token/enrollment.js.map +1 -0
- package/dist/component/token/pkce.d.ts +31 -24
- package/dist/component/token/pkce.d.ts.map +1 -1
- package/dist/component/token/pkce.js +15 -20
- package/dist/component/token/pkce.js.map +1 -1
- package/dist/component/token/refresh.d.ts +37 -34
- package/dist/component/token/refresh.d.ts.map +1 -1
- package/dist/component/token/refresh.js +7 -4
- package/dist/component/token/refresh.js.map +1 -1
- package/dist/component/token/verification.d.ts +32 -32
- package/dist/component/token/verification.d.ts.map +1 -1
- package/dist/component/token/verification.js +4 -3
- package/dist/component/token/verification.js.map +1 -1
- package/dist/component/user/email.d.ts +17 -17
- package/dist/component/user/email.d.ts.map +1 -1
- package/dist/component/user/email.js +2 -2
- package/dist/component/user/email.js.map +1 -1
- package/dist/component/user/key.d.ts +27 -27
- package/dist/component/user/key.d.ts.map +1 -1
- package/dist/component/user/key.js +2 -2
- package/dist/component/user/key.js.map +1 -1
- package/dist/component/user.d.ts +38 -40
- package/dist/component/user.d.ts.map +1 -1
- package/dist/component/user.js +157 -36
- package/dist/component/user.js.map +1 -1
- package/dist/expo/index.d.ts +2 -2
- package/dist/expo/index.d.ts.map +1 -1
- package/dist/expo/index.js +20 -13
- package/dist/expo/index.js.map +1 -1
- package/dist/node_modules/.pnpm/@opentelemetry_sdk-logs@0.214.0_@opentelemetry_api@1.9.1/node_modules/@opentelemetry/sdk-logs/build/src/export/ReadableLogRecord.d.ts +2 -2
- package/dist/node_modules/.pnpm/@opentelemetry_sdk-logs@0.214.0_@opentelemetry_api@1.9.1/node_modules/@opentelemetry/sdk-logs/build/src/export/SdkLogRecord.d.ts +1 -1
- package/dist/node_modules/.pnpm/@opentelemetry_sdk-metrics@2.6.1_@opentelemetry_api@1.9.1/node_modules/@opentelemetry/sdk-metrics/build/src/MeterProvider.d.ts +2 -2
- package/dist/node_modules/.pnpm/@opentelemetry_sdk-metrics@2.6.1_@opentelemetry_api@1.9.1/node_modules/@opentelemetry/sdk-metrics/build/src/export/MetricData.d.ts +1 -1
- package/dist/node_modules/.pnpm/@opentelemetry_sdk-trace-base@2.6.1_@opentelemetry_api@1.9.1/node_modules/@opentelemetry/sdk-trace-base/build/src/Span.d.ts +1 -1
- package/dist/node_modules/.pnpm/@opentelemetry_sdk-trace-base@2.6.1_@opentelemetry_api@1.9.1/node_modules/@opentelemetry/sdk-trace-base/build/src/export/ReadableSpan.d.ts +1 -1
- package/dist/node_modules/.pnpm/@opentelemetry_sdk-trace-base@2.6.1_@opentelemetry_api@1.9.1/node_modules/@opentelemetry/sdk-trace-base/build/src/types.d.ts +1 -1
- package/dist/otel.d.ts +1 -1
- package/dist/providers/anonymous.d.ts +3 -3
- package/dist/providers/anonymous.d.ts.map +1 -1
- package/dist/providers/apple.js +19 -4
- package/dist/providers/apple.js.map +1 -1
- package/dist/providers/credentials.d.ts +1 -1
- package/dist/providers/credentials.d.ts.map +1 -1
- package/dist/providers/credentials.js.map +1 -1
- package/dist/providers/github.d.ts.map +1 -1
- package/dist/providers/github.js +9 -4
- package/dist/providers/github.js.map +1 -1
- package/dist/providers/google.d.ts.map +1 -1
- package/dist/providers/google.js +9 -4
- package/dist/providers/google.js.map +1 -1
- package/dist/providers/microsoft.d.ts.map +1 -1
- package/dist/providers/microsoft.js +12 -4
- package/dist/providers/microsoft.js.map +1 -1
- package/dist/providers/password.d.ts +58 -51
- package/dist/providers/password.d.ts.map +1 -1
- package/dist/providers/password.js.map +1 -1
- package/dist/providers/webauthn.d.ts.map +1 -1
- package/dist/providers/webauthn.js +6 -0
- package/dist/providers/webauthn.js.map +1 -1
- package/dist/server/auth.d.ts +72 -14
- package/dist/server/auth.d.ts.map +1 -1
- package/dist/server/auth.js +3 -3
- package/dist/server/auth.js.map +1 -1
- package/dist/server/component/factor/db.js +10 -3
- package/dist/server/component/factor/db.js.map +1 -1
- package/dist/server/config.d.ts +1 -1
- package/dist/server/connection/domain.d.ts +2 -1
- package/dist/server/connection/domain.d.ts.map +1 -1
- package/dist/server/connection/domain.js +7 -1
- package/dist/server/connection/domain.js.map +1 -1
- package/dist/server/connection/group/service.js +1 -1
- package/dist/server/connection/http.js +60 -48
- package/dist/server/connection/http.js.map +1 -1
- package/dist/server/connection/saml/encoding.js +2 -6
- package/dist/server/connection/saml/encoding.js.map +1 -1
- package/dist/server/connection/saml/signature.js +2 -2
- package/dist/server/connection/saml/signature.js.map +1 -1
- package/dist/server/connection/saml/xmldsig.js +1 -1
- package/dist/server/connection/saml/xmldsig.js.map +1 -1
- package/dist/server/context.js +1 -1
- package/dist/server/context.js.map +1 -1
- package/dist/server/contract.d.ts.map +1 -1
- package/dist/server/contract.js.map +1 -1
- package/dist/server/core.js +40 -1
- package/dist/server/core.js.map +1 -1
- package/dist/server/cors.d.ts +2 -2
- package/dist/server/db.js +4 -1
- package/dist/server/db.js.map +1 -1
- package/dist/server/device.js +1 -1
- package/dist/server/domains/account.d.ts +9 -1
- package/dist/server/domains/account.d.ts.map +1 -1
- package/dist/server/domains/account.js +21 -9
- package/dist/server/domains/account.js.map +1 -1
- package/dist/server/domains/invite.js.map +1 -1
- package/dist/server/domains/session.js.map +1 -1
- package/dist/server/events.d.ts +3 -0
- package/dist/server/events.d.ts.map +1 -1
- package/dist/server/facade.d.ts +1 -33
- package/dist/server/facade.d.ts.map +1 -1
- package/dist/server/facade.js +1 -2
- package/dist/server/facade.js.map +1 -1
- package/dist/server/http.d.ts.map +1 -1
- package/dist/server/http.js.map +1 -1
- package/dist/server/index.d.ts +6 -8
- package/dist/server/index.js +2 -3
- package/dist/server/limits.js +2 -1
- package/dist/server/limits.js.map +1 -1
- package/dist/server/mutations/calls.js +3 -2
- package/dist/server/mutations/credentials/signin.js +1 -0
- package/dist/server/mutations/credentials/signin.js.map +1 -1
- package/dist/server/mutations/enrollment.js +87 -0
- package/dist/server/mutations/enrollment.js.map +1 -0
- package/dist/server/mutations/oauth.js +2 -2
- package/dist/server/mutations/refresh.js +1 -0
- package/dist/server/mutations/refresh.js.map +1 -1
- package/dist/server/mutations/register.js +52 -21
- package/dist/server/mutations/register.js.map +1 -1
- package/dist/server/mutations/store.js +6 -1
- package/dist/server/mutations/store.js.map +1 -1
- package/dist/server/mutations/verify.js +2 -1
- package/dist/server/mutations/verify.js.map +1 -1
- package/dist/server/oauth/client.d.ts +1 -1
- package/dist/server/oauth/client.js.map +1 -1
- package/dist/server/oauth/code.d.ts +1 -1
- package/dist/server/oauth/code.js.map +1 -1
- package/dist/server/oauth/factory.js +89 -13
- package/dist/server/oauth/factory.js.map +1 -1
- package/dist/server/oauth/handlers.js +2 -2
- package/dist/server/oauth/runtime.js +24 -9
- package/dist/server/oauth/runtime.js.map +1 -1
- package/dist/server/preload.d.ts.map +1 -1
- package/dist/server/preload.js +14 -11
- package/dist/server/preload.js.map +1 -1
- package/dist/server/runtime.d.ts +213 -105
- package/dist/server/runtime.d.ts.map +1 -1
- package/dist/server/runtime.js +66 -33
- package/dist/server/runtime.js.map +1 -1
- package/dist/server/session/lifecycle.d.ts +2 -1
- package/dist/server/session/lifecycle.d.ts.map +1 -1
- package/dist/server/session/lifecycle.js +12 -8
- package/dist/server/session/lifecycle.js.map +1 -1
- package/dist/server/signin/flow.js +1 -1
- package/dist/server/telemetry.js +1 -1
- package/dist/server/tokens.js +5 -3
- package/dist/server/tokens.js.map +1 -1
- package/dist/server/totp.js +1 -0
- package/dist/server/totp.js.map +1 -1
- package/dist/server/types.d.ts +79 -13
- package/dist/server/types.d.ts.map +1 -1
- package/dist/server/validators.d.ts +703 -674
- package/dist/server/validators.d.ts.map +1 -1
- package/dist/server/validators.js +34 -8
- package/dist/server/validators.js.map +1 -1
- package/dist/server/webauthn.js +57 -26
- package/dist/server/webauthn.js.map +1 -1
- package/dist/shared/results.d.ts +6 -0
- package/dist/shared/results.d.ts.map +1 -1
- package/dist/test.d.ts +772 -673
- package/dist/test.d.ts.map +1 -1
- package/dist/test.js +50 -1
- package/dist/test.js.map +1 -1
- package/package.json +4 -14
- package/dist/_generated/component.d.ts +0 -3143
- package/dist/_generated/component.d.ts.map +0 -1
- package/dist/_generated/dataModel.d.ts +0 -28
- package/dist/_generated/dataModel.d.ts.map +0 -1
- package/dist/component/functions.d.ts +0 -9
- package/dist/component/functions.d.ts.map +0 -1
- package/dist/component/functions.js +0 -3
- package/dist/core/index.d.ts +0 -497
- package/dist/core/index.d.ts.map +0 -1
- package/dist/core/index.js +0 -83
- package/dist/core/index.js.map +0 -1
- package/dist/model.js.map +0 -1
package/README.md
CHANGED
|
@@ -13,8 +13,13 @@ Configure the component in `convex/convex.config.ts`:
|
|
|
13
13
|
```ts
|
|
14
14
|
import auth from "@estifanos-sh/convex-auth/convex.config";
|
|
15
15
|
import { defineApp } from "convex/server";
|
|
16
|
+
import { v } from "convex/values";
|
|
16
17
|
|
|
17
|
-
const app = defineApp(
|
|
18
|
+
const app = defineApp({
|
|
19
|
+
env: {
|
|
20
|
+
CONVEX_SITE_URL: v.string(),
|
|
21
|
+
},
|
|
22
|
+
});
|
|
18
23
|
app.use(auth);
|
|
19
24
|
|
|
20
25
|
export default app;
|
|
@@ -37,8 +42,26 @@ export const auth = defineAuth(components.auth, {
|
|
|
37
42
|
permissions,
|
|
38
43
|
providers: [password(), webauthn()],
|
|
39
44
|
});
|
|
45
|
+
|
|
46
|
+
export const { signIn, signOut, store } = auth;
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Pass the generated actions directly to the browser client. The provider IDs,
|
|
50
|
+
custom credential validators, action results, and enabled factor helpers are
|
|
51
|
+
inferred without a generic or type assertion.
|
|
52
|
+
|
|
53
|
+
```ts
|
|
54
|
+
import { client } from "@estifanos-sh/convex-auth/browser";
|
|
55
|
+
import { api } from "../convex/_generated/api";
|
|
56
|
+
|
|
57
|
+
export const authClient = client({ convex, api: api.auth });
|
|
40
58
|
```
|
|
41
59
|
|
|
60
|
+
Convex Auth owns users, provider accounts, credential secrets, passkeys,
|
|
61
|
+
recovery continuations, and sessions. Application tables should reference the
|
|
62
|
+
branded auth `userId`; they should not mirror those records or manufacture auth
|
|
63
|
+
IDs in tests.
|
|
64
|
+
|
|
42
65
|
Read the [installation guide](https://estifanos.sh/convex-auth/getting-started/installation/)
|
|
43
66
|
for the complete setup, generated files, environment variables, client bindings,
|
|
44
67
|
and provider configuration.
|
package/dist/bin.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from "node:module";
|
|
3
3
|
import { execFileSync } from "node:child_process";
|
|
4
|
-
import { existsSync, lstatSync,
|
|
4
|
+
import { existsSync, lstatSync, mkdtempSync, readFileSync, readdirSync, unlinkSync, writeFileSync } from "node:fs";
|
|
5
5
|
import os, { tmpdir } from "node:os";
|
|
6
6
|
import path, { dirname, join } from "node:path";
|
|
7
7
|
import process$1, { stdin, stdout } from "node:process";
|
|
@@ -6537,7 +6537,6 @@ async function runSetup(options) {
|
|
|
6537
6537
|
await configureConvexConfig(config);
|
|
6538
6538
|
await initializeAuth(config);
|
|
6539
6539
|
await initializeHttp(config);
|
|
6540
|
-
await initializeAuthCore(config);
|
|
6541
6540
|
await initializeAuthConfig(config);
|
|
6542
6541
|
if (options.variables !== void 0) await configureOtherVariables(config, options.variables);
|
|
6543
6542
|
else printFinalSuccessMessage(config);
|
|
@@ -6887,36 +6886,6 @@ export default auth.http();
|
|
|
6887
6886
|
O.success(`Created ${newPath}`);
|
|
6888
6887
|
}
|
|
6889
6888
|
}
|
|
6890
|
-
async function initializeAuthCore(config) {
|
|
6891
|
-
logStep(config, "Initialize auth/core file");
|
|
6892
|
-
const sourceTemplate = `\
|
|
6893
|
-
import { createAuthContext } from "@estifanos-sh/convex-auth/core";
|
|
6894
|
-
import { components } from "../_generated/api";
|
|
6895
|
-
|
|
6896
|
-
export const auth = createAuthContext(components.auth);
|
|
6897
|
-
`;
|
|
6898
|
-
const source = templateToSource(sourceTemplate);
|
|
6899
|
-
const authDir = path.join(config.convexFolderPath, "auth");
|
|
6900
|
-
const corePath = path.join(authDir, "core");
|
|
6901
|
-
const existingPath = existingNonEmptySourcePath(corePath);
|
|
6902
|
-
if (existingPath !== null) if (doesAlreadyMatchTemplate(readFileSync(existingPath, "utf8"), sourceTemplate)) O.success(`${existingPath} is already set up.`);
|
|
6903
|
-
else {
|
|
6904
|
-
O.info(`You already have ${existingPath}. Make sure it uses createAuthContext:`);
|
|
6905
|
-
O.message(indent(`\n${source}\n`));
|
|
6906
|
-
const ready = await ot({ message: "Ready to continue?" });
|
|
6907
|
-
handleCancel(ready);
|
|
6908
|
-
if (!ready) {
|
|
6909
|
-
pt("Setup cancelled.");
|
|
6910
|
-
process$1.exit(1);
|
|
6911
|
-
}
|
|
6912
|
-
}
|
|
6913
|
-
else {
|
|
6914
|
-
if (!existsSync(authDir)) mkdirSync(authDir, { recursive: true });
|
|
6915
|
-
const newPath = config.usesTypeScript ? `${corePath}.ts` : `${corePath}.js`;
|
|
6916
|
-
writeFileSync(newPath, source);
|
|
6917
|
-
O.success(`Created ${newPath}`);
|
|
6918
|
-
}
|
|
6919
|
-
}
|
|
6920
6889
|
async function initializeAuthConfig(config) {
|
|
6921
6890
|
logStep(config, "Initialize auth.config file");
|
|
6922
6891
|
const sourceTemplate = `\
|
package/dist/browser/index.js
CHANGED
|
@@ -28,17 +28,23 @@ import { ConvexHttpClient } from "convex/browser";
|
|
|
28
28
|
* @returns A browser auth client with the configured auth helpers.
|
|
29
29
|
*/
|
|
30
30
|
function client(options) {
|
|
31
|
-
const
|
|
32
|
-
const
|
|
31
|
+
const runtime = mergeBrowserRuntime(options.runtime);
|
|
32
|
+
const adapterFactories = {
|
|
33
|
+
...options.adapterFactories,
|
|
34
|
+
webauthn: options.adapterFactories?.webauthn ?? ((deps) => createWebAuthnClient(deps))
|
|
35
|
+
};
|
|
36
|
+
if (options.proxyPath !== void 0) return client$1({
|
|
37
|
+
...options,
|
|
38
|
+
storage: options.storage ?? null,
|
|
39
|
+
runtime,
|
|
40
|
+
adapterFactories
|
|
41
|
+
});
|
|
42
|
+
const url = options.url ?? resolveUrl(options.convex);
|
|
33
43
|
return client$1({
|
|
34
44
|
...options,
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
...options.adapterFactories,
|
|
39
|
-
webauthn: options.adapterFactories?.webauthn ?? ((deps) => createWebAuthnClient(deps))
|
|
40
|
-
},
|
|
41
|
-
httpClient: proxyMode ? null : options.httpClient ?? (url ? new ConvexHttpClient(url) : null)
|
|
45
|
+
runtime,
|
|
46
|
+
adapterFactories,
|
|
47
|
+
httpClient: options.httpClient ?? new ConvexHttpClient(url)
|
|
42
48
|
});
|
|
43
49
|
}
|
|
44
50
|
function mergeBrowserRuntime(runtime) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["createClient"],"sources":["../../src/browser/index.ts"],"sourcesContent":["/**\n * Browser-first auth client for `@estifanos-sh/convex-auth/browser`.\n *\n * This entrypoint wraps the framework-agnostic `client(...)`\n * helper with browser defaults such as `ConvexHttpClient`, local storage, URL\n * replacement, OAuth launching, and WebAuthn adapters.\n *\n * @module\n */\n\nimport { ConvexHttpClient } from \"convex/browser\";\n\nimport {\n client as createClient,\n resolveUrl,\n type ClientOptions,\n type PlatformAuthClient,\n} from \"../client/index\";\nimport type { AuthApiRefs } from \"../client/core/types\";\nimport { createWebAuthnClient } from \"./webauthn\";\nimport { createBrowserRuntime } from \"./runtime\";\n\nexport type { PlatformAuthClient as AuthClient, ClientOptions } from \"../client/index\";\n\n/**\n * Create a browser-configured auth client.\n *\n * Applies browser runtime defaults (`ConvexHttpClient` transport, local\n * storage, URL cleanup, OAuth launch, WebAuthn support) on top of the\n * framework-agnostic `client(...)` helper, then returns it directly — the core\n * owns OAuth launch/completion and initialization, driven by the injected\n * browser runtime.\n *\n * @param options - Browser client configuration. See {@link ClientOptions}.\n * @typeParam Api - Auth API references that control which factor helpers are\n * available on the returned client.\n * @returns A browser auth client with the configured auth helpers.\n */\nexport function client<Api extends AuthApiRefs = AuthApiRefs>(\n options: ClientOptions<Api>,\n): PlatformAuthClient<Api> {\n const
|
|
1
|
+
{"version":3,"file":"index.js","names":["createClient"],"sources":["../../src/browser/index.ts"],"sourcesContent":["/**\n * Browser-first auth client for `@estifanos-sh/convex-auth/browser`.\n *\n * This entrypoint wraps the framework-agnostic `client(...)`\n * helper with browser defaults such as `ConvexHttpClient`, local storage, URL\n * replacement, OAuth launching, and WebAuthn adapters.\n *\n * @module\n */\n\nimport { ConvexHttpClient } from \"convex/browser\";\n\nimport {\n client as createClient,\n resolveUrl,\n type ClientOptions,\n type PlatformAuthClient,\n} from \"../client/index\";\nimport type { AuthApiRefs } from \"../client/core/types\";\nimport { createWebAuthnClient } from \"./webauthn\";\nimport { createBrowserRuntime } from \"./runtime\";\n\nexport type { PlatformAuthClient as AuthClient, ClientOptions } from \"../client/index\";\n\n/**\n * Create a browser-configured auth client.\n *\n * Applies browser runtime defaults (`ConvexHttpClient` transport, local\n * storage, URL cleanup, OAuth launch, WebAuthn support) on top of the\n * framework-agnostic `client(...)` helper, then returns it directly — the core\n * owns OAuth launch/completion and initialization, driven by the injected\n * browser runtime.\n *\n * @param options - Browser client configuration. See {@link ClientOptions}.\n * @typeParam Api - Auth API references that control which factor helpers are\n * available on the returned client.\n * @returns A browser auth client with the configured auth helpers.\n */\nexport function client<Api extends AuthApiRefs = AuthApiRefs>(\n options: ClientOptions<Api>,\n): PlatformAuthClient<Api> {\n const runtime = mergeBrowserRuntime(options.runtime);\n const adapterFactories = {\n ...options.adapterFactories,\n webauthn: options.adapterFactories?.webauthn ?? ((deps) => createWebAuthnClient(deps)),\n };\n\n if (options.proxyPath !== undefined) {\n return createClient<Api>({\n ...options,\n storage: options.storage ?? null,\n runtime,\n adapterFactories,\n }) as unknown as PlatformAuthClient<Api>;\n }\n\n const url = options.url ?? resolveUrl(options.convex);\n return createClient<Api>({\n ...options,\n runtime,\n adapterFactories,\n httpClient: options.httpClient ?? new ConvexHttpClient(url),\n }) as unknown as PlatformAuthClient<Api>;\n}\n\nfunction mergeBrowserRuntime(\n runtime: ClientOptions[\"runtime\"],\n): NonNullable<ClientOptions[\"runtime\"]> {\n const defaults = createBrowserRuntime();\n return {\n ...defaults,\n ...runtime,\n environment: runtime?.environment ?? defaults.environment,\n proxy: runtime?.proxy ?? defaults.proxy,\n storage: runtime?.storage === undefined ? defaults.storage : runtime.storage,\n location: runtime?.location ?? defaults.location,\n oauth: runtime?.oauth ?? defaults.oauth,\n sync: runtime?.sync ?? defaults.sync,\n mutex: runtime?.mutex ?? defaults.mutex,\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsCA,SAAgB,OACd,SACyB;CACzB,MAAM,UAAU,oBAAoB,QAAQ,QAAQ;CACpD,MAAM,mBAAmB;EACvB,GAAG,QAAQ;EACX,UAAU,QAAQ,kBAAkB,cAAc,SAAS,qBAAqB,KAAK;EACtF;AAED,KAAI,QAAQ,cAAc,OACxB,QAAOA,SAAkB;EACvB,GAAG;EACH,SAAS,QAAQ,WAAW;EAC5B;EACA;EACD,CAAC;CAGJ,MAAM,MAAM,QAAQ,OAAO,WAAW,QAAQ,OAAO;AACrD,QAAOA,SAAkB;EACvB,GAAG;EACH;EACA;EACA,YAAY,QAAQ,cAAc,IAAI,iBAAiB,IAAI;EAC5D,CAAC;;AAGJ,SAAS,oBACP,SACuC;CACvC,MAAM,WAAW,sBAAsB;AACvC,QAAO;EACL,GAAG;EACH,GAAG;EACH,aAAa,SAAS,eAAe,SAAS;EAC9C,OAAO,SAAS,SAAS,SAAS;EAClC,SAAS,SAAS,YAAY,SAAY,SAAS,UAAU,QAAQ;EACrE,UAAU,SAAS,YAAY,SAAS;EACxC,OAAO,SAAS,SAAS,SAAS;EAClC,MAAM,SAAS,QAAQ,SAAS;EAChC,OAAO,SAAS,SAAS,SAAS;EACnC"}
|
|
@@ -143,11 +143,13 @@ type AuthSubscriber = (state: AuthState) => void;
|
|
|
143
143
|
* @typeParam HasDevice - Whether the device provider is configured.
|
|
144
144
|
*/
|
|
145
145
|
type DefaultSignInReference = FunctionReference<"action", "public", {
|
|
146
|
-
|
|
147
|
-
|
|
146
|
+
request: {
|
|
147
|
+
provider?: string;
|
|
148
|
+
params?: AuthParameters;
|
|
149
|
+
refreshToken?: string;
|
|
150
|
+
};
|
|
148
151
|
verifier?: string;
|
|
149
152
|
continuation?: string;
|
|
150
|
-
refreshToken?: string;
|
|
151
153
|
calledBy?: string;
|
|
152
154
|
}, unknown>;
|
|
153
155
|
type AnySignInReference = FunctionReference<"action", "public", any, any>;
|
|
@@ -389,7 +391,10 @@ interface DeviceClient {
|
|
|
389
391
|
*
|
|
390
392
|
* @typeParam Api - An AuthApiRefs type to extract capability flags from.
|
|
391
393
|
*/
|
|
392
|
-
type
|
|
394
|
+
type SignInRequest<Api extends AuthApiRefs> = FunctionArgs<Api["signIn"]> extends infer Args ? Args extends {
|
|
395
|
+
request: infer Request;
|
|
396
|
+
} ? Request : Args : never;
|
|
397
|
+
type ProviderIds<Api extends AuthApiRefs> = [Api["signIn"]] extends [never] ? string : SignInRequest<Api> extends infer Args ? Args extends unknown ? "provider" extends keyof Args ? Exclude<Args[keyof Args & "provider"], undefined> : never : never : never;
|
|
393
398
|
type HasProvider<Api extends AuthApiRefs, Id extends string> = string extends ProviderIds<Api> ? boolean : Id extends ProviderIds<Api> ? true : false;
|
|
394
399
|
type InferCaps<Api extends AuthApiRefs> = {
|
|
395
400
|
webauthn: HasProvider<Api, "webauthn">;
|
|
@@ -441,9 +446,9 @@ type OAuthSignInParams = OAuthParams;
|
|
|
441
446
|
* providers can be registered under arbitrary IDs.
|
|
442
447
|
*/
|
|
443
448
|
type DefaultParamsForProvider<P> = P extends "password" ? PasswordParams : P extends "email" ? EmailInitiateParams : P extends "anonymous" ? AnonymousParams | undefined : P extends "connection" ? ConnectionParams : P extends "webauthn" ? never : P extends undefined ? CodeCompletionParams : OAuthSignInParams | undefined;
|
|
444
|
-
type ConfiguredProviderArgs<Api extends AuthApiRefs, P> =
|
|
449
|
+
type ConfiguredProviderArgs<Api extends AuthApiRefs, P> = SignInRequest<Api> extends infer Args ? (Args extends {
|
|
445
450
|
provider: P;
|
|
446
|
-
} ? Args : never : never;
|
|
451
|
+
} ? Args : never) : never;
|
|
447
452
|
/** Resolve a provider's exact params from the generated auth action reference. */
|
|
448
453
|
type ParamsForProvider<Api extends AuthApiRefs, P> = string extends ProviderIds<Api> ? DefaultParamsForProvider<P> : P extends "webauthn" | "totp" | "device" ? never : P extends "connection" ? ConnectionParams : [P] extends [undefined] ? CodeCompletionParams : ConfiguredProviderArgs<Api, P> extends infer Args ? [Args] extends [never] ? never : Args extends {
|
|
449
454
|
params: infer Params;
|
|
@@ -518,22 +523,12 @@ type PlatformAuthClient<Api extends AuthApiRefs = AuthApiRefs> = AuthClient<Api>
|
|
|
518
523
|
*
|
|
519
524
|
* @typeParam Api - An AuthApiRefs type.
|
|
520
525
|
*/
|
|
521
|
-
type
|
|
526
|
+
type ClientOptionsBase = {
|
|
522
527
|
/** Any Convex client implementation used to run auth actions. */convex: ConvexTransport; /** Platform runtime implementation used by the client core. */
|
|
523
528
|
runtime?: ClientRuntime; /** Platform-specific factor adapters supplied by higher-level entrypoints. */
|
|
524
529
|
adapters?: ClientAdapters; /** Platform-specific adapter factories supplied by higher-level entrypoints. */
|
|
525
|
-
adapterFactories?: ClientAdapterFactories;
|
|
526
|
-
/**
|
|
527
|
-
* Typed auth function refs from your generated `api` object.
|
|
528
|
-
* Required outside proxy mode.
|
|
529
|
-
*/
|
|
530
|
-
api?: Api; /** Explicit Convex deployment URL when it cannot be inferred from the client. */
|
|
530
|
+
adapterFactories?: ClientAdapterFactories; /** Explicit Convex deployment URL when it cannot be inferred from the client. */
|
|
531
531
|
url?: string;
|
|
532
|
-
/**
|
|
533
|
-
* Optional action-only transport for direct code exchange outside proxy mode.
|
|
534
|
-
* Required in non-browser runtimes when `proxyPath` is not set.
|
|
535
|
-
*/
|
|
536
|
-
httpClient?: ActionTransport | null;
|
|
537
532
|
/**
|
|
538
533
|
* Storage backend for persisted tokens.
|
|
539
534
|
*
|
|
@@ -548,13 +543,7 @@ type ClientOptions<Api extends AuthApiRefs = AuthApiRefs> = {
|
|
|
548
543
|
* persisted value from `storage` instead. Ongoing persistence always uses
|
|
549
544
|
* `storage`.
|
|
550
545
|
*/
|
|
551
|
-
token?: string | null;
|
|
552
|
-
/**
|
|
553
|
-
* Proxy endpoint used instead of direct Convex auth calls.
|
|
554
|
-
* When set, provide `runtime.proxy` and omit direct `api`/`httpClient`
|
|
555
|
-
* transport requirements.
|
|
556
|
-
*/
|
|
557
|
-
proxyPath?: string; /** SSR-safe URL source for reading query parameters. */
|
|
546
|
+
token?: string | null; /** SSR-safe URL source for reading query parameters. */
|
|
558
547
|
location?: URL | (() => URL | null);
|
|
559
548
|
/**
|
|
560
549
|
* Default OAuth `redirectTo` applied to `signIn` calls that omit it. Platform
|
|
@@ -569,6 +558,27 @@ type ClientOptions<Api extends AuthApiRefs = AuthApiRefs> = {
|
|
|
569
558
|
*/
|
|
570
559
|
handshakeTimeoutMs?: number;
|
|
571
560
|
};
|
|
561
|
+
/** Direct Convex mode. Generated auth references are the client contract. */
|
|
562
|
+
type DirectClientOptions<Api extends AuthApiRefs = AuthApiRefs> = ClientOptionsBase & {
|
|
563
|
+
/** Typed auth function refs from the application's generated `api` object. */api: Api; /** Proxy transport and direct transport are mutually exclusive. */
|
|
564
|
+
proxyPath?: never;
|
|
565
|
+
/**
|
|
566
|
+
* Action-only transport used for direct code exchange. Browser and Expo
|
|
567
|
+
* entrypoints provide one automatically; headless runtimes must inject it.
|
|
568
|
+
*/
|
|
569
|
+
httpClient?: ActionTransport | null;
|
|
570
|
+
};
|
|
571
|
+
/** HTTP proxy mode. The proxy owns the Convex function references. */
|
|
572
|
+
type ProxyClientOptions = ClientOptionsBase & {
|
|
573
|
+
/** Proxy endpoint used instead of direct Convex auth calls. */proxyPath: string; /** Generated references belong to direct mode and cannot be mixed with a proxy. */
|
|
574
|
+
api?: never; /** Direct action transports belong to direct mode. */
|
|
575
|
+
httpClient?: never;
|
|
576
|
+
};
|
|
577
|
+
/**
|
|
578
|
+
* Client configuration. Selecting direct or proxy mode makes every required
|
|
579
|
+
* transport explicit and prevents the two modes from being combined.
|
|
580
|
+
*/
|
|
581
|
+
type ClientOptions<Api extends AuthApiRefs = AuthApiRefs> = DirectClientOptions<Api> | ProxyClientOptions;
|
|
572
582
|
type OAuthCompletionResult = {
|
|
573
583
|
handled: false;
|
|
574
584
|
} | {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","names":[],"sources":["../../../src/client/core/types.ts"],"mappings":";;;;;;;;;AA6BA;;;;;;;UAAiB,eAAA;EACf,MAAA,CAAO,MAAA,WAAiB,IAAA,YAAgB,OAAA,CAAQ,KAAA;EAChD,OAAA,CACE,UAAA,GAAa,IAAA;IAAQ,iBAAA;EAAA,MAAiC,OAAA,6BACtD,QAAA,IAAY,eAAA;EAEd,SAAA;AAAA;;UAIe,eAAA;EACf,MAAA,CAAO,MAAA,WAAiB,IAAA,YAAgB,OAAA,CAAQ,KAAA;AAAA;;UAOjC,OAAA;EACf,OAAA,CAAQ,GAAA,uCAA0C,OAAA;EAClD,OAAA,CAAQ,GAAA,UAAa,KAAA,kBAAuB,OAAA;EAC5C,UAAA,CAAW,GAAA,kBAAqB,OAAA;AAAA;;UAIxB,eAAA;EACR,GAAA,IAAO,GAAA;EACP,OAAA,CAAQ,WAAA,kBAA6B,OAAA;AAAA;;;;;;AATvC;;;UAoBU,YAAA;EACR,IAAA,CAAK,GAAA,EAAK,GAAA,mBAAsB,GAAA,GAAM,OAAA,iBAAwB,GAAA;AAAA;;UAItD,WAAA;EACR,SAAA,CACE,GAAA,UACA,QAAA,GAAW,KAAA,2BAAgC,OAAA;AAAA;;UAKrC,YAAA;EACR,OAAA,IAAW,GAAA,UAAa,QAAA,QAAgB,OAAA,CAAQ,CAAA,IAAK,OAAA,CAAQ,CAAA;AAAA;;UAIrD,YAAA;EACR,KAAA,CAAM,IAAA,EAAM,cAAA,EAAgB,SAAA,WAAoB,OAAA,CAAQ,QAAA;AAAA;;;AAnCzD;;;;UA4CgB,aAAA;EACf,WAAA;EACA,OAAA,GAAU,OAAA;EACV,QAAA,GAAW,eAAA;EACX,KAAA,GAAQ,YAAA;EACR,IAAA,GAAO,WAAA;EACP,KAAA,GAAQ,YAAA;EACR,KAAA,GAAQ,YAAA;AAAA;;UAIO,cAAA;EACf,QAAA,GAAW,cAAA;EACX,IAAA,GAAO,UAAA;EACP,MAAA,GAAS,YAAA;AAAA;;;;
|
|
1
|
+
{"version":3,"file":"types.d.ts","names":[],"sources":["../../../src/client/core/types.ts"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","names":[],"sources":["../../../src/client/core/types.ts"],"sourcesContent":["import type { FunctionArgs, FunctionReference } from \"convex/server\";\nimport type { ConvexError, Value } from \"convex/values\";\n\nimport type { AccessToken } from \"../../shared/brand\";\nimport type {\n AnonymousParams,\n CodeParams,\n ConnectionParams,\n EmailParams,\n OAuthParams,\n PasswordParams,\n} from \"../../shared/params\";\nimport type {\n AuthParameters,\n AuthTokens,\n SignInFlowResult,\n SignInWebAuthnOptionsResult,\n} from \"../../shared/results\";\nimport type { ErrorCode } from \"../../shared/codes\";\n\n/**\n * Structural interface for any Convex client.\n * Satisfied by `ConvexClient` (`convex/browser`),\n * `ConvexReactClient` (`convex/react`), and similar transports.\n *\n * `clearAuth` is present on `ConvexReactClient` and `BaseConvexClient`\n * but not on the simplified `ConvexClient`. When available we call it\n * during sign-out for a clean deauthentication.\n */\nexport interface ConvexTransport {\n action(action: unknown, args: unknown): Promise<Value>;\n setAuth(\n fetchToken: (args: { forceRefreshToken: boolean }) => Promise<string | null | undefined>,\n onChange?: (isAuthenticated: boolean) => void,\n ): void;\n clearAuth?(): void;\n}\n\n/** Minimal action-only transport used for unauthenticated auth flows. */\nexport interface ActionTransport {\n action(action: unknown, args: unknown): Promise<Value>;\n}\n\n/** @internal */\nexport type SignInApiRef = { signIn: AuthApiRefs[\"signIn\"] };\n\n/** Pluggable key-value storage supplied by the host runtime. */\nexport interface Storage {\n getItem(key: string): string | null | undefined | Promise<string | null | undefined>;\n setItem(key: string, value: string): void | Promise<void>;\n removeItem(key: string): void | Promise<void>;\n}\n\n/** Platform-neutral location/navigation hooks. */\ninterface LocationRuntime {\n get(): URL | null;\n replace(relativeUrl: string): void | Promise<void>;\n}\n\n/**\n * Platform-specific OAuth launch primitive.\n *\n * `open` receives the provider authorization URL. Platforms that navigate the\n * whole page away (browser) return nothing; platforms that run the flow in an\n * in-app session (Expo) return the callback URL so the core can complete the\n * exchange inline.\n */\ninterface OAuthRuntime {\n open(url: URL): void | string | URL | Promise<void | string | URL>;\n}\n\n/** Cross-context synchronization hooks, such as browser storage events. */\ninterface SyncRuntime {\n subscribe(\n key: string,\n callback: (value: string | null) => void | Promise<void>,\n ): (() => void) | null;\n}\n\n/** Cross-context mutex/locking primitive. */\ninterface MutexRuntime {\n withKey<T>(key: string, callback: () => Promise<T>): Promise<T>;\n}\n\n/** Proxy request execution supplied by the host runtime. */\ninterface ProxyRuntime {\n fetch(body: AuthParameters, proxyPath: string): Promise<Response>;\n}\n\n/**\n * Platform-neutral client runtime dependencies.\n *\n * The core `client` package should depend only on these interfaces, while the\n * browser package can provide concrete implementations backed by DOM APIs.\n */\nexport interface ClientRuntime {\n environment?: \"client\" | \"server\";\n storage?: Storage | null;\n location?: LocationRuntime;\n oauth?: OAuthRuntime;\n sync?: SyncRuntime;\n mutex?: MutexRuntime;\n proxy?: ProxyRuntime;\n}\n\n/** Platform-specific factor adapters injected by entrypoints like `browser`. */\nexport interface ClientAdapters {\n webauthn?: WebAuthnClient;\n totp?: TotpClient;\n device?: DeviceClient;\n}\n\n/**\n * Shared dependencies threaded into every factor client (`totp`, `device`,\n * `webauthn`). The core `client` builds one of these and passes it to each\n * factor factory.\n *\n * @internal\n */\nexport interface FactorDeps {\n proxy: string | undefined;\n convex: ConvexTransport;\n requireApiRefs: () => SignInApiRef;\n proxyFetch: (body: AuthParameters) => Promise<Value>;\n setTokenAndMaybeWait: (\n args:\n | {\n shouldStore: true;\n tokens: AuthTokens | null;\n waitForHandshake: boolean;\n context: { provider?: string; flow: string };\n }\n | {\n shouldStore: false;\n tokens: { token: AccessToken } | null;\n waitForHandshake: boolean;\n context: { provider?: string; flow: string };\n },\n ) => Promise<boolean>;\n}\n\n/**\n * Dependencies provided to platform-specific factor adapters.\n *\n * @internal\n */\nexport type ClientAdapterDeps = FactorDeps;\n\n/**\n * Factory overrides for platform-specific factor adapters.\n *\n * @internal\n */\nexport interface ClientAdapterFactories {\n webauthn?: (deps: ClientAdapterDeps) => WebAuthnClient;\n}\n\n/** @internal */\nexport type SignInActionResult = SignInFlowResult<AuthTokens | null>;\n\n/** @internal */\nexport type WebAuthnRotationResult = Extract<SignInWebAuthnOptionsResult, { operation: \"rotate\" }>;\n\n/**\n * Device authorization payload returned from the `deviceCode` sign-in flow.\n */\nexport type DeviceCodeResult = {\n deviceCode: string;\n userCode: string;\n verificationUri: string;\n verificationUriComplete: string;\n expiresIn: number;\n interval: number;\n};\n\n/**\n * Result of a `signIn` call.\n *\n * - `kind: \"signedIn\"` — credentials were accepted and a client session is now available.\n * - `kind: \"redirect\"` — OAuth flow initiated; redirect the user to `redirect.toString()`.\n * - `kind: \"totpRequired\"` — credentials valid but 2FA is needed; call `auth.totp.verify()`.\n * - `kind: \"deviceCode\"` — device flow initiated; display the code and poll via `auth.device.poll()`.\n * - `kind: \"started\"` — a non-immediate flow started (for example email/phone verification).\n * - `kind: \"failed\"` — the flow did not complete; `code` is the typed {@link ErrorCode}.\n *\n * @see {@link AuthState}\n */\nexport type SignInResult =\n | { kind: \"signedIn\" }\n | { kind: \"redirect\"; redirect: URL; verifier: string }\n | { kind: \"totpRequired\"; verifier: string }\n | { kind: \"deviceCode\"; deviceCode: DeviceCodeResult }\n | { kind: \"started\" }\n | { kind: \"failed\"; code: ErrorCode };\n\n/** @internal */\nexport type AuthSnapshot = {\n phase: \"loading\" | \"handshake\" | \"authenticated\" | \"unauthenticated\";\n isLoading: boolean;\n isAuthenticated: boolean;\n token: string | null;\n};\n\n/** Reactive auth state. `token` is non-null only after Convex confirms auth. */\nexport type AuthState =\n | { status: \"loading\"; token: null }\n | { status: \"signedOut\"; token: null }\n | { status: \"signedIn\"; token: string };\n\n/** Handler for `auth.subscribe`. */\nexport type AuthSubscriber = (state: AuthState) => void;\n\n/**\n * Typed Convex API references for the auth functions.\n * Pass these from your generated `api` object.\n *\n * @typeParam HasWebAuthn - Whether the WebAuthn provider is configured.\n * @typeParam HasTotp - Whether the TOTP provider is configured.\n * @typeParam HasDevice - Whether the device provider is configured.\n */\ntype DefaultSignInReference = FunctionReference<\n \"action\",\n \"public\",\n {\n provider?: string;\n params?: AuthParameters;\n verifier?: string;\n continuation?: string;\n refreshToken?: string;\n calledBy?: string;\n },\n unknown\n>;\n\ntype AnySignInReference = FunctionReference<\"action\", \"public\", any, any>;\n\nexport type AuthApiRefs<SignIn extends AnySignInReference = DefaultSignInReference> = {\n signIn: SignIn;\n signOut: FunctionReference<\"action\", \"public\", Record<string, Value>, unknown>;\n};\n\n/**\n * Optional hints for {@link WebAuthnClient.register}.\n */\nexport type WebAuthnRegisterOptions = {\n /** Human-readable label for this credential (e.g. `\"MacBook Pro\"`). */\n name?: string;\n /** WebAuthn `user.name` override. */\n userName?: string;\n /** WebAuthn `user.displayName` override. */\n userDisplayName?: string;\n};\n\n/**\n * Optional hints for {@link WebAuthnClient.signIn}.\n */\nexport type WebAuthnSignInOptions = {\n /** Email hint to filter discoverable credentials. */\n email?: string;\n /** Set to `true` for conditional UI (autofill) mode. */\n autofill?: boolean;\n};\n\n/**\n * WebAuthn client-side helpers.\n *\n * @see {@link TotpClient}\n * @see {@link DeviceClient}\n */\nexport interface WebAuthnClient {\n /**\n * Check whether the current runtime exposes WebAuthn passkey APIs.\n *\n * @returns `true` when `navigator.credentials` is available.\n *\n * @example\n * ```ts\n * if (auth.webauthn.isSupported()) {\n * // Show passkey registration button\n * }\n * ```\n */\n isSupported(): boolean;\n\n /**\n * Check whether conditional mediation (autofill-style passkeys) is available.\n *\n * @returns `true` when the browser supports `PublicKeyCredential.isConditionalMediationAvailable`.\n *\n * @example\n * ```ts\n * if (await auth.webauthn.isAutofillSupported()) {\n * await auth.webauthn.signIn({ autofill: true });\n * }\n * ```\n */\n isAutofillSupported(): Promise<boolean>;\n\n /**\n * Start a passkey registration flow and complete the WebAuthn ceremony.\n *\n * Creates a new credential bound to the current user's account.\n *\n * @param opts - Optional registration hints.\n * @param opts.name - Human-readable name for the passkey (e.g. `\"MacBook Pro\"`).\n * @param opts.userName - WebAuthn `user.name` override.\n * @param opts.userDisplayName - WebAuthn `user.displayName` override.\n * @returns A {@link SignInResult} — typically `{ kind: \"signedIn\" }` once a client session is available.\n *\n * @example\n * ```ts\n * const result = await auth.webauthn.register({ name: \"My laptop\" });\n * ```\n */\n register(opts?: WebAuthnRegisterOptions): Promise<SignInResult>;\n\n /** @internal Complete registration options returned by a provider continuation. */\n completeRegistration(result: WebAuthnRotationResult): Promise<SignInResult>;\n\n /**\n * Sign in with an existing passkey and complete the WebAuthn ceremony.\n *\n * @param opts - Optional sign-in hints.\n * @param opts.email - Email hint to filter discoverable credentials.\n * @param opts.autofill - Set to `true` for conditional UI (autofill) mode.\n * @returns A {@link SignInResult} — typically `{ kind: \"signedIn\" }` once a client session is available.\n *\n * @example\n * ```ts\n * const result = await auth.webauthn.signIn();\n * ```\n */\n signIn(opts?: WebAuthnSignInOptions): Promise<SignInResult>;\n}\n\n/**\n * Optional hints for {@link TotpClient.setup}.\n */\nexport type TotpSetupOptions = {\n /** Issuer name shown in the authenticator app. */\n name?: string;\n /** Account label shown in the authenticator app. */\n accountName?: string;\n};\n\n/** Result of {@link TotpClient.setup}. */\nexport type TotpSetupResult = {\n /** `otpauth://` URL — render as a QR code. */\n uri: string;\n /** Raw base32-encoded shared secret. */\n secret: string;\n /** Verifier token to pass to {@link TotpClient.confirm}. */\n verifier: string;\n /** Factor ID to pass to {@link TotpClient.confirm}. */\n totpId: string;\n};\n\n/** Params for {@link TotpClient.confirm}. */\nexport type TotpConfirmParams = {\n /** Six-digit OTP from the authenticator app. */\n code: string;\n /** Verifier token from {@link TotpSetupResult.verifier}. */\n verifier: string;\n /** Factor ID from {@link TotpSetupResult.totpId}. */\n totpId: string;\n};\n\n/** Params for {@link TotpClient.verify}. */\nexport type TotpVerifyParams = {\n /** Six-digit OTP from the authenticator app. */\n code: string;\n /** Verifier token from a `totpRequired` sign-in result. */\n verifier: string;\n};\n\n/**\n * TOTP two-factor authentication client-side helpers.\n *\n * @see {@link WebAuthnClient}\n * @see {@link DeviceClient}\n */\nexport interface TotpClient {\n /**\n * Start TOTP enrollment and return the setup URI, secret, verifier, and factor ID.\n *\n * The returned `uri` is an `otpauth://` URL that can be rendered as a QR code\n * for the user to scan with their authenticator app.\n *\n * @param opts - Optional setup hints.\n * @param opts.name - Issuer name shown in the authenticator app.\n * @param opts.accountName - Account label in the authenticator app.\n * @returns An object with `{ uri, secret, verifier, totpId }`.\n *\n * @example\n * ```ts\n * const { uri, secret, verifier, totpId } = await auth.totp.setup();\n * // Render `uri` as a QR code, then confirm:\n * await auth.totp.confirm({ code: userCode, verifier, totpId });\n * ```\n */\n setup(opts?: TotpSetupOptions): Promise<TotpSetupResult>;\n\n /**\n * Confirm a newly created TOTP factor with the first authenticator code.\n *\n * Call this after the user scans the QR code and enters the first OTP.\n *\n * @param opts - Confirmation parameters.\n * @param opts.code - The 6-digit TOTP code from the authenticator app.\n * @param opts.verifier - The verifier string returned by {@link TotpClient.setup}.\n * @param opts.totpId - The factor ID returned by {@link TotpClient.setup}.\n * @returns A {@link SignInResult} — `{ kind: \"signedIn\" }` on success, or\n * `{ kind: \"failed\", code }` when the code is rejected.\n *\n * @example\n * ```ts\n * const result = await auth.totp.confirm({ code: \"123456\", verifier, totpId });\n * if (result.kind === \"failed\") showError(result.code);\n * ```\n */\n confirm(opts: TotpConfirmParams): Promise<SignInResult>;\n\n /**\n * Complete a sign-in that is waiting on TOTP verification.\n *\n * Called when `signIn()` returns `{ kind: \"totpRequired\" }`.\n *\n * @param opts - Verification parameters.\n * @param opts.code - The 6-digit TOTP code from the authenticator app.\n * @param opts.verifier - The verifier string from the `totpRequired` result.\n * @returns A {@link SignInResult} — `{ kind: \"signedIn\" }` on success, or\n * `{ kind: \"failed\", code }` when the code is rejected.\n *\n * @example\n * ```ts\n * const result = await auth.signIn(\"password\", { email, password });\n * if (result.kind === \"totpRequired\") {\n * const totp = await auth.totp.verify({ code: totpCode, verifier: result.verifier });\n * if (totp.kind === \"failed\") showError(totp.code);\n * }\n * ```\n */\n verify(opts: TotpVerifyParams): Promise<SignInResult>;\n}\n\n/** Params for {@link DeviceClient.poll}. */\nexport type DevicePollParams = {\n code: DeviceCodeResult;\n /** Aborts the poll loop cleanly, e.g. on UI unmount. */\n signal?: AbortSignal;\n};\n\n/** Params for {@link DeviceClient.verify}. */\nexport type DeviceVerifyParams = { code: string };\n\n/**\n * Device authorization (RFC 8628) client-side helpers.\n *\n * @see {@link WebAuthnClient}\n * @see {@link TotpClient}\n */\nexport interface DeviceClient {\n /**\n * Poll until a device flow is approved or expires.\n *\n * Polls the server at the interval specified in the {@link DeviceCodeResult}\n * until the user authorizes the device or the code expires.\n *\n * @param opts - Poll options.\n * @param opts.code - The {@link DeviceCodeResult} returned from `signIn(\"device\")`.\n * @param opts.signal - Optional {@link AbortSignal}; aborting returns cleanly\n * at the next loop boundary (e.g. on UI unmount).\n * @throws `ConvexError({ code: \"DEVICE_CODE_EXPIRED\" })` when the code expires before authorization.\n *\n * @example\n * ```ts\n * const controller = new AbortController();\n * const result = await auth.signIn(\"device\");\n * if (result.kind === \"deviceCode\") {\n * // Display result.deviceCode.userCode to the user\n * await auth.device.poll({ code: result.deviceCode, signal: controller.signal });\n * console.log(\"Device authorized!\");\n * }\n * ```\n */\n poll(opts: DevicePollParams): Promise<void>;\n\n /**\n * Approve a device flow from the verification page using the displayed user code.\n *\n * Call this on the authorization page where the user enters the short code\n * shown on the device screen.\n *\n * @param opts - Verification options.\n * @param opts.code - The user code string (e.g. `\"WDJB-MJHT\"`).\n * @throws `ConvexError({ code: \"DEVICE_AUTHORIZATION_FAILED\" })` when verification fails.\n *\n * @example\n * ```ts\n * await auth.device.verify({ code: \"WDJB-MJHT\" });\n * ```\n */\n verify(opts: DeviceVerifyParams): Promise<void>;\n}\n\n/**\n * Extract capability flags from an AuthApiRefs type.\n *\n * @typeParam Api - An AuthApiRefs type to extract capability flags from.\n */\ntype ProviderIds<Api extends AuthApiRefs> = [Api[\"signIn\"]] extends [never]\n ? string\n : FunctionArgs<Api[\"signIn\"]> extends infer Args\n ? Args extends unknown\n ? \"provider\" extends keyof Args\n ? Exclude<Args[keyof Args & \"provider\"], undefined>\n : never\n : never\n : never;\n\ntype HasProvider<Api extends AuthApiRefs, Id extends string> =\n string extends ProviderIds<Api> ? boolean : Id extends ProviderIds<Api> ? true : false;\n\ntype InferCaps<Api extends AuthApiRefs> = {\n webauthn: HasProvider<Api, \"webauthn\">;\n totp: HasProvider<Api, \"totp\">;\n device: HasProvider<Api, \"device\">;\n};\n\n/**\n * Include a capability when configured, omit it when disabled, and keep it\n * optional when a framework binding cannot know the capability.\n */\ntype CapabilityClient<Enabled extends boolean, Name extends string, Client> = [Enabled] extends [\n false,\n]\n ? {}\n : [boolean] extends [Enabled]\n ? { [Key in Name]?: Client }\n : { [Key in Name]: Client };\n\n/** Pending invite detected from URL or recovered from storage after redirect. */\nexport interface PendingInvite {\n /**\n * Raw one-time invite token. Pass to your invite acceptance mutation.\n * @readonly\n */\n readonly token: string;\n /**\n * Invite email from the URL or stored redirect state, if available.\n * @readonly\n */\n readonly email: string | null;\n /**\n * Consume the invite: clears storage/URL params and returns the token.\n *\n * @returns The invite token.\n * @throws When there is no pending invite to accept.\n */\n accept(): Promise<{ token: string }>;\n}\n\n/**\n * Discriminated union of params for the password provider's flows.\n *\n * Each branch maps to one of the six password flows: `signUp`, `signIn`,\n * `reset`, `recover`, `verify`, `change`. Selecting a `flow` literal narrows the\n * accepted params automatically.\n */\nexport type { PasswordParams } from \"../../shared/params\";\n\n/** Params for the email (magic link) provider's initiation step. */\nexport type EmailInitiateParams = EmailParams;\n\n/**\n * Params for completing a code-based flow (no provider). Used to finalise\n * email magic-link sign-ins and other provider-owned code flows when the\n * verification call is made without re-specifying the originating provider.\n */\nexport type CodeCompletionParams = CodeParams;\n\n/** Params for the `connection` provider — requires a connection ID. */\nexport type { ConnectionParams } from \"../../shared/params\";\n\n/** Params for the anonymous provider. Empty / `redirectTo` only. */\nexport type { AnonymousParams } from \"../../shared/params\";\n\n/** Default params shape for OAuth-style providers (google, github, etc.). */\nexport type OAuthSignInParams = OAuthParams;\n\n/**\n * Resolves the `params` argument shape from the `provider` literal.\n *\n * Known special providers (`\"password\"`, `\"email\"`, etc.) get strict typing.\n * Any other string falls back to OAuth-style params, since custom OAuth\n * providers can be registered under arbitrary IDs.\n */\ntype DefaultParamsForProvider<P> = P extends \"password\"\n ? PasswordParams\n : P extends \"email\"\n ? EmailInitiateParams\n : P extends \"anonymous\"\n ? AnonymousParams | undefined\n : P extends \"connection\"\n ? ConnectionParams\n : P extends \"webauthn\"\n ? never\n : P extends undefined\n ? CodeCompletionParams\n : OAuthSignInParams | undefined;\n\ntype ConfiguredProviderArgs<Api extends AuthApiRefs, P> =\n FunctionArgs<Api[\"signIn\"]> extends infer Args\n ? Args extends { provider: P }\n ? Args\n : never\n : never;\n\n/** Resolve a provider's exact params from the generated auth action reference. */\nexport type ParamsForProvider<Api extends AuthApiRefs, P> =\n string extends ProviderIds<Api>\n ? DefaultParamsForProvider<P>\n : P extends \"webauthn\" | \"totp\" | \"device\"\n ? never\n : P extends \"connection\"\n ? ConnectionParams\n : [P] extends [undefined]\n ? CodeCompletionParams\n : ConfiguredProviderArgs<Api, P> extends infer Args\n ? [Args] extends [never]\n ? never\n : Args extends { params: infer Params }\n ? Params\n : Args extends { params?: infer Params }\n ? Params | undefined\n : undefined\n : never;\n\n/**\n * Tuple-rest helper that flips `params` between required and optional based\n * on whether `undefined` is in its resolved type.\n */\nexport type SignInArgs<Api extends AuthApiRefs, P> =\n undefined extends ParamsForProvider<Api, P>\n ? [params?: ParamsForProvider<Api, P>]\n : [params: ParamsForProvider<Api, P>];\n\n/**\n * Public signature for `auth.signIn`. The provider literal discriminates the\n * params shape via {@link ParamsForProvider}, and the params slot is\n * automatically optional when the resolved type permits `undefined`.\n *\n * @example\n * ```ts\n * auth.signIn(\"password\", { flow: \"signIn\", email, password });\n * auth.signIn(\"password\", { flow: \"change\", email, currentPassword, newPassword });\n * auth.signIn(\"anonymous\"); // params optional\n * ```\n */\nexport type SignInOverloads<Api extends AuthApiRefs = AuthApiRefs> = <\n const P extends ProviderIds<Api> | undefined,\n>(\n provider: P,\n ...args: SignInArgs<Api, P>\n) => Promise<SignInResult>;\n\n/**\n * Internal-only loose signature for the `signIn` value. Use this when\n * forwarding through wrappers where TypeScript cannot select an overload\n * from the wrapper's union-typed `provider` argument.\n *\n * @internal\n */\nexport type SignInImpl = (provider?: string, params?: AuthParameters) => Promise<SignInResult>;\n\n/** Base auth client — always present. */\ninterface AuthClientBase<Api extends AuthApiRefs> {\n /** Restore initial auth state for the current runtime. */\n initialize: () => Promise<void>;\n /** SSR-safe query-param reader. */\n param: (name: string) => string | null;\n /**\n * Pending invite recovered from the URL or storage, if present.\n * @readonly\n */\n readonly invite: PendingInvite | null;\n /** Complete an OAuth callback using a URL or authorization code. */\n completeOAuth: (input: URL | string | { code: string }) => Promise<OAuthCompletionResult>;\n /** Start a sign-in flow for a provider. */\n signIn: SignInOverloads<Api>;\n /** Sign out and clear local auth state. */\n signOut: () => Promise<void>;\n /** Subscribe to auth state changes; returns an unsubscribe. */\n subscribe: (handler: AuthSubscriber) => () => void;\n /** Read the current auth state synchronously, e.g. for `useSyncExternalStore`. */\n getSnapshot: () => AuthState;\n /** Tear down listeners and reject in-flight handshakes. */\n destroy: () => void;\n}\n\n/**\n * Framework-agnostic auth client return type.\n *\n * Conditionally includes `totp` and `device` helpers based on the\n * capabilities in the `AuthApiRefs` type. Platform-specific `webauthn` helpers\n * are added by {@link PlatformAuthClient}.\n *\n * @typeParam Api - An AuthApiRefs type that determines which factor helpers are included.\n */\nexport type AuthClient<Api extends AuthApiRefs = AuthApiRefs> = AuthClientBase<Api> &\n CapabilityClient<InferCaps<Api>[\"totp\"], \"totp\", TotpClient> &\n CapabilityClient<InferCaps<Api>[\"device\"], \"device\", DeviceClient>;\n\n/**\n * Browser auth client return type.\n *\n * Extends {@link AuthClient} with conditional WebAuthn helpers when the\n * generated auth API exposes WebAuthn capabilities.\n *\n * @typeParam Api - An AuthApiRefs type that determines which factor helpers are included.\n */\nexport type PlatformAuthClient<Api extends AuthApiRefs = AuthApiRefs> = AuthClient<Api> &\n CapabilityClient<InferCaps<Api>[\"webauthn\"], \"webauthn\", WebAuthnClient>;\n\n/**\n * Options for {@link client}.\n *\n * @typeParam Api - An AuthApiRefs type.\n */\nexport type ClientOptions<Api extends AuthApiRefs = AuthApiRefs> = {\n /** Any Convex client implementation used to run auth actions. */\n convex: ConvexTransport;\n /** Platform runtime implementation used by the client core. */\n runtime?: ClientRuntime;\n /** Platform-specific factor adapters supplied by higher-level entrypoints. */\n adapters?: ClientAdapters;\n /** Platform-specific adapter factories supplied by higher-level entrypoints. */\n adapterFactories?: ClientAdapterFactories;\n /**\n * Typed auth function refs from your generated `api` object.\n * Required outside proxy mode.\n */\n api?: Api;\n /** Explicit Convex deployment URL when it cannot be inferred from the client. */\n url?: string;\n /**\n * Optional action-only transport for direct code exchange outside proxy mode.\n * Required in non-browser runtimes when `proxyPath` is not set.\n */\n httpClient?: ActionTransport | null;\n /**\n * Storage backend for persisted tokens.\n *\n * Defaults to `runtime.storage` when provided, otherwise `null`.\n */\n storage?: Storage | null;\n /**\n * Server-known auth used to seed the synchronous boot so SSR and hydration\n * render the resolved state on first paint. A non-empty JWT boots signed in;\n * `null` boots signed out. Providing this at all marks auth as resolved, so\n * the client skips the loading phase. Omit it (leave `undefined`) to read the\n * persisted value from `storage` instead. Ongoing persistence always uses\n * `storage`.\n */\n token?: string | null;\n /**\n * Proxy endpoint used instead of direct Convex auth calls.\n * When set, provide `runtime.proxy` and omit direct `api`/`httpClient`\n * transport requirements.\n */\n proxyPath?: string;\n /** SSR-safe URL source for reading query parameters. */\n location?: URL | (() => URL | null);\n /**\n * Default OAuth `redirectTo` applied to `signIn` calls that omit it. Platform\n * entrypoints set this (e.g. Expo passes its native redirect URI) so the core\n * can build the authorization URL without a platform-specific `signIn` wrapper.\n */\n oauthRedirectTo?: string;\n /**\n * Milliseconds to wait for the Convex client to confirm a new token\n * before a sign-in handshake rejects with `AUTH_HANDSHAKE_TIMEOUT`.\n * Defaults to `5000`.\n */\n handshakeTimeoutMs?: number;\n};\n\nexport type OAuthCompletionResult = { handled: false } | { handled: true; cleanupUrl: URL | null };\n\n/**\n * Metadata describing the current auth flow for handshake diagnostics.\n *\n * @internal\n */\nexport type AuthFlowContext = {\n provider?: string;\n flow: string;\n};\n\n/**\n * A simple deferred promise that can be resolved or rejected externally.\n */\ninterface SimpleDeferred<T, E = unknown> {\n readonly promise: Promise<T>;\n resolve(value: T): void;\n reject(error: E): void;\n}\n\n/**\n * Create a deferred promise that can be resolved or rejected externally.\n *\n * @returns A deferred object containing the promise and control methods.\n * @internal\n */\nexport function createDeferred<T, E = unknown>(): SimpleDeferred<T, E> {\n let resolve!: (value: T) => void;\n let reject!: (error: E) => void;\n const promise = new Promise<T>((res, rej) => {\n resolve = res;\n reject = rej as (error: E) => void;\n });\n return { promise, resolve, reject };\n}\n\n/** @internal */\nexport type HandshakeWaiter = {\n epoch: number;\n context: AuthFlowContext;\n deferred: SimpleDeferred<void, ConvexError<Value>>;\n timeoutId: ReturnType<typeof setTimeout>;\n};\n"],"mappings":";;;;;;;AA8yBA,SAAgB,iBAAuD;CACrE,IAAI;CACJ,IAAI;AAKJ,QAAO;EAAE,SAJO,IAAI,SAAY,KAAK,QAAQ;AAC3C,aAAU;AACV,YAAS;IACT;EACgB;EAAS;EAAQ"}
|
|
1
|
+
{"version":3,"file":"types.js","names":[],"sources":["../../../src/client/core/types.ts"],"sourcesContent":["import type { FunctionArgs, FunctionReference } from \"convex/server\";\nimport type { ConvexError, Value } from \"convex/values\";\n\nimport type { AccessToken } from \"../../shared/brand\";\nimport type {\n AnonymousParams,\n CodeParams,\n ConnectionParams,\n EmailParams,\n OAuthParams,\n PasswordParams,\n} from \"../../shared/params\";\nimport type {\n AuthParameters,\n AuthTokens,\n SignInFlowResult,\n SignInWebAuthnOptionsResult,\n} from \"../../shared/results\";\nimport type { ErrorCode } from \"../../shared/codes\";\n\n/**\n * Structural interface for any Convex client.\n * Satisfied by `ConvexClient` (`convex/browser`),\n * `ConvexReactClient` (`convex/react`), and similar transports.\n *\n * `clearAuth` is present on `ConvexReactClient` and `BaseConvexClient`\n * but not on the simplified `ConvexClient`. When available we call it\n * during sign-out for a clean deauthentication.\n */\nexport interface ConvexTransport {\n action(action: unknown, args: unknown): Promise<Value>;\n setAuth(\n fetchToken: (args: { forceRefreshToken: boolean }) => Promise<string | null | undefined>,\n onChange?: (isAuthenticated: boolean) => void,\n ): void;\n clearAuth?(): void;\n}\n\n/** Minimal action-only transport used for unauthenticated auth flows. */\nexport interface ActionTransport {\n action(action: unknown, args: unknown): Promise<Value>;\n}\n\n/** @internal */\nexport type SignInApiRef = { signIn: AuthApiRefs[\"signIn\"] };\n\n/** Pluggable key-value storage supplied by the host runtime. */\nexport interface Storage {\n getItem(key: string): string | null | undefined | Promise<string | null | undefined>;\n setItem(key: string, value: string): void | Promise<void>;\n removeItem(key: string): void | Promise<void>;\n}\n\n/** Platform-neutral location/navigation hooks. */\ninterface LocationRuntime {\n get(): URL | null;\n replace(relativeUrl: string): void | Promise<void>;\n}\n\n/**\n * Platform-specific OAuth launch primitive.\n *\n * `open` receives the provider authorization URL. Platforms that navigate the\n * whole page away (browser) return nothing; platforms that run the flow in an\n * in-app session (Expo) return the callback URL so the core can complete the\n * exchange inline.\n */\ninterface OAuthRuntime {\n open(url: URL): void | string | URL | Promise<void | string | URL>;\n}\n\n/** Cross-context synchronization hooks, such as browser storage events. */\ninterface SyncRuntime {\n subscribe(\n key: string,\n callback: (value: string | null) => void | Promise<void>,\n ): (() => void) | null;\n}\n\n/** Cross-context mutex/locking primitive. */\ninterface MutexRuntime {\n withKey<T>(key: string, callback: () => Promise<T>): Promise<T>;\n}\n\n/** Proxy request execution supplied by the host runtime. */\ninterface ProxyRuntime {\n fetch(body: AuthParameters, proxyPath: string): Promise<Response>;\n}\n\n/**\n * Platform-neutral client runtime dependencies.\n *\n * The core `client` package should depend only on these interfaces, while the\n * browser package can provide concrete implementations backed by DOM APIs.\n */\nexport interface ClientRuntime {\n environment?: \"client\" | \"server\";\n storage?: Storage | null;\n location?: LocationRuntime;\n oauth?: OAuthRuntime;\n sync?: SyncRuntime;\n mutex?: MutexRuntime;\n proxy?: ProxyRuntime;\n}\n\n/** Platform-specific factor adapters injected by entrypoints like `browser`. */\nexport interface ClientAdapters {\n webauthn?: WebAuthnClient;\n totp?: TotpClient;\n device?: DeviceClient;\n}\n\n/**\n * Shared dependencies threaded into every factor client (`totp`, `device`,\n * `webauthn`). The core `client` builds one of these and passes it to each\n * factor factory.\n *\n * @internal\n */\nexport interface FactorDeps {\n proxy: string | undefined;\n convex: ConvexTransport;\n requireApiRefs: () => SignInApiRef;\n proxyFetch: (body: AuthParameters) => Promise<Value>;\n setTokenAndMaybeWait: (\n args:\n | {\n shouldStore: true;\n tokens: AuthTokens | null;\n waitForHandshake: boolean;\n context: { provider?: string; flow: string };\n }\n | {\n shouldStore: false;\n tokens: { token: AccessToken } | null;\n waitForHandshake: boolean;\n context: { provider?: string; flow: string };\n },\n ) => Promise<boolean>;\n}\n\n/**\n * Dependencies provided to platform-specific factor adapters.\n *\n * @internal\n */\nexport type ClientAdapterDeps = FactorDeps;\n\n/**\n * Factory overrides for platform-specific factor adapters.\n *\n * @internal\n */\nexport interface ClientAdapterFactories {\n webauthn?: (deps: ClientAdapterDeps) => WebAuthnClient;\n}\n\n/** @internal */\nexport type SignInActionResult = SignInFlowResult<AuthTokens | null>;\n\n/** @internal */\nexport type WebAuthnRotationResult = Extract<SignInWebAuthnOptionsResult, { operation: \"rotate\" }>;\n/** @internal Passkey sign-in options returned by a provider continuation. */\nexport type WebAuthnContinuationSignInResult = Extract<\n SignInWebAuthnOptionsResult,\n { operation: \"signIn\" }\n>;\n\n/**\n * Device authorization payload returned from the `deviceCode` sign-in flow.\n */\nexport type DeviceCodeResult = {\n deviceCode: string;\n userCode: string;\n verificationUri: string;\n verificationUriComplete: string;\n expiresIn: number;\n interval: number;\n};\n\n/**\n * Result of a `signIn` call.\n *\n * - `kind: \"signedIn\"` — credentials were accepted and a client session is now available.\n * - `kind: \"redirect\"` — OAuth flow initiated; redirect the user to `redirect.toString()`.\n * - `kind: \"totpRequired\"` — credentials valid but 2FA is needed; call `auth.totp.verify()`.\n * - `kind: \"deviceCode\"` — device flow initiated; display the code and poll via `auth.device.poll()`.\n * - `kind: \"started\"` — a non-immediate flow started (for example email/phone verification).\n * - `kind: \"failed\"` — the flow did not complete; `code` is the typed {@link ErrorCode}.\n *\n * @see {@link AuthState}\n */\nexport type SignInResult =\n | { kind: \"signedIn\" }\n | { kind: \"redirect\"; redirect: URL; verifier: string }\n | { kind: \"totpRequired\"; verifier: string }\n | { kind: \"deviceCode\"; deviceCode: DeviceCodeResult }\n | { kind: \"started\" }\n | { kind: \"failed\"; code: ErrorCode };\n\n/** @internal */\nexport type AuthSnapshot = {\n phase: \"loading\" | \"handshake\" | \"authenticated\" | \"unauthenticated\";\n isLoading: boolean;\n isAuthenticated: boolean;\n token: string | null;\n};\n\n/** Reactive auth state. `token` is non-null only after Convex confirms auth. */\nexport type AuthState =\n | { status: \"loading\"; token: null }\n | { status: \"signedOut\"; token: null }\n | { status: \"signedIn\"; token: string };\n\n/** Handler for `auth.subscribe`. */\nexport type AuthSubscriber = (state: AuthState) => void;\n\n/**\n * Typed Convex API references for the auth functions.\n * Pass these from your generated `api` object.\n *\n * @typeParam HasWebAuthn - Whether the WebAuthn provider is configured.\n * @typeParam HasTotp - Whether the TOTP provider is configured.\n * @typeParam HasDevice - Whether the device provider is configured.\n */\ntype DefaultSignInReference = FunctionReference<\n \"action\",\n \"public\",\n {\n request: {\n provider?: string;\n params?: AuthParameters;\n refreshToken?: string;\n };\n verifier?: string;\n continuation?: string;\n calledBy?: string;\n },\n unknown\n>;\n\ntype AnySignInReference = FunctionReference<\"action\", \"public\", any, any>;\n\nexport type AuthApiRefs<SignIn extends AnySignInReference = DefaultSignInReference> = {\n signIn: SignIn;\n signOut: FunctionReference<\"action\", \"public\", Record<string, Value>, unknown>;\n};\n\n/**\n * Optional hints for {@link WebAuthnClient.register}.\n */\nexport type WebAuthnRegisterOptions = {\n /** Human-readable label for this credential (e.g. `\"MacBook Pro\"`). */\n name?: string;\n /** WebAuthn `user.name` override. */\n userName?: string;\n /** WebAuthn `user.displayName` override. */\n userDisplayName?: string;\n};\n\n/**\n * Optional hints for {@link WebAuthnClient.signIn}.\n */\nexport type WebAuthnSignInOptions = {\n /** Email hint to filter discoverable credentials. */\n email?: string;\n /** Set to `true` for conditional UI (autofill) mode. */\n autofill?: boolean;\n};\n\n/**\n * WebAuthn client-side helpers.\n *\n * @see {@link TotpClient}\n * @see {@link DeviceClient}\n */\nexport interface WebAuthnClient {\n /**\n * Check whether the current runtime exposes WebAuthn passkey APIs.\n *\n * @returns `true` when `navigator.credentials` is available.\n *\n * @example\n * ```ts\n * if (auth.webauthn.isSupported()) {\n * // Show passkey registration button\n * }\n * ```\n */\n isSupported(): boolean;\n\n /**\n * Check whether conditional mediation (autofill-style passkeys) is available.\n *\n * @returns `true` when the browser supports `PublicKeyCredential.isConditionalMediationAvailable`.\n *\n * @example\n * ```ts\n * if (await auth.webauthn.isAutofillSupported()) {\n * await auth.webauthn.signIn({ autofill: true });\n * }\n * ```\n */\n isAutofillSupported(): Promise<boolean>;\n\n /**\n * Start a passkey registration flow and complete the WebAuthn ceremony.\n *\n * Creates a new credential bound to the current user's account.\n *\n * @param opts - Optional registration hints.\n * @param opts.name - Human-readable name for the passkey (e.g. `\"MacBook Pro\"`).\n * @param opts.userName - WebAuthn `user.name` override.\n * @param opts.userDisplayName - WebAuthn `user.displayName` override.\n * @returns A {@link SignInResult} — typically `{ kind: \"signedIn\" }` once a client session is available.\n *\n * @example\n * ```ts\n * const result = await auth.webauthn.register({ name: \"My laptop\" });\n * ```\n */\n register(opts?: WebAuthnRegisterOptions): Promise<SignInResult>;\n\n /** @internal Complete registration options returned by a provider continuation. */\n completeRegistration(result: WebAuthnRotationResult): Promise<SignInResult>;\n\n /** @internal Complete passkey sign-in options returned by a provider continuation. */\n completeSignIn(result: WebAuthnContinuationSignInResult): Promise<SignInResult>;\n\n /**\n * Sign in with an existing passkey and complete the WebAuthn ceremony.\n *\n * @param opts - Optional sign-in hints.\n * @param opts.email - Email hint to filter discoverable credentials.\n * @param opts.autofill - Set to `true` for conditional UI (autofill) mode.\n * @returns A {@link SignInResult} — typically `{ kind: \"signedIn\" }` once a client session is available.\n *\n * @example\n * ```ts\n * const result = await auth.webauthn.signIn();\n * ```\n */\n signIn(opts?: WebAuthnSignInOptions): Promise<SignInResult>;\n}\n\n/**\n * Optional hints for {@link TotpClient.setup}.\n */\nexport type TotpSetupOptions = {\n /** Issuer name shown in the authenticator app. */\n name?: string;\n /** Account label shown in the authenticator app. */\n accountName?: string;\n};\n\n/** Result of {@link TotpClient.setup}. */\nexport type TotpSetupResult = {\n /** `otpauth://` URL — render as a QR code. */\n uri: string;\n /** Raw base32-encoded shared secret. */\n secret: string;\n /** Verifier token to pass to {@link TotpClient.confirm}. */\n verifier: string;\n /** Factor ID to pass to {@link TotpClient.confirm}. */\n totpId: string;\n};\n\n/** Params for {@link TotpClient.confirm}. */\nexport type TotpConfirmParams = {\n /** Six-digit OTP from the authenticator app. */\n code: string;\n /** Verifier token from {@link TotpSetupResult.verifier}. */\n verifier: string;\n /** Factor ID from {@link TotpSetupResult.totpId}. */\n totpId: string;\n};\n\n/** Params for {@link TotpClient.verify}. */\nexport type TotpVerifyParams = {\n /** Six-digit OTP from the authenticator app. */\n code: string;\n /** Verifier token from a `totpRequired` sign-in result. */\n verifier: string;\n};\n\n/**\n * TOTP two-factor authentication client-side helpers.\n *\n * @see {@link WebAuthnClient}\n * @see {@link DeviceClient}\n */\nexport interface TotpClient {\n /**\n * Start TOTP enrollment and return the setup URI, secret, verifier, and factor ID.\n *\n * The returned `uri` is an `otpauth://` URL that can be rendered as a QR code\n * for the user to scan with their authenticator app.\n *\n * @param opts - Optional setup hints.\n * @param opts.name - Issuer name shown in the authenticator app.\n * @param opts.accountName - Account label in the authenticator app.\n * @returns An object with `{ uri, secret, verifier, totpId }`.\n *\n * @example\n * ```ts\n * const { uri, secret, verifier, totpId } = await auth.totp.setup();\n * // Render `uri` as a QR code, then confirm:\n * await auth.totp.confirm({ code: userCode, verifier, totpId });\n * ```\n */\n setup(opts?: TotpSetupOptions): Promise<TotpSetupResult>;\n\n /**\n * Confirm a newly created TOTP factor with the first authenticator code.\n *\n * Call this after the user scans the QR code and enters the first OTP.\n *\n * @param opts - Confirmation parameters.\n * @param opts.code - The 6-digit TOTP code from the authenticator app.\n * @param opts.verifier - The verifier string returned by {@link TotpClient.setup}.\n * @param opts.totpId - The factor ID returned by {@link TotpClient.setup}.\n * @returns A {@link SignInResult} — `{ kind: \"signedIn\" }` on success, or\n * `{ kind: \"failed\", code }` when the code is rejected.\n *\n * @example\n * ```ts\n * const result = await auth.totp.confirm({ code: \"123456\", verifier, totpId });\n * if (result.kind === \"failed\") showError(result.code);\n * ```\n */\n confirm(opts: TotpConfirmParams): Promise<SignInResult>;\n\n /**\n * Complete a sign-in that is waiting on TOTP verification.\n *\n * Called when `signIn()` returns `{ kind: \"totpRequired\" }`.\n *\n * @param opts - Verification parameters.\n * @param opts.code - The 6-digit TOTP code from the authenticator app.\n * @param opts.verifier - The verifier string from the `totpRequired` result.\n * @returns A {@link SignInResult} — `{ kind: \"signedIn\" }` on success, or\n * `{ kind: \"failed\", code }` when the code is rejected.\n *\n * @example\n * ```ts\n * const result = await auth.signIn(\"password\", { email, password });\n * if (result.kind === \"totpRequired\") {\n * const totp = await auth.totp.verify({ code: totpCode, verifier: result.verifier });\n * if (totp.kind === \"failed\") showError(totp.code);\n * }\n * ```\n */\n verify(opts: TotpVerifyParams): Promise<SignInResult>;\n}\n\n/** Params for {@link DeviceClient.poll}. */\nexport type DevicePollParams = {\n code: DeviceCodeResult;\n /** Aborts the poll loop cleanly, e.g. on UI unmount. */\n signal?: AbortSignal;\n};\n\n/** Params for {@link DeviceClient.verify}. */\nexport type DeviceVerifyParams = { code: string };\n\n/**\n * Device authorization (RFC 8628) client-side helpers.\n *\n * @see {@link WebAuthnClient}\n * @see {@link TotpClient}\n */\nexport interface DeviceClient {\n /**\n * Poll until a device flow is approved or expires.\n *\n * Polls the server at the interval specified in the {@link DeviceCodeResult}\n * until the user authorizes the device or the code expires.\n *\n * @param opts - Poll options.\n * @param opts.code - The {@link DeviceCodeResult} returned from `signIn(\"device\")`.\n * @param opts.signal - Optional {@link AbortSignal}; aborting returns cleanly\n * at the next loop boundary (e.g. on UI unmount).\n * @throws `ConvexError({ code: \"DEVICE_CODE_EXPIRED\" })` when the code expires before authorization.\n *\n * @example\n * ```ts\n * const controller = new AbortController();\n * const result = await auth.signIn(\"device\");\n * if (result.kind === \"deviceCode\") {\n * // Display result.deviceCode.userCode to the user\n * await auth.device.poll({ code: result.deviceCode, signal: controller.signal });\n * console.log(\"Device authorized!\");\n * }\n * ```\n */\n poll(opts: DevicePollParams): Promise<void>;\n\n /**\n * Approve a device flow from the verification page using the displayed user code.\n *\n * Call this on the authorization page where the user enters the short code\n * shown on the device screen.\n *\n * @param opts - Verification options.\n * @param opts.code - The user code string (e.g. `\"WDJB-MJHT\"`).\n * @throws `ConvexError({ code: \"DEVICE_AUTHORIZATION_FAILED\" })` when verification fails.\n *\n * @example\n * ```ts\n * await auth.device.verify({ code: \"WDJB-MJHT\" });\n * ```\n */\n verify(opts: DeviceVerifyParams): Promise<void>;\n}\n\n/**\n * Extract capability flags from an AuthApiRefs type.\n *\n * @typeParam Api - An AuthApiRefs type to extract capability flags from.\n */\ntype SignInRequest<Api extends AuthApiRefs> =\n FunctionArgs<Api[\"signIn\"]> extends infer Args\n ? Args extends { request: infer Request }\n ? Request\n : Args\n : never;\n\ntype ProviderIds<Api extends AuthApiRefs> = [Api[\"signIn\"]] extends [never]\n ? string\n : SignInRequest<Api> extends infer Args\n ? Args extends unknown\n ? \"provider\" extends keyof Args\n ? Exclude<Args[keyof Args & \"provider\"], undefined>\n : never\n : never\n : never;\n\ntype HasProvider<Api extends AuthApiRefs, Id extends string> =\n string extends ProviderIds<Api> ? boolean : Id extends ProviderIds<Api> ? true : false;\n\ntype InferCaps<Api extends AuthApiRefs> = {\n webauthn: HasProvider<Api, \"webauthn\">;\n totp: HasProvider<Api, \"totp\">;\n device: HasProvider<Api, \"device\">;\n};\n\n/**\n * Include a capability when configured, omit it when disabled, and keep it\n * optional when a framework binding cannot know the capability.\n */\ntype CapabilityClient<Enabled extends boolean, Name extends string, Client> = [Enabled] extends [\n false,\n]\n ? {}\n : [boolean] extends [Enabled]\n ? { [Key in Name]?: Client }\n : { [Key in Name]: Client };\n\n/** Pending invite detected from URL or recovered from storage after redirect. */\nexport interface PendingInvite {\n /**\n * Raw one-time invite token. Pass to your invite acceptance mutation.\n * @readonly\n */\n readonly token: string;\n /**\n * Invite email from the URL or stored redirect state, if available.\n * @readonly\n */\n readonly email: string | null;\n /**\n * Consume the invite: clears storage/URL params and returns the token.\n *\n * @returns The invite token.\n * @throws When there is no pending invite to accept.\n */\n accept(): Promise<{ token: string }>;\n}\n\n/**\n * Discriminated union of params for the password provider's flows.\n *\n * Each branch maps to one of the six password flows: `signUp`, `signIn`,\n * `reset`, `recover`, `verify`, `change`. Selecting a `flow` literal narrows the\n * accepted params automatically.\n */\nexport type { PasswordParams } from \"../../shared/params\";\n\n/** Params for the email (magic link) provider's initiation step. */\nexport type EmailInitiateParams = EmailParams;\n\n/**\n * Params for completing a code-based flow (no provider). Used to finalise\n * email magic-link sign-ins and other provider-owned code flows when the\n * verification call is made without re-specifying the originating provider.\n */\nexport type CodeCompletionParams = CodeParams;\n\n/** Params for the `connection` provider — requires a connection ID. */\nexport type { ConnectionParams } from \"../../shared/params\";\n\n/** Params for the anonymous provider. Empty / `redirectTo` only. */\nexport type { AnonymousParams } from \"../../shared/params\";\n\n/** Default params shape for OAuth-style providers (google, github, etc.). */\nexport type OAuthSignInParams = OAuthParams;\n\n/**\n * Resolves the `params` argument shape from the `provider` literal.\n *\n * Known special providers (`\"password\"`, `\"email\"`, etc.) get strict typing.\n * Any other string falls back to OAuth-style params, since custom OAuth\n * providers can be registered under arbitrary IDs.\n */\ntype DefaultParamsForProvider<P> = P extends \"password\"\n ? PasswordParams\n : P extends \"email\"\n ? EmailInitiateParams\n : P extends \"anonymous\"\n ? AnonymousParams | undefined\n : P extends \"connection\"\n ? ConnectionParams\n : P extends \"webauthn\"\n ? never\n : P extends undefined\n ? CodeCompletionParams\n : OAuthSignInParams | undefined;\n\ntype ConfiguredProviderArgs<Api extends AuthApiRefs, P> =\n SignInRequest<Api> extends infer Args ? (Args extends { provider: P } ? Args : never) : never;\n\n/** Resolve a provider's exact params from the generated auth action reference. */\nexport type ParamsForProvider<Api extends AuthApiRefs, P> =\n string extends ProviderIds<Api>\n ? DefaultParamsForProvider<P>\n : P extends \"webauthn\" | \"totp\" | \"device\"\n ? never\n : P extends \"connection\"\n ? ConnectionParams\n : [P] extends [undefined]\n ? CodeCompletionParams\n : ConfiguredProviderArgs<Api, P> extends infer Args\n ? [Args] extends [never]\n ? never\n : Args extends { params: infer Params }\n ? Params\n : Args extends { params?: infer Params }\n ? Params | undefined\n : undefined\n : never;\n\n/**\n * Tuple-rest helper that flips `params` between required and optional based\n * on whether `undefined` is in its resolved type.\n */\nexport type SignInArgs<Api extends AuthApiRefs, P> =\n undefined extends ParamsForProvider<Api, P>\n ? [params?: ParamsForProvider<Api, P>]\n : [params: ParamsForProvider<Api, P>];\n\n/**\n * Public signature for `auth.signIn`. The provider literal discriminates the\n * params shape via {@link ParamsForProvider}, and the params slot is\n * automatically optional when the resolved type permits `undefined`.\n *\n * @example\n * ```ts\n * auth.signIn(\"password\", { flow: \"signIn\", email, password });\n * auth.signIn(\"password\", { flow: \"change\", email, currentPassword, newPassword });\n * auth.signIn(\"anonymous\"); // params optional\n * ```\n */\nexport type SignInOverloads<Api extends AuthApiRefs = AuthApiRefs> = <\n const P extends ProviderIds<Api> | undefined,\n>(\n provider: P,\n ...args: SignInArgs<Api, P>\n) => Promise<SignInResult>;\n\n/**\n * Internal-only loose signature for the `signIn` value. Use this when\n * forwarding through wrappers where TypeScript cannot select an overload\n * from the wrapper's union-typed `provider` argument.\n *\n * @internal\n */\nexport type SignInImpl = (provider?: string, params?: AuthParameters) => Promise<SignInResult>;\n\n/** Base auth client — always present. */\ninterface AuthClientBase<Api extends AuthApiRefs> {\n /** Restore initial auth state for the current runtime. */\n initialize: () => Promise<void>;\n /** SSR-safe query-param reader. */\n param: (name: string) => string | null;\n /**\n * Pending invite recovered from the URL or storage, if present.\n * @readonly\n */\n readonly invite: PendingInvite | null;\n /** Complete an OAuth callback using a URL or authorization code. */\n completeOAuth: (input: URL | string | { code: string }) => Promise<OAuthCompletionResult>;\n /** Start a sign-in flow for a provider. */\n signIn: SignInOverloads<Api>;\n /** Sign out and clear local auth state. */\n signOut: () => Promise<void>;\n /** Subscribe to auth state changes; returns an unsubscribe. */\n subscribe: (handler: AuthSubscriber) => () => void;\n /** Read the current auth state synchronously, e.g. for `useSyncExternalStore`. */\n getSnapshot: () => AuthState;\n /** Tear down listeners and reject in-flight handshakes. */\n destroy: () => void;\n}\n\n/**\n * Framework-agnostic auth client return type.\n *\n * Conditionally includes `totp` and `device` helpers based on the\n * capabilities in the `AuthApiRefs` type. Platform-specific `webauthn` helpers\n * are added by {@link PlatformAuthClient}.\n *\n * @typeParam Api - An AuthApiRefs type that determines which factor helpers are included.\n */\nexport type AuthClient<Api extends AuthApiRefs = AuthApiRefs> = AuthClientBase<Api> &\n CapabilityClient<InferCaps<Api>[\"totp\"], \"totp\", TotpClient> &\n CapabilityClient<InferCaps<Api>[\"device\"], \"device\", DeviceClient>;\n\n/**\n * Browser auth client return type.\n *\n * Extends {@link AuthClient} with conditional WebAuthn helpers when the\n * generated auth API exposes WebAuthn capabilities.\n *\n * @typeParam Api - An AuthApiRefs type that determines which factor helpers are included.\n */\nexport type PlatformAuthClient<Api extends AuthApiRefs = AuthApiRefs> = AuthClient<Api> &\n CapabilityClient<InferCaps<Api>[\"webauthn\"], \"webauthn\", WebAuthnClient>;\n\n/**\n * Options for {@link client}.\n *\n * @typeParam Api - An AuthApiRefs type.\n */\ntype ClientOptionsBase = {\n /** Any Convex client implementation used to run auth actions. */\n convex: ConvexTransport;\n /** Platform runtime implementation used by the client core. */\n runtime?: ClientRuntime;\n /** Platform-specific factor adapters supplied by higher-level entrypoints. */\n adapters?: ClientAdapters;\n /** Platform-specific adapter factories supplied by higher-level entrypoints. */\n adapterFactories?: ClientAdapterFactories;\n /** Explicit Convex deployment URL when it cannot be inferred from the client. */\n url?: string;\n /**\n * Storage backend for persisted tokens.\n *\n * Defaults to `runtime.storage` when provided, otherwise `null`.\n */\n storage?: Storage | null;\n /**\n * Server-known auth used to seed the synchronous boot so SSR and hydration\n * render the resolved state on first paint. A non-empty JWT boots signed in;\n * `null` boots signed out. Providing this at all marks auth as resolved, so\n * the client skips the loading phase. Omit it (leave `undefined`) to read the\n * persisted value from `storage` instead. Ongoing persistence always uses\n * `storage`.\n */\n token?: string | null;\n /** SSR-safe URL source for reading query parameters. */\n location?: URL | (() => URL | null);\n /**\n * Default OAuth `redirectTo` applied to `signIn` calls that omit it. Platform\n * entrypoints set this (e.g. Expo passes its native redirect URI) so the core\n * can build the authorization URL without a platform-specific `signIn` wrapper.\n */\n oauthRedirectTo?: string;\n /**\n * Milliseconds to wait for the Convex client to confirm a new token\n * before a sign-in handshake rejects with `AUTH_HANDSHAKE_TIMEOUT`.\n * Defaults to `5000`.\n */\n handshakeTimeoutMs?: number;\n};\n\n/** Direct Convex mode. Generated auth references are the client contract. */\nexport type DirectClientOptions<Api extends AuthApiRefs = AuthApiRefs> = ClientOptionsBase & {\n /** Typed auth function refs from the application's generated `api` object. */\n api: Api;\n /** Proxy transport and direct transport are mutually exclusive. */\n proxyPath?: never;\n /**\n * Action-only transport used for direct code exchange. Browser and Expo\n * entrypoints provide one automatically; headless runtimes must inject it.\n */\n httpClient?: ActionTransport | null;\n};\n\n/** HTTP proxy mode. The proxy owns the Convex function references. */\nexport type ProxyClientOptions = ClientOptionsBase & {\n /** Proxy endpoint used instead of direct Convex auth calls. */\n proxyPath: string;\n /** Generated references belong to direct mode and cannot be mixed with a proxy. */\n api?: never;\n /** Direct action transports belong to direct mode. */\n httpClient?: never;\n};\n\n/**\n * Client configuration. Selecting direct or proxy mode makes every required\n * transport explicit and prevents the two modes from being combined.\n */\nexport type ClientOptions<Api extends AuthApiRefs = AuthApiRefs> =\n | DirectClientOptions<Api>\n | ProxyClientOptions;\n\nexport type OAuthCompletionResult = { handled: false } | { handled: true; cleanupUrl: URL | null };\n\n/**\n * Metadata describing the current auth flow for handshake diagnostics.\n *\n * @internal\n */\nexport type AuthFlowContext = {\n provider?: string;\n flow: string;\n};\n\n/**\n * A simple deferred promise that can be resolved or rejected externally.\n */\ninterface SimpleDeferred<T, E = unknown> {\n readonly promise: Promise<T>;\n resolve(value: T): void;\n reject(error: E): void;\n}\n\n/**\n * Create a deferred promise that can be resolved or rejected externally.\n *\n * @returns A deferred object containing the promise and control methods.\n * @internal\n */\nexport function createDeferred<T, E = unknown>(): SimpleDeferred<T, E> {\n let resolve!: (value: T) => void;\n let reject!: (error: E) => void;\n const promise = new Promise<T>((res, rej) => {\n resolve = res;\n reject = rej as (error: E) => void;\n });\n return { promise, resolve, reject };\n}\n\n/** @internal */\nexport type HandshakeWaiter = {\n epoch: number;\n context: AuthFlowContext;\n deferred: SimpleDeferred<void, ConvexError<Value>>;\n timeoutId: ReturnType<typeof setTimeout>;\n};\n"],"mappings":";;;;;;;AA00BA,SAAgB,iBAAuD;CACrE,IAAI;CACJ,IAAI;AAKJ,QAAO;EAAE,SAJO,IAAI,SAAY,KAAK,QAAQ;AAC3C,aAAU;AACV,YAAS;IACT;EACgB;EAAS;EAAQ"}
|
|
@@ -11,14 +11,14 @@ function createDeviceClient(deps) {
|
|
|
11
11
|
const requestDeviceSignIn = async (params) => {
|
|
12
12
|
return proxy ? await proxyFetch({
|
|
13
13
|
action: "auth:signIn",
|
|
14
|
-
args: {
|
|
14
|
+
args: { request: {
|
|
15
15
|
provider: "device",
|
|
16
16
|
params
|
|
17
|
-
}
|
|
18
|
-
}) : await convex.action(requireApiRefs().signIn, {
|
|
17
|
+
} }
|
|
18
|
+
}) : await convex.action(requireApiRefs().signIn, { request: {
|
|
19
19
|
provider: "device",
|
|
20
20
|
params
|
|
21
|
-
});
|
|
21
|
+
} });
|
|
22
22
|
};
|
|
23
23
|
return {
|
|
24
24
|
poll: async (opts) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"device.js","names":[],"sources":["../../../src/client/factors/device.ts"],"sourcesContent":["import { ConvexError } from \"convex/values\";\n\nimport type { DeviceClient, DevicePollParams, FactorDeps, SignInActionResult } from \"../core/types\";\nimport type { AuthTokens } from \"../../shared/results\";\nimport type { AuthParameters } from \"../../shared/results\";\nimport { ErrorCode } from \"../../shared/codes\";\n\nfunction isSignedInResult(\n result: SignInActionResult,\n): result is Extract<SignInActionResult, { kind: \"signedIn\" }> {\n return result.kind === \"signedIn\";\n}\n\n/** @internal */\nexport function createDeviceClient(deps: FactorDeps): DeviceClient {\n const { proxy, convex, requireApiRefs, proxyFetch, setTokenAndMaybeWait } = deps;\n\n const requestDeviceSignIn = async (params: AuthParameters): Promise<SignInActionResult> => {\n return (\n proxy\n ? await proxyFetch({\n action: \"auth:signIn\",\n args: { provider: \"device\", params },\n })\n : await convex.action(requireApiRefs().signIn, {\n provider: \"device\"
|
|
1
|
+
{"version":3,"file":"device.js","names":[],"sources":["../../../src/client/factors/device.ts"],"sourcesContent":["import { ConvexError } from \"convex/values\";\n\nimport type { DeviceClient, DevicePollParams, FactorDeps, SignInActionResult } from \"../core/types\";\nimport type { AuthTokens } from \"../../shared/results\";\nimport type { AuthParameters } from \"../../shared/results\";\nimport { ErrorCode } from \"../../shared/codes\";\n\nfunction isSignedInResult(\n result: SignInActionResult,\n): result is Extract<SignInActionResult, { kind: \"signedIn\" }> {\n return result.kind === \"signedIn\";\n}\n\n/** @internal */\nexport function createDeviceClient(deps: FactorDeps): DeviceClient {\n const { proxy, convex, requireApiRefs, proxyFetch, setTokenAndMaybeWait } = deps;\n\n const requestDeviceSignIn = async (params: AuthParameters): Promise<SignInActionResult> => {\n return (\n proxy\n ? await proxyFetch({\n action: \"auth:signIn\",\n args: { request: { provider: \"device\", params } },\n })\n : await convex.action(requireApiRefs().signIn, {\n request: { provider: \"device\", params },\n })\n ) as SignInActionResult;\n };\n\n return {\n poll: async (opts: DevicePollParams): Promise<void> => {\n const { code, signal } = opts;\n const MAX_POLL_DURATION_MS = 30 * 60 * 1000;\n const SLOW_DOWN_INCREMENT_MS = 5 * 1000;\n let currentIntervalMs = code.interval * 1000;\n const startedAt = Date.now();\n const expiresAt = Math.min(\n startedAt + code.expiresIn * 1000,\n startedAt + MAX_POLL_DURATION_MS,\n );\n\n while (Date.now() < expiresAt) {\n if (signal?.aborted) return;\n await new Promise((resolve) => setTimeout(resolve, currentIntervalMs));\n if (signal?.aborted) return;\n\n const params: AuthParameters = {\n flow: \"poll\",\n deviceCode: code.deviceCode,\n };\n\n let pollResult: SignInActionResult | null;\n try {\n pollResult = await requestDeviceSignIn(params);\n } catch (error) {\n if (error instanceof ConvexError) {\n const errorCode = (error.data as { code?: unknown } | undefined)?.code;\n if (errorCode === \"DEVICE_AUTHORIZATION_PENDING\") {\n continue;\n }\n if (errorCode === \"DEVICE_SLOW_DOWN\") {\n currentIntervalMs += SLOW_DOWN_INCREMENT_MS;\n continue;\n }\n }\n throw error;\n }\n\n if (pollResult === null) {\n continue;\n }\n\n if (isSignedInResult(pollResult) && pollResult.session) {\n if (proxy) {\n await setTokenAndMaybeWait({\n shouldStore: false,\n tokens: pollResult.session === null ? null : { token: pollResult.session.token },\n waitForHandshake: true,\n context: { provider: \"device\", flow: \"poll\" },\n });\n } else {\n await setTokenAndMaybeWait({\n shouldStore: true,\n tokens: (pollResult.session as AuthTokens | null) ?? null,\n waitForHandshake: true,\n context: { provider: \"device\", flow: \"poll\" },\n });\n }\n return;\n }\n }\n\n throw new ConvexError({\n code: ErrorCode.DEVICE_CODE_EXPIRED,\n message: \"Device code expired before authorization was completed.\",\n });\n },\n\n verify: async (opts: { code: string }): Promise<void> => {\n const params: AuthParameters = {\n flow: \"verify\",\n userCode: opts.code,\n };\n\n try {\n await requestDeviceSignIn(params);\n } catch (error) {\n throw new ConvexError({\n code: ErrorCode.DEVICE_AUTHORIZATION_FAILED,\n message: error instanceof Error ? error.message : \"Invalid or expired code.\",\n });\n }\n },\n };\n}\n"],"mappings":";;;;AAOA,SAAS,iBACP,QAC6D;AAC7D,QAAO,OAAO,SAAS;;;AAIzB,SAAgB,mBAAmB,MAAgC;CACjE,MAAM,EAAE,OAAO,QAAQ,gBAAgB,YAAY,yBAAyB;CAE5E,MAAM,sBAAsB,OAAO,WAAwD;AACzF,SACE,QACI,MAAM,WAAW;GACf,QAAQ;GACR,MAAM,EAAE,SAAS;IAAE,UAAU;IAAU;IAAQ,EAAE;GAClD,CAAC,GACF,MAAM,OAAO,OAAO,gBAAgB,CAAC,QAAQ,EAC3C,SAAS;GAAE,UAAU;GAAU;GAAQ,EACxC,CAAC;;AAIV,QAAO;EACL,MAAM,OAAO,SAA0C;GACrD,MAAM,EAAE,MAAM,WAAW;GACzB,MAAM,uBAAuB,OAAU;GACvC,MAAM,yBAAyB,IAAI;GACnC,IAAI,oBAAoB,KAAK,WAAW;GACxC,MAAM,YAAY,KAAK,KAAK;GAC5B,MAAM,YAAY,KAAK,IACrB,YAAY,KAAK,YAAY,KAC7B,YAAY,qBACb;AAED,UAAO,KAAK,KAAK,GAAG,WAAW;AAC7B,QAAI,QAAQ,QAAS;AACrB,UAAM,IAAI,SAAS,YAAY,WAAW,SAAS,kBAAkB,CAAC;AACtE,QAAI,QAAQ,QAAS;IAErB,MAAM,SAAyB;KAC7B,MAAM;KACN,YAAY,KAAK;KAClB;IAED,IAAI;AACJ,QAAI;AACF,kBAAa,MAAM,oBAAoB,OAAO;aACvC,OAAO;AACd,SAAI,iBAAiB,aAAa;MAChC,MAAM,YAAa,MAAM,MAAyC;AAClE,UAAI,cAAc,+BAChB;AAEF,UAAI,cAAc,oBAAoB;AACpC,4BAAqB;AACrB;;;AAGJ,WAAM;;AAGR,QAAI,eAAe,KACjB;AAGF,QAAI,iBAAiB,WAAW,IAAI,WAAW,SAAS;AACtD,SAAI,MACF,OAAM,qBAAqB;MACzB,aAAa;MACb,QAAQ,WAAW,YAAY,OAAO,OAAO,EAAE,OAAO,WAAW,QAAQ,OAAO;MAChF,kBAAkB;MAClB,SAAS;OAAE,UAAU;OAAU,MAAM;OAAQ;MAC9C,CAAC;SAEF,OAAM,qBAAqB;MACzB,aAAa;MACb,QAAS,WAAW,WAAiC;MACrD,kBAAkB;MAClB,SAAS;OAAE,UAAU;OAAU,MAAM;OAAQ;MAC9C,CAAC;AAEJ;;;AAIJ,SAAM,IAAI,YAAY;IACpB,MAAM,UAAU;IAChB,SAAS;IACV,CAAC;;EAGJ,QAAQ,OAAO,SAA0C;GACvD,MAAM,SAAyB;IAC7B,MAAM;IACN,UAAU,KAAK;IAChB;AAED,OAAI;AACF,UAAM,oBAAoB,OAAO;YAC1B,OAAO;AACd,UAAM,IAAI,YAAY;KACpB,MAAM,UAAU;KAChB,SAAS,iBAAiB,QAAQ,MAAM,UAAU;KACnD,CAAC;;;EAGP"}
|
|
@@ -41,10 +41,10 @@ function createTotpClient(deps) {
|
|
|
41
41
|
if (proxy) {
|
|
42
42
|
const result$1 = await proxyFetch({
|
|
43
43
|
action: "auth:signIn",
|
|
44
|
-
args: {
|
|
44
|
+
args: { request: {
|
|
45
45
|
provider: "totp",
|
|
46
46
|
params
|
|
47
|
-
}
|
|
47
|
+
} }
|
|
48
48
|
});
|
|
49
49
|
if (!isTotpSetupResult(result$1)) throw new Error("Server did not return TOTP setup data.");
|
|
50
50
|
return {
|
|
@@ -54,10 +54,10 @@ function createTotpClient(deps) {
|
|
|
54
54
|
totpId: result$1.totpSetup.totpId
|
|
55
55
|
};
|
|
56
56
|
}
|
|
57
|
-
const result = await convex.action(requireApiRefs().signIn, {
|
|
57
|
+
const result = await convex.action(requireApiRefs().signIn, { request: {
|
|
58
58
|
provider: "totp",
|
|
59
59
|
params
|
|
60
|
-
});
|
|
60
|
+
} });
|
|
61
61
|
if (!isTotpSetupResult(result)) throw new Error("Server did not return TOTP setup data.");
|
|
62
62
|
return {
|
|
63
63
|
uri: result.totpSetup.uri,
|
|
@@ -75,13 +75,17 @@ function createTotpClient(deps) {
|
|
|
75
75
|
return completeSignIn(proxy ? await proxyFetch({
|
|
76
76
|
action: "auth:signIn",
|
|
77
77
|
args: {
|
|
78
|
-
|
|
79
|
-
|
|
78
|
+
request: {
|
|
79
|
+
provider: "totp",
|
|
80
|
+
params
|
|
81
|
+
},
|
|
80
82
|
verifier: opts.verifier
|
|
81
83
|
}
|
|
82
84
|
}) : await convex.action(requireApiRefs().signIn, {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
+
request: {
|
|
86
|
+
provider: "totp",
|
|
87
|
+
params
|
|
88
|
+
},
|
|
85
89
|
verifier: opts.verifier
|
|
86
90
|
}), "confirm");
|
|
87
91
|
},
|
|
@@ -93,13 +97,17 @@ function createTotpClient(deps) {
|
|
|
93
97
|
return completeSignIn(proxy ? await proxyFetch({
|
|
94
98
|
action: "auth:signIn",
|
|
95
99
|
args: {
|
|
96
|
-
|
|
97
|
-
|
|
100
|
+
request: {
|
|
101
|
+
provider: "totp",
|
|
102
|
+
params
|
|
103
|
+
},
|
|
98
104
|
verifier: opts.verifier
|
|
99
105
|
}
|
|
100
106
|
}) : await convex.action(requireApiRefs().signIn, {
|
|
101
|
-
|
|
102
|
-
|
|
107
|
+
request: {
|
|
108
|
+
provider: "totp",
|
|
109
|
+
params
|
|
110
|
+
},
|
|
103
111
|
verifier: opts.verifier
|
|
104
112
|
}), "verify");
|
|
105
113
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"totp.js","names":["result"],"sources":["../../../src/client/factors/totp.ts"],"sourcesContent":["import type { FactorDeps, SignInActionResult, SignInResult, TotpClient } from \"../core/types\";\nimport { ErrorCode } from \"../../shared/codes\";\nimport type { AuthParameters } from \"../../shared/results\";\n\nfunction isSignedInResult(\n result: SignInActionResult,\n): result is Extract<SignInActionResult, { kind: \"signedIn\" }> {\n return result.kind === \"signedIn\";\n}\n\nfunction isTotpSetupResult(\n result: SignInActionResult,\n): result is Extract<SignInActionResult, { kind: \"totpSetup\" }> {\n return result.kind === \"totpSetup\";\n}\n\n/** @internal */\nexport function createTotpClient(deps: FactorDeps): TotpClient {\n const { proxy, convex, requireApiRefs, proxyFetch, setTokenAndMaybeWait } = deps;\n\n const completeSignIn = async (\n result: SignInActionResult,\n flow: \"confirm\" | \"verify\",\n ): Promise<SignInResult> => {\n if (!isSignedInResult(result) || !result.session) {\n return { kind: \"failed\", code: ErrorCode.TOTP_INVALID_CODE };\n }\n const established = await setTokenAndMaybeWait(\n proxy\n ? {\n shouldStore: false,\n tokens: { token: result.session.token },\n waitForHandshake: true,\n context: { provider: \"totp\", flow },\n }\n : {\n shouldStore: true,\n tokens: result.session,\n waitForHandshake: true,\n context: { provider: \"totp\", flow },\n },\n );\n return established ? { kind: \"signedIn\" } : { kind: \"started\" };\n };\n\n return {\n setup: async (opts?: {\n name?: string;\n accountName?: string;\n }): Promise<{\n uri: string;\n secret: string;\n verifier: string;\n totpId: string;\n }> => {\n const params: AuthParameters = { flow: \"setup\" };\n if (opts?.name) params.name = opts.name;\n if (opts?.accountName) params.accountName = opts.accountName;\n\n if (proxy) {\n const result = (await proxyFetch({\n action: \"auth:signIn\",\n args: { provider: \"totp\", params },\n })) as SignInActionResult;\n if (!isTotpSetupResult(result)) {\n throw new Error(\"Server did not return TOTP setup data.\");\n }\n return {\n uri: result.totpSetup.uri,\n secret: result.totpSetup.secret,\n verifier: result.verifier,\n totpId: result.totpSetup.totpId,\n };\n }\n\n const result = (await convex.action(requireApiRefs().signIn, {\n provider: \"totp\"
|
|
1
|
+
{"version":3,"file":"totp.js","names":["result"],"sources":["../../../src/client/factors/totp.ts"],"sourcesContent":["import type { FactorDeps, SignInActionResult, SignInResult, TotpClient } from \"../core/types\";\nimport { ErrorCode } from \"../../shared/codes\";\nimport type { AuthParameters } from \"../../shared/results\";\n\nfunction isSignedInResult(\n result: SignInActionResult,\n): result is Extract<SignInActionResult, { kind: \"signedIn\" }> {\n return result.kind === \"signedIn\";\n}\n\nfunction isTotpSetupResult(\n result: SignInActionResult,\n): result is Extract<SignInActionResult, { kind: \"totpSetup\" }> {\n return result.kind === \"totpSetup\";\n}\n\n/** @internal */\nexport function createTotpClient(deps: FactorDeps): TotpClient {\n const { proxy, convex, requireApiRefs, proxyFetch, setTokenAndMaybeWait } = deps;\n\n const completeSignIn = async (\n result: SignInActionResult,\n flow: \"confirm\" | \"verify\",\n ): Promise<SignInResult> => {\n if (!isSignedInResult(result) || !result.session) {\n return { kind: \"failed\", code: ErrorCode.TOTP_INVALID_CODE };\n }\n const established = await setTokenAndMaybeWait(\n proxy\n ? {\n shouldStore: false,\n tokens: { token: result.session.token },\n waitForHandshake: true,\n context: { provider: \"totp\", flow },\n }\n : {\n shouldStore: true,\n tokens: result.session,\n waitForHandshake: true,\n context: { provider: \"totp\", flow },\n },\n );\n return established ? { kind: \"signedIn\" } : { kind: \"started\" };\n };\n\n return {\n setup: async (opts?: {\n name?: string;\n accountName?: string;\n }): Promise<{\n uri: string;\n secret: string;\n verifier: string;\n totpId: string;\n }> => {\n const params: AuthParameters = { flow: \"setup\" };\n if (opts?.name) params.name = opts.name;\n if (opts?.accountName) params.accountName = opts.accountName;\n\n if (proxy) {\n const result = (await proxyFetch({\n action: \"auth:signIn\",\n args: { request: { provider: \"totp\", params } },\n })) as SignInActionResult;\n if (!isTotpSetupResult(result)) {\n throw new Error(\"Server did not return TOTP setup data.\");\n }\n return {\n uri: result.totpSetup.uri,\n secret: result.totpSetup.secret,\n verifier: result.verifier,\n totpId: result.totpSetup.totpId,\n };\n }\n\n const result = (await convex.action(requireApiRefs().signIn, {\n request: { provider: \"totp\", params },\n })) as SignInActionResult;\n if (!isTotpSetupResult(result)) {\n throw new Error(\"Server did not return TOTP setup data.\");\n }\n return {\n uri: result.totpSetup.uri,\n secret: result.totpSetup.secret,\n verifier: result.verifier,\n totpId: result.totpSetup.totpId,\n };\n },\n\n confirm: async (opts: {\n code: string;\n verifier: string;\n totpId: string;\n }): Promise<SignInResult> => {\n const params: AuthParameters = {\n flow: \"verify\",\n code: opts.code,\n totpId: opts.totpId,\n };\n\n const result = (\n proxy\n ? await proxyFetch({\n action: \"auth:signIn\",\n args: { request: { provider: \"totp\", params }, verifier: opts.verifier },\n })\n : await convex.action(requireApiRefs().signIn, {\n request: { provider: \"totp\", params },\n verifier: opts.verifier,\n })\n ) as SignInActionResult;\n return completeSignIn(result, \"confirm\");\n },\n\n verify: async (opts: { code: string; verifier: string }): Promise<SignInResult> => {\n const params: AuthParameters = {\n flow: \"verify\",\n code: opts.code,\n };\n\n const result = (\n proxy\n ? await proxyFetch({\n action: \"auth:signIn\",\n args: { request: { provider: \"totp\", params }, verifier: opts.verifier },\n })\n : await convex.action(requireApiRefs().signIn, {\n request: { provider: \"totp\", params },\n verifier: opts.verifier,\n })\n ) as SignInActionResult;\n return completeSignIn(result, \"verify\");\n },\n };\n}\n"],"mappings":";;;AAIA,SAAS,iBACP,QAC6D;AAC7D,QAAO,OAAO,SAAS;;AAGzB,SAAS,kBACP,QAC8D;AAC9D,QAAO,OAAO,SAAS;;;AAIzB,SAAgB,iBAAiB,MAA8B;CAC7D,MAAM,EAAE,OAAO,QAAQ,gBAAgB,YAAY,yBAAyB;CAE5E,MAAM,iBAAiB,OACrB,QACA,SAC0B;AAC1B,MAAI,CAAC,iBAAiB,OAAO,IAAI,CAAC,OAAO,QACvC,QAAO;GAAE,MAAM;GAAU,MAAM,UAAU;GAAmB;AAiB9D,SAfoB,MAAM,qBACxB,QACI;GACE,aAAa;GACb,QAAQ,EAAE,OAAO,OAAO,QAAQ,OAAO;GACvC,kBAAkB;GAClB,SAAS;IAAE,UAAU;IAAQ;IAAM;GACpC,GACD;GACE,aAAa;GACb,QAAQ,OAAO;GACf,kBAAkB;GAClB,SAAS;IAAE,UAAU;IAAQ;IAAM;GACpC,CACN,GACoB,EAAE,MAAM,YAAY,GAAG,EAAE,MAAM,WAAW;;AAGjE,QAAO;EACL,OAAO,OAAO,SAQR;GACJ,MAAM,SAAyB,EAAE,MAAM,SAAS;AAChD,OAAI,MAAM,KAAM,QAAO,OAAO,KAAK;AACnC,OAAI,MAAM,YAAa,QAAO,cAAc,KAAK;AAEjD,OAAI,OAAO;IACT,MAAMA,WAAU,MAAM,WAAW;KAC/B,QAAQ;KACR,MAAM,EAAE,SAAS;MAAE,UAAU;MAAQ;MAAQ,EAAE;KAChD,CAAC;AACF,QAAI,CAAC,kBAAkBA,SAAO,CAC5B,OAAM,IAAI,MAAM,yCAAyC;AAE3D,WAAO;KACL,KAAKA,SAAO,UAAU;KACtB,QAAQA,SAAO,UAAU;KACzB,UAAUA,SAAO;KACjB,QAAQA,SAAO,UAAU;KAC1B;;GAGH,MAAM,SAAU,MAAM,OAAO,OAAO,gBAAgB,CAAC,QAAQ,EAC3D,SAAS;IAAE,UAAU;IAAQ;IAAQ,EACtC,CAAC;AACF,OAAI,CAAC,kBAAkB,OAAO,CAC5B,OAAM,IAAI,MAAM,yCAAyC;AAE3D,UAAO;IACL,KAAK,OAAO,UAAU;IACtB,QAAQ,OAAO,UAAU;IACzB,UAAU,OAAO;IACjB,QAAQ,OAAO,UAAU;IAC1B;;EAGH,SAAS,OAAO,SAIa;GAC3B,MAAM,SAAyB;IAC7B,MAAM;IACN,MAAM,KAAK;IACX,QAAQ,KAAK;IACd;AAaD,UAAO,eAVL,QACI,MAAM,WAAW;IACf,QAAQ;IACR,MAAM;KAAE,SAAS;MAAE,UAAU;MAAQ;MAAQ;KAAE,UAAU,KAAK;KAAU;IACzE,CAAC,GACF,MAAM,OAAO,OAAO,gBAAgB,CAAC,QAAQ;IAC3C,SAAS;KAAE,UAAU;KAAQ;KAAQ;IACrC,UAAU,KAAK;IAChB,CAAC,EAEsB,UAAU;;EAG1C,QAAQ,OAAO,SAAoE;GACjF,MAAM,SAAyB;IAC7B,MAAM;IACN,MAAM,KAAK;IACZ;AAaD,UAAO,eAVL,QACI,MAAM,WAAW;IACf,QAAQ;IACR,MAAM;KAAE,SAAS;MAAE,UAAU;MAAQ;MAAQ;KAAE,UAAU,KAAK;KAAU;IACzE,CAAC,GACF,MAAM,OAAO,OAAO,gBAAgB,CAAC,QAAQ;IAC3C,SAAS;KAAE,UAAU;KAAQ;KAAQ;IACrC,UAAU,KAAK;IAChB,CAAC,EAEsB,SAAS;;EAE1C"}
|