@tinacms/cli 2.2.4 → 2.2.6

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
@@ -2,16 +2,16 @@
2
2
  import { Cli, Builtins } from "clipanion";
3
3
 
4
4
  // package.json
5
- var version = "2.2.4";
5
+ var version = "2.2.6";
6
6
 
7
7
  // src/next/commands/dev-command/index.ts
8
- import path8 from "path";
8
+ import path9 from "path";
9
9
  import { FilesystemBridge as FilesystemBridge2, buildSchema } from "@tinacms/graphql";
10
10
  import { LocalSearchIndexClient, SearchIndexer } from "@tinacms/search";
11
11
  import AsyncLock from "async-lock";
12
12
  import chokidar from "chokidar";
13
13
  import { Command as Command2, Option as Option2 } from "clipanion";
14
- import fs7 from "fs-extra";
14
+ import fs8 from "fs-extra";
15
15
 
16
16
  // src/logger/index.ts
17
17
  import chalk from "chalk";
@@ -691,7 +691,7 @@ var Codegen = class {
691
691
  import { resolve } from "@tinacms/datalayer";
692
692
  import type { TinaClient } from "tinacms/dist/client";
693
693
 
694
- import { queries } from "./types";
694
+ import { queries } from "${this.configManager.isUsingTs() ? "./types.ts" : "./types.js"}";
695
695
  import database from "../database";
696
696
 
697
697
  export async function databaseRequest({ query, variables, user }) {
@@ -757,7 +757,7 @@ export default databaseClient;
757
757
  const errorPolicy = this.configManager.config?.client?.errorPolicy;
758
758
  const apiURL = this.getApiURL();
759
759
  const clientString = `import { createClient } from "tinacms/dist/client";
760
- import { queries } from "./types";
760
+ import { queries } from "${this.configManager.isUsingTs() ? "./types.ts" : "./types.js"}";
761
761
  export const client = createClient({ ${this.noClientBuildCache === false ? `cacheDir: '${normalizePath(
762
762
  this.configManager.generatedCachePath
763
763
  )}', ` : ""}url: ${this.localContentBuild ? `process.env.TINA_LOCAL_URL || '${apiURL}'` : `'${apiURL}'`}, token: '${token}', queries, ${errorPolicy ? `errorPolicy: '${errorPolicy}'` : ""} });
@@ -819,16 +819,22 @@ var unlinkIfExists = async (filepath) => {
819
819
  };
820
820
 
821
821
  // src/next/config-manager.ts
822
- import fs2 from "fs-extra";
823
- import path3 from "path";
822
+ import fs3 from "fs-extra";
823
+ import path4 from "path";
824
824
  import os from "os";
825
825
  import { pathToFileURL } from "url";
826
826
  import * as esbuild from "esbuild";
827
827
  import * as dotenv from "dotenv";
828
828
  import normalizePath2 from "normalize-path";
829
- import chalk3 from "chalk";
829
+ import chalk4 from "chalk";
830
830
  import { createRequire } from "module";
831
831
 
832
+ // src/next/resolve-content-root.ts
833
+ import fs2 from "fs-extra";
834
+ import path3 from "path";
835
+ import chalk3 from "chalk";
836
+ import { z } from "zod";
837
+
832
838
  // src/utils/path.ts
833
839
  import path2 from "path";
834
840
  function stripNativeTrailingSlash(p) {
@@ -848,6 +854,33 @@ var PathTraversalError = class extends Error {
848
854
  }
849
855
  };
850
856
 
857
+ // src/next/resolve-content-root.ts
858
+ var localContentPathSchema = z.string().min(1).optional();
859
+ async function resolveContentRootPath(params) {
860
+ const localContentPath = localContentPathSchema.parse(
861
+ params.localContentPath
862
+ );
863
+ if (!localContentPath) {
864
+ return params.rootPath;
865
+ }
866
+ const fullLocalContentPath = stripNativeTrailingSlash(
867
+ path3.join(params.tinaFolderPath, localContentPath)
868
+ );
869
+ const exists = await fs2.pathExists(fullLocalContentPath);
870
+ if (exists) {
871
+ logger.info(`Using separate content repo at ${fullLocalContentPath}`);
872
+ return fullLocalContentPath;
873
+ }
874
+ logger.warn(
875
+ `${chalk3.yellow("Warning:")} The localContentPath ${chalk3.cyan(
876
+ fullLocalContentPath
877
+ )} does not exist. Please create it or remove the localContentPath from your config file at ${chalk3.cyan(
878
+ params.tinaConfigFilePath
879
+ )}`
880
+ );
881
+ return params.rootPath;
882
+ }
883
+
851
884
  // src/next/config-manager.ts
852
885
  var TINA_FOLDER = "tina";
853
886
  var LEGACY_TINA_FOLDER = ".tina";
