diff --git a/src/node_modules.cc b/src/node_modules.cc index 2649b07bf2cf13..ef4c27a49e55d9 100644 --- a/src/node_modules.cc +++ b/src/node_modules.cc @@ -378,60 +378,56 @@ void BindingData::GetPackageScopeConfig( Realm* realm = Realm::GetCurrent(args); Utf8Value resolved(realm->isolate(), args[0]); - auto package_json_url_base = ada::parse(resolved.ToStringView()); - if (!package_json_url_base) { + + auto current_path_url = ada::parse(resolved.ToStringView()); + if (!current_path_url) { url::ThrowInvalidURL(realm->env(), resolved.ToStringView(), std::nullopt); return; } - auto package_json_url = - ada::parse("./package.json", &package_json_url_base.value()); - if (!package_json_url) { - url::ThrowInvalidURL(realm->env(), "./package.json", resolved.ToString()); - return; - } - std::string_view node_modules_package_path = "/node_modules/package.json"; + auto current_path_opt = url::FileURLToPath(realm->env(), *current_path_url); + CHECK(current_path_opt); + // BufferValue path_buffer(realm->isolate(), current_path_opt.value()); + // // Check if the path has a trailing slash. If so, add it after + // // ToNamespacedPath() as it will be deleted by ToNamespacedPath() + // bool endsWithSlash = path_buffer.ToStringView().ends_with( + // std::filesystem::path::preferred_separator); + // ToNamespacedPath(realm->env(), &path_buffer); + // std::string path_value_str = path_buffer.ToString(); + // if (endsWithSlash) { + // path_value_str.push_back(std::filesystem::path::preferred_separator); + // } + auto current_path = std::filesystem::path(current_path_opt.value()); + auto error_context = ErrorContext(); error_context.is_esm = true; - // TODO(@anonrig): Rewrite this function and avoid calling URL parser. while (true) { - auto pathname = package_json_url->get_pathname(); - if (pathname.ends_with(node_modules_package_path)) { + if (current_path.generic_string().ends_with("/node_modules")) { break; } - auto file_url = url::FileURLToPath(realm->env(), *package_json_url); - CHECK(file_url); error_context.specifier = resolved.ToString(); - auto package_json = GetPackageJSON(realm, *file_url, &error_context); + auto package_json = GetPackageJSON(realm, (current_path / "package.json").generic_string(), &error_context); if (package_json != nullptr) { return args.GetReturnValue().Set(package_json->Serialize(realm)); } - auto last_href = std::string(package_json_url->get_href()); - auto last_pathname = std::string(package_json_url->get_pathname()); - package_json_url = ada::parse("../package.json", &package_json_url.value()); - if (!package_json_url) { - url::ThrowInvalidURL(realm->env(), "../package.json", last_href); - return; - } - - // Terminates at root where ../package.json equals ../../package.json - // (can't just check "/package.json" for Windows support). - if (package_json_url->get_pathname() == last_pathname) { + auto parent_path = current_path.parent_path(); + // If the parent directory is the same as the current directory, stop searching + if (parent_path == current_path) { break; } + current_path = parent_path; } - auto package_json_url_as_path = - url::FileURLToPath(realm->env(), *package_json_url); - CHECK(package_json_url_as_path); + // No package.json found, return the last searched path + auto package_json_path = (current_path / "package.json").generic_string(); return args.GetReturnValue().Set( String::NewFromUtf8(realm->isolate(), - package_json_url_as_path->c_str(), + package_json_path.c_str(), NewStringType::kNormal, - package_json_url_as_path->size()) + package_json_path.size()) .ToLocalChecked()); }