@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 CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@coderich/autograph",
3
3
  "author": "Richard Livolsi (coderich)",
4
- "version": "0.9.13",
4
+ "version": "0.9.14",
5
5
  "description": "AutoGraph",
6
6
  "keywords": [
7
7
  "graphql",
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, promiseChain } = require('../service/app.service');
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();
@@ -1,6 +1,6 @@
1
1
  const { get } = require('lodash');
2
2
  const DataService = require('./DataService');
3
- const { map, ensureArray, keyPaths, mapPromise, toGUID, hashObject } = require('../service/app.service');
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((this.isScalar || this.isEmbedded) && !field.getResolvers().length); },
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, isScalar, isVirtual, isRequired, isEmbedded, modelRef, virtualField, useDefaultResolver } = fieldDef;
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
- // There are FIELD resolvers to run
147
- return new Promise((resolve, reject) => {
148
- return new Promise((res) => {
149
- // Scalars and Embeds do not need DB lookup
150
- if (isScalar || isEmbedded) return res($value);
151
-
152
- // Ensure where clause for DB lookup
153
- args.where = args.where || {};
154
-
155
- if (isArray) {
156
- if (isVirtual) {
157
- args.where[[virtualField]] = this.id; // Is where[[virtualField]] correct?
158
- return res(this.$$services.resolver.match(modelRef).merge(args).many());
159
- }
160
-
161
- // Not a "required" query + strip out nulls
162
- args.where.id = $value;
163
- return res(this.$$services.resolver.match(modelRef).merge(args).many());
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, JSON.stringify(args));
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
 
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
- };
@@ -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
- };
@@ -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
- };