Initial commit with Advoware proxy

This commit is contained in:
root
2025-10-19 14:57:07 +00:00
commit 273aa8b549
45771 changed files with 5534555 additions and 0 deletions

View File

@@ -0,0 +1,60 @@
export declare const CONSTRAINTS: Readonly<{
readonly second: readonly [0, 59];
readonly minute: readonly [0, 59];
readonly hour: readonly [0, 23];
readonly dayOfMonth: readonly [1, 31];
readonly month: readonly [1, 12];
readonly dayOfWeek: readonly [0, 7];
}>;
export declare const PARSE_DEFAULTS: Readonly<{
readonly second: "0";
readonly minute: "*";
readonly hour: "*";
readonly dayOfMonth: "*";
readonly month: "*";
readonly dayOfWeek: "*";
}>;
export declare const ALIASES: Readonly<{
readonly jan: 1;
readonly feb: 2;
readonly mar: 3;
readonly apr: 4;
readonly may: 5;
readonly jun: 6;
readonly jul: 7;
readonly aug: 8;
readonly sep: 9;
readonly oct: 10;
readonly nov: 11;
readonly dec: 12;
readonly sun: 0;
readonly mon: 1;
readonly tue: 2;
readonly wed: 3;
readonly thu: 4;
readonly fri: 5;
readonly sat: 6;
}>;
export declare const TIME_UNITS_MAP: Readonly<{
readonly SECOND: "second";
readonly MINUTE: "minute";
readonly HOUR: "hour";
readonly DAY_OF_MONTH: "dayOfMonth";
readonly MONTH: "month";
readonly DAY_OF_WEEK: "dayOfWeek";
}>;
export declare const TIME_UNITS: ["second", "minute", "hour", "dayOfMonth", "month", "dayOfWeek"];
export declare const TIME_UNITS_LEN: number;
export declare const PRESETS: Readonly<{
readonly '@yearly': "0 0 0 1 1 *";
readonly '@monthly': "0 0 0 1 * *";
readonly '@weekly': "0 0 0 * * 0";
readonly '@daily': "0 0 0 * * *";
readonly '@hourly': "0 0 * * * *";
readonly '@minutely': "0 * * * * *";
readonly '@secondly': "* * * * * *";
readonly '@weekdays': "0 0 0 * * 1-5";
readonly '@weekends': "0 0 0 * * 0,6";
}>;
export declare const RE_WILDCARDS: RegExp;
export declare const RE_RANGE: RegExp;

View File

@@ -0,0 +1,63 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.RE_RANGE = exports.RE_WILDCARDS = exports.PRESETS = exports.TIME_UNITS_LEN = exports.TIME_UNITS = exports.TIME_UNITS_MAP = exports.ALIASES = exports.PARSE_DEFAULTS = exports.CONSTRAINTS = void 0;
exports.CONSTRAINTS = Object.freeze({
second: [0, 59],
minute: [0, 59],
hour: [0, 23],
dayOfMonth: [1, 31],
month: [1, 12],
dayOfWeek: [0, 7]
});
exports.PARSE_DEFAULTS = Object.freeze({
second: '0',
minute: '*',
hour: '*',
dayOfMonth: '*',
month: '*',
dayOfWeek: '*'
});
exports.ALIASES = Object.freeze({
jan: 1,
feb: 2,
mar: 3,
apr: 4,
may: 5,
jun: 6,
jul: 7,
aug: 8,
sep: 9,
oct: 10,
nov: 11,
dec: 12,
sun: 0,
mon: 1,
tue: 2,
wed: 3,
thu: 4,
fri: 5,
sat: 6
});
exports.TIME_UNITS_MAP = Object.freeze({
SECOND: 'second',
MINUTE: 'minute',
HOUR: 'hour',
DAY_OF_MONTH: 'dayOfMonth',
MONTH: 'month',
DAY_OF_WEEK: 'dayOfWeek'
});
exports.TIME_UNITS = Object.freeze(Object.values(exports.TIME_UNITS_MAP));
exports.TIME_UNITS_LEN = exports.TIME_UNITS.length;
exports.PRESETS = Object.freeze({
'@yearly': '0 0 0 1 1 *',
'@monthly': '0 0 0 1 * *',
'@weekly': '0 0 0 * * 0',
'@daily': '0 0 0 * * *',
'@hourly': '0 0 * * * *',
'@minutely': '0 * * * * *',
'@secondly': '* * * * * *',
'@weekdays': '0 0 0 * * 1-5',
'@weekends': '0 0 0 * * 0,6'
});
exports.RE_WILDCARDS = /\*/g;
exports.RE_RANGE = /^(\d+)(?:-(\d+))?(?:\/(\d+))?$/g;

