create-tina-app 2.1.6 → 2.1.7

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/index.js CHANGED
@@ -9,6 +9,19 @@ import path from "path";
9
9
 
10
10
  // src/util/textstyles.ts
11
11
  import chalk from "chalk";
12
+ var stripAnsi = (str) => str.replace(/\]8;;[^]*/g, "").replace(/\[[0-9;]*m/g, "");
13
+ var box = (lines, color = chalk.hex("#EC4816")) => {
14
+ const pad = 1;
15
+ const width = Math.max(...lines.map((l) => stripAnsi(l).length));
16
+ const rule = color("\u2500".repeat(width + pad * 2));
17
+ const top = `${color("\u250C")}${rule}${color("\u2510")}`;
18
+ const bottom = `${color("\u2514")}${rule}${color("\u2518")}`;
19
+ const body = lines.map((line) => {
20
+ const trailing = " ".repeat(width - stripAnsi(line).length);
21
+ return `${color("\u2502")}${" ".repeat(pad)}${line}${trailing}${" ".repeat(pad)}${color("\u2502")}`;
22
+ });
23
+ return [top, ...body, bottom].join("\n");
24
+ };
12
25
  var TextStyles = {
13
26
  tinaOrange: chalk.hex("#EC4816"),
14
27
  link: (url) => `\x1B]8;;${url}\x07${chalk.cyan.underline(url)}\x1B]8;;\x07`,
@@ -143,18 +156,36 @@ async function updateTelemetryConfig(dir, mode) {
143
156
 
144
157
  // src/util/install.ts
145
158
  import spawn from "cross-spawn";
159
+ var MAX_OUTPUT_CHARS = 4e3;
146
160
  function install(packageManager, verboseOutput) {
161
+ const command = `${packageManager} install`;
147
162
  return new Promise((resolve, reject) => {
148
163
  const child = spawn(packageManager, ["install"], {
149
- stdio: verboseOutput ? "inherit" : "ignore",
164
+ stdio: verboseOutput ? "inherit" : ["ignore", "ignore", "pipe"],
150
165
  env: { ...process.env, ADBLOCK: "1", DISABLE_OPENCOLLECTIVE: "1" }
151
166
  });
167
+ let captured = "";
168
+ child.stderr?.on("data", (chunk) => {
169
+ captured = (captured + chunk.toString()).slice(-MAX_OUTPUT_CHARS);
170
+ });
171
+ child.on("error", (err) => {
172
+ reject(
173
+ new Error(`Failed to run "${command}": ${err.message}`)
174
+ );
175
+ });
152
176
  child.on("close", (code) => {
153
- if (code !== 0) {
154
- reject({ command: `${packageManager} install` });
177
+ if (code === 0) {
178
+ resolve();
155
179
  return;
156
180
  }
157
- resolve();
181
+ const details = captured.trim();
182
+ let message = `"${command}" exited with code ${code ?? "unknown"}.`;
183
+ if (details) {
184
+ message += `
185
+
186
+ ${details}`;
187
+ }
188
+ reject(new Error(message));
158
189
  });
159
190
  });
160
191
  }
@@ -422,18 +453,31 @@ async function downloadTemplate(template, root, spinner) {
422
453
  }
423
454
 
424
455
  // src/util/preRunChecks.ts
425
- var SUPPORTED_NODE_VERSION_BOUNDS = { oldest: 20, latest: 22 };
426
- var SUPPORTED_NODE_VERSION_RANGE = [
427
- ...Array(SUPPORTED_NODE_VERSION_BOUNDS.latest).keys()
428
- ].map((i) => i + SUPPORTED_NODE_VERSION_BOUNDS.oldest);
429
- var isSupported = SUPPORTED_NODE_VERSION_RANGE.some(
430
- (version2) => process.version.startsWith(`v${version2}`)
431
- );
456
+ import { readFileSync } from "node:fs";
457
+ import { dirname, join } from "node:path";
458
+ import { fileURLToPath } from "node:url";
459
+ function getSupportedMajors() {
460
+ const here = dirname(fileURLToPath(import.meta.url));
461
+ try {
462
+ const { engines } = JSON.parse(
463
+ readFileSync(join(here, "../package.json"), "utf8")
464
+ );
465
+ return [...String(engines?.node ?? "").matchAll(/(\d+)\.x/g)].map(
466
+ (m) => Number(m[1])
467
+ );
468
+ } catch {
469
+ return [];
470
+ }
471
+ }
432
472
  function preRunChecks(spinner) {
433
473
  spinner.start("Running pre-run checks...");
474
+ const supported = getSupportedMajors();
475
+ const currentMajor = Number(process.versions.node.split(".")[0]);
476
+ const isSupported = supported.includes(currentMajor);
434
477
  if (!isSupported) {
478
+ const range = supported.length ? supported.map((v) => `v${v}`).join(" or ") : "a supported LTS version";
435
479
  spinner.warn(
436
- `Node ${process.version} is not supported by create-tina-app. Please update to be within v${SUPPORTED_NODE_VERSION_BOUNDS.oldest}-v${SUPPORTED_NODE_VERSION_BOUNDS.latest}. See https://nodejs.org/en/download/ for more details.`
480
+ `Node ${process.version} is not supported by create-tina-app. Please use ${range}. See https://nodejs.org/en/download/ for more details.`
437
481
  );
438
482
  } else {
439
483
  spinner.succeed(`Node ${process.version} is supported.`);
@@ -466,7 +510,7 @@ import { Command } from "commander";
466
510
 
467
511
  // package.json
468
512
  var name = "create-tina-app";
469
- var version = "2.1.6";
513
+ var version = "2.1.7";
470
514
 
471
515
  // src/util/packageManagers.ts
472
516
  var PKG_MANAGERS = ["npm", "yarn", "pnpm", "bun"];
@@ -881,6 +925,7 @@ async function fetchPostHogConfig(endpointUrl) {
881
925
  // src/index.ts
882
926
  import { osInfo as getOsSystemInfo } from "systeminformation";
883
927
  var DISCORD_SUPPORT_URL = "https://discord.com/invite/zumN63Ybpf";
928
+ var FAQ_URL = "https://tina.io/docs/faq";
884
929
  var posthogClient = null;
885
930
  async function initializePostHog(configEndpoint, disableGeoip) {
886
931
  let apiKey;
@@ -1231,8 +1276,17 @@ Need more help? Reach out to the TinaCMS community at ${TextStyles.link(
1231
1276
  await install(pkgManager, opts.verbose);
1232
1277
  spinner.succeed();
1233
1278
  } catch (err) {
1234
- const error = err;
1235
- spinner.fail(`Failed to install packages: ${error.message}`);
1279
+ const error = err instanceof Error ? err : new Error(String(err));
1280
+ const reason = error.message || String(err);
1281
+ spinner.fail(`Failed to install packages: ${reason}`);
1282
+ console.log(
1283
+ `
1284
+ ${box([
1285
+ `${TextStyles.bold("Stuck?")} Check the TinaCMS FAQ for common install issues:`,
1286
+ TextStyles.link(FAQ_URL)
1287
+ ])}
1288
+ `
1289
+ );
1236
1290
  packageManagerInstallationHadError = true;
1237
1291
  postHogCaptureError(posthogClient, userId, sessionId, error, {
1238
1292
  errorCode: ERROR_CODES.ERR_INSTALL_PKG_MANAGER_FAILED,
@@ -3,5 +3,7 @@ import { PackageManager } from './packageManagers';
3
3
  * Spawn a package manager installation.
4
4
  *
5
5
  * @returns A Promise that resolves once the installation is finished.
6
+ * On failure it rejects with an `Error` whose message includes the command,
7
+ * the exit code, and the tail of the captured output.
6
8
  */
7
9
  export declare function install(packageManager: PackageManager, verboseOutput: boolean): Promise<void>;
@@ -1,3 +1,8 @@
1
+ /**
2
+ * Draw a bordered box around one or more lines so a message stands out from the
3
+ * surrounding log output.
4
+ */
5
+ export declare const box: (lines: string[], color?: (s: string) => string) => string;
1
6
  export declare const TextStyles: {
2
7
  tinaOrange: import("chalk").ChalkInstance;
3
8
  link: (url: string) => string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-tina-app",
3
- "version": "2.1.6",
3
+ "version": "2.1.7",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "files": [
@@ -20,7 +20,7 @@
20
20
  ]
21
21
  },
22
22
  "engines": {
23
- "node": ">=18.18.0"
23
+ "node": "22.x || 24.x"
24
24
  },
25
25
  "publishConfig": {
26
26
  "registry": "https://registry.npmjs.org"