Skip to content

Commit a32296f

Browse files
committed
Trying to make clearer structure and include idea of having generic tasks within the api
1 parent d24280c commit a32296f

23 files changed

+201
-80
lines changed

.env_template

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
# Can be 'development' or 'production'
22
NODE_ENV=development
33

4+
# Server
5+
USE_HTTPS=false
6+
KEY_LOCATION=/etc/letsencrypt/live/any.example.com/privkey.pem
7+
CERT_LOCATION=/etc/letsencrypt/live/any.example.com/cert.pem
8+
49
# Your app port
510
PORT=3000
611

@@ -9,7 +14,7 @@ DB_DIALECT=postgres
914
DB_HOST=localhost
1015
DB_PORT=5432
1116
DB_USER=postgres
12-
DB_PASSWD=some_password
17+
DB_PASSWORD=some_password
1318
DB_DATABASE=example
1419

1520
# Sequelize logging

nodemon.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
22
"watch": ["src"],
33
"ext": "ts",
4-
"exec": "ts-node ./src/server/index.ts"
4+
"exec": "ts-node ./src/app.ts"
55
}

package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
{
22
"name": "node-express-orm-typescript-template",
33
"version": "1.0.0",
4-
"description": "Simple API template",
4+
"description": "Simplified ts api, app template",
55
"main": "./build/index.js",
66
"scripts": {
77
"build": "tsc --skipLibCheck",
8-
"start": "tsc --skipLibCheck && node ./build/config/server/index.js",
8+
"start": "tsc --skipLibCheck && node ./build/app.js",
99
"ts:watch": "tsc -w"
1010
},
1111
"repository": {

src/components/Authentication/index.ts renamed to src/api/components/Authentication/index.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import {NextFunction, Request, Response} from 'express';
22
import app from "../../server/server";
3-
import HttpError from "../../server/error";
3+
import HttpError from "../../server/error/index";
44
import * as jwt from 'jsonwebtoken';
5-
import {UserModelInterface} from "../../database/models/user";
6-
import * as User from '../../database/dao/user'
5+
import {UserModelInterface} from "../../../database/models/user";
6+
import * as User from '../../../database/dao/user'
77
import * as bcrypt from 'bcrypt';
88

99
/**
File renamed without changes.

src/components/index.ts renamed to src/api/components/index.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import * as AuthenticationComponent from './Authentication'
1+
import * as AuthenticationComponent from './Authentication/index'
22
import * as ExampleComponent from './Example/index';
33

44
export {

src/routes/AuthenticationRouter.ts renamed to src/api/routes/AuthenticationRouter.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {AuthenticationComponent} from '../components';
1+
import {AuthenticationComponent} from '../components/index';
22
import {Router} from 'express';
33

44
/**

src/routes/ExampleRouter.ts renamed to src/api/routes/ExampleRouter.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import {Router} from 'express'
2-
import {ExampleComponent} from '../components'
2+
import {ExampleComponent} from '../components/index'
33
import * as jwtConfig from "../server/jwtAuth";
44

55
/**

src/routes/index.ts renamed to src/api/routes/index.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ import * as swaggerJsdoc from 'swagger-jsdoc'
44
import * as swaggerUi from 'swagger-ui-express';
55
import * as jwtConfig from '../server/jwtAuth';
66

7-
import AuthenticationRouter from '../routes/AuthenticationRouter'
8-
import ExampleRouter from '../routes/ExampleRouter'
7+
import AuthenticationRouter from './AuthenticationRouter'
8+
import ExampleRouter from './ExampleRouter'
99

1010

11-
const swaggerOptions = require('../../swagger');
11+
const swaggerOptions = require('../../../swagger');
1212

1313

1414
const swaggerSpecs = swaggerJsdoc(swaggerOptions);
File renamed without changes.
File renamed without changes.

src/server/jwtAuth.ts renamed to src/api/server/jwtAuth.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import * as jwt from 'jsonwebtoken';
22
import {NextFunction, Request, Response} from 'express';
3-
import HttpError from '../server/error';
3+
import HttpError from './error/index';
44
import * as http from 'http';
55
import app from "./server";
66

File renamed without changes.

src/api/server/server.ts

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import * as express from 'express';
2+
import * as Middleware from './middleware';
3+
import * as Routes from '../routes/index';
4+
import * as dotEnv from 'dotenv'
5+
6+
dotEnv.config();
7+
8+
const app: express.Application = express();
9+
10+
Middleware.configure(app);
11+
Routes.init(app);
12+
Middleware.initErrorHandler(app);
13+
14+
export default app;

src/app.ts

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import * as dbTools from './database/dbTools'
2+
import * as http from 'http';
3+
import * as https from 'https';
4+
import * as eventHandlers from './api/server/eventHandlers';
5+
import server from './api/server/server';
6+
import * as loggingUtil from './app/loggingUtil'
7+
import * as dotEnv from 'dotenv'
8+
import {readFileSync} from 'fs';
9+
import * as app from "./app";
10+
11+
dotEnv.config();
12+
13+
dbTools.dbExists().then(() => {
14+
15+
/**
16+
* API
17+
*/
18+
if (process.env.USE_HTTPS === 'true') {
19+
const options = {
20+
key: readFileSync(process.env.KEY_LOCATION),
21+
cert: readFileSync(process.env.CERT_LOCATION),
22+
};
23+
const Server: https.Server = https.createServer(options, server);
24+
Server.listen(process.env.PORT);
25+
loggingUtil.logInfo('Server running at port ' + process.env.PORT);
26+
Server.on('error', (error: Error) => eventHandlers.onError(error, process.env.PORT));
27+
Server.on('listening', eventHandlers.onListening.bind(Server));
28+
29+
} else {
30+
const Server: http.Server = http.createServer(server);
31+
Server.listen(process.env.PORT);
32+
loggingUtil.logInfo('Server running at port ' + process.env.PORT);
33+
Server.on('error', (error: Error) => eventHandlers.onError(error, process.env.PORT));
34+
Server.on('listening', eventHandlers.onListening.bind(Server));
35+
36+
}
37+
38+
/**
39+
* Jobs
40+
*/
41+
app.app();
42+
43+
}).catch(() => {
44+
process.exit();
45+
});

