@marko/run 0.1.1 → 0.1.3

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.
@@ -36,6 +36,7 @@ var import_url = require("url");
36
36
 
37
37
  // src/adapter/dev-server.ts
38
38
  var import_vite = require("vite");
39
+ var import_strip_ansi = __toESM(require("strip-ansi"), 1);
39
40
  function createViteDevMiddleware(devServer, load, factory) {
40
41
  let value;
41
42
  let middleware;
@@ -51,7 +52,7 @@ function createViteDevMiddleware(devServer, load, factory) {
51
52
  res.statusCode = 500;
52
53
  if (err instanceof Error) {
53
54
  devServer.ssrFixStacktrace(err);
54
- res.end(err.stack);
55
+ res.end(err.stack && (0, import_strip_ansi.default)(err.stack));
55
56
  } else {
56
57
  res.end();
57
58
  }
@@ -4,6 +4,7 @@ import { fileURLToPath } from "url";
4
4
 
5
5
  // src/adapter/dev-server.ts
6
6
  import { createServer } from "vite";
7
+ import stripAnsi from "strip-ansi";
7
8
  function createViteDevMiddleware(devServer, load, factory) {
8
9
  let value;
9
10
  let middleware;
@@ -19,7 +20,7 @@ function createViteDevMiddleware(devServer, load, factory) {
19
20
  res.statusCode = 500;
20
21
  if (err instanceof Error) {
21
22
  devServer.ssrFixStacktrace(err);
22
- res.end(err.stack);
23
+ res.end(err.stack && stripAnsi(err.stack));
23
24
  } else {
24
25
  res.end();
25
26
  }
@@ -20,7 +20,7 @@ export interface NodePlatformInfo {
20
20
  setCookie(cookie: string): void;
21
21
  }
22
22
  /** Connect/Express style request listener/middleware */
23
- export declare type NodeMiddleware = (req: IncomingMessage, res: ServerResponse & {
23
+ export type NodeMiddleware = (req: IncomingMessage, res: ServerResponse & {
24
24
  flush?: () => void;
25
25
  }, next?: () => void) => void;
26
26
  /** Adapter options */
@@ -1,7 +1,6 @@
1
1
  import { defineConfig } from "vite";
2
2
  import marko from "@marko/run/vite";
3
- import nodeAdapter from "@marko/run/adapter";
4
3
 
5
4
  export default defineConfig({
6
- plugins: [marko({ adapter: nodeAdapter() })]
5
+ plugins: [marko()]
7
6
  });
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  // src/cli/index.ts
4
- import path from "path";
5
- import fs2 from "fs";
6
- import { fileURLToPath } from "url";
4
+ import path3 from "path";
5
+ import fs4 from "fs";
6
+ import { fileURLToPath as fileURLToPath2 } from "url";
7
7
  import { build as viteBuild, resolveConfig } from "vite";
8
8
  import sade from "sade";
9
9
 
@@ -91,25 +91,124 @@ function sleep(ms) {
91
91
  return new Promise((resolve) => setTimeout(resolve, ms));
92
92
  }
93
93
 
94
- // src/cli/index.ts
94
+ // src/vite/plugin.ts
95
+ import path2 from "path";
96
+ import crypto from "crypto";
97
+ import fs3 from "fs";
98
+ import glob from "glob";
99
+ import { mergeConfig, resolvePackageData } from "vite";
100
+ import markoVitePlugin, { FileStore } from "@marko/vite";
101
+
102
+ // src/vite/constants.ts
103
+ var virtualFilePrefix = "virtual:marko-run";
104
+ var virtualRoutesPrefix = `${virtualFilePrefix}/routes`;
105
+ var virtualRuntimePrefix = `${virtualFilePrefix}/internal`;
106
+ var RoutableFileTypes = {
107
+ Page: "page",
108
+ Layout: "layout",
109
+ Handler: "handler",
110
+ Middleware: "middleware",
111
+ Meta: "meta",
112
+ NotFound: "404",
113
+ Error: "500"
114
+ };
115
+
116
+ // src/vite/routes/builder.ts
117
+ var markoFiles = `(${RoutableFileTypes.Layout}|${RoutableFileTypes.Page}|${RoutableFileTypes.NotFound}|${RoutableFileTypes.Error})\\.(?:.*\\.)?(marko)`;
118
+ var nonMarkoFiles = `(${RoutableFileTypes.Middleware}|${RoutableFileTypes.Handler}|${RoutableFileTypes.Meta})\\.(?:.*\\.)?(.+)`;
119
+ var routeableFileRegex = new RegExp(
120
+ `^[+](?:${markoFiles}|${nonMarkoFiles})$`,
121
+ "i"
122
+ );
123
+
124
+ // src/vite/routes/walk.ts
125
+ import fs2 from "fs";
126
+ import path from "path";
127
+
128
+ // src/vite/utils/ast.ts
129
+ import * as t from "@babel/types";
130
+
131
+ // src/vite/utils/log.ts
132
+ import Table from "cli-table3";
133
+ import kleur from "kleur";
134
+ import { gzipSizeSync } from "gzip-size";
135
+ import format from "human-format";
136
+ var HttpVerbColors = {
137
+ get: kleur.green,
138
+ post: kleur.magenta,
139
+ put: kleur.cyan,
140
+ delete: kleur.red,
141
+ other: kleur.white
142
+ };
143
+
144
+ // src/vite/plugin.ts
145
+ import { fileURLToPath } from "url";
95
146
  var __dirname = fileURLToPath(new URL(".", import.meta.url));
147
+ var POSIX_SEP = "/";
148
+ var WINDOWS_SEP = "\\";
149
+ var normalizePath = path2.sep === WINDOWS_SEP ? (id) => id.replace(/\\/g, POSIX_SEP) : (id) => id;
150
+ async function resolveAdapter(root, options, log) {
151
+ const { adapter } = options;
152
+ if (adapter !== void 0) {
153
+ return adapter;
154
+ }
155
+ const pkg = resolvePackageData(".", root);
156
+ if (pkg) {
157
+ const dependecies = { ...pkg.data.dependecies, ...pkg.data.devDependencies };
158
+ for (const name of Object.keys(dependecies)) {
159
+ if (name.startsWith("@marko/run-adapter") || name.indexOf("marko-run-adapter") !== -1) {
160
+ try {
161
+ const module2 = await import(name);
162
+ log && console.log(`Using adapter ${name} listed in your package.json dependecies`);
163
+ return module2.default();
164
+ } catch (err) {
165
+ log && console.warn(`Attempt to use package '${name}' failed`, err);
166
+ }
167
+ }
168
+ }
169
+ }
170
+ const defaultAdapter = "@marko/run/adapter";
171
+ const module = await import(defaultAdapter);
172
+ log && console.log("Using default adapter");
173
+ return module.default();
174
+ }
175
+
176
+ // src/cli/index.ts
177
+ var __dirname2 = fileURLToPath2(new URL(".", import.meta.url));
96
178
  var cwd = process.cwd();
97
179
  var defaultPort = +process.env.PORT || 3e3;
98
180
  var defaultConfigFileBases = ["serve.config", "vite.config"];
99
181
  var defaultConfigFileExts = [".js", ".cjs", ".mjs", ".ts", ".mts"];
100
- var prog = sade("marko-run").version("0.0.1").option("-c, --config", `Provide path to a Vite config file (by default looks for a file starting with ${defaultConfigFileBases.join(" or ")} with one of these extensions: ${defaultConfigFileExts.join(", ")})`).option("-e, --env", "Provide path to a dotenv file");
101
- prog.command("preview [entry]").describe("Start a production-like server for already-built app files").option("-o, --output", "Directory to serve files from, and write asset files to if `--build` (default: )").option("-p, --port", "Port the server should listen on (defaults: `$PORT` env variable or 3000)").option("-f, --file", "Output file to start").action(async (entry, opts) => {
182
+ var prog = sade("marko-run").version("0.0.1").option(
183
+ "-c, --config",
184
+ `Provide path to a Vite config file (by default looks for a file starting with ${defaultConfigFileBases.join(
185
+ " or "
186
+ )} with one of these extensions: ${defaultConfigFileExts.join(", ")})`
187
+ ).option("-e, --env", "Provide path to a dotenv file");
188
+ prog.command("preview [entry]").describe("Start a production-like server for already-built app files").option(
189
+ "-o, --output",
190
+ "Directory to serve files from, and write asset files to if `--build` (default: )"
191
+ ).option(
192
+ "-p, --port",
193
+ "Port the server should listen on (defaults: `$PORT` env variable or 3000)"
194
+ ).option("-f, --file", "Output file to start").action(async (entry, opts) => {
102
195
  process.env.NODE_ENV = "production";
103
196
  const config2 = await getViteConfig(cwd, opts.config);
104
197
  await build(entry, config2, opts.output, false, opts.env);
105
198
  await preview(opts.entry, config2, opts.port, opts.output, opts.env);
106
199
  });
107
- prog.command("dev [entry]", "", { default: true }).describe("Start development server in watch mode").option("-p, --port", "Port the dev server should listen on (defaults: 'preview.port' in config, or `$PORT` env variable, or 3000)").example("dev --config vite.config.js").action(async (entry, opts) => {
200
+ prog.command("dev [entry]", "", { default: true }).describe("Start development server in watch mode").option(
201
+ "-p, --port",
202
+ "Port the dev server should listen on (defaults: 'preview.port' in config, or `$PORT` env variable, or 3000)"
203
+ ).example("dev --config vite.config.js").action(async (entry, opts) => {
108
204
  const cmd = opts._.length ? `${entry} ${opts._.join(" ")}` : entry ? `node ${entry}` : void 0;
109
205
  const config2 = await getViteConfig(cwd, opts.config);
110
206
  await dev(cmd, config2, opts.port, opts.env);
111
207
  });
112
- prog.command("build [entry]").describe("Build the application (without serving it)").option("-o, --output", "Directory to write built files (default: 'build.outDir' in Vite config)").option("--skip-client", "Skip the client-side build").example("build --config vite.config.js").action(async (entry, opts) => {
208
+ prog.command("build [entry]").describe("Build the application (without serving it)").option(
209
+ "-o, --output",
210
+ "Directory to write built files (default: 'build.outDir' in Vite config)"
211
+ ).option("--skip-client", "Skip the client-side build").example("build --config vite.config.js").action(async (entry, opts) => {
113
212
  process.env.NODE_ENV = "production";
114
213
  const config2 = await getViteConfig(cwd, opts.config);
115
214
  await build(entry, config2, opts.ouput, opts["skip-client"], opts.env);
@@ -117,46 +216,48 @@ prog.command("build [entry]").describe("Build the application (without serving i
117
216
  prog.parse(process.argv);
118
217
  async function preview(entry, configFile, port, outDir, envFile) {
119
218
  const resolvedConfig = await resolveConfig(
120
- { root: cwd, configFile, build: { outDir } },
219
+ { root: cwd, configFile, logLevel: "silent", build: { outDir } },
121
220
  "serve"
122
221
  );
123
222
  if (port === void 0) {
124
223
  port = resolvedConfig.preview.port ?? defaultPort;
125
224
  }
126
- const adapter = await resolveAdapter(resolvedConfig);
225
+ const adapter = await resolveAdapter2(resolvedConfig);
127
226
  if (!adapter) {
128
227
  throw new Error("No adapter specified for 'serve' command");
129
228
  } else if (!adapter.startPreview) {
130
229
  throw new Error(`Adapter ${adapter.name} does not support 'serve' command`);
131
230
  }
132
- const dir = path.resolve(cwd, resolvedConfig.build.outDir);
133
- const entryFile = entry ? path.join(dir, entry) : await findFileWithExt(dir, "index", [".mjs", ".js"]);
231
+ const dir = path3.resolve(cwd, resolvedConfig.build.outDir);
232
+ const entryFile = entry ? path3.join(dir, entry) : await findFileWithExt(dir, "index", [".mjs", ".js"]);
134
233
  if (envFile) {
135
- envFile = path.resolve(cwd, envFile);
234
+ envFile = path3.resolve(cwd, envFile);
136
235
  }
137
236
  await adapter.startPreview(dir, entryFile, port, envFile);
138
237
  }
139
238
  async function dev(cmd, configFile, port, envFile) {
140
239
  const resolvedConfig = await resolveConfig(
141
- { root: cwd, configFile },
240
+ { root: cwd, configFile, logLevel: "silent" },
142
241
  "build"
143
242
  );
144
243
  if (port === void 0) {
145
244
  port = resolvedConfig.preview.port ?? defaultPort;
146
245
  }
147
246
  if (envFile) {
148
- envFile = path.resolve(cwd, envFile);
247
+ envFile = path3.resolve(cwd, envFile);
149
248
  }
150
249
  if (cmd) {
151
250
  await spawnServer(cmd, port, envFile);
152
251
  } else {
153
- const adapter = await resolveAdapter(resolvedConfig);
252
+ const adapter = await resolveAdapter2(resolvedConfig);
154
253
  if (!adapter) {
155
254
  throw new Error(
156
255
  "No adapter specified for 'dev' command without custom target"
157
256
  );
158
257
  } else if (!adapter.startDev) {
159
- throw new Error(`Adapter '${adapter.name}' does not support 'serve' command`);
258
+ throw new Error(
259
+ `Adapter '${adapter.name}' does not support 'serve' command`
260
+ );
160
261
  } else {
161
262
  await adapter.startDev(configFile, port, envFile);
162
263
  }
@@ -165,10 +266,10 @@ async function dev(cmd, configFile, port, envFile) {
165
266
  async function build(entry, configFile, outDir, skipClient = false, envFile) {
166
267
  var _a;
167
268
  const resolvedConfig = await resolveConfig(
168
- { root: cwd, configFile },
269
+ { root: cwd, configFile, logLevel: "silent" },
169
270
  "build"
170
271
  );
171
- const adapter = await resolveAdapter(resolvedConfig);
272
+ const adapter = await resolveAdapter2(resolvedConfig);
172
273
  if (!adapter) {
173
274
  throw new Error("No adapter specified for build command without entry");
174
275
  }
@@ -181,7 +282,7 @@ async function build(entry, configFile, outDir, skipClient = false, envFile) {
181
282
  }
182
283
  }
183
284
  if (envFile) {
184
- envFile = path.resolve(cwd, envFile);
285
+ envFile = path3.resolve(cwd, envFile);
185
286
  }
186
287
  let buildConfig = {
187
288
  root: cwd,
@@ -222,8 +323,8 @@ async function build(entry, configFile, outDir, skipClient = false, envFile) {
222
323
  }
223
324
  function findFileWithExt(dir, base, extensions = defaultConfigFileExts) {
224
325
  for (const ext of extensions) {
225
- const filePath = path.join(dir, base + ext);
226
- if (fs2.existsSync(filePath)) {
326
+ const filePath = path3.join(dir, base + ext);
327
+ if (fs4.existsSync(filePath)) {
227
328
  return filePath;
228
329
  }
229
330
  }
@@ -231,8 +332,8 @@ function findFileWithExt(dir, base, extensions = defaultConfigFileExts) {
231
332
  }
232
333
  async function getViteConfig(dir, configFile, bases = defaultConfigFileBases) {
233
334
  if (configFile) {
234
- const configFilePath = path.join(dir, configFile);
235
- if (!fs2.existsSync(configFilePath)) {
335
+ const configFilePath = path3.join(dir, configFile);
336
+ if (!fs4.existsSync(configFilePath)) {
236
337
  throw new Error(`No config file found at '${configFilePath}'`);
237
338
  }
238
339
  return configFile;
@@ -243,12 +344,12 @@ async function getViteConfig(dir, configFile, bases = defaultConfigFileBases) {
243
344
  return configFile;
244
345
  }
245
346
  }
246
- return path.join(__dirname, "default.config.mjs");
347
+ return path3.join(__dirname2, "default.config.mjs");
247
348
  }
248
- async function resolveAdapter(config2) {
349
+ async function resolveAdapter2(config2) {
249
350
  const options = getExternalPluginOptions(config2);
250
351
  if (!options) {
251
- throw new Error("Unable to resolve @marko/serve options");
352
+ throw new Error("Unable to resolve @marko/run options");
252
353
  }
253
- return options.adapter;
354
+ return resolveAdapter(config2.root, options);
254
355
  }
@@ -0,0 +1,122 @@
1
+ "use strict";
2
+
3
+ const markoUtils = require("@marko/babel-utils");
4
+ const attrTags = {
5
+ src: [
6
+ "audio",
7
+ "embed",
8
+ "iframe",
9
+ "img",
10
+ "input",
11
+ "script",
12
+ "source",
13
+ "track",
14
+ "video"
15
+ ],
16
+ href: ["a", "area", "link"],
17
+ data: ["object"],
18
+ poster: ["video"],
19
+ srcset: ["img"],
20
+ //something else needs to happen here
21
+ background: ["body"]
22
+ };
23
+ const tagAttrs = Object.keys(attrTags).reduce((tagAttrs, attrName) => {
24
+ attrTags[attrName].forEach(tagName => {
25
+ tagAttrs[tagName] = tagAttrs[tagName] || {};
26
+ tagAttrs[tagName][attrName] = true;
27
+ });
28
+ return tagAttrs;
29
+ }, {});
30
+
31
+ module.exports = function(a, b) {
32
+ if (a.hub) {
33
+ return transformMarko5(a, b);
34
+ }
35
+
36
+ return transformMarko4(a, b);
37
+ };
38
+
39
+ function transformMarko5(path) {
40
+ if (!path.get("name").isStringLiteral()) {
41
+ return;
42
+ }
43
+
44
+ const tagName = path.get("name.value").node;
45
+ const checkAttrs = tagAttrs[tagName];
46
+ if (!checkAttrs) {
47
+ return;
48
+ }
49
+
50
+ path.get("attributes").forEach(attr => {
51
+ if (!checkAttrs[attr.get("name").node]) {
52
+ return;
53
+ }
54
+
55
+ const { confident, value } = attr.get("value").evaluate();
56
+
57
+ if (!confident || !isAssetPath(value)) {
58
+ return;
59
+ }
60
+
61
+ attr.set("value", markoUtils.importDefault(path.hub.file, value, "asset"));
62
+ });
63
+ }
64
+
65
+ function transformMarko4(el, context) {
66
+ const checkAttrs = tagAttrs[el.tagName];
67
+ if (!checkAttrs) {
68
+ return;
69
+ }
70
+
71
+ el.attributes.forEach(attr => {
72
+ if (!checkAttrs[attr.name]) {
73
+ return;
74
+ }
75
+
76
+ const walker = context.createWalker({
77
+ enter: node => {
78
+ switch (node.type) {
79
+ case "ArrayExpression":
80
+ case "ObjectExpression":
81
+ case "Property":
82
+ case "LogicalExpression":
83
+ return;
84
+ case "ConditionalExpression":
85
+ node.consequent = walker.walk(node.consequent);
86
+ node.alternate = walker.walk(node.alternate);
87
+ walker.skip();
88
+ break;
89
+ case "Literal": {
90
+ const { value } = node;
91
+
92
+ if (!isAssetPath(value)) {
93
+ return;
94
+ }
95
+
96
+ context.assetCount = context.assetCount || 0;
97
+ const varName = `__src_asset_${context.assetCount++}__`;
98
+ const tagString = `import ${varName} from ${JSON.stringify(value)}`;
99
+ const importTag = context.createNodeForEl("import");
100
+ importTag.tagString = tagString;
101
+ context.root.prependChild(importTag);
102
+ walker.replace(context.builder.identifier(varName));
103
+ break;
104
+ }
105
+ default:
106
+ walker.skip();
107
+ break;
108
+ }
109
+ }
110
+ });
111
+
112
+ attr.value = walker.walk(attr.value);
113
+ });
114
+ }
115
+
116
+ function isAssetPath(relativePath) {
117
+ if (typeof relativePath !== "string") return false;
118
+ if (relativePath[0] === "/") return false; // Ignore absolute paths.
119
+ if (!/\.[^.]+$/.test(relativePath)) return false; // Ignore paths without a file extension.
120
+ if (/^[a-z]{2,}:/i.test(relativePath)) return false; // Ignore paths with a protocol.
121
+ return true;
122
+ }
@@ -1,12 +1,5 @@
1
1
  import type { HandlerLike, ParamsObject, Route as AnyRoute, Context as AnyContext } from "./types";
2
2
  declare global {
3
- namespace Marko {
4
- interface Global extends MarkoRun.Context {
5
- }
6
- interface Out {
7
- global: Global;
8
- }
9
- }
10
3
  namespace MarkoRun {
11
4
  const NotHandled: unique symbol;
12
5
  const NotMatched: unique symbol;
@@ -18,4 +11,4 @@ declare global {
18
11
  function route<Params extends ParamsObject = {}, Meta = unknown>(handler: Handler<Params, Meta>): typeof handler;
19
12
  }
20
13
  }
21
- export type { Fetch, HandlerLike, InputObject, Invoke, Match, NextFunction, PathTemplate, Route, Context, ContextExtensions, RouteHandler, RouteWithHandler, RuntimeModule, ValidateHref, ValidatePath, } from "./types";
14
+ export type { Context, ContextExtensions, Fetch, HandlerLike, InputObject, Invoke, Match, NextFunction, ParamsObject, PathTemplate, Route, RouteHandler, RouteWithHandler, RuntimeModule, ValidateHref, ValidatePath, } from "./types";
@@ -24,7 +24,7 @@ __export(internal_exports, {
24
24
  NotMatched: () => NotMatched,
25
25
  call: () => call,
26
26
  compose: () => compose,
27
- createInput: () => createInput,
27
+ createContext: () => createContext,
28
28
  noContent: () => noContent,
29
29
  normalize: () => normalize,
30
30
  notHandled: () => notHandled,
@@ -48,14 +48,35 @@ globalThis.MarkoRun ?? (globalThis.MarkoRun = {
48
48
  return handler;
49
49
  }
50
50
  });
51
- function createInput(context) {
52
- let existing;
53
- return (data) => {
54
- existing ?? (existing = {
55
- $global: context
56
- });
57
- return data ? Object.assign(existing, data) : existing;
51
+ var serializedGlobals = { params: true, url: true };
52
+ function createContext(route, request, platform, url = new URL(request.url)) {
53
+ const context = route ? {
54
+ request,
55
+ url,
56
+ platform,
57
+ meta: route.meta,
58
+ params: route.params,
59
+ route: route.path,
60
+ serializedGlobals
61
+ } : {
62
+ request,
63
+ url,
64
+ platform,
65
+ meta: {},
66
+ params: {},
67
+ route: "",
68
+ serializedGlobals
58
69
  };
70
+ let input;
71
+ return [
72
+ context,
73
+ (data) => {
74
+ input ?? (input = {
75
+ $global: context
76
+ });
77
+ return data ? Object.assign(input, data) : input;
78
+ }
79
+ ];
59
80
  }
60
81
  async function call(handler, next, context) {
61
82
  let response;
@@ -151,7 +172,7 @@ function notMatched() {
151
172
  NotMatched,
152
173
  call,
153
174
  compose,
154
- createInput,
175
+ createContext,
155
176
  noContent,
156
177
  normalize,
157
178
  notHandled,
@@ -2,7 +2,7 @@ import type { InputObject, NextFunction, Route, Context, RouteHandler } from "./
2
2
  export declare function pageResponse(template: any, input: Record<PropertyKey, unknown>): Response;
3
3
  export declare const NotHandled: typeof MarkoRun.NotHandled;
4
4
  export declare const NotMatched: typeof MarkoRun.NotMatched;
5
- export declare function createInput(context: Context): (data: InputObject) => InputObject;
5
+ export declare function createContext<Platform, TRoute extends Route>(route: TRoute | undefined, request: Request, platform: Platform, url?: URL): [Context, (data?: InputObject) => InputObject];
6
6
  export declare function call(handler: RouteHandler<Route>, next: NextFunction, context: Context): Promise<Response>;
7
7
  export declare function compose(handlers: RouteHandler[]): RouteHandler;
8
8
  export declare function normalize(obj: RouteHandler | RouteHandler[] | Promise<RouteHandler | RouteHandler[]>): RouteHandler;
@@ -15,14 +15,35 @@ globalThis.MarkoRun ?? (globalThis.MarkoRun = {
15
15
  return handler;
16
16
  }
17
17
  });
18
- function createInput(context) {
19
- let existing;
20
- return (data) => {
21
- existing ?? (existing = {
22
- $global: context
23
- });
24
- return data ? Object.assign(existing, data) : existing;
18
+ var serializedGlobals = { params: true, url: true };
19
+ function createContext(route, request, platform, url = new URL(request.url)) {
20
+ const context = route ? {
21
+ request,
22
+ url,
23
+ platform,
24
+ meta: route.meta,
25
+ params: route.params,
26
+ route: route.path,
27
+ serializedGlobals
28
+ } : {
29
+ request,
30
+ url,
31
+ platform,
32
+ meta: {},
33
+ params: {},
34
+ route: "",
35
+ serializedGlobals
25
36
  };
37
+ let input;
38
+ return [
39
+ context,
40
+ (data) => {
41
+ input ?? (input = {
42
+ $global: context
43
+ });
44
+ return data ? Object.assign(input, data) : input;
45
+ }
46
+ ];
26
47
  }
27
48
  async function call(handler, next, context) {
28
49
  let response;
@@ -117,7 +138,7 @@ export {
117
138
  NotMatched,
118
139
  call,
119
140
  compose,
120
- createInput,
141
+ createContext,
121
142
  noContent,
122
143
  normalize,
123
144
  notHandled,
@@ -1,23 +1,21 @@
1
- declare type Awaitable<T> = Promise<T> | T;
2
- declare type OneOrMany<T> = T | T[];
3
- declare type Combine<T> = T extends object ? {
4
- [P in keyof T]: T[P];
5
- } : T;
1
+ type Awaitable<T> = Promise<T> | T;
2
+ type OneOrMany<T> = T | T[];
6
3
  export interface ContextExtensions {
7
4
  }
8
- export declare type ParamsObject = Record<string, string>;
9
- export declare type InputObject = Record<PropertyKey, any>;
10
- export declare type Context<Platform = unknown, TRoute extends Route = Route> = TRoute extends any ? Combine<ContextExtensions & Readonly<{
11
- url: URL;
12
- request: Request;
13
- route: TRoute["path"];
14
- params: TRoute["params"];
15
- meta: TRoute["meta"];
16
- platform: Platform;
17
- }>> : never;
18
- export declare type NextFunction = () => Awaitable<Response>;
19
- export declare type HandlerLike<TRoute extends Route = Route> = Awaitable<OneOrMany<RouteHandler<TRoute>>>;
20
- export declare type RouteHandler<TRoute extends Route = Route> = (context: Context<unknown, TRoute>, next: NextFunction) => Awaitable<Response | null | void>;
5
+ export type Context<Platform = unknown, TRoute extends Route = Route> = ContextExtensions & {
6
+ readonly url: URL;
7
+ readonly request: Request;
8
+ readonly route: TRoute["path"];
9
+ readonly params: TRoute["params"];
10
+ readonly meta: TRoute["meta"];
11
+ readonly platform: Platform;
12
+ readonly serializedGlobals: Record<string, boolean>;
13
+ };
14
+ export type ParamsObject = Record<string, string>;
15
+ export type InputObject = Record<PropertyKey, any>;
16
+ export type NextFunction = () => Awaitable<Response>;
17
+ export type HandlerLike<TRoute extends Route = Route> = Awaitable<OneOrMany<RouteHandler<TRoute>>>;
18
+ export type RouteHandler<TRoute extends Route = Route> = (context: Context<unknown, TRoute>, next: NextFunction) => Awaitable<Response | null | void>;
21
19
  export interface Route<Params extends ParamsObject = {}, Meta = unknown, Path extends string = string> {
22
20
  path: Path;
23
21
  params: Params;
@@ -26,20 +24,20 @@ export interface Route<Params extends ParamsObject = {}, Meta = unknown, Path ex
26
24
  export interface RouteWithHandler<Params extends ParamsObject = {}, Meta = unknown, Path extends string = string> extends Route<Params, Meta, Path> {
27
25
  handler: RouteHandler<this>;
28
26
  }
29
- export declare type Fetch<Platform = unknown> = (request: Request, platform: Platform) => Promise<Response | void>;
30
- export declare type Match = (method: string, pathname: string) => RouteWithHandler | null;
31
- export declare type Invoke = <Platform = unknown>(route: RouteWithHandler | null, request: Request, platform: Platform) => Promise<Response | void>;
27
+ export type Fetch<Platform = unknown> = (request: Request, platform: Platform) => Promise<Response | void>;
28
+ export type Match = (method: string, pathname: string) => RouteWithHandler | null;
29
+ export type Invoke = <Platform = unknown>(route: RouteWithHandler | null, request: Request, platform: Platform) => Promise<Response | void>;
32
30
  export interface RuntimeModule {
33
31
  fetch: <Platform = unknown>(request: Request, platform: Platform) => Promise<Response | void>;
34
32
  match: (method: string, pathname: string) => RouteWithHandler | null;
35
33
  invoke: <Platform = unknown>(route: RouteWithHandler | null, request: Request, platform: Platform) => Promise<Response | void>;
36
34
  }
37
- declare type Member<T, U> = T extends T ? (U extends T ? T : never) : never;
38
- declare type Segments<T extends string, Acc extends string[] = []> = T extends "" ? Acc : T extends `${infer Left}/${infer Rest}` ? Segments<Rest, [...Acc, Left]> : [...Acc, T];
39
- declare type GTE<A extends any[], B extends any[]> = A["length"] extends B["length"] ? 1 : A extends [infer _Ha, ...infer Ta] ? B extends [infer _Hb, ...infer Tb] ? GTE<Ta, Tb> : 1 : 0;
40
- declare type MatchSegments<A extends string, B extends string> = A extends `${infer P}/${string}*` ? 1 extends GTE<Segments<B>, Segments<P>> ? `${P}/${string}` : never : Segments<B>["length"] extends Segments<A>["length"] ? A : never;
41
- declare 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;
42
- export declare type PathTemplate<Path extends string> = Path extends `${infer Left}/\${${string}}/${infer Rest}` ? PathTemplate<`${Left}/${string}/${Rest}`> : Path extends `${infer Left}/\${${string}}` ? PathTemplate<`${Left}/${string}`> : Path;
43
- export declare type ValidatePath<Paths extends string, Path extends string> = Paths | (Path extends `/${string}` ? MatchSegments<Member<PathPattern<Paths>, Path>, Path> : Path);
44
- export declare 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>;
35
+ type Member<T, U> = T extends T ? (U extends T ? T : never) : never;
36
+ type Segments<T extends string, Acc extends string[] = []> = T extends "" ? Acc : T extends `${infer Left}/${infer Rest}` ? Segments<Rest, [...Acc, Left]> : [...Acc, T];
37
+ type GTE<A extends any[], B extends any[]> = A["length"] extends B["length"] ? 1 : A extends [infer _Ha, ...infer Ta] ? B extends [infer _Hb, ...infer Tb] ? GTE<Ta, Tb> : 1 : 0;
38
+ type MatchSegments<A extends string, B extends string> = A extends `${infer P}/${string}*` ? 1 extends GTE<Segments<B>, Segments<P>> ? `${P}/${string}` : never : Segments<B>["length"] extends Segments<A>["length"] ? A : never;
39
+ 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;
40
+ export type PathTemplate<Path extends string> = Path extends `${infer Left}/\${${string}}/${infer Rest}` ? PathTemplate<`${Left}/${string}/${Rest}`> : Path extends `${infer Left}/\${${string}}` ? PathTemplate<`${Left}/${string}`> : Path;
41
+ export type ValidatePath<Paths extends string, Path extends string> = Paths | (Path extends `/${string}` ? MatchSegments<Member<PathPattern<Paths>, Path>, Path> : Path);
42
+ export 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>;
45
43
  export {};
@@ -1,6 +1,6 @@
1
- import type { Route, BuiltRoutes, RoutableFile, RouterOptions } from "../types";
1
+ import type { Adapter, Route, BuiltRoutes, RoutableFile, RouterOptions } from "../types";
2
2
  export declare function renderRouteTemplate(route: Route): string;
3
3
  export declare function renderRouteEntry(route: Route): string;
4
4
  export declare function renderRouter(routes: BuiltRoutes, options?: RouterOptions): string;
5
5
  export declare function renderMiddleware(middleware: RoutableFile[]): string;
6
- export declare function renderRouteTypeInfo(routes: BuiltRoutes, pathPrefix?: string, adapterTypes?: string): string;
6
+ export declare function renderRouteTypeInfo(routes: BuiltRoutes, pathPrefix?: string, adapter?: Adapter | null): Promise<string>;