@solidjs/start 0.6.1 → 0.7.0
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/client/{index.tsx → index.ts} +0 -2
- package/config/index.d.ts +12 -3
- package/config/index.js +16 -12
- package/config/server-components.js +1 -1
- package/config/server-fns-runtime.ts +3 -0
- package/config/server-handler.ts +20 -9
- package/config/server-runtime.ts +4 -4
- package/middleware/index.ts +5 -5
- package/package.json +20 -15
- package/{shared/FileRoutes.tsx → router/FileRoutes.ts} +1 -1
- package/router/index.ts +1 -0
- package/{shared/lazyRoute.tsx → router/lazyRoute.ts} +0 -2
- package/{shared → router}/routes.ts +1 -1
- package/server/fetchEvent.ts +16 -16
- package/server/handler.ts +7 -8
- package/server/{index.tsx → index.ts} +1 -3
- package/server/pageEvent.ts +3 -3
- package/server/serverFunction.tsx +6 -0
- package/server/spa/{index.tsx → index.ts} +0 -2
- package/server/types.ts +6 -3
- package/shared/dev-overlay/CodeView.tsx +6 -2
- package/shared/{index.tsx → index.ts} +0 -3
- /package/client/{islands.tsx → islands.ts} +0 -0
- /package/client/spa/{index.tsx → index.ts} +0 -0
package/config/index.d.ts
CHANGED
|
@@ -1,19 +1,28 @@
|
|
|
1
1
|
import type { AppOptions } from "vinxi";
|
|
2
2
|
import type { CustomizableConfig } from "vinxi/dist/types/lib/vite-dev";
|
|
3
|
+
import { InlineConfig } from "vite";
|
|
3
4
|
import type { Options } from "vite-plugin-solid";
|
|
4
5
|
|
|
6
|
+
// atleast until we sort which server options are good to use
|
|
7
|
+
type ViteCustomizableConfig = CustomizableConfig & {
|
|
8
|
+
server?: InlineConfig["server"];
|
|
9
|
+
}
|
|
10
|
+
|
|
5
11
|
type SolidStartInlineConfig = {
|
|
6
12
|
ssr?: boolean;
|
|
7
13
|
solid?: Options;
|
|
8
14
|
extensions?: string[];
|
|
9
15
|
server?: AppOptions["server"];
|
|
10
16
|
appRoot?: string;
|
|
17
|
+
routeDir?: string;
|
|
11
18
|
middleware?: string;
|
|
12
|
-
islands?: boolean;
|
|
13
19
|
devOverlay?: boolean;
|
|
20
|
+
experimental?: {
|
|
21
|
+
islands?: boolean;
|
|
22
|
+
}
|
|
14
23
|
vite?:
|
|
15
|
-
|
|
|
16
|
-
| ((options: { router: "server" | "client" | "server-function" }) =>
|
|
24
|
+
| ViteCustomizableConfig
|
|
25
|
+
| ((options: { router: "server" | "client" | "server-function" }) => ViteCustomizableConfig);
|
|
17
26
|
};
|
|
18
27
|
|
|
19
28
|
export declare function defineConfig(baseConfig?: SolidStartInlineConfig): any;
|
package/config/index.js
CHANGED
|
@@ -42,9 +42,12 @@ export function defineConfig(baseConfig = {}) {
|
|
|
42
42
|
const extensions = [...DEFAULT_EXTENSIONS, ...(start.extensions || [])];
|
|
43
43
|
start = defu(start, {
|
|
44
44
|
appRoot: "./src",
|
|
45
|
+
routeDir: "./routes",
|
|
45
46
|
ssr: true,
|
|
46
47
|
devOverlay: true,
|
|
47
|
-
|
|
48
|
+
experimental: {
|
|
49
|
+
islands: false
|
|
50
|
+
},
|
|
48
51
|
solid: {},
|
|
49
52
|
server: {
|
|
50
53
|
experimental: {
|
|
@@ -52,6 +55,7 @@ export function defineConfig(baseConfig = {}) {
|
|
|
52
55
|
}
|
|
53
56
|
}
|
|
54
57
|
});
|
|
58
|
+
const routeDir = join(start.appRoot, start.routeDir);
|
|
55
59
|
let server = start.server;
|
|
56
60
|
if (!start.ssr) {
|
|
57
61
|
server = { ...server, prerender: { routes: ["/"] } };
|
|
@@ -79,11 +83,11 @@ export function defineConfig(baseConfig = {}) {
|
|
|
79
83
|
name: "ssr",
|
|
80
84
|
type: "http",
|
|
81
85
|
link: {
|
|
82
|
-
client: start.islands ? undefined : "client"
|
|
86
|
+
client: start.experimental.islands ? undefined : "client"
|
|
83
87
|
},
|
|
84
88
|
handler: `${start.appRoot}/entry-server${entryExtension}`,
|
|
85
89
|
middleware: start.middleware,
|
|
86
|
-
routes: solidStartServerFsRouter({ dir:
|
|
90
|
+
routes: solidStartServerFsRouter({ dir: routeDir, extensions }),
|
|
87
91
|
extensions,
|
|
88
92
|
target: "server",
|
|
89
93
|
plugins: async () => {
|
|
@@ -106,7 +110,7 @@ export function defineConfig(baseConfig = {}) {
|
|
|
106
110
|
serverTransform({
|
|
107
111
|
runtime: normalize(fileURLToPath(new URL("./server-fns-runtime.ts", import.meta.url)))
|
|
108
112
|
}),
|
|
109
|
-
start.islands ? serverComponents.server() : null,
|
|
113
|
+
start.experimental.islands ? serverComponents.server() : null,
|
|
110
114
|
solid({ ...start.solid, ssr: true, extensions: extensions.map(ext => `.${ext}`) }),
|
|
111
115
|
config("app-server", {
|
|
112
116
|
resolve: {
|
|
@@ -123,7 +127,7 @@ export function defineConfig(baseConfig = {}) {
|
|
|
123
127
|
},
|
|
124
128
|
cacheDir: "node_modules/.vinxi/server",
|
|
125
129
|
define: {
|
|
126
|
-
"import.meta.env.START_ISLANDS": JSON.stringify(start.islands),
|
|
130
|
+
"import.meta.env.START_ISLANDS": JSON.stringify(start.experimental.islands),
|
|
127
131
|
"import.meta.env.SSR": JSON.stringify(true),
|
|
128
132
|
"import.meta.env.START_SSR": JSON.stringify(start.ssr),
|
|
129
133
|
"import.meta.env.START_DEV_OVERLAY": JSON.stringify(start.devOverlay),
|
|
@@ -138,10 +142,10 @@ export function defineConfig(baseConfig = {}) {
|
|
|
138
142
|
type: "client",
|
|
139
143
|
base: "/_build",
|
|
140
144
|
handler: `${start.appRoot}/entry-client${entryExtension}`,
|
|
141
|
-
...(start.islands
|
|
145
|
+
...(start.experimental.islands
|
|
142
146
|
? {}
|
|
143
147
|
: {
|
|
144
|
-
routes: solidStartClientFsRouter({ dir:
|
|
148
|
+
routes: solidStartClientFsRouter({ dir: routeDir, extensions })
|
|
145
149
|
}),
|
|
146
150
|
extensions,
|
|
147
151
|
target: "browser",
|
|
@@ -165,14 +169,14 @@ export function defineConfig(baseConfig = {}) {
|
|
|
165
169
|
serverFunctions.client({
|
|
166
170
|
runtime: normalize(fileURLToPath(new URL("./server-runtime.ts", import.meta.url)))
|
|
167
171
|
}),
|
|
168
|
-
start.islands ? serverComponents.client() : null,
|
|
172
|
+
start.experimental.islands ? serverComponents.client() : null,
|
|
169
173
|
solid({ ...start.solid, ssr: start.ssr, extensions: extensions.map(ext => `.${ext}`) }),
|
|
170
174
|
config("app-client", {
|
|
171
175
|
resolve: {
|
|
172
176
|
alias: {
|
|
173
177
|
"#start/app": join(process.cwd(), start.appRoot, `app${entryExtension}`),
|
|
174
178
|
"~": join(process.cwd(), start.appRoot),
|
|
175
|
-
...(start.islands
|
|
179
|
+
...(start.experimental.islands
|
|
176
180
|
? {
|
|
177
181
|
"@solidjs/start/client": "@solidjs/start/client/islands"
|
|
178
182
|
}
|
|
@@ -187,7 +191,7 @@ export function defineConfig(baseConfig = {}) {
|
|
|
187
191
|
},
|
|
188
192
|
cacheDir: "node_modules/.vinxi/client",
|
|
189
193
|
define: {
|
|
190
|
-
"import.meta.env.START_ISLANDS": JSON.stringify(start.islands),
|
|
194
|
+
"import.meta.env.START_ISLANDS": JSON.stringify(start.experimental.islands),
|
|
191
195
|
"import.meta.env.SSR": JSON.stringify(false),
|
|
192
196
|
"import.meta.env.START_SSR": JSON.stringify(start.ssr),
|
|
193
197
|
"import.meta.env.START_DEV_OVERLAY": JSON.stringify(start.devOverlay),
|
|
@@ -206,7 +210,7 @@ export function defineConfig(baseConfig = {}) {
|
|
|
206
210
|
handler: normalize(fileURLToPath(new URL("./server-handler.ts", import.meta.url))),
|
|
207
211
|
middleware: start.middleware,
|
|
208
212
|
target: "server",
|
|
209
|
-
routes: solidStartServerFsRouter({ dir:
|
|
213
|
+
routes: solidStartServerFsRouter({ dir: routeDir, extensions }),
|
|
210
214
|
plugins: async () => {
|
|
211
215
|
const userConfig = typeof vite === "function" ? await vite({ router: "server-function" }) : { ...vite };
|
|
212
216
|
const plugins = userConfig.plugins || [];
|
|
@@ -243,7 +247,7 @@ export function defineConfig(baseConfig = {}) {
|
|
|
243
247
|
}
|
|
244
248
|
},
|
|
245
249
|
define: {
|
|
246
|
-
"import.meta.env.START_ISLANDS": JSON.stringify(start.islands),
|
|
250
|
+
"import.meta.env.START_ISLANDS": JSON.stringify(start.experimental.islands),
|
|
247
251
|
"import.meta.env.SSR": JSON.stringify(true),
|
|
248
252
|
"import.meta.env.START_SSR": JSON.stringify(start.ssr),
|
|
249
253
|
"import.meta.env.START_DEV_OVERLAY": JSON.stringify(start.devOverlay),
|
|
@@ -20,7 +20,7 @@ function client() {
|
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
function server() {
|
|
23
|
-
const runtime = normalize(fileURLToPath(new URL("./server-runtime.
|
|
23
|
+
const runtime = normalize(fileURLToPath(new URL("./server-runtime.ts", import.meta.url)));
|
|
24
24
|
// export function serverComponents({
|
|
25
25
|
// resolve = {
|
|
26
26
|
// conditions: ["react-server"],
|
|
@@ -16,6 +16,9 @@ export function createServerReference(fn: Function, id: string, name: string) {
|
|
|
16
16
|
const ogEvt = getRequestEvent();
|
|
17
17
|
if (!ogEvt) throw new Error("Cannot call server function outside of a request");
|
|
18
18
|
const evt = cloneEvent(ogEvt);
|
|
19
|
+
evt.locals.serverFunctionMeta = {
|
|
20
|
+
id: id + "#" + name,
|
|
21
|
+
};
|
|
19
22
|
evt.serverOnly = true;
|
|
20
23
|
return provideRequestEvent(evt, () => {
|
|
21
24
|
return fn.apply(thisArg, args);
|
package/config/server-handler.ts
CHANGED
|
@@ -16,12 +16,11 @@ import {
|
|
|
16
16
|
import { sharedConfig } from "solid-js";
|
|
17
17
|
import { renderToString } from "solid-js/web";
|
|
18
18
|
import { provideRequestEvent } from "solid-js/web/storage";
|
|
19
|
-
import { eventHandler, setHeader, setResponseStatus, type
|
|
19
|
+
import { eventHandler, setHeader, setResponseStatus, type HTTPEvent } from "vinxi/http";
|
|
20
20
|
import invariant from "vinxi/lib/invariant";
|
|
21
21
|
import { cloneEvent, getFetchEvent, mergeResponseHeaders } from "../server/fetchEvent";
|
|
22
22
|
import { createPageEvent } from "../server/pageEvent";
|
|
23
23
|
// @ts-ignore
|
|
24
|
-
import App from "#start/app";
|
|
25
24
|
import { FetchEvent, PageEvent } from "../server";
|
|
26
25
|
|
|
27
26
|
function createChunk(data: string) {
|
|
@@ -64,7 +63,7 @@ function serializeToStream(id: string, value: any) {
|
|
|
64
63
|
});
|
|
65
64
|
}
|
|
66
65
|
|
|
67
|
-
async function handleServerFunction(h3Event:
|
|
66
|
+
async function handleServerFunction(h3Event: HTTPEvent) {
|
|
68
67
|
const event = getFetchEvent(h3Event);
|
|
69
68
|
const request = event.request;
|
|
70
69
|
|
|
@@ -72,7 +71,7 @@ async function handleServerFunction(h3Event: H3Event) {
|
|
|
72
71
|
const instance = request.headers.get("X-Server-Instance");
|
|
73
72
|
const singleFlight = request.headers.has("X-Single-Flight");
|
|
74
73
|
const url = new URL(request.url);
|
|
75
|
-
let filepath, name;
|
|
74
|
+
let filepath: string | undefined | null, name: string | undefined | null;
|
|
76
75
|
if (serverReference) {
|
|
77
76
|
invariant(typeof serverReference === "string", "Invalid server function");
|
|
78
77
|
[filepath, name] = serverReference.split("#");
|
|
@@ -131,6 +130,9 @@ async function handleServerFunction(h3Event: H3Event) {
|
|
|
131
130
|
let result = await provideRequestEvent(event, async () => {
|
|
132
131
|
/* @ts-ignore */
|
|
133
132
|
sharedConfig.context = { event };
|
|
133
|
+
event.locals.serverFunctionMeta = {
|
|
134
|
+
id: filepath + "#" + name,
|
|
135
|
+
};
|
|
134
136
|
return serverFunction(...parsed);
|
|
135
137
|
});
|
|
136
138
|
|
|
@@ -142,6 +144,8 @@ async function handleServerFunction(h3Event: H3Event) {
|
|
|
142
144
|
if (result instanceof Response && instance) {
|
|
143
145
|
// forward headers
|
|
144
146
|
if (result.headers) mergeResponseHeaders(h3Event, result.headers);
|
|
147
|
+
// forward non-redirect statuses
|
|
148
|
+
if (result.status && (result.status < 300 || result.status >= 400)) setResponseStatus(h3Event, result.status);
|
|
145
149
|
if ((result as any).customBody) {
|
|
146
150
|
result = await (result as any).customBody();
|
|
147
151
|
} else if (result.body == undefined) result = null;
|
|
@@ -181,21 +185,26 @@ async function handleServerFunction(h3Event: H3Event) {
|
|
|
181
185
|
if (singleFlight && instance) {
|
|
182
186
|
x = await handleSingleFlight(event, x);
|
|
183
187
|
}
|
|
184
|
-
if ((x as any).status === 302 && !instance) setResponseStatus(h3Event, 302);
|
|
185
188
|
// forward headers
|
|
186
189
|
if ((x as any).headers) mergeResponseHeaders(h3Event, (x as any).headers);
|
|
190
|
+
// forward non-redirect statuses
|
|
191
|
+
if ((x as any).status && (!instance || (x as any).status < 300 || (x as any).status >= 400)) setResponseStatus(h3Event, (x as any).status);
|
|
187
192
|
if ((x as any).customBody) {
|
|
188
193
|
x = (x as any).customBody();
|
|
189
194
|
} else if ((x as any).body == undefined) x = null;
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
195
|
+
} else {
|
|
196
|
+
const error = x instanceof Error ? x.message : typeof x === "string" ? x : "true";
|
|
197
|
+
setHeader(h3Event, "X-Error", error);
|
|
198
|
+
}
|
|
199
|
+
if (instance) {
|
|
200
|
+
setHeader(h3Event, "content-type", "text/javascript");
|
|
201
|
+
return serializeToStream(instance, x);
|
|
194
202
|
}
|
|
195
203
|
return x;
|
|
196
204
|
}
|
|
197
205
|
}
|
|
198
206
|
|
|
207
|
+
let App: any;
|
|
199
208
|
async function handleSingleFlight(sourceEvent: FetchEvent, result: any): Promise<Response> {
|
|
200
209
|
let revalidate: string[];
|
|
201
210
|
let url = new URL(sourceEvent.request.headers.get("referer")!).toString();
|
|
@@ -213,6 +222,8 @@ async function handleSingleFlight(sourceEvent: FetchEvent, result: any): Promise
|
|
|
213
222
|
return await provideRequestEvent(event, async () => {
|
|
214
223
|
await createPageEvent(event);
|
|
215
224
|
/* @ts-ignore */
|
|
225
|
+
App || (App = (await import("#start/app")).default);
|
|
226
|
+
/* @ts-ignore */
|
|
216
227
|
event.router.dataOnly = revalidate || true;
|
|
217
228
|
/* @ts-ignore */
|
|
218
229
|
event.router.previousUrl = sourceEvent.request.headers.get("referer");
|
package/config/server-runtime.ts
CHANGED
|
@@ -177,12 +177,12 @@ async function fetchServerFunction(
|
|
|
177
177
|
} else if (contentType && contentType.startsWith("application/json")) {
|
|
178
178
|
result = await response.json();
|
|
179
179
|
} else {
|
|
180
|
-
result = deserializeStream(instance, response);
|
|
180
|
+
result = await deserializeStream(instance, response);
|
|
181
181
|
}
|
|
182
|
-
if (response.
|
|
183
|
-
|
|
182
|
+
if (response.headers.has("X-Error")) {
|
|
183
|
+
throw result;
|
|
184
184
|
}
|
|
185
|
-
|
|
185
|
+
return result;
|
|
186
186
|
}
|
|
187
187
|
|
|
188
188
|
export function createServerReference(fn: Function, id: string, name: string) {
|
package/middleware/index.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
HTTPEvent,
|
|
3
|
+
defineMiddleware,
|
|
4
|
+
sendWebResponse
|
|
5
5
|
} from "vinxi/http";
|
|
6
6
|
import { getFetchEvent } from "../server/fetchEvent";
|
|
7
7
|
import type { FetchEvent } from "../server/types";
|
|
@@ -23,7 +23,7 @@ export type ResponseMiddleware = (
|
|
|
23
23
|
) => Response | Promise<Response> | void | Promise<void>;
|
|
24
24
|
|
|
25
25
|
function wrapRequestMiddleware(onRequest: RequestMiddleware) {
|
|
26
|
-
return async (h3Event:
|
|
26
|
+
return async (h3Event: HTTPEvent) => {
|
|
27
27
|
const fetchEvent = getFetchEvent(h3Event);
|
|
28
28
|
const response = await onRequest(fetchEvent);
|
|
29
29
|
if (!response) {
|
|
@@ -35,7 +35,7 @@ function wrapRequestMiddleware(onRequest: RequestMiddleware) {
|
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
function wrapResponseMiddleware(onBeforeResponse: ResponseMiddleware) {
|
|
38
|
-
return async (h3Event:
|
|
38
|
+
return async (h3Event: HTTPEvent, response: ResponseMiddlewareResponseParam) => {
|
|
39
39
|
const fetchEvent = getFetchEvent(h3Event);
|
|
40
40
|
const mwResponse = await onBeforeResponse(fetchEvent, response);
|
|
41
41
|
if (!mwResponse) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@solidjs/start",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"author": "Ryan Carniato",
|
|
6
6
|
"license": "MIT",
|
|
@@ -11,45 +11,50 @@
|
|
|
11
11
|
"client",
|
|
12
12
|
"config",
|
|
13
13
|
"middleware",
|
|
14
|
+
"router",
|
|
14
15
|
"server",
|
|
15
16
|
"shared",
|
|
16
17
|
"*.d.ts"
|
|
17
18
|
],
|
|
18
|
-
"types": "./shared/index.
|
|
19
|
+
"types": "./shared/index.ts",
|
|
19
20
|
"exports": {
|
|
20
|
-
".": "./shared/index.
|
|
21
|
+
".": "./shared/index.ts",
|
|
21
22
|
"./config": "./config/index.js",
|
|
22
23
|
"./middleware": "./middleware/index.ts",
|
|
23
|
-
"./
|
|
24
|
-
"./server
|
|
25
|
-
"./
|
|
26
|
-
"./client
|
|
27
|
-
"./client/
|
|
24
|
+
"./router": "./router/index.ts",
|
|
25
|
+
"./server": "./server/index.ts",
|
|
26
|
+
"./server/spa": "./server/spa/index.ts",
|
|
27
|
+
"./client": "./client/index.ts",
|
|
28
|
+
"./client/islands": "./client/islands.ts",
|
|
29
|
+
"./client/spa": "./client/spa/index.ts"
|
|
28
30
|
},
|
|
29
31
|
"typesVersions": {
|
|
30
32
|
"*": {
|
|
31
33
|
".": [
|
|
32
|
-
"./shared/index.
|
|
34
|
+
"./shared/index.ts"
|
|
33
35
|
],
|
|
34
36
|
"middleware": [
|
|
35
37
|
"./middleware/index.ts"
|
|
36
38
|
],
|
|
39
|
+
"router": [
|
|
40
|
+
"./router/index.ts"
|
|
41
|
+
],
|
|
37
42
|
"server": [
|
|
38
|
-
"./server/index.
|
|
43
|
+
"./server/index.ts"
|
|
39
44
|
],
|
|
40
45
|
"client": [
|
|
41
|
-
"./client/index.
|
|
46
|
+
"./client/index.ts"
|
|
42
47
|
]
|
|
43
48
|
}
|
|
44
49
|
},
|
|
45
50
|
"devDependencies": {
|
|
46
51
|
"solid-js": "^1.8.15",
|
|
47
|
-
"vinxi": "^0.3.
|
|
52
|
+
"vinxi": "^0.3.10"
|
|
48
53
|
},
|
|
49
54
|
"dependencies": {
|
|
50
|
-
"@vinxi/plugin-directives": "^0.3.
|
|
51
|
-
"@vinxi/server-components": "^0.3.
|
|
52
|
-
"@vinxi/server-functions": "^0.3.
|
|
55
|
+
"@vinxi/plugin-directives": "^0.3.1",
|
|
56
|
+
"@vinxi/server-components": "^0.3.3",
|
|
57
|
+
"@vinxi/server-functions": "^0.3.2",
|
|
53
58
|
"defu": "^6.1.2",
|
|
54
59
|
"error-stack-parser": "^2.1.4",
|
|
55
60
|
"html-to-image": "^1.11.11",
|
package/router/index.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { FileRoutes } from "./FileRoutes";
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
// @refresh skip
|
|
2
|
-
// TODO rename to lazyRoute.ts?
|
|
3
1
|
/// <reference types="vinxi/types/client" />
|
|
4
2
|
import { createComponent, lazy, onCleanup, type Component, type JSX } from "solid-js";
|
|
5
3
|
import { appendStyles, cleanupStyles, preloadStyles, updateStyles } from "vinxi/css";
|
|
@@ -33,7 +33,7 @@ function defineRoutes(fileRoutes: Route[]) {
|
|
|
33
33
|
});
|
|
34
34
|
|
|
35
35
|
if (!parentRoute) {
|
|
36
|
-
routes.push({ ...route, id, path: id.replace(/\/\([^)/]+\)/g, "") });
|
|
36
|
+
routes.push({ ...route, id, path: id.replace(/\/\([^)/]+\)/g, "").replace(/\./g, "/") });
|
|
37
37
|
return routes;
|
|
38
38
|
}
|
|
39
39
|
processRoute(
|
package/server/fetchEvent.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
2
|
H3Event,
|
|
3
|
-
HTTPEventSymbol,
|
|
4
3
|
appendResponseHeader,
|
|
5
4
|
getRequestIP,
|
|
6
5
|
getResponseHeader,
|
|
@@ -11,7 +10,7 @@ import {
|
|
|
11
10
|
removeResponseHeader,
|
|
12
11
|
setHeader,
|
|
13
12
|
setResponseHeader,
|
|
14
|
-
setResponseStatus
|
|
13
|
+
setResponseStatus
|
|
15
14
|
} from "vinxi/http";
|
|
16
15
|
import type { FetchEvent, ResponseStub } from "./types";
|
|
17
16
|
|
|
@@ -23,15 +22,13 @@ export function createFetchEvent(event: H3Event): FetchEvent {
|
|
|
23
22
|
response: createResponseStub(event),
|
|
24
23
|
clientAddress: getRequestIP(event),
|
|
25
24
|
locals: {},
|
|
26
|
-
nativeEvent: event
|
|
27
|
-
[HTTPEventSymbol]: event
|
|
25
|
+
nativeEvent: event
|
|
28
26
|
};
|
|
29
27
|
}
|
|
30
28
|
|
|
31
29
|
export function cloneEvent<T extends FetchEvent>(fetchEvent: T): T {
|
|
32
30
|
return {
|
|
33
|
-
...fetchEvent
|
|
34
|
-
[HTTPEventSymbol]: fetchEvent[HTTPEventSymbol]
|
|
31
|
+
...fetchEvent
|
|
35
32
|
};
|
|
36
33
|
}
|
|
37
34
|
|
|
@@ -54,7 +51,7 @@ class HeaderProxy {
|
|
|
54
51
|
constructor(private event: H3Event) {}
|
|
55
52
|
get(key: string) {
|
|
56
53
|
const h = getResponseHeader(this.event, key);
|
|
57
|
-
return Array.isArray(h) ? h.join(", ") : h;
|
|
54
|
+
return Array.isArray(h) ? h.join(", ") : (h as string) || null;
|
|
58
55
|
}
|
|
59
56
|
has(key: string) {
|
|
60
57
|
return this.get(key) !== undefined;
|
|
@@ -70,24 +67,27 @@ class HeaderProxy {
|
|
|
70
67
|
}
|
|
71
68
|
getSetCookie() {
|
|
72
69
|
const cookies = getResponseHeader(this.event, "Set-Cookie");
|
|
73
|
-
return Array.isArray(cookies) ? cookies : [cookies];
|
|
70
|
+
return Array.isArray(cookies) ? cookies : [cookies as string];
|
|
74
71
|
}
|
|
75
72
|
forEach(fn: (value: string, key: string, object: Headers) => void) {
|
|
76
|
-
return Object.entries
|
|
73
|
+
return Object.entries(getResponseHeaders(this.event)).forEach(([key, value]) =>
|
|
74
|
+
fn(Array.isArray(value) ? value.join(", ") : (value as string), key, this)
|
|
75
|
+
);
|
|
77
76
|
}
|
|
78
77
|
entries() {
|
|
79
|
-
return Object.entries
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
78
|
+
return Object.entries(getResponseHeaders(this.event))
|
|
79
|
+
.map(
|
|
80
|
+
([key, value]) => [key, Array.isArray(value) ? value.join(", ") : value] as [string, string]
|
|
81
|
+
)
|
|
82
|
+
[Symbol.iterator]();
|
|
83
83
|
}
|
|
84
84
|
keys() {
|
|
85
85
|
return Object.keys(getResponseHeaders(this.event))[Symbol.iterator]();
|
|
86
86
|
}
|
|
87
87
|
values() {
|
|
88
|
-
return Object.values
|
|
89
|
-
Array.isArray(value) ? value.join(", ") : value
|
|
90
|
-
|
|
88
|
+
return Object.values(getResponseHeaders(this.event))
|
|
89
|
+
.map(value => (Array.isArray(value) ? value.join(", ") : (value as string)))
|
|
90
|
+
[Symbol.iterator]();
|
|
91
91
|
}
|
|
92
92
|
[Symbol.iterator]() {
|
|
93
93
|
return this.entries()[Symbol.iterator]();
|
package/server/handler.ts
CHANGED
|
@@ -2,14 +2,13 @@ import { sharedConfig } from "solid-js";
|
|
|
2
2
|
import { renderToStream, renderToString } from "solid-js/web";
|
|
3
3
|
import { provideRequestEvent } from "solid-js/web/storage";
|
|
4
4
|
import {
|
|
5
|
-
EventHandlerRequest,
|
|
6
|
-
H3Event,
|
|
7
5
|
eventHandler,
|
|
8
6
|
sendRedirect,
|
|
9
7
|
setHeader,
|
|
10
|
-
setResponseStatus
|
|
8
|
+
setResponseStatus,
|
|
9
|
+
type HTTPEvent
|
|
11
10
|
} from "vinxi/http";
|
|
12
|
-
import { matchAPIRoute } from "../
|
|
11
|
+
import { matchAPIRoute } from "../router/routes";
|
|
13
12
|
import { getFetchEvent } from "./fetchEvent";
|
|
14
13
|
import { createPageEvent } from "./pageEvent";
|
|
15
14
|
import type { APIEvent, FetchEvent, HandlerOptions, PageEvent } from "./types";
|
|
@@ -20,7 +19,7 @@ export function createBaseHandler(
|
|
|
20
19
|
options: HandlerOptions | ((context: PageEvent) => HandlerOptions | Promise<HandlerOptions>) = {}
|
|
21
20
|
) {
|
|
22
21
|
return eventHandler({
|
|
23
|
-
handler: (e:
|
|
22
|
+
handler: (e: HTTPEvent) => {
|
|
24
23
|
const event = getFetchEvent(e);
|
|
25
24
|
|
|
26
25
|
return provideRequestEvent(event, async () => {
|
|
@@ -53,7 +52,7 @@ export function createBaseHandler(
|
|
|
53
52
|
return fn(context);
|
|
54
53
|
}, options);
|
|
55
54
|
if (context.response && context.response.headers.get("Location")) {
|
|
56
|
-
return sendRedirect(
|
|
55
|
+
return sendRedirect(e, context.response.headers.get("Location")!);
|
|
57
56
|
}
|
|
58
57
|
return html;
|
|
59
58
|
}
|
|
@@ -77,7 +76,7 @@ export function createBaseHandler(
|
|
|
77
76
|
return fn(context);
|
|
78
77
|
}, cloned);
|
|
79
78
|
if (context.response && context.response.headers.get("Location")) {
|
|
80
|
-
return sendRedirect(
|
|
79
|
+
return sendRedirect(e, context.response.headers.get("Location")!);
|
|
81
80
|
}
|
|
82
81
|
if (mode === "async") return stream;
|
|
83
82
|
// fix cloudflare streaming
|
|
@@ -89,7 +88,7 @@ export function createBaseHandler(
|
|
|
89
88
|
});
|
|
90
89
|
}
|
|
91
90
|
|
|
92
|
-
function handleShellCompleteRedirect(context: PageEvent, e:
|
|
91
|
+
function handleShellCompleteRedirect(context: PageEvent, e: HTTPEvent) {
|
|
93
92
|
return () => {
|
|
94
93
|
if (context.response && context.response.headers.get("Location")) {
|
|
95
94
|
setResponseStatus(e, 302);
|
package/server/pageEvent.ts
CHANGED
|
@@ -2,16 +2,16 @@ import {
|
|
|
2
2
|
getCookie,
|
|
3
3
|
setCookie
|
|
4
4
|
} from "vinxi/http";
|
|
5
|
-
import { createRoutes } from "../
|
|
5
|
+
import { createRoutes } from "../router/FileRoutes";
|
|
6
6
|
import { FetchEvent, PageEvent } from "./types";
|
|
7
7
|
|
|
8
8
|
function initFromFlash(ctx: FetchEvent) {
|
|
9
|
-
const flash = getCookie(ctx, "flash");
|
|
9
|
+
const flash = getCookie(ctx.nativeEvent, "flash");
|
|
10
10
|
if (!flash) return;
|
|
11
11
|
let param = JSON.parse(flash);
|
|
12
12
|
if (!param || !param.result) return;
|
|
13
13
|
const input = [...param.input.slice(0, -1), new Map(param.input[param.input.length - 1])];
|
|
14
|
-
setCookie(ctx, "flash", "", { maxAge: 0 });
|
|
14
|
+
setCookie(ctx.nativeEvent, "flash", "", { maxAge: 0 });
|
|
15
15
|
return {
|
|
16
16
|
input,
|
|
17
17
|
url: param.url,
|
package/server/types.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { JSX } from "solid-js";
|
|
2
2
|
import { RequestEvent } from "solid-js/web";
|
|
3
|
-
import {
|
|
3
|
+
import { HTTPEvent } from "vinxi/http";
|
|
4
4
|
|
|
5
5
|
// export const FETCH_EVENT = "$FETCH";
|
|
6
6
|
|
|
@@ -47,8 +47,7 @@ export interface FetchEvent {
|
|
|
47
47
|
response: ResponseStub;
|
|
48
48
|
clientAddress?: string;
|
|
49
49
|
locals: RequestEventLocals;
|
|
50
|
-
nativeEvent:
|
|
51
|
-
[HTTPEventSymbol]: H3Event;
|
|
50
|
+
nativeEvent: HTTPEvent;
|
|
52
51
|
}
|
|
53
52
|
export interface RequestEventLocals {
|
|
54
53
|
[key: string | symbol]: any;
|
|
@@ -71,6 +70,10 @@ export interface APIHandler {
|
|
|
71
70
|
(event: APIEvent): Promise<any>;
|
|
72
71
|
}
|
|
73
72
|
|
|
73
|
+
export interface ServerFunctionMeta {
|
|
74
|
+
id: string;
|
|
75
|
+
}
|
|
76
|
+
|
|
74
77
|
declare module "solid-js/web" {
|
|
75
78
|
interface RequestEvent extends FetchEvent {
|
|
76
79
|
serverOnly?: boolean;
|
|
@@ -58,11 +58,15 @@ export function CodeView(props: CodeViewProps): JSX.Element | null {
|
|
|
58
58
|
.join('\n')
|
|
59
59
|
) ,async (value) => {
|
|
60
60
|
const highlighter = await loadHighlighter();
|
|
61
|
-
const
|
|
61
|
+
const fileExtension = props.fileName
|
|
62
62
|
.split(/[#?]/)[0]!
|
|
63
63
|
.split('.')
|
|
64
64
|
.pop()
|
|
65
|
-
?.trim()
|
|
65
|
+
?.trim();
|
|
66
|
+
let lang = fileExtension as BuiltinLanguage;
|
|
67
|
+
if (fileExtension === 'mjs' || fileExtension === 'cjs') {
|
|
68
|
+
lang = 'js';
|
|
69
|
+
}
|
|
66
70
|
return highlighter.codeToHtml(value, {
|
|
67
71
|
theme: 'dark-plus',
|
|
68
72
|
lang,
|
|
File without changes
|
|
File without changes
|