aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <jarred@jarredsumner.com> 2022-03-08 23:37:54 -0800
committerGravatar Jarred Sumner <jarred@jarredsumner.com> 2022-03-08 23:37:54 -0800
commiteeff004ec2d616691430a494a5d3a3b35500c2b0 (patch)
treebb36f0a9213b84db85dee39d086d8e1070c3b830
parent1bf898828b62922887b74752122ea0f9cd042078 (diff)
downloadbun-eeff004ec2d616691430a494a5d3a3b35500c2b0.tar.gz
bun-eeff004ec2d616691430a494a5d3a3b35500c2b0.tar.zst
bun-eeff004ec2d616691430a494a5d3a3b35500c2b0.zip
Fix quoting console.log
-rw-r--r--src/global.zig4
-rw-r--r--src/javascript/jsc/bindings/exports.zig180
-rw-r--r--src/javascript/jsc/webcore/response.zig61
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 {