1const { join, sep } = require('path') 2 3const getOptions = require('./common/get-options.js') 4const { mkdir, mkdtemp, rm } = require('fs/promises') 5 6// create a temp directory, ensure its permissions match its parent, then call 7// the supplied function passing it the path to the directory. clean up after 8// the function finishes, whether it throws or not 9const withTempDir = async (root, fn, opts) => { 10 const options = getOptions(opts, { 11 copy: ['tmpPrefix'], 12 }) 13 // create the directory 14 await mkdir(root, { recursive: true }) 15 16 const target = await mkdtemp(join(`${root}${sep}`, options.tmpPrefix || '')) 17 let err 18 let result 19 20 try { 21 result = await fn(target) 22 } catch (_err) { 23 err = _err 24 } 25 26 try { 27 await rm(target, { force: true, recursive: true }) 28 } catch { 29 // ignore errors 30 } 31 32 if (err) { 33 throw err 34 } 35 36 return result 37} 38 39module.exports = withTempDir 40