Jelajahi Sumber

refactor(server): Split app into Nest modules & reorganize

The app has reached the point where it makes sense to split into smaller modules. This also allowed me to rework the folder structure and the location of many of the files. The result is a more coherent relationship of files and folders.
Michael Bromley 7 tahun lalu
induk
melakukan
fb2c816b33
69 mengubah file dengan 250 tambahan dan 191 penghapusan
  1. 1 1
      server/e2e/test-server.ts
  2. 0 0
      server/src/api/__snapshots__/graphql-custom-fields.spec.ts.snap
  3. 44 0
      server/src/api/api.module.ts
  4. 4 6
      server/src/api/auth/auth.controller.ts
  5. 0 4
      server/src/api/auth/login.dto.ts
  6. 1 1
      server/src/api/common/id-codec.spec.ts
  7. 1 1
      server/src/api/config/config.resolver.ts
  8. 1 1
      server/src/api/facet/facet.resolver.ts
  9. 3 2
      server/src/api/graphql-config.service.ts
  10. 0 0
      server/src/api/graphql-custom-fields.spec.ts
  11. 0 0
      server/src/api/graphql-custom-fields.ts
  12. 3 3
      server/src/api/jwt.strategy.ts
  13. 1 1
      server/src/api/product-option/product-option.resolver.ts
  14. 1 1
      server/src/api/product/product.resolver.ts
  15. 1 1
      server/src/api/roles-guard.ts
  16. 5 60
      server/src/app.module.ts
  17. 0 0
      server/src/common/types/auth-types.ts
  18. 0 0
      server/src/common/types/common-types.graphql
  19. 3 2
      server/src/common/types/common-types.ts
  20. 0 0
      server/src/common/types/language-code.graphql
  21. 3 5
      server/src/common/types/locale-types.ts
  22. 0 0
      server/src/common/types/role.ts
  23. 11 0
      server/src/config/config.module.ts
  24. 1 1
      server/src/config/config.service.mock.ts
  25. 1 1
      server/src/config/config.service.ts
  26. 1 1
      server/src/config/vendure-config.ts
  27. 1 1
      server/src/entity/facet-value/facet-value-translation.entity.ts
  28. 1 1
      server/src/entity/facet-value/facet-value.entity.ts
  29. 1 1
      server/src/entity/facet/facet-translation.entity.ts
  30. 1 1
      server/src/entity/facet/facet.entity.ts
  31. 1 1
      server/src/entity/product-option-group/product-option-group-translation.entity.ts
  32. 1 1
      server/src/entity/product-option-group/product-option-group.dto.ts
  33. 1 1
      server/src/entity/product-option-group/product-option-group.entity.ts
  34. 1 1
      server/src/entity/product-option/product-option-translation.entity.ts
  35. 1 1
      server/src/entity/product-option/product-option.entity.ts
  36. 1 1
      server/src/entity/product-variant/create-product-variant.dto.ts
  37. 1 1
      server/src/entity/product-variant/product-variant-translation.entity.ts
  38. 1 1
      server/src/entity/product-variant/product-variant.entity.ts
  39. 1 1
      server/src/entity/product/product-translation.entity.ts
  40. 1 1
      server/src/entity/product/product.entity.ts
  41. 1 1
      server/src/entity/user/user.entity.ts
  42. 12 0
      server/src/i18n/i18n.module.ts
  43. 1 1
      server/src/i18n/i18n.service.ts
  44. 3 2
      server/src/service/administrator.service.ts
  45. 3 3
      server/src/service/auth.service.ts
  46. 5 4
      server/src/service/customer.service.ts
  47. 6 5
      server/src/service/facet-value.service.ts
  48. 8 7
      server/src/service/facet.service.ts
  49. 2 2
      server/src/service/helpers/build-list-query.ts
  50. 1 1
      server/src/service/helpers/create-translatable.ts
  51. 3 3
      server/src/service/helpers/parse-filter-params.spec.ts
  52. 3 3
      server/src/service/helpers/parse-filter-params.ts
  53. 4 4
      server/src/service/helpers/parse-sort-params.spec.ts
  54. 3 3
      server/src/service/helpers/parse-sort-params.ts
  55. 8 8
      server/src/service/helpers/translate-entity.spec.ts
  56. 3 3
      server/src/service/helpers/translate-entity.ts
  57. 1 1
      server/src/service/helpers/translation-updater.mock.ts
  58. 2 1
      server/src/service/helpers/translation-updater.service.ts
  59. 4 4
      server/src/service/helpers/translation-updater.spec.ts
  60. 3 3
      server/src/service/helpers/translation-updater.ts
  61. 3 2
      server/src/service/helpers/update-translatable.ts
  62. 0 0
      server/src/service/password.service.ts
  63. 6 5
      server/src/service/product-option-group.service.ts
  64. 4 3
      server/src/service/product-option.service.ts
  65. 2 2
      server/src/service/product-variant.service.spec.ts
  66. 6 5
      server/src/service/product-variant.service.ts
  67. 2 2
      server/src/service/product.service.spec.ts
  68. 8 7
      server/src/service/product.service.ts
  69. 43 0
      server/src/service/service.module.ts

+ 1 - 1
server/e2e/test-server.ts

@@ -6,7 +6,7 @@ import { SqljsConnectionOptions } from 'typeorm/driver/sqljs/SqljsConnectionOpti
 
 import { populate, PopulateOptions } from '../mock-data/populate';
 import { preBootstrapConfig } from '../src/bootstrap';
-import { Mutable } from '../src/common/common-types';
+import { Mutable } from '../src/common/types/common-types';
 import { VendureConfig } from '../src/config/vendure-config';
 
 import { testConfig } from './config/test-config';

+ 0 - 0
server/src/entity/__snapshots__/graphql-custom-fields.spec.ts.snap → server/src/api/__snapshots__/graphql-custom-fields.spec.ts.snap


+ 44 - 0
server/src/api/api.module.ts

