@coderich/autograph 0.13.45 → 0.13.46
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/Transformer.js +7 -1
- package/src/query/QueryResolver.js +9 -9
- package/src/schema/Schema.js +29 -17
package/package.json
CHANGED
package/src/data/Transformer.js
CHANGED
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
const Util = require('@coderich/util');
|
|
2
2
|
|
|
3
3
|
module.exports = class Transformer {
|
|
4
|
-
#config = {
|
|
4
|
+
#config = {
|
|
5
|
+
args: {}, // Arguments passed to each thunk
|
|
6
|
+
shape: {}, // The final shape
|
|
7
|
+
defaults: {}, // Default values applied at beginning of transformation
|
|
8
|
+
strictSchema: false, // If true, will strip away unknown attributes
|
|
9
|
+
keepUndefined: false, // If true, will preserve undefined values
|
|
10
|
+
};
|
|
5
11
|
|
|
6
12
|
#operation = {
|
|
7
13
|
set: (target, prop, startValue, proxy) => {
|
|
@@ -60,7 +60,7 @@ module.exports = class QueryResolver extends QueryBuilder {
|
|
|
60
60
|
case 'pullOne': {
|
|
61
61
|
return this.#get(query).then((doc) => {
|
|
62
62
|
const [key] = Object.keys(input);
|
|
63
|
-
const values = get(this.#model.transformers.input.transform(input), key);
|
|
63
|
+
const values = get(this.#model.transformers.input.transform(input), key, []);
|
|
64
64
|
const $input = { [key]: (get(doc, key) || []).filter(el => values.every(v => `${v}` !== `${el}`)) };
|
|
65
65
|
return this.#resolver.match(this.#model.name).id(doc.id).save($input);
|
|
66
66
|
});
|
|
@@ -109,17 +109,17 @@ module.exports = class QueryResolver extends QueryBuilder {
|
|
|
109
109
|
const { id } = query.toObject();
|
|
110
110
|
const txn = this.#resolver.transaction(false);
|
|
111
111
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
const
|
|
115
|
-
const $where = { [
|
|
112
|
+
return txn.run(Util.promiseChain(this.#model.referentialIntegrity.map(({ model, field, path }) => () => {
|
|
113
|
+
const { onDelete, isArray } = field;
|
|
114
|
+
const $path = path.join('.');
|
|
115
|
+
const $where = { [$path]: id };
|
|
116
116
|
|
|
117
|
-
switch (
|
|
118
|
-
case 'cascade': return isArray ? txn.match(model).where($where).pull(
|
|
119
|
-
case 'nullify': return txn.match(model).where($where).save({ [
|
|
117
|
+
switch (onDelete) {
|
|
118
|
+
case 'cascade': return isArray ? txn.match(model).where($where).pull($path, id) : txn.match(model).where($where).remove();
|
|
119
|
+
case 'nullify': return txn.match(model).where($where).save({ [$path]: null });
|
|
120
120
|
case 'restrict': return txn.match(model).where($where).count().then(count => (count ? Promise.reject(new Error('Restricted')) : count));
|
|
121
121
|
case 'defer': return Promise.resolve(); // Used for embedded models (could be improved)
|
|
122
|
-
default: throw new Error(`Unknown onDelete operator: '${
|
|
122
|
+
default: throw new Error(`Unknown onDelete operator: '${onDelete}'`);
|
|
123
123
|
}
|
|
124
124
|
})));
|
|
125
125
|
}
|
package/src/schema/Schema.js
CHANGED
|
@@ -129,6 +129,7 @@ module.exports = class Schema {
|
|
|
129
129
|
visit(this.#typeDefs, {
|
|
130
130
|
enter: (node) => {
|
|
131
131
|
const name = node.name?.value;
|
|
132
|
+
|
|
132
133
|
if (!allowedKinds.includes(node.kind) || operations.includes(name)) return false;
|
|
133
134
|
|
|
134
135
|
if (modelKinds.includes(node.kind)) {
|
|
@@ -424,8 +425,9 @@ module.exports = class Schema {
|
|
|
424
425
|
curr.name, // Rename key
|
|
425
426
|
a => Pipeline.$deserialize({ ...a, ...args, path: a.path.concat(curr.name) }),
|
|
426
427
|
];
|
|
428
|
+
|
|
427
429
|
if (curr.isArray) rules.unshift(({ value }) => (value == null ? value : Util.ensureArray(value)));
|
|
428
|
-
|
|
430
|
+
|
|
429
431
|
if (curr.isEmbedded) {
|
|
430
432
|
rules.unshift(a => Util.map(a.value, (value, i) => {
|
|
431
433
|
const path = a.path.concat(curr.name);
|
|
@@ -433,6 +435,7 @@ module.exports = class Schema {
|
|
|
433
435
|
return curr.model.transformers.doc.transform(value, { ...args, query: a.query, context: a.context, path });
|
|
434
436
|
}));
|
|
435
437
|
}
|
|
438
|
+
|
|
436
439
|
return Object.assign(prev, { [curr.key]: rules });
|
|
437
440
|
}, {}),
|
|
438
441
|
defaults: Object.values($model.fields).reduce((prev, curr) => {
|
|
@@ -450,6 +453,7 @@ module.exports = class Schema {
|
|
|
450
453
|
|
|
451
454
|
// Field resolution comes first (unshift)
|
|
452
455
|
thunks.unshift(($schema) => {
|
|
456
|
+
$field.parent = $model;
|
|
453
457
|
$field.model = $schema.models[$field.type];
|
|
454
458
|
$field.crud = Util.uvl($field.crud, $field.model?.scope, 'crud');
|
|
455
459
|
$field.linkTo ??= $field.model;
|
|
@@ -514,8 +518,12 @@ module.exports = class Schema {
|
|
|
514
518
|
});
|
|
515
519
|
|
|
516
520
|
// Resolve referential integrity
|
|
521
|
+
const onDeleteFields = Array.from(new Set(Object.values(this.#schema.models).reduce((prev, curr) => {
|
|
522
|
+
return prev.concat(Object.values(curr.fields).filter(el => el.onDelete)).flat();
|
|
523
|
+
}, [])));
|
|
524
|
+
|
|
517
525
|
Object.values(this.#schema.models).forEach(($model) => {
|
|
518
|
-
$model.referentialIntegrity = Schema.#identifyOnDeletes(Object.values(this.#schema.models), $model
|
|
526
|
+
$model.referentialIntegrity = Schema.#identifyOnDeletes(Object.values(this.#schema.models).filter(m => m.isEntity), onDeleteFields.filter(f => `${f.model}` === `${$model}`));
|
|
519
527
|
});
|
|
520
528
|
|
|
521
529
|
// Helper methods
|
|
@@ -894,21 +902,25 @@ module.exports = class Schema {
|
|
|
894
902
|
`;
|
|
895
903
|
}
|
|
896
904
|
|
|
897
|
-
static #
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
}
|
|
904
|
-
// else {
|
|
905
|
-
// prev.push(...Schema.#identifyOnDeletes(models, model.name).map(od => Object.assign(od, { fieldRef: field.name, isArray: field.isArray, op: field.onDelete })));
|
|
906
|
-
// }
|
|
907
|
-
}
|
|
908
|
-
});
|
|
905
|
+
static #findPathToField(model, field, path = []) {
|
|
906
|
+
const { target, embeds } = Object.values(model.fields).reduce((prev, curr) => {
|
|
907
|
+
if (curr === field) prev.target = curr;
|
|
908
|
+
else if (curr.isEmbedded) prev.embeds.push(curr);
|
|
909
|
+
return prev;
|
|
910
|
+
}, { embeds: [] });
|
|
909
911
|
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
912
|
+
if (target) return path.concat(target.name);
|
|
913
|
+
if (embeds.length) return embeds.map(f => Schema.#findPathToField(f.model, field, path.concat(f.name))).filter(Boolean)[0];
|
|
914
|
+
return undefined;
|
|
915
|
+
}
|
|
916
|
+
|
|
917
|
+
static #identifyOnDeletes(models, fields) {
|
|
918
|
+
return models.map((model) => {
|
|
919
|
+
return fields.map((field) => {
|
|
920
|
+
const path = Schema.#findPathToField(model, field);
|
|
921
|
+
if (!path) return null;
|
|
922
|
+
return { model, field, path };
|
|
923
|
+
});
|
|
924
|
+
}).flat().filter(Boolean);
|
|
913
925
|
}
|
|
914
926
|
};
|