betterstart-cli 0.0.49 → 0.0.51

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 CHANGED
@@ -21840,7 +21840,7 @@ ${validationErrors.map((error) => ` - ${error}`).join("\n")}`
21840
21840
  }
21841
21841
 
21842
21842
  // adapters/next/commands/init.ts
21843
- import { execFileSync as execFileSync5, spawn as spawn4 } from "child_process";
21843
+ import { execFileSync as execFileSync5, spawn as spawn5 } from "child_process";
21844
21844
  import fs39 from "fs";
21845
21845
  import path50 from "path";
21846
21846
  import * as p18 from "@clack/prompts";
@@ -24406,23 +24406,27 @@ function versionedVercelProjectName(base, attempt) {
24406
24406
  const suffix = `-v${attempt}`;
24407
24407
  return `${base.slice(0, 100 - suffix.length)}${suffix}`;
24408
24408
  }
24409
- async function createVercelProject(runner, cwd, name, env) {
24409
+ async function createVercelProject(runner, cwd, name, options = {}) {
24410
24410
  const base = sanitizeVercelProjectName(name);
24411
24411
  let projectName = base;
24412
24412
  for (let attempt = 1; attempt <= MAX_NAME_ATTEMPTS; attempt++) {
24413
24413
  const candidate = versionedVercelProjectName(base, attempt);
24414
24414
  projectName = candidate;
24415
- const inspect = await runVercel(runner, ["project", "inspect", candidate], {
24416
- cwd,
24417
- mode: "capture",
24418
- timeoutMs: INSPECT_TIMEOUT_MS,
24419
- env
24420
- });
24415
+ const inspect = await runVercel(
24416
+ runner,
24417
+ withScope(["project", "inspect", candidate], options.scope),
24418
+ {
24419
+ cwd,
24420
+ mode: "capture",
24421
+ timeoutMs: INSPECT_TIMEOUT_MS,
24422
+ env: options.env
24423
+ }
24424
+ );
24421
24425
  if (inspect.success) continue;
24422
- const add = await runVercel(runner, ["projects", "add", candidate], {
24426
+ const add = await runVercel(runner, withScope(["projects", "add", candidate], options.scope), {
24423
24427
  cwd,
24424
24428
  mode: "capture",
24425
- env
24429
+ env: options.env
24426
24430
  });
24427
24431
  if (add.success) break;
24428
24432
  if (/already exists/i.test(`${add.stdout}
@@ -24433,17 +24437,24 @@ ${add.stderr}`)) continue;
24433
24437
  fs35.rmSync(path46.join(cwd, ".vercel", "project.json"), { force: true });
24434
24438
  } catch {
24435
24439
  }
24436
- const link = await runVercel(runner, ["link", "--project", projectName, "--yes"], {
24437
- cwd,
24438
- mode: "capture",
24439
- env
24440
- });
24440
+ const link = await runVercel(
24441
+ runner,
24442
+ withScope(["link", "--project", projectName, "--yes"], options.scope),
24443
+ {
24444
+ cwd,
24445
+ mode: "capture",
24446
+ env: options.env
24447
+ }
24448
+ );
24441
24449
  return {
24442
24450
  name: projectName,
24443
24451
  linked: link.success,
24444
24452
  projectId: readLinkedProjectId(cwd)
24445
24453
  };
24446
24454
  }
24455
+ function withScope(args, scope) {
24456
+ return scope ? [...args, "--scope", scope] : args;
24457
+ }
24447
24458
  function readLinkedProjectId(cwd) {
24448
24459
  return readLinkedProjectJson(cwd)?.projectId;
24449
24460
  }
@@ -24620,6 +24631,7 @@ function readBlobTokenFromDotenv(filePath) {
24620
24631
  }
24621
24632
 
24622
24633
  // adapters/next/init/vercel/deploy.ts
24634
+ import { spawn as spawn4 } from "child_process";
24623
24635
  import fs36 from "fs";
24624
24636
  import path47 from "path";
24625
24637
  import { stripVTControlCharacters as stripVTControlCharacters3 } from "util";
@@ -24672,12 +24684,14 @@ async function syncVercelProductionEnv(runner, cwd, env) {
24672
24684
  var LOCAL_PROTOCOL_PATTERN = /^(workspace|link|file|portal):/;
24673
24685
  var ADMIN_CONFIG_IMPORT_PATTERN = /^import\s+\{[^}]*\bdefineConfig\b[^}]*\}\s+from\s+['"]betterstart-cli['"];?[^\S\n]*$/m;
24674
24686
  var ADMIN_CONFIG_IMPORT_SHIM = "const defineConfig = <T>(config: T): T => config";
24675
- function guardProjectForDeploy(cwd) {
24687
+ async function guardProjectForDeploy(cwd, refreshLockfile = runPnpmLockfileOnly) {
24676
24688
  const restores = [];
24677
- const localSpecDeps = guardPackageJson(cwd, restores);
24689
+ const { localSpecDeps, removedCliDep } = guardPackageJson(cwd, restores);
24678
24690
  guardAdminConfig(cwd, restores);
24691
+ const lockfile = removedCliDep ? await guardPnpmLockfile(cwd, restores, refreshLockfile) : "not-needed";
24679
24692
  return {
24680
24693
  localSpecDeps,
24694
+ lockfile,
24681
24695
  restore() {
24682
24696
  for (const restoreFile2 of restores) {
24683
24697
  try {
@@ -24691,14 +24705,14 @@ function guardProjectForDeploy(cwd) {
24691
24705
  function guardPackageJson(cwd, restores) {
24692
24706
  const packageJsonPath = path47.join(cwd, "package.json");
24693
24707
  if (!fs36.existsSync(packageJsonPath)) {
24694
- return [];
24708
+ return { localSpecDeps: [], removedCliDep: false };
24695
24709
  }
24696
24710
  const original = fs36.readFileSync(packageJsonPath, "utf-8");
24697
24711
  let parsed;
24698
24712
  try {
24699
24713
  parsed = JSON.parse(original);
24700
24714
  } catch {
24701
- return [];
24715
+ return { localSpecDeps: [], removedCliDep: false };
24702
24716
  }
24703
24717
  const localSpecDeps = [];
24704
24718
  let removed = false;
@@ -24721,7 +24735,34 @@ function guardPackageJson(cwd, restores) {
24721
24735
  `, "utf-8");
