diff --git a/packages/core/e2e/custom-fields.e2e-spec.ts b/packages/core/e2e/custom-fields.e2e-spec.ts index 129aa78a2d..8de1a17e44 100644 --- a/packages/core/e2e/custom-fields.e2e-spec.ts +++ b/packages/core/e2e/custom-fields.e2e-spec.ts @@ -5,7 +5,7 @@ import gql from 'graphql-tag'; import path from 'path'; import { initialData } from '../../../e2e-common/e2e-initial-data'; -import { testConfig, TEST_SETUP_TIMEOUT_MS } from '../../../e2e-common/test-config'; +import { TEST_SETUP_TIMEOUT_MS, testConfig } from '../../../e2e-common/test-config'; import { assertThrowsWithMessage } from './utils/assert-throws-with-message'; import { fixPostgresTimezone } from './utils/fix-pg-timezone'; @@ -276,18 +276,22 @@ describe('Custom fields', () => { } `); + const customFields = { + stringWithDefault: 'hello', + localeStringWithDefault: 'hola', + intWithDefault: 5, + floatWithDefault: 5.5, + booleanWithDefault: true, + dateTimeWithDefault: '2019-04-30T12:59:16.415Z', + // MySQL does not support defaults on TEXT fields, which is what "simple-json" uses + // internally. See https://stackoverflow.com/q/3466872/772859 + stringListWithDefault: testConfig.dbConnectionOptions.type === 'mysql' ? null : ['cat'], + }; + expect(product).toEqual({ id: 'T_1', name: 'Laptop', - customFields: { - stringWithDefault: 'hello', - localeStringWithDefault: 'hola', - intWithDefault: 5, - floatWithDefault: 5.5, - booleanWithDefault: true, - dateTimeWithDefault: '2019-04-30T12:59:16.415Z', - stringListWithDefault: ['cat'], - }, + customFields, }); }); diff --git a/packages/core/src/entity/register-custom-entity-fields.ts b/packages/core/src/entity/register-custom-entity-fields.ts index 1ea7260fc6..14010e9b3b 100644 --- a/packages/core/src/entity/register-custom-entity-fields.ts +++ b/packages/core/src/entity/register-custom-entity-fields.ts @@ -3,7 +3,7 @@ import { assertNever } from '@vendure/common/lib/shared-utils'; import { Column, ColumnOptions, ColumnType, ConnectionOptions } from 'typeorm'; import { DateUtils } from 'typeorm/util/DateUtils'; -import { CustomFields } from '../config/custom-field/custom-field-types'; +import { CustomFieldConfig, CustomFields } from '../config/custom-field/custom-field-types'; import { Logger } from '../config/logger/vendure-logger'; import { VendureConfig } from '../config/vendure-config'; @@ -54,12 +54,7 @@ function registerCustomFieldsForEntity( const registerColumn = () => { const options: ColumnOptions = { type: list ? 'simple-json' : getColumnType(dbEngine, type), - default: - list && defaultValue - ? JSON.stringify(defaultValue) - : type === 'datetime' - ? formatDefaultDatetime(dbEngine, defaultValue) - : defaultValue, + default: getDefault(customField, dbEngine), name, nullable: nullable === false ? false : true, }; @@ -151,6 +146,22 @@ function getColumnType(dbEngine: ConnectionOptions['type'], type: CustomFieldTyp return 'varchar'; } +function getDefault(customField: CustomFieldConfig, dbEngine: ConnectionOptions['type']) { + const { name, type, list, defaultValue, nullable } = customField; + if (list && defaultValue) { + if (dbEngine === 'mysql') { + // MySQL does not support defaults on TEXT fields, which is what "simple-json" uses + // internally. See https://stackoverflow.com/q/3466872/772859 + Logger.warn( + `MySQL does not support default values on list fields (${name}). No default will be set.`, + ); + return undefined; + } + return JSON.stringify(defaultValue); + } + return type === 'datetime' ? formatDefaultDatetime(dbEngine, defaultValue) : defaultValue; +} + /** * Dynamically registers any custom fields with TypeORM. This function should be run at the bootstrap * stage of the app lifecycle, before the AppModule is initialized.