Migrate to a monorepo structure (#2909)
This commit is contained in:
+113
@@ -0,0 +1,113 @@
|
||||
import assert from 'assert';
|
||||
|
||||
import { FieldMetadataEntity } from 'src/metadata/field-metadata/field-metadata.entity';
|
||||
import { ObjectMetadataEntity } from 'src/metadata/object-metadata/object-metadata.entity';
|
||||
import { BaseObjectMetadata } from 'src/workspace/workspace-sync-metadata/standard-objects/base.object-metadata';
|
||||
|
||||
export class MetadataParser {
|
||||
static parseMetadata(
|
||||
metadata: typeof BaseObjectMetadata,
|
||||
workspaceId: string,
|
||||
dataSourceId: string,
|
||||
) {
|
||||
const objectMetadata = Reflect.getMetadata('objectMetadata', metadata);
|
||||
const fieldMetadata = Reflect.getMetadata('fieldMetadata', metadata);
|
||||
|
||||
if (objectMetadata) {
|
||||
const fields = Object.values(fieldMetadata);
|
||||
|
||||
return {
|
||||
...objectMetadata,
|
||||
workspaceId,
|
||||
dataSourceId,
|
||||
fields: fields.map((field: FieldMetadataEntity) => ({
|
||||
...field,
|
||||
workspaceId,
|
||||
isSystem: objectMetadata.isSystem || field.isSystem,
|
||||
defaultValue: field.defaultValue || null,
|
||||
options: field.options || null,
|
||||
})),
|
||||
};
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
static parseAllMetadata(
|
||||
metadataCollection: (typeof BaseObjectMetadata)[],
|
||||
workspaceId: string,
|
||||
dataSourceId: string,
|
||||
) {
|
||||
return metadataCollection.map((metadata) =>
|
||||
MetadataParser.parseMetadata(metadata, workspaceId, dataSourceId),
|
||||
);
|
||||
}
|
||||
|
||||
static parseRelationMetadata(
|
||||
metadata: typeof BaseObjectMetadata,
|
||||
workspaceId: string,
|
||||
objectMetadataFromDB: Record<string, ObjectMetadataEntity>,
|
||||
) {
|
||||
const objectMetadata = Reflect.getMetadata('objectMetadata', metadata);
|
||||
const relationMetadata = Reflect.getMetadata('relationMetadata', metadata);
|
||||
|
||||
if (!relationMetadata) return [];
|
||||
|
||||
return relationMetadata.map((relation) => {
|
||||
const fromObjectMetadata =
|
||||
objectMetadataFromDB[relation.fromObjectNameSingular];
|
||||
assert(
|
||||
fromObjectMetadata,
|
||||
`Object ${relation.fromObjectNameSingular} not found in DB
|
||||
for relation defined in class ${objectMetadata.nameSingular}`,
|
||||
);
|
||||
|
||||
const toObjectMetadata =
|
||||
objectMetadataFromDB[relation.toObjectNameSingular];
|
||||
assert(
|
||||
toObjectMetadata,
|
||||
`Object ${relation.toObjectNameSingular} not found in DB
|
||||
for relation defined in class ${objectMetadata.nameSingular}`,
|
||||
);
|
||||
|
||||
const fromFieldMetadata =
|
||||
fromObjectMetadata?.fields[relation.fromFieldMetadataName];
|
||||
assert(
|
||||
fromFieldMetadata,
|
||||
`Field ${relation.fromFieldMetadataName} not found in object ${relation.fromObjectNameSingular}
|
||||
for relation defined in class ${objectMetadata.nameSingular}`,
|
||||
);
|
||||
|
||||
const toFieldMetadata =
|
||||
toObjectMetadata?.fields[relation.toFieldMetadataName];
|
||||
assert(
|
||||
toFieldMetadata,
|
||||
`Field ${relation.toFieldMetadataName} not found in object ${relation.toObjectNameSingular}
|
||||
for relation defined in class ${objectMetadata.nameSingular}`,
|
||||
);
|
||||
|
||||
return {
|
||||
relationType: relation.type,
|
||||
fromObjectMetadataId: fromObjectMetadata?.id,
|
||||
toObjectMetadataId: toObjectMetadata?.id,
|
||||
fromFieldMetadataId: fromFieldMetadata?.id,
|
||||
toFieldMetadataId: toFieldMetadata?.id,
|
||||
workspaceId,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
static parseAllRelations(
|
||||
metadataCollection: (typeof BaseObjectMetadata)[],
|
||||
workspaceId: string,
|
||||
objectMetadataFromDB: Record<string, ObjectMetadataEntity>,
|
||||
) {
|
||||
return metadataCollection.flatMap((metadata) =>
|
||||
MetadataParser.parseRelationMetadata(
|
||||
metadata,
|
||||
workspaceId,
|
||||
objectMetadataFromDB,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
+101
@@ -0,0 +1,101 @@
|
||||
import { ObjectMetadataEntity } from 'src/metadata/object-metadata/object-metadata.entity';
|
||||
import { FieldMetadataType } from 'src/metadata/field-metadata/field-metadata.entity';
|
||||
|
||||
import {
|
||||
filterIgnoredProperties,
|
||||
mapObjectMetadataByUniqueIdentifier,
|
||||
} from './sync-metadata.util';
|
||||
|
||||
describe('filterIgnoredProperties', () => {
|
||||
it('should filter out properties based on the ignore list', () => {
|
||||
const obj = {
|
||||
name: 'John',
|
||||
age: 30,
|
||||
email: 'john@example.com',
|
||||
address: '123 Main St',
|
||||
};
|
||||
const propertiesToIgnore = ['age', 'address'];
|
||||
|
||||
const filteredObj = filterIgnoredProperties(obj, propertiesToIgnore);
|
||||
|
||||
expect(filteredObj).toEqual({
|
||||
name: 'John',
|
||||
email: 'john@example.com',
|
||||
});
|
||||
});
|
||||
|
||||
it('should return the original object if ignore list is empty', () => {
|
||||
const obj = {
|
||||
name: 'John',
|
||||
age: 30,
|
||||
email: 'john@example.com',
|
||||
address: '123 Main St',
|
||||
};
|
||||
const propertiesToIgnore: string[] = [];
|
||||
|
||||
const filteredObj = filterIgnoredProperties(obj, propertiesToIgnore);
|
||||
|
||||
expect(filteredObj).toEqual(obj);
|
||||
});
|
||||
|
||||
it('should return an empty object if the original object is empty', () => {
|
||||
const obj = {};
|
||||
const propertiesToIgnore = ['age', 'address'];
|
||||
|
||||
const filteredObj = filterIgnoredProperties(obj, propertiesToIgnore);
|
||||
|
||||
expect(filteredObj).toEqual({});
|
||||
});
|
||||
});
|
||||
|
||||
describe('mapObjectMetadataByUniqueIdentifier', () => {
|
||||
it('should convert an array of ObjectMetadataEntity objects into a map', () => {
|
||||
const arr: DeepPartial<ObjectMetadataEntity>[] = [
|
||||
{
|
||||
nameSingular: 'user',
|
||||
fields: [
|
||||
{ name: 'id', type: FieldMetadataType.UUID },
|
||||
{ name: 'name', type: FieldMetadataType.TEXT },
|
||||
],
|
||||
},
|
||||
{
|
||||
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: {
|
||||
nameSingular: 'user',
|
||||
fields: {
|
||||
id: { name: 'id', type: FieldMetadataType.UUID },
|
||||
name: { name: 'name', type: FieldMetadataType.TEXT },
|
||||
},
|
||||
},
|
||||
product: {
|
||||
nameSingular: 'product',
|
||||
fields: {
|
||||
id: { name: 'id', type: FieldMetadataType.UUID },
|
||||
name: { name: 'name', type: FieldMetadataType.TEXT },
|
||||
price: { 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({});
|
||||
});
|
||||
});
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
import { ObjectMetadataEntity } from 'src/metadata/object-metadata/object-metadata.entity';
|
||||
|
||||
/**
|
||||
* This utility function filters out properties from an object based on a list of properties to ignore.
|
||||
* It returns a new object with only the properties that are not in the ignore list.
|
||||
*
|
||||
* @param obj - The object to filter.
|
||||
* @param propertiesToIgnore - An array of property names to ignore.
|
||||
* @returns A new object with filtered properties.
|
||||
*/
|
||||
export const filterIgnoredProperties = (
|
||||
obj: any,
|
||||
propertiesToIgnore: string[],
|
||||
mapFunction?: (value: any) => any,
|
||||
) => {
|
||||
return Object.fromEntries(
|
||||
Object.entries(obj)
|
||||
.filter(([key]) => !propertiesToIgnore.includes(key))
|
||||
.map(([key, value]) => [key, mapFunction ? mapFunction(value) : value]),
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* 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 = (
|
||||
arr: ObjectMetadataEntity[],
|
||||
) => {
|
||||
return arr.reduce((acc, curr) => {
|
||||
acc[curr.nameSingular] = {
|
||||
...curr,
|
||||
fields: curr.fields.reduce((acc, curr) => {
|
||||
acc[curr.name] = curr;
|
||||
|
||||
return acc;
|
||||
}, {}),
|
||||
};
|
||||
|
||||
return acc;
|
||||
}, {});
|
||||
};
|
||||
|
||||
export const convertStringifiedFieldsToJSON = (fieldMetadata) => {
|
||||
if (fieldMetadata.targetColumnMap) {
|
||||
fieldMetadata.targetColumnMap = JSON.parse(
|
||||
fieldMetadata.targetColumnMap as unknown as string,
|
||||
);
|
||||
}
|
||||
if (fieldMetadata.defaultValue) {
|
||||
fieldMetadata.defaultValue = JSON.parse(
|
||||
fieldMetadata.defaultValue as unknown as string,
|
||||
);
|
||||
}
|
||||
if (fieldMetadata.options) {
|
||||
fieldMetadata.options = JSON.parse(
|
||||
fieldMetadata.options as unknown as string,
|
||||
);
|
||||
}
|
||||
return fieldMetadata;
|
||||
};
|
||||
Reference in New Issue
Block a user