soff-cron 0.0.1 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -39,13 +39,14 @@
39
39
  Cron expressions like `*/15 9-17 * * 1-5` are powerful but hard to read. This library:
40
40
 
41
41
  - ✅ **Converts cron to human text**: "Every 15 minutes, between 9:00 AM and 5:00 PM, Monday through Friday"
42
+ - ✅ **Converts human text to cron**: "every 5 minutes" → `*/5 * * * *` **NEW!**
42
43
  - ✅ **Validates cron syntax**: Catch errors before execution
43
44
  - ✅ **Parses to structured data**: Extract minute/hour/day patterns
44
45
  - ✅ **Zero dependencies**: No bloat, pure TypeScript
45
46
  - ✅ **i18n ready**: Built-in Spanish and English support
46
47
  - ✅ **Tree-shakeable**: Only import what you need
47
48
 
48
- **Perfect for:** Dashboards, task schedulers, configuration UIs, logs, and documentation.
49
+ **Perfect for:** Dashboards, task schedulers, configuration UIs, logs, documentation, and **non-technical users** who need to create schedules!
49
50
 
50
51
  ## 📦 Install
51
52
 
@@ -78,6 +79,18 @@ formatCron('*/15 9-17 * * 1-5', { locale: 'es' });
78
79
  formatCron('@daily', { locale: 'en' });
79
80
  // → "every day"
80
81
 
82
+ // 🔄 Convert natural language to cron expressions
83
+ import { humanizeCron } from 'soff-cron';
84
+
85
+ humanizeCron('every 5 minutes', { locale: 'en' });
86
+ // → { success: true, cronExpression: "*/5 * * * *" }
87
+
88
+ humanizeCron('todos los días a las 2 am', { locale: 'es' });
89
+ // → { success: true, cronExpression: "0 2 * * *" }
90
+
91
+ humanizeCron('every monday at 10am', { locale: 'en' });
92
+ // → { success: true, cronExpression: "0 10 * * 1" }
93
+
81
94
  // ✅ Validate cron expressions
82
95
  validateCron('0 2 * * *');
83
96
  // → { isValid: true }
@@ -119,6 +132,77 @@ Want to add more languages? Check out [`src/i18n/`](src/i18n/) for examples!
119
132
 
120
133
  ## API Reference
121
134
 
135
+ ### `humanizeCron(text, options?)`
136
+
137
+ **NEW!** Converts natural language text to cron expressions. Perfect for non-technical users!
138
+
139
+ **Parameters:**
140
+
141
+ - `text` (string): Human-readable text (e.g., "every 5 minutes")
142
+ - `options` (object, optional):
143
+ - `locale` ('en' | 'es'): Input language (default: `'en'`)
144
+
145
+ **Returns:** `HumanizerResult`
146
+
147
+ ```typescript
148
+ {
149
+ success: boolean;
150
+ cronExpression?: string;
151
+ error?: string;
152
+ suggestions?: string[];
153
+ }
154
+ ```
155
+
156
+ **Supported patterns (English):**
157
+
158
+ - Time intervals: "every minute", "every 5 minutes", "every hour", "every 2 hours"
159
+ - Daily: "every day", "every day at 2am", "at 14:30"
160
+ - Weekly: "every week", "every monday", "every monday at 10am"
161
+ - Monthly: "every month", "on the 1st of every month", "on the 15th of every month at 3pm"
162
+ - Weekdays/weekends: "weekdays at 9am", "weekends at 10am"
163
+
164
+ **Supported patterns (Spanish):**
165
+
166
+ - Intervalos: "cada minuto", "cada 5 minutos", "cada hora", "cada 2 horas"
167
+ - Diario: "todos los días", "todos los días a las 2am", "a las 14:30"
168
+ - Semanal: "cada semana", "todos los lunes", "cada lunes a las 10am"
169
+ - Mensual: "cada mes", "el día 1 de cada mes", "el dia 15 de cada mes a las 3pm"
170
+ - Días laborales: "días de semana a las 9am", "fines de semana a las 10am"
171
+
172
+ **Examples:**
173
+
174
+ ```typescript
175
+ // English
176
+ humanizeCron('every 5 minutes', { locale: 'en' });
177
+ // → { success: true, cronExpression: "*/5 * * * *" }
178
+
179
+ humanizeCron('every monday at 10am', { locale: 'en' });
180
+ // → { success: true, cronExpression: "0 10 * * 1" }
181
+
182
+ humanizeCron('weekdays at 9am', { locale: 'en' });
183
+ // → { success: true, cronExpression: "0 9 * * 1-5" }
184
+
185
+ // Spanish
186
+ humanizeCron('cada 10 minutos', { locale: 'es' });
187
+ // → { success: true, cronExpression: "*/10 * * * *" }
188
+
189
+ humanizeCron('todos los lunes a las 10am', { locale: 'es' });
190
+ // → { success: true, cronExpression: "0 10 * * 1" }
191
+
192
+ humanizeCron('días de semana a las 9am', { locale: 'es' });
193
+ // → { success: true, cronExpression: "0 9 * * 1-5" }
194
+
195
+ // Error handling
196
+ humanizeCron('invalid text', { locale: 'en' });
197
+ // → {
198
+ // success: false,
199
+ // error: "Could not parse the text...",
200
+ // suggestions: ["every 5 minutes", "every day at 9 am"]
201
+ // }
202
+ ```
203
+
204
+ ---
205
+
122
206
  ### `formatCron(expression, options?)`
123
207
 
124
208
  Converts a cron expression to human-readable text.