@@ -0,0 +1,44 @@
+import { Module } from '@nestjs/common';
+import { GraphQLModule } from '@nestjs/graphql';
+
+import { ConfigModule } from '../config/config.module';
+import { I18nModule } from '../i18n/i18n.module';
+import { ServiceModule } from '../service/service.module';
+
+import { AdministratorResolver } from './administrator/administrator.resolver';
+import { AuthController } from './auth/auth.controller';
+import { ConfigResolver } from './config/config.resolver';
+import { CustomerResolver } from './customer/customer.resolver';
+import { FacetResolver } from './facet/facet.resolver';
+import { GraphqlConfigService } from './graphql-config.service';
+import { JwtStrategy } from './jwt.strategy';
+import { ProductOptionResolver } from './product-option/product-option.resolver';
+import { ProductResolver } from './product/product.resolver';
+
+const exportedProviders = [
+    AdministratorResolver,
+    ConfigResolver,
+    FacetResolver,
+    CustomerResolver,
+    ProductOptionResolver,
+    ProductResolver,
+];
+
+/**
+ * The ApiModule is responsible for the public API of the application. This is where requests
+ * come in, are parsed and then handed over to the ServiceModule classes which take care
+ * of the business logic.
+ */
+@Module({
+    imports: [
+        ServiceModule,
+        GraphQLModule.forRootAsync({
+            useClass: GraphqlConfigService,
+            imports: [ConfigModule, I18nModule],
+        }),
+    ],
+    controllers: [AuthController],
+    providers: [...exportedProviders, JwtStrategy],
+    exports: exportedProviders,
+})
+export class ApiModule {}

+ 4 - 6
server/src/api/auth/auth.controller.ts

@@ -1,11 +1,9 @@
 import { Body, Controller, Get, Post, Req } from '@nestjs/common';
 
-import { AuthService } from '../../auth/auth.service';
-import { Role } from '../../auth/role';
-import { RolesGuard } from '../../auth/roles-guard';
+import { Role } from '../../common/types/role';
 import { User } from '../../entity/user/user.entity';
