| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071 | 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 = inferOwnerSyncmodule.exports.clearCache = () => {  cache.clear()  inflight.clear()}
 |