@tinacms/graphql 0.0.0-b832ee4-20250102012112 → 0.0.0-bdc07c1-20250506013835

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1029,41 +1029,6 @@ function* walk(maybeNode, visited = /* @__PURE__ */ new WeakSet()) {
1029
1029
  yield maybeNode;
1030
1030
  visited.add(maybeNode);
1031
1031
  }
1032
- function addNamespaceToSchema(maybeNode, namespace = []) {
1033
- if (typeof maybeNode === "string") {
1034
- return maybeNode;
1035
- }
1036
- if (typeof maybeNode === "boolean") {
1037
- return maybeNode;
1038
- }
1039
- const newNode = maybeNode;
1040
- const keys = Object.keys(maybeNode);
1041
- Object.values(maybeNode).map((m, index) => {
1042
- const key = keys[index];
1043
- if (Array.isArray(m)) {
1044
- newNode[key] = m.map((element) => {
1045
- if (!element) {
1046
- return;
1047
- }
1048
- if (!element.hasOwnProperty("name")) {
1049
- return element;
1050
- }
1051
- const value = element.name || element.value;
1052
- return addNamespaceToSchema(element, [...namespace, value]);
1053
- });
1054
- } else {
1055
- if (!m) {
1056
- return;
1057
- }
1058
- if (!m.hasOwnProperty("name")) {
1059
- newNode[key] = m;
1060
- } else {
1061
- newNode[key] = addNamespaceToSchema(m, [...namespace, m.name]);
1062
- }
1063
- }
1064
- });
1065
- return { ...newNode, namespace };
1066
- }
1067
1032
  var generateNamespacedFieldName = (names, suffix = "") => {
1068
1033
  return (suffix ? [...names, suffix] : names).map(capitalize).join("");
1069
1034
  };
@@ -1882,7 +1847,7 @@ var Builder = class {
1882
1847
  * ```
1883
1848
  *
1884
1849
  * @public
1885
- * @param collection a Tina Cloud collection
1850
+ * @param collection a TinaCloud collection
1886
1851
  */
1887
1852
  this.collectionFragment = async (collection) => {
1888
1853
  const name = NAMER.dataTypeName(collection.namespace);
@@ -2898,6 +2863,7 @@ var filterSelections = (arr) => {
2898
2863
  import { TinaSchema } from "@tinacms/schema-tools";
2899
2864
 
2900
2865
  // src/schema/validate.ts
2866
+ import { addNamespaceToSchema } from "@tinacms/schema-tools";
2901
2867
  import deepClone from "lodash.clonedeep";
2902
2868
  import * as yup2 from "yup";
2903
2869
  import {
@@ -3053,7 +3019,7 @@ var validateField = async (field) => {
3053
3019
  // package.json
3054
3020
  var package_default = {
3055
3021
  name: "@tinacms/graphql",
3056
- version: "1.5.9",
3022
+ version: "1.5.16",
3057
3023
  main: "dist/index.js",
3058
3024
  module: "dist/index.mjs",
3059
3025
  typings: "dist/index.d.ts",
@@ -3080,8 +3046,8 @@ var package_default = {
3080
3046
  build: "tinacms-scripts build",
3081
3047
  docs: "pnpm typedoc",
3082
3048
  serve: "pnpm nodemon dist/server.js",
3083
- test: "jest",
3084
- "test-watch": "jest --watch"
3049
+ test: "vitest run",
3050
+ "test-watch": "vitest"
3085
3051
  },
3086
3052
  dependencies: {
3087
3053
  "@iarna/toml": "^2.2.5",
@@ -3089,12 +3055,12 @@ var package_default = {
3089
3055
  "@tinacms/schema-tools": "workspace:*",
3090
3056
  "abstract-level": "^1.0.4",
3091
3057
  "date-fns": "^2.30.0",
3092
- "fast-glob": "^3.3.2",
3093
- "fs-extra": "^11.2.0",
3058
+ "fast-glob": "^3.3.3",
3059
+ "fs-extra": "^11.3.0",
3094
3060
  "glob-parent": "^6.0.2",
3095
3061
  graphql: "15.8.0",
3096
3062
  "gray-matter": "^4.0.3",
3097
- "isomorphic-git": "^1.27.1",
3063
+ "isomorphic-git": "^1.29.0",
3098
3064
  "js-sha1": "^0.6.0",
3099
3065
  "js-yaml": "^3.14.1",
3100
3066
  "jsonpath-plus": "10.1.0",
@@ -3104,10 +3070,13 @@ var package_default = {
3104
3070
  "many-level": "^2.0.0",
3105
3071
  micromatch: "4.0.8",
3106
3072
  "normalize-path": "^3.0.0",
3107
- "readable-stream": "^4.5.2",
3073
+ "readable-stream": "^4.7.0",
3108
3074
  scmp: "^2.1.0",
3109
3075
  yup: "^0.32.11"
3110
3076
  },
3077
+ peerDependencies: {
3078
+ "@tinacms/common": "workspace:*"
3079
+ },
3111
3080
  publishConfig: {
3112
3081
  registry: "https://registry.npmjs.org"
3113
3082
  },
@@ -3122,24 +3091,23 @@ var package_default = {
3122
3091
  "@types/estree": "^0.0.50",
3123
3092
  "@types/express": "^4.17.21",
3124
3093
  "@types/fs-extra": "^9.0.13",
3125
- "@types/jest": "^26.0.24",
3126
3094
  "@types/js-yaml": "^3.12.10",
3127
3095
  "@types/lodash.camelcase": "^4.3.9",
3128
3096
  "@types/lodash.upperfirst": "^4.3.9",
3129
3097
  "@types/lru-cache": "^5.1.1",
3130
3098
  "@types/mdast": "^3.0.15",
3131
3099
  "@types/micromatch": "^4.0.9",
3132
- "@types/node": "^22.9.0",
3100
+ "@types/node": "^22.13.1",
3133
3101
  "@types/normalize-path": "^3.0.2",
3134
3102
  "@types/ws": "^7.4.7",
3135
3103
  "@types/yup": "^0.29.14",
3136
- jest: "^29.7.0",
3137
- "jest-diff": "^29.7.0",
3138
3104
  "jest-file-snapshot": "^0.5.0",
3139
- "jest-matcher-utils": "^29.7.0",
3140
3105
  "memory-level": "^1.0.0",
3141
3106
  nodemon: "3.1.4",
3142
- typescript: "^5.6.3"
3107
+ typescript: "^5.7.3",
3108
+ vite: "^4.5.9",
3109
+ vitest: "^0.32.4",
3110
+ zod: "^3.24.2"
3143
3111
  }
3144
3112
  };
3145
3113
 
@@ -3295,7 +3263,9 @@ var _buildSchema = async (builder, tinaSchema) => {
3295
3263
  await builder.buildCreateCollectionFolderMutation()
3296
3264
  );
3297
3265
  await sequential(collections, async (collection) => {
3298
- queryTypeDefinitionFields.push(await builder.collectionDocument(collection));
3266
+ queryTypeDefinitionFields.push(
3267
+ await builder.collectionDocument(collection)
3268
+ );
3299
3269
  if (collection.isAuthCollection) {
3300
3270
  queryTypeDefinitionFields.push(
3301
3271
  await builder.authenticationCollectionDocument(collection)
@@ -3610,7 +3580,9 @@ var LevelProxyHandler = {
3610
3580
  throw new Error(`The property, ${property.toString()}, doesn't exist`);
3611
3581
  }
