DOTENV not reading variables properly - javascript

This is my file:
postgresU="myuser"
postgresP="mypass"
postgresH="myhost"
postgresDB="mydb"
postgresC="postgres://${postgresU}:{$postgresP}#{$postgresH}:5432/${postgresDB}"
In my nodejs app,
require('dotenv').config();
var connectionString = process.env.postgresC;
console.log("Connection String:",connectionString);
This prints:
Connection String: "postgres://${postgresU}:${postgresP}#${postgresH}:5432/${postgresDB}"
What am I doing wrong?

You can use a package like dotenv-expand if you want to expand variables in .evn files.
Once installed (with npm or yarn) you can simply use a .env file with:
postgresU="myuser"
postgresP="mypass"
postgresH="myhost"
postgresDB="mydb"
postgresC="postgres://${postgresU}:${postgresP}#${postgresH}:5432/${postgresDB}"
and then process it with:
const dotenv= require('dotenv')
const dotenvExpand = require('dotenv-expand')
let myEnv = dotenv.config()
dotenvExpand(myEnv)
let connectionString = process.env.postgresC;
console.log(connectionString)
postgres://myuser:mypass#myhost:5432/mydb

Related

Check if child_process can run a command in NodeJS

how can I check if child_process can run a command?
'echo' is a valid command that can be run in a terminal, but 'echoes' is not one. For example, if I do this
const cp = require('child_process')
cp.exec('echo hello')
it will work.
If I do this, though
const cp = require('child_process')
cp.exec('echoes hello') //notice how it is echoes instead of echo
it will just error, but maybe the user has a program that adds 'echoes' to a terminal, and in that case, it would be able to run, but if it errors it will just exit out of the process and I won't be able to check if it works.
Is there any way to do this? Thank you so much in advance!
You have to manually loop through dirs in $PATH env & perform look up on those directory.
eg: $PATH is set to /bin:/usr/local/bin then you have to perform
fs.access('/bin/' + command, fs.constants.X_OK)
and
fs.access('/usr/local/bin/' + command, fs.constants.X_OK)
solution would look like this.
const { constants: fsconsts } = require('fs')
const fs = require('fs/promises')
const path = require('path')
const paths = process.env.PATH.split(':')
async function isExecutable(command) {
const cases = []
for (const p of paths) {
const bin = path.join(p, command)
cases.push(fs.access(bin, fsconsts.X_OK)) // X_OK is bit flag which makes sure file is executable
}
await Promise.any(cases)
return command
}
const found = (bin) => console.log('found', bin)
const notfound = (errors) => {
console.log('not found or not executable')
// console.error(errors)
}
// passes
isExecutable('echo').then(found).catch(notfound)
isExecutable('node').then(found).catch(notfound)
// fails
isExecutable('shhhhhh').then(found).catch(notfound)
isExecutable('echoes').then(found).catch(notfound)
NOTE: I think my solution works only on *nix based OSs

How can I choose the NODE_ENV in windows terminal without using npm?

