convex 1.46.0 → 1.48.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +58 -1
- package/dist/browser.bundle.js +7 -1
- package/dist/browser.bundle.js.map +2 -2
- package/dist/cjs/bundler/context.js +7 -5
- package/dist/cjs/bundler/context.js.map +2 -2
- package/dist/cjs/bundler/fs.js +47 -6
- package/dist/cjs/bundler/fs.js.map +2 -2
- package/dist/cjs/bundler/index.js +5 -4
- package/dist/cjs/bundler/index.js.map +2 -2
- package/dist/cjs/cli/account.js +237 -0
- package/dist/cjs/cli/account.js.map +7 -0
- package/dist/cjs/cli/codegen.js +0 -4
- package/dist/cjs/cli/codegen.js.map +2 -2
- package/dist/cjs/cli/configure.js +28 -6
- package/dist/cjs/cli/configure.js.map +2 -2
- package/dist/cjs/cli/deploy.js +27 -2
- package/dist/cjs/cli/deploy.js.map +2 -2
- package/dist/cjs/cli/deploymentSelect.js +2 -2
- package/dist/cjs/cli/deploymentSelect.js.map +2 -2
- package/dist/cjs/cli/dev.js +6 -0
- package/dist/cjs/cli/dev.js.map +2 -2
- package/dist/cjs/cli/env.js +10 -5
- package/dist/cjs/cli/env.js.map +2 -2
- package/dist/cjs/cli/envDefault.js +7 -2
- package/dist/cjs/cli/envDefault.js.map +2 -2
- package/dist/cjs/cli/generatedApi.js.map +1 -1
- package/dist/cjs/cli/lib/api.js +2 -0
- package/dist/cjs/cli/lib/api.js.map +2 -2
- package/dist/cjs/cli/lib/checkForLargeIndexBackfill.js +113 -0
- package/dist/cjs/cli/lib/checkForLargeIndexBackfill.js.map +7 -0
- package/dist/cjs/cli/lib/checkForLargeIndexDeletion.js +36 -47
- package/dist/cjs/cli/lib/checkForLargeIndexDeletion.js.map +2 -2
- package/dist/cjs/cli/lib/checkForSlowSchemaValidation.js +58 -39
- package/dist/cjs/cli/lib/checkForSlowSchemaValidation.js.map +2 -2
- package/dist/cjs/cli/lib/checkForStagedValidatorDeletion.js +90 -0
- package/dist/cjs/cli/lib/checkForStagedValidatorDeletion.js.map +7 -0
- package/dist/cjs/cli/lib/codegen.js.map +2 -2
- package/dist/cjs/cli/lib/command.js +2 -1
- package/dist/cjs/cli/lib/command.js.map +2 -2
- package/dist/cjs/cli/lib/components/definition/bundle.js +37 -11
- package/dist/cjs/cli/lib/components/definition/bundle.js.map +2 -2
- package/dist/cjs/cli/lib/components.js +48 -5
- package/dist/cjs/cli/lib/components.js.map +2 -2
- package/dist/cjs/cli/lib/config.js +56 -17
- package/dist/cjs/cli/lib/config.js.map +2 -2
- package/dist/cjs/cli/lib/deploy2.js +3 -1
- package/dist/cjs/cli/lib/deploy2.js.map +2 -2
- package/dist/cjs/cli/lib/deployApi/evaluateSchema.js +30 -2
- package/dist/cjs/cli/lib/deployApi/evaluateSchema.js.map +2 -2
- package/dist/cjs/cli/lib/deployKeyWarning.js +43 -0
- package/dist/cjs/cli/lib/deployKeyWarning.js.map +7 -0
- package/dist/cjs/cli/lib/deployment.js +2 -0
- package/dist/cjs/cli/lib/deployment.js.map +2 -2
- package/dist/cjs/cli/lib/deploymentSelection.js +27 -18
- package/dist/cjs/cli/lib/deploymentSelection.js.map +2 -2
- package/dist/cjs/cli/lib/dev.js +5 -0
- package/dist/cjs/cli/lib/dev.js.map +2 -2
- package/dist/cjs/cli/lib/envvars.js +32 -0
- package/dist/cjs/cli/lib/envvars.js.map +2 -2
- package/dist/cjs/cli/lib/formatValidationProgress.js +47 -0
- package/dist/cjs/cli/lib/formatValidationProgress.js.map +7 -0
- package/dist/cjs/cli/lib/fsUtils.js +1 -1
- package/dist/cjs/cli/lib/fsUtils.js.map +2 -2
- package/dist/cjs/cli/lib/generateDocs.js +1 -1
- package/dist/cjs/cli/lib/generateDocs.js.map +1 -1
- package/dist/cjs/cli/lib/indexes.js.map +1 -1
- package/dist/cjs/cli/lib/login.js +28 -4
- package/dist/cjs/cli/lib/login.js.map +2 -2
- package/dist/cjs/cli/lib/mcp/requestContext.js +5 -1
- package/dist/cjs/cli/lib/mcp/requestContext.js.map +2 -2
- package/dist/cjs/cli/lib/mcp/tools/env.js +10 -3
- package/dist/cjs/cli/lib/mcp/tools/env.js.map +2 -2
- package/dist/cjs/cli/lib/profileManagement.js +196 -0
- package/dist/cjs/cli/lib/profileManagement.js.map +7 -0
- package/dist/cjs/cli/lib/profiles.js +333 -0
- package/dist/cjs/cli/lib/profiles.js.map +7 -0
- package/dist/cjs/cli/lib/run.js +4 -0
- package/dist/cjs/cli/lib/run.js.map +2 -2
- package/dist/cjs/cli/lib/schemaEvaluation.js +62 -0
- package/dist/cjs/cli/lib/schemaEvaluation.js.map +7 -0
- package/dist/cjs/cli/lib/usageLimits.js +4 -2
- package/dist/cjs/cli/lib/usageLimits.js.map +2 -2
- package/dist/cjs/cli/lib/utils/mutex.js +9 -24
- package/dist/cjs/cli/lib/utils/mutex.js.map +2 -2
- package/dist/cjs/cli/lib/utils/utils.js +66 -27
- package/dist/cjs/cli/lib/utils/utils.js.map +2 -2
- package/dist/cjs/cli/login.js +213 -114
- package/dist/cjs/cli/login.js.map +3 -3
- package/dist/cjs/cli/logout.js +113 -12
- package/dist/cjs/cli/logout.js.map +3 -3
- package/dist/cjs/cli/mcp.js +43 -10
- package/dist/cjs/cli/mcp.js.map +3 -3
- package/dist/cjs/cli/program.js +2 -1
- package/dist/cjs/cli/program.js.map +2 -2
- package/dist/cjs/cli/projectCreate.js +1 -1
- package/dist/cjs/cli/projectCreate.js.map +1 -1
- package/dist/cjs/index.js +1 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/server/impl/actions_impl.js +8 -3
- package/dist/cjs/server/impl/actions_impl.js.map +2 -2
- package/dist/cjs/server/impl/storage_impl.js +29 -0
- package/dist/cjs/server/impl/storage_impl.js.map +2 -2
- package/dist/cjs/server/index.js +1 -0
- package/dist/cjs/server/index.js.map +2 -2
- package/dist/cjs/server/meta.js.map +1 -1
- package/dist/cjs/server/registration.js.map +1 -1
- package/dist/cjs/server/schema.js +34 -12
- package/dist/cjs/server/schema.js.map +2 -2
- package/dist/cjs/server/storage.js.map +1 -1
- package/dist/cjs/values/validators.js +1 -1
- package/dist/cjs/values/validators.js.map +2 -2
- package/dist/cjs/values/value.js +6 -0
- package/dist/cjs/values/value.js.map +2 -2
- package/dist/cjs-types/bundler/context.d.ts +5 -0
- package/dist/cjs-types/bundler/context.d.ts.map +1 -1
- package/dist/cjs-types/bundler/fs.d.ts +7 -2
- package/dist/cjs-types/bundler/fs.d.ts.map +1 -1
- package/dist/cjs-types/bundler/index.d.ts +9 -2
- package/dist/cjs-types/bundler/index.d.ts.map +1 -1
- package/dist/cjs-types/cli/account.d.ts +6 -0
- package/dist/cjs-types/cli/account.d.ts.map +1 -0
- package/dist/cjs-types/cli/codegen.d.ts.map +1 -1
- package/dist/cjs-types/cli/configure.d.ts +6 -0
- package/dist/cjs-types/cli/configure.d.ts.map +1 -1
- package/dist/cjs-types/cli/deploy.d.ts +2 -0
- package/dist/cjs-types/cli/deploy.d.ts.map +1 -1
- package/dist/cjs-types/cli/deploymentCreate.d.ts +6 -6
- package/dist/cjs-types/cli/deploymentSelect.d.ts.map +1 -1
- package/dist/cjs-types/cli/dev.d.ts +1 -0
- package/dist/cjs-types/cli/dev.d.ts.map +1 -1
- package/dist/cjs-types/cli/env.d.ts.map +1 -1
- package/dist/cjs-types/cli/envDefault.d.ts.map +1 -1
- package/dist/cjs-types/cli/generatedApi.d.ts +1 -1
- package/dist/cjs-types/cli/generatedApi.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/api.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/checkForLargeIndexBackfill.d.ts +30 -0
- package/dist/cjs-types/cli/lib/checkForLargeIndexBackfill.d.ts.map +1 -0
- package/dist/cjs-types/cli/lib/checkForLargeIndexDeletion.d.ts +5 -7
- package/dist/cjs-types/cli/lib/checkForLargeIndexDeletion.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/checkForSlowSchemaValidation.d.ts +4 -10
- package/dist/cjs-types/cli/lib/checkForSlowSchemaValidation.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/checkForStagedValidatorDeletion.d.ts +17 -0
- package/dist/cjs-types/cli/lib/checkForStagedValidatorDeletion.d.ts.map +1 -0
- package/dist/cjs-types/cli/lib/codegen.d.ts +0 -3
- package/dist/cjs-types/cli/lib/codegen.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/command.d.ts +2 -0
- package/dist/cjs-types/cli/lib/command.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/components/definition/bundle.d.ts +13 -0
- package/dist/cjs-types/cli/lib/components/definition/bundle.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/components.d.ts +4 -0
- package/dist/cjs-types/cli/lib/components.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/config.d.ts +2 -1
- package/dist/cjs-types/cli/lib/config.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/deploy2.d.ts +2 -0
- package/dist/cjs-types/cli/lib/deploy2.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/deployApi/evaluateSchema.d.ts +460 -16
- package/dist/cjs-types/cli/lib/deployApi/evaluateSchema.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/deployKeyWarning.d.ts +3 -0
- package/dist/cjs-types/cli/lib/deployKeyWarning.d.ts.map +1 -0
- package/dist/cjs-types/cli/lib/deployment.d.ts +2 -0
- package/dist/cjs-types/cli/lib/deployment.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/deploymentSelection.d.ts +2 -1
- package/dist/cjs-types/cli/lib/deploymentSelection.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/dev.d.ts +1 -0
- package/dist/cjs-types/cli/lib/dev.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/envvars.d.ts +6 -0
- package/dist/cjs-types/cli/lib/envvars.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/formatValidationProgress.d.ts +8 -0
- package/dist/cjs-types/cli/lib/formatValidationProgress.d.ts.map +1 -0
- package/dist/cjs-types/cli/lib/fsUtils.d.ts +1 -0
- package/dist/cjs-types/cli/lib/fsUtils.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/login.d.ts +3 -1
- package/dist/cjs-types/cli/lib/login.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/mcp/requestContext.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/mcp/tools/env.d.ts +8 -5
- package/dist/cjs-types/cli/lib/mcp/tools/env.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/mcp/tools/insights.d.ts +2 -2
- package/dist/cjs-types/cli/lib/profileManagement.d.ts +10 -0
- package/dist/cjs-types/cli/lib/profileManagement.d.ts.map +1 -0
- package/dist/cjs-types/cli/lib/profiles.d.ts +59 -0
- package/dist/cjs-types/cli/lib/profiles.d.ts.map +1 -0
- package/dist/cjs-types/cli/lib/run.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/schemaEvaluation.d.ts +33 -0
- package/dist/cjs-types/cli/lib/schemaEvaluation.d.ts.map +1 -0
- package/dist/cjs-types/cli/lib/usageLimits.d.ts +1 -1
- package/dist/cjs-types/cli/lib/usageLimits.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/utils/mutex.d.ts +1 -3
- package/dist/cjs-types/cli/lib/utils/mutex.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/utils/utils.d.ts +15 -2
- package/dist/cjs-types/cli/lib/utils/utils.d.ts.map +1 -1
- package/dist/cjs-types/cli/login.d.ts +21 -0
- package/dist/cjs-types/cli/login.d.ts.map +1 -1
- package/dist/cjs-types/cli/logout.d.ts +8 -1
- package/dist/cjs-types/cli/logout.d.ts.map +1 -1
- package/dist/cjs-types/cli/mcp.d.ts.map +1 -1
- package/dist/cjs-types/cli/program.d.ts.map +1 -1
- package/dist/cjs-types/index.d.ts +1 -1
- package/dist/cjs-types/index.d.ts.map +1 -1
- package/dist/cjs-types/server/impl/actions_impl.d.ts +18 -3
- package/dist/cjs-types/server/impl/actions_impl.d.ts.map +1 -1
- package/dist/cjs-types/server/impl/storage_impl.d.ts.map +1 -1
- package/dist/cjs-types/server/index.d.ts +1 -1
- package/dist/cjs-types/server/index.d.ts.map +1 -1
- package/dist/cjs-types/server/meta.d.ts +63 -0
- package/dist/cjs-types/server/meta.d.ts.map +1 -1
- package/dist/cjs-types/server/registration.d.ts +10 -0
- package/dist/cjs-types/server/registration.d.ts.map +1 -1
- package/dist/cjs-types/server/schema.d.ts +33 -0
- package/dist/cjs-types/server/schema.d.ts.map +1 -1
- package/dist/cjs-types/server/storage.d.ts.map +1 -1
- package/dist/cjs-types/values/value.d.ts.map +1 -1
- package/dist/cli.bundle.cjs +4889 -2980
- package/dist/cli.bundle.cjs.map +4 -4
- package/dist/esm/bundler/context.js +7 -5
- package/dist/esm/bundler/context.js.map +2 -2
- package/dist/esm/bundler/fs.js +47 -6
- package/dist/esm/bundler/fs.js.map +2 -2
- package/dist/esm/bundler/index.js +5 -4
- package/dist/esm/bundler/index.js.map +2 -2
- package/dist/esm/cli/account.js +221 -0
- package/dist/esm/cli/account.js.map +7 -0
- package/dist/esm/cli/codegen.js +0 -4
- package/dist/esm/cli/codegen.js.map +2 -2
- package/dist/esm/cli/configure.js +27 -6
- package/dist/esm/cli/configure.js.map +2 -2
- package/dist/esm/cli/deploy.js +27 -2
- package/dist/esm/cli/deploy.js.map +2 -2
- package/dist/esm/cli/deploymentSelect.js +6 -3
- package/dist/esm/cli/deploymentSelect.js.map +2 -2
- package/dist/esm/cli/dev.js +6 -0
- package/dist/esm/cli/dev.js.map +2 -2
- package/dist/esm/cli/env.js +11 -6
- package/dist/esm/cli/env.js.map +2 -2
- package/dist/esm/cli/envDefault.js +7 -2
- package/dist/esm/cli/envDefault.js.map +2 -2
- package/dist/esm/cli/lib/api.js +2 -0
- package/dist/esm/cli/lib/api.js.map +2 -2
- package/dist/esm/cli/lib/checkForLargeIndexBackfill.js +95 -0
- package/dist/esm/cli/lib/checkForLargeIndexBackfill.js.map +7 -0
- package/dist/esm/cli/lib/checkForLargeIndexDeletion.js +37 -48
- package/dist/esm/cli/lib/checkForLargeIndexDeletion.js.map +2 -2
- package/dist/esm/cli/lib/checkForSlowSchemaValidation.js +63 -41
- package/dist/esm/cli/lib/checkForSlowSchemaValidation.js.map +2 -2
- package/dist/esm/cli/lib/checkForStagedValidatorDeletion.js +68 -0
- package/dist/esm/cli/lib/checkForStagedValidatorDeletion.js.map +7 -0
- package/dist/esm/cli/lib/codegen.js.map +2 -2
- package/dist/esm/cli/lib/command.js +2 -1
- package/dist/esm/cli/lib/command.js.map +2 -2
- package/dist/esm/cli/lib/components/definition/bundle.js +37 -11
- package/dist/esm/cli/lib/components/definition/bundle.js.map +2 -2
- package/dist/esm/cli/lib/components.js +55 -5
- package/dist/esm/cli/lib/components.js.map +2 -2
- package/dist/esm/cli/lib/config.js +55 -17
- package/dist/esm/cli/lib/config.js.map +2 -2
- package/dist/esm/cli/lib/deploy2.js +3 -1
- package/dist/esm/cli/lib/deploy2.js.map +2 -2
- package/dist/esm/cli/lib/deployApi/evaluateSchema.js +28 -2
- package/dist/esm/cli/lib/deployApi/evaluateSchema.js.map +2 -2
- package/dist/esm/cli/lib/deployKeyWarning.js +27 -0
- package/dist/esm/cli/lib/deployKeyWarning.js.map +7 -0
- package/dist/esm/cli/lib/deployment.js +2 -2
- package/dist/esm/cli/lib/deployment.js.map +2 -2
- package/dist/esm/cli/lib/deploymentSelection.js +35 -20
- package/dist/esm/cli/lib/deploymentSelection.js.map +2 -2
- package/dist/esm/cli/lib/dev.js +5 -0
- package/dist/esm/cli/lib/dev.js.map +2 -2
- package/dist/esm/cli/lib/envvars.js +35 -1
- package/dist/esm/cli/lib/envvars.js.map +2 -2
- package/dist/esm/cli/lib/formatValidationProgress.js +24 -0
- package/dist/esm/cli/lib/formatValidationProgress.js.map +7 -0
- package/dist/esm/cli/lib/fsUtils.js +1 -1
- package/dist/esm/cli/lib/fsUtils.js.map +2 -2
- package/dist/esm/cli/lib/generateDocs.js +1 -1
- package/dist/esm/cli/lib/generateDocs.js.map +1 -1
- package/dist/esm/cli/lib/indexes.js.map +1 -1
- package/dist/esm/cli/lib/login.js +36 -4
- package/dist/esm/cli/lib/login.js.map +2 -2
- package/dist/esm/cli/lib/mcp/requestContext.js +5 -1
- package/dist/esm/cli/lib/mcp/requestContext.js.map +2 -2
- package/dist/esm/cli/lib/mcp/tools/env.js +10 -3
- package/dist/esm/cli/lib/mcp/tools/env.js.map +2 -2
- package/dist/esm/cli/lib/profileManagement.js +179 -0
- package/dist/esm/cli/lib/profileManagement.js.map +7 -0
- package/dist/esm/cli/lib/profiles.js +288 -0
- package/dist/esm/cli/lib/profiles.js.map +7 -0
- package/dist/esm/cli/lib/run.js +4 -0
- package/dist/esm/cli/lib/run.js.map +2 -2
- package/dist/esm/cli/lib/schemaEvaluation.js +39 -0
- package/dist/esm/cli/lib/schemaEvaluation.js.map +7 -0
- package/dist/esm/cli/lib/usageLimits.js +4 -2
- package/dist/esm/cli/lib/usageLimits.js.map +2 -2
- package/dist/esm/cli/lib/utils/mutex.js +9 -24
- package/dist/esm/cli/lib/utils/mutex.js.map +2 -2
- package/dist/esm/cli/lib/utils/utils.js +63 -27
- package/dist/esm/cli/lib/utils/utils.js.map +2 -2
- package/dist/esm/cli/login.js +225 -112
- package/dist/esm/cli/login.js.map +3 -3
- package/dist/esm/cli/logout.js +110 -13
- package/dist/esm/cli/logout.js.map +2 -2
- package/dist/esm/cli/mcp.js +34 -10
- package/dist/esm/cli/mcp.js.map +2 -2
- package/dist/esm/cli/program.js +2 -1
- package/dist/esm/cli/program.js.map +2 -2
- package/dist/esm/cli/projectCreate.js +1 -1
- package/dist/esm/cli/projectCreate.js.map +1 -1
- package/dist/esm/index.js +1 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/server/impl/actions_impl.js +7 -3
- package/dist/esm/server/impl/actions_impl.js.map +2 -2
- package/dist/esm/server/impl/storage_impl.js +29 -0
- package/dist/esm/server/impl/storage_impl.js.map +2 -2
- package/dist/esm/server/index.js +4 -1
- package/dist/esm/server/index.js.map +2 -2
- package/dist/esm/server/schema.js +34 -12
- package/dist/esm/server/schema.js.map +2 -2
- package/dist/esm/values/validators.js +1 -1
- package/dist/esm/values/validators.js.map +2 -2
- package/dist/esm/values/value.js +6 -0
- package/dist/esm/values/value.js.map +2 -2
- package/dist/esm-types/bundler/context.d.ts +5 -0
- package/dist/esm-types/bundler/context.d.ts.map +1 -1
- package/dist/esm-types/bundler/fs.d.ts +7 -2
- package/dist/esm-types/bundler/fs.d.ts.map +1 -1
- package/dist/esm-types/bundler/index.d.ts +9 -2
- package/dist/esm-types/bundler/index.d.ts.map +1 -1
- package/dist/esm-types/cli/account.d.ts +6 -0
- package/dist/esm-types/cli/account.d.ts.map +1 -0
- package/dist/esm-types/cli/codegen.d.ts.map +1 -1
- package/dist/esm-types/cli/configure.d.ts +6 -0
- package/dist/esm-types/cli/configure.d.ts.map +1 -1
- package/dist/esm-types/cli/deploy.d.ts +2 -0
- package/dist/esm-types/cli/deploy.d.ts.map +1 -1
- package/dist/esm-types/cli/deploymentCreate.d.ts +6 -6
- package/dist/esm-types/cli/deploymentSelect.d.ts.map +1 -1
- package/dist/esm-types/cli/dev.d.ts +1 -0
- package/dist/esm-types/cli/dev.d.ts.map +1 -1
- package/dist/esm-types/cli/env.d.ts.map +1 -1
- package/dist/esm-types/cli/envDefault.d.ts.map +1 -1
- package/dist/esm-types/cli/generatedApi.d.ts +1 -1
- package/dist/esm-types/cli/generatedApi.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/api.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/checkForLargeIndexBackfill.d.ts +30 -0
- package/dist/esm-types/cli/lib/checkForLargeIndexBackfill.d.ts.map +1 -0
- package/dist/esm-types/cli/lib/checkForLargeIndexDeletion.d.ts +5 -7
- package/dist/esm-types/cli/lib/checkForLargeIndexDeletion.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/checkForSlowSchemaValidation.d.ts +4 -10
- package/dist/esm-types/cli/lib/checkForSlowSchemaValidation.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/checkForStagedValidatorDeletion.d.ts +17 -0
- package/dist/esm-types/cli/lib/checkForStagedValidatorDeletion.d.ts.map +1 -0
- package/dist/esm-types/cli/lib/codegen.d.ts +0 -3
- package/dist/esm-types/cli/lib/codegen.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/command.d.ts +2 -0
- package/dist/esm-types/cli/lib/command.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/components/definition/bundle.d.ts +13 -0
- package/dist/esm-types/cli/lib/components/definition/bundle.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/components.d.ts +4 -0
- package/dist/esm-types/cli/lib/components.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/config.d.ts +2 -1
- package/dist/esm-types/cli/lib/config.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/deploy2.d.ts +2 -0
- package/dist/esm-types/cli/lib/deploy2.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/deployApi/evaluateSchema.d.ts +460 -16
- package/dist/esm-types/cli/lib/deployApi/evaluateSchema.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/deployKeyWarning.d.ts +3 -0
- package/dist/esm-types/cli/lib/deployKeyWarning.d.ts.map +1 -0
- package/dist/esm-types/cli/lib/deployment.d.ts +2 -0
- package/dist/esm-types/cli/lib/deployment.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/deploymentSelection.d.ts +2 -1
- package/dist/esm-types/cli/lib/deploymentSelection.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/dev.d.ts +1 -0
- package/dist/esm-types/cli/lib/dev.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/envvars.d.ts +6 -0
- package/dist/esm-types/cli/lib/envvars.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/formatValidationProgress.d.ts +8 -0
- package/dist/esm-types/cli/lib/formatValidationProgress.d.ts.map +1 -0
- package/dist/esm-types/cli/lib/fsUtils.d.ts +1 -0
- package/dist/esm-types/cli/lib/fsUtils.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/login.d.ts +3 -1
- package/dist/esm-types/cli/lib/login.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/mcp/requestContext.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/mcp/tools/env.d.ts +8 -5
- package/dist/esm-types/cli/lib/mcp/tools/env.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/mcp/tools/insights.d.ts +2 -2
- package/dist/esm-types/cli/lib/profileManagement.d.ts +10 -0
- package/dist/esm-types/cli/lib/profileManagement.d.ts.map +1 -0
- package/dist/esm-types/cli/lib/profiles.d.ts +59 -0
- package/dist/esm-types/cli/lib/profiles.d.ts.map +1 -0
- package/dist/esm-types/cli/lib/run.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/schemaEvaluation.d.ts +33 -0
- package/dist/esm-types/cli/lib/schemaEvaluation.d.ts.map +1 -0
- package/dist/esm-types/cli/lib/usageLimits.d.ts +1 -1
- package/dist/esm-types/cli/lib/usageLimits.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/utils/mutex.d.ts +1 -3
- package/dist/esm-types/cli/lib/utils/mutex.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/utils/utils.d.ts +15 -2
- package/dist/esm-types/cli/lib/utils/utils.d.ts.map +1 -1
- package/dist/esm-types/cli/login.d.ts +21 -0
- package/dist/esm-types/cli/login.d.ts.map +1 -1
- package/dist/esm-types/cli/logout.d.ts +8 -1
- package/dist/esm-types/cli/logout.d.ts.map +1 -1
- package/dist/esm-types/cli/mcp.d.ts.map +1 -1
- package/dist/esm-types/cli/program.d.ts.map +1 -1
- package/dist/esm-types/index.d.ts +1 -1
- package/dist/esm-types/index.d.ts.map +1 -1
- package/dist/esm-types/server/impl/actions_impl.d.ts +18 -3
- package/dist/esm-types/server/impl/actions_impl.d.ts.map +1 -1
- package/dist/esm-types/server/impl/storage_impl.d.ts.map +1 -1
- package/dist/esm-types/server/index.d.ts +1 -1
- package/dist/esm-types/server/index.d.ts.map +1 -1
- package/dist/esm-types/server/meta.d.ts +63 -0
- package/dist/esm-types/server/meta.d.ts.map +1 -1
- package/dist/esm-types/server/registration.d.ts +10 -0
- package/dist/esm-types/server/registration.d.ts.map +1 -1
- package/dist/esm-types/server/schema.d.ts +33 -0
- package/dist/esm-types/server/schema.d.ts.map +1 -1
- package/dist/esm-types/server/storage.d.ts.map +1 -1
- package/dist/esm-types/values/value.d.ts.map +1 -1
- package/dist/react.bundle.js +7 -1
- package/dist/react.bundle.js.map +2 -2
- package/package.json +5 -5
- package/schemas/convex.schema.json +5 -5
- package/src/bundler/context.ts +9 -5
- package/src/bundler/fs.ts +54 -5
- package/src/bundler/index.ts +9 -4
- package/src/cli/account.ts +320 -0
- package/src/cli/codegen.ts +0 -2
- package/src/cli/configure.ts +45 -9
- package/src/cli/deploy.ts +36 -5
- package/src/cli/deploymentSelect.ts +7 -4
- package/src/cli/dev.ts +9 -0
- package/src/cli/env.ts +12 -6
- package/src/cli/envDefault.ts +8 -2
- package/src/cli/generatedApi.ts +1 -1
- package/src/cli/lib/api.ts +5 -1
- package/src/cli/lib/checkForLargeIndexBackfill.ts +173 -0
- package/src/cli/lib/checkForLargeIndexDeletion.ts +45 -58
- package/src/cli/lib/checkForSlowSchemaValidation.ts +76 -65
- package/src/cli/lib/checkForStagedValidatorDeletion.ts +104 -0
- package/src/cli/lib/codegen.ts +0 -3
- package/src/cli/lib/command.ts +3 -0
- package/src/cli/lib/components/definition/bundle.ts +68 -14
- package/src/cli/lib/components.ts +71 -4
- package/src/cli/lib/config.ts +85 -18
- package/src/cli/lib/deploy2.ts +10 -1
- package/src/cli/lib/deployApi/evaluateSchema.ts +35 -0
- package/src/cli/lib/deployKeyWarning.ts +43 -0
- package/src/cli/lib/deployment.ts +2 -2
- package/src/cli/lib/deploymentSelection.ts +37 -18
- package/src/cli/lib/dev.ts +14 -0
- package/src/cli/lib/envvars.ts +43 -1
- package/src/cli/lib/formatValidationProgress.ts +35 -0
- package/src/cli/lib/fsUtils.ts +5 -2
- package/src/cli/lib/generateDocs.ts +1 -1
- package/src/cli/lib/indexes.ts +1 -1
- package/src/cli/lib/login.ts +47 -3
- package/src/cli/lib/mcp/requestContext.ts +7 -1
- package/src/cli/lib/mcp/tools/env.ts +17 -3
- package/src/cli/lib/profileManagement.ts +262 -0
- package/src/cli/lib/profiles.ts +398 -0
- package/src/cli/lib/run.ts +2 -0
- package/src/cli/lib/schemaEvaluation.ts +88 -0
- package/src/cli/lib/usageLimits.ts +2 -0
- package/src/cli/lib/utils/mutex.ts +9 -27
- package/src/cli/lib/utils/utils.ts +83 -36
- package/src/cli/login.ts +293 -168
- package/src/cli/logout.ts +142 -17
- package/src/cli/mcp.ts +48 -11
- package/src/cli/program.ts +2 -0
- package/src/cli/projectCreate.ts +1 -1
- package/src/index.ts +1 -1
- package/src/server/impl/actions_impl.ts +26 -6
- package/src/server/impl/storage_impl.ts +30 -0
- package/src/server/index.ts +5 -1
- package/src/server/meta.ts +56 -2
- package/src/server/registration.ts +10 -0
- package/src/server/schema.ts +37 -15
- package/src/server/storage.ts +17 -0
- package/src/values/validators.ts +1 -1
- package/src/values/value.ts +9 -5
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/cli/lib/deploymentSelection.ts"],
|
|
4
|
-
"sourcesContent": ["import { ProjectResponse } from \"@convex-dev/platform/managementApi\";\nimport { BigBrainAuth, Context } from \"../../bundler/context.js\";\nimport { logVerbose } from \"../../bundler/log.js\";\nimport {\n AccountRequiredDeploymentType,\n DeploymentSelectionOptions,\n DeploymentSelectionWithinProject,\n deploymentSelectionWithinProjectFromOptions,\n DeploymentType,\n fetchTeamAndProjectForKey,\n getTeamAndProjectSlugForDeployment,\n validateDeploymentSelectionForExistingDeployment,\n} from \"./api.js\";\nimport {\n deploymentNameFromAdminKeyOrCrash,\n deploymentTypeFromAdminKey,\n getDeploymentTypeFromConfiguredDeployment,\n isAnonymousDeployment,\n isDeploymentKey,\n isPreviewDeployKey,\n isProjectKey,\n stripDeploymentTypePrefix,\n} from \"./deployment.js\";\nimport {\n parseDeploymentSelector,\n ParsedDeploymentSelector,\n} from \"./deploymentSelector.js\";\nimport { loadProjectLocalConfig } from \"./localDeployment/filePaths.js\";\nimport {\n checkLocalConfigMatchesProject,\n targetProjectForLocalSelector,\n} from \"./localDeployment/projectMismatch.js\";\nimport { chalkStderr } from \"chalk\";\nimport { getBuildEnvironment } from \"./envvars.js\";\nimport { readGlobalConfig } from \"./utils/globalConfig.js\";\nimport {\n CONVEX_DEPLOYMENT_ENV_VAR_NAME,\n CONVEX_DEPLOYMENT_TOKEN_ENV_VAR_NAME,\n CONVEX_DEPLOY_KEY_ENV_VAR_NAME,\n CONVEX_SELF_HOSTED_ADMIN_KEY_VAR_NAME,\n CONVEX_SELF_HOSTED_URL_VAR_NAME,\n ENV_VAR_FILE_PATH,\n bigBrainAPI,\n processDeployKeyValue,\n readDeployKeyFromEnv,\n typedPlatformClient,\n} from \"./utils/utils.js\";\nimport * as dotenv from \"dotenv\";\n\n// ----------------------------------------------------------------------------\n// Big Brain Auth\n// ----------------------------------------------------------------------------\n\n/**\n * The auth header can be a few different things:\n * * An access token (corresponds to device authorization, usually stored in `~/.convex/config.json`)\n * * A preview deploy key (set via the `CONVEX_DEPLOY_KEY` environment variable)\n * * A project key (set via the `CONVEX_DEPLOY_KEY` environment variable)\n * * A deployment key if a deployment key (set via `CONVEX_DEPLOY_KEY` environment variable)\n *\n * Project keys take precedence over the the access token.\n * Deployment keys take precedence over the the access token.\n * This makes using one of these keys while logged in or logged out work the same.\n *\n * We check for the `CONVEX_DEPLOY_KEY` in the `--env-file` if it's provided.\n * Otherwise, we check in the `.env` and `.env.local` files.\n *\n * If we later prompt for log in, we need to call `ctx.setBigBrainAuthHeader` to\n * update the value.\n *\n * @param ctx\n * @param envFile\n * @returns\n */\nexport async function initializeBigBrainAuth(\n ctx: Context,\n initialArgs: {\n url?: string | undefined;\n adminKey?: string | undefined;\n envFile?: string | undefined;\n },\n): Promise<void> {\n if (initialArgs.url !== undefined && initialArgs.adminKey !== undefined) {\n // Do not check any env vars if `url` and `adminKey` are specified via CLI\n ctx._updateBigBrainAuth(\n getBigBrainAuth(ctx, {\n previewDeployKey: null,\n projectKey: null,\n deploymentKey: null,\n }),\n );\n return;\n }\n if (initialArgs.envFile !== undefined) {\n const existingFile = ctx.fs.exists(initialArgs.envFile)\n ? ctx.fs.readUtf8File(initialArgs.envFile)\n : null;\n if (existingFile === null) {\n return ctx.crash({\n exitCode: 1,\n errorType: \"invalid filesystem or env vars\",\n printedMessage: \"env file does not exist\",\n });\n }\n const config = dotenv.parse(existingFile);\n const rawDeployKey = readDeployKeyFromEnv((name) => config[name]);\n const deployKey = await processDeployKeyValue(ctx, rawDeployKey);\n if (deployKey !== undefined) {\n const bigBrainAuth = getBigBrainAuth(ctx, {\n previewDeployKey: isPreviewDeployKey(deployKey) ? deployKey : null,\n projectKey: isProjectKey(deployKey) ? deployKey : null,\n deploymentKey: isDeploymentKey(deployKey) ? deployKey : null,\n });\n ctx._updateBigBrainAuth(bigBrainAuth);\n return;\n }\n // No deploy key was found in the env file, so fall back on using the global config\n ctx._updateBigBrainAuth(\n getBigBrainAuth(ctx, {\n previewDeployKey: null,\n projectKey: null,\n deploymentKey: null,\n }),\n );\n return;\n }\n dotenv.config({ path: ENV_VAR_FILE_PATH });\n dotenv.config();\n const rawDeployKey = readDeployKeyFromEnv((name) => process.env[name]);\n const deployKey = await processDeployKeyValue(ctx, rawDeployKey);\n if (deployKey !== undefined) {\n const bigBrainAuth = getBigBrainAuth(ctx, {\n previewDeployKey: isPreviewDeployKey(deployKey) ? deployKey : null,\n projectKey: isProjectKey(deployKey) ? deployKey : null,\n deploymentKey: isDeploymentKey(deployKey) ? deployKey : null,\n });\n ctx._updateBigBrainAuth(bigBrainAuth);\n return;\n }\n ctx._updateBigBrainAuth(\n getBigBrainAuth(ctx, {\n previewDeployKey: null,\n projectKey: null,\n deploymentKey: null,\n }),\n );\n return;\n}\n\nexport async function updateBigBrainAuthAfterLogin(\n ctx: Context,\n accessToken: string,\n) {\n const existingAuth = ctx.bigBrainAuth();\n if (existingAuth !== null && existingAuth.kind === \"projectKey\") {\n logVerbose(\n `Ignoring update to big brain auth since project key takes precedence`,\n );\n return;\n }\n ctx._updateBigBrainAuth({\n accessToken: accessToken,\n kind: \"accessToken\",\n header: `Bearer ${accessToken}`,\n });\n}\n\nexport async function clearBigBrainAuth(ctx: Context) {\n ctx._updateBigBrainAuth(null);\n}\n\nfunction getBigBrainAuth(\n ctx: Context,\n opts: {\n previewDeployKey: string | null;\n projectKey: string | null;\n deploymentKey: string | null;\n },\n): BigBrainAuth | null {\n if (process.env.CONVEX_OVERRIDE_ACCESS_TOKEN) {\n return {\n accessToken: process.env.CONVEX_OVERRIDE_ACCESS_TOKEN,\n kind: \"accessToken\",\n header: `Bearer ${process.env.CONVEX_OVERRIDE_ACCESS_TOKEN}`,\n };\n }\n if (opts.projectKey !== null) {\n // Project keys take precedence over global config.\n return {\n header: `Bearer ${opts.projectKey}`,\n kind: \"projectKey\",\n projectKey: opts.projectKey,\n };\n }\n if (opts.deploymentKey !== null) {\n // Deployment keys take precedence over global config.\n return {\n header: `Bearer ${opts.deploymentKey}`,\n kind: \"deploymentKey\",\n deploymentKey: opts.deploymentKey,\n };\n }\n const globalConfig = readGlobalConfig(ctx);\n if (globalConfig) {\n return {\n kind: \"accessToken\",\n header: `Bearer ${globalConfig.accessToken}`,\n accessToken: globalConfig.accessToken,\n };\n }\n if (opts.previewDeployKey !== null) {\n return {\n header: `Bearer ${opts.previewDeployKey}`,\n kind: \"previewDeployKey\",\n previewDeployKey: opts.previewDeployKey,\n };\n }\n return null;\n}\n\n// These guards mirror the management API's auth rules client-side so we can\n// fail with a clear message instead of an opaque 401; the server stays\n// authoritative. Creating a deployment also allows project keys, while the\n// deploy-key commands stay personal-access-token only.\n\n/** Crashes unless logged in with a personal access token (not a deploy key). */\nexport async function ensureLoggedInWithAccessToken(\n ctx: Context,\n action: string,\n): Promise<void> {\n const auth = ctx.bigBrainAuth();\n if (auth !== null && auth.kind === \"accessToken\") {\n return;\n }\n // Name whichever deploy-key env var is in effect (CONVEX_DEPLOY_KEY wins).\n const prefix =\n auth === null\n ? \"Run \"\n : process.env[CONVEX_DEPLOYMENT_TOKEN_ENV_VAR_NAME] &&\n !process.env[CONVEX_DEPLOY_KEY_ENV_VAR_NAME]\n ? `Unset ${CONVEX_DEPLOYMENT_TOKEN_ENV_VAR_NAME} and run `\n : `Unset ${CONVEX_DEPLOY_KEY_ENV_VAR_NAME} and run `;\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: `${action} requires being logged in with a personal access token. ${prefix}${chalkStderr.bold(\n \"npx convex login\",\n )} and try again.`,\n });\n}\n\n/**\n * Crashes unless the auth can create a deployment: personal access tokens and\n * project keys are accepted, deploy keys are not.\n */\nexport async function ensureAuthCanCreateDeployment(\n ctx: Context,\n): Promise<void> {\n const auth = ctx.bigBrainAuth();\n if (\n auth !== null &&\n (auth.kind === \"accessToken\" || auth.kind === \"projectKey\")\n ) {\n return;\n }\n if (auth === null) {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: `Creating a deployment requires logging in. Run ${chalkStderr.bold(\n \"npx convex login\",\n )} and try again.`,\n });\n }\n const envVar = process.env[CONVEX_DEPLOY_KEY_ENV_VAR_NAME]\n ? CONVEX_DEPLOY_KEY_ENV_VAR_NAME\n : CONVEX_DEPLOYMENT_TOKEN_ENV_VAR_NAME;\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: `Creating a deployment isn't supported with a deploy key (${envVar}). Run ${chalkStderr.bold(\n \"npx convex login\",\n )} (or use a project key) and try again.`,\n });\n}\n\n// ----------------------------------------------------------------------------\n// Deployment Selection\n// ----------------------------------------------------------------------------\n/**\n * Our CLI has logic to select which deployment to act on.\n *\n * We first check whether we're targeting a deployment within a project, or if we\n * know exactly which deployment to act on (e.g. in the case of self-hosting).\n *\n * We also special case preview deploys since the presence of a preview deploy key\n * triggers different behavior in `npx convex deploy`.\n *\n * Most commands will immediately compute the deployment selection, and then combine\n * that with any relevant CLI flags to figure out which deployment to talk to.\n *\n * Different commands do different things (e.g. `dev` will allow you to create a new project,\n * `deploy` has different behavior for preview deploys)\n *\n * This should be kept in sync with `initializeBigBrainAuth` since environment variables\n * like `CONVEX_DEPLOY_KEY` are used for both deployment selection and auth.\n */\nexport type DeploymentSelection =\n | {\n kind: \"existingDeployment\";\n deploymentToActOn: {\n url: string;\n adminKey: string;\n } & (\n | {\n deploymentFields: DeploymentFields;\n source: \"deployKey\";\n }\n | {\n deploymentFields: null;\n source: \"selfHosted\" | \"cliArgs\";\n }\n );\n }\n | {\n kind: \"deploymentWithinProject\";\n targetProject: ProjectSelection;\n selectionWithinProject: DeploymentSelectionWithinProject;\n }\n | {\n kind: \"preview\";\n previewDeployKey: string;\n selectionWithinProject: DeploymentSelectionWithinProject;\n }\n | {\n kind: \"chooseProject\";\n selectionWithinProject: DeploymentSelectionWithinProject;\n }\n | {\n kind: \"anonymous\";\n deploymentName: string | null;\n selectionWithinProject: DeploymentSelectionWithinProject;\n };\n\ntype DeploymentFields = {\n deploymentName: string;\n deploymentType: DeploymentType;\n projectSlug: string;\n teamSlug: string;\n reference: string | null;\n isDefault: boolean;\n};\n\nexport type ProjectSelection =\n | {\n kind: \"teamAndProjectSlugs\";\n teamSlug: string;\n projectSlug: string;\n }\n | {\n kind: \"deploymentName\";\n deploymentName: string;\n deploymentType: AccountRequiredDeploymentType | null;\n }\n | {\n kind: \"projectDeployKey\";\n projectDeployKey: string;\n };\n\nexport async function getDeploymentSelection(\n ctx: Context,\n cliArgs: DeploymentSelectionOptions,\n): Promise<DeploymentSelection> {\n const metadata = await _getDeploymentSelection(ctx, cliArgs);\n if (metadata.kind === \"existingDeployment\") {\n const selectionWithinProject =\n deploymentSelectionWithinProjectFromOptions(cliArgs);\n await validateDeploymentSelectionForExistingDeployment(\n ctx,\n selectionWithinProject,\n metadata.deploymentToActOn.source,\n );\n }\n logDeploymentSelection(ctx, metadata);\n return metadata;\n}\n\nfunction logDeploymentSelection(_ctx: Context, selection: DeploymentSelection) {\n switch (selection.kind) {\n case \"existingDeployment\": {\n logVerbose(\n `Existing deployment: ${selection.deploymentToActOn.url} ${selection.deploymentToActOn.source}`,\n );\n break;\n }\n case \"deploymentWithinProject\": {\n logVerbose(\n `Deployment within project: ${prettyProjectSelection(selection.targetProject)}`,\n );\n break;\n }\n case \"preview\": {\n logVerbose(`Preview deploy key`);\n break;\n }\n case \"chooseProject\": {\n logVerbose(`Choose project`);\n break;\n }\n case \"anonymous\": {\n logVerbose(\n `Anonymous, has selected deployment?: ${selection.deploymentName !== null}`,\n );\n break;\n }\n default: {\n selection satisfies never;\n logVerbose(`Unknown deployment selection`);\n }\n }\n return null;\n}\n\nfunction prettyProjectSelection(selection: ProjectSelection) {\n switch (selection.kind) {\n case \"teamAndProjectSlugs\": {\n return `Team and project slugs: ${selection.teamSlug} ${selection.projectSlug}`;\n }\n case \"deploymentName\": {\n return `Deployment name: ${selection.deploymentName}`;\n }\n case \"projectDeployKey\": {\n return `Project deploy key`;\n }\n default: {\n selection satisfies never;\n return `Unknown`;\n }\n }\n}\n\nasync function _getDeploymentSelection(\n ctx: Context,\n cliArgs: DeploymentSelectionOptions,\n): Promise<DeploymentSelection> {\n const selectionWithinProject =\n deploymentSelectionWithinProjectFromOptions(cliArgs);\n /*\n - url + adminKey specified via CLI\n - Do not check any env vars (including ones relevant for auth)\n */\n if (cliArgs.url !== undefined && cliArgs.adminKey !== undefined) {\n return {\n kind: \"existingDeployment\",\n deploymentToActOn: {\n url: cliArgs.url,\n adminKey: cliArgs.adminKey,\n deploymentFields: null,\n source: \"cliArgs\",\n },\n };\n }\n\n // If --deployment is a fully qualified selector (team:project:ref or\n // deployment name), we don't need a current project context \u2192 handle it\n // before env var resolution.\n if (cliArgs.deployment !== undefined) {\n const parsed = parseDeploymentSelector(cliArgs.deployment);\n if (parsed.kind === \"inTeamProject\" && parsed.selector.kind !== \"local\") {\n return {\n kind: \"deploymentWithinProject\",\n targetProject: {\n kind: \"teamAndProjectSlugs\",\n teamSlug: parsed.teamSlug,\n projectSlug: parsed.projectSlug,\n },\n selectionWithinProject: {\n kind: \"deploymentSelector\",\n selector: cliArgs.deployment,\n },\n };\n }\n if (parsed.kind === \"deploymentName\") {\n return {\n kind: \"deploymentWithinProject\",\n targetProject: {\n kind: \"deploymentName\",\n deploymentName: parsed.deploymentName,\n deploymentType: null,\n },\n selectionWithinProject: {\n kind: \"deploymentSelector\",\n selector: cliArgs.deployment,\n },\n };\n }\n if (parsed.kind === \"inTeamProject\" && parsed.selector.kind === \"local\") {\n // team:project:local \u2014 we have the cloud project context up front and\n // don't need to consult env vars at all.\n return await resolveLocalDeploymentSelection(\n ctx,\n parsed,\n selectionWithinProject,\n null,\n );\n }\n }\n\n const baseSelection = await resolveBaseDeploymentSelection(\n ctx,\n cliArgs,\n selectionWithinProject,\n );\n\n // If --deployment is a project-scoped local selector (`local` or\n // `project:local`), override the env-var-derived selection with the local\n // deployment after performing a cloud-project-mismatch check.\n if (cliArgs.deployment !== undefined) {\n const parsed = parseDeploymentSelector(cliArgs.deployment);\n if (\n (parsed.kind === \"inCurrentProject\" || parsed.kind === \"inProject\") &&\n parsed.selector.kind === \"local\"\n ) {\n return await resolveLocalDeploymentSelection(\n ctx,\n parsed,\n selectionWithinProject,\n baseSelection,\n );\n }\n }\n\n return baseSelection;\n}\n\nasync function resolveBaseDeploymentSelection(\n ctx: Context,\n cliArgs: DeploymentSelectionOptions,\n selectionWithinProject: DeploymentSelectionWithinProject,\n): Promise<DeploymentSelection> {\n if (cliArgs.envFile !== undefined) {\n // If an `--env-file` is specified, it must contain enough information for both auth and deployment selection.\n logVerbose(`Checking env file: ${cliArgs.envFile}`);\n const existingFile = ctx.fs.exists(cliArgs.envFile)\n ? ctx.fs.readUtf8File(cliArgs.envFile)\n : null;\n if (existingFile === null) {\n return ctx.crash({\n exitCode: 1,\n errorType: \"invalid filesystem or env vars\",\n printedMessage: \"env file does not exist\",\n });\n }\n const config = dotenv.parse(existingFile);\n const result = await getDeploymentSelectionFromEnv(\n ctx,\n selectionWithinProject,\n (name) =>\n config[name] === undefined || config[name] === \"\" ? null : config[name],\n );\n if (result.kind === \"unknown\") {\n return ctx.crash({\n exitCode: 1,\n errorType: \"invalid filesystem or env vars\",\n printedMessage:\n `env file \\`${cliArgs.envFile}\\` did not contain environment variables for a Convex deployment. ` +\n `Expected \\`${CONVEX_DEPLOY_KEY_ENV_VAR_NAME}\\`, \\`${CONVEX_DEPLOYMENT_ENV_VAR_NAME}\\`, or both \\`${CONVEX_SELF_HOSTED_URL_VAR_NAME}\\` and \\`${CONVEX_SELF_HOSTED_ADMIN_KEY_VAR_NAME}\\` to be set.`,\n });\n }\n return result.metadata;\n }\n // start with .env.local (but doesn't override existing)\n dotenv.config({ path: ENV_VAR_FILE_PATH });\n // for variables not already set, use .env values\n dotenv.config();\n const result = await getDeploymentSelectionFromEnv(\n ctx,\n selectionWithinProject,\n (name) => {\n const value = process.env[name];\n if (value === undefined || value === \"\") {\n return null;\n }\n return value;\n },\n );\n if (result.kind !== \"unknown\") {\n return result.metadata;\n }\n // none of these?\n\n const isLoggedIn = ctx.bigBrainAuth() !== null;\n if (\n (!isLoggedIn ||\n process.env.CONVEX_AGENT_MODE === \"anonymous\" ||\n !process.stdin.isTTY) &&\n !cliArgs.implicitProd &&\n shouldAllowAnonymousDevelopment()\n ) {\n return {\n kind: \"anonymous\",\n deploymentName: null,\n selectionWithinProject,\n };\n }\n\n // Choose a project interactively later\n return {\n kind: \"chooseProject\",\n selectionWithinProject,\n };\n}\n\n/**\n * Handles the `[team:project:]local` selector. Loads the on-disk local config\n * and (if the config has a `cloudProjectId`) verifies it matches the cloud\n * project the user is asking about. Crashes on mismatch.\n */\nasync function resolveLocalDeploymentSelection(\n ctx: Context,\n parsed: ParsedDeploymentSelector,\n selectionWithinProject: DeploymentSelectionWithinProject,\n currentSelection: DeploymentSelection | null,\n): Promise<DeploymentSelection> {\n const localConfig = loadProjectLocalConfig(ctx);\n if (localConfig === null) {\n return ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: `No local deployment found. Run ${chalkStderr.bold(\"npx convex deployment create local\")} to create one.`,\n });\n }\n // Only resolve the target cloud project if the on-disk config has a\n // `cloudProjectId` to compare against \u2014 this avoids unnecessary platform\n // calls for older configs and anonymous mode.\n if (localConfig.config.cloudProjectId !== undefined) {\n const target = await targetProjectForLocalSelector(\n ctx,\n parsed,\n currentSelection ?? { kind: \"chooseProject\", selectionWithinProject },\n );\n if (target !== null) {\n const match = checkLocalConfigMatchesProject(\n ctx,\n localConfig.config,\n target,\n );\n if (match === \"mismatch\") {\n const newSelector = `${target.teamSlug}:${target.slug}:local`;\n return ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage:\n `The local deployment in this directory is in a different project than \\`${target.teamSlug}:${target.slug}\\`. ` +\n `\\n${chalkStderr.dim(`${chalkStderr.bold(\"Hint\")}: If you want to move the local deployment to this project, run ${chalkStderr.bold(`npx convex deployment select ${newSelector}`)}`)}`,\n });\n }\n }\n }\n return {\n kind: \"deploymentWithinProject\",\n targetProject: {\n kind: \"deploymentName\",\n deploymentName: localConfig.deploymentName,\n deploymentType: \"local\",\n },\n selectionWithinProject,\n };\n}\n\nasync function getDeploymentSelectionFromEnv(\n ctx: Context,\n selectionWithinProject: DeploymentSelectionWithinProject,\n getEnv: (name: string) => string | null,\n): Promise<\n { kind: \"success\"; metadata: DeploymentSelection } | { kind: \"unknown\" }\n> {\n const rawDeployKey = readDeployKeyFromEnv(getEnv);\n const deployKey = await processDeployKeyValue(ctx, rawDeployKey);\n if (deployKey !== undefined) {\n const deployKeyType = isPreviewDeployKey(deployKey)\n ? \"preview\"\n : isProjectKey(deployKey)\n ? \"project\"\n : \"deployment\";\n switch (deployKeyType) {\n case \"preview\": {\n // `CONVEX_DEPLOY_KEY` is set to a preview deploy key so this takes precedence over anything else.\n // At the moment, we don't verify that there aren't other env vars that would also be used for deployment selection (e.g. `CONVEX_DEPLOYMENT`)\n return {\n kind: \"success\",\n metadata: {\n kind: \"preview\",\n previewDeployKey: deployKey,\n selectionWithinProject,\n },\n };\n }\n case \"project\": {\n // `CONVEX_DEPLOY_KEY` is set to a project deploy key.\n // Commands can select any deployment within the project. At the moment we don't check for other env vars (e.g. `CONVEX_DEPLOYMENT`)\n return {\n kind: \"success\",\n metadata: {\n kind: \"deploymentWithinProject\",\n targetProject: {\n kind: \"projectDeployKey\",\n projectDeployKey: deployKey,\n },\n selectionWithinProject,\n },\n };\n }\n case \"deployment\": {\n // `CONVEX_DEPLOY_KEY` is set to a deployment's deploy key.\n // Deploy to this deployment -- selectors like `--prod` / `--preview-name` will be ignored.\n // At the moment, we don't verify that there aren't other env vars that would also be used for deployment selection (e.g. `CONVEX_DEPLOYMENT`)\n const deploymentName = await deploymentNameFromAdminKeyOrCrash(\n ctx,\n deployKey,\n );\n const deploymentType = deploymentTypeFromAdminKey(deployKey);\n // We cannot derive the deployment URL from the deploy key, because it\n // might be a custom domain. Ask big brain for the URL.\n const url = await bigBrainAPI({\n ctx,\n method: \"POST\",\n path: \"deployment/url_for_key\",\n data: {\n deployKey: deployKey,\n },\n });\n const slugs = await fetchTeamAndProjectForKey(ctx, deployKey);\n return {\n kind: \"success\",\n metadata: {\n kind: \"existingDeployment\",\n deploymentToActOn: {\n url: url,\n adminKey: deployKey,\n deploymentFields: {\n deploymentName: deploymentName,\n deploymentType: deploymentType,\n teamSlug: slugs.team,\n projectSlug: slugs.project,\n reference: slugs.reference,\n isDefault: slugs.isDefault,\n },\n source: \"deployKey\",\n },\n },\n };\n }\n default: {\n deployKeyType satisfies never;\n return ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: `Unexpected deploy key type: ${deployKeyType as any}`,\n });\n }\n }\n }\n\n const convexDeployment = getEnv(CONVEX_DEPLOYMENT_ENV_VAR_NAME);\n const selfHostedUrl = getEnv(CONVEX_SELF_HOSTED_URL_VAR_NAME);\n const selfHostedAdminKey = getEnv(CONVEX_SELF_HOSTED_ADMIN_KEY_VAR_NAME);\n\n if (selfHostedUrl !== null && selfHostedAdminKey !== null) {\n if (convexDeployment !== null) {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"invalid filesystem or env vars\",\n printedMessage: `${CONVEX_DEPLOYMENT_ENV_VAR_NAME} must not be set when ${CONVEX_SELF_HOSTED_URL_VAR_NAME} and ${CONVEX_SELF_HOSTED_ADMIN_KEY_VAR_NAME} are set`,\n });\n }\n return {\n kind: \"success\",\n metadata: {\n kind: \"existingDeployment\",\n deploymentToActOn: {\n url: selfHostedUrl,\n adminKey: selfHostedAdminKey,\n deploymentFields: null,\n source: \"selfHosted\",\n },\n },\n };\n }\n\n // --deployment-name\u2019s deployment may be in a different project from CONVEX_DEPLOYMENT.\n if (selectionWithinProject.kind === \"deploymentName\") {\n return {\n kind: \"success\",\n metadata: {\n kind: \"deploymentWithinProject\",\n targetProject: {\n kind: \"deploymentName\",\n deploymentName: selectionWithinProject.deploymentName,\n deploymentType: null,\n },\n selectionWithinProject,\n },\n };\n }\n\n if (convexDeployment !== null) {\n if (selfHostedUrl !== null || selfHostedAdminKey !== null) {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"invalid filesystem or env vars\",\n printedMessage: `${CONVEX_SELF_HOSTED_URL_VAR_NAME} and ${CONVEX_SELF_HOSTED_ADMIN_KEY_VAR_NAME} must not be set when ${CONVEX_DEPLOYMENT_ENV_VAR_NAME} is set`,\n });\n }\n const targetDeploymentType =\n getDeploymentTypeFromConfiguredDeployment(convexDeployment);\n\n // Commands can select a deployment within the project that this deployment belongs to.\n const targetDeploymentName = stripDeploymentTypePrefix(convexDeployment);\n const isAnonymous = isAnonymousDeployment(targetDeploymentName);\n if (isAnonymous) {\n if (!shouldAllowAnonymousDevelopment()) {\n return {\n kind: \"unknown\",\n };\n }\n return {\n kind: \"success\",\n metadata: {\n kind: \"anonymous\",\n deploymentName: targetDeploymentName,\n selectionWithinProject,\n },\n };\n }\n\n // Overwrite the selection within project\n const newSelectionWithinProject =\n selectionWithinProject.kind === \"unspecified\" &&\n // Fetching local deployment credentials uses the \"unspecified\" code path\n targetDeploymentType !== \"local\"\n ? {\n kind: \"deploymentName\" as const,\n deploymentName: targetDeploymentName,\n }\n : selectionWithinProject;\n return {\n kind: \"success\",\n metadata: {\n kind: \"deploymentWithinProject\",\n targetProject: {\n kind: \"deploymentName\",\n deploymentName: targetDeploymentName,\n deploymentType: targetDeploymentType,\n },\n selectionWithinProject: newSelectionWithinProject,\n },\n };\n }\n\n // Throw a nice error if we're in something like a CI environment where we need a valid deployment configuration\n await checkIfBuildEnvironmentRequiresDeploymentConfig(ctx);\n\n return { kind: \"unknown\" };\n}\n\nasync function checkIfBuildEnvironmentRequiresDeploymentConfig(ctx: Context) {\n const buildEnvironment = getBuildEnvironment();\n if (buildEnvironment) {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage:\n `${buildEnvironment} build environment detected but no Convex deployment configuration found.\\n` +\n `Set one of:\\n` +\n ` \u2022 ${CONVEX_DEPLOY_KEY_ENV_VAR_NAME} for Convex Cloud deployments\\n` +\n ` \u2022 ${CONVEX_SELF_HOSTED_URL_VAR_NAME} and ${CONVEX_SELF_HOSTED_ADMIN_KEY_VAR_NAME} for self-hosted deployments\\n` +\n `See https://docs.convex.dev/production/hosting or https://docs.convex.dev/self-hosting`,\n });\n }\n}\n\n/**\n * Used for things like `npx convex docs` where we want to best effort extract a deployment name\n * but don't do the full deployment selection logic.\n */\nexport const deploymentNameFromSelection = (\n selection: DeploymentSelection,\n): string | null => {\n return deploymentNameAndTypeFromSelection(selection)?.name ?? null;\n};\n\nexport const deploymentNameAndTypeFromSelection = (\n selection: DeploymentSelection,\n): { name: string | null; type: string | null } | null => {\n switch (selection.kind) {\n case \"existingDeployment\": {\n return {\n name:\n selection.deploymentToActOn.deploymentFields?.deploymentName ?? null,\n type:\n selection.deploymentToActOn.deploymentFields?.deploymentType ?? null,\n };\n }\n case \"deploymentWithinProject\": {\n return selection.targetProject.kind === \"deploymentName\"\n ? {\n name: selection.targetProject.deploymentName,\n type: selection.targetProject.deploymentType,\n }\n : null;\n }\n case \"preview\": {\n return null;\n }\n case \"chooseProject\": {\n return null;\n }\n case \"anonymous\": {\n return null;\n }\n default: {\n selection satisfies never;\n }\n }\n return null;\n};\n\nexport const shouldAllowAnonymousDevelopment = (): boolean => {\n // Kill switch / temporary opt out\n if (process.env.CONVEX_ALLOW_ANONYMOUS === \"false\") {\n return false;\n }\n return true;\n};\n\n/**\n * Fetch the project details corresponding to the given ProjectSelection.\n */\nexport async function getProjectDetails(\n ctx: Context,\n projectSelection: ProjectSelection,\n): Promise<ProjectResponse> {\n switch (projectSelection.kind) {\n case \"deploymentName\": {\n if (projectSelection.deploymentType === \"local\") {\n const result = await getTeamAndProjectSlugForDeployment(ctx, {\n deploymentName: projectSelection.deploymentName,\n });\n if (result === null) {\n return ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage:\n \"You don't have access to the selected project. Run `npx convex dev` to select a different project.\",\n });\n }\n return await getProjectDetails(ctx, {\n kind: \"teamAndProjectSlugs\",\n teamSlug: result.teamSlug,\n projectSlug: result.projectSlug,\n });\n }\n\n const deployment = (\n await typedPlatformClient(ctx).GET(\"/deployments/{deployment_name}\", {\n params: {\n path: { deployment_name: projectSelection.deploymentName },\n },\n })\n ).data!;\n return (\n await typedPlatformClient(ctx).GET(\"/projects/{project_id}\", {\n params: { path: { project_id: deployment.projectId } },\n })\n ).data!;\n }\n case \"teamAndProjectSlugs\": {\n return (\n await typedPlatformClient(ctx).GET(\n \"/teams/{team_id_or_slug}/projects/{project_slug}\",\n {\n params: {\n path: {\n team_id_or_slug: projectSelection.teamSlug,\n project_slug: projectSelection.projectSlug,\n },\n },\n },\n )\n ).data!;\n }\n case \"projectDeployKey\": {\n const result = await fetchTeamAndProjectForKey(\n ctx,\n projectSelection.projectDeployKey,\n );\n return (\n await typedPlatformClient(ctx).GET(\"/projects/{project_id}\", {\n params: { path: { project_id: result.projectId } },\n })\n ).data!;\n }\n }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["import { ProjectResponse } from \"@convex-dev/platform/managementApi\";\nimport { BigBrainAuth, Context } from \"../../bundler/context.js\";\nimport { logVerbose } from \"../../bundler/log.js\";\nimport {\n AccountRequiredDeploymentType,\n DeploymentSelectionOptions,\n DeploymentSelectionWithinProject,\n deploymentSelectionWithinProjectFromOptions,\n DeploymentType,\n fetchTeamAndProjectForKey,\n getTeamAndProjectSlugForDeployment,\n validateDeploymentSelectionForExistingDeployment,\n} from \"./api.js\";\nimport {\n deploymentNameFromAdminKeyOrCrash,\n deploymentTypeFromAdminKey,\n getDeploymentTypeFromConfiguredDeployment,\n isAnonymousDeployment,\n isDeploymentKey,\n isPreviewDeployKey,\n isProjectKey,\n stripDeploymentTypePrefix,\n} from \"./deployment.js\";\nimport {\n parseDeploymentSelector,\n ParsedDeploymentSelector,\n} from \"./deploymentSelector.js\";\nimport { loadProjectLocalConfig } from \"./localDeployment/filePaths.js\";\nimport {\n checkLocalConfigMatchesProject,\n targetProjectForLocalSelector,\n} from \"./localDeployment/projectMismatch.js\";\nimport { chalkStderr } from \"chalk\";\nimport {\n getBuildEnvironment,\n loadProjectEnvironmentVariables,\n} from \"./envvars.js\";\nimport { readGlobalConfig } from \"./utils/globalConfig.js\";\nimport {\n getProfileSelection,\n ProfileSelection,\n readProfileAuth,\n} from \"./profiles.js\";\nimport {\n CONVEX_DEPLOYMENT_ENV_VAR_NAME,\n CONVEX_DEPLOYMENT_TOKEN_ENV_VAR_NAME,\n CONVEX_DEPLOY_KEY_ENV_VAR_NAME,\n CONVEX_SELF_HOSTED_ADMIN_KEY_VAR_NAME,\n CONVEX_SELF_HOSTED_URL_VAR_NAME,\n bigBrainAPI,\n processDeployKeyValue,\n readDeployKeyFromEnv,\n readDeployKeyEnvVar,\n typedPlatformClient,\n} from \"./utils/utils.js\";\nimport * as dotenv from \"dotenv\";\n\n// ----------------------------------------------------------------------------\n// Big Brain Auth\n// ----------------------------------------------------------------------------\n\n/**\n * The auth header can be a few different things:\n * * An access token (corresponds to device authorization, usually stored in `~/.convex/config.json`)\n * * A preview deploy key (set via the `CONVEX_DEPLOY_KEY` environment variable)\n * * A project key (set via the `CONVEX_DEPLOY_KEY` environment variable)\n * * A deployment key if a deployment key (set via `CONVEX_DEPLOY_KEY` environment variable)\n *\n * Project keys take precedence over the the access token.\n * Deployment keys take precedence over the the access token.\n * This makes using one of these keys while logged in or logged out work the same.\n *\n * We check for the `CONVEX_DEPLOY_KEY` in the `--env-file` if it's provided.\n * Otherwise, we check in the `.env` and `.env.local` files.\n *\n * If we later prompt for log in, we need to call `ctx.setBigBrainAuthHeader` to\n * update the value.\n *\n * @param ctx\n * @param envFile\n * @returns\n */\nexport async function initializeBigBrainAuth(\n ctx: Context,\n initialArgs: {\n url?: string | undefined;\n adminKey?: string | undefined;\n envFile?: string | undefined;\n },\n): Promise<void> {\n if (initialArgs.url !== undefined && initialArgs.adminKey !== undefined) {\n // Do not check any env vars if `url` and `adminKey` are specified via CLI\n ctx._updateBigBrainAuth(\n await getBigBrainAuth(ctx, {\n previewDeployKey: null,\n projectKey: null,\n deploymentKey: null,\n skipProfile: true,\n }),\n );\n return;\n }\n if (initialArgs.envFile !== undefined) {\n const existingFile = ctx.fs.exists(initialArgs.envFile)\n ? ctx.fs.readUtf8File(initialArgs.envFile)\n : null;\n if (existingFile === null) {\n return ctx.crash({\n exitCode: 1,\n errorType: \"invalid filesystem or env vars\",\n printedMessage: \"env file does not exist\",\n });\n }\n const config = dotenv.parse(existingFile);\n const rawDeployKey = readDeployKeyFromEnv((name) => config[name]);\n const deployKey = await processDeployKeyValue(ctx, rawDeployKey);\n if (deployKey !== undefined) {\n const bigBrainAuth = await getBigBrainAuth(ctx, {\n previewDeployKey: isPreviewDeployKey(deployKey) ? deployKey : null,\n projectKey: isProjectKey(deployKey) ? deployKey : null,\n deploymentKey: isDeploymentKey(deployKey) ? deployKey : null,\n envFile: initialArgs.envFile,\n });\n ctx._updateBigBrainAuth(bigBrainAuth);\n return;\n }\n // No deploy key was found in the env file, so fall back on using the global config\n ctx._updateBigBrainAuth(\n await getBigBrainAuth(ctx, {\n previewDeployKey: null,\n projectKey: null,\n deploymentKey: null,\n envFile: initialArgs.envFile,\n }),\n );\n return;\n }\n loadProjectEnvironmentVariables();\n const rawDeployKey = readDeployKeyFromEnv((name) => process.env[name]);\n const deployKey = await processDeployKeyValue(ctx, rawDeployKey);\n if (deployKey !== undefined) {\n const bigBrainAuth = await getBigBrainAuth(ctx, {\n previewDeployKey: isPreviewDeployKey(deployKey) ? deployKey : null,\n projectKey: isProjectKey(deployKey) ? deployKey : null,\n deploymentKey: isDeploymentKey(deployKey) ? deployKey : null,\n });\n ctx._updateBigBrainAuth(bigBrainAuth);\n return;\n }\n ctx._updateBigBrainAuth(\n await getBigBrainAuth(ctx, {\n previewDeployKey: null,\n projectKey: null,\n deploymentKey: null,\n }),\n );\n return;\n}\n\nexport async function updateBigBrainAuthAfterLogin(\n ctx: Context,\n accessToken: string,\n profile?: ProfileSelection,\n) {\n const existingAuth = ctx.bigBrainAuth();\n if (existingAuth !== null && existingAuth.kind === \"projectKey\") {\n logVerbose(\n `Ignoring update to big brain auth since project key takes precedence`,\n );\n return;\n }\n ctx._updateBigBrainAuth({\n accessToken: accessToken,\n kind: \"accessToken\",\n header: `Bearer ${accessToken}`,\n ...(profile ? { profile } : {}),\n });\n}\n\nexport async function clearBigBrainAuth(ctx: Context) {\n ctx._updateBigBrainAuth(null);\n}\n\nasync function getBigBrainAuth(\n ctx: Context,\n opts: {\n previewDeployKey: string | null;\n projectKey: string | null;\n deploymentKey: string | null;\n envFile?: string;\n skipProfile?: boolean;\n },\n): Promise<BigBrainAuth | null> {\n if (process.env.CONVEX_OVERRIDE_ACCESS_TOKEN) {\n return {\n accessToken: process.env.CONVEX_OVERRIDE_ACCESS_TOKEN,\n kind: \"accessToken\",\n header: `Bearer ${process.env.CONVEX_OVERRIDE_ACCESS_TOKEN}`,\n profile: null,\n };\n }\n if (opts.projectKey !== null) {\n // Project keys take precedence over global config.\n return {\n header: `Bearer ${opts.projectKey}`,\n kind: \"projectKey\",\n projectKey: opts.projectKey,\n };\n }\n if (opts.deploymentKey !== null) {\n // Deployment keys take precedence over global config.\n return {\n header: `Bearer ${opts.deploymentKey}`,\n kind: \"deploymentKey\",\n deploymentKey: opts.deploymentKey,\n };\n }\n const profile = opts.skipProfile\n ? null\n : await getProfileSelection(ctx, { envFile: opts.envFile });\n if (profile !== null) {\n return await readProfileAuth(ctx, profile);\n }\n const globalConfig = readGlobalConfig(ctx);\n if (globalConfig) {\n return {\n kind: \"accessToken\",\n header: `Bearer ${globalConfig.accessToken}`,\n accessToken: globalConfig.accessToken,\n profile: null,\n };\n }\n if (opts.previewDeployKey !== null) {\n return {\n header: `Bearer ${opts.previewDeployKey}`,\n kind: \"previewDeployKey\",\n previewDeployKey: opts.previewDeployKey,\n };\n }\n return null;\n}\n\n// These guards mirror the management API's auth rules client-side so we can\n// fail with a clear message instead of an opaque 401; the server stays\n// authoritative. Creating a deployment also allows project keys, while the\n// deploy-key commands stay personal-access-token only.\n\n/** Crashes unless logged in with a personal access token (not a deploy key). */\nexport async function ensureLoggedInWithAccessToken(\n ctx: Context,\n action: string,\n): Promise<void> {\n const auth = ctx.bigBrainAuth();\n if (auth !== null && auth.kind === \"accessToken\") {\n return;\n }\n // Name whichever deploy-key env var is in effect (CONVEX_DEPLOY_KEY wins).\n const prefix =\n auth === null\n ? \"Run \"\n : process.env[CONVEX_DEPLOYMENT_TOKEN_ENV_VAR_NAME] &&\n !process.env[CONVEX_DEPLOY_KEY_ENV_VAR_NAME]\n ? `Unset ${CONVEX_DEPLOYMENT_TOKEN_ENV_VAR_NAME} and run `\n : `Unset ${CONVEX_DEPLOY_KEY_ENV_VAR_NAME} and run `;\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: `${action} requires being logged in with a personal access token. ${prefix}${chalkStderr.bold(\n \"npx convex login\",\n )} and try again.`,\n });\n}\n\n/**\n * Crashes unless the auth can create a deployment: personal access tokens and\n * project keys are accepted, deploy keys are not.\n */\nexport async function ensureAuthCanCreateDeployment(\n ctx: Context,\n): Promise<void> {\n const auth = ctx.bigBrainAuth();\n if (\n auth !== null &&\n (auth.kind === \"accessToken\" || auth.kind === \"projectKey\")\n ) {\n return;\n }\n if (auth === null) {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: `Creating a deployment requires logging in. Run ${chalkStderr.bold(\n \"npx convex login\",\n )} and try again.`,\n });\n }\n const envVar =\n readDeployKeyEnvVar((name) => process.env[name])?.name ??\n CONVEX_DEPLOY_KEY_ENV_VAR_NAME;\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: `Creating a deployment isn't supported with a deploy key (${envVar}). Run ${chalkStderr.bold(\n \"npx convex login\",\n )} (or use a project key) and try again.`,\n });\n}\n\n// ----------------------------------------------------------------------------\n// Deployment Selection\n// ----------------------------------------------------------------------------\n/**\n * Our CLI has logic to select which deployment to act on.\n *\n * We first check whether we're targeting a deployment within a project, or if we\n * know exactly which deployment to act on (e.g. in the case of self-hosting).\n *\n * We also special case preview deploys since the presence of a preview deploy key\n * triggers different behavior in `npx convex deploy`.\n *\n * Most commands will immediately compute the deployment selection, and then combine\n * that with any relevant CLI flags to figure out which deployment to talk to.\n *\n * Different commands do different things (e.g. `dev` will allow you to create a new project,\n * `deploy` has different behavior for preview deploys)\n *\n * This should be kept in sync with `initializeBigBrainAuth` since environment variables\n * like `CONVEX_DEPLOY_KEY` are used for both deployment selection and auth.\n */\nexport type DeploymentSelection =\n | {\n kind: \"existingDeployment\";\n deploymentToActOn: {\n url: string;\n adminKey: string;\n } & (\n | {\n deploymentFields: DeploymentFields;\n source: \"deployKey\";\n }\n | {\n deploymentFields: null;\n source: \"selfHosted\" | \"cliArgs\";\n }\n );\n }\n | {\n kind: \"deploymentWithinProject\";\n targetProject: ProjectSelection;\n selectionWithinProject: DeploymentSelectionWithinProject;\n }\n | {\n kind: \"preview\";\n previewDeployKey: string;\n selectionWithinProject: DeploymentSelectionWithinProject;\n }\n | {\n kind: \"chooseProject\";\n selectionWithinProject: DeploymentSelectionWithinProject;\n }\n | {\n kind: \"anonymous\";\n deploymentName: string | null;\n selectionWithinProject: DeploymentSelectionWithinProject;\n };\n\ntype DeploymentFields = {\n deploymentName: string;\n deploymentType: DeploymentType;\n projectSlug: string;\n teamSlug: string;\n reference: string | null;\n isDefault: boolean;\n};\n\nexport type ProjectSelection =\n | {\n kind: \"teamAndProjectSlugs\";\n teamSlug: string;\n projectSlug: string;\n }\n | {\n kind: \"deploymentName\";\n deploymentName: string;\n deploymentType: AccountRequiredDeploymentType | null;\n }\n | {\n kind: \"projectDeployKey\";\n projectDeployKey: string;\n };\n\nexport async function getDeploymentSelection(\n ctx: Context,\n cliArgs: DeploymentSelectionOptions,\n): Promise<DeploymentSelection> {\n const metadata = await _getDeploymentSelection(ctx, cliArgs);\n if (metadata.kind === \"existingDeployment\") {\n const selectionWithinProject =\n deploymentSelectionWithinProjectFromOptions(cliArgs);\n await validateDeploymentSelectionForExistingDeployment(\n ctx,\n selectionWithinProject,\n metadata.deploymentToActOn.source,\n );\n }\n logDeploymentSelection(ctx, metadata);\n return metadata;\n}\n\nfunction logDeploymentSelection(_ctx: Context, selection: DeploymentSelection) {\n switch (selection.kind) {\n case \"existingDeployment\": {\n logVerbose(\n `Existing deployment: ${selection.deploymentToActOn.url} ${selection.deploymentToActOn.source}`,\n );\n break;\n }\n case \"deploymentWithinProject\": {\n logVerbose(\n `Deployment within project: ${prettyProjectSelection(selection.targetProject)}`,\n );\n break;\n }\n case \"preview\": {\n logVerbose(`Preview deploy key`);\n break;\n }\n case \"chooseProject\": {\n logVerbose(`Choose project`);\n break;\n }\n case \"anonymous\": {\n logVerbose(\n `Anonymous, has selected deployment?: ${selection.deploymentName !== null}`,\n );\n break;\n }\n default: {\n selection satisfies never;\n logVerbose(`Unknown deployment selection`);\n }\n }\n return null;\n}\n\nfunction prettyProjectSelection(selection: ProjectSelection) {\n switch (selection.kind) {\n case \"teamAndProjectSlugs\": {\n return `Team and project slugs: ${selection.teamSlug} ${selection.projectSlug}`;\n }\n case \"deploymentName\": {\n return `Deployment name: ${selection.deploymentName}`;\n }\n case \"projectDeployKey\": {\n return `Project deploy key`;\n }\n default: {\n selection satisfies never;\n return `Unknown`;\n }\n }\n}\n\nasync function _getDeploymentSelection(\n ctx: Context,\n cliArgs: DeploymentSelectionOptions,\n): Promise<DeploymentSelection> {\n const selectionWithinProject =\n deploymentSelectionWithinProjectFromOptions(cliArgs);\n /*\n - url + adminKey specified via CLI\n - Do not check any env vars (including ones relevant for auth)\n */\n if (cliArgs.url !== undefined && cliArgs.adminKey !== undefined) {\n return {\n kind: \"existingDeployment\",\n deploymentToActOn: {\n url: cliArgs.url,\n adminKey: cliArgs.adminKey,\n deploymentFields: null,\n source: \"cliArgs\",\n },\n };\n }\n\n // If --deployment is a fully qualified selector (team:project:ref or\n // deployment name), we don't need a current project context \u2192 handle it\n // before env var resolution.\n if (cliArgs.deployment !== undefined) {\n const parsed = parseDeploymentSelector(cliArgs.deployment);\n if (parsed.kind === \"inTeamProject\" && parsed.selector.kind !== \"local\") {\n return {\n kind: \"deploymentWithinProject\",\n targetProject: {\n kind: \"teamAndProjectSlugs\",\n teamSlug: parsed.teamSlug,\n projectSlug: parsed.projectSlug,\n },\n selectionWithinProject: {\n kind: \"deploymentSelector\",\n selector: cliArgs.deployment,\n },\n };\n }\n if (parsed.kind === \"deploymentName\") {\n return {\n kind: \"deploymentWithinProject\",\n targetProject: {\n kind: \"deploymentName\",\n deploymentName: parsed.deploymentName,\n deploymentType: null,\n },\n selectionWithinProject: {\n kind: \"deploymentSelector\",\n selector: cliArgs.deployment,\n },\n };\n }\n if (parsed.kind === \"inTeamProject\" && parsed.selector.kind === \"local\") {\n // team:project:local \u2014 we have the cloud project context up front and\n // don't need to consult env vars at all.\n return await resolveLocalDeploymentSelection(\n ctx,\n parsed,\n selectionWithinProject,\n null,\n );\n }\n }\n\n const baseSelection = await resolveBaseDeploymentSelection(\n ctx,\n cliArgs,\n selectionWithinProject,\n );\n\n // If --deployment is a project-scoped local selector (`local` or\n // `project:local`), override the env-var-derived selection with the local\n // deployment after performing a cloud-project-mismatch check.\n if (cliArgs.deployment !== undefined) {\n const parsed = parseDeploymentSelector(cliArgs.deployment);\n if (\n (parsed.kind === \"inCurrentProject\" || parsed.kind === \"inProject\") &&\n parsed.selector.kind === \"local\"\n ) {\n return await resolveLocalDeploymentSelection(\n ctx,\n parsed,\n selectionWithinProject,\n baseSelection,\n );\n }\n }\n\n return baseSelection;\n}\n\nasync function resolveBaseDeploymentSelection(\n ctx: Context,\n cliArgs: DeploymentSelectionOptions,\n selectionWithinProject: DeploymentSelectionWithinProject,\n): Promise<DeploymentSelection> {\n if (cliArgs.envFile !== undefined) {\n // If an `--env-file` is specified, it must contain enough information for both auth and deployment selection.\n logVerbose(`Checking env file: ${cliArgs.envFile}`);\n const existingFile = ctx.fs.exists(cliArgs.envFile)\n ? ctx.fs.readUtf8File(cliArgs.envFile)\n : null;\n if (existingFile === null) {\n return ctx.crash({\n exitCode: 1,\n errorType: \"invalid filesystem or env vars\",\n printedMessage: \"env file does not exist\",\n });\n }\n const config = dotenv.parse(existingFile);\n const result = await getDeploymentSelectionFromEnv(\n ctx,\n selectionWithinProject,\n (name) =>\n config[name] === undefined || config[name] === \"\" ? null : config[name],\n );\n if (result.kind === \"unknown\") {\n return ctx.crash({\n exitCode: 1,\n errorType: \"invalid filesystem or env vars\",\n printedMessage:\n `env file \\`${cliArgs.envFile}\\` did not contain environment variables for a Convex deployment. ` +\n `Expected \\`${CONVEX_DEPLOY_KEY_ENV_VAR_NAME}\\`, \\`${CONVEX_DEPLOYMENT_ENV_VAR_NAME}\\`, or both \\`${CONVEX_SELF_HOSTED_URL_VAR_NAME}\\` and \\`${CONVEX_SELF_HOSTED_ADMIN_KEY_VAR_NAME}\\` to be set.`,\n });\n }\n return result.metadata;\n }\n loadProjectEnvironmentVariables();\n const result = await getDeploymentSelectionFromEnv(\n ctx,\n selectionWithinProject,\n (name) => {\n const value = process.env[name];\n if (value === undefined || value === \"\") {\n return null;\n }\n return value;\n },\n );\n if (result.kind !== \"unknown\") {\n return result.metadata;\n }\n // none of these?\n\n const isLoggedIn = ctx.bigBrainAuth() !== null;\n if (\n (!isLoggedIn ||\n process.env.CONVEX_AGENT_MODE === \"anonymous\" ||\n !process.stdin.isTTY) &&\n !cliArgs.implicitProd &&\n shouldAllowAnonymousDevelopment()\n ) {\n return {\n kind: \"anonymous\",\n deploymentName: null,\n selectionWithinProject,\n };\n }\n\n // Choose a project interactively later\n return {\n kind: \"chooseProject\",\n selectionWithinProject,\n };\n}\n\n/**\n * Handles the `[team:project:]local` selector. Loads the on-disk local config\n * and (if the config has a `cloudProjectId`) verifies it matches the cloud\n * project the user is asking about. Crashes on mismatch.\n */\nasync function resolveLocalDeploymentSelection(\n ctx: Context,\n parsed: ParsedDeploymentSelector,\n selectionWithinProject: DeploymentSelectionWithinProject,\n currentSelection: DeploymentSelection | null,\n): Promise<DeploymentSelection> {\n const localConfig = loadProjectLocalConfig(ctx);\n if (localConfig === null) {\n return ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: `No local deployment found. Run ${chalkStderr.bold(\"npx convex deployment create local\")} to create one.`,\n });\n }\n // Only resolve the target cloud project if the on-disk config has a\n // `cloudProjectId` to compare against \u2014 this avoids unnecessary platform\n // calls for older configs and anonymous mode.\n if (localConfig.config.cloudProjectId !== undefined) {\n const target = await targetProjectForLocalSelector(\n ctx,\n parsed,\n currentSelection ?? { kind: \"chooseProject\", selectionWithinProject },\n );\n if (target !== null) {\n const match = checkLocalConfigMatchesProject(\n ctx,\n localConfig.config,\n target,\n );\n if (match === \"mismatch\") {\n const newSelector = `${target.teamSlug}:${target.slug}:local`;\n return ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage:\n `The local deployment in this directory is in a different project than \\`${target.teamSlug}:${target.slug}\\`. ` +\n `\\n${chalkStderr.dim(`${chalkStderr.bold(\"Hint\")}: If you want to move the local deployment to this project, run ${chalkStderr.bold(`npx convex deployment select ${newSelector}`)}`)}`,\n });\n }\n }\n }\n return {\n kind: \"deploymentWithinProject\",\n targetProject: {\n kind: \"deploymentName\",\n deploymentName: localConfig.deploymentName,\n deploymentType: \"local\",\n },\n selectionWithinProject,\n };\n}\n\nasync function getDeploymentSelectionFromEnv(\n ctx: Context,\n selectionWithinProject: DeploymentSelectionWithinProject,\n getEnv: (name: string) => string | null,\n): Promise<\n { kind: \"success\"; metadata: DeploymentSelection } | { kind: \"unknown\" }\n> {\n const rawDeployKey = readDeployKeyFromEnv(getEnv);\n const deployKey = await processDeployKeyValue(ctx, rawDeployKey);\n if (deployKey !== undefined) {\n const deployKeyType = isPreviewDeployKey(deployKey)\n ? \"preview\"\n : isProjectKey(deployKey)\n ? \"project\"\n : \"deployment\";\n switch (deployKeyType) {\n case \"preview\": {\n // `CONVEX_DEPLOY_KEY` is set to a preview deploy key so this takes precedence over anything else.\n // At the moment, we don't verify that there aren't other env vars that would also be used for deployment selection (e.g. `CONVEX_DEPLOYMENT`)\n return {\n kind: \"success\",\n metadata: {\n kind: \"preview\",\n previewDeployKey: deployKey,\n selectionWithinProject,\n },\n };\n }\n case \"project\": {\n // `CONVEX_DEPLOY_KEY` is set to a project deploy key.\n // Commands can select any deployment within the project. At the moment we don't check for other env vars (e.g. `CONVEX_DEPLOYMENT`)\n return {\n kind: \"success\",\n metadata: {\n kind: \"deploymentWithinProject\",\n targetProject: {\n kind: \"projectDeployKey\",\n projectDeployKey: deployKey,\n },\n selectionWithinProject,\n },\n };\n }\n case \"deployment\": {\n // `CONVEX_DEPLOY_KEY` is set to a deployment's deploy key.\n // Deploy to this deployment -- selectors like `--prod` / `--preview-name` will be ignored.\n // At the moment, we don't verify that there aren't other env vars that would also be used for deployment selection (e.g. `CONVEX_DEPLOYMENT`)\n const deploymentName = await deploymentNameFromAdminKeyOrCrash(\n ctx,\n deployKey,\n );\n const deploymentType = deploymentTypeFromAdminKey(deployKey);\n // We cannot derive the deployment URL from the deploy key, because it\n // might be a custom domain. Ask big brain for the URL.\n const url = await bigBrainAPI({\n ctx,\n method: \"POST\",\n path: \"deployment/url_for_key\",\n data: {\n deployKey: deployKey,\n },\n });\n const slugs = await fetchTeamAndProjectForKey(ctx, deployKey);\n return {\n kind: \"success\",\n metadata: {\n kind: \"existingDeployment\",\n deploymentToActOn: {\n url: url,\n adminKey: deployKey,\n deploymentFields: {\n deploymentName: deploymentName,\n deploymentType: deploymentType,\n teamSlug: slugs.team,\n projectSlug: slugs.project,\n reference: slugs.reference,\n isDefault: slugs.isDefault,\n },\n source: \"deployKey\",\n },\n },\n };\n }\n default: {\n deployKeyType satisfies never;\n return ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: `Unexpected deploy key type: ${deployKeyType as any}`,\n });\n }\n }\n }\n\n const convexDeployment = getEnv(CONVEX_DEPLOYMENT_ENV_VAR_NAME);\n const selfHostedUrl = getEnv(CONVEX_SELF_HOSTED_URL_VAR_NAME);\n const selfHostedAdminKey = getEnv(CONVEX_SELF_HOSTED_ADMIN_KEY_VAR_NAME);\n\n if (selfHostedUrl !== null && selfHostedAdminKey !== null) {\n if (convexDeployment !== null) {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"invalid filesystem or env vars\",\n printedMessage: `${CONVEX_DEPLOYMENT_ENV_VAR_NAME} must not be set when ${CONVEX_SELF_HOSTED_URL_VAR_NAME} and ${CONVEX_SELF_HOSTED_ADMIN_KEY_VAR_NAME} are set`,\n });\n }\n return {\n kind: \"success\",\n metadata: {\n kind: \"existingDeployment\",\n deploymentToActOn: {\n url: selfHostedUrl,\n adminKey: selfHostedAdminKey,\n deploymentFields: null,\n source: \"selfHosted\",\n },\n },\n };\n }\n\n // --deployment-name\u2019s deployment may be in a different project from CONVEX_DEPLOYMENT.\n if (selectionWithinProject.kind === \"deploymentName\") {\n return {\n kind: \"success\",\n metadata: {\n kind: \"deploymentWithinProject\",\n targetProject: {\n kind: \"deploymentName\",\n deploymentName: selectionWithinProject.deploymentName,\n deploymentType: null,\n },\n selectionWithinProject,\n },\n };\n }\n\n if (convexDeployment !== null) {\n if (selfHostedUrl !== null || selfHostedAdminKey !== null) {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"invalid filesystem or env vars\",\n printedMessage: `${CONVEX_SELF_HOSTED_URL_VAR_NAME} and ${CONVEX_SELF_HOSTED_ADMIN_KEY_VAR_NAME} must not be set when ${CONVEX_DEPLOYMENT_ENV_VAR_NAME} is set`,\n });\n }\n const targetDeploymentType =\n getDeploymentTypeFromConfiguredDeployment(convexDeployment);\n\n // Commands can select a deployment within the project that this deployment belongs to.\n const targetDeploymentName = stripDeploymentTypePrefix(convexDeployment);\n const isAnonymous = isAnonymousDeployment(targetDeploymentName);\n if (isAnonymous) {\n if (!shouldAllowAnonymousDevelopment()) {\n return {\n kind: \"unknown\",\n };\n }\n return {\n kind: \"success\",\n metadata: {\n kind: \"anonymous\",\n deploymentName: targetDeploymentName,\n selectionWithinProject,\n },\n };\n }\n\n // Overwrite the selection within project\n const newSelectionWithinProject =\n selectionWithinProject.kind === \"unspecified\" &&\n // Fetching local deployment credentials uses the \"unspecified\" code path\n targetDeploymentType !== \"local\"\n ? {\n kind: \"deploymentName\" as const,\n deploymentName: targetDeploymentName,\n }\n : selectionWithinProject;\n return {\n kind: \"success\",\n metadata: {\n kind: \"deploymentWithinProject\",\n targetProject: {\n kind: \"deploymentName\",\n deploymentName: targetDeploymentName,\n deploymentType: targetDeploymentType,\n },\n selectionWithinProject: newSelectionWithinProject,\n },\n };\n }\n\n // Throw a nice error if we're in something like a CI environment where we need a valid deployment configuration\n await checkIfBuildEnvironmentRequiresDeploymentConfig(ctx);\n\n return { kind: \"unknown\" };\n}\n\nasync function checkIfBuildEnvironmentRequiresDeploymentConfig(ctx: Context) {\n const buildEnvironment = getBuildEnvironment();\n if (buildEnvironment) {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage:\n `${buildEnvironment} build environment detected but no Convex deployment configuration found.\\n` +\n `Set one of:\\n` +\n ` \u2022 ${CONVEX_DEPLOY_KEY_ENV_VAR_NAME} for Convex Cloud deployments\\n` +\n ` \u2022 ${CONVEX_SELF_HOSTED_URL_VAR_NAME} and ${CONVEX_SELF_HOSTED_ADMIN_KEY_VAR_NAME} for self-hosted deployments\\n` +\n `See https://docs.convex.dev/production/hosting or https://docs.convex.dev/self-hosting`,\n });\n }\n}\n\n/**\n * Used for things like `npx convex docs` where we want to best effort extract a deployment name\n * but don't do the full deployment selection logic.\n */\nexport const deploymentNameFromSelection = (\n selection: DeploymentSelection,\n): string | null => {\n return deploymentNameAndTypeFromSelection(selection)?.name ?? null;\n};\n\nexport const deploymentNameAndTypeFromSelection = (\n selection: DeploymentSelection,\n): { name: string | null; type: string | null } | null => {\n switch (selection.kind) {\n case \"existingDeployment\": {\n return {\n name:\n selection.deploymentToActOn.deploymentFields?.deploymentName ?? null,\n type:\n selection.deploymentToActOn.deploymentFields?.deploymentType ?? null,\n };\n }\n case \"deploymentWithinProject\": {\n return selection.targetProject.kind === \"deploymentName\"\n ? {\n name: selection.targetProject.deploymentName,\n type: selection.targetProject.deploymentType,\n }\n : null;\n }\n case \"preview\": {\n return null;\n }\n case \"chooseProject\": {\n return null;\n }\n case \"anonymous\": {\n return null;\n }\n default: {\n selection satisfies never;\n }\n }\n return null;\n};\n\nexport const shouldAllowAnonymousDevelopment = (): boolean => {\n // Kill switch / temporary opt out\n if (process.env.CONVEX_ALLOW_ANONYMOUS === \"false\") {\n return false;\n }\n return true;\n};\n\n/**\n * Fetch the project details corresponding to the given ProjectSelection.\n */\nexport async function getProjectDetails(\n ctx: Context,\n projectSelection: ProjectSelection,\n): Promise<ProjectResponse> {\n switch (projectSelection.kind) {\n case \"deploymentName\": {\n if (projectSelection.deploymentType === \"local\") {\n const result = await getTeamAndProjectSlugForDeployment(ctx, {\n deploymentName: projectSelection.deploymentName,\n });\n if (result === null) {\n return ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage:\n \"You don't have access to the selected project. Run `npx convex dev` to select a different project.\",\n });\n }\n return await getProjectDetails(ctx, {\n kind: \"teamAndProjectSlugs\",\n teamSlug: result.teamSlug,\n projectSlug: result.projectSlug,\n });\n }\n\n const deployment = (\n await typedPlatformClient(ctx).GET(\"/deployments/{deployment_name}\", {\n params: {\n path: { deployment_name: projectSelection.deploymentName },\n },\n })\n ).data!;\n return (\n await typedPlatformClient(ctx).GET(\"/projects/{project_id}\", {\n params: { path: { project_id: deployment.projectId } },\n })\n ).data!;\n }\n case \"teamAndProjectSlugs\": {\n return (\n await typedPlatformClient(ctx).GET(\n \"/teams/{team_id_or_slug}/projects/{project_slug}\",\n {\n params: {\n path: {\n team_id_or_slug: projectSelection.teamSlug,\n project_slug: projectSelection.projectSlug,\n },\n },\n },\n )\n ).data!;\n }\n case \"projectDeployKey\": {\n const result = await fetchTeamAndProjectForKey(\n ctx,\n projectSelection.projectDeployKey,\n );\n return (\n await typedPlatformClient(ctx).GET(\"/projects/{project_id}\", {\n params: { path: { project_id: result.projectId } },\n })\n ).data!;\n }\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["rawDeployKey", "deployKey", "result"]
|
|
7
7
|
}
|
package/dist/esm/cli/lib/dev.js
CHANGED
|
@@ -101,6 +101,11 @@ export async function devAgainstDeployment(ctx, credentials, devOptions) {
|
|
|
101
101
|
// Pass logManager to control logs during deploy
|
|
102
102
|
largeIndexDeletionCheck: "no verification",
|
|
103
103
|
// `convex dev` can’t push to prod
|
|
104
|
+
// `convex dev --prod` pushes straight to production, where an
|
|
105
|
+
// unstaged index on a large table blocks the push for the whole
|
|
106
|
+
// backfill; dev deployments are small enough to let it through.
|
|
107
|
+
largeIndexBackfillCheck: credentials.deploymentType === "prod" ? "ask for confirmation" : "no verification",
|
|
108
|
+
stagedValidatorDeletionCheck: credentials.deploymentType === "prod" ? devOptions.allowUnstagingSchema ? "has confirmation" : "ask for confirmation" : "no verification",
|
|
104
109
|
warnOnSlowSchemaValidation: true,
|
|
105
110
|
message: null
|
|
106
111
|
},
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/cli/lib/dev.ts"],
|
|
4
|
-
"sourcesContent": ["import { chalkStderr } from \"chalk\";\nimport { spawn, ChildProcess } from \"child_process\";\nimport { OneoffCtx } from \"../../bundler/context.js\";\nimport {\n logError,\n logFinishedStep,\n logMessage,\n logWarning,\n showSpinner,\n showSpinnerIfSlow,\n stopSpinner,\n} from \"../../bundler/log.js\";\nimport { runPush } from \"./components.js\";\nimport { performance } from \"perf_hooks\";\nimport path from \"path\";\nimport { LogManager, LogMode, watchLogs } from \"./logs.js\";\nimport { PushOptions } from \"./components.js\";\nimport {\n formatDuration,\n getCurrentTimeString,\n waitForever,\n waitUntilCalled,\n} from \"./utils/utils.js\";\nimport { Crash, WatchContext, Watcher } from \"./watch.js\";\nimport { runFunctionAndLog, subscribe } from \"./run.js\";\nimport { Value } from \"../../values/index.js\";\nimport { DeploymentType } from \"./api.js\";\nimport { readProjectConfig, getAuthKitConfig } from \"./config.js\";\nimport {\n syncAuthKitConfigAfterPush,\n ensureAuthKitProvisionedBeforeBuild,\n} from \"./workos/workos.js\";\nimport { handleDashboard } from \"./localDeployment/dashboard.js\";\nimport { loadDeploymentConfig } from \"./localDeployment/filePaths.js\";\nimport { LocalDeploymentError } from \"./localDeployment/errors.js\";\n\nexport async function devAgainstDeployment(\n ctx: OneoffCtx,\n credentials: {\n url: string;\n adminKey: string;\n deploymentName: string | null;\n deploymentType?: DeploymentType;\n backendVersion?: string | undefined;\n },\n devOptions: {\n verbose: boolean;\n typecheck: \"enable\" | \"try\" | \"disable\";\n typecheckComponents: boolean;\n codegen: boolean;\n once: boolean;\n untilSuccess: boolean;\n run?:\n | { kind: \"function\"; name: string; component?: string | undefined }\n | { kind: \"shell\"; command: string }\n | undefined;\n tailLogs: LogMode;\n traceEvents: boolean;\n debugBundlePath?: string | undefined;\n debugNodeApis: boolean;\n liveComponentSources: boolean;\n pushAllModules: boolean;\n },\n) {\n const logManager = new LogManager(devOptions.tailLogs);\n\n // Pre-flight check: Ensure AuthKit is provisioned before starting dev\n const { projectConfig } = await readProjectConfig(ctx);\n const authKitConfig = await getAuthKitConfig(ctx, projectConfig);\n\n if (authKitConfig && credentials.deploymentName) {\n // Only provision for cloud deployments (dev/preview/prod)\n // Skip for local and anonymous deployments\n const deploymentType = credentials.deploymentType;\n if (\n deploymentType === \"dev\" ||\n deploymentType === \"preview\" ||\n deploymentType === \"prod\"\n ) {\n await ensureAuthKitProvisionedBeforeBuild(\n ctx,\n credentials.deploymentName,\n { deploymentUrl: credentials.url, adminKey: credentials.adminKey },\n deploymentType,\n );\n }\n }\n\n // Anonymous mode starts a local dashboard server alongside long-running `npx convex dev` commands.\n if (\n !devOptions.once &&\n !devOptions.untilSuccess &&\n credentials.deploymentType === \"anonymous\" &&\n credentials.deploymentName !== null\n ) {\n const deploymentConfig = loadDeploymentConfig(\n ctx,\n \"anonymous\",\n credentials.deploymentName,\n );\n if (deploymentConfig === null) {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: `Could not find local deployment config. This is a bug in Convex.`,\n errForSentry: new LocalDeploymentError(\n `Could not find local deployment config to start the anonymous dashboard.`,\n ),\n });\n }\n await handleDashboard(\n ctx,\n {\n name: credentials.deploymentName,\n cloudPort: deploymentConfig.ports.cloud,\n adminKey: deploymentConfig.adminKey,\n },\n {\n backendVersion: credentials.backendVersion,\n },\n );\n }\n\n const promises = [];\n if (devOptions.tailLogs !== \"disable\") {\n promises.push(\n watchLogs(ctx, credentials.url, credentials.adminKey, \"stderr\", {\n logManager,\n success: false,\n }),\n );\n }\n\n promises.push(\n watchAndPush(\n ctx,\n {\n ...credentials,\n verbose: devOptions.verbose,\n dryRun: false,\n typecheck: devOptions.typecheck,\n typecheckComponents: devOptions.typecheckComponents,\n debug: false,\n debugBundlePath: devOptions.debugBundlePath,\n debugNodeApis: devOptions.debugNodeApis,\n codegen: devOptions.codegen,\n liveComponentSources: devOptions.liveComponentSources,\n pushAllModules: devOptions.pushAllModules,\n logManager, // Pass logManager to control logs during deploy\n largeIndexDeletionCheck: \"no verification\", // `convex dev` can\u2019t push to prod\n warnOnSlowSchemaValidation: true,\n message: null,\n },\n devOptions,\n ),\n );\n await Promise.race(promises);\n await ctx.flushAndExit(0);\n}\n\nexport async function watchAndPush(\n outerCtx: OneoffCtx,\n options: PushOptions,\n cmdOptions: {\n run?:\n | { kind: \"function\"; name: string; component?: string | undefined }\n | { kind: \"shell\"; command: string }\n | undefined;\n once: boolean;\n untilSuccess: boolean;\n traceEvents: boolean;\n },\n) {\n const watch: { watcher: Watcher | undefined } = { watcher: undefined };\n const authKitCache: { lastAppliedConfig: string | undefined } = {\n lastAppliedConfig: undefined,\n };\n let numFailures = 0;\n let ran = false;\n let pushed = false;\n let shellChild: ChildProcess | undefined;\n let shellExited: Promise<void> | undefined;\n let shellCleanupHandle: string | undefined;\n let shellSigintListener: (() => void) | undefined;\n let tableNameTriggeringRetry;\n let shouldRetryOnDeploymentEnvVarChange;\n let isFirstPush = true; // Track if this is the first push in the session\n\n try {\n while (true) {\n const start = performance.now();\n tableNameTriggeringRetry = null;\n shouldRetryOnDeploymentEnvVarChange = false;\n\n const ctx = new WatchContext(\n cmdOptions.traceEvents,\n outerCtx.bigBrainAuth(),\n isFirstPush,\n );\n options.logManager?.beginDeploy();\n showSpinner(\"Preparing Convex functions...\");\n try {\n await runPush(ctx, options);\n const end = performance.now();\n // NOTE: If `runPush` throws, `endDeploy` will not be called.\n // This allows you to see the output from the failed deploy without\n // logs getting in the way.\n options.logManager?.endDeploy();\n numFailures = 0;\n logFinishedStep(\n `${getCurrentTimeString()} Convex functions ready! (${formatDuration(\n end - start,\n )})`,\n );\n\n // Sync AuthKit configuration if it has changed\n const { projectConfig } = await readProjectConfig(ctx);\n const authKitConfig = await getAuthKitConfig(ctx, projectConfig);\n\n // Check if config has changed by comparing stringified versions\n const currentConfigString = authKitConfig\n ? JSON.stringify(authKitConfig)\n : undefined;\n\n // Skip sync on first push since ensureAuthKitProvisionedBeforeBuild already configured WorkOS\n if (\n !isFirstPush &&\n currentConfigString !== authKitCache.lastAppliedConfig\n ) {\n // Config has changed, sync it\n await syncAuthKitConfigAfterPush(ctx, projectConfig, {\n deploymentUrl: options.url,\n adminKey: options.adminKey,\n });\n }\n\n // Always update cache after push (even if we skipped sync)\n authKitCache.lastAppliedConfig = currentConfigString;\n isFirstPush = false;\n if (cmdOptions.run !== undefined && !ran) {\n switch (cmdOptions.run.kind) {\n case \"function\":\n await runFunctionInDev(\n ctx,\n options,\n cmdOptions.run.name,\n cmdOptions.run.component,\n );\n break;\n case \"shell\": {\n // Spawn the shell command as a long-running child process,\n // piping stdin/stdout/stderr. It runs alongside dev and is\n // waited on during clean exit or killed on signal exit.\n const shellCommand = cmdOptions.run.command;\n const signalShellChild = (signal: NodeJS.Signals) => {\n if (!shellChild) {\n return;\n }\n const child = shellChild;\n // Kill the entire process group so children of the shell\n // are also killed.\n try {\n if (child.pid !== undefined) {\n // Kill the negative PID to signal the entire process\n // group. Falls back to the child directly if the\n // group is already gone.\n try {\n process.kill(-child.pid, signal);\n } catch {\n child.kill(signal);\n }\n } else {\n child.kill(signal);\n }\n } catch {\n // Child may already be dead.\n }\n };\n const clearShellSigintListener = () => {\n if (shellSigintListener) {\n process.off(\"SIGINT\", shellSigintListener);\n shellSigintListener = undefined;\n }\n };\n shellChild = spawn(shellCommand, [], {\n shell: true,\n stdio: \"inherit\",\n detached: true,\n });\n shellSigintListener = () => {\n clearShellSigintListener();\n signalShellChild(\"SIGINT\");\n };\n process.prependListener(\"SIGINT\", shellSigintListener);\n shellCleanupHandle = outerCtx.registerCleanup(async () => {\n if (shellSigintListener) {\n clearShellSigintListener();\n } else {\n // If the listener already fired (and cleared itself),\n // the child got SIGINT \u2014 give it a moment to exit on\n // its own before escalating to SIGTERM.\n const SIGTERM_ESCALATION_MS = 1000;\n await Promise.race([\n shellExited,\n new Promise((resolve) =>\n setTimeout(resolve, SIGTERM_ESCALATION_MS),\n ),\n ]);\n }\n if (shellChild) {\n signalShellChild(\"SIGTERM\");\n }\n await shellExited;\n });\n shellExited = new Promise<void>((resolve) => {\n shellChild!.on(\"error\", (error) => {\n logError(\n `Failed to run command \\`${shellCommand}\\`: ${error.message}`,\n );\n shellChild = undefined;\n resolve();\n void outerCtx.flushAndExit(1);\n });\n shellChild!.on(\"exit\", (code, signal) => {\n shellChild = undefined;\n resolve();\n // If killed by a signal (e.g. from cleanup on shutdown),\n // don't treat it as a failure \u2014 convex dev is already\n // shutting down.\n if (signal) {\n return;\n }\n if (code !== null && code !== 0) {\n logError(\n `Command \\`${shellCommand}\\` exited with code ${code}`,\n );\n void outerCtx.flushAndExit(1);\n }\n });\n });\n break;\n }\n default: {\n cmdOptions.run satisfies never;\n // Don't return this since it'll bypass the `catch` below.\n await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: `Unexpected arguments for --run`,\n errForSentry: `Unexpected arguments for --run: ${JSON.stringify(\n cmdOptions.run,\n )}`,\n });\n }\n }\n ran = true;\n }\n pushed = true;\n } catch (e: any) {\n // Crash the app on unexpected errors.\n if (!(e instanceof Crash) || !e.errorType) {\n // eslint-disable-next-line no-restricted-syntax\n throw e;\n }\n if (e.errorType === \"fatal\") {\n break;\n }\n // Retry after an exponential backoff if we hit a transient error.\n if (e.errorType === \"transient\" || e.errorType === \"already handled\") {\n const delay = nextBackoff(numFailures);\n numFailures += 1;\n if (e.errorType === \"transient\") {\n logWarning(\n chalkStderr.yellow(\n `Failed due to network error, retrying in ${formatDuration(\n delay,\n )}...`,\n ),\n );\n }\n await new Promise((resolve) => setTimeout(resolve, delay));\n continue;\n }\n\n // Fall through if we had a filesystem-based error.\n // TODO(sarah): Replace this with `logError`.\n // eslint-disable-next-line no-console\n console.assert(\n e.errorType === \"invalid filesystem data\" ||\n e.errorType === \"invalid filesystem or env vars\" ||\n e.errorType[\"invalid filesystem or db data\"] !== undefined,\n );\n if (e.errorType === \"invalid filesystem or env vars\") {\n shouldRetryOnDeploymentEnvVarChange = true;\n } else if (\n e.errorType !== \"invalid filesystem data\" &&\n e.errorType[\"invalid filesystem or db data\"] !== undefined\n ) {\n tableNameTriggeringRetry =\n e.errorType[\"invalid filesystem or db data\"];\n }\n if (cmdOptions.once) {\n await outerCtx.flushAndExit(1, e.errorType);\n }\n // Make sure that we don't spin if this push failed\n // in any edge cases that didn't call `logFailure`\n // before throwing.\n stopSpinner();\n }\n if (cmdOptions.once) {\n return;\n }\n if (pushed && cmdOptions.untilSuccess) {\n return;\n }\n const fileSystemWatch = getFileSystemWatch(ctx, watch, cmdOptions);\n const tableWatch = getTableWatch(\n ctx,\n options,\n tableNameTriggeringRetry?.tableName ?? null,\n tableNameTriggeringRetry?.componentPath,\n );\n const envVarWatch = getDeplymentEnvVarWatch(\n ctx,\n options,\n shouldRetryOnDeploymentEnvVarChange,\n );\n await Promise.race([\n fileSystemWatch.watch(),\n tableWatch.watch(),\n envVarWatch.watch(),\n ]);\n fileSystemWatch.stop();\n void tableWatch.stop();\n void envVarWatch.stop();\n }\n } finally {\n // On clean exit (e.g. --once, --until-success), wait for the shell\n // command to finish naturally. Keep the SIGINT listener active so\n // Ctrl+C during the wait still forwards to the child. On signal\n // exit (e.g. Ctrl+C), the registered cleanup handler will have\n // already killed it.\n if (shellExited) {\n await shellExited;\n }\n if (shellSigintListener) {\n process.off(\"SIGINT\", shellSigintListener);\n shellSigintListener = undefined;\n }\n if (shellCleanupHandle) {\n outerCtx.removeCleanup(shellCleanupHandle);\n }\n }\n}\n\nasync function runFunctionInDev(\n ctx: WatchContext,\n credentials: {\n url: string;\n adminKey: string;\n },\n functionName: string,\n componentPath: string | undefined,\n) {\n await runFunctionAndLog(ctx, {\n deploymentUrl: credentials.url,\n adminKey: credentials.adminKey,\n functionName,\n argsString: \"{}\",\n componentPath,\n callbacks: {\n onSuccess: () => {\n logFinishedStep(`Finished running function \"${functionName}\"`);\n },\n },\n });\n}\n\nfunction getTableWatch(\n ctx: WatchContext,\n credentials: {\n url: string;\n adminKey: string;\n },\n tableName: string | null,\n componentPath: string | undefined,\n) {\n return getFunctionWatch(ctx, {\n deploymentUrl: credentials.url,\n adminKey: credentials.adminKey,\n parsedFunctionName: \"_system/cli/queryTable\",\n getArgs: () => (tableName !== null ? { tableName } : null),\n componentPath,\n });\n}\n\nfunction getDeplymentEnvVarWatch(\n ctx: WatchContext,\n credentials: {\n url: string;\n adminKey: string;\n },\n shouldRetryOnDeploymentEnvVarChange: boolean,\n) {\n return getFunctionWatch(ctx, {\n deploymentUrl: credentials.url,\n adminKey: credentials.adminKey,\n parsedFunctionName: \"_system/cli/queryEnvironmentVariables\",\n getArgs: () => (shouldRetryOnDeploymentEnvVarChange ? {} : null),\n componentPath: undefined,\n });\n}\n\nfunction getFunctionWatch(\n ctx: WatchContext,\n args: {\n deploymentUrl: string;\n adminKey: string;\n parsedFunctionName: string;\n getArgs: () => Record<string, Value> | null;\n componentPath: string | undefined;\n },\n) {\n const [stopPromise, stop] = waitUntilCalled();\n return {\n watch: async () => {\n const functionArgs = args.getArgs();\n if (functionArgs === null) {\n return waitForever();\n }\n let changes = 0;\n return subscribe(ctx, {\n deploymentUrl: args.deploymentUrl,\n adminKey: args.adminKey,\n parsedFunctionName: args.parsedFunctionName,\n parsedFunctionArgs: functionArgs,\n componentPath: args.componentPath,\n until: stopPromise,\n callbacks: {\n onChange: () => {\n changes++;\n // First bump is just the initial results reporting\n if (changes > 1) {\n stop();\n }\n },\n },\n });\n },\n stop: () => {\n stop();\n },\n };\n}\n\nfunction getFileSystemWatch(\n ctx: WatchContext,\n watch: { watcher: Watcher | undefined },\n cmdOptions: { traceEvents: boolean },\n) {\n let hasStopped = false;\n return {\n watch: async () => {\n const observations = ctx.fs.finalize();\n if (observations === \"invalidated\") {\n logMessage(\"Filesystem changed during push, retrying...\");\n return;\n }\n // Initialize the watcher if we haven't done it already. Chokidar expects to have a\n // nonempty watch set at initialization, so we can't do it before running our first\n // push.\n if (!watch.watcher) {\n watch.watcher = new Watcher(observations);\n await showSpinnerIfSlow(\n \"Preparing to watch files...\",\n 500,\n async () => {\n await watch.watcher!.ready();\n },\n );\n stopSpinner();\n }\n // Watch new directories if needed.\n watch.watcher.update(observations);\n\n // Process events until we find one that overlaps with our previous observations.\n let anyChanges = false;\n do {\n await watch.watcher.waitForEvent();\n if (hasStopped) {\n return;\n }\n for (const event of watch.watcher.drainEvents()) {\n if (cmdOptions.traceEvents) {\n logMessage(\n \"Processing\",\n event.name,\n path.relative(\"\", event.absPath),\n );\n }\n const result = observations.overlaps(event);\n if (result.overlaps) {\n const relPath = path.relative(\"\", event.absPath);\n if (cmdOptions.traceEvents) {\n logMessage(`${relPath} ${result.reason}, rebuilding...`);\n }\n anyChanges = true;\n break;\n }\n }\n } while (!anyChanges);\n\n // Wait for the filesystem to quiesce before starting a new push. It's okay to\n // drop filesystem events at this stage since we're already committed to doing\n // a push and resubscribing based on that push's observations.\n let deadline = performance.now() + quiescenceDelay;\n while (true) {\n const now = performance.now();\n if (now >= deadline) {\n break;\n }\n const remaining = deadline - now;\n if (cmdOptions.traceEvents) {\n logMessage(`Waiting for ${formatDuration(remaining)} to quiesce...`);\n }\n const remainingWait = new Promise<\"timeout\">((resolve) =>\n setTimeout(() => resolve(\"timeout\"), deadline - now),\n );\n const result = await Promise.race([\n remainingWait,\n watch.watcher.waitForEvent().then<\"newEvents\">(() => \"newEvents\"),\n ]);\n if (result === \"newEvents\") {\n for (const event of watch.watcher.drainEvents()) {\n const result = observations.overlaps(event);\n // Delay another `quiescenceDelay` since we had an overlapping event.\n if (result.overlaps) {\n if (cmdOptions.traceEvents) {\n logMessage(\n `Received an overlapping event at ${event.absPath}, delaying push.`,\n );\n }\n deadline = performance.now() + quiescenceDelay;\n }\n }\n } else {\n // Let the check above `break` from the loop if we're past our deadlne.\n if (result !== \"timeout\") {\n logError(\n \"Assertion failed: Unexpected result from watcher: \" + result,\n );\n }\n }\n }\n },\n stop: () => {\n hasStopped = true;\n },\n };\n}\n\nconst initialBackoff = 500;\nconst maxBackoff = 16000;\nconst quiescenceDelay = 500;\n\nexport function nextBackoff(prevFailures: number): number {\n const baseBackoff = initialBackoff * Math.pow(2, prevFailures);\n const actualBackoff = Math.min(baseBackoff, maxBackoff);\n const jitter = actualBackoff * (Math.random() - 0.5);\n return actualBackoff + jitter;\n}\n"],
|
|
5
|
-
"mappings": ";AAAA,SAAS,mBAAmB;AAC5B,SAAS,aAA2B;AAEpC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,eAAe;AACxB,SAAS,mBAAmB;AAC5B,OAAO,UAAU;AACjB,SAAS,YAAqB,iBAAiB;AAE/C;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,OAAO,cAAc,eAAe;AAC7C,SAAS,mBAAmB,iBAAiB;AAG7C,SAAS,mBAAmB,wBAAwB;AACpD;AAAA,EACE;AAAA,EACA;AAAA,OACK;AACP,SAAS,uBAAuB;AAChC,SAAS,4BAA4B;AACrC,SAAS,4BAA4B;AAErC,sBAAsB,qBACpB,KACA,aAOA,
|
|
4
|
+
"sourcesContent": ["import { chalkStderr } from \"chalk\";\nimport { spawn, ChildProcess } from \"child_process\";\nimport { OneoffCtx } from \"../../bundler/context.js\";\nimport {\n logError,\n logFinishedStep,\n logMessage,\n logWarning,\n showSpinner,\n showSpinnerIfSlow,\n stopSpinner,\n} from \"../../bundler/log.js\";\nimport { runPush } from \"./components.js\";\nimport { performance } from \"perf_hooks\";\nimport path from \"path\";\nimport { LogManager, LogMode, watchLogs } from \"./logs.js\";\nimport { PushOptions } from \"./components.js\";\nimport {\n formatDuration,\n getCurrentTimeString,\n waitForever,\n waitUntilCalled,\n} from \"./utils/utils.js\";\nimport { Crash, WatchContext, Watcher } from \"./watch.js\";\nimport { runFunctionAndLog, subscribe } from \"./run.js\";\nimport { Value } from \"../../values/index.js\";\nimport { DeploymentType } from \"./api.js\";\nimport { readProjectConfig, getAuthKitConfig } from \"./config.js\";\nimport {\n syncAuthKitConfigAfterPush,\n ensureAuthKitProvisionedBeforeBuild,\n} from \"./workos/workos.js\";\nimport { handleDashboard } from \"./localDeployment/dashboard.js\";\nimport { loadDeploymentConfig } from \"./localDeployment/filePaths.js\";\nimport { LocalDeploymentError } from \"./localDeployment/errors.js\";\n\nexport async function devAgainstDeployment(\n ctx: OneoffCtx,\n credentials: {\n url: string;\n adminKey: string;\n deploymentName: string | null;\n deploymentType?: DeploymentType;\n backendVersion?: string | undefined;\n },\n devOptions: {\n verbose: boolean;\n typecheck: \"enable\" | \"try\" | \"disable\";\n typecheckComponents: boolean;\n codegen: boolean;\n once: boolean;\n untilSuccess: boolean;\n run?:\n | { kind: \"function\"; name: string; component?: string | undefined }\n | { kind: \"shell\"; command: string }\n | undefined;\n tailLogs: LogMode;\n traceEvents: boolean;\n debugBundlePath?: string | undefined;\n debugNodeApis: boolean;\n liveComponentSources: boolean;\n pushAllModules: boolean;\n allowUnstagingSchema: boolean;\n },\n) {\n const logManager = new LogManager(devOptions.tailLogs);\n\n // Pre-flight check: Ensure AuthKit is provisioned before starting dev\n const { projectConfig } = await readProjectConfig(ctx);\n const authKitConfig = await getAuthKitConfig(ctx, projectConfig);\n\n if (authKitConfig && credentials.deploymentName) {\n // Only provision for cloud deployments (dev/preview/prod)\n // Skip for local and anonymous deployments\n const deploymentType = credentials.deploymentType;\n if (\n deploymentType === \"dev\" ||\n deploymentType === \"preview\" ||\n deploymentType === \"prod\"\n ) {\n await ensureAuthKitProvisionedBeforeBuild(\n ctx,\n credentials.deploymentName,\n { deploymentUrl: credentials.url, adminKey: credentials.adminKey },\n deploymentType,\n );\n }\n }\n\n // Anonymous mode starts a local dashboard server alongside long-running `npx convex dev` commands.\n if (\n !devOptions.once &&\n !devOptions.untilSuccess &&\n credentials.deploymentType === \"anonymous\" &&\n credentials.deploymentName !== null\n ) {\n const deploymentConfig = loadDeploymentConfig(\n ctx,\n \"anonymous\",\n credentials.deploymentName,\n );\n if (deploymentConfig === null) {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: `Could not find local deployment config. This is a bug in Convex.`,\n errForSentry: new LocalDeploymentError(\n `Could not find local deployment config to start the anonymous dashboard.`,\n ),\n });\n }\n await handleDashboard(\n ctx,\n {\n name: credentials.deploymentName,\n cloudPort: deploymentConfig.ports.cloud,\n adminKey: deploymentConfig.adminKey,\n },\n {\n backendVersion: credentials.backendVersion,\n },\n );\n }\n\n const promises = [];\n if (devOptions.tailLogs !== \"disable\") {\n promises.push(\n watchLogs(ctx, credentials.url, credentials.adminKey, \"stderr\", {\n logManager,\n success: false,\n }),\n );\n }\n\n promises.push(\n watchAndPush(\n ctx,\n {\n ...credentials,\n verbose: devOptions.verbose,\n dryRun: false,\n typecheck: devOptions.typecheck,\n typecheckComponents: devOptions.typecheckComponents,\n debug: false,\n debugBundlePath: devOptions.debugBundlePath,\n debugNodeApis: devOptions.debugNodeApis,\n codegen: devOptions.codegen,\n liveComponentSources: devOptions.liveComponentSources,\n pushAllModules: devOptions.pushAllModules,\n logManager, // Pass logManager to control logs during deploy\n largeIndexDeletionCheck: \"no verification\", // `convex dev` can\u2019t push to prod\n // `convex dev --prod` pushes straight to production, where an\n // unstaged index on a large table blocks the push for the whole\n // backfill; dev deployments are small enough to let it through.\n largeIndexBackfillCheck:\n credentials.deploymentType === \"prod\"\n ? \"ask for confirmation\"\n : \"no verification\",\n stagedValidatorDeletionCheck:\n credentials.deploymentType === \"prod\"\n ? devOptions.allowUnstagingSchema\n ? \"has confirmation\"\n : \"ask for confirmation\"\n : \"no verification\",\n warnOnSlowSchemaValidation: true,\n message: null,\n },\n devOptions,\n ),\n );\n await Promise.race(promises);\n await ctx.flushAndExit(0);\n}\n\nexport async function watchAndPush(\n outerCtx: OneoffCtx,\n options: PushOptions,\n cmdOptions: {\n run?:\n | { kind: \"function\"; name: string; component?: string | undefined }\n | { kind: \"shell\"; command: string }\n | undefined;\n once: boolean;\n untilSuccess: boolean;\n traceEvents: boolean;\n },\n) {\n const watch: { watcher: Watcher | undefined } = { watcher: undefined };\n const authKitCache: { lastAppliedConfig: string | undefined } = {\n lastAppliedConfig: undefined,\n };\n let numFailures = 0;\n let ran = false;\n let pushed = false;\n let shellChild: ChildProcess | undefined;\n let shellExited: Promise<void> | undefined;\n let shellCleanupHandle: string | undefined;\n let shellSigintListener: (() => void) | undefined;\n let tableNameTriggeringRetry;\n let shouldRetryOnDeploymentEnvVarChange;\n let isFirstPush = true; // Track if this is the first push in the session\n\n try {\n while (true) {\n const start = performance.now();\n tableNameTriggeringRetry = null;\n shouldRetryOnDeploymentEnvVarChange = false;\n\n const ctx = new WatchContext(\n cmdOptions.traceEvents,\n outerCtx.bigBrainAuth(),\n isFirstPush,\n );\n options.logManager?.beginDeploy();\n showSpinner(\"Preparing Convex functions...\");\n try {\n await runPush(ctx, options);\n const end = performance.now();\n // NOTE: If `runPush` throws, `endDeploy` will not be called.\n // This allows you to see the output from the failed deploy without\n // logs getting in the way.\n options.logManager?.endDeploy();\n numFailures = 0;\n logFinishedStep(\n `${getCurrentTimeString()} Convex functions ready! (${formatDuration(\n end - start,\n )})`,\n );\n\n // Sync AuthKit configuration if it has changed\n const { projectConfig } = await readProjectConfig(ctx);\n const authKitConfig = await getAuthKitConfig(ctx, projectConfig);\n\n // Check if config has changed by comparing stringified versions\n const currentConfigString = authKitConfig\n ? JSON.stringify(authKitConfig)\n : undefined;\n\n // Skip sync on first push since ensureAuthKitProvisionedBeforeBuild already configured WorkOS\n if (\n !isFirstPush &&\n currentConfigString !== authKitCache.lastAppliedConfig\n ) {\n // Config has changed, sync it\n await syncAuthKitConfigAfterPush(ctx, projectConfig, {\n deploymentUrl: options.url,\n adminKey: options.adminKey,\n });\n }\n\n // Always update cache after push (even if we skipped sync)\n authKitCache.lastAppliedConfig = currentConfigString;\n isFirstPush = false;\n if (cmdOptions.run !== undefined && !ran) {\n switch (cmdOptions.run.kind) {\n case \"function\":\n await runFunctionInDev(\n ctx,\n options,\n cmdOptions.run.name,\n cmdOptions.run.component,\n );\n break;\n case \"shell\": {\n // Spawn the shell command as a long-running child process,\n // piping stdin/stdout/stderr. It runs alongside dev and is\n // waited on during clean exit or killed on signal exit.\n const shellCommand = cmdOptions.run.command;\n const signalShellChild = (signal: NodeJS.Signals) => {\n if (!shellChild) {\n return;\n }\n const child = shellChild;\n // Kill the entire process group so children of the shell\n // are also killed.\n try {\n if (child.pid !== undefined) {\n // Kill the negative PID to signal the entire process\n // group. Falls back to the child directly if the\n // group is already gone.\n try {\n process.kill(-child.pid, signal);\n } catch {\n child.kill(signal);\n }\n } else {\n child.kill(signal);\n }\n } catch {\n // Child may already be dead.\n }\n };\n const clearShellSigintListener = () => {\n if (shellSigintListener) {\n process.off(\"SIGINT\", shellSigintListener);\n shellSigintListener = undefined;\n }\n };\n shellChild = spawn(shellCommand, [], {\n shell: true,\n stdio: \"inherit\",\n detached: true,\n });\n shellSigintListener = () => {\n clearShellSigintListener();\n signalShellChild(\"SIGINT\");\n };\n process.prependListener(\"SIGINT\", shellSigintListener);\n shellCleanupHandle = outerCtx.registerCleanup(async () => {\n if (shellSigintListener) {\n clearShellSigintListener();\n } else {\n // If the listener already fired (and cleared itself),\n // the child got SIGINT \u2014 give it a moment to exit on\n // its own before escalating to SIGTERM.\n const SIGTERM_ESCALATION_MS = 1000;\n await Promise.race([\n shellExited,\n new Promise((resolve) =>\n setTimeout(resolve, SIGTERM_ESCALATION_MS),\n ),\n ]);\n }\n if (shellChild) {\n signalShellChild(\"SIGTERM\");\n }\n await shellExited;\n });\n shellExited = new Promise<void>((resolve) => {\n shellChild!.on(\"error\", (error) => {\n logError(\n `Failed to run command \\`${shellCommand}\\`: ${error.message}`,\n );\n shellChild = undefined;\n resolve();\n void outerCtx.flushAndExit(1);\n });\n shellChild!.on(\"exit\", (code, signal) => {\n shellChild = undefined;\n resolve();\n // If killed by a signal (e.g. from cleanup on shutdown),\n // don't treat it as a failure \u2014 convex dev is already\n // shutting down.\n if (signal) {\n return;\n }\n if (code !== null && code !== 0) {\n logError(\n `Command \\`${shellCommand}\\` exited with code ${code}`,\n );\n void outerCtx.flushAndExit(1);\n }\n });\n });\n break;\n }\n default: {\n cmdOptions.run satisfies never;\n // Don't return this since it'll bypass the `catch` below.\n await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: `Unexpected arguments for --run`,\n errForSentry: `Unexpected arguments for --run: ${JSON.stringify(\n cmdOptions.run,\n )}`,\n });\n }\n }\n ran = true;\n }\n pushed = true;\n } catch (e: any) {\n // Crash the app on unexpected errors.\n if (!(e instanceof Crash) || !e.errorType) {\n // eslint-disable-next-line no-restricted-syntax\n throw e;\n }\n if (e.errorType === \"fatal\") {\n break;\n }\n // Retry after an exponential backoff if we hit a transient error.\n if (e.errorType === \"transient\" || e.errorType === \"already handled\") {\n const delay = nextBackoff(numFailures);\n numFailures += 1;\n if (e.errorType === \"transient\") {\n logWarning(\n chalkStderr.yellow(\n `Failed due to network error, retrying in ${formatDuration(\n delay,\n )}...`,\n ),\n );\n }\n await new Promise((resolve) => setTimeout(resolve, delay));\n continue;\n }\n\n // Fall through if we had a filesystem-based error.\n // TODO(sarah): Replace this with `logError`.\n // eslint-disable-next-line no-console\n console.assert(\n e.errorType === \"invalid filesystem data\" ||\n e.errorType === \"invalid filesystem or env vars\" ||\n e.errorType[\"invalid filesystem or db data\"] !== undefined,\n );\n if (e.errorType === \"invalid filesystem or env vars\") {\n shouldRetryOnDeploymentEnvVarChange = true;\n } else if (\n e.errorType !== \"invalid filesystem data\" &&\n e.errorType[\"invalid filesystem or db data\"] !== undefined\n ) {\n tableNameTriggeringRetry =\n e.errorType[\"invalid filesystem or db data\"];\n }\n if (cmdOptions.once) {\n await outerCtx.flushAndExit(1, e.errorType);\n }\n // Make sure that we don't spin if this push failed\n // in any edge cases that didn't call `logFailure`\n // before throwing.\n stopSpinner();\n }\n if (cmdOptions.once) {\n return;\n }\n if (pushed && cmdOptions.untilSuccess) {\n return;\n }\n const fileSystemWatch = getFileSystemWatch(ctx, watch, cmdOptions);\n const tableWatch = getTableWatch(\n ctx,\n options,\n tableNameTriggeringRetry?.tableName ?? null,\n tableNameTriggeringRetry?.componentPath,\n );\n const envVarWatch = getDeplymentEnvVarWatch(\n ctx,\n options,\n shouldRetryOnDeploymentEnvVarChange,\n );\n await Promise.race([\n fileSystemWatch.watch(),\n tableWatch.watch(),\n envVarWatch.watch(),\n ]);\n fileSystemWatch.stop();\n void tableWatch.stop();\n void envVarWatch.stop();\n }\n } finally {\n // On clean exit (e.g. --once, --until-success), wait for the shell\n // command to finish naturally. Keep the SIGINT listener active so\n // Ctrl+C during the wait still forwards to the child. On signal\n // exit (e.g. Ctrl+C), the registered cleanup handler will have\n // already killed it.\n if (shellExited) {\n await shellExited;\n }\n if (shellSigintListener) {\n process.off(\"SIGINT\", shellSigintListener);\n shellSigintListener = undefined;\n }\n if (shellCleanupHandle) {\n outerCtx.removeCleanup(shellCleanupHandle);\n }\n }\n}\n\nasync function runFunctionInDev(\n ctx: WatchContext,\n credentials: {\n url: string;\n adminKey: string;\n },\n functionName: string,\n componentPath: string | undefined,\n) {\n await runFunctionAndLog(ctx, {\n deploymentUrl: credentials.url,\n adminKey: credentials.adminKey,\n functionName,\n argsString: \"{}\",\n componentPath,\n callbacks: {\n onSuccess: () => {\n logFinishedStep(`Finished running function \"${functionName}\"`);\n },\n },\n });\n}\n\nfunction getTableWatch(\n ctx: WatchContext,\n credentials: {\n url: string;\n adminKey: string;\n },\n tableName: string | null,\n componentPath: string | undefined,\n) {\n return getFunctionWatch(ctx, {\n deploymentUrl: credentials.url,\n adminKey: credentials.adminKey,\n parsedFunctionName: \"_system/cli/queryTable\",\n getArgs: () => (tableName !== null ? { tableName } : null),\n componentPath,\n });\n}\n\nfunction getDeplymentEnvVarWatch(\n ctx: WatchContext,\n credentials: {\n url: string;\n adminKey: string;\n },\n shouldRetryOnDeploymentEnvVarChange: boolean,\n) {\n return getFunctionWatch(ctx, {\n deploymentUrl: credentials.url,\n adminKey: credentials.adminKey,\n parsedFunctionName: \"_system/cli/queryEnvironmentVariables\",\n getArgs: () => (shouldRetryOnDeploymentEnvVarChange ? {} : null),\n componentPath: undefined,\n });\n}\n\nfunction getFunctionWatch(\n ctx: WatchContext,\n args: {\n deploymentUrl: string;\n adminKey: string;\n parsedFunctionName: string;\n getArgs: () => Record<string, Value> | null;\n componentPath: string | undefined;\n },\n) {\n const [stopPromise, stop] = waitUntilCalled();\n return {\n watch: async () => {\n const functionArgs = args.getArgs();\n if (functionArgs === null) {\n return waitForever();\n }\n let changes = 0;\n return subscribe(ctx, {\n deploymentUrl: args.deploymentUrl,\n adminKey: args.adminKey,\n parsedFunctionName: args.parsedFunctionName,\n parsedFunctionArgs: functionArgs,\n componentPath: args.componentPath,\n until: stopPromise,\n callbacks: {\n onChange: () => {\n changes++;\n // First bump is just the initial results reporting\n if (changes > 1) {\n stop();\n }\n },\n },\n });\n },\n stop: () => {\n stop();\n },\n };\n}\n\nfunction getFileSystemWatch(\n ctx: WatchContext,\n watch: { watcher: Watcher | undefined },\n cmdOptions: { traceEvents: boolean },\n) {\n let hasStopped = false;\n return {\n watch: async () => {\n const observations = ctx.fs.finalize();\n if (observations === \"invalidated\") {\n logMessage(\"Filesystem changed during push, retrying...\");\n return;\n }\n // Initialize the watcher if we haven't done it already. Chokidar expects to have a\n // nonempty watch set at initialization, so we can't do it before running our first\n // push.\n if (!watch.watcher) {\n watch.watcher = new Watcher(observations);\n await showSpinnerIfSlow(\n \"Preparing to watch files...\",\n 500,\n async () => {\n await watch.watcher!.ready();\n },\n );\n stopSpinner();\n }\n // Watch new directories if needed.\n watch.watcher.update(observations);\n\n // Process events until we find one that overlaps with our previous observations.\n let anyChanges = false;\n do {\n await watch.watcher.waitForEvent();\n if (hasStopped) {\n return;\n }\n for (const event of watch.watcher.drainEvents()) {\n if (cmdOptions.traceEvents) {\n logMessage(\n \"Processing\",\n event.name,\n path.relative(\"\", event.absPath),\n );\n }\n const result = observations.overlaps(event);\n if (result.overlaps) {\n const relPath = path.relative(\"\", event.absPath);\n if (cmdOptions.traceEvents) {\n logMessage(`${relPath} ${result.reason}, rebuilding...`);\n }\n anyChanges = true;\n break;\n }\n }\n } while (!anyChanges);\n\n // Wait for the filesystem to quiesce before starting a new push. It's okay to\n // drop filesystem events at this stage since we're already committed to doing\n // a push and resubscribing based on that push's observations.\n let deadline = performance.now() + quiescenceDelay;\n while (true) {\n const now = performance.now();\n if (now >= deadline) {\n break;\n }\n const remaining = deadline - now;\n if (cmdOptions.traceEvents) {\n logMessage(`Waiting for ${formatDuration(remaining)} to quiesce...`);\n }\n const remainingWait = new Promise<\"timeout\">((resolve) =>\n setTimeout(() => resolve(\"timeout\"), deadline - now),\n );\n const result = await Promise.race([\n remainingWait,\n watch.watcher.waitForEvent().then<\"newEvents\">(() => \"newEvents\"),\n ]);\n if (result === \"newEvents\") {\n for (const event of watch.watcher.drainEvents()) {\n const result = observations.overlaps(event);\n // Delay another `quiescenceDelay` since we had an overlapping event.\n if (result.overlaps) {\n if (cmdOptions.traceEvents) {\n logMessage(\n `Received an overlapping event at ${event.absPath}, delaying push.`,\n );\n }\n deadline = performance.now() + quiescenceDelay;\n }\n }\n } else {\n // Let the check above `break` from the loop if we're past our deadlne.\n if (result !== \"timeout\") {\n logError(\n \"Assertion failed: Unexpected result from watcher: \" + result,\n );\n }\n }\n }\n },\n stop: () => {\n hasStopped = true;\n },\n };\n}\n\nconst initialBackoff = 500;\nconst maxBackoff = 16000;\nconst quiescenceDelay = 500;\n\nexport function nextBackoff(prevFailures: number): number {\n const baseBackoff = initialBackoff * Math.pow(2, prevFailures);\n const actualBackoff = Math.min(baseBackoff, maxBackoff);\n const jitter = actualBackoff * (Math.random() - 0.5);\n return actualBackoff + jitter;\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["result"]
|
|
7
7
|
}
|
|
@@ -2,7 +2,41 @@
|
|
|
2
2
|
import { chalkStderr } from "chalk";
|
|
3
3
|
import * as dotenv from "dotenv";
|
|
4
4
|
import { logWarning } from "../../bundler/log.js";
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
CONVEX_DEPLOY_KEY_ENV_VAR_NAME,
|
|
7
|
+
readDeployKeyEnvVar,
|
|
8
|
+
ENV_VAR_FILE_PATH,
|
|
9
|
+
loadPackageJson
|
|
10
|
+
} from "./utils/utils.js";
|
|
11
|
+
export const CONVEX_ACCOUNT_ENV_VAR = "CONVEX_ACCOUNT";
|
|
12
|
+
const loadedEnvironment = /* @__PURE__ */ new Map();
|
|
13
|
+
export function loadProjectEnvironmentVariables() {
|
|
14
|
+
for (const [name, { value }] of loadedEnvironment) {
|
|
15
|
+
if (process.env[name] === value) delete process.env[name];
|
|
16
|
+
}
|
|
17
|
+
loadedEnvironment.clear();
|
|
18
|
+
const environment = {};
|
|
19
|
+
for (const [name, value] of Object.entries(process.env)) {
|
|
20
|
+
if (value !== void 0) environment[name] = value;
|
|
21
|
+
}
|
|
22
|
+
for (const file of [ENV_VAR_FILE_PATH, ".env"]) {
|
|
23
|
+
dotenv.config({ path: file, processEnv: environment });
|
|
24
|
+
for (const [name, value] of Object.entries(environment)) {
|
|
25
|
+
if (name !== CONVEX_ACCOUNT_ENV_VAR && process.env[name] === void 0) {
|
|
26
|
+
process.env[name] = value;
|
|
27
|
+
loadedEnvironment.set(name, { value, source: file });
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
export function getDeployKeySource(key) {
|
|
33
|
+
const envVarName = readDeployKeyEnvVar((name) => process.env[name])?.name ?? CONVEX_DEPLOY_KEY_ENV_VAR_NAME;
|
|
34
|
+
const loaded = loadedEnvironment.get(envVarName);
|
|
35
|
+
return {
|
|
36
|
+
envVarName,
|
|
37
|
+
source: loaded?.value === key ? loaded.source : "shell environment"
|
|
38
|
+
};
|
|
39
|
+
}
|
|
6
40
|
const _FRAMEWORKS = [
|
|
7
41
|
"create-react-app",
|
|
8
42
|
"Next.js",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/cli/lib/envvars.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Help the developer store the CONVEX_URL environment variable.\n */\nimport { chalkStderr } from \"chalk\";\nimport * as dotenv from \"dotenv\";\n\nimport { Context } from \"../../bundler/context.js\";\nimport { logWarning } from \"../../bundler/log.js\";\nimport { loadPackageJson } from \"./utils/utils.js\";\n\nconst _FRAMEWORKS = [\n \"create-react-app\",\n \"Next.js\",\n \"Vite\",\n \"Remix\",\n \"SvelteKit\",\n \"Expo\",\n \"TanStackStart\",\n] as const;\ntype Framework = (typeof _FRAMEWORKS)[number];\n\n/**\n * A configuration for writing the actual (framework specific) `CONVEX_URL`\n * and `CONVEX_SITE_URL` environment variables to a \".env\" type file.\n *\n * May be `null` if there was an error determining any of the field values.\n */\ntype EnvFileUrlConfig = {\n /** The name of the file - typically `.env.local` */\n envFile: string;\n /**\n * The framework specific `CONVEX_URL`\n *\n * If `null`, ignore and don't update that environment variable.\n */\n convexUrlEnvVar: string | null;\n /**\n * The framework specific `CONVEX_SITE_URL`\n *\n * If `null`, ignore and don't update that environment variable.\n */\n siteUrlEnvVar: string | null;\n /** Existing content loaded from the `envFile`, if it exists */\n existingFileContent: string | null;\n} | null;\n\nexport async function writeUrlsToEnvFile(\n ctx: Context,\n options: {\n convexUrl: string;\n siteUrl?: string | null | undefined;\n },\n): Promise<EnvFileUrlConfig> {\n const envFileConfig = await loadEnvFileUrlConfig(ctx, options);\n\n if (envFileConfig === null) {\n return null;\n }\n\n const { envFile, convexUrlEnvVar, siteUrlEnvVar, existingFileContent } =\n envFileConfig;\n let updatedFileContent: string | null = null;\n if (convexUrlEnvVar) {\n updatedFileContent = changedEnvVarFile({\n existingFileContent,\n envVarName: convexUrlEnvVar,\n envVarValue: options.convexUrl,\n commentAfterValue: null,\n commentOnPreviousLine: null,\n })!;\n }\n if (siteUrlEnvVar && options.siteUrl) {\n updatedFileContent = changedEnvVarFile({\n existingFileContent: updatedFileContent ?? existingFileContent,\n envVarName: siteUrlEnvVar,\n envVarValue: options.siteUrl,\n commentAfterValue: null,\n commentOnPreviousLine: null,\n })!;\n }\n if (updatedFileContent) {\n ctx.fs.writeUtf8File(envFile, updatedFileContent);\n }\n\n return envFileConfig;\n}\n\nexport function changedEnvVarFile({\n existingFileContent,\n envVarName,\n envVarValue,\n commentAfterValue,\n commentOnPreviousLine,\n}: {\n existingFileContent: string | null;\n envVarName: string;\n envVarValue: string;\n commentAfterValue: string | null;\n commentOnPreviousLine: string | null;\n}): string | null {\n const varAssignment = `${envVarName}=${envVarValue}${\n commentAfterValue === null ? \"\" : ` # ${commentAfterValue}`\n }`;\n const commentOnPreviousLineWithLineBreak =\n commentOnPreviousLine === null ? \"\" : `${commentOnPreviousLine}\\n`;\n if (existingFileContent === null) {\n return `${commentOnPreviousLineWithLineBreak}${varAssignment}\\n`;\n }\n const config = dotenv.parse(existingFileContent);\n const existing = config[envVarName];\n if (existing === envVarValue) {\n return null;\n }\n if (existing !== undefined) {\n return existingFileContent.replace(\n getEnvVarRegex(envVarName),\n `${varAssignment}`,\n );\n } else {\n const doubleLineBreak = existingFileContent.endsWith(\"\\n\") ? \"\\n\" : \"\\n\\n\";\n return (\n existingFileContent +\n doubleLineBreak +\n commentOnPreviousLineWithLineBreak +\n varAssignment +\n \"\\n\"\n );\n }\n}\n\nexport function getEnvVarRegex(envVarName: string) {\n return new RegExp(`^${envVarName}.*$`, \"m\");\n}\n\nexport async function suggestedEnvVarNames(ctx: Context): Promise<{\n detectedFramework?: Framework;\n convexUrlEnvVar: ConvexUrlEnvVar;\n convexSiteEnvVar: ConvexSiteUrlEnvVar;\n frontendDevUrl?: string;\n publicPrefix?: string;\n}> {\n // no package.json, that's fine, just guess\n if (!ctx.fs.exists(\"package.json\")) {\n return {\n convexUrlEnvVar: \"CONVEX_URL\",\n convexSiteEnvVar: \"CONVEX_SITE_URL\",\n };\n }\n\n const packages = await loadPackageJson(ctx);\n\n // Is it create-react-app?\n const isCreateReactApp = \"react-scripts\" in packages;\n if (isCreateReactApp) {\n return {\n detectedFramework: \"create-react-app\",\n convexUrlEnvVar: \"REACT_APP_CONVEX_URL\",\n convexSiteEnvVar: \"REACT_APP_CONVEX_SITE_URL\",\n frontendDevUrl: \"http://localhost:3000\",\n publicPrefix: \"REACT_APP_\",\n };\n }\n\n const isNextJs = \"next\" in packages;\n if (isNextJs) {\n return {\n detectedFramework: \"Next.js\",\n convexUrlEnvVar: \"NEXT_PUBLIC_CONVEX_URL\",\n convexSiteEnvVar: \"NEXT_PUBLIC_CONVEX_SITE_URL\",\n frontendDevUrl: \"http://localhost:3000\",\n publicPrefix: \"NEXT_PUBLIC_\",\n };\n }\n\n const isExpo = \"expo\" in packages;\n if (isExpo) {\n return {\n detectedFramework: \"Expo\",\n convexUrlEnvVar: \"EXPO_PUBLIC_CONVEX_URL\",\n convexSiteEnvVar: \"EXPO_PUBLIC_CONVEX_SITE_URL\",\n publicPrefix: \"EXPO_PUBLIC_\",\n };\n }\n\n const isSvelteKit = \"@sveltejs/kit\" in packages;\n if (isSvelteKit) {\n return {\n detectedFramework: \"SvelteKit\",\n convexUrlEnvVar: \"PUBLIC_CONVEX_URL\",\n convexSiteEnvVar: \"PUBLIC_CONVEX_SITE_URL\",\n frontendDevUrl: \"http://localhost:5173\",\n publicPrefix: \"PUBLIC_\",\n };\n }\n\n // TanStackStart currently supports VITE_FOO for browser-side envvars.\n const isTanStackStart =\n \"@tanstack/start\" in packages || \"@tanstack/react-start\" in packages;\n\n if (isTanStackStart) {\n return {\n detectedFramework: \"TanStackStart\",\n convexUrlEnvVar: \"VITE_CONVEX_URL\",\n convexSiteEnvVar: \"VITE_CONVEX_SITE_URL\",\n frontendDevUrl: \"http://localhost:3000\",\n publicPrefix: \"VITE_\",\n };\n }\n\n // Vite is a dependency of a lot of things; vite appearing in dependencies is not a strong indicator.\n const isVite = \"vite\" in packages;\n\n if (isVite) {\n return {\n detectedFramework: \"Vite\",\n convexUrlEnvVar: \"VITE_CONVEX_URL\",\n convexSiteEnvVar: \"VITE_CONVEX_SITE_URL\",\n frontendDevUrl: \"http://localhost:5173\",\n publicPrefix: \"VITE_\",\n };\n }\n\n // We detect Remix after Vite because when using Remix as a plugin of Vite\n // (Remix Vite), we want to use Vite-style environment variables.\n const isRemix = \"@remix-run/dev\" in packages;\n if (isRemix) {\n return {\n detectedFramework: \"Remix\",\n convexUrlEnvVar: \"CONVEX_URL\",\n convexSiteEnvVar: \"CONVEX_SITE_URL\",\n frontendDevUrl: \"http://localhost:3000\",\n };\n }\n\n return {\n convexUrlEnvVar: \"CONVEX_URL\",\n convexSiteEnvVar: \"CONVEX_SITE_URL\",\n };\n}\n\nasync function loadEnvFileUrlConfig(\n ctx: Context,\n options: {\n convexUrl: string;\n siteUrl?: string | null | undefined;\n },\n): Promise<EnvFileUrlConfig> {\n const { detectedFramework, convexUrlEnvVar, convexSiteEnvVar } =\n await suggestedEnvVarNames(ctx);\n\n const { envFile, existing } = suggestedDevEnvFile(ctx, detectedFramework);\n\n if (!existing) {\n return {\n envFile,\n convexUrlEnvVar,\n siteUrlEnvVar: convexSiteEnvVar,\n existingFileContent: null,\n };\n }\n\n const existingFileContent = ctx.fs.readUtf8File(envFile);\n const config = dotenv.parse(existingFileContent);\n\n const resolvedConvexUrlEnvVar = resolveEnvVarName(\n convexUrlEnvVar,\n options.convexUrl,\n envFile,\n config,\n EXPECTED_CONVEX_URL_NAMES,\n );\n const resolvedSiteUrlEnvVar = resolveEnvVarName(\n convexSiteEnvVar,\n options.siteUrl ?? \"\",\n envFile,\n config,\n EXPECTED_SITE_URL_NAMES,\n );\n if (\n resolvedConvexUrlEnvVar.kind === \"invalid\" ||\n resolvedSiteUrlEnvVar.kind === \"invalid\"\n ) {\n return null;\n }\n return {\n envFile,\n convexUrlEnvVar: resolvedConvexUrlEnvVar.envVarName,\n siteUrlEnvVar: resolvedSiteUrlEnvVar.envVarName,\n existingFileContent,\n };\n}\n\nfunction resolveEnvVarName(\n envVarName: string,\n envVarValue: string,\n envFile: string,\n config: dotenv.DotenvParseOutput,\n expectedNames: Set<string>,\n):\n | {\n kind: \"invalid\";\n }\n | {\n kind: \"valid\";\n envVarName: string | null;\n } {\n const matching = Object.keys(config).filter((key) => expectedNames.has(key));\n if (matching.length > 1) {\n logWarning(\n chalkStderr.yellow(\n `Found multiple ${envVarName} environment variables in ${envFile} so cannot update automatically.`,\n ),\n );\n return { kind: \"invalid\" };\n }\n if (matching.length === 1) {\n const [existingEnvVarName, oldValue] = [matching[0], config[matching[0]]];\n if (oldValue === envVarValue) {\n // Set envVarName to null to indicate that it shouldn't be updated.\n return { kind: \"valid\", envVarName: null };\n }\n if (\n oldValue !== \"\" &&\n Object.values(config).filter((v) => v === oldValue).length !== 1\n ) {\n logWarning(\n chalkStderr.yellow(\n `Can't safely modify ${envFile} for ${envVarName}, please edit manually.`,\n ),\n );\n return { kind: \"invalid\" };\n }\n return { kind: \"valid\", envVarName: existingEnvVarName };\n }\n return { kind: \"valid\", envVarName };\n}\n\nfunction suggestedDevEnvFile(\n ctx: Context,\n framework?: Framework,\n): {\n existing: boolean;\n envFile: string;\n} {\n // If a .env.local file exists, that's unequivocally the right file\n if (ctx.fs.exists(\".env.local\")) {\n return {\n existing: true,\n envFile: \".env.local\",\n };\n }\n\n // Remix is on team \"don't commit the .env file,\" so .env is for dev.\n if (framework === \"Remix\") {\n return {\n existing: ctx.fs.exists(\".env\"),\n envFile: \".env\",\n };\n }\n\n // The most dev-looking env file that exists, or .env.local\n return {\n existing: ctx.fs.exists(\".env.local\"),\n envFile: \".env.local\",\n };\n}\n\nexport const EXPECTED_CONVEX_URL_NAMES = new Set([\n \"CONVEX_URL\" as const,\n \"PUBLIC_CONVEX_URL\" as const,\n \"NEXT_PUBLIC_CONVEX_URL\" as const,\n \"VITE_CONVEX_URL\" as const,\n \"REACT_APP_CONVEX_URL\" as const,\n \"EXPO_PUBLIC_CONVEX_URL\" as const,\n]);\ntype ConvexUrlEnvVar =\n typeof EXPECTED_CONVEX_URL_NAMES extends Set<infer T> ? T : never;\n\nexport const EXPECTED_SITE_URL_NAMES = new Set([\n \"CONVEX_SITE_URL\" as const,\n \"PUBLIC_CONVEX_SITE_URL\" as const,\n \"NEXT_PUBLIC_CONVEX_SITE_URL\" as const,\n \"VITE_CONVEX_SITE_URL\" as const,\n \"REACT_APP_CONVEX_SITE_URL\" as const,\n \"EXPO_PUBLIC_CONVEX_SITE_URL\" as const,\n]);\ntype ConvexSiteUrlEnvVar =\n typeof EXPECTED_SITE_URL_NAMES extends Set<infer T> ? T : never;\n\n// Crash or warn on\n// CONVEX_DEPLOY_KEY=project:me:new-project|eyABCD0= npx convex\n// which parses as\n// CONVEX_DEPLOY_KEY=project:me:new-project | eyABCD0='' npx convex\n// when what was intended was\n// CONVEX_DEPLOY_KEY=project:me:new-project|eyABCD0= npx convex\n// This only fails so catastrophically when the key ends with `=`.\nexport async function detectSuspiciousEnvironmentVariables(\n ctx: Context,\n ignoreSuspiciousEnvVars = false,\n) {\n for (const [key, value] of Object.entries(process.env)) {\n if (value === \"\" && key.startsWith(\"ey\")) {\n try {\n // add a \"=\" to the end and try to base64 decode (expected format of Convex keys)\n const decoded = JSON.parse(\n Buffer.from(key + \"=\", \"base64\").toString(\"utf8\"),\n );\n // Only parseable v2 tokens to be sure this is a Convex token before complaining.\n if (!(\"v2\" in decoded)) {\n continue;\n }\n } catch {\n continue;\n }\n\n if (ignoreSuspiciousEnvVars) {\n logWarning(\n `ignoring suspicious environment variable ${key}, did you mean to use quotes like CONVEX_DEPLOY_KEY='...'?`,\n );\n } else {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: `Quotes are required around environment variable values by your shell: CONVEX_DEPLOY_KEY='project:name:project|${key.slice(0, 4)}...${key.slice(key.length - 4)}=' npx convex dev`,\n });\n }\n }\n }\n}\n\nexport function getBuildEnvironment(): string | false {\n return process.env.VERCEL\n ? \"Vercel\"\n : process.env.NETLIFY\n ? \"Netlify\"\n : process.env.CF_PAGES || process.env.WORKERS_CI\n ? \"Cloudflare\"\n : false;\n}\n\nexport function getDefaultDeployMessage(): string | null {\n const platforms: Array<{\n name: string;\n detect: () => boolean;\n commitShaVar: string;\n }> = [\n {\n name: \"GitHub Actions\",\n detect: () => !!process.env.GITHUB_ACTIONS,\n commitShaVar: \"GITHUB_SHA\",\n },\n {\n name: \"Vercel\",\n detect: () => !!process.env.VERCEL,\n commitShaVar: \"VERCEL_GIT_COMMIT_SHA\",\n },\n {\n name: \"Netlify\",\n detect: () => !!process.env.NETLIFY,\n commitShaVar: \"COMMIT_REF\",\n },\n {\n name: \"Cloudflare Pages\",\n detect: () => !!process.env.CF_PAGES,\n commitShaVar: \"CF_PAGES_COMMIT_SHA\",\n },\n {\n name: \"Cloudflare Workers\",\n detect: () => !!process.env.WORKERS_CI,\n commitShaVar: \"WORKERS_CI_COMMIT_SHA\",\n },\n {\n name: \"Render\",\n detect: () => !!process.env.RENDER,\n commitShaVar: \"RENDER_GIT_COMMIT\",\n },\n {\n name: \"Railway\",\n detect: () => !!process.env.RAILWAY_ENVIRONMENT,\n commitShaVar: \"RAILWAY_GIT_COMMIT_SHA\",\n },\n {\n name: \"GitLab CI\",\n detect: () => !!process.env.GITLAB_CI,\n commitShaVar: \"CI_COMMIT_SHA\",\n },\n {\n name: \"CircleCI\",\n detect: () => !!process.env.CIRCLECI,\n commitShaVar: \"CIRCLE_SHA1\",\n },\n {\n name: \"Google Cloud Build\",\n detect: () =>\n !!process.env.BUILD_ID &&\n !!process.env.PROJECT_ID &&\n !!process.env.PROJECT_NUMBER &&\n !!process.env.LOCATION,\n commitShaVar: \"SHORT_SHA\",\n },\n {\n name: \"Heroku\",\n detect: () => !!process.env.HEROKU_APP_NAME || !!process.env.DYNO,\n commitShaVar: \"HEROKU_BUILD_COMMIT\",\n },\n ];\n\n const platform = platforms.find((p) => p.detect());\n if (!platform) {\n return null;\n }\n\n const commitSha = process.env[platform.commitShaVar];\n if (!commitSha) {\n return `Deployed from ${platform.name}`;\n }\n\n const shortSha = commitSha.slice(0, 7);\n return `Deployed from ${platform.name} \u2022 ${shortSha}`;\n}\n\nexport function gitBranchFromEnvironment(): string | null {\n if (process.env.VERCEL) {\n // https://vercel.com/docs/projects/environment-variables/system-environment-variables\n return process.env.VERCEL_GIT_COMMIT_REF ?? null;\n }\n if (process.env.NETLIFY) {\n // https://docs.netlify.com/configure-builds/environment-variables/\n return process.env.HEAD ?? null;\n }\n if (process.env.CF_PAGES || process.env.WORKERS_CI) {\n // https://developers.cloudflare.com/pages/configuration/build-configuration/#environment-variables\n // https://developers.cloudflare.com/workers/ci-cd/builds/configuration/#environment-variables\n return process.env.CF_PAGES_BRANCH ?? process.env.WORKERS_CI_BRANCH ?? null;\n }\n\n if (process.env.CI) {\n // https://docs.github.com/en/actions/learn-github-actions/variables\n // https://docs.gitlab.com/ee/ci/variables/predefined_variables.html\n return (\n process.env.GITHUB_HEAD_REF ?? process.env.CI_COMMIT_REF_NAME ?? null\n );\n }\n\n return null;\n}\n\nexport function isNonProdBuildEnvironment(): boolean {\n if (process.env.VERCEL) {\n // https://vercel.com/docs/projects/environment-variables/system-environment-variables\n return process.env.VERCEL_ENV !== \"production\";\n }\n if (process.env.NETLIFY) {\n // https://docs.netlify.com/configure-builds/environment-variables/\n return process.env.CONTEXT !== \"production\";\n }\n if (process.env.CF_PAGES || process.env.WORKERS_CI) {\n // https://developers.cloudflare.com/pages/configuration/build-configuration/#environment-variables\n // https://developers.cloudflare.com/workers/ci-cd/builds/configuration/#environment-variables\n // Branch !== \"main\" is the closest heuristic; Cloudflare Pages\n // does not expose a dedicated production/preview flag.\n const branch = process.env.CF_PAGES_BRANCH ?? process.env.WORKERS_CI_BRANCH;\n return branch !== \"main\";\n }\n return false;\n}\n"],
|
|
5
|
-
"mappings": ";AAGA,SAAS,mBAAmB;AAC5B,YAAY,YAAY;AAGxB,SAAS,kBAAkB;AAC3B,SAAS,
|
|
4
|
+
"sourcesContent": ["/**\n * Help the developer store the CONVEX_URL environment variable.\n */\nimport { chalkStderr } from \"chalk\";\nimport * as dotenv from \"dotenv\";\n\nimport { Context } from \"../../bundler/context.js\";\nimport { logWarning } from \"../../bundler/log.js\";\nimport {\n CONVEX_DEPLOY_KEY_ENV_VAR_NAME,\n readDeployKeyEnvVar,\n ENV_VAR_FILE_PATH,\n loadPackageJson,\n} from \"./utils/utils.js\";\n\nexport const CONVEX_ACCOUNT_ENV_VAR = \"CONVEX_ACCOUNT\";\n\nconst loadedEnvironment = new Map<string, { value: string; source: string }>();\n\nexport function loadProjectEnvironmentVariables() {\n // Only remove values supplied by our previous load; later shell overrides win.\n for (const [name, { value }] of loadedEnvironment) {\n if (process.env[name] === value) delete process.env[name];\n }\n loadedEnvironment.clear();\n const environment: Record<string, string> = {};\n for (const [name, value] of Object.entries(process.env)) {\n if (value !== undefined) environment[name] = value;\n }\n for (const file of [ENV_VAR_FILE_PATH, \".env\"]) {\n dotenv.config({ path: file, processEnv: environment });\n for (const [name, value] of Object.entries(environment)) {\n // Account selection reads the current project's files directly.\n if (name !== CONVEX_ACCOUNT_ENV_VAR && process.env[name] === undefined) {\n process.env[name] = value;\n loadedEnvironment.set(name, { value, source: file });\n }\n }\n }\n}\n\nexport function getDeployKeySource(key: string) {\n const envVarName =\n readDeployKeyEnvVar((name) => process.env[name])?.name ??\n CONVEX_DEPLOY_KEY_ENV_VAR_NAME;\n const loaded = loadedEnvironment.get(envVarName);\n return {\n envVarName,\n source: loaded?.value === key ? loaded.source : \"shell environment\",\n };\n}\n\nconst _FRAMEWORKS = [\n \"create-react-app\",\n \"Next.js\",\n \"Vite\",\n \"Remix\",\n \"SvelteKit\",\n \"Expo\",\n \"TanStackStart\",\n] as const;\ntype Framework = (typeof _FRAMEWORKS)[number];\n\n/**\n * A configuration for writing the actual (framework specific) `CONVEX_URL`\n * and `CONVEX_SITE_URL` environment variables to a \".env\" type file.\n *\n * May be `null` if there was an error determining any of the field values.\n */\ntype EnvFileUrlConfig = {\n /** The name of the file - typically `.env.local` */\n envFile: string;\n /**\n * The framework specific `CONVEX_URL`\n *\n * If `null`, ignore and don't update that environment variable.\n */\n convexUrlEnvVar: string | null;\n /**\n * The framework specific `CONVEX_SITE_URL`\n *\n * If `null`, ignore and don't update that environment variable.\n */\n siteUrlEnvVar: string | null;\n /** Existing content loaded from the `envFile`, if it exists */\n existingFileContent: string | null;\n} | null;\n\nexport async function writeUrlsToEnvFile(\n ctx: Context,\n options: {\n convexUrl: string;\n siteUrl?: string | null | undefined;\n },\n): Promise<EnvFileUrlConfig> {\n const envFileConfig = await loadEnvFileUrlConfig(ctx, options);\n\n if (envFileConfig === null) {\n return null;\n }\n\n const { envFile, convexUrlEnvVar, siteUrlEnvVar, existingFileContent } =\n envFileConfig;\n let updatedFileContent: string | null = null;\n if (convexUrlEnvVar) {\n updatedFileContent = changedEnvVarFile({\n existingFileContent,\n envVarName: convexUrlEnvVar,\n envVarValue: options.convexUrl,\n commentAfterValue: null,\n commentOnPreviousLine: null,\n })!;\n }\n if (siteUrlEnvVar && options.siteUrl) {\n updatedFileContent = changedEnvVarFile({\n existingFileContent: updatedFileContent ?? existingFileContent,\n envVarName: siteUrlEnvVar,\n envVarValue: options.siteUrl,\n commentAfterValue: null,\n commentOnPreviousLine: null,\n })!;\n }\n if (updatedFileContent) {\n ctx.fs.writeUtf8File(envFile, updatedFileContent);\n }\n\n return envFileConfig;\n}\n\nexport function changedEnvVarFile({\n existingFileContent,\n envVarName,\n envVarValue,\n commentAfterValue,\n commentOnPreviousLine,\n}: {\n existingFileContent: string | null;\n envVarName: string;\n envVarValue: string;\n commentAfterValue: string | null;\n commentOnPreviousLine: string | null;\n}): string | null {\n const varAssignment = `${envVarName}=${envVarValue}${\n commentAfterValue === null ? \"\" : ` # ${commentAfterValue}`\n }`;\n const commentOnPreviousLineWithLineBreak =\n commentOnPreviousLine === null ? \"\" : `${commentOnPreviousLine}\\n`;\n if (existingFileContent === null) {\n return `${commentOnPreviousLineWithLineBreak}${varAssignment}\\n`;\n }\n const config = dotenv.parse(existingFileContent);\n const existing = config[envVarName];\n if (existing === envVarValue) {\n return null;\n }\n if (existing !== undefined) {\n return existingFileContent.replace(\n getEnvVarRegex(envVarName),\n `${varAssignment}`,\n );\n } else {\n const doubleLineBreak = existingFileContent.endsWith(\"\\n\") ? \"\\n\" : \"\\n\\n\";\n return (\n existingFileContent +\n doubleLineBreak +\n commentOnPreviousLineWithLineBreak +\n varAssignment +\n \"\\n\"\n );\n }\n}\n\nexport function getEnvVarRegex(envVarName: string) {\n return new RegExp(`^${envVarName}.*$`, \"m\");\n}\n\nexport async function suggestedEnvVarNames(ctx: Context): Promise<{\n detectedFramework?: Framework;\n convexUrlEnvVar: ConvexUrlEnvVar;\n convexSiteEnvVar: ConvexSiteUrlEnvVar;\n frontendDevUrl?: string;\n publicPrefix?: string;\n}> {\n // no package.json, that's fine, just guess\n if (!ctx.fs.exists(\"package.json\")) {\n return {\n convexUrlEnvVar: \"CONVEX_URL\",\n convexSiteEnvVar: \"CONVEX_SITE_URL\",\n };\n }\n\n const packages = await loadPackageJson(ctx);\n\n // Is it create-react-app?\n const isCreateReactApp = \"react-scripts\" in packages;\n if (isCreateReactApp) {\n return {\n detectedFramework: \"create-react-app\",\n convexUrlEnvVar: \"REACT_APP_CONVEX_URL\",\n convexSiteEnvVar: \"REACT_APP_CONVEX_SITE_URL\",\n frontendDevUrl: \"http://localhost:3000\",\n publicPrefix: \"REACT_APP_\",\n };\n }\n\n const isNextJs = \"next\" in packages;\n if (isNextJs) {\n return {\n detectedFramework: \"Next.js\",\n convexUrlEnvVar: \"NEXT_PUBLIC_CONVEX_URL\",\n convexSiteEnvVar: \"NEXT_PUBLIC_CONVEX_SITE_URL\",\n frontendDevUrl: \"http://localhost:3000\",\n publicPrefix: \"NEXT_PUBLIC_\",\n };\n }\n\n const isExpo = \"expo\" in packages;\n if (isExpo) {\n return {\n detectedFramework: \"Expo\",\n convexUrlEnvVar: \"EXPO_PUBLIC_CONVEX_URL\",\n convexSiteEnvVar: \"EXPO_PUBLIC_CONVEX_SITE_URL\",\n publicPrefix: \"EXPO_PUBLIC_\",\n };\n }\n\n const isSvelteKit = \"@sveltejs/kit\" in packages;\n if (isSvelteKit) {\n return {\n detectedFramework: \"SvelteKit\",\n convexUrlEnvVar: \"PUBLIC_CONVEX_URL\",\n convexSiteEnvVar: \"PUBLIC_CONVEX_SITE_URL\",\n frontendDevUrl: \"http://localhost:5173\",\n publicPrefix: \"PUBLIC_\",\n };\n }\n\n // TanStackStart currently supports VITE_FOO for browser-side envvars.\n const isTanStackStart =\n \"@tanstack/start\" in packages || \"@tanstack/react-start\" in packages;\n\n if (isTanStackStart) {\n return {\n detectedFramework: \"TanStackStart\",\n convexUrlEnvVar: \"VITE_CONVEX_URL\",\n convexSiteEnvVar: \"VITE_CONVEX_SITE_URL\",\n frontendDevUrl: \"http://localhost:3000\",\n publicPrefix: \"VITE_\",\n };\n }\n\n // Vite is a dependency of a lot of things; vite appearing in dependencies is not a strong indicator.\n const isVite = \"vite\" in packages;\n\n if (isVite) {\n return {\n detectedFramework: \"Vite\",\n convexUrlEnvVar: \"VITE_CONVEX_URL\",\n convexSiteEnvVar: \"VITE_CONVEX_SITE_URL\",\n frontendDevUrl: \"http://localhost:5173\",\n publicPrefix: \"VITE_\",\n };\n }\n\n // We detect Remix after Vite because when using Remix as a plugin of Vite\n // (Remix Vite), we want to use Vite-style environment variables.\n const isRemix = \"@remix-run/dev\" in packages;\n if (isRemix) {\n return {\n detectedFramework: \"Remix\",\n convexUrlEnvVar: \"CONVEX_URL\",\n convexSiteEnvVar: \"CONVEX_SITE_URL\",\n frontendDevUrl: \"http://localhost:3000\",\n };\n }\n\n return {\n convexUrlEnvVar: \"CONVEX_URL\",\n convexSiteEnvVar: \"CONVEX_SITE_URL\",\n };\n}\n\nasync function loadEnvFileUrlConfig(\n ctx: Context,\n options: {\n convexUrl: string;\n siteUrl?: string | null | undefined;\n },\n): Promise<EnvFileUrlConfig> {\n const { detectedFramework, convexUrlEnvVar, convexSiteEnvVar } =\n await suggestedEnvVarNames(ctx);\n\n const { envFile, existing } = suggestedDevEnvFile(ctx, detectedFramework);\n\n if (!existing) {\n return {\n envFile,\n convexUrlEnvVar,\n siteUrlEnvVar: convexSiteEnvVar,\n existingFileContent: null,\n };\n }\n\n const existingFileContent = ctx.fs.readUtf8File(envFile);\n const config = dotenv.parse(existingFileContent);\n\n const resolvedConvexUrlEnvVar = resolveEnvVarName(\n convexUrlEnvVar,\n options.convexUrl,\n envFile,\n config,\n EXPECTED_CONVEX_URL_NAMES,\n );\n const resolvedSiteUrlEnvVar = resolveEnvVarName(\n convexSiteEnvVar,\n options.siteUrl ?? \"\",\n envFile,\n config,\n EXPECTED_SITE_URL_NAMES,\n );\n if (\n resolvedConvexUrlEnvVar.kind === \"invalid\" ||\n resolvedSiteUrlEnvVar.kind === \"invalid\"\n ) {\n return null;\n }\n return {\n envFile,\n convexUrlEnvVar: resolvedConvexUrlEnvVar.envVarName,\n siteUrlEnvVar: resolvedSiteUrlEnvVar.envVarName,\n existingFileContent,\n };\n}\n\nfunction resolveEnvVarName(\n envVarName: string,\n envVarValue: string,\n envFile: string,\n config: dotenv.DotenvParseOutput,\n expectedNames: Set<string>,\n):\n | {\n kind: \"invalid\";\n }\n | {\n kind: \"valid\";\n envVarName: string | null;\n } {\n const matching = Object.keys(config).filter((key) => expectedNames.has(key));\n if (matching.length > 1) {\n logWarning(\n chalkStderr.yellow(\n `Found multiple ${envVarName} environment variables in ${envFile} so cannot update automatically.`,\n ),\n );\n return { kind: \"invalid\" };\n }\n if (matching.length === 1) {\n const [existingEnvVarName, oldValue] = [matching[0], config[matching[0]]];\n if (oldValue === envVarValue) {\n // Set envVarName to null to indicate that it shouldn't be updated.\n return { kind: \"valid\", envVarName: null };\n }\n if (\n oldValue !== \"\" &&\n Object.values(config).filter((v) => v === oldValue).length !== 1\n ) {\n logWarning(\n chalkStderr.yellow(\n `Can't safely modify ${envFile} for ${envVarName}, please edit manually.`,\n ),\n );\n return { kind: \"invalid\" };\n }\n return { kind: \"valid\", envVarName: existingEnvVarName };\n }\n return { kind: \"valid\", envVarName };\n}\n\nfunction suggestedDevEnvFile(\n ctx: Context,\n framework?: Framework,\n): {\n existing: boolean;\n envFile: string;\n} {\n // If a .env.local file exists, that's unequivocally the right file\n if (ctx.fs.exists(\".env.local\")) {\n return {\n existing: true,\n envFile: \".env.local\",\n };\n }\n\n // Remix is on team \"don't commit the .env file,\" so .env is for dev.\n if (framework === \"Remix\") {\n return {\n existing: ctx.fs.exists(\".env\"),\n envFile: \".env\",\n };\n }\n\n // The most dev-looking env file that exists, or .env.local\n return {\n existing: ctx.fs.exists(\".env.local\"),\n envFile: \".env.local\",\n };\n}\n\nexport const EXPECTED_CONVEX_URL_NAMES = new Set([\n \"CONVEX_URL\" as const,\n \"PUBLIC_CONVEX_URL\" as const,\n \"NEXT_PUBLIC_CONVEX_URL\" as const,\n \"VITE_CONVEX_URL\" as const,\n \"REACT_APP_CONVEX_URL\" as const,\n \"EXPO_PUBLIC_CONVEX_URL\" as const,\n]);\ntype ConvexUrlEnvVar =\n typeof EXPECTED_CONVEX_URL_NAMES extends Set<infer T> ? T : never;\n\nexport const EXPECTED_SITE_URL_NAMES = new Set([\n \"CONVEX_SITE_URL\" as const,\n \"PUBLIC_CONVEX_SITE_URL\" as const,\n \"NEXT_PUBLIC_CONVEX_SITE_URL\" as const,\n \"VITE_CONVEX_SITE_URL\" as const,\n \"REACT_APP_CONVEX_SITE_URL\" as const,\n \"EXPO_PUBLIC_CONVEX_SITE_URL\" as const,\n]);\ntype ConvexSiteUrlEnvVar =\n typeof EXPECTED_SITE_URL_NAMES extends Set<infer T> ? T : never;\n\n// Crash or warn on\n// CONVEX_DEPLOY_KEY=project:me:new-project|eyABCD0= npx convex\n// which parses as\n// CONVEX_DEPLOY_KEY=project:me:new-project | eyABCD0='' npx convex\n// when what was intended was\n// CONVEX_DEPLOY_KEY=project:me:new-project|eyABCD0= npx convex\n// This only fails so catastrophically when the key ends with `=`.\nexport async function detectSuspiciousEnvironmentVariables(\n ctx: Context,\n ignoreSuspiciousEnvVars = false,\n) {\n for (const [key, value] of Object.entries(process.env)) {\n if (value === \"\" && key.startsWith(\"ey\")) {\n try {\n // add a \"=\" to the end and try to base64 decode (expected format of Convex keys)\n const decoded = JSON.parse(\n Buffer.from(key + \"=\", \"base64\").toString(\"utf8\"),\n );\n // Only parseable v2 tokens to be sure this is a Convex token before complaining.\n if (!(\"v2\" in decoded)) {\n continue;\n }\n } catch {\n continue;\n }\n\n if (ignoreSuspiciousEnvVars) {\n logWarning(\n `ignoring suspicious environment variable ${key}, did you mean to use quotes like CONVEX_DEPLOY_KEY='...'?`,\n );\n } else {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: `Quotes are required around environment variable values by your shell: CONVEX_DEPLOY_KEY='project:name:project|${key.slice(0, 4)}...${key.slice(key.length - 4)}=' npx convex dev`,\n });\n }\n }\n }\n}\n\nexport function getBuildEnvironment(): string | false {\n return process.env.VERCEL\n ? \"Vercel\"\n : process.env.NETLIFY\n ? \"Netlify\"\n : process.env.CF_PAGES || process.env.WORKERS_CI\n ? \"Cloudflare\"\n : false;\n}\n\nexport function getDefaultDeployMessage(): string | null {\n const platforms: Array<{\n name: string;\n detect: () => boolean;\n commitShaVar: string;\n }> = [\n {\n name: \"GitHub Actions\",\n detect: () => !!process.env.GITHUB_ACTIONS,\n commitShaVar: \"GITHUB_SHA\",\n },\n {\n name: \"Vercel\",\n detect: () => !!process.env.VERCEL,\n commitShaVar: \"VERCEL_GIT_COMMIT_SHA\",\n },\n {\n name: \"Netlify\",\n detect: () => !!process.env.NETLIFY,\n commitShaVar: \"COMMIT_REF\",\n },\n {\n name: \"Cloudflare Pages\",\n detect: () => !!process.env.CF_PAGES,\n commitShaVar: \"CF_PAGES_COMMIT_SHA\",\n },\n {\n name: \"Cloudflare Workers\",\n detect: () => !!process.env.WORKERS_CI,\n commitShaVar: \"WORKERS_CI_COMMIT_SHA\",\n },\n {\n name: \"Render\",\n detect: () => !!process.env.RENDER,\n commitShaVar: \"RENDER_GIT_COMMIT\",\n },\n {\n name: \"Railway\",\n detect: () => !!process.env.RAILWAY_ENVIRONMENT,\n commitShaVar: \"RAILWAY_GIT_COMMIT_SHA\",\n },\n {\n name: \"GitLab CI\",\n detect: () => !!process.env.GITLAB_CI,\n commitShaVar: \"CI_COMMIT_SHA\",\n },\n {\n name: \"CircleCI\",\n detect: () => !!process.env.CIRCLECI,\n commitShaVar: \"CIRCLE_SHA1\",\n },\n {\n name: \"Google Cloud Build\",\n detect: () =>\n !!process.env.BUILD_ID &&\n !!process.env.PROJECT_ID &&\n !!process.env.PROJECT_NUMBER &&\n !!process.env.LOCATION,\n commitShaVar: \"SHORT_SHA\",\n },\n {\n name: \"Heroku\",\n detect: () => !!process.env.HEROKU_APP_NAME || !!process.env.DYNO,\n commitShaVar: \"HEROKU_BUILD_COMMIT\",\n },\n ];\n\n const platform = platforms.find((p) => p.detect());\n if (!platform) {\n return null;\n }\n\n const commitSha = process.env[platform.commitShaVar];\n if (!commitSha) {\n return `Deployed from ${platform.name}`;\n }\n\n const shortSha = commitSha.slice(0, 7);\n return `Deployed from ${platform.name} \u2022 ${shortSha}`;\n}\n\nexport function gitBranchFromEnvironment(): string | null {\n if (process.env.VERCEL) {\n // https://vercel.com/docs/projects/environment-variables/system-environment-variables\n return process.env.VERCEL_GIT_COMMIT_REF ?? null;\n }\n if (process.env.NETLIFY) {\n // https://docs.netlify.com/configure-builds/environment-variables/\n return process.env.HEAD ?? null;\n }\n if (process.env.CF_PAGES || process.env.WORKERS_CI) {\n // https://developers.cloudflare.com/pages/configuration/build-configuration/#environment-variables\n // https://developers.cloudflare.com/workers/ci-cd/builds/configuration/#environment-variables\n return process.env.CF_PAGES_BRANCH ?? process.env.WORKERS_CI_BRANCH ?? null;\n }\n\n if (process.env.CI) {\n // https://docs.github.com/en/actions/learn-github-actions/variables\n // https://docs.gitlab.com/ee/ci/variables/predefined_variables.html\n return (\n process.env.GITHUB_HEAD_REF ?? process.env.CI_COMMIT_REF_NAME ?? null\n );\n }\n\n return null;\n}\n\nexport function isNonProdBuildEnvironment(): boolean {\n if (process.env.VERCEL) {\n // https://vercel.com/docs/projects/environment-variables/system-environment-variables\n return process.env.VERCEL_ENV !== \"production\";\n }\n if (process.env.NETLIFY) {\n // https://docs.netlify.com/configure-builds/environment-variables/\n return process.env.CONTEXT !== \"production\";\n }\n if (process.env.CF_PAGES || process.env.WORKERS_CI) {\n // https://developers.cloudflare.com/pages/configuration/build-configuration/#environment-variables\n // https://developers.cloudflare.com/workers/ci-cd/builds/configuration/#environment-variables\n // Branch !== \"main\" is the closest heuristic; Cloudflare Pages\n // does not expose a dedicated production/preview flag.\n const branch = process.env.CF_PAGES_BRANCH ?? process.env.WORKERS_CI_BRANCH;\n return branch !== \"main\";\n }\n return false;\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|