Multiple Config in JSON for Node.js - node.js

I am not sure what to title my question.
Its been a adventure with node.js and a helpful person pointed me to ioredis. Currently I have:
var Redis = require("ioredis");
const DBConfig = require(__dirname+'/../Config.json');
var cluster = new Redis.Cluster([
{
port: 6001,
host: "10.0.0.6",
},
{
port: 6002,
host: "10.0.0.5",
},
{
port: 6003,
host: "10.0.0.4",
},
{
port: 6004,
host: "10.0.0.3",
},
{
port: 6005,
host: "10.0.0.2",
},
{
port: 6006,
host: "10.0.0.1",
},
]);
But to me this seems it would be better in a json config file like...
Config.json:
{
"configA" : "abc",
"someotherconfigB" : "Stuff",
"foo" : "bar"
}
{
"port": 6001,
"host": "10.0.0.6",
},
{
"port": 6002,
"host": "10.0.0.5",
},
{
"port": 6003,
"host": "10.0.0.4",
},
{
"port": 6004,
"host": "10.0.0.3",
},
{
"port": 6005,
"host": "10.0.0.2",
},
{
"port": 6006,
"host": "10.0.0.1",
},
}
I am so new and this I just not sure how to implement this without syntax errors.
var Redis = require("ioredis");
const DBConfig = require(__dirname+'/../Config.json');
var cluster = new Redis.Cluster([DBConfig.redis]);
I am not sure how to implement "var cluster = new Redis.Cluster([DBConfig.redis]);" properly

You should declare those settings in as an array under a key
{
"configA" : "abc",
"someotherconfigB" : "Stuff",
"foo" : "bar",
"redisCluster": [
{
"port": 6001,
"host": "10.0.0.6"
},
{
"port": 6002,
"host": "10.0.0.5"
},
{
"port": 6003,
"host": "10.0.0.4"
}
]
}
Then use that key to access that value inside the required config file.
const DBConfig = require('../Config.json');
const cluster = new Redis.Cluster(DBConfig.redisCluster);

First, you need to have a proper config file. Your file seems to contain some config information and node information. I would suggest:
Config.json file:
{
"configs": {
"configA": "abc",
"someotherconfigB": "Stuff",
"foo": "bar"
},
"nodes": [
{
"port": 6001,
"host": "10.0.0.6"
},
{
"port": 6002,
"host": "10.0.0.5"
},
{
"port": 6003,
"host": "10.0.0.4"
},
{
"port": 6004,
"host": "10.0.0.3"
},
{
"port": 6005,
"host": "10.0.0.2"
},
{
"port": 6006,
"host": "10.0.0.1"
}
]
}
Then your file should look like:
const Redis = require('ioredis');
const DBConfig = require(__dirname + '/Config.json');
const cluster = new Redis.Cluster(DBConfig.nodes);
Object.entries(DBConfig.configs).map(([key, value]) => {
cluster.set(key, value);
});
DBConfig.nodes it's already an array. No need to put brackets around it
Object.entries(DBConfig.configs) will give you an array of [key, value] pairs of your DBConfig.configs's properties
Resources:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries

Related

How to Config next-images with existing next.config.js file

I want to use the npm package next-images in my nextjs app.
After reading the documentation for next-images, it says you need to create a next.config.js file with the following code:
const withImages = require('next-images')
module.exports = withImages()
However I already have a next.config.js file, currently it has code inside it that looks like this:
var fs = require('fs');
const nextConfig = {
reactStrictMode: true,
images: {
remotePatterns: [
{
protocol: "http",
hostname: "**",
},
{
protocol: "https",
hostname: "**",
},
],
},
env: {
customSnipcartJS: fs.readFileSync('public/file2.js').toString(),
snipcartInstallJS: fs.readFileSync('public/file1.js').toString()
}
}
module.exports = nextConfig
So my question is, how do I merge the required config code for next-images with my existing configuration I already have in my next.config.js
In case someone else runs in to something like this I found a solution.
I managed to get this to work, you can pass your custom next config in to the withImages method.
So this now works.
var fs = require('fs');
const withImages = require('next-images');
module.exports = withImages({
reactStrictMode: true,
images: {
disableStaticImages: true,
remotePatterns: [
{
protocol: "http",
hostname: "**",
},
{
protocol: "https",
hostname: "**",
},
],
},
env: {
customSnipcartJS: fs.readFileSync('public/file2.js').toString(),
snipcartInstallJS: fs.readFileSync('public/file1.js.js').toString()
}
})

Express generator and Sequelize to AWS Elastic BeanStalk

