aboutsummaryrefslogtreecommitdiff
path: root/src/resolver
diff options
context:
space:
mode:
Diffstat (limited to 'src/resolver')
-rw-r--r--src/resolver/package_json.zig39
-rw-r--r--src/resolver/resolver.zig77
2 files changed, 115 insertions, 1 deletions
diff --git a/src/resolver/package_json.zig b/src/resolver/package_json.zig
index 4949fe49e..9db39ff7a 100644
--- a/src/resolver/package_json.zig
+++ b/src/resolver/package_json.zig
@@ -18,6 +18,8 @@ threadlocal var hashy: [2048]u8 = undefined;
pub const MacroImportReplacementMap = std.StringArrayHashMap(string);
pub const MacroMap = std.StringArrayHashMapUnmanaged(MacroImportReplacementMap);
+const ScriptsMap = std.StringArrayHashMap(string);
+
pub const PackageJSON = struct {
pub const LoadFramework = enum {
none,
@@ -57,6 +59,8 @@ pub const PackageJSON = struct {
version: string = "",
hash: u32 = 0xDEADBEEF,
+ scripts: ?*ScriptsMap = null,
+
always_bundle: []string = &.{},
macros: MacroMap = MacroMap{},
@@ -440,6 +444,7 @@ pub const PackageJSON = struct {
input_path: string,
dirname_fd: StoredFileDescriptorType,
comptime generate_hash: bool,
+ comptime include_scripts: bool,
) ?PackageJSON {
// TODO: remove this extra copy
@@ -690,6 +695,40 @@ pub const PackageJSON = struct {
}
}
+ if (include_scripts) {
+ read_scripts: {
+ if (json.asProperty("scripts")) |scripts_prop| {
+ if (scripts_prop.expr.data == .e_object) {
+ const scripts_obj = scripts_prop.expr.data.e_object;
+
+ var count: usize = 0;
+ for (scripts_obj.properties) |prop| {
+ const key = prop.key.?.asString(r.allocator) orelse continue;
+ const value = prop.value.?.asString(r.allocator) orelse continue;
+
+ count += @as(usize, @boolToInt(key.len > 0 and value.len > 0));
+ }
+
+ if (count == 0) break :read_scripts;
+ var scripts = ScriptsMap.init(r.allocator);
+ scripts.ensureUnusedCapacity(count) catch break :read_scripts;
+
+ for (scripts_obj.properties) |prop| {
+ const key = prop.key.?.asString(r.allocator) orelse continue;
+ const value = prop.value.?.asString(r.allocator) orelse continue;
+
+ if (!(key.len > 0 and value.len > 0)) continue;
+
+ scripts.putAssumeCapacity(key, value);
+ }
+
+ package_json.scripts = r.allocator.create(ScriptsMap) catch unreachable;
+ package_json.scripts.?.* = scripts;
+ }
+ }
+ }
+ }
+
// TODO: side effects
// TODO: exports map
diff --git a/src/resolver/resolver.zig b/src/resolver/resolver.zig
index 45f110e95..7f95dffae 100644
--- a/src/resolver/resolver.zig
+++ b/src/resolver/resolver.zig
@@ -207,6 +207,7 @@ threadlocal var _open_dirs: [256]std.fs.Dir = undefined;
threadlocal var resolve_without_remapping_buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
threadlocal var index_buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
threadlocal var dir_info_uncached_filename_buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
+threadlocal var node_bin_path: [std.fs.MAX_PATH_BYTES]u8 = undefined;
threadlocal var dir_info_uncached_path_buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
threadlocal var tsconfig_base_url_buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
threadlocal var relative_abs_path_buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
@@ -324,6 +325,12 @@ pub const LoadResult = struct {
// This is a global so even if multiple resolvers are created, the mutex will still work
var resolver_Mutex: Mutex = undefined;
var resolver_Mutex_loaded: bool = false;
+
+const BinFolderArray = std.BoundedArray(string, 128);
+var bin_folders: BinFolderArray = undefined;
+var bin_folders_lock: Mutex = Mutex.init();
+var bin_folders_loaded: bool = false;
+
// TODO:
// - Fix "browser" field mapping
// - Consider removing the string list abstraction?
@@ -336,6 +343,9 @@ pub const Resolver = struct {
node_module_bundle: ?*NodeModuleBundle,
extension_order: []const string = undefined,
+ care_about_bin_folder: bool = false,
+ care_about_scripts: bool = false,
+
debug_logs: ?DebugLogs = null,
elapsed: i128 = 0, // tracing
@@ -1361,8 +1371,19 @@ pub const Resolver = struct {
return path.text;
}
+ pub fn binDirs(r: *const ThisResolver) []const string {
+ if (!bin_folders_loaded) return &[_]string{};
+ return bin_folders.constSlice();
+ }
+
pub fn parsePackageJSON(r: *ThisResolver, file: string, dirname_fd: StoredFileDescriptorType) !?*PackageJSON {
- const pkg = PackageJSON.parse(ThisResolver, r, file, dirname_fd, true) orelse return null;
+ var pkg: PackageJSON = undefined;
+ if (!r.care_about_scripts) {
+ pkg = PackageJSON.parse(ThisResolver, r, file, dirname_fd, true, false) orelse return null;
+ } else {
+ pkg = PackageJSON.parse(ThisResolver, r, file, dirname_fd, true, true) orelse return null;
+ }
+
var _pkg = try r.allocator.create(PackageJSON);
_pkg.* = pkg;
return _pkg;
@@ -2477,6 +2498,60 @@ pub const Resolver = struct {
info.has_node_modules = (entry.entry.kind(rfs)) == .dir;
}
}
+
+ if (r.care_about_bin_folder) {
+ append_bin_dir: {
+ if (info.has_node_modules) {
+ if (entries.getComptimeQuery("node_modules")) |q| {
+ if (!bin_folders_loaded) {
+ bin_folders_loaded = true;
+ bin_folders = BinFolderArray.init(0) catch unreachable;
+ }
+
+ const this_dir = std.fs.Dir{ .fd = fd };
+ var file = this_dir.openDirZ("node_modules/.bin", .{}) catch break :append_bin_dir;
+ defer file.close();
+ var bin_path = std.os.getFdPath(file.fd, &node_bin_path) catch break :append_bin_dir;
+ bin_folders_lock.lock();
+ defer bin_folders_lock.unlock();
+
+ for (bin_folders.constSlice()) |existing_folder| {
+ if (strings.eql(existing_folder, bin_path)) {
+ break :append_bin_dir;
+ }
+ }
+
+ bin_folders.append(r.fs.dirname_store.append([]u8, bin_path) catch break :append_bin_dir) catch {};
+ }
+ }
+
+ if (info.is_node_modules) {
+ if (entries.getComptimeQuery(".bin")) |q| {
+ if (q.entry.kind(rfs) == .dir) {
+ if (!bin_folders_loaded) {
+ bin_folders_loaded = true;
+ bin_folders = BinFolderArray.init(0) catch unreachable;
+ }
+
+ const this_dir = std.fs.Dir{ .fd = fd };
+ var file = this_dir.openDirZ(".bin", .{}) catch break :append_bin_dir;
+ defer file.close();
+ var bin_path = std.os.getFdPath(file.fd, &node_bin_path) catch break :append_bin_dir;
+ bin_folders_lock.lock();
+ defer bin_folders_lock.unlock();
+
+ for (bin_folders.constSlice()) |existing_folder| {
+ if (strings.eql(existing_folder, bin_path)) {
+ break :append_bin_dir;
+ }
+ }
+
+ bin_folders.append(r.fs.dirname_store.append([]u8, bin_path) catch break :append_bin_dir) catch {};
+ }
+ }
+ }
+ }
+ }
// }
if (parent != null) {