| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent abecdcb commit ac78491
4 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -6,7 +6,9 @@ const { | |||
| 6 | 6 | ObjectDefineProperty, | |
| 7 | 7 | RegExpPrototypeExec, | |
| 8 | 8 | SafeMap, | |
| 9 | + StringPrototypeEndsWith, | ||
| 9 | 10 | StringPrototypeIndexOf, | |
| 11 | + StringPrototypeLastIndexOf, | ||
| 10 | 12 | StringPrototypeSlice, | |
| 11 | 13 | } = primordials; | |
| 12 | 14 | const { | |
@@ -26,6 +28,7 @@ const { | |||
| 26 | 28 | const { kEmptyObject } = require('internal/util'); | |
| 27 | 29 | const modulesBinding = internalBinding('modules'); | |
| 28 | 30 | const path = require('path'); | |
| 31 | + const permission = require('internal/process/permission'); | ||
| 29 | 32 | const { validateString } = require('internal/validators'); | |
| 30 | 33 | const internalFsBinding = internalBinding('fs'); | |
| 31 | 34 | ||
@@ -127,26 +130,71 @@ function read(jsonPath, { base, specifier, isESM } = kEmptyObject) { | |||
| 127 | 130 | }; | |
| 128 | 131 | } | |
| 129 | 132 | ||
| 133 | + /** | ||
| 134 | + * Given a file path, walk the filesystem upwards until we find its closest parent | ||
| 135 | + * `package.json` file, stopping when: | ||
| 136 | + * 1. we find a `package.json` file; | ||
| 137 | + * 2. we find a path that we do not have permission to read; | ||
| 138 | + * 3. we find a containing `node_modules` directory; | ||
| 139 | + * 4. or, we reach the filesystem root | ||
| 140 | + * @returns {undefined | string} | ||
| 141 | + */ | ||
| 142 | + function findParentPackageJSON(checkPath) { | ||
| 143 | + const enabledPermission = permission.isEnabled(); | ||
| 144 | + | ||
| 145 | + const rootSeparatorIndex = StringPrototypeIndexOf(checkPath, path.sep); | ||
| 146 | + let separatorIndex; | ||
| 147 | + | ||
| 148 | + do { | ||
| 149 | + separatorIndex = StringPrototypeLastIndexOf(checkPath, path.sep); | ||
| 150 | + checkPath = StringPrototypeSlice(checkPath, 0, separatorIndex); | ||
| 151 | + | ||
| 152 | + if (enabledPermission && !permission.has('fs.read', checkPath + path.sep)) { | ||
| 153 | + return undefined; | ||
| 154 | + } | ||
| 155 | + | ||
| 156 | + if (StringPrototypeEndsWith(checkPath, path.sep + 'node_modules')) { | ||
| 157 | + return undefined; | ||
| 158 | + } | ||
| 159 | + | ||
| 160 | + const maybePackageJSONPath = checkPath + path.sep + 'package.json'; | ||
| 161 | + const stat = internalFsBinding.internalModuleStat(checkPath + path.sep + 'package.json'); | ||
| 162 | + | ||
| 163 | + const packageJSONExists = stat === 0; | ||
| 164 | + if (packageJSONExists) { | ||
| 165 | + return maybePackageJSONPath; | ||
| 166 | + } | ||
| 167 | + } while (separatorIndex > rootSeparatorIndex); | ||
| 168 | + | ||
| 169 | + return undefined; | ||
| 170 | + } | ||
| 171 | + | ||
| 130 | 172 | /** | |
| 131 | 173 | * Get the nearest parent package.json file from a given path. | |
| 132 | 174 | * Return the package.json data and the path to the package.json file, or undefined. | |
| 133 | 175 | * @param {string} checkPath The path to start searching from. | |
| 134 | 176 | * @returns {undefined | DeserializedPackageConfig} | |
| 135 | 177 | */ | |
| 136 | 178 | function getNearestParentPackageJSON(checkPath) { | |
| 137 | - if (nearestParentPackageJSONCache.has(checkPath)) { | ||
| 138 | - return nearestParentPackageJSONCache.get(checkPath); | ||
| 179 | + const nearestParentPackageJSON = findParentPackageJSON(checkPath); | ||
| 180 | + | ||
| 181 | + if (nearestParentPackageJSON === undefined) { | ||
| 182 | + return undefined; | ||
| 183 | + } | ||
| 184 | + | ||
| 185 | + if (nearestParentPackageJSONCache.has(nearestParentPackageJSON)) { | ||
| 186 | + return nearestParentPackageJSONCache.get(nearestParentPackageJSON); | ||
| 139 | 187 | } | |
| 140 | 188 | ||
| 141 | - const result = modulesBinding.getNearestParentPackageJSON(checkPath); | ||
| 189 | + const result = modulesBinding.readPackageJSON(nearestParentPackageJSON); | ||
| 142 | 190 | ||
| 143 | 191 | if (result === undefined) { | |
| 144 | 192 | nearestParentPackageJSONCache.set(checkPath, undefined); | |
| 145 | 193 | return undefined; | |
| 146 | 194 | } | |
| 147 | 195 | ||
| 148 | 196 | const packageConfig = deserializePackageJSON(checkPath, result); | |
| 149 | - nearestParentPackageJSONCache.set(checkPath, packageConfig); | ||
| 197 | + nearestParentPackageJSONCache.set(nearestParentPackageJSON, packageConfig); | ||
| 150 | 198 | ||
| 151 | 199 | return packageConfig; | |
| 152 | 200 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -320,40 +320,6 @@ const BindingData::PackageConfig* BindingData::TraverseParent( | |||
| 320 | 320 | return nullptr; | |
| 321 | 321 | } | |
| 322 | 322 | ||
| 323 | - void BindingData::GetNearestParentPackageJSON( | ||
| 324 | - const v8::FunctionCallbackInfo<v8::Value>& args) { | ||
| 325 | - CHECK_GE(args.Length(), 1); | ||
| 326 | - CHECK(args[0]->IsString()); | ||
| 327 | - | ||
| 328 | - Realm* realm = Realm::GetCurrent(args); | ||
| 329 | - BufferValue path_value(realm->isolate(), args[0]); | ||
| 330 | - // Check if the path has a trailing slash. If so, add it after | ||
| 331 | - // ToNamespacedPath() as it will be deleted by ToNamespacedPath() | ||
| 332 | - bool slashCheck = path_value.ToStringView().ends_with(kPathSeparator); | ||
| 333 | - | ||
| 334 | - ToNamespacedPath(realm->env(), &path_value); | ||
| 335 | - | ||
| 336 | - std::string path_value_str = path_value.ToString(); | ||
| 337 | - if (slashCheck) { | ||
| 338 | - path_value_str.push_back(kPathSeparator); | ||
| 339 | - } | ||
| 340 | - | ||
| 341 | - std::filesystem::path path; | ||
| 342 | - | ||
| 343 | - #ifdef _WIN32 | ||
| 344 | - std::wstring wide_path = ConvertToWideString(path_value_str, GetACP()); | ||
| 345 | - path = std::filesystem::path(wide_path); | ||
| 346 | - #else | ||
| 347 | - path = std::filesystem::path(path_value_str); | ||
| 348 | - #endif | ||
| 349 | - | ||
| 350 | - auto package_json = TraverseParent(realm, path); | ||
| 351 | - | ||
| 352 | - if (package_json != nullptr) { | ||
| 353 | - args.GetReturnValue().Set(package_json->Serialize(realm)); | ||
| 354 | - } | ||
| 355 | - } | ||
| 356 | - | ||
| 357 | 323 | void BindingData::GetNearestParentPackageJSONType( | |
| 358 | 324 | const FunctionCallbackInfo<Value>& args) { | |
| 359 | 325 | CHECK_GE(args.Length(), 1); | |
@@ -674,10 +640,6 @@ void BindingData::CreatePerIsolateProperties(IsolateData* isolate_data, | |||
| 674 | 640 | target, | |
| 675 | 641 | "getNearestParentPackageJSONType", | |
| 676 | 642 | GetNearestParentPackageJSONType); | |
| 677 | - SetMethod(isolate, | ||
| 678 | - target, | ||
| 679 | - "getNearestParentPackageJSON", | ||
| 680 | - GetNearestParentPackageJSON); | ||
| 681 | 643 | SetMethod( | |
| 682 | 644 | isolate, target, "getPackageScopeConfig", GetPackageScopeConfig<false>); | |
| 683 | 645 | SetMethod(isolate, target, "getPackageType", GetPackageScopeConfig<true>); | |
@@ -734,7 +696,6 @@ void BindingData::RegisterExternalReferences( | |||
| 734 | 696 | ExternalReferenceRegistry* registry) { | |
| 735 | 697 | registry->Register(ReadPackageJSON); | |
| 736 | 698 | registry->Register(GetNearestParentPackageJSONType); | |
| 737 | - registry->Register(GetNearestParentPackageJSON); | ||
| 738 | 699 | registry->Register(GetPackageScopeConfig<false>); | |
| 739 | 700 | registry->Register(GetPackageScopeConfig<true>); | |
| 740 | 701 | registry->Register(EnableCompileCache); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -55,8 +55,6 @@ class BindingData : public SnapshotableObject { | |||
| 55 | 55 | SET_MEMORY_INFO_NAME(BindingData) | |
| 56 | 56 | ||
| 57 | 57 | static void ReadPackageJSON(const v8::FunctionCallbackInfo<v8::Value>& args); | |
| 58 | - static void GetNearestParentPackageJSON( | ||
| 59 | - const v8::FunctionCallbackInfo<v8::Value>& args); | ||
| 60 | 58 | static void GetNearestParentPackageJSONType( | |
| 61 | 59 | const v8::FunctionCallbackInfo<v8::Value>& args); | |
| 62 | 60 | template <bool return_only_type> | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -23,7 +23,6 @@ export type SerializedPackageConfig = [ | |||
| 23 | 23 | export interface ModulesBinding { | |
| 24 | 24 | readPackageJSON(path: string): SerializedPackageConfig | undefined; | |
| 25 | 25 | getNearestParentPackageJSONType(path: string): PackageConfig['type'] | |
| 26 | - getNearestParentPackageJSON(path: string): SerializedPackageConfig | undefined | ||
| 27 | 26 | getPackageScopeConfig(path: string): SerializedPackageConfig | undefined | |
| 28 | 27 | getPackageType(path: string): PackageConfig['type'] | undefined | |
| 29 | 28 | enableCompileCache(path?: string): { status: number, message?: string, directory?: string } | |
| Back | FazBrowse Home | New Git URL |
0 commit comments