@tinacms/schema-tools 0.0.0-d524599-20241117111320 → 0.0.0-d9672bc-20250218033222

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
@@ -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,29 +1945,8 @@
1961
1945
  }
1962
1946
  }
1963
1947
  };
1964
- this.walkFields = (cb) => {
1965
- const walk = (collectionOrObject, collection, path) => {
1966
- if (collectionOrObject.templates) {
1967
- collectionOrObject.templates.forEach((template) => {
1968
- template.fields.forEach((field) => {
1969
- cb({ field, collection, path: [...path, template.name] });
1970
- });
1971
- });
1972
- }
1973
- if (collectionOrObject.fields) {
1974
- collectionOrObject.fields.forEach((field) => {
1975
- cb({ field, collection, path: [...path, field.name] });
1976
- if (field.type === "rich-text" || field.type === "object") {
1977
- walk(field, collection, [...path, field.name]);
1978
- }
1979
- });
1980
- }
1981
- };
1982
- const collections = this.getCollections();
1983
- collections.forEach((collection) => walk(collection, collection, []));
1984
- };
1985
1948
  this.schema = config;
1986
- this.walkFields(({ field, collection, path }) => {
1949
+ this.walkFields(({ field, collection }) => {
1987
1950
  if (!("searchable" in field)) {
1988
1951
  if (field.type === "image") {
1989
1952
  field.searchable = false;
@@ -2004,20 +1967,51 @@
2004
1967
  field.uid = field.uid || false;
2005
1968
  });
2006
1969
  }
2007
- findReferences(name2) {
1970
+ findReferencesFromCollection(name2) {
2008
1971
  const result = {};
2009
1972
  this.walkFields(({ field, collection: c, path }) => {
1973
+ if (c.name !== name2) {
1974
+ return;
1975
+ }
2010
1976
  if (field.type === "reference") {
2011
- if (field.collections.includes(name2)) {
2012
- if (result[c.name] === void 0) {
2013
- result[c.name] = [];
1977
+ field.collections.forEach((name22) => {
1978
+ if (result[name22] === void 0) {
1979
+ result[name22] = [];
2014
1980
  }
2015
- result[c.name].push({ path, field });
2016
- }
1981
+ result[name22].push(path);
1982
+ });
2017
1983
  }
2018
1984
  });
2019
1985
  return result;
2020
1986
  }
1987
+ walkFields(cb) {
1988
+ const walk = (collectionOrObject, collection, path = "$") => {
1989
+ if (collectionOrObject.templates) {
1990
+ collectionOrObject.templates.forEach((template) => {
1991
+ const templatePath = `${path}.${template.name}`;
1992
+ template.fields.forEach((field) => {
1993
+ const fieldPath = field.list ? `${templatePath}[*].${field.name}` : `${templatePath}.${field.name}`;
1994
+ cb({ field, collection, path: fieldPath });
1995
+ if (field.type === "object") {
1996
+ walk(field, collection, fieldPath);
1997
+ }
1998
+ });
1999
+ });
2000
+ }
2001
+ if (collectionOrObject.fields) {
2002
+ collectionOrObject.fields.forEach((field) => {
2003
+ const fieldPath = field.list ? `${path}.${field.name}[*]` : `${path}.${field.name}`;
2004
+ cb({ field, collection, path: fieldPath });
2005
+ if (field.type === "object" && field.fields) {
2006
+ walk(field, collection, fieldPath);
2007
+ }
2008
+ });
2009
+ }
2010
+ };
2011
+ this.getCollections().forEach((collection) => {
2012
+ walk(collection, collection);
2013
+ });
2014
+ }
2021
2015
  /**
2022
2016
  * This function returns an array of glob matches for a given collection.
2023
2017
  *
@@ -2240,9 +2234,12 @@
2240
2234
  moreInfo.push(parseZodError({ zodError: unionError }));
2241
2235
  });
2242
2236
  }
2243
- const errorMessage = `Error ${issue == null ? void 0 : issue.message} at path ${issue.path.join(
2237
+ const errorMessage = `${issue == null ? void 0 : issue.message}
2238
+ Additional information:
2239
+ - Error found at path ${issue.path.join(
2244
2240
  "."
2245
- )}`;
2241
+ )}
2242
+ `;
2246
2243
  const errorMessages = [errorMessage, ...moreInfo];
2247
2244
  return {
2248
2245
  errors: errorMessages
@@ -2277,6 +2274,9 @@ If you need to use this value in your content you can use the \`nameOverride\` p
2277
2274
  });
2278
2275
  }
2279
2276
  });
2277
+ const duplicateFieldErrorMessage = (fields) => `Fields must have unique names. Found duplicate field names: [${fields}]`;
2278
+ const duplicateTemplateErrorMessage = (templates) => `Templates must have unique names. Found duplicate template names: [${templates}]`;
2279
+ const duplicateCollectionErrorMessage = (collection) => `Collections must have unique names. Found duplicate collection names: [${collection}]`;
2280
2280
  const TypeName = [
2281
2281
  "string",
2282
2282
  "boolean",
@@ -2287,10 +2287,11 @@ If you need to use this value in your content you can use the \`nameOverride\` p
2287
2287
  "reference",
2288
2288
  "rich-text"
2289
2289
  ];
2290
- const typeTypeError = `type must be one of ${TypeName.join(", ")}`;
2291
- const typeRequiredError = `type is required and must be one of ${TypeName.join(
2292
- ", "
2293
- )}`;
2290
+ const formattedTypes = ` - ${TypeName.join("\n - ")}`;
2291
+ const typeTypeError = `Invalid \`type\` property. \`type\` expected to be one of the following values:
2292
+ ${formattedTypes}`;
2293
+ const typeRequiredError = `Missing \`type\` property. Please add a \`type\` property with one of the following:
2294
+ ${formattedTypes}`;
2294
2295
  const Option = z.z.union(
2295
2296
  [
2296
2297
  z.z.string(),
@@ -2376,7 +2377,7 @@ If you need to use this value in your content you can use the \`nameOverride\` p
2376
2377
  if (dups) {
2377
2378
  ctx.addIssue({
2378
2379
  code: z.z.ZodIssueCode.custom,
2379
- message: `Fields must have a unique name, duplicate field names: ${dups}`
2380
+ message: duplicateFieldErrorMessage(dups)
2380
2381
  });
2381
2382
  }
2382
2383
  });
@@ -2386,21 +2387,21 @@ If you need to use this value in your content you can use the \`nameOverride\` p
2386
2387
  invalid_type_error: typeTypeError,
2387
2388
  required_error: typeRequiredError
2388
2389
  }),
2389
- fields: z.z.array(TinaFieldZod).min(1).optional().superRefine((val, ctx) => {
2390
+ fields: z.z.array(TinaFieldZod).min(1, "Property `fields` cannot be empty.").optional().superRefine((val, ctx) => {
2390
2391
  const dups = findDuplicates(val == null ? void 0 : val.map((x) => x.name));
2391
2392
  if (dups) {
2392
2393
  ctx.addIssue({
2393
2394
  code: z.z.ZodIssueCode.custom,
2394
- message: `Fields must have a unique name, duplicate field names: ${dups}`
2395
+ message: duplicateFieldErrorMessage(dups)
2395
2396
  });
2396
2397
  }
2397
2398
  }),
2398
- templates: z.z.array(TemplateTemp).min(1).optional().superRefine((val, ctx) => {
2399
+ templates: z.z.array(TemplateTemp).min(1, "Property `templates` cannot be empty.").optional().superRefine((val, ctx) => {
2399
2400
  const dups = findDuplicates(val == null ? void 0 : val.map((x) => x.name));
2400
2401
  if (dups) {
2401
2402
  ctx.addIssue({
2402
2403
  code: z.z.ZodIssueCode.custom,
2403
- message: `Templates must have a unique name, duplicate template names: ${dups}`
2404
+ message: duplicateTemplateErrorMessage(dups)
2404
2405
  });
2405
2406
  }
2406
2407
  })
@@ -2415,7 +2416,7 @@ If you need to use this value in your content you can use the \`nameOverride\` p
2415
2416
  if (dups) {
2416
2417
  ctx.addIssue({
2417
2418
  code: z.z.ZodIssueCode.custom,
2418
- message: `Templates must have a unique name, duplicate template names: ${dups}`
2419
+ message: duplicateTemplateErrorMessage(dups)
2419
2420
  });
2420
2421
  }
2421
2422
  })
@@ -2435,10 +2436,17 @@ If you need to use this value in your content you can use the \`nameOverride\` p
2435
2436
  ],
2436
2437
  {
2437
2438
  errorMap: (issue, ctx) => {
2438
- var _a;
2439
+ var _a, _b;
2439
2440
  if (issue.code === "invalid_union_discriminator") {
2441
+ if (!((_a = ctx.data) == null ? void 0 : _a.type)) {
2442
+ return {
2443
+ message: `Missing \`type\` property in field \`${ctx.data.name}\`. Please add a \`type\` property with one of the following:
2444
+ ${formattedTypes}`
2445
+ };
2446
+ }
2440
2447
  return {
2441
- message: `Invalid \`type\` property. In the schema is 'type: ${(_a = ctx.data) == null ? void 0 : _a.type}' and expected one of ${TypeName.join(", ")}`
2448
+ 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:
2449
+ ${formattedTypes}`
2442
2450
  };
2443
2451
  }
2444
2452
  return {
@@ -2448,77 +2456,52 @@ If you need to use this value in your content you can use the \`nameOverride\` p
2448
2456
  }
2449
2457
  ).superRefine((val, ctx) => {
2450
2458
  if (val.type === "string") {
2451
- if (val.isTitle) {
2452
- if (val.list) {
2453
- ctx.addIssue({
2454
- code: z.z.ZodIssueCode.custom,
2455
- message: `Can not have \`list: true\` when using \`isTitle\`. Error in value
2456
- ${JSON.stringify(
2457
- val,
2458
- null,
2459
- 2
2460
- )}
2461
- `
2462
- });
2463
- }
2464
- if (!val.required) {
2465
- ctx.addIssue({
2466
- code: z.z.ZodIssueCode.custom,
2467
- message: `Must have { required: true } when using \`isTitle\` Error in value
2468
- ${JSON.stringify(
2469
- val,
2470
- null,
2471
- 2
2472
- )}
2473
- `
2474
- });
2475
- }
2459
+ const stringifiedField = JSON.stringify(val, null, 2);
2460
+ if (val.isTitle && val.list) {
2461
+ ctx.addIssue({
2462
+ code: z.z.ZodIssueCode.custom,
2463
+ message: `\`list: true\` is not allowed when using \`isTitle\` for fields of \`type: string\`. Error found in field:
2464
+ ${stringifiedField}`
2465
+ });
2466
+ }
2467
+ if (val.isTitle && !val.required) {
2468
+ ctx.addIssue({
2469
+ code: z.z.ZodIssueCode.custom,
2470
+ message: `Property \`required: true\` is required when using \`isTitle\` for fields of \`type: string\`. Error found in field:
2471
+ ${stringifiedField}`
2472
+ });
2476
2473
  }
2477
- if (val.uid) {
2474
+ if (val.uid && val.list) {
2478
2475
  if (val.list) {
2479
2476
  ctx.addIssue({
2480
2477
  code: z.z.ZodIssueCode.custom,
2481
- message: `Can not have \`list: true\` when using \`uid\`. Error in value
2482
- ${JSON.stringify(
2483
- val,
2484
- null,
2485
- 2
2486
- )}
2487
- `
2488
- });
2489
- }
2490
- if (!val.required) {
2491
- ctx.addIssue({
2492
- code: z.z.ZodIssueCode.custom,
2493
- message: `Must have { required: true } when using \`uid\` Error in value
2494
- ${JSON.stringify(
2495
- val,
2496
- null,
2497
- 2
2498
- )}
2499
- `
2478
+ message: `\`list: true\` is not allowed when using \`uid\` for fields of \`type: string\`. Error found in field:
2479
+ ${stringifiedField}`
2500
2480
  });
2501
2481
  }
2502
2482
  }
2483
+ if (val.uid && !val.required) {
2484
+ ctx.addIssue({
2485
+ code: z.z.ZodIssueCode.custom,
2486
+ message: `Property \`required: true\` is required when using \`uid\` for fields of \`type: string\`. Error found in field:
2487
+ ${stringifiedField}`
2488
+ });
2489
+ }
2503
2490
  }
2504
2491
  if (val.type === "object") {
2505
- const message = "Must provide one of templates or fields in your collection";
2506
- let isValid = Boolean(val == null ? void 0 : val.templates) || Boolean(val == null ? void 0 : val.fields);
2507
- if (!isValid) {
2492
+ if (!(val == null ? void 0 : val.templates) && !(val == null ? void 0 : val.fields)) {
2508
2493
  ctx.addIssue({
2509
2494
  code: z.z.ZodIssueCode.custom,
2510
- message
2495
+ message: "Fields of `type: object` must have either `templates` or `fields` property."
2496
+ });
2497
+ return false;
2498
+ }
2499
+ if ((val == null ? void 0 : val.templates) && (val == null ? void 0 : val.fields)) {
2500
+ ctx.addIssue({
2501
+ code: z.z.ZodIssueCode.custom,
2502
+ message: "Fields of `type: object` must have either `templates` or `fields` property, not both."
2511
2503
  });
2512
2504
  return false;
2513
- } else {
2514
- isValid = !((val == null ? void 0 : val.templates) && (val == null ? void 0 : val.fields));
2515
- if (!isValid) {
2516
- ctx.addIssue({
2517
- code: z.z.ZodIssueCode.custom,
2518
- message
2519
- });
2520
- }
2521
- return isValid;
2522
2505
  }
2523
2506
  }
2524
2507
  return true;
@@ -2562,8 +2545,8 @@ ${JSON.stringify(
2562
2545
  ];
2563
2546
  const Template = z.z.object({
2564
2547
  label: z.z.string({
2565
- invalid_type_error: "label must be a string",
2566
- required_error: "label was not provided but is required"
2548
+ invalid_type_error: "Invalid data type for property `label`. Must be of type `string`",
2549
+ required_error: "Missing `label` property. Property `label` is required."
2567
2550
  }),
2568
2551
  name,
2569
2552
  fields: z.z.array(TinaFieldZod)
@@ -2573,7 +2556,7 @@ ${JSON.stringify(
2573
2556
  if (dups) {
2574
2557
  ctx.addIssue({
2575
2558
  code: z.z.ZodIssueCode.custom,
2576
- message: `Fields must have a unique name, duplicate field names: ${dups}`
2559
+ message: duplicateFieldErrorMessage(dups)
2577
2560
  });
2578
2561
  }
2579
2562
  });
@@ -2583,7 +2566,7 @@ ${JSON.stringify(
2583
2566
  if (val === "relativePath") {
2584
2567
  ctx.addIssue({
2585
2568
  code: z.z.ZodIssueCode.custom,
2586
- message: `name cannot be 'relativePath'. 'relativePath' is a reserved field name.`
2569
+ message: "Invalid `name` property. `name` cannot be 'relativePath' as it is a reserved field name."
2587
2570
  });
2588
2571
  }
2589
2572
  }),
@@ -2591,7 +2574,7 @@ ${JSON.stringify(
2591
2574
  if (val === ".") {
2592
2575
  ctx.addIssue({
2593
2576
  code: z.z.ZodIssueCode.custom,
2594
- message: `path cannot be '.'. Please use '/' or '' instead. `
2577
+ message: "Invalid `path` property. `path` cannot be '.'. Please use '/' or '' instead."
2595
2578
  });
2596
2579
  }
2597
2580
  }),
@@ -2600,63 +2583,64 @@ ${JSON.stringify(
2600
2583
  isDetached: z.z.boolean().optional()
2601
2584
  });
2602
2585
  const TinaCloudCollection = CollectionBaseSchema.extend({
2603
- fields: z.z.array(TinaFieldZod).min(1).optional().superRefine((val, ctx) => {
2586
+ fields: z.z.array(TinaFieldZod).min(1, "Property `fields` cannot be empty.").optional().superRefine((val, ctx) => {
2604
2587
  const dups = findDuplicates(val == null ? void 0 : val.map((x) => x.name));
2605
2588
  if (dups) {
2606
2589
  ctx.addIssue({
2607
2590
  code: z.z.ZodIssueCode.custom,
2608
- message: `Fields must have a unique name, duplicate field names: ${dups}`
2591
+ message: duplicateFieldErrorMessage(dups)
2609
2592
  });
2610
2593
  }
2611
- }).refine(
2612
- // It is valid if it is 0 or 1
2613
- (val) => {
2614
- const arr = (val == null ? void 0 : val.filter((x) => x.type === "string" && x.isTitle)) || [];
2615
- return arr.length < 2;
2616
- },
2617
- {
2618
- message: "Fields can only have one use of `isTitle`"
2619
- }
2620
- ).refine(
2621
- // It is valid if it is 0 or 1
2622
- (val) => {
2623
- const arr = (val == null ? void 0 : val.filter((x) => x.uid)) || [];
2624
- return arr.length < 2;
2625
- },
2626
- {
2627
- message: "Fields can only have one use of `uid`"
2628
- }
2629
- ).refine(
2630
- // It is valid if it is 0 or 1
2631
- (val) => {
2632
- const arr = (val == null ? void 0 : val.filter((x) => x.type === "password")) || [];
2633
- return arr.length < 2;
2634
- },
2635
- {
2636
- message: "Fields can only have one use of `password` type"
2594
+ }).superRefine((val, ctx) => {
2595
+ const arr = (val == null ? void 0 : val.filter((x) => x.type === "string" && x.isTitle)) || [];
2596
+ if (arr.length > 1) {
2597
+ ctx.addIssue({
2598
+ code: z.z.ZodIssueCode.custom,
2599
+ message: `The following fields have the property \`isTitle\`: [${arr.map((field) => field.name).join(", ")}]. Only one can contain the property \`isTitle\`.`
2600
+ });
2601
+ }
2602
+ }).superRefine((val, ctx) => {
2603
+ const arr = (val == null ? void 0 : val.filter((x) => x.uid)) || [];
2604
+ if (arr.length > 2) {
2605
+ ctx.addIssue({
2606
+ code: z.z.ZodIssueCode.custom,
2607
+ message: `The following fields have the property \`uid\`: [${arr.map((field) => field.name).join(", ")}]. Only one can contain the property \`uid\`.`
2608
+ });
2637
2609
  }
2638
- ),
2639
- templates: z.z.array(Template).min(1).optional().superRefine((val, ctx) => {
2610
+ }).superRefine((val, ctx) => {
2611
+ const arr = (val == null ? void 0 : val.filter((x) => x.type === "password")) || [];
2612
+ if (arr.length > 2) {
2613
+ ctx.addIssue({
2614
+ code: z.z.ZodIssueCode.custom,
2615
+ message: `The following fields have \`type: password\`: [${arr.map((field) => field.name).join(", ")}]. Only one can be of \`type: password\`.`
2616
+ });
2617
+ }
2618
+ }),
2619
+ templates: z.z.array(Template).min(1, "Property `templates` cannot be empty.").optional().superRefine((val, ctx) => {
2640
2620
  const dups = findDuplicates(val == null ? void 0 : val.map((x) => x.name));
2641
2621
  if (dups) {
2642
2622
  ctx.addIssue({
2643
2623
  code: z.z.ZodIssueCode.custom,
2644
- message: `Templates must have a unique name, duplicate template names: ${dups}`
2624
+ message: duplicateFieldErrorMessage(dups)
2645
2625
  });
2646
2626
  }
2647
2627
  })
2648
- }).refine(
2649
- (val) => {
2650
- let isValid = Boolean(val == null ? void 0 : val.templates) || Boolean(val == null ? void 0 : val.fields);
2651
- if (!isValid) {
2652
- return false;
2653
- } else {
2654
- isValid = !((val == null ? void 0 : val.templates) && (val == null ? void 0 : val.fields));
2655
- return isValid;
2656
- }
2657
- },
2658
- { message: "Must provide one of templates or fields in your collection" }
2659
- );
2628
+ }).superRefine((val, ctx) => {
2629
+ if (!(val == null ? void 0 : val.templates) && !(val == null ? void 0 : val.fields)) {
2630
+ ctx.addIssue({
2631
+ code: z.z.ZodIssueCode.custom,
2632
+ message: "Fields of `type: object` must have either `templates` or `fields` property."
2633
+ });
2634
+ return false;
2635
+ }
2636
+ if ((val == null ? void 0 : val.templates) && (val == null ? void 0 : val.fields)) {
2637
+ ctx.addIssue({
2638
+ code: z.z.ZodIssueCode.custom,
2639
+ message: "Fields of `type: object` must have either `templates` or `fields` property, not both."
2640
+ });
2641
+ return false;
2642
+ }
2643
+ });
2660
2644
  const TinaCloudSchemaZod = z.z.object({
2661
2645
  collections: z.z.array(TinaCloudCollection),
2662
2646
  config: tinaConfigZod.optional()
@@ -2666,14 +2650,14 @@ ${JSON.stringify(
2666
2650
  if (dups) {
2667
2651
  ctx.addIssue({
2668
2652
  code: z.z.ZodIssueCode.custom,
2669
- message: `${dups} are duplicate names in your collections. Collection names must be unique.`,
2653
+ message: duplicateCollectionErrorMessage(dups),
2670
2654
  fatal: true
2671
2655
  });
2672
2656
  }
2673
2657
  if (((_b = val.collections) == null ? void 0 : _b.filter((x) => x.isAuthCollection).length) > 1) {
2674
2658
  ctx.addIssue({
2675
2659
  code: z.z.ZodIssueCode.custom,
2676
- message: `Only one collection can be marked as isAuthCollection`,
2660
+ message: "Only one collection can be marked as `isAuthCollection`.",
2677
2661
  fatal: true
2678
2662
  });
2679
2663
  }
@@ -2681,7 +2665,7 @@ ${JSON.stringify(
2681
2665
  if (media && media.tina && media.loadCustomStore) {
2682
2666
  ctx.addIssue({
2683
2667
  code: z.z.ZodIssueCode.custom,
2684
- message: "can not have both loadCustomStore and tina. Must use one or the other",
2668
+ message: "Cannot have both `loadCustomStore` and `tina`. Must use one or the other.",
2685
2669
  fatal: true,
2686
2670
  path: ["config", "media"]
2687
2671
  });
@@ -2690,7 +2674,7 @@ ${JSON.stringify(
2690
2674
  if (search && search.tina && search.searchClient) {
2691
2675
  ctx.addIssue({
2692
2676
  code: z.z.ZodIssueCode.custom,
2693
- message: "can not have both searchClient and tina. Must use one or the other",
2677
+ message: "Cannot have both `searchClient` and `tina`. Must use one or the other.",
2694
2678
  fatal: true,
2695
2679
  path: ["config", "search"]
2696
2680
  });
@@ -2708,7 +2692,7 @@ ${JSON.stringify(
2708
2692
  } catch (e) {
2709
2693
  if (e instanceof z.ZodError) {
2710
2694
  const errors = parseZodError({ zodError: e });
2711
- throw new TinaSchemaValidationError(errors.join(", \n"));
2695
+ throw new TinaSchemaValidationError(errors.join("\n"));
2712
2696
  }
2713
2697
  throw new Error(e);
2714
2698
  }
package/dist/index.mjs CHANGED
@@ -2,42 +2,26 @@ import * as yup from "yup";
2
2
  import UrlPattern from "url-pattern";
3
3
  import z$1, { z, ZodError } from "zod";
4
4
  function addNamespaceToSchema(maybeNode, namespace = []) {
5
- if (typeof maybeNode === "string") {
5
+ if (typeof maybeNode !== "object" || maybeNode === null) {
6
6
  return maybeNode;
7
7
  }
8
- if (typeof maybeNode === "boolean") {
9
- return maybeNode;
10
- }
11
- if (typeof maybeNode === "function") {
12
- return maybeNode;
13
- }
14
- const newNode = { ...maybeNode };
15
- const keys = Object.keys(maybeNode);
16
- Object.values(maybeNode).map((m, index) => {
17
- const key = keys[index];
18
- if (Array.isArray(m)) {
19
- newNode[key] = m.map((element) => {
20
- if (!element) {
21
- return;
22
- }
23
- if (!element.hasOwnProperty("name")) {
24
- return element;
8
+ const newNode = { ...maybeNode, namespace: [...namespace] };
9
+ Object.entries(maybeNode).forEach(([key, value]) => {
10
+ if (Array.isArray(value)) {
11
+ newNode[key] = value.map((element) => {
12
+ if (element && typeof element === "object" && "name" in element) {
13
+ const valueName = element.name || element.value;
14
+ return addNamespaceToSchema(element, [...namespace, valueName]);
25
15
  }
26
- const value = element.name || element.value;
27
- return addNamespaceToSchema(element, [...namespace, value]);
16
+ return element;
28
17
  });
18
+ } else if (value && typeof value === "object" && "name" in value) {
19
+ newNode[key] = addNamespaceToSchema(value, [...namespace, value.name]);
29
20
  } else {
30
- if (!m) {
31
- return;
32
- }
33
- if (!m.hasOwnProperty("name")) {
34
- newNode[key] = m;
35
- } else {
36
- newNode[key] = addNamespaceToSchema(m, [...namespace, m.name]);
37
- }
21
+ newNode[key] = value;
38
22
  }
39
23
  });
40
- return { ...newNode, namespace };
24
+ return newNode;
41
25
  }
42
26
  function getDefaultExportFromCjs(x) {
43
27
  return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x["default"] : x;
@@ -1943,29 +1927,8 @@ class TinaSchema {
1943
1927
  }
1944
1928
  }
1945
1929
  };
1946
- this.walkFields = (cb) => {
1947
- const walk = (collectionOrObject, collection, path) => {
1948
- if (collectionOrObject.templates) {
1949
- collectionOrObject.templates.forEach((template) => {
1950
- template.fields.forEach((field) => {
1951
- cb({ field, collection, path: [...path, template.name] });
1952
- });
1953
- });
1954
- }
1955
- if (collectionOrObject.fields) {
1956
- collectionOrObject.fields.forEach((field) => {
1957
- cb({ field, collection, path: [...path, field.name] });
1958
- if (field.type === "rich-text" || field.type === "object") {
1959
- walk(field, collection, [...path, field.name]);
1960
- }
1961
- });
1962
- }
1963
- };
1964
- const collections = this.getCollections();
1965
- collections.forEach((collection) => walk(collection, collection, []));
1966
- };
1967
1930
  this.schema = config;
1968
- this.walkFields(({ field, collection, path }) => {
1931
+ this.walkFields(({ field, collection }) => {
1969
1932
  if (!("searchable" in field)) {
1970
1933
  if (field.type === "image") {
1971
1934
  field.searchable = false;
@@ -1986,20 +1949,51 @@ class TinaSchema {
1986
1949
  field.uid = field.uid || false;
1987
1950
  });
1988
1951
  }
1989
- findReferences(name2) {
1952
+ findReferencesFromCollection(name2) {
1990
1953
  const result = {};
1991
1954
  this.walkFields(({ field, collection: c, path }) => {
1955
+ if (c.name !== name2) {
1956
+ return;
1957
+ }
1992
1958
  if (field.type === "reference") {
1993
- if (field.collections.includes(name2)) {
1994
- if (result[c.name] === void 0) {
1995
- result[c.name] = [];
1959
+ field.collections.forEach((name22) => {
1960
+ if (result[name22] === void 0) {
1961
+ result[name22] = [];
1996
1962
  }
1997
- result[c.name].push({ path, field });
1998
- }
1963
+ result[name22].push(path);
1964
+ });
1999
1965
  }
2000
1966
  });
2001
1967
  return result;
2002
1968
  }
1969
+ walkFields(cb) {
1970
+ const walk = (collectionOrObject, collection, path = "$") => {
1971
+ if (collectionOrObject.templates) {
1972
+ collectionOrObject.templates.forEach((template) => {
1973
+ const templatePath = `${path}.${template.name}`;
1974
+ template.fields.forEach((field) => {
1975
+ const fieldPath = field.list ? `${templatePath}[*].${field.name}` : `${templatePath}.${field.name}`;
1976
+ cb({ field, collection, path: fieldPath });
1977
+ if (field.type === "object") {
1978
+ walk(field, collection, fieldPath);
1979
+ }
1980
+ });
1981
+ });
1982
+ }
1983
+ if (collectionOrObject.fields) {
1984
+ collectionOrObject.fields.forEach((field) => {
1985
+ const fieldPath = field.list ? `${path}.${field.name}[*]` : `${path}.${field.name}`;
1986
+ cb({ field, collection, path: fieldPath });
1987
+ if (field.type === "object" && field.fields) {
1988
+ walk(field, collection, fieldPath);
1989
+ }
1990
+ });
1991
+ }
1992
+ };
1993
+ this.getCollections().forEach((collection) => {
1994
+ walk(collection, collection);
1995
+ });
1996
+ }
2003
1997
  /**
2004
1998
  * This function returns an array of glob matches for a given collection.
2005
1999
  *
@@ -2222,9 +2216,12 @@ const parseZodError = ({ zodError }) => {
2222
2216
  moreInfo.push(parseZodError({ zodError: unionError }));
2223
2217
  });
2224
2218
  }
2225
- const errorMessage = `Error ${issue == null ? void 0 : issue.message} at path ${issue.path.join(
2219
+ const errorMessage = `${issue == null ? void 0 : issue.message}
2220
+ Additional information:
2221
+ - Error found at path ${issue.path.join(
2226
2222
  "."
2227
- )}`;
2223
+ )}
2224
+ `;
2228
2225
  const errorMessages = [errorMessage, ...moreInfo];
2229
2226
  return {
2230
2227
  errors: errorMessages
@@ -2259,6 +2256,9 @@ If you need to use this value in your content you can use the \`nameOverride\` p
2259
2256
  });
2260
2257
  }
2261
2258
  });
2259
+ const duplicateFieldErrorMessage = (fields) => `Fields must have unique names. Found duplicate field names: [${fields}]`;
2260
+ const duplicateTemplateErrorMessage = (templates) => `Templates must have unique names. Found duplicate template names: [${templates}]`;
2261
+ const duplicateCollectionErrorMessage = (collection) => `Collections must have unique names. Found duplicate collection names: [${collection}]`;
2262
2262
  const TypeName = [
2263
2263
  "string",
2264
2264
  "boolean",
@@ -2269,10 +2269,11 @@ const TypeName = [
2269
2269
  "reference",
2270
2270
  "rich-text"
2271
2271
  ];
2272
- const typeTypeError = `type must be one of ${TypeName.join(", ")}`;
2273
- const typeRequiredError = `type is required and must be one of ${TypeName.join(
2274
- ", "
2275
- )}`;
2272
+ const formattedTypes = ` - ${TypeName.join("\n - ")}`;
2273
+ const typeTypeError = `Invalid \`type\` property. \`type\` expected to be one of the following values:
2274
+ ${formattedTypes}`;
2275
+ const typeRequiredError = `Missing \`type\` property. Please add a \`type\` property with one of the following:
2276
+ ${formattedTypes}`;
2276
2277
  const Option = z.union(
2277
2278
  [
2278
2279
  z.string(),
@@ -2358,7 +2359,7 @@ const TinaFieldZod = z.lazy(() => {
2358
2359
  if (dups) {
2359
2360
  ctx.addIssue({
2360
2361
  code: z.ZodIssueCode.custom,
2361
- message: `Fields must have a unique name, duplicate field names: ${dups}`
2362
+ message: duplicateFieldErrorMessage(dups)
2362
2363
  });
2363
2364
  }
2364
2365
  });
@@ -2368,21 +2369,21 @@ const TinaFieldZod = z.lazy(() => {
2368
2369
  invalid_type_error: typeTypeError,
2369
2370
  required_error: typeRequiredError
2370
2371
  }),
2371
- fields: z.array(TinaFieldZod).min(1).optional().superRefine((val, ctx) => {
2372
+ fields: z.array(TinaFieldZod).min(1, "Property `fields` cannot be empty.").optional().superRefine((val, ctx) => {
2372
2373
  const dups = findDuplicates(val == null ? void 0 : val.map((x) => x.name));
2373
2374
  if (dups) {
2374
2375
  ctx.addIssue({
2375
2376
  code: z.ZodIssueCode.custom,
2376
- message: `Fields must have a unique name, duplicate field names: ${dups}`
2377
+ message: duplicateFieldErrorMessage(dups)
2377
2378
  });
2378
2379
  }
2379
2380
  }),
2380
- templates: z.array(TemplateTemp).min(1).optional().superRefine((val, ctx) => {
2381
+ templates: z.array(TemplateTemp).min(1, "Property `templates` cannot be empty.").optional().superRefine((val, ctx) => {
2381
2382
  const dups = findDuplicates(val == null ? void 0 : val.map((x) => x.name));
2382
2383
  if (dups) {
2383
2384
  ctx.addIssue({
2384
2385
  code: z.ZodIssueCode.custom,
2385
- message: `Templates must have a unique name, duplicate template names: ${dups}`
2386
+ message: duplicateTemplateErrorMessage(dups)
2386
2387
  });
2387
2388
  }
2388
2389
  })
@@ -2397,7 +2398,7 @@ const TinaFieldZod = z.lazy(() => {
2397
2398
  if (dups) {
2398
2399
  ctx.addIssue({
2399
2400
  code: z.ZodIssueCode.custom,
2400
- message: `Templates must have a unique name, duplicate template names: ${dups}`
2401
+ message: duplicateTemplateErrorMessage(dups)
2401
2402
  });
2402
2403
  }
2403
2404
  })
@@ -2417,10 +2418,17 @@ const TinaFieldZod = z.lazy(() => {
2417
2418
  ],
2418
2419
  {
2419
2420
  errorMap: (issue, ctx) => {
2420
- var _a;
2421
+ var _a, _b;
2421
2422
  if (issue.code === "invalid_union_discriminator") {
2423
+ if (!((_a = ctx.data) == null ? void 0 : _a.type)) {
2424
+ return {
2425
+ message: `Missing \`type\` property in field \`${ctx.data.name}\`. Please add a \`type\` property with one of the following:
2426
+ ${formattedTypes}`
2427
+ };
2428
+ }
2422
2429
  return {
2423
- message: `Invalid \`type\` property. In the schema is 'type: ${(_a = ctx.data) == null ? void 0 : _a.type}' and expected one of ${TypeName.join(", ")}`
2430
+ 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:
2431
+ ${formattedTypes}`
2424
2432
  };
2425
2433
  }
2426
2434
  return {
@@ -2430,77 +2438,52 @@ const TinaFieldZod = z.lazy(() => {
2430
2438
  }
2431
2439
  ).superRefine((val, ctx) => {
2432
2440
  if (val.type === "string") {
2433
- if (val.isTitle) {
2434
- if (val.list) {
2435
- ctx.addIssue({
2436
- code: z.ZodIssueCode.custom,
2437
- message: `Can not have \`list: true\` when using \`isTitle\`. Error in value
2438
- ${JSON.stringify(
2439
- val,
2440
- null,
2441
- 2
2442
- )}
2443
- `
2444
- });
2445
- }
2446
- if (!val.required) {
2447
- ctx.addIssue({
2448
- code: z.ZodIssueCode.custom,
2449
- message: `Must have { required: true } when using \`isTitle\` Error in value
2450
- ${JSON.stringify(
2451
- val,
2452
- null,
2453
- 2
2454
- )}
2455
- `
2456
- });
2457
- }
2441
+ const stringifiedField = JSON.stringify(val, null, 2);
2442
+ if (val.isTitle && val.list) {
2443
+ ctx.addIssue({
2444
+ code: z.ZodIssueCode.custom,
2445
+ message: `\`list: true\` is not allowed when using \`isTitle\` for fields of \`type: string\`. Error found in field:
2446
+ ${stringifiedField}`
2447
+ });
2448
+ }
2449
+ if (val.isTitle && !val.required) {
2450
+ ctx.addIssue({
2451
+ code: z.ZodIssueCode.custom,
2452
+ message: `Property \`required: true\` is required when using \`isTitle\` for fields of \`type: string\`. Error found in field:
2453
+ ${stringifiedField}`
2454
+ });
2458
2455
  }
2459
- if (val.uid) {
2456
+ if (val.uid && val.list) {
2460
2457
  if (val.list) {
2461
2458
  ctx.addIssue({
2462
2459
  code: z.ZodIssueCode.custom,
2463
- message: `Can not have \`list: true\` when using \`uid\`. Error in value
2464
- ${JSON.stringify(
2465
- val,
2466
- null,
2467
- 2
2468
- )}
2469
- `
2470
- });
2471
- }
2472
- if (!val.required) {
2473
- ctx.addIssue({
2474
- code: z.ZodIssueCode.custom,
2475
- message: `Must have { required: true } when using \`uid\` Error in value
2476
- ${JSON.stringify(
2477
- val,
2478
- null,
2479
- 2
2480
- )}
2481
- `
2460
+ message: `\`list: true\` is not allowed when using \`uid\` for fields of \`type: string\`. Error found in field:
2461
+ ${stringifiedField}`
2482
2462
  });
2483
2463
  }
2484
2464
  }
2465
+ if (val.uid && !val.required) {
2466
+ ctx.addIssue({
2467
+ code: z.ZodIssueCode.custom,
2468
+ message: `Property \`required: true\` is required when using \`uid\` for fields of \`type: string\`. Error found in field:
2469
+ ${stringifiedField}`
2470
+ });
2471
+ }
2485
2472
  }
2486
2473
  if (val.type === "object") {
2487
- const message = "Must provide one of templates or fields in your collection";
2488
- let isValid = Boolean(val == null ? void 0 : val.templates) || Boolean(val == null ? void 0 : val.fields);
2489
- if (!isValid) {
2474
+ if (!(val == null ? void 0 : val.templates) && !(val == null ? void 0 : val.fields)) {
2490
2475
  ctx.addIssue({
2491
2476
  code: z.ZodIssueCode.custom,
2492
- message
2477
+ message: "Fields of `type: object` must have either `templates` or `fields` property."
2478
+ });
2479
+ return false;
2480
+ }
2481
+ if ((val == null ? void 0 : val.templates) && (val == null ? void 0 : val.fields)) {
2482
+ ctx.addIssue({
2483
+ code: z.ZodIssueCode.custom,
2484
+ message: "Fields of `type: object` must have either `templates` or `fields` property, not both."
2493
2485
  });
2494
2486
  return false;
2495
- } else {
2496
- isValid = !((val == null ? void 0 : val.templates) && (val == null ? void 0 : val.fields));
2497
- if (!isValid) {
2498
- ctx.addIssue({
2499
- code: z.ZodIssueCode.custom,
2500
- message
2501
- });
2502
- }
2503
- return isValid;
2504
2487
  }
2505
2488
  }
2506
2489
  return true;
@@ -2544,8 +2527,8 @@ const FORMATS = [
2544
2527
  ];
2545
2528
  const Template = z.object({
2546
2529
  label: z.string({
2547
- invalid_type_error: "label must be a string",
2548
- required_error: "label was not provided but is required"
2530
+ invalid_type_error: "Invalid data type for property `label`. Must be of type `string`",
2531
+ required_error: "Missing `label` property. Property `label` is required."
2549
2532
  }),
2550
2533
  name,
2551
2534
  fields: z.array(TinaFieldZod)
@@ -2555,7 +2538,7 @@ const Template = z.object({
2555
2538
  if (dups) {
2556
2539
  ctx.addIssue({
2557
2540
  code: z.ZodIssueCode.custom,
2558
- message: `Fields must have a unique name, duplicate field names: ${dups}`
2541
+ message: duplicateFieldErrorMessage(dups)
2559
2542
  });
2560
2543
  }
2561
2544
  });
@@ -2565,7 +2548,7 @@ const CollectionBaseSchema = z.object({
2565
2548
  if (val === "relativePath") {
2566
2549
  ctx.addIssue({
2567
2550
  code: z.ZodIssueCode.custom,
2568
- message: `name cannot be 'relativePath'. 'relativePath' is a reserved field name.`
2551
+ message: "Invalid `name` property. `name` cannot be 'relativePath' as it is a reserved field name."
2569
2552
  });
2570
2553
  }
2571
2554
  }),
@@ -2573,7 +2556,7 @@ const CollectionBaseSchema = z.object({
2573
2556
  if (val === ".") {
2574
2557
  ctx.addIssue({
2575
2558
  code: z.ZodIssueCode.custom,
2576
- message: `path cannot be '.'. Please use '/' or '' instead. `
2559
+ message: "Invalid `path` property. `path` cannot be '.'. Please use '/' or '' instead."
2577
2560
  });
2578
2561
  }
2579
2562
  }),
@@ -2582,63 +2565,64 @@ const CollectionBaseSchema = z.object({
2582
2565
  isDetached: z.boolean().optional()
2583
2566
  });
2584
2567
  const TinaCloudCollection = CollectionBaseSchema.extend({
2585
- fields: z.array(TinaFieldZod).min(1).optional().superRefine((val, ctx) => {
2568
+ fields: z.array(TinaFieldZod).min(1, "Property `fields` cannot be empty.").optional().superRefine((val, ctx) => {
2586
2569
  const dups = findDuplicates(val == null ? void 0 : val.map((x) => x.name));
2587
2570
  if (dups) {
2588
2571
  ctx.addIssue({
2589
2572
  code: z.ZodIssueCode.custom,
2590
- message: `Fields must have a unique name, duplicate field names: ${dups}`
2573
+ message: duplicateFieldErrorMessage(dups)
2591
2574
  });
2592
2575
  }
2593
- }).refine(
2594
- // It is valid if it is 0 or 1
2595
- (val) => {
2596
- const arr = (val == null ? void 0 : val.filter((x) => x.type === "string" && x.isTitle)) || [];
2597
- return arr.length < 2;
2598
- },
2599
- {
2600
- message: "Fields can only have one use of `isTitle`"
2601
- }
2602
- ).refine(
2603
- // It is valid if it is 0 or 1
2604
- (val) => {
2605
- const arr = (val == null ? void 0 : val.filter((x) => x.uid)) || [];
2606
- return arr.length < 2;
2607
- },
2608
- {
2609
- message: "Fields can only have one use of `uid`"
2610
- }
2611
- ).refine(
2612
- // It is valid if it is 0 or 1
2613
- (val) => {
2614
- const arr = (val == null ? void 0 : val.filter((x) => x.type === "password")) || [];
2615
- return arr.length < 2;
2616
- },
2617
- {
2618
- message: "Fields can only have one use of `password` type"
2576
+ }).superRefine((val, ctx) => {
2577
+ const arr = (val == null ? void 0 : val.filter((x) => x.type === "string" && x.isTitle)) || [];
2578
+ if (arr.length > 1) {
2579
+ ctx.addIssue({
2580
+ code: z.ZodIssueCode.custom,
2581
+ message: `The following fields have the property \`isTitle\`: [${arr.map((field) => field.name).join(", ")}]. Only one can contain the property \`isTitle\`.`
2582
+ });
2583
+ }
2584
+ }).superRefine((val, ctx) => {
2585
+ const arr = (val == null ? void 0 : val.filter((x) => x.uid)) || [];
2586
+ if (arr.length > 2) {
2587
+ ctx.addIssue({
2588
+ code: z.ZodIssueCode.custom,
2589
+ message: `The following fields have the property \`uid\`: [${arr.map((field) => field.name).join(", ")}]. Only one can contain the property \`uid\`.`
2590
+ });
2619
2591
  }
2620
- ),
2621
- templates: z.array(Template).min(1).optional().superRefine((val, ctx) => {
2592
+ }).superRefine((val, ctx) => {
2593
+ const arr = (val == null ? void 0 : val.filter((x) => x.type === "password")) || [];
2594
+ if (arr.length > 2) {
2595
+ ctx.addIssue({
2596
+ code: z.ZodIssueCode.custom,
2597
+ message: `The following fields have \`type: password\`: [${arr.map((field) => field.name).join(", ")}]. Only one can be of \`type: password\`.`
2598
+ });
2599
+ }
2600
+ }),
2601
+ templates: z.array(Template).min(1, "Property `templates` cannot be empty.").optional().superRefine((val, ctx) => {
2622
2602
  const dups = findDuplicates(val == null ? void 0 : val.map((x) => x.name));
2623
2603
  if (dups) {
2624
2604
  ctx.addIssue({
2625
2605
  code: z.ZodIssueCode.custom,
2626
- message: `Templates must have a unique name, duplicate template names: ${dups}`
2606
+ message: duplicateFieldErrorMessage(dups)
2627
2607
  });
2628
2608
  }
2629
2609
  })
2630
- }).refine(
2631
- (val) => {
2632
- let isValid = Boolean(val == null ? void 0 : val.templates) || Boolean(val == null ? void 0 : val.fields);
2633
- if (!isValid) {
2634
- return false;
2635
- } else {
2636
- isValid = !((val == null ? void 0 : val.templates) && (val == null ? void 0 : val.fields));
2637
- return isValid;
2638
- }
2639
- },
2640
- { message: "Must provide one of templates or fields in your collection" }
2641
- );
2610
+ }).superRefine((val, ctx) => {
2611
+ if (!(val == null ? void 0 : val.templates) && !(val == null ? void 0 : val.fields)) {
2612
+ ctx.addIssue({
2613
+ code: z.ZodIssueCode.custom,
2614
+ message: "Fields of `type: object` must have either `templates` or `fields` property."
2615
+ });
2616
+ return false;
2617
+ }
2618
+ if ((val == null ? void 0 : val.templates) && (val == null ? void 0 : val.fields)) {
2619
+ ctx.addIssue({
2620
+ code: z.ZodIssueCode.custom,
2621
+ message: "Fields of `type: object` must have either `templates` or `fields` property, not both."
2622
+ });
2623
+ return false;
2624
+ }
2625
+ });
2642
2626
  const TinaCloudSchemaZod = z.object({
2643
2627
  collections: z.array(TinaCloudCollection),
2644
2628
  config: tinaConfigZod.optional()
@@ -2648,14 +2632,14 @@ const TinaCloudSchemaZod = z.object({
2648
2632
  if (dups) {
2649
2633
  ctx.addIssue({
2650
2634
  code: z.ZodIssueCode.custom,
2651
- message: `${dups} are duplicate names in your collections. Collection names must be unique.`,
2635
+ message: duplicateCollectionErrorMessage(dups),
2652
2636
  fatal: true
2653
2637
  });
2654
2638
  }
2655
2639
  if (((_b = val.collections) == null ? void 0 : _b.filter((x) => x.isAuthCollection).length) > 1) {
2656
2640
  ctx.addIssue({
2657
2641
  code: z.ZodIssueCode.custom,
2658
- message: `Only one collection can be marked as isAuthCollection`,
2642
+ message: "Only one collection can be marked as `isAuthCollection`.",
2659
2643
  fatal: true
2660
2644
  });
2661
2645
  }
@@ -2663,7 +2647,7 @@ const TinaCloudSchemaZod = z.object({
2663
2647
  if (media && media.tina && media.loadCustomStore) {
2664
2648
  ctx.addIssue({
2665
2649
  code: z.ZodIssueCode.custom,
2666
- message: "can not have both loadCustomStore and tina. Must use one or the other",
2650
+ message: "Cannot have both `loadCustomStore` and `tina`. Must use one or the other.",
2667
2651
  fatal: true,
2668
2652
  path: ["config", "media"]
2669
2653
  });
@@ -2672,7 +2656,7 @@ const TinaCloudSchemaZod = z.object({
2672
2656
  if (search && search.tina && search.searchClient) {
2673
2657
  ctx.addIssue({
2674
2658
  code: z.ZodIssueCode.custom,
2675
- message: "can not have both searchClient and tina. Must use one or the other",
2659
+ message: "Cannot have both `searchClient` and `tina`. Must use one or the other.",
2676
2660
  fatal: true,
2677
2661
  path: ["config", "search"]
2678
2662
  });
@@ -2690,7 +2674,7 @@ const validateSchema = ({ schema }) => {
2690
2674
  } catch (e) {
2691
2675
  if (e instanceof ZodError) {
2692
2676
  const errors = parseZodError({ zodError: e });
2693
- throw new TinaSchemaValidationError(errors.join(", \n"));
2677
+ throw new TinaSchemaValidationError(errors.join("\n"));
2694
2678
  }
2695
2679
  throw new Error(e);
2696
2680
  }
@@ -1,4 +1,4 @@
1
- import type { Schema, Collection, Template, Collectable, CollectionTemplateable, TinaField } from '../types/index';
1
+ import type { Schema, Collection, Template, Collectable, CollectionTemplateable } from '../types/index';
2
2
  type Version = {
3
3
  fullVersion: string;
4
4
  major: string;
@@ -28,10 +28,7 @@ export declare class TinaSchema {
28
28
  } & Schema);
29
29
  getIsTitleFieldName: (collection: string) => string;
30
30
  getCollectionsByName: (collectionNames: string[]) => Collection<true>[];
31
- findReferences(name: string): Record<string, {
32
- path: string[];
33
- field: TinaField;
34
- }[]>;
31
+ findReferencesFromCollection(name: string): Record<string, string[]>;
35
32
  getCollection: (collectionName: string) => Collection<true>;
36
33
  getCollections: () => Collection<true>[];
37
34
  getCollectionByFullPath: (filepath: string) => Collection<true>;
@@ -63,11 +60,12 @@ export declare class TinaSchema {
63
60
  *
64
61
  */
65
62
  getTemplatesForCollectable: (collection: Collectable) => CollectionTemplateable;
66
- walkFields: (cb: (args: {
67
- field: TinaField;
68
- collection: Collection;
69
- path: string[];
70
- }) => void) => void;
63
+ walkFields(cb: (args: {
64
+ field: any;
65
+ collection: any;
66
+ path: string;
67
+ isListItem?: boolean;
68
+ }) => void): void;
71
69
  /**
72
70
  * This function returns an array of glob matches for a given collection.
73
71
  *
@@ -1,4 +1,8 @@
1
- /**
2
-
3
- */
4
- export declare function addNamespaceToSchema<T extends object | string>(maybeNode: T, namespace?: string[]): T;
1
+ type Node = {
2
+ name?: string;
3
+ value?: string;
4
+ namespace?: string[];
5
+ [key: string]: any;
6
+ };
7
+ export declare function addNamespaceToSchema<T extends Node | string>(maybeNode: T, namespace?: string[]): T;
8
+ export {};
@@ -198,8 +198,14 @@ export type RichTextField<WithNamespace extends boolean = false> = (FieldGeneric
198
198
  * will be stored as frontmatter
199
199
  */
200
200
  isBody?: boolean;
201
+ /**@deprecated use overrides.toolbar */
201
202
  toolbarOverride?: ToolbarOverrideType[];
202
203
  templates?: RichTextTemplate<WithNamespace>[];
204
+ overrides?: {
205
+ toolbar?: ToolbarOverrideType[];
206
+ /**Default set to true */
207
+ showFloatingToolbar?: boolean;
208
+ };
203
209
  /**
204
210
  * By default, Tina parses markdown with MDX, this is a more strict parser
205
211
  * that allows you to use structured content inside markdown (via `templates`).
@@ -1,6 +1,3 @@
1
- /**
2
-
3
- */
4
1
  import { z } from 'zod';
5
2
  import type { TinaField as TinaFieldType } from '../types/index';
6
3
  export declare const TinaFieldZod: z.ZodType<TinaFieldType>;
@@ -1,6 +1,3 @@
1
- /**
2
-
3
- */
4
1
  import { z } from 'zod';
5
2
  export declare const CollectionBaseSchema: z.ZodObject<{
6
3
  label: z.ZodOptional<z.ZodString>;
@@ -0,0 +1,3 @@
1
+ export declare const duplicateFieldErrorMessage: (fields: string) => string;
2
+ export declare const duplicateTemplateErrorMessage: (templates: string) => string;
3
+ export declare const duplicateCollectionErrorMessage: (collection: string) => string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tinacms/schema-tools",
3
- "version": "0.0.0-d524599-20241117111320",
3
+ "version": "0.0.0-d9672bc-20250218033222",
4
4
  "main": "dist/index.js",
5
5
  "module": "./dist/index.mjs",
6
6
  "exports": {
@@ -32,7 +32,7 @@
32
32
  "ts-jest": "^29.2.5",
33
33
  "typescript": "^5.6.3",
34
34
  "yup": "^0.32.11",
35
- "@tinacms/scripts": "0.0.0-d524599-20241117111320"
35
+ "@tinacms/scripts": "1.3.1"
36
36
  },
37
37
  "peerDependencies": {
38
38
  "react": ">=16.14.0",