app.module.ts 3.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. import { MiddlewareConsumer, Module, NestModule, OnApplicationShutdown } from '@nestjs/common';
  2. import cookieSession from 'cookie-session';
  3. import { ApiModule } from './api/api.module';
  4. import { Middleware, MiddlewareHandler } from './common';
  5. import { ConfigModule } from './config/config.module';
  6. import { ConfigService } from './config/config.service';
  7. import { Logger } from './config/logger/vendure-logger';
  8. import { ConnectionModule } from './connection/connection.module';
  9. import { HealthCheckModule } from './health-check/health-check.module';
  10. import { I18nModule } from './i18n/i18n.module';
  11. import { I18nService } from './i18n/i18n.service';
  12. import { PluginModule } from './plugin/plugin.module';
  13. import { ProcessContextModule } from './process-context/process-context.module';
  14. import { ServiceModule } from './service/service.module';
  15. @Module({
  16. imports: [
  17. ProcessContextModule,
  18. ConfigModule,
  19. I18nModule,
  20. ApiModule,
  21. PluginModule.forRoot(),
  22. HealthCheckModule,
  23. ServiceModule,
  24. ConnectionModule,
  25. ],
  26. })
  27. export class AppModule implements NestModule, OnApplicationShutdown {
  28. constructor(
  29. private configService: ConfigService,
  30. private i18nService: I18nService,
  31. ) {}
  32. configure(consumer: MiddlewareConsumer) {
  33. const { adminApiPath, shopApiPath, middleware } = this.configService.apiOptions;
  34. const { cookieOptions } = this.configService.authOptions;
  35. const i18nextHandler = this.i18nService.handle();
  36. const defaultMiddleware: Middleware[] = [
  37. { handler: i18nextHandler, route: adminApiPath },
  38. { handler: i18nextHandler, route: shopApiPath },
  39. ];
  40. const allMiddleware = defaultMiddleware.concat(middleware);
  41. // If the Admin API and Shop API should have specific cookies names, we need to create separate cookie sessions
  42. if (typeof cookieOptions?.name === 'object') {
  43. const shopApiCookieName = cookieOptions.name.shop;
  44. const adminApiCookieName = cookieOptions.name.admin;
  45. allMiddleware.push({
  46. handler: cookieSession({ ...cookieOptions, name: adminApiCookieName }),
  47. route: adminApiPath,
  48. });
  49. allMiddleware.push({
  50. handler: cookieSession({ ...cookieOptions, name: shopApiCookieName }),
  51. route: shopApiPath,
  52. });
  53. }
  54. const consumableMiddlewares = allMiddleware.filter(mid => !mid.beforeListen);
  55. const middlewareByRoute = this.groupMiddlewareByRoute(consumableMiddlewares);
  56. for (const [route, handlers] of Object.entries(middlewareByRoute)) {
  57. consumer.apply(...handlers).forRoutes(route);
  58. }
  59. }
  60. async onApplicationShutdown(signal?: string) {
  61. if (signal) {
  62. Logger.info('Received shutdown signal:' + signal);
  63. }
  64. }
  65. /**
  66. * Groups middleware handler together in an object with the route as the key.
  67. */
  68. private groupMiddlewareByRoute(middlewareArray: Middleware[]): { [route: string]: MiddlewareHandler[] } {
  69. const result = {} as { [route: string]: MiddlewareHandler[] };
  70. for (const middleware of middlewareArray) {
  71. const route = middleware.route || this.configService.apiOptions.adminApiPath;
  72. if (!result[route]) {
  73. result[route] = [];
  74. }
  75. result[route].push(middleware.handler);
  76. }
  77. return result;
  78. }
  79. }