@coderich/autograph 0.9.13 → 0.9.14
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/.DS_Store +0 -0
- package/src/data/Field.js +1 -26
- package/src/data/ResultSet.js +24 -37
- package/src/data/Type.js +0 -14
- package/src/driver/MongoDriver.js +2 -1
- package/src/graphql/.DS_Store +0 -0
- package/src/graphql/extension/framework.js +0 -1
- package/src/data/ResultSetItem.js +0 -178
- package/src/data/ResultSetNew.js +0 -47
- package/src/data/ResultSetObj.js +0 -299
- package/src/data/ResultSetOriginal.js +0 -208
package/package.json
CHANGED
package/src/data/.DS_Store
CHANGED
|
Binary file
|
package/src/data/Field.js
CHANGED
|
@@ -2,7 +2,7 @@ const Type = require('./Type');
|
|
|
2
2
|
const Field = require('../graphql/ast/Field');
|
|
3
3
|
const Rule = require('../core/Rule');
|
|
4
4
|
const Transformer = require('../core/Transformer');
|
|
5
|
-
const { map, uvl, isPlainObject, ensureArray
|
|
5
|
+
const { map, uvl, isPlainObject, ensureArray } = require('../service/app.service');
|
|
6
6
|
|
|
7
7
|
module.exports = class extends Field {
|
|
8
8
|
constructor(model, field) {
|
|
@@ -63,17 +63,6 @@ module.exports = class extends Field {
|
|
|
63
63
|
return transformers.concat(this.type.getDeserializers());
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
-
getResolvers() {
|
|
67
|
-
const resolvers = [];
|
|
68
|
-
|
|
69
|
-
Object.entries(this.getDirectiveArgs('field', {})).forEach(([key, value]) => {
|
|
70
|
-
if (!Array.isArray(value)) value = [value];
|
|
71
|
-
if (key === 'resolve') resolvers.push(...value.map(t => Transformer.getInstances()[t]));
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
return resolvers.concat(this.type.getResolvers());
|
|
75
|
-
}
|
|
76
|
-
|
|
77
66
|
validate(query, value) {
|
|
78
67
|
const modelRef = this.getModelRef();
|
|
79
68
|
const rules = [...this.getRules()];
|
|
@@ -124,20 +113,6 @@ module.exports = class extends Field {
|
|
|
124
113
|
return this.transform(query, value, 'deserialize');
|
|
125
114
|
}
|
|
126
115
|
|
|
127
|
-
/**
|
|
128
|
-
* Applies any user-defined @field(resolve: [...methods]) in series
|
|
129
|
-
* This is ONLY run when resolving a value via the $<name> attribute
|
|
130
|
-
*/
|
|
131
|
-
resolve(query, value) {
|
|
132
|
-
const resolvers = [...this.getResolvers()];
|
|
133
|
-
|
|
134
|
-
return promiseChain(resolvers.map(fn => (chain) => {
|
|
135
|
-
return Promise.resolve(fn(this, uvl(this.cast(chain.pop()), value), query));
|
|
136
|
-
})).then((results) => {
|
|
137
|
-
return uvl(this.cast(results.pop()), value);
|
|
138
|
-
});
|
|
139
|
-
}
|
|
140
|
-
|
|
141
116
|
tform(query, value) {
|
|
142
117
|
// Determine transformers
|
|
143
118
|
const transformers = this.getTransformers();
|
package/src/data/ResultSet.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const { get } = require('lodash');
|
|
2
2
|
const DataService = require('./DataService');
|
|
3
|
-
const { map, ensureArray, keyPaths,
|
|
3
|
+
const { map, ensureArray, keyPaths, toGUID } = require('../service/app.service');
|
|
4
4
|
|
|
5
5
|
const modelCache = new WeakMap();
|
|
6
6
|
|
|
@@ -101,7 +101,7 @@ module.exports = class ResultSet {
|
|
|
101
101
|
virtualField: field.getVirtualField(),
|
|
102
102
|
// deserialize: field.deserialize.bind(field),
|
|
103
103
|
// fieldResolve: field.resolve.bind(field),
|
|
104
|
-
get useDefaultResolver() { return Boolean(
|
|
104
|
+
get useDefaultResolver() { return Boolean(this.isScalar || this.isEmbedded); },
|
|
105
105
|
}));
|
|
106
106
|
|
|
107
107
|
const template = ResultSet.makeModelTemplate(model, fieldDefs);
|
|
@@ -112,7 +112,7 @@ module.exports = class ResultSet {
|
|
|
112
112
|
|
|
113
113
|
static makeModelTemplate(model, fieldDefs) {
|
|
114
114
|
const definition = fieldDefs.reduce((prev, fieldDef) => {
|
|
115
|
-
const { field, key, name, isArray,
|
|
115
|
+
const { field, key, name, isArray, isVirtual, isRequired, isEmbedded, modelRef, virtualField, useDefaultResolver } = fieldDef;
|
|
116
116
|
const $name = `$${name}`;
|
|
117
117
|
|
|
118
118
|
// Deserialized field attributes
|
|
@@ -120,9 +120,7 @@ module.exports = class ResultSet {
|
|
|
120
120
|
get() {
|
|
121
121
|
if (this.$$services.cache.has(name)) return this.$$services.cache.get(name);
|
|
122
122
|
let $value = field.deserialize(this.$$services.query, this.$$services.data[key]);
|
|
123
|
-
if ($value != null && isEmbedded)
|
|
124
|
-
$value = new ResultSet(this.$$services.query.model(modelRef), $value, false);
|
|
125
|
-
}
|
|
123
|
+
if ($value != null && isEmbedded) $value = new ResultSet(this.$$services.query.model(modelRef), $value, false);
|
|
126
124
|
this.$$services.cache.set(name, $value);
|
|
127
125
|
return $value;
|
|
128
126
|
},
|
|
@@ -143,37 +141,26 @@ module.exports = class ResultSet {
|
|
|
143
141
|
// Default resolver return immediately!
|
|
144
142
|
if (useDefaultResolver) return $value;
|
|
145
143
|
|
|
146
|
-
//
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
if (isVirtual) {
|
|
167
|
-
args.where[[virtualField]] = this.id;
|
|
168
|
-
return res(this.$$services.resolver.match(modelRef).merge(args).one());
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
return res(this.$$services.resolver.match(modelRef).id($value).one({ required: isRequired }));
|
|
172
|
-
}).then((results) => {
|
|
173
|
-
if (results == null) return field.resolve(this.$$services.query, results); // Allow field to determine
|
|
174
|
-
return mapPromise(results, result => field.resolve(this.$$services.query, result)).then(() => results); // Resolve the inside fields but still return "results"!!!!
|
|
175
|
-
}).then(resolve).catch(reject);
|
|
176
|
-
});
|
|
144
|
+
// Ensure where clause for DB lookup
|
|
145
|
+
args.where = args.where || {};
|
|
146
|
+
|
|
147
|
+
if (isArray) {
|
|
148
|
+
if (isVirtual) {
|
|
149
|
+
args.where[[virtualField]] = this.id; // Is where[[virtualField]] correct?
|
|
150
|
+
return this.$$services.resolver.match(modelRef).merge(args).many();
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// Not a "required" query + strip out nulls
|
|
154
|
+
args.where.id = $value;
|
|
155
|
+
return this.$$services.resolver.match(modelRef).merge(args).many();
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
if (isVirtual) {
|
|
159
|
+
args.where[[virtualField]] = this.id;
|
|
160
|
+
return this.$$services.resolver.match(modelRef).merge(args).one();
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
return this.$$services.resolver.match(modelRef).id($value).one({ required: isRequired });
|
|
177
164
|
};
|
|
178
165
|
},
|
|
179
166
|
enumerable: false,
|
package/src/data/Type.js
CHANGED
|
@@ -69,18 +69,4 @@ module.exports = class extends Type {
|
|
|
69
69
|
|
|
70
70
|
return transformers;
|
|
71
71
|
}
|
|
72
|
-
|
|
73
|
-
getResolvers() {
|
|
74
|
-
const resolvers = [];
|
|
75
|
-
const scalarType = this.field.getScalarRef();
|
|
76
|
-
|
|
77
|
-
if (scalarType) {
|
|
78
|
-
Object.entries(scalarType.getDirectiveArgs('field', {})).forEach(([key, value]) => {
|
|
79
|
-
if (!Array.isArray(value)) value = [value];
|
|
80
|
-
if (key === 'resolve') resolvers.push(...value.map(t => Transformer.getInstances()[t]));
|
|
81
|
-
});
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
return resolvers;
|
|
85
|
-
}
|
|
86
72
|
};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
const Util = require('util');
|
|
1
2
|
const { get, has } = require('lodash');
|
|
2
3
|
const { MongoClient, ObjectID } = require('mongodb');
|
|
3
4
|
const { proxyDeep, toKeyObj, globToRegex, proxyPromise, isScalarDataType, promiseRetry } = require('../service/app.service');
|
|
@@ -25,7 +26,7 @@ module.exports = class MongoDriver {
|
|
|
25
26
|
}
|
|
26
27
|
|
|
27
28
|
query(collection, method, ...args) {
|
|
28
|
-
if (has(args[args.length - 1], 'debug')) console.log(collection, method,
|
|
29
|
+
if (has(args[args.length - 1], 'debug')) console.log(collection, method, Util.inspect(args, { depth: null, showHidden: false, colors: true }));
|
|
29
30
|
return this.raw(collection)[method](...args);
|
|
30
31
|
}
|
|
31
32
|
|
package/src/graphql/.DS_Store
CHANGED
|
Binary file
|
|
@@ -49,7 +49,6 @@ module.exports = (schema) => {
|
|
|
49
49
|
onDelete: AutoGraphOnDeleteEnum
|
|
50
50
|
|
|
51
51
|
enforce: [AutoGraphEnforceEnum!] #
|
|
52
|
-
resolve: [AutoGraphTransformEnum!] # Transforms when resolving
|
|
53
52
|
transform: [AutoGraphTransformEnum!] # Transforms when serialize + deserialize
|
|
54
53
|
serialize: [AutoGraphTransformEnum!] # Transforms when serialize
|
|
55
54
|
deserialize: [AutoGraphTransformEnum!] # Transforms when deserialize
|
|
@@ -1,178 +0,0 @@
|
|
|
1
|
-
const { get } = require('lodash');
|
|
2
|
-
const { map, keyPaths, mapPromise, toGUID, hashObject } = require('../service/app.service');
|
|
3
|
-
|
|
4
|
-
module.exports = class ResultSetItem {
|
|
5
|
-
constructor(model) {
|
|
6
|
-
const fields = model.getFields().filter(f => f.getName() !== 'id');
|
|
7
|
-
this.resultSetItem = this.createResultSetItem(fields);
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
create(query, data) {
|
|
11
|
-
if (data == null || typeof data !== 'object') return data;
|
|
12
|
-
Object.assign(this, query.toObject());
|
|
13
|
-
this.data = data;
|
|
14
|
-
this.query = query;
|
|
15
|
-
return this.resultSetItem;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
createResultSetItem(fields) {
|
|
19
|
-
const self = this;
|
|
20
|
-
const cache = new Map();
|
|
21
|
-
|
|
22
|
-
const definition = fields.reduce((prev, field) => {
|
|
23
|
-
const key = field.getKey();
|
|
24
|
-
const name = field.getName();
|
|
25
|
-
const $name = `$${name}`;
|
|
26
|
-
|
|
27
|
-
// Deserialized field attributes
|
|
28
|
-
prev[name] = {
|
|
29
|
-
get() {
|
|
30
|
-
const value = self.data[key];
|
|
31
|
-
if (cache.has(name)) return cache.get(name);
|
|
32
|
-
let $value = field.deserialize(self.query, value);
|
|
33
|
-
if ($value != null && field.isEmbedded()) {
|
|
34
|
-
const modelRef = field.getModelRef();
|
|
35
|
-
const newQuery = self.query.model(modelRef);
|
|
36
|
-
$value = map($value, $v => modelRef.getResultSetItem().create(newQuery, $v));
|
|
37
|
-
}
|
|
38
|
-
cache.set(name, $value);
|
|
39
|
-
return $value;
|
|
40
|
-
},
|
|
41
|
-
set($value) {
|
|
42
|
-
cache.set(name, $value);
|
|
43
|
-
},
|
|
44
|
-
enumerable: true,
|
|
45
|
-
configurable: true, // Allows things like delete
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
// Fully deserialized, hydrated, and resolved field attributes
|
|
49
|
-
prev[$name] = {
|
|
50
|
-
get() {
|
|
51
|
-
return (args = {}) => {
|
|
52
|
-
// Ensure where clause
|
|
53
|
-
args.where = args.where || {};
|
|
54
|
-
|
|
55
|
-
// Cache
|
|
56
|
-
const cacheKey = `${$name}-${hashObject(args)}`;
|
|
57
|
-
if (cache.has(cacheKey)) return cache.get(cacheKey);
|
|
58
|
-
|
|
59
|
-
const promise = new Promise((resolve, reject) => {
|
|
60
|
-
(() => {
|
|
61
|
-
const $value = this[name];
|
|
62
|
-
|
|
63
|
-
if (field.isScalar() || field.isEmbedded()) return Promise.resolve($value);
|
|
64
|
-
|
|
65
|
-
const modelRef = field.getModelRef();
|
|
66
|
-
|
|
67
|
-
if (field.isArray()) {
|
|
68
|
-
if (field.isVirtual()) {
|
|
69
|
-
args.where[[field.getVirtualField()]] = this.id; // Is where[[field.getVirtualField()]] correct?
|
|
70
|
-
return self.resolver.match(modelRef).merge(args).many();
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
// Not a "required" query + strip out nulls
|
|
74
|
-
args.where.id = $value;
|
|
75
|
-
return self.resolver.match(modelRef).merge(args).many();
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
if (field.isVirtual()) {
|
|
79
|
-
args.where[[field.getVirtualField()]] = this.id;
|
|
80
|
-
return self.resolver.match(modelRef).merge(args).one();
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
return self.resolver.match(modelRef).id($value).one({ required: field.isRequired() });
|
|
84
|
-
})().then((results) => {
|
|
85
|
-
if (results == null) return field.resolve(self.query, results); // Allow field to determine
|
|
86
|
-
return mapPromise(results, result => field.resolve(self.query, result)).then(() => results); // Resolve the inside fields but still return "results"!!!!
|
|
87
|
-
}).then((resolved) => {
|
|
88
|
-
resolve(resolved);
|
|
89
|
-
}).catch((e) => {
|
|
90
|
-
reject(e);
|
|
91
|
-
});
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
cache.set(cacheKey, promise);
|
|
95
|
-
return promise;
|
|
96
|
-
};
|
|
97
|
-
},
|
|
98
|
-
enumerable: false,
|
|
99
|
-
};
|
|
100
|
-
|
|
101
|
-
// Field count (let's assume it's a Connection Type - meaning dont try with anything else)
|
|
102
|
-
prev[`${$name}:count`] = {
|
|
103
|
-
get() {
|
|
104
|
-
return (q = {}) => {
|
|
105
|
-
q.where = q.where || {};
|
|
106
|
-
if (field.isVirtual()) q.where[field.getVirtualField()] = this.id;
|
|
107
|
-
else q.where.id = this[name];
|
|
108
|
-
return self.resolver.match(field.getModelRef()).merge(q).count();
|
|
109
|
-
};
|
|
110
|
-
},
|
|
111
|
-
enumerable: false,
|
|
112
|
-
};
|
|
113
|
-
|
|
114
|
-
return prev;
|
|
115
|
-
}, {
|
|
116
|
-
id: {
|
|
117
|
-
get() { return self.data.id || self.data[self.model.idKey()]; },
|
|
118
|
-
set(id) { self.data.id = id; }, // Embedded array of documents need to set id
|
|
119
|
-
enumerable: true,
|
|
120
|
-
},
|
|
121
|
-
|
|
122
|
-
$id: {
|
|
123
|
-
get() { return toGUID(self.model.getName(), this.id); },
|
|
124
|
-
enumerable: false,
|
|
125
|
-
},
|
|
126
|
-
|
|
127
|
-
$$cursor: {
|
|
128
|
-
get() {
|
|
129
|
-
const sortPaths = keyPaths(self.sort);
|
|
130
|
-
const sortValues = sortPaths.reduce((prv, path) => Object.assign(prv, { [path]: get(this, path) }), {});
|
|
131
|
-
const sortJSON = JSON.stringify(sortValues);
|
|
132
|
-
return Buffer.from(sortJSON).toString('base64');
|
|
133
|
-
},
|
|
134
|
-
enumerable: false,
|
|
135
|
-
},
|
|
136
|
-
|
|
137
|
-
$$model: {
|
|
138
|
-
value: self.model,
|
|
139
|
-
enumerable: false,
|
|
140
|
-
},
|
|
141
|
-
|
|
142
|
-
$$isResultSetItem: {
|
|
143
|
-
value: true,
|
|
144
|
-
enumerable: false,
|
|
145
|
-
},
|
|
146
|
-
|
|
147
|
-
$$save: {
|
|
148
|
-
get() { return input => self.resolver.match(self.model).id(this.id).save({ ...this, ...input }); },
|
|
149
|
-
enumerable: false,
|
|
150
|
-
},
|
|
151
|
-
|
|
152
|
-
$$remove: {
|
|
153
|
-
get() { return () => self.resolver.match(self.model).id(this.id).remove(); },
|
|
154
|
-
enumerable: false,
|
|
155
|
-
},
|
|
156
|
-
|
|
157
|
-
$$delete: {
|
|
158
|
-
get() { return () => self.resolver.match(self.model).id(this.id).delete(); },
|
|
159
|
-
enumerable: false,
|
|
160
|
-
},
|
|
161
|
-
|
|
162
|
-
toObject: {
|
|
163
|
-
get() {
|
|
164
|
-
return () => map(this, obj => Object.entries(obj).reduce((prev, [key, value]) => {
|
|
165
|
-
if (value === undefined) return prev;
|
|
166
|
-
prev[key] = get(value, '$$isResultSet') ? value.toObject() : value;
|
|
167
|
-
return prev;
|
|
168
|
-
}, {}));
|
|
169
|
-
},
|
|
170
|
-
enumerable: false,
|
|
171
|
-
configurable: true,
|
|
172
|
-
},
|
|
173
|
-
});
|
|
174
|
-
|
|
175
|
-
// Create and return ResultSetItem
|
|
176
|
-
return Object.defineProperties({}, definition);
|
|
177
|
-
}
|
|
178
|
-
};
|
package/src/data/ResultSetNew.js
DELETED
|
@@ -1,47 +0,0 @@
|
|
|
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
|
-
};
|
package/src/data/ResultSetObj.js
DELETED
|
@@ -1,299 +0,0 @@
|
|
|
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
|
-
};
|
|
@@ -1,208 +0,0 @@
|
|
|
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
|
-
|
|
9
|
-
const { resolver, model, sort, first, after, last, before } = query.toObject();
|
|
10
|
-
const fields = model.getFields().filter(f => f.getName() !== 'id');
|
|
11
|
-
|
|
12
|
-
const rs = map(data, (doc) => {
|
|
13
|
-
if (doc == null || typeof doc !== 'object') return doc;
|
|
14
|
-
|
|
15
|
-
//
|
|
16
|
-
const cache = new Map();
|
|
17
|
-
|
|
18
|
-
const definition = fields.reduce((prev, field) => {
|
|
19
|
-
const key = field.getKey();
|
|
20
|
-
const name = field.getName();
|
|
21
|
-
const $name = `$${name}`;
|
|
22
|
-
const value = doc[key];
|
|
23
|
-
|
|
24
|
-
// Deserialized field attributes
|
|
25
|
-
prev[name] = {
|
|
26
|
-
// value,
|
|
27
|
-
get() {
|
|
28
|
-
if (cache.has(name)) return cache.get(name);
|
|
29
|
-
let $value = field.deserialize(query, value);
|
|
30
|
-
$value = $value != null && field.isEmbedded() ? new ResultSet(query.model(field.getModelRef()), $value, false) : $value;
|
|
31
|
-
cache.set(name, $value);
|
|
32
|
-
return $value;
|
|
33
|
-
},
|
|
34
|
-
set($value) {
|
|
35
|
-
cache.set(name, $value);
|
|
36
|
-
},
|
|
37
|
-
enumerable: true,
|
|
38
|
-
configurable: true, // Allows things like delete
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
// Fully deserialized, hydrated, and resolved field attributes
|
|
42
|
-
prev[$name] = {
|
|
43
|
-
// value: () => value,
|
|
44
|
-
get() {
|
|
45
|
-
return (args = {}) => {
|
|
46
|
-
// Ensure where clause
|
|
47
|
-
args.where = args.where || {};
|
|
48
|
-
|
|
49
|
-
// Cache
|
|
50
|
-
const cacheKey = `${$name}-${hashObject(args)}`;
|
|
51
|
-
if (cache.has(cacheKey)) return cache.get(cacheKey);
|
|
52
|
-
|
|
53
|
-
const promise = new Promise((resolve, reject) => {
|
|
54
|
-
(() => {
|
|
55
|
-
const $value = this[name];
|
|
56
|
-
|
|
57
|
-
if (field.isScalar() || field.isEmbedded()) return Promise.resolve($value);
|
|
58
|
-
|
|
59
|
-
const modelRef = field.getModelRef();
|
|
60
|
-
|
|
61
|
-
if (field.isArray()) {
|
|
62
|
-
if (field.isVirtual()) {
|
|
63
|
-
args.where[[field.getVirtualField()]] = this.id; // Is where[[field.getVirtualField()]] correct?
|
|
64
|
-
return resolver.match(modelRef).merge(args).many();
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
// Not a "required" query + strip out nulls
|
|
68
|
-
args.where.id = $value;
|
|
69
|
-
return resolver.match(modelRef).merge(args).many();
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
if (field.isVirtual()) {
|
|
73
|
-
args.where[[field.getVirtualField()]] = this.id;
|
|
74
|
-
return resolver.match(modelRef).merge(args).one();
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
return resolver.match(modelRef).id($value).one({ required: field.isRequired() });
|
|
78
|
-
})().then((results) => {
|
|
79
|
-
if (results == null) return field.resolve(query, results); // Allow field to determine
|
|
80
|
-
return mapPromise(results, result => field.resolve(query, result)).then(() => results); // Resolve the inside fields but still return "results"!!!!
|
|
81
|
-
}).then((resolved) => {
|
|
82
|
-
resolve(resolved);
|
|
83
|
-
}).catch((e) => {
|
|
84
|
-
reject(e);
|
|
85
|
-
});
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
cache.set(cacheKey, promise);
|
|
89
|
-
return promise;
|
|
90
|
-
};
|
|
91
|
-
},
|
|
92
|
-
enumerable: false,
|
|
93
|
-
};
|
|
94
|
-
|
|
95
|
-
// Field count (let's assume it's a Connection Type - meaning dont try with anything else)
|
|
96
|
-
prev[`${$name}:count`] = {
|
|
97
|
-
get() {
|
|
98
|
-
return (q = {}) => {
|
|
99
|
-
q.where = q.where || {};
|
|
100
|
-
if (field.isVirtual()) q.where[field.getVirtualField()] = this.id;
|
|
101
|
-
else q.where.id = this[name];
|
|
102
|
-
return resolver.match(field.getModelRef()).merge(q).count();
|
|
103
|
-
};
|
|
104
|
-
},
|
|
105
|
-
enumerable: false,
|
|
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
|
-
},
|
|
167
|
-
});
|
|
168
|
-
|
|
169
|
-
// Create and return ResultSetItem
|
|
170
|
-
return Object.defineProperties({}, definition);
|
|
171
|
-
});
|
|
172
|
-
|
|
173
|
-
let hasNextPage = false;
|
|
174
|
-
let hasPreviousPage = false;
|
|
175
|
-
if (adjustForPagination && rs.length) (({ hasPreviousPage, hasNextPage } = DataService.paginateResultSet(rs, first, after, last, before)));
|
|
176
|
-
|
|
177
|
-
return Object.defineProperties(rs, {
|
|
178
|
-
$$pageInfo: {
|
|
179
|
-
get() {
|
|
180
|
-
const edges = ensureArray(rs);
|
|
181
|
-
|
|
182
|
-
return {
|
|
183
|
-
startCursor: get(edges, '0.$$cursor', ''),
|
|
184
|
-
endCursor: get(edges, `${edges.length - 1}.$$cursor`, ''),
|
|
185
|
-
hasPreviousPage,
|
|
186
|
-
hasNextPage,
|
|
187
|
-
};
|
|
188
|
-
},
|
|
189
|
-
enumerable: false,
|
|
190
|
-
},
|
|
191
|
-
$$isResultSet: {
|
|
192
|
-
value: true,
|
|
193
|
-
enumerable: false,
|
|
194
|
-
},
|
|
195
|
-
toObject: {
|
|
196
|
-
get() {
|
|
197
|
-
return () => map(this, doc => Object.entries(doc).reduce((prev, [key, value]) => {
|
|
198
|
-
if (value === undefined) return prev;
|
|
199
|
-
prev[key] = get(value, '$$isResultSet') ? value.toObject() : value;
|
|
200
|
-
return prev;
|
|
201
|
-
}, {}));
|
|
202
|
-
},
|
|
203
|
-
enumerable: false,
|
|
204
|
-
configurable: true,
|
|
205
|
-
},
|
|
206
|
-
});
|
|
207
|
-
}
|
|
208
|
-
};
|