@tinacms/schema-tools 0.0.9 → 0.1.2

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.es.js CHANGED
@@ -7,6 +7,9 @@ function addNamespaceToSchema(maybeNode, namespace = []) {
7
7
  if (typeof maybeNode === "boolean") {
8
8
  return maybeNode;
9
9
  }
10
+ if (typeof maybeNode === "function") {
11
+ return maybeNode;
12
+ }
10
13
  const newNode = { ...maybeNode };
11
14
  const keys = Object.keys(maybeNode);
12
15
  Object.values(maybeNode).map((m, index) => {
@@ -102,12 +105,14 @@ const NAMER = {
102
105
  return generateNamespacedFieldName(namespace, "ConnectionEdges");
103
106
  }
104
107
  };
105
- function hasDuplicates(array) {
106
- if (!array) {
107
- return false;
108
- } else {
109
- return new Set(array).size !== array.length;
110
- }
108
+ function findDuplicates(array = []) {
109
+ const duplicates = [
110
+ ...new Set(array.filter((item, index) => array.indexOf(item) !== index))
111
+ ].map((x) => `"${x}"`);
112
+ if (duplicates.length) {
113
+ return duplicates.join(", ");
114
+ } else
115
+ return void 0;
111
116
  }
112
117
  class TinaSchema {
113
118
  constructor(config) {
@@ -169,12 +174,7 @@ class TinaSchema {
169
174
  };
170
175
  this.getCollectionAndTemplateByFullPath = (filepath, templateName) => {
171
176
  let template;
172
- const collection = this.getCollections().find((collection2) => {
173
- return filepath.replace("\\", "/").startsWith(collection2.path);
174
- });
175
- if (!collection) {
176
- throw new Error(`Unable to find collection for file at ${filepath}`);
177
- }
177
+ const collection = this.getCollectionByFullPath(filepath);
178
178
  const templates = this.getTemplatesForCollectable(collection);
179
179
  if (templates.type === "union") {
180
180
  if (templateName) {
@@ -374,6 +374,7 @@ const resolveField = ({ namespace, ...field }, schema) => {
374
374
  key: templateName,
375
375
  inline: template.inline,
376
376
  name: templateName,
377
+ match: template.match,
377
378
  fields: template.fields.map((field2) => resolveField(field2, schema)),
378
379
  ...extraFields2
379
380
  };
@@ -437,7 +438,9 @@ const parseZodError = ({ zodError }) => {
437
438
  const name = z.string({
438
439
  required_error: "Name is required but not provided",
439
440
  invalid_type_error: "Name must be a string"
440
- });
441
+ }).refine((val) => val.match(/^[a-zA-Z0-9_]*$/) !== null, (val) => ({
442
+ message: `name, "${val}" must be alphanumeric and can only contain underscores`
443
+ }));
441
444
  const TypeName = [
442
445
  "string",
443
446
  "boolean",
@@ -456,7 +459,7 @@ const nameProp = z.string({
456
459
  }).superRefine((val, ctx) => {
457
460
  if (val.includes(" "))
458
461
  ctx.addIssue({
459
- message: "name cannot contain spaces",
462
+ message: `name "${val}" cannot contain spaces`,
460
463
  code: z.ZodIssueCode.custom,
461
464
  fatal: true
462
465
  });
@@ -521,23 +524,42 @@ const TinaFieldZod = z.lazy(() => {
521
524
  const TemplateTemp = z.object({
522
525
  label: z.string(),
523
526
  name: nameProp,
524
- fields: z.array(TinaFieldZod)
525
- }).refine((val) => {
526
- var _a;
527
- return !hasDuplicates((_a = val.fields) == null ? void 0 : _a.map((x) => x.name));
528
- }, {
529
- message: "Fields must have a unique name"
527
+ fields: z.array(TinaFieldZod),
528
+ match: z.object({
529
+ start: z.string(),
530
+ end: z.string()
531
+ }).optional()
532
+ }).superRefine((val, ctx) => {
533
+ const dups = findDuplicates(val == null ? void 0 : val.fields.map((x) => x.name));
534
+ if (dups) {
535
+ ctx.addIssue({
536
+ code: z.ZodIssueCode.custom,
537
+ message: `Fields must have a unique name, duplicate field names: ${dups}`
538
+ });
539
+ }
530
540
  });
531
541
  const ObjectField = FieldWithList.extend({
532
542
  type: z.literal("object", {
533
543
  invalid_type_error: typeTypeError,
534
544
  required_error: typeRequiredError
535
545
  }),
536
- fields: z.array(TinaFieldZod).min(1).optional().refine((val) => !hasDuplicates(val == null ? void 0 : val.map((x) => x.name)), {
537
- message: "Fields must have a unique name"
546
+ fields: z.array(TinaFieldZod).min(1).optional().superRefine((val, ctx) => {
547
+ const dups = findDuplicates(val == null ? void 0 : val.map((x) => x.name));
548
+ if (dups) {
549
+ ctx.addIssue({
550
+ code: z.ZodIssueCode.custom,
551
+ message: `Fields must have a unique name, duplicate field names: ${dups}`
552
+ });
553
+ }
538
554
  }),
539
- templates: z.array(TemplateTemp).min(1).optional().refine((val) => !hasDuplicates(val == null ? void 0 : val.map((x) => x.name)), {
540
- message: "Templates must have a unique name"
555
+ templates: z.array(TemplateTemp).min(1).optional().superRefine((val, ctx) => {
556
+ const dups = findDuplicates(val == null ? void 0 : val.map((x) => x.name));
557
+ if (dups) {
558
+ ctx.addIssue({
559
+ code: z.ZodIssueCode.custom,
560
+ message: `Templates must have a unique name, duplicate template names: ${dups}`
561
+ });
562
+ }
541
563
  })
542
564
  });
543
565
  const RichTextField = FieldWithList.extend({
@@ -545,8 +567,14 @@ const TinaFieldZod = z.lazy(() => {
545
567
  invalid_type_error: typeTypeError,
546
568
  required_error: typeRequiredError
547
569
  }),
548
- templates: z.array(TemplateTemp).optional().refine((val) => !hasDuplicates(val == null ? void 0 : val.map((x) => x.name)), {
549
- message: "Templates must have a unique name"
570
+ templates: z.array(TemplateTemp).optional().superRefine((val, ctx) => {
571
+ const dups = findDuplicates(val == null ? void 0 : val.map((x) => x.name));
572
+ if (dups) {
573
+ ctx.addIssue({
574
+ code: z.ZodIssueCode.custom,
575
+ message: `Templates must have a unique name, duplicate template names: ${dups}`
576
+ });
577
+ }
550
578
  })
551
579
  });
552
580
  return z.discriminatedUnion("type", [
@@ -576,13 +604,17 @@ const TinaFieldZod = z.lazy(() => {
576
604
  if (val.list) {
577
605
  ctx.addIssue({
578
606
  code: z.ZodIssueCode.custom,
579
- message: "You can not have `list: true` when using `isTitle`"
607
+ message: `Can not have \`list: true\` when using \`isTitle\`. Error in value
608
+ ${JSON.stringify(val, null, 2)}
609
+ `
580
610
  });
581
611
  }
582
612
  if (!val.required) {
583
613
  ctx.addIssue({
584
614
  code: z.ZodIssueCode.custom,
585
- message: "You must have { required: true } when using `isTitle`"
615
+ message: `Must have { required: true } when using \`isTitle\` Error in value
616
+ ${JSON.stringify(val, null, 2)}
617
+ `
586
618
  });
587
619
  }
588
620
  }
@@ -633,11 +665,15 @@ const Template = z.object({
633
665
  }),
634
666
  name,
635
667
  fields: z.array(TinaFieldZod)
636
- }).refine((val) => {
668
+ }).superRefine((val, ctx) => {
637
669
  var _a;
638
- return !hasDuplicates((_a = val.fields) == null ? void 0 : _a.map((x) => x.name));
639
- }, {
640
- message: "Fields must have a unique name"
670
+ const dups = findDuplicates((_a = val.fields) == null ? void 0 : _a.map((x) => x.name));
671
+ if (dups) {
672
+ ctx.addIssue({
673
+ code: z.ZodIssueCode.custom,
674
+ message: `Fields must have a unique name, duplicate field names: ${dups}`
675
+ });
676
+ }
641
677
  });
642
678
  const TinaCloudCollectionBase = z.object({
643
679
  label: z.string().optional(),
@@ -645,16 +681,28 @@ const TinaCloudCollectionBase = z.object({
645
681
  format: z.enum(FORMATS).optional()
646
682
  });
647
683
  const TinaCloudCollection = TinaCloudCollectionBase.extend({
648
- fields: z.array(TinaFieldZod).min(1).optional().refine((val) => !hasDuplicates(val == null ? void 0 : val.map((x) => x.name)), {
649
- message: "Fields must have a unique name"
684
+ fields: z.array(TinaFieldZod).min(1).optional().superRefine((val, ctx) => {
685
+ const dups = findDuplicates(val == null ? void 0 : val.map((x) => x.name));
686
+ if (dups) {
687
+ ctx.addIssue({
688
+ code: z.ZodIssueCode.custom,
689
+ message: `Fields must have a unique name, duplicate field names: ${dups}`
690
+ });
691
+ }
650
692
  }).refine((val) => {
651
693
  const arr = (val == null ? void 0 : val.filter((x) => x.type === "string" && x.isTitle)) || [];
652
694
  return arr.length < 2;
653
695
  }, {
654
696
  message: "Fields can only have one use of `isTitle`"
655
697
  }),
656
- templates: z.array(Template).min(1).optional().refine((val) => !hasDuplicates(val == null ? void 0 : val.map((x) => x.name)), {
657
- message: "Templates must have a unique name"
698
+ templates: z.array(Template).min(1).optional().superRefine((val, ctx) => {
699
+ const dups = findDuplicates(val == null ? void 0 : val.map((x) => x.name));
700
+ if (dups) {
701
+ ctx.addIssue({
702
+ code: z.ZodIssueCode.custom,
703
+ message: `Templates must have a unique name, duplicate template names: ${dups}`
704
+ });
705
+ }
658
706
  })
659
707
  }).refine((val) => {
660
708
  let isValid = Boolean(val == null ? void 0 : val.templates) || Boolean(val == null ? void 0 : val.fields);
@@ -669,20 +717,21 @@ const TinaCloudSchemaZod = z.object({
669
717
  collections: z.array(TinaCloudCollection),
670
718
  config: tinaConfigZod.optional()
671
719
  }).superRefine((val, ctx) => {
672
- var _a, _b;
673
- if (hasDuplicates(val.collections.map((x) => x.name))) {
720
+ var _a, _b, _c;
721
+ const dups = findDuplicates((_a = val.collections) == null ? void 0 : _a.map((x) => x.name));
722
+ if (dups) {
674
723
  ctx.addIssue({
675
724
  code: z.ZodIssueCode.custom,
676
- message: "can not have two collections with the same name",
725
+ message: `${dups} are duplicate names in your collections. Collection names must be unique.`,
677
726
  fatal: true
678
727
  });
679
728
  }
680
- (_a = val == null ? void 0 : val.collections) == null ? void 0 : _a.map((x) => {
729
+ (_b = val == null ? void 0 : val.collections) == null ? void 0 : _b.map((x) => {
681
730
  if (!x.format) {
682
731
  console.warn(`No format provided for collection ${x.name}, defaulting to .md`);
683
732
  }
684
733
  });
685
- const media = (_b = val == null ? void 0 : val.config) == null ? void 0 : _b.media;
734
+ const media = (_c = val == null ? void 0 : val.config) == null ? void 0 : _c.media;
686
735
  if (media && media.tina && media.loadCustomStore) {
687
736
  ctx.addIssue({
688
737
  code: z.ZodIssueCode.custom,
package/dist/index.js CHANGED
@@ -34,6 +34,9 @@
34
34
  if (typeof maybeNode === "boolean") {
35
35
  return maybeNode;
36
36
  }
37
+ if (typeof maybeNode === "function") {
38
+ return maybeNode;
39
+ }
37
40
  const newNode = { ...maybeNode };
38
41
  const keys = Object.keys(maybeNode);
39
42
  Object.values(maybeNode).map((m, index) => {
@@ -129,12 +132,14 @@
129
132
  return generateNamespacedFieldName(namespace, "ConnectionEdges");
130
133
  }
131
134
  };
132
- function hasDuplicates(array) {
133
- if (!array) {
134
- return false;
135
- } else {
136
- return new Set(array).size !== array.length;
137
- }
135
+ function findDuplicates(array = []) {
136
+ const duplicates = [
137
+ ...new Set(array.filter((item, index) => array.indexOf(item) !== index))
138
+ ].map((x) => `"${x}"`);
139
+ if (duplicates.length) {
140
+ return duplicates.join(", ");
141
+ } else
142
+ return void 0;
138
143
  }
139
144
  class TinaSchema {
140
145
  constructor(config) {
@@ -196,12 +201,7 @@
196
201
  };
197
202
  this.getCollectionAndTemplateByFullPath = (filepath, templateName) => {
198
203
  let template;
199
- const collection = this.getCollections().find((collection2) => {
200
- return filepath.replace("\\", "/").startsWith(collection2.path);
201
- });
202
- if (!collection) {
203
- throw new Error(`Unable to find collection for file at ${filepath}`);
204
- }
204
+ const collection = this.getCollectionByFullPath(filepath);
205
205
  const templates = this.getTemplatesForCollectable(collection);
206
206
  if (templates.type === "union") {
207
207
  if (templateName) {
@@ -401,6 +401,7 @@
401
401
  key: templateName,
402
402
  inline: template.inline,
403
403
  name: templateName,
404
+ match: template.match,
404
405
  fields: template.fields.map((field2) => resolveField(field2, schema)),
405
406
  ...extraFields2
406
407
  };
@@ -464,7 +465,9 @@
464
465
  const name = z.z.string({
465
466
  required_error: "Name is required but not provided",
466
467
  invalid_type_error: "Name must be a string"
467
- });
468
+ }).refine((val) => val.match(/^[a-zA-Z0-9_]*$/) !== null, (val) => ({
469
+ message: `name, "${val}" must be alphanumeric and can only contain underscores`
470
+ }));
468
471
  const TypeName = [
469
472
  "string",
470
473
  "boolean",
@@ -483,7 +486,7 @@
483
486
  }).superRefine((val, ctx) => {
484
487
  if (val.includes(" "))
485
488
  ctx.addIssue({
486
- message: "name cannot contain spaces",
489
+ message: `name "${val}" cannot contain spaces`,
487
490
  code: z.z.ZodIssueCode.custom,
488
491
  fatal: true
489
492
  });
@@ -548,23 +551,42 @@
548
551
  const TemplateTemp = z.z.object({
549
552
  label: z.z.string(),
550
553
  name: nameProp,
551
- fields: z.z.array(TinaFieldZod)
552
- }).refine((val) => {
553
- var _a;
554
- return !hasDuplicates((_a = val.fields) == null ? void 0 : _a.map((x) => x.name));
555
- }, {
556
- message: "Fields must have a unique name"
554
+ fields: z.z.array(TinaFieldZod),
555
+ match: z.z.object({
556
+ start: z.z.string(),
557
+ end: z.z.string()
558
+ }).optional()
559
+ }).superRefine((val, ctx) => {
560
+ const dups = findDuplicates(val == null ? void 0 : val.fields.map((x) => x.name));
561
+ if (dups) {
562
+ ctx.addIssue({
563
+ code: z.z.ZodIssueCode.custom,
564
+ message: `Fields must have a unique name, duplicate field names: ${dups}`
565
+ });
566
+ }
557
567
  });
558
568
  const ObjectField = FieldWithList.extend({
559
569
  type: z.z.literal("object", {
560
570
  invalid_type_error: typeTypeError,
561
571
  required_error: typeRequiredError
562
572
  }),
563
- fields: z.z.array(TinaFieldZod).min(1).optional().refine((val) => !hasDuplicates(val == null ? void 0 : val.map((x) => x.name)), {
564
- message: "Fields must have a unique name"
573
+ fields: z.z.array(TinaFieldZod).min(1).optional().superRefine((val, ctx) => {
574
+ const dups = findDuplicates(val == null ? void 0 : val.map((x) => x.name));
575
+ if (dups) {
576
+ ctx.addIssue({
577
+ code: z.z.ZodIssueCode.custom,
578
+ message: `Fields must have a unique name, duplicate field names: ${dups}`
579
+ });
580
+ }
565
581
  }),
566
- templates: z.z.array(TemplateTemp).min(1).optional().refine((val) => !hasDuplicates(val == null ? void 0 : val.map((x) => x.name)), {
567
- message: "Templates must have a unique name"
582
+ templates: z.z.array(TemplateTemp).min(1).optional().superRefine((val, ctx) => {
583
+ const dups = findDuplicates(val == null ? void 0 : val.map((x) => x.name));
584
+ if (dups) {
585
+ ctx.addIssue({
586
+ code: z.z.ZodIssueCode.custom,
587
+ message: `Templates must have a unique name, duplicate template names: ${dups}`
588
+ });
589
+ }
568
590
  })
569
591
  });
570
592
  const RichTextField = FieldWithList.extend({
@@ -572,8 +594,14 @@
572
594
  invalid_type_error: typeTypeError,
573
595
  required_error: typeRequiredError
574
596
  }),
575
- templates: z.z.array(TemplateTemp).optional().refine((val) => !hasDuplicates(val == null ? void 0 : val.map((x) => x.name)), {
576
- message: "Templates must have a unique name"
597
+ templates: z.z.array(TemplateTemp).optional().superRefine((val, ctx) => {
598
+ const dups = findDuplicates(val == null ? void 0 : val.map((x) => x.name));
599
+ if (dups) {
600
+ ctx.addIssue({
601
+ code: z.z.ZodIssueCode.custom,
602
+ message: `Templates must have a unique name, duplicate template names: ${dups}`
603
+ });
604
+ }
577
605
  })
578
606
  });
579
607
  return z.z.discriminatedUnion("type", [
@@ -603,13 +631,17 @@
603
631
  if (val.list) {
604
632
  ctx.addIssue({
605
633
  code: z.z.ZodIssueCode.custom,
606
- message: "You can not have `list: true` when using `isTitle`"
634
+ message: `Can not have \`list: true\` when using \`isTitle\`. Error in value
635
+ ${JSON.stringify(val, null, 2)}
636
+ `
607
637
  });
608
638
  }
609
639
  if (!val.required) {
610
640
  ctx.addIssue({
611
641
  code: z.z.ZodIssueCode.custom,
612
- message: "You must have { required: true } when using `isTitle`"
642
+ message: `Must have { required: true } when using \`isTitle\` Error in value
643
+ ${JSON.stringify(val, null, 2)}
644
+ `
613
645
  });
614
646
  }
615
647
  }
@@ -660,11 +692,15 @@
660
692
  }),
661
693
  name,
662
694
  fields: z.z.array(TinaFieldZod)
663
- }).refine((val) => {
695
+ }).superRefine((val, ctx) => {
664
696
  var _a;
665
- return !hasDuplicates((_a = val.fields) == null ? void 0 : _a.map((x) => x.name));
666
- }, {
667
- message: "Fields must have a unique name"
697
+ const dups = findDuplicates((_a = val.fields) == null ? void 0 : _a.map((x) => x.name));
698
+ if (dups) {
699
+ ctx.addIssue({
700
+ code: z.z.ZodIssueCode.custom,
701
+ message: `Fields must have a unique name, duplicate field names: ${dups}`
702
+ });
703
+ }
668
704
  });
669
705
  const TinaCloudCollectionBase = z.z.object({
670
706
  label: z.z.string().optional(),
@@ -672,16 +708,28 @@
672
708
  format: z.z.enum(FORMATS).optional()
673
709
  });
674
710
  const TinaCloudCollection = TinaCloudCollectionBase.extend({
675
- fields: z.z.array(TinaFieldZod).min(1).optional().refine((val) => !hasDuplicates(val == null ? void 0 : val.map((x) => x.name)), {
676
- message: "Fields must have a unique name"
711
+ fields: z.z.array(TinaFieldZod).min(1).optional().superRefine((val, ctx) => {
712
+ const dups = findDuplicates(val == null ? void 0 : val.map((x) => x.name));
713
+ if (dups) {
714
+ ctx.addIssue({
715
+ code: z.z.ZodIssueCode.custom,
716
+ message: `Fields must have a unique name, duplicate field names: ${dups}`
717
+ });
718
+ }
677
719
  }).refine((val) => {
678
720
  const arr = (val == null ? void 0 : val.filter((x) => x.type === "string" && x.isTitle)) || [];
679
721
  return arr.length < 2;
680
722
  }, {
681
723
  message: "Fields can only have one use of `isTitle`"
682
724
  }),
683
- templates: z.z.array(Template).min(1).optional().refine((val) => !hasDuplicates(val == null ? void 0 : val.map((x) => x.name)), {
684
- message: "Templates must have a unique name"
725
+ templates: z.z.array(Template).min(1).optional().superRefine((val, ctx) => {
726
+ const dups = findDuplicates(val == null ? void 0 : val.map((x) => x.name));
727
+ if (dups) {
728
+ ctx.addIssue({
729
+ code: z.z.ZodIssueCode.custom,
730
+ message: `Templates must have a unique name, duplicate template names: ${dups}`
731
+ });
732
+ }
685
733
  })
686
734
  }).refine((val) => {
687
735
  let isValid = Boolean(val == null ? void 0 : val.templates) || Boolean(val == null ? void 0 : val.fields);
@@ -696,20 +744,21 @@
696
744
  collections: z.z.array(TinaCloudCollection),
697
745
  config: tinaConfigZod.optional()
698
746
  }).superRefine((val, ctx) => {
699
- var _a, _b;
700
- if (hasDuplicates(val.collections.map((x) => x.name))) {
747
+ var _a, _b, _c;
748
+ const dups = findDuplicates((_a = val.collections) == null ? void 0 : _a.map((x) => x.name));
749
+ if (dups) {
701
750
  ctx.addIssue({
702
751
  code: z.z.ZodIssueCode.custom,
703
- message: "can not have two collections with the same name",
752
+ message: `${dups} are duplicate names in your collections. Collection names must be unique.`,
704
753
  fatal: true
705
754
  });
706
755
  }
707
- (_a = val == null ? void 0 : val.collections) == null ? void 0 : _a.map((x) => {
756
+ (_b = val == null ? void 0 : val.collections) == null ? void 0 : _b.map((x) => {
708
757
  if (!x.format) {
709
758
  console.warn(`No format provided for collection ${x.name}, defaulting to .md`);
710
759
  }
711
760
  });
712
- const media = (_b = val == null ? void 0 : val.config) == null ? void 0 : _b.media;
761
+ const media = (_c = val == null ? void 0 : val.config) == null ? void 0 : _c.media;
713
762
  if (media && media.tina && media.loadCustomStore) {
714
763
  ctx.addIssue({
715
764
  code: z.z.ZodIssueCode.custom,
@@ -10,8 +10,9 @@ 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 { TinaSchema } from '../schema';
14
13
  import type { FC } from 'react';
14
+ import { TinaSchema } from '../schema';
15
+ import type { TinaCloudSchemaConfig } from './config';
15
16
  export declare type UIField<F extends UIField = any, Shape = any> = {
16
17
  label?: string;
17
18
  description?: string;
@@ -21,21 +22,6 @@ export declare type UIField<F extends UIField = any, Shape = any> = {
21
22
  validate?(value: Shape, allValues: any, meta: any, field: UIField<F, Shape>): string | object | undefined | void;
22
23
  defaultValue?: Shape;
23
24
  };
24
- export interface TinaCloudSchemaConfig<Store = any> {
25
- client?: {
26
- referenceDepth?: number;
27
- };
28
- clientId: string;
29
- branch: string;
30
- token: string;
31
- media?: {
32
- loadCustomStore?: () => Promise<Store>;
33
- tina?: {
34
- publicFolder: string;
35
- mediaRoot: string;
36
- };
37
- };
38
- }
39
25
  export interface TinaCloudSchema<WithNamespace extends boolean, Store = any> {
40
26
  templates?: GlobalTemplate<WithNamespace>[];
41
27
  collections: TinaCloudCollection<WithNamespace>[];
@@ -58,11 +44,46 @@ export declare type TinaCloudCollection<WithNamespace extends boolean> = Collect
58
44
  export declare type TinaCloudCollectionBase = TinaCloudCollection<false>;
59
45
  export declare type TinaCloudCollectionEnriched = TinaCloudCollection<true>;
60
46
  declare type FormatType = 'json' | 'md' | 'markdown' | 'mdx';
47
+ declare type Document = {
48
+ _sys: {
49
+ title?: string;
50
+ template: string;
51
+ breadcrumbs: string[];
52
+ path: string;
53
+ basename: string;
54
+ relativePath: string;
55
+ filename: string;
56
+ extension: string;
57
+ };
58
+ };
61
59
  interface BaseCollection {
62
60
  label?: string;
63
61
  name: string;
64
62
  path: string;
65
63
  format?: FormatType;
64
+ ui?: {
65
+ /**
66
+ * Forms for this collection will be editable from the global sidebar rather than the form panel
67
+ */
68
+ global?: boolean | {
69
+ icon?: any;
70
+ layout: 'fullscreen' | 'popup';
71
+ };
72
+ /**
73
+ * Provide the path that your document is viewable on your site
74
+ *
75
+ * eg:
76
+ * ```ts
77
+ * router: ({ document }) => {
78
+ * return `blog-posts/${document._sys.filename}`;
79
+ * }
80
+ * ```
81
+ */
82
+ router?: (args: {
83
+ document: Document;
84
+ collection: TinaCloudCollection<true>;
85
+ }) => string | undefined;
86
+ };
66
87
  match?: string;
67
88
  }
68
89
  declare type CollectionTemplates<WithNamespace extends boolean> = WithNamespace extends true ? CollectionTemplatesWithNamespace<WithNamespace> : CollectionTemplatesInner<WithNamespace>;
@@ -323,6 +344,10 @@ export declare type Template<WithNamespace extends boolean> = WithNamespace exte
323
344
  label: string;
324
345
  name: string;
325
346
  fields: TinaFieldInner<WithNamespace>[];
347
+ match?: {
348
+ start: string;
349
+ end: string;
350
+ };
326
351
  ui?: object | (UIField<any, any> & {
327
352
  previewSrc: string;
328
353
  });
@@ -334,6 +359,10 @@ export declare type Template<WithNamespace extends boolean> = WithNamespace exte
334
359
  previewSrc: string;
335
360
  });
336
361
  fields: TinaFieldInner<WithNamespace>[];
362
+ match?: {
363
+ start: string;
364
+ end: string;
365
+ };
337
366
  };
338
367
  export declare type CollectionTemplateableUnion = {
339
368
  namespace: string[];
@@ -366,4 +395,4 @@ export declare type ResolveFormArgs = {
366
395
  template: Templateable;
367
396
  schema: TinaSchema;
368
397
  };
369
- export {};
398
+ export * from './config';
@@ -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
+ export interface TinaCloudSchemaConfig<Store = any> {
14
+ client?: {
15
+ referenceDepth?: number;
16
+ };
17
+ build?: {
18
+ publicFolder: string;
19
+ outputFolder: string;
20
+ };
21
+ /**
22
+ * The base branch to pull content from. Note that this is ignored for local development
23
+ */
24
+ branch?: string;
25
+ /**
26
+ * Your clientId from app.tina.io
27
+ */
28
+ clientId?: string;
29
+ /**
30
+ * Your read only token from app.tina.io
31
+ */
32
+ token?: string;
33
+ media?: {
34
+ loadCustomStore?: () => Promise<Store>;
35
+ tina?: {
36
+ publicFolder: string;
37
+ mediaRoot: string;
38
+ };
39
+ };
40
+ }
@@ -10,4 +10,10 @@ 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
- export declare function hasDuplicates<T = any>(array: T[]): boolean;
13
+ export declare function hasDuplicates<T = any>(array?: T[]): boolean;
14
+ /**
15
+ *
16
+ * @param array
17
+ * @returns False if the array is undefined or has no duplicates.
18
+ */
19
+ export declare function findDuplicates<T = any>(array?: T[] | undefined): undefined | string;
@@ -11,4 +11,4 @@ See the License for the specific language governing permissions and
11
11
  limitations under the License.
12
12
  */
13
13
  import { z } from 'zod';
14
- export declare const name: z.ZodString;
14
+ export declare const name: z.ZodEffects<z.ZodString, string, string>;
@@ -14,13 +14,13 @@ import { z } from 'zod';
14
14
  export declare const TinaCloudSchemaZod: z.ZodEffects<z.ZodObject<{
15
15
  collections: z.ZodArray<z.ZodEffects<z.ZodObject<z.extendShape<{
16
16
  label: z.ZodOptional<z.ZodString>;
17
- name: z.ZodString;
17
+ name: z.ZodEffects<z.ZodString, string, string>;
18
18
  format: z.ZodOptional<z.ZodEnum<["json", "md", "markdown", "mdx"]>>;
19
19
  }, {
20
20
  fields: z.ZodEffects<z.ZodEffects<z.ZodOptional<z.ZodArray<z.ZodType<import("..").TinaFieldInner<false>, z.ZodTypeDef, import("..").TinaFieldInner<false>>, "many">>, import("..").TinaFieldInner<false>[], import("..").TinaFieldInner<false>[]>, import("..").TinaFieldInner<false>[], import("..").TinaFieldInner<false>[]>;
21
21
  templates: z.ZodEffects<z.ZodOptional<z.ZodArray<z.ZodEffects<z.ZodObject<{
22
22
  label: z.ZodString;
23
- name: z.ZodString;
23
+ name: z.ZodEffects<z.ZodString, string, string>;
24
24
  fields: z.ZodArray<z.ZodType<import("..").TinaFieldInner<false>, z.ZodTypeDef, import("..").TinaFieldInner<false>>, "many">;
25
25
  }, "strip", z.ZodTypeAny, {
26
26
  name?: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tinacms/schema-tools",
3
- "version": "0.0.9",
3
+ "version": "0.1.2",
4
4
  "main": "dist/index.js",
5
5
  "module": "./dist/index.es.js",
6
6
  "exports": {
@@ -23,7 +23,7 @@
23
23
  ]
24
24
  },
25
25
  "devDependencies": {
26
- "@tinacms/scripts": "0.50.9",
26
+ "@tinacms/scripts": "0.51.1",
27
27
  "@types/yup": "^0.29.10",
28
28
  "jest": "^27.0.6",
29
29
  "react": "17.0.2",