semola 0.5.2 → 0.5.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +88 -13
- package/dist/cron/builder/index.cjs +166 -0
- package/dist/cron/builder/index.d.cts +28 -0
- package/dist/cron/builder/index.d.cts.map +1 -0
- package/dist/cron/builder/index.d.mts +28 -0
- package/dist/cron/builder/index.d.mts.map +1 -0
- package/dist/cron/builder/index.mjs +163 -0
- package/dist/cron/builder/index.mjs.map +1 -0
- package/dist/cron/builder/types.cjs +27 -0
- package/dist/cron/builder/types.d.cts +79 -0
- package/dist/cron/builder/types.d.cts.map +1 -0
- package/dist/cron/builder/types.d.mts +79 -0
- package/dist/cron/builder/types.d.mts.map +1 -0
- package/dist/cron/builder/types.mjs +28 -0
- package/dist/cron/builder/types.mjs.map +1 -0
- package/dist/cron/core/index.cjs +308 -0
- package/dist/cron/core/index.d.cts +39 -0
- package/dist/cron/core/index.d.cts.map +1 -0
- package/dist/cron/core/index.d.mts +39 -0
- package/dist/cron/core/index.d.mts.map +1 -0
- package/dist/cron/core/index.mjs +310 -0
- package/dist/cron/core/index.mjs.map +1 -0
- package/dist/cron/{scanner.cjs → core/scanner.cjs} +2 -2
- package/dist/cron/{scanner.mjs → core/scanner.mjs} +2 -2
- package/dist/cron/core/scanner.mjs.map +1 -0
- package/dist/cron/{types.d.cts → core/types.d.cts} +1 -1
- package/dist/cron/core/types.d.cts.map +1 -0
- package/dist/cron/{types.d.mts → core/types.d.mts} +1 -1
- package/dist/cron/core/types.d.mts.map +1 -0
- package/dist/errors/types.d.cts +1 -1
- package/dist/errors/types.d.mts +1 -1
- package/dist/lib/cache/index.d.cts +3 -3
- package/dist/lib/cache/index.d.mts +3 -3
- package/dist/lib/cron/index.cjs +12 -275
- package/dist/lib/cron/index.d.cts +4 -39
- package/dist/lib/cron/index.d.mts +4 -39
- package/dist/lib/cron/index.mjs +4 -277
- package/dist/lib/errors/index.d.cts +2 -2
- package/dist/lib/errors/index.d.cts.map +1 -1
- package/dist/lib/errors/index.d.mts +2 -2
- package/dist/lib/errors/index.d.mts.map +1 -1
- package/dist/lib/errors/index.mjs.map +1 -1
- package/dist/lib/i18n/index.cjs +6 -1
- package/dist/lib/i18n/index.d.cts.map +1 -1
- package/dist/lib/i18n/index.d.mts.map +1 -1
- package/dist/lib/i18n/index.mjs +6 -1
- package/dist/lib/i18n/index.mjs.map +1 -1
- package/dist/lib/logging/index.cjs +18 -0
- package/dist/lib/logging/index.d.cts +7 -0
- package/dist/lib/logging/index.d.mts +7 -0
- package/dist/lib/logging/index.mjs +5 -0
- package/dist/lib/orm/index.cjs +20 -0
- package/dist/lib/orm/index.d.cts +7 -0
- package/dist/lib/orm/index.d.mts +7 -0
- package/dist/lib/orm/index.mjs +6 -0
- package/dist/lib/prompts/index.d.cts +8 -8
- package/dist/lib/prompts/index.d.mts +8 -8
- package/dist/lib/pubsub/index.cjs +82 -13
- package/dist/lib/pubsub/index.d.cts +14 -5
- package/dist/lib/pubsub/index.d.cts.map +1 -1
- package/dist/lib/pubsub/index.d.mts +14 -5
- package/dist/lib/pubsub/index.d.mts.map +1 -1
- package/dist/lib/pubsub/index.mjs +82 -13
- package/dist/lib/pubsub/index.mjs.map +1 -1
- package/dist/lib/queue/index.d.cts +2 -2
- package/dist/lib/queue/index.d.mts +2 -2
- package/dist/lib/workflow/index.cjs +534 -0
- package/dist/lib/workflow/index.d.cts +7 -0
- package/dist/lib/workflow/index.d.cts.map +1 -0
- package/dist/lib/workflow/index.d.mts +7 -0
- package/dist/lib/workflow/index.d.mts.map +1 -0
- package/dist/lib/workflow/index.mjs +535 -0
- package/dist/lib/workflow/index.mjs.map +1 -0
- package/dist/logging/core/index.cjs +99 -0
- package/dist/logging/core/index.d.cts +26 -0
- package/dist/logging/core/index.d.cts.map +1 -0
- package/dist/logging/core/index.d.mts +26 -0
- package/dist/logging/core/index.d.mts.map +1 -0
- package/dist/logging/core/index.mjs +99 -0
- package/dist/logging/core/index.mjs.map +1 -0
- package/dist/logging/core/types.cjs +10 -0
- package/dist/logging/core/types.d.cts +22 -0
- package/dist/logging/core/types.d.cts.map +1 -0
- package/dist/logging/core/types.d.mts +22 -0
- package/dist/logging/core/types.d.mts.map +1 -0
- package/dist/logging/core/types.mjs +12 -0
- package/dist/logging/core/types.mjs.map +1 -0
- package/dist/logging/formatter/index.cjs +119 -0
- package/dist/logging/formatter/index.d.cts +27 -0
- package/dist/logging/formatter/index.d.cts.map +1 -0
- package/dist/logging/formatter/index.d.mts +27 -0
- package/dist/logging/formatter/index.d.mts.map +1 -0
- package/dist/logging/formatter/index.mjs +115 -0
- package/dist/logging/formatter/index.mjs.map +1 -0
- package/dist/logging/formatter/types.d.cts +5 -0
- package/dist/logging/formatter/types.d.cts.map +1 -0
- package/dist/logging/formatter/types.d.mts +5 -0
- package/dist/logging/formatter/types.d.mts.map +1 -0
- package/dist/logging/provider/index.cjs +165 -0
- package/dist/logging/provider/index.d.cts +28 -0
- package/dist/logging/provider/index.d.cts.map +1 -0
- package/dist/logging/provider/index.d.mts +28 -0
- package/dist/logging/provider/index.d.mts.map +1 -0
- package/dist/logging/provider/index.mjs +165 -0
- package/dist/logging/provider/index.mjs.map +1 -0
- package/dist/logging/provider/types.d.cts +23 -0
- package/dist/logging/provider/types.d.cts.map +1 -0
- package/dist/logging/provider/types.d.mts +23 -0
- package/dist/logging/provider/types.d.mts.map +1 -0
- package/dist/orm/column.cjs +137 -0
- package/dist/orm/column.d.cts +121 -0
- package/dist/orm/column.d.cts.map +1 -0
- package/dist/orm/column.d.mts +121 -0
- package/dist/orm/column.d.mts.map +1 -0
- package/dist/orm/column.mjs +132 -0
- package/dist/orm/column.mjs.map +1 -0
- package/dist/orm/dialect/index.cjs +14 -0
- package/dist/orm/dialect/index.mjs +16 -0
- package/dist/orm/dialect/index.mjs.map +1 -0
- package/dist/orm/dialect/mysql.cjs +31 -0
- package/dist/orm/dialect/mysql.mjs +33 -0
- package/dist/orm/dialect/mysql.mjs.map +1 -0
- package/dist/orm/dialect/postgres.cjs +23 -0
- package/dist/orm/dialect/postgres.mjs +25 -0
- package/dist/orm/dialect/postgres.mjs.map +1 -0
- package/dist/orm/dialect/sqlite.cjs +31 -0
- package/dist/orm/dialect/sqlite.mjs +33 -0
- package/dist/orm/dialect/sqlite.mjs.map +1 -0
- package/dist/orm/dialect/utils.cjs +8 -0
- package/dist/orm/dialect/utils.mjs +10 -0
- package/dist/orm/dialect/utils.mjs.map +1 -0
- package/dist/orm/internal/table-columns.cjs +31 -0
- package/dist/orm/internal/table-columns.mjs +32 -0
- package/dist/orm/internal/table-columns.mjs.map +1 -0
- package/dist/orm/internal/table-lookup.cjs +35 -0
- package/dist/orm/internal/table-lookup.mjs +35 -0
- package/dist/orm/internal/table-lookup.mjs.map +1 -0
- package/dist/orm/internal/table-relations.cjs +28 -0
- package/dist/orm/internal/table-relations.mjs +29 -0
- package/dist/orm/internal/table-relations.mjs.map +1 -0
- package/dist/orm/migration/config.cjs +7 -0
- package/dist/orm/migration/config.d.cts +7 -0
- package/dist/orm/migration/config.d.cts.map +1 -0
- package/dist/orm/migration/config.d.mts +7 -0
- package/dist/orm/migration/config.d.mts.map +1 -0
- package/dist/orm/migration/config.mjs +8 -0
- package/dist/orm/migration/config.mjs.map +1 -0
- package/dist/orm/migration/types.d.cts +20 -0
- package/dist/orm/migration/types.d.cts.map +1 -0
- package/dist/orm/migration/types.d.mts +20 -0
- package/dist/orm/migration/types.d.mts.map +1 -0
- package/dist/orm/orm.cjs +41 -0
- package/dist/orm/orm.d.cts +18 -0
- package/dist/orm/orm.d.cts.map +1 -0
- package/dist/orm/orm.d.mts +18 -0
- package/dist/orm/orm.d.mts.map +1 -0
- package/dist/orm/orm.mjs +43 -0
- package/dist/orm/orm.mjs.map +1 -0
- package/dist/orm/relation.cjs +18 -0
- package/dist/orm/relation.d.cts +8 -0
- package/dist/orm/relation.d.cts.map +1 -0
- package/dist/orm/relation.d.mts +8 -0
- package/dist/orm/relation.d.mts.map +1 -0
- package/dist/orm/relation.mjs +19 -0
- package/dist/orm/relation.mjs.map +1 -0
- package/dist/orm/runtime/builders/mutations.cjs +29 -0
- package/dist/orm/runtime/builders/mutations.mjs +28 -0
- package/dist/orm/runtime/builders/mutations.mjs.map +1 -0
- package/dist/orm/runtime/builders/select.cjs +18 -0
- package/dist/orm/runtime/builders/select.mjs +19 -0
- package/dist/orm/runtime/builders/select.mjs.map +1 -0
- package/dist/orm/runtime/client.cjs +90 -0
- package/dist/orm/runtime/client.mjs +92 -0
- package/dist/orm/runtime/client.mjs.map +1 -0
- package/dist/orm/runtime/context.cjs +49 -0
- package/dist/orm/runtime/context.mjs +51 -0
- package/dist/orm/runtime/context.mjs.map +1 -0
- package/dist/orm/runtime/dialect/index.cjs +11 -0
- package/dist/orm/runtime/dialect/index.mjs +13 -0
- package/dist/orm/runtime/dialect/index.mjs.map +1 -0
- package/dist/orm/runtime/dialect/mysql.cjs +95 -0
- package/dist/orm/runtime/dialect/mysql.mjs +97 -0
- package/dist/orm/runtime/dialect/mysql.mjs.map +1 -0
- package/dist/orm/runtime/dialect/postgres.cjs +51 -0
- package/dist/orm/runtime/dialect/postgres.mjs +53 -0
- package/dist/orm/runtime/dialect/postgres.mjs.map +1 -0
- package/dist/orm/runtime/dialect/sqlite.cjs +4 -0
- package/dist/orm/runtime/dialect/sqlite.mjs +7 -0
- package/dist/orm/runtime/dialect/sqlite.mjs.map +1 -0
- package/dist/orm/runtime/errors.cjs +19 -0
- package/dist/orm/runtime/errors.mjs +21 -0
- package/dist/orm/runtime/errors.mjs.map +1 -0
- package/dist/orm/runtime/hydrate/many.cjs +46 -0
- package/dist/orm/runtime/hydrate/many.mjs +48 -0
- package/dist/orm/runtime/hydrate/many.mjs.map +1 -0
- package/dist/orm/runtime/hydrate/one.cjs +38 -0
- package/dist/orm/runtime/hydrate/one.mjs +40 -0
- package/dist/orm/runtime/hydrate/one.mjs.map +1 -0
- package/dist/orm/runtime/hydrate.cjs +49 -0
- package/dist/orm/runtime/hydrate.mjs +51 -0
- package/dist/orm/runtime/hydrate.mjs.map +1 -0
- package/dist/orm/runtime/rows.cjs +30 -0
- package/dist/orm/runtime/rows.mjs +31 -0
- package/dist/orm/runtime/rows.mjs.map +1 -0
- package/dist/orm/runtime/utils.cjs +27 -0
- package/dist/orm/runtime/utils.mjs +27 -0
- package/dist/orm/runtime/utils.mjs.map +1 -0
- package/dist/orm/sql/parse-array.cjs +64 -0
- package/dist/orm/sql/parse-array.mjs +66 -0
- package/dist/orm/sql/parse-array.mjs.map +1 -0
- package/dist/orm/sql/plan/select.cjs +36 -0
- package/dist/orm/sql/plan/select.mjs +38 -0
- package/dist/orm/sql/plan/select.mjs.map +1 -0
- package/dist/orm/sql/plan/where/operators.cjs +95 -0
- package/dist/orm/sql/plan/where/operators.mjs +97 -0
- package/dist/orm/sql/plan/where/operators.mjs.map +1 -0
- package/dist/orm/sql/plan/where.cjs +59 -0
- package/dist/orm/sql/plan/where.mjs +61 -0
- package/dist/orm/sql/plan/where.mjs.map +1 -0
- package/dist/orm/sql/serialize/clauses.cjs +36 -0
- package/dist/orm/sql/serialize/clauses.mjs +37 -0
- package/dist/orm/sql/serialize/clauses.mjs.map +1 -0
- package/dist/orm/sql/serialize/joins.cjs +31 -0
- package/dist/orm/sql/serialize/joins.mjs +33 -0
- package/dist/orm/sql/serialize/joins.mjs.map +1 -0
- package/dist/orm/sql/serialize/values.cjs +30 -0
- package/dist/orm/sql/serialize/values.mjs +32 -0
- package/dist/orm/sql/serialize/values.mjs.map +1 -0
- package/dist/orm/sql/serialize/where/predicate.cjs +73 -0
- package/dist/orm/sql/serialize/where/predicate.mjs +75 -0
- package/dist/orm/sql/serialize/where/predicate.mjs.map +1 -0
- package/dist/orm/sql/serialize/where/tree.cjs +26 -0
- package/dist/orm/sql/serialize/where/tree.mjs +28 -0
- package/dist/orm/sql/serialize/where/tree.mjs.map +1 -0
- package/dist/orm/sql/serialize/where.cjs +10 -0
- package/dist/orm/sql/serialize/where.mjs +12 -0
- package/dist/orm/sql/serialize/where.mjs.map +1 -0
- package/dist/orm/sql/serialize.cjs +24 -0
- package/dist/orm/sql/serialize.mjs +25 -0
- package/dist/orm/sql/serialize.mjs.map +1 -0
- package/dist/orm/table.cjs +12 -0
- package/dist/orm/table.d.cts +12 -0
- package/dist/orm/table.d.cts.map +1 -0
- package/dist/orm/table.d.mts +12 -0
- package/dist/orm/table.d.mts.map +1 -0
- package/dist/orm/table.mjs +14 -0
- package/dist/orm/table.mjs.map +1 -0
- package/dist/orm/types.d.cts +183 -0
- package/dist/orm/types.d.cts.map +1 -0
- package/dist/orm/types.d.mts +183 -0
- package/dist/orm/types.d.mts.map +1 -0
- package/dist/workflow/types.d.cts +83 -0
- package/dist/workflow/types.d.cts.map +1 -0
- package/dist/workflow/types.d.mts +83 -0
- package/dist/workflow/types.d.mts.map +1 -0
- package/package.json +29 -3
- package/dist/cron/scanner.mjs.map +0 -1
- package/dist/cron/types.d.cts.map +0 -1
- package/dist/cron/types.d.mts.map +0 -1
- package/dist/lib/cron/index.d.cts.map +0 -1
- package/dist/lib/cron/index.d.mts.map +0 -1
- package/dist/lib/cron/index.mjs.map +0 -1
package/README.md
CHANGED
|
@@ -18,18 +18,20 @@ Type-safe APIs, Redis queues, pub/sub, i18n, caching & auth with tree-shakeable
|
|
|
18
18
|
|
|
19
19
|
## ✨ Features
|
|
20
20
|
|
|
21
|
-
| Module | Description | Import
|
|
22
|
-
| -------------------- | ------------------------------------------------------ |
|
|
23
|
-
| **🚀 API Framework** | Type-safe REST API with OpenAPI & Bun-native routing | `semola/api`
|
|
24
|
-
| **📬 Queue** | Redis-backed job queue with timeouts & concurrency | `semola/queue`
|
|
25
|
-
| **📡 PubSub** | Type-safe Redis pub/sub for real-time messaging | `semola/pubsub`
|
|
26
|
-
| **🔐 Policy** | Policy-based authorization with type-safe guards | `semola/policy`
|
|
27
|
-
| **🌍 i18n** | Compile-time validated internationalization | `semola/i18n`
|
|
28
|
-
| **💾 Cache** | Redis cache wrapper with TTL & automatic serialization | `semola/cache`
|
|
29
|
-
| **⏰ Cron** | In-memory cron scheduler for periodic task execution | `semola/cron`
|
|
30
|
-
|
|
|
31
|
-
|
|
|
32
|
-
|
|
|
21
|
+
| Module | Description | Import |
|
|
22
|
+
| -------------------- | ------------------------------------------------------ | ----------------- |
|
|
23
|
+
| **🚀 API Framework** | Type-safe REST API with OpenAPI & Bun-native routing | `semola/api` |
|
|
24
|
+
| **📬 Queue** | Redis-backed job queue with timeouts & concurrency | `semola/queue` |
|
|
25
|
+
| **📡 PubSub** | Type-safe Redis pub/sub for real-time messaging | `semola/pubsub` |
|
|
26
|
+
| **🔐 Policy** | Policy-based authorization with type-safe guards | `semola/policy` |
|
|
27
|
+
| **🌍 i18n** | Compile-time validated internationalization | `semola/i18n` |
|
|
28
|
+
| **💾 Cache** | Redis cache wrapper with TTL & automatic serialization | `semola/cache` |
|
|
29
|
+
| **⏰ Cron** | In-memory cron scheduler for periodic task execution | `semola/cron` |
|
|
30
|
+
| **🔁 Workflow** | Durable resumable workflows with step persistence | `semola/workflow` |
|
|
31
|
+
| **⚠️ Errors** | Result-based error handling without try/catch | `semola/errors` |
|
|
32
|
+
| **📃 Logging** | A simple logging utility | `semola/logging` |
|
|
33
|
+
| **⌨️ Prompts** | Interactive zero-dependency CLI prompts | `semola/prompts` |
|
|
34
|
+
| **🗄️ ORM** | Type-safe data layer with query APIs + migrations | `semola/orm` |
|
|
33
35
|
|
|
34
36
|
---
|
|
35
37
|
|
|
@@ -84,6 +86,14 @@ if (error) {
|
|
|
84
86
|
console.log("Success:", data);
|
|
85
87
|
```
|
|
86
88
|
|
|
89
|
+
`mightThrow` and `mightThrowSync` default their error type to `Error`. If a promise or function can reject or throw non-Error values, pass a custom error generic.
|
|
90
|
+
|
|
91
|
+
```typescript
|
|
92
|
+
const [customError] = await mightThrow<never, { code: string }>(
|
|
93
|
+
Promise.reject({ code: "RATE_LIMITED" }),
|
|
94
|
+
);
|
|
95
|
+
```
|
|
96
|
+
|
|
87
97
|
### Process Background Jobs
|
|
88
98
|
|
|
89
99
|
```typescript
|
|
@@ -112,12 +122,16 @@ const pubsub = new PubSub({
|
|
|
112
122
|
});
|
|
113
123
|
|
|
114
124
|
// Subscribe to messages
|
|
115
|
-
await pubsub.subscribe((message) => {
|
|
125
|
+
const [, unsubscribeHandler] = await pubsub.subscribe((message) => {
|
|
116
126
|
console.log("Received:", message);
|
|
117
127
|
});
|
|
118
128
|
|
|
119
129
|
// Publish a message
|
|
120
130
|
await pubsub.publish({ userId: 123, text: "New alert!" });
|
|
131
|
+
|
|
132
|
+
if (unsubscribeHandler) {
|
|
133
|
+
await unsubscribeHandler();
|
|
134
|
+
}
|
|
121
135
|
```
|
|
122
136
|
|
|
123
137
|
### Cache Data with TTL
|
|
@@ -155,6 +169,65 @@ const cleanup = new Cron({
|
|
|
155
169
|
cleanup.start();
|
|
156
170
|
```
|
|
157
171
|
|
|
172
|
+
### Query a Database
|
|
173
|
+
|
|
174
|
+
```typescript
|
|
175
|
+
import { createOrm, createTable, string, uuid } from "semola/orm";
|
|
176
|
+
|
|
177
|
+
const users = createTable("users", {
|
|
178
|
+
id: uuid("id").primaryKey(),
|
|
179
|
+
name: string("name").notNull(),
|
|
180
|
+
email: string("email").unique().notNull(),
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
const db = createOrm({
|
|
184
|
+
url: "sqlite::memory:",
|
|
185
|
+
tables: { users },
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
// Result-pattern query
|
|
189
|
+
const [findErr, rows] = await db.users.findMany({
|
|
190
|
+
where: { name: { contains: "John" } },
|
|
191
|
+
take: 10,
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
if (findErr) {
|
|
195
|
+
console.error(findErr.type, findErr.message);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// Create record (result pattern)
|
|
199
|
+
const [createErr, user] = await db.users.create({
|
|
200
|
+
data: {
|
|
201
|
+
name: "John Doe",
|
|
202
|
+
email: "john@example.com",
|
|
203
|
+
},
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
// Low-level SQL-style methods are also available
|
|
207
|
+
const insertedRows = await db.users.insert({
|
|
208
|
+
data: {
|
|
209
|
+
name: "Jane Doe",
|
|
210
|
+
email: "jane@example.com",
|
|
211
|
+
},
|
|
212
|
+
returning: true,
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
console.log(rows, user, createErr, insertedRows);
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
### Run ORM Migrations
|
|
219
|
+
|
|
220
|
+
```bash
|
|
221
|
+
# create migration from schema diff
|
|
222
|
+
semola orm migrations create add-users
|
|
223
|
+
|
|
224
|
+
# apply pending migrations
|
|
225
|
+
semola orm migrations apply
|
|
226
|
+
|
|
227
|
+
# rollback last applied migration
|
|
228
|
+
semola orm migrations rollback
|
|
229
|
+
```
|
|
230
|
+
|
|
158
231
|
### Check Permissions
|
|
159
232
|
|
|
160
233
|
```typescript
|
|
@@ -272,12 +345,14 @@ _Higher is better for req/sec, lower is better for latency._
|
|
|
272
345
|
- [Queue](./docs/queue.md) - Redis-backed job queue with timeouts & concurrency
|
|
273
346
|
- [PubSub](./docs/pubsub.md) - Type-safe Redis pub/sub
|
|
274
347
|
- [Cron](./docs/cron.md) - In-memory cron scheduler for periodic task execution
|
|
348
|
+
- [Workflow](./docs/workflow.md) - Durable and resumable workflows with step persistence
|
|
275
349
|
- [Policy](./docs/policy.md) - Policy-based authorization
|
|
276
350
|
- [i18n](./docs/i18n.md) - Type-safe internationalization
|
|
277
351
|
- [Cache](./docs/cache.md) - Redis cache wrapper with TTL
|
|
278
352
|
- [Errors](./docs/errors.md) - Result-based error handling
|
|
279
353
|
- [Logging](./docs/logging.md) - Logging utility
|
|
280
354
|
- [Prompts](./docs/prompts.md) - Interactive CLI prompts
|
|
355
|
+
- [ORM](./docs/orm.md) - Type-safe data layer, result-pattern DX, and migrations
|
|
281
356
|
|
|
282
357
|
---
|
|
283
358
|
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
//#region src/lib/cron/builder/index.ts
|
|
2
|
+
const CRON_FIELD_ORDER = [
|
|
3
|
+
"second",
|
|
4
|
+
"minute",
|
|
5
|
+
"hour",
|
|
6
|
+
"day",
|
|
7
|
+
"month",
|
|
8
|
+
"weekday"
|
|
9
|
+
];
|
|
10
|
+
var FieldWrapper = class {
|
|
11
|
+
fields = [];
|
|
12
|
+
add(expr) {
|
|
13
|
+
this.fields.push(expr);
|
|
14
|
+
}
|
|
15
|
+
read() {
|
|
16
|
+
return this.fields;
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
var CronListBuilder = class {
|
|
20
|
+
wrapper;
|
|
21
|
+
constructor(wrapper) {
|
|
22
|
+
this.wrapper = wrapper;
|
|
23
|
+
}
|
|
24
|
+
any() {
|
|
25
|
+
this.wrapper.add({ type: "any" });
|
|
26
|
+
return this;
|
|
27
|
+
}
|
|
28
|
+
range(options) {
|
|
29
|
+
this.wrapper.add({
|
|
30
|
+
type: "range",
|
|
31
|
+
...options
|
|
32
|
+
});
|
|
33
|
+
return this;
|
|
34
|
+
}
|
|
35
|
+
step(options) {
|
|
36
|
+
this.wrapper.add({
|
|
37
|
+
type: "step",
|
|
38
|
+
...options
|
|
39
|
+
});
|
|
40
|
+
return this;
|
|
41
|
+
}
|
|
42
|
+
number(value) {
|
|
43
|
+
this.wrapper.add({
|
|
44
|
+
type: "value",
|
|
45
|
+
value
|
|
46
|
+
});
|
|
47
|
+
return this;
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
function range(options) {
|
|
51
|
+
return {
|
|
52
|
+
type: "range",
|
|
53
|
+
...options
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
function any() {
|
|
57
|
+
return { type: "any" };
|
|
58
|
+
}
|
|
59
|
+
function step(options) {
|
|
60
|
+
return {
|
|
61
|
+
type: "step",
|
|
62
|
+
...options
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
function list(builderFn) {
|
|
66
|
+
const wrapper = new FieldWrapper();
|
|
67
|
+
builderFn(new CronListBuilder(wrapper));
|
|
68
|
+
return {
|
|
69
|
+
type: "list",
|
|
70
|
+
values: wrapper.read()
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
function number(value) {
|
|
74
|
+
return {
|
|
75
|
+
type: "value",
|
|
76
|
+
value
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
function cronJobBuilder(buildFn) {
|
|
80
|
+
const fields = {
|
|
81
|
+
second: void 0,
|
|
82
|
+
minute: void 0,
|
|
83
|
+
hour: void 0,
|
|
84
|
+
day: void 0,
|
|
85
|
+
month: void 0,
|
|
86
|
+
weekday: void 0
|
|
87
|
+
};
|
|
88
|
+
const obj = {
|
|
89
|
+
second(expr) {
|
|
90
|
+
fields.second = checkExpr(expr);
|
|
91
|
+
return obj;
|
|
92
|
+
},
|
|
93
|
+
minute(expr) {
|
|
94
|
+
fields.minute = checkExpr(expr);
|
|
95
|
+
return obj;
|
|
96
|
+
},
|
|
97
|
+
hour(expr) {
|
|
98
|
+
fields.hour = checkExpr(expr);
|
|
99
|
+
return obj;
|
|
100
|
+
},
|
|
101
|
+
day(expr) {
|
|
102
|
+
fields.day = checkExpr(expr);
|
|
103
|
+
return obj;
|
|
104
|
+
},
|
|
105
|
+
month(expr) {
|
|
106
|
+
fields.month = checkExpr(expr);
|
|
107
|
+
return obj;
|
|
108
|
+
},
|
|
109
|
+
weekday(expr) {
|
|
110
|
+
fields.weekday = checkExpr(expr);
|
|
111
|
+
return obj;
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
buildFn(obj);
|
|
115
|
+
return generate(fields);
|
|
116
|
+
}
|
|
117
|
+
function checkExpr(expr) {
|
|
118
|
+
if (expr.type === "list") {
|
|
119
|
+
const { values } = expr;
|
|
120
|
+
if (values.length === 0) throw new Error("EmptyListError: List expression cannot be empty");
|
|
121
|
+
return values.map((e) => handleSimpleExpression(e)).join(",");
|
|
122
|
+
}
|
|
123
|
+
return handleSimpleExpression(expr);
|
|
124
|
+
}
|
|
125
|
+
function handleSimpleExpression(expr) {
|
|
126
|
+
switch (expr.type) {
|
|
127
|
+
case "any": return "*";
|
|
128
|
+
case "value": return `${expr.value}`;
|
|
129
|
+
case "range": {
|
|
130
|
+
const { min, max } = expr;
|
|
131
|
+
if (min > max) throw new Error(`OutOfBoundError: Expected ${min} <= ${max}`);
|
|
132
|
+
return `${min}-${max}`;
|
|
133
|
+
}
|
|
134
|
+
case "step": {
|
|
135
|
+
const { step, range } = expr;
|
|
136
|
+
if (step === 0) throw new Error(`OutOfBoundError: Expected step value greater than zero`);
|
|
137
|
+
if (!range) return `*/${step}`;
|
|
138
|
+
const { min, max } = range;
|
|
139
|
+
if (max === 0) {
|
|
140
|
+
if (min > max) throw new Error(`OutOfBoundError: Expected max value greater than zero`);
|
|
141
|
+
return `${min}-${max}/${step}`;
|
|
142
|
+
}
|
|
143
|
+
if (!max) return `${min}/${step}`;
|
|
144
|
+
if (min > max) throw new Error(`OutOfBoundError: Expected ${min} <= ${max}`);
|
|
145
|
+
return `${min}-${max}/${step}`;
|
|
146
|
+
}
|
|
147
|
+
default: return "*";
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
function generate(fields) {
|
|
151
|
+
const parts = [];
|
|
152
|
+
for (let index = 0; index < CRON_FIELD_ORDER.length; index++) {
|
|
153
|
+
const key = CRON_FIELD_ORDER[index];
|
|
154
|
+
if (!key) return "";
|
|
155
|
+
if (key === "second" && !fields[key]) continue;
|
|
156
|
+
parts.push(fields[key] ?? "*");
|
|
157
|
+
}
|
|
158
|
+
return parts.join(" ");
|
|
159
|
+
}
|
|
160
|
+
//#endregion
|
|
161
|
+
exports.any = any;
|
|
162
|
+
exports.cronJobBuilder = cronJobBuilder;
|
|
163
|
+
exports.list = list;
|
|
164
|
+
exports.number = number;
|
|
165
|
+
exports.range = range;
|
|
166
|
+
exports.step = step;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { BuilderFn, CronExpr, CronListExpr, CronRange, CronStep } from "./types.cjs";
|
|
2
|
+
|
|
3
|
+
//#region src/lib/cron/builder/index.d.ts
|
|
4
|
+
declare class FieldWrapper<T> {
|
|
5
|
+
private fields;
|
|
6
|
+
add(expr: CronListExpr<T>): void;
|
|
7
|
+
read(): CronListExpr<T>[];
|
|
8
|
+
}
|
|
9
|
+
declare class CronListBuilder<T> {
|
|
10
|
+
private wrapper;
|
|
11
|
+
constructor(wrapper: FieldWrapper<T>);
|
|
12
|
+
any(): CronListBuilder<T>;
|
|
13
|
+
range(options: CronRange<T>): CronListBuilder<T>;
|
|
14
|
+
step(options: CronStep<T>): CronListBuilder<T>;
|
|
15
|
+
number(value: T): CronListBuilder<T>;
|
|
16
|
+
}
|
|
17
|
+
declare function range<T>(options: CronRange<T>): CronExpr<T>;
|
|
18
|
+
declare function any<T>(): CronExpr<T>;
|
|
19
|
+
declare function step<T>(options: CronStep<T>): CronExpr<T>;
|
|
20
|
+
declare function list<T>(builderFn: (builder: CronListBuilder<T>) => CronListBuilder<T>): CronExpr<T>;
|
|
21
|
+
declare function number<T>(value: T): {
|
|
22
|
+
type: "value";
|
|
23
|
+
value: T;
|
|
24
|
+
};
|
|
25
|
+
declare function cronJobBuilder(buildFn: BuilderFn): string;
|
|
26
|
+
//#endregion
|
|
27
|
+
export { any, cronJobBuilder, list, number, range, step };
|
|
28
|
+
//# sourceMappingURL=index.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.cts","names":[],"sources":["../../../src/lib/cron/builder/index.ts"],"mappings":";;;cAwBM,YAAA;EAAA,QACI,MAAA;EAED,GAAA,CAAI,IAAA,EAAM,YAAA,CAAa,CAAA;EAIvB,IAAA,CAAA,GAAI,YAAA,CAAA,CAAA;AAAA;AAAA,cAKP,eAAA;EAAA,QACI,OAAA;cAEW,OAAA,EAAS,YAAA,CAAa,CAAA;EAIlC,GAAA,CAAA,GAAO,eAAA,CAAgB,CAAA;EAKvB,KAAA,CAAM,OAAA,EAAS,SAAA,CAAU,CAAA,IAAK,eAAA,CAAgB,CAAA;EAK9C,IAAA,CAAK,OAAA,EAAS,QAAA,CAAS,CAAA,IAAK,eAAA,CAAgB,CAAA;EAK5C,MAAA,CAAO,KAAA,EAAO,CAAA,GAAI,eAAA,CAAgB,CAAA;AAAA;AAAA,iBAM3B,KAAA,GAAA,CAAS,OAAA,EAAS,SAAA,CAAU,CAAA,IAAK,QAAA,CAAS,CAAA;AAAA,iBAI1C,GAAA,GAAA,CAAA,GAAU,QAAA,CAAS,CAAA;AAAA,iBAInB,IAAA,GAAA,CAAQ,OAAA,EAAS,QAAA,CAAS,CAAA,IAAK,QAAA,CAAS,CAAA;AAAA,iBAIxC,IAAA,GAAA,CACd,SAAA,GAAY,OAAA,EAAS,eAAA,CAAgB,CAAA,MAAO,eAAA,CAAgB,CAAA,IAC3D,QAAA,CAAS,CAAA;AAAA,iBAOI,MAAA,GAAA,CAAU,KAAA,EAAO,CAAA;;SAAA,CAAA;AAAA;AAAA,iBAIjB,cAAA,CAAe,OAAA,EAAS,SAAA"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { BuilderFn, CronExpr, CronListExpr, CronRange, CronStep } from "./types.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/lib/cron/builder/index.d.ts
|
|
4
|
+
declare class FieldWrapper<T> {
|
|
5
|
+
private fields;
|
|
6
|
+
add(expr: CronListExpr<T>): void;
|
|
7
|
+
read(): CronListExpr<T>[];
|
|
8
|
+
}
|
|
9
|
+
declare class CronListBuilder<T> {
|
|
10
|
+
private wrapper;
|
|
11
|
+
constructor(wrapper: FieldWrapper<T>);
|
|
12
|
+
any(): CronListBuilder<T>;
|
|
13
|
+
range(options: CronRange<T>): CronListBuilder<T>;
|
|
14
|
+
step(options: CronStep<T>): CronListBuilder<T>;
|
|
15
|
+
number(value: T): CronListBuilder<T>;
|
|
16
|
+
}
|
|
17
|
+
declare function range<T>(options: CronRange<T>): CronExpr<T>;
|
|
18
|
+
declare function any<T>(): CronExpr<T>;
|
|
19
|
+
declare function step<T>(options: CronStep<T>): CronExpr<T>;
|
|
20
|
+
declare function list<T>(builderFn: (builder: CronListBuilder<T>) => CronListBuilder<T>): CronExpr<T>;
|
|
21
|
+
declare function number<T>(value: T): {
|
|
22
|
+
type: "value";
|
|
23
|
+
value: T;
|
|
24
|
+
};
|
|
25
|
+
declare function cronJobBuilder(buildFn: BuilderFn): string;
|
|
26
|
+
//#endregion
|
|
27
|
+
export { any, cronJobBuilder, list, number, range, step };
|
|
28
|
+
//# sourceMappingURL=index.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../../../src/lib/cron/builder/index.ts"],"mappings":";;;cAwBM,YAAA;EAAA,QACI,MAAA;EAED,GAAA,CAAI,IAAA,EAAM,YAAA,CAAa,CAAA;EAIvB,IAAA,CAAA,GAAI,YAAA,CAAA,CAAA;AAAA;AAAA,cAKP,eAAA;EAAA,QACI,OAAA;cAEW,OAAA,EAAS,YAAA,CAAa,CAAA;EAIlC,GAAA,CAAA,GAAO,eAAA,CAAgB,CAAA;EAKvB,KAAA,CAAM,OAAA,EAAS,SAAA,CAAU,CAAA,IAAK,eAAA,CAAgB,CAAA;EAK9C,IAAA,CAAK,OAAA,EAAS,QAAA,CAAS,CAAA,IAAK,eAAA,CAAgB,CAAA;EAK5C,MAAA,CAAO,KAAA,EAAO,CAAA,GAAI,eAAA,CAAgB,CAAA;AAAA;AAAA,iBAM3B,KAAA,GAAA,CAAS,OAAA,EAAS,SAAA,CAAU,CAAA,IAAK,QAAA,CAAS,CAAA;AAAA,iBAI1C,GAAA,GAAA,CAAA,GAAU,QAAA,CAAS,CAAA;AAAA,iBAInB,IAAA,GAAA,CAAQ,OAAA,EAAS,QAAA,CAAS,CAAA,IAAK,QAAA,CAAS,CAAA;AAAA,iBAIxC,IAAA,GAAA,CACd,SAAA,GAAY,OAAA,EAAS,eAAA,CAAgB,CAAA,MAAO,eAAA,CAAgB,CAAA,IAC3D,QAAA,CAAS,CAAA;AAAA,iBAOI,MAAA,GAAA,CAAU,KAAA,EAAO,CAAA;;SAAA,CAAA;AAAA;AAAA,iBAIjB,cAAA,CAAe,OAAA,EAAS,SAAA"}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
//#region src/lib/cron/builder/index.ts
|
|
2
|
+
const CRON_FIELD_ORDER = [
|
|
3
|
+
"second",
|
|
4
|
+
"minute",
|
|
5
|
+
"hour",
|
|
6
|
+
"day",
|
|
7
|
+
"month",
|
|
8
|
+
"weekday"
|
|
9
|
+
];
|
|
10
|
+
var FieldWrapper = class {
|
|
11
|
+
fields = [];
|
|
12
|
+
add(expr) {
|
|
13
|
+
this.fields.push(expr);
|
|
14
|
+
}
|
|
15
|
+
read() {
|
|
16
|
+
return this.fields;
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
var CronListBuilder = class {
|
|
20
|
+
wrapper;
|
|
21
|
+
constructor(wrapper) {
|
|
22
|
+
this.wrapper = wrapper;
|
|
23
|
+
}
|
|
24
|
+
any() {
|
|
25
|
+
this.wrapper.add({ type: "any" });
|
|
26
|
+
return this;
|
|
27
|
+
}
|
|
28
|
+
range(options) {
|
|
29
|
+
this.wrapper.add({
|
|
30
|
+
type: "range",
|
|
31
|
+
...options
|
|
32
|
+
});
|
|
33
|
+
return this;
|
|
34
|
+
}
|
|
35
|
+
step(options) {
|
|
36
|
+
this.wrapper.add({
|
|
37
|
+
type: "step",
|
|
38
|
+
...options
|
|
39
|
+
});
|
|
40
|
+
return this;
|
|
41
|
+
}
|
|
42
|
+
number(value) {
|
|
43
|
+
this.wrapper.add({
|
|
44
|
+
type: "value",
|
|
45
|
+
value
|
|
46
|
+
});
|
|
47
|
+
return this;
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
function range(options) {
|
|
51
|
+
return {
|
|
52
|
+
type: "range",
|
|
53
|
+
...options
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
function any() {
|
|
57
|
+
return { type: "any" };
|
|
58
|
+
}
|
|
59
|
+
function step(options) {
|
|
60
|
+
return {
|
|
61
|
+
type: "step",
|
|
62
|
+
...options
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
function list(builderFn) {
|
|
66
|
+
const wrapper = new FieldWrapper();
|
|
67
|
+
builderFn(new CronListBuilder(wrapper));
|
|
68
|
+
return {
|
|
69
|
+
type: "list",
|
|
70
|
+
values: wrapper.read()
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
function number(value) {
|
|
74
|
+
return {
|
|
75
|
+
type: "value",
|
|
76
|
+
value
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
function cronJobBuilder(buildFn) {
|
|
80
|
+
const fields = {
|
|
81
|
+
second: void 0,
|
|
82
|
+
minute: void 0,
|
|
83
|
+
hour: void 0,
|
|
84
|
+
day: void 0,
|
|
85
|
+
month: void 0,
|
|
86
|
+
weekday: void 0
|
|
87
|
+
};
|
|
88
|
+
const obj = {
|
|
89
|
+
second(expr) {
|
|
90
|
+
fields.second = checkExpr(expr);
|
|
91
|
+
return obj;
|
|
92
|
+
},
|
|
93
|
+
minute(expr) {
|
|
94
|
+
fields.minute = checkExpr(expr);
|
|
95
|
+
return obj;
|
|
96
|
+
},
|
|
97
|
+
hour(expr) {
|
|
98
|
+
fields.hour = checkExpr(expr);
|
|
99
|
+
return obj;
|
|
100
|
+
},
|
|
101
|
+
day(expr) {
|
|
102
|
+
fields.day = checkExpr(expr);
|
|
103
|
+
return obj;
|
|
104
|
+
},
|
|
105
|
+
month(expr) {
|
|
106
|
+
fields.month = checkExpr(expr);
|
|
107
|
+
return obj;
|
|
108
|
+
},
|
|
109
|
+
weekday(expr) {
|
|
110
|
+
fields.weekday = checkExpr(expr);
|
|
111
|
+
return obj;
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
buildFn(obj);
|
|
115
|
+
return generate(fields);
|
|
116
|
+
}
|
|
117
|
+
function checkExpr(expr) {
|
|
118
|
+
if (expr.type === "list") {
|
|
119
|
+
const { values } = expr;
|
|
120
|
+
if (values.length === 0) throw new Error("EmptyListError: List expression cannot be empty");
|
|
121
|
+
return values.map((e) => handleSimpleExpression(e)).join(",");
|
|
122
|
+
}
|
|
123
|
+
return handleSimpleExpression(expr);
|
|
124
|
+
}
|
|
125
|
+
function handleSimpleExpression(expr) {
|
|
126
|
+
switch (expr.type) {
|
|
127
|
+
case "any": return "*";
|
|
128
|
+
case "value": return `${expr.value}`;
|
|
129
|
+
case "range": {
|
|
130
|
+
const { min, max } = expr;
|
|
131
|
+
if (min > max) throw new Error(`OutOfBoundError: Expected ${min} <= ${max}`);
|
|
132
|
+
return `${min}-${max}`;
|
|
133
|
+
}
|
|
134
|
+
case "step": {
|
|
135
|
+
const { step, range } = expr;
|
|
136
|
+
if (step === 0) throw new Error(`OutOfBoundError: Expected step value greater than zero`);
|
|
137
|
+
if (!range) return `*/${step}`;
|
|
138
|
+
const { min, max } = range;
|
|
139
|
+
if (max === 0) {
|
|
140
|
+
if (min > max) throw new Error(`OutOfBoundError: Expected max value greater than zero`);
|
|
141
|
+
return `${min}-${max}/${step}`;
|
|
142
|
+
}
|
|
143
|
+
if (!max) return `${min}/${step}`;
|
|
144
|
+
if (min > max) throw new Error(`OutOfBoundError: Expected ${min} <= ${max}`);
|
|
145
|
+
return `${min}-${max}/${step}`;
|
|
146
|
+
}
|
|
147
|
+
default: return "*";
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
function generate(fields) {
|
|
151
|
+
const parts = [];
|
|
152
|
+
for (let index = 0; index < CRON_FIELD_ORDER.length; index++) {
|
|
153
|
+
const key = CRON_FIELD_ORDER[index];
|
|
154
|
+
if (!key) return "";
|
|
155
|
+
if (key === "second" && !fields[key]) continue;
|
|
156
|
+
parts.push(fields[key] ?? "*");
|
|
157
|
+
}
|
|
158
|
+
return parts.join(" ");
|
|
159
|
+
}
|
|
160
|
+
//#endregion
|
|
161
|
+
export { any, cronJobBuilder, list, number, range, step };
|
|
162
|
+
|
|
163
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../../src/lib/cron/builder/index.ts"],"sourcesContent":["import type {\n BuilderFn,\n CronBuilderType,\n CronExpr,\n CronField,\n CronListExpr,\n CronRange,\n CronStep,\n DayType,\n HourType,\n MonthType,\n TimeType,\n WeekDayType,\n} from \"./types.js\";\n\nconst CRON_FIELD_ORDER: CronField[] = [\n \"second\",\n \"minute\",\n \"hour\",\n \"day\",\n \"month\",\n \"weekday\",\n] as const;\n\nclass FieldWrapper<T> {\n private fields: CronListExpr<T>[] = [];\n\n public add(expr: CronListExpr<T>) {\n this.fields.push(expr);\n }\n\n public read() {\n return this.fields;\n }\n}\n\nclass CronListBuilder<T> {\n private wrapper: FieldWrapper<T>;\n\n public constructor(wrapper: FieldWrapper<T>) {\n this.wrapper = wrapper;\n }\n\n public any(): CronListBuilder<T> {\n this.wrapper.add({ type: \"any\" });\n return this;\n }\n\n public range(options: CronRange<T>): CronListBuilder<T> {\n this.wrapper.add({ type: \"range\", ...options });\n return this;\n }\n\n public step(options: CronStep<T>): CronListBuilder<T> {\n this.wrapper.add({ type: \"step\", ...options });\n return this;\n }\n\n public number(value: T): CronListBuilder<T> {\n this.wrapper.add({ type: \"value\", value: value });\n return this;\n }\n}\n\nexport function range<T>(options: CronRange<T>): CronExpr<T> {\n return { type: \"range\", ...options };\n}\n\nexport function any<T>(): CronExpr<T> {\n return { type: \"any\" };\n}\n\nexport function step<T>(options: CronStep<T>): CronExpr<T> {\n return { type: \"step\", ...options };\n}\n\nexport function list<T>(\n builderFn: (builder: CronListBuilder<T>) => CronListBuilder<T>,\n): CronExpr<T> {\n const wrapper = new FieldWrapper<T>();\n builderFn(new CronListBuilder<T>(wrapper));\n\n return { type: \"list\", values: wrapper.read() };\n}\n\nexport function number<T>(value: T) {\n return { type: \"value\", value: value } satisfies CronExpr<T>;\n}\n\nexport function cronJobBuilder(buildFn: BuilderFn) {\n const fields: Partial<Record<CronField, string>> = {\n second: undefined,\n minute: undefined,\n hour: undefined,\n day: undefined,\n month: undefined,\n weekday: undefined,\n };\n\n const obj: CronBuilderType = {\n second(expr: CronExpr<TimeType>) {\n fields.second = checkExpr(expr);\n return obj;\n },\n minute(expr: CronExpr<TimeType>) {\n fields.minute = checkExpr(expr);\n return obj;\n },\n hour(expr: CronExpr<HourType>) {\n fields.hour = checkExpr(expr);\n return obj;\n },\n day(expr: CronExpr<DayType>) {\n fields.day = checkExpr(expr);\n return obj;\n },\n month(expr: CronExpr<MonthType>) {\n fields.month = checkExpr(expr);\n return obj;\n },\n weekday(expr: CronExpr<WeekDayType>) {\n fields.weekday = checkExpr(expr);\n return obj;\n },\n };\n\n buildFn(obj);\n return generate(fields);\n}\n\nfunction checkExpr<T>(expr: CronExpr<T>) {\n if (expr.type === \"list\") {\n const { values } = expr;\n if (values.length === 0) {\n throw new Error(\"EmptyListError: List expression cannot be empty\");\n }\n\n const data = values.map((e) => handleSimpleExpression(e));\n\n return data.join(\",\");\n }\n\n return handleSimpleExpression(expr);\n}\n\nfunction handleSimpleExpression<T>(expr: CronExpr<T>) {\n switch (expr.type) {\n case \"any\": {\n return \"*\";\n }\n\n case \"value\": {\n return `${expr.value}`;\n }\n\n case \"range\": {\n const { min, max } = expr;\n if (min > max) {\n throw new Error(`OutOfBoundError: Expected ${min} <= ${max}`);\n }\n\n return `${min}-${max}`;\n }\n\n case \"step\": {\n const { step, range } = expr;\n\n if (step === 0) {\n throw new Error(\n `OutOfBoundError: Expected step value greater than zero`,\n );\n }\n\n if (!range) {\n return `*/${step}`;\n }\n\n const { min, max } = range;\n\n if (max === 0) {\n if (min > max) {\n throw new Error(\n `OutOfBoundError: Expected max value greater than zero`,\n );\n }\n\n return `${min}-${max}/${step}`;\n }\n\n if (!max) {\n return `${min}/${step}`;\n }\n\n if (min > max) {\n throw new Error(`OutOfBoundError: Expected ${min} <= ${max}`);\n }\n\n return `${min}-${max}/${step}`;\n }\n\n default: {\n return \"*\";\n }\n }\n}\n\nfunction generate(fields: Partial<Record<CronField, string>>): string {\n const parts: string[] = [];\n\n for (let index = 0; index < CRON_FIELD_ORDER.length; index++) {\n const key = CRON_FIELD_ORDER[index];\n if (!key) return \"\";\n if (key === \"second\" && !fields[key]) {\n continue;\n }\n\n parts.push(fields[key] ?? \"*\");\n }\n\n return parts.join(\" \");\n}\n"],"mappings":";AAeA,MAAM,mBAAgC;CACpC;CACA;CACA;CACA;CACA;CACA;CACD;AAED,IAAM,eAAN,MAAsB;CACpB,SAAoC,EAAE;CAEtC,IAAW,MAAuB;AAChC,OAAK,OAAO,KAAK,KAAK;;CAGxB,OAAc;AACZ,SAAO,KAAK;;;AAIhB,IAAM,kBAAN,MAAyB;CACvB;CAEA,YAAmB,SAA0B;AAC3C,OAAK,UAAU;;CAGjB,MAAiC;AAC/B,OAAK,QAAQ,IAAI,EAAE,MAAM,OAAO,CAAC;AACjC,SAAO;;CAGT,MAAa,SAA2C;AACtD,OAAK,QAAQ,IAAI;GAAE,MAAM;GAAS,GAAG;GAAS,CAAC;AAC/C,SAAO;;CAGT,KAAY,SAA0C;AACpD,OAAK,QAAQ,IAAI;GAAE,MAAM;GAAQ,GAAG;GAAS,CAAC;AAC9C,SAAO;;CAGT,OAAc,OAA8B;AAC1C,OAAK,QAAQ,IAAI;GAAE,MAAM;GAAgB;GAAO,CAAC;AACjD,SAAO;;;AAIX,SAAgB,MAAS,SAAoC;AAC3D,QAAO;EAAE,MAAM;EAAS,GAAG;EAAS;;AAGtC,SAAgB,MAAsB;AACpC,QAAO,EAAE,MAAM,OAAO;;AAGxB,SAAgB,KAAQ,SAAmC;AACzD,QAAO;EAAE,MAAM;EAAQ,GAAG;EAAS;;AAGrC,SAAgB,KACd,WACa;CACb,MAAM,UAAU,IAAI,cAAiB;AACrC,WAAU,IAAI,gBAAmB,QAAQ,CAAC;AAE1C,QAAO;EAAE,MAAM;EAAQ,QAAQ,QAAQ,MAAM;EAAE;;AAGjD,SAAgB,OAAU,OAAU;AAClC,QAAO;EAAE,MAAM;EAAgB;EAAO;;AAGxC,SAAgB,eAAe,SAAoB;CACjD,MAAM,SAA6C;EACjD,QAAQ,KAAA;EACR,QAAQ,KAAA;EACR,MAAM,KAAA;EACN,KAAK,KAAA;EACL,OAAO,KAAA;EACP,SAAS,KAAA;EACV;CAED,MAAM,MAAuB;EAC3B,OAAO,MAA0B;AAC/B,UAAO,SAAS,UAAU,KAAK;AAC/B,UAAO;;EAET,OAAO,MAA0B;AAC/B,UAAO,SAAS,UAAU,KAAK;AAC/B,UAAO;;EAET,KAAK,MAA0B;AAC7B,UAAO,OAAO,UAAU,KAAK;AAC7B,UAAO;;EAET,IAAI,MAAyB;AAC3B,UAAO,MAAM,UAAU,KAAK;AAC5B,UAAO;;EAET,MAAM,MAA2B;AAC/B,UAAO,QAAQ,UAAU,KAAK;AAC9B,UAAO;;EAET,QAAQ,MAA6B;AACnC,UAAO,UAAU,UAAU,KAAK;AAChC,UAAO;;EAEV;AAED,SAAQ,IAAI;AACZ,QAAO,SAAS,OAAO;;AAGzB,SAAS,UAAa,MAAmB;AACvC,KAAI,KAAK,SAAS,QAAQ;EACxB,MAAM,EAAE,WAAW;AACnB,MAAI,OAAO,WAAW,EACpB,OAAM,IAAI,MAAM,kDAAkD;AAKpE,SAFa,OAAO,KAAK,MAAM,uBAAuB,EAAE,CAAC,CAE7C,KAAK,IAAI;;AAGvB,QAAO,uBAAuB,KAAK;;AAGrC,SAAS,uBAA0B,MAAmB;AACpD,SAAQ,KAAK,MAAb;EACE,KAAK,MACH,QAAO;EAGT,KAAK,QACH,QAAO,GAAG,KAAK;EAGjB,KAAK,SAAS;GACZ,MAAM,EAAE,KAAK,QAAQ;AACrB,OAAI,MAAM,IACR,OAAM,IAAI,MAAM,6BAA6B,IAAI,MAAM,MAAM;AAG/D,UAAO,GAAG,IAAI,GAAG;;EAGnB,KAAK,QAAQ;GACX,MAAM,EAAE,MAAM,UAAU;AAExB,OAAI,SAAS,EACX,OAAM,IAAI,MACR,yDACD;AAGH,OAAI,CAAC,MACH,QAAO,KAAK;GAGd,MAAM,EAAE,KAAK,QAAQ;AAErB,OAAI,QAAQ,GAAG;AACb,QAAI,MAAM,IACR,OAAM,IAAI,MACR,wDACD;AAGH,WAAO,GAAG,IAAI,GAAG,IAAI,GAAG;;AAG1B,OAAI,CAAC,IACH,QAAO,GAAG,IAAI,GAAG;AAGnB,OAAI,MAAM,IACR,OAAM,IAAI,MAAM,6BAA6B,IAAI,MAAM,MAAM;AAG/D,UAAO,GAAG,IAAI,GAAG,IAAI,GAAG;;EAG1B,QACE,QAAO;;;AAKb,SAAS,SAAS,QAAoD;CACpE,MAAM,QAAkB,EAAE;AAE1B,MAAK,IAAI,QAAQ,GAAG,QAAQ,iBAAiB,QAAQ,SAAS;EAC5D,MAAM,MAAM,iBAAiB;AAC7B,MAAI,CAAC,IAAK,QAAO;AACjB,MAAI,QAAQ,YAAY,CAAC,OAAO,KAC9B;AAGF,QAAM,KAAK,OAAO,QAAQ,IAAI;;AAGhC,QAAO,MAAM,KAAK,IAAI"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
//#region src/lib/cron/builder/types.ts
|
|
2
|
+
const WeekDay = {
|
|
3
|
+
sun: 0,
|
|
4
|
+
mon: 1,
|
|
5
|
+
tue: 2,
|
|
6
|
+
wed: 3,
|
|
7
|
+
thu: 4,
|
|
8
|
+
fri: 5,
|
|
9
|
+
sat: 6
|
|
10
|
+
};
|
|
11
|
+
const Month = {
|
|
12
|
+
jan: 1,
|
|
13
|
+
feb: 2,
|
|
14
|
+
mar: 3,
|
|
15
|
+
apr: 4,
|
|
16
|
+
may: 5,
|
|
17
|
+
jun: 6,
|
|
18
|
+
jul: 7,
|
|
19
|
+
aug: 8,
|
|
20
|
+
sep: 9,
|
|
21
|
+
oct: 10,
|
|
22
|
+
nov: 11,
|
|
23
|
+
dec: 12
|
|
24
|
+
};
|
|
25
|
+
//#endregion
|
|
26
|
+
exports.Month = Month;
|
|
27
|
+
exports.WeekDay = WeekDay;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
//#region src/lib/cron/builder/types.d.ts
|
|
2
|
+
declare const WeekDay: {
|
|
3
|
+
readonly sun: 0;
|
|
4
|
+
readonly mon: 1;
|
|
5
|
+
readonly tue: 2;
|
|
6
|
+
readonly wed: 3;
|
|
7
|
+
readonly thu: 4;
|
|
8
|
+
readonly fri: 5;
|
|
9
|
+
readonly sat: 6;
|
|
10
|
+
};
|
|
11
|
+
declare const Month: {
|
|
12
|
+
readonly jan: 1;
|
|
13
|
+
readonly feb: 2;
|
|
14
|
+
readonly mar: 3;
|
|
15
|
+
readonly apr: 4;
|
|
16
|
+
readonly may: 5;
|
|
17
|
+
readonly jun: 6;
|
|
18
|
+
readonly jul: 7;
|
|
19
|
+
readonly aug: 8;
|
|
20
|
+
readonly sep: 9;
|
|
21
|
+
readonly oct: 10;
|
|
22
|
+
readonly nov: 11;
|
|
23
|
+
readonly dec: 12;
|
|
24
|
+
};
|
|
25
|
+
type Enumerate<N extends number, Acc extends number[] = []> = Acc["length"] extends N ? Acc[number] : Enumerate<N, [...Acc, Acc["length"]]>;
|
|
26
|
+
type IntRange<F extends number, T extends number> = Exclude<Enumerate<T>, Enumerate<F>>;
|
|
27
|
+
type TimeType = IntRange<0, 60>;
|
|
28
|
+
type HourType = IntRange<0, 24>;
|
|
29
|
+
type DayType = IntRange<1, 32>;
|
|
30
|
+
type MonthType = IntRange<1, 13>;
|
|
31
|
+
type WeekDayType = IntRange<0, 7>;
|
|
32
|
+
type CronRange<T> = {
|
|
33
|
+
min: NoInfer<T>;
|
|
34
|
+
max: NoInfer<T>;
|
|
35
|
+
};
|
|
36
|
+
type CronStep<T> = {
|
|
37
|
+
step: NoInfer<T>;
|
|
38
|
+
range?: {
|
|
39
|
+
min: NoInfer<T>;
|
|
40
|
+
max?: NoInfer<T>;
|
|
41
|
+
};
|
|
42
|
+
};
|
|
43
|
+
type CronField = "second" | "minute" | "hour" | "day" | "month" | "weekday";
|
|
44
|
+
type CronListExpr<T> = Exclude<CronExpr<T>, {
|
|
45
|
+
type: "list";
|
|
46
|
+
}>;
|
|
47
|
+
type CronExpr<T> = {
|
|
48
|
+
type: "any";
|
|
49
|
+
} | {
|
|
50
|
+
type: "value";
|
|
51
|
+
value: T;
|
|
52
|
+
} | {
|
|
53
|
+
type: "range";
|
|
54
|
+
min: T;
|
|
55
|
+
max: T;
|
|
56
|
+
} | {
|
|
57
|
+
type: "step";
|
|
58
|
+
step: T;
|
|
59
|
+
range?: {
|
|
60
|
+
min: T;
|
|
61
|
+
max?: T;
|
|
62
|
+
};
|
|
63
|
+
} | {
|
|
64
|
+
type: "list";
|
|
65
|
+
values: CronListExpr<T>[];
|
|
66
|
+
};
|
|
67
|
+
interface IBuilder<Used extends CronField> {
|
|
68
|
+
second(expr: CronExpr<TimeType>): CronBuilderType<Used | "second">;
|
|
69
|
+
minute(expr: CronExpr<TimeType>): CronBuilderType<Used | "minute">;
|
|
70
|
+
hour(expr: CronExpr<HourType>): CronBuilderType<Used | "hour">;
|
|
71
|
+
day(expr: CronExpr<DayType>): CronBuilderType<Used | "day">;
|
|
72
|
+
month(expr: CronExpr<MonthType>): CronBuilderType<Used | "month">;
|
|
73
|
+
weekday(expr: CronExpr<WeekDayType>): CronBuilderType<Used | "weekday">;
|
|
74
|
+
}
|
|
75
|
+
type CronBuilderType<Used extends CronField = never> = Omit<IBuilder<Used>, Used>;
|
|
76
|
+
type BuilderFn = (builder: CronBuilderType) => void;
|
|
77
|
+
//#endregion
|
|
78
|
+
export { BuilderFn, CronExpr, CronListExpr, CronRange, CronStep, Month, WeekDay };
|
|
79
|
+
//# sourceMappingURL=types.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.cts","names":[],"sources":["../../../src/lib/cron/builder/types.ts"],"mappings":";cAAa,OAAA;EAAA;;;;;;;;cAUA,KAAA;EAAA;;;;;;;;;;;;;KAeR,SAAA,gDAGD,GAAA,mBAAsB,CAAA,GACtB,GAAA,WACA,SAAA,CAAU,CAAA,MAAO,GAAA,EAAK,GAAA;AAAA,KAErB,QAAA,uCAA+C,OAAA,CAClD,SAAA,CAAU,CAAA,GACV,SAAA,CAAU,CAAA;AAAA,KAGA,QAAA,GAAW,QAAA;AAAA,KACX,QAAA,GAAW,QAAA;AAAA,KACX,OAAA,GAAU,QAAA;AAAA,KACV,SAAA,GAAY,QAAA;AAAA,KACZ,WAAA,GAAc,QAAA;AAAA,KAEd,SAAA;EAAiB,GAAA,EAAK,OAAA,CAAQ,CAAA;EAAI,GAAA,EAAK,OAAA,CAAQ,CAAA;AAAA;AAAA,KAC/C,QAAA;EACV,IAAA,EAAM,OAAA,CAAQ,CAAA;EACd,KAAA;IAAU,GAAA,EAAK,OAAA,CAAQ,CAAA;IAAI,GAAA,GAAM,OAAA,CAAQ,CAAA;EAAA;AAAA;AAAA,KAG/B,SAAA;AAAA,KAQA,YAAA,MAAkB,OAAA,CAAQ,QAAA,CAAS,CAAA;EAAM,IAAA;AAAA;AAAA,KAEzC,QAAA;EACN,IAAA;AAAA;EACA,IAAA;EAAe,KAAA,EAAO,CAAA;AAAA;EACtB,IAAA;EAAe,GAAA,EAAK,CAAA;EAAG,GAAA,EAAK,CAAA;AAAA;EAC5B,IAAA;EAAc,IAAA,EAAM,CAAA;EAAG,KAAA;IAAU,GAAA,EAAK,CAAA;IAAG,GAAA,GAAM,CAAA;EAAA;AAAA;EAC/C,IAAA;EAAc,MAAA,EAAQ,YAAA,CAAa,CAAA;AAAA;AAAA,UAE/B,QAAA,cAAsB,SAAA;EAC9B,MAAA,CAAO,IAAA,EAAM,QAAA,CAAS,QAAA,IAAY,eAAA,CAAgB,IAAA;EAClD,MAAA,CAAO,IAAA,EAAM,QAAA,CAAS,QAAA,IAAY,eAAA,CAAgB,IAAA;EAClD,IAAA,CAAK,IAAA,EAAM,QAAA,CAAS,QAAA,IAAY,eAAA,CAAgB,IAAA;EAChD,GAAA,CAAI,IAAA,EAAM,QAAA,CAAS,OAAA,IAAW,eAAA,CAAgB,IAAA;EAC9C,KAAA,CAAM,IAAA,EAAM,QAAA,CAAS,SAAA,IAAa,eAAA,CAAgB,IAAA;EAClD,OAAA,CAAQ,IAAA,EAAM,QAAA,CAAS,WAAA,IAAe,eAAA,CAAgB,IAAA;AAAA;AAAA,KAG5C,eAAA,cAA6B,SAAA,YAAqB,IAAA,CAC5D,QAAA,CAAS,IAAA,GACT,IAAA;AAAA,KAGU,SAAA,IAAa,OAAA,EAAS,eAAA"}
|