@coderich/autograph 0.13.11 → 0.13.12

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.11",
4
+ "version": "0.13.12",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -78,8 +78,9 @@ class Emitter extends EventEmitter {
78
78
  } : (event, next) => {
79
79
  if (arr.includes(`${event.query[prop]}`)) {
80
80
  if (once) this.removeListener(eventName, wrapper);
81
- next(listener(event, next));
81
+ return next(listener(event, next));
82
82
  }
83
+ return next();
83
84
  };
84
85
 
85
86
  return this.on(eventName, wrapper);
@@ -279,6 +279,10 @@ module.exports = class Resolver {
279
279
  const type = query.isMutation ? 'Mutation' : 'Query';
280
280
  const event = { schema: this.#schema, context: this.#context, resolver: this, query };
281
281
 
282
+ // Backwards compat
283
+ query.match = { ...query.where };
284
+ query.toObject = () => query;
285
+
282
286
  return Emitter.emit(`pre${type}`, event).then(async (resultEarly) => {
283
287
  if (resultEarly !== undefined) return resultEarly;
284
288
  if (Util.isEqual(query.changeset, { added: {}, updated: {}, deleted: {} })) return query.doc;
@@ -9,11 +9,13 @@ const Emitter = require('../data/Emitter');
9
9
 
10
10
  const operations = ['Query', 'Mutation', 'Subscription'];
11
11
  // const interfaceKinds = [Kind.INTERFACE_TYPE_DEFINITION, Kind.INTERFACE_TYPE_EXTENSION];
12
+ const scalarKinds = [Kind.SCALAR_TYPE_DEFINITION, Kind.SCALAR_TYPE_EXTENSION];
12
13
  const modelKinds = [Kind.OBJECT_TYPE_DEFINITION, Kind.OBJECT_TYPE_EXTENSION, Kind.INTERFACE_TYPE_DEFINITION, Kind.INTERFACE_TYPE_EXTENSION];
13
- const allowedKinds = modelKinds.concat(Kind.DOCUMENT, Kind.FIELD_DEFINITION, Kind.NON_NULL_TYPE, Kind.NAMED_TYPE, Kind.LIST_TYPE, Kind.DIRECTIVE);
14
+ const fieldKinds = [Kind.FIELD_DEFINITION].concat(scalarKinds);
15
+ const allowedKinds = modelKinds.concat(fieldKinds).concat(Kind.DOCUMENT, Kind.NON_NULL_TYPE, Kind.NAMED_TYPE, Kind.LIST_TYPE, Kind.DIRECTIVE);
14
16
  const pipelines = ['finalize', 'construct', 'restruct', 'instruct', 'normalize', 'serialize'];
15
17
  const inputPipelines = ['finalize', 'construct', 'instruct', 'normalize', 'serialize'];
16
- const scalars = ['ID', 'String', 'Float', 'Int', 'Boolean'];
18
+ // const scalars = ['ID', 'String', 'Float', 'Int', 'Boolean'];
17
19
 
18
20
  module.exports = class Schema {
19
21
  #config;
@@ -123,17 +125,17 @@ module.exports = class Schema {
123
125
  visit(this.#typeDefs, {
124
126
  enter: (node) => {
125
127
  const name = node.name?.value;
126
- if (!allowedKinds.includes(node.kind)) return false;
128
+ if (!allowedKinds.includes(node.kind) || operations.includes(name)) return false;
127
129
 
128
- if (modelKinds.includes(node.kind) && !operations.includes(name)) {
130
+ if (modelKinds.includes(node.kind)) {
129
131
  // this.#schema.types[name] = schema.getType(name);
130
132
 
131
133
  model = this.#schema.models[name] = {
132
134
  name,
133
135
  key: name,
134
136
  fields: {},
135
- crud: 'crud',
136
- scope: 'crud',
137
+ crud: 'crud', // For use when creating API Queries and Mutations
138
+ scope: 'crud', // For use when defining types (how it's field.model reference can be used)
137
139
  idField: 'id',
138
140
  isPersistable: true,
139
141
  source: this.#config.dataSources?.default,
@@ -141,16 +143,16 @@ module.exports = class Schema {
141
143
  directives: {},
142
144
  toString: () => name,
143
145
  };
144
- } else if (node.kind === Kind.FIELD_DEFINITION) {
146
+ } else if (fieldKinds.includes(node.kind)) {
145
147
  isField = true;
146
- field = model.fields[name] = {
148
+ field = {
147
149
  name,
148
150
  key: name,
149
- crud: 'crud',
150
151
  pipelines: pipelines.reduce((prev, key) => Object.assign(prev, { [key]: [] }), {}),
151
152
  directives: {},
152
153
  toString: () => name,
153
154
  };
155
+ if (model) model.fields[name] = field;
154
156
  } else if (node.kind === Kind.NON_NULL_TYPE) {
155
157
  field[isList ? 'isArrayRequired' : 'isRequired'] = true;
156
158
  } else if (node.kind === Kind.NAMED_TYPE) {
@@ -167,8 +169,8 @@ module.exports = class Schema {
167
169
 
168
170
  node.arguments.forEach((arg) => {
169
171
  const key = arg.name.value;
170
- const { value: val, values } = arg.value;
171
- const value = values ? values.map(n => n.value) : val;
172
+ const { value: val, values = { value: val }, kind } = arg.value;
173
+ const value = kind === 'NullValue' ? null : Util.map(values, n => n.value);
172
174
  target.directives[name][key] = value;
173
175
 
174
176
  if (name === directives.index) this.#schema.indexes[this.#schema.indexes.length - 1][key] = value;
@@ -227,7 +229,6 @@ module.exports = class Schema {
227
229
  case 'model-gqlScope': { model.crud = value; break; }
228
230
  case 'model-fieldScope': { model.scope = value; break; }
229
231
  case 'field-gqlScope': { field.crud = value; break; }
230
- case 'field-fieldScope': { field.scope = value; break; }
231
232
 
232
233
  // Pipelines
233
234
  default: {
@@ -243,7 +244,7 @@ module.exports = class Schema {
243
244
  return undefined; // Continue
244
245
  },
245
246
  leave: (node) => {
246
- if (modelKinds.includes(node.kind) && !operations.includes(node.name.value)) {
247
+ if (modelKinds.includes(node.kind)) {
247
248
  const $model = model;
248
249
  // const idField = $model.fields[$model.idField];
249
250
  // $model.primaryKey = Util.nvl(idField?.key, idField?.name, 'id');
@@ -308,11 +309,12 @@ module.exports = class Schema {
308
309
  // Field resolution comes first (unshift)
309
310
  thunks.unshift(($schema) => {
310
311
  $field.model = $schema.models[$field.type];
311
- $field.linkBy = $field.linkBy || $field.model?.idField;
312
+ $field.crud = Util.uvl($field.crud, $field.model?.scope, 'crud');
313
+ $field.linkBy ??= $field.model?.idField;
312
314
  $field.linkField = $field.isVirtual ? $model.fields[$model.idField] : $field;
313
315
  $field.isFKReference = !$field.isPrimaryKey && $field.model?.isMarkedModel && !$field.model?.isEmbedded;
316
+ // $field.isScalar = Boolean(!$field.model || scalars.includes($field.type));
314
317
  $field.isEmbedded = Boolean($field.model && !$field.isFKReference && !$field.isPrimaryKey);
315
- $field.isScalar = Boolean(!$field.model || scalars.includes($field.type));
316
318
 
317
319
  if ($field.isArray) $field.pipelines.normalize.unshift('toArray');
318
320
  if ($field.isPrimaryKey) $field.pipelines.serialize.unshift('$pk'); // Will create/convert to FK type always
@@ -444,7 +446,6 @@ module.exports = class Schema {
444
446
  ref: AutoGraphMixed # Specify the modelRef field's name (overrides isEmbedded)
445
447
  gqlScope: AutoGraphMixed # Dictate how GraphQL API behaves
446
448
  dalScope: AutoGraphMixed # Dictate how the DAL behaves
447
- fieldScope: AutoGraphMixed # Dictate how a FIELD may use me
448
449
  destruct: [AutoGraphPipelineEnum!]
449
450
  transform: [AutoGraphPipelineEnum!]
450
451
  deserialize: [AutoGraphPipelineEnum!]
@@ -466,9 +467,9 @@ module.exports = class Schema {
466
467
 
467
468
  static #api(schema) {
468
469
  // These models are for creating types
469
- const readModels = Object.values(schema.models).filter(model => model.crud?.includes('r'));
470
- const createModels = Object.values(schema.models).filter(model => model.crud?.includes('c'));
471
- const updateModels = Object.values(schema.models).filter(model => model.crud?.includes('u'));
470
+ const readModels = Object.values(schema.models).filter(model => [model.crud, model.scope].join()?.includes('r'));
471
+ const createModels = Object.values(schema.models).filter(model => [model.crud, model.scope].join()?.includes('c'));
472
+ const updateModels = Object.values(schema.models).filter(model => [model.crud, model.scope].join()?.includes('u'));
472
473
 
473
474
  // These are for defining schema queries/mutations
474
475
  const entityModels = Object.values(schema.models).filter(model => model.isEntity);
@@ -586,6 +587,47 @@ module.exports = class Schema {
586
587
  ): ${model}SubscriptionPayload!
587
588
  `)}
588
589
  }
590
+
591
+ ${subscriptionModels.map((model) => {
592
+ const fields = Object.values(model.fields).filter(field => field.crud?.includes('r'));
593
+
594
+ return `
595
+ input ${model}SubscriptionInputFilter {
596
+ when: [SubscriptionWhenEnum!]! = [preEvent, postEvent]
597
+ where: ${model}SubscriptionInputWhere! = {}
598
+ }
599
+
600
+ input ${model}SubscriptionInputWhere {
601
+ ${fields.map(field => `${field}: ${field.model?.isEntity ? `${field.model}InputWhere` : 'AutoGraphMixed'}`)}
602
+ }
603
+
604
+ type ${model}SubscriptionPayload {
605
+ event: ${model}SubscriptionPayloadEvent
606
+ query: ${model}SubscriptionQuery
607
+ }
608
+
609
+ type ${model}SubscriptionPayloadEvent {
610
+ crud: SubscriptionCrudEnum!
611
+ data: ${model}SubscriptionPayloadEventData!
612
+ }
613
+
614
+ type ${model}SubscriptionPayloadEventData {
615
+ ${fields.map(field => `${field}: ${Schema.#getGQLType(field)}`)}
616
+ }
617
+
618
+ interface ${model}SubscriptionQuery {
619
+ ${fields.map(field => `${field}: ${Schema.#getGQLType(field)}`)}
620
+ }
621
+
622
+ type ${model}Create implements ${model}SubscriptionQuery {
623
+ ${fields.map(field => `${field}: ${Schema.#getGQLType(field)}`)}
624
+ }
625
+
626
+ type ${model}Update implements ${model}SubscriptionQuery {
627
+ ${fields.map(field => `${field}: ${Schema.#getGQLType(field)}`)}
628
+ }
629
+ `;
630
+ })}
589
631
  ` : ''}
590
632
  `,
591
633
  resolvers: {