@tinacms/cli 0.0.0-e0ddb8c-20241004065742 → 0.0.0-ea204c9-20250318044256

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
@@ -17,23 +17,28 @@ var __copyProps = (to, from, except, desc) => {
17
17
  return to;
18
18
  };
19
19
  var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
20
+ // If the importer is in node compatibility mode or this is not an ESM
21
+ // file that has been converted to a CommonJS file using a Babel-
22
+ // compatible transform (i.e. "__esModule" has not been set), then set
23
+ // "default" to the CommonJS "module.exports" for node compatibility.
20
24
  isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
21
25
  mod
22
26
  ));
23
27
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
24
28
 
25
29
  // src/index.ts
26
- var src_exports = {};
27
- __export(src_exports, {
28
- default: () => src_default
30
+ var index_exports = {};
31
+ __export(index_exports, {
32
+ default: () => index_default
29
33
  });
30
- module.exports = __toCommonJS(src_exports);
34
+ module.exports = __toCommonJS(index_exports);
31
35
  var import_clipanion8 = require("clipanion");
32
36
 
33
37
  // package.json
34
- var version = "1.6.8";
38
+ var version = "1.9.3";
35
39
 
36
40
  // src/next/commands/dev-command/index.ts
41
+ var import_async_lock = __toESM(require("async-lock"));
37
42
  var import_clipanion2 = require("clipanion");
38
43
  var import_fs_extra6 = __toESM(require("fs-extra"));
39
44
  var import_path5 = __toESM(require("path"));
@@ -57,7 +62,10 @@ function isUnicodeSupported() {
57
62
  if (process.platform !== "win32") {
58
63
  return process.env.TERM !== "linux";
59
64
  }
60
- return Boolean(process.env.CI) || Boolean(process.env.WT_SESSION) || Boolean(process.env.TERMINUS_SUBLIME) || process.env.ConEmuTask === "{cmd::Cmder}" || process.env.TERM_PROGRAM === "Terminus-Sublime" || process.env.TERM_PROGRAM === "vscode" || process.env.TERM === "xterm-256color" || process.env.TERM === "alacritty" || process.env.TERMINAL_EMULATOR === "JetBrains-JediTerm";
65
+ return Boolean(process.env.CI) || Boolean(process.env.WT_SESSION) || // Windows Terminal
66
+ Boolean(process.env.TERMINUS_SUBLIME) || // Terminus (<0.2.27)
67
+ process.env.ConEmuTask === "{cmd::Cmder}" || // ConEmu and cmder
68
+ process.env.TERM_PROGRAM === "Terminus-Sublime" || process.env.TERM_PROGRAM === "vscode" || process.env.TERM === "xterm-256color" || process.env.TERM === "alacritty" || process.env.TERMINAL_EMULATOR === "JetBrains-JediTerm";
61
69
  }
62
70
 
63
71
  // src/logger/index.ts
@@ -212,7 +220,7 @@ var ConfigManager = class {
212
220
  this.generatedCachePath = import_path.default.join(
213
221
  this.generatedFolderPath,
214
222
  ".cache",
215
- String(new Date().getTime())
223
+ String((/* @__PURE__ */ new Date()).getTime())
216
224
  );
217
225
  this.generatedGraphQLGQLPath = import_path.default.join(
218
226
  this.generatedFolderPath,
@@ -355,17 +363,22 @@ var ConfigManager = class {
355
363
  );
356
364
  }
357
365
  getTinaGraphQLVersion() {
358
- var _a, _b;
359
366
  if (this.tinaGraphQLVersionFromCLI) {
360
- return this.tinaGraphQLVersionFromCLI;
367
+ const version2 = this.tinaGraphQLVersionFromCLI.split(".");
368
+ return {
369
+ fullVersion: this.tinaGraphQLVersionFromCLI,
370
+ major: version2[0] || "x",
371
+ minor: version2[1] || "x",
372
+ patch: version2[2] || "x"
373
+ };
361
374
  }
362
375
  const generatedSchema = import_fs_extra.default.readJSONSync(this.generatedSchemaJSONPath);
363
- if (!generatedSchema || !(typeof (generatedSchema == null ? void 0 : generatedSchema.version) !== "undefined") || !(typeof ((_a = generatedSchema == null ? void 0 : generatedSchema.version) == null ? void 0 : _a.major) === "string") || !(typeof ((_b = generatedSchema == null ? void 0 : generatedSchema.version) == null ? void 0 : _b.minor) === "string")) {
376
+ if (!generatedSchema || !(typeof (generatedSchema == null ? void 0 : generatedSchema.version) !== "undefined")) {
364
377
  throw new Error(
365
378
  `Can not find Tina GraphQL version in ${this.generatedSchemaJSONPath}`
366
379
  );
367
380
  }
368
- return `${generatedSchema.version.major}.${generatedSchema.version.minor}`;
381
+ return generatedSchema.version;
369
382
  }
370
383
  printGeneratedClientFilePath() {
371
384
  if (this.isUsingTs()) {
@@ -394,6 +407,9 @@ var ConfigManager = class {
394
407
  }
395
408
  throw `No path provided to print`;
396
409
  }
410
+ /**
411
+ * Given a filepath without an extension, find the first match (eg. tsx, ts, jsx, js)
412
+ */
397
413
  async getPathWithExtension(filepath) {
398
414
  const extensions = ["tsx", "ts", "jsx", "js"];
399
415
  let result;
@@ -427,7 +443,10 @@ var ConfigManager = class {
427
443
  }
428
444
  async loadConfigFile(generatedFolderPath, configFilePath) {
429
445
  const tmpdir = import_path.default.join(import_os.default.tmpdir(), Date.now().toString());
430
- const prebuild = import_path.default.join(this.generatedFolderPath, "config.prebuild.jsx");
446
+ const preBuildConfigPath = import_path.default.join(
447
+ this.generatedFolderPath,
448
+ "config.prebuild.jsx"
449
+ );
431
450
  const outfile = import_path.default.join(tmpdir, "config.build.jsx");
432
451
  const outfile2 = import_path.default.join(tmpdir, "config.build.js");
433
452
  const tempTSConfigFile = import_path.default.join(tmpdir, "tsconfig.json");
@@ -441,7 +460,7 @@ var ConfigManager = class {
441
460
  logLevel: "silent",
442
461
  packages: "external",
443
462
  ignoreAnnotations: true,
444
- outfile: prebuild,
463
+ outfile: preBuildConfigPath,
445
464
  loader: loaders,
446
465
  metafile: true
447
466
  });
@@ -464,6 +483,7 @@ var ConfigManager = class {
464
483
  await esbuild.build({
465
484
  entryPoints: [outfile],
466
485
  bundle: true,
486
+ // Suppress warning about comparison with -0 from client module
467
487
  logLevel: "silent",
468
488
  platform: "node",
469
489
  outfile: outfile2,
@@ -481,7 +501,7 @@ var ConfigManager = class {
481
501
  import_fs_extra.default.removeSync(outfile2);
482
502
  return {
483
503
  config: result.default,
484
- prebuildPath: prebuild,
504
+ prebuildPath: preBuildConfigPath,
485
505
  watchList: flattenedList
486
506
  };
487
507
  }
@@ -570,19 +590,19 @@ var devHTML = (port) => `<!DOCTYPE html>
570
590
  window.$RefreshReg$ = () => {}
571
591
  window.$RefreshSig$ = () => (type) => type
572
592
  window.__vite_plugin_react_preamble_installed__ = true
573
- <\/script>
574
- <script type="module" src="http://localhost:${port}/@vite/client"><\/script>
593
+ </script>
594
+ <script type="module" src="http://localhost:${port}/@vite/client"></script>
575
595
  <script>
576
596
  function handleLoadError() {
577
597
  // Assets have failed to load
578
598
  document.getElementById('root').innerHTML = '${errorHTML}';
579
599
  }
580
- <\/script>
600
+ </script>
581
601
  <script
582
602
  type="module"
583
603
  src="http://localhost:${port}/src/main.tsx"
584
604
  onerror="handleLoadError()"
585
- ><\/script>
605
+ ></script>
586
606
  <body class="tina-tailwind">
587
607
  <div id="root"></div>
588
608
  </body>
@@ -619,14 +639,16 @@ var import_normalize_path2 = __toESM(require("normalize-path"));
619
639
  var import_vite = require("vite");
620
640
 
621
641
  // src/next/vite/tailwind.ts
642
+ var import_node_path = __toESM(require("path"));
643
+ var import_aspect_ratio = __toESM(require("@tailwindcss/aspect-ratio"));
644
+ var import_container_queries = __toESM(require("@tailwindcss/container-queries"));
645
+ var import_typography = __toESM(require("@tailwindcss/typography"));
622
646
  var import_tailwindcss = __toESM(require("tailwindcss"));
623
647
  var import_defaultTheme = __toESM(require("tailwindcss/defaultTheme.js"));
624
- var import_typography = __toESM(require("@tailwindcss/typography"));
625
- var import_aspect_ratio = __toESM(require("@tailwindcss/aspect-ratio"));
626
- var import_node_path = __toESM(require("path"));
627
648
  var tinaTailwind = (spaPath, prebuildFilePath) => {
628
649
  return {
629
650
  name: "vite-plugin-tina",
651
+ // @ts-ignore
630
652
  config: (viteConfig) => {
631
653
  const plugins = [];
632
654
  const content = [
@@ -867,7 +889,11 @@ var tinaTailwind = (spaPath, prebuildFilePath) => {
867
889
  }
868
890
  },
869
891
  content,
870
- plugins: [(0, import_typography.default)({ className: "tina-prose" }), import_aspect_ratio.default]
892
+ plugins: [
893
+ (0, import_typography.default)({ className: "tina-prose" }),
894
+ import_aspect_ratio.default,
895
+ import_container_queries.default
896
+ ]
871
897
  });
872
898
  plugins.push(tw);
873
899
  return {
@@ -934,7 +960,6 @@ async function listFilesRecursively({
934
960
  }
935
961
  var createConfig = async ({
936
962
  configManager,
937
- database,
938
963
  apiURL,
939
964
  plugins = [],
940
965
  noWatch,
@@ -994,6 +1019,8 @@ var createConfig = async ({
994
1019
  if (configManager.config.build.basePath) {
995
1020
  basePath = configManager.config.build.basePath;
996
1021
  }
1022
+ const fullVersion = configManager.getTinaGraphQLVersion();
1023
+ const version2 = `${fullVersion.major}.${fullVersion.minor}`;
997
1024
  const config2 = {
998
1025
  root: configManager.spaRootPath,
999
1026
  base: `/${basePath ? `${(0, import_normalize_path2.default)(basePath)}/` : ""}${(0, import_normalize_path2.default)(
@@ -1005,15 +1032,33 @@ var createConfig = async ({
1005
1032
  dedupe: ["graphql", "tinacms", "react", "react-dom", "react-router-dom"]
1006
1033
  },
1007
1034
  define: {
1035
+ /**
1036
+ * Since we prebuild the config.ts, it's possible for modules to be loaded which make
1037
+ * use of `process`. The main scenario where this is an issue is when co-locating schema
1038
+ * definitions with source files, and specifically source files which impor from NextJS.
1039
+ *
1040
+ * Some examples of what NextJS uses for `process.env` are:
1041
+ * - `process.env.__NEXT_TRAILING_SLASH`
1042
+ * - `process.env.__NEXT_CROSS_ORIGIN`
1043
+ * - `process.env.__NEXT_I18N_SUPPORT`
1044
+ *
1045
+ * Also, interestingly some of the advice for handling this doesn't work, references to replacing
1046
+ * `process.env` with `{}` are problematic, because browsers don't understand the `{}.` syntax,
1047
+ * but node does. This was a surprise, but using `new Object()` seems to do the trick.
1048
+ */
1008
1049
  "process.env": `new Object(${JSON.stringify(publicEnv)})`,
1050
+ // Used by picomatch https://github.com/micromatch/picomatch/blob/master/lib/utils.js#L4
1009
1051
  "process.platform": `"${process.platform}"`,
1010
1052
  __API_URL__: `"${apiURL}"`,
1011
1053
  __BASE_PATH__: `"${((_e = (_d = configManager.config) == null ? void 0 : _d.build) == null ? void 0 : _e.basePath) || ""}"`,
1012
- __TINA_GRAPHQL_VERSION__: `"${configManager.getTinaGraphQLVersion()}"`
1054
+ __TINA_GRAPHQL_VERSION__: version2
1013
1055
  },
1014
1056
  logLevel: "error",
1057
+ // Vite import warnings are noisy
1015
1058
  optimizeDeps: {
1016
1059
  force: true,
1060
+ // Not 100% sure why this isn't being picked up automatically, this works from within the monorepo
1061
+ // but breaks externally
1017
1062
  include: ["react/jsx-runtime", "react/jsx-dev-runtime"]
1018
1063
  },
1019
1064
  server: {
@@ -1021,6 +1066,7 @@ var createConfig = async ({
1021
1066
  watch: noWatch ? {
1022
1067
  ignored: ["**/*"]
1023
1068
  } : {
1069
+ // Ignore everything except for the alias fields we specified above
1024
1070
  ignored: [
1025
1071
  `${configManager.tinaFolderPath}/**/!(config.prebuild.jsx|_graphql.json)`
1026
1072
  ]
@@ -1036,8 +1082,13 @@ var createConfig = async ({
1036
1082
  rollupOptions
1037
1083
  },
1038
1084
  plugins: [
1085
+ /**
1086
+ * `splitVendorChunkPlugin` is needed because `tinacms` is quite large,
1087
+ * Vite's chunking strategy chokes on memory issues for smaller machines (ie. on CI).
1088
+ */
1039
1089
  (0, import_plugin_react.default)({
1040
1090
  babel: {
1091
+ // Supresses the warning [NOTE] babel The code generator has deoptimised the styling of
1041
1092
  compact: true
1042
1093
  }
1043
1094
  }),
@@ -1114,8 +1165,7 @@ var createMediaRouter = (config2) => {
1114
1165
  };
1115
1166
  var parseMediaFolder = (str) => {
1116
1167
  let returnString = str;
1117
- if (returnString.startsWith("/"))
1118
- returnString = returnString.substr(1);
1168
+ if (returnString.startsWith("/")) returnString = returnString.substr(1);
1119
1169
  if (returnString.endsWith("/"))
1120
1170
  returnString = returnString.substr(0, returnString.length - 1);
1121
1171
  return returnString;
@@ -1132,7 +1182,7 @@ var MediaModel = class {
1132
1182
  this.rootPath,
1133
1183
  this.publicFolder,
1134
1184
  this.mediaRoot,
1135
- args.searchPath
1185
+ decodeURIComponent(args.searchPath)
1136
1186
  );
1137
1187
  const searchPath = parseMediaFolder(args.searchPath);
1138
1188
  if (!await import_fs_extra3.default.pathExists(folderPath)) {
@@ -1204,7 +1254,7 @@ var MediaModel = class {
1204
1254
  this.rootPath,
1205
1255
  this.publicFolder,
1206
1256
  this.mediaRoot,
1207
- args.searchPath
1257
+ decodeURIComponent(args.searchPath)
1208
1258
  );
1209
1259
  await import_fs_extra3.default.stat(file);
1210
1260
  await import_fs_extra3.default.remove(file);
@@ -1280,7 +1330,8 @@ var devServerEndPointsPlugin = ({
1280
1330
  configManager,
1281
1331
  apiURL,
1282
1332
  database,
1283
- searchIndex
1333
+ searchIndex,
1334
+ databaseLock
1284
1335
  }) => {
1285
1336
  const plug = {
1286
1337
  name: "graphql-endpoints",
@@ -1324,14 +1375,17 @@ var devServerEndPointsPlugin = ({
1324
1375
  }
1325
1376
  if (req.url === "/graphql") {
1326
1377
  const { query, variables } = req.body;
1327
- const result = await (0, import_graphql.resolve)({
1328
- config: {
1329
- useRelativeMedia: true
1330
- },
1331
- database,
1332
- query,
1333
- variables,
1334
- verbose: false
1378
+ let result;
1379
+ await databaseLock(async () => {
1380
+ result = await (0, import_graphql.resolve)({
1381
+ config: {
1382
+ useRelativeMedia: true
1383
+ },
1384
+ database,
1385
+ query,
1386
+ variables,
1387
+ verbose: false
1388
+ });
1335
1389
  });
1336
1390
  res.end(JSON.stringify(result));
1337
1391
  return;
@@ -1382,6 +1436,7 @@ function viteTransformExtension({
1382
1436
  return {
1383
1437
  code: res.code,
1384
1438
  map: null
1439
+ // TODO:
1385
1440
  };
1386
1441
  }
1387
1442
  }
@@ -1389,10 +1444,16 @@ function viteTransformExtension({
1389
1444
  }
1390
1445
 
1391
1446
  // src/next/commands/dev-command/server/index.ts
1392
- var createDevServer = async (configManager, database, searchIndex, apiURL, noWatch) => {
1447
+ var createDevServer = async (configManager, database, searchIndex, apiURL, noWatch, databaseLock) => {
1393
1448
  const plugins = [
1394
1449
  transformTsxPlugin({ configManager }),
1395
- devServerEndPointsPlugin({ apiURL, configManager, database, searchIndex }),
1450
+ devServerEndPointsPlugin({
1451
+ apiURL,
1452
+ configManager,
1453
+ database,
1454
+ searchIndex,
1455
+ databaseLock
1456
+ }),
1396
1457
  viteTransformExtension()
1397
1458
  ];
1398
1459
  return (0, import_vite3.createServer)(
@@ -1402,6 +1463,14 @@ var createDevServer = async (configManager, database, searchIndex, apiURL, noWat
1402
1463
  apiURL,
1403
1464
  plugins,
1404
1465
  noWatch,
1466
+ /**
1467
+ * Ensure Vite's import scan uses the spaMainPath as the input
1468
+ * so it properly finds everything. This is for dev only, and when
1469
+ * running the server outside of this monorepo vite fails to find
1470
+ * and optimize the imports, so you get errors about it not being
1471
+ * able to find an export from a module, and it's always a CJS
1472
+ * module that Vite would usually transform to an ES module.
1473
+ */
1405
1474
  rollupOptions: {
1406
1475
  input: configManager.spaMainPath,
1407
1476
  onwarn(warning, warn) {
@@ -1527,6 +1596,7 @@ var GenericSdkVisitor = class extends import_visitor_plugin_common.ClientSideBas
1527
1596
  node,
1528
1597
  documentVariableName,
1529
1598
  operationType,
1599
+ // This is the only line that is different
1530
1600
  operationResultType: `{data: ${operationResultType}, errors?: { message: string, locations: { line: number, column: number }[], path: string[] }[], variables: ${operationVariablesTypes}, query: string}`,
1531
1601
  operationVariablesTypes
1532
1602
  });
@@ -1575,6 +1645,8 @@ var plugin = (schema, documents, config2) => {
1575
1645
  const visitor = new GenericSdkVisitor(schema, allFragments, config2);
1576
1646
  const visitorResult = (0, import_graphql3.visit)(allAst, { leave: visitor });
1577
1647
  return {
1648
+ // We will take care of imports
1649
+ // prepend: visitor.getImports(),
1578
1650
  content: [
1579
1651
  visitor.fragments,
1580
1652
  ...visitorResult.definitions.filter((t) => typeof t === "string"),
@@ -1590,6 +1662,7 @@ var generateTypes = async (schema, queryPathGlob = process.cwd(), fragDocPath =
1590
1662
  docs = await loadGraphQLDocuments(queryPathGlob);
1591
1663
  fragDocs = await loadGraphQLDocuments(fragDocPath);
1592
1664
  const res = await (0, import_core.codegen)({
1665
+ // Filename is not used. This is because the typescript plugin returns a string instead of writing to a file.
1593
1666
  filename: process.cwd(),
1594
1667
  schema: (0, import_graphql5.parse)((0, import_graphql5.printSchema)(schema)),
1595
1668
  documents: [...docs, ...fragDocs],
@@ -1624,9 +1697,12 @@ var loadGraphQLDocuments = async (globPath) => {
1624
1697
  loaders: [new import_graphql_file_loader.GraphQLFileLoader()]
1625
1698
  });
1626
1699
  } catch (e) {
1627
- if ((e.message || "").includes(
1628
- "Unable to find any GraphQL type definitions for the following pointers:"
1629
- )) {
1700
+ if (
1701
+ // https://www.graphql-tools.com/docs/documents-loading#no-files-found
1702
+ (e.message || "").includes(
1703
+ "Unable to find any GraphQL type definitions for the following pointers:"
1704
+ )
1705
+ ) {
1630
1706
  } else {
1631
1707
  throw e;
1632
1708
  }
@@ -1663,7 +1739,10 @@ var Codegen = class {
1663
1739
  this.noClientBuildCache = noClientBuildCache;
1664
1740
  }
1665
1741
  async writeConfigFile(fileName, data) {
1666
- const filePath = import_path4.default.join(this.configManager.generatedFolderPath, fileName);
1742
+ const filePath = import_path4.default.join(
1743
+ this.configManager.generatedFolderPath,
1744
+ fileName
1745
+ );
1667
1746
  await import_fs_extra4.default.ensureFile(filePath);
1668
1747
  await import_fs_extra4.default.outputFile(filePath, data);
1669
1748
  if (this.configManager.hasSeparateContentRoot()) {
@@ -1783,16 +1862,14 @@ var Codegen = class {
1783
1862
  const branch = (_a = this.configManager.config) == null ? void 0 : _a.branch;
1784
1863
  const clientId = (_b = this.configManager.config) == null ? void 0 : _b.clientId;
1785
1864
  const token = (_c = this.configManager.config) == null ? void 0 : _c.token;
1786
- const version2 = this.configManager.getTinaGraphQLVersion();
1865
+ const fullVersion = this.configManager.getTinaGraphQLVersion();
1866
+ const version2 = `${fullVersion.major}.${fullVersion.minor}`;
1787
1867
  const baseUrl = ((_d = this.configManager.config.tinaioConfig) == null ? void 0 : _d.contentApiUrlOverride) || `https://${TINA_HOST}`;
1788
1868
  if ((!branch || !clientId || !token) && !this.port && !this.configManager.config.contentApiUrlOverride) {
1789
1869
  const missing = [];
1790
- if (!branch)
1791
- missing.push("branch");
1792
- if (!clientId)
1793
- missing.push("clientId");
1794
- if (!token)
1795
- missing.push("token");
1870
+ if (!branch) missing.push("branch");
1871
+ if (!clientId) missing.push("clientId");
1872
+ if (!token) missing.push("token");
1796
1873
  throw new Error(
1797
1874
  `Client not configured properly. Missing ${missing.join(
1798
1875
  ", "
@@ -1946,7 +2023,11 @@ schema {
1946
2023
  }
1947
2024
  };
1948
2025
  var maybeWarnFragmentSize = async (filepath) => {
1949
- if ((await import_fs_extra4.default.stat(filepath)).size > 100 * 1024) {
2026
+ if (
2027
+ // is the file bigger than 100kb?
2028
+ (await import_fs_extra4.default.stat(filepath)).size > // convert to 100 kb to bytes
2029
+ 100 * 1024
2030
+ ) {
1950
2031
  console.warn(
1951
2032
  "Warning: frags.gql is very large (>100kb). Consider setting the reference depth to 1 or 0. See code snippet below."
1952
2033
  );
@@ -1974,6 +2055,7 @@ var import_many_level = require("many-level");
1974
2055
  var import_memory_level = require("memory-level");
1975
2056
  var createDBServer = (port) => {
1976
2057
  const levelHost = new import_many_level.ManyLevelHost(
2058
+ // @ts-ignore
1977
2059
  new import_memory_level.MemoryLevel({
1978
2060
  valueEncoding: "json"
1979
2061
  })
@@ -2124,7 +2206,9 @@ var BaseCommand = class extends import_clipanion.Command {
2124
2206
  let subProc;
2125
2207
  if (this.subCommand) {
2126
2208
  subProc = await startSubprocess2({ command: this.subCommand });
2127
- logger.info(`Starting subprocess: ${import_chalk4.default.cyan(this.subCommand)}`);
2209
+ logger.info(
2210
+ `Running web application with command: ${import_chalk4.default.cyan(this.subCommand)}`
2211
+ );
2128
2212
  }
2129
2213
  function exitHandler(options, exitCode) {
2130
2214
  if (subProc) {
@@ -2204,7 +2288,7 @@ var BaseCommand = class extends import_clipanion.Command {
2204
2288
  pathFilter
2205
2289
  });
2206
2290
  const tinaPathUpdates = modified.filter(
2207
- (path13) => path13.startsWith(".tina/__generated__/_schema.json") || path13.startsWith("tina/tina-lock.json")
2291
+ (path14) => path14.startsWith(".tina/__generated__/_schema.json") || path14.startsWith("tina/tina-lock.json")
2208
2292
  );
2209
2293
  if (tinaPathUpdates.length > 0) {
2210
2294
  res = await database.indexContent({
@@ -2248,6 +2332,7 @@ var import_search = require("@tinacms/search");
2248
2332
  var DevCommand = class extends BaseCommand {
2249
2333
  constructor() {
2250
2334
  super(...arguments);
2335
+ // NOTE: camelCase commands for string options don't work if there's an `=` used https://github.com/arcanis/clipanion/issues/141
2251
2336
  this.watchFolders = import_clipanion2.Option.String("-w,--watchFolders", {
2252
2337
  description: "DEPRECATED - a list of folders (relative to where this is being run) that the cli will watch for changes"
2253
2338
  });
@@ -2257,6 +2342,10 @@ var DevCommand = class extends BaseCommand {
2257
2342
  this.outputSearchIndexPath = import_clipanion2.Option.String("--outputSearchIndexPath", {
2258
2343
  description: "Path to write the search index to"
2259
2344
  });
2345
+ this.noServer = import_clipanion2.Option.Boolean("--no-server", false, {
2346
+ description: "Do not start the dev server"
2347
+ });
2348
+ this.indexingLock = new import_async_lock.default();
2260
2349
  }
2261
2350
  async catch(error) {
2262
2351
  logger.error("Error occured during tinacms dev");
@@ -2277,10 +2366,13 @@ var DevCommand = class extends BaseCommand {
2277
2366
  rootPath: this.rootPath,
2278
2367
  legacyNoSDK: this.noSDK
2279
2368
  });
2280
- logger.info("Starting Tina Dev Server");
2369
+ logger.info("\u{1F999} TinaCMS Dev Server is initializing...");
2281
2370
  this.logDeprecationWarnings();
2282
2371
  createDBServer(Number(this.datalayerPort));
2283
2372
  let database = null;
2373
+ const dbLock = async (fn) => {
2374
+ return this.indexingLock.acquire("Key", fn);
2375
+ };
2284
2376
  const setup = async ({ firstTime }) => {
2285
2377
  try {
2286
2378
  await configManager.processConfig();
@@ -2331,9 +2423,6 @@ var DevCommand = class extends BaseCommand {
2331
2423
  await import_fs_extra6.default.outputFile(filePath, tinaLockContent);
2332
2424
  }
2333
2425
  }
2334
- if (!this.noWatch) {
2335
- this.watchQueries(configManager, async () => await codegen2.execute());
2336
- }
2337
2426
  await this.indexContentWithSpinner({
2338
2427
  database,
2339
2428
  graphQLSchema: graphQLSchema2,
@@ -2343,6 +2432,13 @@ var DevCommand = class extends BaseCommand {
2343
2432
  if (!firstTime) {
2344
2433
  logger.error("Re-index complete");
2345
2434
  }
2435
+ if (!this.noWatch) {
2436
+ this.watchQueries(
2437
+ configManager,
2438
+ dbLock,
2439
+ async () => await codegen2.execute()
2440
+ );
2441
+ }
2346
2442
  return { apiURL: apiURL2, database, graphQLSchema: graphQLSchema2, tinaSchema: tinaSchema2 };
2347
2443
  } catch (e) {
2348
2444
  logger.error(`
@@ -2377,14 +2473,6 @@ ${dangerText(e.message)}
2377
2473
  tokenSplitRegex: (_d = (_c = configManager.config.search) == null ? void 0 : _c.tina) == null ? void 0 : _d.tokenSplitRegex
2378
2474
  });
2379
2475
  await searchIndexClient.onStartIndexing();
2380
- const server = await createDevServer(
2381
- configManager,
2382
- database,
2383
- searchIndexClient.searchIndex,
2384
- apiURL,
2385
- this.noWatch
2386
- );
2387
- await server.listen(Number(this.port));
2388
2476
  const searchIndexer = new import_search.SearchIndexer({
2389
2477
  batchSize: ((_e = configManager.config.search) == null ? void 0 : _e.indexBatchSize) || 100,
2390
2478
  bridge: new import_graphql10.FilesystemBridge(
@@ -2406,16 +2494,34 @@ ${dangerText(e.message)}
2406
2494
  await searchIndexClient.export(this.outputSearchIndexPath);
2407
2495
  }
2408
2496
  }
2497
+ if (this.noServer) {
2498
+ logger.info("--no-server option specified - Dev server not started");
2499
+ process.exit(0);
2500
+ }
2409
2501
  if (!this.noWatch) {
2410
2502
  this.watchContentFiles(
2411
2503
  configManager,
2412
2504
  database,
2505
+ dbLock,
2413
2506
  configManager.config.search && searchIndexer
2414
2507
  );
2508
+ }
2509
+ const server = await createDevServer(
2510
+ configManager,
2511
+ database,
2512
+ searchIndexClient.searchIndex,
2513
+ apiURL,
2514
+ this.noWatch,
2515
+ dbLock
2516
+ );
2517
+ await server.listen(Number(this.port));
2518
+ if (!this.noWatch) {
2415
2519
  import_chokidar.default.watch(configManager.watchList).on("change", async () => {
2416
- logger.info(`Tina config change detected, rebuilding`);
2417
- await setup({ firstTime: false });
2418
- server.ws.send({ type: "full-reload", path: "*" });
2520
+ await dbLock(async () => {
2521
+ logger.info(`Tina config change detected, rebuilding`);
2522
+ await setup({ firstTime: false });
2523
+ server.ws.send({ type: "full-reload", path: "*" });
2524
+ });
2419
2525
  });
2420
2526
  }
2421
2527
  const subItems = [];
@@ -2428,7 +2534,7 @@ ${dangerText(e.message)}
2428
2534
  const summaryItems = [
2429
2535
  {
2430
2536
  emoji: "\u{1F999}",
2431
- heading: "Tina Config",
2537
+ heading: "TinaCMS URLs",
2432
2538
  subItems: [
2433
2539
  {
2434
2540
  key: "CMS",
@@ -2463,14 +2569,28 @@ ${dangerText(e.message)}
2463
2569
  });
2464
2570
  }
2465
2571
  summary({
2466
- heading: "Tina Dev Server is running...",
2572
+ heading: "\u2705 \u{1F999} TinaCMS Dev Server is active:",
2467
2573
  items: [
2468
2574
  ...summaryItems
2575
+ // {
2576
+ // emoji: '📚',
2577
+ // heading: 'Useful links',
2578
+ // subItems: [
2579
+ // {
2580
+ // key: 'Custom queries',
2581
+ // value: 'https://tina.io/querying',
2582
+ // },
2583
+ // {
2584
+ // key: 'Visual editing',
2585
+ // value: 'https://tina.io/visual-editing',
2586
+ // },
2587
+ // ],
2588
+ // },
2469
2589
  ]
2470
2590
  });
2471
2591
  await this.startSubCommand();
2472
2592
  }
2473
- watchContentFiles(configManager, database, searchIndexer) {
2593
+ watchContentFiles(configManager, database, databaseLock, searchIndexer) {
2474
2594
  const collectionContentFiles = [];
2475
2595
  configManager.config.schema.collections.forEach((collection) => {
2476
2596
  const collectionGlob = `${import_path5.default.join(
@@ -2486,39 +2606,42 @@ ${dangerText(e.message)}
2486
2606
  if (!ready) {
2487
2607
  return;
2488
2608
  }
2489
- const pathFromRoot = configManager.printContentRelativePath(addedFile);
2490
- await database.indexContentByPaths([pathFromRoot]).catch(console.error);
2491
- if (searchIndexer) {
2492
- await searchIndexer.indexContentByPaths([pathFromRoot]).catch(console.error);
2493
- }
2609
+ await databaseLock(async () => {
2610
+ const pathFromRoot = configManager.printContentRelativePath(addedFile);
2611
+ await database.indexContentByPaths([pathFromRoot]).catch(console.error);
2612
+ if (searchIndexer) {
2613
+ await searchIndexer.indexContentByPaths([pathFromRoot]).catch(console.error);
2614
+ }
2615
+ });
2494
2616
  }).on("change", async (changedFile) => {
2495
2617
  const pathFromRoot = configManager.printContentRelativePath(changedFile);
2496
- await database.indexContentByPaths([pathFromRoot]).catch(console.error);
2497
- if (searchIndexer) {
2498
- await searchIndexer.indexContentByPaths([pathFromRoot]).catch(console.error);
2499
- }
2618
+ await databaseLock(async () => {
2619
+ await database.indexContentByPaths([pathFromRoot]).catch(console.error);
2620
+ if (searchIndexer) {
2621
+ await searchIndexer.indexContentByPaths([pathFromRoot]).catch(console.error);
2622
+ }
2623
+ });
2500
2624
  }).on("unlink", async (removedFile) => {
2501
2625
  const pathFromRoot = configManager.printContentRelativePath(removedFile);
2502
- await database.deleteContentByPaths([pathFromRoot]).catch(console.error);
2503
- if (searchIndexer) {
2504
- await searchIndexer.deleteIndexContent([pathFromRoot]).catch(console.error);
2505
- }
2626
+ await databaseLock(async () => {
2627
+ await database.deleteContentByPaths([pathFromRoot]).catch(console.error);
2628
+ if (searchIndexer) {
2629
+ await searchIndexer.deleteIndexContent([pathFromRoot]).catch(console.error);
2630
+ }
2631
+ });
2506
2632
  });
2507
2633
  }
2508
- watchQueries(configManager, callback) {
2509
- let ready = false;
2510
- import_chokidar.default.watch(configManager.userQueriesAndFragmentsGlob).on("ready", () => {
2511
- ready = true;
2512
- }).on("add", async (addedFile) => {
2513
- await callback();
2514
- }).on("change", async (changedFile) => {
2515
- await callback();
2516
- }).on("unlink", async (removedFile) => {
2517
- await callback();
2518
- });
2634
+ watchQueries(configManager, databaseLock, callback) {
2635
+ const executeCallback = async (_) => {
2636
+ await databaseLock(async () => {
2637
+ await callback();
2638
+ });
2639
+ };
2640
+ import_chokidar.default.watch(configManager.userQueriesAndFragmentsGlob).on("add", executeCallback).on("change", executeCallback).on("unlink", executeCallback);
2519
2641
  }
2520
2642
  };
2521
2643
  DevCommand.paths = [["dev"], ["server:start"]];
2644
+ // Prevent indexes and reads occurring at once
2522
2645
  DevCommand.usage = import_clipanion2.Command.Usage({
2523
2646
  category: `Commands`,
2524
2647
  description: `Builds Tina and starts the dev server`,
@@ -2532,6 +2655,8 @@ DevCommand.usage = import_clipanion2.Command.Usage({
2532
2655
  var import_clipanion3 = require("clipanion");
2533
2656
  var import_progress2 = __toESM(require("progress"));
2534
2657
  var import_fs_extra7 = __toESM(require("fs-extra"));
2658
+ var import_crypto = __toESM(require("crypto"));
2659
+ var import_path6 = __toESM(require("path"));
2535
2660
  var import_graphql11 = require("@tinacms/graphql");
2536
2661
 
2537
2662
  // src/next/commands/build-command/server.ts
@@ -2575,7 +2700,7 @@ var buildProductionSpa = async (configManager, database, apiURL) => {
2575
2700
  // src/next/commands/build-command/index.ts
2576
2701
  var import_schema_tools2 = require("@tinacms/schema-tools");
2577
2702
  var import_graphql12 = require("graphql");
2578
- var import_core2 = require("@graphql-inspector/core");
2703
+ var import_core3 = require("@graphql-inspector/core");
2579
2704
 
2580
2705
  // src/next/commands/build-command/waitForDB.ts
2581
2706
  var import_progress = __toESM(require("progress"));
@@ -2677,6 +2802,20 @@ var waitForDB = async (config2, apiUrl, previewName, verbose) => {
2677
2802
 
2678
2803
  // src/next/commands/build-command/index.ts
2679
2804
  var import_search2 = require("@tinacms/search");
2805
+
2806
+ // src/utils/index.ts
2807
+ var import_core2 = require("@graphql-inspector/core");
2808
+ var getFaqLink = (type) => {
2809
+ switch (type) {
2810
+ case import_core2.ChangeType.FieldRemoved: {
2811
+ return "https://tina.io/docs/introduction/faq#how-do-i-resolve-the-local-graphql-schema-doesnt-match-the-remote-graphql-schema-errors";
2812
+ }
2813
+ default:
2814
+ return null;
2815
+ }
2816
+ };
2817
+
2818
+ // src/next/commands/build-command/index.ts
2680
2819
  var BuildCommand = class extends BaseCommand {
2681
2820
  constructor() {
2682
2821
  super(...arguments);
@@ -2692,6 +2831,9 @@ var BuildCommand = class extends BaseCommand {
2692
2831
  this.tinaGraphQLVersion = import_clipanion3.Option.String("--tina-graphql-version", {
2693
2832
  description: "Specify the version of @tinacms/graphql to use (defaults to latest)"
2694
2833
  });
2834
+ /**
2835
+ * This option allows the user to skip the tina cloud checks if they want to. This could be useful for mismatched GraphQL versions or if they want to build only using the local client and never connect to Tina Cloud
2836
+ */
2695
2837
  this.skipCloudChecks = import_clipanion3.Option.Boolean("--skip-cloud-checks", false, {
2696
2838
  description: "Skips checking the provided cloud config."
2697
2839
  });
@@ -2797,14 +2939,15 @@ ${dangerText(e.message)}
2797
2939
  database,
2798
2940
  null,
2799
2941
  apiURL,
2800
- true
2942
+ true,
2943
+ (lockedFn) => lockedFn()
2801
2944
  );
2802
2945
  await server.listen(Number(this.port));
2803
2946
  console.log("server listening on port", this.port);
2804
2947
  }
2805
2948
  const skipCloudChecks = this.skipCloudChecks || configManager.hasSelfHostedConfig();
2806
2949
  if (!skipCloudChecks) {
2807
- const { hasUpstream } = await this.checkClientInfo(
2950
+ const { hasUpstream, timestamp } = await this.checkClientInfo(
2808
2951
  configManager,
2809
2952
  codegen2.productionUrl,
2810
2953
  this.previewBaseBranch
@@ -2832,7 +2975,16 @@ ${dangerText(e.message)}
2832
2975
  await this.checkGraphqlSchema(
2833
2976
  configManager,
2834
2977
  database,
2835
- codegen2.productionUrl
2978
+ codegen2.productionUrl,
2979
+ timestamp
2980
+ );
2981
+ await this.checkTinaSchema(
2982
+ configManager,
2983
+ database,
2984
+ codegen2.productionUrl,
2985
+ this.previewName,
2986
+ this.verbose,
2987
+ timestamp
2836
2988
  );
2837
2989
  }
2838
2990
  await buildProductionSpa(configManager, database, codegen2.productionUrl);
@@ -2850,7 +3002,9 @@ ${dangerText(e.message)}
2850
3002
  `ERROR: Branch not configured in tina search configuration.`
2851
3003
  )}`
2852
3004
  );
2853
- throw new Error("Branch not configured in tina search configuration.");
3005
+ throw new Error(
3006
+ "Branch not configured in tina search configuration."
3007
+ );
2854
3008
  }
2855
3009
  if (!((_d = configManager.config) == null ? void 0 : _d.clientId)) {
2856
3010
  logger.error(`${dangerText(`ERROR: clientId not configured.`)}`);
@@ -2951,11 +3105,13 @@ ${dangerText(e.message)}
2951
3105
  const bar2 = new import_progress2.default("Checking clientId and token. :prog", 1);
2952
3106
  let branchKnown = false;
2953
3107
  let hasUpstream = false;
3108
+ let timestamp;
2954
3109
  try {
2955
3110
  const res = await request({
2956
3111
  token,
2957
3112
  url
2958
3113
  });
3114
+ timestamp = res.timestamp || 0;
2959
3115
  bar2.tick({
2960
3116
  prog: "\u2705"
2961
3117
  });
@@ -2991,13 +3147,17 @@ ${dangerText(e.message)}
2991
3147
  });
2992
3148
  throw e;
2993
3149
  }
2994
- const branchBar = new import_progress2.default("Checking branch is on Tina Cloud. :prog", 1);
3150
+ const branchBar = new import_progress2.default(
3151
+ "Checking branch is on Tina Cloud. :prog",
3152
+ 1
3153
+ );
2995
3154
  if (branchKnown) {
2996
3155
  branchBar.tick({
2997
3156
  prog: "\u2705"
2998
3157
  });
2999
3158
  return {
3000
- hasUpstream
3159
+ hasUpstream,
3160
+ timestamp
3001
3161
  };
3002
3162
  }
3003
3163
  for (let i = 0; i <= 5; i++) {
@@ -3087,14 +3247,14 @@ ${dangerText(e.message)}
3087
3247
  throw e;
3088
3248
  }
3089
3249
  }
3090
- async checkGraphqlSchema(configManager, database, apiURL) {
3250
+ async checkGraphqlSchema(configManager, database, apiURL, timestamp) {
3091
3251
  const bar2 = new import_progress2.default(
3092
3252
  "Checking local GraphQL Schema matches server. :prog",
3093
3253
  1
3094
3254
  );
3095
3255
  const { config: config2 } = configManager;
3096
3256
  const token = config2.token;
3097
- const remoteSchema = await fetchRemoteGraphqlSchema({
3257
+ const { remoteSchema, remoteProjectVersion } = await fetchRemoteGraphqlSchema({
3098
3258
  url: apiURL,
3099
3259
  token
3100
3260
  });
@@ -3114,7 +3274,7 @@ Additional info: Branch: ${config2.branch}, Client ID: ${config2.clientId} `;
3114
3274
  const localSchemaDocument = await database.getGraphQLSchemaFromBridge();
3115
3275
  const localGraphqlSchema = (0, import_graphql12.buildASTSchema)(localSchemaDocument);
3116
3276
  try {
3117
- const diffResult = await (0, import_core2.diff)(localGraphqlSchema, remoteGqlSchema);
3277
+ const diffResult = await (0, import_core3.diff)(remoteGqlSchema, localGraphqlSchema);
3118
3278
  if (diffResult.length === 0) {
3119
3279
  bar2.tick({
3120
3280
  prog: "\u2705"
@@ -3123,12 +3283,30 @@ Additional info: Branch: ${config2.branch}, Client ID: ${config2.clientId} `;
3123
3283
  bar2.tick({
3124
3284
  prog: "\u274C"
3125
3285
  });
3126
- let errorMessage = `The local GraphQL schema doesn't match the remote GraphQL schema. Please push up your changes to GitHub to update your remote GraphQL schema.`;
3127
- if (config2 == null ? void 0 : config2.branch) {
3128
- errorMessage += `
3286
+ const type = diffResult[0].type;
3287
+ const reason = diffResult[0].message;
3288
+ const errorLevel = diffResult[0].criticality.level;
3289
+ const faqLink = getFaqLink(type);
3290
+ const tinaGraphQLVersion = configManager.getTinaGraphQLVersion();
3291
+ let errorMessage = `The local GraphQL schema doesn't match the remote GraphQL schema. Please push up your changes to GitHub to update your remote GraphQL schema. ${faqLink && `
3292
+ Check out '${faqLink}' for possible solutions.`}`;
3293
+ errorMessage += `
3129
3294
 
3130
- Additional info: Branch: ${config2.branch}, Client ID: ${config2.clientId} `;
3295
+ Additional info:
3296
+
3297
+ `;
3298
+ if (config2 == null ? void 0 : config2.branch) {
3299
+ errorMessage += ` Branch: ${config2.branch}, Client ID: ${config2.clientId}
3300
+ `;
3131
3301
  }
3302
+ errorMessage += ` Local GraphQL version: ${tinaGraphQLVersion.fullVersion} / Remote GraphQL version: ${remoteProjectVersion}
3303
+ `;
3304
+ errorMessage += ` Last indexed at: ${new Date(
3305
+ timestamp
3306
+ ).toUTCString()}
3307
+ `;
3308
+ errorMessage += ` Reason: [${errorLevel} - ${type}] ${reason}
3309
+ `;
3132
3310
  throw new Error(errorMessage);
3133
3311
  }
3134
3312
  } catch (e) {
@@ -3143,6 +3321,73 @@ Additional info: Branch: ${config2.branch}, Client ID: ${config2.clientId} `;
3143
3321
  }
3144
3322
  }
3145
3323
  }
3324
+ async checkTinaSchema(configManager, database, apiURL, previewName, verbose, timestamp) {
3325
+ const bar2 = new import_progress2.default(
3326
+ "Checking local Tina Schema matches server. :prog",
3327
+ 1
3328
+ );
3329
+ const { config: config2 } = configManager;
3330
+ const token = config2.token;
3331
+ const { clientId, branch, isLocalClient, host } = (0, import_schema_tools2.parseURL)(apiURL);
3332
+ if (isLocalClient || !host || !clientId || !branch) {
3333
+ if (verbose) {
3334
+ logger.info(
3335
+ logText("Not using Tina Cloud, skipping Tina Schema check")
3336
+ );
3337
+ }
3338
+ return;
3339
+ }
3340
+ const { tinaSchema: remoteTinaSchemaSha } = await fetchSchemaSha({
3341
+ url: `https://${host}/db/${clientId}/${previewName || branch}/schemaSha`,
3342
+ token
3343
+ });
3344
+ if (!remoteTinaSchemaSha) {
3345
+ bar2.tick({
3346
+ prog: "\u274C"
3347
+ });
3348
+ let errorMessage = `The remote Tina schema does not exist. Check indexing for this branch.`;
3349
+ if (config2 == null ? void 0 : config2.branch) {
3350
+ errorMessage += `
3351
+
3352
+ Additional info: Branch: ${config2.branch}, Client ID: ${config2.clientId} `;
3353
+ }
3354
+ throw new Error(errorMessage);
3355
+ }
3356
+ if (!database.bridge) {
3357
+ throw new Error(`No bridge configured`);
3358
+ }
3359
+ const localTinaSchema = JSON.parse(
3360
+ await database.bridge.get(
3361
+ import_path6.default.join(database.tinaDirectory, "__generated__", "_schema.json")
3362
+ )
3363
+ );
3364
+ localTinaSchema.version = void 0;
3365
+ const localTinaSchemaSha = import_crypto.default.createHash("sha256").update(JSON.stringify(localTinaSchema)).digest("hex");
3366
+ if (localTinaSchemaSha === remoteTinaSchemaSha) {
3367
+ bar2.tick({
3368
+ prog: "\u2705"
3369
+ });
3370
+ } else {
3371
+ bar2.tick({
3372
+ prog: "\u274C"
3373
+ });
3374
+ let errorMessage = `The local Tina schema doesn't match the remote Tina schema. Please push up your changes to GitHub to update your remote tina schema.`;
3375
+ errorMessage += `
3376
+
3377
+ Additional info:
3378
+
3379
+ `;
3380
+ if (config2 == null ? void 0 : config2.branch) {
3381
+ errorMessage += ` Branch: ${config2.branch}, Client ID: ${config2.clientId}
3382
+ `;
3383
+ }
3384
+ errorMessage += ` Last indexed at: ${new Date(
3385
+ timestamp
3386
+ ).toUTCString()}
3387
+ `;
3388
+ throw new Error(errorMessage);
3389
+ }
3390
+ }
3146
3391
  };
3147
3392
  BuildCommand.paths = [["build"]];
3148
3393
  BuildCommand.usage = import_clipanion3.Command.Usage({
@@ -3209,7 +3454,26 @@ var fetchRemoteGraphqlSchema = async ({
3209
3454
  body
3210
3455
  });
3211
3456
  const data = await res.json();
3212
- return data == null ? void 0 : data.data;
3457
+ return {
3458
+ remoteSchema: data == null ? void 0 : data.data,
3459
+ remoteRuntimeVersion: res.headers.get("tinacms-grapqhl-version"),
3460
+ remoteProjectVersion: res.headers.get("tinacms-graphql-project-version")
3461
+ };
3462
+ };
3463
+ var fetchSchemaSha = async ({
3464
+ url,
3465
+ token
3466
+ }) => {
3467
+ const headers = new Headers();
3468
+ if (token) {
3469
+ headers.append("X-API-KEY", token);
3470
+ }
3471
+ const res = await fetch(url, {
3472
+ method: "GET",
3473
+ headers,
3474
+ cache: "no-cache"
3475
+ });
3476
+ return res.json();
3213
3477
  };
3214
3478
 
3215
3479
  // src/next/commands/audit-command/index.ts
@@ -3318,6 +3582,7 @@ var auditDocuments = async (args) => {
3318
3582
  logger.error(import_chalk5.default.red(err.message));
3319
3583
  if (err.originalError.originalError) {
3320
3584
  logger.error(
3585
+ // @ts-ignore FIXME: this doesn't seem right
3321
3586
  import_chalk5.default.red(` ${err.originalError.originalError.message}`)
3322
3587
  );
3323
3588
  }
@@ -3464,25 +3729,25 @@ var import_clipanion6 = require("clipanion");
3464
3729
 
3465
3730
  // src/cmds/init/detectEnvironment.ts
3466
3731
  var import_fs_extra8 = __toESM(require("fs-extra"));
3467
- var import_path6 = __toESM(require("path"));
3732
+ var import_path7 = __toESM(require("path"));
3468
3733
  var checkGitignoreForItem = async ({
3469
3734
  baseDir,
3470
3735
  line
3471
3736
  }) => {
3472
- const gitignoreContent = import_fs_extra8.default.readFileSync(import_path6.default.join(baseDir, ".gitignore")).toString();
3737
+ const gitignoreContent = import_fs_extra8.default.readFileSync(import_path7.default.join(baseDir, ".gitignore")).toString();
3473
3738
  return gitignoreContent.split("\n").some((item) => item === line);
3474
3739
  };
3475
3740
  var makeGeneratedFile = async (name2, generatedFileType, parentPath, opts) => {
3476
3741
  const result = {
3477
- fullPathTS: import_path6.default.join(
3742
+ fullPathTS: import_path7.default.join(
3478
3743
  parentPath,
3479
3744
  `${name2}.${(opts == null ? void 0 : opts.typescriptSuffix) || (opts == null ? void 0 : opts.extensionOverride) || "ts"}`
3480
3745
  ),
3481
- fullPathJS: import_path6.default.join(
3746
+ fullPathJS: import_path7.default.join(
3482
3747
  parentPath,
3483
3748
  `${name2}.${(opts == null ? void 0 : opts.extensionOverride) || "js"}`
3484
3749
  ),
3485
- fullPathOverride: (opts == null ? void 0 : opts.extensionOverride) ? import_path6.default.join(parentPath, `${name2}.${opts == null ? void 0 : opts.extensionOverride}`) : "",
3750
+ fullPathOverride: (opts == null ? void 0 : opts.extensionOverride) ? import_path7.default.join(parentPath, `${name2}.${opts == null ? void 0 : opts.extensionOverride}`) : "",
3486
3751
  generatedFileType,
3487
3752
  name: name2,
3488
3753
  parentPath,
@@ -3512,18 +3777,20 @@ var detectEnvironment = async ({
3512
3777
  }) => {
3513
3778
  var _a;
3514
3779
  const hasForestryConfig = await import_fs_extra8.default.pathExists(
3515
- import_path6.default.join(pathToForestryConfig, ".forestry", "settings.yml")
3780
+ import_path7.default.join(pathToForestryConfig, ".forestry", "settings.yml")
3516
3781
  );
3517
- const sampleContentPath = import_path6.default.join(
3782
+ const sampleContentPath = import_path7.default.join(
3518
3783
  baseDir,
3519
3784
  "content",
3520
3785
  "posts",
3521
3786
  "hello-world.md"
3522
3787
  );
3523
- const usingSrc = import_fs_extra8.default.pathExistsSync(import_path6.default.join(baseDir, "src")) && (import_fs_extra8.default.pathExistsSync(import_path6.default.join(baseDir, "src", "app")) || import_fs_extra8.default.pathExistsSync(import_path6.default.join(baseDir, "src", "pages")));
3524
- const tinaFolder = import_path6.default.join(baseDir, "tina");
3788
+ const usingSrc = import_fs_extra8.default.pathExistsSync(import_path7.default.join(baseDir, "src")) && (import_fs_extra8.default.pathExistsSync(import_path7.default.join(baseDir, "src", "app")) || import_fs_extra8.default.pathExistsSync(import_path7.default.join(baseDir, "src", "pages")));
3789
+ const tinaFolder = import_path7.default.join(baseDir, "tina");
3525
3790
  const tinaConfigExists = Boolean(
3526
- await import_fs_extra8.default.pathExists(tinaFolder) && (await import_fs_extra8.default.readdir(tinaFolder)).find((x) => x.includes("config"))
3791
+ // Does the tina folder exist?
3792
+ await import_fs_extra8.default.pathExists(tinaFolder) && // Does the tina folder contain a config file?
3793
+ (await import_fs_extra8.default.readdir(tinaFolder)).find((x) => x.includes("config"))
3527
3794
  );
3528
3795
  const pagesDir = [baseDir, usingSrc ? "src" : false, "pages"].filter(
3529
3796
  Boolean
@@ -3535,12 +3802,12 @@ var detectEnvironment = async ({
3535
3802
  "next-api-handler": await makeGeneratedFile(
3536
3803
  "[...routes]",
3537
3804
  "next-api-handler",
3538
- import_path6.default.join(...pagesDir, "api", "tina")
3805
+ import_path7.default.join(...pagesDir, "api", "tina")
3539
3806
  ),
3540
3807
  "reactive-example": await makeGeneratedFile(
3541
3808
  "[filename]",
3542
3809
  "reactive-example",
3543
- import_path6.default.join(...pagesDir, "demo", "blog"),
3810
+ import_path7.default.join(...pagesDir, "demo", "blog"),
3544
3811
  {
3545
3812
  typescriptSuffix: "tsx"
3546
3813
  }
@@ -3548,13 +3815,13 @@ var detectEnvironment = async ({
3548
3815
  "users-json": await makeGeneratedFile(
3549
3816
  "index",
3550
3817
  "users-json",
3551
- import_path6.default.join(baseDir, "content", "users"),
3818
+ import_path7.default.join(baseDir, "content", "users"),
3552
3819
  { extensionOverride: "json" }
3553
3820
  ),
3554
3821
  "sample-content": await makeGeneratedFile(
3555
3822
  "hello-world",
3556
3823
  "sample-content",
3557
- import_path6.default.join(baseDir, "content", "posts"),
3824
+ import_path7.default.join(baseDir, "content", "posts"),
3558
3825
  { extensionOverride: "md" }
3559
3826
  )
3560
3827
  };
@@ -3580,13 +3847,13 @@ var detectEnvironment = async ({
3580
3847
  );
3581
3848
  }
3582
3849
  }
3583
- const hasGitIgnore = await import_fs_extra8.default.pathExists(import_path6.default.join(".gitignore"));
3850
+ const hasGitIgnore = await import_fs_extra8.default.pathExists(import_path7.default.join(".gitignore"));
3584
3851
  const hasGitIgnoreNodeModules = hasGitIgnore && await checkGitignoreForItem({ baseDir, line: "node_modules" });
3585
3852
  const hasEnvTina = hasGitIgnore && await checkGitignoreForItem({ baseDir, line: ".env.tina" });
3586
3853
  const hasGitIgnoreEnv = hasGitIgnore && await checkGitignoreForItem({ baseDir, line: ".env" });
3587
3854
  let frontMatterFormat;
3588
3855
  if (hasForestryConfig) {
3589
- const hugoConfigPath = import_path6.default.join(rootPath, "config.toml");
3856
+ const hugoConfigPath = import_path7.default.join(rootPath, "config.toml");
3590
3857
  if (await import_fs_extra8.default.pathExists(hugoConfigPath)) {
3591
3858
  const hugoConfig = await import_fs_extra8.default.readFile(hugoConfigPath, "utf8");
3592
3859
  const metaDataFormat = (_a = hugoConfig.match(/metaDataFormat = "(.*)"/)) == null ? void 0 : _a[1];
@@ -3758,6 +4025,7 @@ var supportedDatabaseAdapters = {
3758
4025
  {
3759
4026
  from: "mongodb",
3760
4027
  imported: [],
4028
+ // not explicitly imported
3761
4029
  packageName: "mongodb"
3762
4030
  }
3763
4031
  ]
@@ -3830,6 +4098,10 @@ var chooseDatabaseAdapter = async ({
3830
4098
  title: "MongoDB",
3831
4099
  value: "mongodb"
3832
4100
  }
4101
+ // {
4102
+ // title: "I'll create my own database adapter",
4103
+ // value: 'other',
4104
+ // },
3833
4105
  ]
3834
4106
  }
3835
4107
  ]);
@@ -4107,6 +4379,7 @@ async function configure(env, opts) {
4107
4379
  packageManager,
4108
4380
  forestryMigrate: false,
4109
4381
  isLocalEnvVarName: "TINA_PUBLIC_IS_LOCAL",
4382
+ // TODO: give this a better default
4110
4383
  typescript: false
4111
4384
  };
4112
4385
  if (config2.framework.name === "next") {
@@ -4194,31 +4467,41 @@ var CLICommand = class {
4194
4467
  };
4195
4468
 
4196
4469
  // src/cmds/init/apply.ts
4197
- var import_path10 = __toESM(require("path"));
4470
+ var import_path11 = __toESM(require("path"));
4198
4471
 
4199
4472
  // src/cmds/forestry-migrate/index.ts
4200
4473
  var import_fs_extra10 = __toESM(require("fs-extra"));
4201
- var import_path8 = __toESM(require("path"));
4474
+ var import_path9 = __toESM(require("path"));
4202
4475
  var import_js_yaml2 = __toESM(require("js-yaml"));
4203
4476
  var import_minimatch = __toESM(require("minimatch"));
4204
4477
  var import_graphql16 = require("@tinacms/graphql");
4205
4478
 
4206
4479
  // src/cmds/forestry-migrate/util/index.ts
4207
4480
  var import_fs_extra9 = __toESM(require("fs-extra"));
4208
- var import_path7 = __toESM(require("path"));
4481
+ var import_path8 = __toESM(require("path"));
4209
4482
  var import_js_yaml = __toESM(require("js-yaml"));
4210
4483
  var import_zod = __toESM(require("zod"));
4211
4484
 
4212
4485
  // src/cmds/forestry-migrate/util/errorSingleton.ts
4213
- var ErrorSingleton = class {
4486
+ var ErrorSingleton = class _ErrorSingleton {
4487
+ /**
4488
+ * The Singleton's constructor should always be private to prevent direct
4489
+ * construction calls with the `new` operator.
4490
+ */
4214
4491
  constructor() {
4215
4492
  }
4493
+ /**
4494
+ * The static method that controls the access to the singleton instance.
4495
+ *
4496
+ * This implementation let you subclass the Singleton class while keeping
4497
+ * just one instance of each subclass around.
4498
+ */
4216
4499
  static getInstance() {
4217
- if (!ErrorSingleton.instance) {
4218
- ErrorSingleton.instance = new ErrorSingleton();
4219
- ErrorSingleton.instance.collectionNameErrors = [];
4500
+ if (!_ErrorSingleton.instance) {
4501
+ _ErrorSingleton.instance = new _ErrorSingleton();
4502
+ _ErrorSingleton.instance.collectionNameErrors = [];
4220
4503
  }
4221
- return ErrorSingleton.instance;
4504
+ return _ErrorSingleton.instance;
4222
4505
  }
4223
4506
  addErrorName(error) {
4224
4507
  this.collectionNameErrors.push(error);
@@ -4261,8 +4544,7 @@ var makeFieldsWithInternalCode = ({
4261
4544
  if (hasBody) {
4262
4545
  return [bodyField, `__TINA_INTERNAL__:::...${field}():::`];
4263
4546
  } else {
4264
- if (spread)
4265
- return `__TINA_INTERNAL__:::...${field}():::`;
4547
+ if (spread) return `__TINA_INTERNAL__:::...${field}():::`;
4266
4548
  return `__TINA_INTERNAL__:::${field}():::`;
4267
4549
  }
4268
4550
  };
@@ -4346,6 +4628,7 @@ var forestryConfigSchema = import_zod.default.object({
4346
4628
  )
4347
4629
  });
4348
4630
  var forestryFieldWithoutField = import_zod.default.object({
4631
+ // TODO: maybe better type this?
4349
4632
  type: import_zod.default.union([
4350
4633
  import_zod.default.literal("text"),
4351
4634
  import_zod.default.literal("datetime"),
@@ -4369,6 +4652,7 @@ var forestryFieldWithoutField = import_zod.default.object({
4369
4652
  default: import_zod.default.any().optional(),
4370
4653
  template: import_zod.default.string().optional(),
4371
4654
  config: import_zod.default.object({
4655
+ // min and max are used for lists
4372
4656
  min: import_zod.default.number().optional().nullable(),
4373
4657
  max: import_zod.default.number().optional().nullable(),
4374
4658
  required: import_zod.default.boolean().optional().nullable(),
@@ -4382,6 +4666,7 @@ var forestryFieldWithoutField = import_zod.default.object({
4382
4666
  import_zod.default.literal("pages"),
4383
4667
  import_zod.default.literal("documents"),
4384
4668
  import_zod.default.literal("simple"),
4669
+ // TODO: I want to ignore this key if its invalid
4385
4670
  import_zod.default.string()
4386
4671
  ]).optional().nullable(),
4387
4672
  section: import_zod.default.string().optional().nullable()
@@ -4417,6 +4702,7 @@ var transformForestryFieldsToTinaFields = ({
4417
4702
  }
4418
4703
  let field;
4419
4704
  switch (forestryField2.type) {
4705
+ // Single filed types
4420
4706
  case "text":
4421
4707
  field = {
4422
4708
  type: "string",
@@ -4496,6 +4782,7 @@ var transformForestryFieldsToTinaFields = ({
4496
4782
  );
4497
4783
  }
4498
4784
  break;
4785
+ // List Types
4499
4786
  case "list":
4500
4787
  field = {
4501
4788
  type: "string",
@@ -4518,6 +4805,7 @@ var transformForestryFieldsToTinaFields = ({
4518
4805
  }
4519
4806
  };
4520
4807
  break;
4808
+ // Object (Group) types
4521
4809
  case "field_group":
4522
4810
  field = {
4523
4811
  type: "object",
@@ -4558,6 +4846,7 @@ var transformForestryFieldsToTinaFields = ({
4558
4846
  });
4559
4847
  const fieldsString = stringifyLabelWithField(template2.label);
4560
4848
  const t = {
4849
+ // @ts-ignore
4561
4850
  fields: makeFieldsWithInternalCode({
4562
4851
  hasBody: false,
4563
4852
  field: fieldsString
@@ -4566,7 +4855,6 @@ var transformForestryFieldsToTinaFields = ({
4566
4855
  name: stringifyTemplateName(tem, tem)
4567
4856
  };
4568
4857
  if (t.name != tem) {
4569
- ;
4570
4858
  t.nameOverride = tem;
4571
4859
  }
4572
4860
  templates2.push(t);
@@ -4595,6 +4883,7 @@ var transformForestryFieldsToTinaFields = ({
4595
4883
  spread: true
4596
4884
  });
4597
4885
  tinaFields.push(
4886
+ // @ts-ignore
4598
4887
  field2
4599
4888
  );
4600
4889
  break;
@@ -4616,7 +4905,7 @@ var transformForestryFieldsToTinaFields = ({
4616
4905
  return tinaFields;
4617
4906
  };
4618
4907
  var getFieldsFromTemplates = ({ tem, pathToForestryConfig, skipBlocks = false }) => {
4619
- const templatePath = import_path7.default.join(
4908
+ const templatePath = import_path8.default.join(
4620
4909
  pathToForestryConfig,
4621
4910
  ".forestry",
4622
4911
  "front_matter",
@@ -4654,6 +4943,7 @@ var parseSections = ({ val }) => {
4654
4943
 
4655
4944
  // src/cmds/forestry-migrate/index.ts
4656
4945
  var BODY_FIELD = {
4946
+ // This is the body field
4657
4947
  type: "rich-text",
4658
4948
  name: "body",
4659
4949
  label: "Body of Document",
@@ -4691,8 +4981,8 @@ var generateAllTemplates = async ({
4691
4981
  pathToForestryConfig
4692
4982
  }) => {
4693
4983
  const allTemplates = (await import_fs_extra10.default.readdir(
4694
- import_path8.default.join(pathToForestryConfig, ".forestry", "front_matter", "templates")
4695
- )).map((tem) => import_path8.default.basename(tem, ".yml"));
4984
+ import_path9.default.join(pathToForestryConfig, ".forestry", "front_matter", "templates")
4985
+ )).map((tem) => import_path9.default.basename(tem, ".yml"));
4696
4986
  const templateMap = /* @__PURE__ */ new Map();
4697
4987
  const proms = allTemplates.map(async (tem) => {
4698
4988
  try {
@@ -4712,8 +5002,7 @@ var generateAllTemplates = async ({
4712
5002
  };
4713
5003
  var generateCollectionFromForestrySection = (args) => {
4714
5004
  const { section, templateMap } = args;
4715
- if (section.read_only)
4716
- return;
5005
+ if (section.read_only) return;
4717
5006
  let format3 = "md";
4718
5007
  if (section.new_doc_ext) {
4719
5008
  const ext = checkExt(section.new_doc_ext);
@@ -4780,12 +5069,14 @@ var generateCollectionFromForestrySection = (args) => {
4780
5069
  if (((forestryTemplates == null ? void 0 : forestryTemplates.length) || 0) > 1) {
4781
5070
  c = {
4782
5071
  ...baseCollection,
5072
+ // @ts-expect-error
4783
5073
  templates: forestryTemplates.map((tem) => {
4784
5074
  const currentTemplate = templateMap.get(tem);
4785
5075
  const fieldsString = stringifyLabelWithField(
4786
5076
  currentTemplate.templateObj.label
4787
5077
  );
4788
5078
  return {
5079
+ // fields: [BODY_FIELD],
4789
5080
  fields: makeFieldsWithInternalCode({
4790
5081
  hasBody,
4791
5082
  field: fieldsString,
@@ -4803,6 +5094,8 @@ var generateCollectionFromForestrySection = (args) => {
4803
5094
  const fieldsString = stringifyLabelWithField(template.templateObj.label);
4804
5095
  c = {
4805
5096
  ...baseCollection,
5097
+ // fields: [BODY_FIELD],
5098
+ // @ts-expect-error
4806
5099
  fields: makeFieldsWithInternalCode({
4807
5100
  field: fieldsString,
4808
5101
  hasBody,
@@ -4834,9 +5127,9 @@ var generateCollectionFromForestrySection = (args) => {
4834
5127
  return c;
4835
5128
  } else if (section.type === "document") {
4836
5129
  const filePath = section.path;
4837
- const extname = import_path8.default.extname(filePath);
4838
- const fileName = import_path8.default.basename(filePath, extname);
4839
- const dir = import_path8.default.dirname(filePath);
5130
+ const extname = import_path9.default.extname(filePath);
5131
+ const fileName = import_path9.default.basename(filePath, extname);
5132
+ const dir = import_path9.default.dirname(filePath);
4840
5133
  const ext = checkExt(extname);
4841
5134
  if (ext) {
4842
5135
  const fields = [];
@@ -4899,7 +5192,7 @@ var generateCollections = async ({
4899
5192
  usingTypescript
4900
5193
  });
4901
5194
  const forestryConfig = await import_fs_extra10.default.readFile(
4902
- import_path8.default.join(pathToForestryConfig, ".forestry", "settings.yml")
5195
+ import_path9.default.join(pathToForestryConfig, ".forestry", "settings.yml")
4903
5196
  );
4904
5197
  rewriteTemplateKeysInDocs({
4905
5198
  templateMap,
@@ -4930,11 +5223,11 @@ var rewriteTemplateKeysInDocs = (args) => {
4930
5223
  const { templateObj } = templateMap.get(templateKey);
4931
5224
  (_a = templateObj == null ? void 0 : templateObj.pages) == null ? void 0 : _a.forEach((page) => {
4932
5225
  try {
4933
- const filePath = import_path8.default.join(page);
5226
+ const filePath = import_path9.default.join(page);
4934
5227
  if (import_fs_extra10.default.lstatSync(filePath).isDirectory()) {
4935
5228
  return;
4936
5229
  }
4937
- const extname = import_path8.default.extname(filePath);
5230
+ const extname = import_path9.default.extname(filePath);
4938
5231
  const fileContent = import_fs_extra10.default.readFileSync(filePath).toString();
4939
5232
  const content = (0, import_graphql16.parseFile)(
4940
5233
  fileContent,
@@ -4966,7 +5259,7 @@ var import_fs_extra13 = __toESM(require("fs-extra"));
4966
5259
  // src/next/commands/codemod-command/index.ts
4967
5260
  var import_clipanion5 = require("clipanion");
4968
5261
  var import_fs_extra11 = __toESM(require("fs-extra"));
4969
- var import_path9 = __toESM(require("path"));
5262
+ var import_path10 = __toESM(require("path"));
4970
5263
  var CodemodCommand = class extends import_clipanion5.Command {
4971
5264
  constructor() {
4972
5265
  super(...arguments);
@@ -5010,7 +5303,7 @@ var moveTinaFolder = async (rootPath = process.cwd()) => {
5010
5303
  logger.error(e.message);
5011
5304
  process.exit(1);
5012
5305
  }
5013
- const tinaDestination = import_path9.default.join(configManager.rootPath, "tina");
5306
+ const tinaDestination = import_path10.default.join(configManager.rootPath, "tina");
5014
5307
  if (await import_fs_extra11.default.existsSync(tinaDestination)) {
5015
5308
  logger.info(
5016
5309
  `Folder already exists at ${tinaDestination}. Either delete this folder to complete the codemod, or ensure you have properly copied your config from the ".tina" folder.`
@@ -5025,7 +5318,7 @@ var moveTinaFolder = async (rootPath = process.cwd()) => {
5025
5318
  };
5026
5319
  var writeGitignore = async (rootPath) => {
5027
5320
  await import_fs_extra11.default.outputFileSync(
5028
- import_path9.default.join(rootPath, "tina", ".gitignore"),
5321
+ import_path10.default.join(rootPath, "tina", ".gitignore"),
5029
5322
  "__generated__"
5030
5323
  );
5031
5324
  };
@@ -5550,6 +5843,7 @@ var makeImportsVisitor = (sourceFile, importMap) => (ctx) => (node) => {
5550
5843
  ) : [];
5551
5844
  const newImports = [
5552
5845
  .../* @__PURE__ */ new Set([
5846
+ // we use Set to remove duplicates
5553
5847
  ...existingImports,
5554
5848
  ...imports
5555
5849
  ])
@@ -5704,10 +5998,14 @@ var addSelfHostedTinaAuthToConfig = async (config2, configFile) => {
5704
5998
  );
5705
5999
  const { configImports, configAuthProviderClass, extraTinaCollections } = config2.authProvider;
5706
6000
  const importMap = {
5707
- ...configImports.reduce((acc, { from, imported }) => {
5708
- acc[from] = imported;
5709
- return acc;
5710
- }, {})
6001
+ // iterate over configImports and add them to the import map
6002
+ ...configImports.reduce(
6003
+ (acc, { from, imported }) => {
6004
+ acc[from] = imported;
6005
+ return acc;
6006
+ },
6007
+ {}
6008
+ )
5711
6009
  };
5712
6010
  const transformedSourceFileResult = import_typescript3.default.transform(
5713
6011
  sourceFile,
@@ -5863,8 +6161,8 @@ async function apply({
5863
6161
  await addConfigFile({
5864
6162
  configArgs: {
5865
6163
  config: config2,
5866
- publicFolder: import_path10.default.join(
5867
- import_path10.default.relative(process.cwd(), pathToForestryConfig),
6164
+ publicFolder: import_path11.default.join(
6165
+ import_path11.default.relative(process.cwd(), pathToForestryConfig),
5868
6166
  config2.publicFolder
5869
6167
  ),
5870
6168
  collections,
@@ -5878,7 +6176,13 @@ async function apply({
5878
6176
  config: config2
5879
6177
  });
5880
6178
  }
5881
- if (env.tinaConfigExists && params.isBackendInit && config2.hosting === "self-host" && (((_a = config2.authProvider) == null ? void 0 : _a.name) || "") !== "tina-cloud") {
6179
+ if (
6180
+ // if the config was just generated we do not need to update the config file because it will be generated correctly
6181
+ env.tinaConfigExists && // Are we running tinacms init backend
6182
+ params.isBackendInit && // Do the user choose the 'self-host' option
6183
+ config2.hosting === "self-host" && // the user did not choose the 'tina-cloud' auth provider
6184
+ (((_a = config2.authProvider) == null ? void 0 : _a.name) || "") !== "tina-cloud"
6185
+ ) {
5882
6186
  await addSelfHostedTinaAuthToConfig(config2, env.generatedFiles["config"]);
5883
6187
  }
5884
6188
  logNextSteps({
@@ -5931,18 +6235,18 @@ var createPackageJSON = async () => {
5931
6235
  };
5932
6236
  var createGitignore = async ({ baseDir }) => {
5933
6237
  logger.info(logText("No .gitignore found, creating one"));
5934
- import_fs_extra13.default.outputFileSync(import_path10.default.join(baseDir, ".gitignore"), "node_modules");
6238
+ import_fs_extra13.default.outputFileSync(import_path11.default.join(baseDir, ".gitignore"), "node_modules");
5935
6239
  };
5936
6240
  var updateGitIgnore = async ({
5937
6241
  baseDir,
5938
6242
  items
5939
6243
  }) => {
5940
6244
  logger.info(logText(`Adding ${items.join(",")} to .gitignore`));
5941
- const gitignoreContent = import_fs_extra13.default.readFileSync(import_path10.default.join(baseDir, ".gitignore")).toString();
6245
+ const gitignoreContent = import_fs_extra13.default.readFileSync(import_path11.default.join(baseDir, ".gitignore")).toString();
5942
6246
  const newGitignoreContent = [...gitignoreContent.split("\n"), ...items].join(
5943
6247
  "\n"
5944
6248
  );
5945
- await import_fs_extra13.default.writeFile(import_path10.default.join(baseDir, ".gitignore"), newGitignoreContent);
6249
+ await import_fs_extra13.default.writeFile(import_path11.default.join(baseDir, ".gitignore"), newGitignoreContent);
5946
6250
  };
5947
6251
  var addDependencies = async (config2, env, params) => {
5948
6252
  var _a, _b, _c, _d, _e, _f, _g, _h, _i;
@@ -6012,22 +6316,22 @@ var writeGeneratedFile = async ({
6012
6316
  content,
6013
6317
  typescript
6014
6318
  }) => {
6015
- const { exists, path: path13, parentPath } = generatedFile.resolve(typescript);
6319
+ const { exists, path: path14, parentPath } = generatedFile.resolve(typescript);
6016
6320
  if (exists) {
6017
6321
  if (overwrite) {
6018
- logger.info(`Overwriting file at ${path13}... \u2705`);
6019
- import_fs_extra13.default.outputFileSync(path13, content);
6322
+ logger.info(`Overwriting file at ${path14}... \u2705`);
6323
+ import_fs_extra13.default.outputFileSync(path14, content);
6020
6324
  } else {
6021
- logger.info(`Not overwriting file at ${path13}.`);
6325
+ logger.info(`Not overwriting file at ${path14}.`);
6022
6326
  logger.info(
6023
- logText(`Please add the following to ${path13}:
6327
+ logText(`Please add the following to ${path14}:
6024
6328
  ${indentText(content)}}`)
6025
6329
  );
6026
6330
  }
6027
6331
  } else {
6028
- logger.info(`Adding file at ${path13}... \u2705`);
6332
+ logger.info(`Adding file at ${path14}... \u2705`);
6029
6333
  await import_fs_extra13.default.ensureDir(parentPath);
6030
- import_fs_extra13.default.outputFileSync(path13, content);
6334
+ import_fs_extra13.default.outputFileSync(path14, content);
6031
6335
  }
6032
6336
  };
6033
6337
  var addConfigFile = async ({
@@ -6110,7 +6414,7 @@ var addContentFile = async ({
6110
6414
  return () => ({
6111
6415
  exists: env.sampleContentExists,
6112
6416
  path: env.sampleContentPath,
6113
- parentPath: import_path10.default.dirname(env.sampleContentPath)
6417
+ parentPath: import_path11.default.dirname(env.sampleContentPath)
6114
6418
  });
6115
6419
  }
6116
6420
  },
@@ -6133,7 +6437,7 @@ ${titleText(" TinaCMS ")} backend initialized!`));
6133
6437
  return `${x.key}=${x.value || "***"}`;
6134
6438
  }).join("\n") + `
6135
6439
  TINA_PUBLIC_IS_LOCAL=true`;
6136
- const envFile = import_path10.default.join(process.cwd(), ".env");
6440
+ const envFile = import_path11.default.join(process.cwd(), ".env");
6137
6441
  if (!import_fs_extra13.default.existsSync(envFile)) {
6138
6442
  logger.info(`Adding .env file to your project... \u2705`);
6139
6443
  import_fs_extra13.default.writeFileSync(envFile, envFileText);
@@ -6156,6 +6460,13 @@ ${titleText(" TinaCMS ")} has been initialized!`));
6156
6460
  logger.info(
6157
6461
  "To get started run: " + cmdText(frameworkDevCmds[framework.name]({ packageManager }))
6158
6462
  );
6463
+ if (framework.name === "hugo") {
6464
+ logger.info(
6465
+ focusText("Hugo is required. "),
6466
+ "Don't have Hugo installed? Follow this guide to set it up: ",
6467
+ linkText("https://gohugo.io/installation/")
6468
+ );
6469
+ }
6159
6470
  logger.info(
6160
6471
  "To get your site production ready, run: " + cmdText(`tinacms init backend`)
6161
6472
  );
@@ -6171,6 +6482,7 @@ var other = ({ packageManager }) => {
6171
6482
  const packageManagers = {
6172
6483
  pnpm: `pnpm`,
6173
6484
  npm: `npx`,
6485
+ // npx is the way to run executables that aren't in your "scripts"
6174
6486
  yarn: `yarn`
6175
6487
  };
6176
6488
  return `${packageManagers[packageManager]} tinacms dev -c "<your dev command>"`;
@@ -6183,6 +6495,7 @@ var frameworkDevCmds = {
6183
6495
  const packageManagers = {
6184
6496
  pnpm: `pnpm`,
6185
6497
  npm: `npm run`,
6498
+ // npx is the way to run executables that aren't in your "scripts"
6186
6499
  yarn: `yarn`
6187
6500
  };
6188
6501
  return `${packageManagers[packageManager]} dev`;
@@ -6197,7 +6510,7 @@ var addReactiveFile = {
6197
6510
  dataLayer
6198
6511
  }) => {
6199
6512
  var _a, _b;
6200
- const packageJsonPath = import_path10.default.join(baseDir, "package.json");
6513
+ const packageJsonPath = import_path11.default.join(baseDir, "package.json");
6201
6514
  await writeGeneratedFile({
6202
6515
  generatedFile,
6203
6516
  typescript: config2.typescript,
@@ -6439,6 +6752,4 @@ cli.register(SearchIndexCommand);
6439
6752
  cli.register(import_clipanion8.Builtins.DefinitionsCommand);
6440
6753
  cli.register(import_clipanion8.Builtins.HelpCommand);
6441
6754
  cli.register(import_clipanion8.Builtins.VersionCommand);
6442
- var src_default = cli;
6443
- // Annotate the CommonJS export names for ESM import in node:
6444
- 0 && (module.exports = {});
6755
+ var index_default = cli;