@tinacms/schema-tools 0.0.0-ecea7ac-20241011043815 → 0.0.0-ed6025e-20251201040055
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 +234 -176
- package/dist/index.mjs +234 -176
- package/dist/schema/TinaSchema.d.ts +21 -1
- package/dist/schema/addNamespaceToSchema.d.ts +8 -4
- package/dist/types/index.d.ts +73 -25
- package/dist/util/normalizePath.d.ts +8 -0
- package/dist/validate/fields.d.ts +0 -3
- package/dist/validate/schema.d.ts +101 -39
- package/dist/validate/tinaCloudSchemaConfig.d.ts +37 -0
- package/dist/validate/util.d.ts +3 -0
- package/package.json +8 -9
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;
|
|
@@ -1680,6 +1664,9 @@
|
|
|
1680
1664
|
};
|
|
1681
1665
|
};
|
|
1682
1666
|
const normalizePath = (filepath) => filepath.replace(/\\/g, "/");
|
|
1667
|
+
const canonicalPath = (filepath) => {
|
|
1668
|
+
return normalizePath(filepath).split("/").filter((name2) => name2 !== "").join("/");
|
|
1669
|
+
};
|
|
1683
1670
|
class TinaSchema {
|
|
1684
1671
|
/**
|
|
1685
1672
|
* Create a schema class from a user defined schema object
|
|
@@ -1729,21 +1716,21 @@
|
|
|
1729
1716
|
};
|
|
1730
1717
|
this.getCollectionByFullPath = (filepath) => {
|
|
1731
1718
|
const fileExtension = filepath.split(".").pop();
|
|
1732
|
-
const
|
|
1719
|
+
const canonicalFilepath = canonicalPath(filepath);
|
|
1733
1720
|
const possibleCollections = this.getCollections().filter((collection) => {
|
|
1734
1721
|
var _a, _b;
|
|
1735
|
-
if (!
|
|
1722
|
+
if (!canonicalFilepath.endsWith(`.gitkeep.${collection.format || "md"}`) && fileExtension !== (collection.format || "md")) {
|
|
1736
1723
|
return false;
|
|
1737
1724
|
}
|
|
1738
1725
|
if (((_a = collection == null ? void 0 : collection.match) == null ? void 0 : _a.include) || ((_b = collection == null ? void 0 : collection.match) == null ? void 0 : _b.exclude)) {
|
|
1739
1726
|
const matches = this.getMatches({ collection });
|
|
1740
|
-
const match = picomatch$1.isMatch(
|
|
1727
|
+
const match = picomatch$1.isMatch(canonicalFilepath, matches);
|
|
1741
1728
|
if (!match) {
|
|
1742
1729
|
return false;
|
|
1743
1730
|
}
|
|
1744
1731
|
}
|
|
1745
|
-
const
|
|
1746
|
-
return
|
|
1732
|
+
const collectionPath = canonicalPath(collection.path);
|
|
1733
|
+
return collectionPath === "" || canonicalFilepath.startsWith(`${collectionPath}/`);
|
|
1747
1734
|
});
|
|
1748
1735
|
if (possibleCollections.length === 0) {
|
|
1749
1736
|
throw new Error(`Unable to find collection for file at ${filepath}`);
|
|
@@ -1961,7 +1948,7 @@
|
|
|
1961
1948
|
}
|
|
1962
1949
|
}
|
|
1963
1950
|
};
|
|
1964
|
-
this.
|
|
1951
|
+
this.legacyWalkFields = (cb) => {
|
|
1965
1952
|
const walk = (collectionOrObject, collection, path) => {
|
|
1966
1953
|
if (collectionOrObject.templates) {
|
|
1967
1954
|
collectionOrObject.templates.forEach((template) => {
|
|
@@ -1983,7 +1970,7 @@
|
|
|
1983
1970
|
collections.forEach((collection) => walk(collection, collection, []));
|
|
1984
1971
|
};
|
|
1985
1972
|
this.schema = config;
|
|
1986
|
-
this.
|
|
1973
|
+
this.legacyWalkFields(({ field, collection }) => {
|
|
1987
1974
|
if (!("searchable" in field)) {
|
|
1988
1975
|
if (field.type === "image") {
|
|
1989
1976
|
field.searchable = false;
|
|
@@ -2004,6 +1991,67 @@
|
|
|
2004
1991
|
field.uid = field.uid || false;
|
|
2005
1992
|
});
|
|
2006
1993
|
}
|
|
1994
|
+
findReferencesFromCollection(name2) {
|
|
1995
|
+
const result = {};
|
|
1996
|
+
this.walkFields(({ field, collection: c, path }) => {
|
|
1997
|
+
if (c.name !== name2) {
|
|
1998
|
+
return;
|
|
1999
|
+
}
|
|
2000
|
+
if (field.type === "reference") {
|
|
2001
|
+
field.collections.forEach((name22) => {
|
|
2002
|
+
if (result[name22] === void 0) {
|
|
2003
|
+
result[name22] = [];
|
|
2004
|
+
}
|
|
2005
|
+
result[name22].push(path);
|
|
2006
|
+
});
|
|
2007
|
+
}
|
|
2008
|
+
});
|
|
2009
|
+
return result;
|
|
2010
|
+
}
|
|
2011
|
+
/**
|
|
2012
|
+
* Walk all fields in tina schema
|
|
2013
|
+
*
|
|
2014
|
+
* @param cb callback function invoked for each field
|
|
2015
|
+
*/
|
|
2016
|
+
walkFields(cb) {
|
|
2017
|
+
const walk = (collectionOrObject, collection, path = "$") => {
|
|
2018
|
+
if (collectionOrObject.templates) {
|
|
2019
|
+
collectionOrObject.templates.forEach((template) => {
|
|
2020
|
+
const templatePath = `${path}.${template.name}`;
|
|
2021
|
+
template.fields.forEach((field) => {
|
|
2022
|
+
const fieldPath = field.list ? `${templatePath}[*].${field.name}` : `${templatePath}.${field.name}`;
|
|
2023
|
+
cb({ field, collection, path: fieldPath });
|
|
2024
|
+
if (field.type === "object") {
|
|
2025
|
+
walk(field, collection, fieldPath);
|
|
2026
|
+
}
|
|
2027
|
+
});
|
|
2028
|
+
});
|
|
2029
|
+
}
|
|
2030
|
+
if (collectionOrObject.fields) {
|
|
2031
|
+
collectionOrObject.fields.forEach((field) => {
|
|
2032
|
+
const fieldPath = field.list ? `${path}.${field.name}[*]` : `${path}.${field.name}`;
|
|
2033
|
+
cb({ field, collection, path: fieldPath });
|
|
2034
|
+
if (field.type === "object" && field.fields) {
|
|
2035
|
+
walk(field, collection, fieldPath);
|
|
2036
|
+
} else if (field.templates) {
|
|
2037
|
+
field.templates.forEach((template) => {
|
|
2038
|
+
const templatePath = `${fieldPath}.${template.name}`;
|
|
2039
|
+
template.fields.forEach((field2) => {
|
|
2040
|
+
const fieldPath2 = field2.list ? `${templatePath}[*].${field2.name}` : `${templatePath}.${field2.name}`;
|
|
2041
|
+
cb({ field: field2, collection, path: fieldPath2 });
|
|
2042
|
+
if (field2.type === "object") {
|
|
2043
|
+
walk(field2, collection, fieldPath2);
|
|
2044
|
+
}
|
|
2045
|
+
});
|
|
2046
|
+
});
|
|
2047
|
+
}
|
|
2048
|
+
});
|
|
2049
|
+
}
|
|
2050
|
+
};
|
|
2051
|
+
this.getCollections().forEach((collection) => {
|
|
2052
|
+
walk(collection, collection);
|
|
2053
|
+
});
|
|
2054
|
+
}
|
|
2007
2055
|
/**
|
|
2008
2056
|
* This function returns an array of glob matches for a given collection.
|
|
2009
2057
|
*
|
|
@@ -2015,16 +2063,16 @@
|
|
|
2015
2063
|
}) {
|
|
2016
2064
|
var _a, _b;
|
|
2017
2065
|
const collection = typeof collectionOrString === "string" ? this.getCollection(collectionOrString) : collectionOrString;
|
|
2018
|
-
const
|
|
2019
|
-
const pathSuffix =
|
|
2066
|
+
const collectionPath = canonicalPath(collection.path);
|
|
2067
|
+
const pathSuffix = collectionPath ? "/" : "";
|
|
2020
2068
|
const format = collection.format || "md";
|
|
2021
2069
|
const matches = [];
|
|
2022
2070
|
if ((_a = collection == null ? void 0 : collection.match) == null ? void 0 : _a.include) {
|
|
2023
|
-
const match = `${
|
|
2071
|
+
const match = `${collectionPath}${pathSuffix}${collection.match.include}.${format}`;
|
|
2024
2072
|
matches.push(match);
|
|
2025
2073
|
}
|
|
2026
2074
|
if ((_b = collection == null ? void 0 : collection.match) == null ? void 0 : _b.exclude) {
|
|
2027
|
-
const exclude = `!(${
|
|
2075
|
+
const exclude = `!(${collectionPath}${pathSuffix}${collection.match.exclude}.${format})`;
|
|
2028
2076
|
matches.push(exclude);
|
|
2029
2077
|
}
|
|
2030
2078
|
return matches;
|
|
@@ -2217,6 +2265,15 @@
|
|
|
2217
2265
|
})
|
|
2218
2266
|
};
|
|
2219
2267
|
};
|
|
2268
|
+
const CONTENT_FORMATS = [
|
|
2269
|
+
"mdx",
|
|
2270
|
+
"md",
|
|
2271
|
+
"markdown",
|
|
2272
|
+
"json",
|
|
2273
|
+
"yaml",
|
|
2274
|
+
"yml",
|
|
2275
|
+
"toml"
|
|
2276
|
+
];
|
|
2220
2277
|
const parseZodError = ({ zodError }) => {
|
|
2221
2278
|
var _a, _b, _c, _d;
|
|
2222
2279
|
const errors = zodError.flatten((issue) => {
|
|
@@ -2226,9 +2283,12 @@
|
|
|
2226
2283
|
moreInfo.push(parseZodError({ zodError: unionError }));
|
|
2227
2284
|
});
|
|
2228
2285
|
}
|
|
2229
|
-
const errorMessage =
|
|
2286
|
+
const errorMessage = `${issue == null ? void 0 : issue.message}
|
|
2287
|
+
Additional information:
|
|
2288
|
+
- Error found at path ${issue.path.join(
|
|
2230
2289
|
"."
|
|
2231
|
-
)}
|
|
2290
|
+
)}
|
|
2291
|
+
`;
|
|
2232
2292
|
const errorMessages = [errorMessage, ...moreInfo];
|
|
2233
2293
|
return {
|
|
2234
2294
|
errors: errorMessages
|
|
@@ -2263,6 +2323,9 @@ If you need to use this value in your content you can use the \`nameOverride\` p
|
|
|
2263
2323
|
});
|
|
2264
2324
|
}
|
|
2265
2325
|
});
|
|
2326
|
+
const duplicateFieldErrorMessage = (fields) => `Fields must have unique names. Found duplicate field names: [${fields}]`;
|
|
2327
|
+
const duplicateTemplateErrorMessage = (templates) => `Templates must have unique names. Found duplicate template names: [${templates}]`;
|
|
2328
|
+
const duplicateCollectionErrorMessage = (collection) => `Collections must have unique names. Found duplicate collection names: [${collection}]`;
|
|
2266
2329
|
const TypeName = [
|
|
2267
2330
|
"string",
|
|
2268
2331
|
"boolean",
|
|
@@ -2273,10 +2336,11 @@ If you need to use this value in your content you can use the \`nameOverride\` p
|
|
|
2273
2336
|
"reference",
|
|
2274
2337
|
"rich-text"
|
|
2275
2338
|
];
|
|
2276
|
-
const
|
|
2277
|
-
const
|
|
2278
|
-
|
|
2279
|
-
|
|
2339
|
+
const formattedTypes = ` - ${TypeName.join("\n - ")}`;
|
|
2340
|
+
const typeTypeError = `Invalid \`type\` property. \`type\` expected to be one of the following values:
|
|
2341
|
+
${formattedTypes}`;
|
|
2342
|
+
const typeRequiredError = `Missing \`type\` property. Please add a \`type\` property with one of the following:
|
|
2343
|
+
${formattedTypes}`;
|
|
2280
2344
|
const Option = z.z.union(
|
|
2281
2345
|
[
|
|
2282
2346
|
z.z.string(),
|
|
@@ -2331,7 +2395,8 @@ If you need to use this value in your content you can use the \`nameOverride\` p
|
|
|
2331
2395
|
type: z.z.literal("image", {
|
|
2332
2396
|
invalid_type_error: typeTypeError,
|
|
2333
2397
|
required_error: typeRequiredError
|
|
2334
|
-
})
|
|
2398
|
+
}),
|
|
2399
|
+
uploadDir: z.z.function().args(z.z.any()).returns(z.z.string()).optional()
|
|
2335
2400
|
});
|
|
2336
2401
|
const DateTimeField = TinaScalerBase.extend({
|
|
2337
2402
|
type: z.z.literal("datetime", {
|
|
@@ -2362,7 +2427,7 @@ If you need to use this value in your content you can use the \`nameOverride\` p
|
|
|
2362
2427
|
if (dups) {
|
|
2363
2428
|
ctx.addIssue({
|
|
2364
2429
|
code: z.z.ZodIssueCode.custom,
|
|
2365
|
-
message:
|
|
2430
|
+
message: duplicateFieldErrorMessage(dups)
|
|
2366
2431
|
});
|
|
2367
2432
|
}
|
|
2368
2433
|
});
|
|
@@ -2372,21 +2437,21 @@ If you need to use this value in your content you can use the \`nameOverride\` p
|
|
|
2372
2437
|
invalid_type_error: typeTypeError,
|
|
2373
2438
|
required_error: typeRequiredError
|
|
2374
2439
|
}),
|
|
2375
|
-
fields: z.z.array(TinaFieldZod).min(1).optional().superRefine((val, ctx) => {
|
|
2440
|
+
fields: z.z.array(TinaFieldZod).min(1, "Property `fields` cannot be empty.").optional().superRefine((val, ctx) => {
|
|
2376
2441
|
const dups = findDuplicates(val == null ? void 0 : val.map((x) => x.name));
|
|
2377
2442
|
if (dups) {
|
|
2378
2443
|
ctx.addIssue({
|
|
2379
2444
|
code: z.z.ZodIssueCode.custom,
|
|
2380
|
-
message:
|
|
2445
|
+
message: duplicateFieldErrorMessage(dups)
|
|
2381
2446
|
});
|
|
2382
2447
|
}
|
|
2383
2448
|
}),
|
|
2384
|
-
templates: z.z.array(TemplateTemp).min(1).optional().superRefine((val, ctx) => {
|
|
2449
|
+
templates: z.z.array(TemplateTemp).min(1, "Property `templates` cannot be empty.").optional().superRefine((val, ctx) => {
|
|
2385
2450
|
const dups = findDuplicates(val == null ? void 0 : val.map((x) => x.name));
|
|
2386
2451
|
if (dups) {
|
|
2387
2452
|
ctx.addIssue({
|
|
2388
2453
|
code: z.z.ZodIssueCode.custom,
|
|
2389
|
-
message:
|
|
2454
|
+
message: duplicateTemplateErrorMessage(dups)
|
|
2390
2455
|
});
|
|
2391
2456
|
}
|
|
2392
2457
|
})
|
|
@@ -2401,7 +2466,7 @@ If you need to use this value in your content you can use the \`nameOverride\` p
|
|
|
2401
2466
|
if (dups) {
|
|
2402
2467
|
ctx.addIssue({
|
|
2403
2468
|
code: z.z.ZodIssueCode.custom,
|
|
2404
|
-
message:
|
|
2469
|
+
message: duplicateTemplateErrorMessage(dups)
|
|
2405
2470
|
});
|
|
2406
2471
|
}
|
|
2407
2472
|
})
|
|
@@ -2421,10 +2486,17 @@ If you need to use this value in your content you can use the \`nameOverride\` p
|
|
|
2421
2486
|
],
|
|
2422
2487
|
{
|
|
2423
2488
|
errorMap: (issue, ctx) => {
|
|
2424
|
-
var _a;
|
|
2489
|
+
var _a, _b;
|
|
2425
2490
|
if (issue.code === "invalid_union_discriminator") {
|
|
2491
|
+
if (!((_a = ctx.data) == null ? void 0 : _a.type)) {
|
|
2492
|
+
return {
|
|
2493
|
+
message: `Missing \`type\` property in field \`${ctx.data.name}\`. Please add a \`type\` property with one of the following:
|
|
2494
|
+
${formattedTypes}`
|
|
2495
|
+
};
|
|
2496
|
+
}
|
|
2426
2497
|
return {
|
|
2427
|
-
message: `Invalid \`type\` property. In the schema is 'type: ${(
|
|
2498
|
+
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:
|
|
2499
|
+
${formattedTypes}`
|
|
2428
2500
|
};
|
|
2429
2501
|
}
|
|
2430
2502
|
return {
|
|
@@ -2434,77 +2506,52 @@ If you need to use this value in your content you can use the \`nameOverride\` p
|
|
|
2434
2506
|
}
|
|
2435
2507
|
).superRefine((val, ctx) => {
|
|
2436
2508
|
if (val.type === "string") {
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
${
|
|
2443
|
-
|
|
2444
|
-
null,
|
|
2445
|
-
2
|
|
2446
|
-
)}
|
|
2447
|
-
`
|
|
2448
|
-
});
|
|
2449
|
-
}
|
|
2450
|
-
if (!val.required) {
|
|
2451
|
-
ctx.addIssue({
|
|
2452
|
-
code: z.z.ZodIssueCode.custom,
|
|
2453
|
-
message: `Must have { required: true } when using \`isTitle\` Error in value
|
|
2454
|
-
${JSON.stringify(
|
|
2455
|
-
val,
|
|
2456
|
-
null,
|
|
2457
|
-
2
|
|
2458
|
-
)}
|
|
2459
|
-
`
|
|
2460
|
-
});
|
|
2461
|
-
}
|
|
2509
|
+
const stringifiedField = JSON.stringify(val, null, 2);
|
|
2510
|
+
if (val.isTitle && val.list) {
|
|
2511
|
+
ctx.addIssue({
|
|
2512
|
+
code: z.z.ZodIssueCode.custom,
|
|
2513
|
+
message: `\`list: true\` is not allowed when using \`isTitle\` for fields of \`type: string\`. Error found in field:
|
|
2514
|
+
${stringifiedField}`
|
|
2515
|
+
});
|
|
2462
2516
|
}
|
|
2463
|
-
if (val.
|
|
2517
|
+
if (val.isTitle && !val.required) {
|
|
2518
|
+
ctx.addIssue({
|
|
2519
|
+
code: z.z.ZodIssueCode.custom,
|
|
2520
|
+
message: `Property \`required: true\` is required when using \`isTitle\` for fields of \`type: string\`. Error found in field:
|
|
2521
|
+
${stringifiedField}`
|
|
2522
|
+
});
|
|
2523
|
+
}
|
|
2524
|
+
if (val.uid && val.list) {
|
|
2464
2525
|
if (val.list) {
|
|
2465
2526
|
ctx.addIssue({
|
|
2466
2527
|
code: z.z.ZodIssueCode.custom,
|
|
2467
|
-
message:
|
|
2468
|
-
${
|
|
2469
|
-
val,
|
|
2470
|
-
null,
|
|
2471
|
-
2
|
|
2472
|
-
)}
|
|
2473
|
-
`
|
|
2474
|
-
});
|
|
2475
|
-
}
|
|
2476
|
-
if (!val.required) {
|
|
2477
|
-
ctx.addIssue({
|
|
2478
|
-
code: z.z.ZodIssueCode.custom,
|
|
2479
|
-
message: `Must have { required: true } when using \`uid\` Error in value
|
|
2480
|
-
${JSON.stringify(
|
|
2481
|
-
val,
|
|
2482
|
-
null,
|
|
2483
|
-
2
|
|
2484
|
-
)}
|
|
2485
|
-
`
|
|
2528
|
+
message: `\`list: true\` is not allowed when using \`uid\` for fields of \`type: string\`. Error found in field:
|
|
2529
|
+
${stringifiedField}`
|
|
2486
2530
|
});
|
|
2487
2531
|
}
|
|
2488
2532
|
}
|
|
2533
|
+
if (val.uid && !val.required) {
|
|
2534
|
+
ctx.addIssue({
|
|
2535
|
+
code: z.z.ZodIssueCode.custom,
|
|
2536
|
+
message: `Property \`required: true\` is required when using \`uid\` for fields of \`type: string\`. Error found in field:
|
|
2537
|
+
${stringifiedField}`
|
|
2538
|
+
});
|
|
2539
|
+
}
|
|
2489
2540
|
}
|
|
2490
2541
|
if (val.type === "object") {
|
|
2491
|
-
|
|
2492
|
-
let isValid = Boolean(val == null ? void 0 : val.templates) || Boolean(val == null ? void 0 : val.fields);
|
|
2493
|
-
if (!isValid) {
|
|
2542
|
+
if (!(val == null ? void 0 : val.templates) && !(val == null ? void 0 : val.fields)) {
|
|
2494
2543
|
ctx.addIssue({
|
|
2495
2544
|
code: z.z.ZodIssueCode.custom,
|
|
2496
|
-
message
|
|
2545
|
+
message: "Fields of `type: object` must have either `templates` or `fields` property."
|
|
2546
|
+
});
|
|
2547
|
+
return false;
|
|
2548
|
+
}
|
|
2549
|
+
if ((val == null ? void 0 : val.templates) && (val == null ? void 0 : val.fields)) {
|
|
2550
|
+
ctx.addIssue({
|
|
2551
|
+
code: z.z.ZodIssueCode.custom,
|
|
2552
|
+
message: "Fields of `type: object` must have either `templates` or `fields` property, not both."
|
|
2497
2553
|
});
|
|
2498
2554
|
return false;
|
|
2499
|
-
} else {
|
|
2500
|
-
isValid = !((val == null ? void 0 : val.templates) && (val == null ? void 0 : val.fields));
|
|
2501
|
-
if (!isValid) {
|
|
2502
|
-
ctx.addIssue({
|
|
2503
|
-
code: z.z.ZodIssueCode.custom,
|
|
2504
|
-
message
|
|
2505
|
-
});
|
|
2506
|
-
}
|
|
2507
|
-
return isValid;
|
|
2508
2555
|
}
|
|
2509
2556
|
}
|
|
2510
2557
|
return true;
|
|
@@ -2531,25 +2578,33 @@ ${JSON.stringify(
|
|
|
2531
2578
|
searchClient: z.any().optional(),
|
|
2532
2579
|
indexBatchSize: z.number().gte(1).optional(),
|
|
2533
2580
|
maxSearchIndexFieldLength: z.number().gte(1).optional()
|
|
2581
|
+
}).optional(),
|
|
2582
|
+
ui: z.object({
|
|
2583
|
+
previewUrl: z.function().optional(),
|
|
2584
|
+
optOutOfUpdateCheck: z.boolean().optional(),
|
|
2585
|
+
regexValidation: z.object({
|
|
2586
|
+
folderNameRegex: z.string().refine(
|
|
2587
|
+
(val) => {
|
|
2588
|
+
try {
|
|
2589
|
+
new RegExp(val);
|
|
2590
|
+
return true;
|
|
2591
|
+
} catch (error) {
|
|
2592
|
+
return false;
|
|
2593
|
+
}
|
|
2594
|
+
},
|
|
2595
|
+
{ message: "folderNameRegex is not a valid regex pattern" }
|
|
2596
|
+
).optional()
|
|
2597
|
+
}).optional()
|
|
2534
2598
|
}).optional()
|
|
2535
2599
|
});
|
|
2536
2600
|
const validateTinaCloudSchemaConfig = (config) => {
|
|
2537
2601
|
const newConfig = tinaConfigZod.parse(config);
|
|
2538
2602
|
return newConfig;
|
|
2539
2603
|
};
|
|
2540
|
-
const FORMATS = [
|
|
2541
|
-
"json",
|
|
2542
|
-
"md",
|
|
2543
|
-
"markdown",
|
|
2544
|
-
"mdx",
|
|
2545
|
-
"toml",
|
|
2546
|
-
"yaml",
|
|
2547
|
-
"yml"
|
|
2548
|
-
];
|
|
2549
2604
|
const Template = z.z.object({
|
|
2550
2605
|
label: z.z.string({
|
|
2551
|
-
invalid_type_error: "label
|
|
2552
|
-
required_error: "label
|
|
2606
|
+
invalid_type_error: "Invalid data type for property `label`. Must be of type `string`",
|
|
2607
|
+
required_error: "Missing `label` property. Property `label` is required."
|
|
2553
2608
|
}),
|
|
2554
2609
|
name,
|
|
2555
2610
|
fields: z.z.array(TinaFieldZod)
|
|
@@ -2559,7 +2614,7 @@ ${JSON.stringify(
|
|
|
2559
2614
|
if (dups) {
|
|
2560
2615
|
ctx.addIssue({
|
|
2561
2616
|
code: z.z.ZodIssueCode.custom,
|
|
2562
|
-
message:
|
|
2617
|
+
message: duplicateFieldErrorMessage(dups)
|
|
2563
2618
|
});
|
|
2564
2619
|
}
|
|
2565
2620
|
});
|
|
@@ -2569,7 +2624,7 @@ ${JSON.stringify(
|
|
|
2569
2624
|
if (val === "relativePath") {
|
|
2570
2625
|
ctx.addIssue({
|
|
2571
2626
|
code: z.z.ZodIssueCode.custom,
|
|
2572
|
-
message: `name cannot be 'relativePath'
|
|
2627
|
+
message: "Invalid `name` property. `name` cannot be 'relativePath' as it is a reserved field name."
|
|
2573
2628
|
});
|
|
2574
2629
|
}
|
|
2575
2630
|
}),
|
|
@@ -2577,72 +2632,73 @@ ${JSON.stringify(
|
|
|
2577
2632
|
if (val === ".") {
|
|
2578
2633
|
ctx.addIssue({
|
|
2579
2634
|
code: z.z.ZodIssueCode.custom,
|
|
2580
|
-
message: `path cannot be '.'. Please use '/' or '' instead.
|
|
2635
|
+
message: "Invalid `path` property. `path` cannot be '.'. Please use '/' or '' instead."
|
|
2581
2636
|
});
|
|
2582
2637
|
}
|
|
2583
2638
|
}),
|
|
2584
|
-
format: z.z.enum(
|
|
2639
|
+
format: z.z.enum(CONTENT_FORMATS).optional(),
|
|
2585
2640
|
isAuthCollection: z.z.boolean().optional(),
|
|
2586
2641
|
isDetached: z.z.boolean().optional()
|
|
2587
2642
|
});
|
|
2588
2643
|
const TinaCloudCollection = CollectionBaseSchema.extend({
|
|
2589
|
-
fields: z.z.array(TinaFieldZod).min(1).optional().superRefine((val, ctx) => {
|
|
2644
|
+
fields: z.z.array(TinaFieldZod).min(1, "Property `fields` cannot be empty.").optional().superRefine((val, ctx) => {
|
|
2590
2645
|
const dups = findDuplicates(val == null ? void 0 : val.map((x) => x.name));
|
|
2591
2646
|
if (dups) {
|
|
2592
2647
|
ctx.addIssue({
|
|
2593
2648
|
code: z.z.ZodIssueCode.custom,
|
|
2594
|
-
message:
|
|
2649
|
+
message: duplicateFieldErrorMessage(dups)
|
|
2595
2650
|
});
|
|
2596
2651
|
}
|
|
2597
|
-
}).
|
|
2598
|
-
|
|
2599
|
-
(
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
|
|
2605
|
-
|
|
2606
|
-
|
|
2607
|
-
|
|
2608
|
-
|
|
2609
|
-
|
|
2610
|
-
|
|
2611
|
-
|
|
2612
|
-
{
|
|
2613
|
-
message: "Fields can only have one use of `uid`"
|
|
2614
|
-
}
|
|
2615
|
-
).refine(
|
|
2616
|
-
// It is valid if it is 0 or 1
|
|
2617
|
-
(val) => {
|
|
2618
|
-
const arr = (val == null ? void 0 : val.filter((x) => x.type === "password")) || [];
|
|
2619
|
-
return arr.length < 2;
|
|
2620
|
-
},
|
|
2621
|
-
{
|
|
2622
|
-
message: "Fields can only have one use of `password` type"
|
|
2652
|
+
}).superRefine((val, ctx) => {
|
|
2653
|
+
const arr = (val == null ? void 0 : val.filter((x) => x.type === "string" && x.isTitle)) || [];
|
|
2654
|
+
if (arr.length > 1) {
|
|
2655
|
+
ctx.addIssue({
|
|
2656
|
+
code: z.z.ZodIssueCode.custom,
|
|
2657
|
+
message: `The following fields have the property \`isTitle\`: [${arr.map((field) => field.name).join(", ")}]. Only one can contain the property \`isTitle\`.`
|
|
2658
|
+
});
|
|
2659
|
+
}
|
|
2660
|
+
}).superRefine((val, ctx) => {
|
|
2661
|
+
const arr = (val == null ? void 0 : val.filter((x) => x.uid)) || [];
|
|
2662
|
+
if (arr.length > 2) {
|
|
2663
|
+
ctx.addIssue({
|
|
2664
|
+
code: z.z.ZodIssueCode.custom,
|
|
2665
|
+
message: `The following fields have the property \`uid\`: [${arr.map((field) => field.name).join(", ")}]. Only one can contain the property \`uid\`.`
|
|
2666
|
+
});
|
|
2623
2667
|
}
|
|
2624
|
-
),
|
|
2625
|
-
|
|
2668
|
+
}).superRefine((val, ctx) => {
|
|
2669
|
+
const arr = (val == null ? void 0 : val.filter((x) => x.type === "password")) || [];
|
|
2670
|
+
if (arr.length > 2) {
|
|
2671
|
+
ctx.addIssue({
|
|
2672
|
+
code: z.z.ZodIssueCode.custom,
|
|
2673
|
+
message: `The following fields have \`type: password\`: [${arr.map((field) => field.name).join(", ")}]. Only one can be of \`type: password\`.`
|
|
2674
|
+
});
|
|
2675
|
+
}
|
|
2676
|
+
}),
|
|
2677
|
+
templates: z.z.array(Template).min(1, "Property `templates` cannot be empty.").optional().superRefine((val, ctx) => {
|
|
2626
2678
|
const dups = findDuplicates(val == null ? void 0 : val.map((x) => x.name));
|
|
2627
2679
|
if (dups) {
|
|
2628
2680
|
ctx.addIssue({
|
|
2629
2681
|
code: z.z.ZodIssueCode.custom,
|
|
2630
|
-
message:
|
|
2682
|
+
message: duplicateFieldErrorMessage(dups)
|
|
2631
2683
|
});
|
|
2632
2684
|
}
|
|
2633
2685
|
})
|
|
2634
|
-
}).
|
|
2635
|
-
(val)
|
|
2636
|
-
|
|
2637
|
-
|
|
2638
|
-
|
|
2639
|
-
}
|
|
2640
|
-
|
|
2641
|
-
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
|
|
2645
|
-
|
|
2686
|
+
}).superRefine((val, ctx) => {
|
|
2687
|
+
if (!(val == null ? void 0 : val.templates) && !(val == null ? void 0 : val.fields)) {
|
|
2688
|
+
ctx.addIssue({
|
|
2689
|
+
code: z.z.ZodIssueCode.custom,
|
|
2690
|
+
message: "Fields of `type: object` must have either `templates` or `fields` property."
|
|
2691
|
+
});
|
|
2692
|
+
return false;
|
|
2693
|
+
}
|
|
2694
|
+
if ((val == null ? void 0 : val.templates) && (val == null ? void 0 : val.fields)) {
|
|
2695
|
+
ctx.addIssue({
|
|
2696
|
+
code: z.z.ZodIssueCode.custom,
|
|
2697
|
+
message: "Fields of `type: object` must have either `templates` or `fields` property, not both."
|
|
2698
|
+
});
|
|
2699
|
+
return false;
|
|
2700
|
+
}
|
|
2701
|
+
});
|
|
2646
2702
|
const TinaCloudSchemaZod = z.z.object({
|
|
2647
2703
|
collections: z.z.array(TinaCloudCollection),
|
|
2648
2704
|
config: tinaConfigZod.optional()
|
|
@@ -2652,14 +2708,14 @@ ${JSON.stringify(
|
|
|
2652
2708
|
if (dups) {
|
|
2653
2709
|
ctx.addIssue({
|
|
2654
2710
|
code: z.z.ZodIssueCode.custom,
|
|
2655
|
-
message:
|
|
2711
|
+
message: duplicateCollectionErrorMessage(dups),
|
|
2656
2712
|
fatal: true
|
|
2657
2713
|
});
|
|
2658
2714
|
}
|
|
2659
2715
|
if (((_b = val.collections) == null ? void 0 : _b.filter((x) => x.isAuthCollection).length) > 1) {
|
|
2660
2716
|
ctx.addIssue({
|
|
2661
2717
|
code: z.z.ZodIssueCode.custom,
|
|
2662
|
-
message:
|
|
2718
|
+
message: "Only one collection can be marked as `isAuthCollection`.",
|
|
2663
2719
|
fatal: true
|
|
2664
2720
|
});
|
|
2665
2721
|
}
|
|
@@ -2667,7 +2723,7 @@ ${JSON.stringify(
|
|
|
2667
2723
|
if (media && media.tina && media.loadCustomStore) {
|
|
2668
2724
|
ctx.addIssue({
|
|
2669
2725
|
code: z.z.ZodIssueCode.custom,
|
|
2670
|
-
message: "
|
|
2726
|
+
message: "Cannot have both `loadCustomStore` and `tina`. Must use one or the other.",
|
|
2671
2727
|
fatal: true,
|
|
2672
2728
|
path: ["config", "media"]
|
|
2673
2729
|
});
|
|
@@ -2676,7 +2732,7 @@ ${JSON.stringify(
|
|
|
2676
2732
|
if (search && search.tina && search.searchClient) {
|
|
2677
2733
|
ctx.addIssue({
|
|
2678
2734
|
code: z.z.ZodIssueCode.custom,
|
|
2679
|
-
message: "
|
|
2735
|
+
message: "Cannot have both `searchClient` and `tina`. Must use one or the other.",
|
|
2680
2736
|
fatal: true,
|
|
2681
2737
|
path: ["config", "search"]
|
|
2682
2738
|
});
|
|
@@ -2694,16 +2750,18 @@ ${JSON.stringify(
|
|
|
2694
2750
|
} catch (e) {
|
|
2695
2751
|
if (e instanceof z.ZodError) {
|
|
2696
2752
|
const errors = parseZodError({ zodError: e });
|
|
2697
|
-
throw new TinaSchemaValidationError(errors.join("
|
|
2753
|
+
throw new TinaSchemaValidationError(errors.join("\n"));
|
|
2698
2754
|
}
|
|
2699
2755
|
throw new Error(e);
|
|
2700
2756
|
}
|
|
2701
2757
|
};
|
|
2758
|
+
exports2.CONTENT_FORMATS = CONTENT_FORMATS;
|
|
2702
2759
|
exports2.NAMER = NAMER;
|
|
2703
2760
|
exports2.TINA_HOST = TINA_HOST;
|
|
2704
2761
|
exports2.TinaSchema = TinaSchema;
|
|
2705
2762
|
exports2.TinaSchemaValidationError = TinaSchemaValidationError;
|
|
2706
2763
|
exports2.addNamespaceToSchema = addNamespaceToSchema;
|
|
2764
|
+
exports2.canonicalPath = canonicalPath;
|
|
2707
2765
|
exports2.normalizePath = normalizePath;
|
|
2708
2766
|
exports2.parseURL = parseURL;
|
|
2709
2767
|
exports2.resolveField = resolveField;
|