UNPKG

typescript-type

Version:
79 lines (68 loc) 2.6 kB
import { randomBytes } from 'crypto'; import { isLeft } from 'fp-ts/lib/Either'; import * as t from 'io-ts'; import reporter from 'io-ts-reporters'; import { PartialRecord } from '../types/operand'; import { BadConfigException } from './driver.exceptions'; import { Statuses } from './driver.statuses'; import { LinkStrategy, LinksObject } from './driver.types'; export abstract class Driver<Config = any> { public name = 'driver'; protected config: Config; protected linkStrategy: LinkStrategy = 'default'; protected abstract links: LinksObject; constructor(config: Config, protected configCodec: any) { this.config = this.getParsedData(config, configCodec); } public setName(name: string) { this.name = name; } public setConfig(config: Config) { this.config = this.getParsedData(config, this.configCodec); } public setLinkStrategy(strategy: LinkStrategy) { this.linkStrategy = strategy; } public generateId(max = 12, length = 8) { const random = randomBytes(3 * 4).toString('base64').replace(/\/|\+/g, ''); return this.now(max) + random.substring(0, length).toUpperCase(); } public status(statuses: PartialRecord<Statuses, string[]>, code: string) { for (const s in statuses) { const c = statuses[<Statuses>s]; if (c && code && c.indexOf(code) > -1) { return s; } } return Statuses.pending; } public now(max = 12): string { return (new Date()).toISOString().replace(/[^0-9]/g, '').substring(0, max); } protected getLinks() { return this.links[this.linkStrategy]; } /** * Parses using the codec and throws an exception if not matching * * @throws BadConfigException */ protected getParsedData = <TData = any, O = TData, I = unknown>(rawData: I, codec: t.Type<TData, O, I>): TData => { const result = codec.decode(rawData); if (isLeft(result)) { // Use a reporter to throw an error if validation fails throw new BadConfigException(reporter.report(result)); } // Get the validated value and use it in your application return result.right; }; } export const getDriver = <T extends Driver, U extends string>( driverName: U, config: Parameters<Driver['setConfig']>[0], drivers: { [x: string]: any; } ): T => { if (!drivers[driverName]) { throw Error(`This driver is not supported, supported drivers: ${Object.keys(drivers).join(', ')}`); } const driver = drivers[driverName], instance = new driver(config) as unknown as T; instance.name = driverName; if (config.sandbox) { instance.setLinkStrategy('sandbox'); } return instance; };