Bläddra i källkod

docs(dashboard): Add docs for several dashboard APIs & components

Michael Bromley 8 månader sedan
förälder
incheckning
e9ee6ef5a3
91 ändrade filer med 2301 tillägg och 79 borttagningar
  1. 201 3
      docs/docs/guides/extending-the-dashboard/getting-started/index.md
  2. 7 1
      docs/docs/reference/core-plugins/graphiql-plugin/index.md
  3. 96 0
      docs/docs/reference/core-plugins/telemetry-plugin/get-sdk-configuration.md
  4. 130 0
      docs/docs/reference/core-plugins/telemetry-plugin/index.md
  5. 50 0
      docs/docs/reference/core-plugins/telemetry-plugin/register-method-hooks.md
  6. 77 0
      docs/docs/reference/core-plugins/telemetry-plugin/telemetry-plugin-options.md
  7. 90 0
      docs/docs/reference/dashboard/components/detail-page.md
  8. 14 0
      docs/docs/reference/dashboard/components/index.md
  9. 148 0
      docs/docs/reference/dashboard/components/list-page.md
  10. 64 0
      docs/docs/reference/dashboard/components/page-action-bar.md
  11. 127 0
      docs/docs/reference/dashboard/components/page-block.md
  12. 59 0
      docs/docs/reference/dashboard/components/page-layout.md
  13. 28 0
      docs/docs/reference/dashboard/components/page-title.md
  14. 35 0
      docs/docs/reference/dashboard/components/page.md
  15. 47 0
      docs/docs/reference/dashboard/extensions/dashboard-action-bar-item.md
  16. 60 0
      docs/docs/reference/dashboard/extensions/dashboard-extension.md
  17. 60 0
      docs/docs/reference/dashboard/extensions/dashboard-page-block-definition.md
  18. 28 0
      docs/docs/reference/dashboard/extensions/define-dashboard-extension.md
  19. 14 0
      docs/docs/reference/dashboard/extensions/index.md
  20. 49 0
      docs/docs/reference/dashboard/extensions/page-block-location.md
  21. 14 0
      docs/docs/reference/dashboard/hooks/index.md
  22. 83 0
      docs/docs/reference/dashboard/hooks/use-auth.md
  23. 77 0
      docs/docs/reference/dashboard/hooks/use-channel.md
  24. 221 0
      docs/docs/reference/dashboard/hooks/use-detail-page.md
  25. 34 0
      docs/docs/reference/dashboard/hooks/use-local-format.md
  26. 23 0
      docs/docs/reference/dashboard/hooks/use-permissions.md
  27. 1 1
      docs/docs/reference/typescript-api/assets/asset-options.md
  28. 1 1
      docs/docs/reference/typescript-api/auth/auth-options.md
  29. 1 1
      docs/docs/reference/typescript-api/auth/cookie-options.md
  30. 3 3
      docs/docs/reference/typescript-api/auth/default-password-validation-strategy.md
  31. 1 1
      docs/docs/reference/typescript-api/auth/superadmin-credentials.md
  32. 1 1
      docs/docs/reference/typescript-api/cache/cache-service.md
  33. 1 1
      docs/docs/reference/typescript-api/cache/sql-cache-strategy.md
  34. 1 1
      docs/docs/reference/typescript-api/configuration/api-options.md
  35. 1 1
      docs/docs/reference/typescript-api/configuration/default-config.md
  36. 1 1
      docs/docs/reference/typescript-api/configuration/entity-options.md
  37. 1 1
      docs/docs/reference/typescript-api/configuration/runtime-vendure-config.md
  38. 7 1
      docs/docs/reference/typescript-api/configuration/system-options.md
  39. 1 1
      docs/docs/reference/typescript-api/configuration/vendure-config.md
  40. 2 2
      docs/docs/reference/typescript-api/data-access/list-query-builder.md
  41. 1 1
      docs/docs/reference/typescript-api/events/blocking-event-handler-options.md
  42. 1 1
      docs/docs/reference/typescript-api/events/event-bus.md
  43. 1 1
      docs/docs/reference/typescript-api/import-export/import-export-options.md
  44. 50 2
      docs/docs/reference/typescript-api/job-queue/default-job-queue-plugin.md
  45. 1 1
      docs/docs/reference/typescript-api/job-queue/index.md
  46. 1 1
      docs/docs/reference/typescript-api/job-queue/job-queue-options.md
  47. 1 1
      docs/docs/reference/typescript-api/job-queue/job-queue-service.md
  48. 1 1
      docs/docs/reference/typescript-api/orders/order-options.md
  49. 1 1
      docs/docs/reference/typescript-api/payment/payment-options.md
  50. 1 1
      docs/docs/reference/typescript-api/products-stock/catalog-options.md
  51. 1 1
      docs/docs/reference/typescript-api/promotions/promotion-options.md
  52. 1 1
      docs/docs/reference/typescript-api/scheduled-tasks/clean-sessions-task.md
  53. 42 6
      docs/docs/reference/typescript-api/scheduled-tasks/scheduled-task.md
  54. 1 1
      docs/docs/reference/typescript-api/scheduled-tasks/scheduler-options.md
  55. 1 1
      docs/docs/reference/typescript-api/service-helpers/order-calculator.md
  56. 1 1
      docs/docs/reference/typescript-api/service-helpers/order-modifier.md
  57. 1 1
      docs/docs/reference/typescript-api/services/administrator-service.md
  58. 3 3
      docs/docs/reference/typescript-api/services/asset-service.md
  59. 1 1
      docs/docs/reference/typescript-api/services/auth-service.md
  60. 1 1
      docs/docs/reference/typescript-api/services/collection-service.md
  61. 1 1
      docs/docs/reference/typescript-api/services/customer-group-service.md
  62. 1 1
      docs/docs/reference/typescript-api/services/facet-value-service.md
  63. 1 1
      docs/docs/reference/typescript-api/services/global-settings-service.md
  64. 1 1
      docs/docs/reference/typescript-api/services/order-service.md
  65. 1 1
      docs/docs/reference/typescript-api/services/order-testing-service.md
  66. 1 1
      docs/docs/reference/typescript-api/services/payment-method-service.md
  67. 1 1
      docs/docs/reference/typescript-api/services/product-option-group-service.md
  68. 1 1
      docs/docs/reference/typescript-api/services/product-option-service.md
  69. 1 1
      docs/docs/reference/typescript-api/services/product-variant-service.md
  70. 1 1
      docs/docs/reference/typescript-api/services/promotion-service.md
  71. 1 1
      docs/docs/reference/typescript-api/services/province-service.md
  72. 1 1
      docs/docs/reference/typescript-api/services/role-service.md
  73. 1 1
      docs/docs/reference/typescript-api/services/session-service.md
  74. 1 1
      docs/docs/reference/typescript-api/services/shipping-method-service.md
  75. 1 1
      docs/docs/reference/typescript-api/services/stock-level-service.md
  76. 2 2
      docs/docs/reference/typescript-api/services/stock-movement-service.md
  77. 1 1
      docs/docs/reference/typescript-api/services/tag-service.md
  78. 1 1
      docs/docs/reference/typescript-api/services/tax-category-service.md
  79. 1 1
      docs/docs/reference/typescript-api/services/tax-rate-service.md
  80. 1 1
      docs/docs/reference/typescript-api/services/user-service.md
  81. 1 1
      docs/docs/reference/typescript-api/services/zone-service.md
  82. 1 1
      docs/docs/reference/typescript-api/shipping/shipping-options.md
  83. 1 1
      docs/docs/reference/typescript-api/tax/tax-options.md
  84. 14 0
      docs/docs/reference/typescript-api/telemetry/index.md
  85. 45 0
      docs/docs/reference/typescript-api/telemetry/instrument.md
  86. 39 0
      docs/docs/reference/typescript-api/telemetry/instrumentation-strategy.md
  87. 60 0
      docs/docs/reference/typescript-api/telemetry/wrapped-method-args.md
  88. 119 0
      packages/dashboard/src/lib/framework/layout-engine/page-layout.tsx
  89. 2 0
      packages/dashboard/src/lib/framework/page/detail-page.tsx
  90. 12 0
      packages/dashboard/src/lib/graphql/graphql-env.d.ts
  91. 15 6
      scripts/docs/typescript-docs-parser.ts

+ 201 - 3
docs/docs/guides/extending-the-dashboard/getting-started/index.md

@@ -16,6 +16,7 @@ The goal of the new dashboard:
 - Improve the developer experience to make it significantly easier and faster to build customizations
 - Reduce boilerplate (repetitive code) by using schema-driven UI generation
 - Modern, AI-ready stack using React, Tailwind & Shadcn.
+- Built-in type-safety with zero extra configuration
 
 Because the dashboard is in beta, not all planned features are available yet. However, enough has been implemented that
 you can try it out and give us feedback.
