@marko/run 0.0.1-beta2 → 0.0.1-beta3
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/default-entry.mjs +9 -3
- package/dist/adapter/dev-server.d.ts +1 -1
- package/dist/adapter/index.cjs +23 -8
- package/dist/adapter/index.js +22 -7
- package/dist/adapter/middleware.cjs +200 -0
- package/dist/adapter/middleware.d.ts +59 -0
- package/dist/adapter/middleware.js +169 -0
- package/dist/cli/default.config.mjs +1 -1
- package/dist/cli/index.mjs +45 -24
- 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 +6 -6
- package/dist/runtime/router.d.ts +4 -4
- package/dist/runtime/router.js +4 -4
- package/dist/runtime/types.d.ts +31 -16
- package/dist/runtime/utils.d.ts +3 -0
- 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 +542 -275
- package/dist/vite/index.d.ts +4 -3
- package/dist/vite/index.js +539 -275
- package/dist/vite/types.d.ts +9 -7
- package/dist/vite/utils/config.d.ts +2 -2
- package/dist/vite/utils/route.d.ts +1 -1
- package/dist/vite/utils/server.d.ts +3 -1
- package/package.json +18 -6
package/dist/vite/index.cjs
CHANGED
|
@@ -29,6 +29,8 @@ __export(vite_exports, {
|
|
|
29
29
|
default: () => markoServe,
|
|
30
30
|
getAvailablePort: () => getAvailablePort,
|
|
31
31
|
isPortInUse: () => isPortInUse,
|
|
32
|
+
loadEnv: () => loadEnv,
|
|
33
|
+
parseEnv: () => parseEnv,
|
|
32
34
|
spawnServer: () => spawnServer
|
|
33
35
|
});
|
|
34
36
|
module.exports = __toCommonJS(vite_exports);
|
|
@@ -36,13 +38,16 @@ module.exports = __toCommonJS(vite_exports);
|
|
|
36
38
|
// src/vite/plugin.ts
|
|
37
39
|
var import_path2 = __toESM(require("path"), 1);
|
|
38
40
|
var import_crypto = __toESM(require("crypto"), 1);
|
|
41
|
+
var import_fs2 = __toESM(require("fs"), 1);
|
|
42
|
+
var import_glob = __toESM(require("glob"), 1);
|
|
39
43
|
var import_vite = require("vite");
|
|
40
44
|
var import_vite2 = __toESM(require("@marko/vite"), 1);
|
|
41
45
|
|
|
42
46
|
// src/vite/constants.ts
|
|
43
|
-
var
|
|
44
|
-
var virtualFilePrefix = "virtual:marko-
|
|
47
|
+
var markoRunFilePrefix = "__marko-run__";
|
|
48
|
+
var virtualFilePrefix = "virtual:marko-run";
|
|
45
49
|
var virtualRoutesPrefix = `${virtualFilePrefix}/routes`;
|
|
50
|
+
var virtualRuntimePrefix = `${virtualFilePrefix}/internal`;
|
|
46
51
|
var httpVerbs = ["get", "post", "put", "delete"];
|
|
47
52
|
var serverEntryQuery = "?marko-server-entry";
|
|
48
53
|
var browserEntryQuery = "?marko-browser-entry";
|
|
@@ -82,15 +87,20 @@ function isSpecialType(type) {
|
|
|
82
87
|
return type === RoutableFileTypes.NotFound || type === RoutableFileTypes.Error;
|
|
83
88
|
}
|
|
84
89
|
async function buildRoutes(walk, basePath) {
|
|
85
|
-
|
|
90
|
+
if (basePath) {
|
|
91
|
+
basePath = basePath.replace(/^\/+|\/+$/g, "");
|
|
92
|
+
}
|
|
93
|
+
const dirStack = [];
|
|
86
94
|
const pathStack = [];
|
|
87
95
|
const paramStack = [];
|
|
88
96
|
const layoutsStack = [];
|
|
89
97
|
const middlewareStack = [];
|
|
90
98
|
const routes = /* @__PURE__ */ new Map();
|
|
91
99
|
const special = {};
|
|
100
|
+
const middleware = /* @__PURE__ */ new Set();
|
|
92
101
|
let isRoot = true;
|
|
93
|
-
let
|
|
102
|
+
let nextFileId = 1;
|
|
103
|
+
let nextRouteIndex = 1;
|
|
94
104
|
let current;
|
|
95
105
|
let children = [];
|
|
96
106
|
await walk({
|
|
@@ -118,10 +128,13 @@ async function buildRoutes(walk, basePath) {
|
|
|
118
128
|
if (!entries) {
|
|
119
129
|
current.files.set(type, entries = []);
|
|
120
130
|
}
|
|
131
|
+
const relativePath = current.originalPath ? `${current.originalPath}/${entry.name}` : entry.name;
|
|
121
132
|
entries.push({
|
|
133
|
+
id: String(nextFileId++),
|
|
122
134
|
type,
|
|
123
135
|
filePath: entry.path,
|
|
124
|
-
|
|
136
|
+
relativePath,
|
|
137
|
+
importPath: `${basePath}/${relativePath}`,
|
|
125
138
|
name: entry.name,
|
|
126
139
|
verbs: type === RoutableFileTypes.Page ? ["get"] : void 0
|
|
127
140
|
});
|
|
@@ -132,20 +145,24 @@ async function buildRoutes(walk, basePath) {
|
|
|
132
145
|
return;
|
|
133
146
|
}
|
|
134
147
|
const { path: path3, files } = current;
|
|
135
|
-
const
|
|
136
|
-
const
|
|
148
|
+
const localMiddleware = (_a = files.get(RoutableFileTypes.Middleware)) == null ? void 0 : _a[0];
|
|
149
|
+
const localLayout = (_b = files.get(RoutableFileTypes.Layout)) == null ? void 0 : _b[0];
|
|
137
150
|
const handler = (_c = files.get(RoutableFileTypes.Handler)) == null ? void 0 : _c[0];
|
|
138
151
|
const page = (_d = files.get(RoutableFileTypes.Page)) == null ? void 0 : _d[0];
|
|
139
152
|
const middlewareStackLength = middlewareStack.length;
|
|
140
153
|
const layoutsStackLength = layoutsStack.length;
|
|
141
|
-
|
|
142
|
-
|
|
154
|
+
if (localMiddleware) {
|
|
155
|
+
middlewareStack.push(localMiddleware);
|
|
156
|
+
}
|
|
157
|
+
if (localLayout) {
|
|
158
|
+
layoutsStack.push(localLayout);
|
|
159
|
+
}
|
|
143
160
|
if (handler || page) {
|
|
144
161
|
const key = path3.replace(/(\$\$?)[^\/]*/g, "$1").replace(/^\/+/, "").replace(/[^a-z0-9_$\/]+/gi, "").replace(/\//g, "__") || "index";
|
|
145
162
|
if (routes.has(key)) {
|
|
146
163
|
console.warn(`Duplicate route for path ${path3} -- ignoring`, current);
|
|
147
164
|
} else {
|
|
148
|
-
const index =
|
|
165
|
+
const index = nextRouteIndex++;
|
|
149
166
|
routes.set(key, {
|
|
150
167
|
index,
|
|
151
168
|
key,
|
|
@@ -158,6 +175,9 @@ async function buildRoutes(walk, basePath) {
|
|
|
158
175
|
handler,
|
|
159
176
|
score: scorePath(path3, index)
|
|
160
177
|
});
|
|
178
|
+
for (const mw of middlewareStack) {
|
|
179
|
+
middleware.add(mw);
|
|
180
|
+
}
|
|
161
181
|
}
|
|
162
182
|
}
|
|
163
183
|
if (isRoot) {
|
|
@@ -193,7 +213,7 @@ async function buildRoutes(walk, basePath) {
|
|
|
193
213
|
if (name.charCodeAt(0) === 36) {
|
|
194
214
|
if (name.charCodeAt(1) === 36) {
|
|
195
215
|
paramStack.push({
|
|
196
|
-
name: name.slice(2) || "
|
|
216
|
+
name: name.slice(2) || "rest",
|
|
197
217
|
index: -1
|
|
198
218
|
});
|
|
199
219
|
} else if (name.length > 1) {
|
|
@@ -223,7 +243,8 @@ async function buildRoutes(walk, basePath) {
|
|
|
223
243
|
});
|
|
224
244
|
return {
|
|
225
245
|
list: [...routes.values()],
|
|
226
|
-
special
|
|
246
|
+
special,
|
|
247
|
+
middleware: [...middleware]
|
|
227
248
|
};
|
|
228
249
|
}
|
|
229
250
|
|
|
@@ -273,6 +294,17 @@ function createWriter(sink, options) {
|
|
|
273
294
|
let firstOpenIndex = 0;
|
|
274
295
|
const branches = [];
|
|
275
296
|
const openWriters = /* @__PURE__ */ new Map();
|
|
297
|
+
function write(data) {
|
|
298
|
+
if (!writer.__isActive) {
|
|
299
|
+
throw new Error("Cannot write to branch that has been joined");
|
|
300
|
+
}
|
|
301
|
+
if (openWriters.size) {
|
|
302
|
+
buffer += data;
|
|
303
|
+
} else {
|
|
304
|
+
sink(data);
|
|
305
|
+
}
|
|
306
|
+
return writer;
|
|
307
|
+
}
|
|
276
308
|
const writer = {
|
|
277
309
|
__isActive: true,
|
|
278
310
|
get indent() {
|
|
@@ -289,24 +321,16 @@ function createWriter(sink, options) {
|
|
|
289
321
|
}
|
|
290
322
|
}
|
|
291
323
|
},
|
|
292
|
-
write(data) {
|
|
293
|
-
if (
|
|
294
|
-
|
|
324
|
+
write(data, indent = false) {
|
|
325
|
+
if (indent && indentString) {
|
|
326
|
+
write(indentString);
|
|
295
327
|
}
|
|
296
|
-
|
|
297
|
-
buffer += data;
|
|
298
|
-
} else {
|
|
299
|
-
sink(data);
|
|
300
|
-
}
|
|
301
|
-
return writer;
|
|
328
|
+
return write(data);
|
|
302
329
|
},
|
|
303
330
|
writeLines(...lines) {
|
|
304
331
|
for (const line of lines) {
|
|
305
332
|
if (line) {
|
|
306
|
-
|
|
307
|
-
writer.write(indentString);
|
|
308
|
-
}
|
|
309
|
-
writer.write(line);
|
|
333
|
+
writer.write(line, true);
|
|
310
334
|
}
|
|
311
335
|
writer.write("\n");
|
|
312
336
|
}
|
|
@@ -453,16 +477,13 @@ function hasVerb(route, verb) {
|
|
|
453
477
|
}
|
|
454
478
|
|
|
455
479
|
// src/vite/codegen/index.ts
|
|
456
|
-
var DefaultCodegenOptions = {
|
|
457
|
-
trailingSlashes: "RedirectWithout"
|
|
458
|
-
};
|
|
459
480
|
function renderRouteTemplate(route) {
|
|
460
481
|
if (!route.page) {
|
|
461
482
|
throw new Error(`Route ${route.key} has no page to render`);
|
|
462
483
|
}
|
|
463
484
|
const writer = createStringWriter();
|
|
464
485
|
writer.writeLines(
|
|
465
|
-
`// ${virtualFilePrefix}/${
|
|
486
|
+
`// ${virtualFilePrefix}/${markoRunFilePrefix}route__${route.key}.marko`
|
|
466
487
|
);
|
|
467
488
|
writer.branch("imports");
|
|
468
489
|
writer.writeLines("");
|
|
@@ -494,25 +515,47 @@ function renderRouteEntry(route) {
|
|
|
494
515
|
}
|
|
495
516
|
const writer = createStringWriter();
|
|
496
517
|
writer.writeLines(
|
|
497
|
-
`// ${virtualFilePrefix}/${
|
|
518
|
+
`// ${virtualFilePrefix}/${markoRunFilePrefix}route__${key}.js`
|
|
498
519
|
);
|
|
499
520
|
const imports = writer.branch("imports");
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
i++;
|
|
521
|
+
const runtimeImports = [];
|
|
522
|
+
if (handler) {
|
|
523
|
+
runtimeImports.push("normalize");
|
|
504
524
|
}
|
|
505
|
-
if (
|
|
506
|
-
|
|
507
|
-
|
|
525
|
+
if (handler || middleware.length) {
|
|
526
|
+
runtimeImports.push("call");
|
|
527
|
+
}
|
|
528
|
+
if (!page || verbs.length > 1) {
|
|
529
|
+
runtimeImports.push("noContent");
|
|
530
|
+
}
|
|
531
|
+
if (runtimeImports.length) {
|
|
532
|
+
imports.writeLines(
|
|
533
|
+
`import { ${runtimeImports.join(", ")} } from '${virtualRuntimePrefix}';`
|
|
534
|
+
);
|
|
535
|
+
}
|
|
536
|
+
if (middleware.length) {
|
|
537
|
+
const names = middleware.map((m) => `mware$${m.id}`);
|
|
538
|
+
imports.writeLines(
|
|
539
|
+
`import { ${names.join(
|
|
540
|
+
", "
|
|
541
|
+
)} } from '${virtualFilePrefix}/${markoRunFilePrefix}middleware.js';`
|
|
508
542
|
);
|
|
543
|
+
}
|
|
544
|
+
if ((_a = handler == null ? void 0 : handler.verbs) == null ? void 0 : _a.length) {
|
|
545
|
+
writer.writeLines("");
|
|
546
|
+
const names = [];
|
|
547
|
+
for (const verb of handler.verbs) {
|
|
548
|
+
const name = verb === "delete" ? "del" : verb;
|
|
549
|
+
names.push(name);
|
|
550
|
+
writer.writeLines(`const handler$${name} = normalize(${name});`);
|
|
551
|
+
}
|
|
509
552
|
imports.writeLines(
|
|
510
553
|
`import { ${names.join(", ")} } from './${handler.importPath}';`
|
|
511
554
|
);
|
|
512
555
|
}
|
|
513
556
|
if (page) {
|
|
514
557
|
imports.writeLines(
|
|
515
|
-
`import page from '${virtualFilePrefix}/${
|
|
558
|
+
`import page from '${virtualFilePrefix}/${markoRunFilePrefix}route__${key}.marko${serverEntryQuery}';`
|
|
516
559
|
);
|
|
517
560
|
}
|
|
518
561
|
if (meta) {
|
|
@@ -520,21 +563,27 @@ function renderRouteEntry(route) {
|
|
|
520
563
|
`export { default as meta$${index} } from './${meta.importPath}';`
|
|
521
564
|
);
|
|
522
565
|
}
|
|
523
|
-
if (!page || verbs.length > 1) {
|
|
524
|
-
writer.writeLines("").writeBlockStart(`function create204Response() {`).writeBlockStart(`return new Response(null, {`).writeLines(`status: 204`).writeBlockEnd(`})`).writeBlockEnd(`}`);
|
|
525
|
-
}
|
|
526
566
|
for (const verb of verbs) {
|
|
527
567
|
writeRouteEntryHandler(writer, route, verb);
|
|
528
568
|
}
|
|
529
569
|
return writer.end();
|
|
530
570
|
}
|
|
531
|
-
function
|
|
571
|
+
function writePageResponse(writer, wrapFn) {
|
|
532
572
|
writer.writeBlock(
|
|
533
|
-
`return new Response(page.stream(
|
|
573
|
+
`${wrapFn ? `const ${wrapFn} = () =>` : `return`} new Response(page.stream(buildInput()), {`,
|
|
534
574
|
["status: 200,", 'headers: { "content-type": "text/html;charset=UTF-8" }'],
|
|
535
575
|
"});"
|
|
536
576
|
);
|
|
537
577
|
}
|
|
578
|
+
function writeMiddleware(writer, middleware, next, wrapFn) {
|
|
579
|
+
if (wrapFn) {
|
|
580
|
+
writer.writeLines(
|
|
581
|
+
`const ${wrapFn} = () => call(${middleware}, ${next}, context);`
|
|
582
|
+
);
|
|
583
|
+
} else {
|
|
584
|
+
writer.writeLines(`return call(${middleware}, ${next}, context);`);
|
|
585
|
+
}
|
|
586
|
+
}
|
|
538
587
|
function writeRouteEntryHandler(writer, route, verb) {
|
|
539
588
|
var _a;
|
|
540
589
|
const { key, index, page, handler, middleware } = route;
|
|
@@ -542,47 +591,38 @@ function writeRouteEntryHandler(writer, route, verb) {
|
|
|
542
591
|
let nextName;
|
|
543
592
|
let currentName;
|
|
544
593
|
let hasBody = false;
|
|
545
|
-
writer.writeLines("").writeBlockStart(
|
|
594
|
+
writer.writeLines("").writeBlockStart(
|
|
595
|
+
`export async function ${verb}$${index}(context, buildInput) {`
|
|
596
|
+
);
|
|
546
597
|
const continuations = writer.branch("cont");
|
|
547
598
|
if (page && verb === "get") {
|
|
548
|
-
currentName = "
|
|
599
|
+
currentName = "__page";
|
|
549
600
|
if ((_a = handler == null ? void 0 : handler.verbs) == null ? void 0 : _a.includes(verb)) {
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
continuations.writeBlockEnd("}");
|
|
601
|
+
const name = `handler$${verb}`;
|
|
602
|
+
writePageResponse(continuations, currentName);
|
|
553
603
|
if (len) {
|
|
554
604
|
nextName = currentName;
|
|
555
|
-
currentName = `
|
|
556
|
-
continuations
|
|
557
|
-
`async function ${currentName}() {`,
|
|
558
|
-
[`return await handler$${verb}(ctx, ${nextName});`],
|
|
559
|
-
"}"
|
|
560
|
-
);
|
|
605
|
+
currentName = `__${name}`;
|
|
606
|
+
writeMiddleware(continuations, name, nextName, currentName);
|
|
561
607
|
} else {
|
|
562
|
-
writer
|
|
608
|
+
writeMiddleware(writer, name, currentName);
|
|
563
609
|
hasBody = true;
|
|
564
610
|
}
|
|
565
611
|
} else if (len) {
|
|
566
|
-
continuations
|
|
567
|
-
writePageResponseContinuation(continuations);
|
|
568
|
-
continuations.writeBlockEnd("}");
|
|
612
|
+
writePageResponse(continuations, currentName);
|
|
569
613
|
nextName = currentName;
|
|
570
614
|
} else {
|
|
571
|
-
|
|
615
|
+
writePageResponse(continuations);
|
|
572
616
|
hasBody = true;
|
|
573
617
|
}
|
|
574
618
|
} else if (handler) {
|
|
575
|
-
|
|
619
|
+
const name = `handler$${verb}`;
|
|
620
|
+
currentName = `__${name}`;
|
|
621
|
+
nextName = "noContent";
|
|
576
622
|
if (len) {
|
|
577
|
-
continuations
|
|
578
|
-
`async function ${currentName}() {`,
|
|
579
|
-
[`return await handler$${verb}(ctx, create204Response);`],
|
|
580
|
-
"}"
|
|
581
|
-
);
|
|
623
|
+
writeMiddleware(continuations, name, nextName, currentName);
|
|
582
624
|
} else {
|
|
583
|
-
writer
|
|
584
|
-
`return await handler$${verb}(ctx, create204Response);`
|
|
585
|
-
);
|
|
625
|
+
writeMiddleware(writer, name, nextName);
|
|
586
626
|
hasBody = true;
|
|
587
627
|
}
|
|
588
628
|
} else {
|
|
@@ -590,24 +630,26 @@ function writeRouteEntryHandler(writer, route, verb) {
|
|
|
590
630
|
}
|
|
591
631
|
if (!hasBody) {
|
|
592
632
|
let i = len;
|
|
593
|
-
while (--
|
|
633
|
+
while (i--) {
|
|
634
|
+
const { id } = middleware[i];
|
|
635
|
+
const name = `mware$${id}`;
|
|
594
636
|
nextName = currentName;
|
|
595
|
-
currentName = `
|
|
596
|
-
continuations
|
|
597
|
-
`async function ${currentName}() {`,
|
|
598
|
-
[`return await middleware$${i + 1}(ctx, ${nextName});`],
|
|
599
|
-
"}"
|
|
600
|
-
);
|
|
637
|
+
currentName = i ? `__${name}` : "";
|
|
638
|
+
writeMiddleware(continuations, name, nextName, currentName);
|
|
601
639
|
}
|
|
602
|
-
writer.writeLines(`return await middleware$1(ctx, ${currentName});`);
|
|
603
640
|
}
|
|
604
641
|
continuations.join();
|
|
605
642
|
writer.writeBlockEnd("}");
|
|
606
643
|
}
|
|
607
|
-
function renderRouter(routes, options =
|
|
644
|
+
function renderRouter(routes, options = {
|
|
645
|
+
trailingSlashes: "RedirectWithout"
|
|
646
|
+
}) {
|
|
608
647
|
const writer = createStringWriter();
|
|
609
648
|
writer.writeLines(`// @marko/run/router`);
|
|
610
649
|
const imports = writer.branch("imports");
|
|
650
|
+
imports.writeLines(
|
|
651
|
+
`import { RequestNotHandled, RequestNotMatched, createInput } from 'virtual:marko-run/internal';`
|
|
652
|
+
);
|
|
611
653
|
for (const route of routes.list) {
|
|
612
654
|
const verbs = getVerbs(route);
|
|
613
655
|
const names = verbs.map((verb) => `${verb}$${route.index}`);
|
|
@@ -615,15 +657,15 @@ function renderRouter(routes, options = DefaultCodegenOptions) {
|
|
|
615
657
|
imports.writeLines(
|
|
616
658
|
`import { ${names.join(
|
|
617
659
|
", "
|
|
618
|
-
)} } from '${virtualFilePrefix}/${
|
|
660
|
+
)} } from '${virtualFilePrefix}/${markoRunFilePrefix}route__${route.key}.js';`
|
|
619
661
|
);
|
|
620
662
|
}
|
|
621
663
|
for (const { key } of Object.values(routes.special)) {
|
|
622
664
|
imports.writeLines(
|
|
623
|
-
`import page$${key} from '${virtualFilePrefix}/${
|
|
665
|
+
`import page$${key} from '${virtualFilePrefix}/${markoRunFilePrefix}special__${key}.marko${serverEntryQuery}';`
|
|
624
666
|
);
|
|
625
667
|
}
|
|
626
|
-
writer.writeLines(
|
|
668
|
+
writer.writeLines(``).writeBlockStart(`function findRoute(method, pathname) {`).writeBlockStart(`switch (method.toLowerCase()) {`);
|
|
627
669
|
for (const verb of httpVerbs) {
|
|
628
670
|
const filteredRoutes = routes.list.filter((route) => hasVerb(route, verb));
|
|
629
671
|
if (filteredRoutes.length) {
|
|
@@ -633,120 +675,105 @@ function renderRouter(routes, options = DefaultCodegenOptions) {
|
|
|
633
675
|
writer.writeBlockEnd("}");
|
|
634
676
|
}
|
|
635
677
|
}
|
|
636
|
-
writer.writeBlockEnd("}").writeBlockEnd("}");
|
|
637
|
-
writer.
|
|
638
|
-
|
|
639
|
-
if (
|
|
640
|
-
|
|
678
|
+
writer.writeBlockEnd("}").writeLines("return null;").writeBlockEnd("}");
|
|
679
|
+
writer.write(`
|
|
680
|
+
export function matchRoute(method, pathname) {
|
|
681
|
+
if (!pathname) {
|
|
682
|
+
pathname = '/';
|
|
683
|
+
} else if (pathname.charAt(0) !== '/') {
|
|
684
|
+
pathname = '/' + pathname;
|
|
641
685
|
}
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
686
|
+
return findRoute(method, pathname);
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
export async function invokeRoute(route, context) {
|
|
690
|
+
try {
|
|
691
|
+
const buildInput = createInput(context);
|
|
692
|
+
if (route) {
|
|
693
|
+
context.params = route.params;
|
|
694
|
+
context.meta = route.meta;
|
|
695
|
+
try {
|
|
696
|
+
const response = await route.handler(context, buildInput);
|
|
697
|
+
if (response) return response;
|
|
698
|
+
} catch (error) {
|
|
699
|
+
if (error === RequestNotHandled) {
|
|
700
|
+
return;
|
|
701
|
+
} else if (error !== RequestNotMatched) {
|
|
702
|
+
throw error;
|
|
703
|
+
}
|
|
704
|
+
}
|
|
705
|
+
`).indent = 2;
|
|
706
|
+
if (routes.special[RoutableFileTypes.NotFound]) {
|
|
707
|
+
writer.write(
|
|
708
|
+
` } else {
|
|
709
|
+
context.params = {};
|
|
710
|
+
context.meta = {};
|
|
711
|
+
}
|
|
712
|
+
if (context.request.headers.get('Accept')?.includes('text/html')) {
|
|
713
|
+
return new Response(page$404.stream(buildInput()), {
|
|
714
|
+
status: 404,
|
|
715
|
+
headers: { "content-type": "text/html;charset=UTF-8" },
|
|
716
|
+
});
|
|
717
|
+
}
|
|
718
|
+
`
|
|
719
|
+
);
|
|
720
|
+
} else {
|
|
721
|
+
writer.writeBlockEnd("}");
|
|
663
722
|
}
|
|
664
|
-
writer.
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
writer.writeBlockStart(
|
|
668
|
-
`if (request.headers.get('Accept')?.includes('text/html')) {`
|
|
723
|
+
writer.indent--;
|
|
724
|
+
writer.writeBlockStart(`} catch (error) {`);
|
|
725
|
+
if (routes.special[RoutableFileTypes.Error]) {
|
|
726
|
+
writer.writeBlockStart(
|
|
727
|
+
`if (context.request.headers.get('Accept')?.includes('text/html')) {`
|
|
669
728
|
).writeBlock(
|
|
670
|
-
`return new Response(page$500.stream({
|
|
729
|
+
`return new Response(page$500.stream(buildInput({ error })), {`,
|
|
671
730
|
[
|
|
672
731
|
`status: 500,`,
|
|
673
732
|
`headers: { "content-type": "text/html;charset=UTF-8" },`
|
|
674
733
|
],
|
|
675
734
|
`});`
|
|
676
|
-
).writeBlockEnd("}")
|
|
677
|
-
}
|
|
678
|
-
writer.writeBlockEnd("}");
|
|
679
|
-
writer.write(`
|
|
680
|
-
export function getMatchedRoute(method, url) {
|
|
681
|
-
const route = matchRoute(method, url.pathname);
|
|
682
|
-
if (route) {
|
|
683
|
-
const [handler, params = {}, meta] = route;
|
|
684
|
-
return {
|
|
685
|
-
handler,
|
|
686
|
-
params,
|
|
687
|
-
meta,
|
|
688
|
-
async invoke(request) {
|
|
689
|
-
return await invokeRoute(route, url, request);
|
|
690
|
-
}
|
|
691
|
-
}
|
|
735
|
+
).writeBlockEnd("}");
|
|
692
736
|
}
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
export async function handler(context) {
|
|
697
|
-
const response = await router(context.request);
|
|
698
|
-
//if (response.body) {
|
|
699
|
-
// context.waitUntil?.(once(Readable.from(response.body), "end"));
|
|
700
|
-
//}
|
|
701
|
-
return response;
|
|
702
|
-
}
|
|
703
|
-
|
|
704
|
-
export async function router(request) {
|
|
737
|
+
writer.writeLines(`throw error;`).writeBlockEnd("}").writeBlockEnd("}").write(`
|
|
738
|
+
export async function router(context) {
|
|
705
739
|
try {
|
|
706
|
-
const url =
|
|
707
|
-
let { pathname } = url;
|
|
708
|
-
|
|
709
|
-
if (pathname !== '/') {
|
|
710
|
-
if (pathname.endsWith('/')) {
|
|
711
|
-
pathname = pathname.replace(/\\/+$/, '');
|
|
712
|
-
`);
|
|
740
|
+
const { url, method } = context;
|
|
741
|
+
let { pathname } = url;`);
|
|
713
742
|
switch (options.trailingSlashes) {
|
|
714
743
|
case "RedirectWithout":
|
|
715
744
|
writer.write(`
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
745
|
+
if (pathname !== '/' && pathname.endsWith('/')) {
|
|
746
|
+
url.pathname = pathname.slice(0, -1);
|
|
747
|
+
return Response.redirect(url);
|
|
748
|
+
}`);
|
|
719
749
|
break;
|
|
720
750
|
case "RedirectWith":
|
|
721
751
|
writer.write(`
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
`);
|
|
752
|
+
if (pathname !== '/' && !pathname.endsWith('/')) {
|
|
753
|
+
url.pathname = pathname + '/';
|
|
754
|
+
return Response.redirect(url);
|
|
755
|
+
}`);
|
|
726
756
|
break;
|
|
727
757
|
case "RewriteWithout":
|
|
728
758
|
writer.write(`
|
|
729
|
-
|
|
730
|
-
|
|
759
|
+
if (pathname !== '/' && pathname.endsWith('/')) {
|
|
760
|
+
url.pathname = pathname = pathname.slice(0, -1);
|
|
761
|
+
}`);
|
|
731
762
|
break;
|
|
732
763
|
case "RewriteWith":
|
|
733
764
|
writer.write(`
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
`);
|
|
765
|
+
if (pathname !== '/' && !pathname.endsWith('/')) {
|
|
766
|
+
url.pathname = pathname = pathname + '/';
|
|
767
|
+
}`);
|
|
737
768
|
break;
|
|
738
769
|
}
|
|
739
|
-
writer.write(`
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
statusText: \`Not Found (No route matched \${pathname})\`,
|
|
745
|
-
status: 404
|
|
746
|
-
});
|
|
747
|
-
} catch (err) {
|
|
770
|
+
writer.write(`
|
|
771
|
+
|
|
772
|
+
const route = matchRoute(method, pathname);
|
|
773
|
+
return await invokeRoute(route, context);
|
|
774
|
+
} catch (error) {
|
|
748
775
|
const message = import.meta.env.DEV
|
|
749
|
-
? \`Internal Server Error (\${
|
|
776
|
+
? \`Internal Server Error (\${error.message})\`
|
|
750
777
|
: "Internal Server Error";
|
|
751
778
|
|
|
752
779
|
return new Response(
|
|
@@ -754,7 +781,7 @@ export async function router(request) {
|
|
|
754
781
|
error: {
|
|
755
782
|
message,
|
|
756
783
|
stack: import.meta.env.DEV
|
|
757
|
-
? \`This will only be seen in development mode\\n\\n\${
|
|
784
|
+
? \`This will only be seen in development mode\\n\\n\${error.stack}\`
|
|
758
785
|
: ""
|
|
759
786
|
}
|
|
760
787
|
}),
|
|
@@ -767,101 +794,259 @@ export async function router(request) {
|
|
|
767
794
|
}`);
|
|
768
795
|
return writer.end();
|
|
769
796
|
}
|
|
770
|
-
function writeRouterVerb(writer, trie, verb, level = 0,
|
|
771
|
-
const {
|
|
772
|
-
|
|
773
|
-
if (level
|
|
774
|
-
|
|
775
|
-
if (
|
|
776
|
-
writer.writeLines(
|
|
777
|
-
`if (pathname === '/') return ${renderMatch(verb, value)}; // ${value.path}`
|
|
778
|
-
);
|
|
779
|
-
}
|
|
780
|
-
if (children || dynamic) {
|
|
781
|
-
writer.writeLines(
|
|
782
|
-
`const segments = pathname.split('/');`,
|
|
783
|
-
`const len = segments.length;`
|
|
784
|
-
);
|
|
785
|
-
}
|
|
786
|
-
} else {
|
|
787
|
-
if (!key) {
|
|
788
|
-
writer.writeBlockStart(`if (segments[${level}]) {`);
|
|
789
|
-
} else if (useSwitch) {
|
|
790
|
-
writer.writeBlockStart(`case '${key}':`);
|
|
791
|
-
} else {
|
|
792
|
-
writer.writeBlockStart(
|
|
793
|
-
`if (segments[${level}]?.toLowerCase() === '${key}') {`
|
|
794
|
-
);
|
|
795
|
-
}
|
|
796
|
-
if (value) {
|
|
797
|
+
function writeRouterVerb(writer, trie, verb, level = 0, offset = 1) {
|
|
798
|
+
const { route, dynamic, catchAll } = trie;
|
|
799
|
+
let closeCount = 0;
|
|
800
|
+
if (level === 0) {
|
|
801
|
+
writer.writeLines(`const len = pathname.length;`);
|
|
802
|
+
if (route) {
|
|
797
803
|
writer.writeLines(
|
|
798
|
-
`if (len ===
|
|
804
|
+
`if (len === 1) return ${renderMatch(verb, route)}; // ${route.path}`
|
|
799
805
|
);
|
|
806
|
+
} else if (trie.static || dynamic) {
|
|
807
|
+
writer.writeBlockStart(`if (len > 1) {`);
|
|
808
|
+
closeCount++;
|
|
800
809
|
}
|
|
801
810
|
}
|
|
802
|
-
if (
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
811
|
+
if (trie.static || dynamic) {
|
|
812
|
+
const next = level + 1;
|
|
813
|
+
const index = `i${next}`;
|
|
814
|
+
let terminal;
|
|
815
|
+
let children;
|
|
816
|
+
writer.writeLines(`const ${index} = pathname.indexOf('/', ${offset}) + 1;`);
|
|
817
|
+
if (trie.static) {
|
|
818
|
+
for (const child of trie.static.values()) {
|
|
819
|
+
if (child.route) {
|
|
820
|
+
(terminal ?? (terminal = [])).push(child);
|
|
810
821
|
}
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
822
|
+
if (child.static || child.dynamic || child.catchAll) {
|
|
823
|
+
(children ?? (children = [])).push(child);
|
|
824
|
+
}
|
|
825
|
+
}
|
|
826
|
+
}
|
|
827
|
+
if (terminal || (dynamic == null ? void 0 : dynamic.route)) {
|
|
828
|
+
closeCount++;
|
|
829
|
+
writer.writeBlockStart(`if (!${index} || ${index} === len) {`);
|
|
830
|
+
let value = `pathname.slice(${offset}, ${index} ? -1 : len)`;
|
|
831
|
+
if (dynamic == null ? void 0 : dynamic.route) {
|
|
832
|
+
const segment = `s${next}`;
|
|
833
|
+
writer.writeLines(`const ${segment} = ${value};`);
|
|
834
|
+
value = segment;
|
|
835
|
+
}
|
|
836
|
+
if (terminal) {
|
|
837
|
+
const useSwitch = terminal.length > 1;
|
|
838
|
+
if (useSwitch) {
|
|
839
|
+
writer.writeBlockStart(`switch (${value}.toLowerCase()) {`);
|
|
840
|
+
}
|
|
841
|
+
for (const { key, route: route2 } of terminal) {
|
|
842
|
+
if (useSwitch) {
|
|
843
|
+
writer.write(`case '${key}': `, true);
|
|
844
|
+
} else {
|
|
845
|
+
writer.write(`if (${value}.toLowerCase() === '${key}') `, true);
|
|
846
|
+
}
|
|
847
|
+
writer.write(
|
|
848
|
+
`return ${renderMatch(verb, route2)}; // ${route2.path}
|
|
849
|
+
`
|
|
850
|
+
);
|
|
815
851
|
}
|
|
852
|
+
if (useSwitch) {
|
|
853
|
+
writer.writeBlockEnd("}");
|
|
854
|
+
}
|
|
855
|
+
}
|
|
856
|
+
if (dynamic == null ? void 0 : dynamic.route) {
|
|
857
|
+
writer.writeLines(
|
|
858
|
+
`if (${value}) return ${renderMatch(verb, dynamic.route)}; // ${dynamic.route.path}`
|
|
859
|
+
);
|
|
816
860
|
}
|
|
817
861
|
}
|
|
818
|
-
if (dynamic) {
|
|
819
|
-
|
|
862
|
+
if (children || (dynamic == null ? void 0 : dynamic.static) || (dynamic == null ? void 0 : dynamic.dynamic) || (dynamic == null ? void 0 : dynamic.catchAll)) {
|
|
863
|
+
if (terminal || (dynamic == null ? void 0 : dynamic.route)) {
|
|
864
|
+
writer.writeBlockEnd("} else {").indent++;
|
|
865
|
+
} else {
|
|
866
|
+
writer.writeBlockStart(`if (${index} && ${index} !== len) {`);
|
|
867
|
+
closeCount++;
|
|
868
|
+
}
|
|
869
|
+
let value = `pathname.slice(${offset}, ${index} - 1)`;
|
|
870
|
+
if ((dynamic == null ? void 0 : dynamic.static) || (dynamic == null ? void 0 : dynamic.dynamic)) {
|
|
871
|
+
const segment = `s${next}`;
|
|
872
|
+
writer.writeLines(`const ${segment} = ${value};`);
|
|
873
|
+
value = segment;
|
|
874
|
+
}
|
|
875
|
+
if (children) {
|
|
876
|
+
const useSwitch = children.length > 1;
|
|
877
|
+
if (useSwitch) {
|
|
878
|
+
writer.writeBlockStart(`switch (${value}.toLowerCase()) {`);
|
|
879
|
+
}
|
|
880
|
+
for (const child of children) {
|
|
881
|
+
if (useSwitch) {
|
|
882
|
+
writer.writeBlockStart(`case '${child.key}': {`);
|
|
883
|
+
} else {
|
|
884
|
+
writer.writeBlockStart(
|
|
885
|
+
`if (${value}.toLowerCase() === '${child.key}') {`
|
|
886
|
+
);
|
|
887
|
+
}
|
|
888
|
+
const nextOffset = typeof offset === "string" ? index : offset + child.key.length + 1;
|
|
889
|
+
writeRouterVerb(writer, child, verb, next, nextOffset);
|
|
890
|
+
writer.writeBlockEnd("}");
|
|
891
|
+
}
|
|
892
|
+
if (useSwitch) {
|
|
893
|
+
writer.writeBlockEnd("}");
|
|
894
|
+
}
|
|
895
|
+
}
|
|
896
|
+
if ((dynamic == null ? void 0 : dynamic.static) || (dynamic == null ? void 0 : dynamic.dynamic) || (dynamic == null ? void 0 : dynamic.catchAll)) {
|
|
897
|
+
writer.writeBlockStart(`if (${value}) {`);
|
|
898
|
+
writeRouterVerb(writer, dynamic, verb, next, index);
|
|
899
|
+
writer.writeBlockEnd(`}`);
|
|
900
|
+
}
|
|
820
901
|
}
|
|
821
902
|
}
|
|
903
|
+
while (closeCount--) {
|
|
904
|
+
writer.writeBlockEnd("}");
|
|
905
|
+
}
|
|
822
906
|
if (catchAll) {
|
|
823
907
|
writer.writeLines(
|
|
824
|
-
`return ${renderMatch(verb, catchAll,
|
|
908
|
+
`return ${renderMatch(verb, catchAll, String(offset))}; // ${catchAll.path}`
|
|
825
909
|
);
|
|
826
|
-
if (level > 0) {
|
|
827
|
-
writer.indent--;
|
|
828
|
-
}
|
|
829
910
|
} else if (level === 0) {
|
|
830
|
-
writer.writeLines("return;");
|
|
831
|
-
} else if (useSwitch) {
|
|
832
|
-
writer.writeLines("break;").indent--;
|
|
833
|
-
} else {
|
|
834
|
-
writer.writeBlockEnd("}");
|
|
911
|
+
writer.writeLines("return null;");
|
|
835
912
|
}
|
|
836
913
|
}
|
|
914
|
+
function wrapPropertyName(name) {
|
|
915
|
+
return /^[^A-Za-z_$]|[^A-Za-z0-9$_]/.test(name) ? `'${name}'` : name;
|
|
916
|
+
}
|
|
837
917
|
function renderParamsInfo(params, pathIndex) {
|
|
918
|
+
if (!params.length) {
|
|
919
|
+
return "{}";
|
|
920
|
+
}
|
|
838
921
|
let result = "";
|
|
839
922
|
let catchAll = "";
|
|
840
|
-
let
|
|
923
|
+
let sep = "{";
|
|
841
924
|
for (const { name, index } of params) {
|
|
842
925
|
if (index >= 0) {
|
|
843
|
-
result +=
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
} else if (pathIndex && pathIndex >= 0) {
|
|
926
|
+
result += `${sep} ${wrapPropertyName(name)}: s${index + 1}`;
|
|
927
|
+
sep || (sep = ",");
|
|
928
|
+
} else if (pathIndex) {
|
|
847
929
|
catchAll = name;
|
|
848
930
|
}
|
|
849
931
|
}
|
|
850
932
|
if (catchAll) {
|
|
851
|
-
result +=
|
|
852
|
-
|
|
933
|
+
result += `${sep} ${wrapPropertyName(
|
|
934
|
+
catchAll
|
|
935
|
+
)}: pathname.slice(${pathIndex})`;
|
|
853
936
|
}
|
|
854
937
|
return result ? result + " }" : "{}";
|
|
855
938
|
}
|
|
856
|
-
function
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
tuple[1] = renderParamsInfo(params, pathIndex);
|
|
939
|
+
function renderParamsInfoType(params) {
|
|
940
|
+
if (!params.length) {
|
|
941
|
+
return "{}";
|
|
860
942
|
}
|
|
861
|
-
|
|
862
|
-
|
|
943
|
+
let result = "{";
|
|
944
|
+
for (const { name } of params) {
|
|
945
|
+
result += ` ${wrapPropertyName(name)}: string;`;
|
|
946
|
+
}
|
|
947
|
+
return result + " }";
|
|
948
|
+
}
|
|
949
|
+
function renderMatch(verb, route, pathIndex) {
|
|
950
|
+
var _a;
|
|
951
|
+
const handler = `${verb}$${route.index}`;
|
|
952
|
+
const params = ((_a = route.params) == null ? void 0 : _a.length) ? renderParamsInfo(route.params, pathIndex) : "{}";
|
|
953
|
+
const meta = route.meta ? `meta$${route.index}` : "{}";
|
|
954
|
+
return `{ handler: ${handler}, params: ${params}, meta: ${meta} }`;
|
|
955
|
+
}
|
|
956
|
+
function renderMiddleware(middleware) {
|
|
957
|
+
const writer = createStringWriter();
|
|
958
|
+
writer.writeLines(
|
|
959
|
+
`// ${virtualFilePrefix}/${markoRunFilePrefix}middleware.js`
|
|
960
|
+
);
|
|
961
|
+
const imports = writer.branch("imports");
|
|
962
|
+
imports.writeLines(`import { normalize } from 'virtual:marko-run/internal';`);
|
|
963
|
+
writer.writeLines("");
|
|
964
|
+
for (const { id, importPath } of middleware) {
|
|
965
|
+
const importName = `mware${id}`;
|
|
966
|
+
imports.writeLines(`import ${importName} from './${importPath}';`);
|
|
967
|
+
writer.writeLines(`export const mware$${id} = normalize(${importName});`);
|
|
968
|
+
}
|
|
969
|
+
imports.join();
|
|
970
|
+
return writer.end();
|
|
971
|
+
}
|
|
972
|
+
function stripTsExtension(path3) {
|
|
973
|
+
const index = path3.lastIndexOf(".");
|
|
974
|
+
if (index !== -1) {
|
|
975
|
+
const ext = path3.slice(index + 1);
|
|
976
|
+
if (ext.toLowerCase() === "ts") {
|
|
977
|
+
return path3.slice(0, index);
|
|
978
|
+
}
|
|
979
|
+
}
|
|
980
|
+
return path3;
|
|
981
|
+
}
|
|
982
|
+
function renderRouteTypeInfo(routes, pathPrefix = ".") {
|
|
983
|
+
const writer = createStringWriter();
|
|
984
|
+
writer.writeLines(
|
|
985
|
+
`/*
|
|
986
|
+
WARNING: This file is automatically generated and any changes made to it will be overwritten without warning.
|
|
987
|
+
Do NOT manually edit this file or your changes will be lost.
|
|
988
|
+
*/
|
|
989
|
+
`,
|
|
990
|
+
`import type { HandlerLike, Route } from "@marko/run";
|
|
991
|
+
`
|
|
992
|
+
);
|
|
993
|
+
const routesWriter = writer.branch("types");
|
|
994
|
+
const middlewareRouteTypes = /* @__PURE__ */ new Map();
|
|
995
|
+
for (const route of routes.list) {
|
|
996
|
+
const { meta, handler, params, middleware } = route;
|
|
997
|
+
const routeType = `Route${route.index}`;
|
|
998
|
+
const pathType = `\`${route.path.replace(
|
|
999
|
+
/\/\$(\$?)([^\/]*)/,
|
|
1000
|
+
(_, catchAll, name) => catchAll ? `/:${name || "rest"}*` : `/:${name}`
|
|
1001
|
+
)}\``;
|
|
1002
|
+
const paramsType = params ? renderParamsInfoType(params) : "{}";
|
|
1003
|
+
let metaType = "undefined";
|
|
1004
|
+
if (meta) {
|
|
1005
|
+
metaType = `typeof import('${pathPrefix}/${stripTsExtension(
|
|
1006
|
+
meta.relativePath
|
|
1007
|
+
)}')`;
|
|
1008
|
+
if (/\.(ts|js|mjs)$/.test(meta.relativePath)) {
|
|
1009
|
+
metaType += `['default']`;
|
|
1010
|
+
}
|
|
1011
|
+
}
|
|
1012
|
+
if (handler) {
|
|
1013
|
+
writeRouteTypeModule(writer, pathPrefix, handler.relativePath, routeType);
|
|
1014
|
+
}
|
|
1015
|
+
if (middleware) {
|
|
1016
|
+
let i = 0;
|
|
1017
|
+
for (const mw of middleware) {
|
|
1018
|
+
const existing = middlewareRouteTypes.get(mw);
|
|
1019
|
+
if (!existing) {
|
|
1020
|
+
middlewareRouteTypes.set(mw, {
|
|
1021
|
+
routeTypes: [routeType],
|
|
1022
|
+
middleware: middleware.slice(0, i)
|
|
1023
|
+
});
|
|
1024
|
+
} else {
|
|
1025
|
+
existing.routeTypes.push(routeType);
|
|
1026
|
+
}
|
|
1027
|
+
i++;
|
|
1028
|
+
}
|
|
1029
|
+
}
|
|
1030
|
+
routesWriter.writeLines(
|
|
1031
|
+
`interface ${routeType} extends Route<${paramsType}, ${metaType}, ${pathType}> {}`
|
|
1032
|
+
);
|
|
1033
|
+
}
|
|
1034
|
+
for (const [file, { routeTypes }] of middlewareRouteTypes) {
|
|
1035
|
+
const routeType = routeTypes.length > 1 ? routeTypes.join(" | ") : routeTypes[0];
|
|
1036
|
+
writeRouteTypeModule(writer, pathPrefix, file.relativePath, routeType);
|
|
1037
|
+
}
|
|
1038
|
+
return writer.end();
|
|
1039
|
+
}
|
|
1040
|
+
function writeRouteTypeModule(writer, pathPrefix, path3, routeType) {
|
|
1041
|
+
writer.writeLines(`
|
|
1042
|
+
declare module '${pathPrefix}/${stripTsExtension(path3)}' {
|
|
1043
|
+
namespace Marko {
|
|
1044
|
+
type CurrentRoute = ${routeType};
|
|
1045
|
+
type Handler<_Params = CurrentRoute['params'], _Meta = CurrentRoute['meta']> = HandlerLike<CurrentRoute>;
|
|
1046
|
+
function route(handler: Handler): typeof handler;
|
|
1047
|
+
function route<_Params = CurrentRoute['params'], _Meta = CurrentRoute['meta']>(handler: Handler): typeof handler;
|
|
863
1048
|
}
|
|
864
|
-
|
|
1049
|
+
}`);
|
|
865
1050
|
}
|
|
866
1051
|
|
|
867
1052
|
// src/vite/utils/ast.ts
|
|
@@ -908,7 +1093,7 @@ function getExportIdentifiers(astProgramNode) {
|
|
|
908
1093
|
var import_cli_table3 = __toESM(require("cli-table3"), 1);
|
|
909
1094
|
var import_kleur = __toESM(require("kleur"), 1);
|
|
910
1095
|
var import_gzip_size = require("gzip-size");
|
|
911
|
-
var
|
|
1096
|
+
var import_human_format = __toESM(require("human-format"), 1);
|
|
912
1097
|
var HttpVerbColors = {
|
|
913
1098
|
get: import_kleur.default.green,
|
|
914
1099
|
post: import_kleur.default.magenta,
|
|
@@ -935,7 +1120,7 @@ function logRoutesTable(routes, bundle) {
|
|
|
935
1120
|
headings.push("Meta");
|
|
936
1121
|
colAligns.push("center");
|
|
937
1122
|
}
|
|
938
|
-
headings.push("Size");
|
|
1123
|
+
headings.push("Size/GZip");
|
|
939
1124
|
colAligns.push("right");
|
|
940
1125
|
const table = new import_cli_table3.default({
|
|
941
1126
|
head: headings.map((title) => import_kleur.default.bold(import_kleur.default.white(title.toUpperCase()))),
|
|
@@ -966,7 +1151,7 @@ function logRoutesTable(routes, bundle) {
|
|
|
966
1151
|
row.push(entryType.join(" -> "));
|
|
967
1152
|
hasMiddleware && row.push(route.middleware.length || "");
|
|
968
1153
|
hasMeta && row.push(route.meta ? "\u2713" : "");
|
|
969
|
-
row.push(size ||
|
|
1154
|
+
row.push(size || "");
|
|
970
1155
|
table.push(row);
|
|
971
1156
|
}
|
|
972
1157
|
}
|
|
@@ -982,36 +1167,52 @@ function logRoutesTable(routes, bundle) {
|
|
|
982
1167
|
function computeRouteSize(route, bundle) {
|
|
983
1168
|
if (route.page) {
|
|
984
1169
|
for (const chunk of Object.values(bundle)) {
|
|
985
|
-
if (chunk.type === "chunk"
|
|
986
|
-
|
|
1170
|
+
if (chunk.type === "chunk") {
|
|
1171
|
+
for (const key of Object.keys(chunk.modules)) {
|
|
1172
|
+
if (key.startsWith(route.page.filePath)) {
|
|
1173
|
+
return computeChunkSize(chunk, bundle);
|
|
1174
|
+
}
|
|
1175
|
+
}
|
|
987
1176
|
}
|
|
988
1177
|
}
|
|
989
1178
|
}
|
|
990
|
-
return 0;
|
|
1179
|
+
return [0, 0];
|
|
1180
|
+
}
|
|
1181
|
+
function byteSize(str) {
|
|
1182
|
+
return new Blob([str]).size;
|
|
991
1183
|
}
|
|
992
1184
|
function computeChunkSize(chunk, bundle, seen = /* @__PURE__ */ new Set()) {
|
|
993
1185
|
if (chunk.type === "asset") {
|
|
994
|
-
return
|
|
1186
|
+
return [
|
|
1187
|
+
byteSize(chunk.source),
|
|
1188
|
+
(0, import_gzip_size.gzipSizeSync)(chunk.source)
|
|
1189
|
+
];
|
|
995
1190
|
}
|
|
996
|
-
|
|
1191
|
+
const size = [byteSize(chunk.code), (0, import_gzip_size.gzipSizeSync)(chunk.code)];
|
|
997
1192
|
for (const id of chunk.imports) {
|
|
998
1193
|
if (!seen.has(id)) {
|
|
999
|
-
|
|
1194
|
+
const [bytes, compBytes] = computeChunkSize(bundle[id], bundle, seen);
|
|
1195
|
+
size[0] += bytes;
|
|
1196
|
+
size[1] += compBytes;
|
|
1000
1197
|
seen.add(id);
|
|
1001
1198
|
}
|
|
1002
1199
|
}
|
|
1003
1200
|
return size;
|
|
1004
1201
|
}
|
|
1005
|
-
function prettySize(
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
if (
|
|
1013
|
-
|
|
1014
|
-
|
|
1202
|
+
function prettySize([bytes, compBytes]) {
|
|
1203
|
+
if (bytes <= 0) {
|
|
1204
|
+
return import_kleur.default.gray("0.0 kB");
|
|
1205
|
+
}
|
|
1206
|
+
const [size, prefix] = (0, import_human_format.default)(bytes, { decimals: 1 }).split(/\s+/);
|
|
1207
|
+
const compSize = (0, import_human_format.default)(compBytes, { decimals: 1, prefix, unit: "B" });
|
|
1208
|
+
let str = import_kleur.default.white(size) + import_kleur.default.gray("/");
|
|
1209
|
+
if (compBytes < 20 * 1e3)
|
|
1210
|
+
str += import_kleur.default.green(compSize);
|
|
1211
|
+
else if (compBytes < 50 * 1e3)
|
|
1212
|
+
str += import_kleur.default.yellow(compSize);
|
|
1213
|
+
else
|
|
1214
|
+
import_kleur.default.bold(import_kleur.default.red(compSize));
|
|
1215
|
+
return str;
|
|
1015
1216
|
}
|
|
1016
1217
|
function prettyPath(path3) {
|
|
1017
1218
|
return path3.replace(/\/\$\$(.*)$/, (_, p) => "/" + import_kleur.default.bold(import_kleur.default.dim(`*${p}`))).replace(/\/\$([^/]+)/g, (_, p) => "/" + import_kleur.default.bold(import_kleur.default.dim(`:${p}`)));
|
|
@@ -1019,17 +1220,19 @@ function prettyPath(path3) {
|
|
|
1019
1220
|
|
|
1020
1221
|
// src/vite/utils/config.ts
|
|
1021
1222
|
var KEY = "__MARKO_SERVE_OPTIONS__";
|
|
1022
|
-
function
|
|
1223
|
+
function getMarkoRunOptions(viteConfig) {
|
|
1023
1224
|
return viteConfig[KEY];
|
|
1024
1225
|
}
|
|
1025
|
-
function
|
|
1226
|
+
function setMarkoRunOptions(viteConfig, options) {
|
|
1026
1227
|
viteConfig[KEY] = options;
|
|
1027
1228
|
return viteConfig;
|
|
1028
1229
|
}
|
|
1029
1230
|
|
|
1030
1231
|
// src/vite/plugin.ts
|
|
1232
|
+
var import_url = require("url");
|
|
1233
|
+
var import_meta = {};
|
|
1234
|
+
var __dirname = (0, import_url.fileURLToPath)(new URL(".", import_meta.url));
|
|
1031
1235
|
var markoExt = ".marko";
|
|
1032
|
-
var markoServeFilePrefix2 = "__marko-serve__";
|
|
1033
1236
|
function isMarkoFile(id) {
|
|
1034
1237
|
return id.endsWith(markoExt);
|
|
1035
1238
|
}
|
|
@@ -1038,8 +1241,10 @@ function markoServe(opts = {}) {
|
|
|
1038
1241
|
let store;
|
|
1039
1242
|
let root;
|
|
1040
1243
|
let resolvedRoutesDir;
|
|
1244
|
+
let typesDir;
|
|
1041
1245
|
let isBuild = false;
|
|
1042
1246
|
let isSSRBuild = false;
|
|
1247
|
+
let tsConfigExists;
|
|
1043
1248
|
let ssrEntryFiles;
|
|
1044
1249
|
let devEntryFile;
|
|
1045
1250
|
let devServer;
|
|
@@ -1048,6 +1253,7 @@ function markoServe(opts = {}) {
|
|
|
1048
1253
|
let routeDataFilename = "routes.json";
|
|
1049
1254
|
let extractVerbs;
|
|
1050
1255
|
let resolvedConfig;
|
|
1256
|
+
let typesFile;
|
|
1051
1257
|
let isStale = true;
|
|
1052
1258
|
let isRendered = false;
|
|
1053
1259
|
const virtualFiles = /* @__PURE__ */ new Map();
|
|
@@ -1055,6 +1261,22 @@ function markoServe(opts = {}) {
|
|
|
1055
1261
|
routesBuild: 0,
|
|
1056
1262
|
routesRender: 0
|
|
1057
1263
|
};
|
|
1264
|
+
async function writeTypesFile() {
|
|
1265
|
+
if (tsConfigExists ?? (tsConfigExists = await globFileExists(
|
|
1266
|
+
root,
|
|
1267
|
+
"{.tsconfig*,tsconfig*.json}"
|
|
1268
|
+
))) {
|
|
1269
|
+
const filepath = import_path2.default.join(typesDir, "routes.d.ts");
|
|
1270
|
+
const data = renderRouteTypeInfo(
|
|
1271
|
+
routes,
|
|
1272
|
+
import_path2.default.relative(typesDir, routesDir)
|
|
1273
|
+
);
|
|
1274
|
+
if (data !== typesFile || !import_fs2.default.existsSync(filepath)) {
|
|
1275
|
+
await ensureDir(typesDir);
|
|
1276
|
+
await import_fs2.default.promises.writeFile(filepath, typesFile = data);
|
|
1277
|
+
}
|
|
1278
|
+
}
|
|
1279
|
+
}
|
|
1058
1280
|
async function setVirtualFiles(render = false) {
|
|
1059
1281
|
for (const route of routes.list) {
|
|
1060
1282
|
if (render && route.handler) {
|
|
@@ -1067,31 +1289,37 @@ function markoServe(opts = {}) {
|
|
|
1067
1289
|
}
|
|
1068
1290
|
if (route.page) {
|
|
1069
1291
|
virtualFiles.set(
|
|
1070
|
-
import_path2.default.join(root, `${
|
|
1292
|
+
import_path2.default.join(root, `${markoRunFilePrefix}route__${route.key}.marko`),
|
|
1071
1293
|
render ? renderRouteTemplate(route) : ""
|
|
1072
1294
|
);
|
|
1073
1295
|
}
|
|
1074
1296
|
virtualFiles.set(
|
|
1075
|
-
import_path2.default.join(root, `${
|
|
1297
|
+
import_path2.default.join(root, `${markoRunFilePrefix}route__${route.key}.js`),
|
|
1076
1298
|
render ? renderRouteEntry(route) : ""
|
|
1077
1299
|
);
|
|
1078
1300
|
}
|
|
1079
1301
|
for (const route of Object.values(routes.special)) {
|
|
1080
1302
|
virtualFiles.set(
|
|
1081
|
-
import_path2.default.join(root, `${
|
|
1303
|
+
import_path2.default.join(root, `${markoRunFilePrefix}special__${route.key}.marko`),
|
|
1082
1304
|
render ? renderRouteTemplate(route) : ""
|
|
1083
1305
|
);
|
|
1084
1306
|
}
|
|
1085
1307
|
virtualFiles.set(
|
|
1086
1308
|
"@marko/run/router",
|
|
1087
|
-
render ? renderRouter(routes,
|
|
1309
|
+
render ? renderRouter(routes, {
|
|
1310
|
+
trailingSlashes: opts.trailingSlashes || "RedirectWithout"
|
|
1311
|
+
}) : ""
|
|
1312
|
+
);
|
|
1313
|
+
virtualFiles.set(
|
|
1314
|
+
import_path2.default.join(root, `${markoRunFilePrefix}middleware.js`),
|
|
1315
|
+
render ? renderMiddleware(routes.middleware) : ""
|
|
1088
1316
|
);
|
|
1089
1317
|
}
|
|
1090
1318
|
const buildVirtualFiles = single(async () => {
|
|
1091
1319
|
const startTime = performance.now();
|
|
1092
1320
|
routes = await buildRoutes(createFSWalker(resolvedRoutesDir), routesDir);
|
|
1093
1321
|
times.routesBuild = performance.now() - startTime;
|
|
1094
|
-
await setVirtualFiles(false);
|
|
1322
|
+
await Promise.all([writeTypesFile(), setVirtualFiles(false)]);
|
|
1095
1323
|
isStale = false;
|
|
1096
1324
|
isRendered = false;
|
|
1097
1325
|
});
|
|
@@ -1105,9 +1333,9 @@ function markoServe(opts = {}) {
|
|
|
1105
1333
|
{
|
|
1106
1334
|
name: "marko-run-vite:pre",
|
|
1107
1335
|
enforce: "pre",
|
|
1108
|
-
async config(
|
|
1336
|
+
async config(config2, env) {
|
|
1109
1337
|
var _a, _b, _c;
|
|
1110
|
-
const externalPluginOptions =
|
|
1338
|
+
const externalPluginOptions = getMarkoRunOptions(config2);
|
|
1111
1339
|
if (externalPluginOptions) {
|
|
1112
1340
|
opts = (0, import_vite.mergeConfig)(opts, externalPluginOptions);
|
|
1113
1341
|
}
|
|
@@ -1115,13 +1343,14 @@ function markoServe(opts = {}) {
|
|
|
1115
1343
|
if (adapterOptions) {
|
|
1116
1344
|
opts = (0, import_vite.mergeConfig)(opts, adapterOptions);
|
|
1117
1345
|
}
|
|
1118
|
-
root = (0, import_vite.normalizePath)(
|
|
1346
|
+
root = (0, import_vite.normalizePath)(config2.root || process.cwd());
|
|
1119
1347
|
store = opts.store || new import_vite2.FileStore(
|
|
1120
1348
|
`marko-serve-vite-${import_crypto.default.createHash("SHA1").update(root).digest("hex")}`
|
|
1121
1349
|
);
|
|
1122
1350
|
isBuild = env.command === "build";
|
|
1123
|
-
isSSRBuild = isBuild && Boolean((_b =
|
|
1351
|
+
isSSRBuild = isBuild && Boolean((_b = config2.build) == null ? void 0 : _b.ssr);
|
|
1124
1352
|
resolvedRoutesDir = import_path2.default.resolve(root, routesDir);
|
|
1353
|
+
typesDir = import_path2.default.join(root, ".marko-run");
|
|
1125
1354
|
devEntryFile = import_path2.default.join(root, "index.html");
|
|
1126
1355
|
let pluginConfig = {
|
|
1127
1356
|
logLevel: isBuild ? "warn" : void 0,
|
|
@@ -1132,18 +1361,18 @@ function markoServe(opts = {}) {
|
|
|
1132
1361
|
emptyOutDir: isSSRBuild
|
|
1133
1362
|
}
|
|
1134
1363
|
};
|
|
1135
|
-
const adapterConfig = await ((_c = adapter == null ? void 0 : adapter.viteConfig) == null ? void 0 : _c.call(adapter,
|
|
1364
|
+
const adapterConfig = await ((_c = adapter == null ? void 0 : adapter.viteConfig) == null ? void 0 : _c.call(adapter, config2));
|
|
1136
1365
|
if (adapterConfig) {
|
|
1137
1366
|
pluginConfig = (0, import_vite.mergeConfig)(pluginConfig, adapterConfig);
|
|
1138
1367
|
}
|
|
1139
|
-
return
|
|
1368
|
+
return setMarkoRunOptions(pluginConfig, opts);
|
|
1140
1369
|
},
|
|
1141
|
-
configResolved(
|
|
1142
|
-
resolvedConfig =
|
|
1370
|
+
configResolved(config2) {
|
|
1371
|
+
resolvedConfig = config2;
|
|
1143
1372
|
const {
|
|
1144
1373
|
ssr,
|
|
1145
1374
|
rollupOptions: { input }
|
|
1146
|
-
} =
|
|
1375
|
+
} = config2.build;
|
|
1147
1376
|
if (typeof ssr === "string") {
|
|
1148
1377
|
ssrEntryFiles = [ssr];
|
|
1149
1378
|
} else if (typeof input === "string") {
|
|
@@ -1174,6 +1403,7 @@ function markoServe(opts = {}) {
|
|
|
1174
1403
|
if (isStale) {
|
|
1175
1404
|
for (const id of virtualFiles.keys()) {
|
|
1176
1405
|
devServer.watcher.emit("change", id);
|
|
1406
|
+
break;
|
|
1177
1407
|
}
|
|
1178
1408
|
}
|
|
1179
1409
|
}
|
|
@@ -1203,12 +1433,18 @@ function markoServe(opts = {}) {
|
|
|
1203
1433
|
},
|
|
1204
1434
|
async resolveId(importee, importer, { ssr }) {
|
|
1205
1435
|
let resolved;
|
|
1206
|
-
if (importee.startsWith(
|
|
1436
|
+
if (importee.startsWith(virtualRuntimePrefix)) {
|
|
1437
|
+
return this.resolve(
|
|
1438
|
+
import_path2.default.resolve(__dirname, "../runtime/internal"),
|
|
1439
|
+
importer,
|
|
1440
|
+
{ skipSelf: true }
|
|
1441
|
+
);
|
|
1442
|
+
} else if (importee.startsWith(virtualFilePrefix)) {
|
|
1207
1443
|
importee = import_path2.default.resolve(
|
|
1208
1444
|
root,
|
|
1209
1445
|
importee.slice(virtualFilePrefix.length + 1)
|
|
1210
1446
|
);
|
|
1211
|
-
} else if (!isBuild && importer === devEntryFile && importee.startsWith(`/${
|
|
1447
|
+
} else if (!isBuild && importer === devEntryFile && importee.startsWith(`/${markoRunFilePrefix}`)) {
|
|
1212
1448
|
importee = import_path2.default.resolve(root, "." + importee);
|
|
1213
1449
|
}
|
|
1214
1450
|
if (isStale) {
|
|
@@ -1330,20 +1566,49 @@ function single(fn) {
|
|
|
1330
1566
|
return result;
|
|
1331
1567
|
};
|
|
1332
1568
|
}
|
|
1569
|
+
async function globFileExists(root, pattern) {
|
|
1570
|
+
return new Promise((resolve, reject) => {
|
|
1571
|
+
(0, import_glob.default)(pattern, { root }, (err, matches) => {
|
|
1572
|
+
if (err) {
|
|
1573
|
+
reject(err);
|
|
1574
|
+
}
|
|
1575
|
+
resolve(matches.length > 0);
|
|
1576
|
+
});
|
|
1577
|
+
});
|
|
1578
|
+
}
|
|
1579
|
+
async function ensureDir(dir) {
|
|
1580
|
+
if (!import_fs2.default.existsSync(dir)) {
|
|
1581
|
+
await import_fs2.default.promises.mkdir(dir, { recursive: true });
|
|
1582
|
+
}
|
|
1583
|
+
}
|
|
1333
1584
|
|
|
1334
1585
|
// src/vite/utils/server.ts
|
|
1335
1586
|
var import_net = __toESM(require("net"), 1);
|
|
1336
1587
|
var import_child_process = __toESM(require("child_process"), 1);
|
|
1337
|
-
|
|
1588
|
+
var import_dotenv = require("dotenv");
|
|
1589
|
+
var import_fs3 = __toESM(require("fs"), 1);
|
|
1590
|
+
async function parseEnv(envFile) {
|
|
1591
|
+
if (import_fs3.default.existsSync(envFile)) {
|
|
1592
|
+
const content = await import_fs3.default.promises.readFile(envFile, "utf8");
|
|
1593
|
+
return (0, import_dotenv.parse)(content);
|
|
1594
|
+
}
|
|
1595
|
+
}
|
|
1596
|
+
function loadEnv(envFile) {
|
|
1597
|
+
(0, import_dotenv.config)({ path: envFile });
|
|
1598
|
+
}
|
|
1599
|
+
async function spawnServer(cmd, port = 0, env, cwd = process.cwd(), wait = 3e4) {
|
|
1338
1600
|
if (port <= 0) {
|
|
1339
1601
|
port = await getAvailablePort();
|
|
1340
1602
|
}
|
|
1603
|
+
if (typeof env === "string") {
|
|
1604
|
+
env = await parseEnv(env);
|
|
1605
|
+
}
|
|
1341
1606
|
const proc = import_child_process.default.spawn(cmd, {
|
|
1342
1607
|
cwd,
|
|
1343
1608
|
shell: true,
|
|
1344
1609
|
stdio: "inherit",
|
|
1345
1610
|
windowsHide: true,
|
|
1346
|
-
env: { NODE_ENV: "development", ...process.env, PORT: `${port}` }
|
|
1611
|
+
env: { ...env, NODE_ENV: "development", ...process.env, PORT: `${port}` }
|
|
1347
1612
|
});
|
|
1348
1613
|
const close = () => {
|
|
1349
1614
|
proc.unref();
|
|
@@ -1390,5 +1655,7 @@ function sleep(ms) {
|
|
|
1390
1655
|
0 && (module.exports = {
|
|
1391
1656
|
getAvailablePort,
|
|
1392
1657
|
isPortInUse,
|
|
1658
|
+
loadEnv,
|
|
1659
|
+
parseEnv,
|
|
1393
1660
|
spawnServer
|
|
1394
1661
|
});
|