mirror of
https://github.com/oven-sh/bun
synced 2026-02-09 18:38:55 +00:00
431 lines
13 KiB
Zig
431 lines
13 KiB
Zig
const JSC = @import("../../../jsc.zig");
|
|
const std = @import("std");
|
|
const Flavor = JSC.Node.Flavor;
|
|
const ArgumentsSlice = JSC.Node.ArgumentsSlice;
|
|
const system = std.os.system;
|
|
const Maybe = JSC.Node.Maybe;
|
|
const Encoding = JSC.Node.Encoding;
|
|
const FeatureFlags = @import("../../../global.zig").FeatureFlags;
|
|
const Args = JSC.Node.NodeFS.Arguments;
|
|
const d = JSC.d;
|
|
|
|
const NodeFSFunction = fn (
|
|
*JSC.Node.NodeFS,
|
|
JSC.C.JSContextRef,
|
|
JSC.C.JSObjectRef,
|
|
JSC.C.JSObjectRef,
|
|
[]const JSC.C.JSValueRef,
|
|
JSC.C.ExceptionRef,
|
|
) JSC.C.JSValueRef;
|
|
|
|
pub const toJSTrait = std.meta.trait.hasFn("toJS");
|
|
pub const fromJSTrait = std.meta.trait.hasFn("fromJS");
|
|
const NodeFSFunctionEnum = JSC.Node.DeclEnum(JSC.Node.NodeFS);
|
|
|
|
fn callSync(comptime FunctionEnum: NodeFSFunctionEnum) NodeFSFunction {
|
|
const Function = @field(JSC.Node.NodeFS, @tagName(FunctionEnum));
|
|
const FunctionType = @TypeOf(Function);
|
|
|
|
const function: std.builtin.TypeInfo.Fn = comptime @typeInfo(FunctionType).Fn;
|
|
comptime if (function.args.len != 3) @compileError("Expected 3 arguments");
|
|
const Arguments = comptime function.args[1].arg_type.?;
|
|
const FormattedName = comptime [1]u8{std.ascii.toUpper(@tagName(FunctionEnum)[0])} ++ @tagName(FunctionEnum)[1..];
|
|
const Result = comptime JSC.Node.Maybe(@field(JSC.Node.NodeFS.ReturnType, FormattedName));
|
|
|
|
const NodeBindingClosure = struct {
|
|
pub fn bind(
|
|
this: *JSC.Node.NodeFS,
|
|
ctx: JSC.C.JSContextRef,
|
|
_: JSC.C.JSObjectRef,
|
|
_: JSC.C.JSObjectRef,
|
|
arguments: []const JSC.C.JSValueRef,
|
|
exception: JSC.C.ExceptionRef,
|
|
) JSC.C.JSValueRef {
|
|
var slice = ArgumentsSlice.init(@ptrCast([*]const JSC.JSValue, arguments.ptr)[0..arguments.len]);
|
|
|
|
defer {
|
|
// TODO: fix this
|
|
for (arguments) |arg| {
|
|
JSC.C.JSValueUnprotect(ctx, arg);
|
|
}
|
|
slice.arena.deinit();
|
|
}
|
|
|
|
const args = if (comptime Arguments != void)
|
|
(Arguments.fromJS(ctx, &slice, exception) orelse return null)
|
|
else
|
|
Arguments{};
|
|
if (exception.* != null) return null;
|
|
|
|
const result: Result = Function(
|
|
this,
|
|
args,
|
|
comptime Flavor.sync,
|
|
);
|
|
return switch (result) {
|
|
.err => |err| brk: {
|
|
exception.* = err.toJS(ctx);
|
|
break :brk null;
|
|
},
|
|
.result => |res| if (comptime Result.ReturnType != void)
|
|
JSC.To.JS.withType(Result.ReturnType, res, ctx, exception)
|
|
else
|
|
JSC.C.JSValueMakeUndefined(ctx),
|
|
};
|
|
}
|
|
};
|
|
|
|
return NodeBindingClosure.bind;
|
|
}
|
|
|
|
fn call(comptime Function: NodeFSFunctionEnum) NodeFSFunction {
|
|
// const FunctionType = @TypeOf(Function);
|
|
_ = Function;
|
|
|
|
// const function: std.builtin.TypeInfo.Fn = comptime @typeInfo(FunctionType).Fn;
|
|
// comptime if (function.args.len != 3) @compileError("Expected 3 arguments");
|
|
// const Arguments = comptime function.args[2].arg_type orelse @compileError(std.fmt.comptimePrint("Function {s} expected to have an arg type at [2]", .{@typeName(FunctionType)}));
|
|
// const Result = comptime function.return_type.?;
|
|
// comptime if (Arguments != void and !fromJSTrait(Arguments)) @compileError(std.fmt.comptimePrint("{s} is missing fromJS()", .{@typeName(Arguments)}));
|
|
// comptime if (Result != void and !toJSTrait(Result)) @compileError(std.fmt.comptimePrint("{s} is missing toJS()", .{@typeName(Result)}));
|
|
const NodeBindingClosure = struct {
|
|
pub fn bind(
|
|
this: *JSC.Node.NodeFS,
|
|
ctx: JSC.C.JSContextRef,
|
|
_: JSC.C.JSObjectRef,
|
|
_: JSC.C.JSObjectRef,
|
|
arguments: []const JSC.C.JSValueRef,
|
|
exception: JSC.C.ExceptionRef,
|
|
) JSC.C.JSValueRef {
|
|
_ = this;
|
|
_ = ctx;
|
|
_ = arguments;
|
|
var err = JSC.SystemError{};
|
|
exception.* = err.toErrorInstance(ctx.ptr()).asObjectRef();
|
|
return null;
|
|
// var slice = ArgumentsSlice.init(arguments);
|
|
|
|
// defer {
|
|
// for (arguments.len) |arg| {
|
|
// JSC.C.JSValueUnprotect(ctx, arg);
|
|
// }
|
|
// slice.arena.deinit();
|
|
// }
|
|
|
|
// const args = if (comptime Arguments != void)
|
|
// Arguments.fromJS(ctx, &slice, exception)
|
|
// else
|
|
// Arguments{};
|
|
// if (exception.* != null) return null;
|
|
|
|
// const result: Maybe(Result) = Function(this, comptime Flavor.sync, args);
|
|
// switch (result) {
|
|
// .err => |err| {
|
|
// exception.* = err.toJS(ctx);
|
|
// return null;
|
|
// },
|
|
// .result => |res| {
|
|
// return switch (comptime Result) {
|
|
// void => JSC.JSValue.jsUndefined().asRef(),
|
|
// else => res.toJS(ctx),
|
|
// };
|
|
// },
|
|
// }
|
|
// unreachable;
|
|
}
|
|
};
|
|
return NodeBindingClosure.bind;
|
|
}
|
|
|
|
pub const NodeFSBindings = JSC.NewClass(
|
|
JSC.Node.NodeFS,
|
|
.{ .name = "fs", .ts = .{ .module = .{ .path = "fs" } } },
|
|
|
|
.{
|
|
.access = .{
|
|
.name = "access",
|
|
.rfn = call(.access),
|
|
},
|
|
.appendFile = .{
|
|
.name = "appendFile",
|
|
.rfn = call(.appendFile),
|
|
},
|
|
.close = .{
|
|
.name = "close",
|
|
.rfn = call(.close),
|
|
},
|
|
.copyFile = .{
|
|
.name = "copyFile",
|
|
.rfn = call(.copyFile),
|
|
},
|
|
.exists = .{
|
|
.name = "exists",
|
|
.rfn = call(.exists),
|
|
},
|
|
.chown = .{
|
|
.name = "chown",
|
|
.rfn = call(.chown),
|
|
},
|
|
.chmod = .{
|
|
.name = "chmod",
|
|
.rfn = call(.chmod),
|
|
},
|
|
.fchmod = .{
|
|
.name = "fchmod",
|
|
.rfn = call(.fchmod),
|
|
},
|
|
.fchown = .{
|
|
.name = "fchown",
|
|
.rfn = call(.fchown),
|
|
},
|
|
.fstat = .{
|
|
.name = "fstat",
|
|
.rfn = call(.fstat),
|
|
},
|
|
.fsync = .{
|
|
.name = "fsync",
|
|
.rfn = call(.fsync),
|
|
},
|
|
.ftruncate = .{
|
|
.name = "ftruncate",
|
|
.rfn = call(.ftruncate),
|
|
},
|
|
.futimes = .{
|
|
.name = "futimes",
|
|
.rfn = call(.futimes),
|
|
},
|
|
.lchmod = .{
|
|
.name = "lchmod",
|
|
.rfn = call(.lchmod),
|
|
},
|
|
.lchown = .{
|
|
.name = "lchown",
|
|
.rfn = call(.lchown),
|
|
},
|
|
.link = .{
|
|
.name = "link",
|
|
.rfn = call(.link),
|
|
},
|
|
.lstat = .{
|
|
.name = "lstat",
|
|
.rfn = call(.lstat),
|
|
},
|
|
.mkdir = .{
|
|
.name = "mkdir",
|
|
.rfn = call(.mkdir),
|
|
},
|
|
.mkdtemp = .{
|
|
.name = "mkdtemp",
|
|
.rfn = call(.mkdtemp),
|
|
},
|
|
.open = .{
|
|
.name = "open",
|
|
.rfn = call(.open),
|
|
},
|
|
.read = .{
|
|
.name = "read",
|
|
.rfn = call(.read),
|
|
},
|
|
.write = .{
|
|
.name = "write",
|
|
.rfn = call(.write),
|
|
},
|
|
.readdir = .{
|
|
.name = "readdir",
|
|
.rfn = call(.readdir),
|
|
},
|
|
.readFile = .{
|
|
.name = "readFile",
|
|
.rfn = call(.readFile),
|
|
},
|
|
.writeFile = .{
|
|
.name = "writeFile",
|
|
.rfn = call(.writeFile),
|
|
},
|
|
.readlink = .{
|
|
.name = "readlink",
|
|
.rfn = call(.readlink),
|
|
},
|
|
.realpath = .{
|
|
.name = "realpath",
|
|
.rfn = call(.realpath),
|
|
},
|
|
.rename = .{
|
|
.name = "rename",
|
|
.rfn = call(.rename),
|
|
},
|
|
.stat = .{
|
|
.name = "stat",
|
|
.rfn = call(.stat),
|
|
},
|
|
.symlink = .{
|
|
.name = "symlink",
|
|
.rfn = call(.symlink),
|
|
},
|
|
.truncate = .{
|
|
.name = "truncate",
|
|
.rfn = call(.truncate),
|
|
},
|
|
.unlink = .{
|
|
.name = "unlink",
|
|
.rfn = call(.unlink),
|
|
},
|
|
.utimes = .{
|
|
.name = "utimes",
|
|
.rfn = call(.utimes),
|
|
},
|
|
.lutimes = .{
|
|
.name = "lutimes",
|
|
.rfn = call(.lutimes),
|
|
},
|
|
|
|
.createReadStream = .{
|
|
.name = "createReadStream",
|
|
.rfn = if (FeatureFlags.node_streams) callSync(.createReadStream) else call(.createReadStream),
|
|
},
|
|
|
|
.createWriteStream = .{
|
|
.name = "createWriteStream",
|
|
.rfn = if (FeatureFlags.node_streams) callSync(.createWriteStream) else call(.createWriteStream),
|
|
},
|
|
|
|
.accessSync = .{
|
|
.name = "accessSync",
|
|
.rfn = callSync(.access),
|
|
},
|
|
.appendFileSync = .{
|
|
.name = "appendFileSync",
|
|
.rfn = callSync(.appendFile),
|
|
},
|
|
.closeSync = .{
|
|
.name = "closeSync",
|
|
.rfn = callSync(.close),
|
|
},
|
|
.copyFileSync = .{
|
|
.name = "copyFileSync",
|
|
.rfn = callSync(.copyFile),
|
|
},
|
|
.existsSync = .{
|
|
.name = "existsSync",
|
|
.rfn = callSync(.exists),
|
|
},
|
|
.chownSync = .{
|
|
.name = "chownSync",
|
|
.rfn = callSync(.chown),
|
|
},
|
|
.chmodSync = .{
|
|
.name = "chmodSync",
|
|
.rfn = callSync(.chmod),
|
|
},
|
|
.fchmodSync = .{
|
|
.name = "fchmodSync",
|
|
.rfn = callSync(.fchmod),
|
|
},
|
|
.fchownSync = .{
|
|
.name = "fchownSync",
|
|
.rfn = callSync(.fchown),
|
|
},
|
|
.fstatSync = .{
|
|
.name = "fstatSync",
|
|
.rfn = callSync(.fstat),
|
|
},
|
|
.fsyncSync = .{
|
|
.name = "fsyncSync",
|
|
.rfn = callSync(.fsync),
|
|
},
|
|
.ftruncateSync = .{
|
|
.name = "ftruncateSync",
|
|
.rfn = callSync(.ftruncate),
|
|
},
|
|
.futimesSync = .{
|
|
.name = "futimesSync",
|
|
.rfn = callSync(.futimes),
|
|
},
|
|
.lchmodSync = .{
|
|
.name = "lchmodSync",
|
|
.rfn = callSync(.lchmod),
|
|
},
|
|
.lchownSync = .{
|
|
.name = "lchownSync",
|
|
.rfn = callSync(.lchown),
|
|
},
|
|
.linkSync = .{
|
|
.name = "linkSync",
|
|
.rfn = callSync(.link),
|
|
},
|
|
.lstatSync = .{
|
|
.name = "lstatSync",
|
|
.rfn = callSync(.lstat),
|
|
},
|
|
.mkdirSync = .{
|
|
.name = "mkdirSync",
|
|
.rfn = callSync(.mkdir),
|
|
},
|
|
.mkdtempSync = .{
|
|
.name = "mkdtempSync",
|
|
.rfn = callSync(.mkdtemp),
|
|
},
|
|
.openSync = .{
|
|
.name = "openSync",
|
|
.rfn = callSync(.open),
|
|
},
|
|
.readSync = .{
|
|
.name = "readSync",
|
|
.rfn = callSync(.read),
|
|
},
|
|
.writeSync = .{
|
|
.name = "writeSync",
|
|
.rfn = callSync(.write),
|
|
},
|
|
.readdirSync = .{
|
|
.name = "readdirSync",
|
|
.rfn = callSync(.readdir),
|
|
},
|
|
.readFileSync = .{
|
|
.name = "readFileSync",
|
|
.rfn = callSync(.readFile),
|
|
},
|
|
.writeFileSync = .{
|
|
.name = "writeFileSync",
|
|
.rfn = callSync(.writeFile),
|
|
},
|
|
.readlinkSync = .{
|
|
.name = "readlinkSync",
|
|
.rfn = callSync(.readlink),
|
|
},
|
|
.realpathSync = .{
|
|
.name = "realpathSync",
|
|
.rfn = callSync(.realpath),
|
|
},
|
|
.renameSync = .{
|
|
.name = "renameSync",
|
|
.rfn = callSync(.rename),
|
|
},
|
|
.statSync = .{
|
|
.name = "statSync",
|
|
.rfn = callSync(.stat),
|
|
},
|
|
.symlinkSync = .{
|
|
.name = "symlinkSync",
|
|
.rfn = callSync(.symlink),
|
|
},
|
|
.truncateSync = .{
|
|
.name = "truncateSync",
|
|
.rfn = callSync(.truncate),
|
|
},
|
|
.unlinkSync = .{
|
|
.name = "unlinkSync",
|
|
.rfn = callSync(.unlink),
|
|
},
|
|
.utimesSync = .{
|
|
.name = "utimesSync",
|
|
.rfn = callSync(.utimes),
|
|
},
|
|
.lutimesSync = .{
|
|
.name = "lutimesSync",
|
|
.rfn = callSync(.lutimes),
|
|
},
|
|
},
|
|
.{},
|
|
);
|