convex 1.47.0 → 1.48.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 +28 -4
- package/README.md +1 -1
- package/dist/browser.bundle.js +1 -1
- package/dist/browser.bundle.js.map +1 -1
- package/dist/cjs/cli/aiFiles.js +26 -4
- package/dist/cjs/cli/aiFiles.js.map +2 -2
- package/dist/cjs/cli/env.js +6 -3
- package/dist/cjs/cli/env.js.map +2 -2
- package/dist/cjs/cli/envDefault.js +5 -2
- package/dist/cjs/cli/envDefault.js.map +2 -2
- package/dist/cjs/cli/lib/aiFiles/guidelinesmd.js +2 -1
- package/dist/cjs/cli/lib/aiFiles/guidelinesmd.js.map +2 -2
- package/dist/cjs/cli/lib/aiFiles/index.js +13 -2
- package/dist/cjs/cli/lib/aiFiles/index.js.map +2 -2
- package/dist/cjs/cli/lib/aiFiles/skills.js +6 -5
- package/dist/cjs/cli/lib/aiFiles/skills.js.map +2 -2
- package/dist/cjs/cli/lib/aiFiles/state.js +1 -1
- package/dist/cjs/cli/lib/aiFiles/state.js.map +1 -1
- package/dist/cjs/cli/lib/components.js +12 -2
- package/dist/cjs/cli/lib/components.js.map +2 -2
- package/dist/cjs/cli/lib/deployApi/startPush.js +42 -1
- package/dist/cjs/cli/lib/deployApi/startPush.js.map +2 -2
- package/dist/cjs/cli/lib/env.js +9 -1
- package/dist/cjs/cli/lib/env.js.map +2 -2
- package/dist/cjs/cli/lib/localDeployment/dashboard.js +11 -1
- package/dist/cjs/cli/lib/localDeployment/dashboard.js.map +2 -2
- package/dist/cjs/cli/lib/localDeployment/download.js +16 -1
- package/dist/cjs/cli/lib/localDeployment/download.js.map +2 -2
- package/dist/cjs/cli/lib/localDeployment/utils.js +4 -0
- package/dist/cjs/cli/lib/localDeployment/utils.js.map +2 -2
- package/dist/cjs/cli/lib/utils/aiAgent.js +32 -0
- package/dist/cjs/cli/lib/utils/aiAgent.js.map +7 -0
- package/dist/cjs/index.js +1 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/server/authentication.js.map +1 -1
- package/dist/cjs/server/components/index.js.map +2 -2
- package/dist/cjs/server/impl/authentication_impl.js +15 -1
- package/dist/cjs/server/impl/authentication_impl.js.map +2 -2
- package/dist/cjs/server/impl/registration_impl.js +1 -1
- package/dist/cjs/server/impl/registration_impl.js.map +2 -2
- 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 +0 -2
- package/dist/cjs/server/schema.js.map +2 -2
- package/dist/cjs/server/storage.js.map +1 -1
- package/dist/cjs-types/cli/aiFiles.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/lib/aiFiles/guidelinesmd.d.ts +3 -1
- package/dist/cjs-types/cli/lib/aiFiles/guidelinesmd.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/aiFiles/index.d.ts +11 -1
- package/dist/cjs-types/cli/lib/aiFiles/index.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/aiFiles/skills.d.ts +4 -1
- package/dist/cjs-types/cli/lib/aiFiles/skills.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/components.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/deployApi/startPush.d.ts +13 -0
- package/dist/cjs-types/cli/lib/deployApi/startPush.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/env.d.ts +1 -0
- package/dist/cjs-types/cli/lib/env.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/localDeployment/dashboard.d.ts +6 -0
- package/dist/cjs-types/cli/lib/localDeployment/dashboard.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/localDeployment/download.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/localDeployment/utils.d.ts +1 -0
- package/dist/cjs-types/cli/lib/localDeployment/utils.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/utils/aiAgent.d.ts +8 -0
- package/dist/cjs-types/cli/lib/utils/aiAgent.d.ts.map +1 -0
- package/dist/cjs-types/index.d.ts +1 -1
- package/dist/cjs-types/server/authentication.d.ts +65 -0
- package/dist/cjs-types/server/authentication.d.ts.map +1 -1
- package/dist/cjs-types/server/components/index.d.ts +6 -0
- package/dist/cjs-types/server/components/index.d.ts.map +1 -1
- package/dist/cjs-types/server/impl/authentication_impl.d.ts +2 -1
- package/dist/cjs-types/server/impl/authentication_impl.d.ts.map +1 -1
- package/dist/cjs-types/server/index.d.ts +2 -2
- package/dist/cjs-types/server/index.d.ts.map +1 -1
- package/dist/cjs-types/server/meta.d.ts +8 -0
- package/dist/cjs-types/server/meta.d.ts.map +1 -1
- package/dist/cjs-types/server/registration.d.ts +5 -3
- package/dist/cjs-types/server/registration.d.ts.map +1 -1
- package/dist/cjs-types/server/schema.d.ts +0 -2
- package/dist/cjs-types/server/schema.d.ts.map +1 -1
- package/dist/cjs-types/server/storage.d.ts +28 -25
- package/dist/cjs-types/server/storage.d.ts.map +1 -1
- package/dist/cli.bundle.cjs +284 -25
- package/dist/cli.bundle.cjs.map +4 -4
- package/dist/esm/cli/aiFiles.js +26 -4
- package/dist/esm/cli/aiFiles.js.map +2 -2
- package/dist/esm/cli/env.js +6 -3
- package/dist/esm/cli/env.js.map +2 -2
- package/dist/esm/cli/envDefault.js +5 -2
- package/dist/esm/cli/envDefault.js.map +2 -2
- package/dist/esm/cli/lib/aiFiles/guidelinesmd.js +2 -1
- package/dist/esm/cli/lib/aiFiles/guidelinesmd.js.map +2 -2
- package/dist/esm/cli/lib/aiFiles/index.js +13 -2
- package/dist/esm/cli/lib/aiFiles/index.js.map +2 -2
- package/dist/esm/cli/lib/aiFiles/skills.js +6 -5
- package/dist/esm/cli/lib/aiFiles/skills.js.map +2 -2
- package/dist/esm/cli/lib/aiFiles/state.js +1 -1
- package/dist/esm/cli/lib/aiFiles/state.js.map +1 -1
- package/dist/esm/cli/lib/components.js +15 -2
- package/dist/esm/cli/lib/components.js.map +2 -2
- package/dist/esm/cli/lib/deployApi/startPush.js +39 -0
- package/dist/esm/cli/lib/deployApi/startPush.js.map +2 -2
- package/dist/esm/cli/lib/env.js +9 -1
- package/dist/esm/cli/lib/env.js.map +2 -2
- package/dist/esm/cli/lib/localDeployment/dashboard.js +9 -0
- package/dist/esm/cli/lib/localDeployment/dashboard.js.map +2 -2
- package/dist/esm/cli/lib/localDeployment/download.js +16 -1
- package/dist/esm/cli/lib/localDeployment/download.js.map +2 -2
- package/dist/esm/cli/lib/localDeployment/utils.js +3 -0
- package/dist/esm/cli/lib/localDeployment/utils.js.map +2 -2
- package/dist/esm/cli/lib/utils/aiAgent.js +10 -0
- package/dist/esm/cli/lib/utils/aiAgent.js.map +7 -0
- package/dist/esm/index.js +1 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/server/components/index.js.map +2 -2
- package/dist/esm/server/impl/authentication_impl.js +13 -0
- package/dist/esm/server/impl/authentication_impl.js.map +2 -2
- package/dist/esm/server/impl/registration_impl.js +2 -2
- package/dist/esm/server/impl/registration_impl.js.map +2 -2
- package/dist/esm/server/index.js.map +2 -2
- package/dist/esm/server/schema.js +0 -2
- package/dist/esm/server/schema.js.map +2 -2
- package/dist/esm-types/cli/aiFiles.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/lib/aiFiles/guidelinesmd.d.ts +3 -1
- package/dist/esm-types/cli/lib/aiFiles/guidelinesmd.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/aiFiles/index.d.ts +11 -1
- package/dist/esm-types/cli/lib/aiFiles/index.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/aiFiles/skills.d.ts +4 -1
- package/dist/esm-types/cli/lib/aiFiles/skills.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/components.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/deployApi/startPush.d.ts +13 -0
- package/dist/esm-types/cli/lib/deployApi/startPush.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/env.d.ts +1 -0
- package/dist/esm-types/cli/lib/env.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/localDeployment/dashboard.d.ts +6 -0
- package/dist/esm-types/cli/lib/localDeployment/dashboard.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/localDeployment/download.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/localDeployment/utils.d.ts +1 -0
- package/dist/esm-types/cli/lib/localDeployment/utils.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/utils/aiAgent.d.ts +8 -0
- package/dist/esm-types/cli/lib/utils/aiAgent.d.ts.map +1 -0
- package/dist/esm-types/index.d.ts +1 -1
- package/dist/esm-types/server/authentication.d.ts +65 -0
- package/dist/esm-types/server/authentication.d.ts.map +1 -1
- package/dist/esm-types/server/components/index.d.ts +6 -0
- package/dist/esm-types/server/components/index.d.ts.map +1 -1
- package/dist/esm-types/server/impl/authentication_impl.d.ts +2 -1
- package/dist/esm-types/server/impl/authentication_impl.d.ts.map +1 -1
- package/dist/esm-types/server/index.d.ts +2 -2
- package/dist/esm-types/server/index.d.ts.map +1 -1
- package/dist/esm-types/server/meta.d.ts +8 -0
- package/dist/esm-types/server/meta.d.ts.map +1 -1
- package/dist/esm-types/server/registration.d.ts +5 -3
- package/dist/esm-types/server/registration.d.ts.map +1 -1
- package/dist/esm-types/server/schema.d.ts +0 -2
- package/dist/esm-types/server/schema.d.ts.map +1 -1
- package/dist/esm-types/server/storage.d.ts +28 -25
- package/dist/esm-types/server/storage.d.ts.map +1 -1
- package/dist/react.bundle.js +1 -1
- package/dist/react.bundle.js.map +1 -1
- package/package.json +3 -2
- package/schemas/convex.schema.json +1 -2
- package/src/cli/aiFiles.ts +30 -4
- package/src/cli/env.ts +4 -1
- package/src/cli/envDefault.ts +4 -1
- package/src/cli/lib/aiFiles/guidelinesmd.ts +7 -2
- package/src/cli/lib/aiFiles/index.ts +23 -3
- package/src/cli/lib/aiFiles/skills.ts +11 -7
- package/src/cli/lib/aiFiles/state.ts +1 -1
- package/src/cli/lib/components.ts +18 -3
- package/src/cli/lib/deployApi/startPush.ts +64 -0
- package/src/cli/lib/env.ts +13 -2
- package/src/cli/lib/localDeployment/dashboard.ts +19 -0
- package/src/cli/lib/localDeployment/download.ts +17 -1
- package/src/cli/lib/localDeployment/utils.ts +4 -0
- package/src/cli/lib/utils/aiAgent.ts +15 -0
- package/src/index.ts +1 -1
- package/src/server/authentication.ts +79 -0
- package/src/server/components/index.ts +11 -0
- package/src/server/impl/authentication_impl.ts +15 -1
- package/src/server/impl/registration_impl.ts +2 -2
- package/src/server/index.ts +6 -0
- package/src/server/meta.ts +0 -8
- package/src/server/registration.ts +5 -2
- package/src/server/schema.ts +0 -2
- package/src/server/storage.ts +29 -42
|
@@ -48,6 +48,7 @@ var import_typecheck = require("./typecheck.js");
|
|
|
48
48
|
var import_fs = require("../../bundler/fs.js");
|
|
49
49
|
var import_debugBundlePath = require("./debugBundlePath.js");
|
|
50
50
|
var import_chalk = require("chalk");
|
|
51
|
+
var import_startPush = require("./deployApi/startPush.js");
|
|
51
52
|
var import_tracing = require("./tracing.js");
|
|
52
53
|
var import_constants = require("./components/constants.js");
|
|
53
54
|
var import_dashboard = require("./dashboard.js");
|
|
@@ -386,7 +387,9 @@ async function startComponentsPushAndCodegen(ctx, parentSpan, projectConfig, con
|
|
|
386
387
|
(span) => (0, import_deploy2.startPush)(ctx, span, startPushRequest, options)
|
|
387
388
|
);
|
|
388
389
|
if (options.verbose) {
|
|
389
|
-
(0, import_log.logMessage)(
|
|
390
|
+
(0, import_log.logMessage)(
|
|
391
|
+
"startPush: " + JSON.stringify((0, import_startPush.startPushResponseForLogging)(startPushResponse), null, 2)
|
|
392
|
+
);
|
|
390
393
|
}
|
|
391
394
|
if (options.codegen) {
|
|
392
395
|
(0, import_log.changeSpinner)("Generating TypeScript bindings...");
|
|
@@ -534,7 +537,14 @@ async function runComponentsPush(ctx, options, configPath, projectConfig) {
|
|
|
534
537
|
}
|
|
535
538
|
function printDiff(startPushResponse, finishPushResponse, opts) {
|
|
536
539
|
if (opts.verbose) {
|
|
537
|
-
const diffString = JSON.stringify(
|
|
540
|
+
const diffString = JSON.stringify(
|
|
541
|
+
(0, import_startPush.redactEnvironmentVariableValues)(
|
|
542
|
+
finishPushResponse,
|
|
543
|
+
startPushResponse.environmentVariables
|
|
544
|
+
),
|
|
545
|
+
null,
|
|
546
|
+
2
|
|
547
|
+
);
|
|
538
548
|
(0, import_log.logMessage)(diffString);
|
|
539
549
|
return;
|
|
540
550
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/cli/lib/components.ts"],
|
|
4
|
-
"sourcesContent": ["import path from \"path\";\nimport { Context } from \"../../bundler/context.js\";\nimport {\n changeSpinner,\n logFinishedStep,\n logMessage,\n} from \"../../bundler/log.js\";\nimport {\n ProjectConfig,\n configFromProjectConfig,\n debugIsolateEndpointBundles,\n getFunctionsDirectoryPath,\n readProjectConfig,\n pullConfig,\n diffConfig,\n} from \"./config.js\";\nimport {\n finishPush,\n reportPushCompleted,\n startPush,\n waitForSchema,\n} from \"./deploy2.js\";\nimport { version } from \"../version.js\";\nimport { ensureHasConvexDependency, functionsDir } from \"./utils/utils.js\";\nimport {\n bundleDefinitions,\n bundleImplementations,\n componentGraph,\n} from \"./components/definition/bundle.js\";\nimport { isComponentDirectory } from \"./components/definition/directoryStructure.js\";\nimport {\n doFinalComponentCodegen,\n doInitialComponentCodegen,\n CodegenOptions,\n doInitConvexFolder,\n doCodegen,\n} from \"./codegen.js\";\nimport {\n AppDefinitionConfig,\n ComponentDefinitionConfig,\n} from \"./deployApi/definitionConfig.js\";\nimport { typeCheckFunctionsInMode, TypeCheckMode } from \"./typecheck.js\";\nimport { withTmpDir } from \"../../bundler/fs.js\";\nimport { handleDebugBundlePath } from \"./debugBundlePath.js\";\nimport { chalkStderr } from \"chalk\";\nimport { StartPushRequest, StartPushResponse } from \"./deployApi/startPush.js\";\nimport { DetailedDeploymentCredentials } from \"./api.js\";\nimport { FinishPushDiff } from \"./deployApi/finishPush.js\";\nimport { Reporter, Span } from \"./tracing.js\";\nimport { DEFINITION_FILENAME_TS } from \"./components/constants.js\";\nimport { DeploymentType } from \"./api.js\";\nimport { deploymentDashboardUrlPage } from \"./dashboard.js\";\nimport { formatIndex, LargeIndexDeletionCheck } from \"./indexes.js\";\nimport { checkForLargeIndexDeletion } from \"./checkForLargeIndexDeletion.js\";\nimport { checkForSlowSchemaValidation } from \"./checkForSlowSchemaValidation.js\";\nimport {\n checkForLargeIndexBackfill,\n LargeIndexBackfillCheck,\n} from \"./checkForLargeIndexBackfill.js\";\nimport {\n pushStagesValidators,\n sharedSchemaEvaluation,\n} from \"./schemaEvaluation.js\";\nimport {\n checkForStagedValidatorDeletion,\n StagedValidatorDeletionCheck,\n} from \"./checkForStagedValidatorDeletion.js\";\nimport { LogManager } from \"./logs.js\";\nimport { createHash } from \"crypto\";\nimport { Bundle, BundleHash } from \"../../bundler/index.js\";\nimport { ModuleHashConfig } from \"./deployApi/modules.js\";\n\nexport type PushOptions = {\n adminKey: string;\n verbose: boolean;\n dryRun: boolean;\n typecheck: \"enable\" | \"try\" | \"disable\";\n typecheckComponents: boolean;\n debug: boolean;\n debugBundlePath?: string | undefined;\n debugNodeApis: boolean;\n codegen: boolean;\n url: string;\n deploymentName: string | null;\n deploymentType?: DeploymentType;\n writePushRequest?: string | undefined;\n liveComponentSources: boolean;\n pushAllModules: boolean;\n logManager?: LogManager | undefined;\n largeIndexDeletionCheck: LargeIndexDeletionCheck;\n largeIndexBackfillCheck: LargeIndexBackfillCheck;\n stagedValidatorDeletionCheck: StagedValidatorDeletionCheck;\n // Whether a dry run should warn when the schema change would block the\n // deploy on a slow table walk. On for deploys; off for commands whose dry\n // runs never deploy (e.g. codegen).\n warnOnSlowSchemaValidation: boolean;\n message: string | null;\n};\n\nexport async function runCodegen(\n ctx: Context,\n credentials: DetailedDeploymentCredentials | null,\n options: CodegenOptions,\n) {\n // This also ensures the current directory is the project root.\n await ensureHasConvexDependency(ctx, \"codegen\");\n\n const { configPath, projectConfig } = await readProjectConfig(ctx);\n const functionsDirectoryPath = functionsDir(configPath, projectConfig);\n\n if (options.init) {\n await doInitConvexFolder(ctx, functionsDirectoryPath, {\n dryRun: options.dryRun,\n debug: options.debug,\n });\n }\n\n if (!options.systemUdfs) {\n if (credentials === null) {\n return;\n }\n\n await startComponentsPushAndCodegen(\n ctx,\n Span.noop(),\n projectConfig,\n configPath,\n {\n ...options,\n deploymentName: credentials.deploymentFields?.deploymentName ?? null,\n ...(credentials.deploymentFields?.deploymentType !== undefined\n ? { deploymentType: credentials.deploymentFields.deploymentType }\n : {}),\n url: credentials.url,\n adminKey: credentials.adminKey,\n generateCommonJSApi: options.commonjs,\n verbose: !!process.env.CONVEX_VERBOSE,\n codegen: true,\n liveComponentSources: options.liveComponentSources,\n typecheckComponents: false,\n debugNodeApis: options.debugNodeApis,\n // Code generation uses the source schema independently of deployment data.\n largeIndexDeletionCheck: \"no verification\",\n largeIndexBackfillCheck: \"no verification\",\n stagedValidatorDeletionCheck: \"no verification\",\n warnOnSlowSchemaValidation: false,\n },\n );\n } else {\n if (options.typecheck !== \"disable\") {\n logMessage(chalkStderr.gray(\"Running TypeScript typecheck\u2026\"));\n }\n\n await doCodegen(ctx, functionsDirectoryPath, options.typecheck, {\n dryRun: options.dryRun,\n debug: options.debug,\n generateCommonJSApi: options.commonjs,\n });\n }\n}\n\nexport async function runPush(ctx: Context, options: PushOptions) {\n const { configPath, projectConfig } = await readProjectConfig(ctx);\n await runComponentsPush(ctx, options, configPath, projectConfig);\n}\n\nexport function hash(bundle: Bundle) {\n return createHash(\"sha256\")\n .update(bundle.source)\n .update(bundle.sourceMap || \"\")\n .digest(\"hex\");\n}\n\nfunction isModuleTheSame(newBundle: Bundle, oldBundleHash: BundleHash) {\n return (\n newBundle.environment === oldBundleHash.environment &&\n hash(newBundle) === oldBundleHash.hash\n );\n}\n\nexport function partitionModulesByChanges(\n functions: Bundle[],\n remoteHashesByPath: Map<string, BundleHash>,\n): {\n unchangedModuleHashes: ModuleHashConfig[];\n changedModules: Bundle[];\n} {\n // Partition modules based on whether they match the existing modules\n const unchangedModuleHashes = functions\n .filter((newBundle) => {\n const oldBundleHash = remoteHashesByPath.get(newBundle.path);\n return oldBundleHash && isModuleTheSame(newBundle, oldBundleHash);\n })\n .map((func) => ({\n path: func.path,\n environment: func.environment,\n sha256: hash(func),\n }));\n const changedModules = functions.filter((newBundle) => {\n const oldBundleHash = remoteHashesByPath.get(newBundle.path);\n return !oldBundleHash || !isModuleTheSame(newBundle, oldBundleHash);\n });\n return { unchangedModuleHashes, changedModules };\n}\n\nasync function getUnchangedModuleHashesFromServer(\n ctx: Context,\n appImplementation: { functions: Bundle[] },\n options: { url: string; adminKey: string },\n): Promise<{\n unchangedModuleHashes: ModuleHashConfig[];\n changedModules: Bundle[];\n}> {\n const remoteConfigWithModuleHashes = await pullConfig(\n ctx,\n undefined,\n undefined,\n options.url,\n options.adminKey,\n );\n const remoteHashesByPath = new Map(\n remoteConfigWithModuleHashes.moduleHashes.map((moduleHash) => [\n moduleHash.path,\n moduleHash,\n ]),\n );\n return partitionModulesByChanges(\n appImplementation.functions,\n remoteHashesByPath,\n );\n}\n\nasync function startComponentsPushAndCodegen(\n ctx: Context,\n parentSpan: Span,\n projectConfig: ProjectConfig,\n configPath: string,\n options: {\n typecheck: TypeCheckMode;\n typecheckComponents: boolean;\n adminKey: string;\n url: string;\n deploymentName: string | null;\n deploymentType?: DeploymentType;\n verbose: boolean;\n debugBundlePath?: string | undefined;\n dryRun: boolean;\n generateCommonJSApi?: boolean;\n debug: boolean;\n writePushRequest?: string | undefined;\n codegen: boolean;\n liveComponentSources?: boolean;\n pushAllModules?: boolean;\n debugNodeApis: boolean;\n largeIndexDeletionCheck: LargeIndexDeletionCheck;\n largeIndexBackfillCheck: LargeIndexBackfillCheck;\n stagedValidatorDeletionCheck: StagedValidatorDeletionCheck;\n warnOnSlowSchemaValidation: boolean;\n codegenOnlyThisComponent?: string | undefined;\n },\n): Promise<StartPushResponse | null> {\n const convexDir = await getFunctionsDirectoryPath(ctx);\n\n // '.' means use the process current working directory, it's the default behavior.\n // Spelling it out here to be explicit for a future where this code can run\n // from other directories.\n // In esbuild the working directory is used to print error messages and resolving\n // relatives paths passed to it. It generally doesn't matter for resolving imports,\n // imports are resolved from the file where they are written.\n const absWorkingDir = path.resolve(\".\");\n const isComponent = isComponentDirectory(ctx, convexDir, true);\n if (isComponent.kind === \"err\") {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"invalid filesystem data\",\n printedMessage: `Invalid component root directory (${isComponent.why}): ${convexDir}`,\n });\n }\n\n let rootComponent = isComponent.component;\n if (options.codegenOnlyThisComponent) {\n const absolutePath = path.resolve(options.codegenOnlyThisComponent);\n let componentConfigPath: string;\n\n // Must be a directory containing a convex.config.ts\n componentConfigPath = path.join(absolutePath, DEFINITION_FILENAME_TS);\n if (!ctx.fs.exists(componentConfigPath)) {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"invalid filesystem data\",\n printedMessage: `Only directories with convex.config.ts files are supported, this directory does not: ${absolutePath}`,\n });\n }\n\n const syntheticConfigPath = path.join(\n rootComponent.path,\n DEFINITION_FILENAME_TS,\n );\n rootComponent = {\n isRoot: true,\n path: rootComponent.path,\n definitionPath: syntheticConfigPath,\n isRootWithoutConfig: false,\n syntheticComponentImport: componentConfigPath,\n };\n }\n\n changeSpinner(\"Finding component definitions...\");\n // Create a list of relevant component directories. These are just for knowing\n // while directories to bundle in bundleDefinitions and bundleImplementations.\n // This produces a bundle in memory as a side effect but it's thrown away.\n const { components, dependencyGraph } = await parentSpan.enterAsync(\n \"componentGraph\",\n () =>\n componentGraph(\n ctx,\n absWorkingDir,\n rootComponent,\n !!options.liveComponentSources,\n options.verbose,\n ),\n );\n\n // Initial codegen is everything we need to get code runnable:\n // root components and other components need a basic _generated/api.ts etc.\n // just to make the code bundleable and runnable so we can analyze.\n if (options.codegen) {\n changeSpinner(\"Generating server code...\");\n await parentSpan.enterAsync(\"doInitialComponentCodegen\", () =>\n withTmpDir(async (tmpDir) => {\n // Skip the root in component cases\n if (!rootComponent.syntheticComponentImport) {\n // Do root first so if a component fails, we'll at least have a working root.\n await doInitialComponentCodegen(ctx, tmpDir, rootComponent, options);\n }\n for (const directory of components.values()) {\n if (directory.isRoot) {\n continue;\n }\n // When --component-dir is used, only generate code for the target component\n if (\n rootComponent.syntheticComponentImport &&\n directory.definitionPath !== rootComponent.syntheticComponentImport\n ) {\n continue;\n }\n await doInitialComponentCodegen(ctx, tmpDir, directory, options);\n }\n }),\n );\n }\n\n changeSpinner(\"Bundling component definitions...\");\n // This bundles everything but the actual function definitions\n const {\n appDefinitionSpecWithoutImpls,\n componentDefinitionSpecsWithoutImpls,\n } = await parentSpan.enterAsync(\"bundleDefinitions\", () =>\n bundleDefinitions(\n ctx,\n absWorkingDir,\n dependencyGraph,\n rootComponent,\n // Note that this *includes* the root component.\n [...components.values()],\n !!options.liveComponentSources,\n options.verbose,\n ),\n );\n\n if (options.debugNodeApis) {\n await debugIsolateEndpointBundles(ctx, projectConfig, configPath);\n logFinishedStep(\n \"All non-'use node' entry points successfully bundled. Skipping rest of push.\",\n );\n return null;\n }\n\n changeSpinner(\"Bundling component schemas and implementations...\");\n const { appImplementation, componentImplementations } =\n await parentSpan.enterAsync(\"bundleImplementations\", () =>\n bundleImplementations({\n ctx,\n rootComponentDirectory: rootComponent,\n // When running codegen for a specific component, don't bundle the root.\n componentDirectories: [...components.values()].filter(\n (dir) => !dir.isRoot && !dir.syntheticComponentImport,\n ),\n nodeExternalPackages: projectConfig.node.externalPackages,\n extraConditions: options.liveComponentSources\n ? [\"@convex-dev/component-source\"]\n : [],\n verbose: options.verbose,\n includeSourcesContent:\n projectConfig.bundler?.includeSourcesContent ?? false,\n }),\n );\n if (options.debugBundlePath) {\n const { config: localConfig } = await configFromProjectConfig(\n ctx,\n projectConfig,\n configPath,\n options.verbose,\n );\n // TODO(ENG-6972): Actually write the bundles for components.\n await handleDebugBundlePath(ctx, options.debugBundlePath, localConfig);\n logMessage(\n `Wrote bundle and metadata for modules in the root to ${options.debugBundlePath}. Skipping rest of push.`,\n );\n return null;\n }\n\n // We're just using the version this CLI is running with for now.\n // This could be different than the version of `convex` the app runs with\n // if the CLI is installed globally.\n // TODO: This should be the version of the `convex` package used by each\n // component, and may be different for each component.\n const udfServerVersion = version;\n\n const { unchangedModuleHashes, changedModules } = options.pushAllModules\n ? {\n unchangedModuleHashes: [],\n changedModules: appImplementation.functions,\n }\n : await parentSpan.enterAsync(\"getUnchangedModuleHashesFromServer\", () =>\n getUnchangedModuleHashesFromServer(ctx, appImplementation, options),\n );\n\n const appDefinition: AppDefinitionConfig = {\n ...appDefinitionSpecWithoutImpls,\n schema: appImplementation.schema,\n changedModules,\n unchangedModuleHashes,\n udfServerVersion,\n };\n\n const componentDefinitions: ComponentDefinitionConfig[] = [];\n for (const componentDefinition of componentDefinitionSpecsWithoutImpls) {\n const impl = componentImplementations.filter(\n (impl) => impl.definitionPath === componentDefinition.definitionPath,\n )[0];\n if (!impl) {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: `missing! couldn't find ${componentDefinition.definitionPath} in ${componentImplementations.map((impl) => impl.definitionPath).toString()}`,\n });\n }\n componentDefinitions.push({\n ...componentDefinition,\n ...impl,\n udfServerVersion,\n });\n }\n const startPushRequest = {\n adminKey: options.adminKey,\n dryRun: options.dryRun,\n functions: projectConfig.functions,\n appDefinition,\n componentDefinitions,\n nodeDependencies: appImplementation.externalNodeDependencies,\n nodeVersion: projectConfig.node.nodeVersion,\n forCodegen: !!options.codegenOnlyThisComponent,\n };\n if (options.writePushRequest) {\n const pushRequestPath = path.resolve(options.writePushRequest);\n ctx.fs.writeUtf8File(\n `${pushRequestPath}.json`,\n JSON.stringify(startPushRequest),\n );\n return null;\n }\n logStartPushSizes(parentSpan, startPushRequest);\n\n const schemaEvaluation = sharedSchemaEvaluation(\n ctx,\n startPushRequest,\n options,\n );\n if (options.largeIndexDeletionCheck !== \"no verification\") {\n await parentSpan.enterAsync(\"checkForLargeIndexDeletion\", (span) =>\n checkForLargeIndexDeletion({\n ctx,\n span,\n request: startPushRequest,\n options,\n schemaEvaluation,\n askForConfirmation:\n options.largeIndexDeletionCheck === \"ask for confirmation\",\n }),\n );\n }\n\n const largeIndexBackfillCheck = options.largeIndexBackfillCheck;\n if (largeIndexBackfillCheck !== \"no verification\") {\n await parentSpan.enterAsync(\"checkForLargeIndexBackfill\", (span) =>\n checkForLargeIndexBackfill({\n ctx,\n span,\n schemaEvaluation,\n options,\n // A dry run never blocks on a backfill, so it only reports.\n mode: options.dryRun ? \"warn\" : largeIndexBackfillCheck,\n }),\n );\n }\n\n const stagedValidatorDeletionCheck = options.stagedValidatorDeletionCheck;\n if (stagedValidatorDeletionCheck !== \"no verification\") {\n await parentSpan.enterAsync(\n \"checkForStagedValidatorDeletion\",\n async (span) => {\n const response = await schemaEvaluation(span);\n await checkForStagedValidatorDeletion({\n ctx,\n response,\n askForConfirmation:\n stagedValidatorDeletionCheck === \"ask for confirmation\",\n // A dry run previews the confirmation required by a real push.\n dryRun: options.dryRun,\n });\n },\n );\n }\n\n // A real push evaluates the schema only when the evaluation is already\n // paid for by the unstaging check or the pushed schema stages a validator,\n // so `dev` pushes of ordinary schemas skip the isolate evaluation and round\n // trip that the status report would otherwise add on every save.\n if (\n options.warnOnSlowSchemaValidation &&\n (options.dryRun ||\n stagedValidatorDeletionCheck !== \"no verification\" ||\n pushStagesValidators(startPushRequest))\n ) {\n await parentSpan.enterAsync(\"checkForSlowSchemaValidation\", (span) =>\n checkForSlowSchemaValidation({\n span,\n schemaEvaluation,\n dryRun: options.dryRun,\n }),\n );\n }\n\n changeSpinner(\"Uploading functions to Convex...\");\n const startPushResponse = await parentSpan.enterAsync(\"startPush\", (span) =>\n startPush(ctx, span, startPushRequest, options),\n );\n\n if (options.verbose) {\n logMessage(\"startPush: \" + JSON.stringify(startPushResponse, null, 2));\n }\n\n if (options.codegen) {\n changeSpinner(\"Generating TypeScript bindings...\");\n await parentSpan.enterAsync(\"doFinalComponentCodegen\", () =>\n withTmpDir(async (tmpDir) => {\n // TODO generating code for the root component last might be better DX\n // When running codegen for a specific component, don't generate types for the root\n if (!rootComponent.syntheticComponentImport) {\n // Do the root first\n await doFinalComponentCodegen(\n ctx,\n tmpDir,\n rootComponent,\n rootComponent,\n startPushResponse,\n components,\n options,\n );\n }\n for (const directory of components.values()) {\n if (directory.isRoot) {\n continue;\n }\n // When --component-dir is used, only generate code for the target component\n if (\n rootComponent.syntheticComponentImport &&\n directory.definitionPath !== rootComponent.syntheticComponentImport\n ) {\n continue;\n }\n await doFinalComponentCodegen(\n ctx,\n tmpDir,\n rootComponent,\n directory,\n startPushResponse,\n components,\n options,\n );\n }\n }),\n );\n }\n\n changeSpinner(\"Running TypeScript...\");\n await parentSpan.enterAsync(\"typeCheckFunctionsInMode\", async () => {\n // When running codegen for a specific component, don't typecheck the root\n if (!rootComponent.syntheticComponentImport) {\n await typeCheckFunctionsInMode(\n ctx,\n options.typecheck,\n rootComponent.path,\n );\n }\n if (options.typecheckComponents) {\n for (const directory of components.values()) {\n if (!directory.isRoot) {\n await typeCheckFunctionsInMode(\n ctx,\n options.typecheck,\n directory.path,\n );\n }\n }\n } else if (rootComponent.syntheticComponentImport) {\n // When running codegen for a specific component, only typecheck that component.\n for (const directory of components.values()) {\n if (\n directory.isRoot ||\n directory.definitionPath !== rootComponent.syntheticComponentImport\n ) {\n continue;\n }\n await typeCheckFunctionsInMode(ctx, options.typecheck, directory.path);\n }\n }\n });\n\n return startPushResponse;\n}\n\nfunction logStartPushSizes(span: Span, startPushRequest: StartPushRequest) {\n let v8Size = 0;\n let v8Count = 0;\n let nodeSize = 0;\n let nodeCount = 0;\n\n for (const componentDefinition of startPushRequest.componentDefinitions) {\n for (const module of componentDefinition.functions) {\n if (module.environment === \"isolate\") {\n v8Size += module.source.length + (module.sourceMap ?? \"\").length;\n v8Count += 1;\n } else if (module.environment === \"node\") {\n nodeSize += module.source.length + (module.sourceMap ?? \"\").length;\n nodeCount += 1;\n }\n }\n }\n span.setProperty(\"v8_size\", v8Size.toString());\n span.setProperty(\"v8_count\", v8Count.toString());\n span.setProperty(\"node_size\", nodeSize.toString());\n span.setProperty(\"node_count\", nodeCount.toString());\n}\n\nexport async function runComponentsPush(\n ctx: Context,\n options: PushOptions,\n configPath: string,\n projectConfig: ProjectConfig,\n) {\n const reporter = new Reporter();\n const pushSpan = Span.root(reporter, \"runComponentsPush\");\n pushSpan.setProperty(\"cli_version\", version);\n const verbose = options.verbose || options.dryRun;\n\n await ensureHasConvexDependency(ctx, \"push\");\n\n const startPushResponse = await pushSpan.enterAsync(\n \"startComponentsPushAndCodegen\",\n (span) =>\n startComponentsPushAndCodegen(\n ctx,\n span,\n projectConfig,\n configPath,\n options,\n ),\n );\n if (!startPushResponse) {\n return;\n }\n\n await pushSpan.enterAsync(\"waitForSchema\", (span) =>\n waitForSchema(ctx, span, startPushResponse, options),\n );\n\n if (verbose) {\n const remoteConfigWithModuleHashes = await pullConfig(\n ctx,\n undefined,\n undefined,\n options.url,\n options.adminKey,\n );\n\n const { config: localConfig } = await configFromProjectConfig(\n ctx,\n projectConfig,\n configPath,\n options.verbose,\n );\n\n changeSpinner(\"Diffing local code and deployment state...\");\n const { diffString } = diffConfig(\n remoteConfigWithModuleHashes,\n localConfig,\n );\n\n logFinishedStep(\n `Remote config ${\n options.dryRun ? \"would\" : \"will\"\n } be overwritten with the following changes:\\n ` +\n diffString.replace(/\\n/g, \"\\n \"),\n );\n }\n\n const finishPushResponse = await pushSpan.enterAsync(\"finishPush\", (span) =>\n finishPush(ctx, span, startPushResponse, options),\n );\n printDiff(startPushResponse, finishPushResponse, options);\n pushSpan.end();\n\n // Asynchronously report that the push completed.\n if (!options.dryRun) {\n void reportPushCompleted(ctx, options.adminKey, options.url, reporter);\n }\n}\n\nfunction printDiff(\n startPushResponse: StartPushResponse,\n finishPushResponse: FinishPushDiff,\n opts: { verbose: boolean; dryRun: boolean; deploymentName: string | null },\n) {\n if (opts.verbose) {\n const diffString = JSON.stringify(finishPushResponse, null, 2);\n logMessage(diffString);\n return;\n }\n const indexDiffs = startPushResponse.schemaChange.indexDiffs;\n const { componentDiffs } = finishPushResponse;\n\n // Print out index diffs for the root component.\n let rootDiff = indexDiffs?.[\"\"] || componentDiffs[\"\"]?.indexDiff;\n if (rootDiff) {\n if (rootDiff.removed_indexes.length > 0) {\n let msg = `${opts.dryRun ? \"Would delete\" : \"Deleted\"} table indexes:\\n`;\n for (const index of rootDiff.removed_indexes) {\n msg += ` [-] ${formatIndex(index)}\\n`;\n }\n msg = msg.slice(0, -1); // strip last new line\n logFinishedStep(msg);\n }\n\n const addedEnabled = rootDiff.added_indexes.filter((i) => !i.staged);\n if (addedEnabled.length > 0) {\n let msg = `${opts.dryRun ? \"Would add\" : \"Added\"} table indexes:\\n`;\n for (const index of addedEnabled) {\n msg += ` [+] ${formatIndex(index)}\\n`;\n }\n msg = msg.slice(0, -1); // strip last new line\n logFinishedStep(msg);\n }\n\n const addedStaged = rootDiff.added_indexes.filter((i) => i.staged);\n if (addedStaged.length > 0) {\n let msg = `${opts.dryRun ? \"Would add\" : \"Added\"} staged table indexes:\\n`;\n for (const index of addedStaged) {\n const table = index.name.split(\".\")[0];\n const progressLink = deploymentDashboardUrlPage(\n opts.deploymentName,\n `/data?table=${table}&showIndexes=true`,\n );\n msg += ` [+] ${formatIndex(index)}\\n`;\n msg += ` See progress: ${progressLink}\\n`;\n }\n msg = msg.slice(0, -1); // strip last new line\n logFinishedStep(msg);\n }\n\n if (rootDiff.enabled_indexes && rootDiff.enabled_indexes.length > 0) {\n let msg = opts.dryRun\n ? `These indexes would be enabled:\\n`\n : `These indexes are now enabled:\\n`;\n for (const index of rootDiff.enabled_indexes) {\n msg += ` [*] ${formatIndex(index)}\\n`;\n }\n msg = msg.slice(0, -1); // strip last new line\n logFinishedStep(msg);\n }\n\n if (rootDiff.disabled_indexes && rootDiff.disabled_indexes.length > 0) {\n let msg = opts.dryRun\n ? `These indexes would be staged:\\n`\n : `These indexes are now staged:\\n`;\n for (const index of rootDiff.disabled_indexes) {\n msg += ` [*] ${formatIndex(index)}\\n`;\n }\n msg = msg.slice(0, -1); // strip last new line\n logFinishedStep(msg);\n }\n }\n\n // Only show component level diffs for other components.\n for (const [componentPath, componentDiff] of Object.entries(componentDiffs)) {\n if (componentPath === \"\") {\n continue;\n }\n if (componentDiff.diffType.type === \"create\") {\n logFinishedStep(`Installed component ${componentPath}.`);\n }\n if (componentDiff.diffType.type === \"unmount\") {\n logFinishedStep(`Unmounted component ${componentPath}.`);\n }\n if (componentDiff.diffType.type === \"remount\") {\n logFinishedStep(`Remounted component ${componentPath}.`);\n }\n }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["import path from \"path\";\nimport { Context } from \"../../bundler/context.js\";\nimport {\n changeSpinner,\n logFinishedStep,\n logMessage,\n} from \"../../bundler/log.js\";\nimport {\n ProjectConfig,\n configFromProjectConfig,\n debugIsolateEndpointBundles,\n getFunctionsDirectoryPath,\n readProjectConfig,\n pullConfig,\n diffConfig,\n} from \"./config.js\";\nimport {\n finishPush,\n reportPushCompleted,\n startPush,\n waitForSchema,\n} from \"./deploy2.js\";\nimport { version } from \"../version.js\";\nimport { ensureHasConvexDependency, functionsDir } from \"./utils/utils.js\";\nimport {\n bundleDefinitions,\n bundleImplementations,\n componentGraph,\n} from \"./components/definition/bundle.js\";\nimport { isComponentDirectory } from \"./components/definition/directoryStructure.js\";\nimport {\n doFinalComponentCodegen,\n doInitialComponentCodegen,\n CodegenOptions,\n doInitConvexFolder,\n doCodegen,\n} from \"./codegen.js\";\nimport {\n AppDefinitionConfig,\n ComponentDefinitionConfig,\n} from \"./deployApi/definitionConfig.js\";\nimport { typeCheckFunctionsInMode, TypeCheckMode } from \"./typecheck.js\";\nimport { withTmpDir } from \"../../bundler/fs.js\";\nimport { handleDebugBundlePath } from \"./debugBundlePath.js\";\nimport { chalkStderr } from \"chalk\";\nimport {\n startPushResponseForLogging,\n redactEnvironmentVariableValues,\n StartPushRequest,\n StartPushResponse,\n} from \"./deployApi/startPush.js\";\nimport { DetailedDeploymentCredentials } from \"./api.js\";\nimport { FinishPushDiff } from \"./deployApi/finishPush.js\";\nimport { Reporter, Span } from \"./tracing.js\";\nimport { DEFINITION_FILENAME_TS } from \"./components/constants.js\";\nimport { DeploymentType } from \"./api.js\";\nimport { deploymentDashboardUrlPage } from \"./dashboard.js\";\nimport { formatIndex, LargeIndexDeletionCheck } from \"./indexes.js\";\nimport { checkForLargeIndexDeletion } from \"./checkForLargeIndexDeletion.js\";\nimport { checkForSlowSchemaValidation } from \"./checkForSlowSchemaValidation.js\";\nimport {\n checkForLargeIndexBackfill,\n LargeIndexBackfillCheck,\n} from \"./checkForLargeIndexBackfill.js\";\nimport {\n pushStagesValidators,\n sharedSchemaEvaluation,\n} from \"./schemaEvaluation.js\";\nimport {\n checkForStagedValidatorDeletion,\n StagedValidatorDeletionCheck,\n} from \"./checkForStagedValidatorDeletion.js\";\nimport { LogManager } from \"./logs.js\";\nimport { createHash } from \"crypto\";\nimport { Bundle, BundleHash } from \"../../bundler/index.js\";\nimport { ModuleHashConfig } from \"./deployApi/modules.js\";\n\nexport type PushOptions = {\n adminKey: string;\n verbose: boolean;\n dryRun: boolean;\n typecheck: \"enable\" | \"try\" | \"disable\";\n typecheckComponents: boolean;\n debug: boolean;\n debugBundlePath?: string | undefined;\n debugNodeApis: boolean;\n codegen: boolean;\n url: string;\n deploymentName: string | null;\n deploymentType?: DeploymentType;\n writePushRequest?: string | undefined;\n liveComponentSources: boolean;\n pushAllModules: boolean;\n logManager?: LogManager | undefined;\n largeIndexDeletionCheck: LargeIndexDeletionCheck;\n largeIndexBackfillCheck: LargeIndexBackfillCheck;\n stagedValidatorDeletionCheck: StagedValidatorDeletionCheck;\n // Whether a dry run should warn when the schema change would block the\n // deploy on a slow table walk. On for deploys; off for commands whose dry\n // runs never deploy (e.g. codegen).\n warnOnSlowSchemaValidation: boolean;\n message: string | null;\n};\n\nexport async function runCodegen(\n ctx: Context,\n credentials: DetailedDeploymentCredentials | null,\n options: CodegenOptions,\n) {\n // This also ensures the current directory is the project root.\n await ensureHasConvexDependency(ctx, \"codegen\");\n\n const { configPath, projectConfig } = await readProjectConfig(ctx);\n const functionsDirectoryPath = functionsDir(configPath, projectConfig);\n\n if (options.init) {\n await doInitConvexFolder(ctx, functionsDirectoryPath, {\n dryRun: options.dryRun,\n debug: options.debug,\n });\n }\n\n if (!options.systemUdfs) {\n if (credentials === null) {\n return;\n }\n\n await startComponentsPushAndCodegen(\n ctx,\n Span.noop(),\n projectConfig,\n configPath,\n {\n ...options,\n deploymentName: credentials.deploymentFields?.deploymentName ?? null,\n ...(credentials.deploymentFields?.deploymentType !== undefined\n ? { deploymentType: credentials.deploymentFields.deploymentType }\n : {}),\n url: credentials.url,\n adminKey: credentials.adminKey,\n generateCommonJSApi: options.commonjs,\n verbose: !!process.env.CONVEX_VERBOSE,\n codegen: true,\n liveComponentSources: options.liveComponentSources,\n typecheckComponents: false,\n debugNodeApis: options.debugNodeApis,\n // Code generation uses the source schema independently of deployment data.\n largeIndexDeletionCheck: \"no verification\",\n largeIndexBackfillCheck: \"no verification\",\n stagedValidatorDeletionCheck: \"no verification\",\n warnOnSlowSchemaValidation: false,\n },\n );\n } else {\n if (options.typecheck !== \"disable\") {\n logMessage(chalkStderr.gray(\"Running TypeScript typecheck\u2026\"));\n }\n\n await doCodegen(ctx, functionsDirectoryPath, options.typecheck, {\n dryRun: options.dryRun,\n debug: options.debug,\n generateCommonJSApi: options.commonjs,\n });\n }\n}\n\nexport async function runPush(ctx: Context, options: PushOptions) {\n const { configPath, projectConfig } = await readProjectConfig(ctx);\n await runComponentsPush(ctx, options, configPath, projectConfig);\n}\n\nexport function hash(bundle: Bundle) {\n return createHash(\"sha256\")\n .update(bundle.source)\n .update(bundle.sourceMap || \"\")\n .digest(\"hex\");\n}\n\nfunction isModuleTheSame(newBundle: Bundle, oldBundleHash: BundleHash) {\n return (\n newBundle.environment === oldBundleHash.environment &&\n hash(newBundle) === oldBundleHash.hash\n );\n}\n\nexport function partitionModulesByChanges(\n functions: Bundle[],\n remoteHashesByPath: Map<string, BundleHash>,\n): {\n unchangedModuleHashes: ModuleHashConfig[];\n changedModules: Bundle[];\n} {\n // Partition modules based on whether they match the existing modules\n const unchangedModuleHashes = functions\n .filter((newBundle) => {\n const oldBundleHash = remoteHashesByPath.get(newBundle.path);\n return oldBundleHash && isModuleTheSame(newBundle, oldBundleHash);\n })\n .map((func) => ({\n path: func.path,\n environment: func.environment,\n sha256: hash(func),\n }));\n const changedModules = functions.filter((newBundle) => {\n const oldBundleHash = remoteHashesByPath.get(newBundle.path);\n return !oldBundleHash || !isModuleTheSame(newBundle, oldBundleHash);\n });\n return { unchangedModuleHashes, changedModules };\n}\n\nasync function getUnchangedModuleHashesFromServer(\n ctx: Context,\n appImplementation: { functions: Bundle[] },\n options: { url: string; adminKey: string },\n): Promise<{\n unchangedModuleHashes: ModuleHashConfig[];\n changedModules: Bundle[];\n}> {\n const remoteConfigWithModuleHashes = await pullConfig(\n ctx,\n undefined,\n undefined,\n options.url,\n options.adminKey,\n );\n const remoteHashesByPath = new Map(\n remoteConfigWithModuleHashes.moduleHashes.map((moduleHash) => [\n moduleHash.path,\n moduleHash,\n ]),\n );\n return partitionModulesByChanges(\n appImplementation.functions,\n remoteHashesByPath,\n );\n}\n\nasync function startComponentsPushAndCodegen(\n ctx: Context,\n parentSpan: Span,\n projectConfig: ProjectConfig,\n configPath: string,\n options: {\n typecheck: TypeCheckMode;\n typecheckComponents: boolean;\n adminKey: string;\n url: string;\n deploymentName: string | null;\n deploymentType?: DeploymentType;\n verbose: boolean;\n debugBundlePath?: string | undefined;\n dryRun: boolean;\n generateCommonJSApi?: boolean;\n debug: boolean;\n writePushRequest?: string | undefined;\n codegen: boolean;\n liveComponentSources?: boolean;\n pushAllModules?: boolean;\n debugNodeApis: boolean;\n largeIndexDeletionCheck: LargeIndexDeletionCheck;\n largeIndexBackfillCheck: LargeIndexBackfillCheck;\n stagedValidatorDeletionCheck: StagedValidatorDeletionCheck;\n warnOnSlowSchemaValidation: boolean;\n codegenOnlyThisComponent?: string | undefined;\n },\n): Promise<StartPushResponse | null> {\n const convexDir = await getFunctionsDirectoryPath(ctx);\n\n // '.' means use the process current working directory, it's the default behavior.\n // Spelling it out here to be explicit for a future where this code can run\n // from other directories.\n // In esbuild the working directory is used to print error messages and resolving\n // relatives paths passed to it. It generally doesn't matter for resolving imports,\n // imports are resolved from the file where they are written.\n const absWorkingDir = path.resolve(\".\");\n const isComponent = isComponentDirectory(ctx, convexDir, true);\n if (isComponent.kind === \"err\") {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"invalid filesystem data\",\n printedMessage: `Invalid component root directory (${isComponent.why}): ${convexDir}`,\n });\n }\n\n let rootComponent = isComponent.component;\n if (options.codegenOnlyThisComponent) {\n const absolutePath = path.resolve(options.codegenOnlyThisComponent);\n let componentConfigPath: string;\n\n // Must be a directory containing a convex.config.ts\n componentConfigPath = path.join(absolutePath, DEFINITION_FILENAME_TS);\n if (!ctx.fs.exists(componentConfigPath)) {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"invalid filesystem data\",\n printedMessage: `Only directories with convex.config.ts files are supported, this directory does not: ${absolutePath}`,\n });\n }\n\n const syntheticConfigPath = path.join(\n rootComponent.path,\n DEFINITION_FILENAME_TS,\n );\n rootComponent = {\n isRoot: true,\n path: rootComponent.path,\n definitionPath: syntheticConfigPath,\n isRootWithoutConfig: false,\n syntheticComponentImport: componentConfigPath,\n };\n }\n\n changeSpinner(\"Finding component definitions...\");\n // Create a list of relevant component directories. These are just for knowing\n // while directories to bundle in bundleDefinitions and bundleImplementations.\n // This produces a bundle in memory as a side effect but it's thrown away.\n const { components, dependencyGraph } = await parentSpan.enterAsync(\n \"componentGraph\",\n () =>\n componentGraph(\n ctx,\n absWorkingDir,\n rootComponent,\n !!options.liveComponentSources,\n options.verbose,\n ),\n );\n\n // Initial codegen is everything we need to get code runnable:\n // root components and other components need a basic _generated/api.ts etc.\n // just to make the code bundleable and runnable so we can analyze.\n if (options.codegen) {\n changeSpinner(\"Generating server code...\");\n await parentSpan.enterAsync(\"doInitialComponentCodegen\", () =>\n withTmpDir(async (tmpDir) => {\n // Skip the root in component cases\n if (!rootComponent.syntheticComponentImport) {\n // Do root first so if a component fails, we'll at least have a working root.\n await doInitialComponentCodegen(ctx, tmpDir, rootComponent, options);\n }\n for (const directory of components.values()) {\n if (directory.isRoot) {\n continue;\n }\n // When --component-dir is used, only generate code for the target component\n if (\n rootComponent.syntheticComponentImport &&\n directory.definitionPath !== rootComponent.syntheticComponentImport\n ) {\n continue;\n }\n await doInitialComponentCodegen(ctx, tmpDir, directory, options);\n }\n }),\n );\n }\n\n changeSpinner(\"Bundling component definitions...\");\n // This bundles everything but the actual function definitions\n const {\n appDefinitionSpecWithoutImpls,\n componentDefinitionSpecsWithoutImpls,\n } = await parentSpan.enterAsync(\"bundleDefinitions\", () =>\n bundleDefinitions(\n ctx,\n absWorkingDir,\n dependencyGraph,\n rootComponent,\n // Note that this *includes* the root component.\n [...components.values()],\n !!options.liveComponentSources,\n options.verbose,\n ),\n );\n\n if (options.debugNodeApis) {\n await debugIsolateEndpointBundles(ctx, projectConfig, configPath);\n logFinishedStep(\n \"All non-'use node' entry points successfully bundled. Skipping rest of push.\",\n );\n return null;\n }\n\n changeSpinner(\"Bundling component schemas and implementations...\");\n const { appImplementation, componentImplementations } =\n await parentSpan.enterAsync(\"bundleImplementations\", () =>\n bundleImplementations({\n ctx,\n rootComponentDirectory: rootComponent,\n // When running codegen for a specific component, don't bundle the root.\n componentDirectories: [...components.values()].filter(\n (dir) => !dir.isRoot && !dir.syntheticComponentImport,\n ),\n nodeExternalPackages: projectConfig.node.externalPackages,\n extraConditions: options.liveComponentSources\n ? [\"@convex-dev/component-source\"]\n : [],\n verbose: options.verbose,\n includeSourcesContent:\n projectConfig.bundler?.includeSourcesContent ?? false,\n }),\n );\n if (options.debugBundlePath) {\n const { config: localConfig } = await configFromProjectConfig(\n ctx,\n projectConfig,\n configPath,\n options.verbose,\n );\n // TODO(ENG-6972): Actually write the bundles for components.\n await handleDebugBundlePath(ctx, options.debugBundlePath, localConfig);\n logMessage(\n `Wrote bundle and metadata for modules in the root to ${options.debugBundlePath}. Skipping rest of push.`,\n );\n return null;\n }\n\n // We're just using the version this CLI is running with for now.\n // This could be different than the version of `convex` the app runs with\n // if the CLI is installed globally.\n // TODO: This should be the version of the `convex` package used by each\n // component, and may be different for each component.\n const udfServerVersion = version;\n\n const { unchangedModuleHashes, changedModules } = options.pushAllModules\n ? {\n unchangedModuleHashes: [],\n changedModules: appImplementation.functions,\n }\n : await parentSpan.enterAsync(\"getUnchangedModuleHashesFromServer\", () =>\n getUnchangedModuleHashesFromServer(ctx, appImplementation, options),\n );\n\n const appDefinition: AppDefinitionConfig = {\n ...appDefinitionSpecWithoutImpls,\n schema: appImplementation.schema,\n changedModules,\n unchangedModuleHashes,\n udfServerVersion,\n };\n\n const componentDefinitions: ComponentDefinitionConfig[] = [];\n for (const componentDefinition of componentDefinitionSpecsWithoutImpls) {\n const impl = componentImplementations.filter(\n (impl) => impl.definitionPath === componentDefinition.definitionPath,\n )[0];\n if (!impl) {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: `missing! couldn't find ${componentDefinition.definitionPath} in ${componentImplementations.map((impl) => impl.definitionPath).toString()}`,\n });\n }\n componentDefinitions.push({\n ...componentDefinition,\n ...impl,\n udfServerVersion,\n });\n }\n const startPushRequest = {\n adminKey: options.adminKey,\n dryRun: options.dryRun,\n functions: projectConfig.functions,\n appDefinition,\n componentDefinitions,\n nodeDependencies: appImplementation.externalNodeDependencies,\n nodeVersion: projectConfig.node.nodeVersion,\n forCodegen: !!options.codegenOnlyThisComponent,\n };\n if (options.writePushRequest) {\n const pushRequestPath = path.resolve(options.writePushRequest);\n ctx.fs.writeUtf8File(\n `${pushRequestPath}.json`,\n JSON.stringify(startPushRequest),\n );\n return null;\n }\n logStartPushSizes(parentSpan, startPushRequest);\n\n const schemaEvaluation = sharedSchemaEvaluation(\n ctx,\n startPushRequest,\n options,\n );\n if (options.largeIndexDeletionCheck !== \"no verification\") {\n await parentSpan.enterAsync(\"checkForLargeIndexDeletion\", (span) =>\n checkForLargeIndexDeletion({\n ctx,\n span,\n request: startPushRequest,\n options,\n schemaEvaluation,\n askForConfirmation:\n options.largeIndexDeletionCheck === \"ask for confirmation\",\n }),\n );\n }\n\n const largeIndexBackfillCheck = options.largeIndexBackfillCheck;\n if (largeIndexBackfillCheck !== \"no verification\") {\n await parentSpan.enterAsync(\"checkForLargeIndexBackfill\", (span) =>\n checkForLargeIndexBackfill({\n ctx,\n span,\n schemaEvaluation,\n options,\n // A dry run never blocks on a backfill, so it only reports.\n mode: options.dryRun ? \"warn\" : largeIndexBackfillCheck,\n }),\n );\n }\n\n const stagedValidatorDeletionCheck = options.stagedValidatorDeletionCheck;\n if (stagedValidatorDeletionCheck !== \"no verification\") {\n await parentSpan.enterAsync(\n \"checkForStagedValidatorDeletion\",\n async (span) => {\n const response = await schemaEvaluation(span);\n await checkForStagedValidatorDeletion({\n ctx,\n response,\n askForConfirmation:\n stagedValidatorDeletionCheck === \"ask for confirmation\",\n // A dry run previews the confirmation required by a real push.\n dryRun: options.dryRun,\n });\n },\n );\n }\n\n // A real push evaluates the schema only when the evaluation is already\n // paid for by the unstaging check or the pushed schema stages a validator,\n // so `dev` pushes of ordinary schemas skip the isolate evaluation and round\n // trip that the status report would otherwise add on every save.\n if (\n options.warnOnSlowSchemaValidation &&\n (options.dryRun ||\n stagedValidatorDeletionCheck !== \"no verification\" ||\n pushStagesValidators(startPushRequest))\n ) {\n await parentSpan.enterAsync(\"checkForSlowSchemaValidation\", (span) =>\n checkForSlowSchemaValidation({\n span,\n schemaEvaluation,\n dryRun: options.dryRun,\n }),\n );\n }\n\n changeSpinner(\"Uploading functions to Convex...\");\n const startPushResponse = await parentSpan.enterAsync(\"startPush\", (span) =>\n startPush(ctx, span, startPushRequest, options),\n );\n\n if (options.verbose) {\n logMessage(\n \"startPush: \" +\n JSON.stringify(startPushResponseForLogging(startPushResponse), null, 2),\n );\n }\n\n if (options.codegen) {\n changeSpinner(\"Generating TypeScript bindings...\");\n await parentSpan.enterAsync(\"doFinalComponentCodegen\", () =>\n withTmpDir(async (tmpDir) => {\n // TODO generating code for the root component last might be better DX\n // When running codegen for a specific component, don't generate types for the root\n if (!rootComponent.syntheticComponentImport) {\n // Do the root first\n await doFinalComponentCodegen(\n ctx,\n tmpDir,\n rootComponent,\n rootComponent,\n startPushResponse,\n components,\n options,\n );\n }\n for (const directory of components.values()) {\n if (directory.isRoot) {\n continue;\n }\n // When --component-dir is used, only generate code for the target component\n if (\n rootComponent.syntheticComponentImport &&\n directory.definitionPath !== rootComponent.syntheticComponentImport\n ) {\n continue;\n }\n await doFinalComponentCodegen(\n ctx,\n tmpDir,\n rootComponent,\n directory,\n startPushResponse,\n components,\n options,\n );\n }\n }),\n );\n }\n\n changeSpinner(\"Running TypeScript...\");\n await parentSpan.enterAsync(\"typeCheckFunctionsInMode\", async () => {\n // When running codegen for a specific component, don't typecheck the root\n if (!rootComponent.syntheticComponentImport) {\n await typeCheckFunctionsInMode(\n ctx,\n options.typecheck,\n rootComponent.path,\n );\n }\n if (options.typecheckComponents) {\n for (const directory of components.values()) {\n if (!directory.isRoot) {\n await typeCheckFunctionsInMode(\n ctx,\n options.typecheck,\n directory.path,\n );\n }\n }\n } else if (rootComponent.syntheticComponentImport) {\n // When running codegen for a specific component, only typecheck that component.\n for (const directory of components.values()) {\n if (\n directory.isRoot ||\n directory.definitionPath !== rootComponent.syntheticComponentImport\n ) {\n continue;\n }\n await typeCheckFunctionsInMode(ctx, options.typecheck, directory.path);\n }\n }\n });\n\n return startPushResponse;\n}\n\nfunction logStartPushSizes(span: Span, startPushRequest: StartPushRequest) {\n let v8Size = 0;\n let v8Count = 0;\n let nodeSize = 0;\n let nodeCount = 0;\n\n for (const componentDefinition of startPushRequest.componentDefinitions) {\n for (const module of componentDefinition.functions) {\n if (module.environment === \"isolate\") {\n v8Size += module.source.length + (module.sourceMap ?? \"\").length;\n v8Count += 1;\n } else if (module.environment === \"node\") {\n nodeSize += module.source.length + (module.sourceMap ?? \"\").length;\n nodeCount += 1;\n }\n }\n }\n span.setProperty(\"v8_size\", v8Size.toString());\n span.setProperty(\"v8_count\", v8Count.toString());\n span.setProperty(\"node_size\", nodeSize.toString());\n span.setProperty(\"node_count\", nodeCount.toString());\n}\n\nexport async function runComponentsPush(\n ctx: Context,\n options: PushOptions,\n configPath: string,\n projectConfig: ProjectConfig,\n) {\n const reporter = new Reporter();\n const pushSpan = Span.root(reporter, \"runComponentsPush\");\n pushSpan.setProperty(\"cli_version\", version);\n const verbose = options.verbose || options.dryRun;\n\n await ensureHasConvexDependency(ctx, \"push\");\n\n const startPushResponse = await pushSpan.enterAsync(\n \"startComponentsPushAndCodegen\",\n (span) =>\n startComponentsPushAndCodegen(\n ctx,\n span,\n projectConfig,\n configPath,\n options,\n ),\n );\n if (!startPushResponse) {\n return;\n }\n\n await pushSpan.enterAsync(\"waitForSchema\", (span) =>\n waitForSchema(ctx, span, startPushResponse, options),\n );\n\n if (verbose) {\n const remoteConfigWithModuleHashes = await pullConfig(\n ctx,\n undefined,\n undefined,\n options.url,\n options.adminKey,\n );\n\n const { config: localConfig } = await configFromProjectConfig(\n ctx,\n projectConfig,\n configPath,\n options.verbose,\n );\n\n changeSpinner(\"Diffing local code and deployment state...\");\n const { diffString } = diffConfig(\n remoteConfigWithModuleHashes,\n localConfig,\n );\n\n logFinishedStep(\n `Remote config ${\n options.dryRun ? \"would\" : \"will\"\n } be overwritten with the following changes:\\n ` +\n diffString.replace(/\\n/g, \"\\n \"),\n );\n }\n\n const finishPushResponse = await pushSpan.enterAsync(\"finishPush\", (span) =>\n finishPush(ctx, span, startPushResponse, options),\n );\n printDiff(startPushResponse, finishPushResponse, options);\n pushSpan.end();\n\n // Asynchronously report that the push completed.\n if (!options.dryRun) {\n void reportPushCompleted(ctx, options.adminKey, options.url, reporter);\n }\n}\n\nfunction printDiff(\n startPushResponse: StartPushResponse,\n finishPushResponse: FinishPushDiff,\n opts: { verbose: boolean; dryRun: boolean; deploymentName: string | null },\n) {\n if (opts.verbose) {\n const diffString = JSON.stringify(\n redactEnvironmentVariableValues(\n finishPushResponse,\n startPushResponse.environmentVariables,\n ),\n null,\n 2,\n );\n logMessage(diffString);\n return;\n }\n const indexDiffs = startPushResponse.schemaChange.indexDiffs;\n const { componentDiffs } = finishPushResponse;\n\n // Print out index diffs for the root component.\n let rootDiff = indexDiffs?.[\"\"] || componentDiffs[\"\"]?.indexDiff;\n if (rootDiff) {\n if (rootDiff.removed_indexes.length > 0) {\n let msg = `${opts.dryRun ? \"Would delete\" : \"Deleted\"} table indexes:\\n`;\n for (const index of rootDiff.removed_indexes) {\n msg += ` [-] ${formatIndex(index)}\\n`;\n }\n msg = msg.slice(0, -1); // strip last new line\n logFinishedStep(msg);\n }\n\n const addedEnabled = rootDiff.added_indexes.filter((i) => !i.staged);\n if (addedEnabled.length > 0) {\n let msg = `${opts.dryRun ? \"Would add\" : \"Added\"} table indexes:\\n`;\n for (const index of addedEnabled) {\n msg += ` [+] ${formatIndex(index)}\\n`;\n }\n msg = msg.slice(0, -1); // strip last new line\n logFinishedStep(msg);\n }\n\n const addedStaged = rootDiff.added_indexes.filter((i) => i.staged);\n if (addedStaged.length > 0) {\n let msg = `${opts.dryRun ? \"Would add\" : \"Added\"} staged table indexes:\\n`;\n for (const index of addedStaged) {\n const table = index.name.split(\".\")[0];\n const progressLink = deploymentDashboardUrlPage(\n opts.deploymentName,\n `/data?table=${table}&showIndexes=true`,\n );\n msg += ` [+] ${formatIndex(index)}\\n`;\n msg += ` See progress: ${progressLink}\\n`;\n }\n msg = msg.slice(0, -1); // strip last new line\n logFinishedStep(msg);\n }\n\n if (rootDiff.enabled_indexes && rootDiff.enabled_indexes.length > 0) {\n let msg = opts.dryRun\n ? `These indexes would be enabled:\\n`\n : `These indexes are now enabled:\\n`;\n for (const index of rootDiff.enabled_indexes) {\n msg += ` [*] ${formatIndex(index)}\\n`;\n }\n msg = msg.slice(0, -1); // strip last new line\n logFinishedStep(msg);\n }\n\n if (rootDiff.disabled_indexes && rootDiff.disabled_indexes.length > 0) {\n let msg = opts.dryRun\n ? `These indexes would be staged:\\n`\n : `These indexes are now staged:\\n`;\n for (const index of rootDiff.disabled_indexes) {\n msg += ` [*] ${formatIndex(index)}\\n`;\n }\n msg = msg.slice(0, -1); // strip last new line\n logFinishedStep(msg);\n }\n }\n\n // Only show component level diffs for other components.\n for (const [componentPath, componentDiff] of Object.entries(componentDiffs)) {\n if (componentPath === \"\") {\n continue;\n }\n if (componentDiff.diffType.type === \"create\") {\n logFinishedStep(`Installed component ${componentPath}.`);\n }\n if (componentDiff.diffType.type === \"unmount\") {\n logFinishedStep(`Unmounted component ${componentPath}.`);\n }\n if (componentDiff.diffType.type === \"remount\") {\n logFinishedStep(`Remounted component ${componentPath}.`);\n }\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["path", "impl", "module"]
|
|
7
7
|
}
|
|
@@ -20,10 +20,12 @@ var startPush_exports = {};
|
|
|
20
20
|
__export(startPush_exports, {
|
|
21
21
|
componentSchemaStatus: () => componentSchemaStatus,
|
|
22
22
|
evaluatePushResponse: () => evaluatePushResponse,
|
|
23
|
+
redactEnvironmentVariableValues: () => redactEnvironmentVariableValues,
|
|
23
24
|
schemaChange: () => schemaChange,
|
|
24
25
|
schemaStatus: () => schemaStatus,
|
|
25
26
|
startPushRequest: () => startPushRequest,
|
|
26
|
-
startPushResponse: () => startPushResponse
|
|
27
|
+
startPushResponse: () => startPushResponse,
|
|
28
|
+
startPushResponseForLogging: () => startPushResponseForLogging
|
|
27
29
|
});
|
|
28
30
|
module.exports = __toCommonJS(startPush_exports);
|
|
29
31
|
var import_zod = require("zod");
|
|
@@ -58,6 +60,45 @@ const startPushResponse = (0, import_utils.looseObject)({
|
|
|
58
60
|
app: import_checkedComponent.checkedComponent,
|
|
59
61
|
schemaChange
|
|
60
62
|
});
|
|
63
|
+
const MIN_SCRUBBED_VALUE_LENGTH = 8;
|
|
64
|
+
function redactEnvironmentVariableValues(node, environmentVariables) {
|
|
65
|
+
const values = Object.values(environmentVariables).filter((value) => value.length >= MIN_SCRUBBED_VALUE_LENGTH).flatMap((value) => {
|
|
66
|
+
const escaped = JSON.stringify(value).slice(1, -1);
|
|
67
|
+
return escaped === value ? [value] : [value, escaped];
|
|
68
|
+
}).sort((a, b) => b.length - a.length);
|
|
69
|
+
const scrub = (child) => {
|
|
70
|
+
if (typeof child === "string") {
|
|
71
|
+
return values.reduce(
|
|
72
|
+
(scrubbed, value) => scrubbed.split(value).join("<redacted>"),
|
|
73
|
+
child
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
if (Array.isArray(child)) {
|
|
77
|
+
return child.map(scrub);
|
|
78
|
+
}
|
|
79
|
+
if (child !== null && typeof child === "object") {
|
|
80
|
+
return Object.fromEntries(
|
|
81
|
+
Object.entries(child).map(([key, grandchild]) => [
|
|
82
|
+
key,
|
|
83
|
+
scrub(grandchild)
|
|
84
|
+
])
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
return child;
|
|
88
|
+
};
|
|
89
|
+
return scrub(node);
|
|
90
|
+
}
|
|
91
|
+
function startPushResponseForLogging(response) {
|
|
92
|
+
return {
|
|
93
|
+
...redactEnvironmentVariableValues(response, response.environmentVariables),
|
|
94
|
+
environmentVariables: Object.fromEntries(
|
|
95
|
+
Object.keys(response.environmentVariables).map((name) => [
|
|
96
|
+
name,
|
|
97
|
+
"<redacted>"
|
|
98
|
+
])
|
|
99
|
+
)
|
|
100
|
+
};
|
|
101
|
+
}
|
|
61
102
|
const evaluatePushResponse = (0, import_utils.looseObject)({
|
|
62
103
|
schemaChange
|
|
63
104
|
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/cli/lib/deployApi/startPush.ts"],
|
|
4
|
-
"sourcesContent": ["import { z } from \"zod\";\nimport { componentDefinitionPath, componentPath } from \"./paths.js\";\nimport { nodeDependency, sourcePackage } from \"./modules.js\";\nimport { checkedComponent } from \"./checkedComponent.js\";\nimport { evaluatedComponentDefinition } from \"./componentDefinition.js\";\nimport {\n appDefinitionConfig,\n componentDefinitionConfig,\n} from \"./definitionConfig.js\";\nimport { authInfo } from \"./types.js\";\nimport { looseObject } from \"./utils.js\";\nimport { indexDiff } from \"./finishPush.js\";\n\nexport const startPushRequest = looseObject({\n adminKey: z.string(),\n dryRun: z.boolean(),\n\n functions: z.string(),\n\n appDefinition: appDefinitionConfig,\n componentDefinitions: z.array(componentDefinitionConfig),\n\n nodeDependencies: z.array(nodeDependency),\n\n nodeVersion: z.optional(z.string()),\n});\nexport type StartPushRequest = z.infer<typeof startPushRequest>;\n\nexport const schemaChange = looseObject({\n allocatedComponentIds: z.any(),\n schemaIds: z.any(),\n indexDiffs: z.record(componentPath, indexDiff).optional(),\n});\nexport type SchemaChange = z.infer<typeof schemaChange>;\n\nexport const startPushResponse = looseObject({\n environmentVariables: z.record(z.string(), z.string()),\n\n externalDepsId: z.nullable(z.string()),\n componentDefinitionPackages: z.record(componentDefinitionPath, sourcePackage),\n\n appAuth: z.array(authInfo),\n analysis: z.record(componentDefinitionPath, evaluatedComponentDefinition),\n\n app: checkedComponent,\n\n schemaChange,\n});\nexport type StartPushResponse = z.infer<typeof startPushResponse>;\n\nexport const evaluatePushResponse = looseObject({\n schemaChange,\n});\nexport type EvaluatePushResponse = z.infer<typeof evaluatePushResponse>;\n\nexport const componentSchemaStatus = looseObject({\n schemaValidationComplete: z.boolean(),\n indexesComplete: z.number(),\n indexesTotal: z.number(),\n});\nexport type ComponentSchemaStatus = z.infer<typeof componentSchemaStatus>;\n\nexport const schemaStatus = z.union([\n looseObject({\n type: z.literal(\"inProgress\"),\n components: z.record(componentPath, componentSchemaStatus),\n }),\n looseObject({\n type: z.literal(\"failed\"),\n error: z.string(),\n componentPath,\n tableName: z.nullable(z.string()),\n }),\n looseObject({\n type: z.literal(\"raceDetected\"),\n }),\n looseObject({\n type: z.literal(\"complete\"),\n }),\n]);\nexport type SchemaStatus = z.infer<typeof schemaStatus>;\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iBAAkB;AAClB,mBAAuD;AACvD,qBAA8C;AAC9C,8BAAiC;AACjC,iCAA6C;AAC7C,8BAGO;AACP,mBAAyB;AACzB,mBAA4B;AAC5B,wBAA0B;AAEnB,MAAM,uBAAmB,0BAAY;AAAA,EAC1C,UAAU,aAAE,OAAO;AAAA,EACnB,QAAQ,aAAE,QAAQ;AAAA,EAElB,WAAW,aAAE,OAAO;AAAA,EAEpB,eAAe;AAAA,EACf,sBAAsB,aAAE,MAAM,iDAAyB;AAAA,EAEvD,kBAAkB,aAAE,MAAM,6BAAc;AAAA,EAExC,aAAa,aAAE,SAAS,aAAE,OAAO,CAAC;AACpC,CAAC;AAGM,MAAM,mBAAe,0BAAY;AAAA,EACtC,uBAAuB,aAAE,IAAI;AAAA,EAC7B,WAAW,aAAE,IAAI;AAAA,EACjB,YAAY,aAAE,OAAO,4BAAe,2BAAS,EAAE,SAAS;AAC1D,CAAC;AAGM,MAAM,wBAAoB,0BAAY;AAAA,EAC3C,sBAAsB,aAAE,OAAO,aAAE,OAAO,GAAG,aAAE,OAAO,CAAC;AAAA,EAErD,gBAAgB,aAAE,SAAS,aAAE,OAAO,CAAC;AAAA,EACrC,6BAA6B,aAAE,OAAO,sCAAyB,4BAAa;AAAA,EAE5E,SAAS,aAAE,MAAM,qBAAQ;AAAA,EACzB,UAAU,aAAE,OAAO,sCAAyB,uDAA4B;AAAA,EAExE,KAAK;AAAA,EAEL;AACF,CAAC;
|
|
4
|
+
"sourcesContent": ["import { z } from \"zod\";\nimport { componentDefinitionPath, componentPath } from \"./paths.js\";\nimport { nodeDependency, sourcePackage } from \"./modules.js\";\nimport { checkedComponent } from \"./checkedComponent.js\";\nimport { evaluatedComponentDefinition } from \"./componentDefinition.js\";\nimport {\n appDefinitionConfig,\n componentDefinitionConfig,\n} from \"./definitionConfig.js\";\nimport { authInfo } from \"./types.js\";\nimport { looseObject } from \"./utils.js\";\nimport { indexDiff } from \"./finishPush.js\";\n\nexport const startPushRequest = looseObject({\n adminKey: z.string(),\n dryRun: z.boolean(),\n\n functions: z.string(),\n\n appDefinition: appDefinitionConfig,\n componentDefinitions: z.array(componentDefinitionConfig),\n\n nodeDependencies: z.array(nodeDependency),\n\n nodeVersion: z.optional(z.string()),\n});\nexport type StartPushRequest = z.infer<typeof startPushRequest>;\n\nexport const schemaChange = looseObject({\n allocatedComponentIds: z.any(),\n schemaIds: z.any(),\n indexDiffs: z.record(componentPath, indexDiff).optional(),\n});\nexport type SchemaChange = z.infer<typeof schemaChange>;\n\nexport const startPushResponse = looseObject({\n environmentVariables: z.record(z.string(), z.string()),\n\n externalDepsId: z.nullable(z.string()),\n componentDefinitionPackages: z.record(componentDefinitionPath, sourcePackage),\n\n appAuth: z.array(authInfo),\n analysis: z.record(componentDefinitionPath, evaluatedComponentDefinition),\n\n app: checkedComponent,\n\n schemaChange,\n});\nexport type StartPushResponse = z.infer<typeof startPushResponse>;\n\n// Values this short are rarely secrets, and replacing them everywhere would\n// garble unrelated strings in the output.\nconst MIN_SCRUBBED_VALUE_LENGTH = 8;\n\n/**\n * Replaces every occurrence of an environment variable's value in `node`'s\n * strings with `<redacted>`. Values reappear in push responses wherever the\n * code read them, such as auth providers built from `process.env` in\n * `auth.config.ts`.\n */\nexport function redactEnvironmentVariableValues<T>(\n node: T,\n environmentVariables: Record<string, string>,\n): T {\n const values = Object.values(environmentVariables)\n .filter((value) => value.length >= MIN_SCRUBBED_VALUE_LENGTH)\n // Strings that hold JSON, like `authDiff` entries, contain the escaped form.\n .flatMap((value) => {\n const escaped = JSON.stringify(value).slice(1, -1);\n return escaped === value ? [value] : [value, escaped];\n })\n .sort((a, b) => b.length - a.length);\n const scrub = (child: unknown): unknown => {\n if (typeof child === \"string\") {\n return values.reduce(\n (scrubbed, value) => scrubbed.split(value).join(\"<redacted>\"),\n child,\n );\n }\n if (Array.isArray(child)) {\n return child.map(scrub);\n }\n if (child !== null && typeof child === \"object\") {\n return Object.fromEntries(\n Object.entries(child).map(([key, grandchild]) => [\n key,\n scrub(grandchild),\n ]),\n );\n }\n return child;\n };\n return scrub(node) as T;\n}\n\n/**\n * A copy of the response that is safe to print. `environmentVariables` holds\n * every value on the deployment so `finish_push` can detect concurrent changes,\n * and those values are often secrets.\n */\nexport function startPushResponseForLogging(\n response: StartPushResponse,\n): StartPushResponse {\n return {\n ...redactEnvironmentVariableValues(response, response.environmentVariables),\n environmentVariables: Object.fromEntries(\n Object.keys(response.environmentVariables).map((name) => [\n name,\n \"<redacted>\",\n ]),\n ),\n };\n}\n\nexport const evaluatePushResponse = looseObject({\n schemaChange,\n});\nexport type EvaluatePushResponse = z.infer<typeof evaluatePushResponse>;\n\nexport const componentSchemaStatus = looseObject({\n schemaValidationComplete: z.boolean(),\n indexesComplete: z.number(),\n indexesTotal: z.number(),\n});\nexport type ComponentSchemaStatus = z.infer<typeof componentSchemaStatus>;\n\nexport const schemaStatus = z.union([\n looseObject({\n type: z.literal(\"inProgress\"),\n components: z.record(componentPath, componentSchemaStatus),\n }),\n looseObject({\n type: z.literal(\"failed\"),\n error: z.string(),\n componentPath,\n tableName: z.nullable(z.string()),\n }),\n looseObject({\n type: z.literal(\"raceDetected\"),\n }),\n looseObject({\n type: z.literal(\"complete\"),\n }),\n]);\nexport type SchemaStatus = z.infer<typeof schemaStatus>;\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/cjs/cli/lib/env.js
CHANGED
|
@@ -42,6 +42,7 @@ var import_run = require("./run.js");
|
|
|
42
42
|
var import_utils = require("./utils/utils.js");
|
|
43
43
|
var import_stdin = require("./utils/stdin.js");
|
|
44
44
|
var import_prompts = require("./utils/prompts.js");
|
|
45
|
+
var import_aiAgent = require("./utils/aiAgent.js");
|
|
45
46
|
var import_envvars = require("./envvars.js");
|
|
46
47
|
var import_formatEnvValueForDotfile = require("./formatEnvValueForDotfile.js");
|
|
47
48
|
var import_utils2 = require("./utils/utils.js");
|
|
@@ -150,8 +151,10 @@ async function envList(ctx, backend, options) {
|
|
|
150
151
|
(0, import_log.logMessage)(`No environment variables set${backend.notice}`);
|
|
151
152
|
return;
|
|
152
153
|
}
|
|
154
|
+
const agent = options?.namesOnly || options?.includeValues ? null : await (0, import_aiAgent.detectAiAgent)();
|
|
155
|
+
const namesOnly = options?.namesOnly || agent !== null;
|
|
153
156
|
for (const { name, value } of envs) {
|
|
154
|
-
if (
|
|
157
|
+
if (namesOnly) {
|
|
155
158
|
(0, import_log.logOutput)(name);
|
|
156
159
|
continue;
|
|
157
160
|
}
|
|
@@ -161,6 +164,11 @@ async function envList(ctx, backend, options) {
|
|
|
161
164
|
}
|
|
162
165
|
(0, import_log.logOutput)(`${name}=${formatted}`);
|
|
163
166
|
}
|
|
167
|
+
if (agent !== null) {
|
|
168
|
+
(0, import_log.logMessage)(
|
|
169
|
+
`Listed names only because an AI agent (${agent}) appears to be running this command. Pass --include-values to print the values too.`
|
|
170
|
+
);
|
|
171
|
+
}
|
|
164
172
|
}
|
|
165
173
|
async function getFileContents(ctx, filePath) {
|
|
166
174
|
if (!ctx.fs.exists(filePath)) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/cli/lib/env.ts"],
|
|
4
|
-
"sourcesContent": ["import { chalkStderr } from \"chalk\";\nimport * as dotenv from \"dotenv\";\nimport { Context } from \"../../bundler/context.js\";\nimport {\n logFailure,\n logFinishedStep,\n logMessage,\n logOutput,\n} from \"../../bundler/log.js\";\nimport { runSystemQuery } from \"./run.js\";\nimport { deploymentFetch, logAndHandleFetchError } from \"./utils/utils.js\";\nimport { readFromStdin } from \"./utils/stdin.js\";\nimport { promptSecret } from \"./utils/prompts.js\";\nimport {\n EXPECTED_CONVEX_URL_NAMES,\n EXPECTED_SITE_URL_NAMES,\n} from \"./envvars.js\";\nimport { formatEnvValueForDotfile } from \"./formatEnvValueForDotfile.js\";\nimport {\n CONVEX_DEPLOY_KEY_ENV_VAR_NAME,\n CONVEX_DEPLOYMENT_ENV_VAR_NAME,\n CONVEX_DEPLOYMENT_TOKEN_ENV_VAR_NAME,\n CONVEX_SELF_HOSTED_URL_VAR_NAME,\n CONVEX_SELF_HOSTED_ADMIN_KEY_VAR_NAME,\n} from \"./utils/utils.js\";\n\nfunction formatList(items: string[]): string {\n if (items.length === 0) return \"\";\n if (items.length === 1) return items[0];\n if (items.length === 2) return `${items[0]} and ${items[1]}`;\n return `${items.slice(0, -1).join(\", \")}, and ${items[items.length - 1]}`;\n}\n\nexport type EnvVarChange = {\n name: string;\n value: string | null; // null = delete\n};\n\nexport type EnvVar = {\n name: string;\n value: string;\n};\n\nexport interface EnvVarBackend {\n get(name: string): Promise<EnvVar | null>;\n list(): Promise<EnvVar[]>;\n update(changes: EnvVarChange[]): Promise<void>;\n notice: string;\n}\n\nexport function deploymentEnvBackend(\n ctx: Context,\n deployment: {\n deploymentUrl: string;\n adminKey: string;\n deploymentNotice?: string;\n },\n): EnvVarBackend {\n return {\n async get(name) {\n const envVar = (await runSystemQuery(ctx, {\n ...deployment,\n functionName: \"_system/cli/queryEnvironmentVariables:get\",\n componentPath: undefined,\n args: { name },\n })) as EnvVar | null;\n return envVar;\n },\n async list() {\n return (await runSystemQuery(ctx, {\n ...deployment,\n functionName: \"_system/cli/queryEnvironmentVariables\",\n componentPath: undefined,\n args: {},\n })) as EnvVar[];\n },\n async update(changes) {\n const fetch = deploymentFetch(ctx, deployment);\n try {\n await fetch(\"/api/update_environment_variables\", {\n body: JSON.stringify({ changes }),\n method: \"POST\",\n });\n } catch (e) {\n return await logAndHandleFetchError(ctx, e);\n }\n },\n notice: deployment.deploymentNotice ?? \"\",\n };\n}\n\nexport async function envSet(\n ctx: Context,\n backend: EnvVarBackend,\n originalName: string | undefined,\n originalValue: string | undefined,\n options?: {\n fromFile?: string;\n force?: boolean;\n secret?: boolean;\n },\n) {\n const { fromFile, force = false } = options ?? {};\n if (originalName) {\n let name = originalName,\n value: string;\n const parsed = await allowEqualsSyntax(ctx, originalName, originalValue);\n if (parsed) {\n [name, value] = parsed;\n } else if (fromFile) {\n value = await getFileContents(ctx, fromFile);\n } else if (!process.stdin.isTTY) {\n value = await getStdIn(ctx);\n } else {\n value = await promptSecret(ctx, {\n message: `Enter value for ${name}:`,\n });\n }\n await backend.update([{ name, value }]);\n if (options?.secret) {\n const formatted = /\\s/.test(value) ? `\"${value}\"` : value;\n logFinishedStep(\n `Successfully set ${chalkStderr.bold(name)} to ${chalkStderr.bold(formatted)}${backend.notice}`,\n );\n } else {\n logFinishedStep(\n `Successfully set ${chalkStderr.bold(name)}${backend.notice}`,\n );\n }\n return true;\n }\n let content: string, source: string;\n if (fromFile) {\n content = await getFileContents(ctx, fromFile);\n source = fromFile;\n } else if (!process.stdin.isTTY) {\n content = await getStdIn(ctx);\n source = \"stdin\";\n } else {\n return false;\n }\n await envSetFromContent(ctx, backend, {\n content,\n source,\n force,\n });\n return true;\n}\n\nexport async function envGet(\n ctx: Context,\n backend: EnvVarBackend,\n name: string,\n) {\n const envVar = await backend.get(name);\n if (envVar === null) {\n logFailure(`Environment variable \"${name}\" not found${backend.notice}`);\n return;\n }\n logOutput(`${envVar.value}`);\n}\n\nexport async function envRemove(\n ctx: Context,\n backend: EnvVarBackend,\n name: string,\n) {\n await backend.update([{ name, value: null }]);\n logFinishedStep(\n `Successfully unset ${chalkStderr.bold(name)}${backend.notice}`,\n );\n}\n\nexport async function envList(\n ctx: Context,\n backend: EnvVarBackend,\n options?: { namesOnly?: boolean },\n) {\n const envs = await backend.list();\n if (envs.length === 0) {\n logMessage(`No environment variables set${backend.notice}`);\n return;\n }\n for (const { name, value } of envs) {\n if (options?.namesOnly) {\n logOutput(name);\n continue;\n }\n const { formatted, warning } = formatEnvValueForDotfile(value);\n if (warning) {\n logMessage(`Warning (${name}): ${warning}`);\n }\n logOutput(`${name}=${formatted}`);\n }\n}\n\nasync function getFileContents(\n ctx: Context,\n filePath: string,\n): Promise<string> {\n if (!ctx.fs.exists(filePath)) {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: `error: file not found: ${filePath}`,\n });\n }\n return ctx.fs.readUtf8File(filePath);\n}\n\nasync function getStdIn(ctx: Context): Promise<string> {\n try {\n return await readFromStdin();\n } catch (error) {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: `error: failed to read from stdin: ${error instanceof Error ? error.message : String(error)}`,\n });\n }\n}\n\nasync function envSetFromContent(\n ctx: Context,\n backend: EnvVarBackend,\n options: {\n content: string;\n source: string;\n force: boolean;\n },\n) {\n const { content, source, force } = options;\n const parsedEnv = dotenv.parse(content);\n\n // Filter out CLI-managed environment variables\n const envVars = Object.entries(parsedEnv);\n const filteredVars: string[] = [];\n\n const envVarsToSet: [string, string][] = [];\n const managedVars = new Set<string>([\n CONVEX_DEPLOY_KEY_ENV_VAR_NAME,\n CONVEX_DEPLOYMENT_TOKEN_ENV_VAR_NAME,\n CONVEX_DEPLOYMENT_ENV_VAR_NAME,\n CONVEX_SELF_HOSTED_URL_VAR_NAME,\n CONVEX_SELF_HOSTED_ADMIN_KEY_VAR_NAME,\n ...EXPECTED_CONVEX_URL_NAMES,\n ...EXPECTED_SITE_URL_NAMES,\n ]);\n for (const [name, value] of envVars) {\n if (managedVars.has(name)) {\n filteredVars.push(name);\n } else {\n envVarsToSet.push([name, value]);\n }\n }\n\n if (filteredVars.length > 0) {\n const varNames = filteredVars.map((n) => chalkStderr.bold(n));\n const formattedNames = formatList(varNames);\n logMessage(\n `Skipping ${filteredVars.length} CLI-managed environment variable${filteredVars.length === 1 ? \"\" : \"s\"}: ${formattedNames}`,\n );\n }\n\n if (envVarsToSet.length === 0) {\n if (envVars.length === 0) {\n logMessage(`No environment variables found in ${source}.`);\n }\n return;\n }\n\n // Fetch existing environment variables\n const existingEnvVars = await backend.list();\n\n const existingEnvMap = new Map(\n existingEnvVars.map((env) => [env.name, env.value]),\n );\n\n // Categorize the environment variables\n const newVars: [string, string][] = [];\n const updatedVars: [string, string][] = [];\n const unchangedVars: [string, string][] = [];\n const conflicts: { name: string; existing: string; new: string }[] = [];\n\n for (const [name, value] of envVarsToSet) {\n const existingValue = existingEnvMap.get(name);\n if (existingValue === undefined) {\n newVars.push([name, value]);\n } else if (existingValue === value) {\n unchangedVars.push([name, value]);\n } else if (force) {\n updatedVars.push([name, value]);\n } else {\n conflicts.push({ name, existing: existingValue, new: value });\n }\n }\n\n // Check for conflicts if not replacing\n if (conflicts.length > 0) {\n const varNames = conflicts.map((c) => chalkStderr.bold(c.name));\n const formattedNames = formatList(varNames);\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage:\n `error: environment variable${conflicts.length === 1 ? \"\" : \"s\"} ${formattedNames} already exist${conflicts.length === 1 ? \"s\" : \"\"} with different value${conflicts.length === 1 ? \"\" : \"s\"}.\\n\\n` +\n `Use ${chalkStderr.bold(\"--force\")} to overwrite existing values.`,\n });\n }\n\n // Build the changes: only new vars when not replacing, new + updated when replacing\n const varsToUpdate = force ? [...newVars, ...updatedVars] : newVars;\n const changes: EnvVarChange[] = varsToUpdate.map(([name, value]) => ({\n name,\n value,\n }));\n\n if (changes.length > 0) {\n await backend.update(changes);\n }\n\n const newCount = newVars.length;\n const updatedCount = updatedVars.length;\n const unchangedCount = unchangedVars.length;\n\n const parts = [];\n if (newCount > 0) parts.push(`${newCount} new`);\n if (updatedCount > 0) parts.push(`${updatedCount} updated`);\n if (unchangedCount > 0) parts.push(`${unchangedCount} unchanged`);\n\n const totalProcessed = newCount + updatedCount + unchangedCount;\n if (changes.length === 0) {\n logMessage(\n `All ${totalProcessed} environment variable${totalProcessed === 1 ? \"\" : \"s\"} from ${chalkStderr.bold(source)} already set${backend.notice}`,\n );\n } else {\n logFinishedStep(\n `Successfully set ${changes.length} environment variable${changes.length === 1 ? \"\" : \"s\"} from ${chalkStderr.bold(source)} (${parts.join(\", \")})${backend.notice}`,\n );\n }\n}\n\nasync function allowEqualsSyntax(\n ctx: Context,\n name: string,\n value: string | undefined,\n): Promise<[string, string] | null> {\n if (/^[a-zA-Z][a-zA-Z0-9_]*=/.test(name)) {\n const [n, ...values] = name.split(\"=\");\n if (value === undefined) {\n return [n, values.join(\"=\")];\n } else {\n await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: `When setting an environment variable, you can either set a value with 'NAME=value', or with NAME value, but not both. Are you missing quotes around the CLI argument? Try: \\n npx convex env set '${name} ${value}'`,\n });\n }\n }\n if (value === undefined) return null;\n return [name, value];\n}\n"],
|
|
5
|
-
"mappings": "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
|
|
4
|
+
"sourcesContent": ["import { chalkStderr } from \"chalk\";\nimport * as dotenv from \"dotenv\";\nimport { Context } from \"../../bundler/context.js\";\nimport {\n logFailure,\n logFinishedStep,\n logMessage,\n logOutput,\n} from \"../../bundler/log.js\";\nimport { runSystemQuery } from \"./run.js\";\nimport { deploymentFetch, logAndHandleFetchError } from \"./utils/utils.js\";\nimport { readFromStdin } from \"./utils/stdin.js\";\nimport { promptSecret } from \"./utils/prompts.js\";\nimport { detectAiAgent } from \"./utils/aiAgent.js\";\nimport {\n EXPECTED_CONVEX_URL_NAMES,\n EXPECTED_SITE_URL_NAMES,\n} from \"./envvars.js\";\nimport { formatEnvValueForDotfile } from \"./formatEnvValueForDotfile.js\";\nimport {\n CONVEX_DEPLOY_KEY_ENV_VAR_NAME,\n CONVEX_DEPLOYMENT_ENV_VAR_NAME,\n CONVEX_DEPLOYMENT_TOKEN_ENV_VAR_NAME,\n CONVEX_SELF_HOSTED_URL_VAR_NAME,\n CONVEX_SELF_HOSTED_ADMIN_KEY_VAR_NAME,\n} from \"./utils/utils.js\";\n\nfunction formatList(items: string[]): string {\n if (items.length === 0) return \"\";\n if (items.length === 1) return items[0];\n if (items.length === 2) return `${items[0]} and ${items[1]}`;\n return `${items.slice(0, -1).join(\", \")}, and ${items[items.length - 1]}`;\n}\n\nexport type EnvVarChange = {\n name: string;\n value: string | null; // null = delete\n};\n\nexport type EnvVar = {\n name: string;\n value: string;\n};\n\nexport interface EnvVarBackend {\n get(name: string): Promise<EnvVar | null>;\n list(): Promise<EnvVar[]>;\n update(changes: EnvVarChange[]): Promise<void>;\n notice: string;\n}\n\nexport function deploymentEnvBackend(\n ctx: Context,\n deployment: {\n deploymentUrl: string;\n adminKey: string;\n deploymentNotice?: string;\n },\n): EnvVarBackend {\n return {\n async get(name) {\n const envVar = (await runSystemQuery(ctx, {\n ...deployment,\n functionName: \"_system/cli/queryEnvironmentVariables:get\",\n componentPath: undefined,\n args: { name },\n })) as EnvVar | null;\n return envVar;\n },\n async list() {\n return (await runSystemQuery(ctx, {\n ...deployment,\n functionName: \"_system/cli/queryEnvironmentVariables\",\n componentPath: undefined,\n args: {},\n })) as EnvVar[];\n },\n async update(changes) {\n const fetch = deploymentFetch(ctx, deployment);\n try {\n await fetch(\"/api/update_environment_variables\", {\n body: JSON.stringify({ changes }),\n method: \"POST\",\n });\n } catch (e) {\n return await logAndHandleFetchError(ctx, e);\n }\n },\n notice: deployment.deploymentNotice ?? \"\",\n };\n}\n\nexport async function envSet(\n ctx: Context,\n backend: EnvVarBackend,\n originalName: string | undefined,\n originalValue: string | undefined,\n options?: {\n fromFile?: string;\n force?: boolean;\n secret?: boolean;\n },\n) {\n const { fromFile, force = false } = options ?? {};\n if (originalName) {\n let name = originalName,\n value: string;\n const parsed = await allowEqualsSyntax(ctx, originalName, originalValue);\n if (parsed) {\n [name, value] = parsed;\n } else if (fromFile) {\n value = await getFileContents(ctx, fromFile);\n } else if (!process.stdin.isTTY) {\n value = await getStdIn(ctx);\n } else {\n value = await promptSecret(ctx, {\n message: `Enter value for ${name}:`,\n });\n }\n await backend.update([{ name, value }]);\n if (options?.secret) {\n const formatted = /\\s/.test(value) ? `\"${value}\"` : value;\n logFinishedStep(\n `Successfully set ${chalkStderr.bold(name)} to ${chalkStderr.bold(formatted)}${backend.notice}`,\n );\n } else {\n logFinishedStep(\n `Successfully set ${chalkStderr.bold(name)}${backend.notice}`,\n );\n }\n return true;\n }\n let content: string, source: string;\n if (fromFile) {\n content = await getFileContents(ctx, fromFile);\n source = fromFile;\n } else if (!process.stdin.isTTY) {\n content = await getStdIn(ctx);\n source = \"stdin\";\n } else {\n return false;\n }\n await envSetFromContent(ctx, backend, {\n content,\n source,\n force,\n });\n return true;\n}\n\nexport async function envGet(\n ctx: Context,\n backend: EnvVarBackend,\n name: string,\n) {\n const envVar = await backend.get(name);\n if (envVar === null) {\n logFailure(`Environment variable \"${name}\" not found${backend.notice}`);\n return;\n }\n logOutput(`${envVar.value}`);\n}\n\nexport async function envRemove(\n ctx: Context,\n backend: EnvVarBackend,\n name: string,\n) {\n await backend.update([{ name, value: null }]);\n logFinishedStep(\n `Successfully unset ${chalkStderr.bold(name)}${backend.notice}`,\n );\n}\n\nexport async function envList(\n ctx: Context,\n backend: EnvVarBackend,\n options?: { namesOnly?: boolean; includeValues?: boolean },\n) {\n const envs = await backend.list();\n if (envs.length === 0) {\n logMessage(`No environment variables set${backend.notice}`);\n return;\n }\n // Agents tend to run `env list` to check what is set, which copies every\n // secret into their context. They get names unless they ask for values.\n const agent =\n options?.namesOnly || options?.includeValues ? null : await detectAiAgent();\n const namesOnly = options?.namesOnly || agent !== null;\n for (const { name, value } of envs) {\n if (namesOnly) {\n logOutput(name);\n continue;\n }\n const { formatted, warning } = formatEnvValueForDotfile(value);\n if (warning) {\n logMessage(`Warning (${name}): ${warning}`);\n }\n logOutput(`${name}=${formatted}`);\n }\n if (agent !== null) {\n logMessage(\n `Listed names only because an AI agent (${agent}) appears to be running this command. Pass --include-values to print the values too.`,\n );\n }\n}\n\nasync function getFileContents(\n ctx: Context,\n filePath: string,\n): Promise<string> {\n if (!ctx.fs.exists(filePath)) {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: `error: file not found: ${filePath}`,\n });\n }\n return ctx.fs.readUtf8File(filePath);\n}\n\nasync function getStdIn(ctx: Context): Promise<string> {\n try {\n return await readFromStdin();\n } catch (error) {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: `error: failed to read from stdin: ${error instanceof Error ? error.message : String(error)}`,\n });\n }\n}\n\nasync function envSetFromContent(\n ctx: Context,\n backend: EnvVarBackend,\n options: {\n content: string;\n source: string;\n force: boolean;\n },\n) {\n const { content, source, force } = options;\n const parsedEnv = dotenv.parse(content);\n\n // Filter out CLI-managed environment variables\n const envVars = Object.entries(parsedEnv);\n const filteredVars: string[] = [];\n\n const envVarsToSet: [string, string][] = [];\n const managedVars = new Set<string>([\n CONVEX_DEPLOY_KEY_ENV_VAR_NAME,\n CONVEX_DEPLOYMENT_TOKEN_ENV_VAR_NAME,\n CONVEX_DEPLOYMENT_ENV_VAR_NAME,\n CONVEX_SELF_HOSTED_URL_VAR_NAME,\n CONVEX_SELF_HOSTED_ADMIN_KEY_VAR_NAME,\n ...EXPECTED_CONVEX_URL_NAMES,\n ...EXPECTED_SITE_URL_NAMES,\n ]);\n for (const [name, value] of envVars) {\n if (managedVars.has(name)) {\n filteredVars.push(name);\n } else {\n envVarsToSet.push([name, value]);\n }\n }\n\n if (filteredVars.length > 0) {\n const varNames = filteredVars.map((n) => chalkStderr.bold(n));\n const formattedNames = formatList(varNames);\n logMessage(\n `Skipping ${filteredVars.length} CLI-managed environment variable${filteredVars.length === 1 ? \"\" : \"s\"}: ${formattedNames}`,\n );\n }\n\n if (envVarsToSet.length === 0) {\n if (envVars.length === 0) {\n logMessage(`No environment variables found in ${source}.`);\n }\n return;\n }\n\n // Fetch existing environment variables\n const existingEnvVars = await backend.list();\n\n const existingEnvMap = new Map(\n existingEnvVars.map((env) => [env.name, env.value]),\n );\n\n // Categorize the environment variables\n const newVars: [string, string][] = [];\n const updatedVars: [string, string][] = [];\n const unchangedVars: [string, string][] = [];\n const conflicts: { name: string; existing: string; new: string }[] = [];\n\n for (const [name, value] of envVarsToSet) {\n const existingValue = existingEnvMap.get(name);\n if (existingValue === undefined) {\n newVars.push([name, value]);\n } else if (existingValue === value) {\n unchangedVars.push([name, value]);\n } else if (force) {\n updatedVars.push([name, value]);\n } else {\n conflicts.push({ name, existing: existingValue, new: value });\n }\n }\n\n // Check for conflicts if not replacing\n if (conflicts.length > 0) {\n const varNames = conflicts.map((c) => chalkStderr.bold(c.name));\n const formattedNames = formatList(varNames);\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage:\n `error: environment variable${conflicts.length === 1 ? \"\" : \"s\"} ${formattedNames} already exist${conflicts.length === 1 ? \"s\" : \"\"} with different value${conflicts.length === 1 ? \"\" : \"s\"}.\\n\\n` +\n `Use ${chalkStderr.bold(\"--force\")} to overwrite existing values.`,\n });\n }\n\n // Build the changes: only new vars when not replacing, new + updated when replacing\n const varsToUpdate = force ? [...newVars, ...updatedVars] : newVars;\n const changes: EnvVarChange[] = varsToUpdate.map(([name, value]) => ({\n name,\n value,\n }));\n\n if (changes.length > 0) {\n await backend.update(changes);\n }\n\n const newCount = newVars.length;\n const updatedCount = updatedVars.length;\n const unchangedCount = unchangedVars.length;\n\n const parts = [];\n if (newCount > 0) parts.push(`${newCount} new`);\n if (updatedCount > 0) parts.push(`${updatedCount} updated`);\n if (unchangedCount > 0) parts.push(`${unchangedCount} unchanged`);\n\n const totalProcessed = newCount + updatedCount + unchangedCount;\n if (changes.length === 0) {\n logMessage(\n `All ${totalProcessed} environment variable${totalProcessed === 1 ? \"\" : \"s\"} from ${chalkStderr.bold(source)} already set${backend.notice}`,\n );\n } else {\n logFinishedStep(\n `Successfully set ${changes.length} environment variable${changes.length === 1 ? \"\" : \"s\"} from ${chalkStderr.bold(source)} (${parts.join(\", \")})${backend.notice}`,\n );\n }\n}\n\nasync function allowEqualsSyntax(\n ctx: Context,\n name: string,\n value: string | undefined,\n): Promise<[string, string] | null> {\n if (/^[a-zA-Z][a-zA-Z0-9_]*=/.test(name)) {\n const [n, ...values] = name.split(\"=\");\n if (value === undefined) {\n return [n, values.join(\"=\")];\n } else {\n await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: `When setting an environment variable, you can either set a value with 'NAME=value', or with NAME value, but not both. Are you missing quotes around the CLI argument? Try: \\n npx convex env set '${name} ${value}'`,\n });\n }\n }\n if (value === undefined) return null;\n return [name, value];\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["import_utils"]
|
|
7
7
|
}
|
|
@@ -30,7 +30,8 @@ var dashboard_exports = {};
|
|
|
30
30
|
__export(dashboard_exports, {
|
|
31
31
|
DEFAULT_LOCAL_DASHBOARD_PORT: () => DEFAULT_LOCAL_DASHBOARD_PORT,
|
|
32
32
|
dashboardUrl: () => dashboardUrl,
|
|
33
|
-
handleDashboard: () => handleDashboard
|
|
33
|
+
handleDashboard: () => handleDashboard,
|
|
34
|
+
isLoopbackHost: () => isLoopbackHost
|
|
34
35
|
});
|
|
35
36
|
module.exports = __toCommonJS(dashboard_exports);
|
|
36
37
|
var import_filePaths = require("./filePaths.js");
|
|
@@ -62,6 +63,11 @@ async function handleDashboard(ctx, deployment, options) {
|
|
|
62
63
|
ctx,
|
|
63
64
|
dashboardPort,
|
|
64
65
|
async (request, response) => {
|
|
66
|
+
if (!isLoopbackHost(request.headers.host, dashboardPort)) {
|
|
67
|
+
response.statusCode = 403;
|
|
68
|
+
response.end();
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
65
71
|
const pathname = new URL(
|
|
66
72
|
request.url ?? "/",
|
|
67
73
|
// We only want to extract the pathname so the base doesn’t matter
|
|
@@ -98,6 +104,10 @@ async function handleDashboard(ctx, deployment, options) {
|
|
|
98
104
|
cleanupHandle
|
|
99
105
|
};
|
|
100
106
|
}
|
|
107
|
+
function isLoopbackHost(host, port) {
|
|
108
|
+
const normalizedHost = host?.toLowerCase();
|
|
109
|
+
return normalizedHost === `127.0.0.1:${port}` || normalizedHost === `localhost:${port}`;
|
|
110
|
+
}
|
|
101
111
|
async function reportSelfHostedEvent(ctx, {
|
|
102
112
|
anonymousId,
|
|
103
113
|
eventName,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/cli/lib/localDeployment/dashboard.ts"],
|
|
4
|
-
"sourcesContent": ["import { Context } from \"../../../bundler/context.js\";\nimport {\n dashboardOutDir,\n loadProjectDashboardConfig,\n loadUuidForAnonymousUser,\n saveProjectDashboardConfig,\n} from \"./filePaths.js\";\nimport { choosePorts } from \"./utils.js\";\nimport { startServer } from \"./serve.js\";\nimport { localDeploymentUrl, selfHostedEventTag } from \"./run.js\";\nimport serveHandler from \"serve-handler\";\nimport {\n ensureBackendBinaryDownloaded,\n ensureDashboardDownloaded,\n} from \"./download.js\";\nimport { bigBrainAPIMaybeThrows } from \"../utils/utils.js\";\n\nexport const DEFAULT_LOCAL_DASHBOARD_PORT = 6790;\n\n/**\n * This runs the `dashboard-self-hosted` app locally.\n * It's currently just used for the `anonymous` flow, while everything else\n * uses `dashboard.convex.dev`, and some of the code below is written\n * assuming this is only used for `anonymous`.\n */\nexport async function handleDashboard(\n ctx: Context,\n deployment: { name: string; cloudPort: number; adminKey: string },\n options: {\n /** The backend version to use if the user overrides the default version with the --local-backend-version flag */\n backendVersion: string | undefined;\n },\n) {\n // We call `ensureBackendBinaryDownloaded` here to get the version,\n // but `handleAnonymousDeployment` has already downloaded it.\n const { version } = await ensureBackendBinaryDownloaded(\n ctx,\n options.backendVersion === undefined\n ? { kind: \"latest\" }\n : { kind: \"version\", version: options.backendVersion },\n );\n const anonymousId = loadUuidForAnonymousUser(ctx) ?? undefined;\n await ensureDashboardDownloaded(ctx, version);\n const [dashboardPort] = await choosePorts(ctx, {\n count: 1,\n startPort: DEFAULT_LOCAL_DASHBOARD_PORT,\n requestedPorts: [null, null],\n });\n saveProjectDashboardConfig(ctx, deployment.name, {\n port: dashboardPort,\n });\n\n let hasReportedSelfHostedEvent = false;\n\n const serverOptions = { cors: false } as const;\n const { cleanupHandle } = await startServer(\n ctx,\n dashboardPort,\n async (request, response) => {\n const pathname = new URL(\n request.url ?? \"/\",\n // We only want to extract the pathname so the base doesn\u2019t matter\n \"http://localhost\",\n ).pathname;\n\n if (pathname === \"/api/current_deployment\") {\n serverOptions satisfies { cors: false };\n response.setHeader(\"Content-Type\", \"application/json\");\n response.end(\n JSON.stringify({\n name: deployment.name,\n url: localDeploymentUrl(deployment.cloudPort),\n adminKey: deployment.adminKey,\n }),\n );\n return;\n }\n\n if (!hasReportedSelfHostedEvent) {\n hasReportedSelfHostedEvent = true;\n void reportSelfHostedEvent(ctx, {\n anonymousId,\n eventName: \"self_host_dashboard_connected\",\n tag: selfHostedEventTag(\"anonymous\"),\n });\n }\n await serveHandler(request, response, {\n public: dashboardOutDir(),\n });\n },\n serverOptions,\n );\n return {\n dashboardPort,\n cleanupHandle,\n };\n}\n\nasync function reportSelfHostedEvent(\n ctx: Context,\n {\n anonymousId,\n eventName,\n eventFields,\n tag,\n }: {\n anonymousId: string | undefined;\n eventName: string;\n eventFields?: Record<string, unknown>;\n tag: string | undefined;\n },\n) {\n try {\n await bigBrainAPIMaybeThrows({\n ctx,\n method: \"POST\",\n path: \"self_hosted_event\",\n data: {\n selfHostedUuid: anonymousId,\n eventName,\n eventFields,\n tag,\n },\n });\n } catch {\n // ignore\n }\n}\n\nexport function dashboardUrl(ctx: Context, deploymentName: string) {\n const dashboardConfig = loadProjectDashboardConfig(ctx, deploymentName);\n if (dashboardConfig === null) {\n return null;\n }\n\n return `http://127.0.0.1:${dashboardConfig.port}/`;\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,uBAKO;AACP,mBAA4B;AAC5B,mBAA4B;AAC5B,iBAAuD;AACvD,2BAAyB;AACzB,sBAGO;AACP,IAAAA,gBAAuC;AAEhC,MAAM,+BAA+B;AAQ5C,eAAsB,gBACpB,KACA,YACA,SAIA;AAGA,QAAM,EAAE,QAAQ,IAAI,UAAM;AAAA,IACxB;AAAA,IACA,QAAQ,mBAAmB,SACvB,EAAE,MAAM,SAAS,IACjB,EAAE,MAAM,WAAW,SAAS,QAAQ,eAAe;AAAA,EACzD;AACA,QAAM,kBAAc,2CAAyB,GAAG,KAAK;AACrD,YAAM,2CAA0B,KAAK,OAAO;AAC5C,QAAM,CAAC,aAAa,IAAI,UAAM,0BAAY,KAAK;AAAA,IAC7C,OAAO;AAAA,IACP,WAAW;AAAA,IACX,gBAAgB,CAAC,MAAM,IAAI;AAAA,EAC7B,CAAC;AACD,mDAA2B,KAAK,WAAW,MAAM;AAAA,IAC/C,MAAM;AAAA,EACR,CAAC;AAED,MAAI,6BAA6B;AAEjC,QAAM,gBAAgB,EAAE,MAAM,MAAM;AACpC,QAAM,EAAE,cAAc,IAAI,UAAM;AAAA,IAC9B;AAAA,IACA;AAAA,IACA,OAAO,SAAS,aAAa;AAC3B,YAAM,WAAW,IAAI;AAAA,QACnB,QAAQ,OAAO;AAAA;AAAA,QAEf;AAAA,MACF,EAAE;AAEF,UAAI,aAAa,2BAA2B;AAC1C;AACA,iBAAS,UAAU,gBAAgB,kBAAkB;AACrD,iBAAS;AAAA,UACP,KAAK,UAAU;AAAA,YACb,MAAM,WAAW;AAAA,YACjB,SAAK,+BAAmB,WAAW,SAAS;AAAA,YAC5C,UAAU,WAAW;AAAA,UACvB,CAAC;AAAA,QACH;AACA;AAAA,MACF;AAEA,UAAI,CAAC,4BAA4B;AAC/B,qCAA6B;AAC7B,aAAK,sBAAsB,KAAK;AAAA,UAC9B;AAAA,UACA,WAAW;AAAA,UACX,SAAK,+BAAmB,WAAW;AAAA,QACrC,CAAC;AAAA,MACH;AACA,gBAAM,qBAAAC,SAAa,SAAS,UAAU;AAAA,QACpC,YAAQ,kCAAgB;AAAA,MAC1B,CAAC;AAAA,IACH;AAAA,IACA;AAAA,EACF;AACA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,EACF;AACF;AAEA,eAAe,sBACb,KACA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAMA;AACA,MAAI;AACF,cAAM,sCAAuB;AAAA,MAC3B;AAAA,MACA,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,MAAM;AAAA,QACJ,gBAAgB;AAAA,QAChB;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH,QAAQ;AAAA,EAER;AACF;AAEO,SAAS,aAAa,KAAc,gBAAwB;AACjE,QAAM,sBAAkB,6CAA2B,KAAK,cAAc;AACtE,MAAI,oBAAoB,MAAM;AAC5B,WAAO;AAAA,EACT;AAEA,SAAO,oBAAoB,gBAAgB,IAAI;AACjD;",
|
|
4
|
+
"sourcesContent": ["import { Context } from \"../../../bundler/context.js\";\nimport {\n dashboardOutDir,\n loadProjectDashboardConfig,\n loadUuidForAnonymousUser,\n saveProjectDashboardConfig,\n} from \"./filePaths.js\";\nimport { choosePorts } from \"./utils.js\";\nimport { startServer } from \"./serve.js\";\nimport { localDeploymentUrl, selfHostedEventTag } from \"./run.js\";\nimport serveHandler from \"serve-handler\";\nimport {\n ensureBackendBinaryDownloaded,\n ensureDashboardDownloaded,\n} from \"./download.js\";\nimport { bigBrainAPIMaybeThrows } from \"../utils/utils.js\";\n\nexport const DEFAULT_LOCAL_DASHBOARD_PORT = 6790;\n\n/**\n * This runs the `dashboard-self-hosted` app locally.\n * It's currently just used for the `anonymous` flow, while everything else\n * uses `dashboard.convex.dev`, and some of the code below is written\n * assuming this is only used for `anonymous`.\n */\nexport async function handleDashboard(\n ctx: Context,\n deployment: { name: string; cloudPort: number; adminKey: string },\n options: {\n /** The backend version to use if the user overrides the default version with the --local-backend-version flag */\n backendVersion: string | undefined;\n },\n) {\n // We call `ensureBackendBinaryDownloaded` here to get the version,\n // but `handleAnonymousDeployment` has already downloaded it.\n const { version } = await ensureBackendBinaryDownloaded(\n ctx,\n options.backendVersion === undefined\n ? { kind: \"latest\" }\n : { kind: \"version\", version: options.backendVersion },\n );\n const anonymousId = loadUuidForAnonymousUser(ctx) ?? undefined;\n await ensureDashboardDownloaded(ctx, version);\n const [dashboardPort] = await choosePorts(ctx, {\n count: 1,\n startPort: DEFAULT_LOCAL_DASHBOARD_PORT,\n requestedPorts: [null, null],\n });\n saveProjectDashboardConfig(ctx, deployment.name, {\n port: dashboardPort,\n });\n\n let hasReportedSelfHostedEvent = false;\n\n const serverOptions = { cors: false } as const;\n const { cleanupHandle } = await startServer(\n ctx,\n dashboardPort,\n async (request, response) => {\n if (!isLoopbackHost(request.headers.host, dashboardPort)) {\n response.statusCode = 403;\n response.end();\n return;\n }\n\n const pathname = new URL(\n request.url ?? \"/\",\n // We only want to extract the pathname so the base doesn\u2019t matter\n \"http://localhost\",\n ).pathname;\n\n if (pathname === \"/api/current_deployment\") {\n serverOptions satisfies { cors: false };\n response.setHeader(\"Content-Type\", \"application/json\");\n response.end(\n JSON.stringify({\n name: deployment.name,\n url: localDeploymentUrl(deployment.cloudPort),\n adminKey: deployment.adminKey,\n }),\n );\n return;\n }\n\n if (!hasReportedSelfHostedEvent) {\n hasReportedSelfHostedEvent = true;\n void reportSelfHostedEvent(ctx, {\n anonymousId,\n eventName: \"self_host_dashboard_connected\",\n tag: selfHostedEventTag(\"anonymous\"),\n });\n }\n await serveHandler(request, response, {\n public: dashboardOutDir(),\n });\n },\n serverOptions,\n );\n return {\n dashboardPort,\n cleanupHandle,\n };\n}\n\n/**\n * The dashboard is only meant to be opened at the URL the CLI prints, so\n * requests addressed to any other hostname are not served, even if that\n * hostname resolves to 127.0.0.1.\n */\nexport function isLoopbackHost(host: string | undefined, port: number) {\n const normalizedHost = host?.toLowerCase();\n return (\n normalizedHost === `127.0.0.1:${port}` ||\n normalizedHost === `localhost:${port}`\n );\n}\n\nasync function reportSelfHostedEvent(\n ctx: Context,\n {\n anonymousId,\n eventName,\n eventFields,\n tag,\n }: {\n anonymousId: string | undefined;\n eventName: string;\n eventFields?: Record<string, unknown>;\n tag: string | undefined;\n },\n) {\n try {\n await bigBrainAPIMaybeThrows({\n ctx,\n method: \"POST\",\n path: \"self_hosted_event\",\n data: {\n selfHostedUuid: anonymousId,\n eventName,\n eventFields,\n tag,\n },\n });\n } catch {\n // ignore\n }\n}\n\nexport function dashboardUrl(ctx: Context, deploymentName: string) {\n const dashboardConfig = loadProjectDashboardConfig(ctx, deploymentName);\n if (dashboardConfig === null) {\n return null;\n }\n\n return `http://127.0.0.1:${dashboardConfig.port}/`;\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,uBAKO;AACP,mBAA4B;AAC5B,mBAA4B;AAC5B,iBAAuD;AACvD,2BAAyB;AACzB,sBAGO;AACP,IAAAA,gBAAuC;AAEhC,MAAM,+BAA+B;AAQ5C,eAAsB,gBACpB,KACA,YACA,SAIA;AAGA,QAAM,EAAE,QAAQ,IAAI,UAAM;AAAA,IACxB;AAAA,IACA,QAAQ,mBAAmB,SACvB,EAAE,MAAM,SAAS,IACjB,EAAE,MAAM,WAAW,SAAS,QAAQ,eAAe;AAAA,EACzD;AACA,QAAM,kBAAc,2CAAyB,GAAG,KAAK;AACrD,YAAM,2CAA0B,KAAK,OAAO;AAC5C,QAAM,CAAC,aAAa,IAAI,UAAM,0BAAY,KAAK;AAAA,IAC7C,OAAO;AAAA,IACP,WAAW;AAAA,IACX,gBAAgB,CAAC,MAAM,IAAI;AAAA,EAC7B,CAAC;AACD,mDAA2B,KAAK,WAAW,MAAM;AAAA,IAC/C,MAAM;AAAA,EACR,CAAC;AAED,MAAI,6BAA6B;AAEjC,QAAM,gBAAgB,EAAE,MAAM,MAAM;AACpC,QAAM,EAAE,cAAc,IAAI,UAAM;AAAA,IAC9B;AAAA,IACA;AAAA,IACA,OAAO,SAAS,aAAa;AAC3B,UAAI,CAAC,eAAe,QAAQ,QAAQ,MAAM,aAAa,GAAG;AACxD,iBAAS,aAAa;AACtB,iBAAS,IAAI;AACb;AAAA,MACF;AAEA,YAAM,WAAW,IAAI;AAAA,QACnB,QAAQ,OAAO;AAAA;AAAA,QAEf;AAAA,MACF,EAAE;AAEF,UAAI,aAAa,2BAA2B;AAC1C;AACA,iBAAS,UAAU,gBAAgB,kBAAkB;AACrD,iBAAS;AAAA,UACP,KAAK,UAAU;AAAA,YACb,MAAM,WAAW;AAAA,YACjB,SAAK,+BAAmB,WAAW,SAAS;AAAA,YAC5C,UAAU,WAAW;AAAA,UACvB,CAAC;AAAA,QACH;AACA;AAAA,MACF;AAEA,UAAI,CAAC,4BAA4B;AAC/B,qCAA6B;AAC7B,aAAK,sBAAsB,KAAK;AAAA,UAC9B;AAAA,UACA,WAAW;AAAA,UACX,SAAK,+BAAmB,WAAW;AAAA,QACrC,CAAC;AAAA,MACH;AACA,gBAAM,qBAAAC,SAAa,SAAS,UAAU;AAAA,QACpC,YAAQ,kCAAgB;AAAA,MAC1B,CAAC;AAAA,IACH;AAAA,IACA;AAAA,EACF;AACA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,EACF;AACF;AAOO,SAAS,eAAe,MAA0B,MAAc;AACrE,QAAM,iBAAiB,MAAM,YAAY;AACzC,SACE,mBAAmB,aAAa,IAAI,MACpC,mBAAmB,aAAa,IAAI;AAExC;AAEA,eAAe,sBACb,KACA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAMA;AACA,MAAI;AACF,cAAM,sCAAuB;AAAA,MAC3B;AAAA,MACA,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,MAAM;AAAA,QACJ,gBAAgB;AAAA,QAChB;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH,QAAQ;AAAA,EAER;AACF;AAEO,SAAS,aAAa,KAAc,gBAAwB;AACjE,QAAM,sBAAkB,6CAA2B,KAAK,cAAc;AACtE,MAAI,oBAAoB,MAAM;AAC5B,WAAO;AAAA,EACT;AAEA,SAAO,oBAAoB,gBAAgB,IAAI;AACjD;",
|
|
6
6
|
"names": ["import_utils", "serveHandler"]
|
|
7
7
|
}
|
|
@@ -45,6 +45,7 @@ var import_fs = require("../../../bundler/fs.js");
|
|
|
45
45
|
var import_fsUtils = require("../fsUtils.js");
|
|
46
46
|
var import_errors = require("./errors.js");
|
|
47
47
|
var import_path = __toESM(require("path"), 1);
|
|
48
|
+
var import_utils = require("./utils.js");
|
|
48
49
|
async function makeExecutable(p) {
|
|
49
50
|
switch (process.platform) {
|
|
50
51
|
case "darwin":
|
|
@@ -74,6 +75,7 @@ async function ensureBackendBinaryDownloaded(ctx, version) {
|
|
|
74
75
|
return _ensureBackendBinaryDownloaded(ctx, latestVersionWithBinary);
|
|
75
76
|
}
|
|
76
77
|
async function _ensureBackendBinaryDownloaded(ctx, version) {
|
|
78
|
+
await assertValidBackendVersion(ctx, version);
|
|
77
79
|
(0, import_log.logVerbose)(`Ensuring backend binary downloaded for version ${version}`);
|
|
78
80
|
const existingDownload = await checkForExistingDownload(ctx, version);
|
|
79
81
|
if (existingDownload !== null) {
|
|
@@ -86,6 +88,18 @@ async function _ensureBackendBinaryDownloaded(ctx, version) {
|
|
|
86
88
|
const binaryPath = await downloadBackendBinary(ctx, version);
|
|
87
89
|
return { version, binaryPath };
|
|
88
90
|
}
|
|
91
|
+
async function assertValidBackendVersion(ctx, version) {
|
|
92
|
+
if (!(0, import_utils.isValidBackendVersion)(version)) {
|
|
93
|
+
return await ctx.crash({
|
|
94
|
+
exitCode: 1,
|
|
95
|
+
errorType: "fatal",
|
|
96
|
+
printedMessage: "Invalid local backend version",
|
|
97
|
+
errForSentry: new import_errors.LocalDeploymentError(
|
|
98
|
+
`Invalid local backend version: ${JSON.stringify(version)}`
|
|
99
|
+
)
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
}
|
|
89
103
|
let cachedLatestVersion = null;
|
|
90
104
|
async function findLatestVersionWithBinary(ctx, requireSuccess) {
|
|
91
105
|
if (cachedLatestVersion !== null) {
|
|
@@ -209,7 +223,7 @@ function getDownloadPath() {
|
|
|
209
223
|
return null;
|
|
210
224
|
}
|
|
211
225
|
function getGithubDownloadUrl(version, filename) {
|
|
212
|
-
return `https://github.com/
|
|
226
|
+
return `https://github.com/convex/convex-backend/releases/download/${version}/${filename}`;
|
|
213
227
|
}
|
|
214
228
|
async function downloadZipFile(ctx, args) {
|
|
215
229
|
const { version, filename, nameForLogging } = args;
|
|
@@ -264,6 +278,7 @@ async function downloadZipFile(ctx, args) {
|
|
|
264
278
|
return (0, import_filePaths.executablePath)(version);
|
|
265
279
|
}
|
|
266
280
|
async function ensureDashboardDownloaded(ctx, version) {
|
|
281
|
+
await assertValidBackendVersion(ctx, version);
|
|
267
282
|
const config = (0, import_filePaths.loadGlobalDashboardConfig)(ctx);
|
|
268
283
|
if (config !== null && config.version === version) {
|
|
269
284
|
return;
|