I'm studying a NodeJs course, the main purpose of this course is to learn NodeJS without using npm, so we reached a stage where we defined our environment variable for staging and production, and I couldn't switch between the NODE_ENV from cmd terminal, we have a config.js file that exports the environment, the index.js imports them and based on the NODE_ENV asked for, it give it to you .
-so this is the config.js script :
/*
**** Creating and exporting config variables
*/
//
var environments = {};
//
environments.staging ={
'port' : 3000,
'envName' : 'staging',
}
environments.production ={
'port' : 5000,
'envName' : 'production',
}
//
var currentEnvironment = typeof(process.env.NODE_ENV) == 'string' ? process.env.NODE_ENV.toLowerCase() :'';
//
var environmentToExport = typeof(environments[currentEnvironment]) == 'object' ? environments[currentEnvironment] : environments.staging;
//
module.exports = environmentToExport;
and the Index.js script is this :
var http = require('http');
var url = require('url');
var stringDecoder = require('string_decoder').StringDecoder;
var config = require('./config');
var server = http.createServer((req,res)=>{ to many lines i coudln't paste them });
server.listen(config.port,()=>{
console.log("Server listening on port Nº : "+config.port+" in "+config.envName+" environment ");
});
So how can I choose the NODE_ENV from terminal ?
As the NODE_ENV is an Environment Variable, you can change this option on the terminal session with the command set (on CMD):
set NODE_ENV=production
node index.js

Node.js require multiple files in the same folder

I'm building a discord bot with node.js for my server and I have a bunch of commands for the bot. Each command is in a different file so I have a lot of const cmd = require("../commands/cmd.js");
const kick = require("../commands/kick");
const info = require("../commands/info");
const cooldown = require("../commands/cooldown");
const help = require("../commands/help");
Is there a simpler way to do this?
Inside folder commands put a file called index.js.
Each time you implement new commands in new file, require that file in index.js and then add it to the exports of it. For example index.js would be:
const kick = require('./kick');
const info = require('./info');
module.exports = {
kick: kick,
info: info
}
And then from any folder you can require multiple commands in one line like this:
const { kick, info } = require('../commands');
Export an object from one file instead?
const kick = require("../commands/kick");
const info = require("../commands/info");
const cooldown = require("../commands/cooldown");
const help = require("../commands/help");
const commands = {
kick,
info,
...
}
module.exports = commands;
And then:
const commands = require('mycommands')
commands.kick()
Create index.js file inside the command folder and then you can export an object like this.
const kick = require("../commands/kick");
const info = require("../commands/info");
const cooldown = require("../commands/cooldown");
const help = require("../commands/help");
const command = {
kick,
info,
cooldown,
help
};
module.exports = command;
You can import and use it like this:
const {kick, info} = require('./commands');

Electron: Load a file with `executeJavaScript`

I need to inject an NPM package into a BrowserView by using executeJavaScript. The package is Web3 and here is what I've tried so far.
import Web3 from 'web3'
const web3 = '' + Web3; // stringify the Web3 class
view.webContents.executeJavaScript(`
const provider = // ... provider got injected successfully because it doesn't have dependencies.
const web3 = new ${web3}(provider);
`)
But this throws the following error.
Uncaught ReferenceError: core is not defined
at new Web3 (<anonymous>:45:5)
at <anonymous>:41:16
Web3 is trying to load its core dependency which unfortunately did not get stringified.
So my question is, how can I load this whole package into the BrowserView? Aka how can you load npm package in the browser, if you do not have control over <script /> tags (at least I wouldn't know how to inject those in Electron)?
Update:
Because of what OJ Kwon suggested in the comments, I tried bundling Web3 with Browserify by running
browserify packages/web3/src/index.js -o web3-bundle.js
. It seemed to have worked, because at the very end of the bundled file (web3-bundle.js) it says:
// ... 50k+ lines long file
var version = require('../package.json').version;
var core = require('web3-core');
var Eth = require('web3-eth');
var Net = require('web3-net');
var Personal = require('web3-eth-personal');
var Shh = require('web3-shh');
var Bzz = require('web3-bzz');
var utils = require('web3-utils');
var Web3 = function Web3() {
var _this = this;
// sets _requestmanager etc
core.packageInit(this, arguments);
this.version = version;
this.utils = utils;
this.eth = new Eth(this);
this.shh = new Shh(this);
this.bzz = new Bzz(this);
// overwrite package setProvider
var setProvider = this.setProvider;
this.setProvider = function (provider, net) {
setProvider.apply(_this, arguments);
this.eth.setProvider(provider, net);
this.shh.setProvider(provider, net);
this.bzz.setProvider(provider);
return true;
};
};
Web3.version = version;
Web3.utils = utils;
Web3.modules = {
Eth: Eth,
Net: Net,
Personal: Personal,
Shh: Shh,
Bzz: Bzz
};
core.addProviders(Web3);
module.exports = Web3;
Now, I'm trying to import and include it like this:
const Web3 = require('./web3-bundle.js');
which doesn't work. It says undefined is not a constructor.
const Web3 = require('./web3-bundle.js').Web3;
and
const Web3 = require('./web3-bundle.js').default;
both didn't work, either. How should one do this?
Update 2:
Inspecting the bundle further, it has uses exports. and module.exports =. My editor only suggests methods and objects exported with exports. as importable 🤔
I suggest you to use this boilerplate or a boilerplate including a good webpack configuration (suggested boilerplate).
Follow these steps:
Clone the repository
Run yarn install
Run yarn add web3
Add import Web3 from 'web3'; into the app/containers/HomePage.js file (react render view).
Enjoy

Environment variables not found during Mocha unit test Node.js

I am trying to run a mocha unit test but one of the modules used by the module I am testing on requires environment variables such as process.env.CLIENT_ID through dotenv. When I run my Mocha test, these environment variables are not found. How can I can include environment variables from a .env file in my mocha unit tests?
test.js:
var messenger = require(__dirname + "/../routes/messenger.js");
var assert = require("assert")
describe("Return Hello", function(){
it('Should return hello',function(done){
messenger.testFunction(function(value){
assert(value === "Hello", 'Should return Hello')
done()
})
})
})
Section of file that contains the problem that goes through unit test:
var express = require("express")
var router = express.Router();
require('dotenv').config()
var plaid = require('plaid');
var mysql = require('mysql');
var fs = require("fs");
const plaidClient = new plaid.Client(
process.env.PLAID_CLIENT_ID, // these are all not found
process.env.PLAID_SECRET,
process.env.PLAID_PUBLIC_KEY,
plaid.environments.sandbox);
to me the most elegant way of setting your env before the tests is inside package.json.
Here is an example to adapt to your own npm test command:
"scripts": {
"test": "mocha -r dotenv/config"
}
The main idea is to add the -r dotenv/config.
The method works as well with dotenv-flow, do not forget to add NODE_ENV=test at the beginning of the command.
It works as well with nodemon.
I found the solution. I had to link the dotenv config explicitly to the location to the .env file by adding the path: options of the .config() method.
Example:
var envPath = __dirname + "/../.env"
require('dotenv').config({path:envPath})
// ^ this was incorrect
var express = require("express")
var router = express.Router();
var plaid = require('plaid');
var mysql = require('mysql');
var fs = require("fs");
const plaidClient = new plaid.Client(
process.env.PLAID_CLIENT_ID,
process.env.PLAID_SECRET,
process.env.PLAID_PUBLIC_KEY,
plaid.environments.sandbox);
The below thing worked for me ;)
"scripts": {
"test": "set DOTENV_CONFIG_PATH=test.env && mocha -r dotenv/config ",
}

Categories