diff options
Diffstat (limited to 'src/resolver')
| -rw-r--r-- | src/resolver/resolver.zig | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/src/resolver/resolver.zig b/src/resolver/resolver.zig index 14bc358d0..40b106f3a 100644 --- a/src/resolver/resolver.zig +++ b/src/resolver/resolver.zig @@ -94,6 +94,7 @@ const bufs = struct { threadlocal var remap_path_trailing_slash: [bun.MAX_PATH_BYTES]u8 = undefined; threadlocal var path_in_global_disk_cache: [bun.MAX_PATH_BYTES]u8 = undefined; threadlocal var abs_to_rel: [bun.MAX_PATH_BYTES]u8 = undefined; + threadlocal var node_modules_paths_buf: [bun.MAX_PATH_BYTES]u8 = undefined; pub inline fn bufs(comptime field: std.meta.DeclEnum(@This())) *@TypeOf(@field(@This(), @tagName(field))) { return &@field(@This(), @tagName(field)); @@ -3107,6 +3108,93 @@ pub const Resolver = struct { }; } + pub export fn Resolver__nodeModulePathsForJS(globalThis: *bun.JSC.JSGlobalObject, callframe: *bun.JSC.CallFrame) callconv(.C) bun.JSC.JSValue { + bun.JSC.markBinding(@src()); + const argument: bun.JSC.JSValue = callframe.argument(0); + + if (argument.isEmpty() or !argument.isString()) { + globalThis.throwInvalidArgumentType("nodeModulePaths", "path", "string"); + return .zero; + } + + const in_str = argument.toBunString(globalThis); + var r = &globalThis.bunVM().bundler.resolver; + return nodeModulePathsJSValue(r, in_str, globalThis); + } + + pub export fn Resolver__propForRequireMainPaths(globalThis: *bun.JSC.JSGlobalObject) callconv(.C) bun.JSC.JSValue { + bun.JSC.markBinding(@src()); + + const in_str = bun.String.create("."); + var r = &globalThis.bunVM().bundler.resolver; + return nodeModulePathsJSValue(r, in_str, globalThis); + } + + pub fn nodeModulePathsJSValue( + r: *ThisResolver, + in_str: bun.String, + globalObject: *bun.JSC.JSGlobalObject, + ) bun.JSC.JSValue { + var list = std.ArrayList(bun.String).init(bun.default_allocator); + defer list.deinit(); + + const sliced = in_str.toUTF8(bun.default_allocator); + defer sliced.deinit(); + + const str = brk: { + if (std.fs.path.isAbsolute(sliced.slice())) break :brk sliced.slice(); + var dir_path_buf = bufs(.node_modules_paths_buf); + break :brk r.fs.joinBuf(&[_]string{ r.fs.top_level_dir, sliced.slice() }, dir_path_buf); + }; + var arena = std.heap.ArenaAllocator.init(bun.default_allocator); + defer arena.deinit(); + var stack_fallback_allocator = std.heap.stackFallback(1024, arena.allocator()); + + if (r.readDirInfo(strings.withoutTrailingSlash(str)) catch null) |result| { + var dir_info = result; + + while (true) { + const path_without_trailing_slash = strings.withoutTrailingSlash(dir_info.abs_path); + const path_parts = brk: { + if (path_without_trailing_slash.len == 1 and path_without_trailing_slash[0] == '/') { + break :brk [2]string{ "", "/node_modules" }; + } + + break :brk [2]string{ path_without_trailing_slash, "/node_modules" }; + }; + list.append( + bun.String.create( + bun.strings.concat(stack_fallback_allocator.get(), &path_parts) catch unreachable, + ), + ) catch unreachable; + dir_info = (r.readDirInfo(std.fs.path.dirname(path_without_trailing_slash) orelse break) catch null) orelse break; + } + } else { + // does not exist + const full_path = std.fs.path.resolve(r.allocator, &[1][]const u8{str}) catch unreachable; + var path = full_path; + while (true) { + const path_without_trailing_slash = strings.withoutTrailingSlash(path); + + list.append( + bun.String.create( + bun.strings.concat( + stack_fallback_allocator.get(), + &[_]string{ + path_without_trailing_slash, + "/node_modules", + }, + ) catch unreachable, + ), + ) catch unreachable; + + path = path[0 .. strings.lastIndexOfChar(path, '/') orelse break]; + } + } + + return bun.String.toJSArray(globalObject, list.items); + } + pub fn loadAsIndex(r: *ThisResolver, dir_info: *DirInfo, extension_order: []const string) ?MatchResult { var rfs = &r.fs.fs; // Try the "index" file with extensions @@ -3892,3 +3980,10 @@ pub const GlobalCache = enum { }; } }; + +comptime { + if (!bun.JSC.is_bindgen) { + _ = Resolver.Resolver__nodeModulePathsForJS; + _ = Resolver.Resolver__propForRequireMainPaths; + } +} |
