@vendure/dashboard 3.3.5-master-202506250629 → 3.3.5-master-202506250727
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/plugin/tests/barrel-exports/my-plugin/index.d.ts +1 -0
- package/dist/plugin/tests/barrel-exports/my-plugin/index.js +17 -0
- package/dist/plugin/tests/barrel-exports/my-plugin/src/my.plugin.d.ts +2 -0
- package/dist/plugin/tests/barrel-exports/my-plugin/src/my.plugin.js +20 -0
- package/dist/plugin/tests/barrel-exports/vendure-config.d.ts +2 -0
- package/dist/plugin/tests/barrel-exports/vendure-config.js +19 -0
- package/dist/plugin/tests/barrel-exports.spec.d.ts +1 -0
- package/dist/plugin/tests/barrel-exports.spec.js +14 -0
- package/dist/plugin/utils/config-loader.js +8 -2
- package/package.json +4 -4
- package/src/app/routes/_authenticated/_administrators/administrators_.$id.tsx +1 -1
- package/src/app/routes/_authenticated/_assets/assets_.$id.tsx +43 -34
- package/src/app/routes/_authenticated/_channels/channels_.$id.tsx +1 -1
- package/src/app/routes/_authenticated/_collections/collections_.$id.tsx +1 -1
- package/src/app/routes/_authenticated/_countries/countries_.$id.tsx +1 -1
- package/src/app/routes/_authenticated/_customer-groups/customer-groups_.$id.tsx +1 -1
- package/src/app/routes/_authenticated/_customers/customers_.$id.tsx +1 -1
- package/src/app/routes/_authenticated/_facets/facets_.$id.tsx +1 -1
- package/src/app/routes/_authenticated/_global-settings/global-settings.tsx +1 -1
- package/src/app/routes/_authenticated/_orders/orders_.$id.tsx +2 -5
- package/src/app/routes/_authenticated/_payment-methods/payment-methods_.$id.tsx +1 -1
- package/src/app/routes/_authenticated/_product-variants/product-variants_.$id.tsx +1 -1
- package/src/app/routes/_authenticated/_products/products_.$id.tsx +11 -8
- package/src/app/routes/_authenticated/_promotions/promotions_.$id.tsx +1 -1
- package/src/app/routes/_authenticated/_roles/roles_.$id.tsx +1 -1
- package/src/app/routes/_authenticated/_sellers/sellers_.$id.tsx +1 -1
- package/src/app/routes/_authenticated/_shipping-methods/shipping-methods_.$id.tsx +1 -1
- package/src/app/routes/_authenticated/_stock-locations/stock-locations_.$id.tsx +1 -1
- package/src/app/routes/_authenticated/_tax-categories/tax-categories_.$id.tsx +1 -1
- package/src/app/routes/_authenticated/_tax-rates/tax-rates_.$id.tsx +1 -1
- package/src/app/routes/_authenticated/_zones/zones_.$id.tsx +1 -1
- package/vite/tests/barrel-exports/my-plugin/index.ts +1 -0
- package/vite/tests/barrel-exports/my-plugin/src/my.plugin.ts +8 -0
- package/vite/tests/barrel-exports/package.json +6 -0
- package/vite/tests/barrel-exports/vendure-config.ts +19 -0
- package/vite/tests/barrel-exports.spec.ts +17 -0
- package/vite/utils/config-loader.ts +10 -2
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './src/my.plugin';
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./src/my.plugin"), exports);
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.MyPlugin = void 0;
|
|
10
|
+
const core_1 = require("@vendure/core");
|
|
11
|
+
let MyPlugin = class MyPlugin {
|
|
12
|
+
};
|
|
13
|
+
exports.MyPlugin = MyPlugin;
|
|
14
|
+
exports.MyPlugin = MyPlugin = __decorate([
|
|
15
|
+
(0, core_1.VendurePlugin)({
|
|
16
|
+
imports: [core_1.PluginCommonModule],
|
|
17
|
+
providers: [],
|
|
18
|
+
dashboard: './dashboard/index.tsx',
|
|
19
|
+
})
|
|
20
|
+
], MyPlugin);
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.config = void 0;
|
|
4
|
+
const my_plugin_1 = require("./my-plugin");
|
|
5
|
+
exports.config = {
|
|
6
|
+
apiOptions: {
|
|
7
|
+
port: 3000,
|
|
8
|
+
},
|
|
9
|
+
authOptions: {
|
|
10
|
+
tokenMethod: 'bearer',
|
|
11
|
+
},
|
|
12
|
+
dbConnectionOptions: {
|
|
13
|
+
type: 'postgres',
|
|
14
|
+
},
|
|
15
|
+
paymentOptions: {
|
|
16
|
+
paymentMethodHandlers: [],
|
|
17
|
+
},
|
|
18
|
+
plugins: [my_plugin_1.MyPlugin],
|
|
19
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { join } from 'path';
|
|
2
|
+
import { describe, expect, it } from 'vitest';
|
|
3
|
+
import { loadVendureConfig } from '../utils/config-loader.js';
|
|
4
|
+
describe('detecting plugins in barrel exports', () => {
|
|
5
|
+
it('should detect plugins in barrel exports', async () => {
|
|
6
|
+
const result = await loadVendureConfig({
|
|
7
|
+
tempDir: join(__dirname, './__temp'),
|
|
8
|
+
vendureConfigPath: join(__dirname, 'barrel-exports', 'vendure-config.ts'),
|
|
9
|
+
});
|
|
10
|
+
expect(result.pluginInfo).toHaveLength(1);
|
|
11
|
+
expect(result.pluginInfo[0].name).toBe('MyPlugin');
|
|
12
|
+
expect(result.pluginInfo[0].dashboardEntryPath).toBe('./dashboard/index.tsx');
|
|
13
|
+
});
|
|
14
|
+
});
|
|
@@ -157,11 +157,14 @@ export async function compileFile({ inputRootDir, inputPath, outputDir, transfor
|
|
|
157
157
|
}
|
|
158
158
|
}
|
|
159
159
|
async function collectImports(node) {
|
|
160
|
-
if (ts.
|
|
160
|
+
if ((ts.isExportDeclaration(node) || ts.isImportDeclaration(node)) &&
|
|
161
|
+
node.moduleSpecifier &&
|
|
162
|
+
ts.isStringLiteral(node.moduleSpecifier)) {
|
|
161
163
|
const importPath = node.moduleSpecifier.text;
|
|
162
164
|
// Handle relative imports
|
|
163
165
|
if (importPath.startsWith('.')) {
|
|
164
166
|
const resolvedPath = path.resolve(path.dirname(absoluteInputPath), importPath);
|
|
167
|
+
// TODO: does this handle index files correctly?
|
|
165
168
|
let resolvedTsPath = resolvedPath + '.ts';
|
|
166
169
|
// Also check for .tsx if .ts doesn't exist
|
|
167
170
|
if (!(await fs.pathExists(resolvedTsPath))) {
|
|
@@ -209,7 +212,9 @@ export async function compileFile({ inputRootDir, inputPath, outputDir, transfor
|
|
|
209
212
|
continue;
|
|
210
213
|
const potentialPathBase = path.resolve(tsConfigInfo.baseUrl, patternPrefix);
|
|
211
214
|
const resolvedPath = path.join(potentialPathBase, remainingImportPath);
|
|
212
|
-
let resolvedTsPath = resolvedPath
|
|
215
|
+
let resolvedTsPath = resolvedPath.endsWith('.ts')
|
|
216
|
+
? resolvedPath
|
|
217
|
+
: resolvedPath + '.ts';
|
|
213
218
|
// Similar existence checks as relative paths
|
|
214
219
|
if (!(await fs.pathExists(resolvedTsPath))) {
|
|
215
220
|
const resolvedTsxPath = resolvedPath + '.tsx';
|
|
@@ -258,6 +263,7 @@ export async function compileFile({ inputRootDir, inputPath, outputDir, transfor
|
|
|
258
263
|
ts.isModuleBlock(child) ||
|
|
259
264
|
ts.isModuleDeclaration(child) ||
|
|
260
265
|
ts.isImportDeclaration(child) ||
|
|
266
|
+
ts.isExportDeclaration(child) ||
|
|
261
267
|
child.kind === ts.SyntaxKind.SyntaxList) {
|
|
262
268
|
await collectImports(child);
|
|
263
269
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vendure/dashboard",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "3.3.5-master-
|
|
4
|
+
"version": "3.3.5-master-202506250727",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -86,8 +86,8 @@
|
|
|
86
86
|
"@types/react-dom": "^19.0.4",
|
|
87
87
|
"@types/react-grid-layout": "^1.3.5",
|
|
88
88
|
"@uidotdev/usehooks": "^2.4.1",
|
|
89
|
-
"@vendure/common": "^3.3.5-master-
|
|
90
|
-
"@vendure/core": "^3.3.5-master-
|
|
89
|
+
"@vendure/common": "^3.3.5-master-202506250727",
|
|
90
|
+
"@vendure/core": "^3.3.5-master-202506250727",
|
|
91
91
|
"@vitejs/plugin-react": "^4.3.4",
|
|
92
92
|
"awesome-graphql-client": "^2.1.0",
|
|
93
93
|
"class-variance-authority": "^0.7.1",
|
|
@@ -130,5 +130,5 @@
|
|
|
130
130
|
"lightningcss-linux-arm64-musl": "^1.29.3",
|
|
131
131
|
"lightningcss-linux-x64-musl": "^1.29.1"
|
|
132
132
|
},
|
|
133
|
-
"gitHead": "
|
|
133
|
+
"gitHead": "a1b6b57cbb9b65a63e88cf06e0e65d5a5dd0a87f"
|
|
134
134
|
}
|
|
@@ -87,7 +87,7 @@ function AdministratorDetailPage() {
|
|
|
87
87
|
const roleIds = form.watch('roleIds');
|
|
88
88
|
|
|
89
89
|
return (
|
|
90
|
-
<Page pageId="administrator-detail" form={form} submitHandler={submitHandler}>
|
|
90
|
+
<Page pageId="administrator-detail" form={form} submitHandler={submitHandler} entity={entity}>
|
|
91
91
|
<PageTitle>{creatingNewEntity ? <Trans>New administrator</Trans> : name}</PageTitle>
|
|
92
92
|
|
|
93
93
|
<PageActionBar>
|
|
@@ -1,23 +1,30 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { detailPageRouteLoader } from '@/framework/page/detail-page-route-loader.js';
|
|
3
|
-
import { createFileRoute } from '@tanstack/react-router'
|
|
4
|
-
import { assetDetailDocument, assetUpdateDocument } from './assets.graphql.js';
|
|
5
|
-
import { Trans, useLingui } from '@/lib/trans.js';
|
|
6
|
-
import { ErrorPage } from '@/components/shared/error-page.js';
|
|
7
|
-
import { toast } from 'sonner';
|
|
8
|
-
import { Page, PageTitle, PageActionBar, PageActionBarRight, PageBlock, PageLayout, CustomFieldsPageBlock } from '@/framework/layout-engine/page-layout.js'
|
|
9
|
-
import { useDetailPage } from '@/framework/page/use-detail-page.js';
|
|
10
|
-
import { PermissionGuard } from '@/components/shared/permission-guard.js';
|
|
11
|
-
import { Button } from '@/components/ui/button.js';
|
|
12
|
-
import { VendureImage } from '@/components/shared/vendure-image.js';
|
|
13
|
-
import { useState, useRef } from 'react';
|
|
14
|
-
import { PreviewPreset } from '@/components/shared/asset/asset-preview.js';
|
|
1
|
+
import { AssetFocalPointEditor } from '@/components/shared/asset/asset-focal-point-editor.js';
|
|
15
2
|
import { AssetPreviewSelector } from '@/components/shared/asset/asset-preview-selector.js';
|
|
3
|
+
import { PreviewPreset } from '@/components/shared/asset/asset-preview.js';
|
|
16
4
|
import { AssetProperties } from '@/components/shared/asset/asset-properties.js';
|
|
17
|
-
import { AssetFocalPointEditor } from '@/components/shared/asset/asset-focal-point-editor.js';
|
|
18
|
-
import { FocusIcon } from 'lucide-react';
|
|
19
5
|
import { Point } from '@/components/shared/asset/focal-point-control.js';
|
|
6
|
+
import { ErrorPage } from '@/components/shared/error-page.js';
|
|
7
|
+
import { PermissionGuard } from '@/components/shared/permission-guard.js';
|
|
8
|
+
import { VendureImage } from '@/components/shared/vendure-image.js';
|
|
9
|
+
import { Button } from '@/components/ui/button.js';
|
|
20
10
|
import { Label } from '@/components/ui/label.js';
|
|
11
|
+
import {
|
|
12
|
+
CustomFieldsPageBlock,
|
|
13
|
+
Page,
|
|
14
|
+
PageActionBar,
|
|
15
|
+
PageActionBarRight,
|
|
16
|
+
PageBlock,
|
|
17
|
+
PageLayout,
|
|
18
|
+
PageTitle,
|
|
19
|
+
} from '@/framework/layout-engine/page-layout.js';
|
|
20
|
+
import { detailPageRouteLoader } from '@/framework/page/detail-page-route-loader.js';
|
|
21
|
+
import { useDetailPage } from '@/framework/page/use-detail-page.js';
|
|
22
|
+
import { Trans, useLingui } from '@/lib/trans.js';
|
|
23
|
+
import { createFileRoute } from '@tanstack/react-router';
|
|
24
|
+
import { FocusIcon } from 'lucide-react';
|
|
25
|
+
import { useRef, useState } from 'react';
|
|
26
|
+
import { toast } from 'sonner';
|
|
27
|
+
import { assetDetailDocument, assetUpdateDocument } from './assets.graphql.js';
|
|
21
28
|
export const Route = createFileRoute('/_authenticated/_assets/assets_/$id')({
|
|
22
29
|
component: AssetDetailPage,
|
|
23
30
|
loader: detailPageRouteLoader({
|
|
@@ -25,7 +32,7 @@ export const Route = createFileRoute('/_authenticated/_assets/assets_/$id')({
|
|
|
25
32
|
breadcrumb(isNew, entity) {
|
|
26
33
|
return [
|
|
27
34
|
{ path: '/assets', label: 'Assets' },
|
|
28
|
-
isNew ? <Trans>New asset</Trans> : entity?.name ?? '',
|
|
35
|
+
isNew ? <Trans>New asset</Trans> : (entity?.name ?? ''),
|
|
29
36
|
];
|
|
30
37
|
},
|
|
31
38
|
}),
|
|
@@ -79,17 +86,14 @@ function AssetDetailPage() {
|
|
|
79
86
|
return null;
|
|
80
87
|
}
|
|
81
88
|
return (
|
|
82
|
-
<Page pageId="asset-detail" form={form} submitHandler={submitHandler}>
|
|
89
|
+
<Page pageId="asset-detail" form={form} submitHandler={submitHandler} entity={entity}>
|
|
83
90
|
<PageTitle>
|
|
84
91
|
<Trans>Edit asset</Trans>
|
|
85
92
|
</PageTitle>
|
|
86
93
|
<PageActionBar>
|
|
87
94
|
<PageActionBarRight>
|
|
88
95
|
<PermissionGuard requires={['UpdateChannel']}>
|
|
89
|
-
<Button
|
|
90
|
-
type="submit"
|
|
91
|
-
disabled={!form.formState.isDirty || isPending}
|
|
92
|
-
>
|
|
96
|
+
<Button type="submit" disabled={!form.formState.isDirty || isPending}>
|
|
93
97
|
<Trans>Update</Trans>
|
|
94
98
|
</Button>
|
|
95
99
|
</PermissionGuard>
|
|
@@ -103,7 +107,7 @@ function AssetDetailPage() {
|
|
|
103
107
|
height={height}
|
|
104
108
|
settingFocalPoint={settingFocalPoint}
|
|
105
109
|
focalPoint={form.getValues().focalPoint ?? { x: 0.5, y: 0.5 }}
|
|
106
|
-
onFocalPointChange={
|
|
110
|
+
onFocalPointChange={point => {
|
|
107
111
|
form.setValue('focalPoint.x', point.x, { shouldDirty: true });
|
|
108
112
|
form.setValue('focalPoint.y', point.y, { shouldDirty: true });
|
|
109
113
|
setSettingFocalPoint(false);
|
|
@@ -124,11 +128,7 @@ function AssetDetailPage() {
|
|
|
124
128
|
</AssetFocalPointEditor>
|
|
125
129
|
</div>
|
|
126
130
|
</PageBlock>
|
|
127
|
-
<CustomFieldsPageBlock
|
|
128
|
-
column="main"
|
|
129
|
-
entityType={'Asset'}
|
|
130
|
-
control={form.control}
|
|
131
|
-
/>
|
|
131
|
+
<CustomFieldsPageBlock column="main" entityType={'Asset'} control={form.control} />
|
|
132
132
|
<PageBlock column="side" blockId="asset-properties">
|
|
133
133
|
<AssetProperties asset={entity} />
|
|
134
134
|
</PageBlock>
|
|
@@ -136,15 +136,24 @@ function AssetDetailPage() {
|
|
|
136
136
|
<div className="flex flex-col gap-2">
|
|
137
137
|
<AssetPreviewSelector size={size} setSize={setSize} width={width} height={height} />
|
|
138
138
|
<div className="flex items-center gap-2">
|
|
139
|
-
<Button
|
|
139
|
+
<Button
|
|
140
|
+
type="button"
|
|
141
|
+
variant="outline"
|
|
142
|
+
size="icon"
|
|
143
|
+
onClick={() => setSettingFocalPoint(true)}
|
|
144
|
+
>
|
|
140
145
|
<FocusIcon className="h-4 w-4" />
|
|
141
146
|
</Button>
|
|
142
147
|
<div className="text-sm text-muted-foreground">
|
|
143
|
-
<Label
|
|
148
|
+
<Label>
|
|
149
|
+
<Trans>Focal Point</Trans>
|
|
150
|
+
</Label>
|
|
144
151
|
<div className="text-sm text-muted-foreground">
|
|
145
|
-
{form.getValues().focalPoint?.x && form.getValues().focalPoint?.y
|
|
146
|
-
|
|
147
|
-
|
|
152
|
+
{form.getValues().focalPoint?.x && form.getValues().focalPoint?.y ? (
|
|
153
|
+
`${form.getValues().focalPoint?.x.toFixed(2)}, ${form.getValues().focalPoint?.y.toFixed(2)}`
|
|
154
|
+
) : (
|
|
155
|
+
<Trans>Not set</Trans>
|
|
156
|
+
)}
|
|
148
157
|
</div>
|
|
149
158
|
</div>
|
|
150
159
|
</div>
|
|
@@ -152,5 +161,5 @@ function AssetDetailPage() {
|
|
|
152
161
|
</PageBlock>
|
|
153
162
|
</PageLayout>
|
|
154
163
|
</Page>
|
|
155
|
-
)
|
|
164
|
+
);
|
|
156
165
|
}
|
|
@@ -100,7 +100,7 @@ function ChannelDetailPage() {
|
|
|
100
100
|
const codeIsDefault = entity?.code === DEFAULT_CHANNEL_CODE;
|
|
101
101
|
|
|
102
102
|
return (
|
|
103
|
-
<Page pageId="channel-detail" form={form} submitHandler={submitHandler}>
|
|
103
|
+
<Page pageId="channel-detail" form={form} submitHandler={submitHandler} entity={entity}>
|
|
104
104
|
<PageTitle>
|
|
105
105
|
{creatingNewEntity ? (
|
|
106
106
|
<Trans>New channel</Trans>
|
|
@@ -105,7 +105,7 @@ function CollectionDetailPage() {
|
|
|
105
105
|
const currentInheritFiltersValue = form.watch('inheritFilters');
|
|
106
106
|
|
|
107
107
|
return (
|
|
108
|
-
<Page pageId="collection-detail" form={form} submitHandler={submitHandler}>
|
|
108
|
+
<Page pageId="collection-detail" form={form} submitHandler={submitHandler} entity={entity}>
|
|
109
109
|
<PageTitle>{creatingNewEntity ? <Trans>New collection</Trans> : (entity?.name ?? '')}</PageTitle>
|
|
110
110
|
<PageActionBar>
|
|
111
111
|
<PageActionBarRight>
|
|
@@ -71,7 +71,7 @@ function CountryDetailPage() {
|
|
|
71
71
|
});
|
|
72
72
|
|
|
73
73
|
return (
|
|
74
|
-
<Page pageId="country-detail" form={form} submitHandler={submitHandler}>
|
|
74
|
+
<Page pageId="country-detail" form={form} submitHandler={submitHandler} entity={entity}>
|
|
75
75
|
<PageTitle>{creatingNewEntity ? <Trans>New country</Trans> : (entity?.name ?? '')}</PageTitle>
|
|
76
76
|
<PageActionBar>
|
|
77
77
|
<PageActionBarRight>
|
|
@@ -72,7 +72,7 @@ function CustomerGroupDetailPage() {
|
|
|
72
72
|
});
|
|
73
73
|
|
|
74
74
|
return (
|
|
75
|
-
<Page pageId="customer-group-detail" form={form} submitHandler={submitHandler}>
|
|
75
|
+
<Page pageId="customer-group-detail" form={form} submitHandler={submitHandler} entity={entity}>
|
|
76
76
|
<PageTitle>
|
|
77
77
|
{creatingNewEntity ? <Trans>New customer group</Trans> : (entity?.name ?? '')}
|
|
78
78
|
</PageTitle>
|
|
@@ -137,7 +137,7 @@ function CustomerDetailPage() {
|
|
|
137
137
|
const customerName = entity ? `${entity.firstName} ${entity.lastName}` : '';
|
|
138
138
|
|
|
139
139
|
return (
|
|
140
|
-
<Page pageId="customer-detail" form={form} submitHandler={submitHandler}>
|
|
140
|
+
<Page pageId="customer-detail" form={form} submitHandler={submitHandler} entity={entity}>
|
|
141
141
|
<PageTitle>{creatingNewEntity ? <Trans>New customer</Trans> : customerName}</PageTitle>
|
|
142
142
|
<PageActionBar>
|
|
143
143
|
<PageActionBarRight>
|
|
@@ -82,7 +82,7 @@ function FacetDetailPage() {
|
|
|
82
82
|
});
|
|
83
83
|
|
|
84
84
|
return (
|
|
85
|
-
<Page pageId="facet-detail" form={form} submitHandler={submitHandler}>
|
|
85
|
+
<Page pageId="facet-detail" form={form} submitHandler={submitHandler} entity={entity}>
|
|
86
86
|
<PageTitle>{creatingNewEntity ? <Trans>New facet</Trans> : (entity?.name ?? '')}</PageTitle>
|
|
87
87
|
<PageActionBar>
|
|
88
88
|
<PageActionBarRight>
|
|
@@ -78,7 +78,7 @@ function GlobalSettingsPage() {
|
|
|
78
78
|
});
|
|
79
79
|
|
|
80
80
|
return (
|
|
81
|
-
<Page pageId="global-settings" form={form} submitHandler={submitHandler}>
|
|
81
|
+
<Page pageId="global-settings" form={form} submitHandler={submitHandler} entity={entity}>
|
|
82
82
|
<PageTitle>
|
|
83
83
|
<Trans>Global settings</Trans>
|
|
84
84
|
</PageTitle>
|
|
@@ -27,10 +27,7 @@ import { orderDetailDocument } from './orders.graphql.js';
|
|
|
27
27
|
|
|
28
28
|
export const Route = createFileRoute('/_authenticated/_orders/orders_/$id')({
|
|
29
29
|
component: OrderDetailPage,
|
|
30
|
-
loader: async ({
|
|
31
|
-
context,
|
|
32
|
-
params,
|
|
33
|
-
}) => {
|
|
30
|
+
loader: async ({ context, params }) => {
|
|
34
31
|
if (!params.id) {
|
|
35
32
|
throw new Error('ID param is required');
|
|
36
33
|
}
|
|
@@ -86,7 +83,7 @@ function OrderDetailPage() {
|
|
|
86
83
|
}
|
|
87
84
|
|
|
88
85
|
return (
|
|
89
|
-
<Page pageId="order-detail" form={form} submitHandler={submitHandler}>
|
|
86
|
+
<Page pageId="order-detail" form={form} submitHandler={submitHandler} entity={entity}>
|
|
90
87
|
<PageTitle>{entity?.code ?? ''}</PageTitle>
|
|
91
88
|
<PageActionBar>
|
|
92
89
|
<PageActionBarRight>
|
|
@@ -102,7 +102,7 @@ function PaymentMethodDetailPage() {
|
|
|
102
102
|
});
|
|
103
103
|
|
|
104
104
|
return (
|
|
105
|
-
<Page pageId="payment-method-detail" form={form} submitHandler={submitHandler}>
|
|
105
|
+
<Page pageId="payment-method-detail" form={form} submitHandler={submitHandler} entity={entity}>
|
|
106
106
|
<PageTitle>
|
|
107
107
|
{creatingNewEntity ? <Trans>New payment method</Trans> : (entity?.name ?? '')}
|
|
108
108
|
</PageTitle>
|
|
@@ -102,7 +102,7 @@ function ProductVariantDetailPage() {
|
|
|
102
102
|
const [price, taxCategoryId] = form.watch(['price', 'taxCategoryId']);
|
|
103
103
|
|
|
104
104
|
return (
|
|
105
|
-
<Page pageId="product-variant-detail" form={form} submitHandler={submitHandler}>
|
|
105
|
+
<Page pageId="product-variant-detail" form={form} submitHandler={submitHandler} entity={entity}>
|
|
106
106
|
<PageTitle>
|
|
107
107
|
{creatingNewEntity ? <Trans>New product variant</Trans> : (entity?.name ?? '')}
|
|
108
108
|
</PageTitle>
|
|
@@ -24,12 +24,12 @@ import { detailPageRouteLoader } from '@/framework/page/detail-page-route-loader
|
|
|
24
24
|
import { useDetailPage } from '@/framework/page/use-detail-page.js';
|
|
25
25
|
import { Trans, useLingui } from '@/lib/trans.js';
|
|
26
26
|
import { createFileRoute, useNavigate } from '@tanstack/react-router';
|
|
27
|
+
import { useRef } from 'react';
|
|
27
28
|
import { toast } from 'sonner';
|
|
29
|
+
import { AddProductVariantDialog } from './components/add-product-variant-dialog.js';
|
|
28
30
|
import { CreateProductVariantsDialog } from './components/create-product-variants-dialog.js';
|
|
29
31
|
import { ProductVariantsTable } from './components/product-variants-table.js';
|
|
30
|
-
import { AddProductVariantDialog } from './components/add-product-variant-dialog.js';
|
|
31
32
|
import { createProductDocument, productDetailDocument, updateProductDocument } from './products.graphql.js';
|
|
32
|
-
import { useRef } from 'react';
|
|
33
33
|
|
|
34
34
|
export const Route = createFileRoute('/_authenticated/_products/products_/$id')({
|
|
35
35
|
component: ProductDetailPage,
|
|
@@ -88,9 +88,9 @@ function ProductDetailPage() {
|
|
|
88
88
|
});
|
|
89
89
|
},
|
|
90
90
|
});
|
|
91
|
-
|
|
91
|
+
|
|
92
92
|
return (
|
|
93
|
-
<Page pageId="product-detail"
|
|
93
|
+
<Page pageId="product-detail" form={form} submitHandler={submitHandler} entity={entity}>
|
|
94
94
|
<PageTitle>{creatingNewEntity ? <Trans>New product</Trans> : (entity?.name ?? '')}</PageTitle>
|
|
95
95
|
<PageActionBar>
|
|
96
96
|
<PageActionBarRight>
|
|
@@ -142,10 +142,13 @@ function ProductDetailPage() {
|
|
|
142
142
|
<CustomFieldsPageBlock column="main" entityType="Product" control={form.control} />
|
|
143
143
|
{entity && entity.variantList.totalItems > 0 && (
|
|
144
144
|
<PageBlock column="main" blockId="product-variants-table">
|
|
145
|
-
<ProductVariantsTable
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
145
|
+
<ProductVariantsTable
|
|
146
|
+
productId={params.id}
|
|
147
|
+
registerRefresher={refresher => {
|
|
148
|
+
refreshRef.current = refresher;
|
|
149
|
+
}}
|
|
150
|
+
/>
|
|
151
|
+
<div className="mt-4">
|
|
149
152
|
<AddProductVariantDialog
|
|
150
153
|
productId={params.id}
|
|
151
154
|
onSuccess={() => {
|
|
@@ -114,7 +114,7 @@ function PromotionDetailPage() {
|
|
|
114
114
|
});
|
|
115
115
|
|
|
116
116
|
return (
|
|
117
|
-
<Page pageId="promotion-detail" form={form} submitHandler={submitHandler}>
|
|
117
|
+
<Page pageId="promotion-detail" form={form} submitHandler={submitHandler} entity={entity}>
|
|
118
118
|
<PageTitle>{creatingNewEntity ? <Trans>New promotion</Trans> : (entity?.name ?? '')}</PageTitle>
|
|
119
119
|
<PageActionBar>
|
|
120
120
|
<PageActionBarRight>
|
|
@@ -71,7 +71,7 @@ function RoleDetailPage() {
|
|
|
71
71
|
});
|
|
72
72
|
|
|
73
73
|
return (
|
|
74
|
-
<Page pageId="role-detail" form={form} submitHandler={submitHandler}>
|
|
74
|
+
<Page pageId="role-detail" form={form} submitHandler={submitHandler} entity={entity}>
|
|
75
75
|
<PageTitle>{creatingNewEntity ? <Trans>New role</Trans> : (entity?.description ?? '')}</PageTitle>
|
|
76
76
|
<PageActionBar>
|
|
77
77
|
<PageActionBarRight>
|
|
@@ -65,7 +65,7 @@ function SellerDetailPage() {
|
|
|
65
65
|
});
|
|
66
66
|
|
|
67
67
|
return (
|
|
68
|
-
<Page pageId="seller-detail" form={form} submitHandler={submitHandler}>
|
|
68
|
+
<Page pageId="seller-detail" form={form} submitHandler={submitHandler} entity={entity}>
|
|
69
69
|
<PageTitle>{creatingNewEntity ? <Trans>New seller</Trans> : (entity?.name ?? '')}</PageTitle>
|
|
70
70
|
<PageActionBar>
|
|
71
71
|
<PageActionBarRight>
|
|
@@ -94,7 +94,7 @@ function ShippingMethodDetailPage() {
|
|
|
94
94
|
});
|
|
95
95
|
|
|
96
96
|
return (
|
|
97
|
-
<Page pageId="shipping-method-detail" form={form} submitHandler={submitHandler}>
|
|
97
|
+
<Page pageId="shipping-method-detail" form={form} submitHandler={submitHandler} entity={entity}>
|
|
98
98
|
<PageTitle>
|
|
99
99
|
{creatingNewEntity ? <Trans>New shipping method</Trans> : (entity?.name ?? '')}
|
|
100
100
|
</PageTitle>
|
|
@@ -74,7 +74,7 @@ function StockLocationDetailPage() {
|
|
|
74
74
|
});
|
|
75
75
|
|
|
76
76
|
return (
|
|
77
|
-
<Page pageId="stock-location-detail" form={form} submitHandler={submitHandler}>
|
|
77
|
+
<Page pageId="stock-location-detail" form={form} submitHandler={submitHandler} entity={entity}>
|
|
78
78
|
<PageTitle>
|
|
79
79
|
{creatingNewEntity ? <Trans>New stock location</Trans> : (entity?.name ?? '')}
|
|
80
80
|
</PageTitle>
|
|
@@ -73,7 +73,7 @@ function TaxCategoryDetailPage() {
|
|
|
73
73
|
});
|
|
74
74
|
|
|
75
75
|
return (
|
|
76
|
-
<Page pageId="tax-category-detail" form={form} submitHandler={submitHandler}>
|
|
76
|
+
<Page pageId="tax-category-detail" form={form} submitHandler={submitHandler} entity={entity}>
|
|
77
77
|
<PageTitle>
|
|
78
78
|
{creatingNewEntity ? <Trans>New tax category</Trans> : (entity?.name ?? '')}
|
|
79
79
|
</PageTitle>
|
|
@@ -77,7 +77,7 @@ function TaxRateDetailPage() {
|
|
|
77
77
|
});
|
|
78
78
|
|
|
79
79
|
return (
|
|
80
|
-
<Page pageId="tax-rate-detail" form={form} submitHandler={submitHandler}>
|
|
80
|
+
<Page pageId="tax-rate-detail" form={form} submitHandler={submitHandler} entity={entity}>
|
|
81
81
|
<PageTitle>{creatingNewEntity ? <Trans>New tax rate</Trans> : (entity?.name ?? '')}</PageTitle>
|
|
82
82
|
<PageActionBar>
|
|
83
83
|
<PageActionBarRight>
|
|
@@ -66,7 +66,7 @@ function ZoneDetailPage() {
|
|
|
66
66
|
});
|
|
67
67
|
|
|
68
68
|
return (
|
|
69
|
-
<Page pageId="zone-detail" form={form} submitHandler={submitHandler}>
|
|
69
|
+
<Page pageId="zone-detail" form={form} submitHandler={submitHandler} entity={entity}>
|
|
70
70
|
<PageTitle>{creatingNewEntity ? <Trans>New zone</Trans> : (entity?.name ?? '')}</PageTitle>
|
|
71
71
|
<PageActionBar>
|
|
72
72
|
<PageActionBarRight>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './src/my.plugin';
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { VendureConfig } from '@vendure/core';
|
|
2
|
+
|
|
3
|
+
import { MyPlugin } from './my-plugin';
|
|
4
|
+
|
|
5
|
+
export const config: VendureConfig = {
|
|
6
|
+
apiOptions: {
|
|
7
|
+
port: 3000,
|
|
8
|
+
},
|
|
9
|
+
authOptions: {
|
|
10
|
+
tokenMethod: 'bearer',
|
|
11
|
+
},
|
|
12
|
+
dbConnectionOptions: {
|
|
13
|
+
type: 'postgres',
|
|
14
|
+
},
|
|
15
|
+
paymentOptions: {
|
|
16
|
+
paymentMethodHandlers: [],
|
|
17
|
+
},
|
|
18
|
+
plugins: [MyPlugin],
|
|
19
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { join } from 'path';
|
|
2
|
+
import { describe, expect, it } from 'vitest';
|
|
3
|
+
|
|
4
|
+
import { loadVendureConfig } from '../utils/config-loader.js';
|
|
5
|
+
|
|
6
|
+
describe('detecting plugins in barrel exports', () => {
|
|
7
|
+
it('should detect plugins in barrel exports', async () => {
|
|
8
|
+
const result = await loadVendureConfig({
|
|
9
|
+
tempDir: join(__dirname, './__temp'),
|
|
10
|
+
vendureConfigPath: join(__dirname, 'barrel-exports', 'vendure-config.ts'),
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
expect(result.pluginInfo).toHaveLength(1);
|
|
14
|
+
expect(result.pluginInfo[0].name).toBe('MyPlugin');
|
|
15
|
+
expect(result.pluginInfo[0].dashboardEntryPath).toBe('./dashboard/index.tsx');
|
|
16
|
+
});
|
|
17
|
+
});
|
|
@@ -328,12 +328,17 @@ export async function compileFile({
|
|
|
328
328
|
}
|
|
329
329
|
|
|
330
330
|
async function collectImports(node: ts.Node) {
|
|
331
|
-
if (
|
|
331
|
+
if (
|
|
332
|
+
(ts.isExportDeclaration(node) || ts.isImportDeclaration(node)) &&
|
|
333
|
+
node.moduleSpecifier &&
|
|
334
|
+
ts.isStringLiteral(node.moduleSpecifier)
|
|
335
|
+
) {
|
|
332
336
|
const importPath = node.moduleSpecifier.text;
|
|
333
337
|
|
|
334
338
|
// Handle relative imports
|
|
335
339
|
if (importPath.startsWith('.')) {
|
|
336
340
|
const resolvedPath = path.resolve(path.dirname(absoluteInputPath), importPath);
|
|
341
|
+
// TODO: does this handle index files correctly?
|
|
337
342
|
let resolvedTsPath = resolvedPath + '.ts';
|
|
338
343
|
// Also check for .tsx if .ts doesn't exist
|
|
339
344
|
if (!(await fs.pathExists(resolvedTsPath))) {
|
|
@@ -384,7 +389,9 @@ export async function compileFile({
|
|
|
384
389
|
const potentialPathBase = path.resolve(tsConfigInfo.baseUrl, patternPrefix);
|
|
385
390
|
const resolvedPath = path.join(potentialPathBase, remainingImportPath);
|
|
386
391
|
|
|
387
|
-
let resolvedTsPath = resolvedPath
|
|
392
|
+
let resolvedTsPath = resolvedPath.endsWith('.ts')
|
|
393
|
+
? resolvedPath
|
|
394
|
+
: resolvedPath + '.ts';
|
|
388
395
|
// Similar existence checks as relative paths
|
|
389
396
|
if (!(await fs.pathExists(resolvedTsPath))) {
|
|
390
397
|
const resolvedTsxPath = resolvedPath + '.tsx';
|
|
@@ -429,6 +436,7 @@ export async function compileFile({
|
|
|
429
436
|
ts.isModuleBlock(child) ||
|
|
430
437
|
ts.isModuleDeclaration(child) ||
|
|
431
438
|
ts.isImportDeclaration(child) ||
|
|
439
|
+
ts.isExportDeclaration(child) ||
|
|
432
440
|
child.kind === ts.SyntaxKind.SyntaxList
|
|
433
441
|
) {
|
|
434
442
|
await collectImports(child);
|