Skip to content

Commit

Permalink
Add methods for writing data to temp files (#22)
Browse files Browse the repository at this point in the history
Co-authored-by: Sindre Sorhus <sindresorhus@gmail.com>
  • Loading branch information
Richienb and sindresorhus authored Mar 9, 2020
1 parent a2c7198 commit 532be0c
Show file tree
Hide file tree
Showing 6 changed files with 131 additions and 2 deletions.
29 changes: 28 additions & 1 deletion index.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {MergeExclusive} from 'type-fest';
/// <reference types="node"/>
import {MergeExclusive, TypedArray} from 'type-fest';

declare namespace tempy {
type Options = MergeExclusive<
Expand Down Expand Up @@ -61,6 +62,32 @@ declare const tempy: {
*/
directory(): string;

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

/**
Synchronously write data to a random temp file.
@example
```
import tempy = require('tempy');
tempy.writeSync('🦄');
//=> '/private/var/folders/3x/jf5977fn79jbglr7rk0tq4d00000gn/T/2f3d094aec2cb1b93bb0f4cffce5ebd6'
```
*/
writeSync(fileContent: string | Buffer | TypedArray | DataView, options?: tempy.Options): string;

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

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

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

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

module.exports.file = options => {
options = {
...options
Expand All @@ -28,6 +36,19 @@ module.exports.directory = () => {
return 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.writeSync = (data, options) => {
const filename = module.exports.file(options);
fs.writeFileSync(filename, data);
return filename;
};

Object.defineProperty(module.exports, 'root', {
get() {
return tempDir;
Expand Down
9 changes: 9 additions & 0 deletions index.test-d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,12 @@ expectType<string>(tempy.file({extension: 'png'}));
expectType<string>(tempy.file({name: 'afile.txt'}));
expectError(tempy.file({extension: 'png', name: 'afile.txt'}));
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<string>(tempy.writeSync('unicorn'));
expectType<string>(tempy.writeSync(new Buffer('unicorn')));
expectType<string>(tempy.writeSync('unicorn', {name: 'pony.png'}));
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,9 @@
"unique"
],
"dependencies": {
"is-stream": "^2.0.0",
"temp-dir": "^2.0.0",
"type-fest": "^0.10.0",
"type-fest": "^0.11.0",
"unique-string": "^2.0.0"
},
"devDependencies": {
Expand Down
28 changes: 28 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,34 @@ Filename. Mutually exclusive with the `extension` option.

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

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

Write data to a random temp file.

##### fileContent

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

Data to write to the temp file.

##### options

See [options](#options).

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

Synchronously write data to a random temp file.

##### fileContent

Type: `string | Buffer | TypedArray | DataView`

Data to write to the temp file.

##### options

See [options](#options).

### tempy.root

Get the root temporary directory path. For example: `/private/var/folders/3x/jf5977fn79jbglr7rk0tq4d00000gn/T`
Expand Down
43 changes: 43 additions & 0 deletions test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import path from 'path';
import {tmpdir} from 'os';
import fs from 'fs';
import stream from 'stream';
import test from 'ava';
import tempy from '.';

Expand Down Expand Up @@ -34,9 +36,50 @@ test('.directory()', t => {
t.true(tempy.directory().includes(tmpdir()));
});

test('.write(string)', async t => {
const filePath = await tempy.write('unicorn', {name: 'test.png'});
t.is(fs.readFileSync(filePath, 'utf8'), 'unicorn');
t.is(path.basename(filePath), 'test.png');
});

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

test('.write(stream)', async t => {
const readable = new stream.Readable({
read() {}
});
readable.push('unicorn');
readable.push(null);
const filePath = await tempy.write(readable);
t.is(fs.readFileSync(filePath, 'utf8'), 'unicorn');
});

test('.write(stream) failing stream', async t => {
const readable = new stream.Readable({
read() {}
});
readable.push('unicorn');
setImmediate(() => {
readable.emit('error', new Error('Catch me if you can!'));
readable.push(null);
});
await t.throwsAsync(() => tempy.write(readable), {
instanceOf: Error,
message: 'Catch me if you can!'
});
});

test('.writeSync()', t => {
t.is(fs.readFileSync(tempy.writeSync('unicorn'), 'utf8'), 'unicorn');
});

test('.root', t => {
t.true(tempy.root.length > 0);
t.true(path.isAbsolute(tempy.root));

t.throws(() => {
tempy.root = 'foo';
});
Expand Down

0 comments on commit 532be0c

Please sign in to comment.