UNPKG

convex

Version:

Client for the Convex Cloud

330 lines (329 loc) 12.7 kB
"use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var configure_exports = {}; __export(configure_exports, { deploymentCredentialsOrConfigure: () => deploymentCredentialsOrConfigure }); module.exports = __toCommonJS(configure_exports); var import_chalk = __toESM(require("chalk"), 1); var import_context = require("../bundler/context.js"); var import_api = require("./lib/api.js"); var import_config = require("./lib/config.js"); var import_deployment = require("./lib/deployment.js"); var import_init = require("./lib/init.js"); var import_utils = require("./lib/utils/utils.js"); var import_envvars = require("./lib/envvars.js"); var import_path = __toESM(require("path"), 1); var import_dashboard = require("./dashboard.js"); var import_codegen = require("./lib/codegen.js"); var import_localDeployment = require("./lib/localDeployment/localDeployment.js"); var import_prompts = require("./lib/utils/prompts.js"); async function deploymentCredentialsOrConfigure(ctx, chosenConfiguration, cmdOptions) { if (cmdOptions.url !== void 0 && cmdOptions.adminKey !== void 0) { const credentials = await handleManuallySetUrlAndAdminKey(ctx, { url: cmdOptions.url, adminKey: cmdOptions.adminKey }); return { ...credentials, cleanupHandle: null }; } const { projectSlug, teamSlug } = await selectProject( ctx, chosenConfiguration, { team: cmdOptions.team, project: cmdOptions.project } ); const deploymentOptions = cmdOptions.prod ? { kind: "prod" } : cmdOptions.local ? { kind: "local", ...cmdOptions.localOptions } : { kind: "dev" }; const { deploymentName, deploymentUrl: url, adminKey, cleanupHandle } = await ensureDeploymentProvisioned(ctx, { teamSlug, projectSlug, deploymentOptions }); await updateEnvAndConfigForDeploymentSelection(ctx, { url, deploymentName, teamSlug, projectSlug, deploymentType: deploymentOptions.kind }); return { deploymentName, url, adminKey, cleanupHandle }; } async function handleManuallySetUrlAndAdminKey(ctx, cmdOptions) { const { url, adminKey } = cmdOptions; const didErase = await (0, import_deployment.eraseDeploymentEnvVar)(ctx); if (didErase) { (0, import_context.logMessage)( ctx, import_chalk.default.yellowBright( `Removed the CONVEX_DEPLOYMENT environment variable from .env.local` ) ); } const envVarWrite = await (0, import_envvars.writeConvexUrlToEnvFile)(ctx, url); if (envVarWrite !== null) { (0, import_context.logMessage)( ctx, import_chalk.default.green( `Saved the given --url as ${envVarWrite.envVar} to ${envVarWrite.envFile}` ) ); } return { url, adminKey }; } async function selectProject(ctx, chosenConfiguration, cmdOptions) { let result = null; if (chosenConfiguration === null) { result = await getConfiguredProjectSlugs(ctx); if (result !== null && result !== "AccessDenied") { return result; } } const reconfigure = result === "AccessDenied"; const choice = chosenConfiguration !== "ask" && chosenConfiguration !== null ? chosenConfiguration : await askToConfigure(ctx, reconfigure); switch (choice) { case "new": return selectNewProject(ctx, cmdOptions); case "existing": return selectExistingProject(ctx, cmdOptions); default: return await ctx.crash({ exitCode: 1, errorType: "fatal", printedMessage: "No project selected." }); } } async function getConfiguredProjectSlugs(ctx) { const deploymentName = await (0, import_utils.getConfiguredDeploymentName)(ctx); if (deploymentName !== null) { const result = await getTeamAndProjectSlugForDeployment(ctx, { deploymentName, kind: "cloud" }); if (result !== null) { return result; } else { (0, import_context.logFailure)( ctx, `You don't have access to the project with deployment ${import_chalk.default.bold( deploymentName )}, as configured in ${import_chalk.default.bold(import_deployment.CONVEX_DEPLOYMENT_VAR_NAME)}` ); return "AccessDenied"; } } const { projectConfig } = await (0, import_config.readProjectConfig)(ctx); const { team, project } = projectConfig; if (typeof team === "string" && typeof project === "string") { const hasAccess = await hasAccessToProject(ctx, { teamSlug: team, projectSlug: project }); if (!hasAccess) { (0, import_context.logFailure)( ctx, `You don't have access to the project ${import_chalk.default.bold(project)} in team ${import_chalk.default.bold(team)} as configured in ${import_chalk.default.bold("convex.json")}` ); return "AccessDenied"; } return { teamSlug: team, projectSlug: project }; } return null; } async function getTeamAndProjectSlugForDeployment(ctx, selector) { try { const body = await (0, import_utils.bigBrainAPIMaybeThrows)({ ctx, url: `/api/deployment/${selector.deploymentName}/team_and_project`, method: "GET" }); return { teamSlug: body.team, projectSlug: body.project }; } catch (err) { if (err instanceof import_utils.ThrowingFetchError && (err.serverErrorData?.code === "DeploymentNotFound" || err.serverErrorData?.code === "ProjectNotFound")) { return null; } return (0, import_utils.logAndHandleFetchError)(ctx, err); } } async function hasAccessToProject(ctx, selector) { try { await (0, import_utils.bigBrainAPIMaybeThrows)({ ctx, url: `/api/teams/${selector.teamSlug}/projects/${selector.projectSlug}/deployments`, method: "GET" }); return true; } catch (err) { if (err instanceof import_utils.ThrowingFetchError && (err.serverErrorData?.code === "TeamNotFound" || err.serverErrorData?.code === "ProjectNotFound")) { return false; } return (0, import_utils.logAndHandleFetchError)(ctx, err); } } const cwd = import_path.default.basename(process.cwd()); async function selectNewProject(ctx, config) { const { teamSlug: selectedTeam, chosen: didChooseBetweenTeams } = await (0, import_utils.validateOrSelectTeam)(ctx, config.team, "Team:"); let projectName = config.project || cwd; if (!config.project) { projectName = await (0, import_prompts.promptString)(ctx, { message: "Project name:", default: cwd }); } (0, import_context.showSpinner)(ctx, "Creating new Convex project..."); let projectSlug, teamSlug, projectsRemaining; try { ({ projectSlug, teamSlug, projectsRemaining } = await (0, import_api.createProject)(ctx, { teamSlug: selectedTeam, projectName })); } catch (err) { (0, import_context.logFailure)(ctx, "Unable to create project."); return await (0, import_utils.logAndHandleFetchError)(ctx, err); } const teamMessage = didChooseBetweenTeams ? " in team " + import_chalk.default.bold(teamSlug) : ""; (0, import_context.logFinishedStep)( ctx, `Created project ${import_chalk.default.bold( projectSlug )}${teamMessage}, manage it at ${import_chalk.default.bold( (0, import_dashboard.projectDashboardUrl)(teamSlug, projectSlug) )}` ); if (projectsRemaining <= 2) { (0, import_context.logWarning)( ctx, import_chalk.default.yellow.bold( `Your account now has ${projectsRemaining} project${projectsRemaining === 1 ? "" : "s"} remaining.` ) ); } const { projectConfig: existingProjectConfig } = await (0, import_config.readProjectConfig)(ctx); const configPath = await (0, import_config.configFilepath)(ctx); const functionsPath = (0, import_utils.functionsDir)(configPath, existingProjectConfig); await (0, import_codegen.doInitCodegen)(ctx, functionsPath, true); await (0, import_codegen.doCodegen)(ctx, functionsPath, "disable"); return { teamSlug, projectSlug }; } async function selectExistingProject(ctx, config) { const { teamSlug } = await (0, import_utils.validateOrSelectTeam)(ctx, config.team, "Team:"); const projectSlug = await (0, import_utils.validateOrSelectProject)( ctx, config.project, teamSlug, "Configure project", "Project:" ); if (projectSlug === null) { return await ctx.crash({ exitCode: 1, errorType: "fatal", printedMessage: "Run the command again to create a new project instead." }); } (0, import_context.showSpinner)(ctx, `Reinitializing project ${projectSlug}... `); const { projectConfig: existingProjectConfig } = await (0, import_config.readProjectConfig)(ctx); const functionsPath = (0, import_utils.functionsDir)((0, import_config.configName)(), existingProjectConfig); await (0, import_codegen.doCodegen)(ctx, functionsPath, "disable"); return { teamSlug, projectSlug }; } async function askToConfigure(ctx, reconfigure) { if (!await (0, import_utils.hasProjects)(ctx)) { return "new"; } return await (0, import_prompts.promptOptions)(ctx, { message: reconfigure ? "Configure a different project?" : "What would you like to configure?", default: "new", choices: [ { name: "create a new project", value: "new" }, { name: "choose an existing project", value: "existing" } ] }); } async function ensureDeploymentProvisioned(ctx, options) { switch (options.deploymentOptions.kind) { case "dev": case "prod": { const credentials = await (0, import_api.fetchDeploymentCredentialsProvisioningDevOrProdMaybeThrows)( ctx, { teamSlug: options.teamSlug, projectSlug: options.projectSlug }, options.deploymentOptions.kind ); return { ...credentials, cleanupHandle: null, onActivity: null }; } case "local": { const credentials = await (0, import_localDeployment.handleLocalDeployment)(ctx, { teamSlug: options.teamSlug, projectSlug: options.projectSlug, ...options.deploymentOptions }); return credentials; } default: return await ctx.crash({ exitCode: 1, errorType: "fatal", printedMessage: `Invalid deployment type: ${options.deploymentOptions.kind}`, errForSentry: `Invalid deployment type: ${options.deploymentOptions.kind}` }); } } async function updateEnvAndConfigForDeploymentSelection(ctx, options) { const { configPath, projectConfig: existingProjectConfig } = await (0, import_config.readProjectConfig)(ctx); const functionsPath = (0, import_utils.functionsDir)((0, import_config.configName)(), existingProjectConfig); const { wroteToGitIgnore, changedDeploymentEnvVar } = await (0, import_deployment.writeDeploymentEnvVar)(ctx, options.deploymentType, { team: options.teamSlug, project: options.projectSlug, deploymentName: options.deploymentName }); const projectConfig = await (0, import_config.upgradeOldAuthInfoToAuthConfig)( ctx, existingProjectConfig, functionsPath ); await (0, import_config.writeProjectConfig)(ctx, projectConfig, { deleteIfAllDefault: true }); await (0, import_init.finalizeConfiguration)(ctx, { deploymentType: options.deploymentType, url: options.url, wroteToGitIgnore, changedDeploymentEnvVar, functionsPath: (0, import_utils.functionsDir)(configPath, projectConfig) }); } //# sourceMappingURL=configure.js.map