UNPKG

convex

Version:

Client for the Convex Cloud

207 lines (205 loc) 7.45 kB
"use strict"; import { Command } from "@commander-js/extra-typings"; import { chalkStderr } from "chalk"; import { logMessage, logOutput } from "../bundler/log.js"; import { oneoffContext } from "../bundler/context.js"; import { jsonToConvex } from "../values/value.js"; import { loadSelectedDeploymentCredentials } from "./lib/api.js"; import { actionDescription } from "./lib/command.js"; import { formatValue, pushToDeployment, runInDeployment, runSystemQuery } from "./lib/run.js"; import { ensureHasConvexDependency } from "./lib/utils/utils.js"; import { getDeploymentSelection } from "./lib/deploymentSelection.js"; import { withRunningBackend } from "./lib/localDeployment/run.js"; import { inlineQueryToQuerySource, runTestFunctionQuery } from "./lib/runTestFunction.js"; import { logAndHandleFetchError, ThrowingFetchError } from "./lib/utils/utils.js"; export const run = new Command("run").description( "Run a function or evaluate an inline readonly query on your deployment" ).allowExcessArguments(false).addRunOptions().addDeploymentSelectionOptions(actionDescription("Run the function on")).showHelpAfterError().action(async (functionName, argsString, options) => { const ctx = await oneoffContext(options); const target = await resolveRunTarget({ ctx, functionName, argsString, options }); if (target.kind === "function" || options.push) { await ensureHasConvexDependency(ctx, "run"); } const deploymentSelection = await getDeploymentSelection(ctx, options); const deployment = await loadSelectedDeploymentCredentials( ctx, deploymentSelection, { ensureLocalRunning: false } ); if (deployment.deploymentFields?.deploymentType === "prod" && options.push) { return await ctx.crash({ exitCode: 1, errorType: "fatal", printedMessage: `\`convex run\` doesn't support pushing functions to prod deployments. Remove the --push flag. To push to production use \`npx convex deploy\`.` }); } await withRunningBackend({ ctx, deployment: { deploymentUrl: deployment.url, deploymentFields: deployment.deploymentFields }, action: async () => { if (target.kind === "inlineQuery") { if (options.push) { await pushToDeployment(ctx, { deploymentUrl: deployment.url, adminKey: deployment.adminKey, deploymentName: deployment.deploymentFields?.deploymentName ?? null, typecheck: options.typecheck, typecheckComponents: options.typecheckComponents, codegen: options.codegen === "enable", liveComponentSources: Boolean(options.liveComponentSources) }); } return await runInlineQueryInDeployment({ ctx, deploymentUrl: deployment.url, adminKey: deployment.adminKey, inlineQuery: target.inlineQuery, ...options.component !== void 0 ? { componentPath: options.component } : {} }); } await runInDeployment(ctx, { deploymentUrl: deployment.url, adminKey: deployment.adminKey, deploymentName: deployment.deploymentFields?.deploymentName ?? null, functionName: target.functionName, argsString: target.argsString, componentPath: options.component, identityString: options.identity, push: Boolean(options.push), watch: Boolean(options.watch), typecheck: options.typecheck, typecheckComponents: options.typecheckComponents, codegen: options.codegen === "enable", liveComponentSources: Boolean(options.liveComponentSources) }); } }); }); async function resolveRunTarget(args) { const inlineQuery = args.options.inlineQuery?.trim(); if (inlineQuery !== void 0 && args.functionName !== void 0) { return await args.ctx.crash({ exitCode: 1, errorType: "fatal", printedMessage: "`npx convex run` accepts either <functionName> or `--inline-query`, not both." }); } if (inlineQuery === void 0) { if (args.functionName === void 0) { return await args.ctx.crash({ exitCode: 1, errorType: "fatal", printedMessage: "`npx convex run` requires either <functionName> or `--inline-query`." }); } return { kind: "function", functionName: args.functionName, argsString: args.argsString ?? "{}" }; } if (inlineQuery.length === 0) { return await args.ctx.crash({ exitCode: 1, errorType: "fatal", printedMessage: "`--inline-query` must not be empty." }); } if (args.options.watch) { return await args.ctx.crash({ exitCode: 1, errorType: "fatal", printedMessage: "`--inline-query` can't be combined with `--watch`. Use `convex run <functionName> --watch` for named deployed queries." }); } if (args.options.identity !== void 0) { return await args.ctx.crash({ exitCode: 1, errorType: "fatal", printedMessage: "`--inline-query` can't be combined with `--identity`." }); } return { kind: "inlineQuery", inlineQuery }; } async function runInlineQueryInDeployment(args) { try { const componentId = await resolveInlineQueryComponentId(args); const outcome = await runTestFunctionQuery(args.ctx, { deploymentUrl: args.deploymentUrl, adminKey: args.adminKey, querySource: inlineQueryToQuerySource(args.inlineQuery), ...componentId !== void 0 ? { componentId } : {} }); if (outcome.kind === "applicationFailure") { return await args.ctx.crash({ exitCode: 1, errorType: "fatal", printedMessage: chalkStderr.red( `Query failed: ${JSON.stringify(outcome.payload, null, 2)}` ) }); } for (const line of outcome.logLines) { logMessage(line); } const convexValue = jsonToConvex(outcome.value); if (convexValue !== null) logOutput(formatValue(convexValue)); } catch (err) { if (err instanceof ThrowingFetchError) return await err.handle(args.ctx); return await logAndHandleFetchError(args.ctx, err); } } async function resolveInlineQueryComponentId(args) { const componentPath = args.componentPath?.trim(); if (componentPath === void 0 || componentPath === "_App") { return void 0; } if (componentPath.length === 0) { return await args.ctx.crash({ exitCode: 1, errorType: "fatal", printedMessage: "`--component` must not be empty." }); } const components = await runSystemQuery(args.ctx, { deploymentUrl: args.deploymentUrl, adminKey: args.adminKey, functionName: "_system/frontend/components:list", componentPath: void 0, args: {} }); const component = components.find(({ path }) => path === componentPath); if (component !== void 0) { return component.id; } const availableComponents = components.map(({ path }) => path).filter((path) => path.length > 0).sort(); const availableComponentsMessage = availableComponents.length === 0 ? "This deployment has no mounted components." : `Available components: ${availableComponents.map((path) => `\u2022 ${chalkStderr.gray(path)}`).join("\n")}`; return await args.ctx.crash({ exitCode: 1, errorType: "fatal", printedMessage: `Component path "${componentPath}" was not found. ${availableComponentsMessage} Omit \`--component\` to target the app root.` }); } //# sourceMappingURL=run.js.map