@coderich/autograph 0.9.6 → 0.9.9
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
package/src/data/DataService.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
const {
|
|
1
|
+
const { remove } = require('lodash');
|
|
2
2
|
const Boom = require('../core/Boom');
|
|
3
|
-
const {
|
|
4
|
-
const { isPlainObject, objectContaining, mergeDeep, hashObject } = require('../service/app.service');
|
|
3
|
+
const { isPlainObject, objectContaining, mergeDeep, map } = require('../service/app.service');
|
|
5
4
|
|
|
6
5
|
exports.paginateResultSet = (rs, first, after, last, before) => {
|
|
7
6
|
let hasNextPage = false;
|
|
@@ -38,80 +37,61 @@ exports.paginateResultSet = (rs, first, after, last, before) => {
|
|
|
38
37
|
return { hasNextPage, hasPreviousPage };
|
|
39
38
|
};
|
|
40
39
|
|
|
41
|
-
|
|
40
|
+
/**
|
|
41
|
+
* @param from <Array>
|
|
42
|
+
* @param to <Array>
|
|
43
|
+
*/
|
|
44
|
+
exports.spliceEmbeddedArray = (query, doc, key, from, to) => {
|
|
42
45
|
const { model } = query.toObject();
|
|
43
46
|
const field = model.getField(key);
|
|
44
|
-
if (!field || !field.isArray()) return Promise.reject(Boom.badRequest(`Cannot splice field '${key}'`));
|
|
45
|
-
|
|
46
47
|
const modelRef = field.getModelRef();
|
|
47
|
-
const
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
// Edit
|
|
51
|
-
if (from && to) {
|
|
52
|
-
const arr = get(doc, key) || [];
|
|
53
|
-
if ($from.length > 1 && $to.length === 1) $to = Array.from($from).fill($to[0]);
|
|
54
|
-
|
|
55
|
-
const edits = arr.map((el) => {
|
|
56
|
-
return $from.reduce((prev, val, i) => {
|
|
57
|
-
if (objectContaining(el, val)) return isPlainObject(prev) ? mergeDeep(prev, $to[i]) : $to[i];
|
|
58
|
-
return prev;
|
|
59
|
-
}, el);
|
|
60
|
-
});
|
|
48
|
+
const op = from && to ? 'edit' : (from ? 'pull' : 'push'); // eslint-disable-line no-nested-ternary
|
|
49
|
+
const promises = [];
|
|
61
50
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
if (hashObject(edit) !== hashObject(arr[i])) {
|
|
65
|
-
return createSystemEvent('Mutation', { method: 'update', query: query.clone().model(modelRef).input(edit).doc(doc) }, () => {
|
|
66
|
-
edit = modelRef.appendDefaultFields(query, modelRef.appendCreateFields(edit, true));
|
|
67
|
-
return modelRef.validate(query, edit).then(() => edit);
|
|
68
|
-
});
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
return Promise.resolve(edit);
|
|
72
|
-
})).then((results) => {
|
|
73
|
-
return { [key]: mergeDeep(edits, results) };
|
|
74
|
-
});
|
|
75
|
-
}
|
|
51
|
+
// Can only splice arrays
|
|
52
|
+
if (!field || !field.isArray()) return Promise.reject(Boom.badRequest(`Cannot splice field '${key}'`));
|
|
76
53
|
|
|
77
|
-
|
|
78
|
-
}
|
|
54
|
+
// We have to deserialize because this normalizes the data (casting etc)
|
|
55
|
+
let $to = model.deserialize(query, { [key]: to })[key] || to;
|
|
56
|
+
const $from = model.deserialize(query, { [key]: from })[key] || from;
|
|
79
57
|
|
|
80
|
-
//
|
|
81
|
-
if (
|
|
82
|
-
// key.split('.').reduce((prev, segment, i, arr) => {
|
|
83
|
-
// if (prev == null) return prev;
|
|
58
|
+
// If it's embedded we need to append default/create fields for insertion
|
|
59
|
+
if ($to && field.isEmbedded()) $to = $to.map(el => modelRef.appendDefaultFields(query, modelRef.appendCreateFields(el, true)));
|
|
84
60
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
// if (i < (arr.length - 1)) return $data;
|
|
88
|
-
// remove($data, el => ($from || from).find(val => objectContaining(el, val)));
|
|
89
|
-
// return $data;
|
|
90
|
-
// });
|
|
91
|
-
// }, doc);
|
|
61
|
+
// Convenience so the user does not have to explicity type out the same value over and over to replace
|
|
62
|
+
if ($from && $from.length > 1 && $to && $to.length === 1) $to = Array.from($from).fill($to[0]);
|
|
92
63
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
return data;
|
|
97
|
-
}
|
|
64
|
+
// Traverse the document till we find the segment to modify (in place)
|
|
65
|
+
return key.split('.').reduce((prev, segment, i, arr) => {
|
|
66
|
+
if (prev == null) return prev;
|
|
98
67
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
return Promise.all($to.map((input) => {
|
|
103
|
-
return createSystemEvent('Mutation', { method: 'create', query: query.clone().model(modelRef).input(input).doc(doc) }, () => {
|
|
104
|
-
input = modelRef.appendDefaultFields(query, modelRef.appendCreateFields(input, true));
|
|
105
|
-
return modelRef.validate(query, input).then(() => input);
|
|
106
|
-
});
|
|
107
|
-
})).then((results) => {
|
|
108
|
-
return { [key]: (get(doc, key) || []).concat(...results) };
|
|
109
|
-
});
|
|
110
|
-
}
|
|
68
|
+
return map(prev, (data) => {
|
|
69
|
+
if (i < (arr.length - 1)) return data[segment]; // We have not found the target segment yet
|
|
70
|
+
data[segment] = data[segment] || []; // Ensuring target segment is an array
|
|
111
71
|
|
|
112
|
-
|
|
113
|
-
|
|
72
|
+
switch (op) {
|
|
73
|
+
case 'edit': {
|
|
74
|
+
data[segment].forEach((el, j) => {
|
|
75
|
+
$from.forEach((val, k) => {
|
|
76
|
+
if (objectContaining(el, val)) data[segment][j] = isPlainObject(el) ? mergeDeep(el, $to[k]) : $to[k];
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
break;
|
|
80
|
+
}
|
|
81
|
+
case 'push': {
|
|
82
|
+
data[segment].push(...$to);
|
|
83
|
+
break;
|
|
84
|
+
}
|
|
85
|
+
case 'pull': {
|
|
86
|
+
remove(data[segment], el => $from.find(val => objectContaining(el, val)));
|
|
87
|
+
break;
|
|
88
|
+
}
|
|
89
|
+
default: {
|
|
90
|
+
break;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
114
93
|
|
|
115
|
-
|
|
116
|
-
|
|
94
|
+
return Promise.all(promises);
|
|
95
|
+
});
|
|
96
|
+
}, doc);
|
|
117
97
|
};
|
package/src/graphql/ast/Field.js
CHANGED
|
@@ -175,4 +175,9 @@ module.exports = class Field extends Node {
|
|
|
175
175
|
type = this.isArray() ? `[${type}${this.isArrayElementRequired() ? '!' : ''}]` : type;
|
|
176
176
|
return `${type}${req}`;
|
|
177
177
|
}
|
|
178
|
+
|
|
179
|
+
getSubscriptionType() {
|
|
180
|
+
if (this.isFKReference()) return this.isArray() ? '[ID]' : 'ID';
|
|
181
|
+
return this.getGQLType();
|
|
182
|
+
}
|
|
178
183
|
};
|
|
@@ -90,7 +90,7 @@ module.exports = (schema) => {
|
|
|
90
90
|
}
|
|
91
91
|
|
|
92
92
|
type ${model.getName()}SubscriptionPayloadEventData {
|
|
93
|
-
${getGQLWhereFields(model).map(field => `${field.getName()}: ${field.
|
|
93
|
+
${getGQLWhereFields(model).map(field => `${field.getName()}: ${field.getSubscriptionType()}`)}
|
|
94
94
|
}
|
|
95
95
|
|
|
96
96
|
interface ${model.getName()}SubscriptionQuery {
|
|
@@ -78,7 +78,7 @@ module.exports = class QueryBuilder {
|
|
|
78
78
|
break;
|
|
79
79
|
}
|
|
80
80
|
case 'push': case 'pull': case 'splice': {
|
|
81
|
-
crud = 'update'; // Your
|
|
81
|
+
crud = 'update'; // Your logic wants this to be a simple "update". Sub documents systemEvents will emit either "create" or "udpate"
|
|
82
82
|
method = id ? `${cmd}One` : `${cmd}Many`;
|
|
83
83
|
break;
|
|
84
84
|
}
|
|
@@ -130,17 +130,33 @@ module.exports = class QueryResolver {
|
|
|
130
130
|
});
|
|
131
131
|
}
|
|
132
132
|
|
|
133
|
+
spliceOne(query) {
|
|
134
|
+
const { args } = query.toObject();
|
|
135
|
+
const [key, ...values] = args;
|
|
136
|
+
return this.splice(query.args([key, ...values]));
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
spliceMany(query) {
|
|
140
|
+
const { model, match, transaction, args, flags } = query.toObject();
|
|
141
|
+
const [key, ...values] = args;
|
|
142
|
+
|
|
143
|
+
return this.resolver.match(model).match(match).flags(flags).many().then((docs) => {
|
|
144
|
+
const txn = this.resolver.transaction(transaction);
|
|
145
|
+
docs.forEach(doc => txn.match(model).id(doc.id).splice(key, ...values));
|
|
146
|
+
return txn.run();
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
|
|
133
150
|
splice(query) {
|
|
134
151
|
const { model, match, args, flags } = query.toObject();
|
|
135
152
|
const [key, from, to] = args;
|
|
136
153
|
|
|
137
154
|
return this.resolver.match(model).match(match).flags(flags).one({ required: true }).then(async (doc) => {
|
|
138
|
-
|
|
139
|
-
const merged = mergeDeep(doc, data);
|
|
155
|
+
await DataService.spliceEmbeddedArray(query, doc, key, from, to);
|
|
140
156
|
|
|
141
|
-
return createSystemEvent('Mutation', { method: '
|
|
142
|
-
await model.validate(query,
|
|
143
|
-
const $doc =
|
|
157
|
+
return createSystemEvent('Mutation', { method: 'update', query: query.doc(doc).merged(doc) }, async () => {
|
|
158
|
+
await model.validate(query, doc);
|
|
159
|
+
const $doc = model.serialize(query, doc, true);
|
|
144
160
|
return this.resolver.resolve(query.method('updateOne').doc(doc).$doc($doc));
|
|
145
161
|
});
|
|
146
162
|
});
|