Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#node_modules
M1/node_modules
M2/node_modules

#package-lock.json
package-lock.json

#Package dist
dist

#.env
.env
11 changes: 11 additions & 0 deletions M1/.editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
root = true

[*]
indent_style = space
indent_size = 2
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
end_of_line = lf
# editorconfig-tools is unable to ignore longs strings or urls
max_line_length = null
6 changes: 6 additions & 0 deletions M1/.huskyrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"hooks": {
"pre-commit": "npm run lint && npm run test:c",
"pre-push": "npm run lint && npm run test:c"
}
}
File renamed without changes.
48 changes: 48 additions & 0 deletions M1/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
{
"name": "training-task",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "tsc-watch --project . --onSuccess \"npm run nodemon\"",
"nodemon": "nodemon ./dist/index.js",
"lint": "./node_modules/tslint/bin/tslint -c tslint.json -p tsconfig.json --exclude 'node_modules/**/*.{j,t}s'",
"lint:fix": "npm run lint --fix",
"commit": "npx git-cz"
},
"repository": {
"type": "git",
"url": "git+https://github.com/AryanSinghalGit/training-task.git"
},
"author": "",
"license": "ISC",
"bugs": {
"url": "https://github.com/AryanSinghalGit/training-task/issues"
},
"homepage": "https://github.com/AryanSinghalGit/training-task#readme",
"dependencies": {
"@types/express": "4.17.2",
"@types/mongoose": "5.7.0",
"@types/node": "13.5.1",
"babel-node": "0.0.1-security",
"body-parser": "1.19.0",
"commitizen": "4.0.3",
"cz-conventional-changelog": "3.1.0",
"dotenv": "8.2.0",
"express": "4.17.1",
"git-cz": "4.2.0",
"husky": "4.2.1",
"mongoose": "5.8.11",
"nodemon": "2.0.2",
"object-sizeof": "^1.5.2",
"tslint": "6.0.0"
},
"devDependencies": {
"@babel/core": "7.8.3",
"@babel/node": "7.8.3",
"@babel/preset-env": "7.8.3",
"tsc-watch": "4.1.0",
"typescript": "3.7.5"
}
}
49 changes: 49 additions & 0 deletions M1/src/Server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import * as express from 'express';
import * as bodyParser from 'body-parser';
import { notFoundRoute, errorHandler } from './libs/routes';
import Database from './libs/Database';
import mainRouter from './router';

export class Server {
private app: express.Express;
constructor(protected config) {
this.app = express();
}

public bootstrap = (): Server => {
this.initBodyParser();
this.setupRoutes();
return this;
}

public run = async (): Promise<Server> => {
try {
const { app, config: { port, mongoUrl } }: Server = this;
await Database.open(mongoUrl);
app.listen(port, (err) => {
if (err) {
console.log(err);
}
console.log(`Express app Successfully started on port : ${port} `);
});
}
catch (err) {
throw err;
}
return this;
}

public initBodyParser = () => {
const { app } = this;
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
}

public setupRoutes = (): void => {
const { app }: Server = this;
app.get('/health-check', (req: express.Request, res: express.Response) => res.send('I am OK'));
app.use('/api', mainRouter);
app.use(notFoundRoute);
app.use(errorHandler);
}
}
5 changes: 5 additions & 0 deletions M1/src/config/IConfig.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export interface IConfig {
port: string;
nodeEnv: string;
mongoUrl: string;
}
14 changes: 14 additions & 0 deletions M1/src/config/configuration.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { IConfig } from './IConfig';
import { config } from 'dotenv';

config();

const configuration: IConfig = {
port : process.env.PORT,
nodeEnv : process.env.NODE_ENV,
mongoUrl: process.env.MONGO_URL,
};

Object.freeze(configuration);

export default configuration;
1 change: 1 addition & 0 deletions M1/src/controllers/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { unsortedObjectsRouter } from './unsortedObjects';
55 changes: 55 additions & 0 deletions M1/src/controllers/unsortedObjects/controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { Request, Response } from 'express';
const sizeof = require('object-sizeof');
import { UnsortedObjectsRepository } from '../../repositories/​unsortedObjects';
import SystemResponse from '../../libs/SystemResponse';
import getObject from './helper';

class UnsortedObjectsController {
static instance: UnsortedObjectsController;

static getInstance = () => {
if (UnsortedObjectsController.instance) {
return UnsortedObjectsController.instance;
}
else {
UnsortedObjectsController.instance = new UnsortedObjectsController();
return UnsortedObjectsController.instance;
}
}

create = async (req, res: Response) => {
console.log('----------Create Object----------');
try {
const { rootKeyCount, maxDepth } = req.body;
const start = new Date().getTime();
const object = getObject(rootKeyCount, maxDepth);
const end = new Date().getTime();
const generationTime = end - start;
const size = sizeof(object);
const keyCount = rootKeyCount;
const depth = maxDepth;
const objectDetails = await UnsortedObjectsRepository.create({ object, keyCount, depth, size, generationTime });
if (!objectDetails)
throw { message: 'Data is not inserted' };
SystemResponse.success(res, objectDetails);
}
catch (err) {
SystemResponse.failure(res, err, err.message);
}

};

list = async (req: Request, res: Response) => {
console.log('---------Object List----------');
try {
const objectList = await UnsortedObjectsRepository.list();
SystemResponse.success(res, objectList);
}
catch (err) {
SystemResponse.failure(res, err, err.message);
}
};

}

