@tinacms/graphql 0.0.0-d7c745e-20250102002342 → 0.0.0-d9672bc-20250218033222

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1095,41 +1095,6 @@ function* walk(maybeNode, visited = /* @__PURE__ */ new WeakSet()) {
1095
1095
  yield maybeNode;
1096
1096
  visited.add(maybeNode);
1097
1097
  }
1098
- function addNamespaceToSchema(maybeNode, namespace = []) {
1099
- if (typeof maybeNode === "string") {
1100
- return maybeNode;
1101
- }
1102
- if (typeof maybeNode === "boolean") {
1103
- return maybeNode;
1104
- }
1105
- const newNode = maybeNode;
1106
- const keys = Object.keys(maybeNode);
1107
- Object.values(maybeNode).map((m, index) => {
1108
- const key = keys[index];
1109
- if (Array.isArray(m)) {
1110
- newNode[key] = m.map((element) => {
1111
- if (!element) {
1112
- return;
1113
- }
1114
- if (!element.hasOwnProperty("name")) {
1115
- return element;
1116
- }
1117
- const value = element.name || element.value;
1118
- return addNamespaceToSchema(element, [...namespace, value]);
1119
- });
1120
- } else {
1121
- if (!m) {
1122
- return;
1123
- }
1124
- if (!m.hasOwnProperty("name")) {
1125
- newNode[key] = m;
1126
- } else {
1127
- newNode[key] = addNamespaceToSchema(m, [...namespace, m.name]);
1128
- }
1129
- }
1130
- });
1131
- return { ...newNode, namespace };
1132
- }
1133
1098
  var generateNamespacedFieldName = (names, suffix = "") => {
1134
1099
  return (suffix ? [...names, suffix] : names).map(capitalize).join("");
1135
1100
  };
@@ -2965,12 +2930,13 @@ var filterSelections = (arr) => {
2965
2930
  };
2966
2931
 
2967
2932
  // src/schema/createSchema.ts
2968
- var import_schema_tools2 = require("@tinacms/schema-tools");
2933
+ var import_schema_tools3 = require("@tinacms/schema-tools");
2969
2934
 
2970
2935
  // src/schema/validate.ts
2936
+ var import_schema_tools = require("@tinacms/schema-tools");
2971
2937
  var import_lodash2 = __toESM(require("lodash.clonedeep"));
2972
2938
  var yup2 = __toESM(require("yup"));
