diff --git a/docs/content/docs/plugins/_index.md b/docs/content/docs/plugins/_index.md index 0b809849b1..af5594c4a3 100644 --- a/docs/content/docs/plugins/_index.md +++ b/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: -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. 3. Define new database entities and interact directly with the database. 4. Run code before the server bootstraps, such as starting webservers. diff --git a/docs/content/docs/typescript-api/_index.md b/docs/content/docs/typescript-api/_index.md index 1bfaf1d8bb..444e8ff3cd 100644 --- a/docs/content/docs/typescript-api/_index.md +++ b/docs/content/docs/typescript-api/_index.md @@ -6,7 +6,7 @@ showtoc: false # 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 %}} All documentation in this section is auto-generated from the TypeScript source of the Vendure server. diff --git a/packages/core/e2e/fixtures/test-plugins.ts b/packages/core/e2e/fixtures/test-plugins.ts index 83d0f6e28f..97984340f2 100644 --- a/packages/core/e2e/fixtures/test-plugins.ts +++ b/packages/core/e2e/fixtures/test-plugins.ts @@ -109,7 +109,7 @@ export class TestPluginWithProvider {} @VendurePlugin({ imports: [ConfigModule], - configuration(config: Required): Required { + configuration: config => { // tslint:disable-next-line:no-non-null-assertion config.defaultLanguageCode = LanguageCode.zh; return config; diff --git a/packages/core/src/api/middleware/validate-custom-fields-interceptor.ts b/packages/core/src/api/middleware/validate-custom-fields-interceptor.ts index 3d83e809e5..79c264f982 100644 --- a/packages/core/src/api/middleware/validate-custom-fields-interceptor.ts +++ b/packages/core/src/api/middleware/validate-custom-fields-interceptor.ts @@ -73,24 +73,19 @@ export class ValidateCustomFieldsInterceptor implements NestInterceptor { if (variableValues) { const entityName = typeName.replace(/(Create|Update)(.+)Input/, '$2'); 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, + ); } } } diff --git a/packages/core/src/bootstrap.ts b/packages/core/src/bootstrap.ts index d258686bcc..3160c4669e 100644 --- a/packages/core/src/bootstrap.ts +++ b/packages/core/src/bootstrap.ts @@ -9,15 +9,10 @@ import { ReadOnlyRequired } from './common/types/common-types'; import { getConfig, setConfig } from './config/config-helpers'; import { DefaultLogger } from './config/logger/default-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 { 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'; export type VendureBootstrapFunction = (config: VendureConfig) => Promise; @@ -172,9 +167,7 @@ export async function preBootstrapConfig( /** * Initialize any configured plugins. */ -async function runPluginConfigurations( - config: ReadOnlyRequired, -): Promise> { +async function runPluginConfigurations(config: RuntimeVendureConfig): Promise { for (const plugin of config.plugins) { const configFn = getConfigurationFunction(plugin); if (typeof configFn === 'function') { diff --git a/packages/core/src/config/config-helpers.ts b/packages/core/src/config/config-helpers.ts index 9b365959cd..9959af99d9 100644 --- a/packages/core/src/config/config-helpers.ts +++ b/packages/core/src/config/config-helpers.ts @@ -4,7 +4,7 @@ import { ReadOnlyRequired } from '../common/types/common-types'; import { defaultConfig } from './default-config'; import { mergeConfig } from './merge-config'; -import { VendureConfig } from './vendure-config'; +import { RuntimeVendureConfig, VendureConfig } from './vendure-config'; let activeConfig = defaultConfig; @@ -21,7 +21,7 @@ export function setConfig(userConfig: DeepPartial): void { * used before bootstrapping the app. In all other contexts, the {@link ConfigService} * should be used to access config settings. */ -export function getConfig(): ReadOnlyRequired { +export function getConfig(): Readonly { return activeConfig; } diff --git a/packages/core/src/config/config.service.ts b/packages/core/src/config/config.service.ts index 696a8fbd23..d852dd1344 100644 --- a/packages/core/src/config/config.service.ts +++ b/packages/core/src/config/config.service.ts @@ -4,8 +4,6 @@ import { LanguageCode } from '@vendure/common/lib/generated-types'; import { RequestHandler } from 'express'; import { ConnectionOptions } from 'typeorm'; -import { ReadOnlyRequired } from '../common/types/common-types'; - import { getConfig } from './config-helpers'; import { CustomFields } from './custom-field/custom-field-types'; import { EntityIdStrategy } from './entity-id-strategy/entity-id-strategy'; @@ -17,6 +15,7 @@ import { OrderOptions, PaymentOptions, PromotionOptions, + RuntimeVendureConfig, ShippingOptions, TaxOptions, VendureConfig, @@ -25,7 +24,7 @@ import { @Injectable() export class ConfigService implements VendureConfig { - private activeConfig: ReadOnlyRequired; + private activeConfig: RuntimeVendureConfig; constructor() { this.activeConfig = getConfig(); @@ -36,7 +35,7 @@ export class ConfigService implements VendureConfig { } get authOptions(): Required { - return this.activeConfig.authOptions as Required; + return this.activeConfig.authOptions; } get defaultChannelToken(): string | null { @@ -100,10 +99,10 @@ export class ConfigService implements VendureConfig { } get importExportOptions(): Required { - return this.activeConfig.importExportOptions as Required; + return this.activeConfig.importExportOptions; } - get customFields(): CustomFields { + get customFields(): Required { return this.activeConfig.customFields; } @@ -120,6 +119,6 @@ export class ConfigService implements VendureConfig { } get workerOptions(): WorkerOptions { - return this.activeConfig.workerOptions as Required; + return this.activeConfig.workerOptions; } } diff --git a/packages/core/src/config/default-config.ts b/packages/core/src/config/default-config.ts index 74455d81c5..dead8cdfd0 100644 --- a/packages/core/src/config/default-config.ts +++ b/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 { 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 { NoAssetPreviewStrategy } from './asset-preview-strategy/no-asset-preview-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 { DefaultLogger } from './logger/default-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 { DefaultTaxCalculationStrategy } from './tax/default-tax-calculation-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. + * + * @docsCategory configuration + * @docsPage Configuration */ -export const defaultConfig: ReadOnlyRequired = { +export const defaultConfig: RuntimeVendureConfig = { channelTokenKey: 'vendure-token', defaultChannelToken: null, defaultLanguageCode: LanguageCode.en, @@ -101,7 +102,7 @@ export const defaultConfig: ReadOnlyRequired = { ProductOptionGroup: [], ProductVariant: [], User: [], - } as ReadOnlyRequired, + }, middleware: [], plugins: [], }; diff --git a/packages/core/src/config/vendure-config.ts b/packages/core/src/config/vendure-config.ts index 50015049d7..f2ff11fb55 100644 --- a/packages/core/src/config/vendure-config.ts +++ b/packages/core/src/config/vendure-config.ts @@ -372,7 +372,8 @@ export interface WorkerOptions { * All possible configuration options are defined by the * [`VendureConfig`](https://github.com/vendure-ecommerce/vendure/blob/master/server/src/config/vendure-config.ts) interface. * - * @docsCategory + * @docsCategory configuration + * @docsPage Configuration * */ export interface VendureConfig { /** @@ -523,3 +524,20 @@ export interface VendureConfig { */ 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 { + assetOptions: Required; + authOptions: Required; + customFields: Required; + importExportOptions: Required; + orderOptions: Required; + workerOptions: Required; +} diff --git a/packages/core/src/plugin/vendure-plugin.ts b/packages/core/src/plugin/vendure-plugin.ts index b20c9300dd..11a2764862 100644 --- a/packages/core/src/plugin/vendure-plugin.ts +++ b/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 { DocumentNode } from 'graphql'; -import { VendureConfig } from '../config/vendure-config'; +import { RuntimeVendureConfig } from '../config/vendure-config'; import { PLUGIN_METADATA } from './plugin-metadata'; @@ -87,8 +87,8 @@ export interface APIExtensionDefinition { * @docsPage VendurePluginMetadata */ export type PluginConfigurationFn = ( - config: Required, -) => Required | Promise>; + config: RuntimeVendureConfig, +) => RuntimeVendureConfig | Promise; /** * @description