Exporting sqlite3 db file from inside electron app. Is this possible? - node.js

I've got an app I've put together in Electron which saves data using sqlite3. Everything works as expected. I'd like to be able to export/save the actual database file so I can share it with others, treating it sort of like a save file.
I assume that if this is possible then I need to be using fs as well, which is fine.
Even better, can I just create the database file outside the compiled app from the start? And if so what's the best way to accomplish that?
Otherwise I can switch over to kripken/sql.js or something like that, but I'd rather not put the time in to make those changes if there's an easy way to just have the existing sqlite database file get saved to the user's computer outside the app.

I'm an idiot.
Instead of storing the file internally in the packaged app like this…
const dbPath = path.resolve(__dirname, 'data.db')
…I'm just storing it in the filesystem like this…
const {app} = require('electron').remote;
const dbPath = path.resolve(app.getPath('userData'), 'data.db');
…so that it's accessible from the start.
I'm leaving this question up because I'd be interested if there is a way to have a save file dialogue for an extant file in the packaged app, but in the mean time this is my answer.

Related

node and express - how to use fake data

It's been a while since I used node and express and I was sure that this was possible, but i'm having an issue of figuring it out now.
I have a simple postgres database with sequelize. I am building a back end and don't have a populated database yet. I want to be able to provide fake data to use to build the front end and to test with. Is there a way to populate a database when the node server is started? Maybe by reading a json file into the database?
I know that I could point to this fake data using a setting in the environment file, but I don't see how to read in the data on startup. Is there a way to create a local database, read in the data, and point to that?
You can use fake factory package, I think it can solve your problem.
https://www.npmjs.com/package/faker-factory
FakerJs provides that solution.
import { faker } from '#faker-js/faker';
const randomName = faker.name.findName();
const randomEmail = faker.internet.email();
with the above, you can run a loop for loop to be specific to create
the desired data you may need for your project.
Also, check on the free web-API that provides fake or real data to workon

MongoDB and Mongoose databases not connecting across directories

I have a web server running, that uses mongoDB to store posts created on the website.
I would like to use a separate script to manage some things on the site, however for some reason I can't seem to get the code working across directories.
The website is running in /home/username/program/
I want my utility script to reside in /home/myname/utils/
This is currently the script I have:
#!/usr/bin/nodejs
var mongoose = require('mongoose');
var db = mongoose.connect('mongodb://localhost/db_name',{useNewUrlParser:true});
var chat = require('/home/username/project/lib/models/chat');
chat.findOne(function(err,doc) {
console.log(err,doc);
});
This code works, and gets data, but only if the file it's written it resides in /home/username/project/lib/.
If the file is in /home/mynameutil/ then it doesn't get any data at all. Why is this?
It is appropriate, because you don't start your project on /home/username so your program shared same instance, If you want to create something across the folder considers using workspaces.
Some tools make it easy to create workspaces like yarn and pnpm with this your code can be run in the same instance and share same node_modules. So you can use it across folder

How should I load a file that is inside my own module?

Current code in /config/index.js
const options = (require('js-yaml')).safeLoad(
(require('fs')).readFileSync(`./config/default-config.yaml`, "utf8"));
module.exports = options;
Works fine. Until I publish and use it in my other project. Then it's unable to find the file (naturally) as ./config/default-config.yaml doesn't exist in that project.
The only option I can think of involves checking to see if the file exists at that path, then trying to load it from node_modules/#company/alpha-gamma/config/default-config.yaml. This seems really hacky.
The config object is large, 200+ keys. I don't think it belongs in the code.
What's the best solution for loading a file that exists inside your module? I need to be able to load it for unit tests before publishing and load it at runtime when the library is required by another module.
Maybe the best alternative is to use json since I can then use the require module to load it in, instead of fs.
While I originally suggested utilizing __dirname as a valid option, I was wrong. Calling process.cwd() to fetch the application root and building the path off of that is the best approach.
As documented here:
Proper way to reference files relative to application root in Node.JS

Desktop Top Save Location For User Storage?

While writing a node-webkit application I came across needing to save users uploaded photos through the built in html file input. I can save photos easy enough where I wish via a nice post here on node file uploading and node-webkit's file dialog changes simple enough.
The question really is there a best practice for saving user generated content for a desktop app or is the application folder (OS specific) reasonable to use with say the application or company name? Security is not much of a concern here in this case.
node-webkit (at this time) has an application folder under under process.env.LOCALAPPPATH (for windows users anyway) which could be used.
Another option which is viable is to use an application directory in the exe directory of the program.
IE for node with process global.
var path = require('path');
var appDir = path.dirname( process.execPath ) + path.sep + 'data' + path.sep;
//might produce something like c:\\programs\\node-webkit\\data\\

Temporary File Download

Is there a service that creates basically a one-time download of a file, preferably something I can use from NodeJS?
I've done some research on FilePicker, and haven't found anything about regenerating the link it gives you for a file. There may be a way to do this with NodeJS, but I'm using Meteor at the same time so many Node things probably will conflict.
You could build it with meteor. Using meteor-router with meteorite & use server side routing to deliver the files.
You need a collection to keep track of downloaded files:
Server JS
var downloads = new Meteor.Collection("downloads");
//create a link
downloads.insert({url:"/mydownload.zip",downloaded:false})
Meteor.Router.add('/file/:id', 'GET', function(id) {
download = downloads.findOne(id);
if( download) {
if(dowload.downloaded) {
this.response.send("You've already downloaded me")
}
else
{
//I guess you could just redirect or stream the file for an extra layer of surety
this.response.redirect(download.url);
}
}
});
On the client you can use /files/{{_id}} with _id of the file from downloads the person has as the link
My recommendation would also be to add custom server-side logic to count # of uploads (or just flag a file as downloaded/not downloaded) and respond accordingly. The closest you could do with Filepicker.io would be using the security policies to restrict downloading the file to a specific time interval.
in addition to using the router package
in Meteor.startup you can add
var require = __meteor_bootstrap__.require;
fs = require( 'fs' );
the fs variable should be declared on the server only. the fs package is used by Meteor and does not need to be added separately.
once you have done this, you can create files with Meteor.uuid() as their name which makes them unique and very difficult to guess. It is also possible to delete the file after a certain amount of time by using Meteor.setTimeout
the question is: where do the files to be downloaded come from?
Solution using Heroku Cloud and NodeJS Meteor Hooks
Heroku in particular is actually great for temporary file download links: they offer a "temporary scratchpad" filesystem that is reset every time the program restarts, and each running Node server cannot see the files other instances have created.
Each dyno gets its own ephemeral filesystem, with a fresh copy of the
most recently deployed code. During the dyno’s lifetime its running
processes can use the filesystem as a temporary scratchpad, but no
files that are written are visible to processes in any other dyno and
any files written will be discarded the moment the dyno is stopped or
restarted.
Taken from the Heroku documentation: https://devcenter.heroku.com/articles/dynos#ephemeral-filesystem
Thus, any files written to the "filesystem" will be temporary.
This allows for a very easy solution to this problem: you can simply use NodeJS filesystem manipulation to create temporary files on the server, serve them once (or for a limited time), and then remove them so they cannot be downloaded again.
This in combination with something like $.download() will make a seamless experience which in turn prevents unauthorized downloads.

Resources