Browse Source

feat(server): Create user config infrastructure

Michael Bromley 7 years ago
parent
commit
f2e5c34cee

+ 8 - 14
server/src/app.module.ts

@@ -11,35 +11,29 @@ 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 { getConfig } from './config/vendure-config';
 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 { IdCodecService } from './service/id-codec.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';
 
+const connectionOptions = getConfig().connectionOptions;
+
 @Module({
-    imports: [
-        GraphQLModule,
-        TypeOrmModule.forRoot({
-            type: 'mysql',
-            entities: ['./**/entity/**/*.entity.ts'],
-            synchronize: true,
-            logging: true,
-            host: '192.168.99.100',
-            port: 3306,
-            username: 'root',
-            password: '',
-            database: 'test',
-        }),
-    ],
+    imports: [GraphQLModule, TypeOrmModule.forRoot(connectionOptions)],
     controllers: [AuthController, CustomerController],
     providers: [
         AdministratorResolver,
         AdministratorService,
         AuthService,
+        ConfigService,
         JwtStrategy,
+        IdCodecService,
         PasswordService,
         CustomerService,
         CustomerResolver,

+ 15 - 0
server/src/config/auto-increment-id-strategy.ts

@@ -0,0 +1,15 @@
+import { IntegerIdStrategy } from './entity-id-strategy';
+
+/**
+ * An id strategy which simply uses auto-increment integers as primary keys
+ * for all entities.
+ */
+export class AutoIncrementIdStrategy implements IntegerIdStrategy {
+    primaryKeyType: 'increment';
+    decodeId(id: string): number {
+        return +id;
+    }
+    encodeId(primaryKey: number): string {
+        return primaryKey.toString();
+    }
+}

+ 21 - 0
server/src/config/entity-id-strategy.ts

@@ -0,0 +1,21 @@
+import { ID } from '../common/common-types';
+
+export type PrimaryKeyType = 'increment' | 'uuid';
+
+export interface EntityIdStrategy<T extends ID = ID> {
+    primaryKeyType: PrimaryKeyType;
+    encodeId: (primaryKey: T) => string;
+    decodeId: (id: string) => T;
+}
+
+export interface IntegerIdStrategy extends EntityIdStrategy<number> {
+    primaryKeyType: 'increment';
+    encodeId: (primaryKey: number) => string;
+    decodeId: (id: string) => number;
+}
+
+export interface StringIdStrategy extends EntityIdStrategy<string> {
+    primaryKeyType: 'uuid';
+    encodeId: (primaryKey: string) => string;
+    decodeId: (id: string) => string;
+}

+ 15 - 0
server/src/config/uuid-id-strategy.ts

@@ -0,0 +1,15 @@
+import { StringIdStrategy } from './entity-id-strategy';
+
+/**
+ * An id strategy which simply uses auto-increment integers as primary keys
+ * for all entities.
+ */
+export class UuidIdStrategy implements StringIdStrategy {
+    primaryKeyType: 'uuid';
+    decodeId(id: string): string {
+        return id;
+    }
+    encodeId(primaryKey: string): string {
+        return primaryKey;
+    }
+}

+ 32 - 0
server/src/config/vendure-config.ts

@@ -0,0 +1,32 @@
+import { ConnectionOptions } from 'typeorm';
+import { LanguageCode } from '../locale/language-code';
+import { AutoIncrementIdStrategy } from './auto-increment-id-strategy';
+import { EntityIdStrategy } from './entity-id-strategy';
+
+export interface VendureConfig {
+    defaultLanguageCode: LanguageCode;
+    entityIdStrategy: EntityIdStrategy<any>;
+    connectionOptions: ConnectionOptions;
+}
+
+const defaultConfig: VendureConfig = {
+    defaultLanguageCode: LanguageCode.EN,
+    entityIdStrategy: new AutoIncrementIdStrategy(),
+    connectionOptions: {
+        type: 'mysql',
+    },
+};
+
+let activeConfig = defaultConfig;
+
+export function setConfig(userConfig: Partial<VendureConfig>): void {
+    activeConfig = Object.assign({}, defaultConfig, userConfig);
+}
+
+export function getConfig(): VendureConfig {
+    return activeConfig;
+}
+
+export function getEntityIdStrategy(): EntityIdStrategy {
+    return getConfig().entityIdStrategy;
+}

+ 19 - 0
server/src/service/config.service.mock.ts

@@ -0,0 +1,19 @@
+import { EntityIdStrategy, PrimaryKeyType } from '../config/entity-id-strategy';
+import { VendureEntity } from '../entity/base/base.entity';
+import { MockClass } from '../testing/testing-types';
+import { ConfigService } from './config.service';
+
+export class MockConfigService implements MockClass<ConfigService> {
+    defaultLanguageCode: jest.Mock<any>;
+    entityIdStrategy = new MockIdStrategy();
+    connectionOptions = {};
+}
+
+export const ENCODED = 'encoded';
+export const DECODED = 'decoded';
+
+export class MockIdStrategy implements EntityIdStrategy {
+    primaryKeyType = 'integer' as any;
+    encodeId = jest.fn().mockReturnValue(ENCODED);
+    decodeId = jest.fn().mockReturnValue(DECODED);
+}

+ 26 - 0
server/src/service/config.service.ts

@@ -0,0 +1,26 @@
+import { Injectable } from '@nestjs/common';
+import { ConnectionOptions } from 'typeorm';
+import { EntityIdStrategy } from '../config/entity-id-strategy';
+import { getConfig, VendureConfig } from '../config/vendure-config';
+import { LanguageCode } from '../locale/language-code';
+
+@Injectable()
+export class ConfigService implements VendureConfig {
+    get defaultLanguageCode(): LanguageCode {
+        return this.activeConfig.defaultLanguageCode;
+    }
+
+    get entityIdStrategy(): EntityIdStrategy {
+        return this.activeConfig.entityIdStrategy;
+    }
+
+    get connectionOptions(): ConnectionOptions {
+        return this.activeConfig.connectionOptions;
+    }
+
+    private activeConfig: VendureConfig;
+
+    constructor() {
+        this.activeConfig = getConfig();
+    }
+}