soff-cron 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +300 -0
- package/dist/core/formatter.cjs +2 -0
- package/dist/core/formatter.cjs.map +1 -0
- package/dist/core/formatter.d.cts +19 -0
- package/dist/core/formatter.d.ts +19 -0
- package/dist/core/formatter.js +2 -0
- package/dist/core/formatter.js.map +1 -0
- package/dist/core/parser.cjs +2 -0
- package/dist/core/parser.cjs.map +1 -0
- package/dist/core/parser.d.cts +20 -0
- package/dist/core/parser.d.ts +20 -0
- package/dist/core/parser.js +2 -0
- package/dist/core/parser.js.map +1 -0
- package/dist/core/types.cjs +2 -0
- package/dist/core/types.cjs.map +1 -0
- package/dist/core/types.d.cts +142 -0
- package/dist/core/types.d.ts +142 -0
- package/dist/core/types.js +2 -0
- package/dist/core/types.js.map +1 -0
- package/dist/core/validator.cjs +2 -0
- package/dist/core/validator.cjs.map +1 -0
- package/dist/core/validator.d.cts +19 -0
- package/dist/core/validator.d.ts +19 -0
- package/dist/core/validator.js +2 -0
- package/dist/core/validator.js.map +1 -0
- package/dist/i18n/en.cjs +2 -0
- package/dist/i18n/en.cjs.map +1 -0
- package/dist/i18n/en.d.cts +5 -0
- package/dist/i18n/en.d.ts +5 -0
- package/dist/i18n/en.js +2 -0
- package/dist/i18n/en.js.map +1 -0
- package/dist/i18n/es.cjs +2 -0
- package/dist/i18n/es.cjs.map +1 -0
- package/dist/i18n/es.d.cts +61 -0
- package/dist/i18n/es.d.ts +61 -0
- package/dist/i18n/es.js +2 -0
- package/dist/i18n/es.js.map +1 -0
- package/dist/index.cjs +2 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +4 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/package.json +124 -0
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Represents a parsed cron expression field with its values
|
|
3
|
+
*/
|
|
4
|
+
interface CronField {
|
|
5
|
+
/**
|
|
6
|
+
* Raw value from the cron expression (e.g., "*", "0-5", step values)
|
|
7
|
+
*/
|
|
8
|
+
raw: string;
|
|
9
|
+
/**
|
|
10
|
+
* Parsed values as an array of numbers
|
|
11
|
+
* For "*", this will be all valid values for the field
|
|
12
|
+
* For ranges like "0-5", this will be [0, 1, 2, 3, 4, 5]
|
|
13
|
+
* For steps, this will be [0, 15, 30, 45] (example)
|
|
14
|
+
*/
|
|
15
|
+
values: number[];
|
|
16
|
+
/**
|
|
17
|
+
* Whether this field uses the wildcard "*"
|
|
18
|
+
*/
|
|
19
|
+
isWildcard: boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Whether this field uses a range (e.g., "0-5")
|
|
22
|
+
*/
|
|
23
|
+
isRange: boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Whether this field uses a step value
|
|
26
|
+
*/
|
|
27
|
+
isStep: boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Whether this field is a list of values (e.g., "1,3,5")
|
|
30
|
+
*/
|
|
31
|
+
isList: boolean;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Represents a fully parsed cron expression
|
|
35
|
+
*/
|
|
36
|
+
interface ParsedCron {
|
|
37
|
+
/**
|
|
38
|
+
* The original cron expression string
|
|
39
|
+
*/
|
|
40
|
+
expression: string;
|
|
41
|
+
/**
|
|
42
|
+
* Minute field (0-59)
|
|
43
|
+
*/
|
|
44
|
+
minute: CronField;
|
|
45
|
+
/**
|
|
46
|
+
* Hour field (0-23)
|
|
47
|
+
*/
|
|
48
|
+
hour: CronField;
|
|
49
|
+
/**
|
|
50
|
+
* Day of month field (1-31)
|
|
51
|
+
*/
|
|
52
|
+
dayOfMonth: CronField;
|
|
53
|
+
/**
|
|
54
|
+
* Month field (1-12)
|
|
55
|
+
*/
|
|
56
|
+
month: CronField;
|
|
57
|
+
/**
|
|
58
|
+
* Day of week field (0-7, where 0 and 7 are Sunday)
|
|
59
|
+
*/
|
|
60
|
+
dayOfWeek: CronField;
|
|
61
|
+
/**
|
|
62
|
+
* Optional second field (0-59) for 6-field cron expressions
|
|
63
|
+
*/
|
|
64
|
+
second?: CronField;
|
|
65
|
+
/**
|
|
66
|
+
* Whether this is a special expression like @daily, @hourly, etc.
|
|
67
|
+
*/
|
|
68
|
+
isSpecial: boolean;
|
|
69
|
+
/**
|
|
70
|
+
* The special keyword if applicable
|
|
71
|
+
*/
|
|
72
|
+
specialKeyword?: string;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Locale options for formatting
|
|
76
|
+
*/
|
|
77
|
+
type Locale = 'es' | 'en';
|
|
78
|
+
/**
|
|
79
|
+
* Options for formatting cron expressions
|
|
80
|
+
*/
|
|
81
|
+
interface FormatterOptions {
|
|
82
|
+
/**
|
|
83
|
+
* Locale for the output text
|
|
84
|
+
* @default 'en'
|
|
85
|
+
*/
|
|
86
|
+
locale?: Locale;
|
|
87
|
+
/**
|
|
88
|
+
* Whether to use 24-hour format for times
|
|
89
|
+
* @default true
|
|
90
|
+
*/
|
|
91
|
+
use24HourFormat?: boolean;
|
|
92
|
+
/**
|
|
93
|
+
* Whether to include seconds in the output (for 6-field cron)
|
|
94
|
+
* @default false
|
|
95
|
+
*/
|
|
96
|
+
includeSeconds?: boolean;
|
|
97
|
+
/**
|
|
98
|
+
* Whether to use verbose descriptions
|
|
99
|
+
* @default false
|
|
100
|
+
*/
|
|
101
|
+
verbose?: boolean;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Validation result for cron expressions
|
|
105
|
+
*/
|
|
106
|
+
interface ValidationResult {
|
|
107
|
+
/**
|
|
108
|
+
* Whether the cron expression is valid
|
|
109
|
+
*/
|
|
110
|
+
isValid: boolean;
|
|
111
|
+
/**
|
|
112
|
+
* Error message if validation failed
|
|
113
|
+
*/
|
|
114
|
+
error?: string;
|
|
115
|
+
/**
|
|
116
|
+
* The field that caused the error (if applicable)
|
|
117
|
+
*/
|
|
118
|
+
field?: 'minute' | 'hour' | 'dayOfMonth' | 'month' | 'dayOfWeek' | 'second';
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Special cron keywords and their equivalents
|
|
122
|
+
*/
|
|
123
|
+
declare const SPECIAL_KEYWORDS: Record<string, string>;
|
|
124
|
+
/**
|
|
125
|
+
* Field constraints for validation
|
|
126
|
+
*/
|
|
127
|
+
interface FieldConstraints {
|
|
128
|
+
min: number;
|
|
129
|
+
max: number;
|
|
130
|
+
name: string;
|
|
131
|
+
}
|
|
132
|
+
declare const FIELD_CONSTRAINTS: Record<string, FieldConstraints>;
|
|
133
|
+
/**
|
|
134
|
+
* Month names mapping (1-12)
|
|
135
|
+
*/
|
|
136
|
+
declare const MONTH_NAMES: Record<string, number>;
|
|
137
|
+
/**
|
|
138
|
+
* Day of week names mapping (0-7)
|
|
139
|
+
*/
|
|
140
|
+
declare const DAY_NAMES: Record<string, number>;
|
|
141
|
+
|
|
142
|
+
export { type CronField, DAY_NAMES, FIELD_CONSTRAINTS, type FieldConstraints, type FormatterOptions, type Locale, MONTH_NAMES, type ParsedCron, SPECIAL_KEYWORDS, type ValidationResult };
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
var e={"@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 * * * *"},n={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"}},o={JAN:1,FEB:2,MAR:3,APR:4,MAY:5,JUN:6,JUL:7,AUG:8,SEP:9,OCT:10,NOV:11,DEC:12},r={SUN:0,MON:1,TUE:2,WED:3,THU:4,FRI:5,SAT:6};export{r as DAY_NAMES,n as FIELD_CONSTRAINTS,o as MONTH_NAMES,e as SPECIAL_KEYWORDS};//# sourceMappingURL=types.js.map
|
|
2
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/core/types.ts"],"names":["SPECIAL_KEYWORDS","FIELD_CONSTRAINTS","MONTH_NAMES","DAY_NAMES"],"mappings":"AAiJO,IAAMA,CAAAA,CAA2C,CACtD,SAAA,CAAW,WAAA,CACX,WAAA,CAAa,WAAA,CACb,UAAA,CAAY,WAAA,CACZ,SAAA,CAAW,WAAA,CACX,QAAA,CAAU,WAAA,CACV,WAAA,CAAa,YACb,SAAA,CAAW,WACb,CAAA,CAWaC,CAAAA,CAAsD,CACjE,MAAA,CAAQ,CAAE,GAAA,CAAK,CAAA,CAAG,GAAA,CAAK,EAAA,CAAI,IAAA,CAAM,QAAS,CAAA,CAC1C,KAAM,CAAE,GAAA,CAAK,CAAA,CAAG,GAAA,CAAK,EAAA,CAAI,IAAA,CAAM,MAAO,CAAA,CACtC,UAAA,CAAY,CAAE,GAAA,CAAK,CAAA,CAAG,GAAA,CAAK,EAAA,CAAI,KAAM,cAAe,CAAA,CACpD,KAAA,CAAO,CAAE,GAAA,CAAK,CAAA,CAAG,GAAA,CAAK,EAAA,CAAI,IAAA,CAAM,OAAQ,CAAA,CACxC,SAAA,CAAW,CAAE,GAAA,CAAK,EAAG,GAAA,CAAK,CAAA,CAAG,IAAA,CAAM,aAAc,CAAA,CACjD,MAAA,CAAQ,CAAE,GAAA,CAAK,CAAA,CAAG,GAAA,CAAK,EAAA,CAAI,IAAA,CAAM,QAAS,CAC5C,EAKaC,CAAAA,CAAsC,CACjD,GAAA,CAAK,CAAA,CACL,GAAA,CAAK,CAAA,CACL,GAAA,CAAK,CAAA,CACL,GAAA,CAAK,CAAA,CACL,GAAA,CAAK,CAAA,CACL,GAAA,CAAK,CAAA,CACL,IAAK,CAAA,CACL,GAAA,CAAK,CAAA,CACL,GAAA,CAAK,CAAA,CACL,GAAA,CAAK,EAAA,CACL,GAAA,CAAK,EAAA,CACL,GAAA,CAAK,EACP,CAAA,CAKaC,CAAAA,CAAoC,CAC/C,IAAK,CAAA,CACL,GAAA,CAAK,CAAA,CACL,GAAA,CAAK,CAAA,CACL,GAAA,CAAK,CAAA,CACL,GAAA,CAAK,CAAA,CACL,GAAA,CAAK,CAAA,CACL,GAAA,CAAK,CACP","file":"types.js","sourcesContent":["/**\n * Represents a parsed cron expression field with its values\n */\nexport interface CronField {\n /**\n * Raw value from the cron expression (e.g., \"*\", \"0-5\", step values)\n */\n raw: string;\n\n /**\n * Parsed values as an array of numbers\n * For \"*\", this will be all valid values for the field\n * For ranges like \"0-5\", this will be [0, 1, 2, 3, 4, 5]\n * For steps, this will be [0, 15, 30, 45] (example)\n */\n values: number[];\n\n /**\n * Whether this field uses the wildcard \"*\"\n */\n isWildcard: boolean;\n\n /**\n * Whether this field uses a range (e.g., \"0-5\")\n */\n isRange: boolean;\n\n /**\n * Whether this field uses a step value\n */\n isStep: boolean;\n\n /**\n * Whether this field is a list of values (e.g., \"1,3,5\")\n */\n isList: boolean;\n}\n\n/**\n * Represents a fully parsed cron expression\n */\nexport interface ParsedCron {\n /**\n * The original cron expression string\n */\n expression: string;\n\n /**\n * Minute field (0-59)\n */\n minute: CronField;\n\n /**\n * Hour field (0-23)\n */\n hour: CronField;\n\n /**\n * Day of month field (1-31)\n */\n dayOfMonth: CronField;\n\n /**\n * Month field (1-12)\n */\n month: CronField;\n\n /**\n * Day of week field (0-7, where 0 and 7 are Sunday)\n */\n dayOfWeek: CronField;\n\n /**\n * Optional second field (0-59) for 6-field cron expressions\n */\n second?: CronField;\n\n /**\n * Whether this is a special expression like @daily, @hourly, etc.\n */\n isSpecial: boolean;\n\n /**\n * The special keyword if applicable\n */\n specialKeyword?: string;\n}\n\n/**\n * Locale options for formatting\n */\nexport type Locale = 'es' | 'en';\n\n/**\n * Options for formatting cron expressions\n */\nexport interface FormatterOptions {\n /**\n * Locale for the output text\n * @default 'en'\n */\n locale?: Locale;\n\n /**\n * Whether to use 24-hour format for times\n * @default true\n */\n use24HourFormat?: boolean;\n\n /**\n * Whether to include seconds in the output (for 6-field cron)\n * @default false\n */\n includeSeconds?: boolean;\n\n /**\n * Whether to use verbose descriptions\n * @default false\n */\n verbose?: boolean;\n}\n\n/**\n * Validation result for cron expressions\n */\nexport interface ValidationResult {\n /**\n * Whether the cron expression is valid\n */\n isValid: boolean;\n\n /**\n * Error message if validation failed\n */\n error?: string;\n\n /**\n * The field that caused the error (if applicable)\n */\n field?: 'minute' | 'hour' | 'dayOfMonth' | 'month' | 'dayOfWeek' | 'second';\n}\n\n/**\n * Special cron keywords and their equivalents\n */\nexport const SPECIAL_KEYWORDS: Record<string, string> = {\n '@yearly': '0 0 1 1 *',\n '@annually': '0 0 1 1 *',\n '@monthly': '0 0 1 * *',\n '@weekly': '0 0 * * 0',\n '@daily': '0 0 * * *',\n '@midnight': '0 0 * * *',\n '@hourly': '0 * * * *',\n};\n\n/**\n * Field constraints for validation\n */\nexport interface FieldConstraints {\n min: number;\n max: number;\n name: string;\n}\n\nexport const FIELD_CONSTRAINTS: Record<string, FieldConstraints> = {\n minute: { min: 0, max: 59, name: 'minute' },\n hour: { min: 0, max: 23, name: 'hour' },\n dayOfMonth: { min: 1, max: 31, name: 'day of month' },\n month: { min: 1, max: 12, name: 'month' },\n dayOfWeek: { min: 0, max: 7, name: 'day of week' },\n second: { min: 0, max: 59, name: 'second' },\n};\n\n/**\n * Month names mapping (1-12)\n */\nexport const MONTH_NAMES: Record<string, number> = {\n JAN: 1,\n FEB: 2,\n MAR: 3,\n APR: 4,\n MAY: 5,\n JUN: 6,\n JUL: 7,\n AUG: 8,\n SEP: 9,\n OCT: 10,\n NOV: 11,\n DEC: 12,\n};\n\n/**\n * Day of week names mapping (0-7)\n */\nexport const DAY_NAMES: Record<string, number> = {\n SUN: 0,\n MON: 1,\n TUE: 2,\n WED: 3,\n THU: 4,\n FRI: 5,\n SAT: 6,\n};\n"]}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
'use strict';var m={"@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 * * * *"},p={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"}},g={JAN:1,FEB:2,MAR:3,APR:4,MAY:5,JUN:6,JUL:7,AUG:8,SEP:9,OCT:10,NOV:11,DEC:12},V={SUN:0,MON:1,TUE:2,WED:3,THU:4,FRI:5,SAT:6};function O(r,e=false){if(!r||typeof r!="string")return {isValid:false,error:"Cron expression must be a non-empty string"};let n=r.trim();if(n.startsWith("@"))return m[n]?{isValid:true}:{isValid:false,error:`Unknown special keyword: ${n}`};let i=n.split(/\s+/),a=e?6:5;if(i.length!==a)return {isValid:false,error:`Expected ${a} fields, got ${i.length}`};let l=e?["second","minute","hour","dayOfMonth","month","dayOfWeek"]:["minute","hour","dayOfMonth","month","dayOfWeek"];for(let t=0;t<i.length;t++){let o=l[t],c=i[t],y=p[o],f=$(c,y,o);if(!f.isValid)return {isValid:false,error:f.error,field:o}}return {isValid:true}}function $(r,e,n){return r?r==="*"?{isValid:true}:r==="?"?n==="dayOfMonth"||n==="dayOfWeek"?{isValid:true}:{isValid:false,error:`Question mark (?) is only valid for day fields, not ${e.name}`}:r.includes("/")?h(r,e,n):r.includes(",")?x(r,e,n):r.includes("-")?d(r,e,n):u(r,e,n):{isValid:false,error:`${e.name} field cannot be empty`}}function h(r,e,n){let i=r.split("/");if(i.length!==2)return {isValid:false,error:`Invalid step syntax in ${e.name}: ${r}`};let[a,l]=i,t=parseInt(l,10);return isNaN(t)||t<=0?{isValid:false,error:`Invalid step value in ${e.name}: ${l}`}:a==="*"?{isValid:true}:a.includes("-")?d(a,e,n):u(a,e,n)}function d(r,e,n){let i=r.split("-");if(i.length!==2)return {isValid:false,error:`Invalid range syntax in ${e.name}: ${r}`};let[a,l]=i,t=s(a,n),o=s(l,n);return t===null?{isValid:false,error:`Invalid start value in ${e.name} range: ${a}`}:o===null?{isValid:false,error:`Invalid end value in ${e.name} range: ${l}`}:t<e.min||t>e.max?{isValid:false,error:`Start value ${t} 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})`}:t>o?{isValid:false,error:`Start value ${t} cannot be greater than end value ${o} in ${e.name}`}:{isValid:true}}function x(r,e,n){let i=r.split(",");for(let a of i){let l=a.trim();if(!l)return {isValid:false,error:`Empty value in ${e.name} list`};if(l.includes("-")){let t=d(l,e,n);if(!t.isValid)return t}else {let t=u(l,e,n);if(!t.isValid)return t}}return {isValid:true}}function u(r,e,n){let i=s(r,n);return i===null?{isValid:false,error:`Invalid value in ${e.name}: ${r}`}:i<e.min||i>e.max?{isValid:false,error:`Value ${i} is out of range for ${e.name} (${e.min}-${e.max})`}:{isValid:true}}function s(r,e){let n=parseInt(r,10);if(!isNaN(n))return n;if(e==="month"){let i=g[r.toUpperCase()];if(i!==void 0)return i}if(e==="dayOfWeek"){let i=V[r.toUpperCase()];if(i!==void 0)return i}return null}exports.validateCron=O;//# sourceMappingURL=validator.cjs.map
|
|
2
|
+
//# sourceMappingURL=validator.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/core/types.ts","../../src/core/validator.ts"],"names":["SPECIAL_KEYWORDS","FIELD_CONSTRAINTS","MONTH_NAMES","DAY_NAMES","validateCron","expression","allowSeconds","trimmed","fields","expectedFields","fieldNames","i","fieldName","fieldValue","constraints","result","validateField","value","validateStepField","validateListField","validateRangeField","validateSingleValue","parts","range","step","stepNum","startStr","endStr","start","parseFieldValue","end","values","val","num","monthNum","dayNum"],"mappings":"aAiJO,IAAMA,EAA2C,CACtD,SAAA,CAAW,YACX,WAAA,CAAa,WAAA,CACb,WAAY,WAAA,CACZ,SAAA,CAAW,WAAA,CACX,QAAA,CAAU,YACV,WAAA,CAAa,WAAA,CACb,UAAW,WACb,CAAA,CAWaC,EAAsD,CACjE,MAAA,CAAQ,CAAE,GAAA,CAAK,EAAG,GAAA,CAAK,EAAA,CAAI,KAAM,QAAS,CAAA,CAC1C,KAAM,CAAE,GAAA,CAAK,EAAG,GAAA,CAAK,EAAA,CAAI,KAAM,MAAO,CAAA,CACtC,WAAY,CAAE,GAAA,CAAK,EAAG,GAAA,CAAK,EAAA,CAAI,IAAA,CAAM,cAAe,EACpD,KAAA,CAAO,CAAE,IAAK,CAAA,CAAG,GAAA,CAAK,GAAI,IAAA,CAAM,OAAQ,EACxC,SAAA,CAAW,CAAE,IAAK,CAAA,CAAG,GAAA,CAAK,EAAG,IAAA,CAAM,aAAc,EACjD,MAAA,CAAQ,CAAE,GAAA,CAAK,CAAA,CAAG,IAAK,EAAA,CAAI,IAAA,CAAM,QAAS,CAC5C,CAAA,CAKaC,EAAsC,CACjD,GAAA,CAAK,EACL,GAAA,CAAK,CAAA,CACL,IAAK,CAAA,CACL,GAAA,CAAK,EACL,GAAA,CAAK,CAAA,CACL,IAAK,CAAA,CACL,GAAA,CAAK,CAAA,CACL,GAAA,CAAK,EACL,GAAA,CAAK,CAAA,CACL,IAAK,EAAA,CACL,GAAA,CAAK,GACL,GAAA,CAAK,EACP,CAAA,CAKaC,CAAAA,CAAoC,CAC/C,GAAA,CAAK,CAAA,CACL,IAAK,CAAA,CACL,GAAA,CAAK,EACL,GAAA,CAAK,CAAA,CACL,GAAA,CAAK,CAAA,CACL,IAAK,CAAA,CACL,GAAA,CAAK,CACP,CAAA,CCzLO,SAASC,EAAaC,CAAAA,CAAoBC,CAAAA,CAAe,MAAyB,CACvF,GAAI,CAACD,CAAAA,EAAc,OAAOA,GAAe,QAAA,CACvC,OAAO,CACL,OAAA,CAAS,KAAA,CACT,KAAA,CAAO,4CACT,EAGF,IAAME,CAAAA,CAAUF,EAAW,IAAA,EAAK,CAGhC,GAAIE,CAAAA,CAAQ,UAAA,CAAW,GAAG,CAAA,CACxB,OAAIP,EAAiBO,CAAO,CAAA,CACnB,CAAE,OAAA,CAAS,IAAK,EAElB,CACL,OAAA,CAAS,KAAA,CACT,KAAA,CAAO,4BAA4BA,CAAO,CAAA,CAC5C,EAIF,IAAMC,CAAAA,CAASD,EAAQ,KAAA,CAAM,KAAK,EAC5BE,CAAAA,CAAiBH,CAAAA,CAAe,EAAI,CAAA,CAE1C,GAAIE,EAAO,MAAA,GAAWC,CAAAA,CACpB,OAAO,CACL,OAAA,CAAS,KAAA,CACT,KAAA,CAAO,YAAYA,CAAc,CAAA,aAAA,EAAgBD,EAAO,MAAM,CAAA,CAChE,EAIF,IAAME,CAAAA,CAAaJ,CAAAA,CACf,CAAC,SAAU,QAAA,CAAU,MAAA,CAAQ,aAAc,OAAA,CAAS,WAAW,EAC/D,CAAC,QAAA,CAAU,MAAA,CAAQ,YAAA,CAAc,QAAS,WAAW,CAAA,CAGzD,QAASK,CAAAA,CAAI,CAAA,CAAGA,EAAIH,CAAAA,CAAO,MAAA,CAAQG,IAAK,CACtC,IAAMC,EAAYF,CAAAA,CAAWC,CAAC,EACxBE,CAAAA,CAAaL,CAAAA,CAAOG,CAAC,CAAA,CACrBG,CAAAA,CAAcb,CAAAA,CAAkBW,CAAS,EAEzCG,CAAAA,CAASC,CAAAA,CAAcH,EAAYC,CAAAA,CAAaF,CAAS,EAC/D,GAAI,CAACG,EAAO,OAAA,CACV,OAAO,CACL,OAAA,CAAS,KAAA,CACT,MAAOA,CAAAA,CAAO,KAAA,CACd,MAAOH,CACT,CAEJ,CAEA,OAAO,CAAE,OAAA,CAAS,IAAK,CACzB,CAKA,SAASI,EACPC,CAAAA,CACAH,CAAAA,CACAF,EACkB,CAClB,OAAKK,EAQDA,CAAAA,GAAU,GAAA,CACL,CAAE,OAAA,CAAS,IAAK,EAIrBA,CAAAA,GAAU,GAAA,CACRL,CAAAA,GAAc,YAAA,EAAgBA,IAAc,WAAA,CACvC,CAAE,QAAS,IAAK,CAAA,CAElB,CACL,OAAA,CAAS,KAAA,CACT,MAAO,CAAA,oDAAA,EAAuDE,CAAAA,CAAY,IAAI,CAAA,CAChF,CAAA,CAIEG,EAAM,QAAA,CAAS,GAAG,EACbC,CAAAA,CAAkBD,CAAAA,CAAOH,CAAAA,CAAaF,CAAS,EAKpDK,CAAAA,CAAM,QAAA,CAAS,GAAG,CAAA,CACbE,CAAAA,CAAkBF,EAAOH,CAAAA,CAAaF,CAAS,EAIpDK,CAAAA,CAAM,QAAA,CAAS,GAAG,CAAA,CACbG,CAAAA,CAAmBH,EAAOH,CAAAA,CAAaF,CAAS,EAIlDS,CAAAA,CAAoBJ,CAAAA,CAAOH,CAAAA,CAAaF,CAAS,EAvC/C,CACL,OAAA,CAAS,MACT,KAAA,CAAO,CAAA,EAAGE,EAAY,IAAI,CAAA,sBAAA,CAC5B,CAqCJ,CAKA,SAASI,EACPD,CAAAA,CACAH,CAAAA,CACAF,EACkB,CAClB,IAAMU,EAAQL,CAAAA,CAAM,KAAA,CAAM,GAAG,CAAA,CAC7B,GAAIK,CAAAA,CAAM,MAAA,GAAW,EACnB,OAAO,CACL,QAAS,KAAA,CACT,KAAA,CAAO,0BAA0BR,CAAAA,CAAY,IAAI,KAAKG,CAAK,CAAA,CAC7D,EAGF,GAAM,CAACM,EAAOC,CAAI,CAAA,CAAIF,CAAAA,CAGhBG,CAAAA,CAAU,SAASD,CAAAA,CAAM,EAAE,EACjC,OAAI,KAAA,CAAMC,CAAO,CAAA,EAAKA,CAAAA,EAAW,CAAA,CACxB,CACL,QAAS,KAAA,CACT,KAAA,CAAO,yBAAyBX,CAAAA,CAAY,IAAI,KAAKU,CAAI,CAAA,CAC3D,CAAA,CAIED,CAAAA,GAAU,IACL,CAAE,OAAA,CAAS,IAAK,CAAA,CAIrBA,CAAAA,CAAM,SAAS,GAAG,CAAA,CACbH,EAAmBG,CAAAA,CAAOT,CAAAA,CAAaF,CAAS,CAAA,CAGlDS,CAAAA,CAAoBE,EAAOT,CAAAA,CAAaF,CAAS,CAC1D,CAKA,SAASQ,CAAAA,CACPH,CAAAA,CACAH,EACAF,CAAAA,CACkB,CAClB,IAAMU,CAAAA,CAAQL,CAAAA,CAAM,MAAM,GAAG,CAAA,CAC7B,GAAIK,CAAAA,CAAM,MAAA,GAAW,EACnB,OAAO,CACL,QAAS,KAAA,CACT,KAAA,CAAO,2BAA2BR,CAAAA,CAAY,IAAI,CAAA,EAAA,EAAKG,CAAK,EAC9D,CAAA,CAGF,GAAM,CAACS,CAAAA,CAAUC,CAAM,EAAIL,CAAAA,CACrBM,CAAAA,CAAQC,EAAgBH,CAAAA,CAAUd,CAAS,EAC3CkB,CAAAA,CAAMD,CAAAA,CAAgBF,EAAQf,CAAS,CAAA,CAE7C,OAAIgB,CAAAA,GAAU,IAAA,CACL,CACL,OAAA,CAAS,MACT,KAAA,CAAO,CAAA,uBAAA,EAA0Bd,EAAY,IAAI,CAAA,QAAA,EAAWY,CAAQ,CAAA,CACtE,CAAA,CAGEI,IAAQ,IAAA,CACH,CACL,QAAS,KAAA,CACT,KAAA,CAAO,wBAAwBhB,CAAAA,CAAY,IAAI,WAAWa,CAAM,CAAA,CAClE,CAAA,CAGEC,CAAAA,CAAQd,EAAY,GAAA,EAAOc,CAAAA,CAAQd,EAAY,GAAA,CAC1C,CACL,QAAS,KAAA,CACT,KAAA,CAAO,eAAec,CAAK,CAAA,qBAAA,EAAwBd,EAAY,IAAI,CAAA,EAAA,EAAKA,EAAY,GAAG,CAAA,CAAA,EAAIA,EAAY,GAAG,CAAA,CAAA,CAC5G,CAAA,CAGEgB,CAAAA,CAAMhB,EAAY,GAAA,EAAOgB,CAAAA,CAAMhB,EAAY,GAAA,CACtC,CACL,QAAS,KAAA,CACT,KAAA,CAAO,aAAagB,CAAG,CAAA,qBAAA,EAAwBhB,EAAY,IAAI,CAAA,EAAA,EAAKA,EAAY,GAAG,CAAA,CAAA,EAAIA,EAAY,GAAG,CAAA,CAAA,CACxG,CAAA,CAGEc,CAAAA,CAAQE,EACH,CACL,OAAA,CAAS,MACT,KAAA,CAAO,CAAA,YAAA,EAAeF,CAAK,CAAA,kCAAA,EAAqCE,CAAG,OAAOhB,CAAAA,CAAY,IAAI,EAC5F,CAAA,CAGK,CAAE,QAAS,IAAK,CACzB,CAKA,SAASK,CAAAA,CACPF,CAAAA,CACAH,CAAAA,CACAF,EACkB,CAClB,IAAMmB,EAASd,CAAAA,CAAM,KAAA,CAAM,GAAG,CAAA,CAE9B,IAAA,IAAWe,CAAAA,IAAOD,CAAAA,CAAQ,CACxB,IAAMxB,CAAAA,CAAUyB,EAAI,IAAA,EAAK,CACzB,GAAI,CAACzB,CAAAA,CACH,OAAO,CACL,QAAS,KAAA,CACT,KAAA,CAAO,kBAAkBO,CAAAA,CAAY,IAAI,OAC3C,CAAA,CAIF,GAAIP,EAAQ,QAAA,CAAS,GAAG,EAAG,CACzB,IAAMQ,EAASK,CAAAA,CAAmBb,CAAAA,CAASO,EAAaF,CAAS,CAAA,CACjE,GAAI,CAACG,EAAO,OAAA,CACV,OAAOA,CAEX,CAAA,KAAO,CACL,IAAMA,CAAAA,CAASM,CAAAA,CAAoBd,EAASO,CAAAA,CAAaF,CAAS,EAClE,GAAI,CAACG,EAAO,OAAA,CACV,OAAOA,CAEX,CACF,CAEA,OAAO,CAAE,QAAS,IAAK,CACzB,CAKA,SAASM,CAAAA,CACPJ,EACAH,CAAAA,CACAF,CAAAA,CACkB,CAClB,IAAMqB,CAAAA,CAAMJ,EAAgBZ,CAAAA,CAAOL,CAAS,EAE5C,OAAIqB,CAAAA,GAAQ,KACH,CACL,OAAA,CAAS,KAAA,CACT,KAAA,CAAO,oBAAoBnB,CAAAA,CAAY,IAAI,KAAKG,CAAK,CAAA,CACvD,EAGEgB,CAAAA,CAAMnB,CAAAA,CAAY,KAAOmB,CAAAA,CAAMnB,CAAAA,CAAY,IACtC,CACL,OAAA,CAAS,MACT,KAAA,CAAO,CAAA,MAAA,EAASmB,CAAG,CAAA,qBAAA,EAAwBnB,CAAAA,CAAY,IAAI,CAAA,EAAA,EAAKA,EAAY,GAAG,CAAA,CAAA,EAAIA,EAAY,GAAG,CAAA,CAAA,CACpG,EAGK,CAAE,OAAA,CAAS,IAAK,CACzB,CAKA,SAASe,CAAAA,CAAgBZ,CAAAA,CAAeL,EAAkC,CAExE,IAAMqB,EAAM,QAAA,CAAShB,CAAAA,CAAO,EAAE,CAAA,CAC9B,GAAI,CAAC,KAAA,CAAMgB,CAAG,CAAA,CACZ,OAAOA,EAIT,GAAIrB,CAAAA,GAAc,QAAS,CACzB,IAAMsB,EAAWhC,CAAAA,CAAYe,CAAAA,CAAM,aAAa,CAAA,CAChD,GAAIiB,CAAAA,GAAa,MAAA,CACf,OAAOA,CAEX,CAGA,GAAItB,CAAAA,GAAc,YAAa,CAC7B,IAAMuB,EAAShC,CAAAA,CAAUc,CAAAA,CAAM,aAAa,CAAA,CAC5C,GAAIkB,CAAAA,GAAW,MAAA,CACb,OAAOA,CAEX,CAEA,OAAO,IACT","file":"validator.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"]}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { ValidationResult } from './types.cjs';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Validates a cron expression
|
|
5
|
+
* Supports both 5-field and 6-field (with seconds) cron expressions
|
|
6
|
+
* Also supports special keywords like @daily, @hourly, etc.
|
|
7
|
+
*
|
|
8
|
+
* @param expression - The cron expression to validate
|
|
9
|
+
* @param allowSeconds - Whether to allow 6-field cron expressions with seconds
|
|
10
|
+
* @returns ValidationResult object with isValid flag and optional error message
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* validateCron('0 2 * * *') // { isValid: true }
|
|
14
|
+
* validateCron('invalid') // { isValid: false, error: '...' }
|
|
15
|
+
* validateCron('0 0 2 * * *', true) // { isValid: true } (with seconds)
|
|
16
|
+
*/
|
|
17
|
+
declare function validateCron(expression: string, allowSeconds?: boolean): ValidationResult;
|
|
18
|
+
|
|
19
|
+
export { validateCron };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { ValidationResult } from './types.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Validates a cron expression
|
|
5
|
+
* Supports both 5-field and 6-field (with seconds) cron expressions
|
|
6
|
+
* Also supports special keywords like @daily, @hourly, etc.
|
|
7
|
+
*
|
|
8
|
+
* @param expression - The cron expression to validate
|
|
9
|
+
* @param allowSeconds - Whether to allow 6-field cron expressions with seconds
|
|
10
|
+
* @returns ValidationResult object with isValid flag and optional error message
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* validateCron('0 2 * * *') // { isValid: true }
|
|
14
|
+
* validateCron('invalid') // { isValid: false, error: '...' }
|
|
15
|
+
* validateCron('0 0 2 * * *', true) // { isValid: true } (with seconds)
|
|
16
|
+
*/
|
|
17
|
+
declare function validateCron(expression: string, allowSeconds?: boolean): ValidationResult;
|
|
18
|
+
|
|
19
|
+
export { validateCron };
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
var m={"@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 * * * *"},p={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"}},g={JAN:1,FEB:2,MAR:3,APR:4,MAY:5,JUN:6,JUL:7,AUG:8,SEP:9,OCT:10,NOV:11,DEC:12},V={SUN:0,MON:1,TUE:2,WED:3,THU:4,FRI:5,SAT:6};function O(r,e=false){if(!r||typeof r!="string")return {isValid:false,error:"Cron expression must be a non-empty string"};let n=r.trim();if(n.startsWith("@"))return m[n]?{isValid:true}:{isValid:false,error:`Unknown special keyword: ${n}`};let i=n.split(/\s+/),a=e?6:5;if(i.length!==a)return {isValid:false,error:`Expected ${a} fields, got ${i.length}`};let l=e?["second","minute","hour","dayOfMonth","month","dayOfWeek"]:["minute","hour","dayOfMonth","month","dayOfWeek"];for(let t=0;t<i.length;t++){let o=l[t],c=i[t],y=p[o],f=$(c,y,o);if(!f.isValid)return {isValid:false,error:f.error,field:o}}return {isValid:true}}function $(r,e,n){return r?r==="*"?{isValid:true}:r==="?"?n==="dayOfMonth"||n==="dayOfWeek"?{isValid:true}:{isValid:false,error:`Question mark (?) is only valid for day fields, not ${e.name}`}:r.includes("/")?h(r,e,n):r.includes(",")?x(r,e,n):r.includes("-")?d(r,e,n):u(r,e,n):{isValid:false,error:`${e.name} field cannot be empty`}}function h(r,e,n){let i=r.split("/");if(i.length!==2)return {isValid:false,error:`Invalid step syntax in ${e.name}: ${r}`};let[a,l]=i,t=parseInt(l,10);return isNaN(t)||t<=0?{isValid:false,error:`Invalid step value in ${e.name}: ${l}`}:a==="*"?{isValid:true}:a.includes("-")?d(a,e,n):u(a,e,n)}function d(r,e,n){let i=r.split("-");if(i.length!==2)return {isValid:false,error:`Invalid range syntax in ${e.name}: ${r}`};let[a,l]=i,t=s(a,n),o=s(l,n);return t===null?{isValid:false,error:`Invalid start value in ${e.name} range: ${a}`}:o===null?{isValid:false,error:`Invalid end value in ${e.name} range: ${l}`}:t<e.min||t>e.max?{isValid:false,error:`Start value ${t} 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})`}:t>o?{isValid:false,error:`Start value ${t} cannot be greater than end value ${o} in ${e.name}`}:{isValid:true}}function x(r,e,n){let i=r.split(",");for(let a of i){let l=a.trim();if(!l)return {isValid:false,error:`Empty value in ${e.name} list`};if(l.includes("-")){let t=d(l,e,n);if(!t.isValid)return t}else {let t=u(l,e,n);if(!t.isValid)return t}}return {isValid:true}}function u(r,e,n){let i=s(r,n);return i===null?{isValid:false,error:`Invalid value in ${e.name}: ${r}`}:i<e.min||i>e.max?{isValid:false,error:`Value ${i} is out of range for ${e.name} (${e.min}-${e.max})`}:{isValid:true}}function s(r,e){let n=parseInt(r,10);if(!isNaN(n))return n;if(e==="month"){let i=g[r.toUpperCase()];if(i!==void 0)return i}if(e==="dayOfWeek"){let i=V[r.toUpperCase()];if(i!==void 0)return i}return null}export{O as validateCron};//# sourceMappingURL=validator.js.map
|
|
2
|
+
//# sourceMappingURL=validator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/core/types.ts","../../src/core/validator.ts"],"names":["SPECIAL_KEYWORDS","FIELD_CONSTRAINTS","MONTH_NAMES","DAY_NAMES","validateCron","expression","allowSeconds","trimmed","fields","expectedFields","fieldNames","i","fieldName","fieldValue","constraints","result","validateField","value","validateStepField","validateListField","validateRangeField","validateSingleValue","parts","range","step","stepNum","startStr","endStr","start","parseFieldValue","end","values","val","num","monthNum","dayNum"],"mappings":"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","file":"validator.js","sourcesContent":["/**\n * Represents a parsed cron expression field with its values\n */\nexport interface CronField {\n /**\n * Raw value from the cron expression (e.g., \"*\", \"0-5\", step values)\n */\n raw: string;\n\n /**\n * Parsed values as an array of numbers\n * For \"*\", this will be all valid values for the field\n * For ranges like \"0-5\", this will be [0, 1, 2, 3, 4, 5]\n * For steps, this will be [0, 15, 30, 45] (example)\n */\n values: number[];\n\n /**\n * Whether this field uses the wildcard \"*\"\n */\n isWildcard: boolean;\n\n /**\n * Whether this field uses a range (e.g., \"0-5\")\n */\n isRange: boolean;\n\n /**\n * Whether this field uses a step value\n */\n isStep: boolean;\n\n /**\n * Whether this field is a list of values (e.g., \"1,3,5\")\n */\n isList: boolean;\n}\n\n/**\n * Represents a fully parsed cron expression\n */\nexport interface ParsedCron {\n /**\n * The original cron expression string\n */\n expression: string;\n\n /**\n * Minute field (0-59)\n */\n minute: CronField;\n\n /**\n * Hour field (0-23)\n */\n hour: CronField;\n\n /**\n * Day of month field (1-31)\n */\n dayOfMonth: CronField;\n\n /**\n * Month field (1-12)\n */\n month: CronField;\n\n /**\n * Day of week field (0-7, where 0 and 7 are Sunday)\n */\n dayOfWeek: CronField;\n\n /**\n * Optional second field (0-59) for 6-field cron expressions\n */\n second?: CronField;\n\n /**\n * Whether this is a special expression like @daily, @hourly, etc.\n */\n isSpecial: boolean;\n\n /**\n * The special keyword if applicable\n */\n specialKeyword?: string;\n}\n\n/**\n * Locale options for formatting\n */\nexport type Locale = 'es' | 'en';\n\n/**\n * Options for formatting cron expressions\n */\nexport interface FormatterOptions {\n /**\n * Locale for the output text\n * @default 'en'\n */\n locale?: Locale;\n\n /**\n * Whether to use 24-hour format for times\n * @default true\n */\n use24HourFormat?: boolean;\n\n /**\n * Whether to include seconds in the output (for 6-field cron)\n * @default false\n */\n includeSeconds?: boolean;\n\n /**\n * Whether to use verbose descriptions\n * @default false\n */\n verbose?: boolean;\n}\n\n/**\n * Validation result for cron expressions\n */\nexport interface ValidationResult {\n /**\n * Whether the cron expression is valid\n */\n isValid: boolean;\n\n /**\n * Error message if validation failed\n */\n error?: string;\n\n /**\n * The field that caused the error (if applicable)\n */\n field?: 'minute' | 'hour' | 'dayOfMonth' | 'month' | 'dayOfWeek' | 'second';\n}\n\n/**\n * Special cron keywords and their equivalents\n */\nexport const SPECIAL_KEYWORDS: Record<string, string> = {\n '@yearly': '0 0 1 1 *',\n '@annually': '0 0 1 1 *',\n '@monthly': '0 0 1 * *',\n '@weekly': '0 0 * * 0',\n '@daily': '0 0 * * *',\n '@midnight': '0 0 * * *',\n '@hourly': '0 * * * *',\n};\n\n/**\n * Field constraints for validation\n */\nexport interface FieldConstraints {\n min: number;\n max: number;\n name: string;\n}\n\nexport const FIELD_CONSTRAINTS: Record<string, FieldConstraints> = {\n minute: { min: 0, max: 59, name: 'minute' },\n hour: { min: 0, max: 23, name: 'hour' },\n dayOfMonth: { min: 1, max: 31, name: 'day of month' },\n month: { min: 1, max: 12, name: 'month' },\n dayOfWeek: { min: 0, max: 7, name: 'day of week' },\n second: { min: 0, max: 59, name: 'second' },\n};\n\n/**\n * Month names mapping (1-12)\n */\nexport const MONTH_NAMES: Record<string, number> = {\n JAN: 1,\n FEB: 2,\n MAR: 3,\n APR: 4,\n MAY: 5,\n JUN: 6,\n JUL: 7,\n AUG: 8,\n SEP: 9,\n OCT: 10,\n NOV: 11,\n DEC: 12,\n};\n\n/**\n * Day of week names mapping (0-7)\n */\nexport const DAY_NAMES: Record<string, number> = {\n SUN: 0,\n MON: 1,\n TUE: 2,\n WED: 3,\n THU: 4,\n FRI: 5,\n SAT: 6,\n};\n","import type { ValidationResult, FieldConstraints } from './types.js';\nimport { FIELD_CONSTRAINTS, SPECIAL_KEYWORDS, MONTH_NAMES, DAY_NAMES } from './types.js';\n\n/**\n * Validates a cron expression\n * Supports both 5-field and 6-field (with seconds) cron expressions\n * Also supports special keywords like @daily, @hourly, etc.\n *\n * @param expression - The cron expression to validate\n * @param allowSeconds - Whether to allow 6-field cron expressions with seconds\n * @returns ValidationResult object with isValid flag and optional error message\n *\n * @example\n * validateCron('0 2 * * *') // { isValid: true }\n * validateCron('invalid') // { isValid: false, error: '...' }\n * validateCron('0 0 2 * * *', true) // { isValid: true } (with seconds)\n */\nexport function validateCron(expression: string, allowSeconds = false): ValidationResult {\n if (!expression || typeof expression !== 'string') {\n return {\n isValid: false,\n error: 'Cron expression must be a non-empty string',\n };\n }\n\n const trimmed = expression.trim();\n\n // Check for special keywords\n if (trimmed.startsWith('@')) {\n if (SPECIAL_KEYWORDS[trimmed]) {\n return { isValid: true };\n }\n return {\n isValid: false,\n error: `Unknown special keyword: ${trimmed}`,\n };\n }\n\n // Split into fields\n const fields = trimmed.split(/\\s+/);\n const expectedFields = allowSeconds ? 6 : 5;\n\n if (fields.length !== expectedFields) {\n return {\n isValid: false,\n error: `Expected ${expectedFields} fields, got ${fields.length}`,\n };\n }\n\n // Field order: [second] minute hour dayOfMonth month dayOfWeek\n const fieldNames = allowSeconds\n ? ['second', 'minute', 'hour', 'dayOfMonth', 'month', 'dayOfWeek']\n : ['minute', 'hour', 'dayOfMonth', 'month', 'dayOfWeek'];\n\n // Validate each field\n for (let i = 0; i < fields.length; i++) {\n const fieldName = fieldNames[i];\n const fieldValue = fields[i];\n const constraints = FIELD_CONSTRAINTS[fieldName];\n\n const result = validateField(fieldValue, constraints, fieldName);\n if (!result.isValid) {\n return {\n isValid: false,\n error: result.error,\n field: fieldName as ValidationResult['field'],\n };\n }\n }\n\n return { isValid: true };\n}\n\n/**\n * Validates a single cron field\n */\nfunction validateField(\n value: string,\n constraints: FieldConstraints,\n fieldName: string\n): ValidationResult {\n if (!value) {\n return {\n isValid: false,\n error: `${constraints.name} field cannot be empty`,\n };\n }\n\n // Wildcard is always valid\n if (value === '*') {\n return { isValid: true };\n }\n\n // Question mark (for day fields only)\n if (value === '?') {\n if (fieldName === 'dayOfMonth' || fieldName === 'dayOfWeek') {\n return { isValid: true };\n }\n return {\n isValid: false,\n error: `Question mark (?) is only valid for day fields, not ${constraints.name}`,\n };\n }\n\n // Handle step values (e.g., */15, 0-10/2)\n if (value.includes('/')) {\n return validateStepField(value, constraints, fieldName);\n }\n\n // Handle lists (e.g., 1,3,5 or 1-3,5-7)\n // Check lists before ranges because lists can contain ranges\n if (value.includes(',')) {\n return validateListField(value, constraints, fieldName);\n }\n\n // Handle ranges (e.g., 0-5)\n if (value.includes('-')) {\n return validateRangeField(value, constraints, fieldName);\n }\n\n // Single value\n return validateSingleValue(value, constraints, fieldName);\n}\n\n/**\n * Validates a step field with step syntax\n */\nfunction validateStepField(\n value: string,\n constraints: FieldConstraints,\n fieldName: string\n): ValidationResult {\n const parts = value.split('/');\n if (parts.length !== 2) {\n return {\n isValid: false,\n error: `Invalid step syntax in ${constraints.name}: ${value}`,\n };\n }\n\n const [range, step] = parts;\n\n // Validate step value\n const stepNum = parseInt(step, 10);\n if (isNaN(stepNum) || stepNum <= 0) {\n return {\n isValid: false,\n error: `Invalid step value in ${constraints.name}: ${step}`,\n };\n }\n\n // If range is *, it's valid\n if (range === '*') {\n return { isValid: true };\n }\n\n // If range is a number or range, validate it\n if (range.includes('-')) {\n return validateRangeField(range, constraints, fieldName);\n }\n\n return validateSingleValue(range, constraints, fieldName);\n}\n\n/**\n * Validates a range field (e.g., 0-5)\n */\nfunction validateRangeField(\n value: string,\n constraints: FieldConstraints,\n fieldName: string\n): ValidationResult {\n const parts = value.split('-');\n if (parts.length !== 2) {\n return {\n isValid: false,\n error: `Invalid range syntax in ${constraints.name}: ${value}`,\n };\n }\n\n const [startStr, endStr] = parts;\n const start = parseFieldValue(startStr, fieldName);\n const end = parseFieldValue(endStr, fieldName);\n\n if (start === null) {\n return {\n isValid: false,\n error: `Invalid start value in ${constraints.name} range: ${startStr}`,\n };\n }\n\n if (end === null) {\n return {\n isValid: false,\n error: `Invalid end value in ${constraints.name} range: ${endStr}`,\n };\n }\n\n if (start < constraints.min || start > constraints.max) {\n return {\n isValid: false,\n error: `Start value ${start} is out of range for ${constraints.name} (${constraints.min}-${constraints.max})`,\n };\n }\n\n if (end < constraints.min || end > constraints.max) {\n return {\n isValid: false,\n error: `End value ${end} is out of range for ${constraints.name} (${constraints.min}-${constraints.max})`,\n };\n }\n\n if (start > end) {\n return {\n isValid: false,\n error: `Start value ${start} cannot be greater than end value ${end} in ${constraints.name}`,\n };\n }\n\n return { isValid: true };\n}\n\n/**\n * Validates a list field (e.g., 1,3,5)\n */\nfunction validateListField(\n value: string,\n constraints: FieldConstraints,\n fieldName: string\n): ValidationResult {\n const values = value.split(',');\n\n for (const val of values) {\n const trimmed = val.trim();\n if (!trimmed) {\n return {\n isValid: false,\n error: `Empty value in ${constraints.name} list`,\n };\n }\n\n // Each item can be a single value or a range\n if (trimmed.includes('-')) {\n const result = validateRangeField(trimmed, constraints, fieldName);\n if (!result.isValid) {\n return result;\n }\n } else {\n const result = validateSingleValue(trimmed, constraints, fieldName);\n if (!result.isValid) {\n return result;\n }\n }\n }\n\n return { isValid: true };\n}\n\n/**\n * Validates a single numeric value\n */\nfunction validateSingleValue(\n value: string,\n constraints: FieldConstraints,\n fieldName: string\n): ValidationResult {\n const num = parseFieldValue(value, fieldName);\n\n if (num === null) {\n return {\n isValid: false,\n error: `Invalid value in ${constraints.name}: ${value}`,\n };\n }\n\n if (num < constraints.min || num > constraints.max) {\n return {\n isValid: false,\n error: `Value ${num} is out of range for ${constraints.name} (${constraints.min}-${constraints.max})`,\n };\n }\n\n return { isValid: true };\n}\n\n/**\n * Parses a field value, handling numeric values and named values (MON, JAN, etc.)\n */\nfunction parseFieldValue(value: string, fieldName: string): number | null {\n // Try parsing as number first\n const num = parseInt(value, 10);\n if (!isNaN(num)) {\n return num;\n }\n\n // Try parsing as month name\n if (fieldName === 'month') {\n const monthNum = MONTH_NAMES[value.toUpperCase()];\n if (monthNum !== undefined) {\n return monthNum;\n }\n }\n\n // Try parsing as day name\n if (fieldName === 'dayOfWeek') {\n const dayNum = DAY_NAMES[value.toUpperCase()];\n if (dayNum !== undefined) {\n return dayNum;\n }\n }\n\n return null;\n}\n"]}
|
package/dist/i18n/en.cjs
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
'use strict';var e={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",hour:"hour",hours:"hours",day:"day",days:"days",week:"week",weeks:"weeks",month:"month",months:"months",year:"year",years:"years",on:"on",in:"in",and:"and",between:"between",through:"through",of:"of",second:"second",seconds:"seconds",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",noon:"noon",weekday:"weekday",weekend:"weekend"};exports.en=e;//# sourceMappingURL=en.cjs.map
|
|
2
|
+
//# sourceMappingURL=en.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/i18n/en.ts"],"names":["en"],"mappings":"aAEO,IAAMA,CAAAA,CAAkB,CAC7B,EAAA,CAAI,IAAA,CACJ,MAAO,OAAA,CACP,WAAA,CAAa,cAAA,CACb,SAAA,CAAW,YAAA,CACX,QAAA,CAAU,YACV,SAAA,CAAW,YAAA,CACX,UAAA,CAAY,aAAA,CACZ,SAAA,CAAW,YAAA,CACX,OAAQ,QAAA,CACR,OAAA,CAAS,SAAA,CACT,IAAA,CAAM,MAAA,CACN,KAAA,CAAO,QACP,GAAA,CAAK,KAAA,CACL,IAAA,CAAM,MAAA,CACN,IAAA,CAAM,MAAA,CACN,MAAO,OAAA,CACP,KAAA,CAAO,OAAA,CACP,MAAA,CAAQ,QAAA,CACR,IAAA,CAAM,OACN,KAAA,CAAO,OAAA,CACP,EAAA,CAAI,IAAA,CACJ,EAAA,CAAI,IAAA,CACJ,IAAK,KAAA,CACL,OAAA,CAAS,SAAA,CACT,OAAA,CAAS,SAAA,CACT,EAAA,CAAI,KACJ,MAAA,CAAQ,QAAA,CACR,OAAA,CAAS,SAAA,CAGT,MAAA,CAAQ,QAAA,CACR,OAAQ,QAAA,CACR,OAAA,CAAS,SAAA,CACT,SAAA,CAAW,WAAA,CACX,QAAA,CAAU,WACV,MAAA,CAAQ,QAAA,CACR,QAAA,CAAU,UAAA,CAGV,OAAA,CAAS,SAAA,CACT,SAAU,UAAA,CACV,KAAA,CAAO,OAAA,CACP,KAAA,CAAO,OAAA,CACP,GAAA,CAAK,MACL,IAAA,CAAM,MAAA,CACN,IAAA,CAAM,MAAA,CACN,MAAA,CAAQ,QAAA,CACR,UAAW,WAAA,CACX,OAAA,CAAS,SAAA,CACT,QAAA,CAAU,UAAA,CACV,QAAA,CAAU,WAGV,EAAA,CAAI,IAAA,CACJ,EAAA,CAAI,IAAA,CACJ,QAAA,CAAU,UAAA,CACV,KAAM,MAAA,CAGN,OAAA,CAAS,SAAA,CACT,OAAA,CAAS,SACX","file":"en.cjs","sourcesContent":["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"]}
|
package/dist/i18n/en.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
var e={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",hour:"hour",hours:"hours",day:"day",days:"days",week:"week",weeks:"weeks",month:"month",months:"months",year:"year",years:"years",on:"on",in:"in",and:"and",between:"between",through:"through",of:"of",second:"second",seconds:"seconds",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",noon:"noon",weekday:"weekday",weekend:"weekend"};export{e as en};//# sourceMappingURL=en.js.map
|
|
2
|
+
//# sourceMappingURL=en.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/i18n/en.ts"],"names":["en"],"mappings":"AAEO,IAAMA,CAAAA,CAAkB,CAC7B,EAAA,CAAI,IAAA,CACJ,MAAO,OAAA,CACP,WAAA,CAAa,cAAA,CACb,SAAA,CAAW,YAAA,CACX,QAAA,CAAU,YACV,SAAA,CAAW,YAAA,CACX,UAAA,CAAY,aAAA,CACZ,SAAA,CAAW,YAAA,CACX,OAAQ,QAAA,CACR,OAAA,CAAS,SAAA,CACT,IAAA,CAAM,MAAA,CACN,KAAA,CAAO,QACP,GAAA,CAAK,KAAA,CACL,IAAA,CAAM,MAAA,CACN,IAAA,CAAM,MAAA,CACN,MAAO,OAAA,CACP,KAAA,CAAO,OAAA,CACP,MAAA,CAAQ,QAAA,CACR,IAAA,CAAM,OACN,KAAA,CAAO,OAAA,CACP,EAAA,CAAI,IAAA,CACJ,EAAA,CAAI,IAAA,CACJ,IAAK,KAAA,CACL,OAAA,CAAS,SAAA,CACT,OAAA,CAAS,SAAA,CACT,EAAA,CAAI,KACJ,MAAA,CAAQ,QAAA,CACR,OAAA,CAAS,SAAA,CAGT,MAAA,CAAQ,QAAA,CACR,OAAQ,QAAA,CACR,OAAA,CAAS,SAAA,CACT,SAAA,CAAW,WAAA,CACX,QAAA,CAAU,WACV,MAAA,CAAQ,QAAA,CACR,QAAA,CAAU,UAAA,CAGV,OAAA,CAAS,SAAA,CACT,SAAU,UAAA,CACV,KAAA,CAAO,OAAA,CACP,KAAA,CAAO,OAAA,CACP,GAAA,CAAK,MACL,IAAA,CAAM,MAAA,CACN,IAAA,CAAM,MAAA,CACN,MAAA,CAAQ,QAAA,CACR,UAAW,WAAA,CACX,OAAA,CAAS,SAAA,CACT,QAAA,CAAU,UAAA,CACV,QAAA,CAAU,WAGV,EAAA,CAAI,IAAA,CACJ,EAAA,CAAI,IAAA,CACJ,QAAA,CAAU,UAAA,CACV,KAAM,MAAA,CAGN,OAAA,CAAS,SAAA,CACT,OAAA,CAAS,SACX","file":"en.js","sourcesContent":["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"]}
|
package/dist/i18n/es.cjs
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
'use strict';var e={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",hour:"hora",hours:"horas",day:"d\xEDa",days:"d\xEDas",week:"semana",weeks:"semanas",month:"mes",months:"meses",year:"a\xF1o",years:"a\xF1os",on:"el",in:"en",and:"y",between:"entre",through:"hasta",of:"de",second:"segundo",seconds:"segundos",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",noon:"mediod\xEDa",weekday:"d\xEDa de semana",weekend:"fin de semana"};exports.es=e;//# sourceMappingURL=es.cjs.map
|
|
2
|
+
//# sourceMappingURL=es.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/i18n/es.ts"],"names":["es"],"mappings":"aAmEO,IAAMA,CAAAA,CAAkB,CAC7B,EAAA,CAAI,OAAA,CACJ,MAAO,MAAA,CACP,WAAA,CAAa,aAAA,CACb,SAAA,CAAW,WAAA,CACX,QAAA,CAAU,oBACV,SAAA,CAAW,aAAA,CACX,UAAA,CAAY,UAAA,CACZ,SAAA,CAAW,aAAA,CACX,OAAQ,QAAA,CACR,OAAA,CAAS,SAAA,CACT,IAAA,CAAM,MAAA,CACN,KAAA,CAAO,QACP,GAAA,CAAK,QAAA,CACL,IAAA,CAAM,SAAA,CACN,IAAA,CAAM,QAAA,CACN,MAAO,SAAA,CACP,KAAA,CAAO,KAAA,CACP,MAAA,CAAQ,OAAA,CACR,IAAA,CAAM,SACN,KAAA,CAAO,SAAA,CACP,EAAA,CAAI,IAAA,CACJ,EAAA,CAAI,IAAA,CACJ,IAAK,GAAA,CACL,OAAA,CAAS,OAAA,CACT,OAAA,CAAS,OAAA,CACT,EAAA,CAAI,KACJ,MAAA,CAAQ,SAAA,CACR,OAAA,CAAS,UAAA,CAGT,MAAA,CAAQ,SAAA,CACR,OAAQ,OAAA,CACR,OAAA,CAAS,QAAA,CACT,SAAA,CAAW,cAAA,CACX,QAAA,CAAU,SACV,MAAA,CAAQ,SAAA,CACR,QAAA,CAAU,WAAA,CAGV,OAAA,CAAS,OAAA,CACT,SAAU,SAAA,CACV,KAAA,CAAO,OAAA,CACP,KAAA,CAAO,OAAA,CACP,GAAA,CAAK,OACL,IAAA,CAAM,OAAA,CACN,IAAA,CAAM,OAAA,CACN,MAAA,CAAQ,QAAA,CACR,UAAW,YAAA,CACX,OAAA,CAAS,SAAA,CACT,QAAA,CAAU,WAAA,CACV,QAAA,CAAU,YAGV,EAAA,CAAI,IAAA,CACJ,EAAA,CAAI,IAAA,CACJ,QAAA,CAAU,YAAA,CACV,KAAM,aAAA,CAGN,OAAA,CAAS,kBAAA,CACT,OAAA,CAAS,eACX","file":"es.cjs","sourcesContent":["/**\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"]}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Internationalization strings for Spanish
|
|
3
|
+
*/
|
|
4
|
+
interface I18nStrings {
|
|
5
|
+
at: string;
|
|
6
|
+
every: string;
|
|
7
|
+
everyMinute: string;
|
|
8
|
+
everyHour: string;
|
|
9
|
+
everyDay: string;
|
|
10
|
+
everyWeek: string;
|
|
11
|
+
everyMonth: string;
|
|
12
|
+
everyYear: string;
|
|
13
|
+
minute: string;
|
|
14
|
+
minutes: string;
|
|
15
|
+
hour: string;
|
|
16
|
+
hours: string;
|
|
17
|
+
day: string;
|
|
18
|
+
days: string;
|
|
19
|
+
week: string;
|
|
20
|
+
weeks: string;
|
|
21
|
+
month: string;
|
|
22
|
+
months: string;
|
|
23
|
+
year: string;
|
|
24
|
+
years: string;
|
|
25
|
+
on: string;
|
|
26
|
+
in: string;
|
|
27
|
+
and: string;
|
|
28
|
+
between: string;
|
|
29
|
+
through: string;
|
|
30
|
+
of: string;
|
|
31
|
+
second: string;
|
|
32
|
+
seconds: string;
|
|
33
|
+
sunday: string;
|
|
34
|
+
monday: string;
|
|
35
|
+
tuesday: string;
|
|
36
|
+
wednesday: string;
|
|
37
|
+
thursday: string;
|
|
38
|
+
friday: string;
|
|
39
|
+
saturday: string;
|
|
40
|
+
january: string;
|
|
41
|
+
february: string;
|
|
42
|
+
march: string;
|
|
43
|
+
april: string;
|
|
44
|
+
may: string;
|
|
45
|
+
june: string;
|
|
46
|
+
july: string;
|
|
47
|
+
august: string;
|
|
48
|
+
september: string;
|
|
49
|
+
october: string;
|
|
50
|
+
november: string;
|
|
51
|
+
december: string;
|
|
52
|
+
am: string;
|
|
53
|
+
pm: string;
|
|
54
|
+
midnight: string;
|
|
55
|
+
noon: string;
|
|
56
|
+
weekday: string;
|
|
57
|
+
weekend: string;
|
|
58
|
+
}
|
|
59
|
+
declare const es: I18nStrings;
|
|
60
|
+
|
|
61
|
+
export { type I18nStrings, es };
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Internationalization strings for Spanish
|
|
3
|
+
*/
|
|
4
|
+
interface I18nStrings {
|
|
5
|
+
at: string;
|
|
6
|
+
every: string;
|
|
7
|
+
everyMinute: string;
|
|
8
|
+
everyHour: string;
|
|
9
|
+
everyDay: string;
|
|
10
|
+
everyWeek: string;
|
|
11
|
+
everyMonth: string;
|
|
12
|
+
everyYear: string;
|
|
13
|
+
minute: string;
|
|
14
|
+
minutes: string;
|
|
15
|
+
hour: string;
|
|
16
|
+
hours: string;
|
|
17
|
+
day: string;
|
|
18
|
+
days: string;
|
|
19
|
+
week: string;
|
|
20
|
+
weeks: string;
|
|
21
|
+
month: string;
|
|
22
|
+
months: string;
|
|
23
|
+
year: string;
|
|
24
|
+
years: string;
|
|
25
|
+
on: string;
|
|
26
|
+
in: string;
|
|
27
|
+
and: string;
|
|
28
|
+
between: string;
|
|
29
|
+
through: string;
|
|
30
|
+
of: string;
|
|
31
|
+
second: string;
|
|
32
|
+
seconds: string;
|
|
33
|
+
sunday: string;
|
|
34
|
+
monday: string;
|
|
35
|
+
tuesday: string;
|
|
36
|
+
wednesday: string;
|
|
37
|
+
thursday: string;
|
|
38
|
+
friday: string;
|
|
39
|
+
saturday: string;
|
|
40
|
+
january: string;
|
|
41
|
+
february: string;
|
|
42
|
+
march: string;
|
|
43
|
+
april: string;
|
|
44
|
+
may: string;
|
|
45
|
+
june: string;
|
|
46
|
+
july: string;
|
|
47
|
+
august: string;
|
|
48
|
+
september: string;
|
|
49
|
+
october: string;
|
|
50
|
+
november: string;
|
|
51
|
+
december: string;
|
|
52
|
+
am: string;
|
|
53
|
+
pm: string;
|
|
54
|
+
midnight: string;
|
|
55
|
+
noon: string;
|
|
56
|
+
weekday: string;
|
|
57
|
+
weekend: string;
|
|
58
|
+
}
|
|
59
|
+
declare const es: I18nStrings;
|
|
60
|
+
|
|
61
|
+
export { type I18nStrings, es };
|
package/dist/i18n/es.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
var e={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",hour:"hora",hours:"horas",day:"d\xEDa",days:"d\xEDas",week:"semana",weeks:"semanas",month:"mes",months:"meses",year:"a\xF1o",years:"a\xF1os",on:"el",in:"en",and:"y",between:"entre",through:"hasta",of:"de",second:"segundo",seconds:"segundos",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",noon:"mediod\xEDa",weekday:"d\xEDa de semana",weekend:"fin de semana"};export{e as es};//# sourceMappingURL=es.js.map
|
|
2
|
+
//# sourceMappingURL=es.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/i18n/es.ts"],"names":["es"],"mappings":"AAmEO,IAAMA,CAAAA,CAAkB,CAC7B,EAAA,CAAI,OAAA,CACJ,MAAO,MAAA,CACP,WAAA,CAAa,aAAA,CACb,SAAA,CAAW,WAAA,CACX,QAAA,CAAU,oBACV,SAAA,CAAW,aAAA,CACX,UAAA,CAAY,UAAA,CACZ,SAAA,CAAW,aAAA,CACX,OAAQ,QAAA,CACR,OAAA,CAAS,SAAA,CACT,IAAA,CAAM,MAAA,CACN,KAAA,CAAO,QACP,GAAA,CAAK,QAAA,CACL,IAAA,CAAM,SAAA,CACN,IAAA,CAAM,QAAA,CACN,MAAO,SAAA,CACP,KAAA,CAAO,KAAA,CACP,MAAA,CAAQ,OAAA,CACR,IAAA,CAAM,SACN,KAAA,CAAO,SAAA,CACP,EAAA,CAAI,IAAA,CACJ,EAAA,CAAI,IAAA,CACJ,IAAK,GAAA,CACL,OAAA,CAAS,OAAA,CACT,OAAA,CAAS,OAAA,CACT,EAAA,CAAI,KACJ,MAAA,CAAQ,SAAA,CACR,OAAA,CAAS,UAAA,CAGT,MAAA,CAAQ,SAAA,CACR,OAAQ,OAAA,CACR,OAAA,CAAS,QAAA,CACT,SAAA,CAAW,cAAA,CACX,QAAA,CAAU,SACV,MAAA,CAAQ,SAAA,CACR,QAAA,CAAU,WAAA,CAGV,OAAA,CAAS,OAAA,CACT,SAAU,SAAA,CACV,KAAA,CAAO,OAAA,CACP,KAAA,CAAO,OAAA,CACP,GAAA,CAAK,OACL,IAAA,CAAM,OAAA,CACN,IAAA,CAAM,OAAA,CACN,MAAA,CAAQ,QAAA,CACR,UAAW,YAAA,CACX,OAAA,CAAS,SAAA,CACT,QAAA,CAAU,WAAA,CACV,QAAA,CAAU,YAGV,EAAA,CAAI,IAAA,CACJ,EAAA,CAAI,IAAA,CACJ,QAAA,CAAU,YAAA,CACV,KAAM,aAAA,CAGN,OAAA,CAAS,kBAAA,CACT,OAAA,CAAS,eACX","file":"es.js","sourcesContent":["/**\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"]}
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
'use strict';var g={"@yearly":"0 0 1 1 *","@annually":"0 0 1 1 *","@monthly":"0 0 1 * *","@weekly":"0 0 * * 0","@daily":"0 0 * * *","@midnight":"0 0 * * *","@hourly":"0 * * * *"},l={minute:{min:0,max:59,name:"minute"},hour:{min:0,max:23,name:"hour"},dayOfMonth:{min:1,max:31,name:"day of month"},month:{min:1,max:12,name:"month"},dayOfWeek:{min:0,max:7,name:"day of week"},second:{min:0,max:59,name:"second"}},c={JAN:1,FEB:2,MAR:3,APR:4,MAY:5,JUN:6,JUL:7,AUG:8,SEP:9,OCT:10,NOV:11,DEC:12},y={SUN:0,MON:1,TUE:2,WED:3,THU:4,FRI:5,SAT:6};function S(r,e=false){if(!r||typeof r!="string")return {isValid:false,error:"Cron expression must be a non-empty string"};let t=r.trim();if(t.startsWith("@"))return g[t]?{isValid:true}:{isValid:false,error:`Unknown special keyword: ${t}`};let n=t.split(/\s+/),s=e?6:5;if(n.length!==s)return {isValid:false,error:`Expected ${s} fields, got ${n.length}`};let a=e?["second","minute","hour","dayOfMonth","month","dayOfWeek"]:["minute","hour","dayOfMonth","month","dayOfWeek"];for(let i=0;i<n.length;i++){let o=a[i],u=n[i],d=l[o],f=E(u,d,o);if(!f.isValid)return {isValid:false,error:f.error,field:o}}return {isValid:true}}function E(r,e,t){return r?r==="*"?{isValid:true}:r==="?"?t==="dayOfMonth"||t==="dayOfWeek"?{isValid:true}:{isValid:false,error:`Question mark (?) is only valid for day fields, not ${e.name}`}:r.includes("/")?j(r,e,t):r.includes(",")?D(r,e,t):r.includes("-")?C(r,e,t):O(r,e,t):{isValid:false,error:`${e.name} field cannot be empty`}}function j(r,e,t){let n=r.split("/");if(n.length!==2)return {isValid:false,error:`Invalid step syntax in ${e.name}: ${r}`};let[s,a]=n,i=parseInt(a,10);return isNaN(i)||i<=0?{isValid:false,error:`Invalid step value in ${e.name}: ${a}`}:s==="*"?{isValid:true}:s.includes("-")?C(s,e,t):O(s,e,t)}function C(r,e,t){let n=r.split("-");if(n.length!==2)return {isValid:false,error:`Invalid range syntax in ${e.name}: ${r}`};let[s,a]=n,i=b(s,t),o=b(a,t);return i===null?{isValid:false,error:`Invalid start value in ${e.name} range: ${s}`}:o===null?{isValid:false,error:`Invalid end value in ${e.name} range: ${a}`}:i<e.min||i>e.max?{isValid:false,error:`Start value ${i} is out of range for ${e.name} (${e.min}-${e.max})`}:o<e.min||o>e.max?{isValid:false,error:`End value ${o} is out of range for ${e.name} (${e.min}-${e.max})`}:i>o?{isValid:false,error:`Start value ${i} cannot be greater than end value ${o} in ${e.name}`}:{isValid:true}}function D(r,e,t){let n=r.split(",");for(let s of n){let a=s.trim();if(!a)return {isValid:false,error:`Empty value in ${e.name} list`};if(a.includes("-")){let i=C(a,e,t);if(!i.isValid)return i}else {let i=O(a,e,t);if(!i.isValid)return i}}return {isValid:true}}function O(r,e,t){let n=b(r,t);return n===null?{isValid:false,error:`Invalid value in ${e.name}: ${r}`}:n<e.min||n>e.max?{isValid:false,error:`Value ${n} is out of range for ${e.name} (${e.min}-${e.max})`}:{isValid:true}}function b(r,e){let t=parseInt(r,10);if(!isNaN(t))return t;if(e==="month"){let n=c[r.toUpperCase()];if(n!==void 0)return n}if(e==="dayOfWeek"){let n=y[r.toUpperCase()];if(n!==void 0)return n}return null}function M(r,e=false){let t=S(r,e);if(!t.isValid)throw new Error(t.error||"Invalid cron expression");let n=r.trim();if(n.startsWith("@")){let s=g[n];return {expression:n,...k(s,false),isSpecial:true,specialKeyword:n}}return {expression:n,...k(n,e),isSpecial:false}}function k(r,e){let t=r.split(/\s+/);if(e&&t.length===6){let[u,d,f,I,R,A]=t;return {second:m(u,l.second,"second"),minute:m(d,l.minute,"minute"),hour:m(f,l.hour,"hour"),dayOfMonth:m(I,l.dayOfMonth,"dayOfMonth"),month:m(R,l.month,"month"),dayOfWeek:m(A,l.dayOfWeek,"dayOfWeek")}}let[n,s,a,i,o]=t;return {minute:m(n,l.minute,"minute"),hour:m(s,l.hour,"hour"),dayOfMonth:m(a,l.dayOfMonth,"dayOfMonth"),month:m(i,l.month,"month"),dayOfWeek:m(o,l.dayOfWeek,"dayOfWeek")}}function m(r,e,t){let n=r,s=r==="*"||r==="?",a=r.includes("/"),i=r.includes("-")&&!a,o=r.includes(","),u;if(s)u=W(e.min,e.max);else if(a)u=N(r,e,t);else if(o)u=T(r,e,t);else if(i)u=V(r,e,t);else {let d=h(r,t);u=d!==null?[d]:[];}return t==="dayOfWeek"&&(u=u.map(d=>d===7?0:d),u=[...new Set(u)]),u.sort((d,f)=>d-f),{raw:n,values:u,isWildcard:s,isRange:i,isStep:a,isList:o}}function N(r,e,t){let[n,s]=r.split("/"),a=parseInt(s,10),i;if(n==="*")i=W(e.min,e.max);else if(n.includes("-"))i=V(n,e,t);else {let u=h(n,t);i=u!==null?[u]:[];}let o=[];for(let u=0;u<i.length;u+=a)o.push(i[u]);return o}function V(r,e,t){let[n,s]=r.split("-"),a=h(n,t),i=h(s,t);return a===null||i===null?[]:W(a,i)}function T(r,e,t){let n=r.split(","),s=[];for(let a of n){let i=a.trim();if(i.includes("-")){let o=V(i,e,t);s.push(...o);}else {let o=h(i,t);o!==null&&s.push(o);}}return s}function h(r,e){let t=parseInt(r,10);if(!isNaN(t))return t;if(e==="month"){let n=c[r.toUpperCase()];if(n!==void 0)return n}if(e==="dayOfWeek"){let n=y[r.toUpperCase()];if(n!==void 0)return n}return null}function W(r,e){let t=[];for(let n=r;n<=e;n++)t.push(n);return t}var x={at:"a las",every:"cada",everyMinute:"cada minuto",everyHour:"cada hora",everyDay:"todos los d\xEDas",everyWeek:"cada semana",everyMonth:"cada mes",everyYear:"cada a\xF1o",minute:"minuto",minutes:"minutos",day:"d\xEDa",days:"d\xEDas",on:"el",in:"en",and:"y",between:"entre",through:"hasta",second:"segundo",sunday:"domingo",monday:"lunes",tuesday:"martes",wednesday:"mi\xE9rcoles",thursday:"jueves",friday:"viernes",saturday:"s\xE1bado",january:"enero",february:"febrero",march:"marzo",april:"abril",may:"mayo",june:"junio",july:"julio",august:"agosto",september:"septiembre",october:"octubre",november:"noviembre",december:"diciembre",am:"AM",pm:"PM",midnight:"medianoche",weekday:"d\xEDa de semana",weekend:"fin de semana"};var w={at:"at",every:"every",everyMinute:"every minute",everyHour:"every hour",everyDay:"every day",everyWeek:"every week",everyMonth:"every month",everyYear:"every year",minute:"minute",minutes:"minutes",day:"day",days:"days",on:"on",in:"in",and:"and",between:"between",through:"through",second:"second",sunday:"Sunday",monday:"Monday",tuesday:"Tuesday",wednesday:"Wednesday",thursday:"Thursday",friday:"Friday",saturday:"Saturday",january:"January",february:"February",march:"March",april:"April",may:"May",june:"June",july:"July",august:"August",september:"September",october:"October",november:"November",december:"December",am:"AM",pm:"PM",midnight:"midnight",weekday:"weekday",weekend:"weekend"};function P(r){if(r.length<2)return false;for(let e=1;e<r.length;e++)if(r[e]!==r[e-1]+1)return false;return true}function L(r,e={}){let{locale:t="en",use24HourFormat:n=true,includeSeconds:s=false,verbose:a=false}=e,i=t==="es"?x:w,o=M(r,s);return o.isSpecial&&o.specialKeyword?_(o.specialKeyword,i):Y(o,i,n,a)}function _(r,e){return {"@yearly":e.everyYear,"@annually":e.everyYear,"@monthly":e.everyMonth,"@weekly":e.everyWeek,"@daily":e.everyDay,"@midnight":`${e.at} ${e.midnight}`,"@hourly":e.everyHour}[r]||r}function Y(r,e,t,n){let s=[],a=U(r,e,t);a&&s.push(a);let i=K(r,e,n);return i&&s.push(i),s.join(", ")}function U(r,e,t){let{minute:n,hour:s,second:a}=r;if(n.isWildcard&&s.isWildcard)return a&&!a.isWildcard?`${e.at} ${e.second} ${a.values.join(", ")}`:e.everyMinute;if(n.isWildcard){if(s.values.length===1){let i=p(s.values[0],t,e);return `${e.everyMinute} ${e.at} ${i}`}if(s.values.length>1&&s.isRange){let i=p(s.values[0],t,e),o=p(s.values[s.values.length-1],t,e);return `${e.everyMinute}, ${e.between} ${i} ${e.and} ${o}`}}if(s.isWildcard&&!n.isWildcard){if(n.values.length===1)return `${e.at} ${e.minute} ${n.values[0]}`;if(n.isStep){let i=n.values[1]-n.values[0];return `${e.every} ${i} ${e.minutes}`}}if(!n.isWildcard&&!s.isWildcard){if(n.values.length===1&&s.values.length===1){let i=v(s.values[0],n.values[0]),o=t?i:$(s.values[0],n.values[0],e);return `${e.at} ${o}`}if(n.values.length>1||s.values.length>1){if(n.values.length===1&&s.isRange&&s.values.length>1&&P(s.values)){let i=t?v(s.values[0],n.values[0]):$(s.values[0],n.values[0],e),o=t?v(s.values[s.values.length-1],n.values[0]):$(s.values[s.values.length-1],n.values[0],e);return `${e.between} ${i} ${e.and} ${o}`}if(n.isStep){let i=n.values[1]-n.values[0];if(s.isRange){let o=p(s.values[0],t,e),u=p(s.values[s.values.length-1],t,e);return `${e.every} ${i} ${e.minutes}, ${e.between} ${o} ${e.and} ${u}`}return `${e.every} ${i} ${e.minutes}`}}}return H(r,e,t)}function K(r,e,t){let{dayOfMonth:n,month:s,dayOfWeek:a}=r;if(n.isWildcard&&a.isWildcard&&s.isWildcard)return e.everyDay;let i=[];if(!a.isWildcard){let o=J(a.values,e,t);o&&i.push(o);}if(!n.isWildcard&&a.isWildcard){let o=z(n.values,e,t);o&&i.push(o);}if(!s.isWildcard){let o=B(s.values,e,t);o&&i.push(o);}return i.join(", ")}function v(r,e){return `${r.toString().padStart(2,"0")}:${e.toString().padStart(2,"0")}`}function $(r,e,t){let n=r<12?t.am:t.pm;return `${r===0?12:r>12?r-12:r}:${e.toString().padStart(2,"0")} ${n}`}function p(r,e,t){return e?`${r.toString().padStart(2,"0")}:00`:$(r,0,t)}function H(r,e,t){let n=[];for(let s of r.hour.values)for(let a of r.minute.values){let i=t?v(s,a):$(s,a,e);n.push(i);}return n.length<=3?`${e.at} ${n.join(", ")}`:`${e.at} ${n.slice(0,2).join(", ")}... (${n.length} times)`}function J(r,e,t){let n=[e.sunday,e.monday,e.tuesday,e.wednesday,e.thursday,e.friday,e.saturday];if(r.length===5&&r.includes(1)&&r.includes(2)&&r.includes(3)&&r.includes(4)&&r.includes(5))return e.weekday+"s";if(r.length===2&&r.includes(0)&&r.includes(6))return e.weekend+"s";if(r.length===1)return e.on+" "+n[r[0]];if(r.length===7)return e.everyDay;let s=r.map(a=>n[a]);return t||r.length<=3?F(s,e):`${s[0]} ${e.through} ${s[s.length-1]}`}function z(r,e,t){return r.length===1?`${e.on} ${e.day} ${r[0]}`:r.length===31?e.everyDay:t||r.length<=3?`${e.on} ${e.days} ${r.join(", ")}`:`${e.on} ${e.days} ${r[0]} ${e.through} ${r[r.length-1]}`}function B(r,e,t){let n=[e.january,e.february,e.march,e.april,e.may,e.june,e.july,e.august,e.september,e.october,e.november,e.december];if(r.length===1)return `${e.in} ${n[r[0]-1]}`;if(r.length===12)return "";let s=r.map(a=>n[a-1]);return t||r.length<=3?`${e.in} ${F(s,e)}`:`${e.in} ${s[0]} ${e.through} ${s[s.length-1]}`}function F(r,e){if(r.length===0)return "";if(r.length===1)return r[0];if(r.length===2)return `${r[0]} ${e.and} ${r[1]}`;let t=r[r.length-1];return `${r.slice(0,-1).join(", ")}, ${e.and} ${t}`}exports.DAY_NAMES=y;exports.FIELD_CONSTRAINTS=l;exports.MONTH_NAMES=c;exports.SPECIAL_KEYWORDS=g;exports.formatCron=L;exports.parseCron=M;exports.validateCron=S;//# sourceMappingURL=index.cjs.map
|
|
2
|
+
//# sourceMappingURL=index.cjs.map
|