@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/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,31 +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 extends Run.LayoutInput<typeof import(
|
|
911
|
+
export interface Input extends Run.LayoutInput<typeof import("${modulePath}")> {}`
|
|
876
912
|
);
|
|
877
913
|
break;
|
|
878
914
|
case RoutableFileTypes.Error:
|
|
879
915
|
writeModuleDeclaration(
|
|
880
916
|
writer,
|
|
881
|
-
|
|
917
|
+
modulePath,
|
|
882
918
|
"globalThis.MarkoRun.Route",
|
|
883
919
|
`
|
|
884
920
|
export interface Input {
|
|
@@ -887,7 +923,7 @@ async function renderRouteTypeInfo(routes, pathPrefix = ".", adapter) {
|
|
|
887
923
|
);
|
|
888
924
|
break;
|
|
889
925
|
case RoutableFileTypes.NotFound:
|
|
890
|
-
writeModuleDeclaration(writer,
|
|
926
|
+
writeModuleDeclaration(writer, modulePath, "Run.Route");
|
|
891
927
|
break;
|
|
892
928
|
}
|
|
893
929
|
}
|
|
@@ -895,40 +931,15 @@ async function renderRouteTypeInfo(routes, pathPrefix = ".", adapter) {
|
|
|
895
931
|
middlewareWriter.join();
|
|
896
932
|
pageWriter.join();
|
|
897
933
|
layoutWriter.join();
|
|
898
|
-
writer.writeBlockStart(`
|
|
899
|
-
type Routes = {`);
|
|
900
|
-
for (const route of routes.list) {
|
|
901
|
-
const { meta, handler, page } = route;
|
|
902
|
-
if (page || handler) {
|
|
903
|
-
const verbs = [];
|
|
904
|
-
if (page || ((_a = handler == null ? void 0 : handler.verbs) == null ? void 0 : _a.includes("get"))) {
|
|
905
|
-
verbs.push(`"get"`);
|
|
906
|
-
}
|
|
907
|
-
if ((_b = handler == null ? void 0 : handler.verbs) == null ? void 0 : _b.includes("post")) {
|
|
908
|
-
verbs.push(`"post"`);
|
|
909
|
-
}
|
|
910
|
-
let routeType = `{ verb: ${verbs.join(" | ")};`;
|
|
911
|
-
if (meta) {
|
|
912
|
-
const metaPath = stripTsExtension(`${pathPrefix}/${meta.relativePath}`);
|
|
913
|
-
let metaType = `typeof import("${metaPath}")`;
|
|
914
|
-
if (/\.(ts|js|mjs)$/.test(meta.name)) {
|
|
915
|
-
metaType += `["default"]`;
|
|
916
|
-
}
|
|
917
|
-
routeType += ` meta: ${metaType};`;
|
|
918
|
-
}
|
|
919
|
-
writer.writeLines(`"${route.key}": ${routeType} };`);
|
|
920
|
-
}
|
|
921
|
-
}
|
|
922
|
-
writer.writeBlockEnd("}");
|
|
923
934
|
return writer.end();
|
|
924
935
|
}
|
|
925
|
-
function writeModuleDeclaration(writer,
|
|
926
|
-
writer.writeLines("").write(`declare module "${
|
|
936
|
+
function writeModuleDeclaration(writer, name, routeType, moduleTypes) {
|
|
937
|
+
writer.writeLines("").write(`declare module "${name}" {`);
|
|
927
938
|
if (moduleTypes) {
|
|
928
939
|
writer.write(moduleTypes);
|
|
929
940
|
}
|
|
930
941
|
if (routeType) {
|
|
931
|
-
const isMarko =
|
|
942
|
+
const isMarko = name.endsWith(".marko");
|
|
932
943
|
writer.write(`
|
|
933
944
|
namespace MarkoRun {
|
|
934
945
|
export { NotHandled, NotMatched, GetPaths, PostPaths, GetablePath, GetableHref, PostablePath, PostableHref, Platform };
|
|
@@ -942,21 +953,15 @@ function writeModuleDeclaration(writer, path5, routeType, moduleTypes) {
|
|
|
942
953
|
writer.writeLines(`
|
|
943
954
|
}`);
|
|
944
955
|
}
|
|
945
|
-
function pathToURLPatternString(path5) {
|
|
946
|
-
return path5.replace(/\/\$(\$?)([^/]*)/g, (_, catchAll, name) => {
|
|
947
|
-
name = decodeURIComponent(name);
|
|
948
|
-
return catchAll ? `/:${name || "rest"}*` : `/:${name}`;
|
|
949
|
-
});
|
|
950
|
-
}
|
|
951
956
|
function createRouteTrie(routes) {
|
|
952
957
|
const root = {
|
|
953
958
|
key: ""
|
|
954
959
|
};
|
|
955
|
-
function insert(
|
|
960
|
+
function insert(path7, route) {
|
|
956
961
|
let node = root;
|
|
957
|
-
for (const segment of
|
|
962
|
+
for (const segment of path7.segments) {
|
|
958
963
|
if (segment === "$$") {
|
|
959
|
-
node.catchAll ?? (node.catchAll = { route, path:
|
|
964
|
+
node.catchAll ?? (node.catchAll = { route, path: path7 });
|
|
960
965
|
return;
|
|
961
966
|
} else if (segment === "$") {
|
|
962
967
|
node = node.dynamic ?? (node.dynamic = {
|
|
@@ -974,17 +979,18 @@ function createRouteTrie(routes) {
|
|
|
974
979
|
node = next;
|
|
975
980
|
}
|
|
976
981
|
}
|
|
977
|
-
node.path ?? (node.path =
|
|
982
|
+
node.path ?? (node.path = path7);
|
|
978
983
|
node.route ?? (node.route = route);
|
|
979
984
|
}
|
|
980
985
|
for (const route of routes) {
|
|
981
|
-
|
|
982
|
-
insert(path5, route);
|
|
983
|
-
}
|
|
986
|
+
insert(route.path, route);
|
|
984
987
|
}
|
|
985
988
|
return root;
|
|
986
989
|
}
|
|
987
990
|
|
|
991
|
+
// src/vite/routes/builder.ts
|
|
992
|
+
import path3 from "path";
|
|
993
|
+
|
|
988
994
|
// src/vite/routes/parse.ts
|
|
989
995
|
function parseFlatRoute(pattern) {
|
|
990
996
|
if (!pattern) throw new Error("Empty pattern");
|
|
@@ -999,53 +1005,72 @@ function parseFlatRoute(pattern) {
|
|
|
999
1005
|
]);
|
|
1000
1006
|
function parse2(basePaths, group) {
|
|
1001
1007
|
const pathMap = /* @__PURE__ */ new Map();
|
|
1002
|
-
const delimiters = group ? ").," : "
|
|
1008
|
+
const delimiters = group ? "`).," : "`.,";
|
|
1003
1009
|
let charCode;
|
|
1004
1010
|
let segmentStart = i;
|
|
1005
1011
|
let type;
|
|
1006
1012
|
let current;
|
|
1013
|
+
let escaped = "";
|
|
1014
|
+
let escapeStart = 0;
|
|
1007
1015
|
do {
|
|
1008
1016
|
charCode = pattern.charCodeAt(i);
|
|
1009
|
-
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) {
|
|
1010
1028
|
break;
|
|
1011
|
-
} else if (charCode === 44) {
|
|
1029
|
+
} else if (charCode === 44 /* Alternate */) {
|
|
1012
1030
|
if (!current) {
|
|
1013
1031
|
segmentEnd(
|
|
1014
|
-
basePaths.map((
|
|
1015
|
-
...
|
|
1016
|
-
segments:
|
|
1032
|
+
basePaths.map((path7) => ({
|
|
1033
|
+
...path7,
|
|
1034
|
+
segments: path7.segments.slice()
|
|
1017
1035
|
})),
|
|
1018
|
-
|
|
1036
|
+
escaped,
|
|
1019
1037
|
"_",
|
|
1020
1038
|
pathMap
|
|
1021
1039
|
);
|
|
1022
1040
|
} else {
|
|
1023
|
-
segmentEnd(
|
|
1041
|
+
segmentEnd(
|
|
1042
|
+
current,
|
|
1043
|
+
escaped + pattern.slice(segmentStart, i),
|
|
1044
|
+
type,
|
|
1045
|
+
pathMap
|
|
1046
|
+
);
|
|
1024
1047
|
}
|
|
1025
1048
|
current = void 0;
|
|
1026
1049
|
type = void 0;
|
|
1050
|
+
escaped = "";
|
|
1027
1051
|
segmentStart = ++i;
|
|
1028
|
-
} else if (charCode === 46) {
|
|
1052
|
+
} else if (charCode === 46 /* Directory */) {
|
|
1029
1053
|
if (current) {
|
|
1030
|
-
segmentEnd(current, pattern.slice(segmentStart, i), type);
|
|
1054
|
+
segmentEnd(current, escaped + pattern.slice(segmentStart, i), type);
|
|
1031
1055
|
}
|
|
1032
1056
|
type = void 0;
|
|
1057
|
+
escaped = "";
|
|
1033
1058
|
segmentStart = ++i;
|
|
1034
|
-
} else if (charCode === 40) {
|
|
1059
|
+
} else if (charCode === 40 /* GroupStart */) {
|
|
1035
1060
|
const groupPaths = parse2(current || basePaths, ++i);
|
|
1036
1061
|
if (groupPaths.length) {
|
|
1037
1062
|
current = groupPaths;
|
|
1038
1063
|
}
|
|
1039
1064
|
segmentStart = ++i;
|
|
1040
1065
|
} else {
|
|
1041
|
-
if (charCode === 95) {
|
|
1066
|
+
if (charCode === 95 /* Pathless */) {
|
|
1042
1067
|
type = "_";
|
|
1043
|
-
} else if (charCode === 36) {
|
|
1068
|
+
} else if (charCode === 36 /* Dynamic */) {
|
|
1044
1069
|
type = pattern.charCodeAt(i + 1) === 36 ? "$$" : "$";
|
|
1045
1070
|
}
|
|
1046
|
-
current ?? (current = basePaths.map((
|
|
1047
|
-
...
|
|
1048
|
-
segments:
|
|
1071
|
+
current ?? (current = basePaths.map((path7) => ({
|
|
1072
|
+
...path7,
|
|
1073
|
+
segments: path7.segments.slice()
|
|
1049
1074
|
})));
|
|
1050
1075
|
i = len;
|
|
1051
1076
|
for (const char of delimiters) {
|
|
@@ -1056,7 +1081,12 @@ function parseFlatRoute(pattern) {
|
|
|
1056
1081
|
}
|
|
1057
1082
|
}
|
|
1058
1083
|
} while (i < len);
|
|
1059
|
-
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 */) {
|
|
1060
1090
|
throw new Error(
|
|
1061
1091
|
`Invalid route pattern: group was not closed '${pattern.slice(
|
|
1062
1092
|
group
|
|
@@ -1065,16 +1095,21 @@ function parseFlatRoute(pattern) {
|
|
|
1065
1095
|
}
|
|
1066
1096
|
if (!current) {
|
|
1067
1097
|
segmentEnd(
|
|
1068
|
-
basePaths.map((
|
|
1069
|
-
...
|
|
1070
|
-
segments:
|
|
1098
|
+
basePaths.map((path7) => ({
|
|
1099
|
+
...path7,
|
|
1100
|
+
segments: path7.segments.slice()
|
|
1071
1101
|
})),
|
|
1072
|
-
|
|
1073
|
-
|
|
1102
|
+
escaped,
|
|
1103
|
+
void 0,
|
|
1074
1104
|
pathMap
|
|
1075
1105
|
);
|
|
1076
1106
|
} else {
|
|
1077
|
-
segmentEnd(
|
|
1107
|
+
segmentEnd(
|
|
1108
|
+
current,
|
|
1109
|
+
escaped + pattern.slice(segmentStart, i),
|
|
1110
|
+
type,
|
|
1111
|
+
pathMap
|
|
1112
|
+
);
|
|
1078
1113
|
}
|
|
1079
1114
|
return [...pathMap.values()];
|
|
1080
1115
|
}
|
|
@@ -1083,17 +1118,17 @@ function parseFlatRoute(pattern) {
|
|
|
1083
1118
|
if (raw) {
|
|
1084
1119
|
segment = {
|
|
1085
1120
|
raw,
|
|
1086
|
-
name: raw,
|
|
1121
|
+
name: normalizeSegment(raw),
|
|
1087
1122
|
type
|
|
1088
1123
|
};
|
|
1089
1124
|
if (type === "$" || type === "$$") {
|
|
1090
1125
|
segment.name = type;
|
|
1091
|
-
segment.param = raw.slice(type.length);
|
|
1126
|
+
segment.param = normalizeParam(raw.slice(type.length));
|
|
1092
1127
|
}
|
|
1093
1128
|
}
|
|
1094
|
-
for (const
|
|
1129
|
+
for (const path7 of paths) {
|
|
1095
1130
|
if (segment) {
|
|
1096
|
-
if (
|
|
1131
|
+
if (path7.isCatchall) {
|
|
1097
1132
|
throw new Error(
|
|
1098
1133
|
`Invalid route pattern: nested segments are not allowed after a catch-all parameter. Found '.' following '${pattern.slice(
|
|
1099
1134
|
0,
|
|
@@ -1101,26 +1136,36 @@ function parseFlatRoute(pattern) {
|
|
|
1101
1136
|
)}' in '${pattern}'.`
|
|
1102
1137
|
);
|
|
1103
1138
|
}
|
|
1104
|
-
|
|
1105
|
-
|
|
1139
|
+
path7.segments.push(segment);
|
|
1140
|
+
path7.id += path7.id === "/" ? segment.name : `/${segment.name}`;
|
|
1106
1141
|
if (type === "$$") {
|
|
1107
|
-
|
|
1142
|
+
path7.isCatchall = true;
|
|
1108
1143
|
}
|
|
1109
1144
|
}
|
|
1110
1145
|
if (map) {
|
|
1111
|
-
if (map.has(
|
|
1112
|
-
const existing = map.get(
|
|
1146
|
+
if (map.has(path7.id)) {
|
|
1147
|
+
const existing = map.get(path7.id);
|
|
1113
1148
|
const existingExpansion = existing.segments.map((s) => s.raw).join(".");
|
|
1114
|
-
const currentExpansion =
|
|
1149
|
+
const currentExpansion = path7.segments.map((s) => s.raw).join(".");
|
|
1115
1150
|
throw new Error(
|
|
1116
|
-
`Invalid route pattern: route '${
|
|
1151
|
+
`Invalid route pattern: route '${path7.id}' is ambiguous. Expansion '${currentExpansion}' collides with '${existingExpansion}' in '${pattern}'.`
|
|
1117
1152
|
);
|
|
1118
1153
|
}
|
|
1119
|
-
map.set(
|
|
1154
|
+
map.set(path7.id, path7);
|
|
1120
1155
|
}
|
|
1121
1156
|
}
|
|
1122
1157
|
}
|
|
1123
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
|
+
}
|
|
1124
1169
|
|
|
1125
1170
|
// src/vite/routes/vdir.ts
|
|
1126
1171
|
var _dirs, _pathlessDirs;
|
|
@@ -1131,14 +1176,12 @@ var _VDir = class _VDir {
|
|
|
1131
1176
|
__publicField(this, "parent");
|
|
1132
1177
|
__publicField(this, "source");
|
|
1133
1178
|
__publicField(this, "path");
|
|
1134
|
-
__publicField(this, "fullPath");
|
|
1135
1179
|
__publicField(this, "segment");
|
|
1136
1180
|
__publicField(this, "files");
|
|
1137
1181
|
if (!parent || !segment) {
|
|
1138
1182
|
this.parent = null;
|
|
1139
1183
|
this.source = null;
|
|
1140
1184
|
this.path = "/";
|
|
1141
|
-
this.fullPath = "/";
|
|
1142
1185
|
this.segment = {
|
|
1143
1186
|
raw: "",
|
|
1144
1187
|
name: ""
|
|
@@ -1146,12 +1189,8 @@ var _VDir = class _VDir {
|
|
|
1146
1189
|
} else {
|
|
1147
1190
|
this.parent = parent;
|
|
1148
1191
|
this.source = source;
|
|
1149
|
-
this.path = parent.path + (parent.path === "/" ? segment.name : `/${segment.name}`);
|
|
1150
|
-
this.fullPath = parent.fullPath + (parent.fullPath === "/" ? segment.name : `/${segment.name}`);
|
|
1151
|
-
if (segment.param) {
|
|
1152
|
-
this.fullPath += segment.param;
|
|
1153
|
-
}
|
|
1154
1192
|
this.segment = segment;
|
|
1193
|
+
this.path = parent.path + (parent.path === "/" ? "" : "/") + segment.name;
|
|
1155
1194
|
}
|
|
1156
1195
|
}
|
|
1157
1196
|
get pathInfo() {
|
|
@@ -1164,17 +1203,18 @@ var _VDir = class _VDir {
|
|
|
1164
1203
|
for (const { segment } of this) {
|
|
1165
1204
|
const { type, name, param } = segment;
|
|
1166
1205
|
if (name && type !== "_") {
|
|
1167
|
-
value.id += sep +
|
|
1206
|
+
value.id += sep + name;
|
|
1168
1207
|
value.path += sep + name;
|
|
1169
1208
|
value.isEnd = type === "$$";
|
|
1170
1209
|
if (param) {
|
|
1171
|
-
|
|
1210
|
+
const unescapedParam = param.charAt(0) === "`" ? param.slice(1, -1) : param;
|
|
1172
1211
|
const index = type === "$$" ? null : value.segments.length;
|
|
1173
1212
|
if (!value.params) {
|
|
1174
|
-
value.params = { [
|
|
1213
|
+
value.params = { [unescapedParam]: index };
|
|
1175
1214
|
} else if (!(param in value.params)) {
|
|
1176
|
-
value.params[
|
|
1215
|
+
value.params[unescapedParam] = index;
|
|
1177
1216
|
}
|
|
1217
|
+
value.path += param;
|
|
1178
1218
|
}
|
|
1179
1219
|
value.segments.push(name);
|
|
1180
1220
|
sep = "/";
|
|
@@ -1186,11 +1226,11 @@ var _VDir = class _VDir {
|
|
|
1186
1226
|
});
|
|
1187
1227
|
return value;
|
|
1188
1228
|
}
|
|
1189
|
-
addDir(
|
|
1229
|
+
addDir(path7, segment) {
|
|
1190
1230
|
const map = segment.type === "_" ? __privateGet(this, _pathlessDirs) ?? __privateSet(this, _pathlessDirs, /* @__PURE__ */ new Map()) : __privateGet(this, _dirs) ?? __privateSet(this, _dirs, /* @__PURE__ */ new Map());
|
|
1191
1231
|
const key = segment.type === "$" ? segment.raw : segment.name;
|
|
1192
1232
|
if (!map.has(key)) {
|
|
1193
|
-
const dir = new _VDir(this, segment,
|
|
1233
|
+
const dir = new _VDir(this, segment, path7);
|
|
1194
1234
|
map.set(key, dir);
|
|
1195
1235
|
return dir;
|
|
1196
1236
|
}
|
|
@@ -1206,15 +1246,15 @@ var _VDir = class _VDir {
|
|
|
1206
1246
|
const existing = this.files.get(file.type);
|
|
1207
1247
|
if (existing !== file) {
|
|
1208
1248
|
throw new Error(
|
|
1209
|
-
`Duplicate file type
|
|
1249
|
+
`Duplicate file type ${file.type} added at path ${this.path}. File ${file.filePath} collides with ${existing.filePath}.`
|
|
1210
1250
|
);
|
|
1211
1251
|
} else if (file.type === RoutableFileTypes.Page || file.type === RoutableFileTypes.Handler) {
|
|
1212
1252
|
throw new Error(
|
|
1213
|
-
`Ambiguous path definition: route
|
|
1253
|
+
`Ambiguous path definition: route ${this.path} is defined multiple times by ${file.filePath}`
|
|
1214
1254
|
);
|
|
1215
1255
|
}
|
|
1216
1256
|
throw new Error(
|
|
1217
|
-
`Ambiguous path definition: file
|
|
1257
|
+
`Ambiguous path definition: file ${this.path} is included multiple times by ${file.filePath}`
|
|
1218
1258
|
);
|
|
1219
1259
|
}
|
|
1220
1260
|
}
|
|
@@ -1236,10 +1276,10 @@ var _VDir = class _VDir {
|
|
|
1236
1276
|
const dirs = [];
|
|
1237
1277
|
const unique = /* @__PURE__ */ new Map();
|
|
1238
1278
|
for (const root of roots) {
|
|
1239
|
-
for (const
|
|
1279
|
+
for (const path7 of paths) {
|
|
1240
1280
|
let dir = root;
|
|
1241
|
-
for (const segment of
|
|
1242
|
-
dir = dir.addDir(
|
|
1281
|
+
for (const segment of path7.segments) {
|
|
1282
|
+
dir = dir.addDir(path7, segment);
|
|
1243
1283
|
}
|
|
1244
1284
|
const existing = unique.get(dir.path);
|
|
1245
1285
|
if (existing) {
|
|
@@ -1252,7 +1292,7 @@ var _VDir = class _VDir {
|
|
|
1252
1292
|
}
|
|
1253
1293
|
}
|
|
1254
1294
|
throw new Error(
|
|
1255
|
-
`Ambiguous directory structure:
|
|
1295
|
+
`Ambiguous directory structure: ${sourcePath}${path7.source} defines ${dir.path} multiple times.`
|
|
1256
1296
|
);
|
|
1257
1297
|
} else {
|
|
1258
1298
|
unique.set(dir.path, dir);
|
|
@@ -1278,13 +1318,11 @@ function matchRoutableFile(filename) {
|
|
|
1278
1318
|
const match = filename.match(routeableFileRegex);
|
|
1279
1319
|
return match && (match[1] || match[3]).toLowerCase();
|
|
1280
1320
|
}
|
|
1281
|
-
function
|
|
1282
|
-
return type === RoutableFileTypes.NotFound || type === RoutableFileTypes.Error;
|
|
1283
|
-
}
|
|
1284
|
-
async function buildRoutes(sources) {
|
|
1321
|
+
async function buildRoutes(sources, outDir) {
|
|
1285
1322
|
const uniqueRoutes = /* @__PURE__ */ new Map();
|
|
1286
1323
|
const routes = [];
|
|
1287
1324
|
const special = {};
|
|
1325
|
+
const seenKeys = /* @__PURE__ */ new Map();
|
|
1288
1326
|
const middlewares = /* @__PURE__ */ new Set();
|
|
1289
1327
|
const unusedFiles = /* @__PURE__ */ new Set();
|
|
1290
1328
|
const currentLayouts = /* @__PURE__ */ new Set();
|
|
@@ -1292,13 +1330,13 @@ async function buildRoutes(sources) {
|
|
|
1292
1330
|
const root = new VDir();
|
|
1293
1331
|
const dirStack = [];
|
|
1294
1332
|
let basePath;
|
|
1295
|
-
let importPrefix;
|
|
1296
1333
|
let activeDirs;
|
|
1297
1334
|
let isBaseDir;
|
|
1298
1335
|
let nextFileId = 1;
|
|
1299
1336
|
let nextRouteIndex = 1;
|
|
1300
1337
|
const walkOptions = {
|
|
1301
|
-
onEnter(
|
|
1338
|
+
onEnter(dir) {
|
|
1339
|
+
let { name } = dir;
|
|
1302
1340
|
const prevDirStackLength = dirStack.length;
|
|
1303
1341
|
if (isBaseDir) {
|
|
1304
1342
|
isBaseDir = false;
|
|
@@ -1317,15 +1355,16 @@ async function buildRoutes(sources) {
|
|
|
1317
1355
|
dirStack.length = prevDirStackLength;
|
|
1318
1356
|
};
|
|
1319
1357
|
},
|
|
1320
|
-
onFile(
|
|
1358
|
+
onFile(file) {
|
|
1359
|
+
const { name } = file;
|
|
1321
1360
|
const match = name.match(routeableFileRegex);
|
|
1322
1361
|
if (!match) {
|
|
1323
1362
|
return;
|
|
1324
1363
|
}
|
|
1325
1364
|
const type = (match[1] || match[3]).toLowerCase();
|
|
1326
|
-
if (dirStack.length &&
|
|
1365
|
+
if (dirStack.length && (type === RoutableFileTypes.NotFound || type === RoutableFileTypes.Error)) {
|
|
1327
1366
|
console.warn(
|
|
1328
|
-
`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}`
|
|
1329
1368
|
);
|
|
1330
1369
|
return;
|
|
1331
1370
|
}
|
|
@@ -1334,19 +1373,15 @@ async function buildRoutes(sources) {
|
|
|
1334
1373
|
const paths = parseFlatRoute(name.slice(0, match.index));
|
|
1335
1374
|
dirs = VDir.addPaths(activeDirs, paths);
|
|
1336
1375
|
}
|
|
1337
|
-
const
|
|
1338
|
-
const relativePath = dirPath ? `${dirPath}/${name}` : name;
|
|
1339
|
-
const file = {
|
|
1376
|
+
const routableFile = {
|
|
1340
1377
|
id: String(nextFileId++),
|
|
1341
1378
|
name,
|
|
1342
1379
|
type,
|
|
1343
|
-
filePath:
|
|
1344
|
-
relativePath,
|
|
1345
|
-
importPath: `${importPrefix}/${relativePath}`,
|
|
1380
|
+
filePath: file.path,
|
|
1346
1381
|
verbs: type === RoutableFileTypes.Page ? ["get", "head"] : void 0
|
|
1347
1382
|
};
|
|
1348
1383
|
for (const dir of dirs) {
|
|
1349
|
-
dir.addFile(
|
|
1384
|
+
dir.addFile(routableFile);
|
|
1350
1385
|
}
|
|
1351
1386
|
}
|
|
1352
1387
|
};
|
|
@@ -1354,7 +1389,6 @@ async function buildRoutes(sources) {
|
|
|
1354
1389
|
sources = [sources];
|
|
1355
1390
|
}
|
|
1356
1391
|
for (const source of sources) {
|
|
1357
|
-
importPrefix = source.importPrefix ? source.importPrefix.replace(/^\/+|\/+$/g, "") : "";
|
|
1358
1392
|
basePath = source.basePath || "";
|
|
1359
1393
|
activeDirs = [root];
|
|
1360
1394
|
isBaseDir = true;
|
|
@@ -1374,7 +1408,8 @@ async function buildRoutes(sources) {
|
|
|
1374
1408
|
layout = dir.files.get(RoutableFileTypes.Layout);
|
|
1375
1409
|
const handler = dir.files.get(RoutableFileTypes.Handler);
|
|
1376
1410
|
const page = dir.files.get(RoutableFileTypes.Page);
|
|
1377
|
-
|
|
1411
|
+
const pathInfo = dir.pathInfo;
|
|
1412
|
+
let layoutsUsed = false;
|
|
1378
1413
|
if (middleware) {
|
|
1379
1414
|
if (currentMiddleware.has(middleware)) {
|
|
1380
1415
|
middleware = void 0;
|
|
@@ -1391,64 +1426,64 @@ async function buildRoutes(sources) {
|
|
|
1391
1426
|
unusedFiles.add(layout);
|
|
1392
1427
|
}
|
|
1393
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
|
+
}
|
|
1394
1445
|
if (page || handler) {
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
const existing = uniqueRoutes.get(path5.id);
|
|
1446
|
+
if (uniqueRoutes.has(pathInfo.id)) {
|
|
1447
|
+
const existing = uniqueRoutes.get(pathInfo.id);
|
|
1398
1448
|
const route = routes[existing.index];
|
|
1399
1449
|
const existingFiles = [route.handler, route.page].filter(Boolean).map((f) => f.filePath);
|
|
1400
1450
|
const currentFiles = [handler, page].filter(Boolean).map((f) => f.filePath);
|
|
1401
|
-
throw new Error(
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
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;
|
|
1406
1461
|
}
|
|
1407
|
-
uniqueRoutes.set(path5.id, { dir, index: routes.length });
|
|
1408
1462
|
routes.push({
|
|
1409
1463
|
index: nextRouteIndex++,
|
|
1410
|
-
key
|
|
1411
|
-
|
|
1464
|
+
key,
|
|
1465
|
+
path: pathInfo,
|
|
1412
1466
|
middleware: [...currentMiddleware],
|
|
1413
1467
|
layouts: page ? [...currentLayouts] : [],
|
|
1414
1468
|
meta: dir.files.get(RoutableFileTypes.Meta),
|
|
1415
1469
|
page,
|
|
1416
1470
|
handler,
|
|
1417
|
-
|
|
1471
|
+
templateFilePath: page && currentLayouts.size ? path3.join(outDir, key + ".marko") : void 0
|
|
1418
1472
|
});
|
|
1419
|
-
|
|
1420
|
-
if (dir === root) {
|
|
1421
|
-
for (const [type, file] of dir.files) {
|
|
1422
|
-
if (isSpecialType(type)) {
|
|
1423
|
-
hasSpecial = true;
|
|
1424
|
-
special[type] = {
|
|
1425
|
-
index: 0,
|
|
1426
|
-
key: type,
|
|
1427
|
-
paths: [],
|
|
1428
|
-
middleware: [],
|
|
1429
|
-
layouts: [...currentLayouts],
|
|
1430
|
-
page: file,
|
|
1431
|
-
entryName: `${markoRunFilePrefix}special.${type}`
|
|
1432
|
-
};
|
|
1433
|
-
}
|
|
1434
|
-
}
|
|
1435
|
-
}
|
|
1436
|
-
if (handler || page) {
|
|
1473
|
+
layoutsUsed = !!page;
|
|
1437
1474
|
for (const middleware2 of currentMiddleware) {
|
|
1438
1475
|
middlewares.add(middleware2);
|
|
1439
1476
|
unusedFiles.delete(middleware2);
|
|
1440
1477
|
}
|
|
1441
1478
|
}
|
|
1442
|
-
if (
|
|
1479
|
+
if (layoutsUsed) {
|
|
1443
1480
|
for (const layout2 of currentLayouts) {
|
|
1444
1481
|
unusedFiles.delete(layout2);
|
|
1445
1482
|
}
|
|
1446
1483
|
}
|
|
1447
1484
|
}
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
traverse(child);
|
|
1451
|
-
}
|
|
1485
|
+
for (const childDir of dir.dirs()) {
|
|
1486
|
+
traverse(childDir);
|
|
1452
1487
|
}
|
|
1453
1488
|
if (middleware) {
|
|
1454
1489
|
currentMiddleware.delete(middleware);
|
|
@@ -1458,10 +1493,13 @@ async function buildRoutes(sources) {
|
|
|
1458
1493
|
}
|
|
1459
1494
|
}
|
|
1460
1495
|
}
|
|
1496
|
+
function replaceInvalidFilenameChars(str) {
|
|
1497
|
+
return str.replace(/[<>:"/\\|?*]+/g, "_");
|
|
1498
|
+
}
|
|
1461
1499
|
|
|
1462
1500
|
// src/vite/routes/walk.ts
|
|
1463
1501
|
import fs from "fs";
|
|
1464
|
-
import
|
|
1502
|
+
import path4 from "path";
|
|
1465
1503
|
function createFSWalker(dir) {
|
|
1466
1504
|
return async function walkFS({
|
|
1467
1505
|
onEnter,
|
|
@@ -1476,7 +1514,7 @@ function createFSWalker(dir) {
|
|
|
1476
1514
|
const entries = await fs.promises.readdir(dir2.path, {
|
|
1477
1515
|
withFileTypes: true
|
|
1478
1516
|
});
|
|
1479
|
-
const prefix = dir2.path +
|
|
1517
|
+
const prefix = dir2.path + path4.sep;
|
|
1480
1518
|
for (const entry of entries) {
|
|
1481
1519
|
const walkEntry = {
|
|
1482
1520
|
name: entry.name,
|
|
@@ -1499,7 +1537,7 @@ function createFSWalker(dir) {
|
|
|
1499
1537
|
await walk(
|
|
1500
1538
|
{
|
|
1501
1539
|
path: dir,
|
|
1502
|
-
name:
|
|
1540
|
+
name: path4.basename(dir)
|
|
1503
1541
|
},
|
|
1504
1542
|
maxDepth
|
|
1505
1543
|
);
|
|
@@ -1616,36 +1654,34 @@ function logRoutesTable(routes, bundle) {
|
|
|
1616
1654
|
style: { compact: true }
|
|
1617
1655
|
});
|
|
1618
1656
|
for (const route of routes.list) {
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
if (route.page && (verb === "get" || verb === "head")) {
|
|
1633
|
-
entryType.push(kleur2.yellow("page"));
|
|
1634
|
-
if (verb === "get") {
|
|
1635
|
-
size = prettySize(computeRouteSize(route, bundle));
|
|
1636
|
-
}
|
|
1637
|
-
}
|
|
1638
|
-
const row = [verbCell];
|
|
1639
|
-
if (verbs.length === 1 || firstRow) {
|
|
1640
|
-
row.push({ rowSpan: verbs.length, content: prettyPath(path5.path) });
|
|
1641
|
-
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));
|
|
1642
1670
|
}
|
|
1643
|
-
row.push(entryType.join(" -> "));
|
|
1644
|
-
hasMiddleware && row.push(route.middleware.length || "");
|
|
1645
|
-
hasMeta && row.push(route.meta ? "\u2713" : "");
|
|
1646
|
-
row.push(size || "");
|
|
1647
|
-
table.push(row);
|
|
1648
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);
|
|
1649
1685
|
}
|
|
1650
1686
|
}
|
|
1651
1687
|
for (const [key, route] of Object.entries(routes.special).sort()) {
|
|
@@ -1701,17 +1737,20 @@ function prettySize([bytes, compBytes]) {
|
|
|
1701
1737
|
else str += kleur2.bold(kleur2.red(compSize));
|
|
1702
1738
|
return str;
|
|
1703
1739
|
}
|
|
1704
|
-
function prettyPath(
|
|
1705
|
-
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
|
+
);
|
|
1706
1745
|
}
|
|
1707
1746
|
|
|
1708
1747
|
// src/vite/utils/read-once-persisted-store.ts
|
|
1709
1748
|
import { promises as fs2 } from "fs";
|
|
1710
1749
|
import os from "os";
|
|
1711
|
-
import
|
|
1750
|
+
import path5 from "path";
|
|
1712
1751
|
var noop = () => {
|
|
1713
1752
|
};
|
|
1714
|
-
var tmpFile =
|
|
1753
|
+
var tmpFile = path5.join(os.tmpdir(), "marko-run-storage.json");
|
|
1715
1754
|
var values = /* @__PURE__ */ new Map();
|
|
1716
1755
|
var loadedFromDisk;
|
|
1717
1756
|
var ReadOncePersistedStore = class {
|
|
@@ -1753,17 +1792,17 @@ process.once("beforeExit", (code) => {
|
|
|
1753
1792
|
|
|
1754
1793
|
// src/vite/plugin.ts
|
|
1755
1794
|
var debug = createDebug("@marko/run");
|
|
1756
|
-
var __dirname =
|
|
1795
|
+
var __dirname = path6.dirname(fileURLToPath(import.meta.url));
|
|
1757
1796
|
var PLUGIN_NAME_PREFIX = "marko-run-vite";
|
|
1758
|
-
var POSIX_SEP = "/";
|
|
1759
|
-
var WINDOWS_SEP = "\\";
|
|
1760
1797
|
var CLIENT_OUT_DIR = "public";
|
|
1761
1798
|
var MIDDLEWARE_FILENAME = `${markoRunFilePrefix}middleware.js`;
|
|
1762
1799
|
var ROUTER_FILENAME = `${markoRunFilePrefix}router.js`;
|
|
1763
1800
|
var defaultPort = Number(process.env.PORT || 3e3);
|
|
1764
|
-
var normalizePath = path4.sep === WINDOWS_SEP ? (id) => id.replace(/\\/g, POSIX_SEP) : (id) => id;
|
|
1765
1801
|
function markoRun(opts = {}) {
|
|
1766
|
-
let
|
|
1802
|
+
let routesDir;
|
|
1803
|
+
let adapter;
|
|
1804
|
+
let trailingSlashes;
|
|
1805
|
+
const { ...markoVitePluginOptions } = opts;
|
|
1767
1806
|
let store;
|
|
1768
1807
|
let root;
|
|
1769
1808
|
let shouldEmptyOutDir = false;
|
|
@@ -1796,12 +1835,8 @@ function markoRun(opts = {}) {
|
|
|
1796
1835
|
root,
|
|
1797
1836
|
"{.tsconfig*,tsconfig*.json}"
|
|
1798
1837
|
)))) {
|
|
1799
|
-
const filepath =
|
|
1800
|
-
const data = await renderRouteTypeInfo(
|
|
1801
|
-
routes2,
|
|
1802
|
-
normalizePath(path4.relative(typesDir, resolvedRoutesDir)),
|
|
1803
|
-
adapter
|
|
1804
|
-
);
|
|
1838
|
+
const filepath = path6.join(typesDir, "routes.d.ts");
|
|
1839
|
+
const data = await renderRouteTypeInfo(routes2, typesDir, adapter);
|
|
1805
1840
|
if (data !== typesFile || !fs3.existsSync(filepath)) {
|
|
1806
1841
|
await ensureDir(typesDir);
|
|
1807
1842
|
await fs3.promises.writeFile(filepath, typesFile = data);
|
|
@@ -1812,20 +1847,25 @@ function markoRun(opts = {}) {
|
|
|
1812
1847
|
function buildVirtualFiles() {
|
|
1813
1848
|
return buildVirtualFilesResult ?? (buildVirtualFilesResult = (async () => {
|
|
1814
1849
|
virtualFiles.clear();
|
|
1815
|
-
routes = await buildRoutes(
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1850
|
+
routes = await buildRoutes(
|
|
1851
|
+
{
|
|
1852
|
+
walker: createFSWalker(resolvedRoutesDir)
|
|
1853
|
+
},
|
|
1854
|
+
entryFilesDir
|
|
1855
|
+
);
|
|
1819
1856
|
if (!routes.list.length) {
|
|
1820
1857
|
throw new Error("No routes generated");
|
|
1821
1858
|
}
|
|
1822
1859
|
for (const route of routes.list) {
|
|
1823
|
-
virtualFiles.set(
|
|
1860
|
+
virtualFiles.set(
|
|
1861
|
+
path6.posix.join(root, getRouteVirtualFileName(route)),
|
|
1862
|
+
""
|
|
1863
|
+
);
|
|
1824
1864
|
}
|
|
1825
1865
|
if (routes.middleware.length) {
|
|
1826
|
-
virtualFiles.set(
|
|
1866
|
+
virtualFiles.set(path6.posix.join(root, MIDDLEWARE_FILENAME), "");
|
|
1827
1867
|
}
|
|
1828
|
-
virtualFiles.set(
|
|
1868
|
+
virtualFiles.set(path6.posix.join(root, ROUTER_FILENAME), "");
|
|
1829
1869
|
return routes;
|
|
1830
1870
|
})());
|
|
1831
1871
|
}
|
|
@@ -1839,111 +1879,78 @@ function markoRun(opts = {}) {
|
|
|
1839
1879
|
fs3.rmSync(entryFilesDir, { recursive: true });
|
|
1840
1880
|
}
|
|
1841
1881
|
for (const route of routes2.list) {
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1882
|
+
if (route.handler) {
|
|
1883
|
+
const exports = await getExportsFromFile(
|
|
1884
|
+
context,
|
|
1885
|
+
route.handler.filePath
|
|
1886
|
+
);
|
|
1887
|
+
route.handler.verbs = [];
|
|
1846
1888
|
for (const name of exports) {
|
|
1847
1889
|
const verb = name.toLowerCase();
|
|
1848
1890
|
if (name === verb.toUpperCase() && httpVerbs.includes(verb)) {
|
|
1849
|
-
handler.verbs.push(verb);
|
|
1891
|
+
route.handler.verbs.push(verb);
|
|
1850
1892
|
}
|
|
1851
1893
|
}
|
|
1852
|
-
if (!handler.verbs.length) {
|
|
1894
|
+
if (!route.handler.verbs.length) {
|
|
1853
1895
|
context.warn(
|
|
1854
|
-
`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(", ")}`
|
|
1855
1897
|
);
|
|
1856
1898
|
}
|
|
1857
1899
|
}
|
|
1858
|
-
if (
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
path4.relative(routeFileDir, root)
|
|
1867
|
-
);
|
|
1868
|
-
fs3.mkdirSync(routeFileDir, { recursive: true });
|
|
1869
|
-
const pageNameIndex = page.name.indexOf("+page");
|
|
1870
|
-
const pageNamePrefix = pageNameIndex > 0 ? `${page.name.slice(0, pageNameIndex)}.` : "";
|
|
1871
|
-
fs3.writeFileSync(
|
|
1872
|
-
route.templateFilePath = path4.join(
|
|
1873
|
-
routeFileDir,
|
|
1874
|
-
pageNamePrefix + "route.marko"
|
|
1875
|
-
),
|
|
1876
|
-
renderRouteTemplate(
|
|
1877
|
-
route,
|
|
1878
|
-
(to) => path4.posix.join(routeFileRelativePathPosix, to)
|
|
1879
|
-
)
|
|
1880
|
-
);
|
|
1881
|
-
} else {
|
|
1882
|
-
route.templateFilePath = page.filePath;
|
|
1883
|
-
}
|
|
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
|
+
);
|
|
1884
1908
|
}
|
|
1885
1909
|
virtualFiles.set(
|
|
1886
|
-
|
|
1887
|
-
renderRouteEntry(route,
|
|
1910
|
+
path6.posix.join(root, getRouteVirtualFileName(route)),
|
|
1911
|
+
renderRouteEntry(route, root)
|
|
1888
1912
|
);
|
|
1889
1913
|
}
|
|
1890
1914
|
for (const route of Object.values(routes2.special)) {
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
)
|
|
1898
|
-
|
|
1899
|
-
const routeFileRelativePathPosix = normalizePath(
|
|
1900
|
-
path4.relative(routeFileDir, root)
|
|
1901
|
-
);
|
|
1902
|
-
fs3.mkdirSync(routeFileDir, { recursive: true });
|
|
1903
|
-
fs3.writeFileSync(
|
|
1904
|
-
route.templateFilePath = path4.join(
|
|
1905
|
-
routeFileDir,
|
|
1906
|
-
`route.${key}.marko`
|
|
1907
|
-
),
|
|
1908
|
-
renderRouteTemplate(
|
|
1909
|
-
route,
|
|
1910
|
-
(to) => path4.posix.join(routeFileRelativePathPosix, to)
|
|
1911
|
-
)
|
|
1912
|
-
);
|
|
1913
|
-
} else {
|
|
1914
|
-
route.templateFilePath = page.filePath;
|
|
1915
|
-
}
|
|
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
|
+
);
|
|
1916
1923
|
}
|
|
1917
1924
|
}
|
|
1918
1925
|
if (routes2.middleware.length) {
|
|
1919
1926
|
for (const middleware of routes2.middleware) {
|
|
1920
1927
|
if (!(await getExportsFromFile(context, middleware.filePath)).includes("default")) {
|
|
1921
1928
|
context.warn(
|
|
1922
|
-
`Did not find a default export in middleware '${
|
|
1929
|
+
`Did not find a default export in middleware '${path6.relative(root, middleware.filePath)}'`
|
|
1923
1930
|
);
|
|
1924
1931
|
}
|
|
1925
1932
|
}
|
|
1926
1933
|
virtualFiles.set(
|
|
1927
|
-
|
|
1928
|
-
renderMiddleware(routes2.middleware)
|
|
1934
|
+
path6.posix.join(root, MIDDLEWARE_FILENAME),
|
|
1935
|
+
renderMiddleware(routes2.middleware, root)
|
|
1929
1936
|
);
|
|
1930
1937
|
}
|
|
1931
1938
|
virtualFiles.set(
|
|
1932
|
-
|
|
1933
|
-
renderRouter(routes2,
|
|
1934
|
-
trailingSlashes
|
|
1939
|
+
path6.posix.join(root, ROUTER_FILENAME),
|
|
1940
|
+
renderRouter(routes2, root, {
|
|
1941
|
+
trailingSlashes
|
|
1935
1942
|
})
|
|
1936
1943
|
);
|
|
1937
1944
|
await writeTypesFile(routes2);
|
|
1938
1945
|
if (adapter == null ? void 0 : adapter.routesGenerated) {
|
|
1939
|
-
await adapter.routesGenerated(
|
|
1940
|
-
routes2,
|
|
1941
|
-
new Map(virtualFiles.entries()),
|
|
1942
|
-
{
|
|
1946
|
+
await adapter.routesGenerated({
|
|
1947
|
+
routes: routes2,
|
|
1948
|
+
virtualFiles: new Map(virtualFiles.entries()),
|
|
1949
|
+
meta: {
|
|
1943
1950
|
buildTime: times.routesBuild,
|
|
1944
1951
|
renderTime: times.routesRender
|
|
1945
1952
|
}
|
|
1946
|
-
);
|
|
1953
|
+
});
|
|
1947
1954
|
if (!isBuild) {
|
|
1948
1955
|
await ((_a = opts == null ? void 0 : opts.emitRoutes) == null ? void 0 : _a.call(opts, routes2.list));
|
|
1949
1956
|
}
|
|
@@ -1953,7 +1960,7 @@ function markoRun(opts = {}) {
|
|
|
1953
1960
|
throw err;
|
|
1954
1961
|
}
|
|
1955
1962
|
virtualFiles.set(
|
|
1956
|
-
|
|
1963
|
+
path6.posix.join(root, ROUTER_FILENAME),
|
|
1957
1964
|
`throw ${JSON.stringify(prepareError(err))}`
|
|
1958
1965
|
);
|
|
1959
1966
|
}
|
|
@@ -1990,27 +1997,28 @@ function markoRun(opts = {}) {
|
|
|
1990
1997
|
}
|
|
1991
1998
|
}
|
|
1992
1999
|
routesDir = opts.routesDir || "src/routes";
|
|
2000
|
+
trailingSlashes = opts.trailingSlashes || "RedirectWithout";
|
|
1993
2001
|
store = new ReadOncePersistedStore(
|
|
1994
2002
|
`vite-marko-run${opts.runtimeId ? `-${opts.runtimeId}` : ""}`
|
|
1995
2003
|
);
|
|
1996
2004
|
markoVitePluginOptions.runtimeId = opts.runtimeId;
|
|
1997
2005
|
markoVitePluginOptions.basePathVar = opts.basePathVar;
|
|
1998
|
-
resolvedRoutesDir =
|
|
1999
|
-
outputDir =
|
|
2000
|
-
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");
|
|
2001
2009
|
entryFilesDirPosix = normalizePath(entryFilesDir);
|
|
2002
2010
|
relativeEntryFilesDirPosix = normalizePath(
|
|
2003
|
-
|
|
2011
|
+
path6.relative(root, entryFilesDir)
|
|
2004
2012
|
);
|
|
2005
|
-
typesDir =
|
|
2006
|
-
devEntryFile =
|
|
2013
|
+
typesDir = path6.join(root, ".marko-run");
|
|
2014
|
+
devEntryFile = path6.join(root, "index.html");
|
|
2007
2015
|
devEntryFilePosix = normalizePath(devEntryFile);
|
|
2008
2016
|
let outDir = ((_e = config2.build) == null ? void 0 : _e.outDir) || "dist";
|
|
2009
2017
|
const assetsDir = ((_f = config2.build) == null ? void 0 : _f.assetsDir) || "assets";
|
|
2010
2018
|
let rollupOutputOptions = (_h = (_g = config2.build) == null ? void 0 : _g.rollupOptions) == null ? void 0 : _h.output;
|
|
2011
2019
|
if (isBuild) {
|
|
2012
2020
|
if (!isSSRBuild) {
|
|
2013
|
-
outDir =
|
|
2021
|
+
outDir = path6.join(outDir, CLIENT_OUT_DIR);
|
|
2014
2022
|
}
|
|
2015
2023
|
const defaultRollupOutputOptions = {
|
|
2016
2024
|
assetFileNames({ name }) {
|
|
@@ -2135,7 +2143,7 @@ function markoRun(opts = {}) {
|
|
|
2135
2143
|
devServer.watcher.on("all", async (type, filename) => {
|
|
2136
2144
|
seenErrors.clear();
|
|
2137
2145
|
const routableFileType = matchRoutableFile(
|
|
2138
|
-
|
|
2146
|
+
path6.parse(filename).base
|
|
2139
2147
|
);
|
|
2140
2148
|
if (filename.startsWith(resolvedRoutesDir) && routableFileType) {
|
|
2141
2149
|
if (type === "add" || type === "unlink" || type === "change" && (routableFileType === RoutableFileTypes.Handler || routableFileType === RoutableFileTypes.Middleware)) {
|
|
@@ -2185,19 +2193,19 @@ function markoRun(opts = {}) {
|
|
|
2185
2193
|
},
|
|
2186
2194
|
async resolveId(importee, importer) {
|
|
2187
2195
|
if (importee === "@marko/run/router") {
|
|
2188
|
-
return normalizePath(
|
|
2196
|
+
return normalizePath(path6.resolve(root, ROUTER_FILENAME));
|
|
2189
2197
|
} else if (importee.endsWith(".marko") && importee.includes(relativeEntryFilesDirPosix)) {
|
|
2190
2198
|
if (!importee.startsWith(root)) {
|
|
2191
|
-
importee =
|
|
2199
|
+
importee = path6.resolve(root, "." + importee);
|
|
2192
2200
|
}
|
|
2193
2201
|
return normalizePath(importee);
|
|
2194
2202
|
}
|
|
2195
2203
|
let virtualFilePath;
|
|
2196
2204
|
if (importee.startsWith(virtualFilePrefix)) {
|
|
2197
2205
|
virtualFilePath = importee.slice(virtualFilePrefix.length + 1);
|
|
2198
|
-
importee =
|
|
2206
|
+
importee = path6.resolve(root, virtualFilePath);
|
|
2199
2207
|
} else if (!isBuild && importer && (importer === devEntryFile || normalizePath(importer) === devEntryFilePosix) && importee.startsWith(`/${markoRunFilePrefix}`)) {
|
|
2200
|
-
importee =
|
|
2208
|
+
importee = path6.resolve(root, "." + importee);
|
|
2201
2209
|
}
|
|
2202
2210
|
importee = normalizePath(importee);
|
|
2203
2211
|
if (!buildVirtualFilesResult) {
|
|
@@ -2206,7 +2214,7 @@ function markoRun(opts = {}) {
|
|
|
2206
2214
|
if (virtualFiles.has(importee)) {
|
|
2207
2215
|
return importee;
|
|
2208
2216
|
} else if (virtualFilePath) {
|
|
2209
|
-
const filePath =
|
|
2217
|
+
const filePath = path6.resolve(__dirname, "..", virtualFilePath);
|
|
2210
2218
|
return await this.resolve(filePath, importer, {
|
|
2211
2219
|
skipSelf: true
|
|
2212
2220
|
});
|
|
@@ -2245,7 +2253,7 @@ function markoRun(opts = {}) {
|
|
|
2245
2253
|
const builtEntries = Object.values(bundle).reduce(
|
|
2246
2254
|
(acc, item) => {
|
|
2247
2255
|
if (item.type === "chunk" && item.isEntry) {
|
|
2248
|
-
acc.push(
|
|
2256
|
+
acc.push(path6.join(options.dir, item.fileName));
|
|
2249
2257
|
}
|
|
2250
2258
|
return acc;
|
|
2251
2259
|
},
|
|
@@ -2273,12 +2281,12 @@ function markoRun(opts = {}) {
|
|
|
2273
2281
|
fs3.rmSync(entryFilesDir, { recursive: true });
|
|
2274
2282
|
}
|
|
2275
2283
|
if ((adapter == null ? void 0 : adapter.buildEnd) && routes) {
|
|
2276
|
-
await adapter.buildEnd(
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
routeData.builtEntries,
|
|
2280
|
-
routeData.sourceEntries
|
|
2281
|
-
);
|
|
2284
|
+
await adapter.buildEnd({
|
|
2285
|
+
routes,
|
|
2286
|
+
config: resolvedConfig,
|
|
2287
|
+
builtEntries: routeData.builtEntries,
|
|
2288
|
+
sourceEntries: routeData.sourceEntries
|
|
2289
|
+
});
|
|
2282
2290
|
}
|
|
2283
2291
|
}
|
|
2284
2292
|
}
|
|
@@ -2310,11 +2318,11 @@ async function ensureDir(dir) {
|
|
|
2310
2318
|
}
|
|
2311
2319
|
async function getPackageData(dir) {
|
|
2312
2320
|
do {
|
|
2313
|
-
const pkgPath =
|
|
2321
|
+
const pkgPath = path6.join(dir, "package.json");
|
|
2314
2322
|
if (fs3.existsSync(pkgPath)) {
|
|
2315
2323
|
return JSON.parse(await fs3.promises.readFile(pkgPath, "utf-8"));
|
|
2316
2324
|
}
|
|
2317
|
-
} while (dir !== (dir =
|
|
2325
|
+
} while (dir !== (dir = path6.dirname(dir)));
|
|
2318
2326
|
return null;
|
|
2319
2327
|
}
|
|
2320
2328
|
async function resolveAdapter(root, options, log) {
|