Node.js library for parsing crontab instructions with timezone support, DST handling, and iterator capabilities
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Individual cron field classes with validation, constraints, and special character support for building custom expressions and advanced field manipulation.
Collection container for all cron fields with validation and utilities.
/**
* Creates a new CronFieldCollection instance
* @param fields - Object containing all required cron fields
* @throws Error if any required field is missing or validation fails
*/
constructor(fields: CronFields);
/**
* Creates a new CronFieldCollection by partially overriding fields from an existing one
* @param base - The base CronFieldCollection to copy from
* @param fields - The fields to override (CronField instances or raw values)
* @returns New CronFieldCollection instance
*/
static from(base: CronFieldCollection, fields: CronFieldOverride): CronFieldCollection;
interface CronFields {
second: CronSecond;
minute: CronMinute;
hour: CronHour;
dayOfMonth: CronDayOfMonth;
month: CronMonth;
dayOfWeek: CronDayOfWeek;
}
interface CronFieldOverride {
second?: CronSecond | SixtyRange[];
minute?: CronMinute | SixtyRange[];
hour?: CronHour | HourRange[];
dayOfMonth?: CronDayOfMonth | DayOfMonthRange[];
month?: CronMonth | MonthRange[];
dayOfWeek?: CronDayOfWeek | DayOfWeekRange[];
}Usage Examples:
import {
CronFieldCollection,
CronSecond,
CronMinute,
CronHour,
CronDayOfMonth,
CronMonth,
CronDayOfWeek
} from "cron-parser";
// Create field collection manually
const fields = new CronFieldCollection({
second: new CronSecond([0]),
minute: new CronMinute([0, 30]),
hour: new CronHour([9, 17]),
dayOfMonth: new CronDayOfMonth([1, 15]),
month: new CronMonth([1, 6, 12]),
dayOfWeek: new CronDayOfWeek([1, 2, 3, 4, 5]) // Mon-Fri
});
console.log('Field collection created:', fields.stringify());
// Create modified collection using 'from' method with CronField instances
const modified1 = CronFieldCollection.from(fields, {
hour: new CronHour([12]),
minute: new CronMinute([15, 45])
});
console.log('Modified with CronField instances:', modified1.stringify());
// Create modified collection using raw values
const modified2 = CronFieldCollection.from(fields, {
hour: [8, 12, 16], // Will create new CronHour([8, 12, 16])
dayOfWeek: [6, 0] // Will create new CronDayOfWeek([6, 0]) for weekends
});
console.log('Modified with raw values:', modified2.stringify());Access individual cron fields from the collection.
// Readonly access to individual fields
readonly second: CronSecond; // Seconds field (0-59)
readonly minute: CronMinute; // Minutes field (0-59)
readonly hour: CronHour; // Hours field (0-23)
readonly dayOfMonth: CronDayOfMonth; // Day of month field (1-31, L)
readonly month: CronMonth; // Month field (1-12)
readonly dayOfWeek: CronDayOfWeek; // Day of week field (0-7, L, #)Usage Examples:
const collection = new CronFieldCollection({
second: new CronSecond([0, 30]),
minute: new CronMinute([15]),
hour: new CronHour([9, 13, 17]),
dayOfMonth: new CronDayOfMonth([1, 15]),
month: new CronMonth([1, 4, 7, 10]), // Quarterly
dayOfWeek: new CronDayOfWeek([1]) // Mondays only
});
// Access individual fields
console.log('Second values:', collection.second.values); // [0, 30]
console.log('Minute values:', collection.minute.values); // [15]
console.log('Hour values:', collection.hour.values); // [9, 13, 17]
console.log('Day values:', collection.dayOfMonth.values); // [1, 15]
console.log('Month values:', collection.month.values); // [1, 4, 7, 10]
console.log('Weekday values:', collection.dayOfWeek.values); // [1]
// Check field properties
console.log('Hour is wildcard:', collection.hour.isWildcard); // false
console.log('Month has L char:', collection.month.hasLastChar); // false
console.log('Day of week nth day:', collection.dayOfWeek.nthDay); // 0 (none)
// Field constraints
console.log('Hour min/max:', collection.hour.min, collection.hour.max); // 0, 23
console.log('Month chars:', collection.month.chars); // []Convert field collections back to cron string format.
/**
* Returns a string representation of the cron field values
* @param includeSeconds - Whether to include seconds in the output (default: false)
* @returns The formatted cron string
*/
stringify(includeSeconds?: boolean): string;
/**
* Returns a string representation for a single cron field
* @param field - The cron field to stringify
* @returns The stringified cron field
*/
stringifyField(field: CronField): string;Usage Examples:
const collection = new CronFieldCollection({
second: new CronSecond([0, 15, 30, 45]),
minute: new CronMinute([0]),
hour: new CronHour([9, 13, 17]),
dayOfMonth: new CronDayOfMonth([1, 15]),
month: new CronMonth([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]), // All months
dayOfWeek: new CronDayOfWeek([1, 2, 3, 4, 5]) // Weekdays
});
// 5-field format (no seconds)
console.log('5-field:', collection.stringify()); // "0 9,13,17 1,15 * 1-5"
// 6-field format (with seconds)
console.log('6-field:', collection.stringify(true)); // "*/15 0 9,13,17 1,15 * 1-5"
// Individual field stringification
console.log('Hour field:', collection.stringifyField(collection.hour)); // "9,13,17"
console.log('Second field:', collection.stringifyField(collection.second)); // "*/15"
console.log('Month field:', collection.stringifyField(collection.month)); // "*"
// Compact representation examples
const hourlyOnWeekdays = new CronFieldCollection({
second: new CronSecond([0]),
minute: new CronMinute([0]),
hour: new CronHour([9, 10, 11, 12, 13, 14, 15, 16, 17]), // 9-17 range
dayOfMonth: new CronDayOfMonth(Array.from({length: 31}, (_, i) => i + 1)), // All days
month: new CronMonth([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]), // All months
dayOfWeek: new CronDayOfWeek([1, 2, 3, 4, 5]) // Weekdays
});
console.log('Compact format:', hourlyOnWeekdays.stringify()); // "0 9-17 * * 1-5"Serialize field collections to plain objects for storage or transmission.
/**
* Returns a serialized representation of the cron fields values
* @returns Object containing the cron field values
*/
serialize(): SerializedCronFields;
interface SerializedCronFields {
second: SerializedCronField;
minute: SerializedCronField;
hour: SerializedCronField;
dayOfMonth: SerializedCronField;
month: SerializedCronField;
dayOfWeek: SerializedCronField;
}
interface SerializedCronField {
wildcard: boolean;
values: (number | string)[];
}Usage Examples:
const collection = new CronFieldCollection({
second: new CronSecond([0]),
minute: new CronMinute([0, 30]),
hour: new CronHour([9]),
dayOfMonth: new CronDayOfMonth(['L']), // Last day of month
month: new CronMonth([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]), // Wildcard
dayOfWeek: new CronDayOfWeek([1]) // Monday
});
const serialized = collection.serialize();
console.log('Serialized:', JSON.stringify(serialized, null, 2));
/* Output:
{
"second": { "wildcard": false, "values": [0] },
"minute": { "wildcard": false, "values": [0, 30] },
"hour": { "wildcard": false, "values": [9] },
"dayOfMonth": { "wildcard": false, "values": ["L"] },
"month": { "wildcard": true, "values": [1,2,3,4,5,6,7,8,9,10,11,12] },
"dayOfWeek": { "wildcard": false, "values": [1] }
}
*/
// Use serialized data for storage, transmission, or debugging
const fieldData = collection.serialize();
console.log('Month is wildcard:', fieldData.month.wildcard); // true
console.log('Minute values:', fieldData.minute.values); // [0, 30]
console.log('Special chars in dayOfMonth:', fieldData.dayOfMonth.values); // ["L"]Abstract base class providing common functionality for all field types.
/**
* Abstract base class for all cron fields
*/
abstract class CronField {
// Static properties (implemented by subclasses)
static get min(): CronMin; // Minimum allowed value
static get max(): CronMax; // Maximum allowed value
static get chars(): readonly CronChars[]; // Allowed special characters
static get validChars(): RegExp; // Validation regex
static get constraints(): CronConstraints; // Combined constraints
// Instance properties
get min(): number; // Field minimum value
get max(): number; // Field maximum value
get chars(): readonly string[]; // Field special characters
get hasLastChar(): boolean; // Has 'L' character
get hasQuestionMarkChar(): boolean; // Has '?' character
get isWildcard(): boolean; // Is wildcard field
get values(): CronFieldType; // Field values array
// Instance methods
validate(): void; // Validate field values
serialize(): SerializedCronField; // Serialize field
// Static methods
static sorter(a: number | string, b: number | string): number; // Value sorter
}
interface CronConstraints {
min: CronMin;
max: CronMax;
chars: readonly CronChars[];
validChars: RegExp;
}
interface SerializedCronField {
wildcard: boolean;
values: (number | string)[];
}Usage Examples:
import { CronHour, CronDayOfWeek } from "cron-parser";
// Create field instances
const hourField = new CronHour([9, 10, 11, 12, 13, 14, 15, 16, 17]);
const dowField = new CronDayOfWeek([1, 2, 3, 4, 5]);
// Access static properties via class
console.log('Hour constraints:', CronHour.constraints);
console.log('Hour min/max:', CronHour.min, CronHour.max); // 0, 23
console.log('Hour valid chars:', CronHour.validChars);
console.log('Hour special chars:', CronHour.chars); // []
console.log('DOW constraints:', CronDayOfWeek.constraints);
console.log('DOW min/max:', CronDayOfWeek.min, CronDayOfWeek.max); // 0, 7
console.log('DOW special chars:', CronDayOfWeek.chars); // ['L']
// Access instance properties
console.log('Hour values:', hourField.values); // [9,10,11,12,13,14,15,16,17]
console.log('Hour is wildcard:', hourField.isWildcard); // false
console.log('Hour has L char:', hourField.hasLastChar); // false
console.log('DOW values:', dowField.values); // [1,2,3,4,5]
console.log('DOW is wildcard:', dowField.isWildcard); // false
console.log('DOW has L char:', dowField.hasLastChar); // false
// Validate fields
try {
hourField.validate();
console.log('Hour field is valid');
} catch (error) {
console.log('Hour field validation error:', error.message);
}
// Serialize individual fields
const hourSerialized = hourField.serialize();
console.log('Hour serialized:', hourSerialized);
// { wildcard: false, values: [9,10,11,12,13,14,15,16,17] }Individual field classes with their specific constraints and behavior.
// CronSecond - seconds field (0-59)
class CronSecond extends CronField {
static get min(): 0;
static get max(): 59;
static get chars(): readonly [];
constructor(values: SixtyRange[], options?: CronFieldOptions);
get values(): SixtyRange[];
}
// CronMinute - minutes field (0-59)
class CronMinute extends CronField {
static get min(): 0;
static get max(): 59;
static get chars(): readonly [];
constructor(values: SixtyRange[], options?: CronFieldOptions);
get values(): SixtyRange[];
}
// CronHour - hours field (0-23)
class CronHour extends CronField {
static get min(): 0;
static get max(): 23;
static get chars(): readonly [];
constructor(values: HourRange[], options?: CronFieldOptions);
get values(): HourRange[];
}
// CronDayOfMonth - day of month field (1-31, L)
class CronDayOfMonth extends CronField {
static get min(): 1;
static get max(): 31;
static get chars(): readonly ['L'];
constructor(values: DayOfMonthRange[], options?: CronFieldOptions);
get values(): DayOfMonthRange[];
}
// CronMonth - month field (1-12)
class CronMonth extends CronField {
static get min(): 1;
static get max(): 12;
static get chars(): readonly [];
static get daysInMonth(): readonly number[]; // [31,29,31,30,31,30,31,31,30,31,30,31]
constructor(values: MonthRange[], options?: CronFieldOptions);
get values(): MonthRange[];
}
// CronDayOfWeek - day of week field (0-7, L, supports #)
class CronDayOfWeek extends CronField {
static get min(): 0;
static get max(): 7;
static get chars(): readonly ['L'];
static get validChars(): RegExp; // Includes # character support
constructor(values: DayOfWeekRange[], options?: CronFieldOptions);
get values(): DayOfWeekRange[];
get nthDay(): number; // For # syntax (1-5, 0 if not specified)
}
interface CronFieldOptions {
rawValue?: string; // Original string value
wildcard?: boolean; // Override wildcard detection
nthDayOfWeek?: number; // For # syntax in day of week
}Usage Examples:
// Create specific field types
const seconds = new CronSecond([0, 15, 30, 45]); // Every 15 seconds
const minutes = new CronMinute([0, 30]); // Every 30 minutes
const hours = new CronHour([9, 13, 17]); // 9 AM, 1 PM, 5 PM
const days = new CronDayOfMonth([1, 15, 'L']); // 1st, 15th, and last day
const months = new CronMonth([3, 6, 9, 12]); // Quarterly
const weekdays = new CronDayOfWeek([1, 2, 3, 4, 5]); // Monday through Friday
// Special day of week with nth occurrence
const firstMonday = new CronDayOfWeek([1], { nthDayOfWeek: 1 }); // First Monday
const thirdFriday = new CronDayOfWeek([5], { nthDayOfWeek: 3 }); // Third Friday
console.log('First Monday nth day:', firstMonday.nthDay); // 1
console.log('Third Friday nth day:', thirdFriday.nthDay); // 3
console.log('Regular weekdays nth day:', weekdays.nthDay); // 0
// Access month-specific data
console.log('Days in each month:', CronMonth.daysInMonth);
// [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
// Field validation examples
try {
const invalidHour = new CronHour([25]); // Hour 25 doesn't exist
} catch (error) {
console.log('Invalid hour error:', error.message);
// CronHour Validation error, got value 25 expected range 0-23
}
try {
const invalidMonth = new CronMonth([0, 13]); // Months 0 and 13 don't exist
} catch (error) {
console.log('Invalid month error:', error.message);
// CronMonth Validation error, got value 0 expected range 1-12
}
// Working with special characters
const lastDay = new CronDayOfMonth(['L']); // Last day of month
const lastFriday = new CronDayOfWeek(['5L']); // Last Friday (if supported)
console.log('Last day values:', lastDay.values); // ['L']
console.log('Last day has L char:', lastDay.hasLastChar); // trueInstall with Tessl CLI
npx tessl i tessl/npm-cron-parser