soff-cron 0.0.1
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/LICENSE +21 -0
- package/README.md +300 -0
- package/dist/core/formatter.cjs +2 -0
- package/dist/core/formatter.cjs.map +1 -0
- package/dist/core/formatter.d.cts +19 -0
- package/dist/core/formatter.d.ts +19 -0
- package/dist/core/formatter.js +2 -0
- package/dist/core/formatter.js.map +1 -0
- package/dist/core/parser.cjs +2 -0
- package/dist/core/parser.cjs.map +1 -0
- package/dist/core/parser.d.cts +20 -0
- package/dist/core/parser.d.ts +20 -0
- package/dist/core/parser.js +2 -0
- package/dist/core/parser.js.map +1 -0
- package/dist/core/types.cjs +2 -0
- package/dist/core/types.cjs.map +1 -0
- package/dist/core/types.d.cts +142 -0
- package/dist/core/types.d.ts +142 -0
- package/dist/core/types.js +2 -0
- package/dist/core/types.js.map +1 -0
- package/dist/core/validator.cjs +2 -0
- package/dist/core/validator.cjs.map +1 -0
- package/dist/core/validator.d.cts +19 -0
- package/dist/core/validator.d.ts +19 -0
- package/dist/core/validator.js +2 -0
- package/dist/core/validator.js.map +1 -0
- package/dist/i18n/en.cjs +2 -0
- package/dist/i18n/en.cjs.map +1 -0
- package/dist/i18n/en.d.cts +5 -0
- package/dist/i18n/en.d.ts +5 -0
- package/dist/i18n/en.js +2 -0
- package/dist/i18n/en.js.map +1 -0
- package/dist/i18n/es.cjs +2 -0
- package/dist/i18n/es.cjs.map +1 -0
- package/dist/i18n/es.d.cts +61 -0
- package/dist/i18n/es.d.ts +61 -0
- package/dist/i18n/es.js +2 -0
- package/dist/i18n/es.js.map +1 -0
- package/dist/index.cjs +2 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +4 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/package.json +124 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/types.ts","../src/core/validator.ts","../src/core/parser.ts","../src/i18n/es.ts","../src/i18n/en.ts","../src/core/formatter.ts"],"names":["SPECIAL_KEYWORDS","FIELD_CONSTRAINTS","MONTH_NAMES","DAY_NAMES","validateCron","expression","allowSeconds","trimmed","fields","expectedFields","fieldNames","fieldName","fieldValue","constraints","result","validateField","value","validateStepField","validateListField","validateRangeField","validateSingleValue","parts","range","step","stepNum","startStr","endStr","start","parseFieldValue","end","values","val","num","monthNum","dayNum","parseCron","validation","actualExpression","parseStandardCron","second","minute","hour","dayOfMonth","month","dayOfWeek","parseField","raw","isWildcard","isStep","isRange","isList","generateRange","parseStepField","parseListField","parseRangeField","v","a","b","stepStr","baseValues","i","_constraints","part","rangeValues","es","en","isConsecutiveRange","formatCron","options","locale","use24HourFormat","includeSeconds","verbose","i18n","parsed","formatSpecialKeyword","formatStandardCron","keyword","timePart","formatTime","datePart","formatDate","formattedHour","formatHour","time","formatTime24Hour","formatted","formatTime12Hour","startTime","endTime","formatTimeList","dayPart","formatDaysOfWeek","formatDaysOfMonth","monthPart","formatMonths","period","times","days","dayNames","names","d","formatList","months","monthNames","m","items","last"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Represents a parsed cron expression field with its values\n */\nexport interface CronField {\n /**\n * Raw value from the cron expression (e.g., \"*\", \"0-5\", step values)\n */\n raw: string;\n\n /**\n * Parsed values as an array of numbers\n * For \"*\", this will be all valid values for the field\n * For ranges like \"0-5\", this will be [0, 1, 2, 3, 4, 5]\n * For steps, this will be [0, 15, 30, 45] (example)\n */\n values: number[];\n\n /**\n * Whether this field uses the wildcard \"*\"\n */\n isWildcard: boolean;\n\n /**\n * Whether this field uses a range (e.g., \"0-5\")\n */\n isRange: boolean;\n\n /**\n * Whether this field uses a step value\n */\n isStep: boolean;\n\n /**\n * Whether this field is a list of values (e.g., \"1,3,5\")\n */\n isList: boolean;\n}\n\n/**\n * Represents a fully parsed cron expression\n */\nexport interface ParsedCron {\n /**\n * The original cron expression string\n */\n expression: string;\n\n /**\n * Minute field (0-59)\n */\n minute: CronField;\n\n /**\n * Hour field (0-23)\n */\n hour: CronField;\n\n /**\n * Day of month field (1-31)\n */\n dayOfMonth: CronField;\n\n /**\n * Month field (1-12)\n */\n month: CronField;\n\n /**\n * Day of week field (0-7, where 0 and 7 are Sunday)\n */\n dayOfWeek: CronField;\n\n /**\n * Optional second field (0-59) for 6-field cron expressions\n */\n second?: CronField;\n\n /**\n * Whether this is a special expression like @daily, @hourly, etc.\n */\n isSpecial: boolean;\n\n /**\n * The special keyword if applicable\n */\n specialKeyword?: string;\n}\n\n/**\n * Locale options for formatting\n */\nexport type Locale = 'es' | 'en';\n\n/**\n * Options for formatting cron expressions\n */\nexport interface FormatterOptions {\n /**\n * Locale for the output text\n * @default 'en'\n */\n locale?: Locale;\n\n /**\n * Whether to use 24-hour format for times\n * @default true\n */\n use24HourFormat?: boolean;\n\n /**\n * Whether to include seconds in the output (for 6-field cron)\n * @default false\n */\n includeSeconds?: boolean;\n\n /**\n * Whether to use verbose descriptions\n * @default false\n */\n verbose?: boolean;\n}\n\n/**\n * Validation result for cron expressions\n */\nexport interface ValidationResult {\n /**\n * Whether the cron expression is valid\n */\n isValid: boolean;\n\n /**\n * Error message if validation failed\n */\n error?: string;\n\n /**\n * The field that caused the error (if applicable)\n */\n field?: 'minute' | 'hour' | 'dayOfMonth' | 'month' | 'dayOfWeek' | 'second';\n}\n\n/**\n * Special cron keywords and their equivalents\n */\nexport const SPECIAL_KEYWORDS: Record<string, string> = {\n '@yearly': '0 0 1 1 *',\n '@annually': '0 0 1 1 *',\n '@monthly': '0 0 1 * *',\n '@weekly': '0 0 * * 0',\n '@daily': '0 0 * * *',\n '@midnight': '0 0 * * *',\n '@hourly': '0 * * * *',\n};\n\n/**\n * Field constraints for validation\n */\nexport interface FieldConstraints {\n min: number;\n max: number;\n name: string;\n}\n\nexport const FIELD_CONSTRAINTS: Record<string, FieldConstraints> = {\n minute: { min: 0, max: 59, name: 'minute' },\n hour: { min: 0, max: 23, name: 'hour' },\n dayOfMonth: { min: 1, max: 31, name: 'day of month' },\n month: { min: 1, max: 12, name: 'month' },\n dayOfWeek: { min: 0, max: 7, name: 'day of week' },\n second: { min: 0, max: 59, name: 'second' },\n};\n\n/**\n * Month names mapping (1-12)\n */\nexport const MONTH_NAMES: Record<string, number> = {\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/**\n * Day of week names mapping (0-7)\n */\nexport const DAY_NAMES: Record<string, number> = {\n SUN: 0,\n MON: 1,\n TUE: 2,\n WED: 3,\n THU: 4,\n FRI: 5,\n SAT: 6,\n};\n","import type { ValidationResult, FieldConstraints } from './types.js';\nimport { FIELD_CONSTRAINTS, SPECIAL_KEYWORDS, MONTH_NAMES, DAY_NAMES } from './types.js';\n\n/**\n * Validates a cron expression\n * Supports both 5-field and 6-field (with seconds) cron expressions\n * Also supports special keywords like @daily, @hourly, etc.\n *\n * @param expression - The cron expression to validate\n * @param allowSeconds - Whether to allow 6-field cron expressions with seconds\n * @returns ValidationResult object with isValid flag and optional error message\n *\n * @example\n * validateCron('0 2 * * *') // { isValid: true }\n * validateCron('invalid') // { isValid: false, error: '...' }\n * validateCron('0 0 2 * * *', true) // { isValid: true } (with seconds)\n */\nexport function validateCron(expression: string, allowSeconds = false): ValidationResult {\n if (!expression || typeof expression !== 'string') {\n return {\n isValid: false,\n error: 'Cron expression must be a non-empty string',\n };\n }\n\n const trimmed = expression.trim();\n\n // Check for special keywords\n if (trimmed.startsWith('@')) {\n if (SPECIAL_KEYWORDS[trimmed]) {\n return { isValid: true };\n }\n return {\n isValid: false,\n error: `Unknown special keyword: ${trimmed}`,\n };\n }\n\n // Split into fields\n const fields = trimmed.split(/\\s+/);\n const expectedFields = allowSeconds ? 6 : 5;\n\n if (fields.length !== expectedFields) {\n return {\n isValid: false,\n error: `Expected ${expectedFields} fields, got ${fields.length}`,\n };\n }\n\n // Field order: [second] minute hour dayOfMonth month dayOfWeek\n const fieldNames = allowSeconds\n ? ['second', 'minute', 'hour', 'dayOfMonth', 'month', 'dayOfWeek']\n : ['minute', 'hour', 'dayOfMonth', 'month', 'dayOfWeek'];\n\n // Validate each field\n for (let i = 0; i < fields.length; i++) {\n const fieldName = fieldNames[i];\n const fieldValue = fields[i];\n const constraints = FIELD_CONSTRAINTS[fieldName];\n\n const result = validateField(fieldValue, constraints, fieldName);\n if (!result.isValid) {\n return {\n isValid: false,\n error: result.error,\n field: fieldName as ValidationResult['field'],\n };\n }\n }\n\n return { isValid: true };\n}\n\n/**\n * Validates a single cron field\n */\nfunction validateField(\n value: string,\n constraints: FieldConstraints,\n fieldName: string\n): ValidationResult {\n if (!value) {\n return {\n isValid: false,\n error: `${constraints.name} field cannot be empty`,\n };\n }\n\n // Wildcard is always valid\n if (value === '*') {\n return { isValid: true };\n }\n\n // Question mark (for day fields only)\n if (value === '?') {\n if (fieldName === 'dayOfMonth' || fieldName === 'dayOfWeek') {\n return { isValid: true };\n }\n return {\n isValid: false,\n error: `Question mark (?) is only valid for day fields, not ${constraints.name}`,\n };\n }\n\n // Handle step values (e.g., */15, 0-10/2)\n if (value.includes('/')) {\n return validateStepField(value, constraints, fieldName);\n }\n\n // Handle lists (e.g., 1,3,5 or 1-3,5-7)\n // Check lists before ranges because lists can contain ranges\n if (value.includes(',')) {\n return validateListField(value, constraints, fieldName);\n }\n\n // Handle ranges (e.g., 0-5)\n if (value.includes('-')) {\n return validateRangeField(value, constraints, fieldName);\n }\n\n // Single value\n return validateSingleValue(value, constraints, fieldName);\n}\n\n/**\n * Validates a step field with step syntax\n */\nfunction validateStepField(\n value: string,\n constraints: FieldConstraints,\n fieldName: string\n): ValidationResult {\n const parts = value.split('/');\n if (parts.length !== 2) {\n return {\n isValid: false,\n error: `Invalid step syntax in ${constraints.name}: ${value}`,\n };\n }\n\n const [range, step] = parts;\n\n // Validate step value\n const stepNum = parseInt(step, 10);\n if (isNaN(stepNum) || stepNum <= 0) {\n return {\n isValid: false,\n error: `Invalid step value in ${constraints.name}: ${step}`,\n };\n }\n\n // If range is *, it's valid\n if (range === '*') {\n return { isValid: true };\n }\n\n // If range is a number or range, validate it\n if (range.includes('-')) {\n return validateRangeField(range, constraints, fieldName);\n }\n\n return validateSingleValue(range, constraints, fieldName);\n}\n\n/**\n * Validates a range field (e.g., 0-5)\n */\nfunction validateRangeField(\n value: string,\n constraints: FieldConstraints,\n fieldName: string\n): ValidationResult {\n const parts = value.split('-');\n if (parts.length !== 2) {\n return {\n isValid: false,\n error: `Invalid range syntax in ${constraints.name}: ${value}`,\n };\n }\n\n const [startStr, endStr] = parts;\n const start = parseFieldValue(startStr, fieldName);\n const end = parseFieldValue(endStr, fieldName);\n\n if (start === null) {\n return {\n isValid: false,\n error: `Invalid start value in ${constraints.name} range: ${startStr}`,\n };\n }\n\n if (end === null) {\n return {\n isValid: false,\n error: `Invalid end value in ${constraints.name} range: ${endStr}`,\n };\n }\n\n if (start < constraints.min || start > constraints.max) {\n return {\n isValid: false,\n error: `Start value ${start} is out of range for ${constraints.name} (${constraints.min}-${constraints.max})`,\n };\n }\n\n if (end < constraints.min || end > constraints.max) {\n return {\n isValid: false,\n error: `End value ${end} is out of range for ${constraints.name} (${constraints.min}-${constraints.max})`,\n };\n }\n\n if (start > end) {\n return {\n isValid: false,\n error: `Start value ${start} cannot be greater than end value ${end} in ${constraints.name}`,\n };\n }\n\n return { isValid: true };\n}\n\n/**\n * Validates a list field (e.g., 1,3,5)\n */\nfunction validateListField(\n value: string,\n constraints: FieldConstraints,\n fieldName: string\n): ValidationResult {\n const values = value.split(',');\n\n for (const val of values) {\n const trimmed = val.trim();\n if (!trimmed) {\n return {\n isValid: false,\n error: `Empty value in ${constraints.name} list`,\n };\n }\n\n // Each item can be a single value or a range\n if (trimmed.includes('-')) {\n const result = validateRangeField(trimmed, constraints, fieldName);\n if (!result.isValid) {\n return result;\n }\n } else {\n const result = validateSingleValue(trimmed, constraints, fieldName);\n if (!result.isValid) {\n return result;\n }\n }\n }\n\n return { isValid: true };\n}\n\n/**\n * Validates a single numeric value\n */\nfunction validateSingleValue(\n value: string,\n constraints: FieldConstraints,\n fieldName: string\n): ValidationResult {\n const num = parseFieldValue(value, fieldName);\n\n if (num === null) {\n return {\n isValid: false,\n error: `Invalid value in ${constraints.name}: ${value}`,\n };\n }\n\n if (num < constraints.min || num > constraints.max) {\n return {\n isValid: false,\n error: `Value ${num} is out of range for ${constraints.name} (${constraints.min}-${constraints.max})`,\n };\n }\n\n return { isValid: true };\n}\n\n/**\n * Parses a field value, handling numeric values and named values (MON, JAN, etc.)\n */\nfunction parseFieldValue(value: string, fieldName: string): number | null {\n // Try parsing as number first\n const num = parseInt(value, 10);\n if (!isNaN(num)) {\n return num;\n }\n\n // Try parsing as month name\n if (fieldName === 'month') {\n const monthNum = MONTH_NAMES[value.toUpperCase()];\n if (monthNum !== undefined) {\n return monthNum;\n }\n }\n\n // Try parsing as day name\n if (fieldName === 'dayOfWeek') {\n const dayNum = DAY_NAMES[value.toUpperCase()];\n if (dayNum !== undefined) {\n return dayNum;\n }\n }\n\n return null;\n}\n","import type { ParsedCron, CronField, FieldConstraints } from './types.js';\nimport { FIELD_CONSTRAINTS, SPECIAL_KEYWORDS, MONTH_NAMES, DAY_NAMES } from './types.js';\nimport { validateCron } from './validator.js';\n\n/**\n * Parses a cron expression into a structured format\n *\n * @param expression - The cron expression to parse\n * @param allowSeconds - Whether to allow 6-field cron expressions with seconds\n * @returns ParsedCron object with structured field information\n * @throws Error if the cron expression is invalid\n *\n * @example\n * parseCron('0 2 * * *')\n * // Returns: { minute: { raw: '0', values: [0], ... }, hour: { raw: '2', values: [2], ... }, ... }\n *\n * parseCron('* /15 9-17 * * 1-5')\n * // Returns parsed structure for \"every 15 minutes between 9 AM and 5 PM, Monday to Friday\"\n */\nexport function parseCron(expression: string, allowSeconds = false): ParsedCron {\n // Validate first\n const validation = validateCron(expression, allowSeconds);\n if (!validation.isValid) {\n throw new Error(validation.error || 'Invalid cron expression');\n }\n\n const trimmed = expression.trim();\n\n // Handle special keywords\n if (trimmed.startsWith('@')) {\n const actualExpression = SPECIAL_KEYWORDS[trimmed];\n return {\n expression: trimmed,\n ...parseStandardCron(actualExpression, false),\n isSpecial: true,\n specialKeyword: trimmed,\n };\n }\n\n return {\n expression: trimmed,\n ...parseStandardCron(trimmed, allowSeconds),\n isSpecial: false,\n };\n}\n\n/**\n * Parses a standard cron expression (non-special)\n */\nfunction parseStandardCron(\n expression: string,\n allowSeconds: boolean\n): Omit<ParsedCron, 'expression' | 'isSpecial'> {\n const fields = expression.split(/\\s+/);\n\n if (allowSeconds && fields.length === 6) {\n const [second, minute, hour, dayOfMonth, month, dayOfWeek] = fields;\n return {\n second: parseField(second, FIELD_CONSTRAINTS.second, 'second'),\n minute: parseField(minute, FIELD_CONSTRAINTS.minute, 'minute'),\n hour: parseField(hour, FIELD_CONSTRAINTS.hour, 'hour'),\n dayOfMonth: parseField(dayOfMonth, FIELD_CONSTRAINTS.dayOfMonth, 'dayOfMonth'),\n month: parseField(month, FIELD_CONSTRAINTS.month, 'month'),\n dayOfWeek: parseField(dayOfWeek, FIELD_CONSTRAINTS.dayOfWeek, 'dayOfWeek'),\n };\n }\n\n const [minute, hour, dayOfMonth, month, dayOfWeek] = fields;\n return {\n minute: parseField(minute, FIELD_CONSTRAINTS.minute, 'minute'),\n hour: parseField(hour, FIELD_CONSTRAINTS.hour, 'hour'),\n dayOfMonth: parseField(dayOfMonth, FIELD_CONSTRAINTS.dayOfMonth, 'dayOfMonth'),\n month: parseField(month, FIELD_CONSTRAINTS.month, 'month'),\n dayOfWeek: parseField(dayOfWeek, FIELD_CONSTRAINTS.dayOfWeek, 'dayOfWeek'),\n };\n}\n\n/**\n * Parses a single cron field\n */\nfunction parseField(value: string, constraints: FieldConstraints, fieldName: string): CronField {\n const raw = value;\n const isWildcard = value === '*' || value === '?';\n const isStep = value.includes('/');\n const isRange = value.includes('-') && !isStep;\n const isList = value.includes(',');\n\n let values: number[];\n\n if (isWildcard) {\n // Generate all possible values\n values = generateRange(constraints.min, constraints.max);\n } else if (isStep) {\n values = parseStepField(value, constraints, fieldName);\n } else if (isList) {\n values = parseListField(value, constraints, fieldName);\n } else if (isRange) {\n values = parseRangeField(value, constraints, fieldName);\n } else {\n // Single value\n const num = parseFieldValue(value, fieldName);\n values = num !== null ? [num] : [];\n }\n\n // Normalize day of week (both 0 and 7 are Sunday)\n if (fieldName === 'dayOfWeek') {\n values = values.map((v) => (v === 7 ? 0 : v));\n // Remove duplicates\n values = [...new Set(values)];\n }\n\n // Sort values\n values.sort((a, b) => a - b);\n\n return {\n raw,\n values,\n isWildcard,\n isRange,\n isStep,\n isList,\n };\n}\n\n/**\n * Parses a step field with step syntax\n */\nfunction parseStepField(value: string, constraints: FieldConstraints, fieldName: string): number[] {\n const [range, stepStr] = value.split('/');\n const step = parseInt(stepStr, 10);\n\n let baseValues: number[];\n\n if (range === '*') {\n baseValues = generateRange(constraints.min, constraints.max);\n } else if (range.includes('-')) {\n baseValues = parseRangeField(range, constraints, fieldName);\n } else {\n const num = parseFieldValue(range, fieldName);\n baseValues = num !== null ? [num] : [];\n }\n\n // Apply step\n const result: number[] = [];\n for (let i = 0; i < baseValues.length; i += step) {\n result.push(baseValues[i]);\n }\n\n return result;\n}\n\n/**\n * Parses a range field (e.g., 0-5)\n */\nfunction parseRangeField(\n value: string,\n _constraints: FieldConstraints,\n fieldName: string\n): number[] {\n const [startStr, endStr] = value.split('-');\n const start = parseFieldValue(startStr, fieldName);\n const end = parseFieldValue(endStr, fieldName);\n\n if (start === null || end === null) {\n return [];\n }\n\n return generateRange(start, end);\n}\n\n/**\n * Parses a list field (e.g., 1,3,5)\n */\nfunction parseListField(\n value: string,\n _constraints: FieldConstraints,\n fieldName: string\n): number[] {\n const parts = value.split(',');\n const result: number[] = [];\n\n for (const part of parts) {\n const trimmed = part.trim();\n if (trimmed.includes('-')) {\n const rangeValues = parseRangeField(trimmed, _constraints, fieldName);\n result.push(...rangeValues);\n } else {\n const num = parseFieldValue(trimmed, fieldName);\n if (num !== null) {\n result.push(num);\n }\n }\n }\n\n return result;\n}\n\n/**\n * Parses a field value, handling numeric values and named values (MON, JAN, etc.)\n */\nfunction parseFieldValue(value: string, fieldName: string): number | null {\n // Try parsing as number first\n const num = parseInt(value, 10);\n if (!isNaN(num)) {\n return num;\n }\n\n // Try parsing as month name\n if (fieldName === 'month') {\n const monthNum = MONTH_NAMES[value.toUpperCase()];\n if (monthNum !== undefined) {\n return monthNum;\n }\n }\n\n // Try parsing as day name\n if (fieldName === 'dayOfWeek') {\n const dayNum = DAY_NAMES[value.toUpperCase()];\n if (dayNum !== undefined) {\n return dayNum;\n }\n }\n\n return null;\n}\n\n/**\n * Generates a range of numbers from start to end (inclusive)\n */\nfunction generateRange(start: number, end: number): number[] {\n const result: number[] = [];\n for (let i = start; i <= end; i++) {\n result.push(i);\n }\n return result;\n}\n","/**\n * Internationalization strings for Spanish\n */\nexport interface I18nStrings {\n at: string;\n every: string;\n everyMinute: string;\n everyHour: string;\n everyDay: string;\n everyWeek: string;\n everyMonth: string;\n everyYear: string;\n minute: string;\n minutes: string;\n hour: string;\n hours: string;\n day: string;\n days: string;\n week: string;\n weeks: string;\n month: string;\n months: string;\n year: string;\n years: string;\n on: string;\n in: string;\n and: string;\n between: string;\n through: string;\n of: string;\n second: string;\n seconds: string;\n\n // Day names\n sunday: string;\n monday: string;\n tuesday: string;\n wednesday: string;\n thursday: string;\n friday: string;\n saturday: string;\n\n // Month names\n january: string;\n february: string;\n march: string;\n april: string;\n may: string;\n june: string;\n july: string;\n august: string;\n september: string;\n october: string;\n november: string;\n december: string;\n\n // Time periods\n am: string;\n pm: string;\n midnight: string;\n noon: string;\n\n // Special\n weekday: string;\n weekend: string;\n}\n\nexport const es: I18nStrings = {\n at: 'a las',\n every: 'cada',\n everyMinute: 'cada minuto',\n everyHour: 'cada hora',\n everyDay: 'todos los días',\n everyWeek: 'cada semana',\n everyMonth: 'cada mes',\n everyYear: 'cada año',\n minute: 'minuto',\n minutes: 'minutos',\n hour: 'hora',\n hours: 'horas',\n day: 'día',\n days: 'días',\n week: 'semana',\n weeks: 'semanas',\n month: 'mes',\n months: 'meses',\n year: 'año',\n years: 'años',\n on: 'el',\n in: 'en',\n and: 'y',\n between: 'entre',\n through: 'hasta',\n of: 'de',\n second: 'segundo',\n seconds: 'segundos',\n\n // Day names\n sunday: 'domingo',\n monday: 'lunes',\n tuesday: 'martes',\n wednesday: 'miércoles',\n thursday: 'jueves',\n friday: 'viernes',\n saturday: 'sábado',\n\n // Month names\n january: 'enero',\n february: 'febrero',\n march: 'marzo',\n april: 'abril',\n may: 'mayo',\n june: 'junio',\n july: 'julio',\n august: 'agosto',\n september: 'septiembre',\n october: 'octubre',\n november: 'noviembre',\n december: 'diciembre',\n\n // Time periods\n am: 'AM',\n pm: 'PM',\n midnight: 'medianoche',\n noon: 'mediodía',\n\n // Special\n weekday: 'día de semana',\n weekend: 'fin de semana',\n};\n","import type { I18nStrings } from './es.js';\n\nexport const en: I18nStrings = {\n at: 'at',\n every: 'every',\n everyMinute: 'every minute',\n everyHour: 'every hour',\n everyDay: 'every day',\n everyWeek: 'every week',\n everyMonth: 'every month',\n everyYear: 'every year',\n minute: 'minute',\n minutes: 'minutes',\n hour: 'hour',\n hours: 'hours',\n day: 'day',\n days: 'days',\n week: 'week',\n weeks: 'weeks',\n month: 'month',\n months: 'months',\n year: 'year',\n years: 'years',\n on: 'on',\n in: 'in',\n and: 'and',\n between: 'between',\n through: 'through',\n of: 'of',\n second: 'second',\n seconds: 'seconds',\n\n // Day names\n sunday: 'Sunday',\n monday: 'Monday',\n tuesday: 'Tuesday',\n wednesday: 'Wednesday',\n thursday: 'Thursday',\n friday: 'Friday',\n saturday: 'Saturday',\n\n // Month names\n january: 'January',\n february: 'February',\n march: 'March',\n april: 'April',\n may: 'May',\n june: 'June',\n july: 'July',\n august: 'August',\n september: 'September',\n october: 'October',\n november: 'November',\n december: 'December',\n\n // Time periods\n am: 'AM',\n pm: 'PM',\n midnight: 'midnight',\n noon: 'noon',\n\n // Special\n weekday: 'weekday',\n weekend: 'weekend',\n};\n","import type { ParsedCron, FormatterOptions } from './types.js';\nimport type { I18nStrings } from '../i18n/es.js';\nimport { parseCron } from './parser.js';\nimport { es } from '../i18n/es.js';\nimport { en } from '../i18n/en.js';\n\n/**\n * Helper function to check if an array of numbers is a consecutive range\n */\nfunction isConsecutiveRange(values: number[]): boolean {\n if (values.length < 2) return false;\n for (let i = 1; i < values.length; i++) {\n if (values[i] !== values[i - 1] + 1) {\n return false;\n }\n }\n return true;\n}\n\n/**\n * Formats a cron expression into human-readable text\n *\n * @param expression - The cron expression to format\n * @param options - Formatting options (locale, format preferences)\n * @returns Human-readable description of the cron expression\n *\n * @example\n * formatCron('0 2 * * *', { locale: 'es' })\n * // Returns: \"A las 2:00 AM, todos los días\"\n *\n * formatCron('* /15 9-17 * * 1-5', { locale: 'en' })\n * // Returns: \"Every 15 minutes, between 9:00 AM and 5:00 PM, Monday through Friday\"\n */\nexport function formatCron(expression: string, options: FormatterOptions = {}): string {\n const {\n locale = 'en',\n use24HourFormat = true,\n includeSeconds = false,\n verbose = false,\n } = options;\n\n const i18n = locale === 'es' ? es : en;\n const parsed = parseCron(expression, includeSeconds);\n\n // Handle special keywords\n if (parsed.isSpecial && parsed.specialKeyword) {\n return formatSpecialKeyword(parsed.specialKeyword, i18n);\n }\n\n return formatStandardCron(parsed, i18n, use24HourFormat, verbose);\n}\n\n/**\n * Formats special cron keywords\n */\nfunction formatSpecialKeyword(keyword: string, i18n: I18nStrings): string {\n const map: Record<string, string> = {\n '@yearly': i18n.everyYear,\n '@annually': i18n.everyYear,\n '@monthly': i18n.everyMonth,\n '@weekly': i18n.everyWeek,\n '@daily': i18n.everyDay,\n '@midnight': `${i18n.at} ${i18n.midnight}`,\n '@hourly': i18n.everyHour,\n };\n\n return map[keyword] || keyword;\n}\n\n/**\n * Formats a standard cron expression\n */\nfunction formatStandardCron(\n parsed: ParsedCron,\n i18n: I18nStrings,\n use24HourFormat: boolean,\n verbose: boolean\n): string {\n const parts: string[] = [];\n\n // Time part (seconds, minutes, hours)\n const timePart = formatTime(parsed, i18n, use24HourFormat);\n if (timePart) {\n parts.push(timePart);\n }\n\n // Day/Month part\n const datePart = formatDate(parsed, i18n, verbose);\n if (datePart) {\n parts.push(datePart);\n }\n\n return parts.join(', ');\n}\n\n/**\n * Formats the time portion of a cron expression\n */\nfunction formatTime(parsed: ParsedCron, i18n: I18nStrings, use24HourFormat: boolean): string {\n const { minute, hour, second } = parsed;\n\n // Check for special patterns\n if (minute.isWildcard && hour.isWildcard) {\n if (second && !second.isWildcard) {\n return `${i18n.at} ${i18n.second} ${second.values.join(', ')}`;\n }\n return i18n.everyMinute;\n }\n\n if (minute.isWildcard) {\n // Every minute of specific hours\n if (hour.values.length === 1) {\n const formattedHour = formatHour(hour.values[0], use24HourFormat, i18n);\n return `${i18n.everyMinute} ${i18n.at} ${formattedHour}`;\n }\n if (hour.values.length > 1 && hour.isRange) {\n const start = formatHour(hour.values[0], use24HourFormat, i18n);\n const end = formatHour(hour.values[hour.values.length - 1], use24HourFormat, i18n);\n return `${i18n.everyMinute}, ${i18n.between} ${start} ${i18n.and} ${end}`;\n }\n }\n\n if (hour.isWildcard && !minute.isWildcard) {\n // Every hour at specific minutes\n if (minute.values.length === 1) {\n return `${i18n.at} ${i18n.minute} ${minute.values[0]}`;\n }\n if (minute.isStep) {\n const step = minute.values[1] - minute.values[0];\n return `${i18n.every} ${step} ${i18n.minutes}`;\n }\n }\n\n // Specific time\n if (!minute.isWildcard && !hour.isWildcard) {\n if (minute.values.length === 1 && hour.values.length === 1) {\n const time = formatTime24Hour(hour.values[0], minute.values[0]);\n const formatted = use24HourFormat\n ? time\n : formatTime12Hour(hour.values[0], minute.values[0], i18n);\n return `${i18n.at} ${formatted}`;\n }\n\n // Multiple specific times\n if (minute.values.length > 1 || hour.values.length > 1) {\n // Check if it's a range pattern (consecutive hours with same minute)\n if (\n minute.values.length === 1 &&\n hour.isRange &&\n hour.values.length > 1 &&\n isConsecutiveRange(hour.values)\n ) {\n const startTime = use24HourFormat\n ? formatTime24Hour(hour.values[0], minute.values[0])\n : formatTime12Hour(hour.values[0], minute.values[0], i18n);\n const endTime = use24HourFormat\n ? formatTime24Hour(hour.values[hour.values.length - 1], minute.values[0])\n : formatTime12Hour(hour.values[hour.values.length - 1], minute.values[0], i18n);\n return `${i18n.between} ${startTime} ${i18n.and} ${endTime}`;\n }\n\n if (minute.isStep) {\n const step = minute.values[1] - minute.values[0];\n if (hour.isRange) {\n const start = formatHour(hour.values[0], use24HourFormat, i18n);\n const end = formatHour(hour.values[hour.values.length - 1], use24HourFormat, i18n);\n return `${i18n.every} ${step} ${i18n.minutes}, ${i18n.between} ${start} ${i18n.and} ${end}`;\n }\n return `${i18n.every} ${step} ${i18n.minutes}`;\n }\n }\n }\n\n // Default: list all combinations\n return formatTimeList(parsed, i18n, use24HourFormat);\n}\n\n/**\n * Formats the date portion of a cron expression\n */\nfunction formatDate(parsed: ParsedCron, i18n: I18nStrings, verbose: boolean): string {\n const { dayOfMonth, month, dayOfWeek } = parsed;\n\n // Every day\n if (dayOfMonth.isWildcard && dayOfWeek.isWildcard && month.isWildcard) {\n return i18n.everyDay;\n }\n\n const parts: string[] = [];\n\n // Day of week\n if (!dayOfWeek.isWildcard) {\n const dayPart = formatDaysOfWeek(dayOfWeek.values, i18n, verbose);\n if (dayPart) {\n parts.push(dayPart);\n }\n }\n\n // Day of month\n if (!dayOfMonth.isWildcard && dayOfWeek.isWildcard) {\n const dayPart = formatDaysOfMonth(dayOfMonth.values, i18n, verbose);\n if (dayPart) {\n parts.push(dayPart);\n }\n }\n\n // Month\n if (!month.isWildcard) {\n const monthPart = formatMonths(month.values, i18n, verbose);\n if (monthPart) {\n parts.push(monthPart);\n }\n }\n\n return parts.join(', ');\n}\n\n/**\n * Formats hour in 24-hour format\n */\nfunction formatTime24Hour(hour: number, minute: number): string {\n return `${hour.toString().padStart(2, '0')}:${minute.toString().padStart(2, '0')}`;\n}\n\n/**\n * Formats hour in 12-hour format\n */\nfunction formatTime12Hour(hour: number, minute: number, i18n: I18nStrings): string {\n const period = hour < 12 ? i18n.am : i18n.pm;\n const hour12 = hour === 0 ? 12 : hour > 12 ? hour - 12 : hour;\n return `${hour12}:${minute.toString().padStart(2, '0')} ${period}`;\n}\n\n/**\n * Formats a single hour\n */\nfunction formatHour(hour: number, use24HourFormat: boolean, i18n: I18nStrings): string {\n if (use24HourFormat) {\n return `${hour.toString().padStart(2, '0')}:00`;\n }\n return formatTime12Hour(hour, 0, i18n);\n}\n\n/**\n * Formats a list of times\n */\nfunction formatTimeList(parsed: ParsedCron, i18n: I18nStrings, use24HourFormat: boolean): string {\n const times: string[] = [];\n\n for (const hour of parsed.hour.values) {\n for (const minute of parsed.minute.values) {\n const time = use24HourFormat\n ? formatTime24Hour(hour, minute)\n : formatTime12Hour(hour, minute, i18n);\n times.push(time);\n }\n }\n\n if (times.length <= 3) {\n return `${i18n.at} ${times.join(`, `)}`;\n }\n\n return `${i18n.at} ${times.slice(0, 2).join(', ')}... (${times.length} times)`;\n}\n\n/**\n * Formats days of the week\n */\nfunction formatDaysOfWeek(days: number[], i18n: I18nStrings, verbose: boolean): string {\n const dayNames = [\n i18n.sunday,\n i18n.monday,\n i18n.tuesday,\n i18n.wednesday,\n i18n.thursday,\n i18n.friday,\n i18n.saturday,\n ];\n\n // Check for weekdays (Mon-Fri)\n if (\n days.length === 5 &&\n days.includes(1) &&\n days.includes(2) &&\n days.includes(3) &&\n days.includes(4) &&\n days.includes(5)\n ) {\n return i18n.weekday + 's';\n }\n\n // Check for weekend\n if (days.length === 2 && days.includes(0) && days.includes(6)) {\n return i18n.weekend + 's';\n }\n\n if (days.length === 1) {\n return i18n.on + ' ' + dayNames[days[0]];\n }\n\n if (days.length === 7) {\n return i18n.everyDay;\n }\n\n // List days\n const names = days.map((d) => dayNames[d]);\n if (verbose || days.length <= 3) {\n return formatList(names, i18n);\n }\n\n return `${names[0]} ${i18n.through} ${names[names.length - 1]}`;\n}\n\n/**\n * Formats days of the month\n */\nfunction formatDaysOfMonth(days: number[], i18n: I18nStrings, verbose: boolean): string {\n if (days.length === 1) {\n return `${i18n.on} ${i18n.day} ${days[0]}`;\n }\n\n if (days.length === 31) {\n return i18n.everyDay;\n }\n\n if (verbose || days.length <= 3) {\n return `${i18n.on} ${i18n.days} ${days.join(', ')}`;\n }\n\n return `${i18n.on} ${i18n.days} ${days[0]} ${i18n.through} ${days[days.length - 1]}`;\n}\n\n/**\n * Formats months\n */\nfunction formatMonths(months: number[], i18n: I18nStrings, verbose: boolean): string {\n const monthNames = [\n i18n.january,\n i18n.february,\n i18n.march,\n i18n.april,\n i18n.may,\n i18n.june,\n i18n.july,\n i18n.august,\n i18n.september,\n i18n.october,\n i18n.november,\n i18n.december,\n ];\n\n if (months.length === 1) {\n return `${i18n.in} ${monthNames[months[0] - 1]}`;\n }\n\n if (months.length === 12) {\n return '';\n }\n\n const names = months.map((m) => monthNames[m - 1]);\n if (verbose || months.length <= 3) {\n return `${i18n.in} ${formatList(names, i18n)}`;\n }\n\n return `${i18n.in} ${names[0]} ${i18n.through} ${names[names.length - 1]}`;\n}\n\n/**\n * Formats a list of items with proper grammar\n */\nfunction formatList(items: string[], i18n: I18nStrings): string {\n if (items.length === 0) return '';\n if (items.length === 1) return items[0];\n if (items.length === 2) return `${items[0]} ${i18n.and} ${items[1]}`;\n\n const last = items[items.length - 1];\n const rest = items.slice(0, -1);\n return `${rest.join(', ')}, ${i18n.and} ${last}`;\n}\n"]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { validateCron } from './core/validator.cjs';
|
|
2
|
+
export { parseCron } from './core/parser.cjs';
|
|
3
|
+
export { formatCron } from './core/formatter.cjs';
|
|
4
|
+
export { CronField, DAY_NAMES, FIELD_CONSTRAINTS, FieldConstraints, FormatterOptions, Locale, MONTH_NAMES, ParsedCron, SPECIAL_KEYWORDS, ValidationResult } from './core/types.cjs';
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { validateCron } from './core/validator.js';
|
|
2
|
+
export { parseCron } from './core/parser.js';
|
|
3
|
+
export { formatCron } from './core/formatter.js';
|
|
4
|
+
export { CronField, DAY_NAMES, FIELD_CONSTRAINTS, FieldConstraints, FormatterOptions, Locale, MONTH_NAMES, ParsedCron, SPECIAL_KEYWORDS, ValidationResult } from './core/types.js';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
var g={"@yearly":"0 0 1 1 *","@annually":"0 0 1 1 *","@monthly":"0 0 1 * *","@weekly":"0 0 * * 0","@daily":"0 0 * * *","@midnight":"0 0 * * *","@hourly":"0 * * * *"},l={minute:{min:0,max:59,name:"minute"},hour:{min:0,max:23,name:"hour"},dayOfMonth:{min:1,max:31,name:"day of month"},month:{min:1,max:12,name:"month"},dayOfWeek:{min:0,max:7,name:"day of week"},second:{min:0,max:59,name:"second"}},c={JAN:1,FEB:2,MAR:3,APR:4,MAY:5,JUN:6,JUL:7,AUG:8,SEP:9,OCT:10,NOV:11,DEC:12},y={SUN:0,MON:1,TUE:2,WED:3,THU:4,FRI:5,SAT:6};function S(r,e=false){if(!r||typeof r!="string")return {isValid:false,error:"Cron expression must be a non-empty string"};let t=r.trim();if(t.startsWith("@"))return g[t]?{isValid:true}:{isValid:false,error:`Unknown special keyword: ${t}`};let n=t.split(/\s+/),s=e?6:5;if(n.length!==s)return {isValid:false,error:`Expected ${s} fields, got ${n.length}`};let a=e?["second","minute","hour","dayOfMonth","month","dayOfWeek"]:["minute","hour","dayOfMonth","month","dayOfWeek"];for(let i=0;i<n.length;i++){let o=a[i],u=n[i],d=l[o],f=E(u,d,o);if(!f.isValid)return {isValid:false,error:f.error,field:o}}return {isValid:true}}function E(r,e,t){return r?r==="*"?{isValid:true}:r==="?"?t==="dayOfMonth"||t==="dayOfWeek"?{isValid:true}:{isValid:false,error:`Question mark (?) is only valid for day fields, not ${e.name}`}:r.includes("/")?j(r,e,t):r.includes(",")?D(r,e,t):r.includes("-")?C(r,e,t):O(r,e,t):{isValid:false,error:`${e.name} field cannot be empty`}}function j(r,e,t){let n=r.split("/");if(n.length!==2)return {isValid:false,error:`Invalid step syntax in ${e.name}: ${r}`};let[s,a]=n,i=parseInt(a,10);return isNaN(i)||i<=0?{isValid:false,error:`Invalid step value in ${e.name}: ${a}`}:s==="*"?{isValid:true}:s.includes("-")?C(s,e,t):O(s,e,t)}function C(r,e,t){let n=r.split("-");if(n.length!==2)return {isValid:false,error:`Invalid range syntax in ${e.name}: ${r}`};let[s,a]=n,i=b(s,t),o=b(a,t);return i===null?{isValid:false,error:`Invalid start value in ${e.name} range: ${s}`}:o===null?{isValid:false,error:`Invalid end value in ${e.name} range: ${a}`}:i<e.min||i>e.max?{isValid:false,error:`Start value ${i} is out of range for ${e.name} (${e.min}-${e.max})`}:o<e.min||o>e.max?{isValid:false,error:`End value ${o} is out of range for ${e.name} (${e.min}-${e.max})`}:i>o?{isValid:false,error:`Start value ${i} cannot be greater than end value ${o} in ${e.name}`}:{isValid:true}}function D(r,e,t){let n=r.split(",");for(let s of n){let a=s.trim();if(!a)return {isValid:false,error:`Empty value in ${e.name} list`};if(a.includes("-")){let i=C(a,e,t);if(!i.isValid)return i}else {let i=O(a,e,t);if(!i.isValid)return i}}return {isValid:true}}function O(r,e,t){let n=b(r,t);return n===null?{isValid:false,error:`Invalid value in ${e.name}: ${r}`}:n<e.min||n>e.max?{isValid:false,error:`Value ${n} is out of range for ${e.name} (${e.min}-${e.max})`}:{isValid:true}}function b(r,e){let t=parseInt(r,10);if(!isNaN(t))return t;if(e==="month"){let n=c[r.toUpperCase()];if(n!==void 0)return n}if(e==="dayOfWeek"){let n=y[r.toUpperCase()];if(n!==void 0)return n}return null}function M(r,e=false){let t=S(r,e);if(!t.isValid)throw new Error(t.error||"Invalid cron expression");let n=r.trim();if(n.startsWith("@")){let s=g[n];return {expression:n,...k(s,false),isSpecial:true,specialKeyword:n}}return {expression:n,...k(n,e),isSpecial:false}}function k(r,e){let t=r.split(/\s+/);if(e&&t.length===6){let[u,d,f,I,R,A]=t;return {second:m(u,l.second,"second"),minute:m(d,l.minute,"minute"),hour:m(f,l.hour,"hour"),dayOfMonth:m(I,l.dayOfMonth,"dayOfMonth"),month:m(R,l.month,"month"),dayOfWeek:m(A,l.dayOfWeek,"dayOfWeek")}}let[n,s,a,i,o]=t;return {minute:m(n,l.minute,"minute"),hour:m(s,l.hour,"hour"),dayOfMonth:m(a,l.dayOfMonth,"dayOfMonth"),month:m(i,l.month,"month"),dayOfWeek:m(o,l.dayOfWeek,"dayOfWeek")}}function m(r,e,t){let n=r,s=r==="*"||r==="?",a=r.includes("/"),i=r.includes("-")&&!a,o=r.includes(","),u;if(s)u=W(e.min,e.max);else if(a)u=N(r,e,t);else if(o)u=T(r,e,t);else if(i)u=V(r,e,t);else {let d=h(r,t);u=d!==null?[d]:[];}return t==="dayOfWeek"&&(u=u.map(d=>d===7?0:d),u=[...new Set(u)]),u.sort((d,f)=>d-f),{raw:n,values:u,isWildcard:s,isRange:i,isStep:a,isList:o}}function N(r,e,t){let[n,s]=r.split("/"),a=parseInt(s,10),i;if(n==="*")i=W(e.min,e.max);else if(n.includes("-"))i=V(n,e,t);else {let u=h(n,t);i=u!==null?[u]:[];}let o=[];for(let u=0;u<i.length;u+=a)o.push(i[u]);return o}function V(r,e,t){let[n,s]=r.split("-"),a=h(n,t),i=h(s,t);return a===null||i===null?[]:W(a,i)}function T(r,e,t){let n=r.split(","),s=[];for(let a of n){let i=a.trim();if(i.includes("-")){let o=V(i,e,t);s.push(...o);}else {let o=h(i,t);o!==null&&s.push(o);}}return s}function h(r,e){let t=parseInt(r,10);if(!isNaN(t))return t;if(e==="month"){let n=c[r.toUpperCase()];if(n!==void 0)return n}if(e==="dayOfWeek"){let n=y[r.toUpperCase()];if(n!==void 0)return n}return null}function W(r,e){let t=[];for(let n=r;n<=e;n++)t.push(n);return t}var x={at:"a las",every:"cada",everyMinute:"cada minuto",everyHour:"cada hora",everyDay:"todos los d\xEDas",everyWeek:"cada semana",everyMonth:"cada mes",everyYear:"cada a\xF1o",minute:"minuto",minutes:"minutos",day:"d\xEDa",days:"d\xEDas",on:"el",in:"en",and:"y",between:"entre",through:"hasta",second:"segundo",sunday:"domingo",monday:"lunes",tuesday:"martes",wednesday:"mi\xE9rcoles",thursday:"jueves",friday:"viernes",saturday:"s\xE1bado",january:"enero",february:"febrero",march:"marzo",april:"abril",may:"mayo",june:"junio",july:"julio",august:"agosto",september:"septiembre",october:"octubre",november:"noviembre",december:"diciembre",am:"AM",pm:"PM",midnight:"medianoche",weekday:"d\xEDa de semana",weekend:"fin de semana"};var w={at:"at",every:"every",everyMinute:"every minute",everyHour:"every hour",everyDay:"every day",everyWeek:"every week",everyMonth:"every month",everyYear:"every year",minute:"minute",minutes:"minutes",day:"day",days:"days",on:"on",in:"in",and:"and",between:"between",through:"through",second:"second",sunday:"Sunday",monday:"Monday",tuesday:"Tuesday",wednesday:"Wednesday",thursday:"Thursday",friday:"Friday",saturday:"Saturday",january:"January",february:"February",march:"March",april:"April",may:"May",june:"June",july:"July",august:"August",september:"September",october:"October",november:"November",december:"December",am:"AM",pm:"PM",midnight:"midnight",weekday:"weekday",weekend:"weekend"};function P(r){if(r.length<2)return false;for(let e=1;e<r.length;e++)if(r[e]!==r[e-1]+1)return false;return true}function L(r,e={}){let{locale:t="en",use24HourFormat:n=true,includeSeconds:s=false,verbose:a=false}=e,i=t==="es"?x:w,o=M(r,s);return o.isSpecial&&o.specialKeyword?_(o.specialKeyword,i):Y(o,i,n,a)}function _(r,e){return {"@yearly":e.everyYear,"@annually":e.everyYear,"@monthly":e.everyMonth,"@weekly":e.everyWeek,"@daily":e.everyDay,"@midnight":`${e.at} ${e.midnight}`,"@hourly":e.everyHour}[r]||r}function Y(r,e,t,n){let s=[],a=U(r,e,t);a&&s.push(a);let i=K(r,e,n);return i&&s.push(i),s.join(", ")}function U(r,e,t){let{minute:n,hour:s,second:a}=r;if(n.isWildcard&&s.isWildcard)return a&&!a.isWildcard?`${e.at} ${e.second} ${a.values.join(", ")}`:e.everyMinute;if(n.isWildcard){if(s.values.length===1){let i=p(s.values[0],t,e);return `${e.everyMinute} ${e.at} ${i}`}if(s.values.length>1&&s.isRange){let i=p(s.values[0],t,e),o=p(s.values[s.values.length-1],t,e);return `${e.everyMinute}, ${e.between} ${i} ${e.and} ${o}`}}if(s.isWildcard&&!n.isWildcard){if(n.values.length===1)return `${e.at} ${e.minute} ${n.values[0]}`;if(n.isStep){let i=n.values[1]-n.values[0];return `${e.every} ${i} ${e.minutes}`}}if(!n.isWildcard&&!s.isWildcard){if(n.values.length===1&&s.values.length===1){let i=v(s.values[0],n.values[0]),o=t?i:$(s.values[0],n.values[0],e);return `${e.at} ${o}`}if(n.values.length>1||s.values.length>1){if(n.values.length===1&&s.isRange&&s.values.length>1&&P(s.values)){let i=t?v(s.values[0],n.values[0]):$(s.values[0],n.values[0],e),o=t?v(s.values[s.values.length-1],n.values[0]):$(s.values[s.values.length-1],n.values[0],e);return `${e.between} ${i} ${e.and} ${o}`}if(n.isStep){let i=n.values[1]-n.values[0];if(s.isRange){let o=p(s.values[0],t,e),u=p(s.values[s.values.length-1],t,e);return `${e.every} ${i} ${e.minutes}, ${e.between} ${o} ${e.and} ${u}`}return `${e.every} ${i} ${e.minutes}`}}}return H(r,e,t)}function K(r,e,t){let{dayOfMonth:n,month:s,dayOfWeek:a}=r;if(n.isWildcard&&a.isWildcard&&s.isWildcard)return e.everyDay;let i=[];if(!a.isWildcard){let o=J(a.values,e,t);o&&i.push(o);}if(!n.isWildcard&&a.isWildcard){let o=z(n.values,e,t);o&&i.push(o);}if(!s.isWildcard){let o=B(s.values,e,t);o&&i.push(o);}return i.join(", ")}function v(r,e){return `${r.toString().padStart(2,"0")}:${e.toString().padStart(2,"0")}`}function $(r,e,t){let n=r<12?t.am:t.pm;return `${r===0?12:r>12?r-12:r}:${e.toString().padStart(2,"0")} ${n}`}function p(r,e,t){return e?`${r.toString().padStart(2,"0")}:00`:$(r,0,t)}function H(r,e,t){let n=[];for(let s of r.hour.values)for(let a of r.minute.values){let i=t?v(s,a):$(s,a,e);n.push(i);}return n.length<=3?`${e.at} ${n.join(", ")}`:`${e.at} ${n.slice(0,2).join(", ")}... (${n.length} times)`}function J(r,e,t){let n=[e.sunday,e.monday,e.tuesday,e.wednesday,e.thursday,e.friday,e.saturday];if(r.length===5&&r.includes(1)&&r.includes(2)&&r.includes(3)&&r.includes(4)&&r.includes(5))return e.weekday+"s";if(r.length===2&&r.includes(0)&&r.includes(6))return e.weekend+"s";if(r.length===1)return e.on+" "+n[r[0]];if(r.length===7)return e.everyDay;let s=r.map(a=>n[a]);return t||r.length<=3?F(s,e):`${s[0]} ${e.through} ${s[s.length-1]}`}function z(r,e,t){return r.length===1?`${e.on} ${e.day} ${r[0]}`:r.length===31?e.everyDay:t||r.length<=3?`${e.on} ${e.days} ${r.join(", ")}`:`${e.on} ${e.days} ${r[0]} ${e.through} ${r[r.length-1]}`}function B(r,e,t){let n=[e.january,e.february,e.march,e.april,e.may,e.june,e.july,e.august,e.september,e.october,e.november,e.december];if(r.length===1)return `${e.in} ${n[r[0]-1]}`;if(r.length===12)return "";let s=r.map(a=>n[a-1]);return t||r.length<=3?`${e.in} ${F(s,e)}`:`${e.in} ${s[0]} ${e.through} ${s[s.length-1]}`}function F(r,e){if(r.length===0)return "";if(r.length===1)return r[0];if(r.length===2)return `${r[0]} ${e.and} ${r[1]}`;let t=r[r.length-1];return `${r.slice(0,-1).join(", ")}, ${e.and} ${t}`}export{y as DAY_NAMES,l as FIELD_CONSTRAINTS,c as MONTH_NAMES,g as SPECIAL_KEYWORDS,L as formatCron,M as parseCron,S as validateCron};//# sourceMappingURL=index.js.map
|
|
2
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/types.ts","../src/core/validator.ts","../src/core/parser.ts","../src/i18n/es.ts","../src/i18n/en.ts","../src/core/formatter.ts"],"names":["SPECIAL_KEYWORDS","FIELD_CONSTRAINTS","MONTH_NAMES","DAY_NAMES","validateCron","expression","allowSeconds","trimmed","fields","expectedFields","fieldNames","fieldName","fieldValue","constraints","result","validateField","value","validateStepField","validateListField","validateRangeField","validateSingleValue","parts","range","step","stepNum","startStr","endStr","start","parseFieldValue","end","values","val","num","monthNum","dayNum","parseCron","validation","actualExpression","parseStandardCron","second","minute","hour","dayOfMonth","month","dayOfWeek","parseField","raw","isWildcard","isStep","isRange","isList","generateRange","parseStepField","parseListField","parseRangeField","v","a","b","stepStr","baseValues","i","_constraints","part","rangeValues","es","en","isConsecutiveRange","formatCron","options","locale","use24HourFormat","includeSeconds","verbose","i18n","parsed","formatSpecialKeyword","formatStandardCron","keyword","timePart","formatTime","datePart","formatDate","formattedHour","formatHour","time","formatTime24Hour","formatted","formatTime12Hour","startTime","endTime","formatTimeList","dayPart","formatDaysOfWeek","formatDaysOfMonth","monthPart","formatMonths","period","times","days","dayNames","names","d","formatList","months","monthNames","m","items","last"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Represents a parsed cron expression field with its values\n */\nexport interface CronField {\n /**\n * Raw value from the cron expression (e.g., \"*\", \"0-5\", step values)\n */\n raw: string;\n\n /**\n * Parsed values as an array of numbers\n * For \"*\", this will be all valid values for the field\n * For ranges like \"0-5\", this will be [0, 1, 2, 3, 4, 5]\n * For steps, this will be [0, 15, 30, 45] (example)\n */\n values: number[];\n\n /**\n * Whether this field uses the wildcard \"*\"\n */\n isWildcard: boolean;\n\n /**\n * Whether this field uses a range (e.g., \"0-5\")\n */\n isRange: boolean;\n\n /**\n * Whether this field uses a step value\n */\n isStep: boolean;\n\n /**\n * Whether this field is a list of values (e.g., \"1,3,5\")\n */\n isList: boolean;\n}\n\n/**\n * Represents a fully parsed cron expression\n */\nexport interface ParsedCron {\n /**\n * The original cron expression string\n */\n expression: string;\n\n /**\n * Minute field (0-59)\n */\n minute: CronField;\n\n /**\n * Hour field (0-23)\n */\n hour: CronField;\n\n /**\n * Day of month field (1-31)\n */\n dayOfMonth: CronField;\n\n /**\n * Month field (1-12)\n */\n month: CronField;\n\n /**\n * Day of week field (0-7, where 0 and 7 are Sunday)\n */\n dayOfWeek: CronField;\n\n /**\n * Optional second field (0-59) for 6-field cron expressions\n */\n second?: CronField;\n\n /**\n * Whether this is a special expression like @daily, @hourly, etc.\n */\n isSpecial: boolean;\n\n /**\n * The special keyword if applicable\n */\n specialKeyword?: string;\n}\n\n/**\n * Locale options for formatting\n */\nexport type Locale = 'es' | 'en';\n\n/**\n * Options for formatting cron expressions\n */\nexport interface FormatterOptions {\n /**\n * Locale for the output text\n * @default 'en'\n */\n locale?: Locale;\n\n /**\n * Whether to use 24-hour format for times\n * @default true\n */\n use24HourFormat?: boolean;\n\n /**\n * Whether to include seconds in the output (for 6-field cron)\n * @default false\n */\n includeSeconds?: boolean;\n\n /**\n * Whether to use verbose descriptions\n * @default false\n */\n verbose?: boolean;\n}\n\n/**\n * Validation result for cron expressions\n */\nexport interface ValidationResult {\n /**\n * Whether the cron expression is valid\n */\n isValid: boolean;\n\n /**\n * Error message if validation failed\n */\n error?: string;\n\n /**\n * The field that caused the error (if applicable)\n */\n field?: 'minute' | 'hour' | 'dayOfMonth' | 'month' | 'dayOfWeek' | 'second';\n}\n\n/**\n * Special cron keywords and their equivalents\n */\nexport const SPECIAL_KEYWORDS: Record<string, string> = {\n '@yearly': '0 0 1 1 *',\n '@annually': '0 0 1 1 *',\n '@monthly': '0 0 1 * *',\n '@weekly': '0 0 * * 0',\n '@daily': '0 0 * * *',\n '@midnight': '0 0 * * *',\n '@hourly': '0 * * * *',\n};\n\n/**\n * Field constraints for validation\n */\nexport interface FieldConstraints {\n min: number;\n max: number;\n name: string;\n}\n\nexport const FIELD_CONSTRAINTS: Record<string, FieldConstraints> = {\n minute: { min: 0, max: 59, name: 'minute' },\n hour: { min: 0, max: 23, name: 'hour' },\n dayOfMonth: { min: 1, max: 31, name: 'day of month' },\n month: { min: 1, max: 12, name: 'month' },\n dayOfWeek: { min: 0, max: 7, name: 'day of week' },\n second: { min: 0, max: 59, name: 'second' },\n};\n\n/**\n * Month names mapping (1-12)\n */\nexport const MONTH_NAMES: Record<string, number> = {\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/**\n * Day of week names mapping (0-7)\n */\nexport const DAY_NAMES: Record<string, number> = {\n SUN: 0,\n MON: 1,\n TUE: 2,\n WED: 3,\n THU: 4,\n FRI: 5,\n SAT: 6,\n};\n","import type { ValidationResult, FieldConstraints } from './types.js';\nimport { FIELD_CONSTRAINTS, SPECIAL_KEYWORDS, MONTH_NAMES, DAY_NAMES } from './types.js';\n\n/**\n * Validates a cron expression\n * Supports both 5-field and 6-field (with seconds) cron expressions\n * Also supports special keywords like @daily, @hourly, etc.\n *\n * @param expression - The cron expression to validate\n * @param allowSeconds - Whether to allow 6-field cron expressions with seconds\n * @returns ValidationResult object with isValid flag and optional error message\n *\n * @example\n * validateCron('0 2 * * *') // { isValid: true }\n * validateCron('invalid') // { isValid: false, error: '...' }\n * validateCron('0 0 2 * * *', true) // { isValid: true } (with seconds)\n */\nexport function validateCron(expression: string, allowSeconds = false): ValidationResult {\n if (!expression || typeof expression !== 'string') {\n return {\n isValid: false,\n error: 'Cron expression must be a non-empty string',\n };\n }\n\n const trimmed = expression.trim();\n\n // Check for special keywords\n if (trimmed.startsWith('@')) {\n if (SPECIAL_KEYWORDS[trimmed]) {\n return { isValid: true };\n }\n return {\n isValid: false,\n error: `Unknown special keyword: ${trimmed}`,\n };\n }\n\n // Split into fields\n const fields = trimmed.split(/\\s+/);\n const expectedFields = allowSeconds ? 6 : 5;\n\n if (fields.length !== expectedFields) {\n return {\n isValid: false,\n error: `Expected ${expectedFields} fields, got ${fields.length}`,\n };\n }\n\n // Field order: [second] minute hour dayOfMonth month dayOfWeek\n const fieldNames = allowSeconds\n ? ['second', 'minute', 'hour', 'dayOfMonth', 'month', 'dayOfWeek']\n : ['minute', 'hour', 'dayOfMonth', 'month', 'dayOfWeek'];\n\n // Validate each field\n for (let i = 0; i < fields.length; i++) {\n const fieldName = fieldNames[i];\n const fieldValue = fields[i];\n const constraints = FIELD_CONSTRAINTS[fieldName];\n\n const result = validateField(fieldValue, constraints, fieldName);\n if (!result.isValid) {\n return {\n isValid: false,\n error: result.error,\n field: fieldName as ValidationResult['field'],\n };\n }\n }\n\n return { isValid: true };\n}\n\n/**\n * Validates a single cron field\n */\nfunction validateField(\n value: string,\n constraints: FieldConstraints,\n fieldName: string\n): ValidationResult {\n if (!value) {\n return {\n isValid: false,\n error: `${constraints.name} field cannot be empty`,\n };\n }\n\n // Wildcard is always valid\n if (value === '*') {\n return { isValid: true };\n }\n\n // Question mark (for day fields only)\n if (value === '?') {\n if (fieldName === 'dayOfMonth' || fieldName === 'dayOfWeek') {\n return { isValid: true };\n }\n return {\n isValid: false,\n error: `Question mark (?) is only valid for day fields, not ${constraints.name}`,\n };\n }\n\n // Handle step values (e.g., */15, 0-10/2)\n if (value.includes('/')) {\n return validateStepField(value, constraints, fieldName);\n }\n\n // Handle lists (e.g., 1,3,5 or 1-3,5-7)\n // Check lists before ranges because lists can contain ranges\n if (value.includes(',')) {\n return validateListField(value, constraints, fieldName);\n }\n\n // Handle ranges (e.g., 0-5)\n if (value.includes('-')) {\n return validateRangeField(value, constraints, fieldName);\n }\n\n // Single value\n return validateSingleValue(value, constraints, fieldName);\n}\n\n/**\n * Validates a step field with step syntax\n */\nfunction validateStepField(\n value: string,\n constraints: FieldConstraints,\n fieldName: string\n): ValidationResult {\n const parts = value.split('/');\n if (parts.length !== 2) {\n return {\n isValid: false,\n error: `Invalid step syntax in ${constraints.name}: ${value}`,\n };\n }\n\n const [range, step] = parts;\n\n // Validate step value\n const stepNum = parseInt(step, 10);\n if (isNaN(stepNum) || stepNum <= 0) {\n return {\n isValid: false,\n error: `Invalid step value in ${constraints.name}: ${step}`,\n };\n }\n\n // If range is *, it's valid\n if (range === '*') {\n return { isValid: true };\n }\n\n // If range is a number or range, validate it\n if (range.includes('-')) {\n return validateRangeField(range, constraints, fieldName);\n }\n\n return validateSingleValue(range, constraints, fieldName);\n}\n\n/**\n * Validates a range field (e.g., 0-5)\n */\nfunction validateRangeField(\n value: string,\n constraints: FieldConstraints,\n fieldName: string\n): ValidationResult {\n const parts = value.split('-');\n if (parts.length !== 2) {\n return {\n isValid: false,\n error: `Invalid range syntax in ${constraints.name}: ${value}`,\n };\n }\n\n const [startStr, endStr] = parts;\n const start = parseFieldValue(startStr, fieldName);\n const end = parseFieldValue(endStr, fieldName);\n\n if (start === null) {\n return {\n isValid: false,\n error: `Invalid start value in ${constraints.name} range: ${startStr}`,\n };\n }\n\n if (end === null) {\n return {\n isValid: false,\n error: `Invalid end value in ${constraints.name} range: ${endStr}`,\n };\n }\n\n if (start < constraints.min || start > constraints.max) {\n return {\n isValid: false,\n error: `Start value ${start} is out of range for ${constraints.name} (${constraints.min}-${constraints.max})`,\n };\n }\n\n if (end < constraints.min || end > constraints.max) {\n return {\n isValid: false,\n error: `End value ${end} is out of range for ${constraints.name} (${constraints.min}-${constraints.max})`,\n };\n }\n\n if (start > end) {\n return {\n isValid: false,\n error: `Start value ${start} cannot be greater than end value ${end} in ${constraints.name}`,\n };\n }\n\n return { isValid: true };\n}\n\n/**\n * Validates a list field (e.g., 1,3,5)\n */\nfunction validateListField(\n value: string,\n constraints: FieldConstraints,\n fieldName: string\n): ValidationResult {\n const values = value.split(',');\n\n for (const val of values) {\n const trimmed = val.trim();\n if (!trimmed) {\n return {\n isValid: false,\n error: `Empty value in ${constraints.name} list`,\n };\n }\n\n // Each item can be a single value or a range\n if (trimmed.includes('-')) {\n const result = validateRangeField(trimmed, constraints, fieldName);\n if (!result.isValid) {\n return result;\n }\n } else {\n const result = validateSingleValue(trimmed, constraints, fieldName);\n if (!result.isValid) {\n return result;\n }\n }\n }\n\n return { isValid: true };\n}\n\n/**\n * Validates a single numeric value\n */\nfunction validateSingleValue(\n value: string,\n constraints: FieldConstraints,\n fieldName: string\n): ValidationResult {\n const num = parseFieldValue(value, fieldName);\n\n if (num === null) {\n return {\n isValid: false,\n error: `Invalid value in ${constraints.name}: ${value}`,\n };\n }\n\n if (num < constraints.min || num > constraints.max) {\n return {\n isValid: false,\n error: `Value ${num} is out of range for ${constraints.name} (${constraints.min}-${constraints.max})`,\n };\n }\n\n return { isValid: true };\n}\n\n/**\n * Parses a field value, handling numeric values and named values (MON, JAN, etc.)\n */\nfunction parseFieldValue(value: string, fieldName: string): number | null {\n // Try parsing as number first\n const num = parseInt(value, 10);\n if (!isNaN(num)) {\n return num;\n }\n\n // Try parsing as month name\n if (fieldName === 'month') {\n const monthNum = MONTH_NAMES[value.toUpperCase()];\n if (monthNum !== undefined) {\n return monthNum;\n }\n }\n\n // Try parsing as day name\n if (fieldName === 'dayOfWeek') {\n const dayNum = DAY_NAMES[value.toUpperCase()];\n if (dayNum !== undefined) {\n return dayNum;\n }\n }\n\n return null;\n}\n","import type { ParsedCron, CronField, FieldConstraints } from './types.js';\nimport { FIELD_CONSTRAINTS, SPECIAL_KEYWORDS, MONTH_NAMES, DAY_NAMES } from './types.js';\nimport { validateCron } from './validator.js';\n\n/**\n * Parses a cron expression into a structured format\n *\n * @param expression - The cron expression to parse\n * @param allowSeconds - Whether to allow 6-field cron expressions with seconds\n * @returns ParsedCron object with structured field information\n * @throws Error if the cron expression is invalid\n *\n * @example\n * parseCron('0 2 * * *')\n * // Returns: { minute: { raw: '0', values: [0], ... }, hour: { raw: '2', values: [2], ... }, ... }\n *\n * parseCron('* /15 9-17 * * 1-5')\n * // Returns parsed structure for \"every 15 minutes between 9 AM and 5 PM, Monday to Friday\"\n */\nexport function parseCron(expression: string, allowSeconds = false): ParsedCron {\n // Validate first\n const validation = validateCron(expression, allowSeconds);\n if (!validation.isValid) {\n throw new Error(validation.error || 'Invalid cron expression');\n }\n\n const trimmed = expression.trim();\n\n // Handle special keywords\n if (trimmed.startsWith('@')) {\n const actualExpression = SPECIAL_KEYWORDS[trimmed];\n return {\n expression: trimmed,\n ...parseStandardCron(actualExpression, false),\n isSpecial: true,\n specialKeyword: trimmed,\n };\n }\n\n return {\n expression: trimmed,\n ...parseStandardCron(trimmed, allowSeconds),\n isSpecial: false,\n };\n}\n\n/**\n * Parses a standard cron expression (non-special)\n */\nfunction parseStandardCron(\n expression: string,\n allowSeconds: boolean\n): Omit<ParsedCron, 'expression' | 'isSpecial'> {\n const fields = expression.split(/\\s+/);\n\n if (allowSeconds && fields.length === 6) {\n const [second, minute, hour, dayOfMonth, month, dayOfWeek] = fields;\n return {\n second: parseField(second, FIELD_CONSTRAINTS.second, 'second'),\n minute: parseField(minute, FIELD_CONSTRAINTS.minute, 'minute'),\n hour: parseField(hour, FIELD_CONSTRAINTS.hour, 'hour'),\n dayOfMonth: parseField(dayOfMonth, FIELD_CONSTRAINTS.dayOfMonth, 'dayOfMonth'),\n month: parseField(month, FIELD_CONSTRAINTS.month, 'month'),\n dayOfWeek: parseField(dayOfWeek, FIELD_CONSTRAINTS.dayOfWeek, 'dayOfWeek'),\n };\n }\n\n const [minute, hour, dayOfMonth, month, dayOfWeek] = fields;\n return {\n minute: parseField(minute, FIELD_CONSTRAINTS.minute, 'minute'),\n hour: parseField(hour, FIELD_CONSTRAINTS.hour, 'hour'),\n dayOfMonth: parseField(dayOfMonth, FIELD_CONSTRAINTS.dayOfMonth, 'dayOfMonth'),\n month: parseField(month, FIELD_CONSTRAINTS.month, 'month'),\n dayOfWeek: parseField(dayOfWeek, FIELD_CONSTRAINTS.dayOfWeek, 'dayOfWeek'),\n };\n}\n\n/**\n * Parses a single cron field\n */\nfunction parseField(value: string, constraints: FieldConstraints, fieldName: string): CronField {\n const raw = value;\n const isWildcard = value === '*' || value === '?';\n const isStep = value.includes('/');\n const isRange = value.includes('-') && !isStep;\n const isList = value.includes(',');\n\n let values: number[];\n\n if (isWildcard) {\n // Generate all possible values\n values = generateRange(constraints.min, constraints.max);\n } else if (isStep) {\n values = parseStepField(value, constraints, fieldName);\n } else if (isList) {\n values = parseListField(value, constraints, fieldName);\n } else if (isRange) {\n values = parseRangeField(value, constraints, fieldName);\n } else {\n // Single value\n const num = parseFieldValue(value, fieldName);\n values = num !== null ? [num] : [];\n }\n\n // Normalize day of week (both 0 and 7 are Sunday)\n if (fieldName === 'dayOfWeek') {\n values = values.map((v) => (v === 7 ? 0 : v));\n // Remove duplicates\n values = [...new Set(values)];\n }\n\n // Sort values\n values.sort((a, b) => a - b);\n\n return {\n raw,\n values,\n isWildcard,\n isRange,\n isStep,\n isList,\n };\n}\n\n/**\n * Parses a step field with step syntax\n */\nfunction parseStepField(value: string, constraints: FieldConstraints, fieldName: string): number[] {\n const [range, stepStr] = value.split('/');\n const step = parseInt(stepStr, 10);\n\n let baseValues: number[];\n\n if (range === '*') {\n baseValues = generateRange(constraints.min, constraints.max);\n } else if (range.includes('-')) {\n baseValues = parseRangeField(range, constraints, fieldName);\n } else {\n const num = parseFieldValue(range, fieldName);\n baseValues = num !== null ? [num] : [];\n }\n\n // Apply step\n const result: number[] = [];\n for (let i = 0; i < baseValues.length; i += step) {\n result.push(baseValues[i]);\n }\n\n return result;\n}\n\n/**\n * Parses a range field (e.g., 0-5)\n */\nfunction parseRangeField(\n value: string,\n _constraints: FieldConstraints,\n fieldName: string\n): number[] {\n const [startStr, endStr] = value.split('-');\n const start = parseFieldValue(startStr, fieldName);\n const end = parseFieldValue(endStr, fieldName);\n\n if (start === null || end === null) {\n return [];\n }\n\n return generateRange(start, end);\n}\n\n/**\n * Parses a list field (e.g., 1,3,5)\n */\nfunction parseListField(\n value: string,\n _constraints: FieldConstraints,\n fieldName: string\n): number[] {\n const parts = value.split(',');\n const result: number[] = [];\n\n for (const part of parts) {\n const trimmed = part.trim();\n if (trimmed.includes('-')) {\n const rangeValues = parseRangeField(trimmed, _constraints, fieldName);\n result.push(...rangeValues);\n } else {\n const num = parseFieldValue(trimmed, fieldName);\n if (num !== null) {\n result.push(num);\n }\n }\n }\n\n return result;\n}\n\n/**\n * Parses a field value, handling numeric values and named values (MON, JAN, etc.)\n */\nfunction parseFieldValue(value: string, fieldName: string): number | null {\n // Try parsing as number first\n const num = parseInt(value, 10);\n if (!isNaN(num)) {\n return num;\n }\n\n // Try parsing as month name\n if (fieldName === 'month') {\n const monthNum = MONTH_NAMES[value.toUpperCase()];\n if (monthNum !== undefined) {\n return monthNum;\n }\n }\n\n // Try parsing as day name\n if (fieldName === 'dayOfWeek') {\n const dayNum = DAY_NAMES[value.toUpperCase()];\n if (dayNum !== undefined) {\n return dayNum;\n }\n }\n\n return null;\n}\n\n/**\n * Generates a range of numbers from start to end (inclusive)\n */\nfunction generateRange(start: number, end: number): number[] {\n const result: number[] = [];\n for (let i = start; i <= end; i++) {\n result.push(i);\n }\n return result;\n}\n","/**\n * Internationalization strings for Spanish\n */\nexport interface I18nStrings {\n at: string;\n every: string;\n everyMinute: string;\n everyHour: string;\n everyDay: string;\n everyWeek: string;\n everyMonth: string;\n everyYear: string;\n minute: string;\n minutes: string;\n hour: string;\n hours: string;\n day: string;\n days: string;\n week: string;\n weeks: string;\n month: string;\n months: string;\n year: string;\n years: string;\n on: string;\n in: string;\n and: string;\n between: string;\n through: string;\n of: string;\n second: string;\n seconds: string;\n\n // Day names\n sunday: string;\n monday: string;\n tuesday: string;\n wednesday: string;\n thursday: string;\n friday: string;\n saturday: string;\n\n // Month names\n january: string;\n february: string;\n march: string;\n april: string;\n may: string;\n june: string;\n july: string;\n august: string;\n september: string;\n october: string;\n november: string;\n december: string;\n\n // Time periods\n am: string;\n pm: string;\n midnight: string;\n noon: string;\n\n // Special\n weekday: string;\n weekend: string;\n}\n\nexport const es: I18nStrings = {\n at: 'a las',\n every: 'cada',\n everyMinute: 'cada minuto',\n everyHour: 'cada hora',\n everyDay: 'todos los días',\n everyWeek: 'cada semana',\n everyMonth: 'cada mes',\n everyYear: 'cada año',\n minute: 'minuto',\n minutes: 'minutos',\n hour: 'hora',\n hours: 'horas',\n day: 'día',\n days: 'días',\n week: 'semana',\n weeks: 'semanas',\n month: 'mes',\n months: 'meses',\n year: 'año',\n years: 'años',\n on: 'el',\n in: 'en',\n and: 'y',\n between: 'entre',\n through: 'hasta',\n of: 'de',\n second: 'segundo',\n seconds: 'segundos',\n\n // Day names\n sunday: 'domingo',\n monday: 'lunes',\n tuesday: 'martes',\n wednesday: 'miércoles',\n thursday: 'jueves',\n friday: 'viernes',\n saturday: 'sábado',\n\n // Month names\n january: 'enero',\n february: 'febrero',\n march: 'marzo',\n april: 'abril',\n may: 'mayo',\n june: 'junio',\n july: 'julio',\n august: 'agosto',\n september: 'septiembre',\n october: 'octubre',\n november: 'noviembre',\n december: 'diciembre',\n\n // Time periods\n am: 'AM',\n pm: 'PM',\n midnight: 'medianoche',\n noon: 'mediodía',\n\n // Special\n weekday: 'día de semana',\n weekend: 'fin de semana',\n};\n","import type { I18nStrings } from './es.js';\n\nexport const en: I18nStrings = {\n at: 'at',\n every: 'every',\n everyMinute: 'every minute',\n everyHour: 'every hour',\n everyDay: 'every day',\n everyWeek: 'every week',\n everyMonth: 'every month',\n everyYear: 'every year',\n minute: 'minute',\n minutes: 'minutes',\n hour: 'hour',\n hours: 'hours',\n day: 'day',\n days: 'days',\n week: 'week',\n weeks: 'weeks',\n month: 'month',\n months: 'months',\n year: 'year',\n years: 'years',\n on: 'on',\n in: 'in',\n and: 'and',\n between: 'between',\n through: 'through',\n of: 'of',\n second: 'second',\n seconds: 'seconds',\n\n // Day names\n sunday: 'Sunday',\n monday: 'Monday',\n tuesday: 'Tuesday',\n wednesday: 'Wednesday',\n thursday: 'Thursday',\n friday: 'Friday',\n saturday: 'Saturday',\n\n // Month names\n january: 'January',\n february: 'February',\n march: 'March',\n april: 'April',\n may: 'May',\n june: 'June',\n july: 'July',\n august: 'August',\n september: 'September',\n october: 'October',\n november: 'November',\n december: 'December',\n\n // Time periods\n am: 'AM',\n pm: 'PM',\n midnight: 'midnight',\n noon: 'noon',\n\n // Special\n weekday: 'weekday',\n weekend: 'weekend',\n};\n","import type { ParsedCron, FormatterOptions } from './types.js';\nimport type { I18nStrings } from '../i18n/es.js';\nimport { parseCron } from './parser.js';\nimport { es } from '../i18n/es.js';\nimport { en } from '../i18n/en.js';\n\n/**\n * Helper function to check if an array of numbers is a consecutive range\n */\nfunction isConsecutiveRange(values: number[]): boolean {\n if (values.length < 2) return false;\n for (let i = 1; i < values.length; i++) {\n if (values[i] !== values[i - 1] + 1) {\n return false;\n }\n }\n return true;\n}\n\n/**\n * Formats a cron expression into human-readable text\n *\n * @param expression - The cron expression to format\n * @param options - Formatting options (locale, format preferences)\n * @returns Human-readable description of the cron expression\n *\n * @example\n * formatCron('0 2 * * *', { locale: 'es' })\n * // Returns: \"A las 2:00 AM, todos los días\"\n *\n * formatCron('* /15 9-17 * * 1-5', { locale: 'en' })\n * // Returns: \"Every 15 minutes, between 9:00 AM and 5:00 PM, Monday through Friday\"\n */\nexport function formatCron(expression: string, options: FormatterOptions = {}): string {\n const {\n locale = 'en',\n use24HourFormat = true,\n includeSeconds = false,\n verbose = false,\n } = options;\n\n const i18n = locale === 'es' ? es : en;\n const parsed = parseCron(expression, includeSeconds);\n\n // Handle special keywords\n if (parsed.isSpecial && parsed.specialKeyword) {\n return formatSpecialKeyword(parsed.specialKeyword, i18n);\n }\n\n return formatStandardCron(parsed, i18n, use24HourFormat, verbose);\n}\n\n/**\n * Formats special cron keywords\n */\nfunction formatSpecialKeyword(keyword: string, i18n: I18nStrings): string {\n const map: Record<string, string> = {\n '@yearly': i18n.everyYear,\n '@annually': i18n.everyYear,\n '@monthly': i18n.everyMonth,\n '@weekly': i18n.everyWeek,\n '@daily': i18n.everyDay,\n '@midnight': `${i18n.at} ${i18n.midnight}`,\n '@hourly': i18n.everyHour,\n };\n\n return map[keyword] || keyword;\n}\n\n/**\n * Formats a standard cron expression\n */\nfunction formatStandardCron(\n parsed: ParsedCron,\n i18n: I18nStrings,\n use24HourFormat: boolean,\n verbose: boolean\n): string {\n const parts: string[] = [];\n\n // Time part (seconds, minutes, hours)\n const timePart = formatTime(parsed, i18n, use24HourFormat);\n if (timePart) {\n parts.push(timePart);\n }\n\n // Day/Month part\n const datePart = formatDate(parsed, i18n, verbose);\n if (datePart) {\n parts.push(datePart);\n }\n\n return parts.join(', ');\n}\n\n/**\n * Formats the time portion of a cron expression\n */\nfunction formatTime(parsed: ParsedCron, i18n: I18nStrings, use24HourFormat: boolean): string {\n const { minute, hour, second } = parsed;\n\n // Check for special patterns\n if (minute.isWildcard && hour.isWildcard) {\n if (second && !second.isWildcard) {\n return `${i18n.at} ${i18n.second} ${second.values.join(', ')}`;\n }\n return i18n.everyMinute;\n }\n\n if (minute.isWildcard) {\n // Every minute of specific hours\n if (hour.values.length === 1) {\n const formattedHour = formatHour(hour.values[0], use24HourFormat, i18n);\n return `${i18n.everyMinute} ${i18n.at} ${formattedHour}`;\n }\n if (hour.values.length > 1 && hour.isRange) {\n const start = formatHour(hour.values[0], use24HourFormat, i18n);\n const end = formatHour(hour.values[hour.values.length - 1], use24HourFormat, i18n);\n return `${i18n.everyMinute}, ${i18n.between} ${start} ${i18n.and} ${end}`;\n }\n }\n\n if (hour.isWildcard && !minute.isWildcard) {\n // Every hour at specific minutes\n if (minute.values.length === 1) {\n return `${i18n.at} ${i18n.minute} ${minute.values[0]}`;\n }\n if (minute.isStep) {\n const step = minute.values[1] - minute.values[0];\n return `${i18n.every} ${step} ${i18n.minutes}`;\n }\n }\n\n // Specific time\n if (!minute.isWildcard && !hour.isWildcard) {\n if (minute.values.length === 1 && hour.values.length === 1) {\n const time = formatTime24Hour(hour.values[0], minute.values[0]);\n const formatted = use24HourFormat\n ? time\n : formatTime12Hour(hour.values[0], minute.values[0], i18n);\n return `${i18n.at} ${formatted}`;\n }\n\n // Multiple specific times\n if (minute.values.length > 1 || hour.values.length > 1) {\n // Check if it's a range pattern (consecutive hours with same minute)\n if (\n minute.values.length === 1 &&\n hour.isRange &&\n hour.values.length > 1 &&\n isConsecutiveRange(hour.values)\n ) {\n const startTime = use24HourFormat\n ? formatTime24Hour(hour.values[0], minute.values[0])\n : formatTime12Hour(hour.values[0], minute.values[0], i18n);\n const endTime = use24HourFormat\n ? formatTime24Hour(hour.values[hour.values.length - 1], minute.values[0])\n : formatTime12Hour(hour.values[hour.values.length - 1], minute.values[0], i18n);\n return `${i18n.between} ${startTime} ${i18n.and} ${endTime}`;\n }\n\n if (minute.isStep) {\n const step = minute.values[1] - minute.values[0];\n if (hour.isRange) {\n const start = formatHour(hour.values[0], use24HourFormat, i18n);\n const end = formatHour(hour.values[hour.values.length - 1], use24HourFormat, i18n);\n return `${i18n.every} ${step} ${i18n.minutes}, ${i18n.between} ${start} ${i18n.and} ${end}`;\n }\n return `${i18n.every} ${step} ${i18n.minutes}`;\n }\n }\n }\n\n // Default: list all combinations\n return formatTimeList(parsed, i18n, use24HourFormat);\n}\n\n/**\n * Formats the date portion of a cron expression\n */\nfunction formatDate(parsed: ParsedCron, i18n: I18nStrings, verbose: boolean): string {\n const { dayOfMonth, month, dayOfWeek } = parsed;\n\n // Every day\n if (dayOfMonth.isWildcard && dayOfWeek.isWildcard && month.isWildcard) {\n return i18n.everyDay;\n }\n\n const parts: string[] = [];\n\n // Day of week\n if (!dayOfWeek.isWildcard) {\n const dayPart = formatDaysOfWeek(dayOfWeek.values, i18n, verbose);\n if (dayPart) {\n parts.push(dayPart);\n }\n }\n\n // Day of month\n if (!dayOfMonth.isWildcard && dayOfWeek.isWildcard) {\n const dayPart = formatDaysOfMonth(dayOfMonth.values, i18n, verbose);\n if (dayPart) {\n parts.push(dayPart);\n }\n }\n\n // Month\n if (!month.isWildcard) {\n const monthPart = formatMonths(month.values, i18n, verbose);\n if (monthPart) {\n parts.push(monthPart);\n }\n }\n\n return parts.join(', ');\n}\n\n/**\n * Formats hour in 24-hour format\n */\nfunction formatTime24Hour(hour: number, minute: number): string {\n return `${hour.toString().padStart(2, '0')}:${minute.toString().padStart(2, '0')}`;\n}\n\n/**\n * Formats hour in 12-hour format\n */\nfunction formatTime12Hour(hour: number, minute: number, i18n: I18nStrings): string {\n const period = hour < 12 ? i18n.am : i18n.pm;\n const hour12 = hour === 0 ? 12 : hour > 12 ? hour - 12 : hour;\n return `${hour12}:${minute.toString().padStart(2, '0')} ${period}`;\n}\n\n/**\n * Formats a single hour\n */\nfunction formatHour(hour: number, use24HourFormat: boolean, i18n: I18nStrings): string {\n if (use24HourFormat) {\n return `${hour.toString().padStart(2, '0')}:00`;\n }\n return formatTime12Hour(hour, 0, i18n);\n}\n\n/**\n * Formats a list of times\n */\nfunction formatTimeList(parsed: ParsedCron, i18n: I18nStrings, use24HourFormat: boolean): string {\n const times: string[] = [];\n\n for (const hour of parsed.hour.values) {\n for (const minute of parsed.minute.values) {\n const time = use24HourFormat\n ? formatTime24Hour(hour, minute)\n : formatTime12Hour(hour, minute, i18n);\n times.push(time);\n }\n }\n\n if (times.length <= 3) {\n return `${i18n.at} ${times.join(`, `)}`;\n }\n\n return `${i18n.at} ${times.slice(0, 2).join(', ')}... (${times.length} times)`;\n}\n\n/**\n * Formats days of the week\n */\nfunction formatDaysOfWeek(days: number[], i18n: I18nStrings, verbose: boolean): string {\n const dayNames = [\n i18n.sunday,\n i18n.monday,\n i18n.tuesday,\n i18n.wednesday,\n i18n.thursday,\n i18n.friday,\n i18n.saturday,\n ];\n\n // Check for weekdays (Mon-Fri)\n if (\n days.length === 5 &&\n days.includes(1) &&\n days.includes(2) &&\n days.includes(3) &&\n days.includes(4) &&\n days.includes(5)\n ) {\n return i18n.weekday + 's';\n }\n\n // Check for weekend\n if (days.length === 2 && days.includes(0) && days.includes(6)) {\n return i18n.weekend + 's';\n }\n\n if (days.length === 1) {\n return i18n.on + ' ' + dayNames[days[0]];\n }\n\n if (days.length === 7) {\n return i18n.everyDay;\n }\n\n // List days\n const names = days.map((d) => dayNames[d]);\n if (verbose || days.length <= 3) {\n return formatList(names, i18n);\n }\n\n return `${names[0]} ${i18n.through} ${names[names.length - 1]}`;\n}\n\n/**\n * Formats days of the month\n */\nfunction formatDaysOfMonth(days: number[], i18n: I18nStrings, verbose: boolean): string {\n if (days.length === 1) {\n return `${i18n.on} ${i18n.day} ${days[0]}`;\n }\n\n if (days.length === 31) {\n return i18n.everyDay;\n }\n\n if (verbose || days.length <= 3) {\n return `${i18n.on} ${i18n.days} ${days.join(', ')}`;\n }\n\n return `${i18n.on} ${i18n.days} ${days[0]} ${i18n.through} ${days[days.length - 1]}`;\n}\n\n/**\n * Formats months\n */\nfunction formatMonths(months: number[], i18n: I18nStrings, verbose: boolean): string {\n const monthNames = [\n i18n.january,\n i18n.february,\n i18n.march,\n i18n.april,\n i18n.may,\n i18n.june,\n i18n.july,\n i18n.august,\n i18n.september,\n i18n.october,\n i18n.november,\n i18n.december,\n ];\n\n if (months.length === 1) {\n return `${i18n.in} ${monthNames[months[0] - 1]}`;\n }\n\n if (months.length === 12) {\n return '';\n }\n\n const names = months.map((m) => monthNames[m - 1]);\n if (verbose || months.length <= 3) {\n return `${i18n.in} ${formatList(names, i18n)}`;\n }\n\n return `${i18n.in} ${names[0]} ${i18n.through} ${names[names.length - 1]}`;\n}\n\n/**\n * Formats a list of items with proper grammar\n */\nfunction formatList(items: string[], i18n: I18nStrings): string {\n if (items.length === 0) return '';\n if (items.length === 1) return items[0];\n if (items.length === 2) return `${items[0]} ${i18n.and} ${items[1]}`;\n\n const last = items[items.length - 1];\n const rest = items.slice(0, -1);\n return `${rest.join(', ')}, ${i18n.and} ${last}`;\n}\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "soff-cron",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Lightweight, tree-shakeable cron expression parser and human-readable formatter",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.cjs",
|
|
7
|
+
"module": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"sideEffects": false,
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"import": {
|
|
13
|
+
"types": "./dist/index.d.ts",
|
|
14
|
+
"default": "./dist/index.js"
|
|
15
|
+
},
|
|
16
|
+
"require": {
|
|
17
|
+
"types": "./dist/index.d.cts",
|
|
18
|
+
"default": "./dist/index.cjs"
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"./core/parser": {
|
|
22
|
+
"import": {
|
|
23
|
+
"types": "./dist/core/parser.d.ts",
|
|
24
|
+
"default": "./dist/core/parser.js"
|
|
25
|
+
},
|
|
26
|
+
"require": {
|
|
27
|
+
"types": "./dist/core/parser.d.cts",
|
|
28
|
+
"default": "./dist/core/parser.cjs"
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
"./core/formatter": {
|
|
32
|
+
"import": {
|
|
33
|
+
"types": "./dist/core/formatter.d.ts",
|
|
34
|
+
"default": "./dist/core/formatter.js"
|
|
35
|
+
},
|
|
36
|
+
"require": {
|
|
37
|
+
"types": "./dist/core/formatter.d.cts",
|
|
38
|
+
"default": "./dist/core/formatter.cjs"
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
"./core/validator": {
|
|
42
|
+
"import": {
|
|
43
|
+
"types": "./dist/core/validator.d.ts",
|
|
44
|
+
"default": "./dist/core/validator.js"
|
|
45
|
+
},
|
|
46
|
+
"require": {
|
|
47
|
+
"types": "./dist/core/validator.d.cts",
|
|
48
|
+
"default": "./dist/core/validator.cjs"
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
"./i18n/es": {
|
|
52
|
+
"import": {
|
|
53
|
+
"types": "./dist/i18n/es.d.ts",
|
|
54
|
+
"default": "./dist/i18n/es.js"
|
|
55
|
+
},
|
|
56
|
+
"require": {
|
|
57
|
+
"types": "./dist/i18n/es.d.cts",
|
|
58
|
+
"default": "./dist/i18n/es.cjs"
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
"./i18n/en": {
|
|
62
|
+
"import": {
|
|
63
|
+
"types": "./dist/i18n/en.d.ts",
|
|
64
|
+
"default": "./dist/i18n/en.js"
|
|
65
|
+
},
|
|
66
|
+
"require": {
|
|
67
|
+
"types": "./dist/i18n/en.d.cts",
|
|
68
|
+
"default": "./dist/i18n/en.cjs"
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
"scripts": {
|
|
73
|
+
"build": "tsup",
|
|
74
|
+
"dev": "tsup --watch",
|
|
75
|
+
"test": "vitest",
|
|
76
|
+
"test:watch": "vitest --watch",
|
|
77
|
+
"test:coverage": "vitest --coverage",
|
|
78
|
+
"lint": "eslint .",
|
|
79
|
+
"lint:fix": "eslint . --fix",
|
|
80
|
+
"type-check": "tsc --noEmit"
|
|
81
|
+
},
|
|
82
|
+
"keywords": [
|
|
83
|
+
"cron",
|
|
84
|
+
"cron-parser",
|
|
85
|
+
"cron-formatter",
|
|
86
|
+
"human-readable",
|
|
87
|
+
"schedule",
|
|
88
|
+
"task-scheduler",
|
|
89
|
+
"crontab",
|
|
90
|
+
"typescript",
|
|
91
|
+
"zero-dependencies",
|
|
92
|
+
"tree-shakeable",
|
|
93
|
+
"latam"
|
|
94
|
+
],
|
|
95
|
+
"author": "Soff Contributors",
|
|
96
|
+
"license": "MIT",
|
|
97
|
+
"repository": {
|
|
98
|
+
"type": "git",
|
|
99
|
+
"url": "https://github.com/bledxs/soff-monorepo.git",
|
|
100
|
+
"directory": "packages/soff-cron"
|
|
101
|
+
},
|
|
102
|
+
"bugs": {
|
|
103
|
+
"url": "https://github.com/bledxs/soff-monorepo/issues"
|
|
104
|
+
},
|
|
105
|
+
"homepage": "https://github.com/bledxs/soff-monorepo/tree/master/packages/soff-cron#readme",
|
|
106
|
+
"files": [
|
|
107
|
+
"dist",
|
|
108
|
+
"README.md",
|
|
109
|
+
"LICENSE"
|
|
110
|
+
],
|
|
111
|
+
"devDependencies": {
|
|
112
|
+
"@eslint/js": "^9.39.1",
|
|
113
|
+
"@soff/tsconfig": "*",
|
|
114
|
+
"@types/node": "^25.0.0",
|
|
115
|
+
"@vitest/coverage-v8": "^4.0.15",
|
|
116
|
+
"eslint": "^9.39.1",
|
|
117
|
+
"eslint-config-prettier": "^10.1.8",
|
|
118
|
+
"globals": "^16.5.0",
|
|
119
|
+
"tsup": "^8.5.1",
|
|
120
|
+
"typescript": "^5.9.3",
|
|
121
|
+
"typescript-eslint": "^8.49.0",
|
|
122
|
+
"vitest": "^4.0.15"
|
|
123
|
+
}
|
|
124
|
+
}
|