View File

@@ -0,0 +1,5 @@
export declare class CronError extends Error {
}
export declare class ExclusiveParametersError extends CronError {
constructor(param1: string, param2: string);
}

View File

@@ -0,0 +1,12 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ExclusiveParametersError = exports.CronError = void 0;
class CronError extends Error {
}
exports.CronError = CronError;
class ExclusiveParametersError extends CronError {
constructor(param1, param2) {
super(`You can't specify both ${param1} and ${param2}`);
}
}
exports.ExclusiveParametersError = ExclusiveParametersError;

View File

@@ -0,0 +1,8 @@
import { DateTime } from 'luxon';
import { CronTime } from './time';
export { CronJob } from './job';
export { CronTime } from './time';
export { CronCallback, CronCommand, CronContext, CronJobParams, CronOnCompleteCallback, CronOnCompleteCommand, Ranges, TimeUnit } from './types/cron.types';
export declare const sendAt: (cronTime: string | Date | DateTime) => DateTime;
export declare const timeout: (cronTime: string | Date | DateTime) => number;
export declare const validateCronExpression: typeof CronTime.validateCronExpression;

View File

@@ -0,0 +1,13 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.validateCronExpression = exports.timeout = exports.sendAt = exports.CronTime = exports.CronJob = void 0;
const time_1 = require("./time");
var job_1 = require("./job");
Object.defineProperty(exports, "CronJob", { enumerable: true, get: function () { return job_1.CronJob; } });
var time_2 = require("./time");
Object.defineProperty(exports, "CronTime", { enumerable: true, get: function () { return time_2.CronTime; } });
const sendAt = (cronTime) => new time_1.CronTime(cronTime).sendAt();
exports.sendAt = sendAt;
const timeout = (cronTime) => new time_1.CronTime(cronTime).getTimeout();
exports.timeout = timeout;
exports.validateCronExpression = time_1.CronTime.validateCronExpression;

View File

@@ -0,0 +1,34 @@
import { CronTime } from './time';
import { CronCallback, CronContext, CronJobParams, CronOnCompleteCallback, CronOnCompleteCommand, WithOnComplete } from './types/cron.types';
export declare class CronJob<OC extends CronOnCompleteCommand | null = null, C = null> {
cronTime: CronTime;
unrefTimeout: boolean;
lastExecution: Date | null;
runOnce: boolean;
context: CronContext<C>;
onComplete?: WithOnComplete<OC> extends true ? CronOnCompleteCallback : undefined;
waitForCompletion: boolean;
errorHandler?: CronJobParams<OC, C>['errorHandler'];
name?: string;
threshold: number;
private _isActive;
private _isCallbackRunning;
private _timeout?;
private _callbacks;
get isActive(): boolean;
get isCallbackRunning(): boolean;
constructor(cronTime: CronJobParams<OC, C>['cronTime'], onTick: CronJobParams<OC, C>['onTick'], onComplete?: CronJobParams<OC, C>['onComplete'], start?: CronJobParams<OC, C>['start'], timeZone?: CronJobParams<OC, C>['timeZone'], context?: CronJobParams<OC, C>['context'], runOnInit?: CronJobParams<OC, C>['runOnInit'], utcOffset?: null, unrefTimeout?: CronJobParams<OC, C>['unrefTimeout'], waitForCompletion?: CronJobParams<OC, C>['waitForCompletion'], errorHandler?: CronJobParams<OC, C>['errorHandler'], name?: CronJobParams<OC, C>['name'], threshold?: CronJobParams<OC, C>['threshold']);
constructor(cronTime: CronJobParams<OC, C>['cronTime'], onTick: CronJobParams<OC, C>['onTick'], onComplete?: CronJobParams<OC, C>['onComplete'], start?: CronJobParams<OC, C>['start'], timeZone?: null, context?: CronJobParams<OC, C>['context'], runOnInit?: CronJobParams<OC, C>['runOnInit'], utcOffset?: CronJobParams<OC, C>['utcOffset'], unrefTimeout?: CronJobParams<OC, C>['unrefTimeout'], waitForCompletion?: CronJobParams<OC, C>['waitForCompletion'], errorHandler?: CronJobParams<OC, C>['errorHandler'], name?: CronJobParams<OC, C>['name'], threshold?: CronJobParams<OC, C>['threshold']);
static from<OC extends CronOnCompleteCommand | null = null, C = null>(params: CronJobParams<OC, C>): CronJob<OC, C>;
private _fnWrap;
addCallback(callback: CronCallback<C, WithOnComplete<OC>>): void;
setTime(time: CronTime): void;
nextDate(): import("luxon").DateTime<boolean>;
fireOnTick(): Promise<void>;
nextDates(i?: number): import("luxon").DateTime<boolean>[];
start(): void;
lastDate(): Date | null;
private _executeOnComplete;
private _waitForJobCompletion;
stop(): Promise<void> | undefined;
}

