chore(orchestration): prevent throwing on already defined workflow (#5337)
**What** At the moment, when importing something from medusa entry point, if two medusa packages are installed because of a plugin, the evaluation of the import can end up throwing that a workflow is already defined. To prevent that from happening, we can just not throw if it is already defined and just return prematurely and make it idempotent.
This commit is contained in:
committed by
GitHub
parent
a1807aea83
commit
e47461d95c
@@ -80,6 +80,52 @@ describe("WorkflowManager", () => {
|
||||
expect(wf).toEqual(["create-product", "broken-delivery", "deliver-product"])
|
||||
})
|
||||
|
||||
it("should throw when registering a workflow with an existing id", () => {
|
||||
let err
|
||||
try {
|
||||
WorkflowManager.register(
|
||||
"create-product",
|
||||
{
|
||||
action: "foo",
|
||||
next: {
|
||||
action: "bar",
|
||||
next: {
|
||||
action: "xor",
|
||||
},
|
||||
},
|
||||
},
|
||||
handlers
|
||||
)
|
||||
} catch (e) {
|
||||
err = e
|
||||
}
|
||||
|
||||
expect(err).toBeDefined()
|
||||
expect(err.message).toBe(
|
||||
`Workflow with id "create-product" and step definition already exists.`
|
||||
)
|
||||
})
|
||||
|
||||
it("should not throw when registering a workflow with an existing id but identical definition", () => {
|
||||
let err
|
||||
try {
|
||||
WorkflowManager.register(
|
||||
"create-product",
|
||||
{
|
||||
action: "foo",
|
||||
next: {
|
||||
action: "bar",
|
||||
},
|
||||
},
|
||||
handlers
|
||||
)
|
||||
} catch (e) {
|
||||
err = e
|
||||
}
|
||||
|
||||
expect(err).not.toBeDefined()
|
||||
})
|
||||
|
||||
it("should begin a transaction and returns its final state", async () => {
|
||||
const flow = new LocalWorkflow("create-product", container)
|
||||
const transaction = await flow.run("t-id", {
|
||||
|
||||
@@ -75,12 +75,18 @@ export class WorkflowManager {
|
||||
requiredModules?: Set<string>,
|
||||
optionalModules?: Set<string>
|
||||
) {
|
||||
if (WorkflowManager.workflows.has(workflowId)) {
|
||||
throw new Error(`Workflow with id "${workflowId}" is already defined.`)
|
||||
}
|
||||
|
||||
const finalFlow = flow instanceof OrchestratorBuilder ? flow.build() : flow
|
||||
|
||||
if (WorkflowManager.workflows.has(workflowId)) {
|
||||
const areStepsEqual =
|
||||
JSON.stringify(finalFlow) ===
|
||||
JSON.stringify(WorkflowManager.workflows.get(workflowId)!.flow_)
|
||||
|
||||
if (!areStepsEqual) {
|
||||
throw new Error(`Workflow with id "${workflowId}" and step definition already exists.`)
|
||||
}
|
||||
}
|
||||
|
||||
WorkflowManager.workflows.set(workflowId, {
|
||||
id: workflowId,
|
||||
flow_: finalFlow,
|
||||
|
||||
33
packages/utils/src/common/__tests__/deep-equal-obj.spec.ts
Normal file
33
packages/utils/src/common/__tests__/deep-equal-obj.spec.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import { deepEqualObj } from "../deep-equal-obj"
|
||||
|
||||
describe("deepEqualObj", function () {
|
||||
it("should return true if objects are equal", function () {
|
||||
const object1 = {
|
||||
foo: "bar",
|
||||
bar: "foo",
|
||||
xar: { foo: "bar", wor: { bar: "foo", ror: ["test", "test1"] } },
|
||||
}
|
||||
const object2 = {
|
||||
foo: "bar",
|
||||
bar: "foo",
|
||||
xar: { foo: "bar", wor: { bar: "foo", ror: ["test", "test1"] } },
|
||||
}
|
||||
|
||||
expect(deepEqualObj(object1, object2)).toBe(true)
|
||||
})
|
||||
|
||||
it("should return false if objects are not equal", function () {
|
||||
const object1 = {
|
||||
foo: "bar",
|
||||
bar: "foo",
|
||||
xar: { foo: "bar", wor: { bar: "foo", ror: ["test", "test1"] } },
|
||||
}
|
||||
const object2 = {
|
||||
foo: "bar",
|
||||
bar: "foo",
|
||||
xar: { foo: "bar", wor: { bar: "foo", ror: ["test", "test1_"] } },
|
||||
}
|
||||
|
||||
expect(deepEqualObj(object1, object2)).toBe(false)
|
||||
})
|
||||
})
|
||||
24
packages/utils/src/common/deep-equal-obj.ts
Normal file
24
packages/utils/src/common/deep-equal-obj.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
export function deepEqualObj(obj1: object, obj2: object): boolean {
|
||||
if (typeof obj1 !== typeof obj2) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (typeof obj1 !== "object" || obj1 === null) {
|
||||
return obj1 === obj2
|
||||
}
|
||||
|
||||
const obj1Keys = Object.keys(obj1)
|
||||
const obj2Keys = Object.keys(obj2)
|
||||
|
||||
if (obj1Keys.length !== obj2Keys.length) {
|
||||
return false
|
||||
}
|
||||
|
||||
for (const key of obj1Keys) {
|
||||
if (!obj2Keys.includes(key) || !deepEqualObj(obj1[key], obj2[key])) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
@@ -29,3 +29,4 @@ export * from "./to-pascal-case"
|
||||
export * from "./transaction"
|
||||
export * from "./upper-case-first"
|
||||
export * from "./wrap-handler"
|
||||
export * from "./deep-equal-obj"
|
||||
|
||||
Reference in New Issue
Block a user