Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: sindresorhus/tempy
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: ae6e6a26a506759e5f19cb128d139bf018129d88
Choose a base ref
...
head repository: sindresorhus/tempy
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 943ade0c935367117adbe2b690516ebc94139c6d
Choose a head ref
  • 10 commits
  • 7 files changed
  • 2 contributors

Commits on Apr 16, 2020

  1. Meta tweaks

    sindresorhus committed Apr 16, 2020
    Copy the full SHA
    37229ce View commit details

Commits on Jul 17, 2020

  1. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    1a64f8b View commit details

Commits on Jul 18, 2020

  1. Allow setting a prefix for temp directory (#20)

    Co-authored-by: Sindre Sorhus <sindresorhus@gmail.com>
    Richienb and sindresorhus authored Jul 18, 2020

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    f7fc51f View commit details
  2. Meta tweaks

    sindresorhus committed Jul 18, 2020

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    ae9af82 View commit details
  3. 0.6.0

    sindresorhus committed Jul 18, 2020

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    77204fe View commit details

Commits on Aug 30, 2020

  1. Copy the full SHA
    c6e32f1 View commit details

Commits on Sep 13, 2020

  1. Add cleanup methods (#25)

    Co-authored-by: Sindre Sorhus <sindresorhus@gmail.com>
    Richienb and sindresorhus authored Sep 13, 2020
    Copy the full SHA
    96592fe View commit details
  2. 0.7.0

    sindresorhus committed Sep 13, 2020
    Copy the full SHA
    e7b4c4f View commit details

Commits on Sep 26, 2020

  1. Update dependencies

    sindresorhus committed Sep 26, 2020
    Copy the full SHA
    709bd3d View commit details
  2. 0.7.1

    sindresorhus committed Sep 26, 2020
    Copy the full SHA
    943ade0 View commit details
Showing with 253 additions and 75 deletions.
  1. +1 −0 .travis.yml
  2. +127 −53 index.d.ts
  3. +17 −3 index.js
  4. +13 −3 index.test-d.ts
  5. +13 −5 package.json
  6. +49 −8 readme.md
  7. +33 −3 test.js
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
language: node_js
node_js:
- '14'
- '12'
- '10'
180 changes: 127 additions & 53 deletions index.d.ts
Original file line number Diff line number Diff line change
@@ -2,78 +2,152 @@
import {MergeExclusive, TypedArray} from 'type-fest';

declare namespace tempy {
type Options = MergeExclusive<
{
/**
type FileOptions = MergeExclusive<
{
/**
File extension.
Mutually exclusive with the `name` option.
_You usually won't need this option. Specify it only when actually needed._
*/
readonly extension?: string;
},
{
/**
readonly extension?: string;
},
{
/**
Filename.
Mutually exclusive with the `extension` option.
_You usually won't need this option. Specify it only when actually needed._
*/
readonly name?: string;
}
readonly name?: string;
}
>;
}

declare const tempy: {
/**
Get a temporary file path you can write to.
@example
```
import tempy = require('tempy');

tempy.file();
//=> '/private/var/folders/3x/jf5977fn79jbglr7rk0tq4d00000gn/T/4f504b9edb5ba0e89451617bf9f971dd'
type DirectoryOptions = {
/**
_You usually won't need this option. Specify it only when actually needed._
tempy.file({extension: 'png'});
//=> '/private/var/folders/3x/jf5977fn79jbglr7rk0tq4d00000gn/T/a9fb0decd08179eb6cf4691568aa2018.png'
Directory prefix.
tempy.file({name: 'unicorn.png'});
//=> '/private/var/folders/3x/jf5977fn79jbglr7rk0tq4d00000gn/T/f7f62bfd4e2a05f1589947647ed3f9ec/unicorn.png'
tempy.directory();
//=> '/private/var/folders/3x/jf5977fn79jbglr7rk0tq4d00000gn/T/2f3d094aec2cb1b93bb0f4cffce5ebd6'
```
*/
file(options?: tempy.Options): string;
Useful for testing by making it easier to identify cache directories that are created.
*/
readonly prefix?: string;
};

/**
Get a temporary directory path. The directory is created for you.
@example
```
import tempy = require('tempy');
tempy.directory();
//=> '/private/var/folders/3x/jf5977fn79jbglr7rk0tq4d00000gn/T/2f3d094aec2cb1b93bb0f4cffce5ebd6'
```
The temporary path created by the function. Can be asynchronous.
*/
directory(): string;

/**
Write data to a random temp file.
@example
```
import tempy = require('tempy');
type TaskCallback = (tempPath: string) => Promise<void> | void;
}

await tempy.write('🦄');
//=> '/private/var/folders/3x/jf5977fn79jbglr7rk0tq4d00000gn/T/2f3d094aec2cb1b93bb0f4cffce5ebd6'
```
*/
write(fileContent: string | Buffer | TypedArray | DataView | NodeJS.ReadableStream, options?: tempy.Options): Promise<string>;
declare const tempy: {
file: {
/**
The `callback` resolves with a temporary file path you can write to. The file is automatically cleaned up after the callback is executed.
@returns A promise that resolves after the callback is executed and the file is cleaned up.
@example
```
import tempy = require('tempy');
await tempy.file.task(tempFile => {
console.log(tempFile);
//=> '/private/var/folders/3x/jf5977fn79jbglr7rk0tq4d00000gn/T/4f504b9edb5ba0e89451617bf9f971dd'
});
```
*/
task: (callback: tempy.TaskCallback, options?: tempy.FileOptions) => Promise<void>;

/**
Get a temporary file path you can write to.
@example
```
import tempy = require('tempy');
tempy.file();
//=> '/private/var/folders/3x/jf5977fn79jbglr7rk0tq4d00000gn/T/4f504b9edb5ba0e89451617bf9f971dd'
tempy.file({extension: 'png'});
//=> '/private/var/folders/3x/jf5977fn79jbglr7rk0tq4d00000gn/T/a9fb0decd08179eb6cf4691568aa2018.png'
tempy.file({name: 'unicorn.png'});
//=> '/private/var/folders/3x/jf5977fn79jbglr7rk0tq4d00000gn/T/f7f62bfd4e2a05f1589947647ed3f9ec/unicorn.png'
tempy.directory();
//=> '/private/var/folders/3x/jf5977fn79jbglr7rk0tq4d00000gn/T/2f3d094aec2cb1b93bb0f4cffce5ebd6'
```
*/
(options?: tempy.FileOptions): string;
};

directory: {
/**
The `callback` resolves with a temporary directory path you can write to. The directory is automatically cleaned up after the callback is executed.
@returns A promise that resolves after the callback is executed and the directory is cleaned up.
@example
```
import tempy = require('tempy');
await tempy.directory.task(tempDirectory => {
//=> '/private/var/folders/3x/jf5977fn79jbglr7rk0tq4d00000gn/T/2f3d094aec2cb1b93bb0f4cffce5ebd6'
})
```
*/
task: (callback: tempy.TaskCallback, options?: tempy.DirectoryOptions) => Promise<void>;

/**
Get a temporary directory path. The directory is created for you.
@example
```
import tempy = require('tempy');
tempy.directory();
//=> '/private/var/folders/3x/jf5977fn79jbglr7rk0tq4d00000gn/T/2f3d094aec2cb1b93bb0f4cffce5ebd6'
tempy.directory({prefix: 'a'});
//=> '/private/var/folders/3x/jf5977fn79jbglr7rk0tq4d00000gn/T/name_3c085674ad31223b9653c88f725d6b41'
```
*/
(options?: tempy.DirectoryOptions): string;
};

write: {
/**
Write data to a random temp file. The file is automatically cleaned up after the callback is executed.
@returns A promise that resolves after the callback is executed and the file is cleaned up.
@example
```
import tempy = require('tempy');
await tempy.write.task('🦄', tempFile => {
//=> '/private/var/folders/3x/jf5977fn79jbglr7rk0tq4d00000gn/T/4f504b9edb5ba0e89451617bf9f971dd'
});
```
*/
task: (fileContent: string | Buffer | TypedArray | DataView | NodeJS.ReadableStream, callback: tempy.TaskCallback, options?: tempy.FileOptions) => Promise<void>;

/**
Write data to a random temp file.
@example
```
import tempy = require('tempy');
await tempy.write('🦄');
//=> '/private/var/folders/3x/jf5977fn79jbglr7rk0tq4d00000gn/T/2f3d094aec2cb1b93bb0f4cffce5ebd6'
```
*/
(fileContent: string | Buffer | TypedArray | DataView | NodeJS.ReadableStream, options?: tempy.FileOptions): Promise<string>;
};

/**
Synchronously write data to a random temp file.
@@ -86,7 +160,7 @@ declare const tempy: {
//=> '/private/var/folders/3x/jf5977fn79jbglr7rk0tq4d00000gn/T/2f3d094aec2cb1b93bb0f4cffce5ebd6'
```
*/
writeSync(fileContent: string | Buffer | TypedArray | DataView, options?: tempy.Options): string;
writeSync: (fileContent: string | Buffer | TypedArray | DataView, options?: tempy.FileOptions) => string;

/**
Get the root temporary directory path.
20 changes: 17 additions & 3 deletions index.js
Original file line number Diff line number Diff line change
@@ -4,16 +4,24 @@ const path = require('path');
const uniqueString = require('unique-string');
const tempDir = require('temp-dir');
const isStream = require('is-stream');
const del = require('del');
const stream = require('stream');
const {promisify} = require('util');

const pipeline = promisify(stream.pipeline);
const {writeFile} = fs.promises;

const getPath = () => path.join(tempDir, uniqueString());
const getPath = (prefix = '') => path.join(tempDir, prefix + uniqueString());

const writeStream = async (filePath, data) => pipeline(data, fs.createWriteStream(filePath));

const createTask = (tempyFunction, {extraArguments = 0} = {}) => async (...arguments_) => {
const [callback, options] = arguments_.slice(extraArguments);
const result = await tempyFunction(...arguments_.slice(0, extraArguments), options);
await callback(result);
await del(result, {force: true});
};

module.exports.file = options => {
options = {
...options
@@ -30,19 +38,25 @@ module.exports.file = options => {
return getPath() + (options.extension === undefined || options.extension === null ? '' : '.' + options.extension.replace(/^\./, ''));
};

module.exports.directory = () => {
const directory = getPath();
module.exports.file.task = createTask(module.exports.file);

module.exports.directory = ({prefix = ''} = {}) => {
const directory = getPath(prefix);
fs.mkdirSync(directory);
return directory;
};

module.exports.directory.task = createTask(module.exports.directory);

module.exports.write = async (data, options) => {
const filename = module.exports.file(options);
const write = isStream(data) ? writeStream : writeFile;
await write(filename, data);
return filename;
};

module.exports.write.task = createTask(module.exports.write, {extraArguments: 1});

module.exports.writeSync = (data, options) => {
const filename = module.exports.file(options);
fs.writeFileSync(filename, data);
16 changes: 13 additions & 3 deletions index.test-d.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
import {expectType, expectError} from 'tsd';
import tempy = require('.');

const options: tempy.Options = {};
const options: tempy.FileOptions = {}; // eslint-disable-line @typescript-eslint/no-unused-vars
expectType<string>(tempy.directory());
expectType<string>(tempy.directory({prefix: 'name_'}));
expectType<string>(tempy.file());
expectType<Promise<void>>(tempy.file.task(temporaryFile => {
expectType<string>(temporaryFile);
}));
expectType<Promise<void>>(tempy.directory.task(temporaryDirectory => {
expectType<string>(temporaryDirectory);
}));
expectType<string>(tempy.file({extension: 'png'}));
expectType<string>(tempy.file({name: 'afile.txt'}));
expectError(tempy.file({extension: 'png', name: 'afile.txt'}));
@@ -12,8 +19,11 @@ expectType<string>(tempy.root);
expectType<Promise<string>>(tempy.write('unicorn'));
expectType<Promise<string>>(tempy.write('unicorn', {name: 'pony.png'}));
expectType<Promise<string>>(tempy.write(process.stdin, {name: 'pony.png'}));
expectType<Promise<string>>(tempy.write(new Buffer('pony'), {name: 'pony.png'}));
expectType<Promise<string>>(tempy.write(Buffer.from('pony'), {name: 'pony.png'}));
expectType<Promise<void>>(tempy.write.task('', temporaryFile => {
expectType<string>(temporaryFile);
}));

expectType<string>(tempy.writeSync('unicorn'));
expectType<string>(tempy.writeSync(new Buffer('unicorn')));
expectType<string>(tempy.writeSync(Buffer.from('unicorn')));
expectType<string>(tempy.writeSync('unicorn', {name: 'pony.png'}));
18 changes: 13 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "tempy",
"version": "0.5.0",
"version": "0.7.1",
"description": "Get a random temporary file or directory path",
"license": "MIT",
"repository": "sindresorhus/tempy",
@@ -35,14 +35,22 @@
"unique"
],
"dependencies": {
"del": "^6.0.0",
"is-stream": "^2.0.0",
"temp-dir": "^2.0.0",
"type-fest": "^0.12.0",
"type-fest": "^0.16.0",
"unique-string": "^2.0.0"
},
"devDependencies": {
"ava": "^1.4.1",
"tsd": "^0.11.0",
"xo": "^0.25.4"
"ava": "^2.4.0",
"path-exists": "^4.0.0",
"touch": "^3.1.0",
"tsd": "^0.13.1",
"xo": "^0.33.1"
},
"xo": {
"rules": {
"node/no-unsupported-features/node-builtins": "off"
}
}
}
57 changes: 49 additions & 8 deletions readme.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# tempy [![Build Status](https://travis-ci.org/sindresorhus/tempy.svg?branch=master)](https://travis-ci.org/sindresorhus/tempy)
# tempy [![Build Status](https://travis-ci.com/sindresorhus/tempy.svg?branch=master)](https://travis-ci.com/github/sindresorhus/tempy)

> Get a random temporary file or directory path
@@ -24,6 +24,9 @@ tempy.file({name: 'unicorn.png'});

tempy.directory();
//=> '/private/var/folders/3x/jf5977fn79jbglr7rk0tq4d00000gn/T/2f3d094aec2cb1b93bb0f4cffce5ebd6'

tempy.directory({prefix: 'name'});
//=> '/private/var/folders/3x/jf5977fn79jbglr7rk0tq4d00000gn/T/name_3c085674ad31223b9653c88f725d6b41'
```

## API
@@ -32,6 +35,16 @@ tempy.directory();

Get a temporary file path you can write to.

### tempy.file.task(callback, options?)

The `callback` resolves with a temporary file path you can write to. The file is automatically cleaned up after the callback is executed. Returns a promise that resolves after the callback is executed and the file is cleaned up.

#### callback

Type: `(tempPath: string) => void`

A callback that is executed with the temp file path. Can be asynchronous.

#### options

Type: `object`
@@ -50,20 +63,54 @@ Type: `string`

Filename. Mutually exclusive with the `extension` option.

### tempy.directory()
### tempy.directory(options?)

Get a temporary directory path. The directory is created for you.

### tempy.directory.task(callback, options?)

The `callback` resolves with a temporary directory path you can write to. The directory is automatically cleaned up after the callback is executed. Returns a promise that resolves after the callback is executed and the directory is cleaned up.

##### callback

Type: `(tempPath: string) => void`

A callback that is executed with the temp directory path. Can be asynchronous.

#### options

Type: `Object`

##### prefix

Type: `string`

Directory prefix.

Useful for testing by making it easier to identify cache directories that are created.

*You usually won't need this option. Specify it only when actually needed.*

### tempy.write(fileContent, options?)

Write data to a random temp file.

### tempy.write.task(fileContent, callback, options?)

Write data to a random temp file. The file is automatically cleaned up after the callback is executed. Returns a promise that resolves after the callback is executed and the file is cleaned up.

##### fileContent

Type: `string | Buffer | TypedArray | DataView | stream.Readable`

Data to write to the temp file.

##### callback

Type: `(tempPath: string) => void`

A callback that is executed with the temp file path. Can be asynchronous.

##### options

See [options](#options).
@@ -85,9 +132,3 @@ See [options](#options).
### tempy.root

Get the root temporary directory path. For example: `/private/var/folders/3x/jf5977fn79jbglr7rk0tq4d00000gn/T`

## FAQ

#### Why doesn't it have a cleanup method?

Temp files will be periodically cleaned up on macOS. Most Linux distros will clean up on reboot. If you're generating a lot of temp files, it's recommended to use a complementary module like [`del`](https://github.com/sindresorhus/del) for cleanup.
36 changes: 33 additions & 3 deletions test.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import path from 'path';
import {tmpdir} from 'os';
import tempDir from 'temp-dir';
import pathExists from 'path-exists';
import touch from 'touch';
import fs from 'fs';
import stream from 'stream';
import test from 'ava';
import tempy from '.';

test('.file()', t => {
t.true(tempy.file().includes(tmpdir()));
t.true(tempy.file().includes(tempDir));
t.false(tempy.file().endsWith('.'));
t.false(tempy.file({extension: undefined}).endsWith('.'));
t.false(tempy.file({extension: null}).endsWith('.'));
@@ -32,8 +34,28 @@ test('.file()', t => {
});
});

test('.file.task()', async t => {
let temporaryFilePath;
await tempy.file.task(async temporaryFile => {
await touch(temporaryFile);
temporaryFilePath = temporaryFile;
});
t.false(await pathExists(temporaryFilePath));
});

test('.directory()', t => {
t.true(tempy.directory().includes(tmpdir()));
const prefix = 'name_';

t.true(tempy.directory().includes(tempDir));
t.true(path.basename(tempy.directory({prefix})).startsWith(prefix));
});

test('.directory.task()', async t => {
let temporaryDirectoryPath;
await tempy.directory.task(async temporaryDirectory => {
temporaryDirectoryPath = temporaryDirectory;
});
t.false(await pathExists(temporaryDirectoryPath));
});

test('.write(string)', async t => {
@@ -42,6 +64,14 @@ test('.write(string)', async t => {
t.is(path.basename(filePath), 'test.png');
});

test('.write.task(string)', async t => {
let temporaryFilePath;
await tempy.write.task('', async temporaryFile => {
temporaryFilePath = temporaryFile;
});
t.false(await pathExists(temporaryFilePath));
});

test('.write(buffer)', async t => {
const filePath = await tempy.write(Buffer.from('unicorn'));
t.is(fs.readFileSync(filePath, 'utf8'), 'unicorn');