@restorecommerce/facade 1.0.1 → 1.1.1

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 (56) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/codegen/index.js +1 -1
  3. package/dist/gql/protos/federation.d.ts +6 -0
  4. package/dist/gql/protos/federation.js +51 -0
  5. package/dist/gql/protos/graphql.d.ts +5 -27
  6. package/dist/gql/protos/graphql.js +3 -564
  7. package/dist/gql/protos/index.d.ts +3 -0
  8. package/dist/gql/protos/index.js +3 -0
  9. package/dist/gql/protos/registry.d.ts +2 -2
  10. package/dist/gql/protos/resolvers.d.ts +9 -0
  11. package/dist/gql/protos/resolvers.js +427 -0
  12. package/dist/gql/protos/schema.d.ts +14 -0
  13. package/dist/gql/protos/schema.js +234 -0
  14. package/dist/gql/protos/types.d.ts +20 -0
  15. package/dist/gql/protos/utils.d.ts +5 -0
  16. package/dist/gql/protos/utils.js +27 -1
  17. package/dist/index.d.ts +9 -9
  18. package/dist/index.js +78 -7
  19. package/dist/interfaces.d.ts +2 -0
  20. package/dist/modules/access-control/gql/schema.generated.d.ts +30 -0
  21. package/dist/modules/access-control/gql/schema.generated.js +7 -1
  22. package/dist/modules/catalog/gql/schema.generated.d.ts +30 -0
  23. package/dist/modules/catalog/gql/schema.generated.js +7 -1
  24. package/dist/modules/fulfillment/gql/schema.generated.d.ts +183 -113
  25. package/dist/modules/fulfillment/gql/schema.generated.js +13 -6
  26. package/dist/modules/identity/gql/federation.d.ts +1 -1
  27. package/dist/modules/identity/gql/federation.js +1 -9
  28. package/dist/modules/identity/gql/schema.generated.d.ts +35 -0
  29. package/dist/modules/identity/gql/schema.generated.js +7 -1
  30. package/dist/modules/identity/gql/types.js +2 -0
  31. package/dist/modules/indexing/gql/federation.d.ts +2 -2
  32. package/dist/modules/indexing/gql/federation.js +2 -2
  33. package/dist/modules/indexing/gql/schema.d.ts +2 -2
  34. package/dist/modules/indexing/gql/schema.generated.d.ts +43 -2
  35. package/dist/modules/indexing/gql/schema.generated.js +7 -0
  36. package/dist/modules/indexing/gql/schema.js +1 -2
  37. package/dist/modules/indexing/gql/types.d.ts +2 -0
  38. package/dist/modules/indexing/gql/types.js +5 -2
  39. package/dist/modules/indexing/interfaces.d.ts +2 -2
  40. package/dist/modules/invoicing/gql/schema.generated.d.ts +87 -8
  41. package/dist/modules/invoicing/gql/schema.generated.js +7 -1
  42. package/dist/modules/notification/gql/schema.generated.d.ts +30 -0
  43. package/dist/modules/notification/gql/schema.generated.js +7 -1
  44. package/dist/modules/ordering/gql/federation.js +4 -4
  45. package/dist/modules/ordering/gql/schema.generated.d.ts +257 -195
  46. package/dist/modules/ordering/gql/schema.generated.js +18 -1
  47. package/dist/modules/ostorage/gql/schema.generated.d.ts +30 -0
  48. package/dist/modules/ostorage/gql/schema.generated.js +7 -1
  49. package/dist/modules/payment/gql/schema.generated.d.ts +30 -0
  50. package/dist/modules/payment/gql/schema.generated.js +7 -1
  51. package/dist/modules/resource/gql/schema.generated.d.ts +114 -12
  52. package/dist/modules/resource/gql/schema.generated.js +7 -1
  53. package/dist/modules/scheduling/gql/schema.generated.d.ts +30 -0
  54. package/dist/modules/scheduling/gql/schema.generated.js +7 -1
  55. package/generate.ts +6 -3
  56. package/package.json +18 -9
