@tinacms/schema-tools 0.0.0-d7c5ec1-20250219020924 → 0.0.0-d9487bf-20251119052214
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 +79 -27
- package/dist/index.mjs +79 -27
- package/dist/schema/TinaSchema.d.ts +21 -5
- package/dist/types/index.d.ts +41 -21
- package/dist/util/normalizePath.d.ts +8 -0
- package/dist/validate/schema.d.ts +36 -36
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1664,6 +1664,9 @@
|
|
|
1664
1664
|
};
|
|
1665
1665
|
};
|
|
1666
1666
|
const normalizePath = (filepath) => filepath.replace(/\\/g, "/");
|
|
1667
|
+
const canonicalPath = (filepath) => {
|
|
1668
|
+
return normalizePath(filepath).split("/").filter((name2) => name2 !== "").join("/");
|
|
1669
|
+
};
|
|
1667
1670
|
class TinaSchema {
|
|
1668
1671
|
/**
|
|
1669
1672
|
* Create a schema class from a user defined schema object
|
|
@@ -1713,21 +1716,21 @@
|
|
|
1713
1716
|
};
|
|
1714
1717
|
this.getCollectionByFullPath = (filepath) => {
|
|
1715
1718
|
const fileExtension = filepath.split(".").pop();
|
|
1716
|
-
const
|
|
1719
|
+
const canonicalFilepath = canonicalPath(filepath);
|
|
1717
1720
|
const possibleCollections = this.getCollections().filter((collection) => {
|
|
1718
1721
|
var _a, _b;
|
|
1719
|
-
if (!
|
|
1722
|
+
if (!canonicalFilepath.endsWith(`.gitkeep.${collection.format || "md"}`) && fileExtension !== (collection.format || "md")) {
|
|
1720
1723
|
return false;
|
|
1721
1724
|
}
|
|
1722
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)) {
|
|
1723
1726
|
const matches = this.getMatches({ collection });
|
|
1724
|
-
const match = picomatch$1.isMatch(
|
|
1727
|
+
const match = picomatch$1.isMatch(canonicalFilepath, matches);
|
|
1725
1728
|
if (!match) {
|
|
1726
1729
|
return false;
|
|
1727
1730
|
}
|
|
1728
1731
|
}
|
|
1729
|
-
const
|
|
1730
|
-
return
|
|
1732
|
+
const collectionPath = canonicalPath(collection.path);
|
|
1733
|
+
return collectionPath === "" || canonicalFilepath.startsWith(`${collectionPath}/`);
|
|
1731
1734
|
});
|
|
1732
1735
|
if (possibleCollections.length === 0) {
|
|
1733
1736
|
throw new Error(`Unable to find collection for file at ${filepath}`);
|
|
@@ -1945,7 +1948,7 @@
|
|
|
1945
1948
|
}
|
|
1946
1949
|
}
|
|
1947
1950
|
};
|
|
1948
|
-
this.
|
|
1951
|
+
this.legacyWalkFields = (cb) => {
|
|
1949
1952
|
const walk = (collectionOrObject, collection, path) => {
|
|
1950
1953
|
if (collectionOrObject.templates) {
|
|
1951
1954
|
collectionOrObject.templates.forEach((template) => {
|
|
@@ -1967,7 +1970,7 @@
|
|
|
1967
1970
|
collections.forEach((collection) => walk(collection, collection, []));
|
|
1968
1971
|
};
|
|
1969
1972
|
this.schema = config;
|
|
1970
|
-
this.
|
|
1973
|
+
this.legacyWalkFields(({ field, collection }) => {
|
|
1971
1974
|
if (!("searchable" in field)) {
|
|
1972
1975
|
if (field.type === "image") {
|
|
1973
1976
|
field.searchable = false;
|
|
@@ -1988,20 +1991,67 @@
|
|
|
1988
1991
|
field.uid = field.uid || false;
|
|
1989
1992
|
});
|
|
1990
1993
|
}
|
|
1991
|
-
|
|
1994
|
+
findReferencesFromCollection(name2) {
|
|
1992
1995
|
const result = {};
|
|
1993
1996
|
this.walkFields(({ field, collection: c, path }) => {
|
|
1997
|
+
if (c.name !== name2) {
|
|
1998
|
+
return;
|
|
1999
|
+
}
|
|
1994
2000
|
if (field.type === "reference") {
|
|
1995
|
-
|
|
1996
|
-
if (result[
|
|
1997
|
-
result[
|
|
2001
|
+
field.collections.forEach((name22) => {
|
|
2002
|
+
if (result[name22] === void 0) {
|
|
2003
|
+
result[name22] = [];
|
|
1998
2004
|
}
|
|
1999
|
-
result[
|
|
2000
|
-
}
|
|
2005
|
+
result[name22].push(path);
|
|
2006
|
+
});
|
|
2001
2007
|
}
|
|
2002
2008
|
});
|
|
2003
2009
|
return result;
|
|
2004
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
|
+
}
|
|
2005
2055
|
/**
|
|
2006
2056
|
* This function returns an array of glob matches for a given collection.
|
|
2007
2057
|
*
|
|
@@ -2013,16 +2063,16 @@
|
|
|
2013
2063
|
}) {
|
|
2014
2064
|
var _a, _b;
|
|
2015
2065
|
const collection = typeof collectionOrString === "string" ? this.getCollection(collectionOrString) : collectionOrString;
|
|
2016
|
-
const
|
|
2017
|
-
const pathSuffix =
|
|
2066
|
+
const collectionPath = canonicalPath(collection.path);
|
|
2067
|
+
const pathSuffix = collectionPath ? "/" : "";
|
|
2018
2068
|
const format = collection.format || "md";
|
|
2019
2069
|
const matches = [];
|
|
2020
2070
|
if ((_a = collection == null ? void 0 : collection.match) == null ? void 0 : _a.include) {
|
|
2021
|
-
const match = `${
|
|
2071
|
+
const match = `${collectionPath}${pathSuffix}${collection.match.include}.${format}`;
|
|
2022
2072
|
matches.push(match);
|
|
2023
2073
|
}
|
|
2024
2074
|
if ((_b = collection == null ? void 0 : collection.match) == null ? void 0 : _b.exclude) {
|
|
2025
|
-
const exclude = `!(${
|
|
2075
|
+
const exclude = `!(${collectionPath}${pathSuffix}${collection.match.exclude}.${format})`;
|
|
2026
2076
|
matches.push(exclude);
|
|
2027
2077
|
}
|
|
2028
2078
|
return matches;
|
|
@@ -2215,6 +2265,15 @@
|
|
|
2215
2265
|
})
|
|
2216
2266
|
};
|
|
2217
2267
|
};
|
|
2268
|
+
const CONTENT_FORMATS = [
|
|
2269
|
+
"mdx",
|
|
2270
|
+
"md",
|
|
2271
|
+
"markdown",
|
|
2272
|
+
"json",
|
|
2273
|
+
"yaml",
|
|
2274
|
+
"yml",
|
|
2275
|
+
"toml"
|
|
2276
|
+
];
|
|
2218
2277
|
const parseZodError = ({ zodError }) => {
|
|
2219
2278
|
var _a, _b, _c, _d;
|
|
2220
2279
|
const errors = zodError.flatten((issue) => {
|
|
@@ -2524,15 +2583,6 @@ ${stringifiedField}`
|
|
|
2524
2583
|
const newConfig = tinaConfigZod.parse(config);
|
|
2525
2584
|
return newConfig;
|
|
2526
2585
|
};
|
|
2527
|
-
const FORMATS = [
|
|
2528
|
-
"json",
|
|
2529
|
-
"md",
|
|
2530
|
-
"markdown",
|
|
2531
|
-
"mdx",
|
|
2532
|
-
"toml",
|
|
2533
|
-
"yaml",
|
|
2534
|
-
"yml"
|
|
2535
|
-
];
|
|
2536
2586
|
const Template = z.z.object({
|
|
2537
2587
|
label: z.z.string({
|
|
2538
2588
|
invalid_type_error: "Invalid data type for property `label`. Must be of type `string`",
|
|
@@ -2568,7 +2618,7 @@ ${stringifiedField}`
|
|
|
2568
2618
|
});
|
|
2569
2619
|
}
|
|
2570
2620
|
}),
|
|
2571
|
-
format: z.z.enum(
|
|
2621
|
+
format: z.z.enum(CONTENT_FORMATS).optional(),
|
|
2572
2622
|
isAuthCollection: z.z.boolean().optional(),
|
|
2573
2623
|
isDetached: z.z.boolean().optional()
|
|
2574
2624
|
});
|
|
@@ -2687,11 +2737,13 @@ ${stringifiedField}`
|
|
|
2687
2737
|
throw new Error(e);
|
|
2688
2738
|
}
|
|
2689
2739
|
};
|
|
2740
|
+
exports2.CONTENT_FORMATS = CONTENT_FORMATS;
|
|
2690
2741
|
exports2.NAMER = NAMER;
|
|
2691
2742
|
exports2.TINA_HOST = TINA_HOST;
|
|
2692
2743
|
exports2.TinaSchema = TinaSchema;
|
|
2693
2744
|
exports2.TinaSchemaValidationError = TinaSchemaValidationError;
|
|
2694
2745
|
exports2.addNamespaceToSchema = addNamespaceToSchema;
|
|
2746
|
+
exports2.canonicalPath = canonicalPath;
|
|
2695
2747
|
exports2.normalizePath = normalizePath;
|
|
2696
2748
|
exports2.parseURL = parseURL;
|
|
2697
2749
|
exports2.resolveField = resolveField;
|
package/dist/index.mjs
CHANGED
|
@@ -1646,6 +1646,9 @@ const parseURL = (url) => {
|
|
|
1646
1646
|
};
|
|
1647
1647
|
};
|
|
1648
1648
|
const normalizePath = (filepath) => filepath.replace(/\\/g, "/");
|
|
1649
|
+
const canonicalPath = (filepath) => {
|
|
1650
|
+
return normalizePath(filepath).split("/").filter((name2) => name2 !== "").join("/");
|
|
1651
|
+
};
|
|
1649
1652
|
class TinaSchema {
|
|
1650
1653
|
/**
|
|
1651
1654
|
* Create a schema class from a user defined schema object
|
|
@@ -1695,21 +1698,21 @@ class TinaSchema {
|
|
|
1695
1698
|
};
|
|
1696
1699
|
this.getCollectionByFullPath = (filepath) => {
|
|
1697
1700
|
const fileExtension = filepath.split(".").pop();
|
|
1698
|
-
const
|
|
1701
|
+
const canonicalFilepath = canonicalPath(filepath);
|
|
1699
1702
|
const possibleCollections = this.getCollections().filter((collection) => {
|
|
1700
1703
|
var _a, _b;
|
|
1701
|
-
if (!
|
|
1704
|
+
if (!canonicalFilepath.endsWith(`.gitkeep.${collection.format || "md"}`) && fileExtension !== (collection.format || "md")) {
|
|
1702
1705
|
return false;
|
|
1703
1706
|
}
|
|
1704
1707
|
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)) {
|
|
1705
1708
|
const matches = this.getMatches({ collection });
|
|
1706
|
-
const match = picomatch$1.isMatch(
|
|
1709
|
+
const match = picomatch$1.isMatch(canonicalFilepath, matches);
|
|
1707
1710
|
if (!match) {
|
|
1708
1711
|
return false;
|
|
1709
1712
|
}
|
|
1710
1713
|
}
|
|
1711
|
-
const
|
|
1712
|
-
return
|
|
1714
|
+
const collectionPath = canonicalPath(collection.path);
|
|
1715
|
+
return collectionPath === "" || canonicalFilepath.startsWith(`${collectionPath}/`);
|
|
1713
1716
|
});
|
|
1714
1717
|
if (possibleCollections.length === 0) {
|
|
1715
1718
|
throw new Error(`Unable to find collection for file at ${filepath}`);
|
|
@@ -1927,7 +1930,7 @@ class TinaSchema {
|
|
|
1927
1930
|
}
|
|
1928
1931
|
}
|
|
1929
1932
|
};
|
|
1930
|
-
this.
|
|
1933
|
+
this.legacyWalkFields = (cb) => {
|
|
1931
1934
|
const walk = (collectionOrObject, collection, path) => {
|
|
1932
1935
|
if (collectionOrObject.templates) {
|
|
1933
1936
|
collectionOrObject.templates.forEach((template) => {
|
|
@@ -1949,7 +1952,7 @@ class TinaSchema {
|
|
|
1949
1952
|
collections.forEach((collection) => walk(collection, collection, []));
|
|
1950
1953
|
};
|
|
1951
1954
|
this.schema = config;
|
|
1952
|
-
this.
|
|
1955
|
+
this.legacyWalkFields(({ field, collection }) => {
|
|
1953
1956
|
if (!("searchable" in field)) {
|
|
1954
1957
|
if (field.type === "image") {
|
|
1955
1958
|
field.searchable = false;
|
|
@@ -1970,20 +1973,67 @@ class TinaSchema {
|
|
|
1970
1973
|
field.uid = field.uid || false;
|
|
1971
1974
|
});
|
|
1972
1975
|
}
|
|
1973
|
-
|
|
1976
|
+
findReferencesFromCollection(name2) {
|
|
1974
1977
|
const result = {};
|
|
1975
1978
|
this.walkFields(({ field, collection: c, path }) => {
|
|
1979
|
+
if (c.name !== name2) {
|
|
1980
|
+
return;
|
|
1981
|
+
}
|
|
1976
1982
|
if (field.type === "reference") {
|
|
1977
|
-
|
|
1978
|
-
if (result[
|
|
1979
|
-
result[
|
|
1983
|
+
field.collections.forEach((name22) => {
|
|
1984
|
+
if (result[name22] === void 0) {
|
|
1985
|
+
result[name22] = [];
|
|
1980
1986
|
}
|
|
1981
|
-
result[
|
|
1982
|
-
}
|
|
1987
|
+
result[name22].push(path);
|
|
1988
|
+
});
|
|
1983
1989
|
}
|
|
1984
1990
|
});
|
|
1985
1991
|
return result;
|
|
1986
1992
|
}
|
|
1993
|
+
/**
|
|
1994
|
+
* Walk all fields in tina schema
|
|
1995
|
+
*
|
|
1996
|
+
* @param cb callback function invoked for each field
|
|
1997
|
+
*/
|
|
1998
|
+
walkFields(cb) {
|
|
1999
|
+
const walk = (collectionOrObject, collection, path = "$") => {
|
|
2000
|
+
if (collectionOrObject.templates) {
|
|
2001
|
+
collectionOrObject.templates.forEach((template) => {
|
|
2002
|
+
const templatePath = `${path}.${template.name}`;
|
|
2003
|
+
template.fields.forEach((field) => {
|
|
2004
|
+
const fieldPath = field.list ? `${templatePath}[*].${field.name}` : `${templatePath}.${field.name}`;
|
|
2005
|
+
cb({ field, collection, path: fieldPath });
|
|
2006
|
+
if (field.type === "object") {
|
|
2007
|
+
walk(field, collection, fieldPath);
|
|
2008
|
+
}
|
|
2009
|
+
});
|
|
2010
|
+
});
|
|
2011
|
+
}
|
|
2012
|
+
if (collectionOrObject.fields) {
|
|
2013
|
+
collectionOrObject.fields.forEach((field) => {
|
|
2014
|
+
const fieldPath = field.list ? `${path}.${field.name}[*]` : `${path}.${field.name}`;
|
|
2015
|
+
cb({ field, collection, path: fieldPath });
|
|
2016
|
+
if (field.type === "object" && field.fields) {
|
|
2017
|
+
walk(field, collection, fieldPath);
|
|
2018
|
+
} else if (field.templates) {
|
|
2019
|
+
field.templates.forEach((template) => {
|
|
2020
|
+
const templatePath = `${fieldPath}.${template.name}`;
|
|
2021
|
+
template.fields.forEach((field2) => {
|
|
2022
|
+
const fieldPath2 = field2.list ? `${templatePath}[*].${field2.name}` : `${templatePath}.${field2.name}`;
|
|
2023
|
+
cb({ field: field2, collection, path: fieldPath2 });
|
|
2024
|
+
if (field2.type === "object") {
|
|
2025
|
+
walk(field2, collection, fieldPath2);
|
|
2026
|
+
}
|
|
2027
|
+
});
|
|
2028
|
+
});
|
|
2029
|
+
}
|
|
2030
|
+
});
|
|
2031
|
+
}
|
|
2032
|
+
};
|
|
2033
|
+
this.getCollections().forEach((collection) => {
|
|
2034
|
+
walk(collection, collection);
|
|
2035
|
+
});
|
|
2036
|
+
}
|
|
1987
2037
|
/**
|
|
1988
2038
|
* This function returns an array of glob matches for a given collection.
|
|
1989
2039
|
*
|
|
@@ -1995,16 +2045,16 @@ class TinaSchema {
|
|
|
1995
2045
|
}) {
|
|
1996
2046
|
var _a, _b;
|
|
1997
2047
|
const collection = typeof collectionOrString === "string" ? this.getCollection(collectionOrString) : collectionOrString;
|
|
1998
|
-
const
|
|
1999
|
-
const pathSuffix =
|
|
2048
|
+
const collectionPath = canonicalPath(collection.path);
|
|
2049
|
+
const pathSuffix = collectionPath ? "/" : "";
|
|
2000
2050
|
const format = collection.format || "md";
|
|
2001
2051
|
const matches = [];
|
|
2002
2052
|
if ((_a = collection == null ? void 0 : collection.match) == null ? void 0 : _a.include) {
|
|
2003
|
-
const match = `${
|
|
2053
|
+
const match = `${collectionPath}${pathSuffix}${collection.match.include}.${format}`;
|
|
2004
2054
|
matches.push(match);
|
|
2005
2055
|
}
|
|
2006
2056
|
if ((_b = collection == null ? void 0 : collection.match) == null ? void 0 : _b.exclude) {
|
|
2007
|
-
const exclude = `!(${
|
|
2057
|
+
const exclude = `!(${collectionPath}${pathSuffix}${collection.match.exclude}.${format})`;
|
|
2008
2058
|
matches.push(exclude);
|
|
2009
2059
|
}
|
|
2010
2060
|
return matches;
|
|
@@ -2197,6 +2247,15 @@ const resolveForm = ({
|
|
|
2197
2247
|
})
|
|
2198
2248
|
};
|
|
2199
2249
|
};
|
|
2250
|
+
const CONTENT_FORMATS = [
|
|
2251
|
+
"mdx",
|
|
2252
|
+
"md",
|
|
2253
|
+
"markdown",
|
|
2254
|
+
"json",
|
|
2255
|
+
"yaml",
|
|
2256
|
+
"yml",
|
|
2257
|
+
"toml"
|
|
2258
|
+
];
|
|
2200
2259
|
const parseZodError = ({ zodError }) => {
|
|
2201
2260
|
var _a, _b, _c, _d;
|
|
2202
2261
|
const errors = zodError.flatten((issue) => {
|
|
@@ -2506,15 +2565,6 @@ const validateTinaCloudSchemaConfig = (config) => {
|
|
|
2506
2565
|
const newConfig = tinaConfigZod.parse(config);
|
|
2507
2566
|
return newConfig;
|
|
2508
2567
|
};
|
|
2509
|
-
const FORMATS = [
|
|
2510
|
-
"json",
|
|
2511
|
-
"md",
|
|
2512
|
-
"markdown",
|
|
2513
|
-
"mdx",
|
|
2514
|
-
"toml",
|
|
2515
|
-
"yaml",
|
|
2516
|
-
"yml"
|
|
2517
|
-
];
|
|
2518
2568
|
const Template = z.object({
|
|
2519
2569
|
label: z.string({
|
|
2520
2570
|
invalid_type_error: "Invalid data type for property `label`. Must be of type `string`",
|
|
@@ -2550,7 +2600,7 @@ const CollectionBaseSchema = z.object({
|
|
|
2550
2600
|
});
|
|
2551
2601
|
}
|
|
2552
2602
|
}),
|
|
2553
|
-
format: z.enum(
|
|
2603
|
+
format: z.enum(CONTENT_FORMATS).optional(),
|
|
2554
2604
|
isAuthCollection: z.boolean().optional(),
|
|
2555
2605
|
isDetached: z.boolean().optional()
|
|
2556
2606
|
});
|
|
@@ -2670,11 +2720,13 @@ const validateSchema = ({ schema }) => {
|
|
|
2670
2720
|
}
|
|
2671
2721
|
};
|
|
2672
2722
|
export {
|
|
2723
|
+
CONTENT_FORMATS,
|
|
2673
2724
|
NAMER,
|
|
2674
2725
|
TINA_HOST,
|
|
2675
2726
|
TinaSchema,
|
|
2676
2727
|
TinaSchemaValidationError,
|
|
2677
2728
|
addNamespaceToSchema,
|
|
2729
|
+
canonicalPath,
|
|
2678
2730
|
normalizePath,
|
|
2679
2731
|
parseURL,
|
|
2680
2732
|
resolveField,
|
|
@@ -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,7 +60,26 @@ export declare class TinaSchema {
|
|
|
63
60
|
*
|
|
64
61
|
*/
|
|
65
62
|
getTemplatesForCollectable: (collection: Collectable) => CollectionTemplateable;
|
|
66
|
-
|
|
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: {
|
|
67
83
|
field: TinaField;
|
|
68
84
|
collection: Collection;
|
|
69
85
|
path: string[];
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
import type { FC } from 'react';
|
|
2
2
|
import type React from 'react';
|
|
3
|
+
export declare const CONTENT_FORMATS: readonly ["mdx", "md", "markdown", "json", "yaml", "yml", "toml"];
|
|
4
|
+
export type ContentFormat = (typeof CONTENT_FORMATS)[number];
|
|
5
|
+
export type ContentFrontmatterFormat = 'yaml' | 'toml' | 'json';
|
|
6
|
+
export type Parser = {
|
|
7
|
+
type: 'mdx';
|
|
8
|
+
} | {
|
|
9
|
+
type: 'markdown';
|
|
10
|
+
/**
|
|
11
|
+
* Tina will escape entities like `<` and `[` by default. You can choose to turn
|
|
12
|
+
* off all escaping, or specify HTML, so `<div>` will not be turned into `\<div>`
|
|
13
|
+
*/
|
|
14
|
+
skipEscaping?: 'all' | 'html' | 'none';
|
|
15
|
+
} | {
|
|
16
|
+
/**
|
|
17
|
+
* Experimental: Returns the native Slate.js document as JSON. Ideal to retain the pure editor content structure.
|
|
18
|
+
*/
|
|
19
|
+
type: 'slatejson';
|
|
20
|
+
};
|
|
3
21
|
type Meta = {
|
|
4
22
|
active?: boolean;
|
|
5
23
|
dirty?: boolean;
|
|
@@ -111,6 +129,11 @@ export type UIField<Type, List extends boolean> = {
|
|
|
111
129
|
type FieldGeneric<Type, List extends boolean | undefined, ExtraFieldUIProps = {}> = List extends true ? {
|
|
112
130
|
list: true;
|
|
113
131
|
ui?: UIField<Type, true> & ExtraFieldUIProps;
|
|
132
|
+
/**
|
|
133
|
+
* Defines where new items will be added in the list.
|
|
134
|
+
* If not specified, defaults to `append`.
|
|
135
|
+
*/
|
|
136
|
+
addItemBehavior?: 'append' | 'prepend';
|
|
114
137
|
} : List extends false ? {
|
|
115
138
|
list?: false;
|
|
116
139
|
ui?: UIField<Type, false> & ExtraFieldUIProps;
|
|
@@ -212,16 +235,7 @@ export type RichTextField<WithNamespace extends boolean = false> = (FieldGeneric
|
|
|
212
235
|
*
|
|
213
236
|
* Specify `"markdown"` if you're having problems with Tina parsing your content.
|
|
214
237
|
*/
|
|
215
|
-
parser?:
|
|
216
|
-
type: 'markdown';
|
|
217
|
-
/**
|
|
218
|
-
* Tina will escape entities like `<` and `[` by default. You can choose to turn
|
|
219
|
-
* off all escaping, or specify HTML, so `<div>` will not be turned into `\<div>`
|
|
220
|
-
*/
|
|
221
|
-
skipEscaping?: 'all' | 'html' | 'none';
|
|
222
|
-
} | {
|
|
223
|
-
type: 'mdx';
|
|
224
|
-
};
|
|
238
|
+
parser?: Parser;
|
|
225
239
|
};
|
|
226
240
|
export type RichTextTemplate<WithNamespace extends boolean = false> = Template<WithNamespace> & {
|
|
227
241
|
inline?: boolean;
|
|
@@ -377,7 +391,7 @@ export interface Config<CMSCallback = undefined, FormifyCallback = undefined, Do
|
|
|
377
391
|
/**
|
|
378
392
|
* The Schema is used to define the shape of the content.
|
|
379
393
|
*
|
|
380
|
-
* https://tina.io/docs/
|
|
394
|
+
* https://tina.io/docs/r/the-config-file/
|
|
381
395
|
*/
|
|
382
396
|
schema: Schema;
|
|
383
397
|
/**
|
|
@@ -400,7 +414,7 @@ export interface Config<CMSCallback = undefined, FormifyCallback = undefined, Do
|
|
|
400
414
|
token?: string | null;
|
|
401
415
|
ui?: {
|
|
402
416
|
/**
|
|
403
|
-
* When using
|
|
417
|
+
* When using TinaCloud's branching feature, provide the URL for your given branch
|
|
404
418
|
*
|
|
405
419
|
* Eg. If you're deplying to Vercel, and your repo name is 'my-app',
|
|
406
420
|
* Vercel's preview URL would be based on the branch:
|
|
@@ -414,11 +428,17 @@ export interface Config<CMSCallback = undefined, FormifyCallback = undefined, Do
|
|
|
414
428
|
* ```
|
|
415
429
|
* [more info](https://vercel.com/docs/concepts/deployments/generated-urls#url-with-git-branch)
|
|
416
430
|
*/
|
|
417
|
-
previewUrl
|
|
431
|
+
previewUrl?: (context: {
|
|
418
432
|
branch: string;
|
|
419
433
|
}) => {
|
|
420
434
|
url: string;
|
|
421
435
|
};
|
|
436
|
+
/**
|
|
437
|
+
* Opt out of update checks - this will prevent the CMS for checking for new versions
|
|
438
|
+
* If true, the CMS will not check for updates.
|
|
439
|
+
* Defaults to false if not specified.
|
|
440
|
+
*/
|
|
441
|
+
optOutOfUpdateCheck?: boolean;
|
|
422
442
|
};
|
|
423
443
|
/**
|
|
424
444
|
* Configurations for the autogenerated GraphQL HTTP client
|
|
@@ -498,7 +518,7 @@ export interface Config<CMSCallback = undefined, FormifyCallback = undefined, Do
|
|
|
498
518
|
} | {
|
|
499
519
|
/**
|
|
500
520
|
* Use Git-backed assets for media, these values will
|
|
501
|
-
* [Learn more](https://tina.io/docs/
|
|
521
|
+
* [Learn more](https://tina.io/docs/r/repo-based-media/)
|
|
502
522
|
*/
|
|
503
523
|
tina: {
|
|
504
524
|
/**
|
|
@@ -527,7 +547,7 @@ export interface Config<CMSCallback = undefined, FormifyCallback = undefined, Do
|
|
|
527
547
|
} | {
|
|
528
548
|
searchClient?: never;
|
|
529
549
|
/**
|
|
530
|
-
* Use the
|
|
550
|
+
* Use the TinaCloud search index
|
|
531
551
|
*/
|
|
532
552
|
tina: {
|
|
533
553
|
/**
|
|
@@ -554,7 +574,7 @@ export interface Config<CMSCallback = undefined, FormifyCallback = undefined, Do
|
|
|
554
574
|
maxSearchIndexFieldLength?: number;
|
|
555
575
|
};
|
|
556
576
|
/**
|
|
557
|
-
* Used to override the default
|
|
577
|
+
* Used to override the default TinaCloud API URL
|
|
558
578
|
*
|
|
559
579
|
* [mostly for internal use only]
|
|
560
580
|
*/
|
|
@@ -573,7 +593,7 @@ export interface Schema<WithNamespace extends boolean = false> {
|
|
|
573
593
|
/**
|
|
574
594
|
* Collections represent a type of content (EX, blog post, page, author, etc). We recommend using singular naming in a collection (Ex: use post and not posts).
|
|
575
595
|
*
|
|
576
|
-
* https://tina.io/docs/
|
|
596
|
+
* https://tina.io/docs/r/content-modelling-collections/
|
|
577
597
|
*/
|
|
578
598
|
collections: Collection<WithNamespace>[];
|
|
579
599
|
/**
|
|
@@ -587,7 +607,7 @@ interface BaseCollection {
|
|
|
587
607
|
name: string;
|
|
588
608
|
path: string;
|
|
589
609
|
indexes?: IndexType[];
|
|
590
|
-
format?:
|
|
610
|
+
format?: ContentFormat;
|
|
591
611
|
ui?: UICollection;
|
|
592
612
|
/**
|
|
593
613
|
* @deprecated - use `ui.defaultItem` on the each `template` instead
|
|
@@ -596,7 +616,7 @@ interface BaseCollection {
|
|
|
596
616
|
/**
|
|
597
617
|
* This format will be used to parse the markdown frontmatter
|
|
598
618
|
*/
|
|
599
|
-
frontmatterFormat?:
|
|
619
|
+
frontmatterFormat?: ContentFrontmatterFormat;
|
|
600
620
|
/**
|
|
601
621
|
* The delimiters used to parse the frontmatter.
|
|
602
622
|
*/
|
|
@@ -612,7 +632,7 @@ type TemplateCollection<WithNamespace extends boolean = false> = {
|
|
|
612
632
|
/**
|
|
613
633
|
* In most cases, just using fields is enough, however templates can be used when there are multiple variants of the same collection or object. For example in a "page" collection there might be a need for a marketing page template and a content page template, both under the collection "page".
|
|
614
634
|
*
|
|
615
|
-
* https://tina.io/docs/
|
|
635
|
+
* https://tina.io/docs/r/content-modelling-templates/
|
|
616
636
|
*/
|
|
617
637
|
templates: Template<WithNamespace>[];
|
|
618
638
|
fields?: undefined;
|
|
@@ -621,7 +641,7 @@ type FieldCollection<WithNamespace extends boolean = false> = {
|
|
|
621
641
|
/**
|
|
622
642
|
* Fields define the shape of the content and the user input.
|
|
623
643
|
*
|
|
624
|
-
* https://tina.io/docs/
|
|
644
|
+
* https://tina.io/docs/r/string-fields/
|
|
625
645
|
*/
|
|
626
646
|
fields: TinaField<WithNamespace>[];
|
|
627
647
|
templates?: undefined;
|
|
@@ -1 +1,9 @@
|
|
|
1
1
|
export declare const normalizePath: (filepath: string) => string;
|
|
2
|
+
/**
|
|
3
|
+
* Returns the given path such that:
|
|
4
|
+
* - The path separator is converted from '\' to '/' if necessary.
|
|
5
|
+
* - Duplicate '/' are removed
|
|
6
|
+
* - Leading and trailing '/' are cleared
|
|
7
|
+
* @param filepath Filepath to convert to its canonical form
|
|
8
|
+
*/
|
|
9
|
+
export declare const canonicalPath: (filepath: string) => string;
|
|
@@ -3,21 +3,21 @@ export declare const CollectionBaseSchema: z.ZodObject<{
|
|
|
3
3
|
label: z.ZodOptional<z.ZodString>;
|
|
4
4
|
name: z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, string, string>;
|
|
5
5
|
path: z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, string, string>;
|
|
6
|
-
format: z.ZodOptional<z.ZodEnum<["
|
|
6
|
+
format: z.ZodOptional<z.ZodEnum<["mdx", "md", "markdown", "json", "yaml", "yml", "toml"]>>;
|
|
7
7
|
isAuthCollection: z.ZodOptional<z.ZodBoolean>;
|
|
8
8
|
isDetached: z.ZodOptional<z.ZodBoolean>;
|
|
9
9
|
}, "strip", z.ZodTypeAny, {
|
|
10
10
|
name?: string;
|
|
11
11
|
label?: string;
|
|
12
12
|
path?: string;
|
|
13
|
-
format?: "
|
|
13
|
+
format?: "mdx" | "md" | "markdown" | "json" | "yaml" | "yml" | "toml";
|
|
14
14
|
isDetached?: boolean;
|
|
15
15
|
isAuthCollection?: boolean;
|
|
16
16
|
}, {
|
|
17
17
|
name?: string;
|
|
18
18
|
label?: string;
|
|
19
19
|
path?: string;
|
|
20
|
-
format?: "
|
|
20
|
+
format?: "mdx" | "md" | "markdown" | "json" | "yaml" | "yml" | "toml";
|
|
21
21
|
isDetached?: boolean;
|
|
22
22
|
isAuthCollection?: boolean;
|
|
23
23
|
}>;
|
|
@@ -26,90 +26,90 @@ export declare const TinaCloudSchemaZod: z.ZodEffects<z.ZodObject<{
|
|
|
26
26
|
label: z.ZodOptional<z.ZodString>;
|
|
27
27
|
name: z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, string, string>;
|
|
28
28
|
path: z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, string, string>;
|
|
29
|
-
format: z.ZodOptional<z.ZodEnum<["
|
|
29
|
+
format: z.ZodOptional<z.ZodEnum<["mdx", "md", "markdown", "json", "yaml", "yml", "toml"]>>;
|
|
30
30
|
isAuthCollection: z.ZodOptional<z.ZodBoolean>;
|
|
31
31
|
isDetached: z.ZodOptional<z.ZodBoolean>;
|
|
32
32
|
}, {
|
|
33
|
-
fields: z.ZodEffects<z.ZodEffects<z.ZodEffects<z.ZodEffects<z.ZodOptional<z.ZodArray<z.ZodType<import("
|
|
33
|
+
fields: z.ZodEffects<z.ZodEffects<z.ZodEffects<z.ZodEffects<z.ZodOptional<z.ZodArray<z.ZodType<import("../types/index").TinaField, z.ZodTypeDef, import("../types/index").TinaField>, "many">>, import("../types/index").TinaField[], import("../types/index").TinaField[]>, import("../types/index").TinaField[], import("../types/index").TinaField[]>, import("../types/index").TinaField[], import("../types/index").TinaField[]>, import("../types/index").TinaField[], import("../types/index").TinaField[]>;
|
|
34
34
|
templates: z.ZodEffects<z.ZodOptional<z.ZodArray<z.ZodEffects<z.ZodObject<{
|
|
35
35
|
label: z.ZodString;
|
|
36
36
|
name: z.ZodEffects<z.ZodString, string, string>;
|
|
37
|
-
fields: z.ZodArray<z.ZodType<import("
|
|
37
|
+
fields: z.ZodArray<z.ZodType<import("../types/index").TinaField, z.ZodTypeDef, import("../types/index").TinaField>, "many">;
|
|
38
38
|
}, "strip", z.ZodTypeAny, {
|
|
39
39
|
name?: string;
|
|
40
|
-
fields?: import("
|
|
40
|
+
fields?: import("../types/index").TinaField[];
|
|
41
41
|
label?: string;
|
|
42
42
|
}, {
|
|
43
43
|
name?: string;
|
|
44
|
-
fields?: import("
|
|
44
|
+
fields?: import("../types/index").TinaField[];
|
|
45
45
|
label?: string;
|
|
46
46
|
}>, {
|
|
47
47
|
name?: string;
|
|
48
|
-
fields?: import("
|
|
48
|
+
fields?: import("../types/index").TinaField[];
|
|
49
49
|
label?: string;
|
|
50
50
|
}, {
|
|
51
51
|
name?: string;
|
|
52
|
-
fields?: import("
|
|
52
|
+
fields?: import("../types/index").TinaField[];
|
|
53
53
|
label?: string;
|
|
54
54
|
}>, "many">>, {
|
|
55
55
|
name?: string;
|
|
56
|
-
fields?: import("
|
|
56
|
+
fields?: import("../types/index").TinaField[];
|
|
57
57
|
label?: string;
|
|
58
58
|
}[], {
|
|
59
59
|
name?: string;
|
|
60
|
-
fields?: import("
|
|
60
|
+
fields?: import("../types/index").TinaField[];
|
|
61
61
|
label?: string;
|
|
62
62
|
}[]>;
|
|
63
63
|
}>, "strip", z.ZodTypeAny, {
|
|
64
64
|
name?: string;
|
|
65
65
|
templates?: {
|
|
66
66
|
name?: string;
|
|
67
|
-
fields?: import("
|
|
67
|
+
fields?: import("../types/index").TinaField[];
|
|
68
68
|
label?: string;
|
|
69
69
|
}[];
|
|
70
|
-
fields?: import("
|
|
70
|
+
fields?: import("../types/index").TinaField[];
|
|
71
71
|
label?: string;
|
|
72
72
|
path?: string;
|
|
73
|
-
format?: "
|
|
73
|
+
format?: "mdx" | "md" | "markdown" | "json" | "yaml" | "yml" | "toml";
|
|
74
74
|
isDetached?: boolean;
|
|
75
75
|
isAuthCollection?: boolean;
|
|
76
76
|
}, {
|
|
77
77
|
name?: string;
|
|
78
78
|
templates?: {
|
|
79
79
|
name?: string;
|
|
80
|
-
fields?: import("
|
|
80
|
+
fields?: import("../types/index").TinaField[];
|
|
81
81
|
label?: string;
|
|
82
82
|
}[];
|
|
83
|
-
fields?: import("
|
|
83
|
+
fields?: import("../types/index").TinaField[];
|
|
84
84
|
label?: string;
|
|
85
85
|
path?: string;
|
|
86
|
-
format?: "
|
|
86
|
+
format?: "mdx" | "md" | "markdown" | "json" | "yaml" | "yml" | "toml";
|
|
87
87
|
isDetached?: boolean;
|
|
88
88
|
isAuthCollection?: boolean;
|
|
89
89
|
}>, {
|
|
90
90
|
name?: string;
|
|
91
91
|
templates?: {
|
|
92
92
|
name?: string;
|
|
93
|
-
fields?: import("
|
|
93
|
+
fields?: import("../types/index").TinaField[];
|
|
94
94
|
label?: string;
|
|
95
95
|
}[];
|
|
96
|
-
fields?: import("
|
|
96
|
+
fields?: import("../types/index").TinaField[];
|
|
97
97
|
label?: string;
|
|
98
98
|
path?: string;
|
|
99
|
-
format?: "
|
|
99
|
+
format?: "mdx" | "md" | "markdown" | "json" | "yaml" | "yml" | "toml";
|
|
100
100
|
isDetached?: boolean;
|
|
101
101
|
isAuthCollection?: boolean;
|
|
102
102
|
}, {
|
|
103
103
|
name?: string;
|
|
104
104
|
templates?: {
|
|
105
105
|
name?: string;
|
|
106
|
-
fields?: import("
|
|
106
|
+
fields?: import("../types/index").TinaField[];
|
|
107
107
|
label?: string;
|
|
108
108
|
}[];
|
|
109
|
-
fields?: import("
|
|
109
|
+
fields?: import("../types/index").TinaField[];
|
|
110
110
|
label?: string;
|
|
111
111
|
path?: string;
|
|
112
|
-
format?: "
|
|
112
|
+
format?: "mdx" | "md" | "markdown" | "json" | "yaml" | "yml" | "toml";
|
|
113
113
|
isDetached?: boolean;
|
|
114
114
|
isAuthCollection?: boolean;
|
|
115
115
|
}>, "many">;
|
|
@@ -237,13 +237,13 @@ export declare const TinaCloudSchemaZod: z.ZodEffects<z.ZodObject<{
|
|
|
237
237
|
name?: string;
|
|
238
238
|
templates?: {
|
|
239
239
|
name?: string;
|
|
240
|
-
fields?: import("
|
|
240
|
+
fields?: import("../types/index").TinaField[];
|
|
241
241
|
label?: string;
|
|
242
242
|
}[];
|
|
243
|
-
fields?: import("
|
|
243
|
+
fields?: import("../types/index").TinaField[];
|
|
244
244
|
label?: string;
|
|
245
245
|
path?: string;
|
|
246
|
-
format?: "
|
|
246
|
+
format?: "mdx" | "md" | "markdown" | "json" | "yaml" | "yml" | "toml";
|
|
247
247
|
isDetached?: boolean;
|
|
248
248
|
isAuthCollection?: boolean;
|
|
249
249
|
}[];
|
|
@@ -275,13 +275,13 @@ export declare const TinaCloudSchemaZod: z.ZodEffects<z.ZodObject<{
|
|
|
275
275
|
name?: string;
|
|
276
276
|
templates?: {
|
|
277
277
|
name?: string;
|
|
278
|
-
fields?: import("
|
|
278
|
+
fields?: import("../types/index").TinaField[];
|
|
279
279
|
label?: string;
|
|
280
280
|
}[];
|
|
281
|
-
fields?: import("
|
|
281
|
+
fields?: import("../types/index").TinaField[];
|
|
282
282
|
label?: string;
|
|
283
283
|
path?: string;
|
|
284
|
-
format?: "
|
|
284
|
+
format?: "mdx" | "md" | "markdown" | "json" | "yaml" | "yml" | "toml";
|
|
285
285
|
isDetached?: boolean;
|
|
286
286
|
isAuthCollection?: boolean;
|
|
287
287
|
}[];
|
|
@@ -313,13 +313,13 @@ export declare const TinaCloudSchemaZod: z.ZodEffects<z.ZodObject<{
|
|
|
313
313
|
name?: string;
|
|
314
314
|
templates?: {
|
|
315
315
|
name?: string;
|
|
316
|
-
fields?: import("
|
|
316
|
+
fields?: import("../types/index").TinaField[];
|
|
317
317
|
label?: string;
|
|
318
318
|
}[];
|
|
319
|
-
fields?: import("
|
|
319
|
+
fields?: import("../types/index").TinaField[];
|
|
320
320
|
label?: string;
|
|
321
321
|
path?: string;
|
|
322
|
-
format?: "
|
|
322
|
+
format?: "mdx" | "md" | "markdown" | "json" | "yaml" | "yml" | "toml";
|
|
323
323
|
isDetached?: boolean;
|
|
324
324
|
isAuthCollection?: boolean;
|
|
325
325
|
}[];
|
|
@@ -351,13 +351,13 @@ export declare const TinaCloudSchemaZod: z.ZodEffects<z.ZodObject<{
|
|
|
351
351
|
name?: string;
|
|
352
352
|
templates?: {
|
|
353
353
|
name?: string;
|
|
354
|
-
fields?: import("
|
|
354
|
+
fields?: import("../types/index").TinaField[];
|
|
355
355
|
label?: string;
|
|
356
356
|
}[];
|
|
357
|
-
fields?: import("
|
|
357
|
+
fields?: import("../types/index").TinaField[];
|
|
358
358
|
label?: string;
|
|
359
359
|
path?: string;
|
|
360
|
-
format?: "
|
|
360
|
+
format?: "mdx" | "md" | "markdown" | "json" | "yaml" | "yml" | "toml";
|
|
361
361
|
isDetached?: boolean;
|
|
362
362
|
isAuthCollection?: boolean;
|
|
363
363
|
}[];
|
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-d9487bf-20251119052214",
|
|
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.7.3",
|
|
34
34
|
"yup": "^0.32.11",
|
|
35
|
-
"@tinacms/scripts": "0.0.0-
|
|
35
|
+
"@tinacms/scripts": "0.0.0-d9487bf-20251119052214"
|
|
36
36
|
},
|
|
37
37
|
"peerDependencies": {
|
|
38
38
|
"react": ">=16.14.0",
|