Skip to content

Commit

Permalink
Merge branch 'develop' into docs/revise-recipe-examples
Browse files Browse the repository at this point in the history
  • Loading branch information
shahednasser committed Dec 11, 2024
2 parents 588d6f9 + 6eb3798 commit 01aba4b
Show file tree
Hide file tree
Showing 22 changed files with 328 additions and 155 deletions.
5 changes: 3 additions & 2 deletions packages/core/types/src/file/providers/s3.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
export interface S3FileServiceOptions {
file_url: string
access_key_id: string
secret_access_key: string
access_key_id?: string
secret_access_key?: string
authentication_method?: "access-key" | "s3-iam-role"
region: string
bucket: string
prefix?: string
Expand Down
2 changes: 1 addition & 1 deletion packages/modules/providers/file-s3/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
"license": "MIT",
"scripts": {
"test": "jest --passWithNoTests src",
"test:integration": "jest --forceExit -- integration-tests/**/__tests__/**/*.spec.ts",
"test:integration": "jest --forceExit -- integration-tests/__tests__/*.spec.ts",
"build": "rimraf dist && tsc --build ./tsconfig.json",
"watch": "tsc --watch"
},
Expand Down
34 changes: 26 additions & 8 deletions packages/modules/providers/file-s3/src/services/s3-file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ type InjectedDependencies = {
}

interface S3FileServiceConfig {
// TODO: We probably don't need this as either the service should return it or we should be able to calculate it.
fileUrl: string
accessKeyId: string
secretAccessKey: string
accessKeyId?: string
secretAccessKey?: string
authenticationMethod?: "access-key" | "s3-iam-role"
region: string
bucket: string
prefix?: string
Expand All @@ -36,7 +36,6 @@ interface S3FileServiceConfig {
additionalClientConfig?: Record<string, any>
}

// FUTURE: At one point we will probably need to support authenticating with IAM roles instead.
export class S3FileService extends AbstractFileProviderService {
static identifier = "s3"
protected config_: S3FileServiceConfig
Expand All @@ -46,10 +45,23 @@ export class S3FileService extends AbstractFileProviderService {
constructor({ logger }: InjectedDependencies, options: S3FileServiceOptions) {
super()

const authenticationMethod = options.authentication_method ?? "access-key"

if (
authenticationMethod === "access-key" &&
(!options.access_key_id || !options.secret_access_key)
) {
throw new MedusaError(
MedusaError.Types.INVALID_DATA,
`Access key ID and secret access key are required when using access key authentication`
)
}

this.config_ = {
fileUrl: options.file_url,
accessKeyId: options.access_key_id,
secretAccessKey: options.secret_access_key,
authenticationMethod: authenticationMethod,
region: options.region,
bucket: options.bucket,
prefix: options.prefix ?? "",
Expand All @@ -63,11 +75,17 @@ export class S3FileService extends AbstractFileProviderService {
}

protected getClient() {
// If none is provided, the SDK will use the default credentials provider chain, see https://docs.aws.amazon.com/cli/v1/userguide/cli-configure-envvars.html
const credentials =
this.config_.authenticationMethod === "access-key"
? {
accessKeyId: this.config_.accessKeyId!,
secretAccessKey: this.config_.secretAccessKey!,
}
: undefined

const config: S3ClientConfigType = {
credentials: {
accessKeyId: this.config_.accessKeyId,
secretAccessKey: this.config_.secretAccessKey,
},
credentials,
region: this.config_.region,
endpoint: this.config_.endpoint,
...this.config_.additionalClientConfig,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ Add the `validateAndTransformQuery` middleware to the API route in the file `src
```ts title="src/api/middlewares.ts"
import {
validateAndTransformQuery,
defineMiddlewares
defineMiddlewares,
} from "@medusajs/framework/http"
import { PostStoreCustomSchema } from "./custom/validators"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ The first step is to use the `validateAndTransformQuery` middleware on the `GET`
```ts title="src/api/middlewares.ts"
import {
validateAndTransformQuery,
defineMiddlewares
defineMiddlewares,
} from "@medusajs/framework/http"
import { createFindParams } from "@medusajs/medusa/api/utils/validators"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ export const syncBrandsWorkflow = createWorkflow(
() => {
const brands = retrieveBrandsStep()

updateBrandsInCmsStep({ brands })
createBrandsInCmsStep({ brands })
}
)
```
Expand Down
109 changes: 102 additions & 7 deletions www/apps/book/app/learn/fundamentals/workflows/conditions/page.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,17 @@ In this chapter, you'll learn how to execute an action based on a condition in a

## Why If-Conditions Aren't Allowed in Workflows?

Medusa creates an internal representation of the workflow definition you pass to `createWorkflow` to track and store its steps.

At that point, variables in the workflow don't have any values. They only do when you execute the workflow.
Medusa creates an internal representation of the workflow definition you pass to `createWorkflow` to track and store its steps. At that point, variables in the workflow don't have any values. They only do when you execute the workflow.

So, you can't use an if-condition that checks a variable's value, as the condition will be evaluated when Medusa creates the internal representation of the workflow, rather than during execution.

Instead, use when-then from the Workflows SDK.
Instead, use when-then from the Workflows SDK. It allows you to perform steps in a workflow only if a condition that you specify is satisified.

---

## What is the When-Then Utility?
## How to use When-Then?

when-then from the Workflows SDK executes an action if a condition is satisfied. The `when` function accepts as a parameter a function that returns a boolean value, and the `then` function is chained to `when`. `then` accepts as a parameter a function that's executed if `when`'s parameter function returns a `true` value.
The Workflows SDK provides a `when` function that is used to check whether a condition is true. You chain a `then` function to `when` that specifies the steps to execute if the condition in `when` is satisfied.

For example:

Expand Down Expand Up @@ -77,4 +75,101 @@ In this code snippet, you execute the `isActiveStep` only if the `input.is_activ

To specify the action to perform if the condition is satisfied, chain a `then` function to `when` and pass it a callback function.

The callback function is only executed if `when`'s second parameter function returns a `true` value.
The callback function is only executed if `when`'s second parameter function returns a `true` value.

---

## Implementing If-Else with When-Then

when-then doesn't support if-else conditions. Instead, use two `when-then` conditions in your workflow.

For example:

export const ifElseHighlights = [
["7", "when", "This when-then block acts as an if condition."],
["16", "when", "This when-then block acts as an else condiiton."]
]

```ts highlights={ifElseHighlights}
const workflow = createWorkflow(
"workflow",
function (input: {
is_active: boolean
}) {

const isActiveResult = when(
input,
(input) => {
return input.is_active
}
).then(() => {
return isActiveStep()
})

const notIsActiveResult = when(
input,
(input) => {
return input.is_active
}
).then(() => {
return notIsActiveStep()
})

// ...
}
)
```

In the above workflow, you use two `when-then` blocks. The first one performs a step if `input.is_active` is `true`, and the second performs a step if `input.is_active` is `false`, acting as an else condition.

---

## Specify Name for When-Then

Internally, `when-then` blocks have a unique name similar to a step. When you return a step's result in a `when-then` block, the block's name is derived from the step's name. For example:

```ts
const isActiveResult = when(
input,
(input) => {
return input.is_active
}
).then(() => {
return isActiveStep()
})
```

This `when-then` block's internal name will be `when-then-is-active`, where `is-active` is the step's name.

However, if you need to return in your `when-then` block something other than a step's result, you need to specify a unique step name for that block. Otherwise, Medusa will generate a random name for it which can cause unexpected errors in production.

You pass a name for `when-then` as a first parameter of `when`, whose signature can accept three parameters in this case. For example:

export const nameHighlights = [
["2", `"check-is-active"`, "The when-then block's name."],
["10", "return", "`then` returns a value other than the step's result."]
]

```ts highlights={nameHighlights}
const { isActive } = when(
"check-is-active",
input,
(input) => {
return input.is_active
}
).then(() => {
const isActive = isActiveStep()

return {
isActive,
}
})
```

Since `then` returns a value different than the step's result, you pass to the `when` function the following parameters:

1. A unique name to be assigned to the `when-then` block.
2. Either an object or the workflow's input. This data is passed as a parameter to the function in `when`'s second parameter.
3. A function that returns a boolean indicating whether to execute the action in `then`.

The second and third parameters are the same as the parameters you previously passed to `when`.
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,8 @@ const myWorkflow = createWorkflow(
})
```

You can also pair multiple `when-then` blocks to implement an `if-else` condition as explained in [this chapter](../conditions/page.mdx).

### No Conditional Operators

You can't use conditional operators in a workflow, such as `??` or `||`.
Expand Down
4 changes: 2 additions & 2 deletions www/apps/book/generated/edit-dates.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,11 @@ export const generatedEditDates = {
"app/learn/fundamentals/data-models/default-properties/page.mdx": "2024-10-21T13:30:21.368Z",
"app/learn/fundamentals/workflows/advanced-example/page.mdx": "2024-09-11T10:46:59.975Z",
"app/learn/fundamentals/events-and-subscribers/emit-event/page.mdx": "2024-11-25T16:19:32.168Z",
"app/learn/fundamentals/workflows/conditions/page.mdx": "2024-12-09T15:55:51.565Z",
"app/learn/fundamentals/workflows/conditions/page.mdx": "2024-12-11T08:44:00.239Z",
"app/learn/fundamentals/modules/module-link-directions/page.mdx": "2024-07-24T09:16:01+02:00",
"app/learn/fundamentals/admin/page.mdx": "2024-10-23T07:08:55.898Z",
"app/learn/fundamentals/workflows/long-running-workflow/page.mdx": "2024-12-04T07:37:59.822Z",
"app/learn/fundamentals/workflows/constructor-constraints/page.mdx": "2024-12-09T14:43:35.160Z",
"app/learn/fundamentals/workflows/constructor-constraints/page.mdx": "2024-12-11T08:36:08.282Z",
"app/learn/fundamentals/data-models/write-migration/page.mdx": "2024-11-11T15:27:59.794Z",
"app/learn/fundamentals/data-models/manage-relationships/page.mdx": "2024-10-28T04:22:21.328Z",
"app/learn/fundamentals/modules/remote-query/page.mdx": "2024-07-21T21:20:24+02:00",
Expand Down
37 changes: 20 additions & 17 deletions www/apps/resources/app/commerce-modules/cart/extend/page.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -529,12 +529,15 @@ In the workflow, you retrieve the cart's linked `Custom` record using Query.
Next, replace the `TODO` with the following:

```ts title="src/workflows/update-custom-from-cart/index.ts"
const created = when({
input,
carts,
}, (data) =>
!data.carts[0].custom &&
data.input.additional_data?.custom_name?.length > 0
const created = when(
"create-cart-custom-link",
{
input,
carts,
},
(data) =>
!data.carts[0].custom &&
data.input.additional_data?.custom_name?.length > 0
)
.then(() => {
const custom = createCustomStep({
Expand Down Expand Up @@ -563,14 +566,16 @@ To create the `Custom` record, you use the `createCustomStep` you created in an
Next, replace the new `TODO` with the following:

```ts title="src/workflows/update-custom-from-cart/index.ts"
const deleted = when({
input,
carts,
}, (data) =>
data.carts[0].custom && (
data.input.additional_data?.custom_name === null ||
data.input.additional_data?.custom_name.length === 0
)
const deleted = when(
"delete-cart-custom-link",
{
input,
carts,
}, (data) =>
data.carts[0].custom && (
data.input.additional_data?.custom_name === null ||
data.input.additional_data?.custom_name.length === 0
)
)
.then(() => {
deleteCustomStep({
Expand Down Expand Up @@ -599,12 +604,10 @@ const updated = when({
carts,
}, (data) => data.carts[0].custom && data.input.additional_data?.custom_name?.length > 0)
.then(() => {
const custom = updateCustomStep({
return updateCustomStep({
id: carts[0].custom.id,
custom_name: input.additional_data.custom_name,
})

return custom
})

return new WorkflowResponse({
Expand Down
36 changes: 19 additions & 17 deletions www/apps/resources/app/commerce-modules/customer/extend/page.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -541,12 +541,14 @@ In the workflow, you retrieve the customer's linked `Custom` record using Query.
Next, replace the `TODO` with the following:

```ts title="src/workflows/update-custom-from-customer/index.ts"
const created = when({
input,
customers,
}, (data) =>
!data.customers[0].custom &&
data.input.additional_data?.custom_name?.length > 0
const created = when(
"create-customer-custom-link",
{
input,
customers,
}, (data) =>
!data.customers[0].custom &&
data.input.additional_data?.custom_name?.length > 0
)
.then(() => {
const custom = createCustomStep({
Expand Down Expand Up @@ -575,14 +577,16 @@ To create the `Custom` record, you use the `createCustomStep` you created in an
Next, replace the new `TODO` with the following:

```ts title="src/workflows/update-custom-from-customer/index.ts"
const deleted = when({
input,
customers,
}, (data) =>
data.customers[0].custom && (
data.input.additional_data?.custom_name === null ||
data.input.additional_data?.custom_name.length === 0
)
const deleted = when(
"delete-customer-custom-link",
{
input,
customers,
}, (data) =>
data.customers[0].custom && (
data.input.additional_data?.custom_name === null ||
data.input.additional_data?.custom_name.length === 0
)
)
.then(() => {
deleteCustomStep({
Expand Down Expand Up @@ -611,12 +615,10 @@ const updated = when({
customers,
}, (data) => data.customers[0].custom && data.input.additional_data?.custom_name?.length > 0)
.then(() => {
const custom = updateCustomStep({
return updateCustomStep({
id: customers[0].custom.id,
custom_name: input.additional_data.custom_name,
})

return custom
})

return new WorkflowResponse({
Expand Down
Loading

0 comments on commit 01aba4b

Please sign in to comment.