@tinacms/graphql 0.0.0-ecea7ac-20241011043815 → 0.0.0-ed38135-20250102012919
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 +563 -36
- package/dist/index.mjs +560 -37
- package/dist/resolver/index.d.ts +26 -2
- package/package.json +8 -8
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) => {
|
|
@@ -1195,6 +1223,11 @@ var scalarDefinitions = [
|
|
|
1195
1223
|
required: true,
|
|
1196
1224
|
type: astBuilder.TYPES.String
|
|
1197
1225
|
}),
|
|
1226
|
+
astBuilder.FieldDefinition({
|
|
1227
|
+
name: "hasReferences",
|
|
1228
|
+
required: false,
|
|
1229
|
+
type: astBuilder.TYPES.Boolean
|
|
1230
|
+
}),
|
|
1198
1231
|
astBuilder.FieldDefinition({
|
|
1199
1232
|
name: "breadcrumbs",
|
|
1200
1233
|
required: true,
|
|
@@ -1408,6 +1441,19 @@ var Builder = class {
|
|
|
1408
1441
|
this.addToLookupMap = (lookup) => {
|
|
1409
1442
|
this.lookupMap[lookup.type] = lookup;
|
|
1410
1443
|
};
|
|
1444
|
+
/**
|
|
1445
|
+
* ```graphql
|
|
1446
|
+
* # ex.
|
|
1447
|
+
* {
|
|
1448
|
+
* getCollection(collection: $collection) {
|
|
1449
|
+
* name
|
|
1450
|
+
* documents {...}
|
|
1451
|
+
* }
|
|
1452
|
+
* }
|
|
1453
|
+
* ```
|
|
1454
|
+
*
|
|
1455
|
+
* @param collections
|
|
1456
|
+
*/
|
|
1411
1457
|
this.buildCollectionDefinition = async (collections) => {
|
|
1412
1458
|
const name = "collection";
|
|
1413
1459
|
const typeName = "Collection";
|
|
@@ -1478,6 +1524,19 @@ var Builder = class {
|
|
|
1478
1524
|
required: true
|
|
1479
1525
|
});
|
|
1480
1526
|
};
|
|
1527
|
+
/**
|
|
1528
|
+
* ```graphql
|
|
1529
|
+
* # ex.
|
|
1530
|
+
* {
|
|
1531
|
+
* getCollections {
|
|
1532
|
+
* name
|
|
1533
|
+
* documents {...}
|
|
1534
|
+
* }
|
|
1535
|
+
* }
|
|
1536
|
+
* ```
|
|
1537
|
+
*
|
|
1538
|
+
* @param collections
|
|
1539
|
+
*/
|
|
1481
1540
|
this.buildMultiCollectionDefinition = async (collections) => {
|
|
1482
1541
|
const name = "collections";
|
|
1483
1542
|
const typeName = "Collection";
|
|
@@ -1488,6 +1547,17 @@ var Builder = class {
|
|
|
1488
1547
|
required: true
|
|
1489
1548
|
});
|
|
1490
1549
|
};
|
|
1550
|
+
/**
|
|
1551
|
+
* ```graphql
|
|
1552
|
+
* # ex.
|
|
1553
|
+
* {
|
|
1554
|
+
* node(id: $id) {
|
|
1555
|
+
* id
|
|
1556
|
+
* data {...}
|
|
1557
|
+
* }
|
|
1558
|
+
* }
|
|
1559
|
+
* ```
|
|
1560
|
+
*/
|
|
1491
1561
|
this.multiNodeDocument = async () => {
|
|
1492
1562
|
const name = "node";
|
|
1493
1563
|
const args = [
|
|
@@ -1508,6 +1578,19 @@ var Builder = class {
|
|
|
1508
1578
|
required: true
|
|
1509
1579
|
});
|
|
1510
1580
|
};
|
|
1581
|
+
/**
|
|
1582
|
+
* ```graphql
|
|
1583
|
+
* # ex.
|
|
1584
|
+
* {
|
|
1585
|
+
* getDocument(collection: $collection, relativePath: $relativePath) {
|
|
1586
|
+
* id
|
|
1587
|
+
* data {...}
|
|
1588
|
+
* }
|
|
1589
|
+
* }
|
|
1590
|
+
* ```
|
|
1591
|
+
*
|
|
1592
|
+
* @param collections
|
|
1593
|
+
*/
|
|
1511
1594
|
this.multiCollectionDocument = async (collections) => {
|
|
1512
1595
|
const name = "document";
|
|
1513
1596
|
const args = [
|
|
@@ -1533,6 +1616,19 @@ var Builder = class {
|
|
|
1533
1616
|
required: true
|
|
1534
1617
|
});
|
|
1535
1618
|
};
|
|
1619
|
+
/**
|
|
1620
|
+
* ```graphql
|
|
1621
|
+
* # ex.
|
|
1622
|
+
* {
|
|
1623
|
+
* addPendingDocument(collection: $collection, relativePath: $relativePath, params: $params) {
|
|
1624
|
+
* id
|
|
1625
|
+
* data {...}
|
|
1626
|
+
* }
|
|
1627
|
+
* }
|
|
1628
|
+
* ```
|
|
1629
|
+
*
|
|
1630
|
+
* @param collections
|
|
1631
|
+
*/
|
|
1536
1632
|
this.addMultiCollectionDocumentMutation = async () => {
|
|
1537
1633
|
return astBuilder.FieldDefinition({
|
|
1538
1634
|
name: "addPendingDocument",
|
|
@@ -1557,6 +1653,19 @@ var Builder = class {
|
|
|
1557
1653
|
type: astBuilder.TYPES.MultiCollectionDocument
|
|
1558
1654
|
});
|
|
1559
1655
|
};
|
|
1656
|
+
/**
|
|
1657
|
+
* ```graphql
|
|
1658
|
+
* # ex.
|
|
1659
|
+
* {
|
|
1660
|
+
* createDocument(relativePath: $relativePath, params: $params) {
|
|
1661
|
+
* id
|
|
1662
|
+
* data {...}
|
|
1663
|
+
* }
|
|
1664
|
+
* }
|
|
1665
|
+
* ```
|
|
1666
|
+
*
|
|
1667
|
+
* @param collections
|
|
1668
|
+
*/
|
|
1560
1669
|
this.buildCreateCollectionDocumentMutation = async (collections) => {
|
|
1561
1670
|
return astBuilder.FieldDefinition({
|
|
1562
1671
|
name: "createDocument",
|
|
@@ -1584,6 +1693,19 @@ var Builder = class {
|
|
|
1584
1693
|
type: astBuilder.TYPES.MultiCollectionDocument
|
|
1585
1694
|
});
|
|
1586
1695
|
};
|
|
1696
|
+
/**
|
|
1697
|
+
* ```graphql
|
|
1698
|
+
* # ex.
|
|
1699
|
+
* {
|
|
1700
|
+
* updateDocument(relativePath: $relativePath, params: $params) {
|
|
1701
|
+
* id
|
|
1702
|
+
* data {...}
|
|
1703
|
+
* }
|
|
1704
|
+
* }
|
|
1705
|
+
* ```
|
|
1706
|
+
*
|
|
1707
|
+
* @param collections
|
|
1708
|
+
*/
|
|
1587
1709
|
this.buildUpdateCollectionDocumentMutation = async (collections) => {
|
|
1588
1710
|
return astBuilder.FieldDefinition({
|
|
1589
1711
|
name: "updateDocument",
|
|
@@ -1611,6 +1733,19 @@ var Builder = class {
|
|
|
1611
1733
|
type: astBuilder.TYPES.MultiCollectionDocument
|
|
1612
1734
|
});
|
|
1613
1735
|
};
|
|
1736
|
+
/**
|
|
1737
|
+
* ```graphql
|
|
1738
|
+
* # ex.
|
|
1739
|
+
* {
|
|
1740
|
+
* deleteDocument(relativePath: $relativePath, params: $params) {
|
|
1741
|
+
* id
|
|
1742
|
+
* data {...}
|
|
1743
|
+
* }
|
|
1744
|
+
* }
|
|
1745
|
+
* ```
|
|
1746
|
+
*
|
|
1747
|
+
* @param collections
|
|
1748
|
+
*/
|
|
1614
1749
|
this.buildDeleteCollectionDocumentMutation = async (collections) => {
|
|
1615
1750
|
return astBuilder.FieldDefinition({
|
|
1616
1751
|
name: "deleteDocument",
|
|
@@ -1630,6 +1765,19 @@ var Builder = class {
|
|
|
1630
1765
|
type: astBuilder.TYPES.MultiCollectionDocument
|
|
1631
1766
|
});
|
|
1632
1767
|
};
|
|
1768
|
+
/**
|
|
1769
|
+
* ```graphql
|
|
1770
|
+
* # ex.
|
|
1771
|
+
* {
|
|
1772
|
+
* createFolder(folderName: $folderName, params: $params) {
|
|
1773
|
+
* id
|
|
1774
|
+
* data {...}
|
|
1775
|
+
* }
|
|
1776
|
+
* }
|
|
1777
|
+
* ```
|
|
1778
|
+
*
|
|
1779
|
+
* @param collections
|
|
1780
|
+
*/
|
|
1633
1781
|
this.buildCreateCollectionFolderMutation = async () => {
|
|
1634
1782
|
return astBuilder.FieldDefinition({
|
|
1635
1783
|
name: "createFolder",
|
|
@@ -1649,6 +1797,19 @@ var Builder = class {
|
|
|
1649
1797
|
type: astBuilder.TYPES.MultiCollectionDocument
|
|
1650
1798
|
});
|
|
1651
1799
|
};
|
|
1800
|
+
/**
|
|
1801
|
+
* ```graphql
|
|
1802
|
+
* # ex.
|
|
1803
|
+
* {
|
|
1804
|
+
* getPostDocument(relativePath: $relativePath) {
|
|
1805
|
+
* id
|
|
1806
|
+
* data {...}
|
|
1807
|
+
* }
|
|
1808
|
+
* }
|
|
1809
|
+
* ```
|
|
1810
|
+
*
|
|
1811
|
+
* @param collection
|
|
1812
|
+
*/
|
|
1652
1813
|
this.collectionDocument = async (collection) => {
|
|
1653
1814
|
const name = NAMER.queryName([collection.name]);
|
|
1654
1815
|
const type = await this._buildCollectionDocumentType(collection);
|
|
@@ -1709,6 +1870,20 @@ var Builder = class {
|
|
|
1709
1870
|
const args = [];
|
|
1710
1871
|
return astBuilder.FieldDefinition({ type, name, args, required: false });
|
|
1711
1872
|
};
|
|
1873
|
+
/**
|
|
1874
|
+
* Turns a collection into a fragment that gets updated on build. This fragment does not resolve references
|
|
1875
|
+
* ```graphql
|
|
1876
|
+
* # ex.
|
|
1877
|
+
* fragment AuthorsParts on Authors {
|
|
1878
|
+
* name
|
|
1879
|
+
* avatar
|
|
1880
|
+
* ...
|
|
1881
|
+
* }
|
|
1882
|
+
* ```
|
|
1883
|
+
*
|
|
1884
|
+
* @public
|
|
1885
|
+
* @param collection a Tina Cloud collection
|
|
1886
|
+
*/
|
|
1712
1887
|
this.collectionFragment = async (collection) => {
|
|
1713
1888
|
const name = NAMER.dataTypeName(collection.namespace);
|
|
1714
1889
|
const fragmentName = NAMER.fragmentName(collection.namespace);
|
|
@@ -1722,6 +1897,20 @@ var Builder = class {
|
|
|
1722
1897
|
selections: filterSelections(selections)
|
|
1723
1898
|
});
|
|
1724
1899
|
};
|
|
1900
|
+
/**
|
|
1901
|
+
* Given a collection this function returns its selections set. For example for Post this would return
|
|
1902
|
+
*
|
|
1903
|
+
* "
|
|
1904
|
+
* body
|
|
1905
|
+
* title
|
|
1906
|
+
* ... on Author {
|
|
1907
|
+
* name
|
|
1908
|
+
* heroImg
|
|
1909
|
+
* }
|
|
1910
|
+
*
|
|
1911
|
+
* But in the AST format
|
|
1912
|
+
*
|
|
1913
|
+
* */
|
|
1725
1914
|
this._getCollectionFragmentSelections = async (collection, depth) => {
|
|
1726
1915
|
const selections = [];
|
|
1727
1916
|
selections.push({
|
|
@@ -1803,9 +1992,9 @@ var Builder = class {
|
|
|
1803
1992
|
]
|
|
1804
1993
|
});
|
|
1805
1994
|
}
|
|
1995
|
+
// TODO: Should we throw here?
|
|
1806
1996
|
case "reference":
|
|
1807
|
-
if (depth >= this.maxDepth)
|
|
1808
|
-
return false;
|
|
1997
|
+
if (depth >= this.maxDepth) return false;
|
|
1809
1998
|
if (!("collections" in field)) {
|
|
1810
1999
|
return false;
|
|
1811
2000
|
}
|
|
@@ -1837,6 +2026,7 @@ var Builder = class {
|
|
|
1837
2026
|
name: field.name,
|
|
1838
2027
|
selections: [
|
|
1839
2028
|
...selections,
|
|
2029
|
+
// This is ... on Document { id }
|
|
1840
2030
|
{
|
|
1841
2031
|
kind: "InlineFragment",
|
|
1842
2032
|
typeCondition: {
|
|
@@ -1867,6 +2057,19 @@ var Builder = class {
|
|
|
1867
2057
|
});
|
|
1868
2058
|
}
|
|
1869
2059
|
};
|
|
2060
|
+
/**
|
|
2061
|
+
* ```graphql
|
|
2062
|
+
* # ex.
|
|
2063
|
+
* mutation {
|
|
2064
|
+
* updatePostDocument(relativePath: $relativePath, params: $params) {
|
|
2065
|
+
* id
|
|
2066
|
+
* data {...}
|
|
2067
|
+
* }
|
|
2068
|
+
* }
|
|
2069
|
+
* ```
|
|
2070
|
+
*
|
|
2071
|
+
* @param collection
|
|
2072
|
+
*/
|
|
1870
2073
|
this.updateCollectionDocumentMutation = async (collection) => {
|
|
1871
2074
|
return astBuilder.FieldDefinition({
|
|
1872
2075
|
type: await this._buildCollectionDocumentType(collection),
|
|
@@ -1886,6 +2089,19 @@ var Builder = class {
|
|
|
1886
2089
|
]
|
|
1887
2090
|
});
|
|
1888
2091
|
};
|
|
2092
|
+
/**
|
|
2093
|
+
* ```graphql
|
|
2094
|
+
* # ex.
|
|
2095
|
+
* mutation {
|
|
2096
|
+
* createPostDocument(relativePath: $relativePath, params: $params) {
|
|
2097
|
+
* id
|
|
2098
|
+
* data {...}
|
|
2099
|
+
* }
|
|
2100
|
+
* }
|
|
2101
|
+
* ```
|
|
2102
|
+
*
|
|
2103
|
+
* @param collection
|
|
2104
|
+
*/
|
|
1889
2105
|
this.createCollectionDocumentMutation = async (collection) => {
|
|
1890
2106
|
return astBuilder.FieldDefinition({
|
|
1891
2107
|
type: await this._buildCollectionDocumentType(collection),
|
|
@@ -1905,6 +2121,22 @@ var Builder = class {
|
|
|
1905
2121
|
]
|
|
1906
2122
|
});
|
|
1907
2123
|
};
|
|
2124
|
+
/**
|
|
2125
|
+
* ```graphql
|
|
2126
|
+
* # ex.
|
|
2127
|
+
* {
|
|
2128
|
+
* getPostList(first: 10) {
|
|
2129
|
+
* edges {
|
|
2130
|
+
* node {
|
|
2131
|
+
* id
|
|
2132
|
+
* }
|
|
2133
|
+
* }
|
|
2134
|
+
* }
|
|
2135
|
+
* }
|
|
2136
|
+
* ```
|
|
2137
|
+
*
|
|
2138
|
+
* @param collection
|
|
2139
|
+
*/
|
|
1908
2140
|
this.collectionDocumentList = async (collection) => {
|
|
1909
2141
|
const connectionName = NAMER.referenceConnectionType(collection.namespace);
|
|
1910
2142
|
this.addToLookupMap({
|
|
@@ -1920,6 +2152,10 @@ var Builder = class {
|
|
|
1920
2152
|
collection
|
|
1921
2153
|
});
|
|
1922
2154
|
};
|
|
2155
|
+
/**
|
|
2156
|
+
* GraphQL type definitions which remain unchanged regardless
|
|
2157
|
+
* of the supplied Tina schema. Ex. "node" interface
|
|
2158
|
+
*/
|
|
1923
2159
|
this.buildStaticDefinitions = () => staticDefinitions;
|
|
1924
2160
|
this._buildCollectionDocumentType = async (collection, suffix = "", extraFields = [], extraInterfaces = []) => {
|
|
1925
2161
|
const documentTypeName = NAMER.documentTypeName(collection.namespace);
|
|
@@ -2424,6 +2660,7 @@ var Builder = class {
|
|
|
2424
2660
|
name: NAMER.dataFilterTypeName(namespace),
|
|
2425
2661
|
fields: await sequential(collections, async (collection2) => {
|
|
2426
2662
|
return astBuilder.InputValueDefinition({
|
|
2663
|
+
// @ts-ignore
|
|
2427
2664
|
name: collection2.name,
|
|
2428
2665
|
type: NAMER.dataFilterTypeName(collection2.namespace)
|
|
2429
2666
|
});
|
|
@@ -2612,7 +2849,8 @@ Visit https://tina.io/docs/errors/ui-not-supported/ for more information
|
|
|
2612
2849
|
]
|
|
2613
2850
|
});
|
|
2614
2851
|
};
|
|
2615
|
-
this.maxDepth =
|
|
2852
|
+
this.maxDepth = // @ts-ignore
|
|
2853
|
+
config?.tinaSchema.schema?.config?.client?.referenceDepth ?? 2;
|
|
2616
2854
|
this.tinaSchema = config.tinaSchema;
|
|
2617
2855
|
this.lookupMap = {};
|
|
2618
2856
|
}
|
|
@@ -2623,8 +2861,7 @@ Visit https://tina.io/docs/errors/ui-not-supported/ for more information
|
|
|
2623
2861
|
selections.push(field);
|
|
2624
2862
|
});
|
|
2625
2863
|
const filteredSelections = filterSelections(selections);
|
|
2626
|
-
if (!filteredSelections.length)
|
|
2627
|
-
return false;
|
|
2864
|
+
if (!filteredSelections.length) return false;
|
|
2628
2865
|
return astBuilder.InlineFragmentDefinition({
|
|
2629
2866
|
selections: filteredSelections,
|
|
2630
2867
|
name: NAMER.dataTypeName(template.namespace)
|
|
@@ -2707,6 +2944,7 @@ var validationCollectionsPathAndMatch = (collections) => {
|
|
|
2707
2944
|
}).map((x) => `${x.path}${x.format || "md"}`);
|
|
2708
2945
|
if (noMatchCollections.length !== new Set(noMatchCollections).size) {
|
|
2709
2946
|
throw new Error(
|
|
2947
|
+
// TODO: add a link to the docs
|
|
2710
2948
|
"Two collections without match can not have the same `path`. Please make the `path` unique or add a matches property to the collection."
|
|
2711
2949
|
);
|
|
2712
2950
|
}
|
|
@@ -2815,7 +3053,7 @@ var validateField = async (field) => {
|
|
|
2815
3053
|
// package.json
|
|
2816
3054
|
var package_default = {
|
|
2817
3055
|
name: "@tinacms/graphql",
|
|
2818
|
-
version: "1.5.
|
|
3056
|
+
version: "1.5.9",
|
|
2819
3057
|
main: "dist/index.js",
|
|
2820
3058
|
module: "dist/index.mjs",
|
|
2821
3059
|
typings: "dist/index.d.ts",
|
|
@@ -2859,7 +3097,7 @@ var package_default = {
|
|
|
2859
3097
|
"isomorphic-git": "^1.27.1",
|
|
2860
3098
|
"js-sha1": "^0.6.0",
|
|
2861
3099
|
"js-yaml": "^3.14.1",
|
|
2862
|
-
"jsonpath-plus": "
|
|
3100
|
+
"jsonpath-plus": "10.1.0",
|
|
2863
3101
|
"lodash.clonedeep": "^4.5.0",
|
|
2864
3102
|
"lodash.set": "^4.3.2",
|
|
2865
3103
|
"lodash.uniqby": "^4.7.0",
|
|
@@ -2891,7 +3129,7 @@ var package_default = {
|
|
|
2891
3129
|
"@types/lru-cache": "^5.1.1",
|
|
2892
3130
|
"@types/mdast": "^3.0.15",
|
|
2893
3131
|
"@types/micromatch": "^4.0.9",
|
|
2894
|
-
"@types/node": "^22.
|
|
3132
|
+
"@types/node": "^22.9.0",
|
|
2895
3133
|
"@types/normalize-path": "^3.0.2",
|
|
2896
3134
|
"@types/ws": "^7.4.7",
|
|
2897
3135
|
"@types/yup": "^0.29.14",
|
|
@@ -2901,7 +3139,7 @@ var package_default = {
|
|
|
2901
3139
|
"jest-matcher-utils": "^29.7.0",
|
|
2902
3140
|
"memory-level": "^1.0.0",
|
|
2903
3141
|
nodemon: "3.1.4",
|
|
2904
|
-
typescript: "^5.6.
|
|
3142
|
+
typescript: "^5.6.3"
|
|
2905
3143
|
}
|
|
2906
3144
|
};
|
|
2907
3145
|
|
|
@@ -2972,6 +3210,7 @@ var _buildFragments = async (builder, tinaSchema) => {
|
|
|
2972
3210
|
const fragDoc = {
|
|
2973
3211
|
kind: "Document",
|
|
2974
3212
|
definitions: uniqBy2(
|
|
3213
|
+
// @ts-ignore
|
|
2975
3214
|
extractInlineTypes(fragmentDefinitionsFields),
|
|
2976
3215
|
(node) => node.name.value
|
|
2977
3216
|
)
|
|
@@ -2994,6 +3233,7 @@ var _buildQueries = async (builder, tinaSchema) => {
|
|
|
2994
3233
|
fragName,
|
|
2995
3234
|
queryName: queryListName,
|
|
2996
3235
|
filterType: queryFilterTypeName,
|
|
3236
|
+
// look for flag to see if the data layer is enabled
|
|
2997
3237
|
dataLayer: Boolean(
|
|
2998
3238
|
tinaSchema.config?.meta?.flags?.find((x) => x === "experimentalData")
|
|
2999
3239
|
)
|
|
@@ -3003,6 +3243,7 @@ var _buildQueries = async (builder, tinaSchema) => {
|
|
|
3003
3243
|
const queryDoc = {
|
|
3004
3244
|
kind: "Document",
|
|
3005
3245
|
definitions: uniqBy2(
|
|
3246
|
+
// @ts-ignore
|
|
3006
3247
|
extractInlineTypes(operationsDefinitions),
|
|
3007
3248
|
(node) => node.name.value
|
|
3008
3249
|
)
|
|
@@ -3091,6 +3332,7 @@ var _buildSchema = async (builder, tinaSchema) => {
|
|
|
3091
3332
|
return {
|
|
3092
3333
|
kind: "Document",
|
|
3093
3334
|
definitions: uniqBy2(
|
|
3335
|
+
// @ts-ignore
|
|
3094
3336
|
extractInlineTypes(definitions),
|
|
3095
3337
|
(node) => node.name.value
|
|
3096
3338
|
)
|
|
@@ -3107,6 +3349,9 @@ import isValid from "date-fns/isValid/index.js";
|
|
|
3107
3349
|
// src/mdx/index.ts
|
|
3108
3350
|
import { parseMDX, stringifyMDX } from "@tinacms/mdx";
|
|
3109
3351
|
|
|
3352
|
+
// src/resolver/index.ts
|
|
3353
|
+
import { JSONPath as JSONPath2 } from "jsonpath-plus";
|
|
3354
|
+
|
|
3110
3355
|
// src/resolver/error.ts
|
|
3111
3356
|
var TinaGraphQLError = class extends Error {
|
|
3112
3357
|
constructor(message, extensions) {
|
|
@@ -3292,8 +3537,7 @@ var resolveMediaCloudToRelative = (value, config = { useRelativeMedia: true }, s
|
|
|
3292
3537
|
}
|
|
3293
3538
|
if (Array.isArray(value)) {
|
|
3294
3539
|
return value.map((v) => {
|
|
3295
|
-
if (!v || typeof v !== "string")
|
|
3296
|
-
return v;
|
|
3540
|
+
if (!v || typeof v !== "string") return v;
|
|
3297
3541
|
const cleanMediaRoot = cleanUpSlashes(
|
|
3298
3542
|
schema.config.media.tina.mediaRoot
|
|
3299
3543
|
);
|
|
@@ -3321,8 +3565,7 @@ var resolveMediaRelativeToCloud = (value, config = { useRelativeMedia: true }, s
|
|
|
3321
3565
|
}
|
|
3322
3566
|
if (Array.isArray(value)) {
|
|
3323
3567
|
return value.map((v) => {
|
|
3324
|
-
if (!v || typeof v !== "string")
|
|
3325
|
-
return v;
|
|
3568
|
+
if (!v || typeof v !== "string") return v;
|
|
3326
3569
|
const strippedValue = v.replace(cleanMediaRoot, "");
|
|
3327
3570
|
return `https://${config.assetsHost}/${config.clientId}${strippedValue}`;
|
|
3328
3571
|
});
|
|
@@ -3340,8 +3583,7 @@ var cleanUpSlashes = (path7) => {
|
|
|
3340
3583
|
return "";
|
|
3341
3584
|
};
|
|
3342
3585
|
var hasTinaMediaConfig = (schema) => {
|
|
3343
|
-
if (!schema.config?.media?.tina)
|
|
3344
|
-
return false;
|
|
3586
|
+
if (!schema.config?.media?.tina) return false;
|
|
3345
3587
|
if (typeof schema.config?.media?.tina?.publicFolder !== "string" && typeof schema.config?.media?.tina?.mediaRoot !== "string")
|
|
3346
3588
|
return false;
|
|
3347
3589
|
return true;
|
|
@@ -3385,6 +3627,7 @@ var LevelProxyHandler = {
|
|
|
3385
3627
|
} else if (property === "sublevel") {
|
|
3386
3628
|
return (...args) => {
|
|
3387
3629
|
return new Proxy(
|
|
3630
|
+
// eslint-disable-next-line prefer-spread
|
|
3388
3631
|
target[property].apply(target, args),
|
|
3389
3632
|
LevelProxyHandler
|
|
3390
3633
|
);
|
|
@@ -4261,6 +4504,7 @@ var makeFolderOpsForCollection = (folderTree, collection, indexDefinitions, opTy
|
|
|
4261
4504
|
result.push({
|
|
4262
4505
|
type: opType,
|
|
4263
4506
|
key: `${collection.path}/${subFolderKey}.${collection.format}`,
|
|
4507
|
+
// replace the root with the collection path
|
|
4264
4508
|
sublevel: indexSublevel,
|
|
4265
4509
|
value: {}
|
|
4266
4510
|
});
|
|
@@ -4375,6 +4619,7 @@ var resolveFieldData = async ({ namespace, ...field }, rawData, accumulator, tin
|
|
|
4375
4619
|
case "password":
|
|
4376
4620
|
accumulator[field.name] = {
|
|
4377
4621
|
value: void 0,
|
|
4622
|
+
// never resolve the password hash
|
|
4378
4623
|
passwordChangeRequired: value["passwordChangeRequired"] ?? false
|
|
4379
4624
|
};
|
|
4380
4625
|
break;
|
|
@@ -4469,7 +4714,7 @@ var resolveFieldData = async ({ namespace, ...field }, rawData, accumulator, tin
|
|
|
4469
4714
|
}
|
|
4470
4715
|
return accumulator;
|
|
4471
4716
|
};
|
|
4472
|
-
var transformDocumentIntoPayload = async (fullPath, rawData, tinaSchema, config, isAudit) => {
|
|
4717
|
+
var transformDocumentIntoPayload = async (fullPath, rawData, tinaSchema, config, isAudit, hasReferences) => {
|
|
4473
4718
|
const collection = tinaSchema.getCollection(rawData._collection);
|
|
4474
4719
|
try {
|
|
4475
4720
|
const template = tinaSchema.getTemplateForData({
|
|
@@ -4523,6 +4768,7 @@ var transformDocumentIntoPayload = async (fullPath, rawData, tinaSchema, config,
|
|
|
4523
4768
|
basename,
|
|
4524
4769
|
filename,
|
|
4525
4770
|
extension,
|
|
4771
|
+
hasReferences,
|
|
4526
4772
|
path: fullPath,
|
|
4527
4773
|
relativePath,
|
|
4528
4774
|
breadcrumbs,
|
|
@@ -4542,6 +4788,25 @@ var transformDocumentIntoPayload = async (fullPath, rawData, tinaSchema, config,
|
|
|
4542
4788
|
throw e;
|
|
4543
4789
|
}
|
|
4544
4790
|
};
|
|
4791
|
+
var updateObjectWithJsonPath = (obj, path7, newValue) => {
|
|
4792
|
+
if (!path7.includes(".") && !path7.includes("[")) {
|
|
4793
|
+
if (path7 in obj) {
|
|
4794
|
+
obj[path7] = newValue;
|
|
4795
|
+
}
|
|
4796
|
+
return obj;
|
|
4797
|
+
}
|
|
4798
|
+
const parentPath = path7.replace(/\.[^.]+$/, "");
|
|
4799
|
+
const keyToUpdate = path7.match(/[^.]+$/)[0];
|
|
4800
|
+
const parents = JSONPath2({ path: parentPath, json: obj, resultType: "value" });
|
|
4801
|
+
if (parents.length > 0) {
|
|
4802
|
+
parents.forEach((parent) => {
|
|
4803
|
+
if (parent && typeof parent === "object" && keyToUpdate in parent) {
|
|
4804
|
+
parent[keyToUpdate] = newValue;
|
|
4805
|
+
}
|
|
4806
|
+
});
|
|
4807
|
+
}
|
|
4808
|
+
return obj;
|
|
4809
|
+
};
|
|
4545
4810
|
var Resolver = class {
|
|
4546
4811
|
constructor(init) {
|
|
4547
4812
|
this.init = init;
|
|
@@ -4549,6 +4814,7 @@ var Resolver = class {
|
|
|
4549
4814
|
const collection = this.tinaSchema.getCollection(collectionName);
|
|
4550
4815
|
const extraFields = {};
|
|
4551
4816
|
return {
|
|
4817
|
+
// return the collection and hasDocuments to resolve documents at a lower level
|
|
4552
4818
|
documents: { collection, hasDocuments },
|
|
4553
4819
|
...collection,
|
|
4554
4820
|
...extraFields
|
|
@@ -4583,17 +4849,19 @@ var Resolver = class {
|
|
|
4583
4849
|
);
|
|
4584
4850
|
}
|
|
4585
4851
|
};
|
|
4586
|
-
this.getDocument = async (fullPath) => {
|
|
4852
|
+
this.getDocument = async (fullPath, opts = {}) => {
|
|
4587
4853
|
if (typeof fullPath !== "string") {
|
|
4588
4854
|
throw new Error(`fullPath must be of type string for getDocument request`);
|
|
4589
4855
|
}
|
|
4590
4856
|
const rawData = await this.getRaw(fullPath);
|
|
4857
|
+
const hasReferences = opts?.checkReferences ? await this.hasReferences(fullPath, opts.collection) : void 0;
|
|
4591
4858
|
return transformDocumentIntoPayload(
|
|
4592
4859
|
fullPath,
|
|
4593
4860
|
rawData,
|
|
4594
4861
|
this.tinaSchema,
|
|
4595
4862
|
this.config,
|
|
4596
|
-
this.isAudit
|
|
4863
|
+
this.isAudit,
|
|
4864
|
+
hasReferences
|
|
4597
4865
|
);
|
|
4598
4866
|
};
|
|
4599
4867
|
this.deleteDocument = async (fullPath) => {
|
|
@@ -4633,7 +4901,9 @@ var Resolver = class {
|
|
|
4633
4901
|
);
|
|
4634
4902
|
} else {
|
|
4635
4903
|
return this.buildFieldMutations(
|
|
4904
|
+
// @ts-ignore FIXME Argument of type 'string | object' is not assignable to parameter of type '{ [fieldName: string]: string | object | (string | object)[]; }'
|
|
4636
4905
|
fieldValue,
|
|
4906
|
+
//@ts-ignore
|
|
4637
4907
|
objectTemplate,
|
|
4638
4908
|
existingData
|
|
4639
4909
|
);
|
|
@@ -4645,6 +4915,7 @@ var Resolver = class {
|
|
|
4645
4915
|
fieldValue.map(async (item) => {
|
|
4646
4916
|
if (typeof item === "string") {
|
|
4647
4917
|
throw new Error(
|
|
4918
|
+
//@ts-ignore
|
|
4648
4919
|
`Expected object for template value for field ${field.name}`
|
|
4649
4920
|
);
|
|
4650
4921
|
}
|
|
@@ -4653,16 +4924,19 @@ var Resolver = class {
|
|
|
4653
4924
|
});
|
|
4654
4925
|
const [templateName] = Object.entries(item)[0];
|
|
4655
4926
|
const template = templates.find(
|
|
4927
|
+
//@ts-ignore
|
|
4656
4928
|
(template2) => template2.name === templateName
|
|
4657
4929
|
);
|
|
4658
4930
|
if (!template) {
|
|
4659
4931
|
throw new Error(`Expected to find template ${templateName}`);
|
|
4660
4932
|
}
|
|
4661
4933
|
return {
|
|
4934
|
+
// @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
4935
|
...await this.buildFieldMutations(
|
|
4663
4936
|
item[template.name],
|
|
4664
4937
|
template
|
|
4665
4938
|
),
|
|
4939
|
+
//@ts-ignore
|
|
4666
4940
|
_template: template.name
|
|
4667
4941
|
};
|
|
4668
4942
|
})
|
|
@@ -4670,6 +4944,7 @@ var Resolver = class {
|
|
|
4670
4944
|
} else {
|
|
4671
4945
|
if (typeof fieldValue === "string") {
|
|
4672
4946
|
throw new Error(
|
|
4947
|
+
//@ts-ignore
|
|
4673
4948
|
`Expected object for template value for field ${field.name}`
|
|
4674
4949
|
);
|
|
4675
4950
|
}
|
|
@@ -4678,16 +4953,19 @@ var Resolver = class {
|
|
|
4678
4953
|
});
|
|
4679
4954
|
const [templateName] = Object.entries(fieldValue)[0];
|
|
4680
4955
|
const template = templates.find(
|
|
4956
|
+
//@ts-ignore
|
|
4681
4957
|
(template2) => template2.name === templateName
|
|
4682
4958
|
);
|
|
4683
4959
|
if (!template) {
|
|
4684
4960
|
throw new Error(`Expected to find template ${templateName}`);
|
|
4685
4961
|
}
|
|
4686
4962
|
return {
|
|
4963
|
+
// @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
4964
|
...await this.buildFieldMutations(
|
|
4688
4965
|
fieldValue[template.name],
|
|
4689
4966
|
template
|
|
4690
4967
|
),
|
|
4968
|
+
//@ts-ignore
|
|
4691
4969
|
_template: template.name
|
|
4692
4970
|
};
|
|
4693
4971
|
}
|
|
@@ -4727,6 +5005,7 @@ var Resolver = class {
|
|
|
4727
5005
|
return this.getDocument(realPath);
|
|
4728
5006
|
}
|
|
4729
5007
|
const params = await this.buildObjectMutations(
|
|
5008
|
+
// @ts-ignore
|
|
4730
5009
|
args.params[collection.name],
|
|
4731
5010
|
collection
|
|
4732
5011
|
);
|
|
@@ -4772,6 +5051,7 @@ var Resolver = class {
|
|
|
4772
5051
|
const values = {
|
|
4773
5052
|
...oldDoc,
|
|
4774
5053
|
...await this.buildFieldMutations(
|
|
5054
|
+
// @ts-ignore FIXME: failing on unknown, which we don't need to know because it's recursive
|
|
4775
5055
|
templateParams,
|
|
4776
5056
|
template,
|
|
4777
5057
|
doc?._rawData
|
|
@@ -4785,6 +5065,7 @@ var Resolver = class {
|
|
|
4785
5065
|
return this.getDocument(realPath);
|
|
4786
5066
|
}
|
|
4787
5067
|
const params = await this.buildObjectMutations(
|
|
5068
|
+
//@ts-ignore
|
|
4788
5069
|
isCollectionSpecific ? args.params : args.params[collection.name],
|
|
4789
5070
|
collection,
|
|
4790
5071
|
doc?._rawData
|
|
@@ -4792,6 +5073,10 @@ var Resolver = class {
|
|
|
4792
5073
|
await this.database.put(realPath, { ...oldDoc, ...params }, collection.name);
|
|
4793
5074
|
return this.getDocument(realPath);
|
|
4794
5075
|
};
|
|
5076
|
+
/**
|
|
5077
|
+
* Returns top-level fields which are not defined in the collection, so their
|
|
5078
|
+
* values are not eliminated from Tina when new values are saved
|
|
5079
|
+
*/
|
|
4795
5080
|
this.resolveLegacyValues = (oldDoc, collection) => {
|
|
4796
5081
|
const legacyValues = {};
|
|
4797
5082
|
Object.entries(oldDoc).forEach(([key, value]) => {
|
|
@@ -4896,6 +5181,22 @@ var Resolver = class {
|
|
|
4896
5181
|
if (isDeletion) {
|
|
4897
5182
|
const doc = await this.getDocument(realPath);
|
|
4898
5183
|
await this.deleteDocument(realPath);
|
|
5184
|
+
if (await this.hasReferences(realPath, collection)) {
|
|
5185
|
+
const collRefs = await this.findReferences(realPath, collection);
|
|
5186
|
+
for (const [collection2, refFields] of Object.entries(collRefs)) {
|
|
5187
|
+
for (const [refPath, refs] of Object.entries(refFields)) {
|
|
5188
|
+
let refDoc = await this.getRaw(refPath);
|
|
5189
|
+
for (const ref of refs) {
|
|
5190
|
+
refDoc = updateObjectWithJsonPath(
|
|
5191
|
+
refDoc,
|
|
5192
|
+
ref.path.join("."),
|
|
5193
|
+
null
|
|
5194
|
+
);
|
|
5195
|
+
}
|
|
5196
|
+
await this.database.put(refPath, refDoc, collection2);
|
|
5197
|
+
}
|
|
5198
|
+
}
|
|
5199
|
+
}
|
|
4899
5200
|
return doc;
|
|
4900
5201
|
}
|
|
4901
5202
|
if (isUpdateName) {
|
|
@@ -4914,6 +5215,20 @@ var Resolver = class {
|
|
|
4914
5215
|
);
|
|
4915
5216
|
await this.database.put(newRealPath, doc._rawData, collection.name);
|
|
4916
5217
|
await this.deleteDocument(realPath);
|
|
5218
|
+
const collRefs = await this.findReferences(realPath, collection);
|
|
5219
|
+
for (const [collection2, refFields] of Object.entries(collRefs)) {
|
|
5220
|
+
for (const [refPath, refs] of Object.entries(refFields)) {
|
|
5221
|
+
let refDoc = await this.getRaw(refPath);
|
|
5222
|
+
for (const ref of refs) {
|
|
5223
|
+
refDoc = updateObjectWithJsonPath(
|
|
5224
|
+
refDoc,
|
|
5225
|
+
ref.path.join("."),
|
|
5226
|
+
newRealPath
|
|
5227
|
+
);
|
|
5228
|
+
}
|
|
5229
|
+
await this.database.put(refPath, refDoc, collection2);
|
|
5230
|
+
}
|
|
5231
|
+
}
|
|
4917
5232
|
return this.getDocument(newRealPath);
|
|
4918
5233
|
}
|
|
4919
5234
|
if (alreadyExists === false) {
|
|
@@ -4927,7 +5242,10 @@ var Resolver = class {
|
|
|
4927
5242
|
isCollectionSpecific
|
|
4928
5243
|
});
|
|
4929
5244
|
} else {
|
|
4930
|
-
return this.getDocument(realPath
|
|
5245
|
+
return this.getDocument(realPath, {
|
|
5246
|
+
collection,
|
|
5247
|
+
checkReferences: true
|
|
5248
|
+
});
|
|
4931
5249
|
}
|
|
4932
5250
|
};
|
|
4933
5251
|
this.resolveCollectionConnections = async ({ ids }) => {
|
|
@@ -4964,6 +5282,7 @@ var Resolver = class {
|
|
|
4964
5282
|
},
|
|
4965
5283
|
collection: referencedCollection,
|
|
4966
5284
|
hydrator: (path7) => path7
|
|
5285
|
+
// just return the path
|
|
4967
5286
|
}
|
|
4968
5287
|
);
|
|
4969
5288
|
const { edges } = resolvedCollectionConnection;
|
|
@@ -5031,6 +5350,92 @@ var Resolver = class {
|
|
|
5031
5350
|
}
|
|
5032
5351
|
};
|
|
5033
5352
|
};
|
|
5353
|
+
/**
|
|
5354
|
+
* Checks if a document has references to it
|
|
5355
|
+
* @param id The id of the document to check for references
|
|
5356
|
+
* @param c The collection to check for references
|
|
5357
|
+
* @returns true if the document has references, false otherwise
|
|
5358
|
+
*/
|
|
5359
|
+
this.hasReferences = async (id, c) => {
|
|
5360
|
+
let count = 0;
|
|
5361
|
+
const deepRefs = this.tinaSchema.findReferences(c.name);
|
|
5362
|
+
for (const [collection, refs] of Object.entries(deepRefs)) {
|
|
5363
|
+
for (const ref of refs) {
|
|
5364
|
+
await this.database.query(
|
|
5365
|
+
{
|
|
5366
|
+
collection,
|
|
5367
|
+
filterChain: makeFilterChain({
|
|
5368
|
+
conditions: [
|
|
5369
|
+
{
|
|
5370
|
+
filterPath: ref.path.join("."),
|
|
5371
|
+
filterExpression: {
|
|
5372
|
+
_type: "reference",
|
|
5373
|
+
_list: false,
|
|
5374
|
+
eq: id
|
|
5375
|
+
}
|
|
5376
|
+
}
|
|
5377
|
+
]
|
|
5378
|
+
}),
|
|
5379
|
+
sort: ref.field.name
|
|
5380
|
+
},
|
|
5381
|
+
(refId) => {
|
|
5382
|
+
count++;
|
|
5383
|
+
return refId;
|
|
5384
|
+
}
|
|
5385
|
+
);
|
|
5386
|
+
if (count) {
|
|
5387
|
+
return true;
|
|
5388
|
+
}
|
|
5389
|
+
}
|
|
5390
|
+
}
|
|
5391
|
+
return false;
|
|
5392
|
+
};
|
|
5393
|
+
/**
|
|
5394
|
+
* Finds references to a document
|
|
5395
|
+
* @param id the id of the document to find references to
|
|
5396
|
+
* @param c the collection to find references in
|
|
5397
|
+
* @returns references to the document in the form of a map of collection names to a list of fields that reference the document
|
|
5398
|
+
*/
|
|
5399
|
+
this.findReferences = async (id, c) => {
|
|
5400
|
+
const references = {};
|
|
5401
|
+
const deepRefs = this.tinaSchema.findReferences(c.name);
|
|
5402
|
+
for (const [collection, refs] of Object.entries(deepRefs)) {
|
|
5403
|
+
for (const ref of refs) {
|
|
5404
|
+
await this.database.query(
|
|
5405
|
+
{
|
|
5406
|
+
collection,
|
|
5407
|
+
filterChain: makeFilterChain({
|
|
5408
|
+
conditions: [
|
|
5409
|
+
{
|
|
5410
|
+
filterPath: ref.path.join("."),
|
|
5411
|
+
filterExpression: {
|
|
5412
|
+
_type: "reference",
|
|
5413
|
+
_list: false,
|
|
5414
|
+
eq: id
|
|
5415
|
+
}
|
|
5416
|
+
}
|
|
5417
|
+
]
|
|
5418
|
+
}),
|
|
5419
|
+
sort: ref.field.name
|
|
5420
|
+
},
|
|
5421
|
+
(refId) => {
|
|
5422
|
+
if (!references[collection]) {
|
|
5423
|
+
references[collection] = {};
|
|
5424
|
+
}
|
|
5425
|
+
if (!references[collection][refId]) {
|
|
5426
|
+
references[collection][refId] = [];
|
|
5427
|
+
}
|
|
5428
|
+
references[collection][refId].push({
|
|
5429
|
+
path: ref.path,
|
|
5430
|
+
field: ref.field
|
|
5431
|
+
});
|
|
5432
|
+
return refId;
|
|
5433
|
+
}
|
|
5434
|
+
);
|
|
5435
|
+
}
|
|
5436
|
+
}
|
|
5437
|
+
return references;
|
|
5438
|
+
};
|
|
5034
5439
|
this.buildFieldMutations = async (fieldParams, template, existingData) => {
|
|
5035
5440
|
const accum = {};
|
|
5036
5441
|
for (const passwordField of template.fields.filter(
|
|
@@ -5117,6 +5522,27 @@ var Resolver = class {
|
|
|
5117
5522
|
}
|
|
5118
5523
|
return accum;
|
|
5119
5524
|
};
|
|
5525
|
+
/**
|
|
5526
|
+
* A mutation looks nearly identical between updateDocument:
|
|
5527
|
+
* ```graphql
|
|
5528
|
+
* updateDocument(collection: $collection,relativePath: $path, params: {
|
|
5529
|
+
* post: {
|
|
5530
|
+
* title: "Hello, World"
|
|
5531
|
+
* }
|
|
5532
|
+
* })`
|
|
5533
|
+
* ```
|
|
5534
|
+
* and `updatePostDocument`:
|
|
5535
|
+
* ```graphql
|
|
5536
|
+
* updatePostDocument(relativePath: $path, params: {
|
|
5537
|
+
* title: "Hello, World"
|
|
5538
|
+
* })
|
|
5539
|
+
* ```
|
|
5540
|
+
* The problem here is that we don't know whether the payload came from `updateDocument`
|
|
5541
|
+
* or `updatePostDocument` (we could, but for now it's easier not to pipe those details through),
|
|
5542
|
+
* But we do know that when given a `args.collection` value, we can assume that
|
|
5543
|
+
* this was a `updateDocument` request, and thus - should grab the data
|
|
5544
|
+
* from the corresponding field name in the key
|
|
5545
|
+
*/
|
|
5120
5546
|
this.buildParams = (args) => {
|
|
5121
5547
|
try {
|
|
5122
5548
|
assertShape(
|
|
@@ -5216,7 +5642,10 @@ var resolve = async ({
|
|
|
5216
5642
|
const graphQLSchema = buildASTSchema(graphQLSchemaAst);
|
|
5217
5643
|
const tinaConfig = await database.getTinaSchema();
|
|
5218
5644
|
const tinaSchema = await createSchema({
|
|
5645
|
+
// TODO: please update all the types to import from @tinacms/schema-tools
|
|
5646
|
+
// @ts-ignore
|
|
5219
5647
|
schema: tinaConfig,
|
|
5648
|
+
// @ts-ignore
|
|
5220
5649
|
flags: tinaConfig?.meta?.flags
|
|
5221
5650
|
});
|
|
5222
5651
|
const resolver = createResolver({
|
|
@@ -5233,8 +5662,7 @@ var resolve = async ({
|
|
|
5233
5662
|
database
|
|
5234
5663
|
},
|
|
5235
5664
|
typeResolver: async (source, _args, info) => {
|
|
5236
|
-
if (source.__typename)
|
|
5237
|
-
return source.__typename;
|
|
5665
|
+
if (source.__typename) return source.__typename;
|
|
5238
5666
|
const namedType = getNamedType(info.returnType).toString();
|
|
5239
5667
|
const lookup = await database.getLookup(namedType);
|
|
5240
5668
|
if (lookup.resolveType === "unionData") {
|
|
@@ -5383,11 +5811,13 @@ var resolve = async ({
|
|
|
5383
5811
|
set(
|
|
5384
5812
|
params,
|
|
5385
5813
|
userField.path.slice(1),
|
|
5814
|
+
// remove _rawData from users path
|
|
5386
5815
|
users.map((u) => {
|
|
5387
5816
|
if (user[idFieldName] === u[idFieldName]) {
|
|
5388
5817
|
return user;
|
|
5389
5818
|
}
|
|
5390
5819
|
return {
|
|
5820
|
+
// don't overwrite other users' passwords
|
|
5391
5821
|
...u,
|
|
5392
5822
|
[passwordFieldName]: {
|
|
5393
5823
|
...u[passwordFieldName],
|
|
@@ -5410,6 +5840,9 @@ var resolve = async ({
|
|
|
5410
5840
|
}
|
|
5411
5841
|
const isCreation = lookup[info.fieldName] === "create";
|
|
5412
5842
|
switch (lookup.resolveType) {
|
|
5843
|
+
/**
|
|
5844
|
+
* `node(id: $id)`
|
|
5845
|
+
*/
|
|
5413
5846
|
case "nodeDocument":
|
|
5414
5847
|
assertShape(
|
|
5415
5848
|
args,
|
|
@@ -5441,6 +5874,7 @@ var resolve = async ({
|
|
|
5441
5874
|
collection: args.collection,
|
|
5442
5875
|
isMutation,
|
|
5443
5876
|
isCreation,
|
|
5877
|
+
// Right now this is the only case for deletion
|
|
5444
5878
|
isDeletion: info.fieldName === "deleteDocument",
|
|
5445
5879
|
isFolderCreation: info.fieldName === "createFolder",
|
|
5446
5880
|
isUpdateName: Boolean(args?.params?.relativePath),
|
|
@@ -5450,6 +5884,9 @@ var resolve = async ({
|
|
|
5450
5884
|
return result;
|
|
5451
5885
|
}
|
|
5452
5886
|
return value;
|
|
5887
|
+
/**
|
|
5888
|
+
* eg `getMovieDocument.data.actors`
|
|
5889
|
+
*/
|
|
5453
5890
|
case "multiCollectionDocumentList":
|
|
5454
5891
|
if (Array.isArray(value)) {
|
|
5455
5892
|
return {
|
|
@@ -5461,7 +5898,15 @@ var resolve = async ({
|
|
|
5461
5898
|
}
|
|
5462
5899
|
if (info.fieldName === "documents" && value?.collection && value?.hasDocuments) {
|
|
5463
5900
|
let filter = args.filter;
|
|
5464
|
-
if (
|
|
5901
|
+
if (
|
|
5902
|
+
// 1. Make sure that the filter exists
|
|
5903
|
+
typeof args?.filter !== "undefined" && args?.filter !== null && // 2. Make sure that the collection name exists
|
|
5904
|
+
// @ts-ignore
|
|
5905
|
+
typeof value?.collection?.name === "string" && // 3. Make sure that the collection name is in the filter and is not undefined
|
|
5906
|
+
// @ts-ignore
|
|
5907
|
+
Object.keys(args.filter).includes(value?.collection?.name) && // @ts-ignore
|
|
5908
|
+
typeof args.filter[value?.collection?.name] !== "undefined"
|
|
5909
|
+
) {
|
|
5465
5910
|
filter = args.filter[value.collection.name];
|
|
5466
5911
|
}
|
|
5467
5912
|
return resolver.resolveCollectionConnection({
|
|
@@ -5469,12 +5914,20 @@ var resolve = async ({
|
|
|
5469
5914
|
...args,
|
|
5470
5915
|
filter
|
|
5471
5916
|
},
|
|
5917
|
+
// @ts-ignore
|
|
5472
5918
|
collection: value.collection
|
|
5473
5919
|
});
|
|
5474
5920
|
}
|
|
5475
5921
|
throw new Error(
|
|
5476
5922
|
`Expected an array for result of ${info.fieldName} at ${info.path}`
|
|
5477
5923
|
);
|
|
5924
|
+
/**
|
|
5925
|
+
* Collections-specific getter
|
|
5926
|
+
* eg. `getPostDocument`/`createPostDocument`/`updatePostDocument`
|
|
5927
|
+
*
|
|
5928
|
+
* if coming from a query result
|
|
5929
|
+
* the field will be `node`
|
|
5930
|
+
*/
|
|
5478
5931
|
case "collectionDocument": {
|
|
5479
5932
|
if (value) {
|
|
5480
5933
|
return value;
|
|
@@ -5489,11 +5942,32 @@ var resolve = async ({
|
|
|
5489
5942
|
});
|
|
5490
5943
|
return result;
|
|
5491
5944
|
}
|
|
5945
|
+
/**
|
|
5946
|
+
* Collections-specific list getter
|
|
5947
|
+
* eg. `getPageList`
|
|
5948
|
+
*/
|
|
5492
5949
|
case "collectionDocumentList":
|
|
5493
5950
|
return resolver.resolveCollectionConnection({
|
|
5494
5951
|
args,
|
|
5495
5952
|
collection: tinaSchema.getCollection(lookup.collection)
|
|
5496
5953
|
});
|
|
5954
|
+
/**
|
|
5955
|
+
* A polymorphic data set, it can be from a document's data
|
|
5956
|
+
* of any nested object which can be one of many shapes
|
|
5957
|
+
*
|
|
5958
|
+
* ```graphql
|
|
5959
|
+
* getPostDocument(relativePath: $relativePath) {
|
|
5960
|
+
* data {...} <- this part
|
|
5961
|
+
* }
|
|
5962
|
+
* ```
|
|
5963
|
+
* ```graphql
|
|
5964
|
+
* getBlockDocument(relativePath: $relativePath) {
|
|
5965
|
+
* data {
|
|
5966
|
+
* blocks {...} <- or this part
|
|
5967
|
+
* }
|
|
5968
|
+
* }
|
|
5969
|
+
* ```
|
|
5970
|
+
*/
|
|
5497
5971
|
case "unionData":
|
|
5498
5972
|
if (!value) {
|
|
5499
5973
|
if (args.relativePath) {
|
|
@@ -5558,8 +6032,7 @@ var TinaLevelClient = class extends ManyLevelGuest {
|
|
|
5558
6032
|
this.port = port || 9e3;
|
|
5559
6033
|
}
|
|
5560
6034
|
openConnection() {
|
|
5561
|
-
if (this._connected)
|
|
5562
|
-
return;
|
|
6035
|
+
if (this._connected) return;
|
|
5563
6036
|
const socket = connect(this.port);
|
|
5564
6037
|
pipeline(socket, this.createRpcStream(), socket, () => {
|
|
5565
6038
|
this._connected = false;
|
|
@@ -5569,7 +6042,7 @@ var TinaLevelClient = class extends ManyLevelGuest {
|
|
|
5569
6042
|
};
|
|
5570
6043
|
|
|
5571
6044
|
// src/database/index.ts
|
|
5572
|
-
import path4 from "path";
|
|
6045
|
+
import path4 from "node:path";
|
|
5573
6046
|
import { GraphQLError as GraphQLError5 } from "graphql";
|
|
5574
6047
|
import micromatch2 from "micromatch";
|
|
5575
6048
|
import sha2 from "js-sha1";
|
|
@@ -5740,6 +6213,7 @@ var Database = class {
|
|
|
5740
6213
|
"put",
|
|
5741
6214
|
level
|
|
5742
6215
|
),
|
|
6216
|
+
// folder indices
|
|
5743
6217
|
...makeIndexOpsForDocument(
|
|
5744
6218
|
normalizedPath,
|
|
5745
6219
|
`${collection?.name}_${folderKey}`,
|
|
@@ -5762,6 +6236,7 @@ var Database = class {
|
|
|
5762
6236
|
"del",
|
|
5763
6237
|
level
|
|
5764
6238
|
),
|
|
6239
|
+
// folder indices
|
|
5765
6240
|
...makeIndexOpsForDocument(
|
|
5766
6241
|
normalizedPath,
|
|
5767
6242
|
`${collection?.name}_${folderKey}`,
|
|
@@ -5855,6 +6330,7 @@ var Database = class {
|
|
|
5855
6330
|
"put",
|
|
5856
6331
|
level
|
|
5857
6332
|
),
|
|
6333
|
+
// folder indices
|
|
5858
6334
|
...makeIndexOpsForDocument(
|
|
5859
6335
|
normalizedPath,
|
|
5860
6336
|
`${collection?.name}_${folderKey}`,
|
|
@@ -5877,6 +6353,7 @@ var Database = class {
|
|
|
5877
6353
|
"del",
|
|
5878
6354
|
level
|
|
5879
6355
|
),
|
|
6356
|
+
// folder indices
|
|
5880
6357
|
...makeIndexOpsForDocument(
|
|
5881
6358
|
normalizedPath,
|
|
5882
6359
|
`${collection?.name}_${folderKey}`,
|
|
@@ -5954,6 +6431,7 @@ var Database = class {
|
|
|
5954
6431
|
aliasedData,
|
|
5955
6432
|
extension,
|
|
5956
6433
|
writeTemplateKey,
|
|
6434
|
+
//templateInfo.type === 'union',
|
|
5957
6435
|
{
|
|
5958
6436
|
frontmatterFormat: collection?.frontmatterFormat,
|
|
5959
6437
|
frontmatterDelimiters: collection?.frontmatterDelimiters
|
|
@@ -5992,6 +6470,7 @@ var Database = class {
|
|
|
5992
6470
|
SUBLEVEL_OPTIONS
|
|
5993
6471
|
).get(graphqlPath);
|
|
5994
6472
|
};
|
|
6473
|
+
//TODO - is there a reason why the database fetches some config with "bridge.get", and some with "store.get"?
|
|
5995
6474
|
this.getGraphQLSchemaFromBridge = async () => {
|
|
5996
6475
|
if (!this.bridge) {
|
|
5997
6476
|
throw new Error(`No bridge configured`);
|
|
@@ -6038,6 +6517,7 @@ var Database = class {
|
|
|
6038
6517
|
for (const collection of collections) {
|
|
6039
6518
|
const indexDefinitions = {
|
|
6040
6519
|
[DEFAULT_COLLECTION_SORT_KEY]: { fields: [] }
|
|
6520
|
+
// provide a default sort key which is the file sort
|
|
6041
6521
|
};
|
|
6042
6522
|
if (collection.fields) {
|
|
6043
6523
|
for (const field of collection.fields) {
|
|
@@ -6361,12 +6841,12 @@ var Database = class {
|
|
|
6361
6841
|
if (collection?.isDetached) {
|
|
6362
6842
|
level = this.appLevel.sublevel(collection?.name, SUBLEVEL_OPTIONS);
|
|
6363
6843
|
}
|
|
6364
|
-
const
|
|
6844
|
+
const normalizedPath = normalizePath(filepath);
|
|
6365
6845
|
const rootSublevel = level.sublevel(
|
|
6366
6846
|
CONTENT_ROOT_PREFIX,
|
|
6367
6847
|
SUBLEVEL_OPTIONS
|
|
6368
6848
|
);
|
|
6369
|
-
const item = await rootSublevel.get(
|
|
6849
|
+
const item = await rootSublevel.get(normalizedPath);
|
|
6370
6850
|
if (item) {
|
|
6371
6851
|
const folderTreeBuilder = new FolderTreeBuilder();
|
|
6372
6852
|
const folderKey = folderTreeBuilder.update(
|
|
@@ -6375,15 +6855,16 @@ var Database = class {
|
|
|
6375
6855
|
);
|
|
6376
6856
|
await this.contentLevel.batch([
|
|
6377
6857
|
...makeIndexOpsForDocument(
|
|
6378
|
-
|
|
6858
|
+
normalizedPath,
|
|
6379
6859
|
collection.name,
|
|
6380
6860
|
collectionIndexDefinitions,
|
|
6381
6861
|
item,
|
|
6382
6862
|
"del",
|
|
6383
6863
|
level
|
|
6384
6864
|
),
|
|
6865
|
+
// folder indices
|
|
6385
6866
|
...makeIndexOpsForDocument(
|
|
6386
|
-
|
|
6867
|
+
normalizedPath,
|
|
6387
6868
|
`${collection.name}_${folderKey}`,
|
|
6388
6869
|
collectionIndexDefinitions,
|
|
6389
6870
|
item,
|
|
@@ -6392,17 +6873,17 @@ var Database = class {
|
|
|
6392
6873
|
),
|
|
6393
6874
|
{
|
|
6394
6875
|
type: "del",
|
|
6395
|
-
key:
|
|
6876
|
+
key: normalizedPath,
|
|
6396
6877
|
sublevel: rootSublevel
|
|
6397
6878
|
}
|
|
6398
6879
|
]);
|
|
6399
6880
|
}
|
|
6400
6881
|
if (!collection?.isDetached) {
|
|
6401
6882
|
if (this.bridge) {
|
|
6402
|
-
await this.bridge.delete(
|
|
6883
|
+
await this.bridge.delete(normalizedPath);
|
|
6403
6884
|
}
|
|
6404
6885
|
try {
|
|
6405
|
-
await this.onDelete(
|
|
6886
|
+
await this.onDelete(normalizedPath);
|
|
6406
6887
|
} catch (e) {
|
|
6407
6888
|
throw new GraphQLError5(
|
|
6408
6889
|
`Error running onDelete hook for ${filepath}: ${e}`,
|
|
@@ -6536,6 +7017,9 @@ var Database = class {
|
|
|
6536
7017
|
info: templateInfo
|
|
6537
7018
|
};
|
|
6538
7019
|
}
|
|
7020
|
+
/**
|
|
7021
|
+
* Clears the internal cache of the tinaSchema and the lookup file. This allows the state to be reset
|
|
7022
|
+
*/
|
|
6539
7023
|
clearCache() {
|
|
6540
7024
|
this.tinaSchema = null;
|
|
6541
7025
|
this._lookup = null;
|
|
@@ -6632,6 +7116,7 @@ var _indexContent = async (database, level, documentPaths, enqueueOps, collectio
|
|
|
6632
7116
|
"put",
|
|
6633
7117
|
level
|
|
6634
7118
|
),
|
|
7119
|
+
// folder indexes
|
|
6635
7120
|
...makeIndexOpsForDocument(
|
|
6636
7121
|
normalizedPath,
|
|
6637
7122
|
`${collection?.name}_${folderKey}`,
|
|
@@ -6717,6 +7202,7 @@ var _deleteIndexContent = async (database, documentPaths, enqueueOps, collection
|
|
|
6717
7202
|
"del",
|
|
6718
7203
|
database.contentLevel
|
|
6719
7204
|
),
|
|
7205
|
+
// folder indexes
|
|
6720
7206
|
...makeIndexOpsForDocument(
|
|
6721
7207
|
itemKey,
|
|
6722
7208
|
`${collection?.name}_${folderKey}`,
|
|
@@ -6932,17 +7418,26 @@ var IsomorphicBridge = class {
|
|
|
6932
7418
|
getAuthor() {
|
|
6933
7419
|
return {
|
|
6934
7420
|
...this.author,
|
|
6935
|
-
timestamp: Math.round(new Date().getTime() / 1e3),
|
|
7421
|
+
timestamp: Math.round((/* @__PURE__ */ new Date()).getTime() / 1e3),
|
|
6936
7422
|
timezoneOffset: 0
|
|
6937
7423
|
};
|
|
6938
7424
|
}
|
|
6939
7425
|
getCommitter() {
|
|
6940
7426
|
return {
|
|
6941
7427
|
...this.committer,
|
|
6942
|
-
timestamp: Math.round(new Date().getTime() / 1e3),
|
|
7428
|
+
timestamp: Math.round((/* @__PURE__ */ new Date()).getTime() / 1e3),
|
|
6943
7429
|
timezoneOffset: 0
|
|
6944
7430
|
};
|
|
6945
7431
|
}
|
|
7432
|
+
/**
|
|
7433
|
+
* Recursively populate paths matching `pattern` for the given `entry`
|
|
7434
|
+
*
|
|
7435
|
+
* @param pattern - pattern to filter paths by
|
|
7436
|
+
* @param entry - TreeEntry to start building list from
|
|
7437
|
+
* @param path - base path
|
|
7438
|
+
* @param results
|
|
7439
|
+
* @private
|
|
7440
|
+
*/
|
|
6946
7441
|
async listEntries({
|
|
6947
7442
|
pattern,
|
|
6948
7443
|
entry,
|
|
@@ -6975,6 +7470,15 @@ var IsomorphicBridge = class {
|
|
|
6975
7470
|
});
|
|
6976
7471
|
}
|
|
6977
7472
|
}
|
|
7473
|
+
/**
|
|
7474
|
+
* For the specified path, returns an object with an array containing the parts of the path (pathParts)
|
|
7475
|
+
* and an array containing the WalkerEntry objects for the path parts (pathEntries). Any null elements in the
|
|
7476
|
+
* pathEntries are placeholders for non-existent entries.
|
|
7477
|
+
*
|
|
7478
|
+
* @param path - path being resolved
|
|
7479
|
+
* @param ref - ref to resolve path entries for
|
|
7480
|
+
* @private
|
|
7481
|
+
*/
|
|
6978
7482
|
async resolvePathEntries(path7, ref) {
|
|
6979
7483
|
let pathParts = path7.split("/");
|
|
6980
7484
|
const result = await git2.walk({
|
|
@@ -7005,6 +7509,17 @@ var IsomorphicBridge = class {
|
|
|
7005
7509
|
}
|
|
7006
7510
|
return { pathParts, pathEntries };
|
|
7007
7511
|
}
|
|
7512
|
+
/**
|
|
7513
|
+
* Updates tree entry and associated parent tree entries
|
|
7514
|
+
*
|
|
7515
|
+
* @param existingOid - the existing OID
|
|
7516
|
+
* @param updatedOid - the updated OID
|
|
7517
|
+
* @param path - the path of the entry being updated
|
|
7518
|
+
* @param type - the type of the entry being updated (blob or tree)
|
|
7519
|
+
* @param pathEntries - parent path entries
|
|
7520
|
+
* @param pathParts - parent path parts
|
|
7521
|
+
* @private
|
|
7522
|
+
*/
|
|
7008
7523
|
async updateTreeHierarchy(existingOid, updatedOid, path7, type, pathEntries, pathParts) {
|
|
7009
7524
|
const lastIdx = pathEntries.length - 1;
|
|
7010
7525
|
const parentEntry = pathEntries[lastIdx];
|
|
@@ -7060,6 +7575,13 @@ var IsomorphicBridge = class {
|
|
|
7060
7575
|
);
|
|
7061
7576
|
}
|
|
7062
7577
|
}
|
|
7578
|
+
/**
|
|
7579
|
+
* Creates a commit for the specified tree and updates the specified ref to point to the commit
|
|
7580
|
+
*
|
|
7581
|
+
* @param treeSha - sha of the new tree
|
|
7582
|
+
* @param ref - the ref that should be updated
|
|
7583
|
+
* @private
|
|
7584
|
+
*/
|
|
7063
7585
|
async commitTree(treeSha, ref) {
|
|
7064
7586
|
const commitSha = await git2.writeCommit({
|
|
7065
7587
|
...this.isomorphicConfig,
|
|
@@ -7072,6 +7594,7 @@ var IsomorphicBridge = class {
|
|
|
7072
7594
|
})
|
|
7073
7595
|
],
|
|
7074
7596
|
message: this.commitMessage,
|
|
7597
|
+
// TODO these should be configurable
|
|
7075
7598
|
author: this.getAuthor(),
|
|
7076
7599
|
committer: this.getCommitter()
|
|
7077
7600
|
}
|
|
@@ -7309,5 +7832,5 @@ export {
|
|
|
7309
7832
|
transformDocument,
|
|
7310
7833
|
transformDocumentIntoPayload
|
|
7311
7834
|
};
|
|
7312
|
-
//! Replaces _.flattenDeep()
|
|
7313
7835
|
//! Replaces _.get()
|
|
7836
|
+
//! Replaces _.flattenDeep()
|