@solidjs/vite-plugin 3.0.0-next.29 → 3.0.0-next.30
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/dist/cjs/index.cjs +40 -6
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/esm/index.mjs +40 -6
- package/dist/esm/index.mjs.map +1 -1
- package/dist/types/src/http.d.ts +8 -1
- package/package.json +2 -2
package/dist/esm/index.mjs
CHANGED
|
@@ -21,24 +21,54 @@ import { crawlFrameworkPkgs } from 'vitefu';
|
|
|
21
21
|
* different URL than the one node saw — the dev middlewares use it to
|
|
22
22
|
* restore the configured Vite `base` that the dev/preview base middleware
|
|
23
23
|
* stripped, so the handler always sees production-shaped URLs.
|
|
24
|
+
*
|
|
25
|
+
* Handles plain HTTP/1 *and* the HTTP/2 compat API: Vite's dev server uses
|
|
26
|
+
* `http2.createSecureServer({ allowHTTP1: true })` whenever `server.https`
|
|
27
|
+
* is set without a proxy, so under https the middlewares receive
|
|
28
|
+
* `Http2ServerRequest`s. The h2/protocol/abort techniques here are
|
|
29
|
+
* reimplemented from srvx's Node adapter (github.com/h3js/srvx,
|
|
30
|
+
* src/adapters/_node) — reference, not copied code.
|
|
24
31
|
*/
|
|
25
|
-
function webRequestFromNode(req, urlPath) {
|
|
26
|
-
|
|
32
|
+
function webRequestFromNode(req, urlPath, res) {
|
|
33
|
+
// TLS sockets (https and h2) expose `encrypted`; a Request whose url says
|
|
34
|
+
// http: on a TLS connection breaks secure-cookie logic, absolute
|
|
35
|
+
// redirects, and origin checks in application code.
|
|
36
|
+
const protocol = req.socket?.encrypted ? 'https' : 'http';
|
|
37
|
+
// HTTP/2 has no Host header — the authority travels in the `:authority`
|
|
38
|
+
// pseudo-header instead.
|
|
39
|
+
const host = req.headers.host ?? req.headers[':authority'] ?? 'localhost';
|
|
40
|
+
const url = new URL(urlPath ?? req.url ?? '/', `${protocol}://${host}`);
|
|
27
41
|
const headers = new Headers();
|
|
28
42
|
for (const [key, value] of Object.entries(req.headers)) {
|
|
29
43
|
if (value === undefined) continue;
|
|
44
|
+
// HTTP/2 pseudo-headers (:method, :path, :authority, :scheme) are not
|
|
45
|
+
// legal field names — Headers#append throws a TypeError on them.
|
|
46
|
+
if (key[0] === ':') continue;
|
|
30
47
|
if (Array.isArray(value)) {
|
|
31
48
|
for (const item of value) headers.append(key, item);
|
|
32
49
|
} else {
|
|
33
50
|
headers.append(key, value);
|
|
34
51
|
}
|
|
35
52
|
}
|
|
53
|
+
// Surface client disconnects as the request's AbortSignal so handlers can
|
|
54
|
+
// cancel work (streamed SSR renders, in-flight fetches). The response's
|
|
55
|
+
// 'close' fires on normal completion too; `writableEnded` distinguishes a
|
|
56
|
+
// finished response from a client that went away.
|
|
57
|
+
let signal;
|
|
58
|
+
if (res) {
|
|
59
|
+
const controller = new AbortController();
|
|
60
|
+
res.once('close', () => {
|
|
61
|
+
if (!res.writableEnded) controller.abort();
|
|
62
|
+
});
|
|
63
|
+
signal = controller.signal;
|
|
64
|
+
}
|
|
36
65
|
const method = req.method || 'GET';
|
|
37
66
|
const body = method === 'GET' || method === 'HEAD' ? undefined : Readable.toWeb(req);
|
|
38
67
|
return new Request(url, {
|
|
39
68
|
method,
|
|
40
69
|
headers,
|
|
41
70
|
body,
|
|
71
|
+
signal,
|
|
42
72
|
// undici requires half-duplex for streamed request bodies.
|
|
43
73
|
...(body ? {
|
|
44
74
|
duplex: 'half'
|
|
@@ -53,7 +83,11 @@ async function sendWebResponse(res, response) {
|
|
|
53
83
|
if (key !== 'set-cookie') res.setHeader(key, value);
|
|
54
84
|
});
|
|
55
85
|
if (cookies && cookies.length) res.setHeader('set-cookie', cookies);
|
|
56
|
-
|
|
86
|
+
// HEAD gets the head only — and the body must be *cancelled*, not pumped:
|
|
87
|
+
// node discards HEAD body writes, so streaming a long (or endless) body
|
|
88
|
+
// into the void just burns the render. (Technique from srvx.)
|
|
89
|
+
if (!response.body || res.req?.method === 'HEAD') {
|
|
90
|
+
response.body?.cancel().catch(() => {});
|
|
57
91
|
res.end();
|
|
58
92
|
return;
|
|
59
93
|
}
|
|
@@ -1010,7 +1044,7 @@ function serverFunctions(options = {}, internal = {}) {
|
|
|
1010
1044
|
nativeEvent: req
|
|
1011
1045
|
}
|
|
1012
1046
|
};
|
|
1013
|
-
const response = internal.ssrHandler ? await handler.handleRequest(webRequestFromNode(req, dispatchUrl), dispatchOptions) : await handler.handleServerFunctionRequest(webRequestFromNode(req, dispatchUrl), dispatchOptions);
|
|
1047
|
+
const response = internal.ssrHandler ? await handler.handleRequest(webRequestFromNode(req, dispatchUrl, res), dispatchOptions) : await handler.handleServerFunctionRequest(webRequestFromNode(req, dispatchUrl, res), dispatchOptions);
|
|
1014
1048
|
await sendWebResponse(res, response);
|
|
1015
1049
|
})().catch(error => {
|
|
1016
1050
|
if (error instanceof Error) server.ssrFixStacktrace(error);
|
|
@@ -1804,7 +1838,7 @@ function startServe(options, internal = {}) {
|
|
|
1804
1838
|
// server-function endpoint) and hands the URL to application
|
|
1805
1839
|
// code, so restore the base — the deployed production handler
|
|
1806
1840
|
// receives base-prefixed URLs and preview must match it.
|
|
1807
|
-
const response = await handler.handleRequest(webRequestFromNode(req, joinBase(base, req.url || '/')),
|
|
1841
|
+
const response = await handler.handleRequest(webRequestFromNode(req, joinBase(base, req.url || '/'), res),
|
|
1808
1842
|
// Same event extension the dev middleware and a production
|
|
1809
1843
|
// Node entry pass: the raw Node request as `nativeEvent`.
|
|
1810
1844
|
{
|
|
@@ -1861,7 +1895,7 @@ function startServe(options, internal = {}) {
|
|
|
1861
1895
|
// the configured `base` from req.url; restore it so the app
|
|
1862
1896
|
// sees the same URLs in dev as in production (where the
|
|
1863
1897
|
// deployed handler receives base-prefixed requests).
|
|
1864
|
-
const response = await handler.handleRequest(webRequestFromNode(req, joinBase(base, req.url || '/')), {
|
|
1898
|
+
const response = await handler.handleRequest(webRequestFromNode(req, joinBase(base, req.url || '/'), res), {
|
|
1865
1899
|
devHead,
|
|
1866
1900
|
pageRequest,
|
|
1867
1901
|
// The raw Node request on the event, matching what a
|