mirror of
				https://github.com/lingble/twenty.git
				synced 2025-11-03 22:27:57 +00:00 
			
		
		
		
	feat: add missing updateMany and deleteMany resolvers on flexible backend (#2758)
* feat: add missing updateMany and deleteMany resolvers on flexible backend Co-authored-by: v1b3m <vibenjamin6@gmail.com> * Refactor according to review Co-authored-by: v1b3m <vibenjamin6@gmail.com> * Update return types for `createMany`, `updateMany` and `deleteMany` Co-authored-by: v1b3m <vibenjamin6@gmail.com> --------- Co-authored-by: gitstart-twenty <gitstart-twenty@users.noreply.github.com> Co-authored-by: v1b3m <vibenjamin6@gmail.com>
This commit is contained in:
		@@ -21,6 +21,10 @@ export const getResolverName = (
 | 
				
			|||||||
      return `update${pascalCase(objectMetadata.nameSingular)}`;
 | 
					      return `update${pascalCase(objectMetadata.nameSingular)}`;
 | 
				
			||||||
    case 'deleteOne':
 | 
					    case 'deleteOne':
 | 
				
			||||||
      return `delete${pascalCase(objectMetadata.nameSingular)}`;
 | 
					      return `delete${pascalCase(objectMetadata.nameSingular)}`;
 | 
				
			||||||
 | 
					    case 'updateMany':
 | 
				
			||||||
 | 
					      return `update${pascalCase(objectMetadata.namePlural)}`;
 | 
				
			||||||
 | 
					    case 'deleteMany':
 | 
				
			||||||
 | 
					      return `delete${pascalCase(objectMetadata.namePlural)}`;
 | 
				
			||||||
    default:
 | 
					    default:
 | 
				
			||||||
      throw new Error(`Unknown resolver type: ${type}`);
 | 
					      throw new Error(`Unknown resolver type: ${type}`);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -0,0 +1,33 @@
 | 
				
			|||||||
 | 
					import { Injectable } from '@nestjs/common';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { WorkspaceQueryBuilderOptions } from 'src/workspace/workspace-query-builder/interfaces/workspace-query-builder-options.interface';
 | 
				
			||||||
 | 
					import { DeleteManyResolverArgs } from 'src/workspace/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { stringifyWithoutKeyQuote } from 'src/workspace/workspace-query-builder/utils/stringify-without-key-quote.util';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { FieldsStringFactory } from './fields-string.factory';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@Injectable()
 | 
				
			||||||
 | 
					export class DeleteManyQueryFactory {
 | 
				
			||||||
 | 
					  constructor(private readonly fieldsStringFactory: FieldsStringFactory) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  create(args: DeleteManyResolverArgs, options: WorkspaceQueryBuilderOptions) {
 | 
				
			||||||
 | 
					    const fieldsString = this.fieldsStringFactory.create(
 | 
				
			||||||
 | 
					      options.info,
 | 
				
			||||||
 | 
					      options.fieldMetadataCollection,
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return `
 | 
				
			||||||
 | 
					      mutation {
 | 
				
			||||||
 | 
					        deleteFrom${
 | 
				
			||||||
 | 
					          options.targetTableName
 | 
				
			||||||
 | 
					        }Collection(filter: ${stringifyWithoutKeyQuote(args.filter)}) {
 | 
				
			||||||
 | 
					          affectedCount
 | 
				
			||||||
 | 
					          records {
 | 
				
			||||||
 | 
					            ${fieldsString}
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    `;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -8,6 +8,8 @@ import { FieldsStringFactory } from './fields-string.factory';
 | 
				
			|||||||
import { FindManyQueryFactory } from './find-many-query.factory';
 | 
					import { FindManyQueryFactory } from './find-many-query.factory';
 | 
				
			||||||
import { FindOneQueryFactory } from './find-one-query.factory';
 | 
					import { FindOneQueryFactory } from './find-one-query.factory';
 | 
				
			||||||
import { UpdateOneQueryFactory } from './update-one-query.factory';
 | 
					import { UpdateOneQueryFactory } from './update-one-query.factory';
 | 
				
			||||||
 | 
					import { UpdateManyQueryFactory } from './update-many-query.factory';
 | 
				
			||||||
 | 
					import { DeleteManyQueryFactory } from './delete-many-query.factory';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const workspaceQueryBuilderFactories = [
 | 
					export const workspaceQueryBuilderFactories = [
 | 
				
			||||||
  ArgsAliasFactory,
 | 
					  ArgsAliasFactory,
 | 
				
			||||||
@@ -20,4 +22,6 @@ export const workspaceQueryBuilderFactories = [
 | 
				
			|||||||
  FindManyQueryFactory,
 | 
					  FindManyQueryFactory,
 | 
				
			||||||
  FindOneQueryFactory,
 | 
					  FindOneQueryFactory,
 | 
				
			||||||
  UpdateOneQueryFactory,
 | 
					  UpdateOneQueryFactory,
 | 
				
			||||||
 | 
					  UpdateManyQueryFactory,
 | 
				
			||||||
 | 
					  DeleteManyQueryFactory,
 | 
				
			||||||
];
 | 
					];
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -0,0 +1,51 @@
 | 
				
			|||||||
 | 
					import { Injectable } from '@nestjs/common';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import {
 | 
				
			||||||
 | 
					  Record as IRecord,
 | 
				
			||||||
 | 
					  RecordFilter,
 | 
				
			||||||
 | 
					} from 'src/workspace/workspace-query-builder/interfaces/record.interface';
 | 
				
			||||||
 | 
					import { WorkspaceQueryBuilderOptions } from 'src/workspace/workspace-query-builder/interfaces/workspace-query-builder-options.interface';
 | 
				
			||||||
 | 
					import { UpdateManyResolverArgs } from 'src/workspace/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { stringifyWithoutKeyQuote } from 'src/workspace/workspace-query-builder/utils/stringify-without-key-quote.util';
 | 
				
			||||||
 | 
					import { FieldsStringFactory } from 'src/workspace/workspace-query-builder/factories/fields-string.factory';
 | 
				
			||||||
 | 
					import { ArgsAliasFactory } from 'src/workspace/workspace-query-builder/factories/args-alias.factory';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@Injectable()
 | 
				
			||||||
 | 
					export class UpdateManyQueryFactory {
 | 
				
			||||||
 | 
					  constructor(
 | 
				
			||||||
 | 
					    private readonly fieldsStringFactory: FieldsStringFactory,
 | 
				
			||||||
 | 
					    private readonly argsAliasFactory: ArgsAliasFactory,
 | 
				
			||||||
 | 
					  ) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  create<
 | 
				
			||||||
 | 
					    Record extends IRecord = IRecord,
 | 
				
			||||||
 | 
					    Filter extends RecordFilter = RecordFilter,
 | 
				
			||||||
 | 
					  >(
 | 
				
			||||||
 | 
					    args: UpdateManyResolverArgs<Record, Filter>,
 | 
				
			||||||
 | 
					    options: WorkspaceQueryBuilderOptions,
 | 
				
			||||||
 | 
					  ) {
 | 
				
			||||||
 | 
					    const fieldsString = this.fieldsStringFactory.create(
 | 
				
			||||||
 | 
					      options.info,
 | 
				
			||||||
 | 
					      options.fieldMetadataCollection,
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const computedArgs = this.argsAliasFactory.create(
 | 
				
			||||||
 | 
					      args,
 | 
				
			||||||
 | 
					      options.fieldMetadataCollection,
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return `
 | 
				
			||||||
 | 
					    mutation {
 | 
				
			||||||
 | 
					      update${options.targetTableName}Collection(
 | 
				
			||||||
 | 
					        set: ${stringifyWithoutKeyQuote(computedArgs.data)},
 | 
				
			||||||
 | 
					        filter: ${stringifyWithoutKeyQuote(args.filter)},
 | 
				
			||||||
 | 
					      ) {
 | 
				
			||||||
 | 
					        affectedCount
 | 
				
			||||||
 | 
					        records {
 | 
				
			||||||
 | 
					          ${fieldsString}
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }`;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -12,6 +12,8 @@ import {
 | 
				
			|||||||
  CreateManyResolverArgs,
 | 
					  CreateManyResolverArgs,
 | 
				
			||||||
  UpdateOneResolverArgs,
 | 
					  UpdateOneResolverArgs,
 | 
				
			||||||
  DeleteOneResolverArgs,
 | 
					  DeleteOneResolverArgs,
 | 
				
			||||||
 | 
					  UpdateManyResolverArgs,
 | 
				
			||||||
 | 
					  DeleteManyResolverArgs,
 | 
				
			||||||
} from 'src/workspace/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
 | 
					} from 'src/workspace/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { FindManyQueryFactory } from './factories/find-many-query.factory';
 | 
					import { FindManyQueryFactory } from './factories/find-many-query.factory';
 | 
				
			||||||
@@ -19,6 +21,8 @@ import { FindOneQueryFactory } from './factories/find-one-query.factory';
 | 
				
			|||||||
import { CreateManyQueryFactory } from './factories/create-many-query.factory';
 | 
					import { CreateManyQueryFactory } from './factories/create-many-query.factory';
 | 
				
			||||||
import { UpdateOneQueryFactory } from './factories/update-one-query.factory';
 | 
					import { UpdateOneQueryFactory } from './factories/update-one-query.factory';
 | 
				
			||||||
import { DeleteOneQueryFactory } from './factories/delete-one-query.factory';
 | 
					import { DeleteOneQueryFactory } from './factories/delete-one-query.factory';
 | 
				
			||||||
 | 
					import { UpdateManyQueryFactory } from './factories/update-many-query.factory';
 | 
				
			||||||
 | 
					import { DeleteManyQueryFactory } from './factories/delete-many-query.factory';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@Injectable()
 | 
					@Injectable()
 | 
				
			||||||
export class WorkspaceQueryBuilderFactory {
 | 
					export class WorkspaceQueryBuilderFactory {
 | 
				
			||||||
@@ -30,6 +34,8 @@ export class WorkspaceQueryBuilderFactory {
 | 
				
			|||||||
    private readonly createManyQueryFactory: CreateManyQueryFactory,
 | 
					    private readonly createManyQueryFactory: CreateManyQueryFactory,
 | 
				
			||||||
    private readonly updateOneQueryFactory: UpdateOneQueryFactory,
 | 
					    private readonly updateOneQueryFactory: UpdateOneQueryFactory,
 | 
				
			||||||
    private readonly deleteOneQueryFactory: DeleteOneQueryFactory,
 | 
					    private readonly deleteOneQueryFactory: DeleteOneQueryFactory,
 | 
				
			||||||
 | 
					    private readonly updateManyQueryFactory: UpdateManyQueryFactory,
 | 
				
			||||||
 | 
					    private readonly deleteManyQueryFactory: DeleteManyQueryFactory,
 | 
				
			||||||
  ) {}
 | 
					  ) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  findMany<
 | 
					  findMany<
 | 
				
			||||||
@@ -69,4 +75,21 @@ export class WorkspaceQueryBuilderFactory {
 | 
				
			|||||||
  ): string {
 | 
					  ): string {
 | 
				
			||||||
    return this.deleteOneQueryFactory.create(args, options);
 | 
					    return this.deleteOneQueryFactory.create(args, options);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  updateMany<
 | 
				
			||||||
 | 
					    Record extends IRecord = IRecord,
 | 
				
			||||||
 | 
					    Filter extends RecordFilter = RecordFilter,
 | 
				
			||||||
 | 
					  >(
 | 
				
			||||||
 | 
					    args: UpdateManyResolverArgs<Record, Filter>,
 | 
				
			||||||
 | 
					    options: WorkspaceQueryBuilderOptions,
 | 
				
			||||||
 | 
					  ): string {
 | 
				
			||||||
 | 
					    return this.updateManyQueryFactory.create(args, options);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  deleteMany<Filter extends RecordFilter = RecordFilter>(
 | 
				
			||||||
 | 
					    args: DeleteManyResolverArgs<Filter>,
 | 
				
			||||||
 | 
					    options: WorkspaceQueryBuilderOptions,
 | 
				
			||||||
 | 
					  ): string {
 | 
				
			||||||
 | 
					    return this.deleteManyQueryFactory.create(args, options);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,9 +9,11 @@ import {
 | 
				
			|||||||
import {
 | 
					import {
 | 
				
			||||||
  CreateManyResolverArgs,
 | 
					  CreateManyResolverArgs,
 | 
				
			||||||
  CreateOneResolverArgs,
 | 
					  CreateOneResolverArgs,
 | 
				
			||||||
 | 
					  DeleteManyResolverArgs,
 | 
				
			||||||
  DeleteOneResolverArgs,
 | 
					  DeleteOneResolverArgs,
 | 
				
			||||||
  FindManyResolverArgs,
 | 
					  FindManyResolverArgs,
 | 
				
			||||||
  FindOneResolverArgs,
 | 
					  FindOneResolverArgs,
 | 
				
			||||||
 | 
					  UpdateManyResolverArgs,
 | 
				
			||||||
  UpdateOneResolverArgs,
 | 
					  UpdateOneResolverArgs,
 | 
				
			||||||
} from 'src/workspace/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
 | 
					} from 'src/workspace/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -127,6 +129,43 @@ export class WorkspaceQueryRunnerService {
 | 
				
			|||||||
    )?.records?.[0];
 | 
					    )?.records?.[0];
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  async updateMany<Record extends IRecord = IRecord>(
 | 
				
			||||||
 | 
					    args: UpdateManyResolverArgs<Record>,
 | 
				
			||||||
 | 
					    options: WorkspaceQueryRunnerOptions,
 | 
				
			||||||
 | 
					  ): Promise<Record[] | undefined> {
 | 
				
			||||||
 | 
					    const { workspaceId, targetTableName } = options;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const query = this.workspaceQueryBuilderFactory.updateMany(args, options);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const result = await this.execute(query, workspaceId);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return this.parseResult<PGGraphQLMutation<Record>>(
 | 
				
			||||||
 | 
					      result,
 | 
				
			||||||
 | 
					      targetTableName,
 | 
				
			||||||
 | 
					      'update',
 | 
				
			||||||
 | 
					    )?.records;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  async deleteMany<
 | 
				
			||||||
 | 
					    Record extends IRecord = IRecord,
 | 
				
			||||||
 | 
					    Filter extends RecordFilter = RecordFilter,
 | 
				
			||||||
 | 
					  >(
 | 
				
			||||||
 | 
					    args: DeleteManyResolverArgs<Filter>,
 | 
				
			||||||
 | 
					    options: WorkspaceQueryRunnerOptions,
 | 
				
			||||||
 | 
					  ): Promise<Record[] | undefined> {
 | 
				
			||||||
 | 
					    const { workspaceId, targetTableName } = options;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const query = this.workspaceQueryBuilderFactory.deleteMany(args, options);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const result = await this.execute(query, workspaceId);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return this.parseResult<PGGraphQLMutation<Record>>(
 | 
				
			||||||
 | 
					      result,
 | 
				
			||||||
 | 
					      targetTableName,
 | 
				
			||||||
 | 
					      'deleteFrom',
 | 
				
			||||||
 | 
					    )?.records;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private async execute(
 | 
					  private async execute(
 | 
				
			||||||
    query: string,
 | 
					    query: string,
 | 
				
			||||||
    workspaceId: string,
 | 
					    workspaceId: string,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -0,0 +1,36 @@
 | 
				
			|||||||
 | 
					import { Injectable } from '@nestjs/common';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import {
 | 
				
			||||||
 | 
					  DeleteManyResolverArgs,
 | 
				
			||||||
 | 
					  Resolver,
 | 
				
			||||||
 | 
					} from 'src/workspace/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
 | 
				
			||||||
 | 
					import { WorkspaceSchemaBuilderContext } from 'src/workspace/workspace-schema-builder/interfaces/workspace-schema-builder-context.interface';
 | 
				
			||||||
 | 
					import { WorkspaceResolverBuilderFactoryInterface } from 'src/workspace/workspace-resolver-builder/interfaces/workspace-resolver-builder-factory.interface';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { WorkspaceQueryRunnerService } from 'src/workspace/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, {
 | 
				
			||||||
 | 
					        targetTableName: internalContext.targetTableName,
 | 
				
			||||||
 | 
					        workspaceId: internalContext.workspaceId,
 | 
				
			||||||
 | 
					        info,
 | 
				
			||||||
 | 
					        fieldMetadataCollection: internalContext.fieldMetadataCollection,
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -1,9 +1,12 @@
 | 
				
			|||||||
 | 
					import { UpdateManyResolverFactory } from 'src/workspace/workspace-resolver-builder/factories/update-many-resolver.factory';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { FindManyResolverFactory } from './find-many-resolver.factory';
 | 
					import { FindManyResolverFactory } from './find-many-resolver.factory';
 | 
				
			||||||
import { FindOneResolverFactory } from './find-one-resolver.factory';
 | 
					import { FindOneResolverFactory } from './find-one-resolver.factory';
 | 
				
			||||||
import { CreateManyResolverFactory } from './create-many-resolver.factory';
 | 
					import { CreateManyResolverFactory } from './create-many-resolver.factory';
 | 
				
			||||||
import { CreateOneResolverFactory } from './create-one-resolver.factory';
 | 
					import { CreateOneResolverFactory } from './create-one-resolver.factory';
 | 
				
			||||||
import { UpdateOneResolverFactory } from './update-one-resolver.factory';
 | 
					import { UpdateOneResolverFactory } from './update-one-resolver.factory';
 | 
				
			||||||
import { DeleteOneResolverFactory } from './delete-one-resolver.factory';
 | 
					import { DeleteOneResolverFactory } from './delete-one-resolver.factory';
 | 
				
			||||||
 | 
					import { DeleteManyResolverFactory } from './delete-many-resolver.factory';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const workspaceResolverBuilderFactories = [
 | 
					export const workspaceResolverBuilderFactories = [
 | 
				
			||||||
  FindManyResolverFactory,
 | 
					  FindManyResolverFactory,
 | 
				
			||||||
@@ -12,6 +15,8 @@ export const workspaceResolverBuilderFactories = [
 | 
				
			|||||||
  CreateOneResolverFactory,
 | 
					  CreateOneResolverFactory,
 | 
				
			||||||
  UpdateOneResolverFactory,
 | 
					  UpdateOneResolverFactory,
 | 
				
			||||||
  DeleteOneResolverFactory,
 | 
					  DeleteOneResolverFactory,
 | 
				
			||||||
 | 
					  UpdateManyResolverFactory,
 | 
				
			||||||
 | 
					  DeleteManyResolverFactory,
 | 
				
			||||||
];
 | 
					];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const workspaceResolverBuilderMethodNames = {
 | 
					export const workspaceResolverBuilderMethodNames = {
 | 
				
			||||||
@@ -24,5 +29,7 @@ export const workspaceResolverBuilderMethodNames = {
 | 
				
			|||||||
    CreateOneResolverFactory.methodName,
 | 
					    CreateOneResolverFactory.methodName,
 | 
				
			||||||
    UpdateOneResolverFactory.methodName,
 | 
					    UpdateOneResolverFactory.methodName,
 | 
				
			||||||
    DeleteOneResolverFactory.methodName,
 | 
					    DeleteOneResolverFactory.methodName,
 | 
				
			||||||
 | 
					    UpdateManyResolverFactory.methodName,
 | 
				
			||||||
 | 
					    DeleteManyResolverFactory.methodName,
 | 
				
			||||||
  ],
 | 
					  ],
 | 
				
			||||||
} as const;
 | 
					} as const;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -0,0 +1,36 @@
 | 
				
			|||||||
 | 
					import { Injectable } from '@nestjs/common';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import {
 | 
				
			||||||
 | 
					  Resolver,
 | 
				
			||||||
 | 
					  UpdateManyResolverArgs,
 | 
				
			||||||
 | 
					} from 'src/workspace/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
 | 
				
			||||||
 | 
					import { WorkspaceSchemaBuilderContext } from 'src/workspace/workspace-schema-builder/interfaces/workspace-schema-builder-context.interface';
 | 
				
			||||||
 | 
					import { WorkspaceResolverBuilderFactoryInterface } from 'src/workspace/workspace-resolver-builder/interfaces/workspace-resolver-builder-factory.interface';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { WorkspaceQueryRunnerService } from 'src/workspace/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, {
 | 
				
			||||||
 | 
					        targetTableName: internalContext.targetTableName,
 | 
				
			||||||
 | 
					        workspaceId: internalContext.workspaceId,
 | 
				
			||||||
 | 
					        info,
 | 
				
			||||||
 | 
					        fieldMetadataCollection: internalContext.fieldMetadataCollection,
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -39,10 +39,22 @@ export interface UpdateOneResolverArgs<Data extends Record = Record> {
 | 
				
			|||||||
  data: Data;
 | 
					  data: Data;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export interface UpdateManyResolverArgs<
 | 
				
			||||||
 | 
					  Data extends Record = Record,
 | 
				
			||||||
 | 
					  Filter = any,
 | 
				
			||||||
 | 
					> {
 | 
				
			||||||
 | 
					  filter: Filter;
 | 
				
			||||||
 | 
					  data: Data;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export interface DeleteOneResolverArgs {
 | 
					export interface DeleteOneResolverArgs {
 | 
				
			||||||
  id: string;
 | 
					  id: string;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export interface DeleteManyResolverArgs<Filter = any> {
 | 
				
			||||||
 | 
					  filter: Filter;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export type WorkspaceResolverBuilderQueryMethodNames =
 | 
					export type WorkspaceResolverBuilderQueryMethodNames =
 | 
				
			||||||
  (typeof workspaceResolverBuilderMethodNames.queries)[number];
 | 
					  (typeof workspaceResolverBuilderMethodNames.queries)[number];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,6 +5,8 @@ import { IResolvers } from '@graphql-tools/utils';
 | 
				
			|||||||
import { ObjectMetadataInterface } from 'src/workspace/workspace-schema-builder/interfaces/object-metadata.interface';
 | 
					import { ObjectMetadataInterface } from 'src/workspace/workspace-schema-builder/interfaces/object-metadata.interface';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { getResolverName } from 'src/workspace/utils/get-resolver-name.util';
 | 
					import { getResolverName } from 'src/workspace/utils/get-resolver-name.util';
 | 
				
			||||||
 | 
					import { UpdateManyResolverFactory } from 'src/workspace/workspace-resolver-builder/factories/update-many-resolver.factory';
 | 
				
			||||||
 | 
					import { DeleteManyResolverFactory } from 'src/workspace/workspace-resolver-builder/factories/delete-many-resolver.factory';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { FindManyResolverFactory } from './factories/find-many-resolver.factory';
 | 
					import { FindManyResolverFactory } from './factories/find-many-resolver.factory';
 | 
				
			||||||
import { FindOneResolverFactory } from './factories/find-one-resolver.factory';
 | 
					import { FindOneResolverFactory } from './factories/find-one-resolver.factory';
 | 
				
			||||||
@@ -29,6 +31,8 @@ export class WorkspaceResolverFactory {
 | 
				
			|||||||
    private readonly createOneResolverFactory: CreateOneResolverFactory,
 | 
					    private readonly createOneResolverFactory: CreateOneResolverFactory,
 | 
				
			||||||
    private readonly updateOneResolverFactory: UpdateOneResolverFactory,
 | 
					    private readonly updateOneResolverFactory: UpdateOneResolverFactory,
 | 
				
			||||||
    private readonly deleteOneResolverFactory: DeleteOneResolverFactory,
 | 
					    private readonly deleteOneResolverFactory: DeleteOneResolverFactory,
 | 
				
			||||||
 | 
					    private readonly updateManyResolverFactory: UpdateManyResolverFactory,
 | 
				
			||||||
 | 
					    private readonly deleteManyResolverFactory: DeleteManyResolverFactory,
 | 
				
			||||||
  ) {}
 | 
					  ) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  async create(
 | 
					  async create(
 | 
				
			||||||
@@ -46,6 +50,8 @@ export class WorkspaceResolverFactory {
 | 
				
			|||||||
      ['createOne', this.createOneResolverFactory],
 | 
					      ['createOne', this.createOneResolverFactory],
 | 
				
			||||||
      ['updateOne', this.updateOneResolverFactory],
 | 
					      ['updateOne', this.updateOneResolverFactory],
 | 
				
			||||||
      ['deleteOne', this.deleteOneResolverFactory],
 | 
					      ['deleteOne', this.deleteOneResolverFactory],
 | 
				
			||||||
 | 
					      ['updateMany', this.updateManyResolverFactory],
 | 
				
			||||||
 | 
					      ['deleteMany', this.deleteManyResolverFactory],
 | 
				
			||||||
    ]);
 | 
					    ]);
 | 
				
			||||||
    const resolvers: IResolvers = {
 | 
					    const resolvers: IResolvers = {
 | 
				
			||||||
      Query: {},
 | 
					      Query: {},
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,6 +9,7 @@ import { ObjectMetadataInterface } from 'src/workspace/workspace-schema-builder/
 | 
				
			|||||||
import { TypeDefinitionsStorage } from 'src/workspace/workspace-schema-builder/storages/type-definitions.storage';
 | 
					import { TypeDefinitionsStorage } from 'src/workspace/workspace-schema-builder/storages/type-definitions.storage';
 | 
				
			||||||
import { getResolverName } from 'src/workspace/utils/get-resolver-name.util';
 | 
					import { getResolverName } from 'src/workspace/utils/get-resolver-name.util';
 | 
				
			||||||
import { getResolverArgs } from 'src/workspace/workspace-schema-builder/utils/get-resolver-args.util';
 | 
					import { getResolverArgs } from 'src/workspace/workspace-schema-builder/utils/get-resolver-args.util';
 | 
				
			||||||
 | 
					import { TypeMapperService } from 'src/workspace/workspace-schema-builder/services/type-mapper.service';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { ArgsFactory } from './args.factory';
 | 
					import { ArgsFactory } from './args.factory';
 | 
				
			||||||
import { ObjectTypeDefinitionKind } from './object-type-definition.factory';
 | 
					import { ObjectTypeDefinitionKind } from './object-type-definition.factory';
 | 
				
			||||||
@@ -25,6 +26,7 @@ export class RootTypeFactory {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  constructor(
 | 
					  constructor(
 | 
				
			||||||
    private readonly typeDefinitionsStorage: TypeDefinitionsStorage,
 | 
					    private readonly typeDefinitionsStorage: TypeDefinitionsStorage,
 | 
				
			||||||
 | 
					    private readonly typeMapperService: TypeMapperService,
 | 
				
			||||||
    private readonly argsFactory: ArgsFactory,
 | 
					    private readonly argsFactory: ArgsFactory,
 | 
				
			||||||
  ) {}
 | 
					  ) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -70,7 +72,7 @@ export class RootTypeFactory {
 | 
				
			|||||||
      for (const methodName of workspaceResolverMethodNames) {
 | 
					      for (const methodName of workspaceResolverMethodNames) {
 | 
				
			||||||
        const name = getResolverName(objectMetadata, methodName);
 | 
					        const name = getResolverName(objectMetadata, methodName);
 | 
				
			||||||
        const args = getResolverArgs(methodName);
 | 
					        const args = getResolverArgs(methodName);
 | 
				
			||||||
        const outputType = this.typeDefinitionsStorage.getObjectTypeByKey(
 | 
					        const objectType = this.typeDefinitionsStorage.getObjectTypeByKey(
 | 
				
			||||||
          objectMetadata.id,
 | 
					          objectMetadata.id,
 | 
				
			||||||
          methodName === 'findMany'
 | 
					          methodName === 'findMany'
 | 
				
			||||||
            ? ObjectTypeDefinitionKind.Connection
 | 
					            ? ObjectTypeDefinitionKind.Connection
 | 
				
			||||||
@@ -84,7 +86,7 @@ export class RootTypeFactory {
 | 
				
			|||||||
          options,
 | 
					          options,
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (!outputType) {
 | 
					        if (!objectType) {
 | 
				
			||||||
          this.logger.error(
 | 
					          this.logger.error(
 | 
				
			||||||
            `Could not find a GraphQL type for ${objectMetadata.id} for method ${methodName}`,
 | 
					            `Could not find a GraphQL type for ${objectMetadata.id} for method ${methodName}`,
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
@@ -99,6 +101,12 @@ export class RootTypeFactory {
 | 
				
			|||||||
          );
 | 
					          );
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const outputType = this.typeMapperService.mapToGqlType(objectType, {
 | 
				
			||||||
 | 
					          isArray: ['updateMany', 'deleteMany', 'createMany'].includes(
 | 
				
			||||||
 | 
					            methodName,
 | 
				
			||||||
 | 
					          ),
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        fieldConfigMap[name] = {
 | 
					        fieldConfigMap[name] = {
 | 
				
			||||||
          type: outputType,
 | 
					          type: outputType,
 | 
				
			||||||
          args: argsType,
 | 
					          args: argsType,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -36,6 +36,7 @@ export const getResolverArgs = (
 | 
				
			|||||||
        },
 | 
					        },
 | 
				
			||||||
      };
 | 
					      };
 | 
				
			||||||
    case 'findOne':
 | 
					    case 'findOne':
 | 
				
			||||||
 | 
					    case 'deleteMany':
 | 
				
			||||||
      return {
 | 
					      return {
 | 
				
			||||||
        filter: {
 | 
					        filter: {
 | 
				
			||||||
          kind: InputTypeDefinitionKind.Filter,
 | 
					          kind: InputTypeDefinitionKind.Filter,
 | 
				
			||||||
@@ -75,6 +76,17 @@ export const getResolverArgs = (
 | 
				
			|||||||
          isNullable: false,
 | 
					          isNullable: false,
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
      };
 | 
					      };
 | 
				
			||||||
 | 
					    case 'updateMany':
 | 
				
			||||||
 | 
					      return {
 | 
				
			||||||
 | 
					        data: {
 | 
				
			||||||
 | 
					          kind: InputTypeDefinitionKind.Update,
 | 
				
			||||||
 | 
					          isNullable: false,
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        filter: {
 | 
				
			||||||
 | 
					          kind: InputTypeDefinitionKind.Filter,
 | 
				
			||||||
 | 
					          isNullable: false,
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
    default:
 | 
					    default:
 | 
				
			||||||
      throw new Error(`Unknown resolver type: ${type}`);
 | 
					      throw new Error(`Unknown resolver type: ${type}`);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user