@@ -861,6 +894,7 @@ var ConfigManager = class {
861
894
  rootPath;
862
895
  tinaFolderPath;
863
896
  isUsingLegacyFolder;
897
+ hasWarnedLegacyFolder = false;
864
898
  tinaConfigFilePath;
865
899
  tinaSpaPackagePath;
866
900
  contentRootPath;
@@ -907,7 +941,7 @@ var ConfigManager = class {
907
941
  this.legacyNoSDK = legacyNoSDK;
908
942
  }
909
943
  isUsingTs() {
910
- return [".ts", ".tsx"].includes(path3.extname(this.tinaConfigFilePath));
944
+ return [".ts", ".tsx"].includes(path4.extname(this.tinaConfigFilePath));
911
945
  }
912
946
  hasSelfHostedConfig() {
913
947
  return !!this.selfHostedDatabaseFilePath;
@@ -924,12 +958,20 @@ var ConfigManager = class {
924
958
  async processConfig() {
925
959
  const require2 = createRequire(import.meta.url);
926
960
  this.tinaFolderPath = await this.getTinaFolderPath(this.rootPath);
927
- this.envFilePath = path3.resolve(
928
- path3.join(this.tinaFolderPath, "..", ".env")
961
+ if (this.isUsingLegacyFolder && !this.hasWarnedLegacyFolder) {
962
+ this.hasWarnedLegacyFolder = true;
963
+ logger.warn(
964
+ warnText(
965
+ "WARN: Detected legacy `.tina/` config folder. `tina-lock.json` is only generated for the new `tina/` layout, and TinaCloud requires it to index your schema. Migrate by renaming `.tina/` to `tina/` (the contents stay the same). See https://tina.io/docs/tina-folder/overview/."
966
+ )
967
+ );
968
+ }
969
+ this.envFilePath = path4.resolve(
970
+ path4.join(this.tinaFolderPath, "..", ".env")
929
971
  );
930
972
  dotenv.config({ path: this.envFilePath });
931
973
  this.tinaConfigFilePath = await this.getPathWithExtension(
932
- path3.join(this.tinaFolderPath, "config")
974
+ path4.join(this.tinaFolderPath, "config")
933
975
  );
934
976
  if (!this.tinaConfigFilePath) {
935
977
  throw new Error(
@@ -937,89 +979,89 @@ var ConfigManager = class {
937
979
  );
938
980
  }
939
981
  this.selfHostedDatabaseFilePath = await this.getPathWithExtension(
940
- path3.join(this.tinaFolderPath, "database")
982
+ path4.join(this.tinaFolderPath, "database")
941
983
  );
942
- this.generatedFolderPath = path3.join(this.tinaFolderPath, GENERATED_FOLDER);
943
- this.generatedCachePath = path3.join(
984
+ this.generatedFolderPath = path4.join(this.tinaFolderPath, GENERATED_FOLDER);
985
+ this.generatedCachePath = path4.join(
944
986
  this.generatedFolderPath,
945
987
  ".cache",
946
988
  String((/* @__PURE__ */ new Date()).getTime())
947
989
  );
948
- this.generatedGraphQLGQLPath = path3.join(
990
+ this.generatedGraphQLGQLPath = path4.join(
949
991
  this.generatedFolderPath,
950
992
  GRAPHQL_GQL_FILE
951
993
  );
952
- this.generatedGraphQLJSONPath = path3.join(
994
+ this.generatedGraphQLJSONPath = path4.join(
953
995
  this.generatedFolderPath,
954
996
  GRAPHQL_JSON_FILE
955
997
  );
956
- this.generatedSchemaJSONPath = path3.join(
998
+ this.generatedSchemaJSONPath = path4.join(
957
999
  this.generatedFolderPath,
958
1000
  SCHEMA_JSON_FILE
959
1001
  );
960
- this.generatedLookupJSONPath = path3.join(
1002
+ this.generatedLookupJSONPath = path4.join(
961
1003
  this.generatedFolderPath,
962
1004
  LOOKUP_JSON_FILE
963
1005
  );
964
- this.generatedQueriesFilePath = path3.join(
1006
+ this.generatedQueriesFilePath = path4.join(
965
1007
  this.generatedFolderPath,
966
1008
  "queries.gql"
967
1009
  );
968
- this.generatedFragmentsFilePath = path3.join(
1010
+ this.generatedFragmentsFilePath = path4.join(
969
1011
  this.generatedFolderPath,
970
1012
  "frags.gql"
971
1013
  );
972
- this.generatedTypesTSFilePath = path3.join(
1014
+ this.generatedTypesTSFilePath = path4.join(
973
1015
  this.generatedFolderPath,
974
1016
  "types.ts"
975
1017
  );
976
- this.generatedTypesJSFilePath = path3.join(
1018
+ this.generatedTypesJSFilePath = path4.join(
977
1019
  this.generatedFolderPath,
978
1020
  "types.js"
979
1021
  );
980
- this.generatedTypesDFilePath = path3.join(
1022
+ this.generatedTypesDFilePath = path4.join(
981
1023
  this.generatedFolderPath,
982
1024
  "types.d.ts"
983
1025
  );
984
- this.userQueriesAndFragmentsGlob = path3.join(
1026
+ this.userQueriesAndFragmentsGlob = path4.join(
985
1027
  this.tinaFolderPath,
986
1028
  "queries/**/*.{graphql,gql}"
987
1029
  );
988
- this.generatedQueriesAndFragmentsGlob = path3.join(
1030
+ this.generatedQueriesAndFragmentsGlob = path4.join(
989
1031
  this.generatedFolderPath,
990
1032
  "*.{graphql,gql}"
991
1033
  );
992
- this.generatedClientTSFilePath = path3.join(
1034
+ this.generatedClientTSFilePath = path4.join(
993
1035
  this.generatedFolderPath,
994
1036
  "client.ts"
995
1037
  );
996
- this.generatedClientJSFilePath = path3.join(
1038
+ this.generatedClientJSFilePath = path4.join(
997
1039
  this.generatedFolderPath,
998
1040
  "client.js"
999
1041
  );
1000
- this.generatedClientDFilePath = path3.join(
1042
+ this.generatedClientDFilePath = path4.join(
1001
1043
  this.generatedFolderPath,
1002
1044
  "client.d.ts"
1003
1045
  );
1004
- this.generatedDatabaseClientDFilePath = path3.join(
1046
+ this.generatedDatabaseClientDFilePath = path4.join(
1005
1047
  this.generatedFolderPath,
1006
1048
  "databaseClient.d.ts"
1007
1049
  );
1008
- this.generatedDatabaseClientTSFilePath = path3.join(
1050
+ this.generatedDatabaseClientTSFilePath = path4.join(
1009
1051
  this.generatedFolderPath,
1010
1052
  "databaseClient.ts"
1011
1053
  );
1012
- this.generatedDatabaseClientJSFilePath = path3.join(
1054
+ this.generatedDatabaseClientJSFilePath = path4.join(
1013
1055
  this.generatedFolderPath,
1014
1056
  "databaseClient.js"
1015
1057
  );
1016
- const clientExists = this.isUsingTs() ? await fs2.pathExists(this.generatedClientTSFilePath) : await fs2.pathExists(this.generatedClientJSFilePath);
1058
+ const clientExists = this.isUsingTs() ? await fs3.pathExists(this.generatedClientTSFilePath) : await fs3.pathExists(this.generatedClientJSFilePath);
1017
1059
  if (!clientExists) {
1018
1060
  const file = "export default ()=>({})\nexport const client = ()=>({})";
1019
1061
  if (this.isUsingTs()) {
1020
- await fs2.outputFile(this.generatedClientTSFilePath, file);
1062
+ await fs3.outputFile(this.generatedClientTSFilePath, file);
1021
1063
  } else {
1022
- await fs2.outputFile(this.generatedClientJSFilePath, file);
1064
+ await fs3.outputFile(this.generatedClientJSFilePath, file);
1023
1065
  }
1024
1066
  }
1025
1067
  const { config: config2, prebuildPath, watchList } = await this.loadConfigFile(
@@ -1029,62 +1071,47 @@ var ConfigManager = class {
1029
1071
  this.watchList = watchList;
1030
1072
  this.config = config2;
1031
1073
  this.prebuildFilePath = prebuildPath;
1032
- this.publicFolderPath = path3.join(
1074
+ this.publicFolderPath = path4.join(
1033
1075
  this.rootPath,
1034
1076
  this.config.build.publicFolder
1035
1077
  );
1036
- this.outputFolderPath = path3.join(
1078
+ this.outputFolderPath = path4.join(
1037
1079
  this.publicFolderPath,
1038
1080
  this.config.build.outputFolder
1039
1081
  );
1040
- this.outputHTMLFilePath = path3.join(this.outputFolderPath, "index.html");
1041
- this.outputGitignorePath = path3.join(this.outputFolderPath, ".gitignore");
1042
- const fullLocalContentPath = stripNativeTrailingSlash(
1043
- path3.join(this.tinaFolderPath, this.config.localContentPath || "")
1044
- );
1045
- if (this.config.localContentPath) {
1046
- const localContentPathExists = await fs2.pathExists(fullLocalContentPath);
1047
- if (localContentPathExists) {
1048
- logger.info(`Using separate content repo at ${fullLocalContentPath}`);
1049
- this.contentRootPath = fullLocalContentPath;
1050
- } else {
1051
- logger.warn(
1052
- `${chalk3.yellow("Warning:")} The localContentPath ${chalk3.cyan(
1053
- fullLocalContentPath
1054
- )} does not exist. Please create it or remove the localContentPath from your config file at ${chalk3.cyan(
1055
- this.tinaConfigFilePath
1056
- )}`
1057
- );
1058
- }
1059
- }
1060
- if (!this.contentRootPath) {
1061
- this.contentRootPath = this.rootPath;
1062
- }
1063
- this.generatedFolderPathContentRepo = path3.join(
1082
+ this.outputHTMLFilePath = path4.join(this.outputFolderPath, "index.html");
1083
+ this.outputGitignorePath = path4.join(this.outputFolderPath, ".gitignore");
1084
+ this.contentRootPath = await resolveContentRootPath({
1085
+ rootPath: this.rootPath,
1086
+ tinaFolderPath: this.tinaFolderPath,
1087
+ tinaConfigFilePath: this.tinaConfigFilePath,
1088
+ localContentPath: this.config.localContentPath
1089
+ });
1090
+ this.generatedFolderPathContentRepo = path4.join(
1064
1091
  await this.getTinaFolderPath(this.contentRootPath, {
1065
1092
  isContentRoot: this.hasSeparateContentRoot()
1066
1093
  }),
1067
1094
  GENERATED_FOLDER
1068
1095
  );
1069
1096
  this.spaMainPath = require2.resolve("@tinacms/app");
1070
- this.spaRootPath = path3.join(this.spaMainPath, "..", "..");
1097
+ this.spaRootPath = path4.join(this.spaMainPath, "..", "..");
1071
1098
  }
1072
1099
  async getTinaFolderPath(rootPath, { isContentRoot } = {}) {
1073
- const tinaFolderPath = path3.join(rootPath, TINA_FOLDER);
1074
- const tinaFolderExists = await fs2.pathExists(tinaFolderPath);
1100
+ const tinaFolderPath = path4.join(rootPath, TINA_FOLDER);
1101
+ const tinaFolderExists = await fs3.pathExists(tinaFolderPath);
1075
1102
  if (tinaFolderExists) {
1076
1103
  this.isUsingLegacyFolder = false;
1077
1104
  return tinaFolderPath;
1078
1105
  }
1079
- const legacyFolderPath = path3.join(rootPath, LEGACY_TINA_FOLDER);
1080
- const legacyFolderExists = await fs2.pathExists(legacyFolderPath);
1106
+ const legacyFolderPath = path4.join(rootPath, LEGACY_TINA_FOLDER);
1107
+ const legacyFolderExists = await fs3.pathExists(legacyFolderPath);
1081
1108
  if (legacyFolderExists) {
1082
1109
  this.isUsingLegacyFolder = true;
1083
1110
  return legacyFolderPath;
1084
1111
  }
1085
1112
  if (isContentRoot) {
1086
1113
  throw new Error(
1087
- `Unable to find a ${chalk3.cyan("tina/")} folder in your content root at ${chalk3.cyan(rootPath)}. When using localContentPath, the content directory must contain a ${chalk3.cyan("tina/")} folder for generated files. Create one with: mkdir ${path3.join(rootPath, TINA_FOLDER)}`
1114
+ `Unable to find a ${chalk4.cyan("tina/")} folder in your content root at ${chalk4.cyan(rootPath)}. When using localContentPath, the content directory must contain a ${chalk4.cyan("tina/")} folder for generated files. Create one with: mkdir ${path4.join(rootPath, TINA_FOLDER)}`
1088
1115
  );
1089
1116
  }
1090
1117
  throw new Error(
@@ -1101,7 +1128,7 @@ var ConfigManager = class {
1101
1128
  patch: version2[2] || "x"
1102
1129
  };
1103
1130
  }
1104
- const generatedSchema = fs2.readJSONSync(this.generatedSchemaJSONPath);
1131
+ const generatedSchema = fs3.readJSONSync(this.generatedSchemaJSONPath);
1105
1132
  if (!generatedSchema || !(typeof generatedSchema?.version !== "undefined")) {
1106
1133
  throw new Error(
1107
1134
  `Can not find Tina GraphQL version in ${this.generatedSchemaJSONPath}`
@@ -1111,28 +1138,41 @@ var ConfigManager = class {
1111
1138
  }
1112
1139
  printGeneratedClientFilePath() {
1113
1140
  if (this.isUsingTs()) {
1114
- return this.generatedClientTSFilePath.replace(`${this.rootPath}/`, "");
1141
+ return normalizePath2(
1142
+ path4.relative(this.rootPath, this.generatedClientTSFilePath)
1143
+ );
1115
1144
  }
1116
- return this.generatedClientJSFilePath.replace(`${this.rootPath}/`, "");
1145
+ return normalizePath2(
1146
+ path4.relative(this.rootPath, this.generatedClientJSFilePath)
1147
+ );
1117
1148
  }
1118
1149
  printGeneratedTypesFilePath() {
1119
- return this.generatedTypesTSFilePath.replace(`${this.rootPath}/`, "");
1150
+ return normalizePath2(
1151
+ path4.relative(this.rootPath, this.generatedTypesTSFilePath)
1152
+ );
1120
1153
  }
1121
1154
  printoutputHTMLFilePath() {
1122
- return this.outputHTMLFilePath.replace(`${this.publicFolderPath}/`, "");
1155
+ return normalizePath2(
1156
+ path4.relative(this.publicFolderPath, this.outputHTMLFilePath)
1157
+ );
1123
1158
  }
1124
1159
  printRelativePath(filename) {
1125
1160
  if (filename) {
1126
- return filename.replace(/\\/g, "/").replace(`${this.rootPath}/`, "");
1161
+ return normalizePath2(path4.relative(this.rootPath, filename));
1127
1162
  }
1128
1163
  throw `No path provided to print`;
1129
1164
  }
1130
1165
  printPrebuildFilePath() {
1131
- return this.prebuildFilePath.replace(/\\/g, "/").replace(`${this.rootPath}/${this.tinaFolderPath}/`, "");
1166
+ return normalizePath2(
1167
+ path4.relative(
1168
+ path4.join(this.rootPath, this.tinaFolderPath),
1169
+ this.prebuildFilePath
1170
+ )
1171
+ );
1132
1172
  }
1133
1173
  printContentRelativePath(filename) {
1134
1174
  if (filename) {
1135
- return filename.replace(/\\/g, "/").replace(`${this.contentRootPath}/`, "");
1175
+ return normalizePath2(path4.relative(this.contentRootPath, filename));
1136
1176
  }
1137
1177
  throw `No path provided to print`;
1138
1178
  }
@@ -1148,7 +1188,7 @@ var ConfigManager = class {
1148
1188
  return;
1149
1189
  }
1150
1190
  const filepathWithExtension = `${filepath}.${ext}`;
1151
- const exists = fs2.existsSync(filepathWithExtension);
1191
+ const exists = fs3.existsSync(filepathWithExtension);
1152
1192
  if (exists) {
1153
1193
  result = filepathWithExtension;
1154
1194
  }
@@ -1157,8 +1197,8 @@ var ConfigManager = class {
1157
1197
  return result;
1158
1198
  }
1159
1199
  async loadDatabaseFile() {
1160
- const tmpdir = path3.join(os.tmpdir(), Date.now().toString());
1161
- const outfile = path3.join(tmpdir, "database.build.mjs");
1200
+ const tmpdir = path4.join(os.tmpdir(), Date.now().toString());
1201
+ const outfile = path4.join(tmpdir, "database.build.mjs");
1162
1202
  await esbuild.build({
1163
1203
  entryPoints: [this.selfHostedDatabaseFilePath],
1164
1204
  bundle: true,
@@ -1176,22 +1216,22 @@ var ConfigManager = class {
1176
1216
  }
1177
1217
  });
1178
1218
  const result = await import(pathToFileURL(outfile).href);
1179
- fs2.removeSync(outfile);
1219
+ fs3.removeSync(outfile);
1180
1220
  return result.default;
1181
1221
  }
1182
1222
  async loadConfigFile(generatedFolderPath, configFilePath) {
1183
- const tmpdir = path3.join(os.tmpdir(), Date.now().toString());
1184
- const preBuildConfigPath = path3.join(
1223
+ const tmpdir = path4.join(os.tmpdir(), Date.now().toString());
1224
+ const preBuildConfigPath = path4.join(
1185
1225
  this.generatedFolderPath,
1186
1226
  "config.prebuild.jsx"
1187
1227
  );
1188
- const outfile = path3.join(tmpdir, "config.build.jsx");
1189
- const outfile2 = path3.join(tmpdir, "config.build.mjs");
1190
- const tempTSConfigFile = path3.join(tmpdir, "tsconfig.json");
1228
+ const outfile = path4.join(tmpdir, "config.build.jsx");
1229
+ const outfile2 = path4.join(tmpdir, "config.build.mjs");
1230
+ const tempTSConfigFile = path4.join(tmpdir, "tsconfig.json");
1191
1231
  const esmRequireBanner = {
1192
1232
  js: `import { createRequire } from 'module';const require = createRequire(import.meta.url);`
1193
1233
  };
1194
- fs2.outputFileSync(tempTSConfigFile, "{}");
1234
+ fs3.outputFileSync(tempTSConfigFile, "{}");
1195
1235
  const result2 = await esbuild.build({
1196
1236
  entryPoints: [configFilePath],
1197
1237
  bundle: true,
@@ -1241,8 +1281,8 @@ var ConfigManager = class {
1241
1281
  console.error(e);
1242
1282
  throw e;
1243
1283
  }
1244
- fs2.removeSync(outfile);
1245
- fs2.removeSync(outfile2);
1284
+ fs3.removeSync(outfile);
1285
+ fs3.removeSync(outfile2);
1246
1286
  return {
1247
1287
  config: result.default,
1248
1288
  prebuildPath: preBuildConfigPath,
@@ -1333,7 +1373,7 @@ async function createAndInitializeDatabase(configManager, datalayerPort, bridgeO
1333
1373
 
1334
1374
  // src/next/commands/baseCommands.ts
1335
1375
  import { Command, Option } from "clipanion";
1336
- import chalk4 from "chalk";
1376
+ import chalk5 from "chalk";
1337
1377
 
1338
1378
  // src/utils/start-subprocess.ts
1339
1379
  import childProcess from "child_process";
@@ -1367,7 +1407,7 @@ stack: ${code.stack || "No stack was provided"}`);
1367
1407
 
1368
1408
  // src/next/commands/baseCommands.ts
1369
1409
  import { getChangedFiles, getSha, shaExists } from "@tinacms/graphql";
1370
- import fs3 from "fs-extra";
1410
+ import fs4 from "fs-extra";
1371
1411
  var BaseCommand = class extends Command {
1372
1412
  experimentalDataLayer = Option.Boolean("--experimentalData", {
1373
1413
  description: "DEPRECATED - Build the server with additional data querying capabilities"
@@ -1401,7 +1441,7 @@ var BaseCommand = class extends Command {
1401
1441
  if (this.subCommand) {
1402
1442
  subProc = await startSubprocess2({ command: this.subCommand });
1403
1443
  logger.info(
1404
- `Running web application with command: ${chalk4.cyan(this.subCommand)}`
1444
+ `Running web application with command: ${chalk5.cyan(this.subCommand)}`
1405
1445
  );
1406
1446
  }
1407
1447
  function exitHandler(options, exitCode) {
@@ -1449,7 +1489,7 @@ var BaseCommand = class extends Command {
1449
1489
  const rootPath = configManager.rootPath;
1450
1490
  let sha;
1451
1491
  try {
1452
- sha = await getSha({ fs: fs3, dir: rootPath });
1492
+ sha = await getSha({ fs: fs4, dir: rootPath });
1453
1493
  } catch (e) {
1454
1494
  if (partialReindex) {
1455
1495
  console.error(
@@ -1459,7 +1499,7 @@ var BaseCommand = class extends Command {
1459
1499
  }
1460
1500
  }
1461
1501
  const lastSha = await database.getMetadata("lastSha");
1462
- const exists = lastSha && await shaExists({ fs: fs3, dir: rootPath, sha: lastSha });
1502
+ const exists = lastSha && await shaExists({ fs: fs4, dir: rootPath, sha: lastSha });
1463
1503
  let res;
1464
1504
  if (partialReindex && lastSha && exists && sha) {
1465
1505
  const pathFilter = {};
@@ -1474,14 +1514,14 @@ var BaseCommand = class extends Command {
1474
1514
  };
1475
1515
  }
1476
1516
  const { added, modified, deleted } = await getChangedFiles({
1477
- fs: fs3,
1517
+ fs: fs4,
1478
1518
  dir: rootPath,
1479
1519
  from: lastSha,
1480
1520
  to: sha,
1481
1521
  pathFilter
1482
1522
  });
1483
1523
  const tinaPathUpdates = modified.filter(
1484
- (path15) => path15.startsWith(".tina/__generated__/_schema.json") || path15.startsWith("tina/tina-lock.json")
1524
+ (path17) => path17.startsWith(".tina/__generated__/_schema.json") || path17.startsWith("tina/tina-lock.json")
1485
1525
  );
1486
1526
  if (tinaPathUpdates.length > 0) {
1487
1527
  res = await database.indexContent({
@@ -1600,9 +1640,9 @@ var devHTML = (port) => `<!DOCTYPE html>
1600
1640
  import { createServer as createViteServer } from "vite";
1601
1641
 
1602
1642
  // src/next/vite/index.ts
1603
- import path5 from "node:path";
1643
+ import path6 from "node:path";
1604
1644
  import react from "@vitejs/plugin-react";
1605
- import fs4 from "fs-extra";
1645
+ import fs5 from "fs-extra";
1606
1646
  import normalizePath3 from "normalize-path";
1607
1647
  import {
1608
1648
  splitVendorChunkPlugin
@@ -1669,7 +1709,7 @@ function filterPublicEnv(env = process.env) {
1669
1709
  }
1670
1710
 
1671
1711
  // src/next/vite/tailwind.ts
1672
- import path4 from "node:path";
1712
+ import path5 from "node:path";
1673
1713
  import aspectRatio from "@tailwindcss/aspect-ratio";
1674
1714
  import containerQueries from "@tailwindcss/container-queries";
1675
1715
  import twTypography from "@tailwindcss/typography";
@@ -1684,7 +1724,7 @@ var tinaTailwind = (spaPath, prebuildFilePath) => {
1684
1724
  const require2 = createRequire2(import.meta.url);
1685
1725
  const plugins = [];
1686
1726
  const content = [
1687
- path4.join(spaPath, "src/**/*.{vue,js,ts,jsx,tsx,svelte}"),
1727
+ path5.join(spaPath, "src/**/*.{vue,js,ts,jsx,tsx,svelte}"),
1688
1728
  prebuildFilePath,
1689
1729
  require2.resolve("tinacms")
1690
1730
  ];
@@ -1948,35 +1988,35 @@ async function listFilesRecursively({
1948
1988
  config: config2,
1949
1989
  roothPath
1950
1990
  }) {
1951
- const fullDirectoryPath = path5.join(
1991
+ const fullDirectoryPath = path6.join(
1952
1992
  roothPath,
1953
1993
  config2.publicFolder,
1954
1994
  directoryPath
1955
1995
  );
1956
- const exists = await fs4.pathExists(fullDirectoryPath);
1996
+ const exists = await fs5.pathExists(fullDirectoryPath);
1957
1997
  if (!exists) {
1958
1998
  return { "0": [] };
1959
1999
  }
1960
- const items = await fs4.readdir(fullDirectoryPath);
2000
+ const items = await fs5.readdir(fullDirectoryPath);
1961
2001
  const staticMediaItems = [];
1962
2002
  for (const item of items) {
1963
- const itemPath = path5.join(fullDirectoryPath, item);
1964
- const stats = await fs4.promises.lstat(itemPath);
2003
+ const itemPath = path6.join(fullDirectoryPath, item);
2004
+ const stats = await fs5.promises.lstat(itemPath);
1965
2005
  const staticMediaItem = {
1966
2006
  id: item,
1967
2007
  filename: item,
1968
2008
  type: stats.isDirectory() ? "dir" : "file",
1969
2009
  directory: `${directoryPath.replace(config2.mediaRoot, "")}`,
1970
- src: `/${path5.join(directoryPath, item)}`,
2010
+ src: `/${path6.join(directoryPath, item)}`,
1971
2011
  thumbnails: {
1972
- "75x75": `/${path5.join(directoryPath, item)}`,
1973
- "400x400": `/${path5.join(directoryPath, item)}`,
1974
- "1000x1000": `/${path5.join(directoryPath, item)}`
2012
+ "75x75": `/${path6.join(directoryPath, item)}`,
2013
+ "400x400": `/${path6.join(directoryPath, item)}`,
2014
+ "1000x1000": `/${path6.join(directoryPath, item)}`
1975
2015
  }
1976
2016
  };
1977
2017
  if (stats.isDirectory()) {
1978
2018
  staticMediaItem.children = await listFilesRecursively({
1979
- directoryPath: path5.join(directoryPath, item),
2019
+ directoryPath: path6.join(directoryPath, item),
1980
2020
  config: config2,
1981
2021
  roothPath
1982
2022
  });
@@ -2001,7 +2041,7 @@ var createConfig = async ({
2001
2041
  rollupOptions
2002
2042
  }) => {
2003
2043
  const publicEnv = filterPublicEnv();
2004
- const staticMediaPath = path5.join(
2044
+ const staticMediaPath = path6.join(
2005
2045
  configManager.generatedFolderPath,
2006
2046
  "static-media.json"
2007
2047
  );
@@ -2011,21 +2051,21 @@ var createConfig = async ({
2011
2051
  config: configManager.config.media.tina,
2012
2052
  roothPath: configManager.rootPath
2013
2053
  });
2014
- await fs4.outputFile(staticMediaPath, JSON.stringify(staticMedia, null, 2));
2054
+ await fs5.outputFile(staticMediaPath, JSON.stringify(staticMedia, null, 2));
2015
2055
  } else {
2016
- await fs4.outputFile(staticMediaPath, `[]`);
2056
+ await fs5.outputFile(staticMediaPath, `[]`);
2017
2057
  }
2018
2058
  const alias = {
2019
2059
  TINA_IMPORT: configManager.prebuildFilePath,
2020
2060
  SCHEMA_IMPORT: configManager.generatedGraphQLJSONPath,
2021
2061
  STATIC_MEDIA_IMPORT: staticMediaPath,
2022
- crypto: path5.join(configManager.spaRootPath, "src", "dummy-client.ts"),
2023
- fs: path5.join(configManager.spaRootPath, "src", "dummy-client.ts"),
2024
- os: path5.join(configManager.spaRootPath, "src", "dummy-client.ts"),
2025
- path: path5.join(configManager.spaRootPath, "src", "dummy-client.ts")
2062
+ crypto: path6.join(configManager.spaRootPath, "src", "dummy-client.ts"),
2063
+ fs: path6.join(configManager.spaRootPath, "src", "dummy-client.ts"),
2064
+ os: path6.join(configManager.spaRootPath, "src", "dummy-client.ts"),
2065
+ path: path6.join(configManager.spaRootPath, "src", "dummy-client.ts")
2026
2066
  };
2027
2067
  if (configManager.shouldSkipSDK()) {
2028
- alias["CLIENT_IMPORT"] = path5.join(
2068
+ alias["CLIENT_IMPORT"] = path6.join(
2029
2069
  configManager.spaRootPath,
2030
2070
  "src",
2031
2071
  "dummy-client.ts"
@@ -2135,8 +2175,8 @@ var createConfig = async ({
2135
2175
  };
2136
2176
 
2137
2177
  // src/next/vite/plugins.ts
2138
- import fs6 from "fs";
2139
- import path7 from "path";
2178
+ import fs7 from "fs";
2179
+ import path8 from "path";
2140
2180
  import { createFilter } from "@rollup/pluginutils";
2141
2181
  import { resolve as gqlResolve } from "@tinacms/graphql";
2142
2182
  import bodyParser from "body-parser";
@@ -2145,11 +2185,11 @@ import { transform as esbuildTransform } from "esbuild";
2145
2185
  import { transformWithEsbuild } from "vite";
2146
2186
 
2147
2187
  // src/next/commands/dev-command/server/media.ts
2148
- import path6, { join } from "path";
2188
+ import path7, { join } from "path";
2149
2189
  import busboy from "busboy";
2150
- import fs5 from "fs-extra";
2190
+ import fs6 from "fs-extra";
2151
2191
  var createMediaRouter = (config2) => {
2152
- const mediaFolder = path6.join(
2192
+ const mediaFolder = path7.join(
2153
2193
  config2.rootPath,
2154
2194
  config2.publicFolder,
2155
2195
  config2.mediaRoot
@@ -2213,8 +2253,8 @@ var createMediaRouter = (config2) => {
2213
2253
  );
2214
2254
  return;
2215
2255
  }
2216
- await fs5.ensureDir(path6.dirname(saveTo));
2217
- file.pipe(fs5.createWriteStream(saveTo));
2256
+ await fs6.ensureDir(path7.dirname(saveTo));
2257
+ file.pipe(fs6.createWriteStream(saveTo));
2218
2258
  });
2219
2259
  bb.on("error", (error) => {
2220
2260
  responded = true;
@@ -2244,18 +2284,18 @@ var parseMediaFolder = (str) => {
2244
2284
  var ENCODED_TRAVERSAL_RE = /%2e%2e|%2f|%5c/i;
2245
2285
  function resolveRealPath(candidate) {
2246
2286
  try {
2247
- return fs5.realpathSync(candidate);
2287
+ return fs6.realpathSync(candidate);
2248
2288
  } catch {
2249
- const parent = path6.dirname(candidate);
2289
+ const parent = path7.dirname(candidate);
2250
2290
  if (parent === candidate) return candidate;
2251
- return path6.join(resolveRealPath(parent), path6.basename(candidate));
2291
+ return path7.join(resolveRealPath(parent), path7.basename(candidate));
2252
2292
  }
2253
2293
  }
2254
2294
  function assertSymlinkWithinBase(resolved, resolvedBase, userPath) {
2255
2295
  try {
2256
- const realBase = fs5.realpathSync(resolvedBase);
2296
+ const realBase = fs6.realpathSync(resolvedBase);
2257
2297
  const realResolved = resolveRealPath(resolved);
2258
- if (realResolved !== realBase && !realResolved.startsWith(realBase + path6.sep)) {
2298
+ if (realResolved !== realBase && !realResolved.startsWith(realBase + path7.sep)) {
2259
2299
  throw new PathTraversalError(userPath);
2260
2300
  }
2261
2301
  } catch (err) {
@@ -2266,13 +2306,13 @@ function resolveWithinBase(userPath, baseDir) {
2266
2306
  if (ENCODED_TRAVERSAL_RE.test(userPath)) {
2267
2307
  throw new PathTraversalError(userPath);
2268
2308
  }
2269
- const resolvedBase = path6.resolve(baseDir);
2270
- const resolved = path6.resolve(path6.join(baseDir, userPath));
2309
+ const resolvedBase = path7.resolve(baseDir);
2310
+ const resolved = path7.resolve(path7.join(baseDir, userPath));
2271
2311
  if (resolved === resolvedBase) {
2272
2312
  assertSymlinkWithinBase(resolved, resolvedBase, userPath);
2273
2313
  return resolvedBase;
2274
2314
  }
2275
- if (resolved.startsWith(resolvedBase + path6.sep)) {
2315
+ if (resolved.startsWith(resolvedBase + path7.sep)) {
2276
2316
  assertSymlinkWithinBase(resolved, resolvedBase, userPath);
2277
2317
  return resolved;
2278
2318
  }
@@ -2282,12 +2322,12 @@ function resolveStrictlyWithinBase(userPath, baseDir) {
2282
2322
  if (ENCODED_TRAVERSAL_RE.test(userPath)) {
2283
2323
  throw new PathTraversalError(userPath);
2284
2324
  }
2285
- const resolvedBase = path6.resolve(baseDir) + path6.sep;
2286
- const resolved = path6.resolve(path6.join(baseDir, userPath));
2325
+ const resolvedBase = path7.resolve(baseDir) + path7.sep;
2326
+ const resolved = path7.resolve(path7.join(baseDir, userPath));
2287
2327
  if (!resolved.startsWith(resolvedBase)) {
2288
2328
  throw new PathTraversalError(userPath);
2289
2329
  }
2290
- assertSymlinkWithinBase(resolved, path6.resolve(baseDir), userPath);
2330
+ assertSymlinkWithinBase(resolved, path7.resolve(baseDir), userPath);
2291
2331
  return resolved;
2292
2332
  }
2293
2333
  var MediaModel = class {
@@ -2304,16 +2344,16 @@ var MediaModel = class {
2304
2344
  const mediaBase = join(this.rootPath, this.publicFolder, this.mediaRoot);
2305
2345
  const validatedPath = resolveWithinBase(args.searchPath, mediaBase);
2306
2346
  const searchPath = parseMediaFolder(args.searchPath);
2307
- if (!await fs5.pathExists(validatedPath)) {
2347
+ if (!await fs6.pathExists(validatedPath)) {
2308
2348
  return {
2309
2349
  files: [],
2310
2350
  directories: []
2311
2351
  };
2312
2352
  }
2313
- const filesStr = await fs5.readdir(validatedPath);
2353
+ const filesStr = await fs6.readdir(validatedPath);
2314
2354
  const filesProm = filesStr.map(async (file) => {
2315
2355
  const filePath = join(validatedPath, file);
2316
- const stat = await fs5.stat(filePath);
2356
+ const stat = await fs6.stat(filePath);
2317
2357
  let src = `/${file}`;
2318
2358
  const isFile = stat.isFile();
2319
2359
  if (!isFile) {
@@ -2372,8 +2412,8 @@ var MediaModel = class {
2372
2412
  try {
2373
2413
  const mediaBase = join(this.rootPath, this.publicFolder, this.mediaRoot);
2374
2414
  const file = resolveStrictlyWithinBase(args.searchPath, mediaBase);
2375
- await fs5.stat(file);
2376
- await fs5.remove(file);
2415
+ await fs6.stat(file);
2416
+ await fs6.remove(file);
2377
2417
  return { ok: true };
2378
2418
  } catch (error) {
2379
2419
  if (error instanceof PathTraversalError) throw error;
@@ -2481,7 +2521,7 @@ var transformTsxPlugin = ({
2481
2521
  const plug = {
2482
2522
  name: "transform-tsx",
2483
2523
  async transform(code, id) {
2484
- const extName = path7.extname(id);
2524
+ const extName = path8.extname(id);
2485
2525
  if (extName.startsWith(".tsx") || extName.startsWith(".ts")) {
2486
2526
  const result = await esbuildTransform(code, { loader: "tsx" });
2487
2527
  return {
@@ -2592,7 +2632,7 @@ function viteTransformExtension({
2592
2632
  async transform(code, id) {
2593
2633
  if (filter(id)) {
2594
2634
  const { transform: transform2 } = await import("@svgr/core");
2595
- const svgCode = await fs6.promises.readFile(
2635
+ const svgCode = await fs7.promises.readFile(
2596
2636
  id.replace(/\?.*$/, ""),
2597
2637
  "utf8"
2598
2638
  );
@@ -2733,13 +2773,13 @@ var DevCommand = class extends BaseCommand {
2733
2773
  });
2734
2774
  const apiURL2 = await codegen2.execute();
2735
2775
  if (!configManager.isUsingLegacyFolder) {
2736
- const schemaObject = await fs7.readJSON(
2776
+ const schemaObject = await fs8.readJSON(
2737
2777
  configManager.generatedSchemaJSONPath
2738
2778
  );
2739
- const lookupObject = await fs7.readJSON(
2779
+ const lookupObject = await fs8.readJSON(
2740
2780
  configManager.generatedLookupJSONPath
2741
2781
  );
2742
- const graphqlSchemaObject = await fs7.readJSON(
2782
+ const graphqlSchemaObject = await fs8.readJSON(
2743
2783
  configManager.generatedGraphQLJSONPath
2744
2784
  );
2745
2785
  const tinaLockFilename = "tina-lock.json";
@@ -2748,8 +2788,8 @@ var DevCommand = class extends BaseCommand {
2748
2788
  lookup: lookupObject,
2749
2789
  graphql: graphqlSchemaObject
2750
2790
  });
2751
- fs7.writeFileSync(
2752
- path8.join(configManager.tinaFolderPath, tinaLockFilename),
2791
+ fs8.writeFileSync(
2792
+ path9.join(configManager.tinaFolderPath, tinaLockFilename),
2753
2793
  tinaLockContent
2754
2794
  );
2755
2795
  if (configManager.hasSeparateContentRoot()) {
@@ -2757,9 +2797,9 @@ var DevCommand = class extends BaseCommand {
2757
2797
  configManager.contentRootPath,
2758
2798
  { isContentRoot: true }
2759
2799
  );
2760
- const filePath = path8.join(rootPath, tinaLockFilename);
2761
- await fs7.ensureFile(filePath);
2762
- await fs7.outputFile(filePath, tinaLockContent);
2800
+ const filePath = path9.join(rootPath, tinaLockFilename);
2801
+ await fs8.ensureFile(filePath);
2802
+ await fs8.outputFile(filePath, tinaLockContent);
2763
2803
  }
2764
2804
  }
2765
2805
  await this.indexContentWithSpinner({
@@ -2802,8 +2842,8 @@ ${dangerText(e.message)}
2802
2842
  const { apiURL, graphQLSchema, tinaSchema } = await setup({
2803
2843
  firstTime: true
2804
2844
  });
2805
- await fs7.outputFile(configManager.outputHTMLFilePath, devHTML(this.port));
2806
- await fs7.outputFile(
2845
+ await fs8.outputFile(configManager.outputHTMLFilePath, devHTML(this.port));
2846
+ await fs8.outputFile(
2807
2847
  configManager.outputGitignorePath,
2808
2848
  "index.html\nassets/"
2809
2849
  );
@@ -2948,7 +2988,7 @@ ${dangerText(e.message)}
2948
2988
  watchContentFiles(configManager, database, databaseLock, searchIndexer) {
2949
2989
  const collectionContentFiles = [];
2950
2990
  configManager.config.schema.collections.forEach((collection) => {
2951
- const collectionGlob = `${path8.join(
2991
+ const collectionGlob = `${path9.join(
2952
2992
  configManager.contentRootPath,
2953
2993
  collection.path
2954
2994
  )}/**/*.${collection.format || "md"}`;
@@ -2998,7 +3038,7 @@ ${dangerText(e.message)}
2998
3038
 
2999
3039
  // src/next/commands/build-command/index.ts
3000
3040
  import crypto from "crypto";
3001
- import path9 from "path";
3041
+ import path10 from "path";
3002
3042
  import { diff } from "@graphql-inspector/core";
3003
3043
  import { FilesystemBridge as FilesystemBridge3, buildSchema as buildSchema2 } from "@tinacms/graphql";
3004
3044
  import { parseURL as parseURL2 } from "@tinacms/schema-tools";
@@ -3007,7 +3047,7 @@ import {
3007
3047
  TinaCMSSearchIndexClient
3008
3048
  } from "@tinacms/search";
3009
3049
  import { Command as Command3, Option as Option3 } from "clipanion";
3010
- import fs8 from "fs-extra";
3050
+ import fs9 from "fs-extra";
3011
3051
  import {
3012
3052
  buildASTSchema as buildASTSchema2,
3013
3053
  buildClientSchema,
@@ -3366,7 +3406,7 @@ ${dangerText(e.message)}
3366
3406
  }
3367
3407
  }
3368
3408
  await buildProductionSpa(configManager, database, codegen2.productionUrl);
3369
- await fs8.outputFile(
3409
+ await fs9.outputFile(
3370
3410
  configManager.outputGitignorePath,
3371
3411
  "index.html\nassets/"
3372
3412
  );
@@ -3744,7 +3784,7 @@ Additional info: Branch: ${config2.branch}, Client ID: ${config2.clientId} `;
3744
3784
  }
3745
3785
  const localTinaSchema = JSON.parse(
3746
3786
  await database.bridge.get(
3747
- path9.join(database.tinaDirectory, "__generated__", "_schema.json")
3787
+ path10.join(database.tinaDirectory, "__generated__", "_schema.json")
3748
3788
  )
3749
3789
  );
3750
3790
  localTinaSchema.version = void 0;
@@ -3866,7 +3906,7 @@ import { buildSchema as buildSchema3 } from "@tinacms/graphql";
3866
3906
  import prompts from "prompts";
3867
3907
  import { Telemetry } from "@tinacms/metrics";
3868
3908
  import { resolve } from "@tinacms/graphql";
3869
- import chalk5 from "chalk";
3909
+ import chalk6 from "chalk";
3870
3910
  var audit = async ({
3871
3911
  database,
3872
3912
  clean,
@@ -3884,7 +3924,7 @@ var audit = async ({
3884
3924
  });
3885
3925
  if (clean) {
3886
3926
  logger.info(
3887
- `You are using the \`--clean\` option. This will modify your content as if a user is submitting a form. Before running this you should have a ${chalk5.bold(
3927
+ `You are using the \`--clean\` option. This will modify your content as if a user is submitting a form. Before running this you should have a ${chalk6.bold(
3888
3928
  "clean git tree"
3889
3929
  )} so unwanted changes can be undone.
3890
3930
 
@@ -3896,13 +3936,13 @@ var audit = async ({
3896
3936
  message: `Do you want to continue?`
3897
3937
  });
3898
3938
  if (!res.useClean) {
3899
- logger.warn(chalk5.yellowBright("\u26A0\uFE0F Audit not complete"));
3939
+ logger.warn(chalk6.yellowBright("\u26A0\uFE0F Audit not complete"));
3900
3940
  process.exit(0);
3901
3941
  }
3902
3942
  }
3903
3943
  if (useDefaultValues && !clean) {
3904
3944
  logger.warn(
3905
- chalk5.yellowBright(
3945
+ chalk6.yellowBright(
3906
3946
  "WARNING: using the `--useDefaultValues` without the `--clean` flag has no effect. Please re-run audit and add the `--clean` flag"
3907
3947
  )
3908
3948
  );
@@ -3930,10 +3970,10 @@ var audit = async ({
3930
3970
  }
3931
3971
  if (error) {
3932
3972
  logger.error(
3933
- chalk5.redBright(`\u203C\uFE0F Audit ${chalk5.bold("failed")} with errors`)
3973
+ chalk6.redBright(`\u203C\uFE0F Audit ${chalk6.bold("failed")} with errors`)
3934
3974
  );
3935
3975
  } else {
3936
- logger.info(chalk5.greenBright("\u2705 Audit passed"));
3976
+ logger.info(chalk6.greenBright("\u2705 Audit passed"));
3937
3977
  }
3938
3978
  };
3939
3979
  var auditDocuments = async (args) => {
@@ -3961,11 +4001,11 @@ var auditDocuments = async (args) => {
3961
4001
  if (docResult.errors) {
3962
4002
  error = true;
3963
4003
  docResult.errors.forEach((err) => {
3964
- logger.error(chalk5.red(err.message));
4004
+ logger.error(chalk6.red(err.message));
3965
4005
  if (err.originalError.originalError) {
3966
4006
  logger.error(
3967
4007
  // @ts-ignore FIXME: this doesn't seem right
3968
- chalk5.red(` ${err.originalError.originalError.message}`)
4008
+ chalk6.red(` ${err.originalError.originalError.message}`)
3969
4009
  );
3970
4010
  }
3971
4011
  });
@@ -4007,7 +4047,7 @@ var auditDocuments = async (args) => {
4007
4047
  if (mutationRes.errors) {
4008
4048
  mutationRes.errors.forEach((err) => {
4009
4049
  error = true;
4010
- logger.error(chalk5.red(err.message));
4050
+ logger.error(chalk6.red(err.message));
4011
4051
  });
4012
4052
  }
4013
4053
  }
@@ -4107,26 +4147,26 @@ var AuditCommand = class extends Command4 {
4107
4147
  import { Command as Command6, Option as Option6 } from "clipanion";
4108
4148
 
4109
4149
  // src/cmds/init/detectEnvironment.ts
4110
- import fs9 from "fs-extra";
4111
- import path10 from "path";
4150
+ import fs10 from "fs-extra";
4151
+ import path11 from "path";
4112
4152
  var checkGitignoreForItem = async ({
4113
4153
  baseDir,
4114
4154
  line
4115
4155
  }) => {
4116
- const gitignoreContent = fs9.readFileSync(path10.join(baseDir, ".gitignore")).toString();
4156
+ const gitignoreContent = fs10.readFileSync(path11.join(baseDir, ".gitignore")).toString();
4117
4157
  return gitignoreContent.split("\n").some((item) => item === line);
4118
4158
  };
4119
4159
  var makeGeneratedFile = async (name2, generatedFileType, parentPath, opts) => {
4120
4160
  const result = {
4121
- fullPathTS: path10.join(
4161
+ fullPathTS: path11.join(
4122
4162
  parentPath,
4123
4163
  `${name2}.${opts?.typescriptSuffix || opts?.extensionOverride || "ts"}`
4124
4164
  ),
4125
- fullPathJS: path10.join(
4165
+ fullPathJS: path11.join(
4126
4166
  parentPath,
4127
4167
  `${name2}.${opts?.extensionOverride || "js"}`
4128
4168
  ),
4129
- fullPathOverride: opts?.extensionOverride ? path10.join(parentPath, `${name2}.${opts?.extensionOverride}`) : "",
4169
+ fullPathOverride: opts?.extensionOverride ? path11.join(parentPath, `${name2}.${opts?.extensionOverride}`) : "",
4130
4170
  generatedFileType,
4131
4171
  name: name2,
4132
4172
  parentPath,
@@ -4144,8 +4184,8 @@ var makeGeneratedFile = async (name2, generatedFileType, parentPath, opts) => {
4144
4184
  };
4145
4185
  }
4146
4186
  };
4147
- result.typescriptExists = await fs9.pathExists(result.fullPathTS);
4148
- result.javascriptExists = await fs9.pathExists(result.fullPathJS);
4187
+ result.typescriptExists = await fs10.pathExists(result.fullPathTS);
4188
+ result.javascriptExists = await fs10.pathExists(result.fullPathJS);
4149
4189
  return result;
4150
4190
  };
4151
4191
  var detectEnvironment = async ({
@@ -4154,21 +4194,21 @@ var detectEnvironment = async ({
4154
4194
  rootPath,
4155
4195
  debug = false
4156
4196
  }) => {
4157
- const hasForestryConfig = await fs9.pathExists(
4158
- path10.join(pathToForestryConfig, ".forestry", "settings.yml")
4197
+ const hasForestryConfig = await fs10.pathExists(
4198
+ path11.join(pathToForestryConfig, ".forestry", "settings.yml")
4159
4199
  );
4160
- const sampleContentPath = path10.join(
4200
+ const sampleContentPath = path11.join(
4161
4201
  baseDir,
4162
4202
  "content",
4163
4203
  "posts",
4164
4204
  "hello-world.md"
4165
4205
  );
4166
- const usingSrc = fs9.pathExistsSync(path10.join(baseDir, "src")) && (fs9.pathExistsSync(path10.join(baseDir, "src", "app")) || fs9.pathExistsSync(path10.join(baseDir, "src", "pages")));
4167
- const tinaFolder = path10.join(baseDir, "tina");
4206
+ const usingSrc = fs10.pathExistsSync(path11.join(baseDir, "src")) && (fs10.pathExistsSync(path11.join(baseDir, "src", "app")) || fs10.pathExistsSync(path11.join(baseDir, "src", "pages")));
4207
+ const tinaFolder = path11.join(baseDir, "tina");
4168
4208
  const tinaConfigExists = Boolean(
4169
4209
  // Does the tina folder exist?
4170
- await fs9.pathExists(tinaFolder) && // Does the tina folder contain a config file?
4171
- (await fs9.readdir(tinaFolder)).find((x) => x.includes("config"))
4210
+ await fs10.pathExists(tinaFolder) && // Does the tina folder contain a config file?
4211
+ (await fs10.readdir(tinaFolder)).find((x) => x.includes("config"))
4172
4212
  );
4173
4213
  const pagesDir = [baseDir, usingSrc ? "src" : false, "pages"].filter(
4174
4214
  Boolean
@@ -4180,12 +4220,12 @@ var detectEnvironment = async ({
4180
4220
  "next-api-handler": await makeGeneratedFile(
4181
4221
  "[...routes]",
4182
4222
  "next-api-handler",
4183
- path10.join(...pagesDir, "api", "tina")
4223
+ path11.join(...pagesDir, "api", "tina")
4184
4224
  ),
4185
4225
  "reactive-example": await makeGeneratedFile(
4186
4226
  "[filename]",
4187
4227
  "reactive-example",
4188
- path10.join(...pagesDir, "demo", "blog"),
4228
+ path11.join(...pagesDir, "demo", "blog"),
4189
4229
  {
4190
4230
  typescriptSuffix: "tsx"
4191
4231
  }
@@ -4193,22 +4233,22 @@ var detectEnvironment = async ({
4193
4233
  "users-json": await makeGeneratedFile(
4194
4234
  "index",
4195
4235
  "users-json",
4196
- path10.join(baseDir, "content", "users"),
4236
+ path11.join(baseDir, "content", "users"),
4197
4237
  { extensionOverride: "json" }
4198
4238
  ),
4199
4239
  "sample-content": await makeGeneratedFile(
4200
4240
  "hello-world",
4201
4241
  "sample-content",
4202
- path10.join(baseDir, "content", "posts"),
4242
+ path11.join(baseDir, "content", "posts"),
4203
4243
  { extensionOverride: "md" }
4204
4244
  )
4205
4245
  };
4206
- const hasSampleContent = await fs9.pathExists(sampleContentPath);
4207
- const hasPackageJSON = await fs9.pathExists("package.json");
4246
+ const hasSampleContent = await fs10.pathExists(sampleContentPath);
4247
+ const hasPackageJSON = await fs10.pathExists("package.json");
4208
4248
  let hasTinaDeps = false;
4209
4249
  if (hasPackageJSON) {
4210
4250
  try {
4211
- const packageJSON = await fs9.readJSON("package.json");
4251
+ const packageJSON = await fs10.readJSON("package.json");
4212
4252
  const deps = [];
4213
4253
  if (packageJSON?.dependencies) {
4214
4254
  deps.push(...Object.keys(packageJSON.dependencies));
@@ -4225,15 +4265,15 @@ var detectEnvironment = async ({
4225
4265
  );
4226
4266
  }
4227
4267
  }
4228
- const hasGitIgnore = await fs9.pathExists(path10.join(".gitignore"));
4268
+ const hasGitIgnore = await fs10.pathExists(path11.join(".gitignore"));
4229
4269
  const hasGitIgnoreNodeModules = hasGitIgnore && await checkGitignoreForItem({ baseDir, line: "node_modules" });
4230
4270
  const hasEnvTina = hasGitIgnore && await checkGitignoreForItem({ baseDir, line: ".env.tina" });
4231
4271
  const hasGitIgnoreEnv = hasGitIgnore && await checkGitignoreForItem({ baseDir, line: ".env" });
4232
4272
  let frontMatterFormat;
4233
4273
  if (hasForestryConfig) {
4234
- const hugoConfigPath = path10.join(rootPath, "config.toml");
4235
- if (await fs9.pathExists(hugoConfigPath)) {
4236
- const hugoConfig = await fs9.readFile(hugoConfigPath, "utf8");
4274
+ const hugoConfigPath = path11.join(rootPath, "config.toml");
4275
+ if (await fs10.pathExists(hugoConfigPath)) {
4276
+ const hugoConfig = await fs10.readFile(hugoConfigPath, "utf8");
4237
4277
  const metaDataFormat = hugoConfig.toString().match(/metaDataFormat = "(.*)"/)?.[1];
4238
4278
  if (metaDataFormat && (metaDataFormat === "yaml" || metaDataFormat === "toml" || metaDataFormat === "json")) {
4239
4279
  frontMatterFormat = metaDataFormat;
@@ -4846,21 +4886,21 @@ var CLICommand = class {
4846
4886
  };
4847
4887
 
4848
4888
  // src/cmds/init/apply.ts
4849
- import path14 from "path";
4889
+ import path15 from "path";
4850
4890
 
4851
4891
  // src/cmds/forestry-migrate/index.ts
4852
- import fs11 from "fs-extra";
4853
- import path12 from "path";
4892
+ import fs12 from "fs-extra";
4893
+ import path13 from "path";
4854
4894
  import yaml2 from "js-yaml";
4855
4895
  import pkg from "minimatch";
4856
4896
  import { parseFile, stringifyFile } from "@tinacms/graphql";
4857
4897
  import { CONTENT_FORMATS } from "@tinacms/schema-tools";
4858
4898
 
4859
4899
  // src/cmds/forestry-migrate/util/index.ts
4860
- import fs10 from "fs-extra";
4861
- import path11 from "path";
4900
+ import fs11 from "fs-extra";
4901
+ import path12 from "path";
4862
4902
  import yaml from "js-yaml";
4863
- import z from "zod";
4903
+ import z2 from "zod";
4864
4904
 
4865
4905
  // src/cmds/forestry-migrate/util/errorSingleton.ts
4866
4906
  var ErrorSingleton = class _ErrorSingleton {
@@ -4987,82 +5027,82 @@ var stringifyTemplateName = (name2, template) => {
4987
5027
  return newName;
4988
5028
  }
4989
5029
  };
4990
- var forestryConfigSchema = z.object({
4991
- sections: z.array(
4992
- z.object({
4993
- type: z.union([
4994
- z.literal("directory"),
4995
- z.literal("document"),
4996
- z.literal("heading"),
4997
- z.literal("jekyll-pages"),
4998
- z.literal("jekyll-posts")
5030
+ var forestryConfigSchema = z2.object({
5031
+ sections: z2.array(
5032
+ z2.object({
5033
+ type: z2.union([
5034
+ z2.literal("directory"),
5035
+ z2.literal("document"),
5036
+ z2.literal("heading"),
5037
+ z2.literal("jekyll-pages"),
5038
+ z2.literal("jekyll-posts")
4999
5039
  ]),
5000
- label: z.string(),
5001
- path: z.string().optional().nullable(),
5002
- match: z.string().optional().nullable(),
5003
- exclude: z.string().optional().nullable(),
5004
- create: z.union([z.literal("all"), z.literal("documents"), z.literal("none")]).optional(),
5005
- templates: z.array(z.string()).optional().nullable(),
5006
- new_doc_ext: z.string().optional().nullable(),
5007
- read_only: z.boolean().optional().nullable()
5040
+ label: z2.string(),
5041
+ path: z2.string().optional().nullable(),
5042
+ match: z2.string().optional().nullable(),
5043
+ exclude: z2.string().optional().nullable(),
5044
+ create: z2.union([z2.literal("all"), z2.literal("documents"), z2.literal("none")]).optional(),
5045
+ templates: z2.array(z2.string()).optional().nullable(),
5046
+ new_doc_ext: z2.string().optional().nullable(),
5047
+ read_only: z2.boolean().optional().nullable()
5008
5048
  })
5009
5049
  )
5010
5050
  });
5011
- var forestryFieldWithoutField = z.object({
5051
+ var forestryFieldWithoutField = z2.object({
5012
5052
  // TODO: maybe better type this?
5013
- type: z.union([
5014
- z.literal("text"),
5015
- z.literal("datetime"),
5016
- z.literal("list"),
5017
- z.literal("file"),
5018
- z.literal("image_gallery"),
5019
- z.literal("textarea"),
5020
- z.literal("tag_list"),
5021
- z.literal("number"),
5022
- z.literal("boolean"),
5023
- z.literal("field_group"),
5024
- z.literal("field_group_list"),
5025
- z.literal("select"),
5026
- z.literal("include"),
5027
- z.literal("blocks"),
5028
- z.literal("color")
5053
+ type: z2.union([
5054
+ z2.literal("text"),
5055
+ z2.literal("datetime"),
5056
+ z2.literal("list"),
5057
+ z2.literal("file"),
5058
+ z2.literal("image_gallery"),
5059
+ z2.literal("textarea"),
5060
+ z2.literal("tag_list"),
5061
+ z2.literal("number"),
5062
+ z2.literal("boolean"),
5063
+ z2.literal("field_group"),
5064
+ z2.literal("field_group_list"),
5065
+ z2.literal("select"),
5066
+ z2.literal("include"),
5067
+ z2.literal("blocks"),
5068
+ z2.literal("color")
5029
5069
  ]),
5030
- template_types: z.array(z.string()).optional().nullable(),
5031
- name: z.string(),
5032
- label: z.string(),
5033
- default: z.any().optional(),
5034
- template: z.string().optional(),
5035
- config: z.object({
5070
+ template_types: z2.array(z2.string()).optional().nullable(),
5071
+ name: z2.string(),
5072
+ label: z2.string(),
5073
+ default: z2.any().optional(),
5074
+ template: z2.string().optional(),
5075
+ config: z2.object({
5036
5076
  // min and max are used for lists
5037
- min: z.number().optional().nullable(),
5038
- max: z.number().optional().nullable(),
5039
- required: z.boolean().optional().nullable(),
5040
- use_select: z.boolean().optional().nullable(),
5041
- date_format: z.string().optional().nullable(),
5042
- time_format: z.string().optional().nullable(),
5043
- options: z.array(z.string()).optional().nullable(),
5044
- source: z.object({
5045
- type: z.union([
5046
- z.literal("custom"),
5047
- z.literal("pages"),
5048
- z.literal("documents"),
5049
- z.literal("simple"),
5077
+ min: z2.number().optional().nullable(),
5078
+ max: z2.number().optional().nullable(),
5079
+ required: z2.boolean().optional().nullable(),
5080
+ use_select: z2.boolean().optional().nullable(),
5081
+ date_format: z2.string().optional().nullable(),
5082
+ time_format: z2.string().optional().nullable(),
5083
+ options: z2.array(z2.string()).optional().nullable(),
5084
+ source: z2.object({
5085
+ type: z2.union([
5086
+ z2.literal("custom"),
5087
+ z2.literal("pages"),
5088
+ z2.literal("documents"),
5089
+ z2.literal("simple"),
5050
5090
  // TODO: I want to ignore this key if its invalid
5051
- z.string()
5091
+ z2.string()
5052
5092
  ]).optional().nullable(),
5053
- section: z.string().optional().nullable()
5093
+ section: z2.string().optional().nullable()
5054
5094
  }).optional()
5055
5095
  }).optional()
5056
5096
  });
5057
- var forestryField = z.lazy(
5097
+ var forestryField = z2.lazy(
5058
5098
  () => forestryFieldWithoutField.extend({
5059
- fields: z.array(forestryField).optional()
5099
+ fields: z2.array(forestryField).optional()
5060
5100
  })
5061
5101
  );
5062
- var FrontmatterTemplateSchema = z.object({
5063
- label: z.string(),
5064
- hide_body: z.boolean().optional(),
5065
- fields: z.array(forestryField).optional()
5102
+ var FrontmatterTemplateSchema = z2.object({
5103
+ label: z2.string(),
5104
+ hide_body: z2.boolean().optional(),
5105
+ fields: z2.array(forestryField).optional()
5066
5106
  });
5067
5107
  var transformForestryFieldsToTinaFields = ({
5068
5108
  fields,
@@ -5285,7 +5325,7 @@ var transformForestryFieldsToTinaFields = ({
5285
5325
  return tinaFields;
5286
5326
  };
5287
5327
  var getFieldsFromTemplates = ({ tem, pathToForestryConfig, skipBlocks = false }) => {
5288
- const templatePath = path11.join(
5328
+ const templatePath = path12.join(
5289
5329
  pathToForestryConfig,
5290
5330
  ".forestry",
5291
5331
  "front_matter",
@@ -5294,7 +5334,7 @@ var getFieldsFromTemplates = ({ tem, pathToForestryConfig, skipBlocks = false })
5294
5334
  );
5295
5335
  let templateString = "";
5296
5336
  try {
5297
- templateString = fs10.readFileSync(templatePath).toString();
5337
+ templateString = fs11.readFileSync(templatePath).toString();
5298
5338
  } catch {
5299
5339
  throw new Error(
5300
5340
  `Could not find template ${tem} at ${templatePath}
@@ -5360,9 +5400,9 @@ function checkExt(ext) {
5360
5400
  var generateAllTemplates = async ({
5361
5401
  pathToForestryConfig
5362
5402
  }) => {
5363
- const allTemplates = (await fs11.readdir(
5364
- path12.join(pathToForestryConfig, ".forestry", "front_matter", "templates")
5365
- )).map((tem) => path12.basename(tem, ".yml"));
5403
+ const allTemplates = (await fs12.readdir(
5404
+ path13.join(pathToForestryConfig, ".forestry", "front_matter", "templates")
5405
+ )).map((tem) => path13.basename(tem, ".yml"));
5366
5406
  const templateMap = /* @__PURE__ */ new Map();
5367
5407
  const proms = allTemplates.map(async (tem) => {
5368
5408
  try {
@@ -5507,9 +5547,9 @@ var generateCollectionFromForestrySection = (args) => {
5507
5547
  return c;
5508
5548
  } else if (section.type === "document") {
5509
5549
  const filePath = section.path;
5510
- const extname = path12.extname(filePath);
5511
- const fileName = path12.basename(filePath, extname);
5512
- const dir = path12.dirname(filePath);
5550
+ const extname = path13.extname(filePath);
5551
+ const fileName = path13.basename(filePath, extname);
5552
+ const dir = path13.dirname(filePath);
5513
5553
  const ext = checkExt(extname);
5514
5554
  if (ext) {
5515
5555
  const fields = [];
@@ -5571,8 +5611,8 @@ var generateCollections = async ({
5571
5611
  templateMap,
5572
5612
  usingTypescript
5573
5613
  });
5574
- const forestryConfig = await fs11.readFile(
5575
- path12.join(pathToForestryConfig, ".forestry", "settings.yml")
5614
+ const forestryConfig = await fs12.readFile(
5615
+ path13.join(pathToForestryConfig, ".forestry", "settings.yml")
5576
5616
  );
5577
5617
  rewriteTemplateKeysInDocs({
5578
5618
  templateMap,
@@ -5602,12 +5642,12 @@ var rewriteTemplateKeysInDocs = (args) => {
5602
5642
  const { templateObj } = templateMap.get(templateKey);
5603
5643
  templateObj?.pages?.forEach((page) => {
5604
5644
  try {
5605
- const filePath = path12.join(page);
5606
- if (fs11.lstatSync(filePath).isDirectory()) {
5645
+ const filePath = path13.join(page);
5646
+ if (fs12.lstatSync(filePath).isDirectory()) {
5607
5647
  return;
5608
5648
  }
5609
- const extname = path12.extname(filePath);
5610
- const fileContent = fs11.readFileSync(filePath).toString();
5649
+ const extname = path13.extname(filePath);
5650
+ const fileContent = fs12.readFileSync(filePath).toString();
5611
5651
  const content = parseFile(
5612
5652
  fileContent,
5613
5653
  extname,
@@ -5618,7 +5658,7 @@ var rewriteTemplateKeysInDocs = (args) => {
5618
5658
  _template: stringifyLabel(templateKey),
5619
5659
  ...content
5620
5660
  };
5621
- fs11.writeFileSync(
5661
+ fs12.writeFileSync(
5622
5662
  filePath,
5623
5663
  stringifyFile(newContent, extname, true, markdownParseConfig)
5624
5664
  );
@@ -5633,12 +5673,12 @@ var rewriteTemplateKeysInDocs = (args) => {
5633
5673
 
5634
5674
  // src/cmds/init/apply.ts
5635
5675
  import { Telemetry as Telemetry2 } from "@tinacms/metrics";
5636
- import fs14 from "fs-extra";
5676
+ import fs15 from "fs-extra";
5637
5677
 
5638
5678
  // src/next/commands/codemod-command/index.ts
5639
5679
  import { Command as Command5, Option as Option5 } from "clipanion";
5640
- import fs12 from "fs-extra";
5641
- import path13 from "path";
5680
+ import fs13 from "fs-extra";
5681
+ import path14 from "path";
5642
5682
  var CodemodCommand = class extends Command5 {
5643
5683
  static paths = [["codemod"], ["codemod", "move-tina-folder"]];
5644
5684
  rootPath = Option5.String("--rootPath", {
@@ -5679,13 +5719,13 @@ var moveTinaFolder = async (rootPath = process.cwd()) => {
5679
5719
  logger.error(e.message);
5680
5720
  process.exit(1);
5681
5721
  }
5682
- const tinaDestination = path13.join(configManager.rootPath, "tina");
5683
- if (await fs12.existsSync(tinaDestination)) {
5722
+ const tinaDestination = path14.join(configManager.rootPath, "tina");
5723
+ if (await fs13.existsSync(tinaDestination)) {
5684
5724
  logger.info(
5685
5725
  `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.`
5686
5726
  );
5687
5727
  } else {
5688
- await fs12.moveSync(configManager.tinaFolderPath, tinaDestination);
5728
+ await fs13.moveSync(configManager.tinaFolderPath, tinaDestination);
5689
5729
  await writeGitignore(configManager.rootPath);
5690
5730
  logger.info(
5691
5731
  "Move to 'tina' folder complete. Be sure to update any imports of the autogenerated client!"
@@ -5693,8 +5733,8 @@ var moveTinaFolder = async (rootPath = process.cwd()) => {
5693
5733
  }
5694
5734
  };
5695
5735
  var writeGitignore = async (rootPath) => {
5696
- await fs12.outputFileSync(
5697
- path13.join(rootPath, "tina", ".gitignore"),
5736
+ await fs13.outputFileSync(
5737
+ path14.join(rootPath, "tina", ".gitignore"),
5698
5738
  "__generated__"
5699
5739
  );
5700
5740
  };
@@ -6132,7 +6172,7 @@ function extendNextScripts(scripts, opts) {
6132
6172
 
6133
6173
  // src/cmds/init/codegen/index.ts
6134
6174
  import ts2 from "typescript";
6135
- import fs13 from "fs-extra";
6175
+ import fs14 from "fs-extra";
6136
6176
 
6137
6177
  // src/cmds/init/codegen/util.ts
6138
6178
  import ts from "typescript";
@@ -6369,7 +6409,7 @@ var addSelfHostedTinaAuthToConfig = async (config2, configFile) => {
6369
6409
  const pathToConfig = configFile.resolve(config2.typescript).path;
6370
6410
  const sourceFile = ts2.createSourceFile(
6371
6411
  pathToConfig,
6372
- fs13.readFileSync(pathToConfig, "utf8"),
6412
+ fs14.readFileSync(pathToConfig, "utf8"),
6373
6413
  config2.typescript ? ts2.ScriptTarget.Latest : ts2.ScriptTarget.ESNext
6374
6414
  );
6375
6415
  const { configImports, configAuthProviderClass, extraTinaCollections } = config2.authProvider;
@@ -6419,7 +6459,7 @@ var addSelfHostedTinaAuthToConfig = async (config2, configFile) => {
6419
6459
  )
6420
6460
  ].map((visitor) => makeTransformer(visitor))
6421
6461
  );
6422
- return fs13.writeFile(
6462
+ return fs14.writeFile(
6423
6463
  pathToConfig,
6424
6464
  ts2.createPrinter({ omitTrailingSemicolon: true }).printFile(transformedSourceFileResult.transformed[0])
6425
6465
  );
@@ -6537,8 +6577,8 @@ async function apply({
6537
6577
  await addConfigFile({
6538
6578
  configArgs: {
6539
6579
  config: config2,
6540
- publicFolder: path14.join(
6541
- path14.relative(process.cwd(), pathToForestryConfig),
6580
+ publicFolder: path15.join(
6581
+ path15.relative(process.cwd(), pathToForestryConfig),
6542
6582
  config2.publicFolder
6543
6583
  ),
6544
6584
  collections,
@@ -6611,18 +6651,18 @@ var createPackageJSON = async () => {
6611
6651
  };
6612
6652
  var createGitignore = async ({ baseDir }) => {
6613
6653
  logger.info(logText("No .gitignore found, creating one"));
6614
- fs14.outputFileSync(path14.join(baseDir, ".gitignore"), "node_modules");
6654
+ fs15.outputFileSync(path15.join(baseDir, ".gitignore"), "node_modules");
6615
6655
  };
6616
6656
  var updateGitIgnore = async ({
6617
6657
  baseDir,
6618
6658
  items
6619
6659
  }) => {
6620
6660
  logger.info(logText(`Adding ${items.join(",")} to .gitignore`));
6621
- const gitignoreContent = fs14.readFileSync(path14.join(baseDir, ".gitignore")).toString();
6661
+ const gitignoreContent = fs15.readFileSync(path15.join(baseDir, ".gitignore")).toString();
6622
6662
  const newGitignoreContent = [...gitignoreContent.split("\n"), ...items].join(
6623
6663
  "\n"
6624
6664
  );
6625
- await fs14.writeFile(path14.join(baseDir, ".gitignore"), newGitignoreContent);
6665
+ await fs15.writeFile(path15.join(baseDir, ".gitignore"), newGitignoreContent);
6626
6666
  };
6627
6667
  var addDependencies = async (config2, env, params) => {
6628
6668
  const { packageManager } = config2;
@@ -6693,22 +6733,22 @@ var writeGeneratedFile = async ({
6693
6733
  content,
6694
6734
  typescript
6695
6735
  }) => {
6696
- const { exists, path: path15, parentPath } = generatedFile.resolve(typescript);
6736
+ const { exists, path: path17, parentPath } = generatedFile.resolve(typescript);
6697
6737
  if (exists) {
6698
6738
  if (overwrite) {
6699
- logger.info(`Overwriting file at ${path15}... \u2705`);
6700
- fs14.outputFileSync(path15, content);
6739
+ logger.info(`Overwriting file at ${path17}... \u2705`);
6740
+ fs15.outputFileSync(path17, content);
6701
6741
  } else {
6702
- logger.info(`Not overwriting file at ${path15}.`);
6742
+ logger.info(`Not overwriting file at ${path17}.`);
6703
6743
  logger.info(
6704
- logText(`Please add the following to ${path15}:
6744
+ logText(`Please add the following to ${path17}:
6705
6745
  ${indentText(content)}}`)
6706
6746
  );
6707
6747
  }
6708
6748
  } else {
6709
- logger.info(`Adding file at ${path15}... \u2705`);
6710
- await fs14.ensureDir(parentPath);
6711
- fs14.outputFileSync(path15, content);
6749
+ logger.info(`Adding file at ${path17}... \u2705`);
6750
+ await fs15.ensureDir(parentPath);
6751
+ fs15.outputFileSync(path17, content);
6712
6752
  }
6713
6753
  };
6714
6754
  var addConfigFile = async ({
@@ -6786,7 +6826,7 @@ var addContentFile = async ({
6786
6826
  return () => ({
6787
6827
  exists: env.sampleContentExists,
6788
6828
  path: env.sampleContentPath,
6789
- parentPath: path14.dirname(env.sampleContentPath)
6829
+ parentPath: path15.dirname(env.sampleContentPath)
6790
6830
  });
6791
6831
  }
6792
6832
  },
@@ -6809,10 +6849,10 @@ ${titleText(" TinaCMS ")} backend initialized!`));
6809
6849
  return `${x.key}=${x.value || "***"}`;
6810
6850
  }).join("\n") + `
6811
6851
  TINA_PUBLIC_IS_LOCAL=true`;
6812
- const envFile = path14.join(process.cwd(), ".env");
6813
- if (!fs14.existsSync(envFile)) {
6852
+ const envFile = path15.join(process.cwd(), ".env");
6853
+ if (!fs15.existsSync(envFile)) {
6814
6854
  logger.info(`Adding .env file to your project... \u2705`);
6815
- fs14.writeFileSync(envFile, envFileText);
6855
+ fs15.writeFileSync(envFile, envFileText);
6816
6856
  } else {
6817
6857
  logger.info(
6818
6858
  "Please add the following environment variables to your .env file"
@@ -6881,7 +6921,7 @@ var addReactiveFile = {
6881
6921
  baseDir,
6882
6922
  dataLayer
6883
6923
  }) => {
6884
- const packageJsonPath = path14.join(baseDir, "package.json");
6924
+ const packageJsonPath = path15.join(baseDir, "package.json");
6885
6925
  await writeGeneratedFile({
6886
6926
  generatedFile,
6887
6927
  typescript: config2.typescript,
@@ -6894,7 +6934,7 @@ var addReactiveFile = {
6894
6934
  })
6895
6935
  });
6896
6936
  logger.info("Adding a nextjs example... \u2705");
6897
- const packageJson = JSON.parse(fs14.readFileSync(packageJsonPath).toString());
6937
+ const packageJson = JSON.parse(fs15.readFileSync(packageJsonPath).toString());
6898
6938
  const scripts = packageJson.scripts || {};
6899
6939
  const updatedPackageJson = JSON.stringify(
6900
6940
  {
@@ -6907,7 +6947,7 @@ var addReactiveFile = {
6907
6947
  null,
6908
6948
  2
6909
6949
  );
6910
- fs14.writeFileSync(packageJsonPath, updatedPackageJson);
6950
+ fs15.writeFileSync(packageJsonPath, updatedPackageJson);
6911
6951
  }
6912
6952
  };
6913
6953
  function execShellCommand(cmd) {
@@ -7103,6 +7143,356 @@ var SearchIndexCommand = class extends Command7 {
7103
7143
  }
7104
7144
  };
7105
7145
 
7146
+ // src/next/commands/doctor-command/index.ts
7147
+ import { Command as Command8, Option as Option8 } from "clipanion";
7148
+
7149
+ // src/next/commands/doctor-command/doctor.ts
7150
+ import path16 from "path";
7151
+ import fs16 from "fs-extra";
7152
+ import yaml3 from "js-yaml";
7153
+ var DEPENDENCY_TYPES = [
7154
+ "dependencies",
7155
+ "devDependencies",
7156
+ "optionalDependencies",
7157
+ "peerDependencies"
7158
+ ];
7159
+ var LOCAL_REFERENCE_PREFIXES = [
7160
+ "file:",
7161
+ "link:",
7162
+ "patch:",
7163
+ "portal:",
7164
+ "workspace:"
7165
+ ];
7166
+ function isTinaPackage(name2) {
7167
+ return name2 === "tinacms" || name2 === "create-tina-app" || name2.startsWith("@tinacms/") || name2.startsWith("tinacms-") || name2.startsWith("next-tinacms-");
7168
+ }
7169
+ function getTinaDependencies(packageJson) {
7170
+ const dependencies = /* @__PURE__ */ new Map();
7171
+ for (const dependencyType of DEPENDENCY_TYPES) {
7172
+ for (const [name2, declared] of Object.entries(
7173
+ packageJson[dependencyType] || {}
7174
+ )) {
7175
+ if (!isTinaPackage(name2) || dependencies.has(name2)) continue;
7176
+ dependencies.set(name2, { name: name2, declared, dependencyType });
7177
+ }
7178
+ }
7179
+ return [...dependencies.values()].sort(
7180
+ (a, b) => a.name.localeCompare(b.name)
7181
+ );
7182
+ }
7183
+ async function readProjectPackageJson(rootPath) {
7184
+ const packageJsonPath = path16.join(rootPath, "package.json");
7185
+ if (!await fs16.pathExists(packageJsonPath)) {
7186
+ throw new Error(`No package.json found at ${packageJsonPath}`);
7187
+ }
7188
+ return fs16.readJSON(packageJsonPath);
7189
+ }
7190
+ async function resolveInstalledVersions({
7191
+ rootPath,
7192
+ dependencies
7193
+ }) {
7194
+ const lockfileVersions = await readLockfileVersions(rootPath);
7195
+ return Promise.all(
7196
+ dependencies.map(async (dependency) => {
7197
+ const installed = await readNodeModulesVersion(rootPath, dependency.name) || lockfileVersions.get(dependency.name);
7198
+ return { ...dependency, installed };
7199
+ })
7200
+ );
7201
+ }
7202
+ async function fetchLatestVersion(packageName, timeoutMs) {
7203
+ const controller = new AbortController();
7204
+ const timeout2 = setTimeout(() => controller.abort(), timeoutMs);
7205
+ try {
7206
+ const response = await fetch(
7207
+ `https://registry.npmjs.org/${encodeURIComponent(packageName)}`,
7208
+ { signal: controller.signal }
7209
+ );
7210
+ if (!response.ok) {
7211
+ throw new Error(`npm registry returned ${response.status}`);
7212
+ }
7213
+ const body = await response.json();
7214
+ const latest = body?.["dist-tags"]?.latest;
7215
+ if (typeof latest !== "string" || latest.length === 0) {
7216
+ throw new Error("npm registry response did not include dist-tags.latest");
7217
+ }
7218
+ return latest;
7219
+ } finally {
7220
+ clearTimeout(timeout2);
7221
+ }
7222
+ }
7223
+ function classifyDependency(dependency, latest, error) {
7224
+ if (!dependency.installed) {
7225
+ return {
7226
+ ...dependency,
7227
+ latest,
7228
+ status: "unknown",
7229
+ error: "Installed version could not be resolved from node_modules or lockfile"
7230
+ };
7231
+ }
7232
+ if (isLocalReference(dependency.installed)) {
7233
+ return {
7234
+ ...dependency,
7235
+ latest,
7236
+ status: "local",
7237
+ error
7238
+ };
7239
+ }
7240
+ if (!latest || error) {
7241
+ return {
7242
+ ...dependency,
7243
+ latest,
7244
+ status: "unknown",
7245
+ error
7246
+ };
7247
+ }
7248
+ return {
7249
+ ...dependency,
7250
+ latest,
7251
+ status: normalizeVersion(dependency.installed) === normalizeVersion(latest) ? "current" : "outdated"
7252
+ };
7253
+ }
7254
+ async function checkTinaDependencies({
7255
+ dependencies,
7256
+ fetchLatest
7257
+ }) {
7258
+ return Promise.all(
7259
+ dependencies.map(async (dependency) => {
7260
+ try {
7261
+ const latest = await fetchLatest(dependency.name);
7262
+ return classifyDependency(dependency, latest);
7263
+ } catch (error) {
7264
+ return classifyDependency(
7265
+ dependency,
7266
+ void 0,
7267
+ error instanceof Error ? error.message : String(error)
7268
+ );
7269
+ }
7270
+ })
7271
+ );
7272
+ }
7273
+ function formatDoctorTable(results) {
7274
+ const rows = [
7275
+ ["Package", "Type", "Declared", "Installed", "Latest", "Status"],
7276
+ ...results.map((result) => [
7277
+ result.name,
7278
+ result.dependencyType,
7279
+ result.declared,
7280
+ result.installed || "-",
7281
+ result.latest || "-",
7282
+ formatStatus(result)
7283
+ ])
7284
+ ];
7285
+ const widths = rows[0].map(
7286
+ (_, column) => Math.max(...rows.map((row) => row[column].length))
7287
+ );
7288
+ return rows.map((row, rowIndex) => {
7289
+ const line = row.map((cell, column) => cell.padEnd(widths[column])).join(" ");
7290
+ return rowIndex === 0 ? `${line}
7291
+ ${widths.map((w) => "-".repeat(w)).join(" ")}` : line;
7292
+ }).join("\n");
7293
+ }
7294
+ function formatStatus(result) {
7295
+ if (result.status === "outdated") return "OUTDATED";
7296
+ if (result.status === "local") return "LOCAL";
7297
+ if (result.status === "unknown")
7298
+ return `UNKNOWN${result.error ? ` (${result.error})` : ""}`;
7299
+ return "CURRENT";
7300
+ }
7301
+ function normalizeVersion(version2) {
7302
+ return version2.trim().replace(/^v/, "").split("(")[0].trim();
7303
+ }
7304
+ function isLocalReference(version2) {
7305
+ const normalized = version2.trim();
7306
+ return LOCAL_REFERENCE_PREFIXES.some(
7307
+ (prefix) => normalized.startsWith(prefix)
7308
+ );
7309
+ }
7310
+ async function readNodeModulesVersion(rootPath, packageName) {
7311
+ const packageJsonPath = path16.join(
7312
+ rootPath,
7313
+ "node_modules",
7314
+ ...packageName.split("/"),
7315
+ "package.json"
7316
+ );
7317
+ if (!await fs16.pathExists(packageJsonPath)) return void 0;
7318
+ const packageJson = await fs16.readJSON(packageJsonPath);
7319
+ return typeof packageJson.version === "string" ? packageJson.version : void 0;
7320
+ }
7321
+ async function readLockfileVersions(rootPath) {
7322
+ const readers = [
7323
+ readPackageLockVersions,
7324
+ readPnpmLockVersions,
7325
+ readYarnLockVersions
7326
+ ];
7327
+ for (const reader of readers) {
7328
+ const versions = await reader(rootPath);
7329
+ if (versions.size > 0) return versions;
7330
+ }
7331
+ return /* @__PURE__ */ new Map();
7332
+ }
7333
+ async function readPackageLockVersions(rootPath) {
7334
+ const lockfilePath = path16.join(rootPath, "package-lock.json");
7335
+ const versions = /* @__PURE__ */ new Map();
7336
+ if (!await fs16.pathExists(lockfilePath)) return versions;
7337
+ const lockfile = await fs16.readJSON(lockfilePath);
7338
+ for (const [key, value] of Object.entries(lockfile.packages || {})) {
7339
+ if (!key.startsWith("node_modules/")) continue;
7340
+ const name2 = key.replace(/^node_modules\//, "");
7341
+ const version2 = value.version;
7342
+ if (isTinaPackage(name2) && typeof version2 === "string") {
7343
+ versions.set(name2, version2);
7344
+ }
7345
+ }
7346
+ for (const [name2, value] of Object.entries(lockfile.dependencies || {})) {
7347
+ const version2 = value.version;
7348
+ if (isTinaPackage(name2) && typeof version2 === "string") {
7349
+ versions.set(name2, version2);
7350
+ }
7351
+ }
7352
+ return versions;
7353
+ }
7354
+ async function readPnpmLockVersions(rootPath) {
7355
+ const lockfilePath = path16.join(rootPath, "pnpm-lock.yaml");
7356
+ const versions = /* @__PURE__ */ new Map();
7357
+ if (!await fs16.pathExists(lockfilePath)) return versions;
7358
+ const lockfile = yaml3.load(await fs16.readFile(lockfilePath, "utf8"));
7359
+ const rootImporter = lockfile?.importers?.["."];
7360
+ for (const dependencyType of DEPENDENCY_TYPES) {
7361
+ for (const [name2, value] of Object.entries(
7362
+ rootImporter?.[dependencyType] || {}
7363
+ )) {
7364
+ if (!isTinaPackage(name2)) continue;
7365
+ const version2 = typeof value === "string" ? value : typeof value.version === "string" ? value.version : void 0;
7366
+ if (version2) versions.set(name2, normalizeInstalledVersion(version2));
7367
+ }
7368
+ }
7369
+ for (const key of Object.keys(lockfile?.packages || {})) {
7370
+ const parsed = parsePnpmPackageKey(key);
7371
+ if (parsed && isTinaPackage(parsed.name) && !versions.has(parsed.name)) {
7372
+ versions.set(parsed.name, parsed.version);
7373
+ }
7374
+ }
7375
+ return versions;
7376
+ }
7377
+ async function readYarnLockVersions(rootPath) {
7378
+ const lockfilePath = path16.join(rootPath, "yarn.lock");
7379
+ const versions = /* @__PURE__ */ new Map();
7380
+ if (!await fs16.pathExists(lockfilePath)) return versions;
7381
+ const contents = await fs16.readFile(lockfilePath, "utf8");
7382
+ if (contents.includes("__metadata:")) {
7383
+ return readYarnBerryLockVersions(contents);
7384
+ }
7385
+ const lines = contents.split("\n");
7386
+ let activeNames = [];
7387
+ for (const line of lines) {
7388
+ if (line.length > 0 && !line.startsWith(" ") && line.includes("@")) {
7389
+ activeNames = extractYarnPackageNames(line);
7390
+ continue;
7391
+ }
7392
+ const version2 = line.match(/^\s+version\s+"([^"]+)"/)?.[1];
7393
+ if (!version2) continue;
7394
+ for (const name2 of activeNames) {
7395
+ if (isTinaPackage(name2) && !versions.has(name2)) {
7396
+ versions.set(name2, version2);
7397
+ }
7398
+ }
7399
+ }
7400
+ return versions;
7401
+ }
7402
+ function readYarnBerryLockVersions(contents) {
7403
+ const versions = /* @__PURE__ */ new Map();
7404
+ const lockfile = yaml3.load(contents);
7405
+ for (const [descriptor, value] of Object.entries(lockfile || {})) {
7406
+ if (descriptor === "__metadata") continue;
7407
+ const name2 = extractYarnBerryPackageName(descriptor);
7408
+ const version2 = getYarnBerryInstalledVersion(descriptor, value?.version);
7409
+ if (name2 && isTinaPackage(name2) && version2) {
7410
+ versions.set(name2, version2);
7411
+ }
7412
+ }
7413
+ return versions;
7414
+ }
7415
+ function parsePnpmPackageKey(key) {
7416
+ const normalized = key.replace(/^\//, "");
7417
+ const match = normalized.match(/^(@[^/]+\/[^@]+|[^@/]+)@([^(/]+)/);
7418
+ if (!match) return void 0;
7419
+ return { name: match[1], version: normalizeVersion(match[2]) };
7420
+ }
7421
+ function normalizeInstalledVersion(version2) {
7422
+ return isLocalReference(version2) ? version2 : normalizeVersion(version2);
7423
+ }
7424
+ function extractYarnPackageNames(line) {
7425
+ return line.replace(/:$/, "").split(/,\s*/).map((descriptor) => descriptor.trim().replace(/^"|"$/g, "")).map((descriptor) => {
7426
+ if (descriptor.startsWith("@")) {
7427
+ const [, scope, name2] = descriptor.match(/^(@[^/]+)\/([^@]+)/) || [];
7428
+ return scope && name2 ? `${scope}/${name2}` : descriptor;
7429
+ }
7430
+ return descriptor.split("@")[0];
7431
+ }).filter(Boolean);
7432
+ }
7433
+ function extractYarnBerryPackageName(descriptor) {
7434
+ if (descriptor.startsWith("@")) {
7435
+ return descriptor.match(/^(@[^/]+\/[^@]+)/)?.[1];
7436
+ }
7437
+ return descriptor.split("@")[0] || void 0;
7438
+ }
7439
+ function getYarnBerryInstalledVersion(descriptor, version2) {
7440
+ const name2 = extractYarnBerryPackageName(descriptor);
7441
+ const reference = name2 ? descriptor.slice(name2.length + 1) : void 0;
7442
+ if (reference && isLocalReference(reference)) return reference;
7443
+ return typeof version2 === "string" ? normalizeInstalledVersion(version2) : void 0;
7444
+ }
7445
+
7446
+ // src/next/commands/doctor-command/index.ts
7447
+ var DoctorCommand = class extends Command8 {
7448
+ static paths = [["doctor"]];
7449
+ rootPath = Option8.String("--rootPath", {
7450
+ description: "Specify the root directory to inspect (defaults to current working directory)"
7451
+ });
7452
+ json = Option8.Boolean("--json", false, {
7453
+ description: "Print machine-readable JSON output"
7454
+ });
7455
+ timeout = Option8.String("--timeout", "5000", {
7456
+ description: "npm registry request timeout in milliseconds"
7457
+ });
7458
+ static usage = Command8.Usage({
7459
+ category: "Commands",
7460
+ description: "Check direct TinaCMS dependencies against npm latest"
7461
+ });
7462
+ async catch(error) {
7463
+ const message = error instanceof Error ? error.message : String(error);
7464
+ logger.error(`Error occurred during tinacms doctor: ${message}`);
7465
+ process.exit(1);
7466
+ }
7467
+ async execute() {
7468
+ const rootPath = this.rootPath || process.cwd();
7469
+ const timeoutMs = Number(this.timeout);
7470
+ if (!Number.isFinite(timeoutMs) || timeoutMs <= 0) {
7471
+ logger.error("--timeout must be a positive number");
7472
+ return 1;
7473
+ }
7474
+ const packageJson = await readProjectPackageJson(rootPath);
7475
+ const dependencies = await resolveInstalledVersions({
7476
+ rootPath,
7477
+ dependencies: getTinaDependencies(packageJson)
7478
+ });
7479
+ const results = await checkTinaDependencies({
7480
+ dependencies,
7481
+ fetchLatest: (name2) => fetchLatestVersion(name2, timeoutMs)
7482
+ });
7483
+ if (this.json) {
7484
+ logger.info(JSON.stringify({ rootPath, results }, null, 2));
7485
+ } else if (results.length === 0) {
7486
+ logger.info("No direct TinaCMS dependencies found.");
7487
+ } else {
7488
+ logger.info(formatDoctorTable(results));
7489
+ }
7490
+ const hasOutdated = results.some((result) => result.status === "outdated");
7491
+ const hasUnknown = results.some((result) => result.status === "unknown");
7492
+ return hasOutdated || hasUnknown ? 1 : 0;
7493
+ }
7494
+ };
7495
+
7106
7496
  // src/index.ts
7107
7497
  var cli = new Cli({
7108
7498
  binaryName: `tinacms`,
@@ -7115,6 +7505,7 @@ cli.register(AuditCommand);
7115
7505
  cli.register(InitCommand);
7116
7506
  cli.register(CodemodCommand);
7117
7507
  cli.register(SearchIndexCommand);
7508
+ cli.register(DoctorCommand);
7118
7509
  cli.register(Builtins.DefinitionsCommand);
7119
7510
  cli.register(Builtins.HelpCommand);
7120
7511
  cli.register(Builtins.VersionCommand);