| const { dirname, resolve } = require('path') | 
|   | 
| const fileURLToPath = require('./file-url-to-path/index.js') | 
| const fs = require('../fs.js') | 
|   | 
| // given a path, find the owner of the nearest parent | 
| const find = async (path) => { | 
|   // if we have no getuid, permissions are irrelevant on this platform | 
|   if (!process.getuid) { | 
|     return {} | 
|   } | 
|   | 
|   // fs methods accept URL objects with a scheme of file: so we need to unwrap | 
|   // those into an actual path string before we can resolve it | 
|   const resolved = path != null && path.href && path.origin | 
|     ? resolve(fileURLToPath(path)) | 
|     : resolve(path) | 
|   | 
|   let stat | 
|   | 
|   try { | 
|     stat = await fs.lstat(resolved) | 
|   } finally { | 
|     // if we got a stat, return its contents | 
|     if (stat) { | 
|       return { uid: stat.uid, gid: stat.gid } | 
|     } | 
|   | 
|     // try the parent directory | 
|     if (resolved !== dirname(resolved)) { | 
|       return find(dirname(resolved)) | 
|     } | 
|   | 
|     // no more parents, never got a stat, just return an empty object | 
|     return {} | 
|   } | 
| } | 
|   | 
| // given a path, uid, and gid update the ownership of the path if necessary | 
| const update = async (path, uid, gid) => { | 
|   // nothing to update, just exit | 
|   if (uid === undefined && gid === undefined) { | 
|     return | 
|   } | 
|   | 
|   try { | 
|     // see if the permissions are already the same, if they are we don't | 
|     // need to do anything, so return early | 
|     const stat = await fs.stat(path) | 
|     if (uid === stat.uid && gid === stat.gid) { | 
|       return | 
|     } | 
|   } catch (err) {} | 
|   | 
|   try { | 
|     await fs.chown(path, uid, gid) | 
|   } catch (err) {} | 
| } | 
|   | 
| // accepts a `path` and the `owner` property of an options object and normalizes | 
| // it into an object with numerical `uid` and `gid` | 
| const validate = async (path, input) => { | 
|   let uid | 
|   let gid | 
|   | 
|   if (typeof input === 'string' || typeof input === 'number') { | 
|     uid = input | 
|     gid = input | 
|   } else if (input && typeof input === 'object') { | 
|     uid = input.uid | 
|     gid = input.gid | 
|   } | 
|   | 
|   if (uid === 'inherit' || gid === 'inherit') { | 
|     const owner = await find(path) | 
|     if (uid === 'inherit') { | 
|       uid = owner.uid | 
|     } | 
|   | 
|     if (gid === 'inherit') { | 
|       gid = owner.gid | 
|     } | 
|   } | 
|   | 
|   return { uid, gid } | 
| } | 
|   | 
| module.exports = { | 
|   find, | 
|   update, | 
|   validate, | 
| } |