I made a API express app using express generator and Sequelize ORM, it works great on my local machine using sqlite, I had it deployed on Heroku at one point, but not much for tutorials on how to deploy to AWS Elastic Beanstalk....
bin/www
...
const { sequelize } = require('../models');
...
(async() => {
try {
await sequelize.authenticate();
await sequelize.sync();
console.log(`Connection successful!! on port:${port}`)
}catch(err) {
console.log("Connection failed:", err)
}
}) ();
config/config.json- this worked with postgres on heroku at one point
{
"development": {
"username": "root",
"password": null,
"database": "database_development",
"storage" : "GetNailed",
"dialect": "sqlite"
},
"test": {
"username": "root",
"password": null,
"database": "database_test",
"host": "127.0.0.1",
"dialect": "mysql"
},
"production": {
"use_env_variable": "DATABASE_URL",
"dialect": "postgres",
"dialectOptions": {
"ssl": {
"require": true,
"rejectUnauthorized": false
}
}
}
}
app.js
...
const {sequelize} = require('./models')
async function main() {
await sequelize.sync()
}
main()
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
const adminRouter =require('./routes/admin');
const nailsRouter = require('./routes/nails')
...

How to create JSON nested Objects using NodeJS and JSON.stringify()

My problem is in the port_password.
{
"server": "0.0.0.0",
"server_ipv6": "::",
"local_address": "127.0.0.1",
"local_port": 1080,
"timeout": 120,
"method": "aes-256-cfb",
"protocol": "origin",
"protocol_param": "",
"obfs": "tls1.2_ticket_auth",
"obfs_param": "",
"redirect": "",
"dns_ipv6": false,
"fast_open": true,
"workers": 1,
"port_password": "{\"10000\":\"pass\",\"10001\":\"pass\",\"10002\":\"pass\",}"
}
The code I used to generate JSON.
account.forEach(ssr => {
portsPasswords += JSON.stringify(ssr.port.toString()) + ':' + JSON.stringify(ssr.password.toString()) + ','
})
I want the output something like this. How can I achieve that using NodeJS and JSON.stringfy()?
{
"server": "0.0.0.0",
"server_ipv6": "::",
"local_address": "127.0.0.1",
"local_port": 1080,
"timeout": 120,
"method": "aes-256-cfb",
"protocol": "origin",
"protocol_param": "",
"obfs": "tls1.2_ticket_auth",
"obfs_param": "",
"redirect": "",
"dns_ipv6": false,
"fast_open": true,
"workers": 1,
"port_password": {
"10000":"pass",
"10001":"pass",
"10002":"pass"
}
}
reduce into an object instead:
const account = [
{ port: 10000, password: 'pass1' },
{ port: 10001, password: 'pass2' },
{ port: 10002, password: 'pass3' }
];
const port_password = account.reduce((a, { port, password }) => {
a[port] = password;
return a;
}, {});
const entireObj = {
"server": "0.0.0.0",
// etc
port_password
};
console.log(JSON.stringify(entireObj));

Typeorm connect to multiple database

