@marko/run 0.0.1-beta6 → 0.0.1-beta7
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 +32 -32
- package/dist/adapter/default-entry.mjs +8 -5
- package/dist/adapter/index.cjs +24 -41
- package/dist/adapter/index.js +24 -41
- package/dist/adapter/middleware.cjs +22 -38
- package/dist/adapter/middleware.d.ts +2 -2
- package/dist/adapter/middleware.js +21 -38
- package/dist/runtime/index.d.ts +7 -3
- package/dist/runtime/internal.cjs +16 -13
- package/dist/runtime/internal.d.ts +2 -2
- package/dist/runtime/internal.js +14 -11
- package/dist/runtime/router.cjs +9 -9
- package/dist/runtime/router.d.ts +3 -4
- package/dist/runtime/router.js +6 -6
- package/dist/runtime/types.d.ts +11 -9
- package/dist/vite/codegen/index.d.ts +1 -1
- package/dist/vite/index.cjs +82 -57
- package/dist/vite/index.js +82 -57
- package/package.json +1 -1
package/dist/vite/index.js
CHANGED
|
@@ -123,7 +123,14 @@ async function buildRoutes(walk, basePath) {
|
|
|
123
123
|
if (handler || page) {
|
|
124
124
|
const key = path3.replace(/(\$\$?)[^\/]*/g, "$1").replace(/^\/+/, "").replace(/[^a-z0-9_$\/]+/gi, "").replace(/\//g, "__") || "index";
|
|
125
125
|
if (routes.has(key)) {
|
|
126
|
-
|
|
126
|
+
const existing = routes.get(key);
|
|
127
|
+
const existingFiles = [existing.handler, existing.page].filter(Boolean).map((f) => f.filePath);
|
|
128
|
+
const currentFiles = [handler, page].filter(Boolean).map((f) => f.filePath);
|
|
129
|
+
throw new Error(`Duplicate routes for path ${path3} were defined. A route established by:
|
|
130
|
+
${existingFiles}
|
|
131
|
+
collides with
|
|
132
|
+
${currentFiles.join(" and ")}
|
|
133
|
+
`);
|
|
127
134
|
} else {
|
|
128
135
|
const index = nextRouteIndex++;
|
|
129
136
|
routes.set(key, {
|
|
@@ -171,14 +178,16 @@ async function buildRoutes(walk, basePath) {
|
|
|
171
178
|
const prevChildren = children;
|
|
172
179
|
const prevCurrent = current;
|
|
173
180
|
const prevIsRoot = isRoot;
|
|
174
|
-
if (name.charCodeAt(0) === 95
|
|
181
|
+
if (name.charCodeAt(0) === 95) {
|
|
175
182
|
} else {
|
|
176
183
|
if (name.charCodeAt(0) === 36) {
|
|
177
184
|
if (name.charCodeAt(1) === 36) {
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
185
|
+
if (name.length > 2) {
|
|
186
|
+
paramStack.push({
|
|
187
|
+
name: name.slice(2),
|
|
188
|
+
index: -1
|
|
189
|
+
});
|
|
190
|
+
}
|
|
182
191
|
} else if (name.length > 1) {
|
|
183
192
|
paramStack.push({
|
|
184
193
|
name: name.slice(1),
|
|
@@ -497,7 +506,7 @@ function renderRouteEntry(route) {
|
|
|
497
506
|
);
|
|
498
507
|
}
|
|
499
508
|
if (middleware.length) {
|
|
500
|
-
const names = middleware.map((m) => `mware
|
|
509
|
+
const names = middleware.map((m) => `mware${m.id}`);
|
|
501
510
|
imports.writeLines(
|
|
502
511
|
`import { ${names.join(
|
|
503
512
|
", "
|
|
@@ -508,9 +517,9 @@ function renderRouteEntry(route) {
|
|
|
508
517
|
writer.writeLines("");
|
|
509
518
|
const names = [];
|
|
510
519
|
for (const verb of handler.verbs) {
|
|
511
|
-
const
|
|
512
|
-
names.push(
|
|
513
|
-
writer.writeLines(`const
|
|
520
|
+
const importName = verb.toUpperCase();
|
|
521
|
+
names.push(importName);
|
|
522
|
+
writer.writeLines(`const ${verb}Handler = normalize(${importName});`);
|
|
514
523
|
}
|
|
515
524
|
imports.writeLines(
|
|
516
525
|
`import { ${names.join(", ")} } from './${handler.importPath}';`
|
|
@@ -523,7 +532,7 @@ function renderRouteEntry(route) {
|
|
|
523
532
|
}
|
|
524
533
|
if (meta) {
|
|
525
534
|
imports.writeLines(
|
|
526
|
-
`export { default as meta
|
|
535
|
+
`export { default as meta${index} } from './${meta.importPath}';`
|
|
527
536
|
);
|
|
528
537
|
}
|
|
529
538
|
for (const verb of verbs) {
|
|
@@ -554,14 +563,19 @@ function writeRouteEntryHandler(writer, route, verb) {
|
|
|
554
563
|
let nextName;
|
|
555
564
|
let currentName;
|
|
556
565
|
let hasBody = false;
|
|
557
|
-
writer.writeLines("")
|
|
558
|
-
|
|
559
|
-
|
|
566
|
+
writer.writeLines("");
|
|
567
|
+
if (page) {
|
|
568
|
+
writer.writeBlockStart(
|
|
569
|
+
`export async function ${verb}${index}(context, buildInput) {`
|
|
570
|
+
);
|
|
571
|
+
} else {
|
|
572
|
+
writer.writeBlockStart(`export async function ${verb}${index}(context) {`);
|
|
573
|
+
}
|
|
560
574
|
const continuations = writer.branch("cont");
|
|
561
575
|
if (page && verb === "get") {
|
|
562
576
|
currentName = "__page";
|
|
563
577
|
if ((_a = handler == null ? void 0 : handler.verbs) == null ? void 0 : _a.includes(verb)) {
|
|
564
|
-
const name =
|
|
578
|
+
const name = `${verb}Handler`;
|
|
565
579
|
writePageResponse(continuations, currentName);
|
|
566
580
|
if (len) {
|
|
567
581
|
nextName = currentName;
|
|
@@ -579,7 +593,7 @@ function writeRouteEntryHandler(writer, route, verb) {
|
|
|
579
593
|
hasBody = true;
|
|
580
594
|
}
|
|
581
595
|
} else if (handler) {
|
|
582
|
-
const name =
|
|
596
|
+
const name = `${verb}Handler`;
|
|
583
597
|
currentName = `__${name}`;
|
|
584
598
|
nextName = "noContent";
|
|
585
599
|
if (len) {
|
|
@@ -595,7 +609,7 @@ function writeRouteEntryHandler(writer, route, verb) {
|
|
|
595
609
|
let i = len;
|
|
596
610
|
while (i--) {
|
|
597
611
|
const { id } = middleware[i];
|
|
598
|
-
const name = `mware
|
|
612
|
+
const name = `mware${id}`;
|
|
599
613
|
nextName = currentName;
|
|
600
614
|
currentName = i ? `__${name}` : "";
|
|
601
615
|
writeMiddleware(continuations, name, nextName, currentName);
|
|
@@ -611,12 +625,12 @@ function renderRouter(routes, options = {
|
|
|
611
625
|
writer.writeLines(`// @marko/run/router`);
|
|
612
626
|
const imports = writer.branch("imports");
|
|
613
627
|
imports.writeLines(
|
|
614
|
-
`import {
|
|
628
|
+
`import { NotHandled, NotMatched, createInput } from 'virtual:marko-run/internal';`
|
|
615
629
|
);
|
|
616
630
|
for (const route of routes.list) {
|
|
617
631
|
const verbs = getVerbs(route);
|
|
618
|
-
const names = verbs.map((verb) => `${verb}
|
|
619
|
-
route.meta && names.push(`meta
|
|
632
|
+
const names = verbs.map((verb) => `${verb}${route.index}`);
|
|
633
|
+
route.meta && names.push(`meta${route.index}`);
|
|
620
634
|
imports.writeLines(
|
|
621
635
|
`import { ${names.join(
|
|
622
636
|
", "
|
|
@@ -625,10 +639,16 @@ function renderRouter(routes, options = {
|
|
|
625
639
|
}
|
|
626
640
|
for (const { key } of Object.values(routes.special)) {
|
|
627
641
|
imports.writeLines(
|
|
628
|
-
`import page
|
|
642
|
+
`import page${key} from '${virtualFilePrefix}/${markoRunFilePrefix}special__${key}.marko${serverEntryQuery}';`
|
|
629
643
|
);
|
|
630
644
|
}
|
|
631
|
-
writer.writeLines(``).writeBlockStart(`function
|
|
645
|
+
writer.writeLines(``).writeBlockStart(`export function match(method, pathname) {`).writeLines(
|
|
646
|
+
`if (!pathname) {
|
|
647
|
+
pathname = '/';
|
|
648
|
+
} else if (pathname.charAt(0) !== '/') {
|
|
649
|
+
pathname = '/' + pathname;
|
|
650
|
+
}`
|
|
651
|
+
).writeBlockStart(`switch (method.toLowerCase()) {`);
|
|
632
652
|
for (const verb of httpVerbs) {
|
|
633
653
|
const filteredRoutes = routes.list.filter((route) => hasVerb(route, verb));
|
|
634
654
|
if (filteredRoutes.length) {
|
|
@@ -640,16 +660,12 @@ function renderRouter(routes, options = {
|
|
|
640
660
|
}
|
|
641
661
|
writer.writeBlockEnd("}").writeLines("return null;").writeBlockEnd("}");
|
|
642
662
|
writer.write(`
|
|
643
|
-
export function
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
}
|
|
649
|
-
return findRoute(method, pathname);
|
|
650
|
-
}
|
|
651
|
-
|
|
652
|
-
export async function invokeRoute(route, context) {
|
|
663
|
+
export async function invoke(route, request, platform, url = new URL(request.url)) {
|
|
664
|
+
const context = {
|
|
665
|
+
url,
|
|
666
|
+
request,
|
|
667
|
+
platform
|
|
668
|
+
};
|
|
653
669
|
try {
|
|
654
670
|
const buildInput = createInput(context);
|
|
655
671
|
if (route) {
|
|
@@ -659,9 +675,9 @@ export async function invokeRoute(route, context) {
|
|
|
659
675
|
const response = await route.handler(context, buildInput);
|
|
660
676
|
if (response) return response;
|
|
661
677
|
} catch (error) {
|
|
662
|
-
if (error ===
|
|
678
|
+
if (error === NotHandled) {
|
|
663
679
|
return;
|
|
664
|
-
} else if (error !==
|
|
680
|
+
} else if (error !== NotMatched) {
|
|
665
681
|
throw error;
|
|
666
682
|
}
|
|
667
683
|
}
|
|
@@ -673,7 +689,7 @@ export async function invokeRoute(route, context) {
|
|
|
673
689
|
context.meta = {};
|
|
674
690
|
}
|
|
675
691
|
if (context.request.headers.get('Accept')?.includes('text/html')) {
|
|
676
|
-
return new Response(
|
|
692
|
+
return new Response(page404.stream(buildInput()), {
|
|
677
693
|
status: 404,
|
|
678
694
|
headers: { "content-type": "text/html;charset=UTF-8" },
|
|
679
695
|
});
|
|
@@ -689,7 +705,7 @@ export async function invokeRoute(route, context) {
|
|
|
689
705
|
writer.writeBlockStart(
|
|
690
706
|
`if (context.request.headers.get('Accept')?.includes('text/html')) {`
|
|
691
707
|
).writeBlock(
|
|
692
|
-
`return new Response(
|
|
708
|
+
`return new Response(page500.stream(buildInput({ error })), {`,
|
|
693
709
|
[
|
|
694
710
|
`status: 500,`,
|
|
695
711
|
`headers: { "content-type": "text/html;charset=UTF-8" },`
|
|
@@ -698,9 +714,9 @@ export async function invokeRoute(route, context) {
|
|
|
698
714
|
).writeBlockEnd("}");
|
|
699
715
|
}
|
|
700
716
|
writer.writeLines(`throw error;`).writeBlockEnd("}").writeBlockEnd("}").write(`
|
|
701
|
-
export async function
|
|
717
|
+
export async function fetch(request, platform) {
|
|
702
718
|
try {
|
|
703
|
-
const
|
|
719
|
+
const url = new URL(request.url);
|
|
704
720
|
let { pathname } = url;`);
|
|
705
721
|
switch (options.trailingSlashes) {
|
|
706
722
|
case "RedirectWithout":
|
|
@@ -732,8 +748,8 @@ export async function router(context) {
|
|
|
732
748
|
}
|
|
733
749
|
writer.write(`
|
|
734
750
|
|
|
735
|
-
const route =
|
|
736
|
-
return await
|
|
751
|
+
const route = match(request.method, pathname);
|
|
752
|
+
return await invoke(route, request, platform, url);
|
|
737
753
|
} catch (error) {
|
|
738
754
|
const message = import.meta.env.DEV
|
|
739
755
|
? \`Internal Server Error (\${error.message})\`
|
|
@@ -911,9 +927,9 @@ function renderParamsInfoType(params) {
|
|
|
911
927
|
}
|
|
912
928
|
function renderMatch(verb, route, pathIndex) {
|
|
913
929
|
var _a;
|
|
914
|
-
const handler = `${verb}
|
|
930
|
+
const handler = `${verb}${route.index}`;
|
|
915
931
|
const params = ((_a = route.params) == null ? void 0 : _a.length) ? renderParamsInfo(route.params, pathIndex) : "{}";
|
|
916
|
-
const meta = route.meta ? `meta
|
|
932
|
+
const meta = route.meta ? `meta${route.index}` : "{}";
|
|
917
933
|
return `{ handler: ${handler}, params: ${params}, meta: ${meta} }`;
|
|
918
934
|
}
|
|
919
935
|
function renderMiddleware(middleware) {
|
|
@@ -925,9 +941,9 @@ function renderMiddleware(middleware) {
|
|
|
925
941
|
imports.writeLines(`import { normalize } from 'virtual:marko-run/internal';`);
|
|
926
942
|
writer.writeLines("");
|
|
927
943
|
for (const { id, importPath } of middleware) {
|
|
928
|
-
const importName = `
|
|
944
|
+
const importName = `middleware${id}`;
|
|
929
945
|
imports.writeLines(`import ${importName} from './${importPath}';`);
|
|
930
|
-
writer.writeLines(`export const mware
|
|
946
|
+
writer.writeLines(`export const mware${id} = normalize(${importName});`);
|
|
931
947
|
}
|
|
932
948
|
imports.join();
|
|
933
949
|
return writer.end();
|
|
@@ -942,7 +958,7 @@ function stripTsExtension(path3) {
|
|
|
942
958
|
}
|
|
943
959
|
return path3;
|
|
944
960
|
}
|
|
945
|
-
function renderRouteTypeInfo(routes, pathPrefix = ".") {
|
|
961
|
+
function renderRouteTypeInfo(routes, pathPrefix = ".", adapterTypes = "") {
|
|
946
962
|
var _a, _b;
|
|
947
963
|
const writer = createStringWriter();
|
|
948
964
|
writer.writeLines(
|
|
@@ -950,8 +966,10 @@ function renderRouteTypeInfo(routes, pathPrefix = ".") {
|
|
|
950
966
|
WARNING: This file is automatically generated and any changes made to it will be overwritten without warning.
|
|
951
967
|
Do NOT manually edit this file or your changes will be lost.
|
|
952
968
|
*/
|
|
953
|
-
|
|
954
|
-
`import type { HandlerLike, Route, RouteContext, ValidatePath, ValidateHref } from "@marko/run"
|
|
969
|
+
`,
|
|
970
|
+
`import type { HandlerLike, Route, RouteContext, ValidatePath, ValidateHref } from "@marko/run";`,
|
|
971
|
+
adapterTypes,
|
|
972
|
+
`
|
|
955
973
|
|
|
956
974
|
declare global {
|
|
957
975
|
namespace MarkoRun {`
|
|
@@ -1021,7 +1039,7 @@ declare module '${pathPrefix}/${page.relativePath}' {
|
|
|
1021
1039
|
|
|
1022
1040
|
namespace MarkoRun {
|
|
1023
1041
|
type CurrentRoute = ${routeType};
|
|
1024
|
-
type CurrentContext = RouteContext<CurrentRoute>;
|
|
1042
|
+
type CurrentContext = RouteContext<RouteContext['platform'], CurrentRoute>;
|
|
1025
1043
|
}
|
|
1026
1044
|
}`);
|
|
1027
1045
|
}
|
|
@@ -1086,7 +1104,7 @@ declare module '${pathPrefix}/${file.relativePath}' {
|
|
|
1086
1104
|
|
|
1087
1105
|
namespace MarkoRun {
|
|
1088
1106
|
type CurrentRoute = ${routeTypes.join(" | ")};
|
|
1089
|
-
type CurrentContext = RouteContext<CurrentRoute>;
|
|
1107
|
+
type CurrentContext = RouteContext<RouteContext['platform'], CurrentRoute>;
|
|
1090
1108
|
}
|
|
1091
1109
|
}`);
|
|
1092
1110
|
}
|
|
@@ -1104,7 +1122,7 @@ declare module '${pathPrefix}/${route.page.relativePath}' {
|
|
|
1104
1122
|
|
|
1105
1123
|
namespace MarkoRun {
|
|
1106
1124
|
type CurrentRoute = Route;
|
|
1107
|
-
type CurrentContext = RouteContext<CurrentRoute>;
|
|
1125
|
+
type CurrentContext = RouteContext<RouteContext['platform'], CurrentRoute>;
|
|
1108
1126
|
}
|
|
1109
1127
|
}`);
|
|
1110
1128
|
}
|
|
@@ -1117,7 +1135,7 @@ function writeRouteTypeModule(writer, pathPrefix, path3, routeType) {
|
|
|
1117
1135
|
declare module '${pathPrefix}/${stripTsExtension(path3)}' {
|
|
1118
1136
|
namespace MarkoRun {
|
|
1119
1137
|
type CurrentRoute = ${routeType};
|
|
1120
|
-
type CurrentContext = RouteContext<CurrentRoute>;
|
|
1138
|
+
type CurrentContext = RouteContext<RouteContext['platform'], CurrentRoute>;
|
|
1121
1139
|
type Handler<_Params = CurrentRoute['params'], _Meta = CurrentRoute['meta']> = HandlerLike<CurrentRoute>;
|
|
1122
1140
|
function route(handler: Handler): typeof handler;
|
|
1123
1141
|
function route<_Params = CurrentRoute['params'], _Meta = CurrentRoute['meta']>(handler: Handler): typeof handler;
|
|
@@ -1347,7 +1365,7 @@ function markoServe(opts = {}) {
|
|
|
1347
1365
|
))) {
|
|
1348
1366
|
const filepath = path2.join(typesDir, "routes.d.ts");
|
|
1349
1367
|
const adapterTypeInfo = (adapter == null ? void 0 : adapter.writeTypeInfo) && await (adapter == null ? void 0 : adapter.writeTypeInfo());
|
|
1350
|
-
const data = renderRouteTypeInfo(routes, path2.relative(typesDir, routesDir)
|
|
1368
|
+
const data = renderRouteTypeInfo(routes, path2.relative(typesDir, routesDir), adapterTypeInfo);
|
|
1351
1369
|
if (data !== typesFile || !fs2.existsSync(filepath)) {
|
|
1352
1370
|
await ensureDir(typesDir);
|
|
1353
1371
|
await fs2.promises.writeFile(filepath, typesFile = data);
|
|
@@ -1614,8 +1632,8 @@ async function getVerbsFromFileBuild(context, filePath) {
|
|
|
1614
1632
|
if (result) {
|
|
1615
1633
|
const exportIds = getExportIdentifiers(result.ast);
|
|
1616
1634
|
for (const id of exportIds) {
|
|
1617
|
-
const verb = id
|
|
1618
|
-
if (httpVerbs.includes(verb)) {
|
|
1635
|
+
const verb = id.toLowerCase();
|
|
1636
|
+
if (id === verb.toUpperCase() && httpVerbs.includes(verb)) {
|
|
1619
1637
|
verbs.push(verb);
|
|
1620
1638
|
}
|
|
1621
1639
|
}
|
|
@@ -1626,12 +1644,19 @@ async function getVerbsFromFileDev(devServer, filePath) {
|
|
|
1626
1644
|
const verbs = [];
|
|
1627
1645
|
const result = await devServer.transformRequest(filePath, { ssr: true });
|
|
1628
1646
|
if (result && result.code) {
|
|
1629
|
-
const verbMatchReg = /__vite_ssr_exports__,\s+["'](
|
|
1647
|
+
const verbMatchReg = /__vite_ssr_exports__,\s+["'](GET|POST|PUT|DELETE)["']/gi;
|
|
1630
1648
|
let match = verbMatchReg.exec(result.code);
|
|
1631
1649
|
while (match) {
|
|
1632
|
-
const
|
|
1650
|
+
const id = match[1];
|
|
1651
|
+
const verb = id.toLowerCase();
|
|
1633
1652
|
if (httpVerbs.includes(verb)) {
|
|
1634
|
-
|
|
1653
|
+
if (id === verb.toUpperCase()) {
|
|
1654
|
+
verbs.push(verb);
|
|
1655
|
+
} else {
|
|
1656
|
+
console.warn(
|
|
1657
|
+
`Found export '${id}' in handler ${filePath} which is close to '${verb.toUpperCase()}'. Exported handlers need to be uppercase: GET, POST, PUT or DELETE.`
|
|
1658
|
+
);
|
|
1659
|
+
}
|
|
1635
1660
|
}
|
|
1636
1661
|
match = verbMatchReg.exec(result.code);
|
|
1637
1662
|
}
|