24722
24736
  restores.push(() => fs36.writeFileSync(packageJsonPath, original, "utf-8"));
24723
24737
  }
24724
- return localSpecDeps;
24738
+ return { localSpecDeps, removedCliDep: removed };
24739
+ }
24740
+ async function guardPnpmLockfile(cwd, restores, refreshLockfile) {
24741
+ const lockfilePath = path47.join(cwd, "pnpm-lock.yaml");
24742
+ if (!fs36.existsSync(lockfilePath)) {
24743
+ return "not-needed";
24744
+ }
24745
+ const original = fs36.readFileSync(lockfilePath, "utf-8");
24746
+ restores.push(() => fs36.writeFileSync(lockfilePath, original, "utf-8"));
24747
+ return await refreshLockfile(cwd) ? "updated" : "failed";
24748
+ }
24749
+ var LOCKFILE_REFRESH_TIMEOUT_MS = 12e4;
24750
+ function runPnpmLockfileOnly(cwd) {
24751
+ return new Promise((resolve) => {
24752
+ const child = spawn4("pnpm", ["install", "--lockfile-only"], { cwd, stdio: "ignore" });
24753
+ const timer = setTimeout(() => {
24754
+ child.kill("SIGKILL");
24755
+ resolve(false);
24756
+ }, LOCKFILE_REFRESH_TIMEOUT_MS);
24757
+ child.on("close", (code) => {
24758
+ clearTimeout(timer);
24759
+ resolve(code === 0);
24760
+ });
24761
+ child.on("error", () => {
24762
+ clearTimeout(timer);
24763
+ resolve(false);
24764
+ });
24765
+ });
24725
24766
  }
