Add default relation to standard object on custom object in manifest (#18033)
add default relation fields when creating an object from an application --------- Co-authored-by: prastoin <paul@twenty.com>
This commit is contained in:
@@ -0,0 +1 @@
|
||||
export const API_CLIENT_DIR = 'api-client';
|
||||
@@ -1,10 +1,10 @@
|
||||
import { type SyncableEntityOptions } from '@/application/syncableEntityOptionsType';
|
||||
import {
|
||||
type FieldMetadataDefaultValue,
|
||||
type FieldMetadataOptions,
|
||||
type FieldMetadataType,
|
||||
type FieldMetadataUniversalSettings,
|
||||
type RelationAndMorphRelationFieldMetadataType,
|
||||
FieldMetadataDefaultValue,
|
||||
FieldMetadataOptions,
|
||||
FieldMetadataType,
|
||||
FieldMetadataUniversalSettings,
|
||||
RelationAndMorphRelationFieldMetadataType
|
||||
} from '@/types';
|
||||
|
||||
export type RegularFieldManifest<
|
||||
@@ -25,20 +25,27 @@ export type RegularFieldManifest<
|
||||
objectUniversalIdentifier: string;
|
||||
};
|
||||
|
||||
// Both sides of a relation must be declared explicitly in the manifest.
|
||||
// Relation-specific universal settings (relationType, onDelete, joinColumnName)
|
||||
// are provided through the `universalSettings` field.
|
||||
export type RelationFieldManifest<
|
||||
T extends
|
||||
RelationAndMorphRelationFieldMetadataType = RelationAndMorphRelationFieldMetadataType,
|
||||
> = RegularFieldManifest<T> & {
|
||||
> = Omit<RegularFieldManifest<T>, 'universalSettings' | 'type'> & {
|
||||
type: T;
|
||||
relationTargetFieldMetadataUniversalIdentifier: string;
|
||||
relationTargetObjectMetadataUniversalIdentifier: string;
|
||||
};
|
||||
universalSettings: FieldMetadataUniversalSettings<T>;
|
||||
} & ([T] extends [FieldMetadataType.MORPH_RELATION]
|
||||
? {
|
||||
morphId: string;
|
||||
}
|
||||
: {
|
||||
morphId?: undefined;
|
||||
});
|
||||
|
||||
export type FieldManifest<
|
||||
T extends FieldMetadataType = Exclude<
|
||||
FieldMetadataType,
|
||||
RelationAndMorphRelationFieldMetadataType
|
||||
>,
|
||||
> = RegularFieldManifest<T> | RelationFieldManifest;
|
||||
export type FieldManifest<T extends FieldMetadataType = FieldMetadataType> =
|
||||
T extends RelationAndMorphRelationFieldMetadataType
|
||||
? RelationFieldManifest<
|
||||
Extract<T, RelationAndMorphRelationFieldMetadataType>
|
||||
>
|
||||
: RegularFieldManifest<
|
||||
Exclude<T, RelationAndMorphRelationFieldMetadataType>
|
||||
>;
|
||||
|
||||
@@ -13,6 +13,7 @@ export type {
|
||||
} from './applicationType';
|
||||
export type { ApplicationVariables } from './applicationVariablesType';
|
||||
export type { AssetManifest } from './assetManifestType';
|
||||
export { API_CLIENT_DIR } from './constants/ApiClientDirectory';
|
||||
export { ASSETS_DIR } from './constants/AssetDirectory';
|
||||
export { DEFAULT_API_KEY_NAME } from './constants/DefaultApiKeyName';
|
||||
export { DEFAULT_API_URL_NAME } from './constants/DefaultApiUrlName';
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { type FieldManifest } from '@/application/fieldManifestType';
|
||||
import type { FieldMetadataType } from '@/types';
|
||||
|
||||
type DistributiveOmit<T, K extends PropertyKey> = T extends unknown
|
||||
? Omit<T, K>
|
||||
: never;
|
||||
|
||||
export type ObjectFieldManifest<
|
||||
T extends FieldMetadataType = Exclude<
|
||||
FieldMetadataType,
|
||||
FieldMetadataType.RELATION
|
||||
>,
|
||||
> = Omit<FieldManifest<T>, 'objectUniversalIdentifier'>;
|
||||
T extends FieldMetadataType = FieldMetadataType,
|
||||
> = DistributiveOmit<FieldManifest<T>, 'objectUniversalIdentifier'>;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { addCustomSuffixIfIsReserved } from '@/metadata/add-custom-suffix-if-reserved.util';
|
||||
import { addCustomSuffixIfIsReserved } from '@/metadata/utils/add-custom-suffix-if-reserved.util';
|
||||
|
||||
describe('addCustomSuffixIfIsReserved', () => {
|
||||
it('should add Custom suffix for reserved name "event"', () => {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { computeMetadataNameFromLabel } from '@/metadata/compute-metadata-name-from-label.util';
|
||||
import { computeMetadataNameFromLabel } from '@/metadata/utils/compute-metadata-name-from-label.util';
|
||||
|
||||
describe('computeMetadataNameFromLabel', () => {
|
||||
it('should convert a label to camelCase', () => {
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
import { type ALL_METADATA_NAME } from '@/metadata/all-metadata-name.constant';
|
||||
|
||||
export type AllMetadataName = keyof typeof ALL_METADATA_NAME;
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
import { type STANDARD_OBJECTS } from '@/metadata/constants/standard-object.constant';
|
||||
|
||||
export const DEFAULT_RELATIONS_OBJECTS_STANDARD_IDS = [
|
||||
'timelineActivity',
|
||||
'favorite',
|
||||
'attachment',
|
||||
'noteTarget',
|
||||
'taskTarget',
|
||||
] as const satisfies (keyof typeof STANDARD_OBJECTS)[];
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
export const CORE_OBJECT_NAMES = [
|
||||
const CORE_OBJECT_NAMES = [
|
||||
'approvedAccessDomain',
|
||||
'approvedAccessDomains',
|
||||
'appToken',
|
||||
@@ -7,23 +7,21 @@
|
||||
* |___/
|
||||
*/
|
||||
|
||||
export { addCustomSuffixIfIsReserved } from './add-custom-suffix-if-reserved.util';
|
||||
export { ALL_METADATA_NAME } from './all-metadata-name.constant';
|
||||
export type { AllMetadataName } from './all-metadata-name.type';
|
||||
export { checkIfFieldIsImageIdentifier } from './check-if-field-is-image-identifier.util';
|
||||
export {
|
||||
DEFAULT_LABEL_IDENTIFIER_FIELD_NAME,
|
||||
checkIfFieldIsLabelIdentifier,
|
||||
} from './check-if-field-is-label-identifier.util';
|
||||
export { computeMetadataNameFromLabel } from './compute-metadata-name-from-label.util';
|
||||
export { ALL_METADATA_NAME } from './constants/all-metadata-name.constant';
|
||||
export { DEFAULT_RELATIONS_OBJECTS_STANDARD_IDS } from './constants/default-relations-object-standard-ids.constant';
|
||||
export { RESERVED_METADATA_NAME_KEYWORDS } from './constants/reserved-metadata-name-keywords.constant';
|
||||
export { STANDARD_OBJECTS } from './constants/standard-object.constant';
|
||||
export type { AllMetadataName } from './types/all-metadata-name.type';
|
||||
export type {
|
||||
FailedMetadataValidationError,
|
||||
FailedMetadataValidation,
|
||||
MetadataValidationErrorResponse,
|
||||
} from './MetadataValidationError';
|
||||
export { WorkspaceMigrationV2ExceptionCode } from './MetadataValidationError';
|
||||
export {
|
||||
CORE_OBJECT_NAMES,
|
||||
RESERVED_METADATA_NAME_KEYWORDS,
|
||||
} from './reserved-metadata-name-keywords.constant';
|
||||
export { STANDARD_OBJECTS } from './standard-object.constant';
|
||||
} from './types/MetadataValidationError';
|
||||
export { WorkspaceMigrationV2ExceptionCode } from './types/MetadataValidationError';
|
||||
export { addCustomSuffixIfIsReserved } from './utils/add-custom-suffix-if-reserved.util';
|
||||
export { computeMetadataNameFromLabel } from './utils/compute-metadata-name-from-label.util';
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
import { type AllMetadataName } from './all-metadata-name.type';
|
||||
import { type AllMetadataName } from '@/metadata/types/all-metadata-name.type';
|
||||
|
||||
export type FailedMetadataValidationError = {
|
||||
code: string;
|
||||
@@ -0,0 +1,3 @@
|
||||
import { type ALL_METADATA_NAME } from '@/metadata/constants/all-metadata-name.constant';
|
||||
|
||||
export type AllMetadataName = keyof typeof ALL_METADATA_NAME;
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
import { RESERVED_METADATA_NAME_KEYWORDS } from './reserved-metadata-name-keywords.constant';
|
||||
import { RESERVED_METADATA_NAME_KEYWORDS } from '@/metadata';
|
||||
|
||||
export const addCustomSuffixIfIsReserved = (name: string): string => {
|
||||
if (!name) return name;
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
import { addCustomSuffixIfIsReserved } from '@/metadata/add-custom-suffix-if-reserved.util';
|
||||
import { addCustomSuffixIfIsReserved } from '@/metadata/utils/add-custom-suffix-if-reserved.util';
|
||||
import camelCase from 'lodash.camelcase';
|
||||
import { slugify } from 'transliteration';
|
||||
|
||||
Reference in New Issue
Block a user