@tinacms/schema-tools 0.0.0-b4c6a60-20241010070518 → 0.0.0-bdc07c1-20250506013835

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.d.ts CHANGED
@@ -1,6 +1 @@
1
- export * from './schema';
2
- export * from './types/index';
3
- export * from './validate';
4
- export * from './util/namer';
5
- export * from './util/parseURL';
6
- export * from './util/normalizePath';
1
+ export * from "../src/index"
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  (function(global, factory) {
2
- typeof exports === "object" && typeof module !== "undefined" ? factory(exports, require("yup"), require("url-pattern"), require("zod")) : typeof define === "function" && define.amd ? define(["exports", "yup", "url-pattern", "zod"], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, factory(global["@tinacms/schema-tools"] = {}, global.NOOP, global.NOOP, global.NOOP));
3
- })(this, function(exports2, yup, UrlPattern, z) {
2
+ typeof exports === "object" && typeof module !== "undefined" ? factory(exports, require("yup"), require("url-pattern"), require("zod"), require("@tinacms/common")) : typeof define === "function" && define.amd ? define(["exports", "yup", "url-pattern", "zod", "@tinacms/common"], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, factory(global["@tinacms/schema-tools"] = {}, global.NOOP, global.NOOP, global.NOOP, global.NOOP));
3
+ })(this, function(exports2, yup, UrlPattern, z, common) {
4
4
  "use strict";
5
5
  function _interopNamespaceDefault(e) {
6
6
  const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
@@ -20,42 +20,26 @@
20
20
  }
21
21
  const yup__namespace = /* @__PURE__ */ _interopNamespaceDefault(yup);
22
22
  function addNamespaceToSchema(maybeNode, namespace = []) {
23
- if (typeof maybeNode === "string") {
23
+ if (typeof maybeNode !== "object" || maybeNode === null) {
24
24
  return maybeNode;
25
25
  }
26
- if (typeof maybeNode === "boolean") {
27
- return maybeNode;
28
- }
29
- if (typeof maybeNode === "function") {
30
- return maybeNode;
31
- }
32
- const newNode = { ...maybeNode };
33
- const keys = Object.keys(maybeNode);
34
- Object.values(maybeNode).map((m, index) => {
35
- const key = keys[index];
36
- if (Array.isArray(m)) {
37
- newNode[key] = m.map((element) => {
38
- if (!element) {
39
- return;
40
- }
41
- if (!element.hasOwnProperty("name")) {
42
- return element;
26
+ const newNode = { ...maybeNode, namespace: [...namespace] };
27
+ Object.entries(maybeNode).forEach(([key, value]) => {
28
+ if (Array.isArray(value)) {
29
+ newNode[key] = value.map((element) => {
30
+ if (element && typeof element === "object" && "name" in element) {
31
+ const valueName = element.name || element.value;
32
+ return addNamespaceToSchema(element, [...namespace, valueName]);
43
33
  }
44
- const value = element.name || element.value;
45
- return addNamespaceToSchema(element, [...namespace, value]);
34
+ return element;
46
35
  });
36
+ } else if (value && typeof value === "object" && "name" in value) {
37
+ newNode[key] = addNamespaceToSchema(value, [...namespace, value.name]);
47
38
  } else {
48
- if (!m) {
49
- return;
50
- }
51
- if (!m.hasOwnProperty("name")) {
52
- newNode[key] = m;
53
- } else {
54
- newNode[key] = addNamespaceToSchema(m, [...namespace, m.name]);
55
- }
39
+ newNode[key] = value;
56
40
  }
57
41
  });
58
- return { ...newNode, namespace };
42
+ return newNode;
59
43
  }
60
44
  function getDefaultExportFromCjs(x) {
61
45
  return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x["default"] : x;
@@ -1961,7 +1945,7 @@
1961
1945
  }
1962
1946
  }
1963
1947
  };
1964
- this.walkFields = (cb) => {
1948
+ this.legacyWalkFields = (cb) => {
1965
1949
  const walk = (collectionOrObject, collection, path) => {
1966
1950
  if (collectionOrObject.templates) {
1967
1951
  collectionOrObject.templates.forEach((template) => {
@@ -1983,7 +1967,7 @@
1983
1967
  collections.forEach((collection) => walk(collection, collection, []));
1984
1968
  };
1985
1969
  this.schema = config;
1986
- this.walkFields(({ field, collection, path }) => {
1970
+ this.legacyWalkFields(({ field, collection }) => {
1987
1971
  if (!("searchable" in field)) {
1988
1972
  if (field.type === "image") {
1989
1973
  field.searchable = false;
@@ -2004,6 +1988,67 @@
2004
1988
  field.uid = field.uid || false;
2005
1989
  });
2006
1990
  }
1991
+ findReferencesFromCollection(name2) {
1992
+ const result = {};
1993
+ this.walkFields(({ field, collection: c, path }) => {
1994
+ if (c.name !== name2) {
1995
+ return;
1996
+ }
1997
+ if (field.type === "reference") {
1998
+ field.collections.forEach((name22) => {
1999
+ if (result[name22] === void 0) {
2000
+ result[name22] = [];
2001
+ }
2002
+ result[name22].push(path);
2003
+ });
2004
+ }
2005
+ });
2006
+ return result;
2007
+ }
2008
+ /**
2009
+ * Walk all fields in tina schema
2010
+ *
2011
+ * @param cb callback function invoked for each field
2012
+ */
2013
+ walkFields(cb) {
2014
+ const walk = (collectionOrObject, collection, path = "$") => {
2015
+ if (collectionOrObject.templates) {
2016
+ collectionOrObject.templates.forEach((template) => {
2017
+ const templatePath = `${path}.${template.name}`;
2018
+ template.fields.forEach((field) => {
2019
+ const fieldPath = field.list ? `${templatePath}[*].${field.name}` : `${templatePath}.${field.name}`;
2020
+ cb({ field, collection, path: fieldPath });
2021
+ if (field.type === "object") {
2022
+ walk(field, collection, fieldPath);
2023
+ }
2024
+ });
2025
+ });
2026
+ }
2027
+ if (collectionOrObject.fields) {
2028
+ collectionOrObject.fields.forEach((field) => {
2029
+ const fieldPath = field.list ? `${path}.${field.name}[*]` : `${path}.${field.name}`;
2030
+ cb({ field, collection, path: fieldPath });
2031
+ if (field.type === "object" && field.fields) {
2032
+ walk(field, collection, fieldPath);
2033
+ } else if (field.templates) {
2034
+ field.templates.forEach((template) => {
2035
+ const templatePath = `${fieldPath}.${template.name}`;
2036
+ template.fields.forEach((field2) => {
2037
+ const fieldPath2 = field2.list ? `${templatePath}[*].${field2.name}` : `${templatePath}.${field2.name}`;
2038
+ cb({ field: field2, collection, path: fieldPath2 });
2039
+ if (field2.type === "object") {
2040
+ walk(field2, collection, fieldPath2);
2041
+ }
2042
+ });
2043
+ });
2044
+ }
2045
+ });
2046
+ }
2047
+ };
2048
+ this.getCollections().forEach((collection) => {
2049
+ walk(collection, collection);
2050
+ });
2051
+ }
2007
2052
  /**
2008
2053
  * This function returns an array of glob matches for a given collection.
2009
2054
  *
@@ -2226,9 +2271,12 @@
2226
2271
  moreInfo.push(parseZodError({ zodError: unionError }));
2227
2272
  });
2228
2273
  }
2229
- const errorMessage = `Error ${issue == null ? void 0 : issue.message} at path ${issue.path.join(
2274
+ const errorMessage = `${issue == null ? void 0 : issue.message}
2275
+ Additional information:
2276
+ - Error found at path ${issue.path.join(
2230
2277
  "."
2231
- )}`;
2278
+ )}
2279
+ `;
2232
2280
  const errorMessages = [errorMessage, ...moreInfo];
2233
2281
  return {
2234
2282
  errors: errorMessages
@@ -2263,6 +2311,9 @@ If you need to use this value in your content you can use the \`nameOverride\` p
2263
2311
  });
2264
2312
  }
2265
2313
  });
2314
+ const duplicateFieldErrorMessage = (fields) => `Fields must have unique names. Found duplicate field names: [${fields}]`;
2315
+ const duplicateTemplateErrorMessage = (templates) => `Templates must have unique names. Found duplicate template names: [${templates}]`;
2316
+ const duplicateCollectionErrorMessage = (collection) => `Collections must have unique names. Found duplicate collection names: [${collection}]`;
2266
2317
  const TypeName = [
2267
2318
  "string",
2268
2319
  "boolean",
@@ -2273,10 +2324,11 @@ If you need to use this value in your content you can use the \`nameOverride\` p
2273
2324
  "reference",
2274
2325
  "rich-text"
2275
2326
  ];
2276
- const typeTypeError = `type must be one of ${TypeName.join(", ")}`;
2277
- const typeRequiredError = `type is required and must be one of ${TypeName.join(
2278
- ", "
2279
- )}`;
2327
+ const formattedTypes = ` - ${TypeName.join("\n - ")}`;
2328
+ const typeTypeError = `Invalid \`type\` property. \`type\` expected to be one of the following values:
2329
+ ${formattedTypes}`;
2330
+ const typeRequiredError = `Missing \`type\` property. Please add a \`type\` property with one of the following:
2331
+ ${formattedTypes}`;
2280
2332
  const Option = z.z.union(
2281
2333
  [
2282
2334
  z.z.string(),
@@ -2362,7 +2414,7 @@ If you need to use this value in your content you can use the \`nameOverride\` p
2362
2414
  if (dups) {
2363
2415
  ctx.addIssue({
2364
2416
  code: z.z.ZodIssueCode.custom,
2365
- message: `Fields must have a unique name, duplicate field names: ${dups}`
2417
+ message: duplicateFieldErrorMessage(dups)
2366
2418
  });
2367
2419
  }
2368
2420
  });
@@ -2372,21 +2424,21 @@ If you need to use this value in your content you can use the \`nameOverride\` p
2372
2424
  invalid_type_error: typeTypeError,
2373
2425
  required_error: typeRequiredError
2374
2426
  }),
2375
- fields: z.z.array(TinaFieldZod).min(1).optional().superRefine((val, ctx) => {
2427
+ fields: z.z.array(TinaFieldZod).min(1, "Property `fields` cannot be empty.").optional().superRefine((val, ctx) => {
2376
2428
  const dups = findDuplicates(val == null ? void 0 : val.map((x) => x.name));
2377
2429
  if (dups) {
2378
2430
  ctx.addIssue({
2379
2431
  code: z.z.ZodIssueCode.custom,
2380
- message: `Fields must have a unique name, duplicate field names: ${dups}`
2432
+ message: duplicateFieldErrorMessage(dups)
2381
2433
  });
2382
2434
  }
2383
2435
  }),
2384
- templates: z.z.array(TemplateTemp).min(1).optional().superRefine((val, ctx) => {
2436
+ templates: z.z.array(TemplateTemp).min(1, "Property `templates` cannot be empty.").optional().superRefine((val, ctx) => {
2385
2437
  const dups = findDuplicates(val == null ? void 0 : val.map((x) => x.name));
2386
2438
  if (dups) {
2387
2439
  ctx.addIssue({
2388
2440
  code: z.z.ZodIssueCode.custom,
2389
- message: `Templates must have a unique name, duplicate template names: ${dups}`
2441
+ message: duplicateTemplateErrorMessage(dups)
2390
2442
  });
2391
2443
  }
2392
2444
  })
@@ -2401,7 +2453,7 @@ If you need to use this value in your content you can use the \`nameOverride\` p
2401
2453
  if (dups) {
2402
2454
  ctx.addIssue({
2403
2455
  code: z.z.ZodIssueCode.custom,
2404
- message: `Templates must have a unique name, duplicate template names: ${dups}`
2456
+ message: duplicateTemplateErrorMessage(dups)
2405
2457
  });
2406
2458
  }
2407
2459
  })
@@ -2421,10 +2473,17 @@ If you need to use this value in your content you can use the \`nameOverride\` p
2421
2473
  ],
2422
2474
  {
2423
2475
  errorMap: (issue, ctx) => {
2424
- var _a;
2476
+ var _a, _b;
2425
2477
  if (issue.code === "invalid_union_discriminator") {
2478
+ if (!((_a = ctx.data) == null ? void 0 : _a.type)) {
2479
+ return {
2480
+ message: `Missing \`type\` property in field \`${ctx.data.name}\`. Please add a \`type\` property with one of the following:
2481
+ ${formattedTypes}`
2482
+ };
2483
+ }
2426
2484
  return {
2427
- message: `Invalid \`type\` property. In the schema is 'type: ${(_a = ctx.data) == null ? void 0 : _a.type}' and expected one of ${TypeName.join(", ")}`
2485
+ message: `Invalid \`type\` property in field \`${ctx.data.name}\`. In the schema is 'type: ${(_b = ctx.data) == null ? void 0 : _b.type}' but expected one of the following:
2486
+ ${formattedTypes}`
2428
2487
  };
2429
2488
  }
2430
2489
  return {
@@ -2434,77 +2493,52 @@ If you need to use this value in your content you can use the \`nameOverride\` p
2434
2493
  }
2435
2494
  ).superRefine((val, ctx) => {
2436
2495
  if (val.type === "string") {
2437
- if (val.isTitle) {
2438
- if (val.list) {
2439
- ctx.addIssue({
2440
- code: z.z.ZodIssueCode.custom,
2441
- message: `Can not have \`list: true\` when using \`isTitle\`. Error in value
2442
- ${JSON.stringify(
2443
- val,
2444
- null,
2445
- 2
2446
- )}
2447
- `
2448
- });
2449
- }
2450
- if (!val.required) {
2451
- ctx.addIssue({
2452
- code: z.z.ZodIssueCode.custom,
2453
- message: `Must have { required: true } when using \`isTitle\` Error in value
2454
- ${JSON.stringify(
2455
- val,
2456
- null,
2457
- 2
2458
- )}
2459
- `
2460
- });
2461
- }
2496
+ const stringifiedField = JSON.stringify(val, null, 2);
2497
+ if (val.isTitle && val.list) {
2498
+ ctx.addIssue({
2499
+ code: z.z.ZodIssueCode.custom,
2500
+ message: `\`list: true\` is not allowed when using \`isTitle\` for fields of \`type: string\`. Error found in field:
2501
+ ${stringifiedField}`
2502
+ });
2503
+ }
2504
+ if (val.isTitle && !val.required) {
2505
+ ctx.addIssue({
2506
+ code: z.z.ZodIssueCode.custom,
2507
+ message: `Property \`required: true\` is required when using \`isTitle\` for fields of \`type: string\`. Error found in field:
2508
+ ${stringifiedField}`
2509
+ });
2462
2510
  }
2463
- if (val.uid) {
2511
+ if (val.uid && val.list) {
2464
2512
  if (val.list) {
2465
2513
  ctx.addIssue({
2466
2514
  code: z.z.ZodIssueCode.custom,
2467
- message: `Can not have \`list: true\` when using \`uid\`. Error in value
2468
- ${JSON.stringify(
2469
- val,
2470
- null,
2471
- 2
2472
- )}
2473
- `
2474
- });
2475
- }
2476
- if (!val.required) {
2477
- ctx.addIssue({
2478
- code: z.z.ZodIssueCode.custom,
2479
- message: `Must have { required: true } when using \`uid\` Error in value
2480
- ${JSON.stringify(
2481
- val,
2482
- null,
2483
- 2
2484
- )}
2485
- `
2515
+ message: `\`list: true\` is not allowed when using \`uid\` for fields of \`type: string\`. Error found in field:
2516
+ ${stringifiedField}`
2486
2517
  });
2487
2518
  }
2488
2519
  }
2520
+ if (val.uid && !val.required) {
2521
+ ctx.addIssue({
2522
+ code: z.z.ZodIssueCode.custom,
2523
+ message: `Property \`required: true\` is required when using \`uid\` for fields of \`type: string\`. Error found in field:
2524
+ ${stringifiedField}`
2525
+ });
2526
+ }
2489
2527
  }
2490
2528
  if (val.type === "object") {
2491
- const message = "Must provide one of templates or fields in your collection";
2492
- let isValid = Boolean(val == null ? void 0 : val.templates) || Boolean(val == null ? void 0 : val.fields);
2493
- if (!isValid) {
2529
+ if (!(val == null ? void 0 : val.templates) && !(val == null ? void 0 : val.fields)) {
2494
2530
  ctx.addIssue({
2495
2531
  code: z.z.ZodIssueCode.custom,
2496
- message
2532
+ message: "Fields of `type: object` must have either `templates` or `fields` property."
2533
+ });
2534
+ return false;
2535
+ }
2536
+ if ((val == null ? void 0 : val.templates) && (val == null ? void 0 : val.fields)) {
2537
+ ctx.addIssue({
2538
+ code: z.z.ZodIssueCode.custom,
2539
+ message: "Fields of `type: object` must have either `templates` or `fields` property, not both."
2497
2540
  });
2498
2541
  return false;
2499
- } else {
2500
- isValid = !((val == null ? void 0 : val.templates) && (val == null ? void 0 : val.fields));
2501
- if (!isValid) {
2502
- ctx.addIssue({
2503
- code: z.z.ZodIssueCode.custom,
2504
- message
2505
- });
2506
- }
2507
- return isValid;
2508
2542
  }
2509
2543
  }
2510
2544
  return true;
@@ -2537,19 +2571,10 @@ ${JSON.stringify(
2537
2571
  const newConfig = tinaConfigZod.parse(config);
2538
2572
  return newConfig;
2539
2573
  };
2540
- const FORMATS = [
2541
- "json",
2542
- "md",
2543
- "markdown",
2544
- "mdx",
2545
- "toml",
2546
- "yaml",
2547
- "yml"
2548
- ];
2549
2574
  const Template = z.z.object({
2550
2575
  label: z.z.string({
2551
- invalid_type_error: "label must be a string",
2552
- required_error: "label was not provided but is required"
2576
+ invalid_type_error: "Invalid data type for property `label`. Must be of type `string`",
2577
+ required_error: "Missing `label` property. Property `label` is required."
2553
2578
  }),
2554
2579
  name,
2555
2580
  fields: z.z.array(TinaFieldZod)
@@ -2559,7 +2584,7 @@ ${JSON.stringify(
2559
2584
  if (dups) {
2560
2585
  ctx.addIssue({
2561
2586
  code: z.z.ZodIssueCode.custom,
2562
- message: `Fields must have a unique name, duplicate field names: ${dups}`
2587
+ message: duplicateFieldErrorMessage(dups)
2563
2588
  });
2564
2589
  }
2565
2590
  });
@@ -2569,7 +2594,7 @@ ${JSON.stringify(
2569
2594
  if (val === "relativePath") {
2570
2595
  ctx.addIssue({
2571
2596
  code: z.z.ZodIssueCode.custom,
2572
- message: `name cannot be 'relativePath'. 'relativePath' is a reserved field name.`
2597
+ message: "Invalid `name` property. `name` cannot be 'relativePath' as it is a reserved field name."
2573
2598
  });
2574
2599
  }
2575
2600
  }),
@@ -2577,72 +2602,73 @@ ${JSON.stringify(
2577
2602
  if (val === ".") {
2578
2603
  ctx.addIssue({
2579
2604
  code: z.z.ZodIssueCode.custom,
2580
- message: `path cannot be '.'. Please use '/' or '' instead. `
2605
+ message: "Invalid `path` property. `path` cannot be '.'. Please use '/' or '' instead."
2581
2606
  });
2582
2607
  }
2583
2608
  }),
2584
- format: z.z.enum(FORMATS).optional(),
2609
+ format: z.z.enum(common.CONTENT_FORMATS).optional(),
2585
2610
  isAuthCollection: z.z.boolean().optional(),
2586
2611
  isDetached: z.z.boolean().optional()
2587
2612
  });
2588
2613
  const TinaCloudCollection = CollectionBaseSchema.extend({
2589
- fields: z.z.array(TinaFieldZod).min(1).optional().superRefine((val, ctx) => {
2614
+ fields: z.z.array(TinaFieldZod).min(1, "Property `fields` cannot be empty.").optional().superRefine((val, ctx) => {
2590
2615
  const dups = findDuplicates(val == null ? void 0 : val.map((x) => x.name));
2591
2616
  if (dups) {
2592
2617
  ctx.addIssue({
2593
2618
  code: z.z.ZodIssueCode.custom,
2594
- message: `Fields must have a unique name, duplicate field names: ${dups}`
2619
+ message: duplicateFieldErrorMessage(dups)
2595
2620
  });
2596
2621
  }
2597
- }).refine(
2598
- // It is valid if it is 0 or 1
2599
- (val) => {
2600
- const arr = (val == null ? void 0 : val.filter((x) => x.type === "string" && x.isTitle)) || [];
2601
- return arr.length < 2;
2602
- },
2603
- {
2604
- message: "Fields can only have one use of `isTitle`"
2605
- }
2606
- ).refine(
2607
- // It is valid if it is 0 or 1
2608
- (val) => {
2609
- const arr = (val == null ? void 0 : val.filter((x) => x.uid)) || [];
2610
- return arr.length < 2;
2611
- },
2612
- {
2613
- message: "Fields can only have one use of `uid`"
2614
- }
2615
- ).refine(
2616
- // It is valid if it is 0 or 1
2617
- (val) => {
2618
- const arr = (val == null ? void 0 : val.filter((x) => x.type === "password")) || [];
2619
- return arr.length < 2;
2620
- },
2621
- {
2622
- message: "Fields can only have one use of `password` type"
2622
+ }).superRefine((val, ctx) => {
2623
+ const arr = (val == null ? void 0 : val.filter((x) => x.type === "string" && x.isTitle)) || [];
2624
+ if (arr.length > 1) {
2625
+ ctx.addIssue({
2626
+ code: z.z.ZodIssueCode.custom,
2627
+ message: `The following fields have the property \`isTitle\`: [${arr.map((field) => field.name).join(", ")}]. Only one can contain the property \`isTitle\`.`
2628
+ });
2623
2629
  }
2624
- ),
2625
- templates: z.z.array(Template).min(1).optional().superRefine((val, ctx) => {
2630
+ }).superRefine((val, ctx) => {
2631
+ const arr = (val == null ? void 0 : val.filter((x) => x.uid)) || [];
2632
+ if (arr.length > 2) {
2633
+ ctx.addIssue({
2634
+ code: z.z.ZodIssueCode.custom,
2635
+ message: `The following fields have the property \`uid\`: [${arr.map((field) => field.name).join(", ")}]. Only one can contain the property \`uid\`.`
2636
+ });
2637
+ }
2638
+ }).superRefine((val, ctx) => {
2639
+ const arr = (val == null ? void 0 : val.filter((x) => x.type === "password")) || [];
2640
+ if (arr.length > 2) {
2641
+ ctx.addIssue({
2642
+ code: z.z.ZodIssueCode.custom,
2643
+ message: `The following fields have \`type: password\`: [${arr.map((field) => field.name).join(", ")}]. Only one can be of \`type: password\`.`
2644
+ });
2645
+ }
2646
+ }),
2647
+ templates: z.z.array(Template).min(1, "Property `templates` cannot be empty.").optional().superRefine((val, ctx) => {
2626
2648
  const dups = findDuplicates(val == null ? void 0 : val.map((x) => x.name));
2627
2649
  if (dups) {
2628
2650
  ctx.addIssue({
2629
2651
  code: z.z.ZodIssueCode.custom,
2630
- message: `Templates must have a unique name, duplicate template names: ${dups}`
2652
+ message: duplicateFieldErrorMessage(dups)
2631
2653
  });
2632
2654
  }
2633
2655
  })
2634
- }).refine(
2635
- (val) => {
2636
- let isValid = Boolean(val == null ? void 0 : val.templates) || Boolean(val == null ? void 0 : val.fields);
2637
- if (!isValid) {
2638
- return false;
2639
- } else {
2640
- isValid = !((val == null ? void 0 : val.templates) && (val == null ? void 0 : val.fields));
2641
- return isValid;
2642
- }
2643
- },
2644
- { message: "Must provide one of templates or fields in your collection" }
2645
- );
2656
+ }).superRefine((val, ctx) => {
2657
+ if (!(val == null ? void 0 : val.templates) && !(val == null ? void 0 : val.fields)) {
2658
+ ctx.addIssue({
2659
+ code: z.z.ZodIssueCode.custom,
2660
+ message: "Fields of `type: object` must have either `templates` or `fields` property."
2661
+ });
2662
+ return false;
2663
+ }
2664
+ if ((val == null ? void 0 : val.templates) && (val == null ? void 0 : val.fields)) {
2665
+ ctx.addIssue({
2666
+ code: z.z.ZodIssueCode.custom,
2667
+ message: "Fields of `type: object` must have either `templates` or `fields` property, not both."
2668
+ });
2669
+ return false;
2670
+ }
2671
+ });
2646
2672
  const TinaCloudSchemaZod = z.z.object({
2647
2673
  collections: z.z.array(TinaCloudCollection),
2648
2674
  config: tinaConfigZod.optional()
@@ -2652,14 +2678,14 @@ ${JSON.stringify(
2652
2678
  if (dups) {
2653
2679
  ctx.addIssue({
2654
2680
  code: z.z.ZodIssueCode.custom,
2655
- message: `${dups} are duplicate names in your collections. Collection names must be unique.`,
2681
+ message: duplicateCollectionErrorMessage(dups),
2656
2682
  fatal: true
2657
2683
  });
2658
2684
  }
2659
2685
  if (((_b = val.collections) == null ? void 0 : _b.filter((x) => x.isAuthCollection).length) > 1) {
2660
2686
  ctx.addIssue({
2661
2687
  code: z.z.ZodIssueCode.custom,
2662
- message: `Only one collection can be marked as isAuthCollection`,
2688
+ message: "Only one collection can be marked as `isAuthCollection`.",
2663
2689
  fatal: true
2664
2690
  });
2665
2691
  }
@@ -2667,7 +2693,7 @@ ${JSON.stringify(
2667
2693
  if (media && media.tina && media.loadCustomStore) {
2668
2694
  ctx.addIssue({
2669
2695
  code: z.z.ZodIssueCode.custom,
2670
- message: "can not have both loadCustomStore and tina. Must use one or the other",
2696
+ message: "Cannot have both `loadCustomStore` and `tina`. Must use one or the other.",
2671
2697
  fatal: true,
2672
2698
  path: ["config", "media"]
2673
2699
  });
@@ -2676,7 +2702,7 @@ ${JSON.stringify(
2676
2702
  if (search && search.tina && search.searchClient) {
2677
2703
  ctx.addIssue({
2678
2704
  code: z.z.ZodIssueCode.custom,
2679
- message: "can not have both searchClient and tina. Must use one or the other",
2705
+ message: "Cannot have both `searchClient` and `tina`. Must use one or the other.",
2680
2706
  fatal: true,
2681
2707
  path: ["config", "search"]
2682
2708
  });
@@ -2694,7 +2720,7 @@ ${JSON.stringify(
2694
2720
  } catch (e) {
2695
2721
  if (e instanceof z.ZodError) {
2696
2722
  const errors = parseZodError({ zodError: e });
2697
- throw new TinaSchemaValidationError(errors.join(", \n"));
2723
+ throw new TinaSchemaValidationError(errors.join("\n"));
2698
2724
  }
2699
2725
  throw new Error(e);
2700
2726
  }