From 5a56322d2dd095f3f766c9cab399c39dd0026dc3 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Mon, 25 Oct 2021 15:53:16 +0000 Subject: [PATCH 1/5] chore(deps): update dependency @types/node to v14.17.30 --- examples/package.json | 2 +- package-lock.json | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/package.json b/examples/package.json index a0468bc76..5d95d5de8 100644 --- a/examples/package.json +++ b/examples/package.json @@ -56,7 +56,7 @@ "@nestjs/schematics": "8.0.4", "@nestjs/testing": "8.1.2", "@types/express": "4.17.13", - "@types/node": "14.17.29", + "@types/node": "14.17.30", "@types/passport-jwt": "3.0.6", "@types/passport-local": "1.0.34", "@types/supertest": "2.0.11", diff --git a/package-lock.json b/package-lock.json index a7815d724..18fc86506 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5722,9 +5722,9 @@ } }, "@types/node": { - "version": "14.17.29", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.29.tgz", - "integrity": "sha512-sd4CHI9eTJXTH2vF3RGtGkqvWRwhsSSUFsXD4oG38GZzSZ0tNPbWikd2AbOAcKxCXhOg57fL8FPxjpfSzb2pIQ==" + "version": "14.17.30", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.30.tgz", + "integrity": "sha512-ohVRXKKN5ulqN6fjuWWwh9X4szcHQQjy/sSeH//v442jfzvrXZPUfiCo/odWDU11XMZLB3dyUNIt6HBBBVvSlg==" }, "@types/node-fetch": { "version": "2.5.12", From 0836529e53ee3468ac1ad384cccf0082d9107155 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Mon, 25 Oct 2021 18:31:16 +0000 Subject: [PATCH 2/5] chore(deps): update dependency @types/node to v14.17.31 --- examples/package.json | 2 +- package-lock.json | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/package.json b/examples/package.json index 5d95d5de8..00bad3bc3 100644 --- a/examples/package.json +++ b/examples/package.json @@ -56,7 +56,7 @@ "@nestjs/schematics": "8.0.4", "@nestjs/testing": "8.1.2", "@types/express": "4.17.13", - "@types/node": "14.17.30", + "@types/node": "14.17.31", "@types/passport-jwt": "3.0.6", "@types/passport-local": "1.0.34", "@types/supertest": "2.0.11", diff --git a/package-lock.json b/package-lock.json index 18fc86506..8587643a0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5722,9 +5722,9 @@ } }, "@types/node": { - "version": "14.17.30", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.30.tgz", - "integrity": "sha512-ohVRXKKN5ulqN6fjuWWwh9X4szcHQQjy/sSeH//v442jfzvrXZPUfiCo/odWDU11XMZLB3dyUNIt6HBBBVvSlg==" + "version": "14.17.31", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.31.tgz", + "integrity": "sha512-MUeD1RfIycvO6Msfdl4vzfce7r0FWimF8QFdY1XslfHMFYmUvcZDPkaYrqdVLOi9pugnO4ASHyThb2K4hbjxMA==" }, "@types/node-fetch": { "version": "2.5.12", From 4c8b6de974da9ba439726cb7eb61ac85442f94bc Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Tue, 26 Oct 2021 01:50:28 +0000 Subject: [PATCH 3/5] chore(deps): update dependency @types/node to v14.17.32 --- examples/package.json | 2 +- package-lock.json | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/package.json b/examples/package.json index 00bad3bc3..024d0b14c 100644 --- a/examples/package.json +++ b/examples/package.json @@ -56,7 +56,7 @@ "@nestjs/schematics": "8.0.4", "@nestjs/testing": "8.1.2", "@types/express": "4.17.13", - "@types/node": "14.17.31", + "@types/node": "14.17.32", "@types/passport-jwt": "3.0.6", "@types/passport-local": "1.0.34", "@types/supertest": "2.0.11", diff --git a/package-lock.json b/package-lock.json index 8587643a0..b355d3842 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5722,9 +5722,9 @@ } }, "@types/node": { - "version": "14.17.31", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.31.tgz", - "integrity": "sha512-MUeD1RfIycvO6Msfdl4vzfce7r0FWimF8QFdY1XslfHMFYmUvcZDPkaYrqdVLOi9pugnO4ASHyThb2K4hbjxMA==" + "version": "14.17.32", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.32.tgz", + "integrity": "sha512-JcII3D5/OapPGx+eJ+Ik1SQGyt6WvuqdRfh9jUwL6/iHGjmyOriBDciBUu7lEIBTL2ijxwrR70WUnw5AEDmFvQ==" }, "@types/node-fetch": { "version": "2.5.12", From 8df925e556b9cb4178128c0038e179bd153d2605 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Wed, 27 Oct 2021 17:49:46 +0000 Subject: [PATCH 4/5] chore(deps): update dependency graphql to v15.7.1 --- examples/package.json | 2 +- package-lock.json | 58 ++++++++++++++--------------- packages/query-graphql/package.json | 2 +- 3 files changed, 31 insertions(+), 31 deletions(-) diff --git a/examples/package.json b/examples/package.json index 024d0b14c..13076dc78 100644 --- a/examples/package.json +++ b/examples/package.json @@ -34,7 +34,7 @@ "apollo-server-plugin-base": "3.3.0", "apollo-server-types": "3.3.0", "class-validator": "0.13.1", - "graphql": "15.6.1", + "graphql": "15.7.1", "graphql-query-complexity": "0.9.0", "graphql-tools": "8.2.0", "mongoose": "5.12.0", diff --git a/package-lock.json b/package-lock.json index b355d3842..bfbed8e79 100644 --- a/package-lock.json +++ b/package-lock.json @@ -458,9 +458,9 @@ } }, "@apollographql/apollo-tools": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/@apollographql/apollo-tools/-/apollo-tools-0.5.1.tgz", - "integrity": "sha512-ZII+/xUFfb9ezDU2gad114+zScxVFMVlZ91f8fGApMzlS1kkqoyLnC4AJaQ1Ya/X+b63I20B4Gd+eCL8QuB4sA==" + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/@apollographql/apollo-tools/-/apollo-tools-0.5.2.tgz", + "integrity": "sha512-KxZiw0Us3k1d0YkJDhOpVH5rJ+mBfjXcgoRoCcslbgirjgLotKMzOcx4PZ7YTEvvEROmvG7X3Aon41GvMmyGsw==" }, "@apollographql/graphql-playground-html": { "version": "1.6.29", @@ -1490,21 +1490,21 @@ } }, "@graphql-tools/merge": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/@graphql-tools/merge/-/merge-8.2.0.tgz", - "integrity": "sha512-nfMLYF7zczjnIbChZtqbvozRfuRweMD1Fe9HHd4RXd3Tcsj6E17srW0QJfxUoIIWh4pitj+XwZAwhj1PWBDU7g==", + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/merge/-/merge-8.2.1.tgz", + "integrity": "sha512-Q240kcUszhXiAYudjuJgNuLgy9CryDP3wp83NOZQezfA6h3ByYKU7xI6DiKrdjyVaGpYN3ppUmdj0uf5GaXzMA==", "requires": { - "@graphql-tools/utils": "^8.4.0", + "@graphql-tools/utils": "^8.5.1", "tslib": "~2.3.0" } }, "@graphql-tools/mock": { - "version": "8.4.1", - "resolved": "https://registry.npmjs.org/@graphql-tools/mock/-/mock-8.4.1.tgz", - "integrity": "sha512-eIW2H1k9b4Sczzy1Za+GdaKBc8lTXo8MbJH4oivh1AoGl6/Tu9jTOOTS/b07zQzG+6sIQG54o9W6s2TqDmD+YQ==", + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/@graphql-tools/mock/-/mock-8.4.2.tgz", + "integrity": "sha512-2v4v99mWUB1by+6Bk01PoJCUVnYoNSOT0E5VvFRf5oMwJPaRKLAbC+IjZaRoen1tWpVrg+3Coub7co8jyhvm/Q==", "requires": { - "@graphql-tools/schema": "^8.2.0", - "@graphql-tools/utils": "^8.2.3", + "@graphql-tools/schema": "^8.3.1", + "@graphql-tools/utils": "^8.5.1", "fast-json-stable-stringify": "^2.1.0", "tslib": "~2.3.0" }, @@ -1517,20 +1517,20 @@ } }, "@graphql-tools/schema": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/@graphql-tools/schema/-/schema-8.3.0.tgz", - "integrity": "sha512-OJD4Q1Xa3sffRiHzy0sskZz9ZWeqaujINfoim4CTk5Y9es1LS+WnKi25wVhmL2SGzzmKuAv7oDn+dpQAlM+Gfw==", + "version": "8.3.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/schema/-/schema-8.3.1.tgz", + "integrity": "sha512-3R0AJFe715p4GwF067G5i0KCr/XIdvSfDLvTLEiTDQ8V/hwbOHEKHKWlEBHGRQwkG5lwFQlW1aOn7VnlPERnWQ==", "requires": { - "@graphql-tools/merge": "^8.2.0", - "@graphql-tools/utils": "^8.4.0", + "@graphql-tools/merge": "^8.2.1", + "@graphql-tools/utils": "^8.5.1", "tslib": "~2.3.0", "value-or-promise": "1.0.11" } }, "@graphql-tools/utils": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-8.5.0.tgz", - "integrity": "sha512-jMwLm6YdN+Vbqntg5GHqDvGLpLa/xPSpRs/c40d0rBuel77wo7AaQ8jHeBSpp9y+7kp7HrGSWff1u7yJ7F8ppw==", + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-8.5.1.tgz", + "integrity": "sha512-V/OQVpj+Z05qW9ZdlJWSKzREYlgGEq+juV+pUy3JO9jI+sZo/W3oncuW9+1awwp/RkL0aZ9RgjL+XYOgCsmOLw==", "requires": { "tslib": "~2.3.0" } @@ -6571,9 +6571,9 @@ } }, "apollo-graphql": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/apollo-graphql/-/apollo-graphql-0.9.3.tgz", - "integrity": "sha512-rcAl2E841Iko4kSzj4Pt3PRBitmyq1MvoEmpl04TQSpGnoVgl1E/ZXuLBYxMTSnEAm7umn2IsoY+c6Ll9U/10A==", + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/apollo-graphql/-/apollo-graphql-0.9.4.tgz", + "integrity": "sha512-0X2sZxfmn7lJrRknUPBG+L0LP1B0SKX1qtULIWrDbIpyl9LuSyjnDaGtmvc4IQtyKvmQXtAhEHBnprRokkjkyw==", "requires": { "core-js-pure": "^3.10.2", "lodash.sortby": "^4.7.0", @@ -12349,9 +12349,9 @@ "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==" }, "graphql": { - "version": "15.6.1", - "resolved": "https://registry.npmjs.org/graphql/-/graphql-15.6.1.tgz", - "integrity": "sha512-3i5lu0z6dRvJ48QP9kFxBkJ7h4Kso7PS8eahyTFz5Jm6CvQfLtNIE8LX9N6JLnXTuwR+sIYnXzaWp6anOg0QQw==" + "version": "15.7.1", + "resolved": "https://registry.npmjs.org/graphql/-/graphql-15.7.1.tgz", + "integrity": "sha512-x34S6gC0/peBZnlK60zCJox/d45A7p6At9oN9EPA3qhoIAlR4LNZmXRLkICBckwwTMJzVdA8cx3QIQZMOl606A==" }, "graphql-fields": { "version": "2.0.3", @@ -17169,9 +17169,9 @@ } }, "libphonenumber-js": { - "version": "1.9.38", - "resolved": "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.9.38.tgz", - "integrity": "sha512-7CCl9NZPYtX4JNXdvV5RnrQqrXp7LsLOTpYSUfEJBiySEnC5hysdwouXAuWgPDB55D/fpKm4RjM2/tUUh8kuoA==" + "version": "1.9.39", + "resolved": "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.9.39.tgz", + "integrity": "sha512-TxYz/Ii7mjkocKGKmFHhsTAvvcxr4AY3yUlZzZ2z7HC4DPRrNlzJ9n32/SMogqsyFOXLMXQPCkCInNRbiVaEPA==" }, "lines-and-columns": { "version": "1.1.6", diff --git a/packages/query-graphql/package.json b/packages/query-graphql/package.json index 79af42431..704d38e11 100644 --- a/packages/query-graphql/package.json +++ b/packages/query-graphql/package.json @@ -72,7 +72,7 @@ "class-transformer": "0.4.0", "class-validator": "0.13.1", "dataloader": "2.0.0", - "graphql": "15.6.1", + "graphql": "15.7.1", "graphql-subscriptions": "1.2.1", "ts-mockito": "2.6.1", "ts-morph": "12.0.0", From 4c59cd82f87663a40634523101c7f511afe77e63 Mon Sep 17 00:00:00 2001 From: Tycho Bokdam Date: Thu, 28 Oct 2021 18:53:45 +0200 Subject: [PATCH 5/5] feat: allow for passing `useSoftDelete` in resolver opts --- .../interfaces/delete-many-options.interface.ts | 3 +++ .../src/interfaces/delete-one-options.interface.ts | 7 ++++++- .../src/interfaces/find-by-id-options.interface.ts | 7 ++++++- packages/core/src/interfaces/index.ts | 1 + packages/core/src/services/query.service.ts | 3 ++- .../src/decorators/resolver-query.decorator.ts | 6 +++++- .../query-graphql/src/resolvers/delete.resolver.ts | 12 ++++++++++-- .../query-graphql/src/resolvers/read.resolver.ts | 4 ++-- .../src/resolvers/resolver.interface.ts | 8 ++++---- .../src/services/typeorm-query.service.ts | 14 ++++++++++---- 10 files changed, 49 insertions(+), 16 deletions(-) create mode 100644 packages/core/src/interfaces/delete-many-options.interface.ts diff --git a/packages/core/src/interfaces/delete-many-options.interface.ts b/packages/core/src/interfaces/delete-many-options.interface.ts new file mode 100644 index 000000000..c1f7b8ee0 --- /dev/null +++ b/packages/core/src/interfaces/delete-many-options.interface.ts @@ -0,0 +1,3 @@ +import { DeleteOneOptions } from './delete-one-options.interface'; + +export type DeleteManyOptions = DeleteOneOptions; diff --git a/packages/core/src/interfaces/delete-one-options.interface.ts b/packages/core/src/interfaces/delete-one-options.interface.ts index 05466df88..f8e41f242 100644 --- a/packages/core/src/interfaces/delete-one-options.interface.ts +++ b/packages/core/src/interfaces/delete-one-options.interface.ts @@ -1,3 +1,8 @@ import { Filterable } from './filterable.interface'; -export type DeleteOneOptions = Filterable; +export interface DeleteOneOptions extends Filterable { + /** + * Use soft delete when doing delete mutation + */ + useSoftDelete?: boolean; +} diff --git a/packages/core/src/interfaces/find-by-id-options.interface.ts b/packages/core/src/interfaces/find-by-id-options.interface.ts index bd77ec0b4..a90b656bd 100644 --- a/packages/core/src/interfaces/find-by-id-options.interface.ts +++ b/packages/core/src/interfaces/find-by-id-options.interface.ts @@ -1,3 +1,8 @@ import { Filterable } from './filterable.interface'; -export type FindByIdOptions = Filterable; +export interface FindByIdOptions extends Filterable { + /** + * Allow also deleted records to be get + */ + withDeleted?: boolean; +} diff --git a/packages/core/src/interfaces/index.ts b/packages/core/src/interfaces/index.ts index 3a1ef417c..2f02f7260 100644 --- a/packages/core/src/interfaces/index.ts +++ b/packages/core/src/interfaces/index.ts @@ -13,4 +13,5 @@ export * from './find-by-id-options.interface'; export * from './get-by-id-options.interface'; export * from './update-one-options.interface'; export * from './delete-one-options.interface'; +export * from './delete-many-options.interface'; export * from './filterable.interface'; diff --git a/packages/core/src/services/query.service.ts b/packages/core/src/services/query.service.ts index 7ad665644..8eb2824f1 100644 --- a/packages/core/src/services/query.service.ts +++ b/packages/core/src/services/query.service.ts @@ -13,6 +13,7 @@ import { GetByIdOptions, UpdateOneOptions, DeleteOneOptions, + DeleteManyOptions, } from '../interfaces'; /** @@ -271,7 +272,7 @@ export interface QueryService, U = DeepPartial> { * * @param filter - the filter to find records to delete. */ - deleteMany(filter: Filter): Promise; + deleteMany(filter: Filter, opts?: DeleteManyOptions): Promise; } /** diff --git a/packages/query-graphql/src/decorators/resolver-query.decorator.ts b/packages/query-graphql/src/decorators/resolver-query.decorator.ts index 14d5aa31e..e8acf5a6e 100644 --- a/packages/query-graphql/src/decorators/resolver-query.decorator.ts +++ b/packages/query-graphql/src/decorators/resolver-query.decorator.ts @@ -2,6 +2,10 @@ import { Query, QueryOptions, ReturnTypeFunc } from '@nestjs/graphql'; import { applyDecorators } from '@nestjs/common'; import { isDisabled, ResolverMethod, ResolverMethodOpts } from './resolver-method.decorator'; +export interface QueryResolverMethodOpts extends ResolverMethodOpts { + withDeleted?: boolean; +} + /** * @internal * Decorator for a graphql `query` endpoint. @@ -12,7 +16,7 @@ import { isDisabled, ResolverMethod, ResolverMethodOpts } from './resolver-metho export function ResolverQuery( typeFunc: ReturnTypeFunc, options?: QueryOptions, - ...opts: ResolverMethodOpts[] + ...opts: QueryResolverMethodOpts[] ): MethodDecorator { if (isDisabled(opts)) { return (): void => {}; diff --git a/packages/query-graphql/src/resolvers/delete.resolver.ts b/packages/query-graphql/src/resolvers/delete.resolver.ts index a1f0393cc..ee1c0a390 100644 --- a/packages/query-graphql/src/resolvers/delete.resolver.ts +++ b/packages/query-graphql/src/resolvers/delete.resolver.ts @@ -29,6 +29,10 @@ export interface DeleteResolverOpts extends SubscriptionResolverOpts { * ArgsType for deleteMany mutation. */ DeleteManyInput?: Class>; + /** + * Use soft delete when doing delete mutation + */ + useSoftDelete?: boolean; } export interface DeleteResolver> extends ServiceResolver { @@ -85,7 +89,7 @@ export const Deletable = const deleteManyMutationName = opts.many?.name ?? `deleteMany${pluralBaseName}`; const DMR = DeleteManyResponseType(); - const commonResolverOpts = omit(opts, 'dtoName', 'one', 'many', 'DeleteOneInput', 'DeleteManyInput'); + const commonResolverOpts = omit(opts, 'dtoName', 'one', 'many', 'DeleteOneInput', 'DeleteManyInput', 'useSoftDelete'); @ObjectType(`${baseName}DeleteResponse`) // eslint-disable-next-line @typescript-eslint/ban-ts-comment @@ -124,7 +128,10 @@ export const Deletable = }) authorizeFilter?: Filter, ): Promise> { - const deletedResponse = await this.service.deleteOne(input.input.id, { filter: authorizeFilter ?? {} }); + const deletedResponse = await this.service.deleteOne(input.input.id, { + filter: authorizeFilter ?? {}, + useSoftDelete: opts?.useSoftDelete, + }); if (enableOneSubscriptions) { await this.publishDeletedOneEvent(deletedResponse, authorizeFilter); } @@ -148,6 +155,7 @@ export const Deletable = ): Promise { const deleteManyResponse = await this.service.deleteMany( mergeFilter(input.input.filter, authorizeFilter ?? {}), + opts ?? {}, ); if (enableManySubscriptions) { await this.publishDeletedManyEvent(deleteManyResponse, authorizeFilter); diff --git a/packages/query-graphql/src/resolvers/read.resolver.ts b/packages/query-graphql/src/resolvers/read.resolver.ts index 5f32e0b62..ac609bdf2 100644 --- a/packages/query-graphql/src/resolvers/read.resolver.ts +++ b/packages/query-graphql/src/resolvers/read.resolver.ts @@ -60,7 +60,7 @@ export const Readable = const { QueryArgs = QueryArgsType(DTOClass, { ...opts, connectionName: `${baseName}Connection` }) } = opts; const { ConnectionType } = QueryArgs; - const commonResolverOpts = omit(opts, 'dtoName', 'one', 'many', 'QueryArgs', 'Connection'); + const commonResolverOpts = omit(opts, 'dtoName', 'one', 'many', 'QueryArgs', 'Connection', 'withDeleted'); @ArgsType() class QA extends QueryArgs {} @@ -84,7 +84,7 @@ export const Readable = }) authorizeFilter?: Filter, ): Promise { - return this.service.findById(input.id, { filter: authorizeFilter }); + return this.service.findById(input.id, { filter: authorizeFilter, withDeleted: opts?.one?.withDeleted }); } @ResolverQuery( diff --git a/packages/query-graphql/src/resolvers/resolver.interface.ts b/packages/query-graphql/src/resolvers/resolver.interface.ts index ecc04c99c..fa1c1f562 100644 --- a/packages/query-graphql/src/resolvers/resolver.interface.ts +++ b/packages/query-graphql/src/resolvers/resolver.interface.ts @@ -1,6 +1,6 @@ import { QueryService } from '@nestjs-query/core'; import { DTONamesOpts } from '../common'; -import { ResolverMethodOpts, SubscriptionResolverMethodOpts } from '../decorators'; +import { QueryResolverMethodOpts, SubscriptionResolverMethodOpts } from '../decorators'; import { GraphQLPubSub } from '../subscription'; import { PagingStrategies, QueryArgsTypeOpts } from '../types'; @@ -9,15 +9,15 @@ type NamedEndpoint = { name?: string; }; -export interface ResolverOpts extends ResolverMethodOpts, DTONamesOpts { +export interface ResolverOpts extends QueryResolverMethodOpts, DTONamesOpts { /** * Options for single record graphql endpoints */ - one?: ResolverMethodOpts & NamedEndpoint; + one?: QueryResolverMethodOpts & NamedEndpoint; /** * Options for multiple record graphql endpoints */ - many?: ResolverMethodOpts & NamedEndpoint; + many?: QueryResolverMethodOpts & NamedEndpoint; } export interface SubscriptionResolverOpts extends SubscriptionResolverMethodOpts, DTONamesOpts { diff --git a/packages/query-typeorm/src/services/typeorm-query.service.ts b/packages/query-typeorm/src/services/typeorm-query.service.ts index 23bbef66e..df4b55c35 100644 --- a/packages/query-typeorm/src/services/typeorm-query.service.ts +++ b/packages/query-typeorm/src/services/typeorm-query.service.ts @@ -13,6 +13,7 @@ import { UpdateOneOptions, DeleteOneOptions, Filterable, + DeleteManyOptions, } from '@nestjs-query/core'; import { Repository, DeleteResult } from 'typeorm'; import { QueryDeepPartialEntity } from 'typeorm/query-builder/QueryPartialEntity'; @@ -97,7 +98,11 @@ export class TypeOrmQueryService * @param id - The id of the record to find. */ async findById(id: string | number, opts?: FindByIdOptions): Promise { - return this.filterQueryBuilder.selectById(id, opts ?? {}).getOne(); + const qb = this.filterQueryBuilder.selectById(id, opts ?? {}); + if (opts?.withDeleted) { + qb.withDeleted(); + } + return qb.getOne(); } /** @@ -202,10 +207,11 @@ export class TypeOrmQueryService * * @param id - The `id` of the entity to delete. * @param filter Additional filter to use when finding the entity to delete. + * @param opts - Additional options. */ async deleteOne(id: string | number, opts?: DeleteOneOptions): Promise { const entity = await this.getById(id, opts); - if (this.useSoftDelete) { + if (this.useSoftDelete || opts?.useSoftDelete) { return this.repo.softRemove(entity); } return this.repo.remove(entity); @@ -224,9 +230,9 @@ export class TypeOrmQueryService * * @param filter - A `Filter` to find records to delete. */ - async deleteMany(filter: Filter): Promise { + async deleteMany(filter: Filter, opts?: DeleteManyOptions): Promise { let deleteResult: DeleteResult; - if (this.useSoftDelete) { + if (this.useSoftDelete || opts?.useSoftDelete) { deleteResult = await this.filterQueryBuilder.softDelete({ filter }).execute(); } else { deleteResult = await this.filterQueryBuilder.delete({ filter }).execute();