richie-cron 0.1.2 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/cjs/index.cjs +3 -3
- package/dist/cjs/index.cjs.map +2 -2
- package/dist/cjs/package.json +1 -1
- package/dist/cjs/src/CronExpression.cjs.map +1 -1
- package/dist/cjs/src/CronExpressionParser.cjs +2 -2
- package/dist/cjs/src/CronExpressionParser.cjs.map +3 -3
- package/dist/cjs/src/CronFieldCollection.cjs +2 -2
- package/dist/cjs/src/CronFieldCollection.cjs.map +3 -3
- package/dist/cjs/src/fields/CronDayOfMonth.cjs.map +2 -2
- package/dist/cjs/src/fields/CronDayOfWeek.cjs.map +2 -2
- package/dist/cjs/src/fields/CronField.cjs.map +1 -1
- package/dist/cjs/src/fields/CronHour.cjs.map +2 -2
- package/dist/cjs/src/fields/CronMinute.cjs.map +2 -2
- package/dist/cjs/src/fields/CronMonth.cjs.map +2 -2
- package/dist/cjs/src/fields/CronSecond.cjs.map +2 -2
- package/dist/cjs/src/index.cjs +2 -2
- package/dist/cjs/src/index.cjs.map +2 -2
- package/dist/mjs/index.mjs +3 -3
- package/dist/mjs/index.mjs.map +2 -2
- package/dist/mjs/package.json +1 -1
- package/dist/mjs/src/CronExpression.mjs.map +1 -1
- package/dist/mjs/src/CronExpressionParser.mjs +2 -2
- package/dist/mjs/src/CronExpressionParser.mjs.map +3 -3
- package/dist/mjs/src/CronFieldCollection.mjs +2 -2
- package/dist/mjs/src/CronFieldCollection.mjs.map +3 -3
- package/dist/mjs/src/fields/CronDayOfMonth.mjs.map +2 -2
- package/dist/mjs/src/fields/CronDayOfWeek.mjs.map +2 -2
- package/dist/mjs/src/fields/CronField.mjs.map +1 -1
- package/dist/mjs/src/fields/CronHour.mjs.map +2 -2
- package/dist/mjs/src/fields/CronMinute.mjs.map +2 -2
- package/dist/mjs/src/fields/CronMonth.mjs.map +2 -2
- package/dist/mjs/src/fields/CronSecond.mjs.map +2 -2
- package/dist/mjs/src/index.mjs +2 -2
- package/dist/mjs/src/index.mjs.map +2 -2
- package/dist/types/index.d.ts +2 -2
- package/dist/types/src/CronFieldCollection.d.ts +3 -2
- package/dist/types/src/fields/CronDayOfMonth.d.ts +3 -2
- package/dist/types/src/fields/CronDayOfWeek.d.ts +3 -2
- package/dist/types/src/fields/CronField.d.ts +1 -1
- package/dist/types/src/fields/CronHour.d.ts +3 -2
- package/dist/types/src/fields/CronMinute.d.ts +3 -2
- package/dist/types/src/fields/CronMonth.d.ts +3 -2
- package/dist/types/src/fields/CronSecond.d.ts +3 -2
- package/package.json +1 -1
package/README.md
CHANGED
package/dist/cjs/index.cjs
CHANGED
|
@@ -62,7 +62,7 @@ __export(exports_richie_cron, {
|
|
|
62
62
|
default: () => import_src.default
|
|
63
63
|
});
|
|
64
64
|
module.exports = __toCommonJS(exports_richie_cron);
|
|
65
|
-
__reExport(exports_richie_cron, require("./src.cjs"), module.exports);
|
|
66
|
-
var import_src = __toESM(require("./src.cjs"));
|
|
65
|
+
__reExport(exports_richie_cron, require("./src/index.cjs"), module.exports);
|
|
66
|
+
var import_src = __toESM(require("./src/index.cjs"));
|
|
67
67
|
|
|
68
|
-
//# debugId=
|
|
68
|
+
//# debugId=7DBF88BF945BA38D64756E2164756E21
|
package/dist/cjs/index.cjs.map
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../index.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"export * from './src.cjs';\nexport { default } from './src.cjs';\n"
|
|
5
|
+
"export * from './src/index.cjs';\nexport { default } from './src/index.cjs';\n"
|
|
6
6
|
],
|
|
7
7
|
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AACwB,IAAxB;",
|
|
8
|
-
"debugId": "
|
|
8
|
+
"debugId": "7DBF88BF945BA38D64756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|
package/dist/cjs/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/CronExpression.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"import { CronDate, DateMathOp, TimeUnit } from './CronDate.cjs';\nimport { CronFieldCollection } from './CronFieldCollection.cjs';\nimport { CronFieldType, HourRange, MonthRange, SixtyRange } from './fields.cjs';\n\nexport type CronExpressionOptions = {\n currentDate?: Date | string | number | CronDate;\n endDate?: Date | string | number | CronDate;\n startDate?: Date | string | number | CronDate;\n tz?: string;\n expression?: string;\n hashSeed?: string;\n strict?: boolean;\n};\n\n/**\n * Error message for when the current date is outside the specified time span.\n */\nexport const TIME_SPAN_OUT_OF_BOUNDS_ERROR_MESSAGE = 'Out of the time span range';\n\n/**\n * Error message for when the loop limit is exceeded during iteration.\n */\nexport const LOOPS_LIMIT_EXCEEDED_ERROR_MESSAGE = 'Invalid expression, loop limit exceeded';\n\n/**\n * Cron iteration loop safety limit\n */\nconst LOOP_LIMIT = 10000;\n\n/**\n * Class representing a Cron expression.\n */\nexport class CronExpression {\n #options: CronExpressionOptions & { tz: string };\n readonly #tz: string;\n #currentDate: CronDate;\n readonly #startDate: CronDate | null;\n readonly #endDate: CronDate | null;\n readonly #fields: CronFieldCollection;\n #dstTransitionDayKey: string | null = null;\n #isDstTransitionDay = false;\n\n /**\n * Creates a new CronExpression instance.\n *\n * @param {CronFieldCollection} fields - Cron fields.\n * @param {CronExpressionOptions} options - Parser options.\n */\n constructor(fields: CronFieldCollection, options: CronExpressionOptions) {\n this.#options = {\n ...options,\n tz: options.tz ?? 'UTC',\n };\n this.#tz = this.#options.tz;\n this.#startDate = options.startDate ? new CronDate(options.startDate, this.#tz) : null;\n this.#endDate = options.endDate ? new CronDate(options.endDate, this.#tz) : null;\n\n let currentDateValue = options.currentDate ?? options.startDate;\n if (currentDateValue) {\n const tempCurrentDate = new CronDate(currentDateValue, this.#tz);\n if (this.#startDate && tempCurrentDate.getTime() < this.#startDate.getTime()) {\n currentDateValue = this.#startDate;\n } else if (this.#endDate && tempCurrentDate.getTime() > this.#endDate.getTime()) {\n currentDateValue = this.#endDate;\n }\n }\n\n this.#currentDate = new CronDate(currentDateValue, this.#tz);\n this.#fields = fields;\n }\n\n /**\n * Getter for the cron fields.\n *\n * @returns {CronFieldCollection} Cron fields.\n */\n get fields(): CronFieldCollection {\n return this.#fields;\n }\n\n /**\n * Converts cron fields back to a CronExpression instance.\n *\n * @public\n * @param {Record<string, number[]>} fields - The input cron fields object.\n * @param {CronExpressionOptions} [options] - Optional parsing options.\n * @returns {CronExpression} - A new CronExpression instance.\n */\n static fieldsToExpression(fields: CronFieldCollection, options?: CronExpressionOptions): CronExpression {\n return new CronExpression(fields, options || {});\n }\n\n /**\n * Checks if the given value matches any element in the sequence.\n *\n * @param {number} value - The value to be matched.\n * @param {number[]} sequence - The sequence to be checked against.\n * @returns {boolean} - True if the value matches an element in the sequence; otherwise, false.\n * @memberof CronExpression\n * @private\n */\n static #matchSchedule(value: number, sequence: CronFieldType): boolean {\n return sequence.some((element) => element === value);\n }\n\n /**\n * Returns the minimum or maximum value from the given array of numbers.\n *\n * @param {number[]} values - An array of numbers.\n * @param {boolean} reverse - If true, returns the maximum value; otherwise, returns the minimum value.\n * @returns {number} - The minimum or maximum value.\n */\n #getMinOrMax(values: number[], reverse: boolean): number {\n return values[reverse ? values.length - 1 : 0];\n }\n\n /**\n * Checks whether the given date falls on a DST transition day in its timezone.\n *\n * This is used to disable certain “direct set” fast paths on DST days, because setting the hour\n * directly may land on a non-existent or repeated local time. We cache the result per calendar day\n * to keep iteration overhead low.\n *\n * @param {CronDate} currentDate - Date to check (in the cron timezone)\n * @returns {boolean} True when the day has a DST transition\n * @private\n */\n #checkDstTransition(currentDate: CronDate): boolean {\n // Cache per calendar day (in the cron date's timezone) to avoid repeated work inside the iteration loop.\n const key = `${currentDate.getFullYear()}-${currentDate.getMonth() + 1}-${currentDate.getDate()}`;\n if (this.#dstTransitionDayKey === key) {\n return this.#isDstTransitionDay;\n }\n\n const startOfDay = new CronDate(currentDate);\n startOfDay.setStartOfDay();\n\n const endOfDay = new CronDate(currentDate);\n endOfDay.setEndOfDay();\n\n this.#dstTransitionDayKey = key;\n this.#isDstTransitionDay = startOfDay.getUTCOffset() !== endOfDay.getUTCOffset();\n return this.#isDstTransitionDay;\n }\n\n /**\n * Moves the date to the next/previous allowed second value. If there is no remaining allowed second\n * within the current minute, rolls to the next/previous minute and resets seconds to the min/max allowed.\n *\n * @param {CronDate} currentDate - Mutable date being iterated\n * @param {DateMathOp} dateMathVerb - Add/Subtract depending on direction\n * @param {boolean} reverse - When true, iterating backwards\n * @private\n */\n #moveToNextSecond(currentDate: CronDate, dateMathVerb: DateMathOp, reverse: boolean): void {\n const seconds = this.#fields.second.values as number[];\n const currentSecond = currentDate.getSeconds();\n const nextSecond = this.#fields.second.findNearestValue(currentSecond, reverse);\n\n if (nextSecond !== null) {\n currentDate.setSeconds(nextSecond);\n return;\n }\n\n // Roll over to the next/previous minute and start from the min/max allowed second.\n currentDate.applyDateOperation(dateMathVerb, TimeUnit.Minute, this.#fields.hour.values.length);\n currentDate.setSeconds(this.#getMinOrMax(seconds, reverse));\n }\n\n /**\n * Moves the date to the next/previous allowed minute value and resets seconds to the min/max allowed.\n * If there is no remaining allowed minute within the current hour, rolls to the next/previous hour and\n * resets minutes/seconds to their extrema.\n *\n * @param {CronDate} currentDate - Mutable date being iterated\n * @param {DateMathOp} dateMathVerb - Add/Subtract depending on direction\n * @param {boolean} reverse - When true, iterating backwards\n * @private\n */\n #moveToNextMinute(currentDate: CronDate, dateMathVerb: DateMathOp, reverse: boolean): void {\n const minutes = this.#fields.minute.values as number[];\n const seconds = this.#fields.second.values as number[];\n\n const currentMinute = currentDate.getMinutes();\n const nextMinute = this.#fields.minute.findNearestValue(currentMinute, reverse);\n\n if (nextMinute !== null) {\n currentDate.setMinutes(nextMinute);\n currentDate.setSeconds(this.#getMinOrMax(seconds, reverse));\n return;\n }\n\n // Roll over to the next/previous hour and start from the min/max allowed minute/second.\n currentDate.applyDateOperation(dateMathVerb, TimeUnit.Hour, this.#fields.hour.values.length);\n currentDate.setMinutes(this.#getMinOrMax(minutes, reverse));\n currentDate.setSeconds(this.#getMinOrMax(seconds, reverse));\n }\n\n /**\n * Determines if the current date matches the last specified weekday of the month.\n *\n * @param {Array<(number|string)>} expressions - An array of expressions containing weekdays and \"L\" for the last weekday.\n * @param {CronDate} currentDate - The current date object.\n * @returns {boolean} - True if the current date matches the last specified weekday of the month; otherwise, false.\n * @memberof CronExpression\n * @private\n */\n static #isLastWeekdayOfMonthMatch(expressions: (number | string)[], currentDate: CronDate): boolean {\n const isLastWeekdayOfMonth = currentDate.isLastWeekdayOfMonth();\n return expressions.some((expression: number | string) => {\n // The first character represents the weekday\n const weekday = parseInt(expression.toString().charAt(0), 10) % 7;\n if (Number.isNaN(weekday)) {\n throw new Error(`Invalid last weekday of the month expression: ${expression}`);\n }\n\n // Check if the current date matches the last specified weekday of the month\n return currentDate.getDay() === weekday && isLastWeekdayOfMonth;\n });\n }\n\n /**\n * Find the next scheduled date based on the cron expression.\n * @returns {CronDate} - The next scheduled date or an ES6 compatible iterator object.\n * @memberof CronExpression\n * @public\n */\n next(): CronDate {\n return this.#findSchedule();\n }\n\n /**\n * Find the previous scheduled date based on the cron expression.\n * @returns {CronDate} - The previous scheduled date or an ES6 compatible iterator object.\n * @memberof CronExpression\n * @public\n */\n prev(): CronDate {\n return this.#findSchedule(true);\n }\n\n /**\n * Check if there is a next scheduled date based on the current date and cron expression.\n * @returns {boolean} - Returns true if there is a next scheduled date, false otherwise.\n * @memberof CronExpression\n * @public\n */\n hasNext(): boolean {\n const current = this.#currentDate;\n\n try {\n this.#findSchedule();\n return true;\n } catch {\n return false;\n } finally {\n this.#currentDate = current;\n }\n }\n\n /**\n * Check if there is a previous scheduled date based on the current date and cron expression.\n * @returns {boolean} - Returns true if there is a previous scheduled date, false otherwise.\n * @memberof CronExpression\n * @public\n */\n hasPrev(): boolean {\n const current = this.#currentDate;\n\n try {\n this.#findSchedule(true);\n return true;\n } catch {\n return false;\n } finally {\n this.#currentDate = current;\n }\n }\n\n /**\n * Iterate over a specified number of steps and optionally execute a callback function for each step.\n * @param {number} steps - The number of steps to iterate. Positive value iterates forward, negative value iterates backward.\n * @returns {CronDate[]} - An array of iterator fields or CronDate objects.\n * @memberof CronExpression\n * @public\n */\n take(limit: number): CronDate[] {\n const items: CronDate[] = [];\n if (limit >= 0) {\n for (let i = 0; i < limit; i++) {\n try {\n items.push(this.next());\n } catch {\n return items;\n }\n }\n } else {\n for (let i = 0; i > limit; i--) {\n try {\n items.push(this.prev());\n } catch {\n return items;\n }\n }\n }\n return items;\n }\n\n /**\n * Reset the iterators current date to a new date or the initial date.\n * @param {Date | CronDate} [newDate] - Optional new date to reset to. If not provided, it will reset to the initial date.\n * @memberof CronExpression\n * @public\n */\n reset(newDate?: Date | CronDate): void {\n this.#currentDate = new CronDate(newDate || this.#options.currentDate, this.#tz);\n }\n\n /**\n * Generate a string representation of the cron expression.\n * @param {boolean} [includeSeconds=false] - Whether to include the seconds field in the string representation.\n * @returns {string} - The string representation of the cron expression.\n * @memberof CronExpression\n * @public\n */\n stringify(includeSeconds = false) {\n return this.#fields.stringify(includeSeconds);\n }\n\n /**\n * Check if the cron expression includes the given date\n * @param {Date|CronDate} date\n * @returns {boolean}\n */\n includesDate(date: Date | CronDate): boolean {\n const { second, minute, hour, month } = this.#fields;\n const dt = new CronDate(date, this.#tz);\n\n // Check basic time fields first\n if (\n !second.values.includes(<SixtyRange>dt.getSeconds()) ||\n !minute.values.includes(<SixtyRange>dt.getMinutes()) ||\n !hour.values.includes(<HourRange>dt.getHours()) ||\n !month.values.includes(<MonthRange>(dt.getMonth() + 1))\n ) {\n return false;\n }\n\n // Check day of month and day of week using the same logic as #findSchedule\n if (!this.#matchDayOfMonth(dt)) {\n return false;\n }\n\n // Check nth day of week if specified\n if (this.#fields.dayOfWeek.nthDay > 0) {\n const weekInMonth = Math.ceil(dt.getDate() / 7);\n if (weekInMonth !== this.#fields.dayOfWeek.nthDay) {\n return false;\n }\n }\n return true;\n }\n\n /**\n * Returns the string representation of the cron expression.\n * @returns {CronDate} - The next schedule date.\n */\n toString(): string {\n /* istanbul ignore next - should be impossible under normal use to trigger the or branch */\n return this.#options.expression || this.stringify(true);\n }\n\n /**\n * Determines if the given date matches the cron expression's day of month and day of week fields.\n *\n * The function checks the following rules:\n * Rule 1: If both \"day of month\" and \"day of week\" are restricted (not wildcard), then one or both must match the current day.\n * Rule 2: If \"day of month\" is restricted and \"day of week\" is not restricted, then \"day of month\" must match the current day.\n * Rule 3: If \"day of month\" is a wildcard, \"day of week\" is not a wildcard, and \"day of week\" matches the current day, then the match is accepted.\n * If none of the rules match, the match is rejected.\n *\n * @param {CronDate} currentDate - The current date to be evaluated against the cron expression.\n * @returns {boolean} Returns true if the current date matches the cron expression's day of month and day of week fields, otherwise false.\n * @memberof CronExpression\n * @private\n */\n #matchDayOfMonth(currentDate: CronDate): boolean {\n // Check if day of month and day of week fields are wildcards or restricted (not wildcard).\n const isDayOfMonthWildcardMatch = this.#fields.dayOfMonth.isWildcard;\n const isRestrictedDayOfMonth = !isDayOfMonthWildcardMatch;\n const isDayOfWeekWildcardMatch = this.#fields.dayOfWeek.isWildcard;\n const isRestrictedDayOfWeek = !isDayOfWeekWildcardMatch;\n\n // Calculate if the current date matches the day of month and day of week fields.\n const matchedDOM =\n CronExpression.#matchSchedule(currentDate.getDate(), this.#fields.dayOfMonth.values) ||\n (this.#fields.dayOfMonth.hasLastChar && currentDate.isLastDayOfMonth());\n const matchedDOW =\n CronExpression.#matchSchedule(currentDate.getDay(), this.#fields.dayOfWeek.values) ||\n (this.#fields.dayOfWeek.hasLastChar &&\n CronExpression.#isLastWeekdayOfMonthMatch(this.#fields.dayOfWeek.values, currentDate));\n\n // Rule 1: Both \"day of month\" and \"day of week\" are restricted; one or both must match the current day.\n if (isRestrictedDayOfMonth && isRestrictedDayOfWeek && (matchedDOM || matchedDOW)) {\n return true;\n }\n\n // Rule 2: \"day of month\" restricted and \"day of week\" not restricted; \"day of month\" must match the current day.\n if (matchedDOM && !isRestrictedDayOfWeek) {\n return true;\n }\n\n // Rule 3: \"day of month\" is a wildcard, \"day of week\" is not a wildcard, and \"day of week\" matches the current day.\n if (isDayOfMonthWildcardMatch && !isDayOfWeekWildcardMatch && matchedDOW) {\n return true;\n }\n\n // If none of the rules match, the match is rejected.\n return false;\n }\n\n /**\n * Determines if the current hour matches the cron expression.\n *\n * @param {CronDate} currentDate - The current date object.\n * @param {DateMathOp} dateMathVerb - The date math operation enumeration value.\n * @param {boolean} reverse - A flag indicating whether the matching should be done in reverse order.\n * @returns {boolean} - True if the current hour matches the cron expression; otherwise, false.\n */\n #matchHour(currentDate: CronDate, dateMathVerb: DateMathOp, reverse: boolean): boolean {\n const hourValues = this.#fields.hour.values;\n const hours = hourValues as number[];\n\n const currentHour = currentDate.getHours();\n const isMatch = CronExpression.#matchSchedule(currentHour, hourValues);\n const isDstStart = currentDate.dstStart === currentHour;\n const isDstEnd = currentDate.dstEnd === currentHour;\n\n // DST start: if the scheduled hour is skipped (e.g. 03:00 doesn't exist),\n // accept the next existing hour when it corresponds to the skipped one.\n if (isDstStart) {\n if (CronExpression.#matchSchedule(currentHour - 1, hourValues)) {\n return true;\n }\n currentDate.invokeDateOperation(dateMathVerb, TimeUnit.Hour);\n return false;\n }\n\n // DST end: avoid returning the repeated hour twice when searching forward.\n if (isDstEnd && !reverse) {\n currentDate.dstEnd = null;\n currentDate.applyDateOperation(DateMathOp.Add, TimeUnit.Hour, hours.length);\n return false;\n }\n\n if (isMatch) {\n return true;\n }\n\n // Normal mismatch: if there's no remaining matching hour in this day, jump a whole day first\n // to avoid scanning hour-by-hour across the day boundary.\n currentDate.dstStart = null;\n const nextHour = this.#fields.hour.findNearestValue(currentHour, reverse);\n if (nextHour === null) {\n currentDate.applyDateOperation(dateMathVerb, TimeUnit.Day, hours.length);\n return false;\n }\n // Fast path: jump directly to the next/previous matching hour and reset lower units.\n //\n // On DST transition days, setting the hour directly can land on a non-existent/repeated local time,\n // which breaks the existing DST handling that relies on `applyDateOperation()` to set `dstStart/dstEnd`.\n // For those days, fall back to stepping hour-by-hour to preserve correctness.\n if (this.#checkDstTransition(currentDate)) {\n const steps = reverse ? currentHour - nextHour : nextHour - currentHour;\n for (let i = 0; i < steps; i++) {\n currentDate.applyDateOperation(dateMathVerb, TimeUnit.Hour, hours.length);\n }\n } else {\n currentDate.setHours(nextHour);\n }\n currentDate.setMinutes(this.#getMinOrMax(this.#fields.minute.values as number[], reverse));\n currentDate.setSeconds(this.#getMinOrMax(this.#fields.second.values as number[], reverse));\n return false;\n }\n\n /**\n * Validates the current date against the start and end dates of the cron expression.\n * If the current date is outside the specified time span, an error is thrown.\n *\n * @param currentDate {CronDate} - The current date to validate.\n * @throws {Error} If the current date is outside the specified time span.\n * @private\n */\n #validateTimeSpan(currentDate: CronDate): void {\n if (!this.#startDate && !this.#endDate) {\n return;\n }\n\n const currentTime = currentDate.getTime();\n if (this.#startDate && currentTime < this.#startDate.getTime()) {\n throw new Error(TIME_SPAN_OUT_OF_BOUNDS_ERROR_MESSAGE);\n }\n if (this.#endDate && currentTime > this.#endDate.getTime()) {\n throw new Error(TIME_SPAN_OUT_OF_BOUNDS_ERROR_MESSAGE);\n }\n }\n\n /**\n * Finds the next or previous schedule based on the cron expression.\n *\n * @param {boolean} [reverse=false] - If true, finds the previous schedule; otherwise, finds the next schedule.\n * @returns {CronDate} - The next or previous schedule date.\n * @private\n */\n #findSchedule(reverse = false): CronDate {\n const dateMathVerb: DateMathOp = reverse ? DateMathOp.Subtract : DateMathOp.Add;\n const currentDate = new CronDate(this.#currentDate);\n const startTimestamp = currentDate.getTime();\n let stepCount = 0;\n\n while (++stepCount < LOOP_LIMIT) {\n this.#validateTimeSpan(currentDate);\n\n if (!this.#matchDayOfMonth(currentDate)) {\n currentDate.applyDateOperation(dateMathVerb, TimeUnit.Day, this.#fields.hour.values.length);\n continue;\n }\n if (\n !(this.#fields.dayOfWeek.nthDay <= 0 || Math.ceil(currentDate.getDate() / 7) === this.#fields.dayOfWeek.nthDay)\n ) {\n currentDate.applyDateOperation(dateMathVerb, TimeUnit.Day, this.#fields.hour.values.length);\n continue;\n }\n if (!CronExpression.#matchSchedule(currentDate.getMonth() + 1, this.#fields.month.values)) {\n currentDate.applyDateOperation(dateMathVerb, TimeUnit.Month, this.#fields.hour.values.length);\n continue;\n }\n if (!this.#matchHour(currentDate, dateMathVerb, reverse)) {\n continue;\n }\n if (!CronExpression.#matchSchedule(currentDate.getMinutes(), this.#fields.minute.values)) {\n this.#moveToNextMinute(currentDate, dateMathVerb, reverse);\n continue;\n }\n if (!CronExpression.#matchSchedule(currentDate.getSeconds(), this.#fields.second.values)) {\n this.#moveToNextSecond(currentDate, dateMathVerb, reverse);\n continue;\n }\n\n if (startTimestamp === currentDate.getTime()) {\n if (dateMathVerb === 'Add' || currentDate.getMilliseconds() === 0) {\n currentDate.applyDateOperation(dateMathVerb, TimeUnit.Second, this.#fields.hour.values.length);\n }\n continue;\n }\n break;\n }\n\n /* istanbul ignore next - should be impossible under normal use to trigger the branch */\n if (stepCount > LOOP_LIMIT) {\n throw new Error(LOOPS_LIMIT_EXCEEDED_ERROR_MESSAGE);\n }\n\n if (currentDate.getMilliseconds() !== 0) {\n currentDate.setMilliseconds(0);\n }\n this.#currentDate = currentDate;\n return currentDate;\n }\n\n /**\n * Returns an iterator for iterating through future CronDate instances\n *\n * @name Symbol.iterator\n * @memberof CronExpression\n * @returns {Iterator<CronDate>} An iterator object for CronExpression that returns CronDate values.\n */\n [Symbol.iterator](): Iterator<CronDate> {\n return {\n next: () => {\n try {\n const schedule = this.#findSchedule();\n return { value: schedule, done: false };\n } catch {\n return { value: undefined as any, done: true };\n }\n },\n };\n }\n}\n\nexport default CronExpression;\n"
|
|
5
|
+
"import { CronDate, DateMathOp, TimeUnit } from './CronDate.cjs';\nimport { CronFieldCollection } from './CronFieldCollection.cjs';\nimport type { CronFieldType, HourRange, MonthRange, SixtyRange } from './fields/index.cjs';\n\nexport type CronExpressionOptions = {\n currentDate?: Date | string | number | CronDate;\n endDate?: Date | string | number | CronDate;\n startDate?: Date | string | number | CronDate;\n tz?: string;\n expression?: string;\n hashSeed?: string;\n strict?: boolean;\n};\n\n/**\n * Error message for when the current date is outside the specified time span.\n */\nexport const TIME_SPAN_OUT_OF_BOUNDS_ERROR_MESSAGE = 'Out of the time span range';\n\n/**\n * Error message for when the loop limit is exceeded during iteration.\n */\nexport const LOOPS_LIMIT_EXCEEDED_ERROR_MESSAGE = 'Invalid expression, loop limit exceeded';\n\n/**\n * Cron iteration loop safety limit\n */\nconst LOOP_LIMIT = 10000;\n\n/**\n * Class representing a Cron expression.\n */\nexport class CronExpression {\n #options: CronExpressionOptions & { tz: string };\n readonly #tz: string;\n #currentDate: CronDate;\n readonly #startDate: CronDate | null;\n readonly #endDate: CronDate | null;\n readonly #fields: CronFieldCollection;\n #dstTransitionDayKey: string | null = null;\n #isDstTransitionDay = false;\n\n /**\n * Creates a new CronExpression instance.\n *\n * @param {CronFieldCollection} fields - Cron fields.\n * @param {CronExpressionOptions} options - Parser options.\n */\n constructor(fields: CronFieldCollection, options: CronExpressionOptions) {\n this.#options = {\n ...options,\n tz: options.tz ?? 'UTC',\n };\n this.#tz = this.#options.tz;\n this.#startDate = options.startDate ? new CronDate(options.startDate, this.#tz) : null;\n this.#endDate = options.endDate ? new CronDate(options.endDate, this.#tz) : null;\n\n let currentDateValue = options.currentDate ?? options.startDate;\n if (currentDateValue) {\n const tempCurrentDate = new CronDate(currentDateValue, this.#tz);\n if (this.#startDate && tempCurrentDate.getTime() < this.#startDate.getTime()) {\n currentDateValue = this.#startDate;\n } else if (this.#endDate && tempCurrentDate.getTime() > this.#endDate.getTime()) {\n currentDateValue = this.#endDate;\n }\n }\n\n this.#currentDate = new CronDate(currentDateValue, this.#tz);\n this.#fields = fields;\n }\n\n /**\n * Getter for the cron fields.\n *\n * @returns {CronFieldCollection} Cron fields.\n */\n get fields(): CronFieldCollection {\n return this.#fields;\n }\n\n /**\n * Converts cron fields back to a CronExpression instance.\n *\n * @public\n * @param {Record<string, number[]>} fields - The input cron fields object.\n * @param {CronExpressionOptions} [options] - Optional parsing options.\n * @returns {CronExpression} - A new CronExpression instance.\n */\n static fieldsToExpression(fields: CronFieldCollection, options?: CronExpressionOptions): CronExpression {\n return new CronExpression(fields, options || {});\n }\n\n /**\n * Checks if the given value matches any element in the sequence.\n *\n * @param {number} value - The value to be matched.\n * @param {number[]} sequence - The sequence to be checked against.\n * @returns {boolean} - True if the value matches an element in the sequence; otherwise, false.\n * @memberof CronExpression\n * @private\n */\n static #matchSchedule(value: number, sequence: CronFieldType): boolean {\n return sequence.some((element) => element === value);\n }\n\n /**\n * Returns the minimum or maximum value from the given array of numbers.\n *\n * @param {number[]} values - An array of numbers.\n * @param {boolean} reverse - If true, returns the maximum value; otherwise, returns the minimum value.\n * @returns {number} - The minimum or maximum value.\n */\n #getMinOrMax(values: number[], reverse: boolean): number {\n return values[reverse ? values.length - 1 : 0];\n }\n\n /**\n * Checks whether the given date falls on a DST transition day in its timezone.\n *\n * This is used to disable certain “direct set” fast paths on DST days, because setting the hour\n * directly may land on a non-existent or repeated local time. We cache the result per calendar day\n * to keep iteration overhead low.\n *\n * @param {CronDate} currentDate - Date to check (in the cron timezone)\n * @returns {boolean} True when the day has a DST transition\n * @private\n */\n #checkDstTransition(currentDate: CronDate): boolean {\n // Cache per calendar day (in the cron date's timezone) to avoid repeated work inside the iteration loop.\n const key = `${currentDate.getFullYear()}-${currentDate.getMonth() + 1}-${currentDate.getDate()}`;\n if (this.#dstTransitionDayKey === key) {\n return this.#isDstTransitionDay;\n }\n\n const startOfDay = new CronDate(currentDate);\n startOfDay.setStartOfDay();\n\n const endOfDay = new CronDate(currentDate);\n endOfDay.setEndOfDay();\n\n this.#dstTransitionDayKey = key;\n this.#isDstTransitionDay = startOfDay.getUTCOffset() !== endOfDay.getUTCOffset();\n return this.#isDstTransitionDay;\n }\n\n /**\n * Moves the date to the next/previous allowed second value. If there is no remaining allowed second\n * within the current minute, rolls to the next/previous minute and resets seconds to the min/max allowed.\n *\n * @param {CronDate} currentDate - Mutable date being iterated\n * @param {DateMathOp} dateMathVerb - Add/Subtract depending on direction\n * @param {boolean} reverse - When true, iterating backwards\n * @private\n */\n #moveToNextSecond(currentDate: CronDate, dateMathVerb: DateMathOp, reverse: boolean): void {\n const seconds = this.#fields.second.values as number[];\n const currentSecond = currentDate.getSeconds();\n const nextSecond = this.#fields.second.findNearestValue(currentSecond, reverse);\n\n if (nextSecond !== null) {\n currentDate.setSeconds(nextSecond);\n return;\n }\n\n // Roll over to the next/previous minute and start from the min/max allowed second.\n currentDate.applyDateOperation(dateMathVerb, TimeUnit.Minute, this.#fields.hour.values.length);\n currentDate.setSeconds(this.#getMinOrMax(seconds, reverse));\n }\n\n /**\n * Moves the date to the next/previous allowed minute value and resets seconds to the min/max allowed.\n * If there is no remaining allowed minute within the current hour, rolls to the next/previous hour and\n * resets minutes/seconds to their extrema.\n *\n * @param {CronDate} currentDate - Mutable date being iterated\n * @param {DateMathOp} dateMathVerb - Add/Subtract depending on direction\n * @param {boolean} reverse - When true, iterating backwards\n * @private\n */\n #moveToNextMinute(currentDate: CronDate, dateMathVerb: DateMathOp, reverse: boolean): void {\n const minutes = this.#fields.minute.values as number[];\n const seconds = this.#fields.second.values as number[];\n\n const currentMinute = currentDate.getMinutes();\n const nextMinute = this.#fields.minute.findNearestValue(currentMinute, reverse);\n\n if (nextMinute !== null) {\n currentDate.setMinutes(nextMinute);\n currentDate.setSeconds(this.#getMinOrMax(seconds, reverse));\n return;\n }\n\n // Roll over to the next/previous hour and start from the min/max allowed minute/second.\n currentDate.applyDateOperation(dateMathVerb, TimeUnit.Hour, this.#fields.hour.values.length);\n currentDate.setMinutes(this.#getMinOrMax(minutes, reverse));\n currentDate.setSeconds(this.#getMinOrMax(seconds, reverse));\n }\n\n /**\n * Determines if the current date matches the last specified weekday of the month.\n *\n * @param {Array<(number|string)>} expressions - An array of expressions containing weekdays and \"L\" for the last weekday.\n * @param {CronDate} currentDate - The current date object.\n * @returns {boolean} - True if the current date matches the last specified weekday of the month; otherwise, false.\n * @memberof CronExpression\n * @private\n */\n static #isLastWeekdayOfMonthMatch(expressions: (number | string)[], currentDate: CronDate): boolean {\n const isLastWeekdayOfMonth = currentDate.isLastWeekdayOfMonth();\n return expressions.some((expression: number | string) => {\n // The first character represents the weekday\n const weekday = parseInt(expression.toString().charAt(0), 10) % 7;\n if (Number.isNaN(weekday)) {\n throw new Error(`Invalid last weekday of the month expression: ${expression}`);\n }\n\n // Check if the current date matches the last specified weekday of the month\n return currentDate.getDay() === weekday && isLastWeekdayOfMonth;\n });\n }\n\n /**\n * Find the next scheduled date based on the cron expression.\n * @returns {CronDate} - The next scheduled date or an ES6 compatible iterator object.\n * @memberof CronExpression\n * @public\n */\n next(): CronDate {\n return this.#findSchedule();\n }\n\n /**\n * Find the previous scheduled date based on the cron expression.\n * @returns {CronDate} - The previous scheduled date or an ES6 compatible iterator object.\n * @memberof CronExpression\n * @public\n */\n prev(): CronDate {\n return this.#findSchedule(true);\n }\n\n /**\n * Check if there is a next scheduled date based on the current date and cron expression.\n * @returns {boolean} - Returns true if there is a next scheduled date, false otherwise.\n * @memberof CronExpression\n * @public\n */\n hasNext(): boolean {\n const current = this.#currentDate;\n\n try {\n this.#findSchedule();\n return true;\n } catch {\n return false;\n } finally {\n this.#currentDate = current;\n }\n }\n\n /**\n * Check if there is a previous scheduled date based on the current date and cron expression.\n * @returns {boolean} - Returns true if there is a previous scheduled date, false otherwise.\n * @memberof CronExpression\n * @public\n */\n hasPrev(): boolean {\n const current = this.#currentDate;\n\n try {\n this.#findSchedule(true);\n return true;\n } catch {\n return false;\n } finally {\n this.#currentDate = current;\n }\n }\n\n /**\n * Iterate over a specified number of steps and optionally execute a callback function for each step.\n * @param {number} steps - The number of steps to iterate. Positive value iterates forward, negative value iterates backward.\n * @returns {CronDate[]} - An array of iterator fields or CronDate objects.\n * @memberof CronExpression\n * @public\n */\n take(limit: number): CronDate[] {\n const items: CronDate[] = [];\n if (limit >= 0) {\n for (let i = 0; i < limit; i++) {\n try {\n items.push(this.next());\n } catch {\n return items;\n }\n }\n } else {\n for (let i = 0; i > limit; i--) {\n try {\n items.push(this.prev());\n } catch {\n return items;\n }\n }\n }\n return items;\n }\n\n /**\n * Reset the iterators current date to a new date or the initial date.\n * @param {Date | CronDate} [newDate] - Optional new date to reset to. If not provided, it will reset to the initial date.\n * @memberof CronExpression\n * @public\n */\n reset(newDate?: Date | CronDate): void {\n this.#currentDate = new CronDate(newDate || this.#options.currentDate, this.#tz);\n }\n\n /**\n * Generate a string representation of the cron expression.\n * @param {boolean} [includeSeconds=false] - Whether to include the seconds field in the string representation.\n * @returns {string} - The string representation of the cron expression.\n * @memberof CronExpression\n * @public\n */\n stringify(includeSeconds = false) {\n return this.#fields.stringify(includeSeconds);\n }\n\n /**\n * Check if the cron expression includes the given date\n * @param {Date|CronDate} date\n * @returns {boolean}\n */\n includesDate(date: Date | CronDate): boolean {\n const { second, minute, hour, month } = this.#fields;\n const dt = new CronDate(date, this.#tz);\n\n // Check basic time fields first\n if (\n !second.values.includes(<SixtyRange>dt.getSeconds()) ||\n !minute.values.includes(<SixtyRange>dt.getMinutes()) ||\n !hour.values.includes(<HourRange>dt.getHours()) ||\n !month.values.includes(<MonthRange>(dt.getMonth() + 1))\n ) {\n return false;\n }\n\n // Check day of month and day of week using the same logic as #findSchedule\n if (!this.#matchDayOfMonth(dt)) {\n return false;\n }\n\n // Check nth day of week if specified\n if (this.#fields.dayOfWeek.nthDay > 0) {\n const weekInMonth = Math.ceil(dt.getDate() / 7);\n if (weekInMonth !== this.#fields.dayOfWeek.nthDay) {\n return false;\n }\n }\n return true;\n }\n\n /**\n * Returns the string representation of the cron expression.\n * @returns {CronDate} - The next schedule date.\n */\n toString(): string {\n /* istanbul ignore next - should be impossible under normal use to trigger the or branch */\n return this.#options.expression || this.stringify(true);\n }\n\n /**\n * Determines if the given date matches the cron expression's day of month and day of week fields.\n *\n * The function checks the following rules:\n * Rule 1: If both \"day of month\" and \"day of week\" are restricted (not wildcard), then one or both must match the current day.\n * Rule 2: If \"day of month\" is restricted and \"day of week\" is not restricted, then \"day of month\" must match the current day.\n * Rule 3: If \"day of month\" is a wildcard, \"day of week\" is not a wildcard, and \"day of week\" matches the current day, then the match is accepted.\n * If none of the rules match, the match is rejected.\n *\n * @param {CronDate} currentDate - The current date to be evaluated against the cron expression.\n * @returns {boolean} Returns true if the current date matches the cron expression's day of month and day of week fields, otherwise false.\n * @memberof CronExpression\n * @private\n */\n #matchDayOfMonth(currentDate: CronDate): boolean {\n // Check if day of month and day of week fields are wildcards or restricted (not wildcard).\n const isDayOfMonthWildcardMatch = this.#fields.dayOfMonth.isWildcard;\n const isRestrictedDayOfMonth = !isDayOfMonthWildcardMatch;\n const isDayOfWeekWildcardMatch = this.#fields.dayOfWeek.isWildcard;\n const isRestrictedDayOfWeek = !isDayOfWeekWildcardMatch;\n\n // Calculate if the current date matches the day of month and day of week fields.\n const matchedDOM =\n CronExpression.#matchSchedule(currentDate.getDate(), this.#fields.dayOfMonth.values) ||\n (this.#fields.dayOfMonth.hasLastChar && currentDate.isLastDayOfMonth());\n const matchedDOW =\n CronExpression.#matchSchedule(currentDate.getDay(), this.#fields.dayOfWeek.values) ||\n (this.#fields.dayOfWeek.hasLastChar &&\n CronExpression.#isLastWeekdayOfMonthMatch(this.#fields.dayOfWeek.values, currentDate));\n\n // Rule 1: Both \"day of month\" and \"day of week\" are restricted; one or both must match the current day.\n if (isRestrictedDayOfMonth && isRestrictedDayOfWeek && (matchedDOM || matchedDOW)) {\n return true;\n }\n\n // Rule 2: \"day of month\" restricted and \"day of week\" not restricted; \"day of month\" must match the current day.\n if (matchedDOM && !isRestrictedDayOfWeek) {\n return true;\n }\n\n // Rule 3: \"day of month\" is a wildcard, \"day of week\" is not a wildcard, and \"day of week\" matches the current day.\n if (isDayOfMonthWildcardMatch && !isDayOfWeekWildcardMatch && matchedDOW) {\n return true;\n }\n\n // If none of the rules match, the match is rejected.\n return false;\n }\n\n /**\n * Determines if the current hour matches the cron expression.\n *\n * @param {CronDate} currentDate - The current date object.\n * @param {DateMathOp} dateMathVerb - The date math operation enumeration value.\n * @param {boolean} reverse - A flag indicating whether the matching should be done in reverse order.\n * @returns {boolean} - True if the current hour matches the cron expression; otherwise, false.\n */\n #matchHour(currentDate: CronDate, dateMathVerb: DateMathOp, reverse: boolean): boolean {\n const hourValues = this.#fields.hour.values;\n const hours = hourValues as number[];\n\n const currentHour = currentDate.getHours();\n const isMatch = CronExpression.#matchSchedule(currentHour, hourValues);\n const isDstStart = currentDate.dstStart === currentHour;\n const isDstEnd = currentDate.dstEnd === currentHour;\n\n // DST start: if the scheduled hour is skipped (e.g. 03:00 doesn't exist),\n // accept the next existing hour when it corresponds to the skipped one.\n if (isDstStart) {\n if (CronExpression.#matchSchedule(currentHour - 1, hourValues)) {\n return true;\n }\n currentDate.invokeDateOperation(dateMathVerb, TimeUnit.Hour);\n return false;\n }\n\n // DST end: avoid returning the repeated hour twice when searching forward.\n if (isDstEnd && !reverse) {\n currentDate.dstEnd = null;\n currentDate.applyDateOperation(DateMathOp.Add, TimeUnit.Hour, hours.length);\n return false;\n }\n\n if (isMatch) {\n return true;\n }\n\n // Normal mismatch: if there's no remaining matching hour in this day, jump a whole day first\n // to avoid scanning hour-by-hour across the day boundary.\n currentDate.dstStart = null;\n const nextHour = this.#fields.hour.findNearestValue(currentHour, reverse);\n if (nextHour === null) {\n currentDate.applyDateOperation(dateMathVerb, TimeUnit.Day, hours.length);\n return false;\n }\n // Fast path: jump directly to the next/previous matching hour and reset lower units.\n //\n // On DST transition days, setting the hour directly can land on a non-existent/repeated local time,\n // which breaks the existing DST handling that relies on `applyDateOperation()` to set `dstStart/dstEnd`.\n // For those days, fall back to stepping hour-by-hour to preserve correctness.\n if (this.#checkDstTransition(currentDate)) {\n const steps = reverse ? currentHour - nextHour : nextHour - currentHour;\n for (let i = 0; i < steps; i++) {\n currentDate.applyDateOperation(dateMathVerb, TimeUnit.Hour, hours.length);\n }\n } else {\n currentDate.setHours(nextHour);\n }\n currentDate.setMinutes(this.#getMinOrMax(this.#fields.minute.values as number[], reverse));\n currentDate.setSeconds(this.#getMinOrMax(this.#fields.second.values as number[], reverse));\n return false;\n }\n\n /**\n * Validates the current date against the start and end dates of the cron expression.\n * If the current date is outside the specified time span, an error is thrown.\n *\n * @param currentDate {CronDate} - The current date to validate.\n * @throws {Error} If the current date is outside the specified time span.\n * @private\n */\n #validateTimeSpan(currentDate: CronDate): void {\n if (!this.#startDate && !this.#endDate) {\n return;\n }\n\n const currentTime = currentDate.getTime();\n if (this.#startDate && currentTime < this.#startDate.getTime()) {\n throw new Error(TIME_SPAN_OUT_OF_BOUNDS_ERROR_MESSAGE);\n }\n if (this.#endDate && currentTime > this.#endDate.getTime()) {\n throw new Error(TIME_SPAN_OUT_OF_BOUNDS_ERROR_MESSAGE);\n }\n }\n\n /**\n * Finds the next or previous schedule based on the cron expression.\n *\n * @param {boolean} [reverse=false] - If true, finds the previous schedule; otherwise, finds the next schedule.\n * @returns {CronDate} - The next or previous schedule date.\n * @private\n */\n #findSchedule(reverse = false): CronDate {\n const dateMathVerb: DateMathOp = reverse ? DateMathOp.Subtract : DateMathOp.Add;\n const currentDate = new CronDate(this.#currentDate);\n const startTimestamp = currentDate.getTime();\n let stepCount = 0;\n\n while (++stepCount < LOOP_LIMIT) {\n this.#validateTimeSpan(currentDate);\n\n if (!this.#matchDayOfMonth(currentDate)) {\n currentDate.applyDateOperation(dateMathVerb, TimeUnit.Day, this.#fields.hour.values.length);\n continue;\n }\n if (\n !(this.#fields.dayOfWeek.nthDay <= 0 || Math.ceil(currentDate.getDate() / 7) === this.#fields.dayOfWeek.nthDay)\n ) {\n currentDate.applyDateOperation(dateMathVerb, TimeUnit.Day, this.#fields.hour.values.length);\n continue;\n }\n if (!CronExpression.#matchSchedule(currentDate.getMonth() + 1, this.#fields.month.values)) {\n currentDate.applyDateOperation(dateMathVerb, TimeUnit.Month, this.#fields.hour.values.length);\n continue;\n }\n if (!this.#matchHour(currentDate, dateMathVerb, reverse)) {\n continue;\n }\n if (!CronExpression.#matchSchedule(currentDate.getMinutes(), this.#fields.minute.values)) {\n this.#moveToNextMinute(currentDate, dateMathVerb, reverse);\n continue;\n }\n if (!CronExpression.#matchSchedule(currentDate.getSeconds(), this.#fields.second.values)) {\n this.#moveToNextSecond(currentDate, dateMathVerb, reverse);\n continue;\n }\n\n if (startTimestamp === currentDate.getTime()) {\n if (dateMathVerb === 'Add' || currentDate.getMilliseconds() === 0) {\n currentDate.applyDateOperation(dateMathVerb, TimeUnit.Second, this.#fields.hour.values.length);\n }\n continue;\n }\n break;\n }\n\n /* istanbul ignore next - should be impossible under normal use to trigger the branch */\n if (stepCount > LOOP_LIMIT) {\n throw new Error(LOOPS_LIMIT_EXCEEDED_ERROR_MESSAGE);\n }\n\n if (currentDate.getMilliseconds() !== 0) {\n currentDate.setMilliseconds(0);\n }\n this.#currentDate = currentDate;\n return currentDate;\n }\n\n /**\n * Returns an iterator for iterating through future CronDate instances\n *\n * @name Symbol.iterator\n * @memberof CronExpression\n * @returns {Iterator<CronDate>} An iterator object for CronExpression that returns CronDate values.\n */\n [Symbol.iterator](): Iterator<CronDate> {\n return {\n next: () => {\n try {\n const schedule = this.#findSchedule();\n return { value: schedule, done: false };\n } catch {\n return { value: undefined as any, done: true };\n }\n },\n };\n }\n}\n\nexport default CronExpression;\n"
|
|
6
6
|
],
|
|
7
7
|
"mappings": "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",
|
|
8
8
|
"debugId": "EE6B3C9D2BF080CD64756E2164756E21",
|
|
@@ -39,7 +39,7 @@ module.exports = __toCommonJS(exports_CronExpressionParser);
|
|
|
39
39
|
var import_CronFieldCollection = require("./CronFieldCollection.cjs");
|
|
40
40
|
var import_CronExpression = require("./CronExpression.cjs");
|
|
41
41
|
var import_random = require("./utils/random.cjs");
|
|
42
|
-
var import_fields = require("./fields.cjs");
|
|
42
|
+
var import_fields = require("./fields/index.cjs");
|
|
43
43
|
var PredefinedExpressions;
|
|
44
44
|
((PredefinedExpressions2) => {
|
|
45
45
|
PredefinedExpressions2["@yearly"] = "0 0 0 1 1 *";
|
|
@@ -297,4 +297,4 @@ class CronExpressionParser {
|
|
|
297
297
|
}
|
|
298
298
|
}
|
|
299
299
|
|
|
300
|
-
//# debugId=
|
|
300
|
+
//# debugId=A517E107413A49C064756E2164756E21
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/CronExpressionParser.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"import { CronFieldCollection } from './CronFieldCollection.cjs';\nimport { CronExpression } from './CronExpression.cjs';\nimport type { CronExpressionOptions } from './CronExpression.cjs';\nimport { type PRNG, seededRandom } from './utils/random.cjs';\nimport {\n CronSecond,\n CronMinute,\n CronHour,\n CronMonth,\n CronDayOfMonth,\n CronDayOfWeek,\n CronConstraints,\n DayOfMonthRange,\n DayOfWeekRange,\n HourRange,\n MonthRange,\n ParseRangeResponse,\n SixtyRange,\n} from './fields.cjs';\n\nexport enum PredefinedExpressions {\n '@yearly' = '0 0 0 1 1 *',\n '@annually' = '0 0 0 1 1 *',\n '@monthly' = '0 0 0 1 * *',\n '@weekly' = '0 0 0 * * 0',\n '@daily' = '0 0 0 * * *',\n '@hourly' = '0 0 * * * *',\n '@minutely' = '0 * * * * *',\n '@secondly' = '* * * * * *',\n '@weekdays' = '0 0 0 * * 1-5',\n '@weekends' = '0 0 0 * * 0,6',\n}\n\nexport enum CronUnit {\n Second = 'Second',\n Minute = 'Minute',\n Hour = 'Hour',\n DayOfMonth = 'DayOfMonth',\n Month = 'Month',\n DayOfWeek = 'DayOfWeek',\n}\n\n// these need to be lowercase for the parser to work\nexport enum Months {\n jan = 1,\n feb = 2,\n mar = 3,\n apr = 4,\n may = 5,\n jun = 6,\n jul = 7,\n aug = 8,\n sep = 9,\n oct = 10,\n nov = 11,\n dec = 12,\n}\n\n// these need to be lowercase for the parser to work\nexport enum DayOfWeek {\n sun = 0,\n mon = 1,\n tue = 2,\n wed = 3,\n thu = 4,\n fri = 5,\n sat = 6,\n}\n\nexport type RawCronFields = {\n second: string;\n minute: string;\n hour: string;\n dayOfMonth: string;\n month: string;\n dayOfWeek: string;\n};\n\n/**\n * Static class that parses a cron expression and returns a CronExpression object.\n * @static\n * @class CronExpressionParser\n */\nexport class CronExpressionParser {\n /**\n * Parses a cron expression and returns a CronExpression object.\n * @param {string} expression - The cron expression to parse.\n * @param {CronExpressionOptions} [options={}] - The options to use when parsing the expression.\n * @param {boolean} [options.strict=false] - If true, will throw an error if the expression contains both dayOfMonth and dayOfWeek.\n * @param {CronDate} [options.currentDate=new CronDate(undefined, 'UTC')] - The date to use when calculating the next/previous occurrence.\n *\n * @returns {CronExpression} A CronExpression object.\n */\n static parse(expression: string, options: CronExpressionOptions = {}): CronExpression {\n const { strict = false, hashSeed } = options;\n const rand = seededRandom(hashSeed);\n\n expression = PredefinedExpressions[expression as keyof typeof PredefinedExpressions] || expression;\n const rawFields = CronExpressionParser.#getRawFields(expression, strict);\n if (!(rawFields.dayOfMonth === '*' || rawFields.dayOfWeek === '*' || !strict)) {\n throw new Error('Cannot use both dayOfMonth and dayOfWeek together in strict mode!');\n }\n\n const second = CronExpressionParser.#parseField(\n CronUnit.Second,\n rawFields.second,\n CronSecond.constraints,\n rand,\n ) as SixtyRange[];\n const minute = CronExpressionParser.#parseField(\n CronUnit.Minute,\n rawFields.minute,\n CronMinute.constraints,\n rand,\n ) as SixtyRange[];\n const hour = CronExpressionParser.#parseField(\n CronUnit.Hour,\n rawFields.hour,\n CronHour.constraints,\n rand,\n ) as HourRange[];\n const month = CronExpressionParser.#parseField(\n CronUnit.Month,\n rawFields.month,\n CronMonth.constraints,\n rand,\n ) as MonthRange[];\n const dayOfMonth = CronExpressionParser.#parseField(\n CronUnit.DayOfMonth,\n rawFields.dayOfMonth,\n CronDayOfMonth.constraints,\n rand,\n ) as DayOfMonthRange[];\n const { dayOfWeek: _dayOfWeek, nthDayOfWeek } = CronExpressionParser.#parseNthDay(rawFields.dayOfWeek);\n const dayOfWeek = CronExpressionParser.#parseField(\n CronUnit.DayOfWeek,\n _dayOfWeek,\n CronDayOfWeek.constraints,\n rand,\n ) as DayOfWeekRange[];\n\n const fields = new CronFieldCollection({\n second: new CronSecond(second, { rawValue: rawFields.second }),\n minute: new CronMinute(minute, { rawValue: rawFields.minute }),\n hour: new CronHour(hour, { rawValue: rawFields.hour }),\n dayOfMonth: new CronDayOfMonth(dayOfMonth, { rawValue: rawFields.dayOfMonth }),\n month: new CronMonth(month, { rawValue: rawFields.month }),\n dayOfWeek: new CronDayOfWeek(dayOfWeek, { rawValue: rawFields.dayOfWeek, nthDayOfWeek }),\n });\n return new CronExpression(fields, { ...options, expression });\n }\n\n /**\n * Get the raw fields from a cron expression.\n * @param {string} expression - The cron expression to parse.\n * @param {boolean} strict - If true, will throw an error if the expression contains both dayOfMonth and dayOfWeek.\n * @private\n * @returns {RawCronFields} The raw fields.\n */\n static #getRawFields(expression: string, strict: boolean): RawCronFields {\n if (strict && !expression.length) {\n throw new Error('Invalid cron expression');\n }\n expression = expression || '0 * * * * *';\n const atoms = expression.trim().split(/\\s+/);\n if (strict && atoms.length < 6) {\n throw new Error('Invalid cron expression, expected 6 fields');\n }\n if (atoms.length > 6) {\n throw new Error('Invalid cron expression, too many fields');\n }\n const defaults = ['*', '*', '*', '*', '*', '0'];\n if (atoms.length < defaults.length) {\n atoms.unshift(...defaults.slice(atoms.length));\n }\n const [second, minute, hour, dayOfMonth, month, dayOfWeek] = atoms;\n return { second, minute, hour, dayOfMonth, month, dayOfWeek };\n }\n\n /**\n * Parse a field from a cron expression.\n * @param {CronUnit} field - The field to parse.\n * @param {string} value - The value of the field.\n * @param {CronConstraints} constraints - The constraints for the field.\n * @private\n * @returns {(number | string)[]} The parsed field.\n */\n static #parseField(field: CronUnit, value: string, constraints: CronConstraints, rand: PRNG): (number | string)[] {\n // Replace aliases for month and dayOfWeek\n if (field === CronUnit.Month || field === CronUnit.DayOfWeek) {\n value = value.replace(/[a-z]{3}/gi, (match) => {\n match = match.toLowerCase();\n const replacer = Months[match as keyof typeof Months] || DayOfWeek[match as keyof typeof DayOfWeek];\n if (replacer === undefined) {\n throw new Error(`Validation error, cannot resolve alias \"${match}\"`);\n }\n return replacer.toString();\n });\n }\n\n // Check for valid characters\n if (!constraints.validChars.test(value)) {\n throw new Error(`Invalid characters, got value: ${value}`);\n }\n\n value = this.#parseWildcard(value, constraints);\n value = this.#parseHashed(value, constraints, rand);\n return this.#parseSequence(field, value, constraints);\n }\n\n /**\n * Parse a wildcard from a cron expression.\n * @param {string} value - The value to parse.\n * @param {CronConstraints} constraints - The constraints for the field.\n * @private\n */\n static #parseWildcard(value: string, constraints: CronConstraints): string {\n return value.replace(/[*?]/g, constraints.min + '-' + constraints.max);\n }\n\n /**\n * Parse a hashed value from a cron expression.\n * @param {string} value - The value to parse.\n * @param {CronConstraints} constraints - The constraints for the field.\n * @param {PRNG} rand - The random number generator to use.\n * @private\n */\n static #parseHashed(value: string, constraints: CronConstraints, rand: PRNG): string {\n const randomValue = rand();\n return value.replace(/H(?:\\((\\d+)-(\\d+)\\))?(?:\\/(\\d+))?/g, (_, min, max, step) => {\n // H(range)/step\n if (min && max && step) {\n const minNum = parseInt(min, 10);\n const maxNum = parseInt(max, 10);\n const stepNum = parseInt(step, 10);\n\n if (minNum > maxNum) {\n throw new Error(`Invalid range: ${minNum}-${maxNum}, min > max`);\n }\n if (stepNum <= 0) {\n throw new Error(`Invalid step: ${stepNum}, must be positive`);\n }\n\n const minStart = Math.max(minNum, constraints.min);\n const offset = Math.floor(randomValue * stepNum);\n const values = [];\n for (let i = Math.floor(minStart / stepNum) * stepNum + offset; i <= maxNum; i += stepNum) {\n if (i >= minStart) {\n values.push(i);\n }\n }\n\n return values.join(',');\n }\n // H(range)\n else if (min && max) {\n const minNum = parseInt(min, 10);\n const maxNum = parseInt(max, 10);\n\n if (minNum > maxNum) {\n throw new Error(`Invalid range: ${minNum}-${maxNum}, min > max`);\n }\n return String(Math.floor(randomValue * (maxNum - minNum + 1)) + minNum);\n }\n // H/step\n else if (step) {\n const stepNum = parseInt(step, 10);\n\n // Validate step\n if (stepNum <= 0) {\n throw new Error(`Invalid step: ${stepNum}, must be positive`);\n }\n\n const offset = Math.floor(randomValue * stepNum);\n const values = [];\n for (let i = Math.floor(constraints.min / stepNum) * stepNum + offset; i <= constraints.max; i += stepNum) {\n if (i >= constraints.min) {\n values.push(i);\n }\n }\n\n return values.join(',');\n }\n // H\n else {\n return String(Math.floor(randomValue * (constraints.max - constraints.min + 1) + constraints.min));\n }\n });\n }\n\n /**\n * Parse a sequence from a cron expression.\n * @param {CronUnit} field - The field to parse.\n * @param {string} val - The sequence to parse.\n * @param {CronConstraints} constraints - The constraints for the field.\n * @private\n */\n static #parseSequence(field: CronUnit, val: string, constraints: CronConstraints): (number | string)[] {\n const stack: (number | string)[] = [];\n function handleResult(result: number | string | (number | string)[], constraints: CronConstraints) {\n if (Array.isArray(result)) {\n stack.push(...result);\n } else {\n if (CronExpressionParser.#isValidConstraintChar(constraints, result)) {\n stack.push(result);\n } else {\n const v = parseInt(result.toString(), 10);\n const isValid = v >= constraints.min && v <= constraints.max;\n if (!isValid) {\n throw new Error(\n `Constraint error, got value ${result} expected range ${constraints.min}-${constraints.max}`,\n );\n }\n stack.push(field === CronUnit.DayOfWeek ? v % 7 : result);\n }\n }\n }\n\n const atoms = val.split(',');\n atoms.forEach((atom) => {\n if (!(atom.length > 0)) {\n throw new Error('Invalid list value format');\n }\n handleResult(CronExpressionParser.#parseRepeat(field, atom, constraints), constraints);\n });\n return stack;\n }\n\n /**\n * Parse repeat from a cron expression.\n * @param {CronUnit} field - The field to parse.\n * @param {string} val - The repeat to parse.\n * @param {CronConstraints} constraints - The constraints for the field.\n * @private\n * @returns {(number | string)[]} The parsed repeat.\n */\n static #parseRepeat(field: CronUnit, val: string, constraints: CronConstraints): ParseRangeResponse {\n const atoms = val.split('/');\n if (atoms.length > 2) {\n throw new Error(`Invalid repeat: ${val}`);\n }\n if (atoms.length === 2) {\n if (!atoms[0].includes('-')) {\n atoms[0] = `${atoms[0]}-${constraints.max}`;\n }\n return CronExpressionParser.#parseRange(field, atoms[0], parseInt(atoms[1], 10), constraints);\n }\n\n return CronExpressionParser.#parseRange(field, val, 1, constraints);\n }\n\n /**\n * Validate a cron range.\n * @param {number} min - The minimum value of the range.\n * @param {number} max - The maximum value of the range.\n * @param {CronConstraints} constraints - The constraints for the field.\n * @private\n * @returns {void}\n * @throws {Error} Throws an error if the range is invalid.\n */\n static #validateRange(min: number, max: number, constraints: CronConstraints): void {\n const isValid = !isNaN(min) && !isNaN(max) && min >= constraints.min && max <= constraints.max;\n if (!isValid) {\n throw new Error(`Constraint error, got range ${min}-${max} expected range ${constraints.min}-${constraints.max}`);\n }\n if (min > max) {\n throw new Error(`Invalid range: ${min}-${max}, min(${min}) > max(${max})`);\n }\n }\n\n /**\n * Validate a cron repeat interval.\n * @param {number} repeatInterval - The repeat interval to validate.\n * @private\n * @returns {void}\n * @throws {Error} Throws an error if the repeat interval is invalid.\n */\n static #validateRepeatInterval(repeatInterval: number): void {\n if (!(!isNaN(repeatInterval) && repeatInterval > 0)) {\n throw new Error(`Constraint error, cannot repeat at every ${repeatInterval} time.`);\n }\n }\n\n /**\n * Create a range from a cron expression.\n * @param {CronUnit} field - The field to parse.\n * @param {number} min - The minimum value of the range.\n * @param {number} max - The maximum value of the range.\n * @param {number} repeatInterval - The repeat interval of the range.\n * @private\n * @returns {number[]} The created range.\n */\n static #createRange(field: CronUnit, min: number, max: number, repeatInterval: number): number[] {\n const stack: number[] = [];\n if (field === CronUnit.DayOfWeek && max % 7 === 0) {\n stack.push(0);\n }\n for (let index = min; index <= max; index += repeatInterval) {\n if (stack.indexOf(index) === -1) {\n stack.push(index);\n }\n }\n return stack;\n }\n\n /**\n * Parse a range from a cron expression.\n * @param {CronUnit} field - The field to parse.\n * @param {string} val - The range to parse.\n * @param {number} repeatInterval - The repeat interval of the range.\n * @param {CronConstraints} constraints - The constraints for the field.\n * @private\n * @returns {number[] | string[] | number | string} The parsed range.\n */\n static #parseRange(\n field: CronUnit,\n val: string,\n repeatInterval: number,\n constraints: CronConstraints,\n ): ParseRangeResponse {\n const atoms: string[] = val.split('-');\n if (atoms.length <= 1) {\n return isNaN(+val) ? val : +val;\n }\n const [min, max] = atoms.map((num) => parseInt(num, 10));\n this.#validateRange(min, max, constraints);\n this.#validateRepeatInterval(repeatInterval);\n\n // Create range\n return this.#createRange(field, min, max, repeatInterval);\n }\n\n /**\n * Parse a cron expression.\n * @param {string} val - The cron expression to parse.\n * @private\n * @returns {string} The parsed cron expression.\n */\n static #parseNthDay(val: string): { dayOfWeek: string; nthDayOfWeek?: number } {\n const atoms = val.split('#');\n if (atoms.length <= 1) {\n return { dayOfWeek: atoms[0] };\n }\n const nthValue = +atoms[atoms.length - 1];\n const matches = val.match(/([,-/])/);\n if (matches !== null) {\n throw new Error(\n `Constraint error, invalid dayOfWeek \\`#\\` and \\`${matches?.[0]}\\` special characters are incompatible`,\n );\n }\n if (!(atoms.length <= 2 && !isNaN(nthValue) && nthValue >= 1 && nthValue <= 5)) {\n throw new Error('Constraint error, invalid dayOfWeek occurrence number (#)');\n }\n return { dayOfWeek: atoms[0], nthDayOfWeek: nthValue };\n }\n\n /**\n * Checks if a character is valid for a field.\n * @param {CronConstraints} constraints - The constraints for the field.\n * @param {string | number} value - The value to check.\n * @private\n * @returns {boolean} Whether the character is valid for the field.\n */\n static #isValidConstraintChar(constraints: CronConstraints, value: string | number): boolean {\n return constraints.chars.some((char) => value.toString().includes(char));\n }\n}\n"
|
|
5
|
+
"import { CronFieldCollection } from './CronFieldCollection.cjs';\nimport { CronExpression } from './CronExpression.cjs';\nimport type { CronExpressionOptions } from './CronExpression.cjs';\nimport { type PRNG, seededRandom } from './utils/random.cjs';\nimport {\n CronSecond,\n CronMinute,\n CronHour,\n CronMonth,\n CronDayOfMonth,\n CronDayOfWeek,\n} from './fields/index.cjs';\nimport type {\n CronConstraints,\n DayOfMonthRange,\n DayOfWeekRange,\n HourRange,\n MonthRange,\n ParseRangeResponse,\n SixtyRange,\n} from './fields/index.cjs';\n\nexport enum PredefinedExpressions {\n '@yearly' = '0 0 0 1 1 *',\n '@annually' = '0 0 0 1 1 *',\n '@monthly' = '0 0 0 1 * *',\n '@weekly' = '0 0 0 * * 0',\n '@daily' = '0 0 0 * * *',\n '@hourly' = '0 0 * * * *',\n '@minutely' = '0 * * * * *',\n '@secondly' = '* * * * * *',\n '@weekdays' = '0 0 0 * * 1-5',\n '@weekends' = '0 0 0 * * 0,6',\n}\n\nexport enum CronUnit {\n Second = 'Second',\n Minute = 'Minute',\n Hour = 'Hour',\n DayOfMonth = 'DayOfMonth',\n Month = 'Month',\n DayOfWeek = 'DayOfWeek',\n}\n\n// these need to be lowercase for the parser to work\nexport enum Months {\n jan = 1,\n feb = 2,\n mar = 3,\n apr = 4,\n may = 5,\n jun = 6,\n jul = 7,\n aug = 8,\n sep = 9,\n oct = 10,\n nov = 11,\n dec = 12,\n}\n\n// these need to be lowercase for the parser to work\nexport enum DayOfWeek {\n sun = 0,\n mon = 1,\n tue = 2,\n wed = 3,\n thu = 4,\n fri = 5,\n sat = 6,\n}\n\nexport type RawCronFields = {\n second: string;\n minute: string;\n hour: string;\n dayOfMonth: string;\n month: string;\n dayOfWeek: string;\n};\n\n/**\n * Static class that parses a cron expression and returns a CronExpression object.\n * @static\n * @class CronExpressionParser\n */\nexport class CronExpressionParser {\n /**\n * Parses a cron expression and returns a CronExpression object.\n * @param {string} expression - The cron expression to parse.\n * @param {CronExpressionOptions} [options={}] - The options to use when parsing the expression.\n * @param {boolean} [options.strict=false] - If true, will throw an error if the expression contains both dayOfMonth and dayOfWeek.\n * @param {CronDate} [options.currentDate=new CronDate(undefined, 'UTC')] - The date to use when calculating the next/previous occurrence.\n *\n * @returns {CronExpression} A CronExpression object.\n */\n static parse(expression: string, options: CronExpressionOptions = {}): CronExpression {\n const { strict = false, hashSeed } = options;\n const rand = seededRandom(hashSeed);\n\n expression = PredefinedExpressions[expression as keyof typeof PredefinedExpressions] || expression;\n const rawFields = CronExpressionParser.#getRawFields(expression, strict);\n if (!(rawFields.dayOfMonth === '*' || rawFields.dayOfWeek === '*' || !strict)) {\n throw new Error('Cannot use both dayOfMonth and dayOfWeek together in strict mode!');\n }\n\n const second = CronExpressionParser.#parseField(\n CronUnit.Second,\n rawFields.second,\n CronSecond.constraints,\n rand,\n ) as SixtyRange[];\n const minute = CronExpressionParser.#parseField(\n CronUnit.Minute,\n rawFields.minute,\n CronMinute.constraints,\n rand,\n ) as SixtyRange[];\n const hour = CronExpressionParser.#parseField(\n CronUnit.Hour,\n rawFields.hour,\n CronHour.constraints,\n rand,\n ) as HourRange[];\n const month = CronExpressionParser.#parseField(\n CronUnit.Month,\n rawFields.month,\n CronMonth.constraints,\n rand,\n ) as MonthRange[];\n const dayOfMonth = CronExpressionParser.#parseField(\n CronUnit.DayOfMonth,\n rawFields.dayOfMonth,\n CronDayOfMonth.constraints,\n rand,\n ) as DayOfMonthRange[];\n const { dayOfWeek: _dayOfWeek, nthDayOfWeek } = CronExpressionParser.#parseNthDay(rawFields.dayOfWeek);\n const dayOfWeek = CronExpressionParser.#parseField(\n CronUnit.DayOfWeek,\n _dayOfWeek,\n CronDayOfWeek.constraints,\n rand,\n ) as DayOfWeekRange[];\n\n const fields = new CronFieldCollection({\n second: new CronSecond(second, { rawValue: rawFields.second }),\n minute: new CronMinute(minute, { rawValue: rawFields.minute }),\n hour: new CronHour(hour, { rawValue: rawFields.hour }),\n dayOfMonth: new CronDayOfMonth(dayOfMonth, { rawValue: rawFields.dayOfMonth }),\n month: new CronMonth(month, { rawValue: rawFields.month }),\n dayOfWeek: new CronDayOfWeek(dayOfWeek, { rawValue: rawFields.dayOfWeek, nthDayOfWeek }),\n });\n return new CronExpression(fields, { ...options, expression });\n }\n\n /**\n * Get the raw fields from a cron expression.\n * @param {string} expression - The cron expression to parse.\n * @param {boolean} strict - If true, will throw an error if the expression contains both dayOfMonth and dayOfWeek.\n * @private\n * @returns {RawCronFields} The raw fields.\n */\n static #getRawFields(expression: string, strict: boolean): RawCronFields {\n if (strict && !expression.length) {\n throw new Error('Invalid cron expression');\n }\n expression = expression || '0 * * * * *';\n const atoms = expression.trim().split(/\\s+/);\n if (strict && atoms.length < 6) {\n throw new Error('Invalid cron expression, expected 6 fields');\n }\n if (atoms.length > 6) {\n throw new Error('Invalid cron expression, too many fields');\n }\n const defaults = ['*', '*', '*', '*', '*', '0'];\n if (atoms.length < defaults.length) {\n atoms.unshift(...defaults.slice(atoms.length));\n }\n const [second, minute, hour, dayOfMonth, month, dayOfWeek] = atoms;\n return { second, minute, hour, dayOfMonth, month, dayOfWeek };\n }\n\n /**\n * Parse a field from a cron expression.\n * @param {CronUnit} field - The field to parse.\n * @param {string} value - The value of the field.\n * @param {CronConstraints} constraints - The constraints for the field.\n * @private\n * @returns {(number | string)[]} The parsed field.\n */\n static #parseField(field: CronUnit, value: string, constraints: CronConstraints, rand: PRNG): (number | string)[] {\n // Replace aliases for month and dayOfWeek\n if (field === CronUnit.Month || field === CronUnit.DayOfWeek) {\n value = value.replace(/[a-z]{3}/gi, (match) => {\n match = match.toLowerCase();\n const replacer = Months[match as keyof typeof Months] || DayOfWeek[match as keyof typeof DayOfWeek];\n if (replacer === undefined) {\n throw new Error(`Validation error, cannot resolve alias \"${match}\"`);\n }\n return replacer.toString();\n });\n }\n\n // Check for valid characters\n if (!constraints.validChars.test(value)) {\n throw new Error(`Invalid characters, got value: ${value}`);\n }\n\n value = this.#parseWildcard(value, constraints);\n value = this.#parseHashed(value, constraints, rand);\n return this.#parseSequence(field, value, constraints);\n }\n\n /**\n * Parse a wildcard from a cron expression.\n * @param {string} value - The value to parse.\n * @param {CronConstraints} constraints - The constraints for the field.\n * @private\n */\n static #parseWildcard(value: string, constraints: CronConstraints): string {\n return value.replace(/[*?]/g, constraints.min + '-' + constraints.max);\n }\n\n /**\n * Parse a hashed value from a cron expression.\n * @param {string} value - The value to parse.\n * @param {CronConstraints} constraints - The constraints for the field.\n * @param {PRNG} rand - The random number generator to use.\n * @private\n */\n static #parseHashed(value: string, constraints: CronConstraints, rand: PRNG): string {\n const randomValue = rand();\n return value.replace(/H(?:\\((\\d+)-(\\d+)\\))?(?:\\/(\\d+))?/g, (_, min, max, step) => {\n // H(range)/step\n if (min && max && step) {\n const minNum = parseInt(min, 10);\n const maxNum = parseInt(max, 10);\n const stepNum = parseInt(step, 10);\n\n if (minNum > maxNum) {\n throw new Error(`Invalid range: ${minNum}-${maxNum}, min > max`);\n }\n if (stepNum <= 0) {\n throw new Error(`Invalid step: ${stepNum}, must be positive`);\n }\n\n const minStart = Math.max(minNum, constraints.min);\n const offset = Math.floor(randomValue * stepNum);\n const values = [];\n for (let i = Math.floor(minStart / stepNum) * stepNum + offset; i <= maxNum; i += stepNum) {\n if (i >= minStart) {\n values.push(i);\n }\n }\n\n return values.join(',');\n }\n // H(range)\n else if (min && max) {\n const minNum = parseInt(min, 10);\n const maxNum = parseInt(max, 10);\n\n if (minNum > maxNum) {\n throw new Error(`Invalid range: ${minNum}-${maxNum}, min > max`);\n }\n return String(Math.floor(randomValue * (maxNum - minNum + 1)) + minNum);\n }\n // H/step\n else if (step) {\n const stepNum = parseInt(step, 10);\n\n // Validate step\n if (stepNum <= 0) {\n throw new Error(`Invalid step: ${stepNum}, must be positive`);\n }\n\n const offset = Math.floor(randomValue * stepNum);\n const values = [];\n for (let i = Math.floor(constraints.min / stepNum) * stepNum + offset; i <= constraints.max; i += stepNum) {\n if (i >= constraints.min) {\n values.push(i);\n }\n }\n\n return values.join(',');\n }\n // H\n else {\n return String(Math.floor(randomValue * (constraints.max - constraints.min + 1) + constraints.min));\n }\n });\n }\n\n /**\n * Parse a sequence from a cron expression.\n * @param {CronUnit} field - The field to parse.\n * @param {string} val - The sequence to parse.\n * @param {CronConstraints} constraints - The constraints for the field.\n * @private\n */\n static #parseSequence(field: CronUnit, val: string, constraints: CronConstraints): (number | string)[] {\n const stack: (number | string)[] = [];\n function handleResult(result: number | string | (number | string)[], constraints: CronConstraints) {\n if (Array.isArray(result)) {\n stack.push(...result);\n } else {\n if (CronExpressionParser.#isValidConstraintChar(constraints, result)) {\n stack.push(result);\n } else {\n const v = parseInt(result.toString(), 10);\n const isValid = v >= constraints.min && v <= constraints.max;\n if (!isValid) {\n throw new Error(\n `Constraint error, got value ${result} expected range ${constraints.min}-${constraints.max}`,\n );\n }\n stack.push(field === CronUnit.DayOfWeek ? v % 7 : result);\n }\n }\n }\n\n const atoms = val.split(',');\n atoms.forEach((atom) => {\n if (!(atom.length > 0)) {\n throw new Error('Invalid list value format');\n }\n handleResult(CronExpressionParser.#parseRepeat(field, atom, constraints), constraints);\n });\n return stack;\n }\n\n /**\n * Parse repeat from a cron expression.\n * @param {CronUnit} field - The field to parse.\n * @param {string} val - The repeat to parse.\n * @param {CronConstraints} constraints - The constraints for the field.\n * @private\n * @returns {(number | string)[]} The parsed repeat.\n */\n static #parseRepeat(field: CronUnit, val: string, constraints: CronConstraints): ParseRangeResponse {\n const atoms = val.split('/');\n if (atoms.length > 2) {\n throw new Error(`Invalid repeat: ${val}`);\n }\n if (atoms.length === 2) {\n if (!atoms[0].includes('-')) {\n atoms[0] = `${atoms[0]}-${constraints.max}`;\n }\n return CronExpressionParser.#parseRange(field, atoms[0], parseInt(atoms[1], 10), constraints);\n }\n\n return CronExpressionParser.#parseRange(field, val, 1, constraints);\n }\n\n /**\n * Validate a cron range.\n * @param {number} min - The minimum value of the range.\n * @param {number} max - The maximum value of the range.\n * @param {CronConstraints} constraints - The constraints for the field.\n * @private\n * @returns {void}\n * @throws {Error} Throws an error if the range is invalid.\n */\n static #validateRange(min: number, max: number, constraints: CronConstraints): void {\n const isValid = !isNaN(min) && !isNaN(max) && min >= constraints.min && max <= constraints.max;\n if (!isValid) {\n throw new Error(`Constraint error, got range ${min}-${max} expected range ${constraints.min}-${constraints.max}`);\n }\n if (min > max) {\n throw new Error(`Invalid range: ${min}-${max}, min(${min}) > max(${max})`);\n }\n }\n\n /**\n * Validate a cron repeat interval.\n * @param {number} repeatInterval - The repeat interval to validate.\n * @private\n * @returns {void}\n * @throws {Error} Throws an error if the repeat interval is invalid.\n */\n static #validateRepeatInterval(repeatInterval: number): void {\n if (!(!isNaN(repeatInterval) && repeatInterval > 0)) {\n throw new Error(`Constraint error, cannot repeat at every ${repeatInterval} time.`);\n }\n }\n\n /**\n * Create a range from a cron expression.\n * @param {CronUnit} field - The field to parse.\n * @param {number} min - The minimum value of the range.\n * @param {number} max - The maximum value of the range.\n * @param {number} repeatInterval - The repeat interval of the range.\n * @private\n * @returns {number[]} The created range.\n */\n static #createRange(field: CronUnit, min: number, max: number, repeatInterval: number): number[] {\n const stack: number[] = [];\n if (field === CronUnit.DayOfWeek && max % 7 === 0) {\n stack.push(0);\n }\n for (let index = min; index <= max; index += repeatInterval) {\n if (stack.indexOf(index) === -1) {\n stack.push(index);\n }\n }\n return stack;\n }\n\n /**\n * Parse a range from a cron expression.\n * @param {CronUnit} field - The field to parse.\n * @param {string} val - The range to parse.\n * @param {number} repeatInterval - The repeat interval of the range.\n * @param {CronConstraints} constraints - The constraints for the field.\n * @private\n * @returns {number[] | string[] | number | string} The parsed range.\n */\n static #parseRange(\n field: CronUnit,\n val: string,\n repeatInterval: number,\n constraints: CronConstraints,\n ): ParseRangeResponse {\n const atoms: string[] = val.split('-');\n if (atoms.length <= 1) {\n return isNaN(+val) ? val : +val;\n }\n const [min, max] = atoms.map((num) => parseInt(num, 10));\n this.#validateRange(min, max, constraints);\n this.#validateRepeatInterval(repeatInterval);\n\n // Create range\n return this.#createRange(field, min, max, repeatInterval);\n }\n\n /**\n * Parse a cron expression.\n * @param {string} val - The cron expression to parse.\n * @private\n * @returns {string} The parsed cron expression.\n */\n static #parseNthDay(val: string): { dayOfWeek: string; nthDayOfWeek?: number } {\n const atoms = val.split('#');\n if (atoms.length <= 1) {\n return { dayOfWeek: atoms[0] };\n }\n const nthValue = +atoms[atoms.length - 1];\n const matches = val.match(/([,-/])/);\n if (matches !== null) {\n throw new Error(\n `Constraint error, invalid dayOfWeek \\`#\\` and \\`${matches?.[0]}\\` special characters are incompatible`,\n );\n }\n if (!(atoms.length <= 2 && !isNaN(nthValue) && nthValue >= 1 && nthValue <= 5)) {\n throw new Error('Constraint error, invalid dayOfWeek occurrence number (#)');\n }\n return { dayOfWeek: atoms[0], nthDayOfWeek: nthValue };\n }\n\n /**\n * Checks if a character is valid for a field.\n * @param {CronConstraints} constraints - The constraints for the field.\n * @param {string | number} value - The value to check.\n * @private\n * @returns {boolean} Whether the character is valid for the field.\n */\n static #isValidConstraintChar(constraints: CronConstraints, value: string | number): boolean {\n return constraints.chars.some((char) => value.toString().includes(char));\n }\n}\n"
|
|
6
6
|
],
|
|
7
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAoC,IAApC;AAC+B,IAA/B;AAEwC,IAAxC;
|
|
8
|
-
"debugId": "
|
|
7
|
+
"mappings": "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",
|
|
8
|
+
"debugId": "A517E107413A49C064756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|
|
@@ -32,7 +32,7 @@ __export(exports_CronFieldCollection, {
|
|
|
32
32
|
CronFieldCollection: () => CronFieldCollection
|
|
33
33
|
});
|
|
34
34
|
module.exports = __toCommonJS(exports_CronFieldCollection);
|
|
35
|
-
var import_fields = require("./fields.cjs");
|
|
35
|
+
var import_fields = require("./fields/index.cjs");
|
|
36
36
|
|
|
37
37
|
class CronFieldCollection {
|
|
38
38
|
#second;
|
|
@@ -246,4 +246,4 @@ class CronFieldCollection {
|
|
|
246
246
|
}
|
|
247
247
|
}
|
|
248
248
|
|
|
249
|
-
//# debugId=
|
|
249
|
+
//# debugId=FC40E51090CB9E0B64756E2164756E21
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/CronFieldCollection.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"import {\n CronSecond,\n CronMinute,\n CronHour,\n CronDayOfMonth,\n CronMonth,\n CronDayOfWeek,\n CronField,\n SerializedCronField,\n CronChars,\n} from './fields.cjs';\nimport { SixtyRange, HourRange, DayOfMonthRange, MonthRange, DayOfWeekRange } from './fields/types.cjs';\n\nexport type FieldRange = {\n start: number | CronChars;\n count: number;\n end?: number;\n step?: number;\n};\n\nexport type CronFields = {\n second: CronSecond;\n minute: CronMinute;\n hour: CronHour;\n dayOfMonth: CronDayOfMonth;\n month: CronMonth;\n dayOfWeek: CronDayOfWeek;\n};\n\nexport type CronFieldOverride = {\n second?: CronSecond | SixtyRange[];\n minute?: CronMinute | SixtyRange[];\n hour?: CronHour | HourRange[];\n dayOfMonth?: CronDayOfMonth | DayOfMonthRange[];\n month?: CronMonth | MonthRange[];\n dayOfWeek?: CronDayOfWeek | DayOfWeekRange[];\n};\n\nexport type SerializedCronFields = {\n second: SerializedCronField;\n minute: SerializedCronField;\n hour: SerializedCronField;\n dayOfMonth: SerializedCronField;\n month: SerializedCronField;\n dayOfWeek: SerializedCronField;\n};\n\n/**\n * Represents a complete set of cron fields.\n * @class CronFieldCollection\n */\nexport class CronFieldCollection {\n readonly #second: CronSecond;\n readonly #minute: CronMinute;\n readonly #hour: CronHour;\n readonly #dayOfMonth: CronDayOfMonth;\n readonly #month: CronMonth;\n readonly #dayOfWeek: CronDayOfWeek;\n\n /**\n * Creates a new CronFieldCollection instance by partially overriding fields from an existing one.\n * @param {CronFieldCollection} base - The base CronFieldCollection to copy fields from\n * @param {CronFieldOverride} fields - The fields to override, can be CronField instances or raw values\n * @returns {CronFieldCollection} A new CronFieldCollection instance\n * @example\n * const base = new CronFieldCollection({\n * second: new CronSecond([0]),\n * minute: new CronMinute([0]),\n * hour: new CronHour([12]),\n * dayOfMonth: new CronDayOfMonth([1]),\n * month: new CronMonth([1]),\n * dayOfWeek: new CronDayOfWeek([1])\n * });\n *\n * // Using CronField instances\n * const modified1 = CronFieldCollection.from(base, {\n * hour: new CronHour([15]),\n * minute: new CronMinute([30])\n * });\n *\n * // Using raw values\n * const modified2 = CronFieldCollection.from(base, {\n * hour: [15], // Will create new CronHour\n * minute: [30] // Will create new CronMinute\n * });\n */\n static from(base: CronFieldCollection, fields: CronFieldOverride): CronFieldCollection {\n return new CronFieldCollection({\n second: this.resolveField(CronSecond, base.second, fields.second),\n minute: this.resolveField(CronMinute, base.minute, fields.minute),\n hour: this.resolveField(CronHour, base.hour, fields.hour),\n dayOfMonth: this.resolveField(CronDayOfMonth, base.dayOfMonth, fields.dayOfMonth),\n month: this.resolveField(CronMonth, base.month, fields.month),\n dayOfWeek: this.resolveField(CronDayOfWeek, base.dayOfWeek, fields.dayOfWeek),\n });\n }\n\n /**\n * Resolves a field value, either using the provided CronField instance or creating a new one from raw values.\n * @param constructor - The constructor for creating new field instances\n * @param baseField - The base field to use if no override is provided\n * @param fieldValue - The override value, either a CronField instance or raw values\n * @returns The resolved CronField instance\n * @private\n */\n private static resolveField<T extends CronField, V extends any[]>(\n constructor: new (values: V) => T,\n baseField: T,\n fieldValue: T | V | undefined,\n ): T {\n if (!fieldValue) {\n return baseField;\n }\n if (fieldValue instanceof CronField) {\n return fieldValue as T;\n }\n return new constructor(fieldValue as V);\n }\n\n /**\n * CronFieldCollection constructor. Initializes the cron fields with the provided values.\n * @param {CronFields} param0 - The cron fields values\n * @throws {Error} if validation fails\n * @example\n * const cronFields = new CronFieldCollection({\n * second: new CronSecond([0]),\n * minute: new CronMinute([0, 30]),\n * hour: new CronHour([9]),\n * dayOfMonth: new CronDayOfMonth([15]),\n * month: new CronMonth([1]),\n * dayOfWeek: new CronDayOfTheWeek([1, 2, 3, 4, 5]),\n * })\n *\n * console.log(cronFields.second.values); // [0]\n * console.log(cronFields.minute.values); // [0, 30]\n * console.log(cronFields.hour.values); // [9]\n * console.log(cronFields.dayOfMonth.values); // [15]\n * console.log(cronFields.month.values); // [1]\n * console.log(cronFields.dayOfWeek.values); // [1, 2, 3, 4, 5]\n */\n constructor({ second, minute, hour, dayOfMonth, month, dayOfWeek }: CronFields) {\n if (!second) {\n throw new Error('Validation error, Field second is missing');\n }\n if (!minute) {\n throw new Error('Validation error, Field minute is missing');\n }\n if (!hour) {\n throw new Error('Validation error, Field hour is missing');\n }\n if (!dayOfMonth) {\n throw new Error('Validation error, Field dayOfMonth is missing');\n }\n if (!month) {\n throw new Error('Validation error, Field month is missing');\n }\n if (!dayOfWeek) {\n throw new Error('Validation error, Field dayOfWeek is missing');\n }\n\n if (month.values.length === 1 && !dayOfMonth.hasLastChar) {\n if (!(parseInt(dayOfMonth.values[0] as string, 10) <= CronMonth.daysInMonth[month.values[0] - 1])) {\n throw new Error('Invalid explicit day of month definition');\n }\n }\n\n this.#second = second;\n this.#minute = minute;\n this.#hour = hour;\n this.#month = month;\n this.#dayOfWeek = dayOfWeek;\n this.#dayOfMonth = dayOfMonth;\n }\n\n /**\n * Returns the second field.\n * @returns {CronSecond}\n */\n get second(): CronSecond {\n return this.#second;\n }\n\n /**\n * Returns the minute field.\n * @returns {CronMinute}\n */\n get minute(): CronMinute {\n return this.#minute;\n }\n\n /**\n * Returns the hour field.\n * @returns {CronHour}\n */\n get hour(): CronHour {\n return this.#hour;\n }\n\n /**\n * Returns the day of the month field.\n * @returns {CronDayOfMonth}\n */\n get dayOfMonth(): CronDayOfMonth {\n return this.#dayOfMonth;\n }\n\n /**\n * Returns the month field.\n * @returns {CronMonth}\n */\n get month(): CronMonth {\n return this.#month;\n }\n\n /**\n * Returns the day of the week field.\n * @returns {CronDayOfWeek}\n */\n get dayOfWeek(): CronDayOfWeek {\n return this.#dayOfWeek;\n }\n\n /**\n * Returns a string representation of the cron fields.\n * @param {(number | CronChars)[]} input - The cron fields values\n * @static\n * @returns {FieldRange[]} - The compacted cron fields\n */\n static compactField(input: (number | CronChars)[]): FieldRange[] {\n if (input.length === 0) {\n return [];\n }\n\n // Initialize the output array and current IFieldRange\n const output: FieldRange[] = [];\n let current: FieldRange | undefined = undefined;\n\n input.forEach((item, i, arr) => {\n // If the current FieldRange is undefined, create a new one with the current item as the start.\n if (current === undefined) {\n current = { start: item, count: 1 };\n return;\n }\n\n // Cache the previous and next items in the array.\n const prevItem = arr[i - 1] || current.start;\n const nextItem = arr[i + 1];\n\n // If the current item is 'L' or 'W', push the current FieldRange to the output and\n // create a new FieldRange with the current item as the start.\n // 'L' and 'W' characters are special cases that need to be handled separately.\n if (item === 'L' || item === 'W') {\n output.push(current);\n output.push({ start: item, count: 1 });\n current = undefined;\n return;\n }\n\n // If the current step is undefined and there is a next item, update the current IFieldRange.\n // This block checks if the current step needs to be updated and does so if needed.\n if (current.step === undefined && nextItem !== undefined) {\n const step = item - (prevItem as number);\n const nextStep = (nextItem as number) - item;\n\n // If the current step is less or equal to the next step, update the current FieldRange to include the current item.\n if (step <= nextStep) {\n current = { ...current, count: 2, end: item, step };\n return;\n }\n current.step = 1;\n }\n\n // If the difference between the current item and the current end is equal to the current step,\n // update the current IFieldRange's count and end.\n // This block checks if the current item is part of the current range and updates the range accordingly.\n if (item - (current.end ?? 0) === current.step) {\n current.count++;\n current.end = item;\n } else {\n // If the count is 1, push a new FieldRange with the current start.\n // This handles the case where the current range has only one element.\n if (current.count === 1) {\n // If the count is 2, push two separate IFieldRanges, one for each element.\n output.push({ start: current.start, count: 1 });\n } else if (current.count === 2) {\n output.push({ start: current.start, count: 1 });\n // current.end can never be undefined here but typescript doesn't know that\n // this is why we ?? it and then ignore the prevItem in the coverage\n output.push({\n start: current.end ?? /* istanbul ignore next - see above */ prevItem,\n count: 1,\n });\n } else {\n // Otherwise, push the current FieldRange to the output.\n output.push(current);\n }\n // Reset the current FieldRange with the current item as the start.\n current = { start: item, count: 1 };\n }\n });\n\n // Push the final IFieldRange, if any, to the output array.\n if (current) {\n output.push(current);\n }\n return output;\n }\n\n /**\n * Handles a single range.\n * @param {CronField} field - The cron field to stringify\n * @param {FieldRange} range {start: number, end: number, step: number, count: number} The range to handle.\n * @param {number} max The maximum value for the field.\n * @returns {string | null} The stringified range or null if it cannot be stringified.\n * @private\n */\n static #handleSingleRange(field: CronField, range: FieldRange, max: number): string | null {\n const step = range.step;\n if (!step) {\n return null;\n }\n if (step === 1 && range.start === field.min && range.end && range.end >= max) {\n return field.hasQuestionMarkChar ? '?' : '*';\n }\n if (step !== 1 && range.start === field.min && range.end && range.end >= max - step + 1) {\n return `*/${step}`;\n }\n return null;\n }\n\n /**\n * Handles multiple ranges.\n * @param {FieldRange} range {start: number, end: number, step: number, count: number} The range to handle.\n * @param {number} max The maximum value for the field.\n * @returns {string} The stringified range.\n * @private\n */\n static #handleMultipleRanges(range: FieldRange, max: number): string {\n const step = range.step;\n if (step === 1) {\n return `${range.start}-${range.end}`;\n }\n\n const multiplier = range.start === 0 ? range.count - 1 : range.count;\n /* istanbul ignore if */\n if (!step) {\n throw new Error('Unexpected range step');\n }\n /* istanbul ignore if */\n if (!range.end) {\n throw new Error('Unexpected range end');\n }\n if (step * multiplier > range.end) {\n const mapFn = (_: number, index: number) => {\n /* istanbul ignore if */\n if (typeof range.start !== 'number') {\n throw new Error('Unexpected range start');\n }\n return index % step === 0 ? range.start + index : null;\n };\n /* istanbul ignore if */\n if (typeof range.start !== 'number') {\n throw new Error('Unexpected range start');\n }\n const seed = { length: range.end - range.start + 1 };\n return Array.from(seed, mapFn)\n .filter((value) => value !== null)\n .join(',');\n }\n\n return range.end === max - step + 1 ? `${range.start}/${step}` : `${range.start}-${range.end}/${step}`;\n }\n\n /**\n * Returns a string representation of the cron fields.\n * @param {CronField} field - The cron field to stringify\n * @static\n * @returns {string} - The stringified cron field\n */\n stringifyField(field: CronField): string {\n let max = field.max;\n let values = field.values;\n if (field instanceof CronDayOfWeek) {\n max = 6;\n const dayOfWeek = this.#dayOfWeek.values;\n values = dayOfWeek[dayOfWeek.length - 1] === 7 ? dayOfWeek.slice(0, -1) : dayOfWeek;\n }\n if (field instanceof CronDayOfMonth) {\n max = this.#month.values.length === 1 ? CronMonth.daysInMonth[this.#month.values[0] - 1] : field.max;\n }\n\n const ranges = CronFieldCollection.compactField(values);\n if (ranges.length === 1) {\n const singleRangeResult = CronFieldCollection.#handleSingleRange(field, ranges[0], max);\n if (singleRangeResult) {\n return singleRangeResult;\n }\n }\n return ranges\n .map((range) => {\n const value =\n range.count === 1 ? range.start.toString() : CronFieldCollection.#handleMultipleRanges(range, max);\n if (field instanceof CronDayOfWeek && field.nthDay > 0) {\n return `${value}#${field.nthDay}`;\n }\n return value;\n })\n .join(',');\n }\n\n /**\n * Returns a string representation of the cron field values.\n * @param {boolean} includeSeconds - Whether to include seconds in the output\n * @returns {string} The formatted cron string\n */\n stringify(includeSeconds = false): string {\n const arr = [];\n if (includeSeconds) {\n arr.push(this.stringifyField(this.#second)); // second\n }\n\n arr.push(\n this.stringifyField(this.#minute), // minute\n this.stringifyField(this.#hour), // hour\n this.stringifyField(this.#dayOfMonth), // dayOfMonth\n this.stringifyField(this.#month), // month\n this.stringifyField(this.#dayOfWeek), // dayOfWeek\n );\n return arr.join(' ');\n }\n\n /**\n * Returns a serialized representation of the cron fields values.\n * @returns {SerializedCronFields} An object containing the cron field values\n */\n serialize(): SerializedCronFields {\n return {\n second: this.#second.serialize(),\n minute: this.#minute.serialize(),\n hour: this.#hour.serialize(),\n dayOfMonth: this.#dayOfMonth.serialize(),\n month: this.#month.serialize(),\n dayOfWeek: this.#dayOfWeek.serialize(),\n };\n }\n}\n"
|
|
5
|
+
"import {\n CronSecond,\n CronMinute,\n CronHour,\n CronDayOfMonth,\n CronMonth,\n CronDayOfWeek,\n CronField,\n} from './fields/index.cjs';\nimport type { SerializedCronField, CronChars } from './fields/index.cjs';\nimport type { SixtyRange, HourRange, DayOfMonthRange, MonthRange, DayOfWeekRange } from './fields/types.cjs';\n\nexport type FieldRange = {\n start: number | CronChars;\n count: number;\n end?: number;\n step?: number;\n};\n\nexport type CronFields = {\n second: CronSecond;\n minute: CronMinute;\n hour: CronHour;\n dayOfMonth: CronDayOfMonth;\n month: CronMonth;\n dayOfWeek: CronDayOfWeek;\n};\n\nexport type CronFieldOverride = {\n second?: CronSecond | SixtyRange[];\n minute?: CronMinute | SixtyRange[];\n hour?: CronHour | HourRange[];\n dayOfMonth?: CronDayOfMonth | DayOfMonthRange[];\n month?: CronMonth | MonthRange[];\n dayOfWeek?: CronDayOfWeek | DayOfWeekRange[];\n};\n\nexport type SerializedCronFields = {\n second: SerializedCronField;\n minute: SerializedCronField;\n hour: SerializedCronField;\n dayOfMonth: SerializedCronField;\n month: SerializedCronField;\n dayOfWeek: SerializedCronField;\n};\n\n/**\n * Represents a complete set of cron fields.\n * @class CronFieldCollection\n */\nexport class CronFieldCollection {\n readonly #second: CronSecond;\n readonly #minute: CronMinute;\n readonly #hour: CronHour;\n readonly #dayOfMonth: CronDayOfMonth;\n readonly #month: CronMonth;\n readonly #dayOfWeek: CronDayOfWeek;\n\n /**\n * Creates a new CronFieldCollection instance by partially overriding fields from an existing one.\n * @param {CronFieldCollection} base - The base CronFieldCollection to copy fields from\n * @param {CronFieldOverride} fields - The fields to override, can be CronField instances or raw values\n * @returns {CronFieldCollection} A new CronFieldCollection instance\n * @example\n * const base = new CronFieldCollection({\n * second: new CronSecond([0]),\n * minute: new CronMinute([0]),\n * hour: new CronHour([12]),\n * dayOfMonth: new CronDayOfMonth([1]),\n * month: new CronMonth([1]),\n * dayOfWeek: new CronDayOfWeek([1])\n * });\n *\n * // Using CronField instances\n * const modified1 = CronFieldCollection.from(base, {\n * hour: new CronHour([15]),\n * minute: new CronMinute([30])\n * });\n *\n * // Using raw values\n * const modified2 = CronFieldCollection.from(base, {\n * hour: [15], // Will create new CronHour\n * minute: [30] // Will create new CronMinute\n * });\n */\n static from(base: CronFieldCollection, fields: CronFieldOverride): CronFieldCollection {\n return new CronFieldCollection({\n second: this.resolveField(CronSecond, base.second, fields.second),\n minute: this.resolveField(CronMinute, base.minute, fields.minute),\n hour: this.resolveField(CronHour, base.hour, fields.hour),\n dayOfMonth: this.resolveField(CronDayOfMonth, base.dayOfMonth, fields.dayOfMonth),\n month: this.resolveField(CronMonth, base.month, fields.month),\n dayOfWeek: this.resolveField(CronDayOfWeek, base.dayOfWeek, fields.dayOfWeek),\n });\n }\n\n /**\n * Resolves a field value, either using the provided CronField instance or creating a new one from raw values.\n * @param constructor - The constructor for creating new field instances\n * @param baseField - The base field to use if no override is provided\n * @param fieldValue - The override value, either a CronField instance or raw values\n * @returns The resolved CronField instance\n * @private\n */\n private static resolveField<T extends CronField, V extends any[]>(\n constructor: new (values: V) => T,\n baseField: T,\n fieldValue: T | V | undefined,\n ): T {\n if (!fieldValue) {\n return baseField;\n }\n if (fieldValue instanceof CronField) {\n return fieldValue as T;\n }\n return new constructor(fieldValue as V);\n }\n\n /**\n * CronFieldCollection constructor. Initializes the cron fields with the provided values.\n * @param {CronFields} param0 - The cron fields values\n * @throws {Error} if validation fails\n * @example\n * const cronFields = new CronFieldCollection({\n * second: new CronSecond([0]),\n * minute: new CronMinute([0, 30]),\n * hour: new CronHour([9]),\n * dayOfMonth: new CronDayOfMonth([15]),\n * month: new CronMonth([1]),\n * dayOfWeek: new CronDayOfTheWeek([1, 2, 3, 4, 5]),\n * })\n *\n * console.log(cronFields.second.values); // [0]\n * console.log(cronFields.minute.values); // [0, 30]\n * console.log(cronFields.hour.values); // [9]\n * console.log(cronFields.dayOfMonth.values); // [15]\n * console.log(cronFields.month.values); // [1]\n * console.log(cronFields.dayOfWeek.values); // [1, 2, 3, 4, 5]\n */\n constructor({ second, minute, hour, dayOfMonth, month, dayOfWeek }: CronFields) {\n if (!second) {\n throw new Error('Validation error, Field second is missing');\n }\n if (!minute) {\n throw new Error('Validation error, Field minute is missing');\n }\n if (!hour) {\n throw new Error('Validation error, Field hour is missing');\n }\n if (!dayOfMonth) {\n throw new Error('Validation error, Field dayOfMonth is missing');\n }\n if (!month) {\n throw new Error('Validation error, Field month is missing');\n }\n if (!dayOfWeek) {\n throw new Error('Validation error, Field dayOfWeek is missing');\n }\n\n if (month.values.length === 1 && !dayOfMonth.hasLastChar) {\n if (!(parseInt(dayOfMonth.values[0] as string, 10) <= CronMonth.daysInMonth[month.values[0] - 1])) {\n throw new Error('Invalid explicit day of month definition');\n }\n }\n\n this.#second = second;\n this.#minute = minute;\n this.#hour = hour;\n this.#month = month;\n this.#dayOfWeek = dayOfWeek;\n this.#dayOfMonth = dayOfMonth;\n }\n\n /**\n * Returns the second field.\n * @returns {CronSecond}\n */\n get second(): CronSecond {\n return this.#second;\n }\n\n /**\n * Returns the minute field.\n * @returns {CronMinute}\n */\n get minute(): CronMinute {\n return this.#minute;\n }\n\n /**\n * Returns the hour field.\n * @returns {CronHour}\n */\n get hour(): CronHour {\n return this.#hour;\n }\n\n /**\n * Returns the day of the month field.\n * @returns {CronDayOfMonth}\n */\n get dayOfMonth(): CronDayOfMonth {\n return this.#dayOfMonth;\n }\n\n /**\n * Returns the month field.\n * @returns {CronMonth}\n */\n get month(): CronMonth {\n return this.#month;\n }\n\n /**\n * Returns the day of the week field.\n * @returns {CronDayOfWeek}\n */\n get dayOfWeek(): CronDayOfWeek {\n return this.#dayOfWeek;\n }\n\n /**\n * Returns a string representation of the cron fields.\n * @param {(number | CronChars)[]} input - The cron fields values\n * @static\n * @returns {FieldRange[]} - The compacted cron fields\n */\n static compactField(input: (number | CronChars)[]): FieldRange[] {\n if (input.length === 0) {\n return [];\n }\n\n // Initialize the output array and current IFieldRange\n const output: FieldRange[] = [];\n let current: FieldRange | undefined = undefined;\n\n input.forEach((item, i, arr) => {\n // If the current FieldRange is undefined, create a new one with the current item as the start.\n if (current === undefined) {\n current = { start: item, count: 1 };\n return;\n }\n\n // Cache the previous and next items in the array.\n const prevItem = arr[i - 1] || current.start;\n const nextItem = arr[i + 1];\n\n // If the current item is 'L' or 'W', push the current FieldRange to the output and\n // create a new FieldRange with the current item as the start.\n // 'L' and 'W' characters are special cases that need to be handled separately.\n if (item === 'L' || item === 'W') {\n output.push(current);\n output.push({ start: item, count: 1 });\n current = undefined;\n return;\n }\n\n // If the current step is undefined and there is a next item, update the current IFieldRange.\n // This block checks if the current step needs to be updated and does so if needed.\n if (current.step === undefined && nextItem !== undefined) {\n const step = item - (prevItem as number);\n const nextStep = (nextItem as number) - item;\n\n // If the current step is less or equal to the next step, update the current FieldRange to include the current item.\n if (step <= nextStep) {\n current = { ...current, count: 2, end: item, step };\n return;\n }\n current.step = 1;\n }\n\n // If the difference between the current item and the current end is equal to the current step,\n // update the current IFieldRange's count and end.\n // This block checks if the current item is part of the current range and updates the range accordingly.\n if (item - (current.end ?? 0) === current.step) {\n current.count++;\n current.end = item;\n } else {\n // If the count is 1, push a new FieldRange with the current start.\n // This handles the case where the current range has only one element.\n if (current.count === 1) {\n // If the count is 2, push two separate IFieldRanges, one for each element.\n output.push({ start: current.start, count: 1 });\n } else if (current.count === 2) {\n output.push({ start: current.start, count: 1 });\n // current.end can never be undefined here but typescript doesn't know that\n // this is why we ?? it and then ignore the prevItem in the coverage\n output.push({\n start: current.end ?? /* istanbul ignore next - see above */ prevItem,\n count: 1,\n });\n } else {\n // Otherwise, push the current FieldRange to the output.\n output.push(current);\n }\n // Reset the current FieldRange with the current item as the start.\n current = { start: item, count: 1 };\n }\n });\n\n // Push the final IFieldRange, if any, to the output array.\n if (current) {\n output.push(current);\n }\n return output;\n }\n\n /**\n * Handles a single range.\n * @param {CronField} field - The cron field to stringify\n * @param {FieldRange} range {start: number, end: number, step: number, count: number} The range to handle.\n * @param {number} max The maximum value for the field.\n * @returns {string | null} The stringified range or null if it cannot be stringified.\n * @private\n */\n static #handleSingleRange(field: CronField, range: FieldRange, max: number): string | null {\n const step = range.step;\n if (!step) {\n return null;\n }\n if (step === 1 && range.start === field.min && range.end && range.end >= max) {\n return field.hasQuestionMarkChar ? '?' : '*';\n }\n if (step !== 1 && range.start === field.min && range.end && range.end >= max - step + 1) {\n return `*/${step}`;\n }\n return null;\n }\n\n /**\n * Handles multiple ranges.\n * @param {FieldRange} range {start: number, end: number, step: number, count: number} The range to handle.\n * @param {number} max The maximum value for the field.\n * @returns {string} The stringified range.\n * @private\n */\n static #handleMultipleRanges(range: FieldRange, max: number): string {\n const step = range.step;\n if (step === 1) {\n return `${range.start}-${range.end}`;\n }\n\n const multiplier = range.start === 0 ? range.count - 1 : range.count;\n /* istanbul ignore if */\n if (!step) {\n throw new Error('Unexpected range step');\n }\n /* istanbul ignore if */\n if (!range.end) {\n throw new Error('Unexpected range end');\n }\n if (step * multiplier > range.end) {\n const mapFn = (_: number, index: number) => {\n /* istanbul ignore if */\n if (typeof range.start !== 'number') {\n throw new Error('Unexpected range start');\n }\n return index % step === 0 ? range.start + index : null;\n };\n /* istanbul ignore if */\n if (typeof range.start !== 'number') {\n throw new Error('Unexpected range start');\n }\n const seed = { length: range.end - range.start + 1 };\n return Array.from(seed, mapFn)\n .filter((value) => value !== null)\n .join(',');\n }\n\n return range.end === max - step + 1 ? `${range.start}/${step}` : `${range.start}-${range.end}/${step}`;\n }\n\n /**\n * Returns a string representation of the cron fields.\n * @param {CronField} field - The cron field to stringify\n * @static\n * @returns {string} - The stringified cron field\n */\n stringifyField(field: CronField): string {\n let max = field.max;\n let values = field.values;\n if (field instanceof CronDayOfWeek) {\n max = 6;\n const dayOfWeek = this.#dayOfWeek.values;\n values = dayOfWeek[dayOfWeek.length - 1] === 7 ? dayOfWeek.slice(0, -1) : dayOfWeek;\n }\n if (field instanceof CronDayOfMonth) {\n max = this.#month.values.length === 1 ? CronMonth.daysInMonth[this.#month.values[0] - 1] : field.max;\n }\n\n const ranges = CronFieldCollection.compactField(values);\n if (ranges.length === 1) {\n const singleRangeResult = CronFieldCollection.#handleSingleRange(field, ranges[0], max);\n if (singleRangeResult) {\n return singleRangeResult;\n }\n }\n return ranges\n .map((range) => {\n const value =\n range.count === 1 ? range.start.toString() : CronFieldCollection.#handleMultipleRanges(range, max);\n if (field instanceof CronDayOfWeek && field.nthDay > 0) {\n return `${value}#${field.nthDay}`;\n }\n return value;\n })\n .join(',');\n }\n\n /**\n * Returns a string representation of the cron field values.\n * @param {boolean} includeSeconds - Whether to include seconds in the output\n * @returns {string} The formatted cron string\n */\n stringify(includeSeconds = false): string {\n const arr = [];\n if (includeSeconds) {\n arr.push(this.stringifyField(this.#second)); // second\n }\n\n arr.push(\n this.stringifyField(this.#minute), // minute\n this.stringifyField(this.#hour), // hour\n this.stringifyField(this.#dayOfMonth), // dayOfMonth\n this.stringifyField(this.#month), // month\n this.stringifyField(this.#dayOfWeek), // dayOfWeek\n );\n return arr.join(' ');\n }\n\n /**\n * Returns a serialized representation of the cron fields values.\n * @returns {SerializedCronFields} An object containing the cron field values\n */\n serialize(): SerializedCronFields {\n return {\n second: this.#second.serialize(),\n minute: this.#minute.serialize(),\n hour: this.#hour.serialize(),\n dayOfMonth: this.#dayOfMonth.serialize(),\n month: this.#month.serialize(),\n dayOfWeek: this.#dayOfWeek.serialize(),\n };\n }\n}\n"
|
|
6
6
|
],
|
|
7
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
8
|
-
"debugId": "
|
|
7
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAQO,IARP;AAAA;AAkDO,MAAM,oBAAoB;AAAA,EACtB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,SA6BF,IAAI,CAAC,MAA2B,QAAgD;AAAA,IACrF,OAAO,IAAI,oBAAoB;AAAA,MAC7B,QAAQ,KAAK,aAAa,0BAAY,KAAK,QAAQ,OAAO,MAAM;AAAA,MAChE,QAAQ,KAAK,aAAa,0BAAY,KAAK,QAAQ,OAAO,MAAM;AAAA,MAChE,MAAM,KAAK,aAAa,wBAAU,KAAK,MAAM,OAAO,IAAI;AAAA,MACxD,YAAY,KAAK,aAAa,8BAAgB,KAAK,YAAY,OAAO,UAAU;AAAA,MAChF,OAAO,KAAK,aAAa,yBAAW,KAAK,OAAO,OAAO,KAAK;AAAA,MAC5D,WAAW,KAAK,aAAa,6BAAe,KAAK,WAAW,OAAO,SAAS;AAAA,IAC9E,CAAC;AAAA;AAAA,SAWY,YAAkD,CAC/D,aACA,WACA,YACG;AAAA,IACH,IAAI,CAAC,YAAY;AAAA,MACf,OAAO;AAAA,IACT;AAAA,IACA,IAAI,sBAAsB,yBAAW;AAAA,MACnC,OAAO;AAAA,IACT;AAAA,IACA,OAAO,IAAI,YAAY,UAAe;AAAA;AAAA,EAwBxC,WAAW,GAAG,QAAQ,QAAQ,MAAM,YAAY,OAAO,aAAyB;AAAA,IAC9E,IAAI,CAAC,QAAQ;AAAA,MACX,MAAM,IAAI,MAAM,2CAA2C;AAAA,IAC7D;AAAA,IACA,IAAI,CAAC,QAAQ;AAAA,MACX,MAAM,IAAI,MAAM,2CAA2C;AAAA,IAC7D;AAAA,IACA,IAAI,CAAC,MAAM;AAAA,MACT,MAAM,IAAI,MAAM,yCAAyC;AAAA,IAC3D;AAAA,IACA,IAAI,CAAC,YAAY;AAAA,MACf,MAAM,IAAI,MAAM,+CAA+C;AAAA,IACjE;AAAA,IACA,IAAI,CAAC,OAAO;AAAA,MACV,MAAM,IAAI,MAAM,0CAA0C;AAAA,IAC5D;AAAA,IACA,IAAI,CAAC,WAAW;AAAA,MACd,MAAM,IAAI,MAAM,8CAA8C;AAAA,IAChE;AAAA,IAEA,IAAI,MAAM,OAAO,WAAW,KAAK,CAAC,WAAW,aAAa;AAAA,MACxD,IAAI,EAAE,SAAS,WAAW,OAAO,IAAc,EAAE,KAAK,wBAAU,YAAY,MAAM,OAAO,KAAK,KAAK;AAAA,QACjG,MAAM,IAAI,MAAM,0CAA0C;AAAA,MAC5D;AAAA,IACF;AAAA,IAEA,KAAK,UAAU;AAAA,IACf,KAAK,UAAU;AAAA,IACf,KAAK,QAAQ;AAAA,IACb,KAAK,SAAS;AAAA,IACd,KAAK,aAAa;AAAA,IAClB,KAAK,cAAc;AAAA;AAAA,MAOjB,MAAM,GAAe;AAAA,IACvB,OAAO,KAAK;AAAA;AAAA,MAOV,MAAM,GAAe;AAAA,IACvB,OAAO,KAAK;AAAA;AAAA,MAOV,IAAI,GAAa;AAAA,IACnB,OAAO,KAAK;AAAA;AAAA,MAOV,UAAU,GAAmB;AAAA,IAC/B,OAAO,KAAK;AAAA;AAAA,MAOV,KAAK,GAAc;AAAA,IACrB,OAAO,KAAK;AAAA;AAAA,MAOV,SAAS,GAAkB;AAAA,IAC7B,OAAO,KAAK;AAAA;AAAA,SASP,YAAY,CAAC,OAA6C;AAAA,IAC/D,IAAI,MAAM,WAAW,GAAG;AAAA,MACtB,OAAO,CAAC;AAAA,IACV;AAAA,IAGA,MAAM,SAAuB,CAAC;AAAA,IAC9B,IAAI,UAAkC;AAAA,IAEtC,MAAM,QAAQ,CAAC,MAAM,GAAG,QAAQ;AAAA,MAE9B,IAAI,YAAY,WAAW;AAAA,QACzB,UAAU,EAAE,OAAO,MAAM,OAAO,EAAE;AAAA,QAClC;AAAA,MACF;AAAA,MAGA,MAAM,WAAW,IAAI,IAAI,MAAM,QAAQ;AAAA,MACvC,MAAM,WAAW,IAAI,IAAI;AAAA,MAKzB,IAAI,SAAS,OAAO,SAAS,KAAK;AAAA,QAChC,OAAO,KAAK,OAAO;AAAA,QACnB,OAAO,KAAK,EAAE,OAAO,MAAM,OAAO,EAAE,CAAC;AAAA,QACrC,UAAU;AAAA,QACV;AAAA,MACF;AAAA,MAIA,IAAI,QAAQ,SAAS,aAAa,aAAa,WAAW;AAAA,QACxD,MAAM,OAAO,OAAQ;AAAA,QACrB,MAAM,WAAY,WAAsB;AAAA,QAGxC,IAAI,QAAQ,UAAU;AAAA,UACpB,UAAU,KAAK,SAAS,OAAO,GAAG,KAAK,MAAM,KAAK;AAAA,UAClD;AAAA,QACF;AAAA,QACA,QAAQ,OAAO;AAAA,MACjB;AAAA,MAKA,IAAI,QAAQ,QAAQ,OAAO,OAAO,QAAQ,MAAM;AAAA,QAC9C,QAAQ;AAAA,QACR,QAAQ,MAAM;AAAA,MAChB,EAAO;AAAA,QAGL,IAAI,QAAQ,UAAU,GAAG;AAAA,UAEvB,OAAO,KAAK,EAAE,OAAO,QAAQ,OAAO,OAAO,EAAE,CAAC;AAAA,QAChD,EAAO,SAAI,QAAQ,UAAU,GAAG;AAAA,UAC9B,OAAO,KAAK,EAAE,OAAO,QAAQ,OAAO,OAAO,EAAE,CAAC;AAAA,UAG9C,OAAO,KAAK;AAAA,YACV,OAAO,QAAQ,OAA8C;AAAA,YAC7D,OAAO;AAAA,UACT,CAAC;AAAA,QACH,EAAO;AAAA,UAEL,OAAO,KAAK,OAAO;AAAA;AAAA,QAGrB,UAAU,EAAE,OAAO,MAAM,OAAO,EAAE;AAAA;AAAA,KAErC;AAAA,IAGD,IAAI,SAAS;AAAA,MACX,OAAO,KAAK,OAAO;AAAA,IACrB;AAAA,IACA,OAAO;AAAA;AAAA,SAWF,kBAAkB,CAAC,OAAkB,OAAmB,KAA4B;AAAA,IACzF,MAAM,OAAO,MAAM;AAAA,IACnB,IAAI,CAAC,MAAM;AAAA,MACT,OAAO;AAAA,IACT;AAAA,IACA,IAAI,SAAS,KAAK,MAAM,UAAU,MAAM,OAAO,MAAM,OAAO,MAAM,OAAO,KAAK;AAAA,MAC5E,OAAO,MAAM,sBAAsB,MAAM;AAAA,IAC3C;AAAA,IACA,IAAI,SAAS,KAAK,MAAM,UAAU,MAAM,OAAO,MAAM,OAAO,MAAM,OAAO,MAAM,OAAO,GAAG;AAAA,MACvF,OAAO,KAAK;AAAA,IACd;AAAA,IACA,OAAO;AAAA;AAAA,SAUF,qBAAqB,CAAC,OAAmB,KAAqB;AAAA,IACnE,MAAM,OAAO,MAAM;AAAA,IACnB,IAAI,SAAS,GAAG;AAAA,MACd,OAAO,GAAG,MAAM,SAAS,MAAM;AAAA,IACjC;AAAA,IAEA,MAAM,aAAa,MAAM,UAAU,IAAI,MAAM,QAAQ,IAAI,MAAM;AAAA,IAE/D,IAAI,CAAC,MAAM;AAAA,MACT,MAAM,IAAI,MAAM,uBAAuB;AAAA,IACzC;AAAA,IAEA,IAAI,CAAC,MAAM,KAAK;AAAA,MACd,MAAM,IAAI,MAAM,sBAAsB;AAAA,IACxC;AAAA,IACA,IAAI,OAAO,aAAa,MAAM,KAAK;AAAA,MACjC,MAAM,QAAQ,CAAC,GAAW,UAAkB;AAAA,QAE1C,IAAI,OAAO,MAAM,UAAU,UAAU;AAAA,UACnC,MAAM,IAAI,MAAM,wBAAwB;AAAA,QAC1C;AAAA,QACA,OAAO,QAAQ,SAAS,IAAI,MAAM,QAAQ,QAAQ;AAAA;AAAA,MAGpD,IAAI,OAAO,MAAM,UAAU,UAAU;AAAA,QACnC,MAAM,IAAI,MAAM,wBAAwB;AAAA,MAC1C;AAAA,MACA,MAAM,OAAO,EAAE,QAAQ,MAAM,MAAM,MAAM,QAAQ,EAAE;AAAA,MACnD,OAAO,MAAM,KAAK,MAAM,KAAK,EAC1B,OAAO,CAAC,UAAU,UAAU,IAAI,EAChC,KAAK,GAAG;AAAA,IACb;AAAA,IAEA,OAAO,MAAM,QAAQ,MAAM,OAAO,IAAI,GAAG,MAAM,SAAS,SAAS,GAAG,MAAM,SAAS,MAAM,OAAO;AAAA;AAAA,EASlG,cAAc,CAAC,OAA0B;AAAA,IACvC,IAAI,MAAM,MAAM;AAAA,IAChB,IAAI,SAAS,MAAM;AAAA,IACnB,IAAI,iBAAiB,6BAAe;AAAA,MAClC,MAAM;AAAA,MACN,MAAM,YAAY,KAAK,WAAW;AAAA,MAClC,SAAS,UAAU,UAAU,SAAS,OAAO,IAAI,UAAU,MAAM,GAAG,EAAE,IAAI;AAAA,IAC5E;AAAA,IACA,IAAI,iBAAiB,8BAAgB;AAAA,MACnC,MAAM,KAAK,OAAO,OAAO,WAAW,IAAI,wBAAU,YAAY,KAAK,OAAO,OAAO,KAAK,KAAK,MAAM;AAAA,IACnG;AAAA,IAEA,MAAM,SAAS,oBAAoB,aAAa,MAAM;AAAA,IACtD,IAAI,OAAO,WAAW,GAAG;AAAA,MACvB,MAAM,oBAAoB,oBAAoB,mBAAmB,OAAO,OAAO,IAAI,GAAG;AAAA,MACtF,IAAI,mBAAmB;AAAA,QACrB,OAAO;AAAA,MACT;AAAA,IACF;AAAA,IACA,OAAO,OACJ,IAAI,CAAC,UAAU;AAAA,MACd,MAAM,QACJ,MAAM,UAAU,IAAI,MAAM,MAAM,SAAS,IAAI,oBAAoB,sBAAsB,OAAO,GAAG;AAAA,MACnG,IAAI,iBAAiB,+BAAiB,MAAM,SAAS,GAAG;AAAA,QACtD,OAAO,GAAG,SAAS,MAAM;AAAA,MAC3B;AAAA,MACA,OAAO;AAAA,KACR,EACA,KAAK,GAAG;AAAA;AAAA,EAQb,SAAS,CAAC,iBAAiB,OAAe;AAAA,IACxC,MAAM,MAAM,CAAC;AAAA,IACb,IAAI,gBAAgB;AAAA,MAClB,IAAI,KAAK,KAAK,eAAe,KAAK,OAAO,CAAC;AAAA,IAC5C;AAAA,IAEA,IAAI,KACF,KAAK,eAAe,KAAK,OAAO,GAChC,KAAK,eAAe,KAAK,KAAK,GAC9B,KAAK,eAAe,KAAK,WAAW,GACpC,KAAK,eAAe,KAAK,MAAM,GAC/B,KAAK,eAAe,KAAK,UAAU,CACrC;AAAA,IACA,OAAO,IAAI,KAAK,GAAG;AAAA;AAAA,EAOrB,SAAS,GAAyB;AAAA,IAChC,OAAO;AAAA,MACL,QAAQ,KAAK,QAAQ,UAAU;AAAA,MAC/B,QAAQ,KAAK,QAAQ,UAAU;AAAA,MAC/B,MAAM,KAAK,MAAM,UAAU;AAAA,MAC3B,YAAY,KAAK,YAAY,UAAU;AAAA,MACvC,OAAO,KAAK,OAAO,UAAU;AAAA,MAC7B,WAAW,KAAK,WAAW,UAAU;AAAA,IACvC;AAAA;AAEJ;",
|
|
8
|
+
"debugId": "FC40E51090CB9E0B64756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/fields/CronDayOfMonth.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"import { CronField
|
|
5
|
+
"import { CronField } from './CronField.cjs';\nimport type { CronFieldOptions } from './CronField.cjs';\nimport type { CronChars, CronMax, CronMin, DayOfMonthRange } from './types.cjs';\n\nconst MIN_DAY = 1;\nconst MAX_DAY = 31;\nconst DAY_CHARS = Object.freeze(['L']) as CronChars[];\n\n/**\n * Represents the \"day of the month\" field within a cron expression.\n * @class CronDayOfMonth\n * @extends CronField\n */\nexport class CronDayOfMonth extends CronField {\n static get min(): CronMin {\n return MIN_DAY;\n }\n\n static get max(): CronMax {\n return MAX_DAY;\n }\n\n static get chars(): CronChars[] {\n return DAY_CHARS;\n }\n static get validChars(): RegExp {\n return /^[?,*\\dLH/-]+$|^.*H\\(\\d+-\\d+\\)\\/\\d+.*$|^.*H\\(\\d+-\\d+\\).*$|^.*H\\/\\d+.*$/;\n }\n /**\n * CronDayOfMonth constructor. Initializes the \"day of the month\" field with the provided values.\n * @param {DayOfMonthRange[]} values - Values for the \"day of the month\" field\n * @param {CronFieldOptions} [options] - Options provided by the parser\n * @throws {Error} if validation fails\n */\n constructor(values: DayOfMonthRange[], options?: CronFieldOptions) {\n super(values, options);\n this.validate();\n }\n\n /**\n * Returns an array of allowed values for the \"day of the month\" field.\n * @returns {DayOfMonthRange[]}\n */\n get values(): DayOfMonthRange[] {\n return super.values as DayOfMonthRange[];\n }\n}\n"
|
|
6
6
|
],
|
|
7
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
7
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAA0B,IAA1B;AAIA,IAAM,UAAU;AAChB,IAAM,UAAU;AAChB,IAAM,YAAY,OAAO,OAAO,CAAC,GAAG,CAAC;AAAA;AAO9B,MAAM,uBAAuB,2BAAU;AAAA,aACjC,GAAG,GAAY;AAAA,IACxB,OAAO;AAAA;AAAA,aAGE,GAAG,GAAY;AAAA,IACxB,OAAO;AAAA;AAAA,aAGE,KAAK,GAAgB;AAAA,IAC9B,OAAO;AAAA;AAAA,aAEE,UAAU,GAAW;AAAA,IAC9B,OAAO;AAAA;AAAA,EAQT,WAAW,CAAC,QAA2B,SAA4B;AAAA,IACjE,MAAM,QAAQ,OAAO;AAAA,IACrB,KAAK,SAAS;AAAA;AAAA,MAOZ,MAAM,GAAsB;AAAA,IAC9B,OAAO,MAAM;AAAA;AAEjB;",
|
|
8
8
|
"debugId": "79EC30EE50FEDC6A64756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/fields/CronDayOfWeek.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"import { CronField
|
|
5
|
+
"import { CronField } from './CronField.cjs';\nimport type { CronFieldOptions } from './CronField.cjs';\nimport type { CronChars, CronMax, CronMin, DayOfWeekRange } from './types.cjs';\n\nconst MIN_DAY = 0;\nconst MAX_DAY = 7;\nconst DAY_CHARS: readonly CronChars[] = Object.freeze(['L']);\n\n/**\n * Represents the \"day of the week\" field within a cron expression.\n * @class CronDayOfTheWeek\n * @extends CronField\n */\nexport class CronDayOfWeek extends CronField {\n static get min(): CronMin {\n return MIN_DAY;\n }\n\n static get max(): CronMax {\n return MAX_DAY;\n }\n\n static get chars(): readonly CronChars[] {\n return DAY_CHARS;\n }\n\n static get validChars(): RegExp {\n return /^[?,*\\dLH#/-]+$|^.*H\\(\\d+-\\d+\\)\\/\\d+.*$|^.*H\\(\\d+-\\d+\\).*$|^.*H\\/\\d+.*$/;\n }\n\n /**\n * CronDayOfTheWeek constructor. Initializes the \"day of the week\" field with the provided values.\n * @param {DayOfWeekRange[]} values - Values for the \"day of the week\" field\n * @param {CronFieldOptions} [options] - Options provided by the parser\n */\n constructor(values: DayOfWeekRange[], options?: CronFieldOptions) {\n super(values, options);\n this.validate();\n }\n\n /**\n * Returns an array of allowed values for the \"day of the week\" field.\n * @returns {DayOfWeekRange[]}\n */\n get values(): DayOfWeekRange[] {\n return super.values as DayOfWeekRange[];\n }\n\n /**\n * Returns the nth day of the week if specified in the cron expression.\n * This is used for the '#' character in the cron expression.\n * @returns {number} The nth day of the week (1-5) or 0 if not specified.\n */\n get nthDay(): number {\n return this.options.nthDayOfWeek ?? 0;\n }\n}\n"
|
|
6
6
|
],
|
|
7
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
7
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAA0B,IAA1B;AAIA,IAAM,UAAU;AAChB,IAAM,UAAU;AAChB,IAAM,YAAkC,OAAO,OAAO,CAAC,GAAG,CAAC;AAAA;AAOpD,MAAM,sBAAsB,2BAAU;AAAA,aAChC,GAAG,GAAY;AAAA,IACxB,OAAO;AAAA;AAAA,aAGE,GAAG,GAAY;AAAA,IACxB,OAAO;AAAA;AAAA,aAGE,KAAK,GAAyB;AAAA,IACvC,OAAO;AAAA;AAAA,aAGE,UAAU,GAAW;AAAA,IAC9B,OAAO;AAAA;AAAA,EAQT,WAAW,CAAC,QAA0B,SAA4B;AAAA,IAChE,MAAM,QAAQ,OAAO;AAAA,IACrB,KAAK,SAAS;AAAA;AAAA,MAOZ,MAAM,GAAqB;AAAA,IAC7B,OAAO,MAAM;AAAA;AAAA,MAQX,MAAM,GAAW;AAAA,IACnB,OAAO,KAAK,QAAQ,gBAAgB;AAAA;AAExC;",
|
|
8
8
|
"debugId": "269090F62A08F8C664756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/fields/CronField.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"import { CronChars, CronConstraints, CronFieldType, CronMax, CronMin } from './types.cjs';\n\n/**\n * Represents the serialized form of a cron field.\n * @typedef {Object} SerializedCronField\n * @property {boolean} wildcard - Indicates if the field is a wildcard.\n * @property {(number|string)[]} values - The values of the field.\n */\nexport type SerializedCronField = {\n wildcard: boolean;\n values: (number | string)[];\n};\n\n/**\n * Represents the options for a cron field.\n * @typedef {Object} CronFieldOptions\n * @property {string} rawValue - The raw value of the field.\n * @property {boolean} [wildcard] - Indicates if the field is a wildcard.\n * @property {number} [nthDayOfWeek] - The nth day of the week.\n */\nexport type CronFieldOptions = {\n rawValue?: string;\n wildcard?: boolean;\n nthDayOfWeek?: number;\n};\n\n/**\n * Represents a field within a cron expression.\n * This is a base class and should not be instantiated directly.\n * @class CronField\n */\nexport abstract class CronField {\n readonly #hasLastChar: boolean = false;\n readonly #hasQuestionMarkChar: boolean = false;\n\n readonly #wildcard: boolean = false;\n readonly #values: (number | string)[] = [];\n\n protected readonly options: CronFieldOptions & { rawValue: string } = { rawValue: '' };\n\n /**\n * Returns the minimum value allowed for this field.\n */\n /* istanbul ignore next */ static get min(): CronMin {\n /* istanbul ignore next */\n throw new Error('min must be overridden');\n }\n\n /**\n * Returns the maximum value allowed for this field.\n */\n /* istanbul ignore next */ static get max(): CronMax {\n /* istanbul ignore next */\n throw new Error('max must be overridden');\n }\n\n /**\n * Returns the allowed characters for this field.\n */\n /* istanbul ignore next */ static get chars(): readonly CronChars[] {\n /* istanbul ignore next - this is overridden */\n return Object.freeze([]);\n }\n\n /**\n * Returns the regular expression used to validate this field.\n */\n static get validChars(): RegExp {\n return /^[?,*\\dH/-]+$|^.*H\\(\\d+-\\d+\\)\\/\\d+.*$|^.*H\\(\\d+-\\d+\\).*$|^.*H\\/\\d+.*$/;\n }\n\n /**\n * Returns the constraints for this field.\n */\n static get constraints(): CronConstraints {\n return { min: this.min, max: this.max, chars: this.chars, validChars: this.validChars };\n }\n\n /**\n * CronField constructor. Initializes the field with the provided values.\n * @param {number[] | string[]} values - Values for this field\n * @param {CronFieldOptions} [options] - Options provided by the parser\n * @throws {TypeError} if the constructor is called directly\n * @throws {Error} if validation fails\n */\n protected constructor(values: (number | string)[], options: CronFieldOptions = { rawValue: '' }) {\n if (!Array.isArray(values)) {\n throw new Error(`${this.constructor.name} Validation error, values is not an array`);\n }\n if (!(values.length > 0)) {\n throw new Error(`${this.constructor.name} Validation error, values contains no values`);\n }\n\n /* istanbul ignore next */\n this.options = {\n ...options,\n rawValue: options.rawValue ?? '',\n };\n this.#values = values.sort(CronField.sorter);\n this.#wildcard = this.options.wildcard !== undefined ? this.options.wildcard : this.#isWildcardValue();\n this.#hasLastChar = this.options.rawValue.includes('L') || values.includes('L');\n this.#hasQuestionMarkChar = this.options.rawValue.includes('?') || values.includes('?');\n }\n\n /**\n * Returns the minimum value allowed for this field.\n * @returns {number}\n */\n get min(): number {\n // return the static value from the child class\n return (this.constructor as typeof CronField).min;\n }\n\n /**\n * Returns the maximum value allowed for this field.\n * @returns {number}\n */\n get max(): number {\n // return the static value from the child class\n return (this.constructor as typeof CronField).max;\n }\n\n /**\n * Returns an array of allowed special characters for this field.\n * @returns {string[]}\n */\n get chars(): readonly string[] {\n // return the frozen static value from the child class\n return (this.constructor as typeof CronField).chars;\n }\n\n /**\n * Indicates whether this field has a \"last\" character.\n * @returns {boolean}\n */\n get hasLastChar(): boolean {\n return this.#hasLastChar;\n }\n\n /**\n * Indicates whether this field has a \"question mark\" character.\n * @returns {boolean}\n */\n get hasQuestionMarkChar(): boolean {\n return this.#hasQuestionMarkChar;\n }\n\n /**\n * Indicates whether this field is a wildcard.\n * @returns {boolean}\n */\n get isWildcard(): boolean {\n return this.#wildcard;\n }\n\n /**\n * Returns an array of allowed values for this field.\n * @returns {CronFieldType}\n */\n get values(): CronFieldType {\n return this.#values as CronFieldType;\n }\n\n /**\n * Helper function to sort values in ascending order.\n * @param {number | string} a - First value to compare\n * @param {number | string} b - Second value to compare\n * @returns {number} - A negative, zero, or positive value, depending on the sort order\n */\n static sorter(a: number | string, b: number | string): number {\n const aIsNumber = typeof a === 'number';\n const bIsNumber = typeof b === 'number';\n if (aIsNumber && bIsNumber) return (a as number) - (b as number);\n if (!aIsNumber && !bIsNumber) return (a as string).localeCompare(b as string);\n return aIsNumber ? /* istanbul ignore next - A will always be a number until L-2 is supported */ -1 : 1;\n }\n\n /**\n * Find the next (or previous when `reverse` is true) numeric value in a sorted list.\n * Returns null if there's no value strictly after/before the current one.\n *\n * @param values - Sorted numeric values\n * @param currentValue - Current value to compare against\n * @param reverse - When true, search in reverse for previous smaller value\n */\n static findNearestValueInList(values: number[], currentValue: number, reverse: boolean): number | null {\n if (reverse) {\n for (let i = values.length - 1; i >= 0; i--) {\n if (values[i] < currentValue) return values[i];\n }\n return null;\n }\n\n for (let i = 0; i < values.length; i++) {\n if (values[i] > currentValue) return values[i];\n }\n return null;\n }\n\n /**\n * Instance helper that operates on this field's numeric `values`.\n *\n * @param currentValue - Current value to compare against\n * @param reverse - When true, search in reverse for previous smaller value\n */\n findNearestValue(currentValue: number, reverse: boolean): number | null {\n return (this.constructor as typeof CronField).findNearestValueInList(\n this.values as number[],\n currentValue,\n reverse,\n );\n }\n\n /**\n * Serializes the field to an object.\n * @returns {SerializedCronField}\n */\n serialize(): SerializedCronField {\n return {\n wildcard: this.#wildcard,\n values: this.#values,\n };\n }\n\n /**\n * Validates the field values against the allowed range and special characters.\n * @throws {Error} if validation fails\n */\n validate(): void {\n let badValue: number | string | undefined;\n const charsString = this.chars.length > 0 ? ` or chars ${this.chars.join('')}` : '';\n\n const charTest = (value: string) => (char: string) => new RegExp(`^\\\\d{0,2}${char}$`).test(value);\n const rangeTest = (value: number | string) => {\n badValue = value;\n return typeof value === 'number' ? value >= this.min && value <= this.max : this.chars.some(charTest(value));\n };\n const isValidRange = this.#values.every(rangeTest);\n if (!isValidRange) {\n throw new Error(\n `${this.constructor.name} Validation error, got value ${badValue} expected range ${this.min}-${this.max}${charsString}`,\n );\n }\n // check for duplicate value in this.#values array\n const duplicate = this.#values.find((value, index) => this.#values.indexOf(value) !== index);\n if (duplicate) {\n throw new Error(`${this.constructor.name} Validation error, duplicate values found: ${duplicate}`);\n }\n }\n\n /**\n * Determines if the field is a wildcard based on the values.\n * When options.rawValue is not empty, it checks if the raw value is a wildcard, otherwise it checks if all values in the range are included.\n * @returns {boolean}\n */\n #isWildcardValue(): boolean {\n if (this.options.rawValue.length > 0) {\n return ['*', '?'].includes(this.options.rawValue);\n }\n\n return Array.from({ length: this.max - this.min + 1 }, (_, i) => i + this.min).every((value) =>\n this.#values.includes(value),\n );\n }\n}\n"
|
|
5
|
+
"import type { CronChars, CronConstraints, CronFieldType, CronMax, CronMin } from './types.cjs';\n\n/**\n * Represents the serialized form of a cron field.\n * @typedef {Object} SerializedCronField\n * @property {boolean} wildcard - Indicates if the field is a wildcard.\n * @property {(number|string)[]} values - The values of the field.\n */\nexport type SerializedCronField = {\n wildcard: boolean;\n values: (number | string)[];\n};\n\n/**\n * Represents the options for a cron field.\n * @typedef {Object} CronFieldOptions\n * @property {string} rawValue - The raw value of the field.\n * @property {boolean} [wildcard] - Indicates if the field is a wildcard.\n * @property {number} [nthDayOfWeek] - The nth day of the week.\n */\nexport type CronFieldOptions = {\n rawValue?: string;\n wildcard?: boolean;\n nthDayOfWeek?: number;\n};\n\n/**\n * Represents a field within a cron expression.\n * This is a base class and should not be instantiated directly.\n * @class CronField\n */\nexport abstract class CronField {\n readonly #hasLastChar: boolean = false;\n readonly #hasQuestionMarkChar: boolean = false;\n\n readonly #wildcard: boolean = false;\n readonly #values: (number | string)[] = [];\n\n protected readonly options: CronFieldOptions & { rawValue: string } = { rawValue: '' };\n\n /**\n * Returns the minimum value allowed for this field.\n */\n /* istanbul ignore next */ static get min(): CronMin {\n /* istanbul ignore next */\n throw new Error('min must be overridden');\n }\n\n /**\n * Returns the maximum value allowed for this field.\n */\n /* istanbul ignore next */ static get max(): CronMax {\n /* istanbul ignore next */\n throw new Error('max must be overridden');\n }\n\n /**\n * Returns the allowed characters for this field.\n */\n /* istanbul ignore next */ static get chars(): readonly CronChars[] {\n /* istanbul ignore next - this is overridden */\n return Object.freeze([]);\n }\n\n /**\n * Returns the regular expression used to validate this field.\n */\n static get validChars(): RegExp {\n return /^[?,*\\dH/-]+$|^.*H\\(\\d+-\\d+\\)\\/\\d+.*$|^.*H\\(\\d+-\\d+\\).*$|^.*H\\/\\d+.*$/;\n }\n\n /**\n * Returns the constraints for this field.\n */\n static get constraints(): CronConstraints {\n return { min: this.min, max: this.max, chars: this.chars, validChars: this.validChars };\n }\n\n /**\n * CronField constructor. Initializes the field with the provided values.\n * @param {number[] | string[]} values - Values for this field\n * @param {CronFieldOptions} [options] - Options provided by the parser\n * @throws {TypeError} if the constructor is called directly\n * @throws {Error} if validation fails\n */\n protected constructor(values: (number | string)[], options: CronFieldOptions = { rawValue: '' }) {\n if (!Array.isArray(values)) {\n throw new Error(`${this.constructor.name} Validation error, values is not an array`);\n }\n if (!(values.length > 0)) {\n throw new Error(`${this.constructor.name} Validation error, values contains no values`);\n }\n\n /* istanbul ignore next */\n this.options = {\n ...options,\n rawValue: options.rawValue ?? '',\n };\n this.#values = values.sort(CronField.sorter);\n this.#wildcard = this.options.wildcard !== undefined ? this.options.wildcard : this.#isWildcardValue();\n this.#hasLastChar = this.options.rawValue.includes('L') || values.includes('L');\n this.#hasQuestionMarkChar = this.options.rawValue.includes('?') || values.includes('?');\n }\n\n /**\n * Returns the minimum value allowed for this field.\n * @returns {number}\n */\n get min(): number {\n // return the static value from the child class\n return (this.constructor as typeof CronField).min;\n }\n\n /**\n * Returns the maximum value allowed for this field.\n * @returns {number}\n */\n get max(): number {\n // return the static value from the child class\n return (this.constructor as typeof CronField).max;\n }\n\n /**\n * Returns an array of allowed special characters for this field.\n * @returns {string[]}\n */\n get chars(): readonly string[] {\n // return the frozen static value from the child class\n return (this.constructor as typeof CronField).chars;\n }\n\n /**\n * Indicates whether this field has a \"last\" character.\n * @returns {boolean}\n */\n get hasLastChar(): boolean {\n return this.#hasLastChar;\n }\n\n /**\n * Indicates whether this field has a \"question mark\" character.\n * @returns {boolean}\n */\n get hasQuestionMarkChar(): boolean {\n return this.#hasQuestionMarkChar;\n }\n\n /**\n * Indicates whether this field is a wildcard.\n * @returns {boolean}\n */\n get isWildcard(): boolean {\n return this.#wildcard;\n }\n\n /**\n * Returns an array of allowed values for this field.\n * @returns {CronFieldType}\n */\n get values(): CronFieldType {\n return this.#values as CronFieldType;\n }\n\n /**\n * Helper function to sort values in ascending order.\n * @param {number | string} a - First value to compare\n * @param {number | string} b - Second value to compare\n * @returns {number} - A negative, zero, or positive value, depending on the sort order\n */\n static sorter(a: number | string, b: number | string): number {\n const aIsNumber = typeof a === 'number';\n const bIsNumber = typeof b === 'number';\n if (aIsNumber && bIsNumber) return (a as number) - (b as number);\n if (!aIsNumber && !bIsNumber) return (a as string).localeCompare(b as string);\n return aIsNumber ? /* istanbul ignore next - A will always be a number until L-2 is supported */ -1 : 1;\n }\n\n /**\n * Find the next (or previous when `reverse` is true) numeric value in a sorted list.\n * Returns null if there's no value strictly after/before the current one.\n *\n * @param values - Sorted numeric values\n * @param currentValue - Current value to compare against\n * @param reverse - When true, search in reverse for previous smaller value\n */\n static findNearestValueInList(values: number[], currentValue: number, reverse: boolean): number | null {\n if (reverse) {\n for (let i = values.length - 1; i >= 0; i--) {\n if (values[i] < currentValue) return values[i];\n }\n return null;\n }\n\n for (let i = 0; i < values.length; i++) {\n if (values[i] > currentValue) return values[i];\n }\n return null;\n }\n\n /**\n * Instance helper that operates on this field's numeric `values`.\n *\n * @param currentValue - Current value to compare against\n * @param reverse - When true, search in reverse for previous smaller value\n */\n findNearestValue(currentValue: number, reverse: boolean): number | null {\n return (this.constructor as typeof CronField).findNearestValueInList(\n this.values as number[],\n currentValue,\n reverse,\n );\n }\n\n /**\n * Serializes the field to an object.\n * @returns {SerializedCronField}\n */\n serialize(): SerializedCronField {\n return {\n wildcard: this.#wildcard,\n values: this.#values,\n };\n }\n\n /**\n * Validates the field values against the allowed range and special characters.\n * @throws {Error} if validation fails\n */\n validate(): void {\n let badValue: number | string | undefined;\n const charsString = this.chars.length > 0 ? ` or chars ${this.chars.join('')}` : '';\n\n const charTest = (value: string) => (char: string) => new RegExp(`^\\\\d{0,2}${char}$`).test(value);\n const rangeTest = (value: number | string) => {\n badValue = value;\n return typeof value === 'number' ? value >= this.min && value <= this.max : this.chars.some(charTest(value));\n };\n const isValidRange = this.#values.every(rangeTest);\n if (!isValidRange) {\n throw new Error(\n `${this.constructor.name} Validation error, got value ${badValue} expected range ${this.min}-${this.max}${charsString}`,\n );\n }\n // check for duplicate value in this.#values array\n const duplicate = this.#values.find((value, index) => this.#values.indexOf(value) !== index);\n if (duplicate) {\n throw new Error(`${this.constructor.name} Validation error, duplicate values found: ${duplicate}`);\n }\n }\n\n /**\n * Determines if the field is a wildcard based on the values.\n * When options.rawValue is not empty, it checks if the raw value is a wildcard, otherwise it checks if all values in the range are included.\n * @returns {boolean}\n */\n #isWildcardValue(): boolean {\n if (this.options.rawValue.length > 0) {\n return ['*', '?'].includes(this.options.rawValue);\n }\n\n return Array.from({ length: this.max - this.min + 1 }, (_, i) => i + this.min).every((value) =>\n this.#values.includes(value),\n );\n }\n}\n"
|
|
6
6
|
],
|
|
7
7
|
"mappings": "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",
|
|
8
8
|
"debugId": "327A720EFF1213CF64756E2164756E21",
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/fields/CronHour.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"import { CronField
|
|
5
|
+
"import { CronField } from './CronField.cjs';\nimport type { CronFieldOptions } from './CronField.cjs';\nimport type { CronChars, CronMax, CronMin, HourRange } from './types.cjs';\n\nconst MIN_HOUR = 0;\nconst MAX_HOUR = 23;\nconst HOUR_CHARS: readonly CronChars[] = Object.freeze([]);\n\n/**\n * Represents the \"hour\" field within a cron expression.\n * @class CronHour\n * @extends CronField\n */\nexport class CronHour extends CronField {\n static get min(): CronMin {\n return MIN_HOUR;\n }\n\n static get max(): CronMax {\n return MAX_HOUR;\n }\n\n static get chars(): readonly CronChars[] {\n return HOUR_CHARS;\n }\n\n /**\n * CronHour constructor. Initializes the \"hour\" field with the provided values.\n * @param {HourRange[]} values - Values for the \"hour\" field\n * @param {CronFieldOptions} [options] - Options provided by the parser\n */\n constructor(values: HourRange[], options?: CronFieldOptions) {\n super(values, options);\n this.validate();\n }\n\n /**\n * Returns an array of allowed values for the \"hour\" field.\n * @returns {HourRange[]}\n */\n get values(): HourRange[] {\n return super.values as HourRange[];\n }\n}\n"
|
|
6
6
|
],
|
|
7
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
7
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAA0B,IAA1B;AAIA,IAAM,WAAW;AACjB,IAAM,WAAW;AACjB,IAAM,aAAmC,OAAO,OAAO,CAAC,CAAC;AAAA;AAOlD,MAAM,iBAAiB,2BAAU;AAAA,aAC3B,GAAG,GAAY;AAAA,IACxB,OAAO;AAAA;AAAA,aAGE,GAAG,GAAY;AAAA,IACxB,OAAO;AAAA;AAAA,aAGE,KAAK,GAAyB;AAAA,IACvC,OAAO;AAAA;AAAA,EAQT,WAAW,CAAC,QAAqB,SAA4B;AAAA,IAC3D,MAAM,QAAQ,OAAO;AAAA,IACrB,KAAK,SAAS;AAAA;AAAA,MAOZ,MAAM,GAAgB;AAAA,IACxB,OAAO,MAAM;AAAA;AAEjB;",
|
|
8
8
|
"debugId": "3975ED1A3C63067E64756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/fields/CronMinute.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"import { CronField
|
|
5
|
+
"import { CronField } from './CronField.cjs';\nimport type { CronFieldOptions } from './CronField.cjs';\nimport type { CronChars, CronMax, CronMin, SixtyRange } from './types.cjs';\n\nconst MIN_MINUTE = 0;\nconst MAX_MINUTE = 59;\nconst MINUTE_CHARS: readonly CronChars[] = Object.freeze([]);\n\n/**\n * Represents the \"second\" field within a cron expression.\n * @class CronSecond\n * @extends CronField\n */\nexport class CronMinute extends CronField {\n static get min(): CronMin {\n return MIN_MINUTE;\n }\n\n static get max(): CronMax {\n return MAX_MINUTE;\n }\n\n static get chars(): readonly CronChars[] {\n return MINUTE_CHARS;\n }\n\n /**\n * CronSecond constructor. Initializes the \"second\" field with the provided values.\n * @param {SixtyRange[]} values - Values for the \"second\" field\n * @param {CronFieldOptions} [options] - Options provided by the parser\n */\n constructor(values: SixtyRange[], options?: CronFieldOptions) {\n super(values, options);\n this.validate();\n }\n\n /**\n * Returns an array of allowed values for the \"second\" field.\n * @returns {SixtyRange[]}\n */\n get values(): SixtyRange[] {\n return super.values as SixtyRange[];\n }\n}\n"
|
|
6
6
|
],
|
|
7
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
7
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAA0B,IAA1B;AAIA,IAAM,aAAa;AACnB,IAAM,aAAa;AACnB,IAAM,eAAqC,OAAO,OAAO,CAAC,CAAC;AAAA;AAOpD,MAAM,mBAAmB,2BAAU;AAAA,aAC7B,GAAG,GAAY;AAAA,IACxB,OAAO;AAAA;AAAA,aAGE,GAAG,GAAY;AAAA,IACxB,OAAO;AAAA;AAAA,aAGE,KAAK,GAAyB;AAAA,IACvC,OAAO;AAAA;AAAA,EAQT,WAAW,CAAC,QAAsB,SAA4B;AAAA,IAC5D,MAAM,QAAQ,OAAO;AAAA,IACrB,KAAK,SAAS;AAAA;AAAA,MAOZ,MAAM,GAAiB;AAAA,IACzB,OAAO,MAAM;AAAA;AAEjB;",
|
|
8
8
|
"debugId": "968C526C59BFB4D364756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|