@marko/run 0.8.1 → 0.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -63,7 +63,6 @@ var httpVerbs = [
63
63
  "patch",
64
64
  "options"
65
65
  ];
66
- var serverEntryQuery = "?marko-server-entry";
67
66
  var RoutableFileTypes = {
68
67
  Page: "page",
69
68
  Layout: "layout",
@@ -99,6 +98,11 @@ function getVerbs(route, noAutoHead) {
99
98
  }
100
99
  return [...verbs].sort((a, b) => httpVerbOrder[a] - httpVerbOrder[b]);
101
100
  }
101
+ function getUniqueSortedVerbs(verbs) {
102
+ return [...new Set(verbs)].sort(
103
+ (a, b) => httpVerbOrder[a] - httpVerbOrder[b]
104
+ );
105
+ }
102
106
  function hasVerb(route, verb) {
103
107
  var _a, _b;
104
108
  return verb === "get" && !!route.page || ((_b = (_a = route.handler) == null ? void 0 : _a.verbs) == null ? void 0 : _b.includes(verb)) || verb === "head" && hasVerb(route, "get");
@@ -350,7 +354,7 @@ function renderRouteEntry(route, rootDir) {
350
354
  }
351
355
  if (page) {
352
356
  imports.writeLines(
353
- `import page from "${normalizedRelativePath(rootDir, route.templateFilePath || page.filePath)}${serverEntryQuery}";`
357
+ `import page from "${normalizedRelativePath(rootDir, route.templateFilePath || page.filePath)}";`
354
358
  );
355
359
  }
356
360
  if (meta) {
@@ -483,7 +487,7 @@ function renderRouter(routes, rootDir, runtimeInclude, options = {
483
487
  }
484
488
  for (const route of Object.values(routes.special)) {
485
489
  imports.writeLines(
486
- `import page${route.key} from "${normalizedRelativePath(rootDir, route.templateFilePath || route.page.filePath)}${serverEntryQuery}";`
490
+ `import page${route.key} from "${normalizedRelativePath(rootDir, route.templateFilePath || route.page.filePath)}";`
487
491
  );
488
492
  }
489
493
  writer.writeLines(
@@ -1327,7 +1331,7 @@ async function buildRoutes(sources, outDir) {
1327
1331
  const uniqueRoutes = /* @__PURE__ */ new Map();
1328
1332
  const routes = [];
1329
1333
  const special = {};
1330
- const seenKeys = /* @__PURE__ */ new Map();
1334
+ const seenKeys = /* @__PURE__ */ new Set();
1331
1335
  const middlewares = /* @__PURE__ */ new Set();
1332
1336
  const unusedFiles = /* @__PURE__ */ new Set();
1333
1337
  const currentLayouts = /* @__PURE__ */ new Set();
@@ -1458,12 +1462,13 @@ async function buildRoutes(sources, outDir) {
1458
1462
  );
1459
1463
  }
1460
1464
  uniqueRoutes.set(pathInfo.id, { dir, index: routes.length });
1461
- let key = pathInfo.segments.map(replaceInvalidFilenameChars).concat("route").join("/");
1462
- const keyCount = (seenKeys.get(key) || 0) + 1;
1463
- seenKeys.set(key, keyCount);
1464
- if (keyCount > 1) {
1465
- key += keyCount;
1465
+ const keyBase = pathInfo.segments.map(replaceInvalidFilenameChars).join(".") || "index";
1466
+ let count = 2;
1467
+ let key = keyBase;
1468
+ while (seenKeys.has(key)) {
1469
+ key = keyBase + count++;
1466
1470
  }
1471
+ seenKeys.add(key);
1467
1472
  routes.push({
1468
1473
  index: nextRouteIndex++,
1469
1474
  key,
@@ -1499,7 +1504,7 @@ async function buildRoutes(sources, outDir) {
1499
1504
  }
1500
1505
  }
1501
1506
  function replaceInvalidFilenameChars(str) {
1502
- return str.replace(/[<>:"/\\|?*]+/g, "_");
1507
+ return str.replace(/[<>:"/\\|?*_]+/g, "-");
1503
1508
  }
1504
1509
 
1505
1510
  // src/vite/routes/walk.ts
@@ -1614,7 +1619,7 @@ var HttpVerbColors = {
1614
1619
  function verbColor(verb) {
1615
1620
  return verb in HttpVerbColors ? HttpVerbColors[verb] : kleur2.gray;
1616
1621
  }
1617
- function logRoutesTable(routes, bundle) {
1622
+ function logRoutesTable(routes, externalRoutes, bundle) {
1618
1623
  const hasMiddleware = routes.list.some((route) => route.middleware.length);
1619
1624
  const hasMeta = routes.list.some((route) => route.meta);
1620
1625
  const headings = ["Method", "Path", "Entry"];
@@ -1648,7 +1653,11 @@ function logRoutesTable(routes, bundle) {
1648
1653
  if (route.page && (verb === "get" || verb === "head")) {
1649
1654
  entryType.push(kleur2.yellow("page"));
1650
1655
  if (verb === "get") {
1651
- size = prettySize(computeRouteSize(route, bundle));
1656
+ const routeSize = computeRouteSize(
1657
+ route.templateFilePath,
1658
+ bundle
1659
+ ) || [0, 0];
1660
+ size = prettySize(routeSize);
1652
1661
  }
1653
1662
  }
1654
1663
  const row = [verbCell];
@@ -1670,9 +1679,40 @@ function logRoutesTable(routes, bundle) {
1670
1679
  const row = [kleur2.bold(kleur2.white("*")), key, kleur2.yellow("page")];
1671
1680
  hasMiddleware && row.push("");
1672
1681
  hasMeta && row.push("");
1673
- row.push(prettySize(computeRouteSize(route, bundle)));
1682
+ const routeSize = computeRouteSize(route.templateFilePath, bundle) || [
1683
+ 0,
1684
+ 0
1685
+ ];
1686
+ row.push(prettySize(routeSize));
1674
1687
  table.push(row);
1675
1688
  }
1689
+ for (const external of externalRoutes) {
1690
+ for (const route of external.routes) {
1691
+ const verbs = getUniqueSortedVerbs(route.verbs);
1692
+ let firstRow = true;
1693
+ for (const verb of verbs) {
1694
+ let size = "";
1695
+ const verbCell = verbColor(verb)(verb.toUpperCase());
1696
+ const row = [verbCell];
1697
+ if (verbs.length === 1 || firstRow) {
1698
+ const routeSize = computeRouteSize(route.entryFile, bundle);
1699
+ if (routeSize) {
1700
+ size = prettySize(routeSize);
1701
+ }
1702
+ row.push({
1703
+ rowSpan: verbs.length,
1704
+ content: prettyPath(route.path)
1705
+ });
1706
+ firstRow = false;
1707
+ }
1708
+ row.push(kleur2.magenta(external.name));
1709
+ hasMiddleware && row.push("");
1710
+ hasMeta && row.push("");
1711
+ row.push(size || "");
1712
+ table.push(row);
1713
+ }
1714
+ }
1715
+ }
1676
1716
  if (!table.length) {
1677
1717
  table.push([
1678
1718
  {
@@ -1684,16 +1724,14 @@ function logRoutesTable(routes, bundle) {
1684
1724
  }
1685
1725
  console.log(table.toString());
1686
1726
  }
1687
- function computeRouteSize(route, bundle) {
1688
- const facadeModuleId = route.templateFilePath && `${route.templateFilePath}.html`;
1689
- if (facadeModuleId) {
1727
+ function computeRouteSize(filePath, bundle) {
1728
+ if (filePath) {
1690
1729
  for (const chunk of Object.values(bundle)) {
1691
- if (chunk.type === "chunk" && chunk.isEntry && chunk.facadeModuleId === facadeModuleId) {
1730
+ if (chunk.type === "chunk" && chunk.isEntry && chunk.facadeModuleId === `${filePath}.html`) {
1692
1731
  return computeChunkSize(chunk, bundle);
1693
1732
  }
1694
1733
  }
1695
1734
  }
1696
- return [0, 0];
1697
1735
  }
1698
1736
  function gzipSize(source) {
1699
1737
  return zlib.gzipSync(source, { level: 9 }).length;
@@ -1811,9 +1849,12 @@ function markoRun(opts = {}) {
1811
1849
  let devEntryFilePosix;
1812
1850
  let devServer;
1813
1851
  let routes;
1852
+ let entryTemplates;
1853
+ let entryTemplateImporters;
1814
1854
  let routeData;
1815
1855
  let resolvedConfig;
1816
1856
  let typesFile;
1857
+ const externalRoutes = /* @__PURE__ */ new Set();
1817
1858
  const seenErrors = /* @__PURE__ */ new Set();
1818
1859
  const virtualFiles = /* @__PURE__ */ new Map();
1819
1860
  let times = {
@@ -1847,6 +1888,7 @@ function markoRun(opts = {}) {
1847
1888
  let buildVirtualFilesResult;
1848
1889
  function buildVirtualFiles() {
1849
1890
  return buildVirtualFilesResult ?? (buildVirtualFilesResult = (async () => {
1891
+ var _a, _b;
1850
1892
  virtualFiles.clear();
1851
1893
  if (fs3.existsSync(resolvedRoutesDir)) {
1852
1894
  routes = await buildRoutes(
@@ -1868,16 +1910,43 @@ function markoRun(opts = {}) {
1868
1910
  console.warn(`Routes directory ${resolvedRoutesDir} does not exist`);
1869
1911
  }
1870
1912
  }
1913
+ entryTemplates = /* @__PURE__ */ new Set();
1914
+ entryTemplateImporters = /* @__PURE__ */ new Set();
1871
1915
  for (const route of routes.list) {
1916
+ const routeEntryPath = route.templateFilePath || ((_a = route.page) == null ? void 0 : _a.filePath);
1917
+ if (routeEntryPath) {
1918
+ entryTemplates.add(normalizePath(routeEntryPath));
1919
+ }
1920
+ for (const middleware of route.middleware) {
1921
+ entryTemplateImporters.add(normalizePath(middleware.filePath));
1922
+ }
1923
+ if (route.handler) {
1924
+ entryTemplateImporters.add(normalizePath(route.handler.filePath));
1925
+ }
1872
1926
  virtualFiles.set(
1873
1927
  path6.posix.join(root, getRouteVirtualFileName(route)),
1874
1928
  ""
1875
1929
  );
1876
1930
  }
1931
+ for (const route of Object.values(routes.special)) {
1932
+ const routeEntryPath = route.templateFilePath || ((_b = route.page) == null ? void 0 : _b.filePath);
1933
+ if (routeEntryPath) {
1934
+ entryTemplates.add(normalizePath(routeEntryPath));
1935
+ }
1936
+ }
1877
1937
  if (routes.middleware.length) {
1878
1938
  virtualFiles.set(path6.posix.join(root, MIDDLEWARE_FILENAME), "");
1879
1939
  }
1880
1940
  virtualFiles.set(path6.posix.join(root, ROUTER_FILENAME), "");
1941
+ for (const externalRoute of externalRoutes) {
1942
+ for (const { entryFile } of externalRoute.routes) {
1943
+ if (/\.marko(\?.*)?$/i.test(entryFile)) {
1944
+ entryTemplates.add(normalizePath(entryFile));
1945
+ } else {
1946
+ entryTemplateImporters.add(normalizePath(entryFile));
1947
+ }
1948
+ }
1949
+ }
1881
1950
  return routes;
1882
1951
  })());
1883
1952
  }
@@ -1984,6 +2053,14 @@ function markoRun(opts = {}) {
1984
2053
  {
1985
2054
  name: `${PLUGIN_NAME_PREFIX}:pre`,
1986
2055
  enforce: "pre",
2056
+ api: {
2057
+ addExternalRoutes(routes2) {
2058
+ externalRoutes.add(routes2);
2059
+ return () => {
2060
+ externalRoutes.delete(routes2);
2061
+ };
2062
+ }
2063
+ },
1987
2064
  async config(config2, env) {
1988
2065
  var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B;
1989
2066
  const externalPluginOptions = getExternalPluginOptions(config2);
@@ -2016,6 +2093,10 @@ function markoRun(opts = {}) {
2016
2093
  );
2017
2094
  markoVitePluginOptions.runtimeId = opts.runtimeId;
2018
2095
  markoVitePluginOptions.basePathVar = opts.basePathVar;
2096
+ markoVitePluginOptions.isEntry = (importee, importer) => {
2097
+ var _a2;
2098
+ return entryTemplates.has(importee) || entryTemplateImporters.has(importer) || ((_a2 = adapter == null ? void 0 : adapter.isEntryTemplate) == null ? void 0 : _a2.call(adapter, { template: importee, importer })) || false;
2099
+ };
2019
2100
  resolvedRoutesDir = path6.resolve(root, routesDir);
2020
2101
  outputDir = path6.join(root, ((_d = config2.build) == null ? void 0 : _d.outDir) || "dist");
2021
2102
  entryFilesDir = path6.join(outputDir, ".marko-run");
@@ -2034,23 +2115,9 @@ function markoRun(opts = {}) {
2034
2115
  outDir = path6.join(outDir, CLIENT_OUT_DIR);
2035
2116
  }
2036
2117
  const defaultRollupOutputOptions = {
2037
- assetFileNames({ name }) {
2038
- if (name && name.indexOf("_marko-virtual_id_") < 0) {
2039
- return `${assetsDir}/${getEntryFileName(name) || "[name]"}-[hash].[ext]`;
2040
- }
2041
- return `${assetsDir}/_[hash].[ext]`;
2042
- },
2118
+ assetFileNames: `${assetsDir}/[name]-[hash].[ext]`,
2043
2119
  entryFileNames(info) {
2044
- let name = getEntryFileName(info.facadeModuleId);
2045
- if (!name) {
2046
- for (const id of info.moduleIds) {
2047
- name = getEntryFileName(id);
2048
- if (name) {
2049
- break;
2050
- }
2051
- }
2052
- }
2053
- return `${assetsDir}/${name || "[name]"}-[hash].js`;
2120
+ return `${assetsDir}/${getEntryFileName(info.name) || "[name]"}-[hash].js`;
2054
2121
  },
2055
2122
  chunkFileNames: isSSRBuild ? `_[hash].js` : `${assetsDir}/_[hash].js`
2056
2123
  };
@@ -2204,16 +2271,14 @@ function markoRun(opts = {}) {
2204
2271
  }
2205
2272
  },
2206
2273
  async resolveId(importee, importer) {
2274
+ let virtualFilePath;
2207
2275
  if (importee === "@marko/run/router") {
2208
2276
  return normalizePath(path6.resolve(root, ROUTER_FILENAME));
2209
2277
  } else if (importee.endsWith(".marko") && importee.includes(relativeEntryFilesDirPosix)) {
2210
2278
  if (!importee.startsWith(root)) {
2211
2279
  importee = path6.resolve(root, "." + importee);
2212
2280
  }
2213
- return normalizePath(importee);
2214
- }
2215
- let virtualFilePath;
2216
- if (importee.startsWith(virtualFilePrefix)) {
2281
+ } else if (importee.startsWith(virtualFilePrefix)) {
2217
2282
  virtualFilePath = importee.slice(virtualFilePrefix.length + 1);
2218
2283
  importee = path6.resolve(root, virtualFilePath);
2219
2284
  } else if (!isBuild && importer && (importer === devEntryFile || normalizePath(importer) === devEntryFilePosix) && importee.startsWith(`/${markoRunFilePrefix}`)) {
@@ -2233,9 +2298,6 @@ function markoRun(opts = {}) {
2233
2298
  }
2234
2299
  },
2235
2300
  async load(id) {
2236
- if (id.endsWith(serverEntryQuery)) {
2237
- id = id.slice(0, -serverEntryQuery.length);
2238
- }
2239
2301
  if (!renderVirtualFilesResult) {
2240
2302
  await renderVirtualFiles(this);
2241
2303
  }
@@ -2284,8 +2346,8 @@ function markoRun(opts = {}) {
2284
2346
  }
2285
2347
  store.write(routeData);
2286
2348
  await ((_a = opts == null ? void 0 : opts.emitRoutes) == null ? void 0 : _a.call(opts, routes.list));
2287
- } else if (process.env.MR_EXPLORER !== "true") {
2288
- logRoutesTable(routes, bundle);
2349
+ } else {
2350
+ logRoutesTable(routes, [...externalRoutes], bundle);
2289
2351
  }
2290
2352
  },
2291
2353
  async closeBundle() {
@@ -2358,10 +2420,22 @@ async function resolveAdapter(root, options, log) {
2358
2420
  log && debug("Using default adapter");
2359
2421
  return module.default();
2360
2422
  }
2361
- var markoEntryFileRegex = /__marko-run__([^.]+)(?:\.(.+))?\.marko\.([^.]+)$/;
2423
+ var markoEntryFileRegex = /([^/\\]+)\.marko$/;
2362
2424
  function getEntryFileName(file) {
2363
2425
  const match = file && markoEntryFileRegex.exec(file);
2364
- return match ? match[2] || "index" : void 0;
2426
+ return match ? match[1] : void 0;
2427
+ }
2428
+ function getPlugin(config2) {
2429
+ return config2.plugins.find(
2430
+ (plugin) => plugin.name === `${PLUGIN_NAME_PREFIX}:pre`
2431
+ );
2432
+ }
2433
+ function getApi(config2) {
2434
+ const plugin = getPlugin(config2);
2435
+ if (!plugin) {
2436
+ throw new Error("Marko Run vite plugin not found");
2437
+ }
2438
+ return plugin.api;
2365
2439
  }
2366
2440
  function getImporters(module, fileName, seen = /* @__PURE__ */ new Set()) {
2367
2441
  for (const importer of module.importers) {
@@ -2524,6 +2598,7 @@ function sleep(ms) {
2524
2598
  export {
2525
2599
  markoRun as default,
2526
2600
  defaultConfigPlugin,
2601
+ getApi,
2527
2602
  getAvailablePort,
2528
2603
  getPackageData,
2529
2604
  isPortInUse,
@@ -1,5 +1,5 @@
1
1
  import { type Plugin, type ResolvedConfig } from "vite";
2
- import type { Adapter, Options, PackageData } from "./types";
2
+ import type { Adapter, ExternalRoutes, Options, PackageData } from "./types";
3
3
  export declare const defaultPort: number;
4
4
  declare module "vite" {
5
5
  interface TransformResult {
@@ -10,4 +10,7 @@ export default function markoRun(opts?: Options): Plugin[];
10
10
  export declare function getPackageData(dir: string): Promise<PackageData | null>;
11
11
  export declare function resolveAdapter(root: string, options?: Options, log?: boolean): Promise<Adapter | null>;
12
12
  export declare function isPluginIncluded(config: ResolvedConfig): boolean;
13
+ export declare function getApi(config: ResolvedConfig): {
14
+ addExternalRoutes(routes: ExternalRoutes): () => void;
15
+ };
13
16
  export declare const defaultConfigPlugin: Plugin;
@@ -7,4 +7,3 @@ export interface RouteSource {
7
7
  basePath?: string;
8
8
  }
9
9
  export declare function buildRoutes(sources: RouteSource | RouteSource[], outDir: string): Promise<BuiltRoutes>;
10
- export declare function replaceInvalidFilenameChars(str: string): string;
@@ -53,6 +53,10 @@ export interface Adapter {
53
53
  virtualFiles: Map<string, string>;
54
54
  meta: RouteGenerationData;
55
55
  }): Promise<void> | void;
56
+ isEntryTemplate?(event: {
57
+ template: string;
58
+ importer: string;
59
+ }): boolean;
56
60
  }
57
61
  export interface RouterOptions {
58
62
  trailingSlashes: "Ignore" | "RedirectWithout" | "RedirectWith" | "RewriteWithout" | "RewriteWith";
@@ -112,3 +116,11 @@ export interface ExplorerData {
112
116
  routes: Record<string, Route>;
113
117
  files: Record<string, string>;
114
118
  }
119
+ export interface ExternalRoutes {
120
+ name: string;
121
+ routes: {
122
+ path: string;
123
+ entryFile: string;
124
+ verbs: HttpVerb[];
125
+ }[];
126
+ }
@@ -1,3 +1,3 @@
1
1
  import type { OutputBundle } from "rollup";
2
- import type { BuiltRoutes } from "../types";
3
- export declare function logRoutesTable(routes: BuiltRoutes, bundle: OutputBundle): void;
2
+ import type { BuiltRoutes, ExternalRoutes } from "../types";
3
+ export declare function logRoutesTable(routes: BuiltRoutes, externalRoutes: ExternalRoutes[], bundle: OutputBundle): void;
@@ -1,4 +1,5 @@
1
1
  import type { HttpVerb, Route } from "../types";
2
2
  export declare function getVerbs(route: Route, noAutoHead?: boolean): HttpVerb[];
3
+ export declare function getUniqueSortedVerbs(verbs: HttpVerb[]): HttpVerb[];
3
4
  export declare function hasVerb(route: Route, verb: HttpVerb): boolean;
4
5
  export declare function getRouteVirtualFileName(route: Route): string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@marko/run",
3
- "version": "0.8.1",
3
+ "version": "0.9.1",
4
4
  "description": "The Marko application framework.",
5
5
  "keywords": [
6
6
  "marko"
@@ -55,7 +55,7 @@
55
55
  },
56
56
  "dependencies": {
57
57
  "@marko/run-explorer": "^2.0.1",
58
- "@marko/vite": "^5.1.7",
58
+ "@marko/vite": "^5.3.2",
59
59
  "browserslist": "^4.24.4",
60
60
  "cli-table3": "^0.6.5",
61
61
  "compression": "^1.8.0",