@medusajs/admin-vite-plugin 3.0.0-preview-20250211091350 → 3.0.0-preview-20250406180144

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.d.mts CHANGED
@@ -2,6 +2,7 @@ import * as Vite from 'vite';
2
2
 
3
3
  interface MedusaVitePluginOptions {
4
4
  sources?: string[];
5
+ pluginMode?: boolean;
5
6
  }
6
7
  type MedusaVitePlugin = (config?: MedusaVitePluginOptions) => Vite.Plugin;
7
8
 
package/dist/index.d.ts CHANGED
@@ -2,6 +2,7 @@ import * as Vite from 'vite';
2
2
 
3
3
  interface MedusaVitePluginOptions {
4
4
  sources?: string[];
5
+ pluginMode?: boolean;
5
6
  }
6
7
  type MedusaVitePlugin = (config?: MedusaVitePluginOptions) => Vite.Plugin;
7
8
 
package/dist/index.js CHANGED
@@ -35,7 +35,8 @@ __export(src_exports, {
35
35
  module.exports = __toCommonJS(src_exports);
36
36
 
37
37
  // src/plugin.ts
38
- var import_path2 = __toESM(require("path"));
38
+ var import_promises10 = require("fs/promises");
39
+ var import_node_path = __toESM(require("path"));
39
40
 
40
41
  // src/custom-fields/generate-custom-field-displays.ts
41
42
  var import_admin_shared2 = require("@medusajs/admin-shared");
@@ -1354,9 +1355,25 @@ function generateCode4(results) {
1354
1355
  `;
1355
1356
  }
1356
1357
  function formatRoute(route) {
1357
- return `{
1358
+ let base = `{
1358
1359
  Component: ${route.Component},
1359
- path: "${route.path}",
1360
+ path: "${route.path}"`;
1361
+ if (route.handle) {
1362
+ base += `,
1363
+ handle: ${route.handle}`;
1364
+ }
1365
+ if (route.loader) {
1366
+ base += `,
1367
+ loader: ${route.loader}`;
1368
+ }
1369
+ if (route.children?.length) {
1370
+ return `${base},
1371
+ children: [
1372
+ ${route.children.map((child) => formatRoute(child)).join(",\n ")}
1373
+ ]
1374
+ }`;
1375
+ }
1376
+ return `${base}
1360
1377
  }`;
1361
1378
  }
1362
1379
  async function getFilesFromSources7(sources) {
@@ -1371,21 +1388,29 @@ async function getRouteResults(files) {
1371
1388
  const results = (await Promise.all(files.map(parseFile4))).filter(
1372
1389
  (result) => result !== null
1373
1390
  );
1374
- return results;
1391
+ const routeMap = /* @__PURE__ */ new Map();
1392
+ results.forEach((result) => {
1393
+ const routePath = result.route.path;
1394
+ const isParallel = routePath.includes("/@");
1395
+ if (isParallel) {
1396
+ const parentPath = routePath.split("/@")[0];
1397
+ const parent = routeMap.get(parentPath);
1398
+ if (parent) {
1399
+ parent.route.children = parent.route.children || [];
1400
+ const finalRoute = {
1401
+ ...result.route,
1402
+ path: result.route.path.replace("@", "")
1403
+ };
1404
+ parent.route.children.push(finalRoute);
1405
+ parent.imports.push(...result.imports);
1406
+ }
1407
+ } else {
1408
+ routeMap.set(routePath, result);
1409
+ }
1410
+ });
1411
+ return Array.from(routeMap.values());
1375
1412
  }
1376
1413
  async function parseFile4(file, index) {
1377
- if (!await isValidRouteFile(file)) {
1378
- return null;
1379
- }
1380
- const routePath = getRoute(file);
1381
- const imports = generateImports(file, index);
1382
- const route = generateRoute(routePath, index);
1383
- return {
1384
- imports,
1385
- route
1386
- };
1387
- }
1388
- async function isValidRouteFile(file) {
1389
1414
  const code = await import_promises7.default.readFile(file, "utf-8");
1390
1415
  let ast = null;
1391
1416
  try {
@@ -1395,8 +1420,21 @@ async function isValidRouteFile(file) {
1395
1420
  file,
1396
1421
  error: e
1397
1422
  });
1398
- return false;
1423
+ return null;
1424
+ }
1425
+ if (!await isValidRouteFile(ast, file)) {
1426
+ return null;
1399
1427
  }
1428
+ const { hasHandle, hasLoader } = await hasNamedExports(ast, file);
1429
+ const routePath = getRoute(file);
1430
+ const imports = generateImports(file, index, hasHandle, hasLoader);
1431
+ const route = generateRoute(routePath, index, hasHandle, hasLoader);
1432
+ return {
1433
+ imports,
1434
+ route
1435
+ };
1436
+ }
1437
+ async function isValidRouteFile(ast, file) {
1400
1438
  try {
1401
1439
  return await hasDefaultExport(ast);
1402
1440
  } catch (e) {
@@ -1407,39 +1445,133 @@ ${e}`
1407
1445
  return false;
1408
1446
  }
1409
1447
  }
1410
- function generateImports(file, index) {
1448
+ function generateImports(file, index, hasHandle, hasLoader) {
1411
1449
  const imports = [];
1412
1450
  const route = generateRouteComponentName(index);
1413
1451
  const importPath = normalizePath(file);
1414
- imports.push(`import ${route} from "${importPath}"`);
1452
+ if (!hasHandle && !hasLoader) {
1453
+ imports.push(`import ${route} from "${importPath}"`);
1454
+ } else {
1455
+ const namedImports = [
1456
+ hasHandle && `handle as ${generateHandleName(index)}`,
1457
+ hasLoader && `loader as ${generateLoaderName(index)}`
1458
+ ].filter(Boolean).join(", ");
1459
+ imports.push(`import ${route}, { ${namedImports} } from "${importPath}"`);
1460
+ }
1415
1461
  return imports;
1416
1462
  }
1417
- function generateRoute(route, index) {
1463
+ function generateRoute(route, index, hasHandle, hasLoader) {
1418
1464
  return {
1419
1465
  Component: generateRouteComponentName(index),
1420
- path: route
1466
+ path: route,
1467
+ handle: hasHandle ? generateHandleName(index) : void 0,
1468
+ loader: hasLoader ? generateLoaderName(index) : void 0
1421
1469
  };
1422
1470
  }
1423
1471
  function generateRouteComponentName(index) {
1424
1472
  return `RouteComponent${index}`;
1425
1473
  }
1474
+ function generateHandleName(index) {
1475
+ return `handle${index}`;
1476
+ }
1477
+ function generateLoaderName(index) {
1478
+ return `loader${index}`;
1479
+ }
1480
+ async function hasNamedExports(ast, file) {
1481
+ let hasHandle = false;
1482
+ let hasLoader = false;
1483
+ try {
1484
+ traverse(ast, {
1485
+ ExportNamedDeclaration(path3) {
1486
+ const declaration = path3.node.declaration;
1487
+ if (declaration?.type === "VariableDeclaration") {
1488
+ declaration.declarations.forEach((decl) => {
1489
+ if (decl.id.type === "Identifier" && decl.id.name === "handle") {
1490
+ hasHandle = true;
1491
+ }
1492
+ if (decl.id.type === "Identifier" && decl.id.name === "loader") {
1493
+ hasLoader = true;
1494
+ }
1495
+ });
1496
+ }
1497
+ if (declaration?.type === "FunctionDeclaration" && declaration.id?.name === "loader") {
1498
+ hasLoader = true;
1499
+ }
1500
+ }
1501
+ });
1502
+ } catch (e) {
1503
+ logger.error("An error occurred while checking for named exports.", {
1504
+ file,
1505
+ error: e
1506
+ });
1507
+ }
1508
+ return { hasHandle, hasLoader };
1509
+ }
1426
1510
 
1427
1511
  // src/virtual-modules/generate-virtual-display-module.ts
1428
1512
  var import_outdent4 = require("outdent");
1429
- async function generateVirtualDisplayModule(sources) {
1513
+ async function generateVirtualDisplayModule(sources, pluginMode = false) {
1430
1514
  const displays = await generateCustomFieldDisplays(sources);
1431
1515
  const code = import_outdent4.outdent`
1432
1516
  ${displays.imports.join("\n")}
1433
1517
 
1434
- export default {
1435
- ${displays.code}
1436
- }
1518
+ ${pluginMode ? `const displayModule = { ${displays.code} }` : `export default { ${displays.code} }`}
1437
1519
  `;
1438
1520
  return generateModule(code);
1439
1521
  }
1440
1522
 
1441
1523
  // src/virtual-modules/generate-virtual-form-module.ts
1442
- var import_outdent6 = __toESM(require("outdent"));
1524
+ var import_outdent5 = __toESM(require("outdent"));
1525
+ async function generateVirtualFormModule(sources, pluginMode = false) {
1526
+ const customFields = await generateCustomFieldForms(sources);
1527
+ const imports = [...customFields.imports];
1528
+ const code = import_outdent5.default`
1529
+ ${imports.join("\n")}
1530
+
1531
+ ${pluginMode ? `const formModule = { ${customFields.code} }` : `export default { ${customFields.code} }`}
1532
+ `;
1533
+ return generateModule(code);
1534
+ }
1535
+
1536
+ // src/virtual-modules/generate-virtual-link-module.ts
1537
+ var import_outdent6 = require("outdent");
1538
+ async function generateVirtualLinkModule(sources, pluginMode = false) {
1539
+ const links = await generateCustomFieldLinks(sources);
1540
+ const code = import_outdent6.outdent`
1541
+ ${links.imports.join("\n")}
1542
+
1543
+ ${pluginMode ? `const linkModule = { ${links.code} }` : `export default { ${links.code} }`}
1544
+ `;
1545
+ return generateModule(code);
1546
+ }
1547
+
1548
+ // src/virtual-modules/generate-virtual-menu-item-module.ts
1549
+ var import_outdent7 = __toESM(require("outdent"));
1550
+ async function generateVirtualMenuItemModule(sources, pluginMode = false) {
1551
+ const menuItems = await generateMenuItems(sources);
1552
+ const code = import_outdent7.default`
1553
+ ${menuItems.imports.join("\n")}
1554
+
1555
+ ${pluginMode ? `const menuItemModule = { ${menuItems.code} }` : `export default { ${menuItems.code} }`}
1556
+ `;
1557
+ return generateModule(code);
1558
+ }
1559
+
1560
+ // src/virtual-modules/generate-virtual-route-module.ts
1561
+ var import_outdent8 = require("outdent");
1562
+ async function generateVirtualRouteModule(sources, pluginMode = false) {
1563
+ const routes = await generateRoutes(sources);
1564
+ const imports = [...routes.imports];
1565
+ const code = import_outdent8.outdent`
1566
+ ${imports.join("\n")}
1567
+
1568
+ ${pluginMode ? `const routeModule = { ${routes.code} }` : `export default { ${routes.code} }`}
1569
+ `;
1570
+ return generateModule(code);
1571
+ }
1572
+
1573
+ // src/virtual-modules/generate-virtual-widget-module.ts
1574
+ var import_outdent10 = __toESM(require("outdent"));
1443
1575
 
1444
1576
  // src/widgets/generate-widget-hash.ts
1445
1577
  var import_promises8 = __toESM(require("fs/promises"));
@@ -1492,7 +1624,7 @@ async function getWidgetContents(file) {
1492
1624
  // src/widgets/generate-widgets.ts
1493
1625
  var import_admin_shared5 = require("@medusajs/admin-shared");
1494
1626
  var import_promises9 = __toESM(require("fs/promises"));
1495
- var import_outdent5 = __toESM(require("outdent"));
1627
+ var import_outdent9 = __toESM(require("outdent"));
1496
1628
  async function generateWidgets(sources) {
1497
1629
  const files = await getWidgetFilesFromSources(sources);
1498
1630
  const results = await getWidgetResults(files);
@@ -1509,14 +1641,14 @@ async function getWidgetResults(files) {
1509
1641
  );
1510
1642
  }
1511
1643
  function generateCode5(results) {
1512
- return import_outdent5.default`
1644
+ return import_outdent9.default`
1513
1645
  widgets: [
1514
1646
  ${results.map((r) => formatWidget(r.widget)).join(",\n")}
1515
1647
  ]
1516
1648
  `;
1517
1649
  }
1518
1650
  function formatWidget(widget) {
1519
- return import_outdent5.default`
1651
+ return import_outdent9.default`
1520
1652
  {
1521
1653
  Component: ${widget.Component},
1522
1654
  zone: [${widget.zone.map((z) => `"${z}"`).join(", ")}]
@@ -1667,82 +1799,14 @@ function extractZoneValues(value, zones, file) {
1667
1799
  }
1668
1800
  }
1669
1801
 
1670
- // src/virtual-modules/generate-virtual-form-module.ts
1671
- async function generateVirtualFormModule(sources) {
1672
- const menuItems = await generateMenuItems(sources);
1673
- const widgets = await generateWidgets(sources);
1674
- const customFields = await generateCustomFieldForms(sources);
1675
- const imports = [
1676
- ...menuItems.imports,
1677
- ...widgets.imports,
1678
- ...customFields.imports
1679
- ];
1680
- const code = import_outdent6.default`
1681
- ${imports.join("\n")}
1682
-
1683
- export default {
1684
- ${menuItems.code},
1685
- ${widgets.code},
1686
- ${customFields.code},
1687
- }
1688
- `;
1689
- return generateModule(code);
1690
- }
1691
-
1692
- // src/virtual-modules/generate-virtual-link-module.ts
1693
- var import_outdent7 = require("outdent");
1694
- async function generateVirtualLinkModule(sources) {
1695
- const links = await generateCustomFieldLinks(sources);
1696
- const code = import_outdent7.outdent`
1697
- ${links.imports.join("\n")}
1698
-
1699
- export default {
1700
- ${links.code}
1701
- }
1702
- `;
1703
- return generateModule(code);
1704
- }
1705
-
1706
- // src/virtual-modules/generate-virtual-menu-item-module.ts
1707
- var import_outdent8 = __toESM(require("outdent"));
1708
- async function generateVirtualMenuItemModule(sources) {
1709
- const menuItems = await generateMenuItems(sources);
1710
- const code = import_outdent8.default`
1711
- ${menuItems.imports.join("\n")}
1712
-
1713
- export default {
1714
- ${menuItems.code},
1715
- }
1716
- `;
1717
- return generateModule(code);
1718
- }
1719
-
1720
- // src/virtual-modules/generate-virtual-route-module.ts
1721
- var import_outdent9 = require("outdent");
1722
- async function generateVirtualRouteModule(sources) {
1723
- const routes = await generateRoutes(sources);
1724
- const imports = [...routes.imports];
1725
- const code = import_outdent9.outdent`
1726
- ${imports.join("\n")}
1727
-
1728
- export default {
1729
- ${routes.code}
1730
- }
1731
- `;
1732
- return generateModule(code);
1733
- }
1734
-
1735
1802
  // src/virtual-modules/generate-virtual-widget-module.ts
1736
- var import_outdent10 = __toESM(require("outdent"));
1737
- async function generateVirtualWidgetModule(sources) {
1803
+ async function generateVirtualWidgetModule(sources, pluginMode = false) {
1738
1804
  const widgets = await generateWidgets(sources);
1739
1805
  const imports = [...widgets.imports];
1740
1806
  const code = import_outdent10.default`
1741
1807
  ${imports.join("\n")}
1742
1808
 
1743
- export default {
1744
- ${widgets.code},
1745
- }
1809
+ ${pluginMode ? `const widgetModule = { ${widgets.code} }` : `export default { ${widgets.code} }`}
1746
1810
  `;
1747
1811
  return generateModule(code);
1748
1812
  }
@@ -1807,10 +1871,11 @@ var vmod = {
1807
1871
  var medusaVitePlugin = (options) => {
1808
1872
  const hashMap = /* @__PURE__ */ new Map();
1809
1873
  const _sources = new Set(options?.sources ?? []);
1874
+ const mode = options?.pluginMode ? "plugin" /* PLUGIN */ : "application" /* APPLICATION */;
1810
1875
  let watcher;
1811
1876
  function isFileInSources(file) {
1812
1877
  for (const source of _sources) {
1813
- if (file.startsWith(import_path2.default.resolve(source))) {
1878
+ if (file.startsWith(import_node_path.default.resolve(source))) {
1814
1879
  return true;
1815
1880
  }
1816
1881
  }
@@ -1836,9 +1901,64 @@ var medusaVitePlugin = (options) => {
1836
1901
  }
1837
1902
  }
1838
1903
  }
1904
+ async function generatePluginEntryModule(sources) {
1905
+ const widgetModule = await generateVirtualWidgetModule(sources, true);
1906
+ const routeModule = await generateVirtualRouteModule(sources, true);
1907
+ const menuItemModule = await generateVirtualMenuItemModule(sources, true);
1908
+ const formModule = await generateVirtualFormModule(sources, true);
1909
+ const displayModule = await generateVirtualDisplayModule(sources, true);
1910
+ return `
1911
+ // Auto-generated index file for Medusa Admin UI extensions
1912
+ ${widgetModule.code}
1913
+ ${routeModule.code}
1914
+ ${menuItemModule.code}
1915
+ ${formModule.code}
1916
+ ${displayModule.code}
1917
+
1918
+ const plugin = {
1919
+ widgetModule,
1920
+ routeModule,
1921
+ menuItemModule,
1922
+ formModule,
1923
+ displayModule
1924
+ }
1925
+
1926
+ export default plugin
1927
+ `;
1928
+ }
1929
+ const pluginEntryFile = import_node_path.default.resolve(
1930
+ process.cwd(),
1931
+ "src/admin/__admin-extensions__.js"
1932
+ );
1839
1933
  return {
1840
1934
  name: "@medusajs/admin-vite-plugin",
1841
1935
  enforce: "pre",
1936
+ async buildStart() {
1937
+ switch (mode) {
1938
+ case "plugin" /* PLUGIN */: {
1939
+ const code = await generatePluginEntryModule(_sources);
1940
+ await (0, import_promises10.writeFile)(pluginEntryFile, code, "utf-8");
1941
+ break;
1942
+ }
1943
+ case "application" /* APPLICATION */: {
1944
+ break;
1945
+ }
1946
+ }
1947
+ },
1948
+ async buildEnd() {
1949
+ switch (mode) {
1950
+ case "plugin" /* PLUGIN */: {
1951
+ try {
1952
+ await (0, import_promises10.rm)(pluginEntryFile, { force: true });
1953
+ } catch (error) {
1954
+ }
1955
+ break;
1956
+ }
1957
+ case "application" /* APPLICATION */: {
1958
+ break;
1959
+ }
1960
+ }
1961
+ },
1842
1962
  configureServer(server) {
1843
1963
  watcher = server.watcher;
1844
1964
  watcher?.add(Array.from(_sources));
package/dist/index.mjs CHANGED
@@ -1,4 +1,5 @@
1
1
  // src/plugin.ts
2
+ import { rm, writeFile } from "fs/promises";
2
3
  import path2 from "path";
3
4
 
4
5
  // src/custom-fields/generate-custom-field-displays.ts
@@ -1344,9 +1345,25 @@ function generateCode4(results) {
1344
1345
  `;
1345
1346
  }
1346
1347
  function formatRoute(route) {
1347
- return `{
1348
+ let base = `{
1348
1349
  Component: ${route.Component},
1349
- path: "${route.path}",
1350
+ path: "${route.path}"`;
1351
+ if (route.handle) {
1352
+ base += `,
1353
+ handle: ${route.handle}`;
1354
+ }
1355
+ if (route.loader) {
1356
+ base += `,
1357
+ loader: ${route.loader}`;
1358
+ }
1359
+ if (route.children?.length) {
1360
+ return `${base},
1361
+ children: [
1362
+ ${route.children.map((child) => formatRoute(child)).join(",\n ")}
1363
+ ]
1364
+ }`;
1365
+ }
1366
+ return `${base}
1350
1367
  }`;
1351
1368
  }
1352
1369
  async function getFilesFromSources7(sources) {
@@ -1361,21 +1378,29 @@ async function getRouteResults(files) {
1361
1378
  const results = (await Promise.all(files.map(parseFile4))).filter(
1362
1379
  (result) => result !== null
1363
1380
  );
1364
- return results;
1381
+ const routeMap = /* @__PURE__ */ new Map();
1382
+ results.forEach((result) => {
1383
+ const routePath = result.route.path;
1384
+ const isParallel = routePath.includes("/@");
1385
+ if (isParallel) {
1386
+ const parentPath = routePath.split("/@")[0];
1387
+ const parent = routeMap.get(parentPath);
1388
+ if (parent) {
1389
+ parent.route.children = parent.route.children || [];
1390
+ const finalRoute = {
1391
+ ...result.route,
1392
+ path: result.route.path.replace("@", "")
1393
+ };
1394
+ parent.route.children.push(finalRoute);
1395
+ parent.imports.push(...result.imports);
1396
+ }
1397
+ } else {
1398
+ routeMap.set(routePath, result);
1399
+ }
1400
+ });
1401
+ return Array.from(routeMap.values());
1365
1402
  }
1366
1403
  async function parseFile4(file, index) {
1367
- if (!await isValidRouteFile(file)) {
1368
- return null;
1369
- }
1370
- const routePath = getRoute(file);
1371
- const imports = generateImports(file, index);
1372
- const route = generateRoute(routePath, index);
1373
- return {
1374
- imports,
1375
- route
1376
- };
1377
- }
1378
- async function isValidRouteFile(file) {
1379
1404
  const code = await fs7.readFile(file, "utf-8");
1380
1405
  let ast = null;
1381
1406
  try {
@@ -1385,8 +1410,21 @@ async function isValidRouteFile(file) {
1385
1410
  file,
1386
1411
  error: e
1387
1412
  });
1388
- return false;
1413
+ return null;
1389
1414
  }
1415
+ if (!await isValidRouteFile(ast, file)) {
1416
+ return null;
1417
+ }
1418
+ const { hasHandle, hasLoader } = await hasNamedExports(ast, file);
1419
+ const routePath = getRoute(file);
1420
+ const imports = generateImports(file, index, hasHandle, hasLoader);
1421
+ const route = generateRoute(routePath, index, hasHandle, hasLoader);
1422
+ return {
1423
+ imports,
1424
+ route
1425
+ };
1426
+ }
1427
+ async function isValidRouteFile(ast, file) {
1390
1428
  try {
1391
1429
  return await hasDefaultExport(ast);
1392
1430
  } catch (e) {
@@ -1397,39 +1435,133 @@ ${e}`
1397
1435
  return false;
1398
1436
  }
1399
1437
  }
1400
- function generateImports(file, index) {
1438
+ function generateImports(file, index, hasHandle, hasLoader) {
1401
1439
  const imports = [];
1402
1440
  const route = generateRouteComponentName(index);
1403
1441
  const importPath = normalizePath(file);
1404
- imports.push(`import ${route} from "${importPath}"`);
1442
+ if (!hasHandle && !hasLoader) {
1443
+ imports.push(`import ${route} from "${importPath}"`);
1444
+ } else {
1445
+ const namedImports = [
1446
+ hasHandle && `handle as ${generateHandleName(index)}`,
1447
+ hasLoader && `loader as ${generateLoaderName(index)}`
1448
+ ].filter(Boolean).join(", ");
1449
+ imports.push(`import ${route}, { ${namedImports} } from "${importPath}"`);
1450
+ }
1405
1451
  return imports;
1406
1452
  }
1407
- function generateRoute(route, index) {
1453
+ function generateRoute(route, index, hasHandle, hasLoader) {
1408
1454
  return {
1409
1455
  Component: generateRouteComponentName(index),
1410
- path: route
1456
+ path: route,
1457
+ handle: hasHandle ? generateHandleName(index) : void 0,
1458
+ loader: hasLoader ? generateLoaderName(index) : void 0
1411
1459
  };
1412
1460
  }
1413
1461
  function generateRouteComponentName(index) {
1414
1462
  return `RouteComponent${index}`;
1415
1463
  }
1464
+ function generateHandleName(index) {
1465
+ return `handle${index}`;
1466
+ }
1467
+ function generateLoaderName(index) {
1468
+ return `loader${index}`;
1469
+ }
1470
+ async function hasNamedExports(ast, file) {
1471
+ let hasHandle = false;
1472
+ let hasLoader = false;
1473
+ try {
1474
+ traverse(ast, {
1475
+ ExportNamedDeclaration(path3) {
1476
+ const declaration = path3.node.declaration;
1477
+ if (declaration?.type === "VariableDeclaration") {
1478
+ declaration.declarations.forEach((decl) => {
1479
+ if (decl.id.type === "Identifier" && decl.id.name === "handle") {
1480
+ hasHandle = true;
1481
+ }
1482
+ if (decl.id.type === "Identifier" && decl.id.name === "loader") {
1483
+ hasLoader = true;
1484
+ }
1485
+ });
1486
+ }
1487
+ if (declaration?.type === "FunctionDeclaration" && declaration.id?.name === "loader") {
1488
+ hasLoader = true;
1489
+ }
1490
+ }
1491
+ });
1492
+ } catch (e) {
1493
+ logger.error("An error occurred while checking for named exports.", {
1494
+ file,
1495
+ error: e
1496
+ });
1497
+ }
1498
+ return { hasHandle, hasLoader };
1499
+ }
1416
1500
 
1417
1501
  // src/virtual-modules/generate-virtual-display-module.ts
1418
1502
  import { outdent as outdent4 } from "outdent";
1419
- async function generateVirtualDisplayModule(sources) {
1503
+ async function generateVirtualDisplayModule(sources, pluginMode = false) {
1420
1504
  const displays = await generateCustomFieldDisplays(sources);
1421
1505
  const code = outdent4`
1422
1506
  ${displays.imports.join("\n")}
1423
1507
 
1424
- export default {
1425
- ${displays.code}
1426
- }
1508
+ ${pluginMode ? `const displayModule = { ${displays.code} }` : `export default { ${displays.code} }`}
1427
1509
  `;
1428
1510
  return generateModule(code);
1429
1511
  }
1430
1512
 
1431
1513
  // src/virtual-modules/generate-virtual-form-module.ts
1432
- import outdent6 from "outdent";
1514
+ import outdent5 from "outdent";
1515
+ async function generateVirtualFormModule(sources, pluginMode = false) {
1516
+ const customFields = await generateCustomFieldForms(sources);
1517
+ const imports = [...customFields.imports];
1518
+ const code = outdent5`
1519
+ ${imports.join("\n")}
1520
+
1521
+ ${pluginMode ? `const formModule = { ${customFields.code} }` : `export default { ${customFields.code} }`}
1522
+ `;
1523
+ return generateModule(code);
1524
+ }
1525
+
1526
+ // src/virtual-modules/generate-virtual-link-module.ts
1527
+ import { outdent as outdent6 } from "outdent";
1528
+ async function generateVirtualLinkModule(sources, pluginMode = false) {
1529
+ const links = await generateCustomFieldLinks(sources);
1530
+ const code = outdent6`
1531
+ ${links.imports.join("\n")}
1532
+
1533
+ ${pluginMode ? `const linkModule = { ${links.code} }` : `export default { ${links.code} }`}
1534
+ `;
1535
+ return generateModule(code);
1536
+ }
1537
+
1538
+ // src/virtual-modules/generate-virtual-menu-item-module.ts
1539
+ import outdent7 from "outdent";
1540
+ async function generateVirtualMenuItemModule(sources, pluginMode = false) {
1541
+ const menuItems = await generateMenuItems(sources);
1542
+ const code = outdent7`
1543
+ ${menuItems.imports.join("\n")}
1544
+
1545
+ ${pluginMode ? `const menuItemModule = { ${menuItems.code} }` : `export default { ${menuItems.code} }`}
1546
+ `;
1547
+ return generateModule(code);
1548
+ }
1549
+
1550
+ // src/virtual-modules/generate-virtual-route-module.ts
1551
+ import { outdent as outdent8 } from "outdent";
1552
+ async function generateVirtualRouteModule(sources, pluginMode = false) {
1553
+ const routes = await generateRoutes(sources);
1554
+ const imports = [...routes.imports];
1555
+ const code = outdent8`
1556
+ ${imports.join("\n")}
1557
+
1558
+ ${pluginMode ? `const routeModule = { ${routes.code} }` : `export default { ${routes.code} }`}
1559
+ `;
1560
+ return generateModule(code);
1561
+ }
1562
+
1563
+ // src/virtual-modules/generate-virtual-widget-module.ts
1564
+ import outdent10 from "outdent";
1433
1565
 
1434
1566
  // src/widgets/generate-widget-hash.ts
1435
1567
  import fs8 from "fs/promises";
@@ -1482,7 +1614,7 @@ async function getWidgetContents(file) {
1482
1614
  // src/widgets/generate-widgets.ts
1483
1615
  import { isValidInjectionZone } from "@medusajs/admin-shared";
1484
1616
  import fs9 from "fs/promises";
1485
- import outdent5 from "outdent";
1617
+ import outdent9 from "outdent";
1486
1618
  async function generateWidgets(sources) {
1487
1619
  const files = await getWidgetFilesFromSources(sources);
1488
1620
  const results = await getWidgetResults(files);
@@ -1499,14 +1631,14 @@ async function getWidgetResults(files) {
1499
1631
  );
1500
1632
  }
1501
1633
  function generateCode5(results) {
1502
- return outdent5`
1634
+ return outdent9`
1503
1635
  widgets: [
1504
1636
  ${results.map((r) => formatWidget(r.widget)).join(",\n")}
1505
1637
  ]
1506
1638
  `;
1507
1639
  }
1508
1640
  function formatWidget(widget) {
1509
- return outdent5`
1641
+ return outdent9`
1510
1642
  {
1511
1643
  Component: ${widget.Component},
1512
1644
  zone: [${widget.zone.map((z) => `"${z}"`).join(", ")}]
@@ -1657,82 +1789,14 @@ function extractZoneValues(value, zones, file) {
1657
1789
  }
1658
1790
  }
1659
1791
 
1660
- // src/virtual-modules/generate-virtual-form-module.ts
1661
- async function generateVirtualFormModule(sources) {
1662
- const menuItems = await generateMenuItems(sources);
1663
- const widgets = await generateWidgets(sources);
1664
- const customFields = await generateCustomFieldForms(sources);
1665
- const imports = [
1666
- ...menuItems.imports,
1667
- ...widgets.imports,
1668
- ...customFields.imports
1669
- ];
1670
- const code = outdent6`
1671
- ${imports.join("\n")}
1672
-
1673
- export default {
1674
- ${menuItems.code},
1675
- ${widgets.code},
1676
- ${customFields.code},
1677
- }
1678
- `;
1679
- return generateModule(code);
1680
- }
1681
-
1682
- // src/virtual-modules/generate-virtual-link-module.ts
1683
- import { outdent as outdent7 } from "outdent";
1684
- async function generateVirtualLinkModule(sources) {
1685
- const links = await generateCustomFieldLinks(sources);
1686
- const code = outdent7`
1687
- ${links.imports.join("\n")}
1688
-
1689
- export default {
1690
- ${links.code}
1691
- }
1692
- `;
1693
- return generateModule(code);
1694
- }
1695
-
1696
- // src/virtual-modules/generate-virtual-menu-item-module.ts
1697
- import outdent8 from "outdent";
1698
- async function generateVirtualMenuItemModule(sources) {
1699
- const menuItems = await generateMenuItems(sources);
1700
- const code = outdent8`
1701
- ${menuItems.imports.join("\n")}
1702
-
1703
- export default {
1704
- ${menuItems.code},
1705
- }
1706
- `;
1707
- return generateModule(code);
1708
- }
1709
-
1710
- // src/virtual-modules/generate-virtual-route-module.ts
1711
- import { outdent as outdent9 } from "outdent";
1712
- async function generateVirtualRouteModule(sources) {
1713
- const routes = await generateRoutes(sources);
1714
- const imports = [...routes.imports];
1715
- const code = outdent9`
1716
- ${imports.join("\n")}
1717
-
1718
- export default {
1719
- ${routes.code}
1720
- }
1721
- `;
1722
- return generateModule(code);
1723
- }
1724
-
1725
1792
  // src/virtual-modules/generate-virtual-widget-module.ts
1726
- import outdent10 from "outdent";
1727
- async function generateVirtualWidgetModule(sources) {
1793
+ async function generateVirtualWidgetModule(sources, pluginMode = false) {
1728
1794
  const widgets = await generateWidgets(sources);
1729
1795
  const imports = [...widgets.imports];
1730
1796
  const code = outdent10`
1731
1797
  ${imports.join("\n")}
1732
1798
 
1733
- export default {
1734
- ${widgets.code},
1735
- }
1799
+ ${pluginMode ? `const widgetModule = { ${widgets.code} }` : `export default { ${widgets.code} }`}
1736
1800
  `;
1737
1801
  return generateModule(code);
1738
1802
  }
@@ -1804,6 +1868,7 @@ var vmod = {
1804
1868
  var medusaVitePlugin = (options) => {
1805
1869
  const hashMap = /* @__PURE__ */ new Map();
1806
1870
  const _sources = new Set(options?.sources ?? []);
1871
+ const mode = options?.pluginMode ? "plugin" /* PLUGIN */ : "application" /* APPLICATION */;
1807
1872
  let watcher;
1808
1873
  function isFileInSources(file) {
1809
1874
  for (const source of _sources) {
@@ -1833,9 +1898,64 @@ var medusaVitePlugin = (options) => {
1833
1898
  }
1834
1899
  }
1835
1900
  }
1901
+ async function generatePluginEntryModule(sources) {
1902
+ const widgetModule = await generateVirtualWidgetModule(sources, true);
1903
+ const routeModule = await generateVirtualRouteModule(sources, true);
1904
+ const menuItemModule = await generateVirtualMenuItemModule(sources, true);
1905
+ const formModule = await generateVirtualFormModule(sources, true);
1906
+ const displayModule = await generateVirtualDisplayModule(sources, true);
1907
+ return `
1908
+ // Auto-generated index file for Medusa Admin UI extensions
1909
+ ${widgetModule.code}
1910
+ ${routeModule.code}
1911
+ ${menuItemModule.code}
1912
+ ${formModule.code}
1913
+ ${displayModule.code}
1914
+
1915
+ const plugin = {
1916
+ widgetModule,
1917
+ routeModule,
1918
+ menuItemModule,
1919
+ formModule,
1920
+ displayModule
1921
+ }
1922
+
1923
+ export default plugin
1924
+ `;
1925
+ }
1926
+ const pluginEntryFile = path2.resolve(
1927
+ process.cwd(),
1928
+ "src/admin/__admin-extensions__.js"
1929
+ );
1836
1930
  return {
1837
1931
  name: "@medusajs/admin-vite-plugin",
1838
1932
  enforce: "pre",
1933
+ async buildStart() {
1934
+ switch (mode) {
1935
+ case "plugin" /* PLUGIN */: {
1936
+ const code = await generatePluginEntryModule(_sources);
1937
+ await writeFile(pluginEntryFile, code, "utf-8");
1938
+ break;
1939
+ }
1940
+ case "application" /* APPLICATION */: {
1941
+ break;
1942
+ }
1943
+ }
1944
+ },
1945
+ async buildEnd() {
1946
+ switch (mode) {
1947
+ case "plugin" /* PLUGIN */: {
1948
+ try {
1949
+ await rm(pluginEntryFile, { force: true });
1950
+ } catch (error) {
1951
+ }
1952
+ break;
1953
+ }
1954
+ case "application" /* APPLICATION */: {
1955
+ break;
1956
+ }
1957
+ }
1958
+ },
1839
1959
  configureServer(server) {
1840
1960
  watcher = server.watcher;
1841
1961
  watcher?.add(Array.from(_sources));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@medusajs/admin-vite-plugin",
3
- "version": "3.0.0-preview-20250211091350",
3
+ "version": "3.0.0-preview-20250406180144",
4
4
  "main": "dist/index.js",
5
5
  "module": "dist/index.mjs",
6
6
  "types": "dist/index.d.ts",
@@ -30,8 +30,8 @@
30
30
  "@types/node": "^20.10.4",
31
31
  "tsup": "8.0.1",
32
32
  "typescript": "5.3.3",
33
- "vite": "^5.2.11",
34
- "vitest": "^2.1.9"
33
+ "vite": "^5.4.14",
34
+ "vitest": "^3.0.5"
35
35
  },
36
36
  "peerDependencies": {
37
37
  "vite": "^5.0.0"
@@ -40,7 +40,7 @@
40
40
  "@babel/parser": "7.25.6",
41
41
  "@babel/traverse": "7.25.6",
42
42
  "@babel/types": "7.25.6",
43
- "@medusajs/admin-shared": "3.0.0-preview-20250211091350",
43
+ "@medusajs/admin-shared": "3.0.0-preview-20250406180144",
44
44
  "chokidar": "3.5.3",
45
45
  "fdir": "6.1.1",
46
46
  "magic-string": "0.30.5",