@coderich/autograph 0.13.24 → 0.13.26

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
  "main": "index.js",
4
- "version": "0.13.24",
4
+ "version": "0.13.26",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -6,9 +6,11 @@ const { hashObject } = require('../service/AppService');
6
6
  module.exports = class Loader {
7
7
  #model;
8
8
  #loader;
9
+ #resolver;
9
10
 
10
- constructor(model) {
11
+ constructor(model, resolver) {
11
12
  this.#model = model;
13
+ this.#resolver = resolver;
12
14
  model.loader.cacheKeyFn ??= (query => hashObject(query.toCacheKey()));
13
15
  this.#loader = new DataLoader(keys => this.#resolve(keys), model.loader);
14
16
  }
@@ -28,8 +30,8 @@ module.exports = class Loader {
28
30
 
29
31
  return this.#model.source.client.resolve($query).then((data) => {
30
32
  if (data == null) return null; // Explicit return null;
31
- if ($query.isCursorPaging && Array.isArray(data)) return Loader.#paginateResults(data, query.toObject());
32
- return data;
33
+ if ($query.isCursorPaging && Array.isArray(data)) data = Loader.#paginateResults(data, query.toObject());
34
+ return this.#resolver.toResultSet(this.#model, data);
33
35
  });
34
36
  }));
35
37
  }
@@ -19,16 +19,8 @@ module.exports = class Pipeline {
19
19
  const wrapper = Object.defineProperty((args) => {
20
20
  try {
21
21
  if (ignoreNull && args.value == null) return args.value;
22
-
23
- if (ignoreNull && itemize) {
24
- return Util.map(args.value, (value) => {
25
- const v = factory({ ...args, value });
26
- return v === undefined ? value : v;
27
- });
28
- }
29
-
30
- const value = factory(args);
31
- return value === undefined ? args.value : value;
22
+ if (ignoreNull && itemize) return Util.map(args.value, value => Util.uvl(factory({ ...args, value }), value));
23
+ return Util.uvl(factory(args), args.value);
32
24
  } catch (e) {
33
25
  const { data = {} } = e;
34
26
  throw Boom.boomify(e, { data: { ...args, ...data } });
@@ -168,7 +160,7 @@ module.exports = class Pipeline {
168
160
  static resolve(params, pipeline) {
169
161
  const transformers = params.field.pipelines[pipeline] || [];
170
162
 
171
- return Util.pipeline(transformers.map(t => async (value) => {
163
+ return Util.pipeline(transformers.map(t => (value) => {
172
164
  return Pipeline[t]({ ...params, value });
173
165
  }), params.value);
174
166
  }
@@ -1,6 +1,7 @@
1
1
  const { graphql } = require('graphql');
2
2
  const Boom = require('@hapi/boom');
3
3
  const Util = require('@coderich/util');
4
+ const Pipeline = require('./Pipeline');
4
5
  const Emitter = require('./Emitter');
5
6
  const Loader = require('./Loader');
6
7
  const DataLoader = require('./DataLoader');
@@ -189,11 +190,13 @@ module.exports = class Resolver {
189
190
  */
190
191
  async resolve(query) {
191
192
  let thunk;
192
- const { model, doc, crud, isMutation, flags } = query.toObject();
193
+ const { model, crud, isMutation, flags } = query.toObject();
193
194
  const currSession = this.#sessions.slice(-1).pop();
194
195
 
195
196
  if (isMutation) {
196
197
  thunk = tquery => this.#schema.models[model].source.client.resolve(tquery.toDriver().toObject()).then((results) => {
198
+ const { doc, input } = tquery.toObject();
199
+
197
200
  // We clear the cache immediately (regardless if we're in transaction or not)
198
201
  this.clear(model);
199
202
 
@@ -201,7 +204,9 @@ module.exports = class Resolver {
201
204
  currSession?.thunks.push(...this.#sessions.map(s => () => s.parent.clear(model)));
202
205
 
203
206
  // Return results
204
- return crud === 'delete' ? doc : results;
207
+ if (crud === 'delete') return doc;
208
+ if (crud === 'update') return input;
209
+ return this.toResultSet(model, results);
205
210
  });
206
211
  } else {
207
212
  thunk = tquery => this.#dataLoaders[model].resolve(tquery);
@@ -210,7 +215,7 @@ module.exports = class Resolver {
210
215
  return this.#createSystemEvent(query, (tquery) => {
211
216
  return thunk(tquery).then((result) => {
212
217
  if (flags?.required && (result == null || result?.length === 0)) throw Boom.notFound();
213
- return crud === 'delete' ? result : this.toResultSet(model, result);
218
+ return result;
214
219
  });
215
220
  });
216
221
  }
@@ -220,7 +225,15 @@ module.exports = class Resolver {
220
225
  if (result == null) return result;
221
226
  if (typeof result !== 'object') return result;
222
227
  return Object.defineProperties(Util.map(result, (doc) => {
223
- const $doc = this.#schema.models[model].walk(doc, node => node.value !== undefined && Object.assign(node, { key: node.field.name }), { key: 'key' });
228
+ // Transform result to domain model
229
+ const $doc = this.#schema.models[model].walk(doc, (node) => {
230
+ if (node.value === undefined) return undefined;
231
+ if (node.value != null && node.field.isArray) node.value = Util.ensureArray(node.value);
232
+ node.key = node.field.name;
233
+ return node;
234
+ }, { key: 'key' });
235
+
236
+ // Assign useful/needed meta data
224
237
  return Object.defineProperties($doc, {
225
238
  $: {
226
239
  get: () => {
@@ -262,7 +275,7 @@ module.exports = class Resolver {
262
275
  return Object.entries(this.#schema.models).filter(([key, value]) => {
263
276
  return value.loader && value.isEntity;
264
277
  }).reduce((prev, [key, value]) => {
265
- return Object.assign(prev, { [key]: new DataLoader(value) });
278
+ return Object.assign(prev, { [key]: new DataLoader(value, this) });
266
279
  }, {});
267
280
  }
268
281
 
@@ -283,11 +296,12 @@ module.exports = class Resolver {
283
296
  // if (query.crud === 'update' && Util.isEqual({ added: {}, updated: {}, deleted: {} }, Util.changeset(query.doc, query.input))) return query.doc;
284
297
  const tquery = await $query.transform();
285
298
  // await Emitter.emit('validate', event); // We need to re-connect tquery to event
286
- return thunk(tquery).then((result) => {
287
- event.result = result; // backwards compat
288
- query.result = result;
289
- return Emitter.emit(`post${type}`, event);
290
- });
299
+ return thunk(tquery);
300
+ }).then((result) => {
301
+ event.doc ??= result; // Case of create
302
+ event.result = result; // backwards compat
303
+ query.result = result;
304
+ return Emitter.emit(`post${type}`, event);
291
305
  }).then((result = query.result) => result).catch((e) => {
292
306
  const { data = {} } = e;
293
307
  throw Boom.boomify(e, { data: { ...event, ...data } });