@@ -46,6 +46,7 @@ pub const Response = struct {
46
46
Response ,
47
47
.{
48
48
.@"constructor" = constructor ,
49
+ .@"json" = .{ .rfn = constructJSON },
49
50
},
50
51
.{},
51
52
);
@@ -219,18 +220,21 @@ pub const Response = struct {
219
220
return js .JSValueMakeBoolean (ctx , this .isOK ());
220
221
}
221
222
223
+ fn getOrCreateHeaders (this : * Response ) * Headers.RefCountedHeaders {
224
+ if (this .body .init .headers == null ) {
225
+ this .body .init .headers = Headers .RefCountedHeaders .init (Headers .empty (this .allocator ), this .allocator ) catch unreachable ;
226
+ }
227
+ return this .body .init .headers .? ;
228
+ }
229
+
222
230
pub fn getHeaders (
223
231
this : * Response ,
224
232
ctx : js.JSContextRef ,
225
233
_ : js.JSValueRef ,
226
234
_ : js.JSStringRef ,
227
235
_ : js.ExceptionRef ,
228
236
) js.JSValueRef {
229
- if (this .body .init .headers == null ) {
230
- this .body .init .headers = Headers .RefCountedHeaders .init (Headers .empty (getAllocator (ctx )), getAllocator (ctx )) catch unreachable ;
231
- }
232
-
233
- return Headers .Class .make (ctx , this .body .init .headers .? .getRef ());
237
+ return Headers .Class .make (ctx , this .getOrCreateHeaders ().getRef ());
234
238
}
235
239
236
240
pub fn doClone (
@@ -325,6 +329,73 @@ pub const Response = struct {
325
329
}
326
330
}
327
331
332
+ pub fn constructJSON (
333
+ _ : void ,
334
+ ctx : js.JSContextRef ,
335
+ _ : js.JSObjectRef ,
336
+ _ : js.JSObjectRef ,
337
+ arguments : []const js.JSValueRef ,
338
+ _ : js.ExceptionRef ,
339
+ ) js.JSObjectRef {
340
+ // https://github.com/remix-run/remix/blob/db2c31f64affb2095e4286b91306b96435967969/packages/remix-server-runtime/responses.ts#L4
341
+ var args = JSC .Node .ArgumentsSlice .from (arguments );
342
+ // var response = getAllocator(ctx).create(Response) catch unreachable;
343
+
344
+ var response = Response {
345
+ .body = Body {
346
+ .init = Body.Init {
347
+ .headers = null ,
348
+ .status_code = 200 ,
349
+ },
350
+ .value = Body .Value .empty ,
351
+ },
352
+ .allocator = getAllocator (ctx ),
353
+ .url = "" ,
354
+ };
355
+
356
+ const json_value = args .nextEat () orelse JSC .JSValue .zero ;
357
+
358
+ if (@enumToInt (json_value ) != 0 ) {
359
+ var zig_str = JSC .ZigString .init ("" );
360
+ // calling JSON.stringify on an empty string adds extra quotes
361
+ // so this is correct
362
+ json_value .jsonStringify (ctx .ptr (), 0 , & zig_str );
363
+
364
+ if (zig_str .len > 0 ) {
365
+ var zig_str_slice = zig_str .toSlice (getAllocator (ctx ));
366
+
367
+ if (zig_str_slice .allocated ) {
368
+ response .body .value = .{
369
+ .Blob = Blob .initWithAllASCII (zig_str_slice .mut (), zig_str_slice .allocator , ctx .ptr (), false ),
370
+ };
371
+ } else {
372
+ response .body .value = .{
373
+ .Blob = Blob .initWithAllASCII (getAllocator (ctx ).dupe (u8 , zig_str_slice .slice ()) catch unreachable , zig_str_slice .allocator , ctx .ptr (), true ),
374
+ };
375
+ }
376
+ }
377
+ }
378
+
379
+ if (args .nextEat ()) | init | {
380
+ if (init .isUndefinedOrNull ()) {} else if (init .isNumber ()) {
381
+ response .body .init .status_code = @intCast (u16 , @minimum (@maximum (0 , init .toInt32 ()), std .math .maxInt (u16 )));
382
+ } else {
383
+ if (Body .Init .init (getAllocator (ctx ), ctx , init .asObjectRef ()) catch null ) | _init | {
384
+ response .body .init = _init ;
385
+ if (response .body .init .status_code == 0 ) {
386
+ response .body .init .status_code = 200 ;
387
+ }
388
+ }
389
+ }
390
+ }
391
+
392
+ var headers_ref = response .getOrCreateHeaders ().leak ();
393
+ headers_ref .putHeaderNormalized ("content-type" , "application/json" , false );
394
+ var ptr = response .allocator .create (Response ) catch unreachable ;
395
+ ptr .* = response ;
396
+
397
+ return Response .Class .make (ctx , ptr );
398
+ }
328
399
pub fn constructor (
329
400
ctx : js.JSContextRef ,
330
401
_ : js.JSObjectRef ,
0 commit comments