@qwik.dev/router 2.0.0-beta.27 → 2.0.0-beta.29
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.mjs +31 -36
- package/lib/adapters/bun-server/vite/index.mjs +0 -3
- package/lib/adapters/cloud-run/vite/index.mjs +0 -3
- package/lib/adapters/cloudflare-pages/vite/index.mjs +15 -9
- package/lib/adapters/deno-server/vite/index.mjs +7 -5
- package/lib/adapters/netlify-edge/vite/index.mjs +13 -23
- package/lib/adapters/node-server/vite/index.mjs +0 -3
- package/lib/adapters/shared/vite/index.d.ts +1 -7
- package/lib/adapters/shared/vite/index.mjs +171 -157
- package/lib/adapters/ssg/vite/index.mjs +3 -4
- package/lib/adapters/vercel-edge/vite/index.mjs +25 -9
- package/lib/chunks/error-handler.mjs +26 -26
- package/lib/chunks/fs.mjs +28 -138
- package/lib/chunks/http-error.qwik.mjs +27 -0
- package/lib/chunks/not-found-wrapper.qwik.mjs +25 -0
- package/lib/chunks/pathname.mjs +105 -0
- package/lib/chunks/routing.qwik.mjs +592 -216
- package/lib/chunks/system.mjs +328 -0
- package/lib/chunks/use-functions.qwik.mjs +35 -0
- package/lib/chunks/worker-thread.mjs +271 -0
- package/lib/index.d.ts +136 -102
- package/lib/index.qwik.mjs +699 -751
- package/lib/middleware/aws-lambda/index.mjs +7 -1
- package/lib/middleware/azure-swa/index.mjs +7 -2
- package/lib/middleware/bun/index.mjs +24 -8
- package/lib/middleware/cloudflare-pages/index.mjs +10 -3
- package/lib/middleware/deno/index.mjs +23 -8
- package/lib/middleware/netlify-edge/index.mjs +10 -3
- package/lib/middleware/node/index.mjs +10 -14
- package/lib/middleware/request-handler/index.d.ts +82 -12
- package/lib/middleware/request-handler/index.mjs +661 -524
- package/lib/middleware/vercel-edge/index.mjs +10 -3
- package/lib/modules.d.ts +7 -4
- package/lib/ssg/index.d.ts +48 -16
- package/lib/ssg/index.mjs +320 -7
- package/lib/vite/index.d.ts +6 -0
- package/lib/vite/index.mjs +1106 -630
- package/modules.d.ts +7 -4
- package/package.json +9 -9
- package/lib/chunks/format-error.mjs +0 -137
- package/lib/chunks/index.mjs +0 -884
- package/lib/chunks/types.qwik.mjs +0 -22
package/lib/vite/index.mjs
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { mergeConfig, loadEnv } from 'vite';
|
|
2
2
|
import fs, { existsSync } from 'node:fs';
|
|
3
3
|
import path, { join, dirname, basename, resolve, isAbsolute, extname } from 'node:path';
|
|
4
|
-
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
|
|
4
|
+
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 normalizePath, l as getPathnameFromDirPath, m as getMenuPathname, o as createFileId, p as parseRouteIndexName, q as isPluginModule, s as isPageExt } from '../chunks/fs.mjs';
|
|
5
|
+
import { i as isSameOriginUrl, a as addError, b as addWarning } from '../chunks/pathname.mjs';
|
|
5
6
|
import { marked } from 'marked';
|
|
7
|
+
import { createHash } from 'node:crypto';
|
|
6
8
|
import { SourceMapGenerator } from 'source-map';
|
|
7
9
|
import { visit } from 'unist-util-visit';
|
|
8
10
|
import { parse } from 'yaml';
|
|
@@ -13,7 +15,6 @@ import { toString } from 'hast-util-to-string';
|
|
|
13
15
|
import { refractor } from 'refractor';
|
|
14
16
|
import tsxLang from 'refractor/lang/tsx.js';
|
|
15
17
|
import { optimize } from 'svgo';
|
|
16
|
-
import { p as parseId, f as formatError } from '../chunks/format-error.mjs';
|
|
17
18
|
|
|
18
19
|
function extendConfig(baseConfigExport, serverConfigExport) {
|
|
19
20
|
return async (env) => {
|
|
@@ -73,11 +74,9 @@ function getMarkdownRelativeUrl(opts, containingFilePath, url, checkFileExists)
|
|
|
73
74
|
const parts = normalizePath(strippedUrl).split("/").filter((p) => p.length > 0);
|
|
74
75
|
const filePath = isAbsolute ? join(opts.routesDir, ...parts) : join(dirname(containingFilePath), ...parts);
|
|
75
76
|
if (checkFileExists && !existsSync(filePath)) {
|
|
76
|
-
console.warn(
|
|
77
|
-
`
|
|
77
|
+
console.warn(`
|
|
78
78
|
The link "${url}", found within "${containingFilePath}" does not have a matching source file.
|
|
79
|
-
`
|
|
80
|
-
);
|
|
79
|
+
`);
|
|
81
80
|
}
|
|
82
81
|
const fileName = basename(filePath);
|
|
83
82
|
const sourceFileName = getSourceFile(fileName);
|
|
@@ -113,12 +112,6 @@ function createMenu(opts, filePath) {
|
|
|
113
112
|
function resolveMenu(opts, menuSourceFile) {
|
|
114
113
|
return createMenu(opts, menuSourceFile.filePath);
|
|
115
114
|
}
|
|
116
|
-
async function transformMenu(opts, filePath, content) {
|
|
117
|
-
const parsedMenu = parseMenu(opts, filePath, content);
|
|
118
|
-
const id = createFileId(opts.routesDir, filePath);
|
|
119
|
-
const code = `const ${id} = ${JSON.stringify(parsedMenu, null, 2)};`;
|
|
120
|
-
return `${code} export default ${id}`;
|
|
121
|
-
}
|
|
122
115
|
function parseMenu(opts, filePath, content, checkFileExists = true) {
|
|
123
116
|
const tokens = marked.lexer(content, {});
|
|
124
117
|
let currentDepth = 0;
|
|
@@ -130,11 +123,7 @@ function parseMenu(opts, filePath, content, checkFileExists = true) {
|
|
|
130
123
|
stack.length -= diff + 1;
|
|
131
124
|
}
|
|
132
125
|
if (diff < -1) {
|
|
133
|
-
throw new Error(
|
|
134
|
-
`Menu hierarchy skipped a level, went from <h${"#".repeat(
|
|
135
|
-
currentDepth
|
|
136
|
-
)}> to <h${"#".repeat(t.depth)}>, in menu: ${filePath}`
|
|
137
|
-
);
|
|
126
|
+
throw new Error(`Menu hierarchy skipped a level, went from <h${"#".repeat(currentDepth)}> to <h${"#".repeat(t.depth)}>, in menu: ${filePath}`);
|
|
138
127
|
}
|
|
139
128
|
currentDepth = t.depth;
|
|
140
129
|
const parentNode = stack[stack.length - 1];
|
|
@@ -148,9 +137,7 @@ function parseMenu(opts, filePath, content, checkFileExists = true) {
|
|
|
148
137
|
lastNode.text = h2Token.text;
|
|
149
138
|
lastNode.href = getMarkdownRelativeUrl(opts, filePath, h2Token.href, checkFileExists);
|
|
150
139
|
} else {
|
|
151
|
-
throw new Error(
|
|
152
|
-
`Headings can only be a text or link. Received "${h2Token.type}", value "${h2Token.raw}", in menu: ${filePath}`
|
|
153
|
-
);
|
|
140
|
+
throw new Error(`Headings can only be a text or link. Received "${h2Token.type}", value "${h2Token.raw}", in menu: ${filePath}`);
|
|
154
141
|
}
|
|
155
142
|
if (parentNode) {
|
|
156
143
|
parentNode.items = parentNode.items || [];
|
|
@@ -167,16 +154,16 @@ function parseMenu(opts, filePath, content, checkFileExists = true) {
|
|
|
167
154
|
if (liToken.type === "text") {
|
|
168
155
|
for (const liItem of liToken.tokens) {
|
|
169
156
|
if (liItem.type === "text") {
|
|
170
|
-
parentNode.items.push({
|
|
157
|
+
parentNode.items.push({
|
|
158
|
+
text: liItem.text
|
|
159
|
+
});
|
|
171
160
|
} else if (liItem.type === "link") {
|
|
172
161
|
parentNode.items.push({
|
|
173
162
|
text: liItem.text,
|
|
174
163
|
href: getMarkdownRelativeUrl(opts, filePath, liItem.href, checkFileExists)
|
|
175
164
|
});
|
|
176
165
|
} else {
|
|
177
|
-
throw new Error(
|
|
178
|
-
`List items can only be a text or link. Received "${liItem.type}", value "${liItem.raw}", in menu: ${filePath}`
|
|
179
|
-
);
|
|
166
|
+
throw new Error(`List items can only be a text or link. Received "${liItem.type}", value "${liItem.raw}", in menu: ${filePath}`);
|
|
180
167
|
}
|
|
181
168
|
}
|
|
182
169
|
} else if (liToken.type === "link") {
|
|
@@ -185,23 +172,17 @@ function parseMenu(opts, filePath, content, checkFileExists = true) {
|
|
|
185
172
|
href: getMarkdownRelativeUrl(opts, filePath, liToken.href, checkFileExists)
|
|
186
173
|
});
|
|
187
174
|
} else {
|
|
188
|
-
throw new Error(
|
|
189
|
-
`List items can only be a text or link. Received "${liToken.type}", value "${liToken.raw}", in menu: ${filePath}`
|
|
190
|
-
);
|
|
175
|
+
throw new Error(`List items can only be a text or link. Received "${liToken.type}", value "${liToken.raw}", in menu: ${filePath}`);
|
|
191
176
|
}
|
|
192
177
|
}
|
|
193
178
|
} else {
|
|
194
|
-
throw new Error(
|
|
195
|
-
`Only list items can be used in lists. Received "${li.type}", value "${li.raw}", in menu: ${filePath}`
|
|
196
|
-
);
|
|
179
|
+
throw new Error(`Only list items can be used in lists. Received "${li.type}", value "${li.raw}", in menu: ${filePath}`);
|
|
197
180
|
}
|
|
198
181
|
}
|
|
199
182
|
} else if (t.type === "space") {
|
|
200
183
|
continue;
|
|
201
184
|
} else {
|
|
202
|
-
throw new Error(
|
|
203
|
-
`Menu has a "${t.type}" with the value "${t.raw}". However, only headings and lists can be used in the menu: ${filePath}`
|
|
204
|
-
);
|
|
185
|
+
throw new Error(`Menu has a "${t.type}" with the value "${t.raw}". However, only headings and lists can be used in the menu: ${filePath}`);
|
|
205
186
|
}
|
|
206
187
|
}
|
|
207
188
|
if (stack.length === 0) {
|
|
@@ -209,14 +190,30 @@ function parseMenu(opts, filePath, content, checkFileExists = true) {
|
|
|
209
190
|
}
|
|
210
191
|
return stack[0];
|
|
211
192
|
}
|
|
193
|
+
async function transformMenu(opts, filePath, content) {
|
|
194
|
+
const parsedMenu = parseMenu(opts, filePath, content);
|
|
195
|
+
const id = createFileId(opts.routesDir, filePath);
|
|
196
|
+
const code = `const ${id} = ${JSON.stringify(parsedMenu, null, 2)};`;
|
|
197
|
+
return `${code} export default ${id}`;
|
|
198
|
+
}
|
|
212
199
|
|
|
200
|
+
const PARAM_PATTERN = /^(\.\.\.)?(\w+)?$/;
|
|
201
|
+
const DYNAMIC_SEGMENT = /\[(.+?)\]/;
|
|
213
202
|
function parseRoutePathname(basePathname, pathname) {
|
|
214
203
|
if (pathname === basePathname) {
|
|
215
204
|
return {
|
|
216
205
|
pattern: new RegExp("^" + pathname.replace(/[.*+?^${}()|[\]\\]/g, "\\$&") + "$"),
|
|
217
206
|
routeName: pathname,
|
|
218
207
|
paramNames: [],
|
|
219
|
-
segments: [
|
|
208
|
+
segments: [
|
|
209
|
+
[
|
|
210
|
+
{
|
|
211
|
+
content: "",
|
|
212
|
+
dynamic: false,
|
|
213
|
+
rest: false
|
|
214
|
+
}
|
|
215
|
+
]
|
|
216
|
+
]
|
|
220
217
|
};
|
|
221
218
|
}
|
|
222
219
|
pathname = pathname.slice(1);
|
|
@@ -264,8 +261,6 @@ function parseRoutePathname(basePathname, pathname) {
|
|
|
264
261
|
})
|
|
265
262
|
};
|
|
266
263
|
}
|
|
267
|
-
const PARAM_PATTERN = /^(\.\.\.)?(\w+)?$/;
|
|
268
|
-
const DYNAMIC_SEGMENT = /\[(.+?)\]/;
|
|
269
264
|
|
|
270
265
|
function routeSortCompare(a, b) {
|
|
271
266
|
const maxSegments = Math.max(a.segments.length, b.segments.length);
|
|
@@ -304,38 +299,9 @@ function routeSortCompare(a, b) {
|
|
|
304
299
|
return a.pathname < b.pathname ? -1 : 1;
|
|
305
300
|
}
|
|
306
301
|
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
});
|
|
311
|
-
const routes = sourceFiles.filter((s) => s.type === "route").map((s) => resolveRoute(opts, layouts, s)).sort(routeSortCompare);
|
|
312
|
-
const entries = sourceFiles.filter((s) => s.type === "entry").map((s) => resolveEntry(opts, s)).sort((a, b) => {
|
|
313
|
-
return a.chunkFileName < b.chunkFileName ? -1 : 1;
|
|
314
|
-
});
|
|
315
|
-
const serviceWorkers = sourceFiles.filter((s) => s.type === "service-worker").map((p) => resolveServiceWorkerEntry(opts, p)).sort((a, b) => {
|
|
316
|
-
return a.chunkFileName < b.chunkFileName ? -1 : 1;
|
|
317
|
-
});
|
|
318
|
-
const menus = sourceFiles.filter((s) => s.type === "menu").map((p) => resolveMenu(opts, p)).sort((a, b) => {
|
|
319
|
-
return a.pathname < b.pathname ? -1 : 1;
|
|
320
|
-
});
|
|
321
|
-
let inc = 0;
|
|
322
|
-
const ids = /* @__PURE__ */ new Set();
|
|
323
|
-
const uniqueIds = (b) => {
|
|
324
|
-
for (const r of b) {
|
|
325
|
-
let id = r.id;
|
|
326
|
-
while (ids.has(id)) {
|
|
327
|
-
id = `${r.id}_${inc++}`;
|
|
328
|
-
}
|
|
329
|
-
r.id = id;
|
|
330
|
-
ids.add(id);
|
|
331
|
-
}
|
|
332
|
-
};
|
|
333
|
-
uniqueIds(layouts);
|
|
334
|
-
uniqueIds(routes);
|
|
335
|
-
uniqueIds(entries);
|
|
336
|
-
uniqueIds(serviceWorkers);
|
|
337
|
-
return { layouts, routes, entries, menus, serviceWorkers };
|
|
338
|
-
}
|
|
302
|
+
const LAYOUT_ID = "layout";
|
|
303
|
+
const LAYOUT_NAMED_PREFIX = LAYOUT_ID + "-";
|
|
304
|
+
const LAYOUT_TOP_SUFFIX = "!";
|
|
339
305
|
function resolveLayout(opts, layoutSourceFile) {
|
|
340
306
|
let extlessName = layoutSourceFile.extlessName;
|
|
341
307
|
const filePath = layoutSourceFile.filePath;
|
|
@@ -362,16 +328,13 @@ function resolveLayout(opts, layoutSourceFile) {
|
|
|
362
328
|
};
|
|
363
329
|
return layout;
|
|
364
330
|
}
|
|
365
|
-
const LAYOUT_ID = "layout";
|
|
366
|
-
const LAYOUT_NAMED_PREFIX = LAYOUT_ID + "-";
|
|
367
|
-
const LAYOUT_TOP_SUFFIX = "!";
|
|
368
331
|
function resolveRoute(opts, appLayouts, sourceFile) {
|
|
369
332
|
const filePath = sourceFile.filePath;
|
|
370
333
|
const layouts = [];
|
|
371
334
|
const routesDir = opts.routesDir;
|
|
372
335
|
const { layoutName, layoutStop } = parseRouteIndexName(sourceFile.extlessName);
|
|
373
336
|
let pathname = getPathnameFromDirPath(opts, sourceFile.dirPath);
|
|
374
|
-
if (sourceFile.extlessName === "404") {
|
|
337
|
+
if (sourceFile.extlessName === "404" || sourceFile.extlessName === "error") {
|
|
375
338
|
pathname += sourceFile.extlessName + ".html";
|
|
376
339
|
}
|
|
377
340
|
if (!layoutStop) {
|
|
@@ -400,7 +363,7 @@ function resolveRoute(opts, appLayouts, sourceFile) {
|
|
|
400
363
|
currentDir = normalizePath(dirname(currentDir));
|
|
401
364
|
}
|
|
402
365
|
}
|
|
403
|
-
|
|
366
|
+
return {
|
|
404
367
|
id: createFileId(opts.routesDir, filePath, "Route"),
|
|
405
368
|
filePath,
|
|
406
369
|
pathname,
|
|
@@ -408,152 +371,209 @@ function resolveRoute(opts, appLayouts, sourceFile) {
|
|
|
408
371
|
ext: sourceFile.ext,
|
|
409
372
|
...parseRoutePathname(opts.basePathname, pathname)
|
|
410
373
|
};
|
|
411
|
-
return buildRoute;
|
|
412
374
|
}
|
|
375
|
+
|
|
376
|
+
function parseDirName(name) {
|
|
377
|
+
if (name.startsWith("(") && name.endsWith(")")) {
|
|
378
|
+
return {
|
|
379
|
+
key: null
|
|
380
|
+
};
|
|
381
|
+
}
|
|
382
|
+
const restMatch = /^\[\.\.\.(\w+)\]$/.exec(name);
|
|
383
|
+
if (restMatch) {
|
|
384
|
+
return {
|
|
385
|
+
key: "_A",
|
|
386
|
+
paramName: restMatch[1]
|
|
387
|
+
};
|
|
388
|
+
}
|
|
389
|
+
const paramMatch = /^(.*?)\[(\w+)\](.*?)$/.exec(name);
|
|
390
|
+
if (paramMatch) {
|
|
391
|
+
return {
|
|
392
|
+
key: "_W",
|
|
393
|
+
paramName: paramMatch[2],
|
|
394
|
+
prefix: paramMatch[1] || void 0,
|
|
395
|
+
suffix: paramMatch[3] || void 0
|
|
396
|
+
};
|
|
397
|
+
}
|
|
398
|
+
return {
|
|
399
|
+
key: name.toLowerCase()
|
|
400
|
+
};
|
|
401
|
+
}
|
|
402
|
+
async function walkRouteDir(node, dirPath) {
|
|
403
|
+
const dirItemNames = await fs.promises.readdir(dirPath);
|
|
404
|
+
await Promise.all(dirItemNames.map(async (itemName) => {
|
|
405
|
+
const itemPath = normalizePath(join(dirPath, itemName));
|
|
406
|
+
const stat = await fs.promises.stat(itemPath);
|
|
407
|
+
if (stat.isDirectory()) {
|
|
408
|
+
const parsed = parseDirName(itemName);
|
|
409
|
+
if (parsed.key === null) {
|
|
410
|
+
let child = node.children.get(itemName);
|
|
411
|
+
if (!child) {
|
|
412
|
+
child = {
|
|
413
|
+
_files: [],
|
|
414
|
+
_dirPath: itemPath,
|
|
415
|
+
children: /* @__PURE__ */ new Map()
|
|
416
|
+
};
|
|
417
|
+
node.children.set(itemName, child);
|
|
418
|
+
}
|
|
419
|
+
await walkRouteDir(child, itemPath);
|
|
420
|
+
} else {
|
|
421
|
+
let child = node.children.get(parsed.key);
|
|
422
|
+
if (!child) {
|
|
423
|
+
child = {
|
|
424
|
+
_files: [],
|
|
425
|
+
_dirPath: itemPath,
|
|
426
|
+
children: /* @__PURE__ */ new Map()
|
|
427
|
+
};
|
|
428
|
+
if (parsed.paramName) {
|
|
429
|
+
child._P = parsed.paramName;
|
|
430
|
+
}
|
|
431
|
+
if (parsed.prefix) {
|
|
432
|
+
child._0 = parsed.prefix;
|
|
433
|
+
}
|
|
434
|
+
if (parsed.suffix) {
|
|
435
|
+
child._9 = parsed.suffix;
|
|
436
|
+
}
|
|
437
|
+
node.children.set(parsed.key, child);
|
|
438
|
+
}
|
|
439
|
+
await walkRouteDir(child, itemPath);
|
|
440
|
+
}
|
|
441
|
+
} else {
|
|
442
|
+
const sourceFileName = getSourceFile(itemName);
|
|
443
|
+
if (sourceFileName !== null) {
|
|
444
|
+
node._files.push({
|
|
445
|
+
...sourceFileName,
|
|
446
|
+
fileName: itemName,
|
|
447
|
+
filePath: itemPath,
|
|
448
|
+
dirName: basename(dirPath),
|
|
449
|
+
dirPath: normalizePath(dirPath)
|
|
450
|
+
});
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
}));
|
|
454
|
+
}
|
|
455
|
+
async function walkRoutes(routesDir) {
|
|
456
|
+
const dirPath = normalizePath(routesDir);
|
|
457
|
+
const root = {
|
|
458
|
+
_files: [],
|
|
459
|
+
_dirPath: dirPath,
|
|
460
|
+
children: /* @__PURE__ */ new Map()
|
|
461
|
+
};
|
|
462
|
+
await walkRouteDir(root, dirPath);
|
|
463
|
+
return root;
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
async function walkServerPlugins(opts) {
|
|
467
|
+
const dirPath = opts.serverPluginsDir;
|
|
468
|
+
const dirItemNames = await fs.promises.readdir(dirPath);
|
|
469
|
+
const sourceFiles = [];
|
|
470
|
+
await Promise.all(dirItemNames.map(async (itemName) => {
|
|
471
|
+
const itemPath = normalizePath(join(dirPath, itemName));
|
|
472
|
+
const ext = getExtension(itemName);
|
|
473
|
+
const extlessName = removeExtension(itemName);
|
|
474
|
+
if ((isModuleExt(ext) || isPageModuleExt(ext)) && isPluginModule(extlessName)) {
|
|
475
|
+
sourceFiles.push({
|
|
476
|
+
id: createFileId(opts.serverPluginsDir, itemPath, "Plugin"),
|
|
477
|
+
filePath: itemPath,
|
|
478
|
+
ext
|
|
479
|
+
});
|
|
480
|
+
}
|
|
481
|
+
}));
|
|
482
|
+
return sourceFiles;
|
|
483
|
+
}
|
|
484
|
+
|
|
413
485
|
function resolveEntry(opts, sourceFile) {
|
|
414
486
|
const pathname = getPathnameFromDirPath(opts, sourceFile.dirPath);
|
|
415
487
|
const chunkFileName = pathname.slice(opts.basePathname.length);
|
|
416
|
-
|
|
488
|
+
return {
|
|
417
489
|
id: createFileId(opts.routesDir, sourceFile.filePath, "Route"),
|
|
418
490
|
filePath: sourceFile.filePath,
|
|
419
491
|
chunkFileName,
|
|
420
492
|
...parseRoutePathname(opts.basePathname, pathname)
|
|
421
493
|
};
|
|
422
|
-
return buildEntry;
|
|
423
494
|
}
|
|
424
495
|
function resolveServiceWorkerEntry(opts, sourceFile) {
|
|
425
496
|
const dirPathname = getPathnameFromDirPath(opts, sourceFile.dirPath);
|
|
426
497
|
const pathname = dirPathname + sourceFile.extlessName + ".js";
|
|
427
498
|
const chunkFileName = pathname.slice(opts.basePathname.length);
|
|
428
|
-
|
|
499
|
+
return {
|
|
429
500
|
id: createFileId(opts.routesDir, sourceFile.filePath, "ServiceWorker"),
|
|
430
501
|
filePath: sourceFile.filePath,
|
|
431
502
|
chunkFileName,
|
|
432
503
|
...parseRoutePathname(opts.basePathname, pathname)
|
|
433
504
|
};
|
|
434
|
-
return buildEntry;
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
async function walkRoutes(routesDir) {
|
|
438
|
-
const sourceFiles = [];
|
|
439
|
-
await walkRouteDir(sourceFiles, normalizePath(routesDir), basename(routesDir));
|
|
440
|
-
return sourceFiles;
|
|
441
505
|
}
|
|
442
|
-
|
|
443
|
-
const
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
...sourceFileName,
|
|
455
|
-
fileName: itemName,
|
|
456
|
-
filePath: itemPath,
|
|
457
|
-
dirName,
|
|
458
|
-
dirPath
|
|
459
|
-
});
|
|
460
|
-
}
|
|
461
|
-
}
|
|
462
|
-
})
|
|
463
|
-
);
|
|
464
|
-
}
|
|
465
|
-
|
|
466
|
-
async function walkServerPlugins(opts) {
|
|
467
|
-
const dirPath = opts.serverPluginsDir;
|
|
468
|
-
const dirItemNames = await fs.promises.readdir(dirPath);
|
|
469
|
-
const sourceFiles = [];
|
|
470
|
-
await Promise.all(
|
|
471
|
-
dirItemNames.map(async (itemName) => {
|
|
472
|
-
const itemPath = normalizePath(join(dirPath, itemName));
|
|
473
|
-
const ext = getExtension(itemName);
|
|
474
|
-
const extlessName = removeExtension(itemName);
|
|
475
|
-
if ((isModuleExt(ext) || isPageModuleExt(ext)) && isPluginModule(extlessName)) {
|
|
476
|
-
sourceFiles.push({
|
|
477
|
-
id: createFileId(opts.serverPluginsDir, itemPath, "Plugin"),
|
|
478
|
-
filePath: itemPath,
|
|
479
|
-
ext
|
|
480
|
-
});
|
|
481
|
-
}
|
|
482
|
-
})
|
|
483
|
-
);
|
|
484
|
-
return sourceFiles;
|
|
485
|
-
}
|
|
486
|
-
|
|
487
|
-
async function parseRoutesDir(ctx) {
|
|
488
|
-
try {
|
|
489
|
-
await updateRoutingContext(ctx);
|
|
490
|
-
validateBuild(ctx);
|
|
491
|
-
} catch (e) {
|
|
492
|
-
addError(ctx, e);
|
|
506
|
+
function deriveFromTrie(opts, root) {
|
|
507
|
+
const layouts = [];
|
|
508
|
+
const routes = [];
|
|
509
|
+
const entries = [];
|
|
510
|
+
const serviceWorkers = [];
|
|
511
|
+
const menus = [];
|
|
512
|
+
const allFiles = [];
|
|
513
|
+
function collectAllFiles(node) {
|
|
514
|
+
allFiles.push(...node._files);
|
|
515
|
+
for (const child of node.children.values()) {
|
|
516
|
+
collectAllFiles(child);
|
|
517
|
+
}
|
|
493
518
|
}
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
console.warn(d.message);
|
|
519
|
+
collectAllFiles(root);
|
|
520
|
+
for (const file of allFiles) {
|
|
521
|
+
if (file.type === "layout") {
|
|
522
|
+
layouts.push(resolveLayout(opts, file));
|
|
499
523
|
}
|
|
500
524
|
}
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
ctx.entries = resolved.entries;
|
|
517
|
-
ctx.serviceWorkers = resolved.serviceWorkers;
|
|
518
|
-
ctx.menus = resolved.menus;
|
|
519
|
-
}
|
|
520
|
-
function rewriteRoutes(ctx, routes) {
|
|
521
|
-
if (!ctx.opts.rewriteRoutes) {
|
|
522
|
-
return routes;
|
|
525
|
+
for (const file of allFiles) {
|
|
526
|
+
switch (file.type) {
|
|
527
|
+
case "route":
|
|
528
|
+
routes.push(resolveRoute(opts, layouts, file));
|
|
529
|
+
break;
|
|
530
|
+
case "entry":
|
|
531
|
+
entries.push(resolveEntry(opts, file));
|
|
532
|
+
break;
|
|
533
|
+
case "service-worker":
|
|
534
|
+
serviceWorkers.push(resolveServiceWorkerEntry(opts, file));
|
|
535
|
+
break;
|
|
536
|
+
case "menu":
|
|
537
|
+
menus.push(resolveMenu(opts, file));
|
|
538
|
+
break;
|
|
539
|
+
}
|
|
523
540
|
}
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
);
|
|
535
|
-
if (foundSegmentToTranslate || route.pathname === "/") {
|
|
536
|
-
ctx.opts.rewriteRoutes.forEach((config, configIndex) => {
|
|
537
|
-
if (route.pathname === "/" && !config.prefix) {
|
|
538
|
-
return;
|
|
539
|
-
}
|
|
540
|
-
const routeToPush = translateRoute(route, config, configIndex);
|
|
541
|
-
if (!translatedRoutes.some(
|
|
542
|
-
(item) => item.pathname === routeToPush.pathname && item.routeName === routeToPush.routeName
|
|
543
|
-
)) {
|
|
544
|
-
translatedRoutes.push(routeToPush);
|
|
545
|
-
}
|
|
546
|
-
});
|
|
541
|
+
let inc = 0;
|
|
542
|
+
const ids = /* @__PURE__ */ new Set();
|
|
543
|
+
const uniqueIds = (items) => {
|
|
544
|
+
for (const item of items) {
|
|
545
|
+
let id = item.id;
|
|
546
|
+
while (ids.has(id)) {
|
|
547
|
+
id = `${item.id}_${inc++}`;
|
|
548
|
+
}
|
|
549
|
+
item.id = id;
|
|
550
|
+
ids.add(id);
|
|
547
551
|
}
|
|
548
|
-
}
|
|
549
|
-
|
|
552
|
+
};
|
|
553
|
+
uniqueIds(layouts);
|
|
554
|
+
uniqueIds(routes);
|
|
555
|
+
uniqueIds(entries);
|
|
556
|
+
uniqueIds(serviceWorkers);
|
|
557
|
+
layouts.sort((a, b) => a.id < b.id ? -1 : 1);
|
|
558
|
+
entries.sort((a, b) => a.chunkFileName < b.chunkFileName ? -1 : 1);
|
|
559
|
+
serviceWorkers.sort((a, b) => a.chunkFileName < b.chunkFileName ? -1 : 1);
|
|
560
|
+
menus.sort((a, b) => a.pathname < b.pathname ? -1 : 1);
|
|
561
|
+
return {
|
|
562
|
+
layouts,
|
|
563
|
+
routes,
|
|
564
|
+
entries,
|
|
565
|
+
serviceWorkers,
|
|
566
|
+
menus
|
|
567
|
+
};
|
|
550
568
|
}
|
|
551
569
|
function translateRoute(route, config, configIndex) {
|
|
552
570
|
const replacePath = (part) => (config.paths || {})[part] ?? part;
|
|
553
571
|
const pathnamePrefix = config.prefix ? "/" + config.prefix : "";
|
|
554
572
|
const routeNamePrefix = config.prefix ? config.prefix + "/" : "";
|
|
555
573
|
const idSuffix = config.prefix?.toUpperCase().replace(/-/g, "");
|
|
556
|
-
const patternInfix = config.prefix ? [
|
|
574
|
+
const patternInfix = config.prefix ? [
|
|
575
|
+
config.prefix
|
|
576
|
+
] : [];
|
|
557
577
|
const splittedPathName = route.pathname.split("/");
|
|
558
578
|
const translatedPathParts = splittedPathName.map(replacePath);
|
|
559
579
|
const splittedRouteName = route.routeName.split("/");
|
|
@@ -566,13 +586,11 @@ function translateRoute(route, config, configIndex) {
|
|
|
566
586
|
...translatedPatternOthers
|
|
567
587
|
];
|
|
568
588
|
const translatedPatternString = translatedPatternParts.join("\\/");
|
|
569
|
-
const translatedRegExp = translatedPatternString.substring(
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
(segment) => segment.map((item) => ({ ...item, content: replacePath(item.content) }))
|
|
575
|
-
);
|
|
589
|
+
const translatedRegExp = translatedPatternString.substring(1, route.pathname === "/" ? translatedPatternString.length - 1 : translatedPatternString.length - 2);
|
|
590
|
+
const translatedSegments = route.segments.map((segment) => segment.map((item) => ({
|
|
591
|
+
...item,
|
|
592
|
+
content: replacePath(item.content)
|
|
593
|
+
})));
|
|
576
594
|
if (config.prefix) {
|
|
577
595
|
translatedSegments.splice(0, 0, [
|
|
578
596
|
{
|
|
@@ -584,7 +602,7 @@ function translateRoute(route, config, configIndex) {
|
|
|
584
602
|
}
|
|
585
603
|
const translatedPath = translatedPathParts.join("/");
|
|
586
604
|
const translatedRoute = translatedRouteParts.join("/");
|
|
587
|
-
|
|
605
|
+
return {
|
|
588
606
|
...route,
|
|
589
607
|
id: route.id + (idSuffix || configIndex),
|
|
590
608
|
pathname: pathnamePrefix + translatedPath,
|
|
@@ -592,47 +610,81 @@ function translateRoute(route, config, configIndex) {
|
|
|
592
610
|
pattern: new RegExp(translatedRegExp),
|
|
593
611
|
segments: translatedSegments
|
|
594
612
|
};
|
|
595
|
-
|
|
613
|
+
}
|
|
614
|
+
function rewriteRoutes(ctx, routes) {
|
|
615
|
+
if (!ctx.opts.rewriteRoutes) {
|
|
616
|
+
return routes;
|
|
617
|
+
}
|
|
618
|
+
const translatedRoutes = [];
|
|
619
|
+
let segmentsToTranslate = ctx.opts.rewriteRoutes.flatMap((rewriteConfig) => {
|
|
620
|
+
return Object.keys(rewriteConfig.paths || {});
|
|
621
|
+
});
|
|
622
|
+
segmentsToTranslate = Array.from(new Set(segmentsToTranslate));
|
|
623
|
+
routes.forEach((route) => {
|
|
624
|
+
translatedRoutes.push(route);
|
|
625
|
+
const currentRouteSegments = route.pathname.split("/");
|
|
626
|
+
const foundSegmentToTranslate = currentRouteSegments.some((segment) => segmentsToTranslate.includes(segment));
|
|
627
|
+
if (foundSegmentToTranslate || route.pathname === "/") {
|
|
628
|
+
ctx.opts.rewriteRoutes.forEach((config, configIndex) => {
|
|
629
|
+
if (route.pathname === "/" && !config.prefix) {
|
|
630
|
+
return;
|
|
631
|
+
}
|
|
632
|
+
const routeToPush = translateRoute(route, config, configIndex);
|
|
633
|
+
if (!translatedRoutes.some((item) => item.pathname === routeToPush.pathname && item.routeName === routeToPush.routeName)) {
|
|
634
|
+
translatedRoutes.push(routeToPush);
|
|
635
|
+
}
|
|
636
|
+
});
|
|
637
|
+
}
|
|
638
|
+
});
|
|
639
|
+
return translatedRoutes.sort(routeSortCompare);
|
|
640
|
+
}
|
|
641
|
+
async function _updateRoutingContext(ctx) {
|
|
642
|
+
const serverPlugins = await walkServerPlugins(ctx.opts);
|
|
643
|
+
const routeTrie = await walkRoutes(ctx.opts.routesDir);
|
|
644
|
+
ctx.routeTrie = routeTrie;
|
|
645
|
+
ctx.serverPlugins = serverPlugins;
|
|
646
|
+
const derived = deriveFromTrie(ctx.opts, routeTrie);
|
|
647
|
+
ctx.layouts = derived.layouts;
|
|
648
|
+
ctx.routes = rewriteRoutes(ctx, derived.routes);
|
|
649
|
+
ctx.entries = derived.entries;
|
|
650
|
+
ctx.serviceWorkers = derived.serviceWorkers;
|
|
651
|
+
ctx.menus = derived.menus;
|
|
652
|
+
}
|
|
653
|
+
function updateRoutingContext(ctx) {
|
|
654
|
+
ctx.activeBuild ||= _updateRoutingContext(ctx).finally(() => {
|
|
655
|
+
ctx.activeBuild = null;
|
|
656
|
+
});
|
|
657
|
+
return ctx.activeBuild;
|
|
596
658
|
}
|
|
597
659
|
function validateBuild(ctx) {
|
|
598
660
|
const pathnames = Array.from(new Set(ctx.routes.map((r) => r.pathname))).sort();
|
|
599
661
|
for (const pathname of pathnames) {
|
|
600
662
|
const foundRoutes = ctx.routes.filter((r) => r.pathname === pathname);
|
|
601
663
|
if (foundRoutes.length > 1) {
|
|
602
|
-
addError(
|
|
603
|
-
|
|
604
|
-
`More than one route has been found for pathname "${pathname}". Please narrow it down to only one of these:
|
|
605
|
-
${foundRoutes.map((r) => ` - ${r.filePath}`).join("\n")}`
|
|
606
|
-
);
|
|
664
|
+
addError(ctx, `More than one route has been found for pathname "${pathname}". Please narrow it down to only one of these:
|
|
665
|
+
${foundRoutes.map((r) => ` - ${r.filePath}`).join("\n")}`);
|
|
607
666
|
}
|
|
608
667
|
}
|
|
609
668
|
ctx.layouts.filter((l) => l.layoutType === "top").forEach((l) => {
|
|
610
|
-
addWarning(
|
|
611
|
-
ctx,
|
|
612
|
-
`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/`
|
|
613
|
-
);
|
|
669
|
+
addWarning(ctx, `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/`);
|
|
614
670
|
});
|
|
615
671
|
}
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
dynamicImports: target === "client" || !!dynamicImports,
|
|
631
|
-
isDirty: true,
|
|
632
|
-
activeBuild: null
|
|
633
|
-
};
|
|
634
|
-
return ctx;
|
|
672
|
+
async function parseRoutesDir(ctx) {
|
|
673
|
+
try {
|
|
674
|
+
await updateRoutingContext(ctx);
|
|
675
|
+
validateBuild(ctx);
|
|
676
|
+
} catch (e) {
|
|
677
|
+
addError(ctx, e);
|
|
678
|
+
}
|
|
679
|
+
for (const d of ctx.diagnostics) {
|
|
680
|
+
if (d.type === "error") {
|
|
681
|
+
throw new Error(d.message);
|
|
682
|
+
} else {
|
|
683
|
+
console.warn(d.message);
|
|
684
|
+
}
|
|
685
|
+
}
|
|
635
686
|
}
|
|
687
|
+
|
|
636
688
|
function resetBuildContext(ctx) {
|
|
637
689
|
if (ctx) {
|
|
638
690
|
ctx.routes.length = 0;
|
|
@@ -646,14 +698,14 @@ function resetBuildContext(ctx) {
|
|
|
646
698
|
}
|
|
647
699
|
function normalizeOptions(rootDir, viteBasePath, userOpts) {
|
|
648
700
|
if (!(viteBasePath.startsWith("/") && viteBasePath.endsWith("/"))) {
|
|
649
|
-
console.error(
|
|
650
|
-
`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.`
|
|
651
|
-
);
|
|
701
|
+
console.error(`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.`);
|
|
652
702
|
if (!viteBasePath.endsWith("/")) {
|
|
653
703
|
viteBasePath += "/";
|
|
654
704
|
}
|
|
655
705
|
}
|
|
656
|
-
const opts = {
|
|
706
|
+
const opts = {
|
|
707
|
+
...userOpts
|
|
708
|
+
};
|
|
657
709
|
if (typeof opts.routesDir !== "string") {
|
|
658
710
|
opts.routesDir = resolve(rootDir, "src", "routes");
|
|
659
711
|
} else if (!isAbsolute(opts.routesDir)) {
|
|
@@ -673,9 +725,7 @@ function normalizeOptions(rootDir, viteBasePath, userOpts) {
|
|
|
673
725
|
opts.basePathname = viteBasePath;
|
|
674
726
|
}
|
|
675
727
|
if (!opts.basePathname.endsWith("/")) {
|
|
676
|
-
console.error(
|
|
677
|
-
`Warning: qwik-router plugin basePathname must end with /. This will be an error in v2`
|
|
678
|
-
);
|
|
728
|
+
console.error(`Warning: qwik-router plugin basePathname must end with /. This will be an error in v2`);
|
|
679
729
|
opts.basePathname += "/";
|
|
680
730
|
}
|
|
681
731
|
const url = new URL(opts.basePathname, "https://qwik.dev/");
|
|
@@ -684,9 +734,42 @@ function normalizeOptions(rootDir, viteBasePath, userOpts) {
|
|
|
684
734
|
opts.platform = opts.platform || {};
|
|
685
735
|
return opts;
|
|
686
736
|
}
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
737
|
+
function createBuildContext(rootDir, viteBasePath, userOpts, target, dynamicImports) {
|
|
738
|
+
const ctx = {
|
|
739
|
+
rootDir: normalizePath(rootDir),
|
|
740
|
+
opts: normalizeOptions(rootDir, viteBasePath, userOpts),
|
|
741
|
+
routeTrie: {
|
|
742
|
+
_files: [],
|
|
743
|
+
_dirPath: "",
|
|
744
|
+
children: /* @__PURE__ */ new Map()
|
|
745
|
+
},
|
|
746
|
+
routes: [],
|
|
747
|
+
serverPlugins: [],
|
|
748
|
+
layouts: [],
|
|
749
|
+
entries: [],
|
|
750
|
+
serviceWorkers: [],
|
|
751
|
+
menus: [],
|
|
752
|
+
diagnostics: [],
|
|
753
|
+
frontmatter: /* @__PURE__ */ new Map(),
|
|
754
|
+
target: target || "ssr",
|
|
755
|
+
dynamicImports: target === "client" || !!dynamicImports,
|
|
756
|
+
isDirty: true,
|
|
757
|
+
activeBuild: null
|
|
758
|
+
};
|
|
759
|
+
return ctx;
|
|
760
|
+
}
|
|
761
|
+
|
|
762
|
+
function parseFrontmatterAttrs(yaml) {
|
|
763
|
+
if (typeof yaml === "string") {
|
|
764
|
+
yaml = yaml.trim();
|
|
765
|
+
if (yaml !== "") {
|
|
766
|
+
return parse(yaml);
|
|
767
|
+
}
|
|
768
|
+
}
|
|
769
|
+
return null;
|
|
770
|
+
}
|
|
771
|
+
function parseFrontmatter(ctx) {
|
|
772
|
+
return (mdast, vfile) => {
|
|
690
773
|
const attrs = {};
|
|
691
774
|
visit(mdast, "yaml", (node) => {
|
|
692
775
|
const parsedAttrs = parseFrontmatterAttrs(node.value);
|
|
@@ -699,15 +782,6 @@ function parseFrontmatter(ctx) {
|
|
|
699
782
|
}
|
|
700
783
|
};
|
|
701
784
|
}
|
|
702
|
-
function parseFrontmatterAttrs(yaml) {
|
|
703
|
-
if (typeof yaml === "string") {
|
|
704
|
-
yaml = yaml.trim();
|
|
705
|
-
if (yaml !== "") {
|
|
706
|
-
return parse(yaml);
|
|
707
|
-
}
|
|
708
|
-
}
|
|
709
|
-
return null;
|
|
710
|
-
}
|
|
711
785
|
const metaNames = {
|
|
712
786
|
author: true,
|
|
713
787
|
creator: true,
|
|
@@ -741,7 +815,9 @@ function frontmatterAttrsToDocumentHead(attrs) {
|
|
|
741
815
|
head.title = head.title.replace(/\\@/g, "@");
|
|
742
816
|
} else if (attrName === "og" || attrName === "opengraph") {
|
|
743
817
|
if (typeof attrValue === "object") {
|
|
744
|
-
for (const opengraph of Array.isArray(attrValue) ? attrValue : [
|
|
818
|
+
for (const opengraph of Array.isArray(attrValue) ? attrValue : [
|
|
819
|
+
attrValue
|
|
820
|
+
]) {
|
|
745
821
|
if (opengraph != null && typeof opengraph === "object" && !Array.isArray(opengraph)) {
|
|
746
822
|
for (const [property, content] of Object.entries(opengraph)) {
|
|
747
823
|
if ((property === "title" || property === "description") && content === true) {
|
|
@@ -777,31 +853,6 @@ function frontmatterAttrsToDocumentHead(attrs) {
|
|
|
777
853
|
return null;
|
|
778
854
|
}
|
|
779
855
|
|
|
780
|
-
function rehypeSlug() {
|
|
781
|
-
return (ast) => {
|
|
782
|
-
const mdast = ast;
|
|
783
|
-
const slugs = new Slugger();
|
|
784
|
-
visit(mdast, "element", (node) => {
|
|
785
|
-
const level = headingRank(node);
|
|
786
|
-
if (level && node.properties) {
|
|
787
|
-
const text = toString(node);
|
|
788
|
-
if (!hasProperty(node, "id")) {
|
|
789
|
-
node.properties.id = slugs.slug(text);
|
|
790
|
-
}
|
|
791
|
-
}
|
|
792
|
-
});
|
|
793
|
-
};
|
|
794
|
-
}
|
|
795
|
-
function rehypePage(ctx) {
|
|
796
|
-
return (ast, vfile) => {
|
|
797
|
-
const mdast = ast;
|
|
798
|
-
const sourcePath = normalizePath(vfile.path);
|
|
799
|
-
updateContentLinks(mdast, ctx.opts, sourcePath);
|
|
800
|
-
exportFrontmatter(ctx, mdast, sourcePath);
|
|
801
|
-
exportContentHead(ctx, mdast, sourcePath);
|
|
802
|
-
exportContentHeadings(mdast);
|
|
803
|
-
};
|
|
804
|
-
}
|
|
805
856
|
function renameClassname() {
|
|
806
857
|
return (ast) => {
|
|
807
858
|
const mdast = ast;
|
|
@@ -820,11 +871,17 @@ function wrapTableWithDiv() {
|
|
|
820
871
|
const mdast = ast;
|
|
821
872
|
visit(mdast, "element", (node) => {
|
|
822
873
|
if (node.tagName === "table" && !node.done) {
|
|
823
|
-
const table = {
|
|
874
|
+
const table = {
|
|
875
|
+
...node
|
|
876
|
+
};
|
|
824
877
|
table.done = true;
|
|
825
878
|
node.tagName = "div";
|
|
826
|
-
node.properties = {
|
|
827
|
-
|
|
879
|
+
node.properties = {
|
|
880
|
+
className: "table-wrapper"
|
|
881
|
+
};
|
|
882
|
+
node.children = [
|
|
883
|
+
table
|
|
884
|
+
];
|
|
828
885
|
}
|
|
829
886
|
});
|
|
830
887
|
};
|
|
@@ -837,47 +894,12 @@ function updateContentLinks(mdast, opts, sourcePath) {
|
|
|
837
894
|
if (isSameOriginUrl(href)) {
|
|
838
895
|
const ext = getExtension(href);
|
|
839
896
|
if (isMarkdownExt(ext)) {
|
|
840
|
-
node.properties.href = getMarkdownRelativeUrl(
|
|
841
|
-
opts,
|
|
842
|
-
sourcePath,
|
|
843
|
-
node.properties.href,
|
|
844
|
-
true
|
|
845
|
-
);
|
|
897
|
+
node.properties.href = getMarkdownRelativeUrl(opts, sourcePath, node.properties.href, true);
|
|
846
898
|
}
|
|
847
899
|
}
|
|
848
900
|
}
|
|
849
901
|
});
|
|
850
902
|
}
|
|
851
|
-
function exportFrontmatter(ctx, mdast, sourcePath) {
|
|
852
|
-
const attrs = ctx.frontmatter.get(sourcePath);
|
|
853
|
-
createExport(mdast, "frontmatter", attrs);
|
|
854
|
-
}
|
|
855
|
-
function exportContentHead(ctx, mdast, sourcePath) {
|
|
856
|
-
const attrs = ctx.frontmatter.get(sourcePath);
|
|
857
|
-
const head = frontmatterAttrsToDocumentHead(attrs);
|
|
858
|
-
if (head) {
|
|
859
|
-
createExport(mdast, "head", head);
|
|
860
|
-
}
|
|
861
|
-
}
|
|
862
|
-
function exportContentHeadings(mdast) {
|
|
863
|
-
const headings = [];
|
|
864
|
-
visit(mdast, "element", (node) => {
|
|
865
|
-
const level = headingRank(node);
|
|
866
|
-
if (level && node.properties) {
|
|
867
|
-
if (hasProperty(node, "id")) {
|
|
868
|
-
const text = toString(node);
|
|
869
|
-
headings.push({
|
|
870
|
-
text,
|
|
871
|
-
id: node.properties.id,
|
|
872
|
-
level
|
|
873
|
-
});
|
|
874
|
-
}
|
|
875
|
-
}
|
|
876
|
-
});
|
|
877
|
-
if (headings.length > 0) {
|
|
878
|
-
createExport(mdast, "headings", headings);
|
|
879
|
-
}
|
|
880
|
-
}
|
|
881
903
|
function createExport(mdast, identifierName, val) {
|
|
882
904
|
const mdxjsEsm = {
|
|
883
905
|
type: "mdxjsEsm",
|
|
@@ -898,7 +920,10 @@ function createExport(mdast, identifierName, val) {
|
|
|
898
920
|
declarations: [
|
|
899
921
|
{
|
|
900
922
|
type: "VariableDeclarator",
|
|
901
|
-
id: {
|
|
923
|
+
id: {
|
|
924
|
+
type: "Identifier",
|
|
925
|
+
name: identifierName
|
|
926
|
+
},
|
|
902
927
|
init: valueToEstree(val)
|
|
903
928
|
}
|
|
904
929
|
]
|
|
@@ -910,31 +935,67 @@ function createExport(mdast, identifierName, val) {
|
|
|
910
935
|
};
|
|
911
936
|
mdast.children.unshift(mdxjsEsm);
|
|
912
937
|
}
|
|
938
|
+
function exportFrontmatter(ctx, mdast, sourcePath) {
|
|
939
|
+
const attrs = ctx.frontmatter.get(sourcePath);
|
|
940
|
+
createExport(mdast, "frontmatter", attrs);
|
|
941
|
+
}
|
|
942
|
+
function exportContentHead(ctx, mdast, sourcePath) {
|
|
943
|
+
const attrs = ctx.frontmatter.get(sourcePath);
|
|
944
|
+
const head = frontmatterAttrsToDocumentHead(attrs);
|
|
945
|
+
if (head) {
|
|
946
|
+
createExport(mdast, "head", head);
|
|
947
|
+
}
|
|
948
|
+
}
|
|
913
949
|
const own = {}.hasOwnProperty;
|
|
914
950
|
function hasProperty(node, propName) {
|
|
915
951
|
const value = node && typeof node === "object" && node.type === "element" && node.properties && own.call(node.properties, propName) && node.properties[propName];
|
|
916
952
|
return value != null && value !== false;
|
|
917
953
|
}
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
visit(
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
const lang = getLanguage(className);
|
|
929
|
-
if (lang && refractor.registered(lang)) {
|
|
930
|
-
node.properties.className[i] = "language-" + lang;
|
|
931
|
-
syntaxHighlight(node, lang);
|
|
932
|
-
return;
|
|
954
|
+
function rehypeSlug() {
|
|
955
|
+
return (ast) => {
|
|
956
|
+
const mdast = ast;
|
|
957
|
+
const slugs = new Slugger();
|
|
958
|
+
visit(mdast, "element", (node) => {
|
|
959
|
+
const level = headingRank(node);
|
|
960
|
+
if (level && node.properties) {
|
|
961
|
+
const text = toString(node);
|
|
962
|
+
if (!hasProperty(node, "id")) {
|
|
963
|
+
node.properties.id = slugs.slug(text);
|
|
933
964
|
}
|
|
934
965
|
}
|
|
935
966
|
});
|
|
936
967
|
};
|
|
937
968
|
}
|
|
969
|
+
function exportContentHeadings(mdast) {
|
|
970
|
+
const headings = [];
|
|
971
|
+
visit(mdast, "element", (node) => {
|
|
972
|
+
const level = headingRank(node);
|
|
973
|
+
if (level && node.properties) {
|
|
974
|
+
if (hasProperty(node, "id")) {
|
|
975
|
+
const text = toString(node);
|
|
976
|
+
headings.push({
|
|
977
|
+
text,
|
|
978
|
+
id: node.properties.id,
|
|
979
|
+
level
|
|
980
|
+
});
|
|
981
|
+
}
|
|
982
|
+
}
|
|
983
|
+
});
|
|
984
|
+
if (headings.length > 0) {
|
|
985
|
+
createExport(mdast, "headings", headings);
|
|
986
|
+
}
|
|
987
|
+
}
|
|
988
|
+
function rehypePage(ctx) {
|
|
989
|
+
return (ast, vfile) => {
|
|
990
|
+
const mdast = ast;
|
|
991
|
+
const sourcePath = normalizePath(vfile.path);
|
|
992
|
+
updateContentLinks(mdast, ctx.opts, sourcePath);
|
|
993
|
+
exportFrontmatter(ctx, mdast, sourcePath);
|
|
994
|
+
exportContentHead(ctx, mdast, sourcePath);
|
|
995
|
+
exportContentHeadings(mdast);
|
|
996
|
+
};
|
|
997
|
+
}
|
|
998
|
+
|
|
938
999
|
function syntaxHighlight(node, lang) {
|
|
939
1000
|
const code = toString(node);
|
|
940
1001
|
const result = refractor.highlight(code, lang);
|
|
@@ -951,6 +1012,25 @@ function getLanguage(className) {
|
|
|
951
1012
|
}
|
|
952
1013
|
return null;
|
|
953
1014
|
}
|
|
1015
|
+
function rehypeSyntaxHighlight() {
|
|
1016
|
+
refractor.register(tsxLang);
|
|
1017
|
+
return async (ast) => {
|
|
1018
|
+
visit(ast, "element", (node, _index, parent) => {
|
|
1019
|
+
if (!parent || parent.tagName !== "pre" || node.tagName !== "code" || !Array.isArray(node.properties.className)) {
|
|
1020
|
+
return;
|
|
1021
|
+
}
|
|
1022
|
+
for (let i = 0; i < node.properties.className.length; i++) {
|
|
1023
|
+
const className = node.properties.className[i];
|
|
1024
|
+
const lang = getLanguage(className);
|
|
1025
|
+
if (lang && refractor.registered(lang)) {
|
|
1026
|
+
node.properties.className[i] = "language-" + lang;
|
|
1027
|
+
syntaxHighlight(node, lang);
|
|
1028
|
+
return;
|
|
1029
|
+
}
|
|
1030
|
+
}
|
|
1031
|
+
});
|
|
1032
|
+
};
|
|
1033
|
+
}
|
|
954
1034
|
|
|
955
1035
|
async function createMdxTransformer(ctx) {
|
|
956
1036
|
const { compile } = await import('@mdx-js/mdx');
|
|
@@ -982,21 +1062,34 @@ async function createMdxTransformer(ctx) {
|
|
|
982
1062
|
...userRemarkPlugins,
|
|
983
1063
|
...coreRemarkPlugins,
|
|
984
1064
|
remarkFrontmatter,
|
|
985
|
-
[
|
|
1065
|
+
[
|
|
1066
|
+
parseFrontmatter,
|
|
1067
|
+
ctx
|
|
1068
|
+
]
|
|
986
1069
|
],
|
|
987
1070
|
rehypePlugins: [
|
|
988
1071
|
rehypeSlug,
|
|
989
1072
|
...userRehypePlugins,
|
|
990
1073
|
...coreRehypePlugins,
|
|
991
|
-
[
|
|
1074
|
+
[
|
|
1075
|
+
rehypePage,
|
|
1076
|
+
ctx
|
|
1077
|
+
],
|
|
992
1078
|
renameClassname,
|
|
993
1079
|
wrapTableWithDiv
|
|
994
1080
|
]
|
|
995
1081
|
};
|
|
996
1082
|
return async function(code, id) {
|
|
997
1083
|
const ext = getExtension(id);
|
|
998
|
-
if ([
|
|
999
|
-
|
|
1084
|
+
if ([
|
|
1085
|
+
".mdx",
|
|
1086
|
+
".md",
|
|
1087
|
+
".markdown"
|
|
1088
|
+
].includes(ext)) {
|
|
1089
|
+
const file = new VFile({
|
|
1090
|
+
value: code,
|
|
1091
|
+
path: id
|
|
1092
|
+
});
|
|
1000
1093
|
const compiled = await compile(file, options);
|
|
1001
1094
|
const output = String(compiled.value);
|
|
1002
1095
|
const addImport = `import { jsx } from '@qwik.dev/core';
|
|
@@ -1015,7 +1108,13 @@ export default WrappedMdxContent;
|
|
|
1015
1108
|
if (exportIndex === -1) {
|
|
1016
1109
|
throw new Error("Could not find default export in mdx output");
|
|
1017
1110
|
}
|
|
1018
|
-
|
|
1111
|
+
let eTagExport = "";
|
|
1112
|
+
if (ext === ".md" || ext === ".markdown") {
|
|
1113
|
+
const hash = createHash("sha256").update(code).digest("hex").slice(0, 16);
|
|
1114
|
+
eTagExport = `export const eTag = ${JSON.stringify(hash)};
|
|
1115
|
+
`;
|
|
1116
|
+
}
|
|
1117
|
+
const wrappedOutput = addImport + output.slice(0, exportIndex) + eTagExport + newDefault;
|
|
1019
1118
|
return {
|
|
1020
1119
|
code: wrappedOutput,
|
|
1021
1120
|
map: compiled.map
|
|
@@ -1026,7 +1125,10 @@ export default WrappedMdxContent;
|
|
|
1026
1125
|
|
|
1027
1126
|
function createEntries(ctx, c) {
|
|
1028
1127
|
const isClient = ctx.target === "client";
|
|
1029
|
-
const entries = [
|
|
1128
|
+
const entries = [
|
|
1129
|
+
...ctx.entries,
|
|
1130
|
+
...ctx.serviceWorkers
|
|
1131
|
+
];
|
|
1030
1132
|
if (isClient && entries.length > 0) {
|
|
1031
1133
|
c.push(`
|
|
1032
1134
|
/** Qwik Router Entries Entry */`);
|
|
@@ -1036,7 +1138,10 @@ function createEntries(ctx, c) {
|
|
|
1036
1138
|
}
|
|
1037
1139
|
function generateQwikRouterEntries(ctx) {
|
|
1038
1140
|
const c = [];
|
|
1039
|
-
const entries = [
|
|
1141
|
+
const entries = [
|
|
1142
|
+
...ctx.entries,
|
|
1143
|
+
...ctx.serviceWorkers
|
|
1144
|
+
];
|
|
1040
1145
|
c.push(`
|
|
1041
1146
|
/** Qwik Router Entries (${entries.length}) */`);
|
|
1042
1147
|
for (let i = 0; i < entries.length; i++) {
|
|
@@ -1057,80 +1162,41 @@ function getImportPath(importPath) {
|
|
|
1057
1162
|
return importPath;
|
|
1058
1163
|
}
|
|
1059
1164
|
|
|
1060
|
-
function
|
|
1061
|
-
|
|
1062
|
-
/** Qwik Router Menus (${ctx.menus.length}) */`);
|
|
1063
|
-
c.push(`export const menus = [`);
|
|
1064
|
-
const dynamicImports = !isSSR;
|
|
1065
|
-
const routesDir = ctx.opts.routesDir;
|
|
1066
|
-
for (const m of ctx.menus) {
|
|
1067
|
-
const importPath = JSON.stringify(getImportPath(m.filePath));
|
|
1068
|
-
if (dynamicImports) {
|
|
1069
|
-
c.push(` [${JSON.stringify(m.pathname)}, ()=>import(${importPath})],`);
|
|
1070
|
-
} else {
|
|
1071
|
-
const id = createFileId(routesDir, m.filePath);
|
|
1072
|
-
esmImports.push(`import * as ${id} from ${importPath};`);
|
|
1073
|
-
c.push(` [${JSON.stringify(m.pathname)}, ()=>${id}],`);
|
|
1074
|
-
}
|
|
1075
|
-
}
|
|
1076
|
-
c.push(`];`);
|
|
1165
|
+
function isGroupKey(key) {
|
|
1166
|
+
return key.charCodeAt(0) === 40;
|
|
1077
1167
|
}
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
const dynamicImports = ctx.dynamicImports;
|
|
1082
|
-
if (ctx.layouts.length > 0) {
|
|
1083
|
-
c.push(`
|
|
1084
|
-
/** Qwik Router Layouts (${ctx.layouts.length}) */`);
|
|
1085
|
-
for (const layout of ctx.layouts) {
|
|
1086
|
-
const importPath = JSON.stringify(getImportPath(layout.filePath));
|
|
1087
|
-
if (dynamicImports) {
|
|
1088
|
-
c.push(`const ${layout.id} = ()=>import(${importPath});`);
|
|
1089
|
-
} else {
|
|
1090
|
-
esmImports.push(`import * as ${layout.id}_ from ${importPath};`);
|
|
1091
|
-
c.push(`const ${layout.id} = ()=>${layout.id}_;`);
|
|
1092
|
-
}
|
|
1093
|
-
}
|
|
1168
|
+
function collectFiles(node, cb) {
|
|
1169
|
+
for (const file of node._files) {
|
|
1170
|
+
cb(file, node);
|
|
1094
1171
|
}
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1172
|
+
for (const child of node.children.values()) {
|
|
1173
|
+
collectFiles(child, cb);
|
|
1174
|
+
}
|
|
1175
|
+
}
|
|
1176
|
+
function resolveNamedLayoutChain(ancestorLayouts, nodeLayouts, targetName) {
|
|
1177
|
+
const allLayouts = [
|
|
1178
|
+
...ancestorLayouts,
|
|
1179
|
+
...nodeLayouts
|
|
1180
|
+
];
|
|
1181
|
+
const result = [];
|
|
1182
|
+
let foundNamed = false;
|
|
1183
|
+
for (let i = allLayouts.length - 1; i >= 0; i--) {
|
|
1184
|
+
const layout = allLayouts[i];
|
|
1185
|
+
if (!foundNamed) {
|
|
1186
|
+
if (layout.layoutName === targetName) {
|
|
1187
|
+
result.unshift(layout);
|
|
1188
|
+
foundNamed = true;
|
|
1110
1189
|
}
|
|
1111
|
-
} else
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1190
|
+
} else {
|
|
1191
|
+
if (layout.layoutName === "") {
|
|
1192
|
+
result.unshift(layout);
|
|
1193
|
+
if (layout.layoutType === "top") {
|
|
1194
|
+
break;
|
|
1195
|
+
}
|
|
1116
1196
|
}
|
|
1117
|
-
layouts.push(`()=>${route.id}`);
|
|
1118
|
-
}
|
|
1119
|
-
if (layouts.length > 0) {
|
|
1120
|
-
c.push(` ${createRouteData(qwikPlugin, route, layouts, isSSR)},`);
|
|
1121
1197
|
}
|
|
1122
1198
|
}
|
|
1123
|
-
|
|
1124
|
-
}
|
|
1125
|
-
function createRouteData(qwikPlugin, r, layouts, isSsr) {
|
|
1126
|
-
const routeName = JSON.stringify(r.routeName);
|
|
1127
|
-
const moduleLayouts = `[ ${layouts.join(", ")} ]`;
|
|
1128
|
-
if (isSsr) {
|
|
1129
|
-
const originalPathname = JSON.stringify(r.pathname);
|
|
1130
|
-
const clientBundleNames = JSON.stringify(getClientRouteBundleNames(qwikPlugin, r));
|
|
1131
|
-
return `[ ${routeName}, ${moduleLayouts}, ${originalPathname}, ${clientBundleNames} ]`;
|
|
1132
|
-
}
|
|
1133
|
-
return `[ ${routeName}, ${moduleLayouts} ]`;
|
|
1199
|
+
return result;
|
|
1134
1200
|
}
|
|
1135
1201
|
function getClientRouteBundleNames(qwikPlugin, r) {
|
|
1136
1202
|
const bundlesNames = [];
|
|
@@ -1152,13 +1218,249 @@ function getClientRouteBundleNames(qwikPlugin, r) {
|
|
|
1152
1218
|
}
|
|
1153
1219
|
}
|
|
1154
1220
|
}
|
|
1155
|
-
};
|
|
1156
|
-
for (const layout of r.layouts) {
|
|
1157
|
-
addRouteFile(layout.filePath);
|
|
1221
|
+
};
|
|
1222
|
+
for (const layout of r.layouts) {
|
|
1223
|
+
addRouteFile(layout.filePath);
|
|
1224
|
+
}
|
|
1225
|
+
addRouteFile(r.filePath);
|
|
1226
|
+
}
|
|
1227
|
+
return bundlesNames;
|
|
1228
|
+
}
|
|
1229
|
+
function serializeBuildTrie(ctx, qwikPlugin, node, layoutIdMap, routeIdMap, menuIdMap, errorFiles, notFoundFiles, ancestorLayouts, isSSR, indent) {
|
|
1230
|
+
const lines = [];
|
|
1231
|
+
const nextIndent = indent + " ";
|
|
1232
|
+
if (node._P) {
|
|
1233
|
+
lines.push(`${nextIndent}_P: ${JSON.stringify(node._P)},`);
|
|
1234
|
+
}
|
|
1235
|
+
if (node._0) {
|
|
1236
|
+
lines.push(`${nextIndent}_0: ${JSON.stringify(node._0)},`);
|
|
1237
|
+
}
|
|
1238
|
+
if (node._9) {
|
|
1239
|
+
lines.push(`${nextIndent}_9: ${JSON.stringify(node._9)},`);
|
|
1240
|
+
}
|
|
1241
|
+
if (node._G) {
|
|
1242
|
+
lines.push(`${nextIndent}_G: ${JSON.stringify(node._G)},`);
|
|
1243
|
+
}
|
|
1244
|
+
let layoutExpr;
|
|
1245
|
+
let indexExpr;
|
|
1246
|
+
let indexIsOverride = false;
|
|
1247
|
+
let errorExpr;
|
|
1248
|
+
let notFoundExpr;
|
|
1249
|
+
let menuExpr;
|
|
1250
|
+
let bundleRoute;
|
|
1251
|
+
const nodeLayouts = [];
|
|
1252
|
+
for (const file of node._files) {
|
|
1253
|
+
if (file.type === "menu") {
|
|
1254
|
+
const menuId = menuIdMap.get(file.filePath);
|
|
1255
|
+
if (menuId) {
|
|
1256
|
+
menuExpr = menuId;
|
|
1257
|
+
}
|
|
1258
|
+
} else if (file.type === "layout") {
|
|
1259
|
+
const layoutId = layoutIdMap.get(file.filePath);
|
|
1260
|
+
if (layoutId) {
|
|
1261
|
+
let extlessName = file.extlessName;
|
|
1262
|
+
let layoutType = "nested";
|
|
1263
|
+
if (extlessName.endsWith("!")) {
|
|
1264
|
+
layoutType = "top";
|
|
1265
|
+
extlessName = extlessName.slice(0, -1);
|
|
1266
|
+
}
|
|
1267
|
+
const layoutName = extlessName.startsWith("layout-") ? extlessName.slice("layout-".length) : "";
|
|
1268
|
+
nodeLayouts.push({
|
|
1269
|
+
id: layoutId,
|
|
1270
|
+
layoutName,
|
|
1271
|
+
layoutType
|
|
1272
|
+
});
|
|
1273
|
+
if (layoutName === "") {
|
|
1274
|
+
layoutExpr = layoutId;
|
|
1275
|
+
}
|
|
1276
|
+
}
|
|
1277
|
+
}
|
|
1278
|
+
}
|
|
1279
|
+
for (const file of node._files) {
|
|
1280
|
+
if (file.type !== "route") {
|
|
1281
|
+
continue;
|
|
1282
|
+
}
|
|
1283
|
+
const loaderExpr = routeIdMap.get(file.filePath);
|
|
1284
|
+
if (!loaderExpr) {
|
|
1285
|
+
continue;
|
|
1286
|
+
}
|
|
1287
|
+
const isError = file.extlessName === "error";
|
|
1288
|
+
const is404 = file.extlessName === "404";
|
|
1289
|
+
if (isError) {
|
|
1290
|
+
errorExpr = loaderExpr;
|
|
1291
|
+
errorFiles.set(node._dirPath, file.filePath);
|
|
1292
|
+
} else if (is404) {
|
|
1293
|
+
notFoundExpr = loaderExpr;
|
|
1294
|
+
notFoundFiles.set(node._dirPath, file.filePath);
|
|
1295
|
+
} else {
|
|
1296
|
+
const { layoutName, layoutStop } = parseRouteIndexName(file.extlessName);
|
|
1297
|
+
if (layoutStop) {
|
|
1298
|
+
indexExpr = `[ ${loaderExpr} ]`;
|
|
1299
|
+
indexIsOverride = true;
|
|
1300
|
+
} else if (layoutName) {
|
|
1301
|
+
const chain = resolveNamedLayoutChain(ancestorLayouts, nodeLayouts, layoutName);
|
|
1302
|
+
const chainExprs = chain.map((l) => l.id);
|
|
1303
|
+
chainExprs.push(loaderExpr);
|
|
1304
|
+
indexExpr = `[ ${chainExprs.join(", ")} ]`;
|
|
1305
|
+
indexIsOverride = true;
|
|
1306
|
+
} else {
|
|
1307
|
+
indexExpr = loaderExpr;
|
|
1308
|
+
}
|
|
1309
|
+
bundleRoute = ctx.routes.find((r) => r.filePath === file.filePath);
|
|
1310
|
+
}
|
|
1311
|
+
}
|
|
1312
|
+
if (layoutExpr) {
|
|
1313
|
+
lines.push(`${nextIndent}_L: ${layoutExpr},`);
|
|
1314
|
+
}
|
|
1315
|
+
if (indexExpr) {
|
|
1316
|
+
if (indexIsOverride) {
|
|
1317
|
+
lines.push(`${nextIndent}_I: ${indexExpr},`);
|
|
1318
|
+
} else {
|
|
1319
|
+
lines.push(`${nextIndent}_I: ${indexExpr},`);
|
|
1320
|
+
}
|
|
1321
|
+
if (isSSR && bundleRoute) {
|
|
1322
|
+
const bundleNames = getClientRouteBundleNames(qwikPlugin, bundleRoute);
|
|
1323
|
+
if (bundleNames.length > 0) {
|
|
1324
|
+
lines.push(`${nextIndent}_B: ${JSON.stringify(bundleNames)},`);
|
|
1325
|
+
}
|
|
1326
|
+
}
|
|
1327
|
+
}
|
|
1328
|
+
if (errorExpr) {
|
|
1329
|
+
lines.push(`${nextIndent}_E: ${errorExpr},`);
|
|
1330
|
+
}
|
|
1331
|
+
if (notFoundExpr) {
|
|
1332
|
+
lines.push(`${nextIndent}_4: ${notFoundExpr},`);
|
|
1333
|
+
}
|
|
1334
|
+
if (menuExpr) {
|
|
1335
|
+
lines.push(`${nextIndent}_N: ${menuExpr},`);
|
|
1336
|
+
}
|
|
1337
|
+
const childAncestors = [
|
|
1338
|
+
...ancestorLayouts,
|
|
1339
|
+
...nodeLayouts
|
|
1340
|
+
];
|
|
1341
|
+
const groupChildren = [];
|
|
1342
|
+
const regularChildren = [];
|
|
1343
|
+
for (const [key, child] of node.children) {
|
|
1344
|
+
if (isGroupKey(key)) {
|
|
1345
|
+
groupChildren.push([
|
|
1346
|
+
key,
|
|
1347
|
+
child
|
|
1348
|
+
]);
|
|
1349
|
+
} else {
|
|
1350
|
+
regularChildren.push([
|
|
1351
|
+
key,
|
|
1352
|
+
child
|
|
1353
|
+
]);
|
|
1354
|
+
}
|
|
1355
|
+
}
|
|
1356
|
+
if (groupChildren.length > 0) {
|
|
1357
|
+
groupChildren.sort((a, b) => a[0].localeCompare(b[0]));
|
|
1358
|
+
const groupStrs = [];
|
|
1359
|
+
for (const [_key, child] of groupChildren) {
|
|
1360
|
+
const childStr = serializeBuildTrie(ctx, qwikPlugin, child, layoutIdMap, routeIdMap, menuIdMap, errorFiles, notFoundFiles, childAncestors, isSSR, nextIndent);
|
|
1361
|
+
if (childStr !== "{}") {
|
|
1362
|
+
groupStrs.push(childStr);
|
|
1363
|
+
}
|
|
1364
|
+
}
|
|
1365
|
+
if (groupStrs.length > 0) {
|
|
1366
|
+
lines.push(`${nextIndent}_M: [${groupStrs.join(", ")}],`);
|
|
1367
|
+
}
|
|
1368
|
+
}
|
|
1369
|
+
for (const [key, child] of regularChildren) {
|
|
1370
|
+
const childStr = serializeBuildTrie(ctx, qwikPlugin, child, layoutIdMap, routeIdMap, menuIdMap, errorFiles, notFoundFiles, childAncestors, isSSR, nextIndent);
|
|
1371
|
+
if (childStr !== "{}") {
|
|
1372
|
+
const keyStr = JSON.stringify(key);
|
|
1373
|
+
lines.push(`${nextIndent}${keyStr}: ${childStr},`);
|
|
1374
|
+
}
|
|
1375
|
+
}
|
|
1376
|
+
if (lines.length === 0) {
|
|
1377
|
+
return "{}";
|
|
1378
|
+
}
|
|
1379
|
+
return `{
|
|
1380
|
+
${lines.join("\n")}
|
|
1381
|
+
${indent}}`;
|
|
1382
|
+
}
|
|
1383
|
+
function createRoutes(ctx, qwikPlugin, c, esmImports, isSSR) {
|
|
1384
|
+
const includeEndpoints = isSSR;
|
|
1385
|
+
const dynamicImports = ctx.dynamicImports;
|
|
1386
|
+
const layoutIdMap = /* @__PURE__ */ new Map();
|
|
1387
|
+
const routeIdMap = /* @__PURE__ */ new Map();
|
|
1388
|
+
const menuIdMap = /* @__PURE__ */ new Map();
|
|
1389
|
+
const errorFiles = /* @__PURE__ */ new Map();
|
|
1390
|
+
const notFoundFiles = /* @__PURE__ */ new Map();
|
|
1391
|
+
let layoutCount = 0;
|
|
1392
|
+
let routeCount = 0;
|
|
1393
|
+
let menuCount = 0;
|
|
1394
|
+
collectFiles(ctx.routeTrie, (file, _node) => {
|
|
1395
|
+
if (file.type === "layout") {
|
|
1396
|
+
const id = ctx.layouts.find((l) => l.filePath === file.filePath)?.id;
|
|
1397
|
+
if (id) {
|
|
1398
|
+
layoutIdMap.set(file.filePath, id);
|
|
1399
|
+
layoutCount++;
|
|
1400
|
+
}
|
|
1401
|
+
} else if (file.type === "route") {
|
|
1402
|
+
const route = ctx.routes.find((r) => r.filePath === file.filePath);
|
|
1403
|
+
if (route) {
|
|
1404
|
+
routeCount++;
|
|
1405
|
+
}
|
|
1406
|
+
} else if (file.type === "menu") {
|
|
1407
|
+
const id = createFileId(ctx.opts.routesDir, file.filePath);
|
|
1408
|
+
menuIdMap.set(file.filePath, id);
|
|
1409
|
+
menuCount++;
|
|
1410
|
+
}
|
|
1411
|
+
});
|
|
1412
|
+
if (layoutCount > 0) {
|
|
1413
|
+
c.push(`
|
|
1414
|
+
/** Qwik Router Layouts (${layoutCount}) */`);
|
|
1415
|
+
for (const [filePath, id] of layoutIdMap) {
|
|
1416
|
+
const importPath = JSON.stringify(getImportPath(filePath));
|
|
1417
|
+
if (dynamicImports) {
|
|
1418
|
+
c.push(`const ${id} = ()=>import(${importPath});`);
|
|
1419
|
+
} else {
|
|
1420
|
+
esmImports.push(`import * as ${id}_ from ${importPath};`);
|
|
1421
|
+
c.push(`const ${id} = ()=>${id}_;`);
|
|
1422
|
+
}
|
|
1423
|
+
}
|
|
1424
|
+
}
|
|
1425
|
+
if (menuCount > 0) {
|
|
1426
|
+
c.push(`
|
|
1427
|
+
/** Qwik Router Menus (${menuCount}) */`);
|
|
1428
|
+
for (const [filePath, id] of menuIdMap) {
|
|
1429
|
+
const importPath = JSON.stringify(getImportPath(filePath));
|
|
1430
|
+
if (dynamicImports) {
|
|
1431
|
+
c.push(`const ${id} = ()=>import(${importPath});`);
|
|
1432
|
+
} else {
|
|
1433
|
+
esmImports.push(`import * as ${id}_ from ${importPath};`);
|
|
1434
|
+
c.push(`const ${id} = ()=>${id}_;`);
|
|
1435
|
+
}
|
|
1436
|
+
}
|
|
1437
|
+
}
|
|
1438
|
+
c.push(`
|
|
1439
|
+
/** Qwik Router Routes (${routeCount}) */`);
|
|
1440
|
+
for (const route of ctx.routes) {
|
|
1441
|
+
if (isPageExt(route.ext)) {
|
|
1442
|
+
const importPath = getImportPath(route.filePath);
|
|
1443
|
+
let loaderExpr;
|
|
1444
|
+
if (dynamicImports) {
|
|
1445
|
+
loaderExpr = `()=>import(${JSON.stringify(importPath)})`;
|
|
1446
|
+
} else {
|
|
1447
|
+
esmImports.push(`import * as ${route.id} from ${JSON.stringify(importPath)};`);
|
|
1448
|
+
loaderExpr = `()=>${route.id}`;
|
|
1449
|
+
}
|
|
1450
|
+
routeIdMap.set(route.filePath, loaderExpr);
|
|
1451
|
+
} else if (includeEndpoints && isModuleExt(route.ext)) {
|
|
1452
|
+
const importPath = getImportPath(route.filePath);
|
|
1453
|
+
esmImports.push(`import * as ${route.id} from ${JSON.stringify(importPath)};`);
|
|
1454
|
+
routeIdMap.set(route.filePath, `()=>${route.id}`);
|
|
1158
1455
|
}
|
|
1159
|
-
addRouteFile(r.filePath);
|
|
1160
1456
|
}
|
|
1161
|
-
|
|
1457
|
+
const trieStr = serializeBuildTrie(ctx, qwikPlugin, ctx.routeTrie, layoutIdMap, routeIdMap, menuIdMap, errorFiles, notFoundFiles, [], isSSR, "");
|
|
1458
|
+
const baseSegments = ctx.opts.basePathname.split("/").filter((s) => s.length > 0);
|
|
1459
|
+
let routesExpr = trieStr;
|
|
1460
|
+
for (let j = baseSegments.length - 1; j >= 0; j--) {
|
|
1461
|
+
routesExpr = `{ ${JSON.stringify(baseSegments[j])}: ${routesExpr} }`;
|
|
1462
|
+
}
|
|
1463
|
+
c.push(`export const routes = ${routesExpr};`);
|
|
1162
1464
|
}
|
|
1163
1465
|
|
|
1164
1466
|
function createServerPlugins(ctx, _qwikPlugin, c, esmImports, isSSR) {
|
|
@@ -1186,17 +1488,17 @@ function generateQwikRouterConfig(ctx, qwikPlugin, isSSR) {
|
|
|
1186
1488
|
import { isDev } from '@qwik.dev/core/build';`);
|
|
1187
1489
|
createServerPlugins(ctx, qwikPlugin, c, esmImports, isSSR);
|
|
1188
1490
|
createRoutes(ctx, qwikPlugin, c, esmImports, isSSR);
|
|
1189
|
-
createMenus(ctx, c, esmImports, isSSR);
|
|
1190
1491
|
createEntries(ctx, c);
|
|
1191
1492
|
c.push(`export const trailingSlash = ${JSON.stringify(!globalThis.__NO_TRAILING_SLASH__)};`);
|
|
1192
1493
|
c.push(`export const basePathname = ${JSON.stringify(ctx.opts.basePathname)};`);
|
|
1193
1494
|
c.push(`export const cacheModules = !isDev;`);
|
|
1194
|
-
c.push(
|
|
1195
|
-
`export default { routes, serverPlugins, menus, trailingSlash, basePathname, cacheModules };`
|
|
1196
|
-
);
|
|
1495
|
+
c.push(`export default { routes, serverPlugins, trailingSlash, basePathname, cacheModules };`);
|
|
1197
1496
|
return esmImports.join("\n") + c.join("\n");
|
|
1198
1497
|
}
|
|
1199
1498
|
|
|
1499
|
+
const SW_UNREGISTER = `
|
|
1500
|
+
"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)
|
|
1501
|
+
`;
|
|
1200
1502
|
function generateServiceWorkerRegister(ctx, swRegister) {
|
|
1201
1503
|
let swReg;
|
|
1202
1504
|
let swUrl = "/service-worker.js";
|
|
@@ -1204,24 +1506,31 @@ function generateServiceWorkerRegister(ctx, swRegister) {
|
|
|
1204
1506
|
swReg = SW_UNREGISTER;
|
|
1205
1507
|
} else {
|
|
1206
1508
|
swReg = swRegister;
|
|
1207
|
-
const sw = ctx.serviceWorkers.sort(
|
|
1208
|
-
(a, b) => a.chunkFileName.length < b.chunkFileName.length ? -1 : 1
|
|
1209
|
-
)[0];
|
|
1509
|
+
const sw = ctx.serviceWorkers.sort((a, b) => a.chunkFileName.length < b.chunkFileName.length ? -1 : 1)[0];
|
|
1210
1510
|
swUrl = ctx.opts.basePathname + sw.chunkFileName;
|
|
1211
1511
|
}
|
|
1212
1512
|
swReg = swReg.replace("__url", swUrl);
|
|
1213
1513
|
return `export default ${JSON.stringify(swReg)};`;
|
|
1214
1514
|
}
|
|
1215
|
-
const SW_UNREGISTER = `
|
|
1216
|
-
"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)
|
|
1217
|
-
`;
|
|
1218
1515
|
|
|
1516
|
+
function isBundlePartOfRoute(bundle, routeAndLayoutPaths) {
|
|
1517
|
+
if (!bundle.origins) {
|
|
1518
|
+
return false;
|
|
1519
|
+
}
|
|
1520
|
+
for (const bundleOrigin of bundle.origins) {
|
|
1521
|
+
const originPath = removeExtension(bundleOrigin);
|
|
1522
|
+
return routeAndLayoutPaths.some((path) => path.endsWith(originPath));
|
|
1523
|
+
}
|
|
1524
|
+
}
|
|
1219
1525
|
function getRouteImports(routes, manifest) {
|
|
1220
1526
|
const result = {};
|
|
1221
1527
|
routes.forEach((route) => {
|
|
1222
1528
|
const routePath = removeExtension(route.filePath);
|
|
1223
1529
|
const layoutPaths = route.layouts ? route.layouts.map((layout) => removeExtension(layout.filePath)) : [];
|
|
1224
|
-
const routeAndLayoutPaths = [
|
|
1530
|
+
const routeAndLayoutPaths = [
|
|
1531
|
+
routePath,
|
|
1532
|
+
...layoutPaths
|
|
1533
|
+
];
|
|
1225
1534
|
const bundles = [];
|
|
1226
1535
|
for (const [bundleName, bundle] of Object.entries(manifest.bundles)) {
|
|
1227
1536
|
if (isBundlePartOfRoute(bundle, routeAndLayoutPaths)) {
|
|
@@ -1229,7 +1538,9 @@ function getRouteImports(routes, manifest) {
|
|
|
1229
1538
|
}
|
|
1230
1539
|
}
|
|
1231
1540
|
if (bundles.length > 0) {
|
|
1232
|
-
result[route.routeName] = {
|
|
1541
|
+
result[route.routeName] = {
|
|
1542
|
+
dynamicImports: bundles
|
|
1543
|
+
};
|
|
1233
1544
|
}
|
|
1234
1545
|
});
|
|
1235
1546
|
for (const bundleName of Object.keys(manifest.bundles)) {
|
|
@@ -1237,71 +1548,235 @@ function getRouteImports(routes, manifest) {
|
|
|
1237
1548
|
if (bundle.origins?.some((s) => s.endsWith(QWIK_ROUTER_CONFIG_ID))) {
|
|
1238
1549
|
result[bundleName] = {
|
|
1239
1550
|
...bundle,
|
|
1240
|
-
dynamicImports: bundle.dynamicImports?.filter(
|
|
1241
|
-
(d) => manifest.bundles[d].origins?.some((s) => s.endsWith("menu.md"))
|
|
1242
|
-
)
|
|
1551
|
+
dynamicImports: bundle.dynamicImports?.filter((d) => manifest.bundles[d].origins?.some((s) => s.endsWith("menu.md")))
|
|
1243
1552
|
};
|
|
1244
1553
|
break;
|
|
1245
1554
|
}
|
|
1246
1555
|
}
|
|
1247
1556
|
return result;
|
|
1248
1557
|
}
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1558
|
+
|
|
1559
|
+
const safeParseInt = (nu) => {
|
|
1560
|
+
try {
|
|
1561
|
+
return parseInt(nu, 10);
|
|
1562
|
+
} catch {
|
|
1563
|
+
return void 0;
|
|
1252
1564
|
}
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1565
|
+
};
|
|
1566
|
+
const findLocation = (e) => {
|
|
1567
|
+
const stack = e.stack;
|
|
1568
|
+
if (typeof stack === "string") {
|
|
1569
|
+
const lines = stack.split("\n").filter((l) => !l.includes("/node_modules/") && !l.includes("(node:"));
|
|
1570
|
+
for (let i = 1; i < lines.length; i++) {
|
|
1571
|
+
const line = lines[i].replace("file:///", "/");
|
|
1572
|
+
if (/^\s+at/.test(line)) {
|
|
1573
|
+
const start = line.indexOf("/");
|
|
1574
|
+
const end = line.lastIndexOf(")", start);
|
|
1575
|
+
if (start > 0) {
|
|
1576
|
+
const path = line.slice(start, end);
|
|
1577
|
+
const parts = path.split(":");
|
|
1578
|
+
const nu0 = safeParseInt(parts[parts.length - 1]);
|
|
1579
|
+
const nu1 = safeParseInt(parts[parts.length - 2]);
|
|
1580
|
+
if (typeof nu0 === "number" && typeof nu1 === "number") {
|
|
1581
|
+
parts.length -= 2;
|
|
1582
|
+
return {
|
|
1583
|
+
file: parts.join(":"),
|
|
1584
|
+
line: nu1,
|
|
1585
|
+
column: nu0
|
|
1586
|
+
};
|
|
1587
|
+
} else if (typeof nu0 === "number") {
|
|
1588
|
+
parts.length -= 1;
|
|
1589
|
+
return {
|
|
1590
|
+
file: parts.join(":"),
|
|
1591
|
+
line: nu0,
|
|
1592
|
+
column: void 0
|
|
1593
|
+
};
|
|
1594
|
+
} else {
|
|
1595
|
+
return {
|
|
1596
|
+
file: parts.join(":"),
|
|
1597
|
+
line: void 0,
|
|
1598
|
+
column: void 0
|
|
1599
|
+
};
|
|
1600
|
+
}
|
|
1601
|
+
}
|
|
1602
|
+
}
|
|
1603
|
+
}
|
|
1604
|
+
}
|
|
1605
|
+
return void 0;
|
|
1606
|
+
};
|
|
1607
|
+
const splitRE = /\r?\n/;
|
|
1608
|
+
const range = 2;
|
|
1609
|
+
function posToNumber(source, pos) {
|
|
1610
|
+
if (typeof pos === "number") {
|
|
1611
|
+
return pos;
|
|
1612
|
+
}
|
|
1613
|
+
if (pos.lo != null) {
|
|
1614
|
+
return pos.lo;
|
|
1615
|
+
}
|
|
1616
|
+
const lines = source.split(splitRE);
|
|
1617
|
+
const { line, column } = pos;
|
|
1618
|
+
let start = 0;
|
|
1619
|
+
for (let i = 0; i < line - 1 && i < lines.length; i++) {
|
|
1620
|
+
start += lines[i].length + 1;
|
|
1621
|
+
}
|
|
1622
|
+
return start + column;
|
|
1623
|
+
}
|
|
1624
|
+
function generateCodeFrame(source, start = 0, end) {
|
|
1625
|
+
start = posToNumber(source, start);
|
|
1626
|
+
end = end || start;
|
|
1627
|
+
const lines = source.split(splitRE);
|
|
1628
|
+
let count = 0;
|
|
1629
|
+
const res = [];
|
|
1630
|
+
for (let i = 0; i < lines.length; i++) {
|
|
1631
|
+
count += lines[i].length + 1;
|
|
1632
|
+
if (count >= start) {
|
|
1633
|
+
for (let j = i - range; j <= i + range || end > count; j++) {
|
|
1634
|
+
if (j < 0 || j >= lines.length) {
|
|
1635
|
+
continue;
|
|
1636
|
+
}
|
|
1637
|
+
const line = j + 1;
|
|
1638
|
+
res.push(`${line}${" ".repeat(Math.max(3 - String(line).length, 0))}| ${lines[j]}`);
|
|
1639
|
+
const lineLength = lines[j].length;
|
|
1640
|
+
if (j === i) {
|
|
1641
|
+
const pad = Math.max(start - (count - lineLength) + 1, 0);
|
|
1642
|
+
const length = Math.max(1, end > count ? lineLength - pad : end - start);
|
|
1643
|
+
res.push(` | ` + " ".repeat(pad) + "^".repeat(length));
|
|
1644
|
+
} else if (j > i) {
|
|
1645
|
+
if (end > count) {
|
|
1646
|
+
const length = Math.max(Math.min(end - count, lineLength), 1);
|
|
1647
|
+
res.push(` | ` + "^".repeat(length));
|
|
1648
|
+
}
|
|
1649
|
+
count += lineLength + 1;
|
|
1650
|
+
}
|
|
1651
|
+
}
|
|
1652
|
+
break;
|
|
1653
|
+
}
|
|
1256
1654
|
}
|
|
1655
|
+
return res.join("\n");
|
|
1656
|
+
}
|
|
1657
|
+
function parseId(originalId) {
|
|
1658
|
+
const [pathId, query] = originalId.split("?");
|
|
1659
|
+
const queryStr = query || "";
|
|
1660
|
+
return {
|
|
1661
|
+
originalId,
|
|
1662
|
+
pathId,
|
|
1663
|
+
query: queryStr ? `?${query}` : "",
|
|
1664
|
+
params: new URLSearchParams(queryStr)
|
|
1665
|
+
};
|
|
1257
1666
|
}
|
|
1258
1667
|
|
|
1259
|
-
function
|
|
1260
|
-
const
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1668
|
+
function optimizeSvg({ code, path: path2 }, userOpts) {
|
|
1669
|
+
const svgAttributes = {};
|
|
1670
|
+
const prefixIdsConfiguration = userOpts?.imageOptimization?.svgo?.prefixIds;
|
|
1671
|
+
const maybePrefixIdsPlugin = prefixIdsConfiguration !== false ? [
|
|
1672
|
+
{
|
|
1673
|
+
name: "prefixIds",
|
|
1674
|
+
params: prefixIdsConfiguration
|
|
1675
|
+
}
|
|
1676
|
+
] : [];
|
|
1677
|
+
const userPlugins = userOpts?.imageOptimization?.svgo?.plugins?.filter((plugin) => {
|
|
1678
|
+
if (plugin === "preset-default" || typeof plugin === "object" && plugin.name === "preset-default") {
|
|
1679
|
+
console.warn(`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.`);
|
|
1680
|
+
return false;
|
|
1681
|
+
}
|
|
1682
|
+
if (plugin === "prefixIds" || typeof plugin === "object" && plugin.name === "prefixIds") {
|
|
1683
|
+
console.warn(`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.`);
|
|
1684
|
+
return false;
|
|
1685
|
+
}
|
|
1686
|
+
return true;
|
|
1687
|
+
}) || [];
|
|
1688
|
+
const data = optimize(code, {
|
|
1689
|
+
floatPrecision: userOpts?.imageOptimization?.svgo?.floatPrecision,
|
|
1690
|
+
multipass: userOpts?.imageOptimization?.svgo?.multipass,
|
|
1691
|
+
path: path2,
|
|
1692
|
+
plugins: [
|
|
1693
|
+
{
|
|
1694
|
+
name: "preset-default",
|
|
1695
|
+
params: {
|
|
1696
|
+
overrides: {
|
|
1697
|
+
removeViewBox: false,
|
|
1698
|
+
...userOpts?.imageOptimization?.svgo?.defaultPresetOverrides
|
|
1699
|
+
}
|
|
1700
|
+
}
|
|
1701
|
+
},
|
|
1702
|
+
{
|
|
1703
|
+
name: "customPluginName",
|
|
1704
|
+
fn: () => {
|
|
1705
|
+
return {
|
|
1706
|
+
element: {
|
|
1707
|
+
exit: (node) => {
|
|
1708
|
+
if (node.name === "svg") {
|
|
1709
|
+
node.name = "g";
|
|
1710
|
+
Object.assign(svgAttributes, node.attributes);
|
|
1711
|
+
node.attributes = {};
|
|
1712
|
+
}
|
|
1275
1713
|
}
|
|
1276
1714
|
}
|
|
1277
|
-
return {
|
|
1278
|
-
srcSet,
|
|
1279
|
-
width: largestImage === null || largestImage === void 0 ? void 0 : largestImage.width,
|
|
1280
|
-
height: largestImage === null || largestImage === void 0 ? void 0 : largestImage.height
|
|
1281
|
-
};
|
|
1282
1715
|
};
|
|
1716
|
+
}
|
|
1717
|
+
},
|
|
1718
|
+
...maybePrefixIdsPlugin,
|
|
1719
|
+
...userPlugins
|
|
1720
|
+
]
|
|
1721
|
+
}).data;
|
|
1722
|
+
svgAttributes.dangerouslySetInnerHTML = data.slice(3, -4);
|
|
1723
|
+
return {
|
|
1724
|
+
data,
|
|
1725
|
+
svgAttributes
|
|
1726
|
+
};
|
|
1727
|
+
}
|
|
1728
|
+
function imagePlugin(userOpts) {
|
|
1729
|
+
const supportedExtensions = [
|
|
1730
|
+
".jpg",
|
|
1731
|
+
".jpeg",
|
|
1732
|
+
".png",
|
|
1733
|
+
".webp",
|
|
1734
|
+
".gif",
|
|
1735
|
+
".avif",
|
|
1736
|
+
".tiff"
|
|
1737
|
+
];
|
|
1738
|
+
return [
|
|
1739
|
+
import('vite-imagetools').then(({ imagetools }) => imagetools({
|
|
1740
|
+
exclude: [],
|
|
1741
|
+
extendOutputFormats(builtins) {
|
|
1742
|
+
const jsx = () => (metadatas) => {
|
|
1743
|
+
const srcSet = metadatas.map((meta) => `${meta.src} ${meta.width}w`).join(", ");
|
|
1744
|
+
let largestImage;
|
|
1745
|
+
let largestImageSize = 0;
|
|
1746
|
+
for (let i = 0; i < metadatas.length; i++) {
|
|
1747
|
+
const m = metadatas[i];
|
|
1748
|
+
if (m.width > largestImageSize) {
|
|
1749
|
+
largestImage = m;
|
|
1750
|
+
largestImageSize = m.width;
|
|
1751
|
+
}
|
|
1752
|
+
}
|
|
1283
1753
|
return {
|
|
1284
|
-
|
|
1285
|
-
|
|
1754
|
+
srcSet,
|
|
1755
|
+
width: largestImage === null || largestImage === void 0 ? void 0 : largestImage.width,
|
|
1756
|
+
height: largestImage === null || largestImage === void 0 ? void 0 : largestImage.height
|
|
1286
1757
|
};
|
|
1287
|
-
}
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1758
|
+
};
|
|
1759
|
+
return {
|
|
1760
|
+
...builtins,
|
|
1761
|
+
jsx
|
|
1762
|
+
};
|
|
1763
|
+
},
|
|
1764
|
+
defaultDirectives: (url) => {
|
|
1765
|
+
if (url.searchParams.has("jsx")) {
|
|
1766
|
+
const { jsx: _, ...params } = Object.fromEntries(url.searchParams.entries());
|
|
1767
|
+
return new URLSearchParams({
|
|
1768
|
+
format: "webp",
|
|
1769
|
+
quality: "75",
|
|
1770
|
+
w: "200;400;600;800;1200",
|
|
1771
|
+
withoutEnlargement: "",
|
|
1772
|
+
...userOpts?.imageOptimization?.jsxDirectives,
|
|
1773
|
+
...params,
|
|
1774
|
+
as: "jsx"
|
|
1775
|
+
});
|
|
1302
1776
|
}
|
|
1303
|
-
|
|
1304
|
-
|
|
1777
|
+
return new URLSearchParams();
|
|
1778
|
+
}
|
|
1779
|
+
})).catch((err) => {
|
|
1305
1780
|
console.error("Error loading vite-imagetools, image imports are not available", err);
|
|
1306
1781
|
return null;
|
|
1307
1782
|
}),
|
|
@@ -1341,7 +1816,10 @@ function imagePlugin(userOpts) {
|
|
|
1341
1816
|
map: null
|
|
1342
1817
|
};
|
|
1343
1818
|
} else if (extension === ".svg") {
|
|
1344
|
-
const { svgAttributes } = optimizeSvg({
|
|
1819
|
+
const { svgAttributes } = optimizeSvg({
|
|
1820
|
+
code,
|
|
1821
|
+
path: pathId
|
|
1822
|
+
}, userOpts);
|
|
1345
1823
|
return {
|
|
1346
1824
|
code: `
|
|
1347
1825
|
import { _jsxSorted } from '@qwik.dev/core';
|
|
@@ -1358,89 +1836,50 @@ function imagePlugin(userOpts) {
|
|
|
1358
1836
|
}
|
|
1359
1837
|
];
|
|
1360
1838
|
}
|
|
1361
|
-
function optimizeSvg({ code, path: path2 }, userOpts) {
|
|
1362
|
-
const svgAttributes = {};
|
|
1363
|
-
const prefixIdsConfiguration = userOpts?.imageOptimization?.svgo?.prefixIds;
|
|
1364
|
-
const maybePrefixIdsPlugin = prefixIdsConfiguration !== false ? [{ name: "prefixIds", params: prefixIdsConfiguration }] : [];
|
|
1365
|
-
const userPlugins = userOpts?.imageOptimization?.svgo?.plugins?.filter((plugin) => {
|
|
1366
|
-
if (plugin === "preset-default" || typeof plugin === "object" && plugin.name === "preset-default") {
|
|
1367
|
-
console.warn(
|
|
1368
|
-
`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.`
|
|
1369
|
-
);
|
|
1370
|
-
return false;
|
|
1371
|
-
}
|
|
1372
|
-
if (plugin === "prefixIds" || typeof plugin === "object" && plugin.name === "prefixIds") {
|
|
1373
|
-
console.warn(
|
|
1374
|
-
`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.`
|
|
1375
|
-
);
|
|
1376
|
-
return false;
|
|
1377
|
-
}
|
|
1378
|
-
return true;
|
|
1379
|
-
}) || [];
|
|
1380
|
-
const data = optimize(code, {
|
|
1381
|
-
floatPrecision: userOpts?.imageOptimization?.svgo?.floatPrecision,
|
|
1382
|
-
multipass: userOpts?.imageOptimization?.svgo?.multipass,
|
|
1383
|
-
path: path2,
|
|
1384
|
-
plugins: [
|
|
1385
|
-
{
|
|
1386
|
-
name: "preset-default",
|
|
1387
|
-
params: {
|
|
1388
|
-
overrides: {
|
|
1389
|
-
removeViewBox: false,
|
|
1390
|
-
...userOpts?.imageOptimization?.svgo?.defaultPresetOverrides
|
|
1391
|
-
}
|
|
1392
|
-
}
|
|
1393
|
-
},
|
|
1394
|
-
{
|
|
1395
|
-
name: "customPluginName",
|
|
1396
|
-
fn: () => {
|
|
1397
|
-
return {
|
|
1398
|
-
element: {
|
|
1399
|
-
exit: (node) => {
|
|
1400
|
-
if (node.name === "svg") {
|
|
1401
|
-
node.name = "g";
|
|
1402
|
-
Object.assign(svgAttributes, node.attributes);
|
|
1403
|
-
node.attributes = {};
|
|
1404
|
-
}
|
|
1405
|
-
}
|
|
1406
|
-
}
|
|
1407
|
-
};
|
|
1408
|
-
}
|
|
1409
|
-
},
|
|
1410
|
-
...maybePrefixIdsPlugin,
|
|
1411
|
-
...userPlugins
|
|
1412
|
-
]
|
|
1413
|
-
}).data;
|
|
1414
|
-
svgAttributes.dangerouslySetInnerHTML = data.slice(3, -4);
|
|
1415
|
-
return {
|
|
1416
|
-
data,
|
|
1417
|
-
svgAttributes
|
|
1418
|
-
};
|
|
1419
|
-
}
|
|
1420
1839
|
|
|
1421
1840
|
async function validatePlugin(opts) {
|
|
1422
1841
|
if (typeof opts.routesDir !== "string") {
|
|
1423
1842
|
throw new Error(`qwikRouter plugin "routesDir" option missing`);
|
|
1424
1843
|
}
|
|
1425
1844
|
if (!isAbsolute(opts.routesDir)) {
|
|
1426
|
-
throw new Error(
|
|
1427
|
-
`qwikRouter plugin "routesDir" option must be an absolute path: ${opts.routesDir}`
|
|
1428
|
-
);
|
|
1845
|
+
throw new Error(`qwikRouter plugin "routesDir" option must be an absolute path: ${opts.routesDir}`);
|
|
1429
1846
|
}
|
|
1430
1847
|
try {
|
|
1431
1848
|
const s = await fs.promises.stat(opts.routesDir);
|
|
1432
1849
|
if (!s.isDirectory()) {
|
|
1433
|
-
throw new Error(
|
|
1434
|
-
`qwikRouter plugin "routesDir" option must be a directory: ${opts.routesDir}`
|
|
1435
|
-
);
|
|
1850
|
+
throw new Error(`qwikRouter plugin "routesDir" option must be a directory: ${opts.routesDir}`);
|
|
1436
1851
|
}
|
|
1437
1852
|
} catch (e) {
|
|
1438
1853
|
throw new Error(`qwikRouter plugin "routesDir" not found: ${e}`);
|
|
1439
1854
|
}
|
|
1440
1855
|
}
|
|
1441
1856
|
|
|
1857
|
+
function formatError(e) {
|
|
1858
|
+
if (e instanceof Error) {
|
|
1859
|
+
const err = e;
|
|
1860
|
+
let loc = err.loc;
|
|
1861
|
+
if (!err.frame && !err.plugin) {
|
|
1862
|
+
if (!loc) {
|
|
1863
|
+
loc = findLocation(err);
|
|
1864
|
+
}
|
|
1865
|
+
if (loc) {
|
|
1866
|
+
err.loc = loc;
|
|
1867
|
+
if (loc.file) {
|
|
1868
|
+
err.id = normalizePath(err.loc.file);
|
|
1869
|
+
try {
|
|
1870
|
+
const code = fs.readFileSync(err.loc.file, "utf-8");
|
|
1871
|
+
err.frame = generateCodeFrame(code, err.loc);
|
|
1872
|
+
} catch {
|
|
1873
|
+
}
|
|
1874
|
+
}
|
|
1875
|
+
}
|
|
1876
|
+
}
|
|
1877
|
+
}
|
|
1878
|
+
return e;
|
|
1879
|
+
}
|
|
1880
|
+
|
|
1442
1881
|
class HtmlTransformPatcher {
|
|
1443
|
-
state = 0
|
|
1882
|
+
state = 0;
|
|
1444
1883
|
buffer = "";
|
|
1445
1884
|
headInnerIndex = -1;
|
|
1446
1885
|
bodyInnerIndex = -1;
|
|
@@ -1495,7 +1934,7 @@ class HtmlTransformPatcher {
|
|
|
1495
1934
|
};
|
|
1496
1935
|
}
|
|
1497
1936
|
handleWrite(chunk, encoding, callback) {
|
|
1498
|
-
if (!this.isHtmlResponse || this.state === 3
|
|
1937
|
+
if (!this.isHtmlResponse || this.state === 3) {
|
|
1499
1938
|
return this.origWrite(chunk, encoding, callback);
|
|
1500
1939
|
}
|
|
1501
1940
|
if (typeof encoding === "function") {
|
|
@@ -1514,7 +1953,7 @@ class HtmlTransformPatcher {
|
|
|
1514
1953
|
}
|
|
1515
1954
|
this.buffer += data;
|
|
1516
1955
|
switch (this.state) {
|
|
1517
|
-
case 0
|
|
1956
|
+
case 0:
|
|
1518
1957
|
if (this.headInnerIndex === -1) {
|
|
1519
1958
|
const headMatch = this.buffer.match(/<head[^>]*>/i);
|
|
1520
1959
|
if (headMatch) {
|
|
@@ -1525,16 +1964,16 @@ class HtmlTransformPatcher {
|
|
|
1525
1964
|
if (this.headInnerIndex !== -1) {
|
|
1526
1965
|
const bodyMatch = this.buffer.slice(this.headInnerIndex).match(/<body[^>]*>/i);
|
|
1527
1966
|
if (bodyMatch) {
|
|
1528
|
-
this.state = 1
|
|
1967
|
+
this.state = 1;
|
|
1529
1968
|
const bodyOuterIndex = this.buffer.indexOf(bodyMatch[0]);
|
|
1530
1969
|
this.bodyInnerIndex = bodyOuterIndex + bodyMatch[0].length;
|
|
1531
1970
|
this.processingPromise = this.processHead();
|
|
1532
1971
|
}
|
|
1533
1972
|
}
|
|
1534
1973
|
break;
|
|
1535
|
-
case 1
|
|
1974
|
+
case 1:
|
|
1536
1975
|
break;
|
|
1537
|
-
case 2
|
|
1976
|
+
case 2:
|
|
1538
1977
|
this.handleStreamingBodyState();
|
|
1539
1978
|
break;
|
|
1540
1979
|
default:
|
|
@@ -1545,42 +1984,31 @@ class HtmlTransformPatcher {
|
|
|
1545
1984
|
}
|
|
1546
1985
|
async processHead() {
|
|
1547
1986
|
try {
|
|
1548
|
-
const fakeHtml =
|
|
1549
|
-
const transformedHtml = await this.server.transformIndexHtml(
|
|
1550
|
-
|
|
1551
|
-
fakeHtml
|
|
1552
|
-
);
|
|
1987
|
+
const fakeHtml = `<html><head>[FAKE_HEAD]</head><body>[FAKE_BODY]</body></html>`;
|
|
1988
|
+
const transformedHtml = await this.server.transformIndexHtml(this.request.url || "/", fakeHtml);
|
|
1989
|
+
const hmrBridge = this.server.hot ? `<script type="module" src="/@id/@qwik-hmr-bridge"><\/script>` : "";
|
|
1553
1990
|
const fakeHeadIndex = transformedHtml.indexOf("[FAKE_HEAD]");
|
|
1554
1991
|
const fakeHeadCloseIndex = transformedHtml.indexOf("</head>", fakeHeadIndex);
|
|
1555
1992
|
if (fakeHeadIndex === -1 || fakeHeadCloseIndex === -1) {
|
|
1556
1993
|
throw new Error("Transformed HTML does not contain [FAKE_HEAD]...</head>");
|
|
1557
1994
|
}
|
|
1558
1995
|
const headPreContent = transformedHtml.slice("<html><head>".length, fakeHeadIndex).trim();
|
|
1559
|
-
const headPostContent = transformedHtml.slice(
|
|
1560
|
-
fakeHeadIndex + "[FAKE_HEAD]".length,
|
|
1561
|
-
fakeHeadCloseIndex
|
|
1562
|
-
);
|
|
1996
|
+
const headPostContent = transformedHtml.slice(fakeHeadIndex + "[FAKE_HEAD]".length, fakeHeadCloseIndex) + hmrBridge;
|
|
1563
1997
|
const fakeBodyStartIndex = transformedHtml.indexOf("<body>", fakeHeadCloseIndex);
|
|
1564
1998
|
const fakeBodyIndex = transformedHtml.indexOf("[FAKE_BODY]", fakeBodyStartIndex);
|
|
1565
1999
|
const fakeBodyEndIndex = transformedHtml.indexOf("</body>", fakeBodyIndex);
|
|
1566
2000
|
if (fakeBodyIndex === -1 || fakeBodyEndIndex === -1) {
|
|
1567
2001
|
throw new Error("Transformed HTML does not contain [FAKE_BODY]...</body>");
|
|
1568
2002
|
}
|
|
1569
|
-
const bodyPreContent = transformedHtml.slice(
|
|
1570
|
-
|
|
1571
|
-
fakeBodyIndex
|
|
1572
|
-
);
|
|
1573
|
-
this.bodyPostContent = transformedHtml.slice(
|
|
1574
|
-
fakeBodyIndex + "[FAKE_BODY]".length,
|
|
1575
|
-
fakeBodyEndIndex
|
|
1576
|
-
);
|
|
2003
|
+
const bodyPreContent = transformedHtml.slice(fakeBodyStartIndex + "<body>".length, fakeBodyIndex);
|
|
2004
|
+
this.bodyPostContent = transformedHtml.slice(fakeBodyIndex + "[FAKE_BODY]".length, fakeBodyEndIndex);
|
|
1577
2005
|
const headCloseIndex = this.buffer.indexOf("</head>", this.headInnerIndex);
|
|
1578
2006
|
if (headCloseIndex === -1) {
|
|
1579
2007
|
throw new Error("Buffered HTML does not contain </head>");
|
|
1580
2008
|
}
|
|
1581
2009
|
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);
|
|
1582
2010
|
if (this.bodyPostContent.length > 0) {
|
|
1583
|
-
this.state = 2
|
|
2011
|
+
this.state = 2;
|
|
1584
2012
|
this.handleStreamingBodyState();
|
|
1585
2013
|
return;
|
|
1586
2014
|
}
|
|
@@ -1603,7 +2031,7 @@ class HtmlTransformPatcher {
|
|
|
1603
2031
|
this.flushBuffer(6);
|
|
1604
2032
|
}
|
|
1605
2033
|
transitionToPassthrough() {
|
|
1606
|
-
this.state = 3
|
|
2034
|
+
this.state = 3;
|
|
1607
2035
|
this.flushBuffer();
|
|
1608
2036
|
}
|
|
1609
2037
|
flushBuffer(keep = 0) {
|
|
@@ -1648,9 +2076,7 @@ const makeRouterDevMiddleware = (server, ctx) => async (req, res, next) => {
|
|
|
1648
2076
|
}
|
|
1649
2077
|
const entry = ctx.entries.find((e) => req.url === `${server.config.base}${e.chunkFileName}`);
|
|
1650
2078
|
if (entry) {
|
|
1651
|
-
const entryContents = await server.transformRequest(
|
|
1652
|
-
`/@fs${entry.filePath.startsWith("/") ? "" : "/"}${entry.filePath}`
|
|
1653
|
-
);
|
|
2079
|
+
const entryContents = await server.transformRequest(`/@fs${entry.filePath.startsWith("/") ? "" : "/"}${entry.filePath}`);
|
|
1654
2080
|
if (entryContents) {
|
|
1655
2081
|
res.setHeader("Content-Type", "text/javascript");
|
|
1656
2082
|
res.end(entryContents.code);
|
|
@@ -1661,19 +2087,15 @@ const makeRouterDevMiddleware = (server, ctx) => async (req, res, next) => {
|
|
|
1661
2087
|
}
|
|
1662
2088
|
if (req.url === `${server.config.base}service-worker.js`) {
|
|
1663
2089
|
res.setHeader("Content-Type", "text/javascript");
|
|
1664
|
-
res.end(
|
|
1665
|
-
`/* Qwik Router Dev Service Worker */self.addEventListener('install', () => self.skipWaiting());self.addEventListener('activate', (ev) => ev.waitUntil(self.clients.claim()));`
|
|
1666
|
-
);
|
|
2090
|
+
res.end(`/* Qwik Router Dev Service Worker */self.addEventListener('install', () => self.skipWaiting());self.addEventListener('activate', (ev) => ev.waitUntil(self.clients.claim()));`);
|
|
1667
2091
|
return;
|
|
1668
2092
|
}
|
|
1669
2093
|
globalThis.__qwik = void 0;
|
|
1670
|
-
const { createQwikRouter } = await server.ssrLoadModule(
|
|
1671
|
-
"@qwik.dev/router/middleware/node"
|
|
1672
|
-
);
|
|
2094
|
+
const { createQwikRouter } = await server.ssrLoadModule("@qwik.dev/router/middleware/node");
|
|
1673
2095
|
try {
|
|
1674
|
-
const render =
|
|
2096
|
+
const render = async (opts) => {
|
|
1675
2097
|
return await renderer(opts);
|
|
1676
|
-
}
|
|
2098
|
+
};
|
|
1677
2099
|
const { router, staticFile, notFound } = createQwikRouter({
|
|
1678
2100
|
render,
|
|
1679
2101
|
// inject the platform from dev middleware options
|
|
@@ -1694,14 +2116,26 @@ const makeRouterDevMiddleware = (server, ctx) => async (req, res, next) => {
|
|
|
1694
2116
|
return;
|
|
1695
2117
|
}
|
|
1696
2118
|
};
|
|
1697
|
-
const CSS_EXTENSIONS = [
|
|
2119
|
+
const CSS_EXTENSIONS = [
|
|
2120
|
+
".css",
|
|
2121
|
+
".scss",
|
|
2122
|
+
".sass",
|
|
2123
|
+
".less",
|
|
2124
|
+
".styl",
|
|
2125
|
+
".stylus"
|
|
2126
|
+
];
|
|
1698
2127
|
const JS_EXTENSIONS = /\.[mc]?[tj]sx?$/;
|
|
1699
2128
|
const isCssPath = (url) => CSS_EXTENSIONS.some((ext) => url.endsWith(ext));
|
|
1700
2129
|
const getCssUrls = (server) => {
|
|
2130
|
+
const clientGraph = server.environments.client.moduleGraph;
|
|
2131
|
+
const ssrGraph = server.environments.ssr.moduleGraph;
|
|
1701
2132
|
const cssModules = /* @__PURE__ */ new Set();
|
|
1702
2133
|
const cssImportedByCSS = /* @__PURE__ */ new Set();
|
|
1703
|
-
|
|
1704
|
-
|
|
2134
|
+
for (const graph of [
|
|
2135
|
+
clientGraph,
|
|
2136
|
+
ssrGraph
|
|
2137
|
+
]) {
|
|
2138
|
+
for (const mod of graph.idToModuleMap.values()) {
|
|
1705
2139
|
const [pathId, query] = mod.url.split("?");
|
|
1706
2140
|
if (!query && isCssPath(pathId)) {
|
|
1707
2141
|
const isEntryCSS = mod.importers.size === 0;
|
|
@@ -1718,20 +2152,23 @@ const getCssUrls = (server) => {
|
|
|
1718
2152
|
return importerPath && JS_EXTENSIONS.test(importerPath);
|
|
1719
2153
|
});
|
|
1720
2154
|
if ((isEntryCSS || hasJSImporter) && !hasCSSImporter && !cssImportedByCSS.has(mod.url)) {
|
|
1721
|
-
cssModules.add(mod);
|
|
2155
|
+
cssModules.add(`${mod.url}${mod.lastHMRTimestamp ? `?t=${mod.lastHMRTimestamp}` : ""}`);
|
|
1722
2156
|
}
|
|
1723
2157
|
}
|
|
1724
|
-
}
|
|
1725
|
-
}
|
|
1726
|
-
return [
|
|
1727
|
-
|
|
1728
|
-
|
|
2158
|
+
}
|
|
2159
|
+
}
|
|
2160
|
+
return [
|
|
2161
|
+
...cssModules
|
|
2162
|
+
];
|
|
1729
2163
|
};
|
|
1730
2164
|
const getRouterIndexTags = (server) => {
|
|
1731
2165
|
const cssUrls = getCssUrls(server);
|
|
1732
2166
|
return cssUrls.map((url) => ({
|
|
1733
2167
|
tag: "link",
|
|
1734
|
-
attrs: {
|
|
2168
|
+
attrs: {
|
|
2169
|
+
rel: "stylesheet",
|
|
2170
|
+
href: url
|
|
2171
|
+
}
|
|
1735
2172
|
}));
|
|
1736
2173
|
};
|
|
1737
2174
|
|
|
@@ -1739,11 +2176,25 @@ const QWIK_ROUTER_CONFIG_ID = "@qwik-router-config";
|
|
|
1739
2176
|
const QWIK_ROUTER_ENTRIES_ID = "@qwik-router-entries";
|
|
1740
2177
|
const QWIK_ROUTER = "@qwik.dev/router";
|
|
1741
2178
|
const QWIK_ROUTER_SW_REGISTER = "@qwik-router-sw-register";
|
|
1742
|
-
function
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
2179
|
+
async function generateServerPackageJson(outDir) {
|
|
2180
|
+
await fs.promises.mkdir(outDir, {
|
|
2181
|
+
recursive: true
|
|
2182
|
+
});
|
|
2183
|
+
const serverPackageJsonPath = join(outDir, "package.json");
|
|
2184
|
+
let packageJson = {};
|
|
2185
|
+
if (fs.existsSync(serverPackageJsonPath)) {
|
|
2186
|
+
const content = await fs.promises.readFile(serverPackageJsonPath, "utf-8");
|
|
2187
|
+
const contentAsJson = JSON.parse(content);
|
|
2188
|
+
packageJson = {
|
|
2189
|
+
...contentAsJson
|
|
2190
|
+
};
|
|
2191
|
+
}
|
|
2192
|
+
packageJson = {
|
|
2193
|
+
...packageJson,
|
|
2194
|
+
type: "module"
|
|
2195
|
+
};
|
|
2196
|
+
const serverPackageJsonCode = JSON.stringify(packageJson, null, 2);
|
|
2197
|
+
await fs.promises.writeFile(serverPackageJsonPath, serverPackageJsonCode);
|
|
1747
2198
|
}
|
|
1748
2199
|
function qwikRouterPlugin(userOpts) {
|
|
1749
2200
|
let ctx = null;
|
|
@@ -1773,20 +2224,37 @@ function qwikRouterPlugin(userOpts) {
|
|
|
1773
2224
|
viteCommand = viteEnv.command;
|
|
1774
2225
|
const updatedViteConfig = {
|
|
1775
2226
|
define: {
|
|
1776
|
-
"globalThis.__DEFAULT_LOADERS_SERIALIZATION_STRATEGY__": JSON.stringify(
|
|
1777
|
-
|
|
1778
|
-
)
|
|
1779
|
-
"globalThis.__NO_TRAILING_SLASH__": JSON.stringify(userOpts?.trailingSlash === false)
|
|
2227
|
+
"globalThis.__DEFAULT_LOADERS_SERIALIZATION_STRATEGY__": JSON.stringify(userOpts?.defaultLoadersSerializationStrategy || "never"),
|
|
2228
|
+
"globalThis.__NO_TRAILING_SLASH__": JSON.stringify(userOpts?.trailingSlash === false),
|
|
2229
|
+
"globalThis.__SSR_CACHE_SIZE__": JSON.stringify(viteEnv.command === "serve" ? 0 : userOpts?.ssrCacheSize ?? 50)
|
|
1780
2230
|
},
|
|
1781
2231
|
appType: "custom",
|
|
1782
2232
|
resolve: {
|
|
1783
|
-
dedupe: [
|
|
2233
|
+
dedupe: [
|
|
2234
|
+
QWIK_ROUTER,
|
|
2235
|
+
"@builder.io/qwik-city"
|
|
2236
|
+
],
|
|
1784
2237
|
alias: [
|
|
1785
|
-
{
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
{
|
|
2238
|
+
{
|
|
2239
|
+
find: "@builder.io/qwik-city",
|
|
2240
|
+
replacement: "@qwik.dev/router"
|
|
2241
|
+
},
|
|
2242
|
+
{
|
|
2243
|
+
find: /^@builder\.io\/qwik-city\/(.*)/,
|
|
2244
|
+
replacement: "@qwik.dev/router/$1"
|
|
2245
|
+
},
|
|
2246
|
+
{
|
|
2247
|
+
find: "@qwik-city-plan",
|
|
2248
|
+
replacement: QWIK_ROUTER_CONFIG_ID
|
|
2249
|
+
},
|
|
2250
|
+
{
|
|
2251
|
+
find: "@qwik-city-entries",
|
|
2252
|
+
replacement: QWIK_ROUTER_ENTRIES_ID
|
|
2253
|
+
},
|
|
2254
|
+
{
|
|
2255
|
+
find: "@qwik-city-sw-register",
|
|
2256
|
+
replacement: QWIK_ROUTER_SW_REGISTER
|
|
2257
|
+
}
|
|
1790
2258
|
]
|
|
1791
2259
|
},
|
|
1792
2260
|
optimizeDeps: {
|
|
@@ -1804,8 +2272,11 @@ function qwikRouterPlugin(userOpts) {
|
|
|
1804
2272
|
QWIK_ROUTER_SW_REGISTER
|
|
1805
2273
|
]
|
|
1806
2274
|
},
|
|
2275
|
+
// Duplicated from configEnvironment to support legacy vite build --ssr compatibility
|
|
1807
2276
|
ssr: {
|
|
1808
|
-
external: [
|
|
2277
|
+
external: [
|
|
2278
|
+
"node:async_hooks"
|
|
2279
|
+
],
|
|
1809
2280
|
noExternal: [
|
|
1810
2281
|
QWIK_ROUTER,
|
|
1811
2282
|
QWIK_ROUTER_CONFIG_ID,
|
|
@@ -1824,22 +2295,33 @@ function qwikRouterPlugin(userOpts) {
|
|
|
1824
2295
|
};
|
|
1825
2296
|
return updatedViteConfig;
|
|
1826
2297
|
},
|
|
2298
|
+
configEnvironment(name, _config, _env) {
|
|
2299
|
+
if (name === "ssr") {
|
|
2300
|
+
return {
|
|
2301
|
+
resolve: {
|
|
2302
|
+
external: [
|
|
2303
|
+
"node:async_hooks"
|
|
2304
|
+
],
|
|
2305
|
+
noExternal: [
|
|
2306
|
+
QWIK_ROUTER,
|
|
2307
|
+
QWIK_ROUTER_CONFIG_ID,
|
|
2308
|
+
QWIK_ROUTER_ENTRIES_ID,
|
|
2309
|
+
QWIK_ROUTER_SW_REGISTER,
|
|
2310
|
+
"zod"
|
|
2311
|
+
]
|
|
2312
|
+
}
|
|
2313
|
+
};
|
|
2314
|
+
}
|
|
2315
|
+
return {};
|
|
2316
|
+
},
|
|
1827
2317
|
async configResolved(config) {
|
|
1828
2318
|
Object.assign(process.env, loadEnv(config.mode, process.cwd(), ""));
|
|
1829
2319
|
rootDir = resolve(config.root);
|
|
1830
2320
|
const target = config.build?.ssr || config.mode === "ssr" ? "ssr" : "client";
|
|
1831
|
-
ctx = createBuildContext(
|
|
1832
|
-
rootDir,
|
|
1833
|
-
config.base,
|
|
1834
|
-
userOpts,
|
|
1835
|
-
target,
|
|
1836
|
-
!userOpts?.staticImportRoutes
|
|
1837
|
-
);
|
|
2321
|
+
ctx = createBuildContext(rootDir, config.base, userOpts, target, !userOpts?.staticImportRoutes);
|
|
1838
2322
|
await validatePlugin(ctx.opts);
|
|
1839
2323
|
mdxTransform = await createMdxTransformer(ctx);
|
|
1840
|
-
qwikPlugin = config.plugins.find(
|
|
1841
|
-
(p) => p.name === "vite-plugin-qwik"
|
|
1842
|
-
);
|
|
2324
|
+
qwikPlugin = config.plugins.find((p) => p.name === "vite-plugin-qwik");
|
|
1843
2325
|
if (!qwikPlugin) {
|
|
1844
2326
|
throw new Error("Missing vite-plugin-qwik");
|
|
1845
2327
|
}
|
|
@@ -1853,10 +2335,7 @@ function qwikRouterPlugin(userOpts) {
|
|
|
1853
2335
|
},
|
|
1854
2336
|
async configureServer(server) {
|
|
1855
2337
|
devServer = server;
|
|
1856
|
-
const toWatch = resolve(
|
|
1857
|
-
rootDir,
|
|
1858
|
-
"src/routes/**/{index,layout,entry,service-worker}{.,@,-}*"
|
|
1859
|
-
);
|
|
2338
|
+
const toWatch = resolve(rootDir, "src/routes/**/{index,layout,entry,service-worker}{.,@,-}*");
|
|
1860
2339
|
server.watcher.add(toWatch);
|
|
1861
2340
|
await new Promise((resolve2) => setTimeout(resolve2, 1e3));
|
|
1862
2341
|
server.watcher.on("change", (path) => {
|
|
@@ -1918,7 +2397,7 @@ function qwikRouterPlugin(userOpts) {
|
|
|
1918
2397
|
});
|
|
1919
2398
|
}
|
|
1920
2399
|
if (isRouterConfig) {
|
|
1921
|
-
return generateQwikRouterConfig(ctx, qwikPlugin,
|
|
2400
|
+
return generateQwikRouterConfig(ctx, qwikPlugin, this.environment.config.consumer === "server");
|
|
1922
2401
|
}
|
|
1923
2402
|
if (isSwRegister) {
|
|
1924
2403
|
return generateServiceWorkerRegister(ctx, swRegister);
|
|
@@ -1938,7 +2417,10 @@ function qwikRouterPlugin(userOpts) {
|
|
|
1938
2417
|
const fileName = basename(id);
|
|
1939
2418
|
if (isMenuFileName(fileName)) {
|
|
1940
2419
|
const menuCode = await transformMenu(ctx.opts, id, code);
|
|
1941
|
-
return {
|
|
2420
|
+
return {
|
|
2421
|
+
code: menuCode,
|
|
2422
|
+
map: null
|
|
2423
|
+
};
|
|
1942
2424
|
}
|
|
1943
2425
|
if (mdxTransform) {
|
|
1944
2426
|
try {
|
|
@@ -1969,8 +2451,11 @@ function qwikRouterPlugin(userOpts) {
|
|
|
1969
2451
|
return null;
|
|
1970
2452
|
},
|
|
1971
2453
|
generateBundle(_, bundles) {
|
|
1972
|
-
if (
|
|
1973
|
-
const entries = [
|
|
2454
|
+
if (this.environment.config.consumer === "client") {
|
|
2455
|
+
const entries = [
|
|
2456
|
+
...ctx.entries,
|
|
2457
|
+
...ctx.serviceWorkers
|
|
2458
|
+
].map((entry) => {
|
|
1974
2459
|
return {
|
|
1975
2460
|
chunkFileName: entry.chunkFileName,
|
|
1976
2461
|
extensionlessFilePath: removeExtension(entry.filePath)
|
|
@@ -1993,7 +2478,7 @@ function qwikRouterPlugin(userOpts) {
|
|
|
1993
2478
|
closeBundle: {
|
|
1994
2479
|
sequential: true,
|
|
1995
2480
|
async handler() {
|
|
1996
|
-
if (
|
|
2481
|
+
if (this.environment.config.consumer === "server" && outDir) {
|
|
1997
2482
|
await generateServerPackageJson(outDir);
|
|
1998
2483
|
}
|
|
1999
2484
|
}
|
|
@@ -2001,23 +2486,14 @@ function qwikRouterPlugin(userOpts) {
|
|
|
2001
2486
|
};
|
|
2002
2487
|
return plugin;
|
|
2003
2488
|
}
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
...contentAsJson
|
|
2013
|
-
};
|
|
2014
|
-
}
|
|
2015
|
-
packageJson = {
|
|
2016
|
-
...packageJson,
|
|
2017
|
-
type: "module"
|
|
2018
|
-
};
|
|
2019
|
-
const serverPackageJsonCode = JSON.stringify(packageJson, null, 2);
|
|
2020
|
-
await fs.promises.writeFile(serverPackageJsonPath, serverPackageJsonCode);
|
|
2489
|
+
function qwikRouter(userOpts) {
|
|
2490
|
+
return [
|
|
2491
|
+
qwikRouterPlugin(userOpts),
|
|
2492
|
+
...imagePlugin(userOpts)
|
|
2493
|
+
];
|
|
2494
|
+
}
|
|
2495
|
+
function qwikCity(userOpts) {
|
|
2496
|
+
return qwikRouter(userOpts);
|
|
2021
2497
|
}
|
|
2022
2498
|
|
|
2023
2499
|
export { extendConfig, qwikCity, qwikRouter };
|