@coderich/autograph 0.13.28 → 0.13.30
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 +1 -1
- package/src/data/Pipeline.js +5 -4
- package/src/data/Resolver.js +18 -10
- package/src/schema/Schema.js +14 -11
package/package.json
CHANGED
package/src/data/Pipeline.js
CHANGED
|
@@ -67,14 +67,15 @@ module.exports = class Pipeline {
|
|
|
67
67
|
//
|
|
68
68
|
Pipeline.define('$pk', (params) => {
|
|
69
69
|
const { pkField } = params.model;
|
|
70
|
-
const
|
|
71
|
-
return
|
|
70
|
+
const v = get(params.query.doc, params.path) || params.value?.[pkField] || params.value; // I "think" the get() is for embedded documents
|
|
71
|
+
if (v == null) return params.field.generator({ ...params, value: v });
|
|
72
|
+
return Util.map(v, value => params.field.generator({ ...params, value }));
|
|
72
73
|
}, { ignoreNull: false });
|
|
73
74
|
|
|
74
75
|
Pipeline.define('$fk', (params) => {
|
|
75
76
|
const { fkField } = params.field;
|
|
76
|
-
const
|
|
77
|
-
return
|
|
77
|
+
const v = params.value?.[fkField] || params.value;
|
|
78
|
+
return Util.map(v, value => params.field.generator({ ...params, value }));
|
|
78
79
|
});
|
|
79
80
|
|
|
80
81
|
Pipeline.define('$default', ({ field: { defaultValue }, value }) => (value === undefined ? defaultValue : value), { ignoreNull: false });
|
package/src/data/Resolver.js
CHANGED
|
@@ -286,22 +286,17 @@ module.exports = class Resolver {
|
|
|
286
286
|
}
|
|
287
287
|
|
|
288
288
|
#createSystemEvent($query, thunk = () => {}) {
|
|
289
|
-
|
|
289
|
+
let query = $query.toObject();
|
|
290
290
|
const type = query.isMutation ? 'Mutation' : 'Query';
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
// Backwards compat
|
|
294
|
-
Object.assign(event, query);
|
|
295
|
-
query.match = query.where;
|
|
296
|
-
query.toObject = () => query;
|
|
297
|
-
event.merged = event.input;
|
|
298
|
-
event.input = event.args?.input;
|
|
291
|
+
let event = this.#createEvent(query);
|
|
299
292
|
|
|
300
293
|
return Emitter.emit(`pre${type}`, event).then(async (resultEarly) => {
|
|
301
294
|
if (resultEarly !== undefined) return resultEarly; // Nothing to validate/transform
|
|
302
295
|
// if (query.crud === 'update' && Util.isEqual({ added: {}, updated: {}, deleted: {} }, Util.changeset(query.doc, query.input))) return query.doc;
|
|
303
296
|
const tquery = await $query.transform(false);
|
|
304
|
-
|
|
297
|
+
query = tquery.toObject();
|
|
298
|
+
event = this.#createEvent(query);
|
|
299
|
+
if (query.isMutation) await Emitter.emit('validate', event);
|
|
305
300
|
return thunk(tquery);
|
|
306
301
|
}).then((result) => {
|
|
307
302
|
event.doc ??= result; // Case of create
|
|
@@ -314,6 +309,19 @@ module.exports = class Resolver {
|
|
|
314
309
|
});
|
|
315
310
|
}
|
|
316
311
|
|
|
312
|
+
#createEvent(query) {
|
|
313
|
+
const event = { schema: this.#schema, context: this.#context, resolver: this, query };
|
|
314
|
+
|
|
315
|
+
// Backwards compat
|
|
316
|
+
Object.assign(event, query);
|
|
317
|
+
query.match = query.where;
|
|
318
|
+
query.toObject = () => query;
|
|
319
|
+
event.merged = event.input;
|
|
320
|
+
event.input = event.args?.input;
|
|
321
|
+
|
|
322
|
+
return event;
|
|
323
|
+
}
|
|
324
|
+
|
|
317
325
|
static $loader(name, resolver, config) {
|
|
318
326
|
if (!name) return loaders;
|
|
319
327
|
if (!resolver) return loaders[name];
|
package/src/schema/Schema.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
const Util = require('@coderich/util');
|
|
4
4
|
const { Kind, parse, visit } = require('graphql');
|
|
5
|
-
const { mergeTypeDefs, mergeFields } = require('@graphql-tools/merge');
|
|
5
|
+
const { mergeTypeDefs, mergeFields, mergeDirectives } = require('@graphql-tools/merge');
|
|
6
6
|
const { isLeafValue, mergeDeep, fromGUID } = require('../service/AppService');
|
|
7
7
|
const Pipeline = require('../data/Pipeline');
|
|
8
8
|
const Emitter = require('../data/Emitter');
|
|
@@ -50,12 +50,12 @@ module.exports = class Schema {
|
|
|
50
50
|
* Decorate each marked @model with config-driven field decorators
|
|
51
51
|
*/
|
|
52
52
|
decorate() {
|
|
53
|
-
const { directives } = this.#config;
|
|
53
|
+
const { directives: { model } } = this.#config;
|
|
54
54
|
|
|
55
55
|
this.#typeDefs = visit(this.#typeDefs, {
|
|
56
56
|
enter: (node) => {
|
|
57
57
|
if (modelKinds.includes(node.kind) && !operations.includes(node.name.value)) {
|
|
58
|
-
const directive = node.directives.find(({ name }) => name.value ===
|
|
58
|
+
const directive = node.directives.find(({ name }) => name.value === model);
|
|
59
59
|
|
|
60
60
|
if (directive) {
|
|
61
61
|
const arg = directive.arguments.find(({ name }) => name.value === 'decorate');
|
|
@@ -63,8 +63,10 @@ module.exports = class Schema {
|
|
|
63
63
|
const decorator = this.#config.decorators?.[value];
|
|
64
64
|
|
|
65
65
|
if (decorator) {
|
|
66
|
-
const { fields } = parse(
|
|
66
|
+
const { fields, directives } = parse(decorator).definitions[0];
|
|
67
67
|
node.fields = mergeFields(node, node.fields, fields, { noLocation: true, onFieldTypeConflict: (f, a, b) => a });
|
|
68
|
+
const modelDirective = directives.find(({ name }) => name.value === model);
|
|
69
|
+
if (modelDirective) Object.assign(directive, mergeDirectives([directive], [modelDirective], { noLocation: true, onFieldTypeConflict: (f, a, b) => a })[0]);
|
|
68
70
|
return node;
|
|
69
71
|
}
|
|
70
72
|
}
|
|
@@ -139,6 +141,7 @@ module.exports = class Schema {
|
|
|
139
141
|
isPersistable: true,
|
|
140
142
|
source: this.#config.dataSources?.default,
|
|
141
143
|
loader: this.#config.dataLoaders?.default,
|
|
144
|
+
generator: this.#config.generators?.default,
|
|
142
145
|
pipelines: pipelines.reduce((prev, key) => Object.assign(prev, { [key]: [] }), {}),
|
|
143
146
|
directives: {},
|
|
144
147
|
toString: () => name,
|
|
@@ -247,6 +250,10 @@ module.exports = class Schema {
|
|
|
247
250
|
break;
|
|
248
251
|
}
|
|
249
252
|
// Generic by target directives
|
|
253
|
+
case `${directives.model}-id`: case `${directives.field}-id`: {
|
|
254
|
+
target.generator = this.#config.generators[value];
|
|
255
|
+
break;
|
|
256
|
+
}
|
|
250
257
|
case `${directives.model}-persist`: case `${directives.field}-persist`: {
|
|
251
258
|
target.isPersistable = value;
|
|
252
259
|
break;
|
|
@@ -255,10 +262,8 @@ module.exports = class Schema {
|
|
|
255
262
|
target[key] = Util.nvl(value, '');
|
|
256
263
|
break;
|
|
257
264
|
}
|
|
258
|
-
case `${directives.model}-id`:
|
|
259
265
|
case `${directives.model}-key`:
|
|
260
266
|
case `${directives.model}-meta`:
|
|
261
|
-
case `${directives.field}-id`:
|
|
262
267
|
case `${directives.field}-key`:
|
|
263
268
|
case `${directives.field}-onDelete`: {
|
|
264
269
|
target[key] = value;
|
|
@@ -287,8 +292,6 @@ module.exports = class Schema {
|
|
|
287
292
|
if (modelKinds.includes(node.kind)) {
|
|
288
293
|
const $model = model;
|
|
289
294
|
|
|
290
|
-
model.id ??= model.source?.id;
|
|
291
|
-
|
|
292
295
|
// Model resolution after field resolution (push)
|
|
293
296
|
thunks.push(($schema) => {
|
|
294
297
|
$model.isEntity = Boolean($model.isMarkedModel && !$model.isEmbedded);
|
|
@@ -348,7 +351,6 @@ module.exports = class Schema {
|
|
|
348
351
|
|
|
349
352
|
// Field resolution comes first (unshift)
|
|
350
353
|
thunks.unshift(($schema) => {
|
|
351
|
-
$field.id ??= $model.id;
|
|
352
354
|
$field.model = $schema.models[$field.type];
|
|
353
355
|
$field.crud = Util.uvl($field.crud, $field.model?.scope, 'crud');
|
|
354
356
|
$field.linkTo ??= $field.model;
|
|
@@ -358,6 +360,7 @@ module.exports = class Schema {
|
|
|
358
360
|
$field.isFKReference = !$field.isPrimaryKey && $field.model?.isMarkedModel && !$field.model?.isEmbedded;
|
|
359
361
|
$field.isEmbedded = Boolean($field.model && !$field.isFKReference && !$field.isPrimaryKey);
|
|
360
362
|
$field.isScalar = scalars.includes($field.type);
|
|
363
|
+
$field.generator ??= $model.generator;
|
|
361
364
|
|
|
362
365
|
// Merge Enums and Scalar type definitions
|
|
363
366
|
const enumer = this.#schema.enums[$field.type];
|
|
@@ -487,7 +490,7 @@ module.exports = class Schema {
|
|
|
487
490
|
enum AutoGraphPipelineEnum { ${Object.keys(Pipeline).filter(k => !k.startsWith('$')).join(' ')} }
|
|
488
491
|
|
|
489
492
|
directive @${model}(
|
|
490
|
-
id: String # Specify the
|
|
493
|
+
id: String # Specify the generator strategy (default: "default")
|
|
491
494
|
pk: String # Specify the PK field (default "id")
|
|
492
495
|
key: String # Specify db table/collection name
|
|
493
496
|
crud: AutoGraphMixed # CRUD API
|
|
@@ -510,7 +513,7 @@ module.exports = class Schema {
|
|
|
510
513
|
) on OBJECT | INTERFACE
|
|
511
514
|
|
|
512
515
|
directive @${field}(
|
|
513
|
-
id: String # Specify the
|
|
516
|
+
id: String # Specify the generator strategy (default: "default")
|
|
514
517
|
fk: String # Specify the FK field (default model.pk)
|
|
515
518
|
key: String # Specify db key
|
|
516
519
|
persist: Boolean # Persist this field (default true)
|