feat: refactor folder structure (#4498)

* feat: wip refactor folder structure

* Fix

* fix position

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
Jérémy M
2024-03-15 14:40:58 +01:00
committed by GitHub
parent 52f1b3ac98
commit 94487f6737
760 changed files with 3215 additions and 3155 deletions

View File

@ -0,0 +1,76 @@
import {
ComputedPartialObjectMetadata,
PartialObjectMetadata,
} from 'src/engine/workspace-manager/workspace-sync-metadata/interfaces/partial-object-metadata.interface';
import { ComputedPartialFieldMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/interfaces/partial-field-metadata.interface';
import { ObjectMetadataEntity } from 'src/engine-metadata/object-metadata/object-metadata.entity';
import { generateTargetColumnMap } from 'src/engine-metadata/field-metadata/utils/generate-target-column-map.util';
import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity';
import { createDeterministicUuid } from 'src/engine/workspace-manager/workspace-sync-metadata/utils/create-deterministic-uuid.util';
export const computeStandardObject = (
standardObjectMetadata: Omit<PartialObjectMetadata, 'standardId'> & {
standardId: string | null;
},
originalObjectMetadata: ObjectMetadataEntity,
customObjectMetadataCollection: ObjectMetadataEntity[] = [],
): ComputedPartialObjectMetadata => {
const fields: ComputedPartialFieldMetadata[] = [];
for (const partialFieldMetadata of standardObjectMetadata.fields) {
if ('paramsFactory' in partialFieldMetadata) {
// Compute standard fields of custom object
for (const customObjectMetadata of customObjectMetadataCollection) {
const { paramsFactory, ...rest } = partialFieldMetadata;
const { joinColumn, ...data } = paramsFactory(customObjectMetadata);
// Relation
fields.push({
...data,
...rest,
defaultValue: null,
targetColumnMap: {},
});
// Foreign key
fields.push({
...rest,
standardId: createDeterministicUuid(data.standardId),
name: joinColumn,
type: FieldMetadataType.UUID,
label: `${data.label} ID (foreign key)`,
description: `${data.description} id foreign key`,
defaultValue: null,
icon: undefined,
targetColumnMap: generateTargetColumnMap(
FieldMetadataType.UUID,
rest.isCustom,
joinColumn,
),
isSystem: true,
});
}
} else {
const labelText =
typeof partialFieldMetadata.label === 'function'
? partialFieldMetadata.label(originalObjectMetadata)
: partialFieldMetadata.label;
const descriptionText =
typeof partialFieldMetadata.description === 'function'
? partialFieldMetadata.description(originalObjectMetadata)
: partialFieldMetadata.description;
fields.push({
...partialFieldMetadata,
label: labelText,
description: descriptionText,
});
}
}
return {
...standardObjectMetadata,
fields,
};
};

View File

@ -0,0 +1,12 @@
import { camelCase } from 'src/utils/camel-case';
export const convertClassNameToObjectMetadataName = (name: string): string => {
const classSuffix = 'ObjectMetadata';
let objectName = camelCase(name);
if (objectName.endsWith(classSuffix)) {
objectName = objectName.slice(0, -classSuffix.length);
}
return objectName;
};

View File

@ -0,0 +1,10 @@
import { createHash } from 'crypto';
export const createDeterministicUuid = (inputUuid: string): string => {
const hash = createHash('sha256').update(inputUuid).digest('hex');
return `20202020-${hash.substring(0, 4)}-4${hash.substring(
4,
7,
)}-8${hash.substring(7, 10)}-${hash.substring(10, 22)}`;
};

View File

@ -0,0 +1,11 @@
import { GateDecoratorParams } from 'src/engine/workspace-manager/workspace-sync-metadata/interfaces/gate-decorator.interface';
export const isGatedAndNotEnabled = (
gate: GateDecoratorParams | undefined,
workspaceFeatureFlagsMap: Record<string, boolean>,
): boolean => {
const featureFlagValue =
gate?.featureFlag && workspaceFeatureFlagsMap[gate.featureFlag];
return gate?.featureFlag !== undefined && !featureFlagValue;
};

View File

@ -0,0 +1,60 @@
import { ObjectMetadataEntity } from 'src/engine-metadata/object-metadata/object-metadata.entity';
import { FieldMetadataType } from 'src/engine-metadata/field-metadata/field-metadata.entity';
import { mapObjectMetadataByUniqueIdentifier } from './sync-metadata.util';
describe('mapObjectMetadataByUniqueIdentifier', () => {
it('should convert an array of ObjectMetadataEntity objects into a map', () => {
const arr: DeepPartial<ObjectMetadataEntity>[] = [
{
standardId: 'user',
nameSingular: 'user',
fields: [
{ name: 'id', type: FieldMetadataType.UUID },
{ name: 'name', type: FieldMetadataType.TEXT },
],
},
{
standardId: 'product',
nameSingular: 'product',
fields: [
{ name: 'id', type: FieldMetadataType.UUID },
{ name: 'name', type: FieldMetadataType.TEXT },
{ name: 'price', type: FieldMetadataType.UUID },
],
},
];
const mappedObject = mapObjectMetadataByUniqueIdentifier(
arr as ObjectMetadataEntity[],
);
expect(mappedObject).toEqual({
user: {
standardId: 'user',
nameSingular: 'user',
fields: [
{ name: 'id', type: FieldMetadataType.UUID },
{ name: 'name', type: FieldMetadataType.TEXT },
],
},
product: {
standardId: 'product',
nameSingular: 'product',
fields: [
{ name: 'id', type: FieldMetadataType.UUID },
{ name: 'name', type: FieldMetadataType.TEXT },
{ name: 'price', type: FieldMetadataType.UUID },
],
},
});
});
it('should return an empty map if the input array is empty', () => {
const arr: ObjectMetadataEntity[] = [];
const mappedObject = mapObjectMetadataByUniqueIdentifier(arr);
expect(mappedObject).toEqual({});
});
});

View File

@ -0,0 +1,31 @@
/**
* This utility function converts an array of ObjectMetadataEntity objects into a map,
* where the keys are the nameSingular properties of the objects.
* Each object in the map contains the original object metadata and its fields as a nested map.
*
* @param arr - The array of ObjectMetadataEntity objects to convert.
* @returns A map of object metadata, with nameSingular as the key and the object as the value.
*/
export const mapObjectMetadataByUniqueIdentifier = <
T extends { standardId: string | null },
>(
arr: T[],
keyFactory: (obj: T) => string | null = (obj) => obj.standardId,
): Record<string, T> => {
return arr.reduce(
(acc, curr) => {
const key = keyFactory(curr);
if (!key) {
return acc;
}
acc[key] = {
...curr,
};
return acc;
},
{} as Record<string, T>,
);
};