semola 0.5.3 → 0.5.4
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/index-BhGNDjPq.d.mts +13 -0
- package/dist/index-DxSbeGP-.d.cts +13 -0
- package/dist/lib/api/index.cjs +522 -4
- package/dist/lib/api/index.d.cts +270 -4
- package/dist/lib/api/index.d.mts +270 -4
- package/dist/lib/api/index.mjs +520 -2
- package/dist/lib/cache/index.d.cts +16 -4
- package/dist/lib/cache/index.d.mts +16 -4
- package/dist/lib/cache/index.mjs +0 -2
- package/dist/lib/cron/index.cjs +734 -12
- package/dist/lib/cron/index.d.cts +145 -3
- package/dist/lib/cron/index.d.mts +145 -3
- package/dist/lib/cron/index.mjs +725 -3
- package/dist/lib/errors/index.d.cts +2 -13
- package/dist/lib/errors/index.d.mts +2 -13
- package/dist/lib/errors/index.mjs +0 -2
- package/dist/lib/i18n/index.d.cts +12 -4
- package/dist/lib/i18n/index.d.mts +12 -4
- package/dist/lib/i18n/index.mjs +0 -2
- package/dist/lib/logging/index.cjs +386 -17
- package/dist/lib/logging/index.d.cts +107 -6
- package/dist/lib/logging/index.d.mts +107 -6
- package/dist/lib/logging/index.mjs +373 -4
- package/dist/lib/policy/index.cjs +206 -20
- package/dist/lib/policy/index.d.cts +61 -5
- package/dist/lib/policy/index.d.mts +61 -5
- package/dist/lib/policy/index.mjs +187 -3
- package/dist/lib/prompts/index.cjs +374 -14
- package/dist/lib/prompts/index.d.cts +69 -4
- package/dist/lib/prompts/index.d.mts +69 -4
- package/dist/lib/prompts/index.mjs +362 -4
- package/dist/lib/pubsub/index.d.cts +9 -4
- package/dist/lib/pubsub/index.d.mts +9 -4
- package/dist/lib/pubsub/index.mjs +0 -2
- package/dist/lib/queue/index.d.cts +48 -6
- package/dist/lib/queue/index.d.mts +48 -6
- package/dist/lib/queue/index.mjs +0 -2
- package/dist/lib/workflow/index.d.cts +82 -4
- package/dist/lib/workflow/index.d.mts +82 -4
- package/dist/lib/workflow/index.mjs +0 -2
- package/package.json +1 -1
- package/dist/api/core/index.cjs +0 -206
- package/dist/api/core/index.d.cts +0 -21
- package/dist/api/core/index.d.cts.map +0 -1
- package/dist/api/core/index.d.mts +0 -21
- package/dist/api/core/index.d.mts.map +0 -1
- package/dist/api/core/index.mjs +0 -208
- package/dist/api/core/index.mjs.map +0 -1
- package/dist/api/core/types.d.cts +0 -107
- package/dist/api/core/types.d.cts.map +0 -1
- package/dist/api/core/types.d.mts +0 -107
- package/dist/api/core/types.d.mts.map +0 -1
- package/dist/api/middleware/index.cjs +0 -8
- package/dist/api/middleware/index.d.cts +0 -11
- package/dist/api/middleware/index.d.cts.map +0 -1
- package/dist/api/middleware/index.d.mts +0 -11
- package/dist/api/middleware/index.d.mts.map +0 -1
- package/dist/api/middleware/index.mjs +0 -10
- package/dist/api/middleware/index.mjs.map +0 -1
- package/dist/api/middleware/types.d.cts +0 -16
- package/dist/api/middleware/types.d.cts.map +0 -1
- package/dist/api/middleware/types.d.mts +0 -16
- package/dist/api/middleware/types.d.mts.map +0 -1
- package/dist/api/openapi/index.cjs +0 -254
- package/dist/api/openapi/index.mjs +0 -256
- package/dist/api/openapi/index.mjs.map +0 -1
- package/dist/api/openapi/types.d.cts +0 -60
- package/dist/api/openapi/types.d.cts.map +0 -1
- package/dist/api/openapi/types.d.mts +0 -60
- package/dist/api/openapi/types.d.mts.map +0 -1
- package/dist/api/validation/index.cjs +0 -64
- package/dist/api/validation/index.mjs +0 -61
- package/dist/api/validation/index.mjs.map +0 -1
- package/dist/cache/types.d.cts +0 -17
- package/dist/cache/types.d.cts.map +0 -1
- package/dist/cache/types.d.mts +0 -17
- package/dist/cache/types.d.mts.map +0 -1
- package/dist/cron/builder/index.cjs +0 -166
- package/dist/cron/builder/index.d.cts +0 -28
- package/dist/cron/builder/index.d.cts.map +0 -1
- package/dist/cron/builder/index.d.mts +0 -28
- package/dist/cron/builder/index.d.mts.map +0 -1
- package/dist/cron/builder/index.mjs +0 -163
- package/dist/cron/builder/index.mjs.map +0 -1
- package/dist/cron/builder/types.cjs +0 -27
- package/dist/cron/builder/types.d.cts +0 -79
- package/dist/cron/builder/types.d.cts.map +0 -1
- package/dist/cron/builder/types.d.mts +0 -79
- package/dist/cron/builder/types.d.mts.map +0 -1
- package/dist/cron/builder/types.mjs +0 -28
- package/dist/cron/builder/types.mjs.map +0 -1
- package/dist/cron/core/index.cjs +0 -308
- package/dist/cron/core/index.d.cts +0 -39
- package/dist/cron/core/index.d.cts.map +0 -1
- package/dist/cron/core/index.d.mts +0 -39
- package/dist/cron/core/index.d.mts.map +0 -1
- package/dist/cron/core/index.mjs +0 -310
- package/dist/cron/core/index.mjs.map +0 -1
- package/dist/cron/core/scanner.cjs +0 -237
- package/dist/cron/core/scanner.mjs +0 -238
- package/dist/cron/core/scanner.mjs.map +0 -1
- package/dist/cron/core/types.d.cts +0 -11
- package/dist/cron/core/types.d.cts.map +0 -1
- package/dist/cron/core/types.d.mts +0 -11
- package/dist/cron/core/types.d.mts.map +0 -1
- package/dist/errors/types.d.cts +0 -5
- package/dist/errors/types.d.cts.map +0 -1
- package/dist/errors/types.d.mts +0 -5
- package/dist/errors/types.d.mts.map +0 -1
- package/dist/i18n/types.d.cts +0 -13
- package/dist/i18n/types.d.cts.map +0 -1
- package/dist/i18n/types.d.mts +0 -13
- package/dist/i18n/types.d.mts.map +0 -1
- package/dist/lib/cache/index.d.cts.map +0 -1
- package/dist/lib/cache/index.d.mts.map +0 -1
- package/dist/lib/cache/index.mjs.map +0 -1
- package/dist/lib/errors/index.d.cts.map +0 -1
- package/dist/lib/errors/index.d.mts.map +0 -1
- package/dist/lib/errors/index.mjs.map +0 -1
- package/dist/lib/i18n/index.d.cts.map +0 -1
- package/dist/lib/i18n/index.d.mts.map +0 -1
- package/dist/lib/i18n/index.mjs.map +0 -1
- package/dist/lib/orm/index.cjs +0 -20
- package/dist/lib/orm/index.d.cts +0 -7
- package/dist/lib/orm/index.d.mts +0 -7
- package/dist/lib/orm/index.mjs +0 -6
- package/dist/lib/policy/index.d.cts.map +0 -1
- package/dist/lib/policy/index.d.mts.map +0 -1
- package/dist/lib/policy/index.mjs.map +0 -1
- package/dist/lib/prompts/index.d.cts.map +0 -1
- package/dist/lib/prompts/index.d.mts.map +0 -1
- package/dist/lib/prompts/index.mjs.map +0 -1
- package/dist/lib/pubsub/index.d.cts.map +0 -1
- package/dist/lib/pubsub/index.d.mts.map +0 -1
- package/dist/lib/pubsub/index.mjs.map +0 -1
- package/dist/lib/queue/index.d.cts.map +0 -1
- package/dist/lib/queue/index.d.mts.map +0 -1
- package/dist/lib/queue/index.mjs.map +0 -1
- package/dist/lib/workflow/index.d.cts.map +0 -1
- package/dist/lib/workflow/index.d.mts.map +0 -1
- package/dist/lib/workflow/index.mjs.map +0 -1
- package/dist/logging/core/index.cjs +0 -99
- package/dist/logging/core/index.d.cts +0 -26
- package/dist/logging/core/index.d.cts.map +0 -1
- package/dist/logging/core/index.d.mts +0 -26
- package/dist/logging/core/index.d.mts.map +0 -1
- package/dist/logging/core/index.mjs +0 -99
- package/dist/logging/core/index.mjs.map +0 -1
- package/dist/logging/core/types.cjs +0 -10
- package/dist/logging/core/types.d.cts +0 -22
- package/dist/logging/core/types.d.cts.map +0 -1
- package/dist/logging/core/types.d.mts +0 -22
- package/dist/logging/core/types.d.mts.map +0 -1
- package/dist/logging/core/types.mjs +0 -12
- package/dist/logging/core/types.mjs.map +0 -1
- package/dist/logging/formatter/index.cjs +0 -119
- package/dist/logging/formatter/index.d.cts +0 -27
- package/dist/logging/formatter/index.d.cts.map +0 -1
- package/dist/logging/formatter/index.d.mts +0 -27
- package/dist/logging/formatter/index.d.mts.map +0 -1
- package/dist/logging/formatter/index.mjs +0 -115
- package/dist/logging/formatter/index.mjs.map +0 -1
- package/dist/logging/formatter/types.d.cts +0 -5
- package/dist/logging/formatter/types.d.cts.map +0 -1
- package/dist/logging/formatter/types.d.mts +0 -5
- package/dist/logging/formatter/types.d.mts.map +0 -1
- package/dist/logging/provider/index.cjs +0 -165
- package/dist/logging/provider/index.d.cts +0 -28
- package/dist/logging/provider/index.d.cts.map +0 -1
- package/dist/logging/provider/index.d.mts +0 -28
- package/dist/logging/provider/index.d.mts.map +0 -1
- package/dist/logging/provider/index.mjs +0 -165
- package/dist/logging/provider/index.mjs.map +0 -1
- package/dist/logging/provider/types.d.cts +0 -23
- package/dist/logging/provider/types.d.cts.map +0 -1
- package/dist/logging/provider/types.d.mts +0 -23
- package/dist/logging/provider/types.d.mts.map +0 -1
- package/dist/node_modules/@standard-schema/spec/dist/index.d.cts +0 -80
- package/dist/node_modules/@standard-schema/spec/dist/index.d.cts.map +0 -1
- package/dist/node_modules/@standard-schema/spec/dist/index.d.mts +0 -80
- package/dist/node_modules/@standard-schema/spec/dist/index.d.mts.map +0 -1
- package/dist/orm/column.cjs +0 -137
- package/dist/orm/column.d.cts +0 -121
- package/dist/orm/column.d.cts.map +0 -1
- package/dist/orm/column.d.mts +0 -121
- package/dist/orm/column.d.mts.map +0 -1
- package/dist/orm/column.mjs +0 -132
- package/dist/orm/column.mjs.map +0 -1
- package/dist/orm/dialect/index.cjs +0 -14
- package/dist/orm/dialect/index.mjs +0 -16
- package/dist/orm/dialect/index.mjs.map +0 -1
- package/dist/orm/dialect/mysql.cjs +0 -31
- package/dist/orm/dialect/mysql.mjs +0 -33
- package/dist/orm/dialect/mysql.mjs.map +0 -1
- package/dist/orm/dialect/postgres.cjs +0 -23
- package/dist/orm/dialect/postgres.mjs +0 -25
- package/dist/orm/dialect/postgres.mjs.map +0 -1
- package/dist/orm/dialect/sqlite.cjs +0 -31
- package/dist/orm/dialect/sqlite.mjs +0 -33
- package/dist/orm/dialect/sqlite.mjs.map +0 -1
- package/dist/orm/dialect/utils.cjs +0 -8
- package/dist/orm/dialect/utils.mjs +0 -10
- package/dist/orm/dialect/utils.mjs.map +0 -1
- package/dist/orm/internal/table-columns.cjs +0 -31
- package/dist/orm/internal/table-columns.mjs +0 -32
- package/dist/orm/internal/table-columns.mjs.map +0 -1
- package/dist/orm/internal/table-lookup.cjs +0 -35
- package/dist/orm/internal/table-lookup.mjs +0 -35
- package/dist/orm/internal/table-lookup.mjs.map +0 -1
- package/dist/orm/internal/table-relations.cjs +0 -28
- package/dist/orm/internal/table-relations.mjs +0 -29
- package/dist/orm/internal/table-relations.mjs.map +0 -1
- package/dist/orm/migration/config.cjs +0 -7
- package/dist/orm/migration/config.d.cts +0 -7
- package/dist/orm/migration/config.d.cts.map +0 -1
- package/dist/orm/migration/config.d.mts +0 -7
- package/dist/orm/migration/config.d.mts.map +0 -1
- package/dist/orm/migration/config.mjs +0 -8
- package/dist/orm/migration/config.mjs.map +0 -1
- package/dist/orm/migration/types.d.cts +0 -20
- package/dist/orm/migration/types.d.cts.map +0 -1
- package/dist/orm/migration/types.d.mts +0 -20
- package/dist/orm/migration/types.d.mts.map +0 -1
- package/dist/orm/orm.cjs +0 -41
- package/dist/orm/orm.d.cts +0 -18
- package/dist/orm/orm.d.cts.map +0 -1
- package/dist/orm/orm.d.mts +0 -18
- package/dist/orm/orm.d.mts.map +0 -1
- package/dist/orm/orm.mjs +0 -43
- package/dist/orm/orm.mjs.map +0 -1
- package/dist/orm/relation.cjs +0 -18
- package/dist/orm/relation.d.cts +0 -8
- package/dist/orm/relation.d.cts.map +0 -1
- package/dist/orm/relation.d.mts +0 -8
- package/dist/orm/relation.d.mts.map +0 -1
- package/dist/orm/relation.mjs +0 -19
- package/dist/orm/relation.mjs.map +0 -1
- package/dist/orm/runtime/builders/mutations.cjs +0 -29
- package/dist/orm/runtime/builders/mutations.mjs +0 -28
- package/dist/orm/runtime/builders/mutations.mjs.map +0 -1
- package/dist/orm/runtime/builders/select.cjs +0 -18
- package/dist/orm/runtime/builders/select.mjs +0 -19
- package/dist/orm/runtime/builders/select.mjs.map +0 -1
- package/dist/orm/runtime/client.cjs +0 -90
- package/dist/orm/runtime/client.mjs +0 -92
- package/dist/orm/runtime/client.mjs.map +0 -1
- package/dist/orm/runtime/context.cjs +0 -49
- package/dist/orm/runtime/context.mjs +0 -51
- package/dist/orm/runtime/context.mjs.map +0 -1
- package/dist/orm/runtime/dialect/index.cjs +0 -11
- package/dist/orm/runtime/dialect/index.mjs +0 -13
- package/dist/orm/runtime/dialect/index.mjs.map +0 -1
- package/dist/orm/runtime/dialect/mysql.cjs +0 -95
- package/dist/orm/runtime/dialect/mysql.mjs +0 -97
- package/dist/orm/runtime/dialect/mysql.mjs.map +0 -1
- package/dist/orm/runtime/dialect/postgres.cjs +0 -51
- package/dist/orm/runtime/dialect/postgres.mjs +0 -53
- package/dist/orm/runtime/dialect/postgres.mjs.map +0 -1
- package/dist/orm/runtime/dialect/sqlite.cjs +0 -4
- package/dist/orm/runtime/dialect/sqlite.mjs +0 -7
- package/dist/orm/runtime/dialect/sqlite.mjs.map +0 -1
- package/dist/orm/runtime/errors.cjs +0 -19
- package/dist/orm/runtime/errors.mjs +0 -21
- package/dist/orm/runtime/errors.mjs.map +0 -1
- package/dist/orm/runtime/hydrate/many.cjs +0 -46
- package/dist/orm/runtime/hydrate/many.mjs +0 -48
- package/dist/orm/runtime/hydrate/many.mjs.map +0 -1
- package/dist/orm/runtime/hydrate/one.cjs +0 -38
- package/dist/orm/runtime/hydrate/one.mjs +0 -40
- package/dist/orm/runtime/hydrate/one.mjs.map +0 -1
- package/dist/orm/runtime/hydrate.cjs +0 -49
- package/dist/orm/runtime/hydrate.mjs +0 -51
- package/dist/orm/runtime/hydrate.mjs.map +0 -1
- package/dist/orm/runtime/rows.cjs +0 -30
- package/dist/orm/runtime/rows.mjs +0 -31
- package/dist/orm/runtime/rows.mjs.map +0 -1
- package/dist/orm/runtime/utils.cjs +0 -27
- package/dist/orm/runtime/utils.mjs +0 -27
- package/dist/orm/runtime/utils.mjs.map +0 -1
- package/dist/orm/sql/parse-array.cjs +0 -64
- package/dist/orm/sql/parse-array.mjs +0 -66
- package/dist/orm/sql/parse-array.mjs.map +0 -1
- package/dist/orm/sql/plan/select.cjs +0 -36
- package/dist/orm/sql/plan/select.mjs +0 -38
- package/dist/orm/sql/plan/select.mjs.map +0 -1
- package/dist/orm/sql/plan/where/operators.cjs +0 -95
- package/dist/orm/sql/plan/where/operators.mjs +0 -97
- package/dist/orm/sql/plan/where/operators.mjs.map +0 -1
- package/dist/orm/sql/plan/where.cjs +0 -59
- package/dist/orm/sql/plan/where.mjs +0 -61
- package/dist/orm/sql/plan/where.mjs.map +0 -1
- package/dist/orm/sql/serialize/clauses.cjs +0 -36
- package/dist/orm/sql/serialize/clauses.mjs +0 -37
- package/dist/orm/sql/serialize/clauses.mjs.map +0 -1
- package/dist/orm/sql/serialize/joins.cjs +0 -31
- package/dist/orm/sql/serialize/joins.mjs +0 -33
- package/dist/orm/sql/serialize/joins.mjs.map +0 -1
- package/dist/orm/sql/serialize/values.cjs +0 -30
- package/dist/orm/sql/serialize/values.mjs +0 -32
- package/dist/orm/sql/serialize/values.mjs.map +0 -1
- package/dist/orm/sql/serialize/where/predicate.cjs +0 -73
- package/dist/orm/sql/serialize/where/predicate.mjs +0 -75
- package/dist/orm/sql/serialize/where/predicate.mjs.map +0 -1
- package/dist/orm/sql/serialize/where/tree.cjs +0 -26
- package/dist/orm/sql/serialize/where/tree.mjs +0 -28
- package/dist/orm/sql/serialize/where/tree.mjs.map +0 -1
- package/dist/orm/sql/serialize/where.cjs +0 -10
- package/dist/orm/sql/serialize/where.mjs +0 -12
- package/dist/orm/sql/serialize/where.mjs.map +0 -1
- package/dist/orm/sql/serialize.cjs +0 -24
- package/dist/orm/sql/serialize.mjs +0 -25
- package/dist/orm/sql/serialize.mjs.map +0 -1
- package/dist/orm/table.cjs +0 -12
- package/dist/orm/table.d.cts +0 -12
- package/dist/orm/table.d.cts.map +0 -1
- package/dist/orm/table.d.mts +0 -12
- package/dist/orm/table.d.mts.map +0 -1
- package/dist/orm/table.mjs +0 -14
- package/dist/orm/table.mjs.map +0 -1
- package/dist/orm/types.d.cts +0 -183
- package/dist/orm/types.d.cts.map +0 -1
- package/dist/orm/types.d.mts +0 -183
- package/dist/orm/types.d.mts.map +0 -1
- package/dist/policy/helpers.cjs +0 -206
- package/dist/policy/helpers.d.cts +0 -50
- package/dist/policy/helpers.d.cts.map +0 -1
- package/dist/policy/helpers.d.mts +0 -50
- package/dist/policy/helpers.d.mts.map +0 -1
- package/dist/policy/helpers.mjs +0 -190
- package/dist/policy/helpers.mjs.map +0 -1
- package/dist/policy/types.d.cts +0 -16
- package/dist/policy/types.d.cts.map +0 -1
- package/dist/policy/types.d.mts +0 -16
- package/dist/policy/types.d.mts.map +0 -1
- package/dist/prompts/core/keys.cjs +0 -165
- package/dist/prompts/core/keys.mjs +0 -167
- package/dist/prompts/core/keys.mjs.map +0 -1
- package/dist/prompts/core/runtime.cjs +0 -104
- package/dist/prompts/core/runtime.mjs +0 -106
- package/dist/prompts/core/runtime.mjs.map +0 -1
- package/dist/prompts/core/session.cjs +0 -98
- package/dist/prompts/core/session.mjs +0 -100
- package/dist/prompts/core/session.mjs.map +0 -1
- package/dist/prompts/core/types.d.cts +0 -21
- package/dist/prompts/core/types.d.cts.map +0 -1
- package/dist/prompts/core/types.d.mts +0 -21
- package/dist/prompts/core/types.d.mts.map +0 -1
- package/dist/prompts/types.d.cts +0 -52
- package/dist/prompts/types.d.cts.map +0 -1
- package/dist/prompts/types.d.mts +0 -52
- package/dist/prompts/types.d.mts.map +0 -1
- package/dist/pubsub/types.d.cts +0 -10
- package/dist/pubsub/types.d.cts.map +0 -1
- package/dist/pubsub/types.d.mts +0 -10
- package/dist/pubsub/types.d.mts.map +0 -1
- package/dist/queue/types.d.cts +0 -47
- package/dist/queue/types.d.cts.map +0 -1
- package/dist/queue/types.d.mts +0 -47
- package/dist/queue/types.d.mts.map +0 -1
- package/dist/workflow/types.d.cts +0 -83
- package/dist/workflow/types.d.cts.map +0 -1
- package/dist/workflow/types.d.mts +0 -83
- package/dist/workflow/types.d.mts.map +0 -1
package/dist/cron/core/index.mjs
DELETED
|
@@ -1,310 +0,0 @@
|
|
|
1
|
-
import { err, mightThrow, ok } from "../../lib/errors/index.mjs";
|
|
2
|
-
import { FieldAmount, Scanner } from "./scanner.mjs";
|
|
3
|
-
//#region src/lib/cron/core/index.ts
|
|
4
|
-
const RETRY_DELAY_MS = 3600 * 1e3;
|
|
5
|
-
const MAX_YEARS = 4;
|
|
6
|
-
const ALIASES = {
|
|
7
|
-
"@yearly": "0 0 1 1 *",
|
|
8
|
-
"@monthly": "0 0 1 * *",
|
|
9
|
-
"@weekly": "0 0 * * 0",
|
|
10
|
-
"@daily": "0 0 * * *",
|
|
11
|
-
"@hourly": "0 * * * *",
|
|
12
|
-
"@minutely": "* * * * *"
|
|
13
|
-
};
|
|
14
|
-
const CronSecondRange = {
|
|
15
|
-
min: 0,
|
|
16
|
-
max: 59
|
|
17
|
-
};
|
|
18
|
-
const CronMinuteRange = {
|
|
19
|
-
min: 0,
|
|
20
|
-
max: 59
|
|
21
|
-
};
|
|
22
|
-
const CronHourRange = {
|
|
23
|
-
min: 0,
|
|
24
|
-
max: 23
|
|
25
|
-
};
|
|
26
|
-
const CronDayRange = {
|
|
27
|
-
min: 1,
|
|
28
|
-
max: 31
|
|
29
|
-
};
|
|
30
|
-
const CronMonthRange = {
|
|
31
|
-
min: 1,
|
|
32
|
-
max: 12
|
|
33
|
-
};
|
|
34
|
-
const CronDayOfWeekRange = {
|
|
35
|
-
min: 0,
|
|
36
|
-
max: 6
|
|
37
|
-
};
|
|
38
|
-
var Cron = class {
|
|
39
|
-
options;
|
|
40
|
-
status = "idle";
|
|
41
|
-
timeoutId = null;
|
|
42
|
-
second = Array(CronSecondRange.max + 1).fill(0);
|
|
43
|
-
minute = Array(CronMinuteRange.max + 1).fill(0);
|
|
44
|
-
hour = Array(CronHourRange.max + 1).fill(0);
|
|
45
|
-
day = Array(CronDayRange.max + 1).fill(0);
|
|
46
|
-
month = Array(CronMonthRange.max + 1).fill(0);
|
|
47
|
-
dayOfWeek = Array(CronDayOfWeekRange.max + 1).fill(0);
|
|
48
|
-
hasSeconds;
|
|
49
|
-
_dayWildcard = false;
|
|
50
|
-
_dowWildcard = false;
|
|
51
|
-
fillRange(values, min, max) {
|
|
52
|
-
for (let i = min; i <= max; i++) values[i] = 1;
|
|
53
|
-
}
|
|
54
|
-
handleStep(part, values, min, max) {
|
|
55
|
-
const [rangePart, stepStr] = part.split("/");
|
|
56
|
-
if (!rangePart) return err("InvalidValueError", `'${rangePart}' is empty`);
|
|
57
|
-
if (!stepStr) return err("InvalidValueError", `'${stepStr}' is empty`);
|
|
58
|
-
const step = Number(stepStr);
|
|
59
|
-
if (!Number.isInteger(step)) return err("InvalidValueError", `'${step}' is not a valid number`);
|
|
60
|
-
if (step <= 0) return err("OutOfBoundError", `Expected ${step} > 0`);
|
|
61
|
-
if (rangePart === "*") {
|
|
62
|
-
for (let i = min; i <= max; i += step) values[i] = 1;
|
|
63
|
-
return ok(true);
|
|
64
|
-
}
|
|
65
|
-
if (rangePart.includes("-")) return this.handleStepRange(rangePart, step, values, min, max);
|
|
66
|
-
return this.handleStepSingle(rangePart, step, values, min, max);
|
|
67
|
-
}
|
|
68
|
-
handleStepRange(range, step, values, min, max) {
|
|
69
|
-
const [startStr, endStr] = range.split("-");
|
|
70
|
-
if (!endStr) return err("InvalidValueError", `'${endStr}' is empty`);
|
|
71
|
-
let start = min;
|
|
72
|
-
if (startStr && startStr.length > 0) start = Number(startStr);
|
|
73
|
-
const end = Number(endStr);
|
|
74
|
-
if (!Number.isInteger(start)) return err("InvalidValueError", `'${start}' is not a valid number`);
|
|
75
|
-
if (!Number.isInteger(end)) return err("InvalidValueError", `'${end}' is not a valid number`);
|
|
76
|
-
if (start < min) return err("OutOfBoundError", `Expected ${start} >= ${min}`);
|
|
77
|
-
if (end > max) return err("OutOfBoundError", `Expected ${end} <= ${max}`);
|
|
78
|
-
if (start > end) return err("OutOfBoundError", `Expected ${start} <= ${end}`);
|
|
79
|
-
for (let i = start; i <= end; i += step) values[i] = 1;
|
|
80
|
-
return ok(true);
|
|
81
|
-
}
|
|
82
|
-
handleStepSingle(value, step, values, min, max) {
|
|
83
|
-
const start = Number(value);
|
|
84
|
-
if (!Number.isInteger(start)) return err("InvalidValueError", `'${start}' is not a valid number`);
|
|
85
|
-
if (start < min) return err("OutOfBoundError", `Expected ${start} >= ${min}`);
|
|
86
|
-
if (start > max) return err("OutOfBoundError", `Expected ${start} <= ${max}`);
|
|
87
|
-
for (let i = start; i <= max; i += step) values[i] = 1;
|
|
88
|
-
return ok(true);
|
|
89
|
-
}
|
|
90
|
-
handleRange(part, values, min, max) {
|
|
91
|
-
const [startStr, endStr] = part.split("-");
|
|
92
|
-
if (!startStr) return err("InvalidValueError", `'${startStr}' is empty`);
|
|
93
|
-
if (!endStr) return err("InvalidValueError", `'${endStr}' is empty`);
|
|
94
|
-
const start = Number(startStr);
|
|
95
|
-
const end = Number(endStr);
|
|
96
|
-
if (!Number.isInteger(start)) return err("InvalidValueError", `'${start}' is not a valid number`);
|
|
97
|
-
if (!Number.isInteger(end)) return err("InvalidValueError", `'${end}' is not a valid number`);
|
|
98
|
-
if (start < min) return err("OutOfBoundError", `Expected ${start} >= ${min}`);
|
|
99
|
-
if (end > max) return err("OutOfBoundError", `Expected ${end} <= ${max}`);
|
|
100
|
-
if (start > end) return err("OutOfBoundError", `Expected ${start} <= ${end}`);
|
|
101
|
-
for (let i = start; i <= end; i++) values[i] = 1;
|
|
102
|
-
return ok(true);
|
|
103
|
-
}
|
|
104
|
-
handleNumber(value, values, min, max) {
|
|
105
|
-
const n = Number(value);
|
|
106
|
-
if (!Number.isInteger(n)) return err("InvalidValueError", `'${value}' is not a valid number`);
|
|
107
|
-
if (n < min) return err("OutOfBoundError", `Expected ${n} >= ${min}`);
|
|
108
|
-
if (n > max) return err("OutOfBoundError", `Expected ${n} <= ${max}`);
|
|
109
|
-
values[n] = 1;
|
|
110
|
-
return ok(true);
|
|
111
|
-
}
|
|
112
|
-
constructor(options) {
|
|
113
|
-
this.options = options;
|
|
114
|
-
const expr = this.resolveAlias(options.schedule);
|
|
115
|
-
const [error, tokens] = new Scanner(expr).scan();
|
|
116
|
-
if (error) throw new Error(`${error.type}: ${error.message}`);
|
|
117
|
-
this.hasSeconds = expr.trim().split(/\s+/).length === FieldAmount.max;
|
|
118
|
-
const [parsingError, _] = this.parse(tokens);
|
|
119
|
-
if (parsingError) throw new Error(`${parsingError.type}: ${parsingError.message}`);
|
|
120
|
-
}
|
|
121
|
-
resolveAlias(schedule) {
|
|
122
|
-
return ALIASES[schedule] || schedule;
|
|
123
|
-
}
|
|
124
|
-
parse(tokens) {
|
|
125
|
-
for (let i = 0; i < tokens.length; i++) {
|
|
126
|
-
const token = tokens[i];
|
|
127
|
-
if (!token) return err("InvalidValueError", "Undefined token");
|
|
128
|
-
const tokenType = token.getTokenType();
|
|
129
|
-
switch (token.getField()) {
|
|
130
|
-
case "second": {
|
|
131
|
-
const [error, _] = this.handleField(token, this.second, CronSecondRange.min, CronSecondRange.max);
|
|
132
|
-
if (error) return err(error.type, `${error.message} in field '${token.getField()}'`);
|
|
133
|
-
break;
|
|
134
|
-
}
|
|
135
|
-
case "minute": {
|
|
136
|
-
const [error, _] = this.handleField(token, this.minute, CronMinuteRange.min, CronMinuteRange.max);
|
|
137
|
-
if (error) return err(error.type, `${error.message} in field '${token.getField()}'`);
|
|
138
|
-
break;
|
|
139
|
-
}
|
|
140
|
-
case "hour": {
|
|
141
|
-
const [error, _] = this.handleField(token, this.hour, CronHourRange.min, CronHourRange.max);
|
|
142
|
-
if (error) return err(error.type, `${error.message} in field '${token.getField()}'`);
|
|
143
|
-
break;
|
|
144
|
-
}
|
|
145
|
-
case "day": {
|
|
146
|
-
if (tokenType === "any") this._dayWildcard = true;
|
|
147
|
-
const [error, _] = this.handleField(token, this.day, CronDayRange.min, CronDayRange.max);
|
|
148
|
-
if (error) return err(error.type, `${error.message} in field '${token.getField()}'`);
|
|
149
|
-
break;
|
|
150
|
-
}
|
|
151
|
-
case "month": {
|
|
152
|
-
const [error, _] = this.handleField(token, this.month, CronMonthRange.min, CronMonthRange.max);
|
|
153
|
-
if (error) return err(error.type, `${error.message} in field '${token.getField()}'`);
|
|
154
|
-
break;
|
|
155
|
-
}
|
|
156
|
-
case "weekday": {
|
|
157
|
-
if (tokenType === "any") this._dowWildcard = true;
|
|
158
|
-
const [error, _] = this.handleField(token, this.dayOfWeek, CronDayOfWeekRange.min, CronDayOfWeekRange.max);
|
|
159
|
-
if (error) return err(error.type, `${error.message} in field '${token.getField()}'`);
|
|
160
|
-
break;
|
|
161
|
-
}
|
|
162
|
-
default: return err("InvalidValueError", `Invalid field '${token.getField()}'`);
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
return ok(true);
|
|
166
|
-
}
|
|
167
|
-
handleField(token, field, min, max) {
|
|
168
|
-
switch (token.getTokenType()) {
|
|
169
|
-
case "any":
|
|
170
|
-
this.fillRange(field, min, max);
|
|
171
|
-
break;
|
|
172
|
-
case "number": {
|
|
173
|
-
const [error, _] = this.handleNumber(token.getComponent(), field, min, max);
|
|
174
|
-
if (error) return err(error.type, error.message);
|
|
175
|
-
break;
|
|
176
|
-
}
|
|
177
|
-
case "range": {
|
|
178
|
-
const component = token.getComponent();
|
|
179
|
-
const [error, _] = this.handleRange(component, field, min, max);
|
|
180
|
-
if (error) return err(error.type, error.message);
|
|
181
|
-
break;
|
|
182
|
-
}
|
|
183
|
-
case "step": {
|
|
184
|
-
const component = token.getComponent();
|
|
185
|
-
const [error, _] = this.handleStep(component, field, min, max);
|
|
186
|
-
if (error) return err(error.type, error.message);
|
|
187
|
-
break;
|
|
188
|
-
}
|
|
189
|
-
default: return err("InvalidValueError", `Invalid token type '${token.getTokenType()}'`);
|
|
190
|
-
}
|
|
191
|
-
return ok(true);
|
|
192
|
-
}
|
|
193
|
-
matches(date) {
|
|
194
|
-
const s = date.getSeconds();
|
|
195
|
-
const m = date.getMinutes();
|
|
196
|
-
const h = date.getHours();
|
|
197
|
-
const d = date.getDate();
|
|
198
|
-
const mon = date.getMonth();
|
|
199
|
-
const dow = date.getDay();
|
|
200
|
-
const isSecondMatch = this.hasSeconds ? this.second[s] === 1 : true;
|
|
201
|
-
const isMinuteMatch = this.minute[m] === 1;
|
|
202
|
-
const isHourMatch = this.hour[h] === 1;
|
|
203
|
-
const isMonthMatch = this.month[mon + 1] === 1;
|
|
204
|
-
let isDayOrDowMatch;
|
|
205
|
-
if (!this._dayWildcard && !this._dowWildcard) isDayOrDowMatch = this.day[d] === 1 || this.dayOfWeek[dow] === 1;
|
|
206
|
-
else isDayOrDowMatch = this.day[d] === 1 && this.dayOfWeek[dow] === 1;
|
|
207
|
-
return isSecondMatch && isMinuteMatch && isHourMatch && isDayOrDowMatch && isMonthMatch;
|
|
208
|
-
}
|
|
209
|
-
getNextRun() {
|
|
210
|
-
const date = /* @__PURE__ */ new Date();
|
|
211
|
-
if (this.hasSeconds) {
|
|
212
|
-
date.setMilliseconds(0);
|
|
213
|
-
date.setSeconds(date.getSeconds() + 1);
|
|
214
|
-
} else {
|
|
215
|
-
date.setSeconds(0, 0);
|
|
216
|
-
date.setMinutes(date.getMinutes() + 1);
|
|
217
|
-
}
|
|
218
|
-
const deadline = new Date(date);
|
|
219
|
-
deadline.setFullYear(deadline.getFullYear() + MAX_YEARS);
|
|
220
|
-
while (date < deadline) {
|
|
221
|
-
const s = date.getSeconds();
|
|
222
|
-
const m = date.getMinutes();
|
|
223
|
-
const h = date.getHours();
|
|
224
|
-
const d = date.getDate();
|
|
225
|
-
const mon = date.getMonth();
|
|
226
|
-
const dow = date.getDay();
|
|
227
|
-
if (this.month[mon + 1] === 0) {
|
|
228
|
-
date.setDate(1);
|
|
229
|
-
date.setMonth(mon + 1);
|
|
230
|
-
date.setHours(0, 0, 0, 0);
|
|
231
|
-
continue;
|
|
232
|
-
}
|
|
233
|
-
let isDayOrDowMatch;
|
|
234
|
-
if (!this._dayWildcard && !this._dowWildcard) isDayOrDowMatch = this.day[d] === 0 && this.dayOfWeek[dow] === 0;
|
|
235
|
-
else isDayOrDowMatch = this.day[d] === 0 || this.dayOfWeek[dow] === 0;
|
|
236
|
-
if (isDayOrDowMatch) {
|
|
237
|
-
date.setDate(d + 1);
|
|
238
|
-
date.setHours(0, 0, 0, 0);
|
|
239
|
-
continue;
|
|
240
|
-
}
|
|
241
|
-
if (this.hour[h] === 0) {
|
|
242
|
-
date.setHours(h + 1);
|
|
243
|
-
date.setMinutes(0, 0, 0);
|
|
244
|
-
continue;
|
|
245
|
-
}
|
|
246
|
-
if (this.minute[m] === 0) {
|
|
247
|
-
date.setMinutes(m + 1);
|
|
248
|
-
date.setSeconds(0, 0);
|
|
249
|
-
continue;
|
|
250
|
-
}
|
|
251
|
-
if (this.hasSeconds && this.second[s] === 0) {
|
|
252
|
-
date.setSeconds(s + 1);
|
|
253
|
-
date.setMilliseconds(0);
|
|
254
|
-
continue;
|
|
255
|
-
}
|
|
256
|
-
return new Date(date);
|
|
257
|
-
}
|
|
258
|
-
return null;
|
|
259
|
-
}
|
|
260
|
-
start() {
|
|
261
|
-
if (this.status !== "idle") return;
|
|
262
|
-
this.status = "running";
|
|
263
|
-
this.next();
|
|
264
|
-
}
|
|
265
|
-
stop() {
|
|
266
|
-
this.status = "idle";
|
|
267
|
-
if (this.timeoutId) {
|
|
268
|
-
clearTimeout(this.timeoutId);
|
|
269
|
-
this.timeoutId = null;
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
pause() {
|
|
273
|
-
if (this.status !== "running") return;
|
|
274
|
-
this.status = "paused";
|
|
275
|
-
if (this.timeoutId) {
|
|
276
|
-
clearTimeout(this.timeoutId);
|
|
277
|
-
this.timeoutId = null;
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
|
-
resume() {
|
|
281
|
-
if (this.status !== "paused") return;
|
|
282
|
-
this.status = "running";
|
|
283
|
-
this.next();
|
|
284
|
-
}
|
|
285
|
-
getStatus() {
|
|
286
|
-
return this.status;
|
|
287
|
-
}
|
|
288
|
-
next() {
|
|
289
|
-
if (this.status !== "running") return;
|
|
290
|
-
const nextRun = this.getNextRun();
|
|
291
|
-
if (!nextRun) {
|
|
292
|
-
this.timeoutId = setTimeout(() => this.next(), RETRY_DELAY_MS);
|
|
293
|
-
return;
|
|
294
|
-
}
|
|
295
|
-
const delay = nextRun.getTime() - Date.now();
|
|
296
|
-
this.timeoutId = setTimeout(() => {
|
|
297
|
-
this.run();
|
|
298
|
-
}, Math.max(0, delay));
|
|
299
|
-
}
|
|
300
|
-
async run() {
|
|
301
|
-
if (this.status !== "running") return;
|
|
302
|
-
const handlerResult = this.options.handler();
|
|
303
|
-
await mightThrow(Promise.resolve(handlerResult));
|
|
304
|
-
if (this.status === "running") this.next();
|
|
305
|
-
}
|
|
306
|
-
};
|
|
307
|
-
//#endregion
|
|
308
|
-
export { Cron };
|
|
309
|
-
|
|
310
|
-
//# sourceMappingURL=index.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../../../src/lib/cron/core/index.ts"],"sourcesContent":["import { err, mightThrow, ok } from \"../../errors/index.js\";\nimport { FieldAmount, Scanner, type Token } from \"./scanner.js\";\nimport type { CronOptions, CronParsingError, CronStatus } from \"./types.js\";\n\nconst RETRY_DELAY_MS = 60 * 60 * 1000; // 1 hour\nconst MAX_YEARS = 4;\n\nconst ALIASES: Record<string, string> = {\n \"@yearly\": \"0 0 1 1 *\",\n \"@monthly\": \"0 0 1 * *\",\n \"@weekly\": \"0 0 * * 0\",\n \"@daily\": \"0 0 * * *\",\n \"@hourly\": \"0 * * * *\",\n \"@minutely\": \"* * * * *\",\n};\n\nconst CronSecondRange = {\n min: 0,\n max: 59,\n} as const;\n\nconst CronMinuteRange = {\n min: 0,\n max: 59,\n} as const;\n\nconst CronHourRange = {\n min: 0,\n max: 23,\n} as const;\n\nconst CronDayRange = {\n min: 1,\n max: 31,\n} as const;\n\nconst CronMonthRange = {\n min: 1,\n max: 12,\n} as const;\n\nconst CronDayOfWeekRange = {\n min: 0,\n max: 6,\n} as const;\n\nexport class Cron {\n private options: CronOptions;\n private status: CronStatus = \"idle\";\n private timeoutId: NodeJS.Timeout | null = null;\n\n // Array-based storage using 1-indexed slots (0 = don't run, 1 = run)\n private second = Array<number>(CronSecondRange.max + 1).fill(0); // 0-59\n private minute = Array<number>(CronMinuteRange.max + 1).fill(0); // 0-59\n private hour = Array<number>(CronHourRange.max + 1).fill(0); // 0-23\n private day = Array<number>(CronDayRange.max + 1).fill(0); // indices 1-31 (0 unused)\n private month = Array<number>(CronMonthRange.max + 1).fill(0); // indices 1-12 (0 unused)\n private dayOfWeek = Array<number>(CronDayOfWeekRange.max + 1).fill(0); // 0-6\n private hasSeconds: boolean;\n private _dayWildcard = false;\n private _dowWildcard = false;\n\n // Fill all values from min to max with 1\n private fillRange(values: number[], min: number, max: number) {\n for (let i = min; i <= max; i++) {\n values[i] = 1;\n }\n }\n\n private handleStep(part: string, values: number[], min: number, max: number) {\n // Split step format into range and step components\n const [rangePart, stepStr] = part.split(\"/\");\n\n if (!rangePart) {\n return err<CronParsingError>(\n \"InvalidValueError\",\n `'${rangePart}' is empty`,\n );\n }\n\n if (!stepStr) {\n return err<CronParsingError>(\n \"InvalidValueError\",\n `'${stepStr}' is empty`,\n );\n }\n\n const step = Number(stepStr);\n\n // Validate step is a positive integer\n if (!Number.isInteger(step)) {\n return err<CronParsingError>(\n \"InvalidValueError\",\n `'${step}' is not a valid number`,\n );\n }\n\n if (step <= 0) {\n return err<CronParsingError>(\"OutOfBoundError\", `Expected ${step} > 0`);\n }\n\n if (rangePart === \"*\") {\n // Wildcard with step: apply step across entire range\n for (let i = min; i <= max; i += step) {\n values[i] = 1;\n }\n\n return ok(true);\n }\n\n if (rangePart.includes(\"-\")) {\n // Range with step: delegate to specialized handler\n return this.handleStepRange(rangePart, step, values, min, max);\n }\n\n // Single value with step: delegate to specialized handler\n return this.handleStepSingle(rangePart, step, values, min, max);\n }\n\n private handleStepRange(\n range: string,\n step: number,\n values: number[],\n min: number,\n max: number,\n ) {\n // Split range into start and end values\n const [startStr, endStr] = range.split(\"-\");\n\n if (!endStr) {\n return err<CronParsingError>(\"InvalidValueError\", `'${endStr}' is empty`);\n }\n\n let start = min;\n if (startStr && startStr.length > 0) {\n start = Number(startStr);\n }\n\n const end = Number(endStr);\n\n // Validate range boundaries are integers within bounds\n if (!Number.isInteger(start)) {\n return err<CronParsingError>(\n \"InvalidValueError\",\n `'${start}' is not a valid number`,\n );\n }\n\n if (!Number.isInteger(end)) {\n return err<CronParsingError>(\n \"InvalidValueError\",\n `'${end}' is not a valid number`,\n );\n }\n\n if (start < min) {\n return err<CronParsingError>(\n \"OutOfBoundError\",\n `Expected ${start} >= ${min}`,\n );\n }\n\n if (end > max) {\n return err<CronParsingError>(\n \"OutOfBoundError\",\n `Expected ${end} <= ${max}`,\n );\n }\n\n if (start > end) {\n return err<CronParsingError>(\n \"OutOfBoundError\",\n `Expected ${start} <= ${end}`,\n );\n }\n\n // Apply step through range\n for (let i = start; i <= end; i += step) {\n values[i] = 1;\n }\n\n return ok(true);\n }\n\n private handleStepSingle(\n value: string,\n step: number,\n values: number[],\n min: number,\n max: number,\n ) {\n const start = Number(value);\n\n // Validate starting value is an integer within bounds\n if (!Number.isInteger(start)) {\n return err<CronParsingError>(\n \"InvalidValueError\",\n `'${start}' is not a valid number`,\n );\n }\n\n if (start < min) {\n return err<CronParsingError>(\n \"OutOfBoundError\",\n `Expected ${start} >= ${min}`,\n );\n }\n\n if (start > max) {\n return err<CronParsingError>(\n \"OutOfBoundError\",\n `Expected ${start} <= ${max}`,\n );\n }\n\n // Apply step from start to end of range\n for (let i = start; i <= max; i += step) {\n values[i] = 1;\n }\n\n return ok(true);\n }\n\n private handleRange(\n part: string,\n values: number[],\n min: number,\n max: number,\n ) {\n // Split range into start and end values\n const [startStr, endStr] = part.split(\"-\");\n\n if (!startStr) {\n return err<CronParsingError>(\n \"InvalidValueError\",\n `'${startStr}' is empty`,\n );\n }\n\n if (!endStr) {\n return err<CronParsingError>(\"InvalidValueError\", `'${endStr}' is empty`);\n }\n\n const start = Number(startStr);\n const end = Number(endStr);\n\n // Validate range boundaries are integers within bounds\n if (!Number.isInteger(start)) {\n return err<CronParsingError>(\n \"InvalidValueError\",\n `'${start}' is not a valid number`,\n );\n }\n\n if (!Number.isInteger(end)) {\n return err<CronParsingError>(\n \"InvalidValueError\",\n `'${end}' is not a valid number`,\n );\n }\n\n if (start < min) {\n return err<CronParsingError>(\n \"OutOfBoundError\",\n `Expected ${start} >= ${min}`,\n );\n }\n\n if (end > max) {\n return err<CronParsingError>(\n \"OutOfBoundError\",\n `Expected ${end} <= ${max}`,\n );\n }\n\n if (start > end) {\n return err<CronParsingError>(\n \"OutOfBoundError\",\n `Expected ${start} <= ${end}`,\n );\n }\n\n // Mark all values in the range\n for (let i = start; i <= end; i++) {\n values[i] = 1;\n }\n\n return ok(true);\n }\n\n private handleNumber(\n value: string,\n values: number[],\n min: number,\n max: number,\n ) {\n const n = Number(value);\n\n // Validate value is an integer within bounds\n if (!Number.isInteger(n)) {\n return err<CronParsingError>(\n \"InvalidValueError\",\n `'${value}' is not a valid number`,\n );\n }\n\n if (n < min) {\n return err<CronParsingError>(\n \"OutOfBoundError\",\n `Expected ${n} >= ${min}`,\n );\n }\n if (n > max) {\n return err<CronParsingError>(\n \"OutOfBoundError\",\n `Expected ${n} <= ${max}`,\n );\n }\n\n values[n] = 1;\n\n return ok(true);\n }\n\n public constructor(options: CronOptions) {\n this.options = options;\n\n // Resolve alias or use raw expression\n const expr = this.resolveAlias(options.schedule);\n const [error, tokens] = new Scanner(expr).scan();\n if (error) throw new Error(`${error.type}: ${error.message}`);\n\n const fields = expr.trim().split(/\\s+/);\n this.hasSeconds = fields.length === FieldAmount.max;\n\n // Parse and validate the cron expression\n const [parsingError, _] = this.parse(tokens);\n\n if (parsingError) {\n throw new Error(`${parsingError.type}: ${parsingError.message}`);\n }\n }\n\n // Map alias to standard cron expression if present\n private resolveAlias(schedule: string) {\n return ALIASES[schedule] || schedule;\n }\n\n private parse(tokens: Token[]) {\n for (let i = 0; i < tokens.length; i++) {\n const token = tokens[i];\n\n if (!token) {\n return err<CronParsingError>(\"InvalidValueError\", \"Undefined token\");\n }\n\n const tokenType = token.getTokenType();\n\n switch (token.getField()) {\n case \"second\": {\n const [error, _] = this.handleField(\n token,\n this.second,\n CronSecondRange.min,\n CronSecondRange.max,\n );\n\n if (error) {\n return err<CronParsingError>(\n error.type,\n `${error.message} in field '${token.getField()}'`,\n );\n }\n\n break;\n }\n case \"minute\": {\n const [error, _] = this.handleField(\n token,\n this.minute,\n CronMinuteRange.min,\n CronMinuteRange.max,\n );\n\n if (error) {\n return err<CronParsingError>(\n error.type,\n `${error.message} in field '${token.getField()}'`,\n );\n }\n\n break;\n }\n case \"hour\": {\n const [error, _] = this.handleField(\n token,\n this.hour,\n CronHourRange.min,\n CronHourRange.max,\n );\n\n if (error) {\n return err<CronParsingError>(\n error.type,\n `${error.message} in field '${token.getField()}'`,\n );\n }\n\n break;\n }\n case \"day\": {\n if (tokenType === \"any\") {\n this._dayWildcard = true;\n }\n\n const [error, _] = this.handleField(\n token,\n this.day,\n CronDayRange.min,\n CronDayRange.max,\n );\n\n if (error) {\n return err<CronParsingError>(\n error.type,\n `${error.message} in field '${token.getField()}'`,\n );\n }\n\n break;\n }\n case \"month\": {\n const [error, _] = this.handleField(\n token,\n this.month,\n CronMonthRange.min,\n CronMonthRange.max,\n );\n\n if (error) {\n return err<CronParsingError>(\n error.type,\n `${error.message} in field '${token.getField()}'`,\n );\n }\n\n break;\n }\n case \"weekday\": {\n if (tokenType === \"any\") {\n this._dowWildcard = true;\n }\n\n const [error, _] = this.handleField(\n token,\n this.dayOfWeek,\n CronDayOfWeekRange.min,\n CronDayOfWeekRange.max,\n );\n\n if (error) {\n return err<CronParsingError>(\n error.type,\n `${error.message} in field '${token.getField()}'`,\n );\n }\n\n break;\n }\n default:\n return err<CronParsingError>(\n \"InvalidValueError\",\n `Invalid field '${token.getField()}'`,\n );\n }\n }\n\n return ok(true);\n }\n\n private handleField(token: Token, field: number[], min: number, max: number) {\n switch (token.getTokenType()) {\n case \"any\": {\n this.fillRange(field, min, max);\n break;\n }\n case \"number\": {\n const [error, _] = this.handleNumber(\n token.getComponent(),\n field,\n min,\n max,\n );\n if (error) return err<CronParsingError>(error.type, error.message);\n\n break;\n }\n case \"range\": {\n const component = token.getComponent();\n const [error, _] = this.handleRange(component, field, min, max);\n if (error) return err<CronParsingError>(error.type, error.message);\n\n break;\n }\n case \"step\": {\n const component = token.getComponent();\n const [error, _] = this.handleStep(component, field, min, max);\n if (error) return err<CronParsingError>(error.type, error.message);\n\n break;\n }\n default:\n return err<CronParsingError>(\n \"InvalidValueError\",\n `Invalid token type '${token.getTokenType()}'`,\n );\n }\n\n return ok(true);\n }\n\n public matches(date: Date) {\n // Extract date/time components\n const s = date.getSeconds();\n const m = date.getMinutes();\n const h = date.getHours();\n const d = date.getDate();\n const mon = date.getMonth();\n const dow = date.getDay();\n\n // Check each component against configured values\n const isSecondMatch = this.hasSeconds ? this.second[s] === 1 : true;\n const isMinuteMatch = this.minute[m] === 1;\n const isHourMatch = this.hour[h] === 1;\n const isMonthMatch = this.month[mon + 1] === 1;\n\n // Standard cron: when both day-of-month and day-of-week are restricted (not *),\n // fire if EITHER matches. When at least one is *, use AND (the wildcard is always 1).\n let isDayOrDowMatch: boolean;\n\n if (!this._dayWildcard && !this._dowWildcard) {\n isDayOrDowMatch = this.day[d] === 1 || this.dayOfWeek[dow] === 1;\n } else {\n isDayOrDowMatch = this.day[d] === 1 && this.dayOfWeek[dow] === 1;\n }\n\n return (\n isSecondMatch &&\n isMinuteMatch &&\n isHourMatch &&\n isDayOrDowMatch &&\n isMonthMatch\n );\n }\n\n public getNextRun() {\n const date = new Date();\n\n // Start from next minute/second\n if (this.hasSeconds) {\n date.setMilliseconds(0);\n date.setSeconds(date.getSeconds() + 1);\n } else {\n date.setSeconds(0, 0);\n date.setMinutes(date.getMinutes() + 1);\n }\n\n // Search up to 4 years to cover leap-day schedules (next Feb 29 can be ~4 years away)\n const deadline = new Date(date);\n deadline.setFullYear(deadline.getFullYear() + MAX_YEARS);\n\n while (date < deadline) {\n const s = date.getSeconds();\n const m = date.getMinutes();\n const h = date.getHours();\n const d = date.getDate();\n const mon = date.getMonth();\n const dow = date.getDay();\n\n if (this.month[mon + 1] === 0) {\n date.setDate(1);\n date.setMonth(mon + 1);\n date.setHours(0, 0, 0, 0);\n continue;\n }\n\n let isDayOrDowMatch: boolean;\n if (!this._dayWildcard && !this._dowWildcard) {\n isDayOrDowMatch = this.day[d] === 0 && this.dayOfWeek[dow] === 0;\n } else {\n isDayOrDowMatch = this.day[d] === 0 || this.dayOfWeek[dow] === 0;\n }\n\n if (isDayOrDowMatch) {\n date.setDate(d + 1);\n date.setHours(0, 0, 0, 0);\n continue;\n }\n\n if (this.hour[h] === 0) {\n date.setHours(h + 1);\n date.setMinutes(0, 0, 0);\n continue;\n }\n\n if (this.minute[m] === 0) {\n date.setMinutes(m + 1);\n date.setSeconds(0, 0);\n continue;\n }\n\n if (this.hasSeconds && this.second[s] === 0) {\n date.setSeconds(s + 1);\n date.setMilliseconds(0);\n continue;\n }\n\n return new Date(date);\n }\n\n return null;\n }\n\n public start() {\n if (this.status !== \"idle\") return;\n\n this.status = \"running\";\n this.next();\n }\n\n public stop() {\n this.status = \"idle\";\n\n if (this.timeoutId) {\n clearTimeout(this.timeoutId);\n this.timeoutId = null;\n }\n }\n\n public pause() {\n if (this.status !== \"running\") return;\n\n this.status = \"paused\";\n\n if (this.timeoutId) {\n clearTimeout(this.timeoutId);\n this.timeoutId = null;\n }\n }\n\n public resume() {\n if (this.status !== \"paused\") return;\n\n this.status = \"running\";\n this.next();\n }\n\n public getStatus() {\n return this.status;\n }\n\n private next() {\n if (this.status !== \"running\") return;\n\n const nextRun = this.getNextRun();\n\n if (!nextRun) {\n this.timeoutId = setTimeout(() => this.next(), RETRY_DELAY_MS);\n return;\n }\n\n const delay = nextRun.getTime() - Date.now();\n const actualDelay = Math.max(0, delay);\n\n this.timeoutId = setTimeout(() => {\n this.run();\n }, actualDelay);\n }\n\n private async run() {\n if (this.status !== \"running\") return;\n\n const handlerResult = this.options.handler();\n await mightThrow(Promise.resolve(handlerResult));\n\n if (this.status === \"running\") {\n this.next();\n }\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,237 +0,0 @@
|
|
|
1
|
-
const require_lib_errors_index = require("../../lib/errors/index.cjs");
|
|
2
|
-
//#region src/lib/cron/core/scanner.ts
|
|
3
|
-
const FieldAmount = {
|
|
4
|
-
min: 5,
|
|
5
|
-
max: 6
|
|
6
|
-
};
|
|
7
|
-
var Token = class {
|
|
8
|
-
type;
|
|
9
|
-
component;
|
|
10
|
-
value;
|
|
11
|
-
field;
|
|
12
|
-
constructor(component, type, value, field) {
|
|
13
|
-
this.component = component;
|
|
14
|
-
this.type = type;
|
|
15
|
-
this.value = value;
|
|
16
|
-
this.field = field;
|
|
17
|
-
}
|
|
18
|
-
getComponent() {
|
|
19
|
-
return this.component;
|
|
20
|
-
}
|
|
21
|
-
getTokenType() {
|
|
22
|
-
return this.type;
|
|
23
|
-
}
|
|
24
|
-
getTokenValue() {
|
|
25
|
-
return this.value;
|
|
26
|
-
}
|
|
27
|
-
getField() {
|
|
28
|
-
return this.field;
|
|
29
|
-
}
|
|
30
|
-
toString() {
|
|
31
|
-
return `Token{${`component="${this.component}", type=${this.type}`}, ${`field="${this.field}", value=${this.value}`}}`;
|
|
32
|
-
}
|
|
33
|
-
equals(other) {
|
|
34
|
-
if (!other) return false;
|
|
35
|
-
const isComponentEqual = this.component === other.getComponent();
|
|
36
|
-
const isTokenTypeEqual = this.type === other.getTokenType();
|
|
37
|
-
const isTokenValueEqual = this.value === other.getTokenValue();
|
|
38
|
-
const isFieldEqual = this.field === other.getField();
|
|
39
|
-
return isComponentEqual && isTokenTypeEqual && isTokenValueEqual && isFieldEqual;
|
|
40
|
-
}
|
|
41
|
-
};
|
|
42
|
-
var Scanner = class {
|
|
43
|
-
expression;
|
|
44
|
-
current;
|
|
45
|
-
start;
|
|
46
|
-
tokens;
|
|
47
|
-
constructor(expression) {
|
|
48
|
-
this.expression = expression;
|
|
49
|
-
this.current = 0;
|
|
50
|
-
this.start = 0;
|
|
51
|
-
this.tokens = [];
|
|
52
|
-
}
|
|
53
|
-
scan() {
|
|
54
|
-
if (this.expression.length === 0) return require_lib_errors_index.err("EmptyCronExpressionError", "Cron expression have zero length");
|
|
55
|
-
const fields = this.expression.trim().split(/\s+/);
|
|
56
|
-
const hasMinLen = fields.length === FieldAmount.min;
|
|
57
|
-
const hasMaxLen = fields.length === FieldAmount.max;
|
|
58
|
-
if (!hasMinLen && !hasMaxLen) return require_lib_errors_index.err("CronLengthError", `Invalid number of fields for '${this.expression}'. Expected 5 or 6 fields but got ${fields.length} field(s)`);
|
|
59
|
-
const components = this.createComponent(fields);
|
|
60
|
-
for (let idx = 0; idx < components.length; idx++) {
|
|
61
|
-
const component = components[idx];
|
|
62
|
-
if (!component) return require_lib_errors_index.err("CronExpressionError", `Invalid cron expression: ${this.expression}`);
|
|
63
|
-
this.current = 0;
|
|
64
|
-
this.start = 0;
|
|
65
|
-
const [error, _] = this.scanComponent(component);
|
|
66
|
-
if (error) return require_lib_errors_index.err(error.type, error.message);
|
|
67
|
-
}
|
|
68
|
-
return require_lib_errors_index.ok(this.tokens);
|
|
69
|
-
}
|
|
70
|
-
scanComponent(component) {
|
|
71
|
-
const { field, content } = component;
|
|
72
|
-
while (this.current < content.length) {
|
|
73
|
-
let currentCh = this.advance(content);
|
|
74
|
-
switch (currentCh) {
|
|
75
|
-
case "*": {
|
|
76
|
-
const ch = this.peek(content);
|
|
77
|
-
if (this.match(content, "/")) {
|
|
78
|
-
const [error, _] = this.handleStep(component);
|
|
79
|
-
if (error) return require_lib_errors_index.err(error.type, error.message);
|
|
80
|
-
} else if (!ch || ch === ",") this.addToken("*", "any", "*", field);
|
|
81
|
-
else return require_lib_errors_index.err("CronExpressionError", `Invalid any expression '${content}' for field '${field}'`);
|
|
82
|
-
break;
|
|
83
|
-
}
|
|
84
|
-
case "-":
|
|
85
|
-
currentCh = this.advance(content);
|
|
86
|
-
if (this.isDigit(currentCh)) {
|
|
87
|
-
const [error, _] = this.handleRangeWithStep(component);
|
|
88
|
-
if (error) return require_lib_errors_index.err(error.type, error.message);
|
|
89
|
-
} else return require_lib_errors_index.err("CronExpressionError", `Invalid range expression '${content}' for field '${field}'`);
|
|
90
|
-
break;
|
|
91
|
-
case ",": {
|
|
92
|
-
if (this.current === 1 && this.start === 0) return require_lib_errors_index.err("CronExpressionError", `Invalid list expression '${content}' for field '${field}'`);
|
|
93
|
-
const next = this.peek(content);
|
|
94
|
-
if (!next || next === ",") return require_lib_errors_index.err("CronExpressionError", `Invalid list expression '${content}' for field '${field}'`);
|
|
95
|
-
break;
|
|
96
|
-
}
|
|
97
|
-
default:
|
|
98
|
-
if (this.isDigit(currentCh)) {
|
|
99
|
-
const [error, _] = this.handleNumber(component);
|
|
100
|
-
if (error) return require_lib_errors_index.err(error.type, error.message);
|
|
101
|
-
} else return require_lib_errors_index.err("CronExpressionError", `Invalid cron expression '${this.expression}' in field '${field}'`);
|
|
102
|
-
break;
|
|
103
|
-
}
|
|
104
|
-
this.start = this.current;
|
|
105
|
-
}
|
|
106
|
-
return require_lib_errors_index.ok(true);
|
|
107
|
-
}
|
|
108
|
-
addToken(component, type, value, field) {
|
|
109
|
-
const token = new Token(component, type, value, field);
|
|
110
|
-
this.tokens.push(token);
|
|
111
|
-
}
|
|
112
|
-
advance(content) {
|
|
113
|
-
const currentCh = content.charAt(this.current);
|
|
114
|
-
this.current += 1;
|
|
115
|
-
return currentCh;
|
|
116
|
-
}
|
|
117
|
-
match(content, expected) {
|
|
118
|
-
if (this.current >= content.length) return false;
|
|
119
|
-
if (content.charAt(this.current) !== expected) return false;
|
|
120
|
-
this.current += 1;
|
|
121
|
-
return true;
|
|
122
|
-
}
|
|
123
|
-
peek(content) {
|
|
124
|
-
if (this.current >= content.length) return void 0;
|
|
125
|
-
return content.charAt(this.current);
|
|
126
|
-
}
|
|
127
|
-
handleStep(component) {
|
|
128
|
-
const { field, content } = component;
|
|
129
|
-
let ch = this.peek(content);
|
|
130
|
-
const slashIdx = this.current - 1;
|
|
131
|
-
while (ch && this.isDigit(ch)) {
|
|
132
|
-
this.advance(content);
|
|
133
|
-
ch = this.peek(content);
|
|
134
|
-
}
|
|
135
|
-
if (ch && ch !== ",") return require_lib_errors_index.err("CronExpressionError", `Invalid step expression '${content}' for field '${field}'`);
|
|
136
|
-
const tokenContent = content.substring(this.start, this.current);
|
|
137
|
-
const value = content.slice(slashIdx + 1, this.current);
|
|
138
|
-
if (value.length === 0) return require_lib_errors_index.err("CronExpressionError", `Invalid step expression '${content}' for field '${field}'`);
|
|
139
|
-
this.addToken(tokenContent, "step", Number(value), field);
|
|
140
|
-
return require_lib_errors_index.ok(true);
|
|
141
|
-
}
|
|
142
|
-
handleRangeWithStep(component) {
|
|
143
|
-
const { field, content } = component;
|
|
144
|
-
let ch = this.peek(content);
|
|
145
|
-
while (ch && this.isDigit(ch)) {
|
|
146
|
-
this.advance(content);
|
|
147
|
-
ch = this.peek(content);
|
|
148
|
-
}
|
|
149
|
-
if (!ch) return require_lib_errors_index.err("CronExpressionError", `Invalid range expression '${content}' for field '${field}'`);
|
|
150
|
-
if (this.match(content, "/")) {
|
|
151
|
-
const [error, _] = this.handleStep(component);
|
|
152
|
-
if (error) return require_lib_errors_index.err(error.type, error.message);
|
|
153
|
-
return require_lib_errors_index.ok(true);
|
|
154
|
-
}
|
|
155
|
-
return require_lib_errors_index.err("CronExpressionError", `Invalid range expression '${content}' for field '${field}'`);
|
|
156
|
-
}
|
|
157
|
-
handleNumber(component) {
|
|
158
|
-
const { field, content } = component;
|
|
159
|
-
let ch = this.peek(content);
|
|
160
|
-
this.start = this.current - 1;
|
|
161
|
-
while (ch && this.isDigit(ch)) {
|
|
162
|
-
this.advance(content);
|
|
163
|
-
ch = this.peek(content);
|
|
164
|
-
}
|
|
165
|
-
if (!ch) {
|
|
166
|
-
const item = content.substring(this.start);
|
|
167
|
-
this.addToken(item, "number", Number(item), field);
|
|
168
|
-
return require_lib_errors_index.ok(true);
|
|
169
|
-
}
|
|
170
|
-
if (this.match(content, "-")) {
|
|
171
|
-
const [error, _] = this.handleRange(component);
|
|
172
|
-
if (error) return require_lib_errors_index.err(error.type, error.message);
|
|
173
|
-
return require_lib_errors_index.ok(true);
|
|
174
|
-
}
|
|
175
|
-
if (this.match(content, "/")) {
|
|
176
|
-
const [error, _] = this.handleStep(component);
|
|
177
|
-
if (error) return require_lib_errors_index.err(error.type, error.message);
|
|
178
|
-
return require_lib_errors_index.ok(true);
|
|
179
|
-
}
|
|
180
|
-
if (!this.isDigit(ch) && ch !== ",") return require_lib_errors_index.err("CronExpressionError", `Invalid number '${content}' for field '${field}'`);
|
|
181
|
-
const item = content.substring(this.start, this.current);
|
|
182
|
-
this.addToken(item, "number", Number(item), field);
|
|
183
|
-
return require_lib_errors_index.ok(true);
|
|
184
|
-
}
|
|
185
|
-
handleRange(component) {
|
|
186
|
-
const { field, content } = component;
|
|
187
|
-
let ch = this.peek(content);
|
|
188
|
-
if (!ch) return require_lib_errors_index.err("CronExpressionError", `Invalid range expression '${content}' for field '${field}'`);
|
|
189
|
-
while (ch && this.isDigit(ch)) {
|
|
190
|
-
this.advance(content);
|
|
191
|
-
ch = this.peek(content);
|
|
192
|
-
}
|
|
193
|
-
if (!ch) {
|
|
194
|
-
const tokenContent = content.substring(this.start);
|
|
195
|
-
this.addToken(tokenContent, "range", tokenContent, field);
|
|
196
|
-
return require_lib_errors_index.ok(true);
|
|
197
|
-
}
|
|
198
|
-
if (this.match(content, "/")) {
|
|
199
|
-
const [error, _] = this.handleStep(component);
|
|
200
|
-
if (error) return require_lib_errors_index.err(error.type, error.message);
|
|
201
|
-
return require_lib_errors_index.ok(true);
|
|
202
|
-
}
|
|
203
|
-
if (ch && ch !== ",") return require_lib_errors_index.err("CronExpressionError", `Invalid range expression '${content}' for field '${field}'`);
|
|
204
|
-
const tokenContent = content.substring(this.start, this.current);
|
|
205
|
-
this.addToken(tokenContent, "range", tokenContent, field);
|
|
206
|
-
return require_lib_errors_index.ok(true);
|
|
207
|
-
}
|
|
208
|
-
isDigit(ch) {
|
|
209
|
-
return ch >= "0" && ch <= "9";
|
|
210
|
-
}
|
|
211
|
-
createComponent(fields) {
|
|
212
|
-
const fieldNames = [
|
|
213
|
-
"second",
|
|
214
|
-
"minute",
|
|
215
|
-
"hour",
|
|
216
|
-
"day",
|
|
217
|
-
"month",
|
|
218
|
-
"weekday"
|
|
219
|
-
];
|
|
220
|
-
const components = [];
|
|
221
|
-
let offset = 1;
|
|
222
|
-
if (fields.length === FieldAmount.max) offset = 0;
|
|
223
|
-
for (let idx = 0; idx < fields.length; idx++) {
|
|
224
|
-
const fieldName = fieldNames[idx + offset];
|
|
225
|
-
const content = fields[idx];
|
|
226
|
-
if (!fieldName || !content) break;
|
|
227
|
-
components.push({
|
|
228
|
-
content,
|
|
229
|
-
field: fieldName
|
|
230
|
-
});
|
|
231
|
-
}
|
|
232
|
-
return components;
|
|
233
|
-
}
|
|
234
|
-
};
|
|
235
|
-
//#endregion
|
|
236
|
-
exports.FieldAmount = FieldAmount;
|
|
237
|
-
exports.Scanner = Scanner;
|