2973
- var import_schema_tools = require("@tinacms/schema-tools");
2939
+ var import_schema_tools2 = require("@tinacms/schema-tools");
2974
2940
  var FIELD_TYPES = [
2975
2941
  "string",
2976
2942
  "number",
@@ -2983,7 +2949,7 @@ var FIELD_TYPES = [
2983
2949
  "password"
2984
2950
  ];
2985
2951
  var validateSchema = async (schema) => {
2986
- const schema2 = addNamespaceToSchema(
2952
+ const schema2 = (0, import_schema_tools.addNamespaceToSchema)(
2987
2953
  (0, import_lodash2.default)(schema)
2988
2954
  );
2989
2955
  const collections = await sequential(
@@ -2992,7 +2958,7 @@ var validateSchema = async (schema) => {
2992
2958
  );
2993
2959
  validationCollectionsPathAndMatch(collections);
2994
2960
  if (schema2.config) {
2995
- const config = (0, import_schema_tools.validateTinaCloudSchemaConfig)(schema2.config);
2961
+ const config = (0, import_schema_tools2.validateTinaCloudSchemaConfig)(schema2.config);
2996
2962
  return {
2997
2963
  collections,
2998
2964
  config
@@ -3124,7 +3090,7 @@ var validateField = async (field) => {
3124
3090
  // package.json
3125
3091
  var package_default = {
3126
3092
  name: "@tinacms/graphql",
3127
- version: "1.5.9",
3093
+ version: "1.5.12",
3128
3094
  main: "dist/index.js",
3129
3095
  module: "dist/index.mjs",
3130
3096
  typings: "dist/index.d.ts",
@@ -3151,8 +3117,8 @@ var package_default = {
3151
3117
  build: "tinacms-scripts build",
3152
3118
  docs: "pnpm typedoc",
3153
3119
  serve: "pnpm nodemon dist/server.js",
3154
- test: "jest",
3155
- "test-watch": "jest --watch"
3120
+ test: "vitest run",
3121
+ "test-watch": "vitest"
3156
3122
  },
3157
3123
  dependencies: {
3158
3124
  "@iarna/toml": "^2.2.5",
@@ -3193,7 +3159,6 @@ var package_default = {
3193
3159
  "@types/estree": "^0.0.50",
3194
3160
  "@types/express": "^4.17.21",
3195
3161
  "@types/fs-extra": "^9.0.13",
3196
- "@types/jest": "^26.0.24",
3197
3162
  "@types/js-yaml": "^3.12.10",
3198
3163
  "@types/lodash.camelcase": "^4.3.9",
3199
3164
  "@types/lodash.upperfirst": "^4.3.9",
@@ -3204,13 +3169,13 @@ var package_default = {
3204
3169
  "@types/normalize-path": "^3.0.2",
3205
3170
  "@types/ws": "^7.4.7",
3206
3171
  "@types/yup": "^0.29.14",
3207
- jest: "^29.7.0",
3208
- "jest-diff": "^29.7.0",
3209
3172
  "jest-file-snapshot": "^0.5.0",
3210
- "jest-matcher-utils": "^29.7.0",
3211
3173
  "memory-level": "^1.0.0",
3212
3174
  nodemon: "3.1.4",
3213
- typescript: "^5.6.3"
3175
+ typescript: "^5.6.3",
3176
+ vite: "^4.3.9",
3177
+ vitest: "^0.32.2",
3178
+ zod: "^3.23.8"
3214
3179
  }
3215
3180
  };
3216
3181
 
@@ -3225,7 +3190,7 @@ var createSchema = async ({
3225
3190
  if (flags && flags.length > 0) {
3226
3191
  meta["flags"] = flags;
3227
3192
  }
3228
- return new import_schema_tools2.TinaSchema({
3193
+ return new import_schema_tools3.TinaSchema({
3229
3194
  version: {
3230
3195
  fullVersion: package_default.version,
3231
3196
  major,
@@ -3723,7 +3688,7 @@ var import_path2 = __toESM(require("path"));
3723
3688
  var import_toml = __toESM(require("@iarna/toml"));
3724
3689
  var import_js_yaml = __toESM(require("js-yaml"));
3725
3690
  var import_gray_matter = __toESM(require("gray-matter"));
3726
- var import_schema_tools3 = require("@tinacms/schema-tools");
3691
+ var import_schema_tools4 = require("@tinacms/schema-tools");
3727
3692
  var import_micromatch = __toESM(require("micromatch"));
3728
3693
  var import_path = __toESM(require("path"));
3729
3694
 
@@ -3936,7 +3901,7 @@ var scanAllContent = async (tinaSchema, bridge, callback) => {
3936
3901
  const filesSeen = /* @__PURE__ */ new Map();
3937
3902
  const duplicateFiles = /* @__PURE__ */ new Set();
3938
3903
  await sequential(tinaSchema.getCollections(), async (collection) => {
3939
- const normalPath = (0, import_schema_tools3.normalizePath)(collection.path);
3904
+ const normalPath = (0, import_schema_tools4.normalizePath)(collection.path);
3940
3905
  const format = collection.format || "md";
3941
3906
  const documentPaths = await bridge.glob(normalPath, format);
3942
3907
  const matches = tinaSchema.getMatches({ collection });
@@ -4048,7 +4013,7 @@ var getTemplateForFile = (templateInfo, data) => {
4048
4013
  throw new Error(`Unable to determine template`);
4049
4014
  };
4050
4015
  var loadAndParseWithAliases = async (bridge, filepath, collection, templateInfo) => {
4051
- const dataString = await bridge.get((0, import_schema_tools3.normalizePath)(filepath));
4016
+ const dataString = await bridge.get((0, import_schema_tools4.normalizePath)(filepath));
4052
4017
  const data = parseFile(
4053
4018
  dataString,
4054
4019
  import_path.default.extname(filepath),
@@ -4070,6 +4035,9 @@ var loadAndParseWithAliases = async (bridge, filepath, collection, templateInfo)
4070
4035
 
4071
4036
  // src/database/datalayer.ts
4072
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__";
4073
4041
  var DEFAULT_NUMERIC_LPAD = 4;
4074
4042
  var applyPadding = (input, pad) => {
4075
4043
  if (pad) {
@@ -4527,7 +4495,7 @@ var FolderTreeBuilder = class {
4527
4495
  return this._tree;
4528
4496
  }
4529
4497
  update(documentPath, collectionPath) {
4530
- let folderPath = import_path2.default.dirname((0, import_schema_tools3.normalizePath)(documentPath));
4498
+ let folderPath = import_path2.default.dirname((0, import_schema_tools4.normalizePath)(documentPath));
4531
4499
  if (folderPath === ".") {
4532
4500
  folderPath = "";
4533
4501
  }
@@ -4540,7 +4508,7 @@ var FolderTreeBuilder = class {
4540
4508
  if (!this._tree[current2]) {
4541
4509
  this._tree[current2] = /* @__PURE__ */ new Set();
4542
4510
  }
4543
- this._tree[current2].add((0, import_schema_tools3.normalizePath)(import_path2.default.join(current2, part)));
4511
+ this._tree[current2].add((0, import_schema_tools4.normalizePath)(import_path2.default.join(current2, part)));
4544
4512
  parent.push(part);
4545
4513
  });
4546
4514
  const current = parent.join("/");
@@ -4643,6 +4611,41 @@ var makeIndexOpsForDocument = (filepath, collection, indexDefinitions, data, opT
4643
4611
  }
4644
4612
  return result;
4645
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 (references2[ref]) {
4630
+ references2[ref].push(path7);
4631
+ } else {
4632
+ references2[ref] = [path7];
4633
+ }
4634
+ }
4635
+ for (const ref of Object.keys(references2)) {
4636
+ for (const path7 of references2[ref]) {
4637
+ result.push({
4638
+ type: opType,
4639
+ key: `${ref}${INDEX_KEY_FIELD_SEPARATOR}${path7}${INDEX_KEY_FIELD_SEPARATOR}${filepath}`,
4640
+ sublevel: refSublevel,
4641
+ value: opType === "put" ? {} : void 0
4642
+ });
4643
+ }
4644
+ }
4645
+ }
4646
+ }
4647
+ return result;
4648
+ };
4646
4649
  var makeStringEscaper = (regex, replacement) => {
4647
4650
  return (input) => {
4648
4651
  if (Array.isArray(input)) {
@@ -5260,17 +5263,15 @@ var Resolver = class {
5260
5263
  await this.deleteDocument(realPath);
5261
5264
  if (await this.hasReferences(realPath, collection)) {
5262
5265
  const collRefs = await this.findReferences(realPath, collection);
5263
- for (const [collection2, refFields] of Object.entries(collRefs)) {
5264
- for (const [refPath, refs] of Object.entries(refFields)) {
5265
- let refDoc = await this.getRaw(refPath);
5266
- for (const ref of refs) {
5267
- refDoc = updateObjectWithJsonPath(
5268
- refDoc,
5269
- ref.path.join("."),
5270
- null
5271
- );
5266
+ for (const [collection2, docsWithRefs] of Object.entries(collRefs)) {
5267
+ for (const [pathToDocWithRef, referencePaths] of Object.entries(
5268
+ docsWithRefs
5269
+ )) {
5270
+ let refDoc = await this.getRaw(pathToDocWithRef);
5271
+ for (const path7 of referencePaths) {
5272
+ refDoc = updateObjectWithJsonPath(refDoc, path7, null);
5272
5273
  }
5273
- await this.database.put(refPath, refDoc, collection2);
5274
+ await this.database.put(pathToDocWithRef, refDoc, collection2);
5274
5275
  }
5275
5276
  }
5276
5277
  }
@@ -5293,17 +5294,19 @@ var Resolver = class {
5293
5294
  await this.database.put(newRealPath, doc._rawData, collection.name);
5294
5295
  await this.deleteDocument(realPath);
5295
5296
  const collRefs = await this.findReferences(realPath, collection);
5296
- for (const [collection2, refFields] of Object.entries(collRefs)) {
5297
- for (const [refPath, refs] of Object.entries(refFields)) {
5298
- let refDoc = await this.getRaw(refPath);
5299
- for (const ref of refs) {
5300
- refDoc = updateObjectWithJsonPath(
5301
- refDoc,
5302
- ref.path.join("."),
5297
+ for (const [collection2, docsWithRefs] of Object.entries(collRefs)) {
5298
+ for (const [pathToDocWithRef, referencePaths] of Object.entries(
5299
+ docsWithRefs
5300
+ )) {
5301
+ let docWithRef = await this.getRaw(pathToDocWithRef);
5302
+ for (const path7 of referencePaths) {
5303
+ docWithRef = updateObjectWithJsonPath(
5304
+ docWithRef,
5305
+ path7,
5303
5306
  newRealPath
5304
5307
  );
5305
5308
  }
5306
- await this.database.put(refPath, refDoc, collection2);
5309
+ await this.database.put(pathToDocWithRef, docWithRef, collection2);
5307
5310
  }
5308
5311
  }
5309
5312
  return this.getDocument(newRealPath);
@@ -5435,35 +5438,30 @@ var Resolver = class {
5435
5438
  */
5436
5439
  this.hasReferences = async (id, c) => {
5437
5440
  let count = 0;
5438
- const deepRefs = this.tinaSchema.findReferences(c.name);
5439
- for (const [collection, refs] of Object.entries(deepRefs)) {
5440
- for (const ref of refs) {
5441
- await this.database.query(
5442
- {
5443
- collection,
5444
- filterChain: makeFilterChain({
5445
- conditions: [
5446
- {
5447
- filterPath: ref.path.join("."),
5448
- filterExpression: {
5449
- _type: "reference",
5450
- _list: false,
5451
- eq: id
5452
- }
5453
- }
5454
- ]
5455
- }),
5456
- sort: ref.field.name
5457
- },
5458
- (refId) => {
5459
- count++;
5460
- return refId;
5461
- }
5462
- );
5463
- if (count) {
5464
- return true;
5465
- }
5441
+ await this.database.query(
5442
+ {
5443
+ collection: c.name,
5444
+ filterChain: makeFilterChain({
5445
+ conditions: [
5446
+ {
5447
+ filterPath: REFS_REFERENCE_FIELD,
5448
+ filterExpression: {
5449
+ _type: "string",
5450
+ _list: false,
5451
+ eq: id
5452
+ }
5453
+ }
5454
+ ]
5455
+ }),
5456
+ sort: REFS_COLLECTIONS_SORT_KEY
5457
+ },
5458
+ (refId) => {
5459
+ count++;
5460
+ return refId;
5466
5461
  }
5462
+ );
5463
+ if (count) {
5464
+ return true;
5467
5465
  }
5468
5466
  return false;
5469
5467
  };
@@ -5471,46 +5469,41 @@ var Resolver = class {
5471
5469
  * Finds references to a document
5472
5470
  * @param id the id of the document to find references to
5473
5471
  * @param c the collection to find references in
5474
- * @returns references to the document in the form of a map of collection names to a list of fields that reference the document
5472
+ * @returns a map of references to the document
5475
5473
  */
5476
5474
  this.findReferences = async (id, c) => {
5477
5475
  const references = {};
5478
- const deepRefs = this.tinaSchema.findReferences(c.name);
5479
- for (const [collection, refs] of Object.entries(deepRefs)) {
5480
- for (const ref of refs) {
5481
- await this.database.query(
5482
- {
5483
- collection,
5484
- filterChain: makeFilterChain({
5485
- conditions: [
5486
- {
5487
- filterPath: ref.path.join("."),
5488
- filterExpression: {
5489
- _type: "reference",
5490
- _list: false,
5491
- eq: id
5492
- }
5493
- }
5494
- ]
5495
- }),
5496
- sort: ref.field.name
5497
- },
5498
- (refId) => {
5499
- if (!references[collection]) {
5500
- references[collection] = {};
5501
- }
5502
- if (!references[collection][refId]) {
5503
- references[collection][refId] = [];
5476
+ await this.database.query(
5477
+ {
5478
+ collection: c.name,
5479
+ filterChain: makeFilterChain({
5480
+ conditions: [
5481
+ {
5482
+ filterPath: REFS_REFERENCE_FIELD,
5483
+ filterExpression: {
5484
+ _type: "string",
5485
+ _list: false,
5486
+ eq: id
5487
+ }
5504
5488
  }
5505
- references[collection][refId].push({
5506
- path: ref.path,
5507
- field: ref.field
5508
- });
5509
- return refId;
5510
- }
5511
- );
5489
+ ]
5490
+ }),
5491
+ sort: REFS_COLLECTIONS_SORT_KEY
5492
+ },
5493
+ (refId, rawItem) => {
5494
+ if (!references[c.name]) {
5495
+ references[c.name] = {};
5496
+ }
5497
+ if (!references[c.name][refId]) {
5498
+ references[c.name][refId] = [];
5499
+ }
5500
+ const referencePath = rawItem == null ? void 0 : rawItem[REFS_PATH_FIELD];
5501
+ if (referencePath) {
5502
+ references[c.name][refId].push(referencePath);
5503
+ }
5504
+ return refId;
5512
5505
  }
5513
- }
5506
+ );
5514
5507
  return references;
5515
5508
  };
5516
5509
  this.buildFieldMutations = async (fieldParams, template, existingData) => {
@@ -6234,7 +6227,7 @@ var Database = class {
6234
6227
  const contentObject = await level.sublevel(
6235
6228
  CONTENT_ROOT_PREFIX,
6236
6229
  SUBLEVEL_OPTIONS
6237
- ).get((0, import_schema_tools3.normalizePath)(filepath));
6230
+ ).get((0, import_schema_tools4.normalizePath)(filepath));
6238
6231
  if (!contentObject) {
6239
6232
  throw new NotFoundError(`Unable to find record ${filepath}`);
6240
6233
  }
@@ -6246,6 +6239,7 @@ var Database = class {
6246
6239
  }
6247
6240
  };
6248
6241
  this.addPendingDocument = async (filepath, data) => {
6242
+ var _a;
6249
6243
  await this.initLevel();
6250
6244
  const dataFields = await this.formatBodyOnPayload(filepath, data);
6251
6245
  const collection = await this.collectionForPath(filepath);
@@ -6259,7 +6253,8 @@ var Database = class {
6259
6253
  );
6260
6254
  const indexDefinitions = await this.getIndexDefinitions(this.contentLevel);
6261
6255
  const collectionIndexDefinitions = indexDefinitions == null ? void 0 : indexDefinitions[collection.name];
6262
- const normalizedPath = (0, import_schema_tools3.normalizePath)(filepath);
6256
+ const collectionReferences = (_a = await this.getCollectionReferences()) == null ? void 0 : _a[collection.name];
6257
+ const normalizedPath = (0, import_schema_tools4.normalizePath)(filepath);
6263
6258
  if (!(collection == null ? void 0 : collection.isDetached)) {
6264
6259
  if (this.bridge) {
6265
6260
  await this.bridge.put(normalizedPath, stringifiedFile);
@@ -6287,6 +6282,14 @@ var Database = class {
6287
6282
  let delOps = [];
6288
6283
  if (!isGitKeep(normalizedPath, collection)) {
6289
6284
  putOps = [
6285
+ ...makeRefOpsForDocument(
6286
+ normalizedPath,
6287
+ collection == null ? void 0 : collection.name,
6288
+ collectionReferences,
6289
+ dataFields,
6290
+ "put",
6291
+ level
6292
+ ),
6290
6293
  ...makeIndexOpsForDocument(
6291
6294
  normalizedPath,
6292
6295
  collection == null ? void 0 : collection.name,
@@ -6310,6 +6313,14 @@ var Database = class {
6310
6313
  SUBLEVEL_OPTIONS
6311
6314
  ).get(normalizedPath);
6312
6315
  delOps = existingItem ? [
6316
+ ...makeRefOpsForDocument(
6317
+ normalizedPath,
6318
+ collection == null ? void 0 : collection.name,
6319
+ collectionReferences,
6320
+ existingItem,
6321
+ "del",
6322
+ level
6323
+ ),
6313
6324
  ...makeIndexOpsForDocument(
6314
6325
  normalizedPath,
6315
6326
  collection == null ? void 0 : collection.name,
@@ -6345,7 +6356,7 @@ var Database = class {
6345
6356
  await level.batch(ops);
6346
6357
  };
6347
6358
  this.put = async (filepath, data, collectionName) => {
6348
- var _a, _b;
6359
+ var _a, _b, _c;
6349
6360
  await this.initLevel();
6350
6361
  try {
6351
6362
  if (SYSTEM_FILES.includes(filepath)) {
@@ -6358,13 +6369,14 @@ var Database = class {
6358
6369
  );
6359
6370
  collectionIndexDefinitions = indexDefinitions == null ? void 0 : indexDefinitions[collectionName];
6360
6371
  }
6361
- const normalizedPath = (0, import_schema_tools3.normalizePath)(filepath);
6372
+ const collectionReferences = (_a = await this.getCollectionReferences()) == null ? void 0 : _a[collectionName];
6373
+ const normalizedPath = (0, import_schema_tools4.normalizePath)(filepath);
6362
6374
  const dataFields = await this.formatBodyOnPayload(filepath, data);
6363
6375
  const collection = await this.collectionForPath(filepath);
6364
6376
  if (!collection) {
6365
6377
  throw new import_graphql6.GraphQLError(`Unable to find collection for ${filepath}.`);
6366
6378
  }
6367
- if (((_a = collection.match) == null ? void 0 : _a.exclude) || ((_b = collection.match) == null ? void 0 : _b.include)) {
6379
+ if (((_b = collection.match) == null ? void 0 : _b.exclude) || ((_c = collection.match) == null ? void 0 : _c.include)) {
6368
6380
  const matches = this.tinaSchema.getMatches({ collection });
6369
6381
  const match = import_micromatch2.default.isMatch(filepath, matches);
6370
6382
  if (!match) {
@@ -6405,6 +6417,14 @@ var Database = class {
6405
6417
  let delOps = [];
6406
6418
  if (!isGitKeep(normalizedPath, collection)) {
6407
6419
  putOps = [
6420
+ ...makeRefOpsForDocument(
6421
+ normalizedPath,
6422
+ collectionName,
6423
+ collectionReferences,
6424
+ dataFields,
6425
+ "put",
6426
+ level
6427
+ ),
6408
6428
  ...makeIndexOpsForDocument(
6409
6429
  normalizedPath,
6410
6430
  collectionName,
@@ -6428,6 +6448,14 @@ var Database = class {
6428
6448
  SUBLEVEL_OPTIONS
6429
6449
  ).get(normalizedPath);
6430
6450
  delOps = existingItem ? [
6451
+ ...makeRefOpsForDocument(
6452
+ normalizedPath,
6453
+ collectionName,
6454
+ collectionReferences,
6455
+ existingItem,
6456
+ "del",
6457
+ level
6458
+ ),
6431
6459
  ...makeIndexOpsForDocument(
6432
6460
  normalizedPath,
6433
6461
  collectionName,
@@ -6532,7 +6560,7 @@ var Database = class {
6532
6560
  };
6533
6561
  this.getLookup = async (returnType) => {
6534
6562
  await this.initLevel();
6535
- const lookupPath = (0, import_schema_tools3.normalizePath)(
6563
+ const lookupPath = (0, import_schema_tools4.normalizePath)(
6536
6564
  import_node_path.default.join(this.getGeneratedFolder(), `_lookup.json`)
6537
6565
  );
6538
6566
  if (!this._lookup) {
@@ -6545,7 +6573,7 @@ var Database = class {
6545
6573
  };
6546
6574
  this.getGraphQLSchema = async () => {
6547
6575
  await this.initLevel();
6548
- const graphqlPath = (0, import_schema_tools3.normalizePath)(
6576
+ const graphqlPath = (0, import_schema_tools4.normalizePath)(
6549
6577
  import_node_path.default.join(this.getGeneratedFolder(), `_graphql.json`)
6550
6578
  );
6551
6579
  return await this.contentLevel.sublevel(
@@ -6558,7 +6586,7 @@ var Database = class {
6558
6586
  if (!this.bridge) {
6559
6587
  throw new Error(`No bridge configured`);
6560
6588
  }
6561
- const graphqlPath = (0, import_schema_tools3.normalizePath)(
6589
+ const graphqlPath = (0, import_schema_tools4.normalizePath)(
6562
6590
  import_node_path.default.join(this.getGeneratedFolder(), `_graphql.json`)
6563
6591
  );
6564
6592
  const _graphql = await this.bridge.get(graphqlPath);
@@ -6566,7 +6594,7 @@ var Database = class {
6566
6594
  };
6567
6595
  this.getTinaSchema = async (level) => {
6568
6596
  await this.initLevel();
6569
- const schemaPath = (0, import_schema_tools3.normalizePath)(
6597
+ const schemaPath = (0, import_schema_tools4.normalizePath)(
6570
6598
  import_node_path.default.join(this.getGeneratedFolder(), `_schema.json`)
6571
6599
  );
6572
6600
  return await (level || this.contentLevel).sublevel(
@@ -6582,7 +6610,7 @@ var Database = class {
6582
6610
  const schema = existingSchema || await this.getTinaSchema(level || this.contentLevel);
6583
6611
  if (!schema) {
6584
6612
  throw new Error(
6585
- `Unable to get schema from level db: ${(0, import_schema_tools3.normalizePath)(
6613
+ `Unable to get schema from level db: ${(0, import_schema_tools4.normalizePath)(
6586
6614
  import_node_path.default.join(this.getGeneratedFolder(), `_schema.json`)
6587
6615
  )}`
6588
6616
  );
@@ -6590,6 +6618,22 @@ var Database = class {
6590
6618
  this.tinaSchema = await createSchema({ schema });
6591
6619
  return this.tinaSchema;
6592
6620
  };
6621
+ this.getCollectionReferences = async (level) => {
6622
+ if (this.collectionReferences) {
6623
+ return this.collectionReferences;
6624
+ }
6625
+ const result = {};
6626
+ const schema = await this.getSchema(level || this.contentLevel);
6627
+ const collections = schema.getCollections();
6628
+ for (const collection of collections) {
6629
+ const collectionReferences = this.tinaSchema.findReferencesFromCollection(
6630
+ collection.name
6631
+ );
6632
+ result[collection.name] = collectionReferences;
6633
+ }
6634
+ this.collectionReferences = result;
6635
+ return result;
6636
+ };
6593
6637
  this.getIndexDefinitions = async (level) => {
6594
6638
  if (!this.collectionIndexDefinitions) {
6595
6639
  await new Promise(async (resolve2, reject) => {
@@ -6599,8 +6643,23 @@ var Database = class {
6599
6643
  const collections = schema.getCollections();
6600
6644
  for (const collection of collections) {
6601
6645
  const indexDefinitions = {
6602
- [DEFAULT_COLLECTION_SORT_KEY]: { fields: [] }
6646
+ [DEFAULT_COLLECTION_SORT_KEY]: { fields: [] },
6603
6647
  // provide a default sort key which is the file sort
6648
+ // pseudo-index for the collection's references
6649
+ [REFS_COLLECTIONS_SORT_KEY]: {
6650
+ fields: [
6651
+ {
6652
+ name: REFS_REFERENCE_FIELD,
6653
+ type: "string",
6654
+ list: false
6655
+ },
6656
+ {
6657
+ name: REFS_PATH_FIELD,
6658
+ type: "string",
6659
+ list: false
6660
+ }
6661
+ ]
6662
+ }
6604
6663
  };
6605
6664
  if (collection.fields) {
6606
6665
  for (const field of collection.fields) {
@@ -6752,29 +6811,36 @@ var Database = class {
6752
6811
  }
6753
6812
  startKey = startKey || key || "";
6754
6813
  endKey = key || "";
6755
- edges = [...edges, { cursor: key, path: filepath }];
6814
+ edges = [...edges, { cursor: key, path: filepath, value: itemRecord }];
6756
6815
  }
6757
6816
  return {
6758
- edges: await sequential(edges, async (edge) => {
6759
- try {
6760
- const node = await hydrator(edge.path);
6761
- return {
6762
- node,
6763
- cursor: btoa(edge.cursor)
6764
- };
6765
- } catch (error) {
6766
- console.log(error);
6767
- if (error instanceof Error && (!edge.path.includes(".tina/__generated__/_graphql.json") || !edge.path.includes("tina/__generated__/_graphql.json"))) {
6768
- throw new TinaQueryError({
6769
- originalError: error,
6770
- file: edge.path,
6771
- collection: collection.name,
6772
- stack: error.stack
6773
- });
6817
+ edges: await sequential(
6818
+ edges,
6819
+ async ({
6820
+ cursor,
6821
+ path: path7,
6822
+ value
6823
+ }) => {
6824
+ try {
6825
+ const node = await hydrator(path7, value);
6826
+ return {
6827
+ node,
6828
+ cursor: btoa(cursor)
6829
+ };
6830
+ } catch (error) {
6831
+ console.log(error);
6832
+ if (error instanceof Error && (!path7.includes(".tina/__generated__/_graphql.json") || !path7.includes("tina/__generated__/_graphql.json"))) {
6833
+ throw new TinaQueryError({
6834
+ originalError: error,
6835
+ file: path7,
6836
+ collection: collection.name,
6837
+ stack: error.stack
6838
+ });
6839
+ }
6840
+ throw error;
6774
6841
  }
6775
- throw error;
6776
6842
  }
6777
- }),
6843
+ ),
6778
6844
  pageInfo: {
6779
6845
  hasPreviousPage,
6780
6846
  hasNextPage,
@@ -6799,7 +6865,7 @@ var Database = class {
6799
6865
  try {
6800
6866
  lookup = lookupFromLockFile || JSON.parse(
6801
6867
  await this.bridge.get(
6802
- (0, import_schema_tools3.normalizePath)(
6868
+ (0, import_schema_tools4.normalizePath)(
6803
6869
  import_node_path.default.join(this.getGeneratedFolder(), "_lookup.json")
6804
6870
  )
6805
6871
  )
@@ -6824,15 +6890,15 @@ var Database = class {
6824
6890
  }
6825
6891
  const contentRootLevel = nextLevel.sublevel(CONTENT_ROOT_PREFIX, SUBLEVEL_OPTIONS);
6826
6892
  await contentRootLevel.put(
6827
- (0, import_schema_tools3.normalizePath)(import_node_path.default.join(this.getGeneratedFolder(), "_graphql.json")),
6893
+ (0, import_schema_tools4.normalizePath)(import_node_path.default.join(this.getGeneratedFolder(), "_graphql.json")),
6828
6894
  graphQLSchema
6829
6895
  );
6830
6896
  await contentRootLevel.put(
6831
- (0, import_schema_tools3.normalizePath)(import_node_path.default.join(this.getGeneratedFolder(), "_schema.json")),
6897
+ (0, import_schema_tools4.normalizePath)(import_node_path.default.join(this.getGeneratedFolder(), "_schema.json")),
6832
6898
  tinaSchema.schema
6833
6899
  );
6834
6900
  await contentRootLevel.put(
6835
- (0, import_schema_tools3.normalizePath)(import_node_path.default.join(this.getGeneratedFolder(), "_lookup.json")),
6901
+ (0, import_schema_tools4.normalizePath)(import_node_path.default.join(this.getGeneratedFolder(), "_lookup.json")),
6836
6902
  lookup
6837
6903
  );
6838
6904
  const result = await this._indexAllContent(
@@ -6914,18 +6980,20 @@ var Database = class {
6914
6980
  }
6915
6981
  };
6916
6982
  this.delete = async (filepath) => {
6983
+ var _a;
6917
6984
  await this.initLevel();
6918
6985
  const collection = await this.collectionForPath(filepath);
6919
6986
  if (!collection) {
6920
6987
  throw new Error(`No collection found for path: ${filepath}`);
6921
6988
  }
6922
6989
  const indexDefinitions = await this.getIndexDefinitions(this.contentLevel);
6990
+ const collectionReferences = (_a = await this.getCollectionReferences()) == null ? void 0 : _a[collection.name];
6923
6991
  const collectionIndexDefinitions = indexDefinitions == null ? void 0 : indexDefinitions[collection.name];
6924
6992
  let level = this.contentLevel;
6925
6993
  if (collection == null ? void 0 : collection.isDetached) {
6926
6994
  level = this.appLevel.sublevel(collection == null ? void 0 : collection.name, SUBLEVEL_OPTIONS);
6927
6995
  }
6928
- const normalizedPath = (0, import_schema_tools3.normalizePath)(filepath);
6996
+ const normalizedPath = (0, import_schema_tools4.normalizePath)(filepath);
6929
6997
  const rootSublevel = level.sublevel(
6930
6998
  CONTENT_ROOT_PREFIX,
6931
6999
  SUBLEVEL_OPTIONS
@@ -6938,6 +7006,14 @@ var Database = class {
6938
7006
  collection.path || ""
6939
7007
  );
6940
7008
  await this.contentLevel.batch([
7009
+ ...makeRefOpsForDocument(
7010
+ normalizedPath,
7011
+ collection.name,
7012
+ collectionReferences,
7013
+ item,
7014
+ "del",
7015
+ level
7016
+ ),
6941
7017
  ...makeIndexOpsForDocument(
6942
7018
  normalizedPath,
6943
7019
  collection.name,
@@ -7155,6 +7231,7 @@ var hashPasswordValues = async (data, passwordFields) => Promise.all(
7155
7231
  );
7156
7232
  var isGitKeep = (filepath, collection) => filepath.endsWith(`.gitkeep.${(collection == null ? void 0 : collection.format) || "md"}`);
7157
7233
  var _indexContent = async (database, level, documentPaths, enqueueOps, collection, passwordFields) => {
7234
+ var _a;
7158
7235
  let collectionIndexDefinitions;
7159
7236
  let collectionPath;
7160
7237
  if (collection) {
@@ -7165,6 +7242,7 @@ var _indexContent = async (database, level, documentPaths, enqueueOps, collectio
7165
7242
  }
7166
7243
  collectionPath = collection.path;
7167
7244
  }
7245
+ const collectionReferences = (_a = await database.getCollectionReferences()) == null ? void 0 : _a[collection == null ? void 0 : collection.name];
7168
7246
  const tinaSchema = await database.getSchema();
7169
7247
  let templateInfo = null;
7170
7248
  if (collection) {
@@ -7185,13 +7263,60 @@ var _indexContent = async (database, level, documentPaths, enqueueOps, collectio
7185
7263
  if (passwordFields == null ? void 0 : passwordFields.length) {
7186
7264
  await hashPasswordValues(aliasedData, passwordFields);
7187
7265
  }
7188
- const normalizedPath = (0, import_schema_tools3.normalizePath)(filepath);
7266
+ const normalizedPath = (0, import_schema_tools4.normalizePath)(filepath);
7267
+ const rootSublevel = level.sublevel(
7268
+ CONTENT_ROOT_PREFIX,
7269
+ SUBLEVEL_OPTIONS
7270
+ );
7189
7271
  const folderKey = folderTreeBuilder.update(
7190
7272
  normalizedPath,
7191
7273
  collectionPath || ""
7192
7274
  );
7275
+ const item = await rootSublevel.get(normalizedPath);
7276
+ if (item) {
7277
+ await database.contentLevel.batch([
7278
+ ...makeRefOpsForDocument(
7279
+ normalizedPath,
7280
+ collection == null ? void 0 : collection.name,
7281
+ collectionReferences,
7282
+ item,
7283
+ "del",
7284
+ level
7285
+ ),
7286
+ ...makeIndexOpsForDocument(
7287
+ normalizedPath,
7288
+ collection.name,
7289
+ collectionIndexDefinitions,
7290
+ item,
7291
+ "del",
7292
+ level
7293
+ ),
7294
+ // folder indices
7295
+ ...makeIndexOpsForDocument(
7296
+ normalizedPath,
7297
+ `${collection.name}_${folderKey}`,
7298
+ collectionIndexDefinitions,
7299
+ item,
7300
+ "del",
7301
+ level
7302
+ ),
7303
+ {
7304
+ type: "del",
7305
+ key: normalizedPath,
7306
+ sublevel: rootSublevel
7307
+ }
7308
+ ]);
7309
+ }
7193
7310
  if (!isGitKeep(filepath, collection)) {
7194
7311
  await enqueueOps([
7312
+ ...makeRefOpsForDocument(
7313
+ normalizedPath,
7314
+ collection == null ? void 0 : collection.name,
7315
+ collectionReferences,
7316
+ aliasedData,
7317
+ "put",
7318
+ level
7319
+ ),
7195
7320
  ...makeIndexOpsForDocument(
7196
7321
  normalizedPath,
7197
7322
  collection == null ? void 0 : collection.name,
@@ -7242,6 +7367,7 @@ var _indexContent = async (database, level, documentPaths, enqueueOps, collectio
7242
7367
  }
7243
7368
  };
7244
7369
  var _deleteIndexContent = async (database, documentPaths, enqueueOps, collection) => {
7370
+ var _a;
7245
7371
  if (!documentPaths.length) {
7246
7372
  return;
7247
7373
  }
@@ -7255,6 +7381,7 @@ var _deleteIndexContent = async (database, documentPaths, enqueueOps, collection
7255
7381
  throw new Error(`No indexDefinitions for collection ${collection.name}`);
7256
7382
  }
7257
7383
  }
7384
+ const collectionReferences = (_a = await database.getCollectionReferences()) == null ? void 0 : _a[collection == null ? void 0 : collection.name];
7258
7385
  const tinaSchema = await database.getSchema();
7259
7386
  let templateInfo = null;
7260
7387
  if (collection) {
@@ -7266,7 +7393,7 @@ var _deleteIndexContent = async (database, documentPaths, enqueueOps, collection
7266
7393
  );
7267
7394
  const folderTreeBuilder = new FolderTreeBuilder();
7268
7395
  await sequential(documentPaths, async (filepath) => {
7269
- const itemKey = (0, import_schema_tools3.normalizePath)(filepath);
7396
+ const itemKey = (0, import_schema_tools4.normalizePath)(filepath);
7270
7397
  const item = await rootLevel.get(itemKey);
7271
7398
  if (item) {
7272
7399
  const folderKey = folderTreeBuilder.update(
@@ -7278,6 +7405,14 @@ var _deleteIndexContent = async (database, documentPaths, enqueueOps, collection
7278
7405
  item
7279
7406
  ) : item;
7280
7407
  await enqueueOps([
7408
+ ...makeRefOpsForDocument(
7409
+ itemKey,
7410
+ collection == null ? void 0 : collection.name,
7411
+ collectionReferences,
7412
+ aliasedData,
7413
+ "del",
7414
+ database.contentLevel
7415
+ ),
7281
7416
  ...makeIndexOpsForDocument(
7282
7417
  itemKey,
7283
7418
  collection.name,
@@ -7353,14 +7488,14 @@ var getChangedFiles = async ({
7353
7488
  const rootDir = await findGitRoot(dir);
7354
7489
  let pathPrefix = "";
7355
7490
  if (rootDir !== dir) {
7356
- pathPrefix = (0, import_schema_tools3.normalizePath)(dir.substring(rootDir.length + 1));
7491
+ pathPrefix = (0, import_schema_tools4.normalizePath)(dir.substring(rootDir.length + 1));
7357
7492
  }
7358
7493
  await import_isomorphic_git.default.walk({
7359
7494
  fs: fs4,
7360
7495
  dir: rootDir,
7361
7496
  trees: [import_isomorphic_git.default.TREE({ ref: from }), import_isomorphic_git.default.TREE({ ref: to })],
7362
7497
  map: async function(filename, [A, B]) {
7363
- const relativePath = (0, import_schema_tools3.normalizePath)(filename).substring(pathPrefix.length);
7498
+ const relativePath = (0, import_schema_tools4.normalizePath)(filename).substring(pathPrefix.length);
7364
7499
  let matches = false;
7365
7500
  for (const [key, matcher] of Object.entries(pathFilter)) {
7366
7501
  if (relativePath.startsWith(key)) {