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