@marko/run 0.9.5 → 0.9.7

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.
@@ -1,6 +1,6 @@
1
1
  // src/adapter/index.ts
2
2
  import fs5 from "fs";
3
- import inspector from "inspector";
3
+ import inspector2 from "inspector";
4
4
  import path8 from "path";
5
5
  import { fileURLToPath as fileURLToPath2 } from "url";
6
6
 
@@ -20,9 +20,10 @@ import {
20
20
 
21
21
  // src/adapter/utils.ts
22
22
  import kleur from "kleur";
23
- import supporsColor from "supports-color";
23
+ import supportsColor from "supports-color";
24
24
  function stripAnsi(string) {
25
25
  return string.replace(
26
+ /* cspell:disable-next-line */
26
27
  /([\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><])/g,
27
28
  ""
28
29
  );
@@ -43,10 +44,10 @@ function prepareError(err) {
43
44
  };
44
45
  }
45
46
  function logInfoBox(address, explorer) {
46
- const color = !!supporsColor.stdout;
47
+ const color = !!supportsColor.stdout;
47
48
  let message = kleur.bold("Marko Run");
48
49
  if (true) {
49
- message += ` v${"0.9.5"}`;
50
+ message += ` v${"0.9.7"}`;
50
51
  }
51
52
  message += "\n\n";
52
53
  message += kleur.dim("Server listening at");
@@ -232,7 +233,7 @@ var httpVerbOrder = httpVerbs.reduce(
232
233
  import path3 from "path";
233
234
  var markoFiles = `(${RoutableFileTypes.Layout}|${RoutableFileTypes.Page}|${RoutableFileTypes.NotFound}|${RoutableFileTypes.Error})\\.(?:.*\\.)?(marko)`;
234
235
  var nonMarkoFiles = `(${RoutableFileTypes.Middleware}|${RoutableFileTypes.Handler}|${RoutableFileTypes.Meta})\\.(?:.*\\.)?(.+)`;
235
- var routeableFileRegex = new RegExp(
236
+ var RoutableFileRegex = new RegExp(
236
237
  `[+](?:${markoFiles}|${nonMarkoFiles})$`,
237
238
  "i"
238
239
  );
@@ -302,11 +303,11 @@ async function resolveAdapter(root, options, log) {
302
303
  }
303
304
  const pkg = await getPackageData(root);
304
305
  if (pkg) {
305
- let dependecies = pkg.dependencies ? Object.keys(pkg.dependencies) : [];
306
+ let dependencies = pkg.dependencies ? Object.keys(pkg.dependencies) : [];
306
307
  if (pkg.devDependencies) {
307
- dependecies = dependecies.concat(Object.keys(pkg.devDependencies));
308
+ dependencies = dependencies.concat(Object.keys(pkg.devDependencies));
308
309
  }
309
- for (const name of dependecies) {
310
+ for (const name of dependencies) {
310
311
  if (name.startsWith("@marko/run-adapter") || name.indexOf("marko-run-adapter") !== -1) {
311
312
  try {
312
313
  const module2 = await import(
@@ -314,7 +315,7 @@ async function resolveAdapter(root, options, log) {
314
315
  name
315
316
  );
316
317
  log && debug(
317
- `Using adapter ${name} listed in your package.json dependecies`
318
+ `Using adapter ${name} listed in your package.json dependencies`
318
319
  );
319
320
  return module2.default();
320
321
  } catch (err) {
@@ -459,7 +460,7 @@ async function waitForServer(port, wait = 0) {
459
460
  await sleep(100);
460
461
  } else {
461
462
  throw new Error(
462
- `Timeout while wating for server to start on port "${port}".`
463
+ `Timeout while waiting for server to start on port "${port}".`
463
464
  );
464
465
  }
465
466
  }
@@ -532,9 +533,9 @@ import {
532
533
  // src/adapter/logger.ts
533
534
  import DraftLog from "draftlog";
534
535
  import format2 from "human-format";
535
- import inpspector from "inspector";
536
+ import inspector from "inspector";
536
537
  import kleur3 from "kleur";
537
- if (!inpspector.url()) {
538
+ if (!inspector.url()) {
538
539
  DraftLog.into(console);
539
540
  DraftLog.defaults.canReWrite = false;
540
541
  }
@@ -1024,8 +1025,8 @@ function adapter() {
1024
1025
  port,
1025
1026
  envFile
1026
1027
  );
1027
- nextWorker.on("message", (messsage) => {
1028
- if (messsage === "restart") {
1028
+ nextWorker.on("message", (message) => {
1029
+ if (message === "restart") {
1029
1030
  start();
1030
1031
  }
1031
1032
  }).send({ type: "start", entry, config: config2 });
@@ -1055,7 +1056,7 @@ function adapter() {
1055
1056
  envFile && await loadEnv(envFile);
1056
1057
  const inspect = getInspectOptions(options.args);
1057
1058
  if (inspect) {
1058
- inspector.open(inspect.port, inspect.host, inspect.wait);
1059
+ inspector2.open(inspect.port, inspect.host, inspect.wait);
1059
1060
  }
1060
1061
  const listenerPromise = new Promise((resolve) => {
1061
1062
  const listener2 = devServer.middlewares.listen(port, () => {
@@ -21,7 +21,7 @@ import { build as viteBuild, resolveConfig } from "vite";
21
21
 
22
22
  // src/adapter/index.ts
23
23
  import fs5 from "fs";
24
- import inspector from "inspector";
24
+ import inspector2 from "inspector";
25
25
  import path8 from "path";
26
26
  import { fileURLToPath as fileURLToPath2 } from "url";
27
27
 
@@ -41,9 +41,10 @@ import {
41
41
 
42
42
  // src/adapter/utils.ts
43
43
  import kleur from "kleur";
44
- import supporsColor from "supports-color";
44
+ import supportsColor from "supports-color";
45
45
  function stripAnsi(string) {
46
46
  return string.replace(
47
+ /* cspell:disable-next-line */
47
48
  /([\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><])/g,
48
49
  ""
49
50
  );
@@ -326,7 +327,10 @@ function renderRouteEntry(route, rootDir) {
326
327
  const imports = writer.branch("imports");
327
328
  const runtimeImports = [];
328
329
  if (handler) {
329
- runtimeImports.push("normalize");
330
+ runtimeImports.push("normalizeHandler");
331
+ }
332
+ if (meta) {
333
+ runtimeImports.push("normalizeMeta");
330
334
  }
331
335
  if (handler || middleware.length) {
332
336
  runtimeImports.push("call");
@@ -358,7 +362,9 @@ function renderRouteEntry(route, rootDir) {
358
362
  for (const verb of handler.verbs) {
359
363
  const importName = verb.toUpperCase();
360
364
  names.push(importName);
361
- writer.writeLines(`const ${verb}Handler = normalize(${importName});`);
365
+ writer.writeLines(
366
+ `const ${verb}Handler = normalizeHandler(${importName});`
367
+ );
362
368
  }
363
369
  imports.writeLines(
364
370
  `import { ${names.join(", ")} } from "${normalizedRelativePath(rootDir, handler.filePath)}";`
@@ -370,8 +376,18 @@ function renderRouteEntry(route, rootDir) {
370
376
  );
371
377
  }
372
378
  if (meta) {
379
+ const metaName = `meta${index}`;
380
+ const metaVerbsExports = verbs.map((verb) => {
381
+ var _a2;
382
+ const name = verb === "head" && !((_a2 = handler == null ? void 0 : handler.verbs) == null ? void 0 : _a2.includes(verb)) ? "GET" : verb.toUpperCase();
383
+ return `${name}: ${verb}${index}_meta`;
384
+ }).join(", ");
385
+ writer.writeLines("");
373
386
  imports.writeLines(
374
- `export { default as meta${index} } from "${normalizedRelativePath(rootDir, meta.filePath)}";`
387
+ `import ${metaName} from "${normalizedRelativePath(rootDir, meta.filePath)}";`
388
+ );
389
+ writer.writeLines(
390
+ `export const { ${metaVerbsExports} } = normalizeMeta(${metaName});`
375
391
  );
376
392
  }
377
393
  for (const verb of verbs) {
@@ -490,10 +506,16 @@ function renderRouter(routes, rootDir, runtimeInclude, options = {
490
506
  );
491
507
  for (const route of routes.list) {
492
508
  const verbs = getVerbs(route);
493
- const names = verbs.map((verb) => `${verb}${route.index}`);
494
- route.meta && names.push(`meta${route.index}`);
509
+ const routeImports = [];
510
+ for (const verb of verbs) {
511
+ const verbName = `${verb}${route.index}`;
512
+ routeImports.push(verbName);
513
+ if (route.meta) {
514
+ routeImports.push(`${verbName}_meta`);
515
+ }
516
+ }
495
517
  imports.writeLines(
496
- `import { ${names.join(", ")} } from "${virtualFilePrefix}/${getRouteVirtualFileName(route)}";`
518
+ `import { ${routeImports.join(", ")} } from "${virtualFilePrefix}/${getRouteVirtualFileName(route)}";`
497
519
  );
498
520
  }
499
521
  for (const route of Object.values(routes.special)) {
@@ -785,14 +807,14 @@ function renderParams(params, pathIndex) {
785
807
  function renderMatch(verb, route, path10, pathIndex) {
786
808
  const handler = `${verb}${route.index}`;
787
809
  const params = path10.params ? renderParams(path10.params, pathIndex) : "{}";
788
- const meta = route.meta ? `meta${route.index}` : "{}";
810
+ const meta = route.meta ? `${verb}${route.index}_meta` : "{}";
789
811
  return `{ handler: ${handler}, params: ${params}, meta: ${meta}, path: '${path10.path}' }`;
790
812
  }
791
813
  function renderMiddleware(middleware, rootDir) {
792
814
  const writer = createStringWriter();
793
815
  const imports = writer.branch("imports");
794
816
  imports.writeLines(
795
- `import { normalize } from "${virtualFilePrefix}/runtime/internal";`
817
+ `import { normalizeHandler } from "${virtualFilePrefix}/runtime/internal";`
796
818
  );
797
819
  writer.writeLines("");
798
820
  for (const { id, filePath } of middleware) {
@@ -800,7 +822,9 @@ function renderMiddleware(middleware, rootDir) {
800
822
  imports.writeLines(
801
823
  `import ${importName} from "${normalizedRelativePath(rootDir, filePath)}";`
802
824
  );
803
- writer.writeLines(`export const mware${id} = normalize(${importName});`);
825
+ writer.writeLines(
826
+ `export const mware${id} = normalizeHandler(${importName});`
827
+ );
804
828
  }
805
829
  imports.join();
806
830
  return writer.end();
@@ -959,7 +983,12 @@ function writeModuleDeclaration(writer, name, routeType, moduleTypes) {
959
983
  export { NotHandled, NotMatched, GetPaths, PostPaths, GetablePath, GetableHref, PostablePath, PostableHref, Platform };
960
984
  export type Route = ${routeType};
961
985
  export type Context = Run.MultiRouteContext<Route>${isMarko ? " & Marko.Global" : ""};
962
- export type Handler = Run.HandlerLike<Route>;
986
+ export type Handler = Run.HandlerLike<Route>;`);
987
+ for (const verb of httpVerbs) {
988
+ writer.write(`
989
+ export type ${verb.toUpperCase()} = Run.HandlerLike<Route, "${verb.toUpperCase()}">;`);
990
+ }
991
+ writer.write(`
963
992
  /** @deprecated use \`((context, next) => { ... }) satisfies MarkoRun.Handler\` instead */
964
993
  export const route: Run.HandlerTypeFn<Route>;
965
994
  }`);
@@ -1324,12 +1353,12 @@ var VDir = _VDir;
1324
1353
  // src/vite/routes/builder.ts
1325
1354
  var markoFiles = `(${RoutableFileTypes.Layout}|${RoutableFileTypes.Page}|${RoutableFileTypes.NotFound}|${RoutableFileTypes.Error})\\.(?:.*\\.)?(marko)`;
1326
1355
  var nonMarkoFiles = `(${RoutableFileTypes.Middleware}|${RoutableFileTypes.Handler}|${RoutableFileTypes.Meta})\\.(?:.*\\.)?(.+)`;
1327
- var routeableFileRegex = new RegExp(
1356
+ var RoutableFileRegex = new RegExp(
1328
1357
  `[+](?:${markoFiles}|${nonMarkoFiles})$`,
1329
1358
  "i"
1330
1359
  );
1331
1360
  function matchRoutableFile(filename) {
1332
- const match = filename.match(routeableFileRegex);
1361
+ const match = filename.match(RoutableFileRegex);
1333
1362
  return match && (match[1] || match[3]).toLowerCase();
1334
1363
  }
1335
1364
  async function buildRoutes(sources, outDir) {
@@ -1371,7 +1400,7 @@ async function buildRoutes(sources, outDir) {
1371
1400
  },
1372
1401
  onFile(file) {
1373
1402
  const { name } = file;
1374
- const match = name.match(routeableFileRegex);
1403
+ const match = name.match(RoutableFileRegex);
1375
1404
  if (!match) {
1376
1405
  return;
1377
1406
  }
@@ -2146,9 +2175,15 @@ function markoRun(opts = {}) {
2146
2175
  }
2147
2176
  rollupOutputOptions = mergeOutputOptions(
2148
2177
  {
2149
- assetFileNames: `${assetsDir}/[name]-[hash].[ext]`,
2178
+ assetFileNames(info) {
2179
+ var _a2;
2180
+ const name = ((_a2 = info.names) == null ? void 0 : _a2[0]) && cleanFileName(info.names[0]);
2181
+ return name ? `${assetsDir}/${name}-[hash].[ext]` : `${assetsDir}/_[hash].[ext]`;
2182
+ },
2150
2183
  entryFileNames(info) {
2151
- return `${assetsDir}/${getEntryFileName(info.name) || "[name]"}-[hash].js`;
2184
+ const raw = getEntryFileName(info.name) || info.name;
2185
+ const name = raw && cleanFileName(raw);
2186
+ return name ? `${assetsDir}/${name}-[hash].js` : `${assetsDir}/_[hash].js`;
2152
2187
  },
2153
2188
  chunkFileNames: isSSRBuild ? `_[hash].js` : `${assetsDir}/_[hash].js`
2154
2189
  },
@@ -2430,11 +2465,11 @@ async function resolveAdapter(root, options, log) {
2430
2465
  }
2431
2466
  const pkg = await getPackageData(root);
2432
2467
  if (pkg) {
2433
- let dependecies = pkg.dependencies ? Object.keys(pkg.dependencies) : [];
2468
+ let dependencies = pkg.dependencies ? Object.keys(pkg.dependencies) : [];
2434
2469
  if (pkg.devDependencies) {
2435
- dependecies = dependecies.concat(Object.keys(pkg.devDependencies));
2470
+ dependencies = dependencies.concat(Object.keys(pkg.devDependencies));
2436
2471
  }
2437
- for (const name of dependecies) {
2472
+ for (const name of dependencies) {
2438
2473
  if (name.startsWith("@marko/run-adapter") || name.indexOf("marko-run-adapter") !== -1) {
2439
2474
  try {
2440
2475
  const module2 = await import(
@@ -2442,7 +2477,7 @@ async function resolveAdapter(root, options, log) {
2442
2477
  name
2443
2478
  );
2444
2479
  log && debug(
2445
- `Using adapter ${name} listed in your package.json dependecies`
2480
+ `Using adapter ${name} listed in your package.json dependencies`
2446
2481
  );
2447
2482
  return module2.default();
2448
2483
  } catch (err) {
@@ -2464,6 +2499,9 @@ function getEntryFileName(file) {
2464
2499
  const match = file && markoEntryFileRegex.exec(file);
2465
2500
  return match ? match[1] : void 0;
2466
2501
  }
2502
+ function cleanFileName(name) {
2503
+ return name.replace(/\.[^/.]+$/, "").replace(/[^a-zA-Z0-9._[\]-]+/g, "-").replace(/-{2,}/g, "-").replace(/^-|-$/g, "");
2504
+ }
2467
2505
  function getPlugin(config2) {
2468
2506
  return config2.plugins.find(
2469
2507
  (plugin) => plugin.name === `${PLUGIN_NAME_PREFIX}:pre`
@@ -2538,9 +2576,9 @@ import {
2538
2576
  // src/adapter/logger.ts
2539
2577
  import DraftLog from "draftlog";
2540
2578
  import format2 from "human-format";
2541
- import inpspector from "inspector";
2579
+ import inspector from "inspector";
2542
2580
  import kleur3 from "kleur";
2543
- if (!inpspector.url()) {
2581
+ if (!inspector.url()) {
2544
2582
  DraftLog.into(console);
2545
2583
  DraftLog.defaults.canReWrite = false;
2546
2584
  }
@@ -1,13 +1,23 @@
1
1
  import { InlineConfig } from "vite";
2
2
  import { NotHandled, NotMatched } from "./namespace";
3
- import type { AnyContext, AnyHandler, AnyRoute, GetableHref, GetablePath, GetPaths, HandlerTypeFn, Platform, PostableHref, PostablePath, PostPaths, RuntimeModule } from "./types";
3
+ import type { AnyRoute, GetableHref, GetablePath, GetPaths, HandlerLike, HandlerTypeFn, MultiRouteContext, Platform, PostableHref, PostablePath, PostPaths, RuntimeModule } from "./types";
4
4
  declare global {
5
5
  var __marko_run__: RuntimeModule;
6
6
  var __marko_run_vite_config__: InlineConfig | undefined;
7
7
  namespace MarkoRun {
8
+ export { GetableHref, GetablePath, GetPaths, NotHandled, NotMatched, Platform, PostableHref, PostablePath, PostPaths, };
9
+ export type Route = AnyRoute;
10
+ export type Context = MultiRouteContext<AnyRoute>;
11
+ export type Handler = HandlerLike<AnyRoute>;
12
+ export type GET = HandlerLike<AnyRoute, "GET">;
13
+ export type HEAD = HandlerLike<AnyRoute, "HEAD">;
14
+ export type POST = HandlerLike<AnyRoute, "POST">;
15
+ export type PUT = HandlerLike<AnyRoute, "PUT">;
16
+ export type DELETE = HandlerLike<AnyRoute, "DELETE">;
17
+ export type PATCH = HandlerLike<AnyRoute, "PATCH">;
18
+ export type OPTIONS = HandlerLike<AnyRoute, "OPTIONS">;
8
19
  /** @deprecated use `((context, next) => { ... }) satisfies MarkoRun.Handler` instead */
9
20
  export const route: HandlerTypeFn;
10
- export { AnyContext as Context, GetableHref, GetablePath, GetPaths, AnyHandler as Handler, NotHandled, NotMatched, Platform, PostableHref, PostablePath, PostPaths, AnyRoute as Route, };
11
21
  }
12
22
  }
13
- export type { AppData, Context, DefineApp, Fetch, HandlerLike, HandlerTypeFn, InputObject, Invoke, LayoutInput, Match, MultiRouteContext, NextFunction, ParamsObject, Platform, Route, RouteHandler, Routes, RouteWithHandler, RuntimeModule, } from "./types";
23
+ export type { AppData, Context, DefineApp, Fetch, HandlerLike, HandlerTypeFn, InputObject, Invoke, LayoutInput, Match, MultiRouteContext, NextFunction, ParamsObject, Platform, Route, RouteHandler, Routes, RouteWithHandler, RuntimeModule, Verb, } from "./types";
@@ -26,7 +26,8 @@ __export(internal_exports, {
26
26
  compose: () => compose,
27
27
  createContext: () => createContext,
28
28
  noContent: () => noContent,
29
- normalize: () => normalize,
29
+ normalizeHandler: () => normalizeHandler,
30
+ normalizeMeta: () => getMetaDataLookup,
30
31
  notHandled: () => notHandled,
31
32
  notMatched: () => notMatched,
32
33
  passthrough: () => passthrough,
@@ -39,6 +40,49 @@ module.exports = __toCommonJS(internal_exports);
39
40
  var import_url = require("url");
40
41
  var __importMetaURL = (0, import_url.pathToFileURL)(__filename);
41
42
 
43
+ // src/vite/constants.ts
44
+ var httpVerbs = [
45
+ "get",
46
+ "head",
47
+ "post",
48
+ "put",
49
+ "delete",
50
+ "patch",
51
+ "options"
52
+ ];
53
+
54
+ // src/vite/utils/meta-data.ts
55
+ var verbKeys = new Set(httpVerbs.map((v) => v.toUpperCase()));
56
+ function isObject(obj) {
57
+ return obj && typeof obj === "object" && !Array.isArray(obj);
58
+ }
59
+ function getMetaDataForVerb(data, verb) {
60
+ if (!httpVerbs.includes(verb.toLowerCase())) {
61
+ throw new Error(
62
+ `Invalid argument 'verb': expected one of ${[...verbKeys].join(", ")} but received ${verb}`
63
+ );
64
+ }
65
+ if (isObject(data)) {
66
+ return Object.keys(data).reduce(
67
+ (result, key) => {
68
+ if (!(key in result || verbKeys.has(key))) {
69
+ result[key] = data[key];
70
+ }
71
+ return result;
72
+ },
73
+ isObject(data[verb]) ? { ...data[verb] } : {}
74
+ );
75
+ }
76
+ return data;
77
+ }
78
+ function getMetaDataLookup(data) {
79
+ const lookup = {};
80
+ for (const verb of verbKeys) {
81
+ lookup[verb] = getMetaDataForVerb(data, verb);
82
+ }
83
+ return lookup;
84
+ }
85
+
42
86
  // src/runtime/internal.ts
43
87
  var NotHandled = Symbol(
44
88
  "marko-run not handled"
@@ -101,6 +145,7 @@ function createContext(route, request, platform, url = new URL(request.url)) {
101
145
  }
102
146
  return {
103
147
  request,
148
+ method: request.method,
104
149
  url,
105
150
  platform,
106
151
  meta,
@@ -211,7 +256,7 @@ function compose(handlers) {
211
256
  })();
212
257
  };
213
258
  }
214
- function normalize(obj) {
259
+ function normalizeHandler(obj) {
215
260
  if (typeof obj === "function") {
216
261
  return obj;
217
262
  } else if (Array.isArray(obj)) {
@@ -255,7 +300,8 @@ function notMatched() {
255
300
  compose,
256
301
  createContext,
257
302
  noContent,
258
- normalize,
303
+ normalizeHandler,
304
+ normalizeMeta,
259
305
  notHandled,
260
306
  notMatched,
261
307
  passthrough,
@@ -1,10 +1,11 @@
1
1
  import type { AnyRoute, Awaitable, Context, MultiRouteContext, NextFunction, Platform, RouteHandler } from "./types";
2
+ export { getMetaDataLookup as normalizeMeta } from "../vite/utils/meta-data";
2
3
  export declare const NotHandled: typeof MarkoRun.NotHandled;
3
4
  export declare const NotMatched: typeof MarkoRun.NotMatched;
4
5
  export declare function createContext<TRoute extends AnyRoute>(route: TRoute | null, request: Request, platform: Platform, url?: URL): Context<TRoute>;
5
6
  export declare function call<TRoute extends AnyRoute>(handler: RouteHandler<TRoute>, next: NextFunction, context: MultiRouteContext<TRoute>): Promise<Response>;
6
7
  export declare function compose(handlers: RouteHandler[]): RouteHandler;
7
- export declare function normalize(obj: RouteHandler | RouteHandler[] | Promise<RouteHandler | RouteHandler[]>): RouteHandler;
8
+ export declare function normalizeHandler(obj: RouteHandler | RouteHandler[] | Promise<RouteHandler | RouteHandler[]>): RouteHandler;
8
9
  export declare function stripResponseBodySync(response: Response): Response;
9
10
  export declare function stripResponseBody(response: Awaitable<Response>): Awaitable<Response>;
10
11
  export declare function passthrough(): void;
@@ -1,3 +1,46 @@
1
+ // src/vite/constants.ts
2
+ var httpVerbs = [
3
+ "get",
4
+ "head",
5
+ "post",
6
+ "put",
7
+ "delete",
8
+ "patch",
9
+ "options"
10
+ ];
11
+
12
+ // src/vite/utils/meta-data.ts
13
+ var verbKeys = new Set(httpVerbs.map((v) => v.toUpperCase()));
14
+ function isObject(obj) {
15
+ return obj && typeof obj === "object" && !Array.isArray(obj);
16
+ }
17
+ function getMetaDataForVerb(data, verb) {
18
+ if (!httpVerbs.includes(verb.toLowerCase())) {
19
+ throw new Error(
20
+ `Invalid argument 'verb': expected one of ${[...verbKeys].join(", ")} but received ${verb}`
21
+ );
22
+ }
23
+ if (isObject(data)) {
24
+ return Object.keys(data).reduce(
25
+ (result, key) => {
26
+ if (!(key in result || verbKeys.has(key))) {
27
+ result[key] = data[key];
28
+ }
29
+ return result;
30
+ },
31
+ isObject(data[verb]) ? { ...data[verb] } : {}
32
+ );
33
+ }
34
+ return data;
35
+ }
36
+ function getMetaDataLookup(data) {
37
+ const lookup = {};
38
+ for (const verb of verbKeys) {
39
+ lookup[verb] = getMetaDataForVerb(data, verb);
40
+ }
41
+ return lookup;
42
+ }
43
+
1
44
  // src/runtime/internal.ts
2
45
  var NotHandled = Symbol(
3
46
  "marko-run not handled"
@@ -60,6 +103,7 @@ function createContext(route, request, platform, url = new URL(request.url)) {
60
103
  }
61
104
  return {
62
105
  request,
106
+ method: request.method,
63
107
  url,
64
108
  platform,
65
109
  meta,
@@ -170,7 +214,7 @@ function compose(handlers) {
170
214
  })();
171
215
  };
172
216
  }
173
- function normalize(obj) {
217
+ function normalizeHandler(obj) {
174
218
  if (typeof obj === "function") {
175
219
  return obj;
176
220
  } else if (Array.isArray(obj)) {
@@ -213,7 +257,8 @@ export {
213
257
  compose,
214
258
  createContext,
215
259
  noContent,
216
- normalize,
260
+ normalizeHandler,
261
+ getMetaDataLookup as normalizeMeta,
217
262
  notHandled,
218
263
  notMatched,
219
264
  passthrough,
@@ -1,3 +1,3 @@
1
1
  export declare const NotHandled: unique symbol;
2
2
  export declare const NotMatched: unique symbol;
3
- export type { GetableHref, GetablePath, GetPaths, Platform, PostableHref, PostablePath, PostPaths, } from "./types";
3
+ export type { GetableHref, GetablePath, GetPaths, Platform, PostableHref, PostablePath, PostPaths, Verb, } from "./types";
@@ -1,24 +1,28 @@
1
- export type Awaitable<T> = Promise<T> | T;
1
+ import type { HttpVerb } from "../vite";
2
2
  type OneOrMany<T> = T | T[];
3
3
  type NoParams = {};
4
4
  type AllKeys<T> = T extends T ? keyof T : never;
5
5
  type Simplify<T> = T extends unknown ? {
6
6
  [K in keyof T]: T[K];
7
7
  } : never;
8
+ type IsObject<T> = T extends object ? T extends any[] ? 0 : T extends (...args: any[]) => any ? 0 : 1 : 0;
8
9
  type SuperSet<T, U extends T> = T & {
9
10
  [K in AllKeys<U> as K extends keyof T ? never : K]?: never;
10
11
  };
11
12
  type SuperSets<T, U extends T, K extends keyof T> = Omit<T, K> & {
12
13
  [P in K]: Simplify<SuperSet<T[P], U[P]>>;
13
14
  };
15
+ export type Awaitable<T> = Promise<T> | T;
16
+ export type Verb = Uppercase<HttpVerb>;
14
17
  export interface Platform {
15
18
  }
16
- export interface Context<TRoute extends Route = AnyRoute> {
19
+ export interface Context<TRoute extends Route = AnyRoute, TVerb extends Verb = Verb> {
17
20
  readonly url: URL;
18
21
  readonly request: Request;
22
+ readonly method: TVerb;
19
23
  readonly route: TRoute["path"];
20
24
  readonly params: TRoute["params"];
21
- readonly meta: TRoute["meta"];
25
+ readonly meta: NormalizedMeta<TRoute["meta"], TVerb>;
22
26
  readonly platform: Platform;
23
27
  readonly serializedGlobals: Record<string, boolean>;
24
28
  readonly parent: Context | undefined;
@@ -27,14 +31,14 @@ export interface Context<TRoute extends Route = AnyRoute> {
27
31
  redirect(to: string | URL, status?: number): Response;
28
32
  back(fallback?: string | URL, status?: number): Response;
29
33
  }
30
- export type MultiRouteContext<TRoute extends Route, _Preserved extends TRoute = TRoute> = TRoute extends any ? Context<Simplify<SuperSets<TRoute, _Preserved, "params">>> : never;
34
+ export type MultiRouteContext<TRoute extends Route, TVerb extends Verb = Verb, _Preserved extends TRoute = TRoute> = TRoute extends any ? TVerb extends any ? Context<Simplify<SuperSets<TRoute, _Preserved, "params">>, TVerb> : never : never;
31
35
  export type ParamsObject = Record<string, string>;
32
36
  export type InputObject = Record<PropertyKey, any>;
33
37
  export type NextFunction = () => Awaitable<Response>;
34
- export type HandlerLike<TRoute extends Route = AnyRoute> = Awaitable<OneOrMany<RouteHandler<TRoute>>>;
38
+ export type HandlerLike<TRoute extends Route = AnyRoute, TVerb extends Verb = Verb> = Awaitable<OneOrMany<RouteHandler<TRoute, TVerb>>>;
35
39
  export type RouteHandlerResult = Response | typeof MarkoRun.NotHandled | typeof MarkoRun.NotMatched | null | void;
36
- export type RouteHandler<TRoute extends Route = AnyRoute> = (context: MultiRouteContext<TRoute>, next: NextFunction) => Awaitable<RouteHandlerResult>;
37
- export interface Route<Params extends ParamsObject = ParamsObject, Meta = unknown, Path extends string = string> {
40
+ export type RouteHandler<TRoute extends Route = AnyRoute, TVerb extends Verb = Verb> = (context: MultiRouteContext<TRoute, TVerb>, next: NextFunction) => Awaitable<RouteHandlerResult>;
41
+ export interface Route<Params extends ParamsObject = ParamsObject, Meta = any, Path extends string = string> {
38
42
  path: Path;
39
43
  params: Params;
40
44
  meta: Meta;
@@ -44,14 +48,14 @@ type DefineRoutes<T extends Record<string, {
44
48
  }>> = {
45
49
  [K in keyof T]: K extends string ? T[K] extends {
46
50
  meta: infer Meta;
47
- } ? Route<PathParams<K>, Meta, K> : Route<PathParams<K>, unknown, K> : never;
51
+ } ? Route<PathParams<K>, Meta, K> : Route<PathParams<K>, any, K> : never;
48
52
  };
49
53
  type DefinePaths<T extends Record<string, {
50
54
  verb: unknown;
51
- }>, Verb extends "get" | "post"> = {
55
+ }>, TVerb extends "get" | "post"> = {
52
56
  [K in keyof T]: K extends string ? T[K] extends {
53
57
  verb: infer V;
54
- } ? V extends Verb ? K : never : never : never;
58
+ } ? V extends TVerb ? K : never : never : never;
55
59
  }[keyof T];
56
60
  export type DefineApp<T extends {
57
61
  routes: Record<string, {
@@ -86,20 +90,22 @@ type MatchSegments<A extends string, B extends string> = A extends `${infer P}/$
86
90
  type PathPattern<T extends string> = T extends `${infer Left}/\${${string}}/${infer Rest}` ? PathPattern<`${Left}/${string}/${Rest}`> : T extends `${infer Left}/\${...${string}}` ? PathPattern<`${Left}/${string}*`> : T extends `${infer Left}/\${${string}}` ? PathPattern<`${Left}/${string}`> : T;
87
91
  type ValidatePath<Paths extends string, Path extends string> = Paths | (Path extends `/${string}` ? MatchSegments<Member<PathPattern<Paths>, Path>, Path> : Path);
88
92
  type ValidateHref<Paths extends string, Href extends string> = Href extends `${infer P}#${infer H}?${infer Q}` ? `${ValidatePath<Paths, P>}#${H}?${Q}` : Href extends `${infer P}?${infer Q}` ? `${ValidatePath<Paths, P>}?${Q}` : Href extends `${infer P}#${infer H}` ? `${ValidatePath<Paths, P>}#${H}` : ValidatePath<Paths, Href>;
93
+ type NormalizedMetaObject<T, TVerb extends Verb = Verb> = IsObject<T> extends 1 ? TVerb extends keyof T ? Simplify<Omit<T, Verb | keyof T[TVerb]> & T[TVerb]> : Simplify<Omit<T, Verb>> : never;
94
+ export type NormalizedMeta<T, TVerb extends Verb = Verb> = IsObject<T> extends 1 ? {
95
+ [K in TVerb]: NormalizedMetaObject<T, K>;
96
+ }[TVerb] : T;
97
+ export type NormalizedMetaLookup<T> = {
98
+ [K in Verb]: IsObject<T> extends 1 ? NormalizedMetaObject<T, K> : T;
99
+ };
89
100
  export interface AppData {
90
101
  }
91
- type HasAppData = AppData extends {
92
- routes: any;
93
- } ? 1 : 0;
94
- type AnyParams = 0 extends HasAppData ? ParamsObject : never;
95
- type AnyMeta = 0 extends HasAppData ? unknown : never;
96
102
  export type Routes = AppData extends {
97
103
  routes: infer T;
98
104
  } ? T : Record<string, Route>;
99
105
  export type AnyRoute = Routes[keyof Routes];
100
- export type AnyContext = MultiRouteContext<AnyRoute>;
101
- export type AnyHandler<Params extends AnyParams = AnyParams, Meta extends AnyMeta = AnyMeta> = 0 extends HasAppData ? HandlerLike<Route<Params, Meta>> : HandlerLike<AnyRoute>;
102
- export type HandlerTypeFn<TRoute extends Route = AnyRoute> = 0 extends HasAppData ? <Params extends ParamsObject = ParamsObject, Meta = unknown, T extends HandlerLike<Route<Params, Meta>> = HandlerLike<Route<Params, Meta>>>(handler: T) => T : <T extends HandlerLike<TRoute>>(handler: T) => T;
106
+ export type HandlerTypeFn<TRoute extends Route = AnyRoute> = AppData extends {
107
+ routes: any;
108
+ } ? <Params extends ParamsObject = ParamsObject, Meta = any, T extends HandlerLike<Route<Params, Meta>> = HandlerLike<Route<Params, Meta>>>(handler: T) => T : <T extends HandlerLike<TRoute>>(handler: T) => T;
103
109
  type DefaultAPI = keyof Exclude<Marko.Renderable, Marko.Template<any, any> | Marko.Body<any, any> | string> extends "content" ? "tags" : "class";
104
110
  type TemplateAPI<T> = T extends {
105
111
  api: infer API;