diff options
-rw-r--r-- | src/global.zig | 4 | ||||
-rw-r--r-- | src/javascript/jsc/bindings/exports.zig | 180 | ||||
-rw-r--r-- | src/javascript/jsc/webcore/response.zig | 61 |
3 files changed, 203 insertions, 42 deletions
diff --git a/src/global.zig b/src/global.zig index e15034e92..e2e99bab8 100644 --- a/src/global.zig +++ b/src/global.zig @@ -89,3 +89,7 @@ pub inline fn constStrToU8(s: []const u8) []u8 { } pub const MAX_PATH_BYTES: usize = if (Environment.isWasm) 1024 else std.fs.MAX_PATH_BYTES; + +pub inline fn cast(comptime To: type, value: anytype) To { + return @ptrCast(To, @alignCast(@alignOf(To), value)); +} diff --git a/src/javascript/jsc/bindings/exports.zig b/src/javascript/jsc/bindings/exports.zig index daf3c0e65..e4c2a3be9 100644 --- a/src/javascript/jsc/bindings/exports.zig +++ b/src/javascript/jsc/bindings/exports.zig @@ -27,7 +27,7 @@ const JSModuleRecord = JSC.JSModuleRecord; const Microtask = JSC.Microtask; const JSPrivateDataPtr = @import("../base.zig").JSPrivateDataPtr; const Backtrace = @import("../../../deps/backtrace.zig"); - +const JSPrinter = @import("../../../js_printer.zig"); pub const ZigGlobalObject = extern struct { pub const shim = Shimmer("Zig", "GlobalObject", @This()); bytes: shim.Bytes, @@ -1005,6 +1005,7 @@ pub const ZigConsoleClient = struct { hide_native: bool = false, globalThis: *JSGlobalObject, indent: u32 = 0, + quote_strings: bool = false, pub const ZigFormatter = struct { formatter: *ZigConsoleClient.Formatter, @@ -1296,6 +1297,80 @@ pub const ZigConsoleClient = struct { } } + pub fn printComma(_: *ZigConsoleClient.Formatter, comptime Writer: type, writer: Writer, comptime enable_ansi_colors: bool) !void { + try writer.writeAll(comptime Output.prettyFmt("<r><d>,<r>", enable_ansi_colors)); + } + + pub fn MapIterator(comptime Writer: type, comptime enable_ansi_colors: bool) type { + return struct { + formatter: *ZigConsoleClient.Formatter, + writer: Writer, + pub fn forEach(_: [*c]JSC.VM, globalObject: [*c]JSGlobalObject, ctx: ?*anyopaque, nextValue: JSValue) callconv(.C) void { + var this: *@This() = bun.cast(*@This(), ctx orelse return); + const key = JSC.JSObject.getIndex(nextValue, globalObject, 0); + const value = JSC.JSObject.getIndex(nextValue, globalObject, 1); + this.formatter.writeIndent(Writer, this.writer) catch unreachable; + const key_tag = Tag.get(key, globalObject); + if (key_tag.tag == Tag.String) { + this.writer.writeAll("\"") catch unreachable; + } + this.formatter.format( + key_tag, + Writer, + this.writer, + key, + this.formatter.globalThis, + enable_ansi_colors, + ); + if (key_tag.tag == Tag.String) { + this.writer.writeAll("\": ") catch unreachable; + } else { + this.writer.writeAll(": ") catch unreachable; + } + const value_tag = Tag.get(value, globalObject); + if (value_tag.tag == Tag.String) { + this.writer.writeAll("\"") catch unreachable; + } + this.formatter.format( + value_tag, + Writer, + this.writer, + value, + this.formatter.globalThis, + enable_ansi_colors, + ); + if (value_tag.tag == Tag.String) { + this.writer.writeAll("\"") catch unreachable; + } + this.formatter.printComma(Writer, this.writer, enable_ansi_colors) catch unreachable; + this.writer.writeAll("\n") catch unreachable; + } + }; + } + + pub fn SetIterator(comptime Writer: type, comptime enable_ansi_colors: bool) type { + return struct { + formatter: *ZigConsoleClient.Formatter, + writer: Writer, + pub fn forEach(_: [*c]JSC.VM, globalObject: [*c]JSGlobalObject, ctx: ?*anyopaque, nextValue: JSValue) callconv(.C) void { + var this: *@This() = bun.cast(*@This(), ctx orelse return); + this.formatter.writeIndent(Writer, this.writer) catch {}; + const key_tag = Tag.get(nextValue, globalObject); + this.formatter.format( + key_tag, + Writer, + this.writer, + nextValue, + this.formatter.globalThis, + enable_ansi_colors, + ); + + this.formatter.printComma(Writer, this.writer, enable_ansi_colors) catch unreachable; + this.writer.writeAll("\n") catch unreachable; + } + }; + } + pub fn printAs( this: *ZigConsoleClient.Formatter, comptime Format: ZigConsoleClient.Formatter.Tag, @@ -1337,6 +1412,30 @@ pub const ZigConsoleClient = struct { .String => { var str = ZigString.init(""); value.toZigString(&str, this.globalThis); + + if (this.quote_strings and jsType != .RegExpObject) { + if (str.len == 0) { + writer.writeAll("\"\""); + return; + } + + if (comptime enable_ansi_colors) { + writer.writeAll(Output.prettyFmt("<r><green>", true)); + } + + defer if (comptime enable_ansi_colors) + writer.writeAll(Output.prettyFmt("<r>", true)); + + if (str.is16Bit()) { + this.printAs(.JSON, Writer, writer_, value, .StringObject, enable_ansi_colors); + return; + } + + JSPrinter.writeJSONString(str.slice(), Writer, writer_, false) catch unreachable; + + return; + } + if (jsType == .RegExpObject) { writer.print(comptime Output.prettyFmt("<r><red>", enable_ansi_colors), .{}); } @@ -1399,25 +1498,22 @@ pub const ZigConsoleClient = struct { writer.writeAll("[ "); var i: u32 = 0; var ref = value.asObjectRef(); + + var prev_quote_strings = this.quote_strings; + this.quote_strings = true; + defer this.quote_strings = prev_quote_strings; while (i < len) : (i += 1) { if (i > 0) { - writer.writeAll(", "); + this.printComma(Writer, writer_, enable_ansi_colors) catch unreachable; + writer.writeAll(" "); } const element = JSValue.fromRef(CAPI.JSObjectGetPropertyAtIndex(this.globalThis.ref(), ref, i, null)); const tag = Tag.get(element, this.globalThis); - if (tag.cell.isStringLike()) { - if (comptime enable_ansi_colors) { - writer.writeAll(comptime Output.prettyFmt("<r><green>", true)); - } - writer.writeAll("\""); - } - this.format(tag, Writer, writer_, element, this.globalThis, enable_ansi_colors); if (tag.cell.isStringLike()) { - writer.writeAll("\""); if (comptime enable_ansi_colors) { writer.writeAll(comptime Output.prettyFmt("<r>", true)); } @@ -1490,8 +1586,56 @@ pub const ZigConsoleClient = struct { .GlobalObject => { writer.writeAll(comptime Output.prettyFmt("<cyan>[this.globalThis]<r>", enable_ansi_colors)); }, - .Map => {}, - .Set => {}, + .Map => { + this.writeIndent(Writer, writer_) catch {}; + const length_value = value.get(this.globalThis, "size") orelse JSC.JSValue.jsNumberFromInt32(0); + const length = length_value.toInt32(); + + const prev_quote_strings = this.quote_strings; + this.quote_strings = true; + defer this.quote_strings = prev_quote_strings; + + if (length == 0) { + return writer.writeAll("Map {}"); + } + writer.print("Map({d}) {{\n", .{length}); + { + this.indent += 1; + defer this.indent -|= 1; + var iter = MapIterator(Writer, enable_ansi_colors){ + .formatter = this, + .writer = writer_, + }; + value.forEach(this.globalThis, &iter, @TypeOf(iter).forEach); + } + this.writeIndent(Writer, writer_) catch {}; + writer.writeAll("}"); + }, + .Set => { + const length_value = value.get(this.globalThis, "size") orelse JSC.JSValue.jsNumberFromInt32(0); + const length = length_value.toInt32(); + + const prev_quote_strings = this.quote_strings; + this.quote_strings = true; + defer this.quote_strings = prev_quote_strings; + + this.writeIndent(Writer, writer_) catch {}; + if (length == 0) { + return writer.writeAll("Set {}"); + } + writer.print("Set({d}) {{\n", .{length}); + { + this.indent += 1; + defer this.indent -|= 1; + var iter = SetIterator(Writer, enable_ansi_colors){ + .formatter = this, + .writer = writer_, + }; + value.forEach(this.globalThis, &iter, @TypeOf(iter).forEach); + } + this.writeIndent(Writer, writer_) catch {}; + writer.writeAll("}"); + }, .JSON => { var str = ZigString.init(""); value.jsonStringify(this.globalThis, this.indent, &str); @@ -1517,6 +1661,10 @@ pub const ZigConsoleClient = struct { const count_ = CAPI.JSPropertyNameArrayGetCount(array); var i: usize = 0; + const prev_quote_strings = this.quote_strings; + this.quote_strings = true; + defer this.quote_strings = prev_quote_strings; + var name_str = ZigString.init(""); value.getPrototype(this.globalThis).getNameProperty(this.globalThis, &name_str); @@ -1550,20 +1698,19 @@ pub const ZigConsoleClient = struct { if (comptime enable_ansi_colors) { writer.writeAll(comptime Output.prettyFmt("<r><green>", true)); } - writer.writeAll("\""); } this.format(tag, Writer, writer_, JSValue.fromRef(property_value), this.globalThis, enable_ansi_colors); if (tag.cell.isStringLike()) { - writer.writeAll("\""); if (comptime enable_ansi_colors) { writer.writeAll(comptime Output.prettyFmt("<r>", true)); } } if (i + 1 < count_) { - writer.writeAll(", "); + this.printComma(Writer, writer_, enable_ansi_colors) catch unreachable; + writer.writeAll(" "); } } @@ -1582,7 +1729,8 @@ pub const ZigConsoleClient = struct { const slice = buffer.slice(); while (i < len) : (i += 1) { if (i > 0) { - writer.writeAll(", "); + this.printComma(Writer, writer_, enable_ansi_colors) catch unreachable; + writer.writeAll(" "); } writer.print(comptime Output.prettyFmt("<r><yellow>{d}<r>", enable_ansi_colors), .{slice[i]}); diff --git a/src/javascript/jsc/webcore/response.zig b/src/javascript/jsc/webcore/response.zig index 2680f54a3..a091c7cf2 100644 --- a/src/javascript/jsc/webcore/response.zig +++ b/src/javascript/jsc/webcore/response.zig @@ -38,7 +38,7 @@ const JSGlobalObject = JSC.JSGlobalObject; const VirtualMachine = @import("../javascript.zig").VirtualMachine; const Task = @import("../javascript.zig").Task; - +const JSPrinter = @import("../../../js_printer.zig"); const picohttp = @import("picohttp"); pub const Response = struct { @@ -90,36 +90,43 @@ pub const Response = struct { pub const Props = struct {}; pub fn writeFormat(this: *const Response, formatter: *JSC.Formatter, writer: anytype, comptime enable_ansi_colors: bool) !void { - try formatter.writeIndent(@TypeOf(writer), writer); + const Writer = @TypeOf(writer); + try formatter.writeIndent(Writer, writer); try writer.print("Response ({}) {{\n", .{bun.fmt.size(this.body.len)}); { formatter.indent += 1; defer formatter.indent -|= 1; - try formatter.writeIndent(@TypeOf(writer), writer); + try formatter.writeIndent(Writer, writer); try writer.writeAll("ok: "); - formatter.printAs(.Boolean, @TypeOf(writer), writer, JSC.JSValue.jsBoolean(this.isOK()), .BooleanObject, enable_ansi_colors); + formatter.printAs(.Boolean, Writer, writer, JSC.JSValue.jsBoolean(this.isOK()), .BooleanObject, enable_ansi_colors); + formatter.printComma(Writer, writer, enable_ansi_colors) catch unreachable; try writer.writeAll("\n"); try this.body.writeFormat(formatter, writer, enable_ansi_colors); + + formatter.printComma(Writer, writer, enable_ansi_colors) catch unreachable; try writer.writeAll("\n"); - try formatter.writeIndent(@TypeOf(writer), writer); + try formatter.writeIndent(Writer, writer); try writer.writeAll("url: \""); try writer.print(comptime Output.prettyFmt("<r><b>{s}<r>", enable_ansi_colors), .{this.url}); - try writer.writeAll("\"\n"); + try writer.writeAll("\""); + formatter.printComma(Writer, writer, enable_ansi_colors) catch unreachable; + try writer.writeAll("\n"); - try formatter.writeIndent(@TypeOf(writer), writer); - try writer.writeAll("statusText: \""); - try writer.writeAll(this.status_text); - try writer.writeAll("\"\n"); + try formatter.writeIndent(Writer, writer); + try writer.writeAll("statusText: "); + try JSPrinter.writeJSONString(this.status_text, Writer, writer, false); + formatter.printComma(Writer, writer, enable_ansi_colors) catch unreachable; + try writer.writeAll("\n"); - try formatter.writeIndent(@TypeOf(writer), writer); + try formatter.writeIndent(Writer, writer); try writer.writeAll("redirected: "); - formatter.printAs(.Boolean, @TypeOf(writer), writer, JSC.JSValue.jsBoolean(this.redirected), .BooleanObject, enable_ansi_colors); + formatter.printAs(.Boolean, Writer, writer, JSC.JSValue.jsBoolean(this.redirected), .BooleanObject, enable_ansi_colors); } try writer.writeAll("\n"); - try formatter.writeIndent(@TypeOf(writer), writer); + try formatter.writeIndent(Writer, writer); try writer.writeAll("}"); } @@ -1381,14 +1388,14 @@ pub const Headers = struct { return result; } - pub fn writeFormat(this: *const Headers, formatter: *JSC.Formatter, writer: anytype, comptime _: bool) !void { + pub fn writeFormat(this: *const Headers, formatter: *JSC.Formatter, writer: anytype, comptime enable_ansi_colors: bool) !void { if (this.entries.len == 0) { try writer.writeAll("Headers (0 KB) {}"); return; } try writer.print("Headers ({}) {{\n", .{bun.fmt.size(this.buf.items.len)}); - + const Writer = @TypeOf(writer); { var slice = this.entries.slice(); const names = slice.items(.name); @@ -1398,16 +1405,15 @@ pub const Headers = struct { for (names) |name, i| { if (i > 0) { + formatter.printComma(Writer, writer, enable_ansi_colors) catch unreachable; writer.writeAll("\n") catch unreachable; } const value = values[i]; - formatter.writeIndent(@TypeOf(writer), writer) catch unreachable; - writer.writeAll("\"") catch unreachable; - writer.writeAll(this.asStr(name)) catch unreachable; - writer.writeAll("\": \"") catch unreachable; - writer.writeAll(this.asStr(value)) catch unreachable; - writer.writeAll("\"") catch unreachable; + formatter.writeIndent(Writer, writer) catch unreachable; + try JSPrinter.writeJSONString(this.asStr(name), Writer, writer, false); + writer.writeAll(": ") catch unreachable; + try JSPrinter.writeJSONString(this.asStr(value), Writer, writer, false); } } @@ -1462,21 +1468,24 @@ pub const Body = struct { ptr_allocator: ?std.mem.Allocator = null, pub fn writeFormat(this: *const Body, formatter: *JSC.Formatter, writer: anytype, comptime enable_ansi_colors: bool) !void { - try formatter.writeIndent(@TypeOf(writer), writer); + const Writer = @TypeOf(writer); + + try formatter.writeIndent(Writer, writer); try writer.writeAll("bodyUsed: "); - formatter.printAs(.Boolean, @TypeOf(writer), writer, JSC.JSValue.jsBoolean(!(this.value == .Unconsumed or this.value == .Empty)), .BooleanObject, enable_ansi_colors); + formatter.printAs(.Boolean, Writer, writer, JSC.JSValue.jsBoolean(!(this.value == .Unconsumed or this.value == .Empty)), .BooleanObject, enable_ansi_colors); + try formatter.printComma(Writer, writer, enable_ansi_colors); try writer.writeAll("\n"); if (this.init.headers) |*headers| { - try formatter.writeIndent(@TypeOf(writer), writer); + try formatter.writeIndent(Writer, writer); try writer.writeAll("headers: "); try headers.writeFormat(formatter, writer, comptime enable_ansi_colors); try writer.writeAll("\n"); } - try formatter.writeIndent(@TypeOf(writer), writer); + try formatter.writeIndent(Writer, writer); try writer.writeAll("status: "); - formatter.printAs(.Double, @TypeOf(writer), writer, JSC.JSValue.jsNumber(this.init.status_code), .NumberObject, enable_ansi_colors); + formatter.printAs(.Double, Writer, writer, JSC.JSValue.jsNumber(this.init.status_code), .NumberObject, enable_ansi_colors); } pub fn deinit(this: *Body, allocator: std.mem.Allocator) void { |