@luisrodrigues/nestjs-scheduler-dashboard 0.1.2 → 0.1.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/jobs.service.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ export declare class JobsService {
|
|
|
7
7
|
getJobs(): {
|
|
8
8
|
cron: {
|
|
9
9
|
name: string;
|
|
10
|
-
cronExpression:
|
|
10
|
+
cronExpression: string;
|
|
11
11
|
running: boolean;
|
|
12
12
|
nextRun: string;
|
|
13
13
|
history: import(".").JobExecution[];
|
|
@@ -22,7 +22,7 @@ export declare class JobsService {
|
|
|
22
22
|
};
|
|
23
23
|
getJob(name: string): {
|
|
24
24
|
name: string;
|
|
25
|
-
cronExpression:
|
|
25
|
+
cronExpression: string;
|
|
26
26
|
running: boolean;
|
|
27
27
|
nextRun: string;
|
|
28
28
|
history: import(".").JobExecution[];
|
package/dist/jobs.service.js
CHANGED
|
@@ -15,6 +15,35 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
15
15
|
exports.JobsService = void 0;
|
|
16
16
|
const common_1 = require("@nestjs/common");
|
|
17
17
|
const schedule_1 = require("@nestjs/schedule");
|
|
18
|
+
function resolveNextRun(job) {
|
|
19
|
+
try {
|
|
20
|
+
const next = job.nextDate?.();
|
|
21
|
+
if (!next)
|
|
22
|
+
return null;
|
|
23
|
+
if (typeof next.toISO === 'function')
|
|
24
|
+
return next.toISO();
|
|
25
|
+
if (next instanceof Date)
|
|
26
|
+
return next.toISOString();
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
function resolveCronExpression(cronTime) {
|
|
34
|
+
if (!cronTime || typeof cronTime !== 'object')
|
|
35
|
+
return null;
|
|
36
|
+
const ct = cronTime;
|
|
37
|
+
const src = ct['source'] ?? ct['_source'];
|
|
38
|
+
if (typeof src === 'string')
|
|
39
|
+
return src;
|
|
40
|
+
if (typeof cronTime.toString === 'function') {
|
|
41
|
+
const str = cronTime.toString();
|
|
42
|
+
if (str !== '[object Object]')
|
|
43
|
+
return str;
|
|
44
|
+
}
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
18
47
|
const storage_abstract_1 = require("./storage/storage.abstract");
|
|
19
48
|
const job_concurrency_1 = require("./decorators/job-concurrency");
|
|
20
49
|
const scheduler_dash_constants_1 = require("./scheduler-dash.constants");
|
|
@@ -26,7 +55,7 @@ let JobsService = class JobsService {
|
|
|
26
55
|
getJobs() {
|
|
27
56
|
const cron = [...this.schedulerRegistry.getCronJobs().entries()].map(([name, job]) => ({
|
|
28
57
|
name,
|
|
29
|
-
cronExpression: job.cronTime
|
|
58
|
+
cronExpression: resolveCronExpression(job.cronTime),
|
|
30
59
|
running: job.running ?? false,
|
|
31
60
|
nextRun: job.nextDate()?.toISO() ?? null,
|
|
32
61
|
history: this.storage.findByJob(name),
|
|
@@ -42,7 +71,7 @@ let JobsService = class JobsService {
|
|
|
42
71
|
return null;
|
|
43
72
|
return {
|
|
44
73
|
name,
|
|
45
|
-
cronExpression: job.cronTime
|
|
74
|
+
cronExpression: resolveCronExpression(job.cronTime),
|
|
46
75
|
running: job.running ?? false,
|
|
47
76
|
nextRun: job.nextDate()?.toISO() ?? null,
|
|
48
77
|
history: this.storage.findByJob(name),
|
|
@@ -12,4 +12,6 @@ export declare class SchedulerDashModule implements NestModule, OnModuleInit {
|
|
|
12
12
|
configure(consumer: MiddlewareConsumer): void;
|
|
13
13
|
static forRoot(options?: SchedulerDashOptions): DynamicModule;
|
|
14
14
|
static forRootAsync(asyncOptions: SchedulerDashAsyncOptions): DynamicModule;
|
|
15
|
+
private normalizeRoute;
|
|
16
|
+
private escapeRegex;
|
|
15
17
|
}
|
|
@@ -36,11 +36,11 @@ let SchedulerDashModule = SchedulerDashModule_1 = class SchedulerDashModule {
|
|
|
36
36
|
scheduler_dash_context_1.SchedulerDashContext.storage = this.storage;
|
|
37
37
|
scheduler_dash_context_1.SchedulerDashContext.noOverlap = this.options.noOverlap ?? false;
|
|
38
38
|
scheduler_dash_context_1.SchedulerDashContext.maxConcurrent = this.options.maxConcurrent;
|
|
39
|
-
const route = (this.options.route
|
|
39
|
+
const route = this.normalizeRoute(this.options.route);
|
|
40
40
|
this.logger.log(`Dashboard available at /${route}`);
|
|
41
41
|
}
|
|
42
42
|
configure(consumer) {
|
|
43
|
-
const route = (this.options.route
|
|
43
|
+
const route = this.normalizeRoute(this.options.route);
|
|
44
44
|
const guard = (0, auth_1.createAuthGuard)(this.options.auth);
|
|
45
45
|
const svc = this.jobsService;
|
|
46
46
|
const router = express.Router({ mergeParams: true });
|
|
@@ -70,22 +70,27 @@ let SchedulerDashModule = SchedulerDashModule_1 = class SchedulerDashModule {
|
|
|
70
70
|
const ok = svc.stopExecution(req.params.id);
|
|
71
71
|
ok
|
|
72
72
|
? res.json({ stopped: req.params.id })
|
|
73
|
-
: res.status(404).json({
|
|
73
|
+
: res.status(404).json({
|
|
74
|
+
message: `Execution "${req.params.id}" not found or already finished`,
|
|
75
|
+
});
|
|
74
76
|
});
|
|
75
|
-
router.
|
|
77
|
+
router.use((_req, res) => {
|
|
76
78
|
res.sendFile('index.html', { root: PUBLIC_PATH });
|
|
77
79
|
});
|
|
78
80
|
consumer
|
|
79
81
|
.apply((req, res, next) => {
|
|
80
|
-
req.url =
|
|
82
|
+
req.url =
|
|
83
|
+
req.originalUrl.replace(new RegExp(`^/${this.escapeRegex(route)}(?=/|$)`), '') || '/';
|
|
81
84
|
router(req, res, next);
|
|
82
85
|
})
|
|
83
|
-
.forRoutes(
|
|
86
|
+
.forRoutes(route);
|
|
84
87
|
}
|
|
85
88
|
static forRoot(options = {}) {
|
|
86
89
|
const parsed = scheduler_dash_schema_1.SchedulerDashOptionsSchema.safeParse(options);
|
|
87
90
|
if (!parsed.success) {
|
|
88
|
-
throw new Error(`[SchedulerDash] Invalid options:\n${parsed.error.issues
|
|
91
|
+
throw new Error(`[SchedulerDash] Invalid options:\n${parsed.error.issues
|
|
92
|
+
.map(i => ` • ${i.path.join('.')}: ${i.message}`)
|
|
93
|
+
.join('\n')}`);
|
|
89
94
|
}
|
|
90
95
|
return {
|
|
91
96
|
module: SchedulerDashModule_1,
|
|
@@ -111,7 +116,9 @@ let SchedulerDashModule = SchedulerDashModule_1 = class SchedulerDashModule {
|
|
|
111
116
|
const options = await asyncOptions.useFactory(...args);
|
|
112
117
|
const parsed = scheduler_dash_schema_1.SchedulerDashOptionsSchema.safeParse(options);
|
|
113
118
|
if (!parsed.success) {
|
|
114
|
-
throw new Error(`[SchedulerDash] Invalid options:\n${parsed.error.issues
|
|
119
|
+
throw new Error(`[SchedulerDash] Invalid options:\n${parsed.error.issues
|
|
120
|
+
.map(i => ` • ${i.path.join('.')}: ${i.message}`)
|
|
121
|
+
.join('\n')}`);
|
|
115
122
|
}
|
|
116
123
|
return options;
|
|
117
124
|
},
|
|
@@ -126,6 +133,12 @@ let SchedulerDashModule = SchedulerDashModule_1 = class SchedulerDashModule {
|
|
|
126
133
|
],
|
|
127
134
|
};
|
|
128
135
|
}
|
|
136
|
+
normalizeRoute(route) {
|
|
137
|
+
return (route ?? '_scheduler').replace(/^\/+|\/+$/g, '');
|
|
138
|
+
}
|
|
139
|
+
escapeRegex(value) {
|
|
140
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
141
|
+
}
|
|
129
142
|
};
|
|
130
143
|
exports.SchedulerDashModule = SchedulerDashModule;
|
|
131
144
|
exports.SchedulerDashModule = SchedulerDashModule = SchedulerDashModule_1 = __decorate([
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@luisrodrigues/nestjs-scheduler-dashboard",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"description": "Dashboard for @nestjs/schedule — embedded UI, job history, metrics, stop/trigger controls",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -13,11 +13,18 @@
|
|
|
13
13
|
"dev": "tsc -p tsconfig.json --watch"
|
|
14
14
|
},
|
|
15
15
|
"peerDependencies": {
|
|
16
|
-
"@nestjs/common": "^10.0.0",
|
|
17
|
-
"@nestjs/core": "^10.0.0",
|
|
18
|
-
"@nestjs/schedule": "^4.0.0",
|
|
16
|
+
"@nestjs/common": "^8.0.0 || ^9.0.0 || ^10.0.0",
|
|
17
|
+
"@nestjs/core": "^8.0.0 || ^9.0.0 || ^10.0.0",
|
|
18
|
+
"@nestjs/schedule": "^2.0.0 || ^3.0.0 || ^4.0.0",
|
|
19
|
+
"reflect-metadata": "^0.1.13 || ^0.2.0",
|
|
20
|
+
"rxjs": "^7.0.0",
|
|
19
21
|
"express": "^4.0.0"
|
|
20
22
|
},
|
|
23
|
+
"peerDependenciesMeta": {
|
|
24
|
+
"reflect-metadata": { "optional": false },
|
|
25
|
+
"rxjs": { "optional": false },
|
|
26
|
+
"express": { "optional": false }
|
|
27
|
+
},
|
|
21
28
|
"devDependencies": {
|
|
22
29
|
"@nestjs/common": "^10.4.15",
|
|
23
30
|
"@nestjs/core": "^10.4.15",
|