[AUDIT] Run knip over twenty-server (#21159)
# Introduction Run [knip](https://knip.dev/) over twenty-server Used config: ```json { "$schema": "https://unpkg.com/knip@5/schema.json", "workspaces": { "packages/twenty-server": { "entry": [ "src/main.ts", "src/command/command.ts", "src/queue-worker/queue-worker.ts", "src/database/scripts/setup-db.ts", "src/database/scripts/truncate-db.ts", "src/database/clickHouse/migrations/run-migrations.ts", "src/database/clickHouse/seeds/run-seeds.ts", "src/instrument.ts", "lingui.config.ts", "test/integration/graphql/codegen/index.ts", "test/integration/utils/setup-test.ts", "test/integration/utils/teardown-test.ts", "scripts/**/*.ts", "**/*.spec.ts", "**/*.integration-spec.ts" ], "project": ["src/**/*.ts", "test/**/*.ts", "scripts/**/*.ts"], "ignore": [ "src/database/typeorm/**/migrations/**", "src/database/typeorm/**/*.entity.ts", "**/*.workspace-entity.ts", "**/logic-function-resource/constants/seed-project/**" ], "ignoreDependencies": ["@types/psl", "@types/aws-lambda"], "ignoreBinaries": ["nest", "lingui", "typeorm"] } } } ```
This commit is contained in:
-19
@@ -1,19 +0,0 @@
|
||||
import { STANDARD_OBJECTS } from 'twenty-shared/metadata';
|
||||
|
||||
import { type ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||
|
||||
// All workflow-related standard object IDs that should be filtered out from agent access
|
||||
const WORKFLOW_STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS = [
|
||||
STANDARD_OBJECTS.workflow.universalIdentifier,
|
||||
STANDARD_OBJECTS.workflowRun.universalIdentifier,
|
||||
STANDARD_OBJECTS.workflowVersion.universalIdentifier,
|
||||
STANDARD_OBJECTS.workflowAutomatedTrigger.universalIdentifier,
|
||||
] as const;
|
||||
|
||||
export const isWorkflowRelatedObject = (
|
||||
objectMetadata: ObjectMetadataEntity,
|
||||
): boolean => {
|
||||
return WORKFLOW_STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.includes(
|
||||
objectMetadata.universalIdentifier as (typeof WORKFLOW_STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS)[number],
|
||||
);
|
||||
};
|
||||
-5
@@ -1,5 +0,0 @@
|
||||
import { z } from 'zod';
|
||||
|
||||
import { aiProviderAuthTypeSchema } from 'src/engine/metadata-modules/ai/ai-models/types/ai-provider-auth-type.schema';
|
||||
|
||||
export type AiProviderAuthType = z.infer<typeof aiProviderAuthTypeSchema>;
|
||||
-60
@@ -1,60 +0,0 @@
|
||||
import { Field, InputType } from '@nestjs/graphql';
|
||||
|
||||
import {
|
||||
IsBoolean,
|
||||
IsEnum,
|
||||
IsNotEmpty,
|
||||
IsOptional,
|
||||
IsString,
|
||||
IsUUID,
|
||||
} from 'class-validator';
|
||||
import {
|
||||
CalendarChannelContactAutoCreationPolicy,
|
||||
CalendarChannelSyncStage,
|
||||
CalendarChannelVisibility,
|
||||
} from 'twenty-shared/types';
|
||||
|
||||
import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars';
|
||||
|
||||
@InputType()
|
||||
export class CreateCalendarChannelInput {
|
||||
@IsUUID()
|
||||
@IsOptional()
|
||||
@Field(() => UUIDScalarType, { nullable: true })
|
||||
id?: string;
|
||||
|
||||
@IsString()
|
||||
@IsNotEmpty()
|
||||
@Field()
|
||||
handle: string;
|
||||
|
||||
@IsEnum(CalendarChannelVisibility)
|
||||
@IsNotEmpty()
|
||||
@Field(() => CalendarChannelVisibility)
|
||||
visibility: CalendarChannelVisibility;
|
||||
|
||||
@IsEnum(CalendarChannelSyncStage)
|
||||
@IsNotEmpty()
|
||||
@Field(() => CalendarChannelSyncStage)
|
||||
syncStage: CalendarChannelSyncStage;
|
||||
|
||||
@IsUUID()
|
||||
@IsNotEmpty()
|
||||
@Field(() => UUIDScalarType)
|
||||
connectedAccountId: string;
|
||||
|
||||
@IsBoolean()
|
||||
@IsNotEmpty()
|
||||
@Field()
|
||||
isContactAutoCreationEnabled: boolean;
|
||||
|
||||
@IsEnum(CalendarChannelContactAutoCreationPolicy)
|
||||
@IsNotEmpty()
|
||||
@Field(() => CalendarChannelContactAutoCreationPolicy)
|
||||
contactAutoCreationPolicy: CalendarChannelContactAutoCreationPolicy;
|
||||
|
||||
@IsBoolean()
|
||||
@IsNotEmpty()
|
||||
@Field()
|
||||
isSyncEnabled: boolean;
|
||||
}
|
||||
-49
@@ -1,49 +0,0 @@
|
||||
import { Field, InputType } from '@nestjs/graphql';
|
||||
|
||||
import {
|
||||
IsArray,
|
||||
IsNotEmpty,
|
||||
IsOptional,
|
||||
IsString,
|
||||
IsUUID,
|
||||
} from 'class-validator';
|
||||
|
||||
import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars';
|
||||
|
||||
@InputType()
|
||||
export class CreateConnectedAccountInput {
|
||||
@IsUUID()
|
||||
@IsOptional()
|
||||
@Field(() => UUIDScalarType, { nullable: true })
|
||||
id?: string;
|
||||
|
||||
@IsString()
|
||||
@IsNotEmpty()
|
||||
@Field()
|
||||
handle: string;
|
||||
|
||||
@IsString()
|
||||
@IsNotEmpty()
|
||||
@Field()
|
||||
provider: string;
|
||||
|
||||
@IsString()
|
||||
@IsOptional()
|
||||
@Field({ nullable: true })
|
||||
accessToken?: string;
|
||||
|
||||
@IsString()
|
||||
@IsOptional()
|
||||
@Field({ nullable: true })
|
||||
refreshToken?: string;
|
||||
|
||||
@IsArray()
|
||||
@IsOptional()
|
||||
@Field(() => [String], { nullable: true })
|
||||
scopes?: string[];
|
||||
|
||||
@IsUUID()
|
||||
@IsNotEmpty()
|
||||
@Field(() => UUIDScalarType)
|
||||
userWorkspaceId: string;
|
||||
}
|
||||
-32
@@ -1,32 +0,0 @@
|
||||
import { type ObjectMetadataDTO } from 'src/engine/metadata-modules/object-metadata/dtos/object-metadata.dto';
|
||||
import { type ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||
|
||||
export const fromObjectMetadataEntityToObjectMetadataDto = (
|
||||
objectMetadataEntity: ObjectMetadataEntity,
|
||||
): ObjectMetadataDTO => {
|
||||
const {
|
||||
createdAt,
|
||||
updatedAt,
|
||||
description,
|
||||
icon,
|
||||
color,
|
||||
standardOverrides,
|
||||
shortcut,
|
||||
duplicateCriteria,
|
||||
applicationId,
|
||||
...rest
|
||||
} = objectMetadataEntity;
|
||||
|
||||
return {
|
||||
...rest,
|
||||
createdAt: new Date(createdAt),
|
||||
updatedAt: new Date(updatedAt),
|
||||
description: description ?? undefined,
|
||||
icon: icon ?? undefined,
|
||||
color: color ?? undefined,
|
||||
standardOverrides: standardOverrides ?? undefined,
|
||||
shortcut: shortcut ?? undefined,
|
||||
duplicateCriteria: duplicateCriteria ?? undefined,
|
||||
applicationId: applicationId ?? undefined,
|
||||
};
|
||||
};
|
||||
-10
@@ -1,10 +0,0 @@
|
||||
import { FieldMetadataType } from 'twenty-shared/types';
|
||||
|
||||
import { type FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
|
||||
|
||||
export const isFieldMetadataTypeRelation = (
|
||||
fieldMetadata: FieldMetadataEntity,
|
||||
): fieldMetadata is FieldMetadataEntity &
|
||||
FieldMetadataEntity<FieldMetadataType.RELATION> => {
|
||||
return fieldMetadata.type === FieldMetadataType.RELATION;
|
||||
};
|
||||
-44
@@ -1,44 +0,0 @@
|
||||
import { type FieldMetadataDefaultValueForAnyType } from 'twenty-shared/types';
|
||||
|
||||
export const unserializeDefaultValue = (
|
||||
serializedDefaultValue: FieldMetadataDefaultValueForAnyType,
|
||||
// oxlint-disable-next-line @typescripttypescript/no-explicit-any
|
||||
): any => {
|
||||
if (serializedDefaultValue === undefined || serializedDefaultValue === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (typeof serializedDefaultValue === 'number') {
|
||||
return serializedDefaultValue;
|
||||
}
|
||||
|
||||
if (typeof serializedDefaultValue === 'boolean') {
|
||||
return serializedDefaultValue;
|
||||
}
|
||||
|
||||
if (typeof serializedDefaultValue === 'string') {
|
||||
return serializedDefaultValue.replace(/'/g, '');
|
||||
}
|
||||
|
||||
if (Array.isArray(serializedDefaultValue)) {
|
||||
return serializedDefaultValue.map((value) =>
|
||||
unserializeDefaultValue(value),
|
||||
);
|
||||
}
|
||||
|
||||
if (typeof serializedDefaultValue === 'object') {
|
||||
return Object.entries(serializedDefaultValue).reduce(
|
||||
(acc, [key, value]) => {
|
||||
// @ts-expect-error legacy noImplicitAny
|
||||
acc[key] = unserializeDefaultValue(value);
|
||||
|
||||
return acc;
|
||||
},
|
||||
{},
|
||||
);
|
||||
}
|
||||
|
||||
throw new Error(
|
||||
`Invalid serialized default value "${serializedDefaultValue}"`,
|
||||
);
|
||||
};
|
||||
-79
@@ -1,79 +0,0 @@
|
||||
import { plainToInstance } from 'class-transformer';
|
||||
import { validateSync } from 'class-validator';
|
||||
import {
|
||||
FieldMetadataType,
|
||||
type FieldMetadataOptions,
|
||||
} from 'twenty-shared/types';
|
||||
|
||||
import {
|
||||
FieldMetadataComplexOption,
|
||||
type FieldMetadataDefaultOption,
|
||||
} from 'src/engine/metadata-modules/field-metadata/dtos/options.input';
|
||||
import {
|
||||
FieldMetadataException,
|
||||
FieldMetadataExceptionCode,
|
||||
} from 'src/engine/metadata-modules/field-metadata/field-metadata.exception';
|
||||
|
||||
import { isEnumFieldMetadataType } from './is-enum-field-metadata-type.util';
|
||||
|
||||
export const optionsValidatorsMap = {
|
||||
// RATING doesn't need to be provided as it's the backend that will generate the options
|
||||
[FieldMetadataType.SELECT]: [FieldMetadataComplexOption],
|
||||
[FieldMetadataType.MULTI_SELECT]: [FieldMetadataComplexOption],
|
||||
};
|
||||
|
||||
export const validateOptionsForType = (
|
||||
type: FieldMetadataType,
|
||||
options: FieldMetadataOptions,
|
||||
): boolean => {
|
||||
if (options === null) return true;
|
||||
|
||||
if (!Array.isArray(options)) {
|
||||
throw new FieldMetadataException(
|
||||
'Options must be an array',
|
||||
FieldMetadataExceptionCode.INVALID_FIELD_INPUT,
|
||||
);
|
||||
}
|
||||
|
||||
if (!isEnumFieldMetadataType(type)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (type === FieldMetadataType.RATING) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const values = options.map(({ value }) => value);
|
||||
|
||||
// Check if all options are unique
|
||||
if (new Set(values).size !== options.length) {
|
||||
throw new FieldMetadataException(
|
||||
'Options must be unique',
|
||||
FieldMetadataExceptionCode.INVALID_FIELD_INPUT,
|
||||
);
|
||||
}
|
||||
|
||||
const validators = optionsValidatorsMap[type];
|
||||
|
||||
if (!validators) return false;
|
||||
|
||||
const isValid = options.every((option) => {
|
||||
return validators.some((validator) => {
|
||||
const optionsInstance = plainToInstance<
|
||||
// oxlint-disable-next-line @typescripttypescript/no-explicit-any
|
||||
any,
|
||||
FieldMetadataDefaultOption | FieldMetadataComplexOption
|
||||
>(validator, option);
|
||||
|
||||
return (
|
||||
validateSync(optionsInstance, {
|
||||
whitelist: true,
|
||||
forbidNonWhitelisted: true,
|
||||
forbidUnknownValues: true,
|
||||
}).length === 0
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
return isValid;
|
||||
};
|
||||
-25
@@ -1,25 +0,0 @@
|
||||
import {
|
||||
type ValidationArguments,
|
||||
type ValidationOptions,
|
||||
registerDecorator,
|
||||
} from 'class-validator';
|
||||
|
||||
export function IsQuotedString(validationOptions?: ValidationOptions) {
|
||||
return function (object: object, propertyName: string) {
|
||||
registerDecorator({
|
||||
name: 'isQuotedString',
|
||||
target: object.constructor,
|
||||
propertyName: propertyName,
|
||||
options: validationOptions,
|
||||
validator: {
|
||||
// oxlint-disable-next-line @typescripttypescript/no-explicit-any
|
||||
validate(value: any) {
|
||||
return typeof value === 'string' && /^'{1}.*'{1}$/.test(value);
|
||||
},
|
||||
defaultMessage(args: ValidationArguments) {
|
||||
return `${args.property} must be a quoted string`;
|
||||
},
|
||||
},
|
||||
});
|
||||
};
|
||||
}
|
||||
-7
@@ -1,7 +0,0 @@
|
||||
import { type MetadataEntityPropertyName } from 'src/engine/metadata-modules/flat-entity/constant/all-entity-properties-configuration-by-metadata-name.constant';
|
||||
|
||||
export const FLAT_APPLICATION_VARIABLE_EDITABLE_PROPERTIES = [
|
||||
'key',
|
||||
'description',
|
||||
'isSecret',
|
||||
] as const satisfies MetadataEntityPropertyName<'applicationVariable'>[];
|
||||
-7
@@ -1,7 +0,0 @@
|
||||
import { type MetadataEntityPropertyName } from 'src/engine/metadata-modules/flat-entity/constant/all-entity-properties-configuration-by-metadata-name.constant';
|
||||
|
||||
export const FLAT_CONNECTION_PROVIDER_EDITABLE_PROPERTIES = [
|
||||
'displayName',
|
||||
'type',
|
||||
'oauthConfig',
|
||||
] as const satisfies MetadataEntityPropertyName<'connectionProvider'>[];
|
||||
-4
@@ -1,4 +0,0 @@
|
||||
import { type AllFlatEntityTypesByMetadataName } from 'src/engine/metadata-modules/flat-entity/types/all-flat-entity-types-by-metadata-name';
|
||||
|
||||
export type AllFlatEntities =
|
||||
AllFlatEntityTypesByMetadataName[keyof AllFlatEntityTypesByMetadataName]['flatEntity'];
|
||||
-8
@@ -1,8 +0,0 @@
|
||||
import { type AllMetadataName } from 'twenty-shared/metadata';
|
||||
|
||||
export type FlatEntityMapsKeyToMetadata<T extends string> =
|
||||
T extends `flat${infer Name}Maps`
|
||||
? Uncapitalize<Name> extends AllMetadataName
|
||||
? Uncapitalize<Name>
|
||||
: never
|
||||
: never;
|
||||
-25
@@ -1,25 +0,0 @@
|
||||
import { type AllMetadataName } from 'twenty-shared/metadata';
|
||||
|
||||
import { type MetadataEntity } from 'src/engine/metadata-modules/flat-entity/types/metadata-entity.type';
|
||||
|
||||
type ExtractRelationIdProperties<T> = {
|
||||
[K in keyof T]: K extends `${infer _}Id`
|
||||
? K extends 'id' | 'workspaceId'
|
||||
? never
|
||||
: T[K] extends string | null | undefined
|
||||
? K
|
||||
: never
|
||||
: never;
|
||||
}[keyof T];
|
||||
|
||||
type PropertyNameToRelationName<T extends string> = T extends `${infer Name}Id`
|
||||
? Name
|
||||
: never;
|
||||
|
||||
type ExtractEntityRelations<TEntity> = {
|
||||
[K in ExtractRelationIdProperties<TEntity> as PropertyNameToRelationName<K>]: K;
|
||||
};
|
||||
|
||||
export type MetadataNameAndRelations = {
|
||||
[T in AllMetadataName]: Partial<ExtractEntityRelations<MetadataEntity<T>>>;
|
||||
};
|
||||
-70
@@ -1,70 +0,0 @@
|
||||
import isEmpty from 'lodash.isempty';
|
||||
import { isDefined, removePropertiesFromRecord } from 'twenty-shared/utils';
|
||||
|
||||
import {
|
||||
FlatEntityMapsException,
|
||||
FlatEntityMapsExceptionCode,
|
||||
} from 'src/engine/metadata-modules/flat-entity/exceptions/flat-entity-maps.exception';
|
||||
import { type SyncableFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-from.type';
|
||||
import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type';
|
||||
|
||||
export type DeleteFlatEntityFromFlatEntityMapsOrThrowArgs<
|
||||
T extends SyncableFlatEntity,
|
||||
> = {
|
||||
entityToDeleteId: string;
|
||||
flatEntityMaps: FlatEntityMaps<T>;
|
||||
};
|
||||
|
||||
export const deleteFlatEntityFromFlatEntityMapsOrThrow = <
|
||||
T extends SyncableFlatEntity,
|
||||
>({
|
||||
flatEntityMaps,
|
||||
entityToDeleteId,
|
||||
}: DeleteFlatEntityFromFlatEntityMapsOrThrowArgs<T>): FlatEntityMaps<T> => {
|
||||
const universalIdentifierToDelete =
|
||||
flatEntityMaps.universalIdentifierById[entityToDeleteId];
|
||||
|
||||
if (!isDefined(universalIdentifierToDelete)) {
|
||||
throw new FlatEntityMapsException(
|
||||
'deleteFlatEntityFromFlatEntityMapsOrThrow: entity to delete not found',
|
||||
FlatEntityMapsExceptionCode.ENTITY_NOT_FOUND,
|
||||
);
|
||||
}
|
||||
|
||||
const updatedUniversalIdentifierByIdEntries = Object.entries(
|
||||
flatEntityMaps.universalIdentifierById,
|
||||
).filter(([id]) => id !== entityToDeleteId);
|
||||
|
||||
const updatedUniversalIdentifiersByApplicationIdEntries = Object.entries(
|
||||
flatEntityMaps.universalIdentifiersByApplicationId,
|
||||
)
|
||||
.map(([applicationId, universalIdentifiers]) => {
|
||||
const stillPresentUniversalIdentifiers = universalIdentifiers?.filter(
|
||||
(universalIdentifier) =>
|
||||
universalIdentifier !== universalIdentifierToDelete,
|
||||
);
|
||||
|
||||
if (
|
||||
!isDefined(stillPresentUniversalIdentifiers) ||
|
||||
isEmpty(stillPresentUniversalIdentifiers)
|
||||
) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return [applicationId, stillPresentUniversalIdentifiers];
|
||||
})
|
||||
.filter(isDefined);
|
||||
|
||||
return {
|
||||
byUniversalIdentifier: removePropertiesFromRecord(
|
||||
flatEntityMaps.byUniversalIdentifier,
|
||||
[universalIdentifierToDelete],
|
||||
),
|
||||
universalIdentifierById: Object.fromEntries(
|
||||
updatedUniversalIdentifierByIdEntries,
|
||||
),
|
||||
universalIdentifiersByApplicationId: Object.fromEntries(
|
||||
updatedUniversalIdentifiersByApplicationIdEntries,
|
||||
),
|
||||
};
|
||||
};
|
||||
-12
@@ -1,12 +0,0 @@
|
||||
import { uncapitalize } from 'twenty-shared/utils';
|
||||
|
||||
import { type FlatEntityMapsKeyToMetadata } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps-key-to-metadata';
|
||||
|
||||
export const getMetadataNameFromFlatEntityMapsKey = <T extends string>(
|
||||
flatEntityMapsKey: T,
|
||||
): FlatEntityMapsKeyToMetadata<T> => {
|
||||
const withoutPrefix = flatEntityMapsKey.replace(/^flat/, '');
|
||||
const withoutSuffix = withoutPrefix.replace(/Maps$/, '');
|
||||
|
||||
return uncapitalize(withoutSuffix) as FlatEntityMapsKeyToMetadata<T>;
|
||||
};
|
||||
-28
@@ -1,28 +0,0 @@
|
||||
import { type SyncableFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-from.type';
|
||||
import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type';
|
||||
import { addFlatEntityToFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/add-flat-entity-to-flat-entity-maps-or-throw.util';
|
||||
import { deleteFlatEntityFromFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/delete-flat-entity-from-flat-entity-maps-or-throw.util';
|
||||
|
||||
export type ReplaceFlatEntityInFlatEntityMapsOrThrowArgs<
|
||||
T extends SyncableFlatEntity,
|
||||
> = {
|
||||
flatEntity: T;
|
||||
flatEntityMaps: FlatEntityMaps<T>;
|
||||
};
|
||||
|
||||
export const replaceFlatEntityInFlatEntityMapsOrThrow = <
|
||||
T extends SyncableFlatEntity,
|
||||
>({
|
||||
flatEntity,
|
||||
flatEntityMaps,
|
||||
}: ReplaceFlatEntityInFlatEntityMapsOrThrowArgs<T>): FlatEntityMaps<T> => {
|
||||
const flatEntityMapsToReplace = deleteFlatEntityFromFlatEntityMapsOrThrow({
|
||||
flatEntityMaps,
|
||||
entityToDeleteId: flatEntity.id,
|
||||
});
|
||||
|
||||
return addFlatEntityToFlatEntityMapsOrThrow({
|
||||
flatEntity,
|
||||
flatEntityMaps: flatEntityMapsToReplace,
|
||||
});
|
||||
};
|
||||
-6
@@ -1,6 +0,0 @@
|
||||
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
|
||||
|
||||
export type FieldMetadataMinimalInformation = Pick<
|
||||
FlatFieldMetadata,
|
||||
'id' | 'objectMetadataId' | 'name'
|
||||
>;
|
||||
-9
@@ -1,9 +0,0 @@
|
||||
import { type MetadataEntityPropertyName } from 'src/engine/metadata-modules/flat-entity/constant/all-entity-properties-configuration-by-metadata-name.constant';
|
||||
|
||||
export const FLAT_FIELD_PERMISSION_EDITABLE_PROPERTIES = [
|
||||
'roleId',
|
||||
'objectMetadataId',
|
||||
'fieldMetadataId',
|
||||
'canReadFieldValue',
|
||||
'canUpdateFieldValue',
|
||||
] as const satisfies MetadataEntityPropertyName<'fieldPermission'>[];
|
||||
-31
@@ -1,31 +0,0 @@
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type';
|
||||
import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util';
|
||||
import { type FlatFrontComponent } from 'src/engine/metadata-modules/flat-front-component/types/flat-front-component.type';
|
||||
import {
|
||||
FrontComponentException,
|
||||
FrontComponentExceptionCode,
|
||||
} from 'src/engine/metadata-modules/front-component/front-component.exception';
|
||||
|
||||
export const fromDeleteFrontComponentInputToFlatFrontComponentOrThrow = ({
|
||||
flatFrontComponentMaps,
|
||||
frontComponentId,
|
||||
}: {
|
||||
flatFrontComponentMaps: FlatEntityMaps<FlatFrontComponent>;
|
||||
frontComponentId: string;
|
||||
}): FlatFrontComponent => {
|
||||
const existingFlatFrontComponent = findFlatEntityByIdInFlatEntityMaps({
|
||||
flatEntityId: frontComponentId,
|
||||
flatEntityMaps: flatFrontComponentMaps,
|
||||
});
|
||||
|
||||
if (!isDefined(existingFlatFrontComponent)) {
|
||||
throw new FrontComponentException(
|
||||
'Front component not found',
|
||||
FrontComponentExceptionCode.FRONT_COMPONENT_NOT_FOUND,
|
||||
);
|
||||
}
|
||||
|
||||
return existingFlatFrontComponent;
|
||||
};
|
||||
-10
@@ -1,10 +0,0 @@
|
||||
import { type MetadataEntityPropertyName } from 'src/engine/metadata-modules/flat-entity/constant/all-entity-properties-configuration-by-metadata-name.constant';
|
||||
|
||||
export const FLAT_OBJECT_PERMISSION_EDITABLE_PROPERTIES = [
|
||||
'roleId',
|
||||
'objectMetadataId',
|
||||
'canReadObjectRecords',
|
||||
'canUpdateObjectRecords',
|
||||
'canSoftDeleteObjectRecords',
|
||||
'canDestroyObjectRecords',
|
||||
] as const satisfies MetadataEntityPropertyName<'objectPermission'>[];
|
||||
-10
@@ -1,10 +0,0 @@
|
||||
import { type AggregateChartConfigurationDTO } from 'src/engine/metadata-modules/page-layout-widget/dtos/aggregate-chart-configuration.dto';
|
||||
import { type BarChartConfigurationDTO } from 'src/engine/metadata-modules/page-layout-widget/dtos/bar-chart-configuration.dto';
|
||||
import { type LineChartConfigurationDTO } from 'src/engine/metadata-modules/page-layout-widget/dtos/line-chart-configuration.dto';
|
||||
import { type PieChartConfigurationDTO } from 'src/engine/metadata-modules/page-layout-widget/dtos/pie-chart-configuration.dto';
|
||||
|
||||
export type GraphConfiguration =
|
||||
| BarChartConfigurationDTO
|
||||
| LineChartConfigurationDTO
|
||||
| PieChartConfigurationDTO
|
||||
| AggregateChartConfigurationDTO;
|
||||
-6
@@ -1,6 +0,0 @@
|
||||
import { type WidgetConfigurationType } from 'src/engine/metadata-modules/page-layout-widget/enums/widget-configuration-type.type';
|
||||
|
||||
export type IframeConfiguration = {
|
||||
configurationType?: WidgetConfigurationType;
|
||||
url?: string;
|
||||
};
|
||||
@@ -1,6 +0,0 @@
|
||||
export * from './types/flat-page-layout.type';
|
||||
export * from './types/flat-page-layout-maps.type';
|
||||
export * from './constants/flat-page-layout-editable-properties.constant';
|
||||
export * from './utils/transform-page-layout-entity-to-flat-page-layout.util';
|
||||
export * from './services/workspace-flat-page-layout-map-cache.service';
|
||||
export * from './flat-page-layout.module';
|
||||
-7
@@ -1,7 +0,0 @@
|
||||
import { type MetadataEntityPropertyName } from 'src/engine/metadata-modules/flat-entity/constant/all-entity-properties-configuration-by-metadata-name.constant';
|
||||
import { ROLE_TARGET_FOREIGN_KEY_PROPERTIES } from 'src/engine/metadata-modules/flat-role-target/constants/role-target-foreign-key-properties.constant';
|
||||
|
||||
export const FLAT_ROLE_TARGET_EDITABLE_PROPERTIES = [
|
||||
'roleId',
|
||||
...ROLE_TARGET_FOREIGN_KEY_PROPERTIES,
|
||||
] as const satisfies MetadataEntityPropertyName<'roleTarget'>[];
|
||||
-17
@@ -1,17 +0,0 @@
|
||||
import { type MetadataEntityPropertyName } from 'src/engine/metadata-modules/flat-entity/constant/all-entity-properties-configuration-by-metadata-name.constant';
|
||||
|
||||
export const FLAT_ROLE_EDITABLE_PROPERTIES: MetadataEntityPropertyName<'role'>[] =
|
||||
[
|
||||
'label',
|
||||
'description',
|
||||
'icon',
|
||||
'canUpdateAllSettings',
|
||||
'canAccessAllTools',
|
||||
'canReadAllObjectRecords',
|
||||
'canUpdateAllObjectRecords',
|
||||
'canSoftDeleteAllObjectRecords',
|
||||
'canDestroyAllObjectRecords',
|
||||
'canBeAssignedToUsers',
|
||||
'canBeAssignedToAgents',
|
||||
'canBeAssignedToApiKeys',
|
||||
];
|
||||
-14
@@ -1,14 +0,0 @@
|
||||
/* @license Enterprise */
|
||||
|
||||
import { type MetadataEntityPropertyName } from 'src/engine/metadata-modules/flat-entity/constant/all-entity-properties-configuration-by-metadata-name.constant';
|
||||
|
||||
export const FLAT_ROW_LEVEL_PERMISSION_PREDICATE_EDITABLE_PROPERTIES = [
|
||||
'fieldMetadataId',
|
||||
'operand',
|
||||
'value',
|
||||
'rowLevelPermissionPredicateGroupId',
|
||||
'positionInRowLevelPermissionPredicateGroup',
|
||||
'subFieldName',
|
||||
'workspaceMemberFieldMetadataId',
|
||||
'workspaceMemberSubFieldName',
|
||||
] as const satisfies MetadataEntityPropertyName<'rowLevelPermissionPredicate'>[];
|
||||
-9
@@ -1,9 +0,0 @@
|
||||
/* @license Enterprise */
|
||||
|
||||
import { type MetadataEntityPropertyName } from 'src/engine/metadata-modules/flat-entity/constant/all-entity-properties-configuration-by-metadata-name.constant';
|
||||
|
||||
export const FLAT_ROW_LEVEL_PERMISSION_PREDICATE_GROUP_EDITABLE_PROPERTIES = [
|
||||
'logicalOperator',
|
||||
'positionInRowLevelPermissionPredicateGroup',
|
||||
'parentRowLevelPermissionPredicateGroupId',
|
||||
] as const satisfies MetadataEntityPropertyName<'rowLevelPermissionPredicateGroup'>[];
|
||||
-11
@@ -1,11 +0,0 @@
|
||||
import { createHash } from 'crypto';
|
||||
|
||||
export const generateDeterministicIndexName = (columns: string[]): string => {
|
||||
const hash = createHash('sha256');
|
||||
|
||||
columns.forEach((column) => {
|
||||
hash.update(column);
|
||||
});
|
||||
|
||||
return hash.digest('hex').slice(0, 27);
|
||||
};
|
||||
-88
@@ -1,88 +0,0 @@
|
||||
import { Field, InputType } from '@nestjs/graphql';
|
||||
|
||||
import {
|
||||
IsBoolean,
|
||||
IsEnum,
|
||||
IsNotEmpty,
|
||||
IsOptional,
|
||||
IsString,
|
||||
IsUUID,
|
||||
} from 'class-validator';
|
||||
import {
|
||||
MessageChannelContactAutoCreationPolicy,
|
||||
MessageChannelPendingGroupEmailsAction,
|
||||
MessageChannelSyncStage,
|
||||
MessageChannelType,
|
||||
MessageChannelVisibility,
|
||||
MessageFolderImportPolicy,
|
||||
} from 'twenty-shared/types';
|
||||
|
||||
import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars';
|
||||
|
||||
@InputType()
|
||||
export class CreateMessageChannelInput {
|
||||
@IsUUID()
|
||||
@IsOptional()
|
||||
@Field(() => UUIDScalarType, { nullable: true })
|
||||
id?: string;
|
||||
|
||||
@IsString()
|
||||
@IsNotEmpty()
|
||||
@Field()
|
||||
handle: string;
|
||||
|
||||
@IsEnum(MessageChannelVisibility)
|
||||
@IsNotEmpty()
|
||||
@Field(() => MessageChannelVisibility)
|
||||
visibility: MessageChannelVisibility;
|
||||
|
||||
@IsEnum(MessageChannelType)
|
||||
@IsNotEmpty()
|
||||
@Field(() => MessageChannelType)
|
||||
type: MessageChannelType;
|
||||
|
||||
@IsEnum(MessageChannelSyncStage)
|
||||
@IsNotEmpty()
|
||||
@Field(() => MessageChannelSyncStage)
|
||||
syncStage: MessageChannelSyncStage;
|
||||
|
||||
@IsUUID()
|
||||
@IsNotEmpty()
|
||||
@Field(() => UUIDScalarType)
|
||||
connectedAccountId: string;
|
||||
|
||||
@IsBoolean()
|
||||
@IsNotEmpty()
|
||||
@Field()
|
||||
isContactAutoCreationEnabled: boolean;
|
||||
|
||||
@IsEnum(MessageChannelContactAutoCreationPolicy)
|
||||
@IsNotEmpty()
|
||||
@Field(() => MessageChannelContactAutoCreationPolicy)
|
||||
contactAutoCreationPolicy: MessageChannelContactAutoCreationPolicy;
|
||||
|
||||
@IsEnum(MessageFolderImportPolicy)
|
||||
@IsNotEmpty()
|
||||
@Field(() => MessageFolderImportPolicy)
|
||||
messageFolderImportPolicy: MessageFolderImportPolicy;
|
||||
|
||||
@IsBoolean()
|
||||
@IsNotEmpty()
|
||||
@Field()
|
||||
excludeNonProfessionalEmails: boolean;
|
||||
|
||||
@IsBoolean()
|
||||
@IsNotEmpty()
|
||||
@Field()
|
||||
excludeGroupEmails: boolean;
|
||||
|
||||
@IsEnum(MessageChannelPendingGroupEmailsAction)
|
||||
@IsNotEmpty()
|
||||
@Field(() => MessageChannelPendingGroupEmailsAction)
|
||||
pendingGroupEmailsAction: MessageChannelPendingGroupEmailsAction;
|
||||
|
||||
@IsBoolean()
|
||||
@IsNotEmpty()
|
||||
@Field()
|
||||
isSyncEnabled: boolean;
|
||||
}
|
||||
-56
@@ -1,56 +0,0 @@
|
||||
import { Field, InputType } from '@nestjs/graphql';
|
||||
|
||||
import {
|
||||
IsBoolean,
|
||||
IsEnum,
|
||||
IsNotEmpty,
|
||||
IsOptional,
|
||||
IsString,
|
||||
IsUUID,
|
||||
} from 'class-validator';
|
||||
import { MessageFolderPendingSyncAction } from 'twenty-shared/types';
|
||||
|
||||
import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars';
|
||||
|
||||
@InputType()
|
||||
export class CreateMessageFolderInput {
|
||||
@IsUUID()
|
||||
@IsOptional()
|
||||
@Field(() => UUIDScalarType, { nullable: true })
|
||||
id?: string;
|
||||
|
||||
@IsString()
|
||||
@IsOptional()
|
||||
@Field({ nullable: true })
|
||||
name?: string;
|
||||
|
||||
@IsBoolean()
|
||||
@IsNotEmpty()
|
||||
@Field()
|
||||
isSentFolder: boolean;
|
||||
|
||||
@IsBoolean()
|
||||
@IsNotEmpty()
|
||||
@Field()
|
||||
isSynced: boolean;
|
||||
|
||||
@IsString()
|
||||
@IsOptional()
|
||||
@Field({ nullable: true })
|
||||
externalId?: string;
|
||||
|
||||
@IsEnum(MessageFolderPendingSyncAction)
|
||||
@IsNotEmpty()
|
||||
@Field(() => MessageFolderPendingSyncAction)
|
||||
pendingSyncAction: MessageFolderPendingSyncAction;
|
||||
|
||||
@IsUUID()
|
||||
@IsNotEmpty()
|
||||
@Field(() => UUIDScalarType)
|
||||
messageChannelId: string;
|
||||
|
||||
@IsString()
|
||||
@IsOptional()
|
||||
@Field(() => String, { nullable: true })
|
||||
parentFolderId?: string;
|
||||
}
|
||||
-13
@@ -1,13 +0,0 @@
|
||||
import { Field, InputType } from '@nestjs/graphql';
|
||||
|
||||
import { IsNotEmpty, IsUUID } from 'class-validator';
|
||||
|
||||
import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars';
|
||||
|
||||
@InputType()
|
||||
export class DeletePageLayoutWidgetInput {
|
||||
@Field(() => UUIDScalarType)
|
||||
@IsUUID()
|
||||
@IsNotEmpty()
|
||||
id: string;
|
||||
}
|
||||
-1
@@ -1 +0,0 @@
|
||||
export const ADMIN_ROLE_LABEL = 'Admin';
|
||||
@@ -1,3 +0,0 @@
|
||||
import { type FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
|
||||
|
||||
export type FieldMetadataMap = Record<string, FieldMetadataEntity>; // TODO refactor Should be CachedFieldMetadataEntity or best FlatFieldMetadata
|
||||
-8
@@ -1,8 +0,0 @@
|
||||
import { IDENTIFIER_MAX_CHAR_LENGTH } from 'twenty-shared/metadata';
|
||||
import { IDENTIFIER_MIN_CHAR_LENGTH } from 'src/engine/metadata-modules/utils/constants/identifier-min-char-length.constants';
|
||||
|
||||
export const exceedsDatabaseIdentifierMaximumLength = (string: string) =>
|
||||
string.length > IDENTIFIER_MAX_CHAR_LENGTH;
|
||||
|
||||
export const beneathDatabaseIdentifierMinimumLength = (string: string) =>
|
||||
string.length < IDENTIFIER_MIN_CHAR_LENGTH;
|
||||
-44
@@ -1,44 +0,0 @@
|
||||
import { type MessageDescriptor } from '@lingui/core';
|
||||
import { msg } from '@lingui/core/macro';
|
||||
import { assertUnreachable } from 'twenty-shared/utils';
|
||||
|
||||
import { STANDARD_ERROR_MESSAGE } from 'src/engine/api/common/common-query-runners/errors/standard-error-message.constant';
|
||||
import {
|
||||
appendCommonExceptionCode,
|
||||
CustomException,
|
||||
} from 'src/utils/custom-exception';
|
||||
|
||||
export const FlatViewExceptionCode = appendCommonExceptionCode({
|
||||
VIEW_NOT_FOUND: 'VIEW_NOT_FOUND',
|
||||
VIEW_ALREADY_EXISTS: 'VIEW_ALREADY_EXISTS',
|
||||
} as const);
|
||||
|
||||
const getFlatViewExceptionUserFriendlyMessage = (
|
||||
code: keyof typeof FlatViewExceptionCode,
|
||||
) => {
|
||||
switch (code) {
|
||||
case FlatViewExceptionCode.VIEW_NOT_FOUND:
|
||||
return msg`View not found.`;
|
||||
case FlatViewExceptionCode.VIEW_ALREADY_EXISTS:
|
||||
return msg`View already exists.`;
|
||||
case FlatViewExceptionCode.INTERNAL_SERVER_ERROR:
|
||||
return STANDARD_ERROR_MESSAGE;
|
||||
default:
|
||||
assertUnreachable(code);
|
||||
}
|
||||
};
|
||||
|
||||
export class FlatViewException extends CustomException<
|
||||
keyof typeof FlatViewExceptionCode
|
||||
> {
|
||||
constructor(
|
||||
message: string,
|
||||
code: keyof typeof FlatViewExceptionCode,
|
||||
{ userFriendlyMessage }: { userFriendlyMessage?: MessageDescriptor } = {},
|
||||
) {
|
||||
super(message, code, {
|
||||
userFriendlyMessage:
|
||||
userFriendlyMessage ?? getFlatViewExceptionUserFriendlyMessage(code),
|
||||
});
|
||||
}
|
||||
}
|
||||
-4
@@ -1,4 +0,0 @@
|
||||
export enum ViewOpenRecordInType {
|
||||
SIDE_PANEL = 'SIDE_PANEL',
|
||||
RECORD_PAGE = 'RECORD_PAGE',
|
||||
}
|
||||
Reference in New Issue
Block a user