@coderich/autograph 0.13.106 → 0.13.107

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@coderich/autograph",
3
3
  "main": "index.js",
4
- "version": "0.13.106",
4
+ "version": "0.13.107",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -133,7 +133,6 @@ module.exports = class QueryResolver extends QueryBuilder {
133
133
  case 'cascade': return isArray ? txn.match(model).where(where).pull($path, id) : txn.match(model).where(where).remove();
134
134
  case 'nullify': return txn.match(model).where(where).save({ [$path]: null });
135
135
  case 'restrict': return txn.match(model).where(where).count().then(count => (count ? Promise.reject(new Error('Restricted')) : count));
136
- case 'defer': return Promise.resolve(); // Used for embedded models (could be improved)
137
136
  default: throw new Error(`Unknown onDelete operator: '${onDelete}'`);
138
137
  }
139
138
  }));
@@ -142,6 +142,7 @@ module.exports = class Schema {
142
142
  crud: 'crud', // For use when creating API Queries and Mutations
143
143
  scope: 'crud', // For use when defining types (how it's field.model reference can be used)
144
144
  pkField: 'id',
145
+ isEmbedded: true,
145
146
  isPersistable: true,
146
147
  source: this.#config.dataSources?.default,
147
148
  loader: this.#config.dataLoaders?.default,
@@ -156,6 +157,7 @@ module.exports = class Schema {
156
157
  },
157
158
  directives: {},
158
159
  ignorePaths: [],
160
+ referentialIntegrity: [],
159
161
  toString: () => name,
160
162
  };
161
163
  }
@@ -202,8 +204,12 @@ module.exports = class Schema {
202
204
  } else if (node.kind === Kind.DIRECTIVE) {
203
205
  target.directives[name] = target.directives[name] || {};
204
206
 
205
- if (name === directives.model) model.isMarkedModel = true;
206
- else if (name === directives.index) this.#schema.indexes.push({ model });
207
+ if (name === directives.model) {
208
+ model.isMarkedModel = true;
209
+ model.isEmbedded = false;
210
+ } else if (name === directives.index) {
211
+ this.#schema.indexes.push({ model });
212
+ }
207
213
 
208
214
  node.arguments.forEach((arg) => {
209
215
  const key = arg.name.value;
@@ -521,6 +527,9 @@ module.exports = class Schema {
521
527
  $field.isScalar = scalars.includes($field.type);
522
528
  $field.generator ??= $model.generator;
523
529
 
530
+ // Referential Integrity Setup
531
+ if ($field.onDelete) $field.model.referentialIntegrity.push(...this.#findModelPathsToField($model, $field));
532
+
524
533
  // Merge Enums and Scalar type definitions
525
534
  const enumer = this.#schema.enums[$field.type];
526
535
  const scalar = this.#schema.scalars[$field.type];
@@ -573,15 +582,6 @@ module.exports = class Schema {
573
582
  return { key, name, type, on };
574
583
  });
575
584
 
576
- // Resolve referential integrity
577
- const onDeleteFields = Array.from(new Set(Object.values(this.#schema.models).reduce((prev, curr) => {
578
- return prev.concat(Object.values(curr.fields).filter(el => el.onDelete)).flat();
579
- }, [])));
580
-
581
- Object.values(this.#schema.models).forEach(($model) => {
582
- $model.referentialIntegrity = Schema.#identifyOnDeletes(Object.values(this.#schema.models).filter(m => m.isEntity), onDeleteFields.filter(f => `${f.model}` === `${$model}`));
583
- });
584
-
585
585
  // Helper methods
586
586
  const resolvePathCache = {};
587
587
  this.#schema.resolvePath = (path, prop = 'key') => {
@@ -639,6 +639,23 @@ module.exports = class Schema {
639
639
  return this.#config.makeExecutableSchema(this.toObject());
640
640
  }
641
641
 
642
+ #findModelPathsToField(model, field) {
643
+ if (!model.isEmbedded) return [{ model, field, path: [`${field}`] }];
644
+
645
+ const arr = [];
646
+
647
+ Object.values(this.#schema.models).forEach((m) => {
648
+ Util.traverse(Object.values(m.fields), (f, info) => {
649
+ const path = info.path.concat(f.name);
650
+ if (f.isEmbedded) return { value: Object.values(f.model.fields), info: { path } };
651
+ if (f.type === model.name) arr.push({ model: m, field, path: path.concat(`${field}`) });
652
+ return null;
653
+ }, { path: [] });
654
+ });
655
+
656
+ return arr;
657
+ }
658
+
642
659
  static #resolveNodeValue(node) {
643
660
  if (node == null) return node;
644
661
 
@@ -661,7 +678,7 @@ module.exports = class Schema {
661
678
 
662
679
  enum AutoGraphIndexEnum { unique }
663
680
  enum AutoGraphAuthzEnum { private protected public } # DELETE WHEN MIGRATED
664
- enum AutoGraphOnDeleteEnum { cascade nullify restrict defer }
681
+ enum AutoGraphOnDeleteEnum { cascade nullify restrict }
665
682
  enum AutoGraphPipelineEnum { ${Object.keys(Pipeline).filter(k => !k.startsWith('$')).join(' ')} }
666
683
 
667
684
  directive @${model}(
@@ -961,26 +978,4 @@ module.exports = class Schema {
961
978
  before: String
962
979
  `;
963
980
  }
964
-
965
- static #findPathToField(model, field, path = []) {
966
- const { target, embeds } = Object.values(model.fields).reduce((prev, curr) => {
967
- if (curr === field) prev.target = curr;
968
- else if (curr.isEmbedded) prev.embeds.push(curr);
969
- return prev;
970
- }, { embeds: [] });
971
-
972
- if (target) return path.concat(target.name);
973
- if (embeds.length) return embeds.map(f => Schema.#findPathToField(f.model, field, path.concat(f.name))).filter(Boolean)[0];
974
- return undefined;
975
- }
976
-
977
- static #identifyOnDeletes(models, fields) {
978
- return models.map((model) => {
979
- return fields.map((field) => {
980
- const path = Schema.#findPathToField(model, field);
981
- if (!path) return null;
982
- return { model, field, path };
983
- });
984
- }).flat().filter(Boolean);
985
- }
986
981
  };