@tinacms/schema-tools 0.0.0-b4c6a60-20241010070518 → 0.0.0-bdc07c1-20250506013835
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +1 -6
- package/dist/index.js +194 -168
- package/dist/index.mjs +193 -166
- package/dist/schema/TinaSchema.d.ts +21 -1
- package/dist/schema/addNamespaceToSchema.d.ts +8 -4
- package/dist/types/index.d.ts +15 -7
- package/dist/validate/fields.d.ts +0 -3
- package/dist/validate/schema.d.ts +12 -15
- package/dist/validate/util.d.ts +3 -0
- package/package.json +8 -7
package/dist/index.mjs
CHANGED
|
@@ -1,43 +1,28 @@
|
|
|
1
1
|
import * as yup from "yup";
|
|
2
2
|
import UrlPattern from "url-pattern";
|
|
3
3
|
import z$1, { z, ZodError } from "zod";
|
|
4
|
+
import { CONTENT_FORMATS } from "@tinacms/common";
|
|
4
5
|
function addNamespaceToSchema(maybeNode, namespace = []) {
|
|
5
|
-
if (typeof maybeNode
|
|
6
|
+
if (typeof maybeNode !== "object" || maybeNode === null) {
|
|
6
7
|
return maybeNode;
|
|
7
8
|
}
|
|
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;
|
|
9
|
+
const newNode = { ...maybeNode, namespace: [...namespace] };
|
|
10
|
+
Object.entries(maybeNode).forEach(([key, value]) => {
|
|
11
|
+
if (Array.isArray(value)) {
|
|
12
|
+
newNode[key] = value.map((element) => {
|
|
13
|
+
if (element && typeof element === "object" && "name" in element) {
|
|
14
|
+
const valueName = element.name || element.value;
|
|
15
|
+
return addNamespaceToSchema(element, [...namespace, valueName]);
|
|
25
16
|
}
|
|
26
|
-
|
|
27
|
-
return addNamespaceToSchema(element, [...namespace, value]);
|
|
17
|
+
return element;
|
|
28
18
|
});
|
|
19
|
+
} else if (value && typeof value === "object" && "name" in value) {
|
|
20
|
+
newNode[key] = addNamespaceToSchema(value, [...namespace, value.name]);
|
|
29
21
|
} 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
|
-
}
|
|
22
|
+
newNode[key] = value;
|
|
38
23
|
}
|
|
39
24
|
});
|
|
40
|
-
return
|
|
25
|
+
return newNode;
|
|
41
26
|
}
|
|
42
27
|
function getDefaultExportFromCjs(x) {
|
|
43
28
|
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x["default"] : x;
|
|
@@ -1943,7 +1928,7 @@ class TinaSchema {
|
|
|
1943
1928
|
}
|
|
1944
1929
|
}
|
|
1945
1930
|
};
|
|
1946
|
-
this.
|
|
1931
|
+
this.legacyWalkFields = (cb) => {
|
|
1947
1932
|
const walk = (collectionOrObject, collection, path) => {
|
|
1948
1933
|
if (collectionOrObject.templates) {
|
|
1949
1934
|
collectionOrObject.templates.forEach((template) => {
|
|
@@ -1965,7 +1950,7 @@ class TinaSchema {
|
|
|
1965
1950
|
collections.forEach((collection) => walk(collection, collection, []));
|
|
1966
1951
|
};
|
|
1967
1952
|
this.schema = config;
|
|
1968
|
-
this.
|
|
1953
|
+
this.legacyWalkFields(({ field, collection }) => {
|
|
1969
1954
|
if (!("searchable" in field)) {
|
|
1970
1955
|
if (field.type === "image") {
|
|
1971
1956
|
field.searchable = false;
|
|
@@ -1986,6 +1971,67 @@ class TinaSchema {
|
|
|
1986
1971
|
field.uid = field.uid || false;
|
|
1987
1972
|
});
|
|
1988
1973
|
}
|
|
1974
|
+
findReferencesFromCollection(name2) {
|
|
1975
|
+
const result = {};
|
|
1976
|
+
this.walkFields(({ field, collection: c, path }) => {
|
|
1977
|
+
if (c.name !== name2) {
|
|
1978
|
+
return;
|
|
1979
|
+
}
|
|
1980
|
+
if (field.type === "reference") {
|
|
1981
|
+
field.collections.forEach((name22) => {
|
|
1982
|
+
if (result[name22] === void 0) {
|
|
1983
|
+
result[name22] = [];
|
|
1984
|
+
}
|
|
1985
|
+
result[name22].push(path);
|
|
1986
|
+
});
|
|
1987
|
+
}
|
|
1988
|
+
});
|
|
1989
|
+
return result;
|
|
1990
|
+
}
|
|
1991
|
+
/**
|
|
1992
|
+
* Walk all fields in tina schema
|
|
1993
|
+
*
|
|
1994
|
+
* @param cb callback function invoked for each field
|
|
1995
|
+
*/
|
|
1996
|
+
walkFields(cb) {
|
|
1997
|
+
const walk = (collectionOrObject, collection, path = "$") => {
|
|
1998
|
+
if (collectionOrObject.templates) {
|
|
1999
|
+
collectionOrObject.templates.forEach((template) => {
|
|
2000
|
+
const templatePath = `${path}.${template.name}`;
|
|
2001
|
+
template.fields.forEach((field) => {
|
|
2002
|
+
const fieldPath = field.list ? `${templatePath}[*].${field.name}` : `${templatePath}.${field.name}`;
|
|
2003
|
+
cb({ field, collection, path: fieldPath });
|
|
2004
|
+
if (field.type === "object") {
|
|
2005
|
+
walk(field, collection, fieldPath);
|
|
2006
|
+
}
|
|
2007
|
+
});
|
|
2008
|
+
});
|
|
2009
|
+
}
|
|
2010
|
+
if (collectionOrObject.fields) {
|
|
2011
|
+
collectionOrObject.fields.forEach((field) => {
|
|
2012
|
+
const fieldPath = field.list ? `${path}.${field.name}[*]` : `${path}.${field.name}`;
|
|
2013
|
+
cb({ field, collection, path: fieldPath });
|
|
2014
|
+
if (field.type === "object" && field.fields) {
|
|
2015
|
+
walk(field, collection, fieldPath);
|
|
2016
|
+
} else if (field.templates) {
|
|
2017
|
+
field.templates.forEach((template) => {
|
|
2018
|
+
const templatePath = `${fieldPath}.${template.name}`;
|
|
2019
|
+
template.fields.forEach((field2) => {
|
|
2020
|
+
const fieldPath2 = field2.list ? `${templatePath}[*].${field2.name}` : `${templatePath}.${field2.name}`;
|
|
2021
|
+
cb({ field: field2, collection, path: fieldPath2 });
|
|
2022
|
+
if (field2.type === "object") {
|
|
2023
|
+
walk(field2, collection, fieldPath2);
|
|
2024
|
+
}
|
|
2025
|
+
});
|
|
2026
|
+
});
|
|
2027
|
+
}
|
|
2028
|
+
});
|
|
2029
|
+
}
|
|
2030
|
+
};
|
|
2031
|
+
this.getCollections().forEach((collection) => {
|
|
2032
|
+
walk(collection, collection);
|
|
2033
|
+
});
|
|
2034
|
+
}
|
|
1989
2035
|
/**
|
|
1990
2036
|
* This function returns an array of glob matches for a given collection.
|
|
1991
2037
|
*
|
|
@@ -2208,9 +2254,12 @@ const parseZodError = ({ zodError }) => {
|
|
|
2208
2254
|
moreInfo.push(parseZodError({ zodError: unionError }));
|
|
2209
2255
|
});
|
|
2210
2256
|
}
|
|
2211
|
-
const errorMessage =
|
|
2257
|
+
const errorMessage = `${issue == null ? void 0 : issue.message}
|
|
2258
|
+
Additional information:
|
|
2259
|
+
- Error found at path ${issue.path.join(
|
|
2212
2260
|
"."
|
|
2213
|
-
)}
|
|
2261
|
+
)}
|
|
2262
|
+
`;
|
|
2214
2263
|
const errorMessages = [errorMessage, ...moreInfo];
|
|
2215
2264
|
return {
|
|
2216
2265
|
errors: errorMessages
|
|
@@ -2245,6 +2294,9 @@ If you need to use this value in your content you can use the \`nameOverride\` p
|
|
|
2245
2294
|
});
|
|
2246
2295
|
}
|
|
2247
2296
|
});
|
|
2297
|
+
const duplicateFieldErrorMessage = (fields) => `Fields must have unique names. Found duplicate field names: [${fields}]`;
|
|
2298
|
+
const duplicateTemplateErrorMessage = (templates) => `Templates must have unique names. Found duplicate template names: [${templates}]`;
|
|
2299
|
+
const duplicateCollectionErrorMessage = (collection) => `Collections must have unique names. Found duplicate collection names: [${collection}]`;
|
|
2248
2300
|
const TypeName = [
|
|
2249
2301
|
"string",
|
|
2250
2302
|
"boolean",
|
|
@@ -2255,10 +2307,11 @@ const TypeName = [
|
|
|
2255
2307
|
"reference",
|
|
2256
2308
|
"rich-text"
|
|
2257
2309
|
];
|
|
2258
|
-
const
|
|
2259
|
-
const
|
|
2260
|
-
|
|
2261
|
-
|
|
2310
|
+
const formattedTypes = ` - ${TypeName.join("\n - ")}`;
|
|
2311
|
+
const typeTypeError = `Invalid \`type\` property. \`type\` expected to be one of the following values:
|
|
2312
|
+
${formattedTypes}`;
|
|
2313
|
+
const typeRequiredError = `Missing \`type\` property. Please add a \`type\` property with one of the following:
|
|
2314
|
+
${formattedTypes}`;
|
|
2262
2315
|
const Option = z.union(
|
|
2263
2316
|
[
|
|
2264
2317
|
z.string(),
|
|
@@ -2344,7 +2397,7 @@ const TinaFieldZod = z.lazy(() => {
|
|
|
2344
2397
|
if (dups) {
|
|
2345
2398
|
ctx.addIssue({
|
|
2346
2399
|
code: z.ZodIssueCode.custom,
|
|
2347
|
-
message:
|
|
2400
|
+
message: duplicateFieldErrorMessage(dups)
|
|
2348
2401
|
});
|
|
2349
2402
|
}
|
|
2350
2403
|
});
|
|
@@ -2354,21 +2407,21 @@ const TinaFieldZod = z.lazy(() => {
|
|
|
2354
2407
|
invalid_type_error: typeTypeError,
|
|
2355
2408
|
required_error: typeRequiredError
|
|
2356
2409
|
}),
|
|
2357
|
-
fields: z.array(TinaFieldZod).min(1).optional().superRefine((val, ctx) => {
|
|
2410
|
+
fields: z.array(TinaFieldZod).min(1, "Property `fields` cannot be empty.").optional().superRefine((val, ctx) => {
|
|
2358
2411
|
const dups = findDuplicates(val == null ? void 0 : val.map((x) => x.name));
|
|
2359
2412
|
if (dups) {
|
|
2360
2413
|
ctx.addIssue({
|
|
2361
2414
|
code: z.ZodIssueCode.custom,
|
|
2362
|
-
message:
|
|
2415
|
+
message: duplicateFieldErrorMessage(dups)
|
|
2363
2416
|
});
|
|
2364
2417
|
}
|
|
2365
2418
|
}),
|
|
2366
|
-
templates: z.array(TemplateTemp).min(1).optional().superRefine((val, ctx) => {
|
|
2419
|
+
templates: z.array(TemplateTemp).min(1, "Property `templates` cannot be empty.").optional().superRefine((val, ctx) => {
|
|
2367
2420
|
const dups = findDuplicates(val == null ? void 0 : val.map((x) => x.name));
|
|
2368
2421
|
if (dups) {
|
|
2369
2422
|
ctx.addIssue({
|
|
2370
2423
|
code: z.ZodIssueCode.custom,
|
|
2371
|
-
message:
|
|
2424
|
+
message: duplicateTemplateErrorMessage(dups)
|
|
2372
2425
|
});
|
|
2373
2426
|
}
|
|
2374
2427
|
})
|
|
@@ -2383,7 +2436,7 @@ const TinaFieldZod = z.lazy(() => {
|
|
|
2383
2436
|
if (dups) {
|
|
2384
2437
|
ctx.addIssue({
|
|
2385
2438
|
code: z.ZodIssueCode.custom,
|
|
2386
|
-
message:
|
|
2439
|
+
message: duplicateTemplateErrorMessage(dups)
|
|
2387
2440
|
});
|
|
2388
2441
|
}
|
|
2389
2442
|
})
|
|
@@ -2403,10 +2456,17 @@ const TinaFieldZod = z.lazy(() => {
|
|
|
2403
2456
|
],
|
|
2404
2457
|
{
|
|
2405
2458
|
errorMap: (issue, ctx) => {
|
|
2406
|
-
var _a;
|
|
2459
|
+
var _a, _b;
|
|
2407
2460
|
if (issue.code === "invalid_union_discriminator") {
|
|
2461
|
+
if (!((_a = ctx.data) == null ? void 0 : _a.type)) {
|
|
2462
|
+
return {
|
|
2463
|
+
message: `Missing \`type\` property in field \`${ctx.data.name}\`. Please add a \`type\` property with one of the following:
|
|
2464
|
+
${formattedTypes}`
|
|
2465
|
+
};
|
|
2466
|
+
}
|
|
2408
2467
|
return {
|
|
2409
|
-
message: `Invalid \`type\` property. In the schema is 'type: ${(
|
|
2468
|
+
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:
|
|
2469
|
+
${formattedTypes}`
|
|
2410
2470
|
};
|
|
2411
2471
|
}
|
|
2412
2472
|
return {
|
|
@@ -2416,77 +2476,52 @@ const TinaFieldZod = z.lazy(() => {
|
|
|
2416
2476
|
}
|
|
2417
2477
|
).superRefine((val, ctx) => {
|
|
2418
2478
|
if (val.type === "string") {
|
|
2419
|
-
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
${
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
|
|
2433
|
-
ctx.addIssue({
|
|
2434
|
-
code: z.ZodIssueCode.custom,
|
|
2435
|
-
message: `Must have { required: true } when using \`isTitle\` Error in value
|
|
2436
|
-
${JSON.stringify(
|
|
2437
|
-
val,
|
|
2438
|
-
null,
|
|
2439
|
-
2
|
|
2440
|
-
)}
|
|
2441
|
-
`
|
|
2442
|
-
});
|
|
2443
|
-
}
|
|
2479
|
+
const stringifiedField = JSON.stringify(val, null, 2);
|
|
2480
|
+
if (val.isTitle && val.list) {
|
|
2481
|
+
ctx.addIssue({
|
|
2482
|
+
code: z.ZodIssueCode.custom,
|
|
2483
|
+
message: `\`list: true\` is not allowed when using \`isTitle\` for fields of \`type: string\`. Error found in field:
|
|
2484
|
+
${stringifiedField}`
|
|
2485
|
+
});
|
|
2486
|
+
}
|
|
2487
|
+
if (val.isTitle && !val.required) {
|
|
2488
|
+
ctx.addIssue({
|
|
2489
|
+
code: z.ZodIssueCode.custom,
|
|
2490
|
+
message: `Property \`required: true\` is required when using \`isTitle\` for fields of \`type: string\`. Error found in field:
|
|
2491
|
+
${stringifiedField}`
|
|
2492
|
+
});
|
|
2444
2493
|
}
|
|
2445
|
-
if (val.uid) {
|
|
2494
|
+
if (val.uid && val.list) {
|
|
2446
2495
|
if (val.list) {
|
|
2447
2496
|
ctx.addIssue({
|
|
2448
2497
|
code: z.ZodIssueCode.custom,
|
|
2449
|
-
message:
|
|
2450
|
-
${
|
|
2451
|
-
val,
|
|
2452
|
-
null,
|
|
2453
|
-
2
|
|
2454
|
-
)}
|
|
2455
|
-
`
|
|
2456
|
-
});
|
|
2457
|
-
}
|
|
2458
|
-
if (!val.required) {
|
|
2459
|
-
ctx.addIssue({
|
|
2460
|
-
code: z.ZodIssueCode.custom,
|
|
2461
|
-
message: `Must have { required: true } when using \`uid\` Error in value
|
|
2462
|
-
${JSON.stringify(
|
|
2463
|
-
val,
|
|
2464
|
-
null,
|
|
2465
|
-
2
|
|
2466
|
-
)}
|
|
2467
|
-
`
|
|
2498
|
+
message: `\`list: true\` is not allowed when using \`uid\` for fields of \`type: string\`. Error found in field:
|
|
2499
|
+
${stringifiedField}`
|
|
2468
2500
|
});
|
|
2469
2501
|
}
|
|
2470
2502
|
}
|
|
2503
|
+
if (val.uid && !val.required) {
|
|
2504
|
+
ctx.addIssue({
|
|
2505
|
+
code: z.ZodIssueCode.custom,
|
|
2506
|
+
message: `Property \`required: true\` is required when using \`uid\` for fields of \`type: string\`. Error found in field:
|
|
2507
|
+
${stringifiedField}`
|
|
2508
|
+
});
|
|
2509
|
+
}
|
|
2471
2510
|
}
|
|
2472
2511
|
if (val.type === "object") {
|
|
2473
|
-
|
|
2474
|
-
let isValid = Boolean(val == null ? void 0 : val.templates) || Boolean(val == null ? void 0 : val.fields);
|
|
2475
|
-
if (!isValid) {
|
|
2512
|
+
if (!(val == null ? void 0 : val.templates) && !(val == null ? void 0 : val.fields)) {
|
|
2476
2513
|
ctx.addIssue({
|
|
2477
2514
|
code: z.ZodIssueCode.custom,
|
|
2478
|
-
message
|
|
2515
|
+
message: "Fields of `type: object` must have either `templates` or `fields` property."
|
|
2516
|
+
});
|
|
2517
|
+
return false;
|
|
2518
|
+
}
|
|
2519
|
+
if ((val == null ? void 0 : val.templates) && (val == null ? void 0 : val.fields)) {
|
|
2520
|
+
ctx.addIssue({
|
|
2521
|
+
code: z.ZodIssueCode.custom,
|
|
2522
|
+
message: "Fields of `type: object` must have either `templates` or `fields` property, not both."
|
|
2479
2523
|
});
|
|
2480
2524
|
return false;
|
|
2481
|
-
} else {
|
|
2482
|
-
isValid = !((val == null ? void 0 : val.templates) && (val == null ? void 0 : val.fields));
|
|
2483
|
-
if (!isValid) {
|
|
2484
|
-
ctx.addIssue({
|
|
2485
|
-
code: z.ZodIssueCode.custom,
|
|
2486
|
-
message
|
|
2487
|
-
});
|
|
2488
|
-
}
|
|
2489
|
-
return isValid;
|
|
2490
2525
|
}
|
|
2491
2526
|
}
|
|
2492
2527
|
return true;
|
|
@@ -2519,19 +2554,10 @@ const validateTinaCloudSchemaConfig = (config) => {
|
|
|
2519
2554
|
const newConfig = tinaConfigZod.parse(config);
|
|
2520
2555
|
return newConfig;
|
|
2521
2556
|
};
|
|
2522
|
-
const FORMATS = [
|
|
2523
|
-
"json",
|
|
2524
|
-
"md",
|
|
2525
|
-
"markdown",
|
|
2526
|
-
"mdx",
|
|
2527
|
-
"toml",
|
|
2528
|
-
"yaml",
|
|
2529
|
-
"yml"
|
|
2530
|
-
];
|
|
2531
2557
|
const Template = z.object({
|
|
2532
2558
|
label: z.string({
|
|
2533
|
-
invalid_type_error: "label
|
|
2534
|
-
required_error: "label
|
|
2559
|
+
invalid_type_error: "Invalid data type for property `label`. Must be of type `string`",
|
|
2560
|
+
required_error: "Missing `label` property. Property `label` is required."
|
|
2535
2561
|
}),
|
|
2536
2562
|
name,
|
|
2537
2563
|
fields: z.array(TinaFieldZod)
|
|
@@ -2541,7 +2567,7 @@ const Template = z.object({
|
|
|
2541
2567
|
if (dups) {
|
|
2542
2568
|
ctx.addIssue({
|
|
2543
2569
|
code: z.ZodIssueCode.custom,
|
|
2544
|
-
message:
|
|
2570
|
+
message: duplicateFieldErrorMessage(dups)
|
|
2545
2571
|
});
|
|
2546
2572
|
}
|
|
2547
2573
|
});
|
|
@@ -2551,7 +2577,7 @@ const CollectionBaseSchema = z.object({
|
|
|
2551
2577
|
if (val === "relativePath") {
|
|
2552
2578
|
ctx.addIssue({
|
|
2553
2579
|
code: z.ZodIssueCode.custom,
|
|
2554
|
-
message: `name cannot be 'relativePath'
|
|
2580
|
+
message: "Invalid `name` property. `name` cannot be 'relativePath' as it is a reserved field name."
|
|
2555
2581
|
});
|
|
2556
2582
|
}
|
|
2557
2583
|
}),
|
|
@@ -2559,72 +2585,73 @@ const CollectionBaseSchema = z.object({
|
|
|
2559
2585
|
if (val === ".") {
|
|
2560
2586
|
ctx.addIssue({
|
|
2561
2587
|
code: z.ZodIssueCode.custom,
|
|
2562
|
-
message: `path cannot be '.'. Please use '/' or '' instead.
|
|
2588
|
+
message: "Invalid `path` property. `path` cannot be '.'. Please use '/' or '' instead."
|
|
2563
2589
|
});
|
|
2564
2590
|
}
|
|
2565
2591
|
}),
|
|
2566
|
-
format: z.enum(
|
|
2592
|
+
format: z.enum(CONTENT_FORMATS).optional(),
|
|
2567
2593
|
isAuthCollection: z.boolean().optional(),
|
|
2568
2594
|
isDetached: z.boolean().optional()
|
|
2569
2595
|
});
|
|
2570
2596
|
const TinaCloudCollection = CollectionBaseSchema.extend({
|
|
2571
|
-
fields: z.array(TinaFieldZod).min(1).optional().superRefine((val, ctx) => {
|
|
2597
|
+
fields: z.array(TinaFieldZod).min(1, "Property `fields` cannot be empty.").optional().superRefine((val, ctx) => {
|
|
2572
2598
|
const dups = findDuplicates(val == null ? void 0 : val.map((x) => x.name));
|
|
2573
2599
|
if (dups) {
|
|
2574
2600
|
ctx.addIssue({
|
|
2575
2601
|
code: z.ZodIssueCode.custom,
|
|
2576
|
-
message:
|
|
2602
|
+
message: duplicateFieldErrorMessage(dups)
|
|
2577
2603
|
});
|
|
2578
2604
|
}
|
|
2579
|
-
}).
|
|
2580
|
-
|
|
2581
|
-
(
|
|
2582
|
-
|
|
2583
|
-
|
|
2584
|
-
|
|
2585
|
-
|
|
2586
|
-
message: "Fields can only have one use of `isTitle`"
|
|
2587
|
-
}
|
|
2588
|
-
).refine(
|
|
2589
|
-
// It is valid if it is 0 or 1
|
|
2590
|
-
(val) => {
|
|
2591
|
-
const arr = (val == null ? void 0 : val.filter((x) => x.uid)) || [];
|
|
2592
|
-
return arr.length < 2;
|
|
2593
|
-
},
|
|
2594
|
-
{
|
|
2595
|
-
message: "Fields can only have one use of `uid`"
|
|
2596
|
-
}
|
|
2597
|
-
).refine(
|
|
2598
|
-
// It is valid if it is 0 or 1
|
|
2599
|
-
(val) => {
|
|
2600
|
-
const arr = (val == null ? void 0 : val.filter((x) => x.type === "password")) || [];
|
|
2601
|
-
return arr.length < 2;
|
|
2602
|
-
},
|
|
2603
|
-
{
|
|
2604
|
-
message: "Fields can only have one use of `password` type"
|
|
2605
|
+
}).superRefine((val, ctx) => {
|
|
2606
|
+
const arr = (val == null ? void 0 : val.filter((x) => x.type === "string" && x.isTitle)) || [];
|
|
2607
|
+
if (arr.length > 1) {
|
|
2608
|
+
ctx.addIssue({
|
|
2609
|
+
code: z.ZodIssueCode.custom,
|
|
2610
|
+
message: `The following fields have the property \`isTitle\`: [${arr.map((field) => field.name).join(", ")}]. Only one can contain the property \`isTitle\`.`
|
|
2611
|
+
});
|
|
2605
2612
|
}
|
|
2606
|
-
),
|
|
2607
|
-
|
|
2613
|
+
}).superRefine((val, ctx) => {
|
|
2614
|
+
const arr = (val == null ? void 0 : val.filter((x) => x.uid)) || [];
|
|
2615
|
+
if (arr.length > 2) {
|
|
2616
|
+
ctx.addIssue({
|
|
2617
|
+
code: z.ZodIssueCode.custom,
|
|
2618
|
+
message: `The following fields have the property \`uid\`: [${arr.map((field) => field.name).join(", ")}]. Only one can contain the property \`uid\`.`
|
|
2619
|
+
});
|
|
2620
|
+
}
|
|
2621
|
+
}).superRefine((val, ctx) => {
|
|
2622
|
+
const arr = (val == null ? void 0 : val.filter((x) => x.type === "password")) || [];
|
|
2623
|
+
if (arr.length > 2) {
|
|
2624
|
+
ctx.addIssue({
|
|
2625
|
+
code: z.ZodIssueCode.custom,
|
|
2626
|
+
message: `The following fields have \`type: password\`: [${arr.map((field) => field.name).join(", ")}]. Only one can be of \`type: password\`.`
|
|
2627
|
+
});
|
|
2628
|
+
}
|
|
2629
|
+
}),
|
|
2630
|
+
templates: z.array(Template).min(1, "Property `templates` cannot be empty.").optional().superRefine((val, ctx) => {
|
|
2608
2631
|
const dups = findDuplicates(val == null ? void 0 : val.map((x) => x.name));
|
|
2609
2632
|
if (dups) {
|
|
2610
2633
|
ctx.addIssue({
|
|
2611
2634
|
code: z.ZodIssueCode.custom,
|
|
2612
|
-
message:
|
|
2635
|
+
message: duplicateFieldErrorMessage(dups)
|
|
2613
2636
|
});
|
|
2614
2637
|
}
|
|
2615
2638
|
})
|
|
2616
|
-
}).
|
|
2617
|
-
(val)
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
}
|
|
2622
|
-
|
|
2623
|
-
|
|
2624
|
-
|
|
2625
|
-
|
|
2626
|
-
|
|
2627
|
-
|
|
2639
|
+
}).superRefine((val, ctx) => {
|
|
2640
|
+
if (!(val == null ? void 0 : val.templates) && !(val == null ? void 0 : val.fields)) {
|
|
2641
|
+
ctx.addIssue({
|
|
2642
|
+
code: z.ZodIssueCode.custom,
|
|
2643
|
+
message: "Fields of `type: object` must have either `templates` or `fields` property."
|
|
2644
|
+
});
|
|
2645
|
+
return false;
|
|
2646
|
+
}
|
|
2647
|
+
if ((val == null ? void 0 : val.templates) && (val == null ? void 0 : val.fields)) {
|
|
2648
|
+
ctx.addIssue({
|
|
2649
|
+
code: z.ZodIssueCode.custom,
|
|
2650
|
+
message: "Fields of `type: object` must have either `templates` or `fields` property, not both."
|
|
2651
|
+
});
|
|
2652
|
+
return false;
|
|
2653
|
+
}
|
|
2654
|
+
});
|
|
2628
2655
|
const TinaCloudSchemaZod = z.object({
|
|
2629
2656
|
collections: z.array(TinaCloudCollection),
|
|
2630
2657
|
config: tinaConfigZod.optional()
|
|
@@ -2634,14 +2661,14 @@ const TinaCloudSchemaZod = z.object({
|
|
|
2634
2661
|
if (dups) {
|
|
2635
2662
|
ctx.addIssue({
|
|
2636
2663
|
code: z.ZodIssueCode.custom,
|
|
2637
|
-
message:
|
|
2664
|
+
message: duplicateCollectionErrorMessage(dups),
|
|
2638
2665
|
fatal: true
|
|
2639
2666
|
});
|
|
2640
2667
|
}
|
|
2641
2668
|
if (((_b = val.collections) == null ? void 0 : _b.filter((x) => x.isAuthCollection).length) > 1) {
|
|
2642
2669
|
ctx.addIssue({
|
|
2643
2670
|
code: z.ZodIssueCode.custom,
|
|
2644
|
-
message:
|
|
2671
|
+
message: "Only one collection can be marked as `isAuthCollection`.",
|
|
2645
2672
|
fatal: true
|
|
2646
2673
|
});
|
|
2647
2674
|
}
|
|
@@ -2649,7 +2676,7 @@ const TinaCloudSchemaZod = z.object({
|
|
|
2649
2676
|
if (media && media.tina && media.loadCustomStore) {
|
|
2650
2677
|
ctx.addIssue({
|
|
2651
2678
|
code: z.ZodIssueCode.custom,
|
|
2652
|
-
message: "
|
|
2679
|
+
message: "Cannot have both `loadCustomStore` and `tina`. Must use one or the other.",
|
|
2653
2680
|
fatal: true,
|
|
2654
2681
|
path: ["config", "media"]
|
|
2655
2682
|
});
|
|
@@ -2658,7 +2685,7 @@ const TinaCloudSchemaZod = z.object({
|
|
|
2658
2685
|
if (search && search.tina && search.searchClient) {
|
|
2659
2686
|
ctx.addIssue({
|
|
2660
2687
|
code: z.ZodIssueCode.custom,
|
|
2661
|
-
message: "
|
|
2688
|
+
message: "Cannot have both `searchClient` and `tina`. Must use one or the other.",
|
|
2662
2689
|
fatal: true,
|
|
2663
2690
|
path: ["config", "search"]
|
|
2664
2691
|
});
|
|
@@ -2676,7 +2703,7 @@ const validateSchema = ({ schema }) => {
|
|
|
2676
2703
|
} catch (e) {
|
|
2677
2704
|
if (e instanceof ZodError) {
|
|
2678
2705
|
const errors = parseZodError({ zodError: e });
|
|
2679
|
-
throw new TinaSchemaValidationError(errors.join("
|
|
2706
|
+
throw new TinaSchemaValidationError(errors.join("\n"));
|
|
2680
2707
|
}
|
|
2681
2708
|
throw new Error(e);
|
|
2682
2709
|
}
|
|
@@ -28,6 +28,7 @@ export declare class TinaSchema {
|
|
|
28
28
|
} & Schema);
|
|
29
29
|
getIsTitleFieldName: (collection: string) => string;
|
|
30
30
|
getCollectionsByName: (collectionNames: string[]) => Collection<true>[];
|
|
31
|
+
findReferencesFromCollection(name: string): Record<string, string[]>;
|
|
31
32
|
getCollection: (collectionName: string) => Collection<true>;
|
|
32
33
|
getCollections: () => Collection<true>[];
|
|
33
34
|
getCollectionByFullPath: (filepath: string) => Collection<true>;
|
|
@@ -59,7 +60,26 @@ export declare class TinaSchema {
|
|
|
59
60
|
*
|
|
60
61
|
*/
|
|
61
62
|
getTemplatesForCollectable: (collection: Collectable) => CollectionTemplateable;
|
|
62
|
-
|
|
63
|
+
/**
|
|
64
|
+
* Walk all fields in tina schema
|
|
65
|
+
*
|
|
66
|
+
* @param cb callback function invoked for each field
|
|
67
|
+
*/
|
|
68
|
+
walkFields(cb: (args: {
|
|
69
|
+
field: any;
|
|
70
|
+
collection: any;
|
|
71
|
+
path: string;
|
|
72
|
+
isListItem?: boolean;
|
|
73
|
+
}) => void): void;
|
|
74
|
+
/**
|
|
75
|
+
* Walk all fields in Tina Schema
|
|
76
|
+
*
|
|
77
|
+
* This is a legacy version to preserve backwards compatibility for the tina generated schema. It does not
|
|
78
|
+
* traverse fields in object lists in rich-text templates.
|
|
79
|
+
*
|
|
80
|
+
* @param cb callback function invoked for each field
|
|
81
|
+
*/
|
|
82
|
+
legacyWalkFields: (cb: (args: {
|
|
63
83
|
field: TinaField;
|
|
64
84
|
collection: Collection;
|
|
65
85
|
path: string[];
|
|
@@ -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 {};
|