@tsed/agenda 8.11.1 → 8.12.0-rc.1

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.
Files changed (41) hide show
  1. package/lib/esm/constants/constants.js +0 -1
  2. package/lib/esm/decorators/agenda.js +5 -2
  3. package/lib/esm/decorators/define.js +0 -1
  4. package/lib/esm/decorators/every.js +0 -1
  5. package/lib/esm/index.js +1 -3
  6. package/lib/esm/interfaces/AgendaStore.js +0 -1
  7. package/lib/esm/interfaces/interfaces.js +0 -1
  8. package/lib/esm/services/AgendaService.js +121 -0
  9. package/lib/types/decorators/agenda.d.ts +5 -1
  10. package/lib/types/index.d.ts +1 -2
  11. package/lib/types/interfaces/interfaces.d.ts +6 -8
  12. package/lib/types/services/AgendaService.d.ts +13 -0
  13. package/package.json +10 -7
  14. package/readme.md +28 -18
  15. package/lib/esm/AgendaModule.js +0 -132
  16. package/lib/esm/AgendaModule.js.map +0 -1
  17. package/lib/esm/constants/constants.js.map +0 -1
  18. package/lib/esm/decorators/agenda.js.map +0 -1
  19. package/lib/esm/decorators/define.js.map +0 -1
  20. package/lib/esm/decorators/every.js.map +0 -1
  21. package/lib/esm/index.js.map +0 -1
  22. package/lib/esm/interfaces/AgendaStore.js.map +0 -1
  23. package/lib/esm/interfaces/interfaces.js.map +0 -1
  24. package/lib/esm/services/AgendaFactory.js +0 -13
  25. package/lib/esm/services/AgendaFactory.js.map +0 -1
  26. package/lib/types/AgendaModule.d.ts +0 -24
  27. package/lib/types/services/AgendaFactory.d.ts +0 -3
  28. package/src/AgendaModule.spec.ts +0 -221
  29. package/src/AgendaModule.ts +0 -153
  30. package/src/constants/constants.ts +0 -1
  31. package/src/decorators/agenda.spec.ts +0 -22
  32. package/src/decorators/agenda.ts +0 -17
  33. package/src/decorators/define.spec.ts +0 -49
  34. package/src/decorators/define.ts +0 -15
  35. package/src/decorators/every.spec.ts +0 -37
  36. package/src/decorators/every.ts +0 -15
  37. package/src/index.ts +0 -11
  38. package/src/interfaces/AgendaStore.ts +0 -13
  39. package/src/interfaces/interfaces.ts +0 -16
  40. package/src/services/AgendaFactory.ts +0 -15
  41. package/vitest.config.mts +0 -25
@@ -1,2 +1 @@
1
1
  export const PROVIDER_TYPE_AGENDA = "PROVIDER_TYPE_AGENDA";
2
- //# sourceMappingURL=constants.js.map
@@ -1,9 +1,12 @@
1
1
  import { StoreMerge, useDecorators } from "@tsed/core";
2
2
  import { Injectable } from "@tsed/di";
3
3
  import { PROVIDER_TYPE_AGENDA } from "../constants/constants.js";
4
- export function Agenda(options) {
4
+ export function JobsController(options) {
5
5
  return useDecorators(options?.namespace && StoreMerge("agenda", options), Injectable({
6
6
  type: PROVIDER_TYPE_AGENDA
7
7
  }));
8
8
  }
9
- //# sourceMappingURL=agenda.js.map
9
+ /**
10
+ * @deprecated Use `JobsController` instead.
11
+ */
12
+ export const Agenda = JobsController;
@@ -9,4 +9,3 @@ export function Define(options = {}) {
9
9
  Store.from(target).merge("agenda", store);
10
10
  };
11
11
  }
12
- //# sourceMappingURL=define.js.map
@@ -10,4 +10,3 @@ export function Every(interval, options = {}) {
10
10
  Store.from(target).merge("agenda", store);
11
11
  });
12
12
  }
13
- //# sourceMappingURL=every.js.map
package/lib/esm/index.js CHANGED
@@ -1,12 +1,10 @@
1
1
  /**
2
2
  * @file Automatically generated by @tsed/barrels.
3
3
  */
4
- export * from "./AgendaModule.js";
5
4
  export * from "./constants/constants.js";
6
5
  export * from "./decorators/agenda.js";
7
6
  export * from "./decorators/define.js";
8
7
  export * from "./decorators/every.js";
9
8
  export * from "./interfaces/AgendaStore.js";
10
9
  export * from "./interfaces/interfaces.js";
11
- export * from "./services/AgendaFactory.js";
12
- //# sourceMappingURL=index.js.map
10
+ export * from "./services/AgendaService.js";
@@ -1,2 +1 @@
1
1
  export {};
2
- //# sourceMappingURL=AgendaStore.js.map
@@ -1,2 +1 @@
1
1
  export {};
