@coderich/autograph 0.13.23 → 0.13.24

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.23",
4
+ "version": "0.13.24",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -74,12 +74,14 @@ module.exports = class Pipeline {
74
74
 
75
75
  //
76
76
  Pipeline.define('$pk', (params) => {
77
- const value = get(params.query.doc, params.path) || params.value?.id || params.value;
77
+ const { pkField } = params.model;
78
+ const value = get(params.query.doc, params.path) || params.value?.[pkField] || params.value; // I "think" the get() is for embedded documents
78
79
  return Pipeline[params.field.id]({ ...params, value });
79
80
  }, { ignoreNull: false });
80
81
 
81
82
  Pipeline.define('$fk', (params) => {
82
- const value = params.value?.id || params.value;
83
+ const { fkField } = params.field;
84
+ const value = params.value?.[fkField] || params.value;
83
85
  return Pipeline[params.field.id]({ ...params, value });
84
86
  });
85
87
 
@@ -116,10 +118,10 @@ module.exports = class Pipeline {
116
118
  });
117
119
 
118
120
  //
119
- Pipeline.define('ensureId', ({ query, resolver, model, field, value }) => {
120
- const { type } = field;
121
+ Pipeline.define('ensureFK', ({ query, resolver, field, value }) => {
122
+ const { type, fkField } = field;
121
123
  const ids = Util.filterBy(Util.ensureArray(value), (a, b) => `${a}` === `${b}`);
122
- return resolver.match(type).flags(query.flags).where({ id: ids }).count().then((count) => {
124
+ return resolver.match(type).flags(query.flags).where({ [fkField]: ids }).count().then((count) => {
123
125
  if (count !== ids.length) throw Boom.notFound(`${type} Not Found`);
124
126
  });
125
127
  }, { itemize: false });
@@ -233,7 +233,7 @@ module.exports = class Resolver {
233
233
  }
234
234
  case 'lookup': {
235
235
  const field = self.toModel(model).fields[args[0]];
236
- const where = { [field.linkBy]: $doc[field.linkField.name] };
236
+ const where = field.isVirtual ? { [field.linkBy]: $doc[field.linkField] } : { [field.fkField]: $doc[field] };
237
237
  return self.match(field.model).where(where);
238
238
  }
239
239
  default: {
@@ -59,7 +59,7 @@ module.exports = class Schema {
59
59
 
60
60
  if (directive) {
61
61
  const arg = directive.arguments.find(({ name }) => name.value === 'decorate');
62
- const value = arg?.value.value || 'default';
62
+ const value = Util.uvl(Schema.#resolveNodeValue(arg?.value), 'default');
63
63
  const decorator = this.#config.decorators?.[value];
64
64
 
65
65
  if (decorator) {
@@ -214,6 +214,10 @@ module.exports = class Schema {
214
214
  break;
215
215
  }
216
216
  // Field specific directives
217
+ case `${directives.field}-fk`: {
218
+ target.fkField = value;
219
+ break;
220
+ }
217
221
  case `${directives.field}-default`: {
218
222
  target.defaultValue = value;
219
223
  break;
@@ -230,9 +234,14 @@ module.exports = class Schema {
230
234
  target.pipelines.normalize = target.pipelines.normalize.concat(value).filter(Boolean);
231
235
  break;
232
236
  }
237
+ case `${directives.link}-to`: {
238
+ target.linkTo = value;
239
+ target.isVirtual ??= true;
240
+ break;
241
+ }
233
242
  case `${directives.link}-by`: {
234
243
  target.linkBy = value;
235
- target.isVirtual = true;
244
+ target.isVirtual ??= true;
236
245
  break;
237
246
  }
238
247
  // Generic by target directives
@@ -339,8 +348,10 @@ module.exports = class Schema {
339
348
  thunks.unshift(($schema) => {
340
349
  $field.id ??= $model.id;
341
350
  $field.model = $schema.models[$field.type];
342
- $field.linkBy ??= $field.model?.pkField;
343
351
  $field.crud = Util.uvl($field.crud, $field.model?.scope, 'crud');
352
+ $field.linkTo ??= $field.model;
353
+ $field.linkBy ??= $field.linkTo?.pkField; // This defines join logic (below) for both straight+virtual references
354
+ $field.fkField ??= $field.model?.pkField; // This is the fkReference field for straight references
344
355
  $field.linkField = $field.isVirtual ? $model.fields[$model.pkField] : $field;
345
356
  $field.isFKReference = !$field.isPrimaryKey && $field.model?.isMarkedModel && !$field.model?.isEmbedded;
346
357
  $field.isEmbedded = Boolean($field.model && !$field.isFKReference && !$field.isPrimaryKey);
@@ -354,16 +365,16 @@ module.exports = class Schema {
354
365
 
355
366
  if ($field.isArray) $field.pipelines.normalize.unshift('toArray');
356
367
  if ($field.isPrimaryKey) $field.pipelines.serialize.unshift('$pk'); // Will create/convert to FK type always
357
- if ($field.isFKReference) $field.pipelines.serialize.unshift('$fk'); // Will convert to FK type IFF defined in payload
358
-
359
368
  if ($field.isRequired && $field.isPersistable && !$field.isVirtual) $field.pipelines.finalize.push('required');
369
+
360
370
  if ($field.isFKReference) {
361
371
  const to = $field.model.key;
362
372
  const on = $field.model.fields[$field.linkBy].key;
363
373
  const from = $field.linkField.key;
364
374
  const as = `join_${to}`;
365
375
  $field.join = { to, on, from, as };
366
- $field.pipelines.finalize.push('ensureId'); // Absolute Last
376
+ $field.pipelines.serialize.unshift('$fk'); // Will convert to FK type IFF defined in payload
377
+ $field.pipelines.finalize.push('ensureFK'); // Absolute Last
367
378
  }
368
379
  });
369
380
 
@@ -446,6 +457,8 @@ module.exports = class Schema {
446
457
  }
447
458
 
448
459
  static #resolveNodeValue(node) {
460
+ if (node == null) return node;
461
+
449
462
  switch (node.kind) {
450
463
  case 'NullValue': return null;
451
464
  case 'ListValue': return node.values.map(Schema.#resolveNodeValue);
@@ -493,6 +506,7 @@ module.exports = class Schema {
493
506
 
494
507
  directive @${field}(
495
508
  id: String # Specify the ID strategy (eg. "toObjectId")
509
+ fk: String # Specify the FK field (default model.pk)
496
510
  key: String # Specify db key
497
511
  persist: Boolean # Persist this field (default true)
498
512
  connection: Boolean # Treat this field as a connection type (default false - rolling this out slowly)