@tinacms/cli 0.0.0-c72bb45-20241118014046 → 0.0.0-cef656e-20250119001929

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,6 +17,10 @@ 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
  ));
@@ -31,7 +35,7 @@ module.exports = __toCommonJS(src_exports);
31
35
  var import_clipanion8 = require("clipanion");
32
36
 
33
37
  // package.json
34
- var version = "1.6.11";
38
+ var version = "1.8.0";
35
39
 
36
40
  // src/next/commands/dev-command/index.ts
37
41
  var import_clipanion2 = require("clipanion");
@@ -57,7 +61,10 @@ function isUnicodeSupported() {
57
61
  if (process.platform !== "win32") {
58
62
  return process.env.TERM !== "linux";
59
63
  }
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";
64
+ return Boolean(process.env.CI) || Boolean(process.env.WT_SESSION) || // Windows Terminal
65
+ Boolean(process.env.TERMINUS_SUBLIME) || // Terminus (<0.2.27)
66
+ process.env.ConEmuTask === "{cmd::Cmder}" || // ConEmu and cmder
67
+ 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
68
  }
62
69
 
63
70
  // src/logger/index.ts
@@ -212,7 +219,7 @@ var ConfigManager = class {
212
219
  this.generatedCachePath = import_path.default.join(
213
220
  this.generatedFolderPath,
214
221
  ".cache",
215
- String(new Date().getTime())
222
+ String((/* @__PURE__ */ new Date()).getTime())
216
223
  );
217
224
  this.generatedGraphQLGQLPath = import_path.default.join(
218
225
  this.generatedFolderPath,
@@ -355,17 +362,22 @@ var ConfigManager = class {
355
362
  );
356
363
  }
357
364
  getTinaGraphQLVersion() {
358
- var _a, _b;
359
365
  if (this.tinaGraphQLVersionFromCLI) {
360
- return this.tinaGraphQLVersionFromCLI;
366
+ const version2 = this.tinaGraphQLVersionFromCLI.split(".");
367
+ return {
368
+ fullVersion: this.tinaGraphQLVersionFromCLI,
369
+ major: version2[0] || "x",
370
+ minor: version2[1] || "x",
371
+ patch: version2[2] || "x"
372
+ };
361
373
  }
362
374
  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")) {
375
+ if (!generatedSchema || !(typeof (generatedSchema == null ? void 0 : generatedSchema.version) !== "undefined")) {
364
376
  throw new Error(
365
377
  `Can not find Tina GraphQL version in ${this.generatedSchemaJSONPath}`
366
378
  );
367
379
  }
368
- return `${generatedSchema.version.major}.${generatedSchema.version.minor}`;
380
+ return generatedSchema.version;
369
381
  }
370
382
  printGeneratedClientFilePath() {
371
383
  if (this.isUsingTs()) {
@@ -394,6 +406,9 @@ var ConfigManager = class {
394
406
  }
395
407
  throw `No path provided to print`;
396
408
  }
409
+ /**
410
+ * Given a filepath without an extension, find the first match (eg. tsx, ts, jsx, js)
411
+ */
397
412
  async getPathWithExtension(filepath) {
398
413
  const extensions = ["tsx", "ts", "jsx", "js"];
399
414
  let result;
@@ -427,7 +442,10 @@ var ConfigManager = class {
427
442
  }
428
443
  async loadConfigFile(generatedFolderPath, configFilePath) {
429
444
  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");
445
+ const preBuildConfigPath = import_path.default.join(
446
+ this.generatedFolderPath,
447
+ "config.prebuild.jsx"
448
+ );
431
449
  const outfile = import_path.default.join(tmpdir, "config.build.jsx");
432
450
  const outfile2 = import_path.default.join(tmpdir, "config.build.js");
433
451
  const tempTSConfigFile = import_path.default.join(tmpdir, "tsconfig.json");
@@ -441,7 +459,7 @@ var ConfigManager = class {
441
459
  logLevel: "silent",
442
460
  packages: "external",
443
461
  ignoreAnnotations: true,
444
- outfile: prebuild,
462
+ outfile: preBuildConfigPath,
445
463
  loader: loaders,
446
464
  metafile: true
447
465
  });
@@ -464,6 +482,7 @@ var ConfigManager = class {
464
482
  await esbuild.build({
465
483
  entryPoints: [outfile],
466
484
  bundle: true,
485
+ // Suppress warning about comparison with -0 from client module
467
486
  logLevel: "silent",
468
487
  platform: "node",
469
488
  outfile: outfile2,
@@ -481,7 +500,7 @@ var ConfigManager = class {
481
500
  import_fs_extra.default.removeSync(outfile2);
482
501
  return {
483
502
  config: result.default,
484
- prebuildPath: prebuild,
503
+ prebuildPath: preBuildConfigPath,
485
504
  watchList: flattenedList
486
505
  };
487
506
  }
@@ -570,19 +589,19 @@ var devHTML = (port) => `<!DOCTYPE html>
570
589
  window.$RefreshReg$ = () => {}
571
590
  window.$RefreshSig$ = () => (type) => type
572
591
  window.__vite_plugin_react_preamble_installed__ = true
573
- <\/script>
574
- <script type="module" src="http://localhost:${port}/@vite/client"><\/script>
592
+ </script>
593
+ <script type="module" src="http://localhost:${port}/@vite/client"></script>
575
594
  <script>
576
595
  function handleLoadError() {
577
596
  // Assets have failed to load
578
597
  document.getElementById('root').innerHTML = '${errorHTML}';
579
598
  }
580
- <\/script>
599
+ </script>
581
600
  <script
582
601
  type="module"
583
602
  src="http://localhost:${port}/src/main.tsx"
584
603
  onerror="handleLoadError()"
585
- ><\/script>
604
+ ></script>
586
605
  <body class="tina-tailwind">
587
606
  <div id="root"></div>
588
607
  </body>
@@ -628,6 +647,7 @@ var import_defaultTheme = __toESM(require("tailwindcss/defaultTheme.js"));
628
647
  var tinaTailwind = (spaPath, prebuildFilePath) => {
629
648
  return {
630
649
  name: "vite-plugin-tina",
650
+ // @ts-ignore
631
651
  config: (viteConfig) => {
632
652
  const plugins = [];
633
653
  const content = [
@@ -939,7 +959,6 @@ async function listFilesRecursively({
939
959
  }
940
960
  var createConfig = async ({
941
961
  configManager,
942
- database,
943
962
  apiURL,
944
963
  plugins = [],
945
964
  noWatch,
@@ -999,6 +1018,8 @@ var createConfig = async ({
999
1018
  if (configManager.config.build.basePath) {
1000
1019
  basePath = configManager.config.build.basePath;
1001
1020
  }
1021
+ const fullVersion = configManager.getTinaGraphQLVersion();
1022
+ const version2 = `${fullVersion.major}.${fullVersion.minor}`;
1002
1023
  const config2 = {
1003
1024
  root: configManager.spaRootPath,
1004
1025
  base: `/${basePath ? `${(0, import_normalize_path2.default)(basePath)}/` : ""}${(0, import_normalize_path2.default)(
@@ -1010,15 +1031,33 @@ var createConfig = async ({
1010
1031
  dedupe: ["graphql", "tinacms", "react", "react-dom", "react-router-dom"]
1011
1032
  },
1012
1033
  define: {
1034
+ /**
1035
+ * Since we prebuild the config.ts, it's possible for modules to be loaded which make
1036
+ * use of `process`. The main scenario where this is an issue is when co-locating schema
1037
+ * definitions with source files, and specifically source files which impor from NextJS.
1038
+ *
1039
+ * Some examples of what NextJS uses for `process.env` are:
1040
+ * - `process.env.__NEXT_TRAILING_SLASH`
1041
+ * - `process.env.__NEXT_CROSS_ORIGIN`
1042
+ * - `process.env.__NEXT_I18N_SUPPORT`
1043
+ *
1044
+ * Also, interestingly some of the advice for handling this doesn't work, references to replacing
1045
+ * `process.env` with `{}` are problematic, because browsers don't understand the `{}.` syntax,
1046
+ * but node does. This was a surprise, but using `new Object()` seems to do the trick.
1047
+ */
1013
1048
  "process.env": `new Object(${JSON.stringify(publicEnv)})`,
1049
+ // Used by picomatch https://github.com/micromatch/picomatch/blob/master/lib/utils.js#L4
1014
1050
  "process.platform": `"${process.platform}"`,
1015
1051
  __API_URL__: `"${apiURL}"`,
1016
1052
  __BASE_PATH__: `"${((_e = (_d = configManager.config) == null ? void 0 : _d.build) == null ? void 0 : _e.basePath) || ""}"`,
1017
- __TINA_GRAPHQL_VERSION__: `"${configManager.getTinaGraphQLVersion()}"`
1053
+ __TINA_GRAPHQL_VERSION__: version2
1018
1054
  },
1019
1055
  logLevel: "error",
1056
+ // Vite import warnings are noisy
1020
1057
  optimizeDeps: {
1021
1058
  force: true,
1059
+ // Not 100% sure why this isn't being picked up automatically, this works from within the monorepo
1060
+ // but breaks externally
1022
1061
  include: ["react/jsx-runtime", "react/jsx-dev-runtime"]
1023
1062
  },
1024
1063
  server: {
@@ -1026,6 +1065,7 @@ var createConfig = async ({
1026
1065
  watch: noWatch ? {
1027
1066
  ignored: ["**/*"]
1028
1067
  } : {
1068
+ // Ignore everything except for the alias fields we specified above
1029
1069
  ignored: [
1030
1070
  `${configManager.tinaFolderPath}/**/!(config.prebuild.jsx|_graphql.json)`
1031
1071
  ]
@@ -1041,8 +1081,13 @@ var createConfig = async ({
1041
1081
  rollupOptions
1042
1082
  },
1043
1083
  plugins: [
1084
+ /**
1085
+ * `splitVendorChunkPlugin` is needed because `tinacms` is quite large,
1086
+ * Vite's chunking strategy chokes on memory issues for smaller machines (ie. on CI).
1087
+ */
1044
1088
  (0, import_plugin_react.default)({
1045
1089
  babel: {
1090
+ // Supresses the warning [NOTE] babel The code generator has deoptimised the styling of
1046
1091
  compact: true
1047
1092
  }
1048
1093
  }),
@@ -1119,8 +1164,7 @@ var createMediaRouter = (config2) => {
1119
1164
  };
1120
1165
  var parseMediaFolder = (str) => {
1121
1166
  let returnString = str;
1122
- if (returnString.startsWith("/"))
1123
- returnString = returnString.substr(1);
1167
+ if (returnString.startsWith("/")) returnString = returnString.substr(1);
1124
1168
  if (returnString.endsWith("/"))
1125
1169
  returnString = returnString.substr(0, returnString.length - 1);
1126
1170
  return returnString;
@@ -1387,6 +1431,7 @@ function viteTransformExtension({
1387
1431
  return {
1388
1432
  code: res.code,
1389
1433
  map: null
1434
+ // TODO:
1390
1435
  };
1391
1436
  }
1392
1437
  }
@@ -1407,6 +1452,14 @@ var createDevServer = async (configManager, database, searchIndex, apiURL, noWat
1407
1452
  apiURL,
1408
1453
  plugins,
1409
1454
  noWatch,
1455
+ /**
1456
+ * Ensure Vite's import scan uses the spaMainPath as the input
1457
+ * so it properly finds everything. This is for dev only, and when
1458
+ * running the server outside of this monorepo vite fails to find
1459
+ * and optimize the imports, so you get errors about it not being
1460
+ * able to find an export from a module, and it's always a CJS
1461
+ * module that Vite would usually transform to an ES module.
1462
+ */
1410
1463
  rollupOptions: {
1411
1464
  input: configManager.spaMainPath,
1412
1465
  onwarn(warning, warn) {
@@ -1532,6 +1585,7 @@ var GenericSdkVisitor = class extends import_visitor_plugin_common.ClientSideBas
1532
1585
  node,
1533
1586
  documentVariableName,
1534
1587
  operationType,
1588
+ // This is the only line that is different
1535
1589
  operationResultType: `{data: ${operationResultType}, errors?: { message: string, locations: { line: number, column: number }[], path: string[] }[], variables: ${operationVariablesTypes}, query: string}`,
1536
1590
  operationVariablesTypes
1537
1591
  });
@@ -1580,6 +1634,8 @@ var plugin = (schema, documents, config2) => {
1580
1634
  const visitor = new GenericSdkVisitor(schema, allFragments, config2);
1581
1635
  const visitorResult = (0, import_graphql3.visit)(allAst, { leave: visitor });
1582
1636
  return {
1637
+ // We will take care of imports
1638
+ // prepend: visitor.getImports(),
1583
1639
  content: [
1584
1640
  visitor.fragments,
1585
1641
  ...visitorResult.definitions.filter((t) => typeof t === "string"),
@@ -1595,6 +1651,7 @@ var generateTypes = async (schema, queryPathGlob = process.cwd(), fragDocPath =
1595
1651
  docs = await loadGraphQLDocuments(queryPathGlob);
1596
1652
  fragDocs = await loadGraphQLDocuments(fragDocPath);
1597
1653
  const res = await (0, import_core.codegen)({
1654
+ // Filename is not used. This is because the typescript plugin returns a string instead of writing to a file.
1598
1655
  filename: process.cwd(),
1599
1656
  schema: (0, import_graphql5.parse)((0, import_graphql5.printSchema)(schema)),
1600
1657
  documents: [...docs, ...fragDocs],
@@ -1629,9 +1686,12 @@ var loadGraphQLDocuments = async (globPath) => {
1629
1686
  loaders: [new import_graphql_file_loader.GraphQLFileLoader()]
1630
1687
  });
1631
1688
  } catch (e) {
1632
- if ((e.message || "").includes(
1633
- "Unable to find any GraphQL type definitions for the following pointers:"
1634
- )) {
1689
+ if (
1690
+ // https://www.graphql-tools.com/docs/documents-loading#no-files-found
1691
+ (e.message || "").includes(
1692
+ "Unable to find any GraphQL type definitions for the following pointers:"
1693
+ )
1694
+ ) {
1635
1695
  } else {
1636
1696
  throw e;
1637
1697
  }
@@ -1788,16 +1848,14 @@ var Codegen = class {
1788
1848
  const branch = (_a = this.configManager.config) == null ? void 0 : _a.branch;
1789
1849
  const clientId = (_b = this.configManager.config) == null ? void 0 : _b.clientId;
1790
1850
  const token = (_c = this.configManager.config) == null ? void 0 : _c.token;
1791
- const version2 = this.configManager.getTinaGraphQLVersion();
1851
+ const fullVersion = this.configManager.getTinaGraphQLVersion();
1852
+ const version2 = `${fullVersion.major}.${fullVersion.minor}`;
1792
1853
  const baseUrl = ((_d = this.configManager.config.tinaioConfig) == null ? void 0 : _d.contentApiUrlOverride) || `https://${TINA_HOST}`;
1793
1854
  if ((!branch || !clientId || !token) && !this.port && !this.configManager.config.contentApiUrlOverride) {
1794
1855
  const missing = [];
1795
- if (!branch)
1796
- missing.push("branch");
1797
- if (!clientId)
1798
- missing.push("clientId");
1799
- if (!token)
1800
- missing.push("token");
1856
+ if (!branch) missing.push("branch");
1857
+ if (!clientId) missing.push("clientId");
1858
+ if (!token) missing.push("token");
1801
1859
  throw new Error(
1802
1860
  `Client not configured properly. Missing ${missing.join(
1803
1861
  ", "
@@ -1951,7 +2009,11 @@ schema {
1951
2009
  }
1952
2010
  };
1953
2011
  var maybeWarnFragmentSize = async (filepath) => {
1954
- if ((await import_fs_extra4.default.stat(filepath)).size > 100 * 1024) {
2012
+ if (
2013
+ // is the file bigger than 100kb?
2014
+ (await import_fs_extra4.default.stat(filepath)).size > // convert to 100 kb to bytes
2015
+ 100 * 1024
2016
+ ) {
1955
2017
  console.warn(
1956
2018
  "Warning: frags.gql is very large (>100kb). Consider setting the reference depth to 1 or 0. See code snippet below."
1957
2019
  );
@@ -1979,6 +2041,7 @@ var import_many_level = require("many-level");
1979
2041
  var import_memory_level = require("memory-level");
1980
2042
  var createDBServer = (port) => {
1981
2043
  const levelHost = new import_many_level.ManyLevelHost(
2044
+ // @ts-ignore
1982
2045
  new import_memory_level.MemoryLevel({
1983
2046
  valueEncoding: "json"
1984
2047
  })
@@ -2253,6 +2316,7 @@ var import_search = require("@tinacms/search");
2253
2316
  var DevCommand = class extends BaseCommand {
2254
2317
  constructor() {
2255
2318
  super(...arguments);
2319
+ // NOTE: camelCase commands for string options don't work if there's an `=` used https://github.com/arcanis/clipanion/issues/141
2256
2320
  this.watchFolders = import_clipanion2.Option.String("-w,--watchFolders", {
2257
2321
  description: "DEPRECATED - a list of folders (relative to where this is being run) that the cli will watch for changes"
2258
2322
  });
@@ -2471,6 +2535,20 @@ ${dangerText(e.message)}
2471
2535
  heading: "Tina Dev Server is running...",
2472
2536
  items: [
2473
2537
  ...summaryItems
2538
+ // {
2539
+ // emoji: '📚',
2540
+ // heading: 'Useful links',
2541
+ // subItems: [
2542
+ // {
2543
+ // key: 'Custom queries',
2544
+ // value: 'https://tina.io/querying',
2545
+ // },
2546
+ // {
2547
+ // key: 'Visual editing',
2548
+ // value: 'https://tina.io/visual-editing',
2549
+ // },
2550
+ // ],
2551
+ // },
2474
2552
  ]
2475
2553
  });
2476
2554
  await this.startSubCommand();
@@ -2582,7 +2660,7 @@ var buildProductionSpa = async (configManager, database, apiURL) => {
2582
2660
  // src/next/commands/build-command/index.ts
2583
2661
  var import_schema_tools2 = require("@tinacms/schema-tools");
2584
2662
  var import_graphql12 = require("graphql");
2585
- var import_core2 = require("@graphql-inspector/core");
2663
+ var import_core3 = require("@graphql-inspector/core");
2586
2664
 
2587
2665
  // src/next/commands/build-command/waitForDB.ts
2588
2666
  var import_progress = __toESM(require("progress"));
@@ -2684,6 +2762,20 @@ var waitForDB = async (config2, apiUrl, previewName, verbose) => {
2684
2762
 
2685
2763
  // src/next/commands/build-command/index.ts
2686
2764
  var import_search2 = require("@tinacms/search");
2765
+
2766
+ // src/utils/index.ts
2767
+ var import_core2 = require("@graphql-inspector/core");
2768
+ var getFaqLink = (type) => {
2769
+ switch (type) {
2770
+ case import_core2.ChangeType.FieldRemoved: {
2771
+ return "https://tina.io/docs/introduction/faq#how-do-i-resolve-the-local-graphql-schema-doesnt-match-the-remote-graphql-schema-errors";
2772
+ }
2773
+ default:
2774
+ return null;
2775
+ }
2776
+ };
2777
+
2778
+ // src/next/commands/build-command/index.ts
2687
2779
  var BuildCommand = class extends BaseCommand {
2688
2780
  constructor() {
2689
2781
  super(...arguments);
@@ -2699,6 +2791,9 @@ var BuildCommand = class extends BaseCommand {
2699
2791
  this.tinaGraphQLVersion = import_clipanion3.Option.String("--tina-graphql-version", {
2700
2792
  description: "Specify the version of @tinacms/graphql to use (defaults to latest)"
2701
2793
  });
2794
+ /**
2795
+ * 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
2796
+ */
2702
2797
  this.skipCloudChecks = import_clipanion3.Option.Boolean("--skip-cloud-checks", false, {
2703
2798
  description: "Skips checking the provided cloud config."
2704
2799
  });
@@ -2811,7 +2906,7 @@ ${dangerText(e.message)}
2811
2906
  }
2812
2907
  const skipCloudChecks = this.skipCloudChecks || configManager.hasSelfHostedConfig();
2813
2908
  if (!skipCloudChecks) {
2814
- const { hasUpstream } = await this.checkClientInfo(
2909
+ const { hasUpstream, timestamp } = await this.checkClientInfo(
2815
2910
  configManager,
2816
2911
  codegen2.productionUrl,
2817
2912
  this.previewBaseBranch
@@ -2839,14 +2934,16 @@ ${dangerText(e.message)}
2839
2934
  await this.checkGraphqlSchema(
2840
2935
  configManager,
2841
2936
  database,
2842
- codegen2.productionUrl
2937
+ codegen2.productionUrl,
2938
+ timestamp
2843
2939
  );
2844
2940
  await this.checkTinaSchema(
2845
2941
  configManager,
2846
2942
  database,
2847
2943
  codegen2.productionUrl,
2848
2944
  this.previewName,
2849
- this.verbose
2945
+ this.verbose,
2946
+ timestamp
2850
2947
  );
2851
2948
  }
2852
2949
  await buildProductionSpa(configManager, database, codegen2.productionUrl);
@@ -2965,11 +3062,13 @@ ${dangerText(e.message)}
2965
3062
  const bar2 = new import_progress2.default("Checking clientId and token. :prog", 1);
2966
3063
  let branchKnown = false;
2967
3064
  let hasUpstream = false;
3065
+ let timestamp;
2968
3066
  try {
2969
3067
  const res = await request({
2970
3068
  token,
2971
3069
  url
2972
3070
  });
3071
+ timestamp = res.timestamp || 0;
2973
3072
  bar2.tick({
2974
3073
  prog: "\u2705"
2975
3074
  });
@@ -3011,7 +3110,8 @@ ${dangerText(e.message)}
3011
3110
  prog: "\u2705"
3012
3111
  });
3013
3112
  return {
3014
- hasUpstream
3113
+ hasUpstream,
3114
+ timestamp
3015
3115
  };
3016
3116
  }
3017
3117
  for (let i = 0; i <= 5; i++) {
@@ -3101,14 +3201,14 @@ ${dangerText(e.message)}
3101
3201
  throw e;
3102
3202
  }
3103
3203
  }
3104
- async checkGraphqlSchema(configManager, database, apiURL) {
3204
+ async checkGraphqlSchema(configManager, database, apiURL, timestamp) {
3105
3205
  const bar2 = new import_progress2.default(
3106
3206
  "Checking local GraphQL Schema matches server. :prog",
3107
3207
  1
3108
3208
  );
3109
3209
  const { config: config2 } = configManager;
3110
3210
  const token = config2.token;
3111
- const remoteSchema = await fetchRemoteGraphqlSchema({
3211
+ const { remoteSchema, remoteProjectVersion } = await fetchRemoteGraphqlSchema({
3112
3212
  url: apiURL,
3113
3213
  token
3114
3214
  });
@@ -3128,7 +3228,7 @@ Additional info: Branch: ${config2.branch}, Client ID: ${config2.clientId} `;
3128
3228
  const localSchemaDocument = await database.getGraphQLSchemaFromBridge();
3129
3229
  const localGraphqlSchema = (0, import_graphql12.buildASTSchema)(localSchemaDocument);
3130
3230
  try {
3131
- const diffResult = await (0, import_core2.diff)(localGraphqlSchema, remoteGqlSchema);
3231
+ const diffResult = await (0, import_core3.diff)(localGraphqlSchema, remoteGqlSchema);
3132
3232
  if (diffResult.length === 0) {
3133
3233
  bar2.tick({
3134
3234
  prog: "\u2705"
@@ -3137,12 +3237,30 @@ Additional info: Branch: ${config2.branch}, Client ID: ${config2.clientId} `;
3137
3237
  bar2.tick({
3138
3238
  prog: "\u274C"
3139
3239
  });
3140
- 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.`;
3141
- if (config2 == null ? void 0 : config2.branch) {
3142
- errorMessage += `
3240
+ const type = diffResult[0].type;
3241
+ const reason = diffResult[0].message;
3242
+ const errorLevel = diffResult[0].criticality.level;
3243
+ const faqLink = getFaqLink(type);
3244
+ const tinaGraphQLVersion = configManager.getTinaGraphQLVersion();
3245
+ 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 && `
3246
+ Check out '${faqLink}' for possible solutions.`}`;
3247
+ errorMessage += `
3143
3248
 
3144
- Additional info: Branch: ${config2.branch}, Client ID: ${config2.clientId} `;
3249
+ Additional info:
3250
+
3251
+ `;
3252
+ if (config2 == null ? void 0 : config2.branch) {
3253
+ errorMessage += ` Branch: ${config2.branch}, Client ID: ${config2.clientId}
3254
+ `;
3145
3255
  }
3256
+ errorMessage += ` Local GraphQL version: ${tinaGraphQLVersion.fullVersion} / Remote GraphQL version: ${remoteProjectVersion}
3257
+ `;
3258
+ errorMessage += ` Last indexed at: ${new Date(
3259
+ timestamp
3260
+ ).toUTCString()}
3261
+ `;
3262
+ errorMessage += ` Reason: [${errorLevel} - ${type}] ${reason}
3263
+ `;
3146
3264
  throw new Error(errorMessage);
3147
3265
  }
3148
3266
  } catch (e) {
@@ -3157,7 +3275,7 @@ Additional info: Branch: ${config2.branch}, Client ID: ${config2.clientId} `;
3157
3275
  }
3158
3276
  }
3159
3277
  }
3160
- async checkTinaSchema(configManager, database, apiURL, previewName, verbose) {
3278
+ async checkTinaSchema(configManager, database, apiURL, previewName, verbose, timestamp) {
3161
3279
  const bar2 = new import_progress2.default(
3162
3280
  "Checking local Tina Schema matches server. :prog",
3163
3281
  1
@@ -3206,11 +3324,19 @@ Additional info: Branch: ${config2.branch}, Client ID: ${config2.clientId} `;
3206
3324
  prog: "\u274C"
3207
3325
  });
3208
3326
  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.`;
3209
- if (config2 == null ? void 0 : config2.branch) {
3210
- errorMessage += `
3327
+ errorMessage += `
3211
3328
 
3212
- Additional info: Branch: ${config2.branch}, Client ID: ${config2.clientId} `;
3329
+ Additional info:
3330
+
3331
+ `;
3332
+ if (config2 == null ? void 0 : config2.branch) {
3333
+ errorMessage += ` Branch: ${config2.branch}, Client ID: ${config2.clientId}
3334
+ `;
3213
3335
  }
3336
+ errorMessage += ` Last indexed at: ${new Date(
3337
+ timestamp
3338
+ ).toUTCString()}
3339
+ `;
3214
3340
  throw new Error(errorMessage);
3215
3341
  }
3216
3342
  }
@@ -3280,7 +3406,11 @@ var fetchRemoteGraphqlSchema = async ({
3280
3406
  body
3281
3407
  });
3282
3408
  const data = await res.json();
3283
- return data == null ? void 0 : data.data;
3409
+ return {
3410
+ remoteSchema: data == null ? void 0 : data.data,
3411
+ remoteRuntimeVersion: res.headers.get("tinacms-grapqhl-version"),
3412
+ remoteProjectVersion: res.headers.get("tinacms-graphql-project-version")
3413
+ };
3284
3414
  };
3285
3415
  var fetchSchemaSha = async ({
3286
3416
  url,
@@ -3404,6 +3534,7 @@ var auditDocuments = async (args) => {
3404
3534
  logger.error(import_chalk5.default.red(err.message));
3405
3535
  if (err.originalError.originalError) {
3406
3536
  logger.error(
3537
+ // @ts-ignore FIXME: this doesn't seem right
3407
3538
  import_chalk5.default.red(` ${err.originalError.originalError.message}`)
3408
3539
  );
3409
3540
  }
@@ -3609,7 +3740,9 @@ var detectEnvironment = async ({
3609
3740
  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")));
3610
3741
  const tinaFolder = import_path7.default.join(baseDir, "tina");
3611
3742
  const tinaConfigExists = Boolean(
3612
- await import_fs_extra8.default.pathExists(tinaFolder) && (await import_fs_extra8.default.readdir(tinaFolder)).find((x) => x.includes("config"))
3743
+ // Does the tina folder exist?
3744
+ await import_fs_extra8.default.pathExists(tinaFolder) && // Does the tina folder contain a config file?
3745
+ (await import_fs_extra8.default.readdir(tinaFolder)).find((x) => x.includes("config"))
3613
3746
  );
3614
3747
  const pagesDir = [baseDir, usingSrc ? "src" : false, "pages"].filter(
3615
3748
  Boolean
@@ -3844,6 +3977,7 @@ var supportedDatabaseAdapters = {
3844
3977
  {
3845
3978
  from: "mongodb",
3846
3979
  imported: [],
3980
+ // not explicitly imported
3847
3981
  packageName: "mongodb"
3848
3982
  }
3849
3983
  ]
@@ -3916,6 +4050,10 @@ var chooseDatabaseAdapter = async ({
3916
4050
  title: "MongoDB",
3917
4051
  value: "mongodb"
3918
4052
  }
4053
+ // {
4054
+ // title: "I'll create my own database adapter",
4055
+ // value: 'other',
4056
+ // },
3919
4057
  ]
3920
4058
  }
3921
4059
  ]);
@@ -4193,6 +4331,7 @@ async function configure(env, opts) {
4193
4331
  packageManager,
4194
4332
  forestryMigrate: false,
4195
4333
  isLocalEnvVarName: "TINA_PUBLIC_IS_LOCAL",
4334
+ // TODO: give this a better default
4196
4335
  typescript: false
4197
4336
  };
4198
4337
  if (config2.framework.name === "next") {
@@ -4296,15 +4435,25 @@ var import_js_yaml = __toESM(require("js-yaml"));
4296
4435
  var import_zod = __toESM(require("zod"));
4297
4436
 
4298
4437
  // src/cmds/forestry-migrate/util/errorSingleton.ts
4299
- var ErrorSingleton = class {
4438
+ var ErrorSingleton = class _ErrorSingleton {
4439
+ /**
4440
+ * The Singleton's constructor should always be private to prevent direct
4441
+ * construction calls with the `new` operator.
4442
+ */
4300
4443
  constructor() {
4301
4444
  }
4445
+ /**
4446
+ * The static method that controls the access to the singleton instance.
4447
+ *
4448
+ * This implementation let you subclass the Singleton class while keeping
4449
+ * just one instance of each subclass around.
4450
+ */
4302
4451
  static getInstance() {
4303
- if (!ErrorSingleton.instance) {
4304
- ErrorSingleton.instance = new ErrorSingleton();
4305
- ErrorSingleton.instance.collectionNameErrors = [];
4452
+ if (!_ErrorSingleton.instance) {
4453
+ _ErrorSingleton.instance = new _ErrorSingleton();
4454
+ _ErrorSingleton.instance.collectionNameErrors = [];
4306
4455
  }
4307
- return ErrorSingleton.instance;
4456
+ return _ErrorSingleton.instance;
4308
4457
  }
4309
4458
  addErrorName(error) {
4310
4459
  this.collectionNameErrors.push(error);
@@ -4347,8 +4496,7 @@ var makeFieldsWithInternalCode = ({
4347
4496
  if (hasBody) {
4348
4497
  return [bodyField, `__TINA_INTERNAL__:::...${field}():::`];
4349
4498
  } else {
4350
- if (spread)
4351
- return `__TINA_INTERNAL__:::...${field}():::`;
4499
+ if (spread) return `__TINA_INTERNAL__:::...${field}():::`;
4352
4500
  return `__TINA_INTERNAL__:::${field}():::`;
4353
4501
  }
4354
4502
  };
@@ -4432,6 +4580,7 @@ var forestryConfigSchema = import_zod.default.object({
4432
4580
  )
4433
4581
  });
4434
4582
  var forestryFieldWithoutField = import_zod.default.object({
4583
+ // TODO: maybe better type this?
4435
4584
  type: import_zod.default.union([
4436
4585
  import_zod.default.literal("text"),
4437
4586
  import_zod.default.literal("datetime"),
@@ -4455,6 +4604,7 @@ var forestryFieldWithoutField = import_zod.default.object({
4455
4604
  default: import_zod.default.any().optional(),
4456
4605
  template: import_zod.default.string().optional(),
4457
4606
  config: import_zod.default.object({
4607
+ // min and max are used for lists
4458
4608
  min: import_zod.default.number().optional().nullable(),
4459
4609
  max: import_zod.default.number().optional().nullable(),
4460
4610
  required: import_zod.default.boolean().optional().nullable(),
@@ -4468,6 +4618,7 @@ var forestryFieldWithoutField = import_zod.default.object({
4468
4618
  import_zod.default.literal("pages"),
4469
4619
  import_zod.default.literal("documents"),
4470
4620
  import_zod.default.literal("simple"),
4621
+ // TODO: I want to ignore this key if its invalid
4471
4622
  import_zod.default.string()
4472
4623
  ]).optional().nullable(),
4473
4624
  section: import_zod.default.string().optional().nullable()
@@ -4503,6 +4654,7 @@ var transformForestryFieldsToTinaFields = ({
4503
4654
  }
4504
4655
  let field;
4505
4656
  switch (forestryField2.type) {
4657
+ // Single filed types
4506
4658
  case "text":
4507
4659
  field = {
4508
4660
  type: "string",
@@ -4582,6 +4734,7 @@ var transformForestryFieldsToTinaFields = ({
4582
4734
  );
4583
4735
  }
4584
4736
  break;
4737
+ // List Types
4585
4738
  case "list":
4586
4739
  field = {
4587
4740
  type: "string",
@@ -4604,6 +4757,7 @@ var transformForestryFieldsToTinaFields = ({
4604
4757
  }
4605
4758
  };
4606
4759
  break;
4760
+ // Object (Group) types
4607
4761
  case "field_group":
4608
4762
  field = {
4609
4763
  type: "object",
@@ -4644,6 +4798,7 @@ var transformForestryFieldsToTinaFields = ({
4644
4798
  });
4645
4799
  const fieldsString = stringifyLabelWithField(template2.label);
4646
4800
  const t = {
4801
+ // @ts-ignore
4647
4802
  fields: makeFieldsWithInternalCode({
4648
4803
  hasBody: false,
4649
4804
  field: fieldsString
@@ -4681,6 +4836,7 @@ var transformForestryFieldsToTinaFields = ({
4681
4836
  spread: true
4682
4837
  });
4683
4838
  tinaFields.push(
4839
+ // @ts-ignore
4684
4840
  field2
4685
4841
  );
4686
4842
  break;
@@ -4740,6 +4896,7 @@ var parseSections = ({ val }) => {
4740
4896
 
4741
4897
  // src/cmds/forestry-migrate/index.ts
4742
4898
  var BODY_FIELD = {
4899
+ // This is the body field
4743
4900
  type: "rich-text",
4744
4901
  name: "body",
4745
4902
  label: "Body of Document",
@@ -4798,8 +4955,7 @@ var generateAllTemplates = async ({
4798
4955
  };
4799
4956
  var generateCollectionFromForestrySection = (args) => {
4800
4957
  const { section, templateMap } = args;
4801
- if (section.read_only)
4802
- return;
4958
+ if (section.read_only) return;
4803
4959
  let format3 = "md";
4804
4960
  if (section.new_doc_ext) {
4805
4961
  const ext = checkExt(section.new_doc_ext);
@@ -4866,12 +5022,14 @@ var generateCollectionFromForestrySection = (args) => {
4866
5022
  if (((forestryTemplates == null ? void 0 : forestryTemplates.length) || 0) > 1) {
4867
5023
  c = {
4868
5024
  ...baseCollection,
5025
+ // @ts-expect-error
4869
5026
  templates: forestryTemplates.map((tem) => {
4870
5027
  const currentTemplate = templateMap.get(tem);
4871
5028
  const fieldsString = stringifyLabelWithField(
4872
5029
  currentTemplate.templateObj.label
4873
5030
  );
4874
5031
  return {
5032
+ // fields: [BODY_FIELD],
4875
5033
  fields: makeFieldsWithInternalCode({
4876
5034
  hasBody,
4877
5035
  field: fieldsString,
@@ -4889,6 +5047,8 @@ var generateCollectionFromForestrySection = (args) => {
4889
5047
  const fieldsString = stringifyLabelWithField(template.templateObj.label);
4890
5048
  c = {
4891
5049
  ...baseCollection,
5050
+ // fields: [BODY_FIELD],
5051
+ // @ts-expect-error
4892
5052
  fields: makeFieldsWithInternalCode({
4893
5053
  field: fieldsString,
4894
5054
  hasBody,
@@ -5636,6 +5796,7 @@ var makeImportsVisitor = (sourceFile, importMap) => (ctx) => (node) => {
5636
5796
  ) : [];
5637
5797
  const newImports = [
5638
5798
  .../* @__PURE__ */ new Set([
5799
+ // we use Set to remove duplicates
5639
5800
  ...existingImports,
5640
5801
  ...imports
5641
5802
  ])
@@ -5790,6 +5951,7 @@ var addSelfHostedTinaAuthToConfig = async (config2, configFile) => {
5790
5951
  );
5791
5952
  const { configImports, configAuthProviderClass, extraTinaCollections } = config2.authProvider;
5792
5953
  const importMap = {
5954
+ // iterate over configImports and add them to the import map
5793
5955
  ...configImports.reduce((acc, { from, imported }) => {
5794
5956
  acc[from] = imported;
5795
5957
  return acc;
@@ -5964,7 +6126,13 @@ async function apply({
5964
6126
  config: config2
5965
6127
  });
5966
6128
  }
5967
- if (env.tinaConfigExists && params.isBackendInit && config2.hosting === "self-host" && (((_a = config2.authProvider) == null ? void 0 : _a.name) || "") !== "tina-cloud") {
6129
+ if (
6130
+ // if the config was just generated we do not need to update the config file because it will be generated correctly
6131
+ env.tinaConfigExists && // Are we running tinacms init backend
6132
+ params.isBackendInit && // Do the user choose the 'self-host' option
6133
+ config2.hosting === "self-host" && // the user did not choose the 'tina-cloud' auth provider
6134
+ (((_a = config2.authProvider) == null ? void 0 : _a.name) || "") !== "tina-cloud"
6135
+ ) {
5968
6136
  await addSelfHostedTinaAuthToConfig(config2, env.generatedFiles["config"]);
5969
6137
  }
5970
6138
  logNextSteps({
@@ -6257,6 +6425,7 @@ var other = ({ packageManager }) => {
6257
6425
  const packageManagers = {
6258
6426
  pnpm: `pnpm`,
6259
6427
  npm: `npx`,
6428
+ // npx is the way to run executables that aren't in your "scripts"
6260
6429
  yarn: `yarn`
6261
6430
  };
6262
6431
  return `${packageManagers[packageManager]} tinacms dev -c "<your dev command>"`;
@@ -6269,6 +6438,7 @@ var frameworkDevCmds = {
6269
6438
  const packageManagers = {
6270
6439
  pnpm: `pnpm`,
6271
6440
  npm: `npm run`,
6441
+ // npx is the way to run executables that aren't in your "scripts"
6272
6442
  yarn: `yarn`
6273
6443
  };
6274
6444
  return `${packageManagers[packageManager]} dev`;
@@ -6526,5 +6696,3 @@ cli.register(import_clipanion8.Builtins.DefinitionsCommand);
6526
6696
  cli.register(import_clipanion8.Builtins.HelpCommand);
6527
6697
  cli.register(import_clipanion8.Builtins.VersionCommand);
6528
6698
  var src_default = cli;
6529
- // Annotate the CommonJS export names for ESM import in node:
6530
- 0 && (module.exports = {});
@@ -21,19 +21,24 @@ export declare class BuildCommand extends BaseCommand {
21
21
  execute(): Promise<number | void>;
22
22
  checkClientInfo(configManager: ConfigManager, apiURL: string, previewBaseBranch?: string): Promise<{
23
23
  hasUpstream: boolean;
24
+ timestamp: number;
24
25
  }>;
25
26
  syncProject(configManager: ConfigManager, apiURL: string, options?: {
26
27
  upstreamBranch?: string;
27
28
  previewBaseBranch?: string;
28
29
  previewName?: string;
29
30
  }): Promise<void>;
30
- checkGraphqlSchema(configManager: ConfigManager, database: Database, apiURL: string): Promise<void>;
31
- checkTinaSchema(configManager: ConfigManager, database: Database, apiURL: string, previewName: string, verbose: boolean): Promise<void>;
31
+ checkGraphqlSchema(configManager: ConfigManager, database: Database, apiURL: string, timestamp: number): Promise<void>;
32
+ checkTinaSchema(configManager: ConfigManager, database: Database, apiURL: string, previewName: string, verbose: boolean, timestamp: number): Promise<void>;
32
33
  }
33
34
  export declare const fetchRemoteGraphqlSchema: ({ url, token, }: {
34
35
  url: string;
35
36
  token?: string;
36
- }) => Promise<any>;
37
+ }) => Promise<{
38
+ remoteSchema: any;
39
+ remoteRuntimeVersion: string;
40
+ remoteProjectVersion: string;
41
+ }>;
37
42
  export declare const fetchSchemaSha: ({ url, token, }: {
38
43
  url: string;
39
44
  token?: string;
@@ -55,7 +55,12 @@ export declare class ConfigManager {
55
55
  shouldSkipSDK(): boolean;
56
56
  processConfig(): Promise<void>;
57
57
  getTinaFolderPath(rootPath: any): Promise<string>;
58
- getTinaGraphQLVersion(): string;
58
+ getTinaGraphQLVersion(): {
59
+ fullVersion: string;
60
+ major: string;
61
+ minor: string;
62
+ patch: string;
63
+ };
59
64
  printGeneratedClientFilePath(): string;
60
65
  printGeneratedTypesFilePath(): string;
61
66
  printoutputHTMLFilePath(): string;
@@ -22,7 +22,7 @@ interface StaticMediaItem {
22
22
  export interface StaticMedia {
23
23
  [offset: string]: StaticMediaItem[];
24
24
  }
25
- export declare const createConfig: ({ configManager, database, apiURL, plugins, noWatch, rollupOptions, }: {
25
+ export declare const createConfig: ({ configManager, apiURL, plugins, noWatch, rollupOptions, }: {
26
26
  configManager: ConfigManager;
27
27
  database: Database;
28
28
  apiURL: string;
@@ -1,4 +1,6 @@
1
1
  /**
2
2
 
3
3
  */
4
+ import { ChangeType } from '@graphql-inspector/core';
4
5
  export declare const parseMediaFolder: (str: string) => string;
6
+ export declare const getFaqLink: (type: ChangeType) => string | null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tinacms/cli",
3
- "version": "0.0.0-c72bb45-20241118014046",
3
+ "version": "0.0.0-cef656e-20250119001929",
4
4
  "main": "dist/index.js",
5
5
  "typings": "dist/index.d.ts",
6
6
  "files": [
@@ -37,7 +37,7 @@
37
37
  "@types/prompts": "^2.4.9",
38
38
  "@types/yup": "^0.32.0",
39
39
  "jest": "^29.7.0",
40
- "@tinacms/scripts": "0.0.0-c72bb45-20241118014046"
40
+ "@tinacms/scripts": "1.3.1"
41
41
  },
42
42
  "dependencies": {
43
43
  "@graphql-codegen/core": "^2.6.8",
@@ -65,7 +65,7 @@
65
65
  "cors": "^2.8.5",
66
66
  "crypto-js": "^4.2.0",
67
67
  "dotenv": "^16.4.5",
68
- "esbuild": "^0.18.20",
68
+ "esbuild": "^0.24.0",
69
69
  "fs-extra": "^11.2.0",
70
70
  "graphql": "15.8.0",
71
71
  "js-yaml": "^4.1.0",
@@ -84,12 +84,12 @@
84
84
  "vite": "^4.5.5",
85
85
  "yup": "^1.4.0",
86
86
  "zod": "^3.23.8",
87
- "@tinacms/app": "0.0.0-c72bb45-20241118014046",
88
- "@tinacms/schema-tools": "0.0.0-c72bb45-20241118014046",
89
- "@tinacms/search": "0.0.0-c72bb45-20241118014046",
90
- "tinacms": "0.0.0-c72bb45-20241118014046",
91
- "@tinacms/graphql": "0.0.0-c72bb45-20241118014046",
92
- "@tinacms/metrics": "0.0.0-c72bb45-20241118014046"
87
+ "@tinacms/app": "0.0.0-cef656e-20250119001929",
88
+ "@tinacms/graphql": "0.0.0-cef656e-20250119001929",
89
+ "@tinacms/metrics": "1.0.8",
90
+ "@tinacms/schema-tools": "1.7.0",
91
+ "@tinacms/search": "0.0.0-cef656e-20250119001929",
92
+ "tinacms": "0.0.0-cef656e-20250119001929"
93
93
  },
94
94
  "publishConfig": {
95
95
  "registry": "https://registry.npmjs.org"
@@ -98,9 +98,6 @@
98
98
  "url": "https://github.com/tinacms/tinacms.git",
99
99
  "directory": "packages/@tinacms/cli"
100
100
  },
101
- "overrides": {
102
- "dompurify": "2.5.7"
103
- },
104
101
  "scripts": {
105
102
  "build": "tinacms-scripts build",
106
103
  "test": "jest --passWithNoTests",