@mercurjs/dashboard-sdk 2.0.0-canary.73 → 2.0.0-canary.75

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/index.cjs CHANGED
@@ -38,7 +38,31 @@ module.exports = __toCommonJS(index_exports);
38
38
  var import_path5 = __toESM(require("path"), 1);
39
39
  var import_fs4 = __toESM(require("fs"), 1);
40
40
 
41
+ // src/babel.ts
42
+ var import_parser = require("@babel/parser");
43
+ var import_traverse = __toESM(require("@babel/traverse"), 1);
44
+ var import_types = require("@babel/types");
45
+ var traverse;
46
+ if (typeof import_traverse.default === "function") {
47
+ traverse = import_traverse.default;
48
+ } else {
49
+ traverse = import_traverse.default.default;
50
+ }
51
+
41
52
  // src/utils.ts
53
+ function normalizePath(filePath) {
54
+ return filePath.replace(/\\/g, "/");
55
+ }
56
+ function getParserOptions(file) {
57
+ const options = {
58
+ sourceType: "module",
59
+ plugins: ["jsx"]
60
+ };
61
+ if (file.endsWith(".ts") || file.endsWith(".tsx")) {
62
+ options.plugins.push("typescript");
63
+ }
64
+ return options;
65
+ }
42
66
  function resolveExports(moduleExports) {
43
67
  if ("default" in moduleExports && moduleExports.default && "default" in moduleExports.default) {
44
68
  return resolveExports(moduleExports.default);
@@ -67,8 +91,27 @@ var safeRegister = async () => {
67
91
  }
68
92
  return res;
69
93
  };
70
- function normalizePath(filePath) {
71
- return filePath.replace(/\\/g, "/");
94
+ function hasDefaultExport(ast) {
95
+ let found = false;
96
+ traverse(ast, {
97
+ ExportDefaultDeclaration() {
98
+ found = true;
99
+ },
100
+ AssignmentExpression(path6) {
101
+ if (path6.node.left.type === "MemberExpression" && path6.node.left.object.type === "Identifier" && path6.node.left.object.name === "exports" && path6.node.left.property.type === "Identifier" && path6.node.left.property.name === "default") {
102
+ found = true;
103
+ }
104
+ },
105
+ ExportNamedDeclaration(path6) {
106
+ const specifiers = path6.node.specifiers;
107
+ if (specifiers?.some(
108
+ (s) => s.type === "ExportSpecifier" && s.exported.type === "Identifier" && s.exported.name === "default"
109
+ )) {
110
+ found = true;
111
+ }
112
+ }
113
+ });
114
+ return found;
72
115
  }
73
116
 
74
117
  // src/constants.ts
@@ -127,31 +170,51 @@ function crawlPages(dir, pattern = "page") {
127
170
  }
128
171
  return files;
129
172
  }
130
- function hasDefaultExport(filePath) {
131
- try {
132
- const content = import_fs.default.readFileSync(filePath, "utf-8");
133
- return /export\s+default\s+/.test(content) || /export\s*\{\s*[^}]*\s+as\s+default\s*[,}]/.test(content);
134
- } catch {
135
- return false;
136
- }
137
- }
138
- function hasConfigPublic(filePath) {
139
- try {
140
- const content = import_fs.default.readFileSync(filePath, "utf-8");
141
- return /export\s+const\s+config\s*=\s*\{[^}]*public\s*:\s*true/.test(content);
142
- } catch {
143
- return false;
144
- }
145
- }
146
- function getNamedExports(filePath) {
147
- try {
148
- const content = import_fs.default.readFileSync(filePath, "utf-8");
149
- const hasHandle = /export\s+(const|function|async\s+function)\s+handle\b/.test(content) || /export\s*\{[^}]*\bhandle\b[^}]*\}/.test(content);
150
- const hasLoader = /export\s+(const|function|async\s+function)\s+loader\b/.test(content) || /export\s*\{[^}]*\bloader\b[^}]*\}/.test(content);
151
- return { hasHandle, hasLoader };
152
- } catch {
153
- return { hasHandle: false, hasLoader: false };
154
- }
173
+ function hasConfigPublic(ast) {
174
+ let found = false;
175
+ traverse(ast, {
176
+ ExportNamedDeclaration(path6) {
177
+ const declaration = path6.node.declaration;
178
+ if (!(0, import_types.isVariableDeclaration)(declaration)) return;
179
+ for (const decl of declaration.declarations) {
180
+ if ((0, import_types.isVariableDeclarator)(decl) && (0, import_types.isIdentifier)(decl.id, { name: "config" }) && decl.init?.type === "ObjectExpression") {
181
+ const publicProp = decl.init.properties.find(
182
+ (prop) => (0, import_types.isObjectProperty)(prop) && (0, import_types.isIdentifier)(prop.key, { name: "public" }) && (0, import_types.isBooleanLiteral)(prop.value, { value: true })
183
+ );
184
+ if (publicProp) {
185
+ found = true;
186
+ }
187
+ }
188
+ }
189
+ }
190
+ });
191
+ return found;
192
+ }
193
+ function getNamedExports(ast) {
194
+ let hasHandle = false;
195
+ let hasLoader = false;
196
+ traverse(ast, {
197
+ ExportNamedDeclaration(path6) {
198
+ const declaration = path6.node.declaration;
199
+ if (declaration?.type === "VariableDeclaration") {
200
+ declaration.declarations.forEach((decl) => {
201
+ if (decl.id.type === "Identifier" && decl.id.name === "handle") {
202
+ hasHandle = true;
203
+ }
204
+ if (decl.id.type === "Identifier" && decl.id.name === "loader") {
205
+ hasLoader = true;
206
+ }
207
+ });
208
+ }
209
+ if (declaration?.type === "FunctionDeclaration" && declaration.id?.name === "loader") {
210
+ hasLoader = true;
211
+ }
212
+ if (declaration?.type === "FunctionDeclaration" && declaration.id?.name === "handle") {
213
+ hasHandle = true;
214
+ }
215
+ }
216
+ });
217
+ return { hasHandle, hasLoader };
155
218
  }