export default UnsortedObjectsController.getInstance();
60 changes: 60 additions & 0 deletions M1/src/controllers/unsortedObjects/helper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
function getRandomInt(max) {
return Math.floor(Math.random() * max);
}

function getRandomNumber(length) {
let result = '';
const characters = '0123456789';
const charactersLength = characters.length;
for (let i = 0; i < length; i++) {
result += characters.charAt(Math.floor(Math.random() * charactersLength));
}
return result;
}

function getRandomString(length) {
let result = '';
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
const charactersLength = characters.length;
for (let i = 0; i < length; i++) {
result += characters.charAt(Math.floor(Math.random() * charactersLength));
}
return result;
}

function getRandomBoolean() {
const bool = [true, false];
return bool[getRandomInt(2)];
}

const getObject = (rootKeyCount, maxDepth) => {
let rootKey = 0;
let object = {};
while (rootKey < rootKeyCount) {
const max = (maxDepth > 0) ? 5 : 4;
const key = getRandomString(20);
switch (getRandomInt(max)) {
case 0:
object = { ...object, [key]: getRandomNumber(getRandomInt(20)) };
break;
case 1:
object = { ...object, [key]: getRandomString(20) };
break;
case 2:
object = { ...object, [key]: getRandomBoolean() };
break;
case 3:
object = { ...object, [key]: [] };
break;
case 4:
object = { ...object, [key]: getObject(Math.floor(rootKeyCount / 2), maxDepth - 1) };
break;
default:
break;
}
rootKey++;
}
return object;
};

export default getObject;
2 changes: 2 additions & 0 deletions M1/src/controllers/unsortedObjects/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { default as unsortedObjectsController } from './controller';
export { default as unsortedObjectsRouter } from './routes';
11 changes: 11 additions & 0 deletions M1/src/controllers/unsortedObjects/routes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { Router } from 'express';
import controller from './controller';
import { validationHandler } from '../../libs';
import { default as validation } from './validation';

const unsortedObjectsRouter: Router = Router();
unsortedObjectsRouter.route('/')
.get(validationHandler(validation.get), controller.list)
.post(validationHandler(validation.create), controller.create);

export default unsortedObjectsRouter;
23 changes: 23 additions & 0 deletions M1/src/controllers/unsortedObjects/validation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
const validation = {
create:
{
rootKeyCount:
{
required: true,
regex: /[0-9]+$/,
in: ['body'],
errorMessage: 'rootKeyCount is required',
},
maxDepth:
{
required: true,
regex: /[0-9]+$/,
in: ['body'],
errorMessage: 'maxDepth is required'
},
},
get: {
},
};

export default validation;
5 changes: 5 additions & 0 deletions M1/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { Server } from './Server';
import config from './config/configuration';

const server: Server = new Server(config);
server.bootstrap().run();
20 changes: 20 additions & 0 deletions M1/src/libs/Database.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import * as mongoose from 'mongoose';

export default class Database {
static open = (mongoUrl) => {
const promise = new Promise((resolve, reject) => {
mongoose.connect(mongoUrl, { useNewUrlParser: true, useUnifiedTopology: true }, (err) => {
if (err) {
reject(err);
}
console.log('Database Connected at :', mongoUrl);
resolve();
});
});
return promise;
}
static disconnect = () => {
mongoose.connection.close();
console.log('Database disconnected');
};
}
17 changes: 17 additions & 0 deletions M1/src/libs/SystemResponse.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
class SystemResponse {
static success = (res, data, message = 'Success') => {
return res.status(200).send({
status: 'ok',
message,
data
});
}
static failure = (res, err, message = 'Failure', status = 400) => {
return res.status(status).send({
status: err.status || 'Bad Request',
message,
err
});
}
}
export default SystemResponse;
Empty file added M1/src/libs/constant.ts
Empty file.
1 change: 1 addition & 0 deletions M1/src/libs/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { validationHandler } from './routes';
14 changes: 14 additions & 0 deletions M1/src/libs/routes/errorHandler.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import * as express from 'express';

const errorHandler = (err, req: express.Request, res: express.Response, next: express.NextFunction): void => {
const resp = {
message: err.message || err ,
status: err.status || 500,
error: err.error || 'Error Occurred ',
timestamp: new Date()
};
res.status(err.status).send(resp);
res.end('ok');
};

export default errorHandler;
3 changes: 3 additions & 0 deletions M1/src/libs/routes/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export { default as errorHandler } from './errorHandler';
export { default as notFoundRoute } from './notFoundRoute';
export { default as validationHandler } from './validationHandler';
8 changes: 8 additions & 0 deletions M1/src/libs/routes/notFoundRoute.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import * as express from 'express';

const notFoundRoute = (req: express.Request, res: express.Response, next): express.ErrorRequestHandler => {
const err = {error: 'Not Found' , message: 'error', status: 404 };
return next(err);
};

export default notFoundRoute;
Loading