create-tina-app 2.1.6 → 2.1.8

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
  }
@@ -293,11 +324,7 @@ var TEMPLATES = [
293
324
  features: [
294
325
  {
295
326
  name: "Visual Editing",
296
- description: "\u274C"
297
- },
298
- {
299
- name: "ISR",
300
- description: "\u274C"
327
+ description: "\u2705"
301
328
  },
302
329
  {
303
330
  name: "SSG",
@@ -422,18 +449,31 @@ async function downloadTemplate(template, root, spinner) {
422
449
  }
423
450
 
424
451
  // 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
- );
452
+ import { readFileSync } from "node:fs";
453
+ import { dirname, join } from "node:path";
454
+ import { fileURLToPath } from "node:url";
455
+ function getSupportedMajors() {
456
+ const here = dirname(fileURLToPath(import.meta.url));
457
+ try {
458
+ const { engines } = JSON.parse(
459
+ readFileSync(join(here, "../package.json"), "utf8")
460
+ );
461
+ return [...String(engines?.node ?? "").matchAll(/(\d+)\.x/g)].map(
462
+ (m) => Number(m[1])
463
+ );
464
+ } catch {
465
+ return [];
466
+ }
467
+ }
432
468
  function preRunChecks(spinner) {
433
469
  spinner.start("Running pre-run checks...");
470
+ const supported = getSupportedMajors();
471
+ const currentMajor = Number(process.versions.node.split(".")[0]);
472
+ const isSupported = supported.includes(currentMajor);
434
473
  if (!isSupported) {
474
+ const range = supported.length ? supported.map((v) => `v${v}`).join(" or ") : "a supported LTS version";
435
475
  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.`
476
+ `Node ${process.version} is not supported by create-tina-app. Please use ${range}. See https://nodejs.org/en/download/ for more details.`
437
477
  );
438
478
  } else {
439
479
  spinner.succeed(`Node ${process.version} is supported.`);
@@ -466,10 +506,10 @@ import { Command } from "commander";
466
506
 
467
507
  // package.json
468
508
  var name = "create-tina-app";
469
- var version = "2.1.6";
509
+ var version = "2.1.8";
470
510
 
471
511
  // src/util/packageManagers.ts
472
- var PKG_MANAGERS = ["npm", "yarn", "pnpm", "bun"];
512
+ var PKG_MANAGERS = ["pnpm", "yarn", "bun", "npm"];
473
513
 
474
514
  // src/util/options.ts
475
515
  function extractOptions(args) {
@@ -881,6 +921,7 @@ async function fetchPostHogConfig(endpointUrl) {
881
921
  // src/index.ts
882
922
  import { osInfo as getOsSystemInfo } from "systeminformation";
883
923
  var DISCORD_SUPPORT_URL = "https://discord.com/invite/zumN63Ybpf";
924
+ var FAQ_URL = "https://tina.io/docs/faq";
884
925
  var posthogClient = null;
885
926
  async function initializePostHog(configEndpoint, disableGeoip) {
886
927
  let apiKey;
@@ -1037,8 +1078,12 @@ Need more help? Reach out to the TinaCMS community at ${TextStyles.link(
1037
1078
  message: "Which package manager would you like to use?",
1038
1079
  name: "packageManager",
1039
1080
  type: "select",
1081
+ initial: Math.max(0, installedPkgManagers.indexOf("pnpm")),
1040
1082
  choices: installedPkgManagers.map((manager) => {
1041
- return { title: manager, value: manager };
1083
+ return {
1084
+ title: manager === "pnpm" ? "pnpm (recommended)" : manager,
1085
+ value: manager
1086
+ };
1042
1087
  })
1043
1088
  });
1044
1089
  if (!Object.hasOwn(res, "packageManager")) {
@@ -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>;
@@ -3,5 +3,5 @@
3
3
  * To add a new supported package manager, add the usage command to this list.
4
4
  * The `PackageManager` type will be automatically updated as a result.
5
5
  */
6
- export declare const PKG_MANAGERS: readonly ["npm", "yarn", "pnpm", "bun"];
6
+ export declare const PKG_MANAGERS: readonly ["pnpm", "yarn", "bun", "npm"];
7
7
  export type PackageManager = (typeof PKG_MANAGERS)[number];
@@ -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.8",
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"