betterstart-cli 0.0.43 → 0.0.45
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/dist/cli.js +132 -22
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -24889,9 +24889,11 @@ import * as p16 from "@clack/prompts";
|
|
|
24889
24889
|
import pc5 from "picocolors";
|
|
24890
24890
|
var PROVISION_TIMEOUT_MS2 = 18e4;
|
|
24891
24891
|
var INTERACTIVE_PROVISION_TIMEOUT_MS2 = 6e5;
|
|
24892
|
+
var RESOURCE_CONNECT_TIMEOUT_MS = 6e4;
|
|
24893
|
+
var NEON_FREE_PLAN_ID = "free_v3";
|
|
24892
24894
|
async function provisionNeonInteractive(runner, cwd, options) {
|
|
24893
|
-
const
|
|
24894
|
-
|
|
24895
|
+
const provisionSpinner = spinner2();
|
|
24896
|
+
provisionSpinner.start("Creating your Neon database");
|
|
24895
24897
|
const quiet = await runVercel(runner, neonAddArgs(options), {
|
|
24896
24898
|
cwd,
|
|
24897
24899
|
mode: "capture",
|
|
@@ -24899,25 +24901,72 @@ async function provisionNeonInteractive(runner, cwd, options) {
|
|
|
24899
24901
|
env: options.env
|
|
24900
24902
|
});
|
|
24901
24903
|
if (quiet.success) {
|
|
24902
|
-
|
|
24904
|
+
provisionSpinner.clear();
|
|
24903
24905
|
return readNeonProvisionInfo(quiet.stdout);
|
|
24904
24906
|
}
|
|
24905
|
-
|
|
24906
|
-
p16.log.info(
|
|
24907
|
-
`Create your Neon database in the Vercel prompts below ${pc5.dim(
|
|
24908
|
-
"(the Free plan is recommended)."
|
|
24909
|
-
)}`
|
|
24910
|
-
);
|
|
24907
|
+
let promptsShown = false;
|
|
24911
24908
|
const add = await runVercel(runner, connectedNeonAddArgs(options), {
|
|
24912
24909
|
cwd,
|
|
24913
|
-
mode: "
|
|
24910
|
+
mode: "stream",
|
|
24914
24911
|
timeoutMs: INTERACTIVE_PROVISION_TIMEOUT_MS2,
|
|
24915
|
-
env: options.env
|
|
24912
|
+
env: options.env,
|
|
24913
|
+
streamLineFilter: (line) => {
|
|
24914
|
+
if (!showNeonSetupLine(line)) return false;
|
|
24915
|
+
if (!promptsShown) {
|
|
24916
|
+
promptsShown = true;
|
|
24917
|
+
provisionSpinner.clear();
|
|
24918
|
+
p16.log.info(
|
|
24919
|
+
`Finish the Neon database setup in the Vercel prompts below ${pc5.dim(
|
|
24920
|
+
"(the Free plan is recommended)."
|
|
24921
|
+
)}`
|
|
24922
|
+
);
|
|
24923
|
+
}
|
|
24924
|
+
return true;
|
|
24925
|
+
}
|
|
24916
24926
|
});
|
|
24927
|
+
if (!promptsShown) provisionSpinner.clear();
|
|
24917
24928
|
if (!add.success) {
|
|
24918
|
-
|
|
24929
|
+
const combined = `${add.stdout}
|
|
24930
|
+
${add.stderr}`.trim();
|
|
24931
|
+
return {
|
|
24932
|
+
failure: add.timedOut ? "timeout" : "provision-failed",
|
|
24933
|
+
// Lines the user already saw are not repeated as detail.
|
|
24934
|
+
detail: promptsShown ? void 0 : combined || void 0
|
|
24935
|
+
};
|
|
24919
24936
|
}
|
|
24920
|
-
|
|
24937
|
+
const info = readNeonFallbackInfo(`${add.stdout}
|
|
24938
|
+
${add.stderr}`);
|
|
24939
|
+
if (promptsShown) info.usedTerminalFallback = true;
|
|
24940
|
+
return info;
|
|
24941
|
+
}
|
|
24942
|
+
var NEON_SETUP_NOISE = [
|
|
24943
|
+
/^$/,
|
|
24944
|
+
/^Vercel CLI \d/,
|
|
24945
|
+
/^>? ?Installing .+ under /,
|
|
24946
|
+
/^Provisioning resource/,
|
|
24947
|
+
/^Retrieving project/,
|
|
24948
|
+
/^>? ?Success!/,
|
|
24949
|
+
/^>? ?Guide: Run/,
|
|
24950
|
+
/^>? ?Dashboard: https:\/\//,
|
|
24951
|
+
/successfully connected to/i,
|
|
24952
|
+
/^>? ?Overwriting existing \.env/,
|
|
24953
|
+
/^>? ?Downloading/,
|
|
24954
|
+
/^Changes:/,
|
|
24955
|
+
/^\+ [A-Z][A-Z0-9_]*/,
|
|
24956
|
+
/^[✓√] +(Updated|Created)/
|
|
24957
|
+
];
|
|
24958
|
+
function showNeonSetupLine(line) {
|
|
24959
|
+
return !NEON_SETUP_NOISE.some((pattern) => pattern.test(line));
|
|
24960
|
+
}
|
|
24961
|
+
function readNeonFallbackInfo(output) {
|
|
24962
|
+
const info = {};
|
|
24963
|
+
const provisioned = output.match(/successfully provisioned: (\S+)/i)?.[1];
|
|
24964
|
+
if (provisioned) info.resourceName = provisioned;
|
|
24965
|
+
const dashboard = output.match(/Dashboard: (https:\/\/\S+)/i)?.[1];
|
|
24966
|
+
if (dashboard) info.dashboardUrl = dashboard;
|
|
24967
|
+
if (/failed to connect/i.test(output)) info.connectedToProject = false;
|
|
24968
|
+
else if (/successfully connected to/i.test(output)) info.connectedToProject = true;
|
|
24969
|
+
return info;
|
|
24921
24970
|
}
|
|
24922
24971
|
async function provisionNeon(runner, cwd, options) {
|
|
24923
24972
|
const provisionSpinner = spinner2();
|
|
@@ -24953,17 +25002,57 @@ function readNeonProvisionInfo(stdout) {
|
|
|
24953
25002
|
const info = {};
|
|
24954
25003
|
if (meta.dashboardUrl) info.dashboardUrl = meta.dashboardUrl;
|
|
24955
25004
|
if (meta.ssoUrl?.resource) info.resourceUrl = meta.ssoUrl.resource;
|
|
25005
|
+
if (meta.resource?.name) info.resourceName = meta.resource.name;
|
|
25006
|
+
const connectWarning = (meta.warnings ?? []).some((warning) => /failed to connect/i.test(warning));
|
|
25007
|
+
if (meta.envPulled === false || connectWarning) info.connectedToProject = false;
|
|
25008
|
+
else if (meta.envPulled === true) info.connectedToProject = true;
|
|
24956
25009
|
return info;
|
|
24957
25010
|
}
|
|
25011
|
+
async function replaceNeonProjectConnection(runner, cwd, resourceName, env) {
|
|
25012
|
+
const list = await runVercel(runner, ["integration", "list", "--format", "json"], {
|
|
25013
|
+
cwd,
|
|
25014
|
+
mode: "capture",
|
|
25015
|
+
timeoutMs: RESOURCE_CONNECT_TIMEOUT_MS,
|
|
25016
|
+
env
|
|
25017
|
+
});
|
|
25018
|
+
if (list.success) {
|
|
25019
|
+
const payload = parseVercelJson(list.stdout);
|
|
25020
|
+
for (const resource of payload?.resources ?? []) {
|
|
25021
|
+
if (!resource.name || resource.name === resourceName) continue;
|
|
25022
|
+
if (resource.product && !/neon/i.test(resource.product)) continue;
|
|
25023
|
+
await runVercel(runner, ["integration-resource", "disconnect", resource.name, "--yes"], {
|
|
25024
|
+
cwd,
|
|
25025
|
+
mode: "capture",
|
|
25026
|
+
timeoutMs: RESOURCE_CONNECT_TIMEOUT_MS,
|
|
25027
|
+
env
|
|
25028
|
+
});
|
|
25029
|
+
}
|
|
25030
|
+
}
|
|
25031
|
+
const connect = await runVercel(
|
|
25032
|
+
runner,
|
|
25033
|
+
["integration-resource", "connect", resourceName, "--yes"],
|
|
25034
|
+
{
|
|
25035
|
+
cwd,
|
|
25036
|
+
mode: "capture",
|
|
25037
|
+
timeoutMs: RESOURCE_CONNECT_TIMEOUT_MS,
|
|
25038
|
+
env
|
|
25039
|
+
}
|
|
25040
|
+
);
|
|
25041
|
+
return connect.success;
|
|
25042
|
+
}
|
|
24958
25043
|
function neonAddArgs(options) {
|
|
24959
|
-
|
|
24960
|
-
|
|
24961
|
-
|
|
25044
|
+
return [
|
|
25045
|
+
"integration",
|
|
25046
|
+
"add",
|
|
25047
|
+
"neon",
|
|
25048
|
+
"--format",
|
|
25049
|
+
"json",
|
|
25050
|
+
"--plan",
|
|
25051
|
+
options.plan ?? NEON_FREE_PLAN_ID
|
|
25052
|
+
];
|
|
24962
25053
|
}
|
|
24963
25054
|
function connectedNeonAddArgs(options) {
|
|
24964
|
-
|
|
24965
|
-
if (options.plan) addArgs.push("--plan", options.plan);
|
|
24966
|
-
return addArgs;
|
|
25055
|
+
return ["integration", "add", "neon", "--plan", options.plan ?? NEON_FREE_PLAN_ID];
|
|
24967
25056
|
}
|
|
24968
25057
|
|
|
24969
25058
|
// adapters/next/init/vercel/flow.ts
|
|
@@ -24980,14 +25069,28 @@ async function runVercelNeonFlow(options) {
|
|
|
24980
25069
|
p17.log.warn(authFailureMessage(auth.reason));
|
|
24981
25070
|
return { ok: false };
|
|
24982
25071
|
}
|
|
25072
|
+
const linkPreExisted = Boolean(readLinkedProjectId(options.cwd));
|
|
24983
25073
|
const linkLinePrinted = await ensureLinkedProject(runner, options.cwd, options.projectName, env);
|
|
25074
|
+
const preExistingDbUrl = linkPreExisted ? await pullPreExistingDbUrl(runner, options.cwd, env) : void 0;
|
|
24984
25075
|
const neon = await provisionNeonForMode(runner, options);
|
|
24985
25076
|
if (neon.failure) {
|
|
24986
25077
|
p17.log.warn(neonFailureMessage(neon.failure));
|
|
24987
25078
|
if (neon.detail) p17.log.message(pc6.dim(neon.detail));
|
|
24988
25079
|
return { ok: false };
|
|
24989
25080
|
}
|
|
24990
|
-
|
|
25081
|
+
if (neon.connectedToProject === false && neon.resourceName) {
|
|
25082
|
+
const connectSpinner = spinner2();
|
|
25083
|
+
connectSpinner.start("Connecting the database to your Vercel project");
|
|
25084
|
+
await replaceNeonProjectConnection(runner, options.cwd, neon.resourceName, env);
|
|
25085
|
+
connectSpinner.clear();
|
|
25086
|
+
}
|
|
25087
|
+
let databaseUrl = await pullNeonDatabaseUrl(runner, options.cwd, env);
|
|
25088
|
+
if (databaseUrl && databaseUrl === preExistingDbUrl) {
|
|
25089
|
+
databaseUrl = void 0;
|
|
25090
|
+
p17.log.warn(
|
|
25091
|
+
"The linked Vercel project still returns its previous DATABASE_URL \u2014 the new database could not be connected."
|
|
25092
|
+
);
|
|
25093
|
+
}
|
|
24991
25094
|
const dismissSignedInNote = databaseUrl && auth.dismissNote && !neon.usedTerminalFallback ? () => auth.dismissNote?.({ linesBelow: linkLinePrinted ? 1 : 0 }) : void 0;
|
|
24992
25095
|
return {
|
|
24993
25096
|
ok: true,
|
|
@@ -25083,7 +25186,7 @@ async function runVercelDeployFlow(options) {
|
|
|
25083
25186
|
);
|
|
25084
25187
|
}
|
|
25085
25188
|
const deploySpinner = spinner2();
|
|
25086
|
-
deploySpinner.start("Deploying to Vercel
|
|
25189
|
+
deploySpinner.start("Deploying to Vercel, This may take a moment");
|
|
25087
25190
|
let deploy;
|
|
25088
25191
|
try {
|
|
25089
25192
|
deploy = await deployVercelProject(runner, options.cwd, env);
|
|
@@ -25121,6 +25224,13 @@ async function ensureLinkedProject(runner, cwd, projectName, env) {
|
|
|
25121
25224
|
);
|
|
25122
25225
|
return true;
|
|
25123
25226
|
}
|
|
25227
|
+
async function pullPreExistingDbUrl(runner, cwd, env) {
|
|
25228
|
+
const snapshotSpinner = spinner2();
|
|
25229
|
+
snapshotSpinner.start("Checking the linked Vercel project");
|
|
25230
|
+
const url = await pullVercelEnvValue(runner, cwd, readDbUrlFromDotenv, env);
|
|
25231
|
+
snapshotSpinner.clear();
|
|
25232
|
+
return url;
|
|
25233
|
+
}
|
|
25124
25234
|
async function pullNeonDatabaseUrl(runner, cwd, env) {
|
|
25125
25235
|
const neonSpinner = spinner2();
|
|
25126
25236
|
neonSpinner.start("Retrieving DATABASE_URL from Vercel");
|
|
@@ -25962,7 +26072,7 @@ async function runInitCommand(name, options) {
|
|
|
25962
26072
|
}
|
|
25963
26073
|
const coreDependencyPlan = getDependencyPlan([], [], project2.linter.type === "none");
|
|
25964
26074
|
const cliDependencyPlan = getCliDependencySyncPlan(cwd);
|
|
25965
|
-
s.start("Installing dependencies
|
|
26075
|
+
s.start("Installing dependencies, This may take a moment");
|
|
25966
26076
|
const depsResult = await installDependenciesAsync({
|
|
25967
26077
|
cwd,
|
|
25968
26078
|
pm,
|