(id: string, absParentPath: string)
| 296 | } |
| 297 | |
| 298 | private resolveNodeModule(id: string, absParentPath: string): Resolution { |
| 299 | if (! Resolver.isTopLevel(id)) { |
| 300 | return null; |
| 301 | } |
| 302 | |
| 303 | if (Resolver.isNative(id) && |
| 304 | archMatches(this.targetArch, "os")) { |
| 305 | // Forbid installing any server module with the same name as a |
| 306 | // native Node module. |
| 307 | return null; |
| 308 | } |
| 309 | |
| 310 | let sourceRoot: string | undefined; |
| 311 | const relParentPath = pathRelative(this.sourceRoot, absParentPath); |
| 312 | if (! relParentPath.startsWith("..")) { |
| 313 | // If the file is contained by this.sourceRoot, then it's safe to |
| 314 | // use this.sourceRoot as the limiting ancestor directory in the |
| 315 | // while loop below, but we're still going to check whether the file |
| 316 | // resides in an external node_modules directory, since "external" |
| 317 | // .npm/package/node_modules directories are technically contained |
| 318 | // within the root directory of their packages. |
| 319 | sourceRoot = this.sourceRoot; |
| 320 | } |
| 321 | |
| 322 | this.nodeModulesPaths.some(path => { |
| 323 | if (! pathRelative(path, absParentPath).startsWith("..")) { |
| 324 | // If the file is inside an external node_modules directory, |
| 325 | // consider the rootDir to be the parent directory of that |
| 326 | // node_modules directory, rather than this.sourceRoot. |
| 327 | return sourceRoot = pathDirname(path); |
| 328 | } |
| 329 | }); |
| 330 | |
| 331 | let resolved = null; |
| 332 | |
| 333 | if (sourceRoot) { |
| 334 | let dir = absParentPath; // It's ok for absParentPath to be a directory! |
| 335 | let dirStat = this.statOrNull(dir); |
| 336 | if (! (dirStat && dirStat.isDirectory())) { |
| 337 | dir = pathDirname(dir); |
| 338 | } |
| 339 | |
| 340 | while (! (resolved = this.joinAndStat(dir, "node_modules", id))) { |
| 341 | if (dir === sourceRoot) { |
| 342 | break; |
| 343 | } |
| 344 | |
| 345 | const parentDir = pathDirname(dir); |
| 346 | if (dir === parentDir) { |
| 347 | // We've reached the root of the file system?? |
| 348 | break; |
| 349 | } |
| 350 | |
| 351 | dir = parentDir; |
| 352 | } |
| 353 | } |
| 354 | |
| 355 | if (! resolved) { |
no test coverage detected