Index v2 side effects (#14567)
# Introduction Honestly this implem is a mess, discussing a potential side effect handler with @weiko before the build and run that would handle each side effect per entity and operation Handling: - [ ] unique index is generated when a field is updated with the `isUnique` - [x] an index is generated when a relation is created - [x] search vector index creation on custom object creation - [x] renaming a field metadata or an object should re-create all related indexes which are composed by their namings - [x] delete object should remove any related indexes - [x] delete field should update related indexes ( if index ends up empty it should be removed ) - [ ] on object renaming that contains morph fields -> triggers update field -> trigger index recompute - [x] on update name renaming should recompute all related indexes ## TODO - [x] Integration testing - [ ] Refactor the index maps cache to be storing a `idsByObjectMetadataId` - [x] Refactor deterministic name to use order sorting - [x] Remove flat index from flat object ## What's next Will handle morph indexes in a new dedicated PR for the moment will stick to this Same for the cache improvement and uniqueness
This commit is contained in:
-31
@@ -1,31 +0,0 @@
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { EMPTY_FLAT_ENTITY_MAPS } from 'src/engine/core-modules/common/constant/empty-flat-entity-maps.constant';
|
||||
import { type FlatEntityMaps } from 'src/engine/core-modules/common/types/flat-entity-maps.type';
|
||||
import { type FlatEntity } from 'src/engine/core-modules/common/types/flat-entity.type';
|
||||
import { addFlatEntityToFlatEntityMapsOrThrow } from 'src/engine/core-modules/common/utils/add-flat-entity-to-flat-entity-maps-or-throw.util';
|
||||
import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/core-modules/common/utils/find-flat-entity-by-id-in-flat-entity-maps.util';
|
||||
|
||||
export const getSubFlatEntityMaps = <T extends FlatEntity>({
|
||||
flatEntityIds,
|
||||
flatEntityMaps,
|
||||
}: {
|
||||
flatEntityMaps: FlatEntityMaps<T>;
|
||||
flatEntityIds: string[];
|
||||
}): FlatEntityMaps<T> => {
|
||||
return flatEntityIds.reduce<FlatEntityMaps<T>>((acc, flatEntityId) => {
|
||||
const flatEntity = findFlatEntityByIdInFlatEntityMaps({
|
||||
flatEntityId,
|
||||
flatEntityMaps,
|
||||
});
|
||||
|
||||
if (!isDefined(flatEntity)) {
|
||||
return acc;
|
||||
}
|
||||
|
||||
return addFlatEntityToFlatEntityMapsOrThrow({
|
||||
flatEntity,
|
||||
flatEntityMaps: acc,
|
||||
});
|
||||
}, EMPTY_FLAT_ENTITY_MAPS);
|
||||
};
|
||||
@@ -337,6 +337,7 @@ export class DataloaderService {
|
||||
>(async (dataLoaderParams: IndexFieldMetadataLoaderPayload[]) => {
|
||||
const workspaceId = dataLoaderParams[0].workspaceId;
|
||||
|
||||
// This computes the old cache :thinking:
|
||||
const { objectMetadataMaps } =
|
||||
await this.workspaceMetadataCacheService.getExistingOrRecomputeMetadataMaps(
|
||||
{ workspaceId },
|
||||
|
||||
+96
-18
@@ -5,6 +5,9 @@ import { isDefined } from 'twenty-shared/utils';
|
||||
import { In, Repository } from 'typeorm';
|
||||
|
||||
import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/core-modules/common/services/workspace-many-or-all-flat-entity-maps-cache.service.';
|
||||
import { addFlatEntityToFlatEntityMapsOrThrow } from 'src/engine/core-modules/common/utils/add-flat-entity-to-flat-entity-maps-or-throw.util';
|
||||
import { deleteFlatEntityFromFlatEntityMapsOrThrow } from 'src/engine/core-modules/common/utils/delete-flat-entity-from-flat-entity-maps-or-throw.util';
|
||||
import { replaceFlatEntityInFlatEntityMapsOrThrow } from 'src/engine/core-modules/common/utils/replace-flat-entity-in-flat-entity-maps-or-throw.util';
|
||||
import { type CreateFieldInput } from 'src/engine/metadata-modules/field-metadata/dtos/create-field.input';
|
||||
import { type DeleteOneFieldInput } from 'src/engine/metadata-modules/field-metadata/dtos/delete-field.input';
|
||||
import { FieldMetadataDTO } from 'src/engine/metadata-modules/field-metadata/dtos/field-metadata.dto';
|
||||
@@ -64,19 +67,26 @@ export class FieldMetadataServiceV2 {
|
||||
deleteOneFieldInput: DeleteOneFieldInput;
|
||||
workspaceId: string;
|
||||
}): Promise<FieldMetadataDTO> {
|
||||
const { flatObjectMetadataMaps: existingFlatObjectMetadataMaps } =
|
||||
const {
|
||||
flatObjectMetadataMaps: existingFlatObjectMetadataMaps,
|
||||
flatIndexMaps: existingFlatIndexMaps,
|
||||
} =
|
||||
await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps(
|
||||
{
|
||||
workspaceId,
|
||||
flatEntities: ['flatObjectMetadataMaps'],
|
||||
flatEntities: ['flatObjectMetadataMaps', 'flatIndexMaps'],
|
||||
},
|
||||
);
|
||||
|
||||
const flatFieldMetadatasToDelete =
|
||||
fromDeleteFieldInputToFlatFieldMetadatasToDelete({
|
||||
deleteOneFieldInput,
|
||||
existingFlatObjectMetadataMaps,
|
||||
});
|
||||
const {
|
||||
flatFieldMetadatasToDelete,
|
||||
flatIndexesToDelete,
|
||||
flatIndexesToUpdate,
|
||||
} = fromDeleteFieldInputToFlatFieldMetadatasToDelete({
|
||||
deleteOneFieldInput,
|
||||
existingFlatObjectMetadataMaps,
|
||||
existingFlatIndexMaps,
|
||||
});
|
||||
|
||||
const fromFlatObjectMetadataMaps = getSubFlatObjectMetadataMapsOrThrow({
|
||||
flatObjectMetadataMaps: existingFlatObjectMetadataMaps,
|
||||
@@ -100,6 +110,23 @@ export class FieldMetadataServiceV2 {
|
||||
fromFlatObjectMetadataMaps,
|
||||
);
|
||||
|
||||
const toFlatIndexMapsWithUpdatedFlatIndex = flatIndexesToUpdate.reduce(
|
||||
(flatIndexMaps, flatIndex) =>
|
||||
replaceFlatEntityInFlatEntityMapsOrThrow({
|
||||
flatEntity: flatIndex,
|
||||
flatEntityMaps: flatIndexMaps,
|
||||
}),
|
||||
existingFlatIndexMaps,
|
||||
);
|
||||
const toFlatIndexMaps = flatIndexesToDelete.reduce(
|
||||
(flatIndexMaps, flatIndex) =>
|
||||
deleteFlatEntityFromFlatEntityMapsOrThrow({
|
||||
entityToDeleteId: flatIndex.id,
|
||||
flatEntityMaps: flatIndexMaps,
|
||||
}),
|
||||
toFlatIndexMapsWithUpdatedFlatIndex,
|
||||
);
|
||||
|
||||
const validateAndBuildResult =
|
||||
await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration(
|
||||
{
|
||||
@@ -112,6 +139,10 @@ export class FieldMetadataServiceV2 {
|
||||
from: fromFlatObjectMetadataMaps,
|
||||
to: toFlatObjectMetadataMaps,
|
||||
},
|
||||
flatIndexMaps: {
|
||||
from: existingFlatIndexMaps,
|
||||
to: toFlatIndexMaps,
|
||||
},
|
||||
},
|
||||
workspaceId,
|
||||
},
|
||||
@@ -136,16 +167,20 @@ export class FieldMetadataServiceV2 {
|
||||
updateFieldInput: UpdateFieldInput;
|
||||
workspaceId: string;
|
||||
}): Promise<FieldMetadataEntity> {
|
||||
const { flatObjectMetadataMaps: existingFlatObjectMetadataMaps } =
|
||||
const {
|
||||
flatObjectMetadataMaps: existingFlatObjectMetadataMaps,
|
||||
flatIndexMaps: existingFlatIndexMaps,
|
||||
} =
|
||||
await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps(
|
||||
{
|
||||
workspaceId,
|
||||
flatEntities: ['flatObjectMetadataMaps'],
|
||||
flatEntities: ['flatObjectMetadataMaps', 'flatIndexMaps'],
|
||||
},
|
||||
);
|
||||
|
||||
const inputTranspilationResult = fromUpdateFieldInputToFlatFieldMetadata({
|
||||
existingFlatObjectMetadataMaps,
|
||||
flatIndexMaps: existingFlatIndexMaps,
|
||||
flatObjectMetadataMaps: existingFlatObjectMetadataMaps,
|
||||
updateFieldInput,
|
||||
});
|
||||
|
||||
@@ -153,8 +188,10 @@ export class FieldMetadataServiceV2 {
|
||||
throw inputTranspilationResult.error;
|
||||
}
|
||||
|
||||
const optimisticallyUpdatedFlatFieldMetadatas =
|
||||
inputTranspilationResult.result;
|
||||
const {
|
||||
flatFieldMetadatasToUpdate: optimisticallyUpdatedFlatFieldMetadatas,
|
||||
flatIndexMetadatasToUpdate,
|
||||
} = inputTranspilationResult.result;
|
||||
|
||||
const objectMetadataIdWithRelatedObjectMetadataIds = [
|
||||
...new Set(
|
||||
@@ -181,6 +218,15 @@ export class FieldMetadataServiceV2 {
|
||||
fromFlatObjectMetadataMaps,
|
||||
);
|
||||
|
||||
const toFlatIndexMaps = flatIndexMetadatasToUpdate.reduce(
|
||||
(flatIndexMaps, flatIndexMetadata) =>
|
||||
replaceFlatEntityInFlatEntityMapsOrThrow({
|
||||
flatEntity: flatIndexMetadata,
|
||||
flatEntityMaps: flatIndexMaps,
|
||||
}),
|
||||
existingFlatIndexMaps,
|
||||
);
|
||||
|
||||
const validateAndBuildResult =
|
||||
await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration(
|
||||
{
|
||||
@@ -189,6 +235,10 @@ export class FieldMetadataServiceV2 {
|
||||
from: fromFlatObjectMetadataMaps,
|
||||
to: toFlatObjectMetadataMaps,
|
||||
},
|
||||
flatIndexMaps: {
|
||||
from: existingFlatIndexMaps,
|
||||
to: toFlatIndexMaps,
|
||||
},
|
||||
},
|
||||
buildOptions: {
|
||||
isSystemBuild: false,
|
||||
@@ -224,15 +274,20 @@ export class FieldMetadataServiceV2 {
|
||||
return [];
|
||||
}
|
||||
|
||||
const { flatObjectMetadataMaps: existingFlatObjectMetadataMaps } =
|
||||
const {
|
||||
flatObjectMetadataMaps: existingFlatObjectMetadataMaps,
|
||||
flatIndexMaps: existingFlatIndexMaps,
|
||||
} =
|
||||
await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps(
|
||||
{
|
||||
workspaceId,
|
||||
flatEntities: ['flatObjectMetadataMaps'],
|
||||
flatEntities: ['flatObjectMetadataMaps', 'flatIndexMaps'],
|
||||
},
|
||||
);
|
||||
|
||||
const allTranspiledTranspilationInputs = [];
|
||||
const allTranspiledTranspilationInputs: Awaited<
|
||||
ReturnType<typeof fromCreateFieldInputToFlatFieldMetadatasToCreate>
|
||||
>[] = [];
|
||||
|
||||
for (const createInput of createFieldInputs) {
|
||||
allTranspiledTranspilationInputs.push(
|
||||
@@ -249,8 +304,18 @@ export class FieldMetadataServiceV2 {
|
||||
'Multiple validation errors occurred while creating field',
|
||||
);
|
||||
|
||||
const flatFieldMetadatasToCreate = allTranspiledTranspilationInputs.flatMap(
|
||||
({ result }) => result,
|
||||
const {
|
||||
flatFieldMetadatas: flatFieldMetadatasToCreate,
|
||||
indexMetadatas: flatIndexMetadatasToCreate,
|
||||
} = allTranspiledTranspilationInputs.reduce(
|
||||
(acc, { result }) => ({
|
||||
flatFieldMetadatas: [
|
||||
...acc.flatFieldMetadatas,
|
||||
...result.flatFieldMetadatas,
|
||||
],
|
||||
indexMetadatas: [...acc.indexMetadatas, ...result.indexMetadatas],
|
||||
}),
|
||||
{ flatFieldMetadatas: [], indexMetadatas: [] },
|
||||
);
|
||||
|
||||
const impactedObjectMetadataIds = Array.from(
|
||||
@@ -277,6 +342,15 @@ export class FieldMetadataServiceV2 {
|
||||
}),
|
||||
);
|
||||
|
||||
const toFlatIndexMaps = flatIndexMetadatasToCreate.reduce(
|
||||
(flatIndexMaps, flatIndex) =>
|
||||
addFlatEntityToFlatEntityMapsOrThrow({
|
||||
flatEntity: flatIndex,
|
||||
flatEntityMaps: flatIndexMaps,
|
||||
}),
|
||||
existingFlatIndexMaps,
|
||||
);
|
||||
|
||||
const validateAndBuildResult =
|
||||
await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration(
|
||||
{
|
||||
@@ -285,6 +359,10 @@ export class FieldMetadataServiceV2 {
|
||||
from: fromFlatObjectMetadataMaps,
|
||||
to: toFlatObjectMetadataMaps,
|
||||
},
|
||||
flatIndexMaps: {
|
||||
from: existingFlatIndexMaps,
|
||||
to: toFlatIndexMaps,
|
||||
},
|
||||
},
|
||||
buildOptions: {
|
||||
isSystemBuild: false,
|
||||
@@ -305,7 +383,7 @@ export class FieldMetadataServiceV2 {
|
||||
where: {
|
||||
name: In(
|
||||
allTranspiledTranspilationInputs.map(
|
||||
({ result: flatFieldMetadatas }) => flatFieldMetadatas[0].name,
|
||||
({ result: { flatFieldMetadatas } }) => flatFieldMetadatas[0].name,
|
||||
),
|
||||
),
|
||||
workspaceId,
|
||||
|
||||
+353
-313
@@ -83,12 +83,189 @@ exports[`fromCreateFieldInputToFlatFieldMetadatasToCreate MORPH_RELATION test su
|
||||
|
||||
exports[`fromCreateFieldInputToFlatFieldMetadatasToCreate MORPH_RELATION test suite Success cases should create morph relation field metadata with valid input on rocket object to pet object 1`] = `
|
||||
{
|
||||
"result": [
|
||||
{
|
||||
"createdAt": Any<ClockDate>,
|
||||
"defaultValue": null,
|
||||
"description": "new field description",
|
||||
"flatRelationTargetFieldMetadata": {
|
||||
"result": {
|
||||
"flatFieldMetadatas": [
|
||||
{
|
||||
"createdAt": Any<ClockDate>,
|
||||
"defaultValue": null,
|
||||
"description": "new field description",
|
||||
"flatRelationTargetFieldMetadata": {
|
||||
"createdAt": Any<ClockDate>,
|
||||
"defaultValue": null,
|
||||
"description": null,
|
||||
"flatRelationTargetFieldMetadata": {
|
||||
"createdAt": Any<ClockDate>,
|
||||
"defaultValue": null,
|
||||
"description": "new field description",
|
||||
"flatRelationTargetFieldMetadata": null,
|
||||
"flatRelationTargetObjectMetadata": {
|
||||
"createdAt": Any<String>,
|
||||
"description": null,
|
||||
"duplicateCriteria": null,
|
||||
"flatFieldMetadatas": [],
|
||||
"icon": "IconCat",
|
||||
"id": Any<String>,
|
||||
"imageIdentifierFieldMetadataId": null,
|
||||
"isActive": true,
|
||||
"isAuditLogged": true,
|
||||
"isCustom": true,
|
||||
"isLabelSyncedWithName": false,
|
||||
"isRemote": false,
|
||||
"isSearchable": true,
|
||||
"isSystem": false,
|
||||
"isUIReadOnly": false,
|
||||
"labelIdentifierFieldMetadataId": Any<String>,
|
||||
"labelPlural": "Pets",
|
||||
"labelSingular": "Pet",
|
||||
"namePlural": "pets",
|
||||
"nameSingular": "pet",
|
||||
"shortcut": null,
|
||||
"standardId": null,
|
||||
"standardOverrides": null,
|
||||
"targetTableName": "DEPRECATED",
|
||||
"universalIdentifier": Any<String>,
|
||||
"updatedAt": Any<String>,
|
||||
"workspaceId": Any<String>,
|
||||
},
|
||||
"icon": "IconRelationOneToMany",
|
||||
"id": Any<String>,
|
||||
"isActive": true,
|
||||
"isCustom": true,
|
||||
"isLabelSyncedWithName": false,
|
||||
"isNullable": true,
|
||||
"isSystem": false,
|
||||
"isUIReadOnly": false,
|
||||
"isUnique": null,
|
||||
"label": "newFieldLabel",
|
||||
"morphId": Any<String>,
|
||||
"name": "newFieldPets",
|
||||
"objectMetadataId": Any<String>,
|
||||
"options": null,
|
||||
"relationTargetFieldMetadataId": Any<String>,
|
||||
"relationTargetObjectMetadataId": Any<String>,
|
||||
"settings": {
|
||||
"relationType": "ONE_TO_MANY",
|
||||
},
|
||||
"standardId": null,
|
||||
"standardOverrides": null,
|
||||
"type": "MORPH_RELATION",
|
||||
"universalIdentifier": Any<String>,
|
||||
"updatedAt": Any<ClockDate>,
|
||||
"workspaceId": Any<String>,
|
||||
},
|
||||
"flatRelationTargetObjectMetadata": {
|
||||
"createdAt": Any<String>,
|
||||
"description": "A rocket",
|
||||
"duplicateCriteria": null,
|
||||
"flatFieldMetadatas": [],
|
||||
"icon": "IconRocket",
|
||||
"id": Any<String>,
|
||||
"imageIdentifierFieldMetadataId": null,
|
||||
"isActive": true,
|
||||
"isAuditLogged": true,
|
||||
"isCustom": true,
|
||||
"isLabelSyncedWithName": false,
|
||||
"isRemote": false,
|
||||
"isSearchable": true,
|
||||
"isSystem": false,
|
||||
"isUIReadOnly": false,
|
||||
"labelIdentifierFieldMetadataId": Any<String>,
|
||||
"labelPlural": "Rockets",
|
||||
"labelSingular": "Rocket",
|
||||
"namePlural": "rockets",
|
||||
"nameSingular": "rocket",
|
||||
"shortcut": null,
|
||||
"standardId": null,
|
||||
"standardOverrides": null,
|
||||
"targetTableName": "DEPRECATED",
|
||||
"universalIdentifier": Any<String>,
|
||||
"updatedAt": Any<String>,
|
||||
"workspaceId": Any<String>,
|
||||
},
|
||||
"icon": "IconPet",
|
||||
"id": Any<String>,
|
||||
"isActive": true,
|
||||
"isCustom": true,
|
||||
"isLabelSyncedWithName": false,
|
||||
"isNullable": true,
|
||||
"isSystem": false,
|
||||
"isUIReadOnly": false,
|
||||
"isUnique": null,
|
||||
"label": "Pet",
|
||||
"morphId": null,
|
||||
"name": "pet",
|
||||
"objectMetadataId": Any<String>,
|
||||
"options": null,
|
||||
"relationTargetFieldMetadataId": Any<String>,
|
||||
"relationTargetObjectMetadataId": Any<String>,
|
||||
"settings": {
|
||||
"joinColumnName": "petId",
|
||||
"onDelete": "SET_NULL",
|
||||
"relationType": "MANY_TO_ONE",
|
||||
},
|
||||
"standardId": null,
|
||||
"standardOverrides": null,
|
||||
"type": "RELATION",
|
||||
"universalIdentifier": Any<String>,
|
||||
"updatedAt": Any<ClockDate>,
|
||||
"workspaceId": Any<String>,
|
||||
},
|
||||
"flatRelationTargetObjectMetadata": {
|
||||
"createdAt": Any<String>,
|
||||
"description": null,
|
||||
"duplicateCriteria": null,
|
||||
"flatFieldMetadatas": [],
|
||||
"icon": "IconCat",
|
||||
"id": Any<String>,
|
||||
"imageIdentifierFieldMetadataId": null,
|
||||
"isActive": true,
|
||||
"isAuditLogged": true,
|
||||
"isCustom": true,
|
||||
"isLabelSyncedWithName": false,
|
||||
"isRemote": false,
|
||||
"isSearchable": true,
|
||||
"isSystem": false,
|
||||
"isUIReadOnly": false,
|
||||
"labelIdentifierFieldMetadataId": Any<String>,
|
||||
"labelPlural": "Pets",
|
||||
"labelSingular": "Pet",
|
||||
"namePlural": "pets",
|
||||
"nameSingular": "pet",
|
||||
"shortcut": null,
|
||||
"standardId": null,
|
||||
"standardOverrides": null,
|
||||
"targetTableName": "DEPRECATED",
|
||||
"universalIdentifier": Any<String>,
|
||||
"updatedAt": Any<String>,
|
||||
"workspaceId": Any<String>,
|
||||
},
|
||||
"icon": "IconRelationOneToMany",
|
||||
"id": Any<String>,
|
||||
"isActive": true,
|
||||
"isCustom": true,
|
||||
"isLabelSyncedWithName": false,
|
||||
"isNullable": true,
|
||||
"isSystem": false,
|
||||
"isUIReadOnly": false,
|
||||
"isUnique": null,
|
||||
"label": "newFieldLabel",
|
||||
"morphId": Any<String>,
|
||||
"name": "newFieldPets",
|
||||
"objectMetadataId": Any<String>,
|
||||
"options": null,
|
||||
"relationTargetFieldMetadataId": Any<String>,
|
||||
"relationTargetObjectMetadataId": Any<String>,
|
||||
"settings": {
|
||||
"relationType": "ONE_TO_MANY",
|
||||
},
|
||||
"standardId": null,
|
||||
"standardOverrides": null,
|
||||
"type": "MORPH_RELATION",
|
||||
"universalIdentifier": Any<String>,
|
||||
"updatedAt": Any<ClockDate>,
|
||||
"workspaceId": Any<String>,
|
||||
},
|
||||
{
|
||||
"createdAt": Any<ClockDate>,
|
||||
"defaultValue": null,
|
||||
"description": null,
|
||||
@@ -102,7 +279,6 @@ exports[`fromCreateFieldInputToFlatFieldMetadatasToCreate MORPH_RELATION test su
|
||||
"description": null,
|
||||
"duplicateCriteria": null,
|
||||
"flatFieldMetadatas": [],
|
||||
"flatIndexMetadatas": [],
|
||||
"icon": "IconCat",
|
||||
"id": Any<String>,
|
||||
"imageIdentifierFieldMetadataId": null,
|
||||
@@ -158,7 +334,6 @@ exports[`fromCreateFieldInputToFlatFieldMetadatasToCreate MORPH_RELATION test su
|
||||
"description": "A rocket",
|
||||
"duplicateCriteria": null,
|
||||
"flatFieldMetadatas": [],
|
||||
"flatIndexMetadatas": [],
|
||||
"icon": "IconRocket",
|
||||
"id": Any<String>,
|
||||
"imageIdentifierFieldMetadataId": null,
|
||||
@@ -211,95 +386,154 @@ exports[`fromCreateFieldInputToFlatFieldMetadatasToCreate MORPH_RELATION test su
|
||||
"updatedAt": Any<ClockDate>,
|
||||
"workspaceId": Any<String>,
|
||||
},
|
||||
"flatRelationTargetObjectMetadata": {
|
||||
"createdAt": Any<String>,
|
||||
"description": null,
|
||||
"duplicateCriteria": null,
|
||||
"flatFieldMetadatas": [],
|
||||
"flatIndexMetadatas": [],
|
||||
"icon": "IconCat",
|
||||
"id": Any<String>,
|
||||
"imageIdentifierFieldMetadataId": null,
|
||||
"isActive": true,
|
||||
"isAuditLogged": true,
|
||||
"isCustom": true,
|
||||
"isLabelSyncedWithName": false,
|
||||
"isRemote": false,
|
||||
"isSearchable": true,
|
||||
"isSystem": false,
|
||||
"isUIReadOnly": false,
|
||||
"labelIdentifierFieldMetadataId": Any<String>,
|
||||
"labelPlural": "Pets",
|
||||
"labelSingular": "Pet",
|
||||
"namePlural": "pets",
|
||||
"nameSingular": "pet",
|
||||
"shortcut": null,
|
||||
"standardId": null,
|
||||
"standardOverrides": null,
|
||||
"targetTableName": "DEPRECATED",
|
||||
"universalIdentifier": Any<String>,
|
||||
"updatedAt": Any<String>,
|
||||
"workspaceId": Any<String>,
|
||||
},
|
||||
"icon": "IconRelationOneToMany",
|
||||
"id": Any<String>,
|
||||
"isActive": true,
|
||||
"isCustom": true,
|
||||
"isLabelSyncedWithName": false,
|
||||
"isNullable": true,
|
||||
"isSystem": false,
|
||||
"isUIReadOnly": false,
|
||||
"isUnique": null,
|
||||
"label": "newFieldLabel",
|
||||
"morphId": Any<String>,
|
||||
"name": "newFieldPets",
|
||||
"objectMetadataId": Any<String>,
|
||||
"options": null,
|
||||
"relationTargetFieldMetadataId": Any<String>,
|
||||
"relationTargetObjectMetadataId": Any<String>,
|
||||
"settings": {
|
||||
"relationType": "ONE_TO_MANY",
|
||||
},
|
||||
"standardId": null,
|
||||
"standardOverrides": null,
|
||||
"type": "MORPH_RELATION",
|
||||
"universalIdentifier": Any<String>,
|
||||
"updatedAt": Any<ClockDate>,
|
||||
"workspaceId": Any<String>,
|
||||
},
|
||||
{
|
||||
"createdAt": Any<ClockDate>,
|
||||
"defaultValue": null,
|
||||
"description": null,
|
||||
"flatRelationTargetFieldMetadata": {
|
||||
{
|
||||
"createdAt": Any<ClockDate>,
|
||||
"defaultValue": null,
|
||||
"description": "new field description",
|
||||
"flatRelationTargetFieldMetadata": null,
|
||||
"flatRelationTargetFieldMetadata": {
|
||||
"createdAt": Any<ClockDate>,
|
||||
"defaultValue": null,
|
||||
"description": null,
|
||||
"flatRelationTargetFieldMetadata": {
|
||||
"createdAt": Any<ClockDate>,
|
||||
"defaultValue": null,
|
||||
"description": "new field description",
|
||||
"flatRelationTargetFieldMetadata": null,
|
||||
"flatRelationTargetObjectMetadata": {
|
||||
"createdAt": Any<String>,
|
||||
"description": "A company",
|
||||
"duplicateCriteria": null,
|
||||
"flatFieldMetadatas": [],
|
||||
"icon": "IconBuildingSkyscraper",
|
||||
"id": Any<String>,
|
||||
"imageIdentifierFieldMetadataId": null,
|
||||
"isActive": true,
|
||||
"isAuditLogged": true,
|
||||
"isCustom": false,
|
||||
"isLabelSyncedWithName": false,
|
||||
"isRemote": false,
|
||||
"isSearchable": true,
|
||||
"isSystem": false,
|
||||
"isUIReadOnly": false,
|
||||
"labelIdentifierFieldMetadataId": Any<String>,
|
||||
"labelPlural": "Companies",
|
||||
"labelSingular": "Company",
|
||||
"namePlural": "companies",
|
||||
"nameSingular": "company",
|
||||
"shortcut": "C",
|
||||
"standardId": Any<String>,
|
||||
"standardOverrides": null,
|
||||
"targetTableName": "DEPRECATED",
|
||||
"universalIdentifier": Any<String>,
|
||||
"updatedAt": Any<String>,
|
||||
"workspaceId": Any<String>,
|
||||
},
|
||||
"icon": "IconRelationOneToMany",
|
||||
"id": Any<String>,
|
||||
"isActive": true,
|
||||
"isCustom": true,
|
||||
"isLabelSyncedWithName": false,
|
||||
"isNullable": true,
|
||||
"isSystem": false,
|
||||
"isUIReadOnly": false,
|
||||
"isUnique": null,
|
||||
"label": "newFieldLabel",
|
||||
"morphId": Any<String>,
|
||||
"name": "newFieldCompanies",
|
||||
"objectMetadataId": Any<String>,
|
||||
"options": null,
|
||||
"relationTargetFieldMetadataId": Any<String>,
|
||||
"relationTargetObjectMetadataId": Any<String>,
|
||||
"settings": {
|
||||
"relationType": "ONE_TO_MANY",
|
||||
},
|
||||
"standardId": null,
|
||||
"standardOverrides": null,
|
||||
"type": "MORPH_RELATION",
|
||||
"universalIdentifier": Any<String>,
|
||||
"updatedAt": Any<ClockDate>,
|
||||
"workspaceId": Any<String>,
|
||||
},
|
||||
"flatRelationTargetObjectMetadata": {
|
||||
"createdAt": Any<String>,
|
||||
"description": "A rocket",
|
||||
"duplicateCriteria": null,
|
||||
"flatFieldMetadatas": [],
|
||||
"icon": "IconRocket",
|
||||
"id": Any<String>,
|
||||
"imageIdentifierFieldMetadataId": null,
|
||||
"isActive": true,
|
||||
"isAuditLogged": true,
|
||||
"isCustom": true,
|
||||
"isLabelSyncedWithName": false,
|
||||
"isRemote": false,
|
||||
"isSearchable": true,
|
||||
"isSystem": false,
|
||||
"isUIReadOnly": false,
|
||||
"labelIdentifierFieldMetadataId": Any<String>,
|
||||
"labelPlural": "Rockets",
|
||||
"labelSingular": "Rocket",
|
||||
"namePlural": "rockets",
|
||||
"nameSingular": "rocket",
|
||||
"shortcut": null,
|
||||
"standardId": null,
|
||||
"standardOverrides": null,
|
||||
"targetTableName": "DEPRECATED",
|
||||
"universalIdentifier": Any<String>,
|
||||
"updatedAt": Any<String>,
|
||||
"workspaceId": Any<String>,
|
||||
},
|
||||
"icon": "IconBuilding",
|
||||
"id": Any<String>,
|
||||
"isActive": true,
|
||||
"isCustom": true,
|
||||
"isLabelSyncedWithName": false,
|
||||
"isNullable": true,
|
||||
"isSystem": false,
|
||||
"isUIReadOnly": false,
|
||||
"isUnique": null,
|
||||
"label": "Company",
|
||||
"morphId": null,
|
||||
"name": "company",
|
||||
"objectMetadataId": Any<String>,
|
||||
"options": null,
|
||||
"relationTargetFieldMetadataId": Any<String>,
|
||||
"relationTargetObjectMetadataId": Any<String>,
|
||||
"settings": {
|
||||
"joinColumnName": "companyId",
|
||||
"onDelete": "SET_NULL",
|
||||
"relationType": "MANY_TO_ONE",
|
||||
},
|
||||
"standardId": null,
|
||||
"standardOverrides": null,
|
||||
"type": "RELATION",
|
||||
"universalIdentifier": Any<String>,
|
||||
"updatedAt": Any<ClockDate>,
|
||||
"workspaceId": Any<String>,
|
||||
},
|
||||
"flatRelationTargetObjectMetadata": {
|
||||
"createdAt": Any<String>,
|
||||
"description": null,
|
||||
"description": "A company",
|
||||
"duplicateCriteria": null,
|
||||
"flatFieldMetadatas": [],
|
||||
"flatIndexMetadatas": [],
|
||||
"icon": "IconCat",
|
||||
"icon": "IconBuildingSkyscraper",
|
||||
"id": Any<String>,
|
||||
"imageIdentifierFieldMetadataId": null,
|
||||
"isActive": true,
|
||||
"isAuditLogged": true,
|
||||
"isCustom": true,
|
||||
"isCustom": false,
|
||||
"isLabelSyncedWithName": false,
|
||||
"isRemote": false,
|
||||
"isSearchable": true,
|
||||
"isSystem": false,
|
||||
"isUIReadOnly": false,
|
||||
"labelIdentifierFieldMetadataId": Any<String>,
|
||||
"labelPlural": "Pets",
|
||||
"labelSingular": "Pet",
|
||||
"namePlural": "pets",
|
||||
"nameSingular": "pet",
|
||||
"shortcut": null,
|
||||
"standardId": null,
|
||||
"labelPlural": "Companies",
|
||||
"labelSingular": "Company",
|
||||
"namePlural": "companies",
|
||||
"nameSingular": "company",
|
||||
"shortcut": "C",
|
||||
"standardId": Any<String>,
|
||||
"standardOverrides": null,
|
||||
"targetTableName": "DEPRECATED",
|
||||
"universalIdentifier": Any<String>,
|
||||
@@ -317,7 +551,7 @@ exports[`fromCreateFieldInputToFlatFieldMetadatasToCreate MORPH_RELATION test su
|
||||
"isUnique": null,
|
||||
"label": "newFieldLabel",
|
||||
"morphId": Any<String>,
|
||||
"name": "newFieldPets",
|
||||
"name": "newFieldCompanies",
|
||||
"objectMetadataId": Any<String>,
|
||||
"options": null,
|
||||
"relationTargetFieldMetadataId": Any<String>,
|
||||
@@ -332,69 +566,7 @@ exports[`fromCreateFieldInputToFlatFieldMetadatasToCreate MORPH_RELATION test su
|
||||
"updatedAt": Any<ClockDate>,
|
||||
"workspaceId": Any<String>,
|
||||
},
|
||||
"flatRelationTargetObjectMetadata": {
|
||||
"createdAt": Any<String>,
|
||||
"description": "A rocket",
|
||||
"duplicateCriteria": null,
|
||||
"flatFieldMetadatas": [],
|
||||
"flatIndexMetadatas": [],
|
||||
"icon": "IconRocket",
|
||||
"id": Any<String>,
|
||||
"imageIdentifierFieldMetadataId": null,
|
||||
"isActive": true,
|
||||
"isAuditLogged": true,
|
||||
"isCustom": true,
|
||||
"isLabelSyncedWithName": false,
|
||||
"isRemote": false,
|
||||
"isSearchable": true,
|
||||
"isSystem": false,
|
||||
"isUIReadOnly": false,
|
||||
"labelIdentifierFieldMetadataId": Any<String>,
|
||||
"labelPlural": "Rockets",
|
||||
"labelSingular": "Rocket",
|
||||
"namePlural": "rockets",
|
||||
"nameSingular": "rocket",
|
||||
"shortcut": null,
|
||||
"standardId": null,
|
||||
"standardOverrides": null,
|
||||
"targetTableName": "DEPRECATED",
|
||||
"universalIdentifier": Any<String>,
|
||||
"updatedAt": Any<String>,
|
||||
"workspaceId": Any<String>,
|
||||
},
|
||||
"icon": "IconPet",
|
||||
"id": Any<String>,
|
||||
"isActive": true,
|
||||
"isCustom": true,
|
||||
"isLabelSyncedWithName": false,
|
||||
"isNullable": true,
|
||||
"isSystem": false,
|
||||
"isUIReadOnly": false,
|
||||
"isUnique": null,
|
||||
"label": "Pet",
|
||||
"morphId": null,
|
||||
"name": "pet",
|
||||
"objectMetadataId": Any<String>,
|
||||
"options": null,
|
||||
"relationTargetFieldMetadataId": Any<String>,
|
||||
"relationTargetObjectMetadataId": Any<String>,
|
||||
"settings": {
|
||||
"joinColumnName": "petId",
|
||||
"onDelete": "SET_NULL",
|
||||
"relationType": "MANY_TO_ONE",
|
||||
},
|
||||
"standardId": null,
|
||||
"standardOverrides": null,
|
||||
"type": "RELATION",
|
||||
"universalIdentifier": Any<String>,
|
||||
"updatedAt": Any<ClockDate>,
|
||||
"workspaceId": Any<String>,
|
||||
},
|
||||
{
|
||||
"createdAt": Any<ClockDate>,
|
||||
"defaultValue": null,
|
||||
"description": "new field description",
|
||||
"flatRelationTargetFieldMetadata": {
|
||||
{
|
||||
"createdAt": Any<ClockDate>,
|
||||
"defaultValue": null,
|
||||
"description": null,
|
||||
@@ -408,7 +580,6 @@ exports[`fromCreateFieldInputToFlatFieldMetadatasToCreate MORPH_RELATION test su
|
||||
"description": "A company",
|
||||
"duplicateCriteria": null,
|
||||
"flatFieldMetadatas": [],
|
||||
"flatIndexMetadatas": [],
|
||||
"icon": "IconBuildingSkyscraper",
|
||||
"id": Any<String>,
|
||||
"imageIdentifierFieldMetadataId": null,
|
||||
@@ -464,7 +635,6 @@ exports[`fromCreateFieldInputToFlatFieldMetadatasToCreate MORPH_RELATION test su
|
||||
"description": "A rocket",
|
||||
"duplicateCriteria": null,
|
||||
"flatFieldMetadatas": [],
|
||||
"flatIndexMetadatas": [],
|
||||
"icon": "IconRocket",
|
||||
"id": Any<String>,
|
||||
"imageIdentifierFieldMetadataId": null,
|
||||
@@ -517,186 +687,56 @@ exports[`fromCreateFieldInputToFlatFieldMetadatasToCreate MORPH_RELATION test su
|
||||
"updatedAt": Any<ClockDate>,
|
||||
"workspaceId": Any<String>,
|
||||
},
|
||||
"flatRelationTargetObjectMetadata": {
|
||||
"createdAt": Any<String>,
|
||||
"description": "A company",
|
||||
"duplicateCriteria": null,
|
||||
"flatFieldMetadatas": [],
|
||||
"flatIndexMetadatas": [],
|
||||
"icon": "IconBuildingSkyscraper",
|
||||
"id": Any<String>,
|
||||
"imageIdentifierFieldMetadataId": null,
|
||||
"isActive": true,
|
||||
"isAuditLogged": true,
|
||||
"isCustom": false,
|
||||
"isLabelSyncedWithName": false,
|
||||
"isRemote": false,
|
||||
"isSearchable": true,
|
||||
"isSystem": false,
|
||||
"isUIReadOnly": false,
|
||||
"labelIdentifierFieldMetadataId": Any<String>,
|
||||
"labelPlural": "Companies",
|
||||
"labelSingular": "Company",
|
||||
"namePlural": "companies",
|
||||
"nameSingular": "company",
|
||||
"shortcut": "C",
|
||||
"standardId": Any<String>,
|
||||
"standardOverrides": null,
|
||||
"targetTableName": "DEPRECATED",
|
||||
"universalIdentifier": Any<String>,
|
||||
"updatedAt": Any<String>,
|
||||
"workspaceId": Any<String>,
|
||||
},
|
||||
"icon": "IconRelationOneToMany",
|
||||
"id": Any<String>,
|
||||
"isActive": true,
|
||||
"isCustom": true,
|
||||
"isLabelSyncedWithName": false,
|
||||
"isNullable": true,
|
||||
"isSystem": false,
|
||||
"isUIReadOnly": false,
|
||||
"isUnique": null,
|
||||
"label": "newFieldLabel",
|
||||
"morphId": Any<String>,
|
||||
"name": "newFieldCompanies",
|
||||
"objectMetadataId": Any<String>,
|
||||
"options": null,
|
||||
"relationTargetFieldMetadataId": Any<String>,
|
||||
"relationTargetObjectMetadataId": Any<String>,
|
||||
"settings": {
|
||||
"relationType": "ONE_TO_MANY",
|
||||
},
|
||||
"standardId": null,
|
||||
"standardOverrides": null,
|
||||
"type": "MORPH_RELATION",
|
||||
"universalIdentifier": Any<String>,
|
||||
"updatedAt": Any<ClockDate>,
|
||||
"workspaceId": Any<String>,
|
||||
},
|
||||
{
|
||||
"createdAt": Any<ClockDate>,
|
||||
"defaultValue": null,
|
||||
"description": null,
|
||||
"flatRelationTargetFieldMetadata": {
|
||||
],
|
||||
"indexMetadatas": [
|
||||
{
|
||||
"createdAt": Any<ClockDate>,
|
||||
"defaultValue": null,
|
||||
"description": "new field description",
|
||||
"flatRelationTargetFieldMetadata": null,
|
||||
"flatRelationTargetObjectMetadata": {
|
||||
"createdAt": Any<String>,
|
||||
"description": "A company",
|
||||
"duplicateCriteria": null,
|
||||
"flatFieldMetadatas": [],
|
||||
"flatIndexMetadatas": [],
|
||||
"icon": "IconBuildingSkyscraper",
|
||||
"id": Any<String>,
|
||||
"imageIdentifierFieldMetadataId": null,
|
||||
"isActive": true,
|
||||
"isAuditLogged": true,
|
||||
"isCustom": false,
|
||||
"isLabelSyncedWithName": false,
|
||||
"isRemote": false,
|
||||
"isSearchable": true,
|
||||
"isSystem": false,
|
||||
"isUIReadOnly": false,
|
||||
"labelIdentifierFieldMetadataId": Any<String>,
|
||||
"labelPlural": "Companies",
|
||||
"labelSingular": "Company",
|
||||
"namePlural": "companies",
|
||||
"nameSingular": "company",
|
||||
"shortcut": "C",
|
||||
"standardId": Any<String>,
|
||||
"standardOverrides": null,
|
||||
"targetTableName": "DEPRECATED",
|
||||
"universalIdentifier": Any<String>,
|
||||
"updatedAt": Any<String>,
|
||||
"workspaceId": Any<String>,
|
||||
},
|
||||
"icon": "IconRelationOneToMany",
|
||||
"flatIndexFieldMetadatas": [
|
||||
{
|
||||
"createdAt": Any<ClockDate>,
|
||||
"fieldMetadataId": Any<String>,
|
||||
"id": Any<String>,
|
||||
"indexMetadataId": Any<String>,
|
||||
"order": 0,
|
||||
"updatedAt": Any<ClockDate>,
|
||||
},
|
||||
],
|
||||
"id": Any<String>,
|
||||
"isActive": true,
|
||||
"indexType": "BTREE",
|
||||
"indexWhereClause": null,
|
||||
"isCustom": true,
|
||||
"isLabelSyncedWithName": false,
|
||||
"isNullable": true,
|
||||
"isSystem": false,
|
||||
"isUIReadOnly": false,
|
||||
"isUnique": null,
|
||||
"label": "newFieldLabel",
|
||||
"morphId": Any<String>,
|
||||
"name": "newFieldCompanies",
|
||||
"isUnique": false,
|
||||
"name": "IDX_f687e4e4252800dddd8e5518362",
|
||||
"objectMetadataId": Any<String>,
|
||||
"options": null,
|
||||
"relationTargetFieldMetadataId": Any<String>,
|
||||
"relationTargetObjectMetadataId": Any<String>,
|
||||
"settings": {
|
||||
"relationType": "ONE_TO_MANY",
|
||||
},
|
||||
"standardId": null,
|
||||
"standardOverrides": null,
|
||||
"type": "MORPH_RELATION",
|
||||
"universalIdentifier": Any<String>,
|
||||
"updatedAt": Any<ClockDate>,
|
||||
"workspaceId": Any<String>,
|
||||
},
|
||||
"flatRelationTargetObjectMetadata": {
|
||||
"createdAt": Any<String>,
|
||||
"description": "A rocket",
|
||||
"duplicateCriteria": null,
|
||||
"flatFieldMetadatas": [],
|
||||
"flatIndexMetadatas": [],
|
||||
"icon": "IconRocket",
|
||||
{
|
||||
"createdAt": Any<ClockDate>,
|
||||
"flatIndexFieldMetadatas": [
|
||||
{
|
||||
"createdAt": Any<ClockDate>,
|
||||
"fieldMetadataId": Any<String>,
|
||||
"id": Any<String>,
|
||||
"indexMetadataId": Any<String>,
|
||||
"order": 0,
|
||||
"updatedAt": Any<ClockDate>,
|
||||
},
|
||||
],
|
||||
"id": Any<String>,
|
||||
"imageIdentifierFieldMetadataId": null,
|
||||
"isActive": true,
|
||||
"isAuditLogged": true,
|
||||
"indexType": "BTREE",
|
||||
"indexWhereClause": null,
|
||||
"isCustom": true,
|
||||
"isLabelSyncedWithName": false,
|
||||
"isRemote": false,
|
||||
"isSearchable": true,
|
||||
"isSystem": false,
|
||||
"isUIReadOnly": false,
|
||||
"labelIdentifierFieldMetadataId": Any<String>,
|
||||
"labelPlural": "Rockets",
|
||||
"labelSingular": "Rocket",
|
||||
"namePlural": "rockets",
|
||||
"nameSingular": "rocket",
|
||||
"shortcut": null,
|
||||
"standardId": null,
|
||||
"standardOverrides": null,
|
||||
"targetTableName": "DEPRECATED",
|
||||
"isUnique": false,
|
||||
"name": "IDX_cb15d901e889e25d0a9acecb595",
|
||||
"objectMetadataId": Any<String>,
|
||||
"universalIdentifier": Any<String>,
|
||||
"updatedAt": Any<String>,
|
||||
"updatedAt": Any<ClockDate>,
|
||||
"workspaceId": Any<String>,
|
||||
},
|
||||
"icon": "IconBuilding",
|
||||
"id": Any<String>,
|
||||
"isActive": true,
|
||||
"isCustom": true,
|
||||
"isLabelSyncedWithName": false,
|
||||
"isNullable": true,
|
||||
"isSystem": false,
|
||||
"isUIReadOnly": false,
|
||||
"isUnique": null,
|
||||
"label": "Company",
|
||||
"morphId": null,
|
||||
"name": "company",
|
||||
"objectMetadataId": Any<String>,
|
||||
"options": null,
|
||||
"relationTargetFieldMetadataId": Any<String>,
|
||||
"relationTargetObjectMetadataId": Any<String>,
|
||||
"settings": {
|
||||
"joinColumnName": "companyId",
|
||||
"onDelete": "SET_NULL",
|
||||
"relationType": "MANY_TO_ONE",
|
||||
},
|
||||
"standardId": null,
|
||||
"standardOverrides": null,
|
||||
"type": "RELATION",
|
||||
"universalIdentifier": Any<String>,
|
||||
"updatedAt": Any<ClockDate>,
|
||||
"workspaceId": Any<String>,
|
||||
},
|
||||
],
|
||||
],
|
||||
},
|
||||
"status": "success",
|
||||
}
|
||||
`;
|
||||
|
||||
+1
-1
@@ -87,7 +87,7 @@ describe('fromCreateFieldInputToFlatFieldMetadatasToCreate MORPH_RELATION test s
|
||||
if (result.status !== 'success') {
|
||||
throw new Error('Should never occur, typecheck');
|
||||
}
|
||||
expect(result.result.length).toBe(
|
||||
expect(result.result.flatFieldMetadatas.length).toBe(
|
||||
input.rawCreateFieldInput.morphRelationsCreationPayload.length * 2,
|
||||
);
|
||||
expect(result).toMatchSnapshot(
|
||||
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
|
||||
|
||||
export const FLAT_FIELD_METADATA_EDITABLE_PROPERTIES = [
|
||||
'defaultValue',
|
||||
'description',
|
||||
'icon',
|
||||
'isActive',
|
||||
'isLabelSyncedWithName',
|
||||
'isUnique',
|
||||
'label',
|
||||
'name',
|
||||
'options',
|
||||
'settings',
|
||||
] as const satisfies (keyof FlatFieldMetadata)[];
|
||||
+2
-10
@@ -1,15 +1,7 @@
|
||||
import { FLAT_FIELD_METADATA_EDITABLE_PROPERTIES } from 'src/engine/metadata-modules/flat-field-metadata/constants/flat-field-metadata-editable-properties.constant';
|
||||
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
|
||||
|
||||
export const FLAT_FIELD_METADATA_PROPERTIES_TO_COMPARE = [
|
||||
'defaultValue',
|
||||
'description',
|
||||
'icon',
|
||||
'isActive',
|
||||
'isLabelSyncedWithName',
|
||||
'isUnique',
|
||||
'label',
|
||||
'name',
|
||||
'options',
|
||||
...FLAT_FIELD_METADATA_EDITABLE_PROPERTIES,
|
||||
'standardOverrides',
|
||||
'settings',
|
||||
] as const satisfies (keyof FlatFieldMetadata)[];
|
||||
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
import { type FLAT_FIELD_METADATA_EDITABLE_PROPERTIES } from 'src/engine/metadata-modules/flat-field-metadata/constants/flat-field-metadata-editable-properties.constant';
|
||||
|
||||
export type FlatFieldMetadataEditableProperties =
|
||||
(typeof FLAT_FIELD_METADATA_EDITABLE_PROPERTIES)[number];
|
||||
+38
-25
@@ -17,6 +17,7 @@ import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-m
|
||||
import { fromMorphRelationCreateFieldInputToFlatFieldMetadatas } from 'src/engine/metadata-modules/flat-field-metadata/utils/from-morph-relation-create-field-input-to-flat-field-metadatas.util';
|
||||
import { fromRelationCreateFieldInputToFlatFieldMetadatas } from 'src/engine/metadata-modules/flat-field-metadata/utils/from-relation-create-field-input-to-flat-field-metadatas.util';
|
||||
import { getDefaultFlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/utils/get-default-flat-field-metadata-from-create-field-input.util';
|
||||
import { type FlatIndexMetadata } from 'src/engine/metadata-modules/flat-index-metadata/types/flat-index-metadata.type';
|
||||
import { type FlatObjectMetadataMaps } from 'src/engine/metadata-modules/flat-object-metadata-maps/types/flat-object-metadata-maps.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';
|
||||
|
||||
@@ -31,7 +32,10 @@ export const fromCreateFieldInputToFlatFieldMetadatasToCreate = async ({
|
||||
workspaceId,
|
||||
existingFlatObjectMetadataMaps,
|
||||
}: FromCreateFieldInputToFlatObjectMetadataArgs): Promise<
|
||||
FieldInputTranspilationResult<FlatFieldMetadata[]>
|
||||
FieldInputTranspilationResult<{
|
||||
flatFieldMetadatas: FlatFieldMetadata[];
|
||||
indexMetadatas: FlatIndexMetadata[];
|
||||
}>
|
||||
> => {
|
||||
if (rawCreateFieldInput.isRemoteCreation) {
|
||||
return {
|
||||
@@ -99,15 +103,18 @@ export const fromCreateFieldInputToFlatFieldMetadatasToCreate = async ({
|
||||
case FieldMetadataType.RATING: {
|
||||
return {
|
||||
status: 'success',
|
||||
result: [
|
||||
{
|
||||
...commonFlatFieldMetadata,
|
||||
type: createFieldInput.type,
|
||||
settings: null,
|
||||
defaultValue: commonFlatFieldMetadata.defaultValue as string, // Could this be improved ?
|
||||
options: generateRatingOptions(),
|
||||
} satisfies FlatFieldMetadata<typeof createFieldInput.type>,
|
||||
],
|
||||
result: {
|
||||
flatFieldMetadatas: [
|
||||
{
|
||||
...commonFlatFieldMetadata,
|
||||
type: createFieldInput.type,
|
||||
settings: null,
|
||||
defaultValue: commonFlatFieldMetadata.defaultValue as string, // Could this be improved ?
|
||||
options: generateRatingOptions(),
|
||||
} satisfies FlatFieldMetadata<typeof createFieldInput.type>,
|
||||
],
|
||||
indexMetadatas: [],
|
||||
},
|
||||
};
|
||||
}
|
||||
case FieldMetadataType.SELECT:
|
||||
@@ -124,15 +131,18 @@ export const fromCreateFieldInputToFlatFieldMetadatasToCreate = async ({
|
||||
|
||||
return {
|
||||
status: 'success',
|
||||
result: [
|
||||
{
|
||||
...commonFlatFieldMetadata,
|
||||
type: createFieldInput.type,
|
||||
options,
|
||||
defaultValue: commonFlatFieldMetadata.defaultValue as string, // Could this be improved ?
|
||||
settings: null,
|
||||
} satisfies FlatFieldMetadata<typeof createFieldInput.type>,
|
||||
],
|
||||
result: {
|
||||
flatFieldMetadatas: [
|
||||
{
|
||||
...commonFlatFieldMetadata,
|
||||
type: createFieldInput.type,
|
||||
options,
|
||||
defaultValue: commonFlatFieldMetadata.defaultValue as string, // Could this be improved ?
|
||||
settings: null,
|
||||
} satisfies FlatFieldMetadata<typeof createFieldInput.type>,
|
||||
],
|
||||
indexMetadatas: [],
|
||||
},
|
||||
};
|
||||
}
|
||||
case FieldMetadataType.TS_VECTOR: {
|
||||
@@ -165,12 +175,15 @@ export const fromCreateFieldInputToFlatFieldMetadatasToCreate = async ({
|
||||
case FieldMetadataType.ARRAY: {
|
||||
return {
|
||||
status: 'success',
|
||||
result: [
|
||||
{
|
||||
...commonFlatFieldMetadata,
|
||||
type: createFieldInput.type,
|
||||
},
|
||||
],
|
||||
result: {
|
||||
flatFieldMetadatas: [
|
||||
{
|
||||
...commonFlatFieldMetadata,
|
||||
type: createFieldInput.type,
|
||||
},
|
||||
],
|
||||
indexMetadatas: [],
|
||||
},
|
||||
};
|
||||
}
|
||||
default: {
|
||||
|
||||
+104
-2
@@ -3,6 +3,7 @@ import {
|
||||
trimAndRemoveDuplicatedWhitespacesFromObjectStringProperties,
|
||||
} from 'twenty-shared/utils';
|
||||
|
||||
import { type FlatEntityMaps } from 'src/engine/core-modules/common/types/flat-entity-maps.type';
|
||||
import { type DeleteOneFieldInput } from 'src/engine/metadata-modules/field-metadata/dtos/delete-field.input';
|
||||
import {
|
||||
FieldMetadataException,
|
||||
@@ -10,17 +11,27 @@ import {
|
||||
} from 'src/engine/metadata-modules/field-metadata/field-metadata.exception';
|
||||
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
|
||||
import { computeFlatFieldMetadataRelatedFlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/utils/compute-flat-field-metadata-related-flat-field-metadata.util';
|
||||
import { type FlatIndexMetadata } from 'src/engine/metadata-modules/flat-index-metadata/types/flat-index-metadata.type';
|
||||
import { type FlatObjectMetadataMaps } from 'src/engine/metadata-modules/flat-object-metadata-maps/types/flat-object-metadata-maps.type';
|
||||
import { findFlatFieldMetadataInFlatObjectMetadataMapsWithOnlyFieldId } from 'src/engine/metadata-modules/flat-object-metadata-maps/utils/find-flat-field-metadata-in-flat-object-metadata-maps-with-field-id-only.util';
|
||||
import { findFlatObjectMetadataInFlatObjectMetadataMapsOrThrow } from 'src/engine/metadata-modules/flat-object-metadata-maps/utils/find-flat-object-metadata-in-flat-object-metadata-maps-or-throw.util';
|
||||
import { generateFlatIndexMetadataWithNameOrThrow } from 'src/engine/metadata-modules/index-metadata/utils/generate-flat-index.util';
|
||||
|
||||
type FromDeleteFieldInputToFlatFieldMetadatasToDeleteArgs = {
|
||||
existingFlatObjectMetadataMaps: FlatObjectMetadataMaps;
|
||||
existingFlatIndexMaps: FlatEntityMaps<FlatIndexMetadata>;
|
||||
deleteOneFieldInput: DeleteOneFieldInput;
|
||||
};
|
||||
// TODO refactor as a side effect service
|
||||
export const fromDeleteFieldInputToFlatFieldMetadatasToDelete = ({
|
||||
existingFlatObjectMetadataMaps,
|
||||
deleteOneFieldInput: rawDeleteOneInput,
|
||||
}: FromDeleteFieldInputToFlatFieldMetadatasToDeleteArgs): FlatFieldMetadata[] => {
|
||||
existingFlatIndexMaps,
|
||||
}: FromDeleteFieldInputToFlatFieldMetadatasToDeleteArgs): {
|
||||
flatFieldMetadatasToDelete: FlatFieldMetadata[];
|
||||
flatIndexesToUpdate: FlatIndexMetadata[];
|
||||
flatIndexesToDelete: FlatIndexMetadata[];
|
||||
} => {
|
||||
const { id: fieldMetadataToDeleteId } =
|
||||
trimAndRemoveDuplicatedWhitespacesFromObjectStringProperties(
|
||||
rawDeleteOneInput,
|
||||
@@ -46,5 +57,96 @@ export const fromDeleteFieldInputToFlatFieldMetadatasToDelete = ({
|
||||
flatObjectMetadataMaps: existingFlatObjectMetadataMaps,
|
||||
});
|
||||
|
||||
return [flatFieldMetadataToDelete, ...relatedFlatFieldMetadataToDelete];
|
||||
const flatFieldMetadatasToDelete = [
|
||||
flatFieldMetadataToDelete,
|
||||
...relatedFlatFieldMetadataToDelete,
|
||||
];
|
||||
|
||||
const flatIndexMap = new Map<string, FlatIndexMetadata>();
|
||||
const allFlatIndexes = Object.values(existingFlatIndexMaps.byId).filter(
|
||||
isDefined,
|
||||
);
|
||||
|
||||
for (const flatFieldMetadata of flatFieldMetadatasToDelete) {
|
||||
allFlatIndexes.forEach((flatIndex) => {
|
||||
const flatIndexFromMap = flatIndexMap.get(flatIndex.id);
|
||||
|
||||
if (isDefined(flatIndexFromMap)) {
|
||||
const updatedFlatIndexFields =
|
||||
flatIndexFromMap.flatIndexFieldMetadatas.filter(
|
||||
(flatIndexField) =>
|
||||
flatIndexField.fieldMetadataId !== flatFieldMetadata.id,
|
||||
);
|
||||
|
||||
flatIndexMap.set(flatIndexFromMap.id, {
|
||||
...flatIndexFromMap,
|
||||
flatIndexFieldMetadatas: updatedFlatIndexFields,
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (
|
||||
flatIndex.objectMetadataId !== flatFieldMetadata.objectMetadataId ||
|
||||
!flatIndex.flatIndexFieldMetadatas.some(
|
||||
(flatIndexField) =>
|
||||
flatIndexField.fieldMetadataId === flatFieldMetadata.id,
|
||||
)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
const updatedFlatIndexFields = flatIndex.flatIndexFieldMetadatas.filter(
|
||||
(flatIndexField) =>
|
||||
flatIndexField.fieldMetadataId !== flatFieldMetadata.id,
|
||||
);
|
||||
|
||||
flatIndexMap.set(flatIndex.id, {
|
||||
...flatIndex,
|
||||
flatIndexFieldMetadatas: updatedFlatIndexFields,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
const { flatIndexesToDelete, flatIndexesToUpdate } = [
|
||||
...flatIndexMap.values(),
|
||||
].reduce<{
|
||||
flatIndexesToUpdate: FlatIndexMetadata[];
|
||||
flatIndexesToDelete: FlatIndexMetadata[];
|
||||
}>(
|
||||
(acc, flatIndex) => {
|
||||
if (flatIndex.flatIndexFieldMetadatas.length === 0) {
|
||||
return {
|
||||
...acc,
|
||||
flatIndexesToDelete: [...acc.flatIndexesToDelete, flatIndex],
|
||||
};
|
||||
}
|
||||
|
||||
const flatObjectMetadata =
|
||||
findFlatObjectMetadataInFlatObjectMetadataMapsOrThrow({
|
||||
flatObjectMetadataMaps: existingFlatObjectMetadataMaps,
|
||||
objectMetadataId: flatIndex.objectMetadataId,
|
||||
});
|
||||
|
||||
const newIndex = generateFlatIndexMetadataWithNameOrThrow({
|
||||
flatObjectMetadata,
|
||||
flatIndex,
|
||||
});
|
||||
|
||||
return {
|
||||
...acc,
|
||||
flatIndexesToUpdate: [...acc.flatIndexesToUpdate, newIndex],
|
||||
};
|
||||
},
|
||||
{
|
||||
flatIndexesToDelete: [],
|
||||
flatIndexesToUpdate: [],
|
||||
},
|
||||
);
|
||||
|
||||
return {
|
||||
flatFieldMetadatasToDelete,
|
||||
flatIndexesToDelete,
|
||||
flatIndexesToUpdate,
|
||||
};
|
||||
};
|
||||
|
||||
+30
-19
@@ -5,13 +5,13 @@ import { v4 } from 'uuid';
|
||||
|
||||
import { type CreateFieldInput } from 'src/engine/metadata-modules/field-metadata/dtos/create-field.input';
|
||||
import { FieldMetadataExceptionCode } from 'src/engine/metadata-modules/field-metadata/field-metadata.exception';
|
||||
import { type MorphOrRelationFieldMetadataType } from 'src/engine/metadata-modules/field-metadata/types/morph-or-relation-field-metadata-type.type';
|
||||
import { computeMorphOrRelationFieldJoinColumnName } from 'src/engine/metadata-modules/field-metadata/utils/compute-morph-or-relation-field-join-column-name.util';
|
||||
import { computeMorphRelationFieldName } from 'src/engine/metadata-modules/field-metadata/utils/compute-morph-relation-field-name.util';
|
||||
import { type FieldInputTranspilationResult } from 'src/engine/metadata-modules/flat-field-metadata/types/field-input-transpilation-result.type';
|
||||
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
|
||||
import { generateMorphOrRelationFlatFieldMetadataPair } from 'src/engine/metadata-modules/flat-field-metadata/utils/generate-morph-or-relation-flat-field-metadata-pair.util';
|
||||
import { validateMorphRelationCreationPayload } from 'src/engine/metadata-modules/flat-field-metadata/validators/utils/validate-morph-relation-creation-payload.util';
|
||||
import { type FlatIndexMetadata } from 'src/engine/metadata-modules/flat-index-metadata/types/flat-index-metadata.type';
|
||||
import { type FlatObjectMetadataMaps } from 'src/engine/metadata-modules/flat-object-metadata-maps/types/flat-object-metadata-maps.type';
|
||||
import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type';
|
||||
|
||||
@@ -29,9 +29,10 @@ export const fromMorphRelationCreateFieldInputToFlatFieldMetadatas = async ({
|
||||
sourceFlatObjectMetadata,
|
||||
workspaceId,
|
||||
}: FromMorphRelationCreateFieldInputToFlatFieldMetadatasArgs): Promise<
|
||||
FieldInputTranspilationResult<
|
||||
FlatFieldMetadata<MorphOrRelationFieldMetadataType>[]
|
||||
>
|
||||
FieldInputTranspilationResult<{
|
||||
flatFieldMetadatas: FlatFieldMetadata[];
|
||||
indexMetadatas: FlatIndexMetadata[];
|
||||
}>
|
||||
> => {
|
||||
const rawMorphCreationPayload =
|
||||
createFieldInput.morphRelationsCreationPayload;
|
||||
@@ -65,8 +66,8 @@ export const fromMorphRelationCreateFieldInputToFlatFieldMetadatas = async ({
|
||||
const morphRelationCreationPayload =
|
||||
morphRelationCreationPayloadValidation.result;
|
||||
const morphId = v4();
|
||||
const flatFieldMetadatas = morphRelationCreationPayload.flatMap(
|
||||
({ relationCreationPayload, targetFlatObjectMetadata }) => {
|
||||
const flatFieldsAndIndexes = morphRelationCreationPayload.reduce(
|
||||
(acc, { relationCreationPayload, targetFlatObjectMetadata }) => {
|
||||
const currentMorphRelationFieldName = computeMorphRelationFieldName({
|
||||
fieldName: createFieldInput.name,
|
||||
relationType: relationCreationPayload.type,
|
||||
@@ -77,23 +78,33 @@ export const fromMorphRelationCreateFieldInputToFlatFieldMetadatas = async ({
|
||||
name: currentMorphRelationFieldName,
|
||||
});
|
||||
|
||||
return generateMorphOrRelationFlatFieldMetadataPair({
|
||||
createFieldInput: {
|
||||
...createFieldInput,
|
||||
relationCreationPayload,
|
||||
name: currentMorphRelationFieldName,
|
||||
},
|
||||
sourceFlatObjectMetadataJoinColumnName,
|
||||
sourceFlatObjectMetadata,
|
||||
targetFlatObjectMetadata,
|
||||
workspaceId,
|
||||
morphId,
|
||||
});
|
||||
const { flatFieldMetadatas, indexMetadatas } =
|
||||
generateMorphOrRelationFlatFieldMetadataPair({
|
||||
createFieldInput: {
|
||||
...createFieldInput,
|
||||
relationCreationPayload,
|
||||
name: currentMorphRelationFieldName,
|
||||
},
|
||||
sourceFlatObjectMetadataJoinColumnName,
|
||||
sourceFlatObjectMetadata,
|
||||
targetFlatObjectMetadata,
|
||||
workspaceId,
|
||||
morphId,
|
||||
});
|
||||
|
||||
return {
|
||||
indexMetadatas: [...acc.indexMetadatas, ...indexMetadatas],
|
||||
flatFieldMetadatas: [...acc.flatFieldMetadatas, ...flatFieldMetadatas],
|
||||
};
|
||||
},
|
||||
{
|
||||
indexMetadatas: [],
|
||||
flatFieldMetadatas: [],
|
||||
},
|
||||
);
|
||||
|
||||
return {
|
||||
status: 'success',
|
||||
result: flatFieldMetadatas,
|
||||
result: flatFieldsAndIndexes,
|
||||
};
|
||||
};
|
||||
|
||||
+7
-6
@@ -6,8 +6,10 @@ import { type CreateFieldInput } from 'src/engine/metadata-modules/field-metadat
|
||||
import { FieldMetadataExceptionCode } from 'src/engine/metadata-modules/field-metadata/field-metadata.exception';
|
||||
import { computeMorphOrRelationFieldJoinColumnName } from 'src/engine/metadata-modules/field-metadata/utils/compute-morph-or-relation-field-join-column-name.util';
|
||||
import { type FieldInputTranspilationResult } from 'src/engine/metadata-modules/flat-field-metadata/types/field-input-transpilation-result.type';
|
||||
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
|
||||
import { generateMorphOrRelationFlatFieldMetadataPair } from 'src/engine/metadata-modules/flat-field-metadata/utils/generate-morph-or-relation-flat-field-metadata-pair.util';
|
||||
import {
|
||||
generateMorphOrRelationFlatFieldMetadataPair,
|
||||
type SourceTargetMorphOrRelationFlatFieldAndFlatIndex,
|
||||
} from 'src/engine/metadata-modules/flat-field-metadata/utils/generate-morph-or-relation-flat-field-metadata-pair.util';
|
||||
import { validateRelationCreationPayload } from 'src/engine/metadata-modules/flat-field-metadata/validators/utils/validate-relation-creation-payload.util';
|
||||
import { type FlatObjectMetadataMaps } from 'src/engine/metadata-modules/flat-object-metadata-maps/types/flat-object-metadata-maps.type';
|
||||
import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type';
|
||||
@@ -26,7 +28,7 @@ export const fromRelationCreateFieldInputToFlatFieldMetadatas = async ({
|
||||
createFieldInput,
|
||||
workspaceId,
|
||||
}: FromRelationCreateFieldInputToFlatFieldMetadataArgs): Promise<
|
||||
FieldInputTranspilationResult<FlatFieldMetadata<FieldMetadataType.RELATION>[]>
|
||||
FieldInputTranspilationResult<SourceTargetMorphOrRelationFlatFieldAndFlatIndex>
|
||||
> => {
|
||||
const rawCreationPayload = createFieldInput.relationCreationPayload;
|
||||
|
||||
@@ -53,7 +55,7 @@ export const fromRelationCreateFieldInputToFlatFieldMetadatas = async ({
|
||||
const { relationCreationPayload, targetFlatObjectMetadata } =
|
||||
relationValidationResult.result;
|
||||
|
||||
const flatFieldMetadatas = generateMorphOrRelationFlatFieldMetadataPair({
|
||||
const generateResult = generateMorphOrRelationFlatFieldMetadataPair({
|
||||
createFieldInput: {
|
||||
...createFieldInput,
|
||||
relationCreationPayload,
|
||||
@@ -69,7 +71,6 @@ export const fromRelationCreateFieldInputToFlatFieldMetadatas = async ({
|
||||
|
||||
return {
|
||||
status: 'success',
|
||||
result:
|
||||
flatFieldMetadatas as FlatFieldMetadata<FieldMetadataType.RELATION>[],
|
||||
result: generateResult,
|
||||
};
|
||||
};
|
||||
|
||||
+120
-48
@@ -5,71 +5,120 @@ import {
|
||||
} from 'twenty-shared/utils';
|
||||
import { v4 } from 'uuid';
|
||||
|
||||
import { type AllFlatEntityMaps } from 'src/engine/core-modules/common/types/all-flat-entity-maps.type';
|
||||
import { FIELD_METADATA_STANDARD_OVERRIDES_PROPERTIES } from 'src/engine/metadata-modules/field-metadata/constants/field-metadata-standard-overrides-properties.constant';
|
||||
import { type UpdateFieldInput } from 'src/engine/metadata-modules/field-metadata/dtos/update-field.input';
|
||||
import { FieldMetadataExceptionCode } from 'src/engine/metadata-modules/field-metadata/field-metadata.exception';
|
||||
import { type FieldMetadataStandardOverridesProperties } from 'src/engine/metadata-modules/field-metadata/types/field-metadata-standard-overrides-properties.type';
|
||||
import { FLAT_FIELD_METADATA_PROPERTIES_TO_COMPARE } from 'src/engine/metadata-modules/flat-field-metadata/constants/flat-field-metadata-properties-to-compare.constant';
|
||||
import { FLAT_FIELD_METADATA_EDITABLE_PROPERTIES } from 'src/engine/metadata-modules/flat-field-metadata/constants/flat-field-metadata-editable-properties.constant';
|
||||
import { type FieldInputTranspilationResult } from 'src/engine/metadata-modules/flat-field-metadata/types/field-input-transpilation-result.type';
|
||||
import { type FlatFieldMetadataPropertiesToCompare } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata-properties-to-compare.type';
|
||||
import { type FlatFieldMetadataEditableProperties } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata-editable-properties.constant';
|
||||
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
|
||||
import { computeFlatFieldMetadataRelatedFlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/utils/compute-flat-field-metadata-related-flat-field-metadata.util';
|
||||
import { type FlatObjectMetadataMaps } from 'src/engine/metadata-modules/flat-object-metadata-maps/types/flat-object-metadata-maps.type';
|
||||
import { recomputeIndexOnFlatFieldMetadataNameUpdate } from 'src/engine/metadata-modules/flat-field-metadata/utils/recompute-index-on-flat-field-metadata-name-update.util';
|
||||
import { type FlatIndexMetadata } from 'src/engine/metadata-modules/flat-index-metadata/types/flat-index-metadata.type';
|
||||
import { findFlatFieldMetadataInFlatObjectMetadataMapsWithOnlyFieldId } from 'src/engine/metadata-modules/flat-object-metadata-maps/utils/find-flat-field-metadata-in-flat-object-metadata-maps-with-field-id-only.util';
|
||||
import { findFlatObjectMetadataInFlatObjectMetadataMapsOrThrow } from 'src/engine/metadata-modules/flat-object-metadata-maps/utils/find-flat-object-metadata-in-flat-object-metadata-maps-or-throw.util';
|
||||
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 { isStandardMetadata } from 'src/engine/metadata-modules/utils/is-standard-metadata.util';
|
||||
|
||||
const applyUpdatesToFlatFieldMetadata = ({
|
||||
updatedEditableFieldProperties,
|
||||
flatFieldMetadata,
|
||||
}: {
|
||||
updatedEditableFieldProperties: SanitizedUpdateFieldInput;
|
||||
type UpdatedFlatFieldMetadataAndIndexToUpdate = {
|
||||
flatFieldMetadata: FlatFieldMetadata;
|
||||
}) => {
|
||||
return fieldMetadataEditableProperties.reduce((acc, property) => {
|
||||
let newValue = updatedEditableFieldProperties[property];
|
||||
|
||||
if (property === 'options' && isDefined(newValue)) {
|
||||
newValue = updatedEditableFieldProperties[property]?.map((option) => ({
|
||||
id: v4(),
|
||||
...option,
|
||||
}));
|
||||
}
|
||||
|
||||
return {
|
||||
...acc,
|
||||
...(newValue !== undefined ? { [property]: newValue } : {}),
|
||||
};
|
||||
}, flatFieldMetadata);
|
||||
flatIndexMetadataToUpdate: FlatIndexMetadata[];
|
||||
};
|
||||
|
||||
const fieldMetadataEditableProperties =
|
||||
FLAT_FIELD_METADATA_PROPERTIES_TO_COMPARE.filter(
|
||||
(
|
||||
property,
|
||||
): property is Exclude<
|
||||
FlatFieldMetadataPropertiesToCompare,
|
||||
'standardOverrides'
|
||||
> => property !== 'standardOverrides',
|
||||
);
|
||||
|
||||
type SanitizedUpdateFieldInput = ReturnType<
|
||||
typeof extractAndSanitizeObjectStringFields<
|
||||
UpdateFieldInput,
|
||||
(typeof fieldMetadataEditableProperties)[number][]
|
||||
FlatFieldMetadataEditableProperties[]
|
||||
>
|
||||
>;
|
||||
|
||||
type ApplyUpdatesToFlatFieldMetadataArgs = {
|
||||
updatedEditableFieldProperties: SanitizedUpdateFieldInput;
|
||||
fromFlatFieldMetadata: FlatFieldMetadata;
|
||||
} & Pick<AllFlatEntityMaps, 'flatIndexMaps' | 'flatObjectMetadataMaps'>;
|
||||
|
||||
const applyUpdatesToFlatFieldMetadata = ({
|
||||
updatedEditableFieldProperties,
|
||||
fromFlatFieldMetadata,
|
||||
flatObjectMetadataMaps,
|
||||
flatIndexMaps,
|
||||
}: ApplyUpdatesToFlatFieldMetadataArgs) => {
|
||||
return FLAT_FIELD_METADATA_EDITABLE_PROPERTIES.reduce<UpdatedFlatFieldMetadataAndIndexToUpdate>(
|
||||
({ flatFieldMetadata, flatIndexMetadataToUpdate }, property) => {
|
||||
const updatedPropertyValue = updatedEditableFieldProperties[property];
|
||||
const isPropertyUpdated =
|
||||
updatedPropertyValue !== undefined &&
|
||||
flatFieldMetadata[property] !== updatedPropertyValue;
|
||||
|
||||
if (!isPropertyUpdated) {
|
||||
return {
|
||||
flatFieldMetadata,
|
||||
flatIndexMetadataToUpdate,
|
||||
};
|
||||
}
|
||||
const updatedFlatFieldMetadata = {
|
||||
...flatFieldMetadata,
|
||||
[property]: updatedPropertyValue,
|
||||
};
|
||||
|
||||
if (property === 'options') {
|
||||
updatedFlatFieldMetadata.options =
|
||||
updatedEditableFieldProperties[property]?.map((option) => ({
|
||||
id: v4(),
|
||||
...option,
|
||||
})) ?? [];
|
||||
}
|
||||
|
||||
let newFlatIndexMetadataToUpdate: FlatIndexMetadata[] = [];
|
||||
|
||||
if (property === 'name') {
|
||||
const flatObjectMetadata =
|
||||
findFlatObjectMetadataInFlatObjectMetadataMapsOrThrow({
|
||||
flatObjectMetadataMaps,
|
||||
objectMetadataId: flatFieldMetadata.objectMetadataId,
|
||||
});
|
||||
|
||||
newFlatIndexMetadataToUpdate =
|
||||
recomputeIndexOnFlatFieldMetadataNameUpdate({
|
||||
flatObjectMetadata,
|
||||
fromFlatFieldMetadata,
|
||||
toFlatFieldMetadata: {
|
||||
name: updatedFlatFieldMetadata.name,
|
||||
},
|
||||
flatIndexMaps,
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
flatFieldMetadata: updatedFlatFieldMetadata,
|
||||
flatIndexMetadataToUpdate: [
|
||||
...flatIndexMetadataToUpdate,
|
||||
...newFlatIndexMetadataToUpdate,
|
||||
],
|
||||
};
|
||||
},
|
||||
{
|
||||
flatFieldMetadata: structuredClone(fromFlatFieldMetadata),
|
||||
flatIndexMetadataToUpdate: [],
|
||||
},
|
||||
);
|
||||
};
|
||||
|
||||
type FromUpdateFieldInputToFlatFieldMetadataArgs = {
|
||||
existingFlatObjectMetadataMaps: FlatObjectMetadataMaps;
|
||||
updateFieldInput: UpdateFieldInput;
|
||||
} & Pick<AllFlatEntityMaps, 'flatObjectMetadataMaps' | 'flatIndexMaps'>;
|
||||
|
||||
type FlatFieldMetadataAndIndexToUpdate = {
|
||||
flatFieldMetadatasToUpdate: FlatFieldMetadata[];
|
||||
flatIndexMetadatasToUpdate: FlatIndexMetadata[];
|
||||
};
|
||||
export const fromUpdateFieldInputToFlatFieldMetadata = ({
|
||||
existingFlatObjectMetadataMaps,
|
||||
flatIndexMaps,
|
||||
flatObjectMetadataMaps: existingFlatObjectMetadataMaps,
|
||||
updateFieldInput: rawUpdateFieldInput,
|
||||
}: FromUpdateFieldInputToFlatFieldMetadataArgs): FieldInputTranspilationResult<
|
||||
FlatFieldMetadata[]
|
||||
> => {
|
||||
}: FromUpdateFieldInputToFlatFieldMetadataArgs): FieldInputTranspilationResult<FlatFieldMetadataAndIndexToUpdate> => {
|
||||
const updateFieldInputInformalProperties =
|
||||
extractAndSanitizeObjectStringFields(rawUpdateFieldInput, [
|
||||
'objectMetadataId',
|
||||
@@ -77,7 +126,7 @@ export const fromUpdateFieldInputToFlatFieldMetadata = ({
|
||||
]);
|
||||
const updatedEditableFieldProperties = extractAndSanitizeObjectStringFields(
|
||||
rawUpdateFieldInput,
|
||||
fieldMetadataEditableProperties,
|
||||
FLAT_FIELD_METADATA_EDITABLE_PROPERTIES,
|
||||
);
|
||||
|
||||
const existingFlatFieldMetadataToUpdate =
|
||||
@@ -168,7 +217,10 @@ export const fromUpdateFieldInputToFlatFieldMetadata = ({
|
||||
|
||||
return {
|
||||
status: 'success',
|
||||
result: [updatedStandardFlatFieldMetadata],
|
||||
result: {
|
||||
flatFieldMetadatasToUpdate: [updatedStandardFlatFieldMetadata],
|
||||
flatIndexMetadatasToUpdate: [],
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -184,12 +236,32 @@ export const fromUpdateFieldInputToFlatFieldMetadata = ({
|
||||
];
|
||||
|
||||
const optimisticiallyUpdatedFlatFieldMetadatas =
|
||||
flatFieldMetadatasToUpdate.map((flatFieldMetadata) => {
|
||||
return applyUpdatesToFlatFieldMetadata({
|
||||
flatFieldMetadata,
|
||||
updatedEditableFieldProperties,
|
||||
});
|
||||
});
|
||||
flatFieldMetadatasToUpdate.reduce<FlatFieldMetadataAndIndexToUpdate>(
|
||||
(acc, fromFlatFieldMetadata) => {
|
||||
const { flatFieldMetadata, flatIndexMetadataToUpdate } =
|
||||
applyUpdatesToFlatFieldMetadata({
|
||||
flatObjectMetadataMaps: existingFlatObjectMetadataMaps,
|
||||
fromFlatFieldMetadata,
|
||||
flatIndexMaps,
|
||||
updatedEditableFieldProperties,
|
||||
});
|
||||
|
||||
return {
|
||||
flatFieldMetadatasToUpdate: [
|
||||
...acc.flatFieldMetadatasToUpdate,
|
||||
flatFieldMetadata,
|
||||
],
|
||||
flatIndexMetadatasToUpdate: [
|
||||
...acc.flatIndexMetadatasToUpdate,
|
||||
...flatIndexMetadataToUpdate,
|
||||
],
|
||||
};
|
||||
},
|
||||
{
|
||||
flatFieldMetadatasToUpdate: [],
|
||||
flatIndexMetadatasToUpdate: [],
|
||||
},
|
||||
);
|
||||
|
||||
return {
|
||||
status: 'success',
|
||||
|
||||
+70
-8
@@ -6,7 +6,10 @@ import { type MorphOrRelationFieldMetadataType } from 'src/engine/metadata-modul
|
||||
import { computeMorphOrRelationFieldJoinColumnName } from 'src/engine/metadata-modules/field-metadata/utils/compute-morph-or-relation-field-join-column-name.util';
|
||||
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
|
||||
import { getDefaultFlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/utils/get-default-flat-field-metadata-from-create-field-input.util';
|
||||
import { type FlatIndexMetadata } from 'src/engine/metadata-modules/flat-index-metadata/types/flat-index-metadata.type';
|
||||
import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type';
|
||||
import { IndexType } from 'src/engine/metadata-modules/index-metadata/types/indexType.types';
|
||||
import { generateFlatIndexMetadataWithNameOrThrow } from 'src/engine/metadata-modules/index-metadata/utils/generate-flat-index.util';
|
||||
import { RelationOnDeleteAction } from 'src/engine/metadata-modules/relation-metadata/relation-on-delete-action.type';
|
||||
import { computeMetadataNameFromLabel } from 'src/engine/metadata-modules/utils/validate-name-and-label-are-sync-or-throw.util';
|
||||
|
||||
@@ -42,6 +45,12 @@ type GenerateMorphOrRelationFlatFieldMetadataPairArgs = {
|
||||
workspaceId: string;
|
||||
morphId?: string | null;
|
||||
};
|
||||
|
||||
export type SourceTargetMorphOrRelationFlatFieldAndFlatIndex = {
|
||||
flatFieldMetadatas: FlatFieldMetadata[];
|
||||
indexMetadatas: FlatIndexMetadata[];
|
||||
};
|
||||
|
||||
export const generateMorphOrRelationFlatFieldMetadataPair = ({
|
||||
createFieldInput,
|
||||
sourceFlatObjectMetadata,
|
||||
@@ -49,7 +58,7 @@ export const generateMorphOrRelationFlatFieldMetadataPair = ({
|
||||
workspaceId,
|
||||
sourceFlatObjectMetadataJoinColumnName,
|
||||
morphId = null,
|
||||
}: GenerateMorphOrRelationFlatFieldMetadataPairArgs): FlatFieldMetadata<MorphOrRelationFieldMetadataType>[] => {
|
||||
}: GenerateMorphOrRelationFlatFieldMetadataPairArgs): SourceTargetMorphOrRelationFlatFieldAndFlatIndex => {
|
||||
const { relationCreationPayload } = createFieldInput;
|
||||
|
||||
const sourceFlatFieldMetadataSettings =
|
||||
@@ -117,11 +126,64 @@ export const generateMorphOrRelationFlatFieldMetadataPair = ({
|
||||
flatRelationTargetObjectMetadata: sourceFlatObjectMetadata,
|
||||
};
|
||||
|
||||
return [
|
||||
{
|
||||
...sourceFlatFieldMetadata,
|
||||
flatRelationTargetFieldMetadata: targetFlatFieldMetadata,
|
||||
},
|
||||
targetFlatFieldMetadata,
|
||||
] satisfies FlatFieldMetadata<MorphOrRelationFieldMetadataType>[];
|
||||
const indexId = v4();
|
||||
const createdAt = new Date();
|
||||
const indexMetadata: FlatIndexMetadata =
|
||||
generateFlatIndexMetadataWithNameOrThrow({
|
||||
flatIndex: {
|
||||
createdAt,
|
||||
flatIndexFieldMetadatas: [
|
||||
{
|
||||
createdAt,
|
||||
fieldMetadataId:
|
||||
relationCreationPayload.type === RelationType.MANY_TO_ONE
|
||||
? sourceFlatFieldMetadata.id
|
||||
: targetFlatFieldMetadata.id,
|
||||
id: v4(),
|
||||
indexMetadataId: indexId,
|
||||
order: 0,
|
||||
updatedAt: createdAt,
|
||||
},
|
||||
],
|
||||
id: indexId,
|
||||
indexType: IndexType.BTREE,
|
||||
indexWhereClause: null,
|
||||
isCustom: true,
|
||||
isUnique: false,
|
||||
objectMetadataId:
|
||||
relationCreationPayload.type === RelationType.MANY_TO_ONE
|
||||
? sourceFlatObjectMetadata.id
|
||||
: targetFlatObjectMetadata.id,
|
||||
universalIdentifier: indexId,
|
||||
updatedAt: createdAt,
|
||||
workspaceId,
|
||||
},
|
||||
flatObjectMetadata: (relationCreationPayload.type ===
|
||||
RelationType.MANY_TO_ONE
|
||||
? {
|
||||
...sourceFlatObjectMetadata,
|
||||
flatFieldMetadatas: [
|
||||
...sourceFlatObjectMetadata.flatFieldMetadatas,
|
||||
sourceFlatFieldMetadata,
|
||||
],
|
||||
}
|
||||
: {
|
||||
...targetFlatObjectMetadata,
|
||||
flatFieldMetadatas: [
|
||||
...targetFlatObjectMetadata.flatFieldMetadatas,
|
||||
targetFlatFieldMetadata,
|
||||
],
|
||||
}) as FlatObjectMetadata,
|
||||
});
|
||||
|
||||
return {
|
||||
flatFieldMetadatas: [
|
||||
{
|
||||
...sourceFlatFieldMetadata,
|
||||
flatRelationTargetFieldMetadata: targetFlatFieldMetadata,
|
||||
},
|
||||
targetFlatFieldMetadata,
|
||||
],
|
||||
indexMetadatas: [indexMetadata],
|
||||
};
|
||||
};
|
||||
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { type AllFlatEntityMaps } from 'src/engine/core-modules/common/types/all-flat-entity-maps.type';
|
||||
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
|
||||
import { type FlatIndexMetadata } from 'src/engine/metadata-modules/flat-index-metadata/types/flat-index-metadata.type';
|
||||
import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type';
|
||||
import { generateFlatIndexMetadataWithNameOrThrow } from 'src/engine/metadata-modules/index-metadata/utils/generate-flat-index.util';
|
||||
|
||||
type RecomputeIndexOnFlatFieldMetadataNameUpdateArgs = {
|
||||
flatObjectMetadata: FlatObjectMetadata;
|
||||
fromFlatFieldMetadata: FlatFieldMetadata;
|
||||
toFlatFieldMetadata: Pick<FlatFieldMetadata, 'name'>;
|
||||
} & Pick<AllFlatEntityMaps, 'flatIndexMaps'>;
|
||||
|
||||
export const recomputeIndexOnFlatFieldMetadataNameUpdate = ({
|
||||
fromFlatFieldMetadata,
|
||||
toFlatFieldMetadata,
|
||||
flatObjectMetadata,
|
||||
flatIndexMaps,
|
||||
}: RecomputeIndexOnFlatFieldMetadataNameUpdateArgs): FlatIndexMetadata[] => {
|
||||
const relatedFlatIndexMetadata = Object.values(flatIndexMaps.byId).filter(
|
||||
(flatIndexMetadata): flatIndexMetadata is FlatIndexMetadata =>
|
||||
isDefined(flatIndexMetadata) &&
|
||||
flatIndexMetadata.objectMetadataId ===
|
||||
fromFlatFieldMetadata.objectMetadataId &&
|
||||
flatIndexMetadata.flatIndexFieldMetadatas.some(
|
||||
(flatIndexField) =>
|
||||
flatIndexField.fieldMetadataId === fromFlatFieldMetadata.id,
|
||||
),
|
||||
);
|
||||
|
||||
if (relatedFlatIndexMetadata.length === 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const optimisticFlatObjectMetadata = {
|
||||
...flatObjectMetadata,
|
||||
flatFieldMetadatas: flatObjectMetadata.flatFieldMetadatas.map(
|
||||
(flatFieldMetadata) => {
|
||||
if (flatFieldMetadata.id === fromFlatFieldMetadata.id) {
|
||||
return {
|
||||
...flatFieldMetadata,
|
||||
name: toFlatFieldMetadata.name,
|
||||
};
|
||||
}
|
||||
|
||||
return flatFieldMetadata;
|
||||
},
|
||||
),
|
||||
};
|
||||
|
||||
return relatedFlatIndexMetadata.map<FlatIndexMetadata>((flatIndex) => {
|
||||
const newIndex = generateFlatIndexMetadataWithNameOrThrow({
|
||||
flatObjectMetadata: optimisticFlatObjectMetadata,
|
||||
flatIndex,
|
||||
});
|
||||
|
||||
return newIndex;
|
||||
});
|
||||
};
|
||||
+9
-7
@@ -9,16 +9,18 @@ export type IndexMetadataRelationProperties =
|
||||
MetadataEntitiesRelationTarget
|
||||
>;
|
||||
|
||||
export type FlatIndexFieldMetadata = Omit<
|
||||
IndexFieldMetadataEntity,
|
||||
ExtractRecordTypeOrmRelationProperties<
|
||||
IndexFieldMetadataEntity,
|
||||
MetadataEntitiesRelationTarget
|
||||
>
|
||||
>;
|
||||
|
||||
export type FlatIndexMetadata = Omit<
|
||||
IndexMetadataEntity,
|
||||
IndexMetadataRelationProperties
|
||||
> & {
|
||||
universalIdentifier: string;
|
||||
flatIndexFieldMetadatas: Omit<
|
||||
IndexFieldMetadataEntity,
|
||||
ExtractRecordTypeOrmRelationProperties<
|
||||
IndexFieldMetadataEntity,
|
||||
MetadataEntitiesRelationTarget
|
||||
>
|
||||
>[];
|
||||
flatIndexFieldMetadatas: FlatIndexFieldMetadata[];
|
||||
};
|
||||
|
||||
-1
@@ -24,6 +24,5 @@ export const ATTACHMENT_FLAT_OBJECT_MOCK = getFlatObjectMetadataMock({
|
||||
isLabelSyncedWithName: false,
|
||||
workspaceId: '20202020-1c25-4d02-bf25-6aeccf7ea419',
|
||||
universalIdentifier: '20202020-bd3d-4c60-8dca-571c71d4447a',
|
||||
flatIndexMetadatas: [],
|
||||
flatFieldMetadatas: Object.values(ATTACHMENT_FLAT_FIELDS_MOCK),
|
||||
});
|
||||
|
||||
-1
@@ -24,6 +24,5 @@ export const COMPANY_FLAT_OBJECT_MOCK = getFlatObjectMetadataMock({
|
||||
isLabelSyncedWithName: false,
|
||||
workspaceId: '20202020-1c25-4d02-bf25-6aeccf7ea419',
|
||||
universalIdentifier: '20202020-b374-4779-a561-80086cb2e17f',
|
||||
flatIndexMetadatas: [],
|
||||
flatFieldMetadatas: Object.values(COMPANY_FLAT_FIELDS_MOCK),
|
||||
});
|
||||
|
||||
-1
@@ -24,6 +24,5 @@ export const FAVORITE_FLAT_OBJECT_MOCK = getFlatObjectMetadataMock({
|
||||
isLabelSyncedWithName: false,
|
||||
workspaceId: '20202020-1c25-4d02-bf25-6aeccf7ea419',
|
||||
universalIdentifier: '20202020-ab56-4e05-92a3-e2414a499860',
|
||||
flatIndexMetadatas: [],
|
||||
flatFieldMetadatas: Object.values(FAVORITE_FLAT_FIELDS_MOCK),
|
||||
});
|
||||
|
||||
-1
@@ -24,6 +24,5 @@ export const FAVORITE_FOLDER_FLAT_OBJECT_MOCK = getFlatObjectMetadataMock({
|
||||
isLabelSyncedWithName: false,
|
||||
workspaceId: '20202020-1c25-4d02-bf25-6aeccf7ea419',
|
||||
universalIdentifier: '20202020-7cf8-401f-8211-a9587d27fd2d',
|
||||
flatIndexMetadatas: [],
|
||||
flatFieldMetadatas: Object.values(FAVORITE_FOLDER_FLAT_FIELDS_MOCK),
|
||||
});
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@ export const getFlatObjectMetadataMock = (
|
||||
|
||||
return {
|
||||
flatFieldMetadatas: [],
|
||||
flatIndexMetadatas: [],
|
||||
|
||||
description: 'default flat object metadata description',
|
||||
icon: 'icon',
|
||||
id: faker.string.uuid(),
|
||||
|
||||
+1
-1
@@ -24,6 +24,6 @@ export const NOTE_FLAT_OBJECT_MOCK = getFlatObjectMetadataMock({
|
||||
isLabelSyncedWithName: false,
|
||||
workspaceId: '20202020-1c25-4d02-bf25-6aeccf7ea419',
|
||||
universalIdentifier: '20202020-0b00-45cd-b6f6-6cd806fc6804',
|
||||
flatIndexMetadatas: [],
|
||||
|
||||
flatFieldMetadatas: Object.values(NOTE_FLAT_FIELDS_MOCK),
|
||||
});
|
||||
|
||||
+1
-1
@@ -24,6 +24,6 @@ export const NOTE_TARGET_FLAT_OBJECT_MOCK = getFlatObjectMetadataMock({
|
||||
isLabelSyncedWithName: false,
|
||||
workspaceId: '20202020-1c25-4d02-bf25-6aeccf7ea419',
|
||||
universalIdentifier: '20202020-fff0-4b44-be82-bda313884400',
|
||||
flatIndexMetadatas: [],
|
||||
|
||||
flatFieldMetadatas: Object.values(NOTETARGET_FLAT_FIELDS_MOCK),
|
||||
});
|
||||
|
||||
-1
@@ -24,6 +24,5 @@ export const OPPORTUNITY_FLAT_OBJECT_MOCK = getFlatObjectMetadataMock({
|
||||
isLabelSyncedWithName: false,
|
||||
workspaceId: '20202020-1c25-4d02-bf25-6aeccf7ea419',
|
||||
universalIdentifier: '20202020-9549-49dd-b2b2-883999db8938',
|
||||
flatIndexMetadatas: [],
|
||||
flatFieldMetadatas: Object.values(OPPORTUNITY_FLAT_FIELDS_MOCK),
|
||||
});
|
||||
|
||||
+1
-1
@@ -24,6 +24,6 @@ export const PERSON_FLAT_OBJECT_MOCK = getFlatObjectMetadataMock({
|
||||
isLabelSyncedWithName: false,
|
||||
workspaceId: '20202020-1c25-4d02-bf25-6aeccf7ea419',
|
||||
universalIdentifier: '20202020-e674-48e5-a542-72570eee7213',
|
||||
flatIndexMetadatas: [],
|
||||
|
||||
flatFieldMetadatas: Object.values(PERSON_FLAT_FIELDS_MOCK),
|
||||
});
|
||||
|
||||
+1
-1
@@ -24,6 +24,6 @@ export const PET_FLAT_OBJECT_MOCK = getFlatObjectMetadataMock({
|
||||
isLabelSyncedWithName: false,
|
||||
workspaceId: '20202020-1c25-4d02-bf25-6aeccf7ea419',
|
||||
universalIdentifier: 'd34e0f07-1b8c-4de0-938e-599cf05e1f7f',
|
||||
flatIndexMetadatas: [],
|
||||
|
||||
flatFieldMetadatas: Object.values(PET_FLAT_FIELDS_MOCK),
|
||||
});
|
||||
|
||||
+1
-1
@@ -24,6 +24,6 @@ export const ROCKET_FLAT_OBJECT_MOCK = getFlatObjectMetadataMock({
|
||||
isLabelSyncedWithName: false,
|
||||
workspaceId: '20202020-1c25-4d02-bf25-6aeccf7ea419',
|
||||
universalIdentifier: 'd78ec657-74a4-4652-a350-1f44ff62970a',
|
||||
flatIndexMetadatas: [],
|
||||
|
||||
flatFieldMetadatas: Object.values(ROCKET_FLAT_FIELDS_MOCK),
|
||||
});
|
||||
|
||||
+1
-1
@@ -24,6 +24,6 @@ export const TASK_FLAT_OBJECT_MOCK = getFlatObjectMetadataMock({
|
||||
isLabelSyncedWithName: false,
|
||||
workspaceId: '20202020-1c25-4d02-bf25-6aeccf7ea419',
|
||||
universalIdentifier: '20202020-1ba1-48ba-bc83-ef7e5990ed10',
|
||||
flatIndexMetadatas: [],
|
||||
|
||||
flatFieldMetadatas: Object.values(TASK_FLAT_FIELDS_MOCK),
|
||||
});
|
||||
|
||||
+1
-1
@@ -24,6 +24,6 @@ export const TASK_TARGET_FLAT_OBJECT_MOCK = getFlatObjectMetadataMock({
|
||||
isLabelSyncedWithName: false,
|
||||
workspaceId: '20202020-1c25-4d02-bf25-6aeccf7ea419',
|
||||
universalIdentifier: '20202020-5a9a-44e8-95df-771cd06d0fb1',
|
||||
flatIndexMetadatas: [],
|
||||
|
||||
flatFieldMetadatas: Object.values(TASKTARGET_FLAT_FIELDS_MOCK),
|
||||
});
|
||||
|
||||
-1
@@ -24,6 +24,5 @@ export const TIMELINE_ACTIVITY_FLAT_OBJECT_MOCK = getFlatObjectMetadataMock({
|
||||
isLabelSyncedWithName: false,
|
||||
workspaceId: '20202020-1c25-4d02-bf25-6aeccf7ea419',
|
||||
universalIdentifier: '20202020-6736-4337-b5c4-8b39fae325a5',
|
||||
flatIndexMetadatas: [],
|
||||
flatFieldMetadatas: Object.values(TIMELINEACTIVITY_FLAT_FIELDS_MOCK),
|
||||
});
|
||||
|
||||
-2
@@ -1,5 +1,4 @@
|
||||
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
|
||||
import { type FlatIndexMetadata } from 'src/engine/metadata-modules/flat-index-metadata/types/flat-index-metadata.type';
|
||||
import { type ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||
import { type ExtractRecordTypeOrmRelationProperties } from 'src/engine/workspace-manager/workspace-migration-v2/types/extract-record-typeorm-relation-properties.type';
|
||||
import { type MetadataEntitiesRelationTarget } from 'src/engine/workspace-manager/workspace-migration-v2/types/metadata-entities-relation-targets.type';
|
||||
@@ -23,7 +22,6 @@ export type FlatObjectMetadata = Omit<
|
||||
ObjectMetadataRelationProperties | 'dataSourceId'
|
||||
> & {
|
||||
universalIdentifier: string;
|
||||
flatIndexMetadatas: FlatIndexMetadata[];
|
||||
flatFieldMetadatas: FlatFieldMetadata[];
|
||||
};
|
||||
|
||||
|
||||
+22
-7
@@ -5,10 +5,12 @@ import {
|
||||
import { v4 } from 'uuid';
|
||||
|
||||
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
|
||||
import { type FlatIndexMetadata } from 'src/engine/metadata-modules/flat-index-metadata/types/flat-index-metadata.type';
|
||||
import { type FlatObjectMetadataMaps } from 'src/engine/metadata-modules/flat-object-metadata-maps/types/flat-object-metadata-maps.type';
|
||||
import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type';
|
||||
import { type CreateObjectInput } from 'src/engine/metadata-modules/object-metadata/dtos/create-object.input';
|
||||
import { buildDefaultFlatFieldMetadatasForCustomObject } from 'src/engine/metadata-modules/object-metadata/utils/build-default-flat-field-metadatas-for-custom-object.util';
|
||||
import { buildDefaultIndexesForCustomObject } from 'src/engine/metadata-modules/object-metadata/utils/build-default-index-for-custom-object.util';
|
||||
import { buildDefaultRelationFlatFieldMetadatasForCustomObject } from 'src/engine/metadata-modules/object-metadata/utils/build-default-relation-flat-field-metadatas-for-custom-object.util';
|
||||
|
||||
type FromCreateObjectInputToFlatObjectMetadataAndFlatFieldMetadatasToCreateArgs =
|
||||
@@ -24,7 +26,8 @@ export const fromCreateObjectInputToFlatObjectMetadataAndFlatFieldMetadatasToCre
|
||||
existingFlatObjectMetadataMaps,
|
||||
}: FromCreateObjectInputToFlatObjectMetadataAndFlatFieldMetadatasToCreateArgs): {
|
||||
flatObjectMetadataToCreate: FlatObjectMetadata;
|
||||
relationTargetFlatFieldMetadatas: FlatFieldMetadata[];
|
||||
relationTargetFlatFieldMetadataToCreate: FlatFieldMetadata[];
|
||||
flatIndexMetadataToCreate: FlatIndexMetadata[];
|
||||
} => {
|
||||
const createObjectInput =
|
||||
trimAndRemoveDuplicatedWhitespacesFromObjectStringProperties(
|
||||
@@ -41,9 +44,11 @@ export const fromCreateObjectInputToFlatObjectMetadataAndFlatFieldMetadatasToCre
|
||||
);
|
||||
|
||||
const objectMetadataId = v4();
|
||||
const baseCustomFlatFieldMetadatas =
|
||||
const defaultFlatFieldForCustomObjectMaps =
|
||||
buildDefaultFlatFieldMetadatasForCustomObject({
|
||||
objectMetadataId,
|
||||
flatObjectMetadata: {
|
||||
id: objectMetadataId,
|
||||
},
|
||||
workspaceId,
|
||||
});
|
||||
const createdAt = new Date();
|
||||
@@ -53,7 +58,6 @@ export const fromCreateObjectInputToFlatObjectMetadataAndFlatFieldMetadatasToCre
|
||||
updatedAt: createdAt,
|
||||
duplicateCriteria: null,
|
||||
description: createObjectInput.description ?? null,
|
||||
flatIndexMetadatas: [],
|
||||
icon: createObjectInput.icon ?? null,
|
||||
id: objectMetadataId,
|
||||
imageIdentifierFieldMetadataId: null,
|
||||
@@ -65,7 +69,8 @@ export const fromCreateObjectInputToFlatObjectMetadataAndFlatFieldMetadatasToCre
|
||||
isSearchable: true,
|
||||
isUIReadOnly: false,
|
||||
isSystem: false,
|
||||
labelIdentifierFieldMetadataId: baseCustomFlatFieldMetadatas.nameField.id,
|
||||
labelIdentifierFieldMetadataId:
|
||||
defaultFlatFieldForCustomObjectMaps.fields.nameField.id,
|
||||
labelPlural: capitalize(createObjectInput.labelPlural),
|
||||
labelSingular: capitalize(createObjectInput.labelSingular),
|
||||
namePlural: createObjectInput.namePlural,
|
||||
@@ -77,6 +82,7 @@ export const fromCreateObjectInputToFlatObjectMetadataAndFlatFieldMetadatasToCre
|
||||
targetTableName: 'DEPRECATED',
|
||||
workspaceId,
|
||||
};
|
||||
|
||||
const {
|
||||
standardSourceFlatFieldMetadatas,
|
||||
standardTargetFlatFieldMetadatas,
|
||||
@@ -87,12 +93,21 @@ export const fromCreateObjectInputToFlatObjectMetadataAndFlatFieldMetadatasToCre
|
||||
});
|
||||
|
||||
flatObjectMetadataToCreate.flatFieldMetadatas = [
|
||||
...Object.values(baseCustomFlatFieldMetadatas),
|
||||
...Object.values(defaultFlatFieldForCustomObjectMaps.fields),
|
||||
...standardSourceFlatFieldMetadatas,
|
||||
];
|
||||
|
||||
const defaultIndexesForCustomObject = buildDefaultIndexesForCustomObject({
|
||||
defaultFlatFieldForCustomObjectMaps,
|
||||
flatObjectMetadata: flatObjectMetadataToCreate,
|
||||
workspaceId,
|
||||
});
|
||||
|
||||
return {
|
||||
flatObjectMetadataToCreate,
|
||||
relationTargetFlatFieldMetadatas: standardTargetFlatFieldMetadatas,
|
||||
relationTargetFlatFieldMetadataToCreate: standardTargetFlatFieldMetadatas,
|
||||
flatIndexMetadataToCreate: Object.values(
|
||||
defaultIndexesForCustomObject.indexes,
|
||||
),
|
||||
};
|
||||
};
|
||||
|
||||
+21
-4
@@ -3,9 +3,11 @@ import {
|
||||
trimAndRemoveDuplicatedWhitespacesFromObjectStringProperties,
|
||||
} from 'twenty-shared/utils';
|
||||
|
||||
import { type FlatEntityMaps } from 'src/engine/core-modules/common/types/flat-entity-maps.type';
|
||||
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
|
||||
import { findRelationFlatFieldMetadataTargetFlatFieldMetadataOrThrow } from 'src/engine/metadata-modules/flat-field-metadata/utils/find-relation-flat-field-metadatas-target-flat-field-metadata-or-throw.util';
|
||||
import { isMorphOrRelationFlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/utils/is-morph-or-relation-flat-field-metadata.util';
|
||||
import { type FlatIndexMetadata } from 'src/engine/metadata-modules/flat-index-metadata/types/flat-index-metadata.type';
|
||||
import { type FlatObjectMetadataMaps } from 'src/engine/metadata-modules/flat-object-metadata-maps/types/flat-object-metadata-maps.type';
|
||||
import { findFlatObjectMetadataInFlatObjectMetadataMaps } from 'src/engine/metadata-modules/flat-object-metadata-maps/utils/find-flat-object-metadata-in-flat-object-metadata-maps.util';
|
||||
import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type';
|
||||
@@ -15,15 +17,20 @@ import {
|
||||
ObjectMetadataExceptionCode,
|
||||
} from 'src/engine/metadata-modules/object-metadata/object-metadata.exception';
|
||||
|
||||
type FromDeleteObjectInputToFlatFieldMetadatasToDeleteArgs = {
|
||||
deleteObjectInput: DeleteOneObjectInput;
|
||||
existingFlatObjectMetadataMaps: FlatObjectMetadataMaps;
|
||||
existingFlatIndexMaps: FlatEntityMaps<FlatIndexMetadata>;
|
||||
};
|
||||
export const fromDeleteObjectInputToFlatFieldMetadatasToDelete = ({
|
||||
deleteObjectInput: rawDeleteObjectInput,
|
||||
existingFlatObjectMetadataMaps,
|
||||
}: {
|
||||
deleteObjectInput: DeleteOneObjectInput;
|
||||
existingFlatObjectMetadataMaps: FlatObjectMetadataMaps;
|
||||
}): {
|
||||
existingFlatIndexMaps,
|
||||
// This should return an AllFlatEntityMaps
|
||||
}: FromDeleteObjectInputToFlatFieldMetadatasToDeleteArgs): {
|
||||
flatFieldMetadatasToDelete: FlatFieldMetadata[];
|
||||
flatObjectMetadataToDelete: FlatObjectMetadata;
|
||||
flatIndexToDelete: FlatIndexMetadata[];
|
||||
} => {
|
||||
const { id: objectMetadataToDeleteId } =
|
||||
trimAndRemoveDuplicatedWhitespacesFromObjectStringProperties(
|
||||
@@ -61,8 +68,18 @@ export const fromDeleteObjectInputToFlatFieldMetadatasToDelete = ({
|
||||
},
|
||||
);
|
||||
|
||||
// We should maintain a idsByObjectMetadataId maps in the index
|
||||
const flatIndexMetadataToDelete = Object.values(
|
||||
existingFlatIndexMaps.byId,
|
||||
).filter(
|
||||
(flatIndex): flatIndex is FlatIndexMetadata =>
|
||||
isDefined(flatIndex) &&
|
||||
flatIndex.objectMetadataId === flatObjectMetadataToDelete.id,
|
||||
);
|
||||
|
||||
return {
|
||||
flatFieldMetadatasToDelete,
|
||||
flatObjectMetadataToDelete,
|
||||
flatIndexToDelete: flatIndexMetadataToDelete,
|
||||
};
|
||||
};
|
||||
|
||||
-1
@@ -17,7 +17,6 @@ export const fromObjectMetadataEntityToFlatObjectMetadata = (
|
||||
|
||||
return {
|
||||
...objectMetadataEntityWithoutRelations,
|
||||
flatIndexMetadatas: [], // TODO prastoin handle indexes
|
||||
universalIdentifier:
|
||||
objectMetadataEntityWithoutRelations.standardId ??
|
||||
objectMetadataEntityWithoutRelations.id,
|
||||
|
||||
-1
@@ -35,6 +35,5 @@ export const fromObjectMetadataItemWithFieldMapsToFlatObjectMetadata = ({
|
||||
...rest,
|
||||
flatFieldMetadatas,
|
||||
universalIdentifier: rest.standardId ?? rest.id,
|
||||
flatIndexMetadatas: [], // prastoin TODO convert from indexMetadatas to flatIndexMetadatas
|
||||
};
|
||||
};
|
||||
|
||||
+36
-7
@@ -4,12 +4,15 @@ import {
|
||||
trimAndRemoveDuplicatedWhitespacesFromObjectStringProperties,
|
||||
} from 'twenty-shared/utils';
|
||||
|
||||
import { type AllFlatEntityMaps } from 'src/engine/core-modules/common/types/all-flat-entity-maps.type';
|
||||
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
|
||||
import { type FlatIndexMetadata } from 'src/engine/metadata-modules/flat-index-metadata/types/flat-index-metadata.type';
|
||||
import { type FlatObjectMetadataMaps } from 'src/engine/metadata-modules/flat-object-metadata-maps/types/flat-object-metadata-maps.type';
|
||||
import { findFlatObjectMetadataInFlatObjectMetadataMaps } from 'src/engine/metadata-modules/flat-object-metadata-maps/utils/find-flat-object-metadata-in-flat-object-metadata-maps.util';
|
||||
import { FLAT_OBJECT_METADATA_PROPERTIES_TO_COMPARE } from 'src/engine/metadata-modules/flat-object-metadata/constants/flat-object-metadata-properties-to-compare.constant';
|
||||
import { type FlatObjectMetadataPropertiesToCompare } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata-properties-to-compare.type';
|
||||
import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type';
|
||||
import { recomputeIndexAfterFlatObjectMetadataSingularNameUpdate } from 'src/engine/metadata-modules/flat-object-metadata/utils/recompute-index-after-flat-object-metadata-singular-name-update.util';
|
||||
import { renameRelatedMorphFieldOnObjectNamesUpdate } from 'src/engine/metadata-modules/flat-object-metadata/utils/rename-related-morph-field-on-object-names-update.util';
|
||||
import { OBJECT_METADATA_STANDARD_OVERRIDES_PROPERTIES } from 'src/engine/metadata-modules/object-metadata/constants/object-metadata-standard-overrides-properties.constant';
|
||||
import { type UpdateOneObjectInput } from 'src/engine/metadata-modules/object-metadata/dtos/update-object.input';
|
||||
@@ -23,7 +26,7 @@ import { isStandardMetadata } from 'src/engine/metadata-modules/utils/is-standar
|
||||
type FromUpdateObjectInputToFlatObjectMetadataArgs = {
|
||||
existingFlatObjectMetadataMaps: FlatObjectMetadataMaps;
|
||||
updateObjectInput: UpdateOneObjectInput;
|
||||
};
|
||||
} & Pick<AllFlatEntityMaps, 'flatIndexMaps'>;
|
||||
|
||||
const objectMetadataEditableProperties =
|
||||
FLAT_OBJECT_METADATA_PROPERTIES_TO_COMPARE.filter(
|
||||
@@ -37,12 +40,14 @@ const objectMetadataEditableProperties =
|
||||
|
||||
type UpdatedFlatObjectAndOtherObjectFieldMetadatas = {
|
||||
flatObjectMetadata: FlatObjectMetadata;
|
||||
otherObjectFlatFieldMetadatas: FlatFieldMetadata[];
|
||||
otherObjectFlatFieldMetadataToUpdate: FlatFieldMetadata[];
|
||||
flatIndexMetadataToUpdate: FlatIndexMetadata[];
|
||||
};
|
||||
|
||||
export const fromUpdateObjectInputToFlatObjectMetadata = ({
|
||||
existingFlatObjectMetadataMaps,
|
||||
updateObjectInput: rawUpdateObjectInput,
|
||||
flatIndexMaps,
|
||||
}: FromUpdateObjectInputToFlatObjectMetadataArgs): UpdatedFlatObjectAndOtherObjectFieldMetadatas => {
|
||||
const { id: objectMetadataIdToUpdate } =
|
||||
trimAndRemoveDuplicatedWhitespacesFromObjectStringProperties(
|
||||
@@ -102,17 +107,26 @@ export const fromUpdateObjectInputToFlatObjectMetadata = ({
|
||||
|
||||
return {
|
||||
flatObjectMetadata: updatedStandardFlatObjectdMetadata,
|
||||
otherObjectFlatFieldMetadatas: [],
|
||||
otherObjectFlatFieldMetadataToUpdate: [],
|
||||
flatIndexMetadataToUpdate: [],
|
||||
};
|
||||
}
|
||||
|
||||
const initialAccumulator: UpdatedFlatObjectAndOtherObjectFieldMetadatas = {
|
||||
flatObjectMetadata: flatObjectMetadataToUpdate,
|
||||
otherObjectFlatFieldMetadatas: [],
|
||||
otherObjectFlatFieldMetadataToUpdate: [],
|
||||
flatIndexMetadataToUpdate: [],
|
||||
};
|
||||
|
||||
return objectMetadataEditableProperties.reduce<UpdatedFlatObjectAndOtherObjectFieldMetadatas>(
|
||||
({ flatObjectMetadata, otherObjectFlatFieldMetadatas }, property) => {
|
||||
(
|
||||
{
|
||||
flatObjectMetadata,
|
||||
otherObjectFlatFieldMetadataToUpdate: otherObjectFlatFieldMetadatas,
|
||||
flatIndexMetadataToUpdate,
|
||||
},
|
||||
property,
|
||||
) => {
|
||||
const updatedPropertyValue = updatedEditableObjectProperties[property];
|
||||
const isPropertyUpdated =
|
||||
updatedPropertyValue !== undefined &&
|
||||
@@ -121,7 +135,8 @@ export const fromUpdateObjectInputToFlatObjectMetadata = ({
|
||||
if (!isPropertyUpdated) {
|
||||
return {
|
||||
flatObjectMetadata,
|
||||
otherObjectFlatFieldMetadatas,
|
||||
otherObjectFlatFieldMetadataToUpdate: otherObjectFlatFieldMetadatas,
|
||||
flatIndexMetadataToUpdate,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -129,6 +144,7 @@ export const fromUpdateObjectInputToFlatObjectMetadata = ({
|
||||
...flatObjectMetadata,
|
||||
[property]: updatedPropertyValue,
|
||||
};
|
||||
|
||||
const newUpdatedOtherObjectFlatFieldMetadatas =
|
||||
property === 'nameSingular' || property === 'namePlural'
|
||||
? renameRelatedMorphFieldOnObjectNamesUpdate({
|
||||
@@ -138,12 +154,25 @@ export const fromUpdateObjectInputToFlatObjectMetadata = ({
|
||||
})
|
||||
: [];
|
||||
|
||||
const newUpdatedFlatIndexMetadatas =
|
||||
property === 'nameSingular'
|
||||
? recomputeIndexAfterFlatObjectMetadataSingularNameUpdate({
|
||||
existingFlatObjectMetadata: flatObjectMetadataToUpdate,
|
||||
flatIndexMaps,
|
||||
updatedSingularName: updatedFlatObjectMetadata.nameSingular,
|
||||
})
|
||||
: [];
|
||||
|
||||
return {
|
||||
flatObjectMetadata: updatedFlatObjectMetadata,
|
||||
otherObjectFlatFieldMetadatas: [
|
||||
otherObjectFlatFieldMetadataToUpdate: [
|
||||
...otherObjectFlatFieldMetadatas,
|
||||
...newUpdatedOtherObjectFlatFieldMetadatas,
|
||||
],
|
||||
flatIndexMetadataToUpdate: [
|
||||
...flatIndexMetadataToUpdate,
|
||||
...newUpdatedFlatIndexMetadatas,
|
||||
],
|
||||
};
|
||||
},
|
||||
initialAccumulator,
|
||||
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { type AllFlatEntityMaps } from 'src/engine/core-modules/common/types/all-flat-entity-maps.type';
|
||||
import { type FlatIndexMetadata } from 'src/engine/metadata-modules/flat-index-metadata/types/flat-index-metadata.type';
|
||||
import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type';
|
||||
import { generateFlatIndexMetadataWithNameOrThrow } from 'src/engine/metadata-modules/index-metadata/utils/generate-flat-index.util';
|
||||
|
||||
type RecomputeIndexAfterFlatObjectMetadataSingularNameUpdateArgs = {
|
||||
existingFlatObjectMetadata: FlatObjectMetadata;
|
||||
updatedSingularName: string;
|
||||
} & Pick<AllFlatEntityMaps, 'flatIndexMaps'>;
|
||||
export const recomputeIndexAfterFlatObjectMetadataSingularNameUpdate = ({
|
||||
existingFlatObjectMetadata,
|
||||
flatIndexMaps,
|
||||
updatedSingularName,
|
||||
}: RecomputeIndexAfterFlatObjectMetadataSingularNameUpdateArgs): FlatIndexMetadata[] => {
|
||||
const allRelatedFlatIndexMetadata = Object.values(flatIndexMaps.byId).filter(
|
||||
(flatIndexMetadata): flatIndexMetadata is FlatIndexMetadata =>
|
||||
isDefined(flatIndexMetadata) &&
|
||||
flatIndexMetadata.objectMetadataId === existingFlatObjectMetadata.id,
|
||||
);
|
||||
|
||||
if (allRelatedFlatIndexMetadata.length === 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const optimisticFlatObjectMetadata: FlatObjectMetadata = {
|
||||
...existingFlatObjectMetadata,
|
||||
nameSingular: updatedSingularName,
|
||||
};
|
||||
|
||||
return allRelatedFlatIndexMetadata.map<FlatIndexMetadata>((flatIndex) => {
|
||||
const newIndex = generateFlatIndexMetadataWithNameOrThrow({
|
||||
flatIndex,
|
||||
flatObjectMetadata: optimisticFlatObjectMetadata,
|
||||
});
|
||||
|
||||
return newIndex;
|
||||
});
|
||||
};
|
||||
+1
@@ -37,6 +37,7 @@ type RenameRelatedMorphFieldOnObjectNamesUpdateArgs = FromTo<
|
||||
> & {
|
||||
existingFlatObjectMetadataMaps: FlatObjectMetadataMaps;
|
||||
};
|
||||
// We should recompute each index here too ? YES TODO prastoin
|
||||
export const renameRelatedMorphFieldOnObjectNamesUpdate = ({
|
||||
fromFlatObjectMetadata,
|
||||
existingFlatObjectMetadataMaps,
|
||||
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
import { createHash } from 'crypto';
|
||||
|
||||
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
|
||||
import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type';
|
||||
import { computeTableName } from 'src/engine/utils/compute-table-name.util';
|
||||
|
||||
type GenerateDeterministicIndexNameArgs = {
|
||||
flatObjectMetadata: Pick<FlatObjectMetadata, 'nameSingular' | 'isCustom'>;
|
||||
isUnique?: boolean;
|
||||
relatedFieldNames: Pick<FlatFieldMetadata, 'name'>[];
|
||||
};
|
||||
export const generateDeterministicIndexNameV2 = ({
|
||||
relatedFieldNames,
|
||||
flatObjectMetadata,
|
||||
isUnique = false,
|
||||
}: GenerateDeterministicIndexNameArgs): string => {
|
||||
const hash = createHash('sha256');
|
||||
|
||||
const tableName = computeTableName(
|
||||
flatObjectMetadata.nameSingular,
|
||||
flatObjectMetadata.isCustom,
|
||||
);
|
||||
|
||||
const columnsNames = relatedFieldNames.map(
|
||||
(flatFieldMetadata) => flatFieldMetadata.name,
|
||||
);
|
||||
|
||||
[tableName, ...columnsNames].forEach((column) => {
|
||||
hash.update(column);
|
||||
});
|
||||
|
||||
return `IDX_${isUnique ? 'UNIQUE_' : ''}${hash.digest('hex').slice(0, 27)}`;
|
||||
};
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import {
|
||||
FlatEntityMapsException,
|
||||
FlatEntityMapsExceptionCode,
|
||||
} from 'src/engine/core-modules/common/exceptions/flat-entity-maps.exception';
|
||||
import { isMorphOrRelationFlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/utils/is-morph-or-relation-flat-field-metadata.util';
|
||||
import { type FlatIndexMetadata } from 'src/engine/metadata-modules/flat-index-metadata/types/flat-index-metadata.type';
|
||||
import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type';
|
||||
import { generateDeterministicIndexNameV2 } from 'src/engine/metadata-modules/index-metadata/utils/generate-deterministic-index-name-v2';
|
||||
|
||||
type GenerateFlatIndexArgs = {
|
||||
flatObjectMetadata: FlatObjectMetadata;
|
||||
flatIndex: Omit<FlatIndexMetadata, 'name'>;
|
||||
};
|
||||
export const generateFlatIndexMetadataWithNameOrThrow = ({
|
||||
flatObjectMetadata,
|
||||
flatIndex,
|
||||
}: GenerateFlatIndexArgs): FlatIndexMetadata => {
|
||||
const orderedFlatFieldNames = flatIndex.flatIndexFieldMetadatas
|
||||
.sort((a, b) => a.order - b.order)
|
||||
.map((flatIndexField) => {
|
||||
const relatedFlatFieldMetadata =
|
||||
flatObjectMetadata.flatFieldMetadatas.find(
|
||||
(flatFieldMetadata) =>
|
||||
flatFieldMetadata.id === flatIndexField.fieldMetadataId,
|
||||
);
|
||||
|
||||
if (!isDefined(relatedFlatFieldMetadata)) {
|
||||
throw new FlatEntityMapsException(
|
||||
'Could not find flat index field related field in cache',
|
||||
FlatEntityMapsExceptionCode.ENTITY_NOT_FOUND,
|
||||
);
|
||||
}
|
||||
|
||||
const name = isMorphOrRelationFlatFieldMetadata(relatedFlatFieldMetadata)
|
||||
? (relatedFlatFieldMetadata.settings.joinColumnName ??
|
||||
relatedFlatFieldMetadata.name)
|
||||
: relatedFlatFieldMetadata.name;
|
||||
|
||||
return {
|
||||
name,
|
||||
};
|
||||
});
|
||||
|
||||
const name = generateDeterministicIndexNameV2({
|
||||
flatObjectMetadata,
|
||||
isUnique: flatIndex.isUnique,
|
||||
relatedFieldNames: orderedFlatFieldNames,
|
||||
});
|
||||
|
||||
return {
|
||||
...flatIndex,
|
||||
name,
|
||||
};
|
||||
};
|
||||
+77
-19
@@ -4,6 +4,8 @@ import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/core-modules/common/services/workspace-many-or-all-flat-entity-maps-cache.service.';
|
||||
import { addFlatEntityToFlatEntityMapsOrThrow } from 'src/engine/core-modules/common/utils/add-flat-entity-to-flat-entity-maps-or-throw.util';
|
||||
import { deleteFlatEntityFromFlatEntityMapsOrThrow } from 'src/engine/core-modules/common/utils/delete-flat-entity-from-flat-entity-maps-or-throw.util';
|
||||
import { replaceFlatEntityInFlatEntityMapsOrThrow } from 'src/engine/core-modules/common/utils/replace-flat-entity-in-flat-entity-maps-or-throw.util';
|
||||
import { ViewKey } from 'src/engine/core-modules/view/enums/view-key.enum';
|
||||
import { ViewType } from 'src/engine/core-modules/view/enums/view-type.enum';
|
||||
import { FlatView } from 'src/engine/core-modules/view/flat-view/types/flat-view.type';
|
||||
@@ -53,20 +55,25 @@ export class ObjectMetadataServiceV2 {
|
||||
workspaceId: string;
|
||||
updateObjectInput: UpdateOneObjectInput;
|
||||
}): Promise<ObjectMetadataDTO> {
|
||||
const { flatObjectMetadataMaps: existingFlatObjectMetadataMaps } =
|
||||
const {
|
||||
flatObjectMetadataMaps: existingFlatObjectMetadataMaps,
|
||||
flatIndexMaps: existingFlatIndexMaps,
|
||||
} =
|
||||
await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps(
|
||||
{
|
||||
workspaceId,
|
||||
flatEntities: ['flatObjectMetadataMaps'],
|
||||
flatEntities: ['flatObjectMetadataMaps', 'flatIndexMaps'],
|
||||
},
|
||||
);
|
||||
|
||||
const {
|
||||
flatObjectMetadata: optimisticallyUpdatedFlatObjectMetadata,
|
||||
otherObjectFlatFieldMetadatas,
|
||||
otherObjectFlatFieldMetadataToUpdate: otherObjectFlatFieldMetadatas,
|
||||
flatIndexMetadataToUpdate,
|
||||
} = fromUpdateObjectInputToFlatObjectMetadata({
|
||||
existingFlatObjectMetadataMaps,
|
||||
updateObjectInput,
|
||||
flatIndexMaps: existingFlatIndexMaps,
|
||||
});
|
||||
|
||||
const impactedObjectMetadataIds = [
|
||||
@@ -93,6 +100,15 @@ export class ObjectMetadataServiceV2 {
|
||||
}),
|
||||
);
|
||||
|
||||
const toFlatIndexMaps = flatIndexMetadataToUpdate.reduce(
|
||||
(flatIndexMaps, flatIndexMetadata) =>
|
||||
replaceFlatEntityInFlatEntityMapsOrThrow({
|
||||
flatEntity: flatIndexMetadata,
|
||||
flatEntityMaps: flatIndexMaps,
|
||||
}),
|
||||
existingFlatIndexMaps,
|
||||
);
|
||||
|
||||
const validateAndBuildResult =
|
||||
await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration(
|
||||
{
|
||||
@@ -101,6 +117,10 @@ export class ObjectMetadataServiceV2 {
|
||||
from: fromFlatObjectMetadataMaps,
|
||||
to: toFlatObjectMetadataMaps,
|
||||
},
|
||||
flatIndexMaps: {
|
||||
from: existingFlatIndexMaps,
|
||||
to: toFlatIndexMaps,
|
||||
},
|
||||
},
|
||||
buildOptions: {
|
||||
isSystemBuild: false,
|
||||
@@ -155,19 +175,26 @@ export class ObjectMetadataServiceV2 {
|
||||
deleteObjectInput: DeleteOneObjectInput;
|
||||
workspaceId: string;
|
||||
}): Promise<ObjectMetadataDTO> {
|
||||
const { flatObjectMetadataMaps: existingFlatObjectMetadataMaps } =
|
||||
const {
|
||||
flatObjectMetadataMaps: existingFlatObjectMetadataMaps,
|
||||
flatIndexMaps: existingFlatIndexMaps,
|
||||
} =
|
||||
await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps(
|
||||
{
|
||||
workspaceId,
|
||||
flatEntities: ['flatObjectMetadataMaps'],
|
||||
flatEntities: ['flatObjectMetadataMaps', 'flatIndexMaps'],
|
||||
},
|
||||
);
|
||||
|
||||
const { flatFieldMetadatasToDelete, flatObjectMetadataToDelete } =
|
||||
fromDeleteObjectInputToFlatFieldMetadatasToDelete({
|
||||
deleteObjectInput,
|
||||
existingFlatObjectMetadataMaps,
|
||||
});
|
||||
const {
|
||||
flatFieldMetadatasToDelete,
|
||||
flatObjectMetadataToDelete,
|
||||
flatIndexToDelete,
|
||||
} = fromDeleteObjectInputToFlatFieldMetadatasToDelete({
|
||||
existingFlatIndexMaps,
|
||||
deleteObjectInput,
|
||||
existingFlatObjectMetadataMaps,
|
||||
});
|
||||
const { id: objectMetadataToDeleteId } = flatObjectMetadataToDelete;
|
||||
|
||||
const impactedObjectMetadataIds = Array.from(
|
||||
@@ -202,6 +229,15 @@ export class ObjectMetadataServiceV2 {
|
||||
}),
|
||||
);
|
||||
|
||||
const toFlatIndexMaps = flatIndexToDelete.reduce(
|
||||
(flatIndexMaps, flatIndex) =>
|
||||
deleteFlatEntityFromFlatEntityMapsOrThrow({
|
||||
entityToDeleteId: flatIndex.id,
|
||||
flatEntityMaps: flatIndexMaps,
|
||||
}),
|
||||
existingFlatIndexMaps,
|
||||
);
|
||||
|
||||
const validateAndBuildResult =
|
||||
await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration(
|
||||
{
|
||||
@@ -210,6 +246,10 @@ export class ObjectMetadataServiceV2 {
|
||||
from: fromFlatObjectMetadataMaps,
|
||||
to: toFlatObjectMetadataMaps,
|
||||
},
|
||||
flatIndexMaps: {
|
||||
from: existingFlatIndexMaps,
|
||||
to: toFlatIndexMaps,
|
||||
},
|
||||
},
|
||||
buildOptions: {
|
||||
inferDeletionFromMissingEntities: true,
|
||||
@@ -242,6 +282,7 @@ export class ObjectMetadataServiceV2 {
|
||||
flatObjectMetadataMaps: existingFlatObjectMetadataMaps,
|
||||
flatViewMaps: existingFlatViewMaps,
|
||||
flatViewFieldMaps: existingFlatViewFieldMaps,
|
||||
flatIndexMaps: existingFlatIndexMaps,
|
||||
} = await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps(
|
||||
{
|
||||
workspaceId,
|
||||
@@ -249,19 +290,23 @@ export class ObjectMetadataServiceV2 {
|
||||
'flatObjectMetadataMaps',
|
||||
'flatViewMaps',
|
||||
'flatViewFieldMaps',
|
||||
'flatIndexMaps',
|
||||
],
|
||||
},
|
||||
);
|
||||
|
||||
const { flatObjectMetadataToCreate, relationTargetFlatFieldMetadatas } =
|
||||
fromCreateObjectInputToFlatObjectMetadataAndFlatFieldMetadatasToCreate({
|
||||
createObjectInput,
|
||||
workspaceId,
|
||||
existingFlatObjectMetadataMaps,
|
||||
});
|
||||
const {
|
||||
flatObjectMetadataToCreate,
|
||||
relationTargetFlatFieldMetadataToCreate,
|
||||
flatIndexMetadataToCreate,
|
||||
} = fromCreateObjectInputToFlatObjectMetadataAndFlatFieldMetadatasToCreate({
|
||||
createObjectInput,
|
||||
workspaceId,
|
||||
existingFlatObjectMetadataMaps,
|
||||
});
|
||||
|
||||
const existingFlatObjectMetadataMapsWithTargetRelationFlatFieldMetadatas =
|
||||
relationTargetFlatFieldMetadatas.reduce(
|
||||
relationTargetFlatFieldMetadataToCreate.reduce(
|
||||
(flatObjectMetadataMaps, flatFieldMetadata) =>
|
||||
addFlatFieldMetadataInFlatObjectMetadataMapsOrThrow({
|
||||
flatFieldMetadata,
|
||||
@@ -272,7 +317,7 @@ export class ObjectMetadataServiceV2 {
|
||||
|
||||
const flatObjectMetadataMapsWithTargetRelationFlatFieldMetadatas =
|
||||
getSubFlatObjectMetadataMapsOutOfFlatFieldMetadatasOrThrow({
|
||||
flatFieldMetadatas: relationTargetFlatFieldMetadatas,
|
||||
flatFieldMetadatas: relationTargetFlatFieldMetadataToCreate,
|
||||
flatObjectMetadataMaps:
|
||||
existingFlatObjectMetadataMapsWithTargetRelationFlatFieldMetadatas,
|
||||
});
|
||||
@@ -286,7 +331,7 @@ export class ObjectMetadataServiceV2 {
|
||||
|
||||
const impactedObjectMetadataIds = [
|
||||
...new Set(
|
||||
relationTargetFlatFieldMetadatas.map(
|
||||
relationTargetFlatFieldMetadataToCreate.map(
|
||||
({ objectMetadataId }) => objectMetadataId,
|
||||
),
|
||||
),
|
||||
@@ -329,6 +374,15 @@ export class ObjectMetadataServiceV2 {
|
||||
existingFlatViewFieldMaps,
|
||||
);
|
||||
|
||||
const toFlatIndexMaps = flatIndexMetadataToCreate.reduce(
|
||||
(flatIndexMaps, flatIndexMetadata) =>
|
||||
addFlatEntityToFlatEntityMapsOrThrow({
|
||||
flatEntity: flatIndexMetadata,
|
||||
flatEntityMaps: flatIndexMaps,
|
||||
}),
|
||||
existingFlatIndexMaps,
|
||||
);
|
||||
|
||||
const validateAndBuildResult =
|
||||
await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration(
|
||||
{
|
||||
@@ -345,6 +399,10 @@ export class ObjectMetadataServiceV2 {
|
||||
from: existingFlatViewFieldMaps,
|
||||
to: toFlatViewFieldMaps,
|
||||
},
|
||||
flatIndexMaps: {
|
||||
from: existingFlatIndexMaps,
|
||||
to: toFlatIndexMaps,
|
||||
},
|
||||
},
|
||||
buildOptions: {
|
||||
isSystemBuild: false,
|
||||
|
||||
+20
-11
@@ -2,6 +2,7 @@ import { FieldMetadataType } from 'twenty-shared/types';
|
||||
import { v4 } from 'uuid';
|
||||
|
||||
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
|
||||
import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type';
|
||||
import {
|
||||
BASE_OBJECT_STANDARD_FIELD_IDS,
|
||||
CUSTOM_OBJECT_STANDARD_FIELD_IDS,
|
||||
@@ -10,12 +11,16 @@ import { getTsVectorColumnExpressionFromFields } from 'src/engine/workspace-mana
|
||||
|
||||
type BuildDefaultFlatFieldMetadataForCustomObjectArgs = {
|
||||
workspaceId: string;
|
||||
objectMetadataId: string;
|
||||
flatObjectMetadata: Pick<FlatObjectMetadata, 'id'>;
|
||||
};
|
||||
|
||||
export type DefaultFlatFieldForCustomObjectMaps = ReturnType<
|
||||
typeof buildDefaultFlatFieldMetadatasForCustomObject
|
||||
>;
|
||||
// This could be replaced totally by an import schema + its transpilation when it's ready
|
||||
export const buildDefaultFlatFieldMetadatasForCustomObject = ({
|
||||
workspaceId,
|
||||
objectMetadataId,
|
||||
flatObjectMetadata: { id: objectMetadataId },
|
||||
}: BuildDefaultFlatFieldMetadataForCustomObjectArgs) => {
|
||||
const createdAt = new Date();
|
||||
const idField: FlatFieldMetadata<FieldMetadataType.UUID> = {
|
||||
@@ -278,13 +283,17 @@ export const buildDefaultFlatFieldMetadatasForCustomObject = ({
|
||||
};
|
||||
|
||||
return {
|
||||
idField,
|
||||
nameField,
|
||||
createdAtField,
|
||||
updatedAtField,
|
||||
deletedAtField,
|
||||
createdByField,
|
||||
positionField,
|
||||
searchVectorField,
|
||||
} as const;
|
||||
fields: {
|
||||
idField,
|
||||
nameField,
|
||||
createdAtField,
|
||||
updatedAtField,
|
||||
deletedAtField,
|
||||
createdByField,
|
||||
positionField,
|
||||
searchVectorField,
|
||||
},
|
||||
} as const satisfies {
|
||||
fields: Record<string, FlatFieldMetadata>;
|
||||
};
|
||||
};
|
||||
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
import { v4 } from 'uuid';
|
||||
|
||||
import { type FlatIndexMetadata } from 'src/engine/metadata-modules/flat-index-metadata/types/flat-index-metadata.type';
|
||||
import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type';
|
||||
import { IndexType } from 'src/engine/metadata-modules/index-metadata/types/indexType.types';
|
||||
import { generateFlatIndexMetadataWithNameOrThrow } from 'src/engine/metadata-modules/index-metadata/utils/generate-flat-index.util';
|
||||
import { type DefaultFlatFieldForCustomObjectMaps } from 'src/engine/metadata-modules/object-metadata/utils/build-default-flat-field-metadatas-for-custom-object.util';
|
||||
|
||||
export const buildDefaultIndexesForCustomObject = ({
|
||||
workspaceId,
|
||||
flatObjectMetadata,
|
||||
defaultFlatFieldForCustomObjectMaps,
|
||||
}: {
|
||||
workspaceId: string;
|
||||
flatObjectMetadata: FlatObjectMetadata;
|
||||
defaultFlatFieldForCustomObjectMaps: DefaultFlatFieldForCustomObjectMaps;
|
||||
}) => {
|
||||
const tsFlatVectorIndexId = v4();
|
||||
const createdAt = new Date();
|
||||
const tsVectorFlatIndex = generateFlatIndexMetadataWithNameOrThrow({
|
||||
flatIndex: {
|
||||
createdAt,
|
||||
flatIndexFieldMetadatas: [
|
||||
{
|
||||
createdAt,
|
||||
fieldMetadataId:
|
||||
defaultFlatFieldForCustomObjectMaps.fields.searchVectorField.id,
|
||||
id: v4(),
|
||||
indexMetadataId: tsFlatVectorIndexId,
|
||||
order: 0,
|
||||
updatedAt: createdAt,
|
||||
},
|
||||
],
|
||||
id: tsFlatVectorIndexId,
|
||||
indexType: IndexType.GIN,
|
||||
indexWhereClause: null,
|
||||
isCustom: false,
|
||||
isUnique: false,
|
||||
objectMetadataId: flatObjectMetadata.id,
|
||||
universalIdentifier: tsFlatVectorIndexId,
|
||||
updatedAt: createdAt,
|
||||
workspaceId,
|
||||
},
|
||||
flatObjectMetadata,
|
||||
});
|
||||
|
||||
return {
|
||||
indexes: {
|
||||
tsVectorFlatIndex,
|
||||
},
|
||||
} as const satisfies { indexes: Record<string, FlatIndexMetadata> };
|
||||
};
|
||||
+9
-1
@@ -6,7 +6,9 @@ import { ViewFieldEntity } from 'src/engine/core-modules/view/entities/view-fiel
|
||||
import { ViewEntity } from 'src/engine/core-modules/view/entities/view.entity';
|
||||
import { WorkspaceFlatViewFieldMapCacheService } from 'src/engine/core-modules/view/flat-view/services/workspace-flat-view-field-map-cache.service';
|
||||
import { WorkspaceFlatViewMapCacheService } from 'src/engine/core-modules/view/flat-view/services/workspace-flat-view-map-cache.service';
|
||||
import { WorkspaceFlatIndexMapCacheService } from 'src/engine/metadata-modules/flat-index-metadata/services/workspace-flat-index-map-cache.service';
|
||||
import { WorkspaceFlatObjectMetadataMapCacheService } from 'src/engine/metadata-modules/flat-object-metadata/services/workspace-flat-object-metadata-map-cache.service';
|
||||
import { IndexMetadataEntity } from 'src/engine/metadata-modules/index-metadata/index-metadata.entity';
|
||||
import { WorkspaceMetadataCacheModule } from 'src/engine/metadata-modules/workspace-metadata-cache/workspace-metadata-cache.module';
|
||||
import { WorkspaceMetadataVersionModule } from 'src/engine/metadata-modules/workspace-metadata-version/workspace-metadata-version.module';
|
||||
import { WorkspacePermissionsCacheModule } from 'src/engine/metadata-modules/workspace-permissions-cache/workspace-permissions-cache.module';
|
||||
@@ -18,19 +20,25 @@ import { WorkspaceFlatMapCacheRegistryService } from 'src/engine/workspace-flat-
|
||||
WorkspaceMetadataCacheModule,
|
||||
WorkspaceMetadataVersionModule,
|
||||
WorkspacePermissionsCacheModule,
|
||||
TypeOrmModule.forFeature([ViewEntity, ViewFieldEntity]),
|
||||
TypeOrmModule.forFeature([
|
||||
ViewEntity,
|
||||
ViewFieldEntity,
|
||||
IndexMetadataEntity,
|
||||
]),
|
||||
],
|
||||
providers: [
|
||||
WorkspaceFlatMapCacheRegistryService,
|
||||
WorkspaceFlatObjectMetadataMapCacheService,
|
||||
WorkspaceFlatViewMapCacheService,
|
||||
WorkspaceFlatViewFieldMapCacheService,
|
||||
WorkspaceFlatIndexMapCacheService,
|
||||
],
|
||||
exports: [
|
||||
WorkspaceFlatMapCacheRegistryService,
|
||||
WorkspaceFlatObjectMetadataMapCacheService,
|
||||
WorkspaceFlatViewMapCacheService,
|
||||
WorkspaceFlatViewFieldMapCacheService,
|
||||
WorkspaceFlatIndexMapCacheService,
|
||||
],
|
||||
})
|
||||
export class WorkspaceFlatMapCacheModule {}
|
||||
|
||||
+2
-2
@@ -208,14 +208,14 @@ export class WorkspaceMigrationBuildOrchestratorService {
|
||||
relatedFlatEntityMapsKeys,
|
||||
actions: [
|
||||
// Object and fields
|
||||
...orchestratorActionsReport.fieldMetadata.deleted,
|
||||
...orchestratorActionsReport.index.deleted,
|
||||
...orchestratorActionsReport.fieldMetadata.deleted,
|
||||
...orchestratorActionsReport.objectMetadata.deleted,
|
||||
...orchestratorActionsReport.objectMetadata.created,
|
||||
...orchestratorActionsReport.index.created,
|
||||
...orchestratorActionsReport.objectMetadata.updated,
|
||||
...orchestratorActionsReport.fieldMetadata.created,
|
||||
...orchestratorActionsReport.fieldMetadata.updated,
|
||||
...orchestratorActionsReport.index.created,
|
||||
...orchestratorActionsReport.index.updated,
|
||||
///
|
||||
|
||||
|
||||
-647
@@ -2408,653 +2408,6 @@ exports[`Workspace migration builder object actions test suite It should build a
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Workspace migration builder object actions test suite It should build a create_object and create_index actions for each of this fieldMetadata 1`] = `
|
||||
{
|
||||
"created": [],
|
||||
"deleted": [],
|
||||
"updated": [],
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Workspace migration builder object actions test suite It should build a create_object and create_index actions for each of this fieldMetadata 2`] = `
|
||||
{
|
||||
"created": [
|
||||
{
|
||||
"createFieldActions": [
|
||||
{
|
||||
"flatFieldMetadata": {
|
||||
"createdAt": Any<String>,
|
||||
"defaultValue": "uuid",
|
||||
"description": "Id",
|
||||
"flatRelationTargetFieldMetadata": null,
|
||||
"flatRelationTargetObjectMetadata": null,
|
||||
"icon": "Icon123",
|
||||
"id": Any<String>,
|
||||
"isActive": true,
|
||||
"isCustom": false,
|
||||
"isLabelSyncedWithName": false,
|
||||
"isNullable": false,
|
||||
"isSystem": true,
|
||||
"isUIReadOnly": false,
|
||||
"isUnique": false,
|
||||
"label": "Id",
|
||||
"morphId": null,
|
||||
"name": "id",
|
||||
"objectMetadataId": Any<String>,
|
||||
"options": null,
|
||||
"relationTargetFieldMetadataId": null,
|
||||
"relationTargetObjectMetadataId": null,
|
||||
"settings": null,
|
||||
"standardId": Any<String>,
|
||||
"standardOverrides": null,
|
||||
"type": "UUID",
|
||||
"universalIdentifier": Any<String>,
|
||||
"updatedAt": Any<String>,
|
||||
"workspaceId": Any<String>,
|
||||
},
|
||||
"type": "create_field",
|
||||
},
|
||||
{
|
||||
"flatFieldMetadata": {
|
||||
"createdAt": Any<String>,
|
||||
"defaultValue": "'Untitled'",
|
||||
"description": "Name",
|
||||
"flatRelationTargetFieldMetadata": null,
|
||||
"flatRelationTargetObjectMetadata": null,
|
||||
"icon": "IconAbc",
|
||||
"id": Any<String>,
|
||||
"isActive": true,
|
||||
"isCustom": false,
|
||||
"isLabelSyncedWithName": false,
|
||||
"isNullable": false,
|
||||
"isSystem": false,
|
||||
"isUIReadOnly": false,
|
||||
"isUnique": false,
|
||||
"label": "Name",
|
||||
"morphId": null,
|
||||
"name": "name",
|
||||
"objectMetadataId": Any<String>,
|
||||
"options": null,
|
||||
"relationTargetFieldMetadataId": null,
|
||||
"relationTargetObjectMetadataId": null,
|
||||
"settings": null,
|
||||
"standardId": Any<String>,
|
||||
"standardOverrides": null,
|
||||
"type": "TEXT",
|
||||
"universalIdentifier": Any<String>,
|
||||
"updatedAt": Any<String>,
|
||||
"workspaceId": Any<String>,
|
||||
},
|
||||
"type": "create_field",
|
||||
},
|
||||
{
|
||||
"flatFieldMetadata": {
|
||||
"createdAt": Any<String>,
|
||||
"defaultValue": "now",
|
||||
"description": "Creation date",
|
||||
"flatRelationTargetFieldMetadata": null,
|
||||
"flatRelationTargetObjectMetadata": null,
|
||||
"icon": "IconCalendar",
|
||||
"id": Any<String>,
|
||||
"isActive": true,
|
||||
"isCustom": false,
|
||||
"isLabelSyncedWithName": false,
|
||||
"isNullable": false,
|
||||
"isSystem": false,
|
||||
"isUIReadOnly": false,
|
||||
"isUnique": false,
|
||||
"label": "Creation date",
|
||||
"morphId": null,
|
||||
"name": "createdAt",
|
||||
"objectMetadataId": Any<String>,
|
||||
"options": null,
|
||||
"relationTargetFieldMetadataId": null,
|
||||
"relationTargetObjectMetadataId": null,
|
||||
"settings": null,
|
||||
"standardId": Any<String>,
|
||||
"standardOverrides": null,
|
||||
"type": "DATE_TIME",
|
||||
"universalIdentifier": Any<String>,
|
||||
"updatedAt": Any<String>,
|
||||
"workspaceId": Any<String>,
|
||||
},
|
||||
"type": "create_field",
|
||||
},
|
||||
{
|
||||
"flatFieldMetadata": {
|
||||
"createdAt": Any<String>,
|
||||
"defaultValue": "now",
|
||||
"description": "Last time the record was changed",
|
||||
"flatRelationTargetFieldMetadata": null,
|
||||
"flatRelationTargetObjectMetadata": null,
|
||||
"icon": "IconCalendarClock",
|
||||
"id": Any<String>,
|
||||
"isActive": true,
|
||||
"isCustom": false,
|
||||
"isLabelSyncedWithName": false,
|
||||
"isNullable": false,
|
||||
"isSystem": false,
|
||||
"isUIReadOnly": false,
|
||||
"isUnique": false,
|
||||
"label": "Last update",
|
||||
"morphId": null,
|
||||
"name": "updatedAt",
|
||||
"objectMetadataId": Any<String>,
|
||||
"options": null,
|
||||
"relationTargetFieldMetadataId": null,
|
||||
"relationTargetObjectMetadataId": null,
|
||||
"settings": null,
|
||||
"standardId": Any<String>,
|
||||
"standardOverrides": null,
|
||||
"type": "DATE_TIME",
|
||||
"universalIdentifier": Any<String>,
|
||||
"updatedAt": Any<String>,
|
||||
"workspaceId": Any<String>,
|
||||
},
|
||||
"type": "create_field",
|
||||
},
|
||||
{
|
||||
"flatFieldMetadata": {
|
||||
"createdAt": Any<String>,
|
||||
"defaultValue": null,
|
||||
"description": "Deletion date",
|
||||
"flatRelationTargetFieldMetadata": null,
|
||||
"flatRelationTargetObjectMetadata": null,
|
||||
"icon": "IconCalendarClock",
|
||||
"id": Any<String>,
|
||||
"isActive": true,
|
||||
"isCustom": false,
|
||||
"isLabelSyncedWithName": false,
|
||||
"isNullable": true,
|
||||
"isSystem": false,
|
||||
"isUIReadOnly": false,
|
||||
"isUnique": false,
|
||||
"label": "Deleted at",
|
||||
"morphId": null,
|
||||
"name": "deletedAt",
|
||||
"objectMetadataId": Any<String>,
|
||||
"options": null,
|
||||
"relationTargetFieldMetadataId": null,
|
||||
"relationTargetObjectMetadataId": null,
|
||||
"settings": null,
|
||||
"standardId": Any<String>,
|
||||
"standardOverrides": null,
|
||||
"type": "DATE_TIME",
|
||||
"universalIdentifier": Any<String>,
|
||||
"updatedAt": Any<String>,
|
||||
"workspaceId": Any<String>,
|
||||
},
|
||||
"type": "create_field",
|
||||
},
|
||||
{
|
||||
"flatFieldMetadata": {
|
||||
"createdAt": Any<String>,
|
||||
"defaultValue": {
|
||||
"name": "''",
|
||||
"source": "'MANUAL'",
|
||||
},
|
||||
"description": "The creator of the record",
|
||||
"flatRelationTargetFieldMetadata": null,
|
||||
"flatRelationTargetObjectMetadata": null,
|
||||
"icon": "IconCreativeCommonsSa",
|
||||
"id": Any<String>,
|
||||
"isActive": true,
|
||||
"isCustom": false,
|
||||
"isLabelSyncedWithName": false,
|
||||
"isNullable": false,
|
||||
"isSystem": false,
|
||||
"isUIReadOnly": false,
|
||||
"isUnique": false,
|
||||
"label": "Created by",
|
||||
"morphId": null,
|
||||
"name": "createdBy",
|
||||
"objectMetadataId": Any<String>,
|
||||
"options": null,
|
||||
"relationTargetFieldMetadataId": null,
|
||||
"relationTargetObjectMetadataId": null,
|
||||
"settings": null,
|
||||
"standardId": Any<String>,
|
||||
"standardOverrides": null,
|
||||
"type": "ACTOR",
|
||||
"universalIdentifier": Any<String>,
|
||||
"updatedAt": Any<String>,
|
||||
"workspaceId": Any<String>,
|
||||
},
|
||||
"type": "create_field",
|
||||
},
|
||||
{
|
||||
"flatFieldMetadata": {
|
||||
"createdAt": Any<String>,
|
||||
"defaultValue": 0,
|
||||
"description": "Position",
|
||||
"flatRelationTargetFieldMetadata": null,
|
||||
"flatRelationTargetObjectMetadata": null,
|
||||
"icon": "IconHierarchy2",
|
||||
"id": Any<String>,
|
||||
"isActive": true,
|
||||
"isCustom": false,
|
||||
"isLabelSyncedWithName": false,
|
||||
"isNullable": false,
|
||||
"isSystem": true,
|
||||
"isUIReadOnly": false,
|
||||
"isUnique": false,
|
||||
"label": "Position",
|
||||
"morphId": null,
|
||||
"name": "position",
|
||||
"objectMetadataId": Any<String>,
|
||||
"options": null,
|
||||
"relationTargetFieldMetadataId": null,
|
||||
"relationTargetObjectMetadataId": null,
|
||||
"settings": null,
|
||||
"standardId": Any<String>,
|
||||
"standardOverrides": null,
|
||||
"type": "POSITION",
|
||||
"universalIdentifier": Any<String>,
|
||||
"updatedAt": Any<String>,
|
||||
"workspaceId": Any<String>,
|
||||
},
|
||||
"type": "create_field",
|
||||
},
|
||||
{
|
||||
"flatFieldMetadata": {
|
||||
"createdAt": Any<String>,
|
||||
"defaultValue": null,
|
||||
"description": "TimelineActivities tied to the Rocket",
|
||||
"flatRelationTargetFieldMetadata": {
|
||||
"createdAt": Any<String>,
|
||||
"defaultValue": null,
|
||||
"description": "TimelineActivities Rocket",
|
||||
"icon": "IconBuildingSkyscraper",
|
||||
"id": Any<String>,
|
||||
"isActive": true,
|
||||
"isCustom": false,
|
||||
"isLabelSyncedWithName": false,
|
||||
"isNullable": true,
|
||||
"isSystem": true,
|
||||
"isUIReadOnly": false,
|
||||
"isUnique": false,
|
||||
"label": "Rocket",
|
||||
"morphId": null,
|
||||
"name": "rocket",
|
||||
"objectMetadataId": Any<String>,
|
||||
"options": null,
|
||||
"relationTargetFieldMetadataId": Any<String>,
|
||||
"relationTargetObjectMetadataId": Any<String>,
|
||||
"settings": {
|
||||
"joinColumnName": "rocketId",
|
||||
"onDelete": "CASCADE",
|
||||
"relationType": "MANY_TO_ONE",
|
||||
},
|
||||
"standardId": Any<String>,
|
||||
"standardOverrides": null,
|
||||
"type": "RELATION",
|
||||
"universalIdentifier": Any<String>,
|
||||
"updatedAt": Any<String>,
|
||||
"workspaceId": Any<String>,
|
||||
},
|
||||
"flatRelationTargetObjectMetadata": null,
|
||||
"icon": "IconTimelineEvent",
|
||||
"id": Any<String>,
|
||||
"isActive": true,
|
||||
"isCustom": false,
|
||||
"isLabelSyncedWithName": false,
|
||||
"isNullable": true,
|
||||
"isSystem": true,
|
||||
"isUIReadOnly": false,
|
||||
"isUnique": false,
|
||||
"label": "TimelineActivities",
|
||||
"morphId": null,
|
||||
"name": "timelineActivities",
|
||||
"objectMetadataId": Any<String>,
|
||||
"options": null,
|
||||
"relationTargetFieldMetadataId": Any<String>,
|
||||
"relationTargetObjectMetadataId": Any<String>,
|
||||
"settings": {
|
||||
"relationType": "ONE_TO_MANY",
|
||||
},
|
||||
"standardId": Any<String>,
|
||||
"standardOverrides": null,
|
||||
"type": "RELATION",
|
||||
"universalIdentifier": Any<String>,
|
||||
"updatedAt": Any<String>,
|
||||
"workspaceId": Any<String>,
|
||||
},
|
||||
"type": "create_field",
|
||||
},
|
||||
{
|
||||
"flatFieldMetadata": {
|
||||
"createdAt": Any<String>,
|
||||
"defaultValue": null,
|
||||
"description": "Favorites tied to the Rocket",
|
||||
"flatRelationTargetFieldMetadata": {
|
||||
"createdAt": Any<String>,
|
||||
"defaultValue": null,
|
||||
"description": "Favorites Rocket",
|
||||
"icon": "IconBuildingSkyscraper",
|
||||
"id": Any<String>,
|
||||
"isActive": true,
|
||||
"isCustom": false,
|
||||
"isLabelSyncedWithName": false,
|
||||
"isNullable": true,
|
||||
"isSystem": true,
|
||||
"isUIReadOnly": false,
|
||||
"isUnique": false,
|
||||
"label": "Rocket",
|
||||
"morphId": null,
|
||||
"name": "rocket",
|
||||
"objectMetadataId": Any<String>,
|
||||
"options": null,
|
||||
"relationTargetFieldMetadataId": Any<String>,
|
||||
"relationTargetObjectMetadataId": Any<String>,
|
||||
"settings": {
|
||||
"joinColumnName": "rocketId",
|
||||
"onDelete": "CASCADE",
|
||||
"relationType": "MANY_TO_ONE",
|
||||
},
|
||||
"standardId": Any<String>,
|
||||
"standardOverrides": null,
|
||||
"type": "RELATION",
|
||||
"universalIdentifier": Any<String>,
|
||||
"updatedAt": Any<String>,
|
||||
"workspaceId": Any<String>,
|
||||
},
|
||||
"flatRelationTargetObjectMetadata": null,
|
||||
"icon": "IconHeart",
|
||||
"id": Any<String>,
|
||||
"isActive": true,
|
||||
"isCustom": false,
|
||||
"isLabelSyncedWithName": false,
|
||||
"isNullable": true,
|
||||
"isSystem": true,
|
||||
"isUIReadOnly": false,
|
||||
"isUnique": false,
|
||||
"label": "Favorites",
|
||||
"morphId": null,
|
||||
"name": "favorites",
|
||||
"objectMetadataId": Any<String>,
|
||||
"options": null,
|
||||
"relationTargetFieldMetadataId": Any<String>,
|
||||
"relationTargetObjectMetadataId": Any<String>,
|
||||
"settings": {
|
||||
"relationType": "ONE_TO_MANY",
|
||||
},
|
||||
"standardId": Any<String>,
|
||||
"standardOverrides": null,
|
||||
"type": "RELATION",
|
||||
"universalIdentifier": Any<String>,
|
||||
"updatedAt": Any<String>,
|
||||
"workspaceId": Any<String>,
|
||||
},
|
||||
"type": "create_field",
|
||||
},
|
||||
{
|
||||
"flatFieldMetadata": {
|
||||
"createdAt": Any<String>,
|
||||
"defaultValue": null,
|
||||
"description": "Attachments tied to the Rocket",
|
||||
"flatRelationTargetFieldMetadata": {
|
||||
"createdAt": Any<String>,
|
||||
"defaultValue": null,
|
||||
"description": "Attachments Rocket",
|
||||
"icon": "IconBuildingSkyscraper",
|
||||
"id": Any<String>,
|
||||
"isActive": true,
|
||||
"isCustom": false,
|
||||
"isLabelSyncedWithName": false,
|
||||
"isNullable": true,
|
||||
"isSystem": true,
|
||||
"isUIReadOnly": false,
|
||||
"isUnique": false,
|
||||
"label": "Rocket",
|
||||
"morphId": null,
|
||||
"name": "rocket",
|
||||
"objectMetadataId": Any<String>,
|
||||
"options": null,
|
||||
"relationTargetFieldMetadataId": Any<String>,
|
||||
"relationTargetObjectMetadataId": Any<String>,
|
||||
"settings": {
|
||||
"joinColumnName": "rocketId",
|
||||
"onDelete": "CASCADE",
|
||||
"relationType": "MANY_TO_ONE",
|
||||
},
|
||||
"standardId": Any<String>,
|
||||
"standardOverrides": null,
|
||||
"type": "RELATION",
|
||||
"universalIdentifier": Any<String>,
|
||||
"updatedAt": Any<String>,
|
||||
"workspaceId": Any<String>,
|
||||
},
|
||||
"flatRelationTargetObjectMetadata": null,
|
||||
"icon": "IconFileImport",
|
||||
"id": Any<String>,
|
||||
"isActive": true,
|
||||
"isCustom": false,
|
||||
"isLabelSyncedWithName": false,
|
||||
"isNullable": true,
|
||||
"isSystem": true,
|
||||
"isUIReadOnly": false,
|
||||
"isUnique": false,
|
||||
"label": "Attachments",
|
||||
"morphId": null,
|
||||
"name": "attachments",
|
||||
"objectMetadataId": Any<String>,
|
||||
"options": null,
|
||||
"relationTargetFieldMetadataId": Any<String>,
|
||||
"relationTargetObjectMetadataId": Any<String>,
|
||||
"settings": {
|
||||
"relationType": "ONE_TO_MANY",
|
||||
},
|
||||
"standardId": Any<String>,
|
||||
"standardOverrides": null,
|
||||
"type": "RELATION",
|
||||
"universalIdentifier": Any<String>,
|
||||
"updatedAt": Any<String>,
|
||||
"workspaceId": Any<String>,
|
||||
},
|
||||
"type": "create_field",
|
||||
},
|
||||
{
|
||||
"flatFieldMetadata": {
|
||||
"createdAt": Any<String>,
|
||||
"defaultValue": null,
|
||||
"description": "NoteTargets tied to the Rocket",
|
||||
"flatRelationTargetFieldMetadata": {
|
||||
"createdAt": Any<String>,
|
||||
"defaultValue": null,
|
||||
"description": "NoteTargets Rocket",
|
||||
"icon": "IconBuildingSkyscraper",
|
||||
"id": Any<String>,
|
||||
"isActive": true,
|
||||
"isCustom": false,
|
||||
"isLabelSyncedWithName": false,
|
||||
"isNullable": true,
|
||||
"isSystem": true,
|
||||
"isUIReadOnly": false,
|
||||
"isUnique": false,
|
||||
"label": "Rocket",
|
||||
"morphId": null,
|
||||
"name": "rocket",
|
||||
"objectMetadataId": Any<String>,
|
||||
"options": null,
|
||||
"relationTargetFieldMetadataId": Any<String>,
|
||||
"relationTargetObjectMetadataId": Any<String>,
|
||||
"settings": {
|
||||
"joinColumnName": "rocketId",
|
||||
"onDelete": "CASCADE",
|
||||
"relationType": "MANY_TO_ONE",
|
||||
},
|
||||
"standardId": Any<String>,
|
||||
"standardOverrides": null,
|
||||
"type": "RELATION",
|
||||
"universalIdentifier": Any<String>,
|
||||
"updatedAt": Any<String>,
|
||||
"workspaceId": Any<String>,
|
||||
},
|
||||
"flatRelationTargetObjectMetadata": null,
|
||||
"icon": "IconCheckbox",
|
||||
"id": Any<String>,
|
||||
"isActive": true,
|
||||
"isCustom": false,
|
||||
"isLabelSyncedWithName": false,
|
||||
"isNullable": true,
|
||||
"isSystem": true,
|
||||
"isUIReadOnly": false,
|
||||
"isUnique": false,
|
||||
"label": "NoteTargets",
|
||||
"morphId": null,
|
||||
"name": "noteTargets",
|
||||
"objectMetadataId": Any<String>,
|
||||
"options": null,
|
||||
"relationTargetFieldMetadataId": Any<String>,
|
||||
"relationTargetObjectMetadataId": Any<String>,
|
||||
"settings": {
|
||||
"relationType": "ONE_TO_MANY",
|
||||
},
|
||||
"standardId": Any<String>,
|
||||
"standardOverrides": null,
|
||||
"type": "RELATION",
|
||||
"universalIdentifier": Any<String>,
|
||||
"updatedAt": Any<String>,
|
||||
"workspaceId": Any<String>,
|
||||
},
|
||||
"type": "create_field",
|
||||
},
|
||||
{
|
||||
"flatFieldMetadata": {
|
||||
"createdAt": Any<String>,
|
||||
"defaultValue": null,
|
||||
"description": "TaskTargets tied to the Rocket",
|
||||
"flatRelationTargetFieldMetadata": {
|
||||
"createdAt": Any<String>,
|
||||
"defaultValue": null,
|
||||
"description": "TaskTargets Rocket",
|
||||
"icon": "IconBuildingSkyscraper",
|
||||
"id": Any<String>,
|
||||
"isActive": true,
|
||||
"isCustom": false,
|
||||
"isLabelSyncedWithName": false,
|
||||
"isNullable": true,
|
||||
"isSystem": true,
|
||||
"isUIReadOnly": false,
|
||||
"isUnique": false,
|
||||
"label": "Rocket",
|
||||
"morphId": null,
|
||||
"name": "rocket",
|
||||
"objectMetadataId": Any<String>,
|
||||
"options": null,
|
||||
"relationTargetFieldMetadataId": Any<String>,
|
||||
"relationTargetObjectMetadataId": Any<String>,
|
||||
"settings": {
|
||||
"joinColumnName": "rocketId",
|
||||
"onDelete": "CASCADE",
|
||||
"relationType": "MANY_TO_ONE",
|
||||
},
|
||||
"standardId": Any<String>,
|
||||
"standardOverrides": null,
|
||||
"type": "RELATION",
|
||||
"universalIdentifier": Any<String>,
|
||||
"updatedAt": Any<String>,
|
||||
"workspaceId": Any<String>,
|
||||
},
|
||||
"flatRelationTargetObjectMetadata": null,
|
||||
"icon": "IconCheckbox",
|
||||
"id": Any<String>,
|
||||
"isActive": true,
|
||||
"isCustom": false,
|
||||
"isLabelSyncedWithName": false,
|
||||
"isNullable": true,
|
||||
"isSystem": true,
|
||||
"isUIReadOnly": false,
|
||||
"isUnique": false,
|
||||
"label": "TaskTargets",
|
||||
"morphId": null,
|
||||
"name": "taskTargets",
|
||||
"objectMetadataId": Any<String>,
|
||||
"options": null,
|
||||
"relationTargetFieldMetadataId": Any<String>,
|
||||
"relationTargetObjectMetadataId": Any<String>,
|
||||
"settings": {
|
||||
"relationType": "ONE_TO_MANY",
|
||||
},
|
||||
"standardId": Any<String>,
|
||||
"standardOverrides": null,
|
||||
"type": "RELATION",
|
||||
"universalIdentifier": Any<String>,
|
||||
"updatedAt": Any<String>,
|
||||
"workspaceId": Any<String>,
|
||||
},
|
||||
"type": "create_field",
|
||||
},
|
||||
{
|
||||
"flatFieldMetadata": {
|
||||
"createdAt": Any<String>,
|
||||
"defaultValue": null,
|
||||
"description": "Field used for full-text search",
|
||||
"flatRelationTargetFieldMetadata": null,
|
||||
"flatRelationTargetObjectMetadata": null,
|
||||
"icon": null,
|
||||
"id": Any<String>,
|
||||
"isActive": false,
|
||||
"isCustom": false,
|
||||
"isLabelSyncedWithName": false,
|
||||
"isNullable": true,
|
||||
"isSystem": true,
|
||||
"isUIReadOnly": false,
|
||||
"isUnique": false,
|
||||
"label": "Search vector",
|
||||
"morphId": null,
|
||||
"name": "searchVector",
|
||||
"objectMetadataId": Any<String>,
|
||||
"options": null,
|
||||
"relationTargetFieldMetadataId": null,
|
||||
"relationTargetObjectMetadataId": null,
|
||||
"settings": null,
|
||||
"standardId": Any<String>,
|
||||
"standardOverrides": null,
|
||||
"type": "TS_VECTOR",
|
||||
"universalIdentifier": Any<String>,
|
||||
"updatedAt": Any<String>,
|
||||
"workspaceId": Any<String>,
|
||||
},
|
||||
"type": "create_field",
|
||||
},
|
||||
],
|
||||
"flatObjectMetadataWithoutFields": {
|
||||
"createdAt": Any<String>,
|
||||
"description": "A rocket",
|
||||
"duplicateCriteria": null,
|
||||
"icon": "IconRocket",
|
||||
"id": Any<String>,
|
||||
"imageIdentifierFieldMetadataId": null,
|
||||
"isActive": true,
|
||||
"isAuditLogged": true,
|
||||
"isCustom": true,
|
||||
"isLabelSyncedWithName": false,
|
||||
"isRemote": false,
|
||||
"isSearchable": true,
|
||||
"isSystem": false,
|
||||
"isUIReadOnly": false,
|
||||
"labelIdentifierFieldMetadataId": Any<String>,
|
||||
"labelPlural": "Rockets",
|
||||
"labelSingular": "Rocket",
|
||||
"namePlural": "rockets",
|
||||
"nameSingular": "rocket",
|
||||
"shortcut": null,
|
||||
"standardId": null,
|
||||
"standardOverrides": null,
|
||||
"targetTableName": "DEPRECATED",
|
||||
"universalIdentifier": Any<String>,
|
||||
"updatedAt": Any<String>,
|
||||
"workspaceId": Any<String>,
|
||||
},
|
||||
"type": "create_object",
|
||||
},
|
||||
],
|
||||
"deleted": [],
|
||||
"updated": [],
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Workspace migration builder object actions test suite It should build a delete_object action with custom deactivated object 1`] = `
|
||||
{
|
||||
"created": [],
|
||||
|
||||
-26
@@ -1,4 +1,3 @@
|
||||
import { getFlatIndexMetadataMock } from 'src/engine/metadata-modules/flat-index-metadata/__mocks__/get-flat-index-metadata.mock';
|
||||
import { FLAT_OBJECT_METADATA_MAPS_MOCKS } from 'src/engine/metadata-modules/flat-object-metadata-maps/mocks/flat-object-metadata-maps.mock';
|
||||
import { deleteObjectFromFlatObjectMetadataMapsOrThrow } from 'src/engine/metadata-modules/flat-object-metadata-maps/utils/delete-object-from-flat-object-metadata-maps-or-throw.util';
|
||||
import { replaceFlatObjectMetadataInFlatObjectMetadataMapsOrThrow } from 'src/engine/metadata-modules/flat-object-metadata-maps/utils/replace-flat-object-metadata-in-flat-object-metadata-maps-or-throw.util';
|
||||
@@ -93,31 +92,6 @@ const CREATE_OBJECT_TEST_CASES: WorkspaceMigrationBuilderTestCase[] = [
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
title:
|
||||
'It should build a create_object and create_index actions for each of this fieldMetadata',
|
||||
context: {
|
||||
input: {
|
||||
fromFlatObjectMetadataMaps:
|
||||
fromFlatObjectMetadatasToFlatObjectMetadataMaps([
|
||||
...STANDARD_RELATION_TARGET_FLAT_OBJECT_METADATA_MOCKS,
|
||||
]),
|
||||
toFlatObjectMetadataMaps:
|
||||
fromFlatObjectMetadatasToFlatObjectMetadataMaps([
|
||||
...STANDARD_RELATION_TARGET_FLAT_OBJECT_METADATA_MOCKS,
|
||||
{
|
||||
...ROCKET_FLAT_OBJECT_MOCK,
|
||||
flatIndexMetadatas: [
|
||||
getFlatIndexMetadataMock({
|
||||
objectMetadataId: ROCKET_FLAT_OBJECT_MOCK.id,
|
||||
universalIdentifier: 'field-metadata-unique-identifier-1',
|
||||
}),
|
||||
],
|
||||
},
|
||||
]),
|
||||
},
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
const UPDATE_OBJECT_TEST_CASES: WorkspaceMigrationBuilderTestCase[] = [
|
||||
|
||||
+5
-1
@@ -1,6 +1,7 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { AllFlatEntityMaps } from 'src/engine/core-modules/common/types/all-flat-entity-maps.type';
|
||||
import { deleteFlatEntityFromFlatEntityMapsOrThrow } from 'src/engine/core-modules/common/utils/delete-flat-entity-from-flat-entity-maps-or-throw.util';
|
||||
import { FlatIndexMetadata } from 'src/engine/metadata-modules/flat-index-metadata/types/flat-index-metadata.type';
|
||||
import { compareTwoFlatIndexMetadata } from 'src/engine/metadata-modules/flat-index-metadata/utils/compare-two-flat-index-metadata.util';
|
||||
import {
|
||||
@@ -139,7 +140,10 @@ export class WorkspaceMigrationV2IndexActionsBuilderService extends WorkspaceEnt
|
||||
this.flatIndexValidatorService.validateFlatIndexCreation({
|
||||
dependencyOptimisticFlatEntityMaps,
|
||||
flatIndexToValidate: toFlatIndex,
|
||||
optimisticFlatIndexMaps,
|
||||
optimisticFlatIndexMaps: deleteFlatEntityFromFlatEntityMapsOrThrow({
|
||||
entityToDeleteId: fromFlatIndex.id,
|
||||
flatEntityMaps: optimisticFlatIndexMaps,
|
||||
}),
|
||||
});
|
||||
|
||||
if (creationValidationResult.errors.length > 0) {
|
||||
|
||||
-38
@@ -1,38 +0,0 @@
|
||||
import { type FromTo } from 'twenty-shared/types';
|
||||
|
||||
import { type FlatIndexMetadata } from 'src/engine/metadata-modules/flat-index-metadata/types/flat-index-metadata.type';
|
||||
import {
|
||||
type FlatObjectMetadata,
|
||||
type FlatObjectMetadataWithoutFields,
|
||||
} from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type';
|
||||
import {
|
||||
type CustomDeletedCreatedUpdatedMatrix,
|
||||
deletedCreatedUpdatedMatrixDispatcher,
|
||||
} from 'src/engine/workspace-manager/workspace-migration-v2/utils/deleted-created-updated-matrix-dispatcher.util';
|
||||
|
||||
export type UpdatedObjectMetadataDeletedCreatedUpdatedIndexMatrix = {
|
||||
flatObjectMetadata: FlatObjectMetadataWithoutFields;
|
||||
} & CustomDeletedCreatedUpdatedMatrix<'indexMetadata', FlatIndexMetadata>;
|
||||
|
||||
export const computeUpdatedObjectMetadataDeletedCreatedUpdatedIndexMatrix = (
|
||||
updatedObjectMetadata: FromTo<FlatObjectMetadata>[],
|
||||
): UpdatedObjectMetadataDeletedCreatedUpdatedIndexMatrix[] => {
|
||||
const matrixAccumulator: UpdatedObjectMetadataDeletedCreatedUpdatedIndexMatrix[] =
|
||||
[];
|
||||
|
||||
for (const { from, to } of updatedObjectMetadata) {
|
||||
const indexMetadataMatrix = deletedCreatedUpdatedMatrixDispatcher({
|
||||
from: from.flatIndexMetadatas,
|
||||
to: to.flatIndexMetadatas,
|
||||
});
|
||||
|
||||
matrixAccumulator.push({
|
||||
flatObjectMetadata: to,
|
||||
createdIndexMetadata: indexMetadataMatrix.created,
|
||||
deletedIndexMetadata: indexMetadataMatrix.deleted,
|
||||
updatedIndexMetadata: indexMetadataMatrix.updated,
|
||||
});
|
||||
}
|
||||
|
||||
return matrixAccumulator;
|
||||
};
|
||||
-1
@@ -5,6 +5,5 @@ import {
|
||||
|
||||
export const fromFlatObjectMetadataToFlatObjectMetadataWithoutFields = ({
|
||||
flatFieldMetadatas: _flatFieldMetadatas,
|
||||
flatIndexMetadatas: _flatIndexMetadatas,
|
||||
...rest
|
||||
}: FlatObjectMetadata): FlatObjectMetadataWithoutFields => rest;
|
||||
|
||||
+2
-2
@@ -94,7 +94,7 @@ export class FlatIndexValidatorService {
|
||||
optimisticFlatIndexMaps.byId,
|
||||
).filter(isDefined);
|
||||
|
||||
const existingFlatIndexOnName = allExistingFlatIndex.some(
|
||||
const existingFlatIndexOnName = allExistingFlatIndex.find(
|
||||
(flatIndexMetadata) =>
|
||||
flatIndexMetadata.name.toLocaleUpperCase() ===
|
||||
flatIndexToValidate.name.toLocaleUpperCase(),
|
||||
@@ -102,7 +102,7 @@ export class FlatIndexValidatorService {
|
||||
|
||||
if (isDefined(existingFlatIndexOnName)) {
|
||||
validationResult.errors.push({
|
||||
code: IndexExceptionCode.INDEX_EMPTY_FIELDS,
|
||||
code: IndexExceptionCode.INDEX_ALREADY_EXISTS,
|
||||
message: t`Index with same name already exists`,
|
||||
userFriendlyMessage: t`Index with same name already exists`,
|
||||
});
|
||||
|
||||
+64
-6
@@ -1,13 +1,26 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import {
|
||||
OptimisticallyApplyActionOnAllFlatEntityMapsArgs,
|
||||
WorkspaceMigrationRunnerActionHandler,
|
||||
} from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/interfaces/workspace-migration-runner-action-handler-service.interface';
|
||||
|
||||
import {
|
||||
WorkspaceQueryRunnerException,
|
||||
WorkspaceQueryRunnerExceptionCode,
|
||||
} from 'src/engine/api/graphql/workspace-query-runner/workspace-query-runner.exception';
|
||||
import {
|
||||
FlatEntityMapsException,
|
||||
FlatEntityMapsExceptionCode,
|
||||
} from 'src/engine/core-modules/common/exceptions/flat-entity-maps.exception';
|
||||
import { AllFlatEntityMaps } from 'src/engine/core-modules/common/types/all-flat-entity-maps.type';
|
||||
import { addFlatEntityToFlatEntityMapsOrThrow } from 'src/engine/core-modules/common/utils/add-flat-entity-to-flat-entity-maps-or-throw.util';
|
||||
import { isMorphOrRelationFlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/utils/is-morph-or-relation-flat-field-metadata.util';
|
||||
import { findFlatFieldMetadataInFlatObjectMetadataMapsWithOnlyFieldId } from 'src/engine/metadata-modules/flat-object-metadata-maps/utils/find-flat-field-metadata-in-flat-object-metadata-maps-with-field-id-only.util';
|
||||
import { findFlatObjectMetadataInFlatObjectMetadataMapsOrThrow } from 'src/engine/metadata-modules/flat-object-metadata-maps/utils/find-flat-object-metadata-in-flat-object-metadata-maps-or-throw.util';
|
||||
import { IndexFieldMetadataEntity } from 'src/engine/metadata-modules/index-metadata/index-field-metadata.entity';
|
||||
import { IndexMetadataEntity } from 'src/engine/metadata-modules/index-metadata/index-metadata.entity';
|
||||
import { WorkspaceSchemaManagerService } from 'src/engine/twenty-orm/workspace-schema-manager/workspace-schema-manager.service';
|
||||
import { type CreateIndexAction } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/workspace-migration-index-action-v2';
|
||||
@@ -44,15 +57,34 @@ export class CreateIndexActionHandlerService extends WorkspaceMigrationRunnerAct
|
||||
queryRunner.manager.getRepository<IndexMetadataEntity>(
|
||||
IndexMetadataEntity,
|
||||
);
|
||||
const indexFieldMetadataRepository =
|
||||
queryRunner.manager.getRepository<IndexFieldMetadataEntity>(
|
||||
IndexFieldMetadataEntity,
|
||||
);
|
||||
|
||||
const {
|
||||
flatIndexMetadata: { flatIndexFieldMetadatas, ...rest },
|
||||
flatIndexMetadata: { flatIndexFieldMetadatas, ...flatIndexMetadata },
|
||||
} = action;
|
||||
|
||||
await indexMetadataRepository.insert({
|
||||
indexFieldMetadatas: flatIndexFieldMetadatas,
|
||||
...rest,
|
||||
});
|
||||
const indexInsertResult =
|
||||
await indexMetadataRepository.insert(flatIndexMetadata);
|
||||
|
||||
if (indexInsertResult.identifiers.length !== 1) {
|
||||
throw new WorkspaceQueryRunnerException(
|
||||
'Failed to create index metadata',
|
||||
WorkspaceQueryRunnerExceptionCode.INTERNAL_SERVER_ERROR,
|
||||
);
|
||||
}
|
||||
const indexMetadataId = indexInsertResult.identifiers[0].id;
|
||||
|
||||
const indexFieldMetadataToInsert = flatIndexFieldMetadatas.map(
|
||||
(flatIndexFieldMetadata) => ({
|
||||
...flatIndexFieldMetadata,
|
||||
indexMetadataId,
|
||||
}),
|
||||
);
|
||||
|
||||
await indexFieldMetadataRepository.insert(indexFieldMetadataToInsert);
|
||||
}
|
||||
|
||||
async executeForWorkspaceSchema(
|
||||
@@ -76,7 +108,33 @@ export class CreateIndexActionHandlerService extends WorkspaceMigrationRunnerAct
|
||||
});
|
||||
|
||||
const quotedColumns = flatIndexMetadata.flatIndexFieldMetadatas.map(
|
||||
(column) => `"${column}"`,
|
||||
({ fieldMetadataId }) => {
|
||||
const flatFieldMetadata =
|
||||
findFlatFieldMetadataInFlatObjectMetadataMapsWithOnlyFieldId({
|
||||
fieldMetadataId,
|
||||
flatObjectMetadataMaps,
|
||||
});
|
||||
|
||||
if (!isDefined(flatFieldMetadata)) {
|
||||
throw new FlatEntityMapsException(
|
||||
'Index field related field metadata not found',
|
||||
FlatEntityMapsExceptionCode.ENTITY_NOT_FOUND,
|
||||
);
|
||||
}
|
||||
|
||||
if (isMorphOrRelationFlatFieldMetadata(flatFieldMetadata)) {
|
||||
if (!isDefined(flatFieldMetadata.settings?.joinColumnName)) {
|
||||
throw new FlatEntityMapsException(
|
||||
'Join column name is not defined for relation field',
|
||||
FlatEntityMapsExceptionCode.ENTITY_NOT_FOUND,
|
||||
);
|
||||
}
|
||||
|
||||
return `"${flatFieldMetadata.settings.joinColumnName}"`;
|
||||
}
|
||||
|
||||
return `"${flatFieldMetadata.name}"`;
|
||||
},
|
||||
);
|
||||
|
||||
await this.workspaceSchemaManagerService.indexManager.createIndex({
|
||||
|
||||
+15
-16
@@ -8,16 +8,22 @@ import {
|
||||
import { AllFlatEntityMaps } from 'src/engine/core-modules/common/types/all-flat-entity-maps.type';
|
||||
import { deleteFlatEntityFromFlatEntityMapsOrThrow } from 'src/engine/core-modules/common/utils/delete-flat-entity-from-flat-entity-maps-or-throw.util';
|
||||
import { findFlatEntityByIdInFlatEntityMapsOrThrow } from 'src/engine/core-modules/common/utils/find-flat-entity-by-id-in-flat-entity-maps-or-throw.util';
|
||||
import { findFlatObjectMetadataInFlatObjectMetadataMapsOrThrow } from 'src/engine/metadata-modules/flat-object-metadata-maps/utils/find-flat-object-metadata-in-flat-object-metadata-maps-or-throw.util';
|
||||
import { IndexMetadataEntity } from 'src/engine/metadata-modules/index-metadata/index-metadata.entity';
|
||||
import { WorkspaceSchemaManagerService } from 'src/engine/twenty-orm/workspace-schema-manager/workspace-schema-manager.service';
|
||||
import { getWorkspaceSchemaName } from 'src/engine/workspace-datasource/utils/get-workspace-schema-name.util';
|
||||
import { type DeleteIndexAction } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/workspace-migration-index-action-v2';
|
||||
import { type WorkspaceMigrationActionRunnerArgs } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/types/workspace-migration-action-runner-args.type';
|
||||
import { getWorkspaceSchemaContextForMigration } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/utils/get-workspace-schema-context-for-migration.util';
|
||||
|
||||
@Injectable()
|
||||
export class DeleteIndexActionHandlerService extends WorkspaceMigrationRunnerActionHandler(
|
||||
'delete_index',
|
||||
) {
|
||||
constructor(
|
||||
private readonly workspaceSchemaManagerService: WorkspaceSchemaManagerService,
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
optimisticallyApplyActionOnAllFlatEntityMaps({
|
||||
action,
|
||||
allFlatEntityMaps: { flatIndexMaps },
|
||||
@@ -51,7 +57,7 @@ export class DeleteIndexActionHandlerService extends WorkspaceMigrationRunnerAct
|
||||
): Promise<void> {
|
||||
const {
|
||||
action,
|
||||
allFlatEntityMaps: { flatObjectMetadataMaps, flatIndexMaps },
|
||||
allFlatEntityMaps: { flatIndexMaps },
|
||||
queryRunner,
|
||||
workspaceId,
|
||||
} = context;
|
||||
@@ -63,19 +69,12 @@ export class DeleteIndexActionHandlerService extends WorkspaceMigrationRunnerAct
|
||||
},
|
||||
);
|
||||
|
||||
const flatObjectMetadata =
|
||||
findFlatObjectMetadataInFlatObjectMetadataMapsOrThrow({
|
||||
flatObjectMetadataMaps,
|
||||
objectMetadataId: flatIndexMetadataToDelete.objectMetadataId,
|
||||
});
|
||||
const { schemaName, tableName } = getWorkspaceSchemaContextForMigration({
|
||||
workspaceId,
|
||||
flatObjectMetadata,
|
||||
});
|
||||
const schemaName = getWorkspaceSchemaName(workspaceId);
|
||||
|
||||
await queryRunner.dropIndex(
|
||||
`${schemaName}.${tableName}`,
|
||||
flatIndexMetadataToDelete.name,
|
||||
);
|
||||
await this.workspaceSchemaManagerService.indexManager.dropIndex({
|
||||
indexName: flatIndexMetadataToDelete.name,
|
||||
queryRunner,
|
||||
schemaName,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
-1
@@ -48,7 +48,6 @@ export class CreateObjectActionHandlerService extends WorkspaceMigrationRunnerAc
|
||||
addFlatObjectMetadataToFlatObjectMetadataMapsOrThrow({
|
||||
flatObjectMetadata: {
|
||||
...flatObjectMetadataWithoutFields,
|
||||
flatIndexMetadatas: [],
|
||||
flatFieldMetadatas,
|
||||
},
|
||||
flatObjectMetadataMaps,
|
||||
|
||||
+100
-5
@@ -5,7 +5,38 @@ exports[`failing createOne FieldMetadataService morph relation fields v2 Morh re
|
||||
"extensions": {
|
||||
"code": "BAD_USER_INPUT",
|
||||
"errors": {
|
||||
"index": [],
|
||||
"index": [
|
||||
{
|
||||
"errors": [
|
||||
{
|
||||
"code": "INDEX_FIELD_NOT_FOUND",
|
||||
"message": "Could not find index field related field metadata",
|
||||
"userFriendlyMessage": "Field referenced in index does not exist",
|
||||
},
|
||||
],
|
||||
"flatEntityMinimalInformation": {
|
||||
"id": Any<String>,
|
||||
"name": "IDX_4a59b92546a3dbf54abee51283a",
|
||||
},
|
||||
"status": "fail",
|
||||
"type": "create_index",
|
||||
},
|
||||
{
|
||||
"errors": [
|
||||
{
|
||||
"code": "INDEX_FIELD_NOT_FOUND",
|
||||
"message": "Could not find index field related field metadata",
|
||||
"userFriendlyMessage": "Field referenced in index does not exist",
|
||||
},
|
||||
],
|
||||
"flatEntityMinimalInformation": {
|
||||
"id": Any<String>,
|
||||
"name": "IDX_247f630f4f88242063a98b01371",
|
||||
},
|
||||
"status": "fail",
|
||||
"type": "create_index",
|
||||
},
|
||||
],
|
||||
"objectMetadata": [
|
||||
{
|
||||
"errors": [
|
||||
@@ -179,7 +210,23 @@ exports[`failing createOne FieldMetadataService morph relation fields v2 it shou
|
||||
"extensions": {
|
||||
"code": "BAD_USER_INPUT",
|
||||
"errors": {
|
||||
"index": [],
|
||||
"index": [
|
||||
{
|
||||
"errors": [
|
||||
{
|
||||
"code": "INDEX_FIELD_NOT_FOUND",
|
||||
"message": "Could not find index field related field metadata",
|
||||
"userFriendlyMessage": "Field referenced in index does not exist",
|
||||
},
|
||||
],
|
||||
"flatEntityMinimalInformation": {
|
||||
"id": Any<String>,
|
||||
"name": "IDX_c1add8eb2b51d67721916a3e5a9",
|
||||
},
|
||||
"status": "fail",
|
||||
"type": "create_index",
|
||||
},
|
||||
],
|
||||
"objectMetadata": [
|
||||
{
|
||||
"errors": [
|
||||
@@ -227,7 +274,23 @@ exports[`failing createOne FieldMetadataService morph relation fields v2 it shou
|
||||
"extensions": {
|
||||
"code": "BAD_USER_INPUT",
|
||||
"errors": {
|
||||
"index": [],
|
||||
"index": [
|
||||
{
|
||||
"errors": [
|
||||
{
|
||||
"code": "INDEX_FIELD_NOT_FOUND",
|
||||
"message": "Could not find index field related field metadata",
|
||||
"userFriendlyMessage": "Field referenced in index does not exist",
|
||||
},
|
||||
],
|
||||
"flatEntityMinimalInformation": {
|
||||
"id": Any<String>,
|
||||
"name": "IDX_c84138bdf8bc3889ef56273281e",
|
||||
},
|
||||
"status": "fail",
|
||||
"type": "create_index",
|
||||
},
|
||||
],
|
||||
"objectMetadata": [
|
||||
{
|
||||
"errors": [
|
||||
@@ -269,7 +332,23 @@ exports[`failing createOne FieldMetadataService morph relation fields v2 it shou
|
||||
"extensions": {
|
||||
"code": "BAD_USER_INPUT",
|
||||
"errors": {
|
||||
"index": [],
|
||||
"index": [
|
||||
{
|
||||
"errors": [
|
||||
{
|
||||
"code": "INDEX_FIELD_NOT_FOUND",
|
||||
"message": "Could not find index field related field metadata",
|
||||
"userFriendlyMessage": "Field referenced in index does not exist",
|
||||
},
|
||||
],
|
||||
"flatEntityMinimalInformation": {
|
||||
"id": Any<String>,
|
||||
"name": "IDX_e07d8240883043fcb1ad1ba0324",
|
||||
},
|
||||
"status": "fail",
|
||||
"type": "create_index",
|
||||
},
|
||||
],
|
||||
"objectMetadata": [
|
||||
{
|
||||
"errors": [
|
||||
@@ -311,7 +390,23 @@ exports[`failing createOne FieldMetadataService morph relation fields v2 it shou
|
||||
"extensions": {
|
||||
"code": "BAD_USER_INPUT",
|
||||
"errors": {
|
||||
"index": [],
|
||||
"index": [
|
||||
{
|
||||
"errors": [
|
||||
{
|
||||
"code": "INDEX_FIELD_NOT_FOUND",
|
||||
"message": "Could not find index field related field metadata",
|
||||
"userFriendlyMessage": "Field referenced in index does not exist",
|
||||
},
|
||||
],
|
||||
"flatEntityMinimalInformation": {
|
||||
"id": Any<String>,
|
||||
"name": "IDX_c1add8eb2b51d67721916a3e5a9",
|
||||
},
|
||||
"status": "fail",
|
||||
"type": "create_index",
|
||||
},
|
||||
],
|
||||
"objectMetadata": [
|
||||
{
|
||||
"errors": [
|
||||
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`Index metadata creation through object metadata creation v2 Should create an index on ts-search-vector standard field when creating a custom object 1`] = `
|
||||
{
|
||||
"indexType": "GIN",
|
||||
"isCustom": false,
|
||||
"isUnique": false,
|
||||
"name": "IDX_be6fe08944beb9886fb83dfbbf1",
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Index metadata creation through object metadata creation v2 Should update index on related object name singular update 1`] = `
|
||||
{
|
||||
"indexType": "GIN",
|
||||
"isCustom": false,
|
||||
"isUnique": false,
|
||||
"name": "IDX_be6fe08944beb9886fb83dfbbf1",
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Index metadata creation through object metadata creation v2 Should update index on related object name singular update 2`] = `
|
||||
{
|
||||
"indexType": "GIN",
|
||||
"isCustom": false,
|
||||
"isUnique": false,
|
||||
"name": "IDX_e1506c1b3612d7f73c39fcaae6e",
|
||||
}
|
||||
`;
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`Index metadata creation on relation field creation v2 Should create and delete index on MANY_TO_ONE relation field creation and deletion 1`] = `
|
||||
{
|
||||
"indexFieldMetadataList": [
|
||||
{
|
||||
"createdAt": Any<String>,
|
||||
"fieldMetadataId": Any<String>,
|
||||
"id": Any<String>,
|
||||
"order": 0,
|
||||
"updatedAt": Any<String>,
|
||||
},
|
||||
],
|
||||
"indexType": "BTREE",
|
||||
"isCustom": true,
|
||||
"isUnique": false,
|
||||
"name": "IDX_c7afa9b8a4109b84530eafdacdb",
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Index metadata creation on relation field creation v2 Should create and delete index on ONE_TO_MANY relation field creation and deletion 1`] = `
|
||||
{
|
||||
"indexFieldMetadataList": [
|
||||
{
|
||||
"createdAt": Any<String>,
|
||||
"fieldMetadataId": Any<String>,
|
||||
"id": Any<String>,
|
||||
"order": 0,
|
||||
"updatedAt": Any<String>,
|
||||
},
|
||||
],
|
||||
"indexType": "BTREE",
|
||||
"isCustom": true,
|
||||
"isUnique": false,
|
||||
"name": "IDX_9343d8f57e4835944dffb85d501",
|
||||
}
|
||||
`;
|
||||
+151
@@ -0,0 +1,151 @@
|
||||
import { CUSTOM_OBJECT_DISHES } from 'test/integration/metadata/suites/object-metadata/constants/custom-object-dishes.constants';
|
||||
import { createOneObjectMetadata } from 'test/integration/metadata/suites/object-metadata/utils/create-one-object-metadata.util';
|
||||
import { deleteOneObjectMetadata } from 'test/integration/metadata/suites/object-metadata/utils/delete-one-object-metadata.util';
|
||||
import { findManyObjectMetadataWithIndexes } from 'test/integration/metadata/suites/object-metadata/utils/find-many-object-metadata-with-indexes.util';
|
||||
import { updateOneObjectMetadata } from 'test/integration/metadata/suites/object-metadata/utils/update-one-object-metadata.util';
|
||||
import { updateFeatureFlag } from 'test/integration/metadata/suites/utils/update-feature-flag.util';
|
||||
import { jestExpectToBeDefined } from 'test/utils/expect-to-be-defined.util.test';
|
||||
import { FieldMetadataType } from 'twenty-shared/types';
|
||||
|
||||
import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum';
|
||||
|
||||
const findObjectWithIndex = async ({
|
||||
objectMetadataId,
|
||||
}: {
|
||||
objectMetadataId: string;
|
||||
}) => {
|
||||
const objects = await findManyObjectMetadataWithIndexes({
|
||||
expectToFail: false,
|
||||
});
|
||||
|
||||
const foundObject = objects.find((object) => object.id === objectMetadataId);
|
||||
|
||||
jestExpectToBeDefined(foundObject);
|
||||
expect(foundObject.id).toBe(objectMetadataId);
|
||||
|
||||
return foundObject;
|
||||
};
|
||||
|
||||
describe('Index metadata creation through object metadata creation v2', () => {
|
||||
let createdObjectId: string;
|
||||
|
||||
beforeAll(async () => {
|
||||
await updateFeatureFlag({
|
||||
expectToFail: false,
|
||||
featureFlag: FeatureFlagKey.IS_WORKSPACE_MIGRATION_V2_ENABLED,
|
||||
value: true,
|
||||
});
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await updateFeatureFlag({
|
||||
expectToFail: false,
|
||||
featureFlag: FeatureFlagKey.IS_WORKSPACE_MIGRATION_V2_ENABLED,
|
||||
value: false,
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
const {
|
||||
labelPlural,
|
||||
description,
|
||||
labelSingular,
|
||||
namePlural,
|
||||
nameSingular,
|
||||
} = CUSTOM_OBJECT_DISHES;
|
||||
|
||||
const { data } = await createOneObjectMetadata({
|
||||
expectToFail: false,
|
||||
input: {
|
||||
labelPlural,
|
||||
description,
|
||||
labelSingular,
|
||||
namePlural,
|
||||
nameSingular,
|
||||
icon: 'IconTest',
|
||||
isLabelSyncedWithName: false,
|
||||
},
|
||||
gqlFields: `
|
||||
id
|
||||
`,
|
||||
});
|
||||
|
||||
createdObjectId = data.createOneObject.id;
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
await updateOneObjectMetadata({
|
||||
input: {
|
||||
idToUpdate: createdObjectId,
|
||||
updatePayload: {
|
||||
isActive: false,
|
||||
},
|
||||
},
|
||||
expectToFail: false,
|
||||
});
|
||||
await deleteOneObjectMetadata({
|
||||
expectToFail: false,
|
||||
input: { idToDelete: createdObjectId },
|
||||
});
|
||||
});
|
||||
|
||||
it('Should create an index on ts-search-vector standard field when creating a custom object', async () => {
|
||||
const foundObject = await findObjectWithIndex({
|
||||
objectMetadataId: createdObjectId,
|
||||
});
|
||||
const tsVectorField = foundObject.fieldsList.find(
|
||||
(field) => field.type === FieldMetadataType.TS_VECTOR,
|
||||
);
|
||||
|
||||
jestExpectToBeDefined(tsVectorField);
|
||||
|
||||
expect(foundObject.indexMetadataList.length).toBe(1);
|
||||
const { indexFieldMetadataList, ...index } =
|
||||
foundObject.indexMetadataList[0];
|
||||
|
||||
expect(index).toMatchSnapshot();
|
||||
expect(indexFieldMetadataList.length).toBe(1);
|
||||
expect(indexFieldMetadataList).toMatchObject([
|
||||
{
|
||||
id: expect.any(String),
|
||||
fieldMetadataId: tsVectorField.id,
|
||||
order: 0,
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it('Should update index on related object name singular update', async () => {
|
||||
const foundObject = await findObjectWithIndex({
|
||||
objectMetadataId: createdObjectId,
|
||||
});
|
||||
|
||||
expect(foundObject.indexMetadataList.length).toBe(1);
|
||||
const { indexFieldMetadataList: _, ...index } =
|
||||
foundObject.indexMetadataList[0];
|
||||
|
||||
expect(index).toMatchSnapshot();
|
||||
const fromIndexName = index.name;
|
||||
|
||||
await updateOneObjectMetadata({
|
||||
input: {
|
||||
idToUpdate: foundObject.id,
|
||||
updatePayload: {
|
||||
nameSingular: 'updatedName',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
{
|
||||
const foundObject = await findObjectWithIndex({
|
||||
objectMetadataId: createdObjectId,
|
||||
});
|
||||
|
||||
expect(foundObject.indexMetadataList.length).toBe(1);
|
||||
const { indexFieldMetadataList: _, ...index } =
|
||||
foundObject.indexMetadataList[0];
|
||||
|
||||
expect(index).toMatchSnapshot();
|
||||
expect(fromIndexName).not.toBe(index.name);
|
||||
}
|
||||
});
|
||||
});
|
||||
+353
@@ -0,0 +1,353 @@
|
||||
import { deleteOneObjectMetadata } from 'test/integration/metadata/suites/object-metadata/utils/delete-one-object-metadata.util';
|
||||
import { updateOneObjectMetadata } from 'test/integration/metadata/suites/object-metadata/utils/update-one-object-metadata.util';
|
||||
import { updateFeatureFlag } from 'test/integration/metadata/suites/utils/update-feature-flag.util';
|
||||
import { FieldMetadataType, RelationType } from 'twenty-shared/types';
|
||||
import { createOneFieldMetadata } from 'test/integration/metadata/suites/field-metadata/utils/create-one-field-metadata.util';
|
||||
import { deleteOneFieldMetadata } from 'test/integration/metadata/suites/field-metadata/utils/delete-one-field-metadata.util';
|
||||
import { updateOneFieldMetadata } from 'test/integration/metadata/suites/field-metadata/utils/update-one-field-metadata.util';
|
||||
import { CUSTOM_OBJECT_DISHES } from 'test/integration/metadata/suites/object-metadata/constants/custom-object-dishes.constants';
|
||||
import { CUSTOM_OBJECT_FOOD } from 'test/integration/metadata/suites/object-metadata/constants/custom-object-food.constants';
|
||||
import { createOneObjectMetadata } from 'test/integration/metadata/suites/object-metadata/utils/create-one-object-metadata.util';
|
||||
import { findManyObjectMetadataWithIndexes } from 'test/integration/metadata/suites/object-metadata/utils/find-many-object-metadata-with-indexes.util';
|
||||
import { jestExpectToBeDefined } from 'test/utils/expect-to-be-defined.util.test';
|
||||
import { extractRecordIdsAndDatesAsExpectAny } from 'test/utils/extract-record-ids-and-dates-as-expect-any';
|
||||
|
||||
import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum';
|
||||
|
||||
describe('Index metadata creation on relation field creation v2', () => {
|
||||
let createdObjectId: string;
|
||||
let secondCreatedObjectId: string;
|
||||
|
||||
beforeAll(async () => {
|
||||
await updateFeatureFlag({
|
||||
expectToFail: false,
|
||||
featureFlag: FeatureFlagKey.IS_WORKSPACE_MIGRATION_V2_ENABLED,
|
||||
value: true,
|
||||
});
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await updateFeatureFlag({
|
||||
expectToFail: false,
|
||||
featureFlag: FeatureFlagKey.IS_WORKSPACE_MIGRATION_V2_ENABLED,
|
||||
value: false,
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
const {
|
||||
labelPlural,
|
||||
description,
|
||||
labelSingular,
|
||||
namePlural,
|
||||
nameSingular,
|
||||
} = CUSTOM_OBJECT_DISHES;
|
||||
|
||||
const { data } = await createOneObjectMetadata({
|
||||
expectToFail: false,
|
||||
input: {
|
||||
labelPlural,
|
||||
description,
|
||||
labelSingular,
|
||||
namePlural,
|
||||
nameSingular,
|
||||
icon: 'IconTest',
|
||||
isLabelSyncedWithName: false,
|
||||
},
|
||||
gqlFields: `
|
||||
id
|
||||
`,
|
||||
});
|
||||
|
||||
createdObjectId = data.createOneObject.id;
|
||||
|
||||
{
|
||||
const {
|
||||
labelPlural,
|
||||
description,
|
||||
labelSingular,
|
||||
namePlural,
|
||||
nameSingular,
|
||||
} = CUSTOM_OBJECT_FOOD;
|
||||
const { data: secondData } = await createOneObjectMetadata({
|
||||
expectToFail: false,
|
||||
input: {
|
||||
labelPlural,
|
||||
description,
|
||||
labelSingular,
|
||||
namePlural,
|
||||
nameSingular,
|
||||
icon: 'IconTest',
|
||||
isLabelSyncedWithName: false,
|
||||
},
|
||||
gqlFields: `
|
||||
id
|
||||
`,
|
||||
});
|
||||
|
||||
secondCreatedObjectId = secondData.createOneObject.id;
|
||||
}
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
for (const objectMetadataId of [createdObjectId, secondCreatedObjectId]) {
|
||||
await updateOneObjectMetadata({
|
||||
input: {
|
||||
idToUpdate: objectMetadataId,
|
||||
updatePayload: {
|
||||
isActive: false,
|
||||
},
|
||||
},
|
||||
expectToFail: false,
|
||||
});
|
||||
await deleteOneObjectMetadata({
|
||||
expectToFail: false,
|
||||
input: { idToDelete: objectMetadataId },
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
it('Should create and delete index on MANY_TO_ONE relation field creation and deletion', async () => {
|
||||
await createOneFieldMetadata({
|
||||
expectToFail: false,
|
||||
input: {
|
||||
name: 'relationField',
|
||||
type: FieldMetadataType.RELATION,
|
||||
label: 'relation field',
|
||||
objectMetadataId: createdObjectId,
|
||||
relationCreationPayload: {
|
||||
type: RelationType.MANY_TO_ONE,
|
||||
targetFieldIcon: '123Icon',
|
||||
targetFieldLabel: 'whatever',
|
||||
targetObjectMetadataId: secondCreatedObjectId,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
let objects = await findManyObjectMetadataWithIndexes({
|
||||
expectToFail: false,
|
||||
});
|
||||
|
||||
const dishObject = objects.find((obj) => obj.id === createdObjectId);
|
||||
const foodObject = objects.find((obj) => obj.id === secondCreatedObjectId);
|
||||
|
||||
jestExpectToBeDefined(dishObject);
|
||||
jestExpectToBeDefined(foodObject);
|
||||
|
||||
const dishRelationField = dishObject.fieldsList.find(
|
||||
(field) =>
|
||||
field.type === FieldMetadataType.RELATION &&
|
||||
field.name === 'relationField',
|
||||
);
|
||||
|
||||
jestExpectToBeDefined(dishRelationField?.relation);
|
||||
expect(dishRelationField.relation.targetObjectMetadata.id).toBe(
|
||||
secondCreatedObjectId,
|
||||
);
|
||||
|
||||
const foodRelationField = foodObject.fieldsList.find(
|
||||
(field) =>
|
||||
field.type === FieldMetadataType.RELATION &&
|
||||
field.id === dishRelationField.relation?.targetFieldMetadata.id,
|
||||
);
|
||||
|
||||
jestExpectToBeDefined(foodRelationField);
|
||||
|
||||
const dishRelationFieldIndex = dishObject.indexMetadataList.find((index) =>
|
||||
index.indexFieldMetadataList.some(
|
||||
(indexField) => indexField.fieldMetadataId === dishRelationField.id,
|
||||
),
|
||||
);
|
||||
|
||||
jestExpectToBeDefined(dishRelationFieldIndex);
|
||||
expect(dishRelationFieldIndex).toMatchSnapshot(
|
||||
extractRecordIdsAndDatesAsExpectAny({ ...dishRelationFieldIndex }),
|
||||
);
|
||||
|
||||
const foodRelationFieldIndex = foodObject.indexMetadataList.find((index) =>
|
||||
index.indexFieldMetadataList.some(
|
||||
(indexField) => indexField.fieldMetadataId === foodRelationField.id,
|
||||
),
|
||||
);
|
||||
|
||||
expect(foodRelationFieldIndex).toBeUndefined();
|
||||
|
||||
await updateOneFieldMetadata({
|
||||
expectToFail: false,
|
||||
input: {
|
||||
idToUpdate: dishRelationField.id,
|
||||
updatePayload: {
|
||||
isActive: false,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
await deleteOneFieldMetadata({
|
||||
expectToFail: false,
|
||||
input: { idToDelete: dishRelationField.id },
|
||||
});
|
||||
|
||||
objects = await findManyObjectMetadataWithIndexes({
|
||||
expectToFail: false,
|
||||
});
|
||||
|
||||
const dishObjectAfterDeletion = objects.find(
|
||||
(obj) => obj.id === createdObjectId,
|
||||
);
|
||||
const foodObjectAfterDeletion = objects.find(
|
||||
(obj) => obj.id === secondCreatedObjectId,
|
||||
);
|
||||
|
||||
jestExpectToBeDefined(dishObjectAfterDeletion);
|
||||
jestExpectToBeDefined(foodObjectAfterDeletion);
|
||||
|
||||
const dishRelationFieldAfterDeletion =
|
||||
dishObjectAfterDeletion.fieldsList.find(
|
||||
(field) =>
|
||||
field.type === FieldMetadataType.RELATION &&
|
||||
field.name === 'relationField',
|
||||
);
|
||||
|
||||
expect(dishRelationFieldAfterDeletion).toBeUndefined();
|
||||
|
||||
const foodRelationFieldAfterDeletion =
|
||||
foodObjectAfterDeletion.fieldsList.find(
|
||||
(field) =>
|
||||
field.type === FieldMetadataType.RELATION &&
|
||||
field.id === dishRelationField?.relation?.targetFieldMetadata.id,
|
||||
);
|
||||
|
||||
expect(foodRelationFieldAfterDeletion).toBeUndefined();
|
||||
|
||||
const dishRelationFieldIndexAfterDeletion =
|
||||
dishObjectAfterDeletion.indexMetadataList.find((index) =>
|
||||
index.indexFieldMetadataList.some(
|
||||
(indexField) => indexField.fieldMetadataId === dishRelationField.id,
|
||||
),
|
||||
);
|
||||
|
||||
expect(dishRelationFieldIndexAfterDeletion).toBeUndefined();
|
||||
});
|
||||
|
||||
it('Should create and delete index on ONE_TO_MANY relation field creation and deletion', async () => {
|
||||
await createOneFieldMetadata({
|
||||
expectToFail: false,
|
||||
input: {
|
||||
name: 'relationField',
|
||||
type: FieldMetadataType.RELATION,
|
||||
label: 'relation field',
|
||||
objectMetadataId: createdObjectId,
|
||||
relationCreationPayload: {
|
||||
type: RelationType.ONE_TO_MANY,
|
||||
targetFieldIcon: '123Icon',
|
||||
targetFieldLabel: 'whatever',
|
||||
targetObjectMetadataId: secondCreatedObjectId,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
let objects = await findManyObjectMetadataWithIndexes({
|
||||
expectToFail: false,
|
||||
});
|
||||
|
||||
const dishObject = objects.find((obj) => obj.id === createdObjectId);
|
||||
const foodObject = objects.find((obj) => obj.id === secondCreatedObjectId);
|
||||
|
||||
jestExpectToBeDefined(dishObject);
|
||||
jestExpectToBeDefined(foodObject);
|
||||
|
||||
const dishRelationField = dishObject.fieldsList.find(
|
||||
(field) =>
|
||||
field.type === FieldMetadataType.RELATION &&
|
||||
field.name === 'relationField',
|
||||
);
|
||||
|
||||
jestExpectToBeDefined(dishRelationField?.relation);
|
||||
expect(dishRelationField.relation.targetObjectMetadata.id).toBe(
|
||||
secondCreatedObjectId,
|
||||
);
|
||||
|
||||
const foodRelationField = foodObject.fieldsList.find(
|
||||
(field) =>
|
||||
field.type === FieldMetadataType.RELATION &&
|
||||
field.id === dishRelationField.relation?.targetFieldMetadata.id,
|
||||
);
|
||||
|
||||
jestExpectToBeDefined(foodRelationField);
|
||||
|
||||
const foodRelationFieldIndex = foodObject.indexMetadataList.find((index) =>
|
||||
index.indexFieldMetadataList.some(
|
||||
(indexField) => indexField.fieldMetadataId === foodRelationField.id,
|
||||
),
|
||||
);
|
||||
|
||||
jestExpectToBeDefined(foodRelationFieldIndex);
|
||||
expect(foodRelationFieldIndex).toMatchSnapshot(
|
||||
extractRecordIdsAndDatesAsExpectAny({ ...foodRelationFieldIndex }),
|
||||
);
|
||||
|
||||
const dishRelationFieldIndex = dishObject.indexMetadataList.find((index) =>
|
||||
index.indexFieldMetadataList.some(
|
||||
(indexField) => indexField.fieldMetadataId === dishRelationField.id,
|
||||
),
|
||||
);
|
||||
|
||||
expect(dishRelationFieldIndex).toBeUndefined();
|
||||
|
||||
await updateOneFieldMetadata({
|
||||
expectToFail: false,
|
||||
input: {
|
||||
idToUpdate: dishRelationField.id,
|
||||
updatePayload: {
|
||||
isActive: false,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
await deleteOneFieldMetadata({
|
||||
expectToFail: false,
|
||||
input: { idToDelete: dishRelationField.id },
|
||||
});
|
||||
|
||||
objects = await findManyObjectMetadataWithIndexes({
|
||||
expectToFail: false,
|
||||
});
|
||||
|
||||
const dishObjectAfterDeletion = objects.find(
|
||||
(obj) => obj.id === createdObjectId,
|
||||
);
|
||||
const foodObjectAfterDeletion = objects.find(
|
||||
(obj) => obj.id === secondCreatedObjectId,
|
||||
);
|
||||
|
||||
jestExpectToBeDefined(dishObjectAfterDeletion);
|
||||
jestExpectToBeDefined(foodObjectAfterDeletion);
|
||||
|
||||
const dishRelationFieldAfterDeletion =
|
||||
dishObjectAfterDeletion.fieldsList.find(
|
||||
(field) =>
|
||||
field.type === FieldMetadataType.RELATION &&
|
||||
field.name === 'relationField',
|
||||
);
|
||||
|
||||
expect(dishRelationFieldAfterDeletion).toBeUndefined();
|
||||
|
||||
const foodRelationFieldAfterDeletion =
|
||||
foodObjectAfterDeletion.fieldsList.find(
|
||||
(field) =>
|
||||
field.type === FieldMetadataType.RELATION &&
|
||||
field.id === dishRelationField?.relation?.targetFieldMetadata.id,
|
||||
);
|
||||
|
||||
expect(foodRelationFieldAfterDeletion).toBeUndefined();
|
||||
|
||||
const foodRelationFieldIndexAfterDeletion =
|
||||
foodObjectAfterDeletion.indexMetadataList.find((index) =>
|
||||
index.indexFieldMetadataList.some(
|
||||
(indexField) => indexField.fieldMetadataId === dishRelationField.id,
|
||||
),
|
||||
);
|
||||
|
||||
expect(foodRelationFieldIndexAfterDeletion).toBeUndefined();
|
||||
});
|
||||
});
|
||||
+462
-21
@@ -5,7 +5,28 @@ exports[`Object metadata creation should fail v2 when labelPlural contains only
|
||||
"extensions": {
|
||||
"code": "BAD_USER_INPUT",
|
||||
"errors": {
|
||||
"index": [],
|
||||
"index": [
|
||||
{
|
||||
"errors": [
|
||||
{
|
||||
"code": "INDEX_OBJECT_NOT_FOUND",
|
||||
"message": "Could not find index related object metadata",
|
||||
"userFriendlyMessage": "Index related object not found",
|
||||
},
|
||||
{
|
||||
"code": "INDEX_FIELD_NOT_FOUND",
|
||||
"message": "Could not find index field related field metadata",
|
||||
"userFriendlyMessage": "Field referenced in index does not exist",
|
||||
},
|
||||
],
|
||||
"flatEntityMinimalInformation": {
|
||||
"id": Any<String>,
|
||||
"name": "IDX_ffebb98ec981552dbecc71223c8",
|
||||
},
|
||||
"status": "fail",
|
||||
"type": "create_index",
|
||||
},
|
||||
],
|
||||
"objectMetadata": [
|
||||
{
|
||||
"errors": [
|
||||
@@ -293,7 +314,28 @@ exports[`Object metadata creation should fail v2 when labelPlural exceeds maximu
|
||||
"extensions": {
|
||||
"code": "BAD_USER_INPUT",
|
||||
"errors": {
|
||||
"index": [],
|
||||
"index": [
|
||||
{
|
||||
"errors": [
|
||||
{
|
||||
"code": "INDEX_OBJECT_NOT_FOUND",
|
||||
"message": "Could not find index related object metadata",
|
||||
"userFriendlyMessage": "Index related object not found",
|
||||
},
|
||||
{
|
||||
"code": "INDEX_FIELD_NOT_FOUND",
|
||||
"message": "Could not find index field related field metadata",
|
||||
"userFriendlyMessage": "Field referenced in index does not exist",
|
||||
},
|
||||
],
|
||||
"flatEntityMinimalInformation": {
|
||||
"id": Any<String>,
|
||||
"name": "IDX_ffebb98ec981552dbecc71223c8",
|
||||
},
|
||||
"status": "fail",
|
||||
"type": "create_index",
|
||||
},
|
||||
],
|
||||
"objectMetadata": [
|
||||
{
|
||||
"errors": [
|
||||
@@ -581,7 +623,28 @@ exports[`Object metadata creation should fail v2 when labelPlural is empty 1`] =
|
||||
"extensions": {
|
||||
"code": "BAD_USER_INPUT",
|
||||
"errors": {
|
||||
"index": [],
|
||||
"index": [
|
||||
{
|
||||
"errors": [
|
||||
{
|
||||
"code": "INDEX_OBJECT_NOT_FOUND",
|
||||
"message": "Could not find index related object metadata",
|
||||
"userFriendlyMessage": "Index related object not found",
|
||||
},
|
||||
{
|
||||
"code": "INDEX_FIELD_NOT_FOUND",
|
||||
"message": "Could not find index field related field metadata",
|
||||
"userFriendlyMessage": "Field referenced in index does not exist",
|
||||
},
|
||||
],
|
||||
"flatEntityMinimalInformation": {
|
||||
"id": Any<String>,
|
||||
"name": "IDX_ffebb98ec981552dbecc71223c8",
|
||||
},
|
||||
"status": "fail",
|
||||
"type": "create_index",
|
||||
},
|
||||
],
|
||||
"objectMetadata": [
|
||||
{
|
||||
"errors": [
|
||||
@@ -869,7 +932,28 @@ exports[`Object metadata creation should fail v2 when labelSingular contains onl
|
||||
"extensions": {
|
||||
"code": "BAD_USER_INPUT",
|
||||
"errors": {
|
||||
"index": [],
|
||||
"index": [
|
||||
{
|
||||
"errors": [
|
||||
{
|
||||
"code": "INDEX_OBJECT_NOT_FOUND",
|
||||
"message": "Could not find index related object metadata",
|
||||
"userFriendlyMessage": "Index related object not found",
|
||||
},
|
||||
{
|
||||
"code": "INDEX_FIELD_NOT_FOUND",
|
||||
"message": "Could not find index field related field metadata",
|
||||
"userFriendlyMessage": "Field referenced in index does not exist",
|
||||
},
|
||||
],
|
||||
"flatEntityMinimalInformation": {
|
||||
"id": Any<String>,
|
||||
"name": "IDX_ffebb98ec981552dbecc71223c8",
|
||||
},
|
||||
"status": "fail",
|
||||
"type": "create_index",
|
||||
},
|
||||
],
|
||||
"objectMetadata": [
|
||||
{
|
||||
"errors": [
|
||||
@@ -1157,7 +1241,28 @@ exports[`Object metadata creation should fail v2 when labelSingular exceeds maxi
|
||||
"extensions": {
|
||||
"code": "BAD_USER_INPUT",
|
||||
"errors": {
|
||||
"index": [],
|
||||
"index": [
|
||||
{
|
||||
"errors": [
|
||||
{
|
||||
"code": "INDEX_OBJECT_NOT_FOUND",
|
||||
"message": "Could not find index related object metadata",
|
||||
"userFriendlyMessage": "Index related object not found",
|
||||
},
|
||||
{
|
||||
"code": "INDEX_FIELD_NOT_FOUND",
|
||||
"message": "Could not find index field related field metadata",
|
||||
"userFriendlyMessage": "Field referenced in index does not exist",
|
||||
},
|
||||
],
|
||||
"flatEntityMinimalInformation": {
|
||||
"id": Any<String>,
|
||||
"name": "IDX_ffebb98ec981552dbecc71223c8",
|
||||
},
|
||||
"status": "fail",
|
||||
"type": "create_index",
|
||||
},
|
||||
],
|
||||
"objectMetadata": [
|
||||
{
|
||||
"errors": [
|
||||
@@ -1445,7 +1550,28 @@ exports[`Object metadata creation should fail v2 when labelSingular is empty 1`]
|
||||
"extensions": {
|
||||
"code": "BAD_USER_INPUT",
|
||||
"errors": {
|
||||
"index": [],
|
||||
"index": [
|
||||
{
|
||||
"errors": [
|
||||
{
|
||||
"code": "INDEX_OBJECT_NOT_FOUND",
|
||||
"message": "Could not find index related object metadata",
|
||||
"userFriendlyMessage": "Index related object not found",
|
||||
},
|
||||
{
|
||||
"code": "INDEX_FIELD_NOT_FOUND",
|
||||
"message": "Could not find index field related field metadata",
|
||||
"userFriendlyMessage": "Field referenced in index does not exist",
|
||||
},
|
||||
],
|
||||
"flatEntityMinimalInformation": {
|
||||
"id": Any<String>,
|
||||
"name": "IDX_ffebb98ec981552dbecc71223c8",
|
||||
},
|
||||
"status": "fail",
|
||||
"type": "create_index",
|
||||
},
|
||||
],
|
||||
"objectMetadata": [
|
||||
{
|
||||
"errors": [
|
||||
@@ -1733,7 +1859,28 @@ exports[`Object metadata creation should fail v2 when labels are identical 1`] =
|
||||
"extensions": {
|
||||
"code": "BAD_USER_INPUT",
|
||||
"errors": {
|
||||
"index": [],
|
||||
"index": [
|
||||
{
|
||||
"errors": [
|
||||
{
|
||||
"code": "INDEX_OBJECT_NOT_FOUND",
|
||||
"message": "Could not find index related object metadata",
|
||||
"userFriendlyMessage": "Index related object not found",
|
||||
},
|
||||
{
|
||||
"code": "INDEX_FIELD_NOT_FOUND",
|
||||
"message": "Could not find index field related field metadata",
|
||||
"userFriendlyMessage": "Field referenced in index does not exist",
|
||||
},
|
||||
],
|
||||
"flatEntityMinimalInformation": {
|
||||
"id": Any<String>,
|
||||
"name": "IDX_ffebb98ec981552dbecc71223c8",
|
||||
},
|
||||
"status": "fail",
|
||||
"type": "create_index",
|
||||
},
|
||||
],
|
||||
"objectMetadata": [
|
||||
{
|
||||
"errors": [
|
||||
@@ -2022,7 +2169,28 @@ exports[`Object metadata creation should fail v2 when labels with whitespaces re
|
||||
"extensions": {
|
||||
"code": "BAD_USER_INPUT",
|
||||
"errors": {
|
||||
"index": [],
|
||||
"index": [
|
||||
{
|
||||
"errors": [
|
||||
{
|
||||
"code": "INDEX_OBJECT_NOT_FOUND",
|
||||
"message": "Could not find index related object metadata",
|
||||
"userFriendlyMessage": "Index related object not found",
|
||||
},
|
||||
{
|
||||
"code": "INDEX_FIELD_NOT_FOUND",
|
||||
"message": "Could not find index field related field metadata",
|
||||
"userFriendlyMessage": "Field referenced in index does not exist",
|
||||
},
|
||||
],
|
||||
"flatEntityMinimalInformation": {
|
||||
"id": Any<String>,
|
||||
"name": "IDX_ffebb98ec981552dbecc71223c8",
|
||||
},
|
||||
"status": "fail",
|
||||
"type": "create_index",
|
||||
},
|
||||
],
|
||||
"objectMetadata": [
|
||||
{
|
||||
"errors": [
|
||||
@@ -2311,7 +2479,28 @@ exports[`Object metadata creation should fail v2 when name exceeds maximum lengt
|
||||
"extensions": {
|
||||
"code": "BAD_USER_INPUT",
|
||||
"errors": {
|
||||
"index": [],
|
||||
"index": [
|
||||
{
|
||||
"errors": [
|
||||
{
|
||||
"code": "INDEX_OBJECT_NOT_FOUND",
|
||||
"message": "Could not find index related object metadata",
|
||||
"userFriendlyMessage": "Index related object not found",
|
||||
},
|
||||
{
|
||||
"code": "INDEX_FIELD_NOT_FOUND",
|
||||
"message": "Could not find index field related field metadata",
|
||||
"userFriendlyMessage": "Field referenced in index does not exist",
|
||||
},
|
||||
],
|
||||
"flatEntityMinimalInformation": {
|
||||
"id": Any<String>,
|
||||
"name": "IDX_da4ca4dc0c441477f29e4a384b0",
|
||||
},
|
||||
"status": "fail",
|
||||
"type": "create_index",
|
||||
},
|
||||
],
|
||||
"objectMetadata": [
|
||||
{
|
||||
"errors": [
|
||||
@@ -2679,7 +2868,28 @@ exports[`Object metadata creation should fail v2 when namePlural has invalid cha
|
||||
"extensions": {
|
||||
"code": "BAD_USER_INPUT",
|
||||
"errors": {
|
||||
"index": [],
|
||||
"index": [
|
||||
{
|
||||
"errors": [
|
||||
{
|
||||
"code": "INDEX_OBJECT_NOT_FOUND",
|
||||
"message": "Could not find index related object metadata",
|
||||
"userFriendlyMessage": "Index related object not found",
|
||||
},
|
||||
{
|
||||
"code": "INDEX_FIELD_NOT_FOUND",
|
||||
"message": "Could not find index field related field metadata",
|
||||
"userFriendlyMessage": "Field referenced in index does not exist",
|
||||
},
|
||||
],
|
||||
"flatEntityMinimalInformation": {
|
||||
"id": Any<String>,
|
||||
"name": "IDX_ffebb98ec981552dbecc71223c8",
|
||||
},
|
||||
"status": "fail",
|
||||
"type": "create_index",
|
||||
},
|
||||
],
|
||||
"objectMetadata": [
|
||||
{
|
||||
"errors": [
|
||||
@@ -2967,7 +3177,28 @@ exports[`Object metadata creation should fail v2 when namePlural is a reserved k
|
||||
"extensions": {
|
||||
"code": "BAD_USER_INPUT",
|
||||
"errors": {
|
||||
"index": [],
|
||||
"index": [
|
||||
{
|
||||
"errors": [
|
||||
{
|
||||
"code": "INDEX_OBJECT_NOT_FOUND",
|
||||
"message": "Could not find index related object metadata",
|
||||
"userFriendlyMessage": "Index related object not found",
|
||||
},
|
||||
{
|
||||
"code": "INDEX_FIELD_NOT_FOUND",
|
||||
"message": "Could not find index field related field metadata",
|
||||
"userFriendlyMessage": "Field referenced in index does not exist",
|
||||
},
|
||||
],
|
||||
"flatEntityMinimalInformation": {
|
||||
"id": Any<String>,
|
||||
"name": "IDX_ffebb98ec981552dbecc71223c8",
|
||||
},
|
||||
"status": "fail",
|
||||
"type": "create_index",
|
||||
},
|
||||
],
|
||||
"objectMetadata": [
|
||||
{
|
||||
"errors": [
|
||||
@@ -3255,7 +3486,28 @@ exports[`Object metadata creation should fail v2 when namePlural is an empty str
|
||||
"extensions": {
|
||||
"code": "BAD_USER_INPUT",
|
||||
"errors": {
|
||||
"index": [],
|
||||
"index": [
|
||||
{
|
||||
"errors": [
|
||||
{
|
||||
"code": "INDEX_OBJECT_NOT_FOUND",
|
||||
"message": "Could not find index related object metadata",
|
||||
"userFriendlyMessage": "Index related object not found",
|
||||
},
|
||||
{
|
||||
"code": "INDEX_FIELD_NOT_FOUND",
|
||||
"message": "Could not find index field related field metadata",
|
||||
"userFriendlyMessage": "Field referenced in index does not exist",
|
||||
},
|
||||
],
|
||||
"flatEntityMinimalInformation": {
|
||||
"id": Any<String>,
|
||||
"name": "IDX_ffebb98ec981552dbecc71223c8",
|
||||
},
|
||||
"status": "fail",
|
||||
"type": "create_index",
|
||||
},
|
||||
],
|
||||
"objectMetadata": [
|
||||
{
|
||||
"errors": [
|
||||
@@ -3548,7 +3800,28 @@ exports[`Object metadata creation should fail v2 when namePlural is not camelCas
|
||||
"extensions": {
|
||||
"code": "BAD_USER_INPUT",
|
||||
"errors": {
|
||||
"index": [],
|
||||
"index": [
|
||||
{
|
||||
"errors": [
|
||||
{
|
||||
"code": "INDEX_OBJECT_NOT_FOUND",
|
||||
"message": "Could not find index related object metadata",
|
||||
"userFriendlyMessage": "Index related object not found",
|
||||
},
|
||||
{
|
||||
"code": "INDEX_FIELD_NOT_FOUND",
|
||||
"message": "Could not find index field related field metadata",
|
||||
"userFriendlyMessage": "Field referenced in index does not exist",
|
||||
},
|
||||
],
|
||||
"flatEntityMinimalInformation": {
|
||||
"id": Any<String>,
|
||||
"name": "IDX_ffebb98ec981552dbecc71223c8",
|
||||
},
|
||||
"status": "fail",
|
||||
"type": "create_index",
|
||||
},
|
||||
],
|
||||
"objectMetadata": [
|
||||
{
|
||||
"errors": [
|
||||
@@ -3841,7 +4114,28 @@ exports[`Object metadata creation should fail v2 when nameSingular contains only
|
||||
"extensions": {
|
||||
"code": "BAD_USER_INPUT",
|
||||
"errors": {
|
||||
"index": [],
|
||||
"index": [
|
||||
{
|
||||
"errors": [
|
||||
{
|
||||
"code": "INDEX_OBJECT_NOT_FOUND",
|
||||
"message": "Could not find index related object metadata",
|
||||
"userFriendlyMessage": "Index related object not found",
|
||||
},
|
||||
{
|
||||
"code": "INDEX_FIELD_NOT_FOUND",
|
||||
"message": "Could not find index field related field metadata",
|
||||
"userFriendlyMessage": "Field referenced in index does not exist",
|
||||
},
|
||||
],
|
||||
"flatEntityMinimalInformation": {
|
||||
"id": Any<String>,
|
||||
"name": "IDX_2e70d840ef39341865172574229",
|
||||
},
|
||||
"status": "fail",
|
||||
"type": "create_index",
|
||||
},
|
||||
],
|
||||
"objectMetadata": [
|
||||
{
|
||||
"errors": [
|
||||
@@ -4244,7 +4538,28 @@ exports[`Object metadata creation should fail v2 when nameSingular contains only
|
||||
"extensions": {
|
||||
"code": "BAD_USER_INPUT",
|
||||
"errors": {
|
||||
"index": [],
|
||||
"index": [
|
||||
{
|
||||
"errors": [
|
||||
{
|
||||
"code": "INDEX_OBJECT_NOT_FOUND",
|
||||
"message": "Could not find index related object metadata",
|
||||
"userFriendlyMessage": "Index related object not found",
|
||||
},
|
||||
{
|
||||
"code": "INDEX_FIELD_NOT_FOUND",
|
||||
"message": "Could not find index field related field metadata",
|
||||
"userFriendlyMessage": "Field referenced in index does not exist",
|
||||
},
|
||||
],
|
||||
"flatEntityMinimalInformation": {
|
||||
"id": Any<String>,
|
||||
"name": "IDX_e0b8367f7f89bf39915991232b6",
|
||||
},
|
||||
"status": "fail",
|
||||
"type": "create_index",
|
||||
},
|
||||
],
|
||||
"objectMetadata": [
|
||||
{
|
||||
"errors": [
|
||||
@@ -4647,7 +4962,28 @@ exports[`Object metadata creation should fail v2 when nameSingular has invalid c
|
||||
"extensions": {
|
||||
"code": "BAD_USER_INPUT",
|
||||
"errors": {
|
||||
"index": [],
|
||||
"index": [
|
||||
{
|
||||
"errors": [
|
||||
{
|
||||
"code": "INDEX_OBJECT_NOT_FOUND",
|
||||
"message": "Could not find index related object metadata",
|
||||
"userFriendlyMessage": "Index related object not found",
|
||||
},
|
||||
{
|
||||
"code": "INDEX_FIELD_NOT_FOUND",
|
||||
"message": "Could not find index field related field metadata",
|
||||
"userFriendlyMessage": "Field referenced in index does not exist",
|
||||
},
|
||||
],
|
||||
"flatEntityMinimalInformation": {
|
||||
"id": Any<String>,
|
||||
"name": "IDX_e895f7d7a9fc30bad070509afab",
|
||||
},
|
||||
"status": "fail",
|
||||
"type": "create_index",
|
||||
},
|
||||
],
|
||||
"objectMetadata": [
|
||||
{
|
||||
"errors": [
|
||||
@@ -5015,7 +5351,28 @@ exports[`Object metadata creation should fail v2 when nameSingular is a reserved
|
||||
"extensions": {
|
||||
"code": "BAD_USER_INPUT",
|
||||
"errors": {
|
||||
"index": [],
|
||||
"index": [
|
||||
{
|
||||
"errors": [
|
||||
{
|
||||
"code": "INDEX_OBJECT_NOT_FOUND",
|
||||
"message": "Could not find index related object metadata",
|
||||
"userFriendlyMessage": "Index related object not found",
|
||||
},
|
||||
{
|
||||
"code": "INDEX_FIELD_NOT_FOUND",
|
||||
"message": "Could not find index field related field metadata",
|
||||
"userFriendlyMessage": "Field referenced in index does not exist",
|
||||
},
|
||||
],
|
||||
"flatEntityMinimalInformation": {
|
||||
"id": Any<String>,
|
||||
"name": "IDX_00aaf7dba3ae2d70218bdebd383",
|
||||
},
|
||||
"status": "fail",
|
||||
"type": "create_index",
|
||||
},
|
||||
],
|
||||
"objectMetadata": [
|
||||
{
|
||||
"errors": [
|
||||
@@ -5383,7 +5740,28 @@ exports[`Object metadata creation should fail v2 when nameSingular is an empty s
|
||||
"extensions": {
|
||||
"code": "BAD_USER_INPUT",
|
||||
"errors": {
|
||||
"index": [],
|
||||
"index": [
|
||||
{
|
||||
"errors": [
|
||||
{
|
||||
"code": "INDEX_OBJECT_NOT_FOUND",
|
||||
"message": "Could not find index related object metadata",
|
||||
"userFriendlyMessage": "Index related object not found",
|
||||
},
|
||||
{
|
||||
"code": "INDEX_FIELD_NOT_FOUND",
|
||||
"message": "Could not find index field related field metadata",
|
||||
"userFriendlyMessage": "Field referenced in index does not exist",
|
||||
},
|
||||
],
|
||||
"flatEntityMinimalInformation": {
|
||||
"id": Any<String>,
|
||||
"name": "IDX_e0b8367f7f89bf39915991232b6",
|
||||
},
|
||||
"status": "fail",
|
||||
"type": "create_index",
|
||||
},
|
||||
],
|
||||
"objectMetadata": [
|
||||
{
|
||||
"errors": [
|
||||
@@ -5786,7 +6164,28 @@ exports[`Object metadata creation should fail v2 when nameSingular is not camelC
|
||||
"extensions": {
|
||||
"code": "BAD_USER_INPUT",
|
||||
"errors": {
|
||||
"index": [],
|
||||
"index": [
|
||||
{
|
||||
"errors": [
|
||||
{
|
||||
"code": "INDEX_OBJECT_NOT_FOUND",
|
||||
"message": "Could not find index related object metadata",
|
||||
"userFriendlyMessage": "Index related object not found",
|
||||
},
|
||||
{
|
||||
"code": "INDEX_FIELD_NOT_FOUND",
|
||||
"message": "Could not find index field related field metadata",
|
||||
"userFriendlyMessage": "Field referenced in index does not exist",
|
||||
},
|
||||
],
|
||||
"flatEntityMinimalInformation": {
|
||||
"id": Any<String>,
|
||||
"name": "IDX_17a51d4440e492a8ec4d594c445",
|
||||
},
|
||||
"status": "fail",
|
||||
"type": "create_index",
|
||||
},
|
||||
],
|
||||
"objectMetadata": [
|
||||
{
|
||||
"errors": [
|
||||
@@ -6189,7 +6588,28 @@ exports[`Object metadata creation should fail v2 when names are identical 1`] =
|
||||
"extensions": {
|
||||
"code": "BAD_USER_INPUT",
|
||||
"errors": {
|
||||
"index": [],
|
||||
"index": [
|
||||
{
|
||||
"errors": [
|
||||
{
|
||||
"code": "INDEX_OBJECT_NOT_FOUND",
|
||||
"message": "Could not find index related object metadata",
|
||||
"userFriendlyMessage": "Index related object not found",
|
||||
},
|
||||
{
|
||||
"code": "INDEX_FIELD_NOT_FOUND",
|
||||
"message": "Could not find index field related field metadata",
|
||||
"userFriendlyMessage": "Field referenced in index does not exist",
|
||||
},
|
||||
],
|
||||
"flatEntityMinimalInformation": {
|
||||
"id": Any<String>,
|
||||
"name": "IDX_acbec9630e5330ad7c000993538",
|
||||
},
|
||||
"status": "fail",
|
||||
"type": "create_index",
|
||||
},
|
||||
],
|
||||
"objectMetadata": [
|
||||
{
|
||||
"errors": [
|
||||
@@ -6478,7 +6898,28 @@ exports[`Object metadata creation should fail v2 when names with whitespaces res
|
||||
"extensions": {
|
||||
"code": "BAD_USER_INPUT",
|
||||
"errors": {
|
||||
"index": [],
|
||||
"index": [
|
||||
{
|
||||
"errors": [
|
||||
{
|
||||
"code": "INDEX_OBJECT_NOT_FOUND",
|
||||
"message": "Could not find index related object metadata",
|
||||
"userFriendlyMessage": "Index related object not found",
|
||||
},
|
||||
{
|
||||
"code": "INDEX_FIELD_NOT_FOUND",
|
||||
"message": "Could not find index field related field metadata",
|
||||
"userFriendlyMessage": "Field referenced in index does not exist",
|
||||
},
|
||||
],
|
||||
"flatEntityMinimalInformation": {
|
||||
"id": Any<String>,
|
||||
"name": "IDX_acbec9630e5330ad7c000993538",
|
||||
},
|
||||
"status": "fail",
|
||||
"type": "create_index",
|
||||
},
|
||||
],
|
||||
"objectMetadata": [
|
||||
{
|
||||
"errors": [
|
||||
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type';
|
||||
|
||||
export const CUSTOM_OBJECT_FOOD = {
|
||||
namePlural: 'foods',
|
||||
nameSingular: 'food',
|
||||
description: 'My favorite foods',
|
||||
labelPlural: 'Foods I love',
|
||||
labelSingular: 'food I love',
|
||||
} as const satisfies Partial<FlatObjectMetadata>;
|
||||
+2
-2
@@ -8,14 +8,14 @@ import { type PerformMetadataQueryParams } from 'test/integration/metadata/types
|
||||
import { warnIfErrorButNotExpectedToFail } from 'test/integration/metadata/utils/warn-if-error-but-not-expected-to-fail.util';
|
||||
import { warnIfNoErrorButExpectedToFail } from 'test/integration/metadata/utils/warn-if-no-error-but-expected-to-fail.util';
|
||||
|
||||
import { type ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||
import { type ObjectMetadataDTO } from 'src/engine/metadata-modules/object-metadata/dtos/object-metadata.dto';
|
||||
|
||||
export const createOneObjectMetadata = async ({
|
||||
input,
|
||||
gqlFields,
|
||||
expectToFail,
|
||||
}: PerformMetadataQueryParams<CreateOneObjectFactoryInput>): CommonResponseBody<{
|
||||
createOneObject: ObjectMetadataEntity; // not accurate
|
||||
createOneObject: ObjectMetadataDTO;
|
||||
}> => {
|
||||
const graphqlOperation = createOneObjectMetadataQueryFactory({
|
||||
input,
|
||||
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
import { findManyObjectMetadata } from 'test/integration/metadata/suites/object-metadata/utils/find-many-object-metadata.util';
|
||||
|
||||
import { type FieldMetadataDTO } from 'src/engine/metadata-modules/field-metadata/dtos/field-metadata.dto';
|
||||
import { type RelationDTO } from 'src/engine/metadata-modules/field-metadata/dtos/relation.dto';
|
||||
import { type IndexFieldMetadataDTO } from 'src/engine/metadata-modules/index-metadata/dtos/index-field-metadata.dto';
|
||||
import { type IndexMetadataDTO } from 'src/engine/metadata-modules/index-metadata/dtos/index-metadata.dto';
|
||||
import { type ObjectMetadataDTO } from 'src/engine/metadata-modules/object-metadata/dtos/object-metadata.dto';
|
||||
|
||||
export const findManyObjectMetadataWithIndexes = async ({
|
||||
expectToFail,
|
||||
}: {
|
||||
expectToFail: boolean;
|
||||
}) => {
|
||||
const { objects } = await findManyObjectMetadata({
|
||||
expectToFail,
|
||||
input: {
|
||||
filter: {},
|
||||
paging: {
|
||||
first: 100,
|
||||
},
|
||||
},
|
||||
gqlFields: `
|
||||
id
|
||||
nameSingular
|
||||
fieldsList {
|
||||
id
|
||||
type
|
||||
name
|
||||
relation {
|
||||
type
|
||||
sourceObjectMetadata {
|
||||
id
|
||||
nameSingular
|
||||
namePlural
|
||||
}
|
||||
targetObjectMetadata {
|
||||
id
|
||||
nameSingular
|
||||
namePlural
|
||||
}
|
||||
sourceFieldMetadata {
|
||||
id
|
||||
name
|
||||
}
|
||||
targetFieldMetadata {
|
||||
id
|
||||
name
|
||||
}
|
||||
}
|
||||
}
|
||||
indexMetadataList {
|
||||
name
|
||||
isUnique
|
||||
isCustom
|
||||
indexType
|
||||
indexFieldMetadataList {
|
||||
id
|
||||
fieldMetadataId
|
||||
createdAt
|
||||
updatedAt
|
||||
order
|
||||
}
|
||||
}
|
||||
`,
|
||||
});
|
||||
|
||||
return objects as Array<
|
||||
ObjectMetadataDTO & {
|
||||
fieldsList: (FieldMetadataDTO & { relation: RelationDTO | null })[];
|
||||
indexMetadataList: Array<
|
||||
IndexMetadataDTO & {
|
||||
indexFieldMetadataList: IndexFieldMetadataDTO[];
|
||||
}
|
||||
>;
|
||||
}
|
||||
>;
|
||||
};
|
||||
Reference in New Issue
Block a user