@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 +166 -182
- package/dist/index.mjs +166 -182
- package/dist/schema/TinaSchema.d.ts +8 -10
- package/dist/schema/addNamespaceToSchema.d.ts +8 -4
- package/dist/types/index.d.ts +6 -0
- package/dist/validate/fields.d.ts +0 -3
- package/dist/validate/schema.d.ts +0 -3
- package/dist/validate/util.d.ts +3 -0
- package/package.json +2 -2
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
|
|
23
|
+
if (typeof maybeNode !== "object" || maybeNode === null) {
|
|
24
24
|
return maybeNode;
|
|
25
25
|
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
2012
|
-
if (result[
|
|
2013
|
-
result[
|
|
1977
|
+
field.collections.forEach((name22) => {
|
|
1978
|
+
if (result[name22] === void 0) {
|
|
1979
|
+
result[name22] = [];
|
|
2014
1980
|
}
|
|
2015
|
-
result[
|
|
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 =
|
|
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
|
|
2291
|
-
const
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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: ${(
|
|
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
|
-
|
|
2452
|
-
|
|
2453
|
-
|
|
2454
|
-
|
|
2455
|
-
|
|
2456
|
-
${
|
|
2457
|
-
|
|
2458
|
-
|
|
2459
|
-
|
|
2460
|
-
|
|
2461
|
-
|
|
2462
|
-
|
|
2463
|
-
|
|
2464
|
-
|
|
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:
|
|
2482
|
-
${
|
|
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
|
-
|
|
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
|
|
2566
|
-
required_error: "label
|
|
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:
|
|
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'
|
|
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:
|
|
2591
|
+
message: duplicateFieldErrorMessage(dups)
|
|
2609
2592
|
});
|
|
2610
2593
|
}
|
|
2611
|
-
}).
|
|
2612
|
-
|
|
2613
|
-
(
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
|
|
2622
|
-
|
|
2623
|
-
|
|
2624
|
-
|
|
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
|
-
|
|
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:
|
|
2624
|
+
message: duplicateFieldErrorMessage(dups)
|
|
2645
2625
|
});
|
|
2646
2626
|
}
|
|
2647
2627
|
})
|
|
2648
|
-
}).
|
|
2649
|
-
(val)
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
}
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
|
|
2658
|
-
|
|
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:
|
|
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:
|
|
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: "
|
|
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: "
|
|
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("
|
|
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
|
|
5
|
+
if (typeof maybeNode !== "object" || maybeNode === null) {
|
|
6
6
|
return maybeNode;
|
|
7
7
|
}
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
1994
|
-
if (result[
|
|
1995
|
-
result[
|
|
1959
|
+
field.collections.forEach((name22) => {
|
|
1960
|
+
if (result[name22] === void 0) {
|
|
1961
|
+
result[name22] = [];
|
|
1996
1962
|
}
|
|
1997
|
-
result[
|
|
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 =
|
|
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
|
|
2273
|
-
const
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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: ${(
|
|
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
|
-
|
|
2434
|
-
|
|
2435
|
-
|
|
2436
|
-
|
|
2437
|
-
|
|
2438
|
-
${
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
|
|
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:
|
|
2464
|
-
${
|
|
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
|
-
|
|
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
|
|
2548
|
-
required_error: "label
|
|
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:
|
|
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'
|
|
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:
|
|
2573
|
+
message: duplicateFieldErrorMessage(dups)
|
|
2591
2574
|
});
|
|
2592
2575
|
}
|
|
2593
|
-
}).
|
|
2594
|
-
|
|
2595
|
-
(
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
|
|
2605
|
-
|
|
2606
|
-
|
|
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
|
-
|
|
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:
|
|
2606
|
+
message: duplicateFieldErrorMessage(dups)
|
|
2627
2607
|
});
|
|
2628
2608
|
}
|
|
2629
2609
|
})
|
|
2630
|
-
}).
|
|
2631
|
-
(val)
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
|
|
2635
|
-
}
|
|
2636
|
-
|
|
2637
|
-
|
|
2638
|
-
|
|
2639
|
-
|
|
2640
|
-
|
|
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:
|
|
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:
|
|
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: "
|
|
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: "
|
|
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("
|
|
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
|
|
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
|
-
|
|
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
|
|
67
|
-
field:
|
|
68
|
-
collection:
|
|
69
|
-
path: string
|
|
70
|
-
|
|
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
|
-
|
|
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 {};
|
package/dist/types/index.d.ts
CHANGED
|
@@ -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`).
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tinacms/schema-tools",
|
|
3
|
-
"version": "0.0.0-
|
|
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": "
|
|
35
|
+
"@tinacms/scripts": "1.3.1"
|
|
36
36
|
},
|
|
37
37
|
"peerDependencies": {
|
|
38
38
|
"react": ">=16.14.0",
|