@rsdk/grpc.server 4.0.0-next.1 → 4.0.0-next.10

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 (48) hide show
  1. package/CHANGELOG.md +56 -0
  2. package/dist/controllers/health.controller.js +4 -4
  3. package/dist/controllers/health.controller.js.map +1 -1
  4. package/dist/controllers/index.d.ts +2 -0
  5. package/dist/controllers/index.js +2 -0
  6. package/dist/controllers/index.js.map +1 -1
  7. package/dist/controllers/metrics.controller.js +2 -1
  8. package/dist/controllers/metrics.controller.js.map +1 -1
  9. package/dist/controllers/reflection/v1.base.controller.d.ts +32 -0
  10. package/dist/controllers/reflection/v1.base.controller.js +177 -0
  11. package/dist/controllers/reflection/v1.base.controller.js.map +1 -0
  12. package/dist/controllers/reflection/v1.controller.d.ts +10 -0
  13. package/dist/controllers/reflection/v1.controller.js +25 -0
  14. package/dist/controllers/reflection/v1.controller.js.map +1 -0
  15. package/dist/controllers/reflection/v1alpha.controller.d.ts +10 -0
  16. package/dist/controllers/reflection/v1alpha.controller.js +25 -0
  17. package/dist/controllers/reflection/v1alpha.controller.js.map +1 -0
  18. package/dist/grpc-logger.interceptor.d.ts +10 -0
  19. package/dist/grpc-logger.interceptor.js +73 -0
  20. package/dist/grpc-logger.interceptor.js.map +1 -0
  21. package/dist/grpc.config.d.ts +2 -0
  22. package/dist/grpc.config.js +18 -1
  23. package/dist/grpc.config.js.map +1 -1
  24. package/dist/grpc.transport.d.ts +13 -1
  25. package/dist/grpc.transport.js +55 -11
  26. package/dist/grpc.transport.js.map +1 -1
  27. package/dist/grpc.utils.d.ts +9 -0
  28. package/dist/grpc.utils.js +18 -0
  29. package/dist/grpc.utils.js.map +1 -0
  30. package/dist/reflection.module.d.ts +5 -0
  31. package/dist/reflection.module.js +33 -0
  32. package/dist/reflection.module.js.map +1 -0
  33. package/dist/reflection.service.d.ts +43 -0
  34. package/dist/reflection.service.js +151 -0
  35. package/dist/reflection.service.js.map +1 -0
  36. package/jest.config.js +11 -0
  37. package/package.json +17 -12
  38. package/src/controllers/index.ts +2 -0
  39. package/src/controllers/reflection/v1.base.controller.ts +173 -0
  40. package/src/controllers/reflection/v1.controller.ts +25 -0
  41. package/src/controllers/reflection/v1alpha.controller.ts +25 -0
  42. package/src/grpc-logger.interceptor.ts +72 -0
  43. package/src/grpc.config.ts +13 -0
  44. package/src/grpc.transport.ts +64 -15
  45. package/src/grpc.utils.ts +20 -0
  46. package/src/reflection.module.ts +26 -0
  47. package/src/reflection.service.spec.ts +86 -0
  48. package/src/reflection.service.ts +210 -0
@@ -4,16 +4,28 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.GrpcTransport = void 0;
7
+ const core_1 = require("@nestjs/core");
7
8
  const grpc_health_v1_1 = __importDefault(require("@rsdk/builtin-contract/dist/grpc.health.v1"));
8
9
  const grpc_metrics_v1_1 = __importDefault(require("@rsdk/builtin-contract/dist/grpc.metrics.v1"));
9
- const core_1 = require("@rsdk/core");
10
+ const grpc_reflection_v1_1 = __importDefault(require("@rsdk/builtin-contract/dist/grpc.reflection.v1"));
11
+ const grpc_reflection_v1alpha_1 = __importDefault(require("@rsdk/builtin-contract/dist/grpc.reflection.v1alpha"));
12
+ const core_2 = require("@rsdk/core");
10
13
  const grpc_loader_1 = require("@rsdk/grpc.loader");
11
14
  const logging_1 = require("@rsdk/logging");
12
15
  const controllers_1 = require("./controllers");
13
16
  const grpc_config_1 = require("./grpc.config");
17
+ const grpc_utils_1 = require("./grpc.utils");
14
18
  const grpc_errors_formatter_1 = require("./grpc-errors.formatter");
15
19
  const grpc_errors_sender_1 = require("./grpc-errors.sender");
