Get full file path in Node.js - javascript

I have an application which uploads csv file into a particular folder, say, "uploads".
Now I want to get the full path of that csv file, for example, D:\MyNodeApp\uploads\Test.csv.
How do I get the file location in Node.js? I used multer to upload file.

var path = require("path");
var absolutePath = path.resolve("Relative file path");
You dir structure for example:
C:->WebServer->Public->Uploads->MyFile.csv
and your working directory would be Public for example, path.resolve would be like that.
path.resolve("./Uploads/MyFile.csv");
POSIX home/WebServer/Public/Uploads/MyFile.csv
WINDOWS C:\WebServer\Public\Uploads\MyFile.csv
this solution is multiplatform and allows your application to work on both windows and posix machines.

Get all files from folder and print each file description.
const path = require( "path" );
const fs = require( 'fs' );
const log = console.log;
const folder = './';
fs.readdirSync( folder ).forEach( file => {
const extname = path.extname( file );
const filename = path.basename( file, extname );
const absolutePath = path.resolve( folder, file );
log( "File : ", file );
log( "filename : ", filename );
log( "extname : ", extname );
log( "absolutePath : ", absolutePath);
});

Assuming you are using multer with express, try this in your controller method:
var path = require('path');
//gets your app's root path
var root = path.dirname(require.main.filename)
// joins uploaded file path with root. replace filename with your input field name
var absolutePath = path.join(root,req.files['filename'].path)

In TypeScript, I did the following based on the relative file path.
import { resolve } from 'path';
public getValidFileToUpload(): string {
return resolve('src/assets/validFilePath/testFile.csv');
}

If you are using a "dirent" type:
const path = require( "path" );
full_path = path.resolve( path_to_folder_containing__dir_ent__ , dir_ent.name );
Class: fs.Dirent
https://nodejs.org/api/fs.html#fs_dirent_name
Module: fs.path
https://nodejs.org/api/path.html

I think the simplest option is:
dirname module: https://nodejs.org/docs/latest/api/modules.html#modules_dirname
filename: https://nodejs.org/docs/latest/api/modules.html#modules_filename
console.log(__dirname)
console.log(__filename)

Related

Error: absolute path: //fileName/ unzipping a folder in protractor nodejs

I tried many ways available in different sites to unzip the downloaded zipped folder and found the below one is simplest way.However, am facing the below issue.Please help me resolve this :
const extract = require('extract-zip');
const path = require('path');
unzip=async function(){
let source = "Downloads/sample.zip";
let destination = "Downloads/";
let sP = path.resolve(source);
console.log("Source path : " +sP);
let dP = path.resolve(destination);
console.log("Destination path : " +dP);
await extract(sP, { dir: dP });
console.log('Extraction complete');
}
Output :
Source path : /Users/myName/Documents/framework/Downloads/sample.zip
Destination path :/Users/myName/Documents/framework/Downloads
.
.
Error: absolute path://sample/
The resolved path should be relative to the path of the directory where the code is being executed.
Replace
let source = '../../Downloads/sample.zip
let destination = '../../Downloads
let sP = path.resolve(source);
let dP = path.resolve(destination);
The problem is the .zip file itself starting with //. Extract-zip uses yauzl which throws an exception if it's an absolute path:
https://github.com/thejoshwolfe/yauzl/issues/135

find in node js, if the zip file contains any .js or .exe or .json format, i want to block those type of upload

I want to validate if the zip file contains any "js", "exe", "JSON" file
Whenever there is this type of file i want to handle it and not upload the same file to the s3 bucket.
const unzip = require('unzip'),
fs = require('fs'),
inputFileName = '/home/nn/Downloads/delete.zip'; // zip file path
fs.createReadStream(inputFileName)
.pipe(unzip.Parse())
.on('entry', (entry) => {
console.log(entry);
// how should i validate here
}
entry.autodrain();
});
You can use the path module, and use the extname(), which gives you the extension and then check from your vulnerable extensions using the includes
const unzip = require('unzip'),
fs = require('fs'),
path = require('path'),
inputFileName = '/home/nayan/Downloads/delete.zip'; // zip file path
fs.createReadStream(inputFileName)
.pipe(unzip.Parse())
.on('entry', (entry) => {
const rest_file_path = ['.js', '.exe', '.zip'],
extension = path.extname(entry.path);
if (rest_file_path.includes(extension)) {
console.log(`Cant upload this zip file as it contains ${extension} file`) // you can handle it here and send a error response
}
entry.autodrain();
});

how to set name of file being uploaded in connect-multiparty?

