@qwik.dev/router 2.0.0-beta.28 → 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 +164 -136
- 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 +20 -5
- package/lib/middleware/cloudflare-pages/index.mjs +8 -2
- package/lib/middleware/deno/index.mjs +19 -5
- package/lib/middleware/netlify-edge/index.mjs +8 -2
- 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 +8 -2
- 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 +1098 -641
- package/modules.d.ts +7 -4
- package/package.json +4 -4
- package/lib/chunks/format-error.mjs +0 -137
- package/lib/chunks/index.mjs +0 -896
- 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:
|
|
@@ -1546,10 +1985,7 @@ class HtmlTransformPatcher {
|
|
|
1546
1985
|
async processHead() {
|
|
1547
1986
|
try {
|
|
1548
1987
|
const fakeHtml = `<html><head>[FAKE_HEAD]</head><body>[FAKE_BODY]</body></html>`;
|
|
1549
|
-
const transformedHtml = await this.server.transformIndexHtml(
|
|
1550
|
-
this.request.url || "/",
|
|
1551
|
-
fakeHtml
|
|
1552
|
-
);
|
|
1988
|
+
const transformedHtml = await this.server.transformIndexHtml(this.request.url || "/", fakeHtml);
|
|
1553
1989
|
const hmrBridge = this.server.hot ? `<script type="module" src="/@id/@qwik-hmr-bridge"><\/script>` : "";
|
|
1554
1990
|
const fakeHeadIndex = transformedHtml.indexOf("[FAKE_HEAD]");
|
|
1555
1991
|
const fakeHeadCloseIndex = transformedHtml.indexOf("</head>", fakeHeadIndex);
|
|
@@ -1564,21 +2000,15 @@ class HtmlTransformPatcher {
|
|
|
1564
2000
|
if (fakeBodyIndex === -1 || fakeBodyEndIndex === -1) {
|
|
1565
2001
|
throw new Error("Transformed HTML does not contain [FAKE_BODY]...</body>");
|
|
1566
2002
|
}
|
|
1567
|
-
const bodyPreContent = transformedHtml.slice(
|
|
1568
|
-
|
|
1569
|
-
fakeBodyIndex
|
|
1570
|
-
);
|
|
1571
|
-
this.bodyPostContent = transformedHtml.slice(
|
|
1572
|
-
fakeBodyIndex + "[FAKE_BODY]".length,
|
|
1573
|
-
fakeBodyEndIndex
|
|
1574
|
-
);
|
|
2003
|
+
const bodyPreContent = transformedHtml.slice(fakeBodyStartIndex + "<body>".length, fakeBodyIndex);
|
|
2004
|
+
this.bodyPostContent = transformedHtml.slice(fakeBodyIndex + "[FAKE_BODY]".length, fakeBodyEndIndex);
|
|
1575
2005
|
const headCloseIndex = this.buffer.indexOf("</head>", this.headInnerIndex);
|
|
1576
2006
|
if (headCloseIndex === -1) {
|
|
1577
2007
|
throw new Error("Buffered HTML does not contain </head>");
|
|
1578
2008
|
}
|
|
1579
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);
|
|
1580
2010
|
if (this.bodyPostContent.length > 0) {
|
|
1581
|
-
this.state = 2
|
|
2011
|
+
this.state = 2;
|
|
1582
2012
|
this.handleStreamingBodyState();
|
|
1583
2013
|
return;
|
|
1584
2014
|
}
|
|
@@ -1601,7 +2031,7 @@ class HtmlTransformPatcher {
|
|
|
1601
2031
|
this.flushBuffer(6);
|
|
1602
2032
|
}
|
|
1603
2033
|
transitionToPassthrough() {
|
|
1604
|
-
this.state = 3
|
|
2034
|
+
this.state = 3;
|
|
1605
2035
|
this.flushBuffer();
|
|
1606
2036
|
}
|
|
1607
2037
|
flushBuffer(keep = 0) {
|
|
@@ -1646,9 +2076,7 @@ const makeRouterDevMiddleware = (server, ctx) => async (req, res, next) => {
|
|
|
1646
2076
|
}
|
|
1647
2077
|
const entry = ctx.entries.find((e) => req.url === `${server.config.base}${e.chunkFileName}`);
|
|
1648
2078
|
if (entry) {
|
|
1649
|
-
const entryContents = await server.transformRequest(
|
|
1650
|
-
`/@fs${entry.filePath.startsWith("/") ? "" : "/"}${entry.filePath}`
|
|
1651
|
-
);
|
|
2079
|
+
const entryContents = await server.transformRequest(`/@fs${entry.filePath.startsWith("/") ? "" : "/"}${entry.filePath}`);
|
|
1652
2080
|
if (entryContents) {
|
|
1653
2081
|
res.setHeader("Content-Type", "text/javascript");
|
|
1654
2082
|
res.end(entryContents.code);
|
|
@@ -1659,19 +2087,15 @@ const makeRouterDevMiddleware = (server, ctx) => async (req, res, next) => {
|
|
|
1659
2087
|
}
|
|
1660
2088
|
if (req.url === `${server.config.base}service-worker.js`) {
|
|
1661
2089
|
res.setHeader("Content-Type", "text/javascript");
|
|
1662
|
-
res.end(
|
|
1663
|
-
`/* Qwik Router Dev Service Worker */self.addEventListener('install', () => self.skipWaiting());self.addEventListener('activate', (ev) => ev.waitUntil(self.clients.claim()));`
|
|
1664
|
-
);
|
|
2090
|
+
res.end(`/* Qwik Router Dev Service Worker */self.addEventListener('install', () => self.skipWaiting());self.addEventListener('activate', (ev) => ev.waitUntil(self.clients.claim()));`);
|
|
1665
2091
|
return;
|
|
1666
2092
|
}
|
|
1667
2093
|
globalThis.__qwik = void 0;
|
|
1668
|
-
const { createQwikRouter } = await server.ssrLoadModule(
|
|
1669
|
-
"@qwik.dev/router/middleware/node"
|
|
1670
|
-
);
|
|
2094
|
+
const { createQwikRouter } = await server.ssrLoadModule("@qwik.dev/router/middleware/node");
|
|
1671
2095
|
try {
|
|
1672
|
-
const render =
|
|
2096
|
+
const render = async (opts) => {
|
|
1673
2097
|
return await renderer(opts);
|
|
1674
|
-
}
|
|
2098
|
+
};
|
|
1675
2099
|
const { router, staticFile, notFound } = createQwikRouter({
|
|
1676
2100
|
render,
|
|
1677
2101
|
// inject the platform from dev middleware options
|
|
@@ -1692,43 +2116,59 @@ const makeRouterDevMiddleware = (server, ctx) => async (req, res, next) => {
|
|
|
1692
2116
|
return;
|
|
1693
2117
|
}
|
|
1694
2118
|
};
|
|
1695
|
-
const CSS_EXTENSIONS = [
|
|
2119
|
+
const CSS_EXTENSIONS = [
|
|
2120
|
+
".css",
|
|
2121
|
+
".scss",
|
|
2122
|
+
".sass",
|
|
2123
|
+
".less",
|
|
2124
|
+
".styl",
|
|
2125
|
+
".stylus"
|
|
2126
|
+
];
|
|
1696
2127
|
const JS_EXTENSIONS = /\.[mc]?[tj]sx?$/;
|
|
1697
2128
|
const isCssPath = (url) => CSS_EXTENSIONS.some((ext) => url.endsWith(ext));
|
|
1698
2129
|
const getCssUrls = (server) => {
|
|
1699
|
-
const
|
|
2130
|
+
const clientGraph = server.environments.client.moduleGraph;
|
|
2131
|
+
const ssrGraph = server.environments.ssr.moduleGraph;
|
|
1700
2132
|
const cssModules = /* @__PURE__ */ new Set();
|
|
1701
2133
|
const cssImportedByCSS = /* @__PURE__ */ new Set();
|
|
1702
|
-
for (const
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
2134
|
+
for (const graph of [
|
|
2135
|
+
clientGraph,
|
|
2136
|
+
ssrGraph
|
|
2137
|
+
]) {
|
|
2138
|
+
for (const mod of graph.idToModuleMap.values()) {
|
|
2139
|
+
const [pathId, query] = mod.url.split("?");
|
|
2140
|
+
if (!query && isCssPath(pathId)) {
|
|
2141
|
+
const isEntryCSS = mod.importers.size === 0;
|
|
2142
|
+
const hasCSSImporter = Array.from(mod.importers).some((importer) => {
|
|
2143
|
+
const importerPath = importer.url || importer.file;
|
|
2144
|
+
const isCSS = importerPath && isCssPath(importerPath);
|
|
2145
|
+
if (isCSS && mod.url) {
|
|
2146
|
+
cssImportedByCSS.add(mod.url);
|
|
2147
|
+
}
|
|
2148
|
+
return isCSS;
|
|
2149
|
+
});
|
|
2150
|
+
const hasJSImporter = Array.from(mod.importers).some((importer) => {
|
|
2151
|
+
const importerPath = importer.url || importer.file;
|
|
2152
|
+
return importerPath && JS_EXTENSIONS.test(importerPath);
|
|
2153
|
+
});
|
|
2154
|
+
if ((isEntryCSS || hasJSImporter) && !hasCSSImporter && !cssImportedByCSS.has(mod.url)) {
|
|
2155
|
+
cssModules.add(`${mod.url}${mod.lastHMRTimestamp ? `?t=${mod.lastHMRTimestamp}` : ""}`);
|
|
1711
2156
|
}
|
|
1712
|
-
return isCSS;
|
|
1713
|
-
});
|
|
1714
|
-
const hasJSImporter = Array.from(mod.importers).some((importer) => {
|
|
1715
|
-
const importerPath = importer.url || importer.file;
|
|
1716
|
-
return importerPath && JS_EXTENSIONS.test(importerPath);
|
|
1717
|
-
});
|
|
1718
|
-
if ((isEntryCSS || hasJSImporter) && !hasCSSImporter && !cssImportedByCSS.has(mod.url)) {
|
|
1719
|
-
cssModules.add(mod);
|
|
1720
2157
|
}
|
|
1721
2158
|
}
|
|
1722
2159
|
}
|
|
1723
|
-
return [
|
|
1724
|
-
|
|
1725
|
-
|
|
2160
|
+
return [
|
|
2161
|
+
...cssModules
|
|
2162
|
+
];
|
|
1726
2163
|
};
|
|
1727
2164
|
const getRouterIndexTags = (server) => {
|
|
1728
2165
|
const cssUrls = getCssUrls(server);
|
|
1729
2166
|
return cssUrls.map((url) => ({
|
|
1730
2167
|
tag: "link",
|
|
1731
|
-
attrs: {
|
|
2168
|
+
attrs: {
|
|
2169
|
+
rel: "stylesheet",
|
|
2170
|
+
href: url
|
|
2171
|
+
}
|
|
1732
2172
|
}));
|
|
1733
2173
|
};
|
|
1734
2174
|
|
|
@@ -1736,11 +2176,25 @@ const QWIK_ROUTER_CONFIG_ID = "@qwik-router-config";
|
|
|
1736
2176
|
const QWIK_ROUTER_ENTRIES_ID = "@qwik-router-entries";
|
|
1737
2177
|
const QWIK_ROUTER = "@qwik.dev/router";
|
|
1738
2178
|
const QWIK_ROUTER_SW_REGISTER = "@qwik-router-sw-register";
|
|
1739
|
-
function
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
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);
|
|
1744
2198
|
}
|
|
1745
2199
|
function qwikRouterPlugin(userOpts) {
|
|
1746
2200
|
let ctx = null;
|
|
@@ -1770,20 +2224,37 @@ function qwikRouterPlugin(userOpts) {
|
|
|
1770
2224
|
viteCommand = viteEnv.command;
|
|
1771
2225
|
const updatedViteConfig = {
|
|
1772
2226
|
define: {
|
|
1773
|
-
"globalThis.__DEFAULT_LOADERS_SERIALIZATION_STRATEGY__": JSON.stringify(
|
|
1774
|
-
|
|
1775
|
-
)
|
|
1776
|
-
"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)
|
|
1777
2230
|
},
|
|
1778
2231
|
appType: "custom",
|
|
1779
2232
|
resolve: {
|
|
1780
|
-
dedupe: [
|
|
2233
|
+
dedupe: [
|
|
2234
|
+
QWIK_ROUTER,
|
|
2235
|
+
"@builder.io/qwik-city"
|
|
2236
|
+
],
|
|
1781
2237
|
alias: [
|
|
1782
|
-
{
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
{
|
|
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
|
+
}
|
|
1787
2258
|
]
|
|
1788
2259
|
},
|
|
1789
2260
|
optimizeDeps: {
|
|
@@ -1803,7 +2274,9 @@ function qwikRouterPlugin(userOpts) {
|
|
|
1803
2274
|
},
|
|
1804
2275
|
// Duplicated from configEnvironment to support legacy vite build --ssr compatibility
|
|
1805
2276
|
ssr: {
|
|
1806
|
-
external: [
|
|
2277
|
+
external: [
|
|
2278
|
+
"node:async_hooks"
|
|
2279
|
+
],
|
|
1807
2280
|
noExternal: [
|
|
1808
2281
|
QWIK_ROUTER,
|
|
1809
2282
|
QWIK_ROUTER_CONFIG_ID,
|
|
@@ -1826,7 +2299,9 @@ function qwikRouterPlugin(userOpts) {
|
|
|
1826
2299
|
if (name === "ssr") {
|
|
1827
2300
|
return {
|
|
1828
2301
|
resolve: {
|
|
1829
|
-
external: [
|
|
2302
|
+
external: [
|
|
2303
|
+
"node:async_hooks"
|
|
2304
|
+
],
|
|
1830
2305
|
noExternal: [
|
|
1831
2306
|
QWIK_ROUTER,
|
|
1832
2307
|
QWIK_ROUTER_CONFIG_ID,
|
|
@@ -1843,18 +2318,10 @@ function qwikRouterPlugin(userOpts) {
|
|
|
1843
2318
|
Object.assign(process.env, loadEnv(config.mode, process.cwd(), ""));
|
|
1844
2319
|
rootDir = resolve(config.root);
|
|
1845
2320
|
const target = config.build?.ssr || config.mode === "ssr" ? "ssr" : "client";
|
|
1846
|
-
ctx = createBuildContext(
|
|
1847
|
-
rootDir,
|
|
1848
|
-
config.base,
|
|
1849
|
-
userOpts,
|
|
1850
|
-
target,
|
|
1851
|
-
!userOpts?.staticImportRoutes
|
|
1852
|
-
);
|
|
2321
|
+
ctx = createBuildContext(rootDir, config.base, userOpts, target, !userOpts?.staticImportRoutes);
|
|
1853
2322
|
await validatePlugin(ctx.opts);
|
|
1854
2323
|
mdxTransform = await createMdxTransformer(ctx);
|
|
1855
|
-
qwikPlugin = config.plugins.find(
|
|
1856
|
-
(p) => p.name === "vite-plugin-qwik"
|
|
1857
|
-
);
|
|
2324
|
+
qwikPlugin = config.plugins.find((p) => p.name === "vite-plugin-qwik");
|
|
1858
2325
|
if (!qwikPlugin) {
|
|
1859
2326
|
throw new Error("Missing vite-plugin-qwik");
|
|
1860
2327
|
}
|
|
@@ -1868,10 +2335,7 @@ function qwikRouterPlugin(userOpts) {
|
|
|
1868
2335
|
},
|
|
1869
2336
|
async configureServer(server) {
|
|
1870
2337
|
devServer = server;
|
|
1871
|
-
const toWatch = resolve(
|
|
1872
|
-
rootDir,
|
|
1873
|
-
"src/routes/**/{index,layout,entry,service-worker}{.,@,-}*"
|
|
1874
|
-
);
|
|
2338
|
+
const toWatch = resolve(rootDir, "src/routes/**/{index,layout,entry,service-worker}{.,@,-}*");
|
|
1875
2339
|
server.watcher.add(toWatch);
|
|
1876
2340
|
await new Promise((resolve2) => setTimeout(resolve2, 1e3));
|
|
1877
2341
|
server.watcher.on("change", (path) => {
|
|
@@ -1933,11 +2397,7 @@ function qwikRouterPlugin(userOpts) {
|
|
|
1933
2397
|
});
|
|
1934
2398
|
}
|
|
1935
2399
|
if (isRouterConfig) {
|
|
1936
|
-
return generateQwikRouterConfig(
|
|
1937
|
-
ctx,
|
|
1938
|
-
qwikPlugin,
|
|
1939
|
-
this.environment.config.consumer === "server"
|
|
1940
|
-
);
|
|
2400
|
+
return generateQwikRouterConfig(ctx, qwikPlugin, this.environment.config.consumer === "server");
|
|
1941
2401
|
}
|
|
1942
2402
|
if (isSwRegister) {
|
|
1943
2403
|
return generateServiceWorkerRegister(ctx, swRegister);
|
|
@@ -1957,7 +2417,10 @@ function qwikRouterPlugin(userOpts) {
|
|
|
1957
2417
|
const fileName = basename(id);
|
|
1958
2418
|
if (isMenuFileName(fileName)) {
|
|
1959
2419
|
const menuCode = await transformMenu(ctx.opts, id, code);
|
|
1960
|
-
return {
|
|
2420
|
+
return {
|
|
2421
|
+
code: menuCode,
|
|
2422
|
+
map: null
|
|
2423
|
+
};
|
|
1961
2424
|
}
|
|
1962
2425
|
if (mdxTransform) {
|
|
1963
2426
|
try {
|
|
@@ -1989,7 +2452,10 @@ function qwikRouterPlugin(userOpts) {
|
|
|
1989
2452
|
},
|
|
1990
2453
|
generateBundle(_, bundles) {
|
|
1991
2454
|
if (this.environment.config.consumer === "client") {
|
|
1992
|
-
const entries = [
|
|
2455
|
+
const entries = [
|
|
2456
|
+
...ctx.entries,
|
|
2457
|
+
...ctx.serviceWorkers
|
|
2458
|
+
].map((entry) => {
|
|
1993
2459
|
return {
|
|
1994
2460
|
chunkFileName: entry.chunkFileName,
|
|
1995
2461
|
extensionlessFilePath: removeExtension(entry.filePath)
|
|
@@ -2020,23 +2486,14 @@ function qwikRouterPlugin(userOpts) {
|
|
|
2020
2486
|
};
|
|
2021
2487
|
return plugin;
|
|
2022
2488
|
}
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
...contentAsJson
|
|
2032
|
-
};
|
|
2033
|
-
}
|
|
2034
|
-
packageJson = {
|
|
2035
|
-
...packageJson,
|
|
2036
|
-
type: "module"
|
|
2037
|
-
};
|
|
2038
|
-
const serverPackageJsonCode = JSON.stringify(packageJson, null, 2);
|
|
2039
|
-
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);
|
|
2040
2497
|
}
|
|
2041
2498
|
|
|
2042
2499
|
export { extendConfig, qwikCity, qwikRouter };
|