Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 21 additions & 3 deletions .github/workflows/build_and_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -177,8 +177,14 @@ jobs:
- 3306
options: --health-cmd="mariadb-admin ping -h localhost -u vendure -ppassword" --health-interval=10s --health-timeout=5s --health-retries=3
elastic:
image: docker.elastic.co/elasticsearch/elasticsearch:7.1.1
image: docker.elastic.co/elasticsearch/elasticsearch:9.1.0
env:
node.name: es
cluster.name: es-docker-cluster
xpack.security.enabled: false
xpack.security.http.ssl.enabled: false
xpack.security.transport.ssl.enabled: false
xpack.license.self_generated.type: basic
discovery.type: single-node
bootstrap.memory_lock: true
ES_JAVA_OPTS: -Xms512m -Xmx512m
Expand Down Expand Up @@ -224,8 +230,14 @@ jobs:
- 3306
options: --health-cmd="mysqladmin ping --silent" --health-interval=10s --health-timeout=20s --health-retries=10
elastic:
image: docker.elastic.co/elasticsearch/elasticsearch:7.1.1
image: docker.elastic.co/elasticsearch/elasticsearch:9.1.0
env:
node.name: es
cluster.name: es-docker-cluster
xpack.security.enabled: false
xpack.security.http.ssl.enabled: false
xpack.security.transport.ssl.enabled: false
xpack.license.self_generated.type: basic
discovery.type: single-node
bootstrap.memory_lock: true
ES_JAVA_OPTS: -Xms512m -Xmx512m
Expand Down Expand Up @@ -272,8 +284,14 @@ jobs:
- 5432
options: --health-cmd=pg_isready --health-interval=10s --health-timeout=5s --health-retries=3
elastic:
image: docker.elastic.co/elasticsearch/elasticsearch:7.1.1
image: docker.elastic.co/elasticsearch/elasticsearch:9.1.0
env:
node.name: es
cluster.name: es-docker-cluster
xpack.security.enabled: false
xpack.security.http.ssl.enabled: false
xpack.security.transport.ssl.enabled: false
xpack.license.self_generated.type: basic
discovery.type: single-node
bootstrap.memory_lock: true
ES_JAVA_OPTS: -Xms512m -Xmx512m
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,19 @@
title: "LocalAssetStorageStrategy"
generated: true
---
<GenerationInfo sourceFile="packages/asset-server-plugin/src/config/local-asset-storage-strategy.ts" sourceLine="15" packageName="@vendure/asset-server-plugin" />
<GenerationInfo sourceFile="packages/asset-server-plugin/src/config/local-asset-storage-strategy.ts" sourceLine="14" packageName="@vendure/asset-server-plugin" />

A persistence strategy which saves files to the local file system.