I use node.js , TS and typeorm for back-end project.
I need to connect to a different database in the middleware according to the parameter I send.
And I've got to send the query to the database.
ormconfig
[
{
"name": "default",
"type": "postgres",
"host": "localhost",
"port": 5432,
"username": "postgres",
"password": "12345",
"database": "dbOne"
},
{
"name": "second-connection",
"type": "postgres",
"host": "localhost",
"port": 5432,
"username": "postgres",
"password": "12345",
"database": "dbTwo"
}
]
That's my connection settings.
After I do that, I'm trying to connect to the middleware.
const connectionOptions = await getConnectionOptions("second-connection");
const conTwo = await createConnection(connectionOptions);
const managerTwo = getManager("second-connection");
const resultTwo = await managerTwo
.createQueryBuilder(SysCompany, "company")
.getOne();
console.log(resultTwo);
I think I can connect to the database, but I'm having trouble with the repository.
Error
EntityMetadataNotFound: No metadata for "SysCompany" was found.
#Entity()
export class SysCompany extends CoreEntityWithTimestamp {
#Column({ length: 100 })
name: string;
// FK
// SysPersonnel
#OneToMany(type => SysPersonnel, personnel => personnel.sysCompany)
sysPersonnels: SysPersonnel[];
}
Maybe typeORM cannot find your JavaScript entity. I had that problem some time ago. You can do the following:
Check your destination folder after you built the project. Is your SysCompany.js available?
Set the entities property in the configuration. It must contain the path to your JS entities. The typeORM docs state that "Each entity must be registered in your connection options".
{
"name": "second-connection",
"type": "postgres",
"host": "localhost",
"port": 5432,
"username": "postgres",
"password": "12345",
"database": "dbTwo"
"entities": ["<path to entities>/**/*.js"]
}
I would also recommend to use a JavaScript configuration file. Your ormconfig.js can then use __dirname (directory name of the current module) to set the path. So if your directories look like this:
project/ormconfig.js
project/dist/entity/SysCompany.js
project/dist/entity/OtherEntity.js
You can use a configuration like this:
import {join} from "path";
...
entities: [
join(__dirname, "dist/entity/**/*.js")
],
...
You could also prevent duplication by using a base configuration object.
import {join} from "path";
const baseOptions = {
type: "postgres",
host: "localhost",
port: 5432,
username: "postgres",
password: "12345",
entities: [
join(__dirname, "dist/entity/**/*.js")
]
}
const defaultConfig = Object.assign({
name: "default",
database: "dbOne",
}, baseOptions);
const secondConfig = Object.assign({
name: "second-connection",
database: "dbTwo",
}, baseOptions);
module.exports = [ defaultConfig, secondConfig ];
In the file where you open the connection you could use an import:
import { secondConfig } from "<path to file>/ormconfig";
const conTwo = await createConnection(secondConfig);
The simplest way to use multiple databases is to create different connections:
import {createConnections} from "typeorm";
const connections = await createConnections([{
name: "db1Connection",
type: "mysql",
host: "localhost",
port: 3306,
username: "root",
password: "admin",
database: "db1",
entities: [__dirname + "/entity/*{.js,.ts}"],
synchronize: true
}, {
name: "db2Connection",
type: "mysql",
host: "localhost",
port: 3306,
username: "root",
password: "admin",
database: "db2",
entities: [__dirname + "/entity/*{.js,.ts}"],
synchronize: true
}]);
This approach allows you to connect to any number of databases you have and each database will have its own configuration, own entities and overall ORM scope and settings.
For each connection a new Connection instance will be created. You must specify a unique name for each connection you create.
The connection options can also be loaded from an ormconfig file. You can load all connections from the ormconfig file:
import {createConnections} from "typeorm";
const connections = await createConnections();
or you can specify which connection to create by name:
import {createConnection} from "typeorm";
const connection = await createConnection("db2Connection");
When working with connections you must specify a connection name to get a specific connection:
import {getConnection} from "typeorm";
const db1Connection = getConnection("db1Connection");
// you can work with "db1" database now...
const db2Connection = getConnection("db2Connection");
// you can work with "db2" database now...
Benefit of using this approach is that you can configure multiple connections with different login credentials, host, port and even database type itself. Downside for might be that you'll need to manage and work with multiple connection instances.

Laravel Echo Server can not be authenticated, got HTTP status 500

I've installed both Laravel echo server and Laravel echo client.
Following is the laravel-echo-server.json configuration.
{
"authHost": "http://taxation.com",
"authEndpoint": "/broadcasting/auth",
"clients": [
{
"appId": "APP_ID",
"key": "someKey"
}
],
"database": "redis",
"databaseConfig": {
"redis": {},
"sqlite": {
"databasePath": "/database/laravel-echo-server.sqlite"
}
},
"devMode": true,
"host": "127.0.0.1",
"port": "3000",
"protocol": "http",
"socketio": {},
"sslCertPath": "",
"sslKeyPath": "",
"sslCertChainPath": "",
"sslPassphrase": ""
}
The following script listens for channel events. It builds fine with npm run dev.
import Echo from 'laravel-echo'
let token = document.head.querySelector('meta[name="token"]');
if (token) {
window.axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content;
} else {
console.error('CSRF token not found: https://laravel.com/docs/csrf#csrf-x-csrf-token');
}
window.Echo = new Echo({
broadcaster: 'socket.io',
host: '127.0.0.1:3000',
reconnectionAttempts: 5
});
window.Echo.join('checked-in-1')
.listen('.user.checked_in', (e) => {
console.log(e);
});
When trying to listen for any event on start laravel-echo-server command. It keeps throwing Client can not be authenticated, got HTTP status 500.
Note :
I really didn't find anything helpful on laravel-echo-serve nor on google.
Any help will be appreciated a lot.
Laravel V5.4
Thanks
Just getting the issue because of CSRF token. Didn't passed the token to the echo.
window.Echo = new Echo({
broadcaster: 'socket.io',
host: '127.0.0.1:3000',
reconnectionAttempts: 5,
csrfToken: token.content <--
});

Resources