@qwik.dev/router 2.0.0-beta.11 → 2.0.0-beta.13
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/lib/adapters/azure-swa/vite/index.cjs +61 -5
- package/lib/adapters/azure-swa/vite/index.mjs +26 -205
- package/lib/adapters/bun-server/vite/index.cjs +27 -5
- package/lib/adapters/bun-server/vite/index.mjs +14 -200
- package/lib/adapters/cloud-run/vite/index.cjs +24 -5
- package/lib/adapters/cloud-run/vite/index.mjs +13 -199
- package/lib/adapters/cloudflare-pages/vite/index.cjs +65 -1
- package/lib/adapters/cloudflare-pages/vite/index.mjs +63 -4
- package/lib/adapters/deno-server/vite/index.cjs +39 -5
- package/lib/adapters/deno-server/vite/index.mjs +16 -202
- package/lib/adapters/netlify-edge/vite/index.cjs +88 -6
- package/lib/adapters/netlify-edge/vite/index.mjs +56 -244
- package/lib/adapters/node-server/vite/index.cjs +27 -5
- package/lib/adapters/node-server/vite/index.mjs +14 -200
- package/lib/adapters/shared/vite/index.cjs +303 -2
- package/lib/adapters/shared/vite/index.d.ts +4 -4
- package/lib/adapters/shared/vite/index.mjs +248 -147
- package/lib/adapters/ssg/vite/index.cjs +19 -5
- package/lib/adapters/ssg/vite/index.mjs +11 -197
- package/lib/adapters/vercel-edge/vite/index.cjs +81 -5
- package/lib/adapters/vercel-edge/vite/index.d.ts +1 -1
- package/lib/adapters/vercel-edge/vite/index.mjs +48 -233
- package/lib/chunks/error-handler.cjs +58 -0
- package/lib/chunks/error-handler.mjs +59 -0
- package/lib/chunks/format-error.cjs +136 -0
- package/lib/chunks/format-error.mjs +137 -0
- package/lib/chunks/fs.cjs +274 -0
- package/lib/chunks/fs.mjs +275 -0
- package/lib/chunks/index.cjs +877 -0
- package/lib/chunks/index.mjs +876 -0
- package/lib/chunks/mime-types.cjs +52 -0
- package/lib/chunks/mime-types.mjs +53 -0
- package/lib/chunks/routing.qwik.cjs +452 -0
- package/lib/chunks/routing.qwik.mjs +453 -0
- package/lib/chunks/types.qwik.cjs +24 -0
- package/lib/chunks/types.qwik.mjs +25 -0
- package/lib/index.d.ts +9 -3
- package/lib/index.qwik.cjs +530 -994
- package/lib/index.qwik.mjs +499 -965
- package/lib/middleware/aws-lambda/index.cjs +52 -1
- package/lib/middleware/aws-lambda/index.mjs +37 -26
- package/lib/middleware/azure-swa/index.cjs +92 -1
- package/lib/middleware/azure-swa/index.mjs +64 -46
- package/lib/middleware/bun/index.cjs +143 -1
- package/lib/middleware/bun/index.mjs +103 -117
- package/lib/middleware/cloudflare-pages/index.cjs +96 -1
- package/lib/middleware/cloudflare-pages/index.mjs +68 -47
- package/lib/middleware/deno/index.cjs +130 -1
- package/lib/middleware/deno/index.mjs +93 -112
- package/lib/middleware/firebase/index.cjs +33 -1
- package/lib/middleware/firebase/index.mjs +25 -16
- package/lib/middleware/netlify-edge/index.cjs +71 -1
- package/lib/middleware/netlify-edge/index.mjs +52 -36
- package/lib/middleware/node/index.cjs +219 -1
- package/lib/middleware/node/index.mjs +178 -165
- package/lib/middleware/request-handler/index.cjs +1488 -18
- package/lib/middleware/request-handler/index.d.ts +20 -2
- package/lib/middleware/request-handler/index.mjs +1223 -882
- package/lib/middleware/vercel-edge/index.cjs +98 -1
- package/lib/middleware/vercel-edge/index.mjs +71 -47
- package/lib/service-worker/index.cjs +5 -0
- package/lib/service-worker/index.mjs +5 -0
- package/lib/ssg/index.cjs +15 -1
- package/lib/ssg/index.mjs +12 -19
- package/lib/vite/index.cjs +2006 -27
- package/lib/vite/index.d.ts +6 -6
- package/lib/vite/index.mjs +1592 -1223
- package/package.json +9 -8
- package/lib/adapters/azure-swa/vite/index-BqUeglYs.cjs +0 -1
- package/lib/adapters/azure-swa/vite/index-CBIchDYq.js +0 -651
- package/lib/adapters/azure-swa/vite/index-ClHGw5z1.js +0 -6
- package/lib/adapters/azure-swa/vite/index-CrwlB95_.js +0 -22
- package/lib/adapters/azure-swa/vite/index-DTIOTwZo.cjs +0 -11
- package/lib/adapters/azure-swa/vite/index-vQuPcef3.cjs +0 -1
- package/lib/adapters/bun-server/vite/index-BqUeglYs.cjs +0 -1
- package/lib/adapters/bun-server/vite/index-CBIchDYq.js +0 -651
- package/lib/adapters/bun-server/vite/index-ClHGw5z1.js +0 -6
- package/lib/adapters/bun-server/vite/index-CrwlB95_.js +0 -22
- package/lib/adapters/bun-server/vite/index-DTIOTwZo.cjs +0 -11
- package/lib/adapters/bun-server/vite/index-vQuPcef3.cjs +0 -1
- package/lib/adapters/cloud-run/vite/index-BqUeglYs.cjs +0 -1
- package/lib/adapters/cloud-run/vite/index-CBIchDYq.js +0 -651
- package/lib/adapters/cloud-run/vite/index-ClHGw5z1.js +0 -6
- package/lib/adapters/cloud-run/vite/index-CrwlB95_.js +0 -22
- package/lib/adapters/cloud-run/vite/index-DTIOTwZo.cjs +0 -11
- package/lib/adapters/cloud-run/vite/index-vQuPcef3.cjs +0 -1
- package/lib/adapters/cloudflare-pages/vite/index-Bg_9YkM5.js +0 -22
- package/lib/adapters/cloudflare-pages/vite/index-C1aDmh1S.cjs +0 -1
- package/lib/adapters/cloudflare-pages/vite/index-CHT9Y93A.js +0 -254
- package/lib/adapters/cloudflare-pages/vite/index-Ck7KvpK1.cjs +0 -11
- package/lib/adapters/cloudflare-pages/vite/index-ClHGw5z1.js +0 -6
- package/lib/adapters/cloudflare-pages/vite/index-Cp1cjAds.js +0 -645
- package/lib/adapters/cloudflare-pages/vite/index-D9RL9dvJ.cjs +0 -5
- package/lib/adapters/cloudflare-pages/vite/index-vQuPcef3.cjs +0 -1
- package/lib/adapters/deno-server/vite/index-BqUeglYs.cjs +0 -1
- package/lib/adapters/deno-server/vite/index-CBIchDYq.js +0 -651
- package/lib/adapters/deno-server/vite/index-ClHGw5z1.js +0 -6
- package/lib/adapters/deno-server/vite/index-CrwlB95_.js +0 -22
- package/lib/adapters/deno-server/vite/index-DTIOTwZo.cjs +0 -11
- package/lib/adapters/deno-server/vite/index-vQuPcef3.cjs +0 -1
- package/lib/adapters/netlify-edge/vite/index-BqUeglYs.cjs +0 -1
- package/lib/adapters/netlify-edge/vite/index-CBIchDYq.js +0 -651
- package/lib/adapters/netlify-edge/vite/index-ClHGw5z1.js +0 -6
- package/lib/adapters/netlify-edge/vite/index-CrwlB95_.js +0 -22
- package/lib/adapters/netlify-edge/vite/index-DTIOTwZo.cjs +0 -11
- package/lib/adapters/netlify-edge/vite/index-vQuPcef3.cjs +0 -1
- package/lib/adapters/node-server/vite/index-BqUeglYs.cjs +0 -1
- package/lib/adapters/node-server/vite/index-CBIchDYq.js +0 -651
- package/lib/adapters/node-server/vite/index-ClHGw5z1.js +0 -6
- package/lib/adapters/node-server/vite/index-CrwlB95_.js +0 -22
- package/lib/adapters/node-server/vite/index-DTIOTwZo.cjs +0 -11
- package/lib/adapters/node-server/vite/index-vQuPcef3.cjs +0 -1
- package/lib/adapters/shared/vite/index-BqUeglYs.cjs +0 -1
- package/lib/adapters/shared/vite/index-CBIchDYq.js +0 -651
- package/lib/adapters/shared/vite/index-ClHGw5z1.js +0 -6
- package/lib/adapters/shared/vite/index-CrwlB95_.js +0 -22
- package/lib/adapters/shared/vite/index-DTIOTwZo.cjs +0 -11
- package/lib/adapters/shared/vite/index-vQuPcef3.cjs +0 -1
- package/lib/adapters/ssg/vite/index-BqUeglYs.cjs +0 -1
- package/lib/adapters/ssg/vite/index-CBIchDYq.js +0 -651
- package/lib/adapters/ssg/vite/index-ClHGw5z1.js +0 -6
- package/lib/adapters/ssg/vite/index-CrwlB95_.js +0 -22
- package/lib/adapters/ssg/vite/index-DTIOTwZo.cjs +0 -11
- package/lib/adapters/ssg/vite/index-vQuPcef3.cjs +0 -1
- package/lib/adapters/vercel-edge/vite/index-BqUeglYs.cjs +0 -1
- package/lib/adapters/vercel-edge/vite/index-CBIchDYq.js +0 -651
- package/lib/adapters/vercel-edge/vite/index-ClHGw5z1.js +0 -6
- package/lib/adapters/vercel-edge/vite/index-CrwlB95_.js +0 -22
- package/lib/adapters/vercel-edge/vite/index-DTIOTwZo.cjs +0 -11
- package/lib/adapters/vercel-edge/vite/index-vQuPcef3.cjs +0 -1
- package/lib/service-worker.cjs +0 -1
- package/lib/service-worker.mjs +0 -5
- package/lib/ssg/deno.cjs +0 -1
- package/lib/ssg/deno.mjs +0 -6
- package/lib/ssg/index-CBIchDYq.js +0 -651
- package/lib/ssg/index-ClHGw5z1.js +0 -6
- package/lib/ssg/index-DTIOTwZo.cjs +0 -11
- package/lib/ssg/index-vQuPcef3.cjs +0 -1
- package/lib/ssg/node.cjs +0 -11
- package/lib/ssg/node.mjs +0 -651
package/lib/vite/index.mjs
CHANGED
|
@@ -1,561 +1,614 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import
|
|
13
|
-
import
|
|
14
|
-
import {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
return e.replace(/\w\S*/g, (t) => t.charAt(0).toUpperCase() + t.slice(1).toLowerCase());
|
|
26
|
-
}
|
|
27
|
-
function re(e, t) {
|
|
28
|
-
e.diagnostics.push({
|
|
29
|
-
type: "error",
|
|
30
|
-
message: t ? String(t.stack || t) : "Error"
|
|
31
|
-
});
|
|
32
|
-
}
|
|
33
|
-
function Re(e, t) {
|
|
34
|
-
e.diagnostics.push({
|
|
35
|
-
type: "warn",
|
|
36
|
-
message: String(t)
|
|
37
|
-
});
|
|
38
|
-
}
|
|
39
|
-
function ne(e, t) {
|
|
40
|
-
if (typeof e == "string" && (e = e.trim(), e !== ""))
|
|
41
|
-
try {
|
|
42
|
-
if (e = e.replace(/\/+/g, "/"), e.startsWith("/") && (e = e.slice(1)), e = new URL(t + e, "https://qwik.dev").pathname, e !== t) {
|
|
43
|
-
if (globalThis.__NO_TRAILING_SLASH__)
|
|
44
|
-
e.endsWith("/") && (e = e.slice(0, e.length - 1));
|
|
45
|
-
else if (!e.endsWith("/")) {
|
|
46
|
-
const r = e.split("/");
|
|
47
|
-
r[r.length - 1].includes(".") || (e += "/");
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
return e;
|
|
51
|
-
} catch (r) {
|
|
52
|
-
console.error(r);
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
3
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
4
|
+
import { mergeConfig, loadEnv } from "vite";
|
|
5
|
+
import fs, { existsSync } from "node:fs";
|
|
6
|
+
import path, { join, dirname, basename, resolve, isAbsolute, extname } from "node:path";
|
|
7
|
+
import { g as getExtension, r as removeExtension, i as isIndexModule, a as isErrorName, b as isLayoutModule, c as isEntryName, d as isMenuFileName, e as isServiceWorkerName, f as isPageModuleExt, h as isModuleExt, j as isMarkdownExt, k as isSameOriginUrl, l as normalizePath, m as getPathnameFromDirPath, o as getMenuPathname, p as createFileId, q as parseRouteIndexName, s as isPluginModule, t as addError, u as addWarning, v as isPageExt } from "../chunks/fs.mjs";
|
|
8
|
+
import { marked } from "marked";
|
|
9
|
+
import { SourceMapGenerator } from "source-map";
|
|
10
|
+
import { visit } from "unist-util-visit";
|
|
11
|
+
import { parse } from "yaml";
|
|
12
|
+
import Slugger from "github-slugger";
|
|
13
|
+
import { valueToEstree } from "estree-util-value-to-estree";
|
|
14
|
+
import { headingRank } from "hast-util-heading-rank";
|
|
15
|
+
import { toString } from "hast-util-to-string";
|
|
16
|
+
import { refractor } from "refractor";
|
|
17
|
+
import tsxLang from "refractor/lang/tsx.js";
|
|
18
|
+
import { optimize } from "svgo";
|
|
19
|
+
import { p as parseId, f as formatError } from "../chunks/format-error.mjs";
|
|
20
|
+
function extendConfig(baseConfigExport, serverConfigExport) {
|
|
21
|
+
return async (env) => {
|
|
22
|
+
let resolvedBase = await baseConfigExport;
|
|
23
|
+
if (typeof resolvedBase === "function") {
|
|
24
|
+
resolvedBase = await resolvedBase(env);
|
|
53
25
|
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
if (typeof e == "string" && (e = e.trim(), e !== "")) {
|
|
58
|
-
const t = e.charAt(0);
|
|
59
|
-
if (t !== "/" && t !== ".") {
|
|
60
|
-
if (t === "#")
|
|
61
|
-
return !1;
|
|
62
|
-
const r = e.indexOf(":");
|
|
63
|
-
if (r > -1) {
|
|
64
|
-
const n = e.slice(0, r).toLowerCase();
|
|
65
|
-
return !$e[n];
|
|
66
|
-
}
|
|
26
|
+
let resolvedServer = await serverConfigExport;
|
|
27
|
+
if (typeof resolvedServer === "function") {
|
|
28
|
+
resolvedServer = await resolvedServer(env);
|
|
67
29
|
}
|
|
68
|
-
return
|
|
69
|
-
}
|
|
70
|
-
return !1;
|
|
30
|
+
return mergeConfig(resolvedBase, resolvedServer);
|
|
31
|
+
};
|
|
71
32
|
}
|
|
72
|
-
const
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
}
|
|
91
|
-
function De(e, t) {
|
|
92
|
-
let r = v(ee(e.routesDir, t));
|
|
93
|
-
r = "/" + v(R(r));
|
|
94
|
-
let n = ne(r, e.basePathname);
|
|
95
|
-
return n.endsWith("/") || (n += "/"), n;
|
|
96
|
-
}
|
|
97
|
-
function $(e) {
|
|
98
|
-
if (typeof e == "string") {
|
|
99
|
-
const t = e.trim().toLowerCase().split(".");
|
|
100
|
-
if (t.length > 1) {
|
|
101
|
-
const r = t.pop().split("?")[0].split("#")[0];
|
|
102
|
-
return r === "ts" && t.pop() === "d" ? ".d.ts" : "." + r;
|
|
103
|
-
}
|
|
33
|
+
const swRegister = 'export default""';
|
|
34
|
+
function getSourceFile(fileName) {
|
|
35
|
+
const ext = getExtension(fileName);
|
|
36
|
+
const extlessName = removeExtension(fileName);
|
|
37
|
+
const isPageModule = isPageModuleExt(ext);
|
|
38
|
+
const isModule = isModuleExt(ext);
|
|
39
|
+
const isMarkdown = isMarkdownExt(ext);
|
|
40
|
+
let type = null;
|
|
41
|
+
if ((isIndexModule(extlessName) || isErrorName(extlessName)) && (isPageModule || isModule || isMarkdown)) {
|
|
42
|
+
type = "route";
|
|
43
|
+
} else if (isLayoutModule(extlessName) && (isPageModule || isModule)) {
|
|
44
|
+
type = "layout";
|
|
45
|
+
} else if (isEntryName(extlessName) && isModule) {
|
|
46
|
+
type = "entry";
|
|
47
|
+
} else if (isMenuFileName(fileName)) {
|
|
48
|
+
type = "menu";
|
|
49
|
+
} else if (isModule && isServiceWorkerName(extlessName)) {
|
|
50
|
+
type = "service-worker";
|
|
104
51
|
}
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
return
|
|
52
|
+
if (type !== null) {
|
|
53
|
+
const sourceFileName = {
|
|
54
|
+
type,
|
|
55
|
+
extlessName,
|
|
56
|
+
ext
|
|
57
|
+
};
|
|
58
|
+
return sourceFileName;
|
|
112
59
|
}
|
|
113
|
-
return
|
|
114
|
-
}
|
|
115
|
-
function v(e) {
|
|
116
|
-
return Oe(ye(e));
|
|
117
|
-
}
|
|
118
|
-
function Oe(e) {
|
|
119
|
-
const t = /^\\\\\?\\/.test(e), r = /[^\u0000-\u0080]+/.test(e);
|
|
120
|
-
return t || r || (e = e.replace(/\\/g, "/"), e.endsWith("/") && (e = e.slice(0, e.length - 1))), e;
|
|
60
|
+
return null;
|
|
121
61
|
}
|
|
122
|
-
function
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
let i = S(M(t));
|
|
126
|
-
if (i = i.replace(/[\W_]+/g, ""), i === "" ? i = "Q" + s : isNaN(i.charAt(0)) || (i = "Q" + i), n.push(Ne(i)), t = v(R(t)), t === e)
|
|
127
|
-
break;
|
|
62
|
+
function getMarkdownRelativeUrl(opts, containingFilePath, url, checkFileExists) {
|
|
63
|
+
if (typeof url !== "string" || !isSameOriginUrl(url)) {
|
|
64
|
+
return url;
|
|
128
65
|
}
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
const
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
}
|
|
141
|
-
function We(e) {
|
|
142
|
-
return /^index(|!|@.+)$/.test(e);
|
|
143
|
-
}
|
|
144
|
-
function je(e) {
|
|
145
|
-
return /^plugin(|@.+)$/.test(e);
|
|
146
|
-
}
|
|
147
|
-
function Ae(e) {
|
|
148
|
-
return /^layout(|!|-.+)$/.test(e);
|
|
149
|
-
}
|
|
150
|
-
function ae(e) {
|
|
151
|
-
return e in ie;
|
|
152
|
-
}
|
|
153
|
-
function U(e) {
|
|
154
|
-
return e in Te;
|
|
155
|
-
}
|
|
156
|
-
function J(e) {
|
|
157
|
-
return e in oe;
|
|
158
|
-
}
|
|
159
|
-
function Ce(e) {
|
|
160
|
-
return e in ie || e in oe;
|
|
161
|
-
}
|
|
162
|
-
function ue(e) {
|
|
163
|
-
return e === "menu.md";
|
|
164
|
-
}
|
|
165
|
-
function Me(e) {
|
|
166
|
-
return e === "service-worker";
|
|
167
|
-
}
|
|
168
|
-
function Le(e) {
|
|
169
|
-
return e === "entry";
|
|
170
|
-
}
|
|
171
|
-
function He(e) {
|
|
172
|
-
try {
|
|
173
|
-
const t = parseInt(e, 10);
|
|
174
|
-
return t >= 400 && t <= 599;
|
|
175
|
-
} catch {
|
|
176
|
-
}
|
|
177
|
-
return !1;
|
|
178
|
-
}
|
|
179
|
-
function qe(e, t = !0) {
|
|
180
|
-
return e.startsWith("__") ? (t && console.warn(
|
|
181
|
-
`Grouped (pathless) layout "${e}" should use the "(${e.slice(
|
|
182
|
-
2
|
|
183
|
-
)})" directory name instead. Prefixing a directory with "__" has been deprecated and will be removed in future versions.`
|
|
184
|
-
), !0) : e.startsWith("(") && e.endsWith(")");
|
|
185
|
-
}
|
|
186
|
-
function le(e) {
|
|
187
|
-
const t = $(e), r = S(e), n = ae(t), s = U(t), i = J(t);
|
|
188
|
-
let o = null;
|
|
189
|
-
return (We(r) || He(r)) && (n || s || i) ? o = "route" : Ae(r) && (n || s) ? o = "layout" : Le(r) && s ? o = "entry" : ue(e) ? o = "menu" : s && Me(r) && (o = "service-worker"), o !== null ? {
|
|
190
|
-
type: o,
|
|
191
|
-
extlessName: r,
|
|
192
|
-
ext: t
|
|
193
|
-
} : null;
|
|
194
|
-
}
|
|
195
|
-
function C(e, t, r, n) {
|
|
196
|
-
if (typeof r != "string" || !se(r))
|
|
197
|
-
return r;
|
|
198
|
-
const s = r.split("?"), i = r.split("#"), o = r.split("?")[0].split("#")[0], a = $(o);
|
|
199
|
-
if (J(a)) {
|
|
200
|
-
const u = o.startsWith("/"), c = v(o).split("/").filter((w) => w.length > 0), l = u ? j(e.routesDir, ...c) : j(R(t), ...c);
|
|
201
|
-
n && !ge(l) && console.warn(
|
|
202
|
-
`
|
|
203
|
-
The link "${r}", found within "${t}" does not have a matching source file.
|
|
66
|
+
const querySplit = url.split("?");
|
|
67
|
+
const hashSplit = url.split("#");
|
|
68
|
+
const strippedUrl = url.split("?")[0].split("#")[0];
|
|
69
|
+
const extension = getExtension(strippedUrl);
|
|
70
|
+
if (isMarkdownExt(extension)) {
|
|
71
|
+
const isAbsolute2 = strippedUrl.startsWith("/");
|
|
72
|
+
const parts = normalizePath(strippedUrl).split("/").filter((p) => p.length > 0);
|
|
73
|
+
const filePath = isAbsolute2 ? join(opts.routesDir, ...parts) : join(dirname(containingFilePath), ...parts);
|
|
74
|
+
if (checkFileExists && !existsSync(filePath)) {
|
|
75
|
+
console.warn(
|
|
76
|
+
`
|
|
77
|
+
The link "${url}", found within "${containingFilePath}" does not have a matching source file.
|
|
204
78
|
`
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
const fileName = basename(filePath);
|
|
82
|
+
const sourceFileName = getSourceFile(fileName);
|
|
83
|
+
if (sourceFileName) {
|
|
84
|
+
const mdDirPath = dirname(filePath);
|
|
85
|
+
let pathname = getPathnameFromDirPath(opts, mdDirPath);
|
|
86
|
+
if (querySplit.length > 1) {
|
|
87
|
+
pathname += "?" + querySplit[1];
|
|
88
|
+
} else if (hashSplit.length > 1) {
|
|
89
|
+
pathname += "#" + hashSplit[1];
|
|
90
|
+
}
|
|
91
|
+
return pathname;
|
|
92
|
+
}
|
|
93
|
+
} else if (extension === "") {
|
|
94
|
+
if (url.endsWith("/")) {
|
|
95
|
+
if (globalThis.__NO_TRAILING_SLASH__) {
|
|
96
|
+
url = url.slice(0, -1);
|
|
97
|
+
}
|
|
98
|
+
} else if (!globalThis.__NO_TRAILING_SLASH__) {
|
|
99
|
+
url += "/";
|
|
211
100
|
}
|
|
212
|
-
}
|
|
213
|
-
return
|
|
101
|
+
}
|
|
102
|
+
return url;
|
|
214
103
|
}
|
|
215
|
-
function
|
|
216
|
-
|
|
217
|
-
pathname:
|
|
218
|
-
filePath
|
|
104
|
+
function createMenu(opts, filePath) {
|
|
105
|
+
const menu = {
|
|
106
|
+
pathname: getMenuPathname(opts, filePath),
|
|
107
|
+
filePath
|
|
219
108
|
};
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
109
|
+
return menu;
|
|
110
|
+
}
|
|
111
|
+
function resolveMenu(opts, menuSourceFile) {
|
|
112
|
+
return createMenu(opts, menuSourceFile.filePath);
|
|
113
|
+
}
|
|
114
|
+
async function transformMenu(opts, filePath, content) {
|
|
115
|
+
const parsedMenu = parseMenu(opts, filePath, content);
|
|
116
|
+
const id = createFileId(opts.routesDir, filePath);
|
|
117
|
+
const code = `const ${id} = ${JSON.stringify(parsedMenu, null, 2)};`;
|
|
118
|
+
return `${code} export default ${id}`;
|
|
119
|
+
}
|
|
120
|
+
function parseMenu(opts, filePath, content, checkFileExists = true) {
|
|
121
|
+
const tokens = marked.lexer(content, {});
|
|
122
|
+
let currentDepth = 0;
|
|
123
|
+
const stack = [];
|
|
124
|
+
for (const t of tokens) {
|
|
125
|
+
if (t.type === "heading") {
|
|
126
|
+
const diff = currentDepth - t.depth;
|
|
127
|
+
if (diff >= 0) {
|
|
128
|
+
stack.length -= diff + 1;
|
|
129
|
+
}
|
|
130
|
+
if (diff < -1) {
|
|
236
131
|
throw new Error(
|
|
237
132
|
`Menu hierarchy skipped a level, went from <h${"#".repeat(
|
|
238
|
-
|
|
239
|
-
)}> to <h${"#".repeat(
|
|
133
|
+
currentDepth
|
|
134
|
+
)}> to <h${"#".repeat(t.depth)}>, in menu: ${filePath}`
|
|
240
135
|
);
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
136
|
+
}
|
|
137
|
+
currentDepth = t.depth;
|
|
138
|
+
const parentNode = stack[stack.length - 1];
|
|
139
|
+
for (const h2Token of t.tokens || []) {
|
|
140
|
+
const lastNode = {
|
|
245
141
|
text: ""
|
|
246
142
|
};
|
|
247
|
-
if (
|
|
248
|
-
|
|
249
|
-
else if (
|
|
250
|
-
|
|
251
|
-
|
|
143
|
+
if (h2Token.type === "text") {
|
|
144
|
+
lastNode.text = h2Token.text;
|
|
145
|
+
} else if (h2Token.type === "link") {
|
|
146
|
+
lastNode.text = h2Token.text;
|
|
147
|
+
lastNode.href = getMarkdownRelativeUrl(opts, filePath, h2Token.href, checkFileExists);
|
|
148
|
+
} else {
|
|
252
149
|
throw new Error(
|
|
253
|
-
`Headings can only be a text or link. Received "${
|
|
150
|
+
`Headings can only be a text or link. Received "${h2Token.type}", value "${h2Token.raw}", in menu: ${filePath}`
|
|
254
151
|
);
|
|
255
|
-
|
|
152
|
+
}
|
|
153
|
+
if (parentNode) {
|
|
154
|
+
parentNode.items = parentNode.items || [];
|
|
155
|
+
parentNode.items.push(lastNode);
|
|
156
|
+
}
|
|
157
|
+
stack.push(lastNode);
|
|
256
158
|
}
|
|
257
|
-
} else if (
|
|
258
|
-
const
|
|
259
|
-
|
|
260
|
-
for (const
|
|
261
|
-
if (
|
|
262
|
-
for (const
|
|
263
|
-
if (
|
|
264
|
-
for (const
|
|
265
|
-
if (
|
|
266
|
-
|
|
267
|
-
else if (
|
|
268
|
-
|
|
269
|
-
text:
|
|
270
|
-
href:
|
|
159
|
+
} else if (t.type === "list") {
|
|
160
|
+
const parentNode = stack[stack.length - 1];
|
|
161
|
+
parentNode.items = parentNode.items || [];
|
|
162
|
+
for (const li of t.items) {
|
|
163
|
+
if (li.type === "list_item") {
|
|
164
|
+
for (const liToken of li.tokens) {
|
|
165
|
+
if (liToken.type === "text") {
|
|
166
|
+
for (const liItem of liToken.tokens) {
|
|
167
|
+
if (liItem.type === "text") {
|
|
168
|
+
parentNode.items.push({ text: liItem.text });
|
|
169
|
+
} else if (liItem.type === "link") {
|
|
170
|
+
parentNode.items.push({
|
|
171
|
+
text: liItem.text,
|
|
172
|
+
href: getMarkdownRelativeUrl(opts, filePath, liItem.href, checkFileExists)
|
|
271
173
|
});
|
|
272
|
-
else
|
|
174
|
+
} else {
|
|
273
175
|
throw new Error(
|
|
274
|
-
`List items can only be a text or link. Received "${
|
|
176
|
+
`List items can only be a text or link. Received "${liItem.type}", value "${liItem.raw}", in menu: ${filePath}`
|
|
275
177
|
);
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
} else if (liToken.type === "link") {
|
|
181
|
+
parentNode.items.push({
|
|
182
|
+
text: liToken.text,
|
|
183
|
+
href: getMarkdownRelativeUrl(opts, filePath, liToken.href, checkFileExists)
|
|
280
184
|
});
|
|
281
|
-
else
|
|
185
|
+
} else {
|
|
282
186
|
throw new Error(
|
|
283
|
-
`List items can only be a text or link. Received "${
|
|
187
|
+
`List items can only be a text or link. Received "${liToken.type}", value "${liToken.raw}", in menu: ${filePath}`
|
|
284
188
|
);
|
|
285
|
-
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
} else {
|
|
286
192
|
throw new Error(
|
|
287
|
-
`Only list items can be used in lists. Received "${
|
|
193
|
+
`Only list items can be used in lists. Received "${li.type}", value "${li.raw}", in menu: ${filePath}`
|
|
288
194
|
);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
} else if (t.type === "space") {
|
|
198
|
+
continue;
|
|
289
199
|
} else {
|
|
290
|
-
if (a.type === "space")
|
|
291
|
-
continue;
|
|
292
200
|
throw new Error(
|
|
293
|
-
`Menu has a "${
|
|
201
|
+
`Menu has a "${t.type}" with the value "${t.raw}". However, only headings and lists can be used in the menu: ${filePath}`
|
|
294
202
|
);
|
|
295
203
|
}
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
204
|
+
}
|
|
205
|
+
if (stack.length === 0) {
|
|
206
|
+
throw new Error(`Menu must start with an h1 in the index: ${filePath}`);
|
|
207
|
+
}
|
|
208
|
+
return stack[0];
|
|
299
209
|
}
|
|
300
|
-
function
|
|
301
|
-
if (
|
|
210
|
+
function parseRoutePathname(basePathname, pathname) {
|
|
211
|
+
if (pathname === basePathname) {
|
|
302
212
|
return {
|
|
303
|
-
pattern: new RegExp("^" +
|
|
304
|
-
routeName:
|
|
213
|
+
pattern: new RegExp("^" + pathname.replace(/[.*+?^${}()|[\]\\]/g, "\\$&") + "$"),
|
|
214
|
+
routeName: pathname,
|
|
305
215
|
paramNames: [],
|
|
306
|
-
segments: [[{ content: "", dynamic:
|
|
216
|
+
segments: [[{ content: "", dynamic: false, rest: false }]]
|
|
307
217
|
};
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
218
|
+
}
|
|
219
|
+
pathname = pathname.slice(1);
|
|
220
|
+
const segments = pathname.split("/");
|
|
221
|
+
const paramNames = [];
|
|
222
|
+
const pattern = new RegExp(
|
|
223
|
+
`^${segments.filter((segment) => segment.length > 0).map((s) => {
|
|
224
|
+
const segment = decodeURI(s);
|
|
225
|
+
const catchAll = /^\[\.\.\.(\w+)?\]$/.exec(segment);
|
|
226
|
+
if (catchAll) {
|
|
227
|
+
paramNames.push(catchAll[1]);
|
|
228
|
+
return "(?:/(.*))?";
|
|
229
|
+
}
|
|
230
|
+
return "/" + segment.split(DYNAMIC_SEGMENT).map((content, i) => {
|
|
231
|
+
if (i % 2) {
|
|
232
|
+
const rg = PARAM_PATTERN.exec(content);
|
|
233
|
+
if (rg) {
|
|
234
|
+
const [, rest, name] = rg;
|
|
235
|
+
paramNames.push(name);
|
|
236
|
+
return rest ? "(.*?)" : "([^/]+?)";
|
|
321
237
|
}
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
}).join("")
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
238
|
+
}
|
|
239
|
+
return encodeURI(content).normalize().replace(/%5[Bb]/g, "[").replace(/%5[Dd]/g, "]").replace(/#/g, "%23").replace(/\?/g, "%3F").replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
240
|
+
}).join("");
|
|
241
|
+
}).join("")}/?$`
|
|
242
|
+
// always match with and without a trailing slash
|
|
243
|
+
);
|
|
244
|
+
return {
|
|
245
|
+
pattern,
|
|
246
|
+
routeName: pathname,
|
|
247
|
+
paramNames,
|
|
248
|
+
segments: segments.map((segment) => {
|
|
249
|
+
const parts = [];
|
|
250
|
+
segment.split(/\[(.+?)\]/).map((content, i) => {
|
|
251
|
+
if (content) {
|
|
252
|
+
const dynamic = !!(i % 2);
|
|
253
|
+
parts.push({
|
|
254
|
+
content,
|
|
255
|
+
dynamic,
|
|
256
|
+
rest: dynamic && content.startsWith("...")
|
|
338
257
|
});
|
|
339
258
|
}
|
|
340
|
-
})
|
|
259
|
+
});
|
|
260
|
+
return parts;
|
|
341
261
|
})
|
|
342
262
|
};
|
|
343
263
|
}
|
|
344
|
-
const
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
if (!
|
|
352
|
-
return
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
264
|
+
const PARAM_PATTERN = /^(\.\.\.)?(\w+)?$/;
|
|
265
|
+
const DYNAMIC_SEGMENT = /\[(.+?)\]/;
|
|
266
|
+
function routeSortCompare(a, b) {
|
|
267
|
+
const maxSegments = Math.max(a.segments.length, b.segments.length);
|
|
268
|
+
for (let i = 0; i < maxSegments; i += 1) {
|
|
269
|
+
const sa = a.segments[i];
|
|
270
|
+
const sb = b.segments[i];
|
|
271
|
+
if (!sa) {
|
|
272
|
+
return a.pathname.includes("[...") ? 1 : -1;
|
|
273
|
+
}
|
|
274
|
+
if (!sb) {
|
|
275
|
+
return b.pathname.includes("[...") ? -1 : 1;
|
|
276
|
+
}
|
|
277
|
+
const maxParts = Math.max(sa.length, sb.length);
|
|
278
|
+
for (let i2 = 0; i2 < maxParts; i2 += 1) {
|
|
279
|
+
const pa = sa[i2];
|
|
280
|
+
const pb = sb[i2];
|
|
281
|
+
if (pa === void 0) {
|
|
282
|
+
return pb.dynamic ? -1 : 1;
|
|
283
|
+
}
|
|
284
|
+
if (pb === void 0) {
|
|
285
|
+
return pa.dynamic ? 1 : -1;
|
|
286
|
+
}
|
|
287
|
+
if (pa.dynamic !== pb.dynamic) {
|
|
288
|
+
return pa.dynamic ? 1 : -1;
|
|
289
|
+
}
|
|
290
|
+
if (pa.dynamic) {
|
|
291
|
+
if (pa.rest !== pb.rest) {
|
|
292
|
+
return pa.rest ? 1 : -1;
|
|
293
|
+
}
|
|
294
|
+
}
|
|
362
295
|
}
|
|
363
296
|
}
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
297
|
+
if (a.pathname === b.pathname) {
|
|
298
|
+
return a.ext > b.ext ? -1 : 1;
|
|
299
|
+
}
|
|
300
|
+
return a.pathname < b.pathname ? -1 : 1;
|
|
301
|
+
}
|
|
302
|
+
function resolveSourceFiles(opts, sourceFiles) {
|
|
303
|
+
const layouts = sourceFiles.filter((s) => s.type === "layout").map((s) => resolveLayout(opts, s)).sort((a, b) => {
|
|
304
|
+
return a.id < b.id ? -1 : 1;
|
|
305
|
+
});
|
|
306
|
+
const routes = sourceFiles.filter((s) => s.type === "route").map((s) => resolveRoute(opts, layouts, s)).sort(routeSortCompare);
|
|
307
|
+
const entries = sourceFiles.filter((s) => s.type === "entry").map((s) => resolveEntry(opts, s)).sort((a, b) => {
|
|
308
|
+
return a.chunkFileName < b.chunkFileName ? -1 : 1;
|
|
309
|
+
});
|
|
310
|
+
const serviceWorkers = sourceFiles.filter((s) => s.type === "service-worker").map((p) => resolveServiceWorkerEntry(opts, p)).sort((a, b) => {
|
|
311
|
+
return a.chunkFileName < b.chunkFileName ? -1 : 1;
|
|
312
|
+
});
|
|
313
|
+
const menus = sourceFiles.filter((s) => s.type === "menu").map((p) => resolveMenu(opts, p)).sort((a, b) => {
|
|
314
|
+
return a.pathname < b.pathname ? -1 : 1;
|
|
315
|
+
});
|
|
316
|
+
let inc = 0;
|
|
317
|
+
const ids = /* @__PURE__ */ new Set();
|
|
318
|
+
const uniqueIds = (b) => {
|
|
319
|
+
for (const r of b) {
|
|
320
|
+
let id = r.id;
|
|
321
|
+
while (ids.has(id)) {
|
|
322
|
+
id = `${r.id}_${inc++}`;
|
|
323
|
+
}
|
|
324
|
+
r.id = id;
|
|
325
|
+
ids.add(id);
|
|
375
326
|
}
|
|
376
327
|
};
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
328
|
+
uniqueIds(layouts);
|
|
329
|
+
uniqueIds(routes);
|
|
330
|
+
uniqueIds(entries);
|
|
331
|
+
uniqueIds(serviceWorkers);
|
|
332
|
+
return { layouts, routes, entries, menus, serviceWorkers };
|
|
333
|
+
}
|
|
334
|
+
function resolveLayout(opts, layoutSourceFile) {
|
|
335
|
+
let extlessName = layoutSourceFile.extlessName;
|
|
336
|
+
const filePath = layoutSourceFile.filePath;
|
|
337
|
+
const dirPath = layoutSourceFile.dirPath;
|
|
338
|
+
let layoutName;
|
|
339
|
+
let layoutType;
|
|
340
|
+
if (extlessName.endsWith(LAYOUT_TOP_SUFFIX)) {
|
|
341
|
+
layoutType = "top";
|
|
342
|
+
extlessName = extlessName.slice(0, extlessName.length - 1);
|
|
343
|
+
} else {
|
|
344
|
+
layoutType = "nested";
|
|
345
|
+
}
|
|
346
|
+
if (extlessName.startsWith(LAYOUT_NAMED_PREFIX)) {
|
|
347
|
+
layoutName = extlessName.slice(LAYOUT_NAMED_PREFIX.length);
|
|
348
|
+
} else {
|
|
349
|
+
layoutName = "";
|
|
350
|
+
}
|
|
351
|
+
const layout = {
|
|
352
|
+
id: createFileId(opts.routesDir, filePath),
|
|
353
|
+
filePath,
|
|
354
|
+
dirPath,
|
|
355
|
+
layoutType,
|
|
356
|
+
layoutName
|
|
389
357
|
};
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
358
|
+
return layout;
|
|
359
|
+
}
|
|
360
|
+
const LAYOUT_ID = "layout";
|
|
361
|
+
const LAYOUT_NAMED_PREFIX = LAYOUT_ID + "-";
|
|
362
|
+
const LAYOUT_TOP_SUFFIX = "!";
|
|
363
|
+
function resolveRoute(opts, appLayouts, sourceFile) {
|
|
364
|
+
const filePath = sourceFile.filePath;
|
|
365
|
+
const layouts = [];
|
|
366
|
+
const routesDir = opts.routesDir;
|
|
367
|
+
const { layoutName, layoutStop } = parseRouteIndexName(sourceFile.extlessName);
|
|
368
|
+
let pathname = getPathnameFromDirPath(opts, sourceFile.dirPath);
|
|
369
|
+
if (sourceFile.extlessName === "404") {
|
|
370
|
+
pathname += sourceFile.extlessName + ".html";
|
|
371
|
+
}
|
|
372
|
+
if (!layoutStop) {
|
|
373
|
+
let currentDir = normalizePath(dirname(filePath));
|
|
374
|
+
let hasFoundNamedLayout = false;
|
|
375
|
+
const hasNamedLayout = layoutName !== "";
|
|
376
|
+
for (let i = 0; i < 20; i++) {
|
|
377
|
+
let layout = void 0;
|
|
378
|
+
if (hasNamedLayout && !hasFoundNamedLayout) {
|
|
379
|
+
layout = appLayouts.find((l) => l.dirPath === currentDir && l.layoutName === layoutName);
|
|
380
|
+
if (layout) {
|
|
381
|
+
hasFoundNamedLayout = true;
|
|
382
|
+
}
|
|
383
|
+
} else {
|
|
384
|
+
layout = appLayouts.find((l) => l.dirPath === currentDir && l.layoutName === "");
|
|
385
|
+
}
|
|
386
|
+
if (layout) {
|
|
387
|
+
layouts.push(layout);
|
|
388
|
+
if (layout.layoutType === "top") {
|
|
389
|
+
break;
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
if (currentDir === routesDir) {
|
|
401
393
|
break;
|
|
402
|
-
|
|
394
|
+
}
|
|
395
|
+
currentDir = normalizePath(dirname(currentDir));
|
|
403
396
|
}
|
|
404
397
|
}
|
|
405
|
-
|
|
406
|
-
id:
|
|
407
|
-
filePath
|
|
408
|
-
pathname
|
|
409
|
-
layouts:
|
|
410
|
-
ext:
|
|
411
|
-
...
|
|
398
|
+
const buildRoute = {
|
|
399
|
+
id: createFileId(opts.routesDir, filePath, "Route"),
|
|
400
|
+
filePath,
|
|
401
|
+
pathname,
|
|
402
|
+
layouts: layouts.reverse(),
|
|
403
|
+
ext: sourceFile.ext,
|
|
404
|
+
...parseRoutePathname(opts.basePathname, pathname)
|
|
412
405
|
};
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
406
|
+
return buildRoute;
|
|
407
|
+
}
|
|
408
|
+
function resolveEntry(opts, sourceFile) {
|
|
409
|
+
const pathname = getPathnameFromDirPath(opts, sourceFile.dirPath);
|
|
410
|
+
const chunkFileName = pathname.slice(opts.basePathname.length);
|
|
411
|
+
const buildEntry = {
|
|
412
|
+
id: createFileId(opts.routesDir, sourceFile.filePath, "Route"),
|
|
413
|
+
filePath: sourceFile.filePath,
|
|
414
|
+
chunkFileName,
|
|
415
|
+
...parseRoutePathname(opts.basePathname, pathname)
|
|
421
416
|
};
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
417
|
+
return buildEntry;
|
|
418
|
+
}
|
|
419
|
+
function resolveServiceWorkerEntry(opts, sourceFile) {
|
|
420
|
+
const dirPathname = getPathnameFromDirPath(opts, sourceFile.dirPath);
|
|
421
|
+
const pathname = dirPathname + sourceFile.extlessName + ".js";
|
|
422
|
+
const chunkFileName = pathname.slice(opts.basePathname.length);
|
|
423
|
+
const buildEntry = {
|
|
424
|
+
id: createFileId(opts.routesDir, sourceFile.filePath, "ServiceWorker"),
|
|
425
|
+
filePath: sourceFile.filePath,
|
|
426
|
+
chunkFileName,
|
|
427
|
+
...parseRoutePathname(opts.basePathname, pathname)
|
|
430
428
|
};
|
|
429
|
+
return buildEntry;
|
|
431
430
|
}
|
|
432
|
-
async function
|
|
433
|
-
const
|
|
434
|
-
|
|
431
|
+
async function walkRoutes(routesDir) {
|
|
432
|
+
const sourceFiles = [];
|
|
433
|
+
await walkRouteDir(sourceFiles, normalizePath(routesDir), basename(routesDir));
|
|
434
|
+
return sourceFiles;
|
|
435
435
|
}
|
|
436
|
-
async function
|
|
437
|
-
const
|
|
436
|
+
async function walkRouteDir(sourceFiles, dirPath, dirName) {
|
|
437
|
+
const dirItemNames = await fs.promises.readdir(dirPath);
|
|
438
438
|
await Promise.all(
|
|
439
|
-
|
|
440
|
-
const
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
439
|
+
dirItemNames.map(async (itemName) => {
|
|
440
|
+
const itemPath = normalizePath(join(dirPath, itemName));
|
|
441
|
+
const stat = await fs.promises.stat(itemPath);
|
|
442
|
+
if (stat.isDirectory()) {
|
|
443
|
+
await walkRouteDir(sourceFiles, itemPath, itemName);
|
|
444
|
+
} else {
|
|
445
|
+
const sourceFileName = getSourceFile(itemName);
|
|
446
|
+
if (sourceFileName !== null) {
|
|
447
|
+
sourceFiles.push({
|
|
448
|
+
...sourceFileName,
|
|
449
|
+
fileName: itemName,
|
|
450
|
+
filePath: itemPath,
|
|
451
|
+
dirName,
|
|
452
|
+
dirPath
|
|
453
|
+
});
|
|
454
|
+
}
|
|
452
455
|
}
|
|
453
456
|
})
|
|
454
457
|
);
|
|
455
458
|
}
|
|
456
|
-
async function
|
|
457
|
-
const
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
459
|
+
async function walkServerPlugins(opts) {
|
|
460
|
+
const dirPath = opts.serverPluginsDir;
|
|
461
|
+
const dirItemNames = await fs.promises.readdir(dirPath);
|
|
462
|
+
const sourceFiles = [];
|
|
463
|
+
await Promise.all(
|
|
464
|
+
dirItemNames.map(async (itemName) => {
|
|
465
|
+
const itemPath = normalizePath(join(dirPath, itemName));
|
|
466
|
+
const ext = getExtension(itemName);
|
|
467
|
+
const extlessName = removeExtension(itemName);
|
|
468
|
+
if ((isModuleExt(ext) || isPageModuleExt(ext)) && isPluginModule(extlessName)) {
|
|
469
|
+
sourceFiles.push({
|
|
470
|
+
id: createFileId(opts.serverPluginsDir, itemPath, "Plugin"),
|
|
471
|
+
filePath: itemPath,
|
|
472
|
+
ext
|
|
473
|
+
});
|
|
474
|
+
}
|
|
466
475
|
})
|
|
467
|
-
)
|
|
476
|
+
);
|
|
477
|
+
return sourceFiles;
|
|
468
478
|
}
|
|
469
|
-
async function
|
|
479
|
+
async function parseRoutesDir(ctx) {
|
|
470
480
|
try {
|
|
471
|
-
await
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
nt(e.opts).then((n) => (e.serverPlugins = n, rt(e.opts.routesDir))).then((n) => {
|
|
484
|
-
const s = Ke(e.opts, n);
|
|
485
|
-
it(e, s), e.layouts = s.layouts, e.routes = s.routes, e.entries = s.entries, e.serviceWorkers = s.serviceWorkers, e.menus = s.menus, t();
|
|
486
|
-
}, r).finally(() => {
|
|
487
|
-
e.activeBuild = null;
|
|
488
|
-
});
|
|
489
|
-
})), e.activeBuild;
|
|
481
|
+
await updateRoutingContext(ctx);
|
|
482
|
+
validateBuild(ctx);
|
|
483
|
+
} catch (e) {
|
|
484
|
+
addError(ctx, e);
|
|
485
|
+
}
|
|
486
|
+
for (const d of ctx.diagnostics) {
|
|
487
|
+
if (d.type === "error") {
|
|
488
|
+
throw new Error(d.message);
|
|
489
|
+
} else {
|
|
490
|
+
console.warn(d.message);
|
|
491
|
+
}
|
|
492
|
+
}
|
|
490
493
|
}
|
|
491
|
-
function
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
}
|
|
509
|
-
function
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
494
|
+
function updateRoutingContext(ctx) {
|
|
495
|
+
ctx.activeBuild || (ctx.activeBuild = _updateRoutingContext(ctx).finally(() => {
|
|
496
|
+
ctx.activeBuild = null;
|
|
497
|
+
}));
|
|
498
|
+
return ctx.activeBuild;
|
|
499
|
+
}
|
|
500
|
+
async function _updateRoutingContext(ctx) {
|
|
501
|
+
const serverPlugins = await walkServerPlugins(ctx.opts);
|
|
502
|
+
const sourceFiles = await walkRoutes(ctx.opts.routesDir);
|
|
503
|
+
const resolved = resolveSourceFiles(ctx.opts, sourceFiles);
|
|
504
|
+
resolved.routes = rewriteRoutes(ctx, resolved.routes);
|
|
505
|
+
ctx.serverPlugins = serverPlugins;
|
|
506
|
+
ctx.layouts = resolved.layouts;
|
|
507
|
+
ctx.routes = resolved.routes;
|
|
508
|
+
ctx.entries = resolved.entries;
|
|
509
|
+
ctx.serviceWorkers = resolved.serviceWorkers;
|
|
510
|
+
ctx.menus = resolved.menus;
|
|
511
|
+
}
|
|
512
|
+
function rewriteRoutes(ctx, routes) {
|
|
513
|
+
if (!ctx.opts.rewriteRoutes) {
|
|
514
|
+
return routes;
|
|
515
|
+
}
|
|
516
|
+
const translatedRoutes = [];
|
|
517
|
+
let segmentsToTranslate = ctx.opts.rewriteRoutes.flatMap((rewriteConfig) => {
|
|
518
|
+
return Object.keys(rewriteConfig.paths || {});
|
|
519
|
+
});
|
|
520
|
+
segmentsToTranslate = Array.from(new Set(segmentsToTranslate));
|
|
521
|
+
routes.forEach((route) => {
|
|
522
|
+
translatedRoutes.push(route);
|
|
523
|
+
const currentRouteSegments = route.pathname.split("/");
|
|
524
|
+
const foundSegmentToTranslate = currentRouteSegments.some(
|
|
525
|
+
(segment) => segmentsToTranslate.includes(segment)
|
|
526
|
+
);
|
|
527
|
+
if (foundSegmentToTranslate || route.pathname === "/") {
|
|
528
|
+
ctx.opts.rewriteRoutes.forEach((config, configIndex) => {
|
|
529
|
+
if (route.pathname === "/" && !config.prefix) {
|
|
530
|
+
return;
|
|
531
|
+
}
|
|
532
|
+
const routeToPush = translateRoute(route, config, configIndex);
|
|
533
|
+
if (!translatedRoutes.some(
|
|
534
|
+
(item) => item.pathname === routeToPush.pathname && item.routeName === routeToPush.routeName
|
|
535
|
+
)) {
|
|
536
|
+
translatedRoutes.push(routeToPush);
|
|
537
|
+
}
|
|
538
|
+
});
|
|
539
|
+
}
|
|
540
|
+
});
|
|
541
|
+
return translatedRoutes.sort(routeSortCompare);
|
|
542
|
+
}
|
|
543
|
+
function translateRoute(route, config, configIndex) {
|
|
544
|
+
const replacePath = (part) => (config.paths || {})[part] ?? part;
|
|
545
|
+
const pathnamePrefix = config.prefix ? "/" + config.prefix : "";
|
|
546
|
+
const routeNamePrefix = config.prefix ? config.prefix + "/" : "";
|
|
547
|
+
const idSuffix = config.prefix?.toUpperCase().replace(/-/g, "");
|
|
548
|
+
const patternInfix = config.prefix ? [config.prefix] : [];
|
|
549
|
+
const splittedPathName = route.pathname.split("/");
|
|
550
|
+
const translatedPathParts = splittedPathName.map(replacePath);
|
|
551
|
+
const splittedRouteName = route.routeName.split("/");
|
|
552
|
+
const translatedRouteParts = splittedRouteName.map(replacePath);
|
|
553
|
+
const splittedPattern = route.pattern.toString().split("\\/");
|
|
554
|
+
const [translatedPatternFirst, ...translatedPatternOthers] = splittedPattern.map(replacePath);
|
|
555
|
+
const translatedPatternParts = [
|
|
556
|
+
translatedPatternFirst,
|
|
557
|
+
...patternInfix,
|
|
558
|
+
...translatedPatternOthers
|
|
559
|
+
];
|
|
560
|
+
const translatedPatternString = translatedPatternParts.join("\\/");
|
|
561
|
+
const translatedRegExp = translatedPatternString.substring(
|
|
515
562
|
1,
|
|
516
|
-
|
|
517
|
-
), b = e.segments.map(
|
|
518
|
-
(k) => k.map((A) => ({ ...A, content: n(A.content) }))
|
|
563
|
+
route.pathname === "/" ? translatedPatternString.length - 1 : translatedPatternString.length - 2
|
|
519
564
|
);
|
|
520
|
-
|
|
521
|
-
{
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
565
|
+
const translatedSegments = route.segments.map(
|
|
566
|
+
(segment) => segment.map((item) => ({ ...item, content: replacePath(item.content) }))
|
|
567
|
+
);
|
|
568
|
+
if (config.prefix) {
|
|
569
|
+
translatedSegments.splice(0, 0, [
|
|
570
|
+
{
|
|
571
|
+
content: config.prefix,
|
|
572
|
+
dynamic: false,
|
|
573
|
+
rest: false
|
|
574
|
+
}
|
|
575
|
+
]);
|
|
576
|
+
}
|
|
577
|
+
const translatedPath = translatedPathParts.join("/");
|
|
578
|
+
const translatedRoute = translatedRouteParts.join("/");
|
|
579
|
+
const routeToPush = {
|
|
580
|
+
...route,
|
|
581
|
+
id: route.id + (idSuffix || configIndex),
|
|
582
|
+
pathname: pathnamePrefix + translatedPath,
|
|
583
|
+
routeName: routeNamePrefix + (translatedRoute !== "/" ? translatedRoute : ""),
|
|
584
|
+
pattern: new RegExp(translatedRegExp),
|
|
585
|
+
segments: translatedSegments
|
|
535
586
|
};
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
`
|
|
546
|
-
|
|
587
|
+
return routeToPush;
|
|
588
|
+
}
|
|
589
|
+
function validateBuild(ctx) {
|
|
590
|
+
const pathnames = Array.from(new Set(ctx.routes.map((r) => r.pathname))).sort();
|
|
591
|
+
for (const pathname of pathnames) {
|
|
592
|
+
const foundRoutes = ctx.routes.filter((r) => r.pathname === pathname);
|
|
593
|
+
if (foundRoutes.length > 1) {
|
|
594
|
+
addError(
|
|
595
|
+
ctx,
|
|
596
|
+
`More than one route has been found for pathname "${pathname}". Please narrow it down to only one of these:
|
|
597
|
+
${foundRoutes.map((r) => ` - ${r.filePath}`).join("\n")}`
|
|
598
|
+
);
|
|
599
|
+
}
|
|
547
600
|
}
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
`The "top" layout feature, which is used by "${
|
|
601
|
+
ctx.layouts.filter((l) => l.layoutType === "top").forEach((l) => {
|
|
602
|
+
addWarning(
|
|
603
|
+
ctx,
|
|
604
|
+
`The "top" layout feature, which is used by "${l.filePath}" has been deprecated and will be removed from future versions. In most cases the "group" layout feature can be used in its place: https://qwik.dev/docs/advanced/routing/`
|
|
552
605
|
);
|
|
553
606
|
});
|
|
554
607
|
}
|
|
555
|
-
function
|
|
556
|
-
|
|
557
|
-
rootDir:
|
|
558
|
-
opts:
|
|
608
|
+
function createBuildContext(rootDir, viteBasePath, userOpts, target, dynamicImports) {
|
|
609
|
+
const ctx = {
|
|
610
|
+
rootDir: normalizePath(rootDir),
|
|
611
|
+
opts: normalizeOptions(rootDir, viteBasePath, userOpts),
|
|
559
612
|
routes: [],
|
|
560
613
|
serverPlugins: [],
|
|
561
614
|
layouts: [],
|
|
@@ -564,57 +617,105 @@ function ut(e, t, r, n, s) {
|
|
|
564
617
|
menus: [],
|
|
565
618
|
diagnostics: [],
|
|
566
619
|
frontmatter: /* @__PURE__ */ new Map(),
|
|
567
|
-
target:
|
|
568
|
-
dynamicImports:
|
|
569
|
-
isDirty:
|
|
620
|
+
target: target || "ssr",
|
|
621
|
+
dynamicImports: target === "client" || !!dynamicImports,
|
|
622
|
+
isDirty: true,
|
|
570
623
|
activeBuild: null
|
|
571
624
|
};
|
|
625
|
+
return ctx;
|
|
626
|
+
}
|
|
627
|
+
function resetBuildContext(ctx) {
|
|
628
|
+
if (ctx) {
|
|
629
|
+
ctx.routes.length = 0;
|
|
630
|
+
ctx.layouts.length = 0;
|
|
631
|
+
ctx.entries.length = 0;
|
|
632
|
+
ctx.menus.length = 0;
|
|
633
|
+
ctx.diagnostics.length = 0;
|
|
634
|
+
ctx.frontmatter.clear();
|
|
635
|
+
ctx.isDirty = true;
|
|
636
|
+
}
|
|
572
637
|
}
|
|
573
|
-
function
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
638
|
+
function normalizeOptions(rootDir, viteBasePath, userOpts) {
|
|
639
|
+
if (!(viteBasePath.startsWith("/") && viteBasePath.endsWith("/"))) {
|
|
640
|
+
console.error(
|
|
641
|
+
`warning: vite's config.base must begin and end with /. This will be an error in v2. If you have a valid use case, please open an issue.`
|
|
642
|
+
);
|
|
643
|
+
if (!viteBasePath.endsWith("/")) {
|
|
644
|
+
viteBasePath += "/";
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
const opts = { ...userOpts };
|
|
648
|
+
if (typeof opts.routesDir !== "string") {
|
|
649
|
+
opts.routesDir = resolve(rootDir, "src", "routes");
|
|
650
|
+
} else if (!isAbsolute(opts.routesDir)) {
|
|
651
|
+
opts.routesDir = resolve(rootDir, opts.routesDir);
|
|
652
|
+
}
|
|
653
|
+
opts.routesDir = normalizePath(opts.routesDir);
|
|
654
|
+
if (typeof opts.serverPluginsDir !== "string") {
|
|
655
|
+
opts.serverPluginsDir = opts.routesDir;
|
|
656
|
+
} else if (!isAbsolute(opts.serverPluginsDir)) {
|
|
657
|
+
opts.serverPluginsDir = resolve(rootDir, opts.serverPluginsDir);
|
|
658
|
+
}
|
|
659
|
+
opts.serverPluginsDir = normalizePath(opts.serverPluginsDir);
|
|
660
|
+
if (typeof opts.baseUrl === "string") {
|
|
661
|
+
opts.basePathname = opts.baseUrl;
|
|
662
|
+
}
|
|
663
|
+
if (typeof opts.basePathname !== "string") {
|
|
664
|
+
opts.basePathname = viteBasePath;
|
|
665
|
+
}
|
|
666
|
+
if (!opts.basePathname.endsWith("/")) {
|
|
667
|
+
console.error(
|
|
668
|
+
`Warning: qwik-router plugin basePathname must end with /. This will be an error in v2`
|
|
669
|
+
);
|
|
670
|
+
opts.basePathname += "/";
|
|
671
|
+
}
|
|
672
|
+
const url = new URL(opts.basePathname, "https://qwik.dev/");
|
|
673
|
+
opts.basePathname = url.pathname;
|
|
674
|
+
opts.mdx = opts.mdx || {};
|
|
675
|
+
opts.platform = opts.platform || {};
|
|
676
|
+
return opts;
|
|
677
|
+
}
|
|
678
|
+
function parseFrontmatter(ctx) {
|
|
679
|
+
return (mdast, vfile) => {
|
|
680
|
+
const attrs = {};
|
|
681
|
+
visit(mdast, "yaml", (node) => {
|
|
682
|
+
const parsedAttrs = parseFrontmatterAttrs(node.value);
|
|
683
|
+
for (const k in parsedAttrs) {
|
|
684
|
+
attrs[k] = parsedAttrs[k];
|
|
685
|
+
}
|
|
686
|
+
});
|
|
687
|
+
if (Object.keys(attrs).length > 0) {
|
|
688
|
+
ctx.frontmatter.set(normalizePath(vfile.path), attrs);
|
|
689
|
+
}
|
|
595
690
|
};
|
|
596
691
|
}
|
|
597
|
-
function
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
692
|
+
function parseFrontmatterAttrs(yaml) {
|
|
693
|
+
if (typeof yaml === "string") {
|
|
694
|
+
yaml = yaml.trim();
|
|
695
|
+
if (yaml !== "") {
|
|
696
|
+
return parse(yaml);
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
return null;
|
|
700
|
+
}
|
|
701
|
+
const metaNames = {
|
|
702
|
+
author: true,
|
|
703
|
+
creator: true,
|
|
704
|
+
"color-scheme": true,
|
|
705
|
+
description: true,
|
|
706
|
+
generator: true,
|
|
707
|
+
keywords: true,
|
|
708
|
+
publisher: true,
|
|
709
|
+
referrer: true,
|
|
710
|
+
robots: true,
|
|
711
|
+
"theme-color": true,
|
|
712
|
+
viewport: true
|
|
612
713
|
};
|
|
613
|
-
function
|
|
614
|
-
if (
|
|
615
|
-
const
|
|
616
|
-
if (
|
|
617
|
-
const
|
|
714
|
+
function frontmatterAttrsToDocumentHead(attrs) {
|
|
715
|
+
if (attrs != null && typeof attrs === "object") {
|
|
716
|
+
const attrNames = Object.keys(attrs);
|
|
717
|
+
if (attrNames.length > 0) {
|
|
718
|
+
const head = {
|
|
618
719
|
title: "",
|
|
619
720
|
meta: [],
|
|
620
721
|
styles: [],
|
|
@@ -622,108 +723,152 @@ function pt(e) {
|
|
|
622
723
|
scripts: [],
|
|
623
724
|
frontmatter: {}
|
|
624
725
|
};
|
|
625
|
-
for (const
|
|
626
|
-
const
|
|
627
|
-
if (
|
|
628
|
-
if (
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
726
|
+
for (const attrName of attrNames) {
|
|
727
|
+
const attrValue = attrs[attrName];
|
|
728
|
+
if (attrValue != null) {
|
|
729
|
+
if (attrName === "title") {
|
|
730
|
+
head.title = attrValue.toString();
|
|
731
|
+
head.title = head.title.replace(/\\@/g, "@");
|
|
732
|
+
} else if (attrName === "og" || attrName === "opengraph") {
|
|
733
|
+
if (typeof attrValue === "object") {
|
|
734
|
+
for (const opengraph of Array.isArray(attrValue) ? attrValue : [attrValue]) {
|
|
735
|
+
if (opengraph != null && typeof opengraph === "object" && !Array.isArray(opengraph)) {
|
|
736
|
+
for (const [property, content] of Object.entries(opengraph)) {
|
|
737
|
+
if ((property === "title" || property === "description") && content === true) {
|
|
738
|
+
if (attrNames.includes(property)) {
|
|
739
|
+
head.meta.push({
|
|
740
|
+
property: `og:${property}`,
|
|
741
|
+
content: attrs[property]?.toString()
|
|
742
|
+
});
|
|
743
|
+
}
|
|
744
|
+
} else {
|
|
745
|
+
head.meta.push({
|
|
746
|
+
property: `og:${property}`,
|
|
747
|
+
content: content?.toString()
|
|
748
|
+
});
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
}
|
|
752
|
+
}
|
|
642
753
|
}
|
|
643
|
-
} else
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
754
|
+
} else if (metaNames[attrName]) {
|
|
755
|
+
head.meta.push({
|
|
756
|
+
name: attrName,
|
|
757
|
+
content: attrValue.toString()
|
|
758
|
+
});
|
|
759
|
+
} else {
|
|
760
|
+
head.frontmatter[attrName] = attrValue;
|
|
761
|
+
}
|
|
762
|
+
}
|
|
647
763
|
}
|
|
648
|
-
return
|
|
764
|
+
return head;
|
|
649
765
|
}
|
|
650
766
|
}
|
|
651
767
|
return null;
|
|
652
768
|
}
|
|
653
|
-
function
|
|
654
|
-
return (
|
|
655
|
-
const
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
769
|
+
function rehypeSlug() {
|
|
770
|
+
return (ast) => {
|
|
771
|
+
const mdast = ast;
|
|
772
|
+
const slugs = new Slugger();
|
|
773
|
+
visit(mdast, "element", (node) => {
|
|
774
|
+
const level = headingRank(node);
|
|
775
|
+
if (level && node.properties) {
|
|
776
|
+
const text = toString(node);
|
|
777
|
+
if (!hasProperty(node, "id")) {
|
|
778
|
+
node.properties.id = slugs.slug(text);
|
|
779
|
+
}
|
|
660
780
|
}
|
|
661
781
|
});
|
|
662
782
|
};
|
|
663
783
|
}
|
|
664
|
-
function
|
|
665
|
-
return (
|
|
666
|
-
const
|
|
667
|
-
|
|
784
|
+
function rehypePage(ctx) {
|
|
785
|
+
return (ast, vfile) => {
|
|
786
|
+
const mdast = ast;
|
|
787
|
+
const sourcePath = normalizePath(vfile.path);
|
|
788
|
+
updateContentLinks(mdast, ctx.opts, sourcePath);
|
|
789
|
+
exportFrontmatter(ctx, mdast, sourcePath);
|
|
790
|
+
exportContentHead(ctx, mdast, sourcePath);
|
|
791
|
+
exportContentHeadings(mdast);
|
|
668
792
|
};
|
|
669
793
|
}
|
|
670
|
-
function
|
|
671
|
-
return (
|
|
672
|
-
|
|
673
|
-
|
|
794
|
+
function renameClassname() {
|
|
795
|
+
return (ast) => {
|
|
796
|
+
const mdast = ast;
|
|
797
|
+
visit(mdast, "element", (node) => {
|
|
798
|
+
if (node.properties) {
|
|
799
|
+
if (node.properties.className) {
|
|
800
|
+
node.properties.class = node.properties.className;
|
|
801
|
+
node.properties.className = void 0;
|
|
802
|
+
}
|
|
803
|
+
}
|
|
674
804
|
});
|
|
675
805
|
};
|
|
676
806
|
}
|
|
677
|
-
function
|
|
678
|
-
return (
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
807
|
+
function wrapTableWithDiv() {
|
|
808
|
+
return (ast) => {
|
|
809
|
+
const mdast = ast;
|
|
810
|
+
visit(mdast, "element", (node) => {
|
|
811
|
+
if (node.tagName === "table" && !node.done) {
|
|
812
|
+
const table = { ...node };
|
|
813
|
+
table.done = true;
|
|
814
|
+
node.tagName = "div";
|
|
815
|
+
node.properties = { className: "table-wrapper" };
|
|
816
|
+
node.children = [table];
|
|
683
817
|
}
|
|
684
818
|
});
|
|
685
819
|
};
|
|
686
820
|
}
|
|
687
|
-
function
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
821
|
+
function updateContentLinks(mdast, opts, sourcePath) {
|
|
822
|
+
visit(mdast, "element", (node) => {
|
|
823
|
+
const tagName = node && node.type === "element" && node.tagName.toLowerCase();
|
|
824
|
+
if (tagName === "a") {
|
|
825
|
+
const href = (node.properties && node.properties.href || "").trim();
|
|
826
|
+
if (isSameOriginUrl(href)) {
|
|
827
|
+
const ext = getExtension(href);
|
|
828
|
+
if (isMarkdownExt(ext)) {
|
|
829
|
+
node.properties.href = getMarkdownRelativeUrl(
|
|
830
|
+
opts,
|
|
831
|
+
sourcePath,
|
|
832
|
+
node.properties.href,
|
|
833
|
+
true
|
|
834
|
+
);
|
|
835
|
+
}
|
|
699
836
|
}
|
|
700
837
|
}
|
|
701
838
|
});
|
|
702
839
|
}
|
|
703
|
-
function
|
|
704
|
-
const
|
|
705
|
-
|
|
706
|
-
}
|
|
707
|
-
function
|
|
708
|
-
const
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
840
|
+
function exportFrontmatter(ctx, mdast, sourcePath) {
|
|
841
|
+
const attrs = ctx.frontmatter.get(sourcePath);
|
|
842
|
+
createExport(mdast, "frontmatter", attrs);
|
|
843
|
+
}
|
|
844
|
+
function exportContentHead(ctx, mdast, sourcePath) {
|
|
845
|
+
const attrs = ctx.frontmatter.get(sourcePath);
|
|
846
|
+
const head = frontmatterAttrsToDocumentHead(attrs);
|
|
847
|
+
if (head) {
|
|
848
|
+
createExport(mdast, "head", head);
|
|
849
|
+
}
|
|
850
|
+
}
|
|
851
|
+
function exportContentHeadings(mdast) {
|
|
852
|
+
const headings = [];
|
|
853
|
+
visit(mdast, "element", (node) => {
|
|
854
|
+
const level = headingRank(node);
|
|
855
|
+
if (level && node.properties) {
|
|
856
|
+
if (hasProperty(node, "id")) {
|
|
857
|
+
const text = toString(node);
|
|
858
|
+
headings.push({
|
|
859
|
+
text,
|
|
860
|
+
id: node.properties.id,
|
|
861
|
+
level
|
|
862
|
+
});
|
|
863
|
+
}
|
|
722
864
|
}
|
|
723
|
-
})
|
|
865
|
+
});
|
|
866
|
+
if (headings.length > 0) {
|
|
867
|
+
createExport(mdast, "headings", headings);
|
|
868
|
+
}
|
|
724
869
|
}
|
|
725
|
-
function
|
|
726
|
-
const
|
|
870
|
+
function createExport(mdast, identifierName, val) {
|
|
871
|
+
const mdxjsEsm = {
|
|
727
872
|
type: "mdxjsEsm",
|
|
728
873
|
value: "",
|
|
729
874
|
data: {
|
|
@@ -742,8 +887,8 @@ function z(e, t, r) {
|
|
|
742
887
|
declarations: [
|
|
743
888
|
{
|
|
744
889
|
type: "VariableDeclarator",
|
|
745
|
-
id: { type: "Identifier", name:
|
|
746
|
-
init:
|
|
890
|
+
id: { type: "Identifier", name: identifierName },
|
|
891
|
+
init: valueToEstree(val)
|
|
747
892
|
}
|
|
748
893
|
]
|
|
749
894
|
}
|
|
@@ -752,393 +897,420 @@ function z(e, t, r) {
|
|
|
752
897
|
}
|
|
753
898
|
}
|
|
754
899
|
};
|
|
755
|
-
|
|
756
|
-
}
|
|
757
|
-
const
|
|
758
|
-
function
|
|
759
|
-
const
|
|
760
|
-
return
|
|
761
|
-
}
|
|
762
|
-
function
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
900
|
+
mdast.children.unshift(mdxjsEsm);
|
|
901
|
+
}
|
|
902
|
+
const own = {}.hasOwnProperty;
|
|
903
|
+
function hasProperty(node, propName) {
|
|
904
|
+
const value = node && typeof node === "object" && node.type === "element" && node.properties && own.call(node.properties, propName) && node.properties[propName];
|
|
905
|
+
return value != null && value !== false;
|
|
906
|
+
}
|
|
907
|
+
function rehypeSyntaxHighlight() {
|
|
908
|
+
refractor.register(tsxLang);
|
|
909
|
+
return async (ast) => {
|
|
910
|
+
visit(ast, "element", (node, _index, parent) => {
|
|
911
|
+
if (!parent || parent.tagName !== "pre" || node.tagName !== "code" || !Array.isArray(node.properties.className)) {
|
|
912
|
+
return;
|
|
913
|
+
}
|
|
914
|
+
for (let i = 0; i < node.properties.className.length; i++) {
|
|
915
|
+
const className = node.properties.className[i];
|
|
916
|
+
const lang = getLanguage(className);
|
|
917
|
+
if (lang && refractor.registered(lang)) {
|
|
918
|
+
node.properties.className[i] = "language-" + lang;
|
|
919
|
+
syntaxHighlight(node, lang);
|
|
920
|
+
return;
|
|
772
921
|
}
|
|
922
|
+
}
|
|
773
923
|
});
|
|
774
924
|
};
|
|
775
925
|
}
|
|
776
|
-
function
|
|
777
|
-
const
|
|
778
|
-
|
|
926
|
+
function syntaxHighlight(node, lang) {
|
|
927
|
+
const code = toString(node);
|
|
928
|
+
const result = refractor.highlight(code, lang);
|
|
929
|
+
if (result && Array.isArray(node.children)) {
|
|
930
|
+
node.children = result.children;
|
|
931
|
+
}
|
|
779
932
|
}
|
|
780
|
-
function
|
|
781
|
-
|
|
933
|
+
function getLanguage(className) {
|
|
934
|
+
if (typeof className === "string") {
|
|
935
|
+
className = className.toLowerCase();
|
|
936
|
+
if (className.startsWith("language-")) {
|
|
937
|
+
return className.slice(9);
|
|
938
|
+
}
|
|
939
|
+
}
|
|
940
|
+
return null;
|
|
782
941
|
}
|
|
783
|
-
async function
|
|
784
|
-
const { compile
|
|
785
|
-
|
|
786
|
-
const
|
|
787
|
-
|
|
788
|
-
const
|
|
789
|
-
|
|
942
|
+
async function createMdxTransformer(ctx) {
|
|
943
|
+
const { compile } = await import("@mdx-js/mdx");
|
|
944
|
+
const { default: remarkFrontmatter } = await import("remark-frontmatter");
|
|
945
|
+
const { default: remarkGfm } = await import("remark-gfm");
|
|
946
|
+
const { default: rehypeAutolinkHeadings } = await import("rehype-autolink-headings");
|
|
947
|
+
const { VFile } = await import("vfile");
|
|
948
|
+
const userMdxOpts = ctx.opts.mdx;
|
|
949
|
+
const userRemarkPlugins = userMdxOpts.remarkPlugins || [];
|
|
950
|
+
const userRehypePlugins = userMdxOpts.rehypePlugins || [];
|
|
951
|
+
const coreMdxPlugins = ctx.opts.mdxPlugins;
|
|
952
|
+
const coreRemarkPlugins = [];
|
|
953
|
+
if (typeof coreMdxPlugins?.remarkGfm === "undefined" || coreMdxPlugins.remarkGfm) {
|
|
954
|
+
coreRemarkPlugins.push(remarkGfm);
|
|
955
|
+
}
|
|
956
|
+
const coreRehypePlugins = [];
|
|
957
|
+
if (typeof coreMdxPlugins?.rehypeSyntaxHighlight === "undefined" || coreMdxPlugins.rehypeSyntaxHighlight) {
|
|
958
|
+
coreRehypePlugins.push(rehypeSyntaxHighlight);
|
|
959
|
+
}
|
|
960
|
+
if (typeof coreMdxPlugins?.rehypeAutolinkHeadings === "undefined" || coreMdxPlugins.rehypeAutolinkHeadings) {
|
|
961
|
+
coreRehypePlugins.push(rehypeAutolinkHeadings);
|
|
962
|
+
}
|
|
963
|
+
const options = {
|
|
964
|
+
SourceMapGenerator,
|
|
790
965
|
jsxImportSource: "@qwik.dev/core",
|
|
791
|
-
...
|
|
966
|
+
...userMdxOpts,
|
|
792
967
|
elementAttributeNameCase: "html",
|
|
793
968
|
remarkPlugins: [
|
|
794
|
-
...
|
|
795
|
-
...
|
|
796
|
-
|
|
797
|
-
[
|
|
969
|
+
...userRemarkPlugins,
|
|
970
|
+
...coreRemarkPlugins,
|
|
971
|
+
remarkFrontmatter,
|
|
972
|
+
[parseFrontmatter, ctx]
|
|
798
973
|
],
|
|
799
974
|
rehypePlugins: [
|
|
800
|
-
|
|
801
|
-
...
|
|
802
|
-
...
|
|
803
|
-
[
|
|
804
|
-
|
|
805
|
-
|
|
975
|
+
rehypeSlug,
|
|
976
|
+
...userRehypePlugins,
|
|
977
|
+
...coreRehypePlugins,
|
|
978
|
+
[rehypePage, ctx],
|
|
979
|
+
renameClassname,
|
|
980
|
+
wrapTableWithDiv
|
|
806
981
|
]
|
|
807
982
|
};
|
|
808
|
-
return async function(
|
|
809
|
-
const
|
|
810
|
-
if ([".mdx", ".md", ".markdown"].includes(
|
|
811
|
-
const
|
|
812
|
-
|
|
983
|
+
return async function(code, id) {
|
|
984
|
+
const ext = getExtension(id);
|
|
985
|
+
if ([".mdx", ".md", ".markdown"].includes(ext)) {
|
|
986
|
+
const file = new VFile({ value: code, path: id });
|
|
987
|
+
const compiled = await compile(file, options);
|
|
988
|
+
const output = String(compiled.value);
|
|
989
|
+
const addImport = `import { jsx } from '@qwik.dev/core';
|
|
990
|
+
`;
|
|
991
|
+
const newDefault = `
|
|
813
992
|
function _missingMdxReference(id, component, place) {
|
|
814
|
-
throw new Error("${
|
|
993
|
+
throw new Error("${id}: Expected " + (component ? "component" : "object") + " \`" + id + "\` to be defined: you likely forgot to import, pass, or provide it." + (place ? "\\nIt’s referenced in your code at \`" + place + "\`" : ""));
|
|
815
994
|
}
|
|
816
995
|
const WrappedMdxContent = () => {
|
|
817
996
|
const content = _createMdxContent({});
|
|
818
997
|
return typeof MDXLayout === 'function' ? jsx(MDXLayout, {children: content}) : content;
|
|
819
998
|
};
|
|
820
999
|
export default WrappedMdxContent;
|
|
821
|
-
|
|
822
|
-
|
|
1000
|
+
`;
|
|
1001
|
+
const exportIndex = output.lastIndexOf("export default ");
|
|
1002
|
+
if (exportIndex === -1) {
|
|
823
1003
|
throw new Error("Could not find default export in mdx output");
|
|
1004
|
+
}
|
|
1005
|
+
const wrappedOutput = addImport + output.slice(0, exportIndex) + newDefault;
|
|
824
1006
|
return {
|
|
825
|
-
code:
|
|
826
|
-
map:
|
|
1007
|
+
code: wrappedOutput,
|
|
1008
|
+
map: compiled.map
|
|
827
1009
|
};
|
|
828
1010
|
}
|
|
829
1011
|
};
|
|
830
1012
|
}
|
|
831
|
-
function
|
|
832
|
-
const
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
`
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
/** Qwik Router Entries (${r.length}) */`);
|
|
841
|
-
for (let n = 0; n < r.length; n++) {
|
|
842
|
-
const s = r[n];
|
|
843
|
-
t.push(`export const ${s.id} = () => import(${JSON.stringify(s.filePath)});`);
|
|
844
|
-
}
|
|
845
|
-
return t.join(`
|
|
846
|
-
`) + `
|
|
847
|
-
`;
|
|
1013
|
+
function createEntries(ctx, c) {
|
|
1014
|
+
const isClient = ctx.target === "client";
|
|
1015
|
+
const entries = [...ctx.entries, ...ctx.serviceWorkers];
|
|
1016
|
+
if (isClient && entries.length > 0) {
|
|
1017
|
+
c.push(`
|
|
1018
|
+
/** Qwik Router Entries Entry */`);
|
|
1019
|
+
c.push(`export const e = () => import("@qwik-router-entries");
|
|
1020
|
+
`);
|
|
1021
|
+
}
|
|
848
1022
|
}
|
|
849
|
-
function
|
|
850
|
-
const
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
for (const o of e.menus) {
|
|
858
|
-
const a = JSON.stringify(W(o.filePath));
|
|
859
|
-
if (s)
|
|
860
|
-
t.push(` [${JSON.stringify(o.pathname)}, ()=>import(${a})],`);
|
|
861
|
-
else {
|
|
862
|
-
const u = I(i, o.filePath);
|
|
863
|
-
r.push(`import * as ${u} from ${a};`), t.push(` [${JSON.stringify(o.pathname)}, ()=>${u}],`);
|
|
864
|
-
}
|
|
1023
|
+
function generateQwikRouterEntries(ctx) {
|
|
1024
|
+
const c = [];
|
|
1025
|
+
const entries = [...ctx.entries, ...ctx.serviceWorkers];
|
|
1026
|
+
c.push(`
|
|
1027
|
+
/** Qwik Router Entries (${entries.length}) */`);
|
|
1028
|
+
for (let i = 0; i < entries.length; i++) {
|
|
1029
|
+
const entry = entries[i];
|
|
1030
|
+
c.push(`export const ${entry.id} = () => import(${JSON.stringify(entry.filePath)});`);
|
|
865
1031
|
}
|
|
866
|
-
|
|
1032
|
+
return c.join("\n") + "\n";
|
|
867
1033
|
}
|
|
868
|
-
function
|
|
869
|
-
const
|
|
870
|
-
if (
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
1034
|
+
function getImportPath(importPath) {
|
|
1035
|
+
const lowerCasePath = importPath.toLowerCase();
|
|
1036
|
+
if (lowerCasePath.endsWith(".tsx") || lowerCasePath.endsWith(".jsx")) {
|
|
1037
|
+
return importPath.slice(0, importPath.length - 4);
|
|
1038
|
+
}
|
|
1039
|
+
if (lowerCasePath.endsWith(".ts")) {
|
|
1040
|
+
return importPath.slice(0, importPath.length - 3);
|
|
1041
|
+
}
|
|
1042
|
+
return importPath;
|
|
1043
|
+
}
|
|
1044
|
+
function createMenus(ctx, c, esmImports, isSSR) {
|
|
1045
|
+
c.push(`
|
|
1046
|
+
/** Qwik Router Menus (${ctx.menus.length}) */`);
|
|
1047
|
+
c.push(`export const menus = [`);
|
|
1048
|
+
const dynamicImports = !isSSR;
|
|
1049
|
+
const routesDir = ctx.opts.routesDir;
|
|
1050
|
+
for (const m of ctx.menus) {
|
|
1051
|
+
const importPath = JSON.stringify(getImportPath(m.filePath));
|
|
1052
|
+
if (dynamicImports) {
|
|
1053
|
+
c.push(` [${JSON.stringify(m.pathname)}, ()=>import(${importPath})],`);
|
|
1054
|
+
} else {
|
|
1055
|
+
const id = createFileId(routesDir, m.filePath);
|
|
1056
|
+
esmImports.push(`import * as ${id} from ${importPath};`);
|
|
1057
|
+
c.push(` [${JSON.stringify(m.pathname)}, ()=>${id}],`);
|
|
1058
|
+
}
|
|
1059
|
+
}
|
|
1060
|
+
c.push(`];`);
|
|
1061
|
+
}
|
|
1062
|
+
function createRoutes(ctx, qwikPlugin, c, esmImports, isSSR) {
|
|
1063
|
+
const includeEndpoints = isSSR;
|
|
1064
|
+
const dynamicImports = ctx.dynamicImports;
|
|
1065
|
+
if (ctx.layouts.length > 0) {
|
|
1066
|
+
c.push(`
|
|
1067
|
+
/** Qwik Router Layouts (${ctx.layouts.length}) */`);
|
|
1068
|
+
for (const layout of ctx.layouts) {
|
|
1069
|
+
const importPath = JSON.stringify(getImportPath(layout.filePath));
|
|
1070
|
+
if (dynamicImports) {
|
|
1071
|
+
c.push(`const ${layout.id} = ()=>import(${importPath});`);
|
|
1072
|
+
} else {
|
|
1073
|
+
esmImports.push(`import * as ${layout.id}_ from ${importPath};`);
|
|
1074
|
+
c.push(`const ${layout.id} = ()=>${layout.id}_;`);
|
|
1075
|
+
}
|
|
876
1076
|
}
|
|
877
1077
|
}
|
|
878
|
-
|
|
879
|
-
/** Qwik Router Routes (${
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
1078
|
+
c.push(`
|
|
1079
|
+
/** Qwik Router Routes (${ctx.routes.length}) */`);
|
|
1080
|
+
c.push(`export const routes = [`);
|
|
1081
|
+
for (const route of ctx.routes) {
|
|
1082
|
+
const layouts = [];
|
|
1083
|
+
if (isPageExt(route.ext)) {
|
|
1084
|
+
for (const layout of route.layouts) {
|
|
1085
|
+
layouts.push(layout.id);
|
|
1086
|
+
}
|
|
1087
|
+
const importPath = getImportPath(route.filePath);
|
|
1088
|
+
if (dynamicImports) {
|
|
1089
|
+
layouts.push(`()=>import(${JSON.stringify(importPath)})`);
|
|
1090
|
+
} else {
|
|
1091
|
+
esmImports.push(`import * as ${route.id} from ${JSON.stringify(importPath)};`);
|
|
1092
|
+
layouts.push(`()=>${route.id}`);
|
|
1093
|
+
}
|
|
1094
|
+
} else if (includeEndpoints && isModuleExt(route.ext)) {
|
|
1095
|
+
const importPath = getImportPath(route.filePath);
|
|
1096
|
+
esmImports.push(`import * as ${route.id} from ${JSON.stringify(importPath)};`);
|
|
1097
|
+
for (const layout of route.layouts) {
|
|
1098
|
+
layouts.push(layout.id);
|
|
1099
|
+
}
|
|
1100
|
+
layouts.push(`()=>${route.id}`);
|
|
893
1101
|
}
|
|
894
|
-
|
|
895
|
-
}
|
|
896
|
-
|
|
897
|
-
}
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
1102
|
+
if (layouts.length > 0) {
|
|
1103
|
+
c.push(` ${createRouteData(qwikPlugin, route, layouts, isSSR)},`);
|
|
1104
|
+
}
|
|
1105
|
+
}
|
|
1106
|
+
c.push(`];`);
|
|
1107
|
+
}
|
|
1108
|
+
function createRouteData(qwikPlugin, r, layouts, isSsr) {
|
|
1109
|
+
const routeName = JSON.stringify(r.routeName);
|
|
1110
|
+
const moduleLayouts = `[ ${layouts.join(", ")} ]`;
|
|
1111
|
+
if (isSsr) {
|
|
1112
|
+
const originalPathname = JSON.stringify(r.pathname);
|
|
1113
|
+
const clientBundleNames = JSON.stringify(getClientRouteBundleNames(qwikPlugin, r));
|
|
1114
|
+
return `[ ${routeName}, ${moduleLayouts}, ${originalPathname}, ${clientBundleNames} ]`;
|
|
1115
|
+
}
|
|
1116
|
+
return `[ ${routeName}, ${moduleLayouts} ]`;
|
|
1117
|
+
}
|
|
1118
|
+
function getClientRouteBundleNames(qwikPlugin, r) {
|
|
1119
|
+
const bundlesNames = [];
|
|
1120
|
+
const manifest = qwikPlugin.api.getManifest();
|
|
1121
|
+
if (manifest) {
|
|
1122
|
+
const manifestBundleNames = Object.keys(manifest.bundles);
|
|
1123
|
+
const addRouteFile = (filePath) => {
|
|
1124
|
+
filePath = removeExtension(filePath);
|
|
1125
|
+
for (const bundleName of manifestBundleNames) {
|
|
1126
|
+
const bundle = manifest.bundles[bundleName];
|
|
1127
|
+
if (bundle.origins) {
|
|
1128
|
+
for (const bundleOrigin of bundle.origins) {
|
|
1129
|
+
const originPath = removeExtension(bundleOrigin);
|
|
1130
|
+
if (filePath.endsWith(originPath)) {
|
|
1131
|
+
if (!bundlesNames.includes(bundleName)) {
|
|
1132
|
+
bundlesNames.push(bundleName);
|
|
1133
|
+
}
|
|
1134
|
+
}
|
|
917
1135
|
}
|
|
1136
|
+
}
|
|
918
1137
|
}
|
|
919
1138
|
};
|
|
920
|
-
for (const
|
|
921
|
-
|
|
922
|
-
i(t.filePath);
|
|
923
|
-
}
|
|
924
|
-
return r;
|
|
925
|
-
}
|
|
926
|
-
function Wt(e, t, r, n, s) {
|
|
927
|
-
if (r.push(`
|
|
928
|
-
/** Qwik Router ServerPlugins (${e.serverPlugins.length}) */`), r.push("export const serverPlugins = ["), s) {
|
|
929
|
-
for (const i of e.serverPlugins) {
|
|
930
|
-
const o = JSON.stringify(W(i.filePath));
|
|
931
|
-
n.push(`import * as ${i.id} from ${o};`);
|
|
1139
|
+
for (const layout of r.layouts) {
|
|
1140
|
+
addRouteFile(layout.filePath);
|
|
932
1141
|
}
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
}
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
1142
|
+
addRouteFile(r.filePath);
|
|
1143
|
+
}
|
|
1144
|
+
return bundlesNames;
|
|
1145
|
+
}
|
|
1146
|
+
function createServerPlugins(ctx, _qwikPlugin, c, esmImports, isSSR) {
|
|
1147
|
+
c.push(`
|
|
1148
|
+
/** Qwik Router ServerPlugins (${ctx.serverPlugins.length}) */`);
|
|
1149
|
+
c.push(`export const serverPlugins = [`);
|
|
1150
|
+
if (isSSR) {
|
|
1151
|
+
for (const file of ctx.serverPlugins) {
|
|
1152
|
+
const importPath = JSON.stringify(getImportPath(file.filePath));
|
|
1153
|
+
esmImports.push(`import * as ${file.id} from ${importPath};`);
|
|
1154
|
+
}
|
|
1155
|
+
for (const file of ctx.serverPlugins) {
|
|
1156
|
+
c.push(` ${file.id},`);
|
|
1157
|
+
}
|
|
1158
|
+
}
|
|
1159
|
+
c.push(`];`);
|
|
1160
|
+
}
|
|
1161
|
+
function generateQwikRouterConfig(ctx, qwikPlugin, isSSR) {
|
|
1162
|
+
const esmImports = [];
|
|
1163
|
+
const c = [];
|
|
1164
|
+
c.push(`
|
|
1165
|
+
/** Qwik Router Config */`);
|
|
1166
|
+
c.push(`
|
|
1167
|
+
import { isDev } from '@qwik.dev/core/build';`);
|
|
1168
|
+
createServerPlugins(ctx, qwikPlugin, c, esmImports, isSSR);
|
|
1169
|
+
createRoutes(ctx, qwikPlugin, c, esmImports, isSSR);
|
|
1170
|
+
createMenus(ctx, c, esmImports, isSSR);
|
|
1171
|
+
createEntries(ctx, c);
|
|
1172
|
+
c.push(`export const trailingSlash = ${JSON.stringify(!globalThis.__NO_TRAILING_SLASH__)};`);
|
|
1173
|
+
c.push(`export const basePathname = ${JSON.stringify(ctx.opts.basePathname)};`);
|
|
1174
|
+
c.push(`export const cacheModules = !isDev;`);
|
|
1175
|
+
c.push(
|
|
1176
|
+
`export default { routes, serverPlugins, menus, trailingSlash, basePathname, cacheModules };`
|
|
1177
|
+
);
|
|
1178
|
+
return esmImports.join("\n") + c.join("\n");
|
|
1179
|
+
}
|
|
1180
|
+
function generateServiceWorkerRegister(ctx, swRegister2) {
|
|
1181
|
+
let swReg;
|
|
1182
|
+
let swUrl = "/service-worker.js";
|
|
1183
|
+
if (ctx.serviceWorkers.length === 0) {
|
|
1184
|
+
swReg = SW_UNREGISTER;
|
|
1185
|
+
} else {
|
|
1186
|
+
swReg = swRegister2;
|
|
1187
|
+
const sw = ctx.serviceWorkers.sort(
|
|
1188
|
+
(a, b) => a.chunkFileName.length < b.chunkFileName.length ? -1 : 1
|
|
956
1189
|
)[0];
|
|
957
|
-
|
|
1190
|
+
swUrl = ctx.opts.basePathname + sw.chunkFileName;
|
|
958
1191
|
}
|
|
959
|
-
|
|
1192
|
+
swReg = swReg.replace("__url", swUrl);
|
|
1193
|
+
return `export default ${JSON.stringify(swReg)};`;
|
|
960
1194
|
}
|
|
961
|
-
const
|
|
1195
|
+
const SW_UNREGISTER = `
|
|
962
1196
|
"serviceWorker"in navigator&&navigator.serviceWorker.getRegistrations().then(r=>{for(const e of r){const c='__url'.split("/").pop();e.active?.scriptURL.endsWith(c||"service-worker.js")&&e.unregister().catch(console.error)}}),"caches"in window&&caches.keys().then(r=>{const e=r.find(c=>c.startsWith("QwikBuild"));e&&caches.delete(e).catch(console.error)}).catch(console.error)
|
|
963
1197
|
`;
|
|
964
|
-
function
|
|
965
|
-
const
|
|
966
|
-
|
|
967
|
-
const
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
1198
|
+
function getRouteImports(routes, manifest) {
|
|
1199
|
+
const result = {};
|
|
1200
|
+
routes.forEach((route) => {
|
|
1201
|
+
const routePath = removeExtension(route.filePath);
|
|
1202
|
+
const layoutPaths = route.layouts ? route.layouts.map((layout) => removeExtension(layout.filePath)) : [];
|
|
1203
|
+
const routeAndLayoutPaths = [routePath, ...layoutPaths];
|
|
1204
|
+
const bundles = [];
|
|
1205
|
+
for (const [bundleName, bundle] of Object.entries(manifest.bundles)) {
|
|
1206
|
+
if (isBundlePartOfRoute(bundle, routeAndLayoutPaths)) {
|
|
1207
|
+
bundles.push(bundleName);
|
|
1208
|
+
}
|
|
1209
|
+
}
|
|
1210
|
+
if (bundles.length > 0) {
|
|
1211
|
+
result[route.routeName] = { dynamicImports: bundles };
|
|
1212
|
+
}
|
|
971
1213
|
});
|
|
972
|
-
for (const
|
|
973
|
-
const
|
|
974
|
-
if (
|
|
975
|
-
|
|
976
|
-
...
|
|
977
|
-
dynamicImports:
|
|
978
|
-
(
|
|
1214
|
+
for (const bundleName of Object.keys(manifest.bundles)) {
|
|
1215
|
+
const bundle = manifest.bundles[bundleName];
|
|
1216
|
+
if (bundle.origins?.some((s) => s.endsWith(QWIK_ROUTER_CONFIG_ID))) {
|
|
1217
|
+
result[bundleName] = {
|
|
1218
|
+
...bundle,
|
|
1219
|
+
dynamicImports: bundle.dynamicImports?.filter(
|
|
1220
|
+
(d) => manifest.bundles[d].origins?.some((s) => s.endsWith("menu.md"))
|
|
979
1221
|
)
|
|
980
1222
|
};
|
|
981
1223
|
break;
|
|
982
1224
|
}
|
|
983
1225
|
}
|
|
984
|
-
return
|
|
985
|
-
}
|
|
986
|
-
function
|
|
987
|
-
if (!
|
|
988
|
-
return
|
|
989
|
-
for (const r of e.origins) {
|
|
990
|
-
const n = S(r);
|
|
991
|
-
return t.some((s) => s.endsWith(n));
|
|
992
|
-
}
|
|
993
|
-
}
|
|
994
|
-
const Ht = (e) => {
|
|
995
|
-
const t = e.stack;
|
|
996
|
-
if (typeof t == "string") {
|
|
997
|
-
const r = t.split(`
|
|
998
|
-
`).filter((n) => !n.includes("/node_modules/") && !n.includes("(node:"));
|
|
999
|
-
for (let n = 1; n < r.length; n++) {
|
|
1000
|
-
const s = r[n].replace("file:///", "/");
|
|
1001
|
-
if (/^\s+at/.test(s)) {
|
|
1002
|
-
const i = s.indexOf("/"), o = s.lastIndexOf(")", i);
|
|
1003
|
-
if (i > 0) {
|
|
1004
|
-
const u = s.slice(i, o).split(":"), c = V(u[u.length - 1]), l = V(u[u.length - 2]);
|
|
1005
|
-
return typeof c == "number" && typeof l == "number" ? (u.length -= 2, {
|
|
1006
|
-
file: u.join(":"),
|
|
1007
|
-
line: l,
|
|
1008
|
-
column: c
|
|
1009
|
-
}) : typeof c == "number" ? (u.length -= 1, {
|
|
1010
|
-
file: u.join(":"),
|
|
1011
|
-
line: c,
|
|
1012
|
-
column: void 0
|
|
1013
|
-
}) : {
|
|
1014
|
-
file: u.join(":"),
|
|
1015
|
-
line: void 0,
|
|
1016
|
-
column: void 0
|
|
1017
|
-
};
|
|
1018
|
-
}
|
|
1019
|
-
}
|
|
1020
|
-
}
|
|
1226
|
+
return result;
|
|
1227
|
+
}
|
|
1228
|
+
function isBundlePartOfRoute(bundle, routeAndLayoutPaths) {
|
|
1229
|
+
if (!bundle.origins) {
|
|
1230
|
+
return false;
|
|
1021
1231
|
}
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
return
|
|
1025
|
-
} catch {
|
|
1026
|
-
return;
|
|
1232
|
+
for (const bundleOrigin of bundle.origins) {
|
|
1233
|
+
const originPath = removeExtension(bundleOrigin);
|
|
1234
|
+
return routeAndLayoutPaths.some((path2) => path2.endsWith(originPath));
|
|
1027
1235
|
}
|
|
1028
|
-
}, he = /\r?\n/, Y = 2;
|
|
1029
|
-
function qt(e, t) {
|
|
1030
|
-
if (typeof t == "number")
|
|
1031
|
-
return t;
|
|
1032
|
-
if (t.lo != null)
|
|
1033
|
-
return t.lo;
|
|
1034
|
-
const r = e.split(he), { line: n, column: s } = t;
|
|
1035
|
-
let i = 0;
|
|
1036
|
-
for (let o = 0; o < n - 1 && o < r.length; o++)
|
|
1037
|
-
i += r[o].length + 1;
|
|
1038
|
-
return i + s;
|
|
1039
|
-
}
|
|
1040
|
-
function Ft(e, t = 0, r) {
|
|
1041
|
-
t = qt(e, t), r = r || t;
|
|
1042
|
-
const n = e.split(he);
|
|
1043
|
-
let s = 0;
|
|
1044
|
-
const i = [];
|
|
1045
|
-
for (let o = 0; o < n.length; o++)
|
|
1046
|
-
if (s += n[o].length + 1, s >= t) {
|
|
1047
|
-
for (let a = o - Y; a <= o + Y || r > s; a++) {
|
|
1048
|
-
if (a < 0 || a >= n.length)
|
|
1049
|
-
continue;
|
|
1050
|
-
const u = a + 1;
|
|
1051
|
-
i.push(`${u}${" ".repeat(Math.max(3 - String(u).length, 0))}| ${n[a]}`);
|
|
1052
|
-
const c = n[a].length;
|
|
1053
|
-
if (a === o) {
|
|
1054
|
-
const l = Math.max(t - (s - c) + 1, 0), f = Math.max(1, r > s ? c - l : r - t);
|
|
1055
|
-
i.push(" | " + " ".repeat(l) + "^".repeat(f));
|
|
1056
|
-
} else if (a > o) {
|
|
1057
|
-
if (r > s) {
|
|
1058
|
-
const l = Math.max(Math.min(r - s, c), 1);
|
|
1059
|
-
i.push(" | " + "^".repeat(l));
|
|
1060
|
-
}
|
|
1061
|
-
s += c + 1;
|
|
1062
|
-
}
|
|
1063
|
-
}
|
|
1064
|
-
break;
|
|
1065
|
-
}
|
|
1066
|
-
return i.join(`
|
|
1067
|
-
`);
|
|
1068
|
-
}
|
|
1069
|
-
function X(e) {
|
|
1070
|
-
const [t, r] = e.split("?"), n = r || "";
|
|
1071
|
-
return {
|
|
1072
|
-
originalId: e,
|
|
1073
|
-
pathId: t,
|
|
1074
|
-
query: n ? `?${r}` : "",
|
|
1075
|
-
params: new URLSearchParams(n)
|
|
1076
|
-
};
|
|
1077
1236
|
}
|
|
1078
|
-
function
|
|
1079
|
-
const
|
|
1237
|
+
function imagePlugin(userOpts) {
|
|
1238
|
+
const supportedExtensions = [".jpg", ".jpeg", ".png", ".webp", ".gif", ".avif", ".tiff"];
|
|
1080
1239
|
return [
|
|
1081
1240
|
import("vite-imagetools").then(
|
|
1082
|
-
({ imagetools
|
|
1241
|
+
({ imagetools }) => imagetools({
|
|
1083
1242
|
exclude: [],
|
|
1084
|
-
extendOutputFormats(
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1243
|
+
extendOutputFormats(builtins) {
|
|
1244
|
+
const jsx = () => (metadatas) => {
|
|
1245
|
+
const srcSet = metadatas.map((meta) => `${meta.src} ${meta.width}w`).join(", ");
|
|
1246
|
+
let largestImage;
|
|
1247
|
+
let largestImageSize = 0;
|
|
1248
|
+
for (let i = 0; i < metadatas.length; i++) {
|
|
1249
|
+
const m = metadatas[i];
|
|
1250
|
+
if (m.width > largestImageSize) {
|
|
1251
|
+
largestImage = m;
|
|
1252
|
+
largestImageSize = m.width;
|
|
1093
1253
|
}
|
|
1094
|
-
return {
|
|
1095
|
-
srcSet: o,
|
|
1096
|
-
width: a?.width,
|
|
1097
|
-
height: a?.height
|
|
1098
|
-
};
|
|
1099
1254
|
}
|
|
1255
|
+
return {
|
|
1256
|
+
srcSet,
|
|
1257
|
+
width: largestImage === null || largestImage === void 0 ? void 0 : largestImage.width,
|
|
1258
|
+
height: largestImage === null || largestImage === void 0 ? void 0 : largestImage.height
|
|
1259
|
+
};
|
|
1260
|
+
};
|
|
1261
|
+
return {
|
|
1262
|
+
...builtins,
|
|
1263
|
+
jsx
|
|
1100
1264
|
};
|
|
1101
1265
|
},
|
|
1102
|
-
defaultDirectives: (
|
|
1103
|
-
if (
|
|
1104
|
-
const { jsx:
|
|
1266
|
+
defaultDirectives: (url) => {
|
|
1267
|
+
if (url.searchParams.has("jsx")) {
|
|
1268
|
+
const { jsx: _, ...params } = Object.fromEntries(url.searchParams.entries());
|
|
1105
1269
|
return new URLSearchParams({
|
|
1106
1270
|
format: "webp",
|
|
1107
1271
|
quality: "75",
|
|
1108
1272
|
w: "200;400;600;800;1200",
|
|
1109
1273
|
withoutEnlargement: "",
|
|
1110
|
-
...
|
|
1111
|
-
...
|
|
1274
|
+
...userOpts?.imageOptimization?.jsxDirectives,
|
|
1275
|
+
...params,
|
|
1112
1276
|
as: "jsx"
|
|
1113
1277
|
});
|
|
1114
1278
|
}
|
|
1115
1279
|
return new URLSearchParams();
|
|
1116
1280
|
}
|
|
1117
1281
|
})
|
|
1118
|
-
).catch((
|
|
1282
|
+
).catch((err) => {
|
|
1283
|
+
console.error("Error loading vite-imagetools, image imports are not available", err);
|
|
1284
|
+
return null;
|
|
1285
|
+
}),
|
|
1119
1286
|
{
|
|
1120
1287
|
name: "qwik-router-image-jsx",
|
|
1121
1288
|
load: {
|
|
1122
1289
|
order: "pre",
|
|
1123
|
-
handler: async (
|
|
1124
|
-
const { params
|
|
1125
|
-
|
|
1290
|
+
handler: async (id) => {
|
|
1291
|
+
const { params, pathId } = parseId(id);
|
|
1292
|
+
const extension = path.extname(pathId).toLowerCase();
|
|
1293
|
+
if (extension === ".svg" && params.has("jsx")) {
|
|
1294
|
+
const code = await fs.promises.readFile(pathId, "utf-8");
|
|
1126
1295
|
return {
|
|
1127
|
-
code
|
|
1128
|
-
moduleSideEffects:
|
|
1296
|
+
code,
|
|
1297
|
+
moduleSideEffects: false
|
|
1129
1298
|
};
|
|
1299
|
+
}
|
|
1130
1300
|
}
|
|
1131
1301
|
},
|
|
1132
|
-
transform(
|
|
1133
|
-
|
|
1134
|
-
const { params
|
|
1135
|
-
if (
|
|
1136
|
-
const
|
|
1137
|
-
if (
|
|
1138
|
-
|
|
1139
|
-
|
|
1302
|
+
transform(code, id) {
|
|
1303
|
+
id = id.toLowerCase();
|
|
1304
|
+
const { params, pathId } = parseId(id);
|
|
1305
|
+
if (params.has("jsx")) {
|
|
1306
|
+
const extension = path.extname(pathId).toLowerCase();
|
|
1307
|
+
if (supportedExtensions.includes(extension)) {
|
|
1308
|
+
if (!code.includes("srcSet")) {
|
|
1309
|
+
this.error(`Image '${id}' could not be optimized to JSX`);
|
|
1310
|
+
}
|
|
1311
|
+
const index = code.indexOf("export default");
|
|
1140
1312
|
return {
|
|
1141
|
-
code:
|
|
1313
|
+
code: code.slice(0, index) + `
|
|
1142
1314
|
import { _jsxSorted } from '@qwik.dev/core';
|
|
1143
1315
|
const PROPS = {srcSet, width, height};
|
|
1144
1316
|
export default function (props, key, _, dev) {
|
|
@@ -1146,12 +1318,12 @@ function Bt(e) {
|
|
|
1146
1318
|
}`,
|
|
1147
1319
|
map: null
|
|
1148
1320
|
};
|
|
1149
|
-
} else if (
|
|
1150
|
-
const { svgAttributes
|
|
1321
|
+
} else if (extension === ".svg") {
|
|
1322
|
+
const { svgAttributes } = optimizeSvg({ code, path: pathId }, userOpts);
|
|
1151
1323
|
return {
|
|
1152
1324
|
code: `
|
|
1153
1325
|
import { _jsxSorted } from '@qwik.dev/core';
|
|
1154
|
-
const PROPS = ${JSON.stringify(
|
|
1326
|
+
const PROPS = ${JSON.stringify(svgAttributes)};
|
|
1155
1327
|
export default function (props, key, _, dev) {
|
|
1156
1328
|
return _jsxSorted('svg', props, PROPS, undefined, 3, key, dev);
|
|
1157
1329
|
}`,
|
|
@@ -1164,130 +1336,175 @@ function Bt(e) {
|
|
|
1164
1336
|
}
|
|
1165
1337
|
];
|
|
1166
1338
|
}
|
|
1167
|
-
function
|
|
1168
|
-
const
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1339
|
+
function optimizeSvg({ code, path: path2 }, userOpts) {
|
|
1340
|
+
const svgAttributes = {};
|
|
1341
|
+
const prefixIdsConfiguration = userOpts?.imageOptimization?.svgo?.prefixIds;
|
|
1342
|
+
const maybePrefixIdsPlugin = prefixIdsConfiguration !== false ? [{ name: "prefixIds", params: prefixIdsConfiguration }] : [];
|
|
1343
|
+
const userPlugins = userOpts?.imageOptimization?.svgo?.plugins?.filter((plugin) => {
|
|
1344
|
+
if (plugin === "preset-default" || typeof plugin === "object" && plugin.name === "preset-default") {
|
|
1345
|
+
console.warn(
|
|
1346
|
+
`You are trying to use the preset-default SVGO plugin. This plugin is already included by default, you can customize it through the defaultPresetOverrides option.`
|
|
1347
|
+
);
|
|
1348
|
+
return false;
|
|
1349
|
+
}
|
|
1350
|
+
if (plugin === "prefixIds" || typeof plugin === "object" && plugin.name === "prefixIds") {
|
|
1351
|
+
console.warn(
|
|
1352
|
+
`You are trying to use the preset-default SVGO plugin. This plugin is already included by default, you can customize it through the prefixIds option.`
|
|
1353
|
+
);
|
|
1354
|
+
return false;
|
|
1355
|
+
}
|
|
1356
|
+
return true;
|
|
1357
|
+
}) || [];
|
|
1358
|
+
const data = optimize(code, {
|
|
1359
|
+
floatPrecision: userOpts?.imageOptimization?.svgo?.floatPrecision,
|
|
1360
|
+
multipass: userOpts?.imageOptimization?.svgo?.multipass,
|
|
1361
|
+
path: path2,
|
|
1176
1362
|
plugins: [
|
|
1177
1363
|
{
|
|
1178
1364
|
name: "preset-default",
|
|
1179
1365
|
params: {
|
|
1180
1366
|
overrides: {
|
|
1181
|
-
removeViewBox:
|
|
1182
|
-
...
|
|
1367
|
+
removeViewBox: false,
|
|
1368
|
+
...userOpts?.imageOptimization?.svgo?.defaultPresetOverrides
|
|
1183
1369
|
}
|
|
1184
1370
|
}
|
|
1185
1371
|
},
|
|
1186
1372
|
{
|
|
1187
1373
|
name: "customPluginName",
|
|
1188
|
-
fn: () =>
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1374
|
+
fn: () => {
|
|
1375
|
+
return {
|
|
1376
|
+
element: {
|
|
1377
|
+
exit: (node) => {
|
|
1378
|
+
if (node.name === "svg") {
|
|
1379
|
+
node.name = "g";
|
|
1380
|
+
Object.assign(svgAttributes, node.attributes);
|
|
1381
|
+
node.attributes = {};
|
|
1382
|
+
}
|
|
1383
|
+
}
|
|
1192
1384
|
}
|
|
1193
|
-
}
|
|
1194
|
-
}
|
|
1385
|
+
};
|
|
1386
|
+
}
|
|
1195
1387
|
},
|
|
1196
|
-
...
|
|
1197
|
-
...
|
|
1388
|
+
...maybePrefixIdsPlugin,
|
|
1389
|
+
...userPlugins
|
|
1198
1390
|
]
|
|
1199
1391
|
}).data;
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1392
|
+
svgAttributes.dangerouslySetInnerHTML = data.slice(3, -4);
|
|
1393
|
+
return {
|
|
1394
|
+
data,
|
|
1395
|
+
svgAttributes
|
|
1203
1396
|
};
|
|
1204
1397
|
}
|
|
1205
|
-
async function
|
|
1206
|
-
if (typeof
|
|
1207
|
-
throw new Error(
|
|
1208
|
-
|
|
1398
|
+
async function validatePlugin(opts) {
|
|
1399
|
+
if (typeof opts.routesDir !== "string") {
|
|
1400
|
+
throw new Error(`qwikRouter plugin "routesDir" option missing`);
|
|
1401
|
+
}
|
|
1402
|
+
if (!isAbsolute(opts.routesDir)) {
|
|
1209
1403
|
throw new Error(
|
|
1210
|
-
`qwikRouter plugin "routesDir" option must be an absolute path: ${
|
|
1404
|
+
`qwikRouter plugin "routesDir" option must be an absolute path: ${opts.routesDir}`
|
|
1211
1405
|
);
|
|
1406
|
+
}
|
|
1212
1407
|
try {
|
|
1213
|
-
|
|
1408
|
+
const s = await fs.promises.stat(opts.routesDir);
|
|
1409
|
+
if (!s.isDirectory()) {
|
|
1214
1410
|
throw new Error(
|
|
1215
|
-
`qwikRouter plugin "routesDir" option must be a directory: ${
|
|
1411
|
+
`qwikRouter plugin "routesDir" option must be a directory: ${opts.routesDir}`
|
|
1216
1412
|
);
|
|
1217
|
-
} catch (t) {
|
|
1218
|
-
throw new Error(`qwikRouter plugin "routesDir" not found: ${t}`);
|
|
1219
|
-
}
|
|
1220
|
-
}
|
|
1221
|
-
function Gt(e) {
|
|
1222
|
-
if (e instanceof Error) {
|
|
1223
|
-
const t = e;
|
|
1224
|
-
let r = t.loc;
|
|
1225
|
-
if (!t.frame && !t.plugin && (r || (r = Ht(t)), r && (t.loc = r, r.file))) {
|
|
1226
|
-
t.id = v(t.loc.file);
|
|
1227
|
-
try {
|
|
1228
|
-
const n = x.readFileSync(t.loc.file, "utf-8");
|
|
1229
|
-
t.frame = Ft(n, t.loc);
|
|
1230
|
-
} catch {
|
|
1231
|
-
}
|
|
1232
1413
|
}
|
|
1414
|
+
} catch (e) {
|
|
1415
|
+
throw new Error(`qwikRouter plugin "routesDir" not found: ${e}`);
|
|
1233
1416
|
}
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
this.
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1417
|
+
}
|
|
1418
|
+
class HtmlTransformPatcher {
|
|
1419
|
+
constructor(req, res, server) {
|
|
1420
|
+
__publicField(this, "state", 0);
|
|
1421
|
+
__publicField(this, "buffer", "");
|
|
1422
|
+
__publicField(this, "headInnerIndex", -1);
|
|
1423
|
+
__publicField(this, "bodyInnerIndex", -1);
|
|
1424
|
+
__publicField(this, "isHtmlResponse", false);
|
|
1425
|
+
__publicField(this, "bodyPostContent", "");
|
|
1426
|
+
__publicField(this, "response");
|
|
1427
|
+
__publicField(this, "server");
|
|
1428
|
+
__publicField(this, "request");
|
|
1429
|
+
__publicField(this, "origWrite");
|
|
1430
|
+
__publicField(this, "origEnd");
|
|
1431
|
+
__publicField(this, "origSetHeader");
|
|
1432
|
+
__publicField(this, "origWriteHead");
|
|
1433
|
+
__publicField(this, "processingPromise", null);
|
|
1434
|
+
this.request = req;
|
|
1435
|
+
this.response = res;
|
|
1436
|
+
this.server = server;
|
|
1437
|
+
this.origWrite = this.response.write.bind(this.response);
|
|
1438
|
+
this.origEnd = this.response.end.bind(this.response);
|
|
1439
|
+
this.origSetHeader = this.response.setHeader.bind(this.response);
|
|
1440
|
+
this.origWriteHead = this.response.writeHead.bind(this.response);
|
|
1441
|
+
this.response.setHeader = (name, value) => {
|
|
1442
|
+
if (name.toLowerCase() === "content-type") {
|
|
1443
|
+
const contentType = String(value).toLowerCase();
|
|
1444
|
+
this.isHtmlResponse = contentType.includes("text/html");
|
|
1445
|
+
}
|
|
1446
|
+
return this.origSetHeader(name, value);
|
|
1447
|
+
};
|
|
1448
|
+
this.response.writeHead = (statusCode, statusMessage, headers) => {
|
|
1449
|
+
if (typeof statusMessage === "object" && statusMessage !== null) {
|
|
1450
|
+
headers = statusMessage;
|
|
1451
|
+
statusMessage = void 0;
|
|
1256
1452
|
}
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
const c = String(u).toLowerCase();
|
|
1263
|
-
this.isHtmlResponse = c.includes("text/html");
|
|
1453
|
+
if (headers && typeof headers === "object") {
|
|
1454
|
+
for (const [key, value] of Object.entries(headers)) {
|
|
1455
|
+
if (key.toLowerCase() === "content-type") {
|
|
1456
|
+
const contentType = String(value).toLowerCase();
|
|
1457
|
+
this.isHtmlResponse = contentType.includes("text/html");
|
|
1264
1458
|
}
|
|
1459
|
+
}
|
|
1265
1460
|
}
|
|
1266
|
-
return this.origWriteHead(
|
|
1267
|
-
}
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1461
|
+
return this.origWriteHead(statusCode, statusMessage, headers);
|
|
1462
|
+
};
|
|
1463
|
+
this.response.write = this.handleWrite.bind(this);
|
|
1464
|
+
this.response.end = (chunk, encoding, callback) => {
|
|
1465
|
+
this.handleEnd(chunk, encoding, callback).catch((error) => {
|
|
1466
|
+
console.error("Error in handleEnd:", error);
|
|
1467
|
+
this.transitionToPassthrough();
|
|
1468
|
+
this.origEnd(chunk, encoding, callback);
|
|
1469
|
+
});
|
|
1470
|
+
return this.response;
|
|
1471
|
+
};
|
|
1472
|
+
}
|
|
1473
|
+
handleWrite(chunk, encoding, callback) {
|
|
1474
|
+
if (!this.isHtmlResponse || this.state === 3) {
|
|
1475
|
+
return this.origWrite(chunk, encoding, callback);
|
|
1476
|
+
}
|
|
1477
|
+
if (typeof encoding === "function") {
|
|
1478
|
+
callback = encoding;
|
|
1479
|
+
encoding = void 0;
|
|
1480
|
+
}
|
|
1481
|
+
let data;
|
|
1482
|
+
if (chunk instanceof ArrayBuffer || chunk instanceof Uint8Array || chunk instanceof Uint16Array || chunk instanceof Uint32Array) {
|
|
1483
|
+
data = new TextDecoder().decode(chunk);
|
|
1484
|
+
} else if (Buffer.isBuffer(chunk)) {
|
|
1485
|
+
data = chunk.toString(encoding || "utf8");
|
|
1486
|
+
} else if (typeof chunk === "string") {
|
|
1487
|
+
data = chunk;
|
|
1488
|
+
} else {
|
|
1489
|
+
data = chunk?.toString() || "";
|
|
1490
|
+
}
|
|
1491
|
+
this.buffer += data;
|
|
1492
|
+
switch (this.state) {
|
|
1277
1493
|
case 0:
|
|
1278
1494
|
if (this.headInnerIndex === -1) {
|
|
1279
|
-
const
|
|
1280
|
-
if (
|
|
1281
|
-
const
|
|
1282
|
-
this.headInnerIndex =
|
|
1495
|
+
const headMatch = this.buffer.match(/<head[^>]*>/i);
|
|
1496
|
+
if (headMatch) {
|
|
1497
|
+
const headOuterIndex = this.buffer.indexOf(headMatch[0]);
|
|
1498
|
+
this.headInnerIndex = headOuterIndex + headMatch[0].length;
|
|
1283
1499
|
}
|
|
1284
1500
|
}
|
|
1285
1501
|
if (this.headInnerIndex !== -1) {
|
|
1286
|
-
const
|
|
1287
|
-
if (
|
|
1502
|
+
const bodyMatch = this.buffer.slice(this.headInnerIndex).match(/<body[^>]*>/i);
|
|
1503
|
+
if (bodyMatch) {
|
|
1288
1504
|
this.state = 1;
|
|
1289
|
-
const
|
|
1290
|
-
this.bodyInnerIndex =
|
|
1505
|
+
const bodyOuterIndex = this.buffer.indexOf(bodyMatch[0]);
|
|
1506
|
+
this.bodyInnerIndex = bodyOuterIndex + bodyMatch[0].length;
|
|
1507
|
+
this.processingPromise = this.processHead();
|
|
1291
1508
|
}
|
|
1292
1509
|
}
|
|
1293
1510
|
break;
|
|
@@ -1299,333 +1516,485 @@ class zt {
|
|
|
1299
1516
|
default:
|
|
1300
1517
|
throw new Error(`Invalid state: ${this.state}`);
|
|
1301
1518
|
}
|
|
1302
|
-
|
|
1519
|
+
callback?.();
|
|
1520
|
+
return true;
|
|
1303
1521
|
}
|
|
1304
1522
|
async processHead() {
|
|
1305
1523
|
try {
|
|
1306
|
-
const
|
|
1524
|
+
const fakeHtml = "<html><head>[FAKE_HEAD]</head><body>[FAKE_BODY]</body></html>";
|
|
1525
|
+
const transformedHtml = await this.server.transformIndexHtml(
|
|
1307
1526
|
this.request.url || "/",
|
|
1308
|
-
|
|
1309
|
-
)
|
|
1310
|
-
|
|
1527
|
+
fakeHtml
|
|
1528
|
+
);
|
|
1529
|
+
const fakeHeadIndex = transformedHtml.indexOf("[FAKE_HEAD]");
|
|
1530
|
+
const fakeHeadCloseIndex = transformedHtml.indexOf("</head>", fakeHeadIndex);
|
|
1531
|
+
if (fakeHeadIndex === -1 || fakeHeadCloseIndex === -1) {
|
|
1311
1532
|
throw new Error("Transformed HTML does not contain [FAKE_HEAD]...</head>");
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1533
|
+
}
|
|
1534
|
+
const headPreContent = transformedHtml.slice("<html><head>".length, fakeHeadIndex).trim();
|
|
1535
|
+
const headPostContent = transformedHtml.slice(
|
|
1536
|
+
fakeHeadIndex + "[FAKE_HEAD]".length,
|
|
1537
|
+
fakeHeadCloseIndex
|
|
1538
|
+
);
|
|
1539
|
+
const fakeBodyStartIndex = transformedHtml.indexOf("<body>", fakeHeadCloseIndex);
|
|
1540
|
+
const fakeBodyIndex = transformedHtml.indexOf("[FAKE_BODY]", fakeBodyStartIndex);
|
|
1541
|
+
const fakeBodyEndIndex = transformedHtml.indexOf("</body>", fakeBodyIndex);
|
|
1542
|
+
if (fakeBodyIndex === -1 || fakeBodyEndIndex === -1) {
|
|
1317
1543
|
throw new Error("Transformed HTML does not contain [FAKE_BODY]...</body>");
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1544
|
+
}
|
|
1545
|
+
const bodyPreContent = transformedHtml.slice(
|
|
1546
|
+
fakeBodyStartIndex + "<body>".length,
|
|
1547
|
+
fakeBodyIndex
|
|
1321
1548
|
);
|
|
1322
|
-
this.bodyPostContent =
|
|
1323
|
-
|
|
1324
|
-
|
|
1549
|
+
this.bodyPostContent = transformedHtml.slice(
|
|
1550
|
+
fakeBodyIndex + "[FAKE_BODY]".length,
|
|
1551
|
+
fakeBodyEndIndex
|
|
1325
1552
|
);
|
|
1326
|
-
const
|
|
1327
|
-
if (
|
|
1553
|
+
const headCloseIndex = this.buffer.indexOf("</head>", this.headInnerIndex);
|
|
1554
|
+
if (headCloseIndex === -1) {
|
|
1328
1555
|
throw new Error("Buffered HTML does not contain </head>");
|
|
1329
|
-
|
|
1330
|
-
|
|
1556
|
+
}
|
|
1557
|
+
this.buffer = this.buffer.slice(0, this.headInnerIndex) + headPreContent + this.buffer.slice(this.headInnerIndex, headCloseIndex) + headPostContent + this.buffer.slice(headCloseIndex, this.bodyInnerIndex) + bodyPreContent + this.buffer.slice(this.bodyInnerIndex);
|
|
1558
|
+
if (this.bodyPostContent.length > 0) {
|
|
1559
|
+
this.state = 2;
|
|
1560
|
+
this.handleStreamingBodyState();
|
|
1331
1561
|
return;
|
|
1332
1562
|
}
|
|
1333
1563
|
this.transitionToPassthrough();
|
|
1334
1564
|
return;
|
|
1335
|
-
} catch (
|
|
1336
|
-
console.error("Error transforming HTML:",
|
|
1565
|
+
} catch (error) {
|
|
1566
|
+
console.error("Error transforming HTML:", error);
|
|
1567
|
+
this.transitionToPassthrough();
|
|
1337
1568
|
return;
|
|
1338
1569
|
}
|
|
1339
1570
|
}
|
|
1340
1571
|
handleStreamingBodyState() {
|
|
1341
|
-
const
|
|
1342
|
-
if (
|
|
1343
|
-
const
|
|
1344
|
-
this.buffer = this.buffer.slice(0,
|
|
1572
|
+
const bodyEndMatch = this.buffer.match(/<\/body>/i);
|
|
1573
|
+
if (bodyEndMatch) {
|
|
1574
|
+
const bodyEndPos = this.buffer.indexOf(bodyEndMatch[0]);
|
|
1575
|
+
this.buffer = this.buffer.slice(0, bodyEndPos) + this.bodyPostContent + this.buffer.slice(bodyEndPos);
|
|
1576
|
+
this.transitionToPassthrough();
|
|
1345
1577
|
return;
|
|
1346
1578
|
}
|
|
1347
1579
|
this.flushBuffer(6);
|
|
1348
1580
|
}
|
|
1349
1581
|
transitionToPassthrough() {
|
|
1350
|
-
this.state = 3
|
|
1582
|
+
this.state = 3;
|
|
1583
|
+
this.flushBuffer();
|
|
1351
1584
|
}
|
|
1352
|
-
flushBuffer(
|
|
1353
|
-
this.buffer.length >
|
|
1585
|
+
flushBuffer(keep = 0) {
|
|
1586
|
+
if (this.buffer.length > keep) {
|
|
1587
|
+
if (keep > 0) {
|
|
1588
|
+
this.origWrite(this.buffer.slice(0, -keep));
|
|
1589
|
+
this.buffer = this.buffer.slice(-keep);
|
|
1590
|
+
} else {
|
|
1591
|
+
this.origWrite(this.buffer);
|
|
1592
|
+
this.buffer = "";
|
|
1593
|
+
}
|
|
1594
|
+
}
|
|
1354
1595
|
}
|
|
1355
|
-
async handleEnd(
|
|
1356
|
-
typeof
|
|
1596
|
+
async handleEnd(chunk, encoding, callback) {
|
|
1597
|
+
if (typeof encoding === "function") {
|
|
1598
|
+
callback = encoding;
|
|
1599
|
+
encoding = void 0;
|
|
1600
|
+
}
|
|
1601
|
+
if (chunk) {
|
|
1602
|
+
this.handleWrite(chunk, encoding);
|
|
1603
|
+
}
|
|
1604
|
+
await this.processingPromise;
|
|
1605
|
+
this.flushBuffer();
|
|
1606
|
+
this.origEnd(callback);
|
|
1357
1607
|
}
|
|
1358
1608
|
}
|
|
1359
|
-
function
|
|
1360
|
-
|
|
1609
|
+
function wrapResponseForHtmlTransform(request, response, server) {
|
|
1610
|
+
new HtmlTransformPatcher(request, response, server);
|
|
1611
|
+
return response;
|
|
1361
1612
|
}
|
|
1362
|
-
const
|
|
1363
|
-
const
|
|
1364
|
-
if (!
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
const
|
|
1369
|
-
if (
|
|
1370
|
-
|
|
1371
|
-
|
|
1613
|
+
const makeRouterDevMiddleware = (server, ctx) => async (req, res, next) => {
|
|
1614
|
+
const mod = await server.ssrLoadModule("src/entry.ssr");
|
|
1615
|
+
if (!mod.default) {
|
|
1616
|
+
console.error("No default export found in src/entry.ssr");
|
|
1617
|
+
return next();
|
|
1618
|
+
}
|
|
1619
|
+
const renderer = mod.default;
|
|
1620
|
+
if (ctx.isDirty) {
|
|
1621
|
+
await updateRoutingContext(ctx);
|
|
1622
|
+
ctx.isDirty = false;
|
|
1623
|
+
}
|
|
1624
|
+
const entry = ctx.entries.find((e) => req.url === `${server.config.base}${e.chunkFileName}`);
|
|
1625
|
+
if (entry) {
|
|
1626
|
+
const entryContents = await server.transformRequest(
|
|
1627
|
+
`/@fs${entry.filePath.startsWith("/") ? "" : "/"}${entry.filePath}`
|
|
1372
1628
|
);
|
|
1373
|
-
|
|
1629
|
+
if (entryContents) {
|
|
1630
|
+
res.setHeader("Content-Type", "text/javascript");
|
|
1631
|
+
res.end(entryContents.code);
|
|
1632
|
+
} else {
|
|
1633
|
+
next();
|
|
1634
|
+
}
|
|
1374
1635
|
return;
|
|
1375
1636
|
}
|
|
1376
|
-
if (
|
|
1377
|
-
|
|
1378
|
-
|
|
1637
|
+
if (req.url === `${server.config.base}service-worker.js`) {
|
|
1638
|
+
res.setHeader("Content-Type", "text/javascript");
|
|
1639
|
+
res.end(
|
|
1640
|
+
`/* Qwik Router Dev Service Worker */self.addEventListener('install', () => self.skipWaiting());self.addEventListener('activate', (ev) => ev.waitUntil(self.clients.claim()));`
|
|
1379
1641
|
);
|
|
1380
1642
|
return;
|
|
1381
1643
|
}
|
|
1382
1644
|
globalThis.__qwik = void 0;
|
|
1383
|
-
const { createQwikRouter
|
|
1645
|
+
const { createQwikRouter } = await server.ssrLoadModule(
|
|
1384
1646
|
"@qwik.dev/router/middleware/node"
|
|
1385
1647
|
);
|
|
1386
1648
|
try {
|
|
1387
|
-
const
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1649
|
+
const render = (async (opts) => {
|
|
1650
|
+
return await renderer(opts);
|
|
1651
|
+
});
|
|
1652
|
+
const { router, staticFile, notFound } = createQwikRouter({ render });
|
|
1653
|
+
const wrappedRes = wrapResponseForHtmlTransform(req, res, server);
|
|
1654
|
+
staticFile(req, wrappedRes, () => {
|
|
1655
|
+
router(req, wrappedRes, () => {
|
|
1656
|
+
notFound(req, wrappedRes, next);
|
|
1391
1657
|
});
|
|
1392
1658
|
});
|
|
1393
|
-
} catch (
|
|
1394
|
-
|
|
1659
|
+
} catch (e) {
|
|
1660
|
+
if (e instanceof Error) {
|
|
1661
|
+
server.ssrFixStacktrace(e);
|
|
1662
|
+
formatError(e);
|
|
1663
|
+
}
|
|
1664
|
+
next(e);
|
|
1395
1665
|
return;
|
|
1396
1666
|
}
|
|
1397
|
-
}
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1667
|
+
};
|
|
1668
|
+
const CSS_EXTENSIONS = [".css", ".scss", ".sass", ".less", ".styl", ".stylus"];
|
|
1669
|
+
const JS_EXTENSIONS = /\.[mc]?[tj]sx?$/;
|
|
1670
|
+
const isCssPath = (url) => CSS_EXTENSIONS.some((ext) => url.endsWith(ext));
|
|
1671
|
+
const getCssUrls = (server) => {
|
|
1672
|
+
const cssModules = /* @__PURE__ */ new Set();
|
|
1673
|
+
const cssImportedByCSS = /* @__PURE__ */ new Set();
|
|
1674
|
+
Array.from(server.moduleGraph.fileToModulesMap.entries()).forEach(([_name, modules]) => {
|
|
1675
|
+
modules.forEach((mod) => {
|
|
1676
|
+
const [pathId, query] = mod.url.split("?");
|
|
1677
|
+
if (!query && isCssPath(pathId)) {
|
|
1678
|
+
const isEntryCSS = mod.importers.size === 0;
|
|
1679
|
+
const hasCSSImporter = Array.from(mod.importers).some((importer) => {
|
|
1680
|
+
const importerPath = importer.url || importer.file;
|
|
1681
|
+
const isCSS = importerPath && isCssPath(importerPath);
|
|
1682
|
+
if (isCSS && mod.url) {
|
|
1683
|
+
cssImportedByCSS.add(mod.url);
|
|
1684
|
+
}
|
|
1685
|
+
return isCSS;
|
|
1686
|
+
});
|
|
1687
|
+
const hasJSImporter = Array.from(mod.importers).some((importer) => {
|
|
1688
|
+
const importerPath = importer.url || importer.file;
|
|
1689
|
+
return importerPath && JS_EXTENSIONS.test(importerPath);
|
|
1409
1690
|
});
|
|
1410
|
-
(
|
|
1691
|
+
if ((isEntryCSS || hasJSImporter) && !hasCSSImporter && !cssImportedByCSS.has(mod.url)) {
|
|
1692
|
+
cssModules.add(mod);
|
|
1693
|
+
}
|
|
1411
1694
|
}
|
|
1412
1695
|
});
|
|
1413
|
-
})
|
|
1414
|
-
|
|
1696
|
+
});
|
|
1697
|
+
return [...cssModules].map(
|
|
1698
|
+
({ url, lastHMRTimestamp }) => `${url}${lastHMRTimestamp ? `?t=${lastHMRTimestamp}` : ""}`
|
|
1415
1699
|
);
|
|
1416
|
-
}
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
}
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
return
|
|
1700
|
+
};
|
|
1701
|
+
const getRouterIndexTags = (server) => {
|
|
1702
|
+
const cssUrls = getCssUrls(server);
|
|
1703
|
+
return cssUrls.map((url) => ({
|
|
1704
|
+
tag: "link",
|
|
1705
|
+
attrs: { rel: "stylesheet", href: url }
|
|
1706
|
+
}));
|
|
1707
|
+
};
|
|
1708
|
+
const QWIK_ROUTER_CONFIG_ID = "@qwik-router-config";
|
|
1709
|
+
const QWIK_ROUTER_ENTRIES_ID = "@qwik-router-entries";
|
|
1710
|
+
const QWIK_ROUTER = "@qwik.dev/router";
|
|
1711
|
+
const QWIK_ROUTER_SW_REGISTER = "@qwik-router-sw-register";
|
|
1712
|
+
function qwikCity(userOpts) {
|
|
1713
|
+
return qwikRouter(userOpts);
|
|
1714
|
+
}
|
|
1715
|
+
function qwikRouter(userOpts) {
|
|
1716
|
+
return [qwikRouterPlugin(userOpts), ...imagePlugin(userOpts)];
|
|
1717
|
+
}
|
|
1718
|
+
function qwikRouterPlugin(userOpts) {
|
|
1719
|
+
let ctx = null;
|
|
1720
|
+
let mdxTransform = null;
|
|
1721
|
+
let rootDir = null;
|
|
1722
|
+
let qwikPlugin;
|
|
1723
|
+
let ssrFormat = "esm";
|
|
1724
|
+
let outDir = null;
|
|
1725
|
+
let viteCommand;
|
|
1726
|
+
let devServer = null;
|
|
1727
|
+
let devSsrServer = userOpts?.devSsrServer;
|
|
1728
|
+
const routesDir = userOpts?.routesDir ?? "src/routes";
|
|
1729
|
+
const serverPluginsDir = userOpts?.serverPluginsDir ?? routesDir;
|
|
1730
|
+
const api = {
|
|
1731
|
+
getBasePathname: () => ctx?.opts.basePathname ?? "/",
|
|
1732
|
+
getRoutes: () => {
|
|
1733
|
+
return ctx?.routes.slice() ?? [];
|
|
1734
|
+
},
|
|
1735
|
+
getServiceWorkers: () => {
|
|
1736
|
+
return ctx?.serviceWorkers.slice() ?? [];
|
|
1737
|
+
}
|
|
1738
|
+
};
|
|
1739
|
+
const plugin = {
|
|
1430
1740
|
name: "vite-plugin-qwik-router",
|
|
1431
1741
|
enforce: "pre",
|
|
1432
|
-
api
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
},
|
|
1437
|
-
async config(d, h) {
|
|
1438
|
-
return a = h.command, {
|
|
1742
|
+
api,
|
|
1743
|
+
async config(_viteConfig, viteEnv) {
|
|
1744
|
+
viteCommand = viteEnv.command;
|
|
1745
|
+
const updatedViteConfig = {
|
|
1439
1746
|
define: {
|
|
1440
1747
|
"globalThis.__DEFAULT_LOADERS_SERIALIZATION_STRATEGY__": JSON.stringify(
|
|
1441
|
-
|
|
1748
|
+
userOpts?.defaultLoadersSerializationStrategy || "never"
|
|
1442
1749
|
),
|
|
1443
|
-
"globalThis.__NO_TRAILING_SLASH__": JSON.stringify(
|
|
1750
|
+
"globalThis.__NO_TRAILING_SLASH__": JSON.stringify(userOpts?.trailingSlash === false)
|
|
1444
1751
|
},
|
|
1445
1752
|
appType: "custom",
|
|
1446
1753
|
resolve: {
|
|
1447
|
-
dedupe: [
|
|
1754
|
+
dedupe: [QWIK_ROUTER, "@builder.io/qwik-city"],
|
|
1448
1755
|
alias: [
|
|
1449
1756
|
{ find: "@builder.io/qwik-city", replacement: "@qwik.dev/router" },
|
|
1450
1757
|
{ find: /^@builder\.io\/qwik-city\/(.*)/, replacement: "@qwik.dev/router/$1" },
|
|
1451
|
-
{ find: "@qwik-city-plan", replacement:
|
|
1452
|
-
{ find: "@qwik-city-entries", replacement:
|
|
1453
|
-
{ find: "@qwik-city-sw-register", replacement:
|
|
1758
|
+
{ find: "@qwik-city-plan", replacement: QWIK_ROUTER_CONFIG_ID },
|
|
1759
|
+
{ find: "@qwik-city-entries", replacement: QWIK_ROUTER_ENTRIES_ID },
|
|
1760
|
+
{ find: "@qwik-city-sw-register", replacement: QWIK_ROUTER_SW_REGISTER }
|
|
1454
1761
|
]
|
|
1455
1762
|
},
|
|
1456
1763
|
optimizeDeps: {
|
|
1457
1764
|
// Let Vite find all app deps, these are not part of the static imports from `src/root`
|
|
1458
1765
|
entries: [
|
|
1459
|
-
`${
|
|
1460
|
-
`${
|
|
1461
|
-
`${
|
|
1766
|
+
`${routesDir}/**/index*`,
|
|
1767
|
+
`${routesDir}/**/layout*`,
|
|
1768
|
+
`${serverPluginsDir}/plugin@*`
|
|
1462
1769
|
],
|
|
1463
1770
|
// These need processing by the optimizer during dev
|
|
1464
1771
|
exclude: [
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1772
|
+
QWIK_ROUTER,
|
|
1773
|
+
QWIK_ROUTER_CONFIG_ID,
|
|
1774
|
+
QWIK_ROUTER_ENTRIES_ID,
|
|
1775
|
+
QWIK_ROUTER_SW_REGISTER
|
|
1469
1776
|
]
|
|
1470
1777
|
},
|
|
1471
1778
|
ssr: {
|
|
1472
1779
|
external: ["node:async_hooks"],
|
|
1473
1780
|
noExternal: [
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1781
|
+
QWIK_ROUTER,
|
|
1782
|
+
QWIK_ROUTER_CONFIG_ID,
|
|
1783
|
+
QWIK_ROUTER_ENTRIES_ID,
|
|
1784
|
+
QWIK_ROUTER_SW_REGISTER,
|
|
1785
|
+
// We've had reports of bundling issues with zod
|
|
1786
|
+
"zod"
|
|
1478
1787
|
]
|
|
1479
1788
|
},
|
|
1480
1789
|
server: {
|
|
1481
1790
|
watch: {
|
|
1482
1791
|
// needed for recursive watching of index and layout files in the src/routes directory
|
|
1483
|
-
disableGlobbing:
|
|
1792
|
+
disableGlobbing: false
|
|
1484
1793
|
}
|
|
1485
1794
|
}
|
|
1486
1795
|
};
|
|
1796
|
+
return updatedViteConfig;
|
|
1487
1797
|
},
|
|
1488
|
-
async configResolved(
|
|
1489
|
-
Object.assign(process.env,
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1798
|
+
async configResolved(config) {
|
|
1799
|
+
Object.assign(process.env, loadEnv(config.mode, process.cwd(), ""));
|
|
1800
|
+
rootDir = resolve(config.root);
|
|
1801
|
+
const target = config.build?.ssr || config.mode === "ssr" ? "ssr" : "client";
|
|
1802
|
+
ctx = createBuildContext(
|
|
1803
|
+
rootDir,
|
|
1804
|
+
config.base,
|
|
1805
|
+
userOpts,
|
|
1806
|
+
target,
|
|
1807
|
+
!userOpts?.staticImportRoutes
|
|
1808
|
+
);
|
|
1809
|
+
await validatePlugin(ctx.opts);
|
|
1810
|
+
mdxTransform = await createMdxTransformer(ctx);
|
|
1811
|
+
qwikPlugin = config.plugins.find(
|
|
1812
|
+
(p) => p.name === "vite-plugin-qwik"
|
|
1813
|
+
);
|
|
1814
|
+
if (!qwikPlugin) {
|
|
1500
1815
|
throw new Error("Missing vite-plugin-qwik");
|
|
1501
|
-
|
|
1816
|
+
}
|
|
1817
|
+
if (typeof devSsrServer !== "boolean") {
|
|
1818
|
+
devSsrServer = qwikPlugin.api._oldDevSsrServer();
|
|
1819
|
+
}
|
|
1820
|
+
qwikPlugin.api.registerBundleGraphAdder?.((manifest) => {
|
|
1821
|
+
return getRouteImports(ctx.routes, manifest);
|
|
1822
|
+
});
|
|
1823
|
+
if (config.ssr?.format === "cjs") {
|
|
1824
|
+
ssrFormat = "cjs";
|
|
1825
|
+
}
|
|
1826
|
+
outDir = config.build?.outDir;
|
|
1502
1827
|
},
|
|
1503
|
-
async configureServer(
|
|
1504
|
-
|
|
1505
|
-
const
|
|
1506
|
-
|
|
1828
|
+
async configureServer(server) {
|
|
1829
|
+
devServer = server;
|
|
1830
|
+
const toWatch = resolve(
|
|
1831
|
+
rootDir,
|
|
1507
1832
|
"src/routes/**/{index,layout,entry,service-worker}{.,@,-}*"
|
|
1508
1833
|
);
|
|
1509
|
-
|
|
1510
|
-
|
|
1834
|
+
server.watcher.add(toWatch);
|
|
1835
|
+
await new Promise((resolve2) => setTimeout(resolve2, 1e3));
|
|
1836
|
+
server.watcher.on("change", (path2) => {
|
|
1837
|
+
if (!/\/(index[.@]|layout[.-]|entry\.|service-worker\.)[^/]*$/.test(path2)) {
|
|
1511
1838
|
return;
|
|
1512
|
-
t.isDirty = !0;
|
|
1513
|
-
const g = d.environments?.ssr?.moduleGraph;
|
|
1514
|
-
if (g) {
|
|
1515
|
-
const b = g.getModuleById("@qwik-router-config");
|
|
1516
|
-
b && g.invalidateModule(b);
|
|
1517
1839
|
}
|
|
1518
|
-
|
|
1840
|
+
ctx.isDirty = true;
|
|
1841
|
+
const graph = server.environments?.ssr?.moduleGraph;
|
|
1842
|
+
if (graph) {
|
|
1843
|
+
const mod = graph.getModuleById("@qwik-router-config");
|
|
1844
|
+
if (mod) {
|
|
1845
|
+
graph.invalidateModule(mod);
|
|
1846
|
+
}
|
|
1847
|
+
}
|
|
1848
|
+
});
|
|
1849
|
+
if (userOpts?.devSsrServer !== false) {
|
|
1519
1850
|
return () => {
|
|
1520
|
-
|
|
1851
|
+
server.middlewares.use(makeRouterDevMiddleware(server, ctx));
|
|
1521
1852
|
};
|
|
1853
|
+
}
|
|
1522
1854
|
},
|
|
1523
1855
|
transformIndexHtml() {
|
|
1524
|
-
if (
|
|
1525
|
-
return
|
|
1856
|
+
if (viteCommand !== "serve") {
|
|
1857
|
+
return;
|
|
1858
|
+
}
|
|
1859
|
+
return getRouterIndexTags(devServer);
|
|
1526
1860
|
},
|
|
1527
1861
|
buildStart() {
|
|
1528
|
-
|
|
1862
|
+
resetBuildContext(ctx);
|
|
1529
1863
|
},
|
|
1530
|
-
resolveId(
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1864
|
+
resolveId(id) {
|
|
1865
|
+
if (id === QWIK_ROUTER_CONFIG_ID || id === QWIK_ROUTER_ENTRIES_ID) {
|
|
1866
|
+
return {
|
|
1867
|
+
id,
|
|
1868
|
+
// user entries added in the routes, like src/routes/service-worker.ts
|
|
1869
|
+
// are added as dynamic imports to the qwik-router-config as a way to create
|
|
1870
|
+
// a new entry point for the build. Ensure these are not treeshaken.
|
|
1871
|
+
moduleSideEffects: "no-treeshake"
|
|
1872
|
+
};
|
|
1873
|
+
}
|
|
1874
|
+
if (id === QWIK_ROUTER_SW_REGISTER) {
|
|
1875
|
+
return id;
|
|
1876
|
+
}
|
|
1877
|
+
return null;
|
|
1538
1878
|
},
|
|
1539
|
-
async load(
|
|
1540
|
-
if (
|
|
1541
|
-
if (
|
|
1542
|
-
return
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1879
|
+
async load(id, opts) {
|
|
1880
|
+
if (ctx) {
|
|
1881
|
+
if (id.endsWith(QWIK_ROUTER_ENTRIES_ID)) {
|
|
1882
|
+
return generateQwikRouterEntries(ctx);
|
|
1883
|
+
}
|
|
1884
|
+
const isRouterConfig = id.endsWith(QWIK_ROUTER_CONFIG_ID);
|
|
1885
|
+
const isSwRegister = id.endsWith(QWIK_ROUTER_SW_REGISTER);
|
|
1886
|
+
if (isRouterConfig || isSwRegister) {
|
|
1887
|
+
if (ctx.isDirty) {
|
|
1888
|
+
await parseRoutesDir(ctx);
|
|
1889
|
+
ctx.isDirty = false;
|
|
1890
|
+
ctx.diagnostics.forEach((d) => {
|
|
1891
|
+
this.warn(d.message);
|
|
1892
|
+
});
|
|
1893
|
+
}
|
|
1894
|
+
if (isRouterConfig) {
|
|
1895
|
+
return generateQwikRouterConfig(ctx, qwikPlugin, opts?.ssr ?? false);
|
|
1896
|
+
}
|
|
1897
|
+
if (isSwRegister) {
|
|
1898
|
+
return generateServiceWorkerRegister(ctx, swRegister);
|
|
1899
|
+
}
|
|
1551
1900
|
}
|
|
1552
1901
|
}
|
|
1553
1902
|
return null;
|
|
1554
1903
|
},
|
|
1555
|
-
async transform(
|
|
1556
|
-
|
|
1904
|
+
async transform(code, id) {
|
|
1905
|
+
const isVirtualId = id.startsWith("\0");
|
|
1906
|
+
if (isVirtualId) {
|
|
1557
1907
|
return;
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
if (
|
|
1908
|
+
}
|
|
1909
|
+
const ext = extname(id).toLowerCase();
|
|
1910
|
+
const isMD = ext === ".md" || ext === ".mdx";
|
|
1911
|
+
if (ctx && isMD) {
|
|
1912
|
+
const fileName = basename(id);
|
|
1913
|
+
if (isMenuFileName(fileName)) {
|
|
1914
|
+
const menuCode = await transformMenu(ctx.opts, id, code);
|
|
1915
|
+
return { code: menuCode, map: null };
|
|
1916
|
+
}
|
|
1917
|
+
if (mdxTransform) {
|
|
1564
1918
|
try {
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1919
|
+
const mdxResult = await mdxTransform(code, id);
|
|
1920
|
+
return mdxResult;
|
|
1921
|
+
} catch (e) {
|
|
1922
|
+
if (e && typeof e == "object" && "position" in e && "reason" in e) {
|
|
1923
|
+
const column = e.position?.start.column;
|
|
1924
|
+
const line = e.position?.start.line;
|
|
1925
|
+
const err = Object.assign(new Error(e.reason), {
|
|
1926
|
+
id,
|
|
1570
1927
|
plugin: "qwik-router-mdx",
|
|
1571
1928
|
loc: {
|
|
1572
|
-
column
|
|
1573
|
-
line
|
|
1929
|
+
column,
|
|
1930
|
+
line
|
|
1574
1931
|
},
|
|
1575
1932
|
stack: ""
|
|
1576
1933
|
});
|
|
1577
|
-
this.error(
|
|
1578
|
-
} else
|
|
1934
|
+
this.error(err);
|
|
1935
|
+
} else if (e instanceof Error) {
|
|
1936
|
+
this.error(e);
|
|
1937
|
+
} else {
|
|
1938
|
+
this.error(String(e));
|
|
1939
|
+
}
|
|
1579
1940
|
}
|
|
1941
|
+
}
|
|
1580
1942
|
}
|
|
1581
1943
|
return null;
|
|
1582
1944
|
},
|
|
1583
|
-
generateBundle(
|
|
1584
|
-
if (
|
|
1585
|
-
const
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1945
|
+
generateBundle(_, bundles) {
|
|
1946
|
+
if (ctx?.target === "client") {
|
|
1947
|
+
const entries = [...ctx.entries, ...ctx.serviceWorkers].map((entry) => {
|
|
1948
|
+
return {
|
|
1949
|
+
chunkFileName: entry.chunkFileName,
|
|
1950
|
+
extensionlessFilePath: removeExtension(entry.filePath)
|
|
1951
|
+
};
|
|
1952
|
+
});
|
|
1953
|
+
for (const entry of entries) {
|
|
1954
|
+
for (const fileName in bundles) {
|
|
1955
|
+
const c = bundles[fileName];
|
|
1956
|
+
if (c.type === "chunk" && c.isDynamicEntry && c.facadeModuleId) {
|
|
1957
|
+
const extensionlessFilePath = removeExtension(normalizePath(c.facadeModuleId));
|
|
1958
|
+
if (entry.extensionlessFilePath === extensionlessFilePath) {
|
|
1959
|
+
c.fileName = entry.chunkFileName;
|
|
1596
1960
|
continue;
|
|
1597
1961
|
}
|
|
1598
1962
|
}
|
|
1599
1963
|
}
|
|
1964
|
+
}
|
|
1600
1965
|
}
|
|
1601
1966
|
},
|
|
1602
1967
|
closeBundle: {
|
|
1603
|
-
sequential:
|
|
1968
|
+
sequential: true,
|
|
1604
1969
|
async handler() {
|
|
1605
|
-
|
|
1970
|
+
if (ctx?.target === "ssr" && outDir) {
|
|
1971
|
+
await generateServerPackageJson(outDir, ssrFormat);
|
|
1972
|
+
}
|
|
1606
1973
|
}
|
|
1607
1974
|
}
|
|
1608
1975
|
};
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1976
|
+
return plugin;
|
|
1977
|
+
}
|
|
1978
|
+
async function generateServerPackageJson(outDir, ssrFormat) {
|
|
1979
|
+
await fs.promises.mkdir(outDir, { recursive: true });
|
|
1980
|
+
const serverPackageJsonPath = join(outDir, "package.json");
|
|
1981
|
+
let packageJson = {};
|
|
1982
|
+
if (fs.existsSync(serverPackageJsonPath)) {
|
|
1983
|
+
const content = await fs.promises.readFile(serverPackageJsonPath, "utf-8");
|
|
1984
|
+
const contentAsJson = JSON.parse(content);
|
|
1985
|
+
packageJson = {
|
|
1986
|
+
...contentAsJson
|
|
1618
1987
|
};
|
|
1619
1988
|
}
|
|
1620
|
-
|
|
1621
|
-
...
|
|
1622
|
-
type:
|
|
1989
|
+
packageJson = {
|
|
1990
|
+
...packageJson,
|
|
1991
|
+
type: ssrFormat == "cjs" ? "commonjs" : "module"
|
|
1623
1992
|
};
|
|
1624
|
-
const
|
|
1625
|
-
await
|
|
1993
|
+
const serverPackageJsonCode = JSON.stringify(packageJson, null, 2);
|
|
1994
|
+
await fs.promises.writeFile(serverPackageJsonPath, serverPackageJsonCode);
|
|
1626
1995
|
}
|
|
1627
1996
|
export {
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1997
|
+
extendConfig,
|
|
1998
|
+
qwikCity,
|
|
1999
|
+
qwikRouter
|
|
1631
2000
|
};
|