```ts title="Signature"
class LocalAssetStorageStrategy implements AssetStorageStrategy {
toAbsoluteUrl: ((reqest: Request, identifier: string) => string) | undefined;
constructor(uploadPath: string, toAbsoluteUrlFn?: (reqest: Request, identifier: string) => string)
writeFileFromStream(fileName: string, data: ReadStream, encoding? BufferEncoding | null) => Promise<string>;
writeFileFromStream(fileName: string, data: ReadStream, encoding?: BufferEncoding | null) => Promise<string>;
writeFileFromBuffer(fileName: string, data: Buffer) => Promise<string>;
fileExists(fileName: string) => Promise<boolean>;
readFileToBuffer(identifier: string) => Promise<Buffer>;
readFileToStream(identifier: string, encoding? BufferEncoding | null) => Promise<Stream>;
readFileToStream(identifier: string, encoding?: BufferEncoding | null) => Promise<Stream>;
deleteFile(identifier: string) => Promise<void>;
}
```
Expand All @@ -36,7 +36,7 @@ class LocalAssetStorageStrategy implements AssetStorageStrategy {

### writeFileFromStream

<MemberInfo kind="method" type={`(fileName: string, data: ReadStream, encoding? BufferEncoding | null) => Promise&#60;string&#62;`} />
<MemberInfo kind="method" type={`(fileName: string, data: ReadStream, encoding?: BufferEncoding | null) => Promise<string>`} />


### writeFileFromBuffer
Expand All @@ -56,7 +56,7 @@ class LocalAssetStorageStrategy implements AssetStorageStrategy {

### readFileToStream

<MemberInfo kind="method" type={`(identifier: string, encoding? BufferEncoding | null) => Promise&#60;Stream&#62;`} />
<MemberInfo kind="method" type={`(identifier: string, encoding?: BufferEncoding | null) => Promise<Stream>`} />


### deleteFile
Expand Down
19 changes: 4 additions & 15 deletions docs/docs/reference/core-plugins/elasticsearch-plugin/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,17 @@
title: "ElasticsearchPlugin"
generated: true
---
<GenerationInfo sourceFile="packages/elasticsearch-plugin/src/plugin.ts" sourceLine="228" packageName="@vendure/elasticsearch-plugin" />
<GenerationInfo sourceFile="packages/elasticsearch-plugin/src/plugin.ts" sourceLine="242" packageName="@vendure/elasticsearch-plugin" />

This plugin allows your product search to be powered by [Elasticsearch](https://github.com/elastic/elasticsearch) - a powerful Open Source search
engine. This is a drop-in replacement for the DefaultSearchPlugin which exposes many powerful configuration options enabling your storefront
to support a wide range of use-cases such as indexing of custom properties, fine control over search index configuration, and to leverage
advanced Elasticsearch features like spacial search.

## Installation
**ElasticSearch v9.1.0 is supported**

**Requires Elasticsearch v7.0 < required Elasticsearch version < 7.10 **
Elasticsearch version 7.10.2 will throw error due to incompatibility with elasticsearch-js client.
[Check here for more info](https://github.com/elastic/elasticsearch-js/issues/1519).

`yarn add @elastic/elasticsearch @vendure/elasticsearch-plugin`

or

`npm install @elastic/elasticsearch @vendure/elasticsearch-plugin`

Make sure to remove the `DefaultSearchPlugin` if it is still in the VendureConfig plugins array.

Then add the `ElasticsearchPlugin`, calling the `.init()` method with [ElasticsearchOptions](/reference/core-plugins/elasticsearch-plugin/elasticsearch-options#elasticsearchoptions):
**Important information about versions and ElasticSearch security:**
The version of ElasticSearch that is deployed, the version of the JS library

*Example*

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
title: "EmailGenerator"
generated: true
---
<GenerationInfo sourceFile="packages/email-plugin/src/generator/email-generator.ts" sourceLine="13" packageName="@vendure/email-plugin" />
<GenerationInfo sourceFile="packages/email-plugin/src/generator/email-generator.ts" sourceLine="15" packageName="@vendure/email-plugin" />

An EmailGenerator generates the subject and body details of an email.

Expand All @@ -14,7 +14,7 @@ interface EmailGenerator<T extends string = any, E extends VendureEvent = any> e
subject: string,
body: string,
templateVars: { [key: string]: any },
): Pick<EmailDetails, 'from' | 'subject' | 'body'>;
): EmailGeneratorResult | Promise<EmailGeneratorResult>;
}
```
* Extends: [`InjectableStrategy`](/reference/typescript-api/common/injectable-strategy#injectablestrategy)
Expand All @@ -30,7 +30,7 @@ interface EmailGenerator<T extends string = any, E extends VendureEvent = any> e
Any necessary setup can be performed here.
### generate

<MemberInfo kind="method" type={`(from: string, subject: string, body: string, templateVars: { [key: string]: any }) => Pick<<a href='/reference/core-plugins/email-plugin/email-plugin-types#emaildetails'>EmailDetails</a>, 'from' | 'subject' | 'body'>`} />
<MemberInfo kind="method" type={`(from: string, subject: string, body: string, templateVars: { [key: string]: any }) => EmailGeneratorResult | Promise<EmailGeneratorResult>`} />

Given a subject and body from an email template, this method generates the final
interpolated email text.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
title: "BullMQPluginOptions"
generated: true
---
<GenerationInfo sourceFile="packages/job-queue-plugin/src/bullmq/types.ts" sourceLine="21" packageName="@vendure/job-queue-plugin" since="1.2.0" />
<GenerationInfo sourceFile="packages/job-queue-plugin/src/bullmq/types.ts" sourceLine="20" packageName="@vendure/job-queue-plugin" since="1.2.0" />

Configuration options for the [BullMQJobQueuePlugin](/reference/core-plugins/job-queue-plugin/bull-mqjob-queue-plugin#bullmqjobqueueplugin).

Expand All @@ -11,6 +11,7 @@ interface BullMQPluginOptions {
connection?: ConnectionOptions;
queueOptions?: Omit<QueueOptions, 'connection'>;
workerOptions?: Omit<WorkerOptions, 'connection'>;
concurrency?: number | ((queueName: string) => number);
setRetries?: (queueName: string, job: Job) => number;
setBackoff?: (queueName: string, job: Job) => BackoffOptions | undefined;
setJobOptions?: (queueName: string, job: Job) => BullJobsOptions;
Expand Down Expand Up @@ -41,6 +42,42 @@ See the [BullMQ QueueOptions docs](https://github.com/taskforcesh/bullmq/blob/ma
Additional options used when instantiating the BullMQ
Worker instance.
See the [BullMQ WorkerOptions docs](https://github.com/taskforcesh/bullmq/blob/master/docs/gitbook/api/bullmq.workeroptions.md)
### concurrency

<MemberInfo kind="property" type={`number | ((queueName: string) => number)`} default={`3`} />

How many jobs from a given queue to process concurrently.

Can be set to a function which receives the queue name and returns
the concurrency limit. This is useful for limiting concurrency on
queues which have resource-intensive jobs.

**Important implementation note:** When using a function, workers are grouped
by the _concurrency value_, not by queue name. Because all Vendure job types
are stored in a single BullMQ queue (`QUEUE_NAME`), any worker can process
any job type. This means:

- Multiple Vendure queues returning the same concurrency value will share a worker
- Jobs from different Vendure queues may be processed by the same worker
- The concurrency limit applies to the total jobs processed by that worker,
not strictly per Vendure queue

For strict per-queue concurrency isolation, consider:
- Creating separate BullMQ queues per Vendure queue (requires custom implementation)
- Using [BullMQ Pro Groups](https://docs.bullmq.io/bullmq-pro/groups)

*Example*

```ts
BullMQJobQueuePlugin.init({
concurrency: (queueName) => {
if (queueName === 'apply-collection-filters') {
return 1;
}
return 5;
}
})
```
### setRetries

<MemberInfo kind="property" type={`(queueName: string, job: Job) => number`} since="1.3.0" />
Expand Down Expand Up @@ -105,7 +142,7 @@ setJobOptions: (queueName, job) => {


</div>
<GenerationInfo sourceFile="packages/job-queue-plugin/src/bullmq/types.ts" sourceLine="122" packageName="@vendure/job-queue-plugin" since="1.3.0" />
<GenerationInfo sourceFile="packages/job-queue-plugin/src/bullmq/types.ts" sourceLine="158" packageName="@vendure/job-queue-plugin" since="1.3.0" />

Configuration for the backoff function when retrying failed jobs.

Expand Down
69 changes: 48 additions & 21 deletions docs/docs/reference/core-plugins/payments-plugin/mollie-plugin.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@
title: "MolliePlugin"
generated: true
---
<GenerationInfo sourceFile="packages/payments-plugin/src/mollie/mollie.plugin.ts" sourceLine="206" packageName="@vendure/payments-plugin" />
<GenerationInfo sourceFile="packages/payments-plugin/src/mollie/mollie.plugin.ts" sourceLine="234" packageName="@vendure/payments-plugin" />

Plugin to enable payments through the [Mollie platform](https://docs.mollie.com/).
This plugin uses the Order API from Mollie, not the Payments API.

## Requirements
### Requirements

1. You will need to create a Mollie account and get your apiKey in the dashboard.
1. You will need to create a Mollie account and get your api key from the Mollie dashboard.
2. Install the Payments plugin and the Mollie client:

`yarn add @vendure/payments-plugin @mollie/api-client`
Expand All @@ -18,7 +18,7 @@ This plugin uses the Order API from Mollie, not the Payments API.

`npm install @vendure/payments-plugin @mollie/api-client`

## Setup
### Setup

1. Add the plugin to your VendureConfig `plugins` array:
```ts
Expand All @@ -30,16 +30,16 @@ This plugin uses the Order API from Mollie, not the Payments API.
MolliePlugin.init({ vendureHost: 'https://yourhost.io/' }),
]
```
2. Create a new PaymentMethod in the Admin UI, and select "Mollie payments" as the handler.
2. Create a new payment method in the Admin UI, and select "Mollie payments" as the handler.
3. Set your Mollie apiKey in the `API Key` field.
4. Set the `Fallback redirectUrl` to the url that the customer should be redirected to after completing the payment.
You can override this url by passing the `redirectUrl` as an argument to the `createMolliePaymentIntent` mutation.

## Storefront usage
### Storefront usage

In your storefront you add a payment to an order using the `createMolliePaymentIntent` mutation. In this example, our Mollie
PaymentMethod was given the code "mollie-payment-method". The `redirectUrl``is the url that is used to redirect the end-user
back to your storefront after completing the payment.
payment method was given the code "mollie-payment-method". The `redirectUrl` should be your order confirmation page.
It is the url that is used to redirect the customer back to your storefront after completing the payment.

```GraphQL
mutation CreateMolliePaymentIntent {
Expand All @@ -61,11 +61,9 @@ mutation CreateMolliePaymentIntent {
}
```

The response will contain
a redirectUrl, which can be used to redirect your customer to the Mollie
platform.
You can use `molliePaymentIntent.url` to redirect the customer to the Mollie platform.

'molliePaymentMethodCode' is an optional parameter that can be passed to skip Mollie's hosted payment method selection screen
The `molliePaymentMethodCode` is an optional parameter that can be passed to preselect a payment method, and skip Mollie's payment method selection screen
You can get available Mollie payment methods with the following query:

```GraphQL
Expand All @@ -92,27 +90,49 @@ You can get available Mollie payment methods with the following query:
```

After completing payment on the Mollie platform,
the user is redirected to the redirect url that was provided in the `createMolliePaymentIntent` mutation, e.g. `https://storefront/order/CH234X5`
the user is redirected by Mollie to the provided redirect url (confirmation page).
E.g. `https://storefront/order/`. The redirect url here was `https://storefront/order`, the order code `CH234X5` is appended automatically by the plugin.

## Pay later methods
#### Force payment status update

Mollie does not give any guarantees on webhook delivery time, and in some rare cases,
the Mollie webhook is delayed and the order status is not updated in Vendure.

You can use the `syncMolliePaymentStatus` mutation to force update the order status based on the Mollie payment status.
This mutation will find any settled or authorized Mollie payments for the given order and update the order status in Vendure accordingly.

```GraphQL
mutation SyncMolliePaymentStatus {
syncMolliePaymentStatus(orderCode: "CH234X5") {
id
state
}
}
```

You should wait for an incoming webhook first, because due to technical limitations on the Mollie API, the `syncMolliePaymentStatus`
mutation will iterate through the last 500 Mollie payments to find the payments for the given order.
Hence, it is not very performant, and should only be used as a fallback when a webhook
was not received for ~10 seconds.

### Pay later methods

Mollie supports pay-later methods like 'Klarna Pay Later'. Pay-later methods are captured immediately after payment.

If your order fulfillment time is longer than 24 hours You should pass `immediateCapture=false` to the `createMolliePaymentIntent` mutation.
This will transition your order to 'PaymentAuthorized' after the Mollie hosted checkout.
You need to manually capture the payment after the order is fulfilled, by settling existing payments, either via the admin UI or in custom code.

Make sure to capture a payment within 28 days, after that the payment will be automaticallreleased.
Make sure to capture a payment within 28 days, after that the payment will be automatically released.
See the [Mollie documentation](https://docs.mollie.com/docs/place-a-hold-for-a-payment#authorization-expiration-window)
for more information.

## ArrangingAdditionalPayment state
### ArrangingAdditionalPayment state

In some rare cases, a customer can add items to the active order, while a Mollie checkout is still open,
for example by opening your storefront in another browser tab.
This could result in an order being in `ArrangingAdditionalPayment` status after the customer finished payment.
You should check if there is still an active order with status `ArrangingAdditionalPayment` on your order confirmation page,
and if so, allow your customer to pay for the additional items by creating another Mollie payment.
In some cases, a customer can add items to the active order, while a Mollie checkout is still open, or an administrator can modify an order.
Both of these actions will result in an order being in `ArrangingAdditionalPayment` status.
To finalize an order in `ArrangingAdditionalPayment` status, you can use call the `createMolliePaymentIntent` mutation again with an additional `orderId` as input.
The `orderId` argument is needed, because an order in `ArrangingAdditionalPayment` status is not an active order anymore.

```ts title="Signature"
class MolliePlugin {
Expand Down Expand Up @@ -149,6 +169,7 @@ interface MolliePluginOptions {
order: Order | null,
) => AdditionalEnabledPaymentMethodsParams | Promise<AdditionalEnabledPaymentMethodsParams>;
immediateCapture?: boolean;
disableWebhookProcessing?: boolean;
}
```

Expand Down Expand Up @@ -204,6 +225,12 @@ Immediate capture mode for pay-later methods like Klarna.
Setting this option will make the plugin ignore the `immediateCapture` option in the `createMolliePaymentIntent` mutation.

The default is true, unless set otherwise as input in the `createMolliePaymentIntent` mutation.
### disableWebhookProcessing

<MemberInfo kind="property" type={`boolean`} since="3.6.0" />

Disable the processing of incoming Mollie webhooks.
Handle with care! This will keep orders in 'AddingItems' state if you don't manually process the Mollie payments via the `syncMolliePaymentStatus` mutation.


</div>
4 changes: 2 additions & 2 deletions docs/docs/reference/dashboard/components/asset-gallery.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
title: "AssetGallery"
generated: true
---
<GenerationInfo sourceFile="packages/dashboard/src/lib/components/shared/asset/asset-gallery.tsx" sourceLine="160" packageName="@vendure/dashboard" />
<GenerationInfo sourceFile="packages/dashboard/src/lib/components/shared/asset/asset-gallery.tsx" sourceLine="162" packageName="@vendure/dashboard" />

A component for displaying a gallery of assets.

Expand All @@ -27,7 +27,7 @@ Parameters

<MemberInfo kind="parameter" type={`<a href='/reference/dashboard/components/asset-gallery#assetgalleryprops'>AssetGalleryProps</a>`} />

<GenerationInfo sourceFile="packages/dashboard/src/lib/components/shared/asset/asset-gallery.tsx" sourceLine="83" packageName="@vendure/dashboard" />
<GenerationInfo sourceFile="packages/dashboard/src/lib/components/shared/asset/asset-gallery.tsx" sourceLine="85" packageName="@vendure/dashboard" />

Props for the [AssetGallery](/reference/dashboard/components/asset-gallery#assetgallery) component.

Expand Down
Loading
Loading