Procházet zdrojové kódy

docs(core): Add more docs on ProductVariantPriceUpdateStrategy

Relates to #2651
Michael Bromley před 1 rokem
rodič
revize
0ead892000
52 změnil soubory, kde provedl 240 přidání a 217 odebrání
  1. 32 0
      docs/docs/guides/core-concepts/channels/index.md
  2. 13 0
      docs/docs/guides/how-to/multi-vendor-marketplaces/index.md
  3. 1 1
      docs/docs/reference/admin-ui-api/action-bar/action-bar-location-id.md
  4. 1 0
      docs/docs/reference/admin-ui-api/action-bar/page-location-id.md
  5. 1 1
      docs/docs/reference/admin-ui-api/custom-detail-components/custom-detail-component-location-id.md
  6. 2 2
      docs/docs/reference/admin-ui-api/list-detail-views/typed-base-list-component.md
  7. 15 7
      docs/docs/reference/core-plugins/elasticsearch-plugin/elasticsearch-options.md
  8. 13 13
      docs/docs/reference/core-plugins/email-plugin/email-plugin-options.md
  9. 1 1
      docs/docs/reference/core-plugins/job-queue-plugin/bull-mqjob-queue-strategy.md
  10. 4 4
      docs/docs/reference/core-plugins/job-queue-plugin/bull-mqplugin-options.md
  11. 1 0
      docs/docs/reference/core-plugins/payments-plugin/stripe-plugin.md
  12. 1 1
      docs/docs/reference/core-plugins/sentry-plugin/index.md
  13. 1 1
      docs/docs/reference/typescript-api/assets/asset-options.md
  14. 1 1
      docs/docs/reference/typescript-api/auth/auth-options.md
  15. 1 1
      docs/docs/reference/typescript-api/auth/cookie-options.md
  16. 1 1
      docs/docs/reference/typescript-api/auth/superadmin-credentials.md
  17. 1 1
      docs/docs/reference/typescript-api/common/currency-code.md
  18. 1 1
      docs/docs/reference/typescript-api/common/job-state.md
  19. 1 1
      docs/docs/reference/typescript-api/common/language-code.md
  20. 1 1
      docs/docs/reference/typescript-api/common/permission.md
  21. 1 1
      docs/docs/reference/typescript-api/configuration/api-options.md
  22. 1 1
      docs/docs/reference/typescript-api/configuration/default-config.md
  23. 1 1
      docs/docs/reference/typescript-api/configuration/entity-options.md
  24. 1 1
      docs/docs/reference/typescript-api/configuration/runtime-vendure-config.md
  25. 8 1
      docs/docs/reference/typescript-api/configuration/system-options.md
  26. 1 1
      docs/docs/reference/typescript-api/configuration/vendure-config.md
  27. 1 1
      docs/docs/reference/typescript-api/custom-fields/custom-field-config.md
  28. 4 144
      docs/docs/reference/typescript-api/custom-fields/index.md
  29. 2 1
      docs/docs/reference/typescript-api/custom-fields/typed-custom-single-field-config.md
  30. 12 2
      docs/docs/reference/typescript-api/entities/product-variant-price.md
  31. 30 0
      docs/docs/reference/typescript-api/events/event-types.md
  32. 2 2
      docs/docs/reference/typescript-api/health-check/health-check-registry-service.md
  33. 1 1
      docs/docs/reference/typescript-api/health-check/http-health-check-strategy.md
  34. 1 1
      docs/docs/reference/typescript-api/import-export/import-export-options.md
  35. 11 1
      docs/docs/reference/typescript-api/job-queue/default-job-queue-plugin.md
  36. 1 1
      docs/docs/reference/typescript-api/job-queue/job-queue-options.md
  37. 13 1
      docs/docs/reference/typescript-api/job-queue/polling-job-queue-strategy.md
  38. 1 1
      docs/docs/reference/typescript-api/orders/order-options.md
  39. 1 1
      docs/docs/reference/typescript-api/payment/payment-options.md
  40. 9 1
      docs/docs/reference/typescript-api/products-stock/catalog-options.md
  41. 1 1
      docs/docs/reference/typescript-api/promotions/promotion-options.md
  42. 9 3
      docs/docs/reference/typescript-api/service-helpers/order-modifier.md
  43. 1 1
      docs/docs/reference/typescript-api/services/collection-service.md
  44. 1 1
      docs/docs/reference/typescript-api/services/history-service.md
  45. 4 3
      docs/docs/reference/typescript-api/services/order-service.md
  46. 3 3
      docs/docs/reference/typescript-api/services/payment-service.md
  47. 6 0
      docs/docs/reference/typescript-api/services/product-variant-service.md
  48. 1 1
      docs/docs/reference/typescript-api/shipping/shipping-options.md
  49. 1 1
      docs/docs/reference/typescript-api/tax/tax-options.md
  50. 3 1
      packages/core/src/config/catalog/default-product-variant-price-update-strategy.ts
  51. 10 0
      packages/core/src/config/catalog/product-variant-price-update-strategy.ts
  52. 5 0
      packages/dev-server/example-plugins/multivendor-plugin/multivendor.plugin.ts

+ 32 - 0
docs/docs/guides/core-concepts/channels/index.md

@@ -66,6 +66,38 @@ GBP and one for USD. This means that you are able to define multiple prices in d
 **Note:** in the diagram above that the ProductVariant is **always assigned to the default Channel**, and thus will have a price in the default channel too. Likewise, the default Channel also has a defaultCurrencyCode. Depending on your requirements, you may or may not make use of the default Channel.
 :::
 