-
-import { LoginDto } from './login.dto';
+import { AuthService } from '../../service/auth.service';
+import { RolesGuard } from '../roles-guard';
 
 @Controller('auth')
 export class AuthController {
@@ -16,7 +14,7 @@ export class AuthController {
      * the user data and a token to be used by Bearer auth.
      */
     @Post('login')
-    async login(@Body() loginDto: LoginDto) {
+    async login(@Body() loginDto: { username: string; password: string }) {
         const { user, token } = await this.authService.createToken(loginDto.username, loginDto.password);
 
         if (token) {

+ 0 - 4
server/src/api/auth/login.dto.ts

@@ -1,4 +0,0 @@
-export interface LoginDto {
-    username: string;
-    password: string;
-}

+ 1 - 1
server/src/api/common/id-codec.spec.ts

@@ -1,4 +1,4 @@
-import { DECODED, ENCODED, MockIdStrategy } from '../../service/config.service.mock';
+import { DECODED, ENCODED, MockIdStrategy } from '../../config/config.service.mock';
 
 import { IdCodec } from './id-codec';
 

+ 1 - 1
server/src/api/config/config.resolver.ts

@@ -1,7 +1,7 @@
 import { Query, Resolver } from '@nestjs/graphql';
 
+import { ConfigService } from '../../config/config.service';
 import { getConfig, VendureConfig } from '../../config/vendure-config';
-import { ConfigService } from '../../service/config.service';
 
 @Resolver('Config')
 export class ConfigResolver {

+ 1 - 1
server/src/api/facet/facet.resolver.ts

@@ -8,10 +8,10 @@ import {
 import { PaginatedList } from 'shared/shared-types';
 
 import { DEFAULT_LANGUAGE_CODE } from '../../common/constants';
+import { Translated } from '../../common/types/locale-types';
 import { FacetValue } from '../../entity/facet-value/facet-value.entity';
 import { Facet } from '../../entity/facet/facet.entity';
 import { I18nError } from '../../i18n/i18n-error';
-import { Translated } from '../../locale/locale-types';
 import { FacetValueService } from '../../service/facet-value.service';
 import { FacetService } from '../../service/facet.service';
 import { ApplyIdCodec } from '../common/apply-id-codec-decorator';

+ 3 - 2
server/src/config/graphql-config.service.ts → server/src/api/graphql-config.service.ts

@@ -8,9 +8,10 @@ import { flatten } from 'lodash';
 import { mergeTypes } from 'merge-graphql-schemas';
 import * as path from 'path';
 
-import { addGraphQLCustomFields } from '../entity/graphql-custom-fields';
+import { ConfigService } from '../config/config.service';
 import { I18nService } from '../i18n/i18n.service';
-import { ConfigService } from '../service/config.service';
+
+import { addGraphQLCustomFields } from './graphql-custom-fields';
 
 @Injectable()
 export class GraphqlConfigService implements GqlOptionsFactory {

+ 0 - 0
server/src/entity/graphql-custom-fields.spec.ts → server/src/api/graphql-custom-fields.spec.ts


+ 0 - 0
server/src/entity/graphql-custom-fields.ts → server/src/api/graphql-custom-fields.ts


+ 3 - 3
server/src/auth/jwt.strategy.ts → server/src/api/jwt.strategy.ts

@@ -2,10 +2,10 @@ import { Injectable, UnauthorizedException } from '@nestjs/common';
 import { PassportStrategy } from '@nestjs/passport';
 import { ExtractJwt, Strategy } from 'passport-jwt';
 
-import { ConfigService } from '../service/config.service';
+import { ConfigService } from '../config/config.service';
+import { AuthService } from '../service/auth.service';
 
-import { JwtPayload } from './auth-types';
-import { AuthService } from './auth.service';
+import { JwtPayload } from '../common/types/auth-types';
 
 @Injectable()
 export class JwtStrategy extends PassportStrategy(Strategy) {

+ 1 - 1
server/src/api/product-option/product-option.resolver.ts

@@ -1,9 +1,9 @@
 import { Mutation, Query, ResolveProperty, Resolver } from '@nestjs/graphql';
 import { CreateProductOptionGroupVariables } from 'shared/generated-types';
 
+import { Translated } from '../../common/types/locale-types';
 import { ProductOptionGroup } from '../../entity/product-option-group/product-option-group.entity';
 import { ProductOption } from '../../entity/product-option/product-option.entity';
-import { Translated } from '../../locale/locale-types';
 import { ProductOptionGroupService } from '../../service/product-option-group.service';
 import { ProductOptionService } from '../../service/product-option.service';
 import { ApplyIdCodec } from '../common/apply-id-codec-decorator';

+ 1 - 1
server/src/api/product/product.resolver.ts

@@ -9,11 +9,11 @@ import {
 import { ID, PaginatedList } from 'shared/shared-types';
 
 import { DEFAULT_LANGUAGE_CODE } from '../../common/constants';
+import { Translated } from '../../common/types/locale-types';
 import { assertFound } from '../../common/utils';
 import { ProductVariant } from '../../entity/product-variant/product-variant.entity';
 import { Product } from '../../entity/product/product.entity';
 import { I18nError } from '../../i18n/i18n-error';
-import { Translated } from '../../locale/locale-types';
 import { FacetValueService } from '../../service/facet-value.service';
 import { ProductVariantService } from '../../service/product-variant.service';
 import { ProductService } from '../../service/product.service';

+ 1 - 1
server/src/auth/roles-guard.ts → server/src/api/roles-guard.ts

@@ -4,7 +4,7 @@ import { ExtractJwt, Strategy } from 'passport-jwt';
 
 import { User } from '../entity/user/user.entity';
 
-import { Role } from './role';
+import { Role } from '../common/types/role';
 
 /**
  * A guard which combines the JWT passport auth method with restrictions based on

+ 5 - 60
server/src/app.module.ts

@@ -1,70 +1,15 @@
 import { MiddlewareConsumer, Module, NestModule } from '@nestjs/common';
-import { GraphQLModule } from '@nestjs/graphql';
-import { TypeOrmModule } from '@nestjs/typeorm';
 import { GraphQLDateTime } from 'graphql-iso-date';
 
-import { AdministratorResolver } from './api/administrator/administrator.resolver';
-import { AuthController } from './api/auth/auth.controller';
-import { ConfigResolver } from './api/config/config.resolver';
-import { CustomerResolver } from './api/customer/customer.resolver';
-import { FacetResolver } from './api/facet/facet.resolver';
-import { ProductOptionResolver } from './api/product-option/product-option.resolver';
-import { ProductResolver } from './api/product/product.resolver';
-import { AuthService } from './auth/auth.service';
-import { JwtStrategy } from './auth/jwt.strategy';
-import { PasswordService } from './auth/password.service';
-import { GraphqlConfigService } from './config/graphql-config.service';
-import { getConfig } from './config/vendure-config';
+import { ApiModule } from './api/api.module';
+import { ConfigModule } from './config/config.module';
+import { ConfigService } from './config/config.service';
 import { validateCustomFieldsConfig } from './entity/custom-entity-fields';
+import { I18nModule } from './i18n/i18n.module';
 import { I18nService } from './i18n/i18n.service';
-import { TranslationUpdaterService } from './locale/translation-updater.service';
-import { AdministratorService } from './service/administrator.service';
-import { ConfigService } from './service/config.service';
-import { CustomerService } from './service/customer.service';
-import { FacetValueService } from './service/facet-value.service';
-import { FacetService } from './service/facet.service';
-import { ProductOptionGroupService } from './service/product-option-group.service';
-import { ProductOptionService } from './service/product-option.service';
-import { ProductVariantService } from './service/product-variant.service';
-import { ProductService } from './service/product.service';
 
 @Module({
-    providers: [ConfigService, I18nService],
-    exports: [ConfigService, I18nService],
-})
-export class ConfigModule {}
-
-@Module({
-    imports: [
-        ConfigModule,
-        GraphQLModule.forRootAsync({
-            useClass: GraphqlConfigService,
-            imports: [ConfigModule],
-        }),
-        TypeOrmModule.forRoot(getConfig().dbConnectionOptions),
-    ],
-    controllers: [AuthController],
-    providers: [
-        AdministratorResolver,
-        AdministratorService,
-        AuthService,
-        ConfigResolver,
-        FacetResolver,
-        FacetService,
-        FacetValueService,
-        JwtStrategy,
-        PasswordService,
-        CustomerService,
-        CustomerResolver,
-        ProductService,
-        ProductOptionResolver,
-        ProductOptionService,
-        ProductOptionGroupService,
-        ProductVariantService,
-        ProductResolver,
-        PasswordService,
-        TranslationUpdaterService,
-    ],
+    imports: [ConfigModule, I18nModule, ApiModule],
 })
 export class AppModule implements NestModule {
     constructor(private configService: ConfigService, private i18nService: I18nService) {}

+ 0 - 0
server/src/auth/auth-types.ts → server/src/common/types/auth-types.ts


+ 0 - 0
server/src/common/common-types.graphql → server/src/common/types/common-types.graphql


+ 3 - 2
server/src/common/common-types.ts → server/src/common/types/common-types.ts

@@ -1,5 +1,6 @@
-import { VendureEntity } from '../entity/base/base.entity';
-import { LocaleString } from '../locale/locale-types';
+import { VendureEntity } from '../../entity/base/base.entity';
+
+import { LocaleString } from './locale-types';
 
 /**
  * Creates a type based on T, but with all properties non-optional

+ 0 - 0
server/src/locale/language-code.graphql → server/src/common/types/language-code.graphql


+ 3 - 5
server/src/locale/locale-types.ts → server/src/common/types/locale-types.ts

@@ -1,11 +1,9 @@
 import { LanguageCode } from 'shared/generated-types';
-import { ID } from 'shared/shared-types';
-import { CustomFieldsObject } from 'shared/shared-types';
+import { CustomFieldsObject, ID } from 'shared/shared-types';
 
-import { UnwrappedArray } from '../common/common-types';
-import { VendureEntity } from '../entity/base/base.entity';
+import { TranslatableRelationsKeys } from '../../service/helpers/translate-entity';
 
-import { TranslatableRelationsKeys } from './translate-entity';
+import { UnwrappedArray } from './common-types';
 
 /**
  * This type should be used in any interfaces where the value is to be

+ 0 - 0
server/src/auth/role.ts → server/src/common/types/role.ts


+ 11 - 0
server/src/config/config.module.ts

@@ -0,0 +1,11 @@
+import { Module } from '@nestjs/common';
+
+import { I18nService } from '../i18n/i18n.service';
+
+import { ConfigService } from './config.service';
+
+@Module({
+    providers: [ConfigService],
+    exports: [ConfigService],
+})
+export class ConfigModule {}

+ 1 - 1
server/src/service/config.service.mock.ts → server/src/config/config.service.mock.ts

@@ -1,8 +1,8 @@
-import { EntityIdStrategy, PrimaryKeyType } from '../config/entity-id-strategy/entity-id-strategy';
 import { VendureEntity } from '../entity/base/base.entity';
 import { MockClass } from '../testing/testing-types';
 
 import { ConfigService } from './config.service';
+import { EntityIdStrategy, PrimaryKeyType } from './entity-id-strategy/entity-id-strategy';
 
 export class MockConfigService implements MockClass<ConfigService> {
     apiPath = 'api';

+ 1 - 1
server/src/service/config.service.ts → server/src/config/config.service.ts

@@ -4,7 +4,7 @@ import { LanguageCode } from 'shared/generated-types';
 import { CustomFields } from 'shared/shared-types';
 import { ConnectionOptions } from 'typeorm';
 
-import { ReadOnlyRequired } from '../common/common-types';
+import { ReadOnlyRequired } from '../common/types/common-types';
 import { EntityIdStrategy } from '../config/entity-id-strategy/entity-id-strategy';
 import { getConfig, VendureConfig } from '../config/vendure-config';
 

+ 1 - 1
server/src/config/vendure-config.ts

@@ -4,7 +4,7 @@ import { API_PATH, API_PORT } from 'shared/shared-constants';
 import { CustomFields, DeepPartial } from 'shared/shared-types';
 import { ConnectionOptions } from 'typeorm';
 
-import { ReadOnlyRequired } from '../common/common-types';
+import { ReadOnlyRequired } from '../common/types/common-types';
 
 import { AutoIncrementIdStrategy } from './entity-id-strategy/auto-increment-id-strategy';
 import { EntityIdStrategy } from './entity-id-strategy/entity-id-strategy';

+ 1 - 1
server/src/entity/facet-value/facet-value-translation.entity.ts

@@ -2,7 +2,7 @@ import { LanguageCode } from 'shared/generated-types';
 import { DeepPartial } from 'shared/shared-types';
 import { Column, Entity, ManyToOne } from 'typeorm';
 
-import { Translation } from '../../locale/locale-types';
+import { Translation } from '../../common/types/locale-types';
 import { VendureEntity } from '../base/base.entity';
 import { CustomFacetValueFieldsTranslation } from '../custom-entity-fields';
 

+ 1 - 1
server/src/entity/facet-value/facet-value.entity.ts

@@ -1,7 +1,7 @@
 import { DeepPartial, HasCustomFields } from 'shared/shared-types';
 import { Column, Entity, ManyToOne, OneToMany } from 'typeorm';
 
-import { LocaleString, Translatable, Translation } from '../../locale/locale-types';
+import { LocaleString, Translatable, Translation } from '../../common/types/locale-types';
 import { VendureEntity } from '../base/base.entity';
 import { CustomFacetValueFields } from '../custom-entity-fields';
 import { Facet } from '../facet/facet.entity';

+ 1 - 1
server/src/entity/facet/facet-translation.entity.ts

@@ -2,7 +2,7 @@ import { LanguageCode } from 'shared/generated-types';
 import { DeepPartial, HasCustomFields } from 'shared/shared-types';
 import { Column, Entity, ManyToOne } from 'typeorm';
 
-import { Translation } from '../../locale/locale-types';
+import { Translation } from '../../common/types/locale-types';
 import { VendureEntity } from '../base/base.entity';
 import { CustomFacetFieldsTranslation } from '../custom-entity-fields';
 

+ 1 - 1
server/src/entity/facet/facet.entity.ts

@@ -1,7 +1,7 @@
 import { DeepPartial, HasCustomFields } from 'shared/shared-types';
 import { Column, Entity, OneToMany } from 'typeorm';
 
-import { LocaleString, Translatable, Translation } from '../../locale/locale-types';
+import { LocaleString, Translatable, Translation } from '../../common/types/locale-types';
 import { VendureEntity } from '../base/base.entity';
 import { CustomFacetFields } from '../custom-entity-fields';
 import { FacetValue } from '../facet-value/facet-value.entity';

+ 1 - 1
server/src/entity/product-option-group/product-option-group-translation.entity.ts

@@ -3,7 +3,7 @@ import { DeepPartial } from 'shared/shared-types';
 import { HasCustomFields } from 'shared/shared-types';
 import { Column, Entity, ManyToOne } from 'typeorm';
 
-import { Translation } from '../../locale/locale-types';
+import { Translation } from '../../common/types/locale-types';
 import { VendureEntity } from '../base/base.entity';
 import { CustomProductOptionGroupFieldsTranslation } from '../custom-entity-fields';
 

+ 1 - 1
server/src/entity/product-option-group/product-option-group.dto.ts

@@ -1,4 +1,4 @@
-import { TranslatedInput } from '../../locale/locale-types';
+import { TranslatedInput } from '../../common/types/locale-types';
 
 import { ProductOptionGroup } from './product-option-group.entity';
 

+ 1 - 1
server/src/entity/product-option-group/product-option-group.entity.ts

@@ -2,7 +2,7 @@ import { DeepPartial } from 'shared/shared-types';
 import { HasCustomFields } from 'shared/shared-types';
 import { Column, Entity, OneToMany } from 'typeorm';
 
-import { LocaleString, Translatable, Translation } from '../../locale/locale-types';
+import { LocaleString, Translatable, Translation } from '../../common/types/locale-types';
 import { VendureEntity } from '../base/base.entity';
 import { CustomProductOptionGroupFields } from '../custom-entity-fields';
 import { ProductOption } from '../product-option/product-option.entity';

+ 1 - 1
server/src/entity/product-option/product-option-translation.entity.ts

@@ -3,7 +3,7 @@ import { DeepPartial } from 'shared/shared-types';
 import { HasCustomFields } from 'shared/shared-types';
 import { Column, Entity, ManyToOne } from 'typeorm';
 
-import { Translation } from '../../locale/locale-types';
+import { Translation } from '../../common/types/locale-types';
 import { VendureEntity } from '../base/base.entity';
 import { CustomProductOptionFieldsTranslation } from '../custom-entity-fields';
 

+ 1 - 1
server/src/entity/product-option/product-option.entity.ts

@@ -2,7 +2,7 @@ import { DeepPartial } from 'shared/shared-types';
 import { HasCustomFields } from 'shared/shared-types';
 import { Column, Entity, ManyToOne, OneToMany } from 'typeorm';
 
-import { LocaleString, Translatable, Translation } from '../../locale/locale-types';
+import { LocaleString, Translatable, Translation } from '../../common/types/locale-types';
 import { VendureEntity } from '../base/base.entity';
 import { CustomProductOptionFields } from '../custom-entity-fields';
 import { ProductOptionGroup } from '../product-option-group/product-option-group.entity';

+ 1 - 1
server/src/entity/product-variant/create-product-variant.dto.ts

@@ -1,6 +1,6 @@
 import { ID } from 'shared/shared-types';
 
-import { TranslatedInput } from '../../locale/locale-types';
+import { TranslatedInput } from '../../common/types/locale-types';
 
 import { ProductVariant } from './product-variant.entity';
 

+ 1 - 1
server/src/entity/product-variant/product-variant-translation.entity.ts

@@ -3,7 +3,7 @@ import { DeepPartial } from 'shared/shared-types';
 import { HasCustomFields } from 'shared/shared-types';
 import { Column, Entity, ManyToOne } from 'typeorm';
 
-import { Translation } from '../../locale/locale-types';
+import { Translation } from '../../common/types/locale-types';
 import { VendureEntity } from '../base/base.entity';
 import { CustomProductVariantFieldsTranslation } from '../custom-entity-fields';
 

+ 1 - 1
server/src/entity/product-variant/product-variant.entity.ts

@@ -1,7 +1,7 @@
 import { DeepPartial, HasCustomFields } from 'shared/shared-types';
 import { Column, Entity, JoinTable, ManyToMany, ManyToOne, OneToMany } from 'typeorm';
 
-import { LocaleString, Translatable, Translation } from '../../locale/locale-types';
+import { LocaleString, Translatable, Translation } from '../../common/types/locale-types';
 import { VendureEntity } from '../base/base.entity';
 import { CustomProductVariantFields } from '../custom-entity-fields';
 import { FacetValue } from '../facet-value/facet-value.entity';

+ 1 - 1
server/src/entity/product/product-translation.entity.ts

@@ -2,7 +2,7 @@ import { LanguageCode } from 'shared/generated-types';
 import { DeepPartial, HasCustomFields } from 'shared/shared-types';
 import { Column, Entity, ManyToOne } from 'typeorm';
 
-import { Translation } from '../../locale/locale-types';
+import { Translation } from '../../common/types/locale-types';
 import { VendureEntity } from '../base/base.entity';
 import { CustomProductFieldsTranslation } from '../custom-entity-fields';
 

+ 1 - 1
server/src/entity/product/product.entity.ts

@@ -2,7 +2,7 @@ import { DeepPartial } from 'shared/shared-types';
 import { HasCustomFields } from 'shared/shared-types';
 import { Column, Entity, JoinTable, ManyToMany, OneToMany } from 'typeorm';
 
-import { LocaleString, Translatable, Translation } from '../../locale/locale-types';
+import { LocaleString, Translatable, Translation } from '../../common/types/locale-types';
 import { VendureEntity } from '../base/base.entity';
 import { CustomProductFields } from '../custom-entity-fields';
 import { ProductOptionGroup } from '../product-option-group/product-option-group.entity';

+ 1 - 1
server/src/entity/user/user.entity.ts

@@ -2,7 +2,7 @@ import { DeepPartial } from 'shared/shared-types';
 import { HasCustomFields } from 'shared/shared-types';
 import { Column, Entity } from 'typeorm';
 
-import { Role } from '../../auth/role';
+import { Role } from '../../common/types/role';
 import { VendureEntity } from '../base/base.entity';
 import { CustomUserFields } from '../custom-entity-fields';
 

+ 12 - 0
server/src/i18n/i18n.module.ts

@@ -0,0 +1,12 @@
+import { Module } from '@nestjs/common';
+
+import { ConfigModule } from '../config/config.module';
+
+import { I18nService } from './i18n.service';
+
+@Module({
+    imports: [ConfigModule],
+    providers: [I18nService],
+    exports: [I18nService],
+})
+export class I18nModule {}

+ 1 - 1
server/src/i18n/i18n.service.ts

@@ -8,7 +8,7 @@ import * as ICU from 'i18next-icu';
 import * as Backend from 'i18next-node-fs-backend';
 import * as path from 'path';
 
-import { ConfigService } from '../service/config.service';
+import { ConfigService } from '../config/config.service';
 
 import { I18nError } from './i18n-error';
 

+ 3 - 2
server/src/service/administrator.service.ts

@@ -2,12 +2,13 @@ import { Injectable } from '@nestjs/common';
 import { InjectConnection } from '@nestjs/typeorm';
 import { Connection } from 'typeorm';
 
-import { PasswordService } from '../auth/password.service';
-import { Role } from '../auth/role';
+import { Role } from '../common/types/role';
 import { CreateAdministratorDto } from '../entity/administrator/administrator.dto';
 import { Administrator } from '../entity/administrator/administrator.entity';
 import { User } from '../entity/user/user.entity';
 
+import { PasswordService } from './password.service';
+
 @Injectable()
 export class AdministratorService {
     constructor(

+ 3 - 3
server/src/auth/auth.service.ts → server/src/service/auth.service.ts

@@ -3,12 +3,12 @@ import { InjectConnection } from '@nestjs/typeorm';
 import * as jwt from 'jsonwebtoken';
 import { Connection } from 'typeorm';
 
+import { JwtPayload } from '../common/types/auth-types';
+import { Role } from '../common/types/role';
+import { ConfigService } from '../config/config.service';
 import { User } from '../entity/user/user.entity';
-import { ConfigService } from '../service/config.service';
 
-import { JwtPayload } from './auth-types';
 import { PasswordService } from './password.service';
-import { Role } from './role';
 
 @Injectable()
 export class AuthService {

+ 5 - 4
server/src/service/customer.service.ts

@@ -3,10 +3,8 @@ import { InjectConnection } from '@nestjs/typeorm';
 import { ID, PaginatedList } from 'shared/shared-types';
 import { Connection } from 'typeorm';
 
-import { PasswordService } from '../auth/password.service';
-import { Role } from '../auth/role';
-import { buildListQuery } from '../common/build-list-query';
-import { ListQueryOptions } from '../common/common-types';
+import { ListQueryOptions } from '../common/types/common-types';
+import { Role } from '../common/types/role';
 import { CreateAddressDto } from '../entity/address/address.dto';
 import { Address } from '../entity/address/address.entity';
 import { CreateCustomerDto } from '../entity/customer/customer.dto';
@@ -14,6 +12,9 @@ import { Customer } from '../entity/customer/customer.entity';
 import { User } from '../entity/user/user.entity';
 import { I18nError } from '../i18n/i18n-error';
 
+import { buildListQuery } from './helpers/build-list-query';
+import { PasswordService } from './password.service';
+
 @Injectable()
 export class CustomerService {
     constructor(

+ 6 - 5
server/src/service/facet-value.service.ts

@@ -10,15 +10,16 @@ import { ID } from 'shared/shared-types';
 import { Connection } from 'typeorm';
 
 import { DEFAULT_LANGUAGE_CODE } from '../common/constants';
-import { createTranslatable } from '../common/create-translatable';
-import { updateTranslatable } from '../common/update-translatable';
+import { Translated } from '../common/types/locale-types';
 import { assertFound } from '../common/utils';
 import { FacetValueTranslation } from '../entity/facet-value/facet-value-translation.entity';
 import { FacetValue } from '../entity/facet-value/facet-value.entity';
 import { Facet } from '../entity/facet/facet.entity';
-import { Translated } from '../locale/locale-types';
-import { translateDeep } from '../locale/translate-entity';
-import { TranslationUpdaterService } from '../locale/translation-updater.service';
+
+import { createTranslatable } from './helpers/create-translatable';
+import { translateDeep } from './helpers/translate-entity';
+import { TranslationUpdaterService } from './helpers/translation-updater.service';
+import { updateTranslatable } from './helpers/update-translatable';
 
 @Injectable()
 export class FacetValueService {

+ 8 - 7
server/src/service/facet.service.ts

@@ -4,17 +4,18 @@ import { CreateFacetInput, LanguageCode, UpdateFacetInput } from 'shared/generat
 import { ID, PaginatedList } from 'shared/shared-types';
 import { Connection } from 'typeorm';
 
-import { buildListQuery } from '../common/build-list-query';
-import { ListQueryOptions } from '../common/common-types';
 import { DEFAULT_LANGUAGE_CODE } from '../common/constants';
-import { createTranslatable } from '../common/create-translatable';
-import { updateTranslatable } from '../common/update-translatable';
+import { ListQueryOptions } from '../common/types/common-types';
+import { Translated } from '../common/types/locale-types';
 import { assertFound } from '../common/utils';
 import { FacetTranslation } from '../entity/facet/facet-translation.entity';
 import { Facet } from '../entity/facet/facet.entity';
-import { Translated } from '../locale/locale-types';
-import { translateDeep } from '../locale/translate-entity';
-import { TranslationUpdaterService } from '../locale/translation-updater.service';
+
+import { buildListQuery } from './helpers/build-list-query';
+import { createTranslatable } from './helpers/create-translatable';
+import { translateDeep } from './helpers/translate-entity';
+import { TranslationUpdaterService } from './helpers/translation-updater.service';
+import { updateTranslatable } from './helpers/update-translatable';
 
 @Injectable()
 export class FacetService {

+ 2 - 2
server/src/common/build-list-query.ts → server/src/service/helpers/build-list-query.ts

@@ -2,9 +2,9 @@ import { Type } from 'shared/shared-types';
 import { Connection, FindManyOptions, SelectQueryBuilder } from 'typeorm';
 import { FindOptionsUtils } from 'typeorm/find-options/FindOptionsUtils';
 
-import { VendureEntity } from '../entity/base/base.entity';
+import { ListQueryOptions } from '../../common/types/common-types';
+import { VendureEntity } from '../../entity/base/base.entity';
 
-import { ListQueryOptions } from './common-types';
 import { parseFilterParams } from './parse-filter-params';
 import { parseSortParams } from './parse-sort-params';
 

+ 1 - 1
server/src/common/create-translatable.ts → server/src/service/helpers/create-translatable.ts

@@ -1,7 +1,7 @@
 import { Type } from 'shared/shared-types';
 import { Connection } from 'typeorm';
 
-import { Translatable, TranslatedInput, Translation } from '../locale/locale-types';
+import { Translatable, TranslatedInput, Translation } from '../../common/types/locale-types';
 
 /**
  * Returns a "save" function which uses the provided connection and dto to

+ 3 - 3
server/src/common/parse-filter-params.spec.ts → server/src/service/helpers/parse-filter-params.spec.ts

@@ -1,7 +1,7 @@
-import { ProductTranslation } from '../entity/product/product-translation.entity';
-import { Product } from '../entity/product/product.entity';
+import { FilterParameter } from '../../common/types/common-types';
+import { ProductTranslation } from '../../entity/product/product-translation.entity';
+import { Product } from '../../entity/product/product.entity';
 
-import { FilterParameter } from './common-types';
 import { parseFilterParams } from './parse-filter-params';
 import { MockConnection } from './parse-sort-params.spec';
 

+ 3 - 3
server/src/common/parse-filter-params.ts → server/src/service/helpers/parse-filter-params.ts

@@ -3,8 +3,8 @@ import { assertNever } from 'shared/shared-utils';
 import { Connection } from 'typeorm';
 import { ColumnMetadata } from 'typeorm/metadata/ColumnMetadata';
 
-import { VendureEntity } from '../entity/base/base.entity';
-import { I18nError } from '../i18n/i18n-error';
+import { VendureEntity } from '../../entity/base/base.entity';
+import { I18nError } from '../../i18n/i18n-error';
 
 import {
     BooleanOperators,
@@ -13,7 +13,7 @@ import {
     NullOptionals,
     NumberOperators,
     StringOperators,
-} from './common-types';
+} from '../../common/types/common-types';
 
 export interface WhereCondition {
     clause: string;

+ 4 - 4
server/src/common/parse-sort-params.spec.ts → server/src/service/helpers/parse-sort-params.spec.ts

@@ -2,11 +2,11 @@ import { Type } from 'shared/shared-types';
 import { ColumnMetadata } from 'typeorm/metadata/ColumnMetadata';
 import { RelationMetadata } from 'typeorm/metadata/RelationMetadata';
 
-import { ProductTranslation } from '../entity/product/product-translation.entity';
-import { Product } from '../entity/product/product.entity';
-import { I18nError } from '../i18n/i18n-error';
+import { SortParameter } from '../../common/types/common-types';
+import { ProductTranslation } from '../../entity/product/product-translation.entity';
+import { Product } from '../../entity/product/product.entity';
+import { I18nError } from '../../i18n/i18n-error';
 
-import { SortParameter } from './common-types';
 import { parseSortParams } from './parse-sort-params';
 
 describe('parseSortParams()', () => {

+ 3 - 3
server/src/common/parse-sort-params.ts → server/src/service/helpers/parse-sort-params.ts

@@ -2,10 +2,10 @@ import { Type } from 'shared/shared-types';
 import { Connection, OrderByCondition } from 'typeorm';
 import { ColumnMetadata } from 'typeorm/metadata/ColumnMetadata';
 
-import { VendureEntity } from '../entity/base/base.entity';
-import { I18nError } from '../i18n/i18n-error';
+import { VendureEntity } from '../../entity/base/base.entity';
+import { I18nError } from '../../i18n/i18n-error';
 
-import { NullOptionals, SortParameter } from './common-types';
+import { NullOptionals, SortParameter } from '../../common/types/common-types';
 
 /**
  * Parses the provided SortParameter array against the metadata of the given entity, ensuring that only

+ 8 - 8
server/src/locale/translate-entity.spec.ts → server/src/service/helpers/translate-entity.spec.ts

@@ -1,13 +1,13 @@
 import { LanguageCode } from 'shared/generated-types';
 
-import { ProductOptionTranslation } from '../entity/product-option/product-option-translation.entity';
-import { ProductOption } from '../entity/product-option/product-option.entity';
-import { ProductVariantTranslation } from '../entity/product-variant/product-variant-translation.entity';
-import { ProductVariant } from '../entity/product-variant/product-variant.entity';
-import { ProductTranslation } from '../entity/product/product-translation.entity';
-import { Product } from '../entity/product/product.entity';
-
-import { Translatable, Translation } from './locale-types';
+import { Translatable, Translation } from '../../common/types/locale-types';
+import { ProductOptionTranslation } from '../../entity/product-option/product-option-translation.entity';
+import { ProductOption } from '../../entity/product-option/product-option.entity';
+import { ProductVariantTranslation } from '../../entity/product-variant/product-variant-translation.entity';
+import { ProductVariant } from '../../entity/product-variant/product-variant.entity';
+import { ProductTranslation } from '../../entity/product/product-translation.entity';
+import { Product } from '../../entity/product/product.entity';
+
 import { translateDeep, translateEntity } from './translate-entity';
 
 const LANGUAGE_CODE = LanguageCode.en;

+ 3 - 3
server/src/locale/translate-entity.ts → server/src/service/helpers/translate-entity.ts

@@ -1,9 +1,9 @@
 import { LanguageCode } from 'shared/generated-types';
 
-import { UnwrappedArray } from '../common/common-types';
-import { I18nError } from '../i18n/i18n-error';
+import { UnwrappedArray } from '../../common/types/common-types';
+import { I18nError } from '../../i18n/i18n-error';
 
-import { Translatable, Translated } from './locale-types';
+import { Translatable, Translated } from '../../common/types/locale-types';
 
 // prettier-ignore
 export type TranslatableRelationsKeys<T> = {

+ 1 - 1
server/src/locale/translation-updater.mock.ts → server/src/service/helpers/translation-updater.mock.ts

@@ -1,4 +1,4 @@
-import { MockClass } from '../testing/testing-types';
+import { MockClass } from '../../testing/testing-types';
 
 import { TranslationUpdater } from './translation-updater';
 import { TranslationUpdaterService } from './translation-updater.service';

+ 2 - 1
server/src/locale/translation-updater.service.ts → server/src/service/helpers/translation-updater.service.ts

@@ -2,7 +2,8 @@ import { Injectable } from '@nestjs/common';
 import { InjectEntityManager } from '@nestjs/typeorm';
 import { EntityManager } from 'typeorm';
 
-import { Translatable } from './locale-types';
+import { Translatable } from '../../common/types/locale-types';
+
 import { TranslationContructor, TranslationUpdater } from './translation-updater';
 
 @Injectable()

+ 4 - 4
server/src/locale/translation-updater.spec.ts → server/src/service/helpers/translation-updater.spec.ts

@@ -1,10 +1,10 @@
 import { LanguageCode } from 'shared/generated-types';
 
-import { ProductTranslation } from '../entity/product/product-translation.entity';
-import { Product } from '../entity/product/product.entity';
-import { MockEntityManager } from '../testing/connection.mock';
+import { TranslationInput } from '../../common/types/locale-types';
+import { ProductTranslation } from '../../entity/product/product-translation.entity';
+import { Product } from '../../entity/product/product.entity';
+import { MockEntityManager } from '../../testing/connection.mock';
 
-import { TranslationInput } from './locale-types';
 import { TranslationUpdater } from './translation-updater';
 
 describe('TranslationUpdater', () => {

+ 3 - 3
server/src/locale/translation-updater.ts → server/src/service/helpers/translation-updater.ts

@@ -1,10 +1,10 @@
 import { DeepPartial } from 'shared/shared-types';
 import { EntityManager } from 'typeorm';
 
-import { foundIn, not } from '../common/utils';
-import { I18nError } from '../i18n/i18n-error';
+import { foundIn, not } from '../../common/utils';
+import { I18nError } from '../../i18n/i18n-error';
 
-import { Translatable, Translation, TranslationInput } from './locale-types';
+import { Translatable, Translation, TranslationInput } from '../../common/types/locale-types';
 
 export interface TranslationContructor<T> {
     new (input?: DeepPartial<TranslationInput<T>> | DeepPartial<Translation<T>>): Translation<T>;

+ 3 - 2
server/src/common/update-translatable.ts → server/src/service/helpers/update-translatable.ts

@@ -1,8 +1,9 @@
 import { ID, Type } from 'shared/shared-types';
 import { Connection } from 'typeorm';
 
-import { Translatable, TranslatedInput, Translation } from '../locale/locale-types';
-import { TranslationUpdaterService } from '../locale/translation-updater.service';
+import { Translatable, TranslatedInput, Translation } from '../../common/types/locale-types';
+
+import { TranslationUpdaterService } from './translation-updater.service';
 
 /**
  * Returns a "save" function which uses the provided connection and dto to

+ 0 - 0
server/src/auth/password.service.ts → server/src/service/password.service.ts


+ 6 - 5
server/src/service/product-option-group.service.ts

@@ -5,15 +5,16 @@ import { ID } from 'shared/shared-types';
 import { Connection, FindManyOptions, Like } from 'typeorm';
 
 import { DEFAULT_LANGUAGE_CODE } from '../common/constants';
-import { createTranslatable } from '../common/create-translatable';
-import { updateTranslatable } from '../common/update-translatable';
+import { Translated } from '../common/types/locale-types';
 import { assertFound } from '../common/utils';
 import { ProductOptionGroupTranslation } from '../entity/product-option-group/product-option-group-translation.entity';
 import { UpdateProductOptionGroupDto } from '../entity/product-option-group/product-option-group.dto';
 import { ProductOptionGroup } from '../entity/product-option-group/product-option-group.entity';
-import { Translated } from '../locale/locale-types';
-import { translateDeep } from '../locale/translate-entity';
-import { TranslationUpdaterService } from '../locale/translation-updater.service';
+
+import { createTranslatable } from './helpers/create-translatable';
+import { translateDeep } from './helpers/translate-entity';
+import { TranslationUpdaterService } from './helpers/translation-updater.service';
+import { updateTranslatable } from './helpers/update-translatable';
 
 @Injectable()
 export class ProductOptionGroupService {

+ 4 - 3
server/src/service/product-option.service.ts

@@ -5,13 +5,14 @@ import { ID } from 'shared/shared-types';
 import { Connection } from 'typeorm';
 
 import { DEFAULT_LANGUAGE_CODE } from '../common/constants';
-import { createTranslatable } from '../common/create-translatable';
+import { Translated } from '../common/types/locale-types';
 import { assertFound } from '../common/utils';
 import { ProductOptionGroup } from '../entity/product-option-group/product-option-group.entity';
 import { ProductOptionTranslation } from '../entity/product-option/product-option-translation.entity';
 import { ProductOption } from '../entity/product-option/product-option.entity';
-import { Translated } from '../locale/locale-types';
-import { translateDeep } from '../locale/translate-entity';
+
+import { createTranslatable } from './helpers/create-translatable';
+import { translateDeep } from './helpers/translate-entity';
 
 @Injectable()
 export class ProductOptionService {

+ 2 - 2
server/src/service/product-variant.service.spec.ts

@@ -8,10 +8,10 @@ import { ProductOption } from '../entity/product-option/product-option.entity';
 import { ProductVariantTranslation } from '../entity/product-variant/product-variant-translation.entity';
 import { ProductVariant } from '../entity/product-variant/product-variant.entity';
 import { Product } from '../entity/product/product.entity';
-import { MockTranslationUpdaterService } from '../locale/translation-updater.mock';
-import { TranslationUpdaterService } from '../locale/translation-updater.service';
 import { MockConnection } from '../testing/connection.mock';
 
+import { MockTranslationUpdaterService } from './helpers/translation-updater.mock';
+import { TranslationUpdaterService } from './helpers/translation-updater.service';
 import { ProductVariantService } from './product-variant.service';
 
 describe('ProductVariantService', () => {

+ 6 - 5
server/src/service/product-variant.service.ts

@@ -6,8 +6,7 @@ import { generateAllCombinations } from 'shared/shared-utils';
 import { Connection } from 'typeorm';
 
 import { DEFAULT_LANGUAGE_CODE } from '../common/constants';
-import { createTranslatable } from '../common/create-translatable';
-import { updateTranslatable } from '../common/update-translatable';
+import { Translated } from '../common/types/locale-types';
 import { assertFound } from '../common/utils';
 import { FacetValue } from '../entity/facet-value/facet-value.entity';
 import { ProductOption } from '../entity/product-option/product-option.entity';
@@ -16,9 +15,11 @@ import { ProductVariantTranslation } from '../entity/product-variant/product-var
 import { ProductVariant } from '../entity/product-variant/product-variant.entity';
 import { Product } from '../entity/product/product.entity';
 import { I18nError } from '../i18n/i18n-error';
-import { Translated } from '../locale/locale-types';
-import { translateDeep } from '../locale/translate-entity';
-import { TranslationUpdaterService } from '../locale/translation-updater.service';
+
+import { createTranslatable } from './helpers/create-translatable';
+import { translateDeep } from './helpers/translate-entity';
+import { TranslationUpdaterService } from './helpers/translation-updater.service';
+import { updateTranslatable } from './helpers/update-translatable';
 
 @Injectable()
 export class ProductVariantService {

+ 2 - 2
server/src/service/product.service.spec.ts

@@ -5,10 +5,10 @@ import { Connection } from 'typeorm';
 import { ProductOptionGroup } from '../entity/product-option-group/product-option-group.entity';
 import { ProductTranslation } from '../entity/product/product-translation.entity';
 import { Product } from '../entity/product/product.entity';
-import { MockTranslationUpdaterService } from '../locale/translation-updater.mock';
-import { TranslationUpdaterService } from '../locale/translation-updater.service';
 import { MockConnection } from '../testing/connection.mock';
 
+import { MockTranslationUpdaterService } from './helpers/translation-updater.mock';
+import { TranslationUpdaterService } from './helpers/translation-updater.service';
 import { ProductService } from './product.service';
 
 describe('ProductService', () => {

+ 8 - 7
server/src/service/product.service.ts

@@ -4,19 +4,20 @@ import { CreateProductInput, LanguageCode, UpdateProductInput } from 'shared/gen
 import { ID, PaginatedList } from 'shared/shared-types';
 import { Connection } from 'typeorm';
 
-import { buildListQuery } from '../common/build-list-query';
-import { ListQueryOptions, NullOptionals } from '../common/common-types';
 import { DEFAULT_LANGUAGE_CODE } from '../common/constants';
-import { createTranslatable } from '../common/create-translatable';
-import { updateTranslatable } from '../common/update-translatable';
+import { ListQueryOptions, NullOptionals } from '../common/types/common-types';
+import { Translated } from '../common/types/locale-types';
 import { assertFound } from '../common/utils';
 import { ProductOptionGroup } from '../entity/product-option-group/product-option-group.entity';
 import { ProductTranslation } from '../entity/product/product-translation.entity';
 import { Product } from '../entity/product/product.entity';
 import { I18nError } from '../i18n/i18n-error';
-import { Translated } from '../locale/locale-types';
-import { translateDeep } from '../locale/translate-entity';
-import { TranslationUpdaterService } from '../locale/translation-updater.service';
+
+import { buildListQuery } from './helpers/build-list-query';
+import { createTranslatable } from './helpers/create-translatable';
+import { translateDeep } from './helpers/translate-entity';
+import { TranslationUpdaterService } from './helpers/translation-updater.service';
+import { updateTranslatable } from './helpers/update-translatable';
 
 @Injectable()
 export class ProductService {

+ 43 - 0
server/src/service/service.module.ts

@@ -0,0 +1,43 @@
+import { Module } from '@nestjs/common';
+import { TypeOrmModule } from '@nestjs/typeorm';
+
+import { ConfigModule } from '../config/config.module';
+import { getConfig } from '../config/vendure-config';
+
+import { AdministratorService } from './administrator.service';
+import { AuthService } from './auth.service';
+import { CustomerService } from './customer.service';
+import { FacetValueService } from './facet-value.service';
+import { FacetService } from './facet.service';
+import { TranslationUpdaterService } from './helpers/translation-updater.service';
+import { PasswordService } from './password.service';
+import { ProductOptionGroupService } from './product-option-group.service';
+import { ProductOptionService } from './product-option.service';
+import { ProductVariantService } from './product-variant.service';
+import { ProductService } from './product.service';
+
+const exportedProviders = [
+    AdministratorService,
+    AuthService,
+    CustomerService,
+    FacetService,
+    FacetValueService,
+    ProductOptionService,
+    ProductOptionGroupService,
+    ProductService,
+    ProductVariantService,
+];
+
+/**
+ * The ServiceModule is responsible for the service layer, i.e. accessing the database
+ * and implementing the main business logic of the application.
+ *
+ * The exported providers are used in the ApiModule, which is responsible for parsing requests
+ * into a format suitable for the service layer logic.
+ */
+@Module({
+    imports: [ConfigModule, TypeOrmModule.forRoot(getConfig().dbConnectionOptions)],
+    providers: [...exportedProviders, PasswordService, TranslationUpdaterService],
+    exports: exportedProviders,
+})
+export class ServiceModule {}