20
+ const grpc_logger_interceptor_1 = require("./grpc-logger.interceptor");
21
+ const reflection_module_1 = require("./reflection.module");
16
22
  class GrpcTransport {
23
+ systemPackages = [
24
+ grpc_health_v1_1.default,
25
+ grpc_metrics_v1_1.default,
26
+ grpc_reflection_v1_1.default,
27
+ grpc_reflection_v1alpha_1.default,
28
+ ];
17
29
  logger = logging_1.LoggerFactory.create(GrpcTransport);
18
30
  packages;
19
31
  address;
@@ -41,6 +53,20 @@ class GrpcTransport {
41
53
  getHealthController() {
42
54
  return controllers_1.HealthController;
43
55
  }
56
+ modules() {
57
+ return [
58
+ reflection_module_1.ReflectionModule.forRoot(this.packages),
59
+ {
60
+ module: GrpcTransport,
61
+ providers: [
62
+ {
63
+ provide: core_1.APP_INTERCEPTOR,
64
+ useClass: grpc_logger_interceptor_1.GrpcLoggerInterceptor,
65
+ },
66
+ ],
67
+ },
68
+ ];
69
+ }
44
70
  /**
45
71
  * Unfortunally we can't access GRPCConfig in constructor because
46
72
  * PlatformConfigModule is not initilalized yet
@@ -53,21 +79,17 @@ class GrpcTransport {
53
79
  this.isInitialized = true;
54
80
  }
55
81
  createMicroserviceOptions() {
56
- this.checkIsInitialized();
57
- const packages = [...this.packages];
58
- if (!packages.some((x) => x.name === grpc_health_v1_1.default.name)) {
59
- packages.push(grpc_health_v1_1.default);
60
- }
61
- if (!packages.some((x) => x.name === grpc_metrics_v1_1.default.name)) {
62
- packages.push(grpc_metrics_v1_1.default);
63
- }
82
+ const packages = this.getUniquePackages();
64
83
  for (const pkg of packages) {
65
84
  for (const service of Object.keys(pkg.definitions['grpc-js'])) {
66
85
  this.logger.info(`Expose grpc-service: ${pkg.name}.${service}`);
67
86
  }
68
87
  }
88
+ this.checkIsInitialized();
89
+ this.assertIsDefined(this.address);
90
+ this.assertIsDefined(this.maxRecv);
91
+ this.assertIsDefined(this.maxSend);
69
92
  return (0, grpc_loader_1.createGrpcOptions)(packages, {
70
- // FIXME добавить проверку
71
93
  address: this.address,
72
94
  maxRecv: this.maxRecv,
73
95
  maxSend: this.maxSend,
@@ -79,8 +101,30 @@ class GrpcTransport {
79
101
  }
80
102
  checkIsInitialized() {
81
103
  if (!this.isInitialized) {
82
- throw new core_1.SequenceException('You should call init() method first!');
104
+ throw new core_2.SequenceException('You should call init() method first!');
105
+ }
106
+ }
107
+ /**
108
+ * Checks the value must be defined and not null
109
+ * @param value any value
110
+ */
111
+ assertIsDefined(value) {
112
+ if (value === undefined || value === null) {
113
+ throw new Error(`${value} is not defined`);
114
+ }
115
+ }
116
+ /**
117
+ * Merge user packages with system packages
118
+ * @returns array of unique packages
119
+ */
120
+ getUniquePackages() {
121
+ const packages = [...this.packages];
122
+ for (const pkg of this.systemPackages) {
123
+ if ((0, grpc_utils_1.isPackageNotIncluded)(packages, pkg)) {
124
+ packages.push(pkg);
125
+ }
83
126
  }
127
+ return packages;
84
128
  }
85
129
  }
86
130
  exports.GrpcTransport = GrpcTransport;
@@ -1 +1 @@
1
- {"version":3,"file":"grpc.transport.js","sourceRoot":"","sources":["../src/grpc.transport.ts"],"names":[],"mappings":";;;;;;AAEA,gGAA2E;AAC3E,kGAA6E;AAS7E,qCAA+C;AAE/C,mDAAsD;AACtD,2CAA8C;AAE9C,+CAAoE;AACpE,+CAA2C;AAC3C,mEAA8D;AAC9D,6DAAwD;AAExD,MAAa,aAAa;IACP,MAAM,GAAG,uBAAa,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;IAC7C,QAAQ,CAAY;IAE7B,OAAO,CAAU;IACjB,OAAO,CAAU;IACjB,OAAO,CAAU;IAEjB,aAAa,GAAG,KAAK,CAAC;IAE9B,YAAY,GAAG,QAAmB;QAChC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC3B,CAAC;IAED,WAAW;QACT,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,kBAAkB;QAChB,OAAO,IAAI,2CAAmB,EAAE,CAAC;IACnC,CAAC;IAED,eAAe;QACb,OAAO,IAAI,qCAAgB,EAAE,CAAC;IAChC,CAAC;IAED,oBAAoB;QAClB,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,oBAAoB;QAClB,OAAO,+BAAiB,CAAC;IAC3B,CAAC;IAED,mBAAmB;QACjB,OAAO,8BAAgB,CAAC;IAC1B,CAAC;IAED;;;OAGG;IACH,IAAI,CAAC,aAA4B;QAC/B,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,aAAa,CAAC,OAAO,CAAC,wBAAU,CAAC,CAAC;QAExE,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;IAC5B,CAAC;IAED,yBAAyB;QACvB,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAE1B,MAAM,QAAQ,GAAG,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC;QAEpC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,wBAAiB,CAAC,IAAI,CAAC,EAAE;YAC5D,QAAQ,CAAC,IAAI,CAAC,wBAAiB,CAAC,CAAC;SAClC;QAED,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,yBAAkB,CAAC,IAAI,CAAC,EAAE;YAC7D,QAAQ,CAAC,IAAI,CAAC,yBAAkB,CAAC,CAAC;SACnC;QAED,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE;YAC1B,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,EAAE;gBAC7D,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,wBAAwB,GAAG,CAAC,IAAI,IAAI,OAAO,EAAE,CAAC,CAAC;aACjE;SACF;QAED,OAAO,IAAA,+BAAiB,EAAC,QAAQ,EAAE;YACjC,0BAA0B;YAC1B,OAAO,EAAE,IAAI,CAAC,OAAQ;YACtB,OAAO,EAAE,IAAI,CAAC,OAAQ;YACtB,OAAO,EAAE,IAAI,CAAC,OAAQ;SACvB,CAAC,CAAC;IACL,CAAC;IAED,OAAO;QACL,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAE1B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,oCAAoC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;IACvE,CAAC;IAEO,kBAAkB;QACxB,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE;YACvB,MAAM,IAAI,wBAAiB,CAAC,sCAAsC,CAAC,CAAC;SACrE;IACH,CAAC;CACF;AAzFD,sCAyFC"}
1
+ {"version":3,"file":"grpc.transport.js","sourceRoot":"","sources":["../src/grpc.transport.ts"],"names":[],"mappings":";;;;;;AACA,uCAA+C;AAE/C,gGAA2E;AAC3E,kGAA6E;AAC7E,wGAAqF;AACrF,kHAA+F;AAU/F,qCAA+C;AAE/C,mDAAsD;AACtD,2CAA8C;AAE9C,+CAAoE;AACpE,+CAA2C;AAC3C,6CAAoD;AACpD,mEAA8D;AAC9D,6DAAwD;AACxD,uEAAkE;AAClE,2DAAuD;AAEvD,MAAa,aAAa;IACP,cAAc,GAAc;QAC3C,wBAAiB;QACjB,yBAAkB;QAClB,4BAAuB;QACvB,iCAA4B;KAC7B,CAAC;IAEe,MAAM,GAAG,uBAAa,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;IAC7C,QAAQ,CAAY;IAE7B,OAAO,CAAU;IACjB,OAAO,CAAU;IACjB,OAAO,CAAU;IAEjB,aAAa,GAAG,KAAK,CAAC;IAE9B,YAAY,GAAG,QAAmB;QAChC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC3B,CAAC;IAED,WAAW;QACT,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,kBAAkB;QAChB,OAAO,IAAI,2CAAmB,EAAE,CAAC;IACnC,CAAC;IAED,eAAe;QACb,OAAO,IAAI,qCAAgB,EAAE,CAAC;IAChC,CAAC;IAED,oBAAoB;QAClB,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,oBAAoB;QAClB,OAAO,+BAAiB,CAAC;IAC3B,CAAC;IAED,mBAAmB;QACjB,OAAO,8BAAgB,CAAC;IAC1B,CAAC;IAED,OAAO;QACL,OAAO;YACL,oCAAgB,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC;YACvC;gBACE,MAAM,EAAE,aAAa;gBACrB,SAAS,EAAE;oBACT;wBACE,OAAO,EAAE,sBAAe;wBACxB,QAAQ,EAAE,+CAAqB;qBAChC;iBACF;aACF;SACF,CAAC;IACJ,CAAC;IAED;;;OAGG;IACH,IAAI,CAAC,aAA4B;QAC/B,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,aAAa,CAAC,OAAO,CAAC,wBAAU,CAAC,CAAC;QAExE,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;IAC5B,CAAC;IAED,yBAAyB;QACvB,MAAM,QAAQ,GAAG,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAE1C,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE;YAC1B,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,EAAE;gBAC7D,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,wBAAwB,GAAG,CAAC,IAAI,IAAI,OAAO,EAAE,CAAC,CAAC;aACjE;SACF;QAED,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC1B,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACnC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACnC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAEnC,OAAO,IAAA,+BAAiB,EAAC,QAAQ,EAAE;YACjC,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,OAAO,EAAE,IAAI,CAAC,OAAO;SACtB,CAAC,CAAC;IACL,CAAC;IAED,OAAO;QACL,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAE1B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,oCAAoC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;IACvE,CAAC;IAEO,kBAAkB;QACxB,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE;YACvB,MAAM,IAAI,wBAAiB,CAAC,sCAAsC,CAAC,CAAC;SACrE;IACH,CAAC;IAED;;;OAGG;IACK,eAAe,CAAI,KAAQ;QACjC,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,EAAE;YACzC,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,iBAAiB,CAAC,CAAC;SAC5C;IACH,CAAC;IAED;;;OAGG;IACK,iBAAiB;QACvB,MAAM,QAAQ,GAAG,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC;QAEpC,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,cAAc,EAAE;YACrC,IAAI,IAAA,iCAAoB,EAAC,QAAQ,EAAE,GAAG,CAAC,EAAE;gBACvC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;aACpB;SACF;QAED,OAAO,QAAQ,CAAC;IAClB,CAAC;CACF;AAnID,sCAmIC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Checks whether a pkg is in the array
3
+ * @param packages array of packages
4
+ * @param pkg package you are looking for
5
+ * @returns true if pkg exists in packages
6
+ */
7
+ export declare const isPackageNotIncluded: <T extends {
8
+ name: string;
9
+ }>(packages: T[], pkg: T) => boolean;
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isPackageNotIncluded = void 0;
4
+ /**
5
+ * Match packages name
6
+ * @param pkg
7
+ * @returns true if names is equal
8
+ */
9
+ const isEqualPackageName = (pkg) => (x) => x.name === pkg.name;
10
+ /**
11
+ * Checks whether a pkg is in the array
12
+ * @param packages array of packages
13
+ * @param pkg package you are looking for
14
+ * @returns true if pkg exists in packages
15
+ */
16
+ const isPackageNotIncluded = (packages, pkg) => !packages.some(isEqualPackageName(pkg));
17
+ exports.isPackageNotIncluded = isPackageNotIncluded;
18
+ //# sourceMappingURL=grpc.utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grpc.utils.js","sourceRoot":"","sources":["../src/grpc.utils.ts"],"names":[],"mappings":";;;AAAA;;;;GAIG;AACH,MAAM,kBAAkB,GACtB,CAA6B,GAAM,EAAE,EAAE,CACvC,CAAC,CAAI,EAAW,EAAE,CAChB,CAAC,CAAC,IAAI,KAAK,GAAG,CAAC,IAAI,CAAC;AAExB;;;;;GAKG;AACI,MAAM,oBAAoB,GAAG,CAClC,QAAa,EACb,GAAM,EACG,EAAE,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,CAAC;AAHzC,QAAA,oBAAoB,wBAGqB"}
@@ -0,0 +1,5 @@
1
+ import type { DynamicModule } from '@nestjs/common';
2
+ import type { Package } from '@rsdk/grpc.loader';
3
+ export declare class ReflectionModule {
4
+ static forRoot(packages: Package[]): DynamicModule;
5
+ }
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var ReflectionModule_1;
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.ReflectionModule = void 0;
11
+ const common_1 = require("@nestjs/common");
12
+ const controllers_1 = require("./controllers");
13
+ const reflection_service_1 = require("./reflection.service");
14
+ let ReflectionModule = ReflectionModule_1 = class ReflectionModule {
15
+ static forRoot(packages) {
16
+ return {
17
+ module: ReflectionModule_1,
18
+ controllers: [controllers_1.ReflectionV1alphaController, controllers_1.ReflectionV1Controller],
19
+ providers: [
20
+ reflection_service_1.ReflectionService,
21
+ {
22
+ provide: 'GRPC_PACKAGES',
23
+ useValue: packages,
24
+ },
25
+ ],
26
+ };
27
+ }
28
+ };
29
+ exports.ReflectionModule = ReflectionModule;
30
+ exports.ReflectionModule = ReflectionModule = ReflectionModule_1 = __decorate([
31
+ (0, common_1.Module)({})
32
+ ], ReflectionModule);
33
+ //# sourceMappingURL=reflection.module.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reflection.module.js","sourceRoot":"","sources":["../src/reflection.module.ts"],"names":[],"mappings":";;;;;;;;;;AACA,2CAAwC;AAGxC,+CAGuB;AACvB,6DAAyD;AAGlD,IAAM,gBAAgB,wBAAtB,MAAM,gBAAgB;IAC3B,MAAM,CAAC,OAAO,CAAC,QAAmB;QAChC,OAAO;YACL,MAAM,EAAE,kBAAgB;YACxB,WAAW,EAAE,CAAC,yCAA2B,EAAE,oCAAsB,CAAC;YAClE,SAAS,EAAE;gBACT,sCAAiB;gBACjB;oBACE,OAAO,EAAE,eAAe;oBACxB,QAAQ,EAAE,QAAQ;iBACnB;aACF;SACF,CAAC;IACJ,CAAC;CACF,CAAA;AAdY,4CAAgB;2BAAhB,gBAAgB;IAD5B,IAAA,eAAM,EAAC,EAAE,CAAC;GACE,gBAAgB,CAc5B"}
@@ -0,0 +1,43 @@
1
+ /// <reference types="node" />
2
+ import type { OnModuleInit } from '@nestjs/common';
3
+ import type { Package } from '@rsdk/grpc.loader';
4
+ export declare class ReflectionService implements OnModuleInit {
5
+ private readonly packages;
6
+ private readonly services;
7
+ private readonly files;
8
+ private readonly logger;
9
+ constructor(packages: Package[]);
10
+ onModuleInit(): void;
11
+ /**
12
+ * List the full names of registered gRPC services
13
+ *
14
+ * note: the spec is unclear as to what the 'listServices' param can be; most
15
+ * clients seem to only pass '*' but unsure if this should behave like a
16
+ * filter. Until we know how this should behave with different inputs this
17
+ * just always returns *all* services.
18
+ *
19
+ * @returns full-qualified service names (eg. 'sample.SampleService')
20
+ */
21
+ listServices(): string[];
22
+ /**
23
+ * Find the proto file(s) that declares the given fully-qualified symbol name
24
+ *
25
+ * @param symbol fully-qualified name of the symbol to lookup
26
+ * (e.g. package.service[.method] or package.type)
27
+ *
28
+ * @returns descriptors of the file which contains this symbol and its imports
29
+ */
30
+ fileBySymbol(symbol: string): Buffer;
31
+ /**
32
+ * Find a proto file by the file name
33
+ * @returns descriptors of the file which contains this symbol and its imports
34
+ */
35
+ fileByName(filename: string): Buffer;
36
+ /**
37
+ * Find a proto file containing an extension to a message type
38
+ * @returns descriptors of the file which contains this symbol and its imports
39
+ */
40
+ fileContainingExtension(containingType: string, extensionNumber: number): Buffer;
41
+ allExtensionNumbersOfType(symbol: string): number[];
42
+ private findSymbol;
43
+ }
@@ -0,0 +1,151 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
14
+ var __importDefault = (this && this.__importDefault) || function (mod) {
15
+ return (mod && mod.__esModule) ? mod : { "default": mod };
16
+ };
17
+ var ReflectionService_1;
18
+ Object.defineProperty(exports, "__esModule", { value: true });
19
+ exports.ReflectionService = void 0;
20
+ const protobuf_1 = require("@bufbuild/protobuf");
21
+ const common_1 = require("@nestjs/common");
22
+ const grpc_health_v1_1 = __importDefault(require("@rsdk/builtin-contract/dist/grpc.health.v1"));
23
+ const grpc_metrics_v1_1 = __importDefault(require("@rsdk/builtin-contract/dist/grpc.metrics.v1"));
24
+ const grpc_reflection_v1_1 = __importDefault(require("@rsdk/builtin-contract/dist/grpc.reflection.v1"));
25
+ const grpc_reflection_v1alpha_1 = __importDefault(require("@rsdk/builtin-contract/dist/grpc.reflection.v1alpha"));
26
+ const logging_1 = require("@rsdk/logging");
27
+ let ReflectionService = ReflectionService_1 = class ReflectionService {
28
+ packages;
29
+ services = new Set();
30
+ files = [];
31
+ logger = logging_1.LoggerFactory.create(ReflectionService_1);
32
+ constructor(packages) {
33
+ this.packages = packages;
34
+ }
35
+ onModuleInit() {
36
+ const allPackages = [
37
+ ...this.packages,
38
+ grpc_health_v1_1.default,
39
+ grpc_metrics_v1_1.default,
40
+ grpc_reflection_v1_1.default,
41
+ grpc_reflection_v1alpha_1.default,
42
+ ];
43
+ const allPackagesNames = new Set(allPackages.map((pkg) => pkg.name));
44
+ for (const pkg of allPackages) {
45
+ if (pkg.descriptor) {
46
+ for (const service of Object.keys(pkg.definitions['grpc-js'])) {
47
+ this.logger.info(`GRPC descriptor loaded for service: ${pkg.name}.${service}`);
48
+ }
49
+ for (const file of protobuf_1.FileDescriptorSet.fromBinary(pkg.descriptor).file) {
50
+ this.files.push(file);
51
+ if (allPackagesNames.has(`${file.package}`)) {
52
+ for (const service of file.service) {
53
+ this.services.add(`${file.package}.${service.name}`);
54
+ }
55
+ }
56
+ }
57
+ }
58
+ }
59
+ }
60
+ /**
61
+ * List the full names of registered gRPC services
62
+ *
63
+ * note: the spec is unclear as to what the 'listServices' param can be; most
64
+ * clients seem to only pass '*' but unsure if this should behave like a
65
+ * filter. Until we know how this should behave with different inputs this
66
+ * just always returns *all* services.
67
+ *
68
+ * @returns full-qualified service names (eg. 'sample.SampleService')
69
+ */
70
+ listServices() {
71
+ return [...this.services];
72
+ }
73
+ /**
74
+ * Find the proto file(s) that declares the given fully-qualified symbol name
75
+ *
76
+ * @param symbol fully-qualified name of the symbol to lookup
77
+ * (e.g. package.service[.method] or package.type)
78
+ *
79
+ * @returns descriptors of the file which contains this symbol and its imports
80
+ */
81
+ fileBySymbol(symbol) {
82
+ const file = this.files.find((file) => this.findSymbol(symbol, file));
83
+ if (file) {
84
+ return Buffer.from(file.toBinary());
85
+ }
86
+ throw new Error(`symbol: ${symbol} not found`);
87
+ }
88
+ /**
89
+ * Find a proto file by the file name
90
+ * @returns descriptors of the file which contains this symbol and its imports
91
+ */
92
+ fileByName(filename) {
93
+ const file = this.files.find((file) => file.name === filename);
94
+ if (file) {
95
+ return Buffer.from(file.toBinary());
96
+ }
97
+ throw new Error(`file: ${filename} not found`);
98
+ }
99
+ /**
100
+ * Find a proto file containing an extension to a message type
101
+ * @returns descriptors of the file which contains this symbol and its imports
102
+ */
103
+ fileContainingExtension(containingType, extensionNumber) {
104
+ const extension = this.files.find((file) => {
105
+ const descriptor = this.findSymbol(containingType, file);
106
+ return (descriptor instanceof protobuf_1.DescriptorProto &&
107
+ descriptor.extension.some((extension) => extensionNumber === extension.number));
108
+ });
109
+ if (extension) {
110
+ return Buffer.from(extension.toBinary());
111
+ }
112
+ throw new Error(`containingType: ${containingType}, extensionNumber: ${extensionNumber} not found`);
113
+ }
114
+ allExtensionNumbersOfType(symbol) {
115
+ return [
116
+ ...new Set(this.files.flatMap((file) => file.extension.flatMap((_fqn, _file, ext) => ext
117
+ .filter((e) => e.extendee === symbol)
118
+ .flatMap((e) => Number(e.number))))),
119
+ ];
120
+ }
121
+ findSymbol(symbol, descriptor, prefix = '') {
122
+ if (descriptor instanceof protobuf_1.FileDescriptorProto) {
123
+ const packageName = descriptor.package;
124
+ const packagePrefix = packageName ? `${packageName}.` : '';
125
+ return (descriptor.messageType.find((type) => this.findSymbol(symbol, type, packagePrefix)) ??
126
+ descriptor.enumType.find((type) => this.findSymbol(symbol, type, packagePrefix)) ??
127
+ descriptor.service.find((type) => this.findSymbol(symbol, type, packagePrefix)));
128
+ }
129
+ const fullName = prefix + descriptor.name;
130
+ if (symbol === fullName) {
131
+ return descriptor;
132
+ }
133
+ if (descriptor instanceof protobuf_1.DescriptorProto) {
134
+ const messagePrefix = `${fullName}.`;
135
+ return (descriptor.nestedType.find((type) => this.findSymbol(symbol, type, messagePrefix)) ??
136
+ descriptor.enumType.find((type) => this.findSymbol(symbol, type, messagePrefix)));
137
+ }
138
+ if (descriptor instanceof protobuf_1.ServiceDescriptorProto) {
139
+ const servicePrefix = `${fullName}.`;
140
+ return descriptor.method.find((method) => this.findSymbol(symbol, method, servicePrefix));
141
+ }
142
+ return undefined;
143
+ }
144
+ };
145
+ exports.ReflectionService = ReflectionService;
146
+ exports.ReflectionService = ReflectionService = ReflectionService_1 = __decorate([
147
+ (0, common_1.Injectable)(),
148
+ __param(0, (0, common_1.Inject)('GRPC_PACKAGES')),
149
+ __metadata("design:paramtypes", [Array])
150
+ ], ReflectionService);
151
+ //# sourceMappingURL=reflection.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reflection.service.js","sourceRoot":"","sources":["../src/reflection.service.ts"],"names":[],"mappings":"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"}
package/jest.config.js ADDED
@@ -0,0 +1,11 @@
1
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
2
+ const { resolve } = require('node:path');
3
+
4
+ /** @type {import('ts-jest').JestConfigWithTsJest} */
5
+ module.exports = {
6
+ preset: 'ts-jest',
7
+ testEnvironment: 'node',
8
+
9
+ setupFiles: ['dotenv/config'],
10
+ rootDir: resolve(__dirname, 'src'),
11
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rsdk/grpc.server",
3
- "version": "4.0.0-next.1",
3
+ "version": "4.0.0-next.10",
4
4
  "description": "Grpc transport for platform, clients and common grpc stuff",
5
5
  "license": "Apache License 2.0",
6
6
  "publishConfig": {
@@ -15,17 +15,22 @@
15
15
  },
16
16
  "peerDependencies": {
17
17
  "@grpc/grpc-js": "^1.8.8",
18
- "@nestjs/common": "^10.1.3",
19
- "@nestjs/microservices": "^10.1.3",
20
- "@rsdk/builtin-contract": "^3.5.0",
21
- "@rsdk/common": "^3.5.0",
22
- "@rsdk/core": "^4.0.0-next.1",
23
- "@rsdk/grpc.common": "^4.0.0-next.1",
24
- "@rsdk/grpc.loader": "^3.5.0",
25
- "@rsdk/logging": "^4.0.0-next.1",
18
+ "@nestjs/common": "^10.0.0",
19
+ "@nestjs/core": "^10.0.0",
20
+ "@nestjs/microservices": "^10.0.0",
21
+ "@rsdk/builtin-contract": "^4.0.0-next.10",
22
+ "@rsdk/common": "^4.0.0-next.10",
23
+ "@rsdk/core": "^4.0.0-next.10",
24
+ "@rsdk/grpc.common": "^4.0.0-next.10",
25
+ "@rsdk/grpc.loader": "^4.0.0-next.10",
26
+ "@rsdk/logging": "^4.0.0-next.10",
26
27
  "nice-grpc": "^2.1.4",
27
- "nice-grpc-opentelemetry": "^0.1.3",
28
- "rxjs": "^7.0.0"
28
+ "reflect-metadata": "^0.1.13",
29
+ "rxjs": "^7.8.1"
29
30
  },
30
- "gitHead": "d21a800ef5dd191b5effec59846c3a44a7ca3d1e"
31
+ "dependencies": {
32
+ "@bufbuild/protobuf": "^1.4.2",
33
+ "nice-grpc-opentelemetry": "^0.1.2"
34
+ },
35
+ "gitHead": "c41d4da9aa0318d5e6417514c763618ce924f9b7"
31
36
  }
@@ -1,2 +1,4 @@
1
1
  export * from './health.controller';
2
2
  export * from './metrics.controller';
3
+ export * from './reflection/v1.controller';
4
+ export * from './reflection/v1alpha.controller';
@@ -0,0 +1,173 @@
1
+ import * as grpc from '@grpc/grpc-js';
2
+ import { Inject, NotImplementedException } from '@nestjs/common';
3
+ import type {
4
+ ServerReflectionGrpcController,
5
+ ServerReflectionRequest,
6
+ ServerReflectionResponse,
7
+ } from '@rsdk/builtin-contract/dist/grpc.reflection.v1';
8
+ import { InjectLogger } from '@rsdk/core';
9
+ import { ILogger } from '@rsdk/logging';
10
+ import type { Observable } from 'rxjs';
11
+ import { Subject } from 'rxjs';
12
+
13
+ import { GRPCConfig } from '../../grpc.config';
14
+ import { ReflectionService } from '../../reflection.service';
15
+
16
+ /**
17
+ * Base class for alpha and final 'v1' versions of the gRPC reflection API
18
+ *
19
+ * note: the final version of the v1 spec was identical to the alpha version, so
20
+ * this common class is used in order to share logic across multiple controllers
21
+ * (this class itself is *not* a controller). See child classes for actual APIs
22
+ *
23
+ * @see {@link https://github.com/grpc/grpc/blob/master/doc/server-reflection.md}
24
+ */
25
+ export class BaseV1GrpcReflectionController
26
+ implements ServerReflectionGrpcController
27
+ {
28
+ constructor(
29
+ private readonly config: GRPCConfig,
30
+ @InjectLogger(ReflectionService) private readonly logger: ILogger,
31
+ @Inject(ReflectionService) private readonly service: ReflectionService,
32
+ ) {}
33
+
34
+ /** Main method for providing information about the running gRPC server
35
+ *
36
+ * The spec defines this as a single streaming method so that the connection
37
+ * stays open to the same running instance of the server for all follow-up
38
+ * requests. This means that we can keep some kind of state about what we've
39
+ * already to that client or not if we need to.
40
+ */
41
+ serverReflectionInfo(
42
+ request$: Observable<ServerReflectionRequest>,
43
+ ): Observable<ServerReflectionResponse> {
44
+ const response$ = new Subject<ServerReflectionResponse>();
45
+
46
+ request$.subscribe({
47
+ next: this.config.reflection
48
+ ? this.resolveReflection(response$)
49
+ : this.reflectionIsDisabled(response$),
50
+ complete: (): void => response$.complete(),
51
+ });
52
+
53
+ return response$.asObservable();
54
+ }
55
+
56
+ private makeResponse(
57
+ request: ServerReflectionRequest,
58
+ ): ServerReflectionResponse {
59
+ if (request.messageRequest?.$case === 'listServices') {
60
+ return this.createServerReflectionResponse(request, {
61
+ $case: 'listServicesResponse',
62
+ listServicesResponse: {
63
+ service: this.service.listServices().map((name) => ({ name })),
64
+ },
65
+ });
66
+ }
67
+
68
+ if (request.messageRequest?.$case === 'fileContainingSymbol') {
69
+ return this.createServerReflectionResponse(request, {
70
+ $case: 'fileDescriptorResponse',
71
+ fileDescriptorResponse: {
72
+ fileDescriptorProto: [
73
+ this.service.fileBySymbol(
74
+ request.messageRequest.fileContainingSymbol,
75
+ ),
76
+ ],
77
+ },
78
+ });
79
+ }
80
+
81
+ if (request.messageRequest?.$case === 'fileByFilename') {
82
+ return this.createServerReflectionResponse(request, {
83
+ $case: 'fileDescriptorResponse',
84
+ fileDescriptorResponse: {
85
+ fileDescriptorProto: [
86
+ this.service.fileByName(request.messageRequest.fileByFilename),
87
+ ],
88
+ },
89
+ });
90
+ }
91
+
92
+ if (request.messageRequest?.$case === 'fileContainingExtension') {
93
+ return this.createServerReflectionResponse(request, {
94
+ $case: 'fileDescriptorResponse',
95
+ fileDescriptorResponse: {
96
+ fileDescriptorProto: [
97
+ this.service.fileContainingExtension(
98
+ request.messageRequest.fileContainingExtension.containingType,
99
+ request.messageRequest.fileContainingExtension.extensionNumber,
100
+ ),
101
+ ],
102
+ },
103
+ });
104
+ }
105
+
106
+ if (request.messageRequest?.$case === 'allExtensionNumbersOfType') {
107
+ return this.createServerReflectionResponse(request, {
108
+ $case: 'allExtensionNumbersResponse',
109
+ allExtensionNumbersResponse: {
110
+ baseTypeName: request.messageRequest.allExtensionNumbersOfType,
111
+ extensionNumber: this.service.allExtensionNumbersOfType(
112
+ request.messageRequest.allExtensionNumbersOfType,
113
+ ),
114
+ },
115
+ });
116
+ }
117
+
118
+ this.logger.error('NotImplementedException', { request });
119
+
120
+ throw new NotImplementedException(request.messageRequest);
121
+ }
122
+
123
+ private createServerReflectionResponse(
124
+ request: ServerReflectionRequest,
125
+ message: ServerReflectionResponse['messageResponse'],
126
+ ): ServerReflectionResponse {
127
+ return {
128
+ validHost: request.host,
129
+ originalRequest: request,
130
+ messageResponse: message,
131
+ };
132
+ }
133
+
134
+ private resolveReflection(
135
+ response$: Subject<ServerReflectionResponse>,
136
+ ): (message: ServerReflectionRequest) => void {
137
+ return (message: ServerReflectionRequest): void => {
138
+ try {
139
+ response$.next(this.makeResponse(message));
140
+ } catch (error) {
141
+ if (error instanceof Error) {
142
+ this.logger.error(error);
143
+ }
144
+
145
+ const response = this.createServerReflectionResponse(message, {
146
+ $case: 'errorResponse',
147
+ errorResponse: {
148
+ errorCode: grpc.status.UNKNOWN,
149
+ errorMessage: `Failed to process gRPC reflection request: ${error}`,
150
+ },
151
+ });
152
+
153
+ response$.next(response);
154
+ }
155
+ };
156
+ }
157
+
158
+ private reflectionIsDisabled(
159
+ response$: Subject<ServerReflectionResponse>,
160
+ ): (message: ServerReflectionRequest) => void {
161
+ return (message: ServerReflectionRequest): void => {
162
+ const response = this.createServerReflectionResponse(message, {
163
+ $case: 'errorResponse',
164
+ errorResponse: {
165
+ errorCode: grpc.status.UNAVAILABLE,
166
+ errorMessage: `Reflection is disabled by config`,
167
+ },
168
+ });
169
+
170
+ return response$.next(response);
171
+ };
172
+ }
173
+ }