156
219
  function generateRouteComponentName(index) {
157
220
  return `RouteComponent${index}`;
@@ -217,18 +280,24 @@ ${indent}}`;
217
280
  return result;
218
281
  }
219
282
  function parseFile(file, pagesDir, index) {
220
- if (!hasDefaultExport(file)) {
283
+ try {
284
+ const code = import_fs.default.readFileSync(file, "utf-8");
285
+ const ast = (0, import_parser.parse)(code, getParserOptions(file));
286
+ if (!hasDefaultExport(ast)) {
287
+ return null;
288
+ }
289
+ const { hasHandle, hasLoader } = getNamedExports(ast);
290
+ const isPublic = hasConfigPublic(ast);
291
+ const routePath = getRoute(file, pagesDir);
292
+ const imports = generateImports(file, index, hasHandle, hasLoader);
293
+ const route = generateRouteObject(routePath, index, hasHandle, hasLoader, isPublic);
294
+ return {
295
+ imports,
296
+ route
297
+ };
298
+ } catch {
221
299
  return null;
222
300
  }
223
- const { hasHandle, hasLoader } = getNamedExports(file);
224
- const isPublic = hasConfigPublic(file);
225
- const routePath = getRoute(file, pagesDir);
226
- const imports = generateImports(file, index, hasHandle, hasLoader);
227
- const route = generateRouteObject(routePath, index, hasHandle, hasLoader, isPublic);
228
- return {
229
- imports,
230
- route
231
- };
232
301
  }
233
302
  function buildRouteTree(results) {
234
303
  const routeMap = /* @__PURE__ */ new Map();
@@ -242,7 +311,7 @@ function buildRouteTree(results) {
242
311
  const parentPath = routePath.split("/@")[0];
243
312
  const parent = routeMap.get(parentPath);
244
313
  if (parent) {
245
- parent.route.children = parent.route.children || [];
314
+ parent.route.children = parent.route.children ?? [];
246
315
  parent.route.children.push({
247
316
  ...result.route,
248
317
  path: result.route.path.replace("/@", "/")
@@ -268,11 +337,8 @@ function generateRoutes({ srcDir, pluginExtensions }) {
268
337
  index++;
269
338
  }
270
339
  }
271
- const pluginImports = pluginExtensions.map(
272
- (ext, i) => `import * as __pluginRaw${i} from "${normalizePath(ext)}"`
273
- );
274
- const pluginUnwraps = pluginExtensions.map(
275
- (_, i) => `const __plugin${i} = __pluginRaw${i}.default ?? __pluginRaw${i}`
340
+ const pluginDeclarations = pluginExtensions.map(
341
+ (ext, i) => `const __plugin${i} = (await import("${normalizePath(ext)}")).default`
276
342
  );
277
343
  const pluginSpreads = pluginExtensions.map(
278
344
  (_, i) => ` ...(__plugin${i}.routeModule?.routes ?? [])`
@@ -280,13 +346,15 @@ function generateRoutes({ srcDir, pluginExtensions }) {
280
346
  const routeTree = buildRouteTree(results);
281
347
  const appImports = routeTree.flatMap((r) => r.imports);
282
348
  const appRoutes = routeTree.map((r) => formatRoute(r.route));
283
- const allImports = [...appImports, ...pluginImports, ...pluginUnwraps];
349
+ const allImports = [...appImports];
284
350
  const allRoutes = [...appRoutes, ...pluginSpreads];
285
- if (allImports.length === 0 && allRoutes.length === 0) {
351
+ if (allImports.length === 0 && pluginDeclarations.length === 0 && allRoutes.length === 0) {
286
352
  return `export const customRoutes = []`;
287
353
  }
288
354
  return `${allImports.join("\n")}
289
355
 
356
+ ${pluginDeclarations.join("\n")}
357
+
290
358
  export const customRoutes = [
291
359
  ${allRoutes.join(",\n")}
292
360
  ]`;
@@ -325,29 +393,90 @@ function getRoute2(file, pagesDir) {
325
393
  ""
326
394
  ) || "/";
327
395
  }
328
- function hasConfigExport(filePath) {
329
- try {
330
- const content = import_fs2.default.readFileSync(filePath, "utf-8");
331
- return /export\s+(const|let|var)\s+config\b/.test(content) || /export\s*\{[^}]*\bconfig\b[^}]*\}/.test(content);
332
- } catch {
333
- return false;
396
+ function getConfigObjectProperties(path6) {
397
+ if ((0, import_types.isVariableDeclarator)(path6.node)) {
398
+ const decl = (0, import_types.isIdentifier)(path6.node.id, { name: "config" }) ? path6.node : null;
399
+ if (!decl) return null;
400
+ if ((0, import_types.isCallExpression)(decl.init) && decl.init.arguments.length > 0 && (0, import_types.isObjectExpression)(decl.init.arguments[0])) {
401
+ return decl.init.arguments[0].properties;
402
+ }
403
+ if ((0, import_types.isObjectExpression)(decl.init)) {
404
+ return decl.init.properties;
405
+ }
406
+ return null;
407
+ }
408
+ const declaration = path6.node.declaration;
409
+ if ((0, import_types.isVariableDeclaration)(declaration)) {
410
+ const configDecl = declaration.declarations.find(
411
+ (d) => (0, import_types.isVariableDeclarator)(d) && (0, import_types.isIdentifier)(d.id, { name: "config" })
412
+ );
413
+ if (configDecl && (0, import_types.isCallExpression)(configDecl.init) && configDecl.init.arguments.length > 0 && (0, import_types.isObjectExpression)(configDecl.init.arguments[0])) {
414
+ return configDecl.init.arguments[0].properties;
415
+ }
416
+ const directDecl = declaration.declarations.find(
417
+ (d) => (0, import_types.isVariableDeclarator)(d) && (0, import_types.isIdentifier)(d.id, { name: "config" })
418
+ );
419
+ if (directDecl && (0, import_types.isObjectExpression)(directDecl.init)) {
420
+ return directDecl.init.properties;
421
+ }
422
+ }
423
+ return null;
424
+ }
425
+ function processConfigProperties(properties) {
426
+ const hasProperty = (name) => properties.some(
427
+ (prop) => (0, import_types.isObjectProperty)(prop) && (0, import_types.isIdentifier)(prop.key, { name })
428
+ );
429
+ const hasLabel = hasProperty("label");
430
+ if (!hasLabel) {
431
+ return null;
432
+ }
433
+ const hasIcon = hasProperty("icon");
434
+ const nested = properties.find(
435
+ (prop) => (0, import_types.isObjectProperty)(prop) && (0, import_types.isIdentifier)(prop.key, { name: "nested" })
436
+ );
437
+ let nestedValue;
438
+ if (nested && (0, import_types.isObjectProperty)(nested) && (0, import_types.isStringLiteral)(nested.value)) {
439
+ nestedValue = nested.value.value;
440
+ }
441
+ const translationNs = properties.find(
442
+ (prop) => (0, import_types.isObjectProperty)(prop) && (0, import_types.isIdentifier)(prop.key, { name: "translationNs" })
443
+ );
444
+ let translationNsValue;
445
+ if (translationNs && (0, import_types.isObjectProperty)(translationNs) && (0, import_types.isStringLiteral)(translationNs.value)) {
446
+ translationNsValue = translationNs.value.value;
447
+ }
448
+ const rank = properties.find(
449
+ (prop) => (0, import_types.isObjectProperty)(prop) && (0, import_types.isIdentifier)(prop.key, { name: "rank" })
450
+ );
451
+ let rankValue;
452
+ if (rank && (0, import_types.isObjectProperty)(rank) && (0, import_types.isNumericLiteral)(rank.value)) {
453
+ rankValue = rank.value.value;
334
454
  }
455
+ return { label: hasLabel, icon: hasIcon, rank: rankValue, nested: nestedValue, translationNs: translationNsValue };
335
456
  }
336
- function getConfigProperties(filePath) {
457
+ function getRouteConfig(file) {
337
458
  try {
338
- const content = import_fs2.default.readFileSync(filePath, "utf-8");
339
- const hasLabel = /\blabel\s*[:=]/.test(content);
340
- if (!hasLabel) {
341
- return null;
342
- }
343
- const hasIcon = /\bicon\s*[:=]/.test(content);
344
- const rankMatch = content.match(/\brank\s*:\s*(\d+)/);
345
- const rank = rankMatch ? parseInt(rankMatch[1], 10) : void 0;
346
- const nestedMatch = content.match(/\bnested\s*:\s*["']([^"']+)["']/);
347
- const nested = nestedMatch ? nestedMatch[1] : void 0;
348
- const translationNsMatch = content.match(/\btranslationNs\s*:\s*["']([^"']+)["']/);
349
- const translationNs = translationNsMatch ? translationNsMatch[1] : void 0;
350
- return { label: hasLabel, icon: hasIcon, rank, nested, translationNs };
459
+ const code = import_fs2.default.readFileSync(file, "utf-8");
460
+ const ast = (0, import_parser.parse)(code, getParserOptions(file));
461
+ let config = null;
462
+ let configFound = false;
463
+ traverse(ast, {
464
+ VariableDeclarator(path6) {
465
+ if (configFound) return;
466
+ const properties = getConfigObjectProperties(path6);
467
+ if (!properties) return;
468
+ config = processConfigProperties(properties);
469
+ if (config) configFound = true;
470
+ },
471
+ ExportNamedDeclaration(path6) {
472
+ if (configFound) return;
473
+ const properties = getConfigObjectProperties(path6);
474
+ if (!properties) return;
475
+ config = processConfigProperties(properties);
476
+ if (config) configFound = true;
477
+ }
478
+ });
479
+ return config;
351
480
  } catch {
352
481
  return null;
353
482
  }
@@ -384,10 +513,7 @@ ${parts.join(",\n")}
384
513
  }`;
