From d6938d847bc77b402cc5729f8f08190fdf785641 Mon Sep 17 00:00:00 2001 From: Pierre Cavin Date: Fri, 6 Oct 2023 00:26:24 +0200 Subject: [PATCH] fix: add back onComplete to callbacks signatures --- src/job.ts | 92 ++++++++++++++++++++++++----------------- src/time.ts | 14 +++---- src/types/cron.types.ts | 40 ++++++++++++++---- 3 files changed, 92 insertions(+), 54 deletions(-) diff --git a/src/job.ts b/src/job.ts index 1355c7c3..54daadc8 100644 --- a/src/job.ts +++ b/src/job.ts @@ -5,54 +5,58 @@ import { CronCallback, CronCommand, CronContext, - CronJobParams + CronJobParams, + CronOnCompleteCallback, + CronOnCompleteCommand, + WithOnComplete } from './types/cron.types'; -export class CronJob { +export class CronJob | null, C = null> { cronTime: CronTime; running = false; unrefTimeout = false; lastExecution: Date | null = null; runOnce = false; context: CronContext; - onComplete?: CronCallback; + onComplete?: WithOnComplete extends true + ? CronOnCompleteCallback + : undefined; private _timeout?: NodeJS.Timeout; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - private _callbacks: ((...args: any) => void)[] = []; + private _callbacks: CronCallback>[] = []; constructor( - cronTime: CronJobParams['cronTime'], - onTick: CronJobParams['onTick'], - onComplete?: CronJobParams['onComplete'], - start?: CronJobParams['start'], - timeZone?: CronJobParams['timeZone'], - context?: CronJobParams['context'], - runOnInit?: CronJobParams['runOnInit'], + cronTime: CronJobParams['cronTime'], + onTick: CronJobParams['onTick'], + onComplete?: CronJobParams['onComplete'], + start?: CronJobParams['start'], + timeZone?: CronJobParams['timeZone'], + context?: CronJobParams['context'], + runOnInit?: CronJobParams['runOnInit'], utcOffset?: null, - unrefTimeout?: CronJobParams['unrefTimeout'] + unrefTimeout?: CronJobParams['unrefTimeout'] ); constructor( - cronTime: CronJobParams['cronTime'], - onTick: CronJobParams['onTick'], - onComplete?: CronJobParams['onComplete'], - start?: CronJobParams['start'], + cronTime: CronJobParams['cronTime'], + onTick: CronJobParams['onTick'], + onComplete?: CronJobParams['onComplete'], + start?: CronJobParams['start'], timeZone?: null, - context?: CronJobParams['context'], - runOnInit?: CronJobParams['runOnInit'], - utcOffset?: CronJobParams['utcOffset'], - unrefTimeout?: CronJobParams['unrefTimeout'] + context?: CronJobParams['context'], + runOnInit?: CronJobParams['runOnInit'], + utcOffset?: CronJobParams['utcOffset'], + unrefTimeout?: CronJobParams['unrefTimeout'] ); constructor( - cronTime: CronJobParams['cronTime'], - onTick: CronJobParams['onTick'], - onComplete?: CronJobParams['onComplete'], - start?: CronJobParams['start'], - timeZone?: CronJobParams['timeZone'], - context?: CronJobParams['context'], - runOnInit?: CronJobParams['runOnInit'], - utcOffset?: CronJobParams['utcOffset'], - unrefTimeout?: CronJobParams['unrefTimeout'] + cronTime: CronJobParams['cronTime'], + onTick: CronJobParams['onTick'], + onComplete?: CronJobParams['onComplete'], + start?: CronJobParams['start'], + timeZone?: CronJobParams['timeZone'], + context?: CronJobParams['context'], + runOnInit?: CronJobParams['runOnInit'], + utcOffset?: CronJobParams['utcOffset'], + unrefTimeout?: CronJobParams['unrefTimeout'] ) { this.context = (context ?? this) as CronContext; @@ -74,7 +78,12 @@ export class CronJob { } if (onComplete != null) { - this.onComplete = this._fnWrap(onComplete); + // casting to the correct type since we just made sure that WithOnComplete = true + this.onComplete = this._fnWrap( + onComplete + ) as WithOnComplete extends true + ? CronOnCompleteCallback + : undefined; } if (this.cronTime.realDate) { @@ -91,7 +100,9 @@ export class CronJob { if (start) this.start(); } - static from(params: CronJobParams) { + static from | null = null>( + params: CronJobParams + ) { // runtime check for JS users // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition if (params.timeZone != null && params.utcOffset != null) { @@ -99,7 +110,7 @@ export class CronJob { } if (params.timeZone != null) { - return new CronJob( + return new CronJob( params.cronTime, params.onTick, params.onComplete, @@ -111,7 +122,7 @@ export class CronJob { params.unrefTimeout ); } else if (params.utcOffset != null) { - return new CronJob( + return new CronJob( params.cronTime, params.onTick, params.onComplete, @@ -123,7 +134,7 @@ export class CronJob { params.unrefTimeout ); } else { - return new CronJob( + return new CronJob( params.cronTime, params.onTick, params.onComplete, @@ -137,7 +148,7 @@ export class CronJob { } } - private _fnWrap(cmd: CronCommand) { + private _fnWrap(cmd: CronCommand): CronCallback { switch (typeof cmd) { case 'function': { return cmd; @@ -161,7 +172,7 @@ export class CronJob { } // eslint-disable-next-line @typescript-eslint/no-explicit-any - addCallback(callback: (...args: any) => void) { + addCallback(callback: CronCallback>) { if (typeof callback === 'function') { this._callbacks.push(callback); } @@ -183,7 +194,12 @@ export class CronJob { fireOnTick() { for (const callback of this._callbacks) { - callback.call(this.context, this.onComplete); + callback.call( + this.context, + this.onComplete as WithOnComplete extends true + ? CronOnCompleteCallback + : never + ); } } diff --git a/src/time.ts b/src/time.ts index 1a32b9f6..a87d4569 100644 --- a/src/time.ts +++ b/src/time.ts @@ -37,19 +37,19 @@ export class CronTime { private dayOfWeek: TimeUnitField<'dayOfWeek'> = {}; constructor( - source: CronJobParams['cronTime'], - timeZone?: CronJobParams['timeZone'], + source: CronJobParams['cronTime'], + timeZone?: CronJobParams['timeZone'], utcOffset?: null ); constructor( - source: CronJobParams['cronTime'], + source: CronJobParams['cronTime'], timeZone?: null, - utcOffset?: CronJobParams['utcOffset'] + utcOffset?: CronJobParams['utcOffset'] ); constructor( - source: CronJobParams['cronTime'], - timeZone?: CronJobParams['timeZone'], - utcOffset?: CronJobParams['utcOffset'] + source: CronJobParams['cronTime'], + timeZone?: CronJobParams['timeZone'], + utcOffset?: CronJobParams['utcOffset'] ) { // runtime check for JS users if (timeZone != null && utcOffset != null) { diff --git a/src/types/cron.types.ts b/src/types/cron.types.ts index 163a7640..67fe1a62 100644 --- a/src/types/cron.types.ts +++ b/src/types/cron.types.ts @@ -4,18 +4,24 @@ import { CONSTRAINTS, TIME_UNITS_MAP } from '../constants'; import { CronJob } from '../job'; import { IntRange } from './utils'; -interface BaseCronJobParams { +interface BaseCronJobParams< + OC extends CronOnCompleteCommand | null, + C = null +> { cronTime: string | Date | DateTime; - onTick: CronCommand; - onComplete?: CronCommand | null; + onTick: CronCommand>; + onComplete?: OC; start?: boolean | null; context?: C; runOnInit?: boolean | null; unrefTimeout?: boolean | null; } -export type CronJobParams = - | BaseCronJobParams & +export type CronJobParams< + OC extends CronOnCompleteCommand | null, + C = null +> = + | BaseCronJobParams & ( | { timeZone?: string | null; @@ -27,12 +33,18 @@ export type CronJobParams = } ); -export type CronContext = C extends null ? CronJob : NonNullable; +export type CronContext = C extends null ? CronJob : NonNullable; -export type CronCallback = (this: CronContext) => void; +export type CronCallback = ( + this: CronContext, + onComplete: WithOnCompleteBool extends true + ? OmitThisParameter> + : never +) => void; -export type CronCommand = - | CronCallback +export type CronOnCompleteCallback = (this: CronContext) => void; + +export type CronSystemCommand = | string | { command: string; @@ -40,6 +52,16 @@ export type CronCommand = options?: SpawnOptions | null; }; +export type CronCommand = + | CronCallback + | CronSystemCommand; + +export type CronOnCompleteCommand = + | OmitThisParameter> + | CronSystemCommand; + +export type WithOnComplete = OC extends null ? false : true; + export type TimeUnit = (typeof TIME_UNITS_MAP)[keyof typeof TIME_UNITS_MAP]; export type TimeUnitField = Partial<