3612
3582
  if (typeof target[property] !== "function") {
3613
- throw new Error(`The property, ${property.toString()}, is not a function`);
3583
+ throw new Error(
3584
+ `The property, ${property.toString()}, is not a function`
3585
+ );
3614
3586
  }
3615
3587
  if (property === "get") {
3616
3588
  return async (...args) => {
@@ -3995,6 +3967,9 @@ var loadAndParseWithAliases = async (bridge, filepath, collection, templateInfo)
3995
3967
 
3996
3968
  // src/database/datalayer.ts
3997
3969
  var DEFAULT_COLLECTION_SORT_KEY = "__filepath__";
3970
+ var REFS_COLLECTIONS_SORT_KEY = "__refs__";
3971
+ var REFS_REFERENCE_FIELD = "__tina_ref__";
3972
+ var REFS_PATH_FIELD = "__tina_ref_path__";
3998
3973
  var DEFAULT_NUMERIC_LPAD = 4;
3999
3974
  var applyPadding = (input, pad) => {
4000
3975
  if (pad) {
@@ -4568,6 +4543,57 @@ var makeIndexOpsForDocument = (filepath, collection, indexDefinitions, data, opT
4568
4543
  }
4569
4544
  return result;
4570
4545
  };
4546
+ var makeRefOpsForDocument = (filepath, collection, references, data, opType, level) => {
4547
+ const result = [];
4548
+ if (collection) {
4549
+ for (const [c, referencePaths] of Object.entries(references || {})) {
4550
+ if (!referencePaths.length) {
4551
+ continue;
4552
+ }
4553
+ const collectionSublevel = level.sublevel(c, SUBLEVEL_OPTIONS);
4554
+ const refSublevel = collectionSublevel.sublevel(
4555
+ REFS_COLLECTIONS_SORT_KEY,
4556
+ SUBLEVEL_OPTIONS
4557
+ );
4558
+ const references2 = {};
4559
+ for (const path7 of referencePaths) {
4560
+ const ref = JSONPath({ path: path7, json: data });
4561
+ if (!ref) {
4562
+ continue;
4563
+ }
4564
+ if (Array.isArray(ref)) {
4565
+ for (const r of ref) {
4566
+ if (!r) {
4567
+ continue;
4568
+ }
4569
+ if (references2[r]) {
4570
+ references2[r].push(path7);
4571
+ } else {
4572
+ references2[r] = [path7];
4573
+ }
4574
+ }
4575
+ } else {
4576
+ if (references2[ref]) {
4577
+ references2[ref].push(path7);
4578
+ } else {
4579
+ references2[ref] = [path7];
4580
+ }
4581
+ }
4582
+ }
4583
+ for (const ref of Object.keys(references2)) {
4584
+ for (const path7 of references2[ref]) {
4585
+ result.push({
4586
+ type: opType,
4587
+ key: `${ref}${INDEX_KEY_FIELD_SEPARATOR}${path7}${INDEX_KEY_FIELD_SEPARATOR}${filepath}`,
4588
+ sublevel: refSublevel,
4589
+ value: opType === "put" ? {} : void 0
4590
+ });
4591
+ }
4592
+ }
4593
+ }
4594
+ }
4595
+ return result;
4596
+ };
4571
4597
  var makeStringEscaper = (regex, replacement) => {
4572
4598
  return (input) => {
4573
4599
  if (Array.isArray(input)) {
@@ -4788,24 +4814,33 @@ var transformDocumentIntoPayload = async (fullPath, rawData, tinaSchema, config,
4788
4814
  throw e;
4789
4815
  }
4790
4816
  };
4791
- var updateObjectWithJsonPath = (obj, path7, newValue) => {
4817
+ var updateObjectWithJsonPath = (obj, path7, oldValue, newValue) => {
4818
+ let updated = false;
4792
4819
  if (!path7.includes(".") && !path7.includes("[")) {
4793
- if (path7 in obj) {
4820
+ if (path7 in obj && obj[path7] === oldValue) {
4794
4821
  obj[path7] = newValue;
4822
+ updated = true;
4795
4823
  }
4796
- return obj;
4797
- }
4798
- const parentPath = path7.replace(/\.[^.]+$/, "");
4799
- const keyToUpdate = path7.match(/[^.]+$/)[0];
4800
- const parents = JSONPath2({ path: parentPath, json: obj, resultType: "value" });
4824
+ return { object: obj, updated };
4825
+ }
4826
+ const parentPath = path7.replace(/\.[^.\[\]]+$/, "");
4827
+ const keyToUpdate = path7.match(/[^.\[\]]+$/)[0];
4828
+ const parents = JSONPath2({
4829
+ path: parentPath,
4830
+ json: obj,
4831
+ resultType: "value"
4832
+ });
4801
4833
  if (parents.length > 0) {
4802
4834
  parents.forEach((parent) => {
4803
4835
  if (parent && typeof parent === "object" && keyToUpdate in parent) {
4804
- parent[keyToUpdate] = newValue;
4836
+ if (parent[keyToUpdate] === oldValue) {
4837
+ parent[keyToUpdate] = newValue;
4838
+ updated = true;
4839
+ }
4805
4840
  }
4806
4841
  });
4807
4842
  }
4808
- return obj;
4843
+ return { object: obj, updated };
4809
4844
  };
4810
4845
  var Resolver = class {
4811
4846
  constructor(init) {
@@ -4822,7 +4857,9 @@ var Resolver = class {
4822
4857
  };
4823
4858
  this.getRaw = async (fullPath) => {
4824
4859
  if (typeof fullPath !== "string") {
4825
- throw new Error(`fullPath must be of type string for getDocument request`);
4860
+ throw new Error(
4861
+ `fullPath must be of type string for getDocument request`
4862
+ );
4826
4863
  }
4827
4864
  return this.database.get(fullPath);
4828
4865
  };
@@ -4851,7 +4888,9 @@ var Resolver = class {
4851
4888
  };
4852
4889
  this.getDocument = async (fullPath, opts = {}) => {
4853
4890
  if (typeof fullPath !== "string") {
4854
- throw new Error(`fullPath must be of type string for getDocument request`);
4891
+ throw new Error(
4892
+ `fullPath must be of type string for getDocument request`
4893
+ );
4855
4894
  }
4856
4895
  const rawData = await this.getRaw(fullPath);
4857
4896
  const hasReferences = opts?.checkReferences ? await this.hasReferences(fullPath, opts.collection) : void 0;
@@ -4866,7 +4905,9 @@ var Resolver = class {
4866
4905
  };
4867
4906
  this.deleteDocument = async (fullPath) => {
4868
4907
  if (typeof fullPath !== "string") {
4869
- throw new Error(`fullPath must be of type string for getDocument request`);
4908
+ throw new Error(
4909
+ `fullPath must be of type string for getDocument request`
4910
+ );
4870
4911
  }
4871
4912
  await this.database.delete(fullPath);
4872
4913
  };
@@ -5070,7 +5111,11 @@ var Resolver = class {
5070
5111
  collection,
5071
5112
  doc?._rawData
5072
5113
  );
5073
- await this.database.put(realPath, { ...oldDoc, ...params }, collection.name);
5114
+ await this.database.put(
5115
+ realPath,
5116
+ { ...oldDoc, ...params },
5117
+ collection.name
5118
+ );
5074
5119
  return this.getDocument(realPath);
5075
5120
  };
5076
5121
  /**
@@ -5183,17 +5228,35 @@ var Resolver = class {
5183
5228
  await this.deleteDocument(realPath);
5184
5229
  if (await this.hasReferences(realPath, collection)) {
5185
5230
  const collRefs = await this.findReferences(realPath, collection);
5186
- for (const [collection2, refFields] of Object.entries(collRefs)) {
5187
- for (const [refPath, refs] of Object.entries(refFields)) {
5188
- let refDoc = await this.getRaw(refPath);
5189
- for (const ref of refs) {
5190
- refDoc = updateObjectWithJsonPath(
5231
+ for (const [collection2, docsWithRefs] of Object.entries(collRefs)) {
5232
+ for (const [pathToDocWithRef, referencePaths] of Object.entries(
5233
+ docsWithRefs
5234
+ )) {
5235
+ let refDoc = await this.getRaw(pathToDocWithRef);
5236
+ let hasUpdate = false;
5237
+ for (const path7 of referencePaths) {
5238
+ const { object: object2, updated } = updateObjectWithJsonPath(
5191
5239
  refDoc,
5192
- ref.path.join("."),
5240
+ path7,
5241
+ realPath,
5193
5242
  null
5194
5243
  );
5244
+ refDoc = object2;
5245
+ hasUpdate = updated || hasUpdate;
5246
+ }
5247
+ if (hasUpdate) {
5248
+ const collectionWithRef = this.tinaSchema.getCollectionByFullPath(pathToDocWithRef);
5249
+ if (!collectionWithRef) {
5250
+ throw new Error(
5251
+ `Unable to find collection for ${pathToDocWithRef}`
5252
+ );
5253
+ }
5254
+ await this.database.put(
5255
+ pathToDocWithRef,
5256
+ refDoc,
5257
+ collectionWithRef.name
5258
+ );
5195
5259
  }
5196
- await this.database.put(refPath, refDoc, collection2);
5197
5260
  }
5198
5261
  }
5199
5262
  }
@@ -5213,26 +5276,49 @@ var Resolver = class {
5213
5276
  collection?.path,
5214
5277
  args.params.relativePath
5215
5278
  );
5279
+ if (newRealPath === realPath) {
5280
+ return doc;
5281
+ }
5216
5282
  await this.database.put(newRealPath, doc._rawData, collection.name);
5217
5283
  await this.deleteDocument(realPath);
5218
5284
  const collRefs = await this.findReferences(realPath, collection);
5219
- for (const [collection2, refFields] of Object.entries(collRefs)) {
5220
- for (const [refPath, refs] of Object.entries(refFields)) {
5221
- let refDoc = await this.getRaw(refPath);
5222
- for (const ref of refs) {
5223
- refDoc = updateObjectWithJsonPath(
5224
- refDoc,
5225
- ref.path.join("."),
5285
+ for (const [collection2, docsWithRefs] of Object.entries(collRefs)) {
5286
+ for (const [pathToDocWithRef, referencePaths] of Object.entries(
5287
+ docsWithRefs
5288
+ )) {
5289
+ let docWithRef = await this.getRaw(pathToDocWithRef);
5290
+ let hasUpdate = false;
5291
+ for (const path7 of referencePaths) {
5292
+ const { object: object2, updated } = updateObjectWithJsonPath(
5293
+ docWithRef,
5294
+ path7,
5295
+ realPath,
5226
5296
  newRealPath
5227
5297
  );
5298
+ docWithRef = object2;
5299
+ hasUpdate = updated || hasUpdate;
5300
+ }
5301
+ if (hasUpdate) {
5302
+ const collectionWithRef = this.tinaSchema.getCollectionByFullPath(pathToDocWithRef);
5303
+ if (!collectionWithRef) {
5304
+ throw new Error(
5305
+ `Unable to find collection for ${pathToDocWithRef}`
5306
+ );
5307
+ }
5308
+ await this.database.put(
5309
+ pathToDocWithRef,
5310
+ docWithRef,
5311
+ collectionWithRef.name
5312
+ );
5228
5313
  }
5229
- await this.database.put(refPath, refDoc, collection2);
5230
5314
  }
5231
5315
  }
5232
5316
  return this.getDocument(newRealPath);
5233
5317
  }
5234
5318
  if (alreadyExists === false) {
5235
- throw new Error(`Unable to update document, ${realPath} does not exist`);
5319
+ throw new Error(
5320
+ `Unable to update document, ${realPath} does not exist`
5321
+ );
5236
5322
  }
5237
5323
  return this.updateResolveDocument({
5238
5324
  collection,
@@ -5358,35 +5444,30 @@ var Resolver = class {
5358
5444
  */
5359
5445
  this.hasReferences = async (id, c) => {
5360
5446
  let count = 0;
5361
- const deepRefs = this.tinaSchema.findReferences(c.name);
5362
- for (const [collection, refs] of Object.entries(deepRefs)) {
5363
- for (const ref of refs) {
5364
- await this.database.query(
5365
- {
5366
- collection,
5367
- filterChain: makeFilterChain({
5368
- conditions: [
5369
- {
5370
- filterPath: ref.path.join("."),
5371
- filterExpression: {
5372
- _type: "reference",
5373
- _list: false,
5374
- eq: id
5375
- }
5376
- }
5377
- ]
5378
- }),
5379
- sort: ref.field.name
5380
- },
5381
- (refId) => {
5382
- count++;
5383
- return refId;
5384
- }
5385
- );
5386
- if (count) {
5387
- return true;
5388
- }
5447
+ await this.database.query(
5448
+ {
5449
+ collection: c.name,
5450
+ filterChain: makeFilterChain({
5451
+ conditions: [
5452
+ {
5453
+ filterPath: REFS_REFERENCE_FIELD,
5454
+ filterExpression: {
5455
+ _type: "string",
5456
+ _list: false,
5457
+ eq: id
5458
+ }
5459
+ }
5460
+ ]
5461
+ }),
5462
+ sort: REFS_COLLECTIONS_SORT_KEY
5463
+ },
5464
+ (refId) => {
5465
+ count++;
5466
+ return refId;
5389
5467
  }
5468
+ );
5469
+ if (count) {
5470
+ return true;
5390
5471
  }
5391
5472
  return false;
5392
5473
  };
@@ -5394,46 +5475,41 @@ var Resolver = class {
5394
5475
  * Finds references to a document
5395
5476
  * @param id the id of the document to find references to
5396
5477
  * @param c the collection to find references in
5397
- * @returns references to the document in the form of a map of collection names to a list of fields that reference the document
5478
+ * @returns a map of references to the document
5398
5479
  */
5399
5480
  this.findReferences = async (id, c) => {
5400
5481
  const references = {};
5401
- const deepRefs = this.tinaSchema.findReferences(c.name);
5402
- for (const [collection, refs] of Object.entries(deepRefs)) {
5403
- for (const ref of refs) {
5404
- await this.database.query(
5405
- {
5406
- collection,
5407
- filterChain: makeFilterChain({
5408
- conditions: [
5409
- {
5410
- filterPath: ref.path.join("."),
5411
- filterExpression: {
5412
- _type: "reference",
5413
- _list: false,
5414
- eq: id
5415
- }
5416
- }
5417
- ]
5418
- }),
5419
- sort: ref.field.name
5420
- },
5421
- (refId) => {
5422
- if (!references[collection]) {
5423
- references[collection] = {};
5424
- }
5425
- if (!references[collection][refId]) {
5426
- references[collection][refId] = [];
5482
+ await this.database.query(
5483
+ {
5484
+ collection: c.name,
5485
+ filterChain: makeFilterChain({
5486
+ conditions: [
5487
+ {
5488
+ filterPath: REFS_REFERENCE_FIELD,
5489
+ filterExpression: {
5490
+ _type: "string",
5491
+ _list: false,
5492
+ eq: id
5493
+ }
5427
5494
  }
5428
- references[collection][refId].push({
5429
- path: ref.path,
5430
- field: ref.field
5431
- });
5432
- return refId;
5433
- }
5434
- );
5495
+ ]
5496
+ }),
5497
+ sort: REFS_COLLECTIONS_SORT_KEY
5498
+ },
5499
+ (refId, rawItem) => {
5500
+ if (!references[c.name]) {
5501
+ references[c.name] = {};
5502
+ }
5503
+ if (!references[c.name][refId]) {
5504
+ references[c.name][refId] = [];
5505
+ }
5506
+ const referencePath = rawItem?.[REFS_PATH_FIELD];
5507
+ if (referencePath) {
5508
+ references[c.name][refId].push(referencePath);
5509
+ }
5510
+ return refId;
5435
5511
  }
5436
- }
5512
+ );
5437
5513
  return references;
5438
5514
  };
5439
5515
  this.buildFieldMutations = async (fieldParams, template, existingData) => {
@@ -6177,6 +6253,7 @@ var Database = class {
6177
6253
  );
6178
6254
  const indexDefinitions = await this.getIndexDefinitions(this.contentLevel);
6179
6255
  const collectionIndexDefinitions = indexDefinitions?.[collection.name];
6256
+ const collectionReferences = (await this.getCollectionReferences())?.[collection.name];
6180
6257
  const normalizedPath = normalizePath(filepath);
6181
6258
  if (!collection?.isDetached) {
6182
6259
  if (this.bridge) {
@@ -6205,6 +6282,14 @@ var Database = class {
6205
6282
  let delOps = [];
6206
6283
  if (!isGitKeep(normalizedPath, collection)) {
6207
6284
  putOps = [
6285
+ ...makeRefOpsForDocument(
6286
+ normalizedPath,
6287
+ collection?.name,
6288
+ collectionReferences,
6289
+ dataFields,
6290
+ "put",
6291
+ level
6292
+ ),
6208
6293
  ...makeIndexOpsForDocument(
6209
6294
  normalizedPath,
6210
6295
  collection?.name,
@@ -6228,6 +6313,14 @@ var Database = class {
6228
6313
  SUBLEVEL_OPTIONS
6229
6314
  ).get(normalizedPath);
6230
6315
  delOps = existingItem ? [
6316
+ ...makeRefOpsForDocument(
6317
+ normalizedPath,
6318
+ collection?.name,
6319
+ collectionReferences,
6320
+ existingItem,
6321
+ "del",
6322
+ level
6323
+ ),
6231
6324
  ...makeIndexOpsForDocument(
6232
6325
  normalizedPath,
6233
6326
  collection?.name,
@@ -6275,6 +6368,7 @@ var Database = class {
6275
6368
  );
6276
6369
  collectionIndexDefinitions = indexDefinitions?.[collectionName];
6277
6370
  }
6371
+ const collectionReferences = (await this.getCollectionReferences())?.[collectionName];
6278
6372
  const normalizedPath = normalizePath(filepath);
6279
6373
  const dataFields = await this.formatBodyOnPayload(filepath, data);
6280
6374
  const collection = await this.collectionForPath(filepath);
@@ -6322,6 +6416,14 @@ var Database = class {
6322
6416
  let delOps = [];
6323
6417
  if (!isGitKeep(normalizedPath, collection)) {
6324
6418
  putOps = [
6419
+ ...makeRefOpsForDocument(
6420
+ normalizedPath,
6421
+ collectionName,
6422
+ collectionReferences,
6423
+ dataFields,
6424
+ "put",
6425
+ level
6426
+ ),
6325
6427
  ...makeIndexOpsForDocument(
6326
6428
  normalizedPath,
6327
6429
  collectionName,
@@ -6345,6 +6447,14 @@ var Database = class {
6345
6447
  SUBLEVEL_OPTIONS
6346
6448
  ).get(normalizedPath);
6347
6449
  delOps = existingItem ? [
6450
+ ...makeRefOpsForDocument(
6451
+ normalizedPath,
6452
+ collectionName,
6453
+ collectionReferences,
6454
+ existingItem,
6455
+ "del",
6456
+ level
6457
+ ),
6348
6458
  ...makeIndexOpsForDocument(
6349
6459
  normalizedPath,
6350
6460
  collectionName,
@@ -6507,6 +6617,22 @@ var Database = class {
6507
6617
  this.tinaSchema = await createSchema({ schema });
6508
6618
  return this.tinaSchema;
6509
6619
  };
6620
+ this.getCollectionReferences = async (level) => {
6621
+ if (this.collectionReferences) {
6622
+ return this.collectionReferences;
6623
+ }
6624
+ const result = {};
6625
+ const schema = await this.getSchema(level || this.contentLevel);
6626
+ const collections = schema.getCollections();
6627
+ for (const collection of collections) {
6628
+ const collectionReferences = this.tinaSchema.findReferencesFromCollection(
6629
+ collection.name
6630
+ );
6631
+ result[collection.name] = collectionReferences;
6632
+ }
6633
+ this.collectionReferences = result;
6634
+ return result;
6635
+ };
6510
6636
  this.getIndexDefinitions = async (level) => {
6511
6637
  if (!this.collectionIndexDefinitions) {
6512
6638
  await new Promise(async (resolve2, reject) => {
@@ -6516,11 +6642,53 @@ var Database = class {
6516
6642
  const collections = schema.getCollections();
6517
6643
  for (const collection of collections) {
6518
6644
  const indexDefinitions = {
6519
- [DEFAULT_COLLECTION_SORT_KEY]: { fields: [] }
6645
+ [DEFAULT_COLLECTION_SORT_KEY]: { fields: [] },
6520
6646
  // provide a default sort key which is the file sort
6647
+ // pseudo-index for the collection's references
6648
+ [REFS_COLLECTIONS_SORT_KEY]: {
6649
+ fields: [
6650
+ {
6651
+ name: REFS_REFERENCE_FIELD,
6652
+ type: "string",
6653
+ list: false
6654
+ },
6655
+ {
6656
+ name: REFS_PATH_FIELD,
6657
+ type: "string",
6658
+ list: false
6659
+ }
6660
+ ]
6661
+ }
6521
6662
  };
6522
- if (collection.fields) {
6523
- for (const field of collection.fields) {
6663
+ let fields = [];
6664
+ if (collection.templates) {
6665
+ const templateFieldMap = {};
6666
+ const conflictedFields = /* @__PURE__ */ new Set();
6667
+ for (const template of collection.templates) {
6668
+ for (const field of template.fields) {
6669
+ if (!templateFieldMap[field.name]) {
6670
+ templateFieldMap[field.name] = field;
6671
+ } else {
6672
+ if (templateFieldMap[field.name].type !== field.type) {
6673
+ console.warn(
6674
+ `Field ${field.name} has conflicting types in templates - skipping index`
6675
+ );
6676
+ conflictedFields.add(field.name);
6677
+ }
6678
+ }
6679
+ }
6680
+ }
6681
+ for (const conflictedField in conflictedFields) {
6682
+ delete templateFieldMap[conflictedField];
6683
+ }
6684
+ for (const field of Object.values(templateFieldMap)) {
6685
+ fields.push(field);
6686
+ }
6687
+ } else if (collection.fields) {
6688
+ fields = collection.fields;
6689
+ }
6690
+ if (fields) {
6691
+ for (const field of fields) {
6524
6692
  if (field.indexed !== void 0 && field.indexed === false || field.type === "object") {
6525
6693
  continue;
6526
6694
  }
@@ -6668,29 +6836,36 @@ var Database = class {
6668
6836
  }
6669
6837
  startKey = startKey || key || "";
6670
6838
  endKey = key || "";
6671
- edges = [...edges, { cursor: key, path: filepath }];
6839
+ edges = [...edges, { cursor: key, path: filepath, value: itemRecord }];
6672
6840
  }
6673
6841
  return {
6674
- edges: await sequential(edges, async (edge) => {
6675
- try {
6676
- const node = await hydrator(edge.path);
6677
- return {
6678
- node,
6679
- cursor: btoa(edge.cursor)
6680
- };
6681
- } catch (error) {
6682
- console.log(error);
6683
- if (error instanceof Error && (!edge.path.includes(".tina/__generated__/_graphql.json") || !edge.path.includes("tina/__generated__/_graphql.json"))) {
6684
- throw new TinaQueryError({
6685
- originalError: error,
6686
- file: edge.path,
6687
- collection: collection.name,
6688
- stack: error.stack
6689
- });
6842
+ edges: await sequential(
6843
+ edges,
6844
+ async ({
6845
+ cursor,
6846
+ path: path7,
6847
+ value
6848
+ }) => {
6849
+ try {
6850
+ const node = await hydrator(path7, value);
6851
+ return {
6852
+ node,
6853
+ cursor: btoa(cursor)
6854
+ };
6855
+ } catch (error) {
6856
+ console.log(error);
6857
+ if (error instanceof Error && (!path7.includes(".tina/__generated__/_graphql.json") || !path7.includes("tina/__generated__/_graphql.json"))) {
6858
+ throw new TinaQueryError({
6859
+ originalError: error,
6860
+ file: path7,
6861
+ collection: collection.name,
6862
+ stack: error.stack
6863
+ });
6864
+ }
6865
+ throw error;
6690
6866
  }
6691
- throw error;
6692
6867
  }
6693
- }),
6868
+ ),
6694
6869
  pageInfo: {
6695
6870
  hasPreviousPage,
6696
6871
  hasNextPage,
@@ -6814,13 +6989,14 @@ var Database = class {
6814
6989
  documentPaths,
6815
6990
  async (collection, documentPaths2) => {
6816
6991
  if (collection && !collection.isDetached) {
6817
- await _indexContent(
6818
- this,
6819
- this.contentLevel,
6820
- documentPaths2,
6992
+ await _indexContent({
6993
+ database: this,
6994
+ level: this.contentLevel,
6995
+ documentPaths: documentPaths2,
6821
6996
  enqueueOps,
6822
- collection
6823
- );
6997
+ collection,
6998
+ isPartialReindex: true
6999
+ });
6824
7000
  }
6825
7001
  }
6826
7002
  );
@@ -6836,6 +7012,7 @@ var Database = class {
6836
7012
  throw new Error(`No collection found for path: ${filepath}`);
6837
7013
  }
6838
7014
  const indexDefinitions = await this.getIndexDefinitions(this.contentLevel);
7015
+ const collectionReferences = (await this.getCollectionReferences())?.[collection.name];
6839
7016
  const collectionIndexDefinitions = indexDefinitions?.[collection.name];
6840
7017
  let level = this.contentLevel;
6841
7018
  if (collection?.isDetached) {
@@ -6854,6 +7031,14 @@ var Database = class {
6854
7031
  collection.path || ""
6855
7032
  );
6856
7033
  await this.contentLevel.batch([
7034
+ ...makeRefOpsForDocument(
7035
+ normalizedPath,
7036
+ collection.name,
7037
+ collectionReferences,
7038
+ item,
7039
+ "del",
7040
+ level
7041
+ ),
6857
7042
  ...makeIndexOpsForDocument(
6858
7043
  normalizedPath,
6859
7044
  collection.name,
@@ -6918,20 +7103,26 @@ var Database = class {
6918
7103
  );
6919
7104
  const doc = await level2.keys({ limit: 1 }).next();
6920
7105
  if (!doc) {
6921
- await _indexContent(
6922
- this,
6923
- level2,
6924
- contentPaths,
7106
+ await _indexContent({
7107
+ database: this,
7108
+ level: level2,
7109
+ documentPaths: contentPaths,
6925
7110
  enqueueOps,
6926
7111
  collection,
6927
- userFields.map((field) => [
7112
+ passwordFields: userFields.map((field) => [
6928
7113
  ...field.path,
6929
7114
  field.passwordFieldName
6930
7115
  ])
6931
- );
7116
+ });
6932
7117
  }
6933
7118
  } else {
6934
- await _indexContent(this, level, contentPaths, enqueueOps, collection);
7119
+ await _indexContent({
7120
+ database: this,
7121
+ level,
7122
+ documentPaths: contentPaths,
7123
+ enqueueOps,
7124
+ collection
7125
+ });
6935
7126
  }
6936
7127
  }
6937
7128
  );
@@ -7070,7 +7261,15 @@ var hashPasswordValues = async (data, passwordFields) => Promise.all(
7070
7261
  )
7071
7262
  );
7072
7263
  var isGitKeep = (filepath, collection) => filepath.endsWith(`.gitkeep.${collection?.format || "md"}`);
7073
- var _indexContent = async (database, level, documentPaths, enqueueOps, collection, passwordFields) => {
7264
+ var _indexContent = async ({
7265
+ database,
7266
+ level,
7267
+ documentPaths,
7268
+ enqueueOps,
7269
+ collection,
7270
+ passwordFields,
7271
+ isPartialReindex
7272
+ }) => {
7074
7273
  let collectionIndexDefinitions;
7075
7274
  let collectionPath;
7076
7275
  if (collection) {
@@ -7081,6 +7280,7 @@ var _indexContent = async (database, level, documentPaths, enqueueOps, collectio
7081
7280
  }
7082
7281
  collectionPath = collection.path;
7083
7282
  }
7283
+ const collectionReferences = (await database.getCollectionReferences())?.[collection?.name];
7084
7284
  const tinaSchema = await database.getSchema();
7085
7285
  let templateInfo = null;
7086
7286
  if (collection) {
@@ -7102,12 +7302,61 @@ var _indexContent = async (database, level, documentPaths, enqueueOps, collectio
7102
7302
  await hashPasswordValues(aliasedData, passwordFields);
7103
7303
  }
7104
7304
  const normalizedPath = normalizePath(filepath);
7305
+ const rootSublevel = level.sublevel(
7306
+ CONTENT_ROOT_PREFIX,
7307
+ SUBLEVEL_OPTIONS
7308
+ );
7105
7309
  const folderKey = folderTreeBuilder.update(
7106
7310
  normalizedPath,
7107
7311
  collectionPath || ""
7108
7312
  );
7313
+ if (isPartialReindex) {
7314
+ const item = await rootSublevel.get(normalizedPath);
7315
+ if (item) {
7316
+ await database.contentLevel.batch([
7317
+ ...makeRefOpsForDocument(
7318
+ normalizedPath,
7319
+ collection?.name,
7320
+ collectionReferences,
7321
+ item,
7322
+ "del",
7323
+ level
7324
+ ),
7325
+ ...makeIndexOpsForDocument(
7326
+ normalizedPath,
7327
+ collection.name,
7328
+ collectionIndexDefinitions,
7329
+ item,
7330
+ "del",
7331
+ level
7332
+ ),
7333
+ // folder indices
7334
+ ...makeIndexOpsForDocument(
7335
+ normalizedPath,
7336
+ `${collection.name}_${folderKey}`,
7337
+ collectionIndexDefinitions,
7338
+ item,
7339
+ "del",
7340
+ level
7341
+ ),
7342
+ {
7343
+ type: "del",
7344
+ key: normalizedPath,
7345
+ sublevel: rootSublevel
7346
+ }
7347
+ ]);
7348
+ }
7349
+ }
7109
7350
  if (!isGitKeep(filepath, collection)) {
7110
7351
  await enqueueOps([
7352
+ ...makeRefOpsForDocument(
7353
+ normalizedPath,
7354
+ collection?.name,
7355
+ collectionReferences,
7356
+ aliasedData,
7357
+ "put",
7358
+ level
7359
+ ),
7111
7360
  ...makeIndexOpsForDocument(
7112
7361
  normalizedPath,
7113
7362
  collection?.name,
@@ -7171,6 +7420,7 @@ var _deleteIndexContent = async (database, documentPaths, enqueueOps, collection
7171
7420
  throw new Error(`No indexDefinitions for collection ${collection.name}`);
7172
7421
  }
7173
7422
  }
7423
+ const collectionReferences = (await database.getCollectionReferences())?.[collection?.name];
7174
7424
  const tinaSchema = await database.getSchema();
7175
7425
  let templateInfo = null;
7176
7426
  if (collection) {
@@ -7194,6 +7444,14 @@ var _deleteIndexContent = async (database, documentPaths, enqueueOps, collection
7194
7444
  item
7195
7445
  ) : item;
7196
7446
  await enqueueOps([
7447
+ ...makeRefOpsForDocument(
7448
+ itemKey,
7449
+ collection?.name,
7450
+ collectionReferences,
7451
+ aliasedData,
7452
+ "del",
7453
+ database.contentLevel
7454
+ ),
7197
7455
  ...makeIndexOpsForDocument(
7198
7456
  itemKey,
7199
7457
  collection.name,