@tinacms/graphql 1.5.13 → 1.5.14
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/database/datalayer.d.ts +5 -1
- package/dist/database/index.d.ts +2 -0
- package/dist/index.js +304 -108
- package/dist/index.mjs +298 -106
- package/dist/resolver/index.d.ts +12 -1
- package/package.json +5 -5
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
*/
|
|
4
4
|
import { BatchOp, Level } from './level';
|
|
5
|
-
import { Collection } from '@tinacms/schema-tools';
|
|
5
|
+
import type { Collection } from '@tinacms/schema-tools';
|
|
6
6
|
export declare enum OP {
|
|
7
7
|
EQ = "eq",
|
|
8
8
|
GT = "gt",
|
|
@@ -49,6 +49,9 @@ export type FilterCondition = {
|
|
|
49
49
|
};
|
|
50
50
|
type StringEscaper = <T extends string | string[]>(input: T) => T;
|
|
51
51
|
export declare const DEFAULT_COLLECTION_SORT_KEY = "__filepath__";
|
|
52
|
+
export declare const REFS_COLLECTIONS_SORT_KEY = "__refs__";
|
|
53
|
+
export declare const REFS_REFERENCE_FIELD = "__tina_ref__";
|
|
54
|
+
export declare const REFS_PATH_FIELD = "__tina_ref_path__";
|
|
52
55
|
export declare const DEFAULT_NUMERIC_LPAD = 4;
|
|
53
56
|
export declare const coerceFilterChainOperands: (filterChain: (BinaryFilter | TernaryFilter)[], escapeString?: StringEscaper) => (BinaryFilter | TernaryFilter)[];
|
|
54
57
|
export declare const makeFilter: ({ filterChain, }: {
|
|
@@ -71,6 +74,7 @@ export declare class FolderTreeBuilder {
|
|
|
71
74
|
}
|
|
72
75
|
export declare const makeFolderOpsForCollection: <T extends object>(folderTree: FolderTree, collection: Collection<true>, indexDefinitions: Record<string, IndexDefinition>, opType: "put" | "del", level: Level, escapeStr?: StringEscaper) => BatchOp[];
|
|
73
76
|
export declare const makeIndexOpsForDocument: <T extends object>(filepath: string, collection: string | undefined, indexDefinitions: Record<string, IndexDefinition>, data: T, opType: "put" | "del", level: Level, escapeStr?: StringEscaper) => BatchOp[];
|
|
77
|
+
export declare const makeRefOpsForDocument: <T extends object>(filepath: string, collection: string | undefined, references: Record<string, string[]> | undefined | null, data: T, opType: "put" | "del", level: Level) => BatchOp[];
|
|
74
78
|
export declare const makeStringEscaper: (regex: RegExp, replacement: string) => StringEscaper;
|
|
75
79
|
export declare const stringEscaper: StringEscaper;
|
|
76
80
|
export {};
|
package/dist/database/index.d.ts
CHANGED
|
@@ -72,6 +72,7 @@ export declare class Database {
|
|
|
72
72
|
private tinaSchema;
|
|
73
73
|
private contentNamespace;
|
|
74
74
|
private collectionIndexDefinitions;
|
|
75
|
+
private collectionReferences;
|
|
75
76
|
private _lookup;
|
|
76
77
|
constructor(config: DatabaseArgs);
|
|
77
78
|
private collectionForPath;
|
|
@@ -125,6 +126,7 @@ export declare class Database {
|
|
|
125
126
|
getGraphQLSchemaFromBridge: () => Promise<DocumentNode>;
|
|
126
127
|
getTinaSchema: (level?: Level) => Promise<Schema>;
|
|
127
128
|
getSchema: (level?: Level, existingSchema?: Schema) => Promise<TinaSchema>;
|
|
129
|
+
getCollectionReferences: (level?: Level) => Promise<Record<string, Record<string, string[]>>>;
|
|
128
130
|
getIndexDefinitions: (level?: Level) => Promise<Record<string, Record<string, IndexDefinition>>>;
|
|
129
131
|
documentExists: (fullpath: unknown) => Promise<boolean>;
|
|
130
132
|
query: (queryOptions: QueryOptions, hydrator: any) => Promise<{
|
package/dist/index.js
CHANGED
|
@@ -3090,7 +3090,7 @@ var validateField = async (field) => {
|
|
|
3090
3090
|
// package.json
|
|
3091
3091
|
var package_default = {
|
|
3092
3092
|
name: "@tinacms/graphql",
|
|
3093
|
-
version: "1.5.
|
|
3093
|
+
version: "1.5.14",
|
|
3094
3094
|
main: "dist/index.js",
|
|
3095
3095
|
module: "dist/index.mjs",
|
|
3096
3096
|
typings: "dist/index.d.ts",
|
|
@@ -4035,6 +4035,9 @@ var loadAndParseWithAliases = async (bridge, filepath, collection, templateInfo)
|
|
|
4035
4035
|
|
|
4036
4036
|
// src/database/datalayer.ts
|
|
4037
4037
|
var DEFAULT_COLLECTION_SORT_KEY = "__filepath__";
|
|
4038
|
+
var REFS_COLLECTIONS_SORT_KEY = "__refs__";
|
|
4039
|
+
var REFS_REFERENCE_FIELD = "__tina_ref__";
|
|
4040
|
+
var REFS_PATH_FIELD = "__tina_ref_path__";
|
|
4038
4041
|
var DEFAULT_NUMERIC_LPAD = 4;
|
|
4039
4042
|
var applyPadding = (input, pad) => {
|
|
4040
4043
|
if (pad) {
|
|
@@ -4608,6 +4611,57 @@ var makeIndexOpsForDocument = (filepath, collection, indexDefinitions, data, opT
|
|
|
4608
4611
|
}
|
|
4609
4612
|
return result;
|
|
4610
4613
|
};
|
|
4614
|
+
var makeRefOpsForDocument = (filepath, collection, references, data, opType, level) => {
|
|
4615
|
+
const result = [];
|
|
4616
|
+
if (collection) {
|
|
4617
|
+
for (const [c, referencePaths] of Object.entries(references || {})) {
|
|
4618
|
+
if (!referencePaths.length) {
|
|
4619
|
+
continue;
|
|
4620
|
+
}
|
|
4621
|
+
const collectionSublevel = level.sublevel(c, SUBLEVEL_OPTIONS);
|
|
4622
|
+
const refSublevel = collectionSublevel.sublevel(
|
|
4623
|
+
REFS_COLLECTIONS_SORT_KEY,
|
|
4624
|
+
SUBLEVEL_OPTIONS
|
|
4625
|
+
);
|
|
4626
|
+
const references2 = {};
|
|
4627
|
+
for (const path7 of referencePaths) {
|
|
4628
|
+
const ref = (0, import_jsonpath_plus.JSONPath)({ path: path7, json: data });
|
|
4629
|
+
if (!ref) {
|
|
4630
|
+
continue;
|
|
4631
|
+
}
|
|
4632
|
+
if (Array.isArray(ref)) {
|
|
4633
|
+
for (const r of ref) {
|
|
4634
|
+
if (!r) {
|
|
4635
|
+
continue;
|
|
4636
|
+
}
|
|
4637
|
+
if (references2[r]) {
|
|
4638
|
+
references2[r].push(path7);
|
|
4639
|
+
} else {
|
|
4640
|
+
references2[r] = [path7];
|
|
4641
|
+
}
|
|
4642
|
+
}
|
|
4643
|
+
} else {
|
|
4644
|
+
if (references2[ref]) {
|
|
4645
|
+
references2[ref].push(path7);
|
|
4646
|
+
} else {
|
|
4647
|
+
references2[ref] = [path7];
|
|
4648
|
+
}
|
|
4649
|
+
}
|
|
4650
|
+
}
|
|
4651
|
+
for (const ref of Object.keys(references2)) {
|
|
4652
|
+
for (const path7 of references2[ref]) {
|
|
4653
|
+
result.push({
|
|
4654
|
+
type: opType,
|
|
4655
|
+
key: `${ref}${INDEX_KEY_FIELD_SEPARATOR}${path7}${INDEX_KEY_FIELD_SEPARATOR}${filepath}`,
|
|
4656
|
+
sublevel: refSublevel,
|
|
4657
|
+
value: opType === "put" ? {} : void 0
|
|
4658
|
+
});
|
|
4659
|
+
}
|
|
4660
|
+
}
|
|
4661
|
+
}
|
|
4662
|
+
}
|
|
4663
|
+
return result;
|
|
4664
|
+
};
|
|
4611
4665
|
var makeStringEscaper = (regex, replacement) => {
|
|
4612
4666
|
return (input) => {
|
|
4613
4667
|
if (Array.isArray(input)) {
|
|
@@ -4829,24 +4883,29 @@ var transformDocumentIntoPayload = async (fullPath, rawData, tinaSchema, config,
|
|
|
4829
4883
|
throw e;
|
|
4830
4884
|
}
|
|
4831
4885
|
};
|
|
4832
|
-
var updateObjectWithJsonPath = (obj, path7, newValue) => {
|
|
4886
|
+
var updateObjectWithJsonPath = (obj, path7, oldValue, newValue) => {
|
|
4887
|
+
let updated = false;
|
|
4833
4888
|
if (!path7.includes(".") && !path7.includes("[")) {
|
|
4834
|
-
if (path7 in obj) {
|
|
4889
|
+
if (path7 in obj && obj[path7] === oldValue) {
|
|
4835
4890
|
obj[path7] = newValue;
|
|
4891
|
+
updated = true;
|
|
4836
4892
|
}
|
|
4837
|
-
return obj;
|
|
4893
|
+
return { object: obj, updated };
|
|
4838
4894
|
}
|
|
4839
|
-
const parentPath = path7.replace(/\.[
|
|
4840
|
-
const keyToUpdate = path7.match(/[
|
|
4895
|
+
const parentPath = path7.replace(/\.[^.\[\]]+$/, "");
|
|
4896
|
+
const keyToUpdate = path7.match(/[^.\[\]]+$/)[0];
|
|
4841
4897
|
const parents = (0, import_jsonpath_plus2.JSONPath)({ path: parentPath, json: obj, resultType: "value" });
|
|
4842
4898
|
if (parents.length > 0) {
|
|
4843
4899
|
parents.forEach((parent) => {
|
|
4844
4900
|
if (parent && typeof parent === "object" && keyToUpdate in parent) {
|
|
4845
|
-
parent[keyToUpdate]
|
|
4901
|
+
if (parent[keyToUpdate] === oldValue) {
|
|
4902
|
+
parent[keyToUpdate] = newValue;
|
|
4903
|
+
updated = true;
|
|
4904
|
+
}
|
|
4846
4905
|
}
|
|
4847
4906
|
});
|
|
4848
4907
|
}
|
|
4849
|
-
return obj;
|
|
4908
|
+
return { object: obj, updated };
|
|
4850
4909
|
};
|
|
4851
4910
|
var Resolver = class {
|
|
4852
4911
|
constructor(init) {
|
|
@@ -5225,17 +5284,35 @@ var Resolver = class {
|
|
|
5225
5284
|
await this.deleteDocument(realPath);
|
|
5226
5285
|
if (await this.hasReferences(realPath, collection)) {
|
|
5227
5286
|
const collRefs = await this.findReferences(realPath, collection);
|
|
5228
|
-
for (const [collection2,
|
|
5229
|
-
for (const [
|
|
5230
|
-
|
|
5231
|
-
|
|
5232
|
-
|
|
5287
|
+
for (const [collection2, docsWithRefs] of Object.entries(collRefs)) {
|
|
5288
|
+
for (const [pathToDocWithRef, referencePaths] of Object.entries(
|
|
5289
|
+
docsWithRefs
|
|
5290
|
+
)) {
|
|
5291
|
+
let refDoc = await this.getRaw(pathToDocWithRef);
|
|
5292
|
+
let hasUpdate = false;
|
|
5293
|
+
for (const path7 of referencePaths) {
|
|
5294
|
+
const { object: object2, updated } = updateObjectWithJsonPath(
|
|
5233
5295
|
refDoc,
|
|
5234
|
-
|
|
5296
|
+
path7,
|
|
5297
|
+
realPath,
|
|
5235
5298
|
null
|
|
5236
5299
|
);
|
|
5300
|
+
refDoc = object2;
|
|
5301
|
+
hasUpdate = updated || hasUpdate;
|
|
5302
|
+
}
|
|
5303
|
+
if (hasUpdate) {
|
|
5304
|
+
const collectionWithRef = this.tinaSchema.getCollectionByFullPath(pathToDocWithRef);
|
|
5305
|
+
if (!collectionWithRef) {
|
|
5306
|
+
throw new Error(
|
|
5307
|
+
`Unable to find collection for ${pathToDocWithRef}`
|
|
5308
|
+
);
|
|
5309
|
+
}
|
|
5310
|
+
await this.database.put(
|
|
5311
|
+
pathToDocWithRef,
|
|
5312
|
+
refDoc,
|
|
5313
|
+
collectionWithRef.name
|
|
5314
|
+
);
|
|
5237
5315
|
}
|
|
5238
|
-
await this.database.put(refPath, refDoc, collection2);
|
|
5239
5316
|
}
|
|
5240
5317
|
}
|
|
5241
5318
|
}
|
|
@@ -5261,17 +5338,35 @@ var Resolver = class {
|
|
|
5261
5338
|
await this.database.put(newRealPath, doc._rawData, collection.name);
|
|
5262
5339
|
await this.deleteDocument(realPath);
|
|
5263
5340
|
const collRefs = await this.findReferences(realPath, collection);
|
|
5264
|
-
for (const [collection2,
|
|
5265
|
-
for (const [
|
|
5266
|
-
|
|
5267
|
-
|
|
5268
|
-
|
|
5269
|
-
|
|
5270
|
-
|
|
5341
|
+
for (const [collection2, docsWithRefs] of Object.entries(collRefs)) {
|
|
5342
|
+
for (const [pathToDocWithRef, referencePaths] of Object.entries(
|
|
5343
|
+
docsWithRefs
|
|
5344
|
+
)) {
|
|
5345
|
+
let docWithRef = await this.getRaw(pathToDocWithRef);
|
|
5346
|
+
let hasUpdate = false;
|
|
5347
|
+
for (const path7 of referencePaths) {
|
|
5348
|
+
const { object: object2, updated } = updateObjectWithJsonPath(
|
|
5349
|
+
docWithRef,
|
|
5350
|
+
path7,
|
|
5351
|
+
realPath,
|
|
5271
5352
|
newRealPath
|
|
5272
5353
|
);
|
|
5354
|
+
docWithRef = object2;
|
|
5355
|
+
hasUpdate = updated || hasUpdate;
|
|
5356
|
+
}
|
|
5357
|
+
if (hasUpdate) {
|
|
5358
|
+
const collectionWithRef = this.tinaSchema.getCollectionByFullPath(pathToDocWithRef);
|
|
5359
|
+
if (!collectionWithRef) {
|
|
5360
|
+
throw new Error(
|
|
5361
|
+
`Unable to find collection for ${pathToDocWithRef}`
|
|
5362
|
+
);
|
|
5363
|
+
}
|
|
5364
|
+
await this.database.put(
|
|
5365
|
+
pathToDocWithRef,
|
|
5366
|
+
docWithRef,
|
|
5367
|
+
collectionWithRef.name
|
|
5368
|
+
);
|
|
5273
5369
|
}
|
|
5274
|
-
await this.database.put(refPath, refDoc, collection2);
|
|
5275
5370
|
}
|
|
5276
5371
|
}
|
|
5277
5372
|
return this.getDocument(newRealPath);
|
|
@@ -5403,35 +5498,30 @@ var Resolver = class {
|
|
|
5403
5498
|
*/
|
|
5404
5499
|
this.hasReferences = async (id, c) => {
|
|
5405
5500
|
let count = 0;
|
|
5406
|
-
|
|
5407
|
-
|
|
5408
|
-
|
|
5409
|
-
|
|
5410
|
-
|
|
5411
|
-
|
|
5412
|
-
|
|
5413
|
-
|
|
5414
|
-
|
|
5415
|
-
|
|
5416
|
-
|
|
5417
|
-
|
|
5418
|
-
|
|
5419
|
-
|
|
5420
|
-
|
|
5421
|
-
|
|
5422
|
-
|
|
5423
|
-
|
|
5424
|
-
|
|
5425
|
-
|
|
5426
|
-
(refId) => {
|
|
5427
|
-
count++;
|
|
5428
|
-
return refId;
|
|
5429
|
-
}
|
|
5430
|
-
);
|
|
5431
|
-
if (count) {
|
|
5432
|
-
return true;
|
|
5433
|
-
}
|
|
5501
|
+
await this.database.query(
|
|
5502
|
+
{
|
|
5503
|
+
collection: c.name,
|
|
5504
|
+
filterChain: makeFilterChain({
|
|
5505
|
+
conditions: [
|
|
5506
|
+
{
|
|
5507
|
+
filterPath: REFS_REFERENCE_FIELD,
|
|
5508
|
+
filterExpression: {
|
|
5509
|
+
_type: "string",
|
|
5510
|
+
_list: false,
|
|
5511
|
+
eq: id
|
|
5512
|
+
}
|
|
5513
|
+
}
|
|
5514
|
+
]
|
|
5515
|
+
}),
|
|
5516
|
+
sort: REFS_COLLECTIONS_SORT_KEY
|
|
5517
|
+
},
|
|
5518
|
+
(refId) => {
|
|
5519
|
+
count++;
|
|
5520
|
+
return refId;
|
|
5434
5521
|
}
|
|
5522
|
+
);
|
|
5523
|
+
if (count) {
|
|
5524
|
+
return true;
|
|
5435
5525
|
}
|
|
5436
5526
|
return false;
|
|
5437
5527
|
};
|
|
@@ -5439,46 +5529,41 @@ var Resolver = class {
|
|
|
5439
5529
|
* Finds references to a document
|
|
5440
5530
|
* @param id the id of the document to find references to
|
|
5441
5531
|
* @param c the collection to find references in
|
|
5442
|
-
* @returns
|
|
5532
|
+
* @returns a map of references to the document
|
|
5443
5533
|
*/
|
|
5444
5534
|
this.findReferences = async (id, c) => {
|
|
5445
5535
|
const references = {};
|
|
5446
|
-
|
|
5447
|
-
|
|
5448
|
-
|
|
5449
|
-
|
|
5450
|
-
|
|
5451
|
-
|
|
5452
|
-
|
|
5453
|
-
|
|
5454
|
-
|
|
5455
|
-
|
|
5456
|
-
|
|
5457
|
-
|
|
5458
|
-
_list: false,
|
|
5459
|
-
eq: id
|
|
5460
|
-
}
|
|
5461
|
-
}
|
|
5462
|
-
]
|
|
5463
|
-
}),
|
|
5464
|
-
sort: ref.field.name
|
|
5465
|
-
},
|
|
5466
|
-
(refId) => {
|
|
5467
|
-
if (!references[collection]) {
|
|
5468
|
-
references[collection] = {};
|
|
5469
|
-
}
|
|
5470
|
-
if (!references[collection][refId]) {
|
|
5471
|
-
references[collection][refId] = [];
|
|
5536
|
+
await this.database.query(
|
|
5537
|
+
{
|
|
5538
|
+
collection: c.name,
|
|
5539
|
+
filterChain: makeFilterChain({
|
|
5540
|
+
conditions: [
|
|
5541
|
+
{
|
|
5542
|
+
filterPath: REFS_REFERENCE_FIELD,
|
|
5543
|
+
filterExpression: {
|
|
5544
|
+
_type: "string",
|
|
5545
|
+
_list: false,
|
|
5546
|
+
eq: id
|
|
5547
|
+
}
|
|
5472
5548
|
}
|
|
5473
|
-
|
|
5474
|
-
|
|
5475
|
-
|
|
5476
|
-
|
|
5477
|
-
|
|
5478
|
-
|
|
5479
|
-
|
|
5549
|
+
]
|
|
5550
|
+
}),
|
|
5551
|
+
sort: REFS_COLLECTIONS_SORT_KEY
|
|
5552
|
+
},
|
|
5553
|
+
(refId, rawItem) => {
|
|
5554
|
+
if (!references[c.name]) {
|
|
5555
|
+
references[c.name] = {};
|
|
5556
|
+
}
|
|
5557
|
+
if (!references[c.name][refId]) {
|
|
5558
|
+
references[c.name][refId] = [];
|
|
5559
|
+
}
|
|
5560
|
+
const referencePath = rawItem == null ? void 0 : rawItem[REFS_PATH_FIELD];
|
|
5561
|
+
if (referencePath) {
|
|
5562
|
+
references[c.name][refId].push(referencePath);
|
|
5563
|
+
}
|
|
5564
|
+
return refId;
|
|
5480
5565
|
}
|
|
5481
|
-
|
|
5566
|
+
);
|
|
5482
5567
|
return references;
|
|
5483
5568
|
};
|
|
5484
5569
|
this.buildFieldMutations = async (fieldParams, template, existingData) => {
|
|
@@ -6214,6 +6299,7 @@ var Database = class {
|
|
|
6214
6299
|
}
|
|
6215
6300
|
};
|
|
6216
6301
|
this.addPendingDocument = async (filepath, data) => {
|
|
6302
|
+
var _a;
|
|
6217
6303
|
await this.initLevel();
|
|
6218
6304
|
const dataFields = await this.formatBodyOnPayload(filepath, data);
|
|
6219
6305
|
const collection = await this.collectionForPath(filepath);
|
|
@@ -6227,6 +6313,7 @@ var Database = class {
|
|
|
6227
6313
|
);
|
|
6228
6314
|
const indexDefinitions = await this.getIndexDefinitions(this.contentLevel);
|
|
6229
6315
|
const collectionIndexDefinitions = indexDefinitions == null ? void 0 : indexDefinitions[collection.name];
|
|
6316
|
+
const collectionReferences = (_a = await this.getCollectionReferences()) == null ? void 0 : _a[collection.name];
|
|
6230
6317
|
const normalizedPath = (0, import_schema_tools4.normalizePath)(filepath);
|
|
6231
6318
|
if (!(collection == null ? void 0 : collection.isDetached)) {
|
|
6232
6319
|
if (this.bridge) {
|
|
@@ -6255,6 +6342,14 @@ var Database = class {
|
|
|
6255
6342
|
let delOps = [];
|
|
6256
6343
|
if (!isGitKeep(normalizedPath, collection)) {
|
|
6257
6344
|
putOps = [
|
|
6345
|
+
...makeRefOpsForDocument(
|
|
6346
|
+
normalizedPath,
|
|
6347
|
+
collection == null ? void 0 : collection.name,
|
|
6348
|
+
collectionReferences,
|
|
6349
|
+
dataFields,
|
|
6350
|
+
"put",
|
|
6351
|
+
level
|
|
6352
|
+
),
|
|
6258
6353
|
...makeIndexOpsForDocument(
|
|
6259
6354
|
normalizedPath,
|
|
6260
6355
|
collection == null ? void 0 : collection.name,
|
|
@@ -6278,6 +6373,14 @@ var Database = class {
|
|
|
6278
6373
|
SUBLEVEL_OPTIONS
|
|
6279
6374
|
).get(normalizedPath);
|
|
6280
6375
|
delOps = existingItem ? [
|
|
6376
|
+
...makeRefOpsForDocument(
|
|
6377
|
+
normalizedPath,
|
|
6378
|
+
collection == null ? void 0 : collection.name,
|
|
6379
|
+
collectionReferences,
|
|
6380
|
+
existingItem,
|
|
6381
|
+
"del",
|
|
6382
|
+
level
|
|
6383
|
+
),
|
|
6281
6384
|
...makeIndexOpsForDocument(
|
|
6282
6385
|
normalizedPath,
|
|
6283
6386
|
collection == null ? void 0 : collection.name,
|
|
@@ -6313,7 +6416,7 @@ var Database = class {
|
|
|
6313
6416
|
await level.batch(ops);
|
|
6314
6417
|
};
|
|
6315
6418
|
this.put = async (filepath, data, collectionName) => {
|
|
6316
|
-
var _a, _b;
|
|
6419
|
+
var _a, _b, _c;
|
|
6317
6420
|
await this.initLevel();
|
|
6318
6421
|
try {
|
|
6319
6422
|
if (SYSTEM_FILES.includes(filepath)) {
|
|
@@ -6326,13 +6429,14 @@ var Database = class {
|
|
|
6326
6429
|
);
|
|
6327
6430
|
collectionIndexDefinitions = indexDefinitions == null ? void 0 : indexDefinitions[collectionName];
|
|
6328
6431
|
}
|
|
6432
|
+
const collectionReferences = (_a = await this.getCollectionReferences()) == null ? void 0 : _a[collectionName];
|
|
6329
6433
|
const normalizedPath = (0, import_schema_tools4.normalizePath)(filepath);
|
|
6330
6434
|
const dataFields = await this.formatBodyOnPayload(filepath, data);
|
|
6331
6435
|
const collection = await this.collectionForPath(filepath);
|
|
6332
6436
|
if (!collection) {
|
|
6333
6437
|
throw new import_graphql6.GraphQLError(`Unable to find collection for ${filepath}.`);
|
|
6334
6438
|
}
|
|
6335
|
-
if (((
|
|
6439
|
+
if (((_b = collection.match) == null ? void 0 : _b.exclude) || ((_c = collection.match) == null ? void 0 : _c.include)) {
|
|
6336
6440
|
const matches = this.tinaSchema.getMatches({ collection });
|
|
6337
6441
|
const match = import_micromatch2.default.isMatch(filepath, matches);
|
|
6338
6442
|
if (!match) {
|
|
@@ -6373,6 +6477,14 @@ var Database = class {
|
|
|
6373
6477
|
let delOps = [];
|
|
6374
6478
|
if (!isGitKeep(normalizedPath, collection)) {
|
|
6375
6479
|
putOps = [
|
|
6480
|
+
...makeRefOpsForDocument(
|
|
6481
|
+
normalizedPath,
|
|
6482
|
+
collectionName,
|
|
6483
|
+
collectionReferences,
|
|
6484
|
+
dataFields,
|
|
6485
|
+
"put",
|
|
6486
|
+
level
|
|
6487
|
+
),
|
|
6376
6488
|
...makeIndexOpsForDocument(
|
|
6377
6489
|
normalizedPath,
|
|
6378
6490
|
collectionName,
|
|
@@ -6396,6 +6508,14 @@ var Database = class {
|
|
|
6396
6508
|
SUBLEVEL_OPTIONS
|
|
6397
6509
|
).get(normalizedPath);
|
|
6398
6510
|
delOps = existingItem ? [
|
|
6511
|
+
...makeRefOpsForDocument(
|
|
6512
|
+
normalizedPath,
|
|
6513
|
+
collectionName,
|
|
6514
|
+
collectionReferences,
|
|
6515
|
+
existingItem,
|
|
6516
|
+
"del",
|
|
6517
|
+
level
|
|
6518
|
+
),
|
|
6399
6519
|
...makeIndexOpsForDocument(
|
|
6400
6520
|
normalizedPath,
|
|
6401
6521
|
collectionName,
|
|
@@ -6558,6 +6678,22 @@ var Database = class {
|
|
|
6558
6678
|
this.tinaSchema = await createSchema({ schema });
|
|
6559
6679
|
return this.tinaSchema;
|
|
6560
6680
|
};
|
|
6681
|
+
this.getCollectionReferences = async (level) => {
|
|
6682
|
+
if (this.collectionReferences) {
|
|
6683
|
+
return this.collectionReferences;
|
|
6684
|
+
}
|
|
6685
|
+
const result = {};
|
|
6686
|
+
const schema = await this.getSchema(level || this.contentLevel);
|
|
6687
|
+
const collections = schema.getCollections();
|
|
6688
|
+
for (const collection of collections) {
|
|
6689
|
+
const collectionReferences = this.tinaSchema.findReferencesFromCollection(
|
|
6690
|
+
collection.name
|
|
6691
|
+
);
|
|
6692
|
+
result[collection.name] = collectionReferences;
|
|
6693
|
+
}
|
|
6694
|
+
this.collectionReferences = result;
|
|
6695
|
+
return result;
|
|
6696
|
+
};
|
|
6561
6697
|
this.getIndexDefinitions = async (level) => {
|
|
6562
6698
|
if (!this.collectionIndexDefinitions) {
|
|
6563
6699
|
await new Promise(async (resolve2, reject) => {
|
|
@@ -6567,8 +6703,23 @@ var Database = class {
|
|
|
6567
6703
|
const collections = schema.getCollections();
|
|
6568
6704
|
for (const collection of collections) {
|
|
6569
6705
|
const indexDefinitions = {
|
|
6570
|
-
[DEFAULT_COLLECTION_SORT_KEY]: { fields: [] }
|
|
6706
|
+
[DEFAULT_COLLECTION_SORT_KEY]: { fields: [] },
|
|
6571
6707
|
// provide a default sort key which is the file sort
|
|
6708
|
+
// pseudo-index for the collection's references
|
|
6709
|
+
[REFS_COLLECTIONS_SORT_KEY]: {
|
|
6710
|
+
fields: [
|
|
6711
|
+
{
|
|
6712
|
+
name: REFS_REFERENCE_FIELD,
|
|
6713
|
+
type: "string",
|
|
6714
|
+
list: false
|
|
6715
|
+
},
|
|
6716
|
+
{
|
|
6717
|
+
name: REFS_PATH_FIELD,
|
|
6718
|
+
type: "string",
|
|
6719
|
+
list: false
|
|
6720
|
+
}
|
|
6721
|
+
]
|
|
6722
|
+
}
|
|
6572
6723
|
};
|
|
6573
6724
|
if (collection.fields) {
|
|
6574
6725
|
for (const field of collection.fields) {
|
|
@@ -6720,29 +6871,36 @@ var Database = class {
|
|
|
6720
6871
|
}
|
|
6721
6872
|
startKey = startKey || key || "";
|
|
6722
6873
|
endKey = key || "";
|
|
6723
|
-
edges = [...edges, { cursor: key, path: filepath }];
|
|
6874
|
+
edges = [...edges, { cursor: key, path: filepath, value: itemRecord }];
|
|
6724
6875
|
}
|
|
6725
6876
|
return {
|
|
6726
|
-
edges: await sequential(
|
|
6727
|
-
|
|
6728
|
-
|
|
6729
|
-
|
|
6730
|
-
|
|
6731
|
-
|
|
6732
|
-
|
|
6733
|
-
|
|
6734
|
-
|
|
6735
|
-
|
|
6736
|
-
|
|
6737
|
-
|
|
6738
|
-
|
|
6739
|
-
|
|
6740
|
-
|
|
6741
|
-
|
|
6877
|
+
edges: await sequential(
|
|
6878
|
+
edges,
|
|
6879
|
+
async ({
|
|
6880
|
+
cursor,
|
|
6881
|
+
path: path7,
|
|
6882
|
+
value
|
|
6883
|
+
}) => {
|
|
6884
|
+
try {
|
|
6885
|
+
const node = await hydrator(path7, value);
|
|
6886
|
+
return {
|
|
6887
|
+
node,
|
|
6888
|
+
cursor: btoa(cursor)
|
|
6889
|
+
};
|
|
6890
|
+
} catch (error) {
|
|
6891
|
+
console.log(error);
|
|
6892
|
+
if (error instanceof Error && (!path7.includes(".tina/__generated__/_graphql.json") || !path7.includes("tina/__generated__/_graphql.json"))) {
|
|
6893
|
+
throw new TinaQueryError({
|
|
6894
|
+
originalError: error,
|
|
6895
|
+
file: path7,
|
|
6896
|
+
collection: collection.name,
|
|
6897
|
+
stack: error.stack
|
|
6898
|
+
});
|
|
6899
|
+
}
|
|
6900
|
+
throw error;
|
|
6742
6901
|
}
|
|
6743
|
-
throw error;
|
|
6744
6902
|
}
|
|
6745
|
-
|
|
6903
|
+
),
|
|
6746
6904
|
pageInfo: {
|
|
6747
6905
|
hasPreviousPage,
|
|
6748
6906
|
hasNextPage,
|
|
@@ -6882,12 +7040,14 @@ var Database = class {
|
|
|
6882
7040
|
}
|
|
6883
7041
|
};
|
|
6884
7042
|
this.delete = async (filepath) => {
|
|
7043
|
+
var _a;
|
|
6885
7044
|
await this.initLevel();
|
|
6886
7045
|
const collection = await this.collectionForPath(filepath);
|
|
6887
7046
|
if (!collection) {
|
|
6888
7047
|
throw new Error(`No collection found for path: ${filepath}`);
|
|
6889
7048
|
}
|
|
6890
7049
|
const indexDefinitions = await this.getIndexDefinitions(this.contentLevel);
|
|
7050
|
+
const collectionReferences = (_a = await this.getCollectionReferences()) == null ? void 0 : _a[collection.name];
|
|
6891
7051
|
const collectionIndexDefinitions = indexDefinitions == null ? void 0 : indexDefinitions[collection.name];
|
|
6892
7052
|
let level = this.contentLevel;
|
|
6893
7053
|
if (collection == null ? void 0 : collection.isDetached) {
|
|
@@ -6906,6 +7066,14 @@ var Database = class {
|
|
|
6906
7066
|
collection.path || ""
|
|
6907
7067
|
);
|
|
6908
7068
|
await this.contentLevel.batch([
|
|
7069
|
+
...makeRefOpsForDocument(
|
|
7070
|
+
normalizedPath,
|
|
7071
|
+
collection.name,
|
|
7072
|
+
collectionReferences,
|
|
7073
|
+
item,
|
|
7074
|
+
"del",
|
|
7075
|
+
level
|
|
7076
|
+
),
|
|
6909
7077
|
...makeIndexOpsForDocument(
|
|
6910
7078
|
normalizedPath,
|
|
6911
7079
|
collection.name,
|
|
@@ -7123,6 +7291,7 @@ var hashPasswordValues = async (data, passwordFields) => Promise.all(
|
|
|
7123
7291
|
);
|
|
7124
7292
|
var isGitKeep = (filepath, collection) => filepath.endsWith(`.gitkeep.${(collection == null ? void 0 : collection.format) || "md"}`);
|
|
7125
7293
|
var _indexContent = async (database, level, documentPaths, enqueueOps, collection, passwordFields) => {
|
|
7294
|
+
var _a;
|
|
7126
7295
|
let collectionIndexDefinitions;
|
|
7127
7296
|
let collectionPath;
|
|
7128
7297
|
if (collection) {
|
|
@@ -7133,6 +7302,7 @@ var _indexContent = async (database, level, documentPaths, enqueueOps, collectio
|
|
|
7133
7302
|
}
|
|
7134
7303
|
collectionPath = collection.path;
|
|
7135
7304
|
}
|
|
7305
|
+
const collectionReferences = (_a = await database.getCollectionReferences()) == null ? void 0 : _a[collection == null ? void 0 : collection.name];
|
|
7136
7306
|
const tinaSchema = await database.getSchema();
|
|
7137
7307
|
let templateInfo = null;
|
|
7138
7308
|
if (collection) {
|
|
@@ -7165,6 +7335,14 @@ var _indexContent = async (database, level, documentPaths, enqueueOps, collectio
|
|
|
7165
7335
|
const item = await rootSublevel.get(normalizedPath);
|
|
7166
7336
|
if (item) {
|
|
7167
7337
|
await database.contentLevel.batch([
|
|
7338
|
+
...makeRefOpsForDocument(
|
|
7339
|
+
normalizedPath,
|
|
7340
|
+
collection == null ? void 0 : collection.name,
|
|
7341
|
+
collectionReferences,
|
|
7342
|
+
item,
|
|
7343
|
+
"del",
|
|
7344
|
+
level
|
|
7345
|
+
),
|
|
7168
7346
|
...makeIndexOpsForDocument(
|
|
7169
7347
|
normalizedPath,
|
|
7170
7348
|
collection.name,
|
|
@@ -7191,6 +7369,14 @@ var _indexContent = async (database, level, documentPaths, enqueueOps, collectio
|
|
|
7191
7369
|
}
|
|
7192
7370
|
if (!isGitKeep(filepath, collection)) {
|
|
7193
7371
|
await enqueueOps([
|
|
7372
|
+
...makeRefOpsForDocument(
|
|
7373
|
+
normalizedPath,
|
|
7374
|
+
collection == null ? void 0 : collection.name,
|
|
7375
|
+
collectionReferences,
|
|
7376
|
+
aliasedData,
|
|
7377
|
+
"put",
|
|
7378
|
+
level
|
|
7379
|
+
),
|
|
7194
7380
|
...makeIndexOpsForDocument(
|
|
7195
7381
|
normalizedPath,
|
|
7196
7382
|
collection == null ? void 0 : collection.name,
|
|
@@ -7241,6 +7427,7 @@ var _indexContent = async (database, level, documentPaths, enqueueOps, collectio
|
|
|
7241
7427
|
}
|
|
7242
7428
|
};
|
|
7243
7429
|
var _deleteIndexContent = async (database, documentPaths, enqueueOps, collection) => {
|
|
7430
|
+
var _a;
|
|
7244
7431
|
if (!documentPaths.length) {
|
|
7245
7432
|
return;
|
|
7246
7433
|
}
|
|
@@ -7254,6 +7441,7 @@ var _deleteIndexContent = async (database, documentPaths, enqueueOps, collection
|
|
|
7254
7441
|
throw new Error(`No indexDefinitions for collection ${collection.name}`);
|
|
7255
7442
|
}
|
|
7256
7443
|
}
|
|
7444
|
+
const collectionReferences = (_a = await database.getCollectionReferences()) == null ? void 0 : _a[collection == null ? void 0 : collection.name];
|
|
7257
7445
|
const tinaSchema = await database.getSchema();
|
|
7258
7446
|
let templateInfo = null;
|
|
7259
7447
|
if (collection) {
|
|
@@ -7277,6 +7465,14 @@ var _deleteIndexContent = async (database, documentPaths, enqueueOps, collection
|
|
|
7277
7465
|
item
|
|
7278
7466
|
) : item;
|
|
7279
7467
|
await enqueueOps([
|
|
7468
|
+
...makeRefOpsForDocument(
|
|
7469
|
+
itemKey,
|
|
7470
|
+
collection == null ? void 0 : collection.name,
|
|
7471
|
+
collectionReferences,
|
|
7472
|
+
aliasedData,
|
|
7473
|
+
"del",
|
|
7474
|
+
database.contentLevel
|
|
7475
|
+
),
|
|
7280
7476
|
...makeIndexOpsForDocument(
|
|
7281
7477
|
itemKey,
|
|
7282
7478
|
collection.name,
|
package/dist/index.mjs
CHANGED
|
@@ -3019,7 +3019,7 @@ var validateField = async (field) => {
|
|
|
3019
3019
|
// package.json
|
|
3020
3020
|
var package_default = {
|
|
3021
3021
|
name: "@tinacms/graphql",
|
|
3022
|
-
version: "1.5.
|
|
3022
|
+
version: "1.5.14",
|
|
3023
3023
|
main: "dist/index.js",
|
|
3024
3024
|
module: "dist/index.mjs",
|
|
3025
3025
|
typings: "dist/index.d.ts",
|
|
@@ -3960,6 +3960,9 @@ var loadAndParseWithAliases = async (bridge, filepath, collection, templateInfo)
|
|
|
3960
3960
|
|
|
3961
3961
|
// src/database/datalayer.ts
|
|
3962
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__";
|
|
3963
3966
|
var DEFAULT_NUMERIC_LPAD = 4;
|
|
3964
3967
|
var applyPadding = (input, pad) => {
|
|
3965
3968
|
if (pad) {
|
|
@@ -4533,6 +4536,57 @@ var makeIndexOpsForDocument = (filepath, collection, indexDefinitions, data, opT
|
|
|
4533
4536
|
}
|
|
4534
4537
|
return result;
|
|
4535
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 (!ref) {
|
|
4555
|
+
continue;
|
|
4556
|
+
}
|
|
4557
|
+
if (Array.isArray(ref)) {
|
|
4558
|
+
for (const r of ref) {
|
|
4559
|
+
if (!r) {
|
|
4560
|
+
continue;
|
|
4561
|
+
}
|
|
4562
|
+
if (references2[r]) {
|
|
4563
|
+
references2[r].push(path7);
|
|
4564
|
+
} else {
|
|
4565
|
+
references2[r] = [path7];
|
|
4566
|
+
}
|
|
4567
|
+
}
|
|
4568
|
+
} else {
|
|
4569
|
+
if (references2[ref]) {
|
|
4570
|
+
references2[ref].push(path7);
|
|
4571
|
+
} else {
|
|
4572
|
+
references2[ref] = [path7];
|
|
4573
|
+
}
|
|
4574
|
+
}
|
|
4575
|
+
}
|
|
4576
|
+
for (const ref of Object.keys(references2)) {
|
|
4577
|
+
for (const path7 of references2[ref]) {
|
|
4578
|
+
result.push({
|
|
4579
|
+
type: opType,
|
|
4580
|
+
key: `${ref}${INDEX_KEY_FIELD_SEPARATOR}${path7}${INDEX_KEY_FIELD_SEPARATOR}${filepath}`,
|
|
4581
|
+
sublevel: refSublevel,
|
|
4582
|
+
value: opType === "put" ? {} : void 0
|
|
4583
|
+
});
|
|
4584
|
+
}
|
|
4585
|
+
}
|
|
4586
|
+
}
|
|
4587
|
+
}
|
|
4588
|
+
return result;
|
|
4589
|
+
};
|
|
4536
4590
|
var makeStringEscaper = (regex, replacement) => {
|
|
4537
4591
|
return (input) => {
|
|
4538
4592
|
if (Array.isArray(input)) {
|
|
@@ -4753,24 +4807,29 @@ var transformDocumentIntoPayload = async (fullPath, rawData, tinaSchema, config,
|
|
|
4753
4807
|
throw e;
|
|
4754
4808
|
}
|
|
4755
4809
|
};
|
|
4756
|
-
var updateObjectWithJsonPath = (obj, path7, newValue) => {
|
|
4810
|
+
var updateObjectWithJsonPath = (obj, path7, oldValue, newValue) => {
|
|
4811
|
+
let updated = false;
|
|
4757
4812
|
if (!path7.includes(".") && !path7.includes("[")) {
|
|
4758
|
-
if (path7 in obj) {
|
|
4813
|
+
if (path7 in obj && obj[path7] === oldValue) {
|
|
4759
4814
|
obj[path7] = newValue;
|
|
4815
|
+
updated = true;
|
|
4760
4816
|
}
|
|
4761
|
-
return obj;
|
|
4817
|
+
return { object: obj, updated };
|
|
4762
4818
|
}
|
|
4763
|
-
const parentPath = path7.replace(/\.[
|
|
4764
|
-
const keyToUpdate = path7.match(/[
|
|
4819
|
+
const parentPath = path7.replace(/\.[^.\[\]]+$/, "");
|
|
4820
|
+
const keyToUpdate = path7.match(/[^.\[\]]+$/)[0];
|
|
4765
4821
|
const parents = JSONPath2({ path: parentPath, json: obj, resultType: "value" });
|
|
4766
4822
|
if (parents.length > 0) {
|
|
4767
4823
|
parents.forEach((parent) => {
|
|
4768
4824
|
if (parent && typeof parent === "object" && keyToUpdate in parent) {
|
|
4769
|
-
parent[keyToUpdate]
|
|
4825
|
+
if (parent[keyToUpdate] === oldValue) {
|
|
4826
|
+
parent[keyToUpdate] = newValue;
|
|
4827
|
+
updated = true;
|
|
4828
|
+
}
|
|
4770
4829
|
}
|
|
4771
4830
|
});
|
|
4772
4831
|
}
|
|
4773
|
-
return obj;
|
|
4832
|
+
return { object: obj, updated };
|
|
4774
4833
|
};
|
|
4775
4834
|
var Resolver = class {
|
|
4776
4835
|
constructor(init) {
|
|
@@ -5148,17 +5207,35 @@ var Resolver = class {
|
|
|
5148
5207
|
await this.deleteDocument(realPath);
|
|
5149
5208
|
if (await this.hasReferences(realPath, collection)) {
|
|
5150
5209
|
const collRefs = await this.findReferences(realPath, collection);
|
|
5151
|
-
for (const [collection2,
|
|
5152
|
-
for (const [
|
|
5153
|
-
|
|
5154
|
-
|
|
5155
|
-
|
|
5210
|
+
for (const [collection2, docsWithRefs] of Object.entries(collRefs)) {
|
|
5211
|
+
for (const [pathToDocWithRef, referencePaths] of Object.entries(
|
|
5212
|
+
docsWithRefs
|
|
5213
|
+
)) {
|
|
5214
|
+
let refDoc = await this.getRaw(pathToDocWithRef);
|
|
5215
|
+
let hasUpdate = false;
|
|
5216
|
+
for (const path7 of referencePaths) {
|
|
5217
|
+
const { object: object2, updated } = updateObjectWithJsonPath(
|
|
5156
5218
|
refDoc,
|
|
5157
|
-
|
|
5219
|
+
path7,
|
|
5220
|
+
realPath,
|
|
5158
5221
|
null
|
|
5159
5222
|
);
|
|
5223
|
+
refDoc = object2;
|
|
5224
|
+
hasUpdate = updated || hasUpdate;
|
|
5225
|
+
}
|
|
5226
|
+
if (hasUpdate) {
|
|
5227
|
+
const collectionWithRef = this.tinaSchema.getCollectionByFullPath(pathToDocWithRef);
|
|
5228
|
+
if (!collectionWithRef) {
|
|
5229
|
+
throw new Error(
|
|
5230
|
+
`Unable to find collection for ${pathToDocWithRef}`
|
|
5231
|
+
);
|
|
5232
|
+
}
|
|
5233
|
+
await this.database.put(
|
|
5234
|
+
pathToDocWithRef,
|
|
5235
|
+
refDoc,
|
|
5236
|
+
collectionWithRef.name
|
|
5237
|
+
);
|
|
5160
5238
|
}
|
|
5161
|
-
await this.database.put(refPath, refDoc, collection2);
|
|
5162
5239
|
}
|
|
5163
5240
|
}
|
|
5164
5241
|
}
|
|
@@ -5184,17 +5261,35 @@ var Resolver = class {
|
|
|
5184
5261
|
await this.database.put(newRealPath, doc._rawData, collection.name);
|
|
5185
5262
|
await this.deleteDocument(realPath);
|
|
5186
5263
|
const collRefs = await this.findReferences(realPath, collection);
|
|
5187
|
-
for (const [collection2,
|
|
5188
|
-
for (const [
|
|
5189
|
-
|
|
5190
|
-
|
|
5191
|
-
|
|
5192
|
-
|
|
5193
|
-
|
|
5264
|
+
for (const [collection2, docsWithRefs] of Object.entries(collRefs)) {
|
|
5265
|
+
for (const [pathToDocWithRef, referencePaths] of Object.entries(
|
|
5266
|
+
docsWithRefs
|
|
5267
|
+
)) {
|
|
5268
|
+
let docWithRef = await this.getRaw(pathToDocWithRef);
|
|
5269
|
+
let hasUpdate = false;
|
|
5270
|
+
for (const path7 of referencePaths) {
|
|
5271
|
+
const { object: object2, updated } = updateObjectWithJsonPath(
|
|
5272
|
+
docWithRef,
|
|
5273
|
+
path7,
|
|
5274
|
+
realPath,
|
|
5194
5275
|
newRealPath
|
|
5195
5276
|
);
|
|
5277
|
+
docWithRef = object2;
|
|
5278
|
+
hasUpdate = updated || hasUpdate;
|
|
5279
|
+
}
|
|
5280
|
+
if (hasUpdate) {
|
|
5281
|
+
const collectionWithRef = this.tinaSchema.getCollectionByFullPath(pathToDocWithRef);
|
|
5282
|
+
if (!collectionWithRef) {
|
|
5283
|
+
throw new Error(
|
|
5284
|
+
`Unable to find collection for ${pathToDocWithRef}`
|
|
5285
|
+
);
|
|
5286
|
+
}
|
|
5287
|
+
await this.database.put(
|
|
5288
|
+
pathToDocWithRef,
|
|
5289
|
+
docWithRef,
|
|
5290
|
+
collectionWithRef.name
|
|
5291
|
+
);
|
|
5196
5292
|
}
|
|
5197
|
-
await this.database.put(refPath, refDoc, collection2);
|
|
5198
5293
|
}
|
|
5199
5294
|
}
|
|
5200
5295
|
return this.getDocument(newRealPath);
|
|
@@ -5326,35 +5421,30 @@ var Resolver = class {
|
|
|
5326
5421
|
*/
|
|
5327
5422
|
this.hasReferences = async (id, c) => {
|
|
5328
5423
|
let count = 0;
|
|
5329
|
-
|
|
5330
|
-
|
|
5331
|
-
|
|
5332
|
-
|
|
5333
|
-
|
|
5334
|
-
|
|
5335
|
-
|
|
5336
|
-
|
|
5337
|
-
|
|
5338
|
-
|
|
5339
|
-
|
|
5340
|
-
|
|
5341
|
-
|
|
5342
|
-
|
|
5343
|
-
|
|
5344
|
-
|
|
5345
|
-
|
|
5346
|
-
|
|
5347
|
-
|
|
5348
|
-
|
|
5349
|
-
(refId) => {
|
|
5350
|
-
count++;
|
|
5351
|
-
return refId;
|
|
5352
|
-
}
|
|
5353
|
-
);
|
|
5354
|
-
if (count) {
|
|
5355
|
-
return true;
|
|
5356
|
-
}
|
|
5424
|
+
await this.database.query(
|
|
5425
|
+
{
|
|
5426
|
+
collection: c.name,
|
|
5427
|
+
filterChain: makeFilterChain({
|
|
5428
|
+
conditions: [
|
|
5429
|
+
{
|
|
5430
|
+
filterPath: REFS_REFERENCE_FIELD,
|
|
5431
|
+
filterExpression: {
|
|
5432
|
+
_type: "string",
|
|
5433
|
+
_list: false,
|
|
5434
|
+
eq: id
|
|
5435
|
+
}
|
|
5436
|
+
}
|
|
5437
|
+
]
|
|
5438
|
+
}),
|
|
5439
|
+
sort: REFS_COLLECTIONS_SORT_KEY
|
|
5440
|
+
},
|
|
5441
|
+
(refId) => {
|
|
5442
|
+
count++;
|
|
5443
|
+
return refId;
|
|
5357
5444
|
}
|
|
5445
|
+
);
|
|
5446
|
+
if (count) {
|
|
5447
|
+
return true;
|
|
5358
5448
|
}
|
|
5359
5449
|
return false;
|
|
5360
5450
|
};
|
|
@@ -5362,46 +5452,41 @@ var Resolver = class {
|
|
|
5362
5452
|
* Finds references to a document
|
|
5363
5453
|
* @param id the id of the document to find references to
|
|
5364
5454
|
* @param c the collection to find references in
|
|
5365
|
-
* @returns
|
|
5455
|
+
* @returns a map of references to the document
|
|
5366
5456
|
*/
|
|
5367
5457
|
this.findReferences = async (id, c) => {
|
|
5368
5458
|
const references = {};
|
|
5369
|
-
|
|
5370
|
-
|
|
5371
|
-
|
|
5372
|
-
|
|
5373
|
-
|
|
5374
|
-
|
|
5375
|
-
|
|
5376
|
-
|
|
5377
|
-
|
|
5378
|
-
|
|
5379
|
-
|
|
5380
|
-
|
|
5381
|
-
_list: false,
|
|
5382
|
-
eq: id
|
|
5383
|
-
}
|
|
5384
|
-
}
|
|
5385
|
-
]
|
|
5386
|
-
}),
|
|
5387
|
-
sort: ref.field.name
|
|
5388
|
-
},
|
|
5389
|
-
(refId) => {
|
|
5390
|
-
if (!references[collection]) {
|
|
5391
|
-
references[collection] = {};
|
|
5392
|
-
}
|
|
5393
|
-
if (!references[collection][refId]) {
|
|
5394
|
-
references[collection][refId] = [];
|
|
5459
|
+
await this.database.query(
|
|
5460
|
+
{
|
|
5461
|
+
collection: c.name,
|
|
5462
|
+
filterChain: makeFilterChain({
|
|
5463
|
+
conditions: [
|
|
5464
|
+
{
|
|
5465
|
+
filterPath: REFS_REFERENCE_FIELD,
|
|
5466
|
+
filterExpression: {
|
|
5467
|
+
_type: "string",
|
|
5468
|
+
_list: false,
|
|
5469
|
+
eq: id
|
|
5470
|
+
}
|
|
5395
5471
|
}
|
|
5396
|
-
|
|
5397
|
-
|
|
5398
|
-
|
|
5399
|
-
|
|
5400
|
-
|
|
5401
|
-
|
|
5402
|
-
|
|
5472
|
+
]
|
|
5473
|
+
}),
|
|
5474
|
+
sort: REFS_COLLECTIONS_SORT_KEY
|
|
5475
|
+
},
|
|
5476
|
+
(refId, rawItem) => {
|
|
5477
|
+
if (!references[c.name]) {
|
|
5478
|
+
references[c.name] = {};
|
|
5479
|
+
}
|
|
5480
|
+
if (!references[c.name][refId]) {
|
|
5481
|
+
references[c.name][refId] = [];
|
|
5482
|
+
}
|
|
5483
|
+
const referencePath = rawItem?.[REFS_PATH_FIELD];
|
|
5484
|
+
if (referencePath) {
|
|
5485
|
+
references[c.name][refId].push(referencePath);
|
|
5486
|
+
}
|
|
5487
|
+
return refId;
|
|
5403
5488
|
}
|
|
5404
|
-
|
|
5489
|
+
);
|
|
5405
5490
|
return references;
|
|
5406
5491
|
};
|
|
5407
5492
|
this.buildFieldMutations = async (fieldParams, template, existingData) => {
|
|
@@ -6145,6 +6230,7 @@ var Database = class {
|
|
|
6145
6230
|
);
|
|
6146
6231
|
const indexDefinitions = await this.getIndexDefinitions(this.contentLevel);
|
|
6147
6232
|
const collectionIndexDefinitions = indexDefinitions?.[collection.name];
|
|
6233
|
+
const collectionReferences = (await this.getCollectionReferences())?.[collection.name];
|
|
6148
6234
|
const normalizedPath = normalizePath(filepath);
|
|
6149
6235
|
if (!collection?.isDetached) {
|
|
6150
6236
|
if (this.bridge) {
|
|
@@ -6173,6 +6259,14 @@ var Database = class {
|
|
|
6173
6259
|
let delOps = [];
|
|
6174
6260
|
if (!isGitKeep(normalizedPath, collection)) {
|
|
6175
6261
|
putOps = [
|
|
6262
|
+
...makeRefOpsForDocument(
|
|
6263
|
+
normalizedPath,
|
|
6264
|
+
collection?.name,
|
|
6265
|
+
collectionReferences,
|
|
6266
|
+
dataFields,
|
|
6267
|
+
"put",
|
|
6268
|
+
level
|
|
6269
|
+
),
|
|
6176
6270
|
...makeIndexOpsForDocument(
|
|
6177
6271
|
normalizedPath,
|
|
6178
6272
|
collection?.name,
|
|
@@ -6196,6 +6290,14 @@ var Database = class {
|
|
|
6196
6290
|
SUBLEVEL_OPTIONS
|
|
6197
6291
|
).get(normalizedPath);
|
|
6198
6292
|
delOps = existingItem ? [
|
|
6293
|
+
...makeRefOpsForDocument(
|
|
6294
|
+
normalizedPath,
|
|
6295
|
+
collection?.name,
|
|
6296
|
+
collectionReferences,
|
|
6297
|
+
existingItem,
|
|
6298
|
+
"del",
|
|
6299
|
+
level
|
|
6300
|
+
),
|
|
6199
6301
|
...makeIndexOpsForDocument(
|
|
6200
6302
|
normalizedPath,
|
|
6201
6303
|
collection?.name,
|
|
@@ -6243,6 +6345,7 @@ var Database = class {
|
|
|
6243
6345
|
);
|
|
6244
6346
|
collectionIndexDefinitions = indexDefinitions?.[collectionName];
|
|
6245
6347
|
}
|
|
6348
|
+
const collectionReferences = (await this.getCollectionReferences())?.[collectionName];
|
|
6246
6349
|
const normalizedPath = normalizePath(filepath);
|
|
6247
6350
|
const dataFields = await this.formatBodyOnPayload(filepath, data);
|
|
6248
6351
|
const collection = await this.collectionForPath(filepath);
|
|
@@ -6290,6 +6393,14 @@ var Database = class {
|
|
|
6290
6393
|
let delOps = [];
|
|
6291
6394
|
if (!isGitKeep(normalizedPath, collection)) {
|
|
6292
6395
|
putOps = [
|
|
6396
|
+
...makeRefOpsForDocument(
|
|
6397
|
+
normalizedPath,
|
|
6398
|
+
collectionName,
|
|
6399
|
+
collectionReferences,
|
|
6400
|
+
dataFields,
|
|
6401
|
+
"put",
|
|
6402
|
+
level
|
|
6403
|
+
),
|
|
6293
6404
|
...makeIndexOpsForDocument(
|
|
6294
6405
|
normalizedPath,
|
|
6295
6406
|
collectionName,
|
|
@@ -6313,6 +6424,14 @@ var Database = class {
|
|
|
6313
6424
|
SUBLEVEL_OPTIONS
|
|
6314
6425
|
).get(normalizedPath);
|
|
6315
6426
|
delOps = existingItem ? [
|
|
6427
|
+
...makeRefOpsForDocument(
|
|
6428
|
+
normalizedPath,
|
|
6429
|
+
collectionName,
|
|
6430
|
+
collectionReferences,
|
|
6431
|
+
existingItem,
|
|
6432
|
+
"del",
|
|
6433
|
+
level
|
|
6434
|
+
),
|
|
6316
6435
|
...makeIndexOpsForDocument(
|
|
6317
6436
|
normalizedPath,
|
|
6318
6437
|
collectionName,
|
|
@@ -6475,6 +6594,22 @@ var Database = class {
|
|
|
6475
6594
|
this.tinaSchema = await createSchema({ schema });
|
|
6476
6595
|
return this.tinaSchema;
|
|
6477
6596
|
};
|
|
6597
|
+
this.getCollectionReferences = async (level) => {
|
|
6598
|
+
if (this.collectionReferences) {
|
|
6599
|
+
return this.collectionReferences;
|
|
6600
|
+
}
|
|
6601
|
+
const result = {};
|
|
6602
|
+
const schema = await this.getSchema(level || this.contentLevel);
|
|
6603
|
+
const collections = schema.getCollections();
|
|
6604
|
+
for (const collection of collections) {
|
|
6605
|
+
const collectionReferences = this.tinaSchema.findReferencesFromCollection(
|
|
6606
|
+
collection.name
|
|
6607
|
+
);
|
|
6608
|
+
result[collection.name] = collectionReferences;
|
|
6609
|
+
}
|
|
6610
|
+
this.collectionReferences = result;
|
|
6611
|
+
return result;
|
|
6612
|
+
};
|
|
6478
6613
|
this.getIndexDefinitions = async (level) => {
|
|
6479
6614
|
if (!this.collectionIndexDefinitions) {
|
|
6480
6615
|
await new Promise(async (resolve2, reject) => {
|
|
@@ -6484,8 +6619,23 @@ var Database = class {
|
|
|
6484
6619
|
const collections = schema.getCollections();
|
|
6485
6620
|
for (const collection of collections) {
|
|
6486
6621
|
const indexDefinitions = {
|
|
6487
|
-
[DEFAULT_COLLECTION_SORT_KEY]: { fields: [] }
|
|
6622
|
+
[DEFAULT_COLLECTION_SORT_KEY]: { fields: [] },
|
|
6488
6623
|
// provide a default sort key which is the file sort
|
|
6624
|
+
// pseudo-index for the collection's references
|
|
6625
|
+
[REFS_COLLECTIONS_SORT_KEY]: {
|
|
6626
|
+
fields: [
|
|
6627
|
+
{
|
|
6628
|
+
name: REFS_REFERENCE_FIELD,
|
|
6629
|
+
type: "string",
|
|
6630
|
+
list: false
|
|
6631
|
+
},
|
|
6632
|
+
{
|
|
6633
|
+
name: REFS_PATH_FIELD,
|
|
6634
|
+
type: "string",
|
|
6635
|
+
list: false
|
|
6636
|
+
}
|
|
6637
|
+
]
|
|
6638
|
+
}
|
|
6489
6639
|
};
|
|
6490
6640
|
if (collection.fields) {
|
|
6491
6641
|
for (const field of collection.fields) {
|
|
@@ -6636,29 +6786,36 @@ var Database = class {
|
|
|
6636
6786
|
}
|
|
6637
6787
|
startKey = startKey || key || "";
|
|
6638
6788
|
endKey = key || "";
|
|
6639
|
-
edges = [...edges, { cursor: key, path: filepath }];
|
|
6789
|
+
edges = [...edges, { cursor: key, path: filepath, value: itemRecord }];
|
|
6640
6790
|
}
|
|
6641
6791
|
return {
|
|
6642
|
-
edges: await sequential(
|
|
6643
|
-
|
|
6644
|
-
|
|
6645
|
-
|
|
6646
|
-
|
|
6647
|
-
|
|
6648
|
-
|
|
6649
|
-
|
|
6650
|
-
|
|
6651
|
-
|
|
6652
|
-
|
|
6653
|
-
|
|
6654
|
-
|
|
6655
|
-
|
|
6656
|
-
|
|
6657
|
-
|
|
6792
|
+
edges: await sequential(
|
|
6793
|
+
edges,
|
|
6794
|
+
async ({
|
|
6795
|
+
cursor,
|
|
6796
|
+
path: path7,
|
|
6797
|
+
value
|
|
6798
|
+
}) => {
|
|
6799
|
+
try {
|
|
6800
|
+
const node = await hydrator(path7, value);
|
|
6801
|
+
return {
|
|
6802
|
+
node,
|
|
6803
|
+
cursor: btoa(cursor)
|
|
6804
|
+
};
|
|
6805
|
+
} catch (error) {
|
|
6806
|
+
console.log(error);
|
|
6807
|
+
if (error instanceof Error && (!path7.includes(".tina/__generated__/_graphql.json") || !path7.includes("tina/__generated__/_graphql.json"))) {
|
|
6808
|
+
throw new TinaQueryError({
|
|
6809
|
+
originalError: error,
|
|
6810
|
+
file: path7,
|
|
6811
|
+
collection: collection.name,
|
|
6812
|
+
stack: error.stack
|
|
6813
|
+
});
|
|
6814
|
+
}
|
|
6815
|
+
throw error;
|
|
6658
6816
|
}
|
|
6659
|
-
throw error;
|
|
6660
6817
|
}
|
|
6661
|
-
|
|
6818
|
+
),
|
|
6662
6819
|
pageInfo: {
|
|
6663
6820
|
hasPreviousPage,
|
|
6664
6821
|
hasNextPage,
|
|
@@ -6804,6 +6961,7 @@ var Database = class {
|
|
|
6804
6961
|
throw new Error(`No collection found for path: ${filepath}`);
|
|
6805
6962
|
}
|
|
6806
6963
|
const indexDefinitions = await this.getIndexDefinitions(this.contentLevel);
|
|
6964
|
+
const collectionReferences = (await this.getCollectionReferences())?.[collection.name];
|
|
6807
6965
|
const collectionIndexDefinitions = indexDefinitions?.[collection.name];
|
|
6808
6966
|
let level = this.contentLevel;
|
|
6809
6967
|
if (collection?.isDetached) {
|
|
@@ -6822,6 +6980,14 @@ var Database = class {
|
|
|
6822
6980
|
collection.path || ""
|
|
6823
6981
|
);
|
|
6824
6982
|
await this.contentLevel.batch([
|
|
6983
|
+
...makeRefOpsForDocument(
|
|
6984
|
+
normalizedPath,
|
|
6985
|
+
collection.name,
|
|
6986
|
+
collectionReferences,
|
|
6987
|
+
item,
|
|
6988
|
+
"del",
|
|
6989
|
+
level
|
|
6990
|
+
),
|
|
6825
6991
|
...makeIndexOpsForDocument(
|
|
6826
6992
|
normalizedPath,
|
|
6827
6993
|
collection.name,
|
|
@@ -7049,6 +7215,7 @@ var _indexContent = async (database, level, documentPaths, enqueueOps, collectio
|
|
|
7049
7215
|
}
|
|
7050
7216
|
collectionPath = collection.path;
|
|
7051
7217
|
}
|
|
7218
|
+
const collectionReferences = (await database.getCollectionReferences())?.[collection?.name];
|
|
7052
7219
|
const tinaSchema = await database.getSchema();
|
|
7053
7220
|
let templateInfo = null;
|
|
7054
7221
|
if (collection) {
|
|
@@ -7081,6 +7248,14 @@ var _indexContent = async (database, level, documentPaths, enqueueOps, collectio
|
|
|
7081
7248
|
const item = await rootSublevel.get(normalizedPath);
|
|
7082
7249
|
if (item) {
|
|
7083
7250
|
await database.contentLevel.batch([
|
|
7251
|
+
...makeRefOpsForDocument(
|
|
7252
|
+
normalizedPath,
|
|
7253
|
+
collection?.name,
|
|
7254
|
+
collectionReferences,
|
|
7255
|
+
item,
|
|
7256
|
+
"del",
|
|
7257
|
+
level
|
|
7258
|
+
),
|
|
7084
7259
|
...makeIndexOpsForDocument(
|
|
7085
7260
|
normalizedPath,
|
|
7086
7261
|
collection.name,
|
|
@@ -7107,6 +7282,14 @@ var _indexContent = async (database, level, documentPaths, enqueueOps, collectio
|
|
|
7107
7282
|
}
|
|
7108
7283
|
if (!isGitKeep(filepath, collection)) {
|
|
7109
7284
|
await enqueueOps([
|
|
7285
|
+
...makeRefOpsForDocument(
|
|
7286
|
+
normalizedPath,
|
|
7287
|
+
collection?.name,
|
|
7288
|
+
collectionReferences,
|
|
7289
|
+
aliasedData,
|
|
7290
|
+
"put",
|
|
7291
|
+
level
|
|
7292
|
+
),
|
|
7110
7293
|
...makeIndexOpsForDocument(
|
|
7111
7294
|
normalizedPath,
|
|
7112
7295
|
collection?.name,
|
|
@@ -7170,6 +7353,7 @@ var _deleteIndexContent = async (database, documentPaths, enqueueOps, collection
|
|
|
7170
7353
|
throw new Error(`No indexDefinitions for collection ${collection.name}`);
|
|
7171
7354
|
}
|
|
7172
7355
|
}
|
|
7356
|
+
const collectionReferences = (await database.getCollectionReferences())?.[collection?.name];
|
|
7173
7357
|
const tinaSchema = await database.getSchema();
|
|
7174
7358
|
let templateInfo = null;
|
|
7175
7359
|
if (collection) {
|
|
@@ -7193,6 +7377,14 @@ var _deleteIndexContent = async (database, documentPaths, enqueueOps, collection
|
|
|
7193
7377
|
item
|
|
7194
7378
|
) : item;
|
|
7195
7379
|
await enqueueOps([
|
|
7380
|
+
...makeRefOpsForDocument(
|
|
7381
|
+
itemKey,
|
|
7382
|
+
collection?.name,
|
|
7383
|
+
collectionReferences,
|
|
7384
|
+
aliasedData,
|
|
7385
|
+
"del",
|
|
7386
|
+
database.contentLevel
|
|
7387
|
+
),
|
|
7196
7388
|
...makeIndexOpsForDocument(
|
|
7197
7389
|
itemKey,
|
|
7198
7390
|
collection.name,
|
package/dist/resolver/index.d.ts
CHANGED
|
@@ -40,6 +40,17 @@ export declare const transformDocumentIntoPayload: (fullPath: string, rawData: {
|
|
|
40
40
|
__typename: string;
|
|
41
41
|
id: string;
|
|
42
42
|
}>;
|
|
43
|
+
/**
|
|
44
|
+
* Updates a property in an object using a JSONPath.
|
|
45
|
+
* @param obj - The object to update.
|
|
46
|
+
* @param path - The JSONPath string.
|
|
47
|
+
* @param newValue - The new value to set at the specified path.
|
|
48
|
+
* @returns the updated object.
|
|
49
|
+
*/
|
|
50
|
+
export declare const updateObjectWithJsonPath: (obj: any, path: string, oldValue: any, newValue: any) => {
|
|
51
|
+
object: any;
|
|
52
|
+
updated: boolean;
|
|
53
|
+
};
|
|
43
54
|
/**
|
|
44
55
|
* The resolver provides functions for all possible types of lookup
|
|
45
56
|
* values and retrieves them from the database
|
|
@@ -346,7 +357,7 @@ export declare class Resolver {
|
|
|
346
357
|
* Finds references to a document
|
|
347
358
|
* @param id the id of the document to find references to
|
|
348
359
|
* @param c the collection to find references in
|
|
349
|
-
* @returns
|
|
360
|
+
* @returns a map of references to the document
|
|
350
361
|
*/
|
|
351
362
|
private findReferences;
|
|
352
363
|
private buildFieldMutations;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tinacms/graphql",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.14",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"module": "dist/index.mjs",
|
|
6
6
|
"typings": "dist/index.d.ts",
|
|
@@ -44,8 +44,8 @@
|
|
|
44
44
|
"readable-stream": "^4.7.0",
|
|
45
45
|
"scmp": "^2.1.0",
|
|
46
46
|
"yup": "^0.32.11",
|
|
47
|
-
"@tinacms/
|
|
48
|
-
"@tinacms/
|
|
47
|
+
"@tinacms/schema-tools": "1.7.2",
|
|
48
|
+
"@tinacms/mdx": "1.6.1"
|
|
49
49
|
},
|
|
50
50
|
"publishConfig": {
|
|
51
51
|
"registry": "https://registry.npmjs.org"
|
|
@@ -76,8 +76,8 @@
|
|
|
76
76
|
"vite": "^4.5.9",
|
|
77
77
|
"vitest": "^0.32.4",
|
|
78
78
|
"zod": "^3.24.2",
|
|
79
|
-
"@tinacms/schema-tools": "1.7.
|
|
80
|
-
"@tinacms/scripts": "1.3.
|
|
79
|
+
"@tinacms/schema-tools": "1.7.2",
|
|
80
|
+
"@tinacms/scripts": "1.3.3"
|
|
81
81
|
},
|
|
82
82
|
"scripts": {
|
|
83
83
|
"types": "pnpm tsc",
|