diff --git a/.changeset/pretty-shoes-sing.md b/.changeset/pretty-shoes-sing.md new file mode 100644 index 0000000000..1dc92ae560 --- /dev/null +++ b/.changeset/pretty-shoes-sing.md @@ -0,0 +1,5 @@ +--- +"@medusajs/medusa": patch +--- + +chore(medusa): add currency to region responses diff --git a/integration-tests/api/__tests__/admin/__snapshots__/region.js.snap b/integration-tests/api/__tests__/admin/__snapshots__/region.js.snap index 844c0de52b..f159638ab1 100644 --- a/integration-tests/api/__tests__/admin/__snapshots__/region.js.snap +++ b/integration-tests/api/__tests__/admin/__snapshots__/region.js.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`/admin/regions Remove region from country on delete successfully creates a region with countries from a previously deleted region 1`] = ` +exports[`/admin/regions Remove region from country on delete should successfully creates a region with countries from a previously deleted region 1`] = ` Object { "deleted": true, "id": "test-region", @@ -8,7 +8,7 @@ Object { } `; -exports[`/admin/regions Remove region from country on delete successfully creates a region with countries from a previously deleted region 2`] = ` +exports[`/admin/regions Remove region from country on delete should successfully creates a region with countries from a previously deleted region 2`] = ` Object { "automatic_taxes": true, "countries": Array [ @@ -23,6 +23,12 @@ Object { }, ], "created_at": Any, + "currency": Object { + "code": "usd", + "name": "US Dollar", + "symbol": "$", + "symbol_native": "$", + }, "currency_code": "usd", "deleted_at": null, "fulfillment_providers": Array [ diff --git a/integration-tests/api/__tests__/admin/region.js b/integration-tests/api/__tests__/admin/region.js index 965eab08da..de986b1e23 100644 --- a/integration-tests/api/__tests__/admin/region.js +++ b/integration-tests/api/__tests__/admin/region.js @@ -55,15 +55,11 @@ describe("/admin/regions", () => { await db.teardown() }) - it("successfully creates a region with countries from a previously deleted region", async () => { + it("should successfully creates a region with countries from a previously deleted region", async () => { const api = useApi() const response = await api - .delete(`/admin/regions/test-region`, { - headers: { - "x-medusa-access-token": "test_token", - }, - }) + .delete(`/admin/regions/test-region`, adminReqConfig) .catch((err) => { console.log(err) }) @@ -85,11 +81,7 @@ describe("/admin/regions", () => { fulfillment_providers: ["test-ful"], countries: ["us"], }, - { - headers: { - "x-medusa-access-token": "test_token", - }, - } + adminReqConfig ) expect(newReg.status).toEqual(200) @@ -153,15 +145,28 @@ describe("/admin/regions", () => { await db.teardown() }) - it("only returns non-deleted regions", async () => { + it("should list the regions with expand currency relation", async () => { + const api = useApi() + + const response = await api.get( + "/admin/regions?limit=1&offset=1&expand=currency", + adminReqConfig + ) + + expect(response.status).toEqual(200) + + expect(response.data.regions[0].currency).toEqual( + expect.objectContaining({ + code: "usd", + }) + ) + }) + + it("should only return non-deleted regions", async () => { const api = useApi() const response = await api - .get(`/admin/regions`, { - headers: { - "x-medusa-access-token": "test_token", - }, - }) + .get(`/admin/regions`, adminReqConfig) .catch((err) => { console.log(err) }) @@ -183,29 +188,21 @@ describe("/admin/regions", () => { expect(response.status).toEqual(200) }) - it("returns count of total regions", async () => { + it("should return count of total regions", async () => { const api = useApi() - const response = await api.get(`/admin/regions?limit=2`, { - headers: { - "x-medusa-access-token": "test_token", - }, - }) + const response = await api.get(`/admin/regions?limit=2`, adminReqConfig) expect(response.data.regions).toHaveLength(2) expect(response.data.count).toEqual(3) expect(response.status).toEqual(200) }) - it("filters correctly on update", async () => { + it("should filter correctly on update", async () => { const api = useApi() const response = await api - .get(`/admin/regions?updated_at[gt]=10-10-2005`, { - headers: { - "x-medusa-access-token": "test_token", - }, - }) + .get(`/admin/regions?updated_at[gt]=10-10-2005`, adminReqConfig) .catch((err) => { console.log(err) }) @@ -225,6 +222,59 @@ describe("/admin/regions", () => { }) }) + describe("GET /admin/regions/:id", () => { + beforeEach(async () => { + const manager = dbConnection.manager + await adminSeeder(dbConnection) + + await manager.insert(Region, { + id: "region-id", + name: "Test Region", + currency_code: "usd", + tax_rate: 0, + }) + }) + + afterEach(async () => { + const db = useDb() + await db.teardown() + }) + + it("should retrieve the region from ID", async () => { + const api = useApi() + + const response = await api.get( + `/admin/regions/region-id?expand=currency`, + adminReqConfig + ) + + expect(response.status).toEqual(200) + expect(response.data.region).toEqual( + expect.objectContaining({ + id: "region-id", + currency: expect.objectContaining({ + code: "usd", + }), + }) + ) + }) + + it("should throw an error when region ID is invalid", async () => { + const api = useApi() + + const error = await api + .get(`/admin/regions/invalid-region-id`, adminReqConfig) + .catch((e) => e) + + expect(error.response.status).toEqual(404) + + expect(error.response.data).toEqual({ + type: "not_found", + message: "Region with invalid-region-id was not found", + }) + }) + }) + describe("DELETE /admin/regions/:id", () => { beforeEach(async () => { await adminSeeder(dbConnection) @@ -246,7 +296,7 @@ describe("/admin/regions", () => { await db.teardown() }) - it("successfully deletes a region with a fulfillment provider", async () => { + it("should successfully deletes a region with a fulfillment provider", async () => { const api = useApi() // add fulfillment provider to the region @@ -255,19 +305,11 @@ describe("/admin/regions", () => { { fulfillment_providers: ["test-ful"], }, - { - headers: { - "x-medusa-access-token": "test_token", - }, - } + adminReqConfig ) const response = await api - .delete(`/admin/regions/test-region`, { - headers: { - "x-medusa-access-token": "test_token", - }, - }) + .delete(`/admin/regions/test-region`, adminReqConfig) .catch((err) => { console.log(err) }) @@ -280,7 +322,7 @@ describe("/admin/regions", () => { expect(response.status).toEqual(200) }) - it("fails to create when countries exists in different region", async () => { + it("should fails to create when countries exists in different region", async () => { const api = useApi() try { @@ -294,11 +336,7 @@ describe("/admin/regions", () => { fulfillment_providers: ["test-ful"], countries: ["us"], }, - { - headers: { - "x-medusa-access-token": "test_token", - }, - } + adminReqConfig ) } catch (error) { expect(error.response.status).toEqual(422) diff --git a/integration-tests/api/__tests__/store/regions.js b/integration-tests/api/__tests__/store/regions.js index cac9e7ddd1..79768ec8c6 100644 --- a/integration-tests/api/__tests__/store/regions.js +++ b/integration-tests/api/__tests__/store/regions.js @@ -27,7 +27,7 @@ describe("/store/carts", () => { beforeAll(async () => { const cwd = path.resolve(path.join(__dirname, "..", "..")) dbConnection = await initDb({ cwd }) - medusaProcess = await setupServer({ cwd }) + medusaProcess = await setupServer({ cwd, verbose: true }) }) afterAll(async () => { @@ -71,5 +71,71 @@ describe("/store/carts", () => { expect(response.data.offset).toEqual(1) expect(response.data.limit).toEqual(1) }) + + it("should list the store regions with expand relations", async () => { + const api = useApi() + + const response = await api.get( + "/store/regions?limit=1&offset=1&expand=currency" + ) + + expect(response.status).toEqual(200) + + expect(response.data.regions[0].currency).toEqual( + expect.objectContaining({ + code: "usd", + }) + ) + }) + }) + + describe("GET /store/regions/:id", () => { + beforeEach(async () => { + const manager = dbConnection.manager + + await manager.insert(Region, { + id: "region-id", + name: "Test Region", + currency_code: "usd", + tax_rate: 0, + }) + }) + + afterEach(async () => { + const db = useDb() + await db.teardown() + }) + + it("should retrieve the region from ID", async () => { + const api = useApi() + + const response = await api.get(`/store/regions/region-id?expand=currency`) + + expect(response.status).toEqual(200) + + expect(response.data.region).toEqual( + expect.objectContaining({ + id: "region-id", + currency: expect.objectContaining({ + code: "usd", + }), + }) + ) + }) + + it("should throw an error when region ID is invalid", async () => { + const api = useApi() + + const error = await api + .get(`/store/regions/invalid-region-id`) + .catch((e) => e) + + expect(error.response.status).toEqual(404) + + expect(error.response.data).toEqual({ + type: "not_found", + message: "Region with invalid-region-id was not found", + }) + }) }) }) diff --git a/packages/medusa/src/api/routes/admin/regions/__tests__/get-region.js b/packages/medusa/src/api/routes/admin/regions/__tests__/get-region.js index be98d8ed07..a5e14fceb4 100644 --- a/packages/medusa/src/api/routes/admin/regions/__tests__/get-region.js +++ b/packages/medusa/src/api/routes/admin/regions/__tests__/get-region.js @@ -19,8 +19,9 @@ const defaultFields = [ const defaultRelations = [ "countries", - "payment_providers", + "currency", "fulfillment_providers", + "payment_providers", ] describe("GET /admin/regions/:region_id", () => { diff --git a/packages/medusa/src/api/routes/admin/regions/__tests__/list-regions.js b/packages/medusa/src/api/routes/admin/regions/__tests__/list-regions.js index 633fd0c6dc..1d4e7d7aa7 100644 --- a/packages/medusa/src/api/routes/admin/regions/__tests__/list-regions.js +++ b/packages/medusa/src/api/routes/admin/regions/__tests__/list-regions.js @@ -1,6 +1,6 @@ import { IdMap } from "medusa-test-utils" -import { RegionServiceMock } from "../../../../../services/__mocks__/region" import { request } from "../../../../../helpers/test-request" +import { RegionServiceMock } from "../../../../../services/__mocks__/region" const defaultFields = [ "id", @@ -19,8 +19,9 @@ const defaultFields = [ const defaultRelations = [ "countries", - "payment_providers", + "currency", "fulfillment_providers", + "payment_providers", ] describe("GET /admin/regions", () => { @@ -54,6 +55,7 @@ describe("GET /admin/regions", () => { relations: defaultRelations, take: 50, skip: 0, + order: { created_at: "DESC" }, } ) }) @@ -89,6 +91,7 @@ describe("GET /admin/regions", () => { relations: defaultRelations, take: 20, skip: 10, + order: { created_at: "DESC" }, } ) }) diff --git a/packages/medusa/src/api/routes/admin/regions/get-region.ts b/packages/medusa/src/api/routes/admin/regions/get-region.ts index f0709b8fba..c1fad4eff2 100644 --- a/packages/medusa/src/api/routes/admin/regions/get-region.ts +++ b/packages/medusa/src/api/routes/admin/regions/get-region.ts @@ -1,6 +1,5 @@ -import { defaultAdminRegionFields, defaultAdminRegionRelations } from "." - import RegionService from "../../../../services/region" +import { FindParams } from "../../../../types/common" /** * @oas [get] /admin/regions/{id} @@ -57,10 +56,10 @@ import RegionService from "../../../../services/region" export default async (req, res) => { const { region_id } = req.params const regionService: RegionService = req.scope.resolve("regionService") - const region = await regionService.retrieve(region_id, { - select: defaultAdminRegionFields, - relations: defaultAdminRegionRelations, - }) + + const region = await regionService.retrieve(region_id, req.retrieveConfig) res.status(200).json({ region }) } + +export class AdminGetRegionsRegionParams extends FindParams {} diff --git a/packages/medusa/src/api/routes/admin/regions/index.ts b/packages/medusa/src/api/routes/admin/regions/index.ts index 767d759fe8..98cbef6bde 100644 --- a/packages/medusa/src/api/routes/admin/regions/index.ts +++ b/packages/medusa/src/api/routes/admin/regions/index.ts @@ -1,10 +1,12 @@ -import { FlagRouter } from "@medusajs/utils" +import { FlagRouter, wrapHandler } from "@medusajs/utils" import { Router } from "express" import "reflect-metadata" import { Region } from "../../../.." import TaxInclusivePricingFeatureFlag from "../../../../loaders/feature-flags/tax-inclusive-pricing" import { DeleteResponse, PaginatedResponse } from "../../../../types/common" -import middlewares from "../../../middlewares" +import { transformQuery } from "../../../middlewares" +import getRegion, { AdminGetRegionsRegionParams } from "./get-region" +import listRegions, { AdminGetRegionsParams } from "./list-regions" const route = Router() @@ -15,50 +17,65 @@ export default (app, featureFlagRouter: FlagRouter) => { defaultAdminRegionFields.push("includes_tax") } - route.get("/", middlewares.wrap(require("./list-regions").default)) - route.get("/:region_id", middlewares.wrap(require("./get-region").default)) + const retrieveTransformQueryConfig = { + defaultFields: defaultAdminRegionFields, + defaultRelations: defaultAdminRegionRelations, + allowedRelations: defaultAdminRegionRelations, + isList: false, + } + + const listTransformQueryConfig = { + ...retrieveTransformQueryConfig, + isList: true, + } + + route.get( + "/", + transformQuery(AdminGetRegionsParams, listTransformQueryConfig), + wrapHandler(listRegions) + ) + + route.get( + "/:region_id", + transformQuery(AdminGetRegionsRegionParams, retrieveTransformQueryConfig), + wrapHandler(getRegion) + ) route.get( "/:region_id/fulfillment-options", - middlewares.wrap(require("./get-fulfillment-options").default) + wrapHandler(require("./get-fulfillment-options").default) ) - route.post("/", middlewares.wrap(require("./create-region").default)) - route.post( - "/:region_id", - middlewares.wrap(require("./update-region").default) - ) + route.post("/", wrapHandler(require("./create-region").default)) + route.post("/:region_id", wrapHandler(require("./update-region").default)) - route.delete( - "/:region_id", - middlewares.wrap(require("./delete-region").default) - ) + route.delete("/:region_id", wrapHandler(require("./delete-region").default)) route.post( "/:region_id/countries", - middlewares.wrap(require("./add-country").default) + wrapHandler(require("./add-country").default) ) route.delete( "/:region_id/countries/:country_code", - middlewares.wrap(require("./remove-country").default) + wrapHandler(require("./remove-country").default) ) route.post( "/:region_id/payment-providers", - middlewares.wrap(require("./add-payment-provider").default) + wrapHandler(require("./add-payment-provider").default) ) route.delete( "/:region_id/payment-providers/:provider_id", - middlewares.wrap(require("./remove-payment-provider").default) + wrapHandler(require("./remove-payment-provider").default) ) route.post( "/:region_id/fulfillment-providers", - middlewares.wrap(require("./add-fulfillment-provider").default) + wrapHandler(require("./add-fulfillment-provider").default) ) route.delete( "/:region_id/fulfillment-providers/:provider_id", - middlewares.wrap(require("./remove-fulfillment-provider").default) + wrapHandler(require("./remove-fulfillment-provider").default) ) return app @@ -83,6 +100,7 @@ export const defaultAdminRegionRelations = [ "countries", "payment_providers", "fulfillment_providers", + "currency", ] /** diff --git a/packages/medusa/src/api/routes/admin/regions/list-regions.ts b/packages/medusa/src/api/routes/admin/regions/list-regions.ts index b0f09fc747..031537aa8d 100644 --- a/packages/medusa/src/api/routes/admin/regions/list-regions.ts +++ b/packages/medusa/src/api/routes/admin/regions/list-regions.ts @@ -1,12 +1,10 @@ -import { IsInt, IsOptional, ValidateNested } from "class-validator" -import _, { identity } from "lodash" -import { defaultAdminRegionFields, defaultAdminRegionRelations } from "." - -import { DateComparisonOperator } from "../../../../types/common" -import { Region } from "../../../.." -import RegionService from "../../../../services/region" import { Type } from "class-transformer" -import { validator } from "../../../../utils/validator" +import { IsOptional, ValidateNested } from "class-validator" +import RegionService from "../../../../services/region" +import { + DateComparisonOperator, + extendedFindParamsMixin, +} from "../../../../types/common" /** * @oas [get] /admin/regions @@ -144,59 +142,29 @@ import { validator } from "../../../../utils/validator" * $ref: "#/components/responses/500_error" */ export default async (req, res) => { - const validated = await validator(AdminGetRegionsParams, req.query) - const regionService: RegionService = req.scope.resolve("regionService") - - const filterableFields = _.omit(validated, ["limit", "offset"]) - - const listConfig = { - select: defaultAdminRegionFields, - relations: defaultAdminRegionRelations, - skip: validated.offset, - take: validated.limit, - } + const { limit, offset } = req.validatedQuery const [regions, count] = await regionService.listAndCount( - _.pickBy(filterableFields, identity), - listConfig + req.filterableFields, + req.listConfig ) res.json({ regions, count, - offset: validated.offset, - limit: validated.limit, + offset, + limit, }) } -/** - * {@inheritDoc FindPaginationParams} - */ -export class AdminGetRegionsPaginationParams { - /** - * {@inheritDoc FindPaginationParams.limit} - * @defaultValue 50 - */ - @IsInt() - @IsOptional() - @Type(() => Number) - limit?: number = 50 - - /** - * {@inheritDoc FindPaginationParams.offset} - * @defaultValue 0 - */ - @IsInt() - @IsOptional() - @Type(() => Number) - offset?: number = 0 -} - /** * Parameters used to filter and configure the pagination of the retrieved regions. */ -export class AdminGetRegionsParams extends AdminGetRegionsPaginationParams { +export class AdminGetRegionsParams extends extendedFindParamsMixin({ + limit: 50, + offset: 0, +}) { /** * Date filters to apply on the regions' `created_at` date. */ diff --git a/packages/medusa/src/api/routes/store/index.js b/packages/medusa/src/api/routes/store/index.js index 19f60502ec..c2629d4fee 100644 --- a/packages/medusa/src/api/routes/store/index.js +++ b/packages/medusa/src/api/routes/store/index.js @@ -48,7 +48,7 @@ export default (app, container, config) => { orderEditRoutes(route) cartRoutes(route, container) shippingOptionRoutes(route) - regionRoutes(route) + regionRoutes(route, featureFlagRouter) swapRoutes(route) variantRoutes(route) returnRoutes(route) diff --git a/packages/medusa/src/api/routes/store/regions/__tests__/get-region.js b/packages/medusa/src/api/routes/store/regions/__tests__/get-region.js index 3434718c65..cc13e0948e 100644 --- a/packages/medusa/src/api/routes/store/regions/__tests__/get-region.js +++ b/packages/medusa/src/api/routes/store/regions/__tests__/get-region.js @@ -23,8 +23,23 @@ describe("Get region by id", () => { { relations: [ "countries", - "payment_providers", + "currency", "fulfillment_providers", + "payment_providers", + ], + select: [ + "id", + "name", + "currency_code", + "tax_rate", + "tax_code", + "gift_cards_taxable", + "automatic_taxes", + "tax_provider_id", + "metadata", + "created_at", + "updated_at", + "deleted_at", ], } ) diff --git a/packages/medusa/src/api/routes/store/regions/__tests__/list-regions.js b/packages/medusa/src/api/routes/store/regions/__tests__/list-regions.js index 6d55a2a749..5fba8918ab 100644 --- a/packages/medusa/src/api/routes/store/regions/__tests__/list-regions.js +++ b/packages/medusa/src/api/routes/store/regions/__tests__/list-regions.js @@ -1,6 +1,6 @@ import { IdMap } from "medusa-test-utils" -import { RegionServiceMock } from "../../../../../services/__mocks__/region" import { request } from "../../../../../helpers/test-request" +import { RegionServiceMock } from "../../../../../services/__mocks__/region" describe("List regions", () => { describe("list regions", () => { @@ -20,11 +20,27 @@ describe("List regions", () => { { relations: [ "countries", - "payment_providers", + "currency", "fulfillment_providers", + "payment_providers", + ], + select: [ + "id", + "name", + "currency_code", + "tax_rate", + "tax_code", + "gift_cards_taxable", + "automatic_taxes", + "tax_provider_id", + "metadata", + "created_at", + "updated_at", + "deleted_at", ], skip: 0, take: 100, + order: { created_at: "DESC" }, } ) }) diff --git a/packages/medusa/src/api/routes/store/regions/get-region.ts b/packages/medusa/src/api/routes/store/regions/get-region.ts index 3719c9bf3b..e4a195cc87 100644 --- a/packages/medusa/src/api/routes/store/regions/get-region.ts +++ b/packages/medusa/src/api/routes/store/regions/get-region.ts @@ -1,5 +1,5 @@ import RegionService from "../../../../services/region" -import { defaultRelations } from "." +import { FindParams } from "../../../../types/common" /** * @oas [get] /store/regions/{id} @@ -46,12 +46,11 @@ import { defaultRelations } from "." */ export default async (req, res) => { const { region_id } = req.params - const regionService: RegionService = req.scope.resolve("regionService") - const region = await regionService.retrieve(region_id, { - relations: defaultRelations, - }) + const region = await regionService.retrieve(region_id, req.retrieveConfig) res.json({ region }) } + +export class StoreGetRegionsRegionParams extends FindParams {} diff --git a/packages/medusa/src/api/routes/store/regions/index.ts b/packages/medusa/src/api/routes/store/regions/index.ts index 958d2828ff..8c2efcb9e2 100644 --- a/packages/medusa/src/api/routes/store/regions/index.ts +++ b/packages/medusa/src/api/routes/store/regions/index.ts @@ -1,23 +1,67 @@ import { PaginatedResponse } from "@medusajs/types" -import { Region } from "./../../../../" +import { TaxInclusivePricingFeatureFlag, wrapHandler } from "@medusajs/utils" import { Router } from "express" -import middlewares from "../../../middlewares" +import { transformQuery } from "../../../middlewares" +import { Region } from "./../../../../" +import getRegion from "./get-region" +import listRegions, { StoreGetRegionsParams } from "./list-regions" const route = Router() -export default (app) => { +export default (app, featureFlagRouter) => { + if (featureFlagRouter.isFeatureEnabled(TaxInclusivePricingFeatureFlag.key)) { + defaultStoreRegionFields.push("includes_tax") + } + + const retrieveTransformQueryConfig = { + defaultFields: defaultStoreRegionFields, + defaultRelations: defaultStoreRegionRelations, + allowedRelations: defaultStoreRegionRelations, + isList: false, + } + + const listTransformQueryConfig = { + ...retrieveTransformQueryConfig, + isList: true, + } + app.use("/regions", route) - route.get("/", middlewares.wrap(require("./list-regions").default)) - route.get("/:region_id", middlewares.wrap(require("./get-region").default)) + route.get( + "/", + transformQuery(StoreGetRegionsParams, listTransformQueryConfig), + wrapHandler(listRegions) + ) + + route.get( + "/:region_id", + transformQuery(StoreGetRegionsParams, retrieveTransformQueryConfig), + wrapHandler(getRegion) + ) return app } -export const defaultRelations = [ +export const defaultStoreRegionRelations = [ "countries", "payment_providers", "fulfillment_providers", + "currency", +] + +export const defaultStoreRegionFields = [ + "id", + "name", + "currency_code", + "tax_rate", + "tax_code", + "gift_cards_taxable", + "automatic_taxes", + "tax_provider_id", + "metadata", + "created_at", + "updated_at", + "deleted_at", ] /** diff --git a/packages/medusa/src/api/routes/store/regions/list-regions.ts b/packages/medusa/src/api/routes/store/regions/list-regions.ts index 44b95f9f5a..ce08ad221d 100644 --- a/packages/medusa/src/api/routes/store/regions/list-regions.ts +++ b/packages/medusa/src/api/routes/store/regions/list-regions.ts @@ -1,11 +1,11 @@ -import { IsInt, IsOptional, ValidateNested } from "class-validator" +import { IsOptional, ValidateNested } from "class-validator" -import { DateComparisonOperator } from "../../../../types/common" -import RegionService from "../../../../services/region" import { Type } from "class-transformer" -import { defaultRelations } from "." -import { omit } from "lodash" -import { validator } from "../../../../utils/validator" +import RegionService from "../../../../services/region" +import { + DateComparisonOperator, + extendedFindParamsMixin, +} from "../../../../types/common" /** * @oas [get] /store/regions @@ -101,38 +101,21 @@ import { validator } from "../../../../utils/validator" * $ref: "#/components/responses/500_error" */ export default async (req, res) => { - const validated = await validator(StoreGetRegionsParams, req.query) - const { limit, offset } = validated - const regionService: RegionService = req.scope.resolve("regionService") - - const filterableFields = omit(validated, ["limit", "offset"]) - - const listConfig = { - relations: defaultRelations, - skip: offset, - take: limit, - } + const { limit, offset } = req.validatedQuery const [regions, count] = await regionService.listAndCount( - filterableFields, - listConfig + req.filterableFields, + req.listConfig ) res.json({ regions, count, limit, offset }) } -export class StoreGetRegionsParams { - @IsOptional() - @IsInt() - @Type(() => Number) - limit?: number = 100 - - @IsOptional() - @IsInt() - @Type(() => Number) - offset?: number = 0 - +export class StoreGetRegionsParams extends extendedFindParamsMixin({ + limit: 100, + offset: 0, +}) { @IsOptional() @ValidateNested() @Type(() => DateComparisonOperator)