29a4f4d685
# Introduction Following https://github.com/twentyhq/twenty/pull/13420 What has been done: - `CreateFieldInput` transpilation to `FlatFieldMetadata` - `FlatFieldMetadata` validator service - A lof of transpilation utils from `input` to `flatObject` or `flatField` - Created dedicated v2 api metadata services - Introducing `inferDeletionFromMissingObjectFieldIndex` in the builder, to avoid diffing every object and field of the current workspace we allow only generating create/update migration operations, usefull when passing by the api metadata ## We still need to in another PR: - Implement a strong unit test coverage and critical functions and services - Finalize flat field metadata validation exception for `options` `defaultValue` `settings` and `relations` - Finalize `flatObjectMetadata` validation and v2 service refactor - Plug the new service when feature flag is enabled
56 lines
1.3 KiB
TypeScript
56 lines
1.3 KiB
TypeScript
import camelCase from 'lodash.camelcase';
|
|
import { slugify } from 'transliteration';
|
|
import { isDefined } from 'twenty-shared/utils';
|
|
|
|
import {
|
|
InvalidMetadataException,
|
|
InvalidMetadataExceptionCode,
|
|
} from 'src/engine/metadata-modules/utils/exceptions/invalid-metadata.exception';
|
|
|
|
export const validateNameAndLabelAreSyncOrThrow = ({
|
|
label,
|
|
name,
|
|
}: {
|
|
label: string;
|
|
name: string;
|
|
}) => {
|
|
const computedName = computeMetadataNameFromLabel(label);
|
|
|
|
if (name !== computedName) {
|
|
throw new InvalidMetadataException(
|
|
`Name is not synced with label. Expected name: "${computedName}", got ${name}`,
|
|
InvalidMetadataExceptionCode.NAME_NOT_SYNCED_WITH_LABEL,
|
|
);
|
|
}
|
|
};
|
|
|
|
export const computeMetadataNameFromLabel = (label: string): string => {
|
|
if (!isDefined(label)) {
|
|
throw new InvalidMetadataException(
|
|
'Label is required',
|
|
InvalidMetadataExceptionCode.LABEL_REQUIRED,
|
|
);
|
|
}
|
|
|
|
const prefixedLabel = /^\d/.test(label) ? `n${label}` : label;
|
|
|
|
if (prefixedLabel === '') {
|
|
return '';
|
|
}
|
|
|
|
const formattedString = slugify(prefixedLabel, {
|
|
trim: true,
|
|
separator: '_',
|
|
allowedChars: 'a-zA-Z0-9',
|
|
});
|
|
|
|
if (formattedString === '') {
|
|
throw new InvalidMetadataException(
|
|
`Invalid label: "${label}"`,
|
|
InvalidMetadataExceptionCode.INVALID_LABEL,
|
|
);
|
|
}
|
|
|
|
return camelCase(formattedString);
|
|
};
|