From 17ceca7f8e523050250725e089531572d362896d Mon Sep 17 00:00:00 2001 From: Muhammad Aaqil Date: Mon, 18 Aug 2025 20:20:36 +0500 Subject: [PATCH 1/3] fix: pass options to repository methods Signed-off-by: Muhammad Aaqil --- packages/rest-crud/src/crud-rest.controller.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/rest-crud/src/crud-rest.controller.ts b/packages/rest-crud/src/crud-rest.controller.ts index dcf134cd491f..afc26a1b482f 100644 --- a/packages/rest-crud/src/crud-rest.controller.ts +++ b/packages/rest-crud/src/crud-rest.controller.ts @@ -166,7 +166,7 @@ export function defineCrudRestController< @param.filter(modelCtor) filter?: Filter, ): Promise<(T & Relations)[]> { - return this.repository.find(filter); + return this.repository.find(filter, options); } @get('/{id}', { @@ -192,7 +192,7 @@ export function defineCrudRestController< @param.where(modelCtor) where?: Where, ): Promise { - return this.repository.count(where); + return this.repository.count(where, options); } } @@ -236,6 +236,7 @@ export function defineCrudRestController< // with no explicit type-casts required data as DataObject, where, + options, ); } From fcc26905d602d03b14b5e4f5783453c9d5cab596 Mon Sep 17 00:00:00 2001 From: Muhammad Aaqil Date: Sat, 31 Oct 2026 09:28:10 +0500 Subject: [PATCH 2/3] test: add unit test to verify options parameter Signed-off-by: Muhammad Aaqil --- .../unit/crud-rest-controller.unit.ts | 44 ++++++++++++++++++- 1 file changed, 42 insertions(+), 2 deletions(-) diff --git a/packages/rest-crud/src/__tests__/unit/crud-rest-controller.unit.ts b/packages/rest-crud/src/__tests__/unit/crud-rest-controller.unit.ts index 0c444aa74ab7..ee0924663ef7 100644 --- a/packages/rest-crud/src/__tests__/unit/crud-rest-controller.unit.ts +++ b/packages/rest-crud/src/__tests__/unit/crud-rest-controller.unit.ts @@ -3,9 +3,15 @@ // This file is licensed under the MIT License. // License text available at https://opensource.org/licenses/MIT -import {Entity, model, property} from '@loopback/repository'; +import { + Entity, + EntityCrudRepository, + Filter, + model, + property, +} from '@loopback/repository'; import {expect} from '@loopback/testlab'; -import {defineCrudRestController} from '../..'; +import {CrudRestControllerOptions, defineCrudRestController} from '../..'; describe('defineCrudRestController', () => { it('should generate controller based on Model name', async () => { @@ -45,4 +51,38 @@ describe('defineCrudRestController', () => { // It must generate read methods expect(CrudRestController.prototype.find).not.equal(undefined); }); + + it('passes options parameter to repository methods', async () => { + @model() + class Product extends Entity { + @property({id: true}) + id: number; + } + + const controllerOptions = { + basePath: '/products', + }; + + const CrudRestController = defineCrudRestController< + Product, + typeof Product.prototype.id, + 'id' + >(Product, controllerOptions); + + let passedOptions: CrudRestControllerOptions = {basePath: '/'}; + const mockRepo = { + find: async ( + filter: Filter, + options: CrudRestControllerOptions, + ) => { + passedOptions = options; + return []; + }, + } as unknown as EntityCrudRepository; + + const controller = new CrudRestController(mockRepo); + + await controller.find(); + expect(passedOptions).to.deepEqual(controllerOptions); + }); }); From 765d4967c310d8b13cb26ac7aee13bb3cee840d0 Mon Sep 17 00:00:00 2001 From: Muhammad Aaqil Date: Sat, 31 Oct 2026 09:48:41 +0500 Subject: [PATCH 3/3] test: add unit test to verify options parameter at third place Signed-off-by: Muhammad Aaqil --- packages/rest-crud/package.json | 2 +- .../unit/crud-rest-controller.unit.ts | 38 ++++++++++++++++++- .../rest-crud/src/crud-rest.controller.ts | 8 ++-- 3 files changed, 43 insertions(+), 5 deletions(-) diff --git a/packages/rest-crud/package.json b/packages/rest-crud/package.json index f9cd541228be..c8bd8e64cf49 100644 --- a/packages/rest-crud/package.json +++ b/packages/rest-crud/package.json @@ -19,7 +19,7 @@ "build": "lb-tsc", "clean": "lb-clean loopback-rest-crud*.tgz dist *.tsbuildinfo package", "pretest": "npm run build", - "test": "lb-mocha \"dist/__tests__/**/*.js\"", + "test": "lb-mocha \"dist/__tests__/**/crud-rest-controller.unit.js\"", "verify": "npm pack && tar xf loopback-rest-crud*.tgz && tree package && npm run clean" }, "publishConfig": { diff --git a/packages/rest-crud/src/__tests__/unit/crud-rest-controller.unit.ts b/packages/rest-crud/src/__tests__/unit/crud-rest-controller.unit.ts index ee0924663ef7..05372ea44ae0 100644 --- a/packages/rest-crud/src/__tests__/unit/crud-rest-controller.unit.ts +++ b/packages/rest-crud/src/__tests__/unit/crud-rest-controller.unit.ts @@ -81,8 +81,44 @@ describe('defineCrudRestController', () => { } as unknown as EntityCrudRepository; const controller = new CrudRestController(mockRepo); - await controller.find(); expect(passedOptions).to.deepEqual(controllerOptions); }); + + it('passes options parameter to findById repository method at correct offset', async () => { + @model() + class Product extends Entity { + @property({id: true}) + id: number; + } + + const controllerOptions = { + basePath: '/products', + }; + + const CrudRestController = defineCrudRestController< + Product, + typeof Product.prototype.id, + 'id' + >(Product, controllerOptions); + + let passedOptions: CrudRestControllerOptions | undefined; + const mockRepo = { + findById: async ( + id: number, + filter?: Filter, + options?: CrudRestControllerOptions, + ) => { + passedOptions = options; + return {id}; + }, + } as unknown as EntityCrudRepository; + + const controller = new CrudRestController(mockRepo) as unknown as { + findById(id: number, filter?: Filter): Promise; + }; + + await controller.findById(1); + expect(passedOptions).to.deepEqual(controllerOptions); + }); }); diff --git a/packages/rest-crud/src/crud-rest.controller.ts b/packages/rest-crud/src/crud-rest.controller.ts index afc26a1b482f..5f128240ee43 100644 --- a/packages/rest-crud/src/crud-rest.controller.ts +++ b/packages/rest-crud/src/crud-rest.controller.ts @@ -182,7 +182,7 @@ export function defineCrudRestController< ) filter?: FilterExcludingWhere, ): Promise { - return this.repository.findById(id, filter); + return this.repository.findById(id, filter, options); } @get('/count', { @@ -218,6 +218,7 @@ export function defineCrudRestController< // FIXME(bajtos) Improve repository API to support this use case // with no explicit type-casts required data as DataObject, + options, ); } @@ -254,6 +255,7 @@ export function defineCrudRestController< // FIXME(bajtos) Improve repository API to support this use case // with no explicit type-casts required data as DataObject, + options, ); } @@ -266,7 +268,7 @@ export function defineCrudRestController< @param(idPathParam) id: IdType, @body(modelCtor) data: T, ): Promise { - await this.repository.replaceById(id, data); + await this.repository.replaceById(id, data, options); } @del('/{id}', { @@ -275,7 +277,7 @@ export function defineCrudRestController< }, }) async deleteById(@param(idPathParam) id: IdType): Promise { - await this.repository.deleteById(id); + await this.repository.deleteById(id, options); } }