@marko/run 0.6.6 → 0.7.1
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 +453 -410
- 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 +444 -416
- package/dist/vite/index.js +426 -395
- 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 +26 -9
- 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,14 +532,16 @@ 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--;
|
|
528
|
-
|
|
539
|
+
if (routes.list.length) {
|
|
540
|
+
writer.writeLines(`
|
|
529
541
|
return new Response(null, {
|
|
530
542
|
status: 404,
|
|
531
543
|
});`);
|
|
544
|
+
}
|
|
532
545
|
if (hasErrorPage) {
|
|
533
546
|
imports.writeLines(`
|
|
534
547
|
const page500ResponseInit = {
|
|
@@ -538,7 +551,7 @@ const page500ResponseInit = {
|
|
|
538
551
|
writer.writeBlockStart(`} catch (error) {`).writeBlockStart(
|
|
539
552
|
`if (context.request.headers.get('Accept')?.includes('text/html')) {`
|
|
540
553
|
).writeLines(
|
|
541
|
-
`return
|
|
554
|
+
`return context.render(page500, { error }, page500ResponseInit);`
|
|
542
555
|
).writeBlockEnd("}").writeLines("throw error;").writeBlockEnd("}");
|
|
543
556
|
}
|
|
544
557
|
writer.writeBlockEnd("}");
|
|
@@ -550,38 +563,40 @@ function renderFetch(writer, options) {
|
|
|
550
563
|
export async function fetch(request, platform) {
|
|
551
564
|
try {
|
|
552
565
|
const url = new URL(request.url);
|
|
553
|
-
|
|
566
|
+
const { pathname } = url;
|
|
567
|
+
const last = pathname.length - 1;
|
|
568
|
+
const hasTrailingSlash = last && pathname.charAt(last) === '/';
|
|
569
|
+
const normalizedPathname = hasTrailingSlash ? pathname.slice(0, last) : pathname;
|
|
570
|
+
const route = match_internal(request.method, normalizedPathname);`);
|
|
554
571
|
switch (options.trailingSlashes) {
|
|
555
572
|
case "RedirectWithout":
|
|
556
573
|
writer.write(`
|
|
557
|
-
if (
|
|
558
|
-
url.pathname =
|
|
574
|
+
if (route && hasTrailingSlash) {
|
|
575
|
+
url.pathname = normalizedPathname
|
|
559
576
|
return Response.redirect(url);
|
|
560
577
|
}`);
|
|
561
578
|
break;
|
|
562
579
|
case "RedirectWith":
|
|
563
580
|
writer.write(`
|
|
564
|
-
if (pathname !== '/' && !
|
|
565
|
-
url.pathname
|
|
581
|
+
if (route && pathname !== '/' && !hasTrailingSlash) {
|
|
582
|
+
url.pathname += '/';
|
|
566
583
|
return Response.redirect(url);
|
|
567
584
|
}`);
|
|
568
585
|
break;
|
|
569
586
|
case "RewriteWithout":
|
|
570
587
|
writer.write(`
|
|
571
|
-
if (
|
|
572
|
-
url.pathname =
|
|
588
|
+
if (route && hasTrailingSlash) {
|
|
589
|
+
url.pathname = normalizedPathname;
|
|
573
590
|
}`);
|
|
574
591
|
break;
|
|
575
592
|
case "RewriteWith":
|
|
576
593
|
writer.write(`
|
|
577
|
-
if (pathname !== '/' && !
|
|
578
|
-
url.pathname
|
|
594
|
+
if (route && pathname !== '/' && !hasTrailingSlash) {
|
|
595
|
+
url.pathname += '/';
|
|
579
596
|
}`);
|
|
580
597
|
break;
|
|
581
598
|
}
|
|
582
599
|
writer.write(`
|
|
583
|
-
|
|
584
|
-
const route = match(request.method, pathname);
|
|
585
600
|
return await invoke(route, request, platform, url);
|
|
586
601
|
} catch (error) {
|
|
587
602
|
if (import.meta.env.DEV) {
|
|
@@ -597,10 +612,9 @@ function writeRouterVerb(writer, trie, verb, level = 0, offset = 1) {
|
|
|
597
612
|
const { route, dynamic, catchAll } = trie;
|
|
598
613
|
let closeCount = 0;
|
|
599
614
|
if (level === 0) {
|
|
600
|
-
writer.writeLines(`const len = pathname.length;`);
|
|
601
615
|
if (route) {
|
|
602
616
|
writer.writeLines(
|
|
603
|
-
`if (len === 1) return ${renderMatch(verb, route, trie.path)}
|
|
617
|
+
`if (len === 1) return ${renderMatch(verb, route, trie.path)};`
|
|
604
618
|
);
|
|
605
619
|
} else if (trie.static || dynamic) {
|
|
606
620
|
writer.writeBlockStart(`if (len > 1) {`);
|
|
@@ -641,17 +655,15 @@ function writeRouterVerb(writer, trie, verb, level = 0, offset = 1) {
|
|
|
641
655
|
if (useSwitch) {
|
|
642
656
|
writer.writeBlockStart(`switch (${value}) {`);
|
|
643
657
|
}
|
|
644
|
-
for (const { key, path:
|
|
658
|
+
for (const { key, path: path7, route: route2 } of terminal) {
|
|
645
659
|
const decodedKey = decodeURIComponent(key);
|
|
646
660
|
if (useSwitch) {
|
|
647
661
|
writer.write(`case '${decodedKey}': `, true);
|
|
648
662
|
} else {
|
|
649
663
|
writer.write(`if (${value} === '${decodedKey}') `, true);
|
|
650
664
|
}
|
|
651
|
-
writer.write(
|
|
652
|
-
|
|
653
|
-
`
|
|
654
|
-
);
|
|
665
|
+
writer.write(`return ${renderMatch(verb, route2, path7)};
|
|
666
|
+
`);
|
|
655
667
|
}
|
|
656
668
|
if (useSwitch) {
|
|
657
669
|
writer.writeBlockEnd("}");
|
|
@@ -663,7 +675,7 @@ function writeRouterVerb(writer, trie, verb, level = 0, offset = 1) {
|
|
|
663
675
|
verb,
|
|
664
676
|
dynamic.route,
|
|
665
677
|
dynamic.path
|
|
666
|
-
)}
|
|
678
|
+
)};`
|
|
667
679
|
);
|
|
668
680
|
}
|
|
669
681
|
}
|
|
@@ -723,7 +735,7 @@ function writeRouterVerb(writer, trie, verb, level = 0, offset = 1) {
|
|
|
723
735
|
catchAll.route,
|
|
724
736
|
catchAll.path,
|
|
725
737
|
String(offset)
|
|
726
|
-
)}
|
|
738
|
+
)};`
|
|
727
739
|
);
|
|
728
740
|
} else if (level === 0) {
|
|
729
741
|
writer.writeLines("return null;");
|
|
@@ -752,43 +764,47 @@ function renderParams(params, pathIndex) {
|
|
|
752
764
|
}
|
|
753
765
|
return result ? result + " }" : "{}";
|
|
754
766
|
}
|
|
755
|
-
function renderMatch(verb, route,
|
|
767
|
+
function renderMatch(verb, route, path7, pathIndex) {
|
|
756
768
|
const handler = `${verb}${route.index}`;
|
|
757
|
-
const params =
|
|
769
|
+
const params = path7.params ? renderParams(path7.params, pathIndex) : "{}";
|
|
758
770
|
const meta = route.meta ? `meta${route.index}` : "{}";
|
|
759
|
-
|
|
760
|
-
return `{ handler: ${handler}, params: ${params}, meta: ${meta}, path: '${pathPattern}' }`;
|
|
771
|
+
return `{ handler: ${handler}, params: ${params}, meta: ${meta}, path: '${path7.path}' }`;
|
|
761
772
|
}
|
|
762
|
-
function renderMiddleware(middleware) {
|
|
773
|
+
function renderMiddleware(middleware, rootDir) {
|
|
763
774
|
const writer = createStringWriter();
|
|
764
775
|
writer.writeLines(
|
|
765
776
|
`// ${virtualFilePrefix}/${markoRunFilePrefix}middleware.js`
|
|
766
777
|
);
|
|
767
778
|
const imports = writer.branch("imports");
|
|
768
779
|
imports.writeLines(
|
|
769
|
-
`import { normalize } from
|
|
780
|
+
`import { normalize } from "${virtualFilePrefix}/runtime/internal";`
|
|
770
781
|
);
|
|
771
782
|
writer.writeLines("");
|
|
772
|
-
for (const { id,
|
|
783
|
+
for (const { id, filePath } of middleware) {
|
|
773
784
|
const importName = `middleware${id}`;
|
|
774
|
-
imports.writeLines(
|
|
785
|
+
imports.writeLines(
|
|
786
|
+
`import ${importName} from "${normalizedRelativePath(rootDir, filePath)}";`
|
|
787
|
+
);
|
|
775
788
|
writer.writeLines(`export const mware${id} = normalize(${importName});`);
|
|
776
789
|
}
|
|
777
790
|
imports.join();
|
|
778
791
|
return writer.end();
|
|
779
792
|
}
|
|
780
|
-
function stripTsExtension(
|
|
781
|
-
const index =
|
|
793
|
+
function stripTsExtension(path7) {
|
|
794
|
+
const index = path7.lastIndexOf(".");
|
|
782
795
|
if (index !== -1) {
|
|
783
|
-
const ext =
|
|
796
|
+
const ext = path7.slice(index + 1);
|
|
784
797
|
if (ext.toLowerCase() === "ts") {
|
|
785
|
-
return
|
|
798
|
+
return path7.slice(0, index);
|
|
786
799
|
}
|
|
787
800
|
}
|
|
788
|
-
return
|
|
801
|
+
return path7;
|
|
789
802
|
}
|
|
790
|
-
|
|
791
|
-
|
|
803
|
+
function decodePath(path7) {
|
|
804
|
+
return path7;
|
|
805
|
+
}
|
|
806
|
+
async function renderRouteTypeInfo(routes, outDir, adapter) {
|
|
807
|
+
var _a, _b, _c, _d;
|
|
792
808
|
const writer = createStringWriter();
|
|
793
809
|
writer.writeLines(
|
|
794
810
|
`/*
|
|
@@ -817,11 +833,31 @@ async function renderRouteTypeInfo(routes, pathPrefix = ".", adapter) {
|
|
|
817
833
|
const routeTypes = /* @__PURE__ */ new Map();
|
|
818
834
|
for (const route of routes.list) {
|
|
819
835
|
let routeType = "";
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
836
|
+
let routeDefinition = "";
|
|
837
|
+
if (route.page || route.handler) {
|
|
838
|
+
const verbs = [];
|
|
839
|
+
if (route.page || ((_b = (_a = route.handler) == null ? void 0 : _a.verbs) == null ? void 0 : _b.includes("get"))) {
|
|
840
|
+
verbs.push(`"get"`);
|
|
841
|
+
}
|
|
842
|
+
if ((_d = (_c = route.handler) == null ? void 0 : _c.verbs) == null ? void 0 : _d.includes("post")) {
|
|
843
|
+
verbs.push(`"post"`);
|
|
844
|
+
}
|
|
845
|
+
routeDefinition = `{ verb: ${verbs.join(" | ")};`;
|
|
846
|
+
if (route.meta) {
|
|
847
|
+
const metaPath = stripTsExtension(
|
|
848
|
+
normalizedRelativePath(outDir, route.meta.filePath)
|
|
849
|
+
);
|
|
850
|
+
let metaType = `typeof import("${metaPath}")`;
|
|
851
|
+
if (/\.(ts|js|mjs)$/.test(route.meta.name)) {
|
|
852
|
+
metaType += `["default"]`;
|
|
853
|
+
}
|
|
854
|
+
routeDefinition += ` meta: ${metaType};`;
|
|
855
|
+
}
|
|
856
|
+
routeDefinition += " }";
|
|
824
857
|
}
|
|
858
|
+
const pathType = `"${decodePath(route.path.path)}"`;
|
|
859
|
+
routeType += routeType ? " | " + pathType : pathType;
|
|
860
|
+
routesWriter.writeLines(`${pathType}: ${routeDefinition};`);
|
|
825
861
|
for (const file of [route.handler, route.page]) {
|
|
826
862
|
if (file) {
|
|
827
863
|
const existing = routeTypes.get(file);
|
|
@@ -854,31 +890,33 @@ async function renderRouteTypeInfo(routes, pathPrefix = ".", adapter) {
|
|
|
854
890
|
const pageWriter = writer.branch("page");
|
|
855
891
|
const layoutWriter = writer.branch("layout");
|
|
856
892
|
for (const [file, types] of routeTypes) {
|
|
857
|
-
const
|
|
893
|
+
const modulePath = stripTsExtension(
|
|
894
|
+
normalizedRelativePath(outDir, file.filePath)
|
|
895
|
+
);
|
|
858
896
|
const routeType = `Run.Routes[${types.join(" | ")}]`;
|
|
859
897
|
switch (file.type) {
|
|
860
898
|
case RoutableFileTypes.Handler:
|
|
861
|
-
writeModuleDeclaration(handlerWriter,
|
|
899
|
+
writeModuleDeclaration(handlerWriter, modulePath, routeType);
|
|
862
900
|
break;
|
|
863
901
|
case RoutableFileTypes.Middleware:
|
|
864
|
-
writeModuleDeclaration(middlewareWriter,
|
|
902
|
+
writeModuleDeclaration(middlewareWriter, modulePath, routeType);
|
|
865
903
|
break;
|
|
866
904
|
case RoutableFileTypes.Page:
|
|
867
|
-
writeModuleDeclaration(pageWriter,
|
|
905
|
+
writeModuleDeclaration(pageWriter, modulePath, routeType);
|
|
868
906
|
break;
|
|
869
907
|
case RoutableFileTypes.Layout:
|
|
870
908
|
writeModuleDeclaration(
|
|
871
909
|
layoutWriter,
|
|
872
|
-
|
|
910
|
+
modulePath,
|
|
873
911
|
routeType,
|
|
874
912
|
`
|
|
875
|
-
export interface Input extends Run.LayoutInput<typeof import(
|
|
913
|
+
export interface Input extends Run.LayoutInput<typeof import("${modulePath}")> {}`
|
|
876
914
|
);
|
|
877
915
|
break;
|
|
878
916
|
case RoutableFileTypes.Error:
|
|
879
917
|
writeModuleDeclaration(
|
|
880
918
|
writer,
|
|
881
|
-
|
|
919
|
+
modulePath,
|
|
882
920
|
"globalThis.MarkoRun.Route",
|
|
883
921
|
`
|
|
884
922
|
export interface Input {
|
|
@@ -887,7 +925,7 @@ async function renderRouteTypeInfo(routes, pathPrefix = ".", adapter) {
|
|
|
887
925
|
);
|
|
888
926
|
break;
|
|
889
927
|
case RoutableFileTypes.NotFound:
|
|
890
|
-
writeModuleDeclaration(writer,
|
|
928
|
+
writeModuleDeclaration(writer, modulePath, "Run.Route");
|
|
891
929
|
break;
|
|
892
930
|
}
|
|
893
931
|
}
|
|
@@ -895,40 +933,15 @@ async function renderRouteTypeInfo(routes, pathPrefix = ".", adapter) {
|
|
|
895
933
|
middlewareWriter.join();
|
|
896
934
|
pageWriter.join();
|
|
897
935
|
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
936
|
return writer.end();
|
|
924
937
|
}
|
|
925
|
-
function writeModuleDeclaration(writer,
|
|
926
|
-
writer.writeLines("").write(`declare module "${
|
|
938
|
+
function writeModuleDeclaration(writer, name, routeType, moduleTypes) {
|
|
939
|
+
writer.writeLines("").write(`declare module "${name}" {`);
|
|
927
940
|
if (moduleTypes) {
|
|
928
941
|
writer.write(moduleTypes);
|
|
929
942
|
}
|
|
930
943
|
if (routeType) {
|
|
931
|
-
const isMarko =
|
|
944
|
+
const isMarko = name.endsWith(".marko");
|
|
932
945
|
writer.write(`
|
|
933
946
|
namespace MarkoRun {
|
|
934
947
|
export { NotHandled, NotMatched, GetPaths, PostPaths, GetablePath, GetableHref, PostablePath, PostableHref, Platform };
|
|
@@ -942,21 +955,15 @@ function writeModuleDeclaration(writer, path5, routeType, moduleTypes) {
|
|
|
942
955
|
writer.writeLines(`
|
|
943
956
|
}`);
|
|
944
957
|
}
|
|
945
|
-
function pathToURLPatternString(path5) {
|
|
946
|
-
return path5.replace(/\/\$(\$?)([^/]*)/g, (_, catchAll, name) => {
|
|
947
|
-
name = decodeURIComponent(name);
|
|
948
|
-
return catchAll ? `/:${name || "rest"}*` : `/:${name}`;
|
|
949
|
-
});
|
|
950
|
-
}
|
|
951
958
|
function createRouteTrie(routes) {
|
|
952
959
|
const root = {
|
|
953
960
|
key: ""
|
|
954
961
|
};
|
|
955
|
-
function insert(
|
|
962
|
+
function insert(path7, route) {
|
|
956
963
|
let node = root;
|
|
957
|
-
for (const segment of
|
|
964
|
+
for (const segment of path7.segments) {
|
|
958
965
|
if (segment === "$$") {
|
|
959
|
-
node.catchAll ?? (node.catchAll = { route, path:
|
|
966
|
+
node.catchAll ?? (node.catchAll = { route, path: path7 });
|
|
960
967
|
return;
|
|
961
968
|
} else if (segment === "$") {
|
|
962
969
|
node = node.dynamic ?? (node.dynamic = {
|
|
@@ -974,17 +981,18 @@ function createRouteTrie(routes) {
|
|
|
974
981
|
node = next;
|
|
975
982
|
}
|
|
976
983
|
}
|
|
977
|
-
node.path ?? (node.path =
|
|
984
|
+
node.path ?? (node.path = path7);
|
|
978
985
|
node.route ?? (node.route = route);
|
|
979
986
|
}
|
|
980
987
|
for (const route of routes) {
|
|
981
|
-
|
|
982
|
-
insert(path5, route);
|
|
983
|
-
}
|
|
988
|
+
insert(route.path, route);
|
|
984
989
|
}
|
|
985
990
|
return root;
|
|
986
991
|
}
|
|
987
992
|
|
|
993
|
+
// src/vite/routes/builder.ts
|
|
994
|
+
import path3 from "path";
|
|
995
|
+
|
|
988
996
|
// src/vite/routes/parse.ts
|
|
989
997
|
function parseFlatRoute(pattern) {
|
|
990
998
|
if (!pattern) throw new Error("Empty pattern");
|
|
@@ -999,53 +1007,72 @@ function parseFlatRoute(pattern) {
|
|
|
999
1007
|
]);
|
|
1000
1008
|
function parse2(basePaths, group) {
|
|
1001
1009
|
const pathMap = /* @__PURE__ */ new Map();
|
|
1002
|
-
const delimiters = group ? ").," : "
|
|
1010
|
+
const delimiters = group ? "`).," : "`.,";
|
|
1003
1011
|
let charCode;
|
|
1004
1012
|
let segmentStart = i;
|
|
1005
1013
|
let type;
|
|
1006
1014
|
let current;
|
|
1015
|
+
let escaped = "";
|
|
1016
|
+
let escapeStart = 0;
|
|
1007
1017
|
do {
|
|
1008
1018
|
charCode = pattern.charCodeAt(i);
|
|
1009
|
-
if (charCode ===
|
|
1019
|
+
if (charCode === 96 /* Escape */) {
|
|
1020
|
+
if (escapeStart) {
|
|
1021
|
+
escaped += pattern.slice(segmentStart, escapeStart - 1) + pattern.slice(escapeStart, i);
|
|
1022
|
+
escapeStart = 0;
|
|
1023
|
+
segmentStart = ++i;
|
|
1024
|
+
} else {
|
|
1025
|
+
escapeStart = i + 1;
|
|
1026
|
+
i = pattern.indexOf("`", escapeStart);
|
|
1027
|
+
if (i < 0) break;
|
|
1028
|
+
}
|
|
1029
|
+
} else if (charCode === 41 /* GroupEnd */ && group) {
|
|
1010
1030
|
break;
|
|
1011
|
-
} else if (charCode === 44) {
|
|
1031
|
+
} else if (charCode === 44 /* Alternate */) {
|
|
1012
1032
|
if (!current) {
|
|
1013
1033
|
segmentEnd(
|
|
1014
|
-
basePaths.map((
|
|
1015
|
-
...
|
|
1016
|
-
segments:
|
|
1034
|
+
basePaths.map((path7) => ({
|
|
1035
|
+
...path7,
|
|
1036
|
+
segments: path7.segments.slice()
|
|
1017
1037
|
})),
|
|
1018
|
-
|
|
1038
|
+
escaped,
|
|
1019
1039
|
"_",
|
|
1020
1040
|
pathMap
|
|
1021
1041
|
);
|
|
1022
1042
|
} else {
|
|
1023
|
-
segmentEnd(
|
|
1043
|
+
segmentEnd(
|
|
1044
|
+
current,
|
|
1045
|
+
escaped + pattern.slice(segmentStart, i),
|
|
1046
|
+
type,
|
|
1047
|
+
pathMap
|
|
1048
|
+
);
|
|
1024
1049
|
}
|
|
1025
1050
|
current = void 0;
|
|
1026
1051
|
type = void 0;
|
|
1052
|
+
escaped = "";
|
|
1027
1053
|
segmentStart = ++i;
|
|
1028
|
-
} else if (charCode === 46) {
|
|
1054
|
+
} else if (charCode === 46 /* Directory */) {
|
|
1029
1055
|
if (current) {
|
|
1030
|
-
segmentEnd(current, pattern.slice(segmentStart, i), type);
|
|
1056
|
+
segmentEnd(current, escaped + pattern.slice(segmentStart, i), type);
|
|
1031
1057
|
}
|
|
1032
1058
|
type = void 0;
|
|
1059
|
+
escaped = "";
|
|
1033
1060
|
segmentStart = ++i;
|
|
1034
|
-
} else if (charCode === 40) {
|
|
1061
|
+
} else if (charCode === 40 /* GroupStart */) {
|
|
1035
1062
|
const groupPaths = parse2(current || basePaths, ++i);
|
|
1036
1063
|
if (groupPaths.length) {
|
|
1037
1064
|
current = groupPaths;
|
|
1038
1065
|
}
|
|
1039
1066
|
segmentStart = ++i;
|
|
1040
1067
|
} else {
|
|
1041
|
-
if (charCode === 95) {
|
|
1068
|
+
if (charCode === 95 /* Pathless */) {
|
|
1042
1069
|
type = "_";
|
|
1043
|
-
} else if (charCode === 36) {
|
|
1070
|
+
} else if (charCode === 36 /* Dynamic */) {
|
|
1044
1071
|
type = pattern.charCodeAt(i + 1) === 36 ? "$$" : "$";
|
|
1045
1072
|
}
|
|
1046
|
-
current ?? (current = basePaths.map((
|
|
1047
|
-
...
|
|
1048
|
-
segments:
|
|
1073
|
+
current ?? (current = basePaths.map((path7) => ({
|
|
1074
|
+
...path7,
|
|
1075
|
+
segments: path7.segments.slice()
|
|
1049
1076
|
})));
|
|
1050
1077
|
i = len;
|
|
1051
1078
|
for (const char of delimiters) {
|
|
@@ -1056,7 +1083,12 @@ function parseFlatRoute(pattern) {
|
|
|
1056
1083
|
}
|
|
1057
1084
|
}
|
|
1058
1085
|
} while (i < len);
|
|
1059
|
-
if (
|
|
1086
|
+
if (escapeStart) {
|
|
1087
|
+
throw new Error(
|
|
1088
|
+
`Invalid route pattern: unclosed escape '${pattern.slice(escapeStart)}' in '${pattern}'`
|
|
1089
|
+
);
|
|
1090
|
+
}
|
|
1091
|
+
if (group && charCode !== 41 /* GroupEnd */) {
|
|
1060
1092
|
throw new Error(
|
|
1061
1093
|
`Invalid route pattern: group was not closed '${pattern.slice(
|
|
1062
1094
|
group
|
|
@@ -1065,16 +1097,21 @@ function parseFlatRoute(pattern) {
|
|
|
1065
1097
|
}
|
|
1066
1098
|
if (!current) {
|
|
1067
1099
|
segmentEnd(
|
|
1068
|
-
basePaths.map((
|
|
1069
|
-
...
|
|
1070
|
-
segments:
|
|
1100
|
+
basePaths.map((path7) => ({
|
|
1101
|
+
...path7,
|
|
1102
|
+
segments: path7.segments.slice()
|
|
1071
1103
|
})),
|
|
1072
|
-
|
|
1073
|
-
|
|
1104
|
+
escaped,
|
|
1105
|
+
void 0,
|
|
1074
1106
|
pathMap
|
|
1075
1107
|
);
|
|
1076
1108
|
} else {
|
|
1077
|
-
segmentEnd(
|
|
1109
|
+
segmentEnd(
|
|
1110
|
+
current,
|
|
1111
|
+
escaped + pattern.slice(segmentStart, i),
|
|
1112
|
+
type,
|
|
1113
|
+
pathMap
|
|
1114
|
+
);
|
|
1078
1115
|
}
|
|
1079
1116
|
return [...pathMap.values()];
|
|
1080
1117
|
}
|
|
@@ -1083,17 +1120,17 @@ function parseFlatRoute(pattern) {
|
|
|
1083
1120
|
if (raw) {
|
|
1084
1121
|
segment = {
|
|
1085
1122
|
raw,
|
|
1086
|
-
name: raw,
|
|
1123
|
+
name: normalizeSegment(raw),
|
|
1087
1124
|
type
|
|
1088
1125
|
};
|
|
1089
1126
|
if (type === "$" || type === "$$") {
|
|
1090
1127
|
segment.name = type;
|
|
1091
|
-
segment.param = raw.slice(type.length);
|
|
1128
|
+
segment.param = normalizeParam(raw.slice(type.length));
|
|
1092
1129
|
}
|
|
1093
1130
|
}
|
|
1094
|
-
for (const
|
|
1131
|
+
for (const path7 of paths) {
|
|
1095
1132
|
if (segment) {
|
|
1096
|
-
if (
|
|
1133
|
+
if (path7.isCatchall) {
|
|
1097
1134
|
throw new Error(
|
|
1098
1135
|
`Invalid route pattern: nested segments are not allowed after a catch-all parameter. Found '.' following '${pattern.slice(
|
|
1099
1136
|
0,
|
|
@@ -1101,26 +1138,36 @@ function parseFlatRoute(pattern) {
|
|
|
1101
1138
|
)}' in '${pattern}'.`
|
|
1102
1139
|
);
|
|
1103
1140
|
}
|
|
1104
|
-
|
|
1105
|
-
|
|
1141
|
+
path7.segments.push(segment);
|
|
1142
|
+
path7.id += path7.id === "/" ? segment.name : `/${segment.name}`;
|
|
1106
1143
|
if (type === "$$") {
|
|
1107
|
-
|
|
1144
|
+
path7.isCatchall = true;
|
|
1108
1145
|
}
|
|
1109
1146
|
}
|
|
1110
1147
|
if (map) {
|
|
1111
|
-
if (map.has(
|
|
1112
|
-
const existing = map.get(
|
|
1148
|
+
if (map.has(path7.id)) {
|
|
1149
|
+
const existing = map.get(path7.id);
|
|
1113
1150
|
const existingExpansion = existing.segments.map((s) => s.raw).join(".");
|
|
1114
|
-
const currentExpansion =
|
|
1151
|
+
const currentExpansion = path7.segments.map((s) => s.raw).join(".");
|
|
1115
1152
|
throw new Error(
|
|
1116
|
-
`Invalid route pattern: route '${
|
|
1153
|
+
`Invalid route pattern: route '${path7.id}' is ambiguous. Expansion '${currentExpansion}' collides with '${existingExpansion}' in '${pattern}'.`
|
|
1117
1154
|
);
|
|
1118
1155
|
}
|
|
1119
|
-
map.set(
|
|
1156
|
+
map.set(path7.id, path7);
|
|
1120
1157
|
}
|
|
1121
1158
|
}
|
|
1122
1159
|
}
|
|
1123
1160
|
}
|
|
1161
|
+
function normalizeParam(segment) {
|
|
1162
|
+
const normalized = normalizeSegment(segment);
|
|
1163
|
+
return /^\$/.test(normalized) ? `\`${normalized}\`` : normalized;
|
|
1164
|
+
}
|
|
1165
|
+
function normalizeSegment(segment) {
|
|
1166
|
+
return decodeURIComponent(segment).replace(
|
|
1167
|
+
/[/?#]/g,
|
|
1168
|
+
(char) => "%" + char.charCodeAt(0).toString(16)
|
|
1169
|
+
);
|
|
1170
|
+
}
|
|
1124
1171
|
|
|
1125
1172
|
// src/vite/routes/vdir.ts
|
|
1126
1173
|
var _dirs, _pathlessDirs;
|
|
@@ -1131,14 +1178,12 @@ var _VDir = class _VDir {
|
|
|
1131
1178
|
__publicField(this, "parent");
|
|
1132
1179
|
__publicField(this, "source");
|
|
1133
1180
|
__publicField(this, "path");
|
|
1134
|
-
__publicField(this, "fullPath");
|
|
1135
1181
|
__publicField(this, "segment");
|
|
1136
1182
|
__publicField(this, "files");
|
|
1137
1183
|
if (!parent || !segment) {
|
|
1138
1184
|
this.parent = null;
|
|
1139
1185
|
this.source = null;
|
|
1140
1186
|
this.path = "/";
|
|
1141
|
-
this.fullPath = "/";
|
|
1142
1187
|
this.segment = {
|
|
1143
1188
|
raw: "",
|
|
1144
1189
|
name: ""
|
|
@@ -1146,12 +1191,8 @@ var _VDir = class _VDir {
|
|
|
1146
1191
|
} else {
|
|
1147
1192
|
this.parent = parent;
|
|
1148
1193
|
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
1194
|
this.segment = segment;
|
|
1195
|
+
this.path = parent.path + (parent.path === "/" ? "" : "/") + segment.name;
|
|
1155
1196
|
}
|
|
1156
1197
|
}
|
|
1157
1198
|
get pathInfo() {
|
|
@@ -1164,17 +1205,18 @@ var _VDir = class _VDir {
|
|
|
1164
1205
|
for (const { segment } of this) {
|
|
1165
1206
|
const { type, name, param } = segment;
|
|
1166
1207
|
if (name && type !== "_") {
|
|
1167
|
-
value.id += sep +
|
|
1208
|
+
value.id += sep + name;
|
|
1168
1209
|
value.path += sep + name;
|
|
1169
1210
|
value.isEnd = type === "$$";
|
|
1170
1211
|
if (param) {
|
|
1171
|
-
|
|
1212
|
+
const unescapedParam = param.charAt(0) === "`" ? param.slice(1, -1) : param;
|
|
1172
1213
|
const index = type === "$$" ? null : value.segments.length;
|
|
1173
1214
|
if (!value.params) {
|
|
1174
|
-
value.params = { [
|
|
1215
|
+
value.params = { [unescapedParam]: index };
|
|
1175
1216
|
} else if (!(param in value.params)) {
|
|
1176
|
-
value.params[
|
|
1217
|
+
value.params[unescapedParam] = index;
|
|
1177
1218
|
}
|
|
1219
|
+
value.path += param;
|
|
1178
1220
|
}
|
|
1179
1221
|
value.segments.push(name);
|
|
1180
1222
|
sep = "/";
|
|
@@ -1186,11 +1228,11 @@ var _VDir = class _VDir {
|
|
|
1186
1228
|
});
|
|
1187
1229
|
return value;
|
|
1188
1230
|
}
|
|
1189
|
-
addDir(
|
|
1231
|
+
addDir(path7, segment) {
|
|
1190
1232
|
const map = segment.type === "_" ? __privateGet(this, _pathlessDirs) ?? __privateSet(this, _pathlessDirs, /* @__PURE__ */ new Map()) : __privateGet(this, _dirs) ?? __privateSet(this, _dirs, /* @__PURE__ */ new Map());
|
|
1191
1233
|
const key = segment.type === "$" ? segment.raw : segment.name;
|
|
1192
1234
|
if (!map.has(key)) {
|
|
1193
|
-
const dir = new _VDir(this, segment,
|
|
1235
|
+
const dir = new _VDir(this, segment, path7);
|
|
1194
1236
|
map.set(key, dir);
|
|
1195
1237
|
return dir;
|
|
1196
1238
|
}
|
|
@@ -1206,15 +1248,15 @@ var _VDir = class _VDir {
|
|
|
1206
1248
|
const existing = this.files.get(file.type);
|
|
1207
1249
|
if (existing !== file) {
|
|
1208
1250
|
throw new Error(
|
|
1209
|
-
`Duplicate file type
|
|
1251
|
+
`Duplicate file type ${file.type} added at path ${this.path}. File ${file.filePath} collides with ${existing.filePath}.`
|
|
1210
1252
|
);
|
|
1211
1253
|
} else if (file.type === RoutableFileTypes.Page || file.type === RoutableFileTypes.Handler) {
|
|
1212
1254
|
throw new Error(
|
|
1213
|
-
`Ambiguous path definition: route
|
|
1255
|
+
`Ambiguous path definition: route ${this.path} is defined multiple times by ${file.filePath}`
|
|
1214
1256
|
);
|
|
1215
1257
|
}
|
|
1216
1258
|
throw new Error(
|
|
1217
|
-
`Ambiguous path definition: file
|
|
1259
|
+
`Ambiguous path definition: file ${this.path} is included multiple times by ${file.filePath}`
|
|
1218
1260
|
);
|
|
1219
1261
|
}
|
|
1220
1262
|
}
|
|
@@ -1236,10 +1278,10 @@ var _VDir = class _VDir {
|
|
|
1236
1278
|
const dirs = [];
|
|
1237
1279
|
const unique = /* @__PURE__ */ new Map();
|
|
1238
1280
|
for (const root of roots) {
|
|
1239
|
-
for (const
|
|
1281
|
+
for (const path7 of paths) {
|
|
1240
1282
|
let dir = root;
|
|
1241
|
-
for (const segment of
|
|
1242
|
-
dir = dir.addDir(
|
|
1283
|
+
for (const segment of path7.segments) {
|
|
1284
|
+
dir = dir.addDir(path7, segment);
|
|
1243
1285
|
}
|
|
1244
1286
|
const existing = unique.get(dir.path);
|
|
1245
1287
|
if (existing) {
|
|
@@ -1252,7 +1294,7 @@ var _VDir = class _VDir {
|
|
|
1252
1294
|
}
|
|
1253
1295
|
}
|
|
1254
1296
|
throw new Error(
|
|
1255
|
-
`Ambiguous directory structure:
|
|
1297
|
+
`Ambiguous directory structure: ${sourcePath}${path7.source} defines ${dir.path} multiple times.`
|
|
1256
1298
|
);
|
|
1257
1299
|
} else {
|
|
1258
1300
|
unique.set(dir.path, dir);
|
|
@@ -1278,13 +1320,11 @@ function matchRoutableFile(filename) {
|
|
|
1278
1320
|
const match = filename.match(routeableFileRegex);
|
|
1279
1321
|
return match && (match[1] || match[3]).toLowerCase();
|
|
1280
1322
|
}
|
|
1281
|
-
function
|
|
1282
|
-
return type === RoutableFileTypes.NotFound || type === RoutableFileTypes.Error;
|
|
1283
|
-
}
|
|
1284
|
-
async function buildRoutes(sources) {
|
|
1323
|
+
async function buildRoutes(sources, outDir) {
|
|
1285
1324
|
const uniqueRoutes = /* @__PURE__ */ new Map();
|
|
1286
1325
|
const routes = [];
|
|
1287
1326
|
const special = {};
|
|
1327
|
+
const seenKeys = /* @__PURE__ */ new Map();
|
|
1288
1328
|
const middlewares = /* @__PURE__ */ new Set();
|
|
1289
1329
|
const unusedFiles = /* @__PURE__ */ new Set();
|
|
1290
1330
|
const currentLayouts = /* @__PURE__ */ new Set();
|
|
@@ -1292,13 +1332,13 @@ async function buildRoutes(sources) {
|
|
|
1292
1332
|
const root = new VDir();
|
|
1293
1333
|
const dirStack = [];
|
|
1294
1334
|
let basePath;
|
|
1295
|
-
let importPrefix;
|
|
1296
1335
|
let activeDirs;
|
|
1297
1336
|
let isBaseDir;
|
|
1298
1337
|
let nextFileId = 1;
|
|
1299
1338
|
let nextRouteIndex = 1;
|
|
1300
1339
|
const walkOptions = {
|
|
1301
|
-
onEnter(
|
|
1340
|
+
onEnter(dir) {
|
|
1341
|
+
let { name } = dir;
|
|
1302
1342
|
const prevDirStackLength = dirStack.length;
|
|
1303
1343
|
if (isBaseDir) {
|
|
1304
1344
|
isBaseDir = false;
|
|
@@ -1317,15 +1357,16 @@ async function buildRoutes(sources) {
|
|
|
1317
1357
|
dirStack.length = prevDirStackLength;
|
|
1318
1358
|
};
|
|
1319
1359
|
},
|
|
1320
|
-
onFile(
|
|
1360
|
+
onFile(file) {
|
|
1361
|
+
const { name } = file;
|
|
1321
1362
|
const match = name.match(routeableFileRegex);
|
|
1322
1363
|
if (!match) {
|
|
1323
1364
|
return;
|
|
1324
1365
|
}
|
|
1325
1366
|
const type = (match[1] || match[3]).toLowerCase();
|
|
1326
|
-
if (dirStack.length &&
|
|
1367
|
+
if (dirStack.length && (type === RoutableFileTypes.NotFound || type === RoutableFileTypes.Error)) {
|
|
1327
1368
|
console.warn(
|
|
1328
|
-
`Special pages '${RoutableFileTypes.NotFound}' and '${RoutableFileTypes.Error}' are only considered in the root directory - ignoring ${
|
|
1369
|
+
`Special pages '${RoutableFileTypes.NotFound}' and '${RoutableFileTypes.Error}' are only considered in the root directory - ignoring ${file.path}`
|
|
1329
1370
|
);
|
|
1330
1371
|
return;
|
|
1331
1372
|
}
|
|
@@ -1334,19 +1375,15 @@ async function buildRoutes(sources) {
|
|
|
1334
1375
|
const paths = parseFlatRoute(name.slice(0, match.index));
|
|
1335
1376
|
dirs = VDir.addPaths(activeDirs, paths);
|
|
1336
1377
|
}
|
|
1337
|
-
const
|
|
1338
|
-
const relativePath = dirPath ? `${dirPath}/${name}` : name;
|
|
1339
|
-
const file = {
|
|
1378
|
+
const routableFile = {
|
|
1340
1379
|
id: String(nextFileId++),
|
|
1341
1380
|
name,
|
|
1342
1381
|
type,
|
|
1343
|
-
filePath:
|
|
1344
|
-
relativePath,
|
|
1345
|
-
importPath: `${importPrefix}/${relativePath}`,
|
|
1382
|
+
filePath: file.path,
|
|
1346
1383
|
verbs: type === RoutableFileTypes.Page ? ["get", "head"] : void 0
|
|
1347
1384
|
};
|
|
1348
1385
|
for (const dir of dirs) {
|
|
1349
|
-
dir.addFile(
|
|
1386
|
+
dir.addFile(routableFile);
|
|
1350
1387
|
}
|
|
1351
1388
|
}
|
|
1352
1389
|
};
|
|
@@ -1354,7 +1391,6 @@ async function buildRoutes(sources) {
|
|
|
1354
1391
|
sources = [sources];
|
|
1355
1392
|
}
|
|
1356
1393
|
for (const source of sources) {
|
|
1357
|
-
importPrefix = source.importPrefix ? source.importPrefix.replace(/^\/+|\/+$/g, "") : "";
|
|
1358
1394
|
basePath = source.basePath || "";
|
|
1359
1395
|
activeDirs = [root];
|
|
1360
1396
|
isBaseDir = true;
|
|
@@ -1374,7 +1410,8 @@ async function buildRoutes(sources) {
|
|
|
1374
1410
|
layout = dir.files.get(RoutableFileTypes.Layout);
|
|
1375
1411
|
const handler = dir.files.get(RoutableFileTypes.Handler);
|
|
1376
1412
|
const page = dir.files.get(RoutableFileTypes.Page);
|
|
1377
|
-
|
|
1413
|
+
const pathInfo = dir.pathInfo;
|
|
1414
|
+
let layoutsUsed = false;
|
|
1378
1415
|
if (middleware) {
|
|
1379
1416
|
if (currentMiddleware.has(middleware)) {
|
|
1380
1417
|
middleware = void 0;
|
|
@@ -1391,64 +1428,64 @@ async function buildRoutes(sources) {
|
|
|
1391
1428
|
unusedFiles.add(layout);
|
|
1392
1429
|
}
|
|
1393
1430
|
}
|
|
1431
|
+
if (dir === root) {
|
|
1432
|
+
for (const [type, file] of dir.files) {
|
|
1433
|
+
if (type === RoutableFileTypes.NotFound || type === RoutableFileTypes.Error) {
|
|
1434
|
+
special[type] = {
|
|
1435
|
+
index: nextRouteIndex++,
|
|
1436
|
+
key: type,
|
|
1437
|
+
path: dir.pathInfo,
|
|
1438
|
+
middleware: [],
|
|
1439
|
+
layouts: [...currentLayouts],
|
|
1440
|
+
page: file,
|
|
1441
|
+
templateFilePath: currentLayouts.size ? path3.join(outDir, `${type}.marko`) : void 0
|
|
1442
|
+
};
|
|
1443
|
+
layoutsUsed = true;
|
|
1444
|
+
}
|
|
1445
|
+
}
|
|
1446
|
+
}
|
|
1394
1447
|
if (page || handler) {
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
const existing = uniqueRoutes.get(path5.id);
|
|
1448
|
+
if (uniqueRoutes.has(pathInfo.id)) {
|
|
1449
|
+
const existing = uniqueRoutes.get(pathInfo.id);
|
|
1398
1450
|
const route = routes[existing.index];
|
|
1399
1451
|
const existingFiles = [route.handler, route.page].filter(Boolean).map((f) => f.filePath);
|
|
1400
1452
|
const currentFiles = [handler, page].filter(Boolean).map((f) => f.filePath);
|
|
1401
|
-
throw new Error(
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1453
|
+
throw new Error(
|
|
1454
|
+
`Duplicate routes for path ${pathInfo.id} were defined. A route established by: "${existingFiles.join(" and ")}" collides with "${currentFiles.join(" and ")}"`
|
|
1455
|
+
);
|
|
1456
|
+
}
|
|
1457
|
+
uniqueRoutes.set(pathInfo.id, { dir, index: routes.length });
|
|
1458
|
+
let key = pathInfo.segments.map(replaceInvalidFilenameChars).concat("route").join("/");
|
|
1459
|
+
const keyCount = (seenKeys.get(key) || 0) + 1;
|
|
1460
|
+
seenKeys.set(key, keyCount);
|
|
1461
|
+
if (keyCount > 1) {
|
|
1462
|
+
key += keyCount;
|
|
1406
1463
|
}
|
|
1407
|
-
uniqueRoutes.set(path5.id, { dir, index: routes.length });
|
|
1408
1464
|
routes.push({
|
|
1409
1465
|
index: nextRouteIndex++,
|
|
1410
|
-
key
|
|
1411
|
-
|
|
1466
|
+
key,
|
|
1467
|
+
path: pathInfo,
|
|
1412
1468
|
middleware: [...currentMiddleware],
|
|
1413
1469
|
layouts: page ? [...currentLayouts] : [],
|
|
1414
1470
|
meta: dir.files.get(RoutableFileTypes.Meta),
|
|
1415
1471
|
page,
|
|
1416
1472
|
handler,
|
|
1417
|
-
|
|
1473
|
+
templateFilePath: page && currentLayouts.size ? path3.join(outDir, key + ".marko") : void 0
|
|
1418
1474
|
});
|
|
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) {
|
|
1475
|
+
layoutsUsed = !!page;
|
|
1437
1476
|
for (const middleware2 of currentMiddleware) {
|
|
1438
1477
|
middlewares.add(middleware2);
|
|
1439
1478
|
unusedFiles.delete(middleware2);
|
|
1440
1479
|
}
|
|
1441
1480
|
}
|
|
1442
|
-
if (
|
|
1481
|
+
if (layoutsUsed) {
|
|
1443
1482
|
for (const layout2 of currentLayouts) {
|
|
1444
1483
|
unusedFiles.delete(layout2);
|
|
1445
1484
|
}
|
|
1446
1485
|
}
|
|
1447
1486
|
}
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
traverse(child);
|
|
1451
|
-
}
|
|
1487
|
+
for (const childDir of dir.dirs()) {
|
|
1488
|
+
traverse(childDir);
|
|
1452
1489
|
}
|
|
1453
1490
|
if (middleware) {
|
|
1454
1491
|
currentMiddleware.delete(middleware);
|
|
@@ -1458,10 +1495,13 @@ async function buildRoutes(sources) {
|
|
|
1458
1495
|
}
|
|
1459
1496
|
}
|
|
1460
1497
|
}
|
|
1498
|
+
function replaceInvalidFilenameChars(str) {
|
|
1499
|
+
return str.replace(/[<>:"/\\|?*]+/g, "_");
|
|
1500
|
+
}
|
|
1461
1501
|
|
|
1462
1502
|
// src/vite/routes/walk.ts
|
|
1463
1503
|
import fs from "fs";
|
|
1464
|
-
import
|
|
1504
|
+
import path4 from "path";
|
|
1465
1505
|
function createFSWalker(dir) {
|
|
1466
1506
|
return async function walkFS({
|
|
1467
1507
|
onEnter,
|
|
@@ -1476,7 +1516,7 @@ function createFSWalker(dir) {
|
|
|
1476
1516
|
const entries = await fs.promises.readdir(dir2.path, {
|
|
1477
1517
|
withFileTypes: true
|
|
1478
1518
|
});
|
|
1479
|
-
const prefix = dir2.path +
|
|
1519
|
+
const prefix = dir2.path + path4.sep;
|
|
1480
1520
|
for (const entry of entries) {
|
|
1481
1521
|
const walkEntry = {
|
|
1482
1522
|
name: entry.name,
|
|
@@ -1499,7 +1539,7 @@ function createFSWalker(dir) {
|
|
|
1499
1539
|
await walk(
|
|
1500
1540
|
{
|
|
1501
1541
|
path: dir,
|
|
1502
|
-
name:
|
|
1542
|
+
name: path4.basename(dir)
|
|
1503
1543
|
},
|
|
1504
1544
|
maxDepth
|
|
1505
1545
|
);
|
|
@@ -1616,36 +1656,34 @@ function logRoutesTable(routes, bundle) {
|
|
|
1616
1656
|
style: { compact: true }
|
|
1617
1657
|
});
|
|
1618
1658
|
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;
|
|
1659
|
+
const verbs = getVerbs(route, true);
|
|
1660
|
+
let firstRow = true;
|
|
1661
|
+
for (const verb of verbs) {
|
|
1662
|
+
const entryType = [];
|
|
1663
|
+
let size = "";
|
|
1664
|
+
const verbCell = verbColor(verb)(verb.toUpperCase());
|
|
1665
|
+
if (route.handler) {
|
|
1666
|
+
entryType.push(kleur2.blue("handler"));
|
|
1667
|
+
}
|
|
1668
|
+
if (route.page && (verb === "get" || verb === "head")) {
|
|
1669
|
+
entryType.push(kleur2.yellow("page"));
|
|
1670
|
+
if (verb === "get") {
|
|
1671
|
+
size = prettySize(computeRouteSize(route, bundle));
|
|
1642
1672
|
}
|
|
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
1673
|
}
|
|
1674
|
+
const row = [verbCell];
|
|
1675
|
+
if (verbs.length === 1 || firstRow) {
|
|
1676
|
+
row.push({
|
|
1677
|
+
rowSpan: verbs.length,
|
|
1678
|
+
content: prettyPath(route.path.path)
|
|
1679
|
+
});
|
|
1680
|
+
firstRow = false;
|
|
1681
|
+
}
|
|
1682
|
+
row.push(entryType.join(" -> "));
|
|
1683
|
+
hasMiddleware && row.push(route.middleware.length || "");
|
|
1684
|
+
hasMeta && row.push(route.meta ? "\u2713" : "");
|
|
1685
|
+
row.push(size || "");
|
|
1686
|
+
table.push(row);
|
|
1649
1687
|
}
|
|
1650
1688
|
}
|
|
1651
1689
|
for (const [key, route] of Object.entries(routes.special).sort()) {
|
|
@@ -1655,6 +1693,15 @@ function logRoutesTable(routes, bundle) {
|
|
|
1655
1693
|
row.push(prettySize(computeRouteSize(route, bundle)));
|
|
1656
1694
|
table.push(row);
|
|
1657
1695
|
}
|
|
1696
|
+
if (!table.length) {
|
|
1697
|
+
table.push([
|
|
1698
|
+
{
|
|
1699
|
+
colSpan: 4,
|
|
1700
|
+
hAlign: "center",
|
|
1701
|
+
content: kleur2.dim(kleur2.white("No routes found"))
|
|
1702
|
+
}
|
|
1703
|
+
]);
|
|
1704
|
+
}
|
|
1658
1705
|
console.log(table.toString());
|
|
1659
1706
|
}
|
|
1660
1707
|
function computeRouteSize(route, bundle) {
|
|
@@ -1701,17 +1748,20 @@ function prettySize([bytes, compBytes]) {
|
|
|
1701
1748
|
else str += kleur2.bold(kleur2.red(compSize));
|
|
1702
1749
|
return str;
|
|
1703
1750
|
}
|
|
1704
|
-
function prettyPath(
|
|
1705
|
-
return
|
|
1751
|
+
function prettyPath(path7) {
|
|
1752
|
+
return path7.replace(
|
|
1753
|
+
/\/(\$\$?)(`?)([^/`]+)\2/g,
|
|
1754
|
+
(_, type, tick, key) => "/" + type + tick + kleur2.bold(kleur2.dim(key)) + tick
|
|
1755
|
+
);
|
|
1706
1756
|
}
|
|
1707
1757
|
|
|
1708
1758
|
// src/vite/utils/read-once-persisted-store.ts
|
|
1709
1759
|
import { promises as fs2 } from "fs";
|
|
1710
1760
|
import os from "os";
|
|
1711
|
-
import
|
|
1761
|
+
import path5 from "path";
|
|
1712
1762
|
var noop = () => {
|
|
1713
1763
|
};
|
|
1714
|
-
var tmpFile =
|
|
1764
|
+
var tmpFile = path5.join(os.tmpdir(), "marko-run-storage.json");
|
|
1715
1765
|
var values = /* @__PURE__ */ new Map();
|
|
1716
1766
|
var loadedFromDisk;
|
|
1717
1767
|
var ReadOncePersistedStore = class {
|
|
@@ -1753,17 +1803,17 @@ process.once("beforeExit", (code) => {
|
|
|
1753
1803
|
|
|
1754
1804
|
// src/vite/plugin.ts
|
|
1755
1805
|
var debug = createDebug("@marko/run");
|
|
1756
|
-
var __dirname =
|
|
1806
|
+
var __dirname = path6.dirname(fileURLToPath(import.meta.url));
|
|
1757
1807
|
var PLUGIN_NAME_PREFIX = "marko-run-vite";
|
|
1758
|
-
var POSIX_SEP = "/";
|
|
1759
|
-
var WINDOWS_SEP = "\\";
|
|
1760
1808
|
var CLIENT_OUT_DIR = "public";
|
|
1761
1809
|
var MIDDLEWARE_FILENAME = `${markoRunFilePrefix}middleware.js`;
|
|
1762
1810
|
var ROUTER_FILENAME = `${markoRunFilePrefix}router.js`;
|
|
1763
1811
|
var defaultPort = Number(process.env.PORT || 3e3);
|
|
1764
|
-
var normalizePath = path4.sep === WINDOWS_SEP ? (id) => id.replace(/\\/g, POSIX_SEP) : (id) => id;
|
|
1765
1812
|
function markoRun(opts = {}) {
|
|
1766
|
-
let
|
|
1813
|
+
let routesDir;
|
|
1814
|
+
let adapter;
|
|
1815
|
+
let trailingSlashes;
|
|
1816
|
+
const { ...markoVitePluginOptions } = opts;
|
|
1767
1817
|
let store;
|
|
1768
1818
|
let root;
|
|
1769
1819
|
let shouldEmptyOutDir = false;
|
|
@@ -1796,12 +1846,8 @@ function markoRun(opts = {}) {
|
|
|
1796
1846
|
root,
|
|
1797
1847
|
"{.tsconfig*,tsconfig*.json}"
|
|
1798
1848
|
)))) {
|
|
1799
|
-
const filepath =
|
|
1800
|
-
const data = await renderRouteTypeInfo(
|
|
1801
|
-
routes2,
|
|
1802
|
-
normalizePath(path4.relative(typesDir, resolvedRoutesDir)),
|
|
1803
|
-
adapter
|
|
1804
|
-
);
|
|
1849
|
+
const filepath = path6.join(typesDir, "routes.d.ts");
|
|
1850
|
+
const data = await renderRouteTypeInfo(routes2, typesDir, adapter);
|
|
1805
1851
|
if (data !== typesFile || !fs3.existsSync(filepath)) {
|
|
1806
1852
|
await ensureDir(typesDir);
|
|
1807
1853
|
await fs3.promises.writeFile(filepath, typesFile = data);
|
|
@@ -1812,20 +1858,36 @@ function markoRun(opts = {}) {
|
|
|
1812
1858
|
function buildVirtualFiles() {
|
|
1813
1859
|
return buildVirtualFilesResult ?? (buildVirtualFilesResult = (async () => {
|
|
1814
1860
|
virtualFiles.clear();
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1861
|
+
if (fs3.existsSync(resolvedRoutesDir)) {
|
|
1862
|
+
routes = await buildRoutes(
|
|
1863
|
+
{
|
|
1864
|
+
walker: createFSWalker(resolvedRoutesDir)
|
|
1865
|
+
},
|
|
1866
|
+
entryFilesDir
|
|
1867
|
+
);
|
|
1868
|
+
if (!isBuild && !routes.list.length && !Object.keys(routes.special).length) {
|
|
1869
|
+
console.warn(`No routes found in ${resolvedRoutesDir}`);
|
|
1870
|
+
}
|
|
1871
|
+
} else {
|
|
1872
|
+
routes = {
|
|
1873
|
+
list: [],
|
|
1874
|
+
special: {},
|
|
1875
|
+
middleware: []
|
|
1876
|
+
};
|
|
1877
|
+
if (!isBuild) {
|
|
1878
|
+
console.warn(`Routes directory ${resolvedRoutesDir} does not exist`);
|
|
1879
|
+
}
|
|
1821
1880
|
}
|
|
1822
1881
|
for (const route of routes.list) {
|
|
1823
|
-
virtualFiles.set(
|
|
1882
|
+
virtualFiles.set(
|
|
1883
|
+
path6.posix.join(root, getRouteVirtualFileName(route)),
|
|
1884
|
+
""
|
|
1885
|
+
);
|
|
1824
1886
|
}
|
|
1825
1887
|
if (routes.middleware.length) {
|
|
1826
|
-
virtualFiles.set(
|
|
1888
|
+
virtualFiles.set(path6.posix.join(root, MIDDLEWARE_FILENAME), "");
|
|
1827
1889
|
}
|
|
1828
|
-
virtualFiles.set(
|
|
1890
|
+
virtualFiles.set(path6.posix.join(root, ROUTER_FILENAME), "");
|
|
1829
1891
|
return routes;
|
|
1830
1892
|
})());
|
|
1831
1893
|
}
|
|
@@ -1839,111 +1901,78 @@ function markoRun(opts = {}) {
|
|
|
1839
1901
|
fs3.rmSync(entryFilesDir, { recursive: true });
|
|
1840
1902
|
}
|
|
1841
1903
|
for (const route of routes2.list) {
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1904
|
+
if (route.handler) {
|
|
1905
|
+
const exports = await getExportsFromFile(
|
|
1906
|
+
context,
|
|
1907
|
+
route.handler.filePath
|
|
1908
|
+
);
|
|
1909
|
+
route.handler.verbs = [];
|
|
1846
1910
|
for (const name of exports) {
|
|
1847
1911
|
const verb = name.toLowerCase();
|
|
1848
1912
|
if (name === verb.toUpperCase() && httpVerbs.includes(verb)) {
|
|
1849
|
-
handler.verbs.push(verb);
|
|
1913
|
+
route.handler.verbs.push(verb);
|
|
1850
1914
|
}
|
|
1851
1915
|
}
|
|
1852
|
-
if (!handler.verbs.length) {
|
|
1916
|
+
if (!route.handler.verbs.length) {
|
|
1853
1917
|
context.warn(
|
|
1854
|
-
`Did not find any http verb exports in
|
|
1918
|
+
`Did not find any http verb exports in ${path6.relative(root, route.handler.filePath)} - expected ${httpVerbs.map((v) => v.toUpperCase()).join(", ")}`
|
|
1855
1919
|
);
|
|
1856
1920
|
}
|
|
1857
1921
|
}
|
|
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
|
-
}
|
|
1922
|
+
if (route.templateFilePath) {
|
|
1923
|
+
fs3.mkdirSync(path6.dirname(route.templateFilePath), {
|
|
1924
|
+
recursive: true
|
|
1925
|
+
});
|
|
1926
|
+
fs3.writeFileSync(
|
|
1927
|
+
route.templateFilePath,
|
|
1928
|
+
renderRouteTemplate(route, root)
|
|
1929
|
+
);
|
|
1884
1930
|
}
|
|
1885
1931
|
virtualFiles.set(
|
|
1886
|
-
|
|
1887
|
-
renderRouteEntry(route,
|
|
1932
|
+
path6.posix.join(root, getRouteVirtualFileName(route)),
|
|
1933
|
+
renderRouteEntry(route, root)
|
|
1888
1934
|
);
|
|
1889
1935
|
}
|
|
1890
1936
|
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
|
-
}
|
|
1937
|
+
if (route.templateFilePath) {
|
|
1938
|
+
fs3.mkdirSync(path6.dirname(route.templateFilePath), {
|
|
1939
|
+
recursive: true
|
|
1940
|
+
});
|
|
1941
|
+
fs3.writeFileSync(
|
|
1942
|
+
route.templateFilePath,
|
|
1943
|
+
renderRouteTemplate(route, root)
|
|
1944
|
+
);
|
|
1916
1945
|
}
|
|
1917
1946
|
}
|
|
1918
1947
|
if (routes2.middleware.length) {
|
|
1919
1948
|
for (const middleware of routes2.middleware) {
|
|
1920
1949
|
if (!(await getExportsFromFile(context, middleware.filePath)).includes("default")) {
|
|
1921
1950
|
context.warn(
|
|
1922
|
-
`Did not find a default export in middleware '${
|
|
1951
|
+
`Did not find a default export in middleware '${path6.relative(root, middleware.filePath)}'`
|
|
1923
1952
|
);
|
|
1924
1953
|
}
|
|
1925
1954
|
}
|
|
1926
1955
|
virtualFiles.set(
|
|
1927
|
-
|
|
1928
|
-
renderMiddleware(routes2.middleware)
|
|
1956
|
+
path6.posix.join(root, MIDDLEWARE_FILENAME),
|
|
1957
|
+
renderMiddleware(routes2.middleware, root)
|
|
1929
1958
|
);
|
|
1930
1959
|
}
|
|
1931
1960
|
virtualFiles.set(
|
|
1932
|
-
|
|
1933
|
-
renderRouter(routes2,
|
|
1934
|
-
trailingSlashes
|
|
1961
|
+
path6.posix.join(root, ROUTER_FILENAME),
|
|
1962
|
+
renderRouter(routes2, root, {
|
|
1963
|
+
trailingSlashes
|
|
1935
1964
|
})
|
|
1936
1965
|
);
|
|
1937
1966
|
await writeTypesFile(routes2);
|
|
1938
1967
|
if (adapter == null ? void 0 : adapter.routesGenerated) {
|
|
1939
|
-
await adapter.routesGenerated(
|
|
1940
|
-
routes2,
|
|
1941
|
-
new Map(virtualFiles.entries()),
|
|
1942
|
-
{
|
|
1968
|
+
await adapter.routesGenerated({
|
|
1969
|
+
routes: routes2,
|
|
1970
|
+
virtualFiles: new Map(virtualFiles.entries()),
|
|
1971
|
+
meta: {
|
|
1943
1972
|
buildTime: times.routesBuild,
|
|
1944
1973
|
renderTime: times.routesRender
|
|
1945
1974
|
}
|
|
1946
|
-
);
|
|
1975
|
+
});
|
|
1947
1976
|
if (!isBuild) {
|
|
1948
1977
|
await ((_a = opts == null ? void 0 : opts.emitRoutes) == null ? void 0 : _a.call(opts, routes2.list));
|
|
1949
1978
|
}
|
|
@@ -1953,7 +1982,7 @@ function markoRun(opts = {}) {
|
|
|
1953
1982
|
throw err;
|
|
1954
1983
|
}
|
|
1955
1984
|
virtualFiles.set(
|
|
1956
|
-
|
|
1985
|
+
path6.posix.join(root, ROUTER_FILENAME),
|
|
1957
1986
|
`throw ${JSON.stringify(prepareError(err))}`
|
|
1958
1987
|
);
|
|
1959
1988
|
}
|
|
@@ -1990,27 +2019,28 @@ function markoRun(opts = {}) {
|
|
|
1990
2019
|
}
|
|
1991
2020
|
}
|
|
1992
2021
|
routesDir = opts.routesDir || "src/routes";
|
|
2022
|
+
trailingSlashes = opts.trailingSlashes || "RedirectWithout";
|
|
1993
2023
|
store = new ReadOncePersistedStore(
|
|
1994
2024
|
`vite-marko-run${opts.runtimeId ? `-${opts.runtimeId}` : ""}`
|
|
1995
2025
|
);
|
|
1996
2026
|
markoVitePluginOptions.runtimeId = opts.runtimeId;
|
|
1997
2027
|
markoVitePluginOptions.basePathVar = opts.basePathVar;
|
|
1998
|
-
resolvedRoutesDir =
|
|
1999
|
-
outputDir =
|
|
2000
|
-
entryFilesDir =
|
|
2028
|
+
resolvedRoutesDir = path6.resolve(root, routesDir);
|
|
2029
|
+
outputDir = path6.join(root, ((_d = config2.build) == null ? void 0 : _d.outDir) || "dist");
|
|
2030
|
+
entryFilesDir = path6.join(outputDir, ".marko-run");
|
|
2001
2031
|
entryFilesDirPosix = normalizePath(entryFilesDir);
|
|
2002
2032
|
relativeEntryFilesDirPosix = normalizePath(
|
|
2003
|
-
|
|
2033
|
+
path6.relative(root, entryFilesDir)
|
|
2004
2034
|
);
|
|
2005
|
-
typesDir =
|
|
2006
|
-
devEntryFile =
|
|
2035
|
+
typesDir = path6.join(root, ".marko-run");
|
|
2036
|
+
devEntryFile = path6.join(root, "index.html");
|
|
2007
2037
|
devEntryFilePosix = normalizePath(devEntryFile);
|
|
2008
2038
|
let outDir = ((_e = config2.build) == null ? void 0 : _e.outDir) || "dist";
|
|
2009
2039
|
const assetsDir = ((_f = config2.build) == null ? void 0 : _f.assetsDir) || "assets";
|
|
2010
2040
|
let rollupOutputOptions = (_h = (_g = config2.build) == null ? void 0 : _g.rollupOptions) == null ? void 0 : _h.output;
|
|
2011
2041
|
if (isBuild) {
|
|
2012
2042
|
if (!isSSRBuild) {
|
|
2013
|
-
outDir =
|
|
2043
|
+
outDir = path6.join(outDir, CLIENT_OUT_DIR);
|
|
2014
2044
|
}
|
|
2015
2045
|
const defaultRollupOutputOptions = {
|
|
2016
2046
|
assetFileNames({ name }) {
|
|
@@ -2135,7 +2165,7 @@ function markoRun(opts = {}) {
|
|
|
2135
2165
|
devServer.watcher.on("all", async (type, filename) => {
|
|
2136
2166
|
seenErrors.clear();
|
|
2137
2167
|
const routableFileType = matchRoutableFile(
|
|
2138
|
-
|
|
2168
|
+
path6.parse(filename).base
|
|
2139
2169
|
);
|
|
2140
2170
|
if (filename.startsWith(resolvedRoutesDir) && routableFileType) {
|
|
2141
2171
|
if (type === "add" || type === "unlink" || type === "change" && (routableFileType === RoutableFileTypes.Handler || routableFileType === RoutableFileTypes.Middleware)) {
|
|
@@ -2185,19 +2215,19 @@ function markoRun(opts = {}) {
|
|
|
2185
2215
|
},
|
|
2186
2216
|
async resolveId(importee, importer) {
|
|
2187
2217
|
if (importee === "@marko/run/router") {
|
|
2188
|
-
return normalizePath(
|
|
2218
|
+
return normalizePath(path6.resolve(root, ROUTER_FILENAME));
|
|
2189
2219
|
} else if (importee.endsWith(".marko") && importee.includes(relativeEntryFilesDirPosix)) {
|
|
2190
2220
|
if (!importee.startsWith(root)) {
|
|
2191
|
-
importee =
|
|
2221
|
+
importee = path6.resolve(root, "." + importee);
|
|
2192
2222
|
}
|
|
2193
2223
|
return normalizePath(importee);
|
|
2194
2224
|
}
|
|
2195
2225
|
let virtualFilePath;
|
|
2196
2226
|
if (importee.startsWith(virtualFilePrefix)) {
|
|
2197
2227
|
virtualFilePath = importee.slice(virtualFilePrefix.length + 1);
|
|
2198
|
-
importee =
|
|
2228
|
+
importee = path6.resolve(root, virtualFilePath);
|
|
2199
2229
|
} else if (!isBuild && importer && (importer === devEntryFile || normalizePath(importer) === devEntryFilePosix) && importee.startsWith(`/${markoRunFilePrefix}`)) {
|
|
2200
|
-
importee =
|
|
2230
|
+
importee = path6.resolve(root, "." + importee);
|
|
2201
2231
|
}
|
|
2202
2232
|
importee = normalizePath(importee);
|
|
2203
2233
|
if (!buildVirtualFilesResult) {
|
|
@@ -2206,7 +2236,7 @@ function markoRun(opts = {}) {
|
|
|
2206
2236
|
if (virtualFiles.has(importee)) {
|
|
2207
2237
|
return importee;
|
|
2208
2238
|
} else if (virtualFilePath) {
|
|
2209
|
-
const filePath =
|
|
2239
|
+
const filePath = path6.resolve(__dirname, "..", virtualFilePath);
|
|
2210
2240
|
return await this.resolve(filePath, importer, {
|
|
2211
2241
|
skipSelf: true
|
|
2212
2242
|
});
|
|
@@ -2220,7 +2250,8 @@ function markoRun(opts = {}) {
|
|
|
2220
2250
|
await renderVirtualFiles(this);
|
|
2221
2251
|
}
|
|
2222
2252
|
if (virtualFiles.has(id)) {
|
|
2223
|
-
|
|
2253
|
+
const file = virtualFiles.get(id);
|
|
2254
|
+
return file;
|
|
2224
2255
|
} else if (!id.startsWith(entryFilesDirPosix) && /[/\\]__marko-run__[^?/\\]+\.(js|marko)$/.exec(id)) {
|
|
2225
2256
|
return "";
|
|
2226
2257
|
}
|
|
@@ -2245,7 +2276,7 @@ function markoRun(opts = {}) {
|
|
|
2245
2276
|
const builtEntries = Object.values(bundle).reduce(
|
|
2246
2277
|
(acc, item) => {
|
|
2247
2278
|
if (item.type === "chunk" && item.isEntry) {
|
|
2248
|
-
acc.push(
|
|
2279
|
+
acc.push(path6.join(options.dir, item.fileName));
|
|
2249
2280
|
}
|
|
2250
2281
|
return acc;
|
|
2251
2282
|
},
|
|
@@ -2273,12 +2304,12 @@ function markoRun(opts = {}) {
|
|
|
2273
2304
|
fs3.rmSync(entryFilesDir, { recursive: true });
|
|
2274
2305
|
}
|
|
2275
2306
|
if ((adapter == null ? void 0 : adapter.buildEnd) && routes) {
|
|
2276
|
-
await adapter.buildEnd(
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
routeData.builtEntries,
|
|
2280
|
-
routeData.sourceEntries
|
|
2281
|
-
);
|
|
2307
|
+
await adapter.buildEnd({
|
|
2308
|
+
routes,
|
|
2309
|
+
config: resolvedConfig,
|
|
2310
|
+
builtEntries: routeData.builtEntries,
|
|
2311
|
+
sourceEntries: routeData.sourceEntries
|
|
2312
|
+
});
|
|
2282
2313
|
}
|
|
2283
2314
|
}
|
|
2284
2315
|
}
|
|
@@ -2310,11 +2341,11 @@ async function ensureDir(dir) {
|
|
|
2310
2341
|
}
|
|
2311
2342
|
async function getPackageData(dir) {
|
|
2312
2343
|
do {
|
|
2313
|
-
const pkgPath =
|
|
2344
|
+
const pkgPath = path6.join(dir, "package.json");
|
|
2314
2345
|
if (fs3.existsSync(pkgPath)) {
|
|
2315
2346
|
return JSON.parse(await fs3.promises.readFile(pkgPath, "utf-8"));
|
|
2316
2347
|
}
|
|
2317
|
-
} while (dir !== (dir =
|
|
2348
|
+
} while (dir !== (dir = path6.dirname(dir)));
|
|
2318
2349
|
return null;
|
|
2319
2350
|
}
|
|
2320
2351
|
async function resolveAdapter(root, options, log) {
|