feat: region payment providers management workflows/api (#6864)
This commit is contained in:
1 parent
12fcb655cd
commit
e944a627f0
48 files changed
+1029
-85
No files matched your search
@@ -0,0 +1,13 @@
|
|||||||
|
---
|
||||||
|
"@medusajs/medusa": patch
|
||||||
|
"@medusajs/core-flows": patch
|
||||||
|
"@medusajs/link-modules": patch
|
||||||
|
"medusa-test-utils": patch
|
||||||
|
"@medusajs/modules-sdk": patch
|
||||||
|
"@medusajs/orchestration": patch
|
||||||
|
"@medusajs/payment": patch
|
||||||
|
"@medusajs/types": patch
|
||||||
|
"@medusajs/utils": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
feat: region payment providers management workflows/api
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
import { ModuleRegistrationName, Modules } from "@medusajs/modules-sdk"
|
import { ModuleRegistrationName, Modules } from "@medusajs/modules-sdk"
|
||||||
import { IPaymentModuleService, IRegionModuleService } from "@medusajs/types"
|
import { IPaymentModuleService, IRegionModuleService } from "@medusajs/types"
|
||||||
import { medusaIntegrationTestRunner } from "medusa-test-utils"
|
import { medusaIntegrationTestRunner } from "medusa-test-utils"
|
||||||
|
import {ContainerRegistrationKeys} from "@medusajs/utils";
|
||||||
|
|
||||||
jest.setTimeout(50000)
|
jest.setTimeout(50000)
|
||||||
|
|
||||||
@@ -20,8 +21,8 @@ medusaIntegrationTestRunner({
|
|||||||
appContainer = getContainer()
|
appContainer = getContainer()
|
||||||
regionModule = appContainer.resolve(ModuleRegistrationName.REGION)
|
regionModule = appContainer.resolve(ModuleRegistrationName.REGION)
|
||||||
paymentModule = appContainer.resolve(ModuleRegistrationName.PAYMENT)
|
paymentModule = appContainer.resolve(ModuleRegistrationName.PAYMENT)
|
||||||
remoteQuery = appContainer.resolve("remoteQuery")
|
remoteQuery = appContainer.resolve(ContainerRegistrationKeys.REMOTE_QUERY)
|
||||||
remoteLink = appContainer.resolve("remoteLink")
|
remoteLink = appContainer.resolve(ContainerRegistrationKeys.REMOTE_LINK)
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should query region and payment provider link with remote query", async () => {
|
it("should query region and payment provider link with remote query", async () => {
|
||||||
@@ -73,7 +74,7 @@ medusaIntegrationTestRunner({
|
|||||||
])
|
])
|
||||||
)
|
)
|
||||||
|
|
||||||
expect(otherLink).toHaveLength(1)
|
expect(otherLink).toHaveLength(2)
|
||||||
expect(otherLink).toEqual(
|
expect(otherLink).toEqual(
|
||||||
expect.arrayContaining([
|
expect.arrayContaining([
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
@@ -84,6 +85,10 @@ medusaIntegrationTestRunner({
|
|||||||
}),
|
}),
|
||||||
]),
|
]),
|
||||||
}),
|
}),
|
||||||
|
expect.objectContaining({
|
||||||
|
id: "pp_system_default_2",
|
||||||
|
regions: []
|
||||||
|
}),
|
||||||
])
|
])
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -47,10 +47,9 @@ medusaIntegrationTestRunner({
|
|||||||
metadata: { foo: "bar" },
|
metadata: { foo: "bar" },
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
expect(created.data.region.countries.map((c) => c.iso_2)).toEqual([
|
expect(
|
||||||
"us",
|
created.data.region.countries.map((c) => c.iso_2).sort()
|
||||||
"ca",
|
).toEqual(["ca", "us"])
|
||||||
])
|
|
||||||
|
|
||||||
const updated = await api.post(
|
const updated = await api.post(
|
||||||
`/admin/regions/${created.data.region.id}`,
|
`/admin/regions/${created.data.region.id}`,
|
||||||
@@ -96,6 +95,174 @@ medusaIntegrationTestRunner({
|
|||||||
expect(deletedRegion.deleted_at).toBeTruthy()
|
expect(deletedRegion.deleted_at).toBeTruthy()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it("should create the region with the available payment providers if the providers exists", async () => {
|
||||||
|
const paymentProviderId = "pp_system_default"
|
||||||
|
|
||||||
|
const created = await api.post(
|
||||||
|
`/admin/regions?fields=*payment_providers`,
|
||||||
|
{
|
||||||
|
name: "Test Region",
|
||||||
|
currency_code: "usd",
|
||||||
|
countries: ["us", "ca"],
|
||||||
|
metadata: { foo: "bar" },
|
||||||
|
payment_providers: [paymentProviderId],
|
||||||
|
},
|
||||||
|
adminHeaders
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(created.status).toEqual(200)
|
||||||
|
expect(created.data.region).toEqual(
|
||||||
|
expect.objectContaining({
|
||||||
|
id: created.data.region.id,
|
||||||
|
name: "Test Region",
|
||||||
|
currency_code: "usd",
|
||||||
|
metadata: { foo: "bar" },
|
||||||
|
payment_providers: [
|
||||||
|
expect.objectContaining({
|
||||||
|
id: paymentProviderId,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
})
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should update the region available payment providers", async () => {
|
||||||
|
const paymentProviderId = "pp_system_default"
|
||||||
|
const paymentProvider2Id = "pp_system_default_2"
|
||||||
|
|
||||||
|
const created = await api.post(
|
||||||
|
`/admin/regions`,
|
||||||
|
{
|
||||||
|
name: "Test Region",
|
||||||
|
currency_code: "usd",
|
||||||
|
countries: ["us", "ca"],
|
||||||
|
metadata: { foo: "bar" },
|
||||||
|
},
|
||||||
|
adminHeaders
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assign a new payment provider
|
||||||
|
*/
|
||||||
|
|
||||||
|
await api.post(
|
||||||
|
`/admin/regions/${created.data.region.id}`,
|
||||||
|
{
|
||||||
|
payment_providers: [paymentProviderId],
|
||||||
|
},
|
||||||
|
adminHeaders
|
||||||
|
)
|
||||||
|
|
||||||
|
let regionResponse = await api.get(
|
||||||
|
`/admin/regions/${created.data.region.id}?fields=*payment_providers`,
|
||||||
|
adminHeaders
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(regionResponse.status).toEqual(200)
|
||||||
|
expect(regionResponse.data.region.payment_providers).toHaveLength(1)
|
||||||
|
expect(regionResponse.data.region).toEqual(
|
||||||
|
expect.objectContaining({
|
||||||
|
id: regionResponse.data.region.id,
|
||||||
|
payment_providers: [
|
||||||
|
expect.objectContaining({
|
||||||
|
id: paymentProviderId,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replace the region payment providers by a new one set of providers
|
||||||
|
*/
|
||||||
|
|
||||||
|
await api.post(
|
||||||
|
`/admin/regions/${created.data.region.id}`,
|
||||||
|
{
|
||||||
|
payment_providers: [paymentProvider2Id],
|
||||||
|
},
|
||||||
|
adminHeaders
|
||||||
|
)
|
||||||
|
|
||||||
|
regionResponse = await api.get(
|
||||||
|
`/admin/regions/${created.data.region.id}?fields=*payment_providers`,
|
||||||
|
adminHeaders
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(regionResponse.status).toEqual(200)
|
||||||
|
expect(regionResponse.data.region.payment_providers).toHaveLength(1)
|
||||||
|
expect(regionResponse.data.region).toEqual(
|
||||||
|
expect.objectContaining({
|
||||||
|
id: regionResponse.data.region.id,
|
||||||
|
payment_providers: [
|
||||||
|
expect.objectContaining({
|
||||||
|
id: paymentProvider2Id,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replace the region payment providers with both providers
|
||||||
|
*/
|
||||||
|
|
||||||
|
await api.post(
|
||||||
|
`/admin/regions/${created.data.region.id}`,
|
||||||
|
{
|
||||||
|
payment_providers: [paymentProviderId, paymentProvider2Id],
|
||||||
|
},
|
||||||
|
adminHeaders
|
||||||
|
)
|
||||||
|
|
||||||
|
regionResponse = await api.get(
|
||||||
|
`/admin/regions/${created.data.region.id}?fields=*payment_providers`,
|
||||||
|
adminHeaders
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(regionResponse.status).toEqual(200)
|
||||||
|
expect(regionResponse.data.region.payment_providers).toHaveLength(2)
|
||||||
|
expect(regionResponse.data.region).toEqual(
|
||||||
|
expect.objectContaining({
|
||||||
|
id: regionResponse.data.region.id,
|
||||||
|
payment_providers: [
|
||||||
|
expect.objectContaining({
|
||||||
|
id: paymentProvider2Id,
|
||||||
|
}),
|
||||||
|
expect.objectContaining({
|
||||||
|
id: paymentProviderId,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
})
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should throw on update if the given payment providers does not exists", async () => {
|
||||||
|
const created = await api.post(
|
||||||
|
`/admin/regions`,
|
||||||
|
{
|
||||||
|
name: "Test Region",
|
||||||
|
currency_code: "usd",
|
||||||
|
countries: ["us", "ca"],
|
||||||
|
metadata: { foo: "bar" },
|
||||||
|
},
|
||||||
|
adminHeaders
|
||||||
|
)
|
||||||
|
|
||||||
|
const updateErr = await api
|
||||||
|
.post(
|
||||||
|
`/admin/regions/${created.data.region.id}`,
|
||||||
|
{
|
||||||
|
payment_providers: ["test"],
|
||||||
|
},
|
||||||
|
adminHeaders
|
||||||
|
)
|
||||||
|
.catch((e) => e)
|
||||||
|
|
||||||
|
expect(updateErr.response.status).toEqual(404)
|
||||||
|
expect(updateErr.response.data.message).toEqual(
|
||||||
|
"Payment providers with ids test not found or not enabled"
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
it("should throw on missing required properties in create", async () => {
|
it("should throw on missing required properties in create", async () => {
|
||||||
const err = await api
|
const err = await api
|
||||||
.post(`/admin/regions`, {}, adminHeaders)
|
.post(`/admin/regions`, {}, adminHeaders)
|
||||||
|
|||||||
@@ -0,0 +1,148 @@
|
|||||||
|
import { medusaIntegrationTestRunner } from "medusa-test-utils"
|
||||||
|
import { createRegionsWorkflow } from "@medusajs/core-flows"
|
||||||
|
import { MedusaContainer, RegionDTO } from "@medusajs/types"
|
||||||
|
import { createAdminUser } from "../../../../helpers/create-admin-user"
|
||||||
|
import {
|
||||||
|
ContainerRegistrationKeys,
|
||||||
|
remoteQueryObjectFromString,
|
||||||
|
} from "@medusajs/utils"
|
||||||
|
|
||||||
|
jest.setTimeout(200000)
|
||||||
|
|
||||||
|
const env = { MEDUSA_FF_MEDUSA_V2: true }
|
||||||
|
const adminHeaders = {
|
||||||
|
headers: { "x-medusa-access-token": "test_token" },
|
||||||
|
}
|
||||||
|
|
||||||
|
medusaIntegrationTestRunner({
|
||||||
|
env,
|
||||||
|
testSuite: ({ dbConnection, getContainer, api }) => {
|
||||||
|
let container: MedusaContainer
|
||||||
|
let region: RegionDTO
|
||||||
|
|
||||||
|
beforeAll(() => {
|
||||||
|
container = getContainer()
|
||||||
|
})
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await createAdminUser(dbConnection, adminHeaders, container)
|
||||||
|
})
|
||||||
|
|
||||||
|
describe("create region workflow", () => {
|
||||||
|
it("should create a region", async () => {
|
||||||
|
const paymentProviderId = "pp_system_default"
|
||||||
|
|
||||||
|
const data = {
|
||||||
|
name: "Test Region",
|
||||||
|
currency_code: "usd",
|
||||||
|
countries: ["us", "ca"],
|
||||||
|
metadata: { foo: "bar" },
|
||||||
|
payment_providers: [paymentProviderId],
|
||||||
|
}
|
||||||
|
|
||||||
|
let {
|
||||||
|
result: [createRegion],
|
||||||
|
} = await createRegionsWorkflow(container).run({
|
||||||
|
input: {
|
||||||
|
regions: [data],
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const remoteQuery = container.resolve(
|
||||||
|
ContainerRegistrationKeys.REMOTE_QUERY
|
||||||
|
)
|
||||||
|
|
||||||
|
;[createRegion] = await remoteQuery(
|
||||||
|
remoteQueryObjectFromString({
|
||||||
|
entryPoint: "region",
|
||||||
|
variables: {
|
||||||
|
filters: {
|
||||||
|
id: createRegion.id,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
fields: [
|
||||||
|
"id",
|
||||||
|
"name",
|
||||||
|
"currency_code",
|
||||||
|
"metadata",
|
||||||
|
"countries.*",
|
||||||
|
"payment_providers.*",
|
||||||
|
],
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(createRegion).toEqual(
|
||||||
|
expect.objectContaining({
|
||||||
|
id: expect.any(String),
|
||||||
|
name: data.name,
|
||||||
|
currency_code: data.currency_code,
|
||||||
|
countries: expect.arrayContaining(
|
||||||
|
data.countries.map((iso_2) => expect.objectContaining({ iso_2 }))
|
||||||
|
),
|
||||||
|
metadata: data.metadata,
|
||||||
|
payment_providers: [
|
||||||
|
expect.objectContaining({
|
||||||
|
id: paymentProviderId,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
})
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should revert the created region and payment providers", async () => {
|
||||||
|
const paymentProviderId = "pp_system_default"
|
||||||
|
|
||||||
|
const data = {
|
||||||
|
name: "Test Region",
|
||||||
|
currency_code: "usd",
|
||||||
|
countries: ["us", "ca"],
|
||||||
|
metadata: { foo: "bar" },
|
||||||
|
payment_providers: [paymentProviderId],
|
||||||
|
}
|
||||||
|
|
||||||
|
const workflow = createRegionsWorkflow(container)
|
||||||
|
workflow.addAction(
|
||||||
|
"throw",
|
||||||
|
{
|
||||||
|
invoke: async function failStep() {
|
||||||
|
throw new Error(`Failed to create region`)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
noCompensation: true,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
const { errors } = await workflow.run({
|
||||||
|
input: {
|
||||||
|
regions: [data],
|
||||||
|
},
|
||||||
|
throwOnError: false,
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(errors).toHaveLength(1)
|
||||||
|
expect(errors[0].error.message).toEqual(`Failed to create region`)
|
||||||
|
|
||||||
|
const remoteQuery = container.resolve(
|
||||||
|
ContainerRegistrationKeys.REMOTE_QUERY
|
||||||
|
)
|
||||||
|
|
||||||
|
const createRegions = await remoteQuery(
|
||||||
|
remoteQueryObjectFromString({
|
||||||
|
entryPoint: "region",
|
||||||
|
fields: [
|
||||||
|
"id",
|
||||||
|
"name",
|
||||||
|
"currency_code",
|
||||||
|
"metadata",
|
||||||
|
"countries.*",
|
||||||
|
"payment_providers.*",
|
||||||
|
],
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(createRegions).toHaveLength(0)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
})
|
||||||
@@ -0,0 +1,112 @@
|
|||||||
|
import { medusaIntegrationTestRunner } from "medusa-test-utils"
|
||||||
|
import { updateRegionsWorkflow } from "@medusajs/core-flows"
|
||||||
|
import {ContainerLike, MedusaContainer, RegionDTO} from "@medusajs/types"
|
||||||
|
import { createAdminUser } from "../../../../helpers/create-admin-user"
|
||||||
|
|
||||||
|
jest.setTimeout(200000)
|
||||||
|
|
||||||
|
const env = { MEDUSA_FF_MEDUSA_V2: true }
|
||||||
|
const adminHeaders = {
|
||||||
|
headers: { "x-medusa-access-token": "test_token" },
|
||||||
|
}
|
||||||
|
|
||||||
|
medusaIntegrationTestRunner({
|
||||||
|
env,
|
||||||
|
testSuite: ({ dbConnection, getContainer, api }) => {
|
||||||
|
let container: MedusaContainer
|
||||||
|
let region: RegionDTO
|
||||||
|
|
||||||
|
beforeAll(() => {
|
||||||
|
container = getContainer()
|
||||||
|
})
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await createAdminUser(dbConnection, adminHeaders, container)
|
||||||
|
|
||||||
|
region = (
|
||||||
|
await api.post(
|
||||||
|
`/admin/regions`,
|
||||||
|
{
|
||||||
|
name: "Test Region",
|
||||||
|
currency_code: "usd",
|
||||||
|
countries: ["us", "ca"],
|
||||||
|
metadata: { foo: "bar" },
|
||||||
|
},
|
||||||
|
adminHeaders
|
||||||
|
)
|
||||||
|
).data.region
|
||||||
|
})
|
||||||
|
|
||||||
|
describe("update region workflow", () => {
|
||||||
|
it("should update a region", async () => {
|
||||||
|
const updateData = {
|
||||||
|
name: "United States update",
|
||||||
|
}
|
||||||
|
|
||||||
|
const {
|
||||||
|
result: [updatedRegion],
|
||||||
|
} = await updateRegionsWorkflow(container).run({
|
||||||
|
input: {
|
||||||
|
selector: { id: region.id },
|
||||||
|
update: updateData,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(updatedRegion).toEqual(
|
||||||
|
expect.objectContaining({
|
||||||
|
id: region.id,
|
||||||
|
name: updateData.name,
|
||||||
|
})
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should revert region update and payment providers update when it fails", async () => {
|
||||||
|
const paymentProviderId = "pp_system_default"
|
||||||
|
const paymentProvider2Id = "pp_system_default_2"
|
||||||
|
const updateData = {
|
||||||
|
name: "United States update",
|
||||||
|
payment_providers: [paymentProviderId, paymentProvider2Id],
|
||||||
|
}
|
||||||
|
|
||||||
|
const workflow = updateRegionsWorkflow(container)
|
||||||
|
workflow.addAction(
|
||||||
|
"throw",
|
||||||
|
{
|
||||||
|
invoke: async function failStep() {
|
||||||
|
throw new Error(`Failed to update region`)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
noCompensation: true,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
const { errors } = await workflow.run({
|
||||||
|
input: {
|
||||||
|
selector: { id: region.id },
|
||||||
|
update: updateData,
|
||||||
|
},
|
||||||
|
throwOnError: false,
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(errors).toHaveLength(1)
|
||||||
|
expect(errors[0].error.message).toEqual(`Failed to update region`)
|
||||||
|
|
||||||
|
const updatedRegion = (
|
||||||
|
await api.get(
|
||||||
|
`/admin/regions/${region.id}?fields=*payment_providers`,
|
||||||
|
adminHeaders
|
||||||
|
)
|
||||||
|
).data.region
|
||||||
|
|
||||||
|
expect(updatedRegion).toEqual(
|
||||||
|
expect.objectContaining({
|
||||||
|
id: region.id,
|
||||||
|
name: region.name,
|
||||||
|
payment_providers: [],
|
||||||
|
})
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
})
|
||||||
@@ -10,6 +10,17 @@ process.env.LOG_LEVEL = "error"
|
|||||||
|
|
||||||
const enableMedusaV2 = process.env.MEDUSA_FF_MEDUSA_V2 == "true"
|
const enableMedusaV2 = process.env.MEDUSA_FF_MEDUSA_V2 == "true"
|
||||||
|
|
||||||
|
const customPaymentProvider = {
|
||||||
|
resolve: {
|
||||||
|
services: [require("@medusajs/payment/dist/providers/system").default],
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
config: {
|
||||||
|
default_2: {},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
plugins: [],
|
plugins: [],
|
||||||
projectConfig: {
|
projectConfig: {
|
||||||
@@ -70,7 +81,13 @@ module.exports = {
|
|||||||
[Modules.STORE]: true,
|
[Modules.STORE]: true,
|
||||||
[Modules.TAX]: true,
|
[Modules.TAX]: true,
|
||||||
[Modules.CURRENCY]: true,
|
[Modules.CURRENCY]: true,
|
||||||
[Modules.PAYMENT]: true,
|
[Modules.PAYMENT]: {
|
||||||
|
resolve: "@medusajs/payment",
|
||||||
|
/** @type {import('@medusajs/payment').PaymentModuleOptions}*/
|
||||||
|
options: {
|
||||||
|
providers: [customPaymentProvider],
|
||||||
|
},
|
||||||
|
},
|
||||||
[Modules.FULFILLMENT]: {
|
[Modules.FULFILLMENT]: {
|
||||||
/** @type {import('@medusajs/fulfillment').FulfillmentModuleOptions} */
|
/** @type {import('@medusajs/fulfillment').FulfillmentModuleOptions} */
|
||||||
options: {
|
options: {
|
||||||
|
|||||||
@@ -0,0 +1,216 @@
|
|||||||
|
import { ModuleRegistrationName, RemoteLink } from "@medusajs/modules-sdk"
|
||||||
|
import { IPaymentModuleService, RemoteQueryFunction } from "@medusajs/types"
|
||||||
|
import { createStep, StepResponse } from "@medusajs/workflows-sdk"
|
||||||
|
import {
|
||||||
|
arrayDifference,
|
||||||
|
ContainerRegistrationKeys,
|
||||||
|
LINKS,
|
||||||
|
MedusaError,
|
||||||
|
Modules,
|
||||||
|
promiseAll,
|
||||||
|
remoteQueryObjectFromString,
|
||||||
|
} from "@medusajs/utils"
|
||||||
|
|
||||||
|
export interface SetRegionsPaymentProvidersStepInput {
|
||||||
|
input: {
|
||||||
|
id: string
|
||||||
|
payment_providers?: string[]
|
||||||
|
}[]
|
||||||
|
}
|
||||||
|
|
||||||
|
interface FilteredSetRegionsPaymentProvidersStepInput {
|
||||||
|
id: string
|
||||||
|
payment_providers: string[]
|
||||||
|
}
|
||||||
|
|
||||||
|
type LinkItems = {
|
||||||
|
[Modules.REGION]: { region_id: string }
|
||||||
|
[Modules.PAYMENT]: { payment_provider_id: string }
|
||||||
|
}[]
|
||||||
|
|
||||||
|
async function validatePaymentProvidersExists(
|
||||||
|
paymentService: IPaymentModuleService,
|
||||||
|
paymentProviderIds: string[]
|
||||||
|
) {
|
||||||
|
const paymentProviders = await paymentService.listPaymentProviders({
|
||||||
|
id: { $in: paymentProviderIds },
|
||||||
|
is_enabled: true,
|
||||||
|
})
|
||||||
|
|
||||||
|
const retrievedPaymentProviderIds = paymentProviders.map((p) => p.id)
|
||||||
|
|
||||||
|
const missingProviders = arrayDifference(
|
||||||
|
paymentProviderIds,
|
||||||
|
retrievedPaymentProviderIds
|
||||||
|
)
|
||||||
|
|
||||||
|
if (missingProviders.length) {
|
||||||
|
throw new MedusaError(
|
||||||
|
MedusaError.Types.NOT_FOUND,
|
||||||
|
`Payment providers with ids ${missingProviders.join(
|
||||||
|
", "
|
||||||
|
)} not found or not enabled`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getCurrentRegionPaymentProvidersLinks(
|
||||||
|
regionIds: string[],
|
||||||
|
{ remoteQuery }: { remoteQuery: RemoteQueryFunction }
|
||||||
|
): Promise<
|
||||||
|
{
|
||||||
|
[Modules.REGION]: { region_id: string }
|
||||||
|
[Modules.PAYMENT]: { payment_provider_id: string }
|
||||||
|
}[]
|
||||||
|
> {
|
||||||
|
const query = remoteQueryObjectFromString({
|
||||||
|
service: LINKS.RegionPaymentProvider,
|
||||||
|
variables: {
|
||||||
|
filters: { region_id: regionIds },
|
||||||
|
take: null,
|
||||||
|
},
|
||||||
|
fields: ["region_id", "payment_provider_id"],
|
||||||
|
})
|
||||||
|
|
||||||
|
const regionProviderLinks = (await remoteQuery(query)) as {
|
||||||
|
region_id: string
|
||||||
|
payment_provider_id: string
|
||||||
|
}[]
|
||||||
|
|
||||||
|
return regionProviderLinks.map((region) => {
|
||||||
|
return {
|
||||||
|
[Modules.REGION]: {
|
||||||
|
region_id: region.region_id,
|
||||||
|
},
|
||||||
|
[Modules.PAYMENT]: {
|
||||||
|
payment_provider_id: region.payment_provider_id,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export const setRegionsPaymentProvidersStepId =
|
||||||
|
"add-region-payment-providers-step"
|
||||||
|
export const setRegionsPaymentProvidersStep = createStep(
|
||||||
|
setRegionsPaymentProvidersStepId,
|
||||||
|
async (data: SetRegionsPaymentProvidersStepInput, { container }) => {
|
||||||
|
const dataInputToProcess = data.input.filter((inputData) => {
|
||||||
|
return inputData.payment_providers?.length
|
||||||
|
}) as FilteredSetRegionsPaymentProvidersStepInput[]
|
||||||
|
|
||||||
|
if (!dataInputToProcess.length) {
|
||||||
|
return new StepResponse(void 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
const paymentService = container.resolve<IPaymentModuleService>(
|
||||||
|
ModuleRegistrationName.PAYMENT
|
||||||
|
)
|
||||||
|
const remoteLink = container.resolve<RemoteLink>(
|
||||||
|
ContainerRegistrationKeys.REMOTE_LINK
|
||||||
|
)
|
||||||
|
const remoteQuery = container.resolve<RemoteQueryFunction>(
|
||||||
|
ContainerRegistrationKeys.REMOTE_QUERY
|
||||||
|
)
|
||||||
|
|
||||||
|
const allPaymentProviderIds = dataInputToProcess
|
||||||
|
.map((inputData) => {
|
||||||
|
return inputData.payment_providers!
|
||||||
|
})
|
||||||
|
.flat()
|
||||||
|
const uniquePaymentProviderIds = Array.from(
|
||||||
|
new Set<string>(allPaymentProviderIds)
|
||||||
|
)
|
||||||
|
|
||||||
|
await validatePaymentProvidersExists(
|
||||||
|
paymentService,
|
||||||
|
uniquePaymentProviderIds
|
||||||
|
)
|
||||||
|
|
||||||
|
const regionIds = dataInputToProcess.map((inputData) => inputData.id)
|
||||||
|
const currentExistingLinks = await getCurrentRegionPaymentProvidersLinks(
|
||||||
|
regionIds,
|
||||||
|
{ remoteQuery }
|
||||||
|
)
|
||||||
|
|
||||||
|
const linksToRemove: LinkItems = currentExistingLinks
|
||||||
|
.filter((existingLink) => {
|
||||||
|
return !dataInputToProcess.some((input) => {
|
||||||
|
return (
|
||||||
|
input.id === existingLink[Modules.REGION].region_id &&
|
||||||
|
input.payment_providers.includes(
|
||||||
|
existingLink[Modules.PAYMENT].payment_provider_id
|
||||||
|
)
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.map((link) => {
|
||||||
|
return {
|
||||||
|
[Modules.REGION]: { region_id: link[Modules.REGION].region_id },
|
||||||
|
[Modules.PAYMENT]: {
|
||||||
|
payment_provider_id: link[Modules.PAYMENT].payment_provider_id,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const linksToCreate = dataInputToProcess
|
||||||
|
.map((inputData) => {
|
||||||
|
return inputData.payment_providers.map((provider) => {
|
||||||
|
const alreadyExists = currentExistingLinks.some((link) => {
|
||||||
|
return (
|
||||||
|
link[Modules.REGION].region_id === inputData.id &&
|
||||||
|
link[Modules.PAYMENT].payment_provider_id === provider
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
if (alreadyExists) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
[Modules.REGION]: { region_id: inputData.id },
|
||||||
|
[Modules.PAYMENT]: { payment_provider_id: provider },
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.flat()
|
||||||
|
.filter((d): d is LinkItems[0] => !!d)
|
||||||
|
|
||||||
|
const promises: Promise<unknown[]>[] = []
|
||||||
|
|
||||||
|
if (linksToRemove.length) {
|
||||||
|
promises.push(remoteLink.dismiss(linksToRemove))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (linksToCreate.length) {
|
||||||
|
promises.push(remoteLink.create(linksToCreate))
|
||||||
|
}
|
||||||
|
|
||||||
|
await promiseAll(promises)
|
||||||
|
|
||||||
|
return new StepResponse(void 0, {
|
||||||
|
linksToCreate: linksToRemove,
|
||||||
|
linksToRemove: linksToCreate,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
async (rollbackData, { container }) => {
|
||||||
|
if (!rollbackData) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const remoteLink = container.resolve<RemoteLink>(
|
||||||
|
ContainerRegistrationKeys.REMOTE_LINK
|
||||||
|
)
|
||||||
|
|
||||||
|
const promises: Promise<unknown[]>[] = []
|
||||||
|
|
||||||
|
if (rollbackData.linksToRemove.length) {
|
||||||
|
promises.push(remoteLink.dismiss(rollbackData.linksToRemove))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rollbackData.linksToCreate.length) {
|
||||||
|
promises.push(remoteLink.create(rollbackData.linksToCreate))
|
||||||
|
}
|
||||||
|
|
||||||
|
await promiseAll(promises)
|
||||||
|
}
|
||||||
|
)
|
||||||
@@ -29,6 +29,10 @@ export const updateRegionsStep = createStep(
|
|||||||
relations,
|
relations,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
if (Object.keys(data.update).length === 0) {
|
||||||
|
return new StepResponse(prevData, [])
|
||||||
|
}
|
||||||
|
|
||||||
const regions = await service.update(data.selector, data.update)
|
const regions = await service.update(data.selector, data.update)
|
||||||
|
|
||||||
return new StepResponse(regions, prevData)
|
return new StepResponse(regions, prevData)
|
||||||
@@ -48,7 +52,7 @@ export const updateRegionsStep = createStep(
|
|||||||
name: r.name,
|
name: r.name,
|
||||||
currency_code: r.currency_code,
|
currency_code: r.currency_code,
|
||||||
metadata: r.metadata,
|
metadata: r.metadata,
|
||||||
countries: r.countries.map((c) => c.iso_2),
|
countries: r.countries?.map((c) => c.iso_2),
|
||||||
}))
|
}))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,57 @@
|
|||||||
import { CreateRegionDTO, RegionDTO } from "@medusajs/types"
|
import { WorkflowTypes } from "@medusajs/types"
|
||||||
import { WorkflowData, createWorkflow } from "@medusajs/workflows-sdk"
|
import {
|
||||||
|
createWorkflow,
|
||||||
|
transform,
|
||||||
|
WorkflowData,
|
||||||
|
} from "@medusajs/workflows-sdk"
|
||||||
import { createRegionsStep } from "../steps"
|
import { createRegionsStep } from "../steps"
|
||||||
|
import { setRegionsPaymentProvidersStep } from "../steps/set-regions-payment-providers"
|
||||||
type WorkflowInput = { regionsData: CreateRegionDTO[] }
|
|
||||||
|
|
||||||
export const createRegionsWorkflowId = "create-regions"
|
export const createRegionsWorkflowId = "create-regions"
|
||||||
export const createRegionsWorkflow = createWorkflow(
|
export const createRegionsWorkflow = createWorkflow(
|
||||||
createRegionsWorkflowId,
|
createRegionsWorkflowId,
|
||||||
(input: WorkflowData<WorkflowInput>): WorkflowData<RegionDTO[]> => {
|
(
|
||||||
return createRegionsStep(input.regionsData)
|
input: WorkflowData<WorkflowTypes.RegionWorkflow.CreateRegionsWorkflowInput>
|
||||||
|
): WorkflowData<WorkflowTypes.RegionWorkflow.CreateRegionsWorkflowOutput> => {
|
||||||
|
const data = transform(input, (data) => {
|
||||||
|
const regionIndexToPaymentProviders = data.regions.map(
|
||||||
|
(region, index) => {
|
||||||
|
return {
|
||||||
|
region_index: index,
|
||||||
|
payment_providers: region.payment_providers,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
return {
|
||||||
|
regions: data.regions,
|
||||||
|
regionIndexToPaymentProviders,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const regions = createRegionsStep(data.regions)
|
||||||
|
|
||||||
|
const normalizedRegionProviderData = transform(
|
||||||
|
{
|
||||||
|
regionIndexToPaymentProviders: data.regionIndexToPaymentProviders,
|
||||||
|
regions,
|
||||||
|
},
|
||||||
|
(data) => {
|
||||||
|
return data.regionIndexToPaymentProviders.map(
|
||||||
|
({ region_index, payment_providers }) => {
|
||||||
|
return {
|
||||||
|
id: data.regions[region_index].id,
|
||||||
|
payment_providers,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
setRegionsPaymentProvidersStep({
|
||||||
|
input: normalizedRegionProviderData,
|
||||||
|
})
|
||||||
|
|
||||||
|
return regions
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@@ -1,22 +1,46 @@
|
|||||||
|
import { WorkflowTypes } from "@medusajs/types"
|
||||||
import {
|
import {
|
||||||
FilterableRegionProps,
|
createWorkflow,
|
||||||
RegionDTO,
|
transform,
|
||||||
UpdateRegionDTO,
|
WorkflowData,
|
||||||
} from "@medusajs/types"
|
} from "@medusajs/workflows-sdk"
|
||||||
import { WorkflowData, createWorkflow } from "@medusajs/workflows-sdk"
|
|
||||||
import { updateRegionsStep } from "../steps"
|
import { updateRegionsStep } from "../steps"
|
||||||
|
import { setRegionsPaymentProvidersStep } from "../steps/set-regions-payment-providers"
|
||||||
type UpdateRegionsStepInput = {
|
|
||||||
selector: FilterableRegionProps
|
|
||||||
update: UpdateRegionDTO
|
|
||||||
}
|
|
||||||
|
|
||||||
type WorkflowInput = UpdateRegionsStepInput
|
|
||||||
|
|
||||||
export const updateRegionsWorkflowId = "update-regions"
|
export const updateRegionsWorkflowId = "update-regions"
|
||||||
export const updateRegionsWorkflow = createWorkflow(
|
export const updateRegionsWorkflow = createWorkflow(
|
||||||
updateRegionsWorkflowId,
|
updateRegionsWorkflowId,
|
||||||
(input: WorkflowData<WorkflowInput>): WorkflowData<RegionDTO[]> => {
|
(
|
||||||
return updateRegionsStep(input)
|
input: WorkflowData<WorkflowTypes.RegionWorkflow.UpdateRegionsWorkflowInput>
|
||||||
|
): WorkflowData<WorkflowTypes.RegionWorkflow.UpdateRegionsWorkflowOutput> => {
|
||||||
|
const data = transform(input, (data) => {
|
||||||
|
const { selector, update } = data
|
||||||
|
const { payment_providers = [], ...rest } = update
|
||||||
|
return {
|
||||||
|
selector,
|
||||||
|
update: rest,
|
||||||
|
payment_providers,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const regions = updateRegionsStep(data)
|
||||||
|
|
||||||
|
const upsertProvidersNormalizedInput = transform(
|
||||||
|
{ data, regions },
|
||||||
|
(data) => {
|
||||||
|
return data.regions.map((region) => {
|
||||||
|
return {
|
||||||
|
id: region.id,
|
||||||
|
payment_providers: data.data.payment_providers,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
setRegionsPaymentProvidersStep({
|
||||||
|
input: upsertProvidersNormalizedInput,
|
||||||
|
})
|
||||||
|
|
||||||
|
return regions
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import { Modules } from "@medusajs/modules-sdk"
|
import { Modules } from "@medusajs/modules-sdk"
|
||||||
import { ModuleJoinerConfig } from "@medusajs/types"
|
import { ModuleJoinerConfig } from "@medusajs/types"
|
||||||
import { LINKS } from "../links"
|
import { LINKS } from "@medusajs/utils"
|
||||||
|
|
||||||
export const CartPaymentCollection: ModuleJoinerConfig = {
|
export const CartPaymentCollection: ModuleJoinerConfig = {
|
||||||
serviceName: LINKS.CartPaymentCollection,
|
serviceName: LINKS.CartPaymentCollection,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { Modules } from "@medusajs/modules-sdk"
|
import { Modules } from "@medusajs/modules-sdk"
|
||||||
import { ModuleJoinerConfig } from "@medusajs/types"
|
import { ModuleJoinerConfig } from "@medusajs/types"
|
||||||
import { LINKS } from "../links"
|
import { LINKS } from "@medusajs/utils"
|
||||||
|
|
||||||
export const CartPromotion: ModuleJoinerConfig = {
|
export const CartPromotion: ModuleJoinerConfig = {
|
||||||
serviceName: LINKS.CartPromotion,
|
serviceName: LINKS.CartPromotion,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { Modules } from "@medusajs/modules-sdk"
|
import { Modules } from "@medusajs/modules-sdk"
|
||||||
import { ModuleJoinerConfig } from "@medusajs/types"
|
import { ModuleJoinerConfig } from "@medusajs/types"
|
||||||
import { LINKS } from "../links"
|
import { LINKS } from "@medusajs/utils"
|
||||||
|
|
||||||
export const FulfillmentSetLocation: ModuleJoinerConfig = {
|
export const FulfillmentSetLocation: ModuleJoinerConfig = {
|
||||||
serviceName: LINKS.FulfillmentSetLocation,
|
serviceName: LINKS.FulfillmentSetLocation,
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { ModuleJoinerConfig } from "@medusajs/types"
|
import { ModuleJoinerConfig } from "@medusajs/types"
|
||||||
|
import { LINKS } from "@medusajs/utils"
|
||||||
import { LINKS } from "../links"
|
|
||||||
|
|
||||||
export const OrderSalesChannel: ModuleJoinerConfig = {
|
export const OrderSalesChannel: ModuleJoinerConfig = {
|
||||||
serviceName: LINKS.OrderSalesChannel,
|
serviceName: LINKS.OrderSalesChannel,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { Modules } from "@medusajs/modules-sdk"
|
import { Modules } from "@medusajs/modules-sdk"
|
||||||
import { ModuleJoinerConfig } from "@medusajs/types"
|
import { ModuleJoinerConfig } from "@medusajs/types"
|
||||||
import { LINKS } from "../links"
|
import { LINKS } from "@medusajs/utils"
|
||||||
|
|
||||||
export const ProductSalesChannel: ModuleJoinerConfig = {
|
export const ProductSalesChannel: ModuleJoinerConfig = {
|
||||||
serviceName: LINKS.ProductSalesChannel,
|
serviceName: LINKS.ProductSalesChannel,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { Modules } from "@medusajs/modules-sdk"
|
import { Modules } from "@medusajs/modules-sdk"
|
||||||
import { ModuleJoinerConfig } from "@medusajs/types"
|
import { ModuleJoinerConfig } from "@medusajs/types"
|
||||||
import { LINKS } from "../links"
|
import { LINKS } from "@medusajs/utils"
|
||||||
|
|
||||||
export const ProductShippingProfile: ModuleJoinerConfig = {
|
export const ProductShippingProfile: ModuleJoinerConfig = {
|
||||||
serviceName: LINKS.ProductShippingProfile,
|
serviceName: LINKS.ProductShippingProfile,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { Modules } from "@medusajs/modules-sdk"
|
import { Modules } from "@medusajs/modules-sdk"
|
||||||
import { ModuleJoinerConfig } from "@medusajs/types"
|
import { ModuleJoinerConfig } from "@medusajs/types"
|
||||||
import { LINKS } from "../links"
|
import { LINKS } from "@medusajs/utils"
|
||||||
|
|
||||||
export const ProductVariantInventoryItem: ModuleJoinerConfig = {
|
export const ProductVariantInventoryItem: ModuleJoinerConfig = {
|
||||||
serviceName: LINKS.ProductVariantInventoryItem,
|
serviceName: LINKS.ProductVariantInventoryItem,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { Modules } from "@medusajs/modules-sdk"
|
import { Modules } from "@medusajs/modules-sdk"
|
||||||
import { ModuleJoinerConfig } from "@medusajs/types"
|
import { ModuleJoinerConfig } from "@medusajs/types"
|
||||||
import { LINKS } from "../links"
|
import { LINKS } from "@medusajs/utils"
|
||||||
|
|
||||||
export const ProductVariantPriceSet: ModuleJoinerConfig = {
|
export const ProductVariantPriceSet: ModuleJoinerConfig = {
|
||||||
serviceName: LINKS.ProductVariantPriceSet,
|
serviceName: LINKS.ProductVariantPriceSet,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { Modules } from "@medusajs/modules-sdk"
|
import { Modules } from "@medusajs/modules-sdk"
|
||||||
import { ModuleJoinerConfig } from "@medusajs/types"
|
import { ModuleJoinerConfig } from "@medusajs/types"
|
||||||
import { LINKS } from "../links"
|
import { LINKS } from "@medusajs/utils"
|
||||||
|
|
||||||
export const PublishableApiKeySalesChannel: ModuleJoinerConfig = {
|
export const PublishableApiKeySalesChannel: ModuleJoinerConfig = {
|
||||||
serviceName: LINKS.PublishableApiKeySalesChannel,
|
serviceName: LINKS.PublishableApiKeySalesChannel,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { Modules } from "@medusajs/modules-sdk"
|
import { Modules } from "@medusajs/modules-sdk"
|
||||||
import { ModuleJoinerConfig } from "@medusajs/types"
|
import { ModuleJoinerConfig } from "@medusajs/types"
|
||||||
import { LINKS } from "../links"
|
import { LINKS } from "@medusajs/utils"
|
||||||
|
|
||||||
export const RegionPaymentProvider: ModuleJoinerConfig = {
|
export const RegionPaymentProvider: ModuleJoinerConfig = {
|
||||||
serviceName: LINKS.RegionPaymentProvider,
|
serviceName: LINKS.RegionPaymentProvider,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { Modules } from "@medusajs/modules-sdk"
|
import { Modules } from "@medusajs/modules-sdk"
|
||||||
import { ModuleJoinerConfig } from "@medusajs/types"
|
import { ModuleJoinerConfig } from "@medusajs/types"
|
||||||
import { LINKS } from "../links"
|
import { LINKS } from "@medusajs/utils"
|
||||||
|
|
||||||
export const SalesChannelLocation: ModuleJoinerConfig = {
|
export const SalesChannelLocation: ModuleJoinerConfig = {
|
||||||
serviceName: LINKS.SalesChannelLocation,
|
serviceName: LINKS.SalesChannelLocation,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { Modules } from "@medusajs/modules-sdk"
|
import { Modules } from "@medusajs/modules-sdk"
|
||||||
import { ModuleJoinerConfig } from "@medusajs/types"
|
import { ModuleJoinerConfig } from "@medusajs/types"
|
||||||
import { LINKS } from "../links"
|
import { LINKS } from "@medusajs/utils"
|
||||||
|
|
||||||
export const ShippingOptionPriceSet: ModuleJoinerConfig = {
|
export const ShippingOptionPriceSet: ModuleJoinerConfig = {
|
||||||
serviceName: LINKS.ShippingOptionPriceSet,
|
serviceName: LINKS.ShippingOptionPriceSet,
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { getDatabaseURL } from "./database"
|
|||||||
import { initDb } from "./medusa-test-runner-utils/use-db"
|
import { initDb } from "./medusa-test-runner-utils/use-db"
|
||||||
import { startBootstrapApp } from "./medusa-test-runner-utils/bootstrap-app"
|
import { startBootstrapApp } from "./medusa-test-runner-utils/bootstrap-app"
|
||||||
import { createDatabase, dropDatabase } from "pg-god"
|
import { createDatabase, dropDatabase } from "pg-god"
|
||||||
import { ContainerLike } from "@medusajs/types"
|
import {ContainerLike, MedusaContainer} from "@medusajs/types"
|
||||||
import { createMedusaContainer } from "@medusajs/utils"
|
import { createMedusaContainer } from "@medusajs/utils"
|
||||||
|
|
||||||
const axios = require("axios").default
|
const axios = require("axios").default
|
||||||
@@ -70,7 +70,7 @@ const dbTestUtilFactory = (): any => ({
|
|||||||
export interface MedusaSuiteOptions<TService = unknown> {
|
export interface MedusaSuiteOptions<TService = unknown> {
|
||||||
dbUtils: any
|
dbUtils: any
|
||||||
dbConnection: any // Legacy typeorm connection
|
dbConnection: any // Legacy typeorm connection
|
||||||
getContainer: () => ContainerLike
|
getContainer: () => MedusaContainer
|
||||||
api: any
|
api: any
|
||||||
dbConfig: {
|
dbConfig: {
|
||||||
dbName: string
|
dbName: string
|
||||||
@@ -89,7 +89,7 @@ export function medusaIntegrationTestRunner({
|
|||||||
testSuite,
|
testSuite,
|
||||||
}: {
|
}: {
|
||||||
moduleName?: string
|
moduleName?: string
|
||||||
env?: Record<string, string>
|
env?: Record<string, string | any>
|
||||||
dbName?: string
|
dbName?: string
|
||||||
schema?: string
|
schema?: string
|
||||||
debug?: boolean
|
debug?: boolean
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ export function moduleIntegrationTestRunner({
|
|||||||
injectedDependencies?: Record<string, any>
|
injectedDependencies?: Record<string, any>
|
||||||
resolve?: string
|
resolve?: string
|
||||||
debug?: boolean
|
debug?: boolean
|
||||||
testSuite: <TService = unknown>(options: SuiteOptions<TService>) => () => void
|
testSuite: <TService = unknown>(options: SuiteOptions<TService>) => void
|
||||||
}) {
|
}) {
|
||||||
const moduleSdkImports = require("@medusajs/modules-sdk")
|
const moduleSdkImports = require("@medusajs/modules-sdk")
|
||||||
|
|
||||||
|
|||||||
@@ -8,8 +8,10 @@ import {
|
|||||||
} from "@medusajs/core-flows"
|
} from "@medusajs/core-flows"
|
||||||
|
|
||||||
import { UpdateRegionDTO } from "@medusajs/types"
|
import { UpdateRegionDTO } from "@medusajs/types"
|
||||||
import { defaultAdminRegionFields } from "../query-config"
|
import {
|
||||||
import { remoteQueryObjectFromString } from "@medusajs/utils"
|
ContainerRegistrationKeys,
|
||||||
|
remoteQueryObjectFromString
|
||||||
|
} from "@medusajs/utils"
|
||||||
|
|
||||||
export const GET = async (
|
export const GET = async (
|
||||||
req: AuthenticatedMedusaRequest,
|
req: AuthenticatedMedusaRequest,
|
||||||
@@ -22,7 +24,7 @@ export const GET = async (
|
|||||||
const queryObject = remoteQueryObjectFromString({
|
const queryObject = remoteQueryObjectFromString({
|
||||||
entryPoint: "region",
|
entryPoint: "region",
|
||||||
variables,
|
variables,
|
||||||
fields: defaultAdminRegionFields,
|
fields: req.remoteQueryConfig.fields,
|
||||||
})
|
})
|
||||||
|
|
||||||
const [region] = await remoteQuery(queryObject)
|
const [region] = await remoteQuery(queryObject)
|
||||||
@@ -46,7 +48,19 @@ export const POST = async (
|
|||||||
throw errors[0].error
|
throw errors[0].error
|
||||||
}
|
}
|
||||||
|
|
||||||
res.status(200).json({ region: result[0] })
|
const remoteQuery = req.scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY)
|
||||||
|
|
||||||
|
const queryObject = remoteQueryObjectFromString({
|
||||||
|
entryPoint: "region",
|
||||||
|
variables: {
|
||||||
|
filters: { id: req.params.id },
|
||||||
|
},
|
||||||
|
fields: req.remoteQueryConfig.fields,
|
||||||
|
})
|
||||||
|
|
||||||
|
const regions = await remoteQuery(queryObject)
|
||||||
|
|
||||||
|
res.status(200).json({ region: regions[0] })
|
||||||
}
|
}
|
||||||
|
|
||||||
export const DELETE = async (
|
export const DELETE = async (
|
||||||
|
|||||||
@@ -40,11 +40,23 @@ export const adminRegionRoutesMiddlewares: MiddlewareRoute[] = [
|
|||||||
{
|
{
|
||||||
method: ["POST"],
|
method: ["POST"],
|
||||||
matcher: "/admin/regions",
|
matcher: "/admin/regions",
|
||||||
middlewares: [transformBody(AdminPostRegionsReq)],
|
middlewares: [
|
||||||
|
transformQuery(
|
||||||
|
AdminGetRegionsRegionParams,
|
||||||
|
QueryConfig.retrieveTransformQueryConfig
|
||||||
|
),
|
||||||
|
transformBody(AdminPostRegionsReq),
|
||||||
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
method: ["POST"],
|
method: ["POST"],
|
||||||
matcher: "/admin/regions/:id",
|
matcher: "/admin/regions/:id",
|
||||||
middlewares: [transformBody(AdminPostRegionsRegionReq)],
|
middlewares: [
|
||||||
|
transformQuery(
|
||||||
|
AdminGetRegionsRegionParams,
|
||||||
|
QueryConfig.retrieveTransformQueryConfig
|
||||||
|
),
|
||||||
|
transformBody(AdminPostRegionsRegionReq),
|
||||||
|
],
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
@@ -1,5 +1,3 @@
|
|||||||
export const defaultAdminRegionRelations = ["countries"]
|
|
||||||
export const allowedAdminRegionRelations = ["countries"]
|
|
||||||
export const defaultAdminRegionFields = [
|
export const defaultAdminRegionFields = [
|
||||||
"id",
|
"id",
|
||||||
"name",
|
"name",
|
||||||
@@ -16,13 +14,12 @@ export const defaultAdminRegionFields = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
export const retrieveTransformQueryConfig = {
|
export const retrieveTransformQueryConfig = {
|
||||||
defaultFields: defaultAdminRegionFields,
|
defaults: defaultAdminRegionFields,
|
||||||
defaultRelations: defaultAdminRegionRelations,
|
|
||||||
allowedRelations: allowedAdminRegionRelations,
|
|
||||||
isList: false,
|
isList: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
export const listTransformQueryConfig = {
|
export const listTransformQueryConfig = {
|
||||||
|
defaults: defaultAdminRegionFields,
|
||||||
defaultLimit: 20,
|
defaultLimit: 20,
|
||||||
isList: true,
|
isList: true,
|
||||||
}
|
}
|
||||||
@@ -5,24 +5,24 @@ import {
|
|||||||
|
|
||||||
import { CreateRegionDTO } from "@medusajs/types"
|
import { CreateRegionDTO } from "@medusajs/types"
|
||||||
import { createRegionsWorkflow } from "@medusajs/core-flows"
|
import { createRegionsWorkflow } from "@medusajs/core-flows"
|
||||||
import { defaultAdminRegionFields } from "./query-config"
|
import {
|
||||||
import { remoteQueryObjectFromString } from "@medusajs/utils"
|
ContainerRegistrationKeys,
|
||||||
|
remoteQueryObjectFromString,
|
||||||
|
} from "@medusajs/utils"
|
||||||
|
|
||||||
export const GET = async (
|
export const GET = async (
|
||||||
req: AuthenticatedMedusaRequest,
|
req: AuthenticatedMedusaRequest,
|
||||||
res: MedusaResponse
|
res: MedusaResponse
|
||||||
) => {
|
) => {
|
||||||
const remoteQuery = req.scope.resolve("remoteQuery")
|
const remoteQuery = req.scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY)
|
||||||
|
|
||||||
const queryObject = remoteQueryObjectFromString({
|
const queryObject = remoteQueryObjectFromString({
|
||||||
entryPoint: "region",
|
entryPoint: "region",
|
||||||
variables: {
|
variables: {
|
||||||
filters: req.filterableFields,
|
filters: req.filterableFields,
|
||||||
order: req.listConfig.order,
|
...req.remoteQueryConfig.pagination,
|
||||||
skip: req.listConfig.skip,
|
|
||||||
take: req.listConfig.take,
|
|
||||||
},
|
},
|
||||||
fields: defaultAdminRegionFields,
|
fields: req.remoteQueryConfig.fields,
|
||||||
})
|
})
|
||||||
|
|
||||||
const { rows: regions, metadata } = await remoteQuery(queryObject)
|
const { rows: regions, metadata } = await remoteQuery(queryObject)
|
||||||
@@ -46,7 +46,7 @@ export const POST = async (
|
|||||||
]
|
]
|
||||||
|
|
||||||
const { result, errors } = await createRegionsWorkflow(req.scope).run({
|
const { result, errors } = await createRegionsWorkflow(req.scope).run({
|
||||||
input: { regionsData: input },
|
input: { regions: input },
|
||||||
throwOnError: false,
|
throwOnError: false,
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -54,5 +54,17 @@ export const POST = async (
|
|||||||
throw errors[0].error
|
throw errors[0].error
|
||||||
}
|
}
|
||||||
|
|
||||||
res.status(200).json({ region: result[0] })
|
const remoteQuery = req.scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY)
|
||||||
|
|
||||||
|
const queryObject = remoteQueryObjectFromString({
|
||||||
|
entryPoint: "region",
|
||||||
|
variables: {
|
||||||
|
filters: { id: result[0].id },
|
||||||
|
},
|
||||||
|
fields: req.remoteQueryConfig.fields,
|
||||||
|
})
|
||||||
|
|
||||||
|
const regions = await remoteQuery(queryObject)
|
||||||
|
|
||||||
|
res.status(200).json({ region: regions[0] })
|
||||||
}
|
}
|
||||||
@@ -7,7 +7,7 @@ import {
|
|||||||
IsString,
|
IsString,
|
||||||
ValidateNested,
|
ValidateNested,
|
||||||
} from "class-validator"
|
} from "class-validator"
|
||||||
import { FindParams, extendedFindParamsMixin } from "../../../types/common"
|
import { extendedFindParamsMixin, FindParams } from "../../../types/common"
|
||||||
import { OperatorMapValidator } from "../../../types/validators/operator-map"
|
import { OperatorMapValidator } from "../../../types/validators/operator-map"
|
||||||
|
|
||||||
export class AdminGetRegionsRegionParams extends FindParams {}
|
export class AdminGetRegionsRegionParams extends FindParams {}
|
||||||
@@ -90,6 +90,11 @@ export class AdminPostRegionsReq {
|
|||||||
@IsObject()
|
@IsObject()
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
metadata?: Record<string, unknown>
|
metadata?: Record<string, unknown>
|
||||||
|
|
||||||
|
@IsOptional()
|
||||||
|
@IsArray()
|
||||||
|
@IsString({ each: true })
|
||||||
|
payment_providers?: string[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export class AdminPostRegionsRegionReq {
|
export class AdminPostRegionsRegionReq {
|
||||||
@@ -108,4 +113,9 @@ export class AdminPostRegionsRegionReq {
|
|||||||
@IsObject()
|
@IsObject()
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
metadata?: Record<string, unknown>
|
metadata?: Record<string, unknown>
|
||||||
|
|
||||||
|
@IsOptional()
|
||||||
|
@IsArray()
|
||||||
|
@IsString({ each: true })
|
||||||
|
payment_providers?: string[]
|
||||||
}
|
}
|
||||||
@@ -11,6 +11,7 @@ export enum LinkModuleUtils {
|
|||||||
REMOTE_LINK = "remoteLink",
|
REMOTE_LINK = "remoteLink",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Remove this enum and use the one from @medusajs/utils
|
||||||
export enum Modules {
|
export enum Modules {
|
||||||
AUTH = "auth",
|
AUTH = "auth",
|
||||||
CACHE = "cacheService",
|
CACHE = "cacheService",
|
||||||
|
|||||||
@@ -70,7 +70,11 @@ export function toRemoteJoinerQuery(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (isEntryPoint) {
|
if (isEntryPoint) {
|
||||||
|
if (value.isServiceAccess) {
|
||||||
|
remoteJoinerQuery.service = key
|
||||||
|
} else {
|
||||||
remoteJoinerQuery.alias = key
|
remoteJoinerQuery.alias = key
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
remoteJoinerQuery.expands!.push(expandObj)
|
remoteJoinerQuery.expands!.push(expandObj)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,3 +8,4 @@ export default moduleDefinition
|
|||||||
export { revertMigration, runMigrations }
|
export { revertMigration, runMigrations }
|
||||||
|
|
||||||
export * from "./initialize"
|
export * from "./initialize"
|
||||||
|
export * from "./types"
|
||||||
@@ -1,5 +1,27 @@
|
|||||||
import { Logger } from "@medusajs/types"
|
import {
|
||||||
|
Logger,
|
||||||
|
ModuleProviderExports,
|
||||||
|
ModuleServiceInitializeOptions,
|
||||||
|
} from "@medusajs/types"
|
||||||
|
|
||||||
export type InitializeModuleInjectableDependencies = {
|
export type InitializeModuleInjectableDependencies = {
|
||||||
logger?: Logger
|
logger?: Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type PaymentModuleOptions = Partial<ModuleServiceInitializeOptions> & {
|
||||||
|
/**
|
||||||
|
* Providers to be registered
|
||||||
|
*/
|
||||||
|
providers?: {
|
||||||
|
/**
|
||||||
|
* The module provider to be registered
|
||||||
|
*/
|
||||||
|
resolve: string | ModuleProviderExports
|
||||||
|
options: {
|
||||||
|
/**
|
||||||
|
* key value pair of the provider name and the configuration to be passed to the provider constructor
|
||||||
|
*/
|
||||||
|
config: Record<string, unknown>
|
||||||
|
}
|
||||||
|
}[]
|
||||||
|
}
|
||||||
@@ -465,7 +465,7 @@ export interface FilterablePaymentProviderProps
|
|||||||
/**
|
/**
|
||||||
* The IDs to filter the payment collection by.
|
* The IDs to filter the payment collection by.
|
||||||
*/
|
*/
|
||||||
id?: string | string[]
|
id?: string | string[] | OperatorMap<string | string[]>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Filter by enabled status
|
* Filter by enabled status
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ export interface FilterableRegionProps
|
|||||||
/**
|
/**
|
||||||
* The IDs to filter the regions by.
|
* The IDs to filter the regions by.
|
||||||
*/
|
*/
|
||||||
id?: string[] | string
|
id?: string[] | string | OperatorMap<string | string[]>
|
||||||
/**
|
/**
|
||||||
* Filter regions by their name.
|
* Filter regions by their name.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -4,4 +4,5 @@ export * as ProductWorkflow from "./product"
|
|||||||
export * as InventoryWorkflow from "./inventory"
|
export * as InventoryWorkflow from "./inventory"
|
||||||
export * as PriceListWorkflow from "./price-list"
|
export * as PriceListWorkflow from "./price-list"
|
||||||
export * as UserWorkflow from "./user"
|
export * as UserWorkflow from "./user"
|
||||||
|
export * as RegionWorkflow from "./region"
|
||||||
export * as InviteWorkflow from "./invite"
|
export * as InviteWorkflow from "./invite"
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
import { CreateRegionDTO, RegionDTO } from "../../region"
|
||||||
|
|
||||||
|
export interface CreateRegionsWorkflowInput {
|
||||||
|
regions: (CreateRegionDTO & {
|
||||||
|
payment_providers?: string[]
|
||||||
|
})[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export type CreateRegionsWorkflowOutput = RegionDTO[]
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
export * from "./update-regions"
|
||||||
|
export * from "./create-regions"
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
import { FilterableRegionProps, RegionDTO, UpdateRegionDTO } from "../../region"
|
||||||
|
|
||||||
|
export interface UpdateRegionsWorkflowInput {
|
||||||
|
selector: FilterableRegionProps
|
||||||
|
update: UpdateRegionDTO & {
|
||||||
|
payment_providers?: string[]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export type UpdateRegionsWorkflowOutput = RegionDTO[]
|
||||||
@@ -13,4 +13,5 @@ export * as SearchUtils from "./search"
|
|||||||
export * as ShippingProfileUtils from "./shipping"
|
export * as ShippingProfileUtils from "./shipping"
|
||||||
export * as UserUtils from "./user"
|
export * as UserUtils from "./user"
|
||||||
export * as InventoryUtils from "./inventory"
|
export * as InventoryUtils from "./inventory"
|
||||||
|
export * as LinkUtils from "./link"
|
||||||
export * as ApiKeyUtils from "./api-key"
|
export * as ApiKeyUtils from "./api-key"
|
||||||
@@ -48,6 +48,57 @@ describe("remoteQueryObjectFromString", function () {
|
|||||||
"url",
|
"url",
|
||||||
"metadata",
|
"metadata",
|
||||||
],
|
],
|
||||||
|
isServiceAccess: false,
|
||||||
|
tags: {
|
||||||
|
fields: ["id", "created_at", "updated_at", "deleted_at", "value"],
|
||||||
|
},
|
||||||
|
|
||||||
|
options: {
|
||||||
|
fields: [
|
||||||
|
"id",
|
||||||
|
"created_at",
|
||||||
|
"updated_at",
|
||||||
|
"deleted_at",
|
||||||
|
"title",
|
||||||
|
"product_id",
|
||||||
|
"metadata",
|
||||||
|
],
|
||||||
|
values: {
|
||||||
|
fields: [
|
||||||
|
"id",
|
||||||
|
"created_at",
|
||||||
|
"updated_at",
|
||||||
|
"deleted_at",
|
||||||
|
"value",
|
||||||
|
"option_id",
|
||||||
|
"variant_id",
|
||||||
|
"metadata",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should return a remote query object using service entry point", function () {
|
||||||
|
const output = remoteQueryObjectFromString({
|
||||||
|
service: "product",
|
||||||
|
variables: {},
|
||||||
|
fields,
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(output).toEqual({
|
||||||
|
product: {
|
||||||
|
__args: {},
|
||||||
|
fields: [
|
||||||
|
"id",
|
||||||
|
"created_at",
|
||||||
|
"updated_at",
|
||||||
|
"deleted_at",
|
||||||
|
"url",
|
||||||
|
"metadata",
|
||||||
|
],
|
||||||
|
isServiceAccess: true,
|
||||||
tags: {
|
tags: {
|
||||||
fields: ["id", "created_at", "updated_at", "deleted_at", "value"],
|
fields: ["id", "created_at", "updated_at", "deleted_at", "value"],
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
/**
|
/**
|
||||||
* Convert a string fields array to a remote query object
|
* Convert a string fields array to a remote query object
|
||||||
* @param entryPoint
|
* @param config - The configuration object
|
||||||
* @param variables
|
|
||||||
* @param fields
|
|
||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
* const fields = [
|
* const fields = [
|
||||||
@@ -83,28 +81,41 @@
|
|||||||
* // },
|
* // },
|
||||||
* // }
|
* // }
|
||||||
*/
|
*/
|
||||||
export function remoteQueryObjectFromString({
|
export function remoteQueryObjectFromString(
|
||||||
entryPoint,
|
config:
|
||||||
variables,
|
| {
|
||||||
fields,
|
|
||||||
}: {
|
|
||||||
entryPoint: string
|
entryPoint: string
|
||||||
variables?: any
|
variables?: any
|
||||||
fields: string[]
|
fields: string[]
|
||||||
}): object {
|
}
|
||||||
|
| {
|
||||||
|
service: string
|
||||||
|
variables?: any
|
||||||
|
fields: string[]
|
||||||
|
}
|
||||||
|
): object {
|
||||||
|
const { entryPoint, service, variables, fields } = {
|
||||||
|
...config,
|
||||||
|
entryPoint: "entryPoint" in config ? config.entryPoint : undefined,
|
||||||
|
service: "service" in config ? config.service : undefined,
|
||||||
|
}
|
||||||
|
|
||||||
|
const entryKey = (entryPoint ?? service) as string
|
||||||
|
|
||||||
const remoteJoinerConfig: object = {
|
const remoteJoinerConfig: object = {
|
||||||
[entryPoint]: {
|
[entryKey]: {
|
||||||
fields: [],
|
fields: [],
|
||||||
|
isServiceAccess: !!service, // specifies if the entry point is a service
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
if (variables) {
|
if (variables) {
|
||||||
remoteJoinerConfig[entryPoint]["__args"] = variables
|
remoteJoinerConfig[entryKey]["__args"] = variables
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const field of fields) {
|
for (const field of fields) {
|
||||||
if (!field.includes(".")) {
|
if (!field.includes(".")) {
|
||||||
remoteJoinerConfig[entryPoint]["fields"].push(field)
|
remoteJoinerConfig[entryKey]["fields"].push(field)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,7 +125,7 @@ export function remoteQueryObjectFromString({
|
|||||||
const deepConfigRef = fieldSegments.reduce((acc, curr) => {
|
const deepConfigRef = fieldSegments.reduce((acc, curr) => {
|
||||||
acc[curr] ??= {}
|
acc[curr] ??= {}
|
||||||
return acc[curr]
|
return acc[curr]
|
||||||
}, remoteJoinerConfig[entryPoint])
|
}, remoteJoinerConfig[entryKey])
|
||||||
|
|
||||||
deepConfigRef["fields"] ??= []
|
deepConfigRef["fields"] ??= []
|
||||||
deepConfigRef["fields"].push(fieldProperty)
|
deepConfigRef["fields"].push(fieldProperty)
|
||||||
|
|||||||
@@ -22,5 +22,6 @@ export * from "./totals"
|
|||||||
export * from "./totals/big-number"
|
export * from "./totals/big-number"
|
||||||
export * from "./user"
|
export * from "./user"
|
||||||
export * from "./api-key"
|
export * from "./api-key"
|
||||||
|
export * from "./link"
|
||||||
|
|
||||||
export const MedusaModuleType = Symbol.for("MedusaModule")
|
export const MedusaModuleType = Symbol.for("MedusaModule")
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
import { lowerCaseFirst, toPascalCase } from "../common"
|
||||||
|
|
||||||
|
export const composeLinkName = (...args) => {
|
||||||
|
return lowerCaseFirst(toPascalCase(composeTableName(...args.concat("link"))))
|
||||||
|
}
|
||||||
|
|
||||||
|
export const composeTableName = (...args) => {
|
||||||
|
return args.map((name) => name.replace(/(_id|Service)$/gi, "")).join("_")
|
||||||
|
}
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
export * from "./links"
|
||||||
|
export * from "./compose-link-name"
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import { Modules } from "@medusajs/modules-sdk"
|
import { Modules } from "../modules-sdk"
|
||||||
import { composeLinkName } from "./utils"
|
import { composeLinkName } from "./compose-link-name"
|
||||||
|
|
||||||
export const LINKS = {
|
export const LINKS = {
|
||||||
ProductVariantInventoryItem: composeLinkName(
|
ProductVariantInventoryItem: composeLinkName(
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
export enum Modules {
|
||||||
|
AUTH = "auth",
|
||||||
|
CACHE = "cacheService",
|
||||||
|
CART = "cart",
|
||||||
|
CUSTOMER = "customer",
|
||||||
|
EVENT_BUS = "eventBus",
|
||||||
|
INVENTORY = "inventoryService",
|
||||||
|
LINK = "linkModules",
|
||||||
|
PAYMENT = "payment",
|
||||||
|
PRICING = "pricingService",
|
||||||
|
PRODUCT = "productService",
|
||||||
|
PROMOTION = "promotion",
|
||||||
|
SALES_CHANNEL = "salesChannel",
|
||||||
|
TAX = "tax",
|
||||||
|
FULFILLMENT = "fulfillment",
|
||||||
|
STOCK_LOCATION = "stockLocationService",
|
||||||
|
USER = "user",
|
||||||
|
WORKFLOW_ENGINE = "workflows",
|
||||||
|
REGION = "region",
|
||||||
|
ORDER = "order",
|
||||||
|
API_KEY = "apiKey",
|
||||||
|
STORE = "store",
|
||||||
|
CURRENCY = "currency",
|
||||||
|
}
|
||||||
@@ -8,3 +8,4 @@ export * from "./create-pg-connection"
|
|||||||
export * from "./migration-scripts"
|
export * from "./migration-scripts"
|
||||||
export * from "./internal-module-service-factory"
|
export * from "./internal-module-service-factory"
|
||||||
export * from "./abstract-module-service-factory"
|
export * from "./abstract-module-service-factory"
|
||||||
|
export * from "./definition"
|
||||||
Reference in new issue
Block a user