Browse Source

feat(core): Add means to selectively ignore plugin compatibility errors

Closes #2958
Michael Bromley 1 year ago
parent
commit
e362475cb4
22 changed files with 303 additions and 56 deletions
  1. 18 18
      docs/docs/reference/core-plugins/asset-server-plugin/asset-server-options.md
  2. 2 1
      docs/docs/reference/core-plugins/asset-server-plugin/s3asset-storage-strategy.md
  3. 36 0
      docs/docs/reference/graphql-api/admin/object-types.md
  4. 8 0
      docs/docs/reference/graphql-api/shop/object-types.md
  5. 46 2
      docs/docs/reference/typescript-api/common/bootstrap.md
  6. 1 1
      docs/docs/reference/typescript-api/common/currency-code.md
  7. 1 1
      docs/docs/reference/typescript-api/common/job-state.md
  8. 1 1
      docs/docs/reference/typescript-api/common/language-code.md
  9. 1 1
      docs/docs/reference/typescript-api/common/permission.md
  10. 7 0
      docs/docs/reference/typescript-api/custom-fields/index.md
  11. 12 2
      docs/docs/reference/typescript-api/entities/history-entry.md
  12. 12 2
      docs/docs/reference/typescript-api/entities/payment.md
  13. 12 2
      docs/docs/reference/typescript-api/entities/refund.md
  14. 11 1
      docs/docs/reference/typescript-api/entities/session.md
  15. 12 2
      docs/docs/reference/typescript-api/entities/shipping-line.md
  16. 12 2
      docs/docs/reference/typescript-api/entities/stock-level.md
  17. 12 2
      docs/docs/reference/typescript-api/entities/stock-movement.md
  18. 7 2
      docs/docs/reference/typescript-api/plugin/vendure-plugin-metadata.md
  19. 1 1
      docs/docs/reference/typescript-api/plugin/vendure-plugin.md
  20. 9 3
      docs/docs/reference/typescript-api/worker/bootstrap-worker.md
  21. 77 12
      packages/core/src/bootstrap.ts
  22. 5 0
      packages/core/src/plugin/vendure-plugin.ts

+ 18 - 18
docs/docs/reference/core-plugins/asset-server-plugin/asset-server-options.md

@@ -26,8 +26,8 @@ interface AssetServerOptions {
     imageTransformStrategy?: ImageTransformStrategy | ImageTransformStrategy[];
     imageTransformStrategy?: ImageTransformStrategy | ImageTransformStrategy[];
     namingStrategy?: AssetNamingStrategy;
     namingStrategy?: AssetNamingStrategy;
     previewStrategy?: AssetPreviewStrategy;
     previewStrategy?: AssetPreviewStrategy;
-    storageStrategyFactory?: (
-        options: AssetServerOptions,
+    storageStrategyFactory?: (
+        options: AssetServerOptions,
     ) => AssetStorageStrategy | Promise<AssetStorageStrategy>;
     ) => AssetStorageStrategy | Promise<AssetStorageStrategy>;
     cacheHeader?: CacheConfig | string;
     cacheHeader?: CacheConfig | string;
 }
 }
@@ -49,12 +49,12 @@ The local directory to which assets will be uploaded when using the <a href='/re
 
 
 <MemberInfo kind="property" type={`string | ((ctx: <a href='/reference/typescript-api/request/request-context#requestcontext'>RequestContext</a>, identifier: string) =&#62; string)`}   />
 <MemberInfo kind="property" type={`string | ((ctx: <a href='/reference/typescript-api/request/request-context#requestcontext'>RequestContext</a>, identifier: string) =&#62; string)`}   />
 
 
-The complete URL prefix of the asset files. For example, "https://demo.vendure.io/assets/". A
-function can also be provided to handle more complex cases, such as serving multiple domains
-from a single server. In this case, the function should return a string url prefix.
-
-If not provided, the plugin will attempt to guess based off the incoming
-request and the configured route. However, in all but the simplest cases,
+The complete URL prefix of the asset files. For example, "https://demo.vendure.io/assets/". A
+function can also be provided to handle more complex cases, such as serving multiple domains
+from a single server. In this case, the function should return a string url prefix.
+
+If not provided, the plugin will attempt to guess based off the incoming
+request and the configured route. However, in all but the simplest cases,
 this guess may not yield correct results.
 this guess may not yield correct results.
 ### previewMaxWidth
 ### previewMaxWidth
 
 
@@ -75,12 +75,12 @@ An array of additional <a href='/reference/core-plugins/asset-server-plugin/imag
 
 
 <MemberInfo kind="property" type={`<a href='/reference/core-plugins/asset-server-plugin/image-transform-strategy#imagetransformstrategy'>ImageTransformStrategy</a> | <a href='/reference/core-plugins/asset-server-plugin/image-transform-strategy#imagetransformstrategy'>ImageTransformStrategy</a>[]`} default={`[]`}  since="3.1.0"  />
 <MemberInfo kind="property" type={`<a href='/reference/core-plugins/asset-server-plugin/image-transform-strategy#imagetransformstrategy'>ImageTransformStrategy</a> | <a href='/reference/core-plugins/asset-server-plugin/image-transform-strategy#imagetransformstrategy'>ImageTransformStrategy</a>[]`} default={`[]`}  since="3.1.0"  />
 
 
-The strategy or strategies to use to determine the parameters for transforming an image.
-This can be used to implement custom image transformation logic, for example to
-limit transform parameters to a known set of presets.
-
-If multiple strategies are provided, they will be executed in the order in which they are defined.
-If a strategy throws an error, the image transformation will be aborted and the error
+The strategy or strategies to use to determine the parameters for transforming an image.
+This can be used to implement custom image transformation logic, for example to
+limit transform parameters to a known set of presets.
+
+If multiple strategies are provided, they will be executed in the order in which they are defined.
+If a strategy throws an error, the image transformation will be aborted and the error
 will be logged, with an HTTP 400 response sent to the client.
 will be logged, with an HTTP 400 response sent to the client.
 ### namingStrategy
 ### namingStrategy
 
 
@@ -91,19 +91,19 @@ Defines how asset files and preview images are named before being saved.
 
 
 <MemberInfo kind="property" type={`<a href='/reference/typescript-api/assets/asset-preview-strategy#assetpreviewstrategy'>AssetPreviewStrategy</a>`}  since="1.7.0"  />
 <MemberInfo kind="property" type={`<a href='/reference/typescript-api/assets/asset-preview-strategy#assetpreviewstrategy'>AssetPreviewStrategy</a>`}  since="1.7.0"  />
 
 
-Defines how previews are generated for a given Asset binary. By default, this uses
+Defines how previews are generated for a given Asset binary. By default, this uses
 the <a href='/reference/core-plugins/asset-server-plugin/sharp-asset-preview-strategy#sharpassetpreviewstrategy'>SharpAssetPreviewStrategy</a>
 the <a href='/reference/core-plugins/asset-server-plugin/sharp-asset-preview-strategy#sharpassetpreviewstrategy'>SharpAssetPreviewStrategy</a>
 ### storageStrategyFactory
 ### storageStrategyFactory
 
 
-<MemberInfo kind="property" type={`(         options: <a href='/reference/core-plugins/asset-server-plugin/asset-server-options#assetserveroptions'>AssetServerOptions</a>,     ) =&#62; <a href='/reference/typescript-api/assets/asset-storage-strategy#assetstoragestrategy'>AssetStorageStrategy</a> | Promise&#60;<a href='/reference/typescript-api/assets/asset-storage-strategy#assetstoragestrategy'>AssetStorageStrategy</a>&#62;`} default={`() =&#62; <a href='/reference/core-plugins/asset-server-plugin/local-asset-storage-strategy#localassetstoragestrategy'>LocalAssetStorageStrategy</a>`}   />
+<MemberInfo kind="property" type={`(
         options: <a href='/reference/core-plugins/asset-server-plugin/asset-server-options#assetserveroptions'>AssetServerOptions</a>,
     ) =&#62; <a href='/reference/typescript-api/assets/asset-storage-strategy#assetstoragestrategy'>AssetStorageStrategy</a> | Promise&#60;<a href='/reference/typescript-api/assets/asset-storage-strategy#assetstoragestrategy'>AssetStorageStrategy</a>&#62;`} default={`() =&#62; <a href='/reference/core-plugins/asset-server-plugin/local-asset-storage-strategy#localassetstoragestrategy'>LocalAssetStorageStrategy</a>`}   />
 
 
