Fix flatFieldMetadata transpiler to fit real cache typing (#13529)
# Introduction
The cache is not accurately typed regarding the `fieldMetadataMaps` they
do not contain relations
In this way we:
- Created dedicated transpilation tools for cache manipulation
- Avoided recursivity in transpilation tools
- Fix and finalized the createMany fields metadata service v2
- Refactor the validator to handle validation :)
## What's next:
- Implem integration tests to make things run 🙃
- migrate existing settings valdiation
- Finish the create object metadata service
- Handle update input transpilation and validation
This commit is contained in:
+118
@@ -0,0 +1,118 @@
|
||||
import { FieldMetadataType } from 'twenty-shared/types';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
|
||||
import { FlatRelationTargetFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-relation-target-field-metadata.type';
|
||||
import { fromObjectMetadataItemWithFieldMapsToFlatObjectMetadataWithoutFields } from 'src/engine/metadata-modules/flat-object-metadata/utils/from-object-metadata-item-with-field-maps-to-flat-object-metadata-without-fields.util';
|
||||
import { CachedFieldMetadataEntity } from 'src/engine/metadata-modules/types/cached-field-metadata-entity';
|
||||
import { ObjectMetadataMaps } from 'src/engine/metadata-modules/types/object-metadata-maps';
|
||||
import {
|
||||
WorkspaceMetadataCacheException,
|
||||
WorkspaceMetadataCacheExceptionCode,
|
||||
} from 'src/engine/metadata-modules/workspace-metadata-cache/exceptions/workspace-metadata-cache.exception';
|
||||
import { isCachedFieldMetadataEntityOfType } from 'src/engine/utils/is-cached-field-metadata-of-type.util';
|
||||
|
||||
const fromCachedRelationFieldMetadataEntityToFlatRelationTargetFieldMetadata = <
|
||||
T extends FieldMetadataType.RELATION | FieldMetadataType.MORPH_RELATION,
|
||||
>(
|
||||
cachedFieldMetadataEntity: CachedFieldMetadataEntity<T>,
|
||||
): FlatRelationTargetFieldMetadata => {
|
||||
return {
|
||||
...cachedFieldMetadataEntity,
|
||||
uniqueIdentifier:
|
||||
cachedFieldMetadataEntity.standardId ?? cachedFieldMetadataEntity.id,
|
||||
type: cachedFieldMetadataEntity.type,
|
||||
};
|
||||
};
|
||||
|
||||
type CachedFieldMetadataEntityAndObjectMetadataMap<
|
||||
T extends FieldMetadataType,
|
||||
> = {
|
||||
objectMetadataMaps: ObjectMetadataMaps;
|
||||
cachedFieldMetadataEntity: CachedFieldMetadataEntity<T>;
|
||||
};
|
||||
|
||||
export const fromCachedFieldMetadataEntityToFlatFieldMetadata = <
|
||||
T extends FieldMetadataType,
|
||||
>(
|
||||
{
|
||||
cachedFieldMetadataEntity,
|
||||
objectMetadataMaps,
|
||||
}: CachedFieldMetadataEntityAndObjectMetadataMap<T>,
|
||||
// This is intended to be abstract return type
|
||||
): FlatFieldMetadata => {
|
||||
if (
|
||||
isCachedFieldMetadataEntityOfType(
|
||||
cachedFieldMetadataEntity,
|
||||
FieldMetadataType.RELATION,
|
||||
) ||
|
||||
isCachedFieldMetadataEntityOfType(
|
||||
cachedFieldMetadataEntity,
|
||||
FieldMetadataType.MORPH_RELATION,
|
||||
)
|
||||
) {
|
||||
const relationTargetObjectMetadataItemWithFieldsMaps =
|
||||
objectMetadataMaps.byId[
|
||||
cachedFieldMetadataEntity.relationTargetObjectMetadataId
|
||||
];
|
||||
|
||||
if (!isDefined(relationTargetObjectMetadataItemWithFieldsMaps)) {
|
||||
throw new WorkspaceMetadataCacheException(
|
||||
'Cache object is not up to date',
|
||||
WorkspaceMetadataCacheExceptionCode.OBJECT_METADATA_MAP_NOT_FOUND,
|
||||
);
|
||||
}
|
||||
|
||||
const flatRelationTargetObjectMetadata =
|
||||
fromObjectMetadataItemWithFieldMapsToFlatObjectMetadataWithoutFields(
|
||||
relationTargetObjectMetadataItemWithFieldsMaps,
|
||||
);
|
||||
|
||||
const relationTargetCachedFieldMetadata =
|
||||
relationTargetObjectMetadataItemWithFieldsMaps.fieldsById[
|
||||
cachedFieldMetadataEntity.relationTargetFieldMetadataId
|
||||
];
|
||||
|
||||
if (!isDefined(relationTargetCachedFieldMetadata)) {
|
||||
throw new WorkspaceMetadataCacheException(
|
||||
'Cache field is not up to date',
|
||||
WorkspaceMetadataCacheExceptionCode.FIELD_METADATA_NOT_FOUND,
|
||||
);
|
||||
}
|
||||
if (
|
||||
!isCachedFieldMetadataEntityOfType(
|
||||
relationTargetCachedFieldMetadata,
|
||||
FieldMetadataType.RELATION,
|
||||
)
|
||||
) {
|
||||
throw new WorkspaceMetadataCacheException(
|
||||
'Cache field is invalid',
|
||||
WorkspaceMetadataCacheExceptionCode.FIELD_METADATA_INVALID,
|
||||
);
|
||||
}
|
||||
|
||||
const flatRelationTargetFieldMetadata =
|
||||
fromCachedRelationFieldMetadataEntityToFlatRelationTargetFieldMetadata(
|
||||
relationTargetCachedFieldMetadata,
|
||||
);
|
||||
|
||||
return {
|
||||
...cachedFieldMetadataEntity,
|
||||
uniqueIdentifier:
|
||||
cachedFieldMetadataEntity.standardId ?? cachedFieldMetadataEntity.id,
|
||||
flatRelationTargetFieldMetadata,
|
||||
flatRelationTargetObjectMetadata,
|
||||
type: cachedFieldMetadataEntity.type,
|
||||
} satisfies FlatFieldMetadata<
|
||||
FieldMetadataType.RELATION | FieldMetadataType.MORPH_RELATION
|
||||
>;
|
||||
}
|
||||
|
||||
return {
|
||||
...cachedFieldMetadataEntity,
|
||||
uniqueIdentifier:
|
||||
cachedFieldMetadataEntity.standardId ?? cachedFieldMetadataEntity.id,
|
||||
flatRelationTargetFieldMetadata: null,
|
||||
flatRelationTargetObjectMetadata: null,
|
||||
};
|
||||
};
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
import { FlatObjectMetadataWithoutFields } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type';
|
||||
import { ObjectMetadataItemWithFieldMaps } from 'src/engine/metadata-modules/types/object-metadata-item-with-field-maps';
|
||||
import { fromObjectMetadataEntityToFlatObjectMetadataWithoutFields } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/utils/from-object-metadata-entity-to-flat-object-metadata-without-fields.util';
|
||||
|
||||
export const fromObjectMetadataItemWithFieldMapsToFlatObjectMetadataWithoutFields =
|
||||
(
|
||||
objectMetadataItemWithFieldMaps: ObjectMetadataItemWithFieldMaps,
|
||||
): FlatObjectMetadataWithoutFields => {
|
||||
const {
|
||||
fieldsById: _fieldsById,
|
||||
fieldIdByJoinColumnName: _fieldIdByJoinColumnName,
|
||||
fieldIdByName: _fieldIdByName,
|
||||
indexMetadatas,
|
||||
...rest
|
||||
} = objectMetadataItemWithFieldMaps;
|
||||
|
||||
return fromObjectMetadataEntityToFlatObjectMetadataWithoutFields({
|
||||
...rest,
|
||||
fields: [],
|
||||
indexMetadatas,
|
||||
});
|
||||
};
|
||||
+28
-9
@@ -1,21 +1,40 @@
|
||||
import { FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type';
|
||||
import { fromObjectMetadataEntityToFlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/utils/from-object-metadata-entity-to-flat-object-metadata.util';
|
||||
import { fromCachedFieldMetadataEntityToFlatFieldMetadata } from 'src/engine/metadata-modules/flat-object-metadata/utils/from-cached-field-metadata-entity-to-flat-field-metadata.util';
|
||||
import { CachedFieldMetadataEntity } from 'src/engine/metadata-modules/types/cached-field-metadata-entity';
|
||||
import { ObjectMetadataItemWithFieldMaps } from 'src/engine/metadata-modules/types/object-metadata-item-with-field-maps';
|
||||
import { ObjectMetadataMaps } from 'src/engine/metadata-modules/types/object-metadata-maps';
|
||||
|
||||
export const fromObjectMetadataItemWithFieldMapsToFlatObjectMetadata = (
|
||||
objectMetadataItemWithFieldMaps: ObjectMetadataItemWithFieldMaps,
|
||||
): FlatObjectMetadata => {
|
||||
type FromObjectMetadataItemWithFieldMapsToFlatObjectMetadataArgs = {
|
||||
objectMetadataItemWithFieldMaps: ObjectMetadataItemWithFieldMaps;
|
||||
objectMetadataMaps: ObjectMetadataMaps;
|
||||
};
|
||||
export const fromObjectMetadataItemWithFieldMapsToFlatObjectMetadata = ({
|
||||
objectMetadataItemWithFieldMaps,
|
||||
objectMetadataMaps,
|
||||
}: FromObjectMetadataItemWithFieldMapsToFlatObjectMetadataArgs): FlatObjectMetadata => {
|
||||
const {
|
||||
fieldsById,
|
||||
fieldIdByJoinColumnName: _fieldIdByJoinColumnName,
|
||||
fieldIdByName: _fieldIdByName,
|
||||
indexMetadatas,
|
||||
indexMetadatas: _indexMetadatas,
|
||||
...rest
|
||||
} = objectMetadataItemWithFieldMaps;
|
||||
|
||||
return fromObjectMetadataEntityToFlatObjectMetadata({
|
||||
const cachedFieldMetadataEntities =
|
||||
Object.values<CachedFieldMetadataEntity>(fieldsById);
|
||||
|
||||
const flatFieldMetadatas = cachedFieldMetadataEntities.map(
|
||||
(cachedFieldMetadataEntity) =>
|
||||
fromCachedFieldMetadataEntityToFlatFieldMetadata({
|
||||
cachedFieldMetadataEntity,
|
||||
objectMetadataMaps,
|
||||
}),
|
||||
);
|
||||
|
||||
return {
|
||||
...rest,
|
||||
fields: Object.values(fieldsById),
|
||||
indexMetadatas,
|
||||
});
|
||||
flatFieldMetadatas,
|
||||
uniqueIdentifier: rest.standardId ?? rest.id,
|
||||
flatIndexMetadatas: [], // prastoin TODO convert from indexMetadatas to flatIndexMetadatas
|
||||
};
|
||||
};
|
||||
|
||||
+15
-4
@@ -3,6 +3,10 @@ import { isDefined } from 'twenty-shared/utils';
|
||||
import { FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type';
|
||||
import { fromObjectMetadataItemWithFieldMapsToFlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/utils/from-object-metadata-item-with-field-maps-to-flat-object-metadata.util';
|
||||
import { ObjectMetadataMaps } from 'src/engine/metadata-modules/types/object-metadata-maps';
|
||||
import {
|
||||
WorkspaceMetadataCacheException,
|
||||
WorkspaceMetadataCacheExceptionCode,
|
||||
} from 'src/engine/metadata-modules/workspace-metadata-cache/exceptions/workspace-metadata-cache.exception';
|
||||
|
||||
export const fromObjectMetadataMapsToFlatObjectMetadatas = (
|
||||
objectMetadataMaps: ObjectMetadataMaps,
|
||||
@@ -10,12 +14,19 @@ export const fromObjectMetadataMapsToFlatObjectMetadatas = (
|
||||
const objectMetadataIds = Object.keys(objectMetadataMaps.byId);
|
||||
|
||||
return objectMetadataIds.flatMap<FlatObjectMetadata>((objectMetadataId) => {
|
||||
const occurrence = objectMetadataMaps.byId[objectMetadataId];
|
||||
const objectMetadataItemWithFieldMaps =
|
||||
objectMetadataMaps.byId[objectMetadataId];
|
||||
|
||||
if (!isDefined(occurrence)) {
|
||||
return [];
|
||||
if (!isDefined(objectMetadataItemWithFieldMaps)) {
|
||||
throw new WorkspaceMetadataCacheException(
|
||||
'Object metadata not found in cache',
|
||||
WorkspaceMetadataCacheExceptionCode.OBJECT_METADATA_MAP_NOT_FOUND,
|
||||
);
|
||||
}
|
||||
|
||||
return fromObjectMetadataItemWithFieldMapsToFlatObjectMetadata(occurrence);
|
||||
return fromObjectMetadataItemWithFieldMapsToFlatObjectMetadata({
|
||||
objectMetadataItemWithFieldMaps,
|
||||
objectMetadataMaps,
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user