@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.
@@ -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 {};
@@ -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.13",
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(/[^.]+$/)[0];
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] = newValue;
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, refFields] of Object.entries(collRefs)) {
5229
- for (const [refPath, refs] of Object.entries(refFields)) {
5230
- let refDoc = await this.getRaw(refPath);
5231
- for (const ref of refs) {
5232
- refDoc = updateObjectWithJsonPath(
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
- ref.path.join("."),
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, refFields] of Object.entries(collRefs)) {
5265
- for (const [refPath, refs] of Object.entries(refFields)) {
5266
- let refDoc = await this.getRaw(refPath);
5267
- for (const ref of refs) {
5268
- refDoc = updateObjectWithJsonPath(
5269
- refDoc,
5270
- ref.path.join("."),
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
- const deepRefs = this.tinaSchema.findReferences(c.name);
5407
- for (const [collection, refs] of Object.entries(deepRefs)) {
5408
- for (const ref of refs) {
5409
- await this.database.query(
5410
- {
5411
- collection,
5412
- filterChain: makeFilterChain({
5413
- conditions: [
5414
- {
5415
- filterPath: ref.path.join("."),
5416
- filterExpression: {
5417
- _type: "reference",
5418
- _list: false,
5419
- eq: id
5420
- }
5421
- }
5422
- ]
5423
- }),
5424
- sort: ref.field.name
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 references to the document in the form of a map of collection names to a list of fields that reference the document
5532
+ * @returns a map of references to the document
5443
5533
  */
5444
5534
  this.findReferences = async (id, c) => {
5445
5535
  const references = {};
5446
- const deepRefs = this.tinaSchema.findReferences(c.name);
5447
- for (const [collection, refs] of Object.entries(deepRefs)) {
5448
- for (const ref of refs) {
5449
- await this.database.query(
5450
- {
5451
- collection,
5452
- filterChain: makeFilterChain({
5453
- conditions: [
5454
- {
5455
- filterPath: ref.path.join("."),
5456
- filterExpression: {
5457
- _type: "reference",
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
- references[collection][refId].push({
5474
- path: ref.path,
5475
- field: ref.field
5476
- });
5477
- return refId;
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 (((_a = collection.match) == null ? void 0 : _a.exclude) || ((_b = collection.match) == null ? void 0 : _b.include)) {
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(edges, async (edge) => {
6727
- try {
6728
- const node = await hydrator(edge.path);
6729
- return {
6730
- node,
6731
- cursor: btoa(edge.cursor)
6732
- };
6733
- } catch (error) {
6734
- console.log(error);
6735
- if (error instanceof Error && (!edge.path.includes(".tina/__generated__/_graphql.json") || !edge.path.includes("tina/__generated__/_graphql.json"))) {
6736
- throw new TinaQueryError({
6737
- originalError: error,
6738
- file: edge.path,
6739
- collection: collection.name,
6740
- stack: error.stack
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.13",
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(/[^.]+$/)[0];
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] = newValue;
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, refFields] of Object.entries(collRefs)) {
5152
- for (const [refPath, refs] of Object.entries(refFields)) {
5153
- let refDoc = await this.getRaw(refPath);
5154
- for (const ref of refs) {
5155
- refDoc = updateObjectWithJsonPath(
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
- ref.path.join("."),
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, refFields] of Object.entries(collRefs)) {
5188
- for (const [refPath, refs] of Object.entries(refFields)) {
5189
- let refDoc = await this.getRaw(refPath);
5190
- for (const ref of refs) {
5191
- refDoc = updateObjectWithJsonPath(
5192
- refDoc,
5193
- ref.path.join("."),
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
- const deepRefs = this.tinaSchema.findReferences(c.name);
5330
- for (const [collection, refs] of Object.entries(deepRefs)) {
5331
- for (const ref of refs) {
5332
- await this.database.query(
5333
- {
5334
- collection,
5335
- filterChain: makeFilterChain({
5336
- conditions: [
5337
- {
5338
- filterPath: ref.path.join("."),
5339
- filterExpression: {
5340
- _type: "reference",
5341
- _list: false,
5342
- eq: id
5343
- }
5344
- }
5345
- ]
5346
- }),
5347
- sort: ref.field.name
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 references to the document in the form of a map of collection names to a list of fields that reference the document
5455
+ * @returns a map of references to the document
5366
5456
  */
5367
5457
  this.findReferences = async (id, c) => {
5368
5458
  const references = {};
5369
- const deepRefs = this.tinaSchema.findReferences(c.name);
5370
- for (const [collection, refs] of Object.entries(deepRefs)) {
5371
- for (const ref of refs) {
5372
- await this.database.query(
5373
- {
5374
- collection,
5375
- filterChain: makeFilterChain({
5376
- conditions: [
5377
- {
5378
- filterPath: ref.path.join("."),
5379
- filterExpression: {
5380
- _type: "reference",
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
- references[collection][refId].push({
5397
- path: ref.path,
5398
- field: ref.field
5399
- });
5400
- return refId;
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(edges, async (edge) => {
6643
- try {
6644
- const node = await hydrator(edge.path);
6645
- return {
6646
- node,
6647
- cursor: btoa(edge.cursor)
6648
- };
6649
- } catch (error) {
6650
- console.log(error);
6651
- if (error instanceof Error && (!edge.path.includes(".tina/__generated__/_graphql.json") || !edge.path.includes("tina/__generated__/_graphql.json"))) {
6652
- throw new TinaQueryError({
6653
- originalError: error,
6654
- file: edge.path,
6655
- collection: collection.name,
6656
- stack: error.stack
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,
@@ -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 references to the document in the form of a map of collection names to a list of fields that reference the document
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.13",
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/mdx": "1.6.0",
48
- "@tinacms/schema-tools": "1.7.1"
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.1",
80
- "@tinacms/scripts": "1.3.2"
79
+ "@tinacms/schema-tools": "1.7.2",
80
+ "@tinacms/scripts": "1.3.3"
81
81
  },
82
82
  "scripts": {
83
83
  "types": "pnpm tsc",