Skip to content

Commit

Permalink
Merge pull request #29 from schubergphilis/strict-type-checks
Browse files Browse the repository at this point in the history
Enables strict mode on microchassis
  • Loading branch information
rthewhite committed Dec 1, 2017
2 parents 86d6c8c + ff4490b commit 402351a
Show file tree
Hide file tree
Showing 27 changed files with 204 additions and 172 deletions.
11 changes: 9 additions & 2 deletions package.json
Expand Up @@ -36,21 +36,28 @@
"**/*.test.js",
"**/__tests__/**",
"**/node_modules/**",
"src/vendor.d.ts",
"example",
"dist",
"coverage"
],
"all": true
},
"devDependencies": {
"@types/chai": "^4.0.4",
"@types/async": "^2.0.45",
"@types/body-parser": "^1.16.8",
"@types/chai": "^4.0.6",
"@types/connect-timeout": "0.0.33",
"@types/deepmerge": "^1.3.2",
"@types/express": "^4.0.37",
"@types/http-status": "^0.2.30",
"@types/mocha": "^2.2.43",
"@types/node": "^8.0.47",
"@types/protobufjs": "^5.0.31",
"@types/reflect-metadata": "0.0.5",
"@types/sinon": "^2.3.5",
"@types/sinon-chai": "^2.7.29",
"@types/uuid": "^3.4.3",
"chai": "^4.1.2",
"coveralls": "^2.13.3",
"mocha": "^3.5.3",
Expand All @@ -66,7 +73,7 @@
"typescript": "^2.5.3"
},
"dependencies": {
"@types/deepmerge": "^1.3.2",
"@types/minimist": "^1.2.0",
"async": "^2.5.0",
"body-parser": "^1.18.2",
"connect-timeout": "^1.9.0",
Expand Down
8 changes: 4 additions & 4 deletions src/config.ts
Expand Up @@ -99,7 +99,7 @@ export class Config {
for (let i = 0, len = this.knownOptions.length; i < len; i++) {
const option = this.knownOptions[i];

this[option.dest] = option.value;
(<any>this)[option.dest] = option.value;

// Check for commandline arguments
if (option.args) {
Expand All @@ -109,20 +109,20 @@ export class Config {
const value = args[option.args[j]];
if (value) {
argValue = value;
this[option.dest] = value;
(<any>this)[option.dest] = value;
break;
}
}

if (argValue) {
this[option.dest] = argValue;
(<any>this)[option.dest] = argValue;
break;
}
}

// Check for environment variables
if (option.env && process.env[option.env]) {
this[option.dest] = process.env[option.env];
(<any>this)[option.dest] = process.env[option.env];
}
};
}
Expand Down
8 changes: 4 additions & 4 deletions src/grpc-server.ts
Expand Up @@ -55,7 +55,7 @@ interface GrpcImplementation {

@injectable()
export class GrpcServer {
private server;
private server: any;
private services: GrpcImplementation = {};
private proto: PackagedProtobufDefinition | ProtobufDefinition;
private health = new BehaviorSubject(false);
Expand All @@ -66,7 +66,7 @@ export class GrpcServer {
private logger: Logger,
private healthManager: HealthManager
) {
healthManager.registerCheck('GRPC server', this.health);
this.healthManager.registerCheck('GRPC server', this.health);
this.proto = grpc.load(this.protoConfig.path);
}

Expand Down Expand Up @@ -111,9 +111,9 @@ export class GrpcServer {

this.server = new grpc.Server();
this.server.addService(this.service, this.services);
this.server.bind(`0.0.0.0:${this.config['grpcPort']}`, grpc.ServerCredentials.createInsecure());
this.server.bind(`0.0.0.0:${(<any>this.config)['grpcPort']}`, grpc.ServerCredentials.createInsecure());
this.server.start();
this.logger.info(`Grpc server started listening on: ${this.config['grpcPort']}`);
this.logger.info(`Grpc server started listening on: ${(<any>this.config)['grpcPort']}`);

// Notify the server is healhty
this.health.next(true);
Expand Down
29 changes: 14 additions & 15 deletions src/health.ts
Expand Up @@ -2,7 +2,7 @@ import { injectable } from 'inversify';
import { Logger } from './logger';
import 'rxjs/add/operator/distinctUntilChanged';
import 'rxjs/add/operator/skip';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import { BehaviorSubject } from 'rxjs';


interface HealthChecks {
Expand All @@ -13,11 +13,10 @@ interface HealthChecks {
export class HealthManager {
private checks: HealthChecks = {};
private _health = false;
private _previousHealth = false;

constructor(private logger: Logger) {}
constructor(private logger: Logger) { }

public registerCheck(name: string, check) {
public registerCheck(name: string, check: BehaviorSubject<boolean>) {
if (this.checks[name]) {
throw new Error(`Health check with name: ${name} already exists`);
}
Expand All @@ -32,13 +31,13 @@ export class HealthManager {
check
.skip(1)
.distinctUntilChanged()
.subscribe((status) => {
if (status === false) {
this.logger.warn(`Health check: ${name} became unhealthy`);
this.healthy = false;
} else {
.subscribe((status: boolean) => {
if (status === true) {
this.logger.info(`Health check: ${name} became healthy`);
this.determineHealth();
} else {
this.logger.warn(`Health check: ${name} became unhealthy`);
this.healthy = false;
}
});
}
Expand All @@ -64,7 +63,7 @@ export class HealthManager {
}

public getReport() {
const report = {};
const report: any = {};

for (const check in this.checks) {
if (this.checks.hasOwnProperty(check)) {
Expand All @@ -80,11 +79,11 @@ export class HealthManager {
const keys = Object.keys(this.checks);

for (let i = 0, len = keys.length; i < len; i++) {
const checkStatus = this.checks[keys[i]].getValue();
if (checkStatus === false) {
status = false;
break;
}
const checkStatus = this.checks[keys[i]].getValue();
if (checkStatus === false) {
status = false;
break;
}
}

this.healthy = status;
Expand Down
50 changes: 30 additions & 20 deletions src/http-server.ts
@@ -1,5 +1,6 @@
import { injectable, inject } from 'inversify';
import { Request, Response, NextFunction } from 'express';

import { Request, Response, NextFunction, Express } from 'express';
import * as bodyParser from 'body-parser';
import * as httpStatus from 'http-status';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
Expand Down Expand Up @@ -30,13 +31,18 @@ export interface HttpService {
export class HttpServer {
public health = new BehaviorSubject(false);
protected registeredUrls: RegisteredServices = {};
protected server;

constructor( @inject('express') private express, private config: Config, private logger: Logger, healthManager: HealthManager) {
protected server: Express;

constructor(
@inject('express') private express: () => Express | Object,
private config: Config,
private logger: Logger,
healthManager: HealthManager
) {
healthManager.registerCheck('HTTP server', this.health);

// Setup express and a json body parser
this.server = express();
this.server = <Express>(this.express());
this.server.use(bodyParser.json({
type: (request) => {
let contentType = '';
Expand All @@ -54,7 +60,7 @@ export class HttpServer {
}));

// Register health check endpoint
const healthUrl = this.normalizeURL(this.config['healthCheckURL'] || '/check');
const healthUrl = this.normalizeURL((<any>this.config)['healthCheckURL'] || '/check');

this.server.get(healthUrl, (_: Request, response: Response) => {
const report = healthManager.getReport();
Expand All @@ -81,16 +87,16 @@ export class HttpServer {
this.logger.info(`Registering HTTP handler: ${service.method || method} ${url}`);
this.registeredUrls[url] = service.method;

this.server[method](url, (request: Request, response: Response) => {
(this.server as any)[method](url, (request: Request, response: Response) => {
this.handleRequest(service, request, response);
});
}

// Starts the http server
public start() {
// Set a 30 seconds request timeout
const connectTimeout: number = this.config['connectTimeout'] || 30000;
this.server.use(timeout(connectTimeout));
const connectTimeout: number = (<any>this.config)['connectTimeout'] || 30000;
this.server.use(timeout(`${connectTimeout}ms`));

// 404 middleware
this.server.use((request: Request, response: Response, _: NextFunction) => {
Expand All @@ -102,7 +108,7 @@ export class HttpServer {
});

// Error middleware
this.server.use((error, request: Request, response: Response, _: NextFunction) => {
this.server.use((error: any, request: Request, response: Response, _: NextFunction) => {
this.logger.error(`Express error middleware error for ${request.url}`, error);
console.error(error);

Expand All @@ -111,8 +117,8 @@ export class HttpServer {
});
});

this.server.listen(this.config['httpPort'], () => {
this.logger.info(`Http server starting listening on: ${this.config['httpPort']}`);
this.server.listen((<any>this.config)['httpPort'], () => {
this.logger.info(`Http server starting listening on: ${(<any>this.config)['httpPort']} `);
this.health.next(true);
});
}
Expand All @@ -126,7 +132,7 @@ export class HttpServer {


if (!service.unauthenticated && !context.token) {
this.logger.audit(`Unauthenticated request on: ${service.url}`);
this.logger.audit(`Unauthenticated request on: ${service.url} `);
response.status(httpStatus.FORBIDDEN).send('Unauthenticated');
return;
}
Expand All @@ -149,7 +155,7 @@ export class HttpServer {
response.status(status).send(content);

const duration = new Date().getTime() - startTime.getTime();
this.logger.info(`Http request '${request.url}' ended: ${status}, duration: ${duration}ms`, { context });
this.logger.info(`Http request '${request.url}' ended: ${status}, duration: ${duration} ms`, { context });
})
.catch((error: ServiceResponse = {}) => {
this.logger.error(error.content);
Expand All @@ -160,7 +166,7 @@ export class HttpServer {
response.status(status).send(content);

const duration = new Date().getTime() - startTime.getTime();
this.logger.info(`Http request '${request.url}' ended: ${status}, duration: ${duration}ms`, { context });
this.logger.info(`Http request '${request.url}' ended: ${status}, duration: ${duration} ms`, { context });
});
}

Expand All @@ -171,8 +177,8 @@ export class HttpServer {
}

// Check for root in config and prepend to the url
if (this.config['httpRoot']) {
let httpRoot = this.config['httpRoot'];
if ((<any>this.config)['httpRoot']) {
let httpRoot = (<any>this.config)['httpRoot'];

// Should start with an slash
if (httpRoot.charAt(0) !== '/') {
Expand Down Expand Up @@ -243,10 +249,14 @@ export class HttpServer {
user = request.headers['remoteuser'].toString();
}

// if (token === undefined || user === undefined) {
// throw new Error('Could not create context, lacking token or user');
// }

return {
token,
requestId,
user
token: <string>token,
requestId: requestId,
user: <string>user
}
}
}
8 changes: 4 additions & 4 deletions src/logger/logger.ts
Expand Up @@ -23,7 +23,7 @@ export interface LogRecord {
message: string;
time: Date;
formatArgs: Array<string>,
extra: Object;
extra: any;
}

export type LogProcessor = (message: LogRecord) => LogRecord;
Expand Down Expand Up @@ -61,19 +61,19 @@ export class Logger {
private handlers: Array<LogHandler> = [];

constructor(private config: Config) {
switch (config['logLevel'] || LogLevel.DEBUG) {
switch ((<any>this.config)['logLevel'] || LogLevel.DEBUG) {
case 'debug': this.logLevel = LogLevel.DEBUG; break;
case 'info': this.logLevel = LogLevel.INFO; break;
case 'warn': this.logLevel = LogLevel.WARN; break;
case 'error': this.logLevel = LogLevel.ERROR; break;
case 'fatal': this.logLevel = LogLevel.FATAL; break;
}

if (config['debug'] === true || config['debug'] === 'true') {
if ((<any>config)['debug'] === true || (<any>config)['debug'] === 'true') {
this._debug = true;
}

const loggerOptions: LoggerOptions = this.config['loggerOptions']
const loggerOptions: LoggerOptions = (<any>this.config)['loggerOptions']
const processors = loggerOptions && loggerOptions.processors ? loggerOptions.processors : this.defaultProcessors;
const handlers = loggerOptions && loggerOptions.handlers ? loggerOptions.handlers : this.defaultHandlers;

Expand Down
4 changes: 2 additions & 2 deletions src/logger/processors/assign-instance.ts
Expand Up @@ -5,8 +5,8 @@ import { LogRecord } from './../logger';
let instanceId = uuid();

const func = function(config: Config) {
if (config['instanceId']) {
instanceId = config['instanceId'];
if ((<any>config)['instanceId']) {
instanceId = (<any>config)['instanceId'];
}

return (record: LogRecord): LogRecord => {
Expand Down
2 changes: 1 addition & 1 deletion src/logger/processors/assign-session-hash.ts
Expand Up @@ -3,7 +3,7 @@ import { Config } from './../../config';
import { LogRecord } from './../logger';

export function assignSessionHash(config: Config) {
const secret = config['sessionHashKey'];
const secret = (<any>config)['sessionHashKey'];

return (record: LogRecord): LogRecord => {
if (secret && record.extra['context'] !== undefined) {
Expand Down
2 changes: 1 addition & 1 deletion src/logger/processors/assign-version.ts
Expand Up @@ -2,7 +2,7 @@ import { Config } from './../../config';
import { LogRecord } from './../logger';

export function assignVersion(config: Config) {
const version = config['applicationVersion'];
const version = (<any>config)['applicationVersion'];

return (record: LogRecord): LogRecord => {
if (version !== undefined) {
Expand Down
5 changes: 2 additions & 3 deletions src/logger/processors/remove-sensitive-info.ts
Expand Up @@ -4,8 +4,8 @@ import { LogRecord } from './../logger';
export function removeSensitiveInfo(config: Config) {
let sensitiveKeys = ['token', 'user', 'password', 'context'];

if (config['sensitiveKeys']) {
sensitiveKeys = sensitiveKeys.concat(config['sensitiveKeys']);
if ((<any>config)['sensitiveKeys']) {
sensitiveKeys = sensitiveKeys.concat((<any>config)['sensitiveKeys']);
}

return (record: LogRecord): LogRecord => {
Expand All @@ -17,4 +17,3 @@ export function removeSensitiveInfo(config: Config) {
return record;
}
}

10 changes: 5 additions & 5 deletions src/providers/db/mariadbProvider.ts
Expand Up @@ -26,11 +26,11 @@ export class MariadbProvider extends DbProvider implements EntityProvider {
super();

const providedOptions: Partial<MysqlConnectionOptions> = {
username: this.config['dbUser'],
password: this.config['dbPassword'] || '',
database: this.config['dbName'],
host: this.config['dbHost'],
port: this.config['dbPort'],
username: (this.config as any)['dbUser'],
password: (this.config as any)['dbPassword'] || '',
database: (this.config as any)['dbName'],
host: (this.config as any)['dbHost'],
port: (this.config as any)['dbPort'],
entities: this.entities
};
const options: ConnectionOptions = deepmerge(this.connectionOptions, providedOptions);
Expand Down

0 comments on commit 402351a

Please sign in to comment.