app.module.ts 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. import {
  2. MiddlewareConsumer,
  3. Module,
  4. NestModule,
  5. OnApplicationBootstrap,
  6. OnApplicationShutdown,
  7. } from '@nestjs/common';
  8. import { ModuleRef } from '@nestjs/core';
  9. import { RequestHandler } from 'express';
  10. import { ApiModule } from './api/api.module';
  11. import { ConfigurableOperationDef } from './common/configurable-operation';
  12. import { Injector } from './common/injector';
  13. import { InjectableStrategy } from './common/types/injectable-strategy';
  14. import { ConfigModule } from './config/config.module';
  15. import { ConfigService } from './config/config.service';
  16. import { Logger } from './config/logger/vendure-logger';
  17. import { HealthCheckModule } from './health-check/health-check.module';
  18. import { I18nModule } from './i18n/i18n.module';
  19. import { I18nService } from './i18n/i18n.service';
  20. import { PluginModule } from './plugin/plugin.module';
  21. import { ProcessContextModule } from './process-context/process-context.module';
  22. @Module({
  23. imports: [
  24. ConfigModule,
  25. I18nModule,
  26. ApiModule,
  27. PluginModule.forRoot(),
  28. ProcessContextModule.forRoot(),
  29. HealthCheckModule,
  30. ],
  31. })
  32. export class AppModule implements NestModule, OnApplicationBootstrap, OnApplicationShutdown {
  33. constructor(
  34. private configService: ConfigService,
  35. private i18nService: I18nService,
  36. private moduleRef: ModuleRef,
  37. ) {}
  38. async onApplicationBootstrap() {
  39. await this.initInjectableStrategies();
  40. await this.initConfigurableOperations();
  41. }
  42. configure(consumer: MiddlewareConsumer) {
  43. const { adminApiPath, shopApiPath, middleware } = this.configService.apiOptions;
  44. const i18nextHandler = this.i18nService.handle();
  45. const defaultMiddleware: Array<{ handler: RequestHandler; route?: string }> = [
  46. { handler: i18nextHandler, route: adminApiPath },
  47. { handler: i18nextHandler, route: shopApiPath },
  48. ];
  49. const allMiddleware = defaultMiddleware.concat(middleware);
  50. const middlewareByRoute = this.groupMiddlewareByRoute(allMiddleware);
  51. for (const [route, handlers] of Object.entries(middlewareByRoute)) {
  52. consumer.apply(...handlers).forRoutes(route);
  53. }
  54. }
  55. async onApplicationShutdown(signal?: string) {
  56. await this.destroyInjectableStrategies();
  57. await this.destroyConfigurableOperations();
  58. if (signal) {
  59. Logger.info('Received shutdown signal:' + signal);
  60. }
  61. }
  62. /**
  63. * Groups middleware handlers together in an object with the route as the key.
  64. */
  65. private groupMiddlewareByRoute(
  66. middlewareArray: Array<{ handler: RequestHandler; route?: string }>,
  67. ): { [route: string]: RequestHandler[] } {
  68. const result = {} as { [route: string]: RequestHandler[] };
  69. for (const middleware of middlewareArray) {
  70. const route = middleware.route || this.configService.apiOptions.adminApiPath;
  71. if (!result[route]) {
  72. result[route] = [];
  73. }
  74. result[route].push(middleware.handler);
  75. }
  76. return result;
  77. }
  78. private async initInjectableStrategies() {
  79. const injector = new Injector(this.moduleRef);
  80. for (const strategy of this.getInjectableStrategies()) {
  81. if (typeof strategy.init === 'function') {
  82. await strategy.init(injector);
  83. }
  84. }
  85. }
  86. private async destroyInjectableStrategies() {
  87. for (const strategy of this.getInjectableStrategies()) {
  88. if (typeof strategy.destroy === 'function') {
  89. await strategy.destroy();
  90. }
  91. }
  92. }
  93. private async initConfigurableOperations() {
  94. const injector = new Injector(this.moduleRef);
  95. for (const operation of this.getConfigurableOperations()) {
  96. await operation.init(injector);
  97. }
  98. }
  99. private async destroyConfigurableOperations() {
  100. for (const operation of this.getConfigurableOperations()) {
  101. await operation.destroy();
  102. }
  103. }
  104. private getInjectableStrategies(): InjectableStrategy[] {
  105. const {
  106. assetNamingStrategy,
  107. assetPreviewStrategy,
  108. assetStorageStrategy,
  109. } = this.configService.assetOptions;
  110. const { adminAuthenticationStrategy, shopAuthenticationStrategy } = this.configService.authOptions;
  111. const { taxCalculationStrategy, taxZoneStrategy } = this.configService.taxOptions;
  112. const { jobQueueStrategy } = this.configService.jobQueueOptions;
  113. const {
  114. mergeStrategy,
  115. checkoutMergeStrategy,
  116. priceCalculationStrategy,
  117. process,
  118. orderCodeStrategy,
  119. } = this.configService.orderOptions;
  120. const { entityIdStrategy } = this.configService;
  121. return [
  122. ...adminAuthenticationStrategy,
  123. ...shopAuthenticationStrategy,
  124. assetNamingStrategy,
  125. assetPreviewStrategy,
  126. assetStorageStrategy,
  127. taxCalculationStrategy,
  128. taxZoneStrategy,
  129. jobQueueStrategy,
  130. mergeStrategy,
  131. checkoutMergeStrategy,
  132. orderCodeStrategy,
  133. entityIdStrategy,
  134. priceCalculationStrategy,
  135. ...process,
  136. ];
  137. }
  138. private getConfigurableOperations(): Array<ConfigurableOperationDef<any>> {
  139. const { paymentMethodHandlers } = this.configService.paymentOptions;
  140. const { collectionFilters } = this.configService.catalogOptions;
  141. const { promotionActions, promotionConditions } = this.configService.promotionOptions;
  142. const { shippingCalculators, shippingEligibilityCheckers } = this.configService.shippingOptions;
  143. return [
  144. ...paymentMethodHandlers,
  145. ...collectionFilters,
  146. ...(promotionActions || []),
  147. ...(promotionConditions || []),
  148. ...(shippingCalculators || []),
  149. ...(shippingEligibilityCheckers || []),
  150. ];
  151. }
  152. }