Object metadata API create one using workspace migration v2 (#13420)
# Introduction In this PR we create basic transpilation methods and utils to handle input to flat, entity to flat, object maps to flat. In order to transpile everything into a common validation that will be implemented in another PR ## FieldMetadataEntity typing Added `never | null` to fields that should never be in order to ease general abstracted method to pass null, as anw it's what is in the database ## Todo - ~~Create a feature flag~~ - Integration test for object creation through metadata api + pg col introspection and snapshoting
This commit is contained in:
@@ -28,10 +28,10 @@ export const getMockFieldMetadataEntity = <
|
||||
isSystem: false,
|
||||
isUnique: null,
|
||||
object: {} as ObjectMetadataEntity,
|
||||
relationTargetFieldMetadata: null as never,
|
||||
relationTargetFieldMetadataId: null as never,
|
||||
relationTargetObjectMetadata: null as never,
|
||||
relationTargetObjectMetadataId: null as never,
|
||||
relationTargetFieldMetadata: null,
|
||||
relationTargetFieldMetadataId: null,
|
||||
relationTargetObjectMetadata: null,
|
||||
relationTargetObjectMetadataId: null,
|
||||
standardId: null,
|
||||
standardOverrides: null,
|
||||
id: faker.string.uuid(),
|
||||
|
||||
-107
@@ -1,107 +0,0 @@
|
||||
import { EachTestingContext } from 'twenty-shared/testing';
|
||||
|
||||
import { trimAndRemoveDuplicatedWhitespacesFromObjectStringProperties } from 'src/utils/trim-and-remove-duplicated-whitespaces-from-object-string-properties';
|
||||
|
||||
type SanitizeObjectStringPropertiesTestCase = EachTestingContext<{
|
||||
input: Record<string, any>;
|
||||
keys: string[];
|
||||
expected: Record<string, any>;
|
||||
}>;
|
||||
|
||||
describe('trim-and-remove-duplicated-whitespaces-from-object-string-properties', () => {
|
||||
const testCases: SanitizeObjectStringPropertiesTestCase[] = [
|
||||
{
|
||||
title: 'should sanitize single string property',
|
||||
context: {
|
||||
input: { name: ' John Doe ' },
|
||||
keys: ['name'],
|
||||
expected: { name: 'John Doe' },
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'should sanitize multiple string properties',
|
||||
context: {
|
||||
input: {
|
||||
firstName: ' John ',
|
||||
lastName: ' Doe ',
|
||||
email: ' john.doe@example.com ',
|
||||
},
|
||||
keys: ['firstName', 'lastName', 'email'],
|
||||
expected: {
|
||||
firstName: 'John',
|
||||
lastName: 'Doe',
|
||||
email: 'john.doe@example.com',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'should preserve undefined properties',
|
||||
context: {
|
||||
input: { name: ' John Doe ' },
|
||||
keys: ['name', 'age'],
|
||||
expected: { name: 'John Doe' },
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'should handle null properties',
|
||||
context: {
|
||||
input: { name: ' John Doe ', description: null },
|
||||
keys: ['name', 'description'],
|
||||
expected: { name: 'John Doe', description: null },
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'should not modify non-string properties',
|
||||
context: {
|
||||
input: { name: ' John Doe ', age: 30, active: true },
|
||||
// In real life passing age would raise an TypeScript error
|
||||
keys: ['name', 'age', 'active'],
|
||||
expected: { name: 'John Doe', age: 30, active: true },
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'should handle empty string',
|
||||
context: {
|
||||
input: { name: ' ' },
|
||||
keys: ['name'],
|
||||
expected: { name: '' },
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'should handle object with no properties to sanitize',
|
||||
context: {
|
||||
input: { age: 30, active: true },
|
||||
keys: ['name'],
|
||||
expected: { age: 30, active: true },
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'should handle nested whitespace',
|
||||
context: {
|
||||
input: { description: ' This is a test ' },
|
||||
keys: ['description'],
|
||||
expected: { description: 'This is a test' },
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'should trim only provided keys fields',
|
||||
context: {
|
||||
input: {
|
||||
name: ' John Doe ',
|
||||
description: ' this is a test ',
|
||||
},
|
||||
keys: ['description'],
|
||||
expected: { name: ' John Doe ', description: 'this is a test' },
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
test.each(testCases)('$title', ({ context: { input, keys, expected } }) => {
|
||||
const result = trimAndRemoveDuplicatedWhitespacesFromObjectStringProperties(
|
||||
input,
|
||||
keys,
|
||||
);
|
||||
|
||||
expect(result).toEqual(expected);
|
||||
});
|
||||
});
|
||||
-68
@@ -1,68 +0,0 @@
|
||||
import { EachTestingContext } from 'twenty-shared/testing';
|
||||
|
||||
import { trimAndRemoveDuplicatedWhitespacesFromString } from 'src/utils/trim-and-remove-duplicated-whitespaces-from-string';
|
||||
|
||||
type TrimAndRemoveWhitespacesTestCase = EachTestingContext<{
|
||||
input: string;
|
||||
expected: string;
|
||||
}>;
|
||||
|
||||
describe('trim-and-remove-duplicated-whitespaces-from-string', () => {
|
||||
const testCases: TrimAndRemoveWhitespacesTestCase[] = [
|
||||
{
|
||||
title: 'should trim and remove duplicated whitespaces from a string',
|
||||
context: {
|
||||
input: ' Hello World ',
|
||||
expected: 'Hello World',
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'should handle string with multiple spaces between words',
|
||||
context: {
|
||||
input: 'This is a test',
|
||||
expected: 'This is a test',
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'should handle string with only whitespaces',
|
||||
context: {
|
||||
input: ' ',
|
||||
expected: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'should handle empty string',
|
||||
context: {
|
||||
input: '',
|
||||
expected: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'should handle string with tabs and newlines',
|
||||
context: {
|
||||
input: 'Hello\t\t\tWorld\n\n Test',
|
||||
expected: 'Hello World Test',
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'should handle string with leading and trailing spaces',
|
||||
context: {
|
||||
input: ' Leading and trailing spaces ',
|
||||
expected: 'Leading and trailing spaces',
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'should preserve single spaces between words',
|
||||
context: {
|
||||
input: 'This is already properly spaced',
|
||||
expected: 'This is already properly spaced',
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
test.each(testCases)('$title', ({ context: { input, expected } }) => {
|
||||
const result = trimAndRemoveDuplicatedWhitespacesFromString(input);
|
||||
|
||||
expect(result).toEqual(expected);
|
||||
});
|
||||
});
|
||||
-31
@@ -1,31 +0,0 @@
|
||||
import { trimAndRemoveDuplicatedWhitespacesFromString } from 'src/utils/trim-and-remove-duplicated-whitespaces-from-string';
|
||||
|
||||
type OnlyStringPropertiesKey<T> = Extract<keyof T, string>;
|
||||
|
||||
type StringPropertyKeys<T> = {
|
||||
[K in OnlyStringPropertiesKey<T>]: T[K] extends string | undefined
|
||||
? K
|
||||
: never;
|
||||
}[OnlyStringPropertiesKey<T>];
|
||||
|
||||
export const trimAndRemoveDuplicatedWhitespacesFromObjectStringProperties = <T>(
|
||||
obj: T,
|
||||
keys: StringPropertyKeys<T>[],
|
||||
) => {
|
||||
return keys.reduce((acc, key) => {
|
||||
const occurrence = acc[key];
|
||||
|
||||
if (
|
||||
occurrence === undefined ||
|
||||
typeof occurrence !== 'string' ||
|
||||
occurrence === null
|
||||
) {
|
||||
return acc;
|
||||
}
|
||||
|
||||
return {
|
||||
...acc,
|
||||
[key]: trimAndRemoveDuplicatedWhitespacesFromString(occurrence),
|
||||
};
|
||||
}, obj);
|
||||
};
|
||||
@@ -1,4 +0,0 @@
|
||||
const MULTIPLE_WHITESPACE_REGEX = /\s+/g;
|
||||
|
||||
export const trimAndRemoveDuplicatedWhitespacesFromString = (str: string) =>
|
||||
str.trim().replace(MULTIPLE_WHITESPACE_REGEX, ' ');
|
||||
Reference in New Issue
Block a user