@@ -47,8 +48,17 @@ export default defineConfig({
     },
     plugins: [
         vendureDashboardPlugin({
+            // The vendureDashboardPlugin will scan your configuration in order
+            // to find any plugins which have dashboard extensions, as well as
+            // to introspect the GraphQL schema based on any API extensions 
+            // and custom fields that are configured.
             vendureConfigPath: pathToFileURL('./src/vendure-config.ts'),
-            adminUiConfig: { vapiHost: 'http://localhost', apiPort: 3000 },
+            // Points to the location of your Vendure server. 
+            adminUiConfig: { apiHost: 'http://localhost', apiPort: 3000 },
+            // When you start the Vite server, your Admin API schema will
+            // be introspected and the types will be generated in this location.
+            // These types can be used in your dashboard extensions to provide
+            // type safety when writing queries and mutations.
             gqlTadaOutputPath: './src/gql',
         }),
     ],
@@ -68,6 +78,10 @@ to correctly resolve imports of GraphQL types & interpret JSX in your dashboard
 ```json title="tsconfig.json"
 {
     "compilerOptions": {
+        // highlight-start
+        "module": "nodenext",
+        "moduleResolution": "nodenext",
+        // highlight-end
         // ... existing options
         // highlight-start
         "jsx": "react-jsx",
@@ -75,7 +89,17 @@ to correctly resolve imports of GraphQL types & interpret JSX in your dashboard
             "@/gql": ["./src/gql/graphql.ts"]
         }
         // highlight-end
-    }
+    },
+    "exclude": [
+        "node_modules", 
+        "migration.ts", 
+        "src/plugins/**/ui/*",
+        "admin-ui",
+        // highlight-start
+        "src/plugins/**/dashboard/*", 
+        "vite.*.*ts"
+        // highlight-end
+    ]
 }
 ```
 
@@ -349,7 +373,8 @@ You should now be able to see the list view, which will be empty:
 
 Now let's create a detail page so we can start adding articles.
 
-We'll begin with the simplest approach, where the form will be auto-generated for us based on the GraphQL schema. 
+We'll begin with the simplest approach, where the form will be auto-generated for us based on the GraphQL schema
+using the [DetailPage](/reference/dashboard/components/detail-page) component.
 This is useful for quickly getting started, but you will probably want to customize the form later on.
 
 Create a new file called `article-detail.tsx` in the `./src/plugins/cms/dashboard` directory:
@@ -451,6 +476,179 @@ Congratulations! You can now add, edit and delete articles in the dashboard.
 
 ![List view with entries](./list-view-full.webp)
 
+### Customizing the detail page
+
+The auto-generated [DetailPage](/reference/dashboard/components/detail-page) is a great way to get started and quickly be able
+to interact with your entities. But let's now see how we can fully customize the layout and form fields.
+
+```tsx title="src/plugins/cms/dashboard/article-detail.tsx"
+import {
+    DashboardRouteDefinition,
+    detailPageRouteLoader,
+    useDetailPage,
+    Page,
+    PageTitle,
+    PageActionBar,
+    PageActionBarRight,
+    PermissionGuard,
+    Button,
+    PageLayout,
+    PageBlock,
+    FormFieldWrapper,
+    DetailFormGrid,
+    Switch,
+    Input,
+    RichTextInput,
+    CustomFieldsPageBlock,
+} from '@vendure/dashboard';
+import {AnyRoute, useNavigate} from '@tanstack/react-router'
+import {toast} from 'sonner';
+
+import {graphql} from '@/gql';
+
+const articleDetailDocument = graphql(`
+    query GetArticleDetail($id: ID!) {
+        article(id: $id) {
+            id
+            createdAt
+            updatedAt
+            isPublished
+            title
+            slug
+            body
+            customFields
+        }
+    }
+`);
+
+const createArticleDocument = graphql(`
+    mutation CreateArticle($input: CreateArticleInput!) {
+        createArticle(input: $input) {
+            id
+        }
+    }
+`);
+
+const updateArticleDocument = graphql(`
+    mutation UpdateArticle($input: UpdateArticleInput!) {
+        updateArticle(input: $input) {
+            id
+        }
+    }
+`);
+
+export const articleDetail: DashboardRouteDefinition = {
+    path: '/articles/$id',
+    loader: detailPageRouteLoader({
+        queryDocument: articleDetailDocument,
+        breadcrumb: (isNew, entity) => [
+            {path: '/articles', label: 'Articles'},
+            isNew ? 'New article' : entity?.title,
+        ],
+    }),
+    component: route => {
+        return (
+            <ArticleDetailPage route={route} />
+        );
+    },
+};
+
+
+function ArticleDetailPage({route}: { route: AnyRoute }) {
+    const params = route.useParams();
+    const navigate = useNavigate();
+    const creatingNewEntity = params.id === 'new';
+
+    const {form, submitHandler, entity, isPending, resetForm} = useDetailPage({
+        queryDocument: articleDetailDocument,
+        createDocument: createArticleDocument,
+        updateDocument: updateArticleDocument,
+        setValuesForUpdate: article => {
+            return {
+                id: article?.id ?? '',
+                isPublished: article?.isPublished ?? false,
+                title: article?.title ?? '',
+                slug: article?.slug ?? '',
+                body: article?.body ?? '',
+            };
+        },
+        params: {id: params.id},
+        onSuccess: async data => {
+            toast('Successfully updated article');
+            resetForm();
+            if (creatingNewEntity) {
+                await navigate({to: `../$id`, params: { id: data.id } });
+            }
+        },
+        onError: err => {
+            toast('Failed to update article', {
+                description: err instanceof Error ? err.message : 'Unknown error',
+            });
+        },
+    });
+
+    return (
+        <Page pageId="article-detail" form={form} submitHandler={submitHandler}>
+            <PageTitle>{creatingNewEntity ? 'New article' : (entity?.title ?? '')}</PageTitle>
+            <PageActionBar>
+                <PageActionBarRight>
+                    <PermissionGuard requires={['UpdateProduct', 'UpdateCatalog']}>
+                        <Button
+                            type="submit"
+                            disabled={!form.formState.isDirty || !form.formState.isValid || isPending}
+                        >
+                            Update
+                        </Button>
+                    </PermissionGuard>
+                </PageActionBarRight>
+            </PageActionBar>
+            <PageLayout>
+                <PageBlock column="side" blockId="publish-status">
+                    <FormFieldWrapper
+                        control={form.control}
+                        name="isPublished"
+                        label="Is Published"
+                        render={({field}) => (
+                            <Switch checked={field.value} onCheckedChange={field.onChange}/>
+                        )}
+                    />
+                </PageBlock>
+                <PageBlock column="main" blockId="main-form">
+                    <DetailFormGrid>
+                        <FormFieldWrapper
+                            control={form.control}
+                            name="title"
+                            label="Title"
+                            render={({field}) => <Input {...field} />}
+                        />
+                        <FormFieldWrapper
+                            control={form.control}
+                            name="slug"
+                            label="Slug"
+                            render={({field}) => <Input {...field} />}
+                        />
+                    </DetailFormGrid>
+                    <FormFieldWrapper
+                        control={form.control}
+                        name="body"
+                        label="Content"
+                        render={({field}) => <RichTextInput value={field.value ?? ''} onChange={field.onChange} />}
+                    />
+                </PageBlock>
+                <CustomFieldsPageBlock column="main" entityType="Article" control={form.control}/>
+            </PageLayout>
+        </Page>
+    );
+}
+```
+
+In the above example, we have:
+
+- Used the [Page](/reference/dashboard/components/page), [PageTitle](/reference/dashboard/components/page-title), 
+  [PageActionBar](/reference/dashboard/components/page-action-bar) and [PageLayout](/reference/dashboard/components/page-layout) components to create a layout for our page.
+- Used [PageBlock](/reference/dashboard/components/page-block) components to structure the page into blocks.
+- Used custom form components (such as the `RichTextInput`) to better represent the data.
+
 ### Defining page blocks
 
 In the Dashboard, all pages are build from blocks. Every block has a `pageId` and a `blockId` which uniquely locates it in the

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

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## GraphiqlPlugin
 
-<GenerationInfo sourceFile="packages/graphiql-plugin/src/plugin.ts" sourceLine="44" packageName="@vendure/graphiql-plugin" />
+<GenerationInfo sourceFile="packages/graphiql-plugin/src/plugin.ts" sourceLine="43" packageName="@vendure/graphiql-plugin" />
 
 This plugin provides a GraphiQL UI for exploring and testing the Vendure GraphQL APIs.
 
@@ -35,6 +35,7 @@ const config: VendureConfig = {
 
 ```ts title="Signature"
 class GraphiqlPlugin implements NestModule {
+    static options: Required<GraphiqlPluginOptions>;
     constructor(processContext: ProcessContext, configService: ConfigService, graphiQLService: GraphiQLService)
     init(options: GraphiqlPluginOptions = {}) => Type<GraphiqlPlugin>;
     configure(consumer: MiddlewareConsumer) => ;
@@ -46,6 +47,11 @@ class GraphiqlPlugin implements NestModule {
 
 <div className="members-wrapper">
 
+### options
+
+<MemberInfo kind="property" type={`Required&#60;GraphiqlPluginOptions&#62;`}   />
+
+
 ### constructor
 
 <MemberInfo kind="method" type={`(processContext: <a href='/reference/typescript-api/common/process-context#processcontext'>ProcessContext</a>, configService: ConfigService, graphiQLService: GraphiQLService) => GraphiqlPlugin`}   />

+ 96 - 0
docs/docs/reference/core-plugins/telemetry-plugin/get-sdk-configuration.md

@@ -0,0 +1,96 @@
+---
+title: "GetSdkConfiguration"
+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';
+
+
+## getSdkConfiguration
+
+<GenerationInfo sourceFile="packages/telemetry-plugin/src/instrumentation.ts" sourceLine="89" packageName="@vendure/telemetry-plugin" />
+
+Creates a configuration object for the OpenTelemetry Node SDK. This is used to set up a custom
+preload script which must be run before the main Vendure server is loaded by means of the
+Node.js `--require` flag.
+
+*Example*
+
+```ts
+// instrumentation.ts
+import { OTLPLogExporter } from '@opentelemetry/exporter-logs-otlp-proto';
+import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';
+import { BatchLogRecordProcessor } from '@opentelemetry/sdk-logs';
+import { NodeSDK } from '@opentelemetry/sdk-node';
+import { BatchSpanProcessor } from '@opentelemetry/sdk-trace-base';
+import { getSdkConfiguration } from '@vendure/telemetry-plugin/preload';
+
+process.env.OTEL_EXPORTER_OTLP_ENDPOINT = 'http://localhost:3100/otlp';
+process.env.OTEL_LOGS_EXPORTER = 'otlp';
+process.env.OTEL_RESOURCE_ATTRIBUTES = 'service.name=vendure-dev-server';
+
+const traceExporter = new OTLPTraceExporter({
+    url: 'http://localhost:4318/v1/traces',
+});
+const logExporter = new OTLPLogExporter();
+
+const config = getSdkConfiguration({
+    config: {
+        spanProcessors: [new BatchSpanProcessor(traceExporter)],
+        logRecordProcessors: [new BatchLogRecordProcessor(logExporter)],
+    },
+});
+
+const sdk = new NodeSDK(config);
+
+sdk.start();
+```
+
+This would them be run as:
+```bash
+node --require ./dist/instrumentation.js ./dist/server.js
+```
+
+```ts title="Signature"
+function getSdkConfiguration(options?: SdkConfigurationOptions): Partial<NodeSDKConfiguration>
+```
+Parameters
+
+### options
+
+<MemberInfo kind="parameter" type={`<a href='/reference/core-plugins/telemetry-plugin/get-sdk-configuration#sdkconfigurationoptions'>SdkConfigurationOptions</a>`} />
+
+
+
+## SdkConfigurationOptions
+
+<GenerationInfo sourceFile="packages/telemetry-plugin/src/instrumentation.ts" sourceLine="27" packageName="@vendure/telemetry-plugin" />
+
+Options for configuring the OpenTelemetry Node SDK.
+
+```ts title="Signature"
+interface SdkConfigurationOptions {
+    logToConsole?: boolean;
+    config: Partial<NodeSDKConfiguration>;
+}
+```
+
+<div className="members-wrapper">
+
+### logToConsole
+
+<MemberInfo kind="property" type={`boolean`} default={`false`}   />
+
+When set to `true`, the SDK will log spans to the console instead of sending them to an
+exporter. This should just be used for debugging purposes.
+### config
+
+<MemberInfo kind="property" type={`Partial&#60;NodeSDKConfiguration&#62;`}   />
+
+The configuration object for the OpenTelemetry Node SDK.
+
+
+</div>

+ 130 - 0
docs/docs/reference/core-plugins/telemetry-plugin/index.md

@@ -0,0 +1,130 @@
+---
+title: "TelemetryPlugin"
+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';
+
+
+## TelemetryPlugin
+
+<GenerationInfo sourceFile="packages/telemetry-plugin/src/telemetry.plugin.ts" sourceLine="102" packageName="@vendure/telemetry-plugin" since="3.3.0" />
+
+The TelemetryPlugin is used to instrument the Vendure application and collect telemetry data using
+[OpenTelemetry](https://opentelemetry.io/).
+
+## Installation
+
+```
+npm install @vendure/telemetry-plugin
+```
+
+## Configuration
+
+The plugin is configured via the `TelemetryPlugin.init()` method. This method accepts an options object
+which defines the OtelLogger options and method hooks.
+
+*Example*
+
+```ts
+import { VendureConfig } from '@vendure/core';
+import { TelemetryPlugin, registerMethodHooks } from '@vendure/telemetry-plugin';
+
+export const config: VendureConfig = {
+  // ...
+  plugins: [
+    TelemetryPlugin.init({
+      loggerOptions: {
+        // Log to the console at the verbose level
+        console: LogLevel.Verbose,
+      },
+    }),
+  ],
+};
+```
+
+## Preloading the SDK
+
+In order to use the OpenTelemetry SDK, you must preload it before the Vendure server is started.
+This is done by using the `--require` flag when starting the server with a custom preload script.
+
+Create a file named `instrumentation.ts` in the root of your project and add the following code:
+
+```ts
+import { OTLPLogExporter } from '@opentelemetry/exporter-logs-otlp-proto';
+import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';
+import { BatchLogRecordProcessor } from '@opentelemetry/sdk-logs';
+import { NodeSDK } from '@opentelemetry/sdk-node';
+import { BatchSpanProcessor } from '@opentelemetry/sdk-trace-base';
+import { getSdkConfiguration } from '@vendure/telemetry-plugin/preload';
+
+// In this example we are using Loki as the OTLP endpoint for logging
+process.env.OTEL_EXPORTER_OTLP_ENDPOINT = 'http://localhost:3100/otlp';
+process.env.OTEL_LOGS_EXPORTER = 'otlp';
+process.env.OTEL_RESOURCE_ATTRIBUTES = 'service.name=vendure-dev-server';
+
+// We are using Jaeger as the OTLP endpoint for tracing
+const traceExporter = new OTLPTraceExporter({
+    url: 'http://localhost:4318/v1/traces',
+});
+const logExporter = new OTLPLogExporter();
+
+// The getSdkConfiguration method returns a configuration object for the OpenTelemetry Node SDK.
+// It also performs other configuration tasks such as setting a special environment variable
+// to enable instrumentation in the Vendure core code.
+const config = getSdkConfiguration({
+    config: {
+        // Pass in any custom configuration options for the Node SDK here
+        spanProcessors: [new BatchSpanProcessor(traceExporter)],
+        logRecordProcessors: [new BatchLogRecordProcessor(logExporter)],
+    },
+});
+
+const sdk = new NodeSDK(config);
+
+sdk.start();
+```
+
+The server would then be started with the following command:
+
+```bash
+node --require ./dist/instrumentation.js ./dist/server.js
+```
+
+or for development with ts-node:
+
+```bash
+npx ts-node --require ./src/instrumentation.ts ./src/server.ts
+```
+
+```ts title="Signature"
+class TelemetryPlugin {
+    static options: TelemetryPluginOptions = {};
+    constructor(methodHooksService: MethodHooksService, options: TelemetryPluginOptions)
+    init(options: TelemetryPluginOptions) => ;
+}
+```
+
+<div className="members-wrapper">
+
+### options
+
+<MemberInfo kind="property" type={`<a href='/reference/core-plugins/telemetry-plugin/telemetry-plugin-options#telemetrypluginoptions'>TelemetryPluginOptions</a>`}   />
+
+
+### constructor
+
+<MemberInfo kind="method" type={`(methodHooksService: MethodHooksService, options: <a href='/reference/core-plugins/telemetry-plugin/telemetry-plugin-options#telemetrypluginoptions'>TelemetryPluginOptions</a>) => TelemetryPlugin`}   />
+
+
+### init
+
+<MemberInfo kind="method" type={`(options: <a href='/reference/core-plugins/telemetry-plugin/telemetry-plugin-options#telemetrypluginoptions'>TelemetryPluginOptions</a>) => `}   />
+
+
+
+
+</div>

+ 50 - 0
docs/docs/reference/core-plugins/telemetry-plugin/register-method-hooks.md

@@ -0,0 +1,50 @@
+---
+title: "RegisterMethodHooks"
+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';
+
+
+## registerMethodHooks
+
+<GenerationInfo sourceFile="packages/telemetry-plugin/src/service/method-hooks.service.ts" sourceLine="60" packageName="@vendure/telemetry-plugin" since="3.3.0" />
+
+Allows you to register hooks for a specific method of an instrumented class.
+These hooks allow extra telemetry actions to be performed on the method.
+
+They can then be passed to the <a href='/reference/core-plugins/telemetry-plugin/#telemetryplugin'>TelemetryPlugin</a> via the <a href='/reference/core-plugins/telemetry-plugin/telemetry-plugin-options#telemetrypluginoptions'>TelemetryPluginOptions</a>.
+
+*Example*
+
+```typescript
+const productServiceHooks = registerMethodHooks(ProductService, {
+    findOne: {
+        // This will be called before the method is executed
+        pre: ({ args: [ctx, productId], span }) => {
+            span.setAttribute('productId', productId);
+        },
+        // This will be called after the method is executed
+        post: ({ result, span }) => {
+            span.setAttribute('found', !!result);
+        },
+    },
+});
+```
+
+```ts title="Signature"
+function registerMethodHooks<T>(target: Type<T>, hooks: MethodHooksForType<T>): MethodHookConfig<T>
+```
+Parameters
+
+### target
+
+<MemberInfo kind="parameter" type={`Type&#60;T&#62;`} />
+
+### hooks
+
+<MemberInfo kind="parameter" type={`MethodHooksForType&#60;T&#62;`} />
+

+ 77 - 0
docs/docs/reference/core-plugins/telemetry-plugin/telemetry-plugin-options.md

@@ -0,0 +1,77 @@
+---
+title: "TelemetryPluginOptions"
+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';
+
+
+## TelemetryPluginOptions
+
+<GenerationInfo sourceFile="packages/telemetry-plugin/src/types.ts" sourceLine="18" packageName="@vendure/telemetry-plugin" since="3.3.0" />
+
+Configuration options for the TelemetryPlugin.
+
+```ts title="Signature"
+interface TelemetryPluginOptions {
+    loggerOptions?: OtelLoggerOptions;
+    methodHooks?: Array<MethodHookConfig<any>>;
+}
+```
+
+<div className="members-wrapper">
+
+### loggerOptions
+
+<MemberInfo kind="property" type={`OtelLoggerOptions`}   />
+
+The options for the OtelLogger.
+
+For example, to also include logging to the console, you can use the following:
+```ts
+import { LogLevel } from '@vendure/core';
+import { TelemetryPlugin } from '@vendure/telemetry-plugin';
+
+TelemetryPlugin.init({
+    loggerOptions: {
+        console: LogLevel.Verbose,
+    },
+});
+```
+### methodHooks
+
+<MemberInfo kind="property" type={`Array&#60;MethodHookConfig&#60;any&#62;&#62;`}   />
+
+Method hooks allow you to add extra telemetry actions to specific methods.
+To define hooks on a method, use the <a href='/reference/core-plugins/telemetry-plugin/register-method-hooks#registermethodhooks'>registerMethodHooks</a> function.
+
+*Example*
+
+```ts
+import { TelemetryPlugin, registerMethodHooks } from '@vendure/telemetry-plugin';
+
+TelemetryPlugin.init({
+  methodHooks: [
+    registerMethodHooks(ProductService, {
+
+      // Define some hooks for the `findOne` method
+      findOne: {
+        // This will be called before the method is executed
+        pre: ({ args: [ctx, productId], span }) => {
+          span.setAttribute('productId', productId);
+        },
+        // This will be called after the method is executed
+        post: ({ result, span }) => {
+          span.setAttribute('found', !!result);
+        },
+      },
+    }),
+  ],
+});
+```
+
+
+</div>

+ 90 - 0
docs/docs/reference/dashboard/components/detail-page.md

@@ -0,0 +1,90 @@
+---
+title: "DetailPage"
+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';
+
+
+## DetailPage
+
+<GenerationInfo sourceFile="packages/dashboard/src/lib/framework/page/detail-page.tsx" sourceLine="90" packageName="@vendure/dashboard" since="3.3.0" />
+
+**Status: Developer Preview**
+
+Auto-generates a detail page with a form based on the provided query and mutation documents.
+
+For more control over the layout, you would use the more low-level <a href='/reference/dashboard/components/page#page'>Page</a> component.
+
+```ts title="Signature"
+function DetailPage<T extends TypedDocumentNode<any, any>, C extends TypedDocumentNode<any, any>, U extends TypedDocumentNode<any, any>>(props: DetailPageProps<T, C, U>): void
+```
+Parameters
+
+### props
+
+<MemberInfo kind="parameter" type={`<a href='/reference/dashboard/components/detail-page#detailpageprops'>DetailPageProps</a>&#60;T, C, U&#62;`} />
+
+
+
+## DetailPageProps
+
+<GenerationInfo sourceFile="packages/dashboard/src/lib/framework/page/detail-page.tsx" sourceLine="34" packageName="@vendure/dashboard" since="3.3.0" />
+
+**Status: Developer Preview**
+
+```ts title="Signature"
+interface DetailPageProps<T extends TypedDocumentNode<any, any>, C extends TypedDocumentNode<any, any>, U extends TypedDocumentNode<any, any>, EntityField extends keyof ResultOf<T> = DetailEntityPath<T>> {
+    pageId: string;
+    route: AnyRoute;
+    title: (entity: ResultOf<T>[EntityField]) => string;
+    queryDocument: T;
+    createDocument?: C;
+    updateDocument: U;
+    setValuesForUpdate: (entity: ResultOf<T>[EntityField]) => VariablesOf<U>['input'];
+}
+```
+
+<div className="members-wrapper">
+
+### pageId
+
+<MemberInfo kind="property" type={`string`}   />
+
+A unique identifier for the page.
+### route
+
+<MemberInfo kind="property" type={`AnyRoute`}   />
+
+The Tanstack Router route used to navigate to this page.
+### title
+
+<MemberInfo kind="property" type={`(entity: ResultOf&#60;T&#62;[EntityField]) =&#62; string`}   />
+
+The title of the page.
+### queryDocument
+
+<MemberInfo kind="property" type={`T`}   />
+
+The query document used to fetch the entity.
+### createDocument
+
+<MemberInfo kind="property" type={`C`}   />
+
+The mutation document used to create the entity.
+### updateDocument
+
+<MemberInfo kind="property" type={`U`}   />
+
+The mutation document used to update the entity.
+### setValuesForUpdate
+
+<MemberInfo kind="property" type={`(entity: ResultOf&#60;T&#62;[EntityField]) =&#62; VariablesOf&#60;U&#62;['input']`}   />
+
+A function that sets the values for the update input type based on the entity.
+
+
+</div>

+ 14 - 0
docs/docs/reference/dashboard/components/index.md

@@ -0,0 +1,14 @@
+---
+title: "Components"
+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 />

+ 148 - 0
docs/docs/reference/dashboard/components/list-page.md

@@ -0,0 +1,148 @@
+---
+title: "ListPage"
+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';
+
+
+## ListPage
+
+<GenerationInfo sourceFile="packages/dashboard/src/lib/framework/page/list-page.tsx" sourceLine="78" packageName="@vendure/dashboard" since="3.3.0" />
+
+**Status: Developer Preview**
+
+Auto-generates a list page with columns generated based on the provided query document fields.
+
+```ts title="Signature"
+function ListPage<T extends TypedDocumentNode<U, V>, U extends Record<string, any> = any, V extends ListQueryOptionsShape = ListQueryOptionsShape, AC extends AdditionalColumns<T> = AdditionalColumns<T>>(props: ListPageProps<T, U, V, AC>): void
+```
+Parameters
+
+### props
+
+<MemberInfo kind="parameter" type={`<a href='/reference/dashboard/components/list-page#listpageprops'>ListPageProps</a>&#60;T, U, V, AC&#62;`} />
+
+
+
+## ListPageProps
+
+<GenerationInfo sourceFile="packages/dashboard/src/lib/framework/page/list-page.tsx" sourceLine="42" packageName="@vendure/dashboard" since="3.3.0" />
+
+**Status: Developer Preview**
+
+```ts title="Signature"
+interface ListPageProps<T extends TypedDocumentNode<U, V>, U extends ListQueryShape, V extends ListQueryOptionsShape, AC extends AdditionalColumns<T>> {
+    pageId?: string;
+    route: AnyRoute | (() => AnyRoute);
+    title: string | React.ReactElement;
+    listQuery: T;
+    deleteMutation?: TypedDocumentNode<any, { id: string }>;
+    transformVariables?: (variables: V) => V;
+    onSearchTermChange?: (searchTerm: string) => NonNullable<V['options']>['filter'];
+    customizeColumns?: CustomizeColumnConfig<T>;
+    additionalColumns?: AC;
+    defaultColumnOrder?: (keyof ListQueryFields<T> | keyof AC)[];
+    defaultSort?: SortingState;
+    defaultVisibility?: Partial<Record<keyof ListQueryFields<T> | keyof AC, boolean>>;
+    children?: React.ReactNode;
+    facetedFilters?: FacetedFilterConfig<T>;
+    rowActions?: RowAction<ListQueryFields<T>>[];
+    transformData?: (data: any[]) => any[];
+    setTableOptions?: (table: TableOptions<any>) => TableOptions<any>;
+}
+```
+
+<div className="members-wrapper">
+
+### pageId
+
+<MemberInfo kind="property" type={`string`}   />
+
+
+### route
+
+<MemberInfo kind="property" type={`AnyRoute | (() =&#62; AnyRoute)`}   />
+
+
+### title
+
+<MemberInfo kind="property" type={`string | React.ReactElement`}   />
+
+
+### listQuery
+
+<MemberInfo kind="property" type={`T`}   />
+
+
+### deleteMutation
+
+<MemberInfo kind="property" type={`TypedDocumentNode&#60;any, { id: string }&#62;`}   />
+
+
+### transformVariables
+
+<MemberInfo kind="property" type={`(variables: V) =&#62; V`}   />
+
+
+### onSearchTermChange
+
+<MemberInfo kind="property" type={`(searchTerm: string) =&#62; NonNullable&#60;V['options']&#62;['filter']`}   />
+
+
+### customizeColumns
+
+<MemberInfo kind="property" type={`CustomizeColumnConfig&#60;T&#62;`}   />
+
+
+### additionalColumns
+
+<MemberInfo kind="property" type={`AC`}   />
+
+
+### defaultColumnOrder
+
+<MemberInfo kind="property" type={`(keyof ListQueryFields&#60;T&#62; | keyof AC)[]`}   />
+
+
+### defaultSort
+
+<MemberInfo kind="property" type={`SortingState`}   />
+
+
+### defaultVisibility
+
+<MemberInfo kind="property" type={`Partial&#60;Record&#60;keyof ListQueryFields&#60;T&#62; | keyof AC, boolean&#62;&#62;`}   />
+
+
+### children
+
+<MemberInfo kind="property" type={`React.ReactNode`}   />
+
+
+### facetedFilters
+
+<MemberInfo kind="property" type={`FacetedFilterConfig&#60;T&#62;`}   />
+
+
+### rowActions
+
+<MemberInfo kind="property" type={`RowAction&#60;ListQueryFields&#60;T&#62;&#62;[]`}   />
+
+
+### transformData
+
+<MemberInfo kind="property" type={`(data: any[]) =&#62; any[]`}   />
+
+
+### setTableOptions
+
+<MemberInfo kind="property" type={`(table: TableOptions&#60;any&#62;) =&#62; TableOptions&#60;any&#62;`}   />
+
+
+
+
+</div>

+ 64 - 0
docs/docs/reference/dashboard/components/page-action-bar.md

@@ -0,0 +1,64 @@
+---
+title: "PageActionBar"
+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';
+
+
+## PageActionBar
+
+<GenerationInfo sourceFile="packages/dashboard/src/lib/framework/layout-engine/page-layout.tsx" sourceLine="262" packageName="@vendure/dashboard" since="3.3.0" />
+
+**Status: Developer Preview**
+
+A component for displaying the main actions for a page. This should be used inside the <a href='/reference/dashboard/components/page#page'>Page</a> component.
+It should be used in conjunction with the <a href='/reference/dashboard/components/page-action-bar#pageactionbarleft'>PageActionBarLeft</a> and <a href='/reference/dashboard/components/page-action-bar#pageactionbarright'>PageActionBarRight</a> components
+as direct children.
+
+```ts title="Signature"
+function PageActionBar(props: { children: React.ReactNode }): void
+```
+Parameters
+
+### props
+
+<MemberInfo kind="parameter" type={`{ children: React.ReactNode }`} />
+
+
+
+## PageActionBarLeft
+
+<GenerationInfo sourceFile="packages/dashboard/src/lib/framework/layout-engine/page-layout.tsx" sourceLine="288" packageName="@vendure/dashboard" since="3.3.0" />
+
+**Status: Developer Preview**
+
+```ts title="Signature"
+function PageActionBarLeft(props: { children: React.ReactNode }): void
+```
+Parameters
+
+### props
+
+<MemberInfo kind="parameter" type={`{ children: React.ReactNode }`} />
+
+
+
+## PageActionBarRight
+
+<GenerationInfo sourceFile="packages/dashboard/src/lib/framework/layout-engine/page-layout.tsx" sourceLine="300" packageName="@vendure/dashboard" since="3.3.0" />
+
+**Status: Developer Preview**
+
+```ts title="Signature"
+function PageActionBarRight(props: { children: React.ReactNode }): void
+```
+Parameters
+
+### props
+
+<MemberInfo kind="parameter" type={`{ children: React.ReactNode }`} />
+

+ 127 - 0
docs/docs/reference/dashboard/components/page-block.md

@@ -0,0 +1,127 @@
+---
+title: "PageBlock"
+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';
+
+
+## PageBlock
+
+<GenerationInfo sourceFile="packages/dashboard/src/lib/framework/layout-engine/page-layout.tsx" sourceLine="352" packageName="@vendure/dashboard" since="3.3.0" />
+
+**Status: Developer Preview**
+
+A component for displaying a block of content on a page. This should be used inside the <a href='/reference/dashboard/components/page-layout#pagelayout'>PageLayout</a> component.
+It should be provided with a `column` prop to determine which column it should appear in, and a `blockId` prop
+to identify the block.
+
+```ts title="Signature"
+function PageBlock(props: PageBlockProps): void
+```
+Parameters
+
+### props
+
+<MemberInfo kind="parameter" type={`<a href='/reference/dashboard/components/page-block#pageblockprops'>PageBlockProps</a>`} />
+
+
+
+## PageBlockProps
+
+<GenerationInfo sourceFile="packages/dashboard/src/lib/framework/layout-engine/page-layout.tsx" sourceLine="329" packageName="@vendure/dashboard" since="3.3.0" />
+
+**Status: Developer Preview**
+
+```ts title="Signature"
+type PageBlockProps = {
+    children?: React.ReactNode;
+    column: 'main' | 'side';
+    blockId?: string;
+    title?: React.ReactNode | string;
+    description?: React.ReactNode | string;
+    className?: string;
+}
+```
+
+<div className="members-wrapper">
+
+### children
+
+<MemberInfo kind="property" type={`React.ReactNode`}   />
+
+
+### column
+
+<MemberInfo kind="property" type={`'main' | 'side'`}   />
+
+
+### blockId
+
+<MemberInfo kind="property" type={`string`}   />
+
+
+### title
+
+<MemberInfo kind="property" type={`React.ReactNode | string`}   />
+
+
+### description
+
+<MemberInfo kind="property" type={`React.ReactNode | string`}   />
+
+
+### className
+
+<MemberInfo kind="property" type={`string`}   />
+
+
+
+
+</div>
+
+
+## FullWidthPageBlock
+
+<GenerationInfo sourceFile="packages/dashboard/src/lib/framework/layout-engine/page-layout.tsx" sourceLine="379" packageName="@vendure/dashboard" since="3.3.0" />
+
+**Status: Developer Preview**
+
+A component for displaying a block of content on a page that takes up the full width of the page.
+This should be used inside the <a href='/reference/dashboard/components/page-layout#pagelayout'>PageLayout</a> component.
+
+```ts title="Signature"
+function FullWidthPageBlock(props: Pick<PageBlockProps, 'children' | 'className' | 'blockId'>): void
+```
+Parameters
+
+### props
+
+<MemberInfo kind="parameter" type={`Pick&#60;<a href='/reference/dashboard/components/page-block#pageblockprops'>PageBlockProps</a>, 'children' | 'className' | 'blockId'&#62;`} />
+
+
+
+## CustomFieldsPageBlock
+
+<GenerationInfo sourceFile="packages/dashboard/src/lib/framework/layout-engine/page-layout.tsx" sourceLine="401" packageName="@vendure/dashboard" since="3.3.0" />
+
+**Status: Developer Preview**
+
+A component for displaying an auto-generated form for custom fields on a page.
+
+```ts title="Signature"
+function CustomFieldsPageBlock(props: {
+    column: 'main' | 'side';
+    entityType: string;
+    control: Control<any, any>;
+}): void
+```
+Parameters
+
+### props
+
+<MemberInfo kind="parameter" type={`{     column: 'main' | 'side';     entityType: string;     control: Control&#60;any, any&#62;; }`} />
+

+ 59 - 0
docs/docs/reference/dashboard/components/page-layout.md

@@ -0,0 +1,59 @@
+---
+title: "PageLayout"
+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';
+
+
+## PageLayout
+
+<GenerationInfo sourceFile="packages/dashboard/src/lib/framework/layout-engine/page-layout.tsx" sourceLine="158" packageName="@vendure/dashboard" since="3.3.0" />
+
+**Status: Developer Preview**
+
+This component governs the layout of the contents of a <a href='/reference/dashboard/components/page#page'>Page</a> component.
+It should contain all the <a href='/reference/dashboard/components/page-block#pageblock'>PageBlock</a> components that are to be displayed on the page.
+
+```ts title="Signature"
+function PageLayout(props: PageLayoutProps): void
+```
+Parameters
+
+### props
+
+<MemberInfo kind="parameter" type={`<a href='/reference/dashboard/components/page-layout#pagelayoutprops'>PageLayoutProps</a>`} />
+
+
+
+## PageLayoutProps
+
+<GenerationInfo sourceFile="packages/dashboard/src/lib/framework/layout-engine/page-layout.tsx" sourceLine="128" packageName="@vendure/dashboard" since="3.3.0" />
+
+**Status: Developer Preview**
+
+```ts title="Signature"
+type PageLayoutProps = {
+    children: React.ReactNode;
+    className?: string;
+}
+```
+
+<div className="members-wrapper">
+
+### children
+
+<MemberInfo kind="property" type={`React.ReactNode`}   />
+
+
+### className
+
+<MemberInfo kind="property" type={`string`}   />
+
+
+
+
+</div>

+ 28 - 0
docs/docs/reference/dashboard/components/page-title.md

@@ -0,0 +1,28 @@
+---
+title: "PageTitle"
+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';
+
+
+## PageTitle
+
+<GenerationInfo sourceFile="packages/dashboard/src/lib/framework/layout-engine/page-layout.tsx" sourceLine="245" packageName="@vendure/dashboard" since="3.3.0" />
+
+**Status: Developer Preview**
+
+A component for displaying the title of a page. This should be used inside the <a href='/reference/dashboard/components/page#page'>Page</a> component.
+
+```ts title="Signature"
+function PageTitle(props: { children: React.ReactNode }): void
+```
+Parameters
+
+### props
+
+<MemberInfo kind="parameter" type={`{ children: React.ReactNode }`} />
+

+ 35 - 0
docs/docs/reference/dashboard/components/page.md

@@ -0,0 +1,35 @@
+---
+title: "Page"
+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';
+
+
+## Page
+
+<GenerationInfo sourceFile="packages/dashboard/src/lib/framework/layout-engine/page-layout.tsx" sourceLine="44" packageName="@vendure/dashboard" since="3.3.0" />
+
+**Status: Developer Preview**
+
+This component should be used to wrap _all_ pages in the dashboard. It provides
+a consistent layout as well as a context for the slot-based PageBlock system.
+
+The typical hierarchy of a page is as follows:
+- `Page`
+ - <a href='/reference/dashboard/components/page-title#pagetitle'>PageTitle</a>
+ - <a href='/reference/dashboard/components/page-action-bar#pageactionbar'>PageActionBar</a>
+ - <a href='/reference/dashboard/components/page-layout#pagelayout'>PageLayout</a>
+
+```ts title="Signature"
+function Page(props: PageProps): void
+```
+Parameters
+
+### props
+
+<MemberInfo kind="parameter" type={`PageProps`} />
+

+ 47 - 0
docs/docs/reference/dashboard/extensions/dashboard-action-bar-item.md

@@ -0,0 +1,47 @@
+---
+title: "DashboardActionBarItem"
+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';
+
+
+## DashboardActionBarItem
+
+<GenerationInfo sourceFile="packages/dashboard/src/lib/framework/extension-api/extension-api-types.ts" sourceLine="30" packageName="@vendure/dashboard" since="3.3.0" />
+
+**Status: Developer Preview**
+
+Allows you to define custom action bar items for any page in the dashboard.
+
+```ts title="Signature"
+interface DashboardActionBarItem {
+    pageId: string;
+    component: React.FunctionComponent<{ context: PageContextValue }>;
+    requiresPermission?: string | string[];
+}
+```
+
+<div className="members-wrapper">
+
+### pageId
+
+<MemberInfo kind="property" type={`string`}   />
+
+The ID of the page where the action bar item should be displayed.
+### component
+
+<MemberInfo kind="property" type={`React.FunctionComponent&#60;{ context: PageContextValue }&#62;`}   />
+
+A React component that will be rendered in the action bar.
+### requiresPermission
+
+<MemberInfo kind="property" type={`string | string[]`}   />
+
+Any permissions that are required to display this action bar item.
+
+
+</div>

+ 60 - 0
docs/docs/reference/dashboard/extensions/dashboard-extension.md

@@ -0,0 +1,60 @@
+---
+title: "DashboardExtension"
+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';
+
+
+## DashboardExtension
+
+<GenerationInfo sourceFile="packages/dashboard/src/lib/framework/extension-api/extension-api-types.ts" sourceLine="100" packageName="@vendure/dashboard" since="3.3.0" />
+
+**Status: Developer Preview**
+
+This is used to define the routes, widgets, etc. that will be displayed in the dashboard.
+
+```ts title="Signature"
+interface DashboardExtension {
+    routes?: DashboardRouteDefinition[];
+    pageBlocks?: DashboardPageBlockDefinition[];
+    actionBarItems?: DashboardActionBarItem[];
+    alerts?: DashboardAlertDefinition[];
+    widgets?: DashboardWidgetDefinition[];
+}
+```
+
+<div className="members-wrapper">
+
+### routes
+
+<MemberInfo kind="property" type={`DashboardRouteDefinition[]`}   />
+
+Allows you to define custom routes such as list or detail views.
+### pageBlocks
+
+<MemberInfo kind="property" type={`<a href='/reference/dashboard/extensions/dashboard-page-block-definition#dashboardpageblockdefinition'>DashboardPageBlockDefinition</a>[]`}   />
+
+Allows you to define custom page blocks for any page in the dashboard.
+### actionBarItems
+
+<MemberInfo kind="property" type={`<a href='/reference/dashboard/extensions/dashboard-action-bar-item#dashboardactionbaritem'>DashboardActionBarItem</a>[]`}   />
+
+Allows you to define custom action bar items for any page in the dashboard.
+### alerts
+
+<MemberInfo kind="property" type={`DashboardAlertDefinition[]`}   />
+
+Not yet implemented
+### widgets
+
+<MemberInfo kind="property" type={`DashboardWidgetDefinition[]`}   />
+
+Allows you to define custom routes for the dashboard, which will render the
+given components and optionally also add a nav menu item.
+
+
+</div>

+ 60 - 0
docs/docs/reference/dashboard/extensions/dashboard-page-block-definition.md

@@ -0,0 +1,60 @@
+---
+title: "DashboardPageBlockDefinition"
+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';
+
+
+## DashboardPageBlockDefinition
+
+<GenerationInfo sourceFile="packages/dashboard/src/lib/framework/extension-api/extension-api-types.ts" sourceLine="83" packageName="@vendure/dashboard" since="3.3.0" />
+
+**Status: Developer Preview**
+
+This allows you to insert a custom component into a specific location
+on any page in the dashboard.
+
+```ts title="Signature"
+interface DashboardPageBlockDefinition {
+    id: string;
+    title?: React.ReactNode;
+    location: PageBlockLocation;
+    component: React.FunctionComponent<{ context: PageContextValue }>;
+    requiresPermission?: string | string[];
+}
+```
+
+<div className="members-wrapper">
+
+### id
+
+<MemberInfo kind="property" type={`string`}   />
+
+
+### title
+
+<MemberInfo kind="property" type={`React.ReactNode`}   />
+
+
+### location
+
+<MemberInfo kind="property" type={`<a href='/reference/dashboard/extensions/page-block-location#pageblocklocation'>PageBlockLocation</a>`}   />
+
+
+### component
+
+<MemberInfo kind="property" type={`React.FunctionComponent&#60;{ context: PageContextValue }&#62;`}   />
+
+
+### requiresPermission
+
+<MemberInfo kind="property" type={`string | string[]`}   />
+
+
+
+
+</div>

+ 28 - 0
docs/docs/reference/dashboard/extensions/define-dashboard-extension.md

@@ -0,0 +1,28 @@
+---
+title: "DefineDashboardExtension"
+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';
+
+
+## defineDashboardExtension
+
+<GenerationInfo sourceFile="packages/dashboard/src/lib/framework/extension-api/define-dashboard-extension.ts" sourceLine="35" packageName="@vendure/dashboard" since="3.3.0" />
+
+**Status: Developer Preview**
+
+The main entry point for extensions to the React-based dashboard.
+
+```ts title="Signature"
+function defineDashboardExtension(extension: DashboardExtension): void
+```
+Parameters
+
+### extension
+
+<MemberInfo kind="parameter" type={`<a href='/reference/dashboard/extensions/dashboard-extension#dashboardextension'>DashboardExtension</a>`} />
+

+ 14 - 0
docs/docs/reference/dashboard/extensions/index.md

@@ -0,0 +1,14 @@
+---
+title: "Extensions"
+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 />

+ 49 - 0
docs/docs/reference/dashboard/extensions/page-block-location.md

@@ -0,0 +1,49 @@
+---
+title: "PageBlockLocation"
+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';
+
+
+## PageBlockLocation
+
+<GenerationInfo sourceFile="packages/dashboard/src/lib/framework/extension-api/extension-api-types.ts" sourceLine="67" packageName="@vendure/dashboard" since="3.3.0" />
+
+**Status: Developer Preview**
+
+The location of a page block in the dashboard. The location can be found by turning on
+"developer mode" in the dashboard user menu (bottom left corner) and then
+clicking the `< />` icon when hovering over a page block.
+
+```ts title="Signature"
+type PageBlockLocation = {
+    pageId: string;
+    position: PageBlockPosition;
+    column: 'main' | 'side';
+}
+```
+
+<div className="members-wrapper">
+
+### pageId
+
+<MemberInfo kind="property" type={`string`}   />
+
+
+### position
+
+<MemberInfo kind="property" type={`PageBlockPosition`}   />
+
+
+### column
+
+<MemberInfo kind="property" type={`'main' | 'side'`}   />
+
+
+
+
+</div>

+ 14 - 0
docs/docs/reference/dashboard/hooks/index.md

@@ -0,0 +1,14 @@
+---
+title: "Hooks"
+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 />

+ 83 - 0
docs/docs/reference/dashboard/hooks/use-auth.md

@@ -0,0 +1,83 @@
+---
+title: "UseAuth"
+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';
+
+
+## useAuth
+
+<GenerationInfo sourceFile="packages/dashboard/src/lib/hooks/use-auth.tsx" sourceLine="17" packageName="@vendure/dashboard" since="3.3.0" />
+
+**Status: Developer Preview**
+
+Provides access to the <a href='/reference/dashboard/hooks/use-channel#channelcontext'>ChannelContext</a> which contains information
+about the active channel.
+
+```ts title="Signature"
+function useAuth(): void
+```
+
+
+## AuthContext
+
+<GenerationInfo sourceFile="packages/dashboard/src/lib/providers/auth.tsx" sourceLine="17" packageName="@vendure/dashboard" since="3.3.0" />
+
+**Status: Developer Preview**
+
+```ts title="Signature"
+interface AuthContext {
+    status: 'authenticated' | 'verifying' | 'unauthenticated';
+    authenticationError?: string;
+    isAuthenticated: boolean;
+    login: (username: string, password: string, onSuccess?: () => void) => void;
+    logout: (onSuccess?: () => void) => Promise<void>;
+    user: ResultOf<typeof CurrentUserQuery>['activeAdministrator'] | undefined;
+    channels: NonNullable<ResultOf<typeof CurrentUserQuery>['me']>['channels'] | undefined;
+}
+```
+
+<div className="members-wrapper">
+
+### status
+
+<MemberInfo kind="property" type={`'authenticated' | 'verifying' | 'unauthenticated'`}   />
+
+
+### authenticationError
+
+<MemberInfo kind="property" type={`string`}   />
+
+
+### isAuthenticated
+
+<MemberInfo kind="property" type={`boolean`}   />
+
+
+### login
+
+<MemberInfo kind="property" type={`(username: string, password: string, onSuccess?: () =&#62; void) =&#62; void`}   />
+
+
+### logout
+
+<MemberInfo kind="property" type={`(onSuccess?: () =&#62; void) =&#62; Promise&#60;void&#62;`}   />
+
+
+### user
+
+<MemberInfo kind="property" type={`ResultOf&#60;typeof CurrentUserQuery&#62;['activeAdministrator'] | undefined`}   />
+
+
+### channels
+
+<MemberInfo kind="property" type={`NonNullable&#60;ResultOf&#60;typeof CurrentUserQuery&#62;['me']&#62;['channels'] | undefined`}   />
+
+
+
+
+</div>

+ 77 - 0
docs/docs/reference/dashboard/hooks/use-channel.md

@@ -0,0 +1,77 @@
+---
+title: "UseChannel"
+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';
+
+
+## useChannel
+
+<GenerationInfo sourceFile="packages/dashboard/src/lib/hooks/use-channel.ts" sourceLine="19" packageName="@vendure/dashboard" since="3.3.0" />
+
+**Status: Developer Preview**
+
+Provides access to the <a href='/reference/dashboard/hooks/use-channel#channelcontext'>ChannelContext</a> which contains information
+about the active channel.
+
+```ts title="Signature"
+function useChannel(): void
+```
+
+
+## ChannelContext
+
+<GenerationInfo sourceFile="packages/dashboard/src/lib/providers/channel-provider.tsx" sourceLine="52" packageName="@vendure/dashboard" since="3.3.0" />
+
+**Status: Developer Preview**
+
+```ts title="Signature"
+interface ChannelContext {
+    activeChannel: ActiveChannel | undefined;
+    channels: Channel[];
+    selectedChannelId: string | undefined;
+    selectedChannel: Channel | undefined;
+    isLoading: boolean;
+    setSelectedChannel: (channelId: string) => void;
+}
+```
+
+<div className="members-wrapper">
+
+### activeChannel
+
+<MemberInfo kind="property" type={`ActiveChannel | undefined`}   />
+
+
+### channels
+
+<MemberInfo kind="property" type={`<a href='/reference/typescript-api/entities/channel#channel'>Channel</a>[]`}   />
+
+
+### selectedChannelId
+
+<MemberInfo kind="property" type={`string | undefined`}   />
+
+
+### selectedChannel
+
+<MemberInfo kind="property" type={`<a href='/reference/typescript-api/entities/channel#channel'>Channel</a> | undefined`}   />
+
+
+### isLoading
+
+<MemberInfo kind="property" type={`boolean`}   />
+
+
+### setSelectedChannel
+
+<MemberInfo kind="property" type={`(channelId: string) =&#62; void`}   />
+
+
+
+
+</div>

+ 221 - 0
docs/docs/reference/dashboard/hooks/use-detail-page.md

@@ -0,0 +1,221 @@
+---
+title: "UseDetailPage"
+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';
+
+
+## useDetailPage
+
+<GenerationInfo sourceFile="packages/dashboard/src/lib/framework/page/use-detail-page.ts" sourceLine="216" packageName="@vendure/dashboard" since="3.3.0" />
+
+**Status: Developer Preview**
+
+This hook is used to create an entity detail page which can read
+and update an entity.
+
+*Example*
+
+```ts
+const { form, submitHandler, entity, isPending, resetForm } = useDetailPage({
+    queryDocument: paymentMethodDetailDocument,
+    createDocument: createPaymentMethodDocument,
+    updateDocument: updatePaymentMethodDocument,
+    setValuesForUpdate: entity => {
+        return {
+            id: entity.id,
+            enabled: entity.enabled,
+            name: entity.name,
+            code: entity.code,
+            description: entity.description,
+            checker: entity.checker?.code
+                ? {
+                      code: entity.checker?.code,
+                      arguments: entity.checker?.args,
+                  }
+                : null,
+            handler: entity.handler?.code
+                ? {
+                      code: entity.handler?.code,
+                      arguments: entity.handler?.args,
+                  }
+                : null,
+            translations: entity.translations.map(translation => ({
+                id: translation.id,
+                languageCode: translation.languageCode,
+                name: translation.name,
+                description: translation.description,
+            })),
+            customFields: entity.customFields,
+        };
+    },
+    transformCreateInput: input => {
+        return {
+            ...input,
+            checker: input.checker?.code ? input.checker : undefined,
+            handler: input.handler,
+        };
+    },
+    params: { id: params.id },
+    onSuccess: async data => {
+        toast.success(i18n.t('Successfully updated payment method'));
+        resetForm();
+        if (creatingNewEntity) {
+            await navigate({ to: `../$id`, params: { id: data.id } });
+        }
+    },
+    onError: err => {
+        toast.error(i18n.t('Failed to update payment method'), {
+            description: err instanceof Error ? err.message : 'Unknown error',
+        });
+    },
+});
+```
+
+```ts title="Signature"
+function useDetailPage<T extends TypedDocumentNode<any, any>, C extends TypedDocumentNode<any, any>, U extends TypedDocumentNode<any, any>, EntityField extends keyof ResultOf<T> = keyof ResultOf<T>, VarNameUpdate extends keyof VariablesOf<U> = 'input', VarNameCreate extends keyof VariablesOf<C> = 'input'>(options: DetailPageOptions<T, C, U, EntityField, VarNameCreate, VarNameUpdate>): UseDetailPageResult<T, C, U, EntityField>
+```
+Parameters
+
+### options
+
+<MemberInfo kind="parameter" type={`<a href='/reference/dashboard/hooks/use-detail-page#detailpageoptions'>DetailPageOptions</a>&#60;T, C, U, EntityField, VarNameCreate, VarNameUpdate&#62;`} />
+
+
+
+## DetailPageOptions
+
+<GenerationInfo sourceFile="packages/dashboard/src/lib/framework/page/use-detail-page.ts" sourceLine="37" packageName="@vendure/dashboard" since="3.3.0" />
+
+**Status: Developer Preview**
+
+```ts title="Signature"
+interface DetailPageOptions<T extends TypedDocumentNode<any, any>, C extends TypedDocumentNode<any, any>, U extends TypedDocumentNode<any, any>, EntityField extends keyof ResultOf<T> = DetailEntityPath<T>, VarNameCreate extends keyof VariablesOf<C> = 'input', VarNameUpdate extends keyof VariablesOf<U> = 'input'> {
+    queryDocument: T;
+    entityField?: EntityField;
+    params: {
+        id: string;
+    };
+    createDocument?: C;
+    updateDocument?: U;
+    setValuesForUpdate: (entity: NonNullable<ResultOf<T>[EntityField]>) => VariablesOf<U>[VarNameUpdate];
+    transformCreateInput?: (input: VariablesOf<C>[VarNameCreate]) => VariablesOf<C>[VarNameCreate];
+    transformUpdateInput?: (input: VariablesOf<U>[VarNameUpdate]) => VariablesOf<U>[VarNameUpdate];
+    onSuccess?: (entity: ResultOf<C>[keyof ResultOf<C>] | ResultOf<U>[keyof ResultOf<U>]) => void;
+    onError?: (error: unknown) => void;
+}
+```
+
+<div className="members-wrapper">
+
+### queryDocument
+
+<MemberInfo kind="property" type={`T`}   />
+
+The query document to fetch the entity.
+### entityField
+
+<MemberInfo kind="property" type={`EntityField`}   />
+
+The field of the query document that contains the entity.
+### params
+
+<MemberInfo kind="property" type={`{         id: string;     }`}   />
+
+The parameters used to identify the entity.
+### createDocument
+
+<MemberInfo kind="property" type={`C`}   />
+
+The document to create the entity.
+### updateDocument
+
+<MemberInfo kind="property" type={`U`}   />
+
+The document to update the entity.
+### setValuesForUpdate
+
+<MemberInfo kind="property" type={`(entity: NonNullable&#60;ResultOf&#60;T&#62;[EntityField]&#62;) =&#62; VariablesOf&#60;U&#62;[VarNameUpdate]`}   />
+
+The function to set the values for the update document.
+### transformCreateInput
+
+<MemberInfo kind="property" type={`(input: VariablesOf&#60;C&#62;[VarNameCreate]) =&#62; VariablesOf&#60;C&#62;[VarNameCreate]`}   />
+
+
+### transformUpdateInput
+
+<MemberInfo kind="property" type={`(input: VariablesOf&#60;U&#62;[VarNameUpdate]) =&#62; VariablesOf&#60;U&#62;[VarNameUpdate]`}   />
+
+
+### onSuccess
+
+<MemberInfo kind="property" type={`(entity: ResultOf&#60;C&#62;[keyof ResultOf&#60;C&#62;] | ResultOf&#60;U&#62;[keyof ResultOf&#60;U&#62;]) =&#62; void`}   />
+
+The function to call when the update is successful.
+### onError
+
+<MemberInfo kind="property" type={`(error: unknown) =&#62; void`}   />
+
+The function to call when the update is successful.
+
+
+</div>
+
+
+## UseDetailPageResult
+
+<GenerationInfo sourceFile="packages/dashboard/src/lib/framework/page/use-detail-page.ts" sourceLine="133" packageName="@vendure/dashboard" since="3.3.0" />
+
+**Status: Developer Preview**
+
+```ts title="Signature"
+interface UseDetailPageResult<T extends TypedDocumentNode<any, any>, C extends TypedDocumentNode<any, any>, U extends TypedDocumentNode<any, any>, EntityField extends keyof ResultOf<T>> {
+    form: UseFormReturn<RemoveNullFields<VariablesOf<U>['input']>>;
+    submitHandler: (event: FormEvent<HTMLFormElement>) => void;
+    entity?: DetailPageEntity<T, EntityField>;
+    isPending: boolean;
+    refreshEntity: () => void;
+    resetForm: () => void;
+}
+```
+
+<div className="members-wrapper">
+
+### form
+
+<MemberInfo kind="property" type={`UseFormReturn&#60;RemoveNullFields&#60;VariablesOf&#60;U&#62;['input']&#62;&#62;`}   />
+
+
+### submitHandler
+
+<MemberInfo kind="property" type={`(event: FormEvent&#60;HTMLFormElement&#62;) =&#62; void`}   />
+
+
+### entity
+
+<MemberInfo kind="property" type={`DetailPageEntity&#60;T, EntityField&#62;`}   />
+
+
+### isPending
+
+<MemberInfo kind="property" type={`boolean`}   />
+
+
+### refreshEntity
+
+<MemberInfo kind="property" type={`() =&#62; void`}   />
+
+
+### resetForm
+
+<MemberInfo kind="property" type={`() =&#62; void`}   />
+
+
+
+
+</div>

+ 34 - 0
docs/docs/reference/dashboard/hooks/use-local-format.md

@@ -0,0 +1,34 @@
+---
+title: "UseLocalFormat"
+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';
+
+
+## useLocalFormat
+
+<GenerationInfo sourceFile="packages/dashboard/src/lib/hooks/use-local-format.ts" sourceLine="26" packageName="@vendure/dashboard" />
+
+This hook is used to format numbers and currencies using the configured language and
+locale of the dashboard app.
+
+*Example*
+
+```ts
+const {
+         formatCurrency,
+         formatNumber,
+         formatDate,
+         formatLanguageName,
+         formatCurrencyName,
+         toMajorUnits,
+} = useLocalFormat();
+```
+
+```ts title="Signature"
+function useLocalFormat(): void
+```

+ 23 - 0
docs/docs/reference/dashboard/hooks/use-permissions.md

@@ -0,0 +1,23 @@
+---
+title: "UsePermissions"
+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';
+
+
+## usePermissions
+
+<GenerationInfo sourceFile="packages/dashboard/src/lib/hooks/use-permissions.ts" sourceLine="19" packageName="@vendure/dashboard" since="3.3.0" />
+
+**Status: Developer Preview**
+
+Returns a `hasPermissions` function that can be used to determine whether the active user
+has the given permissions on the active channel.
+
+```ts title="Signature"
+function usePermissions(): void
+```

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

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

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

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

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

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

+ 3 - 3
docs/docs/reference/typescript-api/auth/default-password-validation-strategy.md

@@ -14,7 +14,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 <GenerationInfo sourceFile="packages/core/src/config/auth/default-password-validation-strategy.ts" sourceLine="18" packageName="@vendure/core" since="1.5.0" />
 
 The DefaultPasswordValidationStrategy allows you to specify a minimum length and/or
-a regular expression to match passwords against.
+a regular expression to match passwords against. The default `maxLength` is `72`.
 
 TODO:
 By default, the `minLength` will be set to `4`. This is rather permissive and is only
@@ -23,7 +23,7 @@ this default will be made more strict.
 
 ```ts title="Signature"
 class DefaultPasswordValidationStrategy implements PasswordValidationStrategy {
-    constructor(options: { minLength?: number; regexp?: RegExp })
+    constructor(options: { minLength?: number; maxLength?: number; regexp?: RegExp })
     validate(ctx: RequestContext, password: string) => boolean | string;
 }
 ```
@@ -35,7 +35,7 @@ class DefaultPasswordValidationStrategy implements PasswordValidationStrategy {
 
 ### constructor
 
-<MemberInfo kind="method" type={`(options: { minLength?: number; regexp?: RegExp }) => DefaultPasswordValidationStrategy`}   />
+<MemberInfo kind="method" type={`(options: { minLength?: number; maxLength?: number; regexp?: RegExp }) => DefaultPasswordValidationStrategy`}   />
 
 
 ### validate

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

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

+ 1 - 1
docs/docs/reference/typescript-api/cache/cache-service.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## CacheService
 
-<GenerationInfo sourceFile="packages/core/src/cache/cache.service.ts" sourceLine="20" packageName="@vendure/core" since="3.1.0" />
+<GenerationInfo sourceFile="packages/core/src/cache/cache.service.ts" sourceLine="21" packageName="@vendure/core" since="3.1.0" />
 
 The CacheService is used to cache data in order to optimize performance.
 

+ 1 - 1
docs/docs/reference/typescript-api/cache/sql-cache-strategy.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## SqlCacheStrategy
 
-<GenerationInfo sourceFile="packages/core/src/plugin/default-cache-plugin/sql-cache-strategy.ts" sourceLine="20" packageName="@vendure/core" since="3.1.0" />
+<GenerationInfo sourceFile="packages/core/src/plugin/default-cache-plugin/sql-cache-strategy.ts" sourceLine="21" packageName="@vendure/core" since="3.1.0" />
 
 A <a href='/reference/typescript-api/cache/cache-strategy#cachestrategy'>CacheStrategy</a> that stores cached items in the database. This
 is the strategy used by the <a href='/reference/typescript-api/cache/default-cache-plugin#defaultcacheplugin'>DefaultCachePlugin</a>.

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

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

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

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

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

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

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

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

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

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## SystemOptions
 
-<GenerationInfo sourceFile="packages/core/src/config/vendure-config.ts" sourceLine="1102" packageName="@vendure/core" since="1.6.0" />
+<GenerationInfo sourceFile="packages/core/src/config/vendure-config.ts" sourceLine="1103" packageName="@vendure/core" since="1.6.0" />
 
 Options relating to system functions.
 
@@ -20,6 +20,7 @@ interface SystemOptions {
     healthChecks?: HealthCheckStrategy[];
     errorHandlers?: ErrorHandlerStrategy[];
     cacheStrategy?: CacheStrategy;
+    instrumentationStrategy?: InstrumentationStrategy;
 }
 ```
 
@@ -43,6 +44,11 @@ when an error occurs, either on the server or the worker.
 
 Defines the underlying method used to store cache key-value pairs which powers the
 <a href='/reference/typescript-api/cache/cache-service#cacheservice'>CacheService</a>.
+### instrumentationStrategy
+
+<MemberInfo kind="property" type={`<a href='/reference/typescript-api/telemetry/instrumentation-strategy#instrumentationstrategy'>InstrumentationStrategy</a>`}   />
+
+
 
 
 </div>

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

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

+ 2 - 2
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="200" 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:
@@ -121,7 +121,7 @@ to join that relation.
 
 ## ExtendedListQueryOptions
 
-<GenerationInfo sourceFile="packages/core/src/service/helpers/list-query-builder/list-query-builder.ts" sourceLine="41" 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.
 

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

@@ -11,7 +11,7 @@ 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" />
+<GenerationInfo sourceFile="packages/core/src/event-bus/event-bus.ts" sourceLine="23" packageName="@vendure/core" since="2.2.0" />
 
 Options for registering a blocking event handler.
 

+ 1 - 1
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="97" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/event-bus/event-bus.ts" sourceLine="98" packageName="@vendure/core" />
 
 The EventBus is used to globally publish events which can then be subscribed to.
 

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

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

+ 50 - 2
docs/docs/reference/typescript-api/job-queue/default-job-queue-plugin.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## DefaultJobQueuePlugin
 
-<GenerationInfo sourceFile="packages/core/src/plugin/default-job-queue-plugin/default-job-queue-plugin.ts" sourceLine="183" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/plugin/default-job-queue-plugin/default-job-queue-plugin.ts" sourceLine="127" packageName="@vendure/core" />
 
 A plugin which configures Vendure to use the SQL database to persist the JobQueue jobs using the <a href='/reference/typescript-api/job-queue/sql-job-queue-strategy#sqljobqueuestrategy'>SqlJobQueueStrategy</a>. If you add this
 plugin to an existing Vendure installation, you'll need to run a [database migration](/guides/developer-guide/migrations), since this
@@ -101,6 +101,29 @@ export const config: VendureConfig = {
 };
 ```
 
+### Removing old jobs
+Since v3.3, the job queue will automatically remove old jobs from the database. This is done by a scheduled task
+which runs every 2 hours by default. The number of jobs to keep in the database can be configured using the
+`keepJobsCount` option. The default is 1000.
+
+*Example*
+
+```ts
+export const config: VendureConfig = {
+  plugins: [
+    DefaultJobQueuePlugin.init({
+      // The number of completed/failed/cancelled
+      // jobs to keep in the database. The default is 1000.
+      keepJobsCount: 100,
+      // The interval at which to run the clean-up task.
+      // This can be a standard cron expression or a function
+      // that returns a cron expression. The default is every 2 hours.
+      cleanJobsSchedule: cron => cron.every(5).hours(),
+    }),
+  ],
+};
+```
+
 ```ts title="Signature"
 class DefaultJobQueuePlugin {
     init(options: DefaultJobQueueOptions) => Type<DefaultJobQueuePlugin>;
@@ -119,9 +142,18 @@ class DefaultJobQueuePlugin {
 </div>
 
 
+## cleanJobsTask
+
+<GenerationInfo sourceFile="packages/core/src/plugin/default-job-queue-plugin/clean-jobs-task.ts" sourceLine="18" packageName="@vendure/core" since="3.3.0" />
+
+A <a href='/reference/typescript-api/scheduled-tasks/scheduled-task#scheduledtask'>ScheduledTask</a> that cleans up old jobs from the database when using the DefaultJobQueuePlugin.
+You can configure the settings & schedule of the task via the <a href='/reference/typescript-api/job-queue/default-job-queue-plugin#defaultjobqueueplugin'>DefaultJobQueuePlugin</a> options.
+
+
+
 ## DefaultJobQueueOptions
 
-<GenerationInfo sourceFile="packages/core/src/plugin/default-job-queue-plugin/default-job-queue-plugin.ts" sourceLine="21" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/plugin/default-job-queue-plugin/types.ts" sourceLine="12" packageName="@vendure/core" />
 
 Configuration options for the DefaultJobQueuePlugin. These values get passed into the
 <a href='/reference/typescript-api/job-queue/sql-job-queue-strategy#sqljobqueuestrategy'>SqlJobQueueStrategy</a>.
@@ -134,6 +166,8 @@ interface DefaultJobQueueOptions {
     setRetries?: (queueName: string, job: Job) => number;
     useDatabaseForBuffer?: boolean;
     gracefulShutdownTimeout?: number;
+    keepJobsCount?: number;
+    cleanJobsSchedule?: ScheduledTaskConfig['schedule'];
 }
 ```
 
@@ -196,6 +230,20 @@ That means when the server is shut down but a job is running, the job queue will
 wait for the job to complete before allowing the server to shut down. If the job
 does not complete within this timeout window, the job will be forced to stop
 and the server will shut down anyway.
+### keepJobsCount
+
+<MemberInfo kind="property" type={`number`} default={`1000`}  since="3.3.0"  />
+
+The number of completed/failed jobs to keep in the database. This is useful for
+debugging and auditing purposes, but if you have a lot of jobs, it may be
+desirable to limit the number of records in the database.
+### cleanJobsSchedule
+
+<MemberInfo kind="property" type={`<a href='/reference/typescript-api/scheduled-tasks/scheduled-task#scheduledtaskconfig'>ScheduledTaskConfig</a>['schedule']`} default={`cron =&#62; cron.every(2).hours()`}  since="3.3.0"  />
+
+The schedule for the "clean-jobs" task. This task will run periodically to clean up
+old jobs from the database. The schedule can be a cron expression or a function
+that returns a cron expression.
 
 
 </div>

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

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## JobQueue
 
-<GenerationInfo sourceFile="packages/core/src/job-queue/job-queue.ts" sourceLine="25" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/job-queue/job-queue.ts" sourceLine="21" packageName="@vendure/core" />
 
 A JobQueue is used to process <a href='/reference/typescript-api/job-queue/job#job'>Job</a>s. A job is added to the queue via the
 `.add()` method, and the configured <a href='/reference/typescript-api/job-queue/job-queue-strategy#jobqueuestrategy'>JobQueueStrategy</a> will check for new jobs and process each

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

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

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

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## JobQueueService
 
-<GenerationInfo sourceFile="packages/core/src/job-queue/job-queue.service.ts" sourceLine="48" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/job-queue/job-queue.service.ts" sourceLine="49" packageName="@vendure/core" />
 
 The JobQueueService is used to create new <a href='/reference/typescript-api/job-queue/#jobqueue'>JobQueue</a> instances and access
 existing jobs.

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

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

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

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

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

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## CatalogOptions
 
-<GenerationInfo sourceFile="packages/core/src/config/vendure-config.ts" sourceLine="699" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/config/vendure-config.ts" sourceLine="700" packageName="@vendure/core" />
 
 Options related to products and collections.
 

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

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

+ 1 - 1
docs/docs/reference/typescript-api/scheduled-tasks/clean-sessions-task.md

@@ -13,7 +13,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 <GenerationInfo sourceFile="packages/core/src/scheduler/tasks/clean-sessions-task.ts" sourceLine="37" packageName="@vendure/core" since="3.3.0" />
 
-A scheduled task that cleans expired & inactive sessions from the database.
+A <a href='/reference/typescript-api/scheduled-tasks/scheduled-task#scheduledtask'>ScheduledTask</a> that cleans expired & inactive sessions from the database.
 
 *Example*
 

+ 42 - 6
docs/docs/reference/typescript-api/scheduled-tasks/scheduled-task.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## ScheduledTask
 
-<GenerationInfo sourceFile="packages/core/src/scheduler/scheduled-task.ts" sourceLine="90" packageName="@vendure/core" since="3.3.0" />
+<GenerationInfo sourceFile="packages/core/src/scheduler/scheduled-task.ts" sourceLine="120" packageName="@vendure/core" since="3.3.0" />
 
 Use this class to define a scheduled task that will be executed at a given cron schedule.
 
@@ -23,7 +23,7 @@ import { ScheduledTask } from '@vendure/core';
 const task = new ScheduledTask({
     id: 'test-job',
     schedule: cron => cron.every(2).minutes(),
-    execute: async (injector, params) => {
+    execute: async ({ injector, scheduledContext, params }) => {
         // some logic here
     },
 });
@@ -76,7 +76,7 @@ import { ScheduledTask } from '@vendure/core';
 const task = new ScheduledTask({
     id: 'test-job',
     schedule: cron => cron.every(2).minutes(),
-    execute: async (injector, params) => {
+    execute: async ({ injector, scheduledContext, params }) => {
         // some logic here
     },
 });
@@ -89,9 +89,45 @@ task.configure({ schedule: cron => cron.every(5).minutes() });
 </div>
 
 
+## ScheduledTaskExecutionArgs
+
+<GenerationInfo sourceFile="packages/core/src/scheduler/scheduled-task.ts" sourceLine="16" packageName="@vendure/core" since="3.3.0" />
+
+The arguments passed to the execute method of a scheduled task.
+
+```ts title="Signature"
+interface ScheduledTaskExecutionArgs<C extends Record<string, any> = Record<string, any>> {
+    injector: Injector;
+    scheduledContext: RequestContext;
+    params: C;
+}
+```
+
+<div className="members-wrapper">
+
+### injector
+
+<MemberInfo kind="property" type={`<a href='/reference/typescript-api/common/injector#injector'>Injector</a>`}   />
+
+The injector instance.
+### scheduledContext
+
+<MemberInfo kind="property" type={`<a href='/reference/typescript-api/request/request-context#requestcontext'>RequestContext</a>`}   />
+
+A RequestContext instance that is configured for the scheduled task.
+### params
+
+<MemberInfo kind="property" type={`C`}   />
+
+The parameters for the scheduled task.
+
+
+</div>
+
+
 ## ScheduledTaskConfig
 
-<GenerationInfo sourceFile="packages/core/src/scheduler/scheduled-task.ts" sourceLine="12" packageName="@vendure/core" since="3.3.0" />
+<GenerationInfo sourceFile="packages/core/src/scheduler/scheduled-task.ts" sourceLine="42" packageName="@vendure/core" since="3.3.0" />
 
 The configuration for a scheduled task.
 
@@ -103,7 +139,7 @@ interface ScheduledTaskConfig<C extends Record<string, any> = Record<string, any
     schedule: string | ((cronTime: typeof CronTime) => string);
     timeout?: number | string;
     preventOverlap?: boolean;
-    execute(injector: Injector, config: C): Promise<any>;
+    execute(args: ScheduledTaskExecutionArgs<C>): Promise<any>;
 }
 ```
 
@@ -156,7 +192,7 @@ will be considered to have failed with a timeout error.
 Whether the scheduled task should be prevented from running if it is already running.
 ### execute
 
-<MemberInfo kind="method" type={`(injector: <a href='/reference/typescript-api/common/injector#injector'>Injector</a>, config: C) => Promise&#60;any&#62;`}   />
+<MemberInfo kind="method" type={`(args: <a href='/reference/typescript-api/scheduled-tasks/scheduled-task#scheduledtaskexecutionargs'>ScheduledTaskExecutionArgs</a>&#60;C&#62;) => Promise&#60;any&#62;`}   />
 
 The function that will be executed when the scheduled task is run.
 

+ 1 - 1
docs/docs/reference/typescript-api/scheduled-tasks/scheduler-options.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## SchedulerOptions
 
-<GenerationInfo sourceFile="packages/core/src/config/vendure-config.ts" sourceLine="976" packageName="@vendure/core" since="3.3.0" />
+<GenerationInfo sourceFile="packages/core/src/config/vendure-config.ts" sourceLine="977" packageName="@vendure/core" since="3.3.0" />
 
 Options related to scheduled tasks..
 

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

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## OrderCalculator
 
-<GenerationInfo sourceFile="packages/core/src/service/helpers/order-calculator/order-calculator.ts" sourceLine="34" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/service/helpers/order-calculator/order-calculator.ts" sourceLine="35" packageName="@vendure/core" />
 
 This helper is used when making changes to an Order, to apply all applicable price adjustments to that Order,
 including:

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

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## OrderModifier
 
-<GenerationInfo sourceFile="packages/core/src/service/helpers/order-modifier/order-modifier.ts" sourceLine="82" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/service/helpers/order-modifier/order-modifier.ts" sourceLine="83" packageName="@vendure/core" />
 
 This helper is responsible for modifying the contents of an Order.
 

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

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

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

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## AssetService
 
-<GenerationInfo sourceFile="packages/core/src/service/services/asset.service.ts" sourceLine="90" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/service/services/asset.service.ts" sourceLine="91" packageName="@vendure/core" />
 
 Contains methods relating to <a href='/reference/typescript-api/entities/asset#asset'>Asset</a> entities.
 
@@ -119,7 +119,7 @@ Create an Asset from a file stream, for example to create an Asset during data i
 
 ## EntityWithAssets
 
-<GenerationInfo sourceFile="packages/core/src/service/services/asset.service.ts" sourceLine="66" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/service/services/asset.service.ts" sourceLine="67" packageName="@vendure/core" />
 
 Certain entities (Product, ProductVariant, Collection) use this interface
 to model a featured asset and then a list of assets with a defined order.
@@ -153,7 +153,7 @@ interface EntityWithAssets extends VendureEntity {
 
 ## EntityAssetInput
 
-<GenerationInfo sourceFile="packages/core/src/service/services/asset.service.ts" sourceLine="78" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/service/services/asset.service.ts" sourceLine="79" packageName="@vendure/core" />
 
 Used when updating entities which implement <a href='/reference/typescript-api/services/asset-service#entitywithassets'>EntityWithAssets</a>.
 

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

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## AuthService
 
-<GenerationInfo sourceFile="packages/core/src/service/services/auth.service.ts" sourceLine="36" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/service/services/auth.service.ts" sourceLine="37" packageName="@vendure/core" />
 
 Contains methods relating to <a href='/reference/typescript-api/entities/session#session'>Session</a>, <a href='/reference/typescript-api/entities/authenticated-session#authenticatedsession'>AuthenticatedSession</a> & <a href='/reference/typescript-api/entities/anonymous-session#anonymoussession'>AnonymousSession</a> entities.
 

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

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

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

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## CustomerGroupService
 
-<GenerationInfo sourceFile="packages/core/src/service/services/customer-group.service.ts" sourceLine="37" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/service/services/customer-group.service.ts" sourceLine="38" packageName="@vendure/core" />
 
 Contains methods relating to <a href='/reference/typescript-api/entities/customer-group#customergroup'>CustomerGroup</a> entities.
 

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

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## FacetValueService
 
-<GenerationInfo sourceFile="packages/core/src/service/services/facet-value.service.ts" sourceLine="39" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/service/services/facet-value.service.ts" sourceLine="40" packageName="@vendure/core" />
 
 Contains methods relating to <a href='/reference/typescript-api/entities/facet-value#facetvalue'>FacetValue</a> entities.
 

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

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## GlobalSettingsService
 
-<GenerationInfo sourceFile="packages/core/src/service/services/global-settings.service.ts" sourceLine="22" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/service/services/global-settings.service.ts" sourceLine="23" packageName="@vendure/core" />
 
 Contains methods relating to the <a href='/reference/typescript-api/entities/global-settings#globalsettings'>GlobalSettings</a> entity.
 

+ 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="139" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/service/services/order.service.ts" sourceLine="140" packageName="@vendure/core" />
 
 Contains methods relating to <a href='/reference/typescript-api/entities/order#order'>Order</a> entities.
 

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

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## OrderTestingService
 
-<GenerationInfo sourceFile="packages/core/src/service/services/order-testing.service.ts" sourceLine="34" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/service/services/order-testing.service.ts" sourceLine="35" packageName="@vendure/core" />
 
 This service is responsible for creating temporary mock Orders against which tests can be run, such as
 testing a ShippingMethod or Promotion.

+ 1 - 1
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="46" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/service/services/payment-method.service.ts" sourceLine="47" packageName="@vendure/core" />
 
 Contains methods relating to <a href='/reference/typescript-api/entities/payment-method#paymentmethod'>PaymentMethod</a> entities.
 

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

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## ProductOptionGroupService
 
-<GenerationInfo sourceFile="packages/core/src/service/services/product-option-group.service.ts" sourceLine="34" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/service/services/product-option-group.service.ts" sourceLine="35" packageName="@vendure/core" />
 
 Contains methods relating to <a href='/reference/typescript-api/entities/product-option-group#productoptiongroup'>ProductOptionGroup</a> entities.
 

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

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## ProductOptionService
 
-<GenerationInfo sourceFile="packages/core/src/service/services/product-option.service.ts" sourceLine="32" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/service/services/product-option.service.ts" sourceLine="33" packageName="@vendure/core" />
 
 Contains methods relating to <a href='/reference/typescript-api/entities/product-option#productoption'>ProductOption</a> entities.
 

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

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## ProductVariantService
 
-<GenerationInfo sourceFile="packages/core/src/service/services/product-variant.service.ts" sourceLine="69" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/service/services/product-variant.service.ts" sourceLine="70" packageName="@vendure/core" />
 
 Contains methods relating to <a href='/reference/typescript-api/entities/product-variant#productvariant'>ProductVariant</a> entities.
 

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

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

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

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

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

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

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

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

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

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## ShippingMethodService
 
-<GenerationInfo sourceFile="packages/core/src/service/services/shipping-method.service.ts" sourceLine="44" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/service/services/shipping-method.service.ts" sourceLine="45" packageName="@vendure/core" />
 
 Contains methods relating to <a href='/reference/typescript-api/entities/shipping-method#shippingmethod'>ShippingMethod</a> entities.
 

+ 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="22" packageName="@vendure/core" since="2.0.0" />
+<GenerationInfo sourceFile="packages/core/src/service/services/stock-level.service.ts" sourceLine="23" 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,

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

@@ -19,7 +19,7 @@ Contains methods relating to <a href='/reference/typescript-api/entities/stock-m
 class StockMovementService {
     shippingEligibilityCheckers: ShippingEligibilityChecker[];
     shippingCalculators: ShippingCalculator[];
-    constructor(connection: TransactionalConnection, listQueryBuilder: ListQueryBuilder, globalSettingsService: GlobalSettingsService, stockLevelService: StockLevelService, eventBus: EventBus, stockLocationService: StockLocationService, configService: ConfigService)
+    constructor(connection: TransactionalConnection, listQueryBuilder: ListQueryBuilder, globalSettingsService: GlobalSettingsService, stockLevelService: StockLevelService, eventBus: EventBus, stockLocationService: StockLocationService)
     getStockMovementsByProductVariantId(ctx: RequestContext, productVariantId: ID, options: StockMovementListOptions) => Promise<PaginatedList<StockMovement>>;
     adjustProductVariantStock(ctx: RequestContext, productVariantId: ID, stockOnHandNumberOrInput: number | StockLevelInput[]) => Promise<StockAdjustment[]>;
     createAllocationsForOrder(ctx: RequestContext, order: Order) => Promise<Allocation[]>;
@@ -44,7 +44,7 @@ class StockMovementService {
 
 ### constructor
 
-<MemberInfo kind="method" type={`(connection: <a href='/reference/typescript-api/data-access/transactional-connection#transactionalconnection'>TransactionalConnection</a>, listQueryBuilder: <a href='/reference/typescript-api/data-access/list-query-builder#listquerybuilder'>ListQueryBuilder</a>, globalSettingsService: <a href='/reference/typescript-api/services/global-settings-service#globalsettingsservice'>GlobalSettingsService</a>, stockLevelService: <a href='/reference/typescript-api/services/stock-level-service#stocklevelservice'>StockLevelService</a>, eventBus: <a href='/reference/typescript-api/events/event-bus#eventbus'>EventBus</a>, stockLocationService: StockLocationService, configService: ConfigService) => StockMovementService`}   />
+<MemberInfo kind="method" type={`(connection: <a href='/reference/typescript-api/data-access/transactional-connection#transactionalconnection'>TransactionalConnection</a>, listQueryBuilder: <a href='/reference/typescript-api/data-access/list-query-builder#listquerybuilder'>ListQueryBuilder</a>, globalSettingsService: <a href='/reference/typescript-api/services/global-settings-service#globalsettingsservice'>GlobalSettingsService</a>, stockLevelService: <a href='/reference/typescript-api/services/stock-level-service#stocklevelservice'>StockLevelService</a>, eventBus: <a href='/reference/typescript-api/events/event-bus#eventbus'>EventBus</a>, stockLocationService: StockLocationService) => StockMovementService`}   />
 
 
 ### getStockMovementsByProductVariantId

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

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

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

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## TaxRateService
 
-<GenerationInfo sourceFile="packages/core/src/service/services/tax-rate.service.ts" sourceLine="35" packageName="@vendure/core" />
+<GenerationInfo sourceFile="packages/core/src/service/services/tax-rate.service.ts" sourceLine="36" packageName="@vendure/core" />
 
 Contains methods relating to <a href='/reference/typescript-api/entities/tax-rate#taxrate'>TaxRate</a> entities.
 

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

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

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

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

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

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

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

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

+ 14 - 0
docs/docs/reference/typescript-api/telemetry/index.md

@@ -0,0 +1,14 @@
+---
+title: "Telemetry"
+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 />

+ 45 - 0
docs/docs/reference/typescript-api/telemetry/instrument.md

@@ -0,0 +1,45 @@
+---
+title: "Instrument"
+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';
+
+
+## Instrument
+
+<GenerationInfo sourceFile="packages/core/src/common/instrument-decorator.ts" sourceLine="40" packageName="@vendure/core" since="3.3.0" />
+
+This decorator is used to apply instrumentation to a class. It is intended to be used in conjunction
+with an <a href='/reference/typescript-api/telemetry/instrumentation-strategy#instrumentationstrategy'>InstrumentationStrategy</a> which defines how the instrumentation should be applied.
+
+In order for the instrumentation to be applied, the `VENDURE_ENABLE_INSTRUMENTATION` environment
+variable (exported from the `@vendure/core` package as `ENABLE_INSTRUMENTATION_ENV_VAR`) must be set to `true`.
+This is done to avoid the overhead of instrumentation in environments where it is not needed.
+
+For more information on how instrumentation is used, see docs on the TelemetryPlugin.
+
+*Example*
+
+```ts
+import { Instrument } from '@vendure/core';
+import { Injectable } from '@nestjs/common';
+
+@Injectable()
+// highlight-next-line
+@Instrument()
+export class MyService {
+
+  // Calls to this method will be instrumented
+  myMethod() {
+    // ...
+  }
+}
+```
+
+```ts title="Signature"
+function Instrument(): ClassDecorator
+```

+ 39 - 0
docs/docs/reference/typescript-api/telemetry/instrumentation-strategy.md

@@ -0,0 +1,39 @@
+---
+title: "InstrumentationStrategy"
+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';
+
+
+## InstrumentationStrategy
+
+<GenerationInfo sourceFile="packages/core/src/config/system/instrumentation-strategy.ts" sourceLine="51" packageName="@vendure/core" since="3.3.0" />
+
+This interface is used to define a strategy for instrumenting methods of
+classes which are decorated with the <a href='/reference/typescript-api/telemetry/instrument#instrument'>Instrument</a> decorator.
+
+```ts title="Signature"
+interface InstrumentationStrategy extends InjectableStrategy {
+    wrapMethod(args: WrappedMethodArgs): any;
+}
+```
+* Extends: <code><a href='/reference/typescript-api/common/injectable-strategy#injectablestrategy'>InjectableStrategy</a></code>
+
+
+
+<div className="members-wrapper">
+
+### wrapMethod
+
+<MemberInfo kind="method" type={`(args: <a href='/reference/typescript-api/telemetry/wrapped-method-args#wrappedmethodargs'>WrappedMethodArgs</a>) => any`}   />
+
+When a method of an instrumented class is called, it will be wrapped (by means of
+a Proxy) and this method will be called. The `applyOriginalFunction` function
+will apply the original method and return the result.
+
+
+</div>

+ 60 - 0
docs/docs/reference/typescript-api/telemetry/wrapped-method-args.md

@@ -0,0 +1,60 @@
+---
+title: "WrappedMethodArgs"
+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';
+
+
+## WrappedMethodArgs
+
+<GenerationInfo sourceFile="packages/core/src/config/system/instrumentation-strategy.ts" sourceLine="13" packageName="@vendure/core" since="3.3.0" />
+
+The arguments that are passed to the `wrapMethod` method of the
+<a href='/reference/typescript-api/telemetry/instrumentation-strategy#instrumentationstrategy'>InstrumentationStrategy</a> interface.
+
+```ts title="Signature"
+interface WrappedMethodArgs {
+    instance: any;
+    target: Type<any>;
+    methodName: string;
+    args: any[];
+    applyOriginalFunction: () => any | Promise<any>;
+}
+```
+
+<div className="members-wrapper">
+
+### instance
+
+<MemberInfo kind="property" type={`any`}   />
+
+The instance of the class which is being instrumented.
+### target
+
+<MemberInfo kind="property" type={`Type&#60;any&#62;`}   />
+
+The class which is being instrumented.
+### methodName
+
+<MemberInfo kind="property" type={`string`}   />
+
+The name of the method which is being instrumented.
+### args
+
+<MemberInfo kind="property" type={`any[]`}   />
+
+The arguments which are passed to the method.
+### applyOriginalFunction
+
+<MemberInfo kind="property" type={`() =&#62; any | Promise&#60;any&#62;`}   />
+
+A function which applies the original method and returns the result.
+This is used to call the original method after the instrumentation has
+been applied.
+
+
+</div>

+ 119 - 0
packages/dashboard/src/lib/framework/layout-engine/page-layout.tsx

@@ -23,6 +23,24 @@ export interface PageProps extends ComponentProps<'div'> {
     submitHandler?: any;
 }
 
+/**
+ * @description
+ * **Status: Developer Preview**
+ *
+ * This component should be used to wrap _all_ pages in the dashboard. It provides
+ * a consistent layout as well as a context for the slot-based PageBlock system.
+ *
+ * The typical hierarchy of a page is as follows:
+ * - `Page`
+ *  - {@link PageTitle}
+ *  - {@link PageActionBar}
+ *  - {@link PageLayout}
+ *
+ * @docsCategory components
+ * @docsPage Page
+ * @docsWeight 0
+ * @since 3.3.0
+ */
 export function Page({ children, pageId, entity, form, submitHandler, ...props }: PageProps) {
     const childArray = React.Children.toArray(children);
 
@@ -99,6 +117,14 @@ export function PageContentWithOptionalForm({ form, pageHeader, pageContent, sub
     );
 }
 
+/**
+ * @description
+ * **Status: Developer Preview**
+ *
+ * @docsCategory components
+ * @docsPage PageLayout
+ * @since 3.3.0
+ */
 export type PageLayoutProps = {
     children: React.ReactNode;
     className?: string;
@@ -117,6 +143,18 @@ function isPageBlock(child: unknown): child is React.ReactElement<PageBlockProps
     return hasColumn || hasBlockId;
 }
 
+/**
+ * @description
+ * **Status: Developer Preview**
+ *
+ * This component governs the layout of the contents of a {@link Page} component.
+ * It should contain all the {@link PageBlock} components that are to be displayed on the page.
+ *
+ * @docsCategory components
+ * @docsPage PageLayout
+ * @docsWeight 0
+ * @since 3.3.0
+ */
 export function PageLayout({ children, className }: PageLayoutProps) {
     const page = usePage();
     const isDesktop = useMediaQuery('only screen and (min-width : 769px)');
@@ -194,10 +232,33 @@ export function DetailFormGrid({ children }: { children: React.ReactNode }) {
     return <div className="md:grid md:grid-cols-2 gap-4 items-start mb-4">{children}</div>;
 }
 
+/**
+ * @description
+ * **Status: Developer Preview**
+ *
+ * A component for displaying the title of a page. This should be used inside the {@link Page} component.
+ *
+ * @docsCategory components
+ * @docsPage PageTitle
+ * @since 3.3.0
+ */
 export function PageTitle({ children }: { children: React.ReactNode }) {
     return <h1 className="text-2xl font-semibold">{children}</h1>;
 }
 
+/**
+ * @description
+ * **Status: Developer Preview**
+ *
+ * A component for displaying the main actions for a page. This should be used inside the {@link Page} component.
+ * It should be used in conjunction with the {@link PageActionBarLeft} and {@link PageActionBarRight} components
+ * as direct children.
+ *
+ * @docsCategory components
+ * @docsPage PageActionBar
+ * @docsWeight 0
+ * @since 3.3.0
+ */
 export function PageActionBar({ children }: { children: React.ReactNode }) {
     let childArray = React.Children.toArray(children);
 
@@ -216,10 +277,26 @@ export function PageActionBar({ children }: { children: React.ReactNode }) {
     );
 }
 
+/**
+ * @description
+ * **Status: Developer Preview**
+ *
+ * @docsCategory components
+ * @docsPage PageActionBar
+ * @since 3.3.0
+ */
 export function PageActionBarLeft({ children }: { children: React.ReactNode }) {
     return <div className="flex justify-start gap-2">{children}</div>;
 }
 
+/**
+ * @description
+ * **Status: Developer Preview**
+ *
+ * @docsCategory components
+ * @docsPage PageActionBar
+ * @since 3.3.0
+ */
 export function PageActionBarRight({ children }: { children: React.ReactNode }) {
     const page = usePage();
     const actionBarItems = page.pageId ? getDashboardActionBarItems(page.pageId) : [];
@@ -241,6 +318,14 @@ function PageActionBarItem({ item, page }: { item: DashboardActionBarItem; page:
     );
 }
 
+/**
+ * @description
+ * **Status: Developer Preview**
+ *
+ * @docsCategory components
+ * @docsPage PageBlock
+ * @since 3.3.0
+ */
 export type PageBlockProps = {
     children?: React.ReactNode;
     /** Which column this block should appear in */
@@ -251,6 +336,19 @@ export type PageBlockProps = {
     className?: string;
 };
 
+/**
+ * @description
+ * **Status: Developer Preview**
+ *
+ * A component for displaying a block of content on a page. This should be used inside the {@link PageLayout} component.
+ * It should be provided with a `column` prop to determine which column it should appear in, and a `blockId` prop
+ * to identify the block.
+ *
+ * @docsCategory components
+ * @docsPage PageBlock
+ * @docsWeight 0
+ * @since 3.3.0
+ */
 export function PageBlock({ children, title, description, className, blockId }: PageBlockProps) {
     return (
         <LocationWrapper blockId={blockId}>
@@ -267,6 +365,17 @@ export function PageBlock({ children, title, description, className, blockId }:
     );
 }
 
+/**
+ * @description
+ * **Status: Developer Preview**
+ *
+ * A component for displaying a block of content on a page that takes up the full width of the page.
+ * This should be used inside the {@link PageLayout} component.
+ *
+ * @docsCategory components
+ * @docsPage PageBlock
+ * @since 3.3.0
+ */
 export function FullWidthPageBlock({
                                        children,
                                        className,
@@ -279,6 +388,16 @@ export function FullWidthPageBlock({
     );
 }
 
+/**
+ * @description
+ * **Status: Developer Preview**
+ *
+ * A component for displaying an auto-generated form for custom fields on a page.
+ *
+ * @docsCategory components
+ * @docsPage PageBlock
+ * @since 3.3.0
+ */
 export function CustomFieldsPageBlock({
                                           column,
                                           entityType,

+ 2 - 0
packages/dashboard/src/lib/framework/page/detail-page.tsx

@@ -80,6 +80,8 @@ export interface DetailPageProps<
  *
  * Auto-generates a detail page with a form based on the provided query and mutation documents.
  *
+ * For more control over the layout, you would use the more low-level {@link Page} component.
+ *
  * @docsCategory components
  * @docsPage DetailPage
  * @docsWeight 0

Filskillnaden har hållts tillbaka eftersom den är för stor
+ 12 - 0
packages/dashboard/src/lib/graphql/graphql-env.d.ts


+ 15 - 6
scripts/docs/typescript-docs-parser.ts

@@ -167,12 +167,21 @@ export class TypescriptDocsParser {
                 members: this.parseMembers(statement.members) as PropertyInfo[],
             };
         } else if (ts.isFunctionDeclaration(statement)) {
-            const parameters = statement.parameters.map(p => ({
-                name: p.name.getText(),
-                type: p.type ? p.type.getText() : '',
-                optional: !!p.questionToken,
-                initializer: p.initializer && p.initializer.getText(),
-            }));
+            const parameters = statement.parameters.map(p => {
+                let name = p.name.getText();
+                if (name.startsWith('{') && name.endsWith('}') && info.sourceFile.endsWith('.tsx')) {
+                    // The "name" of a React component is often a destructured object, e.g. `{ prod1, prop2 }` etc.
+                    // In this case we will simply replace that with "props".
+                    name = 'props';
+                }
+                return {
+                    name,
+                    type: p.type ? p.type.getText() : '',
+                    optional: !!p.questionToken,
+                    initializer: p.initializer && p.initializer.getText(),
+                }
+            });
+
             return {
                 ...info,
                 kind: 'function',

Vissa filer visades inte eftersom för många filer har ändrats