Integration testing v2 enum field types fail and success path (#14010)

# Introduction
Migrating and improving performances of field enum integrations tests
success and failing tests cases to be using the new v2 api

## Discovered issue
When deleting an object in v1 it will leave related enums until the
object is re-created
Something not done anymore within the create in v2 but in the delete
operation
We should implem an upgrade command to remove such relicas

## Bugs
- Update/create default value multi select runner wrong sql query -> FIX
- Update default value multi select regression, we should allow option
without an id to be inserted -> FIX
- default value compare dynamic json stringify convertion or not in
compare tools for object and fields
This commit is contained in:
Paul Rastoin
2025-08-28 12:23:04 +02:00
committed by GitHub
parent 533d7fe49a
commit 59d90bedaa
72 changed files with 8236 additions and 1616 deletions
@@ -0,0 +1,23 @@
import { t } from '@lingui/core/macro';
import {
BaseGraphQLError,
ErrorCode,
} from 'src/engine/core-modules/graphql/utils/graphql-errors.util';
import { type WorkspaceMigrationBuilderExceptionV2 } from 'src/engine/workspace-manager/workspace-migration-v2/exceptions/workspace-migration-builder-exception-v2';
import { fromWorkspaceMigrationBuilderExceptionToValidationResponseError } from 'src/engine/workspace-manager/workspace-migration-v2/interceptors/utils/from-workspace-migration-builder-exception-to-validation-response-error.util';
export const workspaceMigrationBuilderExceptionV2Formatter = (
error: WorkspaceMigrationBuilderExceptionV2,
) => {
const { errors, summary } =
fromWorkspaceMigrationBuilderExceptionToValidationResponseError(error);
throw new BaseGraphQLError(error.message, ErrorCode.BAD_USER_INPUT, {
code: 'METADATA_VALIDATION_ERROR',
errors,
summary,
message: `Validation failed for ${summary.invalidObjects} object(s) and ${summary.invalidFields} field(s)`,
userFriendlyMessage: t`Validation failed for ${summary.invalidObjects} object(s) and ${summary.invalidFields} field(s)`,
});
};
@@ -1,42 +0,0 @@
import {
type CallHandler,
type ExecutionContext,
type NestInterceptor,
} from '@nestjs/common';
import { t } from '@lingui/core/macro';
import { catchError, type Observable } from 'rxjs';
import {
BaseGraphQLError,
ErrorCode,
} from 'src/engine/core-modules/graphql/utils/graphql-errors.util';
import { WorkspaceMigrationBuilderExceptionV2 } from 'src/engine/workspace-manager/workspace-migration-v2/exceptions/workspace-migration-builder-exception-v2';
import { fromWorkspaceMigrationBuilderExceptionToValidationResponseError } from 'src/engine/workspace-manager/workspace-migration-v2/interceptors/utils/from-workspace-migration-builder-exception-to-validation-response-error.util';
export class WorkspaceMigrationBuilderExceptionV2Interceptor
implements NestInterceptor
{
intercept(_: ExecutionContext, next: CallHandler): Observable<unknown> {
return next.handle().pipe(
catchError((error) => {
if (!(error instanceof WorkspaceMigrationBuilderExceptionV2)) {
throw error;
}
const { errors, summary } =
fromWorkspaceMigrationBuilderExceptionToValidationResponseError(
error,
);
throw new BaseGraphQLError(error.message, ErrorCode.BAD_USER_INPUT, {
code: 'METADATA_VALIDATION_ERROR',
errors,
summary,
message: `Validation failed for ${summary.invalidObjects} object(s) and ${summary.invalidFields} field(s)`,
userFriendlyMessage: t`Validation failed for ${summary.invalidObjects} object(s) and ${summary.invalidFields} field(s)`,
});
}),
);
}
}
@@ -68,8 +68,8 @@ export class WorkspaceMigrationV2FieldActionsBuilderService {
to: toFlatFieldMetadata,
} of updatedFlatFieldMetadatas) {
const updates = compareTwoFlatFieldMetadata({
from: fromFlatFieldMetadata,
to: toFlatFieldMetadata,
fromFlatFieldMetadata,
toFlatFieldMetadata,
});
if (updates.length === 0) {
@@ -31,7 +31,7 @@ export type CreatedDeletedUpdatedObjectMetadataInputMatrix = FromTo<
FlatObjectMetadata
> & {
buildOptions: WorkspaceMigrationV2BuilderOptions;
fromFlatObjectMetadataMaps: FlatObjectMetadataMaps; // should be renamed to from
fromFlatObjectMetadataMaps: FlatObjectMetadataMaps;
};
@Injectable()
@@ -0,0 +1,10 @@
import { type FromTo } from 'twenty-shared/types';
import { type FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
import { type FlatFieldMetadataPropertiesToCompare } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata-properties-to-compare.type';
export type FlatFieldMetadataPropertyUpdate<
T extends FlatFieldMetadataPropertiesToCompare,
> = {
property: T;
} & FromTo<FieldMetadataEntity[T]>;
@@ -1,8 +1,6 @@
import { type FromTo } from 'twenty-shared/types';
import { type FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
import { type FlatFieldMetadataPropertiesToCompare } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata-properties-to-compare.type';
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
import { type FlatFieldMetadataPropertyUpdate } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/flat-field-metadata-property-update.type';
export type CreateFieldAction = {
type: 'create_field';
@@ -16,9 +14,7 @@ export type UpdateFieldAction = {
objectMetadataId: string;
updates: Array<
{
[P in FlatFieldMetadataPropertiesToCompare]: {
property: P;
} & FromTo<FieldMetadataEntity[P]>;
[P in FlatFieldMetadataPropertiesToCompare]: FlatFieldMetadataPropertyUpdate<P>;
}[FlatFieldMetadataPropertiesToCompare]
>;
};
@@ -0,0 +1,95 @@
import { type ColumnType } from 'typeorm';
import { type FieldMetadataDefaultSerializableValue } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata-default-value.interface';
import {
FieldMetadataException,
FieldMetadataExceptionCode,
} from 'src/engine/metadata-modules/field-metadata/field-metadata.exception';
import { isFunctionDefaultValue } from 'src/engine/metadata-modules/field-metadata/utils/is-function-default-value.util';
import { serializeFunctionDefaultValue } from 'src/engine/metadata-modules/field-metadata/utils/serialize-function-default-value.util';
import { removeSqlDDLInjection } from 'src/engine/workspace-manager/workspace-migration-runner/utils/remove-sql-injection.util';
type SerializeDefaultValueV2Args = {
defaultValue?: FieldMetadataDefaultSerializableValue;
columnType?: ColumnType;
schemaName: string;
tableName: string;
columnName: string;
};
export const serializeDefaultValueV2 = ({
columnType,
defaultValue,
schemaName,
tableName,
columnName,
}: SerializeDefaultValueV2Args) => {
const safeSchemaName = removeSqlDDLInjection(schemaName);
const safeTableName = removeSqlDDLInjection(tableName);
const safeColumnName = removeSqlDDLInjection(columnName);
if (defaultValue === undefined || defaultValue === null) {
return 'NULL';
}
// Function default values
if (isFunctionDefaultValue(defaultValue)) {
const serializedTypeDefaultValue =
serializeFunctionDefaultValue(defaultValue);
if (!serializedTypeDefaultValue) {
throw new FieldMetadataException(
'Invalid default value',
FieldMetadataExceptionCode.INVALID_FIELD_INPUT,
);
}
return serializedTypeDefaultValue;
}
const castSuffix =
columnType === 'enum'
? `::${safeSchemaName}."${safeTableName}_${safeColumnName}_enum"`
: `::${columnType}`;
const sanitizeAndAddCastPrefix = (defaultValue: string) =>
`'${removeSqlDDLInjection(defaultValue)}'` + castSuffix;
switch (typeof defaultValue) {
case 'string': {
if (!defaultValue.startsWith("'") || !defaultValue.endsWith("'")) {
throw new FieldMetadataException(
`Invalid string default value "${defaultValue}" should be single quoted`,
FieldMetadataExceptionCode.INVALID_FIELD_INPUT,
);
}
return sanitizeAndAddCastPrefix(defaultValue);
}
case 'boolean':
case 'number': {
return sanitizeAndAddCastPrefix(`${defaultValue}`);
}
case 'object': {
if (defaultValue instanceof Date) {
return sanitizeAndAddCastPrefix(`'${defaultValue.toISOString()}'`);
}
if (Array.isArray(defaultValue)) {
const arrayValues = defaultValue
.map((val) => `'${removeSqlDDLInjection(val)}'`)
.join(',');
return `ARRAY[${arrayValues}]${castSuffix}[]`;
}
return sanitizeAndAddCastPrefix(`'${JSON.stringify(defaultValue)}'`); // Won't work :thinking: at all will remove every brackets and so on
}
default: {
throw new FieldMetadataException(
`Invalid default value "${defaultValue}"`,
FieldMetadataExceptionCode.INVALID_FIELD_INPUT,
);
}
}
};
@@ -63,6 +63,11 @@ export class CreateFieldActionHandlerService extends WorkspaceMigrationRunnerAct
operation: EnumOperation.CREATE,
});
const columnDefinitions = generateColumnDefinitions({
flatFieldMetadata: flatFieldMetadata,
flatObjectMetadataWithoutFields: flatObjectMetadataWithFlatFieldMaps,
});
await executeBatchEnumOperations({
enumOperations,
queryRunner,
@@ -70,11 +75,6 @@ export class CreateFieldActionHandlerService extends WorkspaceMigrationRunnerAct
workspaceSchemaManagerService: this.workspaceSchemaManagerService,
});
const columnDefinitions = generateColumnDefinitions({
flatFieldMetadata: flatFieldMetadata,
flatObjectMetadataWithoutFields: flatObjectMetadataWithFlatFieldMaps,
});
await this.workspaceSchemaManagerService.columnManager.addColumns({
queryRunner,
schemaName,
@@ -1,21 +1,15 @@
import { Injectable } from '@nestjs/common';
import { type EnumFieldMetadataType, type FromTo } from 'twenty-shared/types';
import { isDefined } from 'twenty-shared/utils';
import { type QueryRunner } from 'typeorm';
import { ColumnType, type QueryRunner } from 'typeorm';
import { type FieldMetadataDefaultValueForAnyType } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata-default-value.interface';
import { WorkspaceMigrationRunnerActionHandler } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/interfaces/workspace-migration-runner-action-handler-service.interface';
import {
type FieldMetadataComplexOption,
type FieldMetadataDefaultOption,
} from 'src/engine/metadata-modules/field-metadata/dtos/options.input';
import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
import { computeCompositeColumnName } from 'src/engine/metadata-modules/field-metadata/utils/compute-column-name.util';
import { getCompositeTypeOrThrow } from 'src/engine/metadata-modules/field-metadata/utils/get-composite-type-or-throw.util';
import { isCompositeFieldMetadataType } from 'src/engine/metadata-modules/field-metadata/utils/is-composite-field-metadata-type.util';
import { unserializeDefaultValue } from 'src/engine/metadata-modules/field-metadata/utils/unserialize-default-value';
import { FlatFieldMetadataPropertiesToCompare } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata-properties-to-compare.type';
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
import { isCompositeFlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/utils/is-composite-flat-field-metadata.util';
import { isEnumFlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/utils/is-enum-flat-field-metadata.util';
@@ -23,9 +17,13 @@ import { isRelationFlatFieldMetadata } from 'src/engine/metadata-modules/flat-fi
import { findFlatFieldMetadataInFlatObjectMetadataMapsOrThrow } from 'src/engine/metadata-modules/flat-object-metadata-maps/utils/find-flat-field-metadata-in-flat-object-metadata-maps-or-throw.util';
import { findFlatObjectMetadataWithFlatFieldMapsInFlatObjectMetadataMapsOrThrow } from 'src/engine/metadata-modules/flat-object-metadata-maps/utils/find-flat-object-metadata-with-flat-field-maps-in-flat-object-metadata-maps-or-throw.util';
import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type';
import { fromFlatObjectMetadataWithFlatFieldMapsToFlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/utils/from-flat-object-metadata-with-flat-field-maps-to-flat-object-metadatas.util';
import { fieldMetadataTypeToColumnType } from 'src/engine/metadata-modules/workspace-migration/utils/field-metadata-type-to-column-type.util';
import { WorkspaceSchemaManagerService } from 'src/engine/twenty-orm/workspace-schema-manager/workspace-schema-manager.service';
import { isRelationFieldMetadataType } from 'src/engine/utils/is-relation-field-metadata-type.util';
import { FlatFieldMetadataPropertyUpdate } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/flat-field-metadata-property-update.type';
import { type UpdateFieldAction } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/workspace-migration-field-action-v2';
import { serializeDefaultValueV2 } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/utils/serialize-default-value-v2.util';
import {
WorkspaceMigrationRunnerException,
WorkspaceMigrationRunnerExceptionCode,
@@ -40,6 +38,16 @@ import {
executeBatchEnumOperations,
} from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/utils/workspace-schema-enum-operations.util';
type UpdateFieldPropertyUpdateHandlerArgs<
T extends FlatFieldMetadataPropertiesToCompare,
> = {
queryRunner: QueryRunner;
schemaName: string;
tableName: string;
flatFieldMetadata: FlatFieldMetadata;
update: FlatFieldMetadataPropertyUpdate<T>;
};
@Injectable()
export class UpdateFieldActionHandlerService extends WorkspaceMigrationRunnerActionHandler(
'update_field',
@@ -85,12 +93,6 @@ export class UpdateFieldActionHandlerService extends WorkspaceMigrationRunnerAct
flatObjectMetadata: flatObjectMetadataWithFlatFieldMaps,
});
const flatObjectMetadata =
findFlatObjectMetadataWithFlatFieldMapsInFlatObjectMetadataMapsOrThrow({
flatObjectMetadataMaps,
objectMetadataId,
});
const currentFlatFieldMetadata =
findFlatFieldMetadataInFlatObjectMetadataMapsOrThrow({
flatObjectMetadataMaps,
@@ -102,51 +104,52 @@ export class UpdateFieldActionHandlerService extends WorkspaceMigrationRunnerAct
for (const update of updates) {
if (update.property === 'name') {
await this.handleFieldNameUpdate(
await this.handleFieldNameUpdate({
queryRunner,
schemaName,
tableName,
optimisticFlatFieldMetadata,
flatFieldMetadata: optimisticFlatFieldMetadata,
update,
);
});
optimisticFlatFieldMetadata.name = update.to;
}
if (update.property === 'defaultValue') {
await this.handleFieldDefaultValueUpdate(
await this.handleFieldDefaultValueUpdate({
queryRunner,
schemaName,
tableName,
optimisticFlatFieldMetadata,
flatFieldMetadata: optimisticFlatFieldMetadata,
update,
);
});
optimisticFlatFieldMetadata.defaultValue = update.to;
}
if (
update.property === 'options' &&
isEnumFlatFieldMetadata(optimisticFlatFieldMetadata)
) {
await this.handleFieldOptionsUpdate(
await this.handleFieldOptionsUpdate({
queryRunner,
schemaName,
tableName,
flatObjectMetadata,
optimisticFlatFieldMetadata,
flatObjectMetadata:
fromFlatObjectMetadataWithFlatFieldMapsToFlatObjectMetadata(
flatObjectMetadataWithFlatFieldMaps,
),
flatFieldMetadata: optimisticFlatFieldMetadata,
update,
);
});
optimisticFlatFieldMetadata.options = update.to ?? [];
}
}
}
private async handleFieldNameUpdate(
queryRunner: QueryRunner,
schemaName: string,
tableName: string,
flatFieldMetadata: FlatFieldMetadata,
update: {
property: 'name';
} & FromTo<string>,
) {
private async handleFieldNameUpdate({
flatFieldMetadata,
queryRunner,
schemaName,
tableName,
update,
}: UpdateFieldPropertyUpdateHandlerArgs<'name'>) {
if (isCompositeFlatFieldMetadata(flatFieldMetadata)) {
const compositeType = getCompositeTypeOrThrow(flatFieldMetadata.type);
@@ -208,15 +211,17 @@ export class UpdateFieldActionHandlerService extends WorkspaceMigrationRunnerAct
});
}
private async handleFieldDefaultValueUpdate(
queryRunner: QueryRunner,
schemaName: string,
tableName: string,
flatFieldMetadata: FlatFieldMetadata,
update: {
property: 'defaultValue';
} & FromTo<FieldMetadataDefaultValueForAnyType>,
) {
private async handleFieldDefaultValueUpdate({
flatFieldMetadata,
queryRunner,
schemaName,
tableName,
update,
}: UpdateFieldPropertyUpdateHandlerArgs<'defaultValue'>) {
const columnType = fieldMetadataTypeToColumnType(
flatFieldMetadata.type,
) as ColumnType;
if (isCompositeFieldMetadataType(flatFieldMetadata.type)) {
const compositeType = getCompositeTypeOrThrow(flatFieldMetadata.type);
@@ -233,11 +238,15 @@ export class UpdateFieldActionHandlerService extends WorkspaceMigrationRunnerAct
property,
);
// @ts-expect-error - TODO: fix this
let compositeDefaultValue = update.to?.[property.name];
let compositeDefaultValue = update.to?.[property.name]; // not valid should be serialized
const serializedNewDefaultValue = unserializeDefaultValue(
compositeDefaultValue,
);
const serializedNewDefaultValue = serializeDefaultValueV2({
columnName: compositeColumnName,
schemaName,
tableName,
columnType,
defaultValue: compositeDefaultValue,
});
await this.workspaceSchemaManagerService.columnManager.alterColumnDefault(
{
@@ -250,7 +259,13 @@ export class UpdateFieldActionHandlerService extends WorkspaceMigrationRunnerAct
);
}
} else {
const serializedNewDefaultValue = unserializeDefaultValue(update.to);
const serializedNewDefaultValue = serializeDefaultValueV2({
columnName: flatFieldMetadata.name,
schemaName,
tableName,
columnType,
defaultValue: update.to,
});
await this.workspaceSchemaManagerService.columnManager.alterColumnDefault(
{
@@ -264,18 +279,16 @@ export class UpdateFieldActionHandlerService extends WorkspaceMigrationRunnerAct
}
}
private async handleFieldOptionsUpdate(
queryRunner: QueryRunner,
schemaName: string,
tableName: string,
flatObjectMetadata: FlatObjectMetadata,
flatFieldMetadata: FlatFieldMetadata<EnumFieldMetadataType>,
update: {
property: 'options';
} & FromTo<
FieldMetadataDefaultOption[] | FieldMetadataComplexOption[] | null
>,
) {
private async handleFieldOptionsUpdate({
flatFieldMetadata,
queryRunner,
schemaName,
tableName,
update,
flatObjectMetadata,
}: UpdateFieldPropertyUpdateHandlerArgs<'options'> & {
flatObjectMetadata: FlatObjectMetadata;
}) {
const fromOptionsById = new Map(
(update.from ?? [])
.filter((opt) => isDefined(opt.id))
@@ -55,7 +55,7 @@ describe('Generate Column Definitions', () => {
isArray: false,
isNullable: true,
isUnique: false,
default: null,
default: 'NULL',
});
});
@@ -98,7 +98,7 @@ describe('Generate Column Definitions', () => {
isArray: true,
isNullable: true,
isUnique: false,
default: null,
default: 'NULL',
});
});
});
@@ -188,7 +188,7 @@ describe('Generate Column Definitions', () => {
columns.forEach((column) => {
expect(column.isNullable).toBe(true);
expect(column.isUnique).toBe(false);
expect(column.default).toBe(null);
expect(column.default).toBe('NULL');
});
});
@@ -199,7 +199,7 @@ describe('Generate Column Definitions', () => {
type: FieldMetadataType.CURRENCY,
name: 'price',
defaultValue: {
amountMicros: '100000000',
amountMicros: "'100000000'",
currencyCode: "'USD'",
},
});
@@ -220,7 +220,7 @@ describe('Generate Column Definitions', () => {
type: 'numeric',
isNullable: true,
isUnique: false,
default: '100000000',
default: "'100000000'::numeric",
});
expect(columns[1]).toMatchObject({
@@ -228,7 +228,7 @@ describe('Generate Column Definitions', () => {
type: 'text',
isNullable: true,
isUnique: false,
default: 'USD',
default: "'USD'::text",
});
});
});
@@ -254,7 +254,7 @@ describe('Generate Column Definitions', () => {
type: 'text',
isNullable: true,
isUnique: false,
default: null,
default: 'NULL',
isArray: false,
},
]);
@@ -280,7 +280,7 @@ describe('Generate Column Definitions', () => {
type: 'boolean',
isNullable: true,
isUnique: false,
default: true,
default: "'true'::boolean",
isArray: false,
},
]);
@@ -307,7 +307,7 @@ describe('Generate Column Definitions', () => {
type: 'text',
isNullable: true,
isUnique: false,
default: null,
default: 'NULL',
isArray: false,
},
]);
@@ -332,7 +332,7 @@ describe('Generate Column Definitions', () => {
type: 'uuid',
isNullable: true,
isUnique: false,
default: null,
default: 'NULL',
isArray: false,
},
]);
@@ -1,4 +1,5 @@
import { FieldMetadataType } from 'twenty-shared/types';
import { type ColumnType } from 'typeorm';
import { type CompositeProperty } from 'src/engine/metadata-modules/field-metadata/interfaces/composite-type.interface';
@@ -8,8 +9,6 @@ import {
computeCompositeColumnName,
} from 'src/engine/metadata-modules/field-metadata/utils/compute-column-name.util';
import { getCompositeTypeOrThrow } from 'src/engine/metadata-modules/field-metadata/utils/get-composite-type-or-throw.util';
import { serializeDefaultValue } from 'src/engine/metadata-modules/field-metadata/utils/serialize-default-value';
import { unserializeDefaultValue } from 'src/engine/metadata-modules/field-metadata/utils/unserialize-default-value';
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
import { isCompositeFlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/utils/is-composite-flat-field-metadata.util';
import { isFlatFieldMetadataEntityOfType } from 'src/engine/metadata-modules/flat-field-metadata/utils/is-flat-field-metadata-of-type.util';
@@ -17,6 +16,7 @@ import { type FlatObjectMetadataWithoutFields } from 'src/engine/metadata-module
import { fieldMetadataTypeToColumnType } from 'src/engine/metadata-modules/workspace-migration/utils/field-metadata-type-to-column-type.util';
import { type WorkspaceSchemaColumnDefinition } from 'src/engine/twenty-orm/workspace-schema-manager/types/workspace-schema-column-definition.type';
import { computePostgresEnumName } from 'src/engine/workspace-manager/workspace-migration-runner/utils/compute-postgres-enum-name.util';
import { serializeDefaultValueV2 } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/utils/serialize-default-value-v2.util';
import {
WorkspaceMigrationRunnerException,
WorkspaceMigrationRunnerExceptionCode,
@@ -54,10 +54,14 @@ export const generateCompositeColumnDefinition = ({
const defaultValue =
// @ts-expect-error - TODO: fix this
parentFieldMetadata.defaultValue?.[compositeProperty.name];
const unserializedDefaultValue = unserializeDefaultValue(defaultValue);
const columnType = fieldMetadataTypeToColumnType(compositeProperty.type);
const serializedDefaultValue = serializeDefaultValueV2({
columnName,
schemaName,
tableName,
columnType: columnType as ColumnType,
defaultValue,
});
const isArrayFlag =
compositeProperty.type === FieldMetadataType.ARRAY ||
@@ -72,7 +76,7 @@ export const generateCompositeColumnDefinition = ({
: columnType,
isNullable: parentFieldMetadata.isNullable || !compositeProperty.isRequired,
isUnique: parentFieldMetadata.isUnique ?? false,
default: unserializedDefaultValue,
default: serializedDefaultValue,
isArray: isArrayFlag,
};
@@ -120,23 +124,29 @@ const generateRelationColumnDefinition = (
};
};
const generateStandardColumnDefinition = (
const generateColumnDefinition = (
flatFieldMetadata: FlatFieldMetadata,
tableName: string,
schemaName: string,
): WorkspaceSchemaColumnDefinition => {
const columnName = computeColumnName(flatFieldMetadata.name);
const serializedDefaultValue = serializeDefaultValue(
flatFieldMetadata.defaultValue,
);
const columnType = fieldMetadataTypeToColumnType(flatFieldMetadata.type);
const columnType = fieldMetadataTypeToColumnType(
flatFieldMetadata.type,
) as ColumnType;
const serializedDefaultValue = serializeDefaultValueV2({
columnName,
schemaName,
tableName,
columnType,
defaultValue: flatFieldMetadata.defaultValue,
});
return {
name: columnName,
type:
columnType === 'enum'
? `"${schemaName}"."${computePostgresEnumName({ tableName, columnName })}"`
: columnType,
: (columnType as string),
isNullable: flatFieldMetadata.isNullable ?? true,
isArray:
flatFieldMetadata.type === FieldMetadataType.ARRAY ||
@@ -194,7 +204,5 @@ export const generateColumnDefinitions = ({
return relationColumn ? [relationColumn] : [];
}
return [
generateStandardColumnDefinition(flatFieldMetadata, tableName, schemaName),
];
return [generateColumnDefinition(flatFieldMetadata, tableName, schemaName)];
};