aboutsummaryrefslogtreecommitdiff
path: root/src/bun.js/api
diff options
context:
space:
mode:
Diffstat (limited to 'src/bun.js/api')
-rw-r--r--src/bun.js/api/bun.zig21
-rw-r--r--src/bun.js/api/bun/socket.zig71
-rw-r--r--src/bun.js/api/server.zig130
3 files changed, 150 insertions, 72 deletions
diff --git a/src/bun.js/api/bun.zig b/src/bun.js/api/bun.zig
index e9b760de5..32bd0a9ec 100644
--- a/src/bun.js/api/bun.zig
+++ b/src/bun.js/api/bun.zig
@@ -942,7 +942,17 @@ fn doResolve(
return null;
}
- return doResolveWithArgs(ctx, specifier.getZigString(ctx.ptr()), from.getZigString(ctx.ptr()), exception, false);
+ var is_esm = true;
+ if (args.nextEat()) |next| {
+ if (next.isBoolean()) {
+ is_esm = next.toBoolean();
+ } else {
+ JSC.throwInvalidArguments("esm must be a boolean", .{}, ctx, exception);
+ return null;
+ }
+ }
+
+ return doResolveWithArgs(ctx, specifier.getZigString(ctx.ptr()), from.getZigString(ctx.ptr()), exception, is_esm, false);
}
fn doResolveWithArgs(
@@ -950,6 +960,7 @@ fn doResolveWithArgs(
specifier: ZigString,
from: ZigString,
exception: js.ExceptionRef,
+ is_esm: bool,
comptime is_file_path: bool,
) ?JSC.JSValue {
var errorable: ErrorableZigString = undefined;
@@ -960,6 +971,7 @@ fn doResolveWithArgs(
ctx.ptr(),
specifier,
from,
+ is_esm,
);
} else {
VirtualMachine.resolveForAPI(
@@ -967,6 +979,7 @@ fn doResolveWithArgs(
ctx.ptr(),
specifier,
from,
+ is_esm,
);
}
@@ -1010,10 +1023,11 @@ export fn Bun__resolve(
global: *JSGlobalObject,
specifier: JSValue,
source: JSValue,
+ is_esm: bool,
) JSC.JSValue {
var exception_ = [1]JSC.JSValueRef{null};
var exception = &exception_;
- const value = doResolveWithArgs(global, specifier.getZigString(global), source.getZigString(global), exception, true) orelse {
+ const value = doResolveWithArgs(global, specifier.getZigString(global), source.getZigString(global), exception, is_esm, true) orelse {
return JSC.JSPromise.rejectedPromiseValue(global, JSC.JSValue.fromRef(exception[0]));
};
return JSC.JSPromise.resolvedPromiseValue(global, value);
@@ -1023,10 +1037,11 @@ export fn Bun__resolveSync(
global: *JSGlobalObject,
specifier: JSValue,
source: JSValue,
+ is_esm: bool,
) JSC.JSValue {
var exception_ = [1]JSC.JSValueRef{null};
var exception = &exception_;
- return doResolveWithArgs(global, specifier.getZigString(global), source.getZigString(global), exception, true) orelse {
+ return doResolveWithArgs(global, specifier.getZigString(global), source.getZigString(global), exception, is_esm, true) orelse {
return JSC.JSValue.fromRef(exception[0]);
};
}
diff --git a/src/bun.js/api/bun/socket.zig b/src/bun.js/api/bun/socket.zig
index f4dcfb01c..911dc9e89 100644
--- a/src/bun.js/api/bun/socket.zig
+++ b/src/bun.js/api/bun/socket.zig
@@ -232,38 +232,65 @@ pub const SocketConfig = struct {
}
}
- if (opts.getTruthy(globalObject, "hostname")) |hostname| {
- if (hostname.isEmptyOrUndefinedOrNull() or !hostname.isString()) {
- exception.* = JSC.toInvalidArguments("Expected \"hostname\" to be a string", .{}, globalObject).asObjectRef();
- return null;
- }
+ hostname_or_unix: {
+ if (opts.getTruthy(globalObject, "unix")) |unix_socket| {
+ if (!unix_socket.isString()) {
+ exception.* = JSC.toInvalidArguments("Expected \"unix\" to be a string", .{}, globalObject).asObjectRef();
+ return null;
+ }
- const port_value = opts.get(globalObject, "port") orelse JSValue.zero;
- if (port_value.isEmptyOrUndefinedOrNull() or !port_value.isNumber() or port_value.toInt64() > std.math.maxInt(u16) or port_value.toInt64() < 0) {
- exception.* = JSC.toInvalidArguments("Expected \"port\" to be a number between 0 and 65535", .{}, globalObject).asObjectRef();
- return null;
- }
+ hostname_or_unix = unix_socket.getZigString(globalObject).toSlice(bun.default_allocator);
- hostname_or_unix = hostname.getZigString(globalObject).toSlice(bun.default_allocator);
- port = port_value.toU16();
+ if (strings.hasPrefixComptime(hostname_or_unix.slice(), "file://") or strings.hasPrefixComptime(hostname_or_unix.slice(), "unix://") or strings.hasPrefixComptime(hostname_or_unix.slice(), "sock://")) {
+ hostname_or_unix.ptr += 7;
+ hostname_or_unix.len -|= 7;
+ }
- if (hostname_or_unix.len == 0) {
- exception.* = JSC.toInvalidArguments("Expected \"hostname\" to be a non-empty string", .{}, globalObject).asObjectRef();
- return null;
- }
- } else if (opts.getTruthy(globalObject, "unix")) |unix_socket| {
- if (unix_socket.isEmptyOrUndefinedOrNull() or !unix_socket.isString()) {
- exception.* = JSC.toInvalidArguments("Expected \"unix\" to be a string", .{}, globalObject).asObjectRef();
- return null;
+ if (hostname_or_unix.len > 0) {
+ break :hostname_or_unix;
+ }
}
- hostname_or_unix = unix_socket.getZigString(globalObject).toSlice(bun.default_allocator);
+ if (opts.getTruthy(globalObject, "hostname")) |hostname| {
+ if (!hostname.isString()) {
+ exception.* = JSC.toInvalidArguments("Expected \"hostname\" to be a string", .{}, globalObject).asObjectRef();
+ return null;
+ }
+
+ var port_value = opts.get(globalObject, "port") orelse JSValue.zero;
+ hostname_or_unix = hostname.getZigString(globalObject).toSlice(bun.default_allocator);
+
+ if (port_value.isEmptyOrUndefinedOrNull() and hostname_or_unix.len > 0) {
+ const parsed_url = bun.URL.parse(hostname_or_unix.slice());
+ if (parsed_url.getPort()) |port_num| {
+ port_value = JSValue.jsNumber(port_num);
+ hostname_or_unix.ptr = parsed_url.hostname.ptr;
+ hostname_or_unix.len = @truncate(u32, parsed_url.hostname.len);
+ }
+ }
+
+ if (port_value.isEmptyOrUndefinedOrNull() or !port_value.isNumber() or port_value.toInt64() > std.math.maxInt(u16) or port_value.toInt64() < 0) {
+ exception.* = JSC.toInvalidArguments("Expected \"port\" to be a number between 0 and 65535", .{}, globalObject).asObjectRef();
+ return null;
+ }
+
+ port = port_value.toU16();
+
+ if (hostname_or_unix.len == 0) {
+ exception.* = JSC.toInvalidArguments("Expected \"hostname\" to be a non-empty string", .{}, globalObject).asObjectRef();
+ return null;
+ }
+
+ if (hostname_or_unix.len > 0) {
+ break :hostname_or_unix;
+ }
+ }
if (hostname_or_unix.len == 0) {
exception.* = JSC.toInvalidArguments("Expected \"unix\" to be a non-empty string", .{}, globalObject).asObjectRef();
return null;
}
- } else {
+
exception.* = JSC.toInvalidArguments("Expected either \"hostname\" or \"unix\"", .{}, globalObject).asObjectRef();
return null;
}
diff --git a/src/bun.js/api/server.zig b/src/bun.js/api/server.zig
index f47ee9fc0..137d164f0 100644
--- a/src/bun.js/api/server.zig
+++ b/src/bun.js/api/server.zig
@@ -2135,8 +2135,8 @@ fn NewRequestContext(comptime ssl_enabled: bool, comptime debug_mode: bool, comp
const result = JSC.C.JSObjectCallAsFunctionReturnValue(this.server.globalThis, this.server.config.onError.asObjectRef(), this.server.thisObject.asObjectRef(), 1, &args);
if (!result.isEmptyOrUndefinedOrNull()) {
- if (result.isError() or result.isAggregateError(this.server.globalThis)) {
- this.finishRunningErrorHandler(result, status);
+ if (result.toError()) |err| {
+ this.finishRunningErrorHandler(err, status);
return;
} else if (result.as(Response)) |response| {
this.render(response);
@@ -2514,7 +2514,10 @@ pub const WebSocketServer = struct {
active_connections: usize = 0,
/// used by publish()
- ssl: bool = false,
+ flags: packed struct(u2) {
+ ssl: bool = false,
+ publish_to_self: bool = true,
+ } = .{},
pub fn fromJS(globalObject: *JSC.JSGlobalObject, object: JSC.JSValue) ?Handler {
var handler = Handler{ .globalObject = globalObject };
@@ -2752,6 +2755,17 @@ pub const WebSocketServer = struct {
}
}
+ if (object.get(globalObject, "publishToSelf")) |value| {
+ if (!value.isUndefinedOrNull()) {
+ if (!value.isBoolean()) {
+ globalObject.throwInvalidArguments("websocket expects publishToSelf to be a boolean", .{});
+ return null;
+ }
+
+ server.handler.flags.publish_to_self = value.toBoolean();
+ }
+ }
+
server.protect();
return server;
}
@@ -3025,7 +3039,9 @@ pub const ServerWebSocket = struct {
log("publish() closed", .{});
return JSValue.jsNumber(0);
};
- const ssl = this.handler.ssl;
+ const flags = this.handler.flags;
+ const ssl = flags.ssl;
+ const publish_to_self = flags.publish_to_self;
const topic_value = args.ptr[0];
const message_value = args.ptr[1];
@@ -3051,16 +3067,23 @@ pub const ServerWebSocket = struct {
return .zero;
}
- if (message_value.asArrayBuffer(globalThis)) |buffer| {
+ if (message_value.asArrayBuffer(globalThis)) |array_buffer| {
+ const buffer = array_buffer.slice();
+
if (buffer.len == 0) {
globalThis.throw("publish requires a non-empty message", .{});
return .zero;
}
+ const result = if (!publish_to_self)
+ this.websocket.publish(topic_slice.slice(), buffer, .binary, compress)
+ else
+ uws.AnyWebSocket.publishWithOptions(ssl, app, topic_slice.slice(), buffer, .binary, compress);
+
return JSValue.jsNumber(
// if 0, return 0
// else return number of bytes sent
- @as(i32, @boolToInt(uws.AnyWebSocket.publishWithOptions(ssl, app, topic_slice.slice(), buffer.slice(), .binary, compress))) * @intCast(i32, @truncate(u31, buffer.len)),
+ if (result) @intCast(i32, @truncate(u31, buffer.len)) else @as(i32, 0),
);
}
@@ -3072,10 +3095,16 @@ pub const ServerWebSocket = struct {
}
const buffer = string_slice.slice();
+
+ const result = if (!publish_to_self)
+ this.websocket.publish(topic_slice.slice(), buffer, .text, compress)
+ else
+ uws.AnyWebSocket.publishWithOptions(ssl, app, topic_slice.slice(), buffer, .text, compress);
+
return JSValue.jsNumber(
// if 0, return 0
// else return number of bytes sent
- @as(i32, @boolToInt(uws.AnyWebSocket.publishWithOptions(ssl, app, topic_slice.slice(), buffer, .text, compress))) * @intCast(i32, @truncate(u31, buffer.len)),
+ if (result) @intCast(i32, @truncate(u31, buffer.len)) else @as(i32, 0),
);
}
@@ -3099,7 +3128,9 @@ pub const ServerWebSocket = struct {
log("publish() closed", .{});
return JSValue.jsNumber(0);
};
- const ssl = this.handler.ssl;
+ const flags = this.handler.flags;
+ const ssl = flags.ssl;
+ const publish_to_self = flags.publish_to_self;
const topic_value = args.ptr[0];
const message_value = args.ptr[1];
@@ -3132,10 +3163,16 @@ pub const ServerWebSocket = struct {
}
const buffer = string_slice.slice();
+
+ const result = if (!publish_to_self)
+ this.websocket.publish(topic_slice.slice(), buffer, .text, compress)
+ else
+ uws.AnyWebSocket.publishWithOptions(ssl, app, topic_slice.slice(), buffer, .text, compress);
+
return JSValue.jsNumber(
// if 0, return 0
// else return number of bytes sent
- @as(i32, @boolToInt(uws.AnyWebSocket.publishWithOptions(ssl, app, topic_slice.slice(), buffer, .text, compress))) * @intCast(i32, @truncate(u31, buffer.len)),
+ if (result) @intCast(i32, @truncate(u31, buffer.len)) else @as(i32, 0),
);
}
@@ -3156,7 +3193,9 @@ pub const ServerWebSocket = struct {
log("publish() closed", .{});
return JSValue.jsNumber(0);
};
- const ssl = this.handler.ssl;
+ const flags = this.handler.flags;
+ const ssl = flags.ssl;
+ const publish_to_self = flags.publish_to_self;
const topic_value = args.ptr[0];
const message_value = args.ptr[1];
const compress_value = args.ptr[2];
@@ -3180,19 +3219,25 @@ pub const ServerWebSocket = struct {
globalThis.throw("publishBinary requires a non-empty message", .{});
return .zero;
}
- const buffer = message_value.asArrayBuffer(globalThis) orelse {
+ const array_buffer = message_value.asArrayBuffer(globalThis) orelse {
globalThis.throw("publishBinary expects an ArrayBufferView", .{});
return .zero;
};
+ const buffer = array_buffer.slice();
if (buffer.len == 0) {
return JSC.JSValue.jsNumber(0);
}
+ const result = if (!publish_to_self)
+ this.websocket.publish(topic_slice.slice(), buffer, .binary, compress)
+ else
+ uws.AnyWebSocket.publishWithOptions(ssl, app, topic_slice.slice(), buffer, .binary, compress);
+
return JSValue.jsNumber(
// if 0, return 0
// else return number of bytes sent
- @as(i32, @boolToInt(uws.AnyWebSocket.publishWithOptions(ssl, app, topic_slice.slice(), buffer.slice(), .binary, compress))) * @intCast(i32, @truncate(u31, buffer.len)),
+ if (result) @intCast(i32, @truncate(u31, buffer.len)) else @as(i32, 0),
);
}
@@ -3200,13 +3245,15 @@ pub const ServerWebSocket = struct {
this: *ServerWebSocket,
globalThis: *JSC.JSGlobalObject,
topic_str: *JSC.JSString,
- buffer: *JSC.JSUint8Array,
+ array: *JSC.JSUint8Array,
) callconv(.C) JSC.JSValue {
var app = this.handler.app orelse {
log("publish() closed", .{});
return JSValue.jsNumber(0);
};
- const ssl = this.handler.ssl;
+ const flags = this.handler.flags;
+ const ssl = flags.ssl;
+ const publish_to_self = flags.publish_to_self;
var topic_slice = topic_str.toSlice(globalThis, bun.default_allocator);
defer topic_slice.deinit();
@@ -3217,30 +3264,20 @@ pub const ServerWebSocket = struct {
const compress = true;
- const slice = buffer.slice();
- if (slice.len == 0) {
+ const buffer = array.slice();
+ if (buffer.len == 0) {
return JSC.JSValue.jsNumber(0);
}
+ const result = if (!publish_to_self)
+ this.websocket.publish(topic_slice.slice(), buffer, .binary, compress)
+ else
+ uws.AnyWebSocket.publishWithOptions(ssl, app, topic_slice.slice(), buffer, .binary, compress);
+
return JSValue.jsNumber(
// if 0, return 0
// else return number of bytes sent
- @as(
- i32,
- @boolToInt(
- uws.AnyWebSocket.publishWithOptions(
- ssl,
- app,
- topic_slice.slice(),
- slice,
- .binary,
- compress,
- ),
- ),
- ) * @intCast(
- i32,
- @truncate(u31, slice.len),
- ),
+ if (result) @intCast(i32, @truncate(u31, buffer.len)) else @as(i32, 0),
);
}
@@ -3254,7 +3291,9 @@ pub const ServerWebSocket = struct {
log("publish() closed", .{});
return JSValue.jsNumber(0);
};
- const ssl = this.handler.ssl;
+ const flags = this.handler.flags;
+ const ssl = flags.ssl;
+ const publish_to_self = flags.publish_to_self;
var topic_slice = topic_str.toSlice(globalThis, bun.default_allocator);
defer topic_slice.deinit();
@@ -3266,24 +3305,21 @@ pub const ServerWebSocket = struct {
const compress = true;
const slice = str.toSlice(globalThis, bun.default_allocator);
- if (slice.len == 0) {
+ defer slice.deinit();
+ const buffer = slice.slice();
+
+ if (buffer.len == 0) {
return JSC.JSValue.jsNumber(0);
}
+ const result = if (!publish_to_self)
+ this.websocket.publish(topic_slice.slice(), buffer, .text, compress)
+ else
+ uws.AnyWebSocket.publishWithOptions(ssl, app, topic_slice.slice(), buffer, .text, compress);
return JSValue.jsNumber(
// if 0, return 0
// else return number of bytes sent
- @as(i32, @boolToInt(uws.AnyWebSocket.publishWithOptions(
- ssl,
- app,
- topic_slice.slice(),
- slice.slice(),
- .text,
- compress,
- ))) * @intCast(
- i32,
- @truncate(u31, slice.len),
- ),
+ if (result) @intCast(i32, @truncate(u31, buffer.len)) else @as(i32, 0),
);
}
@@ -4107,7 +4143,7 @@ pub fn NewServer(comptime ssl_enabled_: bool, comptime debug_mode_: bool) type {
}
if (new_config.websocket) |*ws| {
- ws.handler.ssl = ssl_enabled;
+ ws.handler.flags.ssl = ssl_enabled;
if (ws.handler.onMessage != .zero or ws.handler.onOpen != .zero) {
if (this.config.websocket) |old_ws| {
old_ws.unprotect();
@@ -4671,7 +4707,7 @@ pub fn NewServer(comptime ssl_enabled_: bool, comptime debug_mode_: bool) type {
if (this.config.websocket) |*websocket| {
websocket.globalObject = this.globalThis;
websocket.handler.app = this.app;
- websocket.handler.ssl = ssl_enabled;
+ websocket.handler.flags.ssl = ssl_enabled;
this.app.ws(
"/*",
this,