diff --git a/integration-tests/modules/__tests__/shipping-options/admin/shipping-options.spec.ts b/integration-tests/modules/__tests__/shipping-options/admin/shipping-options.spec.ts index 7a647d78d5..3e248186a7 100644 --- a/integration-tests/modules/__tests__/shipping-options/admin/shipping-options.spec.ts +++ b/integration-tests/modules/__tests__/shipping-options/admin/shipping-options.spec.ts @@ -237,8 +237,7 @@ medusaIntegrationTestRunner({ const shippingOptionId = response.data.shipping_option.id - const updateShippingOptionPayload = { - } + const updateShippingOptionPayload = {} let err = await api .post( @@ -337,6 +336,54 @@ medusaIntegrationTestRunner({ ) }) }) + + describe("DELETE /admin/shipping-options/:id", () => { + it("should delete a shipping option successfully", async () => { + const shippingOptionPayload = { + name: "Test shipping option", + service_zone_id: fulfillmentSet.service_zones[0].id, + shipping_profile_id: shippingProfile.id, + provider_id: "manual_test-provider", + price_type: "flat", + type: { + label: "Test type", + description: "Test description", + code: "test-code", + }, + prices: [ + { + currency_code: "usd", + amount: 1000, + }, + { + region_id: region.id, + amount: 1000, + }, + ], + rules: [shippingOptionRule], + } + + const response = await api.post( + `/admin/shipping-options`, + shippingOptionPayload, + adminHeaders + ) + + const shippingOptionId = response.data.shipping_option.id + + await api.delete( + `/admin/shipping-options/${shippingOptionId}`, + adminHeaders + ) + + const shippingOptions = await api.get( + `/admin/shipping-options`, + adminHeaders + ) + + expect(shippingOptions.data.shipping_options).toHaveLength(0) + }) + }) }) }, }) diff --git a/integration-tests/modules/__tests__/shipping-options/workflows/delete-shipping-options.ts b/integration-tests/modules/__tests__/shipping-options/workflows/delete-shipping-options.ts new file mode 100644 index 0000000000..c9f6a35384 --- /dev/null +++ b/integration-tests/modules/__tests__/shipping-options/workflows/delete-shipping-options.ts @@ -0,0 +1,263 @@ +import { ModuleRegistrationName } from "@medusajs/modules-sdk" +import { + FulfillmentSetDTO, + FulfillmentWorkflow, + IFulfillmentModuleService, + IRegionModuleService, + ServiceZoneDTO, + ShippingProfileDTO, +} from "@medusajs/types" +import { medusaIntegrationTestRunner } from "medusa-test-utils/dist" +import { + createShippingOptionsWorkflow, + deleteShippingOptionsWorkflow, +} from "@medusajs/core-flows" +import { + ContainerRegistrationKeys, + remoteQueryObjectFromString, + RuleOperator, +} from "@medusajs/utils" + +jest.setTimeout(100000) + +const env = { MEDUSA_FF_MEDUSA_V2: true } +const provider_id = "manual_test-provider" + +medusaIntegrationTestRunner({ + env, + testSuite: ({ getContainer }) => { + let service: IFulfillmentModuleService + let container + + beforeAll(() => { + container = getContainer() + service = container.resolve(ModuleRegistrationName.FULFILLMENT) + }) + + describe("Fulfillment workflows", () => { + let fulfillmentSet: FulfillmentSetDTO + let serviceZone: ServiceZoneDTO + let shippingProfile: ShippingProfileDTO + + beforeEach(async () => { + shippingProfile = await service.createShippingProfiles({ + name: "test", + type: "default", + }) + + fulfillmentSet = await service.create({ + name: "Test fulfillment set", + type: "manual_test", + }) + + serviceZone = await service.createServiceZones({ + name: "Test service zone", + fulfillment_set_id: fulfillmentSet.id, + geo_zones: [ + { + type: "country", + country_code: "US", + }, + ], + }) + }) + + it("should delete shipping options", async () => { + const regionService = container.resolve( + ModuleRegistrationName.REGION + ) as IRegionModuleService + + const [region] = await regionService.create([ + { + name: "Test region", + currency_code: "eur", + countries: ["fr"], + }, + ]) + + const shippingOptionData: FulfillmentWorkflow.CreateShippingOptionsWorkflowInput = + { + name: "Test shipping option", + price_type: "flat", + service_zone_id: serviceZone.id, + shipping_profile_id: shippingProfile.id, + provider_id, + type: { + code: "manual-type", + label: "Manual Type", + description: "Manual Type Description", + }, + prices: [ + { + currency_code: "usd", + amount: 10, + }, + { + region_id: region.id, + amount: 100, + }, + ], + rules: [ + { + attribute: "total", + operator: RuleOperator.EQ, + value: "100", + }, + ], + } + + const { result } = await createShippingOptionsWorkflow(container).run({ + input: [shippingOptionData], + }) + + await deleteShippingOptionsWorkflow(container).run({ + input: { ids: [result[0].id] }, + }) + + const remoteQuery = container.resolve( + ContainerRegistrationKeys.REMOTE_QUERY + ) + + const remoteQueryObject = remoteQueryObjectFromString({ + entryPoint: "shipping_option", + variables: { + id: result[0].id, + }, + fields: [ + "id", + "name", + "price_type", + "service_zone_id", + "shipping_profile_id", + "provider_id", + "data", + "metadata", + "type.*", + "created_at", + "updated_at", + "deleted_at", + "shipping_option_type_id", + "prices.*", + ], + }) + + const createdShippingOption = await remoteQuery(remoteQueryObject) + expect(createdShippingOption).toHaveLength(0) + }) + + it("should revert the deleted shipping options", async () => { + const regionService = container.resolve( + ModuleRegistrationName.REGION + ) as IRegionModuleService + + const [region] = await regionService.create([ + { + name: "Test region", + currency_code: "eur", + countries: ["fr"], + }, + ]) + + const shippingOptionData: FulfillmentWorkflow.CreateShippingOptionsWorkflowInput = + { + name: "Test shipping option", + price_type: "flat", + service_zone_id: serviceZone.id, + shipping_profile_id: shippingProfile.id, + provider_id, + type: { + code: "manual-type", + label: "Manual Type", + description: "Manual Type Description", + }, + prices: [ + { + currency_code: "usd", + amount: 10, + }, + { + region_id: region.id, + amount: 100, + }, + ], + rules: [ + { + attribute: "total", + operator: RuleOperator.EQ, + value: "100", + }, + ], + } + + const deleteWorkflow = await deleteShippingOptionsWorkflow(container) + + deleteWorkflow.addAction( + "throw", + { + invoke: async function failStep() { + throw new Error(`Failed to delete shipping options`) + }, + }, + { + noCompensation: true, + } + ) + + const { result } = await createShippingOptionsWorkflow(container).run({ + input: [shippingOptionData], + }) + + const { errors } = await deleteWorkflow.run({ + input: { ids: [result[0].id] }, + throwOnError: false, + }) + + expect(errors).toHaveLength(1) + expect(errors[0].error.message).toEqual( + `Failed to delete shipping options` + ) + + const remoteQuery = container.resolve( + ContainerRegistrationKeys.REMOTE_QUERY + ) + + const remoteQueryObject = remoteQueryObjectFromString({ + entryPoint: "shipping_option", + fields: [ + "id", + "name", + "price_type", + "service_zone_id", + "shipping_profile_id", + "provider_id", + "data", + "metadata", + "type.*", + "created_at", + "updated_at", + "deleted_at", + "shipping_option_type_id", + ], + }) + + const createdShippingOptions = await remoteQuery(remoteQueryObject) + + expect(createdShippingOptions).toHaveLength(1) + expect(createdShippingOptions[0]).toEqual( + expect.objectContaining({ + name: shippingOptionData.name, + price_type: shippingOptionData.price_type, + service_zone_id: serviceZone.id, + shipping_profile_id: shippingProfile.id, + provider_id: provider_id, + data: null, + metadata: null, + type: expect.objectContaining({ + id: expect.any(String), + }), + }) + ) + }) + }) + }, +}) diff --git a/packages/core-flows/src/fulfillment/steps/delete-shipping-options.ts b/packages/core-flows/src/fulfillment/steps/delete-shipping-options.ts new file mode 100644 index 0000000000..ff6f2133a9 --- /dev/null +++ b/packages/core-flows/src/fulfillment/steps/delete-shipping-options.ts @@ -0,0 +1,41 @@ +import { + DeleteEntityInput, + ModuleRegistrationName, +} from "@medusajs/modules-sdk" +import { IFulfillmentModuleService } from "@medusajs/types" +import { createStep, StepResponse } from "@medusajs/workflows-sdk" +import { Modules } from "@medusajs/utils" + +export const deleteShippingOptionsStepId = "delete-shipping-options-step" +export const deleteShippingOptionsStep = createStep( + deleteShippingOptionsStepId, + async (ids: string[], { container }) => { + if (!ids?.length) { + return + } + + const service = container.resolve( + ModuleRegistrationName.FULFILLMENT + ) + + const softDeletedEntities = await service.softDeleteShippingOptions(ids) + + return new StepResponse( + { + [Modules.FULFILLMENT]: softDeletedEntities, + } as DeleteEntityInput, + ids + ) + }, + async (prevIds, { container }) => { + if (!prevIds?.length) { + return + } + + const service = container.resolve( + ModuleRegistrationName.FULFILLMENT + ) + + await service.restoreShippingOptions(prevIds) + } +) diff --git a/packages/core-flows/src/fulfillment/steps/index.ts b/packages/core-flows/src/fulfillment/steps/index.ts index f9ce27234b..33b35f206d 100644 --- a/packages/core-flows/src/fulfillment/steps/index.ts +++ b/packages/core-flows/src/fulfillment/steps/index.ts @@ -4,5 +4,6 @@ export * from "./create-fulfillment-set" export * from "./create-service-zones" export * from "./upsert-shipping-options" export * from "./delete-service-zones" +export * from "./delete-shipping-options" export * from "./create-shipping-profiles" export * from "./remove-rules-from-fulfillment-shipping-option" diff --git a/packages/core-flows/src/fulfillment/workflows/delete-shipping-options.ts b/packages/core-flows/src/fulfillment/workflows/delete-shipping-options.ts new file mode 100644 index 0000000000..b588f4f00f --- /dev/null +++ b/packages/core-flows/src/fulfillment/workflows/delete-shipping-options.ts @@ -0,0 +1,17 @@ +import { FulfillmentWorkflow } from "@medusajs/types" +import { createWorkflow, WorkflowData } from "@medusajs/workflows-sdk" +import { deleteShippingOptionsStep } from "../steps" +import { removeRemoteLinkStep } from "../../common" + +export const deleteShippingOptionsWorkflowId = + "delete-shipping-options-workflow" +export const deleteShippingOptionsWorkflow = createWorkflow( + deleteShippingOptionsWorkflowId, + ( + input: WorkflowData + ) => { + const softDeletedEntities = deleteShippingOptionsStep(input.ids) + + removeRemoteLinkStep(softDeletedEntities) + } +) diff --git a/packages/core-flows/src/fulfillment/workflows/index.ts b/packages/core-flows/src/fulfillment/workflows/index.ts index c3f198ed52..ea0602ebe9 100644 --- a/packages/core-flows/src/fulfillment/workflows/index.ts +++ b/packages/core-flows/src/fulfillment/workflows/index.ts @@ -3,6 +3,7 @@ export * from "./create-service-zones" export * from "./create-shipping-options" export * from "./create-shipping-profiles" export * from "./delete-service-zones" +export * from "./delete-shipping-options" export * from "./remove-rules-from-fulfillment-shipping-option" export * from "./update-service-zones" export * from "./update-shipping-options" diff --git a/packages/medusa-test-utils/src/medusa-test-runner-utils/use-db.js b/packages/medusa-test-utils/src/medusa-test-runner-utils/use-db.js index e28eaf0687..78970c33e1 100644 --- a/packages/medusa-test-utils/src/medusa-test-runner-utils/use-db.js +++ b/packages/medusa-test-utils/src/medusa-test-runner-utils/use-db.js @@ -9,7 +9,6 @@ const { } = require("@medusajs/utils") const { DataSource } = require("typeorm") const { ContainerRegistrationKeys } = require("@medusajs/utils") -const { migrateMedusaApp } = require("@medusajs/medusa/dist/loaders/medusa-app") const { logger } = require("@medusajs/medusa-cli/dist/reporter") module.exports = { @@ -114,6 +113,9 @@ module.exports = { featureFlagRouter: asValue(featureFlagRouter), }) + const { + migrateMedusaApp, + } = require("@medusajs/medusa/dist/loaders/medusa-app") await migrateMedusaApp( { configModule, container }, { registerInContainer: false } diff --git a/packages/medusa/src/api-v2/admin/shipping-options/[id]/route.ts b/packages/medusa/src/api-v2/admin/shipping-options/[id]/route.ts index 3e4e993035..1796b1b944 100644 --- a/packages/medusa/src/api-v2/admin/shipping-options/[id]/route.ts +++ b/packages/medusa/src/api-v2/admin/shipping-options/[id]/route.ts @@ -2,9 +2,15 @@ import { ContainerRegistrationKeys, remoteQueryObjectFromString, } from "@medusajs/utils" -import { AdminShippingOptionRetrieveResponse } from "@medusajs/types" +import { + AdminShippingOptionDeleteResponse, + AdminShippingOptionRetrieveResponse, +} from "@medusajs/types" import { AdminUpdateShippingOptionType } from "../validators" -import { updateShippingOptionsWorkflow } from "@medusajs/core-flows" +import { + deleteShippingOptionsWorkflow, + updateShippingOptionsWorkflow, +} from "@medusajs/core-flows" import { AuthenticatedMedusaRequest, MedusaResponse, @@ -42,3 +48,25 @@ export const POST = async ( res.status(200).json({ shipping_option: shippingOption }) } + +export const DELETE = async ( + req: AuthenticatedMedusaRequest, + res: MedusaResponse +) => { + const shippingOptionId = req.params.id + + const workflow = deleteShippingOptionsWorkflow(req.scope) + + const { errors } = await workflow.run({ + input: { ids: [shippingOptionId] }, + throwOnError: false, + }) + + if (Array.isArray(errors) && errors[0]) { + throw errors[0].error + } + + res + .status(200) + .json({ id: shippingOptionId, object: "shipping_option", deleted: true }) +} diff --git a/packages/medusa/src/api-v2/admin/shipping-options/middlewares.ts b/packages/medusa/src/api-v2/admin/shipping-options/middlewares.ts index ece6240c46..c13c8650c3 100644 --- a/packages/medusa/src/api-v2/admin/shipping-options/middlewares.ts +++ b/packages/medusa/src/api-v2/admin/shipping-options/middlewares.ts @@ -3,11 +3,15 @@ import { authenticate } from "../../../utils/authenticate-middleware" import { AdminCreateShippingOption, AdminGetShippingOptionParams, + AdminListShippingOptionParams, AdminShippingOptionRulesBatchAdd, AdminShippingOptionRulesBatchRemove, AdminUpdateShippingOption, } from "./validators" -import { retrieveTransformQueryConfig } from "./query-config" +import { + listTransformQueryConfig, + retrieveTransformQueryConfig, +} from "./query-config" import { validateAndTransformBody } from "../../utils/validate-body" import { validateAndTransformQuery } from "../../utils/validate-query" @@ -17,6 +21,17 @@ export const adminShippingOptionRoutesMiddlewares: MiddlewareRoute[] = [ middlewares: [authenticate("admin", ["bearer", "session"])], }, + { + method: ["GET"], + matcher: "/admin/shipping-options", + middlewares: [ + validateAndTransformQuery( + AdminListShippingOptionParams, + listTransformQueryConfig + ), + ], + }, + { method: ["POST"], matcher: "/admin/shipping-options", @@ -41,6 +56,11 @@ export const adminShippingOptionRoutesMiddlewares: MiddlewareRoute[] = [ ], }, + { + method: ["DELETE"], + matcher: "/admin/shipping-options/:id", + }, + { method: ["POST"], matcher: "/admin/shipping-options/:id/rules/batch/add", diff --git a/packages/medusa/src/api-v2/admin/shipping-options/route.ts b/packages/medusa/src/api-v2/admin/shipping-options/route.ts index f548583ca0..344a551dba 100644 --- a/packages/medusa/src/api-v2/admin/shipping-options/route.ts +++ b/packages/medusa/src/api-v2/admin/shipping-options/route.ts @@ -3,13 +3,43 @@ import { ContainerRegistrationKeys, remoteQueryObjectFromString, } from "@medusajs/utils" -import { AdminShippingOptionRetrieveResponse } from "@medusajs/types" +import { + AdminShippingOptionListResponse, + AdminShippingOptionRetrieveResponse +} from "@medusajs/types" import { AuthenticatedMedusaRequest, MedusaResponse, } from "../../../types/routing" import { AdminCreateShippingOptionType } from "./validators" +export const GET = async ( + req: AuthenticatedMedusaRequest, + res: MedusaResponse +) => { + const remoteQuery = req.scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY) + + const variables = { + filters: req.filterableFields, + ...req.remoteQueryConfig.pagination, + } + + const queryObject = remoteQueryObjectFromString({ + entryPoint: "shipping_options", + variables, + fields: req.remoteQueryConfig.fields, + }) + + const { rows: shipping_options, metadata } = await remoteQuery(queryObject) + + res.json({ + shipping_options, + count: metadata.count, + offset: metadata.skip, + limit: metadata.take, + }) +} + export const POST = async ( req: AuthenticatedMedusaRequest, res: MedusaResponse diff --git a/packages/medusa/src/api-v2/admin/shipping-options/validators.ts b/packages/medusa/src/api-v2/admin/shipping-options/validators.ts index 813100f8b5..da95a5c5f2 100644 --- a/packages/medusa/src/api-v2/admin/shipping-options/validators.ts +++ b/packages/medusa/src/api-v2/admin/shipping-options/validators.ts @@ -3,9 +3,13 @@ import { ShippingOptionPriceType as ShippingOptionPriceTypeEnum, } from "@medusajs/utils" import { z } from "zod" -import { createSelectParams } from "../../utils/validators" +import { createFindParams, createSelectParams } from "../../utils/validators" export const AdminGetShippingOptionParams = createSelectParams() +export const AdminListShippingOptionParams = createFindParams({ + offset: 0, + limit: 20, +}) /** * SHIPPING OPTIONS RULES @@ -99,4 +103,4 @@ export const AdminUpdateShippingOption = z export type AdminUpdateShippingOptionType = z.infer< typeof AdminUpdateShippingOption -> \ No newline at end of file +> diff --git a/packages/types/src/http/common/deleted-response.ts b/packages/types/src/http/common/deleted-response.ts new file mode 100644 index 0000000000..a446c109dd --- /dev/null +++ b/packages/types/src/http/common/deleted-response.ts @@ -0,0 +1,19 @@ +/** + * The fields returned in the response of a DELETE request. + */ +export type DeleteResponse = { + /** + * The ID of the item that was deleted. + */ + id: string + + /** + * The type of the item that was deleted. + */ + object: string + + /** + * Whether the item was deleted successfully. + */ + deleted: boolean +} diff --git a/packages/types/src/http/common/index.ts b/packages/types/src/http/common/index.ts index 0f115a0712..7ff7d9a964 100644 --- a/packages/types/src/http/common/index.ts +++ b/packages/types/src/http/common/index.ts @@ -1 +1,2 @@ export * from "./paginated-response" +export * from "./deleted-response" diff --git a/packages/types/src/http/fulfillment/admin/shipping-option.ts b/packages/types/src/http/fulfillment/admin/shipping-option.ts index c96e7b8b1f..3f7cbea2fc 100644 --- a/packages/types/src/http/fulfillment/admin/shipping-option.ts +++ b/packages/types/src/http/fulfillment/admin/shipping-option.ts @@ -5,6 +5,7 @@ import { AdminShippingOptionRuleResponse } from "./shipping-option-rule" import { AdminShippingProfileResponse } from "./shipping-profile" import { AdminFulfillmentProviderResponse } from "./fulfillment-provider" import { AdminPriceSetPriceResponse } from "../../pricing" +import { DeleteResponse, PaginatedResponse } from "../../common" /** * @experimental @@ -34,5 +35,17 @@ interface AdminShippingOptionResponse { * @experimental */ export interface AdminShippingOptionRetrieveResponse { - shipping_option: AdminShippingOptionResponse[] + shipping_option: AdminShippingOptionResponse } + +/** + * @experimental + */ +export interface AdminShippingOptionListResponse extends PaginatedResponse { + shipping_options: AdminShippingOptionResponse[] +} + +/** + * @experimental + */ +export interface AdminShippingOptionDeleteResponse extends DeleteResponse {} diff --git a/packages/types/src/workflow/fulfillment/delete-shipping-options.ts b/packages/types/src/workflow/fulfillment/delete-shipping-options.ts new file mode 100644 index 0000000000..b50212e171 --- /dev/null +++ b/packages/types/src/workflow/fulfillment/delete-shipping-options.ts @@ -0,0 +1,3 @@ +export interface DeleteShippingOptionsWorkflowInput { + ids: string[] +} diff --git a/packages/types/src/workflow/fulfillment/index.ts b/packages/types/src/workflow/fulfillment/index.ts index 8ac89fcc92..97932e5585 100644 --- a/packages/types/src/workflow/fulfillment/index.ts +++ b/packages/types/src/workflow/fulfillment/index.ts @@ -1,4 +1,5 @@ export * from "./create-shipping-options" export * from "./service-zones" +export * from "./delete-shipping-options" export * from "./shipping-profiles" export * from "./update-shipping-options" diff --git a/packages/utils/src/modules-sdk/__tests__/abstract-module-service-factory.spec.ts b/packages/utils/src/modules-sdk/__tests__/abstract-module-service-factory.spec.ts index 59717981ec..140e301a1a 100644 --- a/packages/utils/src/modules-sdk/__tests__/abstract-module-service-factory.spec.ts +++ b/packages/utils/src/modules-sdk/__tests__/abstract-module-service-factory.spec.ts @@ -115,7 +115,7 @@ describe("Abstract Module Service Factory", () => { it("should have softDelete method", async () => { const result = await instance.softDelete("1") - expect(result).toEqual(undefined) + expect(result).toEqual({}) expect( containerMock.mainModelMockService.softDelete ).toHaveBeenCalledWith(["1"], defaultTransactionContext) @@ -123,7 +123,7 @@ describe("Abstract Module Service Factory", () => { it("should have restore method", async () => { const result = await instance.restore("1") - expect(result).toEqual(undefined) + expect(result).toEqual({}) expect(containerMock.mainModelMockService.restore).toHaveBeenCalledWith( ["1"], defaultTransactionContext @@ -175,7 +175,7 @@ describe("Abstract Module Service Factory", () => { it("should have softDelete method for other models", async () => { const result = await instance.softDeleteOtherModelMock1s("1") - expect(result).toEqual(undefined) + expect(result).toEqual({}) expect( containerMock.otherModelMock1Service.softDelete ).toHaveBeenCalledWith(["1"], defaultTransactionContext) @@ -183,7 +183,7 @@ describe("Abstract Module Service Factory", () => { it("should have restore method for other models", async () => { const result = await instance.restoreOtherModelMock1s("1") - expect(result).toEqual(undefined) + expect(result).toEqual({}) expect(containerMock.otherModelMock1Service.restore).toHaveBeenCalledWith( ["1"], defaultTransactionContext diff --git a/packages/utils/src/modules-sdk/abstract-module-service-factory.ts b/packages/utils/src/modules-sdk/abstract-module-service-factory.ts index 366ff35f5b..6e6ab83048 100644 --- a/packages/utils/src/modules-sdk/abstract-module-service-factory.ts +++ b/packages/utils/src/modules-sdk/abstract-module-service-factory.ts @@ -12,11 +12,11 @@ import { SoftDeleteReturn, } from "@medusajs/types" import { - MapToConfig, isString, kebabCase, lowerCaseFirst, mapObjectTo, + MapToConfig, pluralize, upperCaseFirst, } from "../common" @@ -505,18 +505,15 @@ export function abstractModuleServiceFactory< })) ) - let mappedCascadedEntitiesMap - if (config.returnLinkableKeys) { - // Map internal table/column names to their respective external linkable keys - // eg: product.id = product_id, variant.id = variant_id - mappedCascadedEntitiesMap = mapObjectTo( - cascadedEntitiesMap, - entityNameToLinkableKeysMap, - { - pick: config.returnLinkableKeys, - } - ) - } + // Map internal table/column names to their respective external linkable keys + // eg: product.id = product_id, variant.id = variant_id + const mappedCascadedEntitiesMap = mapObjectTo( + cascadedEntitiesMap, + entityNameToLinkableKeysMap, + { + pick: config.returnLinkableKeys, + } + ) return mappedCascadedEntitiesMap ? mappedCascadedEntitiesMap : void 0 } @@ -540,17 +537,15 @@ export function abstractModuleServiceFactory< ].restore(primaryKeyValues_, sharedContext) let mappedCascadedEntitiesMap - if (config.returnLinkableKeys) { - // Map internal table/column names to their respective external linkable keys - // eg: product.id = product_id, variant.id = variant_id - mappedCascadedEntitiesMap = mapObjectTo( - cascadedEntitiesMap, - entityNameToLinkableKeysMap, - { - pick: config.returnLinkableKeys, - } - ) - } + // Map internal table/column names to their respective external linkable keys + // eg: product.id = product_id, variant.id = variant_id + mappedCascadedEntitiesMap = mapObjectTo( + cascadedEntitiesMap, + entityNameToLinkableKeysMap, + { + pick: config.returnLinkableKeys, + } + ) return mappedCascadedEntitiesMap ? mappedCascadedEntitiesMap : void 0 }