[BREAKING_CHANGE/GRAPHQL/OBJECT_METADATA_CREATE_ONE] Remove object/fields/view-fields v1 implementation (#15823)
# Introduction Remove the v2 feature flag for view-field field-metadata and object-metadata metadata entities ## Some details - Disabled nestjs-query for object metadata creation and explicitly calling it - removed all v1 integration tests files ## Remarks Not remove v2 referencing in both filenaming right now will handle that globally later ## Breaking change Due to object metadata resolver createOne standardization had to rename the input from `CreateObjectInput` to `CreateOneObjectInput`
This commit is contained in:
+2
-2
@@ -6,7 +6,7 @@ import { DeleteRecordService } from 'src/engine/core-modules/record-crud/service
|
||||
import { FindRecordsService } from 'src/engine/core-modules/record-crud/services/find-records.service';
|
||||
import { UpdateRecordService } from 'src/engine/core-modules/record-crud/services/update-record.service';
|
||||
import { RecordInputTransformerService } from 'src/engine/core-modules/record-transformer/services/record-input-transformer.service';
|
||||
import { ObjectMetadataService } from 'src/engine/metadata-modules/object-metadata/object-metadata.service';
|
||||
import { ObjectMetadataServiceV2 } from 'src/engine/metadata-modules/object-metadata/object-metadata-v2.service';
|
||||
import { WorkspacePermissionsCacheService } from 'src/engine/metadata-modules/workspace-permissions-cache/workspace-permissions-cache.service';
|
||||
import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager';
|
||||
import { WorkspaceCacheStorageService } from 'src/engine/workspace-cache-storage/workspace-cache-storage.service';
|
||||
@@ -57,7 +57,7 @@ describe('ToolService', () => {
|
||||
},
|
||||
},
|
||||
{
|
||||
provide: ObjectMetadataService,
|
||||
provide: ObjectMetadataServiceV2,
|
||||
useValue: {
|
||||
findManyWithinWorkspace: jest.fn().mockResolvedValue([testObject]),
|
||||
},
|
||||
|
||||
@@ -17,7 +17,7 @@ import {
|
||||
type ToolHints,
|
||||
type ToolOperation,
|
||||
} from 'src/engine/metadata-modules/ai-router/types/tool-hints.interface';
|
||||
import { ObjectMetadataService } from 'src/engine/metadata-modules/object-metadata/object-metadata.service';
|
||||
import { ObjectMetadataServiceV2 } from 'src/engine/metadata-modules/object-metadata/object-metadata-v2.service';
|
||||
import { WorkspacePermissionsCacheService } from 'src/engine/metadata-modules/workspace-permissions-cache/workspace-permissions-cache.service';
|
||||
import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager';
|
||||
import { type RolePermissionConfig } from 'src/engine/twenty-orm/types/role-permission-config';
|
||||
@@ -29,7 +29,7 @@ export class ToolService {
|
||||
|
||||
constructor(
|
||||
private readonly twentyORMGlobalManager: TwentyORMGlobalManager,
|
||||
private readonly objectMetadataService: ObjectMetadataService,
|
||||
private readonly objectMetadataService: ObjectMetadataServiceV2,
|
||||
protected readonly workspacePermissionsCacheService: WorkspacePermissionsCacheService,
|
||||
private readonly createRecordService: CreateRecordService,
|
||||
private readonly updateRecordService: UpdateRecordService,
|
||||
|
||||
+6
-6
@@ -219,7 +219,7 @@ export class ApplicationSyncService {
|
||||
);
|
||||
|
||||
for (const fieldToDelete of fieldsToDelete) {
|
||||
await this.fieldMetadataServiceV2.updateOne({
|
||||
await this.fieldMetadataServiceV2.updateOneField({
|
||||
updateFieldInput: {
|
||||
id: fieldToDelete.id,
|
||||
isActive: false,
|
||||
@@ -256,7 +256,7 @@ export class ApplicationSyncService {
|
||||
isNullable: fieldToSync.isNullable ?? true,
|
||||
};
|
||||
|
||||
await this.fieldMetadataServiceV2.updateOne({
|
||||
await this.fieldMetadataServiceV2.updateOneField({
|
||||
updateFieldInput,
|
||||
workspaceId,
|
||||
});
|
||||
@@ -281,7 +281,7 @@ export class ApplicationSyncService {
|
||||
workspaceId,
|
||||
};
|
||||
|
||||
await this.fieldMetadataServiceV2.createOne({
|
||||
await this.fieldMetadataServiceV2.createOneField({
|
||||
createFieldInput,
|
||||
workspaceId,
|
||||
});
|
||||
@@ -341,7 +341,7 @@ export class ApplicationSyncService {
|
||||
);
|
||||
|
||||
for (const objectToDelete of objectsToDelete) {
|
||||
await this.objectMetadataServiceV2.deleteOne({
|
||||
await this.objectMetadataServiceV2.deleteOneObject({
|
||||
deleteObjectInput: { id: objectToDelete.id },
|
||||
workspaceId,
|
||||
isSystemBuild: true,
|
||||
@@ -372,7 +372,7 @@ export class ApplicationSyncService {
|
||||
},
|
||||
};
|
||||
|
||||
await this.objectMetadataServiceV2.updateOne({
|
||||
await this.objectMetadataServiceV2.updateOneObject({
|
||||
updateObjectInput,
|
||||
workspaceId,
|
||||
});
|
||||
@@ -404,7 +404,7 @@ export class ApplicationSyncService {
|
||||
applicationId,
|
||||
};
|
||||
|
||||
const createdObject = await this.objectMetadataServiceV2.createOne({
|
||||
const createdObject = await this.objectMetadataServiceV2.createOneObject({
|
||||
createObjectInput,
|
||||
workspaceId,
|
||||
});
|
||||
|
||||
@@ -4,7 +4,7 @@ import { AccessTokenService } from 'src/engine/core-modules/auth/token/services/
|
||||
import { FeatureFlagService } from 'src/engine/core-modules/feature-flag/services/feature-flag.service';
|
||||
import { OpenApiService } from 'src/engine/core-modules/open-api/open-api.service';
|
||||
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
|
||||
import { ObjectMetadataService } from 'src/engine/metadata-modules/object-metadata/object-metadata.service';
|
||||
import { ObjectMetadataServiceV2 } from 'src/engine/metadata-modules/object-metadata/object-metadata-v2.service';
|
||||
|
||||
describe('OpenApiService', () => {
|
||||
let service: OpenApiService;
|
||||
@@ -18,7 +18,7 @@ describe('OpenApiService', () => {
|
||||
useValue: {},
|
||||
},
|
||||
{
|
||||
provide: ObjectMetadataService,
|
||||
provide: ObjectMetadataServiceV2,
|
||||
useValue: {},
|
||||
},
|
||||
{
|
||||
|
||||
@@ -47,8 +47,8 @@ import {
|
||||
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
|
||||
import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||
import { WorkspaceNotFoundDefaultError } from 'src/engine/core-modules/workspace/workspace.exception';
|
||||
import { ObjectMetadataServiceV2 } from 'src/engine/metadata-modules/object-metadata/object-metadata-v2.service';
|
||||
import { type ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||
import { ObjectMetadataService } from 'src/engine/metadata-modules/object-metadata/object-metadata.service';
|
||||
import { standardObjectMetadataDefinitions } from 'src/engine/workspace-manager/workspace-sync-metadata/standard-objects';
|
||||
import { shouldExcludeFromWorkspaceApi } from 'src/engine/workspace-manager/workspace-sync-metadata/utils/should-exclude-from-workspace-api.util';
|
||||
import { getServerUrl } from 'src/utils/get-server-url';
|
||||
@@ -58,7 +58,7 @@ export class OpenApiService {
|
||||
constructor(
|
||||
private readonly accessTokenService: AccessTokenService,
|
||||
private readonly twentyConfigService: TwentyConfigService,
|
||||
private readonly objectMetadataService: ObjectMetadataService,
|
||||
private readonly objectMetadataService: ObjectMetadataServiceV2,
|
||||
private readonly featureFlagService: FeatureFlagService,
|
||||
) {}
|
||||
|
||||
|
||||
-215
@@ -1,215 +0,0 @@
|
||||
import { Transform } from 'class-transformer';
|
||||
import {
|
||||
IsArray,
|
||||
IsBoolean,
|
||||
IsEnum,
|
||||
IsNumber,
|
||||
IsString,
|
||||
} from 'class-validator';
|
||||
|
||||
import { ConfigVariableType } from 'src/engine/core-modules/twenty-config/enums/config-variable-type.enum';
|
||||
import { applyBasicValidators } from 'src/engine/core-modules/twenty-config/utils/apply-basic-validators.util';
|
||||
import { configTransformers } from 'src/engine/core-modules/twenty-config/utils/config-transformers.util';
|
||||
|
||||
jest.mock('class-transformer', () => ({
|
||||
Transform: jest.fn(),
|
||||
}));
|
||||
|
||||
jest.mock('class-validator', () => ({
|
||||
IsBoolean: jest.fn().mockReturnValue(jest.fn()),
|
||||
IsNumber: jest.fn().mockReturnValue(jest.fn()),
|
||||
IsString: jest.fn().mockReturnValue(jest.fn()),
|
||||
IsEnum: jest.fn().mockReturnValue(jest.fn()),
|
||||
IsArray: jest.fn().mockReturnValue(jest.fn()),
|
||||
}));
|
||||
|
||||
jest.mock(
|
||||
'src/engine/core-modules/twenty-config/utils/config-transformers.util',
|
||||
() => ({
|
||||
configTransformers: {
|
||||
boolean: jest.fn(),
|
||||
number: jest.fn(),
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
describe('applyBasicValidators', () => {
|
||||
const mockTarget = {};
|
||||
const mockPropertyKey = 'testProperty';
|
||||
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
describe('boolean type', () => {
|
||||
it('should apply boolean transformers and validators', () => {
|
||||
let capturedTransformFn;
|
||||
|
||||
(Transform as jest.Mock).mockImplementation((transformFn) => {
|
||||
capturedTransformFn = transformFn;
|
||||
|
||||
return jest.fn();
|
||||
});
|
||||
|
||||
applyBasicValidators(
|
||||
ConfigVariableType.BOOLEAN,
|
||||
mockTarget,
|
||||
mockPropertyKey,
|
||||
);
|
||||
|
||||
expect(Transform).toHaveBeenCalled();
|
||||
expect(IsBoolean).toHaveBeenCalled();
|
||||
|
||||
const transformFn = capturedTransformFn;
|
||||
const mockTransformParams = { value: 'true' };
|
||||
|
||||
(configTransformers.boolean as jest.Mock).mockReturnValueOnce(true);
|
||||
// @ts-expect-error legacy noImplicitAny
|
||||
const result1 = transformFn(mockTransformParams);
|
||||
|
||||
expect(configTransformers.boolean).toHaveBeenCalledWith('true');
|
||||
expect(result1).toBe(true);
|
||||
|
||||
(configTransformers.boolean as jest.Mock).mockReturnValueOnce(undefined);
|
||||
// @ts-expect-error legacy noImplicitAny
|
||||
const result2 = transformFn(mockTransformParams);
|
||||
|
||||
expect(result2).toBe('true');
|
||||
});
|
||||
});
|
||||
|
||||
describe('number type', () => {
|
||||
it('should apply number transformers and validators', () => {
|
||||
let capturedTransformFn;
|
||||
|
||||
(Transform as jest.Mock).mockImplementation((transformFn) => {
|
||||
capturedTransformFn = transformFn;
|
||||
|
||||
return jest.fn();
|
||||
});
|
||||
|
||||
applyBasicValidators(
|
||||
ConfigVariableType.NUMBER,
|
||||
mockTarget,
|
||||
mockPropertyKey,
|
||||
);
|
||||
|
||||
expect(Transform).toHaveBeenCalled();
|
||||
expect(IsNumber).toHaveBeenCalled();
|
||||
|
||||
const transformFn = capturedTransformFn;
|
||||
const mockTransformParams = { value: '42' };
|
||||
|
||||
(configTransformers.number as jest.Mock).mockReturnValueOnce(42);
|
||||
// @ts-expect-error legacy noImplicitAny
|
||||
const result1 = transformFn(mockTransformParams);
|
||||
|
||||
expect(configTransformers.number).toHaveBeenCalledWith('42');
|
||||
expect(result1).toBe(42);
|
||||
|
||||
(configTransformers.number as jest.Mock).mockReturnValueOnce(undefined);
|
||||
// @ts-expect-error legacy noImplicitAny
|
||||
const result2 = transformFn(mockTransformParams);
|
||||
|
||||
expect(result2).toBe('42');
|
||||
});
|
||||
});
|
||||
|
||||
describe('string type', () => {
|
||||
it('should apply string validator', () => {
|
||||
applyBasicValidators(
|
||||
ConfigVariableType.STRING,
|
||||
mockTarget,
|
||||
mockPropertyKey,
|
||||
);
|
||||
|
||||
expect(IsString).toHaveBeenCalled();
|
||||
expect(Transform).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('enum type', () => {
|
||||
it('should apply enum validator with string array options', () => {
|
||||
const enumOptions = ['option1', 'option2', 'option3'];
|
||||
|
||||
applyBasicValidators(
|
||||
ConfigVariableType.ENUM,
|
||||
mockTarget,
|
||||
mockPropertyKey,
|
||||
enumOptions,
|
||||
);
|
||||
|
||||
expect(IsEnum).toHaveBeenCalledWith(enumOptions);
|
||||
expect(Transform).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should apply enum validator with enum object options', () => {
|
||||
enum TestEnum {
|
||||
Option1 = 'value1',
|
||||
Option2 = 'value2',
|
||||
Option3 = 'value3',
|
||||
}
|
||||
|
||||
jest.mock(
|
||||
'src/engine/core-modules/twenty-config/utils/type-transformers.registry',
|
||||
() => ({
|
||||
typeTransformers: {
|
||||
enum: {
|
||||
getValidators: jest.fn().mockImplementation((options) => {
|
||||
if (options && Object.keys(options).length > 0) {
|
||||
return [IsEnum(options)];
|
||||
}
|
||||
|
||||
return [];
|
||||
}),
|
||||
getTransformers: jest.fn().mockReturnValue([]),
|
||||
},
|
||||
},
|
||||
}),
|
||||
{ virtual: true },
|
||||
);
|
||||
|
||||
applyBasicValidators(
|
||||
ConfigVariableType.ENUM,
|
||||
mockTarget,
|
||||
mockPropertyKey,
|
||||
TestEnum,
|
||||
);
|
||||
|
||||
expect(IsEnum).toHaveBeenCalledWith(TestEnum);
|
||||
expect(Transform).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should not apply enum validator without options', () => {
|
||||
applyBasicValidators(
|
||||
ConfigVariableType.ENUM,
|
||||
mockTarget,
|
||||
mockPropertyKey,
|
||||
);
|
||||
|
||||
expect(IsEnum).not.toHaveBeenCalled();
|
||||
expect(Transform).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('array type', () => {
|
||||
it('should apply array validator', () => {
|
||||
applyBasicValidators(
|
||||
ConfigVariableType.ARRAY,
|
||||
mockTarget,
|
||||
mockPropertyKey,
|
||||
);
|
||||
|
||||
expect(IsArray).toHaveBeenCalled();
|
||||
expect(Transform).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('unsupported type', () => {
|
||||
it('should throw error for unsupported types', () => {
|
||||
expect(() => {
|
||||
applyBasicValidators('unsupported' as any, mockTarget, mockPropertyKey);
|
||||
}).toThrow('Unsupported config variable type: unsupported');
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user