Browse Source

docs: Generate TS docs

Michael Bromley 1 year ago
parent
commit
58dc9fd3fd
55 changed files with 745 additions and 318 deletions
  1. 92 0
      docs/docs/reference/admin-ui-api/alerts/alert-config.md
  2. 56 0
      docs/docs/reference/admin-ui-api/alerts/alert-context.md
  3. 14 0
      docs/docs/reference/admin-ui-api/alerts/index.md
  4. 27 0
      docs/docs/reference/admin-ui-api/alerts/register-alert.md
  5. 2 2
      docs/docs/reference/admin-ui-api/components/data-table-component.md
  6. 1 1
      docs/docs/reference/admin-ui-api/routes/register-route-component-options.md
  7. 2 2
      docs/docs/reference/admin-ui-api/services/modal-service.md
  8. 82 44
      docs/docs/reference/admin-ui-api/ui-devkit/admin-ui-extension.md
  9. 1 1
      docs/docs/reference/admin-ui-api/ui-devkit/ui-extension-compiler-options.md
  10. 1 1
      docs/docs/reference/admin-ui-api/ui-devkit/ui-extension-compiler-process-argument.md
  11. 11 1
      docs/docs/reference/core-plugins/asset-server-plugin/index.md
  12. 115 129
      docs/docs/reference/core-plugins/elasticsearch-plugin/elasticsearch-options.md
  13. 21 31
      docs/docs/reference/core-plugins/payments-plugin/mollie-plugin.md
  14. 1 1
      docs/docs/reference/typescript-api/common/currency-code.md
  15. 1 1
      docs/docs/reference/typescript-api/common/job-state.md
  16. 1 1
      docs/docs/reference/typescript-api/common/language-code.md
  17. 1 1
      docs/docs/reference/typescript-api/common/permission.md
  18. 1 1
      docs/docs/reference/typescript-api/custom-fields/custom-field-config.md
  19. 1 1
      docs/docs/reference/typescript-api/custom-fields/index.md
  20. 3 3
      docs/docs/reference/typescript-api/data-access/entity-hydrator.md
  21. 9 3
      docs/docs/reference/typescript-api/data-access/list-query-builder.md
  22. 22 1
      docs/docs/reference/typescript-api/entities/asset.md
  23. 36 1
      docs/docs/reference/typescript-api/entities/channel.md
  24. 2 2
      docs/docs/reference/typescript-api/entities/collection.md
  25. 16 2
      docs/docs/reference/typescript-api/entities/facet-value.md
  26. 8 1
      docs/docs/reference/typescript-api/entities/fulfillment.md
  27. 3 3
      docs/docs/reference/typescript-api/entities/order.md
  28. 1 1
      docs/docs/reference/typescript-api/entities/product-option-group.md
  29. 8 1
      docs/docs/reference/typescript-api/entities/product-option.md
  30. 5 5
      docs/docs/reference/typescript-api/entities/product-variant.md
  31. 8 8
      docs/docs/reference/typescript-api/entities/product.md
  32. 7 0
      docs/docs/reference/typescript-api/entities/promotion.md
  33. 8 1
      docs/docs/reference/typescript-api/entities/tax-category.md
  34. 61 0
      docs/docs/reference/typescript-api/events/blocking-event-handler-options.md
  35. 41 3
      docs/docs/reference/typescript-api/events/event-bus.md
  36. 1 1
      docs/docs/reference/typescript-api/events/event-types.md
  37. 1 1
      docs/docs/reference/typescript-api/fulfillment/fulfillment-process.md
  38. 1 1
      docs/docs/reference/typescript-api/import-export/asset-importer.md
  39. 1 1
      docs/docs/reference/typescript-api/import-export/fast-importer-service.md
  40. 1 1
      docs/docs/reference/typescript-api/orders/guest-checkout-strategy.md
  41. 1 1
      docs/docs/reference/typescript-api/orders/order-process.md
  42. 2 2
      docs/docs/reference/typescript-api/orders/order-seller-strategy.md
  43. 1 1
      docs/docs/reference/typescript-api/products-stock/default-stock-location-strategy.md
  44. 1 1
      docs/docs/reference/typescript-api/request/relations-decorator.md
  45. 10 2
      docs/docs/reference/typescript-api/service-helpers/order-modifier.md
  46. 6 3
      docs/docs/reference/typescript-api/service-helpers/product-price-applicator.md
  47. 25 25
      docs/docs/reference/typescript-api/services/customer-service.md
  48. 11 11
      docs/docs/reference/typescript-api/services/fulfillment-service.md
  49. 1 1
      docs/docs/reference/typescript-api/services/order-service.md
  50. 6 6
      docs/docs/reference/typescript-api/services/payment-method-service.md
  51. 2 2
      docs/docs/reference/typescript-api/services/product-option-group-service.md
  52. 2 2
      docs/docs/reference/typescript-api/services/product-variant-service.md
  53. 1 1
      docs/docs/reference/typescript-api/services/stock-level-service.md
  54. 1 1
      docs/docs/reference/typescript-api/services/stock-movement-service.md
  55. 1 1
      docs/docs/reference/typescript-api/services/tax-category-service.md

+ 92 - 0
docs/docs/reference/admin-ui-api/alerts/alert-config.md

@@ -0,0 +1,92 @@
+---
+title: "AlertConfig"
+isDefaultIndex: false
+generated: true
+---
+<!-- This file was generated from the Vendure source. Do not modify. Instead, re-run the "docs:build" script -->
+import MemberInfo from '@site/src/components/MemberInfo';
+import GenerationInfo from '@site/src/components/GenerationInfo';
+import MemberDescription from '@site/src/components/MemberDescription';
+
+
+## AlertConfig
+
+<GenerationInfo sourceFile="packages/admin-ui/src/lib/core/src/providers/alerts/alerts.service.ts" sourceLine="62" packageName="@vendure/admin-ui" since="2.2.0" />
+
+A configuration object for an Admin UI alert.
+
+```ts title="Signature"
+interface AlertConfig<T = any> {
+    id: string;
+    check: (context: AlertContext) => T | Promise<T> | Observable<T>;
+    recheck?: (context: AlertContext) => Observable<any>;
+    isAlert: (data: T, context: AlertContext) => boolean;
+    action: (data: T, context: AlertContext) => void;
+    label: (
+        data: T,
+        context: AlertContext,
+    ) => { text: string; translationVars?: { [key: string]: string | number } };
+    requiredPermissions?: Permission[];
+}
+```
+
+<div className="members-wrapper">
+
+### id
+
+<MemberInfo kind="property" type={`string`}   />
+
+A unique identifier for the alert.
+### check
+
+<MemberInfo kind="property" type={`(context: <a href='/reference/admin-ui-api/alerts/alert-context#alertcontext'>AlertContext</a>) =&#62; T | Promise&#60;T&#62; | Observable&#60;T&#62;`}   />
+
+A function which is gets the data used to determine whether the alert should be shown.
+Typically, this function will query the server or some other remote data source.
+
+This function will be called once when the Admin UI app bootstraps, and can be also
+set to run at regular intervals by setting the `recheckIntervalMs` property.
+### recheck
+
+<MemberInfo kind="property" type={`(context: <a href='/reference/admin-ui-api/alerts/alert-context#alertcontext'>AlertContext</a>) =&#62; Observable&#60;any&#62;`} default="undefined"   />
+
+A function which returns an Observable which is used to determine when to re-run the `check`
+function. Whenever the observable emits, the `check` function will be called again.
+
+A basic time-interval-based recheck can be achieved by using the `interval` function from RxJS.
+
+*Example*
+
+```ts
+import { interval } from 'rxjs';
+
+// ...
+recheck: () => interval(60_000)
+```
+
+If this is not set, the `check` function will only be called once when the Admin UI app bootstraps.
+### isAlert
+
+<MemberInfo kind="property" type={`(data: T, context: <a href='/reference/admin-ui-api/alerts/alert-context#alertcontext'>AlertContext</a>) =&#62; boolean`}   />
+
+A function which determines whether the alert should be shown based on the data returned by the `check`
+function.
+### action
+
+<MemberInfo kind="property" type={`(data: T, context: <a href='/reference/admin-ui-api/alerts/alert-context#alertcontext'>AlertContext</a>) =&#62; void`}   />
+
+A function which is called when the alert is clicked in the Admin UI.
+### label
+
+<MemberInfo kind="property" type={`(         data: T,         context: <a href='/reference/admin-ui-api/alerts/alert-context#alertcontext'>AlertContext</a>,     ) =&#62; { text: string; translationVars?: { [key: string]: string | number } }`}   />
+
+A function which returns the text used in the UI to describe the alert.
+### requiredPermissions
+
+<MemberInfo kind="property" type={`<a href='/reference/typescript-api/common/permission#permission'>Permission</a>[]`}   />
+
+A list of permissions which the current Administrator must have in order. If the current
+Administrator does not have these permissions, none of the other alert functions will be called.
+
+
+</div>

+ 56 - 0
docs/docs/reference/admin-ui-api/alerts/alert-context.md

@@ -0,0 +1,56 @@
+---
+title: "AlertContext"
+isDefaultIndex: false
+generated: true
+---
+<!-- This file was generated from the Vendure source. Do not modify. Instead, re-run the "docs:build" script -->
+import MemberInfo from '@site/src/components/MemberInfo';
+import GenerationInfo from '@site/src/components/GenerationInfo';
+import MemberDescription from '@site/src/components/MemberDescription';
+
+
+## AlertContext
+
+<GenerationInfo sourceFile="packages/admin-ui/src/lib/core/src/providers/alerts/alerts.service.ts" sourceLine="28" packageName="@vendure/admin-ui" since="2.2.0" />
+
+The context object which is passed to the `check`, `isAlert`, `label` and `action` functions of an
+<a href='/reference/admin-ui-api/alerts/alert-config#alertconfig'>AlertConfig</a> object.
+
+```ts title="Signature"
+interface AlertContext {
+    injector: Injector;
+    dataService: DataService;
+    notificationService: NotificationService;
+    modalService: ModalService;
+}
+```
+
+<div className="members-wrapper">
+
+### injector
+
+<MemberInfo kind="property" type={`<a href='/reference/typescript-api/common/injector#injector'>Injector</a>`}   />
+
+The Angular [Injector](https://angular.dev/api/core/Injector) which can be used to get instances
+of services and other providers available in the application.
+### dataService
+
+<MemberInfo kind="property" type={`<a href='/reference/admin-ui-api/services/data-service#dataservice'>DataService</a>`}   />
+
+The [DataService](/reference/admin-ui-api/services/data-service), which provides methods for querying the
+server-side data.
+### notificationService
+
+<MemberInfo kind="property" type={`<a href='/reference/admin-ui-api/services/notification-service#notificationservice'>NotificationService</a>`}   />
+
+The [NotificationService](/reference/admin-ui-api/services/notification-service), which provides methods for
+displaying notifications to the user.
+### modalService
+
+<MemberInfo kind="property" type={`<a href='/reference/admin-ui-api/services/modal-service#modalservice'>ModalService</a>`}   />
+
+The [ModalService](/reference/admin-ui-api/services/modal-service), which provides methods for
+opening modal dialogs.
+
+
+</div>

+ 14 - 0
docs/docs/reference/admin-ui-api/alerts/index.md

@@ -0,0 +1,14 @@
+---
+title: "Alerts"
+isDefaultIndex: true
+generated: true
+---
+<!-- This file was generated from the Vendure source. Do not modify. Instead, re-run the "docs:build" script -->
+import MemberInfo from '@site/src/components/MemberInfo';
+import GenerationInfo from '@site/src/components/GenerationInfo';
+import MemberDescription from '@site/src/components/MemberDescription';
+
+
+import DocCardList from '@theme/DocCardList';
+
+<DocCardList />

+ 27 - 0
docs/docs/reference/admin-ui-api/alerts/register-alert.md

@@ -0,0 +1,27 @@
+---
+title: "RegisterAlert"
+isDefaultIndex: false
+generated: true
+---
+<!-- This file was generated from the Vendure source. Do not modify. Instead, re-run the "docs:build" script -->
+import MemberInfo from '@site/src/components/MemberInfo';
+import GenerationInfo from '@site/src/components/GenerationInfo';
+import MemberDescription from '@site/src/components/MemberDescription';
+
+
+## registerAlert
+
+<GenerationInfo sourceFile="packages/admin-ui/src/lib/core/src/extension/register-alert.ts" sourceLine="12" packageName="@vendure/admin-ui" since="2.2.0" />
+
+Registers an alert which can be displayed in the Admin UI alert dropdown in the top bar.
+The alert is configured using the <a href='/reference/admin-ui-api/alerts/alert-config#alertconfig'>AlertConfig</a> object.
+
+```ts title="Signature"
+function registerAlert(config: AlertConfig): FactoryProvider
+```
+Parameters
+
+### config
+
+<MemberInfo kind="parameter" type={`<a href='/reference/admin-ui-api/alerts/alert-config#alertconfig'>AlertConfig</a>`} />
+

+ 2 - 2
docs/docs/reference/admin-ui-api/components/data-table-component.md

@@ -82,7 +82,7 @@ class DataTableComponent<T> implements AfterContentInit, OnChanges, OnInit, OnDe
     @Output() pageChange = new EventEmitter<number>();
     @Output() itemsPerPageChange = new EventEmitter<number>();
     @Input() allSelected: boolean;
-    @Input() isRowSelectedFn: (item: T) => boolean;
+    @Input() isRowSelectedFn: ((item: T) => boolean) | undefined;
     @Output() allSelectChange = new EventEmitter<void>();
     @Output() rowSelectChange = new EventEmitter<{ event: MouseEvent; item: T }>();
     @ContentChildren(DataTableColumnComponent) columns: QueryList<DataTableColumnComponent>;
@@ -154,7 +154,7 @@ class DataTableComponent<T> implements AfterContentInit, OnChanges, OnInit, OnDe
 
 ### isRowSelectedFn
 
-<MemberInfo kind="property" type={`(item: T) =&#62; boolean`}   />
+<MemberInfo kind="property" type={`((item: T) =&#62; boolean) | undefined`}   />
 
 
 ### allSelectChange

+ 1 - 1
docs/docs/reference/admin-ui-api/routes/register-route-component-options.md

@@ -23,7 +23,7 @@ type RegisterRouteComponentOptions<Component extends any | BaseDetailComponent<E
     path?: string;
     query?: T;
     getBreadcrumbs?: (entity: Exclude<ResultOf<T>[R], 'Query'>) => BreadcrumbValue;
-    entityKey?: Component extends BaseDetailComponent<any> ? R : undefined;
+    entityKey?: Component extends BaseDetailComponent<any> ? R : string;
     variables?: T extends TypedDocumentNode<any, infer V> ? Omit<V, 'id'> : never;
     routeConfig?: Route;
 } & (Component extends BaseDetailComponent<any> ? { entityKey: R } : unknown)

