exisjs 0.7.5 → 0.7.7
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/cli/commands/build.d.ts.map +1 -1
- package/dist/cli/commands/build.js +12 -0
- package/dist/cli/commands/build.js.map +1 -1
- package/dist/cli/commands/clean.d.ts +5 -0
- package/dist/cli/commands/clean.d.ts.map +1 -0
- package/dist/cli/commands/clean.js +30 -0
- package/dist/cli/commands/clean.js.map +1 -0
- package/dist/cli/commands/dev.d.ts.map +1 -1
- package/dist/cli/commands/dev.js +171 -86
- package/dist/cli/commands/dev.js.map +1 -1
- package/dist/cli/commands/generate.d.ts +6 -1
- package/dist/cli/commands/generate.d.ts.map +1 -1
- package/dist/cli/commands/generate.js +57 -2
- package/dist/cli/commands/generate.js.map +1 -1
- package/dist/cli/commands/start.d.ts.map +1 -1
- package/dist/cli/commands/start.js +54 -16
- package/dist/cli/commands/start.js.map +1 -1
- package/dist/cli/index.js +26 -3
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/manifest.d.ts +1 -0
- package/dist/cli/manifest.d.ts.map +1 -1
- package/dist/cli/manifest.js +264 -33
- package/dist/cli/manifest.js.map +1 -1
- package/dist/cli/resolve-aliases.d.ts +1 -1
- package/dist/cli/resolve-aliases.d.ts.map +1 -1
- package/dist/cli/resolve-aliases.js +30 -13
- package/dist/cli/resolve-aliases.js.map +1 -1
- package/dist/config/config.d.ts +3 -1
- package/dist/config/config.d.ts.map +1 -1
- package/dist/config/config.js +9 -0
- package/dist/config/config.js.map +1 -1
- package/dist/config/types.d.ts +6 -0
- package/dist/config/types.d.ts.map +1 -1
- package/dist/cron/expressions.d.ts +45 -0
- package/dist/cron/expressions.d.ts.map +1 -0
- package/dist/cron/expressions.js +87 -0
- package/dist/cron/expressions.js.map +1 -0
- package/dist/cron/index.d.ts +6 -0
- package/dist/cron/index.d.ts.map +1 -0
- package/dist/cron/index.js +22 -0
- package/dist/cron/index.js.map +1 -0
- package/dist/cron/job.d.ts +50 -0
- package/dist/cron/job.d.ts.map +1 -0
- package/dist/cron/job.js +247 -0
- package/dist/cron/job.js.map +1 -0
- package/dist/cron/manager.d.ts +105 -0
- package/dist/cron/manager.d.ts.map +1 -0
- package/dist/cron/manager.js +245 -0
- package/dist/cron/manager.js.map +1 -0
- package/dist/cron/parser.d.ts +22 -0
- package/dist/cron/parser.d.ts.map +1 -0
- package/dist/cron/parser.js +269 -0
- package/dist/cron/parser.js.map +1 -0
- package/dist/cron/types.d.ts +76 -0
- package/dist/cron/types.d.ts.map +1 -0
- package/dist/cron/types.js +3 -0
- package/dist/cron/types.js.map +1 -0
- package/dist/decorators/constants.d.ts +2 -0
- package/dist/decorators/constants.d.ts.map +1 -1
- package/dist/decorators/constants.js +3 -1
- package/dist/decorators/constants.js.map +1 -1
- package/dist/decorators/core.d.ts +29 -11
- package/dist/decorators/core.d.ts.map +1 -1
- package/dist/decorators/core.js +49 -11
- package/dist/decorators/core.js.map +1 -1
- package/dist/decorators/cron.d.ts +57 -0
- package/dist/decorators/cron.d.ts.map +1 -0
- package/dist/decorators/cron.js +143 -0
- package/dist/decorators/cron.js.map +1 -0
- package/dist/decorators/index.d.ts +2 -0
- package/dist/decorators/index.d.ts.map +1 -1
- package/dist/decorators/index.js +2 -0
- package/dist/decorators/index.js.map +1 -1
- package/dist/decorators/middleware.d.ts +65 -2
- package/dist/decorators/middleware.d.ts.map +1 -1
- package/dist/decorators/middleware.js +148 -62
- package/dist/decorators/middleware.js.map +1 -1
- package/dist/decorators/params.d.ts +102 -2
- package/dist/decorators/params.d.ts.map +1 -1
- package/dist/decorators/params.js +105 -3
- package/dist/decorators/params.js.map +1 -1
- package/dist/decorators/response.d.ts.map +1 -1
- package/dist/decorators/response.js +32 -22
- package/dist/decorators/response.js.map +1 -1
- package/dist/decorators/routing.d.ts +81 -16
- package/dist/decorators/routing.d.ts.map +1 -1
- package/dist/decorators/routing.js +81 -16
- package/dist/decorators/routing.js.map +1 -1
- package/dist/di/container.d.ts.map +1 -1
- package/dist/di/container.js +6 -1
- package/dist/di/container.js.map +1 -1
- package/dist/docs/content/cli/commands.mdx +1 -1
- package/dist/docs/content/controllers.mdx +127 -10
- package/dist/docs/content/cron.mdx +196 -0
- package/dist/docs/content/decorators.mdx +22 -4
- package/dist/docs/content/errors.mdx +58 -9
- package/dist/docs/content/introduction.mdx +7 -7
- package/dist/docs/content/middleware.mdx +269 -6
- package/dist/docs/content/requests.mdx +180 -6
- package/dist/docs/content/responses.mdx +283 -32
- package/dist/docs/content/routing.mdx +46 -0
- package/dist/docs/content/swagger.mdx +228 -0
- package/dist/docs/content/validation.mdx +190 -11
- package/dist/docs/reference/context.mdx +11 -0
- package/dist/docs/reference/cron.mdx +300 -0
- package/dist/docs/reference/decorators.mdx +22 -4
- package/dist/docs/reference/error.mdx +88 -0
- package/dist/docs/reference/logger.mdx +175 -43
- package/dist/docs/reference/middleware.mdx +31 -0
- package/dist/docs/reference/router.mdx +22 -0
- package/dist/docs/reference/swagger.mdx +143 -0
- package/dist/docs/reference/validator.mdx +83 -23
- package/dist/error/errors.d.ts.map +1 -1
- package/dist/error/errors.js +95 -43
- package/dist/error/errors.js.map +1 -1
- package/dist/error/index.d.ts +1 -0
- package/dist/error/index.d.ts.map +1 -1
- package/dist/error/index.js +11 -1
- package/dist/error/index.js.map +1 -1
- package/dist/error/overlay.d.ts +42 -0
- package/dist/error/overlay.d.ts.map +1 -0
- package/dist/error/overlay.js +306 -0
- package/dist/error/overlay.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +22 -1
- package/dist/index.js.map +1 -1
- package/dist/lib/start-server.js +33 -7
- package/dist/lib/start-server.js.map +1 -1
- package/dist/logger/index.d.ts +1 -1
- package/dist/logger/index.d.ts.map +1 -1
- package/dist/logger/index.js +9 -1
- package/dist/logger/index.js.map +1 -1
- package/dist/middleware/guard.d.ts +2 -2
- package/dist/middleware/guard.d.ts.map +1 -1
- package/dist/middleware/guard.js.map +1 -1
- package/dist/middleware/ip-filter.d.ts +1 -0
- package/dist/middleware/ip-filter.d.ts.map +1 -1
- package/dist/middleware/ip-filter.js +2 -0
- package/dist/middleware/ip-filter.js.map +1 -1
- package/dist/middleware/middleware.d.ts +2 -2
- package/dist/middleware/middleware.d.ts.map +1 -1
- package/dist/middleware/middleware.js +20 -2
- package/dist/middleware/middleware.js.map +1 -1
- package/dist/middleware/security.d.ts +43 -1
- package/dist/middleware/security.d.ts.map +1 -1
- package/dist/middleware/security.js +101 -0
- package/dist/middleware/security.js.map +1 -1
- package/dist/response/index.d.ts +229 -6
- package/dist/response/index.d.ts.map +1 -1
- package/dist/response/index.js +272 -2
- package/dist/response/index.js.map +1 -1
- package/dist/router/boundary.d.ts +41 -11
- package/dist/router/boundary.d.ts.map +1 -1
- package/dist/router/boundary.js +24 -2
- package/dist/router/boundary.js.map +1 -1
- package/dist/router/controller-registrar.d.ts.map +1 -1
- package/dist/router/controller-registrar.js +108 -4
- package/dist/router/controller-registrar.js.map +1 -1
- package/dist/router/index.d.ts +2 -2
- package/dist/router/index.d.ts.map +1 -1
- package/dist/router/index.js +2 -1
- package/dist/router/index.js.map +1 -1
- package/dist/router/route-builder.d.ts +262 -65
- package/dist/router/route-builder.d.ts.map +1 -1
- package/dist/router/route-builder.js +181 -23
- package/dist/router/route-builder.js.map +1 -1
- package/dist/router/route-scanner.d.ts +6 -0
- package/dist/router/route-scanner.d.ts.map +1 -1
- package/dist/router/route-scanner.js +71 -792
- package/dist/router/route-scanner.js.map +1 -1
- package/dist/router/router.d.ts.map +1 -1
- package/dist/router/router.js +62 -17
- package/dist/router/router.js.map +1 -1
- package/dist/router/scanner/boundary-loader.d.ts +18 -0
- package/dist/router/scanner/boundary-loader.d.ts.map +1 -0
- package/dist/router/scanner/boundary-loader.js +539 -0
- package/dist/router/scanner/boundary-loader.js.map +1 -0
- package/dist/router/scanner/cron-mounter.d.ts +15 -0
- package/dist/router/scanner/cron-mounter.d.ts.map +1 -0
- package/dist/router/scanner/cron-mounter.js +216 -0
- package/dist/router/scanner/cron-mounter.js.map +1 -0
- package/dist/router/scanner/error-mounter.d.ts +14 -0
- package/dist/router/scanner/error-mounter.d.ts.map +1 -0
- package/dist/router/scanner/error-mounter.js +200 -0
- package/dist/router/scanner/error-mounter.js.map +1 -0
- package/dist/router/scanner/fs-scanner.d.ts +25 -0
- package/dist/router/scanner/fs-scanner.d.ts.map +1 -0
- package/dist/router/scanner/fs-scanner.js +115 -0
- package/dist/router/scanner/fs-scanner.js.map +1 -0
- package/dist/router/scanner/functional-compiler.d.ts +9 -0
- package/dist/router/scanner/functional-compiler.d.ts.map +1 -0
- package/dist/router/scanner/functional-compiler.js +233 -0
- package/dist/router/scanner/functional-compiler.js.map +1 -0
- package/dist/router/scanner/index.d.ts +9 -0
- package/dist/router/scanner/index.d.ts.map +1 -0
- package/dist/router/scanner/index.js +19 -0
- package/dist/router/scanner/index.js.map +1 -0
- package/dist/router/types.d.ts +23 -0
- package/dist/router/types.d.ts.map +1 -1
- package/dist/server/app.d.ts +3 -0
- package/dist/server/app.d.ts.map +1 -1
- package/dist/server/app.js +13 -0
- package/dist/server/app.js.map +1 -1
- package/dist/server/bootstrapper.d.ts.map +1 -1
- package/dist/server/bootstrapper.js +91 -30
- package/dist/server/bootstrapper.js.map +1 -1
- package/dist/server/cluster.d.ts.map +1 -1
- package/dist/server/cluster.js +13 -2
- package/dist/server/cluster.js.map +1 -1
- package/dist/server/context.d.ts +8 -0
- package/dist/server/context.d.ts.map +1 -1
- package/dist/server/context.js +50 -6
- package/dist/server/context.js.map +1 -1
- package/dist/server/helpers/body-parser.d.ts +18 -0
- package/dist/server/helpers/body-parser.d.ts.map +1 -0
- package/dist/server/helpers/body-parser.js +246 -0
- package/dist/server/helpers/body-parser.js.map +1 -0
- package/dist/server/helpers/cookie.d.ts +4 -0
- package/dist/server/helpers/cookie.d.ts.map +1 -0
- package/dist/server/helpers/cookie.js +61 -0
- package/dist/server/helpers/cookie.js.map +1 -0
- package/dist/server/helpers/etag.d.ts +3 -0
- package/dist/server/helpers/etag.d.ts.map +1 -0
- package/dist/server/helpers/etag.js +25 -0
- package/dist/server/helpers/etag.js.map +1 -0
- package/dist/server/helpers/index.d.ts +6 -0
- package/dist/server/helpers/index.d.ts.map +1 -0
- package/dist/server/helpers/index.js +21 -0
- package/dist/server/helpers/index.js.map +1 -0
- package/dist/server/helpers/ip.d.ts +9 -0
- package/dist/server/helpers/ip.d.ts.map +1 -0
- package/dist/server/helpers/ip.js +62 -0
- package/dist/server/helpers/ip.js.map +1 -0
- package/dist/server/helpers/stream.d.ts +4 -0
- package/dist/server/helpers/stream.d.ts.map +1 -0
- package/dist/server/helpers/stream.js +193 -0
- package/dist/server/helpers/stream.js.map +1 -0
- package/dist/server/lifecycle.d.ts +22 -0
- package/dist/server/lifecycle.d.ts.map +1 -0
- package/dist/server/lifecycle.js +106 -0
- package/dist/server/lifecycle.js.map +1 -0
- package/dist/server/request-handler.d.ts +1 -0
- package/dist/server/request-handler.d.ts.map +1 -1
- package/dist/server/request-handler.js +27 -17
- package/dist/server/request-handler.js.map +1 -1
- package/dist/server/request.d.ts +1 -139
- package/dist/server/request.d.ts.map +1 -1
- package/dist/server/request.js +37 -433
- package/dist/server/request.js.map +1 -1
- package/dist/server/response.d.ts +112 -156
- package/dist/server/response.d.ts.map +1 -1
- package/dist/server/response.js +129 -279
- package/dist/server/response.js.map +1 -1
- package/dist/swagger/decorators.d.ts +81 -0
- package/dist/swagger/decorators.d.ts.map +1 -0
- package/dist/swagger/decorators.js +172 -0
- package/dist/swagger/decorators.js.map +1 -0
- package/dist/swagger/generator.d.ts +19 -0
- package/dist/swagger/generator.d.ts.map +1 -0
- package/dist/swagger/generator.js +344 -0
- package/dist/swagger/generator.js.map +1 -0
- package/dist/swagger/index.d.ts +31 -0
- package/dist/swagger/index.d.ts.map +1 -0
- package/dist/swagger/index.js +53 -0
- package/dist/swagger/index.js.map +1 -0
- package/dist/swagger/mounter.d.ts +7 -0
- package/dist/swagger/mounter.d.ts.map +1 -0
- package/dist/swagger/mounter.js +56 -0
- package/dist/swagger/mounter.js.map +1 -0
- package/dist/swagger/types.d.ts +190 -0
- package/dist/swagger/types.d.ts.map +1 -0
- package/dist/swagger/types.js +3 -0
- package/dist/swagger/types.js.map +1 -0
- package/dist/swagger/ui.d.ts +6 -0
- package/dist/swagger/ui.d.ts.map +1 -0
- package/dist/swagger/ui.js +118 -0
- package/dist/swagger/ui.js.map +1 -0
- package/dist/testing/index.d.ts.map +1 -1
- package/dist/testing/index.js +6 -1
- package/dist/testing/index.js.map +1 -1
- package/dist/testing/mocks.d.ts.map +1 -1
- package/dist/testing/mocks.js +15 -3
- package/dist/testing/mocks.js.map +1 -1
- package/dist/utils/logger.d.ts +8 -0
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +184 -1
- package/dist/utils/logger.js.map +1 -1
- package/dist/validator/builder.d.ts +223 -0
- package/dist/validator/builder.d.ts.map +1 -0
- package/dist/validator/builder.js +517 -0
- package/dist/validator/builder.js.map +1 -0
- package/dist/validator/engine.d.ts +19 -0
- package/dist/validator/engine.d.ts.map +1 -0
- package/dist/validator/engine.js +568 -0
- package/dist/validator/engine.js.map +1 -0
- package/dist/validator/error.d.ts +12 -0
- package/dist/validator/error.d.ts.map +1 -0
- package/dist/validator/error.js +63 -0
- package/dist/validator/error.js.map +1 -0
- package/dist/validator/pagination.d.ts +40 -0
- package/dist/validator/pagination.d.ts.map +1 -0
- package/dist/validator/pagination.js +60 -0
- package/dist/validator/pagination.js.map +1 -0
- package/dist/validator/tex-types.d.ts +2 -1
- package/dist/validator/tex-types.d.ts.map +1 -1
- package/dist/validator/tex-types.js +2 -1
- package/dist/validator/tex-types.js.map +1 -1
- package/dist/validator/tex.d.ts +6 -142
- package/dist/validator/tex.d.ts.map +1 -1
- package/dist/validator/tex.js +14 -733
- package/dist/validator/tex.js.map +1 -1
- package/dist/validator/types.d.ts +83 -0
- package/dist/validator/types.d.ts.map +1 -0
- package/dist/validator/types.js +3 -0
- package/dist/validator/types.js.map +1 -0
- package/package.json +8 -4
- package/dist/dev/error-overlay.d.ts +0 -3
- package/dist/dev/error-overlay.d.ts.map +0 -1
- package/dist/dev/error-overlay.js +0 -118
- package/dist/dev/error-overlay.js.map +0 -1
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Cron & Scheduling"
|
|
3
|
+
description: "API Reference for ExisJS Task Scheduling, Cron Expressions, and Job Management."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Cron & Scheduling (`exisjs/cron`, `exisjs/decorators`)
|
|
7
|
+
|
|
8
|
+
The `exisjs/cron` module provides task scheduling, cron expression parsing, interval timers, and runtime job management.
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## 1. Functional Definition Helpers
|
|
13
|
+
|
|
14
|
+
### `cron(scheduleOrOptions, handler?)`
|
|
15
|
+
|
|
16
|
+
Defines a functional cron job.
|
|
17
|
+
|
|
18
|
+
```typescript
|
|
19
|
+
import { cron, CronExpression } from 'exisjs/cron'
|
|
20
|
+
|
|
21
|
+
// Signature 1: Options object with inline run handler
|
|
22
|
+
export default cron({
|
|
23
|
+
name: 'sync-users',
|
|
24
|
+
schedule: CronExpression.EVERY_10_MINUTES,
|
|
25
|
+
timezone: 'UTC',
|
|
26
|
+
preventOverlap: true,
|
|
27
|
+
retries: 2,
|
|
28
|
+
retryDelayMs: 1000,
|
|
29
|
+
async run({ app, log }) {
|
|
30
|
+
// ...
|
|
31
|
+
}
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
// Signature 2: Schedule string with handler
|
|
35
|
+
export const purgeJob = cron('0 0 * * *', async ({ log }) => {
|
|
36
|
+
// ...
|
|
37
|
+
})
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### `cron.every(duration, handler, options?)`
|
|
41
|
+
|
|
42
|
+
Shorthand helper accepting human-readable duration strings (e.g., `'10 seconds'`, `'5 minutes'`, `'2 hours'`).
|
|
43
|
+
|
|
44
|
+
```typescript
|
|
45
|
+
import { cron } from 'exisjs/cron'
|
|
46
|
+
|
|
47
|
+
export const healthCheck = cron.every('30 seconds', async ({ log }) => {
|
|
48
|
+
log.info('Checking external dependencies...')
|
|
49
|
+
}, {
|
|
50
|
+
name: 'ext-health-check'
|
|
51
|
+
})
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### `cron.interval(ms, handler, options?)`
|
|
55
|
+
|
|
56
|
+
Shorthand helper for millisecond recurring intervals.
|
|
57
|
+
|
|
58
|
+
```typescript
|
|
59
|
+
import { cron } from 'exisjs/cron'
|
|
60
|
+
|
|
61
|
+
export const heartbeat = cron.interval(60_000, async ({ log }) => {
|
|
62
|
+
log.info('Server heartbeat tick')
|
|
63
|
+
})
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### `cron.timeout(ms, handler, options?)`
|
|
67
|
+
|
|
68
|
+
Shorthand helper for one-time delayed startup tasks (executes once after application boot).
|
|
69
|
+
|
|
70
|
+
```typescript
|
|
71
|
+
import { cron } from 'exisjs/cron'
|
|
72
|
+
|
|
73
|
+
export const cacheWarmup = cron.timeout(5_000, async ({ app, log }) => {
|
|
74
|
+
log.info('Warming up Redis cache after boot')
|
|
75
|
+
})
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## 2. OOP Decorators (`exisjs/decorators`)
|
|
81
|
+
|
|
82
|
+
### `@Cron(schedule, options?)`
|
|
83
|
+
|
|
84
|
+
Method decorator that marks a class method as a scheduled cron job. Can be used on any `@Injectable()` service.
|
|
85
|
+
|
|
86
|
+
| Parameter | Type | Description |
|
|
87
|
+
| :--- | :--- | :--- |
|
|
88
|
+
| `schedule` | `string` | Standard 5 or 6 field cron expression or `CronExpression` constant. |
|
|
89
|
+
| `options` | `CronJobOptions` | Optional job configuration (name, timezone, preventOverlap, retries, etc.). |
|
|
90
|
+
|
|
91
|
+
```typescript
|
|
92
|
+
import { Injectable, Cron, CronExpression } from 'exisjs/decorators'
|
|
93
|
+
|
|
94
|
+
@Injectable()
|
|
95
|
+
export default class ReportService {
|
|
96
|
+
@Cron(CronExpression.EVERY_DAY_AT_MIDNIGHT, {
|
|
97
|
+
name: 'nightly-report',
|
|
98
|
+
timezone: 'UTC',
|
|
99
|
+
preventOverlap: true,
|
|
100
|
+
})
|
|
101
|
+
async generateDailyReport() {
|
|
102
|
+
// ...
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### `@Interval(ms, options?)`
|
|
108
|
+
|
|
109
|
+
Method decorator for recurring millisecond tasks.
|
|
110
|
+
|
|
111
|
+
```typescript
|
|
112
|
+
import { Injectable, Interval } from 'exisjs/decorators'
|
|
113
|
+
|
|
114
|
+
@Injectable()
|
|
115
|
+
export default class QueueMonitor {
|
|
116
|
+
@Interval(15_000, { name: 'queue-poll' })
|
|
117
|
+
async pollQueue() {
|
|
118
|
+
// ...
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### `@TimeoutTask(ms, options?)` (alias `@ScheduledTimeout`)
|
|
124
|
+
|
|
125
|
+
Method decorator for one-time startup tasks executed after the specified millisecond delay.
|
|
126
|
+
|
|
127
|
+
```typescript
|
|
128
|
+
import { Injectable, TimeoutTask } from 'exisjs/decorators'
|
|
129
|
+
|
|
130
|
+
@Injectable()
|
|
131
|
+
export default class CacheBootstrap {
|
|
132
|
+
@TimeoutTask(3_000, { name: 'seed-cache' })
|
|
133
|
+
async seedCache() {
|
|
134
|
+
// ...
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
## 3. Configuration & Options
|
|
142
|
+
|
|
143
|
+
### `CronJobOptions`
|
|
144
|
+
|
|
145
|
+
Configuration object passed to `cron()` or decorator options:
|
|
146
|
+
|
|
147
|
+
| Property | Type | Default | Description |
|
|
148
|
+
| :--- | :--- | :--- | :--- |
|
|
149
|
+
| `name` | `string` | `auto-generated` | Unique identifier for the job. Used in logs and runtime APIs. |
|
|
150
|
+
| `schedule` | `string` | `undefined` | 5 or 6 field cron expression (e.g. `'0 0 * * *'`). |
|
|
151
|
+
| `interval` | `number` | `undefined` | Millisecond interval for recurring execution. |
|
|
152
|
+
| `timeout` | `number` | `undefined` | Millisecond delay for one-time execution. |
|
|
153
|
+
| `timezone` | `string` | `'UTC'` | Valid IANA timezone string (e.g. `'America/New_York'`, `'Asia/Kolkata'`). |
|
|
154
|
+
| `preventOverlap` | `boolean` | `true` | Skips execution if the previous tick is still running. |
|
|
155
|
+
| `overlapPolicy` | `'skip' \| 'queue'` | `'skip'` | Action taken when execution overlap occurs. |
|
|
156
|
+
| `retries` | `number` | `0` | Number of retry attempts upon failure. |
|
|
157
|
+
| `retryDelayMs` | `number` | `1000` | Milliseconds to wait before executing a retry. |
|
|
158
|
+
| `autoStart` | `boolean` | `true` | Whether the job automatically starts on application bootstrap. |
|
|
159
|
+
| `run` / `handle` | `(ctx: CronContext) => Promise<any> \| any` | `undefined` | The execution callback function. |
|
|
160
|
+
| `onError` | `(err: Error, ctx: CronContext) => void` | `undefined` | Hook called when the job fails after all retries. |
|
|
161
|
+
|
|
162
|
+
### `CronContext`
|
|
163
|
+
|
|
164
|
+
The context object provided as the first argument to job execution handlers:
|
|
165
|
+
|
|
166
|
+
| Property | Type | Description |
|
|
167
|
+
| :--- | :--- | :--- |
|
|
168
|
+
| `name` | `string` | The unique name of the active job. |
|
|
169
|
+
| `scheduledTime` | `Date` | The theoretical timestamp the job was scheduled to run. |
|
|
170
|
+
| `executionTime` | `Date` | The actual timestamp execution began. |
|
|
171
|
+
| `iteration` | `number` | Total number of executions completed by this job instance. |
|
|
172
|
+
| `app` | `App` | Reference to the current ExisJS application instance. |
|
|
173
|
+
| `log` | `Logger` | Scoped logger instance with `job: name` context. |
|
|
174
|
+
|
|
175
|
+
---
|
|
176
|
+
|
|
177
|
+
## 4. `CronExpression` Presets
|
|
178
|
+
|
|
179
|
+
ExisJS exports pre-validated standard cron expression constants:
|
|
180
|
+
|
|
181
|
+
| Constant | Value | Description |
|
|
182
|
+
| :--- | :--- | :--- |
|
|
183
|
+
| `CronExpression.EVERY_SECOND` | `* * * * * *` | Every second (6-field) |
|
|
184
|
+
| `CronExpression.EVERY_5_SECONDS` | `*/5 * * * * *` | Every 5 seconds (6-field) |
|
|
185
|
+
| `CronExpression.EVERY_10_SECONDS` | `*/10 * * * * *` | Every 10 seconds (6-field) |
|
|
186
|
+
| `CronExpression.EVERY_30_SECONDS` | `*/30 * * * * *` | Every 30 seconds (6-field) |
|
|
187
|
+
| `CronExpression.EVERY_MINUTE` | `* * * * *` | Every minute |
|
|
188
|
+
| `CronExpression.EVERY_5_MINUTES` | `*/5 * * * *` | Every 5 minutes |
|
|
189
|
+
| `CronExpression.EVERY_10_MINUTES` | `*/10 * * * *` | Every 10 minutes |
|
|
190
|
+
| `CronExpression.EVERY_15_MINUTES` | `*/15 * * * *` | Every 15 minutes |
|
|
191
|
+
| `CronExpression.EVERY_30_MINUTES` | `*/30 * * * *` | Every 30 minutes |
|
|
192
|
+
| `CronExpression.EVERY_HOUR` | `0 * * * *` | Top of every hour |
|
|
193
|
+
| `CronExpression.EVERY_2_HOURS` | `0 */2 * * *` | Every 2 hours |
|
|
194
|
+
| `CronExpression.EVERY_6_HOURS` | `0 */6 * * *` | Every 6 hours |
|
|
195
|
+
| `CronExpression.EVERY_12_HOURS` | `0 */12 * * *` | Every 12 hours |
|
|
196
|
+
| `CronExpression.EVERY_DAY_AT_MIDNIGHT` | `0 0 * * *` | Daily at 00:00 (Midnight) |
|
|
197
|
+
| `CronExpression.EVERY_DAY_AT_1AM` | `0 1 * * *` | Daily at 01:00 AM |
|
|
198
|
+
| `CronExpression.EVERY_DAY_AT_2AM` | `0 2 * * *` | Daily at 02:00 AM |
|
|
199
|
+
| `CronExpression.EVERY_DAY_AT_NOON` | `0 12 * * *` | Daily at 12:00 PM |
|
|
200
|
+
| `CronExpression.EVERY_WEEK` | `0 0 * * 0` | Every Sunday at midnight |
|
|
201
|
+
| `CronExpression.EVERY_MONTH` | `0 0 1 * *` | First day of every month at midnight |
|
|
202
|
+
| `CronExpression.EVERY_YEAR` | `0 0 1 1 *` | January 1st at midnight |
|
|
203
|
+
|
|
204
|
+
---
|
|
205
|
+
|
|
206
|
+
## 5. Runtime Management API (`app.cron`)
|
|
207
|
+
|
|
208
|
+
Access the cron manager via `app.cron`:
|
|
209
|
+
|
|
210
|
+
### `app.cron.schedule(options)`
|
|
211
|
+
Registers and schedules a new cron job dynamically.
|
|
212
|
+
|
|
213
|
+
```typescript
|
|
214
|
+
const job = app.cron.schedule({
|
|
215
|
+
name: 'dynamic-sync',
|
|
216
|
+
schedule: '0 */3 * * *',
|
|
217
|
+
run: async ({ log }) => {
|
|
218
|
+
log.info('Dynamic sync executed')
|
|
219
|
+
}
|
|
220
|
+
})
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
### `app.cron.get(name)`
|
|
224
|
+
Returns the `CronJob` instance by name, or `undefined` if not found.
|
|
225
|
+
|
|
226
|
+
```typescript
|
|
227
|
+
const job = app.cron.get('nightly-sync')
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
### `app.cron.has(name)`
|
|
231
|
+
Returns `true` if a job with the specified name exists.
|
|
232
|
+
|
|
233
|
+
```typescript
|
|
234
|
+
if (app.cron.has('nightly-sync')) {
|
|
235
|
+
// ...
|
|
236
|
+
}
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
### `app.cron.list()`
|
|
240
|
+
Returns an array of all registered `CronJob` instances.
|
|
241
|
+
|
|
242
|
+
```typescript
|
|
243
|
+
const allJobs = app.cron.list()
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
### `app.cron.status()`
|
|
247
|
+
Returns an array of status and metric descriptors for all registered jobs.
|
|
248
|
+
|
|
249
|
+
```typescript
|
|
250
|
+
const stats = app.cron.status()
|
|
251
|
+
// [
|
|
252
|
+
// {
|
|
253
|
+
// name: 'nightly-sync',
|
|
254
|
+
// status: 'running',
|
|
255
|
+
// running: false,
|
|
256
|
+
// totalExecutions: 14,
|
|
257
|
+
// successCount: 14,
|
|
258
|
+
// failureCount: 0,
|
|
259
|
+
// lastExecution: '2026-09-22T00:00:00.000Z',
|
|
260
|
+
// nextExecution: '2026-09-23T00:00:00.000Z',
|
|
261
|
+
// lastDurationMs: 142
|
|
262
|
+
// }
|
|
263
|
+
// ]
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
### `app.cron.trigger(name)`
|
|
267
|
+
Manually triggers an immediate execution of the specified job, returning the handler result.
|
|
268
|
+
|
|
269
|
+
```typescript
|
|
270
|
+
const result = await app.cron.trigger('nightly-sync')
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
### `app.cron.pause(name)` / `app.cron.resume(name)`
|
|
274
|
+
Pauses or resumes a job's automatic scheduling without unregistering it.
|
|
275
|
+
|
|
276
|
+
```typescript
|
|
277
|
+
app.cron.pause('nightly-sync')
|
|
278
|
+
app.cron.resume('nightly-sync')
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
### `app.cron.remove(name)`
|
|
282
|
+
Stops and unregisters a job by name.
|
|
283
|
+
|
|
284
|
+
```typescript
|
|
285
|
+
app.cron.remove('nightly-sync')
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
### `app.cron.stopAll()`
|
|
289
|
+
Stops all scheduled timers across all registered jobs.
|
|
290
|
+
|
|
291
|
+
```typescript
|
|
292
|
+
app.cron.stopAll()
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
### `app.cron.drain(timeoutMs?)`
|
|
296
|
+
Stops new ticks and awaits any currently running job executions to complete. Called automatically during graceful server shutdown.
|
|
297
|
+
|
|
298
|
+
```typescript
|
|
299
|
+
await app.cron.drain(5000)
|
|
300
|
+
```
|
|
@@ -68,6 +68,10 @@ Parameter decorators automatically extract data from the incoming request and in
|
|
|
68
68
|
- `@Param(nameOrPipe?)`: Injects a URL path parameter (e.g., `id` from `/:id`).
|
|
69
69
|
- `@Headers(nameOrPipe?)`: Injects an HTTP header by name.
|
|
70
70
|
- `@QueryParam(nameOrPipe?)` / `@Query(nameOrPipe?)`: Injects a URL query parameter (e.g., `?search=term`).
|
|
71
|
+
- `@Cookies(nameOrPipe?)` / `@Cookie(nameOrPipe?)`: Injects incoming parsed cookies or a specific cookie value.
|
|
72
|
+
- `@State(keyOrPipe?)`: Injects request state from execution context or middleware.
|
|
73
|
+
- `@AppCtx()`: Injects the root ExisJS Application instance.
|
|
74
|
+
- `@Fields(nameOrPipe?)`: Injects non-file multipart form fields.
|
|
71
75
|
- `@UploadedFile()`: Injects the uploaded file (`req.file`) into the method argument.
|
|
72
76
|
- `@UploadedFiles()`: Injects the uploaded files array or dictionary (`req.files`) into the method argument.
|
|
73
77
|
- `@HostParam(nameOrPipe?)`: Injects a subdomain parameter.
|
|
@@ -83,8 +87,14 @@ Parameter decorators automatically extract data from the incoming request and in
|
|
|
83
87
|
|
|
84
88
|
- `@Use(...middlewaresOrGuardsOrInterceptorsOrFilters)`: Unified decorator that binds middlewares, guards (`canActivate`), interceptors (`intercept`), or exception filters (`catch`) to a controller class or method.
|
|
85
89
|
- `@Upload(fieldName, options?)` / `@UseUpload(...)`: Configures multipart file upload handling for a method, populating `@UploadedFile()` or `@UploadedFiles()`.
|
|
86
|
-
- `@Timeout(ms: number | TimeoutOptions)`: Overrides the request timeout for
|
|
87
|
-
- `@Idempotent(options?)`: Caches responses based on the `Idempotency-Key` header using native in-memory off-heap storage.
|
|
90
|
+
- `@Timeout(ms: number | TimeoutOptions)`: Overrides the request timeout for a class or method (e.g. `@Timeout(120000)`). Passing `0` disables timeouts for long-running streaming or exports.
|
|
91
|
+
- `@Idempotent(options?)`: Caches responses based on the `Idempotency-Key` header using native in-memory off-heap storage. Works at class and method level.
|
|
92
|
+
- `@RateLimit(options?)`: Enforces rate limits (e.g. `@RateLimit({ max: 100, windowMs: 60000 })`) at class or method level.
|
|
93
|
+
- `@Cors(options?)`: Enforces Cross-Origin Resource Sharing rules at class or method level.
|
|
94
|
+
- `@IpFilter(options)`: Enforces CIDR and IP allow/deny lists at class or method level.
|
|
95
|
+
- `@Compress()`: Enables automatic Gzip and Brotli compression on responses.
|
|
96
|
+
- `@Dedupe(options)`: Deduplicates concurrent identical requests sharing the same key.
|
|
97
|
+
- `@BlockProbes(options?)`: Intercepts vulnerability scanner probes (`.env`, `/.git`, `/.DS_Store`) and blackholes them without triggering log noise.
|
|
88
98
|
|
|
89
99
|
---
|
|
90
100
|
|
|
@@ -108,8 +118,16 @@ Parameter decorators automatically extract data from the incoming request and in
|
|
|
108
118
|
|
|
109
119
|
- `@Module({ imports?, controllers?, providers?, exports? })`: OOP class decorator equivalent to `defineModule()` for structuring application modules.
|
|
110
120
|
- `@Injectable(options?)`: Marks a service class as an IoC provider managed by the container. Supports `{ scope: 'singleton' | 'request' | 'transient' }`.
|
|
111
|
-
- `@Inject(token)`: Constructor parameter decorator for injecting dependencies by class, string, or symbol token.
|
|
112
|
-
- `@Optional()`: Constructor parameter decorator resolving missing dependencies to `undefined` without throwing.
|
|
121
|
+
- `@Inject(token)`: Constructor parameter decorator from `exisjs/di` for injecting dependencies by class, string, or symbol token.
|
|
122
|
+
- `@Optional()`: Constructor parameter decorator from `exisjs/di` resolving missing dependencies to `undefined` without throwing.
|
|
113
123
|
- `@Boundary(config)`: Marks a class as a folder-scoped Boundary configuring CORS, headers, exclusions, and pipeline steps.
|
|
114
124
|
- `@Server(config)`: Marks a class as a root server definition.
|
|
115
125
|
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
## 6. Cron & Task Scheduling
|
|
129
|
+
|
|
130
|
+
- `@Cron(schedule: string, options?: CronJobOptions)`: Schedules a class method as a recurring cron job on any `@Injectable()` service.
|
|
131
|
+
- `@Interval(ms: number, options?: IntervalOptions)`: Schedules a class method to execute repeatedly every `ms` milliseconds.
|
|
132
|
+
- `@TimeoutTask(ms: number, options?: TimeoutOptions)` (alias `@ScheduledTimeout`): Schedules a class method to execute once after `ms` milliseconds following application bootstrap.
|
|
133
|
+
|
|
@@ -133,6 +133,50 @@ export class InsufficientFundsError extends HttpError {
|
|
|
133
133
|
|
|
134
134
|
---
|
|
135
135
|
|
|
136
|
+
## Framework Exception File Convention (`src/http/error.ts`)
|
|
137
|
+
|
|
138
|
+
ExisJS natively discovers and auto-mounts `src/http/error.ts` (or `src/http/*.error.ts`) during application bootstrap. It serves as the single source of truth for centralized exception filtering without requiring manual middleware registration in `server.ts`.
|
|
139
|
+
|
|
140
|
+
### Handler Signatures
|
|
141
|
+
|
|
142
|
+
**Functional (`export function onError`):**
|
|
143
|
+
```typescript filename="src/http/error.ts"
|
|
144
|
+
import type { Request, Response } from 'exisjs'
|
|
145
|
+
|
|
146
|
+
export function onError(err: any, req: Request, res: Response): void | Promise<void> {
|
|
147
|
+
const status = err.statusCode || err.status || 500
|
|
148
|
+
res.status(status).json({
|
|
149
|
+
success: false,
|
|
150
|
+
error: {
|
|
151
|
+
code: err.code || 'ERROR',
|
|
152
|
+
message: err.message || 'Internal Server Error',
|
|
153
|
+
path: req.path,
|
|
154
|
+
},
|
|
155
|
+
})
|
|
156
|
+
}
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
**Class-Based OOP (`export default class`):**
|
|
160
|
+
```typescript filename="src/http/error.ts"
|
|
161
|
+
import type { Request, Response } from 'exisjs'
|
|
162
|
+
|
|
163
|
+
export default class GlobalErrorHandler {
|
|
164
|
+
onError(err: any, req: Request, res: Response): void | Promise<void> {
|
|
165
|
+
const status = err.statusCode || err.status || 500
|
|
166
|
+
res.status(status).json({
|
|
167
|
+
success: false,
|
|
168
|
+
error: {
|
|
169
|
+
code: err.code || 'ERROR',
|
|
170
|
+
message: err.message || 'Internal Server Error',
|
|
171
|
+
path: req.path,
|
|
172
|
+
},
|
|
173
|
+
})
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
136
180
|
## Global Error Handler
|
|
137
181
|
|
|
138
182
|
ExisJS uses a highly sophisticated global error handler out of the box, generated via `createErrorHandler(isDev)`.
|
|
@@ -170,3 +214,47 @@ app.use((err, req, res, next) => {
|
|
|
170
214
|
ExisJS natively intercepts and handles Promise rejections at the core routing level.
|
|
171
215
|
|
|
172
216
|
Unlike Express, you do **not** need to wrap your routes in an `asyncHandler`. However, for strict compatibility with older Express middleware ecosystems, `exisjs/error` does export an `asyncHandler` wrapper. Note that using it in ExisJS is entirely redundant and merely adds unnecessary Promise allocations.
|
|
217
|
+
|
|
218
|
+
---
|
|
219
|
+
|
|
220
|
+
## Developer Error Formatting & Overlay Utilities
|
|
221
|
+
|
|
222
|
+
`exisjs/error` also exports powerful error diagnostic utilities that you can use in custom error handlers, CLI scripts, background workers, and testing:
|
|
223
|
+
|
|
224
|
+
```typescript
|
|
225
|
+
import {
|
|
226
|
+
formatDevError,
|
|
227
|
+
renderDevErrorToString,
|
|
228
|
+
categorizeError,
|
|
229
|
+
generateErrorHint,
|
|
230
|
+
buildCodeFrame,
|
|
231
|
+
stripInternalStackFrames,
|
|
232
|
+
devErrorResponse,
|
|
233
|
+
type ParsedError,
|
|
234
|
+
} from 'exisjs/error'
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
### Utility Functions
|
|
238
|
+
|
|
239
|
+
| Function | Signature | Description |
|
|
240
|
+
| :--- | :--- | :--- |
|
|
241
|
+
| `formatDevError` | `(err: Error, optionsOrFile?: string \| { routeFile?: string; title?: string }) => void` | Prints a formatted terminal error envelope with code frames and actionable hints |
|
|
242
|
+
| `renderDevErrorToString` | `(err: Error, optionsOrFile?: ...) => string` | Returns the formatted terminal error envelope string |
|
|
243
|
+
| `categorizeError` | `(err: Error) => string` | Intelligently classifies errors into domain categories (`Validation Schema Error`, `Environment Configuration Error`, etc.) |
|
|
244
|
+
| `generateErrorHint` | `(err: Error) => string \| null` | Generates actionable hints for common coding mistakes |
|
|
245
|
+
| `buildCodeFrame` | `(filePath: string, line: number, col?: number) => string` | Builds a source code snippet visualizer with gutter line numbers and caret indicator |
|
|
246
|
+
| `stripInternalStackFrames` | `(stack?: string) => string[]` | Strips internal Node.js and framework runtime stack frames |
|
|
247
|
+
| `devErrorResponse` | `(err: Error, routeFile?: string) => object` | Generates a structured developer error envelope payload for JSON API responses |
|
|
248
|
+
|
|
249
|
+
### Example: Custom Worker or Script Error Handling
|
|
250
|
+
|
|
251
|
+
```typescript filename="src/workers/import-csv.ts"
|
|
252
|
+
import { formatDevError, categorizeError } from 'exisjs/error'
|
|
253
|
+
|
|
254
|
+
try {
|
|
255
|
+
await processCsvImport(filePath)
|
|
256
|
+
} catch (err: any) {
|
|
257
|
+
// Prints a clean code frame with line numbers and actionable hints directly in terminal
|
|
258
|
+
formatDevError(err, { routeFile: filePath, title: categorizeError(err) })
|
|
259
|
+
}
|
|
260
|
+
```
|