convex
Version:
Client for the Convex Cloud
785 lines (782 loc) • 26.9 kB
JavaScript
;
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 config_exports = {};
__export(config_exports, {
configFilepath: () => configFilepath,
configFromProjectConfig: () => configFromProjectConfig,
configJSON: () => configJSON,
configName: () => configName,
diffConfig: () => diffConfig,
enforceDeprecatedConfigField: () => enforceDeprecatedConfigField,
getFunctionsDirectoryPath: () => getFunctionsDirectoryPath,
handlePushConfigError: () => handlePushConfigError,
parseProjectConfig: () => parseProjectConfig,
productionProvisionHost: () => import_utils2.productionProvisionHost,
provisionHost: () => import_utils2.provisionHost,
pullConfig: () => pullConfig,
pushConfig: () => pushConfig,
readConfig: () => readConfig,
readProjectConfig: () => readProjectConfig,
removedExistingConfig: () => removedExistingConfig,
upgradeOldAuthInfoToAuthConfig: () => upgradeOldAuthInfoToAuthConfig,
writeProjectConfig: () => writeProjectConfig
});
module.exports = __toCommonJS(config_exports);
var import_chalk = __toESM(require("chalk"), 1);
var import_deep_equal = __toESM(require("deep-equal"), 1);
var import_os = require("os");
var import_path = __toESM(require("path"), 1);
var import_context = require("../../bundler/context.js");
var import_bundler = require("../../bundler/index.js");
var import_version = require("../version.js");
var import_dashboard = require("./dashboard.js");
var import_utils = require("./utils/utils.js");
var import_crypto = require("crypto");
var import_util = require("util");
var import_zlib = __toESM(require("zlib"), 1);
var import_fsUtils = require("./fsUtils.js");
var import_errors = require("./localDeployment/errors.js");
var import_utils2 = require("./utils/utils.js");
const brotli = (0, import_util.promisify)(import_zlib.default.brotliCompress);
const DEFAULT_FUNCTIONS_PATH = "convex/";
function isAuthInfo(object) {
return "applicationID" in object && typeof object.applicationID === "string" && "domain" in object && typeof object.domain === "string";
}
function isAuthInfos(object) {
return Array.isArray(object) && object.every((item) => isAuthInfo(item));
}
class ParseError extends Error {
}
async function parseProjectConfig(ctx, obj) {
if (typeof obj !== "object") {
return await ctx.crash({
exitCode: 1,
errorType: "invalid filesystem data",
printedMessage: "Expected `convex.json` to contain an object"
});
}
if (typeof obj.node === "undefined") {
obj.node = {
externalPackages: []
};
} else if (typeof obj.node.externalPackages === "undefined") {
obj.node.externalPackages = [];
} else if (!Array.isArray(obj.node.externalPackages) || !obj.node.externalPackages.every((item) => typeof item === "string")) {
return await ctx.crash({
exitCode: 1,
errorType: "invalid filesystem data",
printedMessage: "Expected `node.externalPackages` in `convex.json` to be an array of strings"
});
}
if (typeof obj.generateCommonJSApi === "undefined") {
obj.generateCommonJSApi = false;
} else if (typeof obj.generateCommonJSApi !== "boolean") {
return await ctx.crash({
exitCode: 1,
errorType: "invalid filesystem data",
printedMessage: "Expected `generateCommonJSApi` in `convex.json` to be true or false"
});
}
if (typeof obj.functions === "undefined") {
obj.functions = DEFAULT_FUNCTIONS_PATH;
} else if (typeof obj.functions !== "string") {
return await ctx.crash({
exitCode: 1,
errorType: "invalid filesystem data",
printedMessage: "Expected `functions` in `convex.json` to be a string"
});
}
if (obj.authInfo !== void 0) {
if (!isAuthInfos(obj.authInfo)) {
return await ctx.crash({
exitCode: 1,
errorType: "invalid filesystem data",
printedMessage: "Expected `authInfo` in `convex.json` to be type AuthInfo[]"
});
}
}
if (typeof obj.codegen === "undefined") {
obj.codegen = {};
}
if (typeof obj.codegen !== "object") {
return await ctx.crash({
exitCode: 1,
errorType: "invalid filesystem data",
printedMessage: "Expected `codegen` in `convex.json` to be an object"
});
}
if (typeof obj.codegen.staticApi === "undefined") {
obj.codegen.staticApi = false;
}
if (typeof obj.codegen.staticDataModel === "undefined") {
obj.codegen.staticDataModel = false;
}
if (typeof obj.codegen.staticApi !== "boolean" || typeof obj.codegen.staticDataModel !== "boolean") {
return await ctx.crash({
exitCode: 1,
errorType: "invalid filesystem data",
printedMessage: "Expected `codegen.staticApi` and `codegen.staticDataModel` in `convex.json` to be booleans"
});
}
return obj;
}
function parseBackendConfig(obj) {
if (typeof obj !== "object") {
throw new ParseError("Expected an object");
}
const { functions, authInfo } = obj;
if (typeof functions !== "string") {
throw new ParseError("Expected functions to be a string");
}
if ((authInfo ?? null) !== null && !isAuthInfos(authInfo)) {
throw new ParseError("Expected authInfo to be type AuthInfo[]");
}
return {
functions,
...(authInfo ?? null) !== null ? { authInfo } : {}
};
}
function configName() {
return "convex.json";
}
async function configFilepath(ctx) {
const configFn = configName();
const preferredLocation = configFn;
const wrongLocation = import_path.default.join("src", configFn);
const preferredLocationExists = ctx.fs.exists(preferredLocation);
const wrongLocationExists = ctx.fs.exists(wrongLocation);
if (preferredLocationExists && wrongLocationExists) {
const message = `${import_chalk.default.red(`Error: both ${preferredLocation} and ${wrongLocation} files exist!`)}
Consolidate these and remove ${wrongLocation}.`;
return await ctx.crash({
exitCode: 1,
errorType: "invalid filesystem data",
printedMessage: message
});
}
if (!preferredLocationExists && wrongLocationExists) {
return await ctx.crash({
exitCode: 1,
errorType: "invalid filesystem data",
printedMessage: `Error: Please move ${wrongLocation} to the root of your project`
});
}
return preferredLocation;
}
async function getFunctionsDirectoryPath(ctx) {
const { projectConfig, configPath } = await readProjectConfig(ctx);
return (0, import_utils.functionsDir)(configPath, projectConfig);
}
async function readProjectConfig(ctx) {
if (!ctx.fs.exists("convex.json")) {
const packages = await (0, import_utils.loadPackageJson)(ctx);
const isCreateReactApp = "react-scripts" in packages;
return {
projectConfig: {
functions: isCreateReactApp ? `src/${DEFAULT_FUNCTIONS_PATH}` : DEFAULT_FUNCTIONS_PATH,
node: {
externalPackages: []
},
generateCommonJSApi: false,
codegen: {
staticApi: false,
staticDataModel: false
}
},
configPath: configName()
};
}
let projectConfig;
const configPath = await configFilepath(ctx);
try {
projectConfig = await parseProjectConfig(
ctx,
JSON.parse(ctx.fs.readUtf8File(configPath))
);
} catch (err) {
if (err instanceof ParseError || err instanceof SyntaxError) {
(0, import_context.logError)(ctx, import_chalk.default.red(`Error: Parsing "${configPath}" failed`));
(0, import_context.logMessage)(ctx, import_chalk.default.gray(err.toString()));
} else {
(0, import_context.logFailure)(
ctx,
`Error: Unable to read project config file "${configPath}"
Are you running this command from the root directory of a Convex project? If so, run \`npx convex dev\` first.`
);
if (err instanceof Error) {
(0, import_context.logError)(ctx, import_chalk.default.red(err.message));
}
}
return await ctx.crash({
exitCode: 1,
errorType: "invalid filesystem data",
errForSentry: err,
// TODO -- move the logging above in here
printedMessage: null
});
}
return {
projectConfig,
configPath
};
}
async function enforceDeprecatedConfigField(ctx, config, field) {
const value = config[field];
if (typeof value === "string") {
return value;
}
const err = new ParseError(`Expected ${field} to be a string`);
return await ctx.crash({
exitCode: 1,
errorType: "invalid filesystem data",
errForSentry: err,
printedMessage: `Error: Parsing convex.json failed:
${import_chalk.default.gray(err.toString())}`
});
}
async function configFromProjectConfig(ctx, projectConfig, configPath, verbose) {
const baseDir = (0, import_utils.functionsDir)(configPath, projectConfig);
const entryPoints = await (0, import_bundler.entryPointsByEnvironment)(ctx, baseDir);
if (verbose) {
(0, import_context.showSpinner)(ctx, "Bundling modules for Convex's runtime...");
}
const convexResult = await (0, import_bundler.bundle)(
ctx,
baseDir,
entryPoints.isolate,
true,
"browser"
);
if (verbose) {
(0, import_context.logMessage)(
ctx,
"Convex's runtime modules: ",
convexResult.modules.map((m) => m.path)
);
}
if (verbose && entryPoints.node.length !== 0) {
(0, import_context.showSpinner)(ctx, "Bundling modules for Node.js runtime...");
}
const nodeResult = await (0, import_bundler.bundle)(
ctx,
baseDir,
entryPoints.node,
true,
"node",
import_path.default.join("_deps", "node"),
projectConfig.node.externalPackages
);
if (verbose && entryPoints.node.length !== 0) {
(0, import_context.logMessage)(
ctx,
"Node.js runtime modules: ",
nodeResult.modules.map((m) => m.path)
);
if (projectConfig.node.externalPackages.length > 0) {
(0, import_context.logMessage)(
ctx,
"Node.js runtime external dependencies (to be installed on the server): ",
[...nodeResult.externalDependencies.entries()].map(
(a) => `${a[0]}: ${a[1]}`
)
);
}
}
const modules = convexResult.modules;
modules.push(...nodeResult.modules);
modules.push(...await (0, import_bundler.bundleAuthConfig)(ctx, baseDir));
const nodeDependencies = [];
for (const [moduleName, moduleVersion] of nodeResult.externalDependencies) {
nodeDependencies.push({ name: moduleName, version: moduleVersion });
}
const bundledModuleInfos = Array.from(
convexResult.bundledModuleNames.keys()
).map((moduleName) => {
return {
name: moduleName,
platform: "convex"
};
});
bundledModuleInfos.push(
...Array.from(nodeResult.bundledModuleNames.keys()).map(
(moduleName) => {
return {
name: moduleName,
platform: "node"
};
}
)
);
return {
config: {
projectConfig,
modules,
nodeDependencies,
// We're just using the version this CLI is running with for now.
// This could be different than the version of `convex` the app runs with
// if the CLI is installed globally.
udfServerVersion: import_version.version
},
bundledModuleInfos
};
}
async function readConfig(ctx, verbose) {
const { projectConfig, configPath } = await readProjectConfig(ctx);
const { config, bundledModuleInfos } = await configFromProjectConfig(
ctx,
projectConfig,
configPath,
verbose
);
return { config, configPath, bundledModuleInfos };
}
async function upgradeOldAuthInfoToAuthConfig(ctx, config, functionsPath) {
if (config.authInfo !== void 0) {
const authConfigPathJS = import_path.default.resolve(functionsPath, "auth.config.js");
const authConfigPathTS = import_path.default.resolve(functionsPath, "auth.config.js");
const authConfigPath = ctx.fs.exists(authConfigPathJS) ? authConfigPathJS : authConfigPathTS;
const authConfigRelativePath = import_path.default.join(
config.functions,
ctx.fs.exists(authConfigPathJS) ? "auth.config.js" : "auth.config.ts"
);
if (ctx.fs.exists(authConfigPath)) {
await ctx.crash({
exitCode: 1,
errorType: "invalid filesystem data",
printedMessage: `Cannot set auth config in both \`${authConfigRelativePath}\` and convex.json, remove it from convex.json`
});
}
if (config.authInfo.length > 0) {
const providersStringLines = JSON.stringify(
config.authInfo,
null,
2
).split(import_os.EOL);
const indentedProvidersString = [providersStringLines[0]].concat(providersStringLines.slice(1).map((line) => ` ${line}`)).join(import_os.EOL);
ctx.fs.writeUtf8File(
authConfigPath,
` export default {
providers: ${indentedProvidersString},
};`
);
(0, import_context.logMessage)(
ctx,
import_chalk.default.yellowBright(
`Moved auth config from config.json to \`${authConfigRelativePath}\``
)
);
}
delete config.authInfo;
}
return config;
}
async function writeProjectConfig(ctx, projectConfig, { deleteIfAllDefault } = {
deleteIfAllDefault: false
}) {
const configPath = await configFilepath(ctx);
const strippedConfig = filterWriteableConfig(stripDefaults(projectConfig));
if (Object.keys(strippedConfig).length > 0) {
try {
const contents = JSON.stringify(strippedConfig, void 0, 2) + "\n";
ctx.fs.writeUtf8File(configPath, contents, 420);
} catch (err) {
return await ctx.crash({
exitCode: 1,
errorType: "invalid filesystem data",
errForSentry: err,
printedMessage: `Error: Unable to write project config file "${configPath}" in current directory
Are you running this command from the root directory of a Convex project?`
});
}
} else if (deleteIfAllDefault && ctx.fs.exists(configPath)) {
ctx.fs.unlink(configPath);
(0, import_context.logMessage)(
ctx,
import_chalk.default.yellowBright(
`Deleted ${configPath} since it completely matched defaults`
)
);
}
ctx.fs.mkdir((0, import_utils.functionsDir)(configPath, projectConfig), {
allowExisting: true
});
}
function stripDefaults(projectConfig) {
const stripped = { ...projectConfig };
if (stripped.functions === DEFAULT_FUNCTIONS_PATH) {
delete stripped.functions;
}
if (Array.isArray(stripped.authInfo) && stripped.authInfo.length === 0) {
delete stripped.authInfo;
}
if (stripped.node.externalPackages.length === 0) {
delete stripped.node.externalPackages;
}
if (stripped.generateCommonJSApi === false) {
delete stripped.generateCommonJSApi;
}
if (Object.keys(stripped.node).length === 0) {
delete stripped.node;
}
if (stripped.codegen.staticApi === false) {
delete stripped.codegen.staticApi;
}
if (stripped.codegen.staticDataModel === false) {
delete stripped.codegen.staticDataModel;
}
if (Object.keys(stripped.codegen).length === 0) {
delete stripped.codegen;
}
return stripped;
}
function filterWriteableConfig(projectConfig) {
const writeable = { ...projectConfig };
delete writeable.project;
delete writeable.team;
delete writeable.prodUrl;
return writeable;
}
function removedExistingConfig(ctx, configPath, options) {
if (!options.allowExistingConfig) {
return false;
}
(0, import_fsUtils.recursivelyDelete)(ctx, configPath);
(0, import_context.logFinishedStep)(ctx, `Removed existing ${configPath}`);
return true;
}
async function pullConfig(ctx, project, team, origin, adminKey) {
const fetch = (0, import_utils.deploymentFetch)(ctx, {
deploymentUrl: origin,
adminKey
});
(0, import_context.changeSpinner)(ctx, "Downloading current deployment state...");
try {
const res = await fetch("/api/get_config_hashes", {
method: "POST",
body: JSON.stringify({ version: import_version.version, adminKey })
});
(0, import_utils.deprecationCheckWarning)(ctx, res);
const data = await res.json();
const backendConfig = parseBackendConfig(data.config);
const projectConfig = {
...backendConfig,
// This field is not stored in the backend, which is ok since it is also
// not used to diff configs.
node: {
externalPackages: []
},
// This field is not stored in the backend, it only affects the client.
generateCommonJSApi: false,
// This field is also not stored in the backend, it only affects the client.
codegen: {
staticApi: false,
staticDataModel: false
},
project,
team,
prodUrl: origin
};
return {
projectConfig,
moduleHashes: data.moduleHashes,
// TODO(presley): Add this to diffConfig().
nodeDependencies: data.nodeDependencies,
udfServerVersion: data.udfServerVersion
};
} catch (err) {
(0, import_context.logFailure)(ctx, `Error: Unable to pull deployment config from ${origin}`);
return await (0, import_utils.logAndHandleFetchError)(ctx, err);
}
}
function configJSON(config, adminKey, schemaId, pushMetrics, bundledModuleInfos) {
const projectConfig = {
projectSlug: config.projectConfig.project,
teamSlug: config.projectConfig.team,
functions: config.projectConfig.functions,
authInfo: config.projectConfig.authInfo
};
return {
config: projectConfig,
modules: config.modules,
nodeDependencies: config.nodeDependencies,
udfServerVersion: config.udfServerVersion,
schemaId,
adminKey,
pushMetrics,
bundledModuleInfos
};
}
async function pushConfig(ctx, config, options) {
const serializedConfig = configJSON(
config,
options.adminKey,
options.schemaId,
options.pushMetrics,
options.bundledModuleInfos
);
const fetch = (0, import_utils.deploymentFetch)(ctx, {
deploymentUrl: options.url,
adminKey: options.adminKey
});
try {
if (config.nodeDependencies.length > 0) {
(0, import_context.changeSpinner)(
ctx,
"Installing external packages and deploying source code..."
);
} else {
(0, import_context.changeSpinner)(ctx, "Analyzing and deploying source code...");
}
await fetch("/api/push_config", {
body: await brotli(JSON.stringify(serializedConfig), {
params: {
[import_zlib.default.constants.BROTLI_PARAM_MODE]: import_zlib.default.constants.BROTLI_MODE_TEXT,
[import_zlib.default.constants.BROTLI_PARAM_QUALITY]: 4
}
}),
method: "POST",
headers: {
"Content-Type": "application/json",
"Content-Encoding": "br"
}
});
} catch (error) {
await handlePushConfigError(
ctx,
error,
"Error: Unable to push deployment config to " + options.url,
options.deploymentName
);
}
}
function renderModule(module2) {
return module2.path + ` (${(0, import_utils.formatSize)(module2.sourceSize)}, source map ${module2.sourceMapSize})`;
}
function hash(bundle2) {
return (0, import_crypto.createHash)("sha256").update(bundle2.source).update(bundle2.sourceMap || "").digest("hex");
}
function compareModules(oldModules, newModules) {
let diff = "";
const oldModuleMap = new Map(
oldModules.map((value) => [value.path, value.hash])
);
const newModuleMap = new Map(
newModules.map((value) => [
value.path,
{
hash: hash(value),
sourceMapSize: value.sourceMap?.length ?? 0,
sourceSize: value.source.length
}
])
);
const updatedModules = [];
const identicalModules = [];
const droppedModules = [];
const addedModules = [];
for (const [path2, oldHash] of oldModuleMap.entries()) {
const newModule = newModuleMap.get(path2);
if (newModule === void 0) {
droppedModules.push(path2);
} else if (newModule.hash !== oldHash) {
updatedModules.push({
path: path2,
sourceMapSize: newModule.sourceMapSize,
sourceSize: newModule.sourceSize
});
} else {
identicalModules.push({
path: path2,
size: newModule.sourceSize + newModule.sourceMapSize
});
}
}
for (const [path2, newModule] of newModuleMap.entries()) {
if (oldModuleMap.get(path2) === void 0) {
addedModules.push({
path: path2,
sourceMapSize: newModule.sourceMapSize,
sourceSize: newModule.sourceSize
});
}
}
if (droppedModules.length > 0 || updatedModules.length > 0) {
diff += "Delete the following modules:\n";
for (const module2 of droppedModules) {
diff += `[-] ${module2}
`;
}
for (const module2 of updatedModules) {
diff += `[-] ${module2.path}
`;
}
}
if (addedModules.length > 0 || updatedModules.length > 0) {
diff += "Add the following modules:\n";
for (const module2 of addedModules) {
diff += "[+] " + renderModule(module2) + "\n";
}
for (const module2 of updatedModules) {
diff += "[+] " + renderModule(module2) + "\n";
}
}
return {
diffString: diff,
stats: {
updated: {
count: updatedModules.length,
size: updatedModules.reduce((acc, curr) => {
return acc + curr.sourceMapSize + curr.sourceSize;
}, 0)
},
identical: {
count: identicalModules.length,
size: identicalModules.reduce((acc, curr) => {
return acc + curr.size;
}, 0)
},
added: {
count: addedModules.length,
size: addedModules.reduce((acc, curr) => {
return acc + curr.sourceMapSize + curr.sourceSize;
}, 0)
},
numDropped: droppedModules.length
}
};
}
function diffConfig(oldConfig, newConfig) {
const { diffString, stats } = compareModules(
oldConfig.moduleHashes,
newConfig.modules
);
let diff = diffString;
const droppedAuth = [];
if (oldConfig.projectConfig.authInfo !== void 0 && newConfig.projectConfig.authInfo !== void 0) {
for (const oldAuth of oldConfig.projectConfig.authInfo) {
let matches2 = false;
for (const newAuth of newConfig.projectConfig.authInfo) {
if ((0, import_deep_equal.default)(oldAuth, newAuth)) {
matches2 = true;
break;
}
}
if (!matches2) {
droppedAuth.push(oldAuth);
}
}
if (droppedAuth.length > 0) {
diff += "Remove the following auth providers:\n";
for (const authInfo of droppedAuth) {
diff += "[-] " + JSON.stringify(authInfo) + "\n";
}
}
const addedAuth = [];
for (const newAuth of newConfig.projectConfig.authInfo) {
let matches2 = false;
for (const oldAuth of oldConfig.projectConfig.authInfo) {
if ((0, import_deep_equal.default)(newAuth, oldAuth)) {
matches2 = true;
break;
}
}
if (!matches2) {
addedAuth.push(newAuth);
}
}
if (addedAuth.length > 0) {
diff += "Add the following auth providers:\n";
for (const auth of addedAuth) {
diff += "[+] " + JSON.stringify(auth) + "\n";
}
}
} else if (oldConfig.projectConfig.authInfo !== void 0 !== (newConfig.projectConfig.authInfo !== void 0)) {
diff += "Moved auth config into auth.config.ts\n";
}
let versionMessage = "";
const matches = oldConfig.udfServerVersion === newConfig.udfServerVersion;
if (oldConfig.udfServerVersion && (!newConfig.udfServerVersion || !matches)) {
versionMessage += `[-] ${oldConfig.udfServerVersion}
`;
}
if (newConfig.udfServerVersion && (!oldConfig.udfServerVersion || !matches)) {
versionMessage += `[+] ${newConfig.udfServerVersion}
`;
}
if (versionMessage) {
diff += "Change the server's function version:\n";
diff += versionMessage;
}
return { diffString: diff, stats };
}
async function handlePushConfigError(ctx, error, defaultMessage, deploymentName) {
const data = error instanceof import_utils.ThrowingFetchError ? error.serverErrorData : void 0;
if (data?.code === "AuthConfigMissingEnvironmentVariable") {
const errorMessage = data.message || "(no error message given)";
const [, variableName] = errorMessage.match(/Environment variable (\S+)/i) ?? [];
const envVarMessage = `Environment variable ${import_chalk.default.bold(
variableName
)} is used in auth config file but its value was not set.`;
let setEnvVarInstructions = "Go set it in the dashboard or using `npx convex env set`";
if (deploymentName !== null) {
const variableQuery = variableName !== void 0 ? `?var=${variableName}` : "";
const dashboardUrl = (0, import_dashboard.deploymentDashboardUrlPage)(
deploymentName,
`/settings/environment-variables${variableQuery}`
);
setEnvVarInstructions = `Go to:
${import_chalk.default.bold(
dashboardUrl
)}
to set it up. `;
}
await ctx.crash({
exitCode: 1,
errorType: "invalid filesystem or env vars",
errForSentry: error,
printedMessage: envVarMessage + "\n" + setEnvVarInstructions
});
}
if (data?.code === "InternalServerError") {
if (deploymentName?.startsWith("local-")) {
(0, import_errors.printLocalDeploymentOnError)(ctx);
return ctx.crash({
exitCode: 1,
errorType: "fatal",
errForSentry: new import_errors.LocalDeploymentError(
"InternalServerError while pushing to local deployment"
),
printedMessage: defaultMessage
});
}
}
(0, import_context.logFailure)(ctx, defaultMessage);
return await (0, import_utils.logAndHandleFetchError)(ctx, error);
}
//# sourceMappingURL=config.js.map