@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.
- package/dist/adapter/index.cjs +2 -1
- package/dist/adapter/index.js +2 -1
- package/dist/adapter/middleware.d.ts +1 -1
- package/dist/cli/default.config.mjs +1 -2
- package/dist/cli/index.mjs +129 -28
- package/dist/components/src-attributes-transformer.cjs +122 -0
- package/dist/runtime/index.d.ts +1 -8
- package/dist/runtime/internal.cjs +30 -9
- package/dist/runtime/internal.d.ts +1 -1
- package/dist/runtime/internal.js +29 -8
- package/dist/runtime/types.d.ts +27 -29
- package/dist/vite/codegen/index.d.ts +2 -2
- package/dist/vite/constants.d.ts +3 -3
- package/dist/vite/index.cjs +188 -115
- package/dist/vite/index.js +189 -116
- package/dist/vite/plugin.d.ts +3 -2
- package/dist/vite/routes/walk.d.ts +2 -2
- package/dist/vite/types.d.ts +4 -4
- package/dist/vite/utils/route.d.ts +1 -1
- package/package.json +5 -4
- package/dist/.tsbuildinfo +0 -1
package/dist/adapter/index.cjs
CHANGED
|
@@ -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
|
}
|
package/dist/adapter/index.js
CHANGED
|
@@ -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
|
|
23
|
+
export type NodeMiddleware = (req: IncomingMessage, res: ServerResponse & {
|
|
24
24
|
flush?: () => void;
|
|
25
25
|
}, next?: () => void) => void;
|
|
26
26
|
/** Adapter options */
|
package/dist/cli/index.mjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// src/cli/index.ts
|
|
4
|
-
import
|
|
5
|
-
import
|
|
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/
|
|
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(
|
|
101
|
-
|
|
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(
|
|
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(
|
|
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
|
|
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 =
|
|
133
|
-
const entryFile = entry ?
|
|
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 =
|
|
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 =
|
|
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
|
|
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(
|
|
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
|
|
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 =
|
|
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 =
|
|
226
|
-
if (
|
|
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 =
|
|
235
|
-
if (!
|
|
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
|
|
347
|
+
return path3.join(__dirname2, "default.config.mjs");
|
|
247
348
|
}
|
|
248
|
-
async function
|
|
349
|
+
async function resolveAdapter2(config2) {
|
|
249
350
|
const options = getExternalPluginOptions(config2);
|
|
250
351
|
if (!options) {
|
|
251
|
-
throw new Error("Unable to resolve @marko/
|
|
352
|
+
throw new Error("Unable to resolve @marko/run options");
|
|
252
353
|
}
|
|
253
|
-
return options
|
|
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
|
+
}
|
package/dist/runtime/index.d.ts
CHANGED
|
@@ -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,
|
|
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
|
-
|
|
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
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
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
|
-
|
|
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
|
|
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;
|
package/dist/runtime/internal.js
CHANGED
|
@@ -15,14 +15,35 @@ globalThis.MarkoRun ?? (globalThis.MarkoRun = {
|
|
|
15
15
|
return handler;
|
|
16
16
|
}
|
|
17
17
|
});
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
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
|
-
|
|
141
|
+
createContext,
|
|
121
142
|
noContent,
|
|
122
143
|
normalize,
|
|
123
144
|
notHandled,
|
package/dist/runtime/types.d.ts
CHANGED
|
@@ -1,23 +1,21 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
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
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
export
|
|
19
|
-
export
|
|
20
|
-
export
|
|
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
|
|
30
|
-
export
|
|
31
|
-
export
|
|
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
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
export
|
|
43
|
-
export
|
|
44
|
-
export
|
|
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,
|
|
6
|
+
export declare function renderRouteTypeInfo(routes: BuiltRoutes, pathPrefix?: string, adapter?: Adapter | null): Promise<string>;
|