@qwik.dev/router 2.0.0-beta.31 → 2.0.0-beta.34
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/chunks/routing.qwik.mjs +6 -6
- package/lib/chunks/worker-thread.qwik.mjs +6 -6
- package/lib/index.d.ts +49 -11
- package/lib/index.qwik.mjs +114 -50
- package/lib/middleware/aws-lambda/index.d.ts +15 -11
- package/lib/middleware/aws-lambda/index.mjs +4 -3
- package/lib/middleware/bun/index.d.ts +9 -5
- package/lib/middleware/bun/index.mjs +3 -22
- package/lib/middleware/deno/index.d.ts +9 -5
- package/lib/middleware/deno/index.mjs +3 -22
- package/lib/middleware/firebase/index.mjs +3 -3
- package/lib/middleware/node/index.d.ts +9 -5
- package/lib/middleware/node/index.mjs +73 -30
- package/lib/vite/index.mjs +216 -84
- package/package.json +3 -3
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { setServerPlatform } from '@qwik.dev/core/server';
|
|
2
|
-
import { isStaticPath,
|
|
2
|
+
import { isStaticPath, mergeHeadersCookies, requestHandler } from '@qwik.dev/router/middleware/request-handler';
|
|
3
3
|
import { M as MIME_TYPES, n as normalizeRequestUrl } from '../../chunks/url.mjs';
|
|
4
4
|
import { join, fromFileUrl, extname } from 'https://deno.land/std/path/mod.ts';
|
|
5
5
|
import { isDev } from '@qwik.dev/core/build';
|
|
@@ -69,27 +69,8 @@ function createQwikRouter(opts) {
|
|
|
69
69
|
});
|
|
70
70
|
}
|
|
71
71
|
}
|
|
72
|
-
const notFound = async (
|
|
73
|
-
|
|
74
|
-
const url = getRequestUrl(request, opts);
|
|
75
|
-
const notFoundHtml = !request.headers.get("accept")?.includes("text/html") || isStaticPath(request.method || "GET", url) ? "Not Found" : getNotFound(url.pathname);
|
|
76
|
-
return new Response(notFoundHtml, {
|
|
77
|
-
status: 404,
|
|
78
|
-
headers: {
|
|
79
|
-
"Content-Type": "text/html; charset=utf-8",
|
|
80
|
-
"X-Not-Found": url.pathname
|
|
81
|
-
}
|
|
82
|
-
});
|
|
83
|
-
} catch (e) {
|
|
84
|
-
console.error(e);
|
|
85
|
-
return new Response(isDev ? String(e || "Error") : "Internal Server Error", {
|
|
86
|
-
status: 500,
|
|
87
|
-
headers: {
|
|
88
|
-
"Content-Type": "text/plain; charset=utf-8",
|
|
89
|
-
"X-Error": "deno-server"
|
|
90
|
-
}
|
|
91
|
-
});
|
|
92
|
-
}
|
|
72
|
+
const notFound = async (_request) => {
|
|
73
|
+
return null;
|
|
93
74
|
};
|
|
94
75
|
const openStaticFile = async (url) => {
|
|
95
76
|
const pathname = url.pathname;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createQwikRouter as createQwikRouter$1 } from '@qwik.dev/router/middleware/node';
|
|
2
2
|
|
|
3
3
|
function createQwikRouter(opts) {
|
|
4
|
-
const { staticFile,
|
|
4
|
+
const { staticFile, router } = createQwikRouter$1({
|
|
5
5
|
render: opts.render,
|
|
6
6
|
manifest: opts.manifest,
|
|
7
7
|
static: {
|
|
@@ -16,8 +16,8 @@ function createQwikRouter(opts) {
|
|
|
16
16
|
});
|
|
17
17
|
const qwikApp = (req, res) => {
|
|
18
18
|
return staticFile(req, res, () => {
|
|
19
|
-
router(req, res, () =>
|
|
20
|
-
})
|
|
19
|
+
router(req, res, () => {
|
|
20
|
+
});
|
|
21
21
|
});
|
|
22
22
|
};
|
|
23
23
|
return qwikApp;
|
|
@@ -11,11 +11,7 @@ import type { ServerResponse } from 'node:http';
|
|
|
11
11
|
export declare const createQwikCity: typeof createQwikRouter;
|
|
12
12
|
|
|
13
13
|
/** @public */
|
|
14
|
-
export declare function createQwikRouter(opts: QwikRouterNodeRequestOptions | QwikCityNodeRequestOptions):
|
|
15
|
-
router: (req: IncomingMessage | Http2ServerRequest, res: ServerResponse, next: NodeRequestNextFunction) => Promise<void>;
|
|
16
|
-
notFound: (req: IncomingMessage | Http2ServerRequest, res: ServerResponse, next: (e: any) => void) => Promise<void>;
|
|
17
|
-
staticFile: (req: IncomingMessage | Http2ServerRequest, res: ServerResponse, next: (e?: any) => void) => Promise<void>;
|
|
18
|
-
};
|
|
14
|
+
export declare function createQwikRouter(opts: QwikRouterNodeRequestOptions | QwikCityNodeRequestOptions): QwikRouterNodeMiddleware;
|
|
19
15
|
|
|
20
16
|
/** @public */
|
|
21
17
|
export declare interface NodeRequestNextFunction {
|
|
@@ -35,6 +31,14 @@ export declare interface PlatformNode {
|
|
|
35
31
|
*/
|
|
36
32
|
export declare type QwikCityNodeRequestOptions = QwikRouterNodeRequestOptions;
|
|
37
33
|
|
|
34
|
+
/** @public */
|
|
35
|
+
export declare interface QwikRouterNodeMiddleware {
|
|
36
|
+
router: (req: IncomingMessage | Http2ServerRequest, res: ServerResponse, next: NodeRequestNextFunction) => Promise<void>;
|
|
37
|
+
/** @deprecated `router` handles 404 responses. Will be removed in V3. */
|
|
38
|
+
notFound: (req: IncomingMessage | Http2ServerRequest, res: ServerResponse, next: (e: any) => void) => Promise<void>;
|
|
39
|
+
staticFile: (req: IncomingMessage | Http2ServerRequest, res: ServerResponse, next: (e?: any) => void) => Promise<void>;
|
|
40
|
+
}
|
|
41
|
+
|
|
38
42
|
/** @public */
|
|
39
43
|
export declare interface QwikRouterNodeRequestOptions extends ServerRenderOptions {
|
|
40
44
|
/** Options for serving static files */
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { isDev } from '@qwik.dev/core';
|
|
2
2
|
import { setServerPlatform } from '@qwik.dev/core/server';
|
|
3
|
-
import { isStaticPath,
|
|
3
|
+
import { isStaticPath, requestHandler } from '@qwik.dev/router/middleware/request-handler';
|
|
4
4
|
import { createReadStream } from 'node:fs';
|
|
5
5
|
import { join, basename, extname } from 'node:path';
|
|
6
6
|
import { fileURLToPath } from 'node:url';
|
|
@@ -32,6 +32,71 @@ function normalizeUrl(url, base) {
|
|
|
32
32
|
function getUrl(req, origin) {
|
|
33
33
|
return normalizeUrl(req.originalUrl || req.url || "/", origin);
|
|
34
34
|
}
|
|
35
|
+
function createNodeResponseSink(res) {
|
|
36
|
+
let closed = res.closed || res.destroyed;
|
|
37
|
+
const closedPromise = closed ? Promise.resolve() : new Promise((resolve) => {
|
|
38
|
+
res.once("close", () => {
|
|
39
|
+
closed = true;
|
|
40
|
+
resolve();
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
const write = (chunk) => {
|
|
44
|
+
if (closed || res.closed || res.destroyed) {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
return new Promise((resolve, reject) => {
|
|
48
|
+
let settled = false;
|
|
49
|
+
const finish = () => {
|
|
50
|
+
if (settled) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
settled = true;
|
|
54
|
+
setImmediate(resolve);
|
|
55
|
+
};
|
|
56
|
+
const fail = (error) => {
|
|
57
|
+
if (settled) {
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
settled = true;
|
|
61
|
+
reject(error);
|
|
62
|
+
};
|
|
63
|
+
closedPromise.then(finish);
|
|
64
|
+
try {
|
|
65
|
+
res.write(chunk, (error) => {
|
|
66
|
+
if (error) {
|
|
67
|
+
if (isIgnoredError(error.message)) {
|
|
68
|
+
finish();
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
fail(error);
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
finish();
|
|
75
|
+
});
|
|
76
|
+
} catch (error) {
|
|
77
|
+
if (error instanceof Error && isIgnoredError(error.message)) {
|
|
78
|
+
finish();
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
fail(error);
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
};
|
|
85
|
+
const close = () => {
|
|
86
|
+
if (closed || res.closed || res.destroyed) {
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
return new Promise((resolve) => {
|
|
90
|
+
res.end(() => {
|
|
91
|
+
resolve();
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
};
|
|
95
|
+
return {
|
|
96
|
+
write,
|
|
97
|
+
close
|
|
98
|
+
};
|
|
99
|
+
}
|
|
35
100
|
async function fromNodeHttp(url, req, res, mode, getClientConn) {
|
|
36
101
|
const requestHeaders = new Headers();
|
|
37
102
|
const nodeRequestHeaders = req.headers;
|
|
@@ -79,6 +144,7 @@ async function fromNodeHttp(url, req, res, mode, getClientConn) {
|
|
|
79
144
|
},
|
|
80
145
|
getWritableStream: (status, headers, cookies) => {
|
|
81
146
|
res.statusCode = status;
|
|
147
|
+
const sink = createNodeResponseSink(res);
|
|
82
148
|
try {
|
|
83
149
|
for (const [key, value] of headers) {
|
|
84
150
|
if (invalidHeadersPattern.test(key)) {
|
|
@@ -95,17 +161,10 @@ async function fromNodeHttp(url, req, res, mode, getClientConn) {
|
|
|
95
161
|
}
|
|
96
162
|
return new WritableStream({
|
|
97
163
|
write(chunk) {
|
|
98
|
-
|
|
99
|
-
return;
|
|
100
|
-
}
|
|
101
|
-
res.write(chunk, (error) => {
|
|
102
|
-
if (error && !isIgnoredError(error.message)) {
|
|
103
|
-
console.error(error);
|
|
104
|
-
}
|
|
105
|
-
});
|
|
164
|
+
return sink.write(chunk);
|
|
106
165
|
},
|
|
107
166
|
close() {
|
|
108
|
-
|
|
167
|
+
return sink.close();
|
|
109
168
|
}
|
|
110
169
|
});
|
|
111
170
|
},
|
|
@@ -139,12 +198,12 @@ function createQwikRouter(opts) {
|
|
|
139
198
|
const handled = await requestHandler(serverRequestEv, opts);
|
|
140
199
|
if (handled) {
|
|
141
200
|
const err = await handled.completion;
|
|
142
|
-
if (err) {
|
|
143
|
-
throw err;
|
|
144
|
-
}
|
|
145
201
|
if (handled.requestEv.headersSent) {
|
|
146
202
|
return;
|
|
147
203
|
}
|
|
204
|
+
if (err) {
|
|
205
|
+
throw err;
|
|
206
|
+
}
|
|
148
207
|
}
|
|
149
208
|
next();
|
|
150
209
|
} catch (e) {
|
|
@@ -152,23 +211,7 @@ function createQwikRouter(opts) {
|
|
|
152
211
|
next(e);
|
|
153
212
|
}
|
|
154
213
|
};
|
|
155
|
-
const notFound = async (
|
|
156
|
-
try {
|
|
157
|
-
if (!res.headersSent) {
|
|
158
|
-
const origin = computeOrigin(req, opts);
|
|
159
|
-
const url = getUrl(req, origin);
|
|
160
|
-
const notFoundHtml = !req.headers.accept?.includes("text/html") || isStaticPath(req.method || "GET", url) ? "Not Found" : getNotFound(url.pathname);
|
|
161
|
-
res.writeHead(404, {
|
|
162
|
-
"Content-Type": "text/html; charset=utf-8",
|
|
163
|
-
"X-Not-Found": url.pathname
|
|
164
|
-
});
|
|
165
|
-
res.end(notFoundHtml);
|
|
166
|
-
}
|
|
167
|
-
} catch (e) {
|
|
168
|
-
console.error(e);
|
|
169
|
-
next(e);
|
|
170
|
-
}
|
|
171
|
-
};
|
|
214
|
+
const notFound = async (_req, _res, next) => next();
|
|
172
215
|
const staticFile = async (req, res, next) => {
|
|
173
216
|
try {
|
|
174
217
|
const origin = computeOrigin(req, opts);
|
package/lib/vite/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { mergeConfig, loadEnv } from 'vite';
|
|
1
|
+
import { mergeConfig, normalizePath as normalizePath$1, 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
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';
|
|
@@ -479,7 +479,7 @@ async function walkServerPlugins(opts) {
|
|
|
479
479
|
});
|
|
480
480
|
}
|
|
481
481
|
}));
|
|
482
|
-
return sourceFiles;
|
|
482
|
+
return sourceFiles.sort((a, b) => a.filePath < b.filePath ? -1 : 1);
|
|
483
483
|
}
|
|
484
484
|
|
|
485
485
|
function resolveEntry(opts, sourceFile) {
|
|
@@ -1326,7 +1326,7 @@ function serializeBuildTrie(ctx, qwikPlugin, node, layoutIdMap, routeIdMap, menu
|
|
|
1326
1326
|
if (node._9) {
|
|
1327
1327
|
lines.push(`${nextIndent}_9: ${JSON.stringify(node._9)},`);
|
|
1328
1328
|
}
|
|
1329
|
-
if (node._G) {
|
|
1329
|
+
if (node._G != null) {
|
|
1330
1330
|
lines.push(`${nextIndent}_G: ${JSON.stringify(node._G)},`);
|
|
1331
1331
|
}
|
|
1332
1332
|
let layoutExpr;
|
|
@@ -1756,6 +1756,67 @@ function parseId(originalId) {
|
|
|
1756
1756
|
};
|
|
1757
1757
|
}
|
|
1758
1758
|
|
|
1759
|
+
const supportedExtensions = [
|
|
1760
|
+
".jpg",
|
|
1761
|
+
".jpeg",
|
|
1762
|
+
".png",
|
|
1763
|
+
".webp",
|
|
1764
|
+
".gif",
|
|
1765
|
+
".avif",
|
|
1766
|
+
".tiff"
|
|
1767
|
+
];
|
|
1768
|
+
const JSX_QUERY_PARAM = "jsx";
|
|
1769
|
+
const INTERNAL_IMAGE_JSX_QUERY_PARAM = "qwik-asset-jsx";
|
|
1770
|
+
const VIRTUAL_IMAGE_JSX_PREFIX = "virtual:";
|
|
1771
|
+
const VIRTUAL_IMAGE_JSX_SUFFIX = ".qwik.jsx";
|
|
1772
|
+
const TO_IMG_ID = "@to-img.qwik.jsx";
|
|
1773
|
+
const VIRTUAL_TO_IMG_ID = "virtual:to-img.qwik.jsx";
|
|
1774
|
+
function createVirtualImageJsxId(pathId, params) {
|
|
1775
|
+
const query = new URLSearchParams(params);
|
|
1776
|
+
query.delete(INTERNAL_IMAGE_JSX_QUERY_PARAM);
|
|
1777
|
+
const queryString = query.toString();
|
|
1778
|
+
return `${VIRTUAL_IMAGE_JSX_PREFIX}${normalizePath$1(pathId)}${VIRTUAL_IMAGE_JSX_SUFFIX}${queryString ? `?${queryString}` : ""}`;
|
|
1779
|
+
}
|
|
1780
|
+
function createImageJsxImportId(pathId, params) {
|
|
1781
|
+
const query = new URLSearchParams(params);
|
|
1782
|
+
query.set(INTERNAL_IMAGE_JSX_QUERY_PARAM, "");
|
|
1783
|
+
return `${normalizePath$1(pathId)}?${query.toString()}`;
|
|
1784
|
+
}
|
|
1785
|
+
function parseVirtualImageJsxId(id) {
|
|
1786
|
+
const parsed = parseId(id);
|
|
1787
|
+
if (!parsed.pathId.startsWith(VIRTUAL_IMAGE_JSX_PREFIX) || !parsed.pathId.endsWith(VIRTUAL_IMAGE_JSX_SUFFIX)) {
|
|
1788
|
+
return null;
|
|
1789
|
+
}
|
|
1790
|
+
const pathId = parsed.pathId.slice(VIRTUAL_IMAGE_JSX_PREFIX.length, -VIRTUAL_IMAGE_JSX_SUFFIX.length);
|
|
1791
|
+
return {
|
|
1792
|
+
...parsed,
|
|
1793
|
+
extension: path.extname(pathId).toLowerCase(),
|
|
1794
|
+
pathId
|
|
1795
|
+
};
|
|
1796
|
+
}
|
|
1797
|
+
function getToImg() {
|
|
1798
|
+
return `
|
|
1799
|
+
import { _jsxSplit, _getVarProps as v, _getConstProps as c} from '@qwik.dev/core';
|
|
1800
|
+
const decoding = "async";
|
|
1801
|
+
const loading = "lazy";
|
|
1802
|
+
export default (s, w, h) =>
|
|
1803
|
+
// Try to preserve const attrs by not spreading when props are not provided
|
|
1804
|
+
p => p
|
|
1805
|
+
? _jsxSplit("img", {decoding, loading, ...v(p)}, {...c(p), height: h, srcSet: s, width: w })
|
|
1806
|
+
: _jsxSplit("img", null, {decoding, height: h, loading, srcSet: s, width: w});
|
|
1807
|
+
`;
|
|
1808
|
+
}
|
|
1809
|
+
function createImageJsxModule(pathId, params) {
|
|
1810
|
+
return `
|
|
1811
|
+
import { srcSet, width, height } from ${JSON.stringify(createImageJsxImportId(pathId, params))};
|
|
1812
|
+
import toImg from ${JSON.stringify(TO_IMG_ID)};
|
|
1813
|
+
|
|
1814
|
+
export default toImg(srcSet, width, height);
|
|
1815
|
+
`;
|
|
1816
|
+
}
|
|
1817
|
+
function createSvgJsxModule(attrs) {
|
|
1818
|
+
return `export default p => <svg {...p} {...${JSON.stringify(attrs)}} />`;
|
|
1819
|
+
}
|
|
1759
1820
|
function optimizeSvg({ code, path: path2 }, userOpts) {
|
|
1760
1821
|
const svgAttributes = {};
|
|
1761
1822
|
const prefixIdsConfiguration = userOpts?.imageOptimization?.svgo?.prefixIds;
|
|
@@ -1771,7 +1832,7 @@ function optimizeSvg({ code, path: path2 }, userOpts) {
|
|
|
1771
1832
|
return false;
|
|
1772
1833
|
}
|
|
1773
1834
|
if (plugin === "prefixIds" || typeof plugin === "object" && plugin.name === "prefixIds") {
|
|
1774
|
-
console.warn(`You are trying to use the
|
|
1835
|
+
console.warn(`You are trying to use the prefixIds SVGO plugin. This plugin is already included by default, you can customize it through the prefixIds option.`);
|
|
1775
1836
|
return false;
|
|
1776
1837
|
}
|
|
1777
1838
|
return true;
|
|
@@ -1817,15 +1878,6 @@ function optimizeSvg({ code, path: path2 }, userOpts) {
|
|
|
1817
1878
|
};
|
|
1818
1879
|
}
|
|
1819
1880
|
function imagePlugin(userOpts) {
|
|
1820
|
-
const supportedExtensions = [
|
|
1821
|
-
".jpg",
|
|
1822
|
-
".jpeg",
|
|
1823
|
-
".png",
|
|
1824
|
-
".webp",
|
|
1825
|
-
".gif",
|
|
1826
|
-
".avif",
|
|
1827
|
-
".tiff"
|
|
1828
|
-
];
|
|
1829
1881
|
return [
|
|
1830
1882
|
import('vite-imagetools').then((_rawProps) => _rawProps.imagetools({
|
|
1831
1883
|
exclude: [],
|
|
@@ -1853,8 +1905,10 @@ function imagePlugin(userOpts) {
|
|
|
1853
1905
|
};
|
|
1854
1906
|
},
|
|
1855
1907
|
defaultDirectives: (url) => {
|
|
1856
|
-
if (url.searchParams.has(
|
|
1857
|
-
const
|
|
1908
|
+
if (url.searchParams.has(JSX_QUERY_PARAM)) {
|
|
1909
|
+
const params = Object.fromEntries(url.searchParams.entries());
|
|
1910
|
+
delete params[JSX_QUERY_PARAM];
|
|
1911
|
+
delete params[INTERNAL_IMAGE_JSX_QUERY_PARAM];
|
|
1858
1912
|
return new URLSearchParams({
|
|
1859
1913
|
format: "webp",
|
|
1860
1914
|
quality: "75",
|
|
@@ -1868,66 +1922,150 @@ function imagePlugin(userOpts) {
|
|
|
1868
1922
|
return new URLSearchParams();
|
|
1869
1923
|
}
|
|
1870
1924
|
})).catch((err) => {
|
|
1871
|
-
console.error(
|
|
1925
|
+
console.error('Error loading vite-imagetools, image imports ("foo.png?jsx") are not available', err);
|
|
1872
1926
|
return null;
|
|
1873
1927
|
}),
|
|
1874
1928
|
{
|
|
1875
1929
|
name: "qwik-router-image-jsx",
|
|
1930
|
+
resolveId: {
|
|
1931
|
+
order: "pre",
|
|
1932
|
+
async handler(id, importer, options) {
|
|
1933
|
+
if (parseVirtualImageJsxId(id)) {
|
|
1934
|
+
return null;
|
|
1935
|
+
}
|
|
1936
|
+
if (id.endsWith(TO_IMG_ID)) {
|
|
1937
|
+
return VIRTUAL_TO_IMG_ID;
|
|
1938
|
+
}
|
|
1939
|
+
const { pathId, params } = parseId(id);
|
|
1940
|
+
if (!params.has(JSX_QUERY_PARAM) || params.has(INTERNAL_IMAGE_JSX_QUERY_PARAM)) {
|
|
1941
|
+
return null;
|
|
1942
|
+
}
|
|
1943
|
+
const resolved = await this.resolve(pathId, importer, {
|
|
1944
|
+
...options,
|
|
1945
|
+
skipSelf: true
|
|
1946
|
+
});
|
|
1947
|
+
const resolvedId = parseId((resolved ?? {
|
|
1948
|
+
id: pathId
|
|
1949
|
+
}).id).pathId;
|
|
1950
|
+
const extension = path.extname(resolvedId).toLowerCase();
|
|
1951
|
+
if (extension !== ".svg" && !supportedExtensions.includes(extension)) {
|
|
1952
|
+
return null;
|
|
1953
|
+
}
|
|
1954
|
+
return {
|
|
1955
|
+
id: createVirtualImageJsxId(resolvedId, params),
|
|
1956
|
+
moduleSideEffects: false
|
|
1957
|
+
};
|
|
1958
|
+
}
|
|
1959
|
+
},
|
|
1876
1960
|
load: {
|
|
1877
1961
|
order: "pre",
|
|
1878
1962
|
handler: async (id) => {
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1963
|
+
if (id === VIRTUAL_TO_IMG_ID) {
|
|
1964
|
+
return getToImg();
|
|
1965
|
+
}
|
|
1966
|
+
const imageId = parseVirtualImageJsxId(id);
|
|
1967
|
+
if (!imageId) {
|
|
1968
|
+
return null;
|
|
1969
|
+
}
|
|
1970
|
+
if (imageId.extension === ".svg") {
|
|
1971
|
+
const code = await fs.promises.readFile(imageId.pathId, "utf-8");
|
|
1883
1972
|
return {
|
|
1884
1973
|
code,
|
|
1885
1974
|
moduleSideEffects: false
|
|
1886
1975
|
};
|
|
1887
1976
|
}
|
|
1977
|
+
return {
|
|
1978
|
+
code: "export default undefined;",
|
|
1979
|
+
moduleSideEffects: false
|
|
1980
|
+
};
|
|
1888
1981
|
}
|
|
1889
1982
|
},
|
|
1890
|
-
transform
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
}
|
|
1899
|
-
const index = code.indexOf("export default");
|
|
1900
|
-
return {
|
|
1901
|
-
code: code.slice(0, index) + `
|
|
1902
|
-
import { _jsxSorted } from '@qwik.dev/core';
|
|
1903
|
-
const PROPS = {srcSet, width, height};
|
|
1904
|
-
export default function (props, key, _, dev) {
|
|
1905
|
-
return _jsxSorted('img', {...{decoding: 'async', loading: 'lazy'}, ...props}, PROPS, undefined, 3, key, dev);
|
|
1906
|
-
}`,
|
|
1907
|
-
map: null
|
|
1908
|
-
};
|
|
1909
|
-
} else if (extension === ".svg") {
|
|
1983
|
+
transform: {
|
|
1984
|
+
order: "pre",
|
|
1985
|
+
handler(code, id) {
|
|
1986
|
+
const imageId = parseVirtualImageJsxId(id);
|
|
1987
|
+
if (!imageId) {
|
|
1988
|
+
return null;
|
|
1989
|
+
}
|
|
1990
|
+
if (imageId.extension === ".svg") {
|
|
1910
1991
|
const { svgAttributes } = optimizeSvg({
|
|
1911
1992
|
code,
|
|
1912
|
-
path: pathId
|
|
1993
|
+
path: imageId.pathId
|
|
1913
1994
|
}, userOpts);
|
|
1914
1995
|
return {
|
|
1915
|
-
code:
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1996
|
+
code: createSvgJsxModule(svgAttributes),
|
|
1997
|
+
map: null
|
|
1998
|
+
};
|
|
1999
|
+
}
|
|
2000
|
+
if (supportedExtensions.includes(imageId.extension)) {
|
|
2001
|
+
return {
|
|
2002
|
+
code: createImageJsxModule(imageId.pathId, imageId.params),
|
|
1921
2003
|
map: null
|
|
1922
2004
|
};
|
|
1923
2005
|
}
|
|
2006
|
+
return null;
|
|
1924
2007
|
}
|
|
1925
|
-
return null;
|
|
1926
2008
|
}
|
|
1927
2009
|
}
|
|
1928
2010
|
];
|
|
1929
2011
|
}
|
|
1930
2012
|
|
|
2013
|
+
async function collectServerFnModuleIds(routingContext, resolvedVirtualId, pluginContext) {
|
|
2014
|
+
const serverFnModules = /* @__PURE__ */ new Set();
|
|
2015
|
+
const queuedModuleIds = /* @__PURE__ */ new Set();
|
|
2016
|
+
const seenModuleIds = /* @__PURE__ */ new Set();
|
|
2017
|
+
const routes = routingContext.routes;
|
|
2018
|
+
const layouts = routingContext.layouts;
|
|
2019
|
+
const serverPlugins = routingContext.serverPlugins;
|
|
2020
|
+
for (let i = 0; i < routes.length; i++) {
|
|
2021
|
+
const route = routes[i];
|
|
2022
|
+
queuedModuleIds.add(route.filePath);
|
|
2023
|
+
for (let j = 0; j < route.layouts.length; j++) {
|
|
2024
|
+
const layout = route.layouts[j];
|
|
2025
|
+
queuedModuleIds.add(layout.filePath);
|
|
2026
|
+
}
|
|
2027
|
+
}
|
|
2028
|
+
for (let i = 0; i < layouts.length; i++) {
|
|
2029
|
+
queuedModuleIds.add(layouts[i].filePath);
|
|
2030
|
+
}
|
|
2031
|
+
for (let i = 0; i < serverPlugins.length; i++) {
|
|
2032
|
+
queuedModuleIds.add(serverPlugins[i].filePath);
|
|
2033
|
+
}
|
|
2034
|
+
while (queuedModuleIds.size > 0) {
|
|
2035
|
+
const [id] = queuedModuleIds;
|
|
2036
|
+
queuedModuleIds.delete(id);
|
|
2037
|
+
if (seenModuleIds.has(id) || id === resolvedVirtualId) {
|
|
2038
|
+
continue;
|
|
2039
|
+
}
|
|
2040
|
+
seenModuleIds.add(id);
|
|
2041
|
+
const resolved = await pluginContext.resolve(id, void 0, {
|
|
2042
|
+
skipSelf: true
|
|
2043
|
+
});
|
|
2044
|
+
if (!resolved || resolved.external) {
|
|
2045
|
+
continue;
|
|
2046
|
+
}
|
|
2047
|
+
const moduleInfo = await pluginContext.load({
|
|
2048
|
+
id: resolved.id
|
|
2049
|
+
});
|
|
2050
|
+
if (moduleInfo.code == null) {
|
|
2051
|
+
continue;
|
|
2052
|
+
}
|
|
2053
|
+
if (moduleInfo.code.includes("serverQrl(")) {
|
|
2054
|
+
serverFnModules.add(moduleInfo.id);
|
|
2055
|
+
}
|
|
2056
|
+
const resolvedImports = moduleInfo.importedIds.concat(moduleInfo.dynamicallyImportedIds);
|
|
2057
|
+
for (let i = 0; i < resolvedImports.length; i++) {
|
|
2058
|
+
const resolvedImport = resolvedImports[i];
|
|
2059
|
+
if (resolvedImport && !seenModuleIds.has(resolvedImport)) {
|
|
2060
|
+
queuedModuleIds.add(resolvedImport);
|
|
2061
|
+
}
|
|
2062
|
+
}
|
|
2063
|
+
}
|
|
2064
|
+
return [
|
|
2065
|
+
...serverFnModules
|
|
2066
|
+
];
|
|
2067
|
+
}
|
|
2068
|
+
|
|
1931
2069
|
async function validatePlugin(opts) {
|
|
1932
2070
|
if (typeof opts.routesDir !== "string") {
|
|
1933
2071
|
throw new Error(`qwikRouter plugin "routesDir" option missing`);
|
|
@@ -2187,16 +2325,14 @@ const makeRouterDevMiddleware = (server, ctx) => async (req, res, next) => {
|
|
|
2187
2325
|
const render = async (opts) => {
|
|
2188
2326
|
return await renderer(opts);
|
|
2189
2327
|
};
|
|
2190
|
-
const { router, staticFile
|
|
2328
|
+
const { router, staticFile } = createQwikRouter({
|
|
2191
2329
|
render,
|
|
2192
2330
|
// inject the platform from dev middleware options
|
|
2193
2331
|
platform: ctx.opts.platform
|
|
2194
2332
|
});
|
|
2195
2333
|
const wrappedRes = wrapResponseForHtmlTransform(req, res, server);
|
|
2196
2334
|
staticFile(req, wrappedRes, () => {
|
|
2197
|
-
router(req, wrappedRes,
|
|
2198
|
-
notFound(req, wrappedRes, next);
|
|
2199
|
-
});
|
|
2335
|
+
router(req, wrappedRes, next);
|
|
2200
2336
|
});
|
|
2201
2337
|
} catch (e) {
|
|
2202
2338
|
if (e instanceof Error) {
|
|
@@ -2288,7 +2424,7 @@ async function generateServerPackageJson(outDir) {
|
|
|
2288
2424
|
const serverPackageJsonCode = JSON.stringify(packageJson, null, 2);
|
|
2289
2425
|
await fs.promises.writeFile(serverPackageJsonPath, serverPackageJsonCode);
|
|
2290
2426
|
}
|
|
2291
|
-
function qwikRouterPlugin(userOpts) {
|
|
2427
|
+
function qwikRouterPlugin(userOpts, buildContextRef) {
|
|
2292
2428
|
let ctx = null;
|
|
2293
2429
|
let mdxTransform = null;
|
|
2294
2430
|
let rootDir = null;
|
|
@@ -2411,6 +2547,7 @@ function qwikRouterPlugin(userOpts) {
|
|
|
2411
2547
|
rootDir = resolve(config.root);
|
|
2412
2548
|
const target = config.build?.ssr || config.mode === "ssr" ? "ssr" : "client";
|
|
2413
2549
|
ctx = createBuildContext(rootDir, config.base, userOpts, target, !userOpts?.staticImportRoutes);
|
|
2550
|
+
buildContextRef.current = ctx;
|
|
2414
2551
|
await validatePlugin(ctx.opts);
|
|
2415
2552
|
mdxTransform = await createMdxTransformer(ctx);
|
|
2416
2553
|
qwikPlugin = config.plugins.find((p) => p.name === "vite-plugin-qwik");
|
|
@@ -2578,20 +2715,32 @@ function qwikRouterPlugin(userOpts) {
|
|
|
2578
2715
|
};
|
|
2579
2716
|
return plugin;
|
|
2580
2717
|
}
|
|
2581
|
-
function serverFnsPlugin() {
|
|
2718
|
+
function serverFnsPlugin(buildContextRef) {
|
|
2582
2719
|
const RESOLVED_ID = "\0" + VIRTUAL_SERVER_FNS;
|
|
2583
2720
|
const serverFnModules = /* @__PURE__ */ new Set();
|
|
2584
|
-
let
|
|
2585
|
-
let resolveServerFns = null;
|
|
2586
|
-
let serverFnsReady;
|
|
2721
|
+
let serverFnsReady = null;
|
|
2587
2722
|
function reset() {
|
|
2588
2723
|
serverFnModules.clear();
|
|
2589
|
-
|
|
2590
|
-
serverFnsReady = new Promise((r) => {
|
|
2591
|
-
resolveServerFns = r;
|
|
2592
|
-
});
|
|
2724
|
+
serverFnsReady = null;
|
|
2593
2725
|
}
|
|
2594
2726
|
reset();
|
|
2727
|
+
async function collectServerFnModules() {
|
|
2728
|
+
if (serverFnsReady) {
|
|
2729
|
+
await serverFnsReady;
|
|
2730
|
+
return;
|
|
2731
|
+
}
|
|
2732
|
+
serverFnsReady = (async () => {
|
|
2733
|
+
const ctx = buildContextRef.current;
|
|
2734
|
+
if (!ctx) {
|
|
2735
|
+
return;
|
|
2736
|
+
}
|
|
2737
|
+
const moduleIds = await collectServerFnModuleIds(ctx, RESOLVED_ID, this);
|
|
2738
|
+
for (let i = 0; i < moduleIds.length; i++) {
|
|
2739
|
+
serverFnModules.add(moduleIds[i]);
|
|
2740
|
+
}
|
|
2741
|
+
})();
|
|
2742
|
+
await serverFnsReady;
|
|
2743
|
+
}
|
|
2595
2744
|
return {
|
|
2596
2745
|
name: "vite-plugin-qwik-router-server-fns",
|
|
2597
2746
|
buildStart() {
|
|
@@ -2611,7 +2760,7 @@ function serverFnsPlugin() {
|
|
|
2611
2760
|
const isServerBuild = this.environment.config.consumer === "server" && this.environment.mode === "build";
|
|
2612
2761
|
if (id === RESOLVED_ID) {
|
|
2613
2762
|
if (isServerBuild) {
|
|
2614
|
-
await
|
|
2763
|
+
await collectServerFnModules.call(this);
|
|
2615
2764
|
}
|
|
2616
2765
|
if (!isServerBuild || serverFnModules.size === 0) {
|
|
2617
2766
|
return "// No server$ functions";
|
|
@@ -2620,35 +2769,18 @@ function serverFnsPlugin() {
|
|
|
2620
2769
|
...serverFnModules
|
|
2621
2770
|
].map((mod) => `import ${JSON.stringify(mod)};`).join("\n");
|
|
2622
2771
|
}
|
|
2623
|
-
if (isServerBuild && id !== RESOLVED_ID) {
|
|
2624
|
-
pendingModules++;
|
|
2625
|
-
this.load({
|
|
2626
|
-
id
|
|
2627
|
-
}).then((result) => {
|
|
2628
|
-
if (typeof result.code === "string" && result.code.includes("serverQrl(")) {
|
|
2629
|
-
serverFnModules.add(id);
|
|
2630
|
-
}
|
|
2631
|
-
}).finally(() => {
|
|
2632
|
-
pendingModules--;
|
|
2633
|
-
if (pendingModules <= 0 && resolveServerFns) {
|
|
2634
|
-
setTimeout(() => {
|
|
2635
|
-
if (pendingModules <= 0 && resolveServerFns) {
|
|
2636
|
-
resolveServerFns();
|
|
2637
|
-
resolveServerFns = null;
|
|
2638
|
-
}
|
|
2639
|
-
}, 50);
|
|
2640
|
-
}
|
|
2641
|
-
});
|
|
2642
|
-
}
|
|
2643
2772
|
return null;
|
|
2644
2773
|
}
|
|
2645
2774
|
}
|
|
2646
2775
|
};
|
|
2647
2776
|
}
|
|
2648
2777
|
function qwikRouter(userOpts) {
|
|
2778
|
+
const buildContextRef = {
|
|
2779
|
+
current: null
|
|
2780
|
+
};
|
|
2649
2781
|
return [
|
|
2650
|
-
qwikRouterPlugin(userOpts),
|
|
2651
|
-
serverFnsPlugin(),
|
|
2782
|
+
qwikRouterPlugin(userOpts, buildContextRef),
|
|
2783
|
+
serverFnsPlugin(buildContextRef),
|
|
2652
2784
|
...imagePlugin(userOpts)
|
|
2653
2785
|
];
|
|
2654
2786
|
}
|