@tinacms/graphql 0.59.8 → 0.59.11

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
@@ -11398,7 +11398,12 @@ var Builder = class {
11398
11398
  documentsType
11399
11399
  ]
11400
11400
  });
11401
- return astBuilder.FieldDefinition({ type, name: name2, args, required: true });
11401
+ return astBuilder.FieldDefinition({
11402
+ type,
11403
+ name: name2,
11404
+ args,
11405
+ required: true
11406
+ });
11402
11407
  };
11403
11408
  this.buildMultiCollectionDefinition = async (collections) => {
11404
11409
  const name2 = "getCollections";
@@ -11539,6 +11544,25 @@ var Builder = class {
11539
11544
  type: astBuilder.TYPES.MultiCollectionDocument
11540
11545
  });
11541
11546
  };
11547
+ this.buildDeleteCollectionDocumentMutation = async (collections) => {
11548
+ return astBuilder.FieldDefinition({
11549
+ name: "deleteDocument",
11550
+ args: [
11551
+ astBuilder.InputValueDefinition({
11552
+ name: "collection",
11553
+ required: false,
11554
+ type: astBuilder.TYPES.String
11555
+ }),
11556
+ astBuilder.InputValueDefinition({
11557
+ name: "relativePath",
11558
+ required: true,
11559
+ type: astBuilder.TYPES.String
11560
+ })
11561
+ ],
11562
+ required: true,
11563
+ type: astBuilder.TYPES.MultiCollectionDocument
11564
+ });
11565
+ };
11542
11566
  this.multiCollectionDocumentList = async (collections) => {
11543
11567
  return this._buildMultiCollectionDocumentListDefinition({
11544
11568
  fieldName: "getDocumentList",
@@ -11902,6 +11926,11 @@ var Builder = class {
11902
11926
  astBuilder.InputValueDefinition({
11903
11927
  name: "exists",
11904
11928
  type: astBuilder.TYPES.Boolean
11929
+ }),
11930
+ astBuilder.InputValueDefinition({
11931
+ name: "in",
11932
+ type: astBuilder.TYPES.Number,
11933
+ list: true
11905
11934
  })
11906
11935
  ]
11907
11936
  })
@@ -11927,6 +11956,11 @@ var Builder = class {
11927
11956
  astBuilder.InputValueDefinition({
11928
11957
  name: "exists",
11929
11958
  type: astBuilder.TYPES.Boolean
11959
+ }),
11960
+ astBuilder.InputValueDefinition({
11961
+ name: "in",
11962
+ type: astBuilder.TYPES.String,
11963
+ list: true
11930
11964
  })
11931
11965
  ]
11932
11966
  })
@@ -11949,6 +11983,11 @@ var Builder = class {
11949
11983
  astBuilder.InputValueDefinition({
11950
11984
  name: "exists",
11951
11985
  type: astBuilder.TYPES.Boolean
11986
+ }),
11987
+ astBuilder.InputValueDefinition({
11988
+ name: "in",
11989
+ type: astBuilder.TYPES.String,
11990
+ list: true
11952
11991
  })
11953
11992
  ]
11954
11993
  })
@@ -12086,7 +12125,7 @@ var Builder = class {
12086
12125
  fields: await sequential(collections, async (collection2) => {
12087
12126
  return astBuilder.InputValueDefinition({
12088
12127
  name: collection2.name,
12089
- type: await this._filterCollectionDocumentType(collection2)
12128
+ type: NAMER.dataFilterTypeName(collection2.namespace)
12090
12129
  });
12091
12130
  })
12092
12131
  })
@@ -12256,6 +12295,10 @@ var listArgs = [
12256
12295
  astBuilder.InputValueDefinition({
12257
12296
  name: "last",
12258
12297
  type: astBuilder.TYPES.Number
12298
+ }),
12299
+ astBuilder.InputValueDefinition({
12300
+ name: "sort",
12301
+ type: astBuilder.TYPES.String
12259
12302
  })
12260
12303
  ];
