Просмотр исходного кода

feat(core): Expose new RuntimeVendureConfig interface

This interface more accurately represents the config object at runtime (once the default config has been merged during bootstrap).
Michael Bromley 6 лет назад
Родитель
Сommit
6ea71242a8

+ 1 - 1
docs/content/docs/plugins/_index.md

@@ -8,7 +8,7 @@ showtoc: true
 
 
 Plugins are the method by which the built-in functionality of Vendure can be extended. Plugins in Vendure allow one to:
 Plugins are the method by which the built-in functionality of Vendure can be extended. Plugins in Vendure allow one to:
 
 
-1. Modify the [VendureConfig]({{< relref "vendure-config" >}}) object.
+1. Modify the [VendureConfig]({{< ref "/docs/typescript-api/configuration" >}}#vendureconfig) object.
 2. Extend the GraphQL API, including modifying existing types and adding completely new queries and mutations.
 2. Extend the GraphQL API, including modifying existing types and adding completely new queries and mutations.
 3. Define new database entities and interact directly with the database.
 3. Define new database entities and interact directly with the database.
 4. Run code before the server bootstraps, such as starting webservers.
 4. Run code before the server bootstraps, such as starting webservers.

+ 1 - 1
docs/content/docs/typescript-api/_index.md

@@ -6,7 +6,7 @@ showtoc: false
 
 
 # Vendure TypeScript API Docs
 # Vendure TypeScript API Docs
 
 
-The Vendure TypeScript API is used when configuring the server (via the [`VendureConfig`]({{< ref "vendure-config" >}}) object) and when writing plugins that extend the functionality of Vendure core.
+The Vendure TypeScript API is used when configuring the server (via the [`VendureConfig`]({{< ref "configuration" >}}#vendureconfig) object) and when writing plugins that extend the functionality of Vendure core.
 
 
 {{% alert %}}
 {{% alert %}}
 All documentation in this section is auto-generated from the TypeScript source of the Vendure server.
 All documentation in this section is auto-generated from the TypeScript source of the Vendure server.

+ 1 - 1
packages/core/e2e/fixtures/test-plugins.ts

@@ -109,7 +109,7 @@ export class TestPluginWithProvider {}
 
 
 @VendurePlugin({
 @VendurePlugin({
     imports: [ConfigModule],
     imports: [ConfigModule],
-    configuration(config: Required<VendureConfig>): Required<VendureConfig> {
+    configuration: config => {
         // tslint:disable-next-line:no-non-null-assertion
         // tslint:disable-next-line:no-non-null-assertion
         config.defaultLanguageCode = LanguageCode.zh;
         config.defaultLanguageCode = LanguageCode.zh;
         return config;
         return config;

+ 13 - 18
packages/core/src/api/middleware/validate-custom-fields-interceptor.ts

@@ -73,24 +73,19 @@ export class ValidateCustomFieldsInterceptor implements NestInterceptor {
         if (variableValues) {
         if (variableValues) {
             const entityName = typeName.replace(/(Create|Update)(.+)Input/, '$2');
             const entityName = typeName.replace(/(Create|Update)(.+)Input/, '$2');
             const customFieldConfig = this.configService.customFields[entityName as keyof CustomFields];
             const customFieldConfig = this.configService.customFields[entityName as keyof CustomFields];
-            if (customFieldConfig) {
-                if (variableValues.customFields) {
-                    this.validateCustomFieldsObject(
-                        customFieldConfig,
-                        languageCode,
-                        variableValues.customFields,
-                    );
-                }
-                const translations = variableValues.translations;
-                if (Array.isArray(translations)) {
-                    for (const translation of translations) {
-                        if (translation.customFields) {
-                            this.validateCustomFieldsObject(
-                                customFieldConfig,
-                                languageCode,
-                                translation.customFields,
-                            );
-                        }
+
+            if (variableValues.customFields) {
+                this.validateCustomFieldsObject(customFieldConfig, languageCode, variableValues.customFields);
+            }
+            const translations = variableValues.translations;
+            if (Array.isArray(translations)) {
+                for (const translation of translations) {
+                    if (translation.customFields) {
+                        this.validateCustomFieldsObject(
+                            customFieldConfig,
+                            languageCode,
+                            translation.customFields,
+                        );
                     }
                     }
                 }
                 }
             }
             }

+ 3 - 10
packages/core/src/bootstrap.ts

@@ -9,15 +9,10 @@ import { ReadOnlyRequired } from './common/types/common-types';
 import { getConfig, setConfig } from './config/config-helpers';
 import { getConfig, setConfig } from './config/config-helpers';
 import { DefaultLogger } from './config/logger/default-logger';
 import { DefaultLogger } from './config/logger/default-logger';
 import { Logger } from './config/logger/vendure-logger';
 import { Logger } from './config/logger/vendure-logger';
-import { VendureConfig } from './config/vendure-config';
+import { RuntimeVendureConfig, VendureConfig } from './config/vendure-config';
 import { registerCustomEntityFields } from './entity/register-custom-entity-fields';
 import { registerCustomEntityFields } from './entity/register-custom-entity-fields';
 import { validateCustomFieldsConfig } from './entity/validate-custom-fields-config';
 import { validateCustomFieldsConfig } from './entity/validate-custom-fields-config';
-import {
-    getConfigurationFunction,
-    getEntitiesFromPlugins,
-    getPluginModules,
-    hasLifecycleMethod,
-} from './plugin/plugin-metadata';
+import { getConfigurationFunction, getEntitiesFromPlugins } from './plugin/plugin-metadata';
 import { logProxyMiddlewares } from './plugin/plugin-utils';
 import { logProxyMiddlewares } from './plugin/plugin-utils';
 
 
 export type VendureBootstrapFunction = (config: VendureConfig) => Promise<INestApplication>;
 export type VendureBootstrapFunction = (config: VendureConfig) => Promise<INestApplication>;
@@ -172,9 +167,7 @@ export async function preBootstrapConfig(
 /**
 /**
  * Initialize any configured plugins.
  * Initialize any configured plugins.
  */
  */
-async function runPluginConfigurations(
-    config: ReadOnlyRequired<VendureConfig>,
-): Promise<ReadOnlyRequired<VendureConfig>> {
+async function runPluginConfigurations(config: RuntimeVendureConfig): Promise<RuntimeVendureConfig> {
     for (const plugin of config.plugins) {
     for (const plugin of config.plugins) {
         const configFn = getConfigurationFunction(plugin);
         const configFn = getConfigurationFunction(plugin);
         if (typeof configFn === 'function') {
         if (typeof configFn === 'function') {

+ 2 - 2
packages/core/src/config/config-helpers.ts

@@ -4,7 +4,7 @@ import { ReadOnlyRequired } from '../common/types/common-types';
 
 
 import { defaultConfig } from './default-config';
 import { defaultConfig } from './default-config';
 import { mergeConfig } from './merge-config';
 import { mergeConfig } from './merge-config';
-import { VendureConfig } from './vendure-config';
+import { RuntimeVendureConfig, VendureConfig } from './vendure-config';
 
 
 let activeConfig = defaultConfig;
 let activeConfig = defaultConfig;
 
 
@@ -21,7 +21,7 @@ export function setConfig(userConfig: DeepPartial<VendureConfig>): void {
  * used before bootstrapping the app. In all other contexts, the {@link ConfigService}
  * used before bootstrapping the app. In all other contexts, the {@link ConfigService}
  * should be used to access config settings.
  * should be used to access config settings.
  */
  */
-export function getConfig(): ReadOnlyRequired<VendureConfig> {
+export function getConfig(): Readonly<RuntimeVendureConfig> {
     return activeConfig;
     return activeConfig;
 }
 }
 
 

+ 6 - 7
packages/core/src/config/config.service.ts

@@ -4,8 +4,6 @@ import { LanguageCode } from '@vendure/common/lib/generated-types';
 import { RequestHandler } from 'express';
 import { RequestHandler } from 'express';
 import { ConnectionOptions } from 'typeorm';
 import { ConnectionOptions } from 'typeorm';
 
 
-import { ReadOnlyRequired } from '../common/types/common-types';
-
 import { getConfig } from './config-helpers';
 import { getConfig } from './config-helpers';
 import { CustomFields } from './custom-field/custom-field-types';
 import { CustomFields } from './custom-field/custom-field-types';
 import { EntityIdStrategy } from './entity-id-strategy/entity-id-strategy';
 import { EntityIdStrategy } from './entity-id-strategy/entity-id-strategy';
@@ -17,6 +15,7 @@ import {
     OrderOptions,
     OrderOptions,
     PaymentOptions,
     PaymentOptions,
     PromotionOptions,
     PromotionOptions,
+    RuntimeVendureConfig,
     ShippingOptions,
     ShippingOptions,
     TaxOptions,
     TaxOptions,
     VendureConfig,
     VendureConfig,
@@ -25,7 +24,7 @@ import {
 
 
 @Injectable()
 @Injectable()
 export class ConfigService implements VendureConfig {
 export class ConfigService implements VendureConfig {
-    private activeConfig: ReadOnlyRequired<VendureConfig>;
+    private activeConfig: RuntimeVendureConfig;
 
 
     constructor() {
     constructor() {
         this.activeConfig = getConfig();
         this.activeConfig = getConfig();
@@ -36,7 +35,7 @@ export class ConfigService implements VendureConfig {
     }
     }
 
 
     get authOptions(): Required<AuthOptions> {
     get authOptions(): Required<AuthOptions> {
-        return this.activeConfig.authOptions as Required<AuthOptions>;
+        return this.activeConfig.authOptions;
     }
     }
 
 
     get defaultChannelToken(): string | null {
     get defaultChannelToken(): string | null {
@@ -100,10 +99,10 @@ export class ConfigService implements VendureConfig {
     }
     }
 
 
     get importExportOptions(): Required<ImportExportOptions> {
     get importExportOptions(): Required<ImportExportOptions> {
-        return this.activeConfig.importExportOptions as Required<ImportExportOptions>;
+        return this.activeConfig.importExportOptions;
     }
     }
 
 
-    get customFields(): CustomFields {
+    get customFields(): Required<CustomFields> {
         return this.activeConfig.customFields;
         return this.activeConfig.customFields;
     }
     }
 
 
@@ -120,6 +119,6 @@ export class ConfigService implements VendureConfig {
     }
     }
 
 
     get workerOptions(): WorkerOptions {
     get workerOptions(): WorkerOptions {
-        return this.activeConfig.workerOptions as Required<WorkerOptions>;
+        return this.activeConfig.workerOptions;
     }
     }
 }
 }

+ 7 - 6
packages/core/src/config/default-config.ts

@@ -2,12 +2,9 @@ import { Transport } from '@nestjs/microservices';
 import { LanguageCode } from '@vendure/common/lib/generated-types';
 import { LanguageCode } from '@vendure/common/lib/generated-types';
 import { DEFAULT_AUTH_TOKEN_HEADER_KEY } from '@vendure/common/lib/shared-constants';
 import { DEFAULT_AUTH_TOKEN_HEADER_KEY } from '@vendure/common/lib/shared-constants';
 
 
-import { ReadOnlyRequired } from '../common/types/common-types';
-
 import { DefaultAssetNamingStrategy } from './asset-naming-strategy/default-asset-naming-strategy';
 import { DefaultAssetNamingStrategy } from './asset-naming-strategy/default-asset-naming-strategy';
 import { NoAssetPreviewStrategy } from './asset-preview-strategy/no-asset-preview-strategy';
 import { NoAssetPreviewStrategy } from './asset-preview-strategy/no-asset-preview-strategy';
 import { NoAssetStorageStrategy } from './asset-storage-strategy/no-asset-storage-strategy';
 import { NoAssetStorageStrategy } from './asset-storage-strategy/no-asset-storage-strategy';
-import { CustomFields } from './custom-field/custom-field-types';
 import { AutoIncrementIdStrategy } from './entity-id-strategy/auto-increment-id-strategy';
 import { AutoIncrementIdStrategy } from './entity-id-strategy/auto-increment-id-strategy';
 import { DefaultLogger } from './logger/default-logger';
 import { DefaultLogger } from './logger/default-logger';
 import { TypeOrmLogger } from './logger/typeorm-logger';
 import { TypeOrmLogger } from './logger/typeorm-logger';
@@ -19,12 +16,16 @@ import { defaultShippingCalculator } from './shipping-method/default-shipping-ca
 import { defaultShippingEligibilityChecker } from './shipping-method/default-shipping-eligibility-checker';
 import { defaultShippingEligibilityChecker } from './shipping-method/default-shipping-eligibility-checker';
 import { DefaultTaxCalculationStrategy } from './tax/default-tax-calculation-strategy';
 import { DefaultTaxCalculationStrategy } from './tax/default-tax-calculation-strategy';
 import { DefaultTaxZoneStrategy } from './tax/default-tax-zone-strategy';
 import { DefaultTaxZoneStrategy } from './tax/default-tax-zone-strategy';
-import { VendureConfig } from './vendure-config';
+import { RuntimeVendureConfig } from './vendure-config';
 
 
 /**
 /**
+ * @description
  * The default configuration settings which are used if not explicitly overridden in the bootstrap() call.
  * The default configuration settings which are used if not explicitly overridden in the bootstrap() call.
+ *
+ * @docsCategory configuration
+ * @docsPage Configuration
  */
  */
-export const defaultConfig: ReadOnlyRequired<VendureConfig> = {
+export const defaultConfig: RuntimeVendureConfig = {
     channelTokenKey: 'vendure-token',
     channelTokenKey: 'vendure-token',
     defaultChannelToken: null,
     defaultChannelToken: null,
     defaultLanguageCode: LanguageCode.en,
     defaultLanguageCode: LanguageCode.en,
@@ -101,7 +102,7 @@ export const defaultConfig: ReadOnlyRequired<VendureConfig> = {
         ProductOptionGroup: [],
         ProductOptionGroup: [],
         ProductVariant: [],
         ProductVariant: [],
         User: [],
         User: [],
-    } as ReadOnlyRequired<CustomFields>,
+    },
     middleware: [],
     middleware: [],
     plugins: [],
     plugins: [],
 };
 };

+ 19 - 1
packages/core/src/config/vendure-config.ts

@@ -372,7 +372,8 @@ export interface WorkerOptions {
  * All possible configuration options are defined by the
  * All possible configuration options are defined by the
  * [`VendureConfig`](https://github.com/vendure-ecommerce/vendure/blob/master/server/src/config/vendure-config.ts) interface.
  * [`VendureConfig`](https://github.com/vendure-ecommerce/vendure/blob/master/server/src/config/vendure-config.ts) interface.
  *
  *
- * @docsCategory
+ * @docsCategory configuration
+ * @docsPage Configuration
  * */
  * */
 export interface VendureConfig {
 export interface VendureConfig {
     /**
     /**
@@ -523,3 +524,20 @@ export interface VendureConfig {
      */
      */
     workerOptions?: WorkerOptions;
     workerOptions?: WorkerOptions;
 }
 }
+
+/**
+ * @description
+ * This interface represents the VendureConfig object available at run-time, i.e. the user-supplied
+ * config values have been merged with the {@link defaultConfig} values.
+ *
+ * @docsCategory configuration
+ * @docsPage Configuration
+ */
+export interface RuntimeVendureConfig extends Required<VendureConfig> {
+    assetOptions: Required<AssetOptions>;
+    authOptions: Required<AuthOptions>;
+    customFields: Required<CustomFields>;
+    importExportOptions: Required<ImportExportOptions>;
+    orderOptions: Required<OrderOptions>;
+    workerOptions: Required<WorkerOptions>;
+}

+ 3 - 3
packages/core/src/plugin/vendure-plugin.ts

@@ -5,7 +5,7 @@ import { pick } from '@vendure/common/lib/pick';
 import { Type } from '@vendure/common/lib/shared-types';
 import { Type } from '@vendure/common/lib/shared-types';
 import { DocumentNode } from 'graphql';
 import { DocumentNode } from 'graphql';
 
 
-import { VendureConfig } from '../config/vendure-config';
+import { RuntimeVendureConfig } from '../config/vendure-config';
 
 
 import { PLUGIN_METADATA } from './plugin-metadata';
 import { PLUGIN_METADATA } from './plugin-metadata';
 
 
@@ -87,8 +87,8 @@ export interface APIExtensionDefinition {
  * @docsPage VendurePluginMetadata
  * @docsPage VendurePluginMetadata
  */
  */
 export type PluginConfigurationFn = (
 export type PluginConfigurationFn = (
-    config: Required<VendureConfig>,
-) => Required<VendureConfig> | Promise<Required<VendureConfig>>;
+    config: RuntimeVendureConfig,
+) => RuntimeVendureConfig | Promise<RuntimeVendureConfig>;
 
 
 /**
 /**
  * @description
  * @description