From 18e45757ab8bb1aa09dc0aa50f15591ab7fde2a3 Mon Sep 17 00:00:00 2001 From: Jacek Tomaszewski Date: Wed, 22 Apr 2026 00:37:14 +0200 Subject: [PATCH 1/2] ci: disable Nx Cloud on fork The Nx Cloud workspace tied to fullstackhouse/nestjs-query has been disabled for exceeding the FREE plan, causing every CI job to exit with 'Workspace is unable to be authorized' before any work runs. Replace the inherited nxCloudAccessToken with neverConnectToCloud:true so Nx runs locally without attempting to contact Nx Cloud. We lose remote cache, which is fine for a low-traffic fork. --- nx.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nx.json b/nx.json index 1f7821dff..3c1905c37 100644 --- a/nx.json +++ b/nx.json @@ -53,7 +53,7 @@ "cache": true } }, - "nxCloudAccessToken": "YWExNTY0MWYtYWMzNy00ZWZkLWIzMWEtMGYzYWY4YWRmMDE1fHJlYWQtd3JpdGU=", + "neverConnectToCloud": true, "useInferencePlugins": false, "defaultBase": "master" } From 6e53779b2300cb8f145c212ad8655ea9488e66ed Mon Sep 17 00:00:00 2001 From: Jacek Tomaszewski Date: Wed, 22 Apr 2026 00:50:06 +0200 Subject: [PATCH 2/2] fix(lint): resolve lint errors uncovered after Nx Cloud disable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With Nx Cloud no longer short-circuiting CI, the lint step actually runs and surfaced pre-existing errors in query-mikro-orm and query-graphql: - prettier/prettier formatting in mikro-orm-query.service.ts and its test file (auto-fixed). - jest/prefer-to-have-length in cursor-query-args.type.spec.ts (auto-fixed). - @typescript-eslint/no-unsafe-argument on existing `as any` calls into MikroORM EntityManager — extended the adjacent no-explicit-any disable comments to cover both rules. - @typescript-eslint/no-extra-semi on `;(response.x as Record…)` leading-semi patterns inside computeAggregateForGroup — rewrote each branch to build a typed local record and assign it back to `response` via a cast, which avoids the leading semi entirely. --- .../query/cursor-query-args.type.spec.ts | 2 +- .../services/mikro-orm-query.service.spec.ts | 6 +-- .../src/services/mikro-orm-query.service.ts | 48 ++++++++++++------- 3 files changed, 34 insertions(+), 22 deletions(-) diff --git a/packages/query-graphql/__tests__/types/query/cursor-query-args.type.spec.ts b/packages/query-graphql/__tests__/types/query/cursor-query-args.type.spec.ts index aa15b99cb..df3dbc227 100644 --- a/packages/query-graphql/__tests__/types/query/cursor-query-args.type.spec.ts +++ b/packages/query-graphql/__tests__/types/query/cursor-query-args.type.spec.ts @@ -139,7 +139,7 @@ describe('Cursor paging strategy QueryArgsType with manual options', (): void => } const queryInstance = plainToClass(TestCursorQuery, queryObj) const errors = validateSync(queryInstance) - expect(errors.length).toBe(1) + expect(errors).toHaveLength(1) expect(errors[0].property).toBe('paging') }) diff --git a/packages/query-mikro-orm/__tests__/services/mikro-orm-query.service.spec.ts b/packages/query-mikro-orm/__tests__/services/mikro-orm-query.service.spec.ts index fa864b4d7..8e57cba13 100644 --- a/packages/query-mikro-orm/__tests__/services/mikro-orm-query.service.spec.ts +++ b/packages/query-mikro-orm/__tests__/services/mikro-orm-query.service.spec.ts @@ -563,9 +563,9 @@ describe('MikroOrmQueryService', () => { }) it('should throw for withDeleted option', async () => { - await expect( - queryService.aggregate({}, { count: [{ field: 'id', args: {} }] }, { withDeleted: true }) - ).rejects.toThrow('MikroOrmQueryService does not support withDeleted on aggregate') + await expect(queryService.aggregate({}, { count: [{ field: 'id', args: {} }] }, { withDeleted: true })).rejects.toThrow( + 'MikroOrmQueryService does not support withDeleted on aggregate' + ) }) }) }) diff --git a/packages/query-mikro-orm/src/services/mikro-orm-query.service.ts b/packages/query-mikro-orm/src/services/mikro-orm-query.service.ts index 384d6bbd9..aff81d13c 100644 --- a/packages/query-mikro-orm/src/services/mikro-orm-query.service.ts +++ b/packages/query-mikro-orm/src/services/mikro-orm-query.service.ts @@ -1,4 +1,14 @@ -import { Collection, EntityData, EntityKey, EntityRepository, FilterQuery, QueryOrder, QueryOrderMap, Reference, wrap } from '@mikro-orm/core' +import { + Collection, + EntityData, + EntityKey, + EntityRepository, + FilterQuery, + QueryOrder, + QueryOrderMap, + Reference, + wrap +} from '@mikro-orm/core' import { OperatorMap } from '@mikro-orm/core/typings' import { AggregateOptions, @@ -98,7 +108,7 @@ export class MikroOrmQueryService): Promise { const em = this.repo.getEntityManager() - // eslint-disable-next-line @typescript-eslint/no-explicit-any + // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument const entity = em.create(this.repo.getEntityName(), record as any) await em.persistAndFlush(entity) @@ -110,7 +120,7 @@ export class MikroOrmQueryService[]): Promise { const em = this.repo.getEntityManager() - // eslint-disable-next-line @typescript-eslint/no-explicit-any + // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument const entities = records.map((r) => em.create(this.repo.getEntityName(), r as any)) await em.persistAndFlush(entities) @@ -135,7 +145,7 @@ export class MikroOrmQueryService, filter: Filter): Promise { const em = this.repo.getEntityManager() const where = this.convertFilter(filter) - // eslint-disable-next-line @typescript-eslint/no-explicit-any + // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument const updatedCount = await em.nativeUpdate(this.repo.getEntityName(), where, update as any) return { updatedCount } } @@ -225,10 +235,7 @@ export class MikroOrmQueryService - ): AggregateResponse[] { + private computeAggregateInMemory(entities: Entity[], aggregateQuery: AggregateQuery): AggregateResponse[] { if (!aggregateQuery.groupBy || aggregateQuery.groupBy.length === 0) { return [this.computeAggregateForGroup(entities, aggregateQuery)] } @@ -265,36 +272,39 @@ export class MikroOrmQueryService = {} if (aggregateQuery.count) { - response.count = {} + const count: Record = {} for (const { field } of aggregateQuery.count) { - ;(response.count as Record)[String(field)] = entities.length + count[String(field)] = entities.length } + response.count = count as AggregateResponse['count'] } if (aggregateQuery.sum) { - response.sum = {} + const sumAcc: Record = {} for (const { field } of aggregateQuery.sum) { const sum = entities.reduce((acc, e) => { const val = (e as Record)[String(field)] return acc + (typeof val === 'number' ? val : 0) }, 0) - ;(response.sum as Record)[String(field)] = sum + sumAcc[String(field)] = sum } + response.sum = sumAcc as AggregateResponse['sum'] } if (aggregateQuery.avg) { - response.avg = {} + const avgAcc: Record = {} for (const { field } of aggregateQuery.avg) { const sum = entities.reduce((acc, e) => { const val = (e as Record)[String(field)] return acc + (typeof val === 'number' ? val : 0) }, 0) - ;(response.avg as Record)[String(field)] = entities.length > 0 ? sum / entities.length : 0 + avgAcc[String(field)] = entities.length > 0 ? sum / entities.length : 0 } + response.avg = avgAcc as AggregateResponse['avg'] } if (aggregateQuery.max) { - response.max = {} + const maxAcc: Record = {} for (const { field } of aggregateQuery.max) { let max: unknown = undefined for (const e of entities) { @@ -303,12 +313,13 @@ export class MikroOrmQueryService)[String(field)] = max + maxAcc[String(field)] = max } + response.max = maxAcc as AggregateResponse['max'] } if (aggregateQuery.min) { - response.min = {} + const minAcc: Record = {} for (const { field } of aggregateQuery.min) { let min: unknown = undefined for (const e of entities) { @@ -317,8 +328,9 @@ export class MikroOrmQueryService)[String(field)] = min + minAcc[String(field)] = min } + response.min = minAcc as AggregateResponse['min'] } return response