aboutsummaryrefslogtreecommitdiff
path: root/src/resolver
diff options
context:
space:
mode:
Diffstat (limited to 'src/resolver')
-rw-r--r--src/resolver/resolver.zig95
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;
+ }
+}