@marko/run 0.0.1-beta2 → 0.0.1-beta4
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/README.md +102 -74
- package/dist/adapter/default-entry.mjs +9 -3
- package/dist/adapter/dev-server.d.ts +1 -1
- package/dist/adapter/index.cjs +189 -8
- package/dist/adapter/index.d.ts +1 -0
- package/dist/adapter/index.js +188 -7
- package/dist/adapter/middleware.cjs +199 -0
- package/dist/adapter/middleware.d.ts +55 -0
- package/dist/adapter/middleware.js +168 -0
- package/dist/cli/default.config.mjs +1 -1
- package/dist/cli/index.mjs +88 -59
- package/dist/runtime/index.cjs +0 -16
- package/dist/runtime/index.d.ts +10 -2
- package/dist/runtime/index.js +0 -7
- package/dist/runtime/internal.cjs +148 -0
- package/dist/runtime/internal.d.ts +10 -0
- package/dist/runtime/internal.js +115 -0
- package/dist/runtime/router.cjs +9 -7
- package/dist/runtime/router.d.ts +4 -4
- package/dist/runtime/router.js +7 -5
- package/dist/runtime/types.d.ts +29 -16
- package/dist/vite/codegen/index.d.ts +4 -3
- package/dist/vite/codegen/writer.d.ts +1 -1
- package/dist/vite/constants.d.ts +3 -2
- package/dist/vite/index.cjs +557 -282
- package/dist/vite/index.d.ts +4 -3
- package/dist/vite/index.js +554 -282
- package/dist/vite/types.d.ts +14 -7
- package/dist/vite/utils/config.d.ts +5 -3
- package/dist/vite/utils/server.d.ts +3 -1
- package/package.json +23 -11
package/dist/cli/index.mjs
CHANGED
|
@@ -2,20 +2,24 @@
|
|
|
2
2
|
|
|
3
3
|
// src/cli/index.ts
|
|
4
4
|
import path from "path";
|
|
5
|
-
import
|
|
5
|
+
import fs2 from "fs";
|
|
6
6
|
import { fileURLToPath } from "url";
|
|
7
7
|
import { build as viteBuild, resolveConfig } from "vite";
|
|
8
8
|
import sade from "sade";
|
|
9
9
|
|
|
10
10
|
// src/vite/utils/config.ts
|
|
11
|
-
var
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
var PluginConfigKey = "__MARKO_RUN_PLUGIN_CONFIG__";
|
|
12
|
+
var AdapterConfigKey = "__MARKO_RUN_ADAPTER_CONFIG__";
|
|
13
|
+
function getConfig(obj, key) {
|
|
14
|
+
return obj[key];
|
|
14
15
|
}
|
|
15
|
-
function
|
|
16
|
-
|
|
17
|
-
return
|
|
16
|
+
function setConfig(obj, key, value) {
|
|
17
|
+
obj[key] = value;
|
|
18
|
+
return obj;
|
|
18
19
|
}
|
|
20
|
+
var getExternalPluginOptions = (viteConfig) => getConfig(viteConfig, PluginConfigKey);
|
|
21
|
+
var setExternalPluginOptions = (viteConfig, value) => setConfig(viteConfig, PluginConfigKey, value);
|
|
22
|
+
var setExternalAdapterOptions = (viteConfig, value) => setConfig(viteConfig, AdapterConfigKey, value);
|
|
19
23
|
|
|
20
24
|
// src/cli/index.ts
|
|
21
25
|
import { MemoryStore } from "@marko/vite";
|
|
@@ -23,16 +27,27 @@ import { MemoryStore } from "@marko/vite";
|
|
|
23
27
|
// src/vite/utils/server.ts
|
|
24
28
|
import net from "net";
|
|
25
29
|
import cp from "child_process";
|
|
26
|
-
|
|
30
|
+
import { parse, config } from "dotenv";
|
|
31
|
+
import fs from "fs";
|
|
32
|
+
async function parseEnv(envFile) {
|
|
33
|
+
if (fs.existsSync(envFile)) {
|
|
34
|
+
const content = await fs.promises.readFile(envFile, "utf8");
|
|
35
|
+
return parse(content);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
async function spawnServer(cmd, port = 0, env, cwd2 = process.cwd(), wait = 3e4) {
|
|
27
39
|
if (port <= 0) {
|
|
28
40
|
port = await getAvailablePort();
|
|
29
41
|
}
|
|
42
|
+
if (typeof env === "string") {
|
|
43
|
+
env = await parseEnv(env);
|
|
44
|
+
}
|
|
30
45
|
const proc = cp.spawn(cmd, {
|
|
31
46
|
cwd: cwd2,
|
|
32
47
|
shell: true,
|
|
33
48
|
stdio: "inherit",
|
|
34
49
|
windowsHide: true,
|
|
35
|
-
env: { NODE_ENV: "development", ...process.env, PORT: `${port}` }
|
|
50
|
+
env: { ...env, NODE_ENV: "development", ...process.env, PORT: `${port}` }
|
|
36
51
|
});
|
|
37
52
|
const close = () => {
|
|
38
53
|
proc.unref();
|
|
@@ -80,23 +95,25 @@ function sleep(ms) {
|
|
|
80
95
|
var __dirname = fileURLToPath(new URL(".", import.meta.url));
|
|
81
96
|
var cwd = process.cwd();
|
|
82
97
|
var defaultPort = +process.env.PORT || 3e3;
|
|
83
|
-
var
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
await
|
|
98
|
+
var defaultConfigFileBases = ["serve.config", "vite.config"];
|
|
99
|
+
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("serve [entry]", "", { default: true }).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) => {
|
|
102
|
+
const config2 = await getViteConfig(cwd, opts.config);
|
|
103
|
+
await build(entry, config2, opts.output, false, opts.env);
|
|
104
|
+
await preview(opts.entry, config2, opts.port, opts.output, opts.env);
|
|
88
105
|
});
|
|
89
|
-
prog.command("dev [entry]").describe("Start
|
|
106
|
+
prog.command("dev [entry]").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) => {
|
|
90
107
|
const cmd = opts._.length ? `${entry} ${opts._.join(" ")}` : entry ? `node ${entry}` : void 0;
|
|
91
|
-
const
|
|
92
|
-
await dev(cmd,
|
|
108
|
+
const config2 = await getViteConfig(cwd, opts.config);
|
|
109
|
+
await dev(cmd, config2, opts.port, opts.env);
|
|
93
110
|
});
|
|
94
|
-
prog.command("build [entry]").describe("Build the application").option("-o, --output", "Directory to
|
|
95
|
-
const
|
|
96
|
-
await build(entry,
|
|
111
|
+
prog.command("build [entry]").describe("Build the application (without serving it)").option("-o, --output", "Directory to write built files (default: )").option("--skip-client", "Skip the client-side build").example("build --config vite.config.js").action(async (entry, opts) => {
|
|
112
|
+
const config2 = await getViteConfig(cwd, opts.config);
|
|
113
|
+
await build(entry, config2, opts.ouput, opts["skip-client"], opts.env);
|
|
97
114
|
});
|
|
98
115
|
prog.parse(process.argv);
|
|
99
|
-
async function preview(entry, configFile, port, outDir) {
|
|
116
|
+
async function preview(entry, configFile, port, outDir, envFile) {
|
|
100
117
|
const resolvedConfig = await resolveConfig(
|
|
101
118
|
{ root: cwd, configFile, build: { outDir } },
|
|
102
119
|
"serve"
|
|
@@ -106,15 +123,18 @@ async function preview(entry, configFile, port, outDir) {
|
|
|
106
123
|
}
|
|
107
124
|
const adapter = await resolveAdapter(resolvedConfig);
|
|
108
125
|
if (!adapter) {
|
|
109
|
-
throw new Error("No adapter specified for serve command");
|
|
126
|
+
throw new Error("No adapter specified for 'serve' command");
|
|
110
127
|
} else if (!adapter.startPreview) {
|
|
111
|
-
throw new Error(`Adapter ${adapter.name} does not support serve command`);
|
|
128
|
+
throw new Error(`Adapter ${adapter.name} does not support 'serve' command`);
|
|
112
129
|
}
|
|
113
130
|
const dir = path.resolve(cwd, resolvedConfig.build.outDir);
|
|
114
131
|
const entryFile = entry ? path.join(dir, entry) : await findFileWithExt(dir, "index", [".mjs", ".js"]);
|
|
115
|
-
|
|
132
|
+
if (envFile) {
|
|
133
|
+
envFile = path.resolve(cwd, envFile);
|
|
134
|
+
}
|
|
135
|
+
await adapter.startPreview(dir, entryFile, port, envFile);
|
|
116
136
|
}
|
|
117
|
-
async function dev(cmd, configFile, port) {
|
|
137
|
+
async function dev(cmd, configFile, port, envFile) {
|
|
118
138
|
const resolvedConfig = await resolveConfig(
|
|
119
139
|
{ root: cwd, configFile },
|
|
120
140
|
"build"
|
|
@@ -122,55 +142,63 @@ async function dev(cmd, configFile, port) {
|
|
|
122
142
|
if (port === void 0) {
|
|
123
143
|
port = resolvedConfig.preview.port ?? defaultPort;
|
|
124
144
|
}
|
|
145
|
+
if (envFile) {
|
|
146
|
+
envFile = path.resolve(cwd, envFile);
|
|
147
|
+
}
|
|
125
148
|
if (cmd) {
|
|
126
|
-
await spawnServer(cmd, port);
|
|
149
|
+
await spawnServer(cmd, port, envFile);
|
|
127
150
|
} else {
|
|
128
151
|
const adapter = await resolveAdapter(resolvedConfig);
|
|
129
152
|
if (!adapter) {
|
|
130
153
|
throw new Error(
|
|
131
|
-
"No adapter specified for dev command without custom target"
|
|
154
|
+
"No adapter specified for 'dev' command without custom target"
|
|
132
155
|
);
|
|
133
156
|
} else if (!adapter.startDev) {
|
|
134
|
-
throw new Error(`Adapter ${adapter.name} does not support serve command`);
|
|
157
|
+
throw new Error(`Adapter '${adapter.name}' does not support 'serve' command`);
|
|
135
158
|
} else {
|
|
136
|
-
await adapter.startDev(configFile, port);
|
|
159
|
+
await adapter.startDev(configFile, port, envFile);
|
|
137
160
|
}
|
|
138
161
|
}
|
|
139
162
|
}
|
|
140
|
-
async function build(entry, configFile, outDir, skipClient = false) {
|
|
163
|
+
async function build(entry, configFile, outDir, skipClient = false, envFile) {
|
|
141
164
|
var _a;
|
|
165
|
+
const resolvedConfig = await resolveConfig(
|
|
166
|
+
{ root: cwd, configFile },
|
|
167
|
+
"build"
|
|
168
|
+
);
|
|
169
|
+
const adapter = await resolveAdapter(resolvedConfig);
|
|
170
|
+
if (!adapter) {
|
|
171
|
+
throw new Error("No adapter specified for build command without entry");
|
|
172
|
+
}
|
|
142
173
|
if (!entry) {
|
|
143
|
-
const resolvedConfig = await resolveConfig(
|
|
144
|
-
{ root: cwd, configFile },
|
|
145
|
-
"build"
|
|
146
|
-
);
|
|
147
|
-
const adapter = await resolveAdapter(resolvedConfig);
|
|
148
|
-
if (!adapter) {
|
|
149
|
-
throw new Error("No adapter specified for build command without entry");
|
|
150
|
-
}
|
|
151
174
|
entry = await ((_a = adapter.getEntryFile) == null ? void 0 : _a.call(adapter));
|
|
152
175
|
if (!entry) {
|
|
153
176
|
throw new Error(
|
|
154
|
-
`Adapter ${adapter.name} does not support
|
|
177
|
+
`Adapter '${adapter.name}' does not support building without an entry`
|
|
155
178
|
);
|
|
156
179
|
}
|
|
157
180
|
}
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
{
|
|
168
|
-
store: new MemoryStore()
|
|
181
|
+
if (envFile) {
|
|
182
|
+
envFile = path.resolve(cwd, envFile);
|
|
183
|
+
}
|
|
184
|
+
let buildConfig = {
|
|
185
|
+
root: cwd,
|
|
186
|
+
configFile,
|
|
187
|
+
build: {
|
|
188
|
+
ssr: false,
|
|
189
|
+
outDir
|
|
169
190
|
}
|
|
170
|
-
|
|
191
|
+
};
|
|
192
|
+
buildConfig = setExternalPluginOptions(buildConfig, {
|
|
193
|
+
store: new MemoryStore()
|
|
194
|
+
});
|
|
195
|
+
buildConfig = setExternalAdapterOptions(buildConfig, {
|
|
196
|
+
envFile
|
|
197
|
+
});
|
|
171
198
|
await viteBuild({
|
|
172
199
|
...buildConfig,
|
|
173
200
|
build: {
|
|
201
|
+
target: "esnext",
|
|
174
202
|
...buildConfig.build,
|
|
175
203
|
ssr: entry,
|
|
176
204
|
rollupOptions: {
|
|
@@ -190,19 +218,20 @@ async function build(entry, configFile, outDir, skipClient = false) {
|
|
|
190
218
|
});
|
|
191
219
|
}
|
|
192
220
|
}
|
|
193
|
-
function findFileWithExt(dir, base, extensions =
|
|
221
|
+
function findFileWithExt(dir, base, extensions = defaultConfigFileExts) {
|
|
194
222
|
for (const ext of extensions) {
|
|
195
223
|
const filePath = path.join(dir, base + ext);
|
|
196
|
-
if (
|
|
224
|
+
if (fs2.existsSync(filePath)) {
|
|
197
225
|
return filePath;
|
|
198
226
|
}
|
|
199
227
|
}
|
|
200
228
|
return void 0;
|
|
201
229
|
}
|
|
202
|
-
async function getViteConfig(dir, configFile, bases =
|
|
230
|
+
async function getViteConfig(dir, configFile, bases = defaultConfigFileBases) {
|
|
203
231
|
if (configFile) {
|
|
204
|
-
|
|
205
|
-
|
|
232
|
+
const configFilePath = path.join(dir, configFile);
|
|
233
|
+
if (!fs2.existsSync(configFilePath)) {
|
|
234
|
+
throw new Error(`No config file found at '${configFilePath}'`);
|
|
206
235
|
}
|
|
207
236
|
return configFile;
|
|
208
237
|
}
|
|
@@ -214,10 +243,10 @@ async function getViteConfig(dir, configFile, bases = ["serve.config", "vite.con
|
|
|
214
243
|
}
|
|
215
244
|
return path.join(__dirname, "default.config.mjs");
|
|
216
245
|
}
|
|
217
|
-
async function resolveAdapter(
|
|
218
|
-
const options =
|
|
246
|
+
async function resolveAdapter(config2) {
|
|
247
|
+
const options = getExternalPluginOptions(config2);
|
|
219
248
|
if (!options) {
|
|
220
|
-
throw new Error("Unable to resolve
|
|
249
|
+
throw new Error("Unable to resolve @marko/serve options");
|
|
221
250
|
}
|
|
222
251
|
return options.adapter;
|
|
223
252
|
}
|
package/dist/runtime/index.cjs
CHANGED
|
@@ -3,10 +3,6 @@ var __defProp = Object.defineProperty;
|
|
|
3
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
5
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
-
var __export = (target, all) => {
|
|
7
|
-
for (var name in all)
|
|
8
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
-
};
|
|
10
6
|
var __copyProps = (to, from, except, desc) => {
|
|
11
7
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
8
|
for (let key of __getOwnPropNames(from))
|
|
@@ -19,16 +15,4 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
19
15
|
|
|
20
16
|
// src/runtime/index.ts
|
|
21
17
|
var runtime_exports = {};
|
|
22
|
-
__export(runtime_exports, {
|
|
23
|
-
getMatchedRoute: () => import_router.getMatchedRoute,
|
|
24
|
-
handler: () => import_router.handler,
|
|
25
|
-
router: () => import_router.router
|
|
26
|
-
});
|
|
27
18
|
module.exports = __toCommonJS(runtime_exports);
|
|
28
|
-
var import_router = require("@marko/run/router");
|
|
29
|
-
// Annotate the CommonJS export names for ESM import in node:
|
|
30
|
-
0 && (module.exports = {
|
|
31
|
-
getMatchedRoute,
|
|
32
|
-
handler,
|
|
33
|
-
router
|
|
34
|
-
});
|
package/dist/runtime/index.d.ts
CHANGED
|
@@ -1,2 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import type { HandlerLike, ParamsObject, Route } from "./types";
|
|
2
|
+
declare global {
|
|
3
|
+
namespace Marko {
|
|
4
|
+
interface CurrentRoute extends Route {
|
|
5
|
+
}
|
|
6
|
+
type Handler<Params extends ParamsObject = {}, Meta = unknown> = HandlerLike<Route<Params, Meta, string>>;
|
|
7
|
+
function route<Params extends ParamsObject = {}, Meta = unknown>(handler: Handler<Params, Meta>): typeof handler;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
export type { HandlerLike, InputObject, InvokeRoute, MatchRoute, NextFunction, RequestContext, Route, RouteContext, RouteContextExtensions, RouteHandler, RouteWithHandler, Router, } from "./types";
|
package/dist/runtime/index.js
CHANGED
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/runtime/internal.ts
|
|
21
|
+
var internal_exports = {};
|
|
22
|
+
__export(internal_exports, {
|
|
23
|
+
RequestNotHandled: () => RequestNotHandled,
|
|
24
|
+
RequestNotMatched: () => RequestNotMatched,
|
|
25
|
+
call: () => call,
|
|
26
|
+
compose: () => compose,
|
|
27
|
+
createInput: () => createInput,
|
|
28
|
+
noContent: () => noContent,
|
|
29
|
+
normalize: () => normalize,
|
|
30
|
+
notHandled: () => notHandled,
|
|
31
|
+
notMatched: () => notMatched
|
|
32
|
+
});
|
|
33
|
+
module.exports = __toCommonJS(internal_exports);
|
|
34
|
+
globalThis.Marko ?? (globalThis.Marko = {});
|
|
35
|
+
globalThis.Marko.route = (handler) => handler;
|
|
36
|
+
var RequestNotHandled = Symbol();
|
|
37
|
+
var RequestNotMatched = Symbol();
|
|
38
|
+
function createInput(context) {
|
|
39
|
+
let existing;
|
|
40
|
+
return (data) => {
|
|
41
|
+
existing ?? (existing = {
|
|
42
|
+
$global: {
|
|
43
|
+
context
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
return data ? Object.assign(existing, data) : existing;
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
async function call(handler, next, context) {
|
|
50
|
+
let response;
|
|
51
|
+
if (process.env.NODE_ENV !== "production") {
|
|
52
|
+
let nextCallCount = 0;
|
|
53
|
+
let didThrow = false;
|
|
54
|
+
try {
|
|
55
|
+
response = await handler(context, () => {
|
|
56
|
+
nextCallCount++;
|
|
57
|
+
return next();
|
|
58
|
+
});
|
|
59
|
+
} catch (error) {
|
|
60
|
+
didThrow = true;
|
|
61
|
+
if (error instanceof Response) {
|
|
62
|
+
return error;
|
|
63
|
+
}
|
|
64
|
+
throw error;
|
|
65
|
+
} finally {
|
|
66
|
+
if (!response && !didThrow && nextCallCount > 0) {
|
|
67
|
+
console.warn(
|
|
68
|
+
`Handler '${handler.name}' called its next function but no response was returned. This will cause the next function to be called again which is wasteful. Either return or throw the result of calling \`next\`, return or throw a new Response object or finally \`throw null\` to skip handling the request`
|
|
69
|
+
);
|
|
70
|
+
} else if (nextCallCount > 1) {
|
|
71
|
+
console.warn(
|
|
72
|
+
`Handler '${handler.name}' called its next function more than once. Make sure this is intentional because it is inefficient.`
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
} else {
|
|
77
|
+
try {
|
|
78
|
+
response = await handler(context, next);
|
|
79
|
+
} catch (error) {
|
|
80
|
+
if (error == null) {
|
|
81
|
+
throw RequestNotHandled;
|
|
82
|
+
} else if (error instanceof Response) {
|
|
83
|
+
return error;
|
|
84
|
+
}
|
|
85
|
+
throw error;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
if (response === null) {
|
|
89
|
+
throw RequestNotMatched;
|
|
90
|
+
}
|
|
91
|
+
return response || next();
|
|
92
|
+
}
|
|
93
|
+
function compose(handlers) {
|
|
94
|
+
const len = handlers.length;
|
|
95
|
+
if (!len) {
|
|
96
|
+
return (_context, next) => next();
|
|
97
|
+
} else if (len === 1) {
|
|
98
|
+
return handlers[0];
|
|
99
|
+
}
|
|
100
|
+
return (context, next) => {
|
|
101
|
+
let i = 0;
|
|
102
|
+
return function nextHandler() {
|
|
103
|
+
return i < len ? call(handlers[i++], nextHandler, context) : next();
|
|
104
|
+
}();
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
function normalize(obj) {
|
|
108
|
+
if (typeof obj === "function") {
|
|
109
|
+
return obj;
|
|
110
|
+
} else if (Array.isArray(obj)) {
|
|
111
|
+
return compose(obj);
|
|
112
|
+
} else if (obj instanceof Promise) {
|
|
113
|
+
const promise = obj.then((value) => {
|
|
114
|
+
fn = Array.isArray(value) ? compose(value) : value;
|
|
115
|
+
});
|
|
116
|
+
let fn = async (context, next) => {
|
|
117
|
+
await promise;
|
|
118
|
+
return fn(context, next);
|
|
119
|
+
};
|
|
120
|
+
return (context, next) => fn(context, next);
|
|
121
|
+
}
|
|
122
|
+
throw new Error(
|
|
123
|
+
`Invalid handler - expected function, array or Promise but received ${obj}`
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
function noContent() {
|
|
127
|
+
return new Response(null, {
|
|
128
|
+
status: 204
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
function notHandled() {
|
|
132
|
+
throw null;
|
|
133
|
+
}
|
|
134
|
+
function notMatched() {
|
|
135
|
+
return null;
|
|
136
|
+
}
|
|
137
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
138
|
+
0 && (module.exports = {
|
|
139
|
+
RequestNotHandled,
|
|
140
|
+
RequestNotMatched,
|
|
141
|
+
call,
|
|
142
|
+
compose,
|
|
143
|
+
createInput,
|
|
144
|
+
noContent,
|
|
145
|
+
normalize,
|
|
146
|
+
notHandled,
|
|
147
|
+
notMatched
|
|
148
|
+
});
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { InputObject, NextFunction, Route, RouteContext, RouteHandler } from "./types";
|
|
2
|
+
export declare const RequestNotHandled: unique symbol;
|
|
3
|
+
export declare const RequestNotMatched: unique symbol;
|
|
4
|
+
export declare function createInput(context: RouteContext): (data: InputObject) => InputObject;
|
|
5
|
+
export declare function call(handler: RouteHandler<Route>, next: NextFunction, context: RouteContext): Promise<Response>;
|
|
6
|
+
export declare function compose(handlers: RouteHandler[]): RouteHandler;
|
|
7
|
+
export declare function normalize(obj: RouteHandler | RouteHandler[] | Promise<RouteHandler | RouteHandler[]>): RouteHandler;
|
|
8
|
+
export declare function noContent(): Response;
|
|
9
|
+
export declare function notHandled(): void;
|
|
10
|
+
export declare function notMatched(): null;
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
// src/runtime/internal.ts
|
|
2
|
+
globalThis.Marko ?? (globalThis.Marko = {});
|
|
3
|
+
globalThis.Marko.route = (handler) => handler;
|
|
4
|
+
var RequestNotHandled = Symbol();
|
|
5
|
+
var RequestNotMatched = Symbol();
|
|
6
|
+
function createInput(context) {
|
|
7
|
+
let existing;
|
|
8
|
+
return (data) => {
|
|
9
|
+
existing ?? (existing = {
|
|
10
|
+
$global: {
|
|
11
|
+
context
|
|
12
|
+
}
|
|
13
|
+
});
|
|
14
|
+
return data ? Object.assign(existing, data) : existing;
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
async function call(handler, next, context) {
|
|
18
|
+
let response;
|
|
19
|
+
if (process.env.NODE_ENV !== "production") {
|
|
20
|
+
let nextCallCount = 0;
|
|
21
|
+
let didThrow = false;
|
|
22
|
+
try {
|
|
23
|
+
response = await handler(context, () => {
|
|
24
|
+
nextCallCount++;
|
|
25
|
+
return next();
|
|
26
|
+
});
|
|
27
|
+
} catch (error) {
|
|
28
|
+
didThrow = true;
|
|
29
|
+
if (error instanceof Response) {
|
|
30
|
+
return error;
|
|
31
|
+
}
|
|
32
|
+
throw error;
|
|
33
|
+
} finally {
|
|
34
|
+
if (!response && !didThrow && nextCallCount > 0) {
|
|
35
|
+
console.warn(
|
|
36
|
+
`Handler '${handler.name}' called its next function but no response was returned. This will cause the next function to be called again which is wasteful. Either return or throw the result of calling \`next\`, return or throw a new Response object or finally \`throw null\` to skip handling the request`
|
|
37
|
+
);
|
|
38
|
+
} else if (nextCallCount > 1) {
|
|
39
|
+
console.warn(
|
|
40
|
+
`Handler '${handler.name}' called its next function more than once. Make sure this is intentional because it is inefficient.`
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
} else {
|
|
45
|
+
try {
|
|
46
|
+
response = await handler(context, next);
|
|
47
|
+
} catch (error) {
|
|
48
|
+
if (error == null) {
|
|
49
|
+
throw RequestNotHandled;
|
|
50
|
+
} else if (error instanceof Response) {
|
|
51
|
+
return error;
|
|
52
|
+
}
|
|
53
|
+
throw error;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
if (response === null) {
|
|
57
|
+
throw RequestNotMatched;
|
|
58
|
+
}
|
|
59
|
+
return response || next();
|
|
60
|
+
}
|
|
61
|
+
function compose(handlers) {
|
|
62
|
+
const len = handlers.length;
|
|
63
|
+
if (!len) {
|
|
64
|
+
return (_context, next) => next();
|
|
65
|
+
} else if (len === 1) {
|
|
66
|
+
return handlers[0];
|
|
67
|
+
}
|
|
68
|
+
return (context, next) => {
|
|
69
|
+
let i = 0;
|
|
70
|
+
return function nextHandler() {
|
|
71
|
+
return i < len ? call(handlers[i++], nextHandler, context) : next();
|
|
72
|
+
}();
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
function normalize(obj) {
|
|
76
|
+
if (typeof obj === "function") {
|
|
77
|
+
return obj;
|
|
78
|
+
} else if (Array.isArray(obj)) {
|
|
79
|
+
return compose(obj);
|
|
80
|
+
} else if (obj instanceof Promise) {
|
|
81
|
+
const promise = obj.then((value) => {
|
|
82
|
+
fn = Array.isArray(value) ? compose(value) : value;
|
|
83
|
+
});
|
|
84
|
+
let fn = async (context, next) => {
|
|
85
|
+
await promise;
|
|
86
|
+
return fn(context, next);
|
|
87
|
+
};
|
|
88
|
+
return (context, next) => fn(context, next);
|
|
89
|
+
}
|
|
90
|
+
throw new Error(
|
|
91
|
+
`Invalid handler - expected function, array or Promise but received ${obj}`
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
function noContent() {
|
|
95
|
+
return new Response(null, {
|
|
96
|
+
status: 204
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
function notHandled() {
|
|
100
|
+
throw null;
|
|
101
|
+
}
|
|
102
|
+
function notMatched() {
|
|
103
|
+
return null;
|
|
104
|
+
}
|
|
105
|
+
export {
|
|
106
|
+
RequestNotHandled,
|
|
107
|
+
RequestNotMatched,
|
|
108
|
+
call,
|
|
109
|
+
compose,
|
|
110
|
+
createInput,
|
|
111
|
+
noContent,
|
|
112
|
+
normalize,
|
|
113
|
+
notHandled,
|
|
114
|
+
notMatched
|
|
115
|
+
};
|
package/dist/runtime/router.cjs
CHANGED
|
@@ -20,20 +20,22 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/runtime/router.ts
|
|
21
21
|
var router_exports = {};
|
|
22
22
|
__export(router_exports, {
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
invokeRoute: () => invokeRoute,
|
|
24
|
+
matchRoute: () => matchRoute,
|
|
25
25
|
router: () => router
|
|
26
26
|
});
|
|
27
27
|
module.exports = __toCommonJS(router_exports);
|
|
28
28
|
function notImplemented() {
|
|
29
|
-
throw new Error(
|
|
29
|
+
throw new Error(
|
|
30
|
+
"This should have been replaced by the @marko/run plugin at build/dev time"
|
|
31
|
+
);
|
|
30
32
|
}
|
|
31
|
-
var handler = notImplemented;
|
|
32
33
|
var router = notImplemented;
|
|
33
|
-
var
|
|
34
|
+
var matchRoute = notImplemented;
|
|
35
|
+
var invokeRoute = notImplemented;
|
|
34
36
|
// Annotate the CommonJS export names for ESM import in node:
|
|
35
37
|
0 && (module.exports = {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
+
invokeRoute,
|
|
39
|
+
matchRoute,
|
|
38
40
|
router
|
|
39
41
|
});
|
package/dist/runtime/router.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
export declare const
|
|
3
|
-
export declare const
|
|
4
|
-
export declare const
|
|
1
|
+
import type { MatchRoute, RequestContext, Route } from "./types";
|
|
2
|
+
export declare const router: <T>(context: RequestContext<T>) => Promise<Response | void>;
|
|
3
|
+
export declare const matchRoute: MatchRoute;
|
|
4
|
+
export declare const invokeRoute: <T>(route: Route | null, context: RequestContext<T>) => Promise<Response | void>;
|
package/dist/runtime/router.js
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
// src/runtime/router.ts
|
|
2
2
|
function notImplemented() {
|
|
3
|
-
throw new Error(
|
|
3
|
+
throw new Error(
|
|
4
|
+
"This should have been replaced by the @marko/run plugin at build/dev time"
|
|
5
|
+
);
|
|
4
6
|
}
|
|
5
|
-
var handler = notImplemented;
|
|
6
7
|
var router = notImplemented;
|
|
7
|
-
var
|
|
8
|
+
var matchRoute = notImplemented;
|
|
9
|
+
var invokeRoute = notImplemented;
|
|
8
10
|
export {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
+
invokeRoute,
|
|
12
|
+
matchRoute,
|
|
11
13
|
router
|
|
12
14
|
};
|