2
- //# sourceMappingURL=interfaces.js.map
@@ -0,0 +1,121 @@
1
+ import { constant, DIContext, injectable, injector, logger, runInContext } from "@tsed/di";
2
+ import { $asyncEmit } from "@tsed/hooks";
3
+ import { Agenda } from "agenda";
4
+ import { v4 as uuid } from "uuid";
5
+ import { PROVIDER_TYPE_AGENDA } from "../constants/constants.js";
6
+ function getOpts() {
7
+ return constant("agenda", { enabled: false });
8
+ }
9
+ function addAgendaDefinitionsForProvider(agenda, provider) {
10
+ const store = provider.store.get("agenda", {});
11
+ if (!store.define) {
12
+ return;
13
+ }
14
+ Object.entries(store.define).forEach(([propertyKey, { name, ...options }]) => {
15
+ const instance = injector().get(provider.token);
16
+ const jobProcessor = instance[propertyKey].bind(instance);
17
+ const jobName = getNameForJob(propertyKey, store.namespace, name);
18
+ agenda.define(jobName, options, jobProcessor);
19
+ });
20
+ }
21
+ async function scheduleJobsForProvider(agenda, provider) {
22
+ const store = provider.store.get("agenda", {});
23
+ if (!store.every) {
24
+ return;
25
+ }
26
+ const promises = Object.entries(store.every).map(([propertyKey, { interval, name, ...options }]) => {
27
+ const jobName = getNameForJob(propertyKey, store.namespace, name);
28
+ return agenda.every(interval, jobName, {}, options);
29
+ });
30
+ await Promise.all(promises);
31
+ }
32
+ function getNameForJob(propertyKey, namespace, customName) {
33
+ const name = customName || propertyKey;
34
+ return namespace ? `${namespace}.${name}` : name;
35
+ }
36
+ async function afterListen(agenda) {
37
+ const opts = getOpts();
38
+ if (opts.enabled) {
39
+ const providers = injector().getProviders(PROVIDER_TYPE_AGENDA);
40
+ if (!opts.disableJobProcessing) {
41
+ logger().info({
42
+ event: "AGENDA_ADD_DEFINITIONS",
43
+ message: "Agenda add definitions"
44
+ });
45
+ providers.forEach((provider) => addAgendaDefinitionsForProvider(agenda, provider));
46
+ await $asyncEmit("$beforeAgendaStart");
47
+ }
48
+ await agenda.start();
49
+ if (!opts.disableJobProcessing) {
50
+ logger().info({
51
+ event: "AGENDA_ADD_JOBS",
52
+ message: "Agenda add scheduled jobs"
53
+ });
54
+ await Promise.all(providers.map((provider) => scheduleJobsForProvider(agenda, provider)));
55
+ await $asyncEmit("$afterAgendaStart");
56
+ }
57
+ }
58
+ }
59
+ async function onDestroy(agenda) {
60
+ const opts = getOpts();
61
+ if (opts.enabled) {
62
+ if (opts.drainJobsBeforeClose && "drain" in agenda) {
63
+ logger().info({
64
+ event: "AGENDA_DRAIN",
65
+ message: "Agenda is draining all jobs before close"
66
+ });
67
+ await agenda.drain();
68
+ }
69
+ else {
70
+ logger().info({
71
+ event: "AGENDA_STOP",
72
+ message: "Agenda is stopping"
73
+ });
74
+ await agenda.stop();
75
+ }
76
+ await agenda.close({ force: true });
77
+ logger().info({ event: "AGENDA_STOP", message: "Agenda stopped" });
78
+ }
79
+ }
80
+ export const AgendaService = injectable(Agenda)
81
+ .factory(() => {
82
+ const opts = getOpts();
83
+ if (opts.enabled) {
84
+ const agenda = new Agenda(opts);
85
+ return new Proxy(agenda, {
86
+ set(target, prop, value) {
87
+ return Reflect.set(target, prop, value);
88
+ },
89
+ get(target, prop) {
90
+ if (prop === "agenda") {
91
+ return target;
92
+ }
93
+ if (prop === "$define") {
94
+ return Reflect.get(target, "define", target);
95
+ }
96
+ if (prop === "define") {
97
+ return (name, options, processor) => {
98
+ return target["define"](name, options, (job) => {
99
+ const $ctx = new DIContext({
100
+ id: uuid()
101
+ });
102
+ $ctx.set("job", job);
103
+ return runInContext($ctx, () => processor(job));
104
+ });
105
+ };
106
+ }
107
+ return Reflect.get(target, prop, target);
108
+ }
109
+ });
110
+ }
111
+ return new Proxy({}, { get: () => () => Promise.resolve() });
112
+ })
113
+ .hooks({
114
+ $afterListen: afterListen,
115
+ $onDestroy: onDestroy
116
+ })
117
+ .token();
118
+ /**
119
+ * @deprecated Use `Agenda` from `agenda` instead.
120
+ */
121
+ export const AgendaModule = Agenda;
@@ -1,5 +1,9 @@
1
1
  interface AgendaOptions {
2
2
  namespace?: string;
3
3
  }
4
- export declare function Agenda(options?: AgendaOptions): ClassDecorator;
4
+ export declare function JobsController(options?: AgendaOptions): any;
5
+ /**
6
+ * @deprecated Use `JobsController` instead.
7
+ */
8
+ export declare const Agenda: typeof JobsController;
5
9
  export {};
@@ -1,11 +1,10 @@
1
1
  /**
2
2
  * @file Automatically generated by @tsed/barrels.
3
3
  */
4
- export * from "./AgendaModule.js";
5
4
  export * from "./constants/constants.js";
6
5
  export * from "./decorators/agenda.js";
7
6
  export * from "./decorators/define.js";
8
7
  export * from "./decorators/every.js";
9
8
  export * from "./interfaces/AgendaStore.js";
10
9
  export * from "./interfaces/interfaces.js";
11
- export * from "./services/AgendaFactory.js";
10
+ export * from "./services/AgendaService.js";
@@ -1,15 +1,13 @@
1
1
  import { AgendaConfig } from "agenda";
2
+ export type AgendaSettings = AgendaConfig & {
3
+ enabled?: boolean;
4
+ disableJobProcessing?: boolean;
5
+ drainJobsBeforeClose?: boolean;
6
+ };
2
7
  declare global {
3
8
  namespace TsED {
4
9
  interface Configuration {
5
- agenda?: {
6
- /**
7
- * Enable Agenda jobs. Default false.
8
- */
9
- enabled?: boolean;
10
- disableJobProcessing?: boolean;
11
- drainJobsBeforeClose?: boolean;
12
- } & AgendaConfig;
10
+ agenda?: AgendaSettings;
13
11
  }
14
12
  }
15
13
  }
@@ -0,0 +1,13 @@
1
+ import { Agenda } from "agenda";
2
+ export declare const AgendaService: {
3
+ readonly __type: "token_factory";
4
+ };
5
+ /**
6
+ * @deprecated Use `Agenda` from `agenda` instead.
7
+ */
8
+ export type AgendaService = Agenda;
9
+ /**
10
+ * @deprecated Use `Agenda` from `agenda` instead.
11
+ */
12
+ export declare const AgendaModule: typeof Agenda;
13
+ export type AgendaModule = Agenda;
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@tsed/agenda",
3
3
  "description": "Agenda package for Ts.ED framework",
4
4
  "type": "module",
5
- "version": "8.11.1",
5
+ "version": "8.12.0-rc.1",
6
6
  "source": "./src/index.ts",
7
7
  "main": "./lib/esm/index.js",
8
8
  "module": "./lib/esm/index.js",
@@ -26,11 +26,11 @@
26
26
  "tslib": "2.7.0"
27
27
  },