View File

@@ -0,0 +1,246 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.CronJob = void 0;
const child_process_1 = require("child_process");
const errors_1 = require("./errors");
const time_1 = require("./time");
class CronJob {
get isActive() {
return this._isActive;
}
get isCallbackRunning() {
return this._isCallbackRunning;
}
constructor(cronTime, onTick, onComplete, start, timeZone, context, runOnInit, utcOffset, unrefTimeout, waitForCompletion, errorHandler, name, threshold) {
this.unrefTimeout = false;
this.lastExecution = null;
this.runOnce = false;
this.waitForCompletion = false;
this.threshold = 250;
this._isActive = false;
this._isCallbackRunning = false;
this._callbacks = [];
this.context = (context !== null && context !== void 0 ? context : this);
this.waitForCompletion = Boolean(waitForCompletion);
this.errorHandler = errorHandler;
if (timeZone != null && utcOffset != null) {
throw new errors_1.ExclusiveParametersError('timeZone', 'utcOffset');
}
if (timeZone != null) {
this.cronTime = new time_1.CronTime(cronTime, timeZone, null);
}
else if (utcOffset != null) {
this.cronTime = new time_1.CronTime(cronTime, null, utcOffset);
}
else {
this.cronTime = new time_1.CronTime(cronTime, timeZone, utcOffset);
}
if (unrefTimeout != null) {
this.unrefTimeout = unrefTimeout;
}
if (onComplete != null) {
this.onComplete = this._fnWrap(onComplete);
}
if (threshold != null) {
this.threshold = Math.abs(threshold);
}
if (name != null) {
this.name = name;
}
if (this.cronTime.realDate) {
this.runOnce = true;
}
this.addCallback(this._fnWrap(onTick));
if (runOnInit) {
this.lastExecution = new Date();
void this.fireOnTick();
}
if (start)
this.start();
}
static from(params) {
if (params.timeZone != null && params.utcOffset != null) {
throw new errors_1.ExclusiveParametersError('timeZone', 'utcOffset');
}
if (params.timeZone != null) {
return new CronJob(params.cronTime, params.onTick, params.onComplete, params.start, params.timeZone, params.context, params.runOnInit, params.utcOffset, params.unrefTimeout, params.waitForCompletion, params.errorHandler, params.name, params.threshold);
}
else if (params.utcOffset != null) {
return new CronJob(params.cronTime, params.onTick, params.onComplete, params.start, null, params.context, params.runOnInit, params.utcOffset, params.unrefTimeout, params.waitForCompletion, params.errorHandler, params.name, params.threshold);
}
else {
return new CronJob(params.cronTime, params.onTick, params.onComplete, params.start, params.timeZone, params.context, params.runOnInit, params.utcOffset, params.unrefTimeout, params.waitForCompletion, params.errorHandler, params.name, params.threshold);
}
}
_fnWrap(cmd) {
var _a, _b;
switch (typeof cmd) {
case 'function': {
return cmd;
}
case 'string': {
const [command, ...args] = cmd.split(' ');
return child_process_1.spawn.bind(undefined, command !== null && command !== void 0 ? command : cmd, args, {});
}
case 'object': {
return child_process_1.spawn.bind(undefined, cmd.command, (_a = cmd.args) !== null && _a !== void 0 ? _a : [], (_b = cmd.options) !== null && _b !== void 0 ? _b : {});
}
}
}
addCallback(callback) {
if (typeof callback === 'function') {
this._callbacks.push(callback);
}
}
setTime(time) {
if (!(time instanceof time_1.CronTime)) {
throw new errors_1.CronError('time must be an instance of CronTime.');
}
const wasRunning = this._isActive;
this.stop();
this.cronTime = time;
if (time.realDate)
this.runOnce = true;
if (wasRunning)
this.start();
}
nextDate() {
return this.cronTime.sendAt();
}
fireOnTick() {
return __awaiter(this, void 0, void 0, function* () {
if (this.waitForCompletion && this._isCallbackRunning)
return;
this._isCallbackRunning = true;
try {
for (const callback of this._callbacks) {
const result = callback.call(this.context, this.onComplete);
if (this.waitForCompletion)
yield result;
}
}
catch (error) {
if (this.errorHandler != null)
this.errorHandler(error);
else
console.error('[Cron] error in callback', error);
}
finally {
this._isCallbackRunning = false;
}
});
}
nextDates(i) {
return this.cronTime.sendAt(i !== null && i !== void 0 ? i : 0);
}
start() {
if (this._isActive)
return;
this._isActive = true;
const MAXDELAY = 2147483647;
let timeout = this.cronTime.getTimeout();
let remaining = 0;
let startTime;
const setCronTimeout = (t) => {
startTime = Date.now();
this._timeout = setTimeout(callbackWrapper, t);
if (this.unrefTimeout && typeof this._timeout.unref === 'function') {
this._timeout.unref();
}
};
const callbackWrapper = () => {
const diff = startTime + timeout - Date.now();
if (diff > 0) {
let newTimeout = this.cronTime.getTimeout();
if (newTimeout > diff) {
newTimeout = diff;
}
remaining += newTimeout;
}
if (remaining) {
if (remaining > MAXDELAY) {
remaining -= MAXDELAY;
timeout = MAXDELAY;
}
else {
timeout = remaining;
remaining = 0;
}
setCronTimeout(timeout);
}
else {
this.lastExecution = new Date();
this._isActive = false;
if (!this.runOnce)
this.start();
void this.fireOnTick();
}
};
if (timeout >= 0) {
if (timeout > MAXDELAY) {
remaining = timeout - MAXDELAY;
timeout = MAXDELAY;
}
setCronTimeout(timeout);
}
else {
const absoluteTimeout = Math.abs(timeout);
const message = `[Cron] Missed execution deadline by ${absoluteTimeout}ms for job${this.name ? ` "${this.name}"` : ''} with cron expression '${String(this.cronTime.source)}'`;
if (absoluteTimeout <= this.threshold) {
console.warn(`${message}. Executing immediately.`);
this.lastExecution = new Date();
void this.fireOnTick();
}
else {
console.warn(`${message}. Skipping execution as it exceeds threshold (${this.threshold}ms).`);
}
timeout = this.cronTime.getTimeout();
setCronTimeout(timeout);
}
}
lastDate() {
return this.lastExecution;
}
_executeOnComplete() {
return __awaiter(this, void 0, void 0, function* () {
if (typeof this.onComplete !== 'function')
return;
try {
yield this.onComplete.call(this.context);
}
catch (error) {
console.error('[Cron] error in onComplete callback:', error);
}
});
}
_waitForJobCompletion() {
return __awaiter(this, void 0, void 0, function* () {
while (this._isCallbackRunning) {
yield new Promise(resolve => setTimeout(resolve, 100));
}
});
}
stop() {
if (this._timeout)
clearTimeout(this._timeout);
this._isActive = false;
if (!this.waitForCompletion) {
void this._executeOnComplete();
return;
}
return Promise.resolve().then(() => __awaiter(this, void 0, void 0, function* () {
yield this._waitForJobCompletion();
yield this._executeOnComplete();
}));
}
}
exports.CronJob = CronJob;

