@medusajs/core-flows 2.22.0-snapshot-20261020204851 → 2.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/AGENTS.md +95 -0
  2. package/README.md +88 -0
  3. package/package.json +8 -5
package/AGENTS.md ADDED
@@ -0,0 +1,95 @@
1
+ # @medusajs/core-flows
2
+
3
+ Library of Medusa's prebuilt workflows and steps (cart, order, product, payment, fulfillment, etc.). The Medusa API routes are thin wrappers around these workflows, and apps reuse them to perform the same business logic with the same side effects (links, events, inventory, locks).
4
+
5
+ ## Using this package
6
+
7
+ - Import from `@medusajs/medusa/core-flows` in apps and plugins (re-export of this package). Inside the monorepo, `packages/medusa` imports `@medusajs/core-flows` directly.
8
+ - Every workflow and step has an exported ID constant next to it: `createProductsWorkflow` / `createProductsWorkflowId`, `createProductsStep` / `createProductsStepId`.
9
+ - Find the right workflow: read the matching API route in `packages/medusa/src/api/{admin,store}/...` to see which workflow it runs, or browse https://docs.medusajs.com/resources/medusa-workflows-reference.md (generated from the TSDoc in this package).
10
+
11
+ ```ts
12
+ import { createProductsWorkflow } from "@medusajs/medusa/core-flows"
13
+
14
+ const { result } = await createProductsWorkflow(req.scope).run({
15
+ input: {
16
+ products: [
17
+ { title: "Shirt", options: [{ title: "Size", values: ["S"] }] },
18
+ ],
19
+ additional_data: { erp_id: "123" },
20
+ },
21
+ })
22
+ ```
23
+
24
+ - Inside a custom workflow, call a prebuilt workflow with `.runAsStep({ input })`, and reuse prebuilt steps directly (e.g. `useQueryGraphStep`, `createRemoteLinkStep`, `emitEventStep`, `acquireLockStep`/`releaseLockStep`).
25
+ - `useQueryGraphStep` has the fixed step name `use-query-graph-step`; call `.config({ name: "..." })` when using it more than once in a workflow.
26
+
27
+ ### Extending via hooks
28
+
29
+ - Workflows expose hooks through `createHook` and list them in `@property hooks.<name>` TSDoc. Consume them in `src/workflows/hooks/*.ts`:
30
+
31
+ ```ts
32
+ import { createProductsWorkflow } from "@medusajs/medusa/core-flows"
33
+ import { StepResponse } from "@medusajs/framework/workflows-sdk"
34
+
35
+ createProductsWorkflow.hooks.productsCreated(
36
+ async ({ products, additional_data }, { container }) => {
37
+ return new StepResponse(undefined, products.map((p) => p.id))
38
+ },
39
+ async (productIds, { container }) => {}
40
+ )
41
+ ```
42
+
43
+ - Hook inputs usually include `additional_data`, which API routes forward from the request body (see https://docs.medusajs.com/learn/fundamentals/api-routes/additional-data.md).
44
+ - One handler per hook per workflow. Docs: https://docs.medusajs.com/learn/fundamentals/workflows/workflow-hooks.md
45
+
46
+ ## Architecture
47
+
48
+ - `src/<domain>/` per commerce domain (e.g. `cart`, `order`, `product`, `payment-collection`, `locking`, `common`, `defaults`), each with:
49
+ - `steps/`: one step per file, mostly a single module-service call plus a compensation that undoes it.
50
+ - `workflows/`: compositions of steps; `order/workflows/` has subfolders for order changes (`claim`, `exchange`, `order-edit`, `return`, `transfer`).
51
+ - `utils/` (or `helpers/`): plain functions and field lists shared by the domain.
52
+ - `index.ts` barrels re-exported by `src/index.ts`.
53
+ - `common/` holds cross-domain steps/workflows: `useQueryGraphStep`, `useRemoteQueryStep`, `emitEventStep`, `createRemoteLinkStep`, `dismissRemoteLinkStep`, `updateRemoteLinksStep`, `createEntitiesStep`, `deleteEntitiesStep`, and `createLinksWorkflow`/`updateLinksWorkflow`/`dismissLinksWorkflow`/`batchLinksWorkflow`.
54
+ - Cart and other concurrency-sensitive workflows wrap their body in `acquireLockStep({ key: input.cart_id, ... })` / `releaseLockStep` (from `locking/`).
55
+ - Step convention (see `product/steps/create-products.ts`):
56
+
57
+ ```ts
58
+ export const createProductsStepId = "create-products"
59
+ export const createProductsStep = createStep(
60
+ createProductsStepId,
61
+ async (data: ProductTypes.CreateProductDTO[], { container }) => {
62
+ const service = container.resolve<IProductModuleService>(Modules.PRODUCT)
63
+ const created = await service.createProducts(data)
64
+ return new StepResponse(created, created.map((product) => product.id))
65
+ },
66
+ async (createdIds, { container }) => {
67
+ if (!createdIds?.length) {
68
+ return
69
+ }
70
+ const service = container.resolve<IProductModuleService>(Modules.PRODUCT)
71
+ await service.deleteProducts(createdIds)
72
+ }
73
+ )
74
+ ```
75
+
76
+ ## Development
77
+
78
+ ```bash
79
+ yarn workspace @medusajs/core-flows build
80
+ yarn workspace @medusajs/core-flows test
81
+ cd packages/core/core-flows && ../../../node_modules/.bin/jest src/cart/utils/__tests__/prepare-confirm-inventory-input.spec.ts
82
+ ```
83
+
84
+ - Unit tests are sparse (`src/**/__tests__/`). Workflow behavior is covered by:
85
+ - `integration-tests/http/__tests__/<domain>/` (through API routes), run with `yarn test:integration:http` from the root.
86
+ - `integration-tests/modules/__tests__/<domain>/` (e.g. `order/workflows/`), run with `yarn test:integration:modules`.
87
+ - Import framework APIs from `@medusajs/framework/*` (`/workflows-sdk`, `/utils`, `/types`), as nearly all files do. `@medusajs/framework` is a peer dependency.
88
+ - New workflows/steps: export an `xWorkflowId`/`xStepId` constant, add TSDoc with `@example`, `@summary`, and `@property hooks.<name>` for each hook (the reference docs are generated from it; use the `writing-tsdocs` skill), and export from the domain `index.ts`.
89
+
90
+ ## Gotchas
91
+
92
+ - Workflow IDs, step IDs, hook names, and hook input shapes are public API: apps consume hooks by name, run workflows by ID through the workflow engine (e.g. the store add-to-cart route calls `workflowEngine.run(addToCartWorkflowId, ...)`), and target steps by ID in `setStepSuccess`. Renaming or reshaping them is breaking.
93
+ - Steps must stay compensatable: return the data needed to undo the action as the second `StepResponse` argument and guard against `undefined` in the compensation.
94
+ - `emitEventStep` emits with the workflow's `eventGroupId`; its compensation clears those grouped events, so emit inside the workflow rather than calling the event bus directly.
95
+ - Adding a step to an existing workflow that already uses the same step needs a unique `.config({ name })`, or registration fails with `Step <name> is already defined in workflow.`
package/README.md ADDED
@@ -0,0 +1,88 @@
1
+ <p align="center">
2
+ <a href="https://www.medusajs.com">
3
+ <picture>
4
+ <source media="(prefers-color-scheme: dark)" srcset="https://user-images.githubusercontent.com/59018053/229103275-b5e482bb-4601-46e6-8142-244f531cebdb.svg">
5
+ <source media="(prefers-color-scheme: light)" srcset="https://user-images.githubusercontent.com/59018053/229103726-e5b529a3-9b3f-4970-8a1f-c6af37f087bf.svg">
6
+ <img alt="Medusa logo" src="https://user-images.githubusercontent.com/59018053/229103726-e5b529a3-9b3f-4970-8a1f-c6af37f087bf.svg">
7
+ </picture>
8
+ </a>
9
+ </p>
10
+ <h1 align="center">
11
+ @medusajs/core-flows
12
+ </h1>
13
+
14
+ <h4 align="center">
15
+ <a href="https://docs.medusajs.com">Documentation</a> |
16
+ <a href="https://www.medusajs.com">Website</a>
17
+ </h4>
18
+
19
+ <p align="center">
20
+ Building blocks for digital commerce
21
+ </p>
22
+ <p align="center">
23
+ <a href="https://github.com/medusajs/medusa/blob/develop/LICENSE">
24
+ <img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="Medusa is released under the MIT license." />
25
+ </a>
26
+ <a href="https://github.com/medusajs/medusa/blob/develop/CONTRIBUTING.md">
27
+ <img src="https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat" alt="PRs welcome!" />
28
+ </a>
29
+ <a href="https://discord.gg/xpCwq3Kfn8">
30
+ <img src="https://img.shields.io/badge/chat-on%20discord-7289DA.svg" alt="Discord Chat" />
31
+ </a>
32
+ <a href="https://twitter.com/intent/follow?screen_name=medusajs">
33
+ <img src="https://img.shields.io/twitter/follow/medusajs.svg?label=Follow%20@medusajs" alt="Follow @medusajs" />
34
+ </a>
35
+ </p>
36
+
37
+ Medusa's built-in commerce workflows and steps: the business flows behind the Medusa API routes, such as creating products, completing carts, and managing orders, returns, and exchanges. Use them in API routes, subscribers, scheduled jobs, or your own workflows to reuse Medusa's logic, or consume their hooks to extend it. Medusa applications import them from `@medusajs/medusa/core-flows`, which re-exports this package.
38
+
39
+ ## At a glance
40
+
41
+ | | |
42
+ | --- | --- |
43
+ | Package | `@medusajs/core-flows` |
44
+ | Type | Core library |
45
+ | Import from | `@medusajs/medusa/core-flows` |
46
+
47
+ ## Features
48
+
49
+ - Workflows and steps grouped by commerce domain under `src/<domain>/`, such as `cart`, `order`, `product`, `payment`, `fulfillment`, `inventory`, `pricing`, `promotion`, `customer`, and `auth`.
50
+ - Each domain has a `workflows/` directory and a `steps/` directory. `locking` and `notification` only have steps.
51
+ - `common` holds generic steps used across domains, such as `useQueryGraphStep`, `createRemoteLinkStep`, and `emitEventStep`.
52
+ - Naming convention: workflows end in `Workflow` (for example, `createProductsWorkflow`), steps end in `Step` (for example, `createProductsStep`), and each has a matching ID constant (for example, `createProductsWorkflowId`).
53
+ - Many workflows expose hooks, such as `createProductsWorkflow.hooks.productsCreated`, to run custom logic within the workflow.
54
+
55
+ ## Installation
56
+
57
+ No separate installation is needed in a Medusa application. It's installed with `@medusajs/medusa`.
58
+
59
+ ## Usage
60
+
61
+ Run a workflow by passing it the Medusa container, then calling `run`:
62
+
63
+ ```ts
64
+ import type { MedusaRequest, MedusaResponse } from "@medusajs/framework/http"
65
+ import { createProductsWorkflow } from "@medusajs/medusa/core-flows"
66
+
67
+ export async function POST(req: MedusaRequest, res: MedusaResponse) {
68
+ const { result } = await createProductsWorkflow(req.scope).run({
69
+ input: {
70
+ products: [
71
+ {
72
+ title: "Shirt",
73
+ },
74
+ ],
75
+ },
76
+ })
77
+
78
+ res.json({ products: result })
79
+ }
80
+ ```
81
+
82
+ Steps, such as `useQueryGraphStep`, are used inside your own workflows created with `createWorkflow` from `@medusajs/framework/workflows-sdk`.
83
+
84
+ ## Resources
85
+
86
+ - [Workflows reference](https://docs.medusajs.com/resources/medusa-workflows-reference)
87
+ - [Workflows](https://docs.medusajs.com/learn/fundamentals/workflows)
88
+ - [Workflow hooks](https://docs.medusajs.com/learn/fundamentals/workflows/workflow-hooks)
package/package.json CHANGED
@@ -1,11 +1,10 @@
1
1
  {
2
2
  "name": "@medusajs/core-flows",
3
- "version": "2.22.0-snapshot-20261020204851",
3
+ "version": "2.22.0",
4
4
  "description": "Set of workflow definitions for Medusa",
5
5
  "main": "dist/index.js",
6
6
  "exports": {
7
- ".": "./dist/index.js",
8
- "./defaults": "./dist/defaults/index.js"
7
+ ".": "./dist/index.js"
9
8
  },
10
9
  "repository": {
11
10
  "type": "git",
@@ -23,14 +22,18 @@
23
22
  },
24
23
  "files": [
25
24
  "dist",
25
+ "AGENTS.md",
26
26
  "!dist/**/__tests__",
27
27
  "!dist/**/__mocks__",
28
28
  "!dist/**/__fixtures__"
29
29
  ],
30
+ "llms": "https://docs.medusajs.com/llms.txt",
31
+ "llmsFull": "https://docs.medusajs.com/llms-full.txt",
32
+ "mcpServer": "https://docs.medusajs.com/mcp",
30
33
  "author": "Medusa",
31
34
  "license": "SEE LICENSE IN LICENSE",
32
35
  "devDependencies": {
33
- "@medusajs/framework": "2.22.0-snapshot-20261020204851"
36
+ "@medusajs/framework": "2.22.0"
34
37
  },
35
38
  "dependencies": {
36
39
  "csv-parse": "^7.0.2",
@@ -38,7 +41,7 @@
38
41
  "json-2-csv": "^5.5.11"
39
42
  },
40
43
  "peerDependencies": {
41
- "@medusajs/framework": "2.22.0-snapshot-20261020204851"
44
+ "@medusajs/framework": "2.22.0"
42
45
  },
43
46
  "scripts": {
44
47
  "build": "yarn run -T rimraf dist && yarn run -T tsc --build",