@herdctl/core 0.0.1 → 0.0.2
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/dist/config/__tests__/agent.test.js +31 -13
- package/dist/config/__tests__/agent.test.js.map +1 -1
- package/dist/config/__tests__/merge.test.js +9 -2
- package/dist/config/__tests__/merge.test.js.map +1 -1
- package/dist/config/__tests__/schema.test.js +350 -1
- package/dist/config/__tests__/schema.test.js.map +1 -1
- package/dist/config/index.d.ts +1 -1
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +3 -1
- package/dist/config/index.js.map +1 -1
- package/dist/config/schema.d.ts +828 -24
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/config/schema.js +118 -6
- package/dist/config/schema.js.map +1 -1
- package/dist/fleet-manager/__tests__/coverage.test.js +11 -332
- package/dist/fleet-manager/__tests__/coverage.test.js.map +1 -1
- package/dist/fleet-manager/__tests__/errors.test.js +1 -49
- package/dist/fleet-manager/__tests__/errors.test.js.map +1 -1
- package/dist/fleet-manager/__tests__/integration.test.js +109 -0
- package/dist/fleet-manager/__tests__/integration.test.js.map +1 -1
- package/dist/fleet-manager/__tests__/reload.test.js +1 -1
- package/dist/fleet-manager/__tests__/reload.test.js.map +1 -1
- package/dist/fleet-manager/config-reload.d.ts +164 -0
- package/dist/fleet-manager/config-reload.d.ts.map +1 -0
- package/dist/fleet-manager/config-reload.js +445 -0
- package/dist/fleet-manager/config-reload.js.map +1 -0
- package/dist/fleet-manager/context.d.ts +76 -0
- package/dist/fleet-manager/context.d.ts.map +1 -0
- package/dist/fleet-manager/context.js +11 -0
- package/dist/fleet-manager/context.js.map +1 -0
- package/dist/fleet-manager/errors.d.ts +0 -25
- package/dist/fleet-manager/errors.d.ts.map +1 -1
- package/dist/fleet-manager/errors.js +0 -38
- package/dist/fleet-manager/errors.js.map +1 -1
- package/dist/fleet-manager/event-emitters.d.ts +123 -0
- package/dist/fleet-manager/event-emitters.d.ts.map +1 -0
- package/dist/fleet-manager/event-emitters.js +136 -0
- package/dist/fleet-manager/event-emitters.js.map +1 -0
- package/dist/fleet-manager/event-types.d.ts +0 -15
- package/dist/fleet-manager/event-types.d.ts.map +1 -1
- package/dist/fleet-manager/fleet-manager.d.ts +40 -653
- package/dist/fleet-manager/fleet-manager.d.ts.map +1 -1
- package/dist/fleet-manager/fleet-manager.js +95 -1720
- package/dist/fleet-manager/fleet-manager.js.map +1 -1
- package/dist/fleet-manager/index.d.ts +13 -2
- package/dist/fleet-manager/index.d.ts.map +1 -1
- package/dist/fleet-manager/index.js +19 -6
- package/dist/fleet-manager/index.js.map +1 -1
- package/dist/fleet-manager/job-control.d.ts +64 -0
- package/dist/fleet-manager/job-control.d.ts.map +1 -0
- package/dist/fleet-manager/job-control.js +296 -0
- package/dist/fleet-manager/job-control.js.map +1 -0
- package/dist/fleet-manager/log-streaming.d.ts +171 -0
- package/dist/fleet-manager/log-streaming.d.ts.map +1 -0
- package/dist/fleet-manager/log-streaming.js +503 -0
- package/dist/fleet-manager/log-streaming.js.map +1 -0
- package/dist/fleet-manager/schedule-executor.d.ts +63 -0
- package/dist/fleet-manager/schedule-executor.d.ts.map +1 -0
- package/dist/fleet-manager/schedule-executor.js +209 -0
- package/dist/fleet-manager/schedule-executor.js.map +1 -0
- package/dist/fleet-manager/schedule-management.d.ts +71 -0
- package/dist/fleet-manager/schedule-management.d.ts.map +1 -0
- package/dist/fleet-manager/schedule-management.js +171 -0
- package/dist/fleet-manager/schedule-management.js.map +1 -0
- package/dist/fleet-manager/status-queries.d.ts +105 -0
- package/dist/fleet-manager/status-queries.d.ts.map +1 -0
- package/dist/fleet-manager/status-queries.js +247 -0
- package/dist/fleet-manager/status-queries.js.map +1 -0
- package/dist/fleet-manager/types.d.ts +0 -39
- package/dist/fleet-manager/types.d.ts.map +1 -1
- package/dist/runner/__tests__/job-executor.test.js +206 -1
- package/dist/runner/__tests__/job-executor.test.js.map +1 -1
- package/dist/runner/job-executor.d.ts +9 -0
- package/dist/runner/job-executor.d.ts.map +1 -1
- package/dist/runner/job-executor.js +78 -4
- package/dist/runner/job-executor.js.map +1 -1
- package/dist/runner/types.d.ts +2 -0
- package/dist/runner/types.d.ts.map +1 -1
- package/dist/scheduler/__tests__/cron.test.d.ts +2 -0
- package/dist/scheduler/__tests__/cron.test.d.ts.map +1 -0
- package/dist/scheduler/__tests__/cron.test.js +867 -0
- package/dist/scheduler/__tests__/cron.test.js.map +1 -0
- package/dist/scheduler/__tests__/scheduler.test.js +164 -5
- package/dist/scheduler/__tests__/scheduler.test.js.map +1 -1
- package/dist/scheduler/cron.d.ts +126 -0
- package/dist/scheduler/cron.d.ts.map +1 -0
- package/dist/scheduler/cron.js +390 -0
- package/dist/scheduler/cron.js.map +1 -0
- package/dist/scheduler/errors.d.ts +81 -1
- package/dist/scheduler/errors.d.ts.map +1 -1
- package/dist/scheduler/errors.js +81 -6
- package/dist/scheduler/errors.js.map +1 -1
- package/dist/scheduler/index.d.ts +1 -0
- package/dist/scheduler/index.d.ts.map +1 -1
- package/dist/scheduler/index.js +2 -0
- package/dist/scheduler/index.js.map +1 -1
- package/dist/scheduler/schedule-runner.d.ts +2 -2
- package/dist/scheduler/schedule-runner.d.ts.map +1 -1
- package/dist/scheduler/schedule-runner.js +20 -8
- package/dist/scheduler/schedule-runner.js.map +1 -1
- package/dist/scheduler/scheduler.d.ts +4 -4
- package/dist/scheduler/scheduler.d.ts.map +1 -1
- package/dist/scheduler/scheduler.js +86 -20
- package/dist/scheduler/scheduler.js.map +1 -1
- package/dist/scheduler/types.d.ts +1 -1
- package/dist/scheduler/types.d.ts.map +1 -1
- package/dist/state/schemas/job-metadata.d.ts +2 -2
- package/package.json +33 -8
- package/.turbo/turbo-build.log +0 -4
- package/.turbo/turbo-test.log +0 -219
- package/.turbo/turbo-typecheck.log +0 -4
- package/coverage/base.css +0 -224
- package/coverage/block-navigation.js +0 -87
- package/coverage/coverage-final.json +0 -51
- package/coverage/favicon.png +0 -0
- package/coverage/index.html +0 -251
- package/coverage/prettify.css +0 -1
- package/coverage/prettify.js +0 -2
- package/coverage/sort-arrow-sprite.png +0 -0
- package/coverage/sorter.js +0 -210
- package/coverage/src/config/index.html +0 -191
- package/coverage/src/config/index.ts.html +0 -442
- package/coverage/src/config/interpolate.ts.html +0 -652
- package/coverage/src/config/loader.ts.html +0 -1501
- package/coverage/src/config/merge.ts.html +0 -823
- package/coverage/src/config/parser.ts.html +0 -1213
- package/coverage/src/config/schema.ts.html +0 -1123
- package/coverage/src/fleet-manager/errors.ts.html +0 -2326
- package/coverage/src/fleet-manager/event-types.ts.html +0 -1219
- package/coverage/src/fleet-manager/fleet-manager.ts.html +0 -7030
- package/coverage/src/fleet-manager/index.html +0 -206
- package/coverage/src/fleet-manager/index.ts.html +0 -469
- package/coverage/src/fleet-manager/job-manager.ts.html +0 -2074
- package/coverage/src/fleet-manager/job-queue.ts.html +0 -2479
- package/coverage/src/fleet-manager/types.ts.html +0 -2602
- package/coverage/src/index.html +0 -116
- package/coverage/src/index.ts.html +0 -181
- package/coverage/src/runner/errors.ts.html +0 -1006
- package/coverage/src/runner/index.html +0 -191
- package/coverage/src/runner/index.ts.html +0 -256
- package/coverage/src/runner/job-executor.ts.html +0 -1429
- package/coverage/src/runner/message-processor.ts.html +0 -1150
- package/coverage/src/runner/sdk-adapter.ts.html +0 -658
- package/coverage/src/runner/types.ts.html +0 -559
- package/coverage/src/scheduler/errors.ts.html +0 -388
- package/coverage/src/scheduler/index.html +0 -206
- package/coverage/src/scheduler/index.ts.html +0 -244
- package/coverage/src/scheduler/interval.ts.html +0 -652
- package/coverage/src/scheduler/schedule-runner.ts.html +0 -1411
- package/coverage/src/scheduler/schedule-state.ts.html +0 -718
- package/coverage/src/scheduler/scheduler.ts.html +0 -1795
- package/coverage/src/scheduler/types.ts.html +0 -733
- package/coverage/src/state/directory.ts.html +0 -736
- package/coverage/src/state/errors.ts.html +0 -376
- package/coverage/src/state/fleet-state.ts.html +0 -937
- package/coverage/src/state/index.html +0 -221
- package/coverage/src/state/index.ts.html +0 -322
- package/coverage/src/state/job-metadata.ts.html +0 -1420
- package/coverage/src/state/job-output.ts.html +0 -1033
- package/coverage/src/state/schemas/fleet-state.ts.html +0 -445
- package/coverage/src/state/schemas/index.html +0 -176
- package/coverage/src/state/schemas/index.ts.html +0 -286
- package/coverage/src/state/schemas/job-metadata.ts.html +0 -628
- package/coverage/src/state/schemas/job-output.ts.html +0 -616
- package/coverage/src/state/schemas/session-info.ts.html +0 -361
- package/coverage/src/state/session.ts.html +0 -844
- package/coverage/src/state/types.ts.html +0 -262
- package/coverage/src/state/utils/atomic.ts.html +0 -748
- package/coverage/src/state/utils/index.html +0 -146
- package/coverage/src/state/utils/index.ts.html +0 -103
- package/coverage/src/state/utils/reads.ts.html +0 -1621
- package/coverage/src/work-sources/adapters/github.ts.html +0 -3583
- package/coverage/src/work-sources/adapters/index.html +0 -131
- package/coverage/src/work-sources/adapters/index.ts.html +0 -277
- package/coverage/src/work-sources/errors.ts.html +0 -298
- package/coverage/src/work-sources/index.html +0 -176
- package/coverage/src/work-sources/index.ts.html +0 -529
- package/coverage/src/work-sources/manager.ts.html +0 -1324
- package/coverage/src/work-sources/registry.ts.html +0 -619
- package/coverage/src/work-sources/types.ts.html +0 -568
- package/dist/fleet-manager/__tests__/event-helpers.test.d.ts +0 -7
- package/dist/fleet-manager/__tests__/event-helpers.test.d.ts.map +0 -1
- package/dist/fleet-manager/__tests__/event-helpers.test.js +0 -368
- package/dist/fleet-manager/__tests__/event-helpers.test.js.map +0 -1
- package/src/config/__tests__/agent.test.ts +0 -864
- package/src/config/__tests__/interpolate.test.ts +0 -644
- package/src/config/__tests__/loader.test.ts +0 -784
- package/src/config/__tests__/merge.test.ts +0 -751
- package/src/config/__tests__/parser.test.ts +0 -533
- package/src/config/__tests__/schema.test.ts +0 -873
- package/src/config/index.ts +0 -119
- package/src/config/interpolate.ts +0 -189
- package/src/config/loader.ts +0 -472
- package/src/config/merge.ts +0 -246
- package/src/config/parser.ts +0 -376
- package/src/config/schema.ts +0 -346
- package/src/fleet-manager/__tests__/coverage.test.ts +0 -2869
- package/src/fleet-manager/__tests__/errors.test.ts +0 -660
- package/src/fleet-manager/__tests__/event-helpers.test.ts +0 -448
- package/src/fleet-manager/__tests__/integration.test.ts +0 -1209
- package/src/fleet-manager/__tests__/job-control.test.ts +0 -283
- package/src/fleet-manager/__tests__/job-manager.test.ts +0 -869
- package/src/fleet-manager/__tests__/job-queue.test.ts +0 -401
- package/src/fleet-manager/__tests__/reload.test.ts +0 -751
- package/src/fleet-manager/__tests__/status-queries.test.ts +0 -595
- package/src/fleet-manager/__tests__/trigger.test.ts +0 -601
- package/src/fleet-manager/errors.ts +0 -747
- package/src/fleet-manager/event-types.ts +0 -378
- package/src/fleet-manager/fleet-manager.ts +0 -2315
- package/src/fleet-manager/index.ts +0 -128
- package/src/fleet-manager/job-manager.ts +0 -663
- package/src/fleet-manager/job-queue.ts +0 -798
- package/src/fleet-manager/types.ts +0 -839
- package/src/index.ts +0 -32
- package/src/runner/__tests__/errors.test.ts +0 -382
- package/src/runner/__tests__/job-executor.test.ts +0 -1708
- package/src/runner/__tests__/message-processor.test.ts +0 -960
- package/src/runner/__tests__/sdk-adapter.test.ts +0 -626
- package/src/runner/errors.ts +0 -307
- package/src/runner/index.ts +0 -57
- package/src/runner/job-executor.ts +0 -448
- package/src/runner/message-processor.ts +0 -355
- package/src/runner/sdk-adapter.ts +0 -191
- package/src/runner/types.ts +0 -158
- package/src/scheduler/__tests__/errors.test.ts +0 -159
- package/src/scheduler/__tests__/interval.test.ts +0 -515
- package/src/scheduler/__tests__/schedule-runner.test.ts +0 -798
- package/src/scheduler/__tests__/schedule-state.test.ts +0 -671
- package/src/scheduler/__tests__/scheduler.test.ts +0 -1280
- package/src/scheduler/errors.ts +0 -101
- package/src/scheduler/index.ts +0 -53
- package/src/scheduler/interval.ts +0 -189
- package/src/scheduler/schedule-runner.ts +0 -442
- package/src/scheduler/schedule-state.ts +0 -211
- package/src/scheduler/scheduler.ts +0 -570
- package/src/scheduler/types.ts +0 -216
- package/src/state/__tests__/directory.test.ts +0 -595
- package/src/state/__tests__/fleet-state.test.ts +0 -868
- package/src/state/__tests__/job-metadata-schema.test.ts +0 -414
- package/src/state/__tests__/job-metadata.test.ts +0 -831
- package/src/state/__tests__/job-output.test.ts +0 -856
- package/src/state/__tests__/session-schema.test.ts +0 -378
- package/src/state/__tests__/session.test.ts +0 -604
- package/src/state/directory.ts +0 -217
- package/src/state/errors.ts +0 -97
- package/src/state/fleet-state.ts +0 -284
- package/src/state/index.ts +0 -79
- package/src/state/job-metadata.ts +0 -445
- package/src/state/job-output.ts +0 -316
- package/src/state/schemas/__tests__/job-output.test.ts +0 -338
- package/src/state/schemas/fleet-state.ts +0 -120
- package/src/state/schemas/index.ts +0 -67
- package/src/state/schemas/job-metadata.ts +0 -181
- package/src/state/schemas/job-output.ts +0 -177
- package/src/state/schemas/session-info.ts +0 -92
- package/src/state/session.ts +0 -253
- package/src/state/types.ts +0 -59
- package/src/state/utils/__tests__/atomic.test.ts +0 -723
- package/src/state/utils/__tests__/reads.test.ts +0 -1071
- package/src/state/utils/atomic.ts +0 -221
- package/src/state/utils/index.ts +0 -6
- package/src/state/utils/reads.ts +0 -512
- package/src/work-sources/__tests__/github.test.ts +0 -1800
- package/src/work-sources/__tests__/manager.test.ts +0 -529
- package/src/work-sources/__tests__/registry.test.ts +0 -477
- package/src/work-sources/__tests__/types.test.ts +0 -479
- package/src/work-sources/adapters/github.ts +0 -1166
- package/src/work-sources/adapters/index.ts +0 -64
- package/src/work-sources/errors.ts +0 -71
- package/src/work-sources/index.ts +0 -148
- package/src/work-sources/manager.ts +0 -413
- package/src/work-sources/registry.ts +0 -178
- package/src/work-sources/types.ts +0 -161
- package/tsconfig.json +0 -9
- package/vitest.config.ts +0 -19
|
@@ -0,0 +1,390 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cron expression parsing utilities for the scheduler module
|
|
3
|
+
*
|
|
4
|
+
* Parses standard 5-field cron expressions and common shorthands like @daily, @hourly, etc.
|
|
5
|
+
* Uses the cron-parser library for robust parsing and validation.
|
|
6
|
+
*/
|
|
7
|
+
import cronParser from "cron-parser";
|
|
8
|
+
import { CronParseError, CRON_FIELDS } from "./errors.js";
|
|
9
|
+
/**
|
|
10
|
+
* Mapping of common cron shorthands to their 5-field equivalents
|
|
11
|
+
*/
|
|
12
|
+
const CRON_SHORTHANDS = {
|
|
13
|
+
"@yearly": "0 0 1 1 *",
|
|
14
|
+
"@annually": "0 0 1 1 *",
|
|
15
|
+
"@monthly": "0 0 1 * *",
|
|
16
|
+
"@weekly": "0 0 * * 0",
|
|
17
|
+
"@daily": "0 0 * * *",
|
|
18
|
+
"@midnight": "0 0 * * *",
|
|
19
|
+
"@hourly": "0 * * * *",
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Parse a cron expression string into a parsed cron expression object
|
|
23
|
+
*
|
|
24
|
+
* Supports standard 5-field cron expressions:
|
|
25
|
+
* - `minute hour day-of-month month day-of-week`
|
|
26
|
+
* - Each field supports standard cron syntax (numbers, ranges, lists, steps, *)
|
|
27
|
+
*
|
|
28
|
+
* Also supports common shorthands:
|
|
29
|
+
* - `@yearly` / `@annually` - Run once a year at midnight on January 1st (0 0 1 1 *)
|
|
30
|
+
* - `@monthly` - Run once a month at midnight on the 1st (0 0 1 * *)
|
|
31
|
+
* - `@weekly` - Run once a week at midnight on Sunday (0 0 * * 0)
|
|
32
|
+
* - `@daily` / `@midnight` - Run once a day at midnight (0 0 * * *)
|
|
33
|
+
* - `@hourly` - Run once an hour at the start of the hour (0 * * * *)
|
|
34
|
+
*
|
|
35
|
+
* @param expression - The cron expression to parse
|
|
36
|
+
* @returns Parsed cron expression with iterator methods
|
|
37
|
+
* @throws {CronParseError} If the expression is invalid
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* // Standard 5-field cron
|
|
41
|
+
* parseCronExpression("0 9 * * 1-5") // 9 AM on weekdays
|
|
42
|
+
* parseCronExpression("0 0 1 * *") // First of every month
|
|
43
|
+
*
|
|
44
|
+
* // Shorthands
|
|
45
|
+
* parseCronExpression("@daily") // Midnight every day
|
|
46
|
+
* parseCronExpression("@hourly") // Start of every hour
|
|
47
|
+
* parseCronExpression("@weekly") // Midnight on Sunday
|
|
48
|
+
*/
|
|
49
|
+
export function parseCronExpression(expression, options) {
|
|
50
|
+
// Handle empty string
|
|
51
|
+
if (!expression || expression.trim() === "") {
|
|
52
|
+
throw new CronParseError('Cron expression cannot be empty. Expected a 5-field cron expression (e.g., "0 9 * * *") or a shorthand like "@daily"', expression);
|
|
53
|
+
}
|
|
54
|
+
const trimmed = expression.trim();
|
|
55
|
+
const isShorthand = trimmed.startsWith("@");
|
|
56
|
+
// Expand shorthand if applicable
|
|
57
|
+
let cronExpr = trimmed;
|
|
58
|
+
if (isShorthand) {
|
|
59
|
+
const lowerShorthand = trimmed.toLowerCase();
|
|
60
|
+
const expanded = CRON_SHORTHANDS[lowerShorthand];
|
|
61
|
+
if (!expanded) {
|
|
62
|
+
const validShorthands = Object.keys(CRON_SHORTHANDS)
|
|
63
|
+
.filter((s) => s !== "@annually" && s !== "@midnight") // Don't show aliases
|
|
64
|
+
.join(", ");
|
|
65
|
+
throw new CronParseError(`Unknown cron shorthand "${trimmed}". Valid shorthands are: ${validShorthands}`, expression);
|
|
66
|
+
}
|
|
67
|
+
cronExpr = expanded;
|
|
68
|
+
}
|
|
69
|
+
// Validate field count before parsing
|
|
70
|
+
const fieldCountError = validateFieldCount(cronExpr);
|
|
71
|
+
if (fieldCountError) {
|
|
72
|
+
throw new CronParseError(CronParseError.buildMessage(trimmed, fieldCountError.reason, fieldCountError.example), expression, { field: "fields", example: fieldCountError.example?.expression });
|
|
73
|
+
}
|
|
74
|
+
// Check for field-specific validation errors before cron-parser
|
|
75
|
+
const fieldError = validateCronFields(cronExpr);
|
|
76
|
+
if (fieldError) {
|
|
77
|
+
throw new CronParseError(CronParseError.buildMessage(trimmed, fieldError.reason, fieldError.example), expression, { cause: undefined, field: fieldError.field, example: fieldError.example?.expression });
|
|
78
|
+
}
|
|
79
|
+
try {
|
|
80
|
+
const parserOptions = {
|
|
81
|
+
tz: options?.tz ?? "UTC",
|
|
82
|
+
};
|
|
83
|
+
if (options?.currentDate) {
|
|
84
|
+
parserOptions.currentDate = options.currentDate;
|
|
85
|
+
}
|
|
86
|
+
const cronExpression = cronParser.parseExpression(cronExpr, parserOptions);
|
|
87
|
+
return {
|
|
88
|
+
expression: cronExpr,
|
|
89
|
+
cronExpression,
|
|
90
|
+
isShorthand,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
catch (error) {
|
|
94
|
+
// Try to extract field-specific error from cron-parser
|
|
95
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown parsing error";
|
|
96
|
+
const parsedError = parseErrorMessage(errorMessage, cronExpr);
|
|
97
|
+
throw new CronParseError(CronParseError.buildMessage(trimmed, parsedError.reason, parsedError.example), expression, {
|
|
98
|
+
cause: error instanceof Error ? error : undefined,
|
|
99
|
+
field: parsedError.field,
|
|
100
|
+
example: parsedError.example?.expression
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Validate field count in cron expression
|
|
106
|
+
*/
|
|
107
|
+
function validateFieldCount(expression) {
|
|
108
|
+
const fields = expression.trim().split(/\s+/);
|
|
109
|
+
if (fields.length < 5) {
|
|
110
|
+
return {
|
|
111
|
+
reason: `expected 5 fields, got ${fields.length}`,
|
|
112
|
+
field: "fields",
|
|
113
|
+
example: { expression: "* * * * *", description: "every minute" },
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
if (fields.length > 5) {
|
|
117
|
+
return {
|
|
118
|
+
reason: `expected 5 fields, got ${fields.length}`,
|
|
119
|
+
field: "fields",
|
|
120
|
+
example: { expression: "0 9 * * *", description: "daily at 9:00 AM" },
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
return null;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Validate individual cron fields for common errors
|
|
127
|
+
*/
|
|
128
|
+
function validateCronFields(expression) {
|
|
129
|
+
const fields = expression.trim().split(/\s+/);
|
|
130
|
+
if (fields.length !== 5) {
|
|
131
|
+
return null; // Field count validation handles this
|
|
132
|
+
}
|
|
133
|
+
for (const fieldInfo of CRON_FIELDS) {
|
|
134
|
+
const fieldValue = fields[fieldInfo.index];
|
|
135
|
+
const error = validateField(fieldValue, fieldInfo);
|
|
136
|
+
if (error) {
|
|
137
|
+
return error;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
return null;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Validate a single cron field
|
|
144
|
+
*/
|
|
145
|
+
function validateField(value, fieldInfo) {
|
|
146
|
+
// Skip wildcards and complex patterns for basic validation
|
|
147
|
+
if (value === "*") {
|
|
148
|
+
return null;
|
|
149
|
+
}
|
|
150
|
+
// Handle step syntax (e.g., */15)
|
|
151
|
+
if (value.startsWith("*/")) {
|
|
152
|
+
const step = parseInt(value.slice(2), 10);
|
|
153
|
+
if (isNaN(step) || step <= 0) {
|
|
154
|
+
return {
|
|
155
|
+
reason: `invalid step value "${value}" for ${fieldInfo.name}`,
|
|
156
|
+
field: fieldInfo.name,
|
|
157
|
+
example: getExampleForField(fieldInfo),
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
return null;
|
|
161
|
+
}
|
|
162
|
+
// Handle ranges (e.g., 1-5)
|
|
163
|
+
if (value.includes("-") && !value.startsWith("-")) {
|
|
164
|
+
const parts = value.split("-");
|
|
165
|
+
if (parts.length === 2) {
|
|
166
|
+
const start = parseInt(parts[0], 10);
|
|
167
|
+
const end = parseInt(parts[1], 10);
|
|
168
|
+
if (!isNaN(start) && !isNaN(end)) {
|
|
169
|
+
if (start < fieldInfo.min || start > fieldInfo.max) {
|
|
170
|
+
return {
|
|
171
|
+
reason: `${fieldInfo.name} must be ${fieldInfo.min}-${fieldInfo.max}`,
|
|
172
|
+
field: fieldInfo.name,
|
|
173
|
+
example: getExampleForField(fieldInfo),
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
if (end < fieldInfo.min || end > fieldInfo.max) {
|
|
177
|
+
return {
|
|
178
|
+
reason: `${fieldInfo.name} must be ${fieldInfo.min}-${fieldInfo.max}`,
|
|
179
|
+
field: fieldInfo.name,
|
|
180
|
+
example: getExampleForField(fieldInfo),
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
return null;
|
|
186
|
+
}
|
|
187
|
+
// Handle lists (e.g., 1,3,5)
|
|
188
|
+
if (value.includes(",")) {
|
|
189
|
+
const parts = value.split(",");
|
|
190
|
+
for (const part of parts) {
|
|
191
|
+
const num = parseInt(part, 10);
|
|
192
|
+
if (!isNaN(num) && (num < fieldInfo.min || num > fieldInfo.max)) {
|
|
193
|
+
return {
|
|
194
|
+
reason: `${fieldInfo.name} must be ${fieldInfo.min}-${fieldInfo.max}`,
|
|
195
|
+
field: fieldInfo.name,
|
|
196
|
+
example: getExampleForField(fieldInfo),
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
return null;
|
|
201
|
+
}
|
|
202
|
+
// Handle simple numeric values
|
|
203
|
+
const num = parseInt(value, 10);
|
|
204
|
+
if (!isNaN(num)) {
|
|
205
|
+
if (num < fieldInfo.min || num > fieldInfo.max) {
|
|
206
|
+
return {
|
|
207
|
+
reason: `${fieldInfo.name} must be ${fieldInfo.min}-${fieldInfo.max}`,
|
|
208
|
+
field: fieldInfo.name,
|
|
209
|
+
example: getExampleForField(fieldInfo),
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
return null;
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Get a helpful example for a specific field
|
|
217
|
+
*/
|
|
218
|
+
function getExampleForField(fieldInfo) {
|
|
219
|
+
switch (fieldInfo.name) {
|
|
220
|
+
case "minute":
|
|
221
|
+
return { expression: "30 * * * *", description: "every hour at :30" };
|
|
222
|
+
case "hour":
|
|
223
|
+
return { expression: "0 9 * * *", description: "daily at 9:00 AM" };
|
|
224
|
+
case "day-of-month":
|
|
225
|
+
return { expression: "0 0 1 * *", description: "first of every month" };
|
|
226
|
+
case "month":
|
|
227
|
+
return { expression: "0 0 1 6 *", description: "June 1st at midnight" };
|
|
228
|
+
case "day-of-week":
|
|
229
|
+
return { expression: "0 9 * * 1-5", description: "weekdays at 9:00 AM" };
|
|
230
|
+
default:
|
|
231
|
+
return { expression: "0 9 * * *", description: "daily at 9:00 AM" };
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Parse error message from cron-parser and extract field info
|
|
236
|
+
*/
|
|
237
|
+
function parseErrorMessage(errorMessage, expression) {
|
|
238
|
+
// Try to identify which field failed
|
|
239
|
+
const lowerMsg = errorMessage.toLowerCase();
|
|
240
|
+
// Check for "Constraint error" messages from cron-parser
|
|
241
|
+
if (lowerMsg.includes("constraint error")) {
|
|
242
|
+
// cron-parser often says things like "Constraint error, got value X expected range Y-Z"
|
|
243
|
+
const valueMatch = errorMessage.match(/got value (\d+)/i);
|
|
244
|
+
const rangeMatch = errorMessage.match(/expected range (\d+)-(\d+)/i);
|
|
245
|
+
if (valueMatch && rangeMatch) {
|
|
246
|
+
const value = parseInt(valueMatch[1], 10);
|
|
247
|
+
const min = parseInt(rangeMatch[1], 10);
|
|
248
|
+
const max = parseInt(rangeMatch[2], 10);
|
|
249
|
+
// Determine which field based on the range
|
|
250
|
+
const field = identifyFieldByRange(min, max);
|
|
251
|
+
if (field) {
|
|
252
|
+
return {
|
|
253
|
+
reason: `${field.name} must be ${field.min}-${field.max}`,
|
|
254
|
+
field: field.name,
|
|
255
|
+
example: getExampleForField(field),
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
// Check for field-specific keywords
|
|
261
|
+
for (const field of CRON_FIELDS) {
|
|
262
|
+
if (lowerMsg.includes(field.name)) {
|
|
263
|
+
return {
|
|
264
|
+
reason: `${field.name} must be ${field.min}-${field.max}`,
|
|
265
|
+
field: field.name,
|
|
266
|
+
example: getExampleForField(field),
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
// Generic fallback
|
|
271
|
+
return {
|
|
272
|
+
reason: errorMessage,
|
|
273
|
+
example: { expression: "0 9 * * *", description: "daily at 9:00 AM" },
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Identify cron field by its valid range
|
|
278
|
+
*/
|
|
279
|
+
function identifyFieldByRange(min, max) {
|
|
280
|
+
for (const field of CRON_FIELDS) {
|
|
281
|
+
if (field.min === min && field.max === max) {
|
|
282
|
+
return field;
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
// Handle day-of-week which can be 0-6 or 0-7
|
|
286
|
+
if (min === 0 && (max === 6 || max === 7)) {
|
|
287
|
+
return CRON_FIELDS[4]; // day-of-week
|
|
288
|
+
}
|
|
289
|
+
return null;
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* Get the next trigger time for a cron expression
|
|
293
|
+
*
|
|
294
|
+
* @param expression - The cron expression (5-field or shorthand)
|
|
295
|
+
* @param fromDate - Optional date to calculate from (defaults to now)
|
|
296
|
+
* @returns The next trigger time as a Date
|
|
297
|
+
* @throws {CronParseError} If the expression is invalid
|
|
298
|
+
*
|
|
299
|
+
* @example
|
|
300
|
+
* // Get next trigger from now
|
|
301
|
+
* getNextCronTrigger("0 9 * * 1-5") // Next 9 AM on a weekday
|
|
302
|
+
*
|
|
303
|
+
* // Get next trigger from a specific date
|
|
304
|
+
* getNextCronTrigger("@daily", new Date("2024-01-15T12:00:00Z"))
|
|
305
|
+
* // Returns 2024-01-16T00:00:00Z
|
|
306
|
+
*/
|
|
307
|
+
export function getNextCronTrigger(expression, fromDate, tz) {
|
|
308
|
+
const parsed = parseCronExpression(expression, {
|
|
309
|
+
currentDate: fromDate,
|
|
310
|
+
tz: tz ?? "UTC",
|
|
311
|
+
});
|
|
312
|
+
return parsed.cronExpression.next().toDate();
|
|
313
|
+
}
|
|
314
|
+
/**
|
|
315
|
+
* Check if a cron expression is valid
|
|
316
|
+
*
|
|
317
|
+
* @param expression - The cron expression to validate
|
|
318
|
+
* @returns true if the expression is valid, false otherwise
|
|
319
|
+
*
|
|
320
|
+
* @example
|
|
321
|
+
* isValidCronExpression("0 9 * * *") // true
|
|
322
|
+
* isValidCronExpression("@daily") // true
|
|
323
|
+
* isValidCronExpression("invalid") // false
|
|
324
|
+
* isValidCronExpression("60 * * * *") // false (minute > 59)
|
|
325
|
+
*/
|
|
326
|
+
export function isValidCronExpression(expression) {
|
|
327
|
+
try {
|
|
328
|
+
parseCronExpression(expression);
|
|
329
|
+
return true;
|
|
330
|
+
}
|
|
331
|
+
catch {
|
|
332
|
+
return false;
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
/**
|
|
336
|
+
* Calculate the next trigger time for a cron expression using system timezone
|
|
337
|
+
*
|
|
338
|
+
* This function uses the system's local timezone for calculations, which is
|
|
339
|
+
* consistent with interval-based scheduling behavior.
|
|
340
|
+
*
|
|
341
|
+
* @param expression - The cron expression (5-field or shorthand)
|
|
342
|
+
* @param after - Optional date to calculate from (defaults to now)
|
|
343
|
+
* @returns The next trigger time as a Date
|
|
344
|
+
* @throws {CronParseError} If the expression is invalid
|
|
345
|
+
*
|
|
346
|
+
* @example
|
|
347
|
+
* // Daily at 9:00 AM
|
|
348
|
+
* const expr = "0 9 * * *";
|
|
349
|
+
* const morning = new Date("2024-01-15T08:00:00");
|
|
350
|
+
* calculateNextCronTrigger(expr, morning) // Returns 2024-01-15T09:00:00 (local)
|
|
351
|
+
*
|
|
352
|
+
* @example
|
|
353
|
+
* // Every 15 minutes (use step syntax)
|
|
354
|
+
* const midHour = new Date("2024-01-15T10:07:00");
|
|
355
|
+
* calculateNextCronTrigger("0,15,30,45 * * * *", midHour) // Returns 2024-01-15T10:15:00 (local)
|
|
356
|
+
*/
|
|
357
|
+
export function calculateNextCronTrigger(expression, after) {
|
|
358
|
+
// Get the system timezone
|
|
359
|
+
const systemTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
360
|
+
const parsed = parseCronExpression(expression, {
|
|
361
|
+
currentDate: after,
|
|
362
|
+
tz: systemTimezone,
|
|
363
|
+
});
|
|
364
|
+
return parsed.cronExpression.next().toDate();
|
|
365
|
+
}
|
|
366
|
+
/**
|
|
367
|
+
* Calculate the previous trigger time for a cron expression
|
|
368
|
+
*
|
|
369
|
+
* Returns the most recent occurrence of the cron schedule before the given time
|
|
370
|
+
* (or before now if no time is specified).
|
|
371
|
+
*
|
|
372
|
+
* @param expression - The cron expression (5-field or shorthand)
|
|
373
|
+
* @param before - Optional date to calculate from (defaults to now)
|
|
374
|
+
* @returns The previous trigger time as a Date
|
|
375
|
+
* @throws {CronParseError} If the expression is invalid
|
|
376
|
+
*
|
|
377
|
+
* @example
|
|
378
|
+
* // If current time is 11:30 and cron is @hourly (at :00)
|
|
379
|
+
* calculatePreviousCronTrigger("@hourly") // Returns 11:00
|
|
380
|
+
*/
|
|
381
|
+
export function calculatePreviousCronTrigger(expression, before) {
|
|
382
|
+
// Get the system timezone
|
|
383
|
+
const systemTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
384
|
+
const parsed = parseCronExpression(expression, {
|
|
385
|
+
currentDate: before,
|
|
386
|
+
tz: systemTimezone,
|
|
387
|
+
});
|
|
388
|
+
return parsed.cronExpression.prev().toDate();
|
|
389
|
+
}
|
|
390
|
+
//# sourceMappingURL=cron.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cron.js","sourceRoot":"","sources":["../../src/scheduler/cron.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,12 +3,38 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Provides typed errors with descriptive messages for scheduler operations.
|
|
5
5
|
*/
|
|
6
|
+
import { FleetManagerError } from "../fleet-manager/errors.js";
|
|
7
|
+
/**
|
|
8
|
+
* Error codes for scheduler errors (extends FleetManagerErrorCode)
|
|
9
|
+
*/
|
|
10
|
+
export declare const SchedulerErrorCode: {
|
|
11
|
+
readonly CRON_PARSE_ERROR: "CRON_PARSE_ERROR";
|
|
12
|
+
readonly INTERVAL_PARSE_ERROR: "INTERVAL_PARSE_ERROR";
|
|
13
|
+
readonly SCHEDULE_TRIGGER_ERROR: "SCHEDULE_TRIGGER_ERROR";
|
|
14
|
+
readonly SCHEDULER_SHUTDOWN_ERROR: "SCHEDULER_SHUTDOWN_ERROR";
|
|
15
|
+
readonly FLEET_MANAGER_ERROR: "FLEET_MANAGER_ERROR";
|
|
16
|
+
readonly CONFIGURATION_ERROR: "CONFIGURATION_ERROR";
|
|
17
|
+
readonly CONFIG_LOAD_ERROR: "CONFIG_LOAD_ERROR";
|
|
18
|
+
readonly AGENT_NOT_FOUND: "AGENT_NOT_FOUND";
|
|
19
|
+
readonly JOB_NOT_FOUND: "JOB_NOT_FOUND";
|
|
20
|
+
readonly SCHEDULE_NOT_FOUND: "SCHEDULE_NOT_FOUND";
|
|
21
|
+
readonly INVALID_STATE: "INVALID_STATE";
|
|
22
|
+
readonly STATE_DIR_ERROR: "STATE_DIR_ERROR";
|
|
23
|
+
readonly CONCURRENCY_LIMIT: "CONCURRENCY_LIMIT";
|
|
24
|
+
readonly SHUTDOWN_ERROR: "SHUTDOWN_ERROR";
|
|
25
|
+
readonly JOB_CANCEL_ERROR: "JOB_CANCEL_ERROR";
|
|
26
|
+
readonly JOB_FORK_ERROR: "JOB_FORK_ERROR";
|
|
27
|
+
};
|
|
28
|
+
export type SchedulerErrorCode = (typeof SchedulerErrorCode)[keyof typeof SchedulerErrorCode];
|
|
6
29
|
/**
|
|
7
30
|
* Base error class for all scheduler errors
|
|
31
|
+
*
|
|
32
|
+
* Extends FleetManagerError to integrate with the broader error hierarchy.
|
|
8
33
|
*/
|
|
9
|
-
export declare class SchedulerError extends
|
|
34
|
+
export declare class SchedulerError extends FleetManagerError {
|
|
10
35
|
constructor(message: string, options?: {
|
|
11
36
|
cause?: Error;
|
|
37
|
+
code?: SchedulerErrorCode;
|
|
12
38
|
});
|
|
13
39
|
}
|
|
14
40
|
/**
|
|
@@ -24,6 +50,60 @@ export declare class IntervalParseError extends SchedulerError {
|
|
|
24
50
|
cause?: Error;
|
|
25
51
|
});
|
|
26
52
|
}
|
|
53
|
+
/**
|
|
54
|
+
* Cron field definitions for validation and error messages
|
|
55
|
+
*/
|
|
56
|
+
export interface CronFieldInfo {
|
|
57
|
+
name: string;
|
|
58
|
+
index: number;
|
|
59
|
+
min: number;
|
|
60
|
+
max: number;
|
|
61
|
+
example: string;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Cron field definitions
|
|
65
|
+
*/
|
|
66
|
+
export declare const CRON_FIELDS: CronFieldInfo[];
|
|
67
|
+
/**
|
|
68
|
+
* Error thrown when a cron expression cannot be parsed
|
|
69
|
+
*
|
|
70
|
+
* This error provides detailed information about what went wrong during parsing,
|
|
71
|
+
* including the invalid expression, which field is invalid, and examples of valid
|
|
72
|
+
* expressions.
|
|
73
|
+
*
|
|
74
|
+
* @example
|
|
75
|
+
* ```typescript
|
|
76
|
+
* try {
|
|
77
|
+
* parseCronExpression("0 25 * * *");
|
|
78
|
+
* } catch (error) {
|
|
79
|
+
* if (error instanceof CronParseError) {
|
|
80
|
+
* console.error(error.message);
|
|
81
|
+
* // CronParseError: Invalid cron expression "0 25 * * *" - hour must be 0-23
|
|
82
|
+
* // Example valid expression: "0 9 * * *" (daily at 9:00 AM)
|
|
83
|
+
* }
|
|
84
|
+
* }
|
|
85
|
+
* ```
|
|
86
|
+
*/
|
|
87
|
+
export declare class CronParseError extends SchedulerError {
|
|
88
|
+
/** The original cron expression that failed to parse */
|
|
89
|
+
readonly expression: string;
|
|
90
|
+
/** The field that caused the error, if identifiable */
|
|
91
|
+
readonly field?: string;
|
|
92
|
+
/** A suggested valid example */
|
|
93
|
+
readonly example?: string;
|
|
94
|
+
constructor(message: string, expression: string, options?: {
|
|
95
|
+
cause?: Error;
|
|
96
|
+
field?: string;
|
|
97
|
+
example?: string;
|
|
98
|
+
});
|
|
99
|
+
/**
|
|
100
|
+
* Build a detailed error message with examples
|
|
101
|
+
*/
|
|
102
|
+
static buildMessage(expression: string, reason: string, example?: {
|
|
103
|
+
expression: string;
|
|
104
|
+
description: string;
|
|
105
|
+
}): string;
|
|
106
|
+
}
|
|
27
107
|
/**
|
|
28
108
|
* Error thrown when a schedule trigger fails during execution
|
|
29
109
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/scheduler/errors.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/scheduler/errors.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACL,iBAAiB,EAElB,MAAM,4BAA4B,CAAC;AAMpC;;GAEG;AACH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;CAOrB,CAAC;AAEX,MAAM,MAAM,kBAAkB,GAC5B,CAAC,OAAO,kBAAkB,CAAC,CAAC,MAAM,OAAO,kBAAkB,CAAC,CAAC;AAM/D;;;;GAIG;AACH,qBAAa,cAAe,SAAQ,iBAAiB;gBAEjD,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,KAAK,CAAC;QAAC,IAAI,CAAC,EAAE,kBAAkB,CAAA;KAAE;CASzD;AAMD;;;;;GAKG;AACH,qBAAa,kBAAmB,SAAQ,cAAc;IACpD,qDAAqD;IACrD,SAAgB,KAAK,EAAE,MAAM,CAAC;gBAElB,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,KAAK,CAAA;KAAE;CAKxE;AAMD;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,eAAO,MAAM,WAAW,EAAE,aAAa,EAMtC,CAAC;AAEF;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBAAa,cAAe,SAAQ,cAAc;IAChD,wDAAwD;IACxD,SAAgB,UAAU,EAAE,MAAM,CAAC;IAEnC,uDAAuD;IACvD,SAAgB,KAAK,CAAC,EAAE,MAAM,CAAC;IAE/B,gCAAgC;IAChC,SAAgB,OAAO,CAAC,EAAE,MAAM,CAAC;gBAG/B,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,KAAK,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE;IAS/D;;OAEG;IACH,MAAM,CAAC,YAAY,CACjB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,GACpD,MAAM;CAOV;AAMD;;;;;;;GAOG;AACH,qBAAa,oBAAqB,SAAQ,cAAc;IACtD,mDAAmD;IACnD,SAAgB,SAAS,EAAE,MAAM,CAAC;IAElC,2CAA2C;IAC3C,SAAgB,YAAY,EAAE,MAAM,CAAC;gBAGnC,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,EACpB,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,KAAK,CAAA;KAAE;CAO9B;AAMD;;;;;GAKG;AACH,qBAAa,sBAAuB,SAAQ,cAAc;IACxD,kEAAkE;IAClE,SAAgB,QAAQ,EAAE,OAAO,CAAC;IAElC,+EAA+E;IAC/E,SAAgB,eAAe,EAAE,MAAM,CAAC;gBAGtC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE;QAAE,QAAQ,EAAE,OAAO,CAAC;QAAC,eAAe,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,KAAK,CAAA;KAAE;CAOzE"}
|
package/dist/scheduler/errors.js
CHANGED
|
@@ -3,17 +3,37 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Provides typed errors with descriptive messages for scheduler operations.
|
|
5
5
|
*/
|
|
6
|
+
import { FleetManagerError, FleetManagerErrorCode, } from "../fleet-manager/errors.js";
|
|
7
|
+
// =============================================================================
|
|
8
|
+
// Error Codes
|
|
9
|
+
// =============================================================================
|
|
10
|
+
/**
|
|
11
|
+
* Error codes for scheduler errors (extends FleetManagerErrorCode)
|
|
12
|
+
*/
|
|
13
|
+
export const SchedulerErrorCode = {
|
|
14
|
+
...FleetManagerErrorCode,
|
|
15
|
+
// Scheduler-specific error codes
|
|
16
|
+
CRON_PARSE_ERROR: "CRON_PARSE_ERROR",
|
|
17
|
+
INTERVAL_PARSE_ERROR: "INTERVAL_PARSE_ERROR",
|
|
18
|
+
SCHEDULE_TRIGGER_ERROR: "SCHEDULE_TRIGGER_ERROR",
|
|
19
|
+
SCHEDULER_SHUTDOWN_ERROR: "SCHEDULER_SHUTDOWN_ERROR",
|
|
20
|
+
};
|
|
6
21
|
// =============================================================================
|
|
7
22
|
// Base Error Class
|
|
8
23
|
// =============================================================================
|
|
9
24
|
/**
|
|
10
25
|
* Base error class for all scheduler errors
|
|
26
|
+
*
|
|
27
|
+
* Extends FleetManagerError to integrate with the broader error hierarchy.
|
|
11
28
|
*/
|
|
12
|
-
export class SchedulerError extends
|
|
29
|
+
export class SchedulerError extends FleetManagerError {
|
|
13
30
|
constructor(message, options) {
|
|
14
|
-
super(message
|
|
31
|
+
super(message, {
|
|
32
|
+
cause: options?.cause,
|
|
33
|
+
// Use type assertion since SchedulerErrorCode is a superset of FleetManagerErrorCode
|
|
34
|
+
code: (options?.code ?? FleetManagerErrorCode.FLEET_MANAGER_ERROR),
|
|
35
|
+
});
|
|
15
36
|
this.name = "SchedulerError";
|
|
16
|
-
this.cause = options?.cause;
|
|
17
37
|
}
|
|
18
38
|
}
|
|
19
39
|
// =============================================================================
|
|
@@ -29,11 +49,66 @@ export class IntervalParseError extends SchedulerError {
|
|
|
29
49
|
/** The original input string that failed to parse */
|
|
30
50
|
input;
|
|
31
51
|
constructor(message, input, options) {
|
|
32
|
-
super(message, options);
|
|
52
|
+
super(message, { cause: options?.cause, code: SchedulerErrorCode.INTERVAL_PARSE_ERROR });
|
|
33
53
|
this.name = "IntervalParseError";
|
|
34
54
|
this.input = input;
|
|
35
55
|
}
|
|
36
56
|
}
|
|
57
|
+
/**
|
|
58
|
+
* Cron field definitions
|
|
59
|
+
*/
|
|
60
|
+
export const CRON_FIELDS = [
|
|
61
|
+
{ name: "minute", index: 0, min: 0, max: 59, example: "0" },
|
|
62
|
+
{ name: "hour", index: 1, min: 0, max: 23, example: "9" },
|
|
63
|
+
{ name: "day-of-month", index: 2, min: 1, max: 31, example: "1" },
|
|
64
|
+
{ name: "month", index: 3, min: 1, max: 12, example: "*" },
|
|
65
|
+
{ name: "day-of-week", index: 4, min: 0, max: 7, example: "*" },
|
|
66
|
+
];
|
|
67
|
+
/**
|
|
68
|
+
* Error thrown when a cron expression cannot be parsed
|
|
69
|
+
*
|
|
70
|
+
* This error provides detailed information about what went wrong during parsing,
|
|
71
|
+
* including the invalid expression, which field is invalid, and examples of valid
|
|
72
|
+
* expressions.
|
|
73
|
+
*
|
|
74
|
+
* @example
|
|
75
|
+
* ```typescript
|
|
76
|
+
* try {
|
|
77
|
+
* parseCronExpression("0 25 * * *");
|
|
78
|
+
* } catch (error) {
|
|
79
|
+
* if (error instanceof CronParseError) {
|
|
80
|
+
* console.error(error.message);
|
|
81
|
+
* // CronParseError: Invalid cron expression "0 25 * * *" - hour must be 0-23
|
|
82
|
+
* // Example valid expression: "0 9 * * *" (daily at 9:00 AM)
|
|
83
|
+
* }
|
|
84
|
+
* }
|
|
85
|
+
* ```
|
|
86
|
+
*/
|
|
87
|
+
export class CronParseError extends SchedulerError {
|
|
88
|
+
/** The original cron expression that failed to parse */
|
|
89
|
+
expression;
|
|
90
|
+
/** The field that caused the error, if identifiable */
|
|
91
|
+
field;
|
|
92
|
+
/** A suggested valid example */
|
|
93
|
+
example;
|
|
94
|
+
constructor(message, expression, options) {
|
|
95
|
+
super(message, { cause: options?.cause, code: SchedulerErrorCode.CRON_PARSE_ERROR });
|
|
96
|
+
this.name = "CronParseError";
|
|
97
|
+
this.expression = expression;
|
|
98
|
+
this.field = options?.field;
|
|
99
|
+
this.example = options?.example;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Build a detailed error message with examples
|
|
103
|
+
*/
|
|
104
|
+
static buildMessage(expression, reason, example) {
|
|
105
|
+
let message = `Invalid cron expression "${expression}" - ${reason}`;
|
|
106
|
+
if (example) {
|
|
107
|
+
message += `\n Example valid expression: "${example.expression}" (${example.description})`;
|
|
108
|
+
}
|
|
109
|
+
return message;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
37
112
|
// =============================================================================
|
|
38
113
|
// Schedule Trigger Errors
|
|
39
114
|
// =============================================================================
|
|
@@ -51,7 +126,7 @@ export class ScheduleTriggerError extends SchedulerError {
|
|
|
51
126
|
/** The name of the schedule that failed */
|
|
52
127
|
scheduleName;
|
|
53
128
|
constructor(message, agentName, scheduleName, options) {
|
|
54
|
-
super(message, options);
|
|
129
|
+
super(message, { cause: options?.cause, code: SchedulerErrorCode.SCHEDULE_TRIGGER_ERROR });
|
|
55
130
|
this.name = "ScheduleTriggerError";
|
|
56
131
|
this.agentName = agentName;
|
|
57
132
|
this.scheduleName = scheduleName;
|
|
@@ -72,7 +147,7 @@ export class SchedulerShutdownError extends SchedulerError {
|
|
|
72
147
|
/** Number of jobs that were still running when shutdown completed/timed out */
|
|
73
148
|
runningJobCount;
|
|
74
149
|
constructor(message, options) {
|
|
75
|
-
super(message, { cause: options.cause });
|
|
150
|
+
super(message, { cause: options.cause, code: SchedulerErrorCode.SCHEDULER_SHUTDOWN_ERROR });
|
|
76
151
|
this.name = "SchedulerShutdownError";
|
|
77
152
|
this.timedOut = options.timedOut;
|
|
78
153
|
this.runningJobCount = options.runningJobCount;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/scheduler/errors.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,gFAAgF;AAChF,
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/scheduler/errors.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
export * from "./errors.js";
|
|
8
8
|
export { parseInterval, calculateNextTrigger, isScheduleDue, } from "./interval.js";
|
|
9
|
+
export { parseCronExpression, getNextCronTrigger, calculateNextCronTrigger, isValidCronExpression, type ParsedCronExpression, type CronParseOptions, } from "./cron.js";
|
|
9
10
|
export { getScheduleState, updateScheduleState, getAgentScheduleStates, type ScheduleStateLogger, type ScheduleStateOptions, type ScheduleStateUpdates, } from "./schedule-state.js";
|
|
10
11
|
export type { SchedulerOptions, SchedulerStatus, SchedulerState, SchedulerLogger, ScheduleCheckResult, ScheduleSkipReason, TriggerInfo, SchedulerTriggerCallback, AgentScheduleInfo, StopOptions, } from "./types.js";
|
|
11
12
|
export { Scheduler } from "./scheduler.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/scheduler/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,cAAc,aAAa,CAAC;AAG5B,OAAO,EACL,aAAa,EACb,oBAAoB,EACpB,aAAa,GACd,MAAM,eAAe,CAAC;AAGvB,OAAO,EACL,gBAAgB,EAChB,mBAAmB,EACnB,sBAAsB,EACtB,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,GAC1B,MAAM,qBAAqB,CAAC;AAG7B,YAAY,EACV,gBAAgB,EAChB,eAAe,EACf,cAAc,EACd,eAAe,EACf,mBAAmB,EACnB,kBAAkB,EAClB,WAAW,EACX,wBAAwB,EACxB,iBAAiB,EACjB,WAAW,GACZ,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAG3C,OAAO,EACL,WAAW,EACX,mBAAmB,EACnB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,KAAK,oBAAoB,EACzB,KAAK,eAAe,GACrB,MAAM,sBAAsB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/scheduler/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,cAAc,aAAa,CAAC;AAG5B,OAAO,EACL,aAAa,EACb,oBAAoB,EACpB,aAAa,GACd,MAAM,eAAe,CAAC;AAGvB,OAAO,EACL,mBAAmB,EACnB,kBAAkB,EAClB,wBAAwB,EACxB,qBAAqB,EACrB,KAAK,oBAAoB,EACzB,KAAK,gBAAgB,GACtB,MAAM,WAAW,CAAC;AAGnB,OAAO,EACL,gBAAgB,EAChB,mBAAmB,EACnB,sBAAsB,EACtB,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,GAC1B,MAAM,qBAAqB,CAAC;AAG7B,YAAY,EACV,gBAAgB,EAChB,eAAe,EACf,cAAc,EACd,eAAe,EACf,mBAAmB,EACnB,kBAAkB,EAClB,WAAW,EACX,wBAAwB,EACxB,iBAAiB,EACjB,WAAW,GACZ,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAG3C,OAAO,EACL,WAAW,EACX,mBAAmB,EACnB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,KAAK,oBAAoB,EACzB,KAAK,eAAe,GACrB,MAAM,sBAAsB,CAAC"}
|