Code Monkey home page Code Monkey logo

tempy's Introduction

tempy

Get a random temporary file or directory path

Install

npm install tempy

Usage

import {temporaryFile, temporaryDirectory} from 'tempy';

temporaryFile();
//=> '/private/var/folders/3x/jf5977fn79jbglr7rk0tq4d00000gn/T/4f504b9edb5ba0e89451617bf9f971dd'

temporaryFile({extension: 'png'});
//=> '/private/var/folders/3x/jf5977fn79jbglr7rk0tq4d00000gn/T/a9fb0decd08179eb6cf4691568aa2018.png'

temporaryFile({name: 'unicorn.png'});
//=> '/private/var/folders/3x/jf5977fn79jbglr7rk0tq4d00000gn/T/f7f62bfd4e2a05f1589947647ed3f9ec/unicorn.png'

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

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

API

temporaryFile(options?)

Get a temporary file path you can write to.

temporaryFileTask(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 with the return value of the callback after it 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

You usually won't need either the extension or name option. Specify them only when actually needed.

extension

Type: string

File extension.

name

Type: string

Filename. Mutually exclusive with the extension option.

temporaryDirectory(options?)

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

temporaryDirectoryTask(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 with the return value of the callback after it 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.

temporaryWrite(fileContent, options?)

Write data to a random temp file.

temporaryWriteTask(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 with the return value of the callback after it 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.

temporaryWriteSync(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.

rootTemporaryDirectory

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

tempy's People

Contributors

bendingbender avatar douglasduteil avatar ksr-yasuda avatar linusu avatar mrjohz avatar richienb avatar sindresorhus avatar transitive-bullshit avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

tempy's Issues

Must use import to load ES Module

Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: /home/cluster/Code/cluster-pdf-api/node_modules/tempy/index.js
require() of ES modules is not supported.
require() of /home/cluster/Code/cluster-pdf-api/node_modules/tempy/index.js from /home/cluster/Code/cluster-pdf-api/dist/document/helper/compress.js is an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which defines all .js files in that package scope as ES modules.
Instead rename index.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from /home/cluster/Code/cluster-pdf-api/node_modules/tempy/package.json.

at Object.Module._extensions..js (internal/modules/cjs/loader.js:1015:13)
at Module.load (internal/modules/cjs/loader.js:863:32)
at Function.Module._load (internal/modules/cjs/loader.js:708:14)
at Module.require (internal/modules/cjs/loader.js:887:19)
at require (internal/modules/cjs/helpers.js:74:18)
at Object.<anonymous> (/home/cluster/Code/cluster-pdf-api/src/document/helper/compress.ts:5:1)
at Module._compile (internal/modules/cjs/loader.js:999:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10)
at Module.load (internal/modules/cjs/loader.js:863:32)
at Function.Module._load (internal/modules/cjs/loader.js:708:14)
at Module.require (internal/modules/cjs/loader.js:887:19)
at require (internal/modules/cjs/helpers.js:74:18)
at Object.<anonymous> (/home/cluster/Code/cluster-pdf-api/src/document/document.service.ts:18:1)
at Module._compile (internal/modules/cjs/loader.js:999:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10)
at Module.load (internal/modules/cjs/loader.js:863:32)

Where did you find that OS will cleanup tmp dir?

The operating system will clean up when needed. No point in us wasting resources and adding complexity.

  1. Most linux distros cleanup tmp on reboot. But if system does not make reboot, tmp is not cleared
  2. Docker has no ability to run periodic cleanup script at all

Here is the example:

tmpfs            10M     0   10M   0% /home/gugu/test
gugu@container:~/test$ fallocate -l 1M t1
gugu@container:~/test$ fallocate -l 1M t2
gugu@container:~/test$ fallocate -l 1M t3
gugu@container:~/test$ fallocate -l 1M t4
gugu@container:~/test$ fallocate -l 1M t5
gugu@container:~/test$ fallocate -l 1M t6
gugu@container:~/test$ fallocate -l 1M t7
gugu@container:~/test$ fallocate -l 1M t8
gugu@container:~/test$ fallocate -l 1M t9
gugu@container:~/test$ fallocate -l 1M t10
gugu@container:~/test$ fallocate -l 1M t11
fallocate: fallocate failed: No space left on device
gugu@container:~/test$

Import issue in Cypress project

Problem:

/Users/oleksandrknyga/www/shaman/shaman-regression-scanner/node_modules/tempy/index.js:1
    ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){import fs from 'node:fs';
                                                                                             ^^^^^^

    SyntaxError: Cannot use import statement outside a module

      1 | import { validate as uuidValidate } from 'uuid'
    > 2 | import { temporaryFile } from 'tempy'
        | ^
      3 | import { Reporter } from '../index'

Package.json:

{
  "name": "...",
  "version": "...",
  "main": "index.js",
  "license": "MIT",
  "scripts": {
    "test": "jest",
    "test-watch": "jest --watch",
    "cy:open": "cypress open",
    "cy:run": "cypress run --browser chrome --headless",
    "e2e-mocha": "npx cypress run --spec 'path_to_file' --browser chrome",
    "lint": "eslint . --ext .ts",
    "lint-fix": "eslint . --ext .ts --fix"
  },
  "dependencies": {
    "@aws-sdk/client-lambda": "^3.100.0",
    "@faker-js/faker": "^6.3.1",
    "axios": "^0.27.2",
    "csv": "^6.1.0",
    "cypress": "^10.0.1",
    "mochawesome": "^7.1.3",
    "typescript": "^4.7.2",
    "uuid": "^8.3.2"
  },
  "devDependencies": {
    "@aws-sdk/types": "^3.110.0",
    "@types/chai": "^4.1.7",
    "@types/jest": "26.0.22",
    "@types/mocha": "^8.0.0",
    "@types/node": "^17.0.42",
    "@types/uuid": "^8.3.4",
    "@typescript-eslint/eslint-plugin": "^5.27.1",
    "@typescript-eslint/parser": "^5.27.1",
    "aws-sdk-client-mock": "^1.0.0",
    "eslint": "^8.17.0",
    "eslint-config-prettier": "^8.5.0",
    "eslint-plugin-cypress": "^2.12.1",
    "eslint-plugin-import": "^2.26.0",
    "eslint-plugin-jsx-a11y": "^6.5.1",
    "jest": "26.6.3",
    "tempy": "^3.0.0",
    "ts-jest": "26.5.4"
  },
  "engines": {
    "npm": ">=7.0.0",
    "node": ">=16.0.0"
  }
}

I tried to use tempy for jest tests on typescript, but import fails.

Cleanup temporary files on process.exit event.

Can there be an option to .file() and .directory() which cleans up files/directories on process.exit?

Example:
tempy.directory({ cleanup: true })

I've tried using tempy.file.task() but Jest ignores tests enclosed in any external function.
Example:

describe("Sample test", () => {
    tempy.file.task(tempFile => {

        // Both these tests dont get executed by Jest
        it("Sample 1", () => {
            expect(true).toBeTruthy() // Wanted to use the file in here.
        })
    
        it("Sample 2", () => {
            expect(true).toBeTruthy() // And the same file here again.
        })
    })
})

I can create a file/directory externally outside and then delete it myself, but that would be tedious. Temporary files on Windows don't get deleted automatically unlike on MacOS, so an option to cleanup on node process exit would be pretty convenient.

Import issue with Vite

When importing tempy from a vite project, I'm getting the following error. tempfile does not have this issue.

It seems like the node: prefix is causing a problem. Not sure if this is a vite issue or a tempy issue.

✘ [ERROR] Could not read from file: /home/brian/project/node_modules/.pnpm/[email protected]/node_modules/node-stdlib-browser/cjs/mock/empty.js/promises

    ../../node_modules/.pnpm/[email protected]/node_modules/tempy/index.js:2:23:
      2 │ import fsPromises from 'node:fs/promises';
        ╵                        ~~~~~~~~~~~~~~~~~~

parse_p_|end /home/brian/project/data/msci_detail_stage0.csv
2:06:13 AM [vite] error while updating dependencies:
Error: Build failed with 1 error:
../../node_modules/.pnpm/[email protected]/node_modules/tempy/index.js:2:23: ERROR: Could not read from file: /home/brian/project/node_modules/.pnpm/[email protected]/node_modules/node-stdlib-browser/cjs/mock/empty.js/promises
    at failureErrorWithLog (/home/brian/project/node_modules/.pnpm/[email protected]/node_modules/esbuild/lib/main.js:1591:15)
    at /home/brian/project/node_modules/.pnpm/[email protected]/node_modules/esbuild/lib/main.js:1047:28
    at runOnEndCallbacks (/home/brian/project/node_modules/.pnpm/[email protected]/node_modules/esbuild/lib/main.js:1463:61)
    at buildResponseToResult (/home/brian/project/node_modules/.pnpm/[email protected]/node_modules/esbuild/lib/main.js:1045:7)
    at /home/brian/project/node_modules/.pnpm/[email protected]/node_modules/esbuild/lib/main.js:1157:14
    at responseCallbacks.<computed> (/home/brian/project/node_modules/.pnpm/[email protected]/node_modules/esbuild/lib/main.js:694:9)
    at handleIncomingPacket (/home/brian/project/node_modules/.pnpm/[email protected]/node_modules/esbuild/lib/main.js:749:9)
    at Socket.readFromStdout (/home/brian/project/node_modules/.pnpm/[email protected]/node_modules/esbuild/lib/main.js:670:7)
    at Socket.emit (node:events:513:28)
    at addChunk (node:internal/streams/readable:324:12)
    at readableAddChunk (node:internal/streams/readable:297:9)
    at Readable.push (node:internal/streams/readable:234:10)
    at Pipe.onStreamRead (node:internal/stream_base_commons:190:23)

Getting `Error: ENOENT: no such file or directory, lstat '/var/folders'` error from tempy's use of temp-dir

Hi, I have a create-react-app running in a Docker container and suddenly started seeing this error. Any tips as to why this might be occuring? Thanks!

node:fs:2486
      handleErrorFromBinding(ctx);
      ^

Error: ENOENT: no such file or directory, lstat '/var/folders'
    at Object.realpathSync (node:fs:2486:7)
    at Object.<anonymous> (/app/node_modules/temp-dir/index.js:9:13)
    at Module._compile (node:internal/modules/cjs/loader:1101:14)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1153:10)
    at Module.load (node:internal/modules/cjs/loader:981:32)
    at Function.Module._load (node:internal/modules/cjs/loader:822:12)
    at Module.require (node:internal/modules/cjs/loader:1005:19)
    at require (node:internal/modules/cjs/helpers:102:18)
    at Object.<anonymous> (/app/node_modules/tempy/index.js:5:17)
    at Module._compile (node:internal/modules/cjs/loader:1101:14) {
  errno: -2,
  syscall: 'lstat',
  code: 'ENOENT',
  path: '/var/folders'
}

Import error when using tempy 2.0.0

I updated tempy from 1.0.1 to 2.0.0 and got the following issue when trying to import it in a typescript file (jest test file):

import tempy from 'tempy'
/path/to/our/project/node_modules/tempy/index.js:1
    ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,jest){import fs, {promises as fsPromises} from 'node:fs';
                                                                                      ^^^^^^

    SyntaxError: Cannot use import statement outside a module

Don't think the issue come from our jest/ts config, but I can provide them if needed

Prefix which includes a path.sep fails

Prefix which includes a path.sep fails.

Repro

This fails as the path will include a path.sep:

const uuid = 'xyz';
const prefixForRun = path.join('runs', `run_${uuid}`);
const outputFolder = temporaryDirectory({prefix: prefixForRun});

This call results in a path of:
'/private/var/folders/6t/frtzt7q96fv9xjqp3knl3vqh0000gn/T/runs/run_xyz'

The mkdir for run_xyz fails since the parent, /private/var/folders/6t/frtzt7q96fv9xjqp3knl3vqh0000gn/T/runs/, does not exist.

Error

Error: ENOENT: no such file or directory, mkdir '/private/var/folders/6t/frtzt7q96fv9xjqp3knl3vqh0000gn/T/runs/run_xyz'
    at Object.mkdirSync (node:fs:1324:3)

Solution

In mkdir, add the {recursive: true} option.

Discussion

Incidentally, fixing this gives an indirect method of #35, as my intention was similar. To organize my temp files/folders for later cleanup, I was adding a parent folder to my requested temp folder.

Properly removing leading dots

I think the regex here:

tempy/index.js

Line 22 in a2c7198

return getPath() + (options.extension === undefined || options.extension === null ? '' : '.' + options.extension.replace(/^\./, ''));

Should be replaced with:

/^\.+/

Otherwise extensions like ..ext will make this replacement useless, albeit maybe nobody ever passed an extension like that to this library.

Add methods for writing data to temp files

Issuehunt badges

I'd like to consolidate the functionality of https://github.com/sindresorhus/temp-write into this module. While doing that, look for ways to improve the original functionality and maybe add some more useful temp-related things.


IssueHunt Summary

richienb richienb has been rewarded.

Backers (Total: $60.00)

Submitted pull Requests


Tips


IssueHunt has been backed by the following sponsors. Become a sponsor

node v15 support

I'm getting some warnings when installing tempy via npm:

❯ npm i tempy
npm WARN EBADENGINE Unsupported engine {
npm WARN EBADENGINE   package: '[email protected]',
npm WARN EBADENGINE   required: { node: '^12.20.0 || ^14.13.1 || >=16.0.0' },
npm WARN EBADENGINE   current: { node: 'v15.14.0', npm: '7.7.6' }
npm WARN EBADENGINE }
npm WARN EBADENGINE Unsupported engine {
npm WARN EBADENGINE   package: '[email protected]',
npm WARN EBADENGINE   required: { node: '^12.20.0 || ^14.13.1 || >=16.0.0' },
npm WARN EBADENGINE   current: { node: 'v15.14.0', npm: '7.7.6' }
npm WARN EBADENGINE }

which seems to be caused by https://github.com/sindresorhus/tempy/blob/main/package.json#L16.

Is there a reason that node v15 is not listed as being supported? It is still widely used, eg. by VSCode.

Temporary file or directory not cleaned up when a task callback throws an error

The temporary file or directory is not cleaned up when a task callback throws an error, which doesn't feel like the expected behavior to me.

Example:

const tempy = require('tempy');
const fs = require('fs');

let createdTempDirectory;

await tempy.directory.task(async (tempDirectory) => {
  createdTempDirectory = tempDirectory;
  throw new Error('Something went wrong');
});

fs.existsSync(createdTempDirectory); // => true

A way to test that I have cleaned all temporary things?

I use tempy extensively in some of my projects. In one of those projects, I have some methods that create a lot of temporary files/folders and deletes them in the end.

I am currently writing automated tests for this project and I want to test that no temporary files/folders were left behind.

Some options I've considered:

  • List everything already in the temp folder before starting the test, then calling my methods and afterwards listing again what is in the temp folder, and checking if both lists are equal. Intuitively I don't like this approach though.
  • Make a wrapper over tempy that keeps track of everything that has been created. To test that there are no leftovers, I loop over each path recorded in this wrapper and check that it doesn't exist. This looks better, but I was wondering if this would be interesting to exist in tempy itself, in the form of a method like tempy.getCreationHistory() (name can be improved).

Also, an implementation of this second idea in tempy would enable an easy solution to #11, in which cleaning up would be just a p-map one-liner deleting everything over that history.

Add `rootDirectory` option

As requested in #33.

I guess it could be useful for when you want to semantically group all the temp directory usage in one directory for easier manual cleanup. This is not really useful for the .task methods though as they clean up themselves.

I'm not entirely sold on this though, as every option adds complexity for the user and most users will not need this. I'm also concerned users will think they need this when most often, they don't.

Create temp folder, then automate `rootDirectory` option

Idea: We could use a higher-level approach to discourage bad behaviour.

I guess it could be useful for when you want to semantically group all the temp directory usage in one directory for easier manual cleanup.

Something like:

import {tempDirectory} from 'tempy';

const root = temporaryDirectory();

const tempFile = root.temporaryFile();
import {temporaryDirectoryTask} from 'tempy';

temporaryDirectoryTask(root => {
	root.temporaryFileTask(tempFile => {
		
	});
})

Perhaps we could call them temporaryDirectoryContext and temporaryDirectoryContextTask? Perhaps we only need the latter?

Context: #35 (comment)

Error: EXDEV: cross-device link not permitted

This came up in ad-si/Transity#32

Summary

The tempy library uses rename to move the files under Linux. While moving a directory to the temporary directory, an error occurred because:

EXDEV oldpath and newpath are not on the same mounted filesystem.
(Linux permits a filesystem to be mounted at multiple points,
but rename() does not work across different mount points,
even if the same filesystem is mounted on both.)

For more, see man rename manpage: http://man7.org/linux/man-pages/man2/rename.2.html

tempy.root doesn't do anything

Setting .root doesn't actually change where the temp directory is created since getPath never references it.

var tempy = requite('tempy');
tempy.root = '/home/someuser';
console.log(tempy.directory());

Returns /tmp/somehash

Issue trying to create a temp file

Tried to create a temp file using the command below:

const tmpAudioFilename = tempy.file({ extension: 'aac' });

Got the following error:

Error: ENOENT: no such file or directory, open '/private/var/folders/ql/zg2bpwbx64189d_bsbkqshqh0000gn/T/adb826c4bd78785c504a2e01cc52f474.aac'

Has anyone come across this issue? What did you do?

Mac OS Mojave
10.14.5

Top level await error

Hi,

I'm getting an error Top-level await is not available in the configured target environment ("node14") when upgrading from 3.0.0 to 3.1.0.

✘ [ERROR] Top-level await is not available in the configured target environment ("node14")

    node_modules/temp-dir/index.js:4:27:
      4 │ const temporaryDirectory = await fs.realpath(os.tmpdir());
        ╵                            ~~~~~

I'm guessing tempy is asking for engine >=14.16 but top-level await is available from 14.8 onwards.

Add ability to easily cleanup

Issuehunt badges

Offer both cleanup when the process exits, manual cleanup method call, and also a context-based cleanup, for examples:

tempy.context(directory => {
	// Use the temp
});

// Temp directory is cleaned up here.

(The temp directory is cleaned up after the callback scope.)
(The above is just an idea. Please consider a better API and naming.)
(The context callback should also be able to be an async function.)

Inspiration: Python Context Managers


If you decide to work on this, please put a good effort into the implementation, docs (and TS definition), and tests.


IssueHunt Summary

richienb richienb has been rewarded.

Backers (Total: $80.00)

Submitted pull Requests


Tips

Returning values from `.task` functions

If a function that is supposed to return data, uses a .task function, the only way to pass data back out of the scope is like this:

const tempy = require('tempy');

module.exports = async () => {
	let result
	await tempy.file.task(tempFile => {
		// Use tempFile
		result = ...
	})
	return result
}

Since .task functions don't already return something, they could simply reflect the returned values:

const tempy = require('tempy');

module.exports = async () => {
	return await tempy.file.task(tempFile => {
		// Use tempFile
		return ...
	})
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.