28
28
  "devDependencies": {
29
- "@tsed/barrels": "8.11.1",
30
- "@tsed/core": "8.11.1",
31
- "@tsed/di": "8.11.1",
32
- "@tsed/platform-http": "8.11.1",
33
- "@tsed/typescript": "8.11.1",
29
+ "@tsed/barrels": "8.12.0-rc.1",
30
+ "@tsed/core": "8.12.0-rc.1",
31
+ "@tsed/di": "8.12.0-rc.1",
32
+ "@tsed/platform-http": "8.12.0-rc.1",
33
+ "@tsed/typescript": "8.12.0-rc.1",
34
34
  "agenda": "^5.0.0",
35
35
  "eslint": "9.12.0",
36
36
  "typescript": "5.4.5",
@@ -45,5 +45,8 @@
45
45
  },
46
46
  "homepage": "https://github.com/tsedio/tsed/tree/production/packages/third-parties/agenda",
47
47
  "author": "Romain Lenzotti",
48
- "license": "MIT"
48
+ "license": "MIT",
49
+ "publishConfig": {
50
+ "tag": "rc"
51
+ }
49
52
  }
package/readme.md CHANGED
@@ -3,9 +3,9 @@
3
3
  </p>
4
4
 
5
5
  <div align="center">
6
-
6
+
7
7
  <h1>Agenda</h1>
