Refactor backend folder structure (#4505)

* Refactor backend folder structure

Co-authored-by: Charles Bochet <charles@twenty.com>

* fix tests

* fix

* move yoga hooks

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
Weiko
2024-03-15 18:37:09 +01:00
committed by GitHub
parent afb9b3e375
commit 2c09096edd
523 changed files with 1386 additions and 1856 deletions

View File

@ -0,0 +1,30 @@
import { RecordDuplicateCriteria } from 'src/engine/api/graphql/workspace-query-builder/interfaces/record.interface';
/**
* objectName: directly reference the name of the object from the metadata tables.
* columnNames: reference the column names not the field names.
* So if we need to reference a custom field, we should directly add the column name like `_customColumn`.
* If we need to terence a composite field, we should add all children of the composite like `nameFirstName` and `nameLastName`
*/
export const duplicateCriteriaCollection: RecordDuplicateCriteria[] = [
{
objectName: 'company',
columnNames: ['domainName'],
},
{
objectName: 'company',
columnNames: ['name'],
},
{
objectName: 'person',
columnNames: ['nameFirstName', 'nameLastName'],
},
{
objectName: 'person',
columnNames: ['linkedinLinkUrl'],
},
{
objectName: 'person',
columnNames: ['email'],
},
];

View File

@ -0,0 +1,38 @@
import { Injectable } from '@nestjs/common';
import {
CreateManyResolverArgs,
Resolver,
} from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
import { WorkspaceSchemaBuilderContext } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-schema-builder-context.interface';
import { WorkspaceResolverBuilderFactoryInterface } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolver-builder-factory.interface';
import { WorkspaceQueryRunnerService } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-runner.service';
@Injectable()
export class CreateManyResolverFactory
implements WorkspaceResolverBuilderFactoryInterface
{
public static methodName = 'createMany' as const;
constructor(
private readonly workspaceQueryRunnerService: WorkspaceQueryRunnerService,
) {}
create(
context: WorkspaceSchemaBuilderContext,
): Resolver<CreateManyResolverArgs> {
const internalContext = context;
return (_source, args, context, info) => {
return this.workspaceQueryRunnerService.createMany(args, {
objectMetadataItem: internalContext.objectMetadataItem,
workspaceId: internalContext.workspaceId,
userId: internalContext.userId,
info,
fieldMetadataCollection: internalContext.fieldMetadataCollection,
objectMetadataCollection: internalContext.objectMetadataCollection,
});
};
}
}

View File

@ -0,0 +1,38 @@
import { Injectable } from '@nestjs/common';
import {
CreateOneResolverArgs,
Resolver,
} from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
import { WorkspaceSchemaBuilderContext } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-schema-builder-context.interface';
import { WorkspaceResolverBuilderFactoryInterface } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolver-builder-factory.interface';
import { WorkspaceQueryRunnerService } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-runner.service';
@Injectable()
export class CreateOneResolverFactory
implements WorkspaceResolverBuilderFactoryInterface
{
public static methodName = 'createOne' as const;
constructor(
private readonly workspaceQueryRunnerService: WorkspaceQueryRunnerService,
) {}
create(
context: WorkspaceSchemaBuilderContext,
): Resolver<CreateOneResolverArgs> {
const internalContext = context;
return (_source, args, context, info) => {
return this.workspaceQueryRunnerService.createOne(args, {
objectMetadataItem: internalContext.objectMetadataItem,
workspaceId: internalContext.workspaceId,
userId: internalContext.userId,
info,
fieldMetadataCollection: internalContext.fieldMetadataCollection,
objectMetadataCollection: internalContext.objectMetadataCollection,
});
};
}
}

View File

@ -0,0 +1,38 @@
import { Injectable } from '@nestjs/common';
import {
DeleteManyResolverArgs,
Resolver,
} from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
import { WorkspaceSchemaBuilderContext } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-schema-builder-context.interface';
import { WorkspaceResolverBuilderFactoryInterface } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolver-builder-factory.interface';
import { WorkspaceQueryRunnerService } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-runner.service';
@Injectable()
export class DeleteManyResolverFactory
implements WorkspaceResolverBuilderFactoryInterface
{
public static methodName = 'deleteMany' as const;
constructor(
private readonly workspaceQueryRunnerService: WorkspaceQueryRunnerService,
) {}
create(
context: WorkspaceSchemaBuilderContext,
): Resolver<DeleteManyResolverArgs> {
const internalContext = context;
return (_source, args, context, info) => {
return this.workspaceQueryRunnerService.deleteMany(args, {
objectMetadataItem: internalContext.objectMetadataItem,
workspaceId: internalContext.workspaceId,
userId: internalContext.userId,
info,
fieldMetadataCollection: internalContext.fieldMetadataCollection,
objectMetadataCollection: internalContext.objectMetadataCollection,
});
};
}
}

View File

@ -0,0 +1,38 @@
import { Injectable } from '@nestjs/common';
import {
DeleteOneResolverArgs,
Resolver,
} from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
import { WorkspaceSchemaBuilderContext } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-schema-builder-context.interface';
import { WorkspaceResolverBuilderFactoryInterface } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolver-builder-factory.interface';
import { WorkspaceQueryRunnerService } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-runner.service';
@Injectable()
export class DeleteOneResolverFactory
implements WorkspaceResolverBuilderFactoryInterface
{
public static methodName = 'deleteOne' as const;
constructor(
private readonly workspaceQueryRunnerService: WorkspaceQueryRunnerService,
) {}
create(
context: WorkspaceSchemaBuilderContext,
): Resolver<DeleteOneResolverArgs> {
const internalContext = context;
return (_source, args, context, info) => {
return this.workspaceQueryRunnerService.deleteOne(args, {
objectMetadataItem: internalContext.objectMetadataItem,
workspaceId: internalContext.workspaceId,
userId: internalContext.userId,
info,
fieldMetadataCollection: internalContext.fieldMetadataCollection,
objectMetadataCollection: internalContext.objectMetadataCollection,
});
};
}
}

View File

@ -0,0 +1,76 @@
import { Injectable } from '@nestjs/common';
import {
Resolver,
FindOneResolverArgs,
ExecuteQuickActionOnOneResolverArgs,
DeleteOneResolverArgs,
} from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
import { Record as IRecord } from 'src/engine/api/graphql/workspace-query-builder/interfaces/record.interface';
import { WorkspaceSchemaBuilderContext } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-schema-builder-context.interface';
import { WorkspaceResolverBuilderFactoryInterface } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolver-builder-factory.interface';
import { WorkspaceQueryRunnerOptions } from 'src/engine/api/graphql/workspace-query-runner/interfaces/query-runner-option.interface';
import { WorkspaceQueryRunnerService } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-runner.service';
import { QuickActionsService } from 'src/engine/modules/quick-actions/quick-actions.service';
@Injectable()
export class ExecuteQuickActionOnOneResolverFactory
implements WorkspaceResolverBuilderFactoryInterface
{
public static methodName = 'executeQuickActionOnOne' as const;
constructor(
private readonly workspaceQueryRunnerService: WorkspaceQueryRunnerService,
private readonly quickActionsService: QuickActionsService,
) {}
create(
context: WorkspaceSchemaBuilderContext,
): Resolver<ExecuteQuickActionOnOneResolverArgs> {
const internalContext = context;
return (_source, args, context, info) => {
return this.executeQuickActionOnOne(args, {
objectMetadataItem: internalContext.objectMetadataItem,
userId: internalContext.userId,
workspaceId: internalContext.workspaceId,
info,
fieldMetadataCollection: internalContext.fieldMetadataCollection,
objectMetadataCollection: internalContext.objectMetadataCollection,
});
};
}
private async executeQuickActionOnOne<Record extends IRecord = IRecord>(
args: DeleteOneResolverArgs,
options: WorkspaceQueryRunnerOptions,
): Promise<Record | undefined> {
switch (options.objectMetadataItem.nameSingular) {
case 'company': {
await this.quickActionsService.executeQuickActionOnCompany(
args.id,
options.workspaceId,
options.objectMetadataItem,
);
break;
}
case 'person': {
await this.quickActionsService.createCompanyFromPerson(
args.id,
options.workspaceId,
options.objectMetadataCollection,
);
break;
}
default:
// TODO: different quick actions per object on frontend
break;
}
return this.workspaceQueryRunnerService.findOne(
{ filter: { id: { eq: args.id } } } as FindOneResolverArgs,
options,
);
}
}

View File

@ -0,0 +1,41 @@
import { UpdateManyResolverFactory } from 'src/engine/api/graphql/workspace-resolver-builder/factories/update-many-resolver.factory';
import { FindDuplicatesResolverFactory } from './find-duplicates-resolver.factory';
import { FindManyResolverFactory } from './find-many-resolver.factory';
import { FindOneResolverFactory } from './find-one-resolver.factory';
import { CreateManyResolverFactory } from './create-many-resolver.factory';
import { CreateOneResolverFactory } from './create-one-resolver.factory';
import { UpdateOneResolverFactory } from './update-one-resolver.factory';
import { DeleteOneResolverFactory } from './delete-one-resolver.factory';
import { DeleteManyResolverFactory } from './delete-many-resolver.factory';
import { ExecuteQuickActionOnOneResolverFactory } from './execute-quick-action-on-one-resolver.factory';
export const workspaceResolverBuilderFactories = [
FindManyResolverFactory,
FindOneResolverFactory,
FindDuplicatesResolverFactory,
CreateManyResolverFactory,
CreateOneResolverFactory,
UpdateOneResolverFactory,
DeleteOneResolverFactory,
ExecuteQuickActionOnOneResolverFactory,
UpdateManyResolverFactory,
DeleteManyResolverFactory,
];
export const workspaceResolverBuilderMethodNames = {
queries: [
FindManyResolverFactory.methodName,
FindOneResolverFactory.methodName,
FindDuplicatesResolverFactory.methodName,
],
mutations: [
CreateManyResolverFactory.methodName,
CreateOneResolverFactory.methodName,
UpdateOneResolverFactory.methodName,
DeleteOneResolverFactory.methodName,
ExecuteQuickActionOnOneResolverFactory.methodName,
UpdateManyResolverFactory.methodName,
DeleteManyResolverFactory.methodName,
],
} as const;

View File

@ -0,0 +1,38 @@
import { Injectable } from '@nestjs/common';
import {
FindDuplicatesResolverArgs,
Resolver,
} from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
import { WorkspaceSchemaBuilderContext } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-schema-builder-context.interface';
import { WorkspaceResolverBuilderFactoryInterface } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolver-builder-factory.interface';
import { WorkspaceQueryRunnerService } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-runner.service';
@Injectable()
export class FindDuplicatesResolverFactory
implements WorkspaceResolverBuilderFactoryInterface
{
public static methodName = 'findDuplicates' as const;
constructor(
private readonly workspaceQueryRunnerService: WorkspaceQueryRunnerService,
) {}
create(
context: WorkspaceSchemaBuilderContext,
): Resolver<FindDuplicatesResolverArgs> {
const internalContext = context;
return (_source, args, context, info) => {
return this.workspaceQueryRunnerService.findDuplicates(args, {
objectMetadataItem: internalContext.objectMetadataItem,
workspaceId: internalContext.workspaceId,
userId: internalContext.userId,
info,
fieldMetadataCollection: internalContext.fieldMetadataCollection,
objectMetadataCollection: internalContext.objectMetadataCollection,
});
};
}
}

View File

@ -0,0 +1,38 @@
import { Injectable } from '@nestjs/common';
import {
FindManyResolverArgs,
Resolver,
} from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
import { WorkspaceSchemaBuilderContext } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-schema-builder-context.interface';
import { WorkspaceResolverBuilderFactoryInterface } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolver-builder-factory.interface';
import { WorkspaceQueryRunnerService } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-runner.service';
@Injectable()
export class FindManyResolverFactory
implements WorkspaceResolverBuilderFactoryInterface
{
public static methodName = 'findMany' as const;
constructor(
private readonly workspaceQueryRunnerService: WorkspaceQueryRunnerService,
) {}
create(
context: WorkspaceSchemaBuilderContext,
): Resolver<FindManyResolverArgs> {
const internalContext = context;
return (_source, args, context, info) => {
return this.workspaceQueryRunnerService.findMany(args, {
objectMetadataItem: internalContext.objectMetadataItem,
workspaceId: internalContext.workspaceId,
userId: internalContext.userId,
info,
fieldMetadataCollection: internalContext.fieldMetadataCollection,
objectMetadataCollection: internalContext.objectMetadataCollection,
});
};
}
}

View File

@ -0,0 +1,38 @@
import { Injectable } from '@nestjs/common';
import {
FindOneResolverArgs,
Resolver,
} from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
import { WorkspaceSchemaBuilderContext } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-schema-builder-context.interface';
import { WorkspaceResolverBuilderFactoryInterface } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolver-builder-factory.interface';
import { WorkspaceQueryRunnerService } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-runner.service';
@Injectable()
export class FindOneResolverFactory
implements WorkspaceResolverBuilderFactoryInterface
{
public static methodName = 'findOne' as const;
constructor(
private readonly workspaceQueryRunnerService: WorkspaceQueryRunnerService,
) {}
create(
context: WorkspaceSchemaBuilderContext,
): Resolver<FindOneResolverArgs> {
const internalContext = context;
return (_source, args, context, info) => {
return this.workspaceQueryRunnerService.findOne(args, {
objectMetadataItem: internalContext.objectMetadataItem,
workspaceId: internalContext.workspaceId,
userId: internalContext.userId,
info,
fieldMetadataCollection: internalContext.fieldMetadataCollection,
objectMetadataCollection: internalContext.objectMetadataCollection,
});
};
}
}

View File

@ -0,0 +1,38 @@
import { Injectable } from '@nestjs/common';
import {
Resolver,
UpdateManyResolverArgs,
} from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
import { WorkspaceSchemaBuilderContext } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-schema-builder-context.interface';
import { WorkspaceResolverBuilderFactoryInterface } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolver-builder-factory.interface';
import { WorkspaceQueryRunnerService } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-runner.service';
@Injectable()
export class UpdateManyResolverFactory
implements WorkspaceResolverBuilderFactoryInterface
{
public static methodName = 'updateMany' as const;
constructor(
private readonly workspaceQueryRunnerService: WorkspaceQueryRunnerService,
) {}
create(
context: WorkspaceSchemaBuilderContext,
): Resolver<UpdateManyResolverArgs> {
const internalContext = context;
return (_source, args, context, info) => {
return this.workspaceQueryRunnerService.updateMany(args, {
objectMetadataItem: internalContext.objectMetadataItem,
workspaceId: internalContext.workspaceId,
userId: internalContext.userId,
info,
fieldMetadataCollection: internalContext.fieldMetadataCollection,
objectMetadataCollection: internalContext.objectMetadataCollection,
});
};
}
}

View File

@ -0,0 +1,38 @@
import { Injectable } from '@nestjs/common';
import {
Resolver,
UpdateOneResolverArgs,
} from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
import { WorkspaceSchemaBuilderContext } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-schema-builder-context.interface';
import { WorkspaceResolverBuilderFactoryInterface } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolver-builder-factory.interface';
import { WorkspaceQueryRunnerService } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-runner.service';
@Injectable()
export class UpdateOneResolverFactory
implements WorkspaceResolverBuilderFactoryInterface
{
public static methodName = 'updateOne' as const;
constructor(
private readonly workspaceQueryRunnerService: WorkspaceQueryRunnerService,
) {}
create(
context: WorkspaceSchemaBuilderContext,
): Resolver<UpdateOneResolverArgs> {
const internalContext = context;
return (_source, args, context, info) => {
return this.workspaceQueryRunnerService.updateOne(args, {
objectMetadataItem: internalContext.objectMetadataItem,
workspaceId: internalContext.workspaceId,
userId: internalContext.userId,
info,
fieldMetadataCollection: internalContext.fieldMetadataCollection,
objectMetadataCollection: internalContext.objectMetadataCollection,
});
};
}
}

View File

@ -0,0 +1,14 @@
import { Record as IRecord } from 'src/engine/api/graphql/workspace-query-builder/interfaces/record.interface';
export interface PGGraphQLResponse<Data = any> {
resolve: {
data: Data;
};
}
export type PGGraphQLResult<Data = any> = [PGGraphQLResponse<Data>];
export interface PGGraphQLMutation<Record = IRecord> {
affectedRows: number;
records: Record[];
}

View File

@ -0,0 +1,7 @@
import { WorkspaceSchemaBuilderContext } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-schema-builder-context.interface';
import { Resolver } from './workspace-resolvers-builder.interface';
export interface WorkspaceResolverBuilderFactoryInterface {
create(context: WorkspaceSchemaBuilderContext): Resolver;
}

View File

@ -0,0 +1,91 @@
import { GraphQLFieldResolver } from 'graphql';
import {
Record,
RecordFilter,
RecordOrderBy,
} from 'src/engine/api/graphql/workspace-query-builder/interfaces/record.interface';
import { workspaceResolverBuilderMethodNames } from 'src/engine/api/graphql/workspace-resolver-builder/factories/factories';
export type Resolver<Args = any> = GraphQLFieldResolver<any, any, Args>;
export interface FindManyResolverArgs<
Filter extends RecordFilter = RecordFilter,
OrderBy extends RecordOrderBy = RecordOrderBy,
> {
first?: number;
last?: number;
before?: string;
after?: string;
filter?: Filter;
orderBy?: OrderBy;
}
export interface FindOneResolverArgs<Filter = any> {
filter?: Filter;
}
export interface FindDuplicatesResolverArgs<Data extends Record = Record> {
id?: string;
data?: Data;
}
export interface CreateOneResolverArgs<Data extends Record = Record> {
data: Data;
}
export interface CreateManyResolverArgs<Data extends Record = Record> {
data: Data[];
}
export interface UpdateOneResolverArgs<Data extends Record = Record> {
id: string;
data: Data;
}
export interface UpdateManyResolverArgs<
Data extends Record = Record,
Filter = any,
> {
filter: Filter;
data: Data;
}
export interface DeleteOneResolverArgs {
id: string;
}
export interface ExecuteQuickActionOnOneResolverArgs {
id: string;
}
export interface DeleteManyResolverArgs<Filter = any> {
filter: Filter;
}
export type WorkspaceResolverBuilderQueryMethodNames =
(typeof workspaceResolverBuilderMethodNames.queries)[number];
export type WorkspaceResolverBuilderMutationMethodNames =
(typeof workspaceResolverBuilderMethodNames.mutations)[number];
export type WorkspaceResolverBuilderMethodNames =
| WorkspaceResolverBuilderQueryMethodNames
| WorkspaceResolverBuilderMutationMethodNames;
export interface WorkspaceResolverBuilderMethods {
readonly queries: readonly WorkspaceResolverBuilderQueryMethodNames[];
readonly mutations: readonly WorkspaceResolverBuilderMutationMethodNames[];
}
export type ResolverArgs =
| CreateManyResolverArgs
| CreateOneResolverArgs
| DeleteManyResolverArgs
| DeleteOneResolverArgs
| FindManyResolverArgs
| FindOneResolverArgs
| FindDuplicatesResolverArgs
| UpdateManyResolverArgs
| UpdateOneResolverArgs;

View File

@ -0,0 +1,15 @@
import { Module } from '@nestjs/common';
import { WorkspaceQueryRunnerModule } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-runner.module';
import { QuickActionsModule } from 'src/engine/modules/quick-actions/quick-actions.module';
import { WorkspaceResolverFactory } from './workspace-resolver.factory';
import { workspaceResolverBuilderFactories } from './factories/factories';
@Module({
imports: [WorkspaceQueryRunnerModule, QuickActionsModule],
providers: [...workspaceResolverBuilderFactories, WorkspaceResolverFactory],
exports: [WorkspaceResolverFactory],
})
export class WorkspaceResolverBuilderModule {}

View File

@ -0,0 +1,120 @@
import { Injectable, Logger } from '@nestjs/common';
import { IResolvers } from '@graphql-tools/utils';
import { ObjectMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/object-metadata.interface';
import { getResolverName } from 'src/engine/utils/get-resolver-name.util';
import { UpdateManyResolverFactory } from 'src/engine/api/graphql/workspace-resolver-builder/factories/update-many-resolver.factory';
import { DeleteManyResolverFactory } from 'src/engine/api/graphql/workspace-resolver-builder/factories/delete-many-resolver.factory';
import { ExecuteQuickActionOnOneResolverFactory } from 'src/engine/api/graphql/workspace-resolver-builder/factories/execute-quick-action-on-one-resolver.factory';
import { FindDuplicatesResolverFactory } from './factories/find-duplicates-resolver.factory';
import { FindManyResolverFactory } from './factories/find-many-resolver.factory';
import { FindOneResolverFactory } from './factories/find-one-resolver.factory';
import { CreateManyResolverFactory } from './factories/create-many-resolver.factory';
import { CreateOneResolverFactory } from './factories/create-one-resolver.factory';
import { UpdateOneResolverFactory } from './factories/update-one-resolver.factory';
import { DeleteOneResolverFactory } from './factories/delete-one-resolver.factory';
import {
WorkspaceResolverBuilderMethodNames,
WorkspaceResolverBuilderMethods,
} from './interfaces/workspace-resolvers-builder.interface';
import { WorkspaceResolverBuilderFactoryInterface } from './interfaces/workspace-resolver-builder-factory.interface';
@Injectable()
export class WorkspaceResolverFactory {
private readonly logger = new Logger(WorkspaceResolverFactory.name);
constructor(
private readonly findManyResolverFactory: FindManyResolverFactory,
private readonly findOneResolverFactory: FindOneResolverFactory,
private readonly findDuplicatesResolverFactory: FindDuplicatesResolverFactory,
private readonly createManyResolverFactory: CreateManyResolverFactory,
private readonly createOneResolverFactory: CreateOneResolverFactory,
private readonly updateOneResolverFactory: UpdateOneResolverFactory,
private readonly deleteOneResolverFactory: DeleteOneResolverFactory,
private readonly executeQuickActionOnOneResolverFactory: ExecuteQuickActionOnOneResolverFactory,
private readonly updateManyResolverFactory: UpdateManyResolverFactory,
private readonly deleteManyResolverFactory: DeleteManyResolverFactory,
) {}
async create(
workspaceId: string,
userId: string | undefined,
objectMetadataCollection: ObjectMetadataInterface[],
workspaceResolverBuilderMethods: WorkspaceResolverBuilderMethods,
): Promise<IResolvers> {
const factories = new Map<
WorkspaceResolverBuilderMethodNames,
WorkspaceResolverBuilderFactoryInterface
>([
['findMany', this.findManyResolverFactory],
['findOne', this.findOneResolverFactory],
['findDuplicates', this.findDuplicatesResolverFactory],
['createMany', this.createManyResolverFactory],
['createOne', this.createOneResolverFactory],
['updateOne', this.updateOneResolverFactory],
['deleteOne', this.deleteOneResolverFactory],
['executeQuickActionOnOne', this.executeQuickActionOnOneResolverFactory],
['updateMany', this.updateManyResolverFactory],
['deleteMany', this.deleteManyResolverFactory],
]);
const resolvers: IResolvers = {
Query: {},
Mutation: {},
};
for (const objectMetadata of objectMetadataCollection) {
// Generate query resolvers
for (const methodName of workspaceResolverBuilderMethods.queries) {
const resolverName = getResolverName(objectMetadata, methodName);
const resolverFactory = factories.get(methodName);
if (!resolverFactory) {
this.logger.error(`Unknown query resolver type: ${methodName}`, {
objectMetadata,
methodName,
resolverName,
});
throw new Error(`Unknown query resolver type: ${methodName}`);
}
resolvers.Query[resolverName] = resolverFactory.create({
workspaceId,
userId,
objectMetadataItem: objectMetadata,
fieldMetadataCollection: objectMetadata.fields,
objectMetadataCollection: objectMetadataCollection,
});
}
// Generate mutation resolvers
for (const methodName of workspaceResolverBuilderMethods.mutations) {
const resolverName = getResolverName(objectMetadata, methodName);
const resolverFactory = factories.get(methodName);
if (!resolverFactory) {
this.logger.error(`Unknown mutation resolver type: ${methodName}`, {
objectMetadata,
methodName,
resolverName,
});
throw new Error(`Unknown mutation resolver type: ${methodName}`);
}
resolvers.Mutation[resolverName] = resolverFactory.create({
workspaceId,
userId,
objectMetadataItem: objectMetadata,
fieldMetadataCollection: objectMetadata.fields,
objectMetadataCollection: objectMetadataCollection,
});
}
}
return resolvers;
}
}