@aalis/util-cron 0.1.0

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 ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Ace Nyan <ace@acenyan.com>
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,55 @@
1
+ /**
2
+ * 把 cron 表达式标准化:
3
+ * - 5 字段 cron 原样返回
4
+ * - 别名 `@hourly` / `@daily` / `@midnight` / `@weekly` / `@monthly` / `@yearly` / `@annually` 展开
5
+ * - `@every Ns/Nm/Nh` 不在此处理(属于 interval 范畴),原样返回
6
+ * - 其他无法识别返回 null
7
+ */
8
+ export declare function normalizeCronExpr(input: string): string | null;
9
+ /**
10
+ * 解析 cron 字段,返回命中数字集合。支持:`*`、`*\/5`、`1-5`、`1,3,5`、
11
+ * 以及范围+步进 `1-30/5` 与 起点+步进 `0/15`(从起点步进到 max)。
12
+ * 非法字段(如 `abc`、`5-`、超界单值)解析为空集,由 validateCronExpr 在创建期拒绝。
13
+ */
14
+ export declare function parseCronField(field: string, min: number, max: number): Set<number>;
15
+ /**
16
+ * 拆分 Date 为 cron 字段需要的本地化数字。
17
+ * - 未传 `timeZone`(或传空串):使用进程本地时区(与 `Date.prototype.getXxx` 等价)
18
+ * - 传 IANA tz(如 `Asia/Shanghai` / `Europe/London`):用 Intl.DateTimeFormat 把同一瞬时换算到该时区
19
+ *
20
+ * 内部不缓存,单次构造 formatter 成本可忽略(cron 1 次/分钟)。
21
+ */
22
+ export declare function dateFieldsInTimeZone(date: Date, timeZone?: string): {
23
+ minute: number;
24
+ hour: number;
25
+ day: number;
26
+ month: number;
27
+ weekday: number;
28
+ };
29
+ /**
30
+ * 判断给定时间是否匹配 cron 表达式(5 字段或别名)。
31
+ * 不处理 @every(应由订阅层用 setInterval)。
32
+ *
33
+ * @param timeZone 可选 IANA 时区名(如 `Asia/Shanghai`)。空串/未传 = 进程本地时区。
34
+ */
35
+ export declare function matchesCron(expr: string, date: Date, timeZone?: string): boolean;
36
+ /**
37
+ * 解析 `@every 30s` / `@every 5m` / `@every 2h` 为秒数;不识别返回 0。
38
+ */
39
+ export declare function parseEverySeconds(input: string): number;
40
+ export type CronExprKind = 'cron' | 'interval';
41
+ export type ValidateResult = {
42
+ ok: true;
43
+ kind: CronExprKind;
44
+ normalized: string;
45
+ intervalSeconds?: number;
46
+ } | {
47
+ ok: false;
48
+ reason: string;
49
+ };
50
+ /**
51
+ * 校验表达式:cron(5 字段或别名)或 interval(`@every Ns/Nm/Nh`)。
52
+ */
53
+ export declare function validateCronExpr(input: string): ValidateResult;
54
+ /** 订阅 / nextFireTime 的可选参数。 */
55
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAQA;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAgB9D;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CA4BnF;AAeD;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,IAAI,EACV,QAAQ,CAAC,EAAE,MAAM,GAChB;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAoC/E;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAchF;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAWvD;AAID,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,UAAU,CAAC;AAE/C,MAAM,MAAM,cAAc,GACtB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,YAAY,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,eAAe,CAAC,EAAE,MAAM,CAAA;CAAE,GAC9E;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAElC;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,cAAc,CA0B9D;AAID,+BAA+B"}
package/dist/index.js ADDED
@@ -0,0 +1,208 @@
1
+ // ===== Cron 表达式解析与匹配(零依赖纯函数) =====
2
+ //
3
+ // POSIX 5 字段 cron + `@hourly`/`@daily`/... 别名 + `@every Ns` 间隔语法。
4
+ // 与 Aalis 的任何概念无关——不 import core、不碰 node:,可在任何 JS 运行时调用。
5
+ //
6
+ // 订阅协议(CronEngine 服务契约)在 @aalis/api-cron-engine,
7
+ // 实现在 @aalis/plugin-cron-engine。
8
+ /**
9
+ * 把 cron 表达式标准化:
10
+ * - 5 字段 cron 原样返回
11
+ * - 别名 `@hourly` / `@daily` / `@midnight` / `@weekly` / `@monthly` / `@yearly` / `@annually` 展开
12
+ * - `@every Ns/Nm/Nh` 不在此处理(属于 interval 范畴),原样返回
13
+ * - 其他无法识别返回 null
14
+ */
15
+ export function normalizeCronExpr(input) {
16
+ const s = input.trim();
17
+ if (s.startsWith('@every'))
18
+ return s;
19
+ const aliases = {
20
+ '@hourly': '0 * * * *',
21
+ '@daily': '0 0 * * *',
22
+ '@midnight': '0 0 * * *',
23
+ '@weekly': '0 0 * * 0',
24
+ '@monthly': '0 0 1 * *',
25
+ '@yearly': '0 0 1 1 *',
26
+ '@annually': '0 0 1 1 *',
27
+ };
28
+ if (aliases[s])
29
+ return aliases[s];
30
+ // 5 字段格式检查
31
+ if (s.split(/\s+/).length === 5)
32
+ return s;
33
+ return null;
34
+ }
35
+ /**
36
+ * 解析 cron 字段,返回命中数字集合。支持:`*`、`*\/5`、`1-5`、`1,3,5`、
37
+ * 以及范围+步进 `1-30/5` 与 起点+步进 `0/15`(从起点步进到 max)。
38
+ * 非法字段(如 `abc`、`5-`、超界单值)解析为空集,由 validateCronExpr 在创建期拒绝。
39
+ */
40
+ export function parseCronField(field, min, max) {
41
+ const result = new Set();
42
+ for (const part of field.split(',')) {
43
+ const trimmed = part.trim();
44
+ // 先拆步进:a-b/step、lo/step、*/step、a-b、lo、* 统一在此处理
45
+ const [rangePart, stepPart] = trimmed.split('/');
46
+ const step = stepPart !== undefined ? parseInt(stepPart, 10) : 1;
47
+ if (Number.isNaN(step) || step <= 0)
48
+ continue; // 非法/缺失步进值 → 跳过该 part
49
+ let lo;
50
+ let hi;
51
+ if (rangePart === '*') {
52
+ lo = min;
53
+ hi = max;
54
+ }
55
+ else if (rangePart.includes('-')) {
56
+ const [a, b] = rangePart.split('-').map(Number);
57
+ if (Number.isNaN(a) || Number.isNaN(b))
58
+ continue; // "5-"、"abc-def" 等
59
+ lo = a;
60
+ hi = b;
61
+ }
62
+ else {
63
+ const n = parseInt(rangePart, 10);
64
+ if (Number.isNaN(n))
65
+ continue;
66
+ lo = n;
67
+ hi = stepPart !== undefined ? max : n; // `lo/step` → lo..max 步进;裸单值 → 仅该值
68
+ }
69
+ // 夹到 [min,max],避免越界(如分钟字段 "1-100" 不塞入 60-99 这些非法分钟)
70
+ for (let i = Math.max(min, lo); i <= Math.min(max, hi); i += step)
71
+ result.add(i);
72
+ }
73
+ return result;
74
+ }
75
+ /**
76
+ * 星期字段:cron 惯例允许 0-7,其中 0 与 7 均表示周日。以 [0,7] 解析后把 7 归一到 0,
77
+ * 以匹配 Date/Intl 的 0-6(周日=0)语义 —— 否则 `* * * * 7` 会校验通过却永不触发。
78
+ */
79
+ function parseWeekdayField(field) {
80
+ const set = parseCronField(field, 0, 7);
81
+ if (set.has(7)) {
82
+ set.delete(7);
83
+ set.add(0);
84
+ }
85
+ return set;
86
+ }
87
+ /**
88
+ * 拆分 Date 为 cron 字段需要的本地化数字。
89
+ * - 未传 `timeZone`(或传空串):使用进程本地时区(与 `Date.prototype.getXxx` 等价)
90
+ * - 传 IANA tz(如 `Asia/Shanghai` / `Europe/London`):用 Intl.DateTimeFormat 把同一瞬时换算到该时区
91
+ *
92
+ * 内部不缓存,单次构造 formatter 成本可忽略(cron 1 次/分钟)。
93
+ */
94
+ export function dateFieldsInTimeZone(date, timeZone) {
95
+ if (!timeZone) {
96
+ return {
97
+ minute: date.getMinutes(),
98
+ hour: date.getHours(),
99
+ day: date.getDate(),
100
+ month: date.getMonth() + 1,
101
+ weekday: date.getDay(),
102
+ };
103
+ }
104
+ // weekday 用单独 formatter('short' 才能稳定 ASCII 输出);其它字段一次 formatToParts 全取
105
+ const partsFmt = new Intl.DateTimeFormat('en-US', {
106
+ timeZone,
107
+ hour12: false,
108
+ year: 'numeric',
109
+ month: '2-digit',
110
+ day: '2-digit',
111
+ hour: '2-digit',
112
+ minute: '2-digit',
113
+ });
114
+ const wdFmt = new Intl.DateTimeFormat('en-US', { timeZone, weekday: 'short' });
115
+ const parts = {};
116
+ for (const p of partsFmt.formatToParts(date)) {
117
+ if (p.type !== 'literal')
118
+ parts[p.type] = p.value;
119
+ }
120
+ // Intl 在 hour12=false 时午夜可能返回 "24" —— 换回 0 以匹配 cron 0-23 语义
121
+ let hour = parseInt(parts.hour, 10);
122
+ if (hour === 24)
123
+ hour = 0;
124
+ const weekdayMap = { Sun: 0, Mon: 1, Tue: 2, Wed: 3, Thu: 4, Fri: 5, Sat: 6 };
125
+ return {
126
+ minute: parseInt(parts.minute, 10),
127
+ hour,
128
+ day: parseInt(parts.day, 10),
129
+ month: parseInt(parts.month, 10),
130
+ weekday: weekdayMap[wdFmt.format(date)] ?? date.getUTCDay(),
131
+ };
132
+ }
133
+ /**
134
+ * 判断给定时间是否匹配 cron 表达式(5 字段或别名)。
135
+ * 不处理 @every(应由订阅层用 setInterval)。
136
+ *
137
+ * @param timeZone 可选 IANA 时区名(如 `Asia/Shanghai`)。空串/未传 = 进程本地时区。
138
+ */
139
+ export function matchesCron(expr, date, timeZone) {
140
+ const normalized = normalizeCronExpr(expr);
141
+ if (!normalized || normalized.startsWith('@every'))
142
+ return false;
143
+ const parts = normalized.split(/\s+/);
144
+ if (parts.length !== 5)
145
+ return false;
146
+ const [minute, hour, day, month, weekday] = parts;
147
+ const f = dateFieldsInTimeZone(date, timeZone);
148
+ return (parseCronField(minute, 0, 59).has(f.minute) &&
149
+ parseCronField(hour, 0, 23).has(f.hour) &&
150
+ parseCronField(day, 1, 31).has(f.day) &&
151
+ parseCronField(month, 1, 12).has(f.month) &&
152
+ parseWeekdayField(weekday).has(f.weekday));
153
+ }
154
+ /**
155
+ * 解析 `@every 30s` / `@every 5m` / `@every 2h` 为秒数;不识别返回 0。
156
+ */
157
+ export function parseEverySeconds(input) {
158
+ const m = input
159
+ .trim()
160
+ .toLowerCase()
161
+ .match(/^@every\s+(\d+)\s*(s|m|h)?$/);
162
+ if (!m)
163
+ return 0;
164
+ const n = parseInt(m[1], 10);
165
+ const unit = m[2] ?? 's';
166
+ if (unit === 'h')
167
+ return n * 3600;
168
+ if (unit === 'm')
169
+ return n * 60;
170
+ return n;
171
+ }
172
+ /**
173
+ * 校验表达式:cron(5 字段或别名)或 interval(`@every Ns/Nm/Nh`)。
174
+ */
175
+ export function validateCronExpr(input) {
176
+ const s = input.trim();
177
+ if (!s)
178
+ return { ok: false, reason: '表达式为空' };
179
+ if (s.startsWith('@every')) {
180
+ const sec = parseEverySeconds(s);
181
+ if (sec <= 0)
182
+ return { ok: false, reason: `无法识别的 @every 表达式: ${s}` };
183
+ return { ok: true, kind: 'interval', normalized: s, intervalSeconds: sec };
184
+ }
185
+ const normalized = normalizeCronExpr(s);
186
+ if (!normalized)
187
+ return { ok: false, reason: `非法 cron 表达式(需 5 字段或别名): ${s}` };
188
+ const fields = normalized.split(/\s+/);
189
+ if (fields.length !== 5)
190
+ return { ok: false, reason: `cron 必须为 5 字段: ${normalized}` };
191
+ // 逐字段校验:任一字段解析为空集(如 `abc`、`5-`、超界单值)即拒绝,避免静默生成永不触发的死任务。
192
+ const ranges = [
193
+ [0, 59],
194
+ [0, 23],
195
+ [1, 31],
196
+ [1, 12],
197
+ [0, 7], // 星期:0-7,0 与 7 均为周日(cron 惯例)
198
+ ];
199
+ for (let i = 0; i < 5; i++) {
200
+ if (parseCronField(fields[i], ranges[i][0], ranges[i][1]).size === 0) {
201
+ return { ok: false, reason: `cron 第 ${i + 1} 字段非法(解析为空): "${fields[i]}"` };
202
+ }
203
+ }
204
+ return { ok: true, kind: 'cron', normalized };
205
+ }
206
+ // ─── 服务接口 ───
207
+ /** 订阅 / nextFireTime 的可选参数。 */
208
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,36 @@
1
+ {
2
+ "name": "@aalis/util-cron",
3
+ "version": "0.1.0",
4
+ "license": "MIT",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "git+https://github.com/AalisLabs/Aalis.git",
8
+ "directory": "packages/util-cron"
9
+ },
10
+ "author": "Ace Nyan <ace@acenyan.com>",
11
+ "bugs": {
12
+ "url": "https://github.com/AalisLabs/Aalis/issues"
13
+ },
14
+ "homepage": "https://github.com/AalisLabs/Aalis#readme",
15
+ "type": "module",
16
+ "main": "dist/index.js",
17
+ "types": "dist/index.d.ts",
18
+ "files": [
19
+ "dist"
20
+ ],
21
+ "devDependencies": {
22
+ "typescript": "^5.7.0"
23
+ },
24
+ "keywords": [
25
+ "aalis",
26
+ "aalis-util"
27
+ ],
28
+ "aalis": {
29
+ "util": true
30
+ },
31
+ "description": "Cron 表达式解析与匹配(POSIX 5 字段 + @别名 + @every 间隔),零依赖纯函数",
32
+ "scripts": {
33
+ "build": "tsc",
34
+ "dev": "tsc --watch"
35
+ }
36
+ }