Ver Fonte

fix(core): Correctly generate customFields field for custom entity types

Michael Bromley há 1 ano atrás
pai
commit
58943e3f5c

+ 1 - 1
packages/core/src/api/config/configure-graphql-module.ts

@@ -1,6 +1,6 @@
 import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo';
 import { DynamicModule } from '@nestjs/common';
-import { GqlModuleOptions, GraphQLModule, GraphQLTypesLoader } from '@nestjs/graphql';
+import { GraphQLModule, GraphQLTypesLoader } from '@nestjs/graphql';
 import { notNullOrUndefined } from '@vendure/common/lib/shared-utils';
 import { buildSchema, extendSchema, GraphQLSchema, printSchema, ValidationContext } from 'graphql';
 import path from 'path';

+ 2 - 2
packages/core/src/bootstrap.ts

@@ -204,7 +204,7 @@ export async function preBootstrapConfig(
         await setConfig(userConfig);
     }
 
-    const entities = await getAllEntities(userConfig);
+    const entities = getAllEntities(userConfig);
     const { coreSubscribersMap } = await import('./entity/subscribers.js');
     await setConfig({
         dbConnectionOptions: {
@@ -276,7 +276,7 @@ async function runPluginConfigurations(config: RuntimeVendureConfig): Promise<Ru
 /**
  * Returns an array of core entities and any additional entities defined in plugins.
  */
-export async function getAllEntities(userConfig: Partial<VendureConfig>): Promise<Array<Type<any>>> {
+export function getAllEntities(userConfig: Partial<VendureConfig>): Array<Type<any>> {
     const coreEntities = Object.values(coreEntitiesMap) as Array<Type<any>>;
     const pluginEntities = getEntitiesFromPlugins(userConfig.plugins);
 

+ 33 - 2
packages/core/src/config/config.service.ts

@@ -1,6 +1,6 @@
 import { DynamicModule, Injectable, Type } from '@nestjs/common';
 import { LanguageCode } from '@vendure/common/lib/generated-types';
-import { DataSourceOptions } from 'typeorm';
+import { DataSourceOptions, getMetadataArgsStorage } from 'typeorm';
 
 import { getConfig } from './config-helpers';
 import { CustomFields } from './custom-field/custom-field-types';
@@ -27,6 +27,7 @@ import {
 @Injectable()
 export class ConfigService implements VendureConfig {
     private activeConfig: RuntimeVendureConfig;
+    private allCustomFieldsConfig: Required<CustomFields> | undefined;
 
     constructor() {
         this.activeConfig = getConfig();
@@ -97,7 +98,10 @@ export class ConfigService implements VendureConfig {
     }
 
     get customFields(): Required<CustomFields> {
-        return this.activeConfig.customFields;
+        if (!this.allCustomFieldsConfig) {
+            this.allCustomFieldsConfig = this.getCustomFieldsForAllEntities();
+        }
+        return this.allCustomFieldsConfig;
     }
 
     get plugins(): Array<DynamicModule | Type<any>> {
@@ -115,4 +119,31 @@ export class ConfigService implements VendureConfig {
     get systemOptions(): Required<SystemOptions> {
         return this.activeConfig.systemOptions;
     }
+
+    private getCustomFieldsForAllEntities(): Required<CustomFields> {
+        const definedCustomFields = this.activeConfig.customFields;
+        const metadataArgsStorage = getMetadataArgsStorage();
+        // We need to check for any entities which have a "customFields" property but which are not
+        // explicitly defined in the customFields config. This is because the customFields object
+        // only includes the built-in entities. Any custom entities which have a "customFields"
+        // must be dynamically added to the customFields object.
+        if (Array.isArray(this.dbConnectionOptions.entities)) {
+            for (const entity of this.dbConnectionOptions.entities) {
+                if (typeof entity === 'function' && !definedCustomFields[entity.name]) {
+                    const hasCustomFields = !!metadataArgsStorage
+                        .filterEmbeddeds(entity)
+                        .find(c => c.propertyName === 'customFields');
+                    const isTranslationEntity =
+                        entity.name.endsWith('Translation') &&
+                        metadataArgsStorage
+                            .filterColumns(entity)
+                            .find(c => c.propertyName === 'languageCode');
+                    if (hasCustomFields && !isTranslationEntity) {
+                        definedCustomFields[entity.name] = [];
+                    }
+                }
+            }
+        }
+        return definedCustomFields;
+    }
 }

+ 0 - 2
packages/core/src/plugin/plugin.module.ts

@@ -3,8 +3,6 @@ import { DynamicModule, Module } from '@nestjs/common';
 import { getConfig } from '../config/config-helpers';
 import { ConfigModule } from '../config/config.module';
 
-import { getModuleMetadata } from './plugin-metadata';
-
 /**
  * This module collects and re-exports all providers defined in plugins so that they can be used in other
  * modules.