src/app/index.ts

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
const schedule = require('node-schedule');
2+
import * as utils from './utils/utils'
3+
4+
export function app(): void {
5+
6+
// Register scheduled tasks
7+
schedule.scheduleJob('* * 6 * * *', () => { // Every 6 hours
8+
utils.exampleTask().then(result => {
9+
}).catch(error => {
10+
});
11+
});
12+
13+
/* More tasks here? */
14+
15+
}

src/app/loggingUtil.ts

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import * as dotEnv from 'dotenv'
2+
3+
dotEnv.config();
4+
5+
6+
function loggingEnabled(): boolean {
7+
return process.env.NODE_ENV === 'development';
8+
}
9+
10+
export function logInfo(str: string) {
11+
if (loggingEnabled()) {
12+
console.info(str);
13+
}
14+
}
15+
16+
export function logError(str: string) {
17+
if (loggingEnabled()) {
18+
console.error(str);
19+
}
20+
}

src/app/utils/utils.ts

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import * as loggingUtil from "../loggingUtil";
2+
import * as dotEnv from 'dotenv'
3+
4+
dotEnv.config();
5+
6+
export async function exampleTask(): Promise<boolean> {
7+
try {
8+
return await examplePromiseFunction;
9+
} catch (error) {
10+
loggingUtil.logError(error);
11+
return false;
12+
}
13+
}
14+
15+
const examplePromiseFunction = new Promise<boolean>((resolve, reject) => {
16+
resolve(true);
17+
});

src/database/dbTools.ts

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import * as dotEnv from 'dotenv'
2+
import * as loggingUtil from '../app/loggingUtil'
3+
4+
const pgTools = require('pgtools');
5+
6+
dotEnv.config();
7+
8+
9+
export async function dbExists(): Promise<boolean> {
10+
try {
11+
return await createDatabase;
12+
} catch (error) {
13+
loggingUtil.logError(error);
14+
return false;
15+
}
16+
}
17+
18+
19+
const createDatabase = new Promise<boolean>((resolve, reject) => {
20+
loggingUtil.logInfo('Pg tools checking database existence...');
21+
pgTools.createdb({
22+
user: process.env.DB_USER,
23+
password: process.env.DB_PASSWORD,
24+
port: process.env.DB_PORT,
25+
host: process.env.DB_HOST
26+
// @ts-ignore
27+
}, process.env.DB_DATABASE, function (error, response) {
28+
if (!error) {
29+
loggingUtil.logInfo('db ' + process.env.DB_DATABASE + ' did not exists. Created it.');
30+
resolve(true);
31+
} else {
32+
loggingUtil.logError(error);
33+
reject(false);
34+
}
35+
});
36+
37+
});

src/database/index.ts

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import {Dialect, Sequelize} from 'sequelize'
2+
import * as dotEnv from 'dotenv'
3+
import * as loggingUtil from "../app/loggingUtil";
4+
5+
dotEnv.config();
6+
7+
const sequelize = new Sequelize(
8+
process.env.DB_DATABASE,
9+
process.env.DB_USER,
10+
process.env.DB_PASSWORD,
11+
{
12+
port: Number(process.env.DB_PORT),
13+
host: process.env.DB_HOST,
14+
dialect: process.env.DB_DIALECT as Dialect,
15+
pool: {
16+
max: 10,
17+
min: 0,
18+
idle: 10000
19+
},
20+
logging: function (str) {
21+
if ((process.env.SEQ_LOGGING === 'true')) {
22+
console.info(str);
23+
}
24+
},
25+
}
26+
);
27+
28+
sequelize.sync().then(function () {
29+
loggingUtil.logInfo('DB connection success.');
30+
}, function (err) {
31+
loggingUtil.logError(JSON.stringify(err));
32+
});
33+
34+
export default sequelize

src/server/index.ts

-20
This file was deleted.

src/server/server.ts

-46
This file was deleted.

0 commit comments

Comments
 (0)