385
514
  }
386
515
  function parseFile2(file, pagesDir, index) {
387
- if (!hasConfigExport(file)) {
388
- return null;
389
- }
390
- const config = getConfigProperties(file);
516
+ const config = getRouteConfig(file);
391
517
  if (!config) {
392
518
  return null;
393
519
  }
@@ -407,24 +533,23 @@ function generateMenuItems({ srcDir, pluginExtensions }) {
407
533
  index++;
408
534
  }
409
535
  }
410
- const pluginImports = pluginExtensions.map(
411
- (ext, i) => `import * as __pluginRaw${i} from "${normalizePath(ext)}"`
412
- );
413
- const pluginUnwraps = pluginExtensions.map(
414
- (_, i) => `const __plugin${i} = __pluginRaw${i}.default ?? __pluginRaw${i}`
536
+ const pluginDeclarations = pluginExtensions.map(
537
+ (ext, i) => `const __plugin${i} = (await import("${normalizePath(ext)}")).default`
415
538
  );
416
539
  const pluginSpreads = pluginExtensions.map(
417
540
  (_, i) => ` ...(__plugin${i}.menuItemModule?.menuItems ?? [])`
418
541
  );
419
542
  const appImports = results.map((r) => r.import);
420
543
  const appMenuItems = results.map((r) => formatMenuItem(r.menuItem));
421
- const allImports = [...appImports, ...pluginImports, ...pluginUnwraps];
544
+ const allImports = [...appImports];
422
545
  const allMenuItems = [...appMenuItems, ...pluginSpreads];
423
- if (allImports.length === 0 && allMenuItems.length === 0) {
546
+ if (allImports.length === 0 && pluginDeclarations.length === 0 && allMenuItems.length === 0) {
424
547
  return `export default { menuItems: [] }`;
425
548
  }
426
549
  return `${allImports.join("\n")}
427
550
 
551
+ ${pluginDeclarations.join("\n")}
552
+
428
553
  export default {
429
554
  menuItems: [
430
555
  ${allMenuItems.join(",\n")}
@@ -623,7 +748,6 @@ function mercurDashboardPlugin(pluginConfig) {
623
748
  "__BASE__": JSON.stringify(config.base || "/")
624
749
  },
625
750
  optimizeDeps: {
626
- include: pluginExtensions,
627
751
  exclude: ["virtual:mercur/config", "virtual:mercur/routes", "virtual:mercur/components", "virtual:mercur/menu-items", "virtual:mercur/i18n"]
628
752
  }
629
753
  };
@@ -0,0 +1,37 @@
1
+ import * as Vite from 'vite';
2
+ import { ComponentType } from 'react';
3
+
4
+ interface MercurConfig {
5
+ medusaConfigPath: string;
6
+ backendUrl?: string;
7
+ name?: string;
8
+ logo?: string;
9
+ components?: {
10
+ MainSidebar?: string;
11
+ SettingsSidebar?: string;
12
+ TopbarActions?: string;
13
+ };
14
+ i18n?: {
15
+ defaultLanguage: string;
16
+ };
17
+ enableSellerRegistration?: boolean;
18
+ }
19
+ interface BuiltMercurConfig extends MercurConfig {
20
+ backendUrl: string;
21
+ base?: string;
22
+ root: string;
23
+ srcDir: string;
24
+ pluginExtensions: string[];
25
+ }
26
+ type RouteConfig = {
27
+ label: string;
28
+ icon?: ComponentType;
29
+ rank?: number;
30
+ nested?: string;
31
+ translationNs?: string;
32
+ public?: boolean;
33
+ };
34
+
35
+ declare function mercurDashboardPlugin(pluginConfig: MercurConfig): Vite.Plugin;
36
+
37
+ export { type BuiltMercurConfig, type MercurConfig, type RouteConfig, mercurDashboardPlugin };
package/dist/index.js ADDED
@@ -0,0 +1,775 @@
1
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
2
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
3
+ }) : x)(function(x) {
4
+ if (typeof require !== "undefined") return require.apply(this, arguments);
5
+ throw Error('Dynamic require of "' + x + '" is not supported');
6
+ });
7
+
8
+ // src/plugin.ts
9
+ import path5 from "path";
10
+ import fs4 from "fs";
11
+
12
+ // src/babel.ts
13
+ import { parse } from "@babel/parser";
14
+ import _traverse from "@babel/traverse";
15
+ import {
16
+ isBooleanLiteral,
17
+ isCallExpression,
18
+ isFunctionDeclaration,
19
+ isIdentifier,
20
+ isMemberExpression,
21
+ isNumericLiteral,
22
+ isObjectExpression,
23
+ isObjectProperty,
24
+ isStringLiteral,
25
+ isVariableDeclaration,
26
+ isVariableDeclarator,
27
+ isArrayExpression
28
+ } from "@babel/types";
29
+ var traverse;
30
+ if (typeof _traverse === "function") {
31
+ traverse = _traverse;
32
+ } else {
33
+ traverse = _traverse.default;
34
+ }
35
+
36
+ // src/utils.ts
37
+ function normalizePath(filePath) {
38
+ return filePath.replace(/\\/g, "/");
39
+ }
40
+ function getParserOptions(file) {
41
+ const options = {
42
+ sourceType: "module",
43
+ plugins: ["jsx"]
44
+ };
45
+ if (file.endsWith(".ts") || file.endsWith(".tsx")) {
46
+ options.plugins.push("typescript");
47
+ }
48
+ return options;
49
+ }
50
+ function resolveExports(moduleExports) {
51
+ if ("default" in moduleExports && moduleExports.default && "default" in moduleExports.default) {
52
+ return resolveExports(moduleExports.default);
53
+ }
54
+ return moduleExports;
55
+ }
56
+ async function getFileExports(path6) {
57
+ const { unregister } = await safeRegister();
58
+ const module = __require(path6);
59
+ unregister();
60
+ return resolveExports(module);
61
+ }
62
+ var safeRegister = async () => {
63
+ const { register } = await import("esbuild-register/dist/node");
64
+ let res;
65
+ try {
66
+ res = register({
67
+ format: "cjs",
68
+ loader: "ts"
69
+ });
70
+ } catch {
71
+ res = {
72
+ unregister: () => {
73
+ }
74
+ };
75
+ }
76
+ return res;
77
+ };
78
+ function hasDefaultExport(ast) {
79
+ let found = false;
80
+ traverse(ast, {
81
+ ExportDefaultDeclaration() {
82
+ found = true;
83
+ },
84
+ AssignmentExpression(path6) {
85
+ if (path6.node.left.type === "MemberExpression" && path6.node.left.object.type === "Identifier" && path6.node.left.object.name === "exports" && path6.node.left.property.type === "Identifier" && path6.node.left.property.name === "default") {
86
+ found = true;
87
+ }
88
+ },
89
+ ExportNamedDeclaration(path6) {
90
+ const specifiers = path6.node.specifiers;
91
+ if (specifiers?.some(
92
+ (s) => s.type === "ExportSpecifier" && s.exported.type === "Identifier" && s.exported.name === "default"
93
+ )) {
94
+ found = true;
95
+ }
96
+ }
97
+ });
98
+ return found;
99
+ }
100
+
101
+ // src/constants.ts
102
+ var VALID_FILE_EXTENSIONS = [".tsx", ".ts", ".jsx", ".js"];
103
+ var CONFIG_VIRTUAL_MODULE = "virtual:mercur/config";
104
+ var ROUTES_VIRTUAL_MODULE = "virtual:mercur/routes";
105
+ var COMPONENTS_VIRTUAL_MODULE = "virtual:mercur/components";
106
+ var MENU_ITEMS_VIRTUAL_MODULE = "virtual:mercur/menu-items";
107
+ var I18N_VIRTUAL_MODULE = "virtual:mercur/i18n";
108
+ var RESOLVED_CONFIG_MODULE = "\0" + CONFIG_VIRTUAL_MODULE;
109
+ var RESOLVED_ROUTES_MODULE = "\0" + ROUTES_VIRTUAL_MODULE;
110
+ var RESOLVED_COMPONENTS_MODULE = "\0" + COMPONENTS_VIRTUAL_MODULE;
111
+ var RESOLVED_MENU_ITEMS_MODULE = "\0" + MENU_ITEMS_VIRTUAL_MODULE;
112
+ var RESOLVED_I18N_MODULE = "\0" + I18N_VIRTUAL_MODULE;
113
+ var VIRTUAL_MODULES = [
114
+ CONFIG_VIRTUAL_MODULE,
115
+ ROUTES_VIRTUAL_MODULE,
116
+ COMPONENTS_VIRTUAL_MODULE,
117
+ MENU_ITEMS_VIRTUAL_MODULE,
118
+ I18N_VIRTUAL_MODULE
119
+ ];
120
+
121
+ // src/virtual-modules.ts
122
+ import path4 from "path";
123
+
124
+ // src/routes.ts
125
+ import fs from "fs";
126
+ import path from "path";
127
+ function getRoute(file, pagesDir) {
128
+ const importPath = normalizePath(file);
129
+ const normalizedPagesDir = normalizePath(pagesDir);
130
+ return importPath.replace(normalizedPagesDir, "").replace(/\[\[\*\]\]/g, "*?").replace(/\[\*\]/g, "*").replace(/\(([^\[\]\)]+)\)/g, "$1?").replace(/\[\[([^\]]+)\]\]/g, ":$1?").replace(/\[([^\]]+)\]/g, ":$1").replace(
131
+ new RegExp(
132
+ `/page\\.(${VALID_FILE_EXTENSIONS.map((ext) => ext.slice(1)).join("|")})$`
133
+ ),
134
+ ""
135
+ ) || "/";
136
+ }
137
+ function crawlPages(dir, pattern = "page") {
138
+ const files = [];
139
+ if (!fs.existsSync(dir)) {
140
+ return files;
141
+ }
142
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
143
+ for (const entry of entries) {
144
+ const fullPath = path.join(dir, entry.name);
145
+ if (entry.isDirectory()) {
146
+ files.push(...crawlPages(fullPath, pattern));
147
+ } else if (entry.isFile()) {
148
+ const ext = path.extname(entry.name);
149
+ const baseName = path.basename(entry.name, ext);
150
+ if (baseName === pattern && VALID_FILE_EXTENSIONS.includes(ext)) {
151
+ files.push(fullPath);
152
+ }
153
+ }
154
+ }
155
+ return files;
156
+ }
157
+ function hasConfigPublic(ast) {
158
+ let found = false;
159
+ traverse(ast, {
160
+ ExportNamedDeclaration(path6) {
161
+ const declaration = path6.node.declaration;
162
+ if (!isVariableDeclaration(declaration)) return;
163
+ for (const decl of declaration.declarations) {
164
+ if (isVariableDeclarator(decl) && isIdentifier(decl.id, { name: "config" }) && decl.init?.type === "ObjectExpression") {
165
+ const publicProp = decl.init.properties.find(
166
+ (prop) => isObjectProperty(prop) && isIdentifier(prop.key, { name: "public" }) && isBooleanLiteral(prop.value, { value: true })
167
+ );
168
+ if (publicProp) {
169
+ found = true;
170
+ }
171
+ }
172
+ }
173
+ }
174
+ });
175
+ return found;
176
+ }
177
+ function getNamedExports(ast) {
178
+ let hasHandle = false;
179
+ let hasLoader = false;
180
+ traverse(ast, {
181
+ ExportNamedDeclaration(path6) {
182
+ const declaration = path6.node.declaration;
183
+ if (declaration?.type === "VariableDeclaration") {
184
+ declaration.declarations.forEach((decl) => {
185
+ if (decl.id.type === "Identifier" && decl.id.name === "handle") {
186
+ hasHandle = true;
187
+ }
188
+ if (decl.id.type === "Identifier" && decl.id.name === "loader") {
189
+ hasLoader = true;
190
+ }
191
+ });
192
+ }
193
+ if (declaration?.type === "FunctionDeclaration" && declaration.id?.name === "loader") {
194
+ hasLoader = true;
195
+ }
196
+ if (declaration?.type === "FunctionDeclaration" && declaration.id?.name === "handle") {
197
+ hasHandle = true;
198
+ }
199
+ }
200
+ });
201
+ return { hasHandle, hasLoader };
202
+ }
203
+ function generateRouteComponentName(index) {
204
+ return `RouteComponent${index}`;
205
+ }
206
+ function generateHandleName(index) {
207
+ return `RouteHandle${index}`;
208
+ }
209
+ function generateLoaderName(index) {
210
+ return `RouteLoader${index}`;
211
+ }
212
+ function generateImports(file, index, hasHandle, hasLoader) {
213
+ const imports = [];
214
+ const componentName = generateRouteComponentName(index);
215
+ const importPath = normalizePath(file);
216
+ if (!hasHandle && !hasLoader) {
217
+ imports.push(`import ${componentName} from "${importPath}"`);
218
+ } else {
219
+ const namedImports = [
220
+ hasHandle && `handle as ${generateHandleName(index)}`,
221
+ hasLoader && `loader as ${generateLoaderName(index)}`
222
+ ].filter(Boolean).join(", ");
223
+ imports.push(`import ${componentName}, { ${namedImports} } from "${importPath}"`);
224
+ }
225
+ return imports;
226
+ }
227
+ function generateRouteObject(routePath, index, hasHandle, hasLoader, isPublic) {
228
+ return {
229
+ Component: generateRouteComponentName(index),
230
+ path: routePath,
231
+ handle: hasHandle ? generateHandleName(index) : void 0,
232
+ loader: hasLoader ? generateLoaderName(index) : void 0,
233
+ isPublic
234
+ };
235
+ }
236
+ function formatRoute(route, indent = " ") {
237
+ let result = `${indent}{
238
+ `;
239
+ result += `${indent} Component: ${route.Component},
240
+ `;
241
+ result += `${indent} path: "${route.path}"`;
242
+ if (route.handle) {
243
+ result += `,
244
+ ${indent} handle: ${route.handle}`;
245
+ }
246
+ if (route.loader) {
247
+ result += `,
248
+ ${indent} loader: ${route.loader}`;
249
+ }
250
+ if (route.isPublic) {
251
+ result += `,
252
+ ${indent} isPublic: true`;
253
+ }
254
+ if (route.children?.length) {
255
+ result += `,
256
+ ${indent} children: [
257
+ `;
258
+ result += route.children.map((child) => formatRoute(child, indent + " ")).join(",\n");
259
+ result += `
260
+ ${indent} ]`;
261
+ }
262
+ result += `
263
+ ${indent}}`;
264
+ return result;
265
+ }
266
+ function parseFile(file, pagesDir, index) {
267
+ try {
268
+ const code = fs.readFileSync(file, "utf-8");
269
+ const ast = parse(code, getParserOptions(file));
270
+ if (!hasDefaultExport(ast)) {
271
+ return null;
272
+ }
273
+ const { hasHandle, hasLoader } = getNamedExports(ast);
274
+ const isPublic = hasConfigPublic(ast);
275
+ const routePath = getRoute(file, pagesDir);
276
+ const imports = generateImports(file, index, hasHandle, hasLoader);
277
+ const route = generateRouteObject(routePath, index, hasHandle, hasLoader, isPublic);
278
+ return {
279
+ imports,
280
+ route
281
+ };
282
+ } catch {
283
+ return null;
284
+ }
285
+ }
286
+ function buildRouteTree(results) {
287
+ const routeMap = /* @__PURE__ */ new Map();
288
+ const sortedResults = [...results].sort(
289
+ (a, b) => a.route.path.split("/").length - b.route.path.split("/").length
290
+ );
291
+ for (const result of sortedResults) {
292
+ const routePath = result.route.path;
293
+ const isParallel = routePath.includes("/@");
294
+ if (isParallel) {
295
+ const parentPath = routePath.split("/@")[0];
296
+ const parent = routeMap.get(parentPath);
297
+ if (parent) {
298
+ parent.route.children = parent.route.children ?? [];
299
+ parent.route.children.push({
300
+ ...result.route,
301
+ path: result.route.path.replace("/@", "/")
302
+ });
303
+ parent.imports.push(...result.imports);
304
+ } else {
305
+ routeMap.set(routePath, result);
306
+ }
307
+ } else {
308
+ routeMap.set(routePath, result);
309
+ }
310
+ }
311
+ return Array.from(routeMap.values());
312
+ }
313
+ function generateRoutes({ srcDir, pluginExtensions }) {
314
+ const pagesDir = path.join(srcDir, "pages");
315
+ let index = 0;
316
+ const results = [];
317
+ for (const file of crawlPages(pagesDir)) {
318
+ const result = parseFile(file, pagesDir, index);
319
+ if (result) {
320
+ results.push(result);
321
+ index++;
322
+ }
323
+ }
324
+ const pluginDeclarations = pluginExtensions.map(
325
+ (ext, i) => `const __plugin${i} = (await import("${normalizePath(ext)}")).default`
326
+ );
327
+ const pluginSpreads = pluginExtensions.map(
328
+ (_, i) => ` ...(__plugin${i}.routeModule?.routes ?? [])`
329
+ );
330
+ const routeTree = buildRouteTree(results);
331
+ const appImports = routeTree.flatMap((r) => r.imports);
332
+ const appRoutes = routeTree.map((r) => formatRoute(r.route));
333
+ const allImports = [...appImports];
334
+ const allRoutes = [...appRoutes, ...pluginSpreads];
335
+ if (allImports.length === 0 && pluginDeclarations.length === 0 && allRoutes.length === 0) {
336
+ return `export const customRoutes = []`;
337
+ }
338
+ return `${allImports.join("\n")}
339
+
340
+ ${pluginDeclarations.join("\n")}
341
+
342
+ export const customRoutes = [
343
+ ${allRoutes.join(",\n")}
344
+ ]`;
345
+ }
346
+
347
+ // src/menu-items.ts
348
+ import fs2 from "fs";
349
+ import path2 from "path";
350
+ function crawlPages2(dir, pattern = "page") {
351
+ const files = [];
352
+ if (!fs2.existsSync(dir)) {
353
+ return files;
354
+ }
355
+ const entries = fs2.readdirSync(dir, { withFileTypes: true });
356
+ for (const entry of entries) {
357
+ const fullPath = path2.join(dir, entry.name);
358
+ if (entry.isDirectory()) {
359
+ files.push(...crawlPages2(fullPath, pattern));
360
+ } else if (entry.isFile()) {
361
+ const ext = path2.extname(entry.name);
362
+ const baseName = path2.basename(entry.name, ext);
363
+ if (baseName === pattern && VALID_FILE_EXTENSIONS.includes(ext)) {
364
+ files.push(fullPath);
365
+ }
366
+ }
367
+ }
368
+ return files;
369
+ }
370
+ function getRoute2(file, pagesDir) {
371
+ const importPath = normalizePath(file);
372
+ const normalizedPagesDir = normalizePath(pagesDir);
373
+ return importPath.replace(normalizedPagesDir, "").replace(/\[\[\*\]\]/g, "*?").replace(/\[\*\]/g, "*").replace(/\(([^\[\]\)]+)\)/g, "$1?").replace(/\[\[([^\]]+)\]\]/g, ":$1?").replace(/\[([^\]]+)\]/g, ":$1").replace(
374
+ new RegExp(
375
+ `/page\\.(${VALID_FILE_EXTENSIONS.map((ext) => ext.slice(1)).join("|")})$`
376
+ ),
377
+ ""
378
+ ) || "/";
379
+ }
380
+ function getConfigObjectProperties(path6) {
381
+ if (isVariableDeclarator(path6.node)) {
382
+ const decl = isIdentifier(path6.node.id, { name: "config" }) ? path6.node : null;
383
+ if (!decl) return null;
384
+ if (isCallExpression(decl.init) && decl.init.arguments.length > 0 && isObjectExpression(decl.init.arguments[0])) {
385
+ return decl.init.arguments[0].properties;
386
+ }
387
+ if (isObjectExpression(decl.init)) {
388
+ return decl.init.properties;
389
+ }
390
+ return null;
391
+ }
392
+ const declaration = path6.node.declaration;
393
+ if (isVariableDeclaration(declaration)) {
394
+ const configDecl = declaration.declarations.find(
395
+ (d) => isVariableDeclarator(d) && isIdentifier(d.id, { name: "config" })
396
+ );
397
+ if (configDecl && isCallExpression(configDecl.init) && configDecl.init.arguments.length > 0 && isObjectExpression(configDecl.init.arguments[0])) {
398
+ return configDecl.init.arguments[0].properties;
399
+ }
400
+ const directDecl = declaration.declarations.find(
401
+ (d) => isVariableDeclarator(d) && isIdentifier(d.id, { name: "config" })
402
+ );
403
+ if (directDecl && isObjectExpression(directDecl.init)) {
404
+ return directDecl.init.properties;
405
+ }
406
+ }
407
+ return null;
408
+ }
409
+ function processConfigProperties(properties) {
410
+ const hasProperty = (name) => properties.some(
411
+ (prop) => isObjectProperty(prop) && isIdentifier(prop.key, { name })
412
+ );
413
+ const hasLabel = hasProperty("label");
414
+ if (!hasLabel) {
415
+ return null;
416
+ }
417
+ const hasIcon = hasProperty("icon");
418
+ const nested = properties.find(
419
+ (prop) => isObjectProperty(prop) && isIdentifier(prop.key, { name: "nested" })
420
+ );
421
+ let nestedValue;
422
+ if (nested && isObjectProperty(nested) && isStringLiteral(nested.value)) {
423
+ nestedValue = nested.value.value;
424
+ }
425
+ const translationNs = properties.find(
426
+ (prop) => isObjectProperty(prop) && isIdentifier(prop.key, { name: "translationNs" })
427
+ );
428
+ let translationNsValue;
429
+ if (translationNs && isObjectProperty(translationNs) && isStringLiteral(translationNs.value)) {
430
+ translationNsValue = translationNs.value.value;
431
+ }
432
+ const rank = properties.find(
433
+ (prop) => isObjectProperty(prop) && isIdentifier(prop.key, { name: "rank" })
434
+ );
435
+ let rankValue;
436
+ if (rank && isObjectProperty(rank) && isNumericLiteral(rank.value)) {
437
+ rankValue = rank.value.value;
438
+ }
439
+ return { label: hasLabel, icon: hasIcon, rank: rankValue, nested: nestedValue, translationNs: translationNsValue };
440
+ }
441
+ function getRouteConfig(file) {
442
+ try {
443
+ const code = fs2.readFileSync(file, "utf-8");
444
+ const ast = parse(code, getParserOptions(file));
445
+ let config = null;
446
+ let configFound = false;
447
+ traverse(ast, {
448
+ VariableDeclarator(path6) {
449
+ if (configFound) return;
450
+ const properties = getConfigObjectProperties(path6);
451
+ if (!properties) return;
452
+ config = processConfigProperties(properties);
453
+ if (config) configFound = true;
454
+ },
455
+ ExportNamedDeclaration(path6) {
456
+ if (configFound) return;
457
+ const properties = getConfigObjectProperties(path6);
458
+ if (!properties) return;
459
+ config = processConfigProperties(properties);
460
+ if (config) configFound = true;
461
+ }
462
+ });
463
+ return config;
464
+ } catch {
465
+ return null;
466
+ }
467
+ }
468
+ function generateRouteConfigName(index) {
469
+ return `RouteConfig${index}`;
470
+ }
471
+ function generateImport(file, index) {
472
+ const importPath = normalizePath(file);
473
+ return `import { config as ${generateRouteConfigName(index)} } from "${importPath}"`;
474
+ }
475
+ function generateMenuItem(config, file, pagesDir, index) {
476
+ const configName = generateRouteConfigName(index);
477
+ return {
478
+ label: `${configName}.label`,
479
+ icon: config.icon ? `${configName}.icon` : void 0,
480
+ path: getRoute2(file, pagesDir),
481
+ rank: config.rank,
482
+ nested: config.nested,
483
+ translationNs: config.translationNs ? `${configName}.translationNs` : void 0
484
+ };
485
+ }
486
+ function formatMenuItem(menuItem) {
487
+ const parts = [
488
+ ` label: ${menuItem.label}`,
489
+ ` icon: ${menuItem.icon || "undefined"}`,
490
+ ` path: "${menuItem.path}"`,
491
+ ` rank: ${menuItem.rank !== void 0 ? menuItem.rank : "undefined"}`,
492
+ ` nested: ${menuItem.nested ? `"${menuItem.nested}"` : "undefined"}`,
493
+ ` translationNs: ${menuItem.translationNs || "undefined"}`
494
+ ];
495
+ return ` {
496
+ ${parts.join(",\n")}
497
+ }`;
498
+ }
499
+ function parseFile2(file, pagesDir, index) {
500
+ const config = getRouteConfig(file);
501
+ if (!config) {
502
+ return null;
503
+ }
504
+ return {
505
+ import: generateImport(file, index),
506
+ menuItem: generateMenuItem(config, file, pagesDir, index)
507
+ };
508
+ }
509
+ function generateMenuItems({ srcDir, pluginExtensions }) {
510
+ const pagesDir = path2.join(srcDir, "pages");
511
+ let index = 0;
512
+ const results = [];
513
+ for (const file of crawlPages2(pagesDir)) {
514
+ const result = parseFile2(file, pagesDir, index);
515
+ if (result) {
516
+ results.push(result);
517
+ index++;
518
+ }
519
+ }
520
+ const pluginDeclarations = pluginExtensions.map(
521
+ (ext, i) => `const __plugin${i} = (await import("${normalizePath(ext)}")).default`
522
+ );
523
+ const pluginSpreads = pluginExtensions.map(
524
+ (_, i) => ` ...(__plugin${i}.menuItemModule?.menuItems ?? [])`
525
+ );
526
+ const appImports = results.map((r) => r.import);
527
+ const appMenuItems = results.map((r) => formatMenuItem(r.menuItem));
528
+ const allImports = [...appImports];
529
+ const allMenuItems = [...appMenuItems, ...pluginSpreads];
530
+ if (allImports.length === 0 && pluginDeclarations.length === 0 && allMenuItems.length === 0) {
531
+ return `export default { menuItems: [] }`;
532
+ }
533
+ return `${allImports.join("\n")}
534
+
535
+ ${pluginDeclarations.join("\n")}
536
+
537
+ export default {
538
+ menuItems: [
539
+ ${allMenuItems.join(",\n")}
540
+ ]
541
+ }`;
542
+ }
543
+
544
+ // src/i18n.ts
545
+ import fs3 from "fs";
546
+ import path3 from "path";
547
+ function findI18nIndex(srcDir) {
548
+ const i18nDir = path3.join(srcDir, "i18n");
549
+ if (!fs3.existsSync(i18nDir)) {
550
+ return null;
551
+ }
552
+ for (const ext of VALID_FILE_EXTENSIONS) {
553
+ const filePath = path3.join(i18nDir, `index${ext}`);
554
+ if (fs3.existsSync(filePath)) {
555
+ return filePath;
556
+ }
557
+ }
558
+ return null;
559
+ }
560
+ function generateI18n({ srcDir }) {
561
+ const indexFile = findI18nIndex(srcDir);
562
+ if (!indexFile) {
563
+ return `export default {}`;
564
+ }
565
+ const importPath = normalizePath(indexFile);
566
+ return `import i18nResources from "${importPath}"
567
+ export default i18nResources`;
568
+ }
569
+
570
+ // src/virtual-modules.ts
571
+ function isVirtualModule(id) {
572
+ return VIRTUAL_MODULES.includes(id);
573
+ }
574
+ function resolveVirtualModule(id) {
575
+ return "\0" + id;
576
+ }
577
+ function loadVirtualModule({
578
+ cwd,
579
+ id,
580
+ mercurConfig
581
+ }) {
582
+ if (id === RESOLVED_CONFIG_MODULE) {
583
+ return loadConfigModule(mercurConfig);
584
+ }
585
+ if (id === RESOLVED_COMPONENTS_MODULE) {
586
+ return loadComponentsModule(mercurConfig, cwd);
587
+ }
588
+ if (id === RESOLVED_ROUTES_MODULE) {
589
+ return loadRoutesModule(mercurConfig);
590
+ }
591
+ if (id === RESOLVED_MENU_ITEMS_MODULE) {
592
+ return loadMenuItemsModule(mercurConfig);
593
+ }
594
+ if (id === RESOLVED_I18N_MODULE) {
595
+ return loadI18nModule(mercurConfig);
596
+ }
597
+ return null;
598
+ }
599
+ function loadConfigModule(mercurConfig) {
600
+ const { components, ...configWithoutComponents } = mercurConfig;
601
+ return `export default ${JSON.stringify(configWithoutComponents)}`;
602
+ }
603
+ function loadComponentsModule(mercurConfig, cwd) {
604
+ const components = mercurConfig.components ?? {};
605
+ const imports = [];
606
+ const exports = [];
607
+ Object.entries(components).forEach(([name, componentPath]) => {
608
+ const resolvedPath = path4.resolve(cwd, "src", componentPath);
609
+ imports.push(`import _${name} from "${resolvedPath}"`);
610
+ exports.push(`${name}: _${name}`);
611
+ });
612
+ return `
613
+ ${imports.join("\n")}
614
+
615
+ export default {
616
+ ${exports.join(",\n ")}
617
+ }
618
+ `;
619
+ }
620
+ function loadRoutesModule(mercurConfig) {
621
+ return generateRoutes(mercurConfig);
622
+ }
623
+ function loadMenuItemsModule(mercurConfig) {
624
+ return generateMenuItems(mercurConfig);
625
+ }
626
+ function loadI18nModule(mercurConfig) {
627
+ return generateI18n(mercurConfig);
628
+ }
629
+
630
+ // src/plugin.ts
631
+ function isPageFile(file) {
632
+ const basename = path5.basename(file, path5.extname(file));
633
+ return basename === "page";
634
+ }
635
+ var UI_MODULE_KEYS = [
636
+ "admin_ui",
637
+ "vendor_ui"
638
+ ];
639
+ function findNodeModulesRoot(configDir) {
640
+ let dir = configDir;
641
+ while (dir !== path5.dirname(dir)) {
642
+ const candidate = path5.join(dir, "node_modules");
643
+ if (fs4.existsSync(candidate) && fs4.statSync(candidate).isDirectory()) {
644
+ return candidate;
645
+ }
646
+ dir = path5.dirname(dir);
647
+ }
648
+ return path5.join(configDir, "node_modules");
649
+ }
650
+ function resolvePluginRoot(resolve, configDir, nodeModulesRoot) {
651
+ try {
652
+ if (resolve.startsWith(".")) {
653
+ const resolved = path5.resolve(configDir, resolve);
654
+ if (fs4.existsSync(resolved)) {
655
+ return fs4.realpathSync(resolved);
656
+ }
657
+ return null;
658
+ }
659
+ const packagePath = path5.join(nodeModulesRoot, resolve);
660
+ if (!fs4.existsSync(packagePath)) {
661
+ return null;
662
+ }
663
+ return fs4.realpathSync(packagePath);
664
+ } catch {
665
+ return null;
666
+ }
667
+ }
668
+ function resolvePluginExtensions(plugins, configDir) {
669
+ const nodeModulesRoot = findNodeModulesRoot(configDir);
670
+ const extensions = [];
671
+ const appTypes = ["admin", "vendor"];
672
+ for (const plugin of plugins) {
673
+ const resolve = typeof plugin === "string" ? plugin : plugin?.resolve;
674
+ if (!resolve || typeof resolve !== "string") continue;
675
+ const pluginRoot = resolvePluginRoot(resolve, configDir, nodeModulesRoot);
676
+ if (!pluginRoot) continue;
677
+ for (const appType of appTypes) {
678
+ const extFile = path5.join(pluginRoot, ".medusa/server/src", appType, "index.js");
679
+ if (fs4.existsSync(extFile)) {
680
+ extensions.push(extFile);
681
+ }
682
+ }
683
+ }
684
+ return extensions;
685
+ }
686
+ async function loadMedusaConfig(medusaConfigPath, root) {
687
+ try {
688
+ const mod = await getFileExports(medusaConfigPath);
689
+ const medusaConfig = mod.default ?? mod;
690
+ const modules = medusaConfig?.modules ?? {};
691
+ const configDir = path5.dirname(medusaConfigPath);
692
+ let base;
693
+ for (const key of UI_MODULE_KEYS) {
694
+ const value = modules[key];
695
+ if (!value || typeof value !== "object" || !value.options?.appDir) continue;
696
+ const appDir = path5.resolve(configDir, value.options.appDir);
697
+ if (appDir === root) {
698
+ base = value.options.path;
699
+ break;
700
+ }
701
+ }
702
+ const plugins = medusaConfig?.plugins ?? [];
703
+ const pluginExtensions = resolvePluginExtensions(plugins, configDir);
704
+ return { base, pluginExtensions };
705
+ } catch {
706
+ return { pluginExtensions: [] };
707
+ }
708
+ }
709
+ function mercurDashboardPlugin(pluginConfig) {
710
+ let root;
711
+ let config;
712
+ return {
713
+ name: "@mercurjs/dashboard-sdk",
714
+ async config(viteConfig) {
715
+ root = viteConfig.root || process.cwd();
716
+ const medusaConfigPath = path5.resolve(root, pluginConfig.medusaConfigPath);
717
+ const { base, pluginExtensions } = await loadMedusaConfig(medusaConfigPath, root);
718
+ const srcDir = path5.join(root, "src");
719
+ const backendUrl = pluginConfig.backendUrl ?? "http://localhost:9000";
720
+ config = {
721
+ ...pluginConfig,
722
+ backendUrl,
723
+ base,
724
+ root,
725
+ srcDir,
726
+ pluginExtensions
727
+ };
728
+ return {
729
+ base: config.base,
730
+ define: {
731
+ "__BACKEND_URL__": JSON.stringify(config.backendUrl),
732
+ "__BASE__": JSON.stringify(config.base || "/")
733
+ },
734
+ optimizeDeps: {
735
+ exclude: ["virtual:mercur/config", "virtual:mercur/routes", "virtual:mercur/components", "virtual:mercur/menu-items", "virtual:mercur/i18n"]
736
+ }
737
+ };
738
+ },
739
+ configResolved(resolvedConfig) {
740
+ root = resolvedConfig.root;
741
+ },
742
+ resolveId(id) {
743
+ if (isVirtualModule(id)) {
744
+ return resolveVirtualModule(id);
745
+ }
746
+ return null;
747
+ },
748
+ load(id) {
749
+ return loadVirtualModule({ cwd: root, id, mercurConfig: config });
750
+ },
751
+ configureServer(server) {
752
+ const handlePageChange = (file) => {
753
+ if (!isPageFile(file)) return;
754
+ const mod = server.moduleGraph.getModuleById(RESOLVED_ROUTES_MODULE);
755
+ if (mod) {
756
+ server.moduleGraph.invalidateModule(mod);
757
+ server.ws.send({ type: "full-reload" });
758
+ }
759
+ };
760
+ server.watcher.on("add", handlePageChange);
761
+ server.watcher.on("unlink", handlePageChange);
762
+ },
763
+ handleHotUpdate({ file, server }) {
764
+ if (isPageFile(file)) {
765
+ const mod = server.moduleGraph.getModuleById(RESOLVED_ROUTES_MODULE);
766
+ if (mod) {
767
+ server.moduleGraph.invalidateModule(mod);
768
+ }
769
+ }
770
+ }
771
+ };
772
+ }
773
+ export {
774
+ mercurDashboardPlugin
775
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mercurjs/dashboard-sdk",
3
- "version": "2.0.0-canary.73",
3
+ "version": "2.0.0-canary.75",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/mercurjs/mercur",
@@ -12,8 +12,8 @@
12
12
  "exports": {
13
13
  ".": {
14
14
  "types": "./dist/index.d.ts",
15
- "require": "./dist/index.cjs",
16
- "default": "./dist/index.cjs"
15
+ "import": "./dist/index.js",
16
+ "require": "./dist/index.cjs"
17
17
  }
18
18
  },
19
19
  "files": [
@@ -25,6 +25,9 @@
25
25
  "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0"
26
26
  },
27
27
  "dependencies": {
28
+ "@babel/parser": "7.25.6",
29
+ "@babel/traverse": "7.25.6",
30
+ "@babel/types": "7.25.6",
28
31
  "esbuild-register": "^3.6.0"
29
32
  },
30
33
  "devDependencies": {