bruce / node-temp Goto Github PK
View Code? Open in Web Editor NEWTemporary File, Directory, and Stream support for Node.js
Home Page: http://github.com/bruce/node-temp
License: MIT License
Temporary File, Directory, and Stream support for Node.js
Home Page: http://github.com/bruce/node-temp
License: MIT License
Hello,
The current release of node-temp uses rimraf 2.6.3, which depends on Glob, which depends on Inflight, which has a security issue: CWE-772. Newer releases of rimraf and Glob exist that do not have this dependency. Temp should be updated to a newer version, as it's used by many downstream packages, like js-codeshift, which currently have this vulnerability.
Currently, the only way to open a temporary file is in a way similar to fs.open()
.
However, for some uses it's preferable to have a Writable Stream
created instead. There's currently no way in node.js to create a Writable Stream
out of plain fd
number, so in such a case a new function in node-temp would be required.
The function could be named temp.createWriteStream
and behave in a similar fashion to fs.createWriteStream().
If I'm not mistaken, using track()
anywhere in the same process means that now all of your tempfiles will get automatically deleted prior to process exit, even in those parts of the program that never intended to remove temporary files. This could affect the mode of operation of any dependencies that happen to also use temp
.
Also that one can not use cleanup()
without having called track()
is IMHO an unwarranted complication. I fail to see what the relevance of this for long-running processes is; if anything, you do want to reliably unlink temporary files in such processes as soon as they're not needed to reduce chances of filling up the disk.
temp.track
mode fails when the file is locked. It should probably unlock the file before removing.
EBUSY: resource busy or locked, unlink 'C:\Users\VSSADM~1\AppData\Local\Temp\atom-test-data2020615-10032-1reom34.5toc\000003.log'
Error: EBUSY: resource busy or locked, unlink 'C:\Users\VSSADM~1\AppData\Local\Temp\atom-test-data2020615-10032-1reom34.5toc\000003.log'
at Object.unlinkSync (fs.js:1008:3)
at rimrafSync (D:\a\1\s\node_modules\temp\node_modules\rimraf\rimraf.js:306:17)
at D:\a\1\s\node_modules\temp\node_modules\rimraf\rimraf.js:342:5
at Array.forEach (<anonymous>:null:null)
at rmkidsSync (D:\a\1\s\node_modules\temp\node_modules\rimraf\rimraf.js:341:26)
at rmdirSync (D:\a\1\s\node_modules\temp\node_modules\rimraf\rimraf.js:334:7)
at rimrafSync (D:\a\1\s\node_modules\temp\node_modules\rimraf\rimraf.js:304:9)
at cleanupDirsSync (D:\a\1\s\node_modules\temp\lib\temp.js:170:5)
at process.cleanupSync (D:\a\1\s\node_modules\temp\lib\temp.js:222:19)
at process.emit (events.js:194:13)
at App.<anonymous> (D:\a\1\s\out\Atom Dev x64\resources\electron.asar\browser\init.js:63:11)
at App.emit (events.js:194:13)
at AtomApplication.exit (D:\a\1\s\src\main-process\atom-application.js:194:9)
at WebContents.<anonymous> (D:\a\1\s\src\main-process\atom-window.js:234:30)
at WebContents.emit (events.js:194:13)
The rimraf js is present in the node_modules/rimraf/ , in the same folder as temp.js and at the global scale too. Still, the module loading is failing.
Doesn't seem to happen on ubuntu 12.04 with node 0.10.38
I wanna read file then change it with through2
then write into the same file, code like:
const tempStream = temp.createWriteStream()
const ss = fs.createReadStream(readfile)
.pipe(fs.createReadStream(tempStream))
.pipe(through2.obj(function (chunk, encoding, done) {
const replaced = chunk.toString().replace(/id="wrap"/g, 'dududud')
done(null, replaced)
}))
.pipe(fs.createWriteStream(readfile))
full error info
TypeError: path must be a string or Buffer
at fs.open (fs.js:572:11)
at go$open (D:\dev\github\auto-activity\node_modules\graceful-fs\graceful-fs.js:236:14)
at open (D:\dev\github\auto-activity\node_modules\graceful-fs\graceful-fs.js:233:12)
at ReadStream$open [as open] (D:\dev\github\auto-activity\node_modules\graceful-fs\graceful-fs.js:185:5)
at new ReadStream (fs.js:1845:10)
at ReadStream (D:\dev\github\auto-activity\node_modules\graceful-fs\graceful-fs.js:178:28)
at Object.createReadStream (D:\dev\github\auto-activity\node_modules\graceful-fs\graceful-fs.js:220:12)
at Promise (D:\dev\github\auto-activity\server\controllers\projectDetail.js:199:16)
at promiseReplace (D:\dev\github\auto-activity\server\controllers\projectDetail.js:192:10)
at postDownloadProject (D:\dev\github\auto-activity\server\controllers\projectDetail.js:177:11)
at dispatch (D:\dev\github\auto-activity\node_modules\koa-compose\index.js:44:32)
at next (D:\dev\github\auto-activity\node_modules\koa-compose\index.js:45:18)
at D:\dev\github\auto-activity\node_modules\koa-router\lib\router.js:345:16
at dispatch (D:\dev\github\auto-activity\node_modules\koa-compose\index.js:44:32)
at D:\dev\github\auto-activity\node_modules\koa-compose\index.js:36:12
at dispatch (D:\dev\github\auto-activity\node_modules\koa-router\lib\router.js:350:31)
xxx POST /api/downloadProject 500 17ms -
server error { InternalServerError: The error is TypeError: path must be a string or Buffer when post download project
at Object.throw (D:\dev\github\auto-activity\node_modules\koa\lib\context.js:91:11)
at postDownloadProject (D:\dev\github\auto-activity\server\controllers\projectDetail.js:187:14)
at process._tickCallback (internal/process/next_tick.js:103:7)
message: 'The error is TypeError: path must be a string or Buffer when post download project' }
Hi!
I noticed that 0.9.1 has been released on npm but there is no 0.9.1 tag on github. I thought it might be helpfull to flag this ๐
Best
Hello,
I am getting an error "npm verb stack Error: 500 Internal Server Error: temp@^0.8.3" when I create a new TFS build. PFA logs. Your help will be highly appreciated.
Thanks in advance,
PS
4_npm install.txt
Hi. during testing we occasionally and unreproducibly get:
nodejs test/temp-test.js
assert.js:89
throw new assert.AssertionError({
^
AssertionError: temp.createWriteStream did not create a file
at Object.<anonymous> (/<<PKGBUILDDIR>>/test/temp-test.js:58:8)
at Module._compile (module.js:409:26)
at Object.Module._extensions..js (module.js:416:10)
at Module.load (module.js:343:32)
at Function.Module._load (module.js:300:12)
at Function.Module.runMain (module.js:441:10)
at startup (node.js:134:18)
at node.js:962:3
see: https://bugs.debian.org/834915
I wonder if this could be related to:
https://stackoverflow.com/a/12906805
If you have a long running server, which is the primary use case for node.js, this will never delete any temp files.
Hey guys, would you please release a new version with updated dependencies? Thank you!
If you're interested in taking over maintenance of this project, please let me know; I've been pulled away for some time. (As you can probably tell)
I'm using jasmine-node for most of my testing. Unfortunately, no cleanup seems to happen upon exit. If I run the following tests
>jasmine-code --verbose no_cleanup_on_exit.spec.js
with no_cleanup_on_exit.spec.js
var temp = require('temp');
temp.track();
describe('temp will create dir that will remain after the process exits', function() {
it('creates a dir', function() {
var p = temp.mkdirSync("shouldBeDeletedOnExit");
console.log('created dir ' + p);
});
});
After running this, the temp dir is still there.
Hey there :)
I want to get some PDFs from a server, merge them and then save the result to the server again.
As the library for merging the files doesn't support input streams, I have to save the files first. So I thought I'd do something like this:
var readStream = share.airwayBills.findOne().createReadStream();
temp.open('pdfgen', function(err, info) {
var writeStream = fs.createWriteStream(info.path + '/out.pdf');
readStream.pipe(writeStream);
writeStream.on('finish', function() {
console.log('Finished');
temp.cleanupSync();
});
});
When not using temp
here the code works, but using it I get this error:
Error: ENOTDIR, open '/var/folders/6y/vpzbkb0j0r366j_98dn42d380000gn/T/pdfgen11567-4723-am1ga0/out.pdf'
When I go into /var/folders/6y/vpzbkb0j0r366j_98dn42d380000gn/T
, pdfgen11567-4723-am1ga0
is not a folder, but an empty file. I think that a) I should get a directory, not a file and that b) it should be deleted using cleanupSync()
(might just not get called here).
What am I doing wrong here? (I'm on a Mac btw)
Thanks!
there is a gulp extension, called gulp-jspm. It uses this module. due to gulp multithreading nature, process.exit event is called for each gulp task, not for node.js process termination.
Example gulp config from spring: gulpfile.zip
actual scenario (3 concurrent threads):
[1] jspm-main started
TempFile1 is created, temp.filesToDelete=[TempFile1], temp listener initialized
[2] jspm-maps started
TempFile2 is created, temp.filesToDelete=[TempFile1, TempFile2]
[3] jspm-admin started
TempFile3 is created, temp.filesToDelete=[TempFile1, TempFile2, TempFile3]
[2] jspm-maps processing
[2] jspm-maps finished
process.exit event called, cleanupFilesSync deleting ALL 3 TEMP FILES! TempFile1, TempFile2, TempFile3 instead of just TempFile2
[3] jspm-admin processing
ERROR: file TempFile3 not found
[1] jspm-main processing
ERROR: file TempFile1 not found
In short, temp module (with it's state filesToDelete) is global to all 3 gulp tasks which leads to conflicts.
Yes, there is a workaround: DO NOT execute jspm gulp tasks in parallel. But it's a gulp main feature. You would just use grunt or pure npm otherwise.
I suggest a fix. Just change temp module functions to:
function deleteFileOnExit(filePath) {
if (!tracking) return false;
var onExit = function() {
rimrafSync(filePath);
};
process.addListener('exit', onExit);
}
function deleteDirOnExit(dirPath) {
if (!tracking) return false;
var onExit = function() {
rimrafSync(dirPath);
};
process.addListener('exit', onExit);
}
It would work for all environments, standalone, grunt, gulp, you name it.
replace current functionality completely or just add new functions like track2/open2 with suggested functionality
PR #89 broke Node 4 compatibility purely because some 'var' were replaced with 'let'. There was no advantage of using 'let', all declarations that were replaced were either global scope or function scope. 'const' (for global package imports) or 'var' can be used with the same effect and it will maintain Node 4 compatibility.
First, here's my code:
readStream = share.airwayBills.findOne().createReadStream();
temp.track();
temp.mkdir('pdfgen', function(err, info) {
var writeStream = fs.createWriteStream(path.join(info, 'out.pdf'));
readStream.pipe(writeStream);
writeStream.on('finish', function() {
temp.cleanup(function(err, stats) {
console.log(stats);
});
});
});
Works great, except for deleting the directory: the log is { files: 0, dirs: 0 }
and the directory still exists.
How can I fix this? Thanks!
Hi, I found a typo in Readme. This is a pull request to fix it #35
I have the following code that i have to write tests for. I want to test if a call was made to "readdir" and as well as tests if an error occurred in the Promise the "logger.error" is called and if an error doesn't occur the promise is resolved. I'm Still new to Jasmine tests, please help. In my approach i keep getting an error : "Unhandled rejection TypeError: path must be a string or Buffer"
Code Snippet:
const MyPromise = require('bluebird');;
const chalk = require('chalk');
const fs = require('fs');
const logger = require('./logger');
function LocalFileLister(settings) {
this._settings = settings;
};
LocalFileLister.prototype.listAllFiles = function() {
logger.trace(' [FILE] List All Files (using local disk)');
return new MyPromise((resolve, reject) => {
fs.readdir(this._settings.dropLocation, function(error, files){
if (error) {
logger.error('localFileLister.js -> listAllFiles');
logger.error(error);
reject(err);
} else {
logger.trace(' [FILE] List All Files complete (using local disk): '+ files.length +' files(s) found');
resolve(files);
}
});
});
};
My - Approach
var LocalFileLister = require('./LocalFileLister');
var fs = require('fs');
describe("Local file listing", () =>{
beforeEach((done) => {
settings = jasmine.createSpyObj('settings', ['settings']);
fs = jasmine.createSpyObj('fs', [ 'readdir']);
fs.readdir.call(function() {
return true;
});
var sut = new LocalFileLister([]);
sut.listAllFiles((done) => {
return new MyPromise((r)=>{
fs.resolve(r);
done();
});
});
});
it("should call listAllFiles", ()=>{
expect(sut.listAllFiles).toHaveBeenCalled();
});
});
A node process that has called temp.track() will have a single process-wide array of files that have been opened and calling temp.cleanup() will delete all of these files.
There is a race condition here where one request could open a temp file but before it has the chance to be used, it can be deleted by some other concurrent request hitting a cleanup() call. Since some node processes tend to be very long-running, simply leaving the files until exit runs the risk of disk filling or having a large batch deletion to perform on exit.
It would be nice to have a middle-ground where file deletion is made more precise so we have the means to avoid this case.
getYear is deprecated and does not set a correct year
It looks like the temporary file cleanup code is only triggered on a clean exit, which means that if you kill the process (e.g. kill <pid>
from a different console) or interrupt it (e.g. ctrl-C in the console the process is running in), the temporary files will not get cleaned up.
I understand that one might not always want to clean up on these signals, but it'd be nice if there were a supported / stable way of getting that hooked in.
Thanks for your consideration!
The NPM metadata lists dates that do not follow the proper time format, this causes some apps (notably Artifactory) to fail, throwing an invalid format exception (they use Joda time to parse it, and it fails).
Those dates are below, notice that they do not have a sub-second time, but the rest of the dates do:
"time": {
"created": "2010-11-09T23:36:39Z",
"modified": "2017-08-16T01:34:42.039Z",
"0.2.0": "2010-11-09T23:36:39Z",
"0.3.0": "2011-12-30T04:56:26.911Z",
"0.4.0": "2012-01-02T06:06:13.789Z",
"0.5.0": "2012-12-27T06:05:40.975Z",
"0.5.1": "2013-06-30T05:34:31.247Z",
"0.6.0": "2013-09-09T06:30:45.938Z",
"0.7.0": "2014-02-26T09:14:42.595Z",
"0.8.0": "2014-06-02T04:56:15.496Z",
"0.8.1": "2014-08-05T00:12:17.410Z",
"0.8.2": "2015-06-08T16:50:31.181Z",
"0.8.3": "2015-06-08T16:55:52.866Z"
},
http://registry.npmjs.com/temp
Error is:
{
"errors" : [ {
"status" : 500,
"message" : "Invalid format: "2010-11-09T23:36:39Z" is malformed at "Z""
} ]
}
You might be inclined to say that this is an Artifactory problem, or a joda time problem... that the date format is acceptable. However, I have found no other packages in npm that have this issue... temp is the only one.
Maybe you think it's an npm issue, and maybe it is. But as a user, there seems to be no way for me to fix this.. so maybe there is something on your end that can be done.
I've been getting the same filename from temp.path() every time my express.js server gets the same request repeated close together (when I doubleclick the button in the browser that triggers the request).
I'm using temp on a little project and it is working out great for the most part. Like the person in the other open issue mentions, the framework is a little to opinionated wrt the exit handling. I would like to see optional 'exitHandler' param to temps exported functions so clients can choose whether or not that want the cleanup 'convenience'. Mo flexible.
I'd be happy to send you a pull request as I don't want to build my own temp solution right now. Just let me know if you are interested.
Thanks
Currently the "temp" folder is taken from os.tmpDir().
Adding a way to change this default can really help.
In /lib/temp.js
, at lines 265 and 276, there are old-style octal numerals 0700
, which are deprecated, and forbidden in strict mode.
While this is valid JavaScript, it can cause problems in certain cases. For example rollup does not like mixing the old syntax and the newer ES6 features : it fails on [email protected] whereas it succeeds on 0.9.1. (I have to admin, I am not sure exactly why).
I suggest to move this to the modern octal syntax 0o700
instead. Another possibility would be to use the same syntax as a few lines below parseInt('0600', 8)
.
@bruce, this is a recommended syntax for copying a file with node.js:
fs.createReadStream('file.html')
.pipe(fs.createWriteStream('newfile.html'));
However it doesn't seem to work with node-temp
:
fs.createReadStream('file.html'))
.pipe(temp.createWriteStream()); // temp file created, 0 bytes written
Of course, the following syntax (from your docs) does work (a sanity check):
temp.open('tempfile', function (err, info) {
fs.write(info.fd, fs.readFileSync('file.html').toString());
fs.close(info.fd, function (err) {
if (err) throw err;
// Do something with the file
});
});
Looking at the code for temp.createWriteStream()
, it seems it returns a stream just like the original fs
api. Am I doing something wrong? Am I missing anything here?
Well, when the install is global in linux.
var temp = require('temp');
console.log(require('os').tmpDir, temp.dir);
/tmp /home/{user}/tmp
my package is @boneskull/gulp-jekyll
.
attempted:
require('temp').mkdir('foo', function(err, dirpath) {
// ..
});
received error:
Error: ENOENT: no such file or directory, mkdir '/var/folders/d4/vrj66_rs375gh9_33xr9bnv80000gs/T/@boneskull/gulp-jekyll115729-72134-11havb5'
Directory /var/folders/d4/vrj66_rs375gh9_33xr9bnv80000gs/T/@boneskull/
does not exist.
I don't think temp.mkdir() will succeed in removing non-empty directories, since it just calls fs.rmdir() on the directory names without first recursively removing all files in them.
The problem is that require("fs").rmdir() is a thin wrapper on top of the underlying POSIX rmdir() call, and that call is specified to fail if the named directory has any files in it.
In Brackets, we've had a problem with node-temp trying to put files in the wrong place because it looks at environment variables but apparently doesn't call os.tmpdir()
as a fallback (which is one proposed solution to our problem).
node-temp should probably make use of Node's included API for finding the tmpdir.
I tried to use this library with Gruntjs and have following issue.
My Gruntfile.coffee looks like
module.exports = (grunt) ->
temp = require('temp')
grunt.registerTask "testemp", "Testing of tmp", () ->
grunt.log.writeln("Test of temp file")
temp.open 'tempfile', (err, info) ->
grunt.log.writeln("Temp file done!")
grunt.log.writeln("Test of temp dir")
temp.mkdir "tempdir", (err, dirPath) ->
grunt.log.writeln("Temp dir done!")
grunt testemp
and result is
Running "testemp" task
Test of temp file
Test of temp dir
Done, without errors.
So basicaly it does nothing.
Have grunt 0.4.1
generateName contains the following for including the current date in a temporary file name:
now.getYear(), now.getMonth(), now.getDay()
now.getDay() returns the day of the week, always between 0-6. It would be more logical to use now.getDate() which returns the day of the month, 1-31.
My application will be allocating lots of temporaries so I would like to see a way other than process exit for the temporary files and directories to get deleted. The other problem is "memory leaking" from allocating all the event listeners on process exit.
Theres a few pull request sitting around from 2015 and there doesn't seem to be much activity, so I was wondering if this repo is even being maintained or if it is not being supported anymore?
Please correct the readme. The write method requires a callback. Without it, it will fail randomly returning "Error: EBADF: bad file descriptor, write"
fs.write(info.fd, myData, function (err) {
fs.close(info.fd, function(err) {
exec("grep foo '" + info.path + "' | wc -l", function(err, stdout) {
util.puts(stdout.trim());
});
});
});
Hey Guys,
Are there any particular reason why you're using rimraf synchronously instead of the asynchronous version?
Thanks.
Gabriel
I would like to create the temp file in a different directory other than System temp directory.
Is it possible?
When creating a temporary file, it's usually best practice to make sure it doesn't already exist. For example, libc's functions like mktemp(3) will test that the unique name it creates doesn't already exist. There is a race condition that can be a bug or security problem, which is one of the reasons that mkstemp(3) exists. In this case the file is opened with O_EXCL so that if the file already exists the open call will fail.
This might sound a bit pedantic, but in a lot of situations it can become pretty important.
You can see for example how libc handles this here:
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.