+### Keeping prices synchronized
+
+When you have products assigned to multiple channels, updates to the price of a product in one channel will not automatically
+be reflected in other channels. For instance, in the diagram above, both the Default channel and the UK channel have a price
+in USD for the same product variant. 
+
+If an administrator of the UK channel changes the USD price to $20, the price in the Default channel will remain at $30. This
+is the default behavior, and is controlled by the [ProductVariantPriceUpdateStrategy](/reference/typescript-api/configuration/product-variant-price-update-strategy).
+
+If you want to keep prices synchronized across all channels, you can set the `syncPricesAcrossChannels` property of the
+[DefaultProductVariantPriceUpdateStrategy](/reference/typescript-api/configuration/product-variant-price-update-strategy#defaultproductvariantpriceupdatestrategy)
+to `true`. This will ensure that when the price of a product variant is updated in one channel, the price in all other channels
+(of that particular currency) will be updated to match.
+
+```ts
+import { DefaultProductVariantPriceUpdateStrategy, VendureConfig } from '@vendure/core';
+
+export const config: VendureConfig = {
+    // ...
+    // highlight-start
+    productVariantPriceUpdateStrategy: new DefaultProductVariantPriceUpdateStrategy({
+        syncPricesAcrossChannels: true,
+    }),
+    // highlight-end
+    // ...
+};
+```
+
+You may however require even more sophisticated logic. For instance, you may want a one-way synchronization, where the price
+in the Default channel is always the master price, and the prices in other channels are updated to match. In this case, you
+can create a custom `ProductVariantPriceUpdateStrategy` which implements the desired logic.
+
 ## Use cases
 
 ### Single shop

+ 13 - 0
docs/docs/guides/how-to/multi-vendor-marketplaces/index.md

@@ -58,6 +58,19 @@ Executing the `registerNewSeller` mutation does the following:
 
 Bob can now log in to the Admin UI using the provided credentials and begin creating products to sell!
 
+### Keeping prices synchronized
+
+In some marketplaces, the same product may be sold by multiple sellers. When this is the case, the product and its variants
+will be assigned not only to the default channel, but to multiple other channels as well - see the 
+[Channels, Currencies & Prices section](/guides/core-concepts/channels/#channels-currencies--prices) for a visual explanation of how this works.
+
+This means that there will be multiple ProductVariantPrice entities per variant, one for each channel. 
+ 
+In order
+to keep prices synchronized across all channels, the example multi-vendor plugin sets the `syncPricesAcrossChannels` property
+of the [DefaultProductVariantPriceUpdateStrategy](/reference/typescript-api/configuration/product-variant-price-update-strategy#defaultproductvariantpriceupdatestrategy)
+to `true`. Your own multi-vendor implementation may require more sophisticated price synchronization logic, in which case
+you can implement your own custom [ProductVariantPriceUpdateStrategy](/reference/typescript-api/configuration/product-variant-price-update-strategy).
 
 ## Assigning OrderLines to the correct Seller
 

+ 1 - 1
docs/docs/reference/admin-ui-api/action-bar/action-bar-location-id.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## ActionBarLocationId
 
-<GenerationInfo sourceFile="packages/admin-ui/src/lib/core/src/common/component-registry-types.ts" sourceLine="104" packageName="@vendure/admin-ui" />
+<GenerationInfo sourceFile="packages/admin-ui/src/lib/core/src/common/component-registry-types.ts" sourceLine="105" packageName="@vendure/admin-ui" />
 
 The valid locationIds for registering action bar items.
 

+ 1 - 0
docs/docs/reference/admin-ui-api/action-bar/page-location-id.md

@@ -38,6 +38,7 @@ type PageLocationId = | 'administrator-detail'
     | 'job-list'
     | 'order-detail'
     | 'order-list'
+    | 'modify-order'
     | 'payment-method-detail'
     | 'payment-method-list'
     | 'product-detail'

+ 1 - 1
docs/docs/reference/admin-ui-api/custom-detail-components/custom-detail-component-location-id.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## CustomDetailComponentLocationId
 
-<GenerationInfo sourceFile="packages/admin-ui/src/lib/core/src/common/component-registry-types.ts" sourceLine="112" packageName="@vendure/admin-ui" />
+<GenerationInfo sourceFile="packages/admin-ui/src/lib/core/src/common/component-registry-types.ts" sourceLine="113" packageName="@vendure/admin-ui" />
 
 The valid locations for embedding a <a href='/reference/admin-ui-api/custom-detail-components/custom-detail-component#customdetailcomponent'>CustomDetailComponent</a>.
 

+ 2 - 2
docs/docs/reference/admin-ui-api/list-detail-views/typed-base-list-component.md

@@ -34,7 +34,7 @@ class TypedBaseListComponent<T extends TypedDocumentNode<any, Vars>, Field exten
     createFilterCollection() => DataTableFilterCollection<NonNullable<NonNullable<Vars['options']>['filter']>>;
     createSortCollection() => DataTableSortCollection<NonNullable<NonNullable<Vars['options']>['sort']>>;
     setLanguage(code: LanguageCode) => ;
-    getCustomFieldConfig(key: Exclude<keyof CustomFields, '__typename'>) => CustomFieldConfig[];
+    getCustomFieldConfig(key: Exclude<keyof CustomFields, '__typename'> | string) => CustomFieldConfig[];
 }
 ```
 * Extends: <code><a href='/reference/admin-ui-api/list-detail-views/base-list-component#baselistcomponent'>BaseListComponent</a>&#60;ResultOf&#60;T&#62;, ItemOf&#60;ResultOf&#60;T&#62;, Field&#62;, VariablesOf&#60;T&#62;&#62;</code>
@@ -103,7 +103,7 @@ class TypedBaseListComponent<T extends TypedDocumentNode<any, Vars>, Field exten
 
 ### getCustomFieldConfig
 
-<MemberInfo kind="method" type={`(key: Exclude&#60;keyof <a href='/reference/typescript-api/custom-fields/#customfields'>CustomFields</a>, '__typename'&#62;) => <a href='/reference/typescript-api/custom-fields/custom-field-config#customfieldconfig'>CustomFieldConfig</a>[]`}   />
+<MemberInfo kind="method" type={`(key: Exclude&#60;keyof <a href='/reference/typescript-api/custom-fields/#customfields'>CustomFields</a>, '__typename'&#62; | string) => <a href='/reference/typescript-api/custom-fields/custom-field-config#customfieldconfig'>CustomFieldConfig</a>[]`}   />
 
 
 

+ 15 - 7
docs/docs/reference/core-plugins/elasticsearch-plugin/elasticsearch-options.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## ElasticsearchOptions
 
-<GenerationInfo sourceFile="packages/elasticsearch-plugin/src/options.ts" sourceLine="31" packageName="@vendure/elasticsearch-plugin" />
+<GenerationInfo sourceFile="packages/elasticsearch-plugin/src/options.ts" sourceLine="30" packageName="@vendure/elasticsearch-plugin" />
 
 Configuration options for the <a href='/reference/core-plugins/elasticsearch-plugin/#elasticsearchplugin'>ElasticsearchPlugin</a>.
 
@@ -27,7 +27,8 @@ interface ElasticsearchOptions {
     indexMappingProperties?: {
         [indexName: string]: object;
     };
-    batchSize?: number;
+    reindexProductsChunkSize?: number;
+    reindexBulkOperationSizeLimit?: number;
     searchConfig?: SearchConfig;
     customProductMappings?: {
         [fieldName: string]: CustomMapping<[Product, ProductVariant[], LanguageCode, Injector, RequestContext]>;
@@ -157,11 +158,18 @@ indexMappingProperties: {
   }
 }
 ```
-### batchSize
+### reindexProductsChunkSize
 
-<MemberInfo kind="property" type={`number`} default="2000"   />
+<MemberInfo kind="property" type={`number`} default="2500"  since="2.1.7"  />
 
-Batch size for bulk operations (e.g. when rebuilding the indices).
+Products limit chunk size for each loop iteration when indexing products.
+### reindexBulkOperationSizeLimit
+
+<MemberInfo kind="property" type={`number`} default="3000"  since="2.1.7"  />
+
+Index operations are performed in bulk, with each bulk operation containing a number of individual
+index operations. This option sets the maximum number of operations in the memory buffer before a
+bulk operation is executed.
 ### searchConfig
 
 <MemberInfo kind="property" type={`<a href='/reference/core-plugins/elasticsearch-plugin/elasticsearch-options#searchconfig'>SearchConfig</a>`}   />
@@ -364,7 +372,7 @@ extend input SearchResultSortParameter {
 
 ## SearchConfig
 
-<GenerationInfo sourceFile="packages/elasticsearch-plugin/src/options.ts" sourceLine="386" packageName="@vendure/elasticsearch-plugin" />
+<GenerationInfo sourceFile="packages/elasticsearch-plugin/src/options.ts" sourceLine="395" packageName="@vendure/elasticsearch-plugin" />
 
 Configuration options for the internal Elasticsearch query which is generated when performing a search.
 
@@ -645,7 +653,7 @@ searchConfig: {
 
 ## BoostFieldsConfig
 
-<GenerationInfo sourceFile="packages/elasticsearch-plugin/src/options.ts" sourceLine="671" packageName="@vendure/elasticsearch-plugin" />
+<GenerationInfo sourceFile="packages/elasticsearch-plugin/src/options.ts" sourceLine="680" packageName="@vendure/elasticsearch-plugin" />
 
 Configuration for [boosting](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-multi-match-query.html#field-boost)
 the scores of given fields when performing a search against a term.

+ 13 - 13
docs/docs/reference/core-plugins/email-plugin/email-plugin-options.md

@@ -19,11 +19,11 @@ Configuration for the EmailPlugin.
 interface EmailPluginOptions {
     templatePath?: string;
     templateLoader?: TemplateLoader;
-    transport:
-        | EmailTransportOptions
-        | ((
-              injector?: Injector,
-              ctx?: RequestContext,
+    transport:
+        | EmailTransportOptions
+        | ((
+              injector?: Injector,
+              ctx?: RequestContext,
           ) => EmailTransportOptions | Promise<EmailTransportOptions>);
     handlers: Array<EmailEventHandler<string, any>>;
     globalTemplateVars?: { [key: string]: any };
@@ -38,43 +38,43 @@ interface EmailPluginOptions {
 
 <MemberInfo kind="property" type={`string`}   />
 
-The path to the location of the email templates. In a default Vendure installation,
+The path to the location of the email templates. In a default Vendure installation,
 the templates are installed to `<project root>/vendure/email/templates`.
 ### templateLoader
 
 <MemberInfo kind="property" type={`<a href='/reference/core-plugins/email-plugin/template-loader#templateloader'>TemplateLoader</a>`}  since="2.0.0"  />
 
-An optional TemplateLoader which can be used to load templates from a custom location or async service.
+An optional TemplateLoader which can be used to load templates from a custom location or async service.
 The default uses the FileBasedTemplateLoader which loads templates from `<project root>/vendure/email/templates`
 ### transport
 
-<MemberInfo kind="property" type={`| <a href='/reference/core-plugins/email-plugin/transport-options#emailtransportoptions'>EmailTransportOptions</a>         | ((               injector?: <a href='/reference/typescript-api/common/injector#injector'>Injector</a>,               ctx?: <a href='/reference/typescript-api/request/request-context#requestcontext'>RequestContext</a>,           ) =&#62; <a href='/reference/core-plugins/email-plugin/transport-options#emailtransportoptions'>EmailTransportOptions</a> | Promise&#60;<a href='/reference/core-plugins/email-plugin/transport-options#emailtransportoptions'>EmailTransportOptions</a>&#62;)`}   />
+<MemberInfo kind="property" type={`| <a href='/reference/core-plugins/email-plugin/transport-options#emailtransportoptions'>EmailTransportOptions</a>
         | ((
               injector?: <a href='/reference/typescript-api/common/injector#injector'>Injector</a>,
               ctx?: <a href='/reference/typescript-api/request/request-context#requestcontext'>RequestContext</a>,
           ) =&#62; <a href='/reference/core-plugins/email-plugin/transport-options#emailtransportoptions'>EmailTransportOptions</a> | Promise&#60;<a href='/reference/core-plugins/email-plugin/transport-options#emailtransportoptions'>EmailTransportOptions</a>&#62;)`}   />
 
 Configures how the emails are sent.
 ### handlers
 
 <MemberInfo kind="property" type={`Array&#60;<a href='/reference/core-plugins/email-plugin/email-event-handler#emaileventhandler'>EmailEventHandler</a>&#60;string, any&#62;&#62;`}   />
 
-An array of <a href='/reference/core-plugins/email-plugin/email-event-handler#emaileventhandler'>EmailEventHandler</a>s which define which Vendure events will trigger
+An array of <a href='/reference/core-plugins/email-plugin/email-event-handler#emaileventhandler'>EmailEventHandler</a>s which define which Vendure events will trigger
 emails, and how those emails are generated.
 ### globalTemplateVars
 
 <MemberInfo kind="property" type={`{ [key: string]: any }`}   />
 
-An object containing variables which are made available to all templates. For example,
-the storefront URL could be defined here and then used in the "email address verification"
+An object containing variables which are made available to all templates. For example,
+the storefront URL could be defined here and then used in the "email address verification"
 email.
 ### emailSender
 
 <MemberInfo kind="property" type={`<a href='/reference/core-plugins/email-plugin/email-sender#emailsender'>EmailSender</a>`} default="<a href='/reference/core-plugins/email-plugin/email-sender#nodemaileremailsender'>NodemailerEmailSender</a>"   />
 
-An optional allowed EmailSender, used to allow custom implementations of the send functionality
+An optional allowed EmailSender, used to allow custom implementations of the send functionality
 while still utilizing the existing emailPlugin functionality.
 ### emailGenerator
 
 <MemberInfo kind="property" type={`<a href='/reference/core-plugins/email-plugin/email-generator#emailgenerator'>EmailGenerator</a>`} default="<a href='/reference/core-plugins/email-plugin/email-generator#handlebarsmjmlgenerator'>HandlebarsMjmlGenerator</a>"   />
 
-An optional allowed EmailGenerator, used to allow custom email generation functionality to
+An optional allowed EmailGenerator, used to allow custom email generation functionality to
 better match with custom email sending functionality.
 
 

+ 1 - 1
docs/docs/reference/core-plugins/job-queue-plugin/bull-mqjob-queue-strategy.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## BullMQJobQueueStrategy
 
-<GenerationInfo sourceFile="packages/job-queue-plugin/src/bullmq/bullmq-job-queue-strategy.ts" sourceLine="40" packageName="@vendure/job-queue-plugin" />
+<GenerationInfo sourceFile="packages/job-queue-plugin/src/bullmq/bullmq-job-queue-strategy.ts" sourceLine="42" packageName="@vendure/job-queue-plugin" />
 
 This JobQueueStrategy uses [BullMQ](https://docs.bullmq.io/) to implement a push-based job queue
 on top of Redis. It should not be used alone, but as part of the <a href='/reference/core-plugins/job-queue-plugin/bull-mqjob-queue-plugin#bullmqjobqueueplugin'>BullMQJobQueuePlugin</a>.

+ 4 - 4
docs/docs/reference/core-plugins/job-queue-plugin/bull-mqplugin-options.md

@@ -18,8 +18,8 @@ Configuration options for the <a href='/reference/core-plugins/job-queue-plugin/
 ```ts title="Signature"
 interface BullMQPluginOptions {
     connection?: ConnectionOptions;
-    queueOptions?: Exclude<QueueOptions, 'connection'>;
-    workerOptions?: Exclude<WorkerOptions, 'connection'>;
+    queueOptions?: Omit<QueueOptions, 'connection'>;
+    workerOptions?: Omit<WorkerOptions, 'connection'>;
     setRetries?: (queueName: string, job: Job) => number;
     setBackoff?: (queueName: string, job: Job) => BackoffOptions | undefined;
 }
@@ -37,14 +37,14 @@ creating a new Queue, Worker and Scheduler instance.
 If omitted, it will attempt to connect to Redis at `127.0.0.1:6379`.
 ### queueOptions
 
-<MemberInfo kind="property" type={`Exclude&#60;QueueOptions, 'connection'&#62;`}   />
+<MemberInfo kind="property" type={`Omit&#60;QueueOptions, 'connection'&#62;`}   />
 
 Additional options used when instantiating the BullMQ
 Queue instance.
 See the [BullMQ QueueOptions docs](https://github.com/taskforcesh/bullmq/blob/master/docs/gitbook/api/bullmq.queueoptions.md)
 ### workerOptions
 
-<MemberInfo kind="property" type={`Exclude&#60;WorkerOptions, 'connection'&#62;`}   />
+<MemberInfo kind="property" type={`Omit&#60;WorkerOptions, 'connection'&#62;`}   />
 
 Additional options used when instantiating the BullMQ
 Worker instance.

+ 1 - 0
docs/docs/reference/core-plugins/payments-plugin/stripe-plugin.md

@@ -243,6 +243,7 @@ export const config: VendureConfig = {
     }),
   ],
 };
+```
 
 Note: If the `paymentIntentCreateParams` is also used and returns a `metadata` key, then the values
 returned by both functions will be merged.

+ 1 - 1
docs/docs/reference/core-plugins/sentry-plugin/index.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## SentryPlugin
 
-<GenerationInfo sourceFile="packages/sentry-plugin/src/sentry-plugin.ts" sourceLine="109" packageName="@vendure/sentry-plugin" />
+<GenerationInfo sourceFile="packages/sentry-plugin/src/sentry-plugin.ts" sourceLine="108" packageName="@vendure/sentry-plugin" />
 
 This plugin integrates the [Sentry](https://sentry.io) error tracking & performance monitoring
 service with your Vendure server. In addition to capturing errors, it also provides built-in

+ 1 - 1
docs/docs/reference/typescript-api/assets/asset-options.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## AssetOptions
 
-<GenerationInfo sourceFile="packages/core/src/config/vendure-config.ts" sourceLine="624" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/config/vendure-config.ts" sourceLine="626" packageName="@vendure/core" />
 
 The AssetOptions define how assets (images and other files) are named and stored, and how preview images are generated.
 

+ 1 - 1
docs/docs/reference/typescript-api/auth/auth-options.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## AuthOptions
 
-<GenerationInfo sourceFile="packages/core/src/config/vendure-config.ts" sourceLine="326" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/config/vendure-config.ts" sourceLine="328" packageName="@vendure/core" />
 
 The AuthOptions define how authentication and authorization is managed.
 

+ 1 - 1
docs/docs/reference/typescript-api/auth/cookie-options.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## CookieOptions
 
-<GenerationInfo sourceFile="packages/core/src/config/vendure-config.ts" sourceLine="221" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/config/vendure-config.ts" sourceLine="223" packageName="@vendure/core" />
 
 Options for the handling of the cookies used to track sessions (only applicable if
 `authOptions.tokenMethod` is set to `'cookie'`). These options are passed directly

+ 1 - 1
docs/docs/reference/typescript-api/auth/superadmin-credentials.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## SuperadminCredentials
 
-<GenerationInfo sourceFile="packages/core/src/config/vendure-config.ts" sourceLine="790" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/config/vendure-config.ts" sourceLine="802" packageName="@vendure/core" />
 
 These credentials will be used to create the Superadmin user & administrator
 when Vendure first bootstraps.

+ 1 - 1
docs/docs/reference/typescript-api/common/currency-code.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## CurrencyCode
 
-<GenerationInfo sourceFile="packages/common/src/generated-types.ts" sourceLine="962" packageName="@vendure/common" />
+<GenerationInfo sourceFile="packages/common/src/generated-types.ts" sourceLine="968" packageName="@vendure/common" />
 
 ISO 4217 currency code
 

+ 1 - 1
docs/docs/reference/typescript-api/common/job-state.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## JobState
 
-<GenerationInfo sourceFile="packages/common/src/generated-types.ts" sourceLine="2107" packageName="@vendure/common" />
+<GenerationInfo sourceFile="packages/common/src/generated-types.ts" sourceLine="2125" packageName="@vendure/common" />
 
 The state of a Job in the JobQueue
 

+ 1 - 1
docs/docs/reference/typescript-api/common/language-code.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## LanguageCode
 
-<GenerationInfo sourceFile="packages/common/src/generated-types.ts" sourceLine="2125" packageName="@vendure/common" />
+<GenerationInfo sourceFile="packages/common/src/generated-types.ts" sourceLine="2143" packageName="@vendure/common" />
 
 Languages in the form of a ISO 639-1 language code with optional
 region or script modifier (e.g. de_AT). The selection available is based

+ 1 - 1
docs/docs/reference/typescript-api/common/permission.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## Permission
 
-<GenerationInfo sourceFile="packages/common/src/generated-types.ts" sourceLine="4237" packageName="@vendure/common" />
+<GenerationInfo sourceFile="packages/common/src/generated-types.ts" sourceLine="4269" packageName="@vendure/common" />
 
 Permissions for administrators and customers. Used to control access to
 GraphQL resolvers via the <a href='/reference/typescript-api/request/allow-decorator#allow'>Allow</a> decorator.

+ 1 - 1
docs/docs/reference/typescript-api/configuration/api-options.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## ApiOptions
 
-<GenerationInfo sourceFile="packages/core/src/config/vendure-config.ts" sourceLine="64" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/config/vendure-config.ts" sourceLine="66" packageName="@vendure/core" />
 
 The ApiOptions define how the Vendure GraphQL APIs are exposed, as well as allowing the API layer
 to be extended with middleware.

+ 1 - 1
docs/docs/reference/typescript-api/configuration/default-config.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## defaultConfig
 
-<GenerationInfo sourceFile="packages/core/src/config/default-config.ts" sourceLine="58" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/config/default-config.ts" sourceLine="59" packageName="@vendure/core" />
 
 The default configuration settings which are used if not explicitly overridden in the bootstrap() call.
 

+ 1 - 1
docs/docs/reference/typescript-api/configuration/entity-options.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## EntityOptions
 
-<GenerationInfo sourceFile="packages/core/src/config/vendure-config.ts" sourceLine="932" packageName="@vendure/core" since="1.3.0" />
+<GenerationInfo sourceFile="packages/core/src/config/vendure-config.ts" sourceLine="944" packageName="@vendure/core" since="1.3.0" />
 
 Options relating to the internal handling of entities.
 

+ 1 - 1
docs/docs/reference/typescript-api/configuration/runtime-vendure-config.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## RuntimeVendureConfig
 
-<GenerationInfo sourceFile="packages/core/src/config/vendure-config.ts" sourceLine="1161" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/config/vendure-config.ts" sourceLine="1182" packageName="@vendure/core" />
 
 This interface represents the VendureConfig object available at run-time, i.e. the user-supplied
 config values have been merged with the <a href='/reference/typescript-api/configuration/default-config#defaultconfig'>defaultConfig</a> values.

+ 8 - 1
docs/docs/reference/typescript-api/configuration/system-options.md

@@ -11,13 +11,14 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## SystemOptions
 
-<GenerationInfo sourceFile="packages/core/src/config/vendure-config.ts" sourceLine="1012" packageName="@vendure/core" since="1.6.0" />
+<GenerationInfo sourceFile="packages/core/src/config/vendure-config.ts" sourceLine="1024" packageName="@vendure/core" since="1.6.0" />
 
 Options relating to system functions.
 
 ```ts title="Signature"
 interface SystemOptions {
     healthChecks?: HealthCheckStrategy[];
+    errorHandlers?: ErrorHandlerStrategy[];
 }
 ```
 
@@ -29,6 +30,12 @@ interface SystemOptions {
 
 Defines an array of <a href='/reference/typescript-api/health-check/health-check-strategy#healthcheckstrategy'>HealthCheckStrategy</a> instances which are used by the `/health` endpoint to verify
 that any critical systems which the Vendure server depends on are also healthy.
+### errorHandlers
+
+<MemberInfo kind="property" type={`<a href='/reference/typescript-api/errors/error-handler-strategy#errorhandlerstrategy'>ErrorHandlerStrategy</a>[]`} default="[]"  since="2.2.0"  />
+
+Defines an array of <a href='/reference/typescript-api/errors/error-handler-strategy#errorhandlerstrategy'>ErrorHandlerStrategy</a> instances which are used to define logic to be executed
+when an error occurs, either on the server or the worker.
 
 
 </div>

+ 1 - 1
docs/docs/reference/typescript-api/configuration/vendure-config.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## VendureConfig
 
-<GenerationInfo sourceFile="packages/core/src/config/vendure-config.ts" sourceLine="1031" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/config/vendure-config.ts" sourceLine="1052" packageName="@vendure/core" />
 
 All possible configuration options are defined by the
 [`VendureConfig`](https://github.com/vendure-ecommerce/vendure/blob/master/server/src/config/vendure-config.ts) interface.

+ 1 - 1
docs/docs/reference/typescript-api/custom-fields/custom-field-config.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## CustomFieldConfig
 
-<GenerationInfo sourceFile="packages/core/src/config/custom-field/custom-field-types.ts" sourceLine="112" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/config/custom-field/custom-field-types.ts" sourceLine="114" packageName="@vendure/core" />
 
 An object used to configure a custom field.
 

+ 4 - 144
docs/docs/reference/typescript-api/custom-fields/index.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## CustomFields
 
-<GenerationInfo sourceFile="packages/core/src/config/custom-field/custom-field-types.ts" sourceLine="147" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/config/custom-field/custom-field-types.ts" sourceLine="149" packageName="@vendure/core" />
 
 Most entities can have additional fields added to them by defining an array of <a href='/reference/typescript-api/custom-fields/custom-field-config#customfieldconfig'>CustomFieldConfig</a>
 objects on against the corresponding key.
@@ -35,7 +35,7 @@ bootstrap({
 ```
 
 ```ts title="Signature"
-interface CustomFields {
+type CustomFields = {
     Address?: CustomFieldConfig[];
     Administrator?: CustomFieldConfig[];
     Asset?: CustomFieldConfig[];
@@ -54,6 +54,7 @@ interface CustomFields {
     ProductOption?: CustomFieldConfig[];
     ProductOptionGroup?: CustomFieldConfig[];
     ProductVariant?: CustomFieldConfig[];
+    ProductVariantPrice?: CustomFieldConfig[];
     Promotion?: CustomFieldConfig[];
     Region?: CustomFieldConfig[];
     Seller?: CustomFieldConfig[];
@@ -63,146 +64,5 @@ interface CustomFields {
     TaxRate?: CustomFieldConfig[];
     User?: CustomFieldConfig[];
     Zone?: CustomFieldConfig[];
-}
+} & { [entity: string]: CustomFieldConfig[] }
 ```
-
-<div className="members-wrapper">
-
-### Address
-
-<MemberInfo kind="property" type={`<a href='/reference/typescript-api/custom-fields/custom-field-config#customfieldconfig'>CustomFieldConfig</a>[]`}   />
-
-
-### Administrator
-
-<MemberInfo kind="property" type={`<a href='/reference/typescript-api/custom-fields/custom-field-config#customfieldconfig'>CustomFieldConfig</a>[]`}   />
-
-
-### Asset
-
-<MemberInfo kind="property" type={`<a href='/reference/typescript-api/custom-fields/custom-field-config#customfieldconfig'>CustomFieldConfig</a>[]`}   />
-
-
-### Channel
-
-<MemberInfo kind="property" type={`<a href='/reference/typescript-api/custom-fields/custom-field-config#customfieldconfig'>CustomFieldConfig</a>[]`}   />
-
-
-### Collection
-
-<MemberInfo kind="property" type={`<a href='/reference/typescript-api/custom-fields/custom-field-config#customfieldconfig'>CustomFieldConfig</a>[]`}   />
-
-
-### Customer
-
-<MemberInfo kind="property" type={`<a href='/reference/typescript-api/custom-fields/custom-field-config#customfieldconfig'>CustomFieldConfig</a>[]`}   />
-
-
-### CustomerGroup
-
-<MemberInfo kind="property" type={`<a href='/reference/typescript-api/custom-fields/custom-field-config#customfieldconfig'>CustomFieldConfig</a>[]`}   />
-
-
-### Facet
-
-<MemberInfo kind="property" type={`<a href='/reference/typescript-api/custom-fields/custom-field-config#customfieldconfig'>CustomFieldConfig</a>[]`}   />
-
-
-### FacetValue
-
-<MemberInfo kind="property" type={`<a href='/reference/typescript-api/custom-fields/custom-field-config#customfieldconfig'>CustomFieldConfig</a>[]`}   />
-
-
-### Fulfillment
-
-<MemberInfo kind="property" type={`<a href='/reference/typescript-api/custom-fields/custom-field-config#customfieldconfig'>CustomFieldConfig</a>[]`}   />
-
-
-### GlobalSettings
-
-<MemberInfo kind="property" type={`<a href='/reference/typescript-api/custom-fields/custom-field-config#customfieldconfig'>CustomFieldConfig</a>[]`}   />
-
-
-### Order
-
-<MemberInfo kind="property" type={`<a href='/reference/typescript-api/custom-fields/custom-field-config#customfieldconfig'>CustomFieldConfig</a>[]`}   />
-
-
-### OrderLine
-
-<MemberInfo kind="property" type={`<a href='/reference/typescript-api/custom-fields/custom-field-config#customfieldconfig'>CustomFieldConfig</a>[]`}   />
-
-
-### PaymentMethod
-
-<MemberInfo kind="property" type={`<a href='/reference/typescript-api/custom-fields/custom-field-config#customfieldconfig'>CustomFieldConfig</a>[]`}   />
-
-
-### Product
-
-<MemberInfo kind="property" type={`<a href='/reference/typescript-api/custom-fields/custom-field-config#customfieldconfig'>CustomFieldConfig</a>[]`}   />
-
-
-### ProductOption
-
-<MemberInfo kind="property" type={`<a href='/reference/typescript-api/custom-fields/custom-field-config#customfieldconfig'>CustomFieldConfig</a>[]`}   />
-
-
-### ProductOptionGroup
-
-<MemberInfo kind="property" type={`<a href='/reference/typescript-api/custom-fields/custom-field-config#customfieldconfig'>CustomFieldConfig</a>[]`}   />
-
-
-### ProductVariant
-
-<MemberInfo kind="property" type={`<a href='/reference/typescript-api/custom-fields/custom-field-config#customfieldconfig'>CustomFieldConfig</a>[]`}   />
-
-
-### Promotion
-
-<MemberInfo kind="property" type={`<a href='/reference/typescript-api/custom-fields/custom-field-config#customfieldconfig'>CustomFieldConfig</a>[]`}   />
-
-
-### Region
-
-<MemberInfo kind="property" type={`<a href='/reference/typescript-api/custom-fields/custom-field-config#customfieldconfig'>CustomFieldConfig</a>[]`}   />
-
-
-### Seller
-
-<MemberInfo kind="property" type={`<a href='/reference/typescript-api/custom-fields/custom-field-config#customfieldconfig'>CustomFieldConfig</a>[]`}   />
-
-
-### ShippingMethod
-
-<MemberInfo kind="property" type={`<a href='/reference/typescript-api/custom-fields/custom-field-config#customfieldconfig'>CustomFieldConfig</a>[]`}   />
-
-
-### StockLocation
-
-<MemberInfo kind="property" type={`<a href='/reference/typescript-api/custom-fields/custom-field-config#customfieldconfig'>CustomFieldConfig</a>[]`}   />
-
-
-### TaxCategory
-
-<MemberInfo kind="property" type={`<a href='/reference/typescript-api/custom-fields/custom-field-config#customfieldconfig'>CustomFieldConfig</a>[]`}   />
-
-
-### TaxRate
-
-<MemberInfo kind="property" type={`<a href='/reference/typescript-api/custom-fields/custom-field-config#customfieldconfig'>CustomFieldConfig</a>[]`}   />
-
-
-### User
-
-<MemberInfo kind="property" type={`<a href='/reference/typescript-api/custom-fields/custom-field-config#customfieldconfig'>CustomFieldConfig</a>[]`}   />
-
-
-### Zone
-
-<MemberInfo kind="property" type={`<a href='/reference/typescript-api/custom-fields/custom-field-config#customfieldconfig'>CustomFieldConfig</a>[]`}   />
-
-
-
-
-</div>

+ 2 - 1
docs/docs/reference/typescript-api/custom-fields/typed-custom-single-field-config.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## TypedCustomSingleFieldConfig
 
-<GenerationInfo sourceFile="packages/core/src/config/custom-field/custom-field-types.ts" sourceLine="55" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/config/custom-field/custom-field-types.ts" sourceLine="56" packageName="@vendure/core" />
 
 Configures a custom field on an entity in the <a href='/reference/typescript-api/custom-fields/#customfields'>CustomFields</a> config object.
 
@@ -22,6 +22,7 @@ type TypedCustomSingleFieldConfig<T extends CustomFieldType, C extends CustomFie
     validate?: (
         value: DefaultValueType<T>,
         injector: Injector,
+        ctx: RequestContext,
     ) => string | LocalizedString[] | void | Promise<string | LocalizedString[] | void>;
 }
 ```

+ 12 - 2
docs/docs/reference/typescript-api/entities/product-variant-price.md

@@ -11,13 +11,13 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## ProductVariantPrice
 
-<GenerationInfo sourceFile="packages/core/src/entity/product-variant/product-variant-price.entity.ts" sourceLine="18" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/entity/product-variant/product-variant-price.entity.ts" sourceLine="20" packageName="@vendure/core" />
 
 A ProductVariantPrice is a Channel-specific price for a ProductVariant. For every Channel to
 which a ProductVariant is assigned, there will be a corresponding ProductVariantPrice entity.
 
 ```ts title="Signature"
-class ProductVariantPrice extends VendureEntity {
+class ProductVariantPrice extends VendureEntity implements HasCustomFields {
     constructor(input?: DeepPartial<ProductVariantPrice>)
     @Money() price: number;
     @EntityId({ nullable: true }) channelId: ID;
@@ -26,11 +26,16 @@ class ProductVariantPrice extends VendureEntity {
     @Index()
     @ManyToOne(type => ProductVariant, variant => variant.productVariantPrices, { onDelete: 'CASCADE' })
     variant: ProductVariant;
+    @Column(type => CustomProductVariantPriceFields)
+    customFields: CustomProductVariantPriceFields;
 }
 ```
 * Extends: <code><a href='/reference/typescript-api/entities/vendure-entity#vendureentity'>VendureEntity</a></code>
 
 
+* Implements: <code>HasCustomFields</code>
+
+
 
 <div className="members-wrapper">
 
@@ -59,6 +64,11 @@ class ProductVariantPrice extends VendureEntity {
 <MemberInfo kind="property" type={`<a href='/reference/typescript-api/entities/product-variant#productvariant'>ProductVariant</a>`}   />
 
 
+### customFields
+
+<MemberInfo kind="property" type={`CustomProductVariantPriceFields`}   />
+
+
 
 
 </div>

+ 30 - 0
docs/docs/reference/typescript-api/events/event-types.md

@@ -1207,6 +1207,36 @@ class ProductVariantEvent extends VendureEntityEvent<ProductVariant[], ProductVa
 
 
 
+</div>
+
+
+## ProductVariantPriceEvent
+
+<GenerationInfo sourceFile="packages/core/src/event-bus/events/product-variant-price-event.ts" sourceLine="17" packageName="@vendure/core" since="2.2.0" />
+
+This event is fired whenever a <a href='/reference/typescript-api/entities/product-variant-price#productvariantprice'>ProductVariantPrice</a> is added, updated or deleted.
+
+```ts title="Signature"
+class ProductVariantPriceEvent extends VendureEntityEvent<
+    ProductVariantPrice[],
+    ProductVariantInputTypes
+> {
+    constructor(ctx: RequestContext, entity: ProductVariantPrice[], type: 'created' | 'updated' | 'deleted', input?: ProductVariantInputTypes)
+}
+```
+* Extends: <code><a href='/reference/typescript-api/events/vendure-entity-event#vendureentityevent'>VendureEntityEvent</a>&#60;     <a href='/reference/typescript-api/entities/product-variant-price#productvariantprice'>ProductVariantPrice</a>[],     ProductVariantInputTypes &#62;</code>
+
+
+
+<div className="members-wrapper">
+
+### constructor
+
+<MemberInfo kind="method" type={`(ctx: <a href='/reference/typescript-api/request/request-context#requestcontext'>RequestContext</a>, entity: <a href='/reference/typescript-api/entities/product-variant-price#productvariantprice'>ProductVariantPrice</a>[], type: 'created' | 'updated' | 'deleted', input?: ProductVariantInputTypes) => ProductVariantPriceEvent`}   />
+
+
+
+
 </div>
 
 

+ 2 - 2
docs/docs/reference/typescript-api/health-check/health-check-registry-service.md

@@ -26,8 +26,8 @@ Plugins which rely on external services (web services, databases etc.) can make
 service to add a check for that dependency to the Vendure health check.
 
 
-Since v1.6.0, the preferred way to implement a custom health check is by creating a new
-<a href='/reference/typescript-api/health-check/health-check-strategy#healthcheckstrategy'>HealthCheckStrategy</a> and then passing it to the `systemOptions.healthChecks` array.
+Since v1.6.0, the preferred way to implement a custom health check is by creating a new <a href='/reference/typescript-api/health-check/health-check-strategy#healthcheckstrategy'>HealthCheckStrategy</a>
+and then passing it to the `systemOptions.healthChecks` array.
 See the <a href='/reference/typescript-api/health-check/health-check-strategy#healthcheckstrategy'>HealthCheckStrategy</a> docs for an example configuration.
 
 The alternative way to register a health check is by injecting this service directly into your

+ 1 - 1
docs/docs/reference/typescript-api/health-check/http-health-check-strategy.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## HttpHealthCheckStrategy
 
-<GenerationInfo sourceFile="packages/core/src/health-check/http-health-check-strategy.ts" sourceLine="36" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/health-check/http-health-check-strategy.ts" sourceLine="37" packageName="@vendure/core" />
 
 A <a href='/reference/typescript-api/health-check/health-check-strategy#healthcheckstrategy'>HealthCheckStrategy</a> used to check health by pinging a url. Internally it uses
 the [NestJS HttpHealthIndicator](https://docs.nestjs.com/recipes/terminus#http-healthcheck).

+ 1 - 1
docs/docs/reference/typescript-api/import-export/import-export-options.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## ImportExportOptions
 
-<GenerationInfo sourceFile="packages/core/src/config/vendure-config.ts" sourceLine="867" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/config/vendure-config.ts" sourceLine="879" packageName="@vendure/core" />
 
 Options related to importing & exporting data.
 

+ 11 - 1
docs/docs/reference/typescript-api/job-queue/default-job-queue-plugin.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## DefaultJobQueuePlugin
 
-<GenerationInfo sourceFile="packages/core/src/plugin/default-job-queue-plugin/default-job-queue-plugin.ts" sourceLine="171" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/plugin/default-job-queue-plugin/default-job-queue-plugin.ts" sourceLine="183" packageName="@vendure/core" />
 
 A plugin which configures Vendure to use the SQL database to persist the JobQueue jobs using the <a href='/reference/typescript-api/job-queue/sql-job-queue-strategy#sqljobqueuestrategy'>SqlJobQueueStrategy</a>. If you add this
 plugin to an existing Vendure installation, you'll need to run a [database migration](/guides/developer-guide/migrations), since this
@@ -133,6 +133,7 @@ interface DefaultJobQueueOptions {
     backoffStrategy?: BackoffStrategy;
     setRetries?: (queueName: string, job: Job) => number;
     useDatabaseForBuffer?: boolean;
+    gracefulShutdownTimeout?: number;
 }
 ```
 
@@ -186,6 +187,15 @@ recommended for production.
 
 When enabled, a new `JobRecordBuffer` database entity will be defined which will
 require a migration when first enabling this option.
+### gracefulShutdownTimeout
+
+<MemberInfo kind="property" type={`number`} default="20_000"  since="2.2.0"  />
+
+The timeout in ms which the queue will use when attempting a graceful shutdown.
+That means when the server is shut down but a job is running, the job queue will
+wait for the job to complete before allowing the server to shut down. If the job
+does not complete within this timeout window, the job will be forced to stop
+and the server will shut down anyway.
 
 
 </div>

+ 1 - 1
docs/docs/reference/typescript-api/job-queue/job-queue-options.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## JobQueueOptions
 
-<GenerationInfo sourceFile="packages/core/src/config/vendure-config.ts" sourceLine="891" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/config/vendure-config.ts" sourceLine="903" packageName="@vendure/core" />
 
 Options related to the built-in job queue.
 

+ 13 - 1
docs/docs/reference/typescript-api/job-queue/polling-job-queue-strategy.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## PollingJobQueueStrategy
 
-<GenerationInfo sourceFile="packages/core/src/job-queue/polling-job-queue-strategy.ts" sourceLine="192" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/job-queue/polling-job-queue-strategy.ts" sourceLine="242" packageName="@vendure/core" />
 
 This class allows easier implementation of <a href='/reference/typescript-api/job-queue/job-queue-strategy#jobqueuestrategy'>JobQueueStrategy</a> in a polling style.
 Instead of providing <a href='/reference/typescript-api/job-queue/job-queue-strategy#jobqueuestrategy'>JobQueueStrategy</a> `start()` you should provide a `next` method.
@@ -25,6 +25,8 @@ class PollingJobQueueStrategy extends InjectableJobQueueStrategy {
     public pollInterval: number | ((queueName: string) => number);
     public setRetries: (queueName: string, job: Job) => number;
     public backOffStrategy?: BackoffStrategy;
+    public gracefulShutdownTimeout: number;
+    protected activeQueues = new QueueNameProcessStorage<ActiveQueue<any>>();
     constructor(config?: PollingJobQueueStrategyConfig)
     constructor(concurrency?: number, pollInterval?: number)
     constructor(concurrencyOrConfig?: number | PollingJobQueueStrategyConfig, maybePollInterval?: number)
@@ -62,6 +64,16 @@ class PollingJobQueueStrategy extends InjectableJobQueueStrategy {
 <MemberInfo kind="property" type={`<a href='/reference/typescript-api/job-queue/types#backoffstrategy'>BackoffStrategy</a>`}   />
 
 
+### gracefulShutdownTimeout
+
+<MemberInfo kind="property" type={`number`}   />
+
+
+### activeQueues
+
+<MemberInfo kind="property" type={``}   />
+
+
 ### constructor
 
 <MemberInfo kind="method" type={`(config?: PollingJobQueueStrategyConfig) => PollingJobQueueStrategy`}   />

+ 1 - 1
docs/docs/reference/typescript-api/orders/order-options.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## OrderOptions
 
-<GenerationInfo sourceFile="packages/core/src/config/vendure-config.ts" sourceLine="479" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/config/vendure-config.ts" sourceLine="481" packageName="@vendure/core" />
 
 
 

+ 1 - 1
docs/docs/reference/typescript-api/payment/payment-options.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## PaymentOptions
 
-<GenerationInfo sourceFile="packages/core/src/config/vendure-config.ts" sourceLine="812" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/config/vendure-config.ts" sourceLine="824" packageName="@vendure/core" />
 
 Defines payment-related options in the <a href='/reference/typescript-api/configuration/vendure-config#vendureconfig'>VendureConfig</a>.
 

+ 9 - 1
docs/docs/reference/typescript-api/products-stock/catalog-options.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## CatalogOptions
 
-<GenerationInfo sourceFile="packages/core/src/config/vendure-config.ts" sourceLine="671" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/config/vendure-config.ts" sourceLine="673" packageName="@vendure/core" />
 
 Options related to products and collections.
 
@@ -20,6 +20,7 @@ interface CatalogOptions {
     collectionFilters?: Array<CollectionFilter<any>>;
     productVariantPriceSelectionStrategy?: ProductVariantPriceSelectionStrategy;
     productVariantPriceCalculationStrategy?: ProductVariantPriceCalculationStrategy;
+    productVariantPriceUpdateStrategy?: ProductVariantPriceUpdateStrategy;
     stockDisplayStrategy?: StockDisplayStrategy;
     stockLocationStrategy?: StockLocationStrategy;
 }
@@ -44,6 +45,13 @@ such as the active Channel and active CurrencyCode.
 
 Defines the strategy used for calculating the price of ProductVariants based
 on the Channel settings and active tax Zone.
+### productVariantPriceUpdateStrategy
+
+<MemberInfo kind="property" type={`<a href='/reference/typescript-api/configuration/product-variant-price-update-strategy#productvariantpriceupdatestrategy'>ProductVariantPriceUpdateStrategy</a>`} default="<a href='/reference/typescript-api/configuration/product-variant-price-update-strategy#defaultproductvariantpriceupdatestrategy'>DefaultProductVariantPriceUpdateStrategy</a>"  since="2.2.0"  />
+
+Defines the strategy which determines what happens to a ProductVariant's prices
+when one of the prices gets updated. For instance, this can be used to synchronize
+prices across multiple Channels.
 ### stockDisplayStrategy
 
 <MemberInfo kind="property" type={`<a href='/reference/typescript-api/products-stock/stock-display-strategy#stockdisplaystrategy'>StockDisplayStrategy</a>`} default="<a href='/reference/typescript-api/products-stock/default-stock-display-strategy#defaultstockdisplaystrategy'>DefaultStockDisplayStrategy</a>"   />

+ 1 - 1
docs/docs/reference/typescript-api/promotions/promotion-options.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## PromotionOptions
 
-<GenerationInfo sourceFile="packages/core/src/config/vendure-config.ts" sourceLine="723" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/config/vendure-config.ts" sourceLine="735" packageName="@vendure/core" />
 
 
 

+ 9 - 3
docs/docs/reference/typescript-api/service-helpers/order-modifier.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## OrderModifier
 
-<GenerationInfo sourceFile="packages/core/src/service/helpers/order-modifier/order-modifier.ts" sourceLine="80" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/service/helpers/order-modifier/order-modifier.ts" sourceLine="81" packageName="@vendure/core" />
 
 This helper is responsible for modifying the contents of an Order.
 
@@ -24,13 +24,14 @@ of these Order-related methods into a more clearly-delineated set of classes.
 
 ```ts title="Signature"
 class OrderModifier {
-    constructor(connection: TransactionalConnection, configService: ConfigService, orderCalculator: OrderCalculator, paymentService: PaymentService, countryService: CountryService, stockMovementService: StockMovementService, productVariantService: ProductVariantService, customFieldRelationService: CustomFieldRelationService, promotionService: PromotionService, eventBus: EventBus, entityHydrator: EntityHydrator, historyService: HistoryService, translator: TranslatorService)
+    constructor(connection: TransactionalConnection, configService: ConfigService, orderCalculator: OrderCalculator, paymentService: PaymentService, countryService: CountryService, stockMovementService: StockMovementService, productVariantService: ProductVariantService, customFieldRelationService: CustomFieldRelationService, promotionService: PromotionService, eventBus: EventBus, shippingCalculator: ShippingCalculator, historyService: HistoryService, translator: TranslatorService)
     constrainQuantityToSaleable(ctx: RequestContext, variant: ProductVariant, quantity: number, existingQuantity:  = 0) => ;
     getExistingOrderLine(ctx: RequestContext, order: Order, productVariantId: ID, customFields?: { [key: string]: any }) => Promise<OrderLine | undefined>;
     getOrCreateOrderLine(ctx: RequestContext, order: Order, productVariantId: ID, customFields?: { [key: string]: any }) => ;
     updateOrderLineQuantity(ctx: RequestContext, orderLine: OrderLine, quantity: number, order: Order) => Promise<OrderLine>;
     cancelOrderByOrderLines(ctx: RequestContext, input: CancelOrderInput, lineInputs: OrderLineInput[]) => ;
     modifyOrder(ctx: RequestContext, input: ModifyOrderInput, order: Order) => Promise<JustErrorResults<ModifyOrderResult> | { order: Order; modification: OrderModification }>;
+    setShippingMethods(ctx: RequestContext, order: Order, shippingMethodIds: ID[]) => ;
 }
 ```
 
@@ -38,7 +39,7 @@ class OrderModifier {
 
 ### constructor
 
-<MemberInfo kind="method" type={`(connection: <a href='/reference/typescript-api/data-access/transactional-connection#transactionalconnection'>TransactionalConnection</a>, configService: ConfigService, orderCalculator: <a href='/reference/typescript-api/service-helpers/order-calculator#ordercalculator'>OrderCalculator</a>, paymentService: <a href='/reference/typescript-api/services/payment-service#paymentservice'>PaymentService</a>, countryService: <a href='/reference/typescript-api/services/country-service#countryservice'>CountryService</a>, stockMovementService: <a href='/reference/typescript-api/services/stock-movement-service#stockmovementservice'>StockMovementService</a>, productVariantService: <a href='/reference/typescript-api/services/product-variant-service#productvariantservice'>ProductVariantService</a>, customFieldRelationService: CustomFieldRelationService, promotionService: <a href='/reference/typescript-api/services/promotion-service#promotionservice'>PromotionService</a>, eventBus: <a href='/reference/typescript-api/events/event-bus#eventbus'>EventBus</a>, entityHydrator: <a href='/reference/typescript-api/data-access/entity-hydrator#entityhydrator'>EntityHydrator</a>, historyService: <a href='/reference/typescript-api/services/history-service#historyservice'>HistoryService</a>, translator: <a href='/reference/typescript-api/service-helpers/translator-service#translatorservice'>TranslatorService</a>) => OrderModifier`}   />
+<MemberInfo kind="method" type={`(connection: <a href='/reference/typescript-api/data-access/transactional-connection#transactionalconnection'>TransactionalConnection</a>, configService: ConfigService, orderCalculator: <a href='/reference/typescript-api/service-helpers/order-calculator#ordercalculator'>OrderCalculator</a>, paymentService: <a href='/reference/typescript-api/services/payment-service#paymentservice'>PaymentService</a>, countryService: <a href='/reference/typescript-api/services/country-service#countryservice'>CountryService</a>, stockMovementService: <a href='/reference/typescript-api/services/stock-movement-service#stockmovementservice'>StockMovementService</a>, productVariantService: <a href='/reference/typescript-api/services/product-variant-service#productvariantservice'>ProductVariantService</a>, customFieldRelationService: CustomFieldRelationService, promotionService: <a href='/reference/typescript-api/services/promotion-service#promotionservice'>PromotionService</a>, eventBus: <a href='/reference/typescript-api/events/event-bus#eventbus'>EventBus</a>, shippingCalculator: <a href='/reference/typescript-api/shipping/shipping-calculator#shippingcalculator'>ShippingCalculator</a>, historyService: <a href='/reference/typescript-api/services/history-service#historyservice'>HistoryService</a>, translator: <a href='/reference/typescript-api/service-helpers/translator-service#translatorservice'>TranslatorService</a>) => OrderModifier`}   />
 
 
 ### constrainQuantityToSaleable
@@ -76,6 +77,11 @@ Returns the actual quantity that the OrderLine was updated to (which may be less
 <MemberInfo kind="method" type={`(ctx: <a href='/reference/typescript-api/request/request-context#requestcontext'>RequestContext</a>, input: ModifyOrderInput, order: <a href='/reference/typescript-api/entities/order#order'>Order</a>) => Promise&#60;JustErrorResults&#60;ModifyOrderResult&#62; | { order: <a href='/reference/typescript-api/entities/order#order'>Order</a>; modification: <a href='/reference/typescript-api/entities/order-modification#ordermodification'>OrderModification</a> }&#62;`}   />
 
 
+### setShippingMethods
+
+<MemberInfo kind="method" type={`(ctx: <a href='/reference/typescript-api/request/request-context#requestcontext'>RequestContext</a>, order: <a href='/reference/typescript-api/entities/order#order'>Order</a>, shippingMethodIds: <a href='/reference/typescript-api/common/id#id'>ID</a>[]) => `}   />
+
+
 
 
 </div>

+ 1 - 1
docs/docs/reference/typescript-api/services/collection-service.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## CollectionService
 
-<GenerationInfo sourceFile="packages/core/src/service/services/collection.service.ts" sourceLine="66" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/service/services/collection.service.ts" sourceLine="67" packageName="@vendure/core" />
 
 Contains methods relating to <a href='/reference/typescript-api/entities/collection#collection'>Collection</a> entities.
 

+ 1 - 1
docs/docs/reference/typescript-api/services/history-service.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## HistoryService
 
-<GenerationInfo sourceFile="packages/core/src/service/services/history.service.ts" sourceLine="241" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/service/services/history.service.ts" sourceLine="248" packageName="@vendure/core" />
 
 Contains methods relating to <a href='/reference/typescript-api/entities/history-entry#historyentry'>HistoryEntry</a> entities. Histories are timelines of actions
 related to a particular Customer or Order, recording significant events such as creation, state changes,

Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 4 - 3
docs/docs/reference/typescript-api/services/order-service.md


+ 3 - 3
docs/docs/reference/typescript-api/services/payment-service.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## PaymentService
 
-<GenerationInfo sourceFile="packages/core/src/service/services/payment.service.ts" sourceLine="42" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/service/services/payment.service.ts" sourceLine="43" packageName="@vendure/core" />
 
 Contains methods relating to <a href='/reference/typescript-api/entities/payment#payment'>Payment</a> entities.
 
@@ -26,7 +26,7 @@ class PaymentService {
     settlePayment(ctx: RequestContext, paymentId: ID) => Promise<PaymentStateTransitionError | Payment>;
     cancelPayment(ctx: RequestContext, paymentId: ID) => Promise<PaymentStateTransitionError | Payment>;
     createManualPayment(ctx: RequestContext, order: Order, amount: number, input: ManualPaymentInput) => ;
-    createRefund(ctx: RequestContext, input: RefundOrderInput, order: Order, selectedPayment: Payment) => Promise<Refund | RefundStateTransitionError>;
+    createRefund(ctx: RequestContext, input: RefundOrderInput, order: Order, selectedPayment: Payment) => Promise<Refund | RefundStateTransitionError | RefundAmountError>;
 }
 ```
 
@@ -95,7 +95,7 @@ preferable to use the <a href='/reference/typescript-api/services/order-service#
 updating the Order state too.
 ### createRefund
 
-<MemberInfo kind="method" type={`(ctx: <a href='/reference/typescript-api/request/request-context#requestcontext'>RequestContext</a>, input: RefundOrderInput, order: <a href='/reference/typescript-api/entities/order#order'>Order</a>, selectedPayment: <a href='/reference/typescript-api/entities/payment#payment'>Payment</a>) => Promise&#60;Refund | RefundStateTransitionError&#62;`}   />
+<MemberInfo kind="method" type={`(ctx: <a href='/reference/typescript-api/request/request-context#requestcontext'>RequestContext</a>, input: RefundOrderInput, order: <a href='/reference/typescript-api/entities/order#order'>Order</a>, selectedPayment: <a href='/reference/typescript-api/entities/payment#payment'>Payment</a>) => Promise&#60;Refund | RefundStateTransitionError | RefundAmountError&#62;`}   />
 
 Creates a Refund against the specified Payment. If the amount to be refunded exceeds the value of the
 specified Payment (in the case of multiple payments on a single Order), then the remaining outstanding

+ 6 - 0
docs/docs/reference/typescript-api/services/product-variant-service.md

@@ -35,6 +35,7 @@ class ProductVariantService {
     create(ctx: RequestContext, input: CreateProductVariantInput[]) => Promise<Array<Translated<ProductVariant>>>;
     update(ctx: RequestContext, input: UpdateProductVariantInput[]) => Promise<Array<Translated<ProductVariant>>>;
     createOrUpdateProductVariantPrice(ctx: RequestContext, productVariantId: ID, price: number, channelId: ID, currencyCode?: CurrencyCode) => Promise<ProductVariantPrice>;
+    deleteProductVariantPrice(ctx: RequestContext, variantId: ID, channelId: ID, currencyCode: CurrencyCode) => ;
     softDelete(ctx: RequestContext, id: ID | ID[]) => Promise<DeletionResponse>;
     hydratePriceFields(ctx: RequestContext, variant: ProductVariant, priceField: F) => Promise<ProductVariant[F]>;
     applyChannelPriceAndTax(variant: ProductVariant, ctx: RequestContext, order?: Order) => Promise<ProductVariant>;
@@ -142,6 +143,11 @@ for those variants which are tracking inventory.
 
 Creates a <a href='/reference/typescript-api/entities/product-variant-price#productvariantprice'>ProductVariantPrice</a> for the given ProductVariant/Channel combination.
 If the `currencyCode` is not specified, the default currency of the Channel will be used.
+### deleteProductVariantPrice
+
+<MemberInfo kind="method" type={`(ctx: <a href='/reference/typescript-api/request/request-context#requestcontext'>RequestContext</a>, variantId: <a href='/reference/typescript-api/common/id#id'>ID</a>, channelId: <a href='/reference/typescript-api/common/id#id'>ID</a>, currencyCode: <a href='/reference/typescript-api/common/currency-code#currencycode'>CurrencyCode</a>) => `}   />
+
+
 ### softDelete
 
 <MemberInfo kind="method" type={`(ctx: <a href='/reference/typescript-api/request/request-context#requestcontext'>RequestContext</a>, id: <a href='/reference/typescript-api/common/id#id'>ID</a> | <a href='/reference/typescript-api/common/id#id'>ID</a>[]) => Promise&#60;DeletionResponse&#62;`}   />

+ 1 - 1
docs/docs/reference/typescript-api/shipping/shipping-options.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## ShippingOptions
 
-<GenerationInfo sourceFile="packages/core/src/config/vendure-config.ts" sourceLine="739" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/config/vendure-config.ts" sourceLine="751" packageName="@vendure/core" />
 
 
 

+ 1 - 1
docs/docs/reference/typescript-api/tax/tax-options.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## TaxOptions
 
-<GenerationInfo sourceFile="packages/core/src/config/vendure-config.ts" sourceLine="844" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/config/vendure-config.ts" sourceLine="856" packageName="@vendure/core" />
 
 
 

+ 3 - 1
packages/core/src/config/catalog/default-product-variant-price-update-strategy.ts

@@ -33,15 +33,17 @@ export interface DefaultProductVariantPriceUpdateStrategyOptions {
  * case, a custom strategy should be implemented.
  *
  * @example
- * ```TypeScript
+ * ```ts
  * import { DefaultProductVariantPriceUpdateStrategy, VendureConfig } from '\@vendure/core';
  *
  * export const config: VendureConfig = {
  *   // ...
  *   catalogOptions: {
+ *     // highlight-start
  *     productVariantPriceUpdateStrategy: new DefaultProductVariantPriceUpdateStrategy({
  *       syncPricesAcrossChannels: true,
  *     }),
+ *     // highlight-end
  *   },
  *   // ...
  * };

+ 10 - 0
packages/core/src/config/catalog/product-variant-price-update-strategy.ts

@@ -33,6 +33,16 @@ export interface UpdatedProductVariantPrice {
  * For instance, in a multichannel setup, if a price is updated for a ProductVariant in one
  * Channel, this strategy can be used to update the prices in other Channels.
  *
+ * Using custom logic, this can be made more sophisticated - for example, you could have a
+ * one-way sync that only updates prices in child channels when the price in the default
+ * channel is updated. You could also have a conditional sync which is dependent on the
+ * permissions of the current administrator, or based on custom field flags on the ProductVariant
+ * or Channel.
+ *
+ * Another use-case might be to update the prices of a ProductVariant in other currencies
+ * when a price is updated in one currency, based on the current exchange rate.
+ *
+ *
  * :::info
  *
  * This is configured via the `catalogOptions.productVariantPriceUpdateStrategy` property of

+ 5 - 0
packages/dev-server/example-plugins/multivendor-plugin/multivendor.plugin.ts

@@ -3,6 +3,7 @@ import {
     Channel,
     ChannelService,
     configureDefaultOrderProcess,
+    DefaultProductVariantPriceUpdateStrategy,
     LanguageCode,
     PaymentMethod,
     PaymentMethodService,
@@ -141,6 +142,10 @@ import { MultivendorPluginOptions } from './types';
         });
         config.orderOptions.process = [customDefaultOrderProcess, multivendorOrderProcess];
         config.orderOptions.orderSellerStrategy = new MultivendorSellerStrategy();
+        config.catalogOptions.productVariantPriceUpdateStrategy =
+            new DefaultProductVariantPriceUpdateStrategy({
+                syncPricesAcrossChannels: true,
+            });
         config.shippingOptions.shippingEligibilityCheckers.push(multivendorShippingEligibilityChecker);
         config.shippingOptions.shippingLineAssignmentStrategy =
             new MultivendorShippingLineAssignmentStrategy();

Některé soubory nejsou zobrazeny, neboť je v těchto rozdílových datech změněno mnoho souborů