View File

@@ -0,0 +1,40 @@
import { DateTime, Zone } from 'luxon';
import { CronError } from './errors';
import { CronJobParams } from './types/cron.types';
type CustomZone = Zone & {
zoneName?: string;
fixed?: string;
};
type CustomDateTime = Omit<DateTime, 'zone'> & {
zone: CustomZone;
};
export declare class CronTime {
source: string | DateTime;
timeZone?: string;
utcOffset?: number;
realDate: boolean;
private second;
private minute;
private hour;
private dayOfMonth;
private month;
private dayOfWeek;
constructor(source: CronJobParams['cronTime'], timeZone?: CronJobParams['timeZone'], utcOffset?: null);
constructor(source: CronJobParams['cronTime'], timeZone?: null, utcOffset?: CronJobParams['utcOffset']);
static validateCronExpression(cronExpression: string): {
valid: boolean;
error?: CronError;
};
private _getWeekDay;
sendAt(): DateTime;
sendAt(i: number): DateTime[];
getTimeout(): number;
toString(): string;
toJSON(): string[];
getNextDateFrom(start: Date | CustomDateTime, timeZone?: string | CustomZone): DateTime;
private _wcOrAll;
private _hasAll;
private _parse;
private _parseField;
}
export {};

View File

@@ -0,0 +1,310 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CronTime = void 0;
const luxon_1 = require("luxon");
const constants_1 = require("./constants");
const errors_1 = require("./errors");
class CronTime {
constructor(source, timeZone, utcOffset) {
this.realDate = false;
this.second = {};
this.minute = {};
this.hour = {};
this.dayOfMonth = {};
this.month = {};
this.dayOfWeek = {};
if (timeZone != null && utcOffset != null) {
throw new errors_1.ExclusiveParametersError('timeZone', 'utcOffset');
}
if (timeZone) {
const dt = luxon_1.DateTime.fromObject({}, { zone: timeZone });
if (!dt.isValid) {
throw new errors_1.CronError('Invalid timezone.');
}
this.timeZone = timeZone;
}
if (utcOffset != null) {
this.utcOffset = utcOffset;
}
if (timeZone == null && utcOffset == null) {
const systemTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
this.timeZone = systemTimezone;
}
if (source instanceof Date || source instanceof luxon_1.DateTime) {
this.source =
source instanceof Date ? luxon_1.DateTime.fromJSDate(source) : source;
this.realDate = true;
}
else {
this.source = source;
this._parse(this.source);
}
}
static validateCronExpression(cronExpression) {
try {
new CronTime(cronExpression);
return {
valid: true
};
}
catch (error) {
return {
valid: false,
error
};
}
}
_getWeekDay(date) {
return date.weekday === 7 ? 0 : date.weekday;
}
sendAt(i) {
let date = this.realDate && this.source instanceof luxon_1.DateTime
? this.source
: luxon_1.DateTime.utc();
if (this.timeZone) {
date = date.setZone(this.timeZone);
}
if (this.utcOffset !== undefined) {
const sign = this.utcOffset < 0 ? '-' : '+';
const offsetHours = Math.trunc(this.utcOffset / 60);
const offsetHoursStr = String(Math.abs(offsetHours)).padStart(2, '0');
const offsetMins = Math.abs(this.utcOffset - offsetHours * 60);
const offsetMinsStr = String(offsetMins).padStart(2, '0');
const utcZone = `UTC${sign}${offsetHoursStr}:${offsetMinsStr}`;
date = date.setZone(utcZone);
if (!date.isValid) {
throw new errors_1.CronError('ERROR: You specified an invalid UTC offset.');
}
}
if (this.realDate) {
if (luxon_1.DateTime.local() > date) {
throw new errors_1.CronError('WARNING: Date in past. Will never be fired.');
}
return date;
}
if (i === undefined || isNaN(i) || i < 0) {
const nextDate = this.getNextDateFrom(date);
return nextDate;
}
else {
const dates = [];
for (; i > 0; i--) {
date = this.getNextDateFrom(date);
dates.push(date);
}
return dates;
}
}
getTimeout() {
return this.sendAt().toMillis() - luxon_1.DateTime.local().toMillis();
}
toString() {
return this.toJSON().join(' ');
}
toJSON() {
return constants_1.TIME_UNITS.map(unit => {
return this._wcOrAll(unit);
});
}
getNextDateFrom(start, timeZone) {
var _a, _b;
if (start instanceof Date) {
start = luxon_1.DateTime.fromJSDate(start);
}
if (timeZone) {
start = start.setZone(timeZone);
}
else {
timeZone = (_a = start.zone.zoneName) !== null && _a !== void 0 ? _a : start.zone.fixed;
}
let date = luxon_1.DateTime.fromFormat(`${start.year}-${start.month}-${start.day} ${start.hour}:${start.minute}:${start.second}`, 'yyyy-M-d H:m:s', {
zone: 'UTC'
});
const firstDate = date.toMillis();
if (!this.realDate) {
if (date.millisecond > 0) {
date = date.set({ millisecond: 0, second: date.second + 1 });
}
}
if (!date.isValid) {
throw new errors_1.CronError('ERROR: You specified an invalid date.');
}
const maxMatch = luxon_1.DateTime.now().plus({ years: 8 });
while (true) {
if (date > maxMatch) {
throw new errors_1.CronError(`Something went wrong. No execution date was found in the next 8 years.
Please provide the following string if you would like to help debug:
Time Zone: ${(_b = timeZone === null || timeZone === void 0 ? void 0 : timeZone.toString()) !== null && _b !== void 0 ? _b : '""'} - Cron String: ${this.source.toString()} - UTC offset: ${date.offset} - current Date: ${luxon_1.DateTime.local().toString()}`);
}
if (!(date.month in this.month) &&
Object.keys(this.month).length !== 12) {
date = date.plus({ month: 1 });
date = date.set({ day: 1, hour: 0, minute: 0, second: 0 });
continue;
}
if ((!(date.day in this.dayOfMonth) &&
Object.keys(this.dayOfMonth).length !== 31 &&
!(this._getWeekDay(date) in this.dayOfWeek &&
Object.keys(this.dayOfWeek).length !== 7)) ||
(!(this._getWeekDay(date) in this.dayOfWeek) &&
Object.keys(this.dayOfWeek).length !== 7 &&
!(date.day in this.dayOfMonth &&
Object.keys(this.dayOfMonth).length !== 31))) {
date = date.plus({ days: 1 });
date = date.set({ hour: 0, minute: 0, second: 0 });
continue;
}
if (!(date.hour in this.hour) && Object.keys(this.hour).length !== 24) {
date = date.plus({ hour: 1 });
date = date.set({ minute: 0, second: 0 });
continue;
}
if (!(date.minute in this.minute) &&
Object.keys(this.minute).length !== 60) {
date = date.plus({ minute: 1 });
date = date.set({ second: 0 });
continue;
}
if (date.toMillis() === firstDate ||
(!(date.second in this.second) &&
Object.keys(this.second).length !== 60)) {
date = date.plus({ second: 1 });
continue;
}
break;
}
const expectedHour = date.hour;
const expectedMinute = date.minute;
date = luxon_1.DateTime.fromFormat(`${date.year}-${date.month}-${date.day} ${date.hour}:${date.minute}:${date.second}`, 'yyyy-M-d H:m:s', {
zone: timeZone
});
const nonDSTReferenceDate = luxon_1.DateTime.fromFormat(`${date.year}-1-1 0:0:0`, 'yyyy-M-d H:m:s', { zone: timeZone });
if ((expectedHour !== date.hour || expectedMinute !== date.minute) &&
nonDSTReferenceDate.offset !== date.offset) {
while (date.minus({ minute: 1 }).offset !== nonDSTReferenceDate.offset) {
date = date.minus({ minute: 1 });
}
return date;
}
const hourTestDate = date.minus({ hour: 1 });
const twoHourTestDate = date.minus({ hour: 2 });
if ((hourTestDate.hour === date.hour ||
twoHourTestDate.hour === hourTestDate.hour) &&
hourTestDate > start) {
date = hourTestDate;
}
const halfHourTestDate = date.minus({ minute: 30 });
if ((halfHourTestDate.minute === date.minute ||
hourTestDate.minute === halfHourTestDate.minute) &&
halfHourTestDate > start) {
date = halfHourTestDate;
}
return date;
}
_wcOrAll(unit) {
if (this._hasAll(unit)) {
return '*';
}
const all = [];
for (const time in this[unit]) {
all.push(time);
}
return all.join(',');
}
_hasAll(unit) {
const constraints = constants_1.CONSTRAINTS[unit];
const low = constraints[0];
const high = unit === constants_1.TIME_UNITS_MAP.DAY_OF_WEEK ? constraints[1] - 1 : constraints[1];
for (let i = low, n = high; i < n; i++) {
if (!(i in this[unit])) {
return false;
}
}
return true;
}
_parse(source) {
var _a;
source = source.toLowerCase();
if (Object.keys(constants_1.PRESETS).includes(source)) {
source = constants_1.PRESETS[source];
}
source = source.replace(/[a-z]{1,3}/gi, (alias) => {
if (Object.keys(constants_1.ALIASES).includes(alias)) {
return constants_1.ALIASES[alias].toString();
}
throw new errors_1.CronError(`Unknown alias: ${alias}`);
});
const units = source.trim().split(/\s+/);
if (units.length < constants_1.TIME_UNITS_LEN - 1) {
throw new errors_1.CronError('Too few fields');
}
if (units.length > constants_1.TIME_UNITS_LEN) {
throw new errors_1.CronError('Too many fields');
}
const unitsLen = units.length;
for (const unit of constants_1.TIME_UNITS) {
const i = constants_1.TIME_UNITS.indexOf(unit);
const cur = (_a = units[i - (constants_1.TIME_UNITS_LEN - unitsLen)]) !== null && _a !== void 0 ? _a : constants_1.PARSE_DEFAULTS[unit];
this._parseField(cur, unit);
}
}
_parseField(value, unit) {
const typeObj = this[unit];
let pointer;
const constraints = constants_1.CONSTRAINTS[unit];
const low = constraints[0];
const high = constraints[1];
const fields = value.split(',');
fields.forEach(field => {
const wildcardIndex = field.indexOf('*');
if (wildcardIndex !== -1 && wildcardIndex !== 0) {
throw new errors_1.CronError(`Field (${field}) has an invalid wildcard expression`);
}
});
value = value.replace(constants_1.RE_WILDCARDS, `${low}-${high}`);
const allRanges = value.split(',');
for (const range of allRanges) {
const match = [...range.matchAll(constants_1.RE_RANGE)][0];
if ((match === null || match === void 0 ? void 0 : match[1]) !== undefined) {
const [, mLower, mUpper, mStep] = match;
let lower = parseInt(mLower, 10);
let upper = mUpper !== undefined ? parseInt(mUpper, 10) : undefined;
const wasStepDefined = mStep !== undefined;
const step = parseInt(mStep !== null && mStep !== void 0 ? mStep : '1', 10);
if (step === 0) {
throw new errors_1.CronError(`Field (${unit}) has a step of zero`);
}
if (upper !== undefined && lower > upper) {
throw new errors_1.CronError(`Field (${unit}) has an invalid range`);
}
const isOutOfRange = lower < low ||
(upper !== undefined && upper > high) ||
(upper === undefined && lower > high);
if (isOutOfRange) {
throw new errors_1.CronError(`Field value (${value}) is out of range`);
}
lower = Math.min(Math.max(low, ~~Math.abs(lower)), high);
if (upper !== undefined) {
upper = Math.min(high, ~~Math.abs(upper));
}
else {
upper = wasStepDefined ? high : lower;
}
pointer = lower;
do {
typeObj[pointer] = true;
pointer += step;
} while (pointer <= upper);
if (unit === 'dayOfWeek') {
if (!typeObj[0] && !!typeObj[7])
typeObj[0] = typeObj[7];
delete typeObj[7];
}
}
else {
throw new errors_1.CronError(`Field (${unit}) cannot be parsed`);
}
}
}
}
exports.CronTime = CronTime;