24726
24767
  function guardAdminConfig(cwd, restores) {
24727
24768
  const adminConfigPath = path47.join(cwd, "admin.config.ts");
@@ -24908,7 +24949,7 @@ async function runVercelNeonFlow(options) {
24908
24949
  p17.log.warn(authFailureMessage(auth.reason));
24909
24950
  return { ok: false };
24910
24951
  }
24911
- await ensureLinkedProject(runner, options.cwd, options.projectName, env);
24952
+ await ensureLinkedProject(runner, options.cwd, options.projectName, env, auth.username);
24912
24953
  const neon = await provisionNeonForMode(runner, options);
24913
24954
  if (neon.failure) {
24914
24955
  p17.log.warn(neonFailureMessage(neon.failure));
@@ -24946,7 +24987,7 @@ async function runVercelBlobFlow(options) {
24946
24987
  p17.log.warn(authFailureMessage(auth.reason));
24947
24988
  return { ok: false };
24948
24989
  }
24949
- await ensureLinkedProject(runner, options.cwd, options.projectName, env);
24990
+ await ensureLinkedProject(runner, options.cwd, options.projectName, env, auth.username);
24950
24991
  const blob = await provisionBlobForMode(runner, options);
24951
24992
  if (blob.failure || !blob.token) {
24952
24993
  p17.log.warn(blobFailureMessage(blob.failure));
@@ -24981,7 +25022,7 @@ async function runVercelDeployFlow(options) {
24981
25022
  printManualDeployHint();
24982
25023
  return { ok: false };
24983
25024
  }
24984
- await ensureLinkedProject(runner, options.cwd, options.projectName, env);
25025
+ await ensureLinkedProject(runner, options.cwd, options.projectName, env, auth.username);
24985
25026
  const envSpinner = spinner2();
24986
25027
  envSpinner.start("Syncing environment variables to Vercel");
24987
25028
  const sync = await syncVercelProductionEnv(runner, options.cwd, env);
@@ -24992,7 +25033,15 @@ async function runVercelDeployFlow(options) {
24992
25033
  );
24993
25034
  }
24994
25035
  ensureVercelJsonFramework(options.cwd);
24995
- const packageGuard = guardProjectForDeploy(options.cwd);
25036
+ const guardSpinner = spinner2();
25037
+ guardSpinner.start("Preparing the project for deploy");
25038
+ const packageGuard = await guardProjectForDeploy(options.cwd);
25039
+ guardSpinner.clear();
25040
+ if (packageGuard.lockfile === "failed") {
25041
+ p17.log.warn(
25042
+ "Could not refresh pnpm-lock.yaml after removing betterstart-cli \u2014 the remote install may fail."
25043
+ );
25044
+ }
24996
25045
  for (const dep of packageGuard.localSpecDeps) {
24997
25046
  p17.log.warn(
24998
25047
  `Dependency ${pc6.cyan(dep)} uses a local spec that cannot install on Vercel \u2014 the remote build may fail.`
@@ -25027,12 +25076,15 @@ async function runVercelDeployFlow(options) {
25027
25076
  function printManualDeployHint() {
25028
25077
  p17.log.info(`You can deploy manually: ${pc6.cyan("vercel deploy --prod")}`);
25029
25078
  }
25030
- async function ensureLinkedProject(runner, cwd, projectName, env) {
25079
+ async function ensureLinkedProject(runner, cwd, projectName, env, scope) {
25031
25080
  if (readLinkedProjectId(cwd)) return;
25032
25081
  const projectSpinner = spinner2();
25033
25082
  projectSpinner.start(`Creating a Vercel project ${pc6.cyan(projectName)}`);
25034
- await createVercelProject(runner, cwd, projectName, env);
25083
+ const project2 = await createVercelProject(runner, cwd, projectName, { env, scope });
25035
25084
  projectSpinner.clear();
25085
+ if (!project2.linked || !project2.projectId) {
25086
+ throw new Error(`Could not link Vercel project ${project2.name} to this directory.`);
25087
+ }
25036
25088
  }
25037
25089
  async function pullNeonDatabaseUrl(runner, cwd, env) {
25038
25090
  const neonSpinner = spinner2();
@@ -26401,7 +26453,7 @@ function runSeedScript(cwd, adminDir, authBasePath, envOverrides) {
26401
26453
  };
26402
26454
  return new Promise((resolve) => {
26403
26455
  const tsxBin = path50.join(cwd, "node_modules", ".bin", "tsx");
26404
- const child = spawn4(tsxBin, [seedPath], {
26456
+ const child = spawn5(tsxBin, [seedPath], {
26405
26457
  cwd,
26406
26458
  stdio: "pipe",
26407
26459
  env: {
@@ -26505,7 +26557,7 @@ ${stderr}`;
26505
26557
  }
26506
26558
  function runQuietCommand(bin, args, options) {
26507
26559
  return new Promise((resolve) => {
26508
- const child = spawn4(bin, args, {
26560
+ const child = spawn5(bin, args, {
26509
26561
  cwd: options.cwd,
26510
26562
  stdio: "pipe",
26511
26563
  env: {
@@ -26645,7 +26697,7 @@ function pipeManagedDevServerStream(stream, target, state) {
26645
26697
  function startManagedDevServer(cwd, devCmd, adminLoginUrl, adminCredentials) {
26646
26698
  return new Promise((resolve, reject) => {
26647
26699
  const [bin, ...args] = devCmd.split(" ");
26648
- const child = spawn4(bin, args, {
26700
+ const child = spawn5(bin, args, {
26649
26701
  cwd,
26650
26702
  stdio: ["inherit", "pipe", "pipe"]
26651
26703
  });