-A function which can be used to configure an <a href='/reference/typescript-api/assets/asset-storage-strategy#assetstoragestrategy'>AssetStorageStrategy</a>. This is useful e.g. if you wish to store your assets
+A function which can be used to configure an <a href='/reference/typescript-api/assets/asset-storage-strategy#assetstoragestrategy'>AssetStorageStrategy</a>. This is useful e.g. if you wish to store your assets
 using a cloud storage provider. By default, the <a href='/reference/core-plugins/asset-server-plugin/local-asset-storage-strategy#localassetstoragestrategy'>LocalAssetStorageStrategy</a> is used.
 using a cloud storage provider. By default, the <a href='/reference/core-plugins/asset-server-plugin/local-asset-storage-strategy#localassetstoragestrategy'>LocalAssetStorageStrategy</a> is used.
 ### cacheHeader
 ### cacheHeader
 
 
 <MemberInfo kind="property" type={`<a href='/reference/core-plugins/asset-server-plugin/cache-config#cacheconfig'>CacheConfig</a> | string`} default={`'public, max-age=15552000'`}  since="1.9.3"  />
 <MemberInfo kind="property" type={`<a href='/reference/core-plugins/asset-server-plugin/cache-config#cacheconfig'>CacheConfig</a> | string`} default={`'public, max-age=15552000'`}  since="1.9.3"  />
 
 
-Configures the `Cache-Control` directive for response to control caching in browsers and shared caches (e.g. Proxies, CDNs).
+Configures the `Cache-Control` directive for response to control caching in browsers and shared caches (e.g. Proxies, CDNs).
 Defaults to publicly cached for 6 months.
 Defaults to publicly cached for 6 months.
 
 
 
 

+ 2 - 1
docs/docs/reference/core-plugins/asset-server-plugin/s3asset-storage-strategy.md

@@ -151,7 +151,8 @@ Using type `any` in order to avoid the need to include `aws-sdk` dependency in g
 
 
 <GenerationInfo sourceFile="packages/asset-server-plugin/src/config/s3-asset-storage-strategy.ts" sourceLine="119" packageName="@vendure/asset-server-plugin" />
 <GenerationInfo sourceFile="packages/asset-server-plugin/src/config/s3-asset-storage-strategy.ts" sourceLine="119" packageName="@vendure/asset-server-plugin" />
 
 
-Returns a configured instance of the <a href='/reference/core-plugins/asset-server-plugin/s3asset-storage-strategy#s3assetstoragestrategy'>S3AssetStorageStrategy</a> which can then be passed to the <a href='/reference/core-plugins/asset-server-plugin/asset-server-options#assetserveroptions'>AssetServerOptions</a>`storageStrategyFactory` property.
+Returns a configured instance of the <a href='/reference/core-plugins/asset-server-plugin/s3asset-storage-strategy#s3assetstoragestrategy'>S3AssetStorageStrategy</a> which can then be passed to the <a href='/reference/core-plugins/asset-server-plugin/asset-server-options#assetserveroptions'>AssetServerOptions</a>
+`storageStrategyFactory` property.
 
 
 Before using this strategy, make sure you have the `@aws-sdk/client-s3` and `@aws-sdk/lib-storage` package installed:
 Before using this strategy, make sure you have the `@aws-sdk/client-s3` and `@aws-sdk/lib-storage` package installed:
 
 

+ 36 - 0
docs/docs/reference/graphql-api/admin/object-types.md

@@ -134,6 +134,8 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 
 <div class="graphql-code-line ">orderLine: <a href="/reference/graphql-api/admin/object-types#orderline">OrderLine</a>!</div>
 <div class="graphql-code-line ">orderLine: <a href="/reference/graphql-api/admin/object-types#orderline">OrderLine</a>!</div>
 
 
+<div class="graphql-code-line ">customFields: <a href="/reference/graphql-api/admin/object-types#json">JSON</a></div>
+
 
 
 <div class="graphql-code-line top-level">&#125;</div>
 <div class="graphql-code-line top-level">&#125;</div>
 </div>
 </div>
@@ -356,6 +358,8 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 
 <div class="graphql-code-line ">orderLine: <a href="/reference/graphql-api/admin/object-types#orderline">OrderLine</a>!</div>
 <div class="graphql-code-line ">orderLine: <a href="/reference/graphql-api/admin/object-types#orderline">OrderLine</a>!</div>
 
 
+<div class="graphql-code-line ">customFields: <a href="/reference/graphql-api/admin/object-types#json">JSON</a></div>
+
 
 
 <div class="graphql-code-line top-level">&#125;</div>
 <div class="graphql-code-line top-level">&#125;</div>
 </div>
 </div>
@@ -847,10 +851,14 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 
 <div class="graphql-code-line ">GlobalSettings: [<a href="/reference/graphql-api/admin/object-types#customfieldconfig">CustomFieldConfig</a>!]!</div>
 <div class="graphql-code-line ">GlobalSettings: [<a href="/reference/graphql-api/admin/object-types#customfieldconfig">CustomFieldConfig</a>!]!</div>
 
 
+<div class="graphql-code-line ">HistoryEntry: [<a href="/reference/graphql-api/admin/object-types#customfieldconfig">CustomFieldConfig</a>!]!</div>
+
 <div class="graphql-code-line ">Order: [<a href="/reference/graphql-api/admin/object-types#customfieldconfig">CustomFieldConfig</a>!]!</div>
 <div class="graphql-code-line ">Order: [<a href="/reference/graphql-api/admin/object-types#customfieldconfig">CustomFieldConfig</a>!]!</div>
 
 
 <div class="graphql-code-line ">OrderLine: [<a href="/reference/graphql-api/admin/object-types#customfieldconfig">CustomFieldConfig</a>!]!</div>
 <div class="graphql-code-line ">OrderLine: [<a href="/reference/graphql-api/admin/object-types#customfieldconfig">CustomFieldConfig</a>!]!</div>
 
 
+<div class="graphql-code-line ">Payment: [<a href="/reference/graphql-api/admin/object-types#customfieldconfig">CustomFieldConfig</a>!]!</div>
+
 <div class="graphql-code-line ">PaymentMethod: [<a href="/reference/graphql-api/admin/object-types#customfieldconfig">CustomFieldConfig</a>!]!</div>
 <div class="graphql-code-line ">PaymentMethod: [<a href="/reference/graphql-api/admin/object-types#customfieldconfig">CustomFieldConfig</a>!]!</div>
 
 
 <div class="graphql-code-line ">Product: [<a href="/reference/graphql-api/admin/object-types#customfieldconfig">CustomFieldConfig</a>!]!</div>
 <div class="graphql-code-line ">Product: [<a href="/reference/graphql-api/admin/object-types#customfieldconfig">CustomFieldConfig</a>!]!</div>
@@ -865,14 +873,24 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 
 <div class="graphql-code-line ">Promotion: [<a href="/reference/graphql-api/admin/object-types#customfieldconfig">CustomFieldConfig</a>!]!</div>
 <div class="graphql-code-line ">Promotion: [<a href="/reference/graphql-api/admin/object-types#customfieldconfig">CustomFieldConfig</a>!]!</div>
 
 
+<div class="graphql-code-line ">Refund: [<a href="/reference/graphql-api/admin/object-types#customfieldconfig">CustomFieldConfig</a>!]!</div>
+
 <div class="graphql-code-line ">Region: [<a href="/reference/graphql-api/admin/object-types#customfieldconfig">CustomFieldConfig</a>!]!</div>
 <div class="graphql-code-line ">Region: [<a href="/reference/graphql-api/admin/object-types#customfieldconfig">CustomFieldConfig</a>!]!</div>
 
 
 <div class="graphql-code-line ">Seller: [<a href="/reference/graphql-api/admin/object-types#customfieldconfig">CustomFieldConfig</a>!]!</div>
 <div class="graphql-code-line ">Seller: [<a href="/reference/graphql-api/admin/object-types#customfieldconfig">CustomFieldConfig</a>!]!</div>
 
 
