UNPKG

convex

Version:

Client for the Convex Cloud

249 lines (248 loc) 8.06 kB
"use strict"; import path from "path"; import { changeSpinner, logMessage } from "../../bundler/context.js"; import { configFromProjectConfig, getFunctionsDirectoryPath, readProjectConfig } from "./config.js"; import { finishPush, startPush, waitForSchema } from "./deploy2.js"; import { version } from "../version.js"; import { runNonComponentsPush } from "./push.js"; import { ensureHasConvexDependency, functionsDir } from "./utils/utils.js"; import { bundleDefinitions, bundleImplementations, componentGraph } from "./components/definition/bundle.js"; import { isComponentDirectory } from "./components/definition/directoryStructure.js"; import { doFinalComponentCodegen, doInitialComponentCodegen, doInitCodegen, doCodegen } from "./codegen.js"; import { typeCheckFunctionsInMode } from "./typecheck.js"; import { withTmpDir } from "../../bundler/fs.js"; import { ROOT_DEFINITION_FILENAME } from "./components/constants.js"; import { handleDebugBundlePath } from "./debugBundlePath.js"; import chalk from "chalk"; import { deploymentSelectionFromOptions, fetchDeploymentCredentialsProvisionProd } from "./api.js"; export async function runCodegen(ctx, options) { await ensureHasConvexDependency(ctx, "codegen"); const { configPath, projectConfig } = await readProjectConfig(ctx); const functionsDirectoryPath = functionsDir(configPath, projectConfig); const componentRootPath = path.resolve( path.join(functionsDirectoryPath, ROOT_DEFINITION_FILENAME) ); if (ctx.fs.exists(componentRootPath)) { const deploymentSelection = deploymentSelectionFromOptions(options); const credentials = await fetchDeploymentCredentialsProvisionProd( ctx, deploymentSelection ); await startComponentsPushAndCodegen(ctx, projectConfig, configPath, { ...options, ...credentials, generateCommonJSApi: options.commonjs, verbose: options.dryRun }); } else { if (options.init) { await doInitCodegen(ctx, functionsDirectoryPath, false, { dryRun: options.dryRun, debug: options.debug }); } if (options.typecheck !== "disable") { logMessage(ctx, chalk.gray("Running TypeScript typecheck\u2026")); } await doCodegen(ctx, functionsDirectoryPath, options.typecheck, { dryRun: options.dryRun, debug: options.debug, generateCommonJSApi: options.commonjs }); } } export async function runPush(ctx, options) { const { configPath, projectConfig } = await readProjectConfig(ctx); const convexDir = functionsDir(configPath, projectConfig); const componentRootPath = path.resolve( path.join(convexDir, ROOT_DEFINITION_FILENAME) ); if (ctx.fs.exists(componentRootPath)) { await runComponentsPush(ctx, options, configPath, projectConfig); } else { await runNonComponentsPush(ctx, options, configPath, projectConfig); } } async function startComponentsPushAndCodegen(ctx, projectConfig, configPath, options) { const verbose = options.verbose || options.dryRun; const convexDir = await getFunctionsDirectoryPath(ctx); const absWorkingDir = path.resolve("."); const isComponent = isComponentDirectory(ctx, convexDir, true); if (isComponent.kind === "err") { return await ctx.crash({ exitCode: 1, errorType: "invalid filesystem data", printedMessage: `Invalid component root directory (${isComponent.why}): ${convexDir}` }); } const rootComponent = isComponent.component; changeSpinner(ctx, "Traversing component definitions..."); const { components, dependencyGraph } = await componentGraph( ctx, absWorkingDir, rootComponent, verbose ); changeSpinner(ctx, "Generating server code..."); await withTmpDir(async (tmpDir) => { await doInitialComponentCodegen(ctx, tmpDir, rootComponent, options); for (const directory of components.values()) { await doInitialComponentCodegen(ctx, tmpDir, directory, options); } }); changeSpinner(ctx, "Bundling component definitions..."); const { appDefinitionSpecWithoutImpls, componentDefinitionSpecsWithoutImpls } = await bundleDefinitions( ctx, absWorkingDir, dependencyGraph, rootComponent, // Note that this *includes* the root component. [...components.values()] ); changeSpinner(ctx, "Bundling component schemas and implementations..."); const { appImplementation, componentImplementations } = await bundleImplementations( ctx, rootComponent, [...components.values()], projectConfig.node.externalPackages, verbose ); if (options.debugBundlePath) { const { config: localConfig } = await configFromProjectConfig( ctx, projectConfig, configPath, verbose ); await handleDebugBundlePath(ctx, options.debugBundlePath, localConfig); logMessage( ctx, `Wrote bundle and metadata for modules in the root to ${options.debugBundlePath}. Skipping rest of push.` ); return null; } const udfServerVersion = version; const appDefinition = { ...appDefinitionSpecWithoutImpls, ...appImplementation, udfServerVersion }; const componentDefinitions = []; for (const componentDefinition of componentDefinitionSpecsWithoutImpls) { const impl = componentImplementations.filter( (impl2) => impl2.definitionPath === componentDefinition.definitionPath )[0]; if (!impl) { return await ctx.crash({ exitCode: 1, errorType: "fatal", printedMessage: `missing! couldn't find ${componentDefinition.definitionPath} in ${componentImplementations.map((impl2) => impl2.definitionPath).toString()}` }); } componentDefinitions.push({ ...componentDefinition, ...impl, udfServerVersion }); } const startPushRequest = { adminKey: options.adminKey, dryRun: false, functions: projectConfig.functions, appDefinition, componentDefinitions, nodeDependencies: appImplementation.externalNodeDependencies }; if (options.writePushRequest) { const pushRequestPath = path.resolve(options.writePushRequest); ctx.fs.writeUtf8File( `${pushRequestPath}.json`, JSON.stringify(startPushRequest) ); return null; } const startPushResponse = await startPush( ctx, options.url, startPushRequest, verbose ); verbose && console.log("startPush:"); verbose && console.dir(startPushResponse, { depth: null }); changeSpinner(ctx, "Finalizing code generation..."); await withTmpDir(async (tmpDir) => { await doFinalComponentCodegen( ctx, tmpDir, rootComponent, rootComponent, startPushResponse, options ); for (const directory of components.values()) { await doFinalComponentCodegen( ctx, tmpDir, rootComponent, directory, startPushResponse, options ); } }); changeSpinner(ctx, "Running TypeScript..."); await typeCheckFunctionsInMode(ctx, options.typecheck, rootComponent.path); for (const directory of components.values()) { await typeCheckFunctionsInMode(ctx, options.typecheck, directory.path); } return startPushResponse; } export async function runComponentsPush(ctx, options, configPath, projectConfig) { const verbose = options.verbose || options.dryRun; await ensureHasConvexDependency(ctx, "push"); if (options.dryRun) { return await ctx.crash({ exitCode: 1, errorType: "fatal", printedMessage: "dryRun not allowed yet" }); } const startPushResponse = await startComponentsPushAndCodegen( ctx, projectConfig, configPath, options ); if (!startPushResponse) { return; } changeSpinner(ctx, "Waiting for schema..."); await waitForSchema(ctx, options.adminKey, options.url, startPushResponse); const finishPushResponse = await finishPush( ctx, options.adminKey, options.url, startPushResponse ); verbose && console.log("finishPush:", finishPushResponse); } //# sourceMappingURL=components.js.map