betterstart-cli 0.0.34 → 0.0.36
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 +120 -13
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1664,8 +1664,8 @@ function ensureDatabasePushDependencies(cwd, pm) {
|
|
|
1664
1664
|
Installing database push dependencies (${missing.map((dependency) => dependency.name).join(", ")})...`
|
|
1665
1665
|
);
|
|
1666
1666
|
for (const dependency of missing) {
|
|
1667
|
-
const
|
|
1668
|
-
if (!
|
|
1667
|
+
const installed2 = installDependency(cwd, pm, dependency.name, dependency.dev);
|
|
1668
|
+
if (!installed2) {
|
|
1669
1669
|
console.log(` Failed to install ${dependency.name}`);
|
|
1670
1670
|
return false;
|
|
1671
1671
|
}
|
|
@@ -3460,7 +3460,7 @@ function schemaManifestContainsMailchimpImports(cwd, config, schemaName) {
|
|
|
3460
3460
|
return false;
|
|
3461
3461
|
}
|
|
3462
3462
|
const content = fs14.readFileSync(fullPath, "utf-8");
|
|
3463
|
-
return markers.some((
|
|
3463
|
+
return markers.some((marker2) => content.includes(marker2));
|
|
3464
3464
|
});
|
|
3465
3465
|
}
|
|
3466
3466
|
function findBlockingIntegrationDependencies(cwd, config, integrationId) {
|
|
@@ -3605,7 +3605,7 @@ async function installIntegrations({
|
|
|
3605
3605
|
const orderedIntegrationIds = resolveIntegrationInstallOrder(integrationIds);
|
|
3606
3606
|
const installedIntegrationIds = normalizeInstalledIntegrations(config);
|
|
3607
3607
|
const skipped = [];
|
|
3608
|
-
const
|
|
3608
|
+
const installed2 = [];
|
|
3609
3609
|
const activated = [];
|
|
3610
3610
|
const warnings = [];
|
|
3611
3611
|
for (const integrationId of orderedIntegrationIds) {
|
|
@@ -3704,7 +3704,7 @@ async function installIntegrations({
|
|
|
3704
3704
|
});
|
|
3705
3705
|
saveInstalledIntegrationManifest(cwd, manifest);
|
|
3706
3706
|
writeConfigFile(cwd, config);
|
|
3707
|
-
|
|
3707
|
+
installed2.push(integrationId);
|
|
3708
3708
|
if (!configureResult.configured && isProviderIntegration(definition)) {
|
|
3709
3709
|
warnings.push(
|
|
3710
3710
|
`${integrationId} was installed but not activated because its required environment variables are still missing.`
|
|
@@ -3712,7 +3712,7 @@ async function installIntegrations({
|
|
|
3712
3712
|
}
|
|
3713
3713
|
}
|
|
3714
3714
|
return {
|
|
3715
|
-
installed,
|
|
3715
|
+
installed: installed2,
|
|
3716
3716
|
activated,
|
|
3717
3717
|
skipped,
|
|
3718
3718
|
warnings,
|
|
@@ -18727,7 +18727,7 @@ async function installPlugins({
|
|
|
18727
18727
|
const orderedPluginIds = resolvePluginInstallOrder(pluginIds);
|
|
18728
18728
|
const installedPluginIds = normalizeInstalledPlugins(config);
|
|
18729
18729
|
const skipped = [];
|
|
18730
|
-
const
|
|
18730
|
+
const installed2 = [];
|
|
18731
18731
|
const warnings = [];
|
|
18732
18732
|
ensureSnapshotGitFiles(cwd);
|
|
18733
18733
|
for (const pluginId of orderedPluginIds) {
|
|
@@ -18796,10 +18796,10 @@ async function installPlugins({
|
|
|
18796
18796
|
};
|
|
18797
18797
|
saveInstalledPluginManifest(cwd, manifest);
|
|
18798
18798
|
writeConfigFile(cwd, config);
|
|
18799
|
-
|
|
18799
|
+
installed2.push(pluginId);
|
|
18800
18800
|
}
|
|
18801
18801
|
return {
|
|
18802
|
-
installed,
|
|
18802
|
+
installed: installed2,
|
|
18803
18803
|
skipped,
|
|
18804
18804
|
warnings,
|
|
18805
18805
|
config
|
|
@@ -21828,6 +21828,89 @@ import fs39 from "fs";
|
|
|
21828
21828
|
import path50 from "path";
|
|
21829
21829
|
import * as p17 from "@clack/prompts";
|
|
21830
21830
|
|
|
21831
|
+
// core-engine/utils/prompt-theme.ts
|
|
21832
|
+
var GREEN_STEP_SUBMIT = "\x1B[32m\u25C7\x1B[39m";
|
|
21833
|
+
var GREEN_CHECK = "\x1B[32m\u2713\x1B[39m";
|
|
21834
|
+
function restyleStepSubmitSymbols(text7) {
|
|
21835
|
+
return text7.split(GREEN_STEP_SUBMIT).join(GREEN_CHECK);
|
|
21836
|
+
}
|
|
21837
|
+
var ROW_ESCAPES = /\u001B\[(\d*)([ABEF])/g;
|
|
21838
|
+
function rowDelta(text7) {
|
|
21839
|
+
let delta = text7.split("\n").length - 1;
|
|
21840
|
+
for (const match of text7.matchAll(ROW_ESCAPES)) {
|
|
21841
|
+
const n = match[1] === "" ? 1 : Number(match[1]);
|
|
21842
|
+
delta += match[2] === "A" || match[2] === "F" ? -n : n;
|
|
21843
|
+
}
|
|
21844
|
+
return delta;
|
|
21845
|
+
}
|
|
21846
|
+
var installed = false;
|
|
21847
|
+
var armed = false;
|
|
21848
|
+
var marker = null;
|
|
21849
|
+
var generation = 0;
|
|
21850
|
+
var rawStdoutWrite;
|
|
21851
|
+
function installPromptCheckmarks() {
|
|
21852
|
+
if (installed || !process.stdout.isTTY || process.env.CI === "true") return () => {
|
|
21853
|
+
};
|
|
21854
|
+
installed = true;
|
|
21855
|
+
const unpatchedOut = process.stdout.write;
|
|
21856
|
+
const unpatchedErr = process.stderr.write;
|
|
21857
|
+
const writeOut = unpatchedOut.bind(process.stdout);
|
|
21858
|
+
const writeErr = unpatchedErr.bind(process.stderr);
|
|
21859
|
+
rawStdoutWrite = writeOut;
|
|
21860
|
+
process.stdout.write = ((chunk, encoding, callback) => {
|
|
21861
|
+
if (typeof chunk !== "string") return writeOut(chunk, encoding, callback);
|
|
21862
|
+
const idx = armed ? chunk.indexOf(GREEN_STEP_SUBMIT) : -1;
|
|
21863
|
+
if (idx === -1) {
|
|
21864
|
+
if (marker) marker.rowsAbove += rowDelta(chunk);
|
|
21865
|
+
return writeOut(restyleStepSubmitSymbols(chunk), encoding, callback);
|
|
21866
|
+
}
|
|
21867
|
+
armed = false;
|
|
21868
|
+
const rest = chunk.slice(idx + GREEN_STEP_SUBMIT.length);
|
|
21869
|
+
marker = { rowsAbove: rowDelta(rest) };
|
|
21870
|
+
return writeOut(
|
|
21871
|
+
restyleStepSubmitSymbols(chunk.slice(0, idx)) + GREEN_STEP_SUBMIT + restyleStepSubmitSymbols(rest),
|
|
21872
|
+
encoding,
|
|
21873
|
+
callback
|
|
21874
|
+
);
|
|
21875
|
+
});
|
|
21876
|
+
process.stderr.write = ((chunk, encoding, callback) => {
|
|
21877
|
+
if (typeof chunk === "string" && marker) marker.rowsAbove += rowDelta(chunk);
|
|
21878
|
+
return writeErr(chunk, encoding, callback);
|
|
21879
|
+
});
|
|
21880
|
+
return () => {
|
|
21881
|
+
process.stdout.write = unpatchedOut;
|
|
21882
|
+
process.stderr.write = unpatchedErr;
|
|
21883
|
+
rawStdoutWrite = void 0;
|
|
21884
|
+
installed = false;
|
|
21885
|
+
armed = false;
|
|
21886
|
+
marker = null;
|
|
21887
|
+
};
|
|
21888
|
+
}
|
|
21889
|
+
function deferNextPromptCheck() {
|
|
21890
|
+
if (!installed) return { confirm() {
|
|
21891
|
+
}, skip() {
|
|
21892
|
+
} };
|
|
21893
|
+
generation += 1;
|
|
21894
|
+
const token = generation;
|
|
21895
|
+
armed = true;
|
|
21896
|
+
marker = null;
|
|
21897
|
+
return {
|
|
21898
|
+
confirm() {
|
|
21899
|
+
if (token !== generation) return;
|
|
21900
|
+
armed = false;
|
|
21901
|
+
const rows = marker?.rowsAbove;
|
|
21902
|
+
marker = null;
|
|
21903
|
+
if (rows === void 0 || rows <= 0 || rows >= (process.stdout.rows ?? 24)) return;
|
|
21904
|
+
rawStdoutWrite?.(`\x1B[${rows}A\r${GREEN_CHECK}\x1B[${rows}B\r`);
|
|
21905
|
+
},
|
|
21906
|
+
skip() {
|
|
21907
|
+
if (token !== generation) return;
|
|
21908
|
+
armed = false;
|
|
21909
|
+
marker = null;
|
|
21910
|
+
}
|
|
21911
|
+
};
|
|
21912
|
+
}
|
|
21913
|
+
|
|
21831
21914
|
// adapters/next/init/prompts/database.ts
|
|
21832
21915
|
import { execFileSync as execFileSync4 } from "child_process";
|
|
21833
21916
|
import * as p10 from "@clack/prompts";
|
|
@@ -22076,6 +22159,7 @@ async function promptPlugins(cwd, options = {}) {
|
|
|
22076
22159
|
overwriteKeys.add(key);
|
|
22077
22160
|
}
|
|
22078
22161
|
};
|
|
22162
|
+
const storageStep = deferNextPromptCheck();
|
|
22079
22163
|
const storage = await p11.select({
|
|
22080
22164
|
message: "Choose a file storage",
|
|
22081
22165
|
options: [
|
|
@@ -22101,6 +22185,7 @@ async function promptPlugins(cwd, options = {}) {
|
|
|
22101
22185
|
}
|
|
22102
22186
|
if (storage === "r2") {
|
|
22103
22187
|
mergeIntegrationConfig(await collectIntegrationConfig(cwd, ["r2"]));
|
|
22188
|
+
storageStep.confirm();
|
|
22104
22189
|
} else if (storage === "vercel-blob") {
|
|
22105
22190
|
const existingToken = readEnvVar(cwd, "BLOB_READ_WRITE_TOKEN")?.trim();
|
|
22106
22191
|
const flow = !existingToken && options.provisionVercelBlob ? await options.provisionVercelBlob() : void 0;
|
|
@@ -22112,6 +22197,8 @@ async function promptPlugins(cwd, options = {}) {
|
|
|
22112
22197
|
vars: [{ key: "BLOB_READ_WRITE_TOKEN", value: flow.token }]
|
|
22113
22198
|
});
|
|
22114
22199
|
overwriteKeys.add("BLOB_READ_WRITE_TOKEN");
|
|
22200
|
+
if (flow.usedTerminalFallback) storageStep.skip();
|
|
22201
|
+
else storageStep.confirm();
|
|
22115
22202
|
} else {
|
|
22116
22203
|
if (existingToken) {
|
|
22117
22204
|
p11.log.info("Using the existing Vercel Blob token from .env.local");
|
|
@@ -22119,7 +22206,11 @@ async function promptPlugins(cwd, options = {}) {
|
|
|
22119
22206
|
p11.log.info("Falling back to a manual Vercel Blob token.");
|
|
22120
22207
|
}
|
|
22121
22208
|
mergeIntegrationConfig(await collectIntegrationConfig(cwd, ["vercel-blob"]));
|
|
22209
|
+
if (flow) storageStep.skip();
|
|
22210
|
+
else storageStep.confirm();
|
|
22122
22211
|
}
|
|
22212
|
+
} else {
|
|
22213
|
+
storageStep.confirm();
|
|
22123
22214
|
}
|
|
22124
22215
|
const selectedPlugins = await p11.multiselect({
|
|
22125
22216
|
message: "Select presets",
|
|
@@ -24468,7 +24559,7 @@ async function provisionBlobStoreInteractive(runner, cwd, options) {
|
|
|
24468
24559
|
return { storeName: quiet.storeName, failure: "env-pull-empty" };
|
|
24469
24560
|
}
|
|
24470
24561
|
pullSpinner.clear();
|
|
24471
|
-
return { token, storeName: quiet.storeName };
|
|
24562
|
+
return { token, storeName: quiet.storeName, usedTerminalFallback: true };
|
|
24472
24563
|
}
|
|
24473
24564
|
async function provisionBlobStore(runner, cwd, options) {
|
|
24474
24565
|
const provisionSpinner = spinner2();
|
|
@@ -24845,7 +24936,8 @@ async function runVercelBlobFlow(options) {
|
|
|
24845
24936
|
return {
|
|
24846
24937
|
ok: true,
|
|
24847
24938
|
token: blob.token,
|
|
24848
|
-
blobStoreName: blob.storeName
|
|
24939
|
+
blobStoreName: blob.storeName,
|
|
24940
|
+
usedTerminalFallback: blob.usedTerminalFallback
|
|
24849
24941
|
};
|
|
24850
24942
|
} catch (error) {
|
|
24851
24943
|
p16.log.warn(
|
|
@@ -24881,7 +24973,9 @@ async function runVercelDeployFlow(options) {
|
|
|
24881
24973
|
} else {
|
|
24882
24974
|
envSpinner.clear();
|
|
24883
24975
|
}
|
|
24976
|
+
let printedWarnings = false;
|
|
24884
24977
|
for (const key of sync.failed) {
|
|
24978
|
+
printedWarnings = true;
|
|
24885
24979
|
p16.log.warn(
|
|
24886
24980
|
`Could not set ${pc6.cyan(key)} on Vercel \u2014 add it in the project's environment settings.`
|
|
24887
24981
|
);
|
|
@@ -24891,6 +24985,7 @@ async function runVercelDeployFlow(options) {
|
|
|
24891
24985
|
}
|
|
24892
24986
|
const packageGuard = guardProjectForDeploy(options.cwd);
|
|
24893
24987
|
for (const dep of packageGuard.localSpecDeps) {
|
|
24988
|
+
printedWarnings = true;
|
|
24894
24989
|
p16.log.warn(
|
|
24895
24990
|
`Dependency ${pc6.cyan(dep)} uses a local spec that cannot install on Vercel \u2014 the remote build may fail.`
|
|
24896
24991
|
);
|
|
@@ -24912,7 +25007,7 @@ async function runVercelDeployFlow(options) {
|
|
|
24912
25007
|
const linkedName = readLinkedProjectName(options.cwd);
|
|
24913
25008
|
const url = linkedName ? `https://${linkedName}.vercel.app` : deploy.url;
|
|
24914
25009
|
deploySpinner.stop(url ? `Deployed ${pc6.cyan(url)}` : "Deployed to Vercel");
|
|
24915
|
-
return { ok: true, url, syncedEnvKeys: sync.synced };
|
|
25010
|
+
return { ok: true, url, syncedEnvKeys: sync.synced, cleanScreen: !printedWarnings };
|
|
24916
25011
|
} catch (error) {
|
|
24917
25012
|
p16.log.warn(`Vercel deploy failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
24918
25013
|
printManualDeployHint();
|
|
@@ -25387,6 +25482,7 @@ function removeExistingAdminPaths(cwd, namespaces) {
|
|
|
25387
25482
|
return removed;
|
|
25388
25483
|
}
|
|
25389
25484
|
async function runInitCommand(name, options) {
|
|
25485
|
+
installPromptCheckmarks();
|
|
25390
25486
|
p17.box(
|
|
25391
25487
|
`
|
|
25392
25488
|
\u2584 \u2597 \u2597 \u2584\u2596\u2597 \u2597
|
|
@@ -25613,6 +25709,7 @@ async function runInitCommand(name, options) {
|
|
|
25613
25709
|
p17.log.info(`Using existing database URL from .env.local ${pc7.dim(`(${masked})`)}`);
|
|
25614
25710
|
databaseUrl = existingDbUrl;
|
|
25615
25711
|
} else {
|
|
25712
|
+
const databaseStep = deferNextPromptCheck();
|
|
25616
25713
|
const servicesResult = await promptServices({ allowVercel: options.vercel !== false });
|
|
25617
25714
|
if (servicesResult.provider === "vercel-cli") {
|
|
25618
25715
|
const flow = await runVercelNeonFlow({
|
|
@@ -25626,17 +25723,22 @@ async function runInitCommand(name, options) {
|
|
|
25626
25723
|
databaseUrl = flow.databaseUrl;
|
|
25627
25724
|
persistDatabaseUrl(cwd, databaseUrl);
|
|
25628
25725
|
dismissVercelSignedInNote = flow.dismissSignedInNote;
|
|
25726
|
+
if (flow.dismissSignedInNote) databaseStep.confirm();
|
|
25727
|
+
else databaseStep.skip();
|
|
25629
25728
|
} else if (flow.ok) {
|
|
25729
|
+
databaseStep.skip();
|
|
25630
25730
|
openBrowserVercelNeonResource(flow.dashboardUrl ?? flow.resourceUrl);
|
|
25631
25731
|
databaseUrl = await promptConnectionString();
|
|
25632
25732
|
persistDatabaseUrl(cwd, databaseUrl);
|
|
25633
25733
|
} else {
|
|
25734
|
+
databaseStep.skip();
|
|
25634
25735
|
p17.log.info("Falling back to a manual database connection string.");
|
|
25635
25736
|
openBrowserVercelNeon();
|
|
25636
25737
|
databaseUrl = await promptConnectionString();
|
|
25637
25738
|
}
|
|
25638
25739
|
} else {
|
|
25639
25740
|
databaseUrl = servicesResult.url;
|
|
25741
|
+
databaseStep.confirm();
|
|
25640
25742
|
}
|
|
25641
25743
|
}
|
|
25642
25744
|
const selectedPlugins = (() => {
|
|
@@ -26152,12 +26254,17 @@ Run manually: ${pc7.cyan(betterstartExecCommand(pm, "seed"))}`,
|
|
|
26152
26254
|
if (options.vercel !== false && !options.skipDeploy) {
|
|
26153
26255
|
const linkedVercelProject = Boolean(readLinkedProjectId(cwd));
|
|
26154
26256
|
if (!options.yes) {
|
|
26257
|
+
const deployStep = deferNextPromptCheck();
|
|
26155
26258
|
const deployNow = await p17.confirm({
|
|
26156
26259
|
message: "Deploy to Vercel now?",
|
|
26157
26260
|
initialValue: linkedVercelProject
|
|
26158
26261
|
});
|
|
26159
26262
|
if (!p17.isCancel(deployNow) && deployNow) {
|
|
26160
|
-
await runVercelDeployFlow({ cwd, projectName, env: process.env });
|
|
26263
|
+
const deployFlow = await runVercelDeployFlow({ cwd, projectName, env: process.env });
|
|
26264
|
+
if (deployFlow.ok && deployFlow.cleanScreen) deployStep.confirm();
|
|
26265
|
+
else deployStep.skip();
|
|
26266
|
+
} else {
|
|
26267
|
+
deployStep.confirm();
|
|
26161
26268
|
}
|
|
26162
26269
|
} else if (linkedVercelProject && process.env.VERCEL_TOKEN) {
|
|
26163
26270
|
const deployFlow = await runVercelDeployFlow({
|