@@ -12,7 +12,12 @@ import {
1212 serializeToJSONStream ,
1313 serializeToJSStream ,
1414} from "./serialization.ts" ;
15- import { BODY_FORMAT_KEY , BodyFormat , extractBody , getHeadersAndBody } from "./server-functions-shared.ts" ;
15+ import {
16+ BODY_FORMAT_KEY ,
17+ BodyFormat ,
18+ extractBody ,
19+ getHeadersAndBody ,
20+ } from "./server-functions-shared.ts" ;
1621import type { FetchEvent , PageEvent } from "./types.ts" ;
1722import { getExpectedRedirectStatus } from "./util.ts" ;
1823
@@ -52,8 +57,14 @@ export async function handleServerFunction(h3Event: H3Event) {
5257 }
5358 }
5459 }
55- if ( request . method === "POST" ) {
56- parsed . push ( await extractBody ( '' , false , request . clone ( ) ) ) ;
60+ if ( request . method === "POST" && request . body !== null ) {
61+ const bodyFormat = request . headers . get ( BODY_FORMAT_KEY ) ;
62+ const decoded = await extractBody ( "" , false , request . clone ( ) ) ;
63+ if ( bodyFormat === BodyFormat . Seroval ) {
64+ parsed = decoded as any [ ] ;
65+ } else {
66+ parsed . push ( decoded ) ;
67+ }
5768 }
5869 try {
5970 let result = await provideRequestEvent ( event , async ( ) => {
@@ -87,18 +98,19 @@ export async function handleServerFunction(h3Event: H3Event) {
8798 // handle no JS success case
8899 if ( ! instance ) return handleNoJS ( result , request , parsed ) ;
89100
90- const body = getHeadersAndBody ( result ) ;
91- if ( body ) {
92- return new Response ( body . body , {
93- headers : body . headers ,
94- } ) ;
95- }
96- h3Event . res . headers . set ( BODY_FORMAT_KEY , BodyFormat . Seroval ) ;
97- if ( import . meta. env . SEROVAL_MODE === "js" ) {
98- h3Event . res . headers . set ( "content-type" , "text/javascript" ) ;
99- return serializeToJSStream ( instance , result ) ;
100- }
101- return serializeToJSONStream ( result ) ;
101+ const body = getHeadersAndBody ( result ) ;
102+ if ( body ) {
103+ return new Response ( body . body , {
104+ headers : body . headers ,
105+ } ) ;
106+ }
107+ h3Event . res . headers . set ( BODY_FORMAT_KEY , BodyFormat . Seroval ) ;
108+ if ( import . meta. env . SEROVAL_MODE === "js" ) {
109+ h3Event . res . headers . set ( "content-type" , "text/javascript" ) ;
110+ return serializeToJSStream ( instance , result ) ;
111+ }
112+ h3Event . res . headers . set ( "content-type" , "text/plain" ) ;
113+ return serializeToJSONStream ( result ) ;
102114 } catch ( x ) {
103115 if ( x instanceof Response ) {
104116 if ( singleFlight && instance ) {
@@ -107,18 +119,14 @@ export async function handleServerFunction(h3Event: H3Event) {
107119 // forward headers
108120 if ( ( x as any ) . headers ) mergeResponseHeaders ( h3Event , ( x as any ) . headers ) ;
109121 // forward non-redirect statuses
110- if (
111- ( x as any ) . status &&
112- ( ! instance || ( x as any ) . status < 300 || ( x as any ) . status >= 400 )
113- )
122+ if ( ( x as any ) . status && ( ! instance || ( x as any ) . status < 300 || ( x as any ) . status >= 400 ) )
114123 h3Event . res . status = ( x as any ) . status ;
115124 if ( ( x as any ) . customBody ) {
116- x = ( x as any ) . customBody ( ) ;
117- } else if ( ( x as any ) . body === undefined ) x = null ;
125+ x = await ( x as any ) . customBody ( ) ;
126+ } else if ( ( x as any ) . body == null ) x = null ;
118127 h3Event . res . headers . set ( "X-Error" , "true" ) ;
119128 } else if ( instance ) {
120- const error =
121- x instanceof Error ? x . message : typeof x === "string" ? x : "true" ;
129+ const error = x instanceof Error ? x . message : typeof x === "string" ? x : "true" ;
122130
123131 h3Event . res . headers . set ( "X-Error" , error . replace ( / [ \r \n ] + / g, "" ) ) ;
124132 } else {
@@ -127,6 +135,11 @@ export async function handleServerFunction(h3Event: H3Event) {
127135 if ( instance ) {
128136 const body = getHeadersAndBody ( x ) ;
129137 if ( body ) {
138+ const headers = new Headers ( body . headers as HeadersInit ) ;
139+ const errorHeader = h3Event . res . headers . get ( "X-Error" ) ;
140+ if ( errorHeader !== null ) {
141+ headers . set ( "X-Error" , errorHeader ) ;
142+ }
130143 return new Response ( body . body , {
131144 headers : body . headers ,
132145 } ) ;
@@ -136,18 +149,14 @@ export async function handleServerFunction(h3Event: H3Event) {
136149 h3Event . res . headers . set ( "content-type" , "text/javascript" ) ;
137150 return serializeToJSStream ( instance , x ) ;
138151 }
152+ h3Event . res . headers . set ( "content-type" , "text/plain" ) ;
139153 return serializeToJSONStream ( x ) ;
140154 }
141155 return x ;
142156 }
143157}
144158
145- function handleNoJS (
146- result : any ,
147- request : Request ,
148- parsed : any [ ] ,
149- thrown ?: boolean ,
150- ) {
159+ function handleNoJS ( result : any , request : Request , parsed : any [ ] , thrown ?: boolean ) {
151160 const url = new URL ( request . url ) ;
152161 const isError = result instanceof Error ;
153162 let statusCode = 302 ;
@@ -157,10 +166,7 @@ function handleNoJS(
157166 if ( result . headers . has ( "Location" ) ) {
158167 headers . set (
159168 `Location` ,
160- new URL (
161- result . headers . get ( "Location" ) ! ,
162- url . origin + import . meta. env . BASE_URL ,
163- ) . toString ( ) ,
169+ new URL ( result . headers . get ( "Location" ) ! , url . origin + import . meta. env . BASE_URL ) . toString ( ) ,
164170 ) ;
165171 statusCode = getExpectedRedirectStatus ( result ) ;
166172 }
@@ -177,10 +183,7 @@ function handleNoJS(
177183 result : isError ? result . message : result ,
178184 thrown : thrown ,
179185 error : isError ,
180- input : [
181- ...parsed . slice ( 0 , - 1 ) ,
182- [ ...parsed [ parsed . length - 1 ] . entries ( ) ] ,
183- ] ,
186+ input : [ ...parsed . slice ( 0 , - 1 ) , [ ...parsed [ parsed . length - 1 ] . entries ( ) ] ] ,
184187 } ) ,
185188 ) } ; Secure; HttpOnly;`,
186189 ) ;
@@ -206,7 +209,7 @@ function createSingleFlightHeaders(sourceEvent: FetchEvent) {
206209 // useH3Internals = true;
207210 // sourceEvent.nativeEvent.node.req.headers.cookie = "";
208211 // }
209- SetCookies . forEach ( ( cookie ) => {
212+ SetCookies . forEach ( cookie => {
210213 if ( ! cookie ) return ;
211214 const { maxAge, expires, name, value } = parseSetCookie ( cookie ) ;
212215 if ( maxAge != null && maxAge <= 0 ) {
@@ -227,10 +230,7 @@ function createSingleFlightHeaders(sourceEvent: FetchEvent) {
227230
228231 return headers ;
229232}
230- async function handleSingleFlight (
231- sourceEvent : FetchEvent ,
232- result : any ,
233- ) : Promise < Response > {
233+ async function handleSingleFlight ( sourceEvent : FetchEvent , result : any ) : Promise < Response > {
234234 let revalidate : string [ ] ;
235235 let url = new URL ( sourceEvent . request . headers . get ( "referer" ) ! ) . toString ( ) ;
236236 if ( result instanceof Response ) {
0 commit comments