@@ -274,6 +358,17 @@ export interface FormatterOptions {
274
358
  verbose?: boolean;
275
359
  }
276
360
 
361
+ export interface HumanizerOptions {
362
+ locale?: 'es' | 'en';
363
+ }
364
+
365
+ export interface HumanizerResult {
366
+ success: boolean;
367
+ cronExpression?: string;
368
+ error?: string;
369
+ suggestions?: string[];
370
+ }
371
+
277
372
  export interface ValidationResult {
278
373
  isValid: boolean;
279
374
  error?: string;
@@ -1,2 +1,2 @@
1
- 'use strict';var h={"@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"}},p={JAN:1,FEB:2,MAR:3,APR:4,MAY:5,JUN:6,JUL:7,AUG:8,SEP:9,OCT:10,NOV:11,DEC:12},$={SUN:0,MON:1,TUE:2,WED:3,THU:4,FRI:5,SAT:6};function V(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 h[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=A(u,d,o);if(!f.isValid)return {isValid:false,error:f.error,field:o}}return {isValid:true}}function A(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("/")?E(r,e,t):r.includes(",")?D(r,e,t):r.includes("-")?S(r,e,t):C(r,e,t):{isValid:false,error:`${e.name} field cannot be empty`}}function E(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("-")?S(s,e,t):C(s,e,t)}function S(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=S(a,e,t);if(!i.isValid)return i}else {let i=C(a,e,t);if(!i.isValid)return i}}return {isValid:true}}function C(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=p[r.toUpperCase()];if(n!==void 0)return n}if(e==="dayOfWeek"){let n=$[r.toUpperCase()];if(n!==void 0)return n}return null}function M(r,e=false){let t=V(r,e);if(!t.isValid)throw new Error(t.error||"Invalid cron expression");let n=r.trim();if(n.startsWith("@")){let s=h[n];return {expression:n,...W(s,false),isSpecial:true,specialKeyword:n}}return {expression:n,...W(n,e),isSpecial:false}}function W(r,e){let t=r.split(/\s+/);if(e&&t.length===6){let[u,d,f,I,R,j]=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(j,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=k(e.min,e.max);else if(a)u=P(r,e,t);else if(o)u=T(r,e,t);else if(i)u=O(r,e,t);else {let d=g(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 P(r,e,t){let[n,s]=r.split("/"),a=parseInt(s,10),i;if(n==="*")i=k(e.min,e.max);else if(n.includes("-"))i=O(n,e,t);else {let u=g(n,t);i=u!==null?[u]:[];}let o=[];for(let u=0;u<i.length;u+=a)o.push(i[u]);return o}function O(r,e,t){let[n,s]=r.split("-"),a=g(n,t),i=g(s,t);return a===null||i===null?[]:k(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=O(i,e,t);s.push(...o);}else {let o=g(i,t);o!==null&&s.push(o);}}return s}function g(r,e){let t=parseInt(r,10);if(!isNaN(t))return t;if(e==="month"){let n=p[r.toUpperCase()];if(n!==void 0)return n}if(e==="dayOfWeek"){let n=$[r.toUpperCase()];if(n!==void 0)return n}return null}function k(r,e){let t=[];for(let n=r;n<=e;n++)t.push(n);return t}var w={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 x={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 N(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 ie(r,e={}){let{locale:t="en",use24HourFormat:n=true,includeSeconds:s=false,verbose:a=false}=e,i=t==="es"?w:x,o=M(r,s);return o.isSpecial&&o.specialKeyword?L(o.specialKeyword,i):_(o,i,n,a)}function L(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 _(r,e,t,n){let s=[],a=Y(r,e,t);a&&s.push(a);let i=U(r,e,n);return i&&s.push(i),s.join(", ")}function Y(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=c(s.values[0],t,e);return `${e.everyMinute} ${e.at} ${i}`}if(s.values.length>1&&s.isRange){let i=c(s.values[0],t,e),o=c(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:y(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&&N(s.values)){let i=t?v(s.values[0],n.values[0]):y(s.values[0],n.values[0],e),o=t?v(s.values[s.values.length-1],n.values[0]):y(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=c(s.values[0],t,e),u=c(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 K(r,e,t)}function U(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=H(a.values,e,t);o&&i.push(o);}if(!n.isWildcard&&a.isWildcard){let o=J(n.values,e,t);o&&i.push(o);}if(!s.isWildcard){let o=z(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 y(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 c(r,e,t){return e?`${r.toString().padStart(2,"0")}:00`:y(r,0,t)}function K(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):y(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 H(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 J(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 z(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}`}exports.formatCron=ie;//# sourceMappingURL=formatter.cjs.map
1
+ 'use strict';var h={"@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 * * * *"},u={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"}},p={JAN:1,FEB:2,MAR:3,APR:4,MAY:5,JUN:6,JUL:7,AUG:8,SEP:9,OCT:10,NOV:11,DEC:12},$={SUN:0,MON:1,TUE:2,WED:3,THU:4,FRI:5,SAT:6};function k(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 h[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 o=e?["second","minute","hour","dayOfMonth","month","dayOfWeek"]:["minute","hour","dayOfMonth","month","dayOfWeek"];for(let i=0;i<n.length;i++){let a=o[i],d=n[i],l=u[a],c=R(d,l,a);if(!c.isValid)return {isValid:false,error:c.error,field:a}}return {isValid:true}}function R(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("/")?D(r,e,t):r.includes(",")?P(r,e,t):r.includes("-")?C(r,e,t):w(r,e,t):{isValid:false,error:`${e.name} field cannot be empty`}}function D(r,e,t){let n=r.split("/");if(n.length!==2)return {isValid:false,error:`Invalid step syntax in ${e.name}: ${r}`};let[s,o]=n,i=parseInt(o,10);return isNaN(i)||i<=0?{isValid:false,error:`Invalid step value in ${e.name}: ${o}`}:s==="*"?{isValid:true}:s.includes("-")?C(s,e,t):w(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,o]=n,i=b(s,t),a=b(o,t);return i===null?{isValid:false,error:`Invalid start value in ${e.name} range: ${s}`}:a===null?{isValid:false,error:`Invalid end value in ${e.name} range: ${o}`}:i<e.min||i>e.max?{isValid:false,error:`Start value ${i} is out of range for ${e.name} (${e.min}-${e.max})`}:a<e.min||a>e.max?{isValid:false,error:`End value ${a} is out of range for ${e.name} (${e.min}-${e.max})`}:i>a?{isValid:false,error:`Start value ${i} cannot be greater than end value ${a} in ${e.name}`}:{isValid:true}}function P(r,e,t){let n=r.split(",");for(let s of n){let o=s.trim();if(!o)return {isValid:false,error:`Empty value in ${e.name} list`};if(o.includes("-")){let i=C(o,e,t);if(!i.isValid)return i}else {let i=w(o,e,t);if(!i.isValid)return i}}return {isValid:true}}function w(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=p[r.toUpperCase()];if(n!==void 0)return n}if(e==="dayOfWeek"){let n=$[r.toUpperCase()];if(n!==void 0)return n}return null}function O(r,e=false){let t=k(r,e);if(!t.isValid)throw new Error(t.error||"Invalid cron expression");let n=r.trim();if(n.startsWith("@")){let s=h[n];return {expression:n,...E(s,false),isSpecial:true,specialKeyword:n}}return {expression:n,...E(n,e),isSpecial:false}}function E(r,e){let t=r.split(/\s+/);if(e&&t.length===6){let[d,l,c,V,F,j]=t;return {second:m(d,u.second,"second"),minute:m(l,u.minute,"minute"),hour:m(c,u.hour,"hour"),dayOfMonth:m(V,u.dayOfMonth,"dayOfMonth"),month:m(F,u.month,"month"),dayOfWeek:m(j,u.dayOfWeek,"dayOfWeek")}}let[n,s,o,i,a]=t;return {minute:m(n,u.minute,"minute"),hour:m(s,u.hour,"hour"),dayOfMonth:m(o,u.dayOfMonth,"dayOfMonth"),month:m(i,u.month,"month"),dayOfWeek:m(a,u.dayOfWeek,"dayOfWeek")}}function m(r,e,t){let n=r,s=r==="*"||r==="?",o=r.includes("/"),i=r.includes("-")&&!o,a=r.includes(","),d;if(s)d=S(e.min,e.max);else if(o)d=A(r,e,t);else if(a)d=T(r,e,t);else if(i)d=x(r,e,t);else {let l=f(r,t);d=l!==null?[l]:[];}return t==="dayOfWeek"&&(d=d.map(l=>l===7?0:l),d=[...new Set(d)]),d.sort((l,c)=>l-c),{raw:n,values:d,isWildcard:s,isRange:i,isStep:o,isList:a}}function A(r,e,t){let[n,s]=r.split("/"),o=parseInt(s,10),i;if(n==="*")i=S(e.min,e.max);else if(n.includes("-"))i=x(n,e,t);else {let d=f(n,t);i=d!==null?[d]:[];}let a=[];for(let d=0;d<i.length;d+=o)a.push(i[d]);return a}function x(r,e,t){let[n,s]=r.split("-"),o=f(n,t),i=f(s,t);return o===null||i===null?[]:S(o,i)}function T(r,e,t){let n=r.split(","),s=[];for(let o of n){let i=o.trim();if(i.includes("-")){let a=x(i,e,t);s.push(...a);}else {let a=f(i,t);a!==null&&s.push(a);}}return s}function f(r,e){let t=parseInt(r,10);if(!isNaN(t))return t;if(e==="month"){let n=p[r.toUpperCase()];if(n!==void 0)return n}if(e==="dayOfWeek"){let n=$[r.toUpperCase()];if(n!==void 0)return n}return null}function S(r,e){let t=[];for(let n=r;n<=e;n++)t.push(n);return t}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:"weekdays",weekend:"weekends"};var I={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\xEDas de semana",weekend:"fines de semana"};function N(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 ie(r,e={}){let{locale:t="en",use24HourFormat:n=true,includeSeconds:s=false,verbose:o=false}=e,i=t==="es"?I:W,a=O(r,s);return a.isSpecial&&a.specialKeyword?L(a.specialKeyword,i):H(a,i,n,o)}function L(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 H(r,e,t,n){let s=[],o=_(r,e,t);o&&s.push(o);let i=Y(r,e,n);return i&&s.push(i),s.join(", ")}function _(r,e,t){let{minute:n,hour:s,second:o}=r;if(n.isWildcard&&s.isWildcard)return o&&!o.isWildcard?`${e.at} ${e.second} ${o.values.join(", ")}`:e.everyMinute;if(n.isWildcard){if(s.values.length===1){let i=y(s.values[0],t,e);return `${e.everyMinute} ${e.at} ${i}`}if(s.values.length>1&&s.isRange){let i=y(s.values[0],t,e),a=y(s.values[s.values.length-1],t,e);return `${e.everyMinute}, ${e.between} ${i} ${e.and} ${a}`}}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]),a=t?i:g(s.values[0],n.values[0],e);return `${e.at} ${a}`}if(n.values.length>1||s.values.length>1){if(n.values.length===1&&s.isRange&&s.values.length>1&&N(s.values)){let i=t?v(s.values[0],n.values[0]):g(s.values[0],n.values[0],e),a=t?v(s.values[s.values.length-1],n.values[0]):g(s.values[s.values.length-1],n.values[0],e);return `${e.between} ${i} ${e.and} ${a}`}if(n.isStep){let i=n.values[1]-n.values[0];if(s.isRange){let a=y(s.values[0],t,e),d=y(s.values[s.values.length-1],t,e);return `${e.every} ${i} ${e.minutes}, ${e.between} ${a} ${e.and} ${d}`}return `${e.every} ${i} ${e.minutes}`}}}return U(r,e,t)}function Y(r,e,t){let{dayOfMonth:n,month:s,dayOfWeek:o}=r;if(n.isWildcard&&o.isWildcard&&s.isWildcard)return e.everyDay;let i=[];if(!o.isWildcard){let a=z(o.values,e,t);a&&i.push(a);}if(!n.isWildcard&&o.isWildcard){let a=K(n.values,e,t);a&&i.push(a);}if(!s.isWildcard){let a=J(s.values,e,t);a&&i.push(a);}return i.join(", ")}function v(r,e){return `${r.toString().padStart(2,"0")}:${e.toString().padStart(2,"0")}`}function g(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 y(r,e,t){return e?`${r.toString().padStart(2,"0")}:00`:g(r,0,t)}function U(r,e,t){let n=[];for(let s of r.hour.values)for(let o of r.minute.values){let i=t?v(s,o):g(s,o,e);n.push(i);}return n.length<=3?`${e.at} ${n.join(", ")}`:`${e.at} ${n.slice(0,2).join(", ")}... (${n.length} times)`}function z(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;if(r.length===2&&r.includes(0)&&r.includes(6))return e.weekend;if(r.length===1)return e.on+" "+n[r[0]];if(r.length===7)return e.everyDay;let s=r.map(o=>n[o]);return t||r.length<=3?M(s,e):`${s[0]} ${e.through} ${s[s.length-1]}`}function K(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 J(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(o=>n[o-1]);return t||r.length<=3?`${e.in} ${M(s,e)}`:`${e.in} ${s[0]} ${e.through} ${s[s.length-1]}`}function M(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}`}exports.formatCron=ie;//# sourceMappingURL=formatter.cjs.map
2
2
  //# sourceMappingURL=formatter.cjs.map
@@ -1 +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":"formatter.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"]}
1
+ {"version":3,"sources":["../../src/core/types.ts","../../src/core/validator.ts","../../src/core/parser.ts","../../src/i18n/en.ts","../../src/i18n/es.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","en","es","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":"formatter.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","import type { I18nStrings } from './es.js';\nimport { parseTimeString, parseDayOfWeek } from '../core/humanizer.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: 'weekdays',\n weekend: 'weekends',\n};\n\n/**\n * Pattern for converting natural language to cron\n */\nexport interface HumanizerPattern {\n /**\n * Regular expression to match the pattern\n */\n regex: RegExp;\n\n /**\n * Function to convert match groups to cron expression\n */\n toCron: (match: RegExpMatchArray, patterns: HumanizerPatterns) => string;\n\n /**\n * Description of what this pattern matches\n */\n description: string;\n}\n\n/**\n * Collection of patterns and helper data for humanizer\n */\nexport interface HumanizerPatterns {\n days: string[];\n months: string[];\n patterns: HumanizerPattern[];\n}\n\nexport const enPatterns: HumanizerPatterns = {\n days: ['sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday'],\n months: [\n 'january',\n 'february',\n 'march',\n 'april',\n 'may',\n 'june',\n 'july',\n 'august',\n 'september',\n 'october',\n 'november',\n 'december',\n ],\n\n patterns: [\n // \"every minute\" → */1 * * * *\n {\n regex: /^every\\s+minute$/,\n toCron: () => '* * * * *',\n description: 'Every minute',\n },\n\n // \"every 5 minutes\" → */5 * * * *\n {\n regex: /^every\\s+(\\d+)\\s+minutes?$/,\n toCron: (match) => `*/${match[1]} * * * *`,\n description: 'Every N minutes',\n },\n\n // \"every hour\" → 0 * * * *\n {\n regex: /^every\\s+hour$/,\n toCron: () => '0 * * * *',\n description: 'Every hour',\n },\n\n // \"every 2 hours\" → 0 */2 * * *\n {\n regex: /^every\\s+(\\d+)\\s+hours?$/,\n toCron: (match) => `0 */${match[1]} * * *`,\n description: 'Every N hours',\n },\n\n // \"every day\" → 0 0 * * *\n {\n regex: /^every\\s+day$/,\n toCron: () => '0 0 * * *',\n description: 'Every day at midnight',\n },\n\n // \"every day at 2am\" or \"every day at 14:30\"\n {\n regex: /^every\\s+day\\s+at\\s+(.+)$/,\n toCron: (match) => {\n const time = parseTimeString(match[1]);\n if (!time) throw new Error('Invalid time format');\n return `${time.minute} ${time.hour} * * *`;\n },\n description: 'Every day at specific time',\n },\n\n // \"every week\" → 0 0 * * 0\n {\n regex: /^every\\s+week$/,\n toCron: () => '0 0 * * 0',\n description: 'Every week (Sunday at midnight)',\n },\n\n // \"every monday\" or \"every mon\"\n {\n regex:\n /^every\\s+(monday|mon|tuesday|tue|wednesday|wed|thursday|thu|friday|fri|saturday|sat|sunday|sun)$/,\n toCron: (match, patterns) => {\n const day = parseDayOfWeek(match[1], patterns);\n if (day === null) throw new Error('Invalid day');\n return `0 0 * * ${day}`;\n },\n description: 'Every specific day of week',\n },\n\n // \"every monday at 10am\"\n {\n regex:\n /^every\\s+(monday|mon|tuesday|tue|wednesday|wed|thursday|thu|friday|fri|saturday|sat|sunday|sun)\\s+at\\s+(.+)$/,\n toCron: (match, patterns) => {\n const day = parseDayOfWeek(match[1], patterns);\n const time = parseTimeString(match[2]);\n if (day === null || !time) throw new Error('Invalid day or time');\n return `${time.minute} ${time.hour} * * ${day}`;\n },\n description: 'Every specific day at specific time',\n },\n\n // \"every month\" → 0 0 1 * *\n {\n regex: /^every\\s+month$/,\n toCron: () => '0 0 1 * *',\n description: 'Every month (1st at midnight)',\n },\n\n // \"on the 1st of every month\" or \"on the 15th of every month\"\n {\n regex: /^on\\s+the\\s+(\\d{1,2})(?:st|nd|rd|th)?\\s+of\\s+every\\s+month(?:\\s+at\\s+(.+))?$/,\n toCron: (match) => {\n const day = parseInt(match[1], 10);\n if (day < 1 || day > 31) throw new Error('Invalid day of month');\n\n if (match[2]) {\n const time = parseTimeString(match[2]);\n if (!time) throw new Error('Invalid time format');\n return `${time.minute} ${time.hour} ${day} * *`;\n }\n return `0 0 ${day} * *`;\n },\n description: 'Specific day of every month',\n },\n\n // \"every year\" → 0 0 1 1 *\n {\n regex: /^every\\s+year$/,\n toCron: () => '0 0 1 1 *',\n description: 'Every year (Jan 1st at midnight)',\n },\n\n // \"at 2am\" or \"at 14:30\"\n {\n regex: /^at\\s+(.+)$/,\n toCron: (match) => {\n const time = parseTimeString(match[1]);\n if (!time) throw new Error('Invalid time format');\n return `${time.minute} ${time.hour} * * *`;\n },\n description: 'Daily at specific time',\n },\n\n // \"weekdays at 9am\" or \"on weekdays at 9am\"\n {\n regex: /^(?:on\\s+)?weekdays?\\s+at\\s+(.+)$/,\n toCron: (match) => {\n const time = parseTimeString(match[1]);\n if (!time) throw new Error('Invalid time format');\n return `${time.minute} ${time.hour} * * 1-5`;\n },\n description: 'Weekdays at specific time',\n },\n\n // \"weekends at 10am\" or \"on weekends at 10am\"\n {\n regex: /^(?:on\\s+)?weekends?\\s+at\\s+(.+)$/,\n toCron: (match) => {\n const time = parseTimeString(match[1]);\n if (!time) throw new Error('Invalid time format');\n return `${time.minute} ${time.hour} * * 0,6`;\n },\n description: 'Weekends at specific time',\n },\n ],\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ías de semana',\n weekend: 'fines de semana',\n};\n\nimport type { HumanizerPatterns } from './en.js';\nimport { parseTimeString, parseDayOfWeek } from '../core/humanizer.js';\n\nexport const esPatterns: HumanizerPatterns = {\n days: ['domingo', 'lunes', 'martes', 'miércoles', 'jueves', 'viernes', 'sábado'],\n months: [\n 'enero',\n 'febrero',\n 'marzo',\n 'abril',\n 'mayo',\n 'junio',\n 'julio',\n 'agosto',\n 'septiembre',\n 'octubre',\n 'noviembre',\n 'diciembre',\n ],\n\n patterns: [\n // \"cada minuto\" → * * * * *\n {\n regex: /^cada\\s+minuto$/,\n toCron: () => '* * * * *',\n description: 'Cada minuto',\n },\n\n // \"cada 5 minutos\" → */5 * * * *\n {\n regex: /^cada\\s+(\\d+)\\s+minutos?$/,\n toCron: (match) => `*/${match[1]} * * * *`,\n description: 'Cada N minutos',\n },\n\n // \"cada hora\" → 0 * * * *\n {\n regex: /^cada\\s+hora$/,\n toCron: () => '0 * * * *',\n description: 'Cada hora',\n },\n\n // \"cada 2 horas\" → 0 */2 * * *\n {\n regex: /^cada\\s+(\\d+)\\s+horas?$/,\n toCron: (match) => `0 */${match[1]} * * *`,\n description: 'Cada N horas',\n },\n\n // \"todos los días\" or \"todos los dias\" → 0 0 * * *\n {\n regex: /^todos\\s+los\\s+d[ií]as$/,\n toCron: () => '0 0 * * *',\n description: 'Todos los días a medianoche',\n },\n\n // \"todos los días a las 2am\" or \"todos los dias a las 14:30\"\n {\n regex: /^todos\\s+los\\s+d[ií]as\\s+a\\s+las?\\s+(.+)$/,\n toCron: (match) => {\n const time = parseTimeString(match[1]);\n if (!time) throw new Error('Formato de hora inválido');\n return `${time.minute} ${time.hour} * * *`;\n },\n description: 'Todos los días a una hora específica',\n },\n\n // \"cada semana\" → 0 0 * * 0\n {\n regex: /^cada\\s+semana$/,\n toCron: () => '0 0 * * 0',\n description: 'Cada semana (domingo a medianoche)',\n },\n\n // \"todos los lunes\" or \"cada lunes\"\n {\n regex:\n /^(?:todos\\s+los|cada)\\s+(lunes|martes|mi[eé]rcoles|jueves|viernes|s[aá]bado|domingo)$/,\n toCron: (match, patterns) => {\n const day = parseDayOfWeek(match[1], patterns);\n if (day === null) throw new Error('Día inválido');\n return `0 0 * * ${day}`;\n },\n description: 'Cada día específico de la semana',\n },\n\n // \"todos los lunes a las 10am\"\n {\n regex:\n /^(?:todos\\s+los|cada)\\s+(lunes|martes|mi[eé]rcoles|jueves|viernes|s[aá]bado|domingo)\\s+a\\s+las?\\s+(.+)$/,\n toCron: (match, patterns) => {\n const day = parseDayOfWeek(match[1], patterns);\n const time = parseTimeString(match[2]);\n if (day === null || !time) throw new Error('Día u hora inválida');\n return `${time.minute} ${time.hour} * * ${day}`;\n },\n description: 'Cada día específico a una hora específica',\n },\n\n // \"cada mes\" → 0 0 1 * *\n {\n regex: /^cada\\s+mes$/,\n toCron: () => '0 0 1 * *',\n description: 'Cada mes (día 1 a medianoche)',\n },\n\n // \"el día 1 de cada mes\" or \"el dia 15 de cada mes\"\n {\n regex: /^el\\s+d[ií]a\\s+(\\d{1,2})\\s+de\\s+cada\\s+mes(?:\\s+a\\s+las?\\s+(.+))?$/,\n toCron: (match) => {\n const day = parseInt(match[1], 10);\n if (day < 1 || day > 31) throw new Error('Día del mes inválido');\n\n if (match[2]) {\n const time = parseTimeString(match[2]);\n if (!time) throw new Error('Formato de hora inválido');\n return `${time.minute} ${time.hour} ${day} * *`;\n }\n return `0 0 ${day} * *`;\n },\n description: 'Día específico de cada mes',\n },\n\n // \"cada año\" → 0 0 1 1 *\n {\n regex: /^cada\\s+a[ñn]o$/,\n toCron: () => '0 0 1 1 *',\n description: 'Cada año (1 de enero a medianoche)',\n },\n\n // \"a las 2am\" or \"a las 14:30\"\n {\n regex: /^a\\s+las?\\s+(.+)$/,\n toCron: (match) => {\n const time = parseTimeString(match[1]);\n if (!time) throw new Error('Formato de hora inválido');\n return `${time.minute} ${time.hour} * * *`;\n },\n description: 'Diariamente a una hora específica',\n },\n\n // \"días de semana a las 9am\" or \"dias laborales a las 9am\"\n {\n regex: /^(?:d[ií]as\\s+de\\s+semana|d[ií]as\\s+laborales)\\s+a\\s+las?\\s+(.+)$/,\n toCron: (match) => {\n const time = parseTimeString(match[1]);\n if (!time) throw new Error('Formato de hora inválido');\n return `${time.minute} ${time.hour} * * 1-5`;\n },\n description: 'Días de semana a una hora específica',\n },\n\n // \"fines de semana a las 10am\"\n {\n regex: /^fines?\\s+de\\s+semana\\s+a\\s+las?\\s+(.+)$/,\n toCron: (match) => {\n const time = parseTimeString(match[1]);\n if (!time) throw new Error('Formato de hora inválido');\n return `${time.minute} ${time.hour} * * 0,6`;\n },\n description: 'Fines de semana a una hora específica',\n },\n ],\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;\n }\n\n // Check for weekend\n if (days.length === 2 && days.includes(0) && days.includes(6)) {\n return i18n.weekend;\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"]}
@@ -1,2 +1,2 @@
1
- var h={"@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"}},p={JAN:1,FEB:2,MAR:3,APR:4,MAY:5,JUN:6,JUL:7,AUG:8,SEP:9,OCT:10,NOV:11,DEC:12},$={SUN:0,MON:1,TUE:2,WED:3,THU:4,FRI:5,SAT:6};function V(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 h[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=A(u,d,o);if(!f.isValid)return {isValid:false,error:f.error,field:o}}return {isValid:true}}function A(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("/")?E(r,e,t):r.includes(",")?D(r,e,t):r.includes("-")?S(r,e,t):C(r,e,t):{isValid:false,error:`${e.name} field cannot be empty`}}function E(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("-")?S(s,e,t):C(s,e,t)}function S(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=S(a,e,t);if(!i.isValid)return i}else {let i=C(a,e,t);if(!i.isValid)return i}}return {isValid:true}}function C(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=p[r.toUpperCase()];if(n!==void 0)return n}if(e==="dayOfWeek"){let n=$[r.toUpperCase()];if(n!==void 0)return n}return null}function M(r,e=false){let t=V(r,e);if(!t.isValid)throw new Error(t.error||"Invalid cron expression");let n=r.trim();if(n.startsWith("@")){let s=h[n];return {expression:n,...W(s,false),isSpecial:true,specialKeyword:n}}return {expression:n,...W(n,e),isSpecial:false}}function W(r,e){let t=r.split(/\s+/);if(e&&t.length===6){let[u,d,f,I,R,j]=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(j,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=k(e.min,e.max);else if(a)u=P(r,e,t);else if(o)u=T(r,e,t);else if(i)u=O(r,e,t);else {let d=g(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 P(r,e,t){let[n,s]=r.split("/"),a=parseInt(s,10),i;if(n==="*")i=k(e.min,e.max);else if(n.includes("-"))i=O(n,e,t);else {let u=g(n,t);i=u!==null?[u]:[];}let o=[];for(let u=0;u<i.length;u+=a)o.push(i[u]);return o}function O(r,e,t){let[n,s]=r.split("-"),a=g(n,t),i=g(s,t);return a===null||i===null?[]:k(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=O(i,e,t);s.push(...o);}else {let o=g(i,t);o!==null&&s.push(o);}}return s}function g(r,e){let t=parseInt(r,10);if(!isNaN(t))return t;if(e==="month"){let n=p[r.toUpperCase()];if(n!==void 0)return n}if(e==="dayOfWeek"){let n=$[r.toUpperCase()];if(n!==void 0)return n}return null}function k(r,e){let t=[];for(let n=r;n<=e;n++)t.push(n);return t}var w={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 x={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 N(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 ie(r,e={}){let{locale:t="en",use24HourFormat:n=true,includeSeconds:s=false,verbose:a=false}=e,i=t==="es"?w:x,o=M(r,s);return o.isSpecial&&o.specialKeyword?L(o.specialKeyword,i):_(o,i,n,a)}function L(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 _(r,e,t,n){let s=[],a=Y(r,e,t);a&&s.push(a);let i=U(r,e,n);return i&&s.push(i),s.join(", ")}function Y(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=c(s.values[0],t,e);return `${e.everyMinute} ${e.at} ${i}`}if(s.values.length>1&&s.isRange){let i=c(s.values[0],t,e),o=c(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:y(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&&N(s.values)){let i=t?v(s.values[0],n.values[0]):y(s.values[0],n.values[0],e),o=t?v(s.values[s.values.length-1],n.values[0]):y(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=c(s.values[0],t,e),u=c(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 K(r,e,t)}function U(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=H(a.values,e,t);o&&i.push(o);}if(!n.isWildcard&&a.isWildcard){let o=J(n.values,e,t);o&&i.push(o);}if(!s.isWildcard){let o=z(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 y(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 c(r,e,t){return e?`${r.toString().padStart(2,"0")}:00`:y(r,0,t)}function K(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):y(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 H(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 J(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 z(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{ie as formatCron};//# sourceMappingURL=formatter.js.map
1
+ var h={"@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 * * * *"},u={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"}},p={JAN:1,FEB:2,MAR:3,APR:4,MAY:5,JUN:6,JUL:7,AUG:8,SEP:9,OCT:10,NOV:11,DEC:12},$={SUN:0,MON:1,TUE:2,WED:3,THU:4,FRI:5,SAT:6};function k(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 h[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 o=e?["second","minute","hour","dayOfMonth","month","dayOfWeek"]:["minute","hour","dayOfMonth","month","dayOfWeek"];for(let i=0;i<n.length;i++){let a=o[i],d=n[i],l=u[a],c=R(d,l,a);if(!c.isValid)return {isValid:false,error:c.error,field:a}}return {isValid:true}}function R(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("/")?D(r,e,t):r.includes(",")?P(r,e,t):r.includes("-")?C(r,e,t):w(r,e,t):{isValid:false,error:`${e.name} field cannot be empty`}}function D(r,e,t){let n=r.split("/");if(n.length!==2)return {isValid:false,error:`Invalid step syntax in ${e.name}: ${r}`};let[s,o]=n,i=parseInt(o,10);return isNaN(i)||i<=0?{isValid:false,error:`Invalid step value in ${e.name}: ${o}`}:s==="*"?{isValid:true}:s.includes("-")?C(s,e,t):w(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,o]=n,i=b(s,t),a=b(o,t);return i===null?{isValid:false,error:`Invalid start value in ${e.name} range: ${s}`}:a===null?{isValid:false,error:`Invalid end value in ${e.name} range: ${o}`}:i<e.min||i>e.max?{isValid:false,error:`Start value ${i} is out of range for ${e.name} (${e.min}-${e.max})`}:a<e.min||a>e.max?{isValid:false,error:`End value ${a} is out of range for ${e.name} (${e.min}-${e.max})`}:i>a?{isValid:false,error:`Start value ${i} cannot be greater than end value ${a} in ${e.name}`}:{isValid:true}}function P(r,e,t){let n=r.split(",");for(let s of n){let o=s.trim();if(!o)return {isValid:false,error:`Empty value in ${e.name} list`};if(o.includes("-")){let i=C(o,e,t);if(!i.isValid)return i}else {let i=w(o,e,t);if(!i.isValid)return i}}return {isValid:true}}function w(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=p[r.toUpperCase()];if(n!==void 0)return n}if(e==="dayOfWeek"){let n=$[r.toUpperCase()];if(n!==void 0)return n}return null}function O(r,e=false){let t=k(r,e);if(!t.isValid)throw new Error(t.error||"Invalid cron expression");let n=r.trim();if(n.startsWith("@")){let s=h[n];return {expression:n,...E(s,false),isSpecial:true,specialKeyword:n}}return {expression:n,...E(n,e),isSpecial:false}}function E(r,e){let t=r.split(/\s+/);if(e&&t.length===6){let[d,l,c,V,F,j]=t;return {second:m(d,u.second,"second"),minute:m(l,u.minute,"minute"),hour:m(c,u.hour,"hour"),dayOfMonth:m(V,u.dayOfMonth,"dayOfMonth"),month:m(F,u.month,"month"),dayOfWeek:m(j,u.dayOfWeek,"dayOfWeek")}}let[n,s,o,i,a]=t;return {minute:m(n,u.minute,"minute"),hour:m(s,u.hour,"hour"),dayOfMonth:m(o,u.dayOfMonth,"dayOfMonth"),month:m(i,u.month,"month"),dayOfWeek:m(a,u.dayOfWeek,"dayOfWeek")}}function m(r,e,t){let n=r,s=r==="*"||r==="?",o=r.includes("/"),i=r.includes("-")&&!o,a=r.includes(","),d;if(s)d=S(e.min,e.max);else if(o)d=A(r,e,t);else if(a)d=T(r,e,t);else if(i)d=x(r,e,t);else {let l=f(r,t);d=l!==null?[l]:[];}return t==="dayOfWeek"&&(d=d.map(l=>l===7?0:l),d=[...new Set(d)]),d.sort((l,c)=>l-c),{raw:n,values:d,isWildcard:s,isRange:i,isStep:o,isList:a}}function A(r,e,t){let[n,s]=r.split("/"),o=parseInt(s,10),i;if(n==="*")i=S(e.min,e.max);else if(n.includes("-"))i=x(n,e,t);else {let d=f(n,t);i=d!==null?[d]:[];}let a=[];for(let d=0;d<i.length;d+=o)a.push(i[d]);return a}function x(r,e,t){let[n,s]=r.split("-"),o=f(n,t),i=f(s,t);return o===null||i===null?[]:S(o,i)}function T(r,e,t){let n=r.split(","),s=[];for(let o of n){let i=o.trim();if(i.includes("-")){let a=x(i,e,t);s.push(...a);}else {let a=f(i,t);a!==null&&s.push(a);}}return s}function f(r,e){let t=parseInt(r,10);if(!isNaN(t))return t;if(e==="month"){let n=p[r.toUpperCase()];if(n!==void 0)return n}if(e==="dayOfWeek"){let n=$[r.toUpperCase()];if(n!==void 0)return n}return null}function S(r,e){let t=[];for(let n=r;n<=e;n++)t.push(n);return t}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:"weekdays",weekend:"weekends"};var I={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\xEDas de semana",weekend:"fines de semana"};function N(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 ie(r,e={}){let{locale:t="en",use24HourFormat:n=true,includeSeconds:s=false,verbose:o=false}=e,i=t==="es"?I:W,a=O(r,s);return a.isSpecial&&a.specialKeyword?L(a.specialKeyword,i):H(a,i,n,o)}function L(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 H(r,e,t,n){let s=[],o=_(r,e,t);o&&s.push(o);let i=Y(r,e,n);return i&&s.push(i),s.join(", ")}function _(r,e,t){let{minute:n,hour:s,second:o}=r;if(n.isWildcard&&s.isWildcard)return o&&!o.isWildcard?`${e.at} ${e.second} ${o.values.join(", ")}`:e.everyMinute;if(n.isWildcard){if(s.values.length===1){let i=y(s.values[0],t,e);return `${e.everyMinute} ${e.at} ${i}`}if(s.values.length>1&&s.isRange){let i=y(s.values[0],t,e),a=y(s.values[s.values.length-1],t,e);return `${e.everyMinute}, ${e.between} ${i} ${e.and} ${a}`}}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]),a=t?i:g(s.values[0],n.values[0],e);return `${e.at} ${a}`}if(n.values.length>1||s.values.length>1){if(n.values.length===1&&s.isRange&&s.values.length>1&&N(s.values)){let i=t?v(s.values[0],n.values[0]):g(s.values[0],n.values[0],e),a=t?v(s.values[s.values.length-1],n.values[0]):g(s.values[s.values.length-1],n.values[0],e);return `${e.between} ${i} ${e.and} ${a}`}if(n.isStep){let i=n.values[1]-n.values[0];if(s.isRange){let a=y(s.values[0],t,e),d=y(s.values[s.values.length-1],t,e);return `${e.every} ${i} ${e.minutes}, ${e.between} ${a} ${e.and} ${d}`}return `${e.every} ${i} ${e.minutes}`}}}return U(r,e,t)}function Y(r,e,t){let{dayOfMonth:n,month:s,dayOfWeek:o}=r;if(n.isWildcard&&o.isWildcard&&s.isWildcard)return e.everyDay;let i=[];if(!o.isWildcard){let a=z(o.values,e,t);a&&i.push(a);}if(!n.isWildcard&&o.isWildcard){let a=K(n.values,e,t);a&&i.push(a);}if(!s.isWildcard){let a=J(s.values,e,t);a&&i.push(a);}return i.join(", ")}function v(r,e){return `${r.toString().padStart(2,"0")}:${e.toString().padStart(2,"0")}`}function g(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 y(r,e,t){return e?`${r.toString().padStart(2,"0")}:00`:g(r,0,t)}function U(r,e,t){let n=[];for(let s of r.hour.values)for(let o of r.minute.values){let i=t?v(s,o):g(s,o,e);n.push(i);}return n.length<=3?`${e.at} ${n.join(", ")}`:`${e.at} ${n.slice(0,2).join(", ")}... (${n.length} times)`}function z(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;if(r.length===2&&r.includes(0)&&r.includes(6))return e.weekend;if(r.length===1)return e.on+" "+n[r[0]];if(r.length===7)return e.everyDay;let s=r.map(o=>n[o]);return t||r.length<=3?M(s,e):`${s[0]} ${e.through} ${s[s.length-1]}`}function K(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 J(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(o=>n[o-1]);return t||r.length<=3?`${e.in} ${M(s,e)}`:`${e.in} ${s[0]} ${e.through} ${s[s.length-1]}`}function M(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{ie as formatCron};//# sourceMappingURL=formatter.js.map
2
2
  //# sourceMappingURL=formatter.js.map