CreateFieldInput transpilation to FlatFieldMetadata, FlatFieldMetadata validation (#13493)
# Introduction Following https://github.com/twentyhq/twenty/pull/13420 What has been done: - `CreateFieldInput` transpilation to `FlatFieldMetadata` - `FlatFieldMetadata` validator service - A lof of transpilation utils from `input` to `flatObject` or `flatField` - Created dedicated v2 api metadata services - Introducing `inferDeletionFromMissingObjectFieldIndex` in the builder, to avoid diffing every object and field of the current workspace we allow only generating create/update migration operations, usefull when passing by the api metadata ## We still need to in another PR: - Implement a strong unit test coverage and critical functions and services - Finalize flat field metadata validation exception for `options` `defaultValue` `settings` and `relations` - Finalize `flatObjectMetadata` validation and v2 service refactor - Plug the new service when feature flag is enabled
This commit is contained in:
-6
@@ -9,15 +9,10 @@ type FlatObjectMetadataOverrides = Required<
|
||||
export const getFlatObjectMetadataMock = (
|
||||
overrides: FlatObjectMetadataOverrides,
|
||||
): FlatObjectMetadata => {
|
||||
const createdAt = faker.date.anytime();
|
||||
|
||||
return {
|
||||
flatFieldMetadatas: [],
|
||||
flatIndexMetadatas: [],
|
||||
createdAt,
|
||||
dataSourceId: faker.string.uuid(),
|
||||
description: 'default flat object metadata description',
|
||||
duplicateCriteria: [],
|
||||
icon: 'icon',
|
||||
id: faker.string.uuid(),
|
||||
imageIdentifierFieldMetadataId: faker.string.uuid(),
|
||||
@@ -37,7 +32,6 @@ export const getFlatObjectMetadataMock = (
|
||||
standardId: null,
|
||||
standardOverrides: null,
|
||||
targetTableName: '',
|
||||
updatedAt: createdAt,
|
||||
workspaceId: faker.string.uuid(),
|
||||
...overrides,
|
||||
};
|
||||
|
||||
+5
-1
@@ -20,7 +20,11 @@ type ObjectMetadataRelationProperties = ExtractRecordTypeOrmRelationProperties<
|
||||
|
||||
export type FlatObjectMetadata = Omit<
|
||||
ObjectMetadataEntity,
|
||||
ObjectMetadataRelationProperties
|
||||
| ObjectMetadataRelationProperties
|
||||
| 'dataSourceId'
|
||||
| 'createdAt'
|
||||
| 'updatedAt'
|
||||
| 'duplicateCriteria'
|
||||
> & {
|
||||
uniqueIdentifier: string;
|
||||
flatIndexMetadatas: FlatIndexMetadata[];
|
||||
|
||||
+1
-1
@@ -23,7 +23,7 @@ export type FlatObjectMetadataPropertiesToCompare =
|
||||
(typeof flatObjectMetadataPropertiesToCompare)[number];
|
||||
|
||||
/**
|
||||
* This comparator handles update on colliding uniqueIdentifier flatObjectdMetadata
|
||||
* This comparator handles update on colliding uniqueIdentifier flatObjectMetadata
|
||||
*/
|
||||
export const compareTwoFlatObjectMetadata = ({
|
||||
from,
|
||||
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
import { trimAndRemoveDuplicatedWhitespacesFromObjectStringProperties } from 'twenty-shared/utils';
|
||||
import { v4 } from 'uuid';
|
||||
|
||||
import { FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type';
|
||||
import { CreateObjectInput } from 'src/engine/metadata-modules/object-metadata/dtos/create-object.input';
|
||||
import {
|
||||
ObjectMetadataException,
|
||||
ObjectMetadataExceptionCode,
|
||||
} from 'src/engine/metadata-modules/object-metadata/object-metadata.exception';
|
||||
import { buildDefaultFlatFieldMetadataForCustomObject } from 'src/engine/metadata-modules/object-metadata/utils/build-default-fields-for-custom-object.util';
|
||||
|
||||
export const fromCreateObjectInputToFlatObjectMetadata = (
|
||||
rawCreateObjectInput: CreateObjectInput,
|
||||
): FlatObjectMetadata => {
|
||||
if (rawCreateObjectInput.isRemote) {
|
||||
throw new ObjectMetadataException(
|
||||
'Remote objects are not supported',
|
||||
ObjectMetadataExceptionCode.INVALID_OBJECT_INPUT,
|
||||
);
|
||||
}
|
||||
|
||||
const createObjectInput =
|
||||
trimAndRemoveDuplicatedWhitespacesFromObjectStringProperties(
|
||||
rawCreateObjectInput,
|
||||
[
|
||||
'description',
|
||||
'icon',
|
||||
'labelPlural',
|
||||
'labelSingular',
|
||||
'namePlural',
|
||||
'nameSingular',
|
||||
'shortcut',
|
||||
],
|
||||
);
|
||||
|
||||
const objectMetadataId = v4();
|
||||
const baseCustomFlatFieldMetadatas =
|
||||
buildDefaultFlatFieldMetadataForCustomObject({
|
||||
objectMetadataId,
|
||||
workspaceId: createObjectInput.workspaceId,
|
||||
});
|
||||
|
||||
return {
|
||||
description: createObjectInput.description ?? null,
|
||||
flatFieldMetadatas: Object.values(baseCustomFlatFieldMetadatas),
|
||||
flatIndexMetadatas: [],
|
||||
icon: createObjectInput.icon ?? null,
|
||||
id: objectMetadataId,
|
||||
imageIdentifierFieldMetadataId: null,
|
||||
isActive: true,
|
||||
isAuditLogged: true,
|
||||
isCustom: true,
|
||||
isLabelSyncedWithName: createObjectInput.isLabelSyncedWithName ?? false,
|
||||
isRemote: false,
|
||||
isSearchable: true,
|
||||
isSystem: false,
|
||||
labelIdentifierFieldMetadataId: baseCustomFlatFieldMetadatas.nameField.id,
|
||||
labelPlural: createObjectInput.labelPlural ?? null,
|
||||
labelSingular: createObjectInput.labelSingular ?? null,
|
||||
namePlural: createObjectInput.namePlural ?? null,
|
||||
nameSingular: createObjectInput.nameSingular ?? null,
|
||||
shortcut: createObjectInput.shortcut ?? null,
|
||||
standardId: null,
|
||||
standardOverrides: null,
|
||||
uniqueIdentifier: objectMetadataId,
|
||||
targetTableName: 'DEPRECATED',
|
||||
workspaceId: createObjectInput.workspaceId,
|
||||
};
|
||||
};
|
||||
+1
-1
@@ -8,7 +8,7 @@ import { mergeTwoFlatFieldMetadatas } from 'src/engine/metadata-modules/flat-fie
|
||||
import { FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type';
|
||||
import { ToMerge } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/to-merge.type';
|
||||
|
||||
export const mergeTwoFlatFieldObjectMetadatas = ({
|
||||
export const mergeTwoFlatObjectMetadatas = ({
|
||||
destFlatObjectMetadatas,
|
||||
toMergeFlatObjectMetadatas,
|
||||
}: ToMerge<FlatObjectMetadata[], 'object'>): FlatObjectMetadata[] => {
|
||||
|
||||
Reference in New Issue
Block a user