@marko/run 0.6.5 → 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 -405
- package/dist/runtime/index.d.ts +1 -1
- 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 +17 -7
- package/dist/vite/codegen/index.d.ts +5 -6
- package/dist/vite/index.cjs +417 -414
- package/dist/vite/index.js +399 -393
- 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/vite/index.js
CHANGED
|
@@ -16,9 +16,12 @@ import createDebug from "debug";
|
|
|
16
16
|
import { resolveToEsbuildTarget } from "esbuild-plugin-browserslist";
|
|
17
17
|
import fs3 from "fs";
|
|
18
18
|
import { glob } from "glob";
|
|
19
|
-
import
|
|
19
|
+
import path6 from "path";
|
|
20
20
|
import { fileURLToPath } from "url";
|
|
21
|
-
import {
|
|
21
|
+
import {
|
|
22
|
+
buildErrorMessage,
|
|
23
|
+
mergeConfig
|
|
24
|
+
} from "vite";
|
|
22
25
|
|
|
23
26
|
// src/adapter/utils.ts
|
|
24
27
|
import kleur from "kleur";
|
|
@@ -46,7 +49,7 @@ function prepareError(err) {
|
|
|
46
49
|
}
|
|
47
50
|
|
|
48
51
|
// src/vite/codegen/index.ts
|
|
49
|
-
import
|
|
52
|
+
import path2 from "path";
|
|
50
53
|
|
|
51
54
|
// src/vite/constants.ts
|
|
52
55
|
var markoRunFilePrefix = "__marko-run__";
|
|
@@ -71,6 +74,12 @@ var RoutableFileTypes = {
|
|
|
71
74
|
Error: "500"
|
|
72
75
|
};
|
|
73
76
|
|
|
77
|
+
// src/vite/utils/fs.ts
|
|
78
|
+
import path from "path";
|
|
79
|
+
var POSIX_SEP = "/";
|
|
80
|
+
var WINDOWS_SEP = "\\";
|
|
81
|
+
var normalizePath = path.sep === WINDOWS_SEP ? (id) => id.replace(/\\/g, POSIX_SEP) : (id) => id;
|
|
82
|
+
|
|
74
83
|
// src/vite/utils/route.ts
|
|
75
84
|
var httpVerbOrder = httpVerbs.reduce(
|
|
76
85
|
(order, verb, index) => {
|
|
@@ -94,6 +103,9 @@ function hasVerb(route, verb) {
|
|
|
94
103
|
var _a, _b;
|
|
95
104
|
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");
|
|
96
105
|
}
|
|
106
|
+
function getRouteVirtualFileName(route) {
|
|
107
|
+
return `${markoRunFilePrefix}${route.key.replace(/\//g, ".")}.js`;
|
|
108
|
+
}
|
|
97
109
|
|
|
98
110
|
// src/vite/codegen/writer.ts
|
|
99
111
|
function createWriter(sink, options) {
|
|
@@ -236,27 +248,34 @@ function createStringWriter(opts) {
|
|
|
236
248
|
}
|
|
237
249
|
|
|
238
250
|
// src/vite/codegen/index.ts
|
|
239
|
-
function
|
|
251
|
+
function normalizedRelativePath(from, to) {
|
|
252
|
+
const relativePath = normalizePath(path2.relative(from, to));
|
|
253
|
+
return relativePath.startsWith(".") ? relativePath : "./" + relativePath;
|
|
254
|
+
}
|
|
255
|
+
function renderRouteTemplate(route, rootDir) {
|
|
240
256
|
if (!route.page) {
|
|
241
257
|
throw new Error(`Route ${route.key} has no page to render`);
|
|
242
258
|
}
|
|
259
|
+
if (!route.templateFilePath) {
|
|
260
|
+
throw new Error(`Route ${route.key} has no template file path`);
|
|
261
|
+
}
|
|
243
262
|
return renderEntryTemplate(
|
|
244
|
-
route.
|
|
263
|
+
normalizedRelativePath(rootDir, route.templateFilePath),
|
|
245
264
|
[...route.layouts, route.page].map(
|
|
246
|
-
(file) =>
|
|
265
|
+
(file) => normalizedRelativePath(
|
|
266
|
+
path2.dirname(route.templateFilePath),
|
|
267
|
+
file.filePath
|
|
268
|
+
)
|
|
247
269
|
),
|
|
248
270
|
route.key === RoutableFileTypes.Error ? ["error"] : []
|
|
249
271
|
);
|
|
250
272
|
}
|
|
251
273
|
function renderEntryTemplate(name, files, pageInputs = []) {
|
|
252
|
-
if (!name) {
|
|
253
|
-
throw new Error(`Invalid argument - 'name' cannot be empty`);
|
|
254
|
-
}
|
|
255
274
|
if (!files.length) {
|
|
256
275
|
throw new Error(`Invalid argument - 'files' cannot be empty`);
|
|
257
276
|
}
|
|
258
277
|
const writer = createStringWriter();
|
|
259
|
-
writer.writeLines(`// ${name}
|
|
278
|
+
writer.writeLines(`// ${name}`);
|
|
260
279
|
writer.branch("imports");
|
|
261
280
|
writer.writeLines("");
|
|
262
281
|
writeEntryTemplateTag(writer, files, pageInputs);
|
|
@@ -266,7 +285,7 @@ function writeEntryTemplateTag(writer, [file, ...rest], pageInputs, index = 1) {
|
|
|
266
285
|
if (file) {
|
|
267
286
|
const isLast = !rest.length;
|
|
268
287
|
const tag = isLast ? "Page" : `Layout${index}`;
|
|
269
|
-
writer.branch("imports").writeLines(`import ${tag} from
|
|
288
|
+
writer.branch("imports").writeLines(`import ${tag} from "${file}";`);
|
|
270
289
|
if (isLast) {
|
|
271
290
|
const attributes = pageInputs.length ? " " + pageInputs.map((name) => `${name}=input.${name}`).join(" ") : "";
|
|
272
291
|
writer.writeLines(`<${tag}${attributes}/>`);
|
|
@@ -277,9 +296,9 @@ function writeEntryTemplateTag(writer, [file, ...rest], pageInputs, index = 1) {
|
|
|
277
296
|
}
|
|
278
297
|
}
|
|
279
298
|
}
|
|
280
|
-
function renderRouteEntry(route,
|
|
299
|
+
function renderRouteEntry(route, rootDir) {
|
|
281
300
|
var _a;
|
|
282
|
-
const { key, index, handler, page, middleware, meta
|
|
301
|
+
const { key, index, handler, page, middleware, meta } = route;
|
|
283
302
|
const verbs = getVerbs(route);
|
|
284
303
|
if (!verbs) {
|
|
285
304
|
throw new Error(
|
|
@@ -287,7 +306,7 @@ function renderRouteEntry(route, entriesDir) {
|
|
|
287
306
|
);
|
|
288
307
|
}
|
|
289
308
|
const writer = createStringWriter();
|
|
290
|
-
writer.writeLines(`// ${virtualFilePrefix}
|
|
309
|
+
writer.writeLines(`// ${virtualFilePrefix}${getRouteVirtualFileName(route)}`);
|
|
291
310
|
const imports = writer.branch("imports");
|
|
292
311
|
const runtimeImports = [];
|
|
293
312
|
if (handler) {
|
|
@@ -299,9 +318,6 @@ function renderRouteEntry(route, entriesDir) {
|
|
|
299
318
|
if (!page || verbs.some((verb) => verb !== "get" && verb !== "head")) {
|
|
300
319
|
runtimeImports.push("noContent");
|
|
301
320
|
}
|
|
302
|
-
if (page) {
|
|
303
|
-
runtimeImports.push("pageResponse");
|
|
304
|
-
}
|
|
305
321
|
if (verbs.includes("head")) {
|
|
306
322
|
runtimeImports.push("stripResponseBody");
|
|
307
323
|
}
|
|
@@ -309,7 +325,7 @@ function renderRouteEntry(route, entriesDir) {
|
|
|
309
325
|
imports.writeLines(
|
|
310
326
|
`import { ${runtimeImports.join(
|
|
311
327
|
", "
|
|
312
|
-
)} } from
|
|
328
|
+
)} } from "${virtualFilePrefix}/runtime/internal";`
|
|
313
329
|
);
|
|
314
330
|
}
|
|
315
331
|
if (middleware.length) {
|
|
@@ -317,7 +333,7 @@ function renderRouteEntry(route, entriesDir) {
|
|
|
317
333
|
imports.writeLines(
|
|
318
334
|
`import { ${names.join(
|
|
319
335
|
", "
|
|
320
|
-
)} } from
|
|
336
|
+
)} } from "${virtualFilePrefix}/${markoRunFilePrefix}middleware.js";`
|
|
321
337
|
);
|
|
322
338
|
}
|
|
323
339
|
if ((_a = handler == null ? void 0 : handler.verbs) == null ? void 0 : _a.length) {
|
|
@@ -329,18 +345,17 @@ function renderRouteEntry(route, entriesDir) {
|
|
|
329
345
|
writer.writeLines(`const ${verb}Handler = normalize(${importName});`);
|
|
330
346
|
}
|
|
331
347
|
imports.writeLines(
|
|
332
|
-
`import { ${names.join(", ")} } from
|
|
348
|
+
`import { ${names.join(", ")} } from "${normalizedRelativePath(rootDir, handler.filePath)}";`
|
|
333
349
|
);
|
|
334
350
|
}
|
|
335
351
|
if (page) {
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
imports.writeLines(`import page from '${importPath}${serverEntryQuery}';`);
|
|
352
|
+
imports.writeLines(
|
|
353
|
+
`import page from "${normalizedRelativePath(rootDir, route.templateFilePath || page.filePath)}${serverEntryQuery}";`
|
|
354
|
+
);
|
|
340
355
|
}
|
|
341
356
|
if (meta) {
|
|
342
357
|
imports.writeLines(
|
|
343
|
-
`export { default as meta${index} } from
|
|
358
|
+
`export { default as meta${index} } from "${normalizedRelativePath(rootDir, meta.filePath)}";`
|
|
344
359
|
);
|
|
345
360
|
}
|
|
346
361
|
for (const verb of verbs) {
|
|
@@ -357,9 +372,7 @@ function writeRouteEntryHandler(writer, route, verb) {
|
|
|
357
372
|
let hasBody = false;
|
|
358
373
|
writer.writeLines("");
|
|
359
374
|
if (page && (verb === "get" || verb === "head")) {
|
|
360
|
-
writer.writeBlockStart(
|
|
361
|
-
`export function ${verb}${index}(context, buildInput) {`
|
|
362
|
-
);
|
|
375
|
+
writer.writeBlockStart(`export function ${verb}${index}(context) {`);
|
|
363
376
|
} else {
|
|
364
377
|
writer.writeBlockStart(`export function ${verb}${index}(context) {`);
|
|
365
378
|
}
|
|
@@ -369,7 +382,7 @@ function writeRouteEntryHandler(writer, route, verb) {
|
|
|
369
382
|
if ((_a = handler == null ? void 0 : handler.verbs) == null ? void 0 : _a.includes(verb)) {
|
|
370
383
|
const name = `${verb}Handler`;
|
|
371
384
|
continuations.writeLines(
|
|
372
|
-
`const ${currentName} = () =>
|
|
385
|
+
`const ${currentName} = () => context.render(page, {});`
|
|
373
386
|
);
|
|
374
387
|
if (len) {
|
|
375
388
|
nextName = currentName;
|
|
@@ -388,17 +401,15 @@ function writeRouteEntryHandler(writer, route, verb) {
|
|
|
388
401
|
hasBody = true;
|
|
389
402
|
}
|
|
390
403
|
} else if (verb === "head") {
|
|
391
|
-
writer.writeLines(
|
|
392
|
-
`return stripResponseBody(get${index}(context, buildInput));`
|
|
393
|
-
);
|
|
404
|
+
writer.writeLines(`return stripResponseBody(get${index}(context));`);
|
|
394
405
|
hasBody = true;
|
|
395
406
|
} else if (len) {
|
|
396
407
|
continuations.writeLines(
|
|
397
|
-
`const ${currentName} = () =>
|
|
408
|
+
`const ${currentName} = () => context.render(page, {});`
|
|
398
409
|
);
|
|
399
410
|
nextName = currentName;
|
|
400
411
|
} else {
|
|
401
|
-
writer.writeLines(`return
|
|
412
|
+
writer.writeLines(`return context.render(page, {});`);
|
|
402
413
|
hasBody = true;
|
|
403
414
|
}
|
|
404
415
|
} else if ((_b = handler == null ? void 0 : handler.verbs) == null ? void 0 : _b.includes(verb)) {
|
|
@@ -448,7 +459,7 @@ function writeRouteEntryHandler(writer, route, verb) {
|
|
|
448
459
|
continuations.join();
|
|
449
460
|
writer.writeBlockEnd("}");
|
|
450
461
|
}
|
|
451
|
-
function renderRouter(routes,
|
|
462
|
+
function renderRouter(routes, rootDir, options = {
|
|
452
463
|
trailingSlashes: "RedirectWithout"
|
|
453
464
|
}) {
|
|
454
465
|
const writer = createStringWriter();
|
|
@@ -457,20 +468,19 @@ function renderRouter(routes, entriesDir, options = {
|
|
|
457
468
|
writer.writeLines(`// @marko/run/router`);
|
|
458
469
|
const imports = writer.branch("imports");
|
|
459
470
|
imports.writeLines(
|
|
460
|
-
`import { NotHandled, NotMatched, createContext
|
|
471
|
+
`import { NotHandled, NotMatched, createContext } from "${virtualFilePrefix}/runtime/internal";`
|
|
461
472
|
);
|
|
462
473
|
for (const route of routes.list) {
|
|
463
474
|
const verbs = getVerbs(route);
|
|
464
475
|
const names = verbs.map((verb) => `${verb}${route.index}`);
|
|
465
476
|
route.meta && names.push(`meta${route.index}`);
|
|
466
477
|
imports.writeLines(
|
|
467
|
-
`import { ${names.join(", ")} } from
|
|
478
|
+
`import { ${names.join(", ")} } from "${virtualFilePrefix}/${getRouteVirtualFileName(route)}";`
|
|
468
479
|
);
|
|
469
480
|
}
|
|
470
481
|
for (const route of Object.values(routes.special)) {
|
|
471
|
-
const importPath = route.layouts.length ? `./${path.posix.join(entriesDir, route.page.relativePath, "..", `route.${route.key}.marko`)}` : `./${route.page.importPath}`;
|
|
472
482
|
imports.writeLines(
|
|
473
|
-
`import page${route.key} from
|
|
483
|
+
`import page${route.key} from "${normalizedRelativePath(rootDir, route.templateFilePath || route.page.filePath)}${serverEntryQuery}";`
|
|
474
484
|
);
|
|
475
485
|
}
|
|
476
486
|
writer.writeLines(
|
|
@@ -478,11 +488,12 @@ function renderRouter(routes, entriesDir, options = {
|
|
|
478
488
|
globalThis.__marko_run__ = { match, fetch, invoke };
|
|
479
489
|
`
|
|
480
490
|
).writeBlockStart(`export function match(method, pathname) {`).writeLines(
|
|
481
|
-
`
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
491
|
+
`const last = pathname.length - 1;
|
|
492
|
+
return match_internal(method, last && pathname.charAt(last) === '/' ? pathname.slice(0, last) : pathname)
|
|
493
|
+
};
|
|
494
|
+
|
|
495
|
+
function match_internal(method, pathname) {
|
|
496
|
+
const len = pathname.length;`
|
|
486
497
|
).writeBlockStart(`switch (method) {`);
|
|
487
498
|
for (const verb of httpVerbs) {
|
|
488
499
|
const filteredRoutes = routes.list.filter((route) => hasVerb(route, verb));
|
|
@@ -498,13 +509,13 @@ globalThis.__marko_run__ = { match, fetch, invoke };
|
|
|
498
509
|
writer.writeLines("").writeBlockStart(
|
|
499
510
|
"export async function invoke(route, request, platform, url) {"
|
|
500
511
|
).writeLines(
|
|
501
|
-
"const
|
|
512
|
+
"const context = createContext(route, request, platform, url);"
|
|
502
513
|
);
|
|
503
514
|
if (hasErrorPage) {
|
|
504
515
|
writer.writeBlockStart("try {");
|
|
505
516
|
}
|
|
506
517
|
writer.writeBlockStart("if (route) {").writeBlockStart("try {").writeLines(
|
|
507
|
-
"const response = await route.handler(context
|
|
518
|
+
"const response = await route.handler(context);",
|
|
508
519
|
"if (response) return response;"
|
|
509
520
|
).indent--;
|
|
510
521
|
writer.writeBlockStart("} catch (error) {").writeLines(
|
|
@@ -521,7 +532,7 @@ const page404ResponseInit = {
|
|
|
521
532
|
);
|
|
522
533
|
writer.write(`
|
|
523
534
|
if (context.request.headers.get('Accept')?.includes('text/html')) {
|
|
524
|
-
return
|
|
535
|
+
return context.render(page404, {}, page404ResponseInit);
|
|
525
536
|
}`);
|
|
526
537
|
}
|
|
527
538
|
writer.indent--;
|
|
@@ -538,7 +549,7 @@ const page500ResponseInit = {
|
|
|
538
549
|
writer.writeBlockStart(`} catch (error) {`).writeBlockStart(
|
|
539
550
|
`if (context.request.headers.get('Accept')?.includes('text/html')) {`
|
|
540
551
|
).writeLines(
|
|
541
|
-
`return
|
|
552
|
+
`return context.render(page500, { error }, page500ResponseInit);`
|
|
542
553
|
).writeBlockEnd("}").writeLines("throw error;").writeBlockEnd("}");
|
|
543
554
|
}
|
|
544
555
|
writer.writeBlockEnd("}");
|
|
@@ -550,38 +561,40 @@ function renderFetch(writer, options) {
|
|
|
550
561
|
export async function fetch(request, platform) {
|
|
551
562
|
try {
|
|
552
563
|
const url = new URL(request.url);
|
|
553
|
-
|
|
564
|
+
const { pathname } = url;
|
|
565
|
+
const last = pathname.length - 1;
|
|
566
|
+
const hasTrailingSlash = last && pathname.charAt(last) === '/';
|
|
567
|
+
const normalizedPathname = hasTrailingSlash ? pathname.slice(0, last) : pathname;
|
|
568
|
+
const route = match_internal(request.method, normalizedPathname);`);
|
|
554
569
|
switch (options.trailingSlashes) {
|
|
555
570
|
case "RedirectWithout":
|
|
556
571
|
writer.write(`
|
|
557
|
-
if (
|
|
558
|
-
url.pathname =
|
|
572
|
+
if (route && hasTrailingSlash) {
|
|
573
|
+
url.pathname = normalizedPathname
|
|
559
574
|
return Response.redirect(url);
|
|
560
575
|
}`);
|
|
561
576
|
break;
|
|
562
577
|
case "RedirectWith":
|
|
563
578
|
writer.write(`
|
|
564
|
-
if (pathname !== '/' && !
|
|
565
|
-
url.pathname
|
|
579
|
+
if (route && pathname !== '/' && !hasTrailingSlash) {
|
|
580
|
+
url.pathname += '/';
|
|
566
581
|
return Response.redirect(url);
|
|
567
582
|
}`);
|
|
568
583
|
break;
|
|
569
584
|
case "RewriteWithout":
|
|
570
585
|
writer.write(`
|
|
571
|
-
if (
|
|
572
|
-
url.pathname =
|
|
586
|
+
if (route && hasTrailingSlash) {
|
|
587
|
+
url.pathname = normalizedPathname;
|
|
573
588
|
}`);
|
|
574
589
|
break;
|
|
575
590
|
case "RewriteWith":
|
|
576
591
|
writer.write(`
|
|
577
|
-
if (pathname !== '/' && !
|
|
578
|
-
url.pathname
|
|
592
|
+
if (route && pathname !== '/' && !hasTrailingSlash) {
|
|
593
|
+
url.pathname += '/';
|
|
579
594
|
}`);
|
|
580
595
|
break;
|
|
581
596
|
}
|
|
582
597
|
writer.write(`
|
|
583
|
-
|
|
584
|
-
const route = match(request.method, pathname);
|
|
585
598
|
return await invoke(route, request, platform, url);
|
|
586
599
|
} catch (error) {
|
|
587
600
|
if (import.meta.env.DEV) {
|
|
@@ -597,10 +610,9 @@ function writeRouterVerb(writer, trie, verb, level = 0, offset = 1) {
|
|
|
597
610
|
const { route, dynamic, catchAll } = trie;
|
|
598
611
|
let closeCount = 0;
|
|
599
612
|
if (level === 0) {
|
|
600
|
-
writer.writeLines(`const len = pathname.length;`);
|
|
601
613
|
if (route) {
|
|
602
614
|
writer.writeLines(
|
|
603
|
-
`if (len === 1) return ${renderMatch(verb, route, trie.path)}
|
|
615
|
+
`if (len === 1) return ${renderMatch(verb, route, trie.path)};`
|
|
604
616
|
);
|
|
605
617
|
} else if (trie.static || dynamic) {
|
|
606
618
|
writer.writeBlockStart(`if (len > 1) {`);
|
|
@@ -641,17 +653,15 @@ function writeRouterVerb(writer, trie, verb, level = 0, offset = 1) {
|
|
|
641
653
|
if (useSwitch) {
|
|
642
654
|
writer.writeBlockStart(`switch (${value}) {`);
|
|
643
655
|
}
|
|
644
|
-
for (const { key, path:
|
|
656
|
+
for (const { key, path: path7, route: route2 } of terminal) {
|
|
645
657
|
const decodedKey = decodeURIComponent(key);
|
|
646
658
|
if (useSwitch) {
|
|
647
659
|
writer.write(`case '${decodedKey}': `, true);
|
|
648
660
|
} else {
|
|
649
661
|
writer.write(`if (${value} === '${decodedKey}') `, true);
|
|
650
662
|
}
|
|
651
|
-
writer.write(
|
|
652
|
-
|
|
653
|
-
`
|
|
654
|
-
);
|
|
663
|
+
writer.write(`return ${renderMatch(verb, route2, path7)};
|
|
664
|
+
`);
|
|
655
665
|
}
|
|
656
666
|
if (useSwitch) {
|
|
657
667
|
writer.writeBlockEnd("}");
|
|
@@ -663,7 +673,7 @@ function writeRouterVerb(writer, trie, verb, level = 0, offset = 1) {
|
|
|
663
673
|
verb,
|
|
664
674
|
dynamic.route,
|
|
665
675
|
dynamic.path
|
|
666
|
-
)}
|
|
676
|
+
)};`
|
|
667
677
|
);
|
|
668
678
|
}
|
|
669
679
|
}
|
|
@@ -723,7 +733,7 @@ function writeRouterVerb(writer, trie, verb, level = 0, offset = 1) {
|
|
|
723
733
|
catchAll.route,
|
|
724
734
|
catchAll.path,
|
|
725
735
|
String(offset)
|
|
726
|
-
)}
|
|
736
|
+
)};`
|
|
727
737
|
);
|
|
728
738
|
} else if (level === 0) {
|
|
729
739
|
writer.writeLines("return null;");
|
|
@@ -752,43 +762,47 @@ function renderParams(params, pathIndex) {
|
|
|
752
762
|
}
|
|
753
763
|
return result ? result + " }" : "{}";
|
|
754
764
|
}
|
|
755
|
-
function renderMatch(verb, route,
|
|
765
|
+
function renderMatch(verb, route, path7, pathIndex) {
|
|
756
766
|
const handler = `${verb}${route.index}`;
|
|
757
|
-
const params =
|
|
767
|
+
const params = path7.params ? renderParams(path7.params, pathIndex) : "{}";
|
|
758
768
|
const meta = route.meta ? `meta${route.index}` : "{}";
|
|
759
|
-
|
|
760
|
-
return `{ handler: ${handler}, params: ${params}, meta: ${meta}, path: '${pathPattern}' }`;
|
|
769
|
+
return `{ handler: ${handler}, params: ${params}, meta: ${meta}, path: '${path7.path}' }`;
|
|
761
770
|
}
|
|
762
|
-
function renderMiddleware(middleware) {
|
|
771
|
+
function renderMiddleware(middleware, rootDir) {
|
|
763
772
|
const writer = createStringWriter();
|
|
764
773
|
writer.writeLines(
|
|
765
774
|
`// ${virtualFilePrefix}/${markoRunFilePrefix}middleware.js`
|
|
766
775
|
);
|
|
767
776
|
const imports = writer.branch("imports");
|
|
768
777
|
imports.writeLines(
|
|
769
|
-
`import { normalize } from
|
|
778
|
+
`import { normalize } from "${virtualFilePrefix}/runtime/internal";`
|
|
770
779
|
);
|
|
771
780
|
writer.writeLines("");
|
|
772
|
-
for (const { id,
|
|
781
|
+
for (const { id, filePath } of middleware) {
|
|
773
782
|
const importName = `middleware${id}`;
|
|
774
|
-
imports.writeLines(
|
|
783
|
+
imports.writeLines(
|
|
784
|
+
`import ${importName} from "${normalizedRelativePath(rootDir, filePath)}";`
|
|
785
|
+
);
|
|
775
786
|
writer.writeLines(`export const mware${id} = normalize(${importName});`);
|
|
776
787
|
}
|
|
777
788
|
imports.join();
|
|
778
789
|
return writer.end();
|
|
779
790
|
}
|
|
780
|
-
function stripTsExtension(
|
|
781
|
-
const index =
|
|
791
|
+
function stripTsExtension(path7) {
|
|
792
|
+
const index = path7.lastIndexOf(".");
|
|
782
793
|
if (index !== -1) {
|
|
783
|
-
const ext =
|
|
794
|
+
const ext = path7.slice(index + 1);
|
|
784
795
|
if (ext.toLowerCase() === "ts") {
|
|
785
|
-
return
|
|
796
|
+
return path7.slice(0, index);
|
|
786
797
|
}
|
|
787
798
|
}
|
|
788
|
-
return
|
|
799
|
+
return path7;
|
|
789
800
|
}
|
|
790
|
-
|
|
791
|
-
|
|
801
|
+
function decodePath(path7) {
|
|
802
|
+
return path7;
|
|
803
|
+
}
|
|
804
|
+
async function renderRouteTypeInfo(routes, outDir, adapter) {
|
|
805
|
+
var _a, _b, _c, _d;
|
|
792
806
|
const writer = createStringWriter();
|
|
793
807
|
writer.writeLines(
|
|
794
808
|
`/*
|
|
@@ -817,11 +831,31 @@ async function renderRouteTypeInfo(routes, pathPrefix = ".", adapter) {
|
|
|
817
831
|
const routeTypes = /* @__PURE__ */ new Map();
|
|
818
832
|
for (const route of routes.list) {
|
|
819
833
|
let routeType = "";
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
834
|
+
let routeDefinition = "";
|
|
835
|
+
if (route.page || route.handler) {
|
|
836
|
+
const verbs = [];
|
|
837
|
+
if (route.page || ((_b = (_a = route.handler) == null ? void 0 : _a.verbs) == null ? void 0 : _b.includes("get"))) {
|
|
838
|
+
verbs.push(`"get"`);
|
|
839
|
+
}
|
|
840
|
+
if ((_d = (_c = route.handler) == null ? void 0 : _c.verbs) == null ? void 0 : _d.includes("post")) {
|
|
841
|
+
verbs.push(`"post"`);
|
|
842
|
+
}
|
|
843
|
+
routeDefinition = `{ verb: ${verbs.join(" | ")};`;
|
|
844
|
+
if (route.meta) {
|
|
845
|
+
const metaPath = stripTsExtension(
|
|
846
|
+
normalizedRelativePath(outDir, route.meta.filePath)
|
|
847
|
+
);
|
|
848
|
+
let metaType = `typeof import("${metaPath}")`;
|
|
849
|
+
if (/\.(ts|js|mjs)$/.test(route.meta.name)) {
|
|
850
|
+
metaType += `["default"]`;
|
|
851
|
+
}
|
|
852
|
+
routeDefinition += ` meta: ${metaType};`;
|
|
853
|
+
}
|
|
854
|
+
routeDefinition += " }";
|
|
824
855
|
}
|
|
856
|
+
const pathType = `"${decodePath(route.path.path)}"`;
|
|
857
|
+
routeType += routeType ? " | " + pathType : pathType;
|
|
858
|
+
routesWriter.writeLines(`${pathType}: ${routeDefinition};`);
|
|
825
859
|
for (const file of [route.handler, route.page]) {
|
|
826
860
|
if (file) {
|
|
827
861
|
const existing = routeTypes.get(file);
|
|
@@ -854,33 +888,33 @@ async function renderRouteTypeInfo(routes, pathPrefix = ".", adapter) {
|
|
|
854
888
|
const pageWriter = writer.branch("page");
|
|
855
889
|
const layoutWriter = writer.branch("layout");
|
|
856
890
|
for (const [file, types] of routeTypes) {
|
|
857
|
-
const
|
|
891
|
+
const modulePath = stripTsExtension(
|
|
892
|
+
normalizedRelativePath(outDir, file.filePath)
|
|
893
|
+
);
|
|
858
894
|
const routeType = `Run.Routes[${types.join(" | ")}]`;
|
|
859
895
|
switch (file.type) {
|
|
860
896
|
case RoutableFileTypes.Handler:
|
|
861
|
-
writeModuleDeclaration(handlerWriter,
|
|
897
|
+
writeModuleDeclaration(handlerWriter, modulePath, routeType);
|
|
862
898
|
break;
|
|
863
899
|
case RoutableFileTypes.Middleware:
|
|
864
|
-
writeModuleDeclaration(middlewareWriter,
|
|
900
|
+
writeModuleDeclaration(middlewareWriter, modulePath, routeType);
|
|
865
901
|
break;
|
|
866
902
|
case RoutableFileTypes.Page:
|
|
867
|
-
writeModuleDeclaration(pageWriter,
|
|
903
|
+
writeModuleDeclaration(pageWriter, modulePath, routeType);
|
|
868
904
|
break;
|
|
869
905
|
case RoutableFileTypes.Layout:
|
|
870
906
|
writeModuleDeclaration(
|
|
871
907
|
layoutWriter,
|
|
872
|
-
|
|
908
|
+
modulePath,
|
|
873
909
|
routeType,
|
|
874
910
|
`
|
|
875
|
-
export interface Input {
|
|
876
|
-
[Run.ContentKeyFor<typeof import('${path5}')>]: Marko.Body;
|
|
877
|
-
}`
|
|
911
|
+
export interface Input extends Run.LayoutInput<typeof import("${modulePath}")> {}`
|
|
878
912
|
);
|
|
879
913
|
break;
|
|
880
914
|
case RoutableFileTypes.Error:
|
|
881
915
|
writeModuleDeclaration(
|
|
882
916
|
writer,
|
|
883
|
-
|
|
917
|
+
modulePath,
|
|
884
918
|
"globalThis.MarkoRun.Route",
|
|
885
919
|
`
|
|
886
920
|
export interface Input {
|
|
@@ -889,7 +923,7 @@ async function renderRouteTypeInfo(routes, pathPrefix = ".", adapter) {
|
|
|
889
923
|
);
|
|
890
924
|
break;
|
|
891
925
|
case RoutableFileTypes.NotFound:
|
|
892
|
-
writeModuleDeclaration(writer,
|
|
926
|
+
writeModuleDeclaration(writer, modulePath, "Run.Route");
|
|
893
927
|
break;
|
|
894
928
|
}
|
|
895
929
|
}
|
|
@@ -897,40 +931,15 @@ async function renderRouteTypeInfo(routes, pathPrefix = ".", adapter) {
|
|
|
897
931
|
middlewareWriter.join();
|
|
898
932
|
pageWriter.join();
|
|
899
933
|
layoutWriter.join();
|
|
900
|
-
writer.writeBlockStart(`
|
|
901
|
-
type Routes = {`);
|
|
902
|
-
for (const route of routes.list) {
|
|
903
|
-
const { meta, handler, page } = route;
|
|
904
|
-
if (page || handler) {
|
|
905
|
-
const verbs = [];
|
|
906
|
-
if (page || ((_a = handler == null ? void 0 : handler.verbs) == null ? void 0 : _a.includes("get"))) {
|
|
907
|
-
verbs.push(`"get"`);
|
|
908
|
-
}
|
|
909
|
-
if ((_b = handler == null ? void 0 : handler.verbs) == null ? void 0 : _b.includes("post")) {
|
|
910
|
-
verbs.push(`"post"`);
|
|
911
|
-
}
|
|
912
|
-
let routeType = `{ verb: ${verbs.join(" | ")};`;
|
|
913
|
-
if (meta) {
|
|
914
|
-
const metaPath = stripTsExtension(`${pathPrefix}/${meta.relativePath}`);
|
|
915
|
-
let metaType = `typeof import("${metaPath}")`;
|
|
916
|
-
if (/\.(ts|js|mjs)$/.test(meta.name)) {
|
|
917
|
-
metaType += `["default"]`;
|
|
918
|
-
}
|
|
919
|
-
routeType += ` meta: ${metaType};`;
|
|
920
|
-
}
|
|
921
|
-
writer.writeLines(`"${route.key}": ${routeType} };`);
|
|
922
|
-
}
|
|
923
|
-
}
|
|
924
|
-
writer.writeBlockEnd("}");
|
|
925
934
|
return writer.end();
|
|
926
935
|
}
|
|
927
|
-
function writeModuleDeclaration(writer,
|
|
928
|
-
writer.writeLines("").write(`declare module "${
|
|
936
|
+
function writeModuleDeclaration(writer, name, routeType, moduleTypes) {
|
|
937
|
+
writer.writeLines("").write(`declare module "${name}" {`);
|
|
929
938
|
if (moduleTypes) {
|
|
930
939
|
writer.write(moduleTypes);
|
|
931
940
|
}
|
|
932
941
|
if (routeType) {
|
|
933
|
-
const isMarko =
|
|
942
|
+
const isMarko = name.endsWith(".marko");
|
|
934
943
|
writer.write(`
|
|
935
944
|
namespace MarkoRun {
|
|
936
945
|
export { NotHandled, NotMatched, GetPaths, PostPaths, GetablePath, GetableHref, PostablePath, PostableHref, Platform };
|
|
@@ -944,21 +953,15 @@ function writeModuleDeclaration(writer, path5, routeType, moduleTypes) {
|
|
|
944
953
|
writer.writeLines(`
|
|
945
954
|
}`);
|
|
946
955
|
}
|
|
947
|
-
function pathToURLPatternString(path5) {
|
|
948
|
-
return path5.replace(/\/\$(\$?)([^/]*)/g, (_, catchAll, name) => {
|
|
949
|
-
name = decodeURIComponent(name);
|
|
950
|
-
return catchAll ? `/:${name || "rest"}*` : `/:${name}`;
|
|
951
|
-
});
|
|
952
|
-
}
|
|
953
956
|
function createRouteTrie(routes) {
|
|
954
957
|
const root = {
|
|
955
958
|
key: ""
|
|
956
959
|
};
|
|
957
|
-
function insert(
|
|
960
|
+
function insert(path7, route) {
|
|
958
961
|
let node = root;
|
|
959
|
-
for (const segment of
|
|
962
|
+
for (const segment of path7.segments) {
|
|
960
963
|
if (segment === "$$") {
|
|
961
|
-
node.catchAll ?? (node.catchAll = { route, path:
|
|
964
|
+
node.catchAll ?? (node.catchAll = { route, path: path7 });
|
|
962
965
|
return;
|
|
963
966
|
} else if (segment === "$") {
|
|
964
967
|
node = node.dynamic ?? (node.dynamic = {
|
|
@@ -976,17 +979,18 @@ function createRouteTrie(routes) {
|
|
|
976
979
|
node = next;
|
|
977
980
|
}
|
|
978
981
|
}
|
|
979
|
-
node.path ?? (node.path =
|
|
982
|
+
node.path ?? (node.path = path7);
|
|
980
983
|
node.route ?? (node.route = route);
|
|
981
984
|
}
|
|
982
985
|
for (const route of routes) {
|
|
983
|
-
|
|
984
|
-
insert(path5, route);
|
|
985
|
-
}
|
|
986
|
+
insert(route.path, route);
|
|
986
987
|
}
|
|
987
988
|
return root;
|
|
988
989
|
}
|
|
989
990
|
|
|
991
|
+
// src/vite/routes/builder.ts
|
|
992
|
+
import path3 from "path";
|
|
993
|
+
|
|
990
994
|
// src/vite/routes/parse.ts
|
|
991
995
|
function parseFlatRoute(pattern) {
|
|
992
996
|
if (!pattern) throw new Error("Empty pattern");
|
|
@@ -1001,53 +1005,72 @@ function parseFlatRoute(pattern) {
|
|
|
1001
1005
|
]);
|
|
1002
1006
|
function parse2(basePaths, group) {
|
|
1003
1007
|
const pathMap = /* @__PURE__ */ new Map();
|
|
1004
|
-
const delimiters = group ? ").," : "
|
|
1008
|
+
const delimiters = group ? "`).," : "`.,";
|
|
1005
1009
|
let charCode;
|
|
1006
1010
|
let segmentStart = i;
|
|
1007
1011
|
let type;
|
|
1008
1012
|
let current;
|
|
1013
|
+
let escaped = "";
|
|
1014
|
+
let escapeStart = 0;
|
|
1009
1015
|
do {
|
|
1010
1016
|
charCode = pattern.charCodeAt(i);
|
|
1011
|
-
if (charCode ===
|
|
1017
|
+
if (charCode === 96 /* Escape */) {
|
|
1018
|
+
if (escapeStart) {
|
|
1019
|
+
escaped += pattern.slice(segmentStart, escapeStart - 1) + pattern.slice(escapeStart, i);
|
|
1020
|
+
escapeStart = 0;
|
|
1021
|
+
segmentStart = ++i;
|
|
1022
|
+
} else {
|
|
1023
|
+
escapeStart = i + 1;
|
|
1024
|
+
i = pattern.indexOf("`", escapeStart);
|
|
1025
|
+
if (i < 0) break;
|
|
1026
|
+
}
|
|
1027
|
+
} else if (charCode === 41 /* GroupEnd */ && group) {
|
|
1012
1028
|
break;
|
|
1013
|
-
} else if (charCode === 44) {
|
|
1029
|
+
} else if (charCode === 44 /* Alternate */) {
|
|
1014
1030
|
if (!current) {
|
|
1015
1031
|
segmentEnd(
|
|
1016
|
-
basePaths.map((
|
|
1017
|
-
...
|
|
1018
|
-
segments:
|
|
1032
|
+
basePaths.map((path7) => ({
|
|
1033
|
+
...path7,
|
|
1034
|
+
segments: path7.segments.slice()
|
|
1019
1035
|
})),
|
|
1020
|
-
|
|
1036
|
+
escaped,
|
|
1021
1037
|
"_",
|
|
1022
1038
|
pathMap
|
|
1023
1039
|
);
|
|
1024
1040
|
} else {
|
|
1025
|
-
segmentEnd(
|
|
1041
|
+
segmentEnd(
|
|
1042
|
+
current,
|
|
1043
|
+
escaped + pattern.slice(segmentStart, i),
|
|
1044
|
+
type,
|
|
1045
|
+
pathMap
|
|
1046
|
+
);
|
|
1026
1047
|
}
|
|
1027
1048
|
current = void 0;
|
|
1028
1049
|
type = void 0;
|
|
1050
|
+
escaped = "";
|
|
1029
1051
|
segmentStart = ++i;
|
|
1030
|
-
} else if (charCode === 46) {
|
|
1052
|
+
} else if (charCode === 46 /* Directory */) {
|
|
1031
1053
|
if (current) {
|
|
1032
|
-
segmentEnd(current, pattern.slice(segmentStart, i), type);
|
|
1054
|
+
segmentEnd(current, escaped + pattern.slice(segmentStart, i), type);
|
|
1033
1055
|
}
|
|
1034
1056
|
type = void 0;
|
|
1057
|
+
escaped = "";
|
|
1035
1058
|
segmentStart = ++i;
|
|
1036
|
-
} else if (charCode === 40) {
|
|
1059
|
+
} else if (charCode === 40 /* GroupStart */) {
|
|
1037
1060
|
const groupPaths = parse2(current || basePaths, ++i);
|
|
1038
1061
|
if (groupPaths.length) {
|
|
1039
1062
|
current = groupPaths;
|
|
1040
1063
|
}
|
|
1041
1064
|
segmentStart = ++i;
|
|
1042
1065
|
} else {
|
|
1043
|
-
if (charCode === 95) {
|
|
1066
|
+
if (charCode === 95 /* Pathless */) {
|
|
1044
1067
|
type = "_";
|
|
1045
|
-
} else if (charCode === 36) {
|
|
1068
|
+
} else if (charCode === 36 /* Dynamic */) {
|
|
1046
1069
|
type = pattern.charCodeAt(i + 1) === 36 ? "$$" : "$";
|
|
1047
1070
|
}
|
|
1048
|
-
current ?? (current = basePaths.map((
|
|
1049
|
-
...
|
|
1050
|
-
segments:
|
|
1071
|
+
current ?? (current = basePaths.map((path7) => ({
|
|
1072
|
+
...path7,
|
|
1073
|
+
segments: path7.segments.slice()
|
|
1051
1074
|
})));
|
|
1052
1075
|
i = len;
|
|
1053
1076
|
for (const char of delimiters) {
|
|
@@ -1058,7 +1081,12 @@ function parseFlatRoute(pattern) {
|
|
|
1058
1081
|
}
|
|
1059
1082
|
}
|
|
1060
1083
|
} while (i < len);
|
|
1061
|
-
if (
|
|
1084
|
+
if (escapeStart) {
|
|
1085
|
+
throw new Error(
|
|
1086
|
+
`Invalid route pattern: unclosed escape '${pattern.slice(escapeStart)}' in '${pattern}'`
|
|
1087
|
+
);
|
|
1088
|
+
}
|
|
1089
|
+
if (group && charCode !== 41 /* GroupEnd */) {
|
|
1062
1090
|
throw new Error(
|
|
1063
1091
|
`Invalid route pattern: group was not closed '${pattern.slice(
|
|
1064
1092
|
group
|
|
@@ -1067,16 +1095,21 @@ function parseFlatRoute(pattern) {
|
|
|
1067
1095
|
}
|
|
1068
1096
|
if (!current) {
|
|
1069
1097
|
segmentEnd(
|
|
1070
|
-
basePaths.map((
|
|
1071
|
-
...
|
|
1072
|
-
segments:
|
|
1098
|
+
basePaths.map((path7) => ({
|
|
1099
|
+
...path7,
|
|
1100
|
+
segments: path7.segments.slice()
|
|
1073
1101
|
})),
|
|
1074
|
-
|
|
1075
|
-
|
|
1102
|
+
escaped,
|
|
1103
|
+
void 0,
|
|
1076
1104
|
pathMap
|
|
1077
1105
|
);
|
|
1078
1106
|
} else {
|
|
1079
|
-
segmentEnd(
|
|
1107
|
+
segmentEnd(
|
|
1108
|
+
current,
|
|
1109
|
+
escaped + pattern.slice(segmentStart, i),
|
|
1110
|
+
type,
|
|
1111
|
+
pathMap
|
|
1112
|
+
);
|
|
1080
1113
|
}
|
|
1081
1114
|
return [...pathMap.values()];
|
|
1082
1115
|
}
|
|
@@ -1085,17 +1118,17 @@ function parseFlatRoute(pattern) {
|
|
|
1085
1118
|
if (raw) {
|
|
1086
1119
|
segment = {
|
|
1087
1120
|
raw,
|
|
1088
|
-
name: raw,
|
|
1121
|
+
name: normalizeSegment(raw),
|
|
1089
1122
|
type
|
|
1090
1123
|
};
|
|
1091
1124
|
if (type === "$" || type === "$$") {
|
|
1092
1125
|
segment.name = type;
|
|
1093
|
-
segment.param = raw.slice(type.length);
|
|
1126
|
+
segment.param = normalizeParam(raw.slice(type.length));
|
|
1094
1127
|
}
|
|
1095
1128
|
}
|
|
1096
|
-
for (const
|
|
1129
|
+
for (const path7 of paths) {
|
|
1097
1130
|
if (segment) {
|
|
1098
|
-
if (
|
|
1131
|
+
if (path7.isCatchall) {
|
|
1099
1132
|
throw new Error(
|
|
1100
1133
|
`Invalid route pattern: nested segments are not allowed after a catch-all parameter. Found '.' following '${pattern.slice(
|
|
1101
1134
|
0,
|
|
@@ -1103,26 +1136,36 @@ function parseFlatRoute(pattern) {
|
|
|
1103
1136
|
)}' in '${pattern}'.`
|
|
1104
1137
|
);
|
|
1105
1138
|
}
|
|
1106
|
-
|
|
1107
|
-
|
|
1139
|
+
path7.segments.push(segment);
|
|
1140
|
+
path7.id += path7.id === "/" ? segment.name : `/${segment.name}`;
|
|
1108
1141
|
if (type === "$$") {
|
|
1109
|
-
|
|
1142
|
+
path7.isCatchall = true;
|
|
1110
1143
|
}
|
|
1111
1144
|
}
|
|
1112
1145
|
if (map) {
|
|
1113
|
-
if (map.has(
|
|
1114
|
-
const existing = map.get(
|
|
1146
|
+
if (map.has(path7.id)) {
|
|
1147
|
+
const existing = map.get(path7.id);
|
|
1115
1148
|
const existingExpansion = existing.segments.map((s) => s.raw).join(".");
|
|
1116
|
-
const currentExpansion =
|
|
1149
|
+
const currentExpansion = path7.segments.map((s) => s.raw).join(".");
|
|
1117
1150
|
throw new Error(
|
|
1118
|
-
`Invalid route pattern: route '${
|
|
1151
|
+
`Invalid route pattern: route '${path7.id}' is ambiguous. Expansion '${currentExpansion}' collides with '${existingExpansion}' in '${pattern}'.`
|
|
1119
1152
|
);
|
|
1120
1153
|
}
|
|
1121
|
-
map.set(
|
|
1154
|
+
map.set(path7.id, path7);
|
|
1122
1155
|
}
|
|
1123
1156
|
}
|
|
1124
1157
|
}
|
|
1125
1158
|
}
|
|
1159
|
+
function normalizeParam(segment) {
|
|
1160
|
+
const normalized = normalizeSegment(segment);
|
|
1161
|
+
return /^\$/.test(normalized) ? `\`${normalized}\`` : normalized;
|
|
1162
|
+
}
|
|
1163
|
+
function normalizeSegment(segment) {
|
|
1164
|
+
return decodeURIComponent(segment).replace(
|
|
1165
|
+
/[/?#]/g,
|
|
1166
|
+
(char) => "%" + char.charCodeAt(0).toString(16)
|
|
1167
|
+
);
|
|
1168
|
+
}
|
|
1126
1169
|
|
|
1127
1170
|
// src/vite/routes/vdir.ts
|
|
1128
1171
|
var _dirs, _pathlessDirs;
|
|
@@ -1133,14 +1176,12 @@ var _VDir = class _VDir {
|
|
|
1133
1176
|
__publicField(this, "parent");
|
|
1134
1177
|
__publicField(this, "source");
|
|
1135
1178
|
__publicField(this, "path");
|
|
1136
|
-
__publicField(this, "fullPath");
|
|
1137
1179
|
__publicField(this, "segment");
|
|
1138
1180
|
__publicField(this, "files");
|
|
1139
1181
|
if (!parent || !segment) {
|
|
1140
1182
|
this.parent = null;
|
|
1141
1183
|
this.source = null;
|
|
1142
1184
|
this.path = "/";
|
|
1143
|
-
this.fullPath = "/";
|
|
1144
1185
|
this.segment = {
|
|
1145
1186
|
raw: "",
|
|
1146
1187
|
name: ""
|
|
@@ -1148,12 +1189,8 @@ var _VDir = class _VDir {
|
|
|
1148
1189
|
} else {
|
|
1149
1190
|
this.parent = parent;
|
|
1150
1191
|
this.source = source;
|
|
1151
|
-
this.path = parent.path + (parent.path === "/" ? segment.name : `/${segment.name}`);
|
|
1152
|
-
this.fullPath = parent.fullPath + (parent.fullPath === "/" ? segment.name : `/${segment.name}`);
|
|
1153
|
-
if (segment.param) {
|
|
1154
|
-
this.fullPath += segment.param;
|
|
1155
|
-
}
|
|
1156
1192
|
this.segment = segment;
|
|
1193
|
+
this.path = parent.path + (parent.path === "/" ? "" : "/") + segment.name;
|
|
1157
1194
|
}
|
|
1158
1195
|
}
|
|
1159
1196
|
get pathInfo() {
|
|
@@ -1166,17 +1203,18 @@ var _VDir = class _VDir {
|
|
|
1166
1203
|
for (const { segment } of this) {
|
|
1167
1204
|
const { type, name, param } = segment;
|
|
1168
1205
|
if (name && type !== "_") {
|
|
1169
|
-
value.id += sep +
|
|
1206
|
+
value.id += sep + name;
|
|
1170
1207
|
value.path += sep + name;
|
|
1171
1208
|
value.isEnd = type === "$$";
|
|
1172
1209
|
if (param) {
|
|
1173
|
-
|
|
1210
|
+
const unescapedParam = param.charAt(0) === "`" ? param.slice(1, -1) : param;
|
|
1174
1211
|
const index = type === "$$" ? null : value.segments.length;
|
|
1175
1212
|
if (!value.params) {
|
|
1176
|
-
value.params = { [
|
|
1213
|
+
value.params = { [unescapedParam]: index };
|
|
1177
1214
|
} else if (!(param in value.params)) {
|
|
1178
|
-
value.params[
|
|
1215
|
+
value.params[unescapedParam] = index;
|
|
1179
1216
|
}
|
|
1217
|
+
value.path += param;
|
|
1180
1218
|
}
|
|
1181
1219
|
value.segments.push(name);
|
|
1182
1220
|
sep = "/";
|
|
@@ -1188,11 +1226,11 @@ var _VDir = class _VDir {
|
|
|
1188
1226
|
});
|
|
1189
1227
|
return value;
|
|
1190
1228
|
}
|
|
1191
|
-
addDir(
|
|
1229
|
+
addDir(path7, segment) {
|
|
1192
1230
|
const map = segment.type === "_" ? __privateGet(this, _pathlessDirs) ?? __privateSet(this, _pathlessDirs, /* @__PURE__ */ new Map()) : __privateGet(this, _dirs) ?? __privateSet(this, _dirs, /* @__PURE__ */ new Map());
|
|
1193
1231
|
const key = segment.type === "$" ? segment.raw : segment.name;
|
|
1194
1232
|
if (!map.has(key)) {
|
|
1195
|
-
const dir = new _VDir(this, segment,
|
|
1233
|
+
const dir = new _VDir(this, segment, path7);
|
|
1196
1234
|
map.set(key, dir);
|
|
1197
1235
|
return dir;
|
|
1198
1236
|
}
|
|
@@ -1208,15 +1246,15 @@ var _VDir = class _VDir {
|
|
|
1208
1246
|
const existing = this.files.get(file.type);
|
|
1209
1247
|
if (existing !== file) {
|
|
1210
1248
|
throw new Error(
|
|
1211
|
-
`Duplicate file type
|
|
1249
|
+
`Duplicate file type ${file.type} added at path ${this.path}. File ${file.filePath} collides with ${existing.filePath}.`
|
|
1212
1250
|
);
|
|
1213
1251
|
} else if (file.type === RoutableFileTypes.Page || file.type === RoutableFileTypes.Handler) {
|
|
1214
1252
|
throw new Error(
|
|
1215
|
-
`Ambiguous path definition: route
|
|
1253
|
+
`Ambiguous path definition: route ${this.path} is defined multiple times by ${file.filePath}`
|
|
1216
1254
|
);
|
|
1217
1255
|
}
|
|
1218
1256
|
throw new Error(
|
|
1219
|
-
`Ambiguous path definition: file
|
|
1257
|
+
`Ambiguous path definition: file ${this.path} is included multiple times by ${file.filePath}`
|
|
1220
1258
|
);
|
|
1221
1259
|
}
|
|
1222
1260
|
}
|
|
@@ -1238,10 +1276,10 @@ var _VDir = class _VDir {
|
|
|
1238
1276
|
const dirs = [];
|
|
1239
1277
|
const unique = /* @__PURE__ */ new Map();
|
|
1240
1278
|
for (const root of roots) {
|
|
1241
|
-
for (const
|
|
1279
|
+
for (const path7 of paths) {
|
|
1242
1280
|
let dir = root;
|
|
1243
|
-
for (const segment of
|
|
1244
|
-
dir = dir.addDir(
|
|
1281
|
+
for (const segment of path7.segments) {
|
|
1282
|
+
dir = dir.addDir(path7, segment);
|
|
1245
1283
|
}
|
|
1246
1284
|
const existing = unique.get(dir.path);
|
|
1247
1285
|
if (existing) {
|
|
@@ -1254,7 +1292,7 @@ var _VDir = class _VDir {
|
|
|
1254
1292
|
}
|
|
1255
1293
|
}
|
|
1256
1294
|
throw new Error(
|
|
1257
|
-
`Ambiguous directory structure:
|
|
1295
|
+
`Ambiguous directory structure: ${sourcePath}${path7.source} defines ${dir.path} multiple times.`
|
|
1258
1296
|
);
|
|
1259
1297
|
} else {
|
|
1260
1298
|
unique.set(dir.path, dir);
|
|
@@ -1280,13 +1318,11 @@ function matchRoutableFile(filename) {
|
|
|
1280
1318
|
const match = filename.match(routeableFileRegex);
|
|
1281
1319
|
return match && (match[1] || match[3]).toLowerCase();
|
|
1282
1320
|
}
|
|
1283
|
-
function
|
|
1284
|
-
return type === RoutableFileTypes.NotFound || type === RoutableFileTypes.Error;
|
|
1285
|
-
}
|
|
1286
|
-
async function buildRoutes(sources) {
|
|
1321
|
+
async function buildRoutes(sources, outDir) {
|
|
1287
1322
|
const uniqueRoutes = /* @__PURE__ */ new Map();
|
|
1288
1323
|
const routes = [];
|
|
1289
1324
|
const special = {};
|
|
1325
|
+
const seenKeys = /* @__PURE__ */ new Map();
|
|
1290
1326
|
const middlewares = /* @__PURE__ */ new Set();
|
|
1291
1327
|
const unusedFiles = /* @__PURE__ */ new Set();
|
|
1292
1328
|
const currentLayouts = /* @__PURE__ */ new Set();
|
|
@@ -1294,13 +1330,13 @@ async function buildRoutes(sources) {
|
|
|
1294
1330
|
const root = new VDir();
|
|
1295
1331
|
const dirStack = [];
|
|
1296
1332
|
let basePath;
|
|
1297
|
-
let importPrefix;
|
|
1298
1333
|
let activeDirs;
|
|
1299
1334
|
let isBaseDir;
|
|
1300
1335
|
let nextFileId = 1;
|
|
1301
1336
|
let nextRouteIndex = 1;
|
|
1302
1337
|
const walkOptions = {
|
|
1303
|
-
onEnter(
|
|
1338
|
+
onEnter(dir) {
|
|
1339
|
+
let { name } = dir;
|
|
1304
1340
|
const prevDirStackLength = dirStack.length;
|
|
1305
1341
|
if (isBaseDir) {
|
|
1306
1342
|
isBaseDir = false;
|
|
@@ -1319,15 +1355,16 @@ async function buildRoutes(sources) {
|
|
|
1319
1355
|
dirStack.length = prevDirStackLength;
|
|
1320
1356
|
};
|
|
1321
1357
|
},
|
|
1322
|
-
onFile(
|
|
1358
|
+
onFile(file) {
|
|
1359
|
+
const { name } = file;
|
|
1323
1360
|
const match = name.match(routeableFileRegex);
|
|
1324
1361
|
if (!match) {
|
|
1325
1362
|
return;
|
|
1326
1363
|
}
|
|
1327
1364
|
const type = (match[1] || match[3]).toLowerCase();
|
|
1328
|
-
if (dirStack.length &&
|
|
1365
|
+
if (dirStack.length && (type === RoutableFileTypes.NotFound || type === RoutableFileTypes.Error)) {
|
|
1329
1366
|
console.warn(
|
|
1330
|
-
`Special pages '${RoutableFileTypes.NotFound}' and '${RoutableFileTypes.Error}' are only considered in the root directory - ignoring ${
|
|
1367
|
+
`Special pages '${RoutableFileTypes.NotFound}' and '${RoutableFileTypes.Error}' are only considered in the root directory - ignoring ${file.path}`
|
|
1331
1368
|
);
|
|
1332
1369
|
return;
|
|
1333
1370
|
}
|
|
@@ -1336,19 +1373,15 @@ async function buildRoutes(sources) {
|
|
|
1336
1373
|
const paths = parseFlatRoute(name.slice(0, match.index));
|
|
1337
1374
|
dirs = VDir.addPaths(activeDirs, paths);
|
|
1338
1375
|
}
|
|
1339
|
-
const
|
|
1340
|
-
const relativePath = dirPath ? `${dirPath}/${name}` : name;
|
|
1341
|
-
const file = {
|
|
1376
|
+
const routableFile = {
|
|
1342
1377
|
id: String(nextFileId++),
|
|
1343
1378
|
name,
|
|
1344
1379
|
type,
|
|
1345
|
-
filePath:
|
|
1346
|
-
relativePath,
|
|
1347
|
-
importPath: `${importPrefix}/${relativePath}`,
|
|
1380
|
+
filePath: file.path,
|
|
1348
1381
|
verbs: type === RoutableFileTypes.Page ? ["get", "head"] : void 0
|
|
1349
1382
|
};
|
|
1350
1383
|
for (const dir of dirs) {
|
|
1351
|
-
dir.addFile(
|
|
1384
|
+
dir.addFile(routableFile);
|
|
1352
1385
|
}
|
|
1353
1386
|
}
|
|
1354
1387
|
};
|
|
@@ -1356,7 +1389,6 @@ async function buildRoutes(sources) {
|
|
|
1356
1389
|
sources = [sources];
|
|
1357
1390
|
}
|
|
1358
1391
|
for (const source of sources) {
|
|
1359
|
-
importPrefix = source.importPrefix ? source.importPrefix.replace(/^\/+|\/+$/g, "") : "";
|
|
1360
1392
|
basePath = source.basePath || "";
|
|
1361
1393
|
activeDirs = [root];
|
|
1362
1394
|
isBaseDir = true;
|
|
@@ -1376,7 +1408,8 @@ async function buildRoutes(sources) {
|
|
|
1376
1408
|
layout = dir.files.get(RoutableFileTypes.Layout);
|
|
1377
1409
|
const handler = dir.files.get(RoutableFileTypes.Handler);
|
|
1378
1410
|
const page = dir.files.get(RoutableFileTypes.Page);
|
|
1379
|
-
|
|
1411
|
+
const pathInfo = dir.pathInfo;
|
|
1412
|
+
let layoutsUsed = false;
|
|
1380
1413
|
if (middleware) {
|
|
1381
1414
|
if (currentMiddleware.has(middleware)) {
|
|
1382
1415
|
middleware = void 0;
|
|
@@ -1393,64 +1426,64 @@ async function buildRoutes(sources) {
|
|
|
1393
1426
|
unusedFiles.add(layout);
|
|
1394
1427
|
}
|
|
1395
1428
|
}
|
|
1429
|
+
if (dir === root) {
|
|
1430
|
+
for (const [type, file] of dir.files) {
|
|
1431
|
+
if (type === RoutableFileTypes.NotFound || type === RoutableFileTypes.Error) {
|
|
1432
|
+
special[type] = {
|
|
1433
|
+
index: nextRouteIndex++,
|
|
1434
|
+
key: type,
|
|
1435
|
+
path: dir.pathInfo,
|
|
1436
|
+
middleware: [],
|
|
1437
|
+
layouts: [...currentLayouts],
|
|
1438
|
+
page: file,
|
|
1439
|
+
templateFilePath: currentLayouts.size ? path3.join(outDir, `${type}.marko`) : void 0
|
|
1440
|
+
};
|
|
1441
|
+
layoutsUsed = true;
|
|
1442
|
+
}
|
|
1443
|
+
}
|
|
1444
|
+
}
|
|
1396
1445
|
if (page || handler) {
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
const existing = uniqueRoutes.get(path5.id);
|
|
1446
|
+
if (uniqueRoutes.has(pathInfo.id)) {
|
|
1447
|
+
const existing = uniqueRoutes.get(pathInfo.id);
|
|
1400
1448
|
const route = routes[existing.index];
|
|
1401
1449
|
const existingFiles = [route.handler, route.page].filter(Boolean).map((f) => f.filePath);
|
|
1402
1450
|
const currentFiles = [handler, page].filter(Boolean).map((f) => f.filePath);
|
|
1403
|
-
throw new Error(
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1451
|
+
throw new Error(
|
|
1452
|
+
`Duplicate routes for path ${pathInfo.id} were defined. A route established by: "${existingFiles.join(" and ")}" collides with "${currentFiles.join(" and ")}"`
|
|
1453
|
+
);
|
|
1454
|
+
}
|
|
1455
|
+
uniqueRoutes.set(pathInfo.id, { dir, index: routes.length });
|
|
1456
|
+
let key = pathInfo.segments.map(replaceInvalidFilenameChars).concat("route").join("/");
|
|
1457
|
+
const keyCount = (seenKeys.get(key) || 0) + 1;
|
|
1458
|
+
seenKeys.set(key, keyCount);
|
|
1459
|
+
if (keyCount > 1) {
|
|
1460
|
+
key += keyCount;
|
|
1408
1461
|
}
|
|
1409
|
-
uniqueRoutes.set(path5.id, { dir, index: routes.length });
|
|
1410
1462
|
routes.push({
|
|
1411
1463
|
index: nextRouteIndex++,
|
|
1412
|
-
key
|
|
1413
|
-
|
|
1464
|
+
key,
|
|
1465
|
+
path: pathInfo,
|
|
1414
1466
|
middleware: [...currentMiddleware],
|
|
1415
1467
|
layouts: page ? [...currentLayouts] : [],
|
|
1416
1468
|
meta: dir.files.get(RoutableFileTypes.Meta),
|
|
1417
1469
|
page,
|
|
1418
1470
|
handler,
|
|
1419
|
-
|
|
1471
|
+
templateFilePath: page && currentLayouts.size ? path3.join(outDir, key + ".marko") : void 0
|
|
1420
1472
|
});
|
|
1421
|
-
|
|
1422
|
-
if (dir === root) {
|
|
1423
|
-
for (const [type, file] of dir.files) {
|
|
1424
|
-
if (isSpecialType(type)) {
|
|
1425
|
-
hasSpecial = true;
|
|
1426
|
-
special[type] = {
|
|
1427
|
-
index: 0,
|
|
1428
|
-
key: type,
|
|
1429
|
-
paths: [],
|
|
1430
|
-
middleware: [],
|
|
1431
|
-
layouts: [...currentLayouts],
|
|
1432
|
-
page: file,
|
|
1433
|
-
entryName: `${markoRunFilePrefix}special.${type}`
|
|
1434
|
-
};
|
|
1435
|
-
}
|
|
1436
|
-
}
|
|
1437
|
-
}
|
|
1438
|
-
if (handler || page) {
|
|
1473
|
+
layoutsUsed = !!page;
|
|
1439
1474
|
for (const middleware2 of currentMiddleware) {
|
|
1440
1475
|
middlewares.add(middleware2);
|
|
1441
1476
|
unusedFiles.delete(middleware2);
|
|
1442
1477
|
}
|
|
1443
1478
|
}
|
|
1444
|
-
if (
|
|
1479
|
+
if (layoutsUsed) {
|
|
1445
1480
|
for (const layout2 of currentLayouts) {
|
|
1446
1481
|
unusedFiles.delete(layout2);
|
|
1447
1482
|
}
|
|
1448
1483
|
}
|
|
1449
1484
|
}
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
traverse(child);
|
|
1453
|
-
}
|
|
1485
|
+
for (const childDir of dir.dirs()) {
|
|
1486
|
+
traverse(childDir);
|
|
1454
1487
|
}
|
|
1455
1488
|
if (middleware) {
|
|
1456
1489
|
currentMiddleware.delete(middleware);
|
|
@@ -1460,10 +1493,13 @@ async function buildRoutes(sources) {
|
|
|
1460
1493
|
}
|
|
1461
1494
|
}
|
|
1462
1495
|
}
|
|
1496
|
+
function replaceInvalidFilenameChars(str) {
|
|
1497
|
+
return str.replace(/[<>:"/\\|?*]+/g, "_");
|
|
1498
|
+
}
|
|
1463
1499
|
|
|
1464
1500
|
// src/vite/routes/walk.ts
|
|
1465
1501
|
import fs from "fs";
|
|
1466
|
-
import
|
|
1502
|
+
import path4 from "path";
|
|
1467
1503
|
function createFSWalker(dir) {
|
|
1468
1504
|
return async function walkFS({
|
|
1469
1505
|
onEnter,
|
|
@@ -1478,7 +1514,7 @@ function createFSWalker(dir) {
|
|
|
1478
1514
|
const entries = await fs.promises.readdir(dir2.path, {
|
|
1479
1515
|
withFileTypes: true
|
|
1480
1516
|
});
|
|
1481
|
-
const prefix = dir2.path +
|
|
1517
|
+
const prefix = dir2.path + path4.sep;
|
|
1482
1518
|
for (const entry of entries) {
|
|
1483
1519
|
const walkEntry = {
|
|
1484
1520
|
name: entry.name,
|
|
@@ -1501,7 +1537,7 @@ function createFSWalker(dir) {
|
|
|
1501
1537
|
await walk(
|
|
1502
1538
|
{
|
|
1503
1539
|
path: dir,
|
|
1504
|
-
name:
|
|
1540
|
+
name: path4.basename(dir)
|
|
1505
1541
|
},
|
|
1506
1542
|
maxDepth
|
|
1507
1543
|
);
|
|
@@ -1618,36 +1654,34 @@ function logRoutesTable(routes, bundle) {
|
|
|
1618
1654
|
style: { compact: true }
|
|
1619
1655
|
});
|
|
1620
1656
|
for (const route of routes.list) {
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
if (route.page && (verb === "get" || verb === "head")) {
|
|
1635
|
-
entryType.push(kleur2.yellow("page"));
|
|
1636
|
-
if (verb === "get") {
|
|
1637
|
-
size = prettySize(computeRouteSize(route, bundle));
|
|
1638
|
-
}
|
|
1639
|
-
}
|
|
1640
|
-
const row = [verbCell];
|
|
1641
|
-
if (verbs.length === 1 || firstRow) {
|
|
1642
|
-
row.push({ rowSpan: verbs.length, content: prettyPath(path5.path) });
|
|
1643
|
-
firstRow = false;
|
|
1657
|
+
const verbs = getVerbs(route, true);
|
|
1658
|
+
let firstRow = true;
|
|
1659
|
+
for (const verb of verbs) {
|
|
1660
|
+
const entryType = [];
|
|
1661
|
+
let size = "";
|
|
1662
|
+
const verbCell = verbColor(verb)(verb.toUpperCase());
|
|
1663
|
+
if (route.handler) {
|
|
1664
|
+
entryType.push(kleur2.blue("handler"));
|
|
1665
|
+
}
|
|
1666
|
+
if (route.page && (verb === "get" || verb === "head")) {
|
|
1667
|
+
entryType.push(kleur2.yellow("page"));
|
|
1668
|
+
if (verb === "get") {
|
|
1669
|
+
size = prettySize(computeRouteSize(route, bundle));
|
|
1644
1670
|
}
|
|
1645
|
-
row.push(entryType.join(" -> "));
|
|
1646
|
-
hasMiddleware && row.push(route.middleware.length || "");
|
|
1647
|
-
hasMeta && row.push(route.meta ? "\u2713" : "");
|
|
1648
|
-
row.push(size || "");
|
|
1649
|
-
table.push(row);
|
|
1650
1671
|
}
|
|
1672
|
+
const row = [verbCell];
|
|
1673
|
+
if (verbs.length === 1 || firstRow) {
|
|
1674
|
+
row.push({
|
|
1675
|
+
rowSpan: verbs.length,
|
|
1676
|
+
content: prettyPath(route.path.path)
|
|
1677
|
+
});
|
|
1678
|
+
firstRow = false;
|
|
1679
|
+
}
|
|
1680
|
+
row.push(entryType.join(" -> "));
|
|
1681
|
+
hasMiddleware && row.push(route.middleware.length || "");
|
|
1682
|
+
hasMeta && row.push(route.meta ? "\u2713" : "");
|
|
1683
|
+
row.push(size || "");
|
|
1684
|
+
table.push(row);
|
|
1651
1685
|
}
|
|
1652
1686
|
}
|
|
1653
1687
|
for (const [key, route] of Object.entries(routes.special).sort()) {
|
|
@@ -1703,17 +1737,20 @@ function prettySize([bytes, compBytes]) {
|
|
|
1703
1737
|
else str += kleur2.bold(kleur2.red(compSize));
|
|
1704
1738
|
return str;
|
|
1705
1739
|
}
|
|
1706
|
-
function prettyPath(
|
|
1707
|
-
return
|
|
1740
|
+
function prettyPath(path7) {
|
|
1741
|
+
return path7.replace(
|
|
1742
|
+
/\/(\$\$?)(`?)([^/`]+)\2/g,
|
|
1743
|
+
(_, type, tick, key) => "/" + type + tick + kleur2.bold(kleur2.dim(key)) + tick
|
|
1744
|
+
);
|
|
1708
1745
|
}
|
|
1709
1746
|
|
|
1710
1747
|
// src/vite/utils/read-once-persisted-store.ts
|
|
1711
1748
|
import { promises as fs2 } from "fs";
|
|
1712
1749
|
import os from "os";
|
|
1713
|
-
import
|
|
1750
|
+
import path5 from "path";
|
|
1714
1751
|
var noop = () => {
|
|
1715
1752
|
};
|
|
1716
|
-
var tmpFile =
|
|
1753
|
+
var tmpFile = path5.join(os.tmpdir(), "marko-run-storage.json");
|
|
1717
1754
|
var values = /* @__PURE__ */ new Map();
|
|
1718
1755
|
var loadedFromDisk;
|
|
1719
1756
|
var ReadOncePersistedStore = class {
|
|
@@ -1755,17 +1792,17 @@ process.once("beforeExit", (code) => {
|
|
|
1755
1792
|
|
|
1756
1793
|
// src/vite/plugin.ts
|
|
1757
1794
|
var debug = createDebug("@marko/run");
|
|
1758
|
-
var __dirname =
|
|
1795
|
+
var __dirname = path6.dirname(fileURLToPath(import.meta.url));
|
|
1759
1796
|
var PLUGIN_NAME_PREFIX = "marko-run-vite";
|
|
1760
|
-
var POSIX_SEP = "/";
|
|
1761
|
-
var WINDOWS_SEP = "\\";
|
|
1762
1797
|
var CLIENT_OUT_DIR = "public";
|
|
1763
1798
|
var MIDDLEWARE_FILENAME = `${markoRunFilePrefix}middleware.js`;
|
|
1764
1799
|
var ROUTER_FILENAME = `${markoRunFilePrefix}router.js`;
|
|
1765
1800
|
var defaultPort = Number(process.env.PORT || 3e3);
|
|
1766
|
-
var normalizePath = path4.sep === WINDOWS_SEP ? (id) => id.replace(/\\/g, POSIX_SEP) : (id) => id;
|
|
1767
1801
|
function markoRun(opts = {}) {
|
|
1768
|
-
let
|
|
1802
|
+
let routesDir;
|
|
1803
|
+
let adapter;
|
|
1804
|
+
let trailingSlashes;
|
|
1805
|
+
const { ...markoVitePluginOptions } = opts;
|
|
1769
1806
|
let store;
|
|
1770
1807
|
let root;
|
|
1771
1808
|
let shouldEmptyOutDir = false;
|
|
@@ -1798,12 +1835,8 @@ function markoRun(opts = {}) {
|
|
|
1798
1835
|
root,
|
|
1799
1836
|
"{.tsconfig*,tsconfig*.json}"
|
|
1800
1837
|
)))) {
|
|
1801
|
-
const filepath =
|
|
1802
|
-
const data = await renderRouteTypeInfo(
|
|
1803
|
-
routes2,
|
|
1804
|
-
normalizePath(path4.relative(typesDir, resolvedRoutesDir)),
|
|
1805
|
-
adapter
|
|
1806
|
-
);
|
|
1838
|
+
const filepath = path6.join(typesDir, "routes.d.ts");
|
|
1839
|
+
const data = await renderRouteTypeInfo(routes2, typesDir, adapter);
|
|
1807
1840
|
if (data !== typesFile || !fs3.existsSync(filepath)) {
|
|
1808
1841
|
await ensureDir(typesDir);
|
|
1809
1842
|
await fs3.promises.writeFile(filepath, typesFile = data);
|
|
@@ -1814,20 +1847,25 @@ function markoRun(opts = {}) {
|
|
|
1814
1847
|
function buildVirtualFiles() {
|
|
1815
1848
|
return buildVirtualFilesResult ?? (buildVirtualFilesResult = (async () => {
|
|
1816
1849
|
virtualFiles.clear();
|
|
1817
|
-
routes = await buildRoutes(
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1850
|
+
routes = await buildRoutes(
|
|
1851
|
+
{
|
|
1852
|
+
walker: createFSWalker(resolvedRoutesDir)
|
|
1853
|
+
},
|
|
1854
|
+
entryFilesDir
|
|
1855
|
+
);
|
|
1821
1856
|
if (!routes.list.length) {
|
|
1822
1857
|
throw new Error("No routes generated");
|
|
1823
1858
|
}
|
|
1824
1859
|
for (const route of routes.list) {
|
|
1825
|
-
virtualFiles.set(
|
|
1860
|
+
virtualFiles.set(
|
|
1861
|
+
path6.posix.join(root, getRouteVirtualFileName(route)),
|
|
1862
|
+
""
|
|
1863
|
+
);
|
|
1826
1864
|
}
|
|
1827
1865
|
if (routes.middleware.length) {
|
|
1828
|
-
virtualFiles.set(
|
|
1866
|
+
virtualFiles.set(path6.posix.join(root, MIDDLEWARE_FILENAME), "");
|
|
1829
1867
|
}
|
|
1830
|
-
virtualFiles.set(
|
|
1868
|
+
virtualFiles.set(path6.posix.join(root, ROUTER_FILENAME), "");
|
|
1831
1869
|
return routes;
|
|
1832
1870
|
})());
|
|
1833
1871
|
}
|
|
@@ -1841,111 +1879,78 @@ function markoRun(opts = {}) {
|
|
|
1841
1879
|
fs3.rmSync(entryFilesDir, { recursive: true });
|
|
1842
1880
|
}
|
|
1843
1881
|
for (const route of routes2.list) {
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1882
|
+
if (route.handler) {
|
|
1883
|
+
const exports = await getExportsFromFile(
|
|
1884
|
+
context,
|
|
1885
|
+
route.handler.filePath
|
|
1886
|
+
);
|
|
1887
|
+
route.handler.verbs = [];
|
|
1848
1888
|
for (const name of exports) {
|
|
1849
1889
|
const verb = name.toLowerCase();
|
|
1850
1890
|
if (name === verb.toUpperCase() && httpVerbs.includes(verb)) {
|
|
1851
|
-
handler.verbs.push(verb);
|
|
1891
|
+
route.handler.verbs.push(verb);
|
|
1852
1892
|
}
|
|
1853
1893
|
}
|
|
1854
|
-
if (!handler.verbs.length) {
|
|
1894
|
+
if (!route.handler.verbs.length) {
|
|
1855
1895
|
context.warn(
|
|
1856
|
-
`Did not find any http verb exports in
|
|
1896
|
+
`Did not find any http verb exports in ${path6.relative(root, route.handler.filePath)} - expected ${httpVerbs.map((v) => v.toUpperCase()).join(", ")}`
|
|
1857
1897
|
);
|
|
1858
1898
|
}
|
|
1859
1899
|
}
|
|
1860
|
-
if (
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
path4.relative(routeFileDir, root)
|
|
1869
|
-
);
|
|
1870
|
-
fs3.mkdirSync(routeFileDir, { recursive: true });
|
|
1871
|
-
const pageNameIndex = page.name.indexOf("+page");
|
|
1872
|
-
const pageNamePrefix = pageNameIndex > 0 ? `${page.name.slice(0, pageNameIndex)}.` : "";
|
|
1873
|
-
fs3.writeFileSync(
|
|
1874
|
-
route.templateFilePath = path4.join(
|
|
1875
|
-
routeFileDir,
|
|
1876
|
-
pageNamePrefix + "route.marko"
|
|
1877
|
-
),
|
|
1878
|
-
renderRouteTemplate(
|
|
1879
|
-
route,
|
|
1880
|
-
(to) => path4.posix.join(routeFileRelativePathPosix, to)
|
|
1881
|
-
)
|
|
1882
|
-
);
|
|
1883
|
-
} else {
|
|
1884
|
-
route.templateFilePath = page.filePath;
|
|
1885
|
-
}
|
|
1900
|
+
if (route.templateFilePath) {
|
|
1901
|
+
fs3.mkdirSync(path6.dirname(route.templateFilePath), {
|
|
1902
|
+
recursive: true
|
|
1903
|
+
});
|
|
1904
|
+
fs3.writeFileSync(
|
|
1905
|
+
route.templateFilePath,
|
|
1906
|
+
renderRouteTemplate(route, root)
|
|
1907
|
+
);
|
|
1886
1908
|
}
|
|
1887
1909
|
virtualFiles.set(
|
|
1888
|
-
|
|
1889
|
-
renderRouteEntry(route,
|
|
1910
|
+
path6.posix.join(root, getRouteVirtualFileName(route)),
|
|
1911
|
+
renderRouteEntry(route, root)
|
|
1890
1912
|
);
|
|
1891
1913
|
}
|
|
1892
1914
|
for (const route of Object.values(routes2.special)) {
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
)
|
|
1900
|
-
|
|
1901
|
-
const routeFileRelativePathPosix = normalizePath(
|
|
1902
|
-
path4.relative(routeFileDir, root)
|
|
1903
|
-
);
|
|
1904
|
-
fs3.mkdirSync(routeFileDir, { recursive: true });
|
|
1905
|
-
fs3.writeFileSync(
|
|
1906
|
-
route.templateFilePath = path4.join(
|
|
1907
|
-
routeFileDir,
|
|
1908
|
-
`route.${key}.marko`
|
|
1909
|
-
),
|
|
1910
|
-
renderRouteTemplate(
|
|
1911
|
-
route,
|
|
1912
|
-
(to) => path4.posix.join(routeFileRelativePathPosix, to)
|
|
1913
|
-
)
|
|
1914
|
-
);
|
|
1915
|
-
} else {
|
|
1916
|
-
route.templateFilePath = page.filePath;
|
|
1917
|
-
}
|
|
1915
|
+
if (route.templateFilePath) {
|
|
1916
|
+
fs3.mkdirSync(path6.dirname(route.templateFilePath), {
|
|
1917
|
+
recursive: true
|
|
1918
|
+
});
|
|
1919
|
+
fs3.writeFileSync(
|
|
1920
|
+
route.templateFilePath,
|
|
1921
|
+
renderRouteTemplate(route, root)
|
|
1922
|
+
);
|
|
1918
1923
|
}
|
|
1919
1924
|
}
|
|
1920
1925
|
if (routes2.middleware.length) {
|
|
1921
1926
|
for (const middleware of routes2.middleware) {
|
|
1922
1927
|
if (!(await getExportsFromFile(context, middleware.filePath)).includes("default")) {
|
|
1923
1928
|
context.warn(
|
|
1924
|
-
`Did not find a default export in middleware '${
|
|
1929
|
+
`Did not find a default export in middleware '${path6.relative(root, middleware.filePath)}'`
|
|
1925
1930
|
);
|
|
1926
1931
|
}
|
|
1927
1932
|
}
|
|
1928
1933
|
virtualFiles.set(
|
|
1929
|
-
|
|
1930
|
-
renderMiddleware(routes2.middleware)
|
|
1934
|
+
path6.posix.join(root, MIDDLEWARE_FILENAME),
|
|
1935
|
+
renderMiddleware(routes2.middleware, root)
|
|
1931
1936
|
);
|
|
1932
1937
|
}
|
|
1933
1938
|
virtualFiles.set(
|
|
1934
|
-
|
|
1935
|
-
renderRouter(routes2,
|
|
1936
|
-
trailingSlashes
|
|
1939
|
+
path6.posix.join(root, ROUTER_FILENAME),
|
|
1940
|
+
renderRouter(routes2, root, {
|
|
1941
|
+
trailingSlashes
|
|
1937
1942
|
})
|
|
1938
1943
|
);
|
|
1939
1944
|
await writeTypesFile(routes2);
|
|
1940
1945
|
if (adapter == null ? void 0 : adapter.routesGenerated) {
|
|
1941
|
-
await adapter.routesGenerated(
|
|
1942
|
-
routes2,
|
|
1943
|
-
new Map(virtualFiles.entries()),
|
|
1944
|
-
{
|
|
1946
|
+
await adapter.routesGenerated({
|
|
1947
|
+
routes: routes2,
|
|
1948
|
+
virtualFiles: new Map(virtualFiles.entries()),
|
|
1949
|
+
meta: {
|
|
1945
1950
|
buildTime: times.routesBuild,
|
|
1946
1951
|
renderTime: times.routesRender
|
|
1947
1952
|
}
|
|
1948
|
-
);
|
|
1953
|
+
});
|
|
1949
1954
|
if (!isBuild) {
|
|
1950
1955
|
await ((_a = opts == null ? void 0 : opts.emitRoutes) == null ? void 0 : _a.call(opts, routes2.list));
|
|
1951
1956
|
}
|
|
@@ -1955,7 +1960,7 @@ function markoRun(opts = {}) {
|
|
|
1955
1960
|
throw err;
|
|
1956
1961
|
}
|
|
1957
1962
|
virtualFiles.set(
|
|
1958
|
-
|
|
1963
|
+
path6.posix.join(root, ROUTER_FILENAME),
|
|
1959
1964
|
`throw ${JSON.stringify(prepareError(err))}`
|
|
1960
1965
|
);
|
|
1961
1966
|
}
|
|
@@ -1992,27 +1997,28 @@ function markoRun(opts = {}) {
|
|
|
1992
1997
|
}
|
|
1993
1998
|
}
|
|
1994
1999
|
routesDir = opts.routesDir || "src/routes";
|
|
2000
|
+
trailingSlashes = opts.trailingSlashes || "RedirectWithout";
|
|
1995
2001
|
store = new ReadOncePersistedStore(
|
|
1996
2002
|
`vite-marko-run${opts.runtimeId ? `-${opts.runtimeId}` : ""}`
|
|
1997
2003
|
);
|
|
1998
2004
|
markoVitePluginOptions.runtimeId = opts.runtimeId;
|
|
1999
2005
|
markoVitePluginOptions.basePathVar = opts.basePathVar;
|
|
2000
|
-
resolvedRoutesDir =
|
|
2001
|
-
outputDir =
|
|
2002
|
-
entryFilesDir =
|
|
2006
|
+
resolvedRoutesDir = path6.resolve(root, routesDir);
|
|
2007
|
+
outputDir = path6.join(root, ((_d = config2.build) == null ? void 0 : _d.outDir) || "dist");
|
|
2008
|
+
entryFilesDir = path6.join(outputDir, ".marko-run");
|
|
2003
2009
|
entryFilesDirPosix = normalizePath(entryFilesDir);
|
|
2004
2010
|
relativeEntryFilesDirPosix = normalizePath(
|
|
2005
|
-
|
|
2011
|
+
path6.relative(root, entryFilesDir)
|
|
2006
2012
|
);
|
|
2007
|
-
typesDir =
|
|
2008
|
-
devEntryFile =
|
|
2013
|
+
typesDir = path6.join(root, ".marko-run");
|
|
2014
|
+
devEntryFile = path6.join(root, "index.html");
|
|
2009
2015
|
devEntryFilePosix = normalizePath(devEntryFile);
|
|
2010
2016
|
let outDir = ((_e = config2.build) == null ? void 0 : _e.outDir) || "dist";
|
|
2011
2017
|
const assetsDir = ((_f = config2.build) == null ? void 0 : _f.assetsDir) || "assets";
|
|
2012
2018
|
let rollupOutputOptions = (_h = (_g = config2.build) == null ? void 0 : _g.rollupOptions) == null ? void 0 : _h.output;
|
|
2013
2019
|
if (isBuild) {
|
|
2014
2020
|
if (!isSSRBuild) {
|
|
2015
|
-
outDir =
|
|
2021
|
+
outDir = path6.join(outDir, CLIENT_OUT_DIR);
|
|
2016
2022
|
}
|
|
2017
2023
|
const defaultRollupOutputOptions = {
|
|
2018
2024
|
assetFileNames({ name }) {
|
|
@@ -2137,7 +2143,7 @@ function markoRun(opts = {}) {
|
|
|
2137
2143
|
devServer.watcher.on("all", async (type, filename) => {
|
|
2138
2144
|
seenErrors.clear();
|
|
2139
2145
|
const routableFileType = matchRoutableFile(
|
|
2140
|
-
|
|
2146
|
+
path6.parse(filename).base
|
|
2141
2147
|
);
|
|
2142
2148
|
if (filename.startsWith(resolvedRoutesDir) && routableFileType) {
|
|
2143
2149
|
if (type === "add" || type === "unlink" || type === "change" && (routableFileType === RoutableFileTypes.Handler || routableFileType === RoutableFileTypes.Middleware)) {
|
|
@@ -2187,19 +2193,19 @@ function markoRun(opts = {}) {
|
|
|
2187
2193
|
},
|
|
2188
2194
|
async resolveId(importee, importer) {
|
|
2189
2195
|
if (importee === "@marko/run/router") {
|
|
2190
|
-
return normalizePath(
|
|
2196
|
+
return normalizePath(path6.resolve(root, ROUTER_FILENAME));
|
|
2191
2197
|
} else if (importee.endsWith(".marko") && importee.includes(relativeEntryFilesDirPosix)) {
|
|
2192
2198
|
if (!importee.startsWith(root)) {
|
|
2193
|
-
importee =
|
|
2199
|
+
importee = path6.resolve(root, "." + importee);
|
|
2194
2200
|
}
|
|
2195
2201
|
return normalizePath(importee);
|
|
2196
2202
|
}
|
|
2197
2203
|
let virtualFilePath;
|
|
2198
2204
|
if (importee.startsWith(virtualFilePrefix)) {
|
|
2199
2205
|
virtualFilePath = importee.slice(virtualFilePrefix.length + 1);
|
|
2200
|
-
importee =
|
|
2206
|
+
importee = path6.resolve(root, virtualFilePath);
|
|
2201
2207
|
} else if (!isBuild && importer && (importer === devEntryFile || normalizePath(importer) === devEntryFilePosix) && importee.startsWith(`/${markoRunFilePrefix}`)) {
|
|
2202
|
-
importee =
|
|
2208
|
+
importee = path6.resolve(root, "." + importee);
|
|
2203
2209
|
}
|
|
2204
2210
|
importee = normalizePath(importee);
|
|
2205
2211
|
if (!buildVirtualFilesResult) {
|
|
@@ -2208,7 +2214,7 @@ function markoRun(opts = {}) {
|
|
|
2208
2214
|
if (virtualFiles.has(importee)) {
|
|
2209
2215
|
return importee;
|
|
2210
2216
|
} else if (virtualFilePath) {
|
|
2211
|
-
const filePath =
|
|
2217
|
+
const filePath = path6.resolve(__dirname, "..", virtualFilePath);
|
|
2212
2218
|
return await this.resolve(filePath, importer, {
|
|
2213
2219
|
skipSelf: true
|
|
2214
2220
|
});
|
|
@@ -2247,7 +2253,7 @@ function markoRun(opts = {}) {
|
|
|
2247
2253
|
const builtEntries = Object.values(bundle).reduce(
|
|
2248
2254
|
(acc, item) => {
|
|
2249
2255
|
if (item.type === "chunk" && item.isEntry) {
|
|
2250
|
-
acc.push(
|
|
2256
|
+
acc.push(path6.join(options.dir, item.fileName));
|
|
2251
2257
|
}
|
|
2252
2258
|
return acc;
|
|
2253
2259
|
},
|
|
@@ -2275,12 +2281,12 @@ function markoRun(opts = {}) {
|
|
|
2275
2281
|
fs3.rmSync(entryFilesDir, { recursive: true });
|
|
2276
2282
|
}
|
|
2277
2283
|
if ((adapter == null ? void 0 : adapter.buildEnd) && routes) {
|
|
2278
|
-
await adapter.buildEnd(
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
routeData.builtEntries,
|
|
2282
|
-
routeData.sourceEntries
|
|
2283
|
-
);
|
|
2284
|
+
await adapter.buildEnd({
|
|
2285
|
+
routes,
|
|
2286
|
+
config: resolvedConfig,
|
|
2287
|
+
builtEntries: routeData.builtEntries,
|
|
2288
|
+
sourceEntries: routeData.sourceEntries
|
|
2289
|
+
});
|
|
2284
2290
|
}
|
|
2285
2291
|
}
|
|
2286
2292
|
}
|
|
@@ -2312,11 +2318,11 @@ async function ensureDir(dir) {
|
|
|
2312
2318
|
}
|
|
2313
2319
|
async function getPackageData(dir) {
|
|
2314
2320
|
do {
|
|
2315
|
-
const pkgPath =
|
|
2321
|
+
const pkgPath = path6.join(dir, "package.json");
|
|
2316
2322
|
if (fs3.existsSync(pkgPath)) {
|
|
2317
2323
|
return JSON.parse(await fs3.promises.readFile(pkgPath, "utf-8"));
|
|
2318
2324
|
}
|
|
2319
|
-
} while (dir !== (dir =
|
|
2325
|
+
} while (dir !== (dir = path6.dirname(dir)));
|
|
2320
2326
|
return null;
|
|
2321
2327
|
}
|
|
2322
2328
|
async function resolveAdapter(root, options, log) {
|