12261
12304
  var filterSelections = (arr) => {
@@ -12370,7 +12413,7 @@ var validateField = async (field) => {
12370
12413
 
12371
12414
  // pnp:/home/runner/work/tinacms/tinacms/packages/@tinacms/graphql/package.json
12372
12415
  var name = "@tinacms/graphql";
12373
- var version = "0.59.8";
12416
+ var version = "0.59.11";
12374
12417
  var main = "dist/index.js";
12375
12418
  var typings = "dist/index.d.ts";
12376
12419
  var files = [
@@ -12416,6 +12459,7 @@ var scripts = {
12416
12459
  };
12417
12460
  var dependencies = {
12418
12461
  "@graphql-tools/relay-operation-optimizer": "^6.4.1",
12462
+ "@tinacms/datalayer": "workspace:*",
12419
12463
  "body-parser": "^1.19.0",
12420
12464
  cors: "^2.8.5",
12421
12465
  dataloader: "^2.0.0",
@@ -12431,6 +12475,7 @@ var dependencies = {
12431
12475
  "graphql-type-json": "^0.3.2",
12432
12476
  "gray-matter": "^4.0.2",
12433
12477
  "js-yaml": "^3.14.0",
12478
+ leveldown: "^6.1.0",
12434
12479
  lodash: "^4.17.20",
12435
12480
  mdast: "^3.0.0",
12436
12481
  "mdast-util-from-markdown": "^1.0.0",
@@ -12438,7 +12483,6 @@ var dependencies = {
12438
12483
  "mdast-util-mdx-expression": "^1.1.0",
12439
12484
  "mdast-util-to-markdown": "^1.2.1",
12440
12485
  "micromark-extension-mdxjs": "^1.0.0",
12441
- mocha: "^9.1.1",
12442
12486
  "normalize-path": "^3.0.0",
12443
12487
  prettier: "^2.2.1",
12444
12488
  "rehype-format": "^3.1.0",
@@ -12473,7 +12517,6 @@ var devDependencies = {
12473
12517
  "@types/fs-extra": "^9.0.2",
12474
12518
  "@types/jest": "^26.0.4",
12475
12519
  "@types/js-yaml": "^3.12.5",
12476
- "@types/level": "^6.0.0",
12477
12520
  "@types/lodash": "^4.14.161",
12478
12521
  "@types/lodash.camelcase": "^4.3.6",
12479
12522
  "@types/lodash.upperfirst": "^4.3.6",
@@ -12771,6 +12814,7 @@ var _buildSchema = async (builder, tinaSchema) => {
12771
12814
  queryTypeDefinitionFields.push(await builder.multiCollectionDocument(collections));
12772
12815
  mutationTypeDefinitionFields.push(await builder.addMultiCollectionDocumentMutation());
12773
12816
  mutationTypeDefinitionFields.push(await builder.buildUpdateCollectionDocumentMutation(collections));
12817
+ mutationTypeDefinitionFields.push(await builder.buildDeleteCollectionDocumentMutation(collections));
12774
12818
  mutationTypeDefinitionFields.push(await builder.buildCreateCollectionDocumentMutation(collections));
12775
12819
  queryTypeDefinitionFields.push(await builder.multiCollectionDocumentList(collections));
12776
12820
  queryTypeDefinitionFields.push(await builder.multiCollectionDocumentFields());
@@ -20128,7 +20172,7 @@ var parseMDXInner = (tree, field) => {
20128
20172
  if (!template) {
20129
20173
  if ((0, import_lodash4.isNull)(node.name)) {
20130
20174
  } else {
20131
- throw new Error(`Found unregistered JSX or HTML: <${node.name}>. Please ensure all structured elements have been registered with your schema.`);
20175
+ throw new Error(`Found unregistered JSX or HTML: <${node.name}>. Please ensure all structured elements have been registered with your schema. https://tina.io/docs/editing/mdx/`);
20132
20176
  }
20133
20177
  }
20134
20178
  if (node.children.length > 0) {
@@ -20357,6 +20401,7 @@ var defaultNodeTypes = {
20357
20401
  delete_mark: plateElements.MARK_STRIKETHROUGH,
20358
20402
  inline_code_mark: plateElements.ELEMENT_CODE_LINE,
20359
20403
  thematic_break: plateElements.ELEMENT_HR,
20404
+ break: "break",
20360
20405
  image: plateElements.ELEMENT_IMAGE
20361
20406
  };
20362
20407
  function remarkToSlate(node) {
@@ -20454,6 +20499,8 @@ function remarkToSlate(node) {
20454
20499
  return __spreadProps(__spreadValues({}, node), {
20455
20500
  children: void 0
20456
20501
  });
20502
+ case "break":
20503
+ return { type: types.break, children: [{ type: "text", text: "" }] };
20457
20504
  default:
20458
20505
  console.log("unknown", node);
20459
20506
  return { type: "text", text: "" };
@@ -22247,6 +22294,10 @@ ${out}
22247
22294
  } catch (e) {
22248
22295
  console.log(e);
22249
22296
  }
22297
+ case "break":
22298
+ return {
22299
+ type: "break"
22300
+ };
22250
22301
  case "text":
22251
22302
  if (node == null ? void 0 : node.code) {
22252
22303
  return {
@@ -22273,7 +22324,102 @@ ${out}
22273
22324
  };
22274
22325
 
22275
22326
  // pnp:/home/runner/work/tinacms/tinacms/packages/@tinacms/graphql/src/resolver/index.ts
22276
- var import_flat = __toModule(require("flat"));
22327
+ var import_datalayer = __toModule(require("@tinacms/datalayer"));
22328
+
22329
+ // pnp:/home/runner/work/tinacms/tinacms/packages/@tinacms/graphql/src/resolver/filter-utils.ts
22330
+ var resolveReferences = async (filter, fields, resolver2) => {
22331
+ for (const fieldKey of Object.keys(filter)) {
22332
+ const fieldDefinition = fields.find((f) => f.name === fieldKey);
22333
+ if (fieldDefinition) {
22334
+ if (fieldDefinition.type === "reference") {
22335
+ const { edges, values } = await resolver2(filter, fieldDefinition);
22336
+ if (edges.length === 1) {
22337
+ filter[fieldKey] = {
22338
+ eq: values[0]
22339
+ };
22340
+ } else if (edges.length > 1) {
22341
+ filter[fieldKey] = {
22342
+ in: values
22343
+ };
22344
+ } else {
22345
+ filter[fieldKey] = {
22346
+ eq: "___null___"
22347
+ };
22348
+ }
22349
+ } else if (fieldDefinition.type === "object") {
22350
+ if (fieldDefinition.templates) {
22351
+ const globalTemplates = {};
22352
+ for (const template of fieldDefinition.templates) {
22353
+ if (typeof template === "string") {
22354
+ globalTemplates[template] = 1;
22355
+ }
22356
+ }
22357
+ for (const templateName of Object.keys(filter[fieldKey])) {
22358
+ if (templateName in globalTemplates) {
22359
+ throw new Error("Global templates not yet supported for queries");
22360
+ }
22361
+ const template = fieldDefinition.templates.find((template2) => !(typeof template2 === "string") && template2.name === templateName);
22362
+ if (template) {
22363
+ await resolveReferences(filter[fieldKey][templateName], template.fields, resolver2);
22364
+ } else {
22365
+ throw new Error(`Template ${templateName} not found`);
22366
+ }
22367
+ }
22368
+ } else {
22369
+ await resolveReferences(filter[fieldKey], fieldDefinition.fields, resolver2);
22370
+ }
22371
+ }
22372
+ } else {
22373
+ throw new Error(`Unable to find field ${fieldKey}`);
22374
+ }
22375
+ }
22376
+ };
22377
+ var collectConditionsForChildFields = (filterNode, fields, pathExpression, collectCondition) => {
22378
+ for (const childFieldName of Object.keys(filterNode)) {
22379
+ const childField = fields.find((field) => field.name === childFieldName);
22380
+ if (!childField) {
22381
+ throw new Error(`Unable to find type for field ${childFieldName}`);
22382
+ }
22383
+ collectConditionsForField(childFieldName, childField, filterNode[childFieldName], pathExpression, collectCondition);
22384
+ }
22385
+ };
22386
+ var collectConditionsForObjectField = (fieldName, field, filterNode, pathExpression, collectCondition) => {
22387
+ if (field.list && field.templates) {
22388
+ const globalTemplates = {};
22389
+ for (const template of field.templates) {
22390
+ if (typeof template === "string") {
22391
+ globalTemplates[template] = 1;
22392
+ }
22393
+ }
22394
+ for (const [filterKey, childFilterNode] of Object.entries(filterNode)) {
22395
+ if (filterKey in globalTemplates) {
22396
+ throw new Error("Global templates not yet supported for queries");
22397
+ }
22398
+ const template = field.templates.find((template2) => !(typeof template2 === "string") && template2.name === filterKey);
22399
+ const jsonPath = `${fieldName}[?(@._template=="${filterKey}")]`;
22400
+ const filterPath = pathExpression ? `${pathExpression}.${jsonPath}` : jsonPath;
22401
+ collectConditionsForChildFields(childFilterNode, template.fields, filterPath, collectCondition);
22402
+ }
22403
+ } else {
22404
+ const jsonPath = `${fieldName}${field.list ? "[*]" : ""}`;
22405
+ const filterPath = pathExpression ? `${pathExpression}.${jsonPath}` : `${jsonPath}`;
22406
+ collectConditionsForChildFields(filterNode, field.fields, filterPath, collectCondition);
22407
+ }
22408
+ };
22409
+ var collectConditionsForField = (fieldName, field, filterNode, pathExpression, collectCondition) => {
22410
+ if (field.type === "object") {
22411
+ collectConditionsForObjectField(fieldName, field, filterNode, pathExpression, collectCondition);
22412
+ } else {
22413
+ collectCondition({
22414
+ filterPath: pathExpression ? `${pathExpression}.${fieldName}` : fieldName,
22415
+ filterExpression: __spreadValues({
22416
+ _type: field.type
22417
+ }, filterNode)
22418
+ });
22419
+ }
22420
+ };
22421
+
22422
+ // pnp:/home/runner/work/tinacms/tinacms/packages/@tinacms/graphql/src/resolver/index.ts
22277
22423
  var createResolver2 = (args) => {
22278
22424
  return new Resolver(args);
22279
22425
  };
@@ -22302,11 +22448,13 @@ var Resolver = class {
22302
22448
  data: rawData,
22303
22449
  collection
22304
22450
  });
22305
- const basename = import_path3.default.basename(fullPath);
22306
- const extension2 = import_path3.default.extname(fullPath);
22307
- const filename = basename.replace(extension2, "");
22451
+ const {
22452
+ base: basename,
22453
+ ext: extension2,
22454
+ name: filename
22455
+ } = import_path3.default.parse(fullPath);
22308
22456
  const relativePath = fullPath.replace("\\", "/").replace(collection.path, "").replace(/^\/|\/$/g, "");
22309
- const breadcrumbs = filename.split("/");
22457
+ const breadcrumbs = relativePath.replace(extension2, "").split("/");
22310
22458
  const form = {
22311
22459
  label: collection.label,
22312
22460
  name: basename,
@@ -22346,6 +22494,12 @@ var Resolver = class {
22346
22494
  throw e;
22347
22495
  }
22348
22496
  };
22497
+ this.deleteDocument = async (fullPath) => {
22498
+ if (typeof fullPath !== "string") {
22499
+ throw new Error(`fullPath must be of type string for getDocument request`);
22500
+ }
22501
+ await this.database.delete(fullPath);
22502
+ };
22349
22503
  this.getDocumentFields = async () => {
22350
22504
  try {
22351
22505
  const response = {};
@@ -22470,7 +22624,7 @@ var Resolver = class {
22470
22624
  return this.getDocument(realPath);
22471
22625
  }
22472
22626
  const params = this.buildObjectMutations(args.params[collection.name], collection);
22473
- await this.database.put(realPath, params);
22627
+ await this.database.put(realPath, params, collection.name);
22474
22628
  return this.getDocument(realPath);
22475
22629
  };
22476
22630
  this.updateResolveDocument = async ({
@@ -22487,7 +22641,7 @@ var Resolver = class {
22487
22641
  case "object":
22488
22642
  if (params2) {
22489
22643
  const values = this.buildFieldMutations(params2, templateInfo.template);
22490
- await this.database.put(realPath, values);
22644
+ await this.database.put(realPath, values, collection.name);
22491
22645
  }
22492
22646
  break;
22493
22647
  case "union":
@@ -22500,14 +22654,14 @@ var Resolver = class {
22500
22654
  const values = __spreadProps(__spreadValues({}, this.buildFieldMutations(templateParams, template)), {
22501
22655
  _template: lastItem(template.namespace)
22502
22656
  });
22503
- await this.database.put(realPath, values);
22657
+ await this.database.put(realPath, values, collection.name);
22504
22658
  }
22505
22659
  });
22506
22660
  }
22507
22661
  return this.getDocument(realPath);
22508
22662
  }
22509
22663
  const params = this.buildObjectMutations(isCollectionSpecific ? args.params : args.params[collection.name], collection);
22510
- await this.database.put(realPath, params);
22664
+ await this.database.put(realPath, params, collection.name);
22511
22665
  return this.getDocument(realPath);
22512
22666
  };
22513
22667
  this.resolveDocument = async ({
@@ -22515,6 +22669,7 @@ var Resolver = class {
22515
22669
  collection: collectionName,
22516
22670
  isMutation,
22517
22671
  isCreation,
22672
+ isDeletion,
22518
22673
  isAddPendingDocument,
22519
22674
  isCollectionSpecific
22520
22675
  }) => {
@@ -22542,6 +22697,14 @@ var Resolver = class {
22542
22697
  isAddPendingDocument
22543
22698
  });
22544
22699
  }
22700
+ if (isDeletion) {
22701
+ if (!alreadyExists) {
22702
+ throw new Error(`Unable to delete document, ${realPath} does not exist`);
22703
+ }
22704
+ const doc = await this.getDocument(realPath);
22705
+ await this.deleteDocument(realPath);
22706
+ return doc;
22707
+ }
22545
22708
  if (alreadyExists === false) {
22546
22709
  throw new Error(`Unable to update document, ${realPath} does not exist`);
22547
22710
  }
@@ -22571,46 +22734,76 @@ var Resolver = class {
22571
22734
  const collection = this.tinaSchema.getCollection(collectionName);
22572
22735
  return this.database.store.glob(collection.path, this.getDocument);
22573
22736
  };
22737
+ this.referenceResolver = async (filter, fieldDefinition) => {
22738
+ const referencedCollection = this.tinaSchema.getCollection(fieldDefinition.collections[0]);
22739
+ if (!referencedCollection) {
22740
+ throw new Error(`Unable to find collection for ${fieldDefinition.collections[0]} querying ${fieldDefinition.name}`);
22741
+ }
22742
+ const sortKeys = Object.keys(filter[fieldDefinition.name][referencedCollection.name]);
22743
+ const resolvedCollectionConnection = await this.resolveCollectionConnection({
22744
+ args: {
22745
+ sort: sortKeys.length === 1 ? sortKeys[0] : void 0,
22746
+ filter: __spreadValues({}, filter[fieldDefinition.name][referencedCollection.name]),
22747
+ first: -1
22748
+ },
22749
+ collection: referencedCollection,
22750
+ hydrator: (path6) => path6
22751
+ });
22752
+ const { edges } = resolvedCollectionConnection;
22753
+ const values = edges.map((edge) => edge.node);
22754
+ return { edges, values };
22755
+ };
22574
22756
  this.resolveCollectionConnection = async ({
22575
22757
  args,
22576
- lookup
22758
+ collection,
22759
+ hydrator
22577
22760
  }) => {
22578
- let documents;
22579
- if (args.filter) {
22580
- const queries = [];
22581
- const flattenedArgs = (0, import_flat.default)(args.filter, { delimiter: "#" });
22582
- Object.entries(flattenedArgs).map(([key2, value]) => {
22583
- const keys2 = key2.split("#");
22584
- const maybeTemplateName = keys2[0];
22585
- const realKey = keys2.slice(0, keys2.length - 1).join("#");
22586
- const collection = this.tinaSchema.getCollection(lookup.collection);
22587
- let templateName = collection.name;
22588
- if (collection.templates) {
22589
- const template = collection.templates.find((template2) => {
22590
- if (typeof template2 === "string") {
22591
- throw new Error("Global templates not yet supported for queries");
22761
+ let edges;
22762
+ let pageInfo;
22763
+ if (args.filter || args.sort) {
22764
+ let conditions;
22765
+ if (args.filter) {
22766
+ if (collection.fields) {
22767
+ conditions = await this.resolveFilterConditions(args.filter, collection.fields, collection.name);
22768
+ } else if (collection.templates) {
22769
+ for (const templateName of Object.keys(args.filter)) {
22770
+ const template = collection.templates.find((template2) => template2.name === templateName);
22771
+ if (template) {
22772
+ conditions = await this.resolveFilterConditions(args.filter[templateName], template.fields, `${collection.name}.${templateName}`);
22773
+ } else {
22774
+ throw new Error(`Error template not found: ${templateName} in collection ${collection.name}`);
22592
22775
  }
22593
- return template2.name === maybeTemplateName;
22594
- });
22595
- if (typeof template === "string") {
22596
- throw new Error("Global templates not yet supported for queries");
22597
- }
22598
- if (template) {
22599
- templateName = template.name;
22600
22776
  }
22601
22777
  }
22602
- queries.push(`__attribute__${lookup.collection}#${templateName}#${realKey}#${value}`);
22603
- });
22604
- documents = await this.database.query(queries, this.getDocument);
22778
+ }
22779
+ const queryOptions = {
22780
+ filterChain: (0, import_datalayer.makeFilterChain)({
22781
+ conditions: conditions || []
22782
+ }),
22783
+ collection: collection.name,
22784
+ sort: args.sort,
22785
+ first: args.first,
22786
+ last: args.last,
22787
+ before: args.before,
22788
+ after: args.after
22789
+ };
22790
+ const result = await this.database.query(queryOptions, hydrator ? hydrator : this.getDocument);
22791
+ edges = result.edges;
22792
+ pageInfo = result.pageInfo;
22605
22793
  } else {
22606
- const collection = await this.tinaSchema.getCollection(lookup.collection);
22607
- documents = await this.database.store.glob(collection.path, this.getDocument);
22794
+ edges = (await this.database.store.glob(collection.path, this.getDocument)).map((document3) => ({
22795
+ node: document3
22796
+ }));
22608
22797
  }
22609
22798
  return {
22610
- totalCount: documents.length,
22611
- edges: documents.map((document3) => {
22612
- return { node: document3 };
22613
- })
22799
+ totalCount: edges.length,
22800
+ edges,
22801
+ pageInfo: pageInfo || {
22802
+ hasPreviousPage: false,
22803
+ hasNextPage: false,
22804
+ startCursor: "",
22805
+ endCursor: ""
22806
+ }
22614
22807
  };
22615
22808
  };
22616
22809
  this.buildFieldMutations = (fieldParams, template) => {
@@ -22744,6 +22937,7 @@ var Resolver = class {
22744
22937
  } = _d, field = __objRest(_d, [
22745
22938
  "namespace"
22746
22939
  ]);
22940
+ field.parentTypename = NAMER.dataTypeName(namespace.filter((_6, i) => i < namespace.length - 1));
22747
22941
  const extraFields = field.ui || {};
22748
22942
  switch (field.type) {
22749
22943
  case "number":
@@ -22871,6 +23065,27 @@ var Resolver = class {
22871
23065
  this.database = init.database;
22872
23066
  this.tinaSchema = init.tinaSchema;
22873
23067
  }
23068
+ async resolveFilterConditions(filter, fields, collectionName) {
23069
+ const conditions = [];
23070
+ const conditionCollector = (condition) => {
23071
+ if (!condition.filterPath) {
23072
+ throw new Error("Error parsing filter - unable to generate filterPath");
23073
+ }
23074
+ if (!condition.filterExpression) {
23075
+ throw new Error(`Error parsing filter - missing expression for ${condition.filterPath}`);
23076
+ }
23077
+ conditions.push(condition);
23078
+ };
23079
+ await resolveReferences(filter, fields, this.referenceResolver);
23080
+ for (const fieldName of Object.keys(filter)) {
23081
+ const field = fields.find((field2) => field2.name === fieldName);
23082
+ if (!field) {
23083
+ throw new Error(`${fieldName} not found in collection ${collectionName}`);
23084
+ }
23085
+ collectConditionsForField(fieldName, field, filter[fieldName], "", conditionCollector);
23086
+ }
23087
+ return conditions;
23088
+ }
22874
23089
  };
22875
23090
  var resolveDateInput = (value) => {
22876
23091
  const date = new Date(value);
@@ -23015,12 +23230,18 @@ var resolve = async ({
23015
23230
  isAddPendingDocument: true
23016
23231
  });
23017
23232
  }
23018
- if (["getDocument", "createDocument", "updateDocument"].includes(info.fieldName)) {
23233
+ if ([
23234
+ "getDocument",
23235
+ "createDocument",
23236
+ "updateDocument",
23237
+ "deleteDocument"
23238
+ ].includes(info.fieldName)) {
23019
23239
  const result2 = await resolver2.resolveDocument({
23020
23240
  args,
23021
23241
  collection: args.collection,
23022
23242
  isMutation,
23023
23243
  isCreation,
23244
+ isDeletion: info.fieldName === "deleteDocument",
23024
23245
  isAddPendingDocument: false,
23025
23246
  isCollectionSpecific: false
23026
23247
  });
@@ -23069,7 +23290,10 @@ var resolve = async ({
23069
23290
  }
23070
23291
  return result;
23071
23292
  case "collectionDocumentList":
23072
- return resolver2.resolveCollectionConnection({ args, lookup });
23293
+ return resolver2.resolveCollectionConnection({
23294
+ args,
23295
+ collection: tinaSchema.getCollection(lookup.collection)
23296
+ });
23073
23297
  case "unionData":
23074
23298
  return value;
23075
23299
  default:
@@ -23378,7 +23602,7 @@ var parseFile = (content3, format, yupSchema) => {
23378
23602
  };
23379
23603
 
23380
23604
  // pnp:/home/runner/work/tinacms/tinacms/packages/@tinacms/graphql/src/database/index.ts
23381
- var import_lodash7 = __toModule(require("lodash"));
23605
+ var import_datalayer2 = __toModule(require("@tinacms/datalayer"));
23382
23606
  var createDatabase = async (config) => {
23383
23607
  return new Database(__spreadProps(__spreadValues({}, config), {
23384
23608
  bridge: config.bridge,
@@ -23390,6 +23614,11 @@ var GENERATED_FOLDER = import_path4.default.join(".tina", "__generated__");
23390
23614
  var Database = class {
23391
23615
  constructor(config) {
23392
23616
  this.config = config;
23617
+ this.collectionForPath = async (filepath) => {
23618
+ const tinaSchema = await this.getSchema();
23619
+ const collection = tinaSchema.schema.collections.find((collection2) => filepath.startsWith(collection2.path));
23620
+ return collection;
23621
+ };
23393
23622
  this.get = async (filepath) => {
23394
23623
  if (SYSTEM_FILES.includes(filepath)) {
23395
23624
  throw new Error(`Unexpected get for config file ${filepath}`);
@@ -23429,27 +23658,39 @@ var Database = class {
23429
23658
  };
23430
23659
  this.addPendingDocument = async (filepath, data) => {
23431
23660
  const { stringifiedFile, payload, keepTemplateKey } = await this.stringifyFile(filepath, data);
23661
+ const collection = await this.collectionForPath(filepath);
23662
+ let collectionIndexDefinitions;
23663
+ if (collection) {
23664
+ const indexDefinitions = await this.getIndexDefinitions();
23665
+ collectionIndexDefinitions = indexDefinitions == null ? void 0 : indexDefinitions[collection.name];
23666
+ }
23432
23667
  if (this.store.supportsSeeding()) {
23433
23668
  await this.bridge.put(filepath, stringifiedFile);
23434
23669
  }
23435
- await this.store.put(filepath, payload, keepTemplateKey);
23670
+ await this.store.put(filepath, payload, {
23671
+ keepTemplateKey,
23672
+ collection: collection == null ? void 0 : collection.name,
23673
+ indexDefinitions: collectionIndexDefinitions
23674
+ });
23436
23675
  };
23437
- this.put = async (filepath, data) => {
23676
+ this.put = async (filepath, data, collection) => {
23438
23677
  if (SYSTEM_FILES.includes(filepath)) {
23439
23678
  throw new Error(`Unexpected put for config file ${filepath}`);
23440
23679
  } else {
23680
+ let collectionIndexDefinitions;
23681
+ if (collection) {
23682
+ const indexDefinitions = await this.getIndexDefinitions();
23683
+ collectionIndexDefinitions = indexDefinitions == null ? void 0 : indexDefinitions[collection];
23684
+ }
23441
23685
  const { stringifiedFile, payload, keepTemplateKey } = await this.stringifyFile(filepath, data);
23442
23686
  if (this.store.supportsSeeding()) {
23443
23687
  await this.bridge.put(filepath, stringifiedFile);
23444
23688
  }
23445
- if (this.store.supportsIndexing()) {
23446
- await indexDocument({
23447
- filepath,
23448
- data,
23449
- database: this
23450
- });
23451
- }
23452
- await this.store.put(filepath, payload, keepTemplateKey);
23689
+ await this.store.put(filepath, payload, {
23690
+ keepTemplateKey,
23691
+ collection,
23692
+ indexDefinitions: collectionIndexDefinitions
23693
+ });
23453
23694
  }
23454
23695
  return true;
23455
23696
  };
@@ -23536,6 +23777,56 @@ var Database = class {
23536
23777
  this.tinaSchema = await createSchema({ schema });
23537
23778
  return this.tinaSchema;
23538
23779
  };
23780
+ this.getIndexDefinitions = async () => {
23781
+ if (!this.collectionIndexDefinitions) {
23782
+ await new Promise(async (resolve2, reject) => {
23783
+ try {
23784
+ const schema = await this.getSchema();
23785
+ const collections = schema.getCollections();
23786
+ for (const collection of collections) {
23787
+ const indexDefinitions = {
23788
+ [import_datalayer2.DEFAULT_COLLECTION_SORT_KEY]: { fields: [] }
23789
+ };
23790
+ if (collection.fields) {
23791
+ for (const field of collection.fields) {
23792
+ if (field.indexed !== void 0 && field.indexed === false || field.type === "object") {
23793
+ continue;
23794
+ }
23795
+ indexDefinitions[field.name] = {
23796
+ fields: [
23797
+ {
23798
+ name: field.name,
23799
+ type: field.type,
23800
+ pad: field.type === "number" ? { fillString: "0", maxLength: import_datalayer2.DEFAULT_NUMERIC_LPAD } : void 0
23801
+ }
23802
+ ]
23803
+ };
23804
+ }
23805
+ }
23806
+ if (collection.indexes) {
23807
+ for (const index2 of collection.indexes) {
23808
+ indexDefinitions[index2.name] = {
23809
+ fields: index2.fields.map((indexField) => {
23810
+ var _a;
23811
+ return {
23812
+ name: indexField.name,
23813
+ type: (_a = collection.fields.find((field) => indexField.name === field.name)) == null ? void 0 : _a.type
23814
+ };
23815
+ })
23816
+ };
23817
+ }
23818
+ }
23819
+ this.collectionIndexDefinitions = this.collectionIndexDefinitions || {};
23820
+ this.collectionIndexDefinitions[collection.name] = indexDefinitions;
23821
+ }
23822
+ resolve2();
23823
+ } catch (err) {
23824
+ reject(err);
23825
+ }
23826
+ });
23827
+ }
23828
+ return this.collectionIndexDefinitions;
23829
+ };
23539
23830
  this.documentExists = async (fullpath) => {
23540
23831
  try {
23541
23832
  await this.get(fullpath);
@@ -23544,16 +23835,60 @@ var Database = class {
23544
23835
  }
23545
23836
  return true;
23546
23837
  };
23547
- this.query = async (queryStrings, hydrator) => {
23548
- return await this.store.query(queryStrings, hydrator);
23838
+ this.query = async (queryOptions, hydrator) => {
23839
+ const { first, after, last, before, sort, collection, filterChain } = queryOptions;
23840
+ const storeQueryOptions = {
23841
+ sort,
23842
+ collection,
23843
+ filterChain
23844
+ };
23845
+ if (first) {
23846
+ storeQueryOptions.limit = first;
23847
+ } else if (last) {
23848
+ storeQueryOptions.limit = last;
23849
+ } else {
23850
+ storeQueryOptions.limit = 10;
23851
+ }
23852
+ if (after) {
23853
+ storeQueryOptions.gt = (0, import_datalayer2.atob)(after);
23854
+ } else if (before) {
23855
+ storeQueryOptions.lt = (0, import_datalayer2.atob)(before);
23856
+ }
23857
+ if (last) {
23858
+ storeQueryOptions.reverse = true;
23859
+ }
23860
+ const indexDefinitions = await this.getIndexDefinitions();
23861
+ storeQueryOptions.indexDefinitions = indexDefinitions == null ? void 0 : indexDefinitions[queryOptions.collection];
23862
+ if (!storeQueryOptions.indexDefinitions) {
23863
+ throw new Error(`No indexDefinitions for collection ${queryOptions.collection}`);
23864
+ }
23865
+ const {
23866
+ edges,
23867
+ pageInfo: { hasPreviousPage, hasNextPage, startCursor, endCursor }
23868
+ } = await this.store.query(storeQueryOptions);
23869
+ return {
23870
+ edges: await sequential(edges, async (edge) => {
23871
+ const node = await hydrator(edge.path);
23872
+ return {
23873
+ node,
23874
+ cursor: (0, import_datalayer2.btoa)(edge.cursor)
23875
+ };
23876
+ }),
23877
+ pageInfo: {
23878
+ hasPreviousPage,
23879
+ hasNextPage,
23880
+ startCursor: (0, import_datalayer2.btoa)(startCursor),
23881
+ endCursor: (0, import_datalayer2.btoa)(endCursor)
23882
+ }
23883
+ };
23549
23884
  };
23550
23885
  this.putConfigFiles = async ({
23551
23886
  graphQLSchema,
23552
23887
  tinaSchema
23553
23888
  }) => {
23554
23889
  if (this.bridge.supportsBuilding()) {
23555
- await this.bridge.putConfig(import_path4.default.join(GENERATED_FOLDER, `_graphql.json`), JSON.stringify(graphQLSchema, null, 2));
23556
- await this.bridge.putConfig(import_path4.default.join(GENERATED_FOLDER, `_schema.json`), JSON.stringify(tinaSchema.schema, null, 2));
23890
+ await this.bridge.putConfig(import_path4.default.join(GENERATED_FOLDER, `_graphql.json`), JSON.stringify(graphQLSchema));
23891
+ await this.bridge.putConfig(import_path4.default.join(GENERATED_FOLDER, `_schema.json`), JSON.stringify(tinaSchema.schema));
23557
23892
  }
23558
23893
  };
23559
23894
  this.indexContent = async ({
@@ -23562,7 +23897,7 @@ var Database = class {
23562
23897
  }) => {
23563
23898
  const lookup = JSON.parse(await this.bridge.get(import_path4.default.join(GENERATED_FOLDER, "_lookup.json")));
23564
23899
  if (this.store.supportsSeeding()) {
23565
- this.store.clear();
23900
+ await this.store.clear();
23566
23901
  await this.store.seed(import_path4.default.join(GENERATED_FOLDER, "_graphql.json"), graphQLSchema);
23567
23902
  await this.store.seed(import_path4.default.join(GENERATED_FOLDER, "_schema.json"), tinaSchema.schema);
23568
23903
  await this.store.seed(import_path4.default.join(GENERATED_FOLDER, "_lookup.json"), lookup);
@@ -23573,14 +23908,39 @@ var Database = class {
23573
23908
  }
23574
23909
  }
23575
23910
  };
23911
+ this.deleteContentByPaths = async (documentPaths) => {
23912
+ const { pathsByCollection, nonCollectionPaths, collections } = await this.partitionPathsByCollection(documentPaths);
23913
+ for (const collection of Object.keys(pathsByCollection)) {
23914
+ await _deleteIndexContent(this, pathsByCollection[collection], collections[collection]);
23915
+ }
23916
+ await _deleteIndexContent(this, nonCollectionPaths, null);
23917
+ };
23576
23918
  this.indexContentByPaths = async (documentPaths) => {
23577
- await _indexContent(this, documentPaths);
23919
+ const { pathsByCollection, nonCollectionPaths, collections } = await this.partitionPathsByCollection(documentPaths);
23920
+ for (const collection of Object.keys(pathsByCollection)) {
23921
+ await _indexContent(this, pathsByCollection[collection], collections[collection]);
23922
+ }
23923
+ await _indexContent(this, nonCollectionPaths);
23924
+ };
23925
+ this.delete = async (filepath) => {
23926
+ const tinaSchema = await this.getSchema();
23927
+ const collection = tinaSchema.schema.collections.find((collection2) => filepath.startsWith(collection2.path));
23928
+ let collectionIndexDefinitions;
23929
+ if (collection) {
23930
+ const indexDefinitions = await this.getIndexDefinitions();
23931
+ collectionIndexDefinitions = indexDefinitions == null ? void 0 : indexDefinitions[collection.name];
23932
+ }
23933
+ await this.store.delete(filepath, {
23934
+ collection: collection.name,
23935
+ indexDefinitions: collectionIndexDefinitions
23936
+ });
23937
+ await this.bridge.delete(filepath);
23578
23938
  };
23579
23939
  this._indexAllContent = async () => {
23580
23940
  const tinaSchema = await this.getSchema();
23581
23941
  await sequential(tinaSchema.getCollections(), async (collection) => {
23582
23942
  const documentPaths = await this.bridge.glob(collection.path);
23583
- await _indexContent(this, documentPaths);
23943
+ await _indexContent(this, documentPaths, collection);
23584
23944
  });
23585
23945
  };
23586
23946
  this.addToLookupMap = async (lookup) => {
@@ -23594,147 +23954,75 @@ var Database = class {
23594
23954
  const updatedLookup = __spreadProps(__spreadValues({}, lookupMap), {
23595
23955
  [lookup.type]: lookup
23596
23956
  });
23597
- await this.bridge.putConfig(lookupPath, JSON.stringify(updatedLookup, null, 2));
23957
+ await this.bridge.putConfig(lookupPath, JSON.stringify(updatedLookup));
23598
23958
  };
23599
23959
  this.bridge = config.bridge;
23600
23960
  this.store = config.store;
23601
23961
  }
23962
+ async partitionPathsByCollection(documentPaths) {
23963
+ const pathsByCollection = {};
23964
+ const nonCollectionPaths = [];
23965
+ const collections = {};
23966
+ for (const documentPath of documentPaths) {
23967
+ const collection = await this.collectionForPath(documentPath);
23968
+ if (collection) {
23969
+ if (!pathsByCollection[collection.name]) {
23970
+ pathsByCollection[collection.name] = [];
23971
+ }
23972
+ collections[collection.name] = collection;
23973
+ pathsByCollection[collection.name].push(documentPath);
23974
+ } else {
23975
+ nonCollectionPaths.push(documentPath);
23976
+ }
23977
+ }
23978
+ return { pathsByCollection, nonCollectionPaths, collections };
23979
+ }
23602
23980
  };
23603
23981
  function hasOwnProperty2(obj, prop) {
23604
23982
  return obj.hasOwnProperty(prop);
23605
23983
  }
23606
- var _indexContent = async (database, documentPaths) => {
23984
+ var _indexContent = async (database, documentPaths, collection) => {
23985
+ let seedOptions = void 0;
23986
+ if (collection) {
23987
+ const indexDefinitions = await database.getIndexDefinitions();
23988
+ const collectionIndexDefinitions = indexDefinitions == null ? void 0 : indexDefinitions[collection.name];
23989
+ if (!collectionIndexDefinitions) {
23990
+ throw new Error(`No indexDefinitions for collection ${collection.name}`);
23991
+ }
23992
+ const numIndexes = Object.keys(collectionIndexDefinitions).length;
23993
+ if (numIndexes > 20) {
23994
+ throw new Error(`A maximum of 20 indexes are allowed per field. Currently collection ${collection.name} has ${numIndexes} indexes. Add 'indexed: false' to exclude a field from indexing.`);
23995
+ }
23996
+ seedOptions = {
23997
+ collection: collection.name,
23998
+ indexDefinitions: collectionIndexDefinitions
23999
+ };
24000
+ }
23607
24001
  await sequential(documentPaths, async (filepath) => {
23608
24002
  const dataString = await database.bridge.get(filepath);
23609
24003
  const data = parseFile(dataString, import_path4.default.extname(filepath), (yup3) => yup3.object({}));
23610
24004
  if (database.store.supportsSeeding()) {
23611
- await database.store.seed(filepath, data);
23612
- }
23613
- if (database.store.supportsIndexing()) {
23614
- return indexDocument({ filepath, data, database });
24005
+ await database.store.seed(filepath, data, seedOptions);
23615
24006
  }
23616
24007
  });
23617
24008
  };
23618
- var indexDocument = async ({
23619
- filepath,
23620
- data,
23621
- database
23622
- }) => {
23623
- var _a;
23624
- const schema = await database.getSchema();
23625
- const collection = await schema.getCollectionByFullPath(filepath);
23626
- let existingData;
23627
- try {
23628
- existingData = await database.get(filepath);
23629
- } catch (err) {
23630
- if (((_a = err.extensions) == null ? void 0 : _a["status"]) !== 404) {
23631
- throw err;
23632
- }
23633
- }
23634
- if (existingData) {
23635
- const attributesToFilterOut = await _indexCollectable({
23636
- record: filepath,
23637
- value: existingData,
23638
- field: collection,
23639
- prefix: collection.name,
23640
- database
23641
- });
23642
- await sequential(attributesToFilterOut, async (attribute) => {
23643
- const records = await database.store.get(attribute) || [];
23644
- await database.store.put(attribute, records.filter((item) => item !== filepath));
23645
- return true;
23646
- });
24009
+ var _deleteIndexContent = async (database, documentPaths, collection) => {
24010
+ let deleteOptions = void 0;
24011
+ if (collection) {
24012
+ const indexDefinitions = await database.getIndexDefinitions();
24013
+ const collectionIndexDefinitions = indexDefinitions == null ? void 0 : indexDefinitions[collection.name];
24014
+ if (!collectionIndexDefinitions) {
24015
+ throw new Error(`No indexDefinitions for collection ${collection.name}`);
24016
+ }
24017
+ deleteOptions = {
24018
+ collection: collection.name,
24019
+ indexDefinitions: collectionIndexDefinitions
24020
+ };
23647
24021
  }
23648
- const attributes = await _indexCollectable({
23649
- record: filepath,
23650
- field: collection,
23651
- value: data,
23652
- prefix: `${lastItem(collection.namespace)}`,
23653
- database
23654
- });
23655
- await sequential(attributes, async (fieldName) => {
23656
- const existingRecords = await database.store.get(fieldName) || [];
23657
- const uniqueItems = [...new Set([...existingRecords, filepath])];
23658
- await database.store.put(fieldName, uniqueItems);
23659
- });
23660
- };
23661
- var _indexCollectable = async (_a) => {
23662
- var _b = _a, {
23663
- field,
23664
- value
23665
- } = _b, rest = __objRest(_b, [
23666
- "field",
23667
- "value"
23668
- ]);
23669
- let template;
23670
- let extra = "";
23671
- if (field.templates) {
23672
- template = field.templates.find((t) => {
23673
- if (typeof t === "string") {
23674
- throw new Error(`Global templates not yet supported`);
23675
- }
23676
- if (hasOwnProperty2(value, "_template")) {
23677
- return t.name === value._template;
23678
- } else {
23679
- throw new Error(`Expected value for collectable with multiple templates to have property _template`);
23680
- }
23681
- });
23682
- extra = `#${lastItem(template.namespace)}`;
23683
- } else {
23684
- template = field;
23685
- }
23686
- const atts = await _indexAttributes({
23687
- record: rest.record,
23688
- data: value,
23689
- prefix: `${rest.prefix}${extra}#${template.name}`,
23690
- fields: template.fields,
23691
- database: rest.database
23692
- });
23693
- return (0, import_lodash7.flatten)(atts).filter((item) => !(0, import_lodash7.isBoolean)(item));
23694
- };
23695
- var _indexAttributes = async (_a) => {
23696
- var _b = _a, {
23697
- data,
23698
- fields
23699
- } = _b, rest = __objRest(_b, [
23700
- "data",
23701
- "fields"
23702
- ]);
23703
- return sequential(fields, async (field) => {
23704
- const value = data[field.name];
23705
- if (!value) {
23706
- return true;
23707
- }
23708
- switch (field.type) {
23709
- case "boolean":
23710
- case "string":
23711
- case "number":
23712
- case "datetime":
23713
- return _indexAttribute(__spreadValues({ value, field }, rest));
23714
- case "object":
23715
- if (field.list) {
23716
- await sequential(value, async (item) => {
23717
- return _indexCollectable(__spreadValues({ field, value: item }, rest));
23718
- });
23719
- } else {
23720
- return _indexCollectable(__spreadValues({ field, value }, rest));
23721
- }
23722
- return true;
23723
- case "reference":
23724
- return _indexAttribute(__spreadValues({ value, field }, rest));
23725
- }
23726
- return true;
24022
+ await sequential(documentPaths, async (filepath) => {
24023
+ database.store.delete(filepath, deleteOptions);
23727
24024
  });
23728
24025
  };
23729
- var _indexAttribute = async ({
23730
- value,
23731
- prefix,
23732
- field
23733
- }) => {
23734
- const stringValue = value.toString().substr(0, 100);
23735
- const fieldName = `__attribute__${prefix}#${field.name}#${stringValue}`;
23736
- return fieldName;
23737
- };
23738
24026
 
23739
24027
  // pnp:/home/runner/work/tinacms/tinacms/packages/@tinacms/graphql/src/index.ts
23740
24028
  var buildSchema = async (rootPath, database) => {