From 9da2d5e2f2b6c77688fd1497b46bad19a19e87fa Mon Sep 17 00:00:00 2001 From: Collin Duncan <3679940+cgduncan7@users.noreply.github.com> Date: Tue, 27 Jun 2023 16:06:19 +0200 Subject: [PATCH] Formatting fixes --- src/app.module.ts | 2 +- src/common/customResponse.ts | 24 +- src/common/dayjs.ts | 20 +- src/logger/middleware.ts | 16 +- src/reservations/config.ts | 4 +- src/reservations/cron.ts | 14 +- src/reservations/entity.ts | 44 ++-- src/reservations/module.ts | 1 - src/reservations/service.ts | 3 +- src/reservations/worker.ts | 36 +-- src/runner/baanreserveren/service.ts | 368 +++++++++++++-------------- src/runner/module.ts | 9 +- src/runner/pages/empty.ts | 16 +- src/runner/service.ts | 142 ++++++----- 14 files changed, 359 insertions(+), 340 deletions(-) diff --git a/src/app.module.ts b/src/app.module.ts index 22b749c..0e506d8 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -25,7 +25,7 @@ import { LoggerModule } from './logger/module' }, defaultJobOptions: { removeOnComplete: true, - } + }, }), ScheduleModule.forRoot(), ConfigModule.forRoot({ isGlobal: true }), diff --git a/src/common/customResponse.ts b/src/common/customResponse.ts index 1566b40..c1cf425 100644 --- a/src/common/customResponse.ts +++ b/src/common/customResponse.ts @@ -1,14 +1,24 @@ -import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common' +import { + Injectable, + NestInterceptor, + ExecutionContext, + CallHandler, +} from '@nestjs/common' import { Observable } from 'rxjs' import { map } from 'rxjs/operators' export interface CustomResponse { - data: T + data: T } @Injectable() -export class CustomResponseTransformInterceptor implements NestInterceptor> { - intercept(_context: ExecutionContext, next: CallHandler): Observable> { - return next.handle().pipe(map(data => ({ data }))) - } -} \ No newline at end of file +export class CustomResponseTransformInterceptor + implements NestInterceptor> +{ + intercept( + _context: ExecutionContext, + next: CallHandler, + ): Observable> { + return next.handle().pipe(map((data) => ({ data }))) + } +} diff --git a/src/common/dayjs.ts b/src/common/dayjs.ts index b21a15d..343f693 100644 --- a/src/common/dayjs.ts +++ b/src/common/dayjs.ts @@ -12,27 +12,27 @@ dayjs.locale('nl') dayjs.tz.setDefault('Europe/Amsterdam') export interface DateRange { - start: dayjs.Dayjs - end: dayjs.Dayjs + start: dayjs.Dayjs + end: dayjs.Dayjs } export interface SerializedDateRange { - start: string - end: string + start: string + end: string } export const convertDateRangeStringToObject = ({ - start, - end, + start, + end, }: { - start: string - end: string + start: string + end: string }): DateRange => ({ start: dayjs(start), end: dayjs(end) }) const dayjsTz = ( - date?: string | number | Date | dayjs.Dayjs | null | undefined + date?: string | number | Date | dayjs.Dayjs | null | undefined, ) => { - return dayjs(date).tz() + return dayjs(date).tz() } export default dayjsTz diff --git a/src/logger/middleware.ts b/src/logger/middleware.ts index 1dbb08d..9e4d604 100644 --- a/src/logger/middleware.ts +++ b/src/logger/middleware.ts @@ -4,13 +4,13 @@ import { LoggerService } from './service' @Injectable() export class LoggerMiddleware implements NestMiddleware { - constructor( - @Inject(LoggerService) - private readonly logger: LoggerService, - ) {} + constructor( + @Inject(LoggerService) + private readonly logger: LoggerService, + ) {} - use(req: Request, _res: Response, next: NextFunction) { - this.logger.log(`${req.method} ${req.originalUrl}`) - next() - } + use(req: Request, _res: Response, next: NextFunction) { + this.logger.log(`${req.method} ${req.originalUrl}`) + next() + } } diff --git a/src/reservations/config.ts b/src/reservations/config.ts index db1a67f..d569d33 100644 --- a/src/reservations/config.ts +++ b/src/reservations/config.ts @@ -1,5 +1,5 @@ export const RESERVATIONS_QUEUE_NAME = 'reservations' export default () => ({ - queueName: RESERVATIONS_QUEUE_NAME -}) \ No newline at end of file + queueName: RESERVATIONS_QUEUE_NAME, +}) diff --git a/src/reservations/cron.ts b/src/reservations/cron.ts index e1490aa..c7be059 100644 --- a/src/reservations/cron.ts +++ b/src/reservations/cron.ts @@ -11,7 +11,7 @@ export class ReservationsCronService { constructor( @Inject(ReservationsService) private readonly reservationService: ReservationsService, - + @InjectQueue(RESERVATIONS_QUEUE_NAME) private readonly reservationsQueue: Queue, @@ -24,8 +24,12 @@ export class ReservationsCronService { timeZone: 'Europe/Amsterdam', }) async handleDailyReservations() { - const reservationsToPerform = await this.reservationService.getByDate() - this.logger.log(`Found ${reservationsToPerform.length} reservations to perform`) - await this.reservationsQueue.addBulk(reservationsToPerform.map((r) => ({ data: r }))) - } + const reservationsToPerform = await this.reservationService.getByDate() + this.logger.log( + `Found ${reservationsToPerform.length} reservations to perform`, + ) + await this.reservationsQueue.addBulk( + reservationsToPerform.map((r) => ({ data: r })), + ) + } } diff --git a/src/reservations/entity.ts b/src/reservations/entity.ts index 24bcd77..4f227c8 100644 --- a/src/reservations/entity.ts +++ b/src/reservations/entity.ts @@ -21,7 +21,7 @@ export class Reservation { @Type(() => Dayjs) @Transform(({ value }) => dayjs(value).format()) dateRangeStart: Dayjs - + @Column('datetime', { nullable: false }) @Type(() => Dayjs) @Transform(({ value }) => dayjs(value).format()) @@ -39,33 +39,33 @@ export class Reservation { @Exclude() public createPossibleDates(): Dayjs[] { - const possibleDates: Dayjs[] = [] + const possibleDates: Dayjs[] = [] - let possibleDate = dayjs(this.dateRangeStart).second(0).millisecond(0) - while (possibleDate.isSameOrBefore(this.dateRangeEnd)) { - possibleDates.push(possibleDate) - possibleDate = possibleDate.add(15, 'minute') - } + let possibleDate = dayjs(this.dateRangeStart).second(0).millisecond(0) + while (possibleDate.isSameOrBefore(this.dateRangeEnd)) { + possibleDates.push(possibleDate) + possibleDate = possibleDate.add(15, 'minute') + } - return possibleDates - } + return possibleDates + } - /** - * Method to check if a reservation is available for reservation in the system - * @returns is reservation date within 7 days - */ + /** + * Method to check if a reservation is available for reservation in the system + * @returns is reservation date within 7 days + */ @Exclude() - public isAvailableForReservation(): boolean { + public isAvailableForReservation(): boolean { return dayjs().diff(this.dateRangeStart, 'day') <= 7 - } + } @Exclude() - public getAllowedReservationDate(): Dayjs { + public getAllowedReservationDate(): Dayjs { return this.dateRangeStart - .hour(0) - .minute(0) - .second(0) - .millisecond(0) - .subtract(7, 'days') - } + .hour(0) + .minute(0) + .second(0) + .millisecond(0) + .subtract(7, 'days') + } } diff --git a/src/reservations/module.ts b/src/reservations/module.ts index 7636301..f7b5226 100644 --- a/src/reservations/module.ts +++ b/src/reservations/module.ts @@ -10,7 +10,6 @@ import { ReservationsWorker } from './worker' import { LoggerModule } from '../logger/module' import { RunnerModule } from '../runner/module' - @Module({ imports: [ LoggerModule, diff --git a/src/reservations/service.ts b/src/reservations/service.ts index 5c7a477..3d06f87 100644 --- a/src/reservations/service.ts +++ b/src/reservations/service.ts @@ -20,7 +20,8 @@ export class ReservationsService { } getByDate(date = dayjs()) { - return this.reservationsRepository.createQueryBuilder() + return this.reservationsRepository + .createQueryBuilder() .where(`DATE(dateRangeStart, '-7 day') = DATE(:date)`, { date }) .getMany() } diff --git a/src/reservations/worker.ts b/src/reservations/worker.ts index a8ecaca..74cf333 100644 --- a/src/reservations/worker.ts +++ b/src/reservations/worker.ts @@ -9,22 +9,26 @@ import { LoggerService } from '../logger/service' @Processor(RESERVATIONS_QUEUE_NAME) export class ReservationsWorker { - constructor( - @Inject(BaanReserverenService) - private readonly brService: BaanReserverenService, + constructor( + @Inject(BaanReserverenService) + private readonly brService: BaanReserverenService, - @Inject(LoggerService) - private readonly logger: LoggerService, - ) {} + @Inject(LoggerService) + private readonly logger: LoggerService, + ) {} - @Process() - async handleReservationJob(job: Job) { - const reservation = plainToInstance(Reservation, job.data, { groups: ['password'] }) - this.logger.log('Handling reservation', { reservation: instanceToPlain(reservation) }) - await this.performReservation(reservation) - } + @Process() + async handleReservationJob(job: Job) { + const reservation = plainToInstance(Reservation, job.data, { + groups: ['password'], + }) + this.logger.log('Handling reservation', { + reservation: instanceToPlain(reservation), + }) + await this.performReservation(reservation) + } - async performReservation(reservation: Reservation) { - await this.brService.performReservation(reservation) - } -} \ No newline at end of file + async performReservation(reservation: Reservation) { + await this.brService.performReservation(reservation) + } +} diff --git a/src/runner/baanreserveren/service.ts b/src/runner/baanreserveren/service.ts index 64b8aa4..825c6a7 100644 --- a/src/runner/baanreserveren/service.ts +++ b/src/runner/baanreserveren/service.ts @@ -9,221 +9,221 @@ import { Reservation } from '../../reservations/entity' const baanReserverenRoot = 'https://squashcity.baanreserveren.nl' export enum BaanReserverenUrls { - Reservations = '/reservations', - Logout = '/auth/logout', + Reservations = '/reservations', + Logout = '/auth/logout', } enum SessionAction { - NoAction, - Logout, - Login, + NoAction, + Logout, + Login, } interface BaanReserverenSession { - username: string - startedAt: Dayjs + username: string + startedAt: Dayjs } @Injectable() export class BaanReserverenService { - private session: BaanReserverenSession | null = null + private session: BaanReserverenSession | null = null - constructor( - @Inject(RunnerService) - private readonly runnerService: RunnerService, + constructor( + @Inject(RunnerService) + private readonly runnerService: RunnerService, - @Inject(EmptyPage) - private readonly page: Page, - ) {} + @Inject(EmptyPage) + private readonly page: Page, + ) {} - private checkSession(username: string) { - if (this.page.url().endsWith(BaanReserverenUrls.Reservations)) { - return this.session?.username !== username - ? SessionAction.Logout - : SessionAction.NoAction - } - return SessionAction.Login - } + private checkSession(username: string) { + if (this.page.url().endsWith(BaanReserverenUrls.Reservations)) { + return this.session?.username !== username + ? SessionAction.Logout + : SessionAction.NoAction + } + return SessionAction.Login + } - private startSession(username: string) { - if (this.session && this.session.username !== username) { - throw new Error('Session already started') - } + private startSession(username: string) { + if (this.session && this.session.username !== username) { + throw new Error('Session already started') + } - if (this.session?.username === username) { - return - } + if (this.session?.username === username) { + return + } - this.session = { - username, - startedAt: dayjs(), - } - } + this.session = { + username, + startedAt: dayjs(), + } + } - private endSession() { - this.session = null - } + private endSession() { + this.session = null + } - private async login(username: string, password: string) { - await this.page - .waitForSelector('input[name=username]') - .then((i) => i?.type(username)) - .catch((e: Error) => { - // throw new RunnerLoginUsernameInputError(e) - }) - await this.page - .$('input[name=password]') - .then((i) => i?.type(password)) - .catch((e: Error) => { - // throw new RunnerLoginPasswordInputError(e) - }) - await this.page - .$('button') - .then((b) => b?.click()) - .catch((e: Error) => { - // throw new RunnerLoginSubmitError(e) - }) - this.startSession(username) - } - - private async logout() { - await this.page.goto(`${baanReserverenRoot}${BaanReserverenUrls.Logout}`) - this.endSession() - } + private async login(username: string, password: string) { + await this.page + .waitForSelector('input[name=username]') + .then((i) => i?.type(username)) + .catch((e: Error) => { + // throw new RunnerLoginUsernameInputError(e) + }) + await this.page + .$('input[name=password]') + .then((i) => i?.type(password)) + .catch((e: Error) => { + // throw new RunnerLoginPasswordInputError(e) + }) + await this.page + .$('button') + .then((b) => b?.click()) + .catch((e: Error) => { + // throw new RunnerLoginSubmitError(e) + }) + this.startSession(username) + } - private async init(reservation: Reservation) { - await this.page.goto(baanReserverenRoot) - const action = await this.checkSession(reservation.username) - switch (action) { - case SessionAction.Logout: - await this.logout() - await this.login(reservation.username, reservation.password) - break - case SessionAction.Login: - await this.login(reservation.username, reservation.password) - break - case SessionAction.NoAction: - default: - break - } - } + private async logout() { + await this.page.goto(`${baanReserverenRoot}${BaanReserverenUrls.Logout}`) + this.endSession() + } - private getLastVisibleDay(): Dayjs { - const lastDayOfMonth = dayjs().add(1, 'month').set('date', 0) - let daysToAdd = 0 - switch (lastDayOfMonth.day()) { - case 0: - daysToAdd = 0 - break - default: - daysToAdd = 7 - lastDayOfMonth.day() - break - } - return lastDayOfMonth.add(daysToAdd, 'day') - } + private async init(reservation: Reservation) { + await this.page.goto(baanReserverenRoot) + const action = await this.checkSession(reservation.username) + switch (action) { + case SessionAction.Logout: + await this.logout() + await this.login(reservation.username, reservation.password) + break + case SessionAction.Login: + await this.login(reservation.username, reservation.password) + break + case SessionAction.NoAction: + default: + break + } + } - private async navigateToDay(date: Dayjs): Promise { - if (this.getLastVisibleDay().isBefore(date)) { - await this.page - ?.waitForSelector('td.month.next') - .then((d) => d?.click()) - .catch((e: Error) => { - throw new RunnerNavigationMonthError(e) - }) - } + private getLastVisibleDay(): Dayjs { + const lastDayOfMonth = dayjs().add(1, 'month').set('date', 0) + let daysToAdd = 0 + switch (lastDayOfMonth.day()) { + case 0: + daysToAdd = 0 + break + default: + daysToAdd = 7 - lastDayOfMonth.day() + break + } + return lastDayOfMonth.add(daysToAdd, 'day') + } - await this.page - ?.waitForSelector( - `td#cal_${date.get('year')}_${date.get('month') + 1}_${date.get( - 'date' - )}` - ) - .then((d) => d?.click()) - .catch((e: Error) => { - throw new RunnerNavigationDayError(e) - }) - await this.page - ?.waitForSelector( - `td#cal_${date.get('year')}_${date.get('month') + 1}_${date.get( - 'date' - )}.selected` - ) - .catch((e: Error) => { - throw new RunnerNavigationSelectionError(e) - }) - } + private async navigateToDay(date: Dayjs): Promise { + if (this.getLastVisibleDay().isBefore(date)) { + await this.page + ?.waitForSelector('td.month.next') + .then((d) => d?.click()) + .catch((e: Error) => { + throw new RunnerNavigationMonthError(e) + }) + } - private async selectAvailableTime(reservation: Reservation): Promise { - let freeCourt: ElementHandle | null | undefined - let i = 0 - const possibleDates = reservation.createPossibleDates() - while (i < possibleDates.length && !freeCourt) { - const possibleDate = possibleDates[i] - const timeString = possibleDate.format('HH:mm') - const selector = - `tr[data-time='${timeString}']` + `> td.free[rowspan='3'][type='free']` - freeCourt = await this.page?.$(selector) - i++ - } + await this.page + ?.waitForSelector( + `td#cal_${date.get('year')}_${date.get('month') + 1}_${date.get( + 'date', + )}`, + ) + .then((d) => d?.click()) + .catch((e: Error) => { + throw new RunnerNavigationDayError(e) + }) + await this.page + ?.waitForSelector( + `td#cal_${date.get('year')}_${date.get('month') + 1}_${date.get( + 'date', + )}.selected`, + ) + .catch((e: Error) => { + throw new RunnerNavigationSelectionError(e) + }) + } - if (!freeCourt) { - throw new NoCourtAvailableError() - } + private async selectAvailableTime(reservation: Reservation): Promise { + let freeCourt: ElementHandle | null | undefined + let i = 0 + const possibleDates = reservation.createPossibleDates() + while (i < possibleDates.length && !freeCourt) { + const possibleDate = possibleDates[i] + const timeString = possibleDate.format('HH:mm') + const selector = + `tr[data-time='${timeString}']` + `> td.free[rowspan='3'][type='free']` + freeCourt = await this.page?.$(selector) + i++ + } - await freeCourt.click().catch((e: Error) => { - throw new RunnerCourtSelectionError(e) - }) - } + if (!freeCourt) { + throw new NoCourtAvailableError() + } - private async selectOpponent(id: string, name: string): Promise { - const player2Search = await this.page - ?.waitForSelector('tr.res-make-player-2 > td > input') - .catch((e: Error) => { - throw new RunnerOpponentSearchError(e) - }) - await player2Search?.type(name).catch((e: Error) => { - throw new RunnerOpponentSearchInputError(e) - }) - await this.page?.waitForNetworkIdle().catch((e: Error) => { - throw new RunnerOpponentSearchNetworkError(e) - }) - await this.page - ?.$('select.br-user-select[name="players[2]"]') - .then((d) => d?.select(id)) - .catch((e: Error) => { - throw new RunnerOpponentSearchSelectionError(e) - }) - } + await freeCourt.click().catch((e: Error) => { + throw new RunnerCourtSelectionError(e) + }) + } - private async confirmReservation(): Promise { - await this.page - ?.$('input#__make_submit') - .then((b) => b?.click()) - .catch((e: Error) => { - throw new RunnerReservationConfirmButtonError(e) - }) - await this.page - ?.waitForSelector('input#__make_submit2') - .then((b) => b?.click()) - .catch((e: Error) => { - throw new RunnerReservationConfirmSubmitError(e) - }) - } + private async selectOpponent(id: string, name: string): Promise { + const player2Search = await this.page + ?.waitForSelector('tr.res-make-player-2 > td > input') + .catch((e: Error) => { + throw new RunnerOpponentSearchError(e) + }) + await player2Search?.type(name).catch((e: Error) => { + throw new RunnerOpponentSearchInputError(e) + }) + await this.page?.waitForNetworkIdle().catch((e: Error) => { + throw new RunnerOpponentSearchNetworkError(e) + }) + await this.page + ?.$('select.br-user-select[name="players[2]"]') + .then((d) => d?.select(id)) + .catch((e: Error) => { + throw new RunnerOpponentSearchSelectionError(e) + }) + } - public async performReservation(reservation: Reservation) { - await this.init(reservation) - await this.navigateToDay(reservation.dateRangeStart) - await this.selectAvailableTime(reservation) - await this.selectOpponent(reservation.opponentId, reservation.opponentName) - // await this.confirmReservation() - } + private async confirmReservation(): Promise { + await this.page + ?.$('input#__make_submit') + .then((b) => b?.click()) + .catch((e: Error) => { + throw new RunnerReservationConfirmButtonError(e) + }) + await this.page + ?.waitForSelector('input#__make_submit2') + .then((b) => b?.click()) + .catch((e: Error) => { + throw new RunnerReservationConfirmSubmitError(e) + }) + } + + public async performReservation(reservation: Reservation) { + await this.init(reservation) + await this.navigateToDay(reservation.dateRangeStart) + await this.selectAvailableTime(reservation) + await this.selectOpponent(reservation.opponentId, reservation.opponentName) + // await this.confirmReservation() + } } export class RunnerError extends Error { - constructor(error: Error) { - super(error.message) - this.stack = error.stack - } + constructor(error: Error) { + super(error.message) + this.stack = error.stack + } } export class PuppeteerError extends RunnerError {} export class PuppeteerBrowserLaunchError extends PuppeteerError {} diff --git a/src/runner/module.ts b/src/runner/module.ts index 965abd0..f2f27c6 100644 --- a/src/runner/module.ts +++ b/src/runner/module.ts @@ -6,9 +6,8 @@ import { BaanReserverenService } from './baanreserveren/service' import { LoggerModule } from '../logger/module' @Module({ - providers: [RunnerService, BaanReserverenService, EmptyPageFactory], - imports: [LoggerModule, BullModule.registerQueue({ name: 'reservations' })], - exports: [EmptyPageFactory, BaanReserverenService], + providers: [RunnerService, BaanReserverenService, EmptyPageFactory], + imports: [LoggerModule, BullModule.registerQueue({ name: 'reservations' })], + exports: [EmptyPageFactory, BaanReserverenService], }) - -export class RunnerModule {} \ No newline at end of file +export class RunnerModule {} diff --git a/src/runner/pages/empty.ts b/src/runner/pages/empty.ts index b1ded1a..49d3919 100644 --- a/src/runner/pages/empty.ts +++ b/src/runner/pages/empty.ts @@ -5,13 +5,13 @@ import { Page } from 'puppeteer' export const EmptyPage = Symbol.for('EmptyPage') export const EmptyPageFactory: FactoryProvider = { - provide: EmptyPage, - useFactory: async (runnerService: RunnerService) => { - const browser = await runnerService.getBrowser() - const page = await browser.newPage() + provide: EmptyPage, + useFactory: async (runnerService: RunnerService) => { + const browser = await runnerService.getBrowser() + const page = await browser.newPage() - return page - }, - inject: [RunnerService], - scope: Scope.TRANSIENT, + return page + }, + inject: [RunnerService], + scope: Scope.TRANSIENT, } diff --git a/src/runner/service.ts b/src/runner/service.ts index 7f19c2b..7fd842e 100644 --- a/src/runner/service.ts +++ b/src/runner/service.ts @@ -1,90 +1,92 @@ -import { Inject, Injectable, BeforeApplicationShutdown, OnModuleInit, Scope } from '@nestjs/common' -import puppeteer, { Browser, BrowserConnectOptions, BrowserLaunchArgumentOptions, LaunchOptions, Page } from 'puppeteer' -import { LoggerService } from '../logger/service' - -enum SessionAction { - NoAction, - Logout, - Login, -} +import { + Injectable, + BeforeApplicationShutdown, + OnModuleInit, +} from '@nestjs/common' +import puppeteer, { + Browser, + BrowserConnectOptions, + BrowserLaunchArgumentOptions, + LaunchOptions, +} from 'puppeteer' interface RunnerSession { - username: string - loggedInAt: Date + username: string + loggedInAt: Date } @Injectable() export class RunnerService implements OnModuleInit, BeforeApplicationShutdown { - private browser?: Browser - private options: LaunchOptions & - BrowserLaunchArgumentOptions & - BrowserConnectOptions = { - args: ['--disable-setuid-sandbox', '--no-sandbox'], - headless: 'new' - } - private session: RunnerSession | null = null + private browser?: Browser + private options: LaunchOptions & + BrowserLaunchArgumentOptions & + BrowserConnectOptions = { + args: ['--disable-setuid-sandbox', '--no-sandbox'], + headless: 'new', + } + private session: RunnerSession | null = null - private async init() { - try { - if (!this.browser) { - this.browser = await puppeteer.launch(this.options) - } - } catch (error) { - throw new PuppeteerBrowserLaunchError(error) - } - } + private async init() { + try { + if (!this.browser) { + this.browser = await puppeteer.launch(this.options) + } + } catch (error) { + throw new PuppeteerBrowserLaunchError(error) + } + } - public async onModuleInit() { - await this.init() - } + public async onModuleInit() { + await this.init() + } - public async beforeApplicationShutdown() { - try { - if (this.browser && this.browser.isConnected()) { - await this.browser.close() - } - } catch (error) { - console.error('error shutting down browser', error) - } - } + public async beforeApplicationShutdown() { + try { + if (this.browser && this.browser.isConnected()) { + await this.browser.close() + } + } catch (error) { + console.error('error shutting down browser', error) + } + } - public async getBrowser(): Promise { - await this.init() - if (!this.browser) { - throw new Error('Browser not initialized') - } - return this.browser - } + public async getBrowser(): Promise { + await this.init() + if (!this.browser) { + throw new Error('Browser not initialized') + } + return this.browser + } - public async getSession(): Promise { - return this.session - } + public async getSession(): Promise { + return this.session + } - public startSession(username: string) { - if (this.session && this.session.username !== username) { - throw new RunnerNewSessionError(new Error('Session already started')) - } + public startSession(username: string) { + if (this.session && this.session.username !== username) { + throw new RunnerNewSessionError(new Error('Session already started')) + } - if (this.session?.username === username) { - return - } + if (this.session?.username === username) { + return + } - this.session = { - username, - loggedInAt: new Date(), - } - } + this.session = { + username, + loggedInAt: new Date(), + } + } - public endSession() { - this.session = null - } + public endSession() { + this.session = null + } } export class RunnerError extends Error { - constructor(error: Error) { - super(error.message) - this.stack = error.stack - } + constructor(error: Error) { + super(error.message) + this.stack = error.stack + } } export class PuppeteerError extends RunnerError {} export class PuppeteerBrowserLaunchError extends PuppeteerError {} @@ -112,4 +114,4 @@ export class RunnerOpponentSearchNetworkError extends RunnerError {} export class RunnerOpponentSearchSelectionError extends RunnerError {} export class RunnerReservationConfirmButtonError extends RunnerError {} -export class RunnerReservationConfirmSubmitError extends RunnerError {} \ No newline at end of file +export class RunnerReservationConfirmSubmitError extends RunnerError {}