service.module.ts 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. import { DynamicModule, Module, OnModuleInit } from '@nestjs/common';
  2. import { TypeOrmModule } from '@nestjs/typeorm';
  3. import { ConfigModule } from '../config/config.module';
  4. import { ConfigService } from '../config/config.service';
  5. import { EventBusModule } from '../event-bus/event-bus.module';
  6. import { AssetUpdater } from './helpers/asset-updater/asset-updater';
  7. import { ListQueryBuilder } from './helpers/list-query-builder/list-query-builder';
  8. import { OrderCalculator } from './helpers/order-calculator/order-calculator';
  9. import { OrderMerger } from './helpers/order-merger/order-merger';
  10. import { OrderStateMachine } from './helpers/order-state-machine/order-state-machine';
  11. import { PasswordCiper } from './helpers/password-cipher/password-ciper';
  12. import { PaymentStateMachine } from './helpers/payment-state-machine/payment-state-machine';
  13. import { RefundStateMachine } from './helpers/refund-state-machine/refund-state-machine';
  14. import { ShippingCalculator } from './helpers/shipping-calculator/shipping-calculator';
  15. import { ShippingConfiguration } from './helpers/shipping-configuration/shipping-configuration';
  16. import { TaxCalculator } from './helpers/tax-calculator/tax-calculator';
  17. import { TranslatableSaver } from './helpers/translatable-saver/translatable-saver';
  18. import { VerificationTokenGenerator } from './helpers/verification-token-generator/verification-token-generator';
  19. import { AdministratorService } from './services/administrator.service';
  20. import { AssetService } from './services/asset.service';
  21. import { AuthService } from './services/auth.service';
  22. import { ChannelService } from './services/channel.service';
  23. import { CollectionService } from './services/collection.service';
  24. import { CountryService } from './services/country.service';
  25. import { CustomerGroupService } from './services/customer-group.service';
  26. import { CustomerService } from './services/customer.service';
  27. import { FacetValueService } from './services/facet-value.service';
  28. import { FacetService } from './services/facet.service';
  29. import { GlobalSettingsService } from './services/global-settings.service';
  30. import { HistoryService } from './services/history.service';
  31. import { JobService } from './services/job.service';
  32. import { OrderTestingService } from './services/order-testing.service';
  33. import { OrderService } from './services/order.service';
  34. import { PaymentMethodService } from './services/payment-method.service';
  35. import { ProductOptionGroupService } from './services/product-option-group.service';
  36. import { ProductOptionService } from './services/product-option.service';
  37. import { ProductVariantService } from './services/product-variant.service';
  38. import { ProductService } from './services/product.service';
  39. import { PromotionService } from './services/promotion.service';
  40. import { RoleService } from './services/role.service';
  41. import { SearchService } from './services/search.service';
  42. import { ShippingMethodService } from './services/shipping-method.service';
  43. import { StockMovementService } from './services/stock-movement.service';
  44. import { TaxCategoryService } from './services/tax-category.service';
  45. import { TaxRateService } from './services/tax-rate.service';
  46. import { UserService } from './services/user.service';
  47. import { ZoneService } from './services/zone.service';
  48. const exportedProviders = [
  49. AdministratorService,
  50. AssetService,
  51. AuthService,
  52. ChannelService,
  53. CollectionService,
  54. CountryService,
  55. CustomerGroupService,
  56. CustomerService,
  57. FacetService,
  58. FacetValueService,
  59. GlobalSettingsService,
  60. HistoryService,
  61. JobService,
  62. OrderService,
  63. OrderTestingService,
  64. PaymentMethodService,
  65. ProductOptionGroupService,
  66. ProductOptionService,
  67. ProductService,
  68. ProductVariantService,
  69. PromotionService,
  70. RoleService,
  71. SearchService,
  72. ShippingMethodService,
  73. StockMovementService,
  74. TaxCategoryService,
  75. TaxRateService,
  76. UserService,
  77. ZoneService,
  78. TranslatableSaver,
  79. ];
  80. let defaultTypeOrmModule: DynamicModule;
  81. let workerTypeOrmModule: DynamicModule;
  82. /**
  83. * The ServiceCoreModule is imported internally by the ServiceModule. It is arranged in this way so that
  84. * there is only a single instance of this module being instantiated, and thus the lifecycle hooks will
  85. * only run a single time.
  86. */
  87. @Module({
  88. imports: [ConfigModule, EventBusModule],
  89. providers: [
  90. ...exportedProviders,
  91. PasswordCiper,
  92. TaxCalculator,
  93. OrderCalculator,
  94. OrderStateMachine,
  95. OrderMerger,
  96. PaymentStateMachine,
  97. ListQueryBuilder,
  98. ShippingCalculator,
  99. AssetUpdater,
  100. VerificationTokenGenerator,
  101. RefundStateMachine,
  102. ShippingConfiguration,
  103. ],
  104. exports: exportedProviders,
  105. })
  106. export class ServiceCoreModule implements OnModuleInit {
  107. constructor(
  108. private channelService: ChannelService,
  109. private roleService: RoleService,
  110. private administratorService: AdministratorService,
  111. private taxRateService: TaxRateService,
  112. private shippingMethodService: ShippingMethodService,
  113. private paymentMethodService: PaymentMethodService,
  114. private globalSettingsService: GlobalSettingsService,
  115. ) {}
  116. async onModuleInit() {
  117. // IMPORTANT - why manually invoke these init methods rather than just relying on
  118. // Nest's "onModuleInit" lifecycle hook within each individual service class?
  119. // The reason is that the order of invokation matters. By explicitly invoking the
  120. // methods below, we can e.g. guarantee that the default channel exists
  121. // (channelService.initChannels()) before we try to create any roles (which assume that
  122. // there is a default Channel to work with.
  123. await this.globalSettingsService.initGlobalSettings();
  124. await this.channelService.initChannels();
  125. await this.roleService.initRoles();
  126. await this.administratorService.initAdministrators();
  127. await this.taxRateService.initTaxRates();
  128. await this.shippingMethodService.initShippingMethods();
  129. await this.paymentMethodService.initPaymentMethods();
  130. }
  131. }
  132. /**
  133. * The ServiceModule is responsible for the service layer, i.e. accessing the database
  134. * and implementing the main business logic of the application.
  135. *
  136. * The exported providers are used in the ApiModule, which is responsible for parsing requests
  137. * into a format suitable for the service layer logic.
  138. */
  139. @Module({
  140. imports: [ServiceCoreModule],
  141. exports: [ServiceCoreModule],
  142. })
  143. export class ServiceModule {
  144. static forRoot(): DynamicModule {
  145. if (!defaultTypeOrmModule) {
  146. defaultTypeOrmModule = TypeOrmModule.forRootAsync({
  147. imports: [ConfigModule],
  148. useFactory: (configService: ConfigService) => {
  149. return configService.dbConnectionOptions;
  150. },
  151. inject: [ConfigService],
  152. });
  153. }
  154. return {
  155. module: ServiceModule,
  156. imports: [defaultTypeOrmModule],
  157. };
  158. }
  159. static forWorker(): DynamicModule {
  160. if (!workerTypeOrmModule) {
  161. workerTypeOrmModule = TypeOrmModule.forRootAsync({
  162. imports: [ConfigModule],
  163. useFactory: (configService: ConfigService) => {
  164. const { dbConnectionOptions, workerOptions } = configService;
  165. if (workerOptions.runInMainProcess) {
  166. // When running in the main process, we can re-use the existing
  167. // default connection.
  168. return {
  169. ...dbConnectionOptions,
  170. name: 'default',
  171. keepConnectionAlive: true,
  172. };
  173. } else {
  174. return {
  175. ...dbConnectionOptions,
  176. name: 'worker',
  177. };
  178. }
  179. },
  180. inject: [ConfigService],
  181. });
  182. }
  183. return {
  184. module: ServiceModule,
  185. imports: [workerTypeOrmModule],
  186. };
  187. }
  188. static forPlugin(): DynamicModule {
  189. return {
  190. module: ServiceModule,
  191. imports: [TypeOrmModule.forFeature()],
  192. };
  193. }
  194. }