@@ -1,65 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.camelCase = exports.generateSubServiceResolvers = exports.generateSubServiceSchemas = exports.getAndGenerateResolvers = exports.getAndGenerateSchema = exports.getWhitelistBlacklistConfig = exports.generateSchema = exports.registerResolverSchema = exports.generateResolver = exports.registerResolverFunction = exports.getGQLResolverFunctions = exports.postProcessGQLValue = exports.preprocessGQLInput = exports.getGQLSchemas = exports.getGQLSchema = void 0;
3
+ exports.getWhitelistBlacklistConfig = exports.postProcessGQLValue = exports.preprocessGQLInput = exports.Mutate = void 0;
4
4
  const graphql_1 = require("graphql");
5
5
  const definition_1 = require("graphql/type/definition");
6
- const types_1 = require("./types");
7
- const registry_1 = require("./registry");
8
- const utils_1 = require("./utils");
9
- const stream = require("stream");
10
- const _ = require("lodash");
11
- const rc_grpc_clients_1 = require("@restorecommerce/rc-grpc-clients");
12
- const resource_base_1 = require("@restorecommerce/rc-grpc-clients/dist/generated/io/restorecommerce/resource_base");
13
- const array_prototype_flat_1 = require("array.prototype.flat");
14
- const typeCache = new Map();
15
- const Mutate = ['Create', 'Update', 'Upsert'];
16
- const inputMethodType = new Map();
17
- const getGQLSchema = (method) => {
18
- const fields = {
19
- // operationStatus: {
20
- // type: new GraphQLNonNull(OperationStatusType),
21
- // },
22
- };
23
- const responseTyping = (0, registry_1.getTyping)(method.outputType);
24
- if (!responseTyping) {
25
- throw Error('Method doesn\'t have registered typings: ' + method.outputType);
26
- }
27
- if (method.outputType !== '.google.protobuf.Empty') {
28
- fields['details'] = {
29
- type: responseTyping.output,
30
- };
31
- }
32
- const outName = 'Proto' + (0, utils_1.capitalizeProtoName)(method.outputType);
33
- let out = typeCache.get(outName);
34
- if (!out) {
35
- out = new graphql_1.GraphQLObjectType({
36
- name: outName,
37
- fields,
38
- });
39
- typeCache.set(outName, out);
40
- }
41
- const typing = (0, registry_1.getTyping)(method.inputType);
42
- if (!typing) {
43
- throw Error('Method doesn\'t have registered typings: ' + method.inputType);
44
- }
45
- return {
46
- type: out,
47
- args: method.inputType === '.google.protobuf.Empty' ? undefined : {
48
- input: {
49
- type: new graphql_1.GraphQLNonNull(typing.input)
50
- }
51
- }
52
- };
53
- };
54
- exports.getGQLSchema = getGQLSchema;
55
- const getGQLSchemas = (service) => {
56
- var _a;
57
- return (_a = service.method) === null || _a === void 0 ? void 0 : _a.reduce((obj, method) => {
58
- obj[method.name] = (0, exports.getGQLSchema)(method);
59
- return obj;
60
- }, {});
61
- };
62
- exports.getGQLSchemas = getGQLSchemas;
6
+ exports.Mutate = ['Create', 'Update', 'Upsert'];
63
7
  const preprocessGQLInput = async (data, model) => {
64
8
  if (model instanceof definition_1.GraphQLEnumType) {
65
9
  return data;
@@ -153,353 +97,6 @@ const postProcessGQLValue = (data, model) => {
153
97
  return data;
154
98
  };
155
99
  exports.postProcessGQLValue = postProcessGQLValue;
156
- const getGQLResolverFunctions = (service, key, serviceKey, cfg) => {
157
- if (!service.method) {
158
- return {};
159
- }
160
- return service.method.reduce((obj, method) => {
161
- var _a, _b, _c, _d;
162
- if ((_b = (_a = cfg[serviceKey]) === null || _a === void 0 ? void 0 : _a.methods) === null || _b === void 0 ? void 0 : _b.blacklist) {
163
- const blacklistMethods = (_d = (_c = cfg[serviceKey]) === null || _c === void 0 ? void 0 : _c.methods) === null || _d === void 0 ? void 0 : _d.blacklist;
164
- if (blacklistMethods.includes(method.name)) {
165
- return {};
166
- }
167
- }
168
- const typing = (0, registry_1.getTyping)(method.inputType);
169
- const outputTyping = (0, registry_1.getTyping)(method.outputType);
170
- if (!typing) {
171
- throw Error(`Method '${method.name}' could not find input type: ${method.inputType}`);
172
- }
173
- if (!outputTyping) {
174
- throw Error(`Method '${method.name}' could not find output type: ${method.outputType}`);
175
- }
176
- if (!('fromPartial' in typing.processor)) {
177
- throw Error(`Method ${method.name} input type '${method.inputType}' does not contain 'fromPartial' function`);
178
- }
179
- let subjectField = null;
180
- if (typing) {
181
- for (let field of typing.meta.field) {
182
- if (field.typeName === types_1.authSubjectType) {
183
- subjectField = field.name;
184
- break;
185
- }
186
- }
187
- }
188
- let methodName = method.name;
189
- if (Mutate.indexOf(method.name) > -1) {
190
- methodName = 'Mutate';
191
- }
192
- if (methodName in obj) {
193
- return obj;
194
- }
195
- obj[methodName] = async (args, context) => {
196
- var _a, _b;
197
- const client = context[key].client;
198
- const service = client[serviceKey];
199
- try {
200
- const converted = await (0, exports.preprocessGQLInput)(args.input, typing.input);
201
- const scope = (_a = args === null || args === void 0 ? void 0 : args.input) === null || _a === void 0 ? void 0 : _a.scope;
202
- let req = typing.processor.fromPartial(converted);
203
- // convert enum strings to integers
204
- req = (0, utils_1.convertEnumToInt)(typing, req);
205
- if (subjectField !== null) {
206
- req.subject = (0, registry_1.getTyping)(types_1.authSubjectType).processor.fromPartial({});
207
- const authToken = context.request.req.headers['authorization'];
208
- if (authToken && authToken.startsWith('Bearer ')) {
209
- req.subject.token = authToken.split(' ')[1];
210
- }
211
- if (scope) {
212
- req.subject.scope = scope;
213
- }
214
- }
215
- let realMethod = method.name;
216
- if (Mutate.indexOf(method.name) > -1) {
217
- const mode = (_b = args === null || args === void 0 ? void 0 : args.input) === null || _b === void 0 ? void 0 : _b.mode;
218
- if (!mode) {
219
- throw new Error('Please specify mode');
220
- }
221
- if (mode === 'CREATE') {
222
- realMethod = 'Create';
223
- }
224
- else if (mode === 'UPDATE') {
225
- realMethod = 'Update';
226
- }
227
- else if (mode === 'UPSERT') {
228
- realMethod = 'Upsert';
229
- }
230
- }
231
- const methodFunc = service[camelCase(realMethod)] || service[realMethod];
232
- const rawResult = await methodFunc(req);
233
- const result = (0, exports.postProcessGQLValue)(rawResult, outputTyping.output);
234
- const grpcClientConfig = cfg.client;
235
- const bufferFields = (0, utils_1.getKeys)(grpcClientConfig === null || grpcClientConfig === void 0 ? void 0 : grpcClientConfig.bufferFields);
236
- if (result instanceof stream.Readable) {
237
- let operationStatus = { code: 0, message: '' };
238
- let aggregatedResponse = await new Promise((resolve, reject) => {
239
- let response = {};
240
- let combinedChunks = {};
241
- result.on('data', (chunk) => {
242
- const chunkObj = _.cloneDeep(chunk);
243
- if (!combinedChunks) {
244
- combinedChunks = chunk;
245
- }
246
- else {
247
- Object.assign(combinedChunks, chunk);
248
- }
249
- const existingBufferFields = _.intersection(Object.keys(chunk), bufferFields);
250
- for (let bufferField of existingBufferFields) {
251
- if (chunkObj[bufferField] && chunkObj[bufferField].value) {
252
- if (!response[bufferField]) {
253
- response[bufferField] = { value: [] };
254
- }
255
- if (response[bufferField] && response[bufferField].value && !_.isArray(response[bufferField].value)) {
256
- response[bufferField].value = [];
257
- }
258
- let data = JSON.parse(chunkObj[bufferField].value.toString());
259
- if (_.isArray(data)) {
260
- for (let dataObj of data) {
261
- response[bufferField].value.push(dataObj);
262
- }
263
- }
264
- else {
265
- response[bufferField].value.push(data);
266
- }
267
- }
268
- }
269
- });
270
- result.on('error', (err) => {
271
- console.error(err);
272
- operationStatus.code = err.code ? err.code : 500;
273
- operationStatus.message = err.message;
274
- });
275
- result.on('end', () => {
276
- if (_.isEmpty(operationStatus.message)) {
277
- operationStatus.code = 200;
278
- operationStatus.message = 'success';
279
- }
280
- if (!_.isEmpty(response)) {
281
- resolve(response);
282
- }
283
- else if (!_.isEmpty(combinedChunks)) {
284
- resolve(combinedChunks);
285
- }
286
- });
287
- });
288
- return { details: aggregatedResponse, operationStatus };
289
- }
290
- if ('items' in result) {
291
- let items = (0, utils_1.decodeBufferFields)(result.items, bufferFields);
292
- return {
293
- details: {
294
- items: items,
295
- operationStatus: result.operationStatus // overall status
296
- },
297
- };
298
- }
299
- else {
300
- return {
301
- details: (0, utils_1.decodeBufferFields)([result], bufferFields)[0]
302
- };
303
- }
304
- }
305
- catch (error) {
306
- console.error(error);
307
- return {
308
- details: {
309
- items: [],
310
- operationStatus: {
311
- code: error.code,
312
- message: error.message
313
- }
314
- }
315
- };
316
- }
317
- };
318
- return obj;
319
- }, {});
320
- };
321
- exports.getGQLResolverFunctions = getGQLResolverFunctions;
322
- const namespaceResolverRegistry = new Map();
323
- const registerResolverFunction = (namespace, name, func, mutation = false, subspace = undefined, service) => {
324
- if (!namespaceResolverRegistry.has(namespace)) {
325
- namespaceResolverRegistry.set(namespace, new Map());
326
- }
327
- if (!namespaceResolverRegistry.get(namespace).has(mutation)) {
328
- namespaceResolverRegistry.get(namespace).set(mutation, new Map());
329
- }
330
- let space = namespaceResolverRegistry.get(namespace).get(mutation);
331
- if (subspace) {
332
- if (!space.has(subspace)) {
333
- space.set(subspace, new Map());
334
- }
335
- space = space.get(subspace);
336
- }
337
- if (space.has(name)) {
338
- if (subspace) {
339
- throw new Error(`Namespace "${namespace}"."${subspace}" already contains a function: ${name} (mutation: ${mutation})`);
340
- }
341
- else {
342
- throw new Error(`Namespace "${namespace}" already contains a function: ${name} (mutation: ${mutation})`);
343
- }
344
- }
345
- if (service) {
346
- const key = (namespace === null || namespace === void 0 ? void 0 : namespace.toLocaleLowerCase()) + '.' + (subspace === null || subspace === void 0 ? void 0 : subspace.toLocaleLowerCase()) + '.' + (name === null || name === void 0 ? void 0 : name.toLocaleLowerCase());
347
- const value = service.method.find((m) => m.name === name);
348
- if (key && (value === null || value === void 0 ? void 0 : value.inputType)) {
349
- inputMethodType.set(key, value.inputType);
350
- }
351
- }
352
- space.set(name, func);
353
- };
354
- exports.registerResolverFunction = registerResolverFunction;
355
- const generateResolver = (...namespaces) => {
356
- const queryResolvers = {};
357
- const mutationResolvers = {};
358
- namespaces.forEach(ns => {
359
- if (!namespaceResolverRegistry.has(ns)) {
360
- throw new Error(`Namespace "${ns}" has no registered functions`);
361
- }
362
- if (namespaceResolverRegistry.get(ns).has(false)) {
363
- const res = {};
364
- namespaceResolverRegistry.get(ns).get(false).forEach((value, key) => {
365
- if (value instanceof Map) {
366
- res[key] = Object.fromEntries(value);
367
- }
368
- else {
369
- res[key] = value;
370
- }
371
- });
372
- queryResolvers[ns] = () => res;
373
- }
374
- if (namespaceResolverRegistry.get(ns).has(true)) {
375
- const res = {};
376
- namespaceResolverRegistry.get(ns).get(true).forEach((value, key) => {
377
- if (value instanceof Map) {
378
- res[key] = Object.fromEntries(value);
379
- }
380
- else {
381
- res[key] = value;
382
- }
383
- });
384
- mutationResolvers[ns] = () => res;
385
- }
386
- });
387
- const resolvers = {};
388
- if (Object.keys(queryResolvers).length > 0) {
389
- resolvers.Query = queryResolvers;
390
- }
391
- if (Object.keys(mutationResolvers).length > 0) {
392
- resolvers.Mutation = mutationResolvers;
393
- }
394
- return resolvers;
395
- };
396
- exports.generateResolver = generateResolver;
397
- const namespaceResolverSchemaRegistry = new Map();
398
- const registerResolverSchema = (namespace, name, schema, mutation = false, subspace = undefined, config) => {
399
- if (!namespaceResolverSchemaRegistry.has(namespace)) {
400
- namespaceResolverSchemaRegistry.set(namespace, new Map());
401
- }
402
- if (subspace && config[subspace]) {
403
- const blacklistMethods = config[subspace].methods.blacklist;
404
- if (blacklistMethods.includes(name)) {
405
- return;
406
- }
407
- }
408
- if (!namespaceResolverSchemaRegistry.get(namespace).has(mutation)) {
409
- namespaceResolverSchemaRegistry.get(namespace).set(mutation, new Map());
410
- }
411
- let space = namespaceResolverSchemaRegistry.get(namespace).get(mutation);
412
- if (subspace) {
413
- if (!space.has(subspace)) {
414
- space.set(subspace, new Map());
415
- }
416
- space = space.get(subspace);
417
- }
418
- if (space.has(name)) {
419
- if (subspace) {
420
- throw new Error(`Namespace "${namespace}"."${subspace}" already contains a schema: ${name} (mutation: ${mutation})`);
421
- }
422
- else {
423
- throw new Error(`Namespace "${namespace}" already contains a schema: ${name} (mutation: ${mutation})`);
424
- }
425
- }
426
- // register create, update and upsert with Mutate
427
- if (Mutate.indexOf(name) > -1) {
428
- name = 'Mutate';
429
- }
430
- space.set(name, schema);
431
- };
432
- exports.registerResolverSchema = registerResolverSchema;
433
- const generateSchema = (setup) => {
434
- const queryFields = {};
435
- const mutationFields = {};
436
- setup.forEach(s => {
437
- if (!namespaceResolverSchemaRegistry.has(s.namespace)) {
438
- throw new Error(`Namespace "${s.namespace}" has no registered schemas`);
439
- }
440
- if (namespaceResolverSchemaRegistry.get(s.namespace).has(false)) {
441
- const fields = {};
442
- namespaceResolverSchemaRegistry.get(s.namespace).get(false).forEach((value, key) => {
443
- if (value instanceof Map) {
444
- const capitalName = (0, utils_1.capitalizeProtoName)(key);
445
- fields[key] = {
446
- type: new graphql_1.GraphQLNonNull(new graphql_1.GraphQLObjectType({
447
- name: s.prefix + capitalName + 'Query',
448
- fields: Object.fromEntries(value),
449
- }))
450
- };
451
- }
452
- else {
453
- fields[key] = value;
454
- }
455
- });
456
- queryFields[s.namespace] = {
457
- type: new graphql_1.GraphQLNonNull(new graphql_1.GraphQLObjectType({
458
- name: s.prefix + 'Query',
459
- fields
460
- }))
461
- };
462
- }
463
- if (namespaceResolverSchemaRegistry.get(s.namespace).has(true)) {
464
- const fields = {};
465
- namespaceResolverSchemaRegistry.get(s.namespace).get(true).forEach((value, key) => {
466
- if (value instanceof Map) {
467
- const capitalName = (0, utils_1.capitalizeProtoName)(key);
468
- fields[key] = {
469
- type: new graphql_1.GraphQLNonNull(new graphql_1.GraphQLObjectType({
470
- name: s.prefix + capitalName + 'Mutation',
471
- fields: Object.fromEntries(value),
472
- }))
473
- };
474
- }
475
- else {
476
- fields[key] = value;
477
- }
478
- });
479
- mutationFields[s.namespace] = {
480
- type: new graphql_1.GraphQLNonNull(new graphql_1.GraphQLObjectType({
481
- name: s.prefix + 'Mutation',
482
- fields
483
- }))
484
- };
485
- }
486
- });
487
- const config = {};
488
- if (Object.keys(queryFields).length > 0) {
489
- config.query = new graphql_1.GraphQLObjectType({
490
- name: 'Query',
491
- fields: queryFields
492
- });
493
- }
494
- if (Object.keys(mutationFields).length > 0) {
495
- config.mutation = new graphql_1.GraphQLObjectType({
496
- name: 'Mutation',
497
- fields: mutationFields
498
- });
499
- }
500
- return new graphql_1.GraphQLSchema(config);
501
- };
502
- exports.generateSchema = generateSchema;
503
100
  const getWhitelistBlacklistConfig = (metaService, config, meta, entity) => {
504
101
  var _a, _b, _c, _d;
505
102
  const queryList = [];
@@ -557,7 +154,7 @@ const getWhitelistBlacklistConfig = (metaService, config, meta, entity) => {
557
154
  }
558
155
  }
559
156
  }
560
- if (Mutate.findIndex(val => mut.has(val)) > -1) {
157
+ if (exports.Mutate.findIndex(val => mut.has(val)) > -1) {
561
158
  mut.add('Mutate');
562
159
  }
563
160
  return {
@@ -566,161 +163,3 @@ const getWhitelistBlacklistConfig = (metaService, config, meta, entity) => {
566
163
  };
567
164
  };
568
165
  exports.getWhitelistBlacklistConfig = getWhitelistBlacklistConfig;
569
- const getAndGenerateSchema = (service, namespace, prefix, cfg, meta) => {
570
- const { mutations, queries } = (0, exports.getWhitelistBlacklistConfig)(service, cfg, meta, service.name);
571
- const schemas = (0, exports.getGQLSchemas)(service);
572
- Object.keys(schemas).forEach(key => {
573
- (0, exports.registerResolverSchema)(namespace, key, schemas[key], !queries.has(key) && mutations.has(key), undefined, cfg);
574
- });
575
- return (0, exports.generateSchema)([{ prefix, namespace }]);
576
- };
577
- exports.getAndGenerateSchema = getAndGenerateSchema;
578
- const getAndGenerateResolvers = (service, namespace, cfg, meta, subspace = undefined, serviceKey = undefined) => {
579
- const { mutations, queries } = (0, exports.getWhitelistBlacklistConfig)(service, cfg, meta, service.name);
580
- const func = (0, exports.getGQLResolverFunctions)(service, namespace, serviceKey || subspace || namespace, cfg);
581
- Object.keys(func).forEach(k => {
582
- (0, exports.registerResolverFunction)(namespace, k, func[k], !queries.has(k) && mutations.has(k), subspace, service);
583
- });
584
- return (0, exports.generateResolver)(namespace);
585
- };
586
- exports.getAndGenerateResolvers = getAndGenerateResolvers;
587
- const generateSubServiceSchemas = (subServices, config, namespace, prefix) => {
588
- subServices.forEach((meta) => {
589
- meta.fileDescriptor.service.forEach(service => {
590
- if (meta.options && meta.options.services && meta.options.services[service.name]) {
591
- const subName = meta.options.services[service.name].options['service_name'];
592
- const { mutations, queries } = (0, exports.getWhitelistBlacklistConfig)(service, config, meta, subName);
593
- const schemas = (0, exports.getGQLSchemas)(service);
594
- Object.keys(schemas).forEach(key => {
595
- (0, exports.registerResolverSchema)(config.root ? subName : namespace, key, schemas[key], !queries.has(key) && mutations.has(key), config.root ? undefined : subName, config);
596
- });
597
- }
598
- });
599
- });
600
- if (config.root) {
601
- return (0, exports.generateSchema)((0, array_prototype_flat_1.default)(subServices.map(meta => {
602
- return meta.fileDescriptor.service.map(service => {
603
- if (meta.options && meta.options.services && meta.options.services[service.name]) {
604
- const subName = meta.options.services[service.name].options['service_name'];
605
- return {
606
- prefix: prefix + subName.substr(0, 1).toUpperCase() + subName.substr(1).toLowerCase(),
607
- namespace: subName
608
- };
609
- }
610
- return null;
611
- }).filter(s => s !== null);
612
- })));
613
- }
614
- return (0, exports.generateSchema)([{ prefix, namespace }]);
615
- };
616
- exports.generateSubServiceSchemas = generateSubServiceSchemas;
617
- const generateSubServiceResolvers = (subServices, config, namespace) => {
618
- subServices.forEach((meta) => {
619
- meta.fileDescriptor.service.forEach(service => {
620
- if (meta.options && meta.options.services && meta.options.services[service.name]) {
621
- const subName = meta.options.services[service.name].options['service_name'];
622
- const { mutations, queries } = (0, exports.getWhitelistBlacklistConfig)(service, config, meta, subName);
623
- const func = (0, exports.getGQLResolverFunctions)(service, namespace, subName || namespace, config);
624
- Object.keys(func).forEach(k => {
625
- const regNamespace = config.root ? subName : namespace;
626
- const regSubspace = config.root ? undefined : subName;
627
- (0, exports.registerResolverFunction)(regNamespace, k, func[k], !queries.has(k) && mutations.has(k), regSubspace, service);
628
- });
629
- }
630
- });
631
- });
632
- if (config.root) {
633
- return (0, exports.generateResolver)(...(0, array_prototype_flat_1.default)(subServices.map(meta => {
634
- return meta.fileDescriptor.service.map(service => {
635
- if (meta.options && meta.options.services && meta.options.services[service.name]) {
636
- return meta.options.services[service.name].options['service_name'];
637
- }
638
- return null;
639
- }).filter(s => s !== null);
640
- })));
641
- }
642
- const finalResolver = (0, exports.generateResolver)(namespace);
643
- subServices.forEach((meta) => {
644
- meta.fileDescriptor.service.forEach(service => {
645
- if (meta.options && meta.options.messages) {
646
- for (const key of Object.keys(meta.options.messages)) {
647
- const message = meta.options.messages[key];
648
- if (message.fields) {
649
- const typing = (0, registry_1.getTyping)('.' + meta.fileDescriptor.package + '.' + key);
650
- if (typing) {
651
- const result = {};
652
- for (const fieldName of Object.keys(message.fields)) {
653
- const field = message.fields[fieldName];
654
- if ('resolver' in field) {
655
- const fieldJsonName = snakeToCamel(fieldName);
656
- const resolver = field['resolver'];
657
- // TODO This creates an N+1 problem!
658
- result[resolver.fieldName] = async (parent, _, ctx) => {
659
- if (!parent || !(fieldJsonName in parent) || parent[fieldJsonName] === undefined) {
660
- return undefined;
661
- }
662
- const client = ctx[resolver.targetService].client;
663
- const service = client[resolver.targetSubService];
664
- const idList = Array.isArray(parent[fieldJsonName]) ? parent[fieldJsonName] : [parent[fieldJsonName]];
665
- // TODO Support custom input messages
666
- const req = rc_grpc_clients_1.ReadRequest.fromPartial({
667
- filters: [{
668
- filter: idList.map(id => ({
669
- field: 'id',
670
- operation: resource_base_1.Filter_Operation.eq,
671
- value: id,
672
- type: resource_base_1.Filter_ValueType.STRING
673
- })),
674
- operator: resource_base_1.FilterOp_Operator.or
675
- }]
676
- });
677
- req.subject = (0, registry_1.getTyping)(types_1.authSubjectType).processor.fromPartial({});
678
- const authToken = ctx.request.req.headers['authorization'];
679
- if (authToken && authToken.startsWith('Bearer ')) {
680
- req.subject.token = authToken.split(' ')[1];
681
- }
682
- const methodFunc = service[camelCase(resolver.targetMethod)] || service[resolver.targetMethod];
683
- const result = await methodFunc(req);
684
- if (result && result.items && result.items.length) {
685
- if (Array.isArray(parent[fieldJsonName])) {
686
- return result.items.map((item) => item.payload);
687
- }
688
- else {
689
- return result.items[0].payload;
690
- }
691
- }
692
- return undefined;
693
- };
694
- }
695
- }
696
- finalResolver[typing.output.name] = result;
697
- }
698
- }
699
- }
700
- }
701
- });
702
- });
703
- return finalResolver;
704
- };
705
- exports.generateSubServiceResolvers = generateSubServiceResolvers;
706
- const snakeToCamel = (s) => {
707
- return s
708
- .split('_')
709
- .map((word, i) => {
710
- if (i === 0) {
711
- // if first symbol is "_" then skip it
712
- return word ? word[0] + word.substring(1).toLowerCase() : '';
713
- }
714
- else {
715
- return capitalize(word.toLowerCase());
716
- }
717
- })
718
- .join('');
719
- };
720
- const capitalize = (s) => {
721
- return s.substring(0, 1).toUpperCase() + s.substring(1);
722
- };
723
- function camelCase(s) {
724
- return s.substring(0, 1).toLowerCase() + s.substring(1);
725
- }
726
- exports.camelCase = camelCase;
@@ -1,3 +1,6 @@
1
1
  export * from './types';
2
2
  export * from './registry';
3
3
  export * from './graphql';
4
+ export * from './federation';
5
+ export * from './resolvers';
6
+ export * from './schema';
@@ -17,3 +17,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./types"), exports);
18
18
  __exportStar(require("./registry"), exports);
19
19
  __exportStar(require("./graphql"), exports);
20
+ __exportStar(require("./federation"), exports);
21
+ __exportStar(require("./resolvers"), exports);
22
+ __exportStar(require("./schema"), exports);
@@ -16,8 +16,8 @@ export declare const registerPackagesRecursive: (...protoMetadata: ProtoMetadata
16
16
  export declare const getRegisteredEnumTypings: () => string[];
17
17
  export declare const getNameSpaceTypeName: (typeName: string) => string | undefined;
18
18
  export declare const recursiveEnumCheck: (typeName: string, enumMap: Map<string, string>, prevFieldName: string, traversedFields: string[]) => Map<string, string>;
19
- export declare const registerTyping: (protoPackage: string, message: DescriptorProto, methodDef: MethodDescriptorProto[], opts?: Omit<Readonly<GraphQLObjectTypeConfig<any, any>>, "fields"> | undefined, inputOpts?: Omit<Readonly<GraphQLInputObjectTypeConfig>, "fields"> | undefined, messageOptions?: ProtoMetaMessageOptions | undefined) => void;
19
+ export declare const registerTyping: (protoPackage: string, message: DescriptorProto, methodDef: MethodDescriptorProto[], opts?: Omit<Readonly<GraphQLObjectTypeConfig<any, any>>, 'fields'>, inputOpts?: Omit<Readonly<GraphQLInputObjectTypeConfig>, 'fields'>, messageOptions?: ProtoMetaMessageOptions) => void;
20
20
  export declare const registerEnumTyping: <T = {
21
21
  [key: string]: any;
22
- }>(protoPackage: string, message: EnumDescriptorProto, opts?: Omit<Readonly<GraphQLEnumTypeConfig>, "values"> | undefined) => void;
22
+ }>(protoPackage: string, message: EnumDescriptorProto, opts?: Omit<Readonly<GraphQLEnumTypeConfig>, 'values'>) => void;
23
23
  export declare const getTyping: (type: string) => TypingData | undefined;
@@ -0,0 +1,9 @@
1
+ import { ProtoMetadata, ServiceClient, ServiceConfig, SubSpaceServiceConfig } from './types';
2
+ import { ServiceDescriptorProto } from 'ts-proto-descriptors';
3
+ import { GraphQLResolveInfo } from 'graphql';
4
+ export declare type ResolverFn<TResult, TParent, TContext, TArgs> = (parent: TParent, args: TArgs, context: TContext, info: GraphQLResolveInfo) => Promise<TResult> | TResult;
5
+ export declare type SubscribeResolverFn<TResult, TParent, TContext, TArgs> = (parent: TParent, args: TArgs, context: TContext, info: GraphQLResolveInfo) => AsyncGenerator<TResult>;
6
+ export declare const getGQLResolverFunctions: <T extends Record<string, any>, CTX extends ServiceClient<CTX, keyof CTX, T>, SRV = any, R = ResolverFn<any, any, ServiceClient<CTX, keyof CTX, T>, any>, B extends keyof T = any, NS extends keyof CTX = any>(service: ServiceDescriptorProto, key: NS, serviceKey: B, cfg: ServiceConfig) => { [key in keyof SRV]: R; };
7
+ export declare const registerResolverFunction: <T extends Record<string, any>, CTX extends ServiceClient<CTX, keyof CTX, T>>(namespace: string, name: string, func: ResolverFn<any, any, ServiceClient<CTX, keyof CTX, T>, any>, mutation?: boolean, subspace?: string | undefined, service?: ServiceDescriptorProto) => void;
8
+ export declare const generateResolver: (...namespaces: string[]) => any;
9
+ export declare const generateSubServiceResolvers: <T, M extends Record<string, any>, CTX extends ServiceClient<CTX, keyof CTX, M>>(subServices: ProtoMetadata[], config: SubSpaceServiceConfig, namespace: string) => T;