@steedos/service-api 2.2.44 → 2.2.45

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.
Files changed (2) hide show
  1. package/index.js +128 -3
  2. package/package.json +3 -3
package/index.js CHANGED
@@ -8,7 +8,9 @@ const {
8
8
  // GraphQLDate,
9
9
  // GraphQLTime,
10
10
  GraphQLDateTime
11
- } = require('graphql-iso-date');
11
+ } = require('graphql-iso-date');
12
+
13
+ const _ = require('lodash');
12
14
 
13
15
  /**
14
16
  * @typedef {import('moleculer').Context} Context Moleculer's Context
@@ -178,7 +180,7 @@ module.exports = {
178
180
  onError(req, res, err) {
179
181
  res.setHeader("Content-Type", "application/json; charset=utf-8");
180
182
  res.writeHead(err.code || 500);
181
- res.end(JSON.stringify({error: err.message}));
183
+ res.end(JSON.stringify({ error: err.message }));
182
184
  }
183
185
  }
184
186
  ],
@@ -241,7 +243,130 @@ module.exports = {
241
243
  // if (req.$action.auth == "required" && !user) {
242
244
  // throw new ApiGateway.Errors.UnAuthorizedError("NO_RIGHTS");
243
245
  // }
244
- }
246
+ },
247
+
248
+ /**
249
+ * Create resolver for action
250
+ *
251
+ * @param {String} actionName
252
+ * @param {Object?} def
253
+ */
254
+ createActionResolver(actionName, def = {}) {
255
+ const {
256
+ dataLoader: useDataLoader = false,
257
+ nullIfError = false,
258
+ params: staticParams = {},
259
+ rootParams = {},
260
+ fileUploadArg = null,
261
+ } = def;
262
+ const rootKeys = Object.keys(rootParams);
263
+
264
+ return async (root, args, context, resolveInfo) => {
265
+ try {
266
+ if (useDataLoader) {
267
+ const dataLoaderMapKey = this.getDataLoaderMapKey(
268
+ actionName,
269
+ staticParams,
270
+ args
271
+ );
272
+ // if a dataLoader batching parameter is specified, then all root params can be data loaded;
273
+ // otherwise use only the primary rootParam
274
+ const primaryDataLoaderRootKey = rootKeys[0]; // for dataloader, use the first root key only
275
+ const dataLoaderBatchParam = this.dataLoaderBatchParams.get(actionName);
276
+ const dataLoaderUseAllRootKeys = dataLoaderBatchParam != null;
277
+
278
+ // check to see if the DataLoader has already been added to the GraphQL context; if not then add it for subsequent use
279
+ let dataLoader;
280
+ if (context.dataLoaders.has(dataLoaderMapKey)) {
281
+ dataLoader = context.dataLoaders.get(dataLoaderMapKey);
282
+ } else {
283
+ const batchedParamKey =
284
+ dataLoaderBatchParam || rootParams[primaryDataLoaderRootKey];
285
+
286
+ dataLoader = this.buildDataLoader(
287
+ context.ctx,
288
+ actionName,
289
+ batchedParamKey,
290
+ staticParams,
291
+ args,
292
+ { hashCacheKey: dataLoaderUseAllRootKeys } // must hash the cache key if not loading scalar
293
+ );
294
+ context.dataLoaders.set(dataLoaderMapKey, dataLoader);
295
+ }
296
+
297
+ let dataLoaderKey;
298
+ if (dataLoaderUseAllRootKeys) {
299
+ if (root && rootKeys) {
300
+ dataLoaderKey = {};
301
+
302
+ rootKeys.forEach(key => {
303
+ _.set(dataLoaderKey, rootParams[key], _.get(root, key));
304
+ });
305
+ }
306
+ } else {
307
+ dataLoaderKey = root && _.get(root, primaryDataLoaderRootKey);
308
+ }
309
+
310
+ if (dataLoaderKey == null) {
311
+ return null;
312
+ }
313
+
314
+ return Array.isArray(dataLoaderKey)
315
+ ? await dataLoader.loadMany(dataLoaderKey)
316
+ : await dataLoader.load(dataLoaderKey);
317
+ } else if (fileUploadArg != null && args[fileUploadArg] != null) {
318
+ const additionalArgs = _.omit(args, [fileUploadArg]);
319
+
320
+ if (Array.isArray(args[fileUploadArg])) {
321
+ return await Promise.all(
322
+ args[fileUploadArg].map(async uploadPromise => {
323
+ const { createReadStream, ...$fileInfo } =
324
+ await uploadPromise;
325
+ const stream = createReadStream();
326
+ return context.ctx.call(actionName, stream, {
327
+ meta: { $fileInfo, $args: additionalArgs },
328
+ });
329
+ })
330
+ );
331
+ }
332
+
333
+ const { createReadStream, ...$fileInfo } = await args[fileUploadArg];
334
+ const stream = createReadStream();
335
+ return await context.ctx.call(actionName, stream, {
336
+ meta: { $fileInfo, $args: additionalArgs },
337
+ });
338
+ } else {
339
+ const params = {};
340
+ if (root && rootKeys) {
341
+ rootKeys.forEach(key => {
342
+ _.set(params, rootParams[key], _.get(root, key));
343
+ });
344
+ }
345
+
346
+ let mergedParams = _.defaultsDeep({}, args, params, staticParams);
347
+
348
+ if (this.prepareContextParams) {
349
+ mergedParams = await this.prepareContextParams(
350
+ mergedParams,
351
+ actionName,
352
+ context
353
+ );
354
+ }
355
+
356
+ return await context.ctx.call(actionName, mergedParams, { meta: {resolveInfo} });
357
+ }
358
+ } catch (err) {
359
+ if (nullIfError) {
360
+ return null;
361
+ }
362
+ /* istanbul ignore next */
363
+ if (err && err.ctx) {
364
+ err.ctx = null; // Avoid circular JSON in Moleculer <= 0.13
365
+ }
366
+ throw err;
367
+ }
368
+ };
369
+ },
245
370
 
246
371
  }
247
372
  };
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@steedos/service-api",
3
- "version": "2.2.44",
3
+ "version": "2.2.45",
4
4
  "main": "index.js",
5
5
  "license": "MIT",
6
6
  "dependencies": {
7
- "@steedos/auth": "2.2.44",
7
+ "@steedos/auth": "2.2.45",
8
8
  "graphql-iso-date": "^3.6.1",
9
9
  "graphql-type-json": "^0.3.2",
10
10
  "moleculer-apollo-server": "^0.3.3",
@@ -14,5 +14,5 @@
14
14
  "publishConfig": {
15
15
  "access": "public"
16
16
  },
17
- "gitHead": "8cc999b9a464479dc147f2cdafd6c39b6d511d2f"
17
+ "gitHead": "0fb1ad43aedc498490d26ae5d8391df4ce34d6ea"
18
18
  }