@tinacms/schema-tools 0.1.0 → 0.1.3
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 +1 -0
- package/dist/index.es.js +157 -48
- package/dist/index.js +157 -47
- package/dist/schema/TinaSchema.d.ts +7 -0
- package/dist/schema/resolveField.d.ts +6 -1
- package/dist/schema/resolveForm.d.ts +6 -1
- package/dist/types/SchemaTypes.d.ts +35 -0
- package/dist/types/SchemaTypes2.d.ts +101 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/schema2.d.ts +13 -0
- package/dist/util/hasDuplicates.d.ts +7 -1
- package/dist/validate/properties.d.ts +1 -1
- package/dist/validate/schema.d.ts +2 -2
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
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
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
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) {
|
|
@@ -160,7 +165,7 @@ class TinaSchema {
|
|
|
160
165
|
};
|
|
161
166
|
this.getCollectionByFullPath = (filepath) => {
|
|
162
167
|
const collection = this.getCollections().find((collection2) => {
|
|
163
|
-
return filepath.replace(
|
|
168
|
+
return filepath.replace(/\\/g, "/").startsWith(collection2.path.replace(/\/?$/, "/"));
|
|
164
169
|
});
|
|
165
170
|
if (!collection) {
|
|
166
171
|
throw new Error(`Unable to find collection for file at ${filepath}`);
|
|
@@ -169,12 +174,7 @@ class TinaSchema {
|
|
|
169
174
|
};
|
|
170
175
|
this.getCollectionAndTemplateByFullPath = (filepath, templateName) => {
|
|
171
176
|
let template;
|
|
172
|
-
const collection = this.
|
|
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) {
|
|
@@ -211,6 +211,72 @@ class TinaSchema {
|
|
|
211
211
|
return template;
|
|
212
212
|
}
|
|
213
213
|
};
|
|
214
|
+
this.transformPayload = (collectionName, payload) => {
|
|
215
|
+
const collection = this.getCollection(collectionName);
|
|
216
|
+
if (collection.templates) {
|
|
217
|
+
const template = collection.templates.find((template2) => {
|
|
218
|
+
if (typeof template2 === "string") {
|
|
219
|
+
throw new Error("Global templates not supported");
|
|
220
|
+
}
|
|
221
|
+
return payload["_template"] === template2.name;
|
|
222
|
+
});
|
|
223
|
+
if (!template) {
|
|
224
|
+
console.error(payload);
|
|
225
|
+
throw new Error(`Unable to find template for payload`);
|
|
226
|
+
}
|
|
227
|
+
if (typeof template === "string") {
|
|
228
|
+
throw new Error("Global templates not supported");
|
|
229
|
+
}
|
|
230
|
+
return {
|
|
231
|
+
[collectionName]: {
|
|
232
|
+
[template.name]: this.transformCollectablePayload(payload, template)
|
|
233
|
+
}
|
|
234
|
+
};
|
|
235
|
+
} else {
|
|
236
|
+
return {
|
|
237
|
+
[collectionName]: this.transformCollectablePayload(payload, collection)
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
};
|
|
241
|
+
this.transformCollectablePayload = (payload, collection) => {
|
|
242
|
+
const accumulator = {};
|
|
243
|
+
Object.entries(payload).forEach(([key, value]) => {
|
|
244
|
+
if (typeof collection.fields === "string") {
|
|
245
|
+
throw new Error("Global templates not supported");
|
|
246
|
+
}
|
|
247
|
+
const field = collection.fields.find((field2) => {
|
|
248
|
+
if (typeof field2 === "string") {
|
|
249
|
+
throw new Error("Global templates not supported");
|
|
250
|
+
}
|
|
251
|
+
return field2.name === key;
|
|
252
|
+
});
|
|
253
|
+
if (field) {
|
|
254
|
+
accumulator[key] = this.transformField(field, value);
|
|
255
|
+
}
|
|
256
|
+
});
|
|
257
|
+
return accumulator;
|
|
258
|
+
};
|
|
259
|
+
this.transformField = (field, value) => {
|
|
260
|
+
if (field.type === "object")
|
|
261
|
+
if (field.templates) {
|
|
262
|
+
if (field.list) {
|
|
263
|
+
assertShape(value, (yup2) => yup2.array(yup2.object({ _template: yup2.string().required() })));
|
|
264
|
+
return value.map((item) => {
|
|
265
|
+
const { _template, ...rest } = item;
|
|
266
|
+
return { [_template]: rest };
|
|
267
|
+
});
|
|
268
|
+
} else {
|
|
269
|
+
assertShape(value, (yup2) => yup2.object({ _template: yup2.string().required() }));
|
|
270
|
+
const { _template, ...rest } = value;
|
|
271
|
+
return { [_template]: rest };
|
|
272
|
+
}
|
|
273
|
+
} else {
|
|
274
|
+
return value;
|
|
275
|
+
}
|
|
276
|
+
else {
|
|
277
|
+
return value;
|
|
278
|
+
}
|
|
279
|
+
};
|
|
214
280
|
this.isMarkdownCollection = (collectionName) => {
|
|
215
281
|
const collection = this.getCollection(collectionName);
|
|
216
282
|
const format = collection.format;
|
|
@@ -261,9 +327,9 @@ class TinaSchema {
|
|
|
261
327
|
this.schema = config;
|
|
262
328
|
}
|
|
263
329
|
}
|
|
264
|
-
const resolveField = (
|
|
330
|
+
const resolveField = (field, schema) => {
|
|
265
331
|
var _a;
|
|
266
|
-
field.parentTypename = NAMER.dataTypeName(namespace.filter((_, i) => i < namespace.length - 1));
|
|
332
|
+
field.parentTypename = NAMER.dataTypeName(field.namespace.filter((_, i) => i < field.namespace.length - 1));
|
|
267
333
|
const extraFields = field.ui || {};
|
|
268
334
|
switch (field.type) {
|
|
269
335
|
case "number":
|
|
@@ -324,10 +390,7 @@ const resolveField = ({ namespace, ...field }, schema) => {
|
|
|
324
390
|
...extraFields
|
|
325
391
|
};
|
|
326
392
|
case "object":
|
|
327
|
-
const templateInfo = schema.getTemplatesForCollectable(
|
|
328
|
-
...field,
|
|
329
|
-
namespace
|
|
330
|
-
});
|
|
393
|
+
const templateInfo = schema.getTemplatesForCollectable(field);
|
|
331
394
|
if (templateInfo.type === "object") {
|
|
332
395
|
return {
|
|
333
396
|
...field,
|
|
@@ -345,6 +408,7 @@ const resolveField = ({ namespace, ...field }, schema) => {
|
|
|
345
408
|
templates2[lastItem(template.namespace)] = {
|
|
346
409
|
label: template.label || templateName,
|
|
347
410
|
key: templateName,
|
|
411
|
+
namespace: [...field.namespace, templateName],
|
|
348
412
|
fields: template.fields.map((field2) => resolveField(field2, schema)),
|
|
349
413
|
...extraFields2
|
|
350
414
|
};
|
|
@@ -353,6 +417,7 @@ const resolveField = ({ namespace, ...field }, schema) => {
|
|
|
353
417
|
return {
|
|
354
418
|
...field,
|
|
355
419
|
typeMap: typeMap2,
|
|
420
|
+
namespace: field.namespace,
|
|
356
421
|
component: field.list ? "blocks" : "not-implemented",
|
|
357
422
|
templates: templates2,
|
|
358
423
|
...extraFields
|
|
@@ -438,7 +503,9 @@ const parseZodError = ({ zodError }) => {
|
|
|
438
503
|
const name = z.string({
|
|
439
504
|
required_error: "Name is required but not provided",
|
|
440
505
|
invalid_type_error: "Name must be a string"
|
|
441
|
-
})
|
|
506
|
+
}).refine((val) => val.match(/^[a-zA-Z0-9_]*$/) !== null, (val) => ({
|
|
507
|
+
message: `name, "${val}" must be alphanumeric and can only contain underscores`
|
|
508
|
+
}));
|
|
442
509
|
const TypeName = [
|
|
443
510
|
"string",
|
|
444
511
|
"boolean",
|
|
@@ -457,7 +524,7 @@ const nameProp = z.string({
|
|
|
457
524
|
}).superRefine((val, ctx) => {
|
|
458
525
|
if (val.includes(" "))
|
|
459
526
|
ctx.addIssue({
|
|
460
|
-
message:
|
|
527
|
+
message: `name "${val}" cannot contain spaces`,
|
|
461
528
|
code: z.ZodIssueCode.custom,
|
|
462
529
|
fatal: true
|
|
463
530
|
});
|
|
@@ -527,22 +594,37 @@ const TinaFieldZod = z.lazy(() => {
|
|
|
527
594
|
start: z.string(),
|
|
528
595
|
end: z.string()
|
|
529
596
|
}).optional()
|
|
530
|
-
}).
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
597
|
+
}).superRefine((val, ctx) => {
|
|
598
|
+
const dups = findDuplicates(val == null ? void 0 : val.fields.map((x) => x.name));
|
|
599
|
+
if (dups) {
|
|
600
|
+
ctx.addIssue({
|
|
601
|
+
code: z.ZodIssueCode.custom,
|
|
602
|
+
message: `Fields must have a unique name, duplicate field names: ${dups}`
|
|
603
|
+
});
|
|
604
|
+
}
|
|
535
605
|
});
|
|
536
606
|
const ObjectField = FieldWithList.extend({
|
|
537
607
|
type: z.literal("object", {
|
|
538
608
|
invalid_type_error: typeTypeError,
|
|
539
609
|
required_error: typeRequiredError
|
|
540
610
|
}),
|
|
541
|
-
fields: z.array(TinaFieldZod).min(1).optional().
|
|
542
|
-
|
|
611
|
+
fields: z.array(TinaFieldZod).min(1).optional().superRefine((val, ctx) => {
|
|
612
|
+
const dups = findDuplicates(val == null ? void 0 : val.map((x) => x.name));
|
|
613
|
+
if (dups) {
|
|
614
|
+
ctx.addIssue({
|
|
615
|
+
code: z.ZodIssueCode.custom,
|
|
616
|
+
message: `Fields must have a unique name, duplicate field names: ${dups}`
|
|
617
|
+
});
|
|
618
|
+
}
|
|
543
619
|
}),
|
|
544
|
-
templates: z.array(TemplateTemp).min(1).optional().
|
|
545
|
-
|
|
620
|
+
templates: z.array(TemplateTemp).min(1).optional().superRefine((val, ctx) => {
|
|
621
|
+
const dups = findDuplicates(val == null ? void 0 : val.map((x) => x.name));
|
|
622
|
+
if (dups) {
|
|
623
|
+
ctx.addIssue({
|
|
624
|
+
code: z.ZodIssueCode.custom,
|
|
625
|
+
message: `Templates must have a unique name, duplicate template names: ${dups}`
|
|
626
|
+
});
|
|
627
|
+
}
|
|
546
628
|
})
|
|
547
629
|
});
|
|
548
630
|
const RichTextField = FieldWithList.extend({
|
|
@@ -550,8 +632,14 @@ const TinaFieldZod = z.lazy(() => {
|
|
|
550
632
|
invalid_type_error: typeTypeError,
|
|
551
633
|
required_error: typeRequiredError
|
|
552
634
|
}),
|
|
553
|
-
templates: z.array(TemplateTemp).optional().
|
|
554
|
-
|
|
635
|
+
templates: z.array(TemplateTemp).optional().superRefine((val, ctx) => {
|
|
636
|
+
const dups = findDuplicates(val == null ? void 0 : val.map((x) => x.name));
|
|
637
|
+
if (dups) {
|
|
638
|
+
ctx.addIssue({
|
|
639
|
+
code: z.ZodIssueCode.custom,
|
|
640
|
+
message: `Templates must have a unique name, duplicate template names: ${dups}`
|
|
641
|
+
});
|
|
642
|
+
}
|
|
555
643
|
})
|
|
556
644
|
});
|
|
557
645
|
return z.discriminatedUnion("type", [
|
|
@@ -581,13 +669,17 @@ const TinaFieldZod = z.lazy(() => {
|
|
|
581
669
|
if (val.list) {
|
|
582
670
|
ctx.addIssue({
|
|
583
671
|
code: z.ZodIssueCode.custom,
|
|
584
|
-
message:
|
|
672
|
+
message: `Can not have \`list: true\` when using \`isTitle\`. Error in value
|
|
673
|
+
${JSON.stringify(val, null, 2)}
|
|
674
|
+
`
|
|
585
675
|
});
|
|
586
676
|
}
|
|
587
677
|
if (!val.required) {
|
|
588
678
|
ctx.addIssue({
|
|
589
679
|
code: z.ZodIssueCode.custom,
|
|
590
|
-
message:
|
|
680
|
+
message: `Must have { required: true } when using \`isTitle\` Error in value
|
|
681
|
+
${JSON.stringify(val, null, 2)}
|
|
682
|
+
`
|
|
591
683
|
});
|
|
592
684
|
}
|
|
593
685
|
}
|
|
@@ -638,11 +730,15 @@ const Template = z.object({
|
|
|
638
730
|
}),
|
|
639
731
|
name,
|
|
640
732
|
fields: z.array(TinaFieldZod)
|
|
641
|
-
}).
|
|
733
|
+
}).superRefine((val, ctx) => {
|
|
642
734
|
var _a;
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
735
|
+
const dups = findDuplicates((_a = val.fields) == null ? void 0 : _a.map((x) => x.name));
|
|
736
|
+
if (dups) {
|
|
737
|
+
ctx.addIssue({
|
|
738
|
+
code: z.ZodIssueCode.custom,
|
|
739
|
+
message: `Fields must have a unique name, duplicate field names: ${dups}`
|
|
740
|
+
});
|
|
741
|
+
}
|
|
646
742
|
});
|
|
647
743
|
const TinaCloudCollectionBase = z.object({
|
|
648
744
|
label: z.string().optional(),
|
|
@@ -650,16 +746,28 @@ const TinaCloudCollectionBase = z.object({
|
|
|
650
746
|
format: z.enum(FORMATS).optional()
|
|
651
747
|
});
|
|
652
748
|
const TinaCloudCollection = TinaCloudCollectionBase.extend({
|
|
653
|
-
fields: z.array(TinaFieldZod).min(1).optional().
|
|
654
|
-
|
|
749
|
+
fields: z.array(TinaFieldZod).min(1).optional().superRefine((val, ctx) => {
|
|
750
|
+
const dups = findDuplicates(val == null ? void 0 : val.map((x) => x.name));
|
|
751
|
+
if (dups) {
|
|
752
|
+
ctx.addIssue({
|
|
753
|
+
code: z.ZodIssueCode.custom,
|
|
754
|
+
message: `Fields must have a unique name, duplicate field names: ${dups}`
|
|
755
|
+
});
|
|
756
|
+
}
|
|
655
757
|
}).refine((val) => {
|
|
656
758
|
const arr = (val == null ? void 0 : val.filter((x) => x.type === "string" && x.isTitle)) || [];
|
|
657
759
|
return arr.length < 2;
|
|
658
760
|
}, {
|
|
659
761
|
message: "Fields can only have one use of `isTitle`"
|
|
660
762
|
}),
|
|
661
|
-
templates: z.array(Template).min(1).optional().
|
|
662
|
-
|
|
763
|
+
templates: z.array(Template).min(1).optional().superRefine((val, ctx) => {
|
|
764
|
+
const dups = findDuplicates(val == null ? void 0 : val.map((x) => x.name));
|
|
765
|
+
if (dups) {
|
|
766
|
+
ctx.addIssue({
|
|
767
|
+
code: z.ZodIssueCode.custom,
|
|
768
|
+
message: `Templates must have a unique name, duplicate template names: ${dups}`
|
|
769
|
+
});
|
|
770
|
+
}
|
|
663
771
|
})
|
|
664
772
|
}).refine((val) => {
|
|
665
773
|
let isValid = Boolean(val == null ? void 0 : val.templates) || Boolean(val == null ? void 0 : val.fields);
|
|
@@ -674,20 +782,21 @@ const TinaCloudSchemaZod = z.object({
|
|
|
674
782
|
collections: z.array(TinaCloudCollection),
|
|
675
783
|
config: tinaConfigZod.optional()
|
|
676
784
|
}).superRefine((val, ctx) => {
|
|
677
|
-
var _a, _b;
|
|
678
|
-
|
|
785
|
+
var _a, _b, _c;
|
|
786
|
+
const dups = findDuplicates((_a = val.collections) == null ? void 0 : _a.map((x) => x.name));
|
|
787
|
+
if (dups) {
|
|
679
788
|
ctx.addIssue({
|
|
680
789
|
code: z.ZodIssueCode.custom,
|
|
681
|
-
message:
|
|
790
|
+
message: `${dups} are duplicate names in your collections. Collection names must be unique.`,
|
|
682
791
|
fatal: true
|
|
683
792
|
});
|
|
684
793
|
}
|
|
685
|
-
(
|
|
794
|
+
(_b = val == null ? void 0 : val.collections) == null ? void 0 : _b.map((x) => {
|
|
686
795
|
if (!x.format) {
|
|
687
796
|
console.warn(`No format provided for collection ${x.name}, defaulting to .md`);
|
|
688
797
|
}
|
|
689
798
|
});
|
|
690
|
-
const media = (
|
|
799
|
+
const media = (_c = val == null ? void 0 : val.config) == null ? void 0 : _c.media;
|
|
691
800
|
if (media && media.tina && media.loadCustomStore) {
|
|
692
801
|
ctx.addIssue({
|
|
693
802
|
code: z.ZodIssueCode.custom,
|
|
@@ -717,4 +826,4 @@ const validateSchema = ({
|
|
|
717
826
|
}
|
|
718
827
|
}
|
|
719
828
|
};
|
|
720
|
-
export { TinaSchema, TinaSchemaValidationError, addNamespaceToSchema, resolveField, resolveForm, validateSchema, validateTinaCloudSchemaConfig };
|
|
829
|
+
export { NAMER, TinaSchema, TinaSchemaValidationError, addNamespaceToSchema, resolveField, resolveForm, validateSchema, validateTinaCloudSchemaConfig };
|
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
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
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) {
|
|
@@ -187,7 +192,7 @@
|
|
|
187
192
|
};
|
|
188
193
|
this.getCollectionByFullPath = (filepath) => {
|
|
189
194
|
const collection = this.getCollections().find((collection2) => {
|
|
190
|
-
return filepath.replace(
|
|
195
|
+
return filepath.replace(/\\/g, "/").startsWith(collection2.path.replace(/\/?$/, "/"));
|
|
191
196
|
});
|
|
192
197
|
if (!collection) {
|
|
193
198
|
throw new Error(`Unable to find collection for file at ${filepath}`);
|
|
@@ -196,12 +201,7 @@
|
|
|
196
201
|
};
|
|
197
202
|
this.getCollectionAndTemplateByFullPath = (filepath, templateName) => {
|
|
198
203
|
let template;
|
|
199
|
-
const collection = this.
|
|
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) {
|
|
@@ -238,6 +238,72 @@
|
|
|
238
238
|
return template;
|
|
239
239
|
}
|
|
240
240
|
};
|
|
241
|
+
this.transformPayload = (collectionName, payload) => {
|
|
242
|
+
const collection = this.getCollection(collectionName);
|
|
243
|
+
if (collection.templates) {
|
|
244
|
+
const template = collection.templates.find((template2) => {
|
|
245
|
+
if (typeof template2 === "string") {
|
|
246
|
+
throw new Error("Global templates not supported");
|
|
247
|
+
}
|
|
248
|
+
return payload["_template"] === template2.name;
|
|
249
|
+
});
|
|
250
|
+
if (!template) {
|
|
251
|
+
console.error(payload);
|
|
252
|
+
throw new Error(`Unable to find template for payload`);
|
|
253
|
+
}
|
|
254
|
+
if (typeof template === "string") {
|
|
255
|
+
throw new Error("Global templates not supported");
|
|
256
|
+
}
|
|
257
|
+
return {
|
|
258
|
+
[collectionName]: {
|
|
259
|
+
[template.name]: this.transformCollectablePayload(payload, template)
|
|
260
|
+
}
|
|
261
|
+
};
|
|
262
|
+
} else {
|
|
263
|
+
return {
|
|
264
|
+
[collectionName]: this.transformCollectablePayload(payload, collection)
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
};
|
|
268
|
+
this.transformCollectablePayload = (payload, collection) => {
|
|
269
|
+
const accumulator = {};
|
|
270
|
+
Object.entries(payload).forEach(([key, value]) => {
|
|
271
|
+
if (typeof collection.fields === "string") {
|
|
272
|
+
throw new Error("Global templates not supported");
|
|
273
|
+
}
|
|
274
|
+
const field = collection.fields.find((field2) => {
|
|
275
|
+
if (typeof field2 === "string") {
|
|
276
|
+
throw new Error("Global templates not supported");
|
|
277
|
+
}
|
|
278
|
+
return field2.name === key;
|
|
279
|
+
});
|
|
280
|
+
if (field) {
|
|
281
|
+
accumulator[key] = this.transformField(field, value);
|
|
282
|
+
}
|
|
283
|
+
});
|
|
284
|
+
return accumulator;
|
|
285
|
+
};
|
|
286
|
+
this.transformField = (field, value) => {
|
|
287
|
+
if (field.type === "object")
|
|
288
|
+
if (field.templates) {
|
|
289
|
+
if (field.list) {
|
|
290
|
+
assertShape(value, (yup2) => yup2.array(yup2.object({ _template: yup2.string().required() })));
|
|
291
|
+
return value.map((item) => {
|
|
292
|
+
const { _template, ...rest } = item;
|
|
293
|
+
return { [_template]: rest };
|
|
294
|
+
});
|
|
295
|
+
} else {
|
|
296
|
+
assertShape(value, (yup2) => yup2.object({ _template: yup2.string().required() }));
|
|
297
|
+
const { _template, ...rest } = value;
|
|
298
|
+
return { [_template]: rest };
|
|
299
|
+
}
|
|
300
|
+
} else {
|
|
301
|
+
return value;
|
|
302
|
+
}
|
|
303
|
+
else {
|
|
304
|
+
return value;
|
|
305
|
+
}
|
|
306
|
+
};
|
|
241
307
|
this.isMarkdownCollection = (collectionName) => {
|
|
242
308
|
const collection = this.getCollection(collectionName);
|
|
243
309
|
const format = collection.format;
|
|
@@ -288,9 +354,9 @@
|
|
|
288
354
|
this.schema = config;
|
|
289
355
|
}
|
|
290
356
|
}
|
|
291
|
-
const resolveField = (
|
|
357
|
+
const resolveField = (field, schema) => {
|
|
292
358
|
var _a;
|
|
293
|
-
field.parentTypename = NAMER.dataTypeName(namespace.filter((_, i) => i < namespace.length - 1));
|
|
359
|
+
field.parentTypename = NAMER.dataTypeName(field.namespace.filter((_, i) => i < field.namespace.length - 1));
|
|
294
360
|
const extraFields = field.ui || {};
|
|
295
361
|
switch (field.type) {
|
|
296
362
|
case "number":
|
|
@@ -351,10 +417,7 @@
|
|
|
351
417
|
...extraFields
|
|
352
418
|
};
|
|
353
419
|
case "object":
|
|
354
|
-
const templateInfo = schema.getTemplatesForCollectable(
|
|
355
|
-
...field,
|
|
356
|
-
namespace
|
|
357
|
-
});
|
|
420
|
+
const templateInfo = schema.getTemplatesForCollectable(field);
|
|
358
421
|
if (templateInfo.type === "object") {
|
|
359
422
|
return {
|
|
360
423
|
...field,
|
|
@@ -372,6 +435,7 @@
|
|
|
372
435
|
templates2[lastItem(template.namespace)] = {
|
|
373
436
|
label: template.label || templateName,
|
|
374
437
|
key: templateName,
|
|
438
|
+
namespace: [...field.namespace, templateName],
|
|
375
439
|
fields: template.fields.map((field2) => resolveField(field2, schema)),
|
|
376
440
|
...extraFields2
|
|
377
441
|
};
|
|
@@ -380,6 +444,7 @@
|
|
|
380
444
|
return {
|
|
381
445
|
...field,
|
|
382
446
|
typeMap: typeMap2,
|
|
447
|
+
namespace: field.namespace,
|
|
383
448
|
component: field.list ? "blocks" : "not-implemented",
|
|
384
449
|
templates: templates2,
|
|
385
450
|
...extraFields
|
|
@@ -465,7 +530,9 @@
|
|
|
465
530
|
const name = z.z.string({
|
|
466
531
|
required_error: "Name is required but not provided",
|
|
467
532
|
invalid_type_error: "Name must be a string"
|
|
468
|
-
})
|
|
533
|
+
}).refine((val) => val.match(/^[a-zA-Z0-9_]*$/) !== null, (val) => ({
|
|
534
|
+
message: `name, "${val}" must be alphanumeric and can only contain underscores`
|
|
535
|
+
}));
|
|
469
536
|
const TypeName = [
|
|
470
537
|
"string",
|
|
471
538
|
"boolean",
|
|
@@ -484,7 +551,7 @@
|
|
|
484
551
|
}).superRefine((val, ctx) => {
|
|
485
552
|
if (val.includes(" "))
|
|
486
553
|
ctx.addIssue({
|
|
487
|
-
message:
|
|
554
|
+
message: `name "${val}" cannot contain spaces`,
|
|
488
555
|
code: z.z.ZodIssueCode.custom,
|
|
489
556
|
fatal: true
|
|
490
557
|
});
|
|
@@ -554,22 +621,37 @@
|
|
|
554
621
|
start: z.z.string(),
|
|
555
622
|
end: z.z.string()
|
|
556
623
|
}).optional()
|
|
557
|
-
}).
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
624
|
+
}).superRefine((val, ctx) => {
|
|
625
|
+
const dups = findDuplicates(val == null ? void 0 : val.fields.map((x) => x.name));
|
|
626
|
+
if (dups) {
|
|
627
|
+
ctx.addIssue({
|
|
628
|
+
code: z.z.ZodIssueCode.custom,
|
|
629
|
+
message: `Fields must have a unique name, duplicate field names: ${dups}`
|
|
630
|
+
});
|
|
631
|
+
}
|
|
562
632
|
});
|
|
563
633
|
const ObjectField = FieldWithList.extend({
|
|
564
634
|
type: z.z.literal("object", {
|
|
565
635
|
invalid_type_error: typeTypeError,
|
|
566
636
|
required_error: typeRequiredError
|
|
567
637
|
}),
|
|
568
|
-
fields: z.z.array(TinaFieldZod).min(1).optional().
|
|
569
|
-
|
|
638
|
+
fields: z.z.array(TinaFieldZod).min(1).optional().superRefine((val, ctx) => {
|
|
639
|
+
const dups = findDuplicates(val == null ? void 0 : val.map((x) => x.name));
|
|
640
|
+
if (dups) {
|
|
641
|
+
ctx.addIssue({
|
|
642
|
+
code: z.z.ZodIssueCode.custom,
|
|
643
|
+
message: `Fields must have a unique name, duplicate field names: ${dups}`
|
|
644
|
+
});
|
|
645
|
+
}
|
|
570
646
|
}),
|
|
571
|
-
templates: z.z.array(TemplateTemp).min(1).optional().
|
|
572
|
-
|
|
647
|
+
templates: z.z.array(TemplateTemp).min(1).optional().superRefine((val, ctx) => {
|
|
648
|
+
const dups = findDuplicates(val == null ? void 0 : val.map((x) => x.name));
|
|
649
|
+
if (dups) {
|
|
650
|
+
ctx.addIssue({
|
|
651
|
+
code: z.z.ZodIssueCode.custom,
|
|
652
|
+
message: `Templates must have a unique name, duplicate template names: ${dups}`
|
|
653
|
+
});
|
|
654
|
+
}
|
|
573
655
|
})
|
|
574
656
|
});
|
|
575
657
|
const RichTextField = FieldWithList.extend({
|
|
@@ -577,8 +659,14 @@
|
|
|
577
659
|
invalid_type_error: typeTypeError,
|
|
578
660
|
required_error: typeRequiredError
|
|
579
661
|
}),
|
|
580
|
-
templates: z.z.array(TemplateTemp).optional().
|
|
581
|
-
|
|
662
|
+
templates: z.z.array(TemplateTemp).optional().superRefine((val, ctx) => {
|
|
663
|
+
const dups = findDuplicates(val == null ? void 0 : val.map((x) => x.name));
|
|
664
|
+
if (dups) {
|
|
665
|
+
ctx.addIssue({
|
|
666
|
+
code: z.z.ZodIssueCode.custom,
|
|
667
|
+
message: `Templates must have a unique name, duplicate template names: ${dups}`
|
|
668
|
+
});
|
|
669
|
+
}
|
|
582
670
|
})
|
|
583
671
|
});
|
|
584
672
|
return z.z.discriminatedUnion("type", [
|
|
@@ -608,13 +696,17 @@
|
|
|
608
696
|
if (val.list) {
|
|
609
697
|
ctx.addIssue({
|
|
610
698
|
code: z.z.ZodIssueCode.custom,
|
|
611
|
-
message:
|
|
699
|
+
message: `Can not have \`list: true\` when using \`isTitle\`. Error in value
|
|
700
|
+
${JSON.stringify(val, null, 2)}
|
|
701
|
+
`
|
|
612
702
|
});
|
|
613
703
|
}
|
|
614
704
|
if (!val.required) {
|
|
615
705
|
ctx.addIssue({
|
|
616
706
|
code: z.z.ZodIssueCode.custom,
|
|
617
|
-
message:
|
|
707
|
+
message: `Must have { required: true } when using \`isTitle\` Error in value
|
|
708
|
+
${JSON.stringify(val, null, 2)}
|
|
709
|
+
`
|
|
618
710
|
});
|
|
619
711
|
}
|
|
620
712
|
}
|
|
@@ -665,11 +757,15 @@
|
|
|
665
757
|
}),
|
|
666
758
|
name,
|
|
667
759
|
fields: z.z.array(TinaFieldZod)
|
|
668
|
-
}).
|
|
760
|
+
}).superRefine((val, ctx) => {
|
|
669
761
|
var _a;
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
762
|
+
const dups = findDuplicates((_a = val.fields) == null ? void 0 : _a.map((x) => x.name));
|
|
763
|
+
if (dups) {
|
|
764
|
+
ctx.addIssue({
|
|
765
|
+
code: z.z.ZodIssueCode.custom,
|
|
766
|
+
message: `Fields must have a unique name, duplicate field names: ${dups}`
|
|
767
|
+
});
|
|
768
|
+
}
|
|
673
769
|
});
|
|
674
770
|
const TinaCloudCollectionBase = z.z.object({
|
|
675
771
|
label: z.z.string().optional(),
|
|
@@ -677,16 +773,28 @@
|
|
|
677
773
|
format: z.z.enum(FORMATS).optional()
|
|
678
774
|
});
|
|
679
775
|
const TinaCloudCollection = TinaCloudCollectionBase.extend({
|
|
680
|
-
fields: z.z.array(TinaFieldZod).min(1).optional().
|
|
681
|
-
|
|
776
|
+
fields: z.z.array(TinaFieldZod).min(1).optional().superRefine((val, ctx) => {
|
|
777
|
+
const dups = findDuplicates(val == null ? void 0 : val.map((x) => x.name));
|
|
778
|
+
if (dups) {
|
|
779
|
+
ctx.addIssue({
|
|
780
|
+
code: z.z.ZodIssueCode.custom,
|
|
781
|
+
message: `Fields must have a unique name, duplicate field names: ${dups}`
|
|
782
|
+
});
|
|
783
|
+
}
|
|
682
784
|
}).refine((val) => {
|
|
683
785
|
const arr = (val == null ? void 0 : val.filter((x) => x.type === "string" && x.isTitle)) || [];
|
|
684
786
|
return arr.length < 2;
|
|
685
787
|
}, {
|
|
686
788
|
message: "Fields can only have one use of `isTitle`"
|
|
687
789
|
}),
|
|
688
|
-
templates: z.z.array(Template).min(1).optional().
|
|
689
|
-
|
|
790
|
+
templates: z.z.array(Template).min(1).optional().superRefine((val, ctx) => {
|
|
791
|
+
const dups = findDuplicates(val == null ? void 0 : val.map((x) => x.name));
|
|
792
|
+
if (dups) {
|
|
793
|
+
ctx.addIssue({
|
|
794
|
+
code: z.z.ZodIssueCode.custom,
|
|
795
|
+
message: `Templates must have a unique name, duplicate template names: ${dups}`
|
|
796
|
+
});
|
|
797
|
+
}
|
|
690
798
|
})
|
|
691
799
|
}).refine((val) => {
|
|
692
800
|
let isValid = Boolean(val == null ? void 0 : val.templates) || Boolean(val == null ? void 0 : val.fields);
|
|
@@ -701,20 +809,21 @@
|
|
|
701
809
|
collections: z.z.array(TinaCloudCollection),
|
|
702
810
|
config: tinaConfigZod.optional()
|
|
703
811
|
}).superRefine((val, ctx) => {
|
|
704
|
-
var _a, _b;
|
|
705
|
-
|
|
812
|
+
var _a, _b, _c;
|
|
813
|
+
const dups = findDuplicates((_a = val.collections) == null ? void 0 : _a.map((x) => x.name));
|
|
814
|
+
if (dups) {
|
|
706
815
|
ctx.addIssue({
|
|
707
816
|
code: z.z.ZodIssueCode.custom,
|
|
708
|
-
message:
|
|
817
|
+
message: `${dups} are duplicate names in your collections. Collection names must be unique.`,
|
|
709
818
|
fatal: true
|
|
710
819
|
});
|
|
711
820
|
}
|
|
712
|
-
(
|
|
821
|
+
(_b = val == null ? void 0 : val.collections) == null ? void 0 : _b.map((x) => {
|
|
713
822
|
if (!x.format) {
|
|
714
823
|
console.warn(`No format provided for collection ${x.name}, defaulting to .md`);
|
|
715
824
|
}
|
|
716
825
|
});
|
|
717
|
-
const media = (
|
|
826
|
+
const media = (_c = val == null ? void 0 : val.config) == null ? void 0 : _c.media;
|
|
718
827
|
if (media && media.tina && media.loadCustomStore) {
|
|
719
828
|
ctx.addIssue({
|
|
720
829
|
code: z.z.ZodIssueCode.custom,
|
|
@@ -744,6 +853,7 @@
|
|
|
744
853
|
}
|
|
745
854
|
}
|
|
746
855
|
};
|
|
856
|
+
exports2.NAMER = NAMER;
|
|
747
857
|
exports2.TinaSchema = TinaSchema;
|
|
748
858
|
exports2.TinaSchemaValidationError = TinaSchemaValidationError;
|
|
749
859
|
exports2.addNamespaceToSchema = addNamespaceToSchema;
|
|
@@ -64,6 +64,13 @@ export declare class TinaSchema {
|
|
|
64
64
|
data?: unknown;
|
|
65
65
|
collection: Collectable;
|
|
66
66
|
}) => Templateable;
|
|
67
|
+
transformPayload: (collectionName: string, payload: object) => {
|
|
68
|
+
[x: string]: {
|
|
69
|
+
[x: string]: {};
|
|
70
|
+
};
|
|
71
|
+
};
|
|
72
|
+
private transformCollectablePayload;
|
|
73
|
+
private transformField;
|
|
67
74
|
isMarkdownCollection: (collectionName: string) => boolean;
|
|
68
75
|
/**
|
|
69
76
|
* Gets the template or templates from the item.
|
|
@@ -21,4 +21,9 @@ import { TinaSchema } from './TinaSchema';
|
|
|
21
21
|
* @param {TinaSchema} schema the entireT Tina Schema
|
|
22
22
|
* @returns unknown
|
|
23
23
|
*/
|
|
24
|
-
export declare const resolveField: (
|
|
24
|
+
export declare const resolveField: (field: TinaFieldEnriched, schema: TinaSchema) => {
|
|
25
|
+
[key: string]: unknown;
|
|
26
|
+
name: string;
|
|
27
|
+
component: string;
|
|
28
|
+
type: string;
|
|
29
|
+
};
|
|
@@ -18,5 +18,10 @@ export declare const resolveForm: ({ collection, basename, template, schema, }:
|
|
|
18
18
|
id: string;
|
|
19
19
|
label: string;
|
|
20
20
|
name: string;
|
|
21
|
-
fields:
|
|
21
|
+
fields: {
|
|
22
|
+
[key: string]: unknown;
|
|
23
|
+
name: string;
|
|
24
|
+
component: string;
|
|
25
|
+
type: string;
|
|
26
|
+
}[];
|
|
22
27
|
};
|
|
@@ -44,11 +44,46 @@ export declare type TinaCloudCollection<WithNamespace extends boolean> = Collect
|
|
|
44
44
|
export declare type TinaCloudCollectionBase = TinaCloudCollection<false>;
|
|
45
45
|
export declare type TinaCloudCollectionEnriched = TinaCloudCollection<true>;
|
|
46
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
|
+
};
|
|
47
59
|
interface BaseCollection {
|
|
48
60
|
label?: string;
|
|
49
61
|
name: string;
|
|
50
62
|
path: string;
|
|
51
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
|
+
};
|
|
52
87
|
match?: string;
|
|
53
88
|
}
|
|
54
89
|
declare type CollectionTemplates<WithNamespace extends boolean> = WithNamespace extends true ? CollectionTemplatesWithNamespace<WithNamespace> : CollectionTemplatesInner<WithNamespace>;
|
|
@@ -0,0 +1,101 @@
|
|
|
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
|
+
import { TinaCloudSchema } from './SchemaTypes';
|
|
14
|
+
/**
|
|
15
|
+
* Used with `defineStaticConfig`
|
|
16
|
+
*
|
|
17
|
+
* These are mostly similar types as whats in `schemaTypes`
|
|
18
|
+
* but since those have gone through several iterations
|
|
19
|
+
* they're pretty messy. These should act as the happy path
|
|
20
|
+
* for iframe/standalone setups which we hope to eventually
|
|
21
|
+
* make the default/only path for all Tina users.
|
|
22
|
+
*/
|
|
23
|
+
export declare type TinaCMSConfig<CMSCallback = undefined, FormifyCallback = undefined, DocumentCreatorCallback = undefined, Store = undefined> = {
|
|
24
|
+
schema: TinaCloudSchema<false>;
|
|
25
|
+
/**
|
|
26
|
+
* The base branch to pull content from. Note that this is ignored for local development
|
|
27
|
+
*/
|
|
28
|
+
branch: string | null;
|
|
29
|
+
/**
|
|
30
|
+
* Your clientId from app.tina.io
|
|
31
|
+
*/
|
|
32
|
+
clientId: string | null;
|
|
33
|
+
/**
|
|
34
|
+
* Your read only token from app.tina.io
|
|
35
|
+
*/
|
|
36
|
+
token: string | null;
|
|
37
|
+
/**
|
|
38
|
+
* Configurations for the autogenerated GraphQL HTTP client
|
|
39
|
+
*/
|
|
40
|
+
client?: {
|
|
41
|
+
/**
|
|
42
|
+
* Autogenerated queries will traverse references to a given depth
|
|
43
|
+
* @default 2
|
|
44
|
+
*/
|
|
45
|
+
referenceDepth?: number;
|
|
46
|
+
};
|
|
47
|
+
build?: {
|
|
48
|
+
/**
|
|
49
|
+
* The folder where your application stores assets, eg. `"public"`
|
|
50
|
+
*/
|
|
51
|
+
publicFolder: string;
|
|
52
|
+
/**
|
|
53
|
+
* TinaCMS is shipped as a single-page app, the value specified here will
|
|
54
|
+
* determine the path when visiting the TinaCMS dashboard.
|
|
55
|
+
*
|
|
56
|
+
* Eg. `"admin"` will be viewable at `[your-development-url]/admin/index.html`
|
|
57
|
+
*/
|
|
58
|
+
outputFolder: string;
|
|
59
|
+
};
|
|
60
|
+
media?: {
|
|
61
|
+
/**
|
|
62
|
+
* Load a media store like Cloudinary
|
|
63
|
+
*
|
|
64
|
+
* ```ts
|
|
65
|
+
* loadCustomStore = async () => {
|
|
66
|
+
* const pack = await import("next-tinacms-cloudinary");
|
|
67
|
+
* return pack.TinaCloudCloudinaryMediaStore;
|
|
68
|
+
* }
|
|
69
|
+
* ```
|
|
70
|
+
*/
|
|
71
|
+
loadCustomStore: () => Promise<Store>;
|
|
72
|
+
tina?: never;
|
|
73
|
+
} | {
|
|
74
|
+
/**
|
|
75
|
+
* Use Git-backed assets for media, these values will
|
|
76
|
+
* [Learn more](https://tina.io/docs/reference/media/repo-based/)
|
|
77
|
+
*/
|
|
78
|
+
tina: {
|
|
79
|
+
/**
|
|
80
|
+
* The folder where your application stores assets, eg. `"public"`
|
|
81
|
+
*/
|
|
82
|
+
publicFolder: string;
|
|
83
|
+
/**
|
|
84
|
+
* The root folder for media managed by Tina. For example, `"uploads"`
|
|
85
|
+
* would store content in `"<my-public-folder>/uploads"`
|
|
86
|
+
*/
|
|
87
|
+
mediaRoot: string;
|
|
88
|
+
};
|
|
89
|
+
loadCustomStore?: never;
|
|
90
|
+
};
|
|
91
|
+
tinaioConfig?: {
|
|
92
|
+
assetsApiUrlOverride?: string;
|
|
93
|
+
frontendUrlOverride?: string;
|
|
94
|
+
identityApiUrlOverride?: string;
|
|
95
|
+
contentApiUrlOverride?: string;
|
|
96
|
+
};
|
|
97
|
+
cmsCallback?: CMSCallback;
|
|
98
|
+
formifyCallback?: FormifyCallback;
|
|
99
|
+
documentCreatorCallback?: DocumentCreatorCallback;
|
|
100
|
+
};
|
|
101
|
+
export {};
|
package/dist/types/index.d.ts
CHANGED
|
@@ -0,0 +1,13 @@
|
|
|
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 {};
|
|
@@ -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
|
|
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;
|
|
@@ -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.1.
|
|
3
|
+
"version": "0.1.3",
|
|
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.51.
|
|
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",
|