How to use docx npm package in production to save a file - node.js

I am generating a doc file using docx-template npm package in node js. and the file is getting successfully saved in my backend/controller folder on my local machine. Now i want to do prod deployment on Heroku but i dont know what path has to be set to save the file in production.
I have used 'fs' module to read and write file. Shown below.
fs.writeFileSync(
path.resolve(__dirname, `${contractName} ${element.frequency}.docx`),
buffer
);

You probably have to use the "send(Buffer)" feature of express.
See the following page :
https://expressjs.com/en/api.html#res.send
const contentTypes = {
docx: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
pptx: "application/vnd.openxmlformats-officedocument.presentationml.presentation",
xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
};
res.set('Content-Type', contentTypes.docx);
res.send(buffer);
This is because the "fs" module is used to write the data on the disk, but if it is in production, most likely what you want is to let the user "download" a file, and that is done using res.send() which takes as an argument a Buffer to achieve this feature.

Related

How to bundle and require non JS dependencies in Firebase Cloud Functions?

I have an http cloud function that returns some dynamic HTML. I want to use Handlebars as the templating engine. The template is sufficiently big that it's not practical to have it in a const variable on top of my function.
I've tried something like:
const template = fs.readFileSync('./template.hbs', 'utf-8');
But when deploying the function I always get an error that the file does not exist:
Error: ENOENT: no such file or directory, open './template.hbs'
The template.hbs is in the same directory as my index.js file so I imagine the problem is that the Firebase CLI is not bundling this file along the rest of files.
According to the docs of Google Cloud Functions it is possible to bundle local modules with "mymodule": "file:mymodule". So I've tried creating a templates folder at the root of the project and added "templates": "file:./templates" to the package.json.
My file structure being something like this:
/my-function
index.js
/templates
something.hbs
index.js //this is the entry point
And then:
const template = fs.readFileSync('../node_modules/templates/something.hbs', 'utf-8');
But I'm getting the same not found error.
What is the proper way of including and requiring a non JS dependencies in a Firebase Cloud Function?
The Firebase CLI will package up all the files in your functions folder, except for node_modules, and send the entire archive to Cloud Functions. It will reconstitue node_modules by running npm install while building the docker image that runs your function.
If your something.hbs is in /templates under your functions folder, you should be able to refer to it as ./templates/something.hbs from the top-level index.js. If your JS is in another folder, you might have to work you way out first with ../templates/something.hbs. The files should all be there - just figure out the path. I wouldn't try to do anything fancy is your package.json. Just take advantage of the fact that the CLI deploys everything but node_modules.
This code works fine for me if I have a file called 'foo' at the root of my functions folder:
import * as fs from 'fs'
export const test = functions.https.onRequest((req, res) => {
const foo = fs.readFileSync('./foo', 'utf-8')
console.log(foo)
res.send(foo)
})
The solution was to use path.join(__dirname,'template.hbs').
const fs = require('fs');
const path = require('path');
const template = fs.readFileSync(path.join(__dirname,'template.hbs'), 'utf-8');
As #doug-stevenson pointed out all files are included in the final bundle but for some reason using the relative path did not work. Forcing an absolute path with __dirname did the trick.

My cli engine(npm package) cant find path to read file when install on another folder

I am building an app that auto completes some type of file. When i run node index.js in the program folder i get the correct i results.
Although i want to make it an npm package that can work as a cli engine. For example i want to write the command generate and the code to produce the results.
In order to auto complete the file i have to read some data that i have stored in a .csv file that comes along with my program.
When i try to run generate command under another folder it can read that file.
I am very new to cli and i don't understand yet quite well how thing work.
Thanks in advance for the help.
Here is the code of my cli conversion.
#!/usr/bin/env node
const program = require("commander");
const {
predict
} = require("./classifier");
program.version("1.0.0").description("ESLint Rules Generator");
program
.command("generate")
.description("Generate ESLint Rules")
.action(() => {
predict();
});
program.parse(process.argv);
Here is the problematic line:
let str = fs.readFileSync("data_files/rules.csv", "utf-8");
This is the error i get: ENOENT: no such file or directory, open 'data_files/rules.csv'

Importing a zip file and getting individual files in it, using Webpack