+<div class="graphql-code-line ">Session: [<a href="/reference/graphql-api/admin/object-types#customfieldconfig">CustomFieldConfig</a>!]!</div>
+
+<div class="graphql-code-line ">ShippingLine: [<a href="/reference/graphql-api/admin/object-types#customfieldconfig">CustomFieldConfig</a>!]!</div>
+
 <div class="graphql-code-line ">ShippingMethod: [<a href="/reference/graphql-api/admin/object-types#customfieldconfig">CustomFieldConfig</a>!]!</div>
 <div class="graphql-code-line ">ShippingMethod: [<a href="/reference/graphql-api/admin/object-types#customfieldconfig">CustomFieldConfig</a>!]!</div>
 
 
+<div class="graphql-code-line ">StockLevel: [<a href="/reference/graphql-api/admin/object-types#customfieldconfig">CustomFieldConfig</a>!]!</div>
+
 <div class="graphql-code-line ">StockLocation: [<a href="/reference/graphql-api/admin/object-types#customfieldconfig">CustomFieldConfig</a>!]!</div>
 <div class="graphql-code-line ">StockLocation: [<a href="/reference/graphql-api/admin/object-types#customfieldconfig">CustomFieldConfig</a>!]!</div>
 
 
+<div class="graphql-code-line ">StockMovement: [<a href="/reference/graphql-api/admin/object-types#customfieldconfig">CustomFieldConfig</a>!]!</div>
+
 <div class="graphql-code-line ">TaxCategory: [<a href="/reference/graphql-api/admin/object-types#customfieldconfig">CustomFieldConfig</a>!]!</div>
 <div class="graphql-code-line ">TaxCategory: [<a href="/reference/graphql-api/admin/object-types#customfieldconfig">CustomFieldConfig</a>!]!</div>
 
 
 <div class="graphql-code-line ">TaxRate: [<a href="/reference/graphql-api/admin/object-types#customfieldconfig">CustomFieldConfig</a>!]!</div>
 <div class="graphql-code-line ">TaxRate: [<a href="/reference/graphql-api/admin/object-types#customfieldconfig">CustomFieldConfig</a>!]!</div>
@@ -1516,6 +1534,8 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 
 <div class="graphql-code-line ">data: <a href="/reference/graphql-api/admin/object-types#json">JSON</a>!</div>
 <div class="graphql-code-line ">data: <a href="/reference/graphql-api/admin/object-types#json">JSON</a>!</div>
 
 
+<div class="graphql-code-line ">customFields: <a href="/reference/graphql-api/admin/object-types#json">JSON</a></div>
+
 
 
 <div class="graphql-code-line top-level">&#125;</div>
 <div class="graphql-code-line top-level">&#125;</div>
 </div>
 </div>
@@ -2593,6 +2613,8 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 
 <div class="graphql-code-line ">metadata: <a href="/reference/graphql-api/admin/object-types#json">JSON</a></div>
 <div class="graphql-code-line ">metadata: <a href="/reference/graphql-api/admin/object-types#json">JSON</a></div>
 
 
+<div class="graphql-code-line ">customFields: <a href="/reference/graphql-api/admin/object-types#json">JSON</a></div>
+
 
 
 <div class="graphql-code-line top-level">&#125;</div>
 <div class="graphql-code-line top-level">&#125;</div>
 </div>
 </div>
@@ -3226,6 +3248,8 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 
 <div class="graphql-code-line ">metadata: <a href="/reference/graphql-api/admin/object-types#json">JSON</a></div>
 <div class="graphql-code-line ">metadata: <a href="/reference/graphql-api/admin/object-types#json">JSON</a></div>
 
 
+<div class="graphql-code-line ">customFields: <a href="/reference/graphql-api/admin/object-types#json">JSON</a></div>
+
 
 
 <div class="graphql-code-line top-level">&#125;</div>
 <div class="graphql-code-line top-level">&#125;</div>
 </div>
 </div>
@@ -3393,6 +3417,8 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 
 <div class="graphql-code-line ">quantity: <a href="/reference/graphql-api/admin/object-types#int">Int</a>!</div>
 <div class="graphql-code-line ">quantity: <a href="/reference/graphql-api/admin/object-types#int">Int</a>!</div>
 
 
+<div class="graphql-code-line ">customFields: <a href="/reference/graphql-api/admin/object-types#json">JSON</a></div>
+
 
 
 <div class="graphql-code-line top-level">&#125;</div>
 <div class="graphql-code-line top-level">&#125;</div>
 </div>
 </div>
@@ -3434,6 +3460,8 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 
 <div class="graphql-code-line ">quantity: <a href="/reference/graphql-api/admin/object-types#int">Int</a>!</div>
 <div class="graphql-code-line ">quantity: <a href="/reference/graphql-api/admin/object-types#int">Int</a>!</div>
 
 
+<div class="graphql-code-line ">customFields: <a href="/reference/graphql-api/admin/object-types#json">JSON</a></div>
+
 
 
 <div class="graphql-code-line top-level">&#125;</div>
 <div class="graphql-code-line top-level">&#125;</div>
 </div>
 </div>
@@ -3488,6 +3516,8 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 
 <div class="graphql-code-line ">quantity: <a href="/reference/graphql-api/admin/object-types#int">Int</a>!</div>
 <div class="graphql-code-line ">quantity: <a href="/reference/graphql-api/admin/object-types#int">Int</a>!</div>
 
 
+<div class="graphql-code-line ">customFields: <a href="/reference/graphql-api/admin/object-types#json">JSON</a></div>
+
 
 
 <div class="graphql-code-line top-level">&#125;</div>
 <div class="graphql-code-line top-level">&#125;</div>
 </div>
 </div>
@@ -3713,6 +3743,8 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 
 <div class="graphql-code-line ">discounts: [<a href="/reference/graphql-api/admin/object-types#discount">Discount</a>!]!</div>
 <div class="graphql-code-line ">discounts: [<a href="/reference/graphql-api/admin/object-types#discount">Discount</a>!]!</div>
 
 
+<div class="graphql-code-line ">customFields: <a href="/reference/graphql-api/admin/object-types#json">JSON</a></div>
+
 
 
 <div class="graphql-code-line top-level">&#125;</div>
 <div class="graphql-code-line top-level">&#125;</div>
 </div>
 </div>
@@ -3837,6 +3869,8 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 
 <div class="graphql-code-line ">quantity: <a href="/reference/graphql-api/admin/object-types#int">Int</a>!</div>
 <div class="graphql-code-line ">quantity: <a href="/reference/graphql-api/admin/object-types#int">Int</a>!</div>
 
 
+<div class="graphql-code-line ">customFields: <a href="/reference/graphql-api/admin/object-types#json">JSON</a></div>
+
 
 
 <div class="graphql-code-line top-level">&#125;</div>
 <div class="graphql-code-line top-level">&#125;</div>
 </div>
 </div>
@@ -3859,6 +3893,8 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 
 <div class="graphql-code-line ">stockLocation: <a href="/reference/graphql-api/admin/object-types#stocklocation">StockLocation</a>!</div>
 <div class="graphql-code-line ">stockLocation: <a href="/reference/graphql-api/admin/object-types#stocklocation">StockLocation</a>!</div>
 
 
+<div class="graphql-code-line ">customFields: <a href="/reference/graphql-api/admin/object-types#json">JSON</a></div>
+
 
 
 <div class="graphql-code-line top-level">&#125;</div>
 <div class="graphql-code-line top-level">&#125;</div>
 </div>
 </div>

+ 8 - 0
docs/docs/reference/graphql-api/shop/object-types.md

@@ -1072,6 +1072,8 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 
 <div class="graphql-code-line ">data: <a href="/reference/graphql-api/shop/object-types#json">JSON</a>!</div>
 <div class="graphql-code-line ">data: <a href="/reference/graphql-api/shop/object-types#json">JSON</a>!</div>
 
 
