feat: Adding support for new FieldMetadataType with Postgres enums (#2674)
* feat: add enum type (RATING, SELECT, MULTI_SELECT) feat: wip enum type feat: try to alter enum feat: wip enum feat: wip enum feat: schema-builder can handle enum fix: return default value in field metadata response * fix: create fieldMedata with options * fix: lint issues * fix: rename abstract factory * feat: drop `PHONE` and `EMAIL` fieldMetadata types * feat: drop `VARCHAR` fieldMetadata type and rely on `TEXT` * Revert "feat: drop `PHONE` and `EMAIL` fieldMetadata types" This reverts commit 3857539f7d42f17c81f6ab92a6db950140b3c8e5.
This commit is contained in:
-70
@@ -1,70 +0,0 @@
|
||||
import { FieldMetadataType } from 'src/metadata/field-metadata/field-metadata.entity';
|
||||
import { convertFieldMetadataToColumnActions } from 'src/metadata/field-metadata/utils/convert-field-metadata-to-column-action.util';
|
||||
|
||||
describe('convertFieldMetadataToColumnActions', () => {
|
||||
it('should convert TEXT field metadata to column actions', () => {
|
||||
const fieldMetadata = {
|
||||
type: FieldMetadataType.TEXT,
|
||||
targetColumnMap: { value: 'name' },
|
||||
defaultValue: { value: 'default text' },
|
||||
} as any;
|
||||
const columnActions = convertFieldMetadataToColumnActions(fieldMetadata);
|
||||
expect(columnActions).toEqual([
|
||||
{
|
||||
action: 'CREATE',
|
||||
columnName: 'name',
|
||||
columnType: 'text',
|
||||
defaultValue: "'default text'",
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it('should convert LINK field metadata to column actions', () => {
|
||||
const fieldMetadata = {
|
||||
type: FieldMetadataType.LINK,
|
||||
targetColumnMap: { label: 'linkLabel', url: 'linkURL' },
|
||||
defaultValue: { label: 'http://example.com', url: 'Example' },
|
||||
} as any;
|
||||
const columnActions = convertFieldMetadataToColumnActions(fieldMetadata);
|
||||
expect(columnActions).toEqual([
|
||||
{
|
||||
action: 'CREATE',
|
||||
columnName: 'linkLabel',
|
||||
columnType: 'varchar',
|
||||
defaultValue: "'http://example.com'",
|
||||
},
|
||||
{
|
||||
action: 'CREATE',
|
||||
columnName: 'linkURL',
|
||||
columnType: 'varchar',
|
||||
defaultValue: "'Example'",
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it('should convert CURRENCY field metadata to column actions', () => {
|
||||
const fieldMetadata = {
|
||||
type: FieldMetadataType.CURRENCY,
|
||||
targetColumnMap: {
|
||||
amountMicros: 'moneyAmountMicros',
|
||||
currencyCode: 'moneyCurrencyCode',
|
||||
},
|
||||
defaultValue: { amountMicros: 100 * 1_000_000, currencyCode: 'USD' },
|
||||
} as any;
|
||||
const columnActions = convertFieldMetadataToColumnActions(fieldMetadata);
|
||||
expect(columnActions).toEqual([
|
||||
{
|
||||
action: 'CREATE',
|
||||
columnName: 'moneyAmountMicros',
|
||||
columnType: 'numeric',
|
||||
defaultValue: 100 * 1_000_000,
|
||||
},
|
||||
{
|
||||
action: 'CREATE',
|
||||
columnName: 'moneyCurrencyCode',
|
||||
columnType: 'varchar',
|
||||
defaultValue: "'USD'",
|
||||
},
|
||||
]);
|
||||
});
|
||||
});
|
||||
-175
@@ -1,175 +0,0 @@
|
||||
import { FieldMetadataDefaultValue } from 'src/metadata/field-metadata/interfaces/field-metadata-default-value.interface';
|
||||
|
||||
import {
|
||||
FieldMetadataEntity,
|
||||
FieldMetadataType,
|
||||
} from 'src/metadata/field-metadata/field-metadata.entity';
|
||||
import {
|
||||
WorkspaceMigrationColumnAction,
|
||||
WorkspaceMigrationColumnActionType,
|
||||
} from 'src/metadata/workspace-migration/workspace-migration.entity';
|
||||
import { serializeDefaultValue } from 'src/metadata/field-metadata/utils/serialize-default-value';
|
||||
|
||||
export function convertFieldMetadataToColumnActions(
|
||||
fieldMetadata: FieldMetadataEntity,
|
||||
): WorkspaceMigrationColumnAction[] {
|
||||
switch (fieldMetadata.type) {
|
||||
case FieldMetadataType.UUID: {
|
||||
const defaultValue =
|
||||
fieldMetadata.defaultValue as FieldMetadataDefaultValue<FieldMetadataType.UUID>;
|
||||
|
||||
return [
|
||||
{
|
||||
action: WorkspaceMigrationColumnActionType.CREATE,
|
||||
columnName: fieldMetadata.targetColumnMap.value,
|
||||
columnType: 'uuid',
|
||||
defaultValue: serializeDefaultValue(defaultValue?.value),
|
||||
},
|
||||
];
|
||||
}
|
||||
case FieldMetadataType.TEXT: {
|
||||
const defaultValue =
|
||||
fieldMetadata.defaultValue as FieldMetadataDefaultValue<FieldMetadataType.TEXT>;
|
||||
|
||||
return [
|
||||
{
|
||||
action: WorkspaceMigrationColumnActionType.CREATE,
|
||||
columnName: fieldMetadata.targetColumnMap.value,
|
||||
columnType: 'text',
|
||||
defaultValue: serializeDefaultValue(defaultValue?.value ?? ''),
|
||||
},
|
||||
];
|
||||
}
|
||||
case FieldMetadataType.PHONE:
|
||||
case FieldMetadataType.EMAIL: {
|
||||
const defaultValue =
|
||||
fieldMetadata.defaultValue as FieldMetadataDefaultValue<
|
||||
FieldMetadataType.PHONE | FieldMetadataType.EMAIL
|
||||
>;
|
||||
|
||||
return [
|
||||
{
|
||||
action: WorkspaceMigrationColumnActionType.CREATE,
|
||||
columnName: fieldMetadata.targetColumnMap.value,
|
||||
columnType: 'varchar',
|
||||
defaultValue: serializeDefaultValue(defaultValue?.value ?? ''),
|
||||
},
|
||||
];
|
||||
}
|
||||
case FieldMetadataType.NUMERIC: {
|
||||
const defaultValue =
|
||||
fieldMetadata.defaultValue as FieldMetadataDefaultValue<FieldMetadataType.NUMERIC>;
|
||||
|
||||
return [
|
||||
{
|
||||
action: WorkspaceMigrationColumnActionType.CREATE,
|
||||
columnName: fieldMetadata.targetColumnMap.value,
|
||||
columnType: 'numeric',
|
||||
defaultValue: serializeDefaultValue(defaultValue?.value),
|
||||
},
|
||||
];
|
||||
}
|
||||
case FieldMetadataType.NUMBER:
|
||||
case FieldMetadataType.PROBABILITY: {
|
||||
const defaultValue =
|
||||
fieldMetadata.defaultValue as FieldMetadataDefaultValue<
|
||||
FieldMetadataType.NUMBER | FieldMetadataType.PROBABILITY
|
||||
>;
|
||||
|
||||
return [
|
||||
{
|
||||
action: WorkspaceMigrationColumnActionType.CREATE,
|
||||
columnName: fieldMetadata.targetColumnMap.value,
|
||||
columnType: 'float',
|
||||
defaultValue: serializeDefaultValue(defaultValue?.value),
|
||||
},
|
||||
];
|
||||
}
|
||||
case FieldMetadataType.BOOLEAN: {
|
||||
const defaultValue =
|
||||
fieldMetadata.defaultValue as FieldMetadataDefaultValue<FieldMetadataType.BOOLEAN>;
|
||||
|
||||
return [
|
||||
{
|
||||
action: WorkspaceMigrationColumnActionType.CREATE,
|
||||
columnName: fieldMetadata.targetColumnMap.value,
|
||||
columnType: 'boolean',
|
||||
defaultValue: serializeDefaultValue(defaultValue?.value),
|
||||
},
|
||||
];
|
||||
}
|
||||
case FieldMetadataType.DATE_TIME: {
|
||||
const defaultValue =
|
||||
fieldMetadata.defaultValue as FieldMetadataDefaultValue<FieldMetadataType.DATE_TIME>;
|
||||
|
||||
return [
|
||||
{
|
||||
action: WorkspaceMigrationColumnActionType.CREATE,
|
||||
columnName: fieldMetadata.targetColumnMap.value,
|
||||
columnType: 'timestamp',
|
||||
defaultValue: serializeDefaultValue(defaultValue?.value),
|
||||
},
|
||||
];
|
||||
}
|
||||
case FieldMetadataType.LINK: {
|
||||
const defaultValue =
|
||||
fieldMetadata.defaultValue as FieldMetadataDefaultValue<FieldMetadataType.LINK>;
|
||||
|
||||
return [
|
||||
{
|
||||
action: WorkspaceMigrationColumnActionType.CREATE,
|
||||
columnName: fieldMetadata.targetColumnMap.label,
|
||||
columnType: 'varchar',
|
||||
defaultValue: serializeDefaultValue(defaultValue?.label ?? ''),
|
||||
},
|
||||
{
|
||||
action: WorkspaceMigrationColumnActionType.CREATE,
|
||||
columnName: fieldMetadata.targetColumnMap.url,
|
||||
columnType: 'varchar',
|
||||
defaultValue: serializeDefaultValue(defaultValue?.url ?? ''),
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
case FieldMetadataType.CURRENCY: {
|
||||
const defaultValue =
|
||||
fieldMetadata.defaultValue as FieldMetadataDefaultValue<FieldMetadataType.CURRENCY>;
|
||||
|
||||
return [
|
||||
{
|
||||
action: WorkspaceMigrationColumnActionType.CREATE,
|
||||
columnName: fieldMetadata.targetColumnMap.amountMicros,
|
||||
columnType: 'numeric',
|
||||
defaultValue: serializeDefaultValue(defaultValue?.amountMicros),
|
||||
},
|
||||
{
|
||||
action: WorkspaceMigrationColumnActionType.CREATE,
|
||||
columnName: fieldMetadata.targetColumnMap.currencyCode,
|
||||
columnType: 'varchar',
|
||||
defaultValue: serializeDefaultValue(defaultValue?.currencyCode ?? ''),
|
||||
},
|
||||
];
|
||||
}
|
||||
case FieldMetadataType.FULL_NAME: {
|
||||
const defaultValue =
|
||||
fieldMetadata.defaultValue as FieldMetadataDefaultValue<FieldMetadataType.FULL_NAME>;
|
||||
|
||||
return [
|
||||
{
|
||||
action: WorkspaceMigrationColumnActionType.CREATE,
|
||||
columnName: fieldMetadata.targetColumnMap.firstName,
|
||||
columnType: 'varchar',
|
||||
defaultValue: serializeDefaultValue(defaultValue?.firstName ?? ''),
|
||||
},
|
||||
{
|
||||
action: WorkspaceMigrationColumnActionType.CREATE,
|
||||
columnName: fieldMetadata.targetColumnMap.lastName,
|
||||
columnType: 'varchar',
|
||||
defaultValue: serializeDefaultValue(defaultValue?.lastName ?? ''),
|
||||
},
|
||||
];
|
||||
}
|
||||
default:
|
||||
throw new Error(`Unknown type ${fieldMetadata.type}`);
|
||||
}
|
||||
}
|
||||
@@ -28,6 +28,9 @@ export function generateTargetColumnMap(
|
||||
case FieldMetadataType.PROBABILITY:
|
||||
case FieldMetadataType.BOOLEAN:
|
||||
case FieldMetadataType.DATE_TIME:
|
||||
case FieldMetadataType.RATING:
|
||||
case FieldMetadataType.SELECT:
|
||||
case FieldMetadataType.MULTI_SELECT:
|
||||
return {
|
||||
value: columnName,
|
||||
};
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
import { FieldMetadataType } from 'src/metadata/field-metadata/field-metadata.entity';
|
||||
|
||||
export const isCompositeFieldMetadataType = (
|
||||
type: FieldMetadataType,
|
||||
): type is
|
||||
| FieldMetadataType.LINK
|
||||
| FieldMetadataType.CURRENCY
|
||||
| FieldMetadataType.FULL_NAME => {
|
||||
return (
|
||||
type === FieldMetadataType.LINK ||
|
||||
type === FieldMetadataType.CURRENCY ||
|
||||
type === FieldMetadataType.FULL_NAME
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,14 @@
|
||||
import { FieldMetadataType } from 'src/metadata/field-metadata/field-metadata.entity';
|
||||
|
||||
export const isEnumFieldMetadataType = (
|
||||
type: FieldMetadataType,
|
||||
): type is
|
||||
| FieldMetadataType.RATING
|
||||
| FieldMetadataType.SELECT
|
||||
| FieldMetadataType.MULTI_SELECT => {
|
||||
return (
|
||||
type === FieldMetadataType.RATING ||
|
||||
type === FieldMetadataType.SELECT ||
|
||||
type === FieldMetadataType.MULTI_SELECT
|
||||
);
|
||||
};
|
||||
@@ -10,7 +10,11 @@ export const serializeDefaultValue = (
|
||||
}
|
||||
|
||||
// Dynamic default values
|
||||
if (typeof defaultValue === 'object' && 'type' in defaultValue) {
|
||||
if (
|
||||
!Array.isArray(defaultValue) &&
|
||||
typeof defaultValue === 'object' &&
|
||||
'type' in defaultValue
|
||||
) {
|
||||
switch (defaultValue.type) {
|
||||
case 'uuid':
|
||||
return 'public.uuid_generate_v4()';
|
||||
@@ -38,6 +42,10 @@ export const serializeDefaultValue = (
|
||||
return `'${defaultValue.toISOString()}'`;
|
||||
}
|
||||
|
||||
if (Array.isArray(defaultValue)) {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
if (typeof defaultValue === 'object') {
|
||||
return `'${JSON.stringify(defaultValue)}'`;
|
||||
}
|
||||
|
||||
+8
-1
@@ -25,7 +25,8 @@ export const validateDefaultValueBasedOnType = (
|
||||
case FieldMetadataType.TEXT:
|
||||
case FieldMetadataType.PHONE:
|
||||
case FieldMetadataType.EMAIL:
|
||||
case FieldMetadataType.ENUM:
|
||||
case FieldMetadataType.RATING:
|
||||
case FieldMetadataType.SELECT:
|
||||
case FieldMetadataType.NUMERIC:
|
||||
return (
|
||||
typeof defaultValue === 'object' &&
|
||||
@@ -82,6 +83,12 @@ export const validateDefaultValueBasedOnType = (
|
||||
typeof defaultValue.lastName === 'string'
|
||||
);
|
||||
|
||||
case FieldMetadataType.MULTI_SELECT:
|
||||
return (
|
||||
Array.isArray(defaultValue) &&
|
||||
defaultValue.every((value) => typeof value === 'string')
|
||||
);
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user