I have a standard webpack environment set up, and I am using ES6 imports with npm packages (the usual import name from 'package'). I'm using webpack-dev-server as my dev environment, and the standard webpack build for building the output directory.
I have a zip file in my source containing a large number of XML files, and in my JS program, I want to be able to read that zip file in and be able to extract individual files from it, so I can get the text from those files and process the XML in them.
I am currently using the xmldoc package for transforming XML text to a JSON object for processing, but I have not been able to find a reliable package for reading in a zip file (using the path to the file) and being able to get the individual files in it. In the ones I have tried, I have run into trouble with node's fs module. If I try adding the target: 'node' property to my webpack config file, I receive an error stating require is not defined.
Is there a reliable npm package compatible with ES6 imports that can read a zip file into my program? I realize that means the zip must be included in the build files to be sent to the browser, but that is better than including the hundreds of individual files without zipping them. Thanks!
I think you want browserfs. Here is example code from the readme. You will also need to do some config for webpack (check the readme):
fetch('mydata.zip').then(function(response) {
return response.arrayBuffer();
}).then(function(zipData) {
var Buffer = BrowserFS.BFSRequire('buffer').Buffer;
BrowserFS.configure({
fs: "MountableFileSystem",
options: {
"/zip": {
fs: "ZipFS",
options: {
// Wrap as Buffer object.
zipData: Buffer.from(zipData)
}
},
"/tmp": { fs: "InMemory" },
"/home": { fs: "IndexedDB" }
}
}, function(e) {
if (e) {
// An error occurred.
throw e;
}
// Otherwise, BrowserFS is ready to use!
});
});

nodeJS:fs.write callback and fs.writeFile not working

I knew nothing about fs until I was learning to use casperjs to scrape some content from a website and save them to a file. Following some examples on the web, I write this file scrape.js (The json data has been tested so it has nothing to do with the issue):
var fs = require('fs');
var url = "http://w.nycweb.io/index.php?option=com_k2&view=itemlist&id=4&Itemid=209&format=json";
var casper = require('casper').create();
casper.start(url,function(){
var json = JSON.parse(this.fetchText('pre'));
var jsonOfItems={},items = json.items;
items.forEach(function(item){
jsonOfItems[item.id] = item.introtext.split('\n');
})
fs.write('videoLinks.json',JSON.stringify(jsonOfItems),function(err){
if (err) console.log(err);
console.log('videoLinks.json saved');
})
});
casper.run();
When I do casperjs scrape.js in command line of my Ubuntu 14.04 server, I won't see the file saved message as expected, although the file is properly saved. So this is the first question: why the callback isn't running at all?
Secondly, I also tried fs.writeFile, but when I replace fs.write with it, the file isn't saved at all, nor is there any error information.
I do notice that in casper documentation it's said that casper is not a node.js module and some module of node.js won't be available, but I doubt it has anything to do with my issues. And I think it worths to mention that previously when I run this script I only get a respond like
I'm 'fs' module.
I had to follow this question to reinstall fs module globally to get it working.
fs.write expects a file descriptor where you are trying to give it a filename. Try fs.writeFile. https://nodejs.org/dist/latest-v4.x/docs/api/fs.html#fs_fs_writefile_file_data_options_callback
Edit: Oh you tried that. Are you sure it didn't write it somewhere like the root directory? Tried a full path in there?
And what version of node are you running?

How to upload file using easy-ftp in node?

I am trying to upload a file into my hosting server using node and easy-ftp.
I try with the following code:
var EasyFtp = require ("easy-ftp");
var ftp = new EasyFtp();
var config = {
host:'homexxxxx.1and1-data.host',
type:'SFTP',
port:'22',
username:'u90xxxx',
password:"mypass"
};
ftp.connect(config);
ftp.upload("/test/test.txt", "/test.txt", function(err){
if (err) throw err;
ftp.close();
});
No error message but no file uploaded
I tried the same using promises
const EasyFTP = require('easy-ftp-extra')
const ftp = new EasyFTP()
const config = {
host:'homexxxxx.1and1-data.host',
type:'SFTP',
port:'22',
username:'u90xxxx',
password:"mypass"
};
ftp.connect(config);
ftp.upload('/test.txt', '/test.txt')
.then(console.log)
.catch(console.error)
ftp.upload()
The same issued. No file is uploaded. No error in node console.
The config is the same used in filezilla to transfer files. SFTP protocol. Everything working well with filezilla.
What I am doing wrong?
Looks like you may have a path problem over here.
"/test/test.txt"
The path specified will try to take file from root folder like "c:\test\test.txt".
Assuming you want the file to be taken from your project folder try this path:
"./test/test.txt"
Other things in your code are precisely the same as in mine and mine works.
For me, it was just silently failing, and intelli-sense was not available.
npm remove easy-ftp
npm install easy-ftp
npm audit fix --force until no more vulnerabilities
Afterwards, intelli-sense was available and it started working.

Resources