I have have one page where I want to accept one file and 3-4 user inputs , I was able to achieve this using connect-multiparty middle-ware but the name of uploaded file is something gibberish with correct extension and uploaded files contents are too correct.
I want to achieve below things
Set name of file being uploaded
Create copy of file with different name if the file with same name exists in target directory
Set max limit on size and restrict type of file.
I searched on net but could not find any working example. My complete code is as below
var express = require('express');
var router = express.Router();
var fs = require('fs');
var multiparty = require('connect-multiparty');
var multipartyMiddleware = multiparty({
uploadDir : '../public/uploads'
});
router.post('/api/user/uploads', multipartyMiddleware, function(req, res) {
var file = req.files.file;
console.log(file.name);
console.log(file.type);
console.log(file);
console.log(req.body.test);
console.log("The file was saved!");
res.json({
success : 1
});
return;
});
module.exports = router;
You will have to rename the file after being copied using fs.rename(), or modify the source code of multiparty inside node_modules. Inside their code they have a function that does the renaming:
function uploadPath(baseDir, filename) {
var ext = path.extname(filename).replace(FILE_EXT_RE, '$1');
var name = randoString(18) + ext;
return path.join(baseDir, name);
}
I have done some modifications to their code so I could use it a little bit like multer:
https://gist.github.com/Edudjr/999c80df952458cc583272a5161b4d08
You would use it like so:
var EXT_RE = /(\.[_\-a-zA-Z0-9]{0,16}).*/g;
var options = {
uploadDir : path.join(__dirname,'../public/images'),
filename: function(filename, callback){
var name = filename.replace(EXT_RE, "");
callback(name+'-YEAH.png');
}
}
var form = new multiparty.Form(options);
They strongly advise you to save the files in the temp folder to prevent DoS on your server.
https://github.com/pillarjs/multiparty/issues/64
You can access it easily, I used this to get file name.
console.log(req.files.uploads.path.split('\\')[1]);
I am using uploads from Angular.

Node Js : Unable to find error in below file filter code

I have written small code to get files filtered by extension. And my point of view logic is fine but I am unable to point out why I am not getting expected output.
Please have a look.
CODE
var fs = require('fs')
var path = require('path')
path_name = process.argv[2]
ext_name = "."+process.argv[3]
var filter_function = function ( path_name,exthide_name,callback) {
fs.readdir(dirpath,function(err,list) {
if(err) return console.error(err)
for ( var i in list) {
if(path.extname(list[i]) == ext_name)
console.log(list[i])
}
})
}
module.exports=filter_function
Output :
linuxmen#linuxmen-fresh:~/test/test1$ node ownModuleNode.js /home/linuxmen/test/test1/ js
linuxmen#linuxmen-fresh:~/test/test1$
But I have so many files with js extension in that directory.
Proof:
linuxmen#linuxmen-fresh:~/test/test1$ ls *js
check_mod1.js ex1.js ex2.js ex3.js ex4.js ex5.js ex6.js ex7.js ex8.js filter.js filter_use.js modse.js ownModuleNode.js se.js use_mod1.js using_module.js
Could please help , what I am missing.
Update - 1 : I am using above code a module file and calling it here.
File using above code
var mymodule = require('./ownModuleNode')
mymodule.filter_function(process.argv[2],process.argv[3])
Update 2 :
var fs = require('fs')
var path = require('path')
path_name = process.argv[2]
ext_name = "."+process.argv[3]
console.log("path_name :",path_name,"extname:",ext_name)
var filter_function = function ( path_name,ext_name,callback) {
fs.readdir(path_name,function(err,list) {
if (err) console.error(err)
console.log(list)
for ( var i in list) {
if(path.extname(list[i]) == ext_name)
console.log(list[i])
}
})
}
module.exports=filter_function
Output:
linuxmen#linuxmen-fresh:~/test/test1$ node ownModuleNode.js /home/linuxmen/test/test1/ js
pathanme : /home/linuxmen/test/test1/ extname: .js
Thank you.
It looks like you are exporting the function directly. When you require() it, you just getting the function. You'll need to use your module in your application. Put this in 'app.js' in the same dir as ownModuleNode.js:
var filterFunction = require('./ownModuleNode');
filterFunction(process.argv[2], process.argv[3]);
Then call it with:
node app ~/Documents/dev/project .js
Outputs:
app.js
ownModuleNode.js
Note that when you pass the extension, you need the preceding dot because path.extname() returns the dot.

meteor js how to write a file to disk from the server

I am writing a meteor package 'myPackage' which needs to write a file onto disk using Npm FileSystem and Pah modules.
The file should end up in the example-app/packages/myPackage/auto_generated/myFile.js, where example-app project
has myPackage added.
fs = Npm.require( 'fs' ) ;
path = Npm.require( 'path' ) ;
Meteor.methods( {
autoGenerate : function( script ) {
var myPath = '/Users/martinfox/tmp/auto-generated' ;
var filePath = path.join(myPath, 'myFile.js' ) ;
console.log( filePath ) ; // shows /Uses/martinfox/tmp/auto-generated/myFile.js
var buffer = new Buffer( script ) ;
fs.writeFileSync( filePath, buffer ) ;
},
} );
When I run the code above (server side only) I get
Exception while invoking method 'autoGenerate' Error: ENOENT,
no such file or directory '/Uses/martinfox/tmp/auto-generated/myFile.js'
Note /Uses/martinfox/tmp/auto-generated folder does exist
Any ideas what is going wrong?
Is it possible to obtain the absolute path to the meteor projects directory?
To get the path of your project you can do this :
from main.js stored in the root of your app
var fs = Npm.require('fs');
__ROOT_APP_PATH__ = fs.realpathSync('.');
console.log(__ROOT_APP_PATH__);
You can also check if your folder exists :
if (!fs.existsSync(myPath)) {
throw new Error(myPath + " does not exists");
}
Hope it will help you
If you are just looking for the absolute path for your app, you could simply do var base = process.env.PWD, which yields: /Users/[username]/[app-name]
This would avoid the extra stuff .meteor/local/build/programs/server

Categories