8
-
8
+
9
9
  [![Build & Release](https://github.com/tsedio/tsed/workflows/Build%20&%20Release/badge.svg)](https://github.com/tsedio/tsed/actions?query=workflow%3A%22Build+%26+Release%22)
10
10
  [![PR Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/tsedio/tsed/blob/master/CONTRIBUTING.md)
11
11
  [![npm version](https://badge.fury.io/js/%40tsed%2Fcommon.svg)](https://badge.fury.io/js/%40tsed%2Fcommon)
@@ -84,10 +84,10 @@ Use the `@Define` decorator on methods that you would like to schedule
84
84
  programmatically via the AgendaService and Agenda instance access.
85
85
 
86
86
  ```ts
87
- import {Agenda, Every, Define} from "@tsed/agenda";
87
+ import {Every, Define, JobsController} from "@tsed/agenda";
88
88
  import {Job} from "agenda";
89
89
 
90
- @Agenda({namespace: "email"})
90
+ @JobsController({namespace: "email"})
91
91
  export class EmailJobService {
92
92
  @Every("60 minutes", {
93
93
  name: "maintenanceJob"
@@ -114,15 +114,17 @@ export class EmailJobService {
114
114
 
115
115
  ## Define a job processor manually
116
116
 
117
- Since Ts.ED 7.53.0, AgendaModule exposes methods to manually define a job processor. It can be useful to define a job processor when you need to fetch data beforehand and dynamically build job name / options.
117
+ Since Ts.ED 7.53.0, AgendaModule exposes methods to manually define a job processor. It can be useful to define a job
118
+ processor when you need to fetch data beforehand and dynamically build job name / options.
118
119
 
119
120
  ```typescript
120
- import {Agenda, AgendaModule, Define} from "@tsed/agenda";
121
+ import {Define, JobsController} from "@tsed/agenda";
122
+ import {Agenda} from "agenda";
121
123
 
122
- @Agenda({namespace: "email"})
124
+ @JobsController({namespace: "email"})
123
125
  export class EmailJobService {
124
126
  @Inject()
125
- agenda: AgendaModule;
127
+ agenda: Agenda;
126
128
 
127
129
  @Inject()
128
130
  httpClient: HttpClient;
@@ -163,15 +165,15 @@ export class EmailJobService {
163
165
  Inject the AgendaService instance to interact with it directly, e.g. to schedule
164
166
  a job manually.
165
167
 
166
- ```typescript
168
+ ```ts
167
169
  import {Service} from "@tsed/di";
168
170
  import {AfterRoutesInit} from "@tsed/platform-params";
169
- import {AgendaModule} from "@tsed/agenda";
171
+ import {Agenda} from "agenda";
170
172
 
171
173
  @Service()
172
174
  export class UsersService {
173
175
  @Inject()
174
- private agenda: AgendaModule;
176
+ private agenda: Agenda;
175
177
 
176
178
  async create(user: User): Promise<User> {
177
179
  // do something
@@ -187,7 +189,8 @@ export class UsersService {
187
189
 
188
190
  ## Using Agendash
189
191
 
190
- [Agendash](https://github.com/agenda/agendash) provides a job overview dashboard that makes it easy to manage, create and
192
+ [Agendash](https://github.com/agenda/agendash) provides a job overview dashboard that makes it easy to manage, create
193
+ and
191
194
  schedule your jobs.
192
195
 
193
196
  ::: tip Note
@@ -206,8 +209,7 @@ Afterward create the module `agendash.module.ts` in src/modules so that the dash
206
209
  import {AfterRoutesInit, PlatformApplication} from "@tsed/platform-http";
207
210
  import {Configuration, Inject, Module} from "@tsed/di";
208
211
  import {Agenda} from "agenda";
209
-
210
- const Agendash = require("agendash");
212
+ import Agendash from "agendash";
211
213
 
212
214
  @Module()
213
215
  export class AgendashModule implements AfterRoutesInit {
@@ -240,7 +242,8 @@ Thank you to all our backers! 🙏 [[Become a backer](https://opencollective.com
240
242
 
241
243
  ## Sponsors
242
244
 
243
- Support this project by becoming a sponsor. Your logo will show up here with a link to your website. [[Become a sponsor](https://opencollective.com/tsed#sponsor)]
245
+ Support this project by becoming a sponsor. Your logo will show up here with a link to your
246
+ website. [[Become a sponsor](https://opencollective.com/tsed#sponsor)]
244
247
 
245
248
  ## License
246
249
 
@@ -248,8 +251,15 @@ The MIT License (MIT)
248
251
 
249
252
  Copyright (c) 2016 - 2021 Romain Lenzotti
250
253
 
251
- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
254
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
255
+ documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
256
+ rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
257
+ persons to whom the Software is furnished to do so, subject to the following conditions:
252
258
 
253
- The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
259
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
260
+ Software.
254
261
 
255
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
262
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
263
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
264
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
265
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -1,132 +0,0 @@
1
- import { __decorate, __metadata } from "tslib";
2
- import { Constant, DIContext, Inject, InjectorService, Module, runInContext } from "@tsed/di";
3
- import { Logger } from "@tsed/logger";
4
- import { v4 as uuid } from "uuid";
5
- import { PROVIDER_TYPE_AGENDA } from "./constants/constants.js";
6
- import { AgendaService } from "./services/AgendaFactory.js";
7
- let AgendaModule = class AgendaModule {
8
- async $afterListen() {
9
- if (this.enabled) {
10
- const providers = this.getProviders();
11
- if (!this.disableJobProcessing) {
12
- this.logger.info({
13
- event: "AGENDA_ADD_DEFINITIONS",
14
- message: "Agenda add definitions"
15
- });
16
- providers.forEach((provider) => this.addAgendaDefinitionsForProvider(provider));
17
- await this.injector.emit("$beforeAgendaStart");
18
- }
19
- await this.agenda.start();
20
- if (!this.disableJobProcessing) {
21
- this.logger.info({
22
- event: "AGENDA_ADD_JOBS",
23
- message: "Agenda add scheduled jobs"
24
- });
25
- await Promise.all(providers.map((provider) => this.scheduleJobsForProvider(provider)));
26
- await this.injector.emit("$afterAgendaStart");
27
- }
28
- }
29
- }
30
- async $onDestroy() {
31
- if (this.enabled) {
32
- if (this.drainJobsBeforeClose && "drain" in this.agenda) {
33
- this.logger.info({
34
- event: "AGENDA_DRAIN",
35
- message: "Agenda is draining all jobs before close"
36
- });
37
- await this.agenda.drain();
38
- }
39
- else {
40
- this.logger.info({
41
- event: "AGENDA_STOP",
42
- message: "Agenda is stopping"
43
- });
44
- await this.agenda.stop();
45
- }
46
- await this.agenda.close({ force: true });
47
- this.logger.info({ event: "AGENDA_STOP", message: "Agenda stopped" });
48
- }
49
- }
50
- define(name, options, processor) {
51
- return this.agenda.define(name, options, (job) => {
52
- const $ctx = new DIContext({
53
- injector: this.injector,
54
- id: uuid(),
55
- logger: this.injector.logger
56
- });
57
- $ctx.set("job", job);
58
- return runInContext($ctx, () => processor(job));
59
- });
60
- }
61
- every(interval, name, data, options) {
62
- return this.agenda.every(interval, name, data, options);
63
- }
64
- schedule(when, name, data) {
65
- return this.agenda.schedule(when, name, data);
66
- }
67
- now(name, data) {
68
- return this.agenda.now(name, data);
69
- }
70
- create(name, data) {
71
- return this.agenda.create(name, data);
72
- }
73
- getProviders() {
74
- return this.injector.getProviders(PROVIDER_TYPE_AGENDA);
75
- }
76
- addAgendaDefinitionsForProvider(provider) {
77
- const store = provider.store.get("agenda", {});
78
- if (!store.define) {
79
- return;
80
- }
81
- Object.entries(store.define).forEach(([propertyKey, { name, ...options }]) => {
82
- const instance = this.injector.get(provider.token);
83
- const jobProcessor = instance[propertyKey].bind(instance);
84
- const jobName = this.getNameForJob(propertyKey, store.namespace, name);
85
- this.define(jobName, options, jobProcessor);
86
- });
87
- }
88
- async scheduleJobsForProvider(provider) {
89
- const store = provider.store.get("agenda", {});
90
- if (!store.every) {
91
- return;
92
- }
93
- const promises = Object.entries(store.every).map(([propertyKey, { interval, name, ...options }]) => {
94
- const jobName = this.getNameForJob(propertyKey, store.namespace, name);
95
- return this.every(interval, jobName, {}, options);
96
- });
97
- await Promise.all(promises);
98
- }
99
- getNameForJob(propertyKey, namespace, customName) {
100
- const name = customName || propertyKey;
101
- return namespace ? `${namespace}.${name}` : name;
102
- }
103
- };
104
- __decorate([
105
- Inject(),
106
- __metadata("design:type", Logger)
107
- ], AgendaModule.prototype, "logger", void 0);
108
- __decorate([
109
- Inject(),
110
- __metadata("design:type", InjectorService)
111
- ], AgendaModule.prototype, "injector", void 0);
112
- __decorate([
113
- Inject(),
114
- __metadata("design:type", AgendaService)
115
- ], AgendaModule.prototype, "agenda", void 0);
116
- __decorate([
117
- Constant("agenda.enabled", false),
118
- __metadata("design:type", Boolean)
119
- ], AgendaModule.prototype, "enabled", void 0);
120
- __decorate([
121
- Constant("agenda.drainJobsBeforeClose", false),
122
- __metadata("design:type", Boolean)
123
- ], AgendaModule.prototype, "drainJobsBeforeClose", void 0);
124
- __decorate([
125
- Constant("agenda.disableJobProcessing", false),
126
- __metadata("design:type", Boolean)
127
- ], AgendaModule.prototype, "disableJobProcessing", void 0);
128
- AgendaModule = __decorate([
129
- Module()
130
- ], AgendaModule);
131
- export { AgendaModule };
132
- //# sourceMappingURL=AgendaModule.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"AgendaModule.js","sourceRoot":"","sources":["../../src/AgendaModule.ts"],"names":[],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../src/constants/constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,oBAAoB,GAAG,sBAAsB,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"agenda.js","sourceRoot":"","sources":["../../../src/decorators/agenda.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAE,aAAa,EAAC,MAAM,YAAY,CAAC;AACrD,OAAO,EAAC,UAAU,EAAC,MAAM,UAAU,CAAC;AAEpC,OAAO,EAAC,oBAAoB,EAAC,MAAM,2BAA2B,CAAC;AAM/D,MAAM,UAAU,MAAM,CAAC,OAAuB;IAC5C,OAAO,aAAa,CAClB,OAAO,EAAE,SAAS,IAAI,UAAU,CAAC,QAAQ,EAAE,OAAO,CAAC,EACnD,UAAU,CAAC;QACT,IAAI,EAAE,oBAAoB;KAC3B,CAAC,CACH,CAAC;AACJ,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"define.js","sourceRoot":"","sources":["../../../src/decorators/define.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,KAAK,EAAC,MAAM,YAAY,CAAC;AAIjC,MAAM,UAAU,MAAM,CAAC,UAAyB,EAAE;IAChD,OAAO,CAAC,MAAW,EAAE,WAAmB,EAAE,EAAE;QAC1C,MAAM,KAAK,GAAgB;YACzB,MAAM,EAAE;gBACN,CAAC,WAAW,CAAC,EAAE,OAAO;aACvB;SACF,CAAC;QAEF,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IAC5C,CAAC,CAAC;AACJ,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"every.js","sourceRoot":"","sources":["../../../src/decorators/every.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,KAAK,EAAE,aAAa,EAAC,MAAM,YAAY,CAAC;AAGhD,OAAO,EAAC,MAAM,EAAC,MAAM,aAAa,CAAC;AAEnC,MAAM,UAAU,KAAK,CAAC,QAAgB,EAAE,UAAwB,EAAE;IAChE,OAAO,aAAa,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,MAAW,EAAE,WAAmB,EAAE,EAAE;QACzE,MAAM,KAAK,GAAgB;YACzB,KAAK,EAAE;gBACL,CAAC,WAAW,CAAC,EAAE,EAAC,GAAG,OAAO,EAAE,QAAQ,EAAC;aACtC;SACF,CAAC;QACF,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,cAAc,mBAAmB,CAAC;AAClC,cAAc,0BAA0B,CAAC;AACzC,cAAc,wBAAwB,CAAC;AACvC,cAAc,wBAAwB,CAAC;AACvC,cAAc,uBAAuB,CAAC;AACtC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,6BAA6B,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"AgendaStore.js","sourceRoot":"","sources":["../../../src/interfaces/AgendaStore.ts"],"names":[],"mappings":""}
@@ -1 +0,0 @@
1
- {"version":3,"file":"interfaces.js","sourceRoot":"","sources":["../../../src/interfaces/interfaces.ts"],"names":[],"mappings":""}
@@ -1,13 +0,0 @@
1
- import { Configuration, registerProvider } from "@tsed/di";
2
- import { Agenda } from "agenda";
3
- // create Alias to avoid confusing import between Agenda from "agenda" and Agenda decorator
4
- export const AgendaService = Agenda;
5
- registerProvider({
6
- token: Agenda,
7
- deps: [Configuration],
8
- useFactory(settings) {
9
- const opts = settings.get("agenda", { enabled: false });
10
- return opts.enabled ? new Agenda(opts) : {};
11
- }
12
- });
13
- //# sourceMappingURL=AgendaFactory.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"AgendaFactory.js","sourceRoot":"","sources":["../../../src/services/AgendaFactory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,aAAa,EAAE,gBAAgB,EAAC,MAAM,UAAU,CAAC;AACzD,OAAO,EAAC,MAAM,EAAe,MAAM,QAAQ,CAAC;AAE5C,2FAA2F;AAC3F,MAAM,CAAC,MAAM,aAAa,GAAG,MAAM,CAAC;AAGpC,gBAAgB,CAAC;IACf,KAAK,EAAE,MAAM;IACb,IAAI,EAAE,CAAC,aAAa,CAAC;IACrB,UAAU,CAAC,QAAuB;QAChC,MAAM,IAAI,GAAG,QAAQ,CAAC,GAAG,CAAoC,QAAQ,EAAE,EAAC,OAAO,EAAE,KAAK,EAAC,CAAC,CAAC;QACzF,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC9C,CAAC;CACF,CAAC,CAAC"}
@@ -1,24 +0,0 @@
1
- import { InjectorService, OnDestroy, Provider } from "@tsed/di";
2
- import { Logger } from "@tsed/logger";
3
- import { AfterListen } from "@tsed/platform-http";
4
- import { Job } from "agenda";
5
- import { AgendaService } from "./services/AgendaFactory.js";
6
- export declare class AgendaModule implements OnDestroy, AfterListen {
7
- protected logger: Logger;
8
- protected injector: InjectorService;
9
- protected agenda: AgendaService;
10
- private enabled;
11
- private drainJobsBeforeClose;
12
- private disableJobProcessing;
13
- $afterListen(): Promise<any>;
14
- $onDestroy(): Promise<any>;
15
- define(name: string, options?: any, processor?: any): void;
16
- every(interval: string, name: string, data?: any, options?: any): Promise<any>;
17
- schedule(when: Date | string, name: string, data?: any): Promise<Job<import("agenda").JobAttributesData>>;
18
- now(name: string, data?: any): Promise<Job<import("agenda").JobAttributesData>>;
19
- create(name: string, data?: any): Job<import("agenda").JobAttributesData>;
20
- protected getProviders(): Provider<any>[];
21
- protected addAgendaDefinitionsForProvider(provider: Provider): void;
22
- protected scheduleJobsForProvider(provider: Provider<any>): Promise<void>;
23
- protected getNameForJob(propertyKey: string, namespace?: string, customName?: string): string;
24
- }
@@ -1,3 +0,0 @@
1
- import { Agenda } from "agenda";
2
- export declare const AgendaService: typeof Agenda;
3
- export type AgendaService = Agenda;
@@ -1,221 +0,0 @@
1
- import {Inject} from "@tsed/di";
2
- import {PlatformTest} from "@tsed/platform-http/testing";
3
- import type {Job} from "agenda";
4
-
5
- import {AgendaModule} from "./AgendaModule.js";
6
- import {Agenda} from "./decorators/agenda.js";
7
- import {Define} from "./decorators/define.js";
8
- import {Every} from "./decorators/every.js";
9
-
10
- vi.mock("agenda", () => {
11
- return {
12
- Agenda: class {
13
- close = vi.fn();
14
- stop = vi.fn();
15
- drain = vi.fn();
16
- define = vi.fn();
17
- every = vi.fn();
18
- schedule = vi.fn();
19
- now = vi.fn();
20
- create = vi.fn().mockReturnValue({
21
- repeatEvery: vi.fn().mockReturnThis(),
22
- save: vi.fn()
23
- });
24
- start = vi.fn();
25
- }
26
- };
27
- });
28
-
29
- @Agenda({namespace: "test-nsp"})
30
- class CustomCampaign {
31
- @Inject()
32
- agenda: AgendaModule;
33
-
34
- job: Job;
35
-
36
- $beforeAgendaStart() {
37
- this.job = this.agenda.create("customName2", {
38
- locale: "fr-FR"
39
- });
40
- }
41
-
42
- $afterAgendaStart() {
43
- return this.job.repeatEvery("1 week").save();
44
- }
45
-
46
- @Every("60 seconds")
47
- test(job: Job) {
48
- // test
49
- return "hello " + job.attrs.name;
50
- }
51
-
52
- @Define({name: "customName"})
53
- test2(job: Job) {
54
- // test
55
- return "hello " + job.attrs.name;
56
- }
57
-
58
- @Define({name: "customName2"})
59
- test3() {
60
- // test
61
- }
62
- }
63
-
64
- @Agenda({namespace: "test-nsp-2"})
65
- class CustomCampaign2 {
66
- @Define({name: "customName"})
67
- test(job: Job) {
68
- // test
69
- return "hello " + job.attrs.name;
70
- }
71
- }
72
-
73
- @Agenda({namespace: "test-nsp-3"})
74
- class CustomCampaign3 {}
75
-
76
- describe("AgendaModule", () => {
77
- describe("when agenda is enabled", () => {
78
- beforeEach(() =>
79
- PlatformTest.create({
80
- agenda: {
81
- enabled: true
82
- }
83
- })
84
- );
85
- afterEach(() => PlatformTest.reset());
86
-
87
- describe("$afterListen()", () => {
88
- it("should load all jobs", async () => {
89
- const agendaModule = PlatformTest.get<any>(AgendaModule)!;
90
- const campaign = PlatformTest.get<CustomCampaign>(CustomCampaign)!;
91
-
92
- await agendaModule.$afterListen();
93
-
94
- expect(agendaModule.agenda.define).toHaveBeenCalledWith("test-nsp.test", {}, expect.any(Function));
95
- expect(agendaModule.agenda.every).toHaveBeenCalledWith("60 seconds", "test-nsp.test", {}, {});
96
- expect(agendaModule.agenda.start).toHaveBeenCalledWith();
97
- expect(agendaModule.agenda.create).toHaveBeenCalledWith("customName2", {locale: "fr-FR"});
98
-
99
- expect(campaign.job.repeatEvery).toHaveBeenCalledWith("1 week");
100
- expect(campaign.job.save).toHaveBeenCalledWith();
101
-
102
- const result = await agendaModule.agenda.define.mock.calls[0][2]({
103
- attrs: {
104
- name: "test-nsp.test"
105
- }
106
- });
107
-
108
- expect(result).toEqual("hello test-nsp.test");
109
- });
110
- });
111
- describe("schedule()", () => {
112
- it("should schedule a job", async () => {
113
- const agendaModule = PlatformTest.get<any>(AgendaModule)!;
114
-
115
- await agendaModule.schedule("now", "test-nsp.test", {});
116
-
117
- expect(agendaModule.agenda.schedule).toHaveBeenCalledWith("now", "test-nsp.test", {});
118
- });
119
- });
120
-
121
- describe("now()", () => {
122
- it("should schedule a job", async () => {
123
- const agendaModule = PlatformTest.get<any>(AgendaModule)!;
124
-
125
- await agendaModule.now("test-nsp.test", {});
126
-
127
- expect(agendaModule.agenda.now).toHaveBeenCalledWith("test-nsp.test", {});
128
- });
129
- });
130
- describe("$onDestroy()", () => {
131
- it("should close agenda", async () => {
132
- const agendaModule = PlatformTest.get<any>(AgendaModule)!;
133
-
134
- await agendaModule.$onDestroy();
135
-
136
- expect(agendaModule.agenda.stop).toHaveBeenCalledWith();
137
- expect(agendaModule.agenda.close).toHaveBeenCalledWith({force: true});
138
- });
139
- });
140
- });
141
- describe("when agenda is enabled and drainJobsBeforeClose = true", () => {
142
- beforeEach(() =>
143
- PlatformTest.create({
144
- agenda: {
145
- enabled: true,
146
- drainJobsBeforeClose: true
147
- }
148
- })
149
- );
150
- afterEach(() => PlatformTest.reset());
151
- describe("$onDestroy()", () => {
152
- it("should close agenda", async () => {
153
- const agendaModule = PlatformTest.get<any>(AgendaModule)!;
154
-
155
- await agendaModule.$onDestroy();
156
-
157
- expect(agendaModule.agenda.drain).toHaveBeenCalledWith();
158
- expect(agendaModule.agenda.close).toHaveBeenCalledWith({force: true});
159
- });
160
- });
161
- });
162
- describe("when agenda is enabled but disableJobProcessing = true", () => {
163
- beforeEach(() =>
164
- PlatformTest.create({
165
- agenda: {
166
- enabled: true,
167
- disableJobProcessing: true
168
- }
169
- })
170
- );
171
- afterEach(() => PlatformTest.reset());
172
-
173
- describe("$afterListen()", () => {
174
- it("should load all jobs", async () => {
175
- const agendaModule = PlatformTest.get<any>(AgendaModule)!;
176
- const campaign = PlatformTest.get<CustomCampaign>(CustomCampaign)!;
177
-
178
- await agendaModule.$afterListen();
179
-
180
- expect(agendaModule.agenda.define).not.toHaveBeenCalled();
181
- expect(agendaModule.agenda.every).not.toHaveBeenCalled();
182
- expect(agendaModule.agenda.start).toHaveBeenCalledWith();
183
- expect(agendaModule.agenda.create).not.toHaveBeenCalled();
184
-
185
- expect(campaign.job).toBeUndefined();
186
- });
187
- });
188
- });
189
-
190
- describe("when agenda is disabled", () => {
191
- beforeEach(() =>
192
- PlatformTest.create({
193
- agenda: {
194
- enabled: false
195
- }
196
- })
197
- );
198
- afterEach(() => PlatformTest.reset());
199
-
200
- describe("$afterListen()", () => {
201
- it("should load all jobs", async () => {
202
- const agendaModule = PlatformTest.get<any>(AgendaModule)!;
203
- const campaign = PlatformTest.get<CustomCampaign>(CustomCampaign)!;
204
-
205
- await agendaModule.$afterListen();
206
-
207
- expect(agendaModule.agenda.define).toBeUndefined();
208
-
209
- expect(campaign.job).toBeUndefined();
210
- });
211
- });
212
-
213
- describe("$onDestroy()", () => {
214
- it("should do nothing", async () => {
215
- const agendaModule = PlatformTest.get<any>(AgendaModule)!;
216
-
217
- await agendaModule.$onDestroy();
218
- });
219
- });
220
- });
221
- });
@@ -1,153 +0,0 @@
1
- import {Constant, DIContext, Inject, InjectorService, Module, OnDestroy, Provider, runInContext} from "@tsed/di";
2
- import {Logger} from "@tsed/logger";
3
- import {AfterListen} from "@tsed/platform-http";
4
- import {Job, Processor} from "agenda";
5
- import {v4 as uuid} from "uuid";
6
-
7
- import {PROVIDER_TYPE_AGENDA} from "./constants/constants.js";
8
- import {AgendaStore} from "./interfaces/AgendaStore.js";
9
- import {AgendaService} from "./services/AgendaFactory.js";
10
-
11
- @Module()
12
- export class AgendaModule implements OnDestroy, AfterListen {
13
- @Inject()
14
- protected logger: Logger;
15
-
16
- @Inject()
17
- protected injector: InjectorService;
18
-
19
- @Inject()
20
- protected agenda: AgendaService;
21
-
22
- @Constant("agenda.enabled", false)
23
- private enabled: boolean;
24
-
25
- @Constant("agenda.drainJobsBeforeClose", false)
26
- private drainJobsBeforeClose: boolean;
27
-
28
- @Constant("agenda.disableJobProcessing", false)
29
- private disableJobProcessing: boolean;
30
-
31
- async $afterListen(): Promise<any> {
32
- if (this.enabled) {
33
- const providers = this.getProviders();
34
-
35
- if (!this.disableJobProcessing) {
36
- this.logger.info({
37
- event: "AGENDA_ADD_DEFINITIONS",
38
- message: "Agenda add definitions"
39
- });
40
- providers.forEach((provider) => this.addAgendaDefinitionsForProvider(provider));
41
-
42
- await this.injector.emit("$beforeAgendaStart");
43
- }
44
-
45
- await this.agenda.start();
46
-
47
- if (!this.disableJobProcessing) {
48
- this.logger.info({
49
- event: "AGENDA_ADD_JOBS",
50
- message: "Agenda add scheduled jobs"
51
- });
52
- await Promise.all(providers.map((provider) => this.scheduleJobsForProvider(provider)));
53
-
54
- await this.injector.emit("$afterAgendaStart");
55
- }
56
- }
57
- }
58
-
59
- async $onDestroy(): Promise<any> {
60
- if (this.enabled) {
61
- if (this.drainJobsBeforeClose && "drain" in this.agenda) {
62
- this.logger.info({
63
- event: "AGENDA_DRAIN",
64
- message: "Agenda is draining all jobs before close"
65
- });
66
- await this.agenda.drain();
67
- } else {
68
- this.logger.info({
69
- event: "AGENDA_STOP",
70
- message: "Agenda is stopping"
71
- });
72
- await this.agenda.stop();
73
- }
74
-
75
- await this.agenda.close({force: true});
76
-
77
- this.logger.info({event: "AGENDA_STOP", message: "Agenda stopped"});
78
- }
79
- }
80
-
81
- define(name: string, options?: any, processor?: any) {
82
- return this.agenda.define(name, options, (job: Job) => {
83
- const $ctx = new DIContext({
84
- injector: this.injector,
85
- id: uuid(),
86
- logger: this.injector.logger
87
- });
88
-
89
- $ctx.set("job", job);
90
-
91
- return runInContext($ctx, () => processor(job));
92
- });
93
- }
94
-
95
- every(interval: string, name: string, data?: any, options?: any) {
96
- return this.agenda.every(interval, name, data, options);
97
- }
98
-
99
- schedule(when: Date | string, name: string, data?: any) {
100
- return this.agenda.schedule(when, name, data);
101
- }
102
-
103
- now(name: string, data?: any) {
104
- return this.agenda.now(name, data);
105
- }
106
-
107
- create(name: string, data?: any) {
108
- return this.agenda.create(name, data);
109
- }
110
-
111
- protected getProviders(): Provider<any>[] {
112
- return this.injector.getProviders(PROVIDER_TYPE_AGENDA);
113
- }
114
-
115
- protected addAgendaDefinitionsForProvider(provider: Provider): void {
116
- const store = provider.store.get<AgendaStore>("agenda", {});
117
-
118
- if (!store.define) {
119
- return;
120
- }
121
-
122
- Object.entries(store.define).forEach(([propertyKey, {name, ...options}]) => {
123
- const instance = this.injector.get(provider.token);
124
-
125
- const jobProcessor: Processor<unknown> = instance[propertyKey].bind(instance) as Processor<unknown>;
126
- const jobName = this.getNameForJob(propertyKey, store.namespace, name);
127
-
128
- this.define(jobName, options, jobProcessor);
129
- });
130
- }
131
-
132
- protected async scheduleJobsForProvider(provider: Provider<any>): Promise<void> {
133
- const store = provider.store.get<AgendaStore>("agenda", {});
134
-
135
- if (!store.every) {
136
- return;
137
- }
138
-
139
- const promises = Object.entries(store.every).map(([propertyKey, {interval, name, ...options}]) => {
140
- const jobName = this.getNameForJob(propertyKey, store.namespace, name);
141
-
142
- return this.every(interval, jobName, {}, options);
143
- });
144
-
145
- await Promise.all(promises);
146
- }
147
-
148
- protected getNameForJob(propertyKey: string, namespace?: string, customName?: string): string {
149
- const name = customName || propertyKey;
150
-
151
- return namespace ? `${namespace}.${name}` : name;
152
- }
153
- }
@@ -1 +0,0 @@
1
- export const PROVIDER_TYPE_AGENDA = "PROVIDER_TYPE_AGENDA";
@@ -1,22 +0,0 @@
1
- import {Store} from "@tsed/core";
2
-
3
- import {Agenda} from "./agenda.js";
4
-
5
- describe("@Agenda()", () => {
6
- it("should set empty metadata", () => {
7
- @Agenda()
8
- class Test {}
9
-
10
- const store = Store.from(Test);
11
- expect(store.get("agenda")).toEqual(undefined);
12
- });
13
- it("should set namespace metadata", () => {
14
- @Agenda({namespace: "nsp1"})
15
- class Test {}
16
-
17
- const store = Store.from(Test);
18
- expect(store.get("agenda")).toEqual({
19
- namespace: "nsp1"
20
- });
21
- });
22
- });
@@ -1,17 +0,0 @@
1
- import {StoreMerge, useDecorators} from "@tsed/core";
2
- import {Injectable} from "@tsed/di";
3
-
4
- import {PROVIDER_TYPE_AGENDA} from "../constants/constants.js";
5
-
6
- interface AgendaOptions {
7
- namespace?: string;
8
- }
9
-
10
- export function Agenda(options?: AgendaOptions): ClassDecorator {
11
- return useDecorators(
12
- options?.namespace && StoreMerge("agenda", options),
13
- Injectable({
14
- type: PROVIDER_TYPE_AGENDA
15
- })
16
- );
17
- }
@@ -1,49 +0,0 @@
1
- import {Store} from "@tsed/core";
2
-
3
- import {Agenda} from "./agenda.js";
4
- import {Define} from "./define.js";
5
-
6
- describe("@Define()", () => {
7
- it("should set empty metadata", () => {
8
- @Agenda()
9
- class Test {
10
- @Define()
11
- testDefineDecorator() {
12
- // test
13
- }
14
-
15
- @Define()
16
- testDefineDecorator2() {
17
- // test 2
18
- }
19
- }
20
-
21
- const store = Store.from(Test);
22
-
23
- expect(store.get("agenda").define).toEqual({
24
- testDefineDecorator: {},
25
- testDefineDecorator2: {}
26
- });
27
- });
28
-
29
- it("should set options metadata", () => {
30
- @Agenda()
31
- class Test {
32
- @Define({
33
- name: "testDefineDecoratorCustomName",
34
- priority: 20
35
- })
36
- test() {
37
- // test
38
- }
39
- }
40
-
41
- const store = Store.from(Test);
42
- expect(store.get("agenda").define).toEqual({
43
- test: {
44
- name: "testDefineDecoratorCustomName",
45
- priority: 20
46
- }
47
- });
48
- });
49
- });
@@ -1,15 +0,0 @@
1
- import {Store} from "@tsed/core";
2
-
3
- import {AgendaStore, DefineOptions} from "../interfaces/AgendaStore.js";
4
-
5
- export function Define(options: DefineOptions = {}): MethodDecorator {
6
- return (target: any, propertyKey: string) => {
7
- const store: AgendaStore = {
8
- define: {
9
- [propertyKey]: options
10
- }
11
- };
12
-
13
- Store.from(target).merge("agenda", store);
14
- };
15
- }
@@ -1,37 +0,0 @@
1
- import {descriptorOf, Store} from "@tsed/core";
2
-
3
- import {Agenda} from "./agenda.js";
4
- import {Every} from "./every.js";
5
-
6
- describe("@Every()", () => {
7
- it("should set metadata", () => {
8
- @Agenda()
9
- class Test {
10
- @Every("60 seconds")
11
- testEveryDecorator() {
12
- // test
13
- }
14
-
15
- @Every("* * * * *")
16
- testEveryDecorator2() {
17
- // test 2
18
- }
19
- }
20
-
21
- const store = Store.from(Test);
22
-
23
- expect(store.get("agenda").define).toEqual({
24
- testEveryDecorator: {},
25
- testEveryDecorator2: {}
26
- });
27
-
28
- expect(store.get("agenda").every).toEqual({
29
- testEveryDecorator: {
30
- interval: "60 seconds"
31
- },
32
- testEveryDecorator2: {
33
- interval: "* * * * *"
34
- }
35
- });
36
- });
37
- });
@@ -1,15 +0,0 @@
1
- import {Store, useDecorators} from "@tsed/core";
2
-
3
- import {AgendaStore, EveryOptions} from "../interfaces/AgendaStore.js";
4
- import {Define} from "./define.js";
5
-
6
- export function Every(interval: string, options: EveryOptions = {}): MethodDecorator {
7
- return useDecorators(Define(options), (target: any, propertyKey: string) => {
8
- const store: AgendaStore = {
9
- every: {
10
- [propertyKey]: {...options, interval}
11
- }
12
- };
13
- Store.from(target).merge("agenda", store);
14
- });
15
- }
package/src/index.ts DELETED
@@ -1,11 +0,0 @@
1
- /**
2
- * @file Automatically generated by @tsed/barrels.
3
- */
4
- export * from "./AgendaModule.js";
5
- export * from "./constants/constants.js";
6
- export * from "./decorators/agenda.js";
7
- export * from "./decorators/define.js";
8
- export * from "./decorators/every.js";
9
- export * from "./interfaces/AgendaStore.js";
10
- export * from "./interfaces/interfaces.js";
11
- export * from "./services/AgendaFactory.js";
@@ -1,13 +0,0 @@
1
- import {DefineOptions as AgendaDefineOptions, JobOptions} from "agenda";
2
-
3
- export interface DefineOptions extends AgendaDefineOptions {
4
- name?: string;
5
- }
6
-
7
- export type EveryOptions = JobOptions & DefineOptions;
8
-
9
- export interface AgendaStore {
10
- namespace?: string;
11
- define?: {[propertyKey: string]: DefineOptions};
12
- every?: {[propertyKey: string]: EveryOptions & {interval: string}};
13
- }
@@ -1,16 +0,0 @@
1
- import {AgendaConfig} from "agenda";
2
-
3
- declare global {
4
- namespace TsED {
5
- interface Configuration {
6
- agenda?: {
7
- /**
8
- * Enable Agenda jobs. Default false.
9
- */
10
- enabled?: boolean;
11
- disableJobProcessing?: boolean;
12
- drainJobsBeforeClose?: boolean;
13
- } & AgendaConfig;
14
- }
15
- }
16
- }
@@ -1,15 +0,0 @@
1
- import {Configuration, registerProvider} from "@tsed/di";
2
- import {Agenda, AgendaConfig} from "agenda";
3
-
4
- // create Alias to avoid confusing import between Agenda from "agenda" and Agenda decorator
5
- export const AgendaService = Agenda;
6
- export type AgendaService = Agenda;
7
-
8
- registerProvider({
9
- token: Agenda,
10
- deps: [Configuration],
11
- useFactory(settings: Configuration) {
12
- const opts = settings.get<AgendaConfig & {enabled: boolean}>("agenda", {enabled: false});
13
- return opts.enabled ? new Agenda(opts) : {};
14
- }
15
- });
package/vitest.config.mts DELETED
@@ -1,25 +0,0 @@
1
- // @ts-ignore
2
- import {presets} from "@tsed/vitest/presets";
3
- import {defineConfig} from "vitest/config";
4
-
5
- export default defineConfig(
6
- {
7
- ...presets,
8
- test: {
9
- ...presets.test,
10
- // @ts-ignore
11
- globalSetup: [
12
- "../../orm/testcontainers-mongo/src/setup/vi.setup.ts"
13
- ],
14
- coverage: {
15
- ...presets.test.coverage,
16
- thresholds: {
17
- statements: 0,
18
- branches: 0,
19
- functions: 0,
20
- lines: 0
21
- }
22
- }
23
- }
24
- }
25
- );