| const cache = new Map() | 
| const fs = require('fs') | 
| const { dirname, resolve } = require('path') | 
|   | 
|   | 
| const lstat = path => new Promise((res, rej) => | 
|   fs.lstat(path, (er, st) => er ? rej(er) : res(st))) | 
|   | 
| const inferOwner = path => { | 
|   path = resolve(path) | 
|   if (cache.has(path)) | 
|     return Promise.resolve(cache.get(path)) | 
|   | 
|   const statThen = st => { | 
|     const { uid, gid } = st | 
|     cache.set(path, { uid, gid }) | 
|     return { uid, gid } | 
|   } | 
|   const parent = dirname(path) | 
|   const parentTrap = parent === path ? null : er => { | 
|     return inferOwner(parent).then((owner) => { | 
|       cache.set(path, owner) | 
|       return owner | 
|     }) | 
|   } | 
|   return lstat(path).then(statThen, parentTrap) | 
| } | 
|   | 
| const inferOwnerSync = path => { | 
|   path = resolve(path) | 
|   if (cache.has(path)) | 
|     return cache.get(path) | 
|   | 
|   const parent = dirname(path) | 
|   | 
|   // avoid obscuring call site by re-throwing | 
|   // "catch" the error by returning from a finally, | 
|   // only if we're not at the root, and the parent call works. | 
|   let threw = true | 
|   try { | 
|     const st = fs.lstatSync(path) | 
|     threw = false | 
|     const { uid, gid } = st | 
|     cache.set(path, { uid, gid }) | 
|     return { uid, gid } | 
|   } finally { | 
|     if (threw && parent !== path) { | 
|       const owner = inferOwnerSync(parent) | 
|       cache.set(path, owner) | 
|       return owner // eslint-disable-line no-unsafe-finally | 
|     } | 
|   } | 
| } | 
|   | 
| const inflight = new Map() | 
| module.exports = path => { | 
|   path = resolve(path) | 
|   if (inflight.has(path)) | 
|     return Promise.resolve(inflight.get(path)) | 
|   const p = inferOwner(path).then(owner => { | 
|     inflight.delete(path) | 
|     return owner | 
|   }) | 
|   inflight.set(path, p) | 
|   return p | 
| } | 
| module.exports.sync = inferOwnerSync | 
| module.exports.clearCache = () => { | 
|   cache.clear() | 
|   inflight.clear() | 
| } |