+<div class="graphql-code-line ">customFields: <a href="/reference/graphql-api/shop/object-types#json">JSON</a></div>
+
 
 
 <div class="graphql-code-line top-level">&#125;</div>
 <div class="graphql-code-line top-level">&#125;</div>
 </div>
 </div>
@@ -1942,6 +1944,8 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 
 <div class="graphql-code-line ">metadata: <a href="/reference/graphql-api/shop/object-types#json">JSON</a></div>
 <div class="graphql-code-line ">metadata: <a href="/reference/graphql-api/shop/object-types#json">JSON</a></div>
 
 
+<div class="graphql-code-line ">customFields: <a href="/reference/graphql-api/shop/object-types#json">JSON</a></div>
+
 
 
 <div class="graphql-code-line top-level">&#125;</div>
 <div class="graphql-code-line top-level">&#125;</div>
 </div>
 </div>
@@ -2470,6 +2474,8 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 
 <div class="graphql-code-line ">metadata: <a href="/reference/graphql-api/shop/object-types#json">JSON</a></div>
 <div class="graphql-code-line ">metadata: <a href="/reference/graphql-api/shop/object-types#json">JSON</a></div>
 
 
+<div class="graphql-code-line ">customFields: <a href="/reference/graphql-api/shop/object-types#json">JSON</a></div>
+
 
 
 <div class="graphql-code-line top-level">&#125;</div>
 <div class="graphql-code-line top-level">&#125;</div>
 </div>
 </div>
@@ -2757,6 +2763,8 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 
 <div class="graphql-code-line ">discounts: [<a href="/reference/graphql-api/shop/object-types#discount">Discount</a>!]!</div>
 <div class="graphql-code-line ">discounts: [<a href="/reference/graphql-api/shop/object-types#discount">Discount</a>!]!</div>
 
 
+<div class="graphql-code-line ">customFields: <a href="/reference/graphql-api/shop/object-types#json">JSON</a></div>
+
 
 
 <div class="graphql-code-line top-level">&#125;</div>
 <div class="graphql-code-line top-level">&#125;</div>
 </div>
 </div>

+ 46 - 2
docs/docs/reference/typescript-api/common/bootstrap.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 
 ## bootstrap
 ## bootstrap
 
 
-<GenerationInfo sourceFile="packages/core/src/bootstrap.ts" sourceLine="106" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/bootstrap.ts" sourceLine="159" packageName="@vendure/core" />
 
 
 Bootstraps the Vendure server. This is the entry point to the application.
 Bootstraps the Vendure server. This is the entry point to the application.
 
 
@@ -49,6 +49,27 @@ bootstrap(config, {
 });
 });
 ```
 ```
 
 
+### Ignoring compatibility errors for plugins
+
+Since v3.1.0, you can ignore compatibility errors for specific plugins by passing the `ignoreCompatibilityErrorsForPlugins` option.
+
+This should be used with caution, only if you are sure that the plugin will still work as expected with the current version of Vendure.
+
+*Example*
+
+```ts
+import { bootstrap } from '@vendure/core';
+import { config } from './vendure-config';
+import { MyPlugin } from './plugins/my-plugin';
+
+bootstrap(config, {
+  // Let's say that `MyPlugin` is not yet compatible with the current version of Vendure
+  // but we know that it will still work as expected, and we are not able to publish
+  // a new version of the plugin right now.
+  ignoreCompatibilityErrorsForPlugins: [MyPlugin],
+});
+```
+
 ```ts title="Signature"
 ```ts title="Signature"
 function bootstrap(userConfig: Partial<VendureConfig>, options?: BootstrapOptions): Promise<INestApplication>
 function bootstrap(userConfig: Partial<VendureConfig>, options?: BootstrapOptions): Promise<INestApplication>
 ```
 ```
@@ -73,7 +94,8 @@ Vendure server.
 
 
 ```ts title="Signature"
 ```ts title="Signature"
 interface BootstrapOptions {
 interface BootstrapOptions {
-    nestApplicationOptions: NestApplicationOptions;
+    nestApplicationOptions?: NestApplicationOptions;
+    ignoreCompatibilityErrorsForPlugins?: Array<DynamicModule | Type<any>>;
 }
 }
 ```
 ```
 
 
