UNPKG

2.1 kBJavaScriptView Raw
1import fs from 'node:fs';
2import fsPromises from 'node:fs/promises';
3import path from 'node:path';
4import stream from 'node:stream';
5import {promisify} from 'node:util';
6import uniqueString from 'unique-string';
7import tempDir from 'temp-dir';
8import {isStream} from 'is-stream';
9
10const pipeline = promisify(stream.pipeline); // TODO: Use `node:stream/promises` when targeting Node.js 16.
11
12const getPath = (prefix = '') => path.join(tempDir, prefix + uniqueString());
13
14const writeStream = async (filePath, data) => pipeline(data, fs.createWriteStream(filePath));
15
16async function runTask(temporaryPath, callback) {
17 try {
18 return await callback(temporaryPath);
19 } finally {
20 await fsPromises.rm(temporaryPath, {recursive: true, force: true, maxRetries: 2});
21 }
22}
23
24export function temporaryFile({name, extension} = {}) {
25 if (name) {
26 if (extension !== undefined && extension !== null) {
27 throw new Error('The `name` and `extension` options are mutually exclusive');
28 }
29
30 return path.join(temporaryDirectory(), name);
31 }
32
33 return getPath() + (extension === undefined || extension === null ? '' : '.' + extension.replace(/^\./, ''));
34}
35
36export const temporaryFileTask = async (callback, options) => runTask(temporaryFile(options), callback);
37
38export function temporaryDirectory({prefix = ''} = {}) {
39 const directory = getPath(prefix);
40 fs.mkdirSync(directory);
41 return directory;
42}
43
44export const temporaryDirectoryTask = async (callback, options) => runTask(temporaryDirectory(options), callback);
45
46export async function temporaryWrite(fileContent, options) {
47 const filename = temporaryFile(options);
48 const write = isStream(fileContent) ? writeStream : fsPromises.writeFile;
49 await write(filename, fileContent);
50 return filename;
51}
52
53export const temporaryWriteTask = async (fileContent, callback, options) => runTask(await temporaryWrite(fileContent, options), callback);
54
55export function temporaryWriteSync(fileContent, options) {
56 const filename = temporaryFile(options);
57 fs.writeFileSync(filename, fileContent);
58 return filename;
59}
60
61export {default as rootTemporaryDirectory} from 'temp-dir';