aboutsummaryrefslogtreecommitdiff
path: root/src/javascript/jsc/javascript.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/javascript/jsc/javascript.zig')
-rw-r--r--src/javascript/jsc/javascript.zig70
1 files changed, 70 insertions, 0 deletions
diff --git a/src/javascript/jsc/javascript.zig b/src/javascript/jsc/javascript.zig
index dc545ae87..4a3c19964 100644
--- a/src/javascript/jsc/javascript.zig
+++ b/src/javascript/jsc/javascript.zig
@@ -179,6 +179,69 @@ pub const Bun = struct {
return ref;
}
+ pub fn readFileAsString(
+ this: void,
+ ctx: js.JSContextRef,
+ function: js.JSObjectRef,
+ thisObject: js.JSObjectRef,
+ arguments: []const js.JSValueRef,
+ exception: js.ExceptionRef,
+ ) js.JSValueRef {
+ if (arguments.len != 1 or !JSValue.isString(JSValue.fromRef(arguments[0]))) {
+ JSError(getAllocator(ctx), "readFile expects a file path as a string. e.g. Bun.readFile(\"public/index.html\")", .{}, ctx, exception);
+ return js.JSValueMakeUndefined(ctx);
+ }
+ var out = ZigString.Empty;
+ JSValue.toZigString(JSValue.fromRef(arguments[0]), &out, VirtualMachine.vm.global);
+ var out_slice = out.slice();
+
+ // The dots are kind of unnecessary. They'll be normalized.
+ if (out.len == 0 or @ptrToInt(out.ptr) == 0 or std.mem.eql(u8, out_slice, ".") or std.mem.eql(u8, out_slice, "..") or std.mem.eql(u8, out_slice, "../")) {
+ JSError(getAllocator(ctx), "readFile expects a valid file path. e.g. Bun.readFile(\"public/index.html\")", .{}, ctx, exception);
+ return js.JSValueMakeUndefined(ctx);
+ }
+
+ var buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
+
+ var parts = [_]string{out_slice};
+ // This does the equivalent of Node's path.normalize(path.join(cwd, out_slice))
+ var path = VirtualMachine.vm.bundler.fs.absBuf(&parts, &buf);
+ buf[path.len] = 0;
+
+ const buf_z: [:0]const u8 = buf[0..path.len :0];
+ var file = std.fs.cwd().openFileZ(buf_z, .{ .read = true, .write = false }) catch |err| {
+ JSError(getAllocator(ctx), "Opening file {s} for path: \"{s}\"", .{ @errorName(err), path }, ctx, exception);
+ return js.JSValueMakeUndefined(ctx);
+ };
+
+ defer file.close();
+
+ const stat = file.stat() catch |err| {
+ JSError(getAllocator(ctx), "Getting file size {s} for \"{s}\"", .{ @errorName(err), path }, ctx, exception);
+ return js.JSValueMakeUndefined(ctx);
+ };
+
+ if (stat.kind != .File) {
+ JSError(getAllocator(ctx), "Can't read a {s} as a string (\"{s}\")", .{ @tagName(stat.kind), path }, ctx, exception);
+ return js.JSValueMakeUndefined(ctx);
+ }
+
+ var contents_buf = VirtualMachine.vm.allocator.alloc(u8, stat.size + 2) catch unreachable; // OOM
+ defer VirtualMachine.vm.allocator.free(contents_buf);
+ const contents_len = file.readAll(contents_buf) catch |err| {
+ JSError(getAllocator(ctx), "{s} reading file (\"{s}\")", .{ @errorName(err), path }, ctx, exception);
+ return js.JSValueMakeUndefined(ctx);
+ };
+
+ contents_buf[contents_len] = 0;
+
+ // Very slow to do it this way. We're copying the string twice.
+ // But it's important that this string is garbage collected instead of manually managed.
+ // We can't really recycle this one.
+ // TODO: use external string
+ return js.JSValueMakeString(ctx, js.JSStringCreateWithUTF8CString(contents_buf.ptr));
+ }
+
pub fn getPublicPath(to: string, comptime Writer: type, writer: Writer) void {
const relative_path = VirtualMachine.vm.bundler.fs.relativeTo(to);
if (VirtualMachine.vm.bundler.options.origin.isAbsolute()) {
@@ -226,6 +289,13 @@ pub const Bun = struct {
.@"return" = "string[]",
},
},
+ .readFile = .{
+ .rfn = Bun.readFileAsString,
+ .ts = d.ts{
+ .name = "readFile",
+ .@"return" = "string",
+ },
+ },
},
.{
.Route = Router.Instance.GetClass(void){},
avatar.com/avatar/717ff67f2d673388855f5df58f884bba?s=13&d=retro' width='13' height='13' alt='Gravatar' /> Jake Boone 2-1/+107 2023-04-05Disable buffering when we clear terminalGravatar Jarred Sumner 1-0/+2 2023-04-05PrettierGravatar Jarred Sumner 3-4/+4 2023-04-05fix(fetch.proxy) fix proxy authentication (#2554)Gravatar Ciro Spaciari 3-31/+186 2023-04-05fix: build warnings (#2562)Gravatar hiroki osame 4-4/+1 2023-04-05In Documentation, move --watch before the script name (#2569)Gravatar Lawlzer 1-4/+5 2023-04-05fix `deepEquals` with array holes and accessors (#2557)Gravatar Dylan Conway 2-10/+249 2023-04-05fix: modules to have null prototype (#2561)Gravatar hiroki osame 2-2/+9 2023-04-04:clock1: :clock2: :clock3:Gravatar Jarred Sumner 1-1/+1 2023-04-04Implement `import.meta.main` (#2556)Gravatar Jarred Sumner 10-8/+89 2023-04-04Dylan/fix some failing tests (#2544)Gravatar Jarred Sumner 10-29/+72 2023-04-04Add npm benchmark (#2555)Gravatar Colin McDonnell 13-1/+271 2023-04-03Use absolute paths morebun-v0.5.9Gravatar Jarred Sumner 2-6/+11 2023-04-03Fix test failureGravatar Jarred Sumner 1-15/+18