@marko/run 0.6.6 → 0.7.0
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 +70 -1
- package/dist/.tsbuildinfo +1 -1
- package/dist/adapter/index.cjs +15 -17
- package/dist/adapter/index.js +15 -17
- package/dist/cli/index.mjs +414 -403
- package/dist/runtime/internal.cjs +55 -28
- package/dist/runtime/internal.d.ts +2 -3
- package/dist/runtime/internal.js +55 -27
- package/dist/runtime/types.d.ts +8 -3
- package/dist/vite/codegen/index.d.ts +5 -6
- package/dist/vite/index.cjs +417 -412
- package/dist/vite/index.js +399 -391
- package/dist/vite/plugin.d.ts +1 -1
- package/dist/vite/routes/builder.d.ts +3 -4
- package/dist/vite/routes/vdir.d.ts +0 -1
- package/dist/vite/routes/walk.d.ts +1 -1
- package/dist/vite/types.d.ts +21 -8
- package/dist/vite/utils/fs.d.ts +1 -0
- package/dist/vite/utils/route.d.ts +1 -0
- package/package.json +3 -2
package/dist/cli/index.mjs
CHANGED
|
@@ -15,7 +15,7 @@ import sade from "sade";
|
|
|
15
15
|
|
|
16
16
|
// src/cli/commands.ts
|
|
17
17
|
import fs5 from "fs";
|
|
18
|
-
import
|
|
18
|
+
import path7 from "path";
|
|
19
19
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
20
20
|
import {
|
|
21
21
|
build as viteBuild,
|
|
@@ -29,9 +29,12 @@ import createDebug from "debug";
|
|
|
29
29
|
import { resolveToEsbuildTarget } from "esbuild-plugin-browserslist";
|
|
30
30
|
import fs3 from "fs";
|
|
31
31
|
import { glob } from "glob";
|
|
32
|
-
import
|
|
32
|
+
import path6 from "path";
|
|
33
33
|
import { fileURLToPath } from "url";
|
|
34
|
-
import {
|
|
34
|
+
import {
|
|
35
|
+
buildErrorMessage,
|
|
36
|
+
mergeConfig
|
|
37
|
+
} from "vite";
|
|
35
38
|
|
|
36
39
|
// src/adapter/utils.ts
|
|
37
40
|
import kleur from "kleur";
|
|
@@ -59,7 +62,7 @@ function prepareError(err) {
|
|
|
59
62
|
}
|
|
60
63
|
|
|
61
64
|
// src/vite/codegen/index.ts
|
|
62
|
-
import
|
|
65
|
+
import path2 from "path";
|
|
63
66
|
|
|
64
67
|
// src/vite/constants.ts
|
|
65
68
|
var markoRunFilePrefix = "__marko-run__";
|
|
@@ -84,6 +87,12 @@ var RoutableFileTypes = {
|
|
|
84
87
|
Error: "500"
|
|
85
88
|
};
|
|
86
89
|
|
|
90
|
+
// src/vite/utils/fs.ts
|
|
91
|
+
import path from "path";
|
|
92
|
+
var POSIX_SEP = "/";
|
|
93
|
+
var WINDOWS_SEP = "\\";
|
|
94
|
+
var normalizePath = path.sep === WINDOWS_SEP ? (id) => id.replace(/\\/g, POSIX_SEP) : (id) => id;
|
|
95
|
+
|
|
87
96
|
// src/vite/utils/route.ts
|
|
88
97
|
var httpVerbOrder = httpVerbs.reduce(
|
|
89
98
|
(order, verb, index) => {
|
|
@@ -107,6 +116,9 @@ function hasVerb(route, verb) {
|
|
|
107
116
|
var _a, _b;
|
|
108
117
|
return verb === "get" && !!route.page || ((_b = (_a = route.handler) == null ? void 0 : _a.verbs) == null ? void 0 : _b.includes(verb)) || verb === "head" && hasVerb(route, "get");
|
|
109
118
|
}
|
|
119
|
+
function getRouteVirtualFileName(route) {
|
|
120
|
+
return `${markoRunFilePrefix}${route.key.replace(/\//g, ".")}.js`;
|
|
121
|
+
}
|
|
110
122
|
|
|
111
123
|
// src/vite/codegen/writer.ts
|
|
112
124
|
function createWriter(sink, options) {
|
|
@@ -249,27 +261,34 @@ function createStringWriter(opts) {
|
|
|
249
261
|
}
|
|
250
262
|
|
|
251
263
|
// src/vite/codegen/index.ts
|
|
252
|
-
function
|
|
264
|
+
function normalizedRelativePath(from, to) {
|
|
265
|
+
const relativePath = normalizePath(path2.relative(from, to));
|
|
266
|
+
return relativePath.startsWith(".") ? relativePath : "./" + relativePath;
|
|
267
|
+
}
|
|
268
|
+
function renderRouteTemplate(route, rootDir) {
|
|
253
269
|
if (!route.page) {
|
|
254
270
|
throw new Error(`Route ${route.key} has no page to render`);
|
|
255
271
|
}
|
|
272
|
+
if (!route.templateFilePath) {
|
|
273
|
+
throw new Error(`Route ${route.key} has no template file path`);
|
|
274
|
+
}
|
|
256
275
|
return renderEntryTemplate(
|
|
257
|
-
route.
|
|
276
|
+
normalizedRelativePath(rootDir, route.templateFilePath),
|
|
258
277
|
[...route.layouts, route.page].map(
|
|
259
|
-
(file) =>
|
|
278
|
+
(file) => normalizedRelativePath(
|
|
279
|
+
path2.dirname(route.templateFilePath),
|
|
280
|
+
file.filePath
|
|
281
|
+
)
|
|
260
282
|
),
|
|
261
283
|
route.key === RoutableFileTypes.Error ? ["error"] : []
|
|
262
284
|
);
|
|
263
285
|
}
|
|
264
286
|
function renderEntryTemplate(name, files, pageInputs = []) {
|
|
265
|
-
if (!name) {
|
|
266
|
-
throw new Error(`Invalid argument - 'name' cannot be empty`);
|
|
267
|
-
}
|
|
268
287
|
if (!files.length) {
|
|
269
288
|
throw new Error(`Invalid argument - 'files' cannot be empty`);
|
|
270
289
|
}
|
|
271
290
|
const writer = createStringWriter();
|
|
272
|
-
writer.writeLines(`// ${name}
|
|
291
|
+
writer.writeLines(`// ${name}`);
|
|
273
292
|
writer.branch("imports");
|
|
274
293
|
writer.writeLines("");
|
|
275
294
|
writeEntryTemplateTag(writer, files, pageInputs);
|
|
@@ -279,7 +298,7 @@ function writeEntryTemplateTag(writer, [file, ...rest], pageInputs, index = 1) {
|
|
|
279
298
|
if (file) {
|
|
280
299
|
const isLast = !rest.length;
|
|
281
300
|
const tag = isLast ? "Page" : `Layout${index}`;
|
|
282
|
-
writer.branch("imports").writeLines(`import ${tag} from
|
|
301
|
+
writer.branch("imports").writeLines(`import ${tag} from "${file}";`);
|
|
283
302
|
if (isLast) {
|
|
284
303
|
const attributes = pageInputs.length ? " " + pageInputs.map((name) => `${name}=input.${name}`).join(" ") : "";
|
|
285
304
|
writer.writeLines(`<${tag}${attributes}/>`);
|
|
@@ -290,9 +309,9 @@ function writeEntryTemplateTag(writer, [file, ...rest], pageInputs, index = 1) {
|
|
|
290
309
|
}
|
|
291
310
|
}
|
|
292
311
|
}
|
|
293
|
-
function renderRouteEntry(route,
|
|
312
|
+
function renderRouteEntry(route, rootDir) {
|
|
294
313
|
var _a;
|
|
295
|
-
const { key, index, handler, page, middleware, meta
|
|
314
|
+
const { key, index, handler, page, middleware, meta } = route;
|
|
296
315
|
const verbs = getVerbs(route);
|
|
297
316
|
if (!verbs) {
|
|
298
317
|
throw new Error(
|
|
@@ -300,7 +319,7 @@ function renderRouteEntry(route, entriesDir) {
|
|
|
300
319
|
);
|
|
301
320
|
}
|
|
302
321
|
const writer = createStringWriter();
|
|
303
|
-
writer.writeLines(`// ${virtualFilePrefix}
|
|
322
|
+
writer.writeLines(`// ${virtualFilePrefix}${getRouteVirtualFileName(route)}`);
|
|
304
323
|
const imports = writer.branch("imports");
|
|
305
324
|
const runtimeImports = [];
|
|
306
325
|
if (handler) {
|
|
@@ -312,9 +331,6 @@ function renderRouteEntry(route, entriesDir) {
|
|
|
312
331
|
if (!page || verbs.some((verb) => verb !== "get" && verb !== "head")) {
|
|
313
332
|
runtimeImports.push("noContent");
|
|
314
333
|
}
|
|
315
|
-
if (page) {
|
|
316
|
-
runtimeImports.push("pageResponse");
|
|
317
|
-
}
|
|
318
334
|
if (verbs.includes("head")) {
|
|
319
335
|
runtimeImports.push("stripResponseBody");
|
|
320
336
|
}
|
|
@@ -322,7 +338,7 @@ function renderRouteEntry(route, entriesDir) {
|
|
|
322
338
|
imports.writeLines(
|
|
323
339
|
`import { ${runtimeImports.join(
|
|
324
340
|
", "
|
|
325
|
-
)} } from
|
|
341
|
+
)} } from "${virtualFilePrefix}/runtime/internal";`
|
|
326
342
|
);
|
|
327
343
|
}
|
|
328
344
|
if (middleware.length) {
|
|
@@ -330,7 +346,7 @@ function renderRouteEntry(route, entriesDir) {
|
|
|
330
346
|
imports.writeLines(
|
|
331
347
|
`import { ${names.join(
|
|
332
348
|
", "
|
|
333
|
-
)} } from
|
|
349
|
+
)} } from "${virtualFilePrefix}/${markoRunFilePrefix}middleware.js";`
|
|
334
350
|
);
|
|
335
351
|
}
|
|
336
352
|
if ((_a = handler == null ? void 0 : handler.verbs) == null ? void 0 : _a.length) {
|
|
@@ -342,18 +358,17 @@ function renderRouteEntry(route, entriesDir) {
|
|
|
342
358
|
writer.writeLines(`const ${verb}Handler = normalize(${importName});`);
|
|
343
359
|
}
|
|
344
360
|
imports.writeLines(
|
|
345
|
-
`import { ${names.join(", ")} } from
|
|
361
|
+
`import { ${names.join(", ")} } from "${normalizedRelativePath(rootDir, handler.filePath)}";`
|
|
346
362
|
);
|
|
347
363
|
}
|
|
348
364
|
if (page) {
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
imports.writeLines(`import page from '${importPath}${serverEntryQuery}';`);
|
|
365
|
+
imports.writeLines(
|
|
366
|
+
`import page from "${normalizedRelativePath(rootDir, route.templateFilePath || page.filePath)}${serverEntryQuery}";`
|
|
367
|
+
);
|
|
353
368
|
}
|
|
354
369
|
if (meta) {
|
|
355
370
|
imports.writeLines(
|
|
356
|
-
`export { default as meta${index} } from
|
|
371
|
+
`export { default as meta${index} } from "${normalizedRelativePath(rootDir, meta.filePath)}";`
|
|
357
372
|
);
|
|
358
373
|
}
|
|
359
374
|
for (const verb of verbs) {
|
|
@@ -370,9 +385,7 @@ function writeRouteEntryHandler(writer, route, verb) {
|
|
|
370
385
|
let hasBody = false;
|
|
371
386
|
writer.writeLines("");
|
|
372
387
|
if (page && (verb === "get" || verb === "head")) {
|
|
373
|
-
writer.writeBlockStart(
|
|
374
|
-
`export function ${verb}${index}(context, buildInput) {`
|
|
375
|
-
);
|
|
388
|
+
writer.writeBlockStart(`export function ${verb}${index}(context) {`);
|
|
376
389
|
} else {
|
|
377
390
|
writer.writeBlockStart(`export function ${verb}${index}(context) {`);
|
|
378
391
|
}
|
|
@@ -382,7 +395,7 @@ function writeRouteEntryHandler(writer, route, verb) {
|
|
|
382
395
|
if ((_a = handler == null ? void 0 : handler.verbs) == null ? void 0 : _a.includes(verb)) {
|
|
383
396
|
const name = `${verb}Handler`;
|
|
384
397
|
continuations.writeLines(
|
|
385
|
-
`const ${currentName} = () =>
|
|
398
|
+
`const ${currentName} = () => context.render(page, {});`
|
|
386
399
|
);
|
|
387
400
|
if (len) {
|
|
388
401
|
nextName = currentName;
|
|
@@ -401,17 +414,15 @@ function writeRouteEntryHandler(writer, route, verb) {
|
|
|
401
414
|
hasBody = true;
|
|
402
415
|
}
|
|
403
416
|
} else if (verb === "head") {
|
|
404
|
-
writer.writeLines(
|
|
405
|
-
`return stripResponseBody(get${index}(context, buildInput));`
|
|
406
|
-
);
|
|
417
|
+
writer.writeLines(`return stripResponseBody(get${index}(context));`);
|
|
407
418
|
hasBody = true;
|
|
408
419
|
} else if (len) {
|
|
409
420
|
continuations.writeLines(
|
|
410
|
-
`const ${currentName} = () =>
|
|
421
|
+
`const ${currentName} = () => context.render(page, {});`
|
|
411
422
|
);
|
|
412
423
|
nextName = currentName;
|
|
413
424
|
} else {
|
|
414
|
-
writer.writeLines(`return
|
|
425
|
+
writer.writeLines(`return context.render(page, {});`);
|
|
415
426
|
hasBody = true;
|
|
416
427
|
}
|
|
417
428
|
} else if ((_b = handler == null ? void 0 : handler.verbs) == null ? void 0 : _b.includes(verb)) {
|
|
@@ -461,7 +472,7 @@ function writeRouteEntryHandler(writer, route, verb) {
|
|
|
461
472
|
continuations.join();
|
|
462
473
|
writer.writeBlockEnd("}");
|
|
463
474
|
}
|
|
464
|
-
function renderRouter(routes,
|
|
475
|
+
function renderRouter(routes, rootDir, options = {
|
|
465
476
|
trailingSlashes: "RedirectWithout"
|
|
466
477
|
}) {
|
|
467
478
|
const writer = createStringWriter();
|
|
@@ -470,20 +481,19 @@ function renderRouter(routes, entriesDir, options = {
|
|
|
470
481
|
writer.writeLines(`// @marko/run/router`);
|
|
471
482
|
const imports = writer.branch("imports");
|
|
472
483
|
imports.writeLines(
|
|
473
|
-
`import { NotHandled, NotMatched, createContext
|
|
484
|
+
`import { NotHandled, NotMatched, createContext } from "${virtualFilePrefix}/runtime/internal";`
|
|
474
485
|
);
|
|
475
486
|
for (const route of routes.list) {
|
|
476
487
|
const verbs = getVerbs(route);
|
|
477
488
|
const names = verbs.map((verb) => `${verb}${route.index}`);
|
|
478
489
|
route.meta && names.push(`meta${route.index}`);
|
|
479
490
|
imports.writeLines(
|
|
480
|
-
`import { ${names.join(", ")} } from
|
|
491
|
+
`import { ${names.join(", ")} } from "${virtualFilePrefix}/${getRouteVirtualFileName(route)}";`
|
|
481
492
|
);
|
|
482
493
|
}
|
|
483
494
|
for (const route of Object.values(routes.special)) {
|
|
484
|
-
const importPath = route.layouts.length ? `./${path.posix.join(entriesDir, route.page.relativePath, "..", `route.${route.key}.marko`)}` : `./${route.page.importPath}`;
|
|
485
495
|
imports.writeLines(
|
|
486
|
-
`import page${route.key} from
|
|
496
|
+
`import page${route.key} from "${normalizedRelativePath(rootDir, route.templateFilePath || route.page.filePath)}${serverEntryQuery}";`
|
|
487
497
|
);
|
|
488
498
|
}
|
|
489
499
|
writer.writeLines(
|
|
@@ -491,11 +501,12 @@ function renderRouter(routes, entriesDir, options = {
|
|
|
491
501
|
globalThis.__marko_run__ = { match, fetch, invoke };
|
|
492
502
|
`
|
|
493
503
|
).writeBlockStart(`export function match(method, pathname) {`).writeLines(
|
|
494
|
-
`
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
504
|
+
`const last = pathname.length - 1;
|
|
505
|
+
return match_internal(method, last && pathname.charAt(last) === '/' ? pathname.slice(0, last) : pathname)
|
|
506
|
+
};
|
|
507
|
+
|
|
508
|
+
function match_internal(method, pathname) {
|
|
509
|
+
const len = pathname.length;`
|
|
499
510
|
).writeBlockStart(`switch (method) {`);
|
|
500
511
|
for (const verb of httpVerbs) {
|
|
501
512
|
const filteredRoutes = routes.list.filter((route) => hasVerb(route, verb));
|
|
@@ -511,13 +522,13 @@ globalThis.__marko_run__ = { match, fetch, invoke };
|
|
|
511
522
|
writer.writeLines("").writeBlockStart(
|
|
512
523
|
"export async function invoke(route, request, platform, url) {"
|
|
513
524
|
).writeLines(
|
|
514
|
-
"const
|
|
525
|
+
"const context = createContext(route, request, platform, url);"
|
|
515
526
|
);
|
|
516
527
|
if (hasErrorPage) {
|
|
517
528
|
writer.writeBlockStart("try {");
|
|
518
529
|
}
|
|
519
530
|
writer.writeBlockStart("if (route) {").writeBlockStart("try {").writeLines(
|
|
520
|
-
"const response = await route.handler(context
|
|
531
|
+
"const response = await route.handler(context);",
|
|
521
532
|
"if (response) return response;"
|
|
522
533
|
).indent--;
|
|
523
534
|
writer.writeBlockStart("} catch (error) {").writeLines(
|
|
@@ -534,7 +545,7 @@ const page404ResponseInit = {
|
|
|
534
545
|
);
|
|
535
546
|
writer.write(`
|
|
536
547
|
if (context.request.headers.get('Accept')?.includes('text/html')) {
|
|
537
|
-
return
|
|
548
|
+
return context.render(page404, {}, page404ResponseInit);
|
|
538
549
|
}`);
|
|
539
550
|
}
|
|
540
551
|
writer.indent--;
|
|
@@ -551,7 +562,7 @@ const page500ResponseInit = {
|
|
|
551
562
|
writer.writeBlockStart(`} catch (error) {`).writeBlockStart(
|
|
552
563
|
`if (context.request.headers.get('Accept')?.includes('text/html')) {`
|
|
553
564
|
).writeLines(
|
|
554
|
-
`return
|
|
565
|
+
`return context.render(page500, { error }, page500ResponseInit);`
|
|
555
566
|
).writeBlockEnd("}").writeLines("throw error;").writeBlockEnd("}");
|
|
556
567
|
}
|
|
557
568
|
writer.writeBlockEnd("}");
|
|
@@ -563,38 +574,40 @@ function renderFetch(writer, options) {
|
|
|
563
574
|
export async function fetch(request, platform) {
|
|
564
575
|
try {
|
|
565
576
|
const url = new URL(request.url);
|
|
566
|
-
|
|
577
|
+
const { pathname } = url;
|
|
578
|
+
const last = pathname.length - 1;
|
|
579
|
+
const hasTrailingSlash = last && pathname.charAt(last) === '/';
|
|
580
|
+
const normalizedPathname = hasTrailingSlash ? pathname.slice(0, last) : pathname;
|
|
581
|
+
const route = match_internal(request.method, normalizedPathname);`);
|
|
567
582
|
switch (options.trailingSlashes) {
|
|
568
583
|
case "RedirectWithout":
|
|
569
584
|
writer.write(`
|
|
570
|
-
if (
|
|
571
|
-
url.pathname =
|
|
585
|
+
if (route && hasTrailingSlash) {
|
|
586
|
+
url.pathname = normalizedPathname
|
|
572
587
|
return Response.redirect(url);
|
|
573
588
|
}`);
|
|
574
589
|
break;
|
|
575
590
|
case "RedirectWith":
|
|
576
591
|
writer.write(`
|
|
577
|
-
if (pathname !== '/' && !
|
|
578
|
-
url.pathname
|
|
592
|
+
if (route && pathname !== '/' && !hasTrailingSlash) {
|
|
593
|
+
url.pathname += '/';
|
|
579
594
|
return Response.redirect(url);
|
|
580
595
|
}`);
|
|
581
596
|
break;
|
|
582
597
|
case "RewriteWithout":
|
|
583
598
|
writer.write(`
|
|
584
|
-
if (
|
|
585
|
-
url.pathname =
|
|
599
|
+
if (route && hasTrailingSlash) {
|
|
600
|
+
url.pathname = normalizedPathname;
|
|
586
601
|
}`);
|
|
587
602
|
break;
|
|
588
603
|
case "RewriteWith":
|
|
589
604
|
writer.write(`
|
|
590
|
-
if (pathname !== '/' && !
|
|
591
|
-
url.pathname
|
|
605
|
+
if (route && pathname !== '/' && !hasTrailingSlash) {
|
|
606
|
+
url.pathname += '/';
|
|
592
607
|
}`);
|
|
593
608
|
break;
|
|
594
609
|
}
|
|
595
610
|
writer.write(`
|
|
596
|
-
|
|
597
|
-
const route = match(request.method, pathname);
|
|
598
611
|
return await invoke(route, request, platform, url);
|
|
599
612
|
} catch (error) {
|
|
600
613
|
if (import.meta.env.DEV) {
|
|
@@ -610,10 +623,9 @@ function writeRouterVerb(writer, trie, verb, level = 0, offset = 1) {
|
|
|
610
623
|
const { route, dynamic, catchAll } = trie;
|
|
611
624
|
let closeCount = 0;
|
|
612
625
|
if (level === 0) {
|
|
613
|
-
writer.writeLines(`const len = pathname.length;`);
|
|
614
626
|
if (route) {
|
|
615
627
|
writer.writeLines(
|
|
616
|
-
`if (len === 1) return ${renderMatch(verb, route, trie.path)}
|
|
628
|
+
`if (len === 1) return ${renderMatch(verb, route, trie.path)};`
|
|
617
629
|
);
|
|
618
630
|
} else if (trie.static || dynamic) {
|
|
619
631
|
writer.writeBlockStart(`if (len > 1) {`);
|
|
@@ -654,17 +666,15 @@ function writeRouterVerb(writer, trie, verb, level = 0, offset = 1) {
|
|
|
654
666
|
if (useSwitch) {
|
|
655
667
|
writer.writeBlockStart(`switch (${value}) {`);
|
|
656
668
|
}
|
|
657
|
-
for (const { key, path:
|
|
669
|
+
for (const { key, path: path8, route: route2 } of terminal) {
|
|
658
670
|
const decodedKey = decodeURIComponent(key);
|
|
659
671
|
if (useSwitch) {
|
|
660
672
|
writer.write(`case '${decodedKey}': `, true);
|
|
661
673
|
} else {
|
|
662
674
|
writer.write(`if (${value} === '${decodedKey}') `, true);
|
|
663
675
|
}
|
|
664
|
-
writer.write(
|
|
665
|
-
|
|
666
|
-
`
|
|
667
|
-
);
|
|
676
|
+
writer.write(`return ${renderMatch(verb, route2, path8)};
|
|
677
|
+
`);
|
|
668
678
|
}
|
|
669
679
|
if (useSwitch) {
|
|
670
680
|
writer.writeBlockEnd("}");
|
|
@@ -676,7 +686,7 @@ function writeRouterVerb(writer, trie, verb, level = 0, offset = 1) {
|
|
|
676
686
|
verb,
|
|
677
687
|
dynamic.route,
|
|
678
688
|
dynamic.path
|
|
679
|
-
)}
|
|
689
|
+
)};`
|
|
680
690
|
);
|
|
681
691
|
}
|
|
682
692
|
}
|
|
@@ -736,7 +746,7 @@ function writeRouterVerb(writer, trie, verb, level = 0, offset = 1) {
|
|
|
736
746
|
catchAll.route,
|
|
737
747
|
catchAll.path,
|
|
738
748
|
String(offset)
|
|
739
|
-
)}
|
|
749
|
+
)};`
|
|
740
750
|
);
|
|
741
751
|
} else if (level === 0) {
|
|
742
752
|
writer.writeLines("return null;");
|
|
@@ -765,43 +775,47 @@ function renderParams(params, pathIndex) {
|
|
|
765
775
|
}
|
|
766
776
|
return result ? result + " }" : "{}";
|
|
767
777
|
}
|
|
768
|
-
function renderMatch(verb, route,
|
|
778
|
+
function renderMatch(verb, route, path8, pathIndex) {
|
|
769
779
|
const handler = `${verb}${route.index}`;
|
|
770
|
-
const params =
|
|
780
|
+
const params = path8.params ? renderParams(path8.params, pathIndex) : "{}";
|
|
771
781
|
const meta = route.meta ? `meta${route.index}` : "{}";
|
|
772
|
-
|
|
773
|
-
return `{ handler: ${handler}, params: ${params}, meta: ${meta}, path: '${pathPattern}' }`;
|
|
782
|
+
return `{ handler: ${handler}, params: ${params}, meta: ${meta}, path: '${path8.path}' }`;
|
|
774
783
|
}
|
|
775
|
-
function renderMiddleware(middleware) {
|
|
784
|
+
function renderMiddleware(middleware, rootDir) {
|
|
776
785
|
const writer = createStringWriter();
|
|
777
786
|
writer.writeLines(
|
|
778
787
|
`// ${virtualFilePrefix}/${markoRunFilePrefix}middleware.js`
|
|
779
788
|
);
|
|
780
789
|
const imports = writer.branch("imports");
|
|
781
790
|
imports.writeLines(
|
|
782
|
-
`import { normalize } from
|
|
791
|
+
`import { normalize } from "${virtualFilePrefix}/runtime/internal";`
|
|
783
792
|
);
|
|
784
793
|
writer.writeLines("");
|
|
785
|
-
for (const { id,
|
|
794
|
+
for (const { id, filePath } of middleware) {
|
|
786
795
|
const importName = `middleware${id}`;
|
|
787
|
-
imports.writeLines(
|
|
796
|
+
imports.writeLines(
|
|
797
|
+
`import ${importName} from "${normalizedRelativePath(rootDir, filePath)}";`
|
|
798
|
+
);
|
|
788
799
|
writer.writeLines(`export const mware${id} = normalize(${importName});`);
|
|
789
800
|
}
|
|
790
801
|
imports.join();
|
|
791
802
|
return writer.end();
|
|
792
803
|
}
|
|
793
|
-
function stripTsExtension(
|
|
794
|
-
const index =
|
|
804
|
+
function stripTsExtension(path8) {
|
|
805
|
+
const index = path8.lastIndexOf(".");
|
|
795
806
|
if (index !== -1) {
|
|
796
|
-
const ext =
|
|
807
|
+
const ext = path8.slice(index + 1);
|
|
797
808
|
if (ext.toLowerCase() === "ts") {
|
|
798
|
-
return
|
|
809
|
+
return path8.slice(0, index);
|
|
799
810
|
}
|
|
800
811
|
}
|
|
801
|
-
return
|
|
812
|
+
return path8;
|
|
802
813
|
}
|
|
803
|
-
|
|
804
|
-
|
|
814
|
+
function decodePath(path8) {
|
|
815
|
+
return path8;
|
|
816
|
+
}
|
|
817
|
+
async function renderRouteTypeInfo(routes, outDir, adapter) {
|
|
818
|
+
var _a, _b, _c, _d;
|
|
805
819
|
const writer = createStringWriter();
|
|
806
820
|
writer.writeLines(
|
|
807
821
|
`/*
|
|
@@ -830,11 +844,31 @@ async function renderRouteTypeInfo(routes, pathPrefix = ".", adapter) {
|
|
|
830
844
|
const routeTypes = /* @__PURE__ */ new Map();
|
|
831
845
|
for (const route of routes.list) {
|
|
832
846
|
let routeType = "";
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
847
|
+
let routeDefinition = "";
|
|
848
|
+
if (route.page || route.handler) {
|
|
849
|
+
const verbs = [];
|
|
850
|
+
if (route.page || ((_b = (_a = route.handler) == null ? void 0 : _a.verbs) == null ? void 0 : _b.includes("get"))) {
|
|
851
|
+
verbs.push(`"get"`);
|
|
852
|
+
}
|
|
853
|
+
if ((_d = (_c = route.handler) == null ? void 0 : _c.verbs) == null ? void 0 : _d.includes("post")) {
|
|
854
|
+
verbs.push(`"post"`);
|
|
855
|
+
}
|
|
856
|
+
routeDefinition = `{ verb: ${verbs.join(" | ")};`;
|
|
857
|
+
if (route.meta) {
|
|
858
|
+
const metaPath = stripTsExtension(
|
|
859
|
+
normalizedRelativePath(outDir, route.meta.filePath)
|
|
860
|
+
);
|
|
861
|
+
let metaType = `typeof import("${metaPath}")`;
|
|
862
|
+
if (/\.(ts|js|mjs)$/.test(route.meta.name)) {
|
|
863
|
+
metaType += `["default"]`;
|
|
864
|
+
}
|
|
865
|
+
routeDefinition += ` meta: ${metaType};`;
|
|
866
|
+
}
|
|
867
|
+
routeDefinition += " }";
|
|
837
868
|
}
|
|
869
|
+
const pathType = `"${decodePath(route.path.path)}"`;
|
|
870
|
+
routeType += routeType ? " | " + pathType : pathType;
|
|
871
|
+
routesWriter.writeLines(`${pathType}: ${routeDefinition};`);
|
|
838
872
|
for (const file of [route.handler, route.page]) {
|
|
839
873
|
if (file) {
|
|
840
874
|
const existing = routeTypes.get(file);
|
|
@@ -867,31 +901,33 @@ async function renderRouteTypeInfo(routes, pathPrefix = ".", adapter) {
|
|
|
867
901
|
const pageWriter = writer.branch("page");
|
|
868
902
|
const layoutWriter = writer.branch("layout");
|
|
869
903
|
for (const [file, types] of routeTypes) {
|
|
870
|
-
const
|
|
904
|
+
const modulePath = stripTsExtension(
|
|
905
|
+
normalizedRelativePath(outDir, file.filePath)
|
|
906
|
+
);
|
|
871
907
|
const routeType = `Run.Routes[${types.join(" | ")}]`;
|
|
872
908
|
switch (file.type) {
|
|
873
909
|
case RoutableFileTypes.Handler:
|
|
874
|
-
writeModuleDeclaration(handlerWriter,
|
|
910
|
+
writeModuleDeclaration(handlerWriter, modulePath, routeType);
|
|
875
911
|
break;
|
|
876
912
|
case RoutableFileTypes.Middleware:
|
|
877
|
-
writeModuleDeclaration(middlewareWriter,
|
|
913
|
+
writeModuleDeclaration(middlewareWriter, modulePath, routeType);
|
|
878
914
|
break;
|
|
879
915
|
case RoutableFileTypes.Page:
|
|
880
|
-
writeModuleDeclaration(pageWriter,
|
|
916
|
+
writeModuleDeclaration(pageWriter, modulePath, routeType);
|
|
881
917
|
break;
|
|
882
918
|
case RoutableFileTypes.Layout:
|
|
883
919
|
writeModuleDeclaration(
|
|
884
920
|
layoutWriter,
|
|
885
|
-
|
|
921
|
+
modulePath,
|
|
886
922
|
routeType,
|
|
887
923
|
`
|
|
888
|
-
export interface Input extends Run.LayoutInput<typeof import(
|
|
924
|
+
export interface Input extends Run.LayoutInput<typeof import("${modulePath}")> {}`
|
|
889
925
|
);
|
|
890
926
|
break;
|
|
891
927
|
case RoutableFileTypes.Error:
|
|
892
928
|
writeModuleDeclaration(
|
|
893
929
|
writer,
|
|
894
|
-
|
|
930
|
+
modulePath,
|
|
895
931
|
"globalThis.MarkoRun.Route",
|
|
896
932
|
`
|
|
897
933
|
export interface Input {
|
|
@@ -900,7 +936,7 @@ async function renderRouteTypeInfo(routes, pathPrefix = ".", adapter) {
|
|
|
900
936
|
);
|
|
901
937
|
break;
|
|
902
938
|
case RoutableFileTypes.NotFound:
|
|
903
|
-
writeModuleDeclaration(writer,
|
|
939
|
+
writeModuleDeclaration(writer, modulePath, "Run.Route");
|
|
904
940
|
break;
|
|
905
941
|
}
|
|
906
942
|
}
|
|
@@ -908,40 +944,15 @@ async function renderRouteTypeInfo(routes, pathPrefix = ".", adapter) {
|
|
|
908
944
|
middlewareWriter.join();
|
|
909
945
|
pageWriter.join();
|
|
910
946
|
layoutWriter.join();
|
|
911
|
-
writer.writeBlockStart(`
|
|
912
|
-
type Routes = {`);
|
|
913
|
-
for (const route of routes.list) {
|
|
914
|
-
const { meta, handler, page } = route;
|
|
915
|
-
if (page || handler) {
|
|
916
|
-
const verbs = [];
|
|
917
|
-
if (page || ((_a = handler == null ? void 0 : handler.verbs) == null ? void 0 : _a.includes("get"))) {
|
|
918
|
-
verbs.push(`"get"`);
|
|
919
|
-
}
|
|
920
|
-
if ((_b = handler == null ? void 0 : handler.verbs) == null ? void 0 : _b.includes("post")) {
|
|
921
|
-
verbs.push(`"post"`);
|
|
922
|
-
}
|
|
923
|
-
let routeType = `{ verb: ${verbs.join(" | ")};`;
|
|
924
|
-
if (meta) {
|
|
925
|
-
const metaPath = stripTsExtension(`${pathPrefix}/${meta.relativePath}`);
|
|
926
|
-
let metaType = `typeof import("${metaPath}")`;
|
|
927
|
-
if (/\.(ts|js|mjs)$/.test(meta.name)) {
|
|
928
|
-
metaType += `["default"]`;
|
|
929
|
-
}
|
|
930
|
-
routeType += ` meta: ${metaType};`;
|
|
931
|
-
}
|
|
932
|
-
writer.writeLines(`"${route.key}": ${routeType} };`);
|
|
933
|
-
}
|
|
934
|
-
}
|
|
935
|
-
writer.writeBlockEnd("}");
|
|
936
947
|
return writer.end();
|
|
937
948
|
}
|
|
938
|
-
function writeModuleDeclaration(writer,
|
|
939
|
-
writer.writeLines("").write(`declare module "${
|
|
949
|
+
function writeModuleDeclaration(writer, name, routeType, moduleTypes) {
|
|
950
|
+
writer.writeLines("").write(`declare module "${name}" {`);
|
|
940
951
|
if (moduleTypes) {
|
|
941
952
|
writer.write(moduleTypes);
|
|
942
953
|
}
|
|
943
954
|
if (routeType) {
|
|
944
|
-
const isMarko =
|
|
955
|
+
const isMarko = name.endsWith(".marko");
|
|
945
956
|
writer.write(`
|
|
946
957
|
namespace MarkoRun {
|
|
947
958
|
export { NotHandled, NotMatched, GetPaths, PostPaths, GetablePath, GetableHref, PostablePath, PostableHref, Platform };
|
|
@@ -955,21 +966,15 @@ function writeModuleDeclaration(writer, path6, routeType, moduleTypes) {
|
|
|
955
966
|
writer.writeLines(`
|
|
956
967
|
}`);
|
|
957
968
|
}
|
|
958
|
-
function pathToURLPatternString(path6) {
|
|
959
|
-
return path6.replace(/\/\$(\$?)([^/]*)/g, (_, catchAll, name) => {
|
|
960
|
-
name = decodeURIComponent(name);
|
|
961
|
-
return catchAll ? `/:${name || "rest"}*` : `/:${name}`;
|
|
962
|
-
});
|
|
963
|
-
}
|
|
964
969
|
function createRouteTrie(routes) {
|
|
965
970
|
const root = {
|
|
966
971
|
key: ""
|
|
967
972
|
};
|
|
968
|
-
function insert(
|
|
973
|
+
function insert(path8, route) {
|
|
969
974
|
let node = root;
|
|
970
|
-
for (const segment of
|
|
975
|
+
for (const segment of path8.segments) {
|
|
971
976
|
if (segment === "$$") {
|
|
972
|
-
node.catchAll ?? (node.catchAll = { route, path:
|
|
977
|
+
node.catchAll ?? (node.catchAll = { route, path: path8 });
|
|
973
978
|
return;
|
|
974
979
|
} else if (segment === "$") {
|
|
975
980
|
node = node.dynamic ?? (node.dynamic = {
|
|
@@ -987,17 +992,18 @@ function createRouteTrie(routes) {
|
|
|
987
992
|
node = next;
|
|
988
993
|
}
|
|
989
994
|
}
|
|
990
|
-
node.path ?? (node.path =
|
|
995
|
+
node.path ?? (node.path = path8);
|
|
991
996
|
node.route ?? (node.route = route);
|
|
992
997
|
}
|
|
993
998
|
for (const route of routes) {
|
|
994
|
-
|
|
995
|
-
insert(path6, route);
|
|
996
|
-
}
|
|
999
|
+
insert(route.path, route);
|
|
997
1000
|
}
|
|
998
1001
|
return root;
|
|
999
1002
|
}
|
|
1000
1003
|
|
|
1004
|
+
// src/vite/routes/builder.ts
|
|
1005
|
+
import path3 from "path";
|
|
1006
|
+
|
|
1001
1007
|
// src/vite/routes/parse.ts
|
|
1002
1008
|
function parseFlatRoute(pattern) {
|
|
1003
1009
|
if (!pattern) throw new Error("Empty pattern");
|
|
@@ -1012,53 +1018,72 @@ function parseFlatRoute(pattern) {
|
|
|
1012
1018
|
]);
|
|
1013
1019
|
function parse2(basePaths, group) {
|
|
1014
1020
|
const pathMap = /* @__PURE__ */ new Map();
|
|
1015
|
-
const delimiters = group ? ").," : "
|
|
1021
|
+
const delimiters = group ? "`).," : "`.,";
|
|
1016
1022
|
let charCode;
|
|
1017
1023
|
let segmentStart = i;
|
|
1018
1024
|
let type;
|
|
1019
1025
|
let current;
|
|
1026
|
+
let escaped = "";
|
|
1027
|
+
let escapeStart = 0;
|
|
1020
1028
|
do {
|
|
1021
1029
|
charCode = pattern.charCodeAt(i);
|
|
1022
|
-
if (charCode ===
|
|
1030
|
+
if (charCode === 96 /* Escape */) {
|
|
1031
|
+
if (escapeStart) {
|
|
1032
|
+
escaped += pattern.slice(segmentStart, escapeStart - 1) + pattern.slice(escapeStart, i);
|
|
1033
|
+
escapeStart = 0;
|
|
1034
|
+
segmentStart = ++i;
|
|
1035
|
+
} else {
|
|
1036
|
+
escapeStart = i + 1;
|
|
1037
|
+
i = pattern.indexOf("`", escapeStart);
|
|
1038
|
+
if (i < 0) break;
|
|
1039
|
+
}
|
|
1040
|
+
} else if (charCode === 41 /* GroupEnd */ && group) {
|
|
1023
1041
|
break;
|
|
1024
|
-
} else if (charCode === 44) {
|
|
1042
|
+
} else if (charCode === 44 /* Alternate */) {
|
|
1025
1043
|
if (!current) {
|
|
1026
1044
|
segmentEnd(
|
|
1027
|
-
basePaths.map((
|
|
1028
|
-
...
|
|
1029
|
-
segments:
|
|
1045
|
+
basePaths.map((path8) => ({
|
|
1046
|
+
...path8,
|
|
1047
|
+
segments: path8.segments.slice()
|
|
1030
1048
|
})),
|
|
1031
|
-
|
|
1049
|
+
escaped,
|
|
1032
1050
|
"_",
|
|
1033
1051
|
pathMap
|
|
1034
1052
|
);
|
|
1035
1053
|
} else {
|
|
1036
|
-
segmentEnd(
|
|
1054
|
+
segmentEnd(
|
|
1055
|
+
current,
|
|
1056
|
+
escaped + pattern.slice(segmentStart, i),
|
|
1057
|
+
type,
|
|
1058
|
+
pathMap
|
|
1059
|
+
);
|
|
1037
1060
|
}
|
|
1038
1061
|
current = void 0;
|
|
1039
1062
|
type = void 0;
|
|
1063
|
+
escaped = "";
|
|
1040
1064
|
segmentStart = ++i;
|
|
1041
|
-
} else if (charCode === 46) {
|
|
1065
|
+
} else if (charCode === 46 /* Directory */) {
|
|
1042
1066
|
if (current) {
|
|
1043
|
-
segmentEnd(current, pattern.slice(segmentStart, i), type);
|
|
1067
|
+
segmentEnd(current, escaped + pattern.slice(segmentStart, i), type);
|
|
1044
1068
|
}
|
|
1045
1069
|
type = void 0;
|
|
1070
|
+
escaped = "";
|
|
1046
1071
|
segmentStart = ++i;
|
|
1047
|
-
} else if (charCode === 40) {
|
|
1072
|
+
} else if (charCode === 40 /* GroupStart */) {
|
|
1048
1073
|
const groupPaths = parse2(current || basePaths, ++i);
|
|
1049
1074
|
if (groupPaths.length) {
|
|
1050
1075
|
current = groupPaths;
|
|
1051
1076
|
}
|
|
1052
1077
|
segmentStart = ++i;
|
|
1053
1078
|
} else {
|
|
1054
|
-
if (charCode === 95) {
|
|
1079
|
+
if (charCode === 95 /* Pathless */) {
|
|
1055
1080
|
type = "_";
|
|
1056
|
-
} else if (charCode === 36) {
|
|
1081
|
+
} else if (charCode === 36 /* Dynamic */) {
|
|
1057
1082
|
type = pattern.charCodeAt(i + 1) === 36 ? "$$" : "$";
|
|
1058
1083
|
}
|
|
1059
|
-
current ?? (current = basePaths.map((
|
|
1060
|
-
...
|
|
1061
|
-
segments:
|
|
1084
|
+
current ?? (current = basePaths.map((path8) => ({
|
|
1085
|
+
...path8,
|
|
1086
|
+
segments: path8.segments.slice()
|
|
1062
1087
|
})));
|
|
1063
1088
|
i = len;
|
|
1064
1089
|
for (const char of delimiters) {
|
|
@@ -1069,7 +1094,12 @@ function parseFlatRoute(pattern) {
|
|
|
1069
1094
|
}
|
|
1070
1095
|
}
|
|
1071
1096
|
} while (i < len);
|
|
1072
|
-
if (
|
|
1097
|
+
if (escapeStart) {
|
|
1098
|
+
throw new Error(
|
|
1099
|
+
`Invalid route pattern: unclosed escape '${pattern.slice(escapeStart)}' in '${pattern}'`
|
|
1100
|
+
);
|
|
1101
|
+
}
|
|
1102
|
+
if (group && charCode !== 41 /* GroupEnd */) {
|
|
1073
1103
|
throw new Error(
|
|
1074
1104
|
`Invalid route pattern: group was not closed '${pattern.slice(
|
|
1075
1105
|
group
|
|
@@ -1078,16 +1108,21 @@ function parseFlatRoute(pattern) {
|
|
|
1078
1108
|
}
|
|
1079
1109
|
if (!current) {
|
|
1080
1110
|
segmentEnd(
|
|
1081
|
-
basePaths.map((
|
|
1082
|
-
...
|
|
1083
|
-
segments:
|
|
1111
|
+
basePaths.map((path8) => ({
|
|
1112
|
+
...path8,
|
|
1113
|
+
segments: path8.segments.slice()
|
|
1084
1114
|
})),
|
|
1085
|
-
|
|
1086
|
-
|
|
1115
|
+
escaped,
|
|
1116
|
+
void 0,
|
|
1087
1117
|
pathMap
|
|
1088
1118
|
);
|
|
1089
1119
|
} else {
|
|
1090
|
-
segmentEnd(
|
|
1120
|
+
segmentEnd(
|
|
1121
|
+
current,
|
|
1122
|
+
escaped + pattern.slice(segmentStart, i),
|
|
1123
|
+
type,
|
|
1124
|
+
pathMap
|
|
1125
|
+
);
|
|
1091
1126
|
}
|
|
1092
1127
|
return [...pathMap.values()];
|
|
1093
1128
|
}
|
|
@@ -1096,17 +1131,17 @@ function parseFlatRoute(pattern) {
|
|
|
1096
1131
|
if (raw) {
|
|
1097
1132
|
segment = {
|
|
1098
1133
|
raw,
|
|
1099
|
-
name: raw,
|
|
1134
|
+
name: normalizeSegment(raw),
|
|
1100
1135
|
type
|
|
1101
1136
|
};
|
|
1102
1137
|
if (type === "$" || type === "$$") {
|
|
1103
1138
|
segment.name = type;
|
|
1104
|
-
segment.param = raw.slice(type.length);
|
|
1139
|
+
segment.param = normalizeParam(raw.slice(type.length));
|
|
1105
1140
|
}
|
|
1106
1141
|
}
|
|
1107
|
-
for (const
|
|
1142
|
+
for (const path8 of paths) {
|
|
1108
1143
|
if (segment) {
|
|
1109
|
-
if (
|
|
1144
|
+
if (path8.isCatchall) {
|
|
1110
1145
|
throw new Error(
|
|
1111
1146
|
`Invalid route pattern: nested segments are not allowed after a catch-all parameter. Found '.' following '${pattern.slice(
|
|
1112
1147
|
0,
|
|
@@ -1114,26 +1149,36 @@ function parseFlatRoute(pattern) {
|
|
|
1114
1149
|
)}' in '${pattern}'.`
|
|
1115
1150
|
);
|
|
1116
1151
|
}
|
|
1117
|
-
|
|
1118
|
-
|
|
1152
|
+
path8.segments.push(segment);
|
|
1153
|
+
path8.id += path8.id === "/" ? segment.name : `/${segment.name}`;
|
|
1119
1154
|
if (type === "$$") {
|
|
1120
|
-
|
|
1155
|
+
path8.isCatchall = true;
|
|
1121
1156
|
}
|
|
1122
1157
|
}
|
|
1123
1158
|
if (map) {
|
|
1124
|
-
if (map.has(
|
|
1125
|
-
const existing = map.get(
|
|
1159
|
+
if (map.has(path8.id)) {
|
|
1160
|
+
const existing = map.get(path8.id);
|
|
1126
1161
|
const existingExpansion = existing.segments.map((s) => s.raw).join(".");
|
|
1127
|
-
const currentExpansion =
|
|
1162
|
+
const currentExpansion = path8.segments.map((s) => s.raw).join(".");
|
|
1128
1163
|
throw new Error(
|
|
1129
|
-
`Invalid route pattern: route '${
|
|
1164
|
+
`Invalid route pattern: route '${path8.id}' is ambiguous. Expansion '${currentExpansion}' collides with '${existingExpansion}' in '${pattern}'.`
|
|
1130
1165
|
);
|
|
1131
1166
|
}
|
|
1132
|
-
map.set(
|
|
1167
|
+
map.set(path8.id, path8);
|
|
1133
1168
|
}
|
|
1134
1169
|
}
|
|
1135
1170
|
}
|
|
1136
1171
|
}
|
|
1172
|
+
function normalizeParam(segment) {
|
|
1173
|
+
const normalized = normalizeSegment(segment);
|
|
1174
|
+
return /^\$/.test(normalized) ? `\`${normalized}\`` : normalized;
|
|
1175
|
+
}
|
|
1176
|
+
function normalizeSegment(segment) {
|
|
1177
|
+
return decodeURIComponent(segment).replace(
|
|
1178
|
+
/[/?#]/g,
|
|
1179
|
+
(char) => "%" + char.charCodeAt(0).toString(16)
|
|
1180
|
+
);
|
|
1181
|
+
}
|
|
1137
1182
|
|
|
1138
1183
|
// src/vite/routes/vdir.ts
|
|
1139
1184
|
var _dirs, _pathlessDirs;
|
|
@@ -1144,14 +1189,12 @@ var _VDir = class _VDir {
|
|
|
1144
1189
|
__publicField(this, "parent");
|
|
1145
1190
|
__publicField(this, "source");
|
|
1146
1191
|
__publicField(this, "path");
|
|
1147
|
-
__publicField(this, "fullPath");
|
|
1148
1192
|
__publicField(this, "segment");
|
|
1149
1193
|
__publicField(this, "files");
|
|
1150
1194
|
if (!parent || !segment) {
|
|
1151
1195
|
this.parent = null;
|
|
1152
1196
|
this.source = null;
|
|
1153
1197
|
this.path = "/";
|
|
1154
|
-
this.fullPath = "/";
|
|
1155
1198
|
this.segment = {
|
|
1156
1199
|
raw: "",
|
|
1157
1200
|
name: ""
|
|
@@ -1159,12 +1202,8 @@ var _VDir = class _VDir {
|
|
|
1159
1202
|
} else {
|
|
1160
1203
|
this.parent = parent;
|
|
1161
1204
|
this.source = source;
|
|
1162
|
-
this.path = parent.path + (parent.path === "/" ? segment.name : `/${segment.name}`);
|
|
1163
|
-
this.fullPath = parent.fullPath + (parent.fullPath === "/" ? segment.name : `/${segment.name}`);
|
|
1164
|
-
if (segment.param) {
|
|
1165
|
-
this.fullPath += segment.param;
|
|
1166
|
-
}
|
|
1167
1205
|
this.segment = segment;
|
|
1206
|
+
this.path = parent.path + (parent.path === "/" ? "" : "/") + segment.name;
|
|
1168
1207
|
}
|
|
1169
1208
|
}
|
|
1170
1209
|
get pathInfo() {
|
|
@@ -1177,17 +1216,18 @@ var _VDir = class _VDir {
|
|
|
1177
1216
|
for (const { segment } of this) {
|
|
1178
1217
|
const { type, name, param } = segment;
|
|
1179
1218
|
if (name && type !== "_") {
|
|
1180
|
-
value.id += sep +
|
|
1219
|
+
value.id += sep + name;
|
|
1181
1220
|
value.path += sep + name;
|
|
1182
1221
|
value.isEnd = type === "$$";
|
|
1183
1222
|
if (param) {
|
|
1184
|
-
|
|
1223
|
+
const unescapedParam = param.charAt(0) === "`" ? param.slice(1, -1) : param;
|
|
1185
1224
|
const index = type === "$$" ? null : value.segments.length;
|
|
1186
1225
|
if (!value.params) {
|
|
1187
|
-
value.params = { [
|
|
1226
|
+
value.params = { [unescapedParam]: index };
|
|
1188
1227
|
} else if (!(param in value.params)) {
|
|
1189
|
-
value.params[
|
|
1228
|
+
value.params[unescapedParam] = index;
|
|
1190
1229
|
}
|
|
1230
|
+
value.path += param;
|
|
1191
1231
|
}
|
|
1192
1232
|
value.segments.push(name);
|
|
1193
1233
|
sep = "/";
|
|
@@ -1199,11 +1239,11 @@ var _VDir = class _VDir {
|
|
|
1199
1239
|
});
|
|
1200
1240
|
return value;
|
|
1201
1241
|
}
|
|
1202
|
-
addDir(
|
|
1242
|
+
addDir(path8, segment) {
|
|
1203
1243
|
const map = segment.type === "_" ? __privateGet(this, _pathlessDirs) ?? __privateSet(this, _pathlessDirs, /* @__PURE__ */ new Map()) : __privateGet(this, _dirs) ?? __privateSet(this, _dirs, /* @__PURE__ */ new Map());
|
|
1204
1244
|
const key = segment.type === "$" ? segment.raw : segment.name;
|
|
1205
1245
|
if (!map.has(key)) {
|
|
1206
|
-
const dir = new _VDir(this, segment,
|
|
1246
|
+
const dir = new _VDir(this, segment, path8);
|
|
1207
1247
|
map.set(key, dir);
|
|
1208
1248
|
return dir;
|
|
1209
1249
|
}
|
|
@@ -1219,15 +1259,15 @@ var _VDir = class _VDir {
|
|
|
1219
1259
|
const existing = this.files.get(file.type);
|
|
1220
1260
|
if (existing !== file) {
|
|
1221
1261
|
throw new Error(
|
|
1222
|
-
`Duplicate file type
|
|
1262
|
+
`Duplicate file type ${file.type} added at path ${this.path}. File ${file.filePath} collides with ${existing.filePath}.`
|
|
1223
1263
|
);
|
|
1224
1264
|
} else if (file.type === RoutableFileTypes.Page || file.type === RoutableFileTypes.Handler) {
|
|
1225
1265
|
throw new Error(
|
|
1226
|
-
`Ambiguous path definition: route
|
|
1266
|
+
`Ambiguous path definition: route ${this.path} is defined multiple times by ${file.filePath}`
|
|
1227
1267
|
);
|
|
1228
1268
|
}
|
|
1229
1269
|
throw new Error(
|
|
1230
|
-
`Ambiguous path definition: file
|
|
1270
|
+
`Ambiguous path definition: file ${this.path} is included multiple times by ${file.filePath}`
|
|
1231
1271
|
);
|
|
1232
1272
|
}
|
|
1233
1273
|
}
|
|
@@ -1249,10 +1289,10 @@ var _VDir = class _VDir {
|
|
|
1249
1289
|
const dirs = [];
|
|
1250
1290
|
const unique = /* @__PURE__ */ new Map();
|
|
1251
1291
|
for (const root of roots) {
|
|
1252
|
-
for (const
|
|
1292
|
+
for (const path8 of paths) {
|
|
1253
1293
|
let dir = root;
|
|
1254
|
-
for (const segment of
|
|
1255
|
-
dir = dir.addDir(
|
|
1294
|
+
for (const segment of path8.segments) {
|
|
1295
|
+
dir = dir.addDir(path8, segment);
|
|
1256
1296
|
}
|
|
1257
1297
|
const existing = unique.get(dir.path);
|
|
1258
1298
|
if (existing) {
|
|
@@ -1265,7 +1305,7 @@ var _VDir = class _VDir {
|
|
|
1265
1305
|
}
|
|
1266
1306
|
}
|
|
1267
1307
|
throw new Error(
|
|
1268
|
-
`Ambiguous directory structure:
|
|
1308
|
+
`Ambiguous directory structure: ${sourcePath}${path8.source} defines ${dir.path} multiple times.`
|
|
1269
1309
|
);
|
|
1270
1310
|
} else {
|
|
1271
1311
|
unique.set(dir.path, dir);
|
|
@@ -1291,13 +1331,11 @@ function matchRoutableFile(filename) {
|
|
|
1291
1331
|
const match = filename.match(routeableFileRegex);
|
|
1292
1332
|
return match && (match[1] || match[3]).toLowerCase();
|
|
1293
1333
|
}
|
|
1294
|
-
function
|
|
1295
|
-
return type === RoutableFileTypes.NotFound || type === RoutableFileTypes.Error;
|
|
1296
|
-
}
|
|
1297
|
-
async function buildRoutes(sources) {
|
|
1334
|
+
async function buildRoutes(sources, outDir) {
|
|
1298
1335
|
const uniqueRoutes = /* @__PURE__ */ new Map();
|
|
1299
1336
|
const routes = [];
|
|
1300
1337
|
const special = {};
|
|
1338
|
+
const seenKeys = /* @__PURE__ */ new Map();
|
|
1301
1339
|
const middlewares = /* @__PURE__ */ new Set();
|
|
1302
1340
|
const unusedFiles = /* @__PURE__ */ new Set();
|
|
1303
1341
|
const currentLayouts = /* @__PURE__ */ new Set();
|
|
@@ -1305,13 +1343,13 @@ async function buildRoutes(sources) {
|
|
|
1305
1343
|
const root = new VDir();
|
|
1306
1344
|
const dirStack = [];
|
|
1307
1345
|
let basePath;
|
|
1308
|
-
let importPrefix;
|
|
1309
1346
|
let activeDirs;
|
|
1310
1347
|
let isBaseDir;
|
|
1311
1348
|
let nextFileId = 1;
|
|
1312
1349
|
let nextRouteIndex = 1;
|
|
1313
1350
|
const walkOptions = {
|
|
1314
|
-
onEnter(
|
|
1351
|
+
onEnter(dir) {
|
|
1352
|
+
let { name } = dir;
|
|
1315
1353
|
const prevDirStackLength = dirStack.length;
|
|
1316
1354
|
if (isBaseDir) {
|
|
1317
1355
|
isBaseDir = false;
|
|
@@ -1330,15 +1368,16 @@ async function buildRoutes(sources) {
|
|
|
1330
1368
|
dirStack.length = prevDirStackLength;
|
|
1331
1369
|
};
|
|
1332
1370
|
},
|
|
1333
|
-
onFile(
|
|
1371
|
+
onFile(file) {
|
|
1372
|
+
const { name } = file;
|
|
1334
1373
|
const match = name.match(routeableFileRegex);
|
|
1335
1374
|
if (!match) {
|
|
1336
1375
|
return;
|
|
1337
1376
|
}
|
|
1338
1377
|
const type = (match[1] || match[3]).toLowerCase();
|
|
1339
|
-
if (dirStack.length &&
|
|
1378
|
+
if (dirStack.length && (type === RoutableFileTypes.NotFound || type === RoutableFileTypes.Error)) {
|
|
1340
1379
|
console.warn(
|
|
1341
|
-
`Special pages '${RoutableFileTypes.NotFound}' and '${RoutableFileTypes.Error}' are only considered in the root directory - ignoring ${
|
|
1380
|
+
`Special pages '${RoutableFileTypes.NotFound}' and '${RoutableFileTypes.Error}' are only considered in the root directory - ignoring ${file.path}`
|
|
1342
1381
|
);
|
|
1343
1382
|
return;
|
|
1344
1383
|
}
|
|
@@ -1347,19 +1386,15 @@ async function buildRoutes(sources) {
|
|
|
1347
1386
|
const paths = parseFlatRoute(name.slice(0, match.index));
|
|
1348
1387
|
dirs = VDir.addPaths(activeDirs, paths);
|
|
1349
1388
|
}
|
|
1350
|
-
const
|
|
1351
|
-
const relativePath = dirPath ? `${dirPath}/${name}` : name;
|
|
1352
|
-
const file = {
|
|
1389
|
+
const routableFile = {
|
|
1353
1390
|
id: String(nextFileId++),
|
|
1354
1391
|
name,
|
|
1355
1392
|
type,
|
|
1356
|
-
filePath:
|
|
1357
|
-
relativePath,
|
|
1358
|
-
importPath: `${importPrefix}/${relativePath}`,
|
|
1393
|
+
filePath: file.path,
|
|
1359
1394
|
verbs: type === RoutableFileTypes.Page ? ["get", "head"] : void 0
|
|
1360
1395
|
};
|
|
1361
1396
|
for (const dir of dirs) {
|
|
1362
|
-
dir.addFile(
|
|
1397
|
+
dir.addFile(routableFile);
|
|
1363
1398
|
}
|
|
1364
1399
|
}
|
|
1365
1400
|
};
|
|
@@ -1367,7 +1402,6 @@ async function buildRoutes(sources) {
|
|
|
1367
1402
|
sources = [sources];
|
|
1368
1403
|
}
|
|
1369
1404
|
for (const source of sources) {
|
|
1370
|
-
importPrefix = source.importPrefix ? source.importPrefix.replace(/^\/+|\/+$/g, "") : "";
|
|
1371
1405
|
basePath = source.basePath || "";
|
|
1372
1406
|
activeDirs = [root];
|
|
1373
1407
|
isBaseDir = true;
|
|
@@ -1387,7 +1421,8 @@ async function buildRoutes(sources) {
|
|
|
1387
1421
|
layout = dir.files.get(RoutableFileTypes.Layout);
|
|
1388
1422
|
const handler = dir.files.get(RoutableFileTypes.Handler);
|
|
1389
1423
|
const page = dir.files.get(RoutableFileTypes.Page);
|
|
1390
|
-
|
|
1424
|
+
const pathInfo = dir.pathInfo;
|
|
1425
|
+
let layoutsUsed = false;
|
|
1391
1426
|
if (middleware) {
|
|
1392
1427
|
if (currentMiddleware.has(middleware)) {
|
|
1393
1428
|
middleware = void 0;
|
|
@@ -1404,64 +1439,64 @@ async function buildRoutes(sources) {
|
|
|
1404
1439
|
unusedFiles.add(layout);
|
|
1405
1440
|
}
|
|
1406
1441
|
}
|
|
1442
|
+
if (dir === root) {
|
|
1443
|
+
for (const [type, file] of dir.files) {
|
|
1444
|
+
if (type === RoutableFileTypes.NotFound || type === RoutableFileTypes.Error) {
|
|
1445
|
+
special[type] = {
|
|
1446
|
+
index: nextRouteIndex++,
|
|
1447
|
+
key: type,
|
|
1448
|
+
path: dir.pathInfo,
|
|
1449
|
+
middleware: [],
|
|
1450
|
+
layouts: [...currentLayouts],
|
|
1451
|
+
page: file,
|
|
1452
|
+
templateFilePath: currentLayouts.size ? path3.join(outDir, `${type}.marko`) : void 0
|
|
1453
|
+
};
|
|
1454
|
+
layoutsUsed = true;
|
|
1455
|
+
}
|
|
1456
|
+
}
|
|
1457
|
+
}
|
|
1407
1458
|
if (page || handler) {
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
const existing = uniqueRoutes.get(path6.id);
|
|
1459
|
+
if (uniqueRoutes.has(pathInfo.id)) {
|
|
1460
|
+
const existing = uniqueRoutes.get(pathInfo.id);
|
|
1411
1461
|
const route = routes[existing.index];
|
|
1412
1462
|
const existingFiles = [route.handler, route.page].filter(Boolean).map((f) => f.filePath);
|
|
1413
1463
|
const currentFiles = [handler, page].filter(Boolean).map((f) => f.filePath);
|
|
1414
|
-
throw new Error(
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1464
|
+
throw new Error(
|
|
1465
|
+
`Duplicate routes for path ${pathInfo.id} were defined. A route established by: "${existingFiles.join(" and ")}" collides with "${currentFiles.join(" and ")}"`
|
|
1466
|
+
);
|
|
1467
|
+
}
|
|
1468
|
+
uniqueRoutes.set(pathInfo.id, { dir, index: routes.length });
|
|
1469
|
+
let key = pathInfo.segments.map(replaceInvalidFilenameChars).concat("route").join("/");
|
|
1470
|
+
const keyCount = (seenKeys.get(key) || 0) + 1;
|
|
1471
|
+
seenKeys.set(key, keyCount);
|
|
1472
|
+
if (keyCount > 1) {
|
|
1473
|
+
key += keyCount;
|
|
1419
1474
|
}
|
|
1420
|
-
uniqueRoutes.set(path6.id, { dir, index: routes.length });
|
|
1421
1475
|
routes.push({
|
|
1422
1476
|
index: nextRouteIndex++,
|
|
1423
|
-
key
|
|
1424
|
-
|
|
1477
|
+
key,
|
|
1478
|
+
path: pathInfo,
|
|
1425
1479
|
middleware: [...currentMiddleware],
|
|
1426
1480
|
layouts: page ? [...currentLayouts] : [],
|
|
1427
1481
|
meta: dir.files.get(RoutableFileTypes.Meta),
|
|
1428
1482
|
page,
|
|
1429
1483
|
handler,
|
|
1430
|
-
|
|
1484
|
+
templateFilePath: page && currentLayouts.size ? path3.join(outDir, key + ".marko") : void 0
|
|
1431
1485
|
});
|
|
1432
|
-
|
|
1433
|
-
if (dir === root) {
|
|
1434
|
-
for (const [type, file] of dir.files) {
|
|
1435
|
-
if (isSpecialType(type)) {
|
|
1436
|
-
hasSpecial = true;
|
|
1437
|
-
special[type] = {
|
|
1438
|
-
index: 0,
|
|
1439
|
-
key: type,
|
|
1440
|
-
paths: [],
|
|
1441
|
-
middleware: [],
|
|
1442
|
-
layouts: [...currentLayouts],
|
|
1443
|
-
page: file,
|
|
1444
|
-
entryName: `${markoRunFilePrefix}special.${type}`
|
|
1445
|
-
};
|
|
1446
|
-
}
|
|
1447
|
-
}
|
|
1448
|
-
}
|
|
1449
|
-
if (handler || page) {
|
|
1486
|
+
layoutsUsed = !!page;
|
|
1450
1487
|
for (const middleware2 of currentMiddleware) {
|
|
1451
1488
|
middlewares.add(middleware2);
|
|
1452
1489
|
unusedFiles.delete(middleware2);
|
|
1453
1490
|
}
|
|
1454
1491
|
}
|
|
1455
|
-
if (
|
|
1492
|
+
if (layoutsUsed) {
|
|
1456
1493
|
for (const layout2 of currentLayouts) {
|
|
1457
1494
|
unusedFiles.delete(layout2);
|
|
1458
1495
|
}
|
|
1459
1496
|
}
|
|
1460
1497
|
}
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
traverse(child);
|
|
1464
|
-
}
|
|
1498
|
+
for (const childDir of dir.dirs()) {
|
|
1499
|
+
traverse(childDir);
|
|
1465
1500
|
}
|
|
1466
1501
|
if (middleware) {
|
|
1467
1502
|
currentMiddleware.delete(middleware);
|
|
@@ -1471,10 +1506,13 @@ async function buildRoutes(sources) {
|
|
|
1471
1506
|
}
|
|
1472
1507
|
}
|
|
1473
1508
|
}
|
|
1509
|
+
function replaceInvalidFilenameChars(str) {
|
|
1510
|
+
return str.replace(/[<>:"/\\|?*]+/g, "_");
|
|
1511
|
+
}
|
|
1474
1512
|
|
|
1475
1513
|
// src/vite/routes/walk.ts
|
|
1476
1514
|
import fs from "fs";
|
|
1477
|
-
import
|
|
1515
|
+
import path4 from "path";
|
|
1478
1516
|
function createFSWalker(dir) {
|
|
1479
1517
|
return async function walkFS({
|
|
1480
1518
|
onEnter,
|
|
@@ -1489,7 +1527,7 @@ function createFSWalker(dir) {
|
|
|
1489
1527
|
const entries = await fs.promises.readdir(dir2.path, {
|
|
1490
1528
|
withFileTypes: true
|
|
1491
1529
|
});
|
|
1492
|
-
const prefix = dir2.path +
|
|
1530
|
+
const prefix = dir2.path + path4.sep;
|
|
1493
1531
|
for (const entry of entries) {
|
|
1494
1532
|
const walkEntry = {
|
|
1495
1533
|
name: entry.name,
|
|
@@ -1512,7 +1550,7 @@ function createFSWalker(dir) {
|
|
|
1512
1550
|
await walk(
|
|
1513
1551
|
{
|
|
1514
1552
|
path: dir,
|
|
1515
|
-
name:
|
|
1553
|
+
name: path4.basename(dir)
|
|
1516
1554
|
},
|
|
1517
1555
|
maxDepth
|
|
1518
1556
|
);
|
|
@@ -1630,36 +1668,34 @@ function logRoutesTable(routes, bundle) {
|
|
|
1630
1668
|
style: { compact: true }
|
|
1631
1669
|
});
|
|
1632
1670
|
for (const route of routes.list) {
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
if (route.page && (verb === "get" || verb === "head")) {
|
|
1647
|
-
entryType.push(kleur2.yellow("page"));
|
|
1648
|
-
if (verb === "get") {
|
|
1649
|
-
size = prettySize(computeRouteSize(route, bundle));
|
|
1650
|
-
}
|
|
1651
|
-
}
|
|
1652
|
-
const row = [verbCell];
|
|
1653
|
-
if (verbs.length === 1 || firstRow) {
|
|
1654
|
-
row.push({ rowSpan: verbs.length, content: prettyPath(path6.path) });
|
|
1655
|
-
firstRow = false;
|
|
1671
|
+
const verbs = getVerbs(route, true);
|
|
1672
|
+
let firstRow = true;
|
|
1673
|
+
for (const verb of verbs) {
|
|
1674
|
+
const entryType = [];
|
|
1675
|
+
let size = "";
|
|
1676
|
+
const verbCell = verbColor(verb)(verb.toUpperCase());
|
|
1677
|
+
if (route.handler) {
|
|
1678
|
+
entryType.push(kleur2.blue("handler"));
|
|
1679
|
+
}
|
|
1680
|
+
if (route.page && (verb === "get" || verb === "head")) {
|
|
1681
|
+
entryType.push(kleur2.yellow("page"));
|
|
1682
|
+
if (verb === "get") {
|
|
1683
|
+
size = prettySize(computeRouteSize(route, bundle));
|
|
1656
1684
|
}
|
|
1657
|
-
row.push(entryType.join(" -> "));
|
|
1658
|
-
hasMiddleware && row.push(route.middleware.length || "");
|
|
1659
|
-
hasMeta && row.push(route.meta ? "\u2713" : "");
|
|
1660
|
-
row.push(size || "");
|
|
1661
|
-
table.push(row);
|
|
1662
1685
|
}
|
|
1686
|
+
const row = [verbCell];
|
|
1687
|
+
if (verbs.length === 1 || firstRow) {
|
|
1688
|
+
row.push({
|
|
1689
|
+
rowSpan: verbs.length,
|
|
1690
|
+
content: prettyPath(route.path.path)
|
|
1691
|
+
});
|
|
1692
|
+
firstRow = false;
|
|
1693
|
+
}
|
|
1694
|
+
row.push(entryType.join(" -> "));
|
|
1695
|
+
hasMiddleware && row.push(route.middleware.length || "");
|
|
1696
|
+
hasMeta && row.push(route.meta ? "\u2713" : "");
|
|
1697
|
+
row.push(size || "");
|
|
1698
|
+
table.push(row);
|
|
1663
1699
|
}
|
|
1664
1700
|
}
|
|
1665
1701
|
for (const [key, route] of Object.entries(routes.special).sort()) {
|
|
@@ -1715,17 +1751,20 @@ function prettySize([bytes, compBytes]) {
|
|
|
1715
1751
|
else str += kleur2.bold(kleur2.red(compSize));
|
|
1716
1752
|
return str;
|
|
1717
1753
|
}
|
|
1718
|
-
function prettyPath(
|
|
1719
|
-
return
|
|
1754
|
+
function prettyPath(path8) {
|
|
1755
|
+
return path8.replace(
|
|
1756
|
+
/\/(\$\$?)(`?)([^/`]+)\2/g,
|
|
1757
|
+
(_, type, tick, key) => "/" + type + tick + kleur2.bold(kleur2.dim(key)) + tick
|
|
1758
|
+
);
|
|
1720
1759
|
}
|
|
1721
1760
|
|
|
1722
1761
|
// src/vite/utils/read-once-persisted-store.ts
|
|
1723
1762
|
import { promises as fs2 } from "fs";
|
|
1724
1763
|
import os from "os";
|
|
1725
|
-
import
|
|
1764
|
+
import path5 from "path";
|
|
1726
1765
|
var noop = () => {
|
|
1727
1766
|
};
|
|
1728
|
-
var tmpFile =
|
|
1767
|
+
var tmpFile = path5.join(os.tmpdir(), "marko-run-storage.json");
|
|
1729
1768
|
var values = /* @__PURE__ */ new Map();
|
|
1730
1769
|
var loadedFromDisk;
|
|
1731
1770
|
var ReadOncePersistedStore = class {
|
|
@@ -1767,17 +1806,17 @@ process.once("beforeExit", (code) => {
|
|
|
1767
1806
|
|
|
1768
1807
|
// src/vite/plugin.ts
|
|
1769
1808
|
var debug = createDebug("@marko/run");
|
|
1770
|
-
var __dirname =
|
|
1809
|
+
var __dirname = path6.dirname(fileURLToPath(import.meta.url));
|
|
1771
1810
|
var PLUGIN_NAME_PREFIX = "marko-run-vite";
|
|
1772
|
-
var POSIX_SEP = "/";
|
|
1773
|
-
var WINDOWS_SEP = "\\";
|
|
1774
1811
|
var CLIENT_OUT_DIR = "public";
|
|
1775
1812
|
var MIDDLEWARE_FILENAME = `${markoRunFilePrefix}middleware.js`;
|
|
1776
1813
|
var ROUTER_FILENAME = `${markoRunFilePrefix}router.js`;
|
|
1777
1814
|
var defaultPort = Number(process.env.PORT || 3e3);
|
|
1778
|
-
var normalizePath = path4.sep === WINDOWS_SEP ? (id) => id.replace(/\\/g, POSIX_SEP) : (id) => id;
|
|
1779
1815
|
function markoRun(opts = {}) {
|
|
1780
|
-
let
|
|
1816
|
+
let routesDir;
|
|
1817
|
+
let adapter;
|
|
1818
|
+
let trailingSlashes;
|
|
1819
|
+
const { ...markoVitePluginOptions } = opts;
|
|
1781
1820
|
let store;
|
|
1782
1821
|
let root;
|
|
1783
1822
|
let shouldEmptyOutDir = false;
|
|
@@ -1810,12 +1849,8 @@ function markoRun(opts = {}) {
|
|
|
1810
1849
|
root,
|
|
1811
1850
|
"{.tsconfig*,tsconfig*.json}"
|
|
1812
1851
|
)))) {
|
|
1813
|
-
const filepath =
|
|
1814
|
-
const data = await renderRouteTypeInfo(
|
|
1815
|
-
routes2,
|
|
1816
|
-
normalizePath(path4.relative(typesDir, resolvedRoutesDir)),
|
|
1817
|
-
adapter
|
|
1818
|
-
);
|
|
1852
|
+
const filepath = path6.join(typesDir, "routes.d.ts");
|
|
1853
|
+
const data = await renderRouteTypeInfo(routes2, typesDir, adapter);
|
|
1819
1854
|
if (data !== typesFile || !fs3.existsSync(filepath)) {
|
|
1820
1855
|
await ensureDir(typesDir);
|
|
1821
1856
|
await fs3.promises.writeFile(filepath, typesFile = data);
|
|
@@ -1826,20 +1861,25 @@ function markoRun(opts = {}) {
|
|
|
1826
1861
|
function buildVirtualFiles() {
|
|
1827
1862
|
return buildVirtualFilesResult ?? (buildVirtualFilesResult = (async () => {
|
|
1828
1863
|
virtualFiles.clear();
|
|
1829
|
-
routes = await buildRoutes(
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1864
|
+
routes = await buildRoutes(
|
|
1865
|
+
{
|
|
1866
|
+
walker: createFSWalker(resolvedRoutesDir)
|
|
1867
|
+
},
|
|
1868
|
+
entryFilesDir
|
|
1869
|
+
);
|
|
1833
1870
|
if (!routes.list.length) {
|
|
1834
1871
|
throw new Error("No routes generated");
|
|
1835
1872
|
}
|
|
1836
1873
|
for (const route of routes.list) {
|
|
1837
|
-
virtualFiles.set(
|
|
1874
|
+
virtualFiles.set(
|
|
1875
|
+
path6.posix.join(root, getRouteVirtualFileName(route)),
|
|
1876
|
+
""
|
|
1877
|
+
);
|
|
1838
1878
|
}
|
|
1839
1879
|
if (routes.middleware.length) {
|
|
1840
|
-
virtualFiles.set(
|
|
1880
|
+
virtualFiles.set(path6.posix.join(root, MIDDLEWARE_FILENAME), "");
|
|
1841
1881
|
}
|
|
1842
|
-
virtualFiles.set(
|
|
1882
|
+
virtualFiles.set(path6.posix.join(root, ROUTER_FILENAME), "");
|
|
1843
1883
|
return routes;
|
|
1844
1884
|
})());
|
|
1845
1885
|
}
|
|
@@ -1853,111 +1893,78 @@ function markoRun(opts = {}) {
|
|
|
1853
1893
|
fs3.rmSync(entryFilesDir, { recursive: true });
|
|
1854
1894
|
}
|
|
1855
1895
|
for (const route of routes2.list) {
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1896
|
+
if (route.handler) {
|
|
1897
|
+
const exports = await getExportsFromFile(
|
|
1898
|
+
context,
|
|
1899
|
+
route.handler.filePath
|
|
1900
|
+
);
|
|
1901
|
+
route.handler.verbs = [];
|
|
1860
1902
|
for (const name of exports) {
|
|
1861
1903
|
const verb = name.toLowerCase();
|
|
1862
1904
|
if (name === verb.toUpperCase() && httpVerbs.includes(verb)) {
|
|
1863
|
-
handler.verbs.push(verb);
|
|
1905
|
+
route.handler.verbs.push(verb);
|
|
1864
1906
|
}
|
|
1865
1907
|
}
|
|
1866
|
-
if (!handler.verbs.length) {
|
|
1908
|
+
if (!route.handler.verbs.length) {
|
|
1867
1909
|
context.warn(
|
|
1868
|
-
`Did not find any http verb exports in
|
|
1910
|
+
`Did not find any http verb exports in ${path6.relative(root, route.handler.filePath)} - expected ${httpVerbs.map((v) => v.toUpperCase()).join(", ")}`
|
|
1869
1911
|
);
|
|
1870
1912
|
}
|
|
1871
1913
|
}
|
|
1872
|
-
if (
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
path4.relative(routeFileDir, root)
|
|
1881
|
-
);
|
|
1882
|
-
fs3.mkdirSync(routeFileDir, { recursive: true });
|
|
1883
|
-
const pageNameIndex = page.name.indexOf("+page");
|
|
1884
|
-
const pageNamePrefix = pageNameIndex > 0 ? `${page.name.slice(0, pageNameIndex)}.` : "";
|
|
1885
|
-
fs3.writeFileSync(
|
|
1886
|
-
route.templateFilePath = path4.join(
|
|
1887
|
-
routeFileDir,
|
|
1888
|
-
pageNamePrefix + "route.marko"
|
|
1889
|
-
),
|
|
1890
|
-
renderRouteTemplate(
|
|
1891
|
-
route,
|
|
1892
|
-
(to) => path4.posix.join(routeFileRelativePathPosix, to)
|
|
1893
|
-
)
|
|
1894
|
-
);
|
|
1895
|
-
} else {
|
|
1896
|
-
route.templateFilePath = page.filePath;
|
|
1897
|
-
}
|
|
1914
|
+
if (route.templateFilePath) {
|
|
1915
|
+
fs3.mkdirSync(path6.dirname(route.templateFilePath), {
|
|
1916
|
+
recursive: true
|
|
1917
|
+
});
|
|
1918
|
+
fs3.writeFileSync(
|
|
1919
|
+
route.templateFilePath,
|
|
1920
|
+
renderRouteTemplate(route, root)
|
|
1921
|
+
);
|
|
1898
1922
|
}
|
|
1899
1923
|
virtualFiles.set(
|
|
1900
|
-
|
|
1901
|
-
renderRouteEntry(route,
|
|
1924
|
+
path6.posix.join(root, getRouteVirtualFileName(route)),
|
|
1925
|
+
renderRouteEntry(route, root)
|
|
1902
1926
|
);
|
|
1903
1927
|
}
|
|
1904
1928
|
for (const route of Object.values(routes2.special)) {
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
)
|
|
1912
|
-
|
|
1913
|
-
const routeFileRelativePathPosix = normalizePath(
|
|
1914
|
-
path4.relative(routeFileDir, root)
|
|
1915
|
-
);
|
|
1916
|
-
fs3.mkdirSync(routeFileDir, { recursive: true });
|
|
1917
|
-
fs3.writeFileSync(
|
|
1918
|
-
route.templateFilePath = path4.join(
|
|
1919
|
-
routeFileDir,
|
|
1920
|
-
`route.${key}.marko`
|
|
1921
|
-
),
|
|
1922
|
-
renderRouteTemplate(
|
|
1923
|
-
route,
|
|
1924
|
-
(to) => path4.posix.join(routeFileRelativePathPosix, to)
|
|
1925
|
-
)
|
|
1926
|
-
);
|
|
1927
|
-
} else {
|
|
1928
|
-
route.templateFilePath = page.filePath;
|
|
1929
|
-
}
|
|
1929
|
+
if (route.templateFilePath) {
|
|
1930
|
+
fs3.mkdirSync(path6.dirname(route.templateFilePath), {
|
|
1931
|
+
recursive: true
|
|
1932
|
+
});
|
|
1933
|
+
fs3.writeFileSync(
|
|
1934
|
+
route.templateFilePath,
|
|
1935
|
+
renderRouteTemplate(route, root)
|
|
1936
|
+
);
|
|
1930
1937
|
}
|
|
1931
1938
|
}
|
|
1932
1939
|
if (routes2.middleware.length) {
|
|
1933
1940
|
for (const middleware of routes2.middleware) {
|
|
1934
1941
|
if (!(await getExportsFromFile(context, middleware.filePath)).includes("default")) {
|
|
1935
1942
|
context.warn(
|
|
1936
|
-
`Did not find a default export in middleware '${
|
|
1943
|
+
`Did not find a default export in middleware '${path6.relative(root, middleware.filePath)}'`
|
|
1937
1944
|
);
|
|
1938
1945
|
}
|
|
1939
1946
|
}
|
|
1940
1947
|
virtualFiles.set(
|
|
1941
|
-
|
|
1942
|
-
renderMiddleware(routes2.middleware)
|
|
1948
|
+
path6.posix.join(root, MIDDLEWARE_FILENAME),
|
|
1949
|
+
renderMiddleware(routes2.middleware, root)
|
|
1943
1950
|
);
|
|
1944
1951
|
}
|
|
1945
1952
|
virtualFiles.set(
|
|
1946
|
-
|
|
1947
|
-
renderRouter(routes2,
|
|
1948
|
-
trailingSlashes
|
|
1953
|
+
path6.posix.join(root, ROUTER_FILENAME),
|
|
1954
|
+
renderRouter(routes2, root, {
|
|
1955
|
+
trailingSlashes
|
|
1949
1956
|
})
|
|
1950
1957
|
);
|
|
1951
1958
|
await writeTypesFile(routes2);
|
|
1952
1959
|
if (adapter == null ? void 0 : adapter.routesGenerated) {
|
|
1953
|
-
await adapter.routesGenerated(
|
|
1954
|
-
routes2,
|
|
1955
|
-
new Map(virtualFiles.entries()),
|
|
1956
|
-
{
|
|
1960
|
+
await adapter.routesGenerated({
|
|
1961
|
+
routes: routes2,
|
|
1962
|
+
virtualFiles: new Map(virtualFiles.entries()),
|
|
1963
|
+
meta: {
|
|
1957
1964
|
buildTime: times.routesBuild,
|
|
1958
1965
|
renderTime: times.routesRender
|
|
1959
1966
|
}
|
|
1960
|
-
);
|
|
1967
|
+
});
|
|
1961
1968
|
if (!isBuild) {
|
|
1962
1969
|
await ((_a = opts == null ? void 0 : opts.emitRoutes) == null ? void 0 : _a.call(opts, routes2.list));
|
|
1963
1970
|
}
|
|
@@ -1967,7 +1974,7 @@ function markoRun(opts = {}) {
|
|
|
1967
1974
|
throw err;
|
|
1968
1975
|
}
|
|
1969
1976
|
virtualFiles.set(
|
|
1970
|
-
|
|
1977
|
+
path6.posix.join(root, ROUTER_FILENAME),
|
|
1971
1978
|
`throw ${JSON.stringify(prepareError(err))}`
|
|
1972
1979
|
);
|
|
1973
1980
|
}
|
|
@@ -2004,27 +2011,28 @@ function markoRun(opts = {}) {
|
|
|
2004
2011
|
}
|
|
2005
2012
|
}
|
|
2006
2013
|
routesDir = opts.routesDir || "src/routes";
|
|
2014
|
+
trailingSlashes = opts.trailingSlashes || "RedirectWithout";
|
|
2007
2015
|
store = new ReadOncePersistedStore(
|
|
2008
2016
|
`vite-marko-run${opts.runtimeId ? `-${opts.runtimeId}` : ""}`
|
|
2009
2017
|
);
|
|
2010
2018
|
markoVitePluginOptions.runtimeId = opts.runtimeId;
|
|
2011
2019
|
markoVitePluginOptions.basePathVar = opts.basePathVar;
|
|
2012
|
-
resolvedRoutesDir =
|
|
2013
|
-
outputDir =
|
|
2014
|
-
entryFilesDir =
|
|
2020
|
+
resolvedRoutesDir = path6.resolve(root, routesDir);
|
|
2021
|
+
outputDir = path6.join(root, ((_d = config2.build) == null ? void 0 : _d.outDir) || "dist");
|
|
2022
|
+
entryFilesDir = path6.join(outputDir, ".marko-run");
|
|
2015
2023
|
entryFilesDirPosix = normalizePath(entryFilesDir);
|
|
2016
2024
|
relativeEntryFilesDirPosix = normalizePath(
|
|
2017
|
-
|
|
2025
|
+
path6.relative(root, entryFilesDir)
|
|
2018
2026
|
);
|
|
2019
|
-
typesDir =
|
|
2020
|
-
devEntryFile =
|
|
2027
|
+
typesDir = path6.join(root, ".marko-run");
|
|
2028
|
+
devEntryFile = path6.join(root, "index.html");
|
|
2021
2029
|
devEntryFilePosix = normalizePath(devEntryFile);
|
|
2022
2030
|
let outDir = ((_e = config2.build) == null ? void 0 : _e.outDir) || "dist";
|
|
2023
2031
|
const assetsDir = ((_f = config2.build) == null ? void 0 : _f.assetsDir) || "assets";
|
|
2024
2032
|
let rollupOutputOptions = (_h = (_g = config2.build) == null ? void 0 : _g.rollupOptions) == null ? void 0 : _h.output;
|
|
2025
2033
|
if (isBuild) {
|
|
2026
2034
|
if (!isSSRBuild) {
|
|
2027
|
-
outDir =
|
|
2035
|
+
outDir = path6.join(outDir, CLIENT_OUT_DIR);
|
|
2028
2036
|
}
|
|
2029
2037
|
const defaultRollupOutputOptions = {
|
|
2030
2038
|
assetFileNames({ name }) {
|
|
@@ -2149,7 +2157,7 @@ function markoRun(opts = {}) {
|
|
|
2149
2157
|
devServer.watcher.on("all", async (type, filename) => {
|
|
2150
2158
|
seenErrors.clear();
|
|
2151
2159
|
const routableFileType = matchRoutableFile(
|
|
2152
|
-
|
|
2160
|
+
path6.parse(filename).base
|
|
2153
2161
|
);
|
|
2154
2162
|
if (filename.startsWith(resolvedRoutesDir) && routableFileType) {
|
|
2155
2163
|
if (type === "add" || type === "unlink" || type === "change" && (routableFileType === RoutableFileTypes.Handler || routableFileType === RoutableFileTypes.Middleware)) {
|
|
@@ -2199,19 +2207,19 @@ function markoRun(opts = {}) {
|
|
|
2199
2207
|
},
|
|
2200
2208
|
async resolveId(importee, importer) {
|
|
2201
2209
|
if (importee === "@marko/run/router") {
|
|
2202
|
-
return normalizePath(
|
|
2210
|
+
return normalizePath(path6.resolve(root, ROUTER_FILENAME));
|
|
2203
2211
|
} else if (importee.endsWith(".marko") && importee.includes(relativeEntryFilesDirPosix)) {
|
|
2204
2212
|
if (!importee.startsWith(root)) {
|
|
2205
|
-
importee =
|
|
2213
|
+
importee = path6.resolve(root, "." + importee);
|
|
2206
2214
|
}
|
|
2207
2215
|
return normalizePath(importee);
|
|
2208
2216
|
}
|
|
2209
2217
|
let virtualFilePath;
|
|
2210
2218
|
if (importee.startsWith(virtualFilePrefix)) {
|
|
2211
2219
|
virtualFilePath = importee.slice(virtualFilePrefix.length + 1);
|
|
2212
|
-
importee =
|
|
2220
|
+
importee = path6.resolve(root, virtualFilePath);
|
|
2213
2221
|
} else if (!isBuild && importer && (importer === devEntryFile || normalizePath(importer) === devEntryFilePosix) && importee.startsWith(`/${markoRunFilePrefix}`)) {
|
|
2214
|
-
importee =
|
|
2222
|
+
importee = path6.resolve(root, "." + importee);
|
|
2215
2223
|
}
|
|
2216
2224
|
importee = normalizePath(importee);
|
|
2217
2225
|
if (!buildVirtualFilesResult) {
|
|
@@ -2220,7 +2228,7 @@ function markoRun(opts = {}) {
|
|
|
2220
2228
|
if (virtualFiles.has(importee)) {
|
|
2221
2229
|
return importee;
|
|
2222
2230
|
} else if (virtualFilePath) {
|
|
2223
|
-
const filePath =
|
|
2231
|
+
const filePath = path6.resolve(__dirname, "..", virtualFilePath);
|
|
2224
2232
|
return await this.resolve(filePath, importer, {
|
|
2225
2233
|
skipSelf: true
|
|
2226
2234
|
});
|
|
@@ -2259,7 +2267,7 @@ function markoRun(opts = {}) {
|
|
|
2259
2267
|
const builtEntries = Object.values(bundle).reduce(
|
|
2260
2268
|
(acc, item) => {
|
|
2261
2269
|
if (item.type === "chunk" && item.isEntry) {
|
|
2262
|
-
acc.push(
|
|
2270
|
+
acc.push(path6.join(options.dir, item.fileName));
|
|
2263
2271
|
}
|
|
2264
2272
|
return acc;
|
|
2265
2273
|
},
|
|
@@ -2287,12 +2295,12 @@ function markoRun(opts = {}) {
|
|
|
2287
2295
|
fs3.rmSync(entryFilesDir, { recursive: true });
|
|
2288
2296
|
}
|
|
2289
2297
|
if ((adapter == null ? void 0 : adapter.buildEnd) && routes) {
|
|
2290
|
-
await adapter.buildEnd(
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
routeData.builtEntries,
|
|
2294
|
-
routeData.sourceEntries
|
|
2295
|
-
);
|
|
2298
|
+
await adapter.buildEnd({
|
|
2299
|
+
routes,
|
|
2300
|
+
config: resolvedConfig,
|
|
2301
|
+
builtEntries: routeData.builtEntries,
|
|
2302
|
+
sourceEntries: routeData.sourceEntries
|
|
2303
|
+
});
|
|
2296
2304
|
}
|
|
2297
2305
|
}
|
|
2298
2306
|
}
|
|
@@ -2324,11 +2332,11 @@ async function ensureDir(dir) {
|
|
|
2324
2332
|
}
|
|
2325
2333
|
async function getPackageData(dir) {
|
|
2326
2334
|
do {
|
|
2327
|
-
const pkgPath =
|
|
2335
|
+
const pkgPath = path6.join(dir, "package.json");
|
|
2328
2336
|
if (fs3.existsSync(pkgPath)) {
|
|
2329
2337
|
return JSON.parse(await fs3.promises.readFile(pkgPath, "utf-8"));
|
|
2330
2338
|
}
|
|
2331
|
-
} while (dir !== (dir =
|
|
2339
|
+
} while (dir !== (dir = path6.dirname(dir)));
|
|
2332
2340
|
return null;
|
|
2333
2341
|
}
|
|
2334
2342
|
async function resolveAdapter(root, options, log) {
|
|
@@ -2433,7 +2441,7 @@ async function getAvailablePort(port) {
|
|
|
2433
2441
|
}
|
|
2434
2442
|
|
|
2435
2443
|
// src/cli/commands.ts
|
|
2436
|
-
var __dirname2 =
|
|
2444
|
+
var __dirname2 = path7.dirname(fileURLToPath2(import.meta.url));
|
|
2437
2445
|
var defaultConfigFileBases = ["vite.config"];
|
|
2438
2446
|
var defaultConfigFileExts = [".js", ".cjs", ".mjs", ".ts", ".mts"];
|
|
2439
2447
|
async function preview(entry, distEntry, cwd, configFile, port, outDir, envFile, args = []) {
|
|
@@ -2462,10 +2470,10 @@ async function preview(entry, distEntry, cwd, configFile, port, outDir, envFile,
|
|
|
2462
2470
|
if (!entry) {
|
|
2463
2471
|
entry = await ((_a = adapter.getEntryFile) == null ? void 0 : _a.call(adapter));
|
|
2464
2472
|
}
|
|
2465
|
-
const dir =
|
|
2466
|
-
const entryFile = distEntry ?
|
|
2473
|
+
const dir = path7.resolve(cwd, resolvedConfig.build.outDir);
|
|
2474
|
+
const entryFile = distEntry ? path7.join(dir, distEntry) : findFileWithExt(dir, "index", [".mjs", ".js"]);
|
|
2467
2475
|
if (envFile) {
|
|
2468
|
-
envFile =
|
|
2476
|
+
envFile = path7.resolve(cwd, envFile);
|
|
2469
2477
|
}
|
|
2470
2478
|
const options = {
|
|
2471
2479
|
cwd,
|
|
@@ -2475,7 +2483,10 @@ async function preview(entry, distEntry, cwd, configFile, port, outDir, envFile,
|
|
|
2475
2483
|
envFile,
|
|
2476
2484
|
entry
|
|
2477
2485
|
};
|
|
2478
|
-
return await adapter.startPreview(
|
|
2486
|
+
return await adapter.startPreview({
|
|
2487
|
+
entry: entryFile,
|
|
2488
|
+
options
|
|
2489
|
+
});
|
|
2479
2490
|
}
|
|
2480
2491
|
async function dev(entry, cwd, configFile, port, envFile, args = []) {
|
|
2481
2492
|
var _a;
|
|
@@ -2489,7 +2500,7 @@ async function dev(entry, cwd, configFile, port, envFile, args = []) {
|
|
|
2489
2500
|
"serve"
|
|
2490
2501
|
);
|
|
2491
2502
|
if (envFile) {
|
|
2492
|
-
envFile =
|
|
2503
|
+
envFile = path7.resolve(cwd, envFile);
|
|
2493
2504
|
}
|
|
2494
2505
|
const [availablePort, adapter] = await Promise.all([
|
|
2495
2506
|
getAvailablePort(
|
|
@@ -2519,7 +2530,7 @@ async function dev(entry, cwd, configFile, port, envFile, args = []) {
|
|
|
2519
2530
|
port: availablePort,
|
|
2520
2531
|
envFile
|
|
2521
2532
|
};
|
|
2522
|
-
return await adapter.startDev(entry, config2, options);
|
|
2533
|
+
return await adapter.startDev({ entry, config: config2, options });
|
|
2523
2534
|
}
|
|
2524
2535
|
async function build(entry, cwd, configFile, outDir, envFile) {
|
|
2525
2536
|
var _a;
|
|
@@ -2543,7 +2554,7 @@ async function build(entry, cwd, configFile, outDir, envFile) {
|
|
|
2543
2554
|
}
|
|
2544
2555
|
}
|
|
2545
2556
|
if (envFile) {
|
|
2546
|
-
envFile =
|
|
2557
|
+
envFile = path7.resolve(cwd, envFile);
|
|
2547
2558
|
}
|
|
2548
2559
|
const buildConfig = setExternalAdapterOptions(
|
|
2549
2560
|
{
|
|
@@ -2581,7 +2592,7 @@ async function build(entry, cwd, configFile, outDir, envFile) {
|
|
|
2581
2592
|
}
|
|
2582
2593
|
function findFileWithExt(dir, base, extensions = defaultConfigFileExts) {
|
|
2583
2594
|
for (const ext of extensions) {
|
|
2584
|
-
const filePath =
|
|
2595
|
+
const filePath = path7.join(dir, base + ext);
|
|
2585
2596
|
if (fs5.existsSync(filePath)) {
|
|
2586
2597
|
return filePath;
|
|
2587
2598
|
}
|
|
@@ -2590,7 +2601,7 @@ function findFileWithExt(dir, base, extensions = defaultConfigFileExts) {
|
|
|
2590
2601
|
}
|
|
2591
2602
|
async function getViteConfig(dir, configFile, bases = defaultConfigFileBases) {
|
|
2592
2603
|
if (configFile) {
|
|
2593
|
-
const configFilePath =
|
|
2604
|
+
const configFilePath = path7.join(dir, configFile);
|
|
2594
2605
|
if (!fs5.existsSync(configFilePath)) {
|
|
2595
2606
|
throw new Error(`No config file found at '${configFilePath}'`);
|
|
2596
2607
|
}
|
|
@@ -2602,7 +2613,7 @@ async function getViteConfig(dir, configFile, bases = defaultConfigFileBases) {
|
|
|
2602
2613
|
return configFile;
|
|
2603
2614
|
}
|
|
2604
2615
|
}
|
|
2605
|
-
return
|
|
2616
|
+
return path7.join(__dirname2, "default.config.mjs");
|
|
2606
2617
|
}
|
|
2607
2618
|
async function resolveAdapter2(config2) {
|
|
2608
2619
|
const options = getExternalPluginOptions(config2);
|