+ 2 - 2
docs/docs/reference/admin-ui-api/services/modal-service.md

@@ -41,7 +41,7 @@ displayed in the modal dialog. See example:
 
 *Example*
 
-```HTML
+```ts
 class MyDialog implements Dialog {
  resolveWith: (result?: any) => void;
 
@@ -59,7 +59,7 @@ class MyDialog implements Dialog {
 
 *Example*
 
-```HTML
+```html
 <ng-template vdrDialogTitle>Title of the modal</ng-template>
 
 <p>

+ 82 - 44
docs/docs/reference/admin-ui-api/ui-devkit/admin-ui-extension.md

@@ -11,27 +11,24 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## AdminUiExtension
 
-<GenerationInfo sourceFile="packages/ui-devkit/src/compiler/types.ts" sourceLine="98" packageName="@vendure/ui-devkit" />
+<GenerationInfo sourceFile="packages/ui-devkit/src/compiler/types.ts" sourceLine="130" packageName="@vendure/ui-devkit" />
 
-Defines extensions to the Admin UI application by specifying additional
-Angular [NgModules](https://angular.io/guide/ngmodules) which are compiled
-into the application.
-
-See [Extending the Admin UI](/guides/extending-the-admin-ui/getting-started/) for
+Defines extensions to the Admin UI application by specifying additional
+Angular [NgModules](https://angular.io/guide/ngmodules) which are compiled
+into the application.
+
+See [Extending the Admin UI](/guides/extending-the-admin-ui/getting-started/) for
 detailed instructions.
 
 ```ts title="Signature"
-interface AdminUiExtension extends Partial<TranslationExtension>,
-        Partial<StaticAssetExtension>,
+interface AdminUiExtension extends Partial<TranslationExtension>,
+        Partial<StaticAssetExtension>,
         Partial<GlobalStylesExtension> {
     id?: string;
     extensionPath: string;
     ngModules?: Array<AdminUiExtensionSharedModule | AdminUiExtensionLazyModule>;
     providers?: string[];
-    routes?: Array<{
-        route: string;
-        filePath: string;
-    }>;
+    routes?: UiExtensionRouteDefinition[];
     pathAlias?: string;
     exclude?: string[];
 }
@@ -46,14 +43,14 @@ interface AdminUiExtension extends Partial<TranslationExtension>,
 
 <MemberInfo kind="property" type={`string`}   />
 
-An optional ID for the extension module. Only used internally for generating
+An optional ID for the extension module. Only used internally for generating
 import paths to your module. If not specified, a unique hash will be used as the id.
 ### extensionPath
 
 <MemberInfo kind="property" type={`string`}   />
 
-The path to the directory containing the extension module(s). The entire contents of this directory
-will be copied into the Admin UI app, including all TypeScript source files, html templates,
+The path to the directory containing the extension module(s). The entire contents of this directory
+will be copied into the Admin UI app, including all TypeScript source files, html templates,
 scss style sheets etc.
 ### ngModules
 
@@ -64,27 +61,27 @@ One or more Angular modules which extend the default Admin UI.
 
 <MemberInfo kind="property" type={`string[]`}   />
 
-Defines the paths to a file that exports an array of shared providers such as nav menu items, custom form inputs,
+Defines the paths to a file that exports an array of shared providers such as nav menu items, custom form inputs,
 custom detail components, action bar items, custom history entry components.
 ### routes
 
-<MemberInfo kind="property" type={`Array&#60;{
         route: string;
         filePath: string;
     }&#62;`}   />
+<MemberInfo kind="property" type={`<a href='/reference/admin-ui-api/ui-devkit/admin-ui-extension#uiextensionroutedefinition'>UiExtensionRouteDefinition</a>[]`}   />
 
-Defines routes that will be lazy-loaded at the `/extensions/` route. The filePath should point to a file
+Defines routes that will be lazy-loaded at the `/extensions/` route. The filePath should point to a file
 relative to the `extensionPath` which exports an array of Angular route definitions.
 ### pathAlias
 
 <MemberInfo kind="property" type={`string`}   />
 
-An optional alias for the module so it can be referenced by other UI extension modules.
-
-By default, Angular modules declared in an AdminUiExtension do not have access to code outside the directory
-defined by the `extensionPath`. A scenario in which that can be useful though is in a monorepo codebase where
-a common NgModule is shared across different plugins, each defined in its own package. An example can be found
-below - note that the main `tsconfig.json` also maps the target module but using a path relative to the project's
-root folder. The UI module is not part of the main TypeScript build task as explained in
-[Extending the Admin UI](https://www.vendure.io/docs/plugins/extending-the-admin-ui/) but having `paths`
-properly configured helps with usual IDE code editing features such as code completion and quick navigation, as
+An optional alias for the module so it can be referenced by other UI extension modules.
+
+By default, Angular modules declared in an AdminUiExtension do not have access to code outside the directory
+defined by the `extensionPath`. A scenario in which that can be useful though is in a monorepo codebase where
+a common NgModule is shared across different plugins, each defined in its own package. An example can be found
+below - note that the main `tsconfig.json` also maps the target module but using a path relative to the project's
+root folder. The UI module is not part of the main TypeScript build task as explained in
+[Extending the Admin UI](https://www.vendure.io/docs/plugins/extending-the-admin-ui/) but having `paths`
+properly configured helps with usual IDE code editing features such as code completion and quick navigation, as
 well as linting.
 
 *Example*
@@ -163,7 +160,7 @@ export class SampleUiExtensionModule {}
 
 <MemberInfo kind="property" type={`string[]`}   />
 
-Optional array specifying filenames or [glob](https://github.com/isaacs/node-glob) patterns that should
+Optional array specifying filenames or [glob](https://github.com/isaacs/node-glob) patterns that should
 be skipped when copying the directory defined by `extensionPath`.
 
 *Example*
@@ -180,7 +177,7 @@ exclude: ['**/*.spec.ts']
 
 <GenerationInfo sourceFile="packages/ui-devkit/src/compiler/types.ts" sourceLine="18" packageName="@vendure/ui-devkit" />
 
-Defines extensions to the Admin UI translations. Can be used as a stand-alone extension definition which only adds translations
+Defines extensions to the Admin UI translations. Can be used as a stand-alone extension definition which only adds translations
 without adding new UI functionality, or as part of a full <a href='/reference/admin-ui-api/ui-devkit/admin-ui-extension#adminuiextension'>AdminUiExtension</a>.
 
 ```ts title="Signature"
@@ -195,9 +192,9 @@ interface TranslationExtension {
 
 <MemberInfo kind="property" type={`{ [languageCode in <a href='/reference/typescript-api/common/language-code#languagecode'>LanguageCode</a>]?: string }`}   />
 
-Optional object defining any translation files for the Admin UI. The value should be an object with
-the key as a 2-character [ISO 639-1 language code](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes),
-and the value being a [glob](https://github.com/isaacs/node-glob) for any relevant
+Optional object defining any translation files for the Admin UI. The value should be an object with
+the key as a 2-character [ISO 639-1 language code](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes),
+and the value being a [glob](https://github.com/isaacs/node-glob) for any relevant
 translation files in JSON format.
 
 *Example*
@@ -231,7 +228,7 @@ interface StaticAssetExtension {
 
 <MemberInfo kind="property" type={`<a href='/reference/admin-ui-api/ui-devkit/admin-ui-extension#staticassetdefinition'>StaticAssetDefinition</a>[]`}   />
 
-Optional array of paths to static assets which will be copied over to the Admin UI app's `/static`
+Optional array of paths to static assets which will be copied over to the Admin UI app's `/static`
 directory.
 
 
@@ -256,7 +253,7 @@ interface GlobalStylesExtension {
 
 <MemberInfo kind="property" type={`string[] | string`}   />
 
-Specifies a path (or array of paths) to global style files (css or Sass) which will be
+Specifies a path (or array of paths) to global style files (css or Sass) which will be
 incorporated into the Admin UI app global stylesheet.
 
 
@@ -281,18 +278,59 @@ interface SassVariableOverridesExtension {
 
 <MemberInfo kind="property" type={`string`}   />
 
-Specifies a path to a Sass style file containing variable declarations, which will take precedence over
+Specifies a path to a Sass style file containing variable declarations, which will take precedence over
 default values defined in Clarity.
 
 
 </div>
 
 
+## UiExtensionRouteDefinition
+
+<GenerationInfo sourceFile="packages/ui-devkit/src/compiler/types.ts" sourceLine="92" packageName="@vendure/ui-devkit" />
+
+Defines a route which will be added to the Admin UI application.
+
+```ts title="Signature"
+interface UiExtensionRouteDefinition {
+    route: string;
+    filePath: string;
+    prefix?: string;
+}
+```
+
+<div className="members-wrapper">
+
+### route
+
+<MemberInfo kind="property" type={`string`}   />
+
+The name of the route. This will be used as the path in the URL.
+### filePath
+
+<MemberInfo kind="property" type={`string`}   />
+
+The path to the file which exports an array of Angular route definitions.
+### prefix
+
+<MemberInfo kind="property" type={`string`}  since="2.2.0"  />
+
+All extensions will be mounted under the `/extensions/` route. This option allows you to specify a
+custom prefix rather than `/extensions/`. For example, setting this to `custom` would cause the extension
+to be mounted at `/custom/<route>` instead.
+
+A common use case for this is to mount the extension at the root of the Admin UI, by setting this to an empty string.
+This is useful when the extension is intended to replace the default Admin UI, rather than extend it.
+
+
+</div>
+
+
 ## StaticAssetDefinition
 
-<GenerationInfo sourceFile="packages/ui-devkit/src/compiler/types.ts" sourceLine="251" packageName="@vendure/ui-devkit" />
+<GenerationInfo sourceFile="packages/ui-devkit/src/compiler/types.ts" sourceLine="280" packageName="@vendure/ui-devkit" />
 
-A static asset can be provided as a path to the asset, or as an object containing a path and a new
+A static asset can be provided as a path to the asset, or as an object containing a path and a new
 name, which will cause the compiler to copy and then rename the asset.
 
 ```ts title="Signature"
@@ -302,7 +340,7 @@ type StaticAssetDefinition = string | { path: string; rename: string }
 
 ## AdminUiExtensionSharedModule
 
-<GenerationInfo sourceFile="packages/ui-devkit/src/compiler/types.ts" sourceLine="260" packageName="@vendure/ui-devkit" />
+<GenerationInfo sourceFile="packages/ui-devkit/src/compiler/types.ts" sourceLine="289" packageName="@vendure/ui-devkit" />
 
 Configuration defining a single NgModule with which to extend the Admin UI.
 
@@ -320,8 +358,8 @@ interface AdminUiExtensionSharedModule {
 
 <MemberInfo kind="property" type={`'shared'`}   />
 
-Shared modules are directly imported into the main AppModule of the Admin UI
-and should be used to declare custom form components and define custom
+Shared modules are directly imported into the main AppModule of the Admin UI
+and should be used to declare custom form components and define custom
 navigation items.
 ### ngModuleFileName
 
@@ -340,7 +378,7 @@ The name of the extension module class.
 
 ## AdminUiExtensionLazyModule
 
-<GenerationInfo sourceFile="packages/ui-devkit/src/compiler/types.ts" sourceLine="287" packageName="@vendure/ui-devkit" />
+<GenerationInfo sourceFile="packages/ui-devkit/src/compiler/types.ts" sourceLine="316" packageName="@vendure/ui-devkit" />
 
 Configuration defining a single NgModule with which to extend the Admin UI.
 
@@ -359,14 +397,14 @@ interface AdminUiExtensionLazyModule {
 
 <MemberInfo kind="property" type={`'lazy'`}   />
 
-Lazy modules are lazy-loaded at the `/extensions/` route and should be used for
+Lazy modules are lazy-loaded at the `/extensions/` route and should be used for
 modules which define new views for the Admin UI.
 ### route
 
 <MemberInfo kind="property" type={`string`}   />
 
-The route specifies the route at which the module will be lazy-loaded. E.g. a value
-of `'foo'` will cause the module to lazy-load when the `/extensions/foo` route
+The route specifies the route at which the module will be lazy-loaded. E.g. a value
+of `'foo'` will cause the module to lazy-load when the `/extensions/foo` route
 is activated.
 ### ngModuleFileName
 

+ 1 - 1
docs/docs/reference/admin-ui-api/ui-devkit/ui-extension-compiler-options.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## UiExtensionCompilerOptions
 
-<GenerationInfo sourceFile="packages/ui-devkit/src/compiler/types.ts" sourceLine="327" packageName="@vendure/ui-devkit" />
+<GenerationInfo sourceFile="packages/ui-devkit/src/compiler/types.ts" sourceLine="356" packageName="@vendure/ui-devkit" />
 
 Options to configure how the Admin UI should be compiled.
 

+ 1 - 1
docs/docs/reference/admin-ui-api/ui-devkit/ui-extension-compiler-process-argument.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## UiExtensionCompilerProcessArgument
 
-<GenerationInfo sourceFile="packages/ui-devkit/src/compiler/types.ts" sourceLine="319" packageName="@vendure/ui-devkit" />
+<GenerationInfo sourceFile="packages/ui-devkit/src/compiler/types.ts" sourceLine="348" packageName="@vendure/ui-devkit" />
 
 Argument to configure process (watch or compile)
 

+ 11 - 1
docs/docs/reference/core-plugins/asset-server-plugin/index.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## AssetServerPlugin
 
-<GenerationInfo sourceFile="packages/asset-server-plugin/src/plugin.ts" sourceLine="139" packageName="@vendure/asset-server-plugin" />
+<GenerationInfo sourceFile="packages/asset-server-plugin/src/plugin.ts" sourceLine="153" packageName="@vendure/asset-server-plugin" />
 
 The `AssetServerPlugin` serves assets (images and other files) from the local file system, and can also be configured to use
 other storage strategies (e.g. <a href='/reference/core-plugins/asset-server-plugin/s3asset-storage-strategy#s3assetstoragestrategy'>S3AssetStorageStrategy</a>. It can also perform on-the-fly image transformations
@@ -85,6 +85,16 @@ supports them. Supported values for `format` are:
 
 The `format` parameter can also be combined with presets (see below).
 
+### Quality
+
+Since v2.2.0, the image quality can be specified by adding the `q` query parameter:
+
+`http://localhost:3000/assets/some-asset.jpg?q=75`
+
+This applies to the `jpg`, `webp` and `avif` formats. The default quality value for `jpg` and `webp` is 80, and for `avif` is 50.
+
+The `q` parameter can also be combined with presets (see below).
+
 ### Transform presets
 
 Presets can be defined which allow a single preset name to be used instead of specifying the width, height and mode. Presets are

+ 115 - 129
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="29" 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>.
 
@@ -24,23 +24,23 @@ interface ElasticsearchOptions {
     clientOptions?: ClientOptions;
     indexPrefix?: string;
     indexSettings?: object;
-    indexMappingProperties?: {
-        [indexName: string]: object;
+    indexMappingProperties?: {
+        [indexName: string]: object;
     };
     reindexProductsChunkSize?: number;
     reindexBulkOperationSizeLimit?: number;
     searchConfig?: SearchConfig;
-    customProductMappings?: {
-        [fieldName: string]: CustomMapping<[Product, ProductVariant[], LanguageCode, Injector, RequestContext]>;
+    customProductMappings?: {
+        [fieldName: string]: CustomMapping<[Product, ProductVariant[], LanguageCode, Injector, RequestContext]>;
     };
-    customProductVariantMappings?: {
-        [fieldName: string]: CustomMapping<[ProductVariant, LanguageCode, Injector, RequestContext]>;
+    customProductVariantMappings?: {
+        [fieldName: string]: CustomMapping<[ProductVariant, LanguageCode, Injector, RequestContext]>;
     };
     bufferUpdates?: boolean;
     hydrateProductRelations?: Array<EntityRelationPaths<Product>>;
     hydrateProductVariantRelations?: Array<EntityRelationPaths<ProductVariant>>;
-    extendSearchInputType?: {
-        [name: string]: PrimitiveTypeVariations<GraphQlPrimitive>;
+    extendSearchInputType?: {
+        [name: string]: PrimitiveTypeVariations<GraphQlPrimitive>;
     };
     extendSearchSortType?: string[];
 }
@@ -72,9 +72,9 @@ Interval in milliseconds between attempts to connect to the ElasticSearch server
 
 <MemberInfo kind="property" type={`ClientOptions`}   />
 
-Options to pass directly to the
-[Elasticsearch Node.js client](https://www.elastic.co/guide/en/elasticsearch/client/javascript-api/current/index.html). For example, to
-set authentication or other more advanced options.
+Options to pass directly to the
+[Elasticsearch Node.js client](https://www.elastic.co/guide/en/elasticsearch/client/javascript-api/current/index.html). For example, to
+set authentication or other more advanced options.
 Note that if the `node` or `nodes` option is specified, it will override the values provided in the `host` and `port` options.
 ### indexPrefix
 
@@ -85,7 +85,7 @@ Prefix for the indices created by the plugin.
 
 <MemberInfo kind="property" type={`object`} default="{}"  since="1.2.0"  />
 
-[These options](https://www.elastic.co/guide/en/elasticsearch/reference/7.x/index-modules.html#index-modules-settings)
+[These options](https://www.elastic.co/guide/en/elasticsearch/reference/7.x/index-modules.html#index-modules-settings)
 are directly passed to index settings. To apply some settings indices will be recreated.
 
 *Example*
@@ -116,12 +116,10 @@ A more complete example can be found in the discussion thread
 [How to make elastic plugin to search by substring with stemming](https://github.com/vendure-ecommerce/vendure/discussions/1066).
 ### indexMappingProperties
 
-<MemberInfo kind="property" type={`{
-         [indexName: string]: object;
-     }`} default="{}"  since="1.2.0"  />
+<MemberInfo kind="property" type={`{
         [indexName: string]: object;
     }`} default="{}"  since="1.2.0"  />
 
-This option allow to redefine or define new properties in mapping. More about elastic
-[mapping](https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping.html)
+This option allow to redefine or define new properties in mapping. More about elastic
+[mapping](https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping.html)
 After changing this option indices will be recreated.
 
 *Example*
@@ -169,8 +167,8 @@ Products limit chunk size for each loop iteration when indexing products.
 
 <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
+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
 
@@ -179,23 +177,21 @@ bulk operation is executed.
 Configuration of the internal Elasticsearch query.
 ### customProductMappings
 
-<MemberInfo kind="property" type={`{
-         [fieldName: string]: CustomMapping&#60;[<a href='/reference/typescript-api/entities/product#product'>Product</a>, <a href='/reference/typescript-api/entities/product-variant#productvariant'>ProductVariant</a>[], <a href='/reference/typescript-api/common/language-code#languagecode'>LanguageCode</a>, <a href='/reference/typescript-api/common/injector#injector'>Injector</a>, <a href='/reference/typescript-api/request/request-context#requestcontext'>RequestContext</a>]&#62;;
-     }`}   />
-
-Custom mappings may be defined which will add the defined data to the
-Elasticsearch index and expose that data via the SearchResult GraphQL type,
-adding a new `customMappings`, `customProductMappings` & `customProductVariantMappings` fields.
-
-The `graphQlType` property may be one of `String`, `Int`, `Float`, `Boolean`, `ID` or list
-versions thereof (`[String!]` etc) and can be appended with a `!` to indicate non-nullable fields.
-
-The `public` (default = `true`) property is used to reveal or hide the property in the GraphQL API schema.
-If this property is set to `false` it's not accessible in the `customMappings` field but it's still getting
-parsed to the elasticsearch index.
-
-This config option defines custom mappings which are accessible when the "groupByProduct"
-input options is set to `true`. In addition, custom variant mappings can be accessed by using
+<MemberInfo kind="property" type={`{
         [fieldName: string]: CustomMapping&#60;[<a href='/reference/typescript-api/entities/product#product'>Product</a>, <a href='/reference/typescript-api/entities/product-variant#productvariant'>ProductVariant</a>[], <a href='/reference/typescript-api/common/language-code#languagecode'>LanguageCode</a>, <a href='/reference/typescript-api/common/injector#injector'>Injector</a>, <a href='/reference/typescript-api/request/request-context#requestcontext'>RequestContext</a>]&#62;;
     }`}   />
+
+Custom mappings may be defined which will add the defined data to the
+Elasticsearch index and expose that data via the SearchResult GraphQL type,
+adding a new `customMappings`, `customProductMappings` & `customProductVariantMappings` fields.
+
+The `graphQlType` property may be one of `String`, `Int`, `Float`, `Boolean`, `ID` or list
+versions thereof (`[String!]` etc) and can be appended with a `!` to indicate non-nullable fields.
+
+The `public` (default = `true`) property is used to reveal or hide the property in the GraphQL API schema.
+If this property is set to `false` it's not accessible in the `customMappings` field but it's still getting
+parsed to the elasticsearch index.
+
+This config option defines custom mappings which are accessible when the "groupByProduct"
+input options is set to `true`. In addition, custom variant mappings can be accessed by using
 the `customProductVariantMappings` field, which is always available.
 
 *Example*
@@ -244,12 +240,10 @@ query SearchProducts($input: SearchInput!) {
 ```
 ### customProductVariantMappings
 
-<MemberInfo kind="property" type={`{
-         [fieldName: string]: CustomMapping&#60;[<a href='/reference/typescript-api/entities/product-variant#productvariant'>ProductVariant</a>, <a href='/reference/typescript-api/common/language-code#languagecode'>LanguageCode</a>, <a href='/reference/typescript-api/common/injector#injector'>Injector</a>, <a href='/reference/typescript-api/request/request-context#requestcontext'>RequestContext</a>]&#62;;
-     }`}   />
+<MemberInfo kind="property" type={`{
         [fieldName: string]: CustomMapping&#60;[<a href='/reference/typescript-api/entities/product-variant#productvariant'>ProductVariant</a>, <a href='/reference/typescript-api/common/language-code#languagecode'>LanguageCode</a>, <a href='/reference/typescript-api/common/injector#injector'>Injector</a>, <a href='/reference/typescript-api/request/request-context#requestcontext'>RequestContext</a>]&#62;;
     }`}   />
 
-This config option defines custom mappings which are accessible when the "groupByProduct"
-input options is set to `false`. In addition, custom product mappings can be accessed by using
+This config option defines custom mappings which are accessible when the "groupByProduct"
+input options is set to `false`. In addition, custom product mappings can be accessed by using
 the `customProductMappings` field, which is always available.
 
 *Example*
@@ -277,20 +271,20 @@ query SearchProducts($input: SearchInput!) {
 
 <MemberInfo kind="property" type={`boolean`} default="false"  since="1.3.0"  />
 
-If set to `true`, updates to Products, ProductVariants and Collections will not immediately
-trigger an update to the search index. Instead, all these changes will be buffered and will
-only be run via a call to the `runPendingSearchIndexUpdates` mutation in the Admin API.
-
-This is very useful for installations with a large number of ProductVariants and/or
-Collections, as the buffering allows better control over when these expensive jobs are run,
-and also performs optimizations to minimize the amount of work that needs to be performed by
+If set to `true`, updates to Products, ProductVariants and Collections will not immediately
+trigger an update to the search index. Instead, all these changes will be buffered and will
+only be run via a call to the `runPendingSearchIndexUpdates` mutation in the Admin API.
+
+This is very useful for installations with a large number of ProductVariants and/or
+Collections, as the buffering allows better control over when these expensive jobs are run,
+and also performs optimizations to minimize the amount of work that needs to be performed by
 the worker.
 ### hydrateProductRelations
 
 <MemberInfo kind="property" type={`Array&#60;<a href='/reference/typescript-api/common/entity-relation-paths#entityrelationpaths'>EntityRelationPaths</a>&#60;<a href='/reference/typescript-api/entities/product#product'>Product</a>&#62;&#62;`} default="[]"  since="1.3.0"  />
 
-Additional product relations that will be fetched from DB while reindexing. This can be used
-in combination with `customProductMappings` to ensure that the required relations are joined
+Additional product relations that will be fetched from DB while reindexing. This can be used
+in combination with `customProductMappings` to ensure that the required relations are joined
 before the `product` object is passed to the `valueFn`.
 
 *Example*
@@ -312,16 +306,14 @@ before the `product` object is passed to the `valueFn`.
 
 <MemberInfo kind="property" type={`Array&#60;<a href='/reference/typescript-api/common/entity-relation-paths#entityrelationpaths'>EntityRelationPaths</a>&#60;<a href='/reference/typescript-api/entities/product-variant#productvariant'>ProductVariant</a>&#62;&#62;`} default="[]"  since="1.3.0"  />
 
-Additional variant relations that will be fetched from DB while reindexing. See
+Additional variant relations that will be fetched from DB while reindexing. See
 `hydrateProductRelations` for more explanation and a usage example.
 ### extendSearchInputType
 
-<MemberInfo kind="property" type={`{
-         [name: string]: PrimitiveTypeVariations&#60;GraphQlPrimitive&#62;;
-     }`} default="{}"  since="1.3.0"  />
+<MemberInfo kind="property" type={`{
         [name: string]: PrimitiveTypeVariations&#60;GraphQlPrimitive&#62;;
     }`} default="{}"  since="1.3.0"  />
 
-Allows the `SearchInput` type to be extended with new input fields. This allows arbitrary
-data to be passed in, which can then be used e.g. in the `mapQuery()` function or
+Allows the `SearchInput` type to be extended with new input fields. This allows arbitrary
+data to be passed in, which can then be used e.g. in the `mapQuery()` function or
 custom `scriptFields` functions.
 
 *Example*
@@ -355,7 +347,7 @@ query {
 
 <MemberInfo kind="property" type={`string[]`} default="[]"  since="1.4.0"  />
 
-Adds a list of sort parameters. This is mostly important to make the
+Adds a list of sort parameters. This is mostly important to make the
 correct sort order values available inside `input` parameter of the `mapSort` option.
 
 *Example*
@@ -392,12 +384,12 @@ interface SearchConfig {
     multiMatchType?: 'best_fields' | 'most_fields' | 'cross_fields' | 'phrase' | 'phrase_prefix' | 'bool_prefix';
     boostFields?: BoostFieldsConfig;
     priceRangeBucketInterval?: number;
-    mapQuery?: (
-        query: any,
-        input: ElasticSearchInput,
-        searchConfig: DeepRequired<SearchConfig>,
-        channelId: ID,
-        enabledOnly: boolean,
+    mapQuery?: (
+        query: any,
+        input: ElasticSearchInput,
+        searchConfig: DeepRequired<SearchConfig>,
+        channelId: ID,
+        enabledOnly: boolean,
     ) => any;
     scriptFields?: { [fieldName: string]: CustomScriptMapping<[ElasticSearchInput]> };
     mapSort?: (sort: ElasticSearchSortInput, input: ElasticSearchInput) => ElasticSearchSortInput;
@@ -410,29 +402,29 @@ interface SearchConfig {
 
 <MemberInfo kind="property" type={`number`} default="50"   />
 
-The maximum number of FacetValues to return from the search query. Internally, this
+The maximum number of FacetValues to return from the search query. Internally, this
 value sets the "size" property of an Elasticsearch aggregation.
 ### collectionMaxSize
 
 <MemberInfo kind="property" type={`number`} default="50"  since="1.1.0"  />
 
-The maximum number of Collections to return from the search query. Internally, this
+The maximum number of Collections to return from the search query. Internally, this
 value sets the "size" property of an Elasticsearch aggregation.
 ### totalItemsMaxSize
 
 <MemberInfo kind="property" type={`number | boolean`} default="10000"  since="1.2.0"  />
 
-The maximum number of totalItems to return from the search query. Internally, this
-value sets the "track_total_hits" property of an Elasticsearch query.
-If this parameter is set to "True", accurate count of totalItems will be returned.
-If this parameter is set to "False", totalItems will be returned as 0.
+The maximum number of totalItems to return from the search query. Internally, this
+value sets the "track_total_hits" property of an Elasticsearch query.
+If this parameter is set to "True", accurate count of totalItems will be returned.
+If this parameter is set to "False", totalItems will be returned as 0.
 If this parameter is set to integer, accurate count of totalItems will be returned not bigger than integer.
 ### multiMatchType
 
 <MemberInfo kind="property" type={`'best_fields' | 'most_fields' | 'cross_fields' | 'phrase' | 'phrase_prefix' | 'bool_prefix'`} default="'best_fields'"   />
 
-Defines the
-[multi match type](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-multi-match-query.html#multi-match-types)
+Defines the
+[multi match type](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-multi-match-query.html#multi-match-types)
 used when matching against a search term.
 ### boostFields
 
@@ -443,49 +435,43 @@ Set custom boost values for particular fields when matching against a search ter
 
 <MemberInfo kind="property" type={`number`}   />
 
-The interval used to group search results into buckets according to price range. For example, setting this to
-`2000` will group into buckets every $20.00:
-
-```json
-{
-  "data": {
-    "search": {
-      "totalItems": 32,
-      "priceRange": {
-        "buckets": [
-          {
-            "to": 2000,
-            "count": 21
-          },
-          {
-            "to": 4000,
-            "count": 7
-          },
-          {
-            "to": 6000,
-            "count": 3
-          },
-          {
-            "to": 12000,
-            "count": 1
-          }
-        ]
-      }
-    }
-  }
-}
+The interval used to group search results into buckets according to price range. For example, setting this to
+`2000` will group into buckets every $20.00:
+
+```json
+{
+  "data": {
+    "search": {
+      "totalItems": 32,
+      "priceRange": {
+        "buckets": [
+          {
+            "to": 2000,
+            "count": 21
+          },
+          {
+            "to": 4000,
+            "count": 7
+          },
+          {
+            "to": 6000,
+            "count": 3
+          },
+          {
+            "to": 12000,
+            "count": 1
+          }
+        ]
+      }
+    }
+  }
+}
 ```
 ### mapQuery
 
-<MemberInfo kind="property" type={`(
-         query: any,
-         input: ElasticSearchInput,
-         searchConfig: DeepRequired&#60;<a href='/reference/core-plugins/elasticsearch-plugin/elasticsearch-options#searchconfig'>SearchConfig</a>&#62;,
-         channelId: <a href='/reference/typescript-api/common/id#id'>ID</a>,
-         enabledOnly: boolean,
-     ) =&#62; any`}   />
+<MemberInfo kind="property" type={`(
         query: any,
         input: ElasticSearchInput,
         searchConfig: DeepRequired&#60;<a href='/reference/core-plugins/elasticsearch-plugin/elasticsearch-options#searchconfig'>SearchConfig</a>&#62;,
         channelId: <a href='/reference/typescript-api/common/id#id'>ID</a>,
         enabledOnly: boolean,
     ) =&#62; any`}   />
 
-This config option allows the the modification of the whole (already built) search query. This allows
+This config option allows the the modification of the whole (already built) search query. This allows
 for e.g. wildcard / fuzzy searches on the index.
 
 *Example*
@@ -524,17 +510,17 @@ mapQuery: (query, input, searchConfig, channelId, enabledOnly){
 
 <MemberInfo kind="property" type={`{ [fieldName: string]: CustomScriptMapping&#60;[ElasticSearchInput]&#62; }`}  since="1.3.0"  />
 
-Sets `script_fields` inside the elasticsearch body which allows returning a script evaluation for each hit.
-
-The script field definition consists of three properties:
-
-* `graphQlType`: This is the type that will be returned when this script field is queried
-via the GraphQL API. It may be one of `String`, `Int`, `Float`, `Boolean`, `ID` or list
-versions thereof (`[String!]` etc) and can be appended with a `!` to indicate non-nullable fields.
-* `context`: determines whether this script field is available when grouping by product. Can be
-`product`, `variant` or `both`.
-* `scriptFn`: This is the function to run on each hit. Should return an object with a `script` property,
-as covered in the
+Sets `script_fields` inside the elasticsearch body which allows returning a script evaluation for each hit.
+
+The script field definition consists of three properties:
+
+* `graphQlType`: This is the type that will be returned when this script field is queried
+via the GraphQL API. It may be one of `String`, `Int`, `Float`, `Boolean`, `ID` or list
+versions thereof (`[String!]` etc) and can be appended with a `!` to indicate non-nullable fields.
+* `context`: determines whether this script field is available when grouping by product. Can be
+`product`, `variant` or `both`.
+* `scriptFn`: This is the function to run on each hit. Should return an object with a `script` property,
+as covered in the
 [Elasticsearch script fields docs](https://www.elastic.co/guide/en/elasticsearch/reference/7.15/search-fields.html#script-fields)
 
 *Example*
@@ -585,10 +571,10 @@ searchConfig: {
 
 <MemberInfo kind="property" type={`(sort: ElasticSearchSortInput, input: ElasticSearchInput) =&#62; ElasticSearchSortInput`} default="{}"  since="1.4.0"  />
 
-Allows extending the `sort` input of the elasticsearch body as covered in
-[Elasticsearch sort docs](https://www.elastic.co/guide/en/elasticsearch/reference/current/sort-search-results.html)
-
-The `sort` input parameter contains the ElasticSearchSortInput generated for the default sort parameters "name" and "price".
+Allows extending the `sort` input of the elasticsearch body as covered in
+[Elasticsearch sort docs](https://www.elastic.co/guide/en/elasticsearch/reference/current/sort-search-results.html)
+
+The `sort` input parameter contains the ElasticSearchSortInput generated for the default sort parameters "name" and "price".
 If neither of those are applied it will be empty.
 
 *Example*
@@ -669,9 +655,9 @@ searchConfig: {
 
 <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.
-
+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.
+
 Boosting a field acts as a score multiplier for matches against that field.
 
 ```ts title="Signature"

+ 21 - 31
docs/docs/reference/core-plugins/payments-plugin/mollie-plugin.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## MolliePlugin
 
-<GenerationInfo sourceFile="packages/payments-plugin/src/mollie/mollie.plugin.ts" sourceLine="203" packageName="@vendure/payments-plugin" />
+<GenerationInfo sourceFile="packages/payments-plugin/src/mollie/mollie.plugin.ts" sourceLine="192" 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.
@@ -36,34 +36,25 @@ This plugin uses the Order API from Mollie, not the Payments API.
     // ...
 
     plugins: [
-      MolliePlugin.init({ vendureHost: 'https://yourhost.io/', useDynamicRedirectUrl: true }),
+      MolliePlugin.init({ vendureHost: 'https://yourhost.io/' }),
     ]
     ```
-2. Create a new PaymentMethod in the Admin UI, and select "Mollie payments" as the handler.
-3. Set your Mollie apiKey in the `API Key` field.
+2. Run a database migration to add the `mollieOrderId` custom field to the order entity.
+3. Create a new PaymentMethod in the Admin UI, and select "Mollie payments" as the handler.
+4. Set your Mollie apiKey in the `API Key` field.
+5. 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.
 
-## Specifying the redirectUrl
-
-Currently, there are two ways to specify the `redirectUrl` to which the customer is redirected after completing the payment:
-1. Configure the `redirectUrl` in the PaymentMethod.
-2. Pass the `redirectUrl` as an argument to the `createPaymentIntent` mutation.
-
-Which method is used depends on the value of the `useDynamicRedirectUrl` option while initializing the plugin.
-By default, this option is set to `false` for backwards compatibility. In a future version, this option will be deprecated.
-Upon deprecation, the `redirectUrl` will always be passed as an argument to the `createPaymentIntent` mutation.
-
-TODO toevoegen van /code weggehaald..!
 ## 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. When using the first method specified in `Specifying the redirectUrl`,
-the order code is appened to the `redirectUrl`. For the second method, the order code is not appended to the specified `redirectUrl`.
+back to your storefront after completing the payment.
 
 ```GraphQL
 mutation CreateMolliePaymentIntent {
   createMolliePaymentIntent(input: {
-    redirectUrl: "https://storefront/order"
+    redirectUrl: "https://storefront/order/1234XYZ"
     paymentMethodCode: "mollie-payment-method"
     molliePaymentMethodCode: "ideal"
   }) {
@@ -107,10 +98,10 @@ You can get available Mollie payment methods with the following query:
  }
 }
 ```
-You can pass `MolliePaymentMethod.code` to the `createMolliePaymentIntent` mutation to skip the method selection.
+You can pass `creditcard` for example, to the `createMolliePaymentIntent` mutation to skip the method selection.
 
 After completing payment on the Mollie platform,
-the user is redirected to the configured redirect url + orderCode: `https://storefront/order/CH234X5`
+the user is redirected to the given redirect url, e.g. `https://storefront/order/CH234X5`
 
 ## Pay later methods
 Mollie supports pay-later methods like 'Klarna Pay Later'. For pay-later methods, the status of an order is
@@ -118,7 +109,15 @@ Mollie supports pay-later methods like 'Klarna Pay Later'. For pay-later methods
 Make sure you capture a payment within 28 days, because this is the Klarna expiry time
 
 If you don't want this behaviour (Authorized first), you can set 'autoCapture=true' on the payment method. This option will immediately
-capture the payment after a customer authorizes the payment.
+capture the payment after a customer authorizes the payment.
+
+## ArrangingAdditionalPayment state
+
+In some rare cases, a customer can add items to the active order, while a Mollie payment 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.
 
 ```ts title="Signature"
 class MolliePlugin {
@@ -146,14 +145,13 @@ Initialize the mollie payment plugin
 
 ## MolliePluginOptions
 
-<GenerationInfo sourceFile="packages/payments-plugin/src/mollie/mollie.plugin.ts" sourceLine="27" packageName="@vendure/payments-plugin" />
+<GenerationInfo sourceFile="packages/payments-plugin/src/mollie/mollie.plugin.ts" sourceLine="29" packageName="@vendure/payments-plugin" />
 
 Configuration options for the Mollie payments plugin.
 
 ```ts title="Signature"
 interface MolliePluginOptions {
     vendureHost: string;
-    useDynamicRedirectUrl?: boolean;
     enabledPaymentMethodsParams?: (
         injector: Injector,
         ctx: RequestContext,
@@ -170,14 +168,6 @@ interface MolliePluginOptions {
 
 The host of your Vendure server, e.g. `'https://my-vendure.io'`.
 This is used by Mollie to send webhook events to the Vendure server
-### useDynamicRedirectUrl
-
-<MemberInfo kind="property" type={`boolean`} default="false"  since="2.0.0"  />
-
-For backwards compatibility, by default set to false.
-This option will be deprecated in a future version.
-When enabled, the `redirectUrl` can be passed via the `createPaymentIntent` mutation
-instead of being configured in the Payment Method.
 ### enabledPaymentMethodsParams
 
 <MemberInfo kind="property" type={`(
         injector: <a href='/reference/typescript-api/common/injector#injector'>Injector</a>,
         ctx: <a href='/reference/typescript-api/request/request-context#requestcontext'>RequestContext</a>,
         order: <a href='/reference/typescript-api/entities/order#order'>Order</a> | null,
     ) =&#62; AdditionalEnabledPaymentMethodsParams | Promise&#60;AdditionalEnabledPaymentMethodsParams&#62;`}  since="2.2.0"  />

+ 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="969" packageName="@vendure/common" />
+<GenerationInfo sourceFile="packages/common/src/generated-types.ts" sourceLine="982" 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="2161" packageName="@vendure/common" />
+<GenerationInfo sourceFile="packages/common/src/generated-types.ts" sourceLine="2174" 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="2179" packageName="@vendure/common" />
+<GenerationInfo sourceFile="packages/common/src/generated-types.ts" sourceLine="2192" 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="4313" packageName="@vendure/common" />
+<GenerationInfo sourceFile="packages/common/src/generated-types.ts" sourceLine="4326" 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/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="126" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/config/custom-field/custom-field-types.ts" sourceLine="124" packageName="@vendure/core" />
 
 An object used to configure a custom field.
 

+ 1 - 1
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="161" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/config/custom-field/custom-field-types.ts" sourceLine="159" 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.

+ 3 - 3
docs/docs/reference/typescript-api/data-access/entity-hydrator.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## EntityHydrator
 
-<GenerationInfo sourceFile="packages/core/src/service/helpers/entity-hydrator/entity-hydrator.service.ts" sourceLine="75" packageName="@vendure/core" since="1.3.0" />
+<GenerationInfo sourceFile="packages/core/src/service/helpers/entity-hydrator/entity-hydrator.service.ts" sourceLine="77" packageName="@vendure/core" since="1.3.0" />
 
 This is a helper class which is used to "hydrate" entity instances, which means to populate them
 with the specified relations. This is useful when writing plugin code which receives an entity,
@@ -71,7 +71,7 @@ await this.entityHydrator
 
 ```ts title="Signature"
 class EntityHydrator {
-    constructor(connection: TransactionalConnection, productPriceApplicator: ProductPriceApplicator, translator: TranslatorService)
+    constructor(connection: TransactionalConnection, productPriceApplicator: ProductPriceApplicator, translator: TranslatorService, listQueryBuilder: ListQueryBuilder)
     hydrate(ctx: RequestContext, target: Entity, options: HydrateOptions<Entity>) => Promise<Entity>;
 }
 ```
@@ -80,7 +80,7 @@ class EntityHydrator {
 
 ### constructor
 
-<MemberInfo kind="method" type={`(connection: <a href='/reference/typescript-api/data-access/transactional-connection#transactionalconnection'>TransactionalConnection</a>, productPriceApplicator: <a href='/reference/typescript-api/service-helpers/product-price-applicator#productpriceapplicator'>ProductPriceApplicator</a>, translator: <a href='/reference/typescript-api/service-helpers/translator-service#translatorservice'>TranslatorService</a>) => EntityHydrator`}   />
+<MemberInfo kind="method" type={`(connection: <a href='/reference/typescript-api/data-access/transactional-connection#transactionalconnection'>TransactionalConnection</a>, productPriceApplicator: <a href='/reference/typescript-api/service-helpers/product-price-applicator#productpriceapplicator'>ProductPriceApplicator</a>, translator: <a href='/reference/typescript-api/service-helpers/translator-service#translatorservice'>TranslatorService</a>, listQueryBuilder: <a href='/reference/typescript-api/data-access/list-query-builder#listquerybuilder'>ListQueryBuilder</a>) => EntityHydrator`}   />
 
 
 ### hydrate

+ 9 - 3
docs/docs/reference/typescript-api/data-access/list-query-builder.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## ListQueryBuilder
 
-<GenerationInfo sourceFile="packages/core/src/service/helpers/list-query-builder/list-query-builder.ts" sourceLine="205" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/service/helpers/list-query-builder/list-query-builder.ts" sourceLine="201" packageName="@vendure/core" />
 
 This helper class is used when fetching entities the database from queries which return a <a href='/reference/typescript-api/common/paginated-list#paginatedlist'>PaginatedList</a> type.
 These queries all follow the same format:
@@ -84,6 +84,7 @@ class ListQueryBuilder implements OnApplicationBootstrap {
     constructor(connection: TransactionalConnection, configService: ConfigService)
     filterObjectHasProperty(filterObject: FP | NullOptionals<FP> | null | undefined, property: keyof FP) => boolean;
     build(entity: Type<T>, options: ListQueryOptions<T> = {}, extendedOptions: ExtendedListQueryOptions<T> = {}) => SelectQueryBuilder<T>;
+    joinTreeRelationsDynamically(qb: SelectQueryBuilder<T>, entity: EntityTarget<T>, requestedRelations: string[] = []) => Set<string>;
 }
 ```
 * Implements: <code>OnApplicationBootstrap</code>
@@ -113,7 +114,12 @@ to join that relation.
 
 <MemberInfo kind="method" type={`(entity: Type&#60;T&#62;, options: ListQueryOptions&#60;T&#62; = {}, extendedOptions: <a href='/reference/typescript-api/data-access/list-query-builder#extendedlistqueryoptions'>ExtendedListQueryOptions</a>&#60;T&#62; = {}) => SelectQueryBuilder&#60;T&#62;`}   />
 
-Creates and configures a SelectQueryBuilder for queries that return paginated lists of entities.
+
+### joinTreeRelationsDynamically
+
+<MemberInfo kind="method" type={`(qb: SelectQueryBuilder&#60;T&#62;, entity: EntityTarget&#60;T&#62;, requestedRelations: string[] = []) => Set&#60;string&#62;`}   />
+
+
 
 
 </div>
@@ -121,7 +127,7 @@ Creates and configures a SelectQueryBuilder for queries that return paginated li
 
 ## ExtendedListQueryOptions
 
-<GenerationInfo sourceFile="packages/core/src/service/helpers/list-query-builder/list-query-builder.ts" sourceLine="46" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/service/helpers/list-query-builder/list-query-builder.ts" sourceLine="42" packageName="@vendure/core" />
 
 Options which can be passed to the ListQueryBuilder's `build()` method.
 

+ 22 - 1
docs/docs/reference/typescript-api/entities/asset.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## Asset
 
-<GenerationInfo sourceFile="packages/core/src/entity/asset/asset.entity.ts" sourceLine="19" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/entity/asset/asset.entity.ts" sourceLine="22" packageName="@vendure/core" />
 
 An Asset represents a file such as an image which can be associated with certain other entities
 such as Products.
@@ -35,6 +35,12 @@ class Asset extends VendureEntity implements Taggable, ChannelAware, HasCustomFi
     @ManyToMany(type => Channel)
     @JoinTable()
     channels: Channel[];
+    @OneToMany(type => Collection, collection => collection.featuredAsset)
+    featuredInCollections?: Collection[];
+    @OneToMany(type => ProductVariant, productVariant => productVariant.featuredAsset)
+    featuredInVariants?: ProductVariant[];
+    @OneToMany(type => Product, product => product.featuredAsset)
+    featuredInProducts?: Product[];
     @Column(type => CustomAssetFields)
     customFields: CustomAssetFields;
 }
@@ -108,6 +114,21 @@ class Asset extends VendureEntity implements Taggable, ChannelAware, HasCustomFi
 <MemberInfo kind="property" type={`<a href='/reference/typescript-api/entities/channel#channel'>Channel</a>[]`}   />
 
 
+### featuredInCollections
+
+<MemberInfo kind="property" type={`<a href='/reference/typescript-api/entities/collection#collection'>Collection</a>[]`}   />
+
+
+### featuredInVariants
+
+<MemberInfo kind="property" type={`<a href='/reference/typescript-api/entities/product-variant#productvariant'>ProductVariant</a>[]`}   />
+
+
+### featuredInProducts
+
+<MemberInfo kind="property" type={`<a href='/reference/typescript-api/entities/product#product'>Product</a>[]`}   />
+
+
 ### customFields
 
 <MemberInfo kind="property" type={`CustomAssetFields`}   />

+ 36 - 1
docs/docs/reference/typescript-api/entities/channel.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## Channel
 
-<GenerationInfo sourceFile="packages/core/src/entity/channel/channel.entity.ts" sourceLine="31" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/entity/channel/channel.entity.ts" sourceLine="36" packageName="@vendure/core" />
 
 A Channel represents a distinct sales channel and configures defaults for that
 channel.
@@ -63,6 +63,16 @@ class Channel extends VendureEntity {
     @Column(type => CustomChannelFields)
     customFields: CustomChannelFields;
     @Column() pricesIncludeTax: boolean;
+    @ManyToMany(type => Product, product => product.channels, { onDelete: 'CASCADE' })
+    products: Product[];
+    @ManyToMany(type => ProductVariant, productVariant => productVariant.channels, { onDelete: 'CASCADE' })
+    productVariants: ProductVariant[];
+    @ManyToMany(type => FacetValue, facetValue => facetValue.channels, { onDelete: 'CASCADE' })
+    facetValues: FacetValue[];
+    @ManyToMany(type => Facet, facet => facet.channels, { onDelete: 'CASCADE' })
+    facets: Facet[];
+    @ManyToMany(type => Collection, collection => collection.channels, { onDelete: 'CASCADE' })
+    collections: Collection[];
 }
 ```
 * Extends: <code><a href='/reference/typescript-api/entities/vendure-entity#vendureentity'>VendureEntity</a></code>
@@ -155,6 +165,31 @@ out of stock.
 <MemberInfo kind="property" type={`boolean`}   />
 
 
+### products
+
+<MemberInfo kind="property" type={`<a href='/reference/typescript-api/entities/product#product'>Product</a>[]`}   />
+
+
+### productVariants
+
+<MemberInfo kind="property" type={`<a href='/reference/typescript-api/entities/product-variant#productvariant'>ProductVariant</a>[]`}   />
+
+
+### facetValues
+
+<MemberInfo kind="property" type={`<a href='/reference/typescript-api/entities/facet-value#facetvalue'>FacetValue</a>[]`}   />
+
+
+### facets
+
+<MemberInfo kind="property" type={`<a href='/reference/typescript-api/entities/facet#facet'>Facet</a>[]`}   />
+
+
+### collections
+
+<MemberInfo kind="property" type={`<a href='/reference/typescript-api/entities/collection#collection'>Collection</a>[]`}   />
+
+
 
 
 </div>

+ 2 - 2
docs/docs/reference/typescript-api/entities/collection.md

@@ -30,7 +30,7 @@ class Collection extends VendureEntity implements Translatable, HasCustomFields,
     @OneToMany(type => CollectionTranslation, translation => translation.base, { eager: true })
     translations: Array<Translation<Collection>>;
     @Index()
-    @ManyToOne(type => Asset, { onDelete: 'SET NULL' })
+    @ManyToOne(type => Asset, asset => asset.featuredInCollections, { onDelete: 'SET NULL' })
     featuredAsset: Asset;
     @OneToMany(type => CollectionAsset, collectionAsset => collectionAsset.collection)
     assets: CollectionAsset[];
@@ -47,7 +47,7 @@ class Collection extends VendureEntity implements Translatable, HasCustomFields,
     parent: Collection;
     @EntityId({ nullable: true })
     parentId: ID;
-    @ManyToMany(type => Channel)
+    @ManyToMany(type => Channel, channel => channel.collections)
     @JoinTable()
     channels: Channel[];
 }

+ 16 - 2
docs/docs/reference/typescript-api/entities/facet-value.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## FacetValue
 
-<GenerationInfo sourceFile="packages/core/src/entity/facet-value/facet-value.entity.ts" sourceLine="21" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/entity/facet-value/facet-value.entity.ts" sourceLine="23" packageName="@vendure/core" />
 
 A particular value of a <a href='/reference/typescript-api/entities/facet#facet'>Facet</a>.
 
@@ -29,9 +29,13 @@ class FacetValue extends VendureEntity implements Translatable, HasCustomFields,
     facetId: ID;
     @Column(type => CustomFacetValueFields)
     customFields: CustomFacetValueFields;
-    @ManyToMany(type => Channel)
+    @ManyToMany(type => Channel, channel => channel.facetValues)
     @JoinTable()
     channels: Channel[];
+    @ManyToMany(() => Product, product => product.facetValues, { onDelete: 'CASCADE' })
+    products: Product[];
+    @ManyToMany(type => ProductVariant, productVariant => productVariant.facetValues)
+    productVariants: ProductVariant[];
 }
 ```
 * Extends: <code><a href='/reference/typescript-api/entities/vendure-entity#vendureentity'>VendureEntity</a></code>
@@ -83,6 +87,16 @@ class FacetValue extends VendureEntity implements Translatable, HasCustomFields,
 <MemberInfo kind="property" type={`<a href='/reference/typescript-api/entities/channel#channel'>Channel</a>[]`}   />
 
 
+### products
+
+<MemberInfo kind="property" type={`<a href='/reference/typescript-api/entities/product#product'>Product</a>[]`}   />
+
+
+### productVariants
+
+<MemberInfo kind="property" type={`<a href='/reference/typescript-api/entities/product-variant#productvariant'>ProductVariant</a>[]`}   />
+
+
 
 
 </div>

+ 8 - 1
docs/docs/reference/typescript-api/entities/fulfillment.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## Fulfillment
 
-<GenerationInfo sourceFile="packages/core/src/entity/fulfillment/fulfillment.entity.ts" sourceLine="17" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/entity/fulfillment/fulfillment.entity.ts" sourceLine="18" packageName="@vendure/core" />
 
 This entity represents a fulfillment of an Order or part of it, i.e. which <a href='/reference/typescript-api/entities/order-line#orderline'>OrderLine</a>s have been
 delivered to the Customer after successful payment.
@@ -28,6 +28,8 @@ class Fulfillment extends VendureEntity implements HasCustomFields {
     handlerCode: string;
     @OneToMany(type => FulfillmentLine, fulfillmentLine => fulfillmentLine.fulfillment)
     lines: FulfillmentLine[];
+    @ManyToMany(type => Order, order => order.fulfillments)
+    orders: Order[];
     @Column(type => CustomFulfillmentFields)
     customFields: CustomFulfillmentFields;
 }
@@ -71,6 +73,11 @@ class Fulfillment extends VendureEntity implements HasCustomFields {
 <MemberInfo kind="property" type={`<a href='/reference/typescript-api/entities/order-line-reference#fulfillmentline'>FulfillmentLine</a>[]`}   />
 
 
+### orders
+
+<MemberInfo kind="property" type={`<a href='/reference/typescript-api/entities/order#order'>Order</a>[]`}   />
+
+
 ### customFields
 
 <MemberInfo kind="property" type={`CustomFulfillmentFields`}   />

+ 3 - 3
docs/docs/reference/typescript-api/entities/order.md

@@ -41,7 +41,7 @@ class Order extends VendureEntity implements ChannelAware, HasCustomFields {
     @Column({ nullable: true })
     orderPlacedAt?: Date;
     @Index()
-    @ManyToOne(type => Customer)
+    @ManyToOne(type => Customer, customer => customer.orders)
     customer?: Customer;
     @EntityId({ nullable: true })
     customerId?: ID;
@@ -51,14 +51,14 @@ class Order extends VendureEntity implements ChannelAware, HasCustomFields {
     surcharges: Surcharge[];
     @Column('simple-array')
     couponCodes: string[];
-    @ManyToMany(type => Promotion)
+    @ManyToMany(type => Promotion, promotion => promotion.orders)
     @JoinTable()
     promotions: Promotion[];
     @Column('simple-json') shippingAddress: OrderAddress;
     @Column('simple-json') billingAddress: OrderAddress;
     @OneToMany(type => Payment, payment => payment.order)
     payments: Payment[];
-    @ManyToMany(type => Fulfillment)
+    @ManyToMany(type => Fulfillment, fulfillment => fulfillment.orders)
     @JoinTable()
     fulfillments: Fulfillment[];
     @Column('varchar')

+ 1 - 1
docs/docs/reference/typescript-api/entities/product-option-group.md

@@ -28,7 +28,7 @@ class ProductOptionGroup extends VendureEntity implements Translatable, HasCusto
     @OneToMany(type => ProductOption, option => option.group)
     options: ProductOption[];
     @Index()
-    @ManyToOne(type => Product)
+    @ManyToOne(type => Product, product => product.optionGroups)
     product: Product;
     @Column(type => CustomProductOptionGroupFields)
     customFields: CustomProductOptionGroupFields;

+ 8 - 1
docs/docs/reference/typescript-api/entities/product-option.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## ProductOption
 
-<GenerationInfo sourceFile="packages/core/src/entity/product-option/product-option.entity.ts" sourceLine="20" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/entity/product-option/product-option.entity.ts" sourceLine="21" packageName="@vendure/core" />
 
 A ProductOption is used to differentiate <a href='/reference/typescript-api/entities/product-variant#productvariant'>ProductVariant</a>s from one another.
 
@@ -29,6 +29,8 @@ class ProductOption extends VendureEntity implements Translatable, HasCustomFiel
     group: ProductOptionGroup;
     @EntityId()
     groupId: ID;
+    @ManyToMany(type => ProductVariant, variant => variant.options)
+    productVariants: ProductVariant[];
     @Column(type => CustomProductOptionFields)
     customFields: CustomProductOptionFields;
 }
@@ -77,6 +79,11 @@ class ProductOption extends VendureEntity implements Translatable, HasCustomFiel
 <MemberInfo kind="property" type={`<a href='/reference/typescript-api/common/id#id'>ID</a>`}   />
 
 
+### productVariants
+
+<MemberInfo kind="property" type={`<a href='/reference/typescript-api/entities/product-variant#productvariant'>ProductVariant</a>[]`}   />
+
+
 ### customFields
 
 <MemberInfo kind="property" type={`CustomProductOptionFields`}   />

+ 5 - 5
docs/docs/reference/typescript-api/entities/product-variant.md

@@ -35,14 +35,14 @@ class ProductVariant extends VendureEntity implements Translatable, HasCustomFie
     priceWithTax: number
     taxRateApplied: TaxRate;
     @Index()
-    @ManyToOne(type => Asset, { onDelete: 'SET NULL' })
+    @ManyToOne(type => Asset, asset => asset.featuredInVariants, { onDelete: 'SET NULL' })
     featuredAsset: Asset;
     @OneToMany(type => ProductVariantAsset, productVariantAsset => productVariantAsset.productVariant, {
         onDelete: 'SET NULL',
     })
     assets: ProductVariantAsset[];
     @Index()
-    @ManyToOne(type => TaxCategory)
+    @ManyToOne(type => TaxCategory, taxCategory => taxCategory.productVariants)
     taxCategory: TaxCategory;
     @OneToMany(type => ProductVariantPrice, price => price.variant, { eager: true })
     productVariantPrices: ProductVariantPrice[];
@@ -63,17 +63,17 @@ class ProductVariant extends VendureEntity implements Translatable, HasCustomFie
     stockLevels: StockLevel[];
     @OneToMany(type => StockMovement, stockMovement => stockMovement.productVariant)
     stockMovements: StockMovement[];
-    @ManyToMany(type => ProductOption)
+    @ManyToMany(type => ProductOption, productOption => productOption.productVariants)
     @JoinTable()
     options: ProductOption[];
-    @ManyToMany(type => FacetValue)
+    @ManyToMany(type => FacetValue, facetValue => facetValue.productVariants)
     @JoinTable()
     facetValues: FacetValue[];
     @Column(type => CustomProductVariantFields)
     customFields: CustomProductVariantFields;
     @ManyToMany(type => Collection, collection => collection.productVariants)
     collections: Collection[];
-    @ManyToMany(type => Channel)
+    @ManyToMany(type => Channel, channel => channel.productVariants)
     @JoinTable()
     channels: Channel[];
 }

+ 8 - 8
docs/docs/reference/typescript-api/entities/product.md

@@ -27,7 +27,7 @@ class Product extends VendureEntity implements Translatable, HasCustomFields, Ch
     @Column({ default: true })
     enabled: boolean;
     @Index()
-    @ManyToOne(type => Asset, { onDelete: 'SET NULL' })
+    @ManyToOne(type => Asset, asset => asset.featuredInProducts, { onDelete: 'SET NULL' })
     featuredAsset: Asset;
     @OneToMany(type => ProductAsset, productAsset => productAsset.product)
     assets: ProductAsset[];
@@ -37,14 +37,14 @@ class Product extends VendureEntity implements Translatable, HasCustomFields, Ch
     variants: ProductVariant[];
     @OneToMany(type => ProductOptionGroup, optionGroup => optionGroup.product)
     optionGroups: ProductOptionGroup[];
-    @ManyToMany(type => FacetValue)
+    @ManyToMany(type => FacetValue, facetValue => facetValue.products)
     @JoinTable()
     facetValues: FacetValue[];
-    @Column(type => CustomProductFields)
-    customFields: CustomProductFields;
     @ManyToMany(type => Channel)
     @JoinTable()
     channels: Channel[];
+    @Column(type => CustomProductFields)
+    customFields: CustomProductFields;
 }
 ```
 * Extends: <code><a href='/reference/typescript-api/entities/vendure-entity#vendureentity'>VendureEntity</a></code>
@@ -116,14 +116,14 @@ class Product extends VendureEntity implements Translatable, HasCustomFields, Ch
 <MemberInfo kind="property" type={`<a href='/reference/typescript-api/entities/facet-value#facetvalue'>FacetValue</a>[]`}   />
 
 
-### customFields
+### channels
 
-<MemberInfo kind="property" type={`CustomProductFields`}   />
+<MemberInfo kind="property" type={`<a href='/reference/typescript-api/entities/channel#channel'>Channel</a>[]`}   />
 
 
-### channels
+### customFields
 
-<MemberInfo kind="property" type={`<a href='/reference/typescript-api/entities/channel#channel'>Channel</a>[]`}   />
+<MemberInfo kind="property" type={`CustomProductFields`}   />
 
 
 

+ 7 - 0
docs/docs/reference/typescript-api/entities/promotion.md

@@ -46,6 +46,8 @@ class Promotion extends AdjustmentSource implements ChannelAware, SoftDeletable,
     @ManyToMany(type => Channel)
     @JoinTable()
     channels: Channel[];
+    @ManyToMany(type => Order, order => order.promotions)
+    orders: Order[];
     @Column(type => CustomPromotionFields)
     customFields: CustomPromotionFields;
     @Column('simple-json') conditions: ConfigurableOperation[];
@@ -131,6 +133,11 @@ class Promotion extends AdjustmentSource implements ChannelAware, SoftDeletable,
 <MemberInfo kind="property" type={`<a href='/reference/typescript-api/entities/channel#channel'>Channel</a>[]`}   />
 
 
+### orders
+
+<MemberInfo kind="property" type={`<a href='/reference/typescript-api/entities/order#order'>Order</a>[]`}   />
+
+
 ### customFields
 
 <MemberInfo kind="property" type={`CustomPromotionFields`}   />

+ 8 - 1
docs/docs/reference/typescript-api/entities/tax-category.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## TaxCategory
 
-<GenerationInfo sourceFile="packages/core/src/entity/tax-category/tax-category.entity.ts" sourceLine="14" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/entity/tax-category/tax-category.entity.ts" sourceLine="15" packageName="@vendure/core" />
 
 A TaxCategory defines what type of taxes to apply to a <a href='/reference/typescript-api/entities/product-variant#productvariant'>ProductVariant</a>.
 
@@ -22,6 +22,8 @@ class TaxCategory extends VendureEntity implements HasCustomFields {
     @Column({ default: false }) isDefault: boolean;
     @Column(type => CustomTaxCategoryFields)
     customFields: CustomTaxCategoryFields;
+    @OneToMany(type => ProductVariant, productVariant => productVariant.taxCategory)
+    productVariants: ProductVariant[];
 }
 ```
 * Extends: <code><a href='/reference/typescript-api/entities/vendure-entity#vendureentity'>VendureEntity</a></code>
@@ -53,6 +55,11 @@ class TaxCategory extends VendureEntity implements HasCustomFields {
 <MemberInfo kind="property" type={`CustomTaxCategoryFields`}   />
 
 
+### productVariants
+
+<MemberInfo kind="property" type={`<a href='/reference/typescript-api/entities/product-variant#productvariant'>ProductVariant</a>[]`}   />
+
+
 
 
 </div>

+ 61 - 0
docs/docs/reference/typescript-api/events/blocking-event-handler-options.md

@@ -0,0 +1,61 @@
+---
+title: "BlockingEventHandlerOptions"
+isDefaultIndex: false
+generated: true
+---
+<!-- This file was generated from the Vendure source. Do not modify. Instead, re-run the "docs:build" script -->
+import MemberInfo from '@site/src/components/MemberInfo';
+import GenerationInfo from '@site/src/components/GenerationInfo';
+import MemberDescription from '@site/src/components/MemberDescription';
+
+
+## BlockingEventHandlerOptions
+
+<GenerationInfo sourceFile="packages/core/src/event-bus/event-bus.ts" sourceLine="22" packageName="@vendure/core" since="2.2.0" />
+
+Options for registering a blocking event handler.
+
+```ts title="Signature"
+type BlockingEventHandlerOptions<T extends VendureEvent> = {
+    event: Type<T> | Array<Type<T>>;
+    handler: (event: T) => void | Promise<void>;
+    id: string;
+    before?: string;
+    after?: string;
+}
+```
+
+<div className="members-wrapper">
+
+### event
+
+<MemberInfo kind="property" type={`Type&#60;T&#62; | Array&#60;Type&#60;T&#62;&#62;`}   />
+
+The event type to which the handler should listen.
+Can be a single event type or an array of event types.
+### handler
+
+<MemberInfo kind="property" type={`(event: T) =&#62; void | Promise&#60;void&#62;`}   />
+
+The handler function which will be executed when the event is published.
+If the handler returns a Promise, the event publishing code will wait for the Promise to resolve
+before continuing. Any errors thrown by the handler will cause the event publishing code to fail.
+### id
+
+<MemberInfo kind="property" type={`string`}   />
+
+A unique identifier for the handler. This can then be used to specify the order in which
+handlers should be executed using the `before` and `after` options in other handlers.
+### before
+
+<MemberInfo kind="property" type={`string`}   />
+
+The ID of another handler which this handler should execute before.
+### after
+
+<MemberInfo kind="property" type={`string`}   />
+
+The ID of another handler which this handler should execute after.
+
+
+</div>

+ 41 - 3
docs/docs/reference/typescript-api/events/event-bus.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## EventBus
 
-<GenerationInfo sourceFile="packages/core/src/event-bus/event-bus.ts" sourceLine="57" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/event-bus/event-bus.ts" sourceLine="97" packageName="@vendure/core" />
 
 The EventBus is used to globally publish events which can then be subscribed to.
 
@@ -56,9 +56,10 @@ export class MyPlugin implements OnApplicationBootstrap {
 ```ts title="Signature"
 class EventBus implements OnModuleDestroy {
     constructor(transactionSubscriber: TransactionSubscriber)
-    publish(event: T) => void;
+    publish(event: T) => Promise<void>;
     ofType(type: Type<T>) => Observable<T>;
     filter(predicate: (event: VendureEvent) => boolean) => Observable<T>;
+    registerBlockingEventHandler(handlerOptions: BlockingEventHandlerOptions<T>) => ;
 }
 ```
 * Implements: <code>OnModuleDestroy</code>
@@ -74,9 +75,15 @@ class EventBus implements OnModuleDestroy {
 
 ### publish
 
-<MemberInfo kind="method" type={`(event: T) => void`}   />
+<MemberInfo kind="method" type={`(event: T) => Promise&#60;void&#62;`}   />
 
 Publish an event which any subscribers can react to.
+
+*Example*
+
+```ts
+await eventBus.publish(new SomeEvent());
+```
 ### ofType
 
 <MemberInfo kind="method" type={`(type: Type&#60;T&#62;) => Observable&#60;T&#62;`}   />
@@ -97,6 +104,37 @@ will only get called after any active database transactions are complete.
 
 This means that the subscriber function can safely access all updated
 data related to the event.
+### registerBlockingEventHandler
+
+<MemberInfo kind="method" type={`(handlerOptions: <a href='/reference/typescript-api/events/blocking-event-handler-options#blockingeventhandleroptions'>BlockingEventHandlerOptions</a>&#60;T&#62;) => `}  since="2.2.0"  />
+
+Register an event handler function which will be executed when an event of the given type is published,
+and will block execution of the code which published the event until the handler has completed.
+
+This is useful when you need assurance that the event handler has successfully completed, and you want
+the triggering code to fail if the handler fails.
+
+::: warning
+This API should be used with caution, as errors or performance issues in the handler can cause the
+associated operation to be slow or fail entirely. For this reason, any handler which takes longer than
+100ms to execute will log a warning. Any non-trivial task to be performed in a blocking event handler
+should be offloaded to a background job using the <a href='/reference/typescript-api/job-queue/job-queue-service#jobqueueservice'>JobQueueService</a>.
+
+Also, be aware that the handler will be executed in the _same database transaction_ as the code which published
+the event (as long as you pass the `ctx` object from the event to any TransactionalConnection calls).
+:::
+
+*Example*
+
+```ts
+eventBus.registerBlockingEventHandler({
+  event: OrderStateTransitionEvent,
+  id: 'my-order-state-transition-handler',
+  handler: async (event) => {
+    // perform some synchronous task
+  }
+});
+```
 
 
 </div>

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

@@ -1121,7 +1121,7 @@ class ProductOptionGroupChangeEvent extends VendureEvent {
 
 ## ProductOptionGroupEvent
 
-<GenerationInfo sourceFile="packages/core/src/event-bus/events/product-option-group-event.ts" sourceLine="21" packageName="@vendure/core" since="1.4" />
+<GenerationInfo sourceFile="packages/core/src/event-bus/events/product-option-group-event.ts" sourceLine="24" packageName="@vendure/core" since="1.4" />
 
 This event is fired whenever a <a href='/reference/typescript-api/entities/product-option-group#productoptiongroup'>ProductOptionGroup</a> is added or updated.
 

+ 1 - 1
docs/docs/reference/typescript-api/fulfillment/fulfillment-process.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## defaultFulfillmentProcess
 
-<GenerationInfo sourceFile="packages/core/src/config/fulfillment/default-fulfillment-process.ts" sourceLine="42" packageName="@vendure/core" since="2.0.0" />
+<GenerationInfo sourceFile="packages/core/src/config/fulfillment/default-fulfillment-process.ts" sourceLine="45" packageName="@vendure/core" since="2.0.0" />
 
 The default <a href='/reference/typescript-api/fulfillment/fulfillment-process#fulfillmentprocess'>FulfillmentProcess</a>. This process includes the following actions:
 

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

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## AssetImporter
 
-<GenerationInfo sourceFile="packages/core/src/data-import/providers/asset-importer/asset-importer.ts" sourceLine="18" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/data-import/providers/asset-importer/asset-importer.ts" sourceLine="17" packageName="@vendure/core" />
 
 This service creates new <a href='/reference/typescript-api/entities/asset#asset'>Asset</a> entities based on string paths provided in the CSV
 import format. The source files are resolved by joining the value of `importExportOptions.importAssetsDir`

+ 1 - 1
docs/docs/reference/typescript-api/import-export/fast-importer-service.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## FastImporterService
 
-<GenerationInfo sourceFile="packages/core/src/data-import/providers/importer/fast-importer.service.ts" sourceLine="40" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/data-import/providers/importer/fast-importer.service.ts" sourceLine="41" packageName="@vendure/core" />
 
 A service to import entities into the database. This replaces the regular `create` methods of the service layer with faster
 versions which skip much of the defensive checks and other DB calls which are not needed when running an import. It also

+ 1 - 1
docs/docs/reference/typescript-api/orders/guest-checkout-strategy.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## GuestCheckoutStrategy
 
-<GenerationInfo sourceFile="packages/core/src/config/order/guest-checkout-strategy.ts" sourceLine="32" packageName="@vendure/core" since="2.0.0" />
+<GenerationInfo sourceFile="packages/core/src/config/order/guest-checkout-strategy.ts" sourceLine="33" packageName="@vendure/core" since="2.0.0" />
 
 A strategy that determines how to deal with guest checkouts - i.e. when a customer
 checks out without being logged in. For example, a strategy could be used to implement

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

@@ -196,7 +196,7 @@ Parameters
 
 ## defaultOrderProcess
 
-<GenerationInfo sourceFile="packages/core/src/config/order/default-order-process.ts" sourceLine="477" packageName="@vendure/core" since="2.0.0" />
+<GenerationInfo sourceFile="packages/core/src/config/order/default-order-process.ts" sourceLine="476" packageName="@vendure/core" since="2.0.0" />
 
 This is the built-in <a href='/reference/typescript-api/orders/order-process#orderprocess'>OrderProcess</a> that ships with Vendure. A customized version of this process
 can be created using the <a href='/reference/typescript-api/orders/order-process#configuredefaultorderprocess'>configureDefaultOrderProcess</a> function, which allows you to pass in an object

+ 2 - 2
docs/docs/reference/typescript-api/orders/order-seller-strategy.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## OrderSellerStrategy
 
-<GenerationInfo sourceFile="packages/core/src/config/order/order-seller-strategy.ts" sourceLine="45" packageName="@vendure/core" since="2.0.0" />
+<GenerationInfo sourceFile="packages/core/src/config/order/order-seller-strategy.ts" sourceLine="43" packageName="@vendure/core" since="2.0.0" />
 
 This strategy defines how an Order can be split into multiple sub-orders for the use-case of
 a multivendor application.
@@ -88,7 +88,7 @@ class DefaultOrderSellerStrategy implements OrderSellerStrategy {
 
 ## SplitOrderContents
 
-<GenerationInfo sourceFile="packages/core/src/config/order/order-seller-strategy.ts" sourceLine="21" packageName="@vendure/core" since="2.0.0" />
+<GenerationInfo sourceFile="packages/core/src/config/order/order-seller-strategy.ts" sourceLine="19" packageName="@vendure/core" since="2.0.0" />
 
 The contents of the aggregate Order which make up a single seller Order.
 

+ 1 - 1
docs/docs/reference/typescript-api/products-stock/default-stock-location-strategy.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## DefaultStockLocationStrategy
 
-<GenerationInfo sourceFile="packages/core/src/config/catalog/default-stock-location-strategy.ts" sourceLine="21" packageName="@vendure/core" since="2.0.0" />
+<GenerationInfo sourceFile="packages/core/src/config/catalog/default-stock-location-strategy.ts" sourceLine="22" packageName="@vendure/core" since="2.0.0" />
 
 The DefaultStockLocationStrategy is the default implementation of the <a href='/reference/typescript-api/products-stock/stock-location-strategy#stocklocationstrategy'>StockLocationStrategy</a>.
 It assumes only a single StockLocation and that all stock is allocated from that location.

+ 1 - 1
docs/docs/reference/typescript-api/request/relations-decorator.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## Relations
 
-<GenerationInfo sourceFile="packages/core/src/api/decorators/relations.decorator.ts" sourceLine="134" packageName="@vendure/core" since="1.6.0" />
+<GenerationInfo sourceFile="packages/core/src/api/decorators/relations.decorator.ts" sourceLine="136" packageName="@vendure/core" since="1.6.0" />
 
 Resolver param decorator which returns an array of relation paths which can be passed through
 to the TypeORM data layer in order to join only the required relations. This works by inspecting

+ 10 - 2
docs/docs/reference/typescript-api/service-helpers/order-modifier.md

@@ -25,7 +25,7 @@ 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, shippingCalculator: ShippingCalculator, historyService: HistoryService, translator: TranslatorService)
-    constrainQuantityToSaleable(ctx: RequestContext, variant: ProductVariant, quantity: number, existingQuantity:  = 0) => ;
+    constrainQuantityToSaleable(ctx: RequestContext, variant: ProductVariant, quantity: number, existingOrderLineQuantity:  = 0, quantityInOtherOrderLines:  = 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>;
@@ -44,10 +44,18 @@ class OrderModifier {
 
 ### constrainQuantityToSaleable
 
-<MemberInfo kind="method" type={`(ctx: <a href='/reference/typescript-api/request/request-context#requestcontext'>RequestContext</a>, variant: <a href='/reference/typescript-api/entities/product-variant#productvariant'>ProductVariant</a>, quantity: number, existingQuantity:  = 0) => `}   />
+<MemberInfo kind="method" type={`(ctx: <a href='/reference/typescript-api/request/request-context#requestcontext'>RequestContext</a>, variant: <a href='/reference/typescript-api/entities/product-variant#productvariant'>ProductVariant</a>, quantity: number, existingOrderLineQuantity:  = 0, quantityInOtherOrderLines:  = 0) => `}   />
 
 Ensure that the ProductVariant has sufficient saleable stock to add the given
 quantity to an Order.
+
+- `existingOrderLineQuantity` is used when adding an item to the order, since if an OrderLine
+already exists then we will be adding the new quantity to the existing quantity.
+- `quantityInOtherOrderLines` is used when we have more than 1 OrderLine containing the same
+ProductVariant. This occurs when there are custom fields defined on the OrderLine and the lines
+have differing values for one or more custom fields. In this case, we need to take _all_ of these
+OrderLines into account when constraining the quantity. See https://github.com/vendure-ecommerce/vendure/issues/2702
+for more on this.
 ### getExistingOrderLine
 
 <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>, productVariantId: <a href='/reference/typescript-api/common/id#id'>ID</a>, customFields?: { [key: string]: any }) => Promise&#60;<a href='/reference/typescript-api/entities/order-line#orderline'>OrderLine</a> | undefined&#62;`}   />

+ 6 - 3
docs/docs/reference/typescript-api/service-helpers/product-price-applicator.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## ProductPriceApplicator
 
-<GenerationInfo sourceFile="packages/core/src/service/helpers/product-price-applicator/product-price-applicator.ts" sourceLine="41" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/service/helpers/product-price-applicator/product-price-applicator.ts" sourceLine="40" packageName="@vendure/core" />
 
 This helper is used to apply the correct price to a ProductVariant based on the current context
 including active Channel, any current Order, etc. If you use the <a href='/reference/typescript-api/data-access/transactional-connection#transactionalconnection'>TransactionalConnection</a> to
@@ -41,7 +41,7 @@ export class MyCustomService {
 ```ts title="Signature"
 class ProductPriceApplicator {
     constructor(configService: ConfigService, taxRateService: TaxRateService, zoneService: ZoneService, requestCache: RequestContextCacheService)
-    applyChannelPriceAndTax(variant: ProductVariant, ctx: RequestContext, order?: Order) => Promise<ProductVariant>;
+    applyChannelPriceAndTax(variant: ProductVariant, ctx: RequestContext, order?: Order, throwIfNoPriceFound:  = false) => Promise<ProductVariant>;
 }
 ```
 
@@ -54,10 +54,13 @@ class ProductPriceApplicator {
 
 ### applyChannelPriceAndTax
 
-<MemberInfo kind="method" type={`(variant: <a href='/reference/typescript-api/entities/product-variant#productvariant'>ProductVariant</a>, ctx: <a href='/reference/typescript-api/request/request-context#requestcontext'>RequestContext</a>, order?: <a href='/reference/typescript-api/entities/order#order'>Order</a>) => Promise&#60;<a href='/reference/typescript-api/entities/product-variant#productvariant'>ProductVariant</a>&#62;`}   />
+<MemberInfo kind="method" type={`(variant: <a href='/reference/typescript-api/entities/product-variant#productvariant'>ProductVariant</a>, ctx: <a href='/reference/typescript-api/request/request-context#requestcontext'>RequestContext</a>, order?: <a href='/reference/typescript-api/entities/order#order'>Order</a>, throwIfNoPriceFound:  = false) => Promise&#60;<a href='/reference/typescript-api/entities/product-variant#productvariant'>ProductVariant</a>&#62;`}   />
 
 Populates the `price` field with the price for the specified channel. Make sure that
 the ProductVariant being passed in has its `taxCategory` relation joined.
 
+If the `throwIfNoPriceFound` option is set to `true`, then an error will be thrown if no
+price is found for the given Channel.
+
 
 </div>

+ 25 - 25
docs/docs/reference/typescript-api/services/customer-service.md

@@ -31,8 +31,8 @@ class CustomerService {
     refreshVerificationToken(ctx: RequestContext, emailAddress: string) => Promise<void>;
     verifyCustomerEmailAddress(ctx: RequestContext, verificationToken: string, password?: string) => Promise<ErrorResultUnion<VerifyCustomerAccountResult, Customer>>;
     requestPasswordReset(ctx: RequestContext, emailAddress: string) => Promise<void>;
-    resetPassword(ctx: RequestContext, passwordResetToken: string, password: string) => Promise<
-        User | PasswordResetTokenExpiredError | PasswordResetTokenInvalidError | PasswordValidationError
+    resetPassword(ctx: RequestContext, passwordResetToken: string, password: string) => Promise<
+        User | PasswordResetTokenExpiredError | PasswordResetTokenInvalidError | PasswordValidationError
     >;
     requestUpdateEmailAddress(ctx: RequestContext, userId: ID, newEmailAddress: string) => Promise<boolean | EmailAddressConflictError>;
     updateEmailAddress(ctx: RequestContext, token: string) => Promise<boolean | IdentifierChangeTokenInvalidError | IdentifierChangeTokenExpiredError>;
@@ -69,8 +69,8 @@ class CustomerService {
 
 <MemberInfo kind="method" type={`(ctx: <a href='/reference/typescript-api/request/request-context#requestcontext'>RequestContext</a>, userId: <a href='/reference/typescript-api/common/id#id'>ID</a>, filterOnChannel:  = true) => Promise&#60;<a href='/reference/typescript-api/entities/customer#customer'>Customer</a> | undefined&#62;`}   />
 
-Returns the Customer entity associated with the given userId, if one exists.
-Setting `filterOnChannel` to `true` will limit the results to Customers which are assigned
+Returns the Customer entity associated with the given userId, if one exists.
+Setting `filterOnChannel` to `true` will limit the results to Customers which are assigned
 to the current active Channel only.
 ### findAddressesByCustomerId
 
@@ -86,13 +86,13 @@ Returns a list of all <a href='/reference/typescript-api/entities/customer-group
 
 <MemberInfo kind="method" type={`(ctx: <a href='/reference/typescript-api/request/request-context#requestcontext'>RequestContext</a>, input: CreateCustomerInput, password?: string) => Promise&#60;<a href='/reference/typescript-api/errors/error-result-union#errorresultunion'>ErrorResultUnion</a>&#60;CreateCustomerResult, <a href='/reference/typescript-api/entities/customer#customer'>Customer</a>&#62;&#62;`}   />
 
-Creates a new Customer, including creation of a new User with the special `customer` Role.
-
-If the `password` argument is specified, the Customer will be immediately verified. If not,
-then an <a href='/reference/typescript-api/events/event-types#accountregistrationevent'>AccountRegistrationEvent</a> is published, so that the customer can have their
-email address verified and set their password in a later step using the `verifyCustomerEmailAddress()`
-method.
-
+Creates a new Customer, including creation of a new User with the special `customer` Role.
+
+If the `password` argument is specified, the Customer will be immediately verified. If not,
+then an <a href='/reference/typescript-api/events/event-types#accountregistrationevent'>AccountRegistrationEvent</a> is published, so that the customer can have their
+email address verified and set their password in a later step using the `verifyCustomerEmailAddress()`
+method.
+
 This method is intended to be used in admin-created Customer flows.
 ### update
 
@@ -113,47 +113,47 @@ This method is intended to be used in admin-created Customer flows.
 
 <MemberInfo kind="method" type={`(ctx: <a href='/reference/typescript-api/request/request-context#requestcontext'>RequestContext</a>, input: RegisterCustomerInput) => Promise&#60;RegisterCustomerAccountResult | EmailAddressConflictError | PasswordValidationError&#62;`}   />
 
-Registers a new Customer account with the <a href='/reference/typescript-api/auth/native-authentication-strategy#nativeauthenticationstrategy'>NativeAuthenticationStrategy</a> and starts
-the email verification flow (unless <a href='/reference/typescript-api/auth/auth-options#authoptions'>AuthOptions</a> `requireVerification` is set to `false`)
-by publishing an <a href='/reference/typescript-api/events/event-types#accountregistrationevent'>AccountRegistrationEvent</a>.
-
+Registers a new Customer account with the <a href='/reference/typescript-api/auth/native-authentication-strategy#nativeauthenticationstrategy'>NativeAuthenticationStrategy</a> and starts
+the email verification flow (unless <a href='/reference/typescript-api/auth/auth-options#authoptions'>AuthOptions</a> `requireVerification` is set to `false`)
+by publishing an <a href='/reference/typescript-api/events/event-types#accountregistrationevent'>AccountRegistrationEvent</a>.
+
 This method is intended to be used in storefront Customer-creation flows.
 ### refreshVerificationToken
 
 <MemberInfo kind="method" type={`(ctx: <a href='/reference/typescript-api/request/request-context#requestcontext'>RequestContext</a>, emailAddress: string) => Promise&#60;void&#62;`}   />
 
-Refreshes a stale email address verification token by generating a new one and
+Refreshes a stale email address verification token by generating a new one and
 publishing a <a href='/reference/typescript-api/events/event-types#accountregistrationevent'>AccountRegistrationEvent</a>.
 ### verifyCustomerEmailAddress
 
 <MemberInfo kind="method" type={`(ctx: <a href='/reference/typescript-api/request/request-context#requestcontext'>RequestContext</a>, verificationToken: string, password?: string) => Promise&#60;<a href='/reference/typescript-api/errors/error-result-union#errorresultunion'>ErrorResultUnion</a>&#60;VerifyCustomerAccountResult, <a href='/reference/typescript-api/entities/customer#customer'>Customer</a>&#62;&#62;`}   />
 
-Given a valid verification token which has been published in an <a href='/reference/typescript-api/events/event-types#accountregistrationevent'>AccountRegistrationEvent</a>, this
+Given a valid verification token which has been published in an <a href='/reference/typescript-api/events/event-types#accountregistrationevent'>AccountRegistrationEvent</a>, this
 method is used to set the Customer as `verified` as part of the account registration flow.
 ### requestPasswordReset
 
 <MemberInfo kind="method" type={`(ctx: <a href='/reference/typescript-api/request/request-context#requestcontext'>RequestContext</a>, emailAddress: string) => Promise&#60;void&#62;`}   />
 
-Publishes a new <a href='/reference/typescript-api/events/event-types#passwordresetevent'>PasswordResetEvent</a> for the given email address. This event creates
+Publishes a new <a href='/reference/typescript-api/events/event-types#passwordresetevent'>PasswordResetEvent</a> for the given email address. This event creates
 a token which can be used in the `resetPassword()` method.
 ### resetPassword
 
-<MemberInfo kind="method" type={`(ctx: <a href='/reference/typescript-api/request/request-context#requestcontext'>RequestContext</a>, passwordResetToken: string, password: string) => Promise&#60;
         <a href='/reference/typescript-api/entities/user#user'>User</a> | PasswordResetTokenExpiredError | PasswordResetTokenInvalidError | PasswordValidationError
     &#62;`}   />
+<MemberInfo kind="method" type={`(ctx: <a href='/reference/typescript-api/request/request-context#requestcontext'>RequestContext</a>, passwordResetToken: string, password: string) => Promise&#60;         <a href='/reference/typescript-api/entities/user#user'>User</a> | PasswordResetTokenExpiredError | PasswordResetTokenInvalidError | PasswordValidationError     &#62;`}   />
 
-Given a valid password reset token created by a call to the `requestPasswordReset()` method,
+Given a valid password reset token created by a call to the `requestPasswordReset()` method,
 this method will change the Customer's password to that given as the `password` argument.
 ### requestUpdateEmailAddress
 
 <MemberInfo kind="method" type={`(ctx: <a href='/reference/typescript-api/request/request-context#requestcontext'>RequestContext</a>, userId: <a href='/reference/typescript-api/common/id#id'>ID</a>, newEmailAddress: string) => Promise&#60;boolean | EmailAddressConflictError&#62;`}   />
 
-Publishes a <a href='/reference/typescript-api/events/event-types#identifierchangerequestevent'>IdentifierChangeRequestEvent</a> for the given User. This event contains a token
-which is then used in the `updateEmailAddress()` method to change the email address of the User &
+Publishes a <a href='/reference/typescript-api/events/event-types#identifierchangerequestevent'>IdentifierChangeRequestEvent</a> for the given User. This event contains a token
+which is then used in the `updateEmailAddress()` method to change the email address of the User &
 Customer.
 ### updateEmailAddress
 
 <MemberInfo kind="method" type={`(ctx: <a href='/reference/typescript-api/request/request-context#requestcontext'>RequestContext</a>, token: string) => Promise&#60;boolean | IdentifierChangeTokenInvalidError | IdentifierChangeTokenExpiredError&#62;`}   />
 
-Given a valid email update token published in a <a href='/reference/typescript-api/events/event-types#identifierchangerequestevent'>IdentifierChangeRequestEvent</a>, this method
+Given a valid email update token published in a <a href='/reference/typescript-api/events/event-types#identifierchangerequestevent'>IdentifierChangeRequestEvent</a>, this method
 will update the Customer & User email address.
 ### createOrUpdate
 
@@ -184,8 +184,8 @@ Creates a new <a href='/reference/typescript-api/entities/address#address'>Addre
 
 <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>) => `}   />
 
-If the Customer associated with the given Order does not yet have any Addresses,
-this method will create new Address(es) based on the Order's shipping & billing
+If the Customer associated with the given Order does not yet have any Addresses,
+this method will create new Address(es) based on the Order's shipping & billing
 addresses.
 ### addNoteToCustomer
 

+ 11 - 11
docs/docs/reference/typescript-api/services/fulfillment-service.md

@@ -21,14 +21,14 @@ class FulfillmentService {
     create(ctx: RequestContext, orders: Order[], lines: OrderLineInput[], handler: ConfigurableOperationInput) => Promise<Fulfillment | InvalidFulfillmentHandlerError | CreateFulfillmentError>;
     getFulfillmentLines(ctx: RequestContext, id: ID) => Promise<FulfillmentLine[]>;
     getFulfillmentsLinesForOrderLine(ctx: RequestContext, orderLineId: ID, relations: RelationPaths<FulfillmentLine> = []) => Promise<FulfillmentLine[]>;
-    transitionToState(ctx: RequestContext, fulfillmentId: ID, state: FulfillmentState) => Promise<
-        | {
-              fulfillment: Fulfillment;
-              orders: Order[];
-              fromState: FulfillmentState;
-              toState: FulfillmentState;
-          }
-        | FulfillmentStateTransitionError
+    transitionToState(ctx: RequestContext, fulfillmentId: ID, state: FulfillmentState) => Promise<
+        | {
+              fulfillment: Fulfillment;
+              orders: Order[];
+              fromState: FulfillmentState;
+              toState: FulfillmentState;
+          }
+        | FulfillmentStateTransitionError
     >;
     getNextStates(fulfillment: Fulfillment) => readonly FulfillmentState[];
 }
@@ -45,7 +45,7 @@ class FulfillmentService {
 
 <MemberInfo kind="method" type={`(ctx: <a href='/reference/typescript-api/request/request-context#requestcontext'>RequestContext</a>, orders: <a href='/reference/typescript-api/entities/order#order'>Order</a>[], lines: OrderLineInput[], handler: ConfigurableOperationInput) => Promise&#60;<a href='/reference/typescript-api/entities/fulfillment#fulfillment'>Fulfillment</a> | InvalidFulfillmentHandlerError | CreateFulfillmentError&#62;`}   />
 
-Creates a new Fulfillment for the given Orders and OrderItems, using the specified
+Creates a new Fulfillment for the given Orders and OrderItems, using the specified
 <a href='/reference/typescript-api/fulfillment/fulfillment-handler#fulfillmenthandler'>FulfillmentHandler</a>.
 ### getFulfillmentLines
 
@@ -59,9 +59,9 @@ Creates a new Fulfillment for the given Orders and OrderItems, using the specifi
 
 ### transitionToState
 
-<MemberInfo kind="method" type={`(ctx: <a href='/reference/typescript-api/request/request-context#requestcontext'>RequestContext</a>, fulfillmentId: <a href='/reference/typescript-api/common/id#id'>ID</a>, state: <a href='/reference/typescript-api/fulfillment/fulfillment-state#fulfillmentstate'>FulfillmentState</a>) => Promise&#60;
         | {
               fulfillment: <a href='/reference/typescript-api/entities/fulfillment#fulfillment'>Fulfillment</a>;
               orders: <a href='/reference/typescript-api/entities/order#order'>Order</a>[];
               fromState: <a href='/reference/typescript-api/fulfillment/fulfillment-state#fulfillmentstate'>FulfillmentState</a>;
               toState: <a href='/reference/typescript-api/fulfillment/fulfillment-state#fulfillmentstate'>FulfillmentState</a>;
           }
         | FulfillmentStateTransitionError
     &#62;`}   />
+<MemberInfo kind="method" type={`(ctx: <a href='/reference/typescript-api/request/request-context#requestcontext'>RequestContext</a>, fulfillmentId: <a href='/reference/typescript-api/common/id#id'>ID</a>, state: <a href='/reference/typescript-api/fulfillment/fulfillment-state#fulfillmentstate'>FulfillmentState</a>) => Promise&#60;         | {               fulfillment: <a href='/reference/typescript-api/entities/fulfillment#fulfillment'>Fulfillment</a>;               orders: <a href='/reference/typescript-api/entities/order#order'>Order</a>[];               fromState: <a href='/reference/typescript-api/fulfillment/fulfillment-state#fulfillmentstate'>FulfillmentState</a>;               toState: <a href='/reference/typescript-api/fulfillment/fulfillment-state#fulfillmentstate'>FulfillmentState</a>;           }         | FulfillmentStateTransitionError     &#62;`}   />
 
-Transitions the specified Fulfillment to a new state and upon successful transition
+Transitions the specified Fulfillment to a new state and upon successful transition
 publishes a <a href='/reference/typescript-api/events/event-types#fulfillmentstatetransitionevent'>FulfillmentStateTransitionEvent</a>.
 ### getNextStates
 

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

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

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

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## PaymentMethodService
 
-<GenerationInfo sourceFile="packages/core/src/service/services/payment-method.service.ts" sourceLine="48" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/service/services/payment-method.service.ts" sourceLine="46" packageName="@vendure/core" />
 
 Contains methods relating to <a href='/reference/typescript-api/entities/payment-method#paymentmethod'>PaymentMethod</a> entities.
 
@@ -28,10 +28,10 @@ class PaymentMethodService {
     getPaymentMethodEligibilityCheckers(ctx: RequestContext) => ConfigurableOperationDefinition[];
     getPaymentMethodHandlers(ctx: RequestContext) => ConfigurableOperationDefinition[];
     getEligiblePaymentMethods(ctx: RequestContext, order: Order) => Promise<PaymentMethodQuote[]>;
-    getMethodAndOperations(ctx: RequestContext, method: string) => Promise<{
-        paymentMethod: PaymentMethod;
-        handler: PaymentMethodHandler;
-        checker: PaymentMethodEligibilityChecker | null;
+    getMethodAndOperations(ctx: RequestContext, method: string) => Promise<{
+        paymentMethod: PaymentMethod;
+        handler: PaymentMethodHandler;
+        checker: PaymentMethodEligibilityChecker | null;
     }>;
 }
 ```
@@ -95,7 +95,7 @@ class PaymentMethodService {
 
 ### getMethodAndOperations
 
-<MemberInfo kind="method" type={`(ctx: <a href='/reference/typescript-api/request/request-context#requestcontext'>RequestContext</a>, method: string) => Promise&#60;{
         paymentMethod: <a href='/reference/typescript-api/entities/payment-method#paymentmethod'>PaymentMethod</a>;
         handler: <a href='/reference/typescript-api/payment/payment-method-handler#paymentmethodhandler'>PaymentMethodHandler</a>;
         checker: <a href='/reference/typescript-api/payment/payment-method-eligibility-checker#paymentmethodeligibilitychecker'>PaymentMethodEligibilityChecker</a> | null;
     }&#62;`}   />
+<MemberInfo kind="method" type={`(ctx: <a href='/reference/typescript-api/request/request-context#requestcontext'>RequestContext</a>, method: string) => Promise&#60;{         paymentMethod: <a href='/reference/typescript-api/entities/payment-method#paymentmethod'>PaymentMethod</a>;         handler: <a href='/reference/typescript-api/payment/payment-method-handler#paymentmethodhandler'>PaymentMethodHandler</a>;         checker: <a href='/reference/typescript-api/payment/payment-method-eligibility-checker#paymentmethodeligibilitychecker'>PaymentMethodEligibilityChecker</a> | null;     }&#62;`}   />
 
 
 

+ 2 - 2
docs/docs/reference/typescript-api/services/product-option-group-service.md

@@ -21,7 +21,7 @@ class ProductOptionGroupService {
     findAll(ctx: RequestContext, filterTerm?: string, relations?: RelationPaths<ProductOptionGroup>) => Promise<Array<Translated<ProductOptionGroup>>>;
     findOne(ctx: RequestContext, id: ID, relations?: RelationPaths<ProductOptionGroup>) => Promise<Translated<ProductOptionGroup> | undefined>;
     getOptionGroupsByProductId(ctx: RequestContext, id: ID) => Promise<Array<Translated<ProductOptionGroup>>>;
-    create(ctx: RequestContext, input: CreateProductOptionGroupInput) => Promise<Translated<ProductOptionGroup>>;
+    create(ctx: RequestContext, input: Omit<CreateProductOptionGroupInput, 'options'>) => Promise<Translated<ProductOptionGroup>>;
     update(ctx: RequestContext, input: UpdateProductOptionGroupInput) => Promise<Translated<ProductOptionGroup>>;
     deleteGroupAndOptionsFromProduct(ctx: RequestContext, id: ID, productId: ID) => ;
 }
@@ -51,7 +51,7 @@ class ProductOptionGroupService {
 
 ### create
 
-<MemberInfo kind="method" type={`(ctx: <a href='/reference/typescript-api/request/request-context#requestcontext'>RequestContext</a>, input: CreateProductOptionGroupInput) => Promise&#60;Translated&#60;<a href='/reference/typescript-api/entities/product-option-group#productoptiongroup'>ProductOptionGroup</a>&#62;&#62;`}   />
+<MemberInfo kind="method" type={`(ctx: <a href='/reference/typescript-api/request/request-context#requestcontext'>RequestContext</a>, input: Omit&#60;CreateProductOptionGroupInput, 'options'&#62;) => Promise&#60;Translated&#60;<a href='/reference/typescript-api/entities/product-option-group#productoptiongroup'>ProductOptionGroup</a>&#62;&#62;`}   />
 
 
 ### update

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

@@ -38,7 +38,7 @@ class ProductVariantService {
     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>;
+    applyChannelPriceAndTax(variant: ProductVariant, ctx: RequestContext, order?: Order, throwIfNoPriceFound:  = false) => Promise<ProductVariant>;
     assignProductVariantsToChannel(ctx: RequestContext, input: AssignProductVariantsToChannelInput) => Promise<Array<Translated<ProductVariant>>>;
     removeProductVariantsFromChannel(ctx: RequestContext, input: RemoveProductVariantsFromChannelInput) => Promise<Array<Translated<ProductVariant>>>;
 }
@@ -164,7 +164,7 @@ method.
 Is optimized to make as few DB calls as possible using caching based on the open request.
 ### applyChannelPriceAndTax
 
-<MemberInfo kind="method" type={`(variant: <a href='/reference/typescript-api/entities/product-variant#productvariant'>ProductVariant</a>, ctx: <a href='/reference/typescript-api/request/request-context#requestcontext'>RequestContext</a>, order?: <a href='/reference/typescript-api/entities/order#order'>Order</a>) => Promise&#60;<a href='/reference/typescript-api/entities/product-variant#productvariant'>ProductVariant</a>&#62;`}   />
+<MemberInfo kind="method" type={`(variant: <a href='/reference/typescript-api/entities/product-variant#productvariant'>ProductVariant</a>, ctx: <a href='/reference/typescript-api/request/request-context#requestcontext'>RequestContext</a>, order?: <a href='/reference/typescript-api/entities/order#order'>Order</a>, throwIfNoPriceFound:  = false) => Promise&#60;<a href='/reference/typescript-api/entities/product-variant#productvariant'>ProductVariant</a>&#62;`}   />
 
 Populates the `price` field with the price for the specified channel.
 ### assignProductVariantsToChannel

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

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## StockLevelService
 
-<GenerationInfo sourceFile="packages/core/src/service/services/stock-level.service.ts" sourceLine="20" packageName="@vendure/core" since="2.0.0" />
+<GenerationInfo sourceFile="packages/core/src/service/services/stock-level.service.ts" sourceLine="22" packageName="@vendure/core" since="2.0.0" />
 
 The StockLevelService is responsible for managing the stock levels of ProductVariants.
 Whenever you need to adjust the `stockOnHand` or `stockAllocated` for a ProductVariant,

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

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## StockMovementService
 
-<GenerationInfo sourceFile="packages/core/src/service/services/stock-movement.service.ts" sourceLine="43" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/service/services/stock-movement.service.ts" sourceLine="41" packageName="@vendure/core" />
 
 Contains methods relating to <a href='/reference/typescript-api/entities/stock-movement#stockmovement'>StockMovement</a> entities.
 

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

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## TaxCategoryService
 
-<GenerationInfo sourceFile="packages/core/src/service/services/tax-category.service.ts" sourceLine="29" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/service/services/tax-category.service.ts" sourceLine="28" packageName="@vendure/core" />
 
 Contains methods relating to <a href='/reference/typescript-api/entities/tax-category#taxcategory'>TaxCategory</a> entities.