@coderich/autograph 0.9.10 → 0.9.13
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/index.js +2 -0
- package/package.json +5 -1
- package/src/.DS_Store +0 -0
- package/src/core/Resolver.js +6 -1
- package/src/core/SchemaDecorator.js +46 -0
- package/src/data/.DS_Store +0 -0
- package/src/data/Model.js +20 -0
- package/src/data/ResultSet.js +200 -146
- package/src/data/ResultSetItem.js +178 -0
- package/src/data/ResultSetNew.js +47 -0
- package/src/data/ResultSetObj.js +299 -0
- package/src/data/{ResultSet2.js → ResultSetOriginal.js} +70 -72
- package/src/driver/MongoDriver.js +8 -4
- package/src/graphql/ast/.DS_Store +0 -0
- package/src/graphql/ast/Model.js +4 -0
- package/src/graphql/ast/Schema.js +2 -3
- package/src/graphql/ast/SchemaDecorator.js +138 -0
- package/src/graphql/ast/TypeDefApi.js +93 -0
- package/src/query/Query.js +1 -19
- package/src/query/QueryResolver.js +5 -1
- package/src/service/app.service.js +18 -1
- package/src/service/event.service.js +1 -0
- package/src/data/ResultSet3.js +0 -186
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
const { get } = require('lodash');
|
|
2
|
+
const DataService = require('./DataService');
|
|
3
|
+
const { map, ensureArray } = require('../service/app.service');
|
|
4
|
+
|
|
5
|
+
module.exports = class ResultSet {
|
|
6
|
+
constructor(query, data, adjustForPagination = true) {
|
|
7
|
+
if (data == null) return data;
|
|
8
|
+
|
|
9
|
+
const { model, first, after, last, before } = query.toObject();
|
|
10
|
+
const rs = map(data, doc => model.getResultSetItem().create(query, doc));
|
|
11
|
+
|
|
12
|
+
let hasNextPage = false;
|
|
13
|
+
let hasPreviousPage = false;
|
|
14
|
+
if (adjustForPagination && rs.length) (({ hasPreviousPage, hasNextPage } = DataService.paginateResultSet(rs, first, after, last, before)));
|
|
15
|
+
|
|
16
|
+
return Object.defineProperties(rs, {
|
|
17
|
+
$$pageInfo: {
|
|
18
|
+
get() {
|
|
19
|
+
const edges = ensureArray(rs);
|
|
20
|
+
|
|
21
|
+
return {
|
|
22
|
+
startCursor: get(edges, '0.$$cursor', ''),
|
|
23
|
+
endCursor: get(edges, `${edges.length - 1}.$$cursor`, ''),
|
|
24
|
+
hasPreviousPage,
|
|
25
|
+
hasNextPage,
|
|
26
|
+
};
|
|
27
|
+
},
|
|
28
|
+
enumerable: false,
|
|
29
|
+
},
|
|
30
|
+
$$isResultSet: {
|
|
31
|
+
value: true,
|
|
32
|
+
enumerable: false,
|
|
33
|
+
},
|
|
34
|
+
toObject: {
|
|
35
|
+
get() {
|
|
36
|
+
return () => map(this, doc => Object.entries(doc).reduce((prev, [key, value]) => {
|
|
37
|
+
if (value === undefined) return prev;
|
|
38
|
+
prev[key] = get(value, '$$isResultSet') ? value.toObject() : value;
|
|
39
|
+
return prev;
|
|
40
|
+
}, {}));
|
|
41
|
+
},
|
|
42
|
+
enumerable: false,
|
|
43
|
+
configurable: true,
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
};
|
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
const { get } = require('lodash');
|
|
2
|
+
const DataService = require('./DataService');
|
|
3
|
+
const { map, ensureArray, keyPaths, mapPromise, toGUID, hashObject } = require('../service/app.service');
|
|
4
|
+
|
|
5
|
+
module.exports = class ResultSet {
|
|
6
|
+
constructor(query, data, adjustForPagination = true) {
|
|
7
|
+
if (data == null) return data;
|
|
8
|
+
const { resolver, model, sort, first, after, last, before } = query.toObject();
|
|
9
|
+
const fields = model.getFields().filter(f => f.getName() !== 'id');
|
|
10
|
+
|
|
11
|
+
const rs = map(data, (doc) => {
|
|
12
|
+
if (doc == null || typeof doc !== 'object') return doc;
|
|
13
|
+
|
|
14
|
+
//
|
|
15
|
+
const cache = new Map();
|
|
16
|
+
|
|
17
|
+
const definition = {
|
|
18
|
+
// $$model: model,
|
|
19
|
+
$$isResultSetItem: true,
|
|
20
|
+
|
|
21
|
+
get id() { return doc.id || doc[model.idKey()]; },
|
|
22
|
+
set id(id) { doc.id = id; }, // Embedded array of documents need to set id
|
|
23
|
+
get $id() { return toGUID(model.getName(), this.id); },
|
|
24
|
+
|
|
25
|
+
get $$cursor() {
|
|
26
|
+
const sortPaths = keyPaths(sort);
|
|
27
|
+
const sortValues = sortPaths.reduce((prv, path) => Object.assign(prv, { [path]: get(this, path) }), {});
|
|
28
|
+
const sortJSON = JSON.stringify(sortValues);
|
|
29
|
+
return Buffer.from(sortJSON).toString('base64');
|
|
30
|
+
},
|
|
31
|
+
|
|
32
|
+
$$save: input => resolver.match(model).id(this.id).save({ ...this, ...input }),
|
|
33
|
+
$$remove: () => resolver.match(model).id(this.id).remove(),
|
|
34
|
+
$$delete: () => resolver.match(model).id(this.id).delete(),
|
|
35
|
+
|
|
36
|
+
get toObject() {
|
|
37
|
+
return () => map(this, obj => Object.entries(obj).reduce((prev, [key, value]) => {
|
|
38
|
+
if (value === undefined) return prev;
|
|
39
|
+
prev[key] = get(value, '$$isResultSet') ? value.toObject() : value;
|
|
40
|
+
return prev;
|
|
41
|
+
}, {}));
|
|
42
|
+
},
|
|
43
|
+
|
|
44
|
+
...fields.reduce((prev, field) => {
|
|
45
|
+
const key = field.getKey();
|
|
46
|
+
const name = field.getName();
|
|
47
|
+
const $name = `$${name}`;
|
|
48
|
+
const value = doc[key];
|
|
49
|
+
|
|
50
|
+
return {
|
|
51
|
+
...prev,
|
|
52
|
+
|
|
53
|
+
// Deserialized field attributes
|
|
54
|
+
get [name]() {
|
|
55
|
+
if (cache.has(name)) return cache.get(name);
|
|
56
|
+
let $value = field.deserialize(query, value);
|
|
57
|
+
$value = $value != null && field.isEmbedded() ? new ResultSet(query.model(field.getModelRef()), $value, false) : $value;
|
|
58
|
+
cache.set(name, $value);
|
|
59
|
+
return $value;
|
|
60
|
+
},
|
|
61
|
+
set [name]($value) {
|
|
62
|
+
cache.set(name, $value);
|
|
63
|
+
},
|
|
64
|
+
|
|
65
|
+
// Fully deserialized, hydrated, and resolved field attributes
|
|
66
|
+
get [$name]() {
|
|
67
|
+
return (args = {}) => {
|
|
68
|
+
// Ensure where clause
|
|
69
|
+
args.where = args.where || {};
|
|
70
|
+
|
|
71
|
+
// Cache
|
|
72
|
+
const cacheKey = `${$name}-${hashObject(args)}`;
|
|
73
|
+
if (cache.has(cacheKey)) return cache.get(cacheKey);
|
|
74
|
+
|
|
75
|
+
const promise = new Promise((resolve, reject) => {
|
|
76
|
+
(() => {
|
|
77
|
+
const $value = this[name];
|
|
78
|
+
|
|
79
|
+
if (field.isScalar() || field.isEmbedded()) return Promise.resolve($value);
|
|
80
|
+
|
|
81
|
+
const modelRef = field.getModelRef();
|
|
82
|
+
|
|
83
|
+
if (field.isArray()) {
|
|
84
|
+
if (field.isVirtual()) {
|
|
85
|
+
args.where[[field.getVirtualField()]] = this.id; // Is where[[field.getVirtualField()]] correct?
|
|
86
|
+
return resolver.match(modelRef).merge(args).many();
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Not a "required" query + strip out nulls
|
|
90
|
+
args.where.id = $value;
|
|
91
|
+
return resolver.match(modelRef).merge(args).many();
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (field.isVirtual()) {
|
|
95
|
+
args.where[[field.getVirtualField()]] = this.id;
|
|
96
|
+
return resolver.match(modelRef).merge(args).one();
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return resolver.match(modelRef).id($value).one({ required: field.isRequired() });
|
|
100
|
+
})().then((results) => {
|
|
101
|
+
if (results == null) return field.resolve(query, results); // Allow field to determine
|
|
102
|
+
return mapPromise(results, result => field.resolve(query, result)).then(() => results); // Resolve the inside fields but still return "results"!!!!
|
|
103
|
+
}).then((resolved) => {
|
|
104
|
+
resolve(resolved);
|
|
105
|
+
}).catch((e) => {
|
|
106
|
+
reject(e);
|
|
107
|
+
});
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
cache.set(cacheKey, promise);
|
|
111
|
+
return promise;
|
|
112
|
+
};
|
|
113
|
+
},
|
|
114
|
+
|
|
115
|
+
// Field count (let's assume it's a Connection Type - meaning dont try with anything else)
|
|
116
|
+
get [`${$name}:count`]() {
|
|
117
|
+
return (q = {}) => {
|
|
118
|
+
q.where = q.where || {};
|
|
119
|
+
if (field.isVirtual()) q.where[field.getVirtualField()] = this.id;
|
|
120
|
+
else q.where.id = this[name];
|
|
121
|
+
return resolver.match(field.getModelRef()).merge(q).count();
|
|
122
|
+
};
|
|
123
|
+
},
|
|
124
|
+
};
|
|
125
|
+
}, {}),
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
// const definition = fields.reduce((prev, field) => {
|
|
129
|
+
// const key = field.getKey();
|
|
130
|
+
// const name = field.getName();
|
|
131
|
+
// const $name = `$${name}`;
|
|
132
|
+
// const value = doc[key];
|
|
133
|
+
|
|
134
|
+
// return {
|
|
135
|
+
// ...prev,
|
|
136
|
+
|
|
137
|
+
// // Deserialized field attributes
|
|
138
|
+
// get [name]() {
|
|
139
|
+
// if (cache.has(name)) return cache.get(name);
|
|
140
|
+
// let $value = field.deserialize(query, value);
|
|
141
|
+
// $value = $value != null && field.isEmbedded() ? new ResultSet(query.model(field.getModelRef()), $value, false) : $value;
|
|
142
|
+
// cache.set(name, $value);
|
|
143
|
+
// return $value;
|
|
144
|
+
// },
|
|
145
|
+
// set [name]($value) {
|
|
146
|
+
// cache.set(name, $value);
|
|
147
|
+
// },
|
|
148
|
+
|
|
149
|
+
// // Fully deserialized, hydrated, and resolved field attributes
|
|
150
|
+
// get [$name]() {
|
|
151
|
+
// return (args = {}) => {
|
|
152
|
+
// // Ensure where clause
|
|
153
|
+
// args.where = args.where || {};
|
|
154
|
+
|
|
155
|
+
// // Cache
|
|
156
|
+
// const cacheKey = `${$name}-${hashObject(args)}`;
|
|
157
|
+
// if (cache.has(cacheKey)) return cache.get(cacheKey);
|
|
158
|
+
|
|
159
|
+
// const promise = new Promise((resolve, reject) => {
|
|
160
|
+
// (() => {
|
|
161
|
+
// const $value = this[name];
|
|
162
|
+
|
|
163
|
+
// if (field.isScalar() || field.isEmbedded()) return Promise.resolve($value);
|
|
164
|
+
|
|
165
|
+
// const modelRef = field.getModelRef();
|
|
166
|
+
|
|
167
|
+
// if (field.isArray()) {
|
|
168
|
+
// if (field.isVirtual()) {
|
|
169
|
+
// args.where[[field.getVirtualField()]] = this.id; // Is where[[field.getVirtualField()]] correct?
|
|
170
|
+
// return resolver.match(modelRef).merge(args).many();
|
|
171
|
+
// }
|
|
172
|
+
|
|
173
|
+
// // Not a "required" query + strip out nulls
|
|
174
|
+
// args.where.id = $value;
|
|
175
|
+
// return resolver.match(modelRef).merge(args).many();
|
|
176
|
+
// }
|
|
177
|
+
|
|
178
|
+
// if (field.isVirtual()) {
|
|
179
|
+
// args.where[[field.getVirtualField()]] = this.id;
|
|
180
|
+
// return resolver.match(modelRef).merge(args).one();
|
|
181
|
+
// }
|
|
182
|
+
|
|
183
|
+
// return resolver.match(modelRef).id($value).one({ required: field.isRequired() });
|
|
184
|
+
// })().then((results) => {
|
|
185
|
+
// if (results == null) return field.resolve(query, results); // Allow field to determine
|
|
186
|
+
// return mapPromise(results, result => field.resolve(query, result)).then(() => results); // Resolve the inside fields but still return "results"!!!!
|
|
187
|
+
// }).then((resolved) => {
|
|
188
|
+
// resolve(resolved);
|
|
189
|
+
// }).catch((e) => {
|
|
190
|
+
// reject(e);
|
|
191
|
+
// });
|
|
192
|
+
// });
|
|
193
|
+
|
|
194
|
+
// cache.set(cacheKey, promise);
|
|
195
|
+
// return promise;
|
|
196
|
+
// };
|
|
197
|
+
// },
|
|
198
|
+
|
|
199
|
+
// // Field count (let's assume it's a Connection Type - meaning dont try with anything else)
|
|
200
|
+
// get [`${$name}:count`]() {
|
|
201
|
+
// return (q = {}) => {
|
|
202
|
+
// q.where = q.where || {};
|
|
203
|
+
// if (field.isVirtual()) q.where[field.getVirtualField()] = this.id;
|
|
204
|
+
// else q.where.id = this[name];
|
|
205
|
+
// return resolver.match(field.getModelRef()).merge(q).count();
|
|
206
|
+
// };
|
|
207
|
+
// },
|
|
208
|
+
// };
|
|
209
|
+
// }, {
|
|
210
|
+
// get id() { return doc.id || doc[model.idKey()]; },
|
|
211
|
+
// set id(id) { doc.id = id; }, // Embedded array of documents need to set id
|
|
212
|
+
|
|
213
|
+
// get $id() { return toGUID(model.getName(), this.id); },
|
|
214
|
+
|
|
215
|
+
// get $$cursor() {
|
|
216
|
+
// const sortPaths = keyPaths(sort);
|
|
217
|
+
// const sortValues = sortPaths.reduce((prv, path) => Object.assign(prv, { [path]: get(this, path) }), {});
|
|
218
|
+
// const sortJSON = JSON.stringify(sortValues);
|
|
219
|
+
// return Buffer.from(sortJSON).toString('base64');
|
|
220
|
+
// },
|
|
221
|
+
|
|
222
|
+
// $$model: model,
|
|
223
|
+
// $$isResultSetItem: true,
|
|
224
|
+
// $$save: input => resolver.match(model).id(this.id).save({ ...this, ...input }),
|
|
225
|
+
// $$remove: () => resolver.match(model).id(this.id).remove(),
|
|
226
|
+
// $$delete: () => resolver.match(model).id(this.id).delete(),
|
|
227
|
+
|
|
228
|
+
// get toObject() {
|
|
229
|
+
// return () => map(this, obj => Object.entries(obj).reduce((prev, [key, value]) => {
|
|
230
|
+
// if (value === undefined) return prev;
|
|
231
|
+
// prev[key] = get(value, '$$isResultSet') ? value.toObject() : value;
|
|
232
|
+
// return prev;
|
|
233
|
+
// }, {}));
|
|
234
|
+
// },
|
|
235
|
+
// });
|
|
236
|
+
|
|
237
|
+
return definition;
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
let hasNextPage = false;
|
|
241
|
+
let hasPreviousPage = false;
|
|
242
|
+
if (adjustForPagination && rs.length) (({ hasPreviousPage, hasNextPage } = DataService.paginateResultSet(rs, first, after, last, before)));
|
|
243
|
+
|
|
244
|
+
return Object.defineProperties(rs, {
|
|
245
|
+
$$pageInfo: {
|
|
246
|
+
get() {
|
|
247
|
+
const edges = ensureArray(rs);
|
|
248
|
+
|
|
249
|
+
return {
|
|
250
|
+
startCursor: get(edges, '0.$$cursor', ''),
|
|
251
|
+
endCursor: get(edges, `${edges.length - 1}.$$cursor`, ''),
|
|
252
|
+
hasPreviousPage,
|
|
253
|
+
hasNextPage,
|
|
254
|
+
};
|
|
255
|
+
},
|
|
256
|
+
enumerable: false,
|
|
257
|
+
},
|
|
258
|
+
$$isResultSet: {
|
|
259
|
+
value: true,
|
|
260
|
+
enumerable: false,
|
|
261
|
+
},
|
|
262
|
+
toObject: {
|
|
263
|
+
get() {
|
|
264
|
+
return () => map(this, doc => Object.entries(doc).reduce((prev, [key, value]) => {
|
|
265
|
+
if (value === undefined) return prev;
|
|
266
|
+
prev[key] = get(value, '$$isResultSet') ? value.toObject() : value;
|
|
267
|
+
return prev;
|
|
268
|
+
}, {}));
|
|
269
|
+
},
|
|
270
|
+
enumerable: false,
|
|
271
|
+
configurable: true,
|
|
272
|
+
},
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
// const idk = {
|
|
276
|
+
// ...rs,
|
|
277
|
+
// $$isResultSet: true,
|
|
278
|
+
// get $$pageInfo() {
|
|
279
|
+
// const edges = ensureArray(rs);
|
|
280
|
+
|
|
281
|
+
// return {
|
|
282
|
+
// startCursor: get(edges, '0.$$cursor', ''),
|
|
283
|
+
// endCursor: get(edges, `${edges.length - 1}.$$cursor`, ''),
|
|
284
|
+
// hasPreviousPage,
|
|
285
|
+
// hasNextPage,
|
|
286
|
+
// };
|
|
287
|
+
// },
|
|
288
|
+
// get toObject() {
|
|
289
|
+
// return () => map(this, doc => Object.entries(doc).reduce((prev, [key, value]) => {
|
|
290
|
+
// if (value === undefined) return prev;
|
|
291
|
+
// prev[key] = get(value, '$$isResultSet') ? value.toObject() : value;
|
|
292
|
+
// return prev;
|
|
293
|
+
// }, {}));
|
|
294
|
+
// },
|
|
295
|
+
// };
|
|
296
|
+
|
|
297
|
+
// return idk;
|
|
298
|
+
}
|
|
299
|
+
};
|
|
@@ -4,6 +4,8 @@ const { map, ensureArray, keyPaths, mapPromise, toGUID, hashObject } = require('
|
|
|
4
4
|
|
|
5
5
|
module.exports = class ResultSet {
|
|
6
6
|
constructor(query, data, adjustForPagination = true) {
|
|
7
|
+
if (data == null) return data;
|
|
8
|
+
|
|
7
9
|
const { resolver, model, sort, first, after, last, before } = query.toObject();
|
|
8
10
|
const fields = model.getFields().filter(f => f.getName() !== 'id');
|
|
9
11
|
|
|
@@ -13,80 +15,15 @@ module.exports = class ResultSet {
|
|
|
13
15
|
//
|
|
14
16
|
const cache = new Map();
|
|
15
17
|
|
|
16
|
-
|
|
17
|
-
const definition = {
|
|
18
|
-
id: {
|
|
19
|
-
get() { return doc.id || doc[model.idKey()]; },
|
|
20
|
-
set(id) { doc.id = id; }, // Embedded array of documents need to set id
|
|
21
|
-
enumerable: true,
|
|
22
|
-
},
|
|
23
|
-
|
|
24
|
-
$id: {
|
|
25
|
-
get() { return toGUID(model.getName(), this.id); },
|
|
26
|
-
enumerable: false,
|
|
27
|
-
},
|
|
28
|
-
|
|
29
|
-
$$cursor: {
|
|
30
|
-
get() {
|
|
31
|
-
const sortPaths = keyPaths(sort);
|
|
32
|
-
const sortValues = sortPaths.reduce((prv, path) => Object.assign(prv, { [path]: get(this, path) }), {});
|
|
33
|
-
const sortJSON = JSON.stringify(sortValues);
|
|
34
|
-
return Buffer.from(sortJSON).toString('base64');
|
|
35
|
-
},
|
|
36
|
-
enumerable: false,
|
|
37
|
-
},
|
|
38
|
-
|
|
39
|
-
$$model: {
|
|
40
|
-
value: model,
|
|
41
|
-
enumerable: false,
|
|
42
|
-
},
|
|
43
|
-
|
|
44
|
-
$$data: {
|
|
45
|
-
value: data,
|
|
46
|
-
enumerable: false,
|
|
47
|
-
},
|
|
48
|
-
|
|
49
|
-
$$isResultSetItem: {
|
|
50
|
-
value: true,
|
|
51
|
-
enumerable: false,
|
|
52
|
-
},
|
|
53
|
-
|
|
54
|
-
$$save: {
|
|
55
|
-
get() { return input => resolver.match(model).id(this.id).save({ ...this, ...input }); },
|
|
56
|
-
enumerable: false,
|
|
57
|
-
},
|
|
58
|
-
|
|
59
|
-
$$remove: {
|
|
60
|
-
get() { return () => resolver.match(model).id(this.id).remove(); },
|
|
61
|
-
enumerable: false,
|
|
62
|
-
},
|
|
63
|
-
|
|
64
|
-
$$delete: {
|
|
65
|
-
get() { return () => resolver.match(model).id(this.id).delete(); },
|
|
66
|
-
enumerable: false,
|
|
67
|
-
},
|
|
68
|
-
|
|
69
|
-
toObject: {
|
|
70
|
-
get() {
|
|
71
|
-
return () => map(this, obj => Object.entries(obj).reduce((prev, [key, value]) => {
|
|
72
|
-
if (value === undefined) return prev;
|
|
73
|
-
prev[key] = get(value, '$$isResultSet') ? value.toObject() : value;
|
|
74
|
-
return prev;
|
|
75
|
-
}, {}));
|
|
76
|
-
},
|
|
77
|
-
enumerable: false,
|
|
78
|
-
configurable: true,
|
|
79
|
-
},
|
|
80
|
-
};
|
|
81
|
-
|
|
82
|
-
fields.forEach((field) => {
|
|
18
|
+
const definition = fields.reduce((prev, field) => {
|
|
83
19
|
const key = field.getKey();
|
|
84
20
|
const name = field.getName();
|
|
85
21
|
const $name = `$${name}`;
|
|
86
22
|
const value = doc[key];
|
|
87
23
|
|
|
88
|
-
//
|
|
89
|
-
|
|
24
|
+
// Deserialized field attributes
|
|
25
|
+
prev[name] = {
|
|
26
|
+
// value,
|
|
90
27
|
get() {
|
|
91
28
|
if (cache.has(name)) return cache.get(name);
|
|
92
29
|
let $value = field.deserialize(query, value);
|
|
@@ -101,8 +38,9 @@ module.exports = class ResultSet {
|
|
|
101
38
|
configurable: true, // Allows things like delete
|
|
102
39
|
};
|
|
103
40
|
|
|
104
|
-
//
|
|
105
|
-
|
|
41
|
+
// Fully deserialized, hydrated, and resolved field attributes
|
|
42
|
+
prev[$name] = {
|
|
43
|
+
// value: () => value,
|
|
106
44
|
get() {
|
|
107
45
|
return (args = {}) => {
|
|
108
46
|
// Ensure where clause
|
|
@@ -155,7 +93,7 @@ module.exports = class ResultSet {
|
|
|
155
93
|
};
|
|
156
94
|
|
|
157
95
|
// Field count (let's assume it's a Connection Type - meaning dont try with anything else)
|
|
158
|
-
|
|
96
|
+
prev[`${$name}:count`] = {
|
|
159
97
|
get() {
|
|
160
98
|
return (q = {}) => {
|
|
161
99
|
q.where = q.where || {};
|
|
@@ -166,6 +104,66 @@ module.exports = class ResultSet {
|
|
|
166
104
|
},
|
|
167
105
|
enumerable: false,
|
|
168
106
|
};
|
|
107
|
+
|
|
108
|
+
return prev;
|
|
109
|
+
}, {
|
|
110
|
+
id: {
|
|
111
|
+
get() { return doc.id || doc[model.idKey()]; },
|
|
112
|
+
set(id) { doc.id = id; }, // Embedded array of documents need to set id
|
|
113
|
+
enumerable: true,
|
|
114
|
+
},
|
|
115
|
+
|
|
116
|
+
$id: {
|
|
117
|
+
get() { return toGUID(model.getName(), this.id); },
|
|
118
|
+
enumerable: false,
|
|
119
|
+
},
|
|
120
|
+
|
|
121
|
+
$$cursor: {
|
|
122
|
+
get() {
|
|
123
|
+
const sortPaths = keyPaths(sort);
|
|
124
|
+
const sortValues = sortPaths.reduce((prv, path) => Object.assign(prv, { [path]: get(this, path) }), {});
|
|
125
|
+
const sortJSON = JSON.stringify(sortValues);
|
|
126
|
+
return Buffer.from(sortJSON).toString('base64');
|
|
127
|
+
},
|
|
128
|
+
enumerable: false,
|
|
129
|
+
},
|
|
130
|
+
|
|
131
|
+
$$model: {
|
|
132
|
+
value: model,
|
|
133
|
+
enumerable: false,
|
|
134
|
+
},
|
|
135
|
+
|
|
136
|
+
$$isResultSetItem: {
|
|
137
|
+
value: true,
|
|
138
|
+
enumerable: false,
|
|
139
|
+
},
|
|
140
|
+
|
|
141
|
+
$$save: {
|
|
142
|
+
get() { return input => resolver.match(model).id(this.id).save({ ...this, ...input }); },
|
|
143
|
+
enumerable: false,
|
|
144
|
+
},
|
|
145
|
+
|
|
146
|
+
$$remove: {
|
|
147
|
+
get() { return () => resolver.match(model).id(this.id).remove(); },
|
|
148
|
+
enumerable: false,
|
|
149
|
+
},
|
|
150
|
+
|
|
151
|
+
$$delete: {
|
|
152
|
+
get() { return () => resolver.match(model).id(this.id).delete(); },
|
|
153
|
+
enumerable: false,
|
|
154
|
+
},
|
|
155
|
+
|
|
156
|
+
toObject: {
|
|
157
|
+
get() {
|
|
158
|
+
return () => map(this, obj => Object.entries(obj).reduce((prev, [key, value]) => {
|
|
159
|
+
if (value === undefined) return prev;
|
|
160
|
+
prev[key] = get(value, '$$isResultSet') ? value.toObject() : value;
|
|
161
|
+
return prev;
|
|
162
|
+
}, {}));
|
|
163
|
+
},
|
|
164
|
+
enumerable: false,
|
|
165
|
+
configurable: true,
|
|
166
|
+
},
|
|
169
167
|
});
|
|
170
168
|
|
|
171
169
|
// Create and return ResultSetItem
|
|
@@ -16,6 +16,10 @@ module.exports = class MongoDriver {
|
|
|
16
16
|
return MongoClient.connect(uri, options);
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
+
disconnect() {
|
|
20
|
+
return this.connection.then(client => client.close());
|
|
21
|
+
}
|
|
22
|
+
|
|
19
23
|
raw(collection) {
|
|
20
24
|
return proxyPromise(this.connection.then(client => client.db().collection(collection)));
|
|
21
25
|
}
|
|
@@ -144,15 +148,15 @@ module.exports = class MongoDriver {
|
|
|
144
148
|
}
|
|
145
149
|
|
|
146
150
|
static getAddFields(query) {
|
|
147
|
-
const {
|
|
151
|
+
const { shape, where } = query;
|
|
148
152
|
|
|
149
|
-
return
|
|
150
|
-
const value = where[
|
|
153
|
+
return shape.reduce((prev, { from, type }) => {
|
|
154
|
+
const value = where[from];
|
|
151
155
|
if (value === undefined) return prev;
|
|
152
156
|
if (!isScalarDataType(type)) return prev;
|
|
153
157
|
const stype = String((type === 'Float' || type === 'Int' ? 'Number' : type)).toLowerCase();
|
|
154
158
|
if (String(typeof value) === `${stype}`) return prev;
|
|
155
|
-
return Object.assign(prev, { [
|
|
159
|
+
return Object.assign(prev, { [from]: { $toString: `$${from}` } });
|
|
156
160
|
}, {});
|
|
157
161
|
}
|
|
158
162
|
|
|
Binary file
|
package/src/graphql/ast/Model.js
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
const FS = require('fs');
|
|
2
2
|
const Glob = require('glob');
|
|
3
|
-
const Path = require('path');
|
|
4
3
|
const Merge = require('deepmerge');
|
|
5
4
|
const { nvl, uvl } = require('../../service/app.service');
|
|
6
5
|
const { validateSchema, makeExecutableSchema, mergeASTSchema, mergeASTArray } = require('../../service/graphql.service');
|
|
7
6
|
const Node = require('./Node');
|
|
8
7
|
const Model = require('./Model');
|
|
9
8
|
|
|
10
|
-
const loadFile = file => FS.readFileSync(
|
|
11
|
-
const reqFile = file => require(
|
|
9
|
+
const loadFile = file => FS.readFileSync(file, 'utf8');
|
|
10
|
+
const reqFile = file => require(file); // eslint-disable-line global-require,import/no-dynamic-require
|
|
12
11
|
|
|
13
12
|
module.exports = class Schema extends Node {
|
|
14
13
|
constructor(schema) {
|