@coderich/autograph 0.10.20 → 0.10.22
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 +2 -2
- package/src/data/Pipeline.js +15 -8
- package/src/query/QueryResolver.js +2 -1
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@coderich/autograph",
|
|
3
3
|
"author": "Richard Livolsi (coderich)",
|
|
4
|
-
"version": "0.10.
|
|
4
|
+
"version": "0.10.22",
|
|
5
5
|
"description": "AutoGraph",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"graphql",
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"graphql-fields": "^2.0.3",
|
|
40
40
|
"lodash": "^4.17.21",
|
|
41
41
|
"mongodb": "4.8.1",
|
|
42
|
-
"object-hash": "^
|
|
42
|
+
"object-hash": "^3.0.0",
|
|
43
43
|
"picomatch": "^2.1.1"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
package/src/data/Pipeline.js
CHANGED
|
@@ -76,12 +76,13 @@ module.exports = class Pipeline {
|
|
|
76
76
|
Pipeline.define('idField', ({ model, field, value }) => field.getIdModel().idValue(value.id || value));
|
|
77
77
|
Pipeline.define('ensureArrayValue', ({ field, value }) => (field.toObject().isArray && !Array.isArray(value) ? [value] : value), { itemize: false });
|
|
78
78
|
|
|
79
|
-
Pipeline.define('ensureId', ({ resolver, field, value }) => {
|
|
79
|
+
Pipeline.define('ensureId', ({ resolver, model, field, value }) => {
|
|
80
|
+
const path = `${model}.${field}`;
|
|
80
81
|
const { type } = field.toObject();
|
|
81
82
|
const ids = Array.from(new Set(ensureArray(value).map(v => `${v}`)));
|
|
82
83
|
|
|
83
84
|
return resolver.match(type).where({ id: ids }).count().then((count) => {
|
|
84
|
-
if (count !== ids.length) throw Boom.notFound(`${type} Not Found
|
|
85
|
+
if (count !== ids.length) throw Boom.notFound(`${type} Not Found`, { path });
|
|
85
86
|
});
|
|
86
87
|
}, { itemize: false });
|
|
87
88
|
|
|
@@ -124,29 +125,34 @@ module.exports = class Pipeline {
|
|
|
124
125
|
|
|
125
126
|
// Required fields
|
|
126
127
|
Pipeline.define('required', ({ model, field, value }) => {
|
|
127
|
-
|
|
128
|
+
const path = `${model}.${field}`;
|
|
129
|
+
if (value == null) throw Boom.badRequest(`${path} is required`, { path });
|
|
128
130
|
}, { ignoreNull: false });
|
|
129
131
|
|
|
130
132
|
// A field cannot hold a reference to itself
|
|
131
133
|
Pipeline.define('selfless', ({ model, field, parent, parentPath, value }) => {
|
|
132
|
-
|
|
134
|
+
const path = `${model}.${field}`;
|
|
135
|
+
if (`${value}` === `${parentPath('id')}`) throw Boom.badData(`${path} cannot hold a reference to itself`, { path });
|
|
133
136
|
});
|
|
134
137
|
|
|
135
138
|
// Once set it cannot be changed
|
|
136
139
|
Pipeline.define('immutable', ({ model, field, docPath, parentPath, path, value }) => {
|
|
140
|
+
const $path = `${model}.${field}`;
|
|
137
141
|
const hint = { id: parentPath('id') };
|
|
138
142
|
const oldVal = docPath(path, hint);
|
|
139
|
-
if (oldVal !== undefined && value !== undefined && `${hashObject(oldVal)}` !== `${hashObject(value)}`) throw Boom.badData(`${
|
|
143
|
+
if (oldVal !== undefined && value !== undefined && `${hashObject(oldVal)}` !== `${hashObject(value)}`) throw Boom.badData(`${$path} is immutable; cannot be changed once set ${oldVal} -> ${value}`, { path: $path });
|
|
140
144
|
});
|
|
141
145
|
|
|
142
146
|
// List of allowed values
|
|
143
147
|
Pipeline.factory('Allow', (...args) => function allow({ model, field, value }) {
|
|
144
|
-
|
|
148
|
+
const path = `${model}.${field}`;
|
|
149
|
+
if (args.indexOf(value) === -1) throw Boom.badData(`${path} allows ${args}; found '${value}'`, { path });
|
|
145
150
|
});
|
|
146
151
|
|
|
147
152
|
// List of disallowed values
|
|
148
153
|
Pipeline.factory('Deny', (...args) => function deny({ model, field, value }) {
|
|
149
|
-
|
|
154
|
+
const path = `${model}.${field}`;
|
|
155
|
+
if (args.indexOf(value) > -1) throw Boom.badData(`${path} denys ${args}; found '${value}'`, { path });
|
|
150
156
|
});
|
|
151
157
|
|
|
152
158
|
// Min/Max range
|
|
@@ -155,9 +161,10 @@ module.exports = class Pipeline {
|
|
|
155
161
|
if (max == null) max = undefined;
|
|
156
162
|
|
|
157
163
|
return function range({ model, field, value }) {
|
|
164
|
+
const path = `${model}.${field}`;
|
|
158
165
|
const num = +value; // Coerce to number if possible
|
|
159
166
|
const test = Number.isNaN(num) ? value.length : num;
|
|
160
|
-
if (test < min || test > max) throw Boom.badData(`${
|
|
167
|
+
if (test < min || test > max) throw Boom.badData(`${path} must satisfy range ${min}:${max}; found '${value}'`, { path });
|
|
161
168
|
};
|
|
162
169
|
}, { itemize: false });
|
|
163
170
|
}
|
|
@@ -186,7 +186,8 @@ module.exports = class QueryResolver {
|
|
|
186
186
|
// Can only splice arrays
|
|
187
187
|
const field = model.getField(key);
|
|
188
188
|
const isArray = field.isArray();
|
|
189
|
-
|
|
189
|
+
const path = `${model}.${field}`;
|
|
190
|
+
if (!isArray) throw Boom.badRequest(`Cannot splice field '${path}'`, { path });
|
|
190
191
|
|
|
191
192
|
return this.resolver.match(model).match(match).one({ required: true }).then(async (doc) => {
|
|
192
193
|
const array = get(doc, key) || [];
|