diff --git a/integration-tests/api/__tests__/admin/api-key.spec.ts b/integration-tests/api/__tests__/admin/api-key.spec.ts index 5974c9f489..45b3d3d096 100644 --- a/integration-tests/api/__tests__/admin/api-key.spec.ts +++ b/integration-tests/api/__tests__/admin/api-key.spec.ts @@ -188,14 +188,19 @@ medusaIntegrationTestRunner({ const { api_key } = apiKeyRes.data const keyWithChannelsRes = await api.post( - `/admin/api-keys/${api_key.id}/sales-channels/batch`, + `/admin/api-keys/${api_key.id}/sales-channels`, { - create: [sales_channel.id], + add: [sales_channel.id], }, adminHeaders ) - const { api_key: keyWithChannels } = keyWithChannelsRes.data + const keyWithChannels = ( + await api.get( + `/admin/api-keys/${api_key.id}?fields=*sales_channels`, + adminHeaders + ) + ).data.api_key expect(keyWithChannelsRes.status).toEqual(200) expect(keyWithChannels.title).toEqual("Test publishable KEY") @@ -229,9 +234,9 @@ medusaIntegrationTestRunner({ const errorRes = await api .post( - `/admin/api-keys/${apiKeyRes.data.api_key.id}/sales-channels/batch`, + `/admin/api-keys/${apiKeyRes.data.api_key.id}/sales-channels`, { - create: [sales_channel.id], + add: [sales_channel.id], }, adminHeaders ) @@ -255,9 +260,9 @@ medusaIntegrationTestRunner({ const errorRes = await api .post( - `/admin/api-keys/${apiKeyRes.data.api_key.id}/sales-channels/batch`, + `/admin/api-keys/${apiKeyRes.data.api_key.id}/sales-channels`, { - create: ["phony"], + add: ["phony"], }, adminHeaders ) @@ -292,14 +297,19 @@ medusaIntegrationTestRunner({ const { api_key } = apiKeyRes.data const keyWithChannelsRes = await api.post( - `/admin/api-keys/${api_key.id}/sales-channels/batch`, + `/admin/api-keys/${api_key.id}/sales-channels`, { - create: [sales_channel.id], + add: [sales_channel.id], }, adminHeaders ) - const { api_key: keyWithChannels } = keyWithChannelsRes.data + const keyWithChannels = ( + await api.get( + `/admin/api-keys/${api_key.id}?fields=*sales_channels`, + adminHeaders + ) + ).data.api_key expect(keyWithChannelsRes.status).toEqual(200) expect(keyWithChannels.title).toEqual("Test publishable KEY") @@ -311,14 +321,19 @@ medusaIntegrationTestRunner({ ]) const keyWithoutChannelsRes = await api.post( - `/admin/api-keys/${api_key.id}/sales-channels/batch`, + `/admin/api-keys/${api_key.id}/sales-channels`, { - delete: [sales_channel.id], + remove: [sales_channel.id], }, adminHeaders ) - const { api_key: keyWithoutChannels } = keyWithoutChannelsRes.data + const keyWithoutChannels = ( + await api.get( + `/admin/api-keys/${api_key.id}?fields=*sales_channels`, + adminHeaders + ) + ).data.api_key expect(keyWithoutChannelsRes.status).toEqual(200) expect(keyWithoutChannels.title).toEqual("Test publishable KEY") @@ -348,14 +363,19 @@ medusaIntegrationTestRunner({ const { api_key } = apiKeyRes.data const keyWithChannelsRes = await api.post( - `/admin/api-keys/${api_key.id}/sales-channels/batch`, + `/admin/api-keys/${api_key.id}/sales-channels`, { - create: [sales_channel.id], + add: [sales_channel.id], }, adminHeaders ) - const { api_key: keyWithChannels } = keyWithChannelsRes.data + const keyWithChannels = ( + await api.get( + `/admin/api-keys/${api_key.id}?fields=*sales_channels`, + adminHeaders + ) + ).data.api_key expect(keyWithChannelsRes.status).toEqual(200) expect(keyWithChannels.title).toEqual("Test publishable KEY") diff --git a/integration-tests/api/__tests__/admin/product.js b/integration-tests/api/__tests__/admin/product.js index fe79f23fc3..74b5f68cd0 100644 --- a/integration-tests/api/__tests__/admin/product.js +++ b/integration-tests/api/__tests__/admin/product.js @@ -2998,8 +2998,7 @@ medusaIntegrationTestRunner({ ) expect(response.status).toEqual(200) - expect(response.data.added).toHaveLength(1) - expect(response.data.removed).toHaveLength(1) + expect(response.data.collection).toBeTruthy() const collection = ( await api.get( diff --git a/integration-tests/api/__tests__/admin/reservations/index.spec.ts b/integration-tests/api/__tests__/admin/reservations/index.spec.ts index 6ace323dd8..4d50a4a331 100644 --- a/integration-tests/api/__tests__/admin/reservations/index.spec.ts +++ b/integration-tests/api/__tests__/admin/reservations/index.spec.ts @@ -318,9 +318,9 @@ medusaIntegrationTestRunner({ scId = scResponse.data.sales_channel.id await api.post( - `/admin/stock-locations/${location}/sales-channels/batch/add`, + `/admin/stock-locations/${location}/sales-channels`, { - sales_channel_ids: [scId], + add: [scId], }, adminHeaders ) diff --git a/integration-tests/api/__tests__/admin/sales-channels.js b/integration-tests/api/__tests__/admin/sales-channels.js index d23ca22243..5503473ce6 100644 --- a/integration-tests/api/__tests__/admin/sales-channels.js +++ b/integration-tests/api/__tests__/admin/sales-channels.js @@ -827,7 +827,7 @@ medusaIntegrationTestRunner({ describe("POST /admin/sales-channels/:id/products/batch", () => { // BREAKING CHANGE: Endpoint has changed // from: /admin/sales-channels/:id/products/batch - // to: /admin/sales-channels/:id/products/batch/add + // to: /admin/sales-channels/:id/products let { salesChannel, product } = {} @@ -860,12 +860,14 @@ medusaIntegrationTestRunner({ }) it("should add products to a sales channel", async () => { - const payload = { - product_ids: breaking( - () => [{ id: product.id }], - () => [product.id] - ), - } + const payload = breaking( + () => ({ + product_ids: [{ id: product.id }], + }), + () => ({ + add: [product.id], + }) + ) const response = await breaking( async () => { @@ -877,7 +879,7 @@ medusaIntegrationTestRunner({ }, async () => { return await api.post( - `/admin/sales-channels/${salesChannel.id}/products/batch/add`, + `/admin/sales-channels/${salesChannel.id}/products`, payload, adminReqConfig ) diff --git a/integration-tests/api/__tests__/admin/stock-location/index.spec.ts b/integration-tests/api/__tests__/admin/stock-location/index.spec.ts index 6b4ae025af..f3e090adb0 100644 --- a/integration-tests/api/__tests__/admin/stock-location/index.spec.ts +++ b/integration-tests/api/__tests__/admin/stock-location/index.spec.ts @@ -308,8 +308,8 @@ medusaIntegrationTestRunner({ it("should add sales channels to a location", async () => { const salesChannelResponse = await api.post( - `/admin/stock-locations/${location.id}/sales-channels/batch/add?fields=*sales_channels`, - { sales_channel_ids: [salesChannel.id] }, + `/admin/stock-locations/${location.id}/sales-channels?fields=*sales_channels`, + { add: [salesChannel.id] }, adminHeaders ) @@ -356,16 +356,16 @@ medusaIntegrationTestRunner({ location = locationResponse.data.stock_location await api.post( - `/admin/stock-locations/${location.id}/sales-channels/batch/add?fields=*sales_channels`, - { sales_channel_ids: [salesChannel1.id, salesChannel2.id] }, + `/admin/stock-locations/${location.id}/sales-channels?fields=*sales_channels`, + { add: [salesChannel1.id, salesChannel2.id] }, adminHeaders ) }) it("should remove sales channels from a location", async () => { const salesChannelResponse = await api.post( - `/admin/stock-locations/${location.id}/sales-channels/batch/remove?fields=*sales_channels`, - { sales_channel_ids: [salesChannel1.id] }, + `/admin/stock-locations/${location.id}/sales-channels?fields=*sales_channels`, + { remove: [salesChannel1.id] }, adminHeaders ) diff --git a/integration-tests/modules/__tests__/customer-group/admin/batch-add-customers.ts b/integration-tests/modules/__tests__/customer-group/admin/batch-add-customers.ts index 054bb6cf7b..ffb79dfed4 100644 --- a/integration-tests/modules/__tests__/customer-group/admin/batch-add-customers.ts +++ b/integration-tests/modules/__tests__/customer-group/admin/batch-add-customers.ts @@ -13,7 +13,7 @@ const adminHeaders = { medusaIntegrationTestRunner({ env, testSuite: ({ dbConnection, getContainer, api }) => { - describe("POST /admin/customer-groups/:id/customers/batch", () => { + describe("POST /admin/customer-groups/:id/customers", () => { let appContainer let customerModuleService: ICustomerModuleService @@ -48,9 +48,9 @@ medusaIntegrationTestRunner({ ]) const response = await api.post( - `/admin/customer-groups/${group.id}/customers/batch`, + `/admin/customer-groups/${group.id}/customers`, { - create: customers.map((c) => c.id), + add: customers.map((c) => c.id), }, adminHeaders ) diff --git a/integration-tests/modules/__tests__/customer-group/admin/batch-remove-customers.ts b/integration-tests/modules/__tests__/customer-group/admin/batch-remove-customers.ts index 33a905151e..d6ed7200f7 100644 --- a/integration-tests/modules/__tests__/customer-group/admin/batch-remove-customers.ts +++ b/integration-tests/modules/__tests__/customer-group/admin/batch-remove-customers.ts @@ -13,7 +13,7 @@ const adminHeaders = { medusaIntegrationTestRunner({ env, testSuite: ({ dbConnection, getContainer, api }) => { - describe("POST /admin/customer-groups/:id/customers/batch", () => { + describe("POST /admin/customer-groups/:id/customers", () => { let appContainer let customerModuleService: ICustomerModuleService @@ -55,9 +55,9 @@ medusaIntegrationTestRunner({ ) const response = await api.post( - `/admin/customer-groups/${group.id}/customers/batch`, + `/admin/customer-groups/${group.id}/customers`, { - delete: customers.map((c) => c.id), + remove: customers.map((c) => c.id), }, adminHeaders ) diff --git a/packages/core-flows/src/api-key/steps/associate-sales-channels-with-publishable-keys.ts b/packages/core-flows/src/api-key/steps/associate-sales-channels-with-publishable-keys.ts deleted file mode 100644 index 31c477a543..0000000000 --- a/packages/core-flows/src/api-key/steps/associate-sales-channels-with-publishable-keys.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { Modules } from "@medusajs/modules-sdk" -import { ContainerRegistrationKeys } from "@medusajs/utils" -import { StepResponse, createStep } from "@medusajs/workflows-sdk" - -interface StepInput { - links: { - api_key_id: string - sales_channel_ids: string[] - }[] -} - -export const associateApiKeysWithSalesChannelsStepId = - "associate-sales-channels-with-api-keys" -export const associateApiKeysWithSalesChannelsStep = createStep( - associateApiKeysWithSalesChannelsStepId, - async (input: StepInput, { container }) => { - const remoteLink = container.resolve(ContainerRegistrationKeys.REMOTE_LINK) - - if (!input.links) { - return - } - - const links = input.links - .map((link) => { - return link.sales_channel_ids.map((id) => { - return { - [Modules.API_KEY]: { - publishable_key_id: link.api_key_id, - }, - [Modules.SALES_CHANNEL]: { - sales_channel_id: id, - }, - } - }) - }) - .flat() - - const createdLinks = await remoteLink.create(links) - - return new StepResponse(createdLinks, links) - }, - async (links, { container }) => { - if (!links) { - return - } - - const remoteLink = container.resolve(ContainerRegistrationKeys.REMOTE_LINK) - - await remoteLink.dismiss(links) - } -) diff --git a/packages/core-flows/src/api-key/steps/detach-sales-channels-from-publishable-keys.ts b/packages/core-flows/src/api-key/steps/detach-sales-channels-from-publishable-keys.ts deleted file mode 100644 index d9f37dd945..0000000000 --- a/packages/core-flows/src/api-key/steps/detach-sales-channels-from-publishable-keys.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { Modules } from "@medusajs/modules-sdk" -import { ContainerRegistrationKeys } from "@medusajs/utils" -import { StepResponse, createStep } from "@medusajs/workflows-sdk" - -interface StepInput { - links: { - api_key_id: string - sales_channel_ids: string[] - }[] -} - -export const detachApiKeysWithSalesChannelsStepId = - "detach-sales-channels-with-api-keys" -export const detachApiKeysWithSalesChannelsStep = createStep( - detachApiKeysWithSalesChannelsStepId, - async (input: StepInput, { container }) => { - const remoteLink = container.resolve(ContainerRegistrationKeys.REMOTE_LINK) - - const links = input.links - .map((link) => { - return link.sales_channel_ids.map((id) => { - return { - [Modules.API_KEY]: { - publishable_key_id: link.api_key_id, - }, - [Modules.SALES_CHANNEL]: { - sales_channel_id: id, - }, - } - }) - }) - .flat() - - await remoteLink.dismiss(links) - - return new StepResponse(void 0, links) - }, - async (links, { container }) => { - if (!links?.length) { - return - } - - const remoteLink = container.resolve(ContainerRegistrationKeys.REMOTE_LINK) - - await remoteLink.create(links) - } -) diff --git a/packages/core-flows/src/api-key/steps/index.ts b/packages/core-flows/src/api-key/steps/index.ts index 2c5337e318..b41b8693ac 100644 --- a/packages/core-flows/src/api-key/steps/index.ts +++ b/packages/core-flows/src/api-key/steps/index.ts @@ -1,7 +1,6 @@ -export * from "./associate-sales-channels-with-publishable-keys" +export * from "./link-sales-channels-to-publishable-key" export * from "./create-api-keys" export * from "./delete-api-keys" -export * from "./detach-sales-channels-from-publishable-keys" export * from "./revoke-api-keys" export * from "./update-api-keys" export * from "./validate-sales-channel-exists" diff --git a/packages/core-flows/src/api-key/steps/link-sales-channels-to-publishable-key.ts b/packages/core-flows/src/api-key/steps/link-sales-channels-to-publishable-key.ts new file mode 100644 index 0000000000..a11d2d774a --- /dev/null +++ b/packages/core-flows/src/api-key/steps/link-sales-channels-to-publishable-key.ts @@ -0,0 +1,62 @@ +import { Modules } from "@medusajs/modules-sdk" +import { LinkWorkflowInput } from "@medusajs/types/src" +import { ContainerRegistrationKeys, promiseAll } from "@medusajs/utils" +import { StepResponse, createStep } from "@medusajs/workflows-sdk" + +export const linkSalesChannelsToApiKeyStepId = "link-sales-channels-to-api-key" +export const linkSalesChannelsToApiKeyStep = createStep( + linkSalesChannelsToApiKeyStepId, + async (input: LinkWorkflowInput, { container }) => { + const remoteLink = container.resolve(ContainerRegistrationKeys.REMOTE_LINK) + if (!input || (!input.add?.length && !input.remove?.length)) { + return + } + + const linksToCreate = (input.add ?? []).map((salesChannelId) => { + return { + [Modules.API_KEY]: { + publishable_key_id: input.id, + }, + [Modules.SALES_CHANNEL]: { + sales_channel_id: salesChannelId, + }, + } + }) + + const linksToDismiss = (input.remove ?? []).map((salesChannelId) => { + return { + [Modules.API_KEY]: { + publishable_key_id: input.id, + }, + [Modules.SALES_CHANNEL]: { + sales_channel_id: salesChannelId, + }, + } + }) + + const promises: Promise[] = [] + if (linksToCreate.length) { + promises.push(remoteLink.create(linksToCreate)) + } + if (linksToDismiss.length) { + promises.push(remoteLink.dismiss(linksToDismiss)) + } + await promiseAll(promises) + + return new StepResponse(void 0, { linksToCreate, linksToDismiss }) + }, + async (prevData, { container }) => { + if (!prevData) { + return + } + + const remoteLink = container.resolve(ContainerRegistrationKeys.REMOTE_LINK) + if (prevData.linksToCreate.length) { + await remoteLink.dismiss(prevData.linksToCreate) + } + + if (prevData.linksToDismiss.length) { + await remoteLink.create(prevData.linksToDismiss) + } + } +) diff --git a/packages/core-flows/src/api-key/workflows/add-sales-channels-to-publishable-key.ts b/packages/core-flows/src/api-key/workflows/add-sales-channels-to-publishable-key.ts deleted file mode 100644 index 2e43647175..0000000000 --- a/packages/core-flows/src/api-key/workflows/add-sales-channels-to-publishable-key.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { - WorkflowData, - createWorkflow, - transform, -} from "@medusajs/workflows-sdk" -import { - associateApiKeysWithSalesChannelsStep, - validateSalesChannelsExistStep, -} from "../steps" - -type WorkflowInput = { - data: { - api_key_id: string - sales_channel_ids: string[] - }[] -} - -export const addSalesChannelsToApiKeyWorkflowId = - "add-sales-channels-to-api-key" -export const addSalesChannelsToApiKeyWorkflow = createWorkflow( - addSalesChannelsToApiKeyWorkflowId, - (input: WorkflowData) => { - const salesChannelIds = transform(input.data, (data) => - data.map((d) => d.sales_channel_ids).flat() - ) - validateSalesChannelsExistStep({ - sales_channel_ids: salesChannelIds, - }) - associateApiKeysWithSalesChannelsStep({ links: input.data }) - } -) diff --git a/packages/core-flows/src/api-key/workflows/index.ts b/packages/core-flows/src/api-key/workflows/index.ts index b817357753..cb223e6778 100644 --- a/packages/core-flows/src/api-key/workflows/index.ts +++ b/packages/core-flows/src/api-key/workflows/index.ts @@ -2,5 +2,4 @@ export * from "./create-api-keys" export * from "./delete-api-keys" export * from "./update-api-keys" export * from "./revoke-api-keys" -export * from "./add-sales-channels-to-publishable-key" -export * from "./remove-sales-channels-from-publishable-key" +export * from "./link-sales-channels-to-publishable-key" diff --git a/packages/core-flows/src/api-key/workflows/link-sales-channels-to-publishable-key.ts b/packages/core-flows/src/api-key/workflows/link-sales-channels-to-publishable-key.ts new file mode 100644 index 0000000000..0f53b539a0 --- /dev/null +++ b/packages/core-flows/src/api-key/workflows/link-sales-channels-to-publishable-key.ts @@ -0,0 +1,19 @@ +import { WorkflowData, createWorkflow } from "@medusajs/workflows-sdk" +import { + linkSalesChannelsToApiKeyStep, + validateSalesChannelsExistStep, +} from "../steps" +import { LinkWorkflowInput } from "@medusajs/types/src" + +export const linkSalesChannelsToApiKeyWorkflowId = + "link-sales-channels-to-api-key" +export const linkSalesChannelsToApiKeyWorkflow = createWorkflow( + linkSalesChannelsToApiKeyWorkflowId, + (input: WorkflowData) => { + validateSalesChannelsExistStep({ + sales_channel_ids: input.add ?? [], + }) + + linkSalesChannelsToApiKeyStep(input) + } +) diff --git a/packages/core-flows/src/api-key/workflows/remove-sales-channels-from-publishable-key.ts b/packages/core-flows/src/api-key/workflows/remove-sales-channels-from-publishable-key.ts deleted file mode 100644 index e02c11aab8..0000000000 --- a/packages/core-flows/src/api-key/workflows/remove-sales-channels-from-publishable-key.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { WorkflowData, createWorkflow } from "@medusajs/workflows-sdk" -import { detachApiKeysWithSalesChannelsStep } from "../steps/detach-sales-channels-from-publishable-keys" - -type WorkflowInput = { - data: { - api_key_id: string - sales_channel_ids: string[] - }[] -} - -export const removeSalesChannelsFromApiKeyWorkflowId = - "remove-sales-channels-from-api-key" -export const removeSalesChannelsFromApiKeyWorkflow = createWorkflow( - removeSalesChannelsFromApiKeyWorkflowId, - (input: WorkflowData) => { - detachApiKeysWithSalesChannelsStep({ links: input.data }) - } -) diff --git a/packages/core-flows/src/customer-group/steps/create-customer-group-customers.ts b/packages/core-flows/src/customer-group/steps/create-customer-group-customers.ts deleted file mode 100644 index cb31cf738d..0000000000 --- a/packages/core-flows/src/customer-group/steps/create-customer-group-customers.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { GroupCustomerPair, ICustomerModuleService } from "@medusajs/types" -import { StepResponse, createStep } from "@medusajs/workflows-sdk" -import { ModuleRegistrationName } from "@medusajs/modules-sdk" - -export const createCustomerGroupCustomersStepId = - "create-customer-group-customers" -export const createCustomerGroupCustomersStep = createStep( - createCustomerGroupCustomersStepId, - async (data: GroupCustomerPair[], { container }) => { - const service = container.resolve( - ModuleRegistrationName.CUSTOMER - ) - - const groupPairs = await service.addCustomerToGroup(data) - - return new StepResponse(groupPairs, data) - }, - async (groupPairs, { container }) => { - if (!groupPairs?.length) { - return - } - - const service = container.resolve( - ModuleRegistrationName.CUSTOMER - ) - - await service.removeCustomerFromGroup(groupPairs) - } -) diff --git a/packages/core-flows/src/customer-group/steps/index.ts b/packages/core-flows/src/customer-group/steps/index.ts index 196a19bd73..a1512feb76 100644 --- a/packages/core-flows/src/customer-group/steps/index.ts +++ b/packages/core-flows/src/customer-group/steps/index.ts @@ -1,5 +1,4 @@ export * from "./update-customer-groups" export * from "./delete-customer-groups" export * from "./create-customer-groups" -export * from "./create-customer-group-customers" -export * from "./delete-customer-group-customers" +export * from "./link-customers-customer-group" diff --git a/packages/core-flows/src/customer-group/steps/link-customers-customer-group.ts b/packages/core-flows/src/customer-group/steps/link-customers-customer-group.ts new file mode 100644 index 0000000000..5c9e7f74f9 --- /dev/null +++ b/packages/core-flows/src/customer-group/steps/link-customers-customer-group.ts @@ -0,0 +1,56 @@ +import { ICustomerModuleService } from "@medusajs/types" +import { StepResponse, createStep } from "@medusajs/workflows-sdk" +import { ModuleRegistrationName } from "@medusajs/modules-sdk" +import { LinkWorkflowInput } from "@medusajs/types/src" +import { promiseAll } from "@medusajs/utils" + +export const linkCustomersToCustomerGroupStepId = + "link-customers-to-customer-group" +export const linkCustomersToCustomerGroupStep = createStep( + linkCustomersToCustomerGroupStepId, + async (data: LinkWorkflowInput, { container }) => { + const service = container.resolve( + ModuleRegistrationName.CUSTOMER + ) + + const toAdd = (data.add ?? []).map((customerId) => { + return { + customer_id: customerId, + customer_group_id: data.id, + } + }) + + const toRemove = (data.remove ?? []).map((customerId) => { + return { + customer_id: customerId, + customer_group_id: data.id, + } + }) + + const promises: Promise[] = [] + if (toAdd.length) { + promises.push(service.addCustomerToGroup(toAdd)) + } + if (toRemove.length) { + promises.push(service.removeCustomerFromGroup(toRemove)) + } + await promiseAll(promises) + + return new StepResponse(void 0, { toAdd, toRemove }) + }, + async (prevData, { container }) => { + if (!prevData) { + return + } + const service = container.resolve( + ModuleRegistrationName.CUSTOMER + ) + + if (prevData.toAdd.length) { + await service.removeCustomerFromGroup(prevData.toAdd) + } + if (prevData.toRemove.length) { + await service.addCustomerToGroup(prevData.toRemove) + } + } +) diff --git a/packages/core-flows/src/customer-group/workflows/create-customer-group-customers.ts b/packages/core-flows/src/customer-group/workflows/create-customer-group-customers.ts deleted file mode 100644 index 6a3da2d856..0000000000 --- a/packages/core-flows/src/customer-group/workflows/create-customer-group-customers.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { GroupCustomerPair } from "@medusajs/types" -import { WorkflowData, createWorkflow } from "@medusajs/workflows-sdk" -import { createCustomerGroupCustomersStep } from "../steps" - -type WorkflowInput = { groupCustomers: GroupCustomerPair[] } - -export const createCustomerGroupCustomersWorkflowId = - "create-customer-group-customers" -export const createCustomerGroupCustomersWorkflow = createWorkflow( - createCustomerGroupCustomersWorkflowId, - (input: WorkflowData): WorkflowData<{ id: string }[]> => { - return createCustomerGroupCustomersStep(input.groupCustomers) - } -) diff --git a/packages/core-flows/src/customer-group/workflows/delete-customer-group-customers.ts b/packages/core-flows/src/customer-group/workflows/delete-customer-group-customers.ts deleted file mode 100644 index 7696a36cc5..0000000000 --- a/packages/core-flows/src/customer-group/workflows/delete-customer-group-customers.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { GroupCustomerPair } from "@medusajs/types" -import { WorkflowData, createWorkflow } from "@medusajs/workflows-sdk" -import { deleteCustomerGroupCustomersStep } from "../steps" - -type WorkflowInput = { groupCustomers: GroupCustomerPair[] } - -export const deleteCustomerGroupCustomersWorkflowId = - "delete-customer-group-customers" -export const deleteCustomerGroupCustomersWorkflow = createWorkflow( - deleteCustomerGroupCustomersWorkflowId, - (input: WorkflowData): WorkflowData => { - return deleteCustomerGroupCustomersStep(input.groupCustomers) - } -) diff --git a/packages/core-flows/src/customer-group/workflows/index.ts b/packages/core-flows/src/customer-group/workflows/index.ts index 196a19bd73..a1512feb76 100644 --- a/packages/core-flows/src/customer-group/workflows/index.ts +++ b/packages/core-flows/src/customer-group/workflows/index.ts @@ -1,5 +1,4 @@ export * from "./update-customer-groups" export * from "./delete-customer-groups" export * from "./create-customer-groups" -export * from "./create-customer-group-customers" -export * from "./delete-customer-group-customers" +export * from "./link-customers-customer-group" diff --git a/packages/core-flows/src/customer-group/workflows/link-customers-customer-group.ts b/packages/core-flows/src/customer-group/workflows/link-customers-customer-group.ts new file mode 100644 index 0000000000..b9a810e1ba --- /dev/null +++ b/packages/core-flows/src/customer-group/workflows/link-customers-customer-group.ts @@ -0,0 +1,12 @@ +import { WorkflowData, createWorkflow } from "@medusajs/workflows-sdk" +import { linkCustomersToCustomerGroupStep } from "../steps" +import { LinkWorkflowInput } from "@medusajs/types/src" + +export const linkCustomersToCustomerGroupWorkflowId = + "link-customers-to-customer-group" +export const linkCustomersToCustomerGroupWorkflow = createWorkflow( + linkCustomersToCustomerGroupWorkflowId, + (input: WorkflowData): WorkflowData => { + return linkCustomersToCustomerGroupStep(input) + } +) diff --git a/packages/core-flows/src/product/steps/batch-link-products-collection.ts b/packages/core-flows/src/product/steps/batch-link-products-collection.ts index e31eaa3b2f..c6e13059ce 100644 --- a/packages/core-flows/src/product/steps/batch-link-products-collection.ts +++ b/packages/core-flows/src/product/steps/batch-link-products-collection.ts @@ -1,13 +1,13 @@ import { ModuleRegistrationName } from "@medusajs/modules-sdk" import { IProductModuleService } from "@medusajs/types" -import { BatchLinkProductsToCollectionDTO } from "@medusajs/types/src" +import { LinkWorkflowInput } from "@medusajs/types/src" import { StepResponse, createStep } from "@medusajs/workflows-sdk" export const batchLinkProductsToCollectionStepId = "batch-link-products-to-collection" export const batchLinkProductsToCollectionStep = createStep( batchLinkProductsToCollectionStepId, - async (data: BatchLinkProductsToCollectionDTO, { container }) => { + async (data: LinkWorkflowInput, { container }) => { const service = container.resolve( ModuleRegistrationName.PRODUCT ) diff --git a/packages/core-flows/src/product/steps/batch-product-variants.ts b/packages/core-flows/src/product/steps/batch-product-variants.ts index 0bf7fe6046..2cad65450b 100644 --- a/packages/core-flows/src/product/steps/batch-product-variants.ts +++ b/packages/core-flows/src/product/steps/batch-product-variants.ts @@ -2,33 +2,33 @@ import { StepResponse, createStep } from "@medusajs/workflows-sdk" import { deleteProductVariantsWorkflow } from "../workflows/delete-product-variants" import { createProductVariantsWorkflow } from "../workflows/create-product-variants" import { updateProductVariantsWorkflow } from "../workflows/update-product-variants" -import { PricingTypes, ProductTypes } from "@medusajs/types" - -type BatchProductVariantsInput = { - create: (ProductTypes.CreateProductVariantDTO & { - prices?: PricingTypes.CreateMoneyAmountDTO[] - })[] - update: (ProductTypes.UpsertProductVariantDTO & { - prices?: PricingTypes.CreateMoneyAmountDTO[] - })[] - delete: string[] -} +import { + BatchWorkflowInput, + CreateProductVariantWorkflowInputDTO, + UpdateProductVariantWorkflowInputDTO, +} from "@medusajs/types" export const batchProductVariantsStepId = "batch-product-variants" export const batchProductVariantsStep = createStep( batchProductVariantsStepId, - async (data: BatchProductVariantsInput, { container }) => { + async ( + data: BatchWorkflowInput< + CreateProductVariantWorkflowInputDTO, + UpdateProductVariantWorkflowInputDTO + >, + { container } + ) => { const { transaction: createTransaction, result: created } = await createProductVariantsWorkflow(container).run({ - input: { product_variants: data.create }, + input: { product_variants: data.create ?? [] }, }) const { transaction: updateTransaction, result: updated } = await updateProductVariantsWorkflow(container).run({ - input: { product_variants: data.update }, + input: { product_variants: data.update ?? [] }, }) const { transaction: deleteTransaction } = await deleteProductVariantsWorkflow(container).run({ - input: { ids: data.delete }, + input: { ids: data.delete ?? [] }, }) return new StepResponse( @@ -36,7 +36,7 @@ export const batchProductVariantsStep = createStep( created, updated, deleted: { - ids: data.delete, + ids: data.delete ?? [], object: "product_variant", deleted: true, }, diff --git a/packages/core-flows/src/product/steps/batch-products.ts b/packages/core-flows/src/product/steps/batch-products.ts index 4818c45afe..09291c2d4d 100644 --- a/packages/core-flows/src/product/steps/batch-products.ts +++ b/packages/core-flows/src/product/steps/batch-products.ts @@ -2,37 +2,34 @@ import { StepResponse, createStep } from "@medusajs/workflows-sdk" import { createProductsWorkflow } from "../workflows/create-products" import { updateProductsWorkflow } from "../workflows/update-products" import { deleteProductsWorkflow } from "../workflows/delete-products" -import { PricingTypes, ProductTypes } from "@medusajs/types" - -type WorkflowInput = { - create: (Omit & { - sales_channels?: { id: string }[] - variants?: (ProductTypes.CreateProductVariantDTO & { - prices?: PricingTypes.CreateMoneyAmountDTO[] - })[] - })[] - update: (ProductTypes.UpsertProductDTO & { - sales_channels?: { id: string }[] - })[] - delete: string[] -} +import { + BatchWorkflowInput, + CreateProductWorkflowInputDTO, + UpdateProductWorkflowInputDTO, +} from "@medusajs/types" export const batchProductsStepId = "batch-products" export const batchProductsStep = createStep( batchProductsStepId, - async (data: WorkflowInput, { container }) => { + async ( + data: BatchWorkflowInput< + CreateProductWorkflowInputDTO, + UpdateProductWorkflowInputDTO + >, + { container } + ) => { const { transaction: createTransaction, result: created } = await createProductsWorkflow(container).run({ - input: { products: data.create }, + input: { products: data.create ?? [] }, }) const { transaction: updateTransaction, result: updated } = await updateProductsWorkflow(container).run({ - input: { products: data.update }, + input: { products: data.update ?? [] }, }) const { transaction: deleteTransaction } = await deleteProductsWorkflow( container ).run({ - input: { ids: data.delete }, + input: { ids: data.delete ?? [] }, }) return new StepResponse( @@ -40,7 +37,7 @@ export const batchProductsStep = createStep( created, updated, deleted: { - ids: data.delete, + ids: data.delete ?? [], object: "product", deleted: true, }, diff --git a/packages/core-flows/src/product/workflows/batch-link-products-collection.ts b/packages/core-flows/src/product/workflows/batch-link-products-collection.ts index 23c67eb1cc..11d7b13b89 100644 --- a/packages/core-flows/src/product/workflows/batch-link-products-collection.ts +++ b/packages/core-flows/src/product/workflows/batch-link-products-collection.ts @@ -1,14 +1,12 @@ import { WorkflowData, createWorkflow } from "@medusajs/workflows-sdk" -import { BatchLinkProductsToCollectionDTO } from "@medusajs/types/src" +import { LinkWorkflowInput } from "@medusajs/types/src" import { batchLinkProductsToCollectionStep } from "../steps/batch-link-products-collection" export const batchLinkProductsToCollectionWorkflowId = "batch-link-products-to-collection" export const batchLinkProductsToCollectionWorkflow = createWorkflow( batchLinkProductsToCollectionWorkflowId, - ( - input: WorkflowData - ): WorkflowData => { + (input: WorkflowData): WorkflowData => { return batchLinkProductsToCollectionStep(input) } ) diff --git a/packages/core-flows/src/product/workflows/batch-product-variants.ts b/packages/core-flows/src/product/workflows/batch-product-variants.ts index 2b058e1087..54caed576f 100644 --- a/packages/core-flows/src/product/workflows/batch-product-variants.ts +++ b/packages/core-flows/src/product/workflows/batch-product-variants.ts @@ -1,33 +1,24 @@ import { WorkflowData, createWorkflow } from "@medusajs/workflows-sdk" import { batchProductVariantsStep } from "../steps/batch-product-variants" -import { PricingTypes, ProductTypes } from "@medusajs/types" - -type BatchProductVariantsInput = { - create: (ProductTypes.CreateProductVariantDTO & { - prices?: PricingTypes.CreateMoneyAmountDTO[] - })[] - update: (ProductTypes.UpsertProductVariantDTO & { - prices?: PricingTypes.CreateMoneyAmountDTO[] - })[] - delete: string[] -} - -type BatchProductVariantsOutput = { - created: ProductTypes.ProductVariantDTO[] - updated: ProductTypes.ProductVariantDTO[] - deleted: { - ids: string[] - object: string - deleted: boolean - } -} +import { + BatchWorkflowInput, + BatchWorkflowOutput, + ProductTypes, + UpdateProductVariantWorkflowInputDTO, + CreateProductVariantWorkflowInputDTO, +} from "@medusajs/types" export const batchProductVariantsWorkflowId = "batch-product-variants" export const batchProductVariantsWorkflow = createWorkflow( batchProductVariantsWorkflowId, ( - input: WorkflowData - ): WorkflowData => { + input: WorkflowData< + BatchWorkflowInput< + CreateProductVariantWorkflowInputDTO, + UpdateProductVariantWorkflowInputDTO + > + > + ): WorkflowData> => { return batchProductVariantsStep(input) } ) diff --git a/packages/core-flows/src/product/workflows/batch-products.ts b/packages/core-flows/src/product/workflows/batch-products.ts index 26a09f8439..3d60535369 100644 --- a/packages/core-flows/src/product/workflows/batch-products.ts +++ b/packages/core-flows/src/product/workflows/batch-products.ts @@ -1,34 +1,24 @@ import { WorkflowData, createWorkflow } from "@medusajs/workflows-sdk" import { batchProductsStep } from "../steps/batch-products" -import { PricingTypes, ProductTypes } from "@medusajs/types" - -type WorkflowInput = { - create: (Omit & { - sales_channels?: { id: string }[] - variants?: (ProductTypes.CreateProductVariantDTO & { - prices?: PricingTypes.CreateMoneyAmountDTO[] - })[] - })[] - update: (ProductTypes.UpsertProductDTO & { - sales_channels?: { id: string }[] - })[] - delete: string[] -} - -type BatchProductsOutput = { - created: ProductTypes.ProductDTO[] - updated: ProductTypes.ProductDTO[] - deleted: { - ids: string[] - object: string - deleted: boolean - } -} +import { + ProductTypes, + BatchWorkflowInput, + CreateProductWorkflowInputDTO, + UpdateProductWorkflowInputDTO, +} from "@medusajs/types" +import { BatchWorkflowOutput } from "@medusajs/types/src" export const batchProductsWorkflowId = "batch-products" export const batchProductsWorkflow = createWorkflow( batchProductsWorkflowId, - (input: WorkflowData): WorkflowData => { + ( + input: WorkflowData< + BatchWorkflowInput< + CreateProductWorkflowInputDTO, + UpdateProductWorkflowInputDTO + > + > + ): WorkflowData> => { return batchProductsStep(input) } ) diff --git a/packages/core-flows/src/product/workflows/create-products.ts b/packages/core-flows/src/product/workflows/create-products.ts index 9a3e27f830..4d9aac1e13 100644 --- a/packages/core-flows/src/product/workflows/create-products.ts +++ b/packages/core-flows/src/product/workflows/create-products.ts @@ -8,16 +8,10 @@ import { createProductsStep } from "../steps/create-products" import { createVariantPricingLinkStep } from "../steps/create-variant-pricing-link" import { createPriceSetsStep } from "../../pricing" import { associateProductsWithSalesChannelsStep } from "../../sales-channel" +import { CreateProductWorkflowInputDTO } from "@medusajs/types/src" -// TODO: We should have separate types here as input, not the module DTO. Eg. the HTTP request that we are handling -// has different data than the DTO, so that needs to be represented differently. type WorkflowInput = { - products: (Omit & { - sales_channels?: { id: string }[] - variants?: (ProductTypes.CreateProductVariantDTO & { - prices?: PricingTypes.CreateMoneyAmountDTO[] - })[] - })[] + products: CreateProductWorkflowInputDTO[] } export const createProductsWorkflowId = "create-products" diff --git a/packages/core-flows/src/sales-channel/steps/associate-locations-with-channel.ts b/packages/core-flows/src/sales-channel/steps/associate-locations-with-channels.ts similarity index 54% rename from packages/core-flows/src/sales-channel/steps/associate-locations-with-channel.ts rename to packages/core-flows/src/sales-channel/steps/associate-locations-with-channels.ts index 1c8e8937bc..bd5b2b4f7a 100644 --- a/packages/core-flows/src/sales-channel/steps/associate-locations-with-channel.ts +++ b/packages/core-flows/src/sales-channel/steps/associate-locations-with-channels.ts @@ -6,38 +6,32 @@ import { Modules } from "@medusajs/modules-sdk" interface StepInput { links: { sales_channel_id: string - location_ids: string[] + location_id: string }[] } -export const associateLocationsWithChannelStepId = - "associate-locations-with-channel-step" -export const associateLocationsWithChannelStep = createStep( - associateLocationsWithChannelStepId, +export const associateLocationsWithSalesChannelsStepId = + "associate-locations-with-sales-channels-step" +export const associateLocationsWithSalesChannelsStep = createStep( + associateLocationsWithSalesChannelsStepId, async (data: StepInput, { container }) => { - if (!data.links.length) { + if (!data.links?.length) { return new StepResponse([], []) } const remoteLink = container.resolve(ContainerRegistrationKeys.REMOTE_LINK) - - const links = data.links - .map((link) => { - return link.location_ids.map((id) => { - return { - [Modules.SALES_CHANNEL]: { - sales_channel_id: link.sales_channel_id, - }, - [Modules.STOCK_LOCATION]: { - stock_location_id: id, - }, - } - }) - }) - .flat() + const links = data.links.map((link) => { + return { + [Modules.SALES_CHANNEL]: { + sales_channel_id: link.sales_channel_id, + }, + [Modules.STOCK_LOCATION]: { + stock_location_id: link.location_id, + }, + } + }) const createdLinks = await remoteLink.create(links) - return new StepResponse(createdLinks, links) }, async (links, { container }) => { @@ -46,7 +40,6 @@ export const associateLocationsWithChannelStep = createStep( } const remoteLink = container.resolve(ContainerRegistrationKeys.REMOTE_LINK) - await remoteLink.dismiss(links) } ) diff --git a/packages/core-flows/src/sales-channel/steps/associate-products-with-channels.ts b/packages/core-flows/src/sales-channel/steps/associate-products-with-channels.ts index 54059c65a8..2cb163e4c8 100644 --- a/packages/core-flows/src/sales-channel/steps/associate-products-with-channels.ts +++ b/packages/core-flows/src/sales-channel/steps/associate-products-with-channels.ts @@ -14,7 +14,7 @@ export const associateProductsWithSalesChannelsStepId = export const associateProductsWithSalesChannelsStep = createStep( associateProductsWithSalesChannelsStepId, async (input: StepInput, { container }) => { - if (!input.links.length) { + if (!input.links?.length) { return new StepResponse([], []) } diff --git a/packages/core-flows/src/sales-channel/steps/detach-locations-from-channels.ts b/packages/core-flows/src/sales-channel/steps/detach-locations-from-channels.ts new file mode 100644 index 0000000000..d746c51eba --- /dev/null +++ b/packages/core-flows/src/sales-channel/steps/detach-locations-from-channels.ts @@ -0,0 +1,48 @@ +import { Modules, RemoteLink } from "@medusajs/modules-sdk" +import { StepResponse, createStep } from "@medusajs/workflows-sdk" + +import { ContainerRegistrationKeys } from "@medusajs/utils" + +interface StepInput { + links: { + sales_channel_id: string + location_id: string + }[] +} + +export const detachLocationsFromSalesChannelsStepId = + "detach-locations-from-sales-channels" +export const detachLocationsFromSalesChannelsStep = createStep( + detachLocationsFromSalesChannelsStepId, + async (data: StepInput, { container }) => { + if (!data.links?.length) { + return new StepResponse([], []) + } + + const remoteLink = container.resolve( + ContainerRegistrationKeys.REMOTE_LINK + ) + + const links = data.links.map((link) => { + return { + [Modules.SALES_CHANNEL]: { + sales_channel_id: link.sales_channel_id, + }, + [Modules.STOCK_LOCATION]: { + stock_location_id: link.location_id, + }, + } + }) + + await remoteLink.dismiss(links) + return new StepResponse(void 0, links) + }, + async (links, { container }) => { + if (!links?.length) { + return + } + + const remoteLink = container.resolve(ContainerRegistrationKeys.REMOTE_LINK) + await remoteLink.create(links) + } +) diff --git a/packages/core-flows/src/sales-channel/steps/detach-products-from-sales-channels.ts b/packages/core-flows/src/sales-channel/steps/detach-products-from-sales-channels.ts index 548b857351..b5e3844175 100644 --- a/packages/core-flows/src/sales-channel/steps/detach-products-from-sales-channels.ts +++ b/packages/core-flows/src/sales-channel/steps/detach-products-from-sales-channels.ts @@ -14,7 +14,7 @@ export const detachProductsFromSalesChannelsStepId = export const detachProductsFromSalesChannelsStep = createStep( detachProductsFromSalesChannelsStepId, async (input: StepInput, { container }) => { - if (!input.links.length) { + if (!input.links?.length) { return new StepResponse(void 0, []) } diff --git a/packages/core-flows/src/sales-channel/steps/index.ts b/packages/core-flows/src/sales-channel/steps/index.ts index 2ab23e59fc..fcebe3f598 100644 --- a/packages/core-flows/src/sales-channel/steps/index.ts +++ b/packages/core-flows/src/sales-channel/steps/index.ts @@ -4,5 +4,5 @@ export * from "./create-sales-channels" export * from "./delete-sales-channels" export * from "./detach-products-from-sales-channels" export * from "./update-sales-channels" -export * from "./associate-locations-with-channel" -export * from "./remove-locations-from-channels" +export * from "./associate-locations-with-channels" +export * from "./detach-locations-from-channels" diff --git a/packages/core-flows/src/sales-channel/steps/remove-locations-from-channels.ts b/packages/core-flows/src/sales-channel/steps/remove-locations-from-channels.ts deleted file mode 100644 index 43b38d48ec..0000000000 --- a/packages/core-flows/src/sales-channel/steps/remove-locations-from-channels.ts +++ /dev/null @@ -1,71 +0,0 @@ -import { Modules, RemoteLink } from "@medusajs/modules-sdk" -import { StepResponse, createStep } from "@medusajs/workflows-sdk" - -import { ContainerRegistrationKeys } from "@medusajs/utils" - -export const removeLocationsFromSalesChannelStepId = - "remove-locations-from-sales-channel" -export const removeLocationsFromSalesChannelStep = createStep( - removeLocationsFromSalesChannelStepId, - async ( - data: { - sales_channel_id: string - location_ids: string[] - }[], - { container } - ) => { - if (!data.length) { - return new StepResponse([], []) - } - - const remoteLink = container.resolve( - ContainerRegistrationKeys.REMOTE_LINK - ) - - const linkModule = remoteLink.getLinkModule( - Modules.SALES_CHANNEL, - "sales_channel_id", - Modules.STOCK_LOCATION, - "stock_location_id" - ) - - if (!linkModule) { - return new StepResponse([], []) - } - - const links = data - .map((d) => - d.location_ids.map((locId) => ({ - sales_channel_id: d.sales_channel_id, - stock_location_id: locId, - })) - ) - .flat() - - await linkModule.softDelete(links) - - return new StepResponse(void 0, links) - }, - async (links, { container }) => { - if (!links?.length) { - return - } - - const remoteLink = container.resolve( - ContainerRegistrationKeys.REMOTE_LINK - ) - - const linkModule = remoteLink.getLinkModule( - Modules.SALES_CHANNEL, - "sales_channel_id", - Modules.STOCK_LOCATION, - "stock_location_id" - ) - - if (!linkModule) { - return - } - - await linkModule.restore(links) - } -) diff --git a/packages/core-flows/src/sales-channel/workflows/add-locations-to-sales-channel.ts b/packages/core-flows/src/sales-channel/workflows/add-locations-to-sales-channel.ts deleted file mode 100644 index 649a935828..0000000000 --- a/packages/core-flows/src/sales-channel/workflows/add-locations-to-sales-channel.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { WorkflowData, createWorkflow } from "@medusajs/workflows-sdk" - -import { SalesChannelDTO } from "@medusajs/types" -import { associateLocationsWithChannelStep } from "../steps" - -interface WorkflowInput { - data: { - sales_channel_id: string - location_ids: string[] - }[] -} - -export const addLocationsToSalesChannelWorkflowId = - "add-locations-to-sales-channel" -export const addLocationsToSalesChannelWorkflow = createWorkflow( - addLocationsToSalesChannelWorkflowId, - (input: WorkflowData): WorkflowData => { - return associateLocationsWithChannelStep({ links: input.data }) - } -) diff --git a/packages/core-flows/src/sales-channel/workflows/add-products-to-sales-channels.ts b/packages/core-flows/src/sales-channel/workflows/add-products-to-sales-channels.ts deleted file mode 100644 index 103c3ab38a..0000000000 --- a/packages/core-flows/src/sales-channel/workflows/add-products-to-sales-channels.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { SalesChannelDTO } from "@medusajs/types" -import { WorkflowData, createWorkflow } from "@medusajs/workflows-sdk" -import { associateProductsWithSalesChannelsStep } from "../steps/associate-products-with-channels" -import { transform } from "@medusajs/workflows-sdk" - -type WorkflowInput = { - data: { - sales_channel_id: string - product_ids: string[] - }[] -} - -export const addProductsToSalesChannelsWorkflowId = - "add-products-to-sales-channels" -export const addProductsToSalesChannelsWorkflow = createWorkflow( - addProductsToSalesChannelsWorkflowId, - (input: WorkflowData): WorkflowData => { - const links = transform({ input }, (data) => { - return data.input.data - .map(({ sales_channel_id, product_ids }) => { - return product_ids.map((product_id) => { - return { - sales_channel_id, - product_id, - } - }) - }) - .flat() - }) - - return associateProductsWithSalesChannelsStep({ links }) - } -) diff --git a/packages/core-flows/src/sales-channel/workflows/index.ts b/packages/core-flows/src/sales-channel/workflows/index.ts index 1194cbc358..4d3987c607 100644 --- a/packages/core-flows/src/sales-channel/workflows/index.ts +++ b/packages/core-flows/src/sales-channel/workflows/index.ts @@ -1,7 +1,4 @@ -export * from "./add-products-to-sales-channels" +export * from "./link-products-to-sales-channel" export * from "./create-sales-channels" export * from "./delete-sales-channels" -export * from "./remove-products-from-sales-channels" export * from "./update-sales-channels" -export * from "./add-locations-to-sales-channel" -export * from "./remove-locations-from-sales-channel" diff --git a/packages/core-flows/src/sales-channel/workflows/link-products-to-sales-channel.ts b/packages/core-flows/src/sales-channel/workflows/link-products-to-sales-channel.ts new file mode 100644 index 0000000000..415e39a994 --- /dev/null +++ b/packages/core-flows/src/sales-channel/workflows/link-products-to-sales-channel.ts @@ -0,0 +1,29 @@ +import { LinkWorkflowInput } from "@medusajs/types" +import { WorkflowData, createWorkflow } from "@medusajs/workflows-sdk" +import { associateProductsWithSalesChannelsStep } from "../steps/associate-products-with-channels" +import { transform } from "@medusajs/workflows-sdk" +import { detachProductsFromSalesChannelsStep } from "../steps" + +export const linkProductsToSalesChannelWorkflowId = + "link-products-to-sales-channel" +export const linkProductsToSalesChannelWorkflow = createWorkflow( + linkProductsToSalesChannelWorkflowId, + (input: WorkflowData): WorkflowData => { + const toAdd = transform({ input }, (data) => { + return data.input.add?.map((productId) => ({ + sales_channel_id: data.input.id, + product_id: productId, + })) + }) + + const toRemove = transform({ input }, (data) => { + return data.input.remove?.map((productId) => ({ + sales_channel_id: data.input.id, + product_id: productId, + })) + }) + + associateProductsWithSalesChannelsStep({ links: toAdd }) + detachProductsFromSalesChannelsStep({ links: toRemove }) + } +) diff --git a/packages/core-flows/src/sales-channel/workflows/remove-locations-from-sales-channel.ts b/packages/core-flows/src/sales-channel/workflows/remove-locations-from-sales-channel.ts deleted file mode 100644 index 5235cc14c7..0000000000 --- a/packages/core-flows/src/sales-channel/workflows/remove-locations-from-sales-channel.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { WorkflowData, createWorkflow } from "@medusajs/workflows-sdk" - -import { removeLocationsFromSalesChannelStep } from "../steps" - -interface WorkflowInput { - data: { - sales_channel_id: string - location_ids: string[] - }[] -} - -export const removeLocationsFromSalesChannelWorkflowId = - "remove-locations-from-sales-channel" -export const removeLocationsFromSalesChannelWorkflow = createWorkflow( - removeLocationsFromSalesChannelWorkflowId, - (input: WorkflowData): WorkflowData => { - removeLocationsFromSalesChannelStep(input.data) - } -) diff --git a/packages/core-flows/src/sales-channel/workflows/remove-products-from-sales-channels.ts b/packages/core-flows/src/sales-channel/workflows/remove-products-from-sales-channels.ts deleted file mode 100644 index 87627762f6..0000000000 --- a/packages/core-flows/src/sales-channel/workflows/remove-products-from-sales-channels.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { SalesChannelDTO } from "@medusajs/types" -import { WorkflowData, createWorkflow } from "@medusajs/workflows-sdk" -import { detachProductsFromSalesChannelsStep } from "../steps/detach-products-from-sales-channels" -import { transform } from "@medusajs/workflows-sdk" - -type WorkflowInput = { - data: { - sales_channel_id: string - product_ids: string[] - }[] -} - -export const removeProductsFromSalesChannelsWorkflowId = - "remove-products-from-sales-channels" -export const removeProductsFromSalesChannelsWorkflow = createWorkflow( - removeProductsFromSalesChannelsWorkflowId, - (input: WorkflowData): WorkflowData => { - const links = transform({ input }, (data) => { - return data.input.data - .map(({ sales_channel_id, product_ids }) => { - return product_ids.map((product_id) => { - return { - sales_channel_id, - product_id, - } - }) - }) - .flat() - }) - - return detachProductsFromSalesChannelsStep({ links }) - } -) diff --git a/packages/core-flows/src/stock-location/workflows/index.ts b/packages/core-flows/src/stock-location/workflows/index.ts index d32b09bb0f..619d4cc489 100644 --- a/packages/core-flows/src/stock-location/workflows/index.ts +++ b/packages/core-flows/src/stock-location/workflows/index.ts @@ -2,3 +2,4 @@ export * from "./create-location-fulfillment-set" export * from "./create-stock-locations" export * from "./delete-stock-locations" export * from "./update-stock-locations" +export * from "./link-sales-channels-to-stock-location" diff --git a/packages/core-flows/src/stock-location/workflows/link-sales-channels-to-stock-location.ts b/packages/core-flows/src/stock-location/workflows/link-sales-channels-to-stock-location.ts new file mode 100644 index 0000000000..d3ef84f5d4 --- /dev/null +++ b/packages/core-flows/src/stock-location/workflows/link-sales-channels-to-stock-location.ts @@ -0,0 +1,31 @@ +import { LinkWorkflowInput } from "@medusajs/types" +import { WorkflowData, createWorkflow } from "@medusajs/workflows-sdk" +import { transform } from "@medusajs/workflows-sdk" +import { + associateLocationsWithSalesChannelsStep, + detachLocationsFromSalesChannelsStep, +} from "../../sales-channel" + +export const linkSalesChannelsToStockLocationWorkflowId = + "link-sales-channels-to-stock-location" +export const linkSalesChannelsToStockLocationWorkflow = createWorkflow( + linkSalesChannelsToStockLocationWorkflowId, + (input: WorkflowData): WorkflowData => { + const toAdd = transform({ input }, (data) => { + return data.input.add?.map((salesChannelId) => ({ + sales_channel_id: salesChannelId, + location_id: data.input.id, + })) + }) + + const toRemove = transform({ input }, (data) => { + return data.input.remove?.map((salesChannelId) => ({ + sales_channel_id: salesChannelId, + location_id: data.input.id, + })) + }) + + associateLocationsWithSalesChannelsStep({ links: toAdd }) + detachLocationsFromSalesChannelsStep({ links: toRemove }) + } +) diff --git a/packages/medusa/src/api-v2/admin/api-keys/[id]/sales-channels/batch/route.ts b/packages/medusa/src/api-v2/admin/api-keys/[id]/sales-channels/batch/route.ts deleted file mode 100644 index 96165b0cb5..0000000000 --- a/packages/medusa/src/api-v2/admin/api-keys/[id]/sales-channels/batch/route.ts +++ /dev/null @@ -1,83 +0,0 @@ -import { - addSalesChannelsToApiKeyWorkflow, - removeSalesChannelsFromApiKeyWorkflow, -} from "@medusajs/core-flows" -import { ApiKeyType, MedusaError } from "@medusajs/utils" -import { - AuthenticatedMedusaRequest, - MedusaResponse, -} from "../../../../../../types/routing" -import { AdminApiKeySalesChannelType } from "../../../validators" -import { BatchMethodRequest } from "@medusajs/types" -import { refetchApiKey } from "../../../helpers" - -export const POST = async ( - req: AuthenticatedMedusaRequest< - BatchMethodRequest - >, - res: MedusaResponse -) => { - const { create, delete: toDelete } = req.validatedBody - const apiKey = await refetchApiKey( - req.params.id, - req.scope, - req.remoteQueryConfig.fields - ) - - if (apiKey.type !== ApiKeyType.PUBLISHABLE) { - throw new MedusaError( - MedusaError.Types.INVALID_DATA, - "Sales channels can only be associated with publishable API keys" - ) - } - - if (create?.length) { - const workflowInput = { - data: [ - { - api_key_id: req.params.id, - sales_channel_ids: create ?? [], - }, - ], - } - - const { errors } = await addSalesChannelsToApiKeyWorkflow(req.scope).run({ - input: workflowInput, - throwOnError: false, - }) - - if (Array.isArray(errors) && errors[0]) { - throw errors[0].error - } - } - - if (toDelete?.length) { - const workflowInput = { - data: [ - { - api_key_id: req.params.id, - sales_channel_ids: toDelete, - }, - ], - } - - const { errors } = await removeSalesChannelsFromApiKeyWorkflow( - req.scope - ).run({ - input: workflowInput, - throwOnError: false, - }) - - if (Array.isArray(errors) && errors[0]) { - throw errors[0].error - } - } - - const newApiKey = await refetchApiKey( - req.params.id, - req.scope, - req.remoteQueryConfig.fields - ) - - res.status(200).json({ api_key: newApiKey }) -} diff --git a/packages/medusa/src/api-v2/admin/api-keys/[id]/sales-channels/route.ts b/packages/medusa/src/api-v2/admin/api-keys/[id]/sales-channels/route.ts new file mode 100644 index 0000000000..91eda3b9e1 --- /dev/null +++ b/packages/medusa/src/api-v2/admin/api-keys/[id]/sales-channels/route.ts @@ -0,0 +1,44 @@ +import { ApiKeyType, MedusaError } from "@medusajs/utils" +import { + AuthenticatedMedusaRequest, + MedusaResponse, +} from "../../../../../types/routing" +import { refetchApiKey } from "../../helpers" +import { LinkMethodRequest } from "@medusajs/types/src" +import { linkSalesChannelsToApiKeyWorkflow } from "@medusajs/core-flows" + +export const POST = async ( + req: AuthenticatedMedusaRequest, + res: MedusaResponse +) => { + const { add, remove } = req.validatedBody + const apiKey = await refetchApiKey(req.params.id, req.scope, ["id", "type"]) + + if (apiKey.type !== ApiKeyType.PUBLISHABLE) { + throw new MedusaError( + MedusaError.Types.INVALID_DATA, + "Sales channels can only be associated with publishable API keys" + ) + } + + const { errors } = await linkSalesChannelsToApiKeyWorkflow(req.scope).run({ + input: { + id: req.params.id, + add, + remove, + }, + throwOnError: false, + }) + + if (Array.isArray(errors) && errors[0]) { + throw errors[0].error + } + + const updatedApiKey = await refetchApiKey( + req.params.id, + req.scope, + req.remoteQueryConfig.fields + ) + + res.status(200).json({ api_key: updatedApiKey }) +} diff --git a/packages/medusa/src/api-v2/admin/api-keys/middlewares.ts b/packages/medusa/src/api-v2/admin/api-keys/middlewares.ts index faa1a09255..8e9e002486 100644 --- a/packages/medusa/src/api-v2/admin/api-keys/middlewares.ts +++ b/packages/medusa/src/api-v2/admin/api-keys/middlewares.ts @@ -4,7 +4,6 @@ import { MiddlewareRoute } from "../../../loaders/helpers/routing/types" import { authenticate } from "../../../utils/authenticate-middleware" import { validateAndTransformQuery } from "../../utils/validate-query" import { - AdminApiKeySalesChannel, AdminCreateApiKey, AdminGetApiKeyParams, AdminGetApiKeysParams, @@ -12,7 +11,7 @@ import { AdminUpdateApiKey, } from "./validators" import { validateAndTransformBody } from "../../utils/validate-body" -import { createBatchBody } from "../../utils/validators" +import { createLinkBody } from "../../utils/validators" export const adminApiKeyRoutesMiddlewares: MiddlewareRoute[] = [ { @@ -79,11 +78,9 @@ export const adminApiKeyRoutesMiddlewares: MiddlewareRoute[] = [ }, { method: ["POST"], - matcher: "/admin/api-keys/:id/sales-channels/batch", + matcher: "/admin/api-keys/:id/sales-channels", middlewares: [ - validateAndTransformBody( - createBatchBody(AdminApiKeySalesChannel, AdminApiKeySalesChannel) - ), + validateAndTransformBody(createLinkBody()), validateAndTransformQuery( AdminGetApiKeyParams, QueryConfig.retrieveTransformQueryConfig diff --git a/packages/medusa/src/api-v2/admin/api-keys/validators.ts b/packages/medusa/src/api-v2/admin/api-keys/validators.ts index 42e47569c8..547930293f 100644 --- a/packages/medusa/src/api-v2/admin/api-keys/validators.ts +++ b/packages/medusa/src/api-v2/admin/api-keys/validators.ts @@ -41,8 +41,3 @@ export type AdminRevokeApiKeyType = z.infer export const AdminRevokeApiKey = z.object({ revoke_in: z.number().optional(), }) - -export type AdminApiKeySalesChannelType = z.infer< - typeof AdminApiKeySalesChannel -> -export const AdminApiKeySalesChannel = z.string() diff --git a/packages/medusa/src/api-v2/admin/customer-groups/[id]/customers/batch/route.ts b/packages/medusa/src/api-v2/admin/customer-groups/[id]/customers/batch/route.ts deleted file mode 100644 index 6b8808da43..0000000000 --- a/packages/medusa/src/api-v2/admin/customer-groups/[id]/customers/batch/route.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { AdminCustomerGroupResponse, BatchMethodRequest } from "@medusajs/types" -import { - AuthenticatedMedusaRequest, - MedusaResponse, -} from "../../../../../../types/routing" -import { AdminSetCustomersCustomerGroupType } from "../../../validators" -import { - createCustomerGroupCustomersWorkflow, - deleteCustomerGroupCustomersWorkflow, -} from "@medusajs/core-flows" -import { refetchCustomerGroup } from "../../../helpers" - -export const POST = async ( - req: AuthenticatedMedusaRequest< - BatchMethodRequest< - AdminSetCustomersCustomerGroupType, - AdminSetCustomersCustomerGroupType - > - >, - res: MedusaResponse -) => { - const { id } = req.params - const { create, delete: toDelete } = req.validatedBody - - if (create?.length) { - const createCustomers = createCustomerGroupCustomersWorkflow(req.scope) - const { errors } = await createCustomers.run({ - input: { - groupCustomers: create.map((c) => ({ - customer_id: c, - customer_group_id: id, - })), - }, - throwOnError: false, - }) - - if (Array.isArray(errors) && errors[0]) { - throw errors[0].error - } - } - - if (toDelete?.length) { - const deleteCustomers = deleteCustomerGroupCustomersWorkflow(req.scope) - const { errors } = await deleteCustomers.run({ - input: { - groupCustomers: toDelete.map((c) => ({ - customer_id: c, - customer_group_id: id, - })), - }, - throwOnError: false, - }) - - if (Array.isArray(errors) && errors[0]) { - throw errors[0].error - } - } - - const customerGroup = await refetchCustomerGroup( - id, - req.scope, - req.remoteQueryConfig.fields - ) - - res.status(200).json({ customer_group: customerGroup }) -} diff --git a/packages/medusa/src/api-v2/admin/customer-groups/[id]/customers/route.ts b/packages/medusa/src/api-v2/admin/customer-groups/[id]/customers/route.ts new file mode 100644 index 0000000000..c769339722 --- /dev/null +++ b/packages/medusa/src/api-v2/admin/customer-groups/[id]/customers/route.ts @@ -0,0 +1,37 @@ +import { linkCustomersToCustomerGroupWorkflow } from "@medusajs/core-flows" +import { + AuthenticatedMedusaRequest, + MedusaResponse, +} from "../../../../../types/routing" + +import { LinkMethodRequest } from "@medusajs/types/src" +import { refetchCustomerGroup } from "../../helpers" + +export const POST = async ( + req: AuthenticatedMedusaRequest, + res: MedusaResponse +) => { + const { id } = req.params + const { add, remove } = req.validatedBody + + const workflow = linkCustomersToCustomerGroupWorkflow(req.scope) + const { errors } = await workflow.run({ + input: { + id, + add, + remove, + }, + throwOnError: false, + }) + + if (Array.isArray(errors) && errors[0]) { + throw errors[0].error + } + + const customerGroup = await refetchCustomerGroup( + req.params.id, + req.scope, + req.remoteQueryConfig.fields + ) + res.status(200).json({ customer_group: customerGroup }) +} diff --git a/packages/medusa/src/api-v2/admin/customer-groups/middlewares.ts b/packages/medusa/src/api-v2/admin/customer-groups/middlewares.ts index 41dd01732f..a7c3dbacf2 100644 --- a/packages/medusa/src/api-v2/admin/customer-groups/middlewares.ts +++ b/packages/medusa/src/api-v2/admin/customer-groups/middlewares.ts @@ -6,11 +6,10 @@ import { AdminCreateCustomerGroup, AdminGetCustomerGroupParams, AdminGetCustomerGroupsParams, - AdminSetCustomersCustomerGroup, AdminUpdateCustomerGroup, } from "./validators" import { validateAndTransformBody } from "../../utils/validate-body" -import { createBatchBody } from "../../utils/validators" +import { createLinkBody } from "../../utils/validators" export const adminCustomerGroupRoutesMiddlewares: MiddlewareRoute[] = [ { @@ -62,14 +61,9 @@ export const adminCustomerGroupRoutesMiddlewares: MiddlewareRoute[] = [ }, { method: ["POST"], - matcher: "/admin/customer-groups/:id/customers/batch", + matcher: "/admin/customer-groups/:id/customers", middlewares: [ - validateAndTransformBody( - createBatchBody( - AdminSetCustomersCustomerGroup, - AdminSetCustomersCustomerGroup - ) - ), + validateAndTransformBody(createLinkBody()), validateAndTransformQuery( AdminGetCustomerGroupParams, QueryConfig.retrieveTransformQueryConfig diff --git a/packages/medusa/src/api-v2/admin/customer-groups/validators.ts b/packages/medusa/src/api-v2/admin/customer-groups/validators.ts index c97ca9e34d..2b6ab506bd 100644 --- a/packages/medusa/src/api-v2/admin/customer-groups/validators.ts +++ b/packages/medusa/src/api-v2/admin/customer-groups/validators.ts @@ -66,8 +66,3 @@ export type AdminUpdateCustomerGroupType = z.infer< export const AdminUpdateCustomerGroup = z.object({ name: z.string(), }) - -export type AdminSetCustomersCustomerGroupType = z.infer< - typeof AdminSetCustomersCustomerGroup -> -export const AdminSetCustomersCustomerGroup = z.string() diff --git a/packages/medusa/src/api-v2/admin/sales-channels/[id]/products/batch/add/route.ts b/packages/medusa/src/api-v2/admin/sales-channels/[id]/products/batch/add/route.ts deleted file mode 100644 index 5238a9d6d8..0000000000 --- a/packages/medusa/src/api-v2/admin/sales-channels/[id]/products/batch/add/route.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { addProductsToSalesChannelsWorkflow } from "@medusajs/core-flows" -import { - AuthenticatedMedusaRequest, - MedusaResponse, -} from "../../../../../../../types/routing" - -import { refetchSalesChannel } from "../../../../helpers" -import { AdminSetSalesChannelProductsBatchType } from "../../../../validators" - -export const POST = async ( - req: AuthenticatedMedusaRequest, - res: MedusaResponse -) => { - const workflowInput = { - data: [ - { - sales_channel_id: req.params.id, - product_ids: req.validatedBody.product_ids, - }, - ], - } - - const { errors } = await addProductsToSalesChannelsWorkflow(req.scope).run({ - input: workflowInput, - throwOnError: false, - }) - - if (Array.isArray(errors) && errors[0]) { - throw errors[0].error - } - - const salesChannel = await refetchSalesChannel( - req.params.id, - req.scope, - req.remoteQueryConfig.fields - ) - res.status(200).json({ sales_channel: salesChannel }) -} diff --git a/packages/medusa/src/api-v2/admin/sales-channels/[id]/products/batch/remove/route.ts b/packages/medusa/src/api-v2/admin/sales-channels/[id]/products/batch/remove/route.ts deleted file mode 100644 index a321c700aa..0000000000 --- a/packages/medusa/src/api-v2/admin/sales-channels/[id]/products/batch/remove/route.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { removeProductsFromSalesChannelsWorkflow } from "@medusajs/core-flows" -import { - AuthenticatedMedusaRequest, - MedusaResponse, -} from "../../../../../../../types/routing" -import { AdminSetSalesChannelProductsBatchType } from "../../../../validators" -import { refetchSalesChannel } from "../../../../helpers" - -export const POST = async ( - req: AuthenticatedMedusaRequest, - res: MedusaResponse -) => { - const workflowInput = { - data: [ - { - sales_channel_id: req.params.id, - product_ids: req.validatedBody.product_ids, - }, - ], - } - - const { errors } = await removeProductsFromSalesChannelsWorkflow( - req.scope - ).run({ - input: workflowInput, - throwOnError: false, - }) - - if (Array.isArray(errors) && errors[0]) { - throw errors[0].error - } - - const salesChannel = await refetchSalesChannel( - req.params.id, - req.scope, - req.remoteQueryConfig.fields - ) - res.status(200).json({ sales_channel: salesChannel }) -} diff --git a/packages/medusa/src/api-v2/admin/sales-channels/[id]/products/route.ts b/packages/medusa/src/api-v2/admin/sales-channels/[id]/products/route.ts new file mode 100644 index 0000000000..ff142c0a3b --- /dev/null +++ b/packages/medusa/src/api-v2/admin/sales-channels/[id]/products/route.ts @@ -0,0 +1,37 @@ +import { + AuthenticatedMedusaRequest, + MedusaResponse, +} from "../../../../../types/routing" + +import { LinkMethodRequest } from "@medusajs/types/src" +import { refetchSalesChannel } from "../../helpers" +import { linkProductsToSalesChannelWorkflow } from "@medusajs/core-flows" + +export const POST = async ( + req: AuthenticatedMedusaRequest, + res: MedusaResponse +) => { + const { id } = req.params + const { add, remove } = req.validatedBody + + const workflow = linkProductsToSalesChannelWorkflow(req.scope) + const { errors } = await workflow.run({ + input: { + id, + add, + remove, + }, + throwOnError: false, + }) + + if (Array.isArray(errors) && errors[0]) { + throw errors[0].error + } + + const salesChannel = await refetchSalesChannel( + req.params.id, + req.scope, + req.remoteQueryConfig.fields + ) + res.status(200).json({ sales_channel: salesChannel }) +} diff --git a/packages/medusa/src/api-v2/admin/sales-channels/middlewares.ts b/packages/medusa/src/api-v2/admin/sales-channels/middlewares.ts index ab4511b347..c976e1b77d 100644 --- a/packages/medusa/src/api-v2/admin/sales-channels/middlewares.ts +++ b/packages/medusa/src/api-v2/admin/sales-channels/middlewares.ts @@ -3,12 +3,12 @@ import { authenticate } from "../../../utils/authenticate-middleware" import { maybeApplyLinkFilter } from "../../utils/maybe-apply-link-filter" import { validateAndTransformBody } from "../../utils/validate-body" import { validateAndTransformQuery } from "../../utils/validate-query" +import { createLinkBody } from "../../utils/validators" import * as QueryConfig from "./query-config" import { AdminCreateSalesChannel, AdminGetSalesChannelParams, AdminGetSalesChannelsParams, - AdminSetSalesChannelProductsBatch, AdminUpdateSalesChannel, } from "./validators" @@ -77,20 +77,9 @@ export const adminSalesChannelRoutesMiddlewares: MiddlewareRoute[] = [ }, { method: ["POST"], - matcher: "/admin/sales-channels/:id/products/batch/add", + matcher: "/admin/sales-channels/:id/products", middlewares: [ - validateAndTransformBody(AdminSetSalesChannelProductsBatch), - validateAndTransformQuery( - AdminGetSalesChannelParams, - QueryConfig.retrieveTransformQueryConfig - ), - ], - }, - { - method: ["POST"], - matcher: "/admin/sales-channels/:id/products/batch/remove", - middlewares: [ - validateAndTransformBody(AdminSetSalesChannelProductsBatch), + validateAndTransformBody(createLinkBody()), validateAndTransformQuery( AdminGetSalesChannelParams, QueryConfig.retrieveTransformQueryConfig diff --git a/packages/medusa/src/api-v2/admin/sales-channels/validators.ts b/packages/medusa/src/api-v2/admin/sales-channels/validators.ts index a271ce6466..ccbcb437a6 100644 --- a/packages/medusa/src/api-v2/admin/sales-channels/validators.ts +++ b/packages/medusa/src/api-v2/admin/sales-channels/validators.ts @@ -50,10 +50,3 @@ export const AdminUpdateSalesChannel = z.object({ is_disabled: z.boolean().optional(), metadata: z.record(z.string(), z.unknown()).optional(), }) - -export type AdminSetSalesChannelProductsBatchType = z.infer< - typeof AdminSetSalesChannelProductsBatch -> -export const AdminSetSalesChannelProductsBatch = z.object({ - product_ids: z.array(z.string()), -}) diff --git a/packages/medusa/src/api-v2/admin/stock-locations/[id]/sales-channels/batch/add/route.ts b/packages/medusa/src/api-v2/admin/stock-locations/[id]/sales-channels/batch/add/route.ts deleted file mode 100644 index 3155414cf4..0000000000 --- a/packages/medusa/src/api-v2/admin/stock-locations/[id]/sales-channels/batch/add/route.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { - MedusaRequest, - MedusaResponse, -} from "../../../../../../../types/routing" - -import { AdminStockLocationsSalesChannelType } from "../../../../validators" -import { addLocationsToSalesChannelWorkflow } from "@medusajs/core-flows" -import { refetchStockLocation } from "../../../../helpers" - -export const POST = async ( - req: MedusaRequest, - res: MedusaResponse -) => { - const workflowInput = { - data: req.validatedBody.sales_channel_ids.map((id) => ({ - sales_channel_id: id, - location_ids: [req.params.id], - })), - } - - const { errors } = await addLocationsToSalesChannelWorkflow(req.scope).run({ - input: workflowInput, - throwOnError: false, - }) - - if (Array.isArray(errors) && errors[0]) { - throw errors[0].error - } - - const stockLocation = await refetchStockLocation( - req.params.id, - req.scope, - req.remoteQueryConfig.fields - ) - - res.status(200).json({ stock_location: stockLocation }) -} diff --git a/packages/medusa/src/api-v2/admin/stock-locations/[id]/sales-channels/batch/remove/route.ts b/packages/medusa/src/api-v2/admin/stock-locations/[id]/sales-channels/batch/remove/route.ts deleted file mode 100644 index 0fb7a10972..0000000000 --- a/packages/medusa/src/api-v2/admin/stock-locations/[id]/sales-channels/batch/remove/route.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { - MedusaRequest, - MedusaResponse, -} from "../../../../../../../types/routing" - -import { AdminStockLocationsSalesChannelType } from "../../../../validators" -import { removeLocationsFromSalesChannelWorkflow } from "@medusajs/core-flows" -import { refetchStockLocation } from "../../../../helpers" - -export const POST = async ( - req: MedusaRequest, - res: MedusaResponse -) => { - const workflowInput = { - data: req.validatedBody.sales_channel_ids.map((id) => ({ - sales_channel_id: id, - location_ids: [req.params.id], - })), - } - - const { errors } = await removeLocationsFromSalesChannelWorkflow( - req.scope - ).run({ - input: workflowInput, - throwOnError: false, - }) - - if (Array.isArray(errors) && errors[0]) { - throw errors[0].error - } - - const stockLocation = await refetchStockLocation( - req.params.id, - req.scope, - req.remoteQueryConfig.fields - ) - - res.status(200).json({ stock_location: stockLocation }) -} diff --git a/packages/medusa/src/api-v2/admin/stock-locations/[id]/sales-channels/route.ts b/packages/medusa/src/api-v2/admin/stock-locations/[id]/sales-channels/route.ts new file mode 100644 index 0000000000..1c9aa4029c --- /dev/null +++ b/packages/medusa/src/api-v2/admin/stock-locations/[id]/sales-channels/route.ts @@ -0,0 +1,37 @@ +import { + AuthenticatedMedusaRequest, + MedusaResponse, +} from "../../../../../types/routing" + +import { LinkMethodRequest } from "@medusajs/types/src" +import { refetchStockLocation } from "../../helpers" +import { linkSalesChannelsToStockLocationWorkflow } from "@medusajs/core-flows" + +export const POST = async ( + req: AuthenticatedMedusaRequest, + res: MedusaResponse +) => { + const { id } = req.params + const { add, remove } = req.validatedBody + + const workflow = linkSalesChannelsToStockLocationWorkflow(req.scope) + const { errors } = await workflow.run({ + input: { + id, + add, + remove, + }, + throwOnError: false, + }) + + if (Array.isArray(errors) && errors[0]) { + throw errors[0].error + } + + const stockLocation = await refetchStockLocation( + req.params.id, + req.scope, + req.remoteQueryConfig.fields + ) + res.status(200).json({ stock_location: stockLocation }) +} diff --git a/packages/medusa/src/api-v2/admin/stock-locations/middlewares.ts b/packages/medusa/src/api-v2/admin/stock-locations/middlewares.ts index 5af051436f..18f67160bb 100644 --- a/packages/medusa/src/api-v2/admin/stock-locations/middlewares.ts +++ b/packages/medusa/src/api-v2/admin/stock-locations/middlewares.ts @@ -3,13 +3,13 @@ import { authenticate } from "../../../utils/authenticate-middleware" import { maybeApplyLinkFilter } from "../../utils/maybe-apply-link-filter" import { validateAndTransformBody } from "../../utils/validate-body" import { validateAndTransformQuery } from "../../utils/validate-query" +import { createLinkBody } from "../../utils/validators" import * as QueryConfig from "./query-config" import { AdminCreateStockLocation, AdminCreateStockLocationFulfillmentSet, AdminGetStockLocationParams, AdminGetStockLocationsParams, - AdminStockLocationsSalesChannel, AdminUpdateStockLocation, } from "./validators" @@ -79,9 +79,9 @@ export const adminStockLocationRoutesMiddlewares: MiddlewareRoute[] = [ }, { method: ["POST"], - matcher: "/admin/stock-locations/:id/sales-channels/batch*", + matcher: "/admin/stock-locations/:id/sales-channels", middlewares: [ - validateAndTransformBody(AdminStockLocationsSalesChannel), + validateAndTransformBody(createLinkBody()), validateAndTransformQuery( AdminGetStockLocationParams, QueryConfig.retrieveTransformQueryConfig diff --git a/packages/medusa/src/api-v2/admin/stock-locations/validators.ts b/packages/medusa/src/api-v2/admin/stock-locations/validators.ts index 73f64b4a3c..1407b0485f 100644 --- a/packages/medusa/src/api-v2/admin/stock-locations/validators.ts +++ b/packages/medusa/src/api-v2/admin/stock-locations/validators.ts @@ -60,13 +60,6 @@ export const AdminUpdateStockLocation = z.object({ metadata: z.record(z.unknown()).optional(), }) -export type AdminStockLocationsSalesChannelType = z.infer< - typeof AdminStockLocationsSalesChannel -> -export const AdminStockLocationsSalesChannel = z.object({ - sales_channel_ids: z.array(z.string()), -}) - export type AdminCreateStockLocationFulfillmentSetType = z.infer< typeof AdminCreateStockLocationFulfillmentSet > diff --git a/packages/types/src/common/batch.ts b/packages/types/src/common/batch.ts index 424ea5e6a3..fb27e73067 100644 --- a/packages/types/src/common/batch.ts +++ b/packages/types/src/common/batch.ts @@ -3,13 +3,19 @@ export type LinkMethodRequest = { remove?: string[] } -export type BatchMethodRequest = { +export type LinkWorkflowInput = { + id: string + add?: string[] + remove?: string[] +} + +export type BatchMethodRequest = { create?: TCreate[] update?: TUpdate[] delete?: string[] } -export type BatchMethodResponse = { +export type BatchMethodResponse = { created: T[] updated: T[] deleted: { @@ -18,3 +24,10 @@ export type BatchMethodResponse = { deleted: boolean } } + +export type BatchWorkflowInput = BatchMethodRequest< + TCreate, + TUpdate +> + +export type BatchWorkflowOutput = BatchMethodResponse diff --git a/packages/types/src/workflows/products/mutations.ts b/packages/types/src/workflows/products/mutations.ts index eef3dd4885..6ee7d8e2cc 100644 --- a/packages/types/src/workflows/products/mutations.ts +++ b/packages/types/src/workflows/products/mutations.ts @@ -1,5 +1,23 @@ -import { LinkMethodRequest } from "../../common" +import { PricingTypes, ProductTypes } from "../../bundles" -export interface BatchLinkProductsToCollectionDTO extends LinkMethodRequest { - id: string +export type CreateProductVariantWorkflowInputDTO = + ProductTypes.CreateProductVariantDTO & { + prices?: PricingTypes.CreateMoneyAmountDTO[] + } + +export type UpdateProductVariantWorkflowInputDTO = + (ProductTypes.UpsertProductVariantDTO & { + prices?: PricingTypes.CreateMoneyAmountDTO[] + })[] + +export type CreateProductWorkflowInputDTO = Omit< + ProductTypes.CreateProductDTO, + "variants" +> & { + sales_channels?: { id: string }[] + variants?: CreateProductVariantWorkflowInputDTO[] +} + +export type UpdateProductWorkflowInputDTO = ProductTypes.UpsertProductDTO & { + sales_channels?: { id: string }[] }