@vendure/dashboard 3.7.1-master-202607140305 → 3.7.1

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.
Files changed (50) hide show
  1. package/dist/bundle/chunks/{2SSKDMRQ-V0WKsSRc.js → 2SSKDMRQ-CGPzX7ok.js} +2 -2
  2. package/dist/bundle/chunks/{AP7HFJJL-BBddTq2E.js → AP7HFJJL-BANaC6nc.js} +1 -1
  3. package/dist/bundle/chunks/{WDYDFRGG-D26K3Vrv.js → WDYDFRGG-DWwEqh2h.js} +2 -2
  4. package/dist/bundle/chunks/{locale-jQNDhpzW.js → locale--aauL66m.js} +1 -1
  5. package/dist/bundle/chunks/{main-B15rd9Eg.js → main-DVt3RsH7.js} +58 -919
  6. package/dist/bundle/chunks/{use-job-queue-polling-DeVrn1rW.js → use-job-queue-polling-mUjHlukj.js} +1328 -12522
  7. package/dist/bundle/lib.js +584 -577
  8. package/dist/bundle/main.js +4 -2
  9. package/dist/plugin/service/metrics.service.js +1 -1
  10. package/dist/vite/lib-externals.d.ts +44 -0
  11. package/dist/vite/lib-externals.js +80 -0
  12. package/dist/vite/vite-plugin-config.js +8 -0
  13. package/package.json +4 -3
  14. package/src/app/routes/_authenticated/_orders/components/edit-order-table.tsx +79 -44
  15. package/src/lib/components/layout/nav-main.tsx +3 -1
  16. package/src/lib/framework/document-introspection/add-custom-fields.ts +2 -2
  17. package/src/lib/framework/document-introspection/include-only-selected-list-fields.ts +4 -1
  18. package/src/lib/framework/extension-api/custom-providers.ts +1 -1
  19. package/dist/vite/.vendure-dashboard-temp/compiler/4341-310b0b9d-e6f1-423a-bc14-79424bdf705f/dev-config.js +0 -251
  20. package/dist/vite/.vendure-dashboard-temp/compiler/4341-310b0b9d-e6f1-423a-bc14-79424bdf705f/package.json +0 -4
  21. package/dist/vite/.vendure-dashboard-temp/compiler/4341-310b0b9d-e6f1-423a-bc14-79424bdf705f/test-plugins/nav-modifier-plugin/nav-modifier-plugin.js +0 -23
  22. package/dist/vite/.vendure-dashboard-temp/compiler/4341-310b0b9d-e6f1-423a-bc14-79424bdf705f/test-plugins/reviews/api/api-extensions.js +0 -99
  23. package/dist/vite/.vendure-dashboard-temp/compiler/4341-310b0b9d-e6f1-423a-bc14-79424bdf705f/test-plugins/reviews/api/product-entity.resolver.js +0 -73
  24. package/dist/vite/.vendure-dashboard-temp/compiler/4341-310b0b9d-e6f1-423a-bc14-79424bdf705f/test-plugins/reviews/api/product-review-admin.resolver.js +0 -146
  25. package/dist/vite/.vendure-dashboard-temp/compiler/4341-310b0b9d-e6f1-423a-bc14-79424bdf705f/test-plugins/reviews/api/product-review-entity.resolver.js +0 -79
  26. package/dist/vite/.vendure-dashboard-temp/compiler/4341-310b0b9d-e6f1-423a-bc14-79424bdf705f/test-plugins/reviews/api/product-review-shop.resolver.js +0 -79
  27. package/dist/vite/.vendure-dashboard-temp/compiler/4341-310b0b9d-e6f1-423a-bc14-79424bdf705f/test-plugins/reviews/entities/product-review-translation.entity.js +0 -47
  28. package/dist/vite/.vendure-dashboard-temp/compiler/4341-310b0b9d-e6f1-423a-bc14-79424bdf705f/test-plugins/reviews/entities/product-review.entity.js +0 -90
  29. package/dist/vite/.vendure-dashboard-temp/compiler/4341-310b0b9d-e6f1-423a-bc14-79424bdf705f/test-plugins/reviews/generated-admin-types.js +0 -1021
  30. package/dist/vite/.vendure-dashboard-temp/compiler/4341-310b0b9d-e6f1-423a-bc14-79424bdf705f/test-plugins/reviews/generated-shop-types.js +0 -974
  31. package/dist/vite/.vendure-dashboard-temp/compiler/4341-310b0b9d-e6f1-423a-bc14-79424bdf705f/test-plugins/reviews/reviews-plugin.js +0 -46
  32. package/dist/vite/.vendure-dashboard-temp/compiler/4341-310b0b9d-e6f1-423a-bc14-79424bdf705f/test-plugins/reviews/types.js +0 -2
  33. package/dist/vite/.vendure-dashboard-temp/gql-tada/4341-310b0b9d-e6f1-423a-bc14-79424bdf705f/schema.graphql +0 -6844
  34. package/dist/vite/.vendure-dashboard-temp/gql-tada/4341-310b0b9d-e6f1-423a-bc14-79424bdf705f/tsconfig.json +0 -10
  35. /package/dist/vite/.vendure-dashboard-temp/compiler/{3415-45ea35af-1ad9-41c6-bb49-f9b5df410aba → 3313-17d5f23c-1ffd-4e86-b905-7235d2fbfa10}/dev-config.js +0 -0
  36. /package/dist/vite/.vendure-dashboard-temp/compiler/{3415-45ea35af-1ad9-41c6-bb49-f9b5df410aba → 3313-17d5f23c-1ffd-4e86-b905-7235d2fbfa10}/package.json +0 -0
  37. /package/dist/vite/.vendure-dashboard-temp/compiler/{3415-45ea35af-1ad9-41c6-bb49-f9b5df410aba → 3313-17d5f23c-1ffd-4e86-b905-7235d2fbfa10}/test-plugins/nav-modifier-plugin/nav-modifier-plugin.js +0 -0
  38. /package/dist/vite/.vendure-dashboard-temp/compiler/{3415-45ea35af-1ad9-41c6-bb49-f9b5df410aba → 3313-17d5f23c-1ffd-4e86-b905-7235d2fbfa10}/test-plugins/reviews/api/api-extensions.js +0 -0
  39. /package/dist/vite/.vendure-dashboard-temp/compiler/{3415-45ea35af-1ad9-41c6-bb49-f9b5df410aba → 3313-17d5f23c-1ffd-4e86-b905-7235d2fbfa10}/test-plugins/reviews/api/product-entity.resolver.js +0 -0
  40. /package/dist/vite/.vendure-dashboard-temp/compiler/{3415-45ea35af-1ad9-41c6-bb49-f9b5df410aba → 3313-17d5f23c-1ffd-4e86-b905-7235d2fbfa10}/test-plugins/reviews/api/product-review-admin.resolver.js +0 -0
  41. /package/dist/vite/.vendure-dashboard-temp/compiler/{3415-45ea35af-1ad9-41c6-bb49-f9b5df410aba → 3313-17d5f23c-1ffd-4e86-b905-7235d2fbfa10}/test-plugins/reviews/api/product-review-entity.resolver.js +0 -0
  42. /package/dist/vite/.vendure-dashboard-temp/compiler/{3415-45ea35af-1ad9-41c6-bb49-f9b5df410aba → 3313-17d5f23c-1ffd-4e86-b905-7235d2fbfa10}/test-plugins/reviews/api/product-review-shop.resolver.js +0 -0
  43. /package/dist/vite/.vendure-dashboard-temp/compiler/{3415-45ea35af-1ad9-41c6-bb49-f9b5df410aba → 3313-17d5f23c-1ffd-4e86-b905-7235d2fbfa10}/test-plugins/reviews/entities/product-review-translation.entity.js +0 -0
  44. /package/dist/vite/.vendure-dashboard-temp/compiler/{3415-45ea35af-1ad9-41c6-bb49-f9b5df410aba → 3313-17d5f23c-1ffd-4e86-b905-7235d2fbfa10}/test-plugins/reviews/entities/product-review.entity.js +0 -0
  45. /package/dist/vite/.vendure-dashboard-temp/compiler/{3415-45ea35af-1ad9-41c6-bb49-f9b5df410aba → 3313-17d5f23c-1ffd-4e86-b905-7235d2fbfa10}/test-plugins/reviews/generated-admin-types.js +0 -0
  46. /package/dist/vite/.vendure-dashboard-temp/compiler/{3415-45ea35af-1ad9-41c6-bb49-f9b5df410aba → 3313-17d5f23c-1ffd-4e86-b905-7235d2fbfa10}/test-plugins/reviews/generated-shop-types.js +0 -0
  47. /package/dist/vite/.vendure-dashboard-temp/compiler/{3415-45ea35af-1ad9-41c6-bb49-f9b5df410aba → 3313-17d5f23c-1ffd-4e86-b905-7235d2fbfa10}/test-plugins/reviews/reviews-plugin.js +0 -0
  48. /package/dist/vite/.vendure-dashboard-temp/compiler/{3415-45ea35af-1ad9-41c6-bb49-f9b5df410aba → 3313-17d5f23c-1ffd-4e86-b905-7235d2fbfa10}/test-plugins/reviews/types.js +0 -0
  49. /package/dist/vite/.vendure-dashboard-temp/gql-tada/{3415-45ea35af-1ad9-41c6-bb49-f9b5df410aba → 3313-17d5f23c-1ffd-4e86-b905-7235d2fbfa10}/schema.graphql +0 -0
  50. /package/dist/vite/.vendure-dashboard-temp/gql-tada/{3415-45ea35af-1ad9-41c6-bb49-f9b5df410aba → 3313-17d5f23c-1ffd-4e86-b905-7235d2fbfa10}/tsconfig.json +0 -0
