@tinacms/graphql 0.0.0-d69e892-20241003042309 → 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/ast-builder/index.d.ts +0 -1
- package/dist/database/datalayer.d.ts +5 -1
- package/dist/database/index.d.ts +2 -0
- package/dist/index.js +787 -125
- package/dist/index.mjs +752 -98
- package/dist/resolver/index.d.ts +26 -2
- package/package.json +13 -14
package/dist/index.mjs
CHANGED
|
@@ -68,6 +68,15 @@ var SysFieldDefinition = {
|
|
|
68
68
|
selectionSet: {
|
|
69
69
|
kind: "SelectionSet",
|
|
70
70
|
selections: [
|
|
71
|
+
// {
|
|
72
|
+
// kind: 'Field' as const,
|
|
73
|
+
// name: {
|
|
74
|
+
// kind: 'Name' as const,
|
|
75
|
+
// value: 'title',
|
|
76
|
+
// },
|
|
77
|
+
// arguments: [],
|
|
78
|
+
// directives: [],
|
|
79
|
+
// },
|
|
71
80
|
{
|
|
72
81
|
kind: "Field",
|
|
73
82
|
name: {
|
|
@@ -86,6 +95,15 @@ var SysFieldDefinition = {
|
|
|
86
95
|
arguments: [],
|
|
87
96
|
directives: []
|
|
88
97
|
},
|
|
98
|
+
{
|
|
99
|
+
kind: "Field",
|
|
100
|
+
name: {
|
|
101
|
+
kind: "Name",
|
|
102
|
+
value: "hasReferences"
|
|
103
|
+
},
|
|
104
|
+
arguments: [],
|
|
105
|
+
directives: []
|
|
106
|
+
},
|
|
89
107
|
{
|
|
90
108
|
kind: "Field",
|
|
91
109
|
name: {
|
|
@@ -126,6 +144,10 @@ var SysFieldDefinition = {
|
|
|
126
144
|
}
|
|
127
145
|
};
|
|
128
146
|
var astBuilder = {
|
|
147
|
+
/**
|
|
148
|
+
* `FormFieldBuilder` acts as a shortcut to building an entire `ObjectTypeDefinition`, we use this
|
|
149
|
+
* because all Tina field objects share a common set of fields ('name', 'label', 'component')
|
|
150
|
+
*/
|
|
129
151
|
FormFieldBuilder: ({
|
|
130
152
|
name,
|
|
131
153
|
additionalFields
|
|
@@ -349,6 +371,8 @@ var astBuilder = {
|
|
|
349
371
|
kind: "Name",
|
|
350
372
|
value: name
|
|
351
373
|
},
|
|
374
|
+
// @ts-ignore FIXME; this is being handled properly but we're lying to
|
|
375
|
+
// ts and then fixing it in the `extractInlineTypes` function
|
|
352
376
|
fields
|
|
353
377
|
}),
|
|
354
378
|
UnionTypeDefinition: ({
|
|
@@ -361,6 +385,8 @@ var astBuilder = {
|
|
|
361
385
|
value: name
|
|
362
386
|
},
|
|
363
387
|
directives: [],
|
|
388
|
+
// @ts-ignore FIXME; this is being handled properly but we're lying to
|
|
389
|
+
// ts and then fixing it in the `extractInlineTypes` function
|
|
364
390
|
types: types.map((name2) => ({
|
|
365
391
|
kind: "NamedType",
|
|
366
392
|
name: {
|
|
@@ -457,8 +483,11 @@ var astBuilder = {
|
|
|
457
483
|
string: "String",
|
|
458
484
|
boolean: "Boolean",
|
|
459
485
|
number: "Float",
|
|
486
|
+
// FIXME - needs to be float or int
|
|
460
487
|
datetime: "String",
|
|
488
|
+
// FIXME
|
|
461
489
|
image: "String",
|
|
490
|
+
// FIXME
|
|
462
491
|
text: "String"
|
|
463
492
|
};
|
|
464
493
|
return scalars[type];
|
|
@@ -957,8 +986,7 @@ var astBuilder = {
|
|
|
957
986
|
}
|
|
958
987
|
};
|
|
959
988
|
var capitalize = (s) => {
|
|
960
|
-
if (typeof s !== "string")
|
|
961
|
-
return "";
|
|
989
|
+
if (typeof s !== "string") return "";
|
|
962
990
|
return s.charAt(0).toUpperCase() + s.slice(1);
|
|
963
991
|
};
|
|
964
992
|
var extractInlineTypes = (item) => {
|
|
@@ -1001,41 +1029,6 @@ function* walk(maybeNode, visited = /* @__PURE__ */ new WeakSet()) {
|
|
|
1001
1029
|
yield maybeNode;
|
|
1002
1030
|
visited.add(maybeNode);
|
|
1003
1031
|
}
|
|
1004
|
-
function addNamespaceToSchema(maybeNode, namespace = []) {
|
|
1005
|
-
if (typeof maybeNode === "string") {
|
|
1006
|
-
return maybeNode;
|
|
1007
|
-
}
|
|
1008
|
-
if (typeof maybeNode === "boolean") {
|
|
1009
|
-
return maybeNode;
|
|
1010
|
-
}
|
|
1011
|
-
const newNode = maybeNode;
|
|
1012
|
-
const keys = Object.keys(maybeNode);
|
|
1013
|
-
Object.values(maybeNode).map((m, index) => {
|
|
1014
|
-
const key = keys[index];
|
|
1015
|
-
if (Array.isArray(m)) {
|
|
1016
|
-
newNode[key] = m.map((element) => {
|
|
1017
|
-
if (!element) {
|
|
1018
|
-
return;
|
|
1019
|
-
}
|
|
1020
|
-
if (!element.hasOwnProperty("name")) {
|
|
1021
|
-
return element;
|
|
1022
|
-
}
|
|
1023
|
-
const value = element.name || element.value;
|
|
1024
|
-
return addNamespaceToSchema(element, [...namespace, value]);
|
|
1025
|
-
});
|
|
1026
|
-
} else {
|
|
1027
|
-
if (!m) {
|
|
1028
|
-
return;
|
|
1029
|
-
}
|
|
1030
|
-
if (!m.hasOwnProperty("name")) {
|
|
1031
|
-
newNode[key] = m;
|
|
1032
|
-
} else {
|
|
1033
|
-
newNode[key] = addNamespaceToSchema(m, [...namespace, m.name]);
|
|
1034
|
-
}
|
|
1035
|
-
}
|
|
1036
|
-
});
|
|
1037
|
-
return { ...newNode, namespace };
|
|
1038
|
-
}
|
|
1039
1032
|
var generateNamespacedFieldName = (names, suffix = "") => {
|
|
1040
1033
|
return (suffix ? [...names, suffix] : names).map(capitalize).join("");
|
|
1041
1034
|
};
|
|
@@ -1195,6 +1188,11 @@ var scalarDefinitions = [
|
|
|
1195
1188
|
required: true,
|
|
1196
1189
|
type: astBuilder.TYPES.String
|
|
1197
1190
|
}),
|
|
1191
|
+
astBuilder.FieldDefinition({
|
|
1192
|
+
name: "hasReferences",
|
|
1193
|
+
required: false,
|
|
1194
|
+
type: astBuilder.TYPES.Boolean
|
|
1195
|
+
}),
|
|
1198
1196
|
astBuilder.FieldDefinition({
|
|
1199
1197
|
name: "breadcrumbs",
|
|
1200
1198
|
required: true,
|
|
@@ -1408,6 +1406,19 @@ var Builder = class {
|
|
|
1408
1406
|
this.addToLookupMap = (lookup) => {
|
|
1409
1407
|
this.lookupMap[lookup.type] = lookup;
|
|
1410
1408
|
};
|
|
1409
|
+
/**
|
|
1410
|
+
* ```graphql
|
|
1411
|
+
* # ex.
|
|
1412
|
+
* {
|
|
1413
|
+
* getCollection(collection: $collection) {
|
|
1414
|
+
* name
|
|
1415
|
+
* documents {...}
|
|
1416
|
+
* }
|
|
1417
|
+
* }
|
|
1418
|
+
* ```
|
|
1419
|
+
*
|
|
1420
|
+
* @param collections
|
|
1421
|
+
*/
|
|
1411
1422
|
this.buildCollectionDefinition = async (collections) => {
|
|
1412
1423
|
const name = "collection";
|
|
1413
1424
|
const typeName = "Collection";
|
|
@@ -1478,6 +1489,19 @@ var Builder = class {
|
|
|
1478
1489
|
required: true
|
|
1479
1490
|
});
|
|
1480
1491
|
};
|
|
1492
|
+
/**
|
|
1493
|
+
* ```graphql
|
|
1494
|
+
* # ex.
|
|
1495
|
+
* {
|
|
1496
|
+
* getCollections {
|
|
1497
|
+
* name
|
|
1498
|
+
* documents {...}
|
|
1499
|
+
* }
|
|
1500
|
+
* }
|
|
1501
|
+
* ```
|
|
1502
|
+
*
|
|
1503
|
+
* @param collections
|
|
1504
|
+
*/
|
|
1481
1505
|
this.buildMultiCollectionDefinition = async (collections) => {
|
|
1482
1506
|
const name = "collections";
|
|
1483
1507
|
const typeName = "Collection";
|
|
@@ -1488,6 +1512,17 @@ var Builder = class {
|
|
|
1488
1512
|
required: true
|
|
1489
1513
|
});
|
|
1490
1514
|
};
|
|
1515
|
+
/**
|
|
1516
|
+
* ```graphql
|
|
1517
|
+
* # ex.
|
|
1518
|
+
* {
|
|
1519
|
+
* node(id: $id) {
|
|
1520
|
+
* id
|
|
1521
|
+
* data {...}
|
|
1522
|
+
* }
|
|
1523
|
+
* }
|
|
1524
|
+
* ```
|
|
1525
|
+
*/
|
|
1491
1526
|
this.multiNodeDocument = async () => {
|
|
1492
1527
|
const name = "node";
|
|
1493
1528
|
const args = [
|
|
@@ -1508,6 +1543,19 @@ var Builder = class {
|
|
|
1508
1543
|
required: true
|
|
1509
1544
|
});
|
|
1510
1545
|
};
|
|
1546
|
+
/**
|
|
1547
|
+
* ```graphql
|
|
1548
|
+
* # ex.
|
|
1549
|
+
* {
|
|
1550
|
+
* getDocument(collection: $collection, relativePath: $relativePath) {
|
|
1551
|
+
* id
|
|
1552
|
+
* data {...}
|
|
1553
|
+
* }
|
|
1554
|
+
* }
|
|
1555
|
+
* ```
|
|
1556
|
+
*
|
|
1557
|
+
* @param collections
|
|
1558
|
+
*/
|
|
1511
1559
|
this.multiCollectionDocument = async (collections) => {
|
|
1512
1560
|
const name = "document";
|
|
1513
1561
|
const args = [
|
|
@@ -1533,6 +1581,19 @@ var Builder = class {
|
|
|
1533
1581
|
required: true
|
|
1534
1582
|
});
|
|
1535
1583
|
};
|
|
1584
|
+
/**
|
|
1585
|
+
* ```graphql
|
|
1586
|
+
* # ex.
|
|
1587
|
+
* {
|
|
1588
|
+
* addPendingDocument(collection: $collection, relativePath: $relativePath, params: $params) {
|
|
1589
|
+
* id
|
|
1590
|
+
* data {...}
|
|
1591
|
+
* }
|
|
1592
|
+
* }
|
|
1593
|
+
* ```
|
|
1594
|
+
*
|
|
1595
|
+
* @param collections
|
|
1596
|
+
*/
|
|
1536
1597
|
this.addMultiCollectionDocumentMutation = async () => {
|
|
1537
1598
|
return astBuilder.FieldDefinition({
|
|
1538
1599
|
name: "addPendingDocument",
|
|
@@ -1557,6 +1618,19 @@ var Builder = class {
|
|
|
1557
1618
|
type: astBuilder.TYPES.MultiCollectionDocument
|
|
1558
1619
|
});
|
|
1559
1620
|
};
|
|
1621
|
+
/**
|
|
1622
|
+
* ```graphql
|
|
1623
|
+
* # ex.
|
|
1624
|
+
* {
|
|
1625
|
+
* createDocument(relativePath: $relativePath, params: $params) {
|
|
1626
|
+
* id
|
|
1627
|
+
* data {...}
|
|
1628
|
+
* }
|
|
1629
|
+
* }
|
|
1630
|
+
* ```
|
|
1631
|
+
*
|
|
1632
|
+
* @param collections
|
|
1633
|
+
*/
|
|
1560
1634
|
this.buildCreateCollectionDocumentMutation = async (collections) => {
|
|
1561
1635
|
return astBuilder.FieldDefinition({
|
|
1562
1636
|
name: "createDocument",
|
|
@@ -1584,6 +1658,19 @@ var Builder = class {
|
|
|
1584
1658
|
type: astBuilder.TYPES.MultiCollectionDocument
|
|
1585
1659
|
});
|
|
1586
1660
|
};
|
|
1661
|
+
/**
|
|
1662
|
+
* ```graphql
|
|
1663
|
+
* # ex.
|
|
1664
|
+
* {
|
|
1665
|
+
* updateDocument(relativePath: $relativePath, params: $params) {
|
|
1666
|
+
* id
|
|
1667
|
+
* data {...}
|
|
1668
|
+
* }
|
|
1669
|
+
* }
|
|
1670
|
+
* ```
|
|
1671
|
+
*
|
|
1672
|
+
* @param collections
|
|
1673
|
+
*/
|
|
1587
1674
|
this.buildUpdateCollectionDocumentMutation = async (collections) => {
|
|
1588
1675
|
return astBuilder.FieldDefinition({
|
|
1589
1676
|
name: "updateDocument",
|
|
@@ -1611,6 +1698,19 @@ var Builder = class {
|
|
|
1611
1698
|
type: astBuilder.TYPES.MultiCollectionDocument
|
|
1612
1699
|
});
|
|
1613
1700
|
};
|
|
1701
|
+
/**
|
|
1702
|
+
* ```graphql
|
|
1703
|
+
* # ex.
|
|
1704
|
+
* {
|
|
1705
|
+
* deleteDocument(relativePath: $relativePath, params: $params) {
|
|
1706
|
+
* id
|
|
1707
|
+
* data {...}
|
|
1708
|
+
* }
|
|
1709
|
+
* }
|
|
1710
|
+
* ```
|
|
1711
|
+
*
|
|
1712
|
+
* @param collections
|
|
1713
|
+
*/
|
|
1614
1714
|
this.buildDeleteCollectionDocumentMutation = async (collections) => {
|
|
1615
1715
|
return astBuilder.FieldDefinition({
|
|
1616
1716
|
name: "deleteDocument",
|
|
@@ -1630,6 +1730,19 @@ var Builder = class {
|
|
|
1630
1730
|
type: astBuilder.TYPES.MultiCollectionDocument
|
|
1631
1731
|
});
|
|
1632
1732
|
};
|
|
1733
|
+
/**
|
|
1734
|
+
* ```graphql
|
|
1735
|
+
* # ex.
|
|
1736
|
+
* {
|
|
1737
|
+
* createFolder(folderName: $folderName, params: $params) {
|
|
1738
|
+
* id
|
|
1739
|
+
* data {...}
|
|
1740
|
+
* }
|
|
1741
|
+
* }
|
|
1742
|
+
* ```
|
|
1743
|
+
*
|
|
1744
|
+
* @param collections
|
|
1745
|
+
*/
|
|
1633
1746
|
this.buildCreateCollectionFolderMutation = async () => {
|
|
1634
1747
|
return astBuilder.FieldDefinition({
|
|
1635
1748
|
name: "createFolder",
|
|
@@ -1649,6 +1762,19 @@ var Builder = class {
|
|
|
1649
1762
|
type: astBuilder.TYPES.MultiCollectionDocument
|
|
1650
1763
|
});
|
|
1651
1764
|
};
|
|
1765
|
+
/**
|
|
1766
|
+
* ```graphql
|
|
1767
|
+
* # ex.
|
|
1768
|
+
* {
|
|
1769
|
+
* getPostDocument(relativePath: $relativePath) {
|
|
1770
|
+
* id
|
|
1771
|
+
* data {...}
|
|
1772
|
+
* }
|
|
1773
|
+
* }
|
|
1774
|
+
* ```
|
|
1775
|
+
*
|
|
1776
|
+
* @param collection
|
|
1777
|
+
*/
|
|
1652
1778
|
this.collectionDocument = async (collection) => {
|
|
1653
1779
|
const name = NAMER.queryName([collection.name]);
|
|
1654
1780
|
const type = await this._buildCollectionDocumentType(collection);
|
|
@@ -1709,6 +1835,20 @@ var Builder = class {
|
|
|
1709
1835
|
const args = [];
|
|
1710
1836
|
return astBuilder.FieldDefinition({ type, name, args, required: false });
|
|
1711
1837
|
};
|
|
1838
|
+
/**
|
|
1839
|
+
* Turns a collection into a fragment that gets updated on build. This fragment does not resolve references
|
|
1840
|
+
* ```graphql
|
|
1841
|
+
* # ex.
|
|
1842
|
+
* fragment AuthorsParts on Authors {
|
|
1843
|
+
* name
|
|
1844
|
+
* avatar
|
|
1845
|
+
* ...
|
|
1846
|
+
* }
|
|
1847
|
+
* ```
|
|
1848
|
+
*
|
|
1849
|
+
* @public
|
|
1850
|
+
* @param collection a Tina Cloud collection
|
|
1851
|
+
*/
|
|
1712
1852
|
this.collectionFragment = async (collection) => {
|
|
1713
1853
|
const name = NAMER.dataTypeName(collection.namespace);
|
|
1714
1854
|
const fragmentName = NAMER.fragmentName(collection.namespace);
|
|
@@ -1722,6 +1862,20 @@ var Builder = class {
|
|
|
1722
1862
|
selections: filterSelections(selections)
|
|
1723
1863
|
});
|
|
1724
1864
|
};
|
|
1865
|
+
/**
|
|
1866
|
+
* Given a collection this function returns its selections set. For example for Post this would return
|
|
1867
|
+
*
|
|
1868
|
+
* "
|
|
1869
|
+
* body
|
|
1870
|
+
* title
|
|
1871
|
+
* ... on Author {
|
|
1872
|
+
* name
|
|
1873
|
+
* heroImg
|
|
1874
|
+
* }
|
|
1875
|
+
*
|
|
1876
|
+
* But in the AST format
|
|
1877
|
+
*
|
|
1878
|
+
* */
|
|
1725
1879
|
this._getCollectionFragmentSelections = async (collection, depth) => {
|
|
1726
1880
|
const selections = [];
|
|
1727
1881
|
selections.push({
|
|
@@ -1803,9 +1957,9 @@ var Builder = class {
|
|
|
1803
1957
|
]
|
|
1804
1958
|
});
|
|
1805
1959
|
}
|
|
1960
|
+
// TODO: Should we throw here?
|
|
1806
1961
|
case "reference":
|
|
1807
|
-
if (depth >= this.maxDepth)
|
|
1808
|
-
return false;
|
|
1962
|
+
if (depth >= this.maxDepth) return false;
|
|
1809
1963
|
if (!("collections" in field)) {
|
|
1810
1964
|
return false;
|
|
1811
1965
|
}
|
|
@@ -1837,6 +1991,7 @@ var Builder = class {
|
|
|
1837
1991
|
name: field.name,
|
|
1838
1992
|
selections: [
|
|
1839
1993
|
...selections,
|
|
1994
|
+
// This is ... on Document { id }
|
|
1840
1995
|
{
|
|
1841
1996
|
kind: "InlineFragment",
|
|
1842
1997
|
typeCondition: {
|
|
@@ -1867,6 +2022,19 @@ var Builder = class {
|
|
|
1867
2022
|
});
|
|
1868
2023
|
}
|
|
1869
2024
|
};
|
|
2025
|
+
/**
|
|
2026
|
+
* ```graphql
|
|
2027
|
+
* # ex.
|
|
2028
|
+
* mutation {
|
|
2029
|
+
* updatePostDocument(relativePath: $relativePath, params: $params) {
|
|
2030
|
+
* id
|
|
2031
|
+
* data {...}
|
|
2032
|
+
* }
|
|
2033
|
+
* }
|
|
2034
|
+
* ```
|
|
2035
|
+
*
|
|
2036
|
+
* @param collection
|
|
2037
|
+
*/
|
|
1870
2038
|
this.updateCollectionDocumentMutation = async (collection) => {
|
|
1871
2039
|
return astBuilder.FieldDefinition({
|
|
1872
2040
|
type: await this._buildCollectionDocumentType(collection),
|
|
@@ -1886,6 +2054,19 @@ var Builder = class {
|
|
|
1886
2054
|
]
|
|
1887
2055
|
});
|
|
1888
2056
|
};
|
|
2057
|
+
/**
|
|
2058
|
+
* ```graphql
|
|
2059
|
+
* # ex.
|
|
2060
|
+
* mutation {
|
|
2061
|
+
* createPostDocument(relativePath: $relativePath, params: $params) {
|
|
2062
|
+
* id
|
|
2063
|
+
* data {...}
|
|
2064
|
+
* }
|
|
2065
|
+
* }
|
|
2066
|
+
* ```
|
|
2067
|
+
*
|
|
2068
|
+
* @param collection
|
|
2069
|
+
*/
|
|
1889
2070
|
this.createCollectionDocumentMutation = async (collection) => {
|
|
1890
2071
|
return astBuilder.FieldDefinition({
|
|
1891
2072
|
type: await this._buildCollectionDocumentType(collection),
|
|
@@ -1905,6 +2086,22 @@ var Builder = class {
|
|
|
1905
2086
|
]
|
|
1906
2087
|
});
|
|
1907
2088
|
};
|
|
2089
|
+
/**
|
|
2090
|
+
* ```graphql
|
|
2091
|
+
* # ex.
|
|
2092
|
+
* {
|
|
2093
|
+
* getPostList(first: 10) {
|
|
2094
|
+
* edges {
|
|
2095
|
+
* node {
|
|
2096
|
+
* id
|
|
2097
|
+
* }
|
|
2098
|
+
* }
|
|
2099
|
+
* }
|
|
2100
|
+
* }
|
|
2101
|
+
* ```
|
|
2102
|
+
*
|
|
2103
|
+
* @param collection
|
|
2104
|
+
*/
|
|
1908
2105
|
this.collectionDocumentList = async (collection) => {
|
|
1909
2106
|
const connectionName = NAMER.referenceConnectionType(collection.namespace);
|
|
1910
2107
|
this.addToLookupMap({
|
|
@@ -1920,6 +2117,10 @@ var Builder = class {
|
|
|
1920
2117
|
collection
|
|
1921
2118
|
});
|
|
1922
2119
|
};
|
|
2120
|
+
/**
|
|
2121
|
+
* GraphQL type definitions which remain unchanged regardless
|
|
2122
|
+
* of the supplied Tina schema. Ex. "node" interface
|
|
2123
|
+
*/
|
|
1923
2124
|
this.buildStaticDefinitions = () => staticDefinitions;
|
|
1924
2125
|
this._buildCollectionDocumentType = async (collection, suffix = "", extraFields = [], extraInterfaces = []) => {
|
|
1925
2126
|
const documentTypeName = NAMER.documentTypeName(collection.namespace);
|
|
@@ -2424,6 +2625,7 @@ var Builder = class {
|
|
|
2424
2625
|
name: NAMER.dataFilterTypeName(namespace),
|
|
2425
2626
|
fields: await sequential(collections, async (collection2) => {
|
|
2426
2627
|
return astBuilder.InputValueDefinition({
|
|
2628
|
+
// @ts-ignore
|
|
2427
2629
|
name: collection2.name,
|
|
2428
2630
|
type: NAMER.dataFilterTypeName(collection2.namespace)
|
|
2429
2631
|
});
|
|
@@ -2612,7 +2814,8 @@ Visit https://tina.io/docs/errors/ui-not-supported/ for more information
|
|
|
2612
2814
|
]
|
|
2613
2815
|
});
|
|
2614
2816
|
};
|
|
2615
|
-
this.maxDepth =
|
|
2817
|
+
this.maxDepth = // @ts-ignore
|
|
2818
|
+
config?.tinaSchema.schema?.config?.client?.referenceDepth ?? 2;
|
|
2616
2819
|
this.tinaSchema = config.tinaSchema;
|
|
2617
2820
|
this.lookupMap = {};
|
|
2618
2821
|
}
|
|
@@ -2623,8 +2826,7 @@ Visit https://tina.io/docs/errors/ui-not-supported/ for more information
|
|
|
2623
2826
|
selections.push(field);
|
|
2624
2827
|
});
|
|
2625
2828
|
const filteredSelections = filterSelections(selections);
|
|
2626
|
-
if (!filteredSelections.length)
|
|
2627
|
-
return false;
|
|
2829
|
+
if (!filteredSelections.length) return false;
|
|
2628
2830
|
return astBuilder.InlineFragmentDefinition({
|
|
2629
2831
|
selections: filteredSelections,
|
|
2630
2832
|
name: NAMER.dataTypeName(template.namespace)
|
|
@@ -2661,6 +2863,7 @@ var filterSelections = (arr) => {
|
|
|
2661
2863
|
import { TinaSchema } from "@tinacms/schema-tools";
|
|
2662
2864
|
|
|
2663
2865
|
// src/schema/validate.ts
|
|
2866
|
+
import { addNamespaceToSchema } from "@tinacms/schema-tools";
|
|
2664
2867
|
import deepClone from "lodash.clonedeep";
|
|
2665
2868
|
import * as yup2 from "yup";
|
|
2666
2869
|
import {
|
|
@@ -2707,6 +2910,7 @@ var validationCollectionsPathAndMatch = (collections) => {
|
|
|
2707
2910
|
}).map((x) => `${x.path}${x.format || "md"}`);
|
|
2708
2911
|
if (noMatchCollections.length !== new Set(noMatchCollections).size) {
|
|
2709
2912
|
throw new Error(
|
|
2913
|
+
// TODO: add a link to the docs
|
|
2710
2914
|
"Two collections without match can not have the same `path`. Please make the `path` unique or add a matches property to the collection."
|
|
2711
2915
|
);
|
|
2712
2916
|
}
|
|
@@ -2815,7 +3019,7 @@ var validateField = async (field) => {
|
|
|
2815
3019
|
// package.json
|
|
2816
3020
|
var package_default = {
|
|
2817
3021
|
name: "@tinacms/graphql",
|
|
2818
|
-
version: "1.5.
|
|
3022
|
+
version: "1.5.12",
|
|
2819
3023
|
main: "dist/index.js",
|
|
2820
3024
|
module: "dist/index.mjs",
|
|
2821
3025
|
typings: "dist/index.d.ts",
|
|
@@ -2842,8 +3046,8 @@ var package_default = {
|
|
|
2842
3046
|
build: "tinacms-scripts build",
|
|
2843
3047
|
docs: "pnpm typedoc",
|
|
2844
3048
|
serve: "pnpm nodemon dist/server.js",
|
|
2845
|
-
test: "
|
|
2846
|
-
"test-watch": "
|
|
3049
|
+
test: "vitest run",
|
|
3050
|
+
"test-watch": "vitest"
|
|
2847
3051
|
},
|
|
2848
3052
|
dependencies: {
|
|
2849
3053
|
"@iarna/toml": "^2.2.5",
|
|
@@ -2859,7 +3063,7 @@ var package_default = {
|
|
|
2859
3063
|
"isomorphic-git": "^1.27.1",
|
|
2860
3064
|
"js-sha1": "^0.6.0",
|
|
2861
3065
|
"js-yaml": "^3.14.1",
|
|
2862
|
-
"jsonpath-plus": "
|
|
3066
|
+
"jsonpath-plus": "10.1.0",
|
|
2863
3067
|
"lodash.clonedeep": "^4.5.0",
|
|
2864
3068
|
"lodash.set": "^4.3.2",
|
|
2865
3069
|
"lodash.uniqby": "^4.7.0",
|
|
@@ -2884,24 +3088,23 @@ var package_default = {
|
|
|
2884
3088
|
"@types/estree": "^0.0.50",
|
|
2885
3089
|
"@types/express": "^4.17.21",
|
|
2886
3090
|
"@types/fs-extra": "^9.0.13",
|
|
2887
|
-
"@types/jest": "^26.0.24",
|
|
2888
3091
|
"@types/js-yaml": "^3.12.10",
|
|
2889
3092
|
"@types/lodash.camelcase": "^4.3.9",
|
|
2890
3093
|
"@types/lodash.upperfirst": "^4.3.9",
|
|
2891
3094
|
"@types/lru-cache": "^5.1.1",
|
|
2892
3095
|
"@types/mdast": "^3.0.15",
|
|
2893
3096
|
"@types/micromatch": "^4.0.9",
|
|
2894
|
-
"@types/node": "^22.
|
|
3097
|
+
"@types/node": "^22.9.0",
|
|
2895
3098
|
"@types/normalize-path": "^3.0.2",
|
|
2896
3099
|
"@types/ws": "^7.4.7",
|
|
2897
3100
|
"@types/yup": "^0.29.14",
|
|
2898
|
-
jest: "^29.7.0",
|
|
2899
|
-
"jest-diff": "^29.7.0",
|
|
2900
3101
|
"jest-file-snapshot": "^0.5.0",
|
|
2901
|
-
"jest-matcher-utils": "^29.7.0",
|
|
2902
3102
|
"memory-level": "^1.0.0",
|
|
2903
3103
|
nodemon: "3.1.4",
|
|
2904
|
-
typescript: "^5.6.
|
|
3104
|
+
typescript: "^5.6.3",
|
|
3105
|
+
vite: "^4.3.9",
|
|
3106
|
+
vitest: "^0.32.2",
|
|
3107
|
+
zod: "^3.23.8"
|
|
2905
3108
|
}
|
|
2906
3109
|
};
|
|
2907
3110
|
|
|
@@ -2972,6 +3175,7 @@ var _buildFragments = async (builder, tinaSchema) => {
|
|
|
2972
3175
|
const fragDoc = {
|
|
2973
3176
|
kind: "Document",
|
|
2974
3177
|
definitions: uniqBy2(
|
|
3178
|
+
// @ts-ignore
|
|
2975
3179
|
extractInlineTypes(fragmentDefinitionsFields),
|
|
2976
3180
|
(node) => node.name.value
|
|
2977
3181
|
)
|
|
@@ -2994,6 +3198,7 @@ var _buildQueries = async (builder, tinaSchema) => {
|
|
|
2994
3198
|
fragName,
|
|
2995
3199
|
queryName: queryListName,
|
|
2996
3200
|
filterType: queryFilterTypeName,
|
|
3201
|
+
// look for flag to see if the data layer is enabled
|
|
2997
3202
|
dataLayer: Boolean(
|
|
2998
3203
|
tinaSchema.config?.meta?.flags?.find((x) => x === "experimentalData")
|
|
2999
3204
|
)
|
|
@@ -3003,6 +3208,7 @@ var _buildQueries = async (builder, tinaSchema) => {
|
|
|
3003
3208
|
const queryDoc = {
|
|
3004
3209
|
kind: "Document",
|
|
3005
3210
|
definitions: uniqBy2(
|
|
3211
|
+
// @ts-ignore
|
|
3006
3212
|
extractInlineTypes(operationsDefinitions),
|
|
3007
3213
|
(node) => node.name.value
|
|
3008
3214
|
)
|
|
@@ -3091,6 +3297,7 @@ var _buildSchema = async (builder, tinaSchema) => {
|
|
|
3091
3297
|
return {
|
|
3092
3298
|
kind: "Document",
|
|
3093
3299
|
definitions: uniqBy2(
|
|
3300
|
+
// @ts-ignore
|
|
3094
3301
|
extractInlineTypes(definitions),
|
|
3095
3302
|
(node) => node.name.value
|
|
3096
3303
|
)
|
|
@@ -3107,6 +3314,9 @@ import isValid from "date-fns/isValid/index.js";
|
|
|
3107
3314
|
// src/mdx/index.ts
|
|
3108
3315
|
import { parseMDX, stringifyMDX } from "@tinacms/mdx";
|
|
3109
3316
|
|
|
3317
|
+
// src/resolver/index.ts
|
|
3318
|
+
import { JSONPath as JSONPath2 } from "jsonpath-plus";
|
|
3319
|
+
|
|
3110
3320
|
// src/resolver/error.ts
|
|
3111
3321
|
var TinaGraphQLError = class extends Error {
|
|
3112
3322
|
constructor(message, extensions) {
|
|
@@ -3292,8 +3502,7 @@ var resolveMediaCloudToRelative = (value, config = { useRelativeMedia: true }, s
|
|
|
3292
3502
|
}
|
|
3293
3503
|
if (Array.isArray(value)) {
|
|
3294
3504
|
return value.map((v) => {
|
|
3295
|
-
if (!v || typeof v !== "string")
|
|
3296
|
-
return v;
|
|
3505
|
+
if (!v || typeof v !== "string") return v;
|
|
3297
3506
|
const cleanMediaRoot = cleanUpSlashes(
|
|
3298
3507
|
schema.config.media.tina.mediaRoot
|
|
3299
3508
|
);
|
|
@@ -3321,8 +3530,7 @@ var resolveMediaRelativeToCloud = (value, config = { useRelativeMedia: true }, s
|
|
|
3321
3530
|
}
|
|
3322
3531
|
if (Array.isArray(value)) {
|
|
3323
3532
|
return value.map((v) => {
|
|
3324
|
-
if (!v || typeof v !== "string")
|
|
3325
|
-
return v;
|
|
3533
|
+
if (!v || typeof v !== "string") return v;
|
|
3326
3534
|
const strippedValue = v.replace(cleanMediaRoot, "");
|
|
3327
3535
|
return `https://${config.assetsHost}/${config.clientId}${strippedValue}`;
|
|
3328
3536
|
});
|
|
@@ -3340,8 +3548,7 @@ var cleanUpSlashes = (path7) => {
|
|
|
3340
3548
|
return "";
|
|
3341
3549
|
};
|
|
3342
3550
|
var hasTinaMediaConfig = (schema) => {
|
|
3343
|
-
if (!schema.config?.media?.tina)
|
|
3344
|
-
return false;
|
|
3551
|
+
if (!schema.config?.media?.tina) return false;
|
|
3345
3552
|
if (typeof schema.config?.media?.tina?.publicFolder !== "string" && typeof schema.config?.media?.tina?.mediaRoot !== "string")
|
|
3346
3553
|
return false;
|
|
3347
3554
|
return true;
|
|
@@ -3385,6 +3592,7 @@ var LevelProxyHandler = {
|
|
|
3385
3592
|
} else if (property === "sublevel") {
|
|
3386
3593
|
return (...args) => {
|
|
3387
3594
|
return new Proxy(
|
|
3595
|
+
// eslint-disable-next-line prefer-spread
|
|
3388
3596
|
target[property].apply(target, args),
|
|
3389
3597
|
LevelProxyHandler
|
|
3390
3598
|
);
|
|
@@ -3752,6 +3960,9 @@ var loadAndParseWithAliases = async (bridge, filepath, collection, templateInfo)
|
|
|
3752
3960
|
|
|
3753
3961
|
// src/database/datalayer.ts
|
|
3754
3962
|
var DEFAULT_COLLECTION_SORT_KEY = "__filepath__";
|
|
3963
|
+
var REFS_COLLECTIONS_SORT_KEY = "__refs__";
|
|
3964
|
+
var REFS_REFERENCE_FIELD = "__tina_ref__";
|
|
3965
|
+
var REFS_PATH_FIELD = "__tina_ref_path__";
|
|
3755
3966
|
var DEFAULT_NUMERIC_LPAD = 4;
|
|
3756
3967
|
var applyPadding = (input, pad) => {
|
|
3757
3968
|
if (pad) {
|
|
@@ -4261,6 +4472,7 @@ var makeFolderOpsForCollection = (folderTree, collection, indexDefinitions, opTy
|
|
|
4261
4472
|
result.push({
|
|
4262
4473
|
type: opType,
|
|
4263
4474
|
key: `${collection.path}/${subFolderKey}.${collection.format}`,
|
|
4475
|
+
// replace the root with the collection path
|
|
4264
4476
|
sublevel: indexSublevel,
|
|
4265
4477
|
value: {}
|
|
4266
4478
|
});
|
|
@@ -4324,6 +4536,41 @@ var makeIndexOpsForDocument = (filepath, collection, indexDefinitions, data, opT
|
|
|
4324
4536
|
}
|
|
4325
4537
|
return result;
|
|
4326
4538
|
};
|
|
4539
|
+
var makeRefOpsForDocument = (filepath, collection, references, data, opType, level) => {
|
|
4540
|
+
const result = [];
|
|
4541
|
+
if (collection) {
|
|
4542
|
+
for (const [c, referencePaths] of Object.entries(references || {})) {
|
|
4543
|
+
if (!referencePaths.length) {
|
|
4544
|
+
continue;
|
|
4545
|
+
}
|
|
4546
|
+
const collectionSublevel = level.sublevel(c, SUBLEVEL_OPTIONS);
|
|
4547
|
+
const refSublevel = collectionSublevel.sublevel(
|
|
4548
|
+
REFS_COLLECTIONS_SORT_KEY,
|
|
4549
|
+
SUBLEVEL_OPTIONS
|
|
4550
|
+
);
|
|
4551
|
+
const references2 = {};
|
|
4552
|
+
for (const path7 of referencePaths) {
|
|
4553
|
+
const ref = JSONPath({ path: path7, json: data });
|
|
4554
|
+
if (references2[ref]) {
|
|
4555
|
+
references2[ref].push(path7);
|
|
4556
|
+
} else {
|
|
4557
|
+
references2[ref] = [path7];
|
|
4558
|
+
}
|
|
4559
|
+
}
|
|
4560
|
+
for (const ref of Object.keys(references2)) {
|
|
4561
|
+
for (const path7 of references2[ref]) {
|
|
4562
|
+
result.push({
|
|
4563
|
+
type: opType,
|
|
4564
|
+
key: `${ref}${INDEX_KEY_FIELD_SEPARATOR}${path7}${INDEX_KEY_FIELD_SEPARATOR}${filepath}`,
|
|
4565
|
+
sublevel: refSublevel,
|
|
4566
|
+
value: opType === "put" ? {} : void 0
|
|
4567
|
+
});
|
|
4568
|
+
}
|
|
4569
|
+
}
|
|
4570
|
+
}
|
|
4571
|
+
}
|
|
4572
|
+
return result;
|
|
4573
|
+
};
|
|
4327
4574
|
var makeStringEscaper = (regex, replacement) => {
|
|
4328
4575
|
return (input) => {
|
|
4329
4576
|
if (Array.isArray(input)) {
|
|
@@ -4375,6 +4622,7 @@ var resolveFieldData = async ({ namespace, ...field }, rawData, accumulator, tin
|
|
|
4375
4622
|
case "password":
|
|
4376
4623
|
accumulator[field.name] = {
|
|
4377
4624
|
value: void 0,
|
|
4625
|
+
// never resolve the password hash
|
|
4378
4626
|
passwordChangeRequired: value["passwordChangeRequired"] ?? false
|
|
4379
4627
|
};
|
|
4380
4628
|
break;
|
|
@@ -4469,7 +4717,7 @@ var resolveFieldData = async ({ namespace, ...field }, rawData, accumulator, tin
|
|
|
4469
4717
|
}
|
|
4470
4718
|
return accumulator;
|
|
4471
4719
|
};
|
|
4472
|
-
var transformDocumentIntoPayload = async (fullPath, rawData, tinaSchema, config, isAudit) => {
|
|
4720
|
+
var transformDocumentIntoPayload = async (fullPath, rawData, tinaSchema, config, isAudit, hasReferences) => {
|
|
4473
4721
|
const collection = tinaSchema.getCollection(rawData._collection);
|
|
4474
4722
|
try {
|
|
4475
4723
|
const template = tinaSchema.getTemplateForData({
|
|
@@ -4523,6 +4771,7 @@ var transformDocumentIntoPayload = async (fullPath, rawData, tinaSchema, config,
|
|
|
4523
4771
|
basename,
|
|
4524
4772
|
filename,
|
|
4525
4773
|
extension,
|
|
4774
|
+
hasReferences,
|
|
4526
4775
|
path: fullPath,
|
|
4527
4776
|
relativePath,
|
|
4528
4777
|
breadcrumbs,
|
|
@@ -4542,6 +4791,25 @@ var transformDocumentIntoPayload = async (fullPath, rawData, tinaSchema, config,
|
|
|
4542
4791
|
throw e;
|
|
4543
4792
|
}
|
|
4544
4793
|
};
|
|
4794
|
+
var updateObjectWithJsonPath = (obj, path7, newValue) => {
|
|
4795
|
+
if (!path7.includes(".") && !path7.includes("[")) {
|
|
4796
|
+
if (path7 in obj) {
|
|
4797
|
+
obj[path7] = newValue;
|
|
4798
|
+
}
|
|
4799
|
+
return obj;
|
|
4800
|
+
}
|
|
4801
|
+
const parentPath = path7.replace(/\.[^.]+$/, "");
|
|
4802
|
+
const keyToUpdate = path7.match(/[^.]+$/)[0];
|
|
4803
|
+
const parents = JSONPath2({ path: parentPath, json: obj, resultType: "value" });
|
|
4804
|
+
if (parents.length > 0) {
|
|
4805
|
+
parents.forEach((parent) => {
|
|
4806
|
+
if (parent && typeof parent === "object" && keyToUpdate in parent) {
|
|
4807
|
+
parent[keyToUpdate] = newValue;
|
|
4808
|
+
}
|
|
4809
|
+
});
|
|
4810
|
+
}
|
|
4811
|
+
return obj;
|
|
4812
|
+
};
|
|
4545
4813
|
var Resolver = class {
|
|
4546
4814
|
constructor(init) {
|
|
4547
4815
|
this.init = init;
|
|
@@ -4549,6 +4817,7 @@ var Resolver = class {
|
|
|
4549
4817
|
const collection = this.tinaSchema.getCollection(collectionName);
|
|
4550
4818
|
const extraFields = {};
|
|
4551
4819
|
return {
|
|
4820
|
+
// return the collection and hasDocuments to resolve documents at a lower level
|
|
4552
4821
|
documents: { collection, hasDocuments },
|
|
4553
4822
|
...collection,
|
|
4554
4823
|
...extraFields
|
|
@@ -4583,17 +4852,19 @@ var Resolver = class {
|
|
|
4583
4852
|
);
|
|
4584
4853
|
}
|
|
4585
4854
|
};
|
|
4586
|
-
this.getDocument = async (fullPath) => {
|
|
4855
|
+
this.getDocument = async (fullPath, opts = {}) => {
|
|
4587
4856
|
if (typeof fullPath !== "string") {
|
|
4588
4857
|
throw new Error(`fullPath must be of type string for getDocument request`);
|
|
4589
4858
|
}
|
|
4590
4859
|
const rawData = await this.getRaw(fullPath);
|
|
4860
|
+
const hasReferences = opts?.checkReferences ? await this.hasReferences(fullPath, opts.collection) : void 0;
|
|
4591
4861
|
return transformDocumentIntoPayload(
|
|
4592
4862
|
fullPath,
|
|
4593
4863
|
rawData,
|
|
4594
4864
|
this.tinaSchema,
|
|
4595
4865
|
this.config,
|
|
4596
|
-
this.isAudit
|
|
4866
|
+
this.isAudit,
|
|
4867
|
+
hasReferences
|
|
4597
4868
|
);
|
|
4598
4869
|
};
|
|
4599
4870
|
this.deleteDocument = async (fullPath) => {
|
|
@@ -4633,7 +4904,9 @@ var Resolver = class {
|
|
|
4633
4904
|
);
|
|
4634
4905
|
} else {
|
|
4635
4906
|
return this.buildFieldMutations(
|
|
4907
|
+
// @ts-ignore FIXME Argument of type 'string | object' is not assignable to parameter of type '{ [fieldName: string]: string | object | (string | object)[]; }'
|
|
4636
4908
|
fieldValue,
|
|
4909
|
+
//@ts-ignore
|
|
4637
4910
|
objectTemplate,
|
|
4638
4911
|
existingData
|
|
4639
4912
|
);
|
|
@@ -4645,6 +4918,7 @@ var Resolver = class {
|
|
|
4645
4918
|
fieldValue.map(async (item) => {
|
|
4646
4919
|
if (typeof item === "string") {
|
|
4647
4920
|
throw new Error(
|
|
4921
|
+
//@ts-ignore
|
|
4648
4922
|
`Expected object for template value for field ${field.name}`
|
|
4649
4923
|
);
|
|
4650
4924
|
}
|
|
@@ -4653,16 +4927,19 @@ var Resolver = class {
|
|
|
4653
4927
|
});
|
|
4654
4928
|
const [templateName] = Object.entries(item)[0];
|
|
4655
4929
|
const template = templates.find(
|
|
4930
|
+
//@ts-ignore
|
|
4656
4931
|
(template2) => template2.name === templateName
|
|
4657
4932
|
);
|
|
4658
4933
|
if (!template) {
|
|
4659
4934
|
throw new Error(`Expected to find template ${templateName}`);
|
|
4660
4935
|
}
|
|
4661
4936
|
return {
|
|
4937
|
+
// @ts-ignore FIXME Argument of type 'unknown' is not assignable to parameter of type '{ [fieldName: string]: string | { [key: string]: unknown; } | (string | { [key: string]: unknown; })[]; }'
|
|
4662
4938
|
...await this.buildFieldMutations(
|
|
4663
4939
|
item[template.name],
|
|
4664
4940
|
template
|
|
4665
4941
|
),
|
|
4942
|
+
//@ts-ignore
|
|
4666
4943
|
_template: template.name
|
|
4667
4944
|
};
|
|
4668
4945
|
})
|
|
@@ -4670,6 +4947,7 @@ var Resolver = class {
|
|
|
4670
4947
|
} else {
|
|
4671
4948
|
if (typeof fieldValue === "string") {
|
|
4672
4949
|
throw new Error(
|
|
4950
|
+
//@ts-ignore
|
|
4673
4951
|
`Expected object for template value for field ${field.name}`
|
|
4674
4952
|
);
|
|
4675
4953
|
}
|
|
@@ -4678,16 +4956,19 @@ var Resolver = class {
|
|
|
4678
4956
|
});
|
|
4679
4957
|
const [templateName] = Object.entries(fieldValue)[0];
|
|
4680
4958
|
const template = templates.find(
|
|
4959
|
+
//@ts-ignore
|
|
4681
4960
|
(template2) => template2.name === templateName
|
|
4682
4961
|
);
|
|
4683
4962
|
if (!template) {
|
|
4684
4963
|
throw new Error(`Expected to find template ${templateName}`);
|
|
4685
4964
|
}
|
|
4686
4965
|
return {
|
|
4966
|
+
// @ts-ignore FIXME Argument of type 'unknown' is not assignable to parameter of type '{ [fieldName: string]: string | { [key: string]: unknown; } | (string | { [key: string]: unknown; })[]; }'
|
|
4687
4967
|
...await this.buildFieldMutations(
|
|
4688
4968
|
fieldValue[template.name],
|
|
4689
4969
|
template
|
|
4690
4970
|
),
|
|
4971
|
+
//@ts-ignore
|
|
4691
4972
|
_template: template.name
|
|
4692
4973
|
};
|
|
4693
4974
|
}
|
|
@@ -4727,6 +5008,7 @@ var Resolver = class {
|
|
|
4727
5008
|
return this.getDocument(realPath);
|
|
4728
5009
|
}
|
|
4729
5010
|
const params = await this.buildObjectMutations(
|
|
5011
|
+
// @ts-ignore
|
|
4730
5012
|
args.params[collection.name],
|
|
4731
5013
|
collection
|
|
4732
5014
|
);
|
|
@@ -4772,6 +5054,7 @@ var Resolver = class {
|
|
|
4772
5054
|
const values = {
|
|
4773
5055
|
...oldDoc,
|
|
4774
5056
|
...await this.buildFieldMutations(
|
|
5057
|
+
// @ts-ignore FIXME: failing on unknown, which we don't need to know because it's recursive
|
|
4775
5058
|
templateParams,
|
|
4776
5059
|
template,
|
|
4777
5060
|
doc?._rawData
|
|
@@ -4785,6 +5068,7 @@ var Resolver = class {
|
|
|
4785
5068
|
return this.getDocument(realPath);
|
|
4786
5069
|
}
|
|
4787
5070
|
const params = await this.buildObjectMutations(
|
|
5071
|
+
//@ts-ignore
|
|
4788
5072
|
isCollectionSpecific ? args.params : args.params[collection.name],
|
|
4789
5073
|
collection,
|
|
4790
5074
|
doc?._rawData
|
|
@@ -4792,6 +5076,10 @@ var Resolver = class {
|
|
|
4792
5076
|
await this.database.put(realPath, { ...oldDoc, ...params }, collection.name);
|
|
4793
5077
|
return this.getDocument(realPath);
|
|
4794
5078
|
};
|
|
5079
|
+
/**
|
|
5080
|
+
* Returns top-level fields which are not defined in the collection, so their
|
|
5081
|
+
* values are not eliminated from Tina when new values are saved
|
|
5082
|
+
*/
|
|
4795
5083
|
this.resolveLegacyValues = (oldDoc, collection) => {
|
|
4796
5084
|
const legacyValues = {};
|
|
4797
5085
|
Object.entries(oldDoc).forEach(([key, value]) => {
|
|
@@ -4896,6 +5184,20 @@ var Resolver = class {
|
|
|
4896
5184
|
if (isDeletion) {
|
|
4897
5185
|
const doc = await this.getDocument(realPath);
|
|
4898
5186
|
await this.deleteDocument(realPath);
|
|
5187
|
+
if (await this.hasReferences(realPath, collection)) {
|
|
5188
|
+
const collRefs = await this.findReferences(realPath, collection);
|
|
5189
|
+
for (const [collection2, docsWithRefs] of Object.entries(collRefs)) {
|
|
5190
|
+
for (const [pathToDocWithRef, referencePaths] of Object.entries(
|
|
5191
|
+
docsWithRefs
|
|
5192
|
+
)) {
|
|
5193
|
+
let refDoc = await this.getRaw(pathToDocWithRef);
|
|
5194
|
+
for (const path7 of referencePaths) {
|
|
5195
|
+
refDoc = updateObjectWithJsonPath(refDoc, path7, null);
|
|
5196
|
+
}
|
|
5197
|
+
await this.database.put(pathToDocWithRef, refDoc, collection2);
|
|
5198
|
+
}
|
|
5199
|
+
}
|
|
5200
|
+
}
|
|
4899
5201
|
return doc;
|
|
4900
5202
|
}
|
|
4901
5203
|
if (isUpdateName) {
|
|
@@ -4914,6 +5216,22 @@ var Resolver = class {
|
|
|
4914
5216
|
);
|
|
4915
5217
|
await this.database.put(newRealPath, doc._rawData, collection.name);
|
|
4916
5218
|
await this.deleteDocument(realPath);
|
|
5219
|
+
const collRefs = await this.findReferences(realPath, collection);
|
|
5220
|
+
for (const [collection2, docsWithRefs] of Object.entries(collRefs)) {
|
|
5221
|
+
for (const [pathToDocWithRef, referencePaths] of Object.entries(
|
|
5222
|
+
docsWithRefs
|
|
5223
|
+
)) {
|
|
5224
|
+
let docWithRef = await this.getRaw(pathToDocWithRef);
|
|
5225
|
+
for (const path7 of referencePaths) {
|
|
5226
|
+
docWithRef = updateObjectWithJsonPath(
|
|
5227
|
+
docWithRef,
|
|
5228
|
+
path7,
|
|
5229
|
+
newRealPath
|
|
5230
|
+
);
|
|
5231
|
+
}
|
|
5232
|
+
await this.database.put(pathToDocWithRef, docWithRef, collection2);
|
|
5233
|
+
}
|
|
5234
|
+
}
|
|
4917
5235
|
return this.getDocument(newRealPath);
|
|
4918
5236
|
}
|
|
4919
5237
|
if (alreadyExists === false) {
|
|
@@ -4927,7 +5245,10 @@ var Resolver = class {
|
|
|
4927
5245
|
isCollectionSpecific
|
|
4928
5246
|
});
|
|
4929
5247
|
} else {
|
|
4930
|
-
return this.getDocument(realPath
|
|
5248
|
+
return this.getDocument(realPath, {
|
|
5249
|
+
collection,
|
|
5250
|
+
checkReferences: true
|
|
5251
|
+
});
|
|
4931
5252
|
}
|
|
4932
5253
|
};
|
|
4933
5254
|
this.resolveCollectionConnections = async ({ ids }) => {
|
|
@@ -4964,6 +5285,7 @@ var Resolver = class {
|
|
|
4964
5285
|
},
|
|
4965
5286
|
collection: referencedCollection,
|
|
4966
5287
|
hydrator: (path7) => path7
|
|
5288
|
+
// just return the path
|
|
4967
5289
|
}
|
|
4968
5290
|
);
|
|
4969
5291
|
const { edges } = resolvedCollectionConnection;
|
|
@@ -5031,6 +5353,82 @@ var Resolver = class {
|
|
|
5031
5353
|
}
|
|
5032
5354
|
};
|
|
5033
5355
|
};
|
|
5356
|
+
/**
|
|
5357
|
+
* Checks if a document has references to it
|
|
5358
|
+
* @param id The id of the document to check for references
|
|
5359
|
+
* @param c The collection to check for references
|
|
5360
|
+
* @returns true if the document has references, false otherwise
|
|
5361
|
+
*/
|
|
5362
|
+
this.hasReferences = async (id, c) => {
|
|
5363
|
+
let count = 0;
|
|
5364
|
+
await this.database.query(
|
|
5365
|
+
{
|
|
5366
|
+
collection: c.name,
|
|
5367
|
+
filterChain: makeFilterChain({
|
|
5368
|
+
conditions: [
|
|
5369
|
+
{
|
|
5370
|
+
filterPath: REFS_REFERENCE_FIELD,
|
|
5371
|
+
filterExpression: {
|
|
5372
|
+
_type: "string",
|
|
5373
|
+
_list: false,
|
|
5374
|
+
eq: id
|
|
5375
|
+
}
|
|
5376
|
+
}
|
|
5377
|
+
]
|
|
5378
|
+
}),
|
|
5379
|
+
sort: REFS_COLLECTIONS_SORT_KEY
|
|
5380
|
+
},
|
|
5381
|
+
(refId) => {
|
|
5382
|
+
count++;
|
|
5383
|
+
return refId;
|
|
5384
|
+
}
|
|
5385
|
+
);
|
|
5386
|
+
if (count) {
|
|
5387
|
+
return true;
|
|
5388
|
+
}
|
|
5389
|
+
return false;
|
|
5390
|
+
};
|
|
5391
|
+
/**
|
|
5392
|
+
* Finds references to a document
|
|
5393
|
+
* @param id the id of the document to find references to
|
|
5394
|
+
* @param c the collection to find references in
|
|
5395
|
+
* @returns a map of references to the document
|
|
5396
|
+
*/
|
|
5397
|
+
this.findReferences = async (id, c) => {
|
|
5398
|
+
const references = {};
|
|
5399
|
+
await this.database.query(
|
|
5400
|
+
{
|
|
5401
|
+
collection: c.name,
|
|
5402
|
+
filterChain: makeFilterChain({
|
|
5403
|
+
conditions: [
|
|
5404
|
+
{
|
|
5405
|
+
filterPath: REFS_REFERENCE_FIELD,
|
|
5406
|
+
filterExpression: {
|
|
5407
|
+
_type: "string",
|
|
5408
|
+
_list: false,
|
|
5409
|
+
eq: id
|
|
5410
|
+
}
|
|
5411
|
+
}
|
|
5412
|
+
]
|
|
5413
|
+
}),
|
|
5414
|
+
sort: REFS_COLLECTIONS_SORT_KEY
|
|
5415
|
+
},
|
|
5416
|
+
(refId, rawItem) => {
|
|
5417
|
+
if (!references[c.name]) {
|
|
5418
|
+
references[c.name] = {};
|
|
5419
|
+
}
|
|
5420
|
+
if (!references[c.name][refId]) {
|
|
5421
|
+
references[c.name][refId] = [];
|
|
5422
|
+
}
|
|
5423
|
+
const referencePath = rawItem?.[REFS_PATH_FIELD];
|
|
5424
|
+
if (referencePath) {
|
|
5425
|
+
references[c.name][refId].push(referencePath);
|
|
5426
|
+
}
|
|
5427
|
+
return refId;
|
|
5428
|
+
}
|
|
5429
|
+
);
|
|
5430
|
+
return references;
|
|
5431
|
+
};
|
|
5034
5432
|
this.buildFieldMutations = async (fieldParams, template, existingData) => {
|
|
5035
5433
|
const accum = {};
|
|
5036
5434
|
for (const passwordField of template.fields.filter(
|
|
@@ -5117,6 +5515,27 @@ var Resolver = class {
|
|
|
5117
5515
|
}
|
|
5118
5516
|
return accum;
|
|
5119
5517
|
};
|
|
5518
|
+
/**
|
|
5519
|
+
* A mutation looks nearly identical between updateDocument:
|
|
5520
|
+
* ```graphql
|
|
5521
|
+
* updateDocument(collection: $collection,relativePath: $path, params: {
|
|
5522
|
+
* post: {
|
|
5523
|
+
* title: "Hello, World"
|
|
5524
|
+
* }
|
|
5525
|
+
* })`
|
|
5526
|
+
* ```
|
|
5527
|
+
* and `updatePostDocument`:
|
|
5528
|
+
* ```graphql
|
|
5529
|
+
* updatePostDocument(relativePath: $path, params: {
|
|
5530
|
+
* title: "Hello, World"
|
|
5531
|
+
* })
|
|
5532
|
+
* ```
|
|
5533
|
+
* The problem here is that we don't know whether the payload came from `updateDocument`
|
|
5534
|
+
* or `updatePostDocument` (we could, but for now it's easier not to pipe those details through),
|
|
5535
|
+
* But we do know that when given a `args.collection` value, we can assume that
|
|
5536
|
+
* this was a `updateDocument` request, and thus - should grab the data
|
|
5537
|
+
* from the corresponding field name in the key
|
|
5538
|
+
*/
|
|
5120
5539
|
this.buildParams = (args) => {
|
|
5121
5540
|
try {
|
|
5122
5541
|
assertShape(
|
|
@@ -5216,7 +5635,10 @@ var resolve = async ({
|
|
|
5216
5635
|
const graphQLSchema = buildASTSchema(graphQLSchemaAst);
|
|
5217
5636
|
const tinaConfig = await database.getTinaSchema();
|
|
5218
5637
|
const tinaSchema = await createSchema({
|
|
5638
|
+
// TODO: please update all the types to import from @tinacms/schema-tools
|
|
5639
|
+
// @ts-ignore
|
|
5219
5640
|
schema: tinaConfig,
|
|
5641
|
+
// @ts-ignore
|
|
5220
5642
|
flags: tinaConfig?.meta?.flags
|
|
5221
5643
|
});
|
|
5222
5644
|
const resolver = createResolver({
|
|
@@ -5233,8 +5655,7 @@ var resolve = async ({
|
|
|
5233
5655
|
database
|
|
5234
5656
|
},
|
|
5235
5657
|
typeResolver: async (source, _args, info) => {
|
|
5236
|
-
if (source.__typename)
|
|
5237
|
-
return source.__typename;
|
|
5658
|
+
if (source.__typename) return source.__typename;
|
|
5238
5659
|
const namedType = getNamedType(info.returnType).toString();
|
|
5239
5660
|
const lookup = await database.getLookup(namedType);
|
|
5240
5661
|
if (lookup.resolveType === "unionData") {
|
|
@@ -5383,11 +5804,13 @@ var resolve = async ({
|
|
|
5383
5804
|
set(
|
|
5384
5805
|
params,
|
|
5385
5806
|
userField.path.slice(1),
|
|
5807
|
+
// remove _rawData from users path
|
|
5386
5808
|
users.map((u) => {
|
|
5387
5809
|
if (user[idFieldName] === u[idFieldName]) {
|
|
5388
5810
|
return user;
|
|
5389
5811
|
}
|
|
5390
5812
|
return {
|
|
5813
|
+
// don't overwrite other users' passwords
|
|
5391
5814
|
...u,
|
|
5392
5815
|
[passwordFieldName]: {
|
|
5393
5816
|
...u[passwordFieldName],
|
|
@@ -5410,6 +5833,9 @@ var resolve = async ({
|
|
|
5410
5833
|
}
|
|
5411
5834
|
const isCreation = lookup[info.fieldName] === "create";
|
|
5412
5835
|
switch (lookup.resolveType) {
|
|
5836
|
+
/**
|
|
5837
|
+
* `node(id: $id)`
|
|
5838
|
+
*/
|
|
5413
5839
|
case "nodeDocument":
|
|
5414
5840
|
assertShape(
|
|
5415
5841
|
args,
|
|
@@ -5441,6 +5867,7 @@ var resolve = async ({
|
|
|
5441
5867
|
collection: args.collection,
|
|
5442
5868
|
isMutation,
|
|
5443
5869
|
isCreation,
|
|
5870
|
+
// Right now this is the only case for deletion
|
|
5444
5871
|
isDeletion: info.fieldName === "deleteDocument",
|
|
5445
5872
|
isFolderCreation: info.fieldName === "createFolder",
|
|
5446
5873
|
isUpdateName: Boolean(args?.params?.relativePath),
|
|
@@ -5450,6 +5877,9 @@ var resolve = async ({
|
|
|
5450
5877
|
return result;
|
|
5451
5878
|
}
|
|
5452
5879
|
return value;
|
|
5880
|
+
/**
|
|
5881
|
+
* eg `getMovieDocument.data.actors`
|
|
5882
|
+
*/
|
|
5453
5883
|
case "multiCollectionDocumentList":
|
|
5454
5884
|
if (Array.isArray(value)) {
|
|
5455
5885
|
return {
|
|
@@ -5461,7 +5891,15 @@ var resolve = async ({
|
|
|
5461
5891
|
}
|
|
5462
5892
|
if (info.fieldName === "documents" && value?.collection && value?.hasDocuments) {
|
|
5463
5893
|
let filter = args.filter;
|
|
5464
|
-
if (
|
|
5894
|
+
if (
|
|
5895
|
+
// 1. Make sure that the filter exists
|
|
5896
|
+
typeof args?.filter !== "undefined" && args?.filter !== null && // 2. Make sure that the collection name exists
|
|
5897
|
+
// @ts-ignore
|
|
5898
|
+
typeof value?.collection?.name === "string" && // 3. Make sure that the collection name is in the filter and is not undefined
|
|
5899
|
+
// @ts-ignore
|
|
5900
|
+
Object.keys(args.filter).includes(value?.collection?.name) && // @ts-ignore
|
|
5901
|
+
typeof args.filter[value?.collection?.name] !== "undefined"
|
|
5902
|
+
) {
|
|
5465
5903
|
filter = args.filter[value.collection.name];
|
|
5466
5904
|
}
|
|
5467
5905
|
return resolver.resolveCollectionConnection({
|
|
@@ -5469,12 +5907,20 @@ var resolve = async ({
|
|
|
5469
5907
|
...args,
|
|
5470
5908
|
filter
|
|
5471
5909
|
},
|
|
5910
|
+
// @ts-ignore
|
|
5472
5911
|
collection: value.collection
|
|
5473
5912
|
});
|
|
5474
5913
|
}
|
|
5475
5914
|
throw new Error(
|
|
5476
5915
|
`Expected an array for result of ${info.fieldName} at ${info.path}`
|
|
5477
5916
|
);
|
|
5917
|
+
/**
|
|
5918
|
+
* Collections-specific getter
|
|
5919
|
+
* eg. `getPostDocument`/`createPostDocument`/`updatePostDocument`
|
|
5920
|
+
*
|
|
5921
|
+
* if coming from a query result
|
|
5922
|
+
* the field will be `node`
|
|
5923
|
+
*/
|
|
5478
5924
|
case "collectionDocument": {
|
|
5479
5925
|
if (value) {
|
|
5480
5926
|
return value;
|
|
@@ -5489,11 +5935,32 @@ var resolve = async ({
|
|
|
5489
5935
|
});
|
|
5490
5936
|
return result;
|
|
5491
5937
|
}
|
|
5938
|
+
/**
|
|
5939
|
+
* Collections-specific list getter
|
|
5940
|
+
* eg. `getPageList`
|
|
5941
|
+
*/
|
|
5492
5942
|
case "collectionDocumentList":
|
|
5493
5943
|
return resolver.resolveCollectionConnection({
|
|
5494
5944
|
args,
|
|
5495
5945
|
collection: tinaSchema.getCollection(lookup.collection)
|
|
5496
5946
|
});
|
|
5947
|
+
/**
|
|
5948
|
+
* A polymorphic data set, it can be from a document's data
|
|
5949
|
+
* of any nested object which can be one of many shapes
|
|
5950
|
+
*
|
|
5951
|
+
* ```graphql
|
|
5952
|
+
* getPostDocument(relativePath: $relativePath) {
|
|
5953
|
+
* data {...} <- this part
|
|
5954
|
+
* }
|
|
5955
|
+
* ```
|
|
5956
|
+
* ```graphql
|
|
5957
|
+
* getBlockDocument(relativePath: $relativePath) {
|
|
5958
|
+
* data {
|
|
5959
|
+
* blocks {...} <- or this part
|
|
5960
|
+
* }
|
|
5961
|
+
* }
|
|
5962
|
+
* ```
|
|
5963
|
+
*/
|
|
5497
5964
|
case "unionData":
|
|
5498
5965
|
if (!value) {
|
|
5499
5966
|
if (args.relativePath) {
|
|
@@ -5558,8 +6025,7 @@ var TinaLevelClient = class extends ManyLevelGuest {
|
|
|
5558
6025
|
this.port = port || 9e3;
|
|
5559
6026
|
}
|
|
5560
6027
|
openConnection() {
|
|
5561
|
-
if (this._connected)
|
|
5562
|
-
return;
|
|
6028
|
+
if (this._connected) return;
|
|
5563
6029
|
const socket = connect(this.port);
|
|
5564
6030
|
pipeline(socket, this.createRpcStream(), socket, () => {
|
|
5565
6031
|
this._connected = false;
|
|
@@ -5569,7 +6035,7 @@ var TinaLevelClient = class extends ManyLevelGuest {
|
|
|
5569
6035
|
};
|
|
5570
6036
|
|
|
5571
6037
|
// src/database/index.ts
|
|
5572
|
-
import path4 from "path";
|
|
6038
|
+
import path4 from "node:path";
|
|
5573
6039
|
import { GraphQLError as GraphQLError5 } from "graphql";
|
|
5574
6040
|
import micromatch2 from "micromatch";
|
|
5575
6041
|
import sha2 from "js-sha1";
|
|
@@ -5704,6 +6170,7 @@ var Database = class {
|
|
|
5704
6170
|
);
|
|
5705
6171
|
const indexDefinitions = await this.getIndexDefinitions(this.contentLevel);
|
|
5706
6172
|
const collectionIndexDefinitions = indexDefinitions?.[collection.name];
|
|
6173
|
+
const collectionReferences = (await this.getCollectionReferences())?.[collection.name];
|
|
5707
6174
|
const normalizedPath = normalizePath(filepath);
|
|
5708
6175
|
if (!collection?.isDetached) {
|
|
5709
6176
|
if (this.bridge) {
|
|
@@ -5732,6 +6199,14 @@ var Database = class {
|
|
|
5732
6199
|
let delOps = [];
|
|
5733
6200
|
if (!isGitKeep(normalizedPath, collection)) {
|
|
5734
6201
|
putOps = [
|
|
6202
|
+
...makeRefOpsForDocument(
|
|
6203
|
+
normalizedPath,
|
|
6204
|
+
collection?.name,
|
|
6205
|
+
collectionReferences,
|
|
6206
|
+
dataFields,
|
|
6207
|
+
"put",
|
|
6208
|
+
level
|
|
6209
|
+
),
|
|
5735
6210
|
...makeIndexOpsForDocument(
|
|
5736
6211
|
normalizedPath,
|
|
5737
6212
|
collection?.name,
|
|
@@ -5740,6 +6215,7 @@ var Database = class {
|
|
|
5740
6215
|
"put",
|
|
5741
6216
|
level
|
|
5742
6217
|
),
|
|
6218
|
+
// folder indices
|
|
5743
6219
|
...makeIndexOpsForDocument(
|
|
5744
6220
|
normalizedPath,
|
|
5745
6221
|
`${collection?.name}_${folderKey}`,
|
|
@@ -5754,6 +6230,14 @@ var Database = class {
|
|
|
5754
6230
|
SUBLEVEL_OPTIONS
|
|
5755
6231
|
).get(normalizedPath);
|
|
5756
6232
|
delOps = existingItem ? [
|
|
6233
|
+
...makeRefOpsForDocument(
|
|
6234
|
+
normalizedPath,
|
|
6235
|
+
collection?.name,
|
|
6236
|
+
collectionReferences,
|
|
6237
|
+
existingItem,
|
|
6238
|
+
"del",
|
|
6239
|
+
level
|
|
6240
|
+
),
|
|
5757
6241
|
...makeIndexOpsForDocument(
|
|
5758
6242
|
normalizedPath,
|
|
5759
6243
|
collection?.name,
|
|
@@ -5762,6 +6246,7 @@ var Database = class {
|
|
|
5762
6246
|
"del",
|
|
5763
6247
|
level
|
|
5764
6248
|
),
|
|
6249
|
+
// folder indices
|
|
5765
6250
|
...makeIndexOpsForDocument(
|
|
5766
6251
|
normalizedPath,
|
|
5767
6252
|
`${collection?.name}_${folderKey}`,
|
|
@@ -5800,6 +6285,7 @@ var Database = class {
|
|
|
5800
6285
|
);
|
|
5801
6286
|
collectionIndexDefinitions = indexDefinitions?.[collectionName];
|
|
5802
6287
|
}
|
|
6288
|
+
const collectionReferences = (await this.getCollectionReferences())?.[collectionName];
|
|
5803
6289
|
const normalizedPath = normalizePath(filepath);
|
|
5804
6290
|
const dataFields = await this.formatBodyOnPayload(filepath, data);
|
|
5805
6291
|
const collection = await this.collectionForPath(filepath);
|
|
@@ -5847,6 +6333,14 @@ var Database = class {
|
|
|
5847
6333
|
let delOps = [];
|
|
5848
6334
|
if (!isGitKeep(normalizedPath, collection)) {
|
|
5849
6335
|
putOps = [
|
|
6336
|
+
...makeRefOpsForDocument(
|
|
6337
|
+
normalizedPath,
|
|
6338
|
+
collectionName,
|
|
6339
|
+
collectionReferences,
|
|
6340
|
+
dataFields,
|
|
6341
|
+
"put",
|
|
6342
|
+
level
|
|
6343
|
+
),
|
|
5850
6344
|
...makeIndexOpsForDocument(
|
|
5851
6345
|
normalizedPath,
|
|
5852
6346
|
collectionName,
|
|
@@ -5855,6 +6349,7 @@ var Database = class {
|
|
|
5855
6349
|
"put",
|
|
5856
6350
|
level
|
|
5857
6351
|
),
|
|
6352
|
+
// folder indices
|
|
5858
6353
|
...makeIndexOpsForDocument(
|
|
5859
6354
|
normalizedPath,
|
|
5860
6355
|
`${collection?.name}_${folderKey}`,
|
|
@@ -5869,6 +6364,14 @@ var Database = class {
|
|
|
5869
6364
|
SUBLEVEL_OPTIONS
|
|
5870
6365
|
).get(normalizedPath);
|
|
5871
6366
|
delOps = existingItem ? [
|
|
6367
|
+
...makeRefOpsForDocument(
|
|
6368
|
+
normalizedPath,
|
|
6369
|
+
collectionName,
|
|
6370
|
+
collectionReferences,
|
|
6371
|
+
existingItem,
|
|
6372
|
+
"del",
|
|
6373
|
+
level
|
|
6374
|
+
),
|
|
5872
6375
|
...makeIndexOpsForDocument(
|
|
5873
6376
|
normalizedPath,
|
|
5874
6377
|
collectionName,
|
|
@@ -5877,6 +6380,7 @@ var Database = class {
|
|
|
5877
6380
|
"del",
|
|
5878
6381
|
level
|
|
5879
6382
|
),
|
|
6383
|
+
// folder indices
|
|
5880
6384
|
...makeIndexOpsForDocument(
|
|
5881
6385
|
normalizedPath,
|
|
5882
6386
|
`${collection?.name}_${folderKey}`,
|
|
@@ -5954,6 +6458,7 @@ var Database = class {
|
|
|
5954
6458
|
aliasedData,
|
|
5955
6459
|
extension,
|
|
5956
6460
|
writeTemplateKey,
|
|
6461
|
+
//templateInfo.type === 'union',
|
|
5957
6462
|
{
|
|
5958
6463
|
frontmatterFormat: collection?.frontmatterFormat,
|
|
5959
6464
|
frontmatterDelimiters: collection?.frontmatterDelimiters
|
|
@@ -5992,6 +6497,7 @@ var Database = class {
|
|
|
5992
6497
|
SUBLEVEL_OPTIONS
|
|
5993
6498
|
).get(graphqlPath);
|
|
5994
6499
|
};
|
|
6500
|
+
//TODO - is there a reason why the database fetches some config with "bridge.get", and some with "store.get"?
|
|
5995
6501
|
this.getGraphQLSchemaFromBridge = async () => {
|
|
5996
6502
|
if (!this.bridge) {
|
|
5997
6503
|
throw new Error(`No bridge configured`);
|
|
@@ -6028,6 +6534,22 @@ var Database = class {
|
|
|
6028
6534
|
this.tinaSchema = await createSchema({ schema });
|
|
6029
6535
|
return this.tinaSchema;
|
|
6030
6536
|
};
|
|
6537
|
+
this.getCollectionReferences = async (level) => {
|
|
6538
|
+
if (this.collectionReferences) {
|
|
6539
|
+
return this.collectionReferences;
|
|
6540
|
+
}
|
|
6541
|
+
const result = {};
|
|
6542
|
+
const schema = await this.getSchema(level || this.contentLevel);
|
|
6543
|
+
const collections = schema.getCollections();
|
|
6544
|
+
for (const collection of collections) {
|
|
6545
|
+
const collectionReferences = this.tinaSchema.findReferencesFromCollection(
|
|
6546
|
+
collection.name
|
|
6547
|
+
);
|
|
6548
|
+
result[collection.name] = collectionReferences;
|
|
6549
|
+
}
|
|
6550
|
+
this.collectionReferences = result;
|
|
6551
|
+
return result;
|
|
6552
|
+
};
|
|
6031
6553
|
this.getIndexDefinitions = async (level) => {
|
|
6032
6554
|
if (!this.collectionIndexDefinitions) {
|
|
6033
6555
|
await new Promise(async (resolve2, reject) => {
|
|
@@ -6037,7 +6559,23 @@ var Database = class {
|
|
|
6037
6559
|
const collections = schema.getCollections();
|
|
6038
6560
|
for (const collection of collections) {
|
|
6039
6561
|
const indexDefinitions = {
|
|
6040
|
-
[DEFAULT_COLLECTION_SORT_KEY]: { fields: [] }
|
|
6562
|
+
[DEFAULT_COLLECTION_SORT_KEY]: { fields: [] },
|
|
6563
|
+
// provide a default sort key which is the file sort
|
|
6564
|
+
// pseudo-index for the collection's references
|
|
6565
|
+
[REFS_COLLECTIONS_SORT_KEY]: {
|
|
6566
|
+
fields: [
|
|
6567
|
+
{
|
|
6568
|
+
name: REFS_REFERENCE_FIELD,
|
|
6569
|
+
type: "string",
|
|
6570
|
+
list: false
|
|
6571
|
+
},
|
|
6572
|
+
{
|
|
6573
|
+
name: REFS_PATH_FIELD,
|
|
6574
|
+
type: "string",
|
|
6575
|
+
list: false
|
|
6576
|
+
}
|
|
6577
|
+
]
|
|
6578
|
+
}
|
|
6041
6579
|
};
|
|
6042
6580
|
if (collection.fields) {
|
|
6043
6581
|
for (const field of collection.fields) {
|
|
@@ -6188,29 +6726,36 @@ var Database = class {
|
|
|
6188
6726
|
}
|
|
6189
6727
|
startKey = startKey || key || "";
|
|
6190
6728
|
endKey = key || "";
|
|
6191
|
-
edges = [...edges, { cursor: key, path: filepath }];
|
|
6729
|
+
edges = [...edges, { cursor: key, path: filepath, value: itemRecord }];
|
|
6192
6730
|
}
|
|
6193
6731
|
return {
|
|
6194
|
-
edges: await sequential(
|
|
6195
|
-
|
|
6196
|
-
|
|
6197
|
-
|
|
6198
|
-
|
|
6199
|
-
|
|
6200
|
-
|
|
6201
|
-
|
|
6202
|
-
|
|
6203
|
-
|
|
6204
|
-
|
|
6205
|
-
|
|
6206
|
-
|
|
6207
|
-
|
|
6208
|
-
|
|
6209
|
-
|
|
6732
|
+
edges: await sequential(
|
|
6733
|
+
edges,
|
|
6734
|
+
async ({
|
|
6735
|
+
cursor,
|
|
6736
|
+
path: path7,
|
|
6737
|
+
value
|
|
6738
|
+
}) => {
|
|
6739
|
+
try {
|
|
6740
|
+
const node = await hydrator(path7, value);
|
|
6741
|
+
return {
|
|
6742
|
+
node,
|
|
6743
|
+
cursor: btoa(cursor)
|
|
6744
|
+
};
|
|
6745
|
+
} catch (error) {
|
|
6746
|
+
console.log(error);
|
|
6747
|
+
if (error instanceof Error && (!path7.includes(".tina/__generated__/_graphql.json") || !path7.includes("tina/__generated__/_graphql.json"))) {
|
|
6748
|
+
throw new TinaQueryError({
|
|
6749
|
+
originalError: error,
|
|
6750
|
+
file: path7,
|
|
6751
|
+
collection: collection.name,
|
|
6752
|
+
stack: error.stack
|
|
6753
|
+
});
|
|
6754
|
+
}
|
|
6755
|
+
throw error;
|
|
6210
6756
|
}
|
|
6211
|
-
throw error;
|
|
6212
6757
|
}
|
|
6213
|
-
|
|
6758
|
+
),
|
|
6214
6759
|
pageInfo: {
|
|
6215
6760
|
hasPreviousPage,
|
|
6216
6761
|
hasNextPage,
|
|
@@ -6356,17 +6901,18 @@ var Database = class {
|
|
|
6356
6901
|
throw new Error(`No collection found for path: ${filepath}`);
|
|
6357
6902
|
}
|
|
6358
6903
|
const indexDefinitions = await this.getIndexDefinitions(this.contentLevel);
|
|
6904
|
+
const collectionReferences = (await this.getCollectionReferences())?.[collection.name];
|
|
6359
6905
|
const collectionIndexDefinitions = indexDefinitions?.[collection.name];
|
|
6360
6906
|
let level = this.contentLevel;
|
|
6361
6907
|
if (collection?.isDetached) {
|
|
6362
6908
|
level = this.appLevel.sublevel(collection?.name, SUBLEVEL_OPTIONS);
|
|
6363
6909
|
}
|
|
6364
|
-
const
|
|
6910
|
+
const normalizedPath = normalizePath(filepath);
|
|
6365
6911
|
const rootSublevel = level.sublevel(
|
|
6366
6912
|
CONTENT_ROOT_PREFIX,
|
|
6367
6913
|
SUBLEVEL_OPTIONS
|
|
6368
6914
|
);
|
|
6369
|
-
const item = await rootSublevel.get(
|
|
6915
|
+
const item = await rootSublevel.get(normalizedPath);
|
|
6370
6916
|
if (item) {
|
|
6371
6917
|
const folderTreeBuilder = new FolderTreeBuilder();
|
|
6372
6918
|
const folderKey = folderTreeBuilder.update(
|
|
@@ -6374,16 +6920,25 @@ var Database = class {
|
|
|
6374
6920
|
collection.path || ""
|
|
6375
6921
|
);
|
|
6376
6922
|
await this.contentLevel.batch([
|
|
6923
|
+
...makeRefOpsForDocument(
|
|
6924
|
+
normalizedPath,
|
|
6925
|
+
collection.name,
|
|
6926
|
+
collectionReferences,
|
|
6927
|
+
item,
|
|
6928
|
+
"del",
|
|
6929
|
+
level
|
|
6930
|
+
),
|
|
6377
6931
|
...makeIndexOpsForDocument(
|
|
6378
|
-
|
|
6932
|
+
normalizedPath,
|
|
6379
6933
|
collection.name,
|
|
6380
6934
|
collectionIndexDefinitions,
|
|
6381
6935
|
item,
|
|
6382
6936
|
"del",
|
|
6383
6937
|
level
|
|
6384
6938
|
),
|
|
6939
|
+
// folder indices
|
|
6385
6940
|
...makeIndexOpsForDocument(
|
|
6386
|
-
|
|
6941
|
+
normalizedPath,
|
|
6387
6942
|
`${collection.name}_${folderKey}`,
|
|
6388
6943
|
collectionIndexDefinitions,
|
|
6389
6944
|
item,
|
|
@@ -6392,17 +6947,17 @@ var Database = class {
|
|
|
6392
6947
|
),
|
|
6393
6948
|
{
|
|
6394
6949
|
type: "del",
|
|
6395
|
-
key:
|
|
6950
|
+
key: normalizedPath,
|
|
6396
6951
|
sublevel: rootSublevel
|
|
6397
6952
|
}
|
|
6398
6953
|
]);
|
|
6399
6954
|
}
|
|
6400
6955
|
if (!collection?.isDetached) {
|
|
6401
6956
|
if (this.bridge) {
|
|
6402
|
-
await this.bridge.delete(
|
|
6957
|
+
await this.bridge.delete(normalizedPath);
|
|
6403
6958
|
}
|
|
6404
6959
|
try {
|
|
6405
|
-
await this.onDelete(
|
|
6960
|
+
await this.onDelete(normalizedPath);
|
|
6406
6961
|
} catch (e) {
|
|
6407
6962
|
throw new GraphQLError5(
|
|
6408
6963
|
`Error running onDelete hook for ${filepath}: ${e}`,
|
|
@@ -6536,6 +7091,9 @@ var Database = class {
|
|
|
6536
7091
|
info: templateInfo
|
|
6537
7092
|
};
|
|
6538
7093
|
}
|
|
7094
|
+
/**
|
|
7095
|
+
* Clears the internal cache of the tinaSchema and the lookup file. This allows the state to be reset
|
|
7096
|
+
*/
|
|
6539
7097
|
clearCache() {
|
|
6540
7098
|
this.tinaSchema = null;
|
|
6541
7099
|
this._lookup = null;
|
|
@@ -6597,6 +7155,7 @@ var _indexContent = async (database, level, documentPaths, enqueueOps, collectio
|
|
|
6597
7155
|
}
|
|
6598
7156
|
collectionPath = collection.path;
|
|
6599
7157
|
}
|
|
7158
|
+
const collectionReferences = (await database.getCollectionReferences())?.[collection?.name];
|
|
6600
7159
|
const tinaSchema = await database.getSchema();
|
|
6601
7160
|
let templateInfo = null;
|
|
6602
7161
|
if (collection) {
|
|
@@ -6618,12 +7177,59 @@ var _indexContent = async (database, level, documentPaths, enqueueOps, collectio
|
|
|
6618
7177
|
await hashPasswordValues(aliasedData, passwordFields);
|
|
6619
7178
|
}
|
|
6620
7179
|
const normalizedPath = normalizePath(filepath);
|
|
7180
|
+
const rootSublevel = level.sublevel(
|
|
7181
|
+
CONTENT_ROOT_PREFIX,
|
|
7182
|
+
SUBLEVEL_OPTIONS
|
|
7183
|
+
);
|
|
6621
7184
|
const folderKey = folderTreeBuilder.update(
|
|
6622
7185
|
normalizedPath,
|
|
6623
7186
|
collectionPath || ""
|
|
6624
7187
|
);
|
|
7188
|
+
const item = await rootSublevel.get(normalizedPath);
|
|
7189
|
+
if (item) {
|
|
7190
|
+
await database.contentLevel.batch([
|
|
7191
|
+
...makeRefOpsForDocument(
|
|
7192
|
+
normalizedPath,
|
|
7193
|
+
collection?.name,
|
|
7194
|
+
collectionReferences,
|
|
7195
|
+
item,
|
|
7196
|
+
"del",
|
|
7197
|
+
level
|
|
7198
|
+
),
|
|
7199
|
+
...makeIndexOpsForDocument(
|
|
7200
|
+
normalizedPath,
|
|
7201
|
+
collection.name,
|
|
7202
|
+
collectionIndexDefinitions,
|
|
7203
|
+
item,
|
|
7204
|
+
"del",
|
|
7205
|
+
level
|
|
7206
|
+
),
|
|
7207
|
+
// folder indices
|
|
7208
|
+
...makeIndexOpsForDocument(
|
|
7209
|
+
normalizedPath,
|
|
7210
|
+
`${collection.name}_${folderKey}`,
|
|
7211
|
+
collectionIndexDefinitions,
|
|
7212
|
+
item,
|
|
7213
|
+
"del",
|
|
7214
|
+
level
|
|
7215
|
+
),
|
|
7216
|
+
{
|
|
7217
|
+
type: "del",
|
|
7218
|
+
key: normalizedPath,
|
|
7219
|
+
sublevel: rootSublevel
|
|
7220
|
+
}
|
|
7221
|
+
]);
|
|
7222
|
+
}
|
|
6625
7223
|
if (!isGitKeep(filepath, collection)) {
|
|
6626
7224
|
await enqueueOps([
|
|
7225
|
+
...makeRefOpsForDocument(
|
|
7226
|
+
normalizedPath,
|
|
7227
|
+
collection?.name,
|
|
7228
|
+
collectionReferences,
|
|
7229
|
+
aliasedData,
|
|
7230
|
+
"put",
|
|
7231
|
+
level
|
|
7232
|
+
),
|
|
6627
7233
|
...makeIndexOpsForDocument(
|
|
6628
7234
|
normalizedPath,
|
|
6629
7235
|
collection?.name,
|
|
@@ -6632,6 +7238,7 @@ var _indexContent = async (database, level, documentPaths, enqueueOps, collectio
|
|
|
6632
7238
|
"put",
|
|
6633
7239
|
level
|
|
6634
7240
|
),
|
|
7241
|
+
// folder indexes
|
|
6635
7242
|
...makeIndexOpsForDocument(
|
|
6636
7243
|
normalizedPath,
|
|
6637
7244
|
`${collection?.name}_${folderKey}`,
|
|
@@ -6686,6 +7293,7 @@ var _deleteIndexContent = async (database, documentPaths, enqueueOps, collection
|
|
|
6686
7293
|
throw new Error(`No indexDefinitions for collection ${collection.name}`);
|
|
6687
7294
|
}
|
|
6688
7295
|
}
|
|
7296
|
+
const collectionReferences = (await database.getCollectionReferences())?.[collection?.name];
|
|
6689
7297
|
const tinaSchema = await database.getSchema();
|
|
6690
7298
|
let templateInfo = null;
|
|
6691
7299
|
if (collection) {
|
|
@@ -6709,6 +7317,14 @@ var _deleteIndexContent = async (database, documentPaths, enqueueOps, collection
|
|
|
6709
7317
|
item
|
|
6710
7318
|
) : item;
|
|
6711
7319
|
await enqueueOps([
|
|
7320
|
+
...makeRefOpsForDocument(
|
|
7321
|
+
itemKey,
|
|
7322
|
+
collection?.name,
|
|
7323
|
+
collectionReferences,
|
|
7324
|
+
aliasedData,
|
|
7325
|
+
"del",
|
|
7326
|
+
database.contentLevel
|
|
7327
|
+
),
|
|
6712
7328
|
...makeIndexOpsForDocument(
|
|
6713
7329
|
itemKey,
|
|
6714
7330
|
collection.name,
|
|
@@ -6717,6 +7333,7 @@ var _deleteIndexContent = async (database, documentPaths, enqueueOps, collection
|
|
|
6717
7333
|
"del",
|
|
6718
7334
|
database.contentLevel
|
|
6719
7335
|
),
|
|
7336
|
+
// folder indexes
|
|
6720
7337
|
...makeIndexOpsForDocument(
|
|
6721
7338
|
itemKey,
|
|
6722
7339
|
`${collection?.name}_${folderKey}`,
|
|
@@ -6932,17 +7549,26 @@ var IsomorphicBridge = class {
|
|
|
6932
7549
|
getAuthor() {
|
|
6933
7550
|
return {
|
|
6934
7551
|
...this.author,
|
|
6935
|
-
timestamp: Math.round(new Date().getTime() / 1e3),
|
|
7552
|
+
timestamp: Math.round((/* @__PURE__ */ new Date()).getTime() / 1e3),
|
|
6936
7553
|
timezoneOffset: 0
|
|
6937
7554
|
};
|
|
6938
7555
|
}
|
|
6939
7556
|
getCommitter() {
|
|
6940
7557
|
return {
|
|
6941
7558
|
...this.committer,
|
|
6942
|
-
timestamp: Math.round(new Date().getTime() / 1e3),
|
|
7559
|
+
timestamp: Math.round((/* @__PURE__ */ new Date()).getTime() / 1e3),
|
|
6943
7560
|
timezoneOffset: 0
|
|
6944
7561
|
};
|
|
6945
7562
|
}
|
|
7563
|
+
/**
|
|
7564
|
+
* Recursively populate paths matching `pattern` for the given `entry`
|
|
7565
|
+
*
|
|
7566
|
+
* @param pattern - pattern to filter paths by
|
|
7567
|
+
* @param entry - TreeEntry to start building list from
|
|
7568
|
+
* @param path - base path
|
|
7569
|
+
* @param results
|
|
7570
|
+
* @private
|
|
7571
|
+
*/
|
|
6946
7572
|
async listEntries({
|
|
6947
7573
|
pattern,
|
|
6948
7574
|
entry,
|
|
@@ -6975,6 +7601,15 @@ var IsomorphicBridge = class {
|
|
|
6975
7601
|
});
|
|
6976
7602
|
}
|
|
6977
7603
|
}
|
|
7604
|
+
/**
|
|
7605
|
+
* For the specified path, returns an object with an array containing the parts of the path (pathParts)
|
|
7606
|
+
* and an array containing the WalkerEntry objects for the path parts (pathEntries). Any null elements in the
|
|
7607
|
+
* pathEntries are placeholders for non-existent entries.
|
|
7608
|
+
*
|
|
7609
|
+
* @param path - path being resolved
|
|
7610
|
+
* @param ref - ref to resolve path entries for
|
|
7611
|
+
* @private
|
|
7612
|
+
*/
|
|
6978
7613
|
async resolvePathEntries(path7, ref) {
|
|
6979
7614
|
let pathParts = path7.split("/");
|
|
6980
7615
|
const result = await git2.walk({
|
|
@@ -7005,6 +7640,17 @@ var IsomorphicBridge = class {
|
|
|
7005
7640
|
}
|
|
7006
7641
|
return { pathParts, pathEntries };
|
|
7007
7642
|
}
|
|
7643
|
+
/**
|
|
7644
|
+
* Updates tree entry and associated parent tree entries
|
|
7645
|
+
*
|
|
7646
|
+
* @param existingOid - the existing OID
|
|
7647
|
+
* @param updatedOid - the updated OID
|
|
7648
|
+
* @param path - the path of the entry being updated
|
|
7649
|
+
* @param type - the type of the entry being updated (blob or tree)
|
|
7650
|
+
* @param pathEntries - parent path entries
|
|
7651
|
+
* @param pathParts - parent path parts
|
|
7652
|
+
* @private
|
|
7653
|
+
*/
|
|
7008
7654
|
async updateTreeHierarchy(existingOid, updatedOid, path7, type, pathEntries, pathParts) {
|
|
7009
7655
|
const lastIdx = pathEntries.length - 1;
|
|
7010
7656
|
const parentEntry = pathEntries[lastIdx];
|
|
@@ -7060,6 +7706,13 @@ var IsomorphicBridge = class {
|
|
|
7060
7706
|
);
|
|
7061
7707
|
}
|
|
7062
7708
|
}
|
|
7709
|
+
/**
|
|
7710
|
+
* Creates a commit for the specified tree and updates the specified ref to point to the commit
|
|
7711
|
+
*
|
|
7712
|
+
* @param treeSha - sha of the new tree
|
|
7713
|
+
* @param ref - the ref that should be updated
|
|
7714
|
+
* @private
|
|
7715
|
+
*/
|
|
7063
7716
|
async commitTree(treeSha, ref) {
|
|
7064
7717
|
const commitSha = await git2.writeCommit({
|
|
7065
7718
|
...this.isomorphicConfig,
|
|
@@ -7072,6 +7725,7 @@ var IsomorphicBridge = class {
|
|
|
7072
7725
|
})
|
|
7073
7726
|
],
|
|
7074
7727
|
message: this.commitMessage,
|
|
7728
|
+
// TODO these should be configurable
|
|
7075
7729
|
author: this.getAuthor(),
|
|
7076
7730
|
committer: this.getCommitter()
|
|
7077
7731
|
}
|
|
@@ -7309,5 +7963,5 @@ export {
|
|
|
7309
7963
|
transformDocument,
|
|
7310
7964
|
transformDocumentIntoPayload
|
|
7311
7965
|
};
|
|
7312
|
-
//! Replaces _.flattenDeep()
|
|
7313
7966
|
//! Replaces _.get()
|
|
7967
|
+
//! Replaces _.flattenDeep()
|