@tinacms/cli 1.0.5 → 1.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -10,5 +10,5 @@
10
10
  See the License for the specific language governing permissions and
11
11
  limitations under the License.
12
12
  */
13
- export declare const attachPath: (ctx: any, next: () => void, _options: any) => Promise<void>;
13
+ export declare const attachPath: (ctx: any, next: () => void, options: any) => Promise<void>;
14
14
  export declare const isProjectTs: (rootPath: string) => Promise<boolean>;
@@ -17,6 +17,7 @@ interface ClientGenOptions {
17
17
  local?: boolean;
18
18
  verbose?: boolean;
19
19
  port?: number;
20
+ rootPath?: string;
20
21
  }
21
22
  interface BuildOptions {
22
23
  local: boolean;
@@ -53,7 +54,7 @@ export declare class ConfigBuilder {
53
54
  graphQLSchema: DocumentNode;
54
55
  tinaSchema: any;
55
56
  }>;
56
- genTypedClient({ usingTs, compiledSchema, noSDK, verbose, local, port, }: ClientGenOptions & {
57
+ genTypedClient({ usingTs, compiledSchema, noSDK, verbose, local, port, rootPath, }: ClientGenOptions & {
57
58
  usingTs: boolean;
58
59
  compiledSchema: any;
59
60
  }): Promise<string>;
@@ -10,7 +10,13 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
10
  See the License for the specific language governing permissions and
11
11
  limitations under the License.
12
12
  */
13
- import type { TinaCloudCollection } from '@tinacms/schema-tools';
13
+ import type { TinaCloudCollection, TinaFieldInner } from '@tinacms/schema-tools';
14
+ export declare const generateAllCollections: ({ rootPath, }: {
15
+ rootPath: string;
16
+ }) => Promise<Map<string, {
17
+ fields: TinaFieldInner<false>[];
18
+ templateObj: any;
19
+ }>>;
14
20
  export declare const generateCollections: ({ forestryPath, rootPath, }: {
15
21
  forestryPath: string;
16
22
  rootPath: string;
@@ -0,0 +1,40 @@
1
+ /**
2
+ Copyright 2021 Forestry.io Holdings, Inc.
3
+ Licensed under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License.
5
+ You may obtain a copy of the License at
6
+ http://www.apache.org/licenses/LICENSE-2.0
7
+ Unless required by applicable law or agreed to in writing, software
8
+ distributed under the License is distributed on an "AS IS" BASIS,
9
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
+ See the License for the specific language governing permissions and
11
+ limitations under the License.
12
+ */
13
+ interface NameError {
14
+ name: string;
15
+ template: string;
16
+ newName: string;
17
+ }
18
+ /**
19
+ * The Singleton class defines the `getInstance` method that lets clients access
20
+ * the unique singleton instance.
21
+ */
22
+ export declare class ErrorSingleton {
23
+ private static instance;
24
+ /**
25
+ * The Singleton's constructor should always be private to prevent direct
26
+ * construction calls with the `new` operator.
27
+ */
28
+ private constructor();
29
+ /**
30
+ * The static method that controls the access to the singleton instance.
31
+ *
32
+ * This implementation let you subclass the Singleton class while keeping
33
+ * just one instance of each subclass around.
34
+ */
35
+ static getInstance(): ErrorSingleton;
36
+ private allErrorNames;
37
+ addErrorName(error: NameError): void;
38
+ printNameErrors(): void;
39
+ }
40
+ export {};
@@ -12,20 +12,24 @@ limitations under the License.
12
12
  */
13
13
  import z from 'zod';
14
14
  import type { TinaFieldInner } from '@tinacms/schema-tools';
15
+ export declare const stringifyName: (name: string, template: string) => string;
15
16
  declare const forestryFieldWithoutField: z.ZodObject<{
16
17
  type: z.ZodUnion<[z.ZodLiteral<"text">, z.ZodLiteral<"datetime">, z.ZodLiteral<"list">, z.ZodLiteral<"file">, z.ZodLiteral<"image_gallery">, z.ZodLiteral<"textarea">, z.ZodLiteral<"tag_list">, z.ZodLiteral<"number">, z.ZodLiteral<"boolean">, z.ZodLiteral<"field_group">, z.ZodLiteral<"field_group_list">, z.ZodLiteral<"select">, z.ZodLiteral<"include">, z.ZodLiteral<"blocks">, z.ZodLiteral<"color">]>;
18
+ template_types: z.ZodNullable<z.ZodOptional<z.ZodArray<z.ZodString, "many">>>;
17
19
  name: z.ZodString;
18
20
  label: z.ZodString;
19
21
  default: z.ZodOptional<z.ZodAny>;
20
22
  config: z.ZodOptional<z.ZodObject<{
21
- required: z.ZodOptional<z.ZodBoolean>;
22
- use_select: z.ZodOptional<z.ZodBoolean>;
23
- date_format: z.ZodOptional<z.ZodString>;
24
- time_format: z.ZodOptional<z.ZodString>;
25
- options: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
23
+ min: z.ZodNullable<z.ZodOptional<z.ZodNumber>>;
24
+ max: z.ZodNullable<z.ZodOptional<z.ZodNumber>>;
25
+ required: z.ZodNullable<z.ZodOptional<z.ZodBoolean>>;
26
+ use_select: z.ZodNullable<z.ZodOptional<z.ZodBoolean>>;
27
+ date_format: z.ZodNullable<z.ZodOptional<z.ZodString>>;
28
+ time_format: z.ZodNullable<z.ZodOptional<z.ZodString>>;
29
+ options: z.ZodNullable<z.ZodOptional<z.ZodArray<z.ZodString, "many">>>;
26
30
  source: z.ZodOptional<z.ZodObject<{
27
- type: z.ZodOptional<z.ZodUnion<[z.ZodLiteral<"custom">, z.ZodLiteral<"pages">, z.ZodLiteral<"documents">, z.ZodLiteral<"simple">, z.ZodString]>>;
28
- section: z.ZodOptional<z.ZodString>;
31
+ type: z.ZodNullable<z.ZodOptional<z.ZodUnion<[z.ZodLiteral<"custom">, z.ZodLiteral<"pages">, z.ZodLiteral<"documents">, z.ZodLiteral<"simple">, z.ZodString]>>>;
32
+ section: z.ZodNullable<z.ZodOptional<z.ZodString>>;
29
33
  }, "strip", z.ZodTypeAny, {
30
34
  type?: string;
31
35
  section?: string;
@@ -36,6 +40,8 @@ declare const forestryFieldWithoutField: z.ZodObject<{
36
40
  }, "strip", z.ZodTypeAny, {
37
41
  required?: boolean;
38
42
  options?: string[];
43
+ min?: number;
44
+ max?: number;
39
45
  use_select?: boolean;
40
46
  date_format?: string;
41
47
  time_format?: string;
@@ -46,6 +52,8 @@ declare const forestryFieldWithoutField: z.ZodObject<{
46
52
  }, {
47
53
  required?: boolean;
48
54
  options?: string[];
55
+ min?: number;
56
+ max?: number;
49
57
  use_select?: boolean;
50
58
  date_format?: string;
51
59
  time_format?: string;
@@ -60,6 +68,8 @@ declare const forestryFieldWithoutField: z.ZodObject<{
60
68
  config?: {
61
69
  required?: boolean;
62
70
  options?: string[];
71
+ min?: number;
72
+ max?: number;
63
73
  use_select?: boolean;
64
74
  date_format?: string;
65
75
  time_format?: string;
@@ -70,12 +80,15 @@ declare const forestryFieldWithoutField: z.ZodObject<{
70
80
  };
71
81
  name?: string;
72
82
  type?: "number" | "boolean" | "file" | "datetime" | "text" | "list" | "select" | "image_gallery" | "textarea" | "tag_list" | "field_group" | "field_group_list" | "include" | "blocks" | "color";
83
+ template_types?: string[];
73
84
  }, {
74
85
  default?: any;
75
86
  label?: string;
76
87
  config?: {
77
88
  required?: boolean;
78
89
  options?: string[];
90
+ min?: number;
91
+ max?: number;
79
92
  use_select?: boolean;
80
93
  date_format?: string;
81
94
  time_format?: string;
@@ -86,6 +99,7 @@ declare const forestryFieldWithoutField: z.ZodObject<{
86
99
  };
87
100
  name?: string;
88
101
  type?: "number" | "boolean" | "file" | "datetime" | "text" | "list" | "select" | "image_gallery" | "textarea" | "tag_list" | "field_group" | "field_group_list" | "include" | "blocks" | "color";
102
+ template_types?: string[];
89
103
  }>;
90
104
  declare type ForestryFieldWithoutFieldType = z.infer<typeof forestryFieldWithoutField>;
91
105
  interface ForestryFieldType extends ForestryFieldWithoutFieldType {
@@ -104,15 +118,25 @@ declare const FrontmatterTemplateSchema: z.ZodObject<{
104
118
  fields?: ForestryFieldType[];
105
119
  hide_body?: boolean;
106
120
  }>;
107
- export declare const transformForestryFieldsToTinaFields: ({ fields, collection, }: {
121
+ export declare const transformForestryFieldsToTinaFields: ({ fields, rootPath, template, skipBlocks, }: {
108
122
  fields: z.infer<typeof FrontmatterTemplateSchema>['fields'];
109
- collection: string;
123
+ rootPath: string;
124
+ template: string;
125
+ skipBlocks?: boolean;
110
126
  }) => TinaFieldInner<false>[];
111
- export declare const getFieldsFromTemplates: ({ tem, rootPath, collection, }: {
127
+ export declare const getFieldsFromTemplates: (_args: {
112
128
  tem: string;
113
- collection: string;
114
129
  rootPath: string;
115
- }) => TinaFieldInner<false>[];
130
+ skipBlocks?: boolean;
131
+ }) => {
132
+ fields: TinaFieldInner<false>[];
133
+ templateObj: any;
134
+ template: {
135
+ label?: string;
136
+ hide_body?: boolean;
137
+ fields?: ForestryFieldType[];
138
+ };
139
+ };
116
140
  export declare const parseTemplates: ({ val }: {
117
141
  val: unknown;
118
142
  }) => {
@@ -13,11 +13,13 @@ limitations under the License.
13
13
  import { GraphQLSchema } from 'graphql';
14
14
  import { TinaCloudSchema } from '@tinacms/schema-tools';
15
15
  export declare const TINA_HOST = "content.tinajs.io";
16
- export declare function genClient({ tinaSchema, usingTs, }: {
16
+ export declare function genClient({ tinaSchema, usingTs, rootPath, }: {
17
17
  tinaSchema: TinaCloudSchema<false>;
18
18
  usingTs?: boolean;
19
+ rootPath: string;
19
20
  }, options: any): Promise<string>;
20
- export declare function genTypes({ schema, usingTs }: {
21
+ export declare function genTypes({ schema, usingTs, rootPath, }: {
21
22
  schema: GraphQLSchema;
22
23
  usingTs?: boolean;
24
+ rootPath: string;
23
25
  }, next: () => void, options: any): Promise<void>;
package/dist/index.js CHANGED
@@ -77,13 +77,14 @@ var init_media = __esm({
77
77
  import_path9 = __toModule(require("path"));
78
78
  init_utils();
79
79
  MediaModel = class {
80
- constructor({ publicFolder, mediaRoot }) {
80
+ constructor({ rootPath: rootPath2, publicFolder, mediaRoot }) {
81
+ this.rootPath = rootPath2;
81
82
  this.mediaRoot = mediaRoot;
82
83
  this.publicFolder = publicFolder;
83
84
  }
84
85
  async listMedia(args) {
85
86
  try {
86
- const folderPath = (0, import_path9.join)(this.publicFolder, this.mediaRoot, args.searchPath);
87
+ const folderPath = (0, import_path9.join)(this.rootPath, this.publicFolder, this.mediaRoot, args.searchPath);
87
88
  const searchPath = parseMediaFolder(args.searchPath);
88
89
  const filesStr = await import_fs_extra7.default.readdir(folderPath);
89
90
  const filesProm = filesStr.map(async (file) => {
@@ -144,7 +145,7 @@ var init_media = __esm({
144
145
  }
145
146
  async deleteMedia(args) {
146
147
  try {
147
- const file = (0, import_path9.join)(this.publicFolder, this.mediaRoot, args.searchPath);
148
+ const file = (0, import_path9.join)(this.rootPath, this.publicFolder, this.mediaRoot, args.searchPath);
148
149
  await import_fs_extra7.default.stat(file);
149
150
  await import_fs_extra7.default.remove(file);
150
151
  return { ok: true };
@@ -166,7 +167,7 @@ var init_routes = __esm({
166
167
  import_multer = __toModule(require("multer"));
167
168
  init_media();
168
169
  createMediaRouter = (config2) => {
169
- const mediaFolder = (0, import_path10.join)(process.cwd(), config2.publicFolder, config2.mediaRoot);
170
+ const mediaFolder = (0, import_path10.join)(config2.rootPath, config2.publicFolder, config2.mediaRoot);
170
171
  const storage = import_multer.default.diskStorage({
171
172
  destination: function(req, file, cb) {
172
173
  cb(null, mediaFolder);
@@ -265,6 +266,7 @@ var init_server = __esm({
265
266
  const schema = await db.getSchema();
266
267
  const mediaPaths = (_c = (_b = (_a = schema == null ? void 0 : schema.schema) == null ? void 0 : _a.config) == null ? void 0 : _b.media) == null ? void 0 : _c.tina;
267
268
  app.use("/media", createMediaRouter({
269
+ rootPath: db.bridge.rootPath,
268
270
  publicFolder: parseMediaFolder((mediaPaths == null ? void 0 : mediaPaths.publicFolder) || ""),
269
271
  mediaRoot: parseMediaFolder((mediaPaths == null ? void 0 : mediaPaths.mediaRoot) || "")
270
272
  }));
@@ -302,7 +304,7 @@ var commander = __toModule(require("commander"));
302
304
 
303
305
  // package.json
304
306
  var name = "@tinacms/cli";
305
- var version = "1.0.5";
307
+ var version = "1.0.7";
306
308
 
307
309
  // src/cmds/audit/audit.ts
308
310
  var import_graphql = __toModule(require("@tinacms/graphql"));
@@ -366,7 +368,7 @@ var auditDocuments = async (args) => {
366
368
  includeCollection: true,
367
369
  includeTemplate: typeof collection.templates !== "undefined"
368
370
  }, topLevelDefaults);
369
- const mutation = `mutation($collection: String!, $relativePath: String!, $params: DocumentMutation!) {
371
+ const mutation = `mutation($collection: String!, $relativePath: String!, $params: DocumentUpdateMutation!) {
370
372
  updateDocument(
371
373
  collection: $collection,
372
374
  relativePath: $relativePath,
@@ -626,9 +628,9 @@ var fileExists = ({
626
628
  }
627
629
  const filePaths = allowedTypes.map((ext) => import_path2.default.join(projectDir, `${filename}.${ext}`));
628
630
  let inputFile = void 0;
629
- filePaths.every((path10) => {
630
- if (import_fs_extra.default.existsSync(path10)) {
631
- inputFile = path10;
631
+ filePaths.every((path11) => {
632
+ if (import_fs_extra.default.existsSync(path11)) {
633
+ inputFile = path11;
632
634
  return false;
633
635
  }
634
636
  return true;
@@ -646,9 +648,9 @@ var getPath = ({
646
648
  }
647
649
  const filePaths = allowedTypes.map((ext) => import_path2.default.join(projectDir, `${filename}.${ext}`));
648
650
  let inputFile = void 0;
649
- filePaths.every((path10) => {
650
- if (import_fs_extra.default.existsSync(path10)) {
651
- inputFile = path10;
651
+ filePaths.every((path11) => {
652
+ if (import_fs_extra.default.existsSync(path11)) {
653
+ inputFile = path11;
652
654
  return false;
653
655
  }
654
656
  return true;
@@ -724,15 +726,15 @@ var cleanup = async ({ tinaTempPath }) => {
724
726
  await import_fs_extra2.default.remove(tinaTempPath);
725
727
  };
726
728
  var compileFile = async (options, fileName) => {
727
- const root2 = options.rootPath;
728
- if (!root2) {
729
+ const root = options.rootPath;
730
+ if (!root) {
729
731
  throw new Error("ctx.rootPath has not been attached");
730
732
  }
731
- const tinaPath = import_path3.default.join(root2, ".tina");
732
- const tsConfigPath = import_path3.default.join(root2, "tsconfig.json");
733
+ const tinaPath = import_path3.default.join(root, ".tina");
734
+ const tsConfigPath = import_path3.default.join(root, "tsconfig.json");
733
735
  const tinaGeneratedPath = import_path3.default.join(tinaPath, "__generated__");
734
736
  const tinaTempPath = import_path3.default.join(tinaGeneratedPath, `temp_${fileName}`);
735
- const packageJSONFilePath = import_path3.default.join(root2, "package.json");
737
+ const packageJSONFilePath = import_path3.default.join(root, "package.json");
736
738
  if (!options.schemaFileType) {
737
739
  const usingTs = await import_fs_extra2.default.pathExists(tsConfigPath);
738
740
  options = __spreadProps(__spreadValues({}, options), { schemaFileType: usingTs ? "ts" : "js" });
@@ -783,8 +785,8 @@ var compileFile = async (options, fileName) => {
783
785
  return returnObject;
784
786
  };
785
787
  var compileSchema = async (options) => {
786
- const root2 = options.rootPath;
787
- const tinaPath = import_path3.default.join(root2, ".tina");
788
+ const root = options.rootPath;
789
+ const tinaPath = import_path3.default.join(root, ".tina");
788
790
  const tinaGeneratedPath = import_path3.default.join(tinaPath, "__generated__");
789
791
  const tinaConfigPath = import_path3.default.join(tinaGeneratedPath, "config");
790
792
  const schemaExists = fileExists({
@@ -1081,13 +1083,13 @@ var loadGraphQLDocuments = async (globPath) => {
1081
1083
  // src/cmds/query-gen/genTypes.ts
1082
1084
  var import_esbuild2 = __toModule(require("esbuild"));
1083
1085
  var TINA_HOST = "content.tinajs.io";
1084
- var root = process.cwd();
1085
- var generatedPath = import_path5.default.join(root, ".tina", "__generated__");
1086
1086
  async function genClient({
1087
1087
  tinaSchema,
1088
- usingTs
1088
+ usingTs,
1089
+ rootPath: rootPath2
1089
1090
  }, options) {
1090
1091
  var _a, _b, _c, _d, _e;
1092
+ const generatedPath = import_path5.default.join(rootPath2, ".tina", "__generated__");
1091
1093
  const branch = (_a = tinaSchema == null ? void 0 : tinaSchema.config) == null ? void 0 : _a.branch;
1092
1094
  const clientId = (_b = tinaSchema == null ? void 0 : tinaSchema.config) == null ? void 0 : _b.clientId;
1093
1095
  const token = (_c = tinaSchema.config) == null ? void 0 : _c.token;
@@ -1111,12 +1113,16 @@ export default client;
1111
1113
  `);
1112
1114
  return apiURL;
1113
1115
  }
1114
- async function genTypes({ schema, usingTs }, next, options) {
1115
- const typesPath = process.cwd() + "/.tina/__generated__/types.ts";
1116
- const typesJSPath = process.cwd() + "/.tina/__generated__/types.js";
1117
- const typesDPath = process.cwd() + "/.tina/__generated__/types.d.ts";
1118
- const fragPath = process.cwd() + "/.tina/__generated__/*.{graphql,gql}";
1119
- const queryPathGlob = process.cwd() + "/.tina/queries/**/*.{graphql,gql}";
1116
+ async function genTypes({
1117
+ schema,
1118
+ usingTs,
1119
+ rootPath: rootPath2
1120
+ }, next, options) {
1121
+ const typesPath = rootPath2 + "/.tina/__generated__/types.ts";
1122
+ const typesJSPath = rootPath2 + "/.tina/__generated__/types.js";
1123
+ const typesDPath = rootPath2 + "/.tina/__generated__/types.d.ts";
1124
+ const fragPath = rootPath2 + "/.tina/__generated__/*.{graphql,gql}";
1125
+ const queryPathGlob = rootPath2 + "/.tina/queries/**/*.{graphql,gql}";
1120
1126
  const typescriptTypes = await generateTypes(schema, queryPathGlob, fragPath, options);
1121
1127
  const code = `//@ts-nocheck
1122
1128
  // DO NOT MODIFY THIS FILE. This file is automatically generated by Tina
@@ -1137,7 +1143,7 @@ async function genTypes({ schema, usingTs }, next, options) {
1137
1143
  await import_fs_extra3.default.outputFile(typesJSPath, jsCode.code);
1138
1144
  }
1139
1145
  const schemaString = await (0, import_graphql8.printSchema)(schema);
1140
- const schemaPath = process.cwd() + "/.tina/__generated__/schema.gql";
1146
+ const schemaPath = rootPath2 + "/.tina/__generated__/schema.gql";
1141
1147
  await import_fs_extra3.default.outputFile(schemaPath, `# DO NOT MODIFY THIS FILE. This file is automatically generated by Tina
1142
1148
  ${schemaString}
1143
1149
  schema {
@@ -1219,7 +1225,7 @@ var import_app = __toModule(require("@tinacms/app"));
1219
1225
 
1220
1226
  // src/utils/spinner.ts
1221
1227
  var import_cli_spinner = __toModule(require("cli-spinner"));
1222
- async function spin({
1228
+ async function localSpin({
1223
1229
  waitFor,
1224
1230
  text
1225
1231
  }) {
@@ -1238,12 +1244,26 @@ async function spin({
1238
1244
  console.log("");
1239
1245
  return res;
1240
1246
  }
1247
+ function spin({
1248
+ waitFor,
1249
+ text
1250
+ }) {
1251
+ if (process.env.CI) {
1252
+ console.log(text);
1253
+ return waitFor();
1254
+ } else {
1255
+ return localSpin({
1256
+ text,
1257
+ waitFor
1258
+ });
1259
+ }
1260
+ }
1241
1261
 
1242
1262
  // src/buildTina/attachPath.ts
1243
1263
  var import_fs_extra5 = __toModule(require("fs-extra"));
1244
1264
  var import_path7 = __toModule(require("path"));
1245
- var attachPath = async (ctx, next, _options) => {
1246
- ctx.rootPath = process.cwd();
1265
+ var attachPath = async (ctx, next, options) => {
1266
+ ctx.rootPath = options.rootPath || process.cwd();
1247
1267
  ctx.usingTs = await isProjectTs(ctx.rootPath);
1248
1268
  next();
1249
1269
  };
@@ -1310,6 +1330,7 @@ var buildCmdBuild = async (ctx, next, options) => {
1310
1330
  noSDK: options.noSDK,
1311
1331
  verbose: options.verbose,
1312
1332
  usingTs: ctx.usingTs,
1333
+ rootPath: ctx.rootPath,
1313
1334
  port: options.port
1314
1335
  });
1315
1336
  ctx.apiUrl = apiUrl;
@@ -1340,6 +1361,7 @@ var ConfigBuilder = class {
1340
1361
  this.database = database;
1341
1362
  }
1342
1363
  async build({ dev, verbose, rootPath: rootPath2, local }) {
1364
+ var _a, _b, _c;
1343
1365
  const usingTs = await isProjectTs(rootPath2);
1344
1366
  if (!rootPath2) {
1345
1367
  throw new Error("Root path has not been attached");
@@ -1359,6 +1381,23 @@ var ConfigBuilder = class {
1359
1381
  dev,
1360
1382
  rootPath: rootPath2
1361
1383
  });
1384
+ if (this.database.bridge.addOutputPath && ((_a = compiledSchema.config) == null ? void 0 : _a.localContentPath)) {
1385
+ if ((_c = (_b = compiledSchema == null ? void 0 : compiledSchema.config) == null ? void 0 : _b.media) == null ? void 0 : _c.tina) {
1386
+ throw new Error(`"media.tina" is not supported when the "localContentPath" property is present.`);
1387
+ }
1388
+ let localContentPath = compiledSchema.config.localContentPath;
1389
+ if (!localContentPath.startsWith("/")) {
1390
+ localContentPath = import_path8.default.join(process.cwd(), ".tina", localContentPath);
1391
+ }
1392
+ if (await import_fs_extra6.default.pathExists(localContentPath)) {
1393
+ logger.info(logText(`Using separate content path ${localContentPath}`));
1394
+ } else {
1395
+ logger.warn(warnText(`Using separate content path ${localContentPath}
1396
+ but no directory was found at that location, creating one...`));
1397
+ await import_fs_extra6.default.mkdir(localContentPath);
1398
+ }
1399
+ this.database.bridge.addOutputPath(localContentPath);
1400
+ }
1362
1401
  const { graphQLSchema, tinaSchema } = await (0, import_graphql9.buildSchema)(rootPath2, this.database, ["experimentalData", "isomorphicGitBridge"]);
1363
1402
  return { schema: compiledSchema, graphQLSchema, tinaSchema };
1364
1403
  }
@@ -1368,15 +1407,16 @@ var ConfigBuilder = class {
1368
1407
  noSDK,
1369
1408
  verbose,
1370
1409
  local,
1371
- port
1410
+ port,
1411
+ rootPath: rootPath2
1372
1412
  }) {
1373
1413
  const astSchema = await (0, import_graphql9.getASTSchema)(this.database);
1374
- await genTypes({ schema: astSchema, usingTs }, () => {
1414
+ await genTypes({ schema: astSchema, usingTs, rootPath: rootPath2 }, () => {
1375
1415
  }, {
1376
1416
  noSDK,
1377
1417
  verbose
1378
1418
  });
1379
- return genClient({ tinaSchema: compiledSchema, usingTs }, {
1419
+ return genClient({ tinaSchema: compiledSchema, usingTs, rootPath: rootPath2 }, {
1380
1420
  local,
1381
1421
  port
1382
1422
  });
@@ -1524,7 +1564,8 @@ async function startServer(ctx, next, {
1524
1564
  noSDK,
1525
1565
  verbose,
1526
1566
  usingTs: ctx.usingTs,
1527
- port
1567
+ port,
1568
+ rootPath: ctx.rootPath
1528
1569
  });
1529
1570
  await spin({
1530
1571
  waitFor: async () => {
@@ -1640,7 +1681,8 @@ var waitForDB = async (ctx, next, options) => {
1640
1681
  }
1641
1682
  const response = await fetch(`https://${host}/db/${clientId}/status/${branch}`, {
1642
1683
  method: "GET",
1643
- headers
1684
+ headers,
1685
+ cache: "no-cache"
1644
1686
  });
1645
1687
  const { status, error } = await response.json();
1646
1688
  const statusMessage = `Indexing status: '${status}'`;
@@ -1728,7 +1770,7 @@ stack: ${code.stack || "No stack was provided"}`);
1728
1770
  };
1729
1771
 
1730
1772
  // src/cmds/init/index.ts
1731
- var import_path13 = __toModule(require("path"));
1773
+ var import_path14 = __toModule(require("path"));
1732
1774
  var import_prettier = __toModule(require("prettier"));
1733
1775
  var import_fs_extra10 = __toModule(require("fs-extra"));
1734
1776
  var import_prompts2 = __toModule(require("prompts"));
@@ -2076,6 +2118,44 @@ var import_fs_extra8 = __toModule(require("fs-extra"));
2076
2118
  var import_path12 = __toModule(require("path"));
2077
2119
  var import_js_yaml = __toModule(require("js-yaml"));
2078
2120
  var import_zod = __toModule(require("zod"));
2121
+
2122
+ // src/cmds/forestry-migrate/util/errorSingleton.ts
2123
+ var ErrorSingleton = class {
2124
+ constructor() {
2125
+ }
2126
+ static getInstance() {
2127
+ if (!ErrorSingleton.instance) {
2128
+ ErrorSingleton.instance = new ErrorSingleton();
2129
+ ErrorSingleton.instance.allErrorNames = [];
2130
+ }
2131
+ return ErrorSingleton.instance;
2132
+ }
2133
+ addErrorName(error) {
2134
+ this.allErrorNames.push(error);
2135
+ }
2136
+ printNameErrors() {
2137
+ logger.error(dangerText("ERROR: TinaCMS only supports alphanumeric field names"));
2138
+ logger.error(`If you wish to edit any of the following fields or template names you will have to update your content and code to use the new name. See ${linkText("https://tina.io/docs/forestry/common-errors/#migrating-fields-with-non-alphanumeric-characters")} for more information.`);
2139
+ logger.error("The following template and field names have been renamed:`");
2140
+ this.allErrorNames.forEach((error) => {
2141
+ logger.error(`- Content that uses ${error.template}.yaml: ${error.name} -> ${error.newName}`);
2142
+ });
2143
+ }
2144
+ };
2145
+
2146
+ // src/cmds/forestry-migrate/util/index.ts
2147
+ var errorSingletonInstance = ErrorSingleton.getInstance();
2148
+ var stringifyName = (name2, template) => {
2149
+ const testRegex = /^[a-zA-Z0-9_]*$/;
2150
+ const updateRegex = /[^a-zA-Z0-9]/g;
2151
+ if (testRegex.test(name2)) {
2152
+ return name2;
2153
+ } else {
2154
+ const newName = name2.replace(updateRegex, "_");
2155
+ errorSingletonInstance.addErrorName({ name: name2, newName, template });
2156
+ return newName;
2157
+ }
2158
+ };
2079
2159
  var forestryConfigSchema = import_zod.default.object({
2080
2160
  sections: import_zod.default.array(import_zod.default.object({
2081
2161
  type: import_zod.default.union([
@@ -2086,13 +2166,13 @@ var forestryConfigSchema = import_zod.default.object({
2086
2166
  import_zod.default.literal("jekyll-posts")
2087
2167
  ]),
2088
2168
  label: import_zod.default.string(),
2089
- path: import_zod.default.string().optional(),
2090
- match: import_zod.default.string().optional(),
2091
- exclude: import_zod.default.string().optional(),
2169
+ path: import_zod.default.string().optional().nullable(),
2170
+ match: import_zod.default.string().optional().nullable(),
2171
+ exclude: import_zod.default.string().optional().nullable(),
2092
2172
  create: import_zod.default.union([import_zod.default.literal("all"), import_zod.default.literal("documents"), import_zod.default.literal("none")]).optional(),
2093
- templates: import_zod.default.array(import_zod.default.string()).optional(),
2094
- new_doc_ext: import_zod.default.string().optional(),
2095
- read_only: import_zod.default.boolean().optional()
2173
+ templates: import_zod.default.array(import_zod.default.string()).optional().nullable(),
2174
+ new_doc_ext: import_zod.default.string().optional().nullable(),
2175
+ read_only: import_zod.default.boolean().optional().nullable()
2096
2176
  }))
2097
2177
  });
2098
2178
  var forestryFieldWithoutField = import_zod.default.object({
@@ -2113,15 +2193,18 @@ var forestryFieldWithoutField = import_zod.default.object({
2113
2193
  import_zod.default.literal("blocks"),
2114
2194
  import_zod.default.literal("color")
2115
2195
  ]),
2196
+ template_types: import_zod.default.array(import_zod.default.string()).optional().nullable(),
2116
2197
  name: import_zod.default.string(),
2117
2198
  label: import_zod.default.string(),
2118
2199
  default: import_zod.default.any().optional(),
2119
2200
  config: import_zod.default.object({
2120
- required: import_zod.default.boolean().optional(),
2121
- use_select: import_zod.default.boolean().optional(),
2122
- date_format: import_zod.default.string().optional(),
2123
- time_format: import_zod.default.string().optional(),
2124
- options: import_zod.default.array(import_zod.default.string()).optional(),
2201
+ min: import_zod.default.number().optional().nullable(),
2202
+ max: import_zod.default.number().optional().nullable(),
2203
+ required: import_zod.default.boolean().optional().nullable(),
2204
+ use_select: import_zod.default.boolean().optional().nullable(),
2205
+ date_format: import_zod.default.string().optional().nullable(),
2206
+ time_format: import_zod.default.string().optional().nullable(),
2207
+ options: import_zod.default.array(import_zod.default.string()).optional().nullable(),
2125
2208
  source: import_zod.default.object({
2126
2209
  type: import_zod.default.union([
2127
2210
  import_zod.default.literal("custom"),
@@ -2129,8 +2212,8 @@ var forestryFieldWithoutField = import_zod.default.object({
2129
2212
  import_zod.default.literal("documents"),
2130
2213
  import_zod.default.literal("simple"),
2131
2214
  import_zod.default.string()
2132
- ]).optional(),
2133
- section: import_zod.default.string().optional()
2215
+ ]).optional().nullable(),
2216
+ section: import_zod.default.string().optional().nullable()
2134
2217
  }).optional()
2135
2218
  }).optional()
2136
2219
  });
@@ -2144,24 +2227,30 @@ var FrontmatterTemplateSchema = import_zod.default.object({
2144
2227
  });
2145
2228
  var transformForestryFieldsToTinaFields = ({
2146
2229
  fields,
2147
- collection
2230
+ rootPath: rootPath2,
2231
+ template,
2232
+ skipBlocks = false
2148
2233
  }) => {
2149
2234
  const tinaFields = [];
2150
2235
  fields == null ? void 0 : fields.forEach((forestryField2) => {
2151
2236
  var _a, _b, _c, _d;
2237
+ if (forestryField2.name === "menu") {
2238
+ logger.info(warnText(`skipping menu field template ${template}.yaml since TinaCMS does not support Hugo or Jekyll menu fields`));
2239
+ return;
2240
+ }
2152
2241
  let field;
2153
2242
  switch (forestryField2.type) {
2154
2243
  case "text":
2155
2244
  field = {
2156
2245
  type: "string",
2157
- name: forestryField2.name,
2246
+ name: stringifyName(forestryField2.name, template),
2158
2247
  label: forestryField2.label
2159
2248
  };
2160
2249
  break;
2161
2250
  case "textarea":
2162
2251
  field = {
2163
2252
  type: "string",
2164
- name: forestryField2.name,
2253
+ name: stringifyName(forestryField2.name, template),
2165
2254
  label: forestryField2.label,
2166
2255
  ui: {
2167
2256
  component: "textarea"
@@ -2171,28 +2260,28 @@ var transformForestryFieldsToTinaFields = ({
2171
2260
  case "datetime":
2172
2261
  field = {
2173
2262
  type: forestryField2.type,
2174
- name: forestryField2.name,
2263
+ name: stringifyName(forestryField2.name, template),
2175
2264
  label: forestryField2.label
2176
2265
  };
2177
2266
  break;
2178
2267
  case "number":
2179
2268
  field = {
2180
2269
  type: "number",
2181
- name: forestryField2.name,
2270
+ name: stringifyName(forestryField2.name, template),
2182
2271
  label: forestryField2.label
2183
2272
  };
2184
2273
  break;
2185
2274
  case "boolean":
2186
2275
  field = {
2187
2276
  type: "boolean",
2188
- name: forestryField2.name,
2277
+ name: stringifyName(forestryField2.name, template),
2189
2278
  label: forestryField2.label
2190
2279
  };
2191
2280
  break;
2192
2281
  case "color":
2193
2282
  field = {
2194
2283
  type: "string",
2195
- name: forestryField2.name,
2284
+ name: stringifyName(forestryField2.name, template),
2196
2285
  label: forestryField2.label,
2197
2286
  ui: {
2198
2287
  component: "color"
@@ -2202,7 +2291,7 @@ var transformForestryFieldsToTinaFields = ({
2202
2291
  case "file":
2203
2292
  field = {
2204
2293
  type: "image",
2205
- name: forestryField2.name || "image",
2294
+ name: stringifyName(forestryField2.name || "image", template),
2206
2295
  label: forestryField2.label
2207
2296
  };
2208
2297
  break;
@@ -2210,18 +2299,18 @@ var transformForestryFieldsToTinaFields = ({
2210
2299
  if ((_a = forestryField2.config) == null ? void 0 : _a.options) {
2211
2300
  field = {
2212
2301
  type: "string",
2213
- name: forestryField2.name,
2302
+ name: stringifyName(forestryField2.name, template),
2214
2303
  label: forestryField2.label,
2215
2304
  options: ((_b = forestryField2.config) == null ? void 0 : _b.options) || []
2216
2305
  };
2217
2306
  } else {
2218
- logger.info(`Warning in collection ${collection}. "select" field migration has only been implemented for simple select. Other versions of select have not been implemented yet. To make your \`${forestryField2.name}\` field work, you will need to manually add it to your schema.`);
2307
+ logger.info(warnText(`Warning in template ${template}.yaml . "select" field migration has only been implemented for simple select. Other versions of select have not been implemented yet. To make your \`${forestryField2.name}\` field work, you will need to manually add it to your schema.`));
2219
2308
  }
2220
2309
  break;
2221
2310
  case "list":
2222
2311
  field = {
2223
2312
  type: "string",
2224
- name: forestryField2.name,
2313
+ name: stringifyName(forestryField2.name, template),
2225
2314
  label: forestryField2.label,
2226
2315
  list: true
2227
2316
  };
@@ -2232,7 +2321,7 @@ var transformForestryFieldsToTinaFields = ({
2232
2321
  case "tag_list":
2233
2322
  field = {
2234
2323
  type: "string",
2235
- name: forestryField2.name,
2324
+ name: stringifyName(forestryField2.name, template),
2236
2325
  label: forestryField2.label,
2237
2326
  list: true,
2238
2327
  ui: {
@@ -2243,32 +2332,61 @@ var transformForestryFieldsToTinaFields = ({
2243
2332
  case "field_group":
2244
2333
  field = {
2245
2334
  type: "object",
2246
- name: forestryField2.name,
2335
+ name: stringifyName(forestryField2.name, template),
2247
2336
  label: forestryField2.label,
2248
2337
  fields: transformForestryFieldsToTinaFields({
2249
2338
  fields: forestryField2.fields,
2250
- collection
2339
+ rootPath: rootPath2,
2340
+ template,
2341
+ skipBlocks
2251
2342
  })
2252
2343
  };
2253
2344
  break;
2254
2345
  case "field_group_list":
2255
2346
  field = {
2256
2347
  type: "object",
2257
- name: forestryField2.name,
2348
+ name: stringifyName(forestryField2.name, template),
2258
2349
  label: forestryField2.label,
2259
2350
  list: true,
2260
2351
  fields: transformForestryFieldsToTinaFields({
2261
2352
  fields: forestryField2.fields,
2262
- collection
2353
+ template,
2354
+ rootPath: rootPath2,
2355
+ skipBlocks
2263
2356
  })
2264
2357
  };
2265
2358
  break;
2359
+ case "blocks":
2360
+ if (skipBlocks)
2361
+ break;
2362
+ const templates = [];
2363
+ forestryField2 == null ? void 0 : forestryField2.template_types.forEach((tem) => {
2364
+ const { fields: fields2, template: template2 } = getFieldsFromTemplates({
2365
+ tem,
2366
+ skipBlocks: true,
2367
+ rootPath: process.cwd()
2368
+ });
2369
+ const t = {
2370
+ fields: fields2,
2371
+ label: template2.label,
2372
+ name: stringifyName(tem, tem)
2373
+ };
2374
+ templates.push(t);
2375
+ });
2376
+ field = {
2377
+ type: "object",
2378
+ list: true,
2379
+ label: forestryField2.label,
2380
+ name: stringifyName(forestryField2.name, template),
2381
+ templates
2382
+ };
2383
+ break;
2266
2384
  case "image_gallery":
2267
2385
  case "include":
2268
- console.log(`Unsupported field type: ${forestryField2.type}, in collection ${collection}. This will not be added to the schema.`);
2386
+ logger.info(warnText(`Unsupported field type: ${forestryField2.type}, in forestry ${template}. This will not be added to the schema.`));
2269
2387
  break;
2270
2388
  default:
2271
- logger.info(`Warning in collection ${collection}. "${forestryField2.type}" migration has not been implemented yet. To make your \`${forestryField2.name}\` field work, you will need to manually add it to your schema.`);
2389
+ logger.info(warnText(`Warning in template ${template}. "${forestryField2.type}" migration has not been implemented yet. To make your \`${forestryField2.name}\` field work, you will need to manually add it to your schema.`));
2272
2390
  }
2273
2391
  if (field) {
2274
2392
  if ((_d = forestryField2.config) == null ? void 0 : _d.required) {
@@ -2279,11 +2397,7 @@ var transformForestryFieldsToTinaFields = ({
2279
2397
  });
2280
2398
  return tinaFields;
2281
2399
  };
2282
- var getFieldsFromTemplates = ({
2283
- tem,
2284
- rootPath: rootPath2,
2285
- collection
2286
- }) => {
2400
+ var getFieldsFromTemplates = ({ tem, rootPath: rootPath2, skipBlocks = false }) => {
2287
2401
  const templatePath = import_path12.default.join(rootPath2, ".forestry", "front_matter", "templates", `${tem}.yml`);
2288
2402
  let templateString = "";
2289
2403
  try {
@@ -2297,9 +2411,11 @@ var getFieldsFromTemplates = ({
2297
2411
  const template = parseTemplates({ val: templateObj });
2298
2412
  const fields = transformForestryFieldsToTinaFields({
2299
2413
  fields: template.fields,
2300
- collection
2414
+ rootPath: rootPath2,
2415
+ template: tem,
2416
+ skipBlocks
2301
2417
  });
2302
- return fields;
2418
+ return { fields, templateObj, template };
2303
2419
  };
2304
2420
  var parseTemplates = ({ val }) => {
2305
2421
  const template = FrontmatterTemplateSchema.parse(val);
@@ -2320,44 +2436,94 @@ var parseSections = ({ val }) => {
2320
2436
 
2321
2437
  // src/cmds/forestry-migrate/index.ts
2322
2438
  var import_fs_extra9 = __toModule(require("fs-extra"));
2439
+ var import_path13 = __toModule(require("path"));
2323
2440
  var import_js_yaml2 = __toModule(require("js-yaml"));
2441
+ var import_minimatch = __toModule(require("minimatch"));
2442
+ var import_graphql10 = __toModule(require("@tinacms/graphql"));
2443
+ var BODY_FIELD = {
2444
+ type: "rich-text",
2445
+ name: "body",
2446
+ label: "Body of Document",
2447
+ description: "This is the markdown body",
2448
+ isBody: true
2449
+ };
2324
2450
  var stringifyLabel = (label) => {
2325
2451
  return label.replace(/[^a-zA-Z0-9]/g, "_").toLowerCase();
2326
2452
  };
2453
+ var generateAllCollections = async ({
2454
+ rootPath: rootPath2
2455
+ }) => {
2456
+ const allTemplates = (await import_fs_extra9.default.readdir(import_path13.default.join(rootPath2, ".forestry", "front_matter", "templates"))).map((tem) => import_path13.default.basename(tem, ".yml"));
2457
+ const templateMap = new Map();
2458
+ const proms = allTemplates.map(async (tem) => {
2459
+ try {
2460
+ const { fields, templateObj } = getFieldsFromTemplates({
2461
+ tem,
2462
+ rootPath: rootPath2
2463
+ });
2464
+ templateMap.set(tem, { fields, templateObj });
2465
+ } catch (e) {
2466
+ logger.log(`Error parsing template frontmatter template', tem + '.yml'`);
2467
+ console.error(e);
2468
+ templateMap.set(tem, { fields: [], templateObj: {} });
2469
+ }
2470
+ });
2471
+ await Promise.all(proms);
2472
+ return templateMap;
2473
+ };
2327
2474
  var generateCollections = async ({
2328
2475
  forestryPath,
2329
2476
  rootPath: rootPath2
2330
2477
  }) => {
2331
- var _a;
2478
+ const templateMap = await generateAllCollections({ rootPath: rootPath2 });
2332
2479
  const forestryConfig = await import_fs_extra9.default.readFile(forestryPath);
2333
2480
  const forestryYaml = import_js_yaml2.default.load(forestryConfig.toString());
2334
2481
  const forestrySchema = parseSections({ val: forestryYaml });
2335
2482
  const collections = [];
2336
- (_a = forestrySchema.sections) == null ? void 0 : _a.forEach((section) => {
2337
- var _a2, _b;
2483
+ const sections = forestrySchema.sections;
2484
+ for (let index = 0; index < sections.length; index++) {
2485
+ const section = sections[index];
2338
2486
  if (section.read_only)
2339
2487
  return;
2340
2488
  switch (section.type) {
2341
2489
  case "directory":
2342
- const fields = [
2343
- {
2344
- type: "rich-text",
2345
- name: "body",
2346
- label: "Body of Document",
2347
- description: "This is the markdown body",
2348
- isBody: true
2490
+ const forestryTemplates = (section == null ? void 0 : section.templates) || [];
2491
+ if (forestryTemplates.length === 0 && section.create === "all") {
2492
+ for (let templateKey of templateMap.keys()) {
2493
+ const { templateObj } = templateMap.get(templateKey);
2494
+ const pages = templateObj == null ? void 0 : templateObj.pages;
2495
+ if (pages) {
2496
+ if (pages.some((page) => (0, import_minimatch.default)(page, section.path + "/" + section.match))) {
2497
+ forestryTemplates.push(templateKey);
2498
+ }
2499
+ }
2349
2500
  }
2350
- ];
2351
- if ((((_a2 = section.templates) == null ? void 0 : _a2.length) || 0) > 1) {
2501
+ }
2502
+ if (((forestryTemplates == null ? void 0 : forestryTemplates.length) || 0) > 1) {
2352
2503
  const templates = [];
2353
- section.templates.forEach((tem) => {
2504
+ forestryTemplates.forEach((tem) => {
2505
+ var _a;
2354
2506
  try {
2355
- const fields2 = getFieldsFromTemplates({
2356
- tem,
2357
- collection: stringifyLabel(section.label),
2358
- rootPath: rootPath2
2507
+ const { fields, templateObj } = templateMap.get(tem);
2508
+ templates.push({
2509
+ fields: [BODY_FIELD, ...fields],
2510
+ label: tem,
2511
+ name: stringifyLabel(tem)
2512
+ });
2513
+ (_a = templateObj == null ? void 0 : templateObj.pages) == null ? void 0 : _a.forEach((page) => {
2514
+ try {
2515
+ const filePath = import_path13.default.join(rootPath2, page);
2516
+ const extname2 = import_path13.default.extname(filePath);
2517
+ const fileContent = import_fs_extra9.default.readFileSync(filePath).toString();
2518
+ const content2 = (0, import_graphql10.parseFile)(fileContent, extname2, (yup) => yup.object({}));
2519
+ const newContent = __spreadValues({
2520
+ _template: stringifyLabel(tem)
2521
+ }, content2);
2522
+ import_fs_extra9.default.writeFileSync(filePath, (0, import_graphql10.stringifyFile)(newContent, extname2, true));
2523
+ } catch (error) {
2524
+ console.log("Error updating file", page);
2525
+ }
2359
2526
  });
2360
- templates.push({ fields: fields2, label: tem, name: stringifyLabel(tem) });
2361
2527
  } catch (e) {
2362
2528
  console.log("Error parsing template ", tem);
2363
2529
  console.error(e);
@@ -2378,16 +2544,28 @@ var generateCollections = async ({
2378
2544
  }
2379
2545
  collections.push(c);
2380
2546
  } else {
2381
- (_b = section.templates) == null ? void 0 : _b.forEach((tem) => {
2547
+ const fields = [BODY_FIELD];
2548
+ forestryTemplates == null ? void 0 : forestryTemplates.forEach((tem) => {
2549
+ var _a;
2382
2550
  try {
2383
- const additionalFields = getFieldsFromTemplates({
2384
- tem,
2385
- rootPath: rootPath2,
2386
- collection: stringifyLabel(section.label)
2387
- });
2551
+ const { fields: additionalFields, templateObj } = templateMap.get(tem);
2388
2552
  fields.push(...additionalFields);
2553
+ (_a = templateObj == null ? void 0 : templateObj.pages) == null ? void 0 : _a.forEach((page) => {
2554
+ try {
2555
+ const filePath = import_path13.default.join(rootPath2, page);
2556
+ const extname2 = import_path13.default.extname(filePath);
2557
+ const fileContent = import_fs_extra9.default.readFileSync(filePath).toString();
2558
+ const content2 = (0, import_graphql10.parseFile)(fileContent, extname2, (yup) => yup.object({}));
2559
+ const newContent = __spreadValues({
2560
+ _template: stringifyLabel(tem)
2561
+ }, content2);
2562
+ import_fs_extra9.default.writeFileSync(filePath, (0, import_graphql10.stringifyFile)(newContent, extname2, true));
2563
+ } catch (error) {
2564
+ logger.log("Error updating file", page);
2565
+ }
2566
+ });
2389
2567
  } catch (e) {
2390
- console.log("Error parsing template ", tem);
2568
+ logger.log("Error parsing template ", tem);
2391
2569
  console.error(e);
2392
2570
  }
2393
2571
  });
@@ -2407,8 +2585,11 @@ var generateCollections = async ({
2407
2585
  collections.push(c);
2408
2586
  }
2409
2587
  break;
2588
+ case "document":
2589
+ console.log(warnText(`Single Document are not supported in TinaCMS yet. Skipping section ${section.label} (${section.path})`));
2590
+ break;
2410
2591
  }
2411
- });
2592
+ }
2412
2593
  return collections;
2413
2594
  };
2414
2595
 
@@ -2556,6 +2737,7 @@ var forestryMigrate = async ({
2556
2737
  rootPath: rootPath2
2557
2738
  }) => {
2558
2739
  logger.info(`It looks like you have a ${focusText(".forestry/settings.yml")} file in your project.`);
2740
+ logger.info(`This migration will update some of your content to match tina. Please ${focusText("save a backup of your content")} before doing this migration. (This can be done with git)`);
2559
2741
  const option = await (0, import_prompts2.default)({
2560
2742
  name: "selection",
2561
2743
  type: "confirm",
@@ -2567,10 +2749,18 @@ ${logText("Note: This migration will not be perfect, but it will get you started
2567
2749
  if (!option["selection"]) {
2568
2750
  return null;
2569
2751
  }
2752
+ const delay = (ms) => new Promise((resolve2) => setTimeout(resolve2, ms));
2753
+ await spin({
2754
+ waitFor: async () => {
2755
+ await delay(2e3);
2756
+ },
2757
+ text: ""
2758
+ });
2570
2759
  const collections = await generateCollections({
2571
2760
  forestryPath,
2572
2761
  rootPath: rootPath2
2573
2762
  });
2763
+ ErrorSingleton.getInstance().printNameErrors();
2574
2764
  return JSON.stringify(collections, null, 2);
2575
2765
  };
2576
2766
  var reportTelemetry = async ({
@@ -2597,22 +2787,22 @@ var createPackageJSON = async () => {
2597
2787
  };
2598
2788
  var createGitignore = async ({ baseDir }) => {
2599
2789
  logger.info(logText("No .gitignore found, creating one"));
2600
- await import_fs_extra10.default.outputFileSync(import_path13.default.join(baseDir, ".gitignore"), "node_modules");
2790
+ await import_fs_extra10.default.outputFileSync(import_path14.default.join(baseDir, ".gitignore"), "node_modules");
2601
2791
  };
2602
2792
  var checkGitignoreForNodeModules = async ({
2603
2793
  baseDir
2604
2794
  }) => {
2605
- const gitignoreContent = await import_fs_extra10.default.readFileSync(import_path13.default.join(baseDir, ".gitignore")).toString();
2795
+ const gitignoreContent = await import_fs_extra10.default.readFileSync(import_path14.default.join(baseDir, ".gitignore")).toString();
2606
2796
  return gitignoreContent.split("\n").some((item) => item === "node_modules");
2607
2797
  };
2608
2798
  var addNodeModulesToGitignore = async ({ baseDir }) => {
2609
2799
  logger.info(logText("Adding node_modules to .gitignore"));
2610
- const gitignoreContent = await import_fs_extra10.default.readFileSync(import_path13.default.join(baseDir, ".gitignore")).toString();
2800
+ const gitignoreContent = await import_fs_extra10.default.readFileSync(import_path14.default.join(baseDir, ".gitignore")).toString();
2611
2801
  const newGitignoreContent = [
2612
2802
  ...gitignoreContent.split("\n"),
2613
2803
  "node_modules"
2614
2804
  ].join("\n");
2615
- await import_fs_extra10.default.writeFileSync(import_path13.default.join(baseDir, ".gitignore"), newGitignoreContent);
2805
+ await import_fs_extra10.default.writeFileSync(import_path14.default.join(baseDir, ".gitignore"), newGitignoreContent);
2616
2806
  };
2617
2807
  var addDependencies = async (packageManager) => {
2618
2808
  logger.info(logText("Adding dependencies, this might take a moment..."));
@@ -2627,8 +2817,8 @@ var addDependencies = async (packageManager) => {
2627
2817
  };
2628
2818
  var addConfigFile = async (args) => {
2629
2819
  const { baseDir, usingTypescript } = args;
2630
- const configPath = import_path13.default.join(".tina", `config.${usingTypescript ? "ts" : "js"}`);
2631
- const fullConfigPath = import_path13.default.join(baseDir, configPath);
2820
+ const configPath = import_path14.default.join(".tina", `config.${usingTypescript ? "ts" : "js"}`);
2821
+ const fullConfigPath = import_path14.default.join(baseDir, configPath);
2632
2822
  if (import_fs_extra10.default.pathExistsSync(fullConfigPath)) {
2633
2823
  const override = await (0, import_prompts2.default)({
2634
2824
  name: "selection",
@@ -2647,8 +2837,8 @@ var addConfigFile = async (args) => {
2647
2837
  }
2648
2838
  };
2649
2839
  var addContentFile = async ({ baseDir }) => {
2650
- const contentPath = import_path13.default.join("content", "posts", "hello-world.md");
2651
- const fullContentPath = import_path13.default.join(baseDir, contentPath);
2840
+ const contentPath = import_path14.default.join("content", "posts", "hello-world.md");
2841
+ const fullContentPath = import_path14.default.join(baseDir, contentPath);
2652
2842
  if (import_fs_extra10.default.pathExistsSync(fullContentPath)) {
2653
2843
  const override = await (0, import_prompts2.default)({
2654
2844
  name: "selection",
@@ -2717,11 +2907,11 @@ var addReactiveFile = {
2717
2907
  baseDir,
2718
2908
  usingTypescript
2719
2909
  }) => {
2720
- const usingSrc = !import_fs_extra10.default.pathExistsSync(import_path13.default.join(baseDir, "pages"));
2721
- const pagesPath = import_path13.default.join(baseDir, usingSrc ? "src" : "", "pages");
2722
- const packageJSONPath = import_path13.default.join(baseDir, "package.json");
2723
- const tinaBlogPagePath = import_path13.default.join(pagesPath, "demo", "blog");
2724
- const tinaBlogPagePathFile = import_path13.default.join(tinaBlogPagePath, `[filename].${usingTypescript ? "tsx" : "js"}`);
2910
+ const usingSrc = !import_fs_extra10.default.pathExistsSync(import_path14.default.join(baseDir, "pages"));
2911
+ const pagesPath = import_path14.default.join(baseDir, usingSrc ? "src" : "", "pages");
2912
+ const packageJSONPath = import_path14.default.join(baseDir, "package.json");
2913
+ const tinaBlogPagePath = import_path14.default.join(pagesPath, "demo", "blog");
2914
+ const tinaBlogPagePathFile = import_path14.default.join(tinaBlogPagePath, `[filename].${usingTypescript ? "tsx" : "js"}`);
2725
2915
  if (!import_fs_extra10.default.pathExistsSync(tinaBlogPagePathFile)) {
2726
2916
  import_fs_extra10.default.mkdirpSync(tinaBlogPagePath);
2727
2917
  import_fs_extra10.default.writeFileSync(tinaBlogPagePathFile, nextPostPage({ usingSrc }));
@@ -2750,27 +2940,21 @@ function execShellCommand(cmd) {
2750
2940
  // src/cmds/statusChecks/checkClientInformation.ts
2751
2941
  var import_progress2 = __toModule(require("progress"));
2752
2942
  async function request(args) {
2753
- let data = {};
2754
2943
  const headers = new Headers();
2755
2944
  if (args.token) {
2756
2945
  headers.append("X-API-KEY", args.token);
2757
2946
  }
2758
2947
  headers.append("Content-Type", "application/json");
2759
- const bodyString = JSON.stringify({
2760
- query: args.query,
2761
- variables: (args == null ? void 0 : args.variables) || {}
2762
- });
2763
2948
  const url = args == null ? void 0 : args.url;
2764
2949
  const res = await fetch(url, {
2765
- method: "POST",
2950
+ method: "GET",
2766
2951
  headers,
2767
- body: bodyString,
2768
2952
  redirect: "follow"
2769
2953
  });
2770
2954
  const json = await res.json();
2771
2955
  if (!res.ok) {
2772
2956
  let additionalInfo = "";
2773
- if (res.status === 401) {
2957
+ if (res.status === 401 || res.status === 403) {
2774
2958
  additionalInfo = "Please check that your client ID, URL and read only token are configured properly.";
2775
2959
  }
2776
2960
  if (json) {
@@ -2787,25 +2971,21 @@ Message from server: ${json.message}`;
2787
2971
  ${json.errors.map((error) => error.message).join("\n")}`);
2788
2972
  }
2789
2973
  return {
2790
- data: json == null ? void 0 : json.data,
2791
- query: args.query
2974
+ status: json == null ? void 0 : json.status,
2975
+ timestamp: json == null ? void 0 : json.timestamp
2792
2976
  };
2793
2977
  }
2794
2978
  var checkClientInfo = async (ctx, next, _options) => {
2795
2979
  var _a;
2796
2980
  const config2 = (_a = ctx.schema) == null ? void 0 : _a.config;
2797
2981
  const token = config2.token;
2798
- const url = ctx.apiUrl;
2982
+ const { clientId, branch, host } = parseURL(ctx.apiUrl);
2983
+ const url = `https://${host}/db/${clientId}/status/${branch}`;
2799
2984
  const bar = new import_progress2.default("Checking clientId, token and branch. :prog", 1);
2800
2985
  try {
2801
2986
  await request({
2802
2987
  token,
2803
- url,
2804
- query: `query {
2805
- collections {
2806
- name
2807
- }
2808
- }`
2988
+ url
2809
2989
  });
2810
2990
  bar.tick({
2811
2991
  prog: "\u2705"
@@ -2838,6 +3018,10 @@ var startServerPortOption = {
2838
3018
  name: "--port <port>",
2839
3019
  description: "Specify a port to run the server on. (default 4001)"
2840
3020
  };
3021
+ var rootPathOption = {
3022
+ name: "--rootPath <rootPath>",
3023
+ description: "Specify the root directory to run the CLI from (defaults to current working directory)"
3024
+ };
2841
3025
  var experimentalDatalayer = {
2842
3026
  name: "--experimentalData",
2843
3027
  description: "Build the server with additional data querying capabilities"
@@ -2938,7 +3122,8 @@ var baseCmds = [
2938
3122
  noSDKCodegenOption,
2939
3123
  noTelemetryOption,
2940
3124
  watchFileOption,
2941
- verboseOption
3125
+ verboseOption,
3126
+ rootPathOption
2942
3127
  ],
2943
3128
  action: (options) => chain([
2944
3129
  attachPath,
@@ -2958,7 +3143,8 @@ var baseCmds = [
2958
3143
  noTelemetryOption,
2959
3144
  verboseOption,
2960
3145
  developmentOption,
2961
- localOption
3146
+ localOption,
3147
+ rootPathOption
2962
3148
  ],
2963
3149
  action: (options) => chain([
2964
3150
  attachPath,
@@ -2972,6 +3158,7 @@ var baseCmds = [
2972
3158
  {
2973
3159
  command: INIT,
2974
3160
  options: [
3161
+ rootPathOption,
2975
3162
  experimentalDatalayer,
2976
3163
  isomorphicGitBridge,
2977
3164
  noTelemetryOption,
@@ -2984,6 +3171,7 @@ var baseCmds = [
2984
3171
  },
2985
3172
  {
2986
3173
  options: [
3174
+ rootPathOption,
2987
3175
  cleanOption,
2988
3176
  useDefaultValuesOption,
2989
3177
  noTelemetryOption,
@@ -27,6 +27,7 @@ interface ListMediaRes {
27
27
  error?: string;
28
28
  }
29
29
  export interface PathConfig {
30
+ rootPath: string;
30
31
  publicFolder: string;
31
32
  mediaRoot: string;
32
33
  }
@@ -37,9 +38,10 @@ declare type SuccessRecord = {
37
38
  message: string;
38
39
  };
39
40
  export declare class MediaModel {
41
+ readonly rootPath: string;
40
42
  readonly publicFolder: string;
41
43
  readonly mediaRoot: string;
42
- constructor({ publicFolder, mediaRoot }: PathConfig);
44
+ constructor({ rootPath, publicFolder, mediaRoot }: PathConfig);
43
45
  listMedia(args: MediaArgs): Promise<ListMediaRes>;
44
46
  deleteMedia(args: MediaArgs): Promise<SuccessRecord>;
45
47
  }
@@ -13,4 +13,4 @@ limitations under the License.
13
13
  export declare function spin<T>({ waitFor, text, }: {
14
14
  waitFor: () => Promise<T>;
15
15
  text: string;
16
- }): Promise<T>;
16
+ }): Promise<any>;
@@ -32,6 +32,7 @@ export declare const cmdText: import("chalk").Chalk & {
32
32
  supportsColor: import("chalk").ColorSupport;
33
33
  };
34
34
  export declare const indentedCmd: (str: any) => string;
35
+ export declare const indentText: (str: any) => string;
35
36
  export declare const logText: import("chalk").Chalk & {
36
37
  supportsColor: import("chalk").ColorSupport;
37
38
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tinacms/cli",
3
- "version": "1.0.5",
3
+ "version": "1.0.7",
4
4
  "main": "dist/index.js",
5
5
  "typings": "dist/index.d.ts",
6
6
  "files": [
@@ -21,7 +21,7 @@
21
21
  ]
22
22
  },
23
23
  "devDependencies": {
24
- "@tinacms/scripts": "1.0.0",
24
+ "@tinacms/scripts": "1.0.1",
25
25
  "@types/clear": "0.1.0",
26
26
  "@types/cli-spinner": "^0.2.1",
27
27
  "@types/cors": "2.8.5",
@@ -52,12 +52,11 @@
52
52
  "@graphql-codegen/visitor-plugin-common": "^2.4.0",
53
53
  "@graphql-tools/graphql-file-loader": "^7.2.0",
54
54
  "@graphql-tools/load": "^7.3.2",
55
- "@tinacms/app": "1.0.4",
56
- "@tinacms/datalayer": "1.0.0",
57
- "@tinacms/graphql": "1.0.4",
55
+ "@tinacms/app": "1.0.5",
56
+ "@tinacms/datalayer": "1.0.1",
57
+ "@tinacms/graphql": "1.1.0",
58
58
  "@tinacms/metrics": "1.0.1",
59
- "@tinacms/schema-tools": "1.1.0",
60
- "add": "^2.0.6",
59
+ "@tinacms/schema-tools": "1.2.1",
61
60
  "ajv": "^6.12.3",
62
61
  "altair-express-middleware": "4.0.6",
63
62
  "auto-bind": "^4.0.0",
@@ -79,12 +78,13 @@
79
78
  "lodash": "^4.17.19",
80
79
  "lodash.get": "^4.4.2",
81
80
  "log4js": "^6.4.0",
81
+ "minimatch": "^5.1.2",
82
82
  "multer": "1.4.5-lts.1",
83
83
  "normalize-path": "^3.0.0",
84
- "url-pattern": "^1.0.3",
85
84
  "prettier": "^2.2.1",
86
85
  "progress": "^2.0.3",
87
86
  "prompts": "^2.4.1",
87
+ "url-pattern": "^1.0.3",
88
88
  "yarn": "^1.22.17",
89
89
  "yup": "^0.32.9",
90
90
  "zod": "^3.14.3"
@@ -101,6 +101,7 @@
101
101
  "test": "jest --passWithNoTests",
102
102
  "types": "pnpm tsc",
103
103
  "test-watch": "jest --passWithNoTests --watch",
104
+ "tinacms": "MONOREPO_DEV=true node ./bin/tinacms",
104
105
  "generate:schema": "yarn node scripts/generateSchema.js"
105
106
  }
106
107
  }