View File

@@ -0,0 +1,53 @@
import { SpawnOptions } from 'child_process';
import { DateTime } from 'luxon';
import { CONSTRAINTS, TIME_UNITS_MAP } from '../constants';
import { CronJob } from '../job';
import { IntRange } from './utils';
interface BaseCronJobParams<OC extends CronOnCompleteCommand | null = null, C = null> {
cronTime: string | Date | DateTime;
onTick: CronCommand<C, WithOnComplete<OC>>;
onComplete?: OC;
start?: boolean | null;
context?: C;
runOnInit?: boolean | null;
unrefTimeout?: boolean | null;
waitForCompletion?: boolean | null;
errorHandler?: ((error: unknown) => void) | null;
threshold?: number | null;
name?: string | null;
}
export type CronJobParams<OC extends CronOnCompleteCommand | null = null, C = null> = BaseCronJobParams<OC, C> & ({
timeZone?: string | null;
utcOffset?: never;
} | {
timeZone?: never;
utcOffset?: number | null;
});
export type CronContext<C> = C extends null ? CronJob : NonNullable<C>;
export type CronCallback<C, WithOnCompleteBool extends boolean = false> = (this: CronContext<C>, onComplete: WithOnCompleteBool extends true ? CronOnCompleteCallback : never) => void | Promise<void>;
export type CronOnCompleteCallback = () => void | Promise<void>;
export type CronSystemCommand = string | {
command: string;
args?: readonly string[] | null;
options?: SpawnOptions | null;
};
export type CronCommand<C, WithOnCompleteBool extends boolean = false> = CronCallback<C, WithOnCompleteBool> | CronSystemCommand;
export type CronOnCompleteCommand = CronOnCompleteCallback | CronSystemCommand;
export type WithOnComplete<OC> = OC extends null ? false : true;
export type TimeUnit = (typeof TIME_UNITS_MAP)[keyof typeof TIME_UNITS_MAP];
export type TimeUnitField<T extends TimeUnit> = Partial<Record<Ranges[T], boolean>>;
export interface Ranges {
second: SecondRange;
minute: MinuteRange;
hour: HourRange;
dayOfMonth: DayOfMonthRange;
month: MonthRange;
dayOfWeek: DayOfWeekRange;
}
export type SecondRange = IntRange<(typeof CONSTRAINTS)['second'][0], (typeof CONSTRAINTS)['second'][1]>;
export type MinuteRange = IntRange<(typeof CONSTRAINTS)['minute'][0], (typeof CONSTRAINTS)['minute'][1]>;
export type HourRange = IntRange<(typeof CONSTRAINTS)['hour'][0], (typeof CONSTRAINTS)['hour'][1]>;
export type DayOfMonthRange = IntRange<(typeof CONSTRAINTS)['dayOfMonth'][0], (typeof CONSTRAINTS)['dayOfMonth'][1]>;
export type MonthRange = IntRange<(typeof CONSTRAINTS)['month'][0], (typeof CONSTRAINTS)['month'][1]>;
export type DayOfWeekRange = IntRange<(typeof CONSTRAINTS)['dayOfWeek'][0], (typeof CONSTRAINTS)['dayOfWeek'][1]>;
export {};

View File

@@ -0,0 +1,2 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });

View File

@@ -0,0 +1,3 @@
export type IntRange<F extends number, T extends number> = Exclude<Enumerate<T>, Enumerate<F, false>>;
type Enumerate<N extends number, WithTail extends boolean = true, Acc extends number[] = []> = Acc['length'] extends N ? WithTail extends true ? [...Acc, Acc['length']][number] : Acc[number] : Enumerate<N, WithTail, [...Acc, Acc['length']]>;
export {};

View File

@@ -0,0 +1,2 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });

View File

@@ -0,0 +1,2 @@
import { Ranges } from './types/cron.types';
export declare const getRecordKeys: <K extends Ranges[keyof Ranges]>(record: Partial<Record<K, boolean>>) => (keyof typeof record)[];

View File

@@ -0,0 +1,7 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getRecordKeys = void 0;
const getRecordKeys = (record) => {
return Object.keys(record);
};
exports.getRecordKeys = getRecordKeys;