@robelest/convex-auth 0.0.4-preview.25 → 0.0.4-preview.28
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 +43 -36
- package/dist/bin.js +5765 -4880
- package/dist/browser/index.d.ts +30 -0
- package/dist/browser/index.js +93 -0
- package/dist/browser/locks.js +11 -0
- package/dist/browser/navigation.js +14 -0
- package/dist/{factors → browser}/passkey.js +23 -32
- package/dist/browser/runtime.js +92 -0
- package/dist/client/core/types.d.ts +452 -5
- package/dist/client/core/types.js +17 -0
- package/dist/client/errors.js +19 -0
- package/dist/client/factors/device.js +94 -0
- package/dist/{factors → client/factors}/totp.js +12 -4
- package/dist/client/index.d.ts +47 -1
- package/dist/client/index.js +269 -232
- package/dist/client/runtime/mutex.js +24 -0
- package/dist/client/runtime/proxy.js +30 -0
- package/dist/client/runtime/storage.js +45 -0
- package/dist/client/services/adapters.js +7 -0
- package/dist/client/services/http.js +6 -0
- package/dist/client/services/resolve.js +13 -0
- package/dist/client/services/runtime.js +6 -0
- package/dist/component/_generated/component.d.ts +1355 -1399
- package/dist/component/convex.config.d.ts +2 -2
- package/dist/component/index.d.ts +4 -26
- package/dist/component/index.js +1 -1
- package/dist/component/model.d.ts +26 -112
- package/dist/component/model.js +76 -54
- package/dist/component/modules.js +38 -0
- package/dist/component/public/factors/devices.js +1 -1
- package/dist/component/public/factors/passkeys.js +1 -1
- package/dist/component/public/factors/totp.js +1 -1
- package/dist/component/public/groups/core.js +2 -2
- package/dist/component/public/groups/invites.js +1 -1
- package/dist/component/public/groups/members.js +1 -1
- package/dist/component/public/identity/accounts.js +1 -1
- package/dist/component/public/identity/codes.js +1 -1
- package/dist/component/public/identity/sessions.js +39 -2
- package/dist/component/public/identity/tokens.js +82 -4
- package/dist/component/public/identity/users.js +1 -1
- package/dist/component/public/identity/verifiers.js +10 -4
- package/dist/component/public/security/keys.js +1 -1
- package/dist/component/public/security/limits.js +1 -1
- package/dist/component/public/{enterprise → sso}/audit.js +26 -26
- package/dist/component/public/sso/core.js +263 -0
- package/dist/component/public/sso/domains.js +280 -0
- package/dist/component/public/{enterprise → sso}/scim.js +87 -87
- package/dist/component/public/sso/secrets.js +125 -0
- package/dist/component/public/{enterprise → sso}/webhooks.js +59 -59
- package/dist/component/public.js +9 -9
- package/dist/component/schema.d.ts +472 -393
- package/dist/component/schema.js +36 -35
- package/dist/core/index.d.ts +380 -0
- package/dist/core/index.js +83 -0
- package/dist/otel.d.ts +69 -0
- package/dist/otel.js +82 -0
- package/dist/providers/anonymous.d.ts +15 -34
- package/dist/providers/anonymous.js +27 -35
- package/dist/providers/apple.d.ts +59 -0
- package/dist/providers/apple.js +58 -0
- package/dist/providers/credentials.d.ts +18 -34
- package/dist/providers/credentials.js +16 -27
- package/dist/providers/custom.d.ts +94 -0
- package/dist/providers/custom.js +119 -0
- package/dist/providers/device.d.ts +15 -49
- package/dist/providers/device.js +17 -34
- package/dist/providers/email.d.ts +21 -38
- package/dist/providers/email.js +36 -55
- package/dist/providers/github.d.ts +54 -0
- package/dist/providers/github.js +75 -0
- package/dist/providers/google.d.ts +54 -0
- package/dist/providers/google.js +61 -0
- package/dist/providers/index.d.ts +16 -12
- package/dist/providers/index.js +15 -11
- package/dist/providers/microsoft.d.ts +57 -0
- package/dist/providers/microsoft.js +101 -0
- package/dist/providers/passkey.d.ts +19 -35
- package/dist/providers/passkey.js +20 -30
- package/dist/providers/password.d.ts +17 -18
- package/dist/providers/password.js +121 -143
- package/dist/providers/phone.d.ts +13 -28
- package/dist/providers/phone.js +21 -46
- package/dist/providers/sso.d.ts +16 -36
- package/dist/providers/sso.js +21 -22
- package/dist/providers/totp.d.ts +13 -29
- package/dist/providers/totp.js +17 -27
- package/dist/server/auth-context.d.ts +204 -0
- package/dist/server/auth-context.js +76 -0
- package/dist/server/auth.d.ts +99 -244
- package/dist/server/auth.js +56 -152
- package/dist/server/componentContext.d.ts +12 -0
- package/dist/server/componentContext.js +1 -0
- package/dist/server/config.js +6 -67
- package/dist/server/constants.js +6 -0
- package/dist/server/contract.d.ts +105 -0
- package/dist/server/contract.js +43 -0
- package/dist/server/cookies.js +3 -2
- package/dist/server/core.js +31 -36
- package/dist/server/crypto.js +34 -44
- package/dist/server/db.js +6 -1
- package/dist/server/device.js +96 -130
- package/dist/server/env.js +48 -0
- package/dist/server/errors.js +20 -0
- package/dist/server/http.d.ts +15 -59
- package/dist/server/http.js +136 -120
- package/dist/server/identity.js +2 -2
- package/dist/server/index.d.ts +5 -4
- package/dist/server/index.js +3 -3
- package/dist/server/keys.js +10 -1
- package/dist/server/limits.js +26 -26
- package/dist/server/log.js +28 -0
- package/dist/server/mounts.d.ts +1107 -296
- package/dist/server/mounts.js +315 -196
- package/dist/server/mutations/account.js +11 -14
- package/dist/server/mutations/code.js +6 -5
- package/dist/server/mutations/invalidate.js +9 -11
- package/dist/server/mutations/oauth.js +112 -73
- package/dist/server/mutations/refresh.js +47 -97
- package/dist/server/mutations/register.js +37 -35
- package/dist/server/mutations/retrieve.js +16 -16
- package/dist/server/mutations/signature.js +15 -18
- package/dist/server/mutations/signin.js +10 -5
- package/dist/server/mutations/signout.js +11 -14
- package/dist/server/mutations/store.js +25 -18
- package/dist/server/mutations/verifier.js +11 -8
- package/dist/server/mutations/verify.js +53 -41
- package/dist/server/oauth/factory.js +44 -0
- package/dist/server/oauth/index.js +12 -0
- package/dist/server/oauth/runtime.js +248 -0
- package/dist/server/passkey.js +331 -365
- package/dist/server/payloads.d.ts +16 -0
- package/dist/server/payloads.js +30 -0
- package/dist/server/{ssr.d.ts → prefetch.d.ts} +2 -2
- package/dist/server/prefetch.js +635 -0
- package/dist/server/random.js +19 -0
- package/dist/server/redirects.js +10 -5
- package/dist/server/refresh.js +14 -86
- package/dist/server/runtime.d.ts +531 -31
- package/dist/server/runtime.js +106 -267
- package/dist/server/secret.js +44 -0
- package/dist/server/services/config.js +10 -0
- package/dist/server/services/group.js +211 -0
- package/dist/server/services/logger.js +8 -0
- package/dist/server/services/providers.js +22 -0
- package/dist/server/services/refresh.js +8 -0
- package/dist/server/services/resolve.js +27 -0
- package/dist/server/services/signin.js +8 -0
- package/dist/server/sessions.js +35 -34
- package/dist/server/signin.js +229 -140
- package/dist/server/{enterprise → sso}/config.js +10 -3
- package/dist/server/sso/domain.d.ts +614 -0
- package/dist/server/sso/domain.js +1175 -0
- package/dist/server/sso/http.js +1060 -0
- package/dist/server/sso/oidc.js +324 -0
- package/dist/server/sso/policies.js +59 -0
- package/dist/server/sso/policy.js +139 -0
- package/dist/server/sso/profile.js +22 -0
- package/dist/server/sso/provision.js +179 -0
- package/dist/{component/server/enterprise → server/sso}/saml.js +142 -56
- package/dist/{component/server/enterprise → server/sso}/scim.js +13 -7
- package/dist/server/sso/shared.js +74 -0
- package/dist/server/sso/validators.js +88 -0
- package/dist/server/sso/webhook.js +94 -0
- package/dist/server/tokens.js +16 -4
- package/dist/server/totp.js +155 -164
- package/dist/server/types.d.ts +306 -296
- package/dist/server/types.js +1 -30
- package/dist/server/url.js +32 -0
- package/dist/server/users.js +74 -40
- package/dist/server/utils/cache.js +51 -0
- package/dist/server/utils/dispatch.js +36 -0
- package/dist/server/utils/retry.js +24 -0
- package/dist/server/utils/span.js +32 -0
- package/dist/shared/errors.js +19 -0
- package/dist/shared/log.js +45 -0
- package/{src/test.ts → dist/test.d.ts} +21 -22
- package/dist/test.js +51 -0
- package/package.json +70 -42
- package/dist/authorization/index.d.ts.map +0 -1
- package/dist/authorization/index.js.map +0 -1
- package/dist/client/core/types.d.ts.map +0 -1
- package/dist/client/index.d.ts.map +0 -1
- package/dist/client/index.js.map +0 -1
- package/dist/component/_generated/api.d.ts +0 -75
- package/dist/component/_generated/api.d.ts.map +0 -1
- package/dist/component/_generated/api.js.map +0 -1
- package/dist/component/_generated/component.d.ts.map +0 -1
- package/dist/component/_generated/dataModel.d.ts +0 -42
- package/dist/component/_generated/dataModel.d.ts.map +0 -1
- package/dist/component/_generated/server.d.ts +0 -117
- package/dist/component/_generated/server.d.ts.map +0 -1
- package/dist/component/_generated/server.js.map +0 -1
- package/dist/component/_virtual/rolldown_runtime.js +0 -18
- package/dist/component/client/core/types.d.ts +0 -2
- package/dist/component/client/index.d.ts +0 -1
- package/dist/component/convex.config.d.ts.map +0 -1
- package/dist/component/convex.config.js.map +0 -1
- package/dist/component/functions.d.ts +0 -25
- package/dist/component/functions.d.ts.map +0 -1
- package/dist/component/functions.js.map +0 -1
- package/dist/component/index.d.ts.map +0 -1
- package/dist/component/model.d.ts.map +0 -1
- package/dist/component/model.js.map +0 -1
- package/dist/component/providers/anonymous.d.ts +0 -54
- package/dist/component/providers/anonymous.d.ts.map +0 -1
- package/dist/component/providers/credentials.d.ts +0 -38
- package/dist/component/providers/credentials.d.ts.map +0 -1
- package/dist/component/providers/device.d.ts +0 -67
- package/dist/component/providers/device.d.ts.map +0 -1
- package/dist/component/providers/email.d.ts +0 -62
- package/dist/component/providers/email.d.ts.map +0 -1
- package/dist/component/providers/oauth.d.ts +0 -25
- package/dist/component/providers/oauth.d.ts.map +0 -1
- package/dist/component/providers/oauth.js +0 -13
- package/dist/component/providers/oauth.js.map +0 -1
- package/dist/component/providers/passkey.d.ts +0 -57
- package/dist/component/providers/passkey.d.ts.map +0 -1
- package/dist/component/providers/password.d.ts +0 -88
- package/dist/component/providers/password.d.ts.map +0 -1
- package/dist/component/providers/phone.d.ts +0 -48
- package/dist/component/providers/phone.d.ts.map +0 -1
- package/dist/component/providers/sso.d.ts +0 -50
- package/dist/component/providers/sso.d.ts.map +0 -1
- package/dist/component/providers/totp.d.ts +0 -45
- package/dist/component/providers/totp.d.ts.map +0 -1
- package/dist/component/public/enterprise/audit.d.ts +0 -73
- package/dist/component/public/enterprise/audit.d.ts.map +0 -1
- package/dist/component/public/enterprise/audit.js.map +0 -1
- package/dist/component/public/enterprise/core.d.ts +0 -176
- package/dist/component/public/enterprise/core.d.ts.map +0 -1
- package/dist/component/public/enterprise/core.js +0 -292
- package/dist/component/public/enterprise/core.js.map +0 -1
- package/dist/component/public/enterprise/domains.d.ts +0 -174
- package/dist/component/public/enterprise/domains.d.ts.map +0 -1
- package/dist/component/public/enterprise/domains.js +0 -271
- package/dist/component/public/enterprise/domains.js.map +0 -1
- package/dist/component/public/enterprise/scim.d.ts +0 -245
- package/dist/component/public/enterprise/scim.d.ts.map +0 -1
- package/dist/component/public/enterprise/scim.js.map +0 -1
- package/dist/component/public/enterprise/secrets.d.ts +0 -78
- package/dist/component/public/enterprise/secrets.d.ts.map +0 -1
- package/dist/component/public/enterprise/secrets.js +0 -118
- package/dist/component/public/enterprise/secrets.js.map +0 -1
- package/dist/component/public/enterprise/webhooks.d.ts +0 -211
- package/dist/component/public/enterprise/webhooks.d.ts.map +0 -1
- package/dist/component/public/enterprise/webhooks.js.map +0 -1
- package/dist/component/public/factors/devices.d.ts +0 -157
- package/dist/component/public/factors/devices.d.ts.map +0 -1
- package/dist/component/public/factors/devices.js.map +0 -1
- package/dist/component/public/factors/passkeys.d.ts +0 -175
- package/dist/component/public/factors/passkeys.d.ts.map +0 -1
- package/dist/component/public/factors/passkeys.js.map +0 -1
- package/dist/component/public/factors/totp.d.ts +0 -189
- package/dist/component/public/factors/totp.d.ts.map +0 -1
- package/dist/component/public/factors/totp.js.map +0 -1
- package/dist/component/public/groups/core.d.ts +0 -137
- package/dist/component/public/groups/core.d.ts.map +0 -1
- package/dist/component/public/groups/core.js.map +0 -1
- package/dist/component/public/groups/invites.d.ts +0 -217
- package/dist/component/public/groups/invites.d.ts.map +0 -1
- package/dist/component/public/groups/invites.js.map +0 -1
- package/dist/component/public/groups/members.d.ts +0 -204
- package/dist/component/public/groups/members.d.ts.map +0 -1
- package/dist/component/public/groups/members.js.map +0 -1
- package/dist/component/public/identity/accounts.d.ts +0 -147
- package/dist/component/public/identity/accounts.d.ts.map +0 -1
- package/dist/component/public/identity/accounts.js.map +0 -1
- package/dist/component/public/identity/codes.d.ts +0 -104
- package/dist/component/public/identity/codes.d.ts.map +0 -1
- package/dist/component/public/identity/codes.js.map +0 -1
- package/dist/component/public/identity/sessions.d.ts +0 -128
- package/dist/component/public/identity/sessions.d.ts.map +0 -1
- package/dist/component/public/identity/sessions.js.map +0 -1
- package/dist/component/public/identity/tokens.d.ts +0 -169
- package/dist/component/public/identity/tokens.d.ts.map +0 -1
- package/dist/component/public/identity/tokens.js.map +0 -1
- package/dist/component/public/identity/users.d.ts +0 -212
- package/dist/component/public/identity/users.d.ts.map +0 -1
- package/dist/component/public/identity/users.js.map +0 -1
- package/dist/component/public/identity/verifiers.d.ts +0 -116
- package/dist/component/public/identity/verifiers.d.ts.map +0 -1
- package/dist/component/public/identity/verifiers.js.map +0 -1
- package/dist/component/public/security/keys.d.ts +0 -209
- package/dist/component/public/security/keys.d.ts.map +0 -1
- package/dist/component/public/security/keys.js.map +0 -1
- package/dist/component/public/security/limits.d.ts +0 -114
- package/dist/component/public/security/limits.d.ts.map +0 -1
- package/dist/component/public/security/limits.js.map +0 -1
- package/dist/component/public.d.ts +0 -28
- package/dist/component/public.d.ts.map +0 -1
- package/dist/component/schema.d.ts.map +0 -1
- package/dist/component/schema.js.map +0 -1
- package/dist/component/server/auth.d.ts +0 -447
- package/dist/component/server/auth.d.ts.map +0 -1
- package/dist/component/server/auth.js +0 -254
- package/dist/component/server/auth.js.map +0 -1
- package/dist/component/server/config.js +0 -121
- package/dist/component/server/config.js.map +0 -1
- package/dist/component/server/context.js +0 -53
- package/dist/component/server/context.js.map +0 -1
- package/dist/component/server/cookies.js +0 -47
- package/dist/component/server/cookies.js.map +0 -1
- package/dist/component/server/core.js +0 -576
- package/dist/component/server/core.js.map +0 -1
- package/dist/component/server/crypto.js +0 -56
- package/dist/component/server/crypto.js.map +0 -1
- package/dist/component/server/db.js +0 -87
- package/dist/component/server/db.js.map +0 -1
- package/dist/component/server/device.js +0 -152
- package/dist/component/server/device.js.map +0 -1
- package/dist/component/server/enterprise/config.js +0 -46
- package/dist/component/server/enterprise/config.js.map +0 -1
- package/dist/component/server/enterprise/domain.js +0 -974
- package/dist/component/server/enterprise/domain.js.map +0 -1
- package/dist/component/server/enterprise/http.js +0 -787
- package/dist/component/server/enterprise/http.js.map +0 -1
- package/dist/component/server/enterprise/oidc.js +0 -248
- package/dist/component/server/enterprise/oidc.js.map +0 -1
- package/dist/component/server/enterprise/policy.js +0 -85
- package/dist/component/server/enterprise/policy.js.map +0 -1
- package/dist/component/server/enterprise/saml.js.map +0 -1
- package/dist/component/server/enterprise/scim.js.map +0 -1
- package/dist/component/server/enterprise/shared.js +0 -51
- package/dist/component/server/enterprise/shared.js.map +0 -1
- package/dist/component/server/http.d.ts +0 -85
- package/dist/component/server/http.d.ts.map +0 -1
- package/dist/component/server/http.js +0 -351
- package/dist/component/server/http.js.map +0 -1
- package/dist/component/server/identity.js +0 -16
- package/dist/component/server/identity.js.map +0 -1
- package/dist/component/server/keys.js +0 -96
- package/dist/component/server/keys.js.map +0 -1
- package/dist/component/server/limits.js +0 -52
- package/dist/component/server/limits.js.map +0 -1
- package/dist/component/server/mutations/account.js +0 -46
- package/dist/component/server/mutations/account.js.map +0 -1
- package/dist/component/server/mutations/code.js +0 -68
- package/dist/component/server/mutations/code.js.map +0 -1
- package/dist/component/server/mutations/invalidate.js +0 -32
- package/dist/component/server/mutations/invalidate.js.map +0 -1
- package/dist/component/server/mutations/oauth.js +0 -116
- package/dist/component/server/mutations/oauth.js.map +0 -1
- package/dist/component/server/mutations/refresh.js +0 -119
- package/dist/component/server/mutations/refresh.js.map +0 -1
- package/dist/component/server/mutations/register.js +0 -87
- package/dist/component/server/mutations/register.js.map +0 -1
- package/dist/component/server/mutations/retrieve.js +0 -61
- package/dist/component/server/mutations/retrieve.js.map +0 -1
- package/dist/component/server/mutations/signature.js +0 -38
- package/dist/component/server/mutations/signature.js.map +0 -1
- package/dist/component/server/mutations/signin.js +0 -27
- package/dist/component/server/mutations/signin.js.map +0 -1
- package/dist/component/server/mutations/signout.js +0 -27
- package/dist/component/server/mutations/signout.js.map +0 -1
- package/dist/component/server/mutations/store/refs.js +0 -15
- package/dist/component/server/mutations/store/refs.js.map +0 -1
- package/dist/component/server/mutations/store.js +0 -70
- package/dist/component/server/mutations/store.js.map +0 -1
- package/dist/component/server/mutations/verifier.js +0 -18
- package/dist/component/server/mutations/verifier.js.map +0 -1
- package/dist/component/server/mutations/verify.js +0 -98
- package/dist/component/server/mutations/verify.js.map +0 -1
- package/dist/component/server/oauth.js +0 -242
- package/dist/component/server/oauth.js.map +0 -1
- package/dist/component/server/passkey.js +0 -415
- package/dist/component/server/passkey.js.map +0 -1
- package/dist/component/server/redirects.js +0 -40
- package/dist/component/server/redirects.js.map +0 -1
- package/dist/component/server/refresh.js +0 -99
- package/dist/component/server/refresh.js.map +0 -1
- package/dist/component/server/runtime.d.ts +0 -136
- package/dist/component/server/runtime.d.ts.map +0 -1
- package/dist/component/server/runtime.js +0 -456
- package/dist/component/server/runtime.js.map +0 -1
- package/dist/component/server/sessions.js +0 -71
- package/dist/component/server/sessions.js.map +0 -1
- package/dist/component/server/signin.js +0 -225
- package/dist/component/server/signin.js.map +0 -1
- package/dist/component/server/tokens.js +0 -17
- package/dist/component/server/tokens.js.map +0 -1
- package/dist/component/server/totp.js +0 -208
- package/dist/component/server/totp.js.map +0 -1
- package/dist/component/server/types.d.ts +0 -949
- package/dist/component/server/types.d.ts.map +0 -1
- package/dist/component/server/types.js +0 -79
- package/dist/component/server/types.js.map +0 -1
- package/dist/component/server/users.js +0 -123
- package/dist/component/server/users.js.map +0 -1
- package/dist/component/server/utils.js +0 -140
- package/dist/component/server/utils.js.map +0 -1
- package/dist/core/types.d.ts +0 -361
- package/dist/core/types.d.ts.map +0 -1
- package/dist/factors/device.js +0 -104
- package/dist/factors/device.js.map +0 -1
- package/dist/factors/passkey.js.map +0 -1
- package/dist/factors/totp.js.map +0 -1
- package/dist/providers/anonymous.d.ts.map +0 -1
- package/dist/providers/anonymous.js.map +0 -1
- package/dist/providers/credentials.d.ts.map +0 -1
- package/dist/providers/credentials.js.map +0 -1
- package/dist/providers/device.d.ts.map +0 -1
- package/dist/providers/device.js.map +0 -1
- package/dist/providers/email.d.ts.map +0 -1
- package/dist/providers/email.js.map +0 -1
- package/dist/providers/oauth.d.ts +0 -69
- package/dist/providers/oauth.d.ts.map +0 -1
- package/dist/providers/oauth.js +0 -43
- package/dist/providers/oauth.js.map +0 -1
- package/dist/providers/passkey.d.ts.map +0 -1
- package/dist/providers/passkey.js.map +0 -1
- package/dist/providers/password.d.ts.map +0 -1
- package/dist/providers/password.js.map +0 -1
- package/dist/providers/phone.d.ts.map +0 -1
- package/dist/providers/phone.js.map +0 -1
- package/dist/providers/sso.d.ts.map +0 -1
- package/dist/providers/sso.js.map +0 -1
- package/dist/providers/totp.d.ts.map +0 -1
- package/dist/providers/totp.js.map +0 -1
- package/dist/runtime/browser.js +0 -68
- package/dist/runtime/browser.js.map +0 -1
- package/dist/runtime/invite.js.map +0 -1
- package/dist/runtime/proxy.js +0 -70
- package/dist/runtime/proxy.js.map +0 -1
- package/dist/runtime/storage.js +0 -37
- package/dist/runtime/storage.js.map +0 -1
- package/dist/server/auth.d.ts.map +0 -1
- package/dist/server/auth.js.map +0 -1
- package/dist/server/config.d.ts +0 -1
- package/dist/server/config.js.map +0 -1
- package/dist/server/context.d.ts +0 -1
- package/dist/server/context.js.map +0 -1
- package/dist/server/cookies.d.ts +0 -1
- package/dist/server/cookies.js.map +0 -1
- package/dist/server/core.d.ts +0 -1315
- package/dist/server/core.d.ts.map +0 -1
- package/dist/server/core.js.map +0 -1
- package/dist/server/crypto.d.ts +0 -8
- package/dist/server/crypto.d.ts.map +0 -1
- package/dist/server/crypto.js.map +0 -1
- package/dist/server/db.d.ts +0 -1
- package/dist/server/db.js.map +0 -1
- package/dist/server/device.d.ts +0 -1
- package/dist/server/device.js.map +0 -1
- package/dist/server/enterprise/config.d.ts +0 -1
- package/dist/server/enterprise/config.js.map +0 -1
- package/dist/server/enterprise/domain.d.ts +0 -401
- package/dist/server/enterprise/domain.d.ts.map +0 -1
- package/dist/server/enterprise/domain.js +0 -974
- package/dist/server/enterprise/domain.js.map +0 -1
- package/dist/server/enterprise/http.d.ts +0 -26
- package/dist/server/enterprise/http.d.ts.map +0 -1
- package/dist/server/enterprise/http.js +0 -787
- package/dist/server/enterprise/http.js.map +0 -1
- package/dist/server/enterprise/oidc.d.ts +0 -1
- package/dist/server/enterprise/oidc.js +0 -248
- package/dist/server/enterprise/oidc.js.map +0 -1
- package/dist/server/enterprise/policy.d.ts +0 -1
- package/dist/server/enterprise/policy.js +0 -85
- package/dist/server/enterprise/policy.js.map +0 -1
- package/dist/server/enterprise/saml.d.ts +0 -1
- package/dist/server/enterprise/saml.js +0 -338
- package/dist/server/enterprise/saml.js.map +0 -1
- package/dist/server/enterprise/scim.d.ts +0 -1
- package/dist/server/enterprise/scim.js +0 -97
- package/dist/server/enterprise/scim.js.map +0 -1
- package/dist/server/enterprise/shared.d.ts +0 -5
- package/dist/server/enterprise/shared.d.ts.map +0 -1
- package/dist/server/enterprise/shared.js +0 -51
- package/dist/server/enterprise/shared.js.map +0 -1
- package/dist/server/enterprise/validators.d.ts +0 -1
- package/dist/server/enterprise/validators.js +0 -60
- package/dist/server/enterprise/validators.js.map +0 -1
- package/dist/server/http.d.ts.map +0 -1
- package/dist/server/http.js.map +0 -1
- package/dist/server/identity.d.ts +0 -1
- package/dist/server/identity.js.map +0 -1
- package/dist/server/keys.d.ts +0 -1
- package/dist/server/keys.js.map +0 -1
- package/dist/server/limits.d.ts +0 -1
- package/dist/server/limits.js.map +0 -1
- package/dist/server/mounts.d.ts.map +0 -1
- package/dist/server/mounts.js.map +0 -1
- package/dist/server/mutations/account.d.ts +0 -29
- package/dist/server/mutations/account.d.ts.map +0 -1
- package/dist/server/mutations/account.js.map +0 -1
- package/dist/server/mutations/code.d.ts +0 -30
- package/dist/server/mutations/code.d.ts.map +0 -1
- package/dist/server/mutations/code.js.map +0 -1
- package/dist/server/mutations/index.d.ts +0 -14
- package/dist/server/mutations/invalidate.d.ts +0 -20
- package/dist/server/mutations/invalidate.d.ts.map +0 -1
- package/dist/server/mutations/invalidate.js.map +0 -1
- package/dist/server/mutations/oauth.d.ts +0 -30
- package/dist/server/mutations/oauth.d.ts.map +0 -1
- package/dist/server/mutations/oauth.js.map +0 -1
- package/dist/server/mutations/refresh.d.ts +0 -21
- package/dist/server/mutations/refresh.d.ts.map +0 -1
- package/dist/server/mutations/refresh.js.map +0 -1
- package/dist/server/mutations/register.d.ts +0 -38
- package/dist/server/mutations/register.d.ts.map +0 -1
- package/dist/server/mutations/register.js.map +0 -1
- package/dist/server/mutations/retrieve.d.ts +0 -33
- package/dist/server/mutations/retrieve.d.ts.map +0 -1
- package/dist/server/mutations/retrieve.js.map +0 -1
- package/dist/server/mutations/signature.d.ts +0 -21
- package/dist/server/mutations/signature.d.ts.map +0 -1
- package/dist/server/mutations/signature.js.map +0 -1
- package/dist/server/mutations/signin.d.ts +0 -22
- package/dist/server/mutations/signin.d.ts.map +0 -1
- package/dist/server/mutations/signin.js.map +0 -1
- package/dist/server/mutations/signout.d.ts +0 -16
- package/dist/server/mutations/signout.d.ts.map +0 -1
- package/dist/server/mutations/signout.js.map +0 -1
- package/dist/server/mutations/store/refs.d.ts +0 -12
- package/dist/server/mutations/store/refs.d.ts.map +0 -1
- package/dist/server/mutations/store/refs.js.map +0 -1
- package/dist/server/mutations/store.d.ts +0 -306
- package/dist/server/mutations/store.d.ts.map +0 -1
- package/dist/server/mutations/store.js.map +0 -1
- package/dist/server/mutations/verifier.d.ts +0 -13
- package/dist/server/mutations/verifier.d.ts.map +0 -1
- package/dist/server/mutations/verifier.js.map +0 -1
- package/dist/server/mutations/verify.d.ts +0 -26
- package/dist/server/mutations/verify.d.ts.map +0 -1
- package/dist/server/mutations/verify.js.map +0 -1
- package/dist/server/oauth.d.ts +0 -1
- package/dist/server/oauth.js +0 -242
- package/dist/server/oauth.js.map +0 -1
- package/dist/server/passkey.d.ts +0 -27
- package/dist/server/passkey.d.ts.map +0 -1
- package/dist/server/passkey.js.map +0 -1
- package/dist/server/redirects.d.ts +0 -1
- package/dist/server/redirects.js.map +0 -1
- package/dist/server/refresh.d.ts +0 -1
- package/dist/server/refresh.js.map +0 -1
- package/dist/server/runtime.d.ts.map +0 -1
- package/dist/server/runtime.js.map +0 -1
- package/dist/server/sessions.d.ts +0 -1
- package/dist/server/sessions.js.map +0 -1
- package/dist/server/signin.d.ts +0 -1
- package/dist/server/signin.js.map +0 -1
- package/dist/server/ssr.d.ts.map +0 -1
- package/dist/server/ssr.js +0 -777
- package/dist/server/ssr.js.map +0 -1
- package/dist/server/templates.d.ts +0 -1
- package/dist/server/templates.js.map +0 -1
- package/dist/server/tokens.d.ts +0 -1
- package/dist/server/tokens.js.map +0 -1
- package/dist/server/totp.d.ts +0 -1
- package/dist/server/totp.js.map +0 -1
- package/dist/server/types.d.ts.map +0 -1
- package/dist/server/types.js.map +0 -1
- package/dist/server/users.d.ts +0 -1
- package/dist/server/users.js.map +0 -1
- package/dist/server/utils.d.ts +0 -1
- package/dist/server/utils.js +0 -140
- package/dist/server/utils.js.map +0 -1
- package/src/authorization/index.ts +0 -83
- package/src/cli/bin.ts +0 -5
- package/src/cli/command.ts +0 -70
- package/src/cli/index.ts +0 -1112
- package/src/cli/keys.ts +0 -23
- package/src/client/core/types.ts +0 -437
- package/src/client/factors/device.ts +0 -158
- package/src/client/factors/passkey.ts +0 -279
- package/src/client/factors/totp.ts +0 -150
- package/src/client/index.ts +0 -1124
- package/src/client/runtime/browser.ts +0 -112
- package/src/client/runtime/invite.ts +0 -63
- package/src/client/runtime/proxy.ts +0 -111
- package/src/client/runtime/storage.ts +0 -79
- package/src/component/_generated/api.ts +0 -96
- package/src/component/_generated/component.ts +0 -3774
- package/src/component/_generated/dataModel.ts +0 -60
- package/src/component/_generated/server.ts +0 -156
- package/src/component/convex.config.ts +0 -5
- package/src/component/functions.ts +0 -104
- package/src/component/index.ts +0 -42
- package/src/component/model.ts +0 -449
- package/src/component/public/enterprise/audit.ts +0 -125
- package/src/component/public/enterprise/core.ts +0 -355
- package/src/component/public/enterprise/domains.ts +0 -327
- package/src/component/public/enterprise/scim.ts +0 -397
- package/src/component/public/enterprise/secrets.ts +0 -133
- package/src/component/public/enterprise/webhooks.ts +0 -307
- package/src/component/public/factors/devices.ts +0 -224
- package/src/component/public/factors/passkeys.ts +0 -243
- package/src/component/public/factors/totp.ts +0 -259
- package/src/component/public/groups/core.ts +0 -481
- package/src/component/public/groups/invites.ts +0 -608
- package/src/component/public/groups/members.ts +0 -410
- package/src/component/public/identity/accounts.ts +0 -207
- package/src/component/public/identity/codes.ts +0 -149
- package/src/component/public/identity/sessions.ts +0 -210
- package/src/component/public/identity/tokens.ts +0 -251
- package/src/component/public/identity/users.ts +0 -355
- package/src/component/public/identity/verifiers.ts +0 -158
- package/src/component/public/security/keys.ts +0 -366
- package/src/component/public/security/limits.ts +0 -174
- package/src/component/public.ts +0 -27
- package/src/component/schema.ts +0 -505
- package/src/providers/anonymous.ts +0 -99
- package/src/providers/credentials.ts +0 -102
- package/src/providers/device.ts +0 -87
- package/src/providers/email.ts +0 -99
- package/src/providers/index.ts +0 -31
- package/src/providers/oauth.ts +0 -117
- package/src/providers/passkey.ts +0 -77
- package/src/providers/password.ts +0 -441
- package/src/providers/phone.ts +0 -93
- package/src/providers/sso.ts +0 -54
- package/src/providers/totp.ts +0 -62
- package/src/samlify.d.ts +0 -53
- package/src/server/auth.ts +0 -949
- package/src/server/config.ts +0 -200
- package/src/server/context.ts +0 -90
- package/src/server/cookies.ts +0 -49
- package/src/server/core.ts +0 -2004
- package/src/server/crypto.ts +0 -90
- package/src/server/db.ts +0 -203
- package/src/server/device.ts +0 -254
- package/src/server/enterprise/config.ts +0 -51
- package/src/server/enterprise/domain.ts +0 -1739
- package/src/server/enterprise/http.ts +0 -1331
- package/src/server/enterprise/oidc.ts +0 -500
- package/src/server/enterprise/policy.ts +0 -128
- package/src/server/enterprise/saml.ts +0 -578
- package/src/server/enterprise/scim.ts +0 -135
- package/src/server/enterprise/shared.ts +0 -134
- package/src/server/enterprise/validators.ts +0 -93
- package/src/server/http.ts +0 -790
- package/src/server/identity.ts +0 -18
- package/src/server/index.ts +0 -40
- package/src/server/keys.ts +0 -158
- package/src/server/limits.ts +0 -107
- package/src/server/mounts.ts +0 -924
- package/src/server/mutations/account.ts +0 -62
- package/src/server/mutations/code.ts +0 -119
- package/src/server/mutations/index.ts +0 -13
- package/src/server/mutations/invalidate.ts +0 -50
- package/src/server/mutations/oauth.ts +0 -243
- package/src/server/mutations/refresh.ts +0 -299
- package/src/server/mutations/register.ts +0 -155
- package/src/server/mutations/retrieve.ts +0 -109
- package/src/server/mutations/signature.ts +0 -57
- package/src/server/mutations/signin.ts +0 -54
- package/src/server/mutations/signout.ts +0 -43
- package/src/server/mutations/store/refs.ts +0 -10
- package/src/server/mutations/store.ts +0 -123
- package/src/server/mutations/verifier.ts +0 -34
- package/src/server/mutations/verify.ts +0 -200
- package/src/server/oauth.ts +0 -418
- package/src/server/passkey.ts +0 -838
- package/src/server/redirects.ts +0 -59
- package/src/server/refresh.ts +0 -218
- package/src/server/runtime.ts +0 -918
- package/src/server/sessions.ts +0 -132
- package/src/server/signin.ts +0 -445
- package/src/server/ssr.ts +0 -1747
- package/src/server/templates.ts +0 -82
- package/src/server/tokens.ts +0 -35
- package/src/server/totp.ts +0 -399
- package/src/server/types.ts +0 -1942
- package/src/server/users.ts +0 -291
- package/src/server/utils.ts +0 -220
- /package/dist/{runtime → client/runtime}/invite.js +0 -0
package/src/cli/index.ts
DELETED
|
@@ -1,1112 +0,0 @@
|
|
|
1
|
-
import { execFileSync } from "child_process";
|
|
2
|
-
import {
|
|
3
|
-
existsSync,
|
|
4
|
-
mkdtempSync,
|
|
5
|
-
readFileSync,
|
|
6
|
-
writeFileSync,
|
|
7
|
-
unlinkSync,
|
|
8
|
-
} from "fs";
|
|
9
|
-
import { tmpdir } from "os";
|
|
10
|
-
import path from "path";
|
|
11
|
-
|
|
12
|
-
import * as p from "@clack/prompts";
|
|
13
|
-
import { Command } from "@commander-js/extra-typings";
|
|
14
|
-
import { config as loadEnvFile } from "dotenv";
|
|
15
|
-
import * as v from "valibot";
|
|
16
|
-
|
|
17
|
-
import { actionDescription } from "./command";
|
|
18
|
-
import { generateKeys } from "./keys";
|
|
19
|
-
|
|
20
|
-
// ---------------------------------------------------------------------------
|
|
21
|
-
// Package version
|
|
22
|
-
// ---------------------------------------------------------------------------
|
|
23
|
-
|
|
24
|
-
function getPackageVersion(): string {
|
|
25
|
-
// When bundled to dist/bin.js the package.json is one level up
|
|
26
|
-
for (const relative of ["..", "../.."]) {
|
|
27
|
-
try {
|
|
28
|
-
const pkgPath = path.resolve(__dirname, relative, "package.json");
|
|
29
|
-
return JSON.parse(readFileSync(pkgPath, "utf-8")).version;
|
|
30
|
-
} catch {
|
|
31
|
-
// try next
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
return "unknown";
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
const version = getPackageVersion();
|
|
38
|
-
|
|
39
|
-
// ---------------------------------------------------------------------------
|
|
40
|
-
// Package-manager detection
|
|
41
|
-
// ---------------------------------------------------------------------------
|
|
42
|
-
|
|
43
|
-
type PackageRunner = { cmd: string; args: string[] };
|
|
44
|
-
|
|
45
|
-
function detectPackageRunner(): PackageRunner {
|
|
46
|
-
// Walk up from cwd to find lockfiles or packageManager field
|
|
47
|
-
let dir = process.cwd();
|
|
48
|
-
const root = path.parse(dir).root;
|
|
49
|
-
|
|
50
|
-
while (dir !== root) {
|
|
51
|
-
const pkgPath = path.join(dir, "package.json");
|
|
52
|
-
if (existsSync(pkgPath)) {
|
|
53
|
-
try {
|
|
54
|
-
const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
|
|
55
|
-
if (typeof pkg.packageManager === "string") {
|
|
56
|
-
const name = pkg.packageManager.split("@")[0];
|
|
57
|
-
if (name === "pnpm") return { cmd: "pnpm", args: ["exec"] };
|
|
58
|
-
if (name === "bun") return { cmd: "bunx", args: [] };
|
|
59
|
-
if (name === "yarn") return { cmd: "yarn", args: ["dlx"] };
|
|
60
|
-
}
|
|
61
|
-
} catch {
|
|
62
|
-
// ignore parse errors
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
if (existsSync(path.join(dir, "pnpm-lock.yaml")))
|
|
67
|
-
return { cmd: "pnpm", args: ["exec"] };
|
|
68
|
-
if (
|
|
69
|
-
existsSync(path.join(dir, "bun.lockb")) ||
|
|
70
|
-
existsSync(path.join(dir, "bun.lock"))
|
|
71
|
-
)
|
|
72
|
-
return { cmd: "bunx", args: [] };
|
|
73
|
-
if (existsSync(path.join(dir, "yarn.lock")))
|
|
74
|
-
return { cmd: "yarn", args: ["dlx"] };
|
|
75
|
-
|
|
76
|
-
dir = path.dirname(dir);
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
return { cmd: "npx", args: [] };
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
const runner = detectPackageRunner();
|
|
83
|
-
|
|
84
|
-
/** Build the full command + args to invoke `convex` via the detected runner. */
|
|
85
|
-
function convexCmd(...subArgs: string[]): { file: string; args: string[] } {
|
|
86
|
-
return { file: runner.cmd, args: [...runner.args, "convex", ...subArgs] };
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
// ---------------------------------------------------------------------------
|
|
90
|
-
// Commander program
|
|
91
|
-
// ---------------------------------------------------------------------------
|
|
92
|
-
|
|
93
|
-
export const program = new Command()
|
|
94
|
-
.name("@robelest/convex-auth")
|
|
95
|
-
.version(version)
|
|
96
|
-
.description(
|
|
97
|
-
"Add code and set environment variables for @robelest/convex-auth.\n\n" +
|
|
98
|
-
"Full docs: https://deepwiki.com/robelest/convex-auth",
|
|
99
|
-
);
|
|
100
|
-
|
|
101
|
-
// ---- Default setup command ----
|
|
102
|
-
program
|
|
103
|
-
.option(
|
|
104
|
-
"--site-url <url>",
|
|
105
|
-
"Your frontend app URL (e.g. 'http://localhost:5173' for dev, 'https://myapp.com' for prod)",
|
|
106
|
-
)
|
|
107
|
-
.option(
|
|
108
|
-
"--secondary-url <urls>",
|
|
109
|
-
"Comma-separated additional frontend URLs allowed to share the same auth instance",
|
|
110
|
-
)
|
|
111
|
-
.option(
|
|
112
|
-
"--variables <json>",
|
|
113
|
-
"Configure additional variables for interactive configuration.",
|
|
114
|
-
)
|
|
115
|
-
.option("--skip-git-check", "Don't warn when running outside a Git checkout.")
|
|
116
|
-
.option("--allow-dirty-git-state", "Don't warn when Git state is not clean.")
|
|
117
|
-
.addDeploymentSelectionOptions(
|
|
118
|
-
actionDescription("Set environment variables on"),
|
|
119
|
-
)
|
|
120
|
-
.action(async (options) => {
|
|
121
|
-
p.intro("@robelest/convex-auth");
|
|
122
|
-
|
|
123
|
-
await checkSourceControl(options);
|
|
124
|
-
|
|
125
|
-
const packageJson = readPackageJson();
|
|
126
|
-
const convexJson = readConvexJson();
|
|
127
|
-
const deployment = readConvexDeployment(options);
|
|
128
|
-
const convexFolderPath = convexJson.functions ?? "convex";
|
|
129
|
-
|
|
130
|
-
const isNextjs = !!packageJson.dependencies?.next;
|
|
131
|
-
const usesTypeScript = !!(
|
|
132
|
-
packageJson.dependencies?.typescript ||
|
|
133
|
-
packageJson.devDependencies?.typescript
|
|
134
|
-
);
|
|
135
|
-
const isVite = !!(
|
|
136
|
-
packageJson.dependencies?.vite || packageJson.devDependencies?.vite
|
|
137
|
-
);
|
|
138
|
-
const isExpo = !!(
|
|
139
|
-
packageJson.dependencies?.expo || packageJson.devDependencies?.expo
|
|
140
|
-
);
|
|
141
|
-
const config: ProjectConfig = {
|
|
142
|
-
isNextjs,
|
|
143
|
-
isVite,
|
|
144
|
-
isExpo,
|
|
145
|
-
usesTypeScript,
|
|
146
|
-
convexFolderPath,
|
|
147
|
-
deployment,
|
|
148
|
-
step: 1,
|
|
149
|
-
};
|
|
150
|
-
|
|
151
|
-
// Step 1: Configure SITE_URL
|
|
152
|
-
await configureSiteUrl(config, options.siteUrl, options.secondaryUrl);
|
|
153
|
-
|
|
154
|
-
// Step 2: Configure private and public key
|
|
155
|
-
await configureKeys(config);
|
|
156
|
-
|
|
157
|
-
// Step 3: Change moduleResolution to "bundler" and turn on skipLibCheck
|
|
158
|
-
await modifyTsConfig(config);
|
|
159
|
-
|
|
160
|
-
// Step 4: Configure convex.config.ts
|
|
161
|
-
await configureConvexConfig(config);
|
|
162
|
-
|
|
163
|
-
// Step 5: Initialize auth.ts
|
|
164
|
-
await initializeAuth(config);
|
|
165
|
-
|
|
166
|
-
// Step 6: Configure http.ts
|
|
167
|
-
await configureHttp(config);
|
|
168
|
-
|
|
169
|
-
// Extra: Configure providers interactively.
|
|
170
|
-
if (options.variables !== undefined) {
|
|
171
|
-
await configureOtherVariables(config, options.variables);
|
|
172
|
-
} else {
|
|
173
|
-
printFinalSuccessMessage(config);
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
p.outro("Done!");
|
|
177
|
-
});
|
|
178
|
-
|
|
179
|
-
// ---------------------------------------------------------------------------
|
|
180
|
-
// Types
|
|
181
|
-
// ---------------------------------------------------------------------------
|
|
182
|
-
|
|
183
|
-
type ProjectConfig = {
|
|
184
|
-
isExpo: boolean;
|
|
185
|
-
isNextjs: boolean;
|
|
186
|
-
isVite: boolean;
|
|
187
|
-
usesTypeScript: boolean;
|
|
188
|
-
convexFolderPath: string;
|
|
189
|
-
deployment: {
|
|
190
|
-
name: string | null;
|
|
191
|
-
type: string | null;
|
|
192
|
-
options: {
|
|
193
|
-
url?: string;
|
|
194
|
-
adminKey?: string;
|
|
195
|
-
prod?: boolean;
|
|
196
|
-
previewName?: string;
|
|
197
|
-
deploymentName?: string;
|
|
198
|
-
};
|
|
199
|
-
};
|
|
200
|
-
// Mutated along the way
|
|
201
|
-
step: number;
|
|
202
|
-
};
|
|
203
|
-
|
|
204
|
-
// ---------------------------------------------------------------------------
|
|
205
|
-
// Step 1: SITE_URL
|
|
206
|
-
// ---------------------------------------------------------------------------
|
|
207
|
-
|
|
208
|
-
async function configureSiteUrl(
|
|
209
|
-
config: ProjectConfig,
|
|
210
|
-
forcedValue?: string,
|
|
211
|
-
forcedSecondaryValue?: string,
|
|
212
|
-
) {
|
|
213
|
-
logStep(config, "Configure SITE_URL");
|
|
214
|
-
if (config.isExpo) {
|
|
215
|
-
p.log.info("React Native projects don't require a SITE_URL.");
|
|
216
|
-
return;
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
// Default to localhost for dev and also for local backend
|
|
220
|
-
// this is not perfect but OK since it's just the default.
|
|
221
|
-
const value =
|
|
222
|
-
config.deployment.type === "dev" || config.deployment.type === null
|
|
223
|
-
? config.isVite
|
|
224
|
-
? "http://localhost:5173"
|
|
225
|
-
: "http://localhost:3000"
|
|
226
|
-
: undefined;
|
|
227
|
-
const description =
|
|
228
|
-
config.deployment.type === "dev"
|
|
229
|
-
? "the URL of your local web server (e.g. http://localhost:1234)"
|
|
230
|
-
: "the URL where your site is hosted (e.g. https://example.com)";
|
|
231
|
-
|
|
232
|
-
await configureEnvVar(config, {
|
|
233
|
-
name: "SITE_URL",
|
|
234
|
-
default: value,
|
|
235
|
-
description,
|
|
236
|
-
validate: (input) => {
|
|
237
|
-
try {
|
|
238
|
-
new URL(input);
|
|
239
|
-
return true;
|
|
240
|
-
} catch {
|
|
241
|
-
return "The URL must start with http:// or https://";
|
|
242
|
-
}
|
|
243
|
-
},
|
|
244
|
-
forcedValue,
|
|
245
|
-
});
|
|
246
|
-
|
|
247
|
-
await configureEnvVar(config, {
|
|
248
|
-
name: "SECONDARY_URL",
|
|
249
|
-
description:
|
|
250
|
-
"additional frontend URLs as a comma-separated list (optional)",
|
|
251
|
-
validate: (input) => {
|
|
252
|
-
if (input.trim() === "") {
|
|
253
|
-
return true;
|
|
254
|
-
}
|
|
255
|
-
for (const candidate of input.split(",").map((url) => url.trim())) {
|
|
256
|
-
if (candidate === "") {
|
|
257
|
-
continue;
|
|
258
|
-
}
|
|
259
|
-
try {
|
|
260
|
-
new URL(candidate);
|
|
261
|
-
} catch {
|
|
262
|
-
return "Each URL must start with http:// or https://";
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
return true;
|
|
266
|
-
},
|
|
267
|
-
forcedValue: forcedSecondaryValue,
|
|
268
|
-
});
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
// ---------------------------------------------------------------------------
|
|
272
|
-
// Generic env var configuration
|
|
273
|
-
// ---------------------------------------------------------------------------
|
|
274
|
-
|
|
275
|
-
async function configureEnvVar(
|
|
276
|
-
config: ProjectConfig,
|
|
277
|
-
variable: {
|
|
278
|
-
name: string;
|
|
279
|
-
default?: string;
|
|
280
|
-
description: string;
|
|
281
|
-
validate?: (input: string) => true | string;
|
|
282
|
-
forcedValue?: string;
|
|
283
|
-
},
|
|
284
|
-
) {
|
|
285
|
-
if (
|
|
286
|
-
variable.forcedValue &&
|
|
287
|
-
(variable.validate ? variable.validate(variable.forcedValue) : true)
|
|
288
|
-
) {
|
|
289
|
-
if (variable.forcedValue.trim() === "") {
|
|
290
|
-
return;
|
|
291
|
-
}
|
|
292
|
-
await setEnvVar(config, variable.name, variable.forcedValue);
|
|
293
|
-
return;
|
|
294
|
-
}
|
|
295
|
-
const existing = backendEnvVar(config, variable.name);
|
|
296
|
-
if (existing !== "") {
|
|
297
|
-
const shouldChange = await promptForConfirmation(
|
|
298
|
-
`The ${printDeployment(config)} already has ${variable.name} configured to "${existing}". Do you want to change it?`,
|
|
299
|
-
{ default: false },
|
|
300
|
-
);
|
|
301
|
-
if (!shouldChange) {
|
|
302
|
-
return;
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
|
-
const chosenValue = await promptForInput(`Enter ${variable.description}`, {
|
|
306
|
-
default: variable.default,
|
|
307
|
-
validate: variable.validate,
|
|
308
|
-
});
|
|
309
|
-
if (chosenValue.trim() === "") {
|
|
310
|
-
return;
|
|
311
|
-
}
|
|
312
|
-
await setEnvVar(config, variable.name, chosenValue);
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
// ---------------------------------------------------------------------------
|
|
316
|
-
// Step 2: Keys
|
|
317
|
-
// ---------------------------------------------------------------------------
|
|
318
|
-
|
|
319
|
-
async function configureKeys(config: ProjectConfig) {
|
|
320
|
-
logStep(config, "Configure signing and encryption keys");
|
|
321
|
-
const { JWT_PRIVATE_KEY, JWKS, AUTH_SECRET_ENCRYPTION_KEY } =
|
|
322
|
-
await generateKeys();
|
|
323
|
-
const existingPrivateKey = backendEnvVar(config, "JWT_PRIVATE_KEY");
|
|
324
|
-
const existingJwks = backendEnvVar(config, "JWKS");
|
|
325
|
-
const existingSecretEncryptionKey = backendEnvVar(
|
|
326
|
-
config,
|
|
327
|
-
"AUTH_SECRET_ENCRYPTION_KEY",
|
|
328
|
-
);
|
|
329
|
-
if (
|
|
330
|
-
existingPrivateKey !== "" ||
|
|
331
|
-
existingJwks !== "" ||
|
|
332
|
-
existingSecretEncryptionKey !== ""
|
|
333
|
-
) {
|
|
334
|
-
const shouldOverwrite = await promptForConfirmation(
|
|
335
|
-
`The ${printDeployment(config)} already has JWT_PRIVATE_KEY, JWKS, or AUTH_SECRET_ENCRYPTION_KEY configured. Overwrite them?`,
|
|
336
|
-
{ default: false },
|
|
337
|
-
);
|
|
338
|
-
if (!shouldOverwrite) {
|
|
339
|
-
return;
|
|
340
|
-
}
|
|
341
|
-
}
|
|
342
|
-
// Use --from-file to avoid shell quoting issues with multiline values
|
|
343
|
-
await setEnvVarFromFile(config, "JWT_PRIVATE_KEY", JWT_PRIVATE_KEY);
|
|
344
|
-
await setEnvVarFromFile(config, "JWKS", JWKS);
|
|
345
|
-
await setEnvVar(
|
|
346
|
-
config,
|
|
347
|
-
"AUTH_SECRET_ENCRYPTION_KEY",
|
|
348
|
-
AUTH_SECRET_ENCRYPTION_KEY,
|
|
349
|
-
{
|
|
350
|
-
hideValue: true,
|
|
351
|
-
},
|
|
352
|
-
);
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
// ---------------------------------------------------------------------------
|
|
356
|
-
// Convex env helpers (no shell injection — argument arrays only)
|
|
357
|
-
// ---------------------------------------------------------------------------
|
|
358
|
-
|
|
359
|
-
function backendEnvVar(config: ProjectConfig, name: string): string {
|
|
360
|
-
const { file, args } = convexCmd(
|
|
361
|
-
"env",
|
|
362
|
-
"get",
|
|
363
|
-
...deploymentArgs(config),
|
|
364
|
-
name,
|
|
365
|
-
);
|
|
366
|
-
return execFileSync(file, args, {
|
|
367
|
-
stdio: "pipe",
|
|
368
|
-
encoding: "utf-8",
|
|
369
|
-
}).slice(0, -1);
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
async function setEnvVar(
|
|
373
|
-
config: ProjectConfig,
|
|
374
|
-
name: string,
|
|
375
|
-
value: string,
|
|
376
|
-
options?: { hideValue: boolean },
|
|
377
|
-
) {
|
|
378
|
-
const { file, args } = convexCmd(
|
|
379
|
-
"env",
|
|
380
|
-
"set",
|
|
381
|
-
...deploymentArgs(config),
|
|
382
|
-
"--",
|
|
383
|
-
name,
|
|
384
|
-
value,
|
|
385
|
-
);
|
|
386
|
-
execFileSync(file, args, {
|
|
387
|
-
stdio: options?.hideValue ? "ignore" : "inherit",
|
|
388
|
-
});
|
|
389
|
-
if (options?.hideValue) {
|
|
390
|
-
p.log.success(`Successfully set ${name} (on ${printDeployment(config)})`);
|
|
391
|
-
}
|
|
392
|
-
}
|
|
393
|
-
|
|
394
|
-
/**
|
|
395
|
-
* Write value to a temp file and use `convex env set KEY --from-file tmpfile`.
|
|
396
|
-
* This avoids shell-quoting issues with multiline values like private keys.
|
|
397
|
-
*/
|
|
398
|
-
async function setEnvVarFromFile(
|
|
399
|
-
config: ProjectConfig,
|
|
400
|
-
name: string,
|
|
401
|
-
value: string,
|
|
402
|
-
) {
|
|
403
|
-
const tmpDir = mkdtempSync(path.join(tmpdir(), "convex-auth-"));
|
|
404
|
-
const tmpFile = path.join(tmpDir, `${name}.tmp`);
|
|
405
|
-
try {
|
|
406
|
-
writeFileSync(tmpFile, value, "utf-8");
|
|
407
|
-
const { file, args } = convexCmd(
|
|
408
|
-
"env",
|
|
409
|
-
"set",
|
|
410
|
-
...deploymentArgs(config),
|
|
411
|
-
name,
|
|
412
|
-
"--from-file",
|
|
413
|
-
tmpFile,
|
|
414
|
-
);
|
|
415
|
-
execFileSync(file, args, { stdio: "ignore" });
|
|
416
|
-
p.log.success(`Successfully set ${name} (on ${printDeployment(config)})`);
|
|
417
|
-
} finally {
|
|
418
|
-
try {
|
|
419
|
-
unlinkSync(tmpFile);
|
|
420
|
-
} catch {
|
|
421
|
-
// cleanup is best-effort
|
|
422
|
-
}
|
|
423
|
-
}
|
|
424
|
-
}
|
|
425
|
-
|
|
426
|
-
function deploymentArgs(config: ProjectConfig): string[] {
|
|
427
|
-
const {
|
|
428
|
-
deployment: {
|
|
429
|
-
options: { adminKey, url, prod, previewName, deploymentName },
|
|
430
|
-
},
|
|
431
|
-
} = config;
|
|
432
|
-
const args: string[] = [];
|
|
433
|
-
|
|
434
|
-
if (adminKey !== undefined) {
|
|
435
|
-
args.push("--admin-key", adminKey);
|
|
436
|
-
}
|
|
437
|
-
|
|
438
|
-
const selectionArgs =
|
|
439
|
-
[
|
|
440
|
-
url ? ["--url", url] : null,
|
|
441
|
-
prod ? ["--prod"] : null,
|
|
442
|
-
previewName ? ["--preview-name", previewName] : null,
|
|
443
|
-
deploymentName ? ["--deployment-name", deploymentName] : null,
|
|
444
|
-
].find((s): s is string[] => s !== null) ?? [];
|
|
445
|
-
|
|
446
|
-
args.push(...selectionArgs);
|
|
447
|
-
return args;
|
|
448
|
-
}
|
|
449
|
-
|
|
450
|
-
function printDeployment(config: ProjectConfig): string {
|
|
451
|
-
const { name, type } = config.deployment;
|
|
452
|
-
return (
|
|
453
|
-
(type !== null ? `${type} ` : "") +
|
|
454
|
-
"deployment" +
|
|
455
|
-
(name !== null ? ` ${name}` : "")
|
|
456
|
-
);
|
|
457
|
-
}
|
|
458
|
-
|
|
459
|
-
// ---------------------------------------------------------------------------
|
|
460
|
-
// Step 3: tsconfig
|
|
461
|
-
// ---------------------------------------------------------------------------
|
|
462
|
-
|
|
463
|
-
// Match `"compilerOptions": {"`
|
|
464
|
-
// ignore comments after the bracket
|
|
465
|
-
// and capture the space between the bracket/last comment
|
|
466
|
-
// and the quote.
|
|
467
|
-
const compilerOptionsPattern =
|
|
468
|
-
/("compilerOptions"\s*:\s*\{(?:\s*(?:\/\*(?:[^*]|\*(?!\/))*\*\/))*(\s*))(?=")/;
|
|
469
|
-
|
|
470
|
-
const validTsConfig = `\
|
|
471
|
-
{
|
|
472
|
-
/* This TypeScript project config describes the environment that
|
|
473
|
-
* Convex functions run in and is used to typecheck them.
|
|
474
|
-
* You can modify it, but some settings required to use Convex.
|
|
475
|
-
*/
|
|
476
|
-
"compilerOptions": {
|
|
477
|
-
/* These settings are not required by Convex and can be modified. */
|
|
478
|
-
"allowJs": true,
|
|
479
|
-
"strict": true,
|
|
480
|
-
"skipLibCheck": true,
|
|
481
|
-
"jsx": "react",
|
|
482
|
-
|
|
483
|
-
/* These compiler options are required by Convex */
|
|
484
|
-
"target": "ESNext",
|
|
485
|
-
"lib": ["ES2021", "dom", "ES2023.Array"],
|
|
486
|
-
"forceConsistentCasingInFileNames": true,
|
|
487
|
-
"allowSyntheticDefaultImports": true,
|
|
488
|
-
"module": "ESNext",
|
|
489
|
-
"moduleResolution": "Bundler",
|
|
490
|
-
"isolatedModules": true,
|
|
491
|
-
"noEmit": true
|
|
492
|
-
},
|
|
493
|
-
"include": ["./**/*"],
|
|
494
|
-
"exclude": ["./_generated"]
|
|
495
|
-
}
|
|
496
|
-
`;
|
|
497
|
-
|
|
498
|
-
async function modifyTsConfig(config: ProjectConfig) {
|
|
499
|
-
logStep(config, "Modify tsconfig file");
|
|
500
|
-
const projectLevelTsConfigPath = "tsconfig.json";
|
|
501
|
-
const tsConfigPath = path.join(config.convexFolderPath, "tsconfig.json");
|
|
502
|
-
if (!existsSync(tsConfigPath)) {
|
|
503
|
-
if (existsSync(projectLevelTsConfigPath)) {
|
|
504
|
-
if (config.isExpo) {
|
|
505
|
-
writeFileSync(tsConfigPath, validTsConfig);
|
|
506
|
-
p.log.success(`Added ${tsConfigPath}`);
|
|
507
|
-
return;
|
|
508
|
-
}
|
|
509
|
-
// else assume that the project-level tsconfig already
|
|
510
|
-
// has the right settings, which is true for Vite and Next.js
|
|
511
|
-
}
|
|
512
|
-
p.log.info(`No ${tsConfigPath} found. Skipping.`);
|
|
513
|
-
return;
|
|
514
|
-
}
|
|
515
|
-
const existingTsConfig = readFileSync(tsConfigPath, "utf8");
|
|
516
|
-
const moduleResolutionPattern = /"moduleResolution"\s*:\s*"(\w+)"/;
|
|
517
|
-
const [, existingModuleResolution] =
|
|
518
|
-
existingTsConfig.match(moduleResolutionPattern) ?? [];
|
|
519
|
-
const skipLibCheckPattern = /"skipLibCheck"\s*:\s*(\w+)/;
|
|
520
|
-
const [, existingSkipLibCheck] =
|
|
521
|
-
existingTsConfig.match(skipLibCheckPattern) ?? [];
|
|
522
|
-
if (
|
|
523
|
-
/Bundler/i.test(existingModuleResolution) &&
|
|
524
|
-
existingSkipLibCheck === "true"
|
|
525
|
-
) {
|
|
526
|
-
p.log.success(`The ${tsConfigPath} is already set up.`);
|
|
527
|
-
return;
|
|
528
|
-
}
|
|
529
|
-
|
|
530
|
-
if (!compilerOptionsPattern.test(existingTsConfig)) {
|
|
531
|
-
p.log.info(`Modify your ${tsConfigPath} to include the following:`);
|
|
532
|
-
const source = `\
|
|
533
|
-
{
|
|
534
|
-
"compilerOptions": {
|
|
535
|
-
"moduleResolution": "Bundler",
|
|
536
|
-
"skipLibCheck": true
|
|
537
|
-
}
|
|
538
|
-
}
|
|
539
|
-
`;
|
|
540
|
-
p.log.message(indent(`\n${source}\n`));
|
|
541
|
-
await promptForConfirmationOrExit("Ready to continue?");
|
|
542
|
-
}
|
|
543
|
-
const changedTsConfig = addCompilerOption(
|
|
544
|
-
addCompilerOption(
|
|
545
|
-
existingTsConfig,
|
|
546
|
-
existingModuleResolution,
|
|
547
|
-
moduleResolutionPattern,
|
|
548
|
-
'"moduleResolution": "Bundler"',
|
|
549
|
-
),
|
|
550
|
-
existingSkipLibCheck,
|
|
551
|
-
skipLibCheckPattern,
|
|
552
|
-
'"skipLibCheck": true',
|
|
553
|
-
);
|
|
554
|
-
writeFileSync(tsConfigPath, changedTsConfig);
|
|
555
|
-
p.log.success(`Modified ${tsConfigPath}`);
|
|
556
|
-
}
|
|
557
|
-
|
|
558
|
-
function addCompilerOption(
|
|
559
|
-
tsconfig: string,
|
|
560
|
-
existingValue: string | undefined,
|
|
561
|
-
pattern: RegExp,
|
|
562
|
-
optionAndValue: string,
|
|
563
|
-
) {
|
|
564
|
-
if (existingValue === undefined) {
|
|
565
|
-
return tsconfig.replace(compilerOptionsPattern, `$1${optionAndValue},$2`);
|
|
566
|
-
} else {
|
|
567
|
-
return tsconfig.replace(pattern, optionAndValue);
|
|
568
|
-
}
|
|
569
|
-
}
|
|
570
|
-
|
|
571
|
-
// ---------------------------------------------------------------------------
|
|
572
|
-
// Step 4: convex.config
|
|
573
|
-
// ---------------------------------------------------------------------------
|
|
574
|
-
|
|
575
|
-
async function configureConvexConfig(config: ProjectConfig) {
|
|
576
|
-
logStep(config, "Configure convex config file");
|
|
577
|
-
const sourceTemplate = `\
|
|
578
|
-
import { defineApp } from "convex/server";
|
|
579
|
-
import auth from "@robelest/convex-auth/convex.config";
|
|
580
|
-
|
|
581
|
-
const app = defineApp();
|
|
582
|
-
|
|
583
|
-
app.use(auth);
|
|
584
|
-
|
|
585
|
-
export default app;
|
|
586
|
-
`;
|
|
587
|
-
const source = templateToSource(sourceTemplate);
|
|
588
|
-
const convexConfigPath = path.join(config.convexFolderPath, "convex.config");
|
|
589
|
-
const existingConfigPath = existingNonEmptySourcePath(convexConfigPath);
|
|
590
|
-
if (existingConfigPath !== null) {
|
|
591
|
-
const existingConfig = readFileSync(existingConfigPath, "utf8");
|
|
592
|
-
if (doesAlreadyMatchTemplate(existingConfig, sourceTemplate)) {
|
|
593
|
-
p.log.success(`The ${existingConfigPath} is already set up.`);
|
|
594
|
-
} else {
|
|
595
|
-
p.log.info(
|
|
596
|
-
`You already have a ${existingConfigPath}, make sure it registers the auth component like this:`,
|
|
597
|
-
);
|
|
598
|
-
p.log.message(indent(`\n${source}\n`));
|
|
599
|
-
await promptForConfirmationOrExit("Ready to continue?");
|
|
600
|
-
}
|
|
601
|
-
} else {
|
|
602
|
-
const newConfigPath = config.usesTypeScript
|
|
603
|
-
? `${convexConfigPath}.ts`
|
|
604
|
-
: `${convexConfigPath}.js`;
|
|
605
|
-
writeFileSync(newConfigPath, source);
|
|
606
|
-
p.log.success(`Created ${newConfigPath}`);
|
|
607
|
-
}
|
|
608
|
-
}
|
|
609
|
-
|
|
610
|
-
// ---------------------------------------------------------------------------
|
|
611
|
-
// Step 5: auth.ts
|
|
612
|
-
// ---------------------------------------------------------------------------
|
|
613
|
-
|
|
614
|
-
async function initializeAuth(config: ProjectConfig) {
|
|
615
|
-
logStep(config, "Initialize auth file");
|
|
616
|
-
const sourceTemplate = `\
|
|
617
|
-
import { createAuth } from "@robelest/convex-auth/component";
|
|
618
|
-
import { components } from "./_generated/api";
|
|
619
|
-
|
|
620
|
-
const auth = createAuth(components.auth, {$$
|
|
621
|
-
providers: [$$],$$
|
|
622
|
-
});
|
|
623
|
-
|
|
624
|
-
export { auth };
|
|
625
|
-
export const { signIn, signOut, store } = auth;
|
|
626
|
-
`;
|
|
627
|
-
const source = templateToSource(sourceTemplate);
|
|
628
|
-
const authPath = path.join(config.convexFolderPath, "auth");
|
|
629
|
-
const existingAuthPath = existingNonEmptySourcePath(authPath);
|
|
630
|
-
if (existingAuthPath !== null) {
|
|
631
|
-
const existingAuth = readFileSync(existingAuthPath, "utf8");
|
|
632
|
-
if (doesAlreadyMatchTemplate(existingAuth, sourceTemplate)) {
|
|
633
|
-
p.log.success(`The ${existingAuthPath} is already set up.`);
|
|
634
|
-
} else {
|
|
635
|
-
p.log.info(
|
|
636
|
-
`You already have a ${existingAuthPath}, make sure it initializes auth with \`createAuth\` like this:`,
|
|
637
|
-
);
|
|
638
|
-
p.log.message(indent(`\n${source}\n`));
|
|
639
|
-
await promptForConfirmationOrExit("Ready to continue?");
|
|
640
|
-
}
|
|
641
|
-
} else {
|
|
642
|
-
const newAuthPath = config.usesTypeScript
|
|
643
|
-
? `${authPath}.ts`
|
|
644
|
-
: `${authPath}.js`;
|
|
645
|
-
writeFileSync(newAuthPath, source);
|
|
646
|
-
p.log.success(`Created ${newAuthPath}`);
|
|
647
|
-
}
|
|
648
|
-
}
|
|
649
|
-
|
|
650
|
-
// ---------------------------------------------------------------------------
|
|
651
|
-
// Step 6: http.ts
|
|
652
|
-
// ---------------------------------------------------------------------------
|
|
653
|
-
|
|
654
|
-
async function configureHttp(config: ProjectConfig) {
|
|
655
|
-
logStep(config, "Configure http file");
|
|
656
|
-
const sourceTemplate = `\
|
|
657
|
-
import { httpRouter } from "convex/server";
|
|
658
|
-
import { auth } from "./auth";
|
|
659
|
-
|
|
660
|
-
const http = httpRouter();
|
|
661
|
-
|
|
662
|
-
auth.http.add(http);
|
|
663
|
-
|
|
664
|
-
export default http;
|
|
665
|
-
`;
|
|
666
|
-
const source = templateToSource(sourceTemplate);
|
|
667
|
-
const httpPath = path.join(config.convexFolderPath, "http");
|
|
668
|
-
const existingHttpPath = existingNonEmptySourcePath(httpPath);
|
|
669
|
-
if (existingHttpPath !== null) {
|
|
670
|
-
const existingHttp = readFileSync(existingHttpPath, "utf8");
|
|
671
|
-
if (doesAlreadyMatchTemplate(existingHttp, sourceTemplate)) {
|
|
672
|
-
p.log.success(`The ${existingHttpPath} is already set up.`);
|
|
673
|
-
} else {
|
|
674
|
-
p.log.info(
|
|
675
|
-
`You already have a ${existingHttpPath}, make sure it includes the call to \`auth.http.add\`:`,
|
|
676
|
-
);
|
|
677
|
-
p.log.message(indent(`\n${source}\n`));
|
|
678
|
-
await promptForConfirmationOrExit("Ready to continue?");
|
|
679
|
-
}
|
|
680
|
-
} else {
|
|
681
|
-
const newHttpPath = config.usesTypeScript
|
|
682
|
-
? `${httpPath}.ts`
|
|
683
|
-
: `${httpPath}.js`;
|
|
684
|
-
writeFileSync(newHttpPath, source);
|
|
685
|
-
p.log.success(`Created ${newHttpPath}`);
|
|
686
|
-
}
|
|
687
|
-
}
|
|
688
|
-
|
|
689
|
-
// ---------------------------------------------------------------------------
|
|
690
|
-
// Extra: --variables
|
|
691
|
-
// ---------------------------------------------------------------------------
|
|
692
|
-
|
|
693
|
-
const VariablesSchema = v.object({
|
|
694
|
-
help: v.optional(v.string()),
|
|
695
|
-
providers: v.array(
|
|
696
|
-
v.object({
|
|
697
|
-
name: v.string(),
|
|
698
|
-
help: v.optional(v.string()),
|
|
699
|
-
variables: v.array(
|
|
700
|
-
v.object({
|
|
701
|
-
name: v.string(),
|
|
702
|
-
description: v.string(),
|
|
703
|
-
}),
|
|
704
|
-
),
|
|
705
|
-
}),
|
|
706
|
-
),
|
|
707
|
-
success: v.optional(v.string()),
|
|
708
|
-
});
|
|
709
|
-
|
|
710
|
-
async function configureOtherVariables(config: ProjectConfig, json: string) {
|
|
711
|
-
let parsed: unknown;
|
|
712
|
-
try {
|
|
713
|
-
parsed = JSON.parse(json);
|
|
714
|
-
} catch (err) {
|
|
715
|
-
logErrorAndExit(
|
|
716
|
-
"The --variables flag must be valid JSON.",
|
|
717
|
-
err instanceof Error ? err.message : String(err),
|
|
718
|
-
);
|
|
719
|
-
}
|
|
720
|
-
|
|
721
|
-
const variables = v.parse(VariablesSchema, parsed);
|
|
722
|
-
logStep(config, "Configure extra environment variables");
|
|
723
|
-
if (variables.help !== undefined) {
|
|
724
|
-
p.log.message(variables.help);
|
|
725
|
-
}
|
|
726
|
-
for (const provider of variables.providers) {
|
|
727
|
-
const shouldConfigure = await promptForConfirmation(
|
|
728
|
-
`Do you want to configure ${provider.name}?`,
|
|
729
|
-
);
|
|
730
|
-
if (!shouldConfigure) {
|
|
731
|
-
continue;
|
|
732
|
-
}
|
|
733
|
-
if (provider.help !== undefined) {
|
|
734
|
-
p.log.message(provider.help);
|
|
735
|
-
}
|
|
736
|
-
for (const variable of provider.variables) {
|
|
737
|
-
await configureEnvVar(config, {
|
|
738
|
-
name: variable.name,
|
|
739
|
-
description: variable.description,
|
|
740
|
-
});
|
|
741
|
-
}
|
|
742
|
-
}
|
|
743
|
-
if (variables.success !== undefined) {
|
|
744
|
-
p.log.success(variables.success);
|
|
745
|
-
}
|
|
746
|
-
}
|
|
747
|
-
|
|
748
|
-
// ---------------------------------------------------------------------------
|
|
749
|
-
// Template helpers
|
|
750
|
-
// ---------------------------------------------------------------------------
|
|
751
|
-
|
|
752
|
-
export function doesAlreadyMatchTemplate(existing: string, template: string) {
|
|
753
|
-
const regex = new RegExp(
|
|
754
|
-
template
|
|
755
|
-
.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")
|
|
756
|
-
.replace(/\\\$\\\$/g, ".*")
|
|
757
|
-
.replace(/;\n/g, ";.*"),
|
|
758
|
-
"s",
|
|
759
|
-
);
|
|
760
|
-
return regex.test(existing);
|
|
761
|
-
}
|
|
762
|
-
|
|
763
|
-
export function templateToSource(template: string) {
|
|
764
|
-
return template.replace(/\$\$/g, "");
|
|
765
|
-
}
|
|
766
|
-
|
|
767
|
-
function existingNonEmptySourcePath(filePath: string): string | null {
|
|
768
|
-
return existsAndNotEmpty(`${filePath}.ts`)
|
|
769
|
-
? `${filePath}.ts`
|
|
770
|
-
: existsAndNotEmpty(`${filePath}.js`)
|
|
771
|
-
? `${filePath}.js`
|
|
772
|
-
: null;
|
|
773
|
-
}
|
|
774
|
-
|
|
775
|
-
function existsAndNotEmpty(filePath: string): boolean {
|
|
776
|
-
return existsSync(filePath) && readFileSync(filePath, "utf8").trim() !== "";
|
|
777
|
-
}
|
|
778
|
-
|
|
779
|
-
// ---------------------------------------------------------------------------
|
|
780
|
-
// Logging
|
|
781
|
-
// ---------------------------------------------------------------------------
|
|
782
|
-
|
|
783
|
-
function logStep(config: ProjectConfig, message: string) {
|
|
784
|
-
p.log.step(`Step ${config.step++}: ${message}`);
|
|
785
|
-
}
|
|
786
|
-
|
|
787
|
-
// ---------------------------------------------------------------------------
|
|
788
|
-
// Source control check
|
|
789
|
-
// ---------------------------------------------------------------------------
|
|
790
|
-
|
|
791
|
-
async function checkSourceControl(options: {
|
|
792
|
-
skipGitCheck?: boolean;
|
|
793
|
-
allowDirtyGitState?: boolean;
|
|
794
|
-
}) {
|
|
795
|
-
if (options.allowDirtyGitState) {
|
|
796
|
-
return;
|
|
797
|
-
}
|
|
798
|
-
const isGit = existsSync(".git");
|
|
799
|
-
if (isGit) {
|
|
800
|
-
let gitStatus: string;
|
|
801
|
-
try {
|
|
802
|
-
gitStatus = execFileSync("git", ["status", "--porcelain"], {
|
|
803
|
-
encoding: "utf-8",
|
|
804
|
-
});
|
|
805
|
-
} catch {
|
|
806
|
-
// git not available — skip check
|
|
807
|
-
return;
|
|
808
|
-
}
|
|
809
|
-
const changedFiles = gitStatus
|
|
810
|
-
.split("\n")
|
|
811
|
-
.filter(
|
|
812
|
-
(line) =>
|
|
813
|
-
!/\bpackage(-lock)?.json/.test(line) &&
|
|
814
|
-
!/\benv\.d\.ts$/.test(line) &&
|
|
815
|
-
line.length > 0,
|
|
816
|
-
);
|
|
817
|
-
if (changedFiles.length > 0) {
|
|
818
|
-
p.log.error(
|
|
819
|
-
"There are unstaged or uncommitted changes in the working directory. " +
|
|
820
|
-
"Please commit or stash them before proceeding.",
|
|
821
|
-
);
|
|
822
|
-
await promptForConfirmationOrExit("Continue anyway?", { default: false });
|
|
823
|
-
}
|
|
824
|
-
} else {
|
|
825
|
-
if (options.skipGitCheck) {
|
|
826
|
-
return;
|
|
827
|
-
}
|
|
828
|
-
p.log.warn(
|
|
829
|
-
"No source control detected. We strongly recommend committing the current state of your code before proceeding.",
|
|
830
|
-
);
|
|
831
|
-
await promptForConfirmationOrExit("Continue anyway?");
|
|
832
|
-
}
|
|
833
|
-
}
|
|
834
|
-
|
|
835
|
-
// ---------------------------------------------------------------------------
|
|
836
|
-
// Project file readers
|
|
837
|
-
// ---------------------------------------------------------------------------
|
|
838
|
-
|
|
839
|
-
type PackageJSON = { __isPackageJSON: true; [key: string]: any };
|
|
840
|
-
|
|
841
|
-
function readPackageJson(): PackageJSON {
|
|
842
|
-
try {
|
|
843
|
-
const data = readFileSync("package.json", "utf8");
|
|
844
|
-
return JSON.parse(data);
|
|
845
|
-
} catch (error: any) {
|
|
846
|
-
logErrorAndExit(
|
|
847
|
-
"`@robelest/convex-auth` must be run from a project directory which " +
|
|
848
|
-
'includes a valid "package.json" file. You can create one by running ' +
|
|
849
|
-
"`npm init`.",
|
|
850
|
-
error.message,
|
|
851
|
-
);
|
|
852
|
-
}
|
|
853
|
-
}
|
|
854
|
-
|
|
855
|
-
type ConvexJSON = { __isConvexJSON: true; [key: string]: any };
|
|
856
|
-
|
|
857
|
-
function readConvexJson(): ConvexJSON {
|
|
858
|
-
if (!existsSync("convex.json")) {
|
|
859
|
-
return {} as ConvexJSON;
|
|
860
|
-
}
|
|
861
|
-
try {
|
|
862
|
-
const data = readFileSync("convex.json", "utf8");
|
|
863
|
-
return JSON.parse(data);
|
|
864
|
-
} catch (error: any) {
|
|
865
|
-
logErrorAndExit(
|
|
866
|
-
"Could not parse your convex.json. Is it valid JSON?",
|
|
867
|
-
error.message,
|
|
868
|
-
);
|
|
869
|
-
}
|
|
870
|
-
}
|
|
871
|
-
|
|
872
|
-
// ---------------------------------------------------------------------------
|
|
873
|
-
// Deployment selection
|
|
874
|
-
// ---------------------------------------------------------------------------
|
|
875
|
-
|
|
876
|
-
export function readConvexDeployment(options: {
|
|
877
|
-
url?: string;
|
|
878
|
-
adminKey?: string;
|
|
879
|
-
prod?: boolean;
|
|
880
|
-
previewName?: string;
|
|
881
|
-
deploymentName?: string;
|
|
882
|
-
}) {
|
|
883
|
-
const { adminKey, url, prod, previewName, deploymentName } = options;
|
|
884
|
-
|
|
885
|
-
if (url) {
|
|
886
|
-
return {
|
|
887
|
-
name: url,
|
|
888
|
-
type: null,
|
|
889
|
-
options,
|
|
890
|
-
};
|
|
891
|
-
}
|
|
892
|
-
|
|
893
|
-
const adminKeyName = adminKey ? deploymentNameFromAdminKey(adminKey) : null;
|
|
894
|
-
const adminKeyType = adminKey ? deploymentTypeFromAdminKey(adminKey) : null;
|
|
895
|
-
|
|
896
|
-
const explicitSelection = [
|
|
897
|
-
prod ? { name: adminKeyName, type: "prod" as const } : null,
|
|
898
|
-
previewName ? { name: previewName, type: "preview" as const } : null,
|
|
899
|
-
deploymentName ? { name: deploymentName, type: adminKeyType } : null,
|
|
900
|
-
adminKey ? { name: adminKeyName, type: adminKeyType } : null,
|
|
901
|
-
].find(
|
|
902
|
-
(
|
|
903
|
-
selection,
|
|
904
|
-
): selection is {
|
|
905
|
-
name: string | null;
|
|
906
|
-
type: string | null;
|
|
907
|
-
} => selection !== null,
|
|
908
|
-
);
|
|
909
|
-
|
|
910
|
-
if (explicitSelection !== undefined) {
|
|
911
|
-
return { ...explicitSelection, options };
|
|
912
|
-
}
|
|
913
|
-
|
|
914
|
-
loadEnvFile({ path: ".env.local" });
|
|
915
|
-
loadEnvFile();
|
|
916
|
-
if (process.env.CONVEX_DEPLOYMENT) {
|
|
917
|
-
const type = getDeploymentTypeFromConfiguredDeployment(
|
|
918
|
-
process.env.CONVEX_DEPLOYMENT,
|
|
919
|
-
);
|
|
920
|
-
return {
|
|
921
|
-
name: stripDeploymentTypePrefix(process.env.CONVEX_DEPLOYMENT),
|
|
922
|
-
type,
|
|
923
|
-
options,
|
|
924
|
-
};
|
|
925
|
-
}
|
|
926
|
-
|
|
927
|
-
logErrorAndExit(
|
|
928
|
-
"Could not find a configured CONVEX_DEPLOYMENT. Did you forget to run `npx convex dev` first?",
|
|
929
|
-
);
|
|
930
|
-
}
|
|
931
|
-
|
|
932
|
-
// NOTE: CONVEX CLI DEP
|
|
933
|
-
// Given a deployment string like "dev:tall-forest-1234"
|
|
934
|
-
// returns only the slug "tall-forest-1234".
|
|
935
|
-
export function stripDeploymentTypePrefix(deployment: string) {
|
|
936
|
-
const [type, name] = deployment.split(":");
|
|
937
|
-
if ((type !== "prod" && type !== "dev" && type !== "preview") || !name) {
|
|
938
|
-
logErrorAndExit(
|
|
939
|
-
"Invalid CONVEX_DEPLOYMENT.",
|
|
940
|
-
'Expected a typed deployment like "dev:my-deployment", "prod:my-deployment", or "preview:my-deployment".',
|
|
941
|
-
);
|
|
942
|
-
}
|
|
943
|
-
return name;
|
|
944
|
-
}
|
|
945
|
-
|
|
946
|
-
// NOTE: CONVEX CLI DEP
|
|
947
|
-
function getDeploymentTypeFromConfiguredDeployment(raw: string) {
|
|
948
|
-
const typeRaw = raw.split(":")[0];
|
|
949
|
-
if (typeRaw === "prod" || typeRaw === "dev" || typeRaw === "preview") {
|
|
950
|
-
return typeRaw;
|
|
951
|
-
}
|
|
952
|
-
logErrorAndExit(
|
|
953
|
-
"Invalid CONVEX_DEPLOYMENT.",
|
|
954
|
-
'Expected a typed deployment like "dev:my-deployment", "prod:my-deployment", or "preview:my-deployment".',
|
|
955
|
-
);
|
|
956
|
-
}
|
|
957
|
-
|
|
958
|
-
// NOTE: CONVEX CLI DEP
|
|
959
|
-
function deploymentNameFromAdminKey(adminKey: string) {
|
|
960
|
-
const parts = adminKey.split("|");
|
|
961
|
-
const hasDeployment = parts.length > 1;
|
|
962
|
-
return hasDeployment && !isPreviewDeployKey(adminKey)
|
|
963
|
-
? stripDeploymentTypePrefix(parts[0])
|
|
964
|
-
: null;
|
|
965
|
-
}
|
|
966
|
-
|
|
967
|
-
// NOTE: CONVEX CLI DEP
|
|
968
|
-
// Examples:
|
|
969
|
-
// "prod:deploymentName|key" -> "prod"
|
|
970
|
-
// "preview:deploymentName|key" -> "preview"
|
|
971
|
-
// "dev:deploymentName|key" -> "dev"
|
|
972
|
-
export function deploymentTypeFromAdminKey(adminKey: string) {
|
|
973
|
-
const type = adminKey.split(":")[0];
|
|
974
|
-
if (type === "prod" || type === "dev" || type === "preview") {
|
|
975
|
-
return type;
|
|
976
|
-
}
|
|
977
|
-
logErrorAndExit(
|
|
978
|
-
"Invalid admin key.",
|
|
979
|
-
'Expected a typed key like "dev:deployment|...", "prod:deployment|...", or "preview:...".',
|
|
980
|
-
);
|
|
981
|
-
}
|
|
982
|
-
|
|
983
|
-
// NOTE: CONVEX CLI DEP
|
|
984
|
-
// Needed to differentiate a preview deploy key
|
|
985
|
-
// from a concrete preview deployment's deploy key.
|
|
986
|
-
// preview deploy key: `preview:team:project|key`
|
|
987
|
-
// preview deployment's deploy key: `preview:deploymentName|key`
|
|
988
|
-
export function isPreviewDeployKey(adminKey: string) {
|
|
989
|
-
const parts = adminKey.split("|");
|
|
990
|
-
if (parts.length === 1) {
|
|
991
|
-
return false;
|
|
992
|
-
}
|
|
993
|
-
const [prefix] = parts;
|
|
994
|
-
const prefixParts = prefix.split(":");
|
|
995
|
-
return prefixParts[0] === "preview" && prefixParts.length === 3;
|
|
996
|
-
}
|
|
997
|
-
|
|
998
|
-
// ---------------------------------------------------------------------------
|
|
999
|
-
// Prompts (using @clack/prompts, with TTY detection on stdin)
|
|
1000
|
-
// ---------------------------------------------------------------------------
|
|
1001
|
-
|
|
1002
|
-
async function promptForConfirmationOrExit(
|
|
1003
|
-
message: string,
|
|
1004
|
-
options: { default?: boolean } = {},
|
|
1005
|
-
) {
|
|
1006
|
-
if (!(await promptForConfirmation(message, options))) {
|
|
1007
|
-
p.cancel("Setup cancelled.");
|
|
1008
|
-
process.exit(1);
|
|
1009
|
-
}
|
|
1010
|
-
}
|
|
1011
|
-
|
|
1012
|
-
async function promptForConfirmation(
|
|
1013
|
-
message: string,
|
|
1014
|
-
options: { default?: boolean } = {},
|
|
1015
|
-
): Promise<boolean> {
|
|
1016
|
-
if (process.stdin.isTTY) {
|
|
1017
|
-
const result = await p.confirm({
|
|
1018
|
-
message,
|
|
1019
|
-
initialValue: options.default ?? true,
|
|
1020
|
-
});
|
|
1021
|
-
if (p.isCancel(result)) {
|
|
1022
|
-
p.cancel("Setup cancelled.");
|
|
1023
|
-
process.exit(1);
|
|
1024
|
-
}
|
|
1025
|
-
return result;
|
|
1026
|
-
} else {
|
|
1027
|
-
return options.default ?? true;
|
|
1028
|
-
}
|
|
1029
|
-
}
|
|
1030
|
-
|
|
1031
|
-
async function promptForInput(
|
|
1032
|
-
message: string,
|
|
1033
|
-
options: {
|
|
1034
|
-
default?: string;
|
|
1035
|
-
validate?: (input: string) => true | string;
|
|
1036
|
-
},
|
|
1037
|
-
): Promise<string> {
|
|
1038
|
-
if (process.stdin.isTTY) {
|
|
1039
|
-
const result = await p.text({
|
|
1040
|
-
message,
|
|
1041
|
-
defaultValue: options.default,
|
|
1042
|
-
placeholder: options.default,
|
|
1043
|
-
validate: options.validate
|
|
1044
|
-
? (val: string | undefined) => {
|
|
1045
|
-
if (val === undefined) return "Input is required";
|
|
1046
|
-
const check = options.validate!(val);
|
|
1047
|
-
if (check === true) return undefined;
|
|
1048
|
-
return check;
|
|
1049
|
-
}
|
|
1050
|
-
: undefined,
|
|
1051
|
-
});
|
|
1052
|
-
if (p.isCancel(result)) {
|
|
1053
|
-
p.cancel("Setup cancelled.");
|
|
1054
|
-
process.exit(1);
|
|
1055
|
-
}
|
|
1056
|
-
return result;
|
|
1057
|
-
} else {
|
|
1058
|
-
if (options.default !== undefined) {
|
|
1059
|
-
return options.default;
|
|
1060
|
-
} else {
|
|
1061
|
-
logErrorAndExit(
|
|
1062
|
-
"Run this command in an interactive terminal to provide input.",
|
|
1063
|
-
);
|
|
1064
|
-
}
|
|
1065
|
-
}
|
|
1066
|
-
}
|
|
1067
|
-
|
|
1068
|
-
// ---------------------------------------------------------------------------
|
|
1069
|
-
// Final success message
|
|
1070
|
-
// ---------------------------------------------------------------------------
|
|
1071
|
-
|
|
1072
|
-
function printFinalSuccessMessage(config: ProjectConfig) {
|
|
1073
|
-
const isProd = config.deployment.type === "prod";
|
|
1074
|
-
const deploymentName = config.deployment.name ?? "your deployment";
|
|
1075
|
-
|
|
1076
|
-
if (isProd) {
|
|
1077
|
-
p.log.success(`Production setup complete for ${deploymentName}.`);
|
|
1078
|
-
p.log.message(" Full docs: https://deepwiki.com/robelest/convex-auth");
|
|
1079
|
-
} else {
|
|
1080
|
-
p.log.success(`Setup complete for ${deploymentName}.`);
|
|
1081
|
-
p.log.message("");
|
|
1082
|
-
p.log.message(
|
|
1083
|
-
" To set up production, run this command with your production URL:",
|
|
1084
|
-
);
|
|
1085
|
-
p.log.message(
|
|
1086
|
-
' npx @robelest/convex-auth --prod --site-url "https://myapp.com"',
|
|
1087
|
-
);
|
|
1088
|
-
p.log.message("");
|
|
1089
|
-
p.log.message(" Don't forget to set provider secrets on production too:");
|
|
1090
|
-
p.log.message(' npx convex env set --prod AUTH_GITHUB_ID "..."');
|
|
1091
|
-
p.log.message(' npx convex env set --prod AUTH_GITHUB_SECRET "..."');
|
|
1092
|
-
p.log.message("");
|
|
1093
|
-
p.log.message(" Full docs: https://deepwiki.com/robelest/convex-auth");
|
|
1094
|
-
}
|
|
1095
|
-
}
|
|
1096
|
-
|
|
1097
|
-
// ---------------------------------------------------------------------------
|
|
1098
|
-
// Error helpers
|
|
1099
|
-
// ---------------------------------------------------------------------------
|
|
1100
|
-
|
|
1101
|
-
function logErrorAndExit(message: string, error?: string): never {
|
|
1102
|
-
p.log.error(`${message}${error !== undefined ? `\n Error: ${error}` : ""}`);
|
|
1103
|
-
process.exit(1);
|
|
1104
|
-
}
|
|
1105
|
-
|
|
1106
|
-
// ---------------------------------------------------------------------------
|
|
1107
|
-
// String helpers
|
|
1108
|
-
// ---------------------------------------------------------------------------
|
|
1109
|
-
|
|
1110
|
-
function indent(string: string) {
|
|
1111
|
-
return string.replace(/^/gm, " ").slice(2);
|
|
1112
|
-
}
|