I have the following issue, in the function sendDownload(downlodable ,objPathArray, responseObject) I am receiving the parameter objPathArray like this:
[{"pathToFile":"./REPORTS/portfolio/onDemand/Portfolio_report_HP_17.08.2021.xlsx","file":"Portfolio_report_HP_17.08.2021.xlsx"}]
The function:
function sendDownload(downlodable ,objPathArray, responseObject) {
if (downlodable) {
responseObject.download((objPathArray[0].pathToFile), (objPathArray[0].file))
console.log('HERE ' + JSON.stringify(objPathArray))
}
}
but when I call the function in my app I receive this error Error: ENOENT: no such file or directory, stat 'C:\Work\reporting-server\REPORTS\portfolio\onDemand\Portfolio_report_HP_17.08.2021.xlsx' and that's because Node is changing my relative path for the file in an absolute one.
What is the best option for me in order to solve this issue ?
Thank you~
Node.js must resolve the path to find the file.
If you give it a relative path then it has to start somewhere and that somewhere is the current working directory.
If you want it to read the file from somewhere else then resolve it to an absolute path yourself.
Generally speaking the tools to do this will be path.resolve and something to tell it where to start from such as a configuration file, environment variable, or the directory the module is in.
Related
I'm packing some files in my lambda package that I need. I've used some example floating around to nearly get it working.
I'm able to verify the path of a file OK
const deviceCert = path.resolve(certType + "-deviceCert.key");
which logs out to
"message": "Resolved path to TEST-deviceCert.key: /var/task/TEST-deviceCert.key"
when I attempt to read the file using
fs.readFile(deviceCert, (err, data) => {
if (err) {
log.error(`Verify deviceCert failure: ${err}`);
responseBody = Helper.buildCORSResponse(502, JSON.stringify({ message: "Unable to locate file required" }));
return callback(null, responseBody);
}
});
I get the following error
Error: ENOENT: no such file or directory, open '/var/task/TEST-deviceCert.key'"
If I can verify the path then why cant I read it?
Any ideas??
Copied from the node.js path.resolve() API documentation:
The path.resolve() method resolves a sequence of paths or path segments into an absolute path.
In other words, resolve concatenates a sequence of strings into one string, formatted as an absolute path. However, it does not check whether or not there is a file at this location. You can use either fs.stat() or fs.access() to verify the presence and access of the file.
eventually confirmed that serverless was packaging the files I needed.
Using fs.readdir I was able to debug the issue and find the path that the packaging process was creating in the Lambda package
/var/task/src//Certs/
Hope this helps someone in the future!!
I have a Node.js module that looks like this:
module.exports = function()
{
// linked dependencies
this.dependency1 = 'dependency1/dependency1.exe';
this.dependency2 = 'dependency2/dependency2.exe';
this.dependency3 = 'dependency3/dependency3.exe';
}
I want developers to be able to easily edit the location of the dependencies relative to the module file itself. However, when using the module, the current working directory process.cwd() is usually not the same as the module directory, so those paths do not resolve correctly. path.resolve() only seems to work relative to the current working directory, and doesn't have any arguments to allow for a custom reference point/path.
I have been able to resolve the paths in the following way, but I find it ugly and cumbersome, and it should be easier than this:
this.ResolvePath = function(p)
{
var cwd = process.cwd();
process.chdir(path.dirname(module.filename));
var resolvedPath = path.resolve(p);
process.chdir(cwd);
return resolvedPath;
}
Is there a cleaner way to do this? I feel like path.relative() should hold the solution, but I can't find a way to make it work. Perhaps chaining together multiple path.relative()s could work, but I can't wrap my brain around how that would work right now.
why not just:
path.resolve(__dirname, p)
__dirname works a bit differently and returns the current modules path, which can then be joined easily with the relative path.
I'm in the process of building an npm package which will be installed globally. Is it possible to have non-code files installed alongside code files that can be referenced from code files?
For example, if my package includes someTextFile.txt and a module.js file (and my package.json includes "bin": {"someCommand":"./module.js"}) can I read the contents of someTextFile.txt into memory in module.js? How would I do that?
The following is an example of a module that loads the contents of a file (string) into the global scope.
core.js : the main module file (entry point of package.json)
//:Understanding: module.exports
module.exports = {
reload:(cb)=>{ console.log("[>] Magick reloading to memory"); ReadSpellBook(cb)}
}
//:Understanding: global object
//the following function is only accesible by the magick module
const ReadSpellBook=(cb)=>{
require('fs').readFile(__dirname+"/spellBook.txt","utf8",(e,theSpells)=>{
if(e){ console.log("[!] The Spell Book is MISSING!\n"); cb(e)}
else{
console.log("[*] Reading Spell Book")
//since we want to make the contents of .txt accesible :
global.SpellBook = theSpells // global.SpellBook is now shared accross all the code (global scope)
cb()//callBack
}
})
}
//·: Initialize :.
console.log("[+] Time for some Magick!")
ReadSpellBook((e)=>e?console.log(e):console.log(SpellBook))
spellBook.txt
ᚠ ᚡ ᚢ ᚣ ᚤ ᚥ ᚦ ᚧ ᚨ ᚩ ᚪ ᚫ ᚬ ᚭ ᚮ ᚯ
ᚰ ᚱ ᚲ ᚳ ᚴ ᚵ ᚶ ᚷ ᚸ ᚹ ᚺ ᚻ ᚼ ᚽ ᚾ ᚿ
ᛀ ᛁ ᛂ ᛃ ᛄ ᛅ ᛆ ᛇ ᛈ ᛉ ᛊ ᛋ ᛌ ᛍ ᛎ ᛏ
ᛐ ᛑ ᛒ ᛓ ᛔ ᛕ ᛖ ᛗ ᛘ ᛙ ᛚ ᛛ ᛜ ᛝ ᛞ ᛟ
ᛠ ᛡ ᛢ ᛣ ᛤ ᛥ ᛦ ᛧ ᛨ ᛩ ᛪ ᛫ ᛬ ᛭ ᛮ ᛯ
If you require it from another piece of code, you will see how it prints to the console and initializes by itself.
If you want to achieve a manual initalization, simply remove the 3 last lines (·: Initialize :.) and use reload() :
const magick = require("core.js")
magick.reload((error)=>{ if(error){throw error}else{
//now you know the SpellBook is loaded
console.log(SpellBook.length)
})
I have built some CLIs which were distributed privately, so I believe I can illuminate a bit here.
Let's say your global modules are installed at a directory called $PATH. When your package will be installed on any machine, it will essentially be extracted at that directory.
When you'll fire up someCommand from any terminal, the module.js will be invoked which was kept at $PATH. If you initially kept the template file in the same directory as your package, then it will be present at that location which is local to module.js.
Assuming you edit the template as a string and then want to write it locally to where the user wished / pwd, you just have to use process.cwd() to get the path to that directory. This totally depends on how you code it out.
In case you want to explicitly include the files only in the npm package, then use files attribute of package.json.
As to particularly answer "how can my code file in the npm package locate the path to the globally installed npm folder in which it is located in a way that is guaranteed to work across OSes and is future proof?", that is very very different from the template thingy you were trying to achieve. Anyway, what you're simply asking here is the global path of npm modules. As a fail safe option, use the path returned by require.main.filename within your code to keep that as a reference.
When you npm publish, it packages everything in the folder, excluding things noted in .npmignore. (If you don't have an .npmignore file, it'll dig into .gitignore. See https://docs.npmjs.com/misc/developers#keeping-files-out-of-your-package) So in short, yes, you can package the text file into your module. Installing the module (locally or globally) will get the text file into place in a way you expect.
How do you find the text file once it's installed? __dirname gives you the path of the current file ... if you ask early enough. See https://nodejs.org/docs/latest/api/globals.html#globals_dirname (If you use __dirname inside a closure, it may be the path of the enclosing function.) For the near-term of "future", this doesn't look like it'll change, and will work as expected in all conditions -- whether the module is installed locally or globally, and whether others depend on the module or it's a direct install.
So let's assume the text file is in the same directory as the currently running script:
var fs = require('fs');
var path = require('path');
var dir = __dirname;
function runIt(cb) {
var fullPath = path.combine(__dirname, 'myfile.txt');
fs.readFile(fullPath, 'utf8' , function (e,content) {
if (e) {
return cb(e);
}
// content now has the contents of the file
cb(content);
}
}
module.exports = runIt;
Sweet!
Suppose I've these directories:
'C:\\src' // Root path.
'C:\\src\\inner1' // Contain 'a.js'
'C:\\src\\inner2\\innermost' // Contain 'b.js'
So, if I do this in C:\\src\\inner1\\a.js:
require('inner2/innermost/b')
It must return the exported value from C:\\src\\inner2\\innermost\\b.js, but I do not want to use the executing script relative path, e.g.:
require('../inner2/innermost/b')
So, independently of the current script directory, I want to require a module from such root path.
How can I do it? There is no problem if I need to specify something at package.json.
Try this way
path = require('path');
path.resolve('../inner2/mostinner/b');
I have image files with read-only attribute set in source folder. I need to copy them to destination folder in most cases several times in gulpfile.js.
I am trying to copy src-to-dest files like this:
gulp.task('copy-images', function () {
gulp.src(path_resource_images + '**/*.jpg')
.pipe(gulp.dest(path_app_images));
});
It works once when the dest folder in empty. But for all next calls I've got an exception that file is read-only in dest folder. How can I remove file attr read-only to make image-copy works every time I call it?
You can use gulp-chmod to handle permissions on your files.
So if you want to set your images readable and writable for everybody, you could go with something like:
var chmod = require('gulp-chmod');
gulp.task('copy-images', function() {
gulp.src(path_resource_images + '**/*.jpg')
.pipe(chmod(666))
.pipe(gulp.dest(path_app_images));
});
By passing options attribute. Set mode value to specify permission for any folders that need to be created as output.
gulp.dest("destination-path-here", {"mode": "0777"})
cheers :-)
rimraf can be used to avoid issues with TFS permissions (by deleting destination files before copying files)
var rimraf = require("rimraf");
gulp.task("images_clean", function (cb) {
rimraf(imagesDest, cb);
});