feat(cli): create DB in start command if not exists (#285)
This commit is contained in:
@@ -1,42 +1,3 @@
|
||||
import appConfig from '../../src/config/app';
|
||||
import logger from '../../src/helpers/logger';
|
||||
import client from './client';
|
||||
|
||||
const createDatabaseAndUser = async () => {
|
||||
if(appConfig.appEnv !== 'development' && appConfig.appEnv !== 'test') {
|
||||
const errorMessage = 'Database creation can be used only with development or test environments!'
|
||||
logger.error(errorMessage)
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
await client.connect();
|
||||
await createDatabase();
|
||||
await createDatabaseUser();
|
||||
await grantPrivileges();
|
||||
|
||||
await client.end();
|
||||
}
|
||||
|
||||
const createDatabase = async () => {
|
||||
await client.query(`CREATE DATABASE ${appConfig.postgresDatabase}`);
|
||||
logger.info(`Database: ${appConfig.postgresDatabase} created!`);
|
||||
}
|
||||
|
||||
const createDatabaseUser = async () => {
|
||||
await client.query(`CREATE USER ${appConfig.postgresUsername}`);
|
||||
logger.info(`Database User: ${appConfig.postgresUsername} created!`);
|
||||
}
|
||||
|
||||
const grantPrivileges = async () => {
|
||||
await client.query(
|
||||
`GRANT ALL PRIVILEGES ON DATABASE ${appConfig.postgresDatabase} TO ${appConfig.postgresUsername};`
|
||||
);
|
||||
|
||||
logger.info(
|
||||
`${appConfig.postgresUsername} has granted all privileges on ${appConfig.postgresDatabase}!`
|
||||
);
|
||||
|
||||
}
|
||||
import { createDatabaseAndUser } from './utils';
|
||||
|
||||
createDatabaseAndUser();
|
||||
|
@@ -1,29 +1,3 @@
|
||||
import appConfig from '../../src/config/app';
|
||||
import logger from '../../src/helpers/logger';
|
||||
import client from './client';
|
||||
|
||||
const dropDatabase = async () => {
|
||||
if (appConfig.appEnv != 'development' && appConfig.appEnv != 'test') {
|
||||
const errorMessage = 'Drop database command can be used only with development or test environments!'
|
||||
|
||||
logger.error(errorMessage)
|
||||
return;
|
||||
}
|
||||
|
||||
await client.connect();
|
||||
await dropDatabaseAndUser();
|
||||
|
||||
await client.end();
|
||||
}
|
||||
|
||||
const dropDatabaseAndUser = async() => {
|
||||
await client.query(`DROP DATABASE IF EXISTS ${appConfig.postgresDatabase}`);
|
||||
logger.info(`Database: ${appConfig.postgresDatabase} removed!`);
|
||||
|
||||
await client.query(`DROP USER IF EXISTS ${appConfig.postgresUsername}`);
|
||||
logger.info(`Database User: ${appConfig.postgresUsername} removed!`);
|
||||
}
|
||||
|
||||
|
||||
import { dropDatabase } from './utils';
|
||||
|
||||
dropDatabase();
|
||||
|
@@ -1,15 +1,3 @@
|
||||
import User from '../../src/models/user';
|
||||
import '../../src/config/orm';
|
||||
import logger from '../../src/helpers/logger';
|
||||
|
||||
const userParams = {
|
||||
email: 'user@automatisch.io',
|
||||
password: 'sample',
|
||||
};
|
||||
|
||||
async function createUser() {
|
||||
const user = await User.query().insertAndFetch(userParams);
|
||||
logger.info(`User has been saved: ${user.email}`);
|
||||
}
|
||||
import { createUser } from './utils';
|
||||
|
||||
createUser();
|
||||
|
100
packages/backend/bin/database/utils.ts
Normal file
100
packages/backend/bin/database/utils.ts
Normal file
@@ -0,0 +1,100 @@
|
||||
import appConfig from '../../src/config/app';
|
||||
import logger from '../../src/helpers/logger';
|
||||
import client from './client';
|
||||
import User from '../../src/models/user';
|
||||
import '../../src/config/orm';
|
||||
|
||||
export async function createUser(email = 'user@automatisch.io', password = 'sample') {
|
||||
const UNIQUE_VIOLATION_CODE = '23505';
|
||||
const userParams = {
|
||||
email,
|
||||
password,
|
||||
};
|
||||
|
||||
try {
|
||||
const user = await User.query().insertAndFetch(userParams);
|
||||
logger.info(`User has been saved: ${user.email}`);
|
||||
} catch (err) {
|
||||
if ((err as any).nativeError.code !== UNIQUE_VIOLATION_CODE) {
|
||||
throw err;
|
||||
}
|
||||
|
||||
logger.info(`User already exists: ${email}`);
|
||||
}
|
||||
}
|
||||
|
||||
export const createDatabaseAndUser = async (database = appConfig.postgresDatabase, user = appConfig.postgresUsername) => {
|
||||
await client.connect();
|
||||
await createDatabase(database);
|
||||
await createDatabaseUser(user);
|
||||
await grantPrivileges(database, user);
|
||||
|
||||
await client.end();
|
||||
}
|
||||
|
||||
export const createDatabase = async (database = appConfig.postgresDatabase) => {
|
||||
const DUPLICATE_DB_CODE = '42P04';
|
||||
|
||||
try {
|
||||
await client.query(`CREATE DATABASE ${database}`);
|
||||
logger.info(`Database: ${database} created!`);
|
||||
} catch (err) {
|
||||
if ((err as any).code !== DUPLICATE_DB_CODE) {
|
||||
throw err;
|
||||
}
|
||||
|
||||
logger.info(`Database: ${database} already exists!`);
|
||||
}
|
||||
}
|
||||
|
||||
export const createDatabaseUser = async (user = appConfig.postgresUsername) => {
|
||||
const DUPLICATE_OBJECT_CODE = '42710';
|
||||
|
||||
try {
|
||||
const result = await client.query(`CREATE USER ${user}`);
|
||||
logger.info(`Database User: ${user} created!`);
|
||||
|
||||
return result;
|
||||
} catch (err) {
|
||||
if ((err as any).code !== DUPLICATE_OBJECT_CODE) {
|
||||
throw err;
|
||||
}
|
||||
|
||||
logger.info(`Database User: ${user} already exists!`);
|
||||
}
|
||||
}
|
||||
|
||||
export const grantPrivileges = async (
|
||||
database = appConfig.postgresDatabase, user = appConfig.postgresUsername
|
||||
) => {
|
||||
await client.query(
|
||||
`GRANT ALL PRIVILEGES ON DATABASE ${database} TO ${user};`
|
||||
);
|
||||
|
||||
logger.info(
|
||||
`${user} has granted all privileges on ${database}!`
|
||||
);
|
||||
}
|
||||
|
||||
export const dropDatabase = async () => {
|
||||
if (appConfig.appEnv != 'development' && appConfig.appEnv != 'test') {
|
||||
const errorMessage = 'Drop database command can be used only with development or test environments!'
|
||||
|
||||
logger.error(errorMessage)
|
||||
return;
|
||||
}
|
||||
|
||||
await client.connect();
|
||||
await dropDatabaseAndUser();
|
||||
|
||||
await client.end();
|
||||
}
|
||||
|
||||
export const dropDatabaseAndUser = async(database = appConfig.postgresDatabase, user = appConfig.postgresUsername) => {
|
||||
await client.query(`DROP DATABASE IF EXISTS ${database}`);
|
||||
logger.info(`Database: ${database} removed!`);
|
||||
|
||||
await client.query(`DROP USER IF EXISTS ${user}`);
|
||||
logger.info(`Database User: ${user} removed!`);
|
||||
}
|
||||
|
2
packages/backend/database.d.ts
vendored
Normal file
2
packages/backend/database.d.ts
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
export * as utils from './dist/bin/database/utils';
|
||||
export * as database from './dist/src/config/database';
|
3
packages/backend/database.js
Normal file
3
packages/backend/database.js
Normal file
@@ -0,0 +1,3 @@
|
||||
/* eslint-disable */
|
||||
module.exports.utils = require('./dist/bin/database/utils');
|
||||
module.exports.database = require('./dist/src/config/database');
|
1
packages/backend/logger.d.ts
vendored
Normal file
1
packages/backend/logger.d.ts
vendored
Normal file
@@ -0,0 +1 @@
|
||||
export * from './dist/src/helpers/logger';
|
2
packages/backend/logger.js
Normal file
2
packages/backend/logger.js
Normal file
@@ -0,0 +1,2 @@
|
||||
/* eslint-disable */
|
||||
module.exports = require('./dist/src/helpers/logger');
|
@@ -3,9 +3,10 @@
|
||||
"version": "0.1.0",
|
||||
"description": "> TODO: description",
|
||||
"scripts": {
|
||||
"dev": "nodemon --watch 'src/**/*.ts' --exec 'ts-node' src/server.ts",
|
||||
"dev": "nodemon --watch 'src/**/*.ts' --watch 'bin/**/*.ts' --exec 'ts-node' src/server.ts",
|
||||
"worker": "nodemon --watch 'src/**/*.ts' --exec 'ts-node' src/worker.ts",
|
||||
"build": "tsc && yarn copy-statics",
|
||||
"build:watch": "nodemon --watch 'src/**/*.ts' --watch 'bin/**/*.ts' --exec yarn build --ext ts",
|
||||
"start": "node dist/src/server.js",
|
||||
"test": "ava",
|
||||
"lint": "eslint . --ignore-path ../../.eslintignore",
|
||||
@@ -53,7 +54,7 @@
|
||||
"twilio": "3.70.0",
|
||||
"twitch-js": "2.0.0-beta.42",
|
||||
"twitter-api-v2": "1.6.0",
|
||||
"winston": "^3.3.3"
|
||||
"winston": "^3.7.1"
|
||||
},
|
||||
"contributors": [
|
||||
{
|
||||
@@ -64,11 +65,19 @@
|
||||
"homepage": "https://github.com/automatisch/automatisch#readme",
|
||||
"main": "dist/src/app",
|
||||
"directories": {
|
||||
"bin": "bin",
|
||||
"src": "src",
|
||||
"test": "__tests__"
|
||||
},
|
||||
"files": [
|
||||
"src"
|
||||
"bin",
|
||||
"src",
|
||||
"server.js",
|
||||
"server.d.ts",
|
||||
"logger.js",
|
||||
"logger.d.ts",
|
||||
"database.js",
|
||||
"database.d.ts"
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
1
packages/backend/server.d.ts
vendored
Normal file
1
packages/backend/server.d.ts
vendored
Normal file
@@ -0,0 +1 @@
|
||||
export * from './dist/src/server';
|
2
packages/backend/server.js
Normal file
2
packages/backend/server.js
Normal file
@@ -0,0 +1,2 @@
|
||||
/* eslint-disable */
|
||||
module.exports = require('./dist/src/server.js');
|
@@ -4,16 +4,14 @@ import type { Knex } from 'knex';
|
||||
import knexConfig from '../../knexfile';
|
||||
import logger from '../helpers/logger';
|
||||
|
||||
const knexInstance: Knex = knex(knexConfig);
|
||||
export const client: Knex = knex(knexConfig);
|
||||
|
||||
const CONNECTION_REFUSED = 'ECONNREFUSED';
|
||||
|
||||
knexInstance.raw('SELECT 1')
|
||||
client.raw('SELECT 1')
|
||||
.catch((err) => {
|
||||
if (err.code === CONNECTION_REFUSED) {
|
||||
logger.error('Make sure you have installed PostgreSQL and it is running.', err);
|
||||
process.exit();
|
||||
}
|
||||
});
|
||||
|
||||
export default knexInstance;
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { Model } from 'objection';
|
||||
import database from './database';
|
||||
import { client } from './database';
|
||||
|
||||
Model.knex(database)
|
||||
Model.knex(client);
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import winston from 'winston'
|
||||
import appConfig from '../config/app'
|
||||
import * as winston from 'winston';
|
||||
import appConfig from '../config/app';
|
||||
|
||||
const levels = {
|
||||
error: 0,
|
||||
@@ -7,11 +7,11 @@ const levels = {
|
||||
info: 2,
|
||||
http: 3,
|
||||
debug: 4,
|
||||
}
|
||||
};
|
||||
|
||||
const level = () => {
|
||||
return appConfig.appEnv === 'development' ? 'debug' : 'info'
|
||||
}
|
||||
};
|
||||
|
||||
const colors = {
|
||||
error: 'red',
|
||||
@@ -19,9 +19,9 @@ const colors = {
|
||||
info: 'green',
|
||||
http: 'magenta',
|
||||
debug: 'white',
|
||||
}
|
||||
};
|
||||
|
||||
winston.addColors(colors)
|
||||
winston.addColors(colors);
|
||||
|
||||
const format = winston.format.combine(
|
||||
winston.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss:ms' }),
|
||||
@@ -29,7 +29,7 @@ const format = winston.format.combine(
|
||||
winston.format.printf(
|
||||
(info) => `${info.timestamp} [${info.level}]: ${info.message}`,
|
||||
),
|
||||
)
|
||||
);
|
||||
|
||||
const transports = [
|
||||
new winston.transports.Console(),
|
||||
@@ -38,13 +38,13 @@ const transports = [
|
||||
level: 'error',
|
||||
}),
|
||||
new winston.transports.File({ filename: 'logs/server.log' }),
|
||||
]
|
||||
];
|
||||
|
||||
const logger = winston.createLogger({
|
||||
export const logger = winston.createLogger({
|
||||
level: level(),
|
||||
levels,
|
||||
format,
|
||||
transports,
|
||||
})
|
||||
});
|
||||
|
||||
export default logger
|
||||
export default logger;
|
||||
|
@@ -13,7 +13,7 @@ class Connection extends Base {
|
||||
formattedData?: IJSONObject;
|
||||
userId!: string;
|
||||
verified = false;
|
||||
count: number;
|
||||
count?: number;
|
||||
|
||||
static tableName = 'connections';
|
||||
|
||||
|
@@ -26,10 +26,5 @@
|
||||
"include": [
|
||||
"src/**/*",
|
||||
"bin/**/*"
|
||||
],
|
||||
"ts-node": {
|
||||
"compilerOptions": {
|
||||
"module": "commonjs"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
Reference in New Issue
Block a user