@@ -84,6 +106,28 @@ interface BootstrapOptions {
 <MemberInfo kind="property" type={`NestApplicationOptions`}   />
 <MemberInfo kind="property" type={`NestApplicationOptions`}   />
 
 
 These options get passed directly to the `NestFactory.create()` method.
 These options get passed directly to the `NestFactory.create()` method.
+### ignoreCompatibilityErrorsForPlugins
+
+<MemberInfo kind="property" type={`Array&#60;DynamicModule | Type&#60;any&#62;&#62;`} default={`[]`}  since="3.1.0"  />
+
+By default, if a plugin specifies a compatibility range which does not include the current
+Vendure version, the bootstrap process will fail. This option allows you to ignore compatibility
+errors for specific plugins.
+
+This setting should be used with caution, only if you are sure that the plugin will still
+work as expected with the current version of Vendure.
+
+*Example*
+
+```ts
+import { bootstrap } from '@vendure/core';
+import { config } from './vendure-config';
+import { MyPlugin } from './plugins/my-plugin';
+
+bootstrap(config, {
+ ignoreCompatibilityErrorsForPlugins: [MyPlugin],
+});
+```
 
 
 
 
 </div>
 </div>

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

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 
 ## CurrencyCode
 ## CurrencyCode
 
 
-<GenerationInfo sourceFile="packages/common/src/generated-types.ts" sourceLine="992" packageName="@vendure/common" />
+<GenerationInfo sourceFile="packages/common/src/generated-types.ts" sourceLine="994" packageName="@vendure/common" />
 
 
 ISO 4217 currency code
 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
 ## JobState
 
 
-<GenerationInfo sourceFile="packages/common/src/generated-types.ts" sourceLine="2228" packageName="@vendure/common" />
+<GenerationInfo sourceFile="packages/common/src/generated-types.ts" sourceLine="2238" packageName="@vendure/common" />
 
 
 The state of a Job in the JobQueue
 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
 ## LanguageCode
 
 
-<GenerationInfo sourceFile="packages/common/src/generated-types.ts" sourceLine="2246" packageName="@vendure/common" />
+<GenerationInfo sourceFile="packages/common/src/generated-types.ts" sourceLine="2256" packageName="@vendure/common" />
 
 
 Languages in the form of a ISO 639-1 language code with optional
 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
 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
 ## Permission
 
 
-<GenerationInfo sourceFile="packages/common/src/generated-types.ts" sourceLine="4411" packageName="@vendure/common" />
+<GenerationInfo sourceFile="packages/common/src/generated-types.ts" sourceLine="4422" packageName="@vendure/common" />
 
 
 Permissions for administrators and customers. Used to control access to
 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.
 GraphQL resolvers via the <a href='/reference/typescript-api/request/allow-decorator#allow'>Allow</a> decorator.

+ 7 - 0
docs/docs/reference/typescript-api/custom-fields/index.md

@@ -47,8 +47,10 @@ type CustomFields = {
     FacetValue?: CustomFieldConfig[];
     FacetValue?: CustomFieldConfig[];
     Fulfillment?: CustomFieldConfig[];
     Fulfillment?: CustomFieldConfig[];
     GlobalSettings?: CustomFieldConfig[];
     GlobalSettings?: CustomFieldConfig[];
+    HistoryEntry?: CustomFieldConfig[];
     Order?: CustomFieldConfig[];
     Order?: CustomFieldConfig[];
     OrderLine?: CustomFieldConfig[];
     OrderLine?: CustomFieldConfig[];
+    Payment?: CustomFieldConfig[];
     PaymentMethod?: CustomFieldConfig[];
     PaymentMethod?: CustomFieldConfig[];
     Product?: CustomFieldConfig[];
     Product?: CustomFieldConfig[];
     ProductOption?: CustomFieldConfig[];
     ProductOption?: CustomFieldConfig[];
@@ -56,10 +58,15 @@ type CustomFields = {
     ProductVariant?: CustomFieldConfig[];
     ProductVariant?: CustomFieldConfig[];
     ProductVariantPrice?: CustomFieldConfig[];
     ProductVariantPrice?: CustomFieldConfig[];
     Promotion?: CustomFieldConfig[];
     Promotion?: CustomFieldConfig[];
+    Refund?: CustomFieldConfig[];
     Region?: CustomFieldConfig[];
     Region?: CustomFieldConfig[];
     Seller?: CustomFieldConfig[];
     Seller?: CustomFieldConfig[];
+    Session?: CustomFieldConfig[];
+    ShippingLine?: CustomFieldConfig[];
     ShippingMethod?: CustomFieldConfig[];
     ShippingMethod?: CustomFieldConfig[];
+    StockLevel?: CustomFieldConfig[];
     StockLocation?: CustomFieldConfig[];
     StockLocation?: CustomFieldConfig[];
+    StockMovement?: CustomFieldConfig[];
     TaxCategory?: CustomFieldConfig[];
     TaxCategory?: CustomFieldConfig[];
     TaxRate?: CustomFieldConfig[];
     TaxRate?: CustomFieldConfig[];
     User?: CustomFieldConfig[];
     User?: CustomFieldConfig[];

+ 12 - 2
docs/docs/reference/typescript-api/entities/history-entry.md

@@ -11,13 +11,13 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 
 ## HistoryEntry
 ## HistoryEntry
 
 
-<GenerationInfo sourceFile="packages/core/src/entity/history-entry/history-entry.entity.ts" sourceLine="14" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/entity/history-entry/history-entry.entity.ts" sourceLine="16" packageName="@vendure/core" />
 
 
 An abstract entity representing an entry in the history of an Order (<a href='/reference/typescript-api/entities/order-history-entry#orderhistoryentry'>OrderHistoryEntry</a>)
 An abstract entity representing an entry in the history of an Order (<a href='/reference/typescript-api/entities/order-history-entry#orderhistoryentry'>OrderHistoryEntry</a>)
 or a Customer (<a href='/reference/typescript-api/entities/customer-history-entry#customerhistoryentry'>CustomerHistoryEntry</a>).
 or a Customer (<a href='/reference/typescript-api/entities/customer-history-entry#customerhistoryentry'>CustomerHistoryEntry</a>).
 
 
 ```ts title="Signature"
 ```ts title="Signature"
-class HistoryEntry extends VendureEntity {
+class HistoryEntry extends VendureEntity implements HasCustomFields {
     @Index()
     @Index()
     @ManyToOne(type => Administrator)
     @ManyToOne(type => Administrator)
     administrator?: Administrator;
     administrator?: Administrator;
@@ -27,11 +27,16 @@ class HistoryEntry extends VendureEntity {
     isPublic: boolean;
     isPublic: boolean;
     @Column('simple-json')
     @Column('simple-json')
     data: any;
     data: any;
+    @Column(type => CustomHistoryEntryFields)
+    customFields: CustomHistoryEntryFields;
 }
 }
 ```
 ```
 * Extends: <code><a href='/reference/typescript-api/entities/vendure-entity#vendureentity'>VendureEntity</a></code>
 * Extends: <code><a href='/reference/typescript-api/entities/vendure-entity#vendureentity'>VendureEntity</a></code>
 
 
 
 
+* Implements: <code>HasCustomFields</code>
+
+
 
 
 <div className="members-wrapper">
 <div className="members-wrapper">
 
 
@@ -55,6 +60,11 @@ class HistoryEntry extends VendureEntity {
 <MemberInfo kind="property" type={`any`}   />
 <MemberInfo kind="property" type={`any`}   />
 
 
 
 
+### customFields
+
+<MemberInfo kind="property" type={`CustomHistoryEntryFields`}   />
+
+
 
 
 
 
 </div>
 </div>

+ 12 - 2
docs/docs/reference/typescript-api/entities/payment.md

@@ -11,13 +11,13 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 
 ## Payment
 ## Payment
 
 
-<GenerationInfo sourceFile="packages/core/src/entity/payment/payment.entity.ts" sourceLine="18" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/entity/payment/payment.entity.ts" sourceLine="20" packageName="@vendure/core" />
 
 
 A Payment represents a single payment transaction and exists in a well-defined state
 A Payment represents a single payment transaction and exists in a well-defined state
 defined by the <a href='/reference/typescript-api/payment/payment-state#paymentstate'>PaymentState</a> type.
 defined by the <a href='/reference/typescript-api/payment/payment-state#paymentstate'>PaymentState</a> type.
 
 
 ```ts title="Signature"
 ```ts title="Signature"
-class Payment extends VendureEntity {
+class Payment extends VendureEntity implements HasCustomFields {
     constructor(input?: DeepPartial<Payment>)
     constructor(input?: DeepPartial<Payment>)
     @Column() method: string;
     @Column() method: string;
     @Money() amount: number;
     @Money() amount: number;
@@ -32,11 +32,16 @@ class Payment extends VendureEntity {
     order: Order;
     order: Order;
     @OneToMany(type => Refund, refund => refund.payment)
     @OneToMany(type => Refund, refund => refund.payment)
     refunds: Refund[];
     refunds: Refund[];
+    @Column(type => CustomPaymentFields)
+    customFields: CustomPaymentFields;
 }
 }
 ```
 ```
 * Extends: <code><a href='/reference/typescript-api/entities/vendure-entity#vendureentity'>VendureEntity</a></code>
 * Extends: <code><a href='/reference/typescript-api/entities/vendure-entity#vendureentity'>VendureEntity</a></code>
 
 
 
 
+* Implements: <code>HasCustomFields</code>
+
+
 
 
 <div className="members-wrapper">
 <div className="members-wrapper">
 
 
@@ -85,6 +90,11 @@ class Payment extends VendureEntity {
 <MemberInfo kind="property" type={`<a href='/reference/typescript-api/entities/refund#refund'>Refund</a>[]`}   />
 <MemberInfo kind="property" type={`<a href='/reference/typescript-api/entities/refund#refund'>Refund</a>[]`}   />
 
 
 
 
+### customFields
+
+<MemberInfo kind="property" type={`CustomPaymentFields`}   />
+
+
 
 
 
 
 </div>
 </div>

+ 12 - 2
docs/docs/reference/typescript-api/entities/refund.md

@@ -11,12 +11,12 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 
 ## Refund
 ## Refund
 
 
-<GenerationInfo sourceFile="packages/core/src/entity/refund/refund.entity.ts" sourceLine="17" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/entity/refund/refund.entity.ts" sourceLine="19" packageName="@vendure/core" />
 
 
 A refund the belongs to an order
 A refund the belongs to an order
 
 
 ```ts title="Signature"
 ```ts title="Signature"
-class Refund extends VendureEntity {
+class Refund extends VendureEntity implements HasCustomFields {
     constructor(input?: DeepPartial<Refund>)
     constructor(input?: DeepPartial<Refund>)
     @Money() items: number;
     @Money() items: number;
     @Money() shipping: number;
     @Money() shipping: number;
@@ -36,11 +36,16 @@ class Refund extends VendureEntity {
     @EntityId()
     @EntityId()
     paymentId: ID;
     paymentId: ID;
     @Column('simple-json') metadata: PaymentMetadata;
     @Column('simple-json') metadata: PaymentMetadata;
+    @Column(type => CustomRefundFields)
+    customFields: CustomRefundFields;
 }
 }
 ```
 ```
 * Extends: <code><a href='/reference/typescript-api/entities/vendure-entity#vendureentity'>VendureEntity</a></code>
 * Extends: <code><a href='/reference/typescript-api/entities/vendure-entity#vendureentity'>VendureEntity</a></code>
 
 
 
 
+* Implements: <code>HasCustomFields</code>
+
+
 
 
 <div className="members-wrapper">
 <div className="members-wrapper">
 
 
@@ -109,6 +114,11 @@ class Refund extends VendureEntity {
 <MemberInfo kind="property" type={`PaymentMetadata`}   />
 <MemberInfo kind="property" type={`PaymentMetadata`}   />
 
 
 
 
+### customFields
+
+<MemberInfo kind="property" type={`CustomRefundFields`}   />
+
+
 
 
 
 
 </div>
 </div>

+ 11 - 1
docs/docs/reference/typescript-api/entities/session.md

@@ -17,7 +17,7 @@ A Session is created when a user makes a request to restricted API operations. A
 in the case of un-authenticated users, otherwise it is an <a href='/reference/typescript-api/entities/authenticated-session#authenticatedsession'>AuthenticatedSession</a>.
 in the case of un-authenticated users, otherwise it is an <a href='/reference/typescript-api/entities/authenticated-session#authenticatedsession'>AuthenticatedSession</a>.
 
 
 ```ts title="Signature"
 ```ts title="Signature"
-class Session extends VendureEntity {
+class Session extends VendureEntity implements HasCustomFields {
     @Index({ unique: true })
     @Index({ unique: true })
     @Column()
     @Column()
     token: string;
     token: string;
@@ -33,11 +33,16 @@ class Session extends VendureEntity {
     @Index()
     @Index()
     @ManyToOne(type => Channel)
     @ManyToOne(type => Channel)
     activeChannel: Channel | null;
     activeChannel: Channel | null;
+    @Column(type => CustomSessionFields)
+    customFields: CustomSessionFields;
 }
 }
 ```
 ```
 * Extends: <code><a href='/reference/typescript-api/entities/vendure-entity#vendureentity'>VendureEntity</a></code>
 * Extends: <code><a href='/reference/typescript-api/entities/vendure-entity#vendureentity'>VendureEntity</a></code>
 
 
 
 
+* Implements: <code>HasCustomFields</code>
+
+
 
 
 <div className="members-wrapper">
 <div className="members-wrapper">
 
 
@@ -76,6 +81,11 @@ class Session extends VendureEntity {
 <MemberInfo kind="property" type={`<a href='/reference/typescript-api/entities/channel#channel'>Channel</a> | null`}   />
 <MemberInfo kind="property" type={`<a href='/reference/typescript-api/entities/channel#channel'>Channel</a> | null`}   />
 
 
 
 
+### customFields
+
+<MemberInfo kind="property" type={`CustomSessionFields`}   />
+
+
 
 
 
 
 </div>
 </div>

+ 12 - 2
docs/docs/reference/typescript-api/entities/shipping-line.md

@@ -11,14 +11,14 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 
 ## ShippingLine
 ## ShippingLine
 
 
-<GenerationInfo sourceFile="packages/core/src/entity/shipping-line/shipping-line.entity.ts" sourceLine="24" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/entity/shipping-line/shipping-line.entity.ts" sourceLine="26" packageName="@vendure/core" />
 
 
 A ShippingLine is created when a <a href='/reference/typescript-api/entities/shipping-method#shippingmethod'>ShippingMethod</a> is applied to an <a href='/reference/typescript-api/entities/order#order'>Order</a>.
 A ShippingLine is created when a <a href='/reference/typescript-api/entities/shipping-method#shippingmethod'>ShippingMethod</a> is applied to an <a href='/reference/typescript-api/entities/order#order'>Order</a>.
 It contains information about the price of the shipping method, any discounts that were
 It contains information about the price of the shipping method, any discounts that were
 applied, and the resulting tax on the shipping method.
 applied, and the resulting tax on the shipping method.
 
 
 ```ts title="Signature"
 ```ts title="Signature"
-class ShippingLine extends VendureEntity {
+class ShippingLine extends VendureEntity implements HasCustomFields {
     constructor(input?: DeepPartial<ShippingLine>)
     constructor(input?: DeepPartial<ShippingLine>)
     @EntityId()
     @EntityId()
     shippingMethodId: ID | null;
     shippingMethodId: ID | null;
@@ -38,6 +38,8 @@ class ShippingLine extends VendureEntity {
     taxLines: TaxLine[];
     taxLines: TaxLine[];
     @OneToMany(type => OrderLine, orderLine => orderLine.shippingLine)
     @OneToMany(type => OrderLine, orderLine => orderLine.shippingLine)
     orderLines: OrderLine[];
     orderLines: OrderLine[];
+    @Column(type => CustomShippingLineFields)
+    customFields: CustomShippingLineFields;
     price: number
     price: number
     priceWithTax: number
     priceWithTax: number
     discountedPrice: number
     discountedPrice: number
@@ -51,6 +53,9 @@ class ShippingLine extends VendureEntity {
 * Extends: <code><a href='/reference/typescript-api/entities/vendure-entity#vendureentity'>VendureEntity</a></code>
 * Extends: <code><a href='/reference/typescript-api/entities/vendure-entity#vendureentity'>VendureEntity</a></code>
 
 
 
 
+* Implements: <code>HasCustomFields</code>
+
+
 
 
 <div className="members-wrapper">
 <div className="members-wrapper">
 
 
@@ -99,6 +104,11 @@ class ShippingLine extends VendureEntity {
 <MemberInfo kind="property" type={`<a href='/reference/typescript-api/entities/order-line#orderline'>OrderLine</a>[]`}   />
 <MemberInfo kind="property" type={`<a href='/reference/typescript-api/entities/order-line#orderline'>OrderLine</a>[]`}   />
 
 
 
 
+### customFields
+
+<MemberInfo kind="property" type={`CustomShippingLineFields`}   />
+
+
 ### price
 ### price
 
 
 <MemberInfo kind="property" type={`number`}   />
 <MemberInfo kind="property" type={`number`}   />

+ 12 - 2
docs/docs/reference/typescript-api/entities/stock-level.md

@@ -11,13 +11,13 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 
 ## StockLevel
 ## StockLevel
 
 
-<GenerationInfo sourceFile="packages/core/src/entity/stock-level/stock-level.entity.ts" sourceLine="16" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/entity/stock-level/stock-level.entity.ts" sourceLine="18" packageName="@vendure/core" />
 
 
 A StockLevel represents the number of a particular <a href='/reference/typescript-api/entities/product-variant#productvariant'>ProductVariant</a> which are available
 A StockLevel represents the number of a particular <a href='/reference/typescript-api/entities/product-variant#productvariant'>ProductVariant</a> which are available
 at a particular <a href='/reference/typescript-api/entities/stock-location#stocklocation'>StockLocation</a>.
 at a particular <a href='/reference/typescript-api/entities/stock-location#stocklocation'>StockLocation</a>.
 
 
 ```ts title="Signature"
 ```ts title="Signature"
-class StockLevel extends VendureEntity {
+class StockLevel extends VendureEntity implements HasCustomFields {
     constructor(input: DeepPartial<StockLevel>)
     constructor(input: DeepPartial<StockLevel>)
     @Index()
     @Index()
     @ManyToOne(type => ProductVariant, productVariant => productVariant.stockLevels, { onDelete: 'CASCADE' })
     @ManyToOne(type => ProductVariant, productVariant => productVariant.stockLevels, { onDelete: 'CASCADE' })
@@ -33,11 +33,16 @@ class StockLevel extends VendureEntity {
     stockOnHand: number;
     stockOnHand: number;
     @Column()
     @Column()
     stockAllocated: number;
     stockAllocated: number;
+    @Column(type => CustomStockLevelFields)
+    customFields: CustomStockLevelFields;
 }
 }
 ```
 ```
 * Extends: <code><a href='/reference/typescript-api/entities/vendure-entity#vendureentity'>VendureEntity</a></code>
 * Extends: <code><a href='/reference/typescript-api/entities/vendure-entity#vendureentity'>VendureEntity</a></code>
 
 
 
 
+* Implements: <code>HasCustomFields</code>
+
+
 
 
 <div className="members-wrapper">
 <div className="members-wrapper">
 
 
@@ -76,6 +81,11 @@ class StockLevel extends VendureEntity {
 <MemberInfo kind="property" type={`number`}   />
 <MemberInfo kind="property" type={`number`}   />
 
 
 
 
+### customFields
+
+<MemberInfo kind="property" type={`CustomStockLevelFields`}   />
+
+
 
 
 
 
 </div>
 </div>

+ 12 - 2
docs/docs/reference/typescript-api/entities/stock-movement.md

@@ -11,13 +11,13 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 
 ## StockMovement
 ## StockMovement
 
 
-<GenerationInfo sourceFile="packages/core/src/entity/stock-movement/stock-movement.entity.ts" sourceLine="19" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/entity/stock-movement/stock-movement.entity.ts" sourceLine="21" packageName="@vendure/core" />
 
 
 A StockMovement is created whenever stock of a particular ProductVariant goes in
 A StockMovement is created whenever stock of a particular ProductVariant goes in
 or out.
 or out.
 
 
 ```ts title="Signature"
 ```ts title="Signature"
-class StockMovement extends VendureEntity {
+class StockMovement extends VendureEntity implements HasCustomFields {
     @Column({ nullable: false, type: 'varchar' })
     @Column({ nullable: false, type: 'varchar' })
     readonly type: StockMovementType;
     readonly type: StockMovementType;
     @Index()
     @Index()
@@ -30,11 +30,16 @@ class StockMovement extends VendureEntity {
     stockLocationId: ID;
     stockLocationId: ID;
     @Column()
     @Column()
     quantity: number;
     quantity: number;
+    @Column(type => CustomStockMovementFields)
+    customFields: CustomStockMovementFields;
 }
 }
 ```
 ```
 * Extends: <code><a href='/reference/typescript-api/entities/vendure-entity#vendureentity'>VendureEntity</a></code>
 * Extends: <code><a href='/reference/typescript-api/entities/vendure-entity#vendureentity'>VendureEntity</a></code>
 
 
 
 
+* Implements: <code>HasCustomFields</code>
+
+
 
 
 <div className="members-wrapper">
 <div className="members-wrapper">
 
 
@@ -63,6 +68,11 @@ class StockMovement extends VendureEntity {
 <MemberInfo kind="property" type={`number`}   />
 <MemberInfo kind="property" type={`number`}   />
 
 
 
 
+### customFields
+
+<MemberInfo kind="property" type={`CustomStockMovementFields`}   />
+
+
 
 
 
 
 </div>
 </div>

+ 7 - 2
docs/docs/reference/typescript-api/plugin/vendure-plugin-metadata.md

@@ -68,6 +68,11 @@ guaranteed to be compatible with the current version of Vendure.
 
 
 To effectively disable this check for a plugin, you can use an overly-permissive string such as `>0.0.0`.
 To effectively disable this check for a plugin, you can use an overly-permissive string such as `>0.0.0`.
 
 
+:::note
+Since Vendure v3.1.0, it is possible to ignore compatibility errors for specific plugins by
+passing the `ignoreCompatibilityErrorsForPlugins` option to the <a href='/reference/typescript-api/common/bootstrap#bootstrap'>bootstrap</a> function.
+:::
+
 *Example*
 *Example*
 
 
 ```ts
 ```ts
@@ -80,7 +85,7 @@ compatibility: '^3.0.0'
 
 
 ## APIExtensionDefinition
 ## APIExtensionDefinition
 
 
-<GenerationInfo sourceFile="packages/core/src/plugin/vendure-plugin.ts" sourceLine="74" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/plugin/vendure-plugin.ts" sourceLine="79" packageName="@vendure/core" />
 
 
 An object which allows a plugin to extend the Vendure GraphQL API.
 An object which allows a plugin to extend the Vendure GraphQL API.
 
 
@@ -128,7 +133,7 @@ Read more about defining custom scalars in the
 
 
 ## PluginConfigurationFn
 ## PluginConfigurationFn
 
 
-<GenerationInfo sourceFile="packages/core/src/plugin/vendure-plugin.ts" sourceLine="112" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/plugin/vendure-plugin.ts" sourceLine="117" packageName="@vendure/core" />
 
 
 This method is called before the app bootstraps and should be used to perform any needed modifications to the <a href='/reference/typescript-api/configuration/vendure-config#vendureconfig'>VendureConfig</a>.
 This method is called before the app bootstraps and should be used to perform any needed modifications to the <a href='/reference/typescript-api/configuration/vendure-config#vendureconfig'>VendureConfig</a>.
 
 

+ 1 - 1
docs/docs/reference/typescript-api/plugin/vendure-plugin.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 
 ## VendurePlugin
 ## VendurePlugin
 
 
-<GenerationInfo sourceFile="packages/core/src/plugin/vendure-plugin.ts" sourceLine="151" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/plugin/vendure-plugin.ts" sourceLine="156" packageName="@vendure/core" />
 
 
 The VendurePlugin decorator is a means of configuring and/or extending the functionality of the Vendure server. A Vendure plugin is
 The VendurePlugin decorator is a means of configuring and/or extending the functionality of the Vendure server. A Vendure plugin is
 a [Nestjs Module](https://docs.nestjs.com/modules), with optional additional metadata defining things like extensions to the GraphQL API, custom
 a [Nestjs Module](https://docs.nestjs.com/modules), with optional additional metadata defining things like extensions to the GraphQL API, custom

+ 9 - 3
docs/docs/reference/typescript-api/worker/bootstrap-worker.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 
 ## bootstrapWorker
 ## bootstrapWorker
 
 
-<GenerationInfo sourceFile="packages/core/src/bootstrap.ts" sourceLine="170" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/bootstrap.ts" sourceLine="223" packageName="@vendure/core" />
 
 
 Bootstraps a Vendure worker. Resolves to a <a href='/reference/typescript-api/worker/vendure-worker#vendureworker'>VendureWorker</a> object containing a reference to the underlying
 Bootstraps a Vendure worker. Resolves to a <a href='/reference/typescript-api/worker/vendure-worker#vendureworker'>VendureWorker</a> object containing a reference to the underlying
 NestJs [standalone application](https://docs.nestjs.com/standalone-applications) as well as convenience
 NestJs [standalone application](https://docs.nestjs.com/standalone-applications) as well as convenience
@@ -51,14 +51,15 @@ Parameters
 
 
 ## BootstrapWorkerOptions
 ## BootstrapWorkerOptions
 
 
-<GenerationInfo sourceFile="packages/core/src/bootstrap.ts" sourceLine="58" packageName="@vendure/core" since="2.2.0" />
+<GenerationInfo sourceFile="packages/core/src/bootstrap.ts" sourceLine="82" packageName="@vendure/core" since="2.2.0" />
 
 
 Additional options that can be used to configure the bootstrap process of the
 Additional options that can be used to configure the bootstrap process of the
 Vendure worker.
 Vendure worker.
 
 
 ```ts title="Signature"
 ```ts title="Signature"
 interface BootstrapWorkerOptions {
 interface BootstrapWorkerOptions {
-    nestApplicationContextOptions: NestApplicationContextOptions;
+    nestApplicationContextOptions?: NestApplicationContextOptions;
+    ignoreCompatibilityErrorsForPlugins?: Array<DynamicModule | Type<any>>;
 }
 }
 ```
 ```
 
 
@@ -69,6 +70,11 @@ interface BootstrapWorkerOptions {
 <MemberInfo kind="property" type={`NestApplicationContextOptions`}   />
 <MemberInfo kind="property" type={`NestApplicationContextOptions`}   />
 
 
 These options get passed directly to the `NestFactory.createApplicationContext` method.
 These options get passed directly to the `NestFactory.createApplicationContext` method.
+### ignoreCompatibilityErrorsForPlugins
+
+<MemberInfo kind="property" type={`Array&#60;DynamicModule | Type&#60;any&#62;&#62;`} default={`[]`}  since="3.1.0"  />
+
+See the `ignoreCompatibilityErrorsForPlugins` option in <a href='/reference/typescript-api/common/bootstrap#bootstrapoptions'>BootstrapOptions</a>.
 
 
 
 
 </div>
 </div>

+ 77 - 12
packages/core/src/bootstrap.ts

@@ -1,4 +1,4 @@
-import { INestApplication, INestApplicationContext } from '@nestjs/common';
+import { DynamicModule, INestApplication, INestApplicationContext } from '@nestjs/common';
 import { NestApplicationContextOptions } from '@nestjs/common/interfaces/nest-application-context-options.interface';
 import { NestApplicationContextOptions } from '@nestjs/common/interfaces/nest-application-context-options.interface';
 import { NestApplicationOptions } from '@nestjs/common/interfaces/nest-application-options.interface';
 import { NestApplicationOptions } from '@nestjs/common/interfaces/nest-application-options.interface';
 import { NestFactory } from '@nestjs/core';
 import { NestFactory } from '@nestjs/core';
@@ -43,7 +43,31 @@ export interface BootstrapOptions {
      * @description
      * @description
      * These options get passed directly to the `NestFactory.create()` method.
      * These options get passed directly to the `NestFactory.create()` method.
      */
      */
-    nestApplicationOptions: NestApplicationOptions;
+    nestApplicationOptions?: NestApplicationOptions;
+    /**
+     * @description
+     * By default, if a plugin specifies a compatibility range which does not include the current
+     * Vendure version, the bootstrap process will fail. This option allows you to ignore compatibility
+     * errors for specific plugins.
+     *
+     * This setting should be used with caution, only if you are sure that the plugin will still
+     * work as expected with the current version of Vendure.
+     *
+     * @example
+     * ```ts
+     * import { bootstrap } from '\@vendure/core';
+     * import { config } from './vendure-config';
+     * import { MyPlugin } from './plugins/my-plugin';
+     *
+     * bootstrap(config, {
+     *  ignoreCompatibilityErrorsForPlugins: [MyPlugin],
+     * });
+     * ```
+     *
+     * @default []
+     * @since 3.1.0
+     */
+    ignoreCompatibilityErrorsForPlugins?: Array<DynamicModule | Type<any>>;
 }
 }
 
 
 /**
 /**
@@ -60,7 +84,15 @@ export interface BootstrapWorkerOptions {
      * @description
      * @description
      * These options get passed directly to the `NestFactory.createApplicationContext` method.
      * These options get passed directly to the `NestFactory.createApplicationContext` method.
      */
      */
-    nestApplicationContextOptions: NestApplicationContextOptions;
+    nestApplicationContextOptions?: NestApplicationContextOptions;
+    /**
+     * @description
+     * See the `ignoreCompatibilityErrorsForPlugins` option in {@link BootstrapOptions}.
+     *
+     * @default []
+     * @since 3.1.0
+     */
+    ignoreCompatibilityErrorsForPlugins?: Array<DynamicModule | Type<any>>;
 }
 }
 
 
 /**
 /**
@@ -99,6 +131,27 @@ export interface BootstrapWorkerOptions {
  *   process.exit(1);
  *   process.exit(1);
  * });
  * });
  * ```
  * ```
+ *
+ * ### Ignoring compatibility errors for plugins
+ *
+ * Since v3.1.0, you can ignore compatibility errors for specific plugins by passing the `ignoreCompatibilityErrorsForPlugins` option.
+ *
+ * This should be used with caution, only if you are sure that the plugin will still work as expected with the current version of Vendure.
+ *
+ * @example
+ * ```ts
+ * import { bootstrap } from '\@vendure/core';
+ * import { config } from './vendure-config';
+ * import { MyPlugin } from './plugins/my-plugin';
+ *
+ * bootstrap(config, {
+ *   // Let's say that `MyPlugin` is not yet compatible with the current version of Vendure
+ *   // but we know that it will still work as expected, and we are not able to publish
+ *   // a new version of the plugin right now.
+ *   ignoreCompatibilityErrorsForPlugins: [MyPlugin],
+ * });
+ * ```
+ *
  * @docsCategory common
  * @docsCategory common
  * @docsPage bootstrap
  * @docsPage bootstrap
  * @docsWeight 0
  * @docsWeight 0
@@ -110,7 +163,7 @@ export async function bootstrap(
     const config = await preBootstrapConfig(userConfig);
     const config = await preBootstrapConfig(userConfig);
     Logger.useLogger(config.logger);
     Logger.useLogger(config.logger);
     Logger.info(`Bootstrapping Vendure Server (pid: ${process.pid})...`);
     Logger.info(`Bootstrapping Vendure Server (pid: ${process.pid})...`);
-    checkPluginCompatibility(config);
+    checkPluginCompatibility(config, options?.ignoreCompatibilityErrorsForPlugins);
 
 
     // The AppModule *must* be loaded only after the entities have been set in the
     // The AppModule *must* be loaded only after the entities have been set in the
     // config, so that they are available when the AppModule decorator is evaluated.
     // config, so that they are available when the AppModule decorator is evaluated.
@@ -176,7 +229,7 @@ export async function bootstrapWorker(
     config.logger.setDefaultContext?.('Vendure Worker');
     config.logger.setDefaultContext?.('Vendure Worker');
     Logger.useLogger(config.logger);
     Logger.useLogger(config.logger);
     Logger.info(`Bootstrapping Vendure Worker (pid: ${process.pid})...`);
     Logger.info(`Bootstrapping Vendure Worker (pid: ${process.pid})...`);
-    checkPluginCompatibility(config);
+    checkPluginCompatibility(config, options?.ignoreCompatibilityErrorsForPlugins);
 
 
     setProcessContext('worker');
     setProcessContext('worker');
     DefaultLogger.hideNestBoostrapLogs();
     DefaultLogger.hideNestBoostrapLogs();
@@ -238,7 +291,10 @@ export async function preBootstrapConfig(
     return config;
     return config;
 }
 }
 
 
-function checkPluginCompatibility(config: RuntimeVendureConfig): void {
+function checkPluginCompatibility(
+    config: RuntimeVendureConfig,
+    ignoredPlugins: Array<DynamicModule | Type<any>> = [],
+): void {
     for (const plugin of config.plugins) {
     for (const plugin of config.plugins) {
         const compatibility = getCompatibility(plugin);
         const compatibility = getCompatibility(plugin);
         const pluginName = (plugin as any).name as string;
         const pluginName = (plugin as any).name as string;
@@ -248,13 +304,22 @@ function checkPluginCompatibility(config: RuntimeVendureConfig): void {
             );
             );
         } else {
         } else {
             if (!satisfies(VENDURE_VERSION, compatibility, { loose: true, includePrerelease: true })) {
             if (!satisfies(VENDURE_VERSION, compatibility, { loose: true, includePrerelease: true })) {
-                Logger.error(
+                const compatibilityErrorMessage =
                     `Plugin "${pluginName}" is not compatible with this version of Vendure. ` +
                     `Plugin "${pluginName}" is not compatible with this version of Vendure. ` +
-                        `It specifies a semver range of "${compatibility}" but the current version is "${VENDURE_VERSION}".`,
-                );
-                throw new InternalServerError(
-                    `Plugin "${pluginName}" is not compatible with this version of Vendure.`,
-                );
+                    `It specifies a semver range of "${compatibility}" but the current version is "${VENDURE_VERSION}".`;
+                if (ignoredPlugins.includes(plugin)) {
+                    Logger.warn(
+                        compatibilityErrorMessage +
+                            `However, this plugin has been explicitly marked as ignored using the 'ignoreCompatibilityErrorsForPlugins' bootstrap option,` +
+                            ` so it will be loaded anyway.`,
+                    );
+                    continue;
+                } else {
+                    Logger.error(compatibilityErrorMessage);
+                    throw new InternalServerError(
+                        `Plugin "${pluginName}" is not compatible with this version of Vendure.`,
+                    );
+                }
             }
             }
         }
         }
     }
     }

+ 5 - 0
packages/core/src/plugin/vendure-plugin.ts

@@ -54,6 +54,11 @@ export interface VendurePluginMetadata extends ModuleMetadata {
      *
      *
      * To effectively disable this check for a plugin, you can use an overly-permissive string such as `>0.0.0`.
      * To effectively disable this check for a plugin, you can use an overly-permissive string such as `>0.0.0`.
      *
      *
+     * :::note
+     * Since Vendure v3.1.0, it is possible to ignore compatibility errors for specific plugins by
+     * passing the `ignoreCompatibilityErrorsForPlugins` option to the {@link bootstrap} function.
+     * :::
+     *
      * @example
      * @example
      * ```ts
      * ```ts
      * compatibility: '^3.0.0'
      * compatibility: '^3.0.0'