feat: make services gettable and injectable by simple strings and not needing to call Symbol.for every time
This commit is contained in:
parent
6c0456fa0d
commit
fc391a02e5
10
src/main.ts
10
src/main.ts
|
@ -13,22 +13,22 @@ import { ISession } from './main/modules/session/i-session';
|
||||||
* https://nodejs.org/api/process.html#process_event_unhandledrejection
|
* https://nodejs.org/api/process.html#process_event_unhandledrejection
|
||||||
*/
|
*/
|
||||||
process.on('unhandledRejection', (reason) => {
|
process.on('unhandledRejection', (reason) => {
|
||||||
const logger: ILogger = container.get(Symbol.for('logger'));
|
const logger: ILogger = container.get('logger');
|
||||||
void logger.fatal(`Unhandled Rejection, see ${logger.getExceptionsLogFile()}`);
|
void logger.fatal(`Unhandled Rejection, see ${logger.getExceptionsLogFile()}`);
|
||||||
throw reason;
|
throw reason;
|
||||||
});
|
});
|
||||||
|
|
||||||
process.on('uncaughtException', (error) => {
|
process.on('uncaughtException', (error) => {
|
||||||
const logger: ILogger = container.get(Symbol.for('logger'));
|
const logger: ILogger = container.get('logger');
|
||||||
void logger.exception(error);
|
void logger.exception(error);
|
||||||
throw error;
|
throw error;
|
||||||
});
|
});
|
||||||
|
|
||||||
async function createWindow(): Promise<void> {
|
async function createWindow(): Promise<void> {
|
||||||
const session: ISession = container.get(Symbol.for('session'));
|
const session: ISession = container.get('session');
|
||||||
session.setHeaders();
|
session.setHeaders();
|
||||||
|
|
||||||
const appWindowMain: IAppWindow = container.get(Symbol.for('app-window-main'));
|
const appWindowMain: IAppWindow = container.get('app-window-main');
|
||||||
|
|
||||||
// and load the index.html of the app.
|
// and load the index.html of the app.
|
||||||
await appWindowMain.open();
|
await appWindowMain.open();
|
||||||
|
@ -57,7 +57,7 @@ app.on('window-all-closed', () => {
|
||||||
app.on('activate', async () => {
|
app.on('activate', async () => {
|
||||||
// On OS X it"s common to re-create a window in the app when the
|
// On OS X it"s common to re-create a window in the app when the
|
||||||
// dock icon is clicked and there are no other windows open.
|
// dock icon is clicked and there are no other windows open.
|
||||||
const appWindowMain: IAppWindow = container.get(Symbol.for('app-window-main'));
|
const appWindowMain: IAppWindow = container.get('app-window-main');
|
||||||
if (appWindowMain.isClosed()) {
|
if (appWindowMain.isClosed()) {
|
||||||
await createWindow();
|
await createWindow();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import 'reflect-metadata';
|
import 'reflect-metadata';
|
||||||
import { Container } from 'inversify';
|
import { Container, interfaces } from 'inversify';
|
||||||
import { MainAppWindow } from '../modules/app-window/main-app-window';
|
import { MainAppWindow } from '../modules/app-window/main-app-window';
|
||||||
import { Logger } from '../modules/logger/logger';
|
import { Logger } from '../modules/logger/logger';
|
||||||
import { NhentaiApi } from '../modules/nhentai/nhentai-api';
|
import { NhentaiApi } from '../modules/nhentai/nhentai-api';
|
||||||
|
@ -7,17 +7,29 @@ import '../modules/nhentai/nhentai-ipc-controller';
|
||||||
import { Session } from '../modules/session/session';
|
import { Session } from '../modules/session/session';
|
||||||
import { Store } from '../modules/store/store';
|
import { Store } from '../modules/store/store';
|
||||||
import { WebCrawler } from '../modules/web-crawler/web-crawler';
|
import { WebCrawler } from '../modules/web-crawler/web-crawler';
|
||||||
|
import BindingToSyntax = interfaces.BindingToSyntax;
|
||||||
|
|
||||||
export const container = new Container({ defaultScope: 'Singleton' });
|
export const container = {
|
||||||
|
original: new Container({ defaultScope: 'Singleton' }),
|
||||||
|
bind<T>(key: string): BindingToSyntax<T> {
|
||||||
|
return this.original.bind<T>(Symbol.for(key));
|
||||||
|
},
|
||||||
|
unbind(key: string): void {
|
||||||
|
return this.original.unbind(Symbol.for(key));
|
||||||
|
},
|
||||||
|
get<T>(key: string): T {
|
||||||
|
return this.original.get<T>(Symbol.for(key));
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
container.bind(Symbol.for('store')).to(Store);
|
container.bind('store').to(Store);
|
||||||
|
|
||||||
container.bind(Symbol.for('web-crawler')).to(WebCrawler);
|
container.bind('web-crawler').to(WebCrawler);
|
||||||
|
|
||||||
container.bind(Symbol.for('nhentai-api')).to(NhentaiApi);
|
container.bind('nhentai-api').to(NhentaiApi);
|
||||||
|
|
||||||
container.bind(Symbol.for('app-window-main')).to(MainAppWindow);
|
container.bind('app-window-main').to(MainAppWindow);
|
||||||
|
|
||||||
container.bind(Symbol.for('session')).to(Session);
|
container.bind('session').to(Session);
|
||||||
|
|
||||||
container.bind(Symbol.for('logger')).to(Logger);
|
container.bind('logger').to(Logger);
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
import { inject as inversifyInject } from 'inversify';
|
||||||
|
|
||||||
|
export function inject(key: string): ReturnType<typeof inversifyInject> {
|
||||||
|
return inversifyInject(Symbol.for(key));
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
import { registerHandler } from '../ipc-server';
|
import { registerHandler } from '../ipc-server';
|
||||||
|
|
||||||
export function answer(channel: IpcChannel): DecoratorFactory<IIpcController, IpcHandler> {
|
export function answer(channel: IpcChannel): DecoratorFactory<IIpcController> {
|
||||||
return function (target: IIpcController, propertyKey): void {
|
return function (target: IIpcController, propertyKey): void {
|
||||||
registerHandler(channel, target, propertyKey);
|
registerHandler(channel, target, propertyKey);
|
||||||
};
|
};
|
||||||
|
|
|
@ -53,20 +53,20 @@ describe('Logger Service', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('creates log files', () => {
|
it('creates log files', () => {
|
||||||
const logger: ILogger = container.get(Symbol.for('logger'));
|
const logger: ILogger = container.get('logger');
|
||||||
|
|
||||||
expect(logger.getLogFile()).path('log file is not created');
|
expect(logger.getLogFile()).path('log file is not created');
|
||||||
expect(logger.getExceptionsLogFile()).path('exception log file is not created');
|
expect(logger.getExceptionsLogFile()).path('exception log file is not created');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('logs exceptions', async () => {
|
it('logs exceptions', async () => {
|
||||||
const logger: ILogger = container.get(Symbol.for('logger'));
|
const logger: ILogger = container.get('logger');
|
||||||
|
|
||||||
await logger.exception(new Error('this is an error'));
|
await logger.exception(new Error('this is an error'));
|
||||||
});
|
});
|
||||||
|
|
||||||
it("default log file doesn't get bigger than 50KB @slow", async () => {
|
it("default log file doesn't get bigger than 50KB @slow", async () => {
|
||||||
const logger: ILogger = container.get(Symbol.for('logger'));
|
const logger: ILogger = container.get('logger');
|
||||||
|
|
||||||
for (let i = 0; i < maxLogSize; i++) {
|
for (let i = 0; i < maxLogSize; i++) {
|
||||||
await logger.log(4, 'your waifu is trash');
|
await logger.log(4, 'your waifu is trash');
|
||||||
|
@ -77,7 +77,7 @@ describe('Logger Service', () => {
|
||||||
}).timeout(15000);
|
}).timeout(15000);
|
||||||
|
|
||||||
it("exception log file doesn't get bigger than 50KB @slow", async () => {
|
it("exception log file doesn't get bigger than 50KB @slow", async () => {
|
||||||
const logger: ILogger = container.get(Symbol.for('logger'));
|
const logger: ILogger = container.get('logger');
|
||||||
|
|
||||||
for (let i = 0; i < maxLogSize; ++i) {
|
for (let i = 0; i < maxLogSize; ++i) {
|
||||||
await logger.exception(new Error('your waifu is trash'));
|
await logger.exception(new Error('your waifu is trash'));
|
||||||
|
@ -88,7 +88,7 @@ describe('Logger Service', () => {
|
||||||
}).timeout(15000);
|
}).timeout(15000);
|
||||||
|
|
||||||
it('logs different levels directly', () => {
|
it('logs different levels directly', () => {
|
||||||
const logger: ILogger = container.get(Symbol.for('logger'));
|
const logger: ILogger = container.get('logger');
|
||||||
|
|
||||||
return fc.assert(
|
return fc.assert(
|
||||||
fc.asyncProperty(logLevelArbitrary as LogLevelArbitrary, fc.string(), async (logLevel, message) => {
|
fc.asyncProperty(logLevelArbitrary as LogLevelArbitrary, fc.string(), async (logLevel, message) => {
|
||||||
|
@ -104,7 +104,7 @@ describe('Logger Service', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('logs different levels indirectly via the generic log function', () => {
|
it('logs different levels indirectly via the generic log function', () => {
|
||||||
const logger: ILogger = container.get(Symbol.for('logger'));
|
const logger: ILogger = container.get('logger');
|
||||||
|
|
||||||
return fc.assert(
|
return fc.assert(
|
||||||
fc.asyncProperty(logLevelNumberArbitrary, fc.string(), async (logLevelNumber, message) => {
|
fc.asyncProperty(logLevelNumberArbitrary, fc.string(), async (logLevelNumber, message) => {
|
||||||
|
@ -123,7 +123,7 @@ describe('Logger Service', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('logs debug only in dev mode', async () => {
|
it('logs debug only in dev mode', async () => {
|
||||||
const logger: ILogger = container.get(Symbol.for('logger'));
|
const logger: ILogger = container.get('logger');
|
||||||
|
|
||||||
setDev();
|
setDev();
|
||||||
await logger.debug('this is a development message');
|
await logger.debug('this is a development message');
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { inject, injectable } from 'inversify';
|
import { injectable } from 'inversify';
|
||||||
import { JSDOM } from 'jsdom';
|
import { JSDOM } from 'jsdom';
|
||||||
import { RequestInit, Response } from 'node-fetch';
|
import { RequestInit, Response } from 'node-fetch';
|
||||||
|
import { inject } from '../../core/inject';
|
||||||
import { WebCrawlerFormError } from '../error/web-crawler-form-error';
|
import { WebCrawlerFormError } from '../error/web-crawler-form-error';
|
||||||
import { WebCrawlerLoginError } from '../error/web-crawler-login-error';
|
import { WebCrawlerLoginError } from '../error/web-crawler-login-error';
|
||||||
import { IWebCrawler } from '../web-crawler/i-web-crawler';
|
import { IWebCrawler } from '../web-crawler/i-web-crawler';
|
||||||
|
@ -33,7 +34,7 @@ interface ILoginParams extends ILoginMeta, ILoginAuth {}
|
||||||
export class NhentaiApi implements INhentaiApi {
|
export class NhentaiApi implements INhentaiApi {
|
||||||
private webCrawler: IWebCrawler;
|
private webCrawler: IWebCrawler;
|
||||||
|
|
||||||
public constructor(@inject(Symbol.for('web-crawler')) webCrawler: IWebCrawler) {
|
public constructor(@inject('web-crawler') webCrawler: IWebCrawler) {
|
||||||
this.webCrawler = webCrawler;
|
this.webCrawler = webCrawler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ export class NhentaiIpcController implements IIpcController {
|
||||||
}
|
}
|
||||||
|
|
||||||
public get(): NhentaiIpcController {
|
public get(): NhentaiIpcController {
|
||||||
const nhentaiApi: INhentaiApi = container.get(Symbol.for('nhentai-api'));
|
const nhentaiApi: INhentaiApi = container.get('nhentai-api');
|
||||||
return new NhentaiIpcController(nhentaiApi);
|
return new NhentaiIpcController(nhentaiApi);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ describe('Store Service', function () {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('loads saved data', () => {
|
it('loads saved data', () => {
|
||||||
const store: IStore = container.get(Symbol.for('store'));
|
const store: IStore = container.get('store');
|
||||||
const testData = {
|
const testData = {
|
||||||
something: 'gaga',
|
something: 'gaga',
|
||||||
somethingElse: 0,
|
somethingElse: 0,
|
||||||
|
|
|
@ -17,8 +17,8 @@ describe('Web Crawler', function () {
|
||||||
before(() => {
|
before(() => {
|
||||||
rewiremock.enable();
|
rewiremock.enable();
|
||||||
|
|
||||||
container.unbind(Symbol.for('store'));
|
container.unbind('store');
|
||||||
container.bind(Symbol.for('store')).to(StoreMock);
|
container.bind('store').to(StoreMock);
|
||||||
});
|
});
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
@ -34,8 +34,8 @@ describe('Web Crawler', function () {
|
||||||
after(() => {
|
after(() => {
|
||||||
rewiremock.disable();
|
rewiremock.disable();
|
||||||
|
|
||||||
container.unbind(Symbol.for('store'));
|
container.unbind('store');
|
||||||
container.bind(Symbol.for('store')).to(Store);
|
container.bind('store').to(Store);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('fetches websites', async () => {
|
it('fetches websites', async () => {
|
||||||
|
@ -54,7 +54,7 @@ describe('Web Crawler', function () {
|
||||||
)
|
)
|
||||||
.persist();
|
.persist();
|
||||||
|
|
||||||
const webCrawler: IWebCrawler = container.get(Symbol.for('web-crawler'));
|
const webCrawler: IWebCrawler = container.get('web-crawler');
|
||||||
|
|
||||||
const res: Response = await webCrawler.fetch(testUrl);
|
const res: Response = await webCrawler.fetch(testUrl);
|
||||||
expect(callback.callCount).to.equal(1, 'multiple requests (or none) are sent when only one should be');
|
expect(callback.callCount).to.equal(1, 'multiple requests (or none) are sent when only one should be');
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { inject, injectable } from 'inversify';
|
import { injectable } from 'inversify';
|
||||||
import { CookieJar } from 'jsdom';
|
import { CookieJar } from 'jsdom';
|
||||||
import nodeFetch, { RequestInit, Response } from 'node-fetch';
|
import nodeFetch, { RequestInit, Response } from 'node-fetch';
|
||||||
|
import { inject } from '../../core/inject';
|
||||||
import { CookieSaveError } from '../error/cookie-save-error';
|
import { CookieSaveError } from '../error/cookie-save-error';
|
||||||
import { IStore } from '../store/i-store';
|
import { IStore } from '../store/i-store';
|
||||||
import { IWebCrawler } from './i-web-crawler';
|
import { IWebCrawler } from './i-web-crawler';
|
||||||
|
@ -13,7 +14,7 @@ export class WebCrawler implements IWebCrawler {
|
||||||
|
|
||||||
private store: IStore;
|
private store: IStore;
|
||||||
|
|
||||||
public constructor(@inject(Symbol.for('store')) store: IStore) {
|
public constructor(@inject('store') store: IStore) {
|
||||||
this.initialized = false;
|
this.initialized = false;
|
||||||
this.cookieJar = new CookieJar();
|
this.cookieJar = new CookieJar();
|
||||||
this.store = store;
|
this.store = store;
|
||||||
|
|
Loading…
Reference in New Issue