@@ -1,6 +1,8 @@
1
1
  import "react/jsx-runtime";
2
- import "./chunks/use-job-queue-polling-DeVrn1rW.js";
3
- import "./chunks/main-B15rd9Eg.js";
2
+ import "./chunks/use-job-queue-polling-mUjHlukj.js";
3
+ import "sonner";
4
+ import "./chunks/main-DVt3RsH7.js";
5
+ import "@tanstack/react-router";
4
6
  import "react";
5
7
  import "react-dom";
6
8
  import "react-dom/client";
@@ -34,7 +34,7 @@ let MetricsService = class MetricsService {
34
34
  .update(JSON.stringify({
35
35
  startDate: calculatedStartDate,
36
36
  endDate: calculatedEndDate,
37
- types: [...types].sort(),
37
+ types: [...types].sort((a, b) => a.localeCompare(b)),
38
38
  channel: ctx.channel.token,
39
39
  }))
40
40
  .digest('base64');
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Dependencies kept **external** in the pre-built dashboard bundle
3
+ * (`dist/bundle`, produced by `vite.lib.config.mts`).
4
+ *
5
+ * Anything not listed here is frozen into the bundle's shared chunks. That is
6
+ * fine for leaf utilities, but a library that (a) owns a React Context or other
7
+ * module-level singleton AND (b) is reachable by extension code through the
8
+ * `@vendure/dashboard` public API MUST be external. Otherwise the consumer's
9
+ * separate extension build re-bundles a second copy: the two module instances
10
+ * each call `createContext()`, and the extension's hook reads a different
11
+ * context than the one the dashboard's provider populated — the "No QueryClient
12
+ * set" class of failure. See issue #4919.
13
+ *
14
+ * A duplication audit that turns this contract into a test lives in
15
+ * `vite/tests/bundle-singleton.spec.ts`.
16
+ */
17
+ /**
18
+ * Always-external: resolved from the consumer's own module graph at runtime
19
+ * (React, Lingui) or injected by the consumer's Vite plugins (`virtual:*`).
20
+ */
21
+ export declare const runtimePeers: Array<string | RegExp>;
22
+ /**
23
+ * Context- and singleton-bearing libraries that must be **shared** between the
24
+ * dashboard app and extension code rather than frozen into the bundle. Keeping
25
+ * them external means both `main.js` (which renders the providers) and an
26
+ * extension's separately-built code resolve to the consumer's single instance.
27
+ */
28
+ export declare const singletonSharedDeps: Array<string | RegExp>;
29
+ /**
30
+ * Bare specifiers of {@link singletonSharedDeps}, for the consumer dev server's
31
+ * dep optimizer (`optimizeDeps.include`) so every bare import — from the
32
+ * pre-built `main.js`, from `lib.js`, and from extension code — resolves to one
33
+ * pre-bundled instance.
34
+ */
35
+ export declare const singletonSharedDepNames: string[];
36
+ /**
37
+ * The full external list for the dashboard bundle build.
38
+ */
39
+ export declare const dashboardBundleExternals: Array<string | RegExp>;
40
+ /**
41
+ * Returns `true` if `id` is matched by any entry in `externals` (string exact
42
+ * match or subpath, or RegExp test).
43
+ */
44
+ export declare function isExternalId(id: string, externals: Array<string | RegExp>): boolean;
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Dependencies kept **external** in the pre-built dashboard bundle
3
+ * (`dist/bundle`, produced by `vite.lib.config.mts`).
4
+ *
5
+ * Anything not listed here is frozen into the bundle's shared chunks. That is
6
+ * fine for leaf utilities, but a library that (a) owns a React Context or other
7
+ * module-level singleton AND (b) is reachable by extension code through the
8
+ * `@vendure/dashboard` public API MUST be external. Otherwise the consumer's
9
+ * separate extension build re-bundles a second copy: the two module instances
10
+ * each call `createContext()`, and the extension's hook reads a different
11
+ * context than the one the dashboard's provider populated — the "No QueryClient
12
+ * set" class of failure. See issue #4919.
13
+ *
14
+ * A duplication audit that turns this contract into a test lives in
15
+ * `vite/tests/bundle-singleton.spec.ts`.
16
+ */
17
+ /**
18
+ * Always-external: resolved from the consumer's own module graph at runtime
19
+ * (React, Lingui) or injected by the consumer's Vite plugins (`virtual:*`).
20
+ */
21
+ export const runtimePeers = [
22
+ // React core (peer deps in user projects)
23
+ 'react',
24
+ 'react-dom',
25
+ 'react-dom/client',
26
+ 'react/jsx-runtime',
27
+ 'react/jsx-dev-runtime',
28
+ // Lingui — macros are transformed separately; keep the runtime external
29
+ /^@lingui\//,
30
+ // Virtual modules — resolved by the consumer's vendureDashboardPlugin
31
+ /^virtual:/,
32
+ // @vendure/common is a peer of every Vendure plugin
33
+ /^@vendure\/common(\/|$)/,
34
+ // The dashboard's own subpath exports
35
+ '@vendure/dashboard/plugin',
36
+ '@vendure/dashboard/vite',
37
+ ];
38
+ /**
39
+ * Context- and singleton-bearing libraries that must be **shared** between the
40
+ * dashboard app and extension code rather than frozen into the bundle. Keeping
41
+ * them external means both `main.js` (which renders the providers) and an
42
+ * extension's separately-built code resolve to the consumer's single instance.
43
+ */
44
+ export const singletonSharedDeps = [
45
+ // @tanstack/react-query — QueryClientContext
46
+ '@tanstack/react-query',
47
+ // react-hook-form — FormProvider context
48
+ 'react-hook-form',
49
+ // @tanstack/react-router — RouterContext (companion packages travel with it
50
+ // since the whole package stays external)
51
+ /^@tanstack\/react-router(\/|$)/,
52
+ // sonner — module-level toast observer
53
+ 'sonner',
54
+ ];
55
+ /**
56
+ * Bare specifiers of {@link singletonSharedDeps}, for the consumer dev server's
57
+ * dep optimizer (`optimizeDeps.include`) so every bare import — from the
58
+ * pre-built `main.js`, from `lib.js`, and from extension code — resolves to one
59
+ * pre-bundled instance.
60
+ */
61
+ export const singletonSharedDepNames = [
62
+ '@tanstack/react-query',
63
+ 'react-hook-form',
64
+ '@tanstack/react-router',
65
+ 'sonner',
66
+ ];
67
+ /**
68
+ * The full external list for the dashboard bundle build.
69
+ */
70
+ export const dashboardBundleExternals = [
71
+ ...runtimePeers,
72
+ ...singletonSharedDeps,
73
+ ];
74
+ /**
75
+ * Returns `true` if `id` is matched by any entry in `externals` (string exact
76
+ * match or subpath, or RegExp test).
77
+ */
78
+ export function isExternalId(id, externals) {
79
+ return externals.some(entry => typeof entry === 'string' ? id === entry || id.startsWith(`${entry}/`) : entry.test(id));
80
+ }
@@ -1,4 +1,5 @@
1
1
  import path from 'path';
2
+ import { singletonSharedDepNames } from './lib-externals.js';
2
3
  export function viteConfigPlugin({ packageRoot, useExperimentalBundle }) {
3
4
  return {
4
5
  name: 'vendure:vite-config-plugin',
@@ -67,6 +68,13 @@ export function viteConfigPlugin({ packageRoot, useExperimentalBundle }) {
67
68
  'use-sync-external-store/shim',
68
69
  'use-sync-external-store/shim/with-selector',
69
70
  '@messageformat/parser',
71
+ // In bundle mode these context/singleton libraries are kept
72
+ // external from the pre-built bundle (see lib-externals.ts),
73
+ // so pre-bundle them here to guarantee that main.js, lib.js
74
+ // and extension code all resolve to ONE instance. Without
75
+ // this the dashboard's provider and an extension's hook can
76
+ // bind to different module instances — issue #4919.
77
+ ...(useExperimentalBundle ? singletonSharedDepNames : []),
70
78
  ] });
71
79
  return config;
72
80
  },
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@vendure/dashboard",
3
3
  "private": false,
4
- "version": "3.7.1-master-202607140305",
4
+ "version": "3.7.1",
5
5
  "type": "module",
6
6
  "repository": {
7
7
  "type": "git",
@@ -22,6 +22,7 @@
22
22
  "build": "npm run check-types && npm run build:vite && npm run build:plugin && npm run build:lib",
23
23
  "watch": "tsc --project tsconfig.vite.json --watch",
24
24
  "test": "vitest run",
25
+ "audit:bundle": "cross-env RUN_BUNDLE_AUDIT=true vitest run vite/tests/bundle-singleton.spec.ts vite/tests/bundle-singleton-dev-serving.spec.ts",
25
26
  "lint": "eslint .",
26
27
  "preview": "vite preview",
27
28
  "generate-index": "node scripts/generate-index.js",
@@ -138,8 +139,8 @@
138
139
  "@storybook/addon-vitest": "^10.3.1",
139
140
  "@storybook/react-vite": "^10.3.1",
140
141
  "@types/node": "^22.19.0",
141
- "@vendure/common": "^3.7.1-master-202607140305",
142
- "@vendure/core": "^3.7.1-master-202607140305",
142
+ "@vendure/common": "3.7.1",
143
+ "@vendure/core": "3.7.1",
143
144
  "@vitest/browser": "^3.2.4",
144
145
  "@vitest/coverage-v8": "^3.2.4",
145
146
  "eslint": "^9.39.0",
@@ -14,7 +14,7 @@ import {
14
14
  VisibilityState,
15
15
  } from '@tanstack/react-table';
16
16
  import { Trash2 } from 'lucide-react';
17
- import { useMemo, useState } from 'react';
17
+ import { useEffect, useMemo, useState } from 'react';
18
18
  import {
19
19
  couponCodeSelectorPromotionListDocument,
20
20
  draftOrderEligibleShippingMethodsDocument,
@@ -27,6 +27,77 @@ import { OrderTableTotals } from './order-table-totals.js';
27
27
  import { ShippingMethodSelector } from './shipping-method-selector.js';
28
28
 
29
29
  type OrderFragment = NonNullable<ResultOf<typeof orderDetailDocument>['order']>;
30
+
31
+ function QuantityCell({
32
+ line,
33
+ onAdjustLine,
34
+ onRemoveLine,
35
+ }: {
36
+ line: OrderLineFragment & { customFields?: Record<string, any> };
37
+ onAdjustLine: OrderTableProps['onAdjustLine'];
38
+ onRemoveLine: OrderTableProps['onRemoveLine'];
39
+ }) {
40
+ const [localValue, setLocalValue] = useState<string>(String(line.quantity));
41
+
42
+ // Sync local value when server state changes (e.g. after mutation completes)
43
+ useEffect(() => {
44
+ setLocalValue(String(line.quantity));
45
+ }, [line.quantity]);
46
+
47
+ const commitValue = (removeOnZero: boolean) => {
48
+ const numValue = localValue === '' ? 0 : Number(localValue);
49
+ if (numValue <= 0 || Number.isNaN(numValue)) {
50
+ if (removeOnZero) {
51
+ onRemoveLine({ lineId: line.id });
52
+ } else {
53
+ // Revert to the server value on blur
54
+ setLocalValue(String(line.quantity));
55
+ }
56
+ } else if (numValue !== line.quantity) {
57
+ onAdjustLine({ lineId: line.id, quantity: numValue, customFields: line.customFields });
58
+ }
59
+ };
60
+
61
+ return (
62
+ <div className="flex gap-2">
63
+ <Input
64
+ type="number"
65
+ value={localValue}
66
+ min={0}
67
+ placeholder="0"
68
+ data-testid="order-line-quantity"
69
+ onChange={e => setLocalValue(e.target.value)}
70
+ onKeyDown={e => {
71
+ if (e.key === 'Enter') {
72
+ e.preventDefault();
73
+ commitValue(true);
74
+ }
75
+ }}
76
+ onBlur={() => commitValue(false)}
77
+ />
78
+ <Button
79
+ variant="outline"
80
+ type="button"
81
+ size="icon"
82
+ onClick={() => onRemoveLine({ lineId: line.id })}
83
+ >
84
+ <Trash2 />
85
+ </Button>
86
+ {line.customFields && (
87
+ <OrderLineCustomFieldsForm
88
+ onUpdate={customFields => {
89
+ onAdjustLine({
90
+ lineId: line.id,
91
+ quantity: line.quantity,
92
+ customFields: customFields,
93
+ });
94
+ }}
95
+ value={line.customFields}
96
+ />
97
+ )}
98
+ </div>
99
+ );
100
+ }
30
101
  type OrderLineFragment = ResultOf<typeof orderLineFragment>;
31
102
 
32
103
  type ShippingMethodQuote = ResultOf<
@@ -110,49 +181,13 @@ export function EditOrderTable({
110
181
  {
111
182
  header: t`Quantity`,
112
183
  accessorKey: 'quantity',
113
- cell: ({ row }) => {
114
- return (
115
- <div className="flex gap-2">
116
- <Input
117
- type="number"
118
- value={row.original.quantity}
119
- min={0}
120
- data-testid="order-line-quantity"
121
- onChange={e => {
122
- const value = Number.isNaN(e.target.valueAsNumber)
123
- ? 0
124
- : e.target.valueAsNumber;
125
- onAdjustLine({
126
- lineId: row.original.id,
127
- quantity: value,
128
- customFields: row.original.customFields,
129
- });
130
- }}
131
- />
132
- <Button
133
- variant="outline"
134
- type="button"
135
- size="icon"
136
- disabled={row.original.quantity === 0}
137
- onClick={() => onRemoveLine({ lineId: row.original.id })}
138
- >
139
- <Trash2 />
140
- </Button>
141
- {row.original.customFields && (
142
- <OrderLineCustomFieldsForm
143
- onUpdate={customFields => {
144
- onAdjustLine({
145
- lineId: row.original.id,
146
- quantity: row.original.quantity,
147
- customFields: customFields,
148
- });
149
- }}
150
- value={row.original.customFields}
151
- />
152
- )}
153
- </div>
154
- );
155
- },
184
+ cell: ({ row }) => (
185
+ <QuantityCell
186
+ line={row.original}
187
+ onAdjustLine={onAdjustLine}
188
+ onRemoveLine={onRemoveLine}
189
+ />
190
+ ),
156
191
  },
157
192
  {
158
193
  header: t`Total`,
@@ -184,7 +184,9 @@ export function NavMain({ items }: Readonly<{ items: Array<NavMenuSection | NavM
184
184
  .map(section => {
185
185
  if ('items' in section) {
186
186
  // Filter items based on permissions
187
- const allowedItems = (section.items ?? []).filter(isItemAllowed).sort(sortByOrder);
187
+ const allowedItems = (section.items ?? [])
188
+ .filter(item => isItemAllowed(item))
189
+ .sort(sortByOrder);
188
190
  return { ...section, items: allowedItems };
189
191
  }
190
192
  return section;
@@ -50,11 +50,11 @@ function createOptionsKey(options?: {
50
50
  }
51
51
 
52
52
  if (options.includeCustomFields) {
53
- parts.push(`include:${[...options.includeCustomFields].sort().join(',')}`);
53
+ parts.push(`include:${[...options.includeCustomFields].sort((a, b) => a.localeCompare(b)).join(',')}`);
54
54
  }
55
55
 
56
56
  if (options.includeNestedFragments) {
57
- parts.push(`nested:${[...options.includeNestedFragments].sort().join(',')}`);
57
+ parts.push(`nested:${[...options.includeNestedFragments].sort((a, b) => a.localeCompare(b)).join(',')}`);
58
58
  }
59
59
 
60
60
  return parts.join('|') || 'default';
@@ -73,7 +73,10 @@ function createCacheKey(
73
73
  }
74
74
 
75
75
  function sortJoin<T>(arr: T[], separator: string): string {
76
- return arr.slice(0).sort().join(separator);
76
+ return arr
77
+ .slice(0)
78
+ .sort((a, b) => String(a).localeCompare(String(b)))
79
+ .join(separator);
77
80
  }
78
81
 
79
82
  /**
@@ -85,7 +85,7 @@ export function registerDashboardCustomProviders(providers: DashboardCustomProvi
85
85
  }
86
86
 
87
87
  if (duplicateIds.size) {
88
- const duplicates = Array.from(duplicateIds).sort();
88
+ const duplicates = Array.from(duplicateIds).sort((a, b) => a.localeCompare(b));
89
89
  throw new Error(
90
90
  `Duplicate dashboard custom provider ids detected: ` +
91
91
  `${duplicates.map(id => `"${id}"`).join(', ')}. ` +
@@ -1,251 +0,0 @@
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
- var __metadata = (this && this.__metadata) || function (k, v) {
9
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
- };
11
- var __importDefault = (this && this.__importDefault) || function (mod) {
12
- return (mod && mod.__esModule) ? mod : { "default": mod };
13
- };
14
- var _a, _b;
15
- Object.defineProperty(exports, "__esModule", { value: true });
16
- exports.devConfig = void 0;
17
- const admin_ui_plugin_1 = require("@vendure/admin-ui-plugin");
18
- const asset_server_plugin_1 = require("@vendure/asset-server-plugin");
19
- const shared_constants_1 = require("@vendure/common/lib/shared-constants");
20
- const core_1 = require("@vendure/core");
21
- const plugin_1 = require("@vendure/dashboard/plugin");
22
- const email_plugin_1 = require("@vendure/email-plugin");
23
- const graphiql_plugin_1 = require("@vendure/graphiql-plugin");
24
- const telemetry_plugin_1 = require("@vendure/telemetry-plugin");
25
- require("dotenv/config");
26
- const path_1 = __importDefault(require("path"));
27
- const nav_modifier_plugin_1 = require("./test-plugins/nav-modifier-plugin/nav-modifier-plugin");
28
- // import { FieldTestPlugin } from './test-plugins/field-test/field-test-plugin';
29
- const reviews_plugin_1 = require("./test-plugins/reviews/reviews-plugin");
30
- const IS_INSTRUMENTED = process.env.IS_INSTRUMENTED === 'true';
31
- const dashboardAppDir = path_1.default.basename(__dirname) === 'dist'
32
- ? path_1.default.join(__dirname, './dashboard')
33
- : path_1.default.join(__dirname, './dist/dashboard');
34
- let ReadonlySettingsTestPlugin = class ReadonlySettingsTestPlugin {
35
- constructor(settingsStoreService, requestContextService) {
36
- this.settingsStoreService = settingsStoreService;
37
- this.requestContextService = requestContextService;
38
- }
39
- async onApplicationBootstrap() {
40
- const ctx = await this.requestContextService.create({ apiType: 'admin' });
41
- await this.settingsStoreService.set(ctx, 'ReadonlyTest.buildVersion', 'v3.5.2');
42
- await this.settingsStoreService.set(ctx, 'ReadonlyTest.buildMeta', {
43
- buildDate: '2026-03-06',
44
- commit: 'd0384f3ed',
45
- features: ['settings-store-ui', 'option-groups'],
46
- });
47
- }
48
- };
49
- ReadonlySettingsTestPlugin = __decorate([
50
- (0, core_1.VendurePlugin)({
51
- imports: [core_1.PluginCommonModule],
52
- configuration: config => {
53
- config.settingsStoreFields = {
54
- ...config.settingsStoreFields,
55
- ReadonlyTest: [
56
- { name: 'buildVersion', readonly: true },
57
- { name: 'buildMeta', readonly: true },
58
- ],
59
- };
60
- return config;
61
- },
62
- }),
63
- __metadata("design:paramtypes", [typeof (_a = typeof core_1.SettingsStoreService !== "undefined" && core_1.SettingsStoreService) === "function" ? _a : Object, typeof (_b = typeof core_1.RequestContextService !== "undefined" && core_1.RequestContextService) === "function" ? _b : Object])
64
- ], ReadonlySettingsTestPlugin);
65
- /**
66
- * Config settings used during development
67
- */
68
- exports.devConfig = {
69
- apiOptions: {
70
- port: Number(process.env.API_PORT) || shared_constants_1.API_PORT,
71
- adminApiPath: shared_constants_1.ADMIN_API_PATH,
72
- adminApiPlayground: {
73
- settings: {
74
- 'request.credentials': 'include',
75
- },
76
- },
77
- adminApiDebug: true,
78
- shopApiPath: shared_constants_1.SHOP_API_PATH,
79
- shopApiPlayground: {
80
- settings: {
81
- 'request.credentials': 'include',
82
- },
83
- },
84
- shopApiDebug: true,
85
- },
86
- authOptions: {
87
- disableAuth: false,
88
- tokenMethod: ['bearer', 'cookie', 'api-key'],
89
- requireVerification: true,
90
- customPermissions: [],
91
- cookieOptions: {
92
- secret: 'abc',
93
- },
94
- },
95
- dbConnectionOptions: {
96
- synchronize: false,
97
- logging: false,
98
- migrations: [path_1.default.join(__dirname, 'migrations/*.ts')],
99
- ...getDbConfig(),
100
- },
101
- paymentOptions: {
102
- paymentMethodHandlers: [core_1.dummyPaymentHandler],
103
- },
104
- settingsStoreFields: {
105
- MyPlugin: [
106
- {
107
- name: 'globalVal',
108
- },
109
- {
110
- name: 'userVal',
111
- scope: core_1.SettingsStoreScopes.user,
112
- },
113
- ],
114
- },
115
- customFields: {},
116
- logger: new core_1.DefaultLogger({ level: core_1.LogLevel.Verbose }),
117
- importExportOptions: {
118
- importAssetsDir: path_1.default.join(__dirname, 'import-assets'),
119
- },
120
- plugins: [
121
- // MultivendorPlugin.init({
122
- // platformFeePercent: 10,
123
- // platformFeeSKU: 'FEE',
124
- // }),
125
- ReadonlySettingsTestPlugin,
126
- reviews_plugin_1.ReviewsPlugin,
127
- // FieldTestPlugin,
128
- nav_modifier_plugin_1.NavModifierPlugin,
129
- graphiql_plugin_1.GraphiqlPlugin.init(),
130
- asset_server_plugin_1.AssetServerPlugin.init({
131
- route: 'assets',
132
- assetUploadDir: path_1.default.join(__dirname, 'assets'),
133
- }),
134
- core_1.DefaultSearchPlugin.init({ bufferUpdates: false, indexStockStatus: false }),
135
- // Enable if you need to debug the job queue
136
- // BullMQJobQueuePlugin.init({}),
137
- core_1.DefaultJobQueuePlugin.init({}),
138
- // JobQueueTestPlugin.init({ queueCount: 10 }),
139
- core_1.DefaultSchedulerPlugin.init({}),
140
- email_plugin_1.EmailPlugin.init({
141
- devMode: true,
142
- route: 'mailbox',
143
- handlers: email_plugin_1.defaultEmailHandlers,
144
- templateLoader: new email_plugin_1.FileBasedTemplateLoader(path_1.default.join(__dirname, '../email-plugin/templates')),
145
- outputPath: path_1.default.join(__dirname, 'test-emails'),
146
- globalTemplateVars: {
147
- verifyEmailAddressUrl: 'http://localhost:4201/verify',
148
- passwordResetUrl: 'http://localhost:4201/reset-password',
149
- changeEmailAddressUrl: 'http://localhost:4201/change-email-address',
150
- },
151
- }),
152
- ...(IS_INSTRUMENTED ? [telemetry_plugin_1.TelemetryPlugin.init({})] : []),
153
- // AdminUiPlugin.init({
154
- // route: 'admin',
155
- // port: 5001,
156
- // adminUiConfig: {},
157
- // // Un-comment to compile a custom admin ui
158
- // // app: compileUiExtensions({
159
- // // outputPath: path.join(__dirname, './custom-admin-ui'),
160
- // // extensions: [
161
- // // {
162
- // // id: 'ui-extensions-library',
163
- // // extensionPath: path.join(__dirname, 'example-plugins/ui-extensions-library/ui'),
164
- // // routes: [{ route: 'ui-library', filePath: 'routes.ts' }],
165
- // // providers: ['providers.ts'],
166
- // // },
167
- // // {
168
- // // globalStyles: path.join(
169
- // // __dirname,
170
- // // 'test-plugins/with-ui-extension/ui/custom-theme.scss',
171
- // // ),
172
- // // },
173
- // // ],
174
- // // devMode: true,
175
- // // }),
176
- // }),
177
- admin_ui_plugin_1.AdminUiPlugin.init({
178
- route: 'admin',
179
- port: 5001,
180
- adminUiConfig: {},
181
- // Un-comment to compile a custom admin ui
182
- // app: compileUiExtensions({
183
- // outputPath: path.join(__dirname, './custom-admin-ui'),
184
- // extensions: [
185
- // {
186
- // id: 'ui-extensions-library',
187
- // extensionPath: path.join(__dirname, 'example-plugins/ui-extensions-library/ui'),
188
- // routes: [{ route: 'ui-library', filePath: 'routes.ts' }],
189
- // providers: ['providers.ts'],
190
- // },
191
- // {
192
- // globalStyles: path.join(
193
- // __dirname,
194
- // 'test-plugins/with-ui-extension/ui/custom-theme.scss',
195
- // ),
196
- // },
197
- // ],
198
- // devMode: true,
199
- // }),
200
- }),
201
- plugin_1.DashboardPlugin.init({
202
- route: 'dashboard',
203
- appDir: dashboardAppDir,
204
- }),
205
- ],
206
- };
207
- function getDbConfig() {
208
- const dbType = process.env.DB || 'mysql';
209
- switch (dbType) {
210
- case 'postgres':
211
- console.log('Using postgres connection');
212
- return {
213
- synchronize: true,
214
- type: 'postgres',
215
- host: process.env.DB_HOST || 'localhost',
216
- port: Number(process.env.DB_PORT) || 5432,
217
- username: process.env.DB_USERNAME || 'vendure',
218
- password: process.env.DB_PASSWORD || 'password',
219
- database: process.env.DB_NAME || 'vendure-dev',
220
- schema: process.env.DB_SCHEMA || 'public',
221
- };
222
- case 'sqlite':
223
- console.log('Using sqlite connection');
224
- return {
225
- synchronize: true,
226
- type: 'better-sqlite3',
227
- database: path_1.default.join(__dirname, 'vendure.sqlite'),
228
- };
229
- case 'sqljs':
230
- console.log('Using sql.js connection');
231
- return {
232
- type: 'sqljs',
233
- autoSave: true,
234
- database: new Uint8Array([]),
235
- location: path_1.default.join(__dirname, 'vendure.sqlite'),
236
- };
237
- case 'mysql':
238
- case 'mariadb':
239
- default:
240
- console.log('Using mysql connection');
241
- return {
242
- synchronize: true,
243
- type: 'mariadb',
244
- host: '127.0.0.1',
245
- port: 3306,
246
- username: 'vendure',
247
- password: 'password',
248
- database: 'vendure-dev',
249
- };
250
- }
251
- }