docs: general fixes and improvements (#7918)

* docs improvements and changes

* updated module definition

* modules + dml changes

* fix build

* fix vale error

* fix lint errors

* fixes to stripe docs

* fix condition

* fix condition

* fix module defintion

* fix checkout

* disable UI action

* change oas preview action

* flatten provider module options

* fix lint errors

* add module link docs

* pr comments fixes

* fix vale error

* change node engine version

* links -> linkable

* add note about database name

* small fixes

* link fixes

* fix response code in api reference

* added migrations step
This commit is contained in:
Shahed Nasser authored and GitHub committed 2024-07-04 17:26:03 +03:00
1 parent 32982e708a
commit 964927b597
149 files changed
+1676 -3008

No files matched your search

@@ -4,9 +4,9 @@ export const metadata = {
# {metadata.title}
In this document, you’ll learn how to access errors that occur during a workflow’s execution.
In this chapter, you’ll learn how to access errors that occur during a workflow’s execution.
## How to Access Workflow Errors
## How to Access Workflow Errors?
By default, when an error occurs in a workflow, it throws that error, and the execution stops.
@@ -23,9 +23,10 @@ Start by creating the file `src/workflows/update-product-erp/index.ts` that will
In the file, add the type of the expected workflow input:
```ts title="src/workflows/update-product-erp/index.ts"
import { UpdateProductDTO } from "@medusajs/types"
import { UpsertProductDTO } from "@medusajs/types"
export type UpdateProductAndErpWorkflowInput = UpsertProductDTO
export type UpdateProductAndErpWorkflowInput = UpdateProductDTO
```
The expected input is the data to update in the product along with the product’s ID.
@@ -40,17 +41,9 @@ Create the file `src/workflows/update-product-erp/steps/update-product.ts` with
export const updateProductHighlights = [
["13", "resolve", "Resolve the `ProductService` from the Medusa container."],
[
"16",
"previousProductData",
"Retrieve the `previousProductData` to pass it to the compensation function.",
],
["19", "", "Update the product."],
[
"39",
"",
"Revert the product’s data using the `previousProductData` passed from the step to the compensation function.",
],
["16", "previousProductData", "Retrieve the `previousProductData` to pass it to the compensation function."],
["19", "updateProducts", "Update the product."],
["39", "updateProducts", "Revert the product’s data using the `previousProductData` passed from the step to the compensation function."]
]
```ts title="src/workflows/update-product-erp/steps/update-product.ts" highlights={updateProductHighlights} collapsibleLines="1-9" expandButtonLabel="Show Imports"
@@ -66,9 +59,10 @@ const updateProduct = createStep(
context.container.resolve(ModuleRegistrationName.PRODUCT)
const { id } = input
const previousProductData = await productModuleService.retrieve(id)
const previousProductData =
await productModuleService.retrieveProduct(id)
const product = await productModuleService.update(id, input)
const product = await productModuleService.updateProducts(id, input)
return new StepResponse(product, {
// pass to compensation function
@@ -82,10 +76,12 @@ const updateProduct = createStep(
const { id, type, options, variants, ...previousData } = previousProductData
await productModuleService.update(id, {
...previousData,
variants: variants.map((variant) => {
const variantOptions = {}
await productModuleService.updateProducts(
id,
{
...previousData,
variants: variants.map((variant) => {
const variantOptions = {}
variant.options.forEach((option) => {
variantOptions[option.option.title] = option.value
@@ -110,7 +106,7 @@ export default updateProduct
In the step:
- You resolve the `ProductService` from the Medusa container.
- You resolve the Product Module's main service from the Medusa container.
- You retrieve the `previousProductData` to pass it to the compensation function.
- You update and return the product.
@@ -211,11 +207,11 @@ Change the content of `src/workflows/update-product-erp/index.ts` to the followi
```ts title="src/workflows/update-product-erp/index.ts" collapsibleLines="1-6" expandButtonLabel="Show Imports"
import { createWorkflow } from "@medusajs/workflows-sdk"
import { UpdateProductDTO, ProductDTO } from "@medusajs/types"
import { UpsertProductDTO, ProductDTO } from "@medusajs/types"
import updateProduct from "./steps/update-product"
import updateErp from "./steps/update-erp"
export type UpdateProductAndErpWorkflowInput = UpdateProductDTO
export type UpdateProductAndErpWorkflowInput = UpsertProductDTO
type WorkflowOutput = {
product: ProductDTO
@@ -8,7 +8,7 @@ In this chapter, you'll learn how to add a compensation function to a step.
## Compensation Function
Errors can occur in a workflow. To avoid data inconsistency, define a function to run when an error occurs in a step. This function is called the compensation function.
To avoid data inconsistency when an error is thrown in a workflow, define a function (called a compensation function) and pass it as a second parameter to the `createStep` function.
For example:
@@ -34,9 +34,11 @@ const step1 = createStep(
)
```
Each step can have a compensation function. The compensation function only runs if an error occurs throughout the Workflow. It’s useful to undo or roll back actions you’ve performed in a step.
Each step can have a compensation function. The compensation function only runs if an error occurs throughout the workflow. It’s useful to undo or roll back actions you’ve performed in a step.
### Test Compensation Function
---
## Test the Compensation Function
1. Add another step that throws an error:
@@ -107,7 +109,7 @@ npm run dev
5. Send a `GET` request to `/store/workflow`:
```bash apiTesting testApiMethod="GET" testApiUrl="http://localhost:9000/store/workflows"
```bash apiTesting testApiMethod="GET" testApiUrl="http://localhost:9000/store/workflow"
curl http://localhost:9000/store/workflow
```
@@ -4,7 +4,7 @@ export const metadata = {
# {metadata.title}
This chapter lists some constraints to keep in mind when defining Workflow constructor functions.
This chapter lists some constraints to keep in mind when defining a workflow's constructor function.
## No Arrow Functions
@@ -28,6 +28,8 @@ const myWorkflow = createWorkflow<
})
```
---
## No Async Functions
The function passed to the `createWorkflow` can’t be an async function:
@@ -50,6 +52,8 @@ const myWorkflow = createWorkflow<
})
```
---
## No Direct Data Manipulation
Since the constructor function only defines how the workflow works, you can’t directly manipulate data within the function. Instead, use the `transform` function:
@@ -22,11 +22,15 @@ A workflow is considered long-running if at least one step has its `async` confi
For example, consider the following workflow and steps:
```ts title="src/workflows/hello-world.ts" highlights={[["13"]]} collapsibleLines="1-10" expandButtonLabel="Show More"
import { createStep, createWorkflow } from "@medusajs/workflows-sdk"
```ts title="src/workflows/hello-world.ts" highlights={[["14"]]} collapsibleLines="1-10" expandButtonLabel="Show More"
import {
createStep,
createWorkflow,
StepResponse,
} from "@medusajs/workflows-sdk"
const step1 = createStep("step-1", async () => {
// ...
return new StepResponse({})
})
const step2 = createStep(
@@ -35,74 +39,90 @@ const step2 = createStep(
async: true,
},
async () => {
// ...
return new StepResponse({})
}
)
const step3 = createStep("step-3", async () => {
// ...
return new StepResponse("Finished three steps")
})
type WorkflowOutput = {
message: string
}
const myWorkflow = createWorkflow<{}, WorkflowOutput>(
{
name: "hello-world",
},
function () {
step1()
step2()
step3()
const myWorkflow = createWorkflow<
{},
WorkflowOutput
>("hello-world", function () {
step1()
step2()
const message = step3()
return {
message,
}
)
})
export default myWorkflow
```
The second step has in its configuration object `async` set to true. This indicates that this step is an asynchronous step.
<Note title="Important">
An asynchronous step must return for the execution to continue.
</Note>
So, when you execute the `hello-world` workflow, it continues its execution in the background once it reaches the second step.
---
## Access Long-Running Workflow Status and Result
<Note type="check">
- [A workflow engine module installed](!resources!/architectural-modules/workflow-engine/in-memory).
</Note>
To access the status and result of a long-running workflow, use the workflow engine registered in the Medusa Container. The workflow engine provides methods to access and subscribe to workflow executions.
For example:
export const highlights = [
["18", "", "Resolve the workflow engine from the Medusa container."],
["24", "subscribe", "Subscribe to status changes of the workflow execution."],
["18", "resolve", "Resolve the workflow engine from the Medusa container."],
["30", "subscribe", "Subscribe to status changes of the workflow execution."],
]
```ts title="src/api/store/workflows/route.ts" highlights={highlights} collapsibleLines="1-11" expandButtonLabel="Show Imports"
import type { MedusaRequest, MedusaResponse } from "@medusajs/medusa"
import myWorkflow from "../../../workflows/hello-world"
import { IWorkflowEngineService } from "@medusajs/workflows-sdk"
import {
IWorkflowEngineService,
} from "@medusajs/types"
import { ModuleRegistrationName } from "@medusajs/utils"
export async function GET(req: MedusaRequest, res: MedusaResponse) {
const { transaction, result } = await myWorkflow(req.scope).run()
const workflowEngine = req.scope.resolve<IWorkflowEngineService>(
const workflowEngineModuleService = req.scope.resolve<
IWorkflowEngineService
>(
ModuleRegistrationName.WORKFLOW_ENGINE
)
await workflowEngine.subscribe({
const subscriptionOptions = {
workflowId: "hello-world",
transactionId: transaction.transactionId,
subscriber: (data) => {
subscriberId: "hello-world-subscriber",
}
await workflowEngineModuleService.subscribe({
...subscriptionOptions,
subscriber: async (data) => {
if (data.eventType === "onFinish") {
console.log("Finished execution", data.result)
// unsubscribe
await workflowEngineModuleService.unsubscribe({
...subscriptionOptions,
subscriberOrId: subscriptionOptions.subscriberId,
})
} else if (data.eventType === "onStepFailure") {
console.log("Workflow failed", data.step)
}
@@ -141,3 +161,5 @@ The `subscribe` method accepts an object having three properties:
/>
Once the workflow execution finishes, the subscriber function is executed with the `eventType` of the received parameter set to `onFinish`. The workflow’s output is set in the `result` property of the parameter.
You can unsubscribe from the workflow using the workflow engine's `unsubscribe` method, which requires the same object parameter as the `subscribe` method.
@@ -8,9 +8,9 @@ In this chapter, you’ll learn how to run workflow steps in parallel.
## parallelize Utility Function
If your workflow has steps that don’t rely on one another’s results, you can run them in parallel. The workflow will wait until all specified steps are finished before continuing with the rest of its implementation.
If your workflow has steps that don’t rely on one another’s results, run them in parallel using the `parallelize` utility function imported from the `@medusajs/workflows-sdk`.
The `parallelize` utility function imported from the `@medusajs/workflows-sdk` package allows you to run the steps in parallel.
The workflow waits until all steps passed to the `parallelize` function finish executing before continuing with the rest of its implementation.
For example:
@@ -55,4 +55,4 @@ const myWorkflow = createWorkflow<
The `parallelize` function accepts the steps to run in parallel as a parameter.
It returns an array of each step’s result. The results are ordered in the result array by the order they're passed in the function's parameter.
It returns an array of the steps' results. The results are ordered based on the `parallelize` parameters' order.
@@ -10,12 +10,13 @@ In this chapter, you’ll learn how to configure steps to allow retrial on failu
By default, when an error occurs in a step, the step and the workflow fail, and the execution stops.
You can configure the step to retry on failure. The `createStep` function can accept a configuration object instead of the step’s name as a first parameter:
You can configure the step to retry on failure. The `createStep` function can accept a configuration object instead of the step’s name as a first parameter.
```ts title="src/workflows/hello-world.ts" highlights={[["10"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports"
For example:
```ts title="src/workflows/hello-world.ts" highlights={[["9"]]} collapsibleLines="1-5" expandButtonLabel="Show Imports"
import {
createStep,
StepResponse,
createWorkflow,
} from "@medusajs/workflows-sdk"