@monque/tsed 0.1.0 → 1.1.0
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 +22 -22
- package/dist/CHANGELOG.md +31 -0
- package/dist/README.md +22 -22
- package/dist/index.cjs +105 -91
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +77 -63
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +78 -64
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +101 -88
- package/dist/index.mjs.map +1 -1
- package/package.json +16 -16
- package/src/config/config.ts +4 -2
- package/src/config/types.ts +35 -2
- package/src/constants/constants.ts +1 -1
- package/src/constants/types.ts +3 -3
- package/src/decorators/cron.ts +5 -5
- package/src/decorators/index.ts +5 -5
- package/src/decorators/{worker-controller.ts → job-controller.ts} +14 -14
- package/src/decorators/{worker.ts → job.ts} +14 -14
- package/src/decorators/types.ts +18 -18
- package/src/index.ts +7 -7
- package/src/monque-module.ts +23 -18
- package/src/utils/build-job-name.ts +2 -2
- package/src/utils/collect-job-metadata.ts +95 -0
- package/src/utils/get-job-token.ts +29 -0
- package/src/utils/index.ts +4 -4
- package/src/utils/resolve-database.ts +6 -5
- package/src/utils/collect-worker-metadata.ts +0 -95
- package/src/utils/get-worker-token.ts +0 -27
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Collect job metadata utility
|
|
3
|
+
*
|
|
4
|
+
* Collects all job metadata from a class decorated with @JobController.
|
|
5
|
+
* Used by MonqueModule to discover and register all jobs.
|
|
6
|
+
*/
|
|
7
|
+
import { Store } from '@tsed/core';
|
|
8
|
+
|
|
9
|
+
import { MONQUE } from '@/constants';
|
|
10
|
+
import type { CronDecoratorOptions, JobDecoratorOptions, JobStore } from '@/decorators';
|
|
11
|
+
|
|
12
|
+
import { buildJobName } from './build-job-name.js';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Collected job registration info ready for Monque.register()
|
|
16
|
+
*/
|
|
17
|
+
export interface CollectedJobMetadata {
|
|
18
|
+
/**
|
|
19
|
+
* Full job name (with namespace prefix if applicable)
|
|
20
|
+
*/
|
|
21
|
+
fullName: string;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Method name on the controller class
|
|
25
|
+
*/
|
|
26
|
+
method: string;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Job options to pass to Monque.register()
|
|
30
|
+
*/
|
|
31
|
+
opts: JobDecoratorOptions | CronDecoratorOptions;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Whether this is a cron job
|
|
35
|
+
*/
|
|
36
|
+
isCron: boolean;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Cron pattern (only for cron jobs)
|
|
40
|
+
*/
|
|
41
|
+
cronPattern?: string;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Collect all job metadata from a class.
|
|
46
|
+
*
|
|
47
|
+
* @param target - The class constructor (decorated with @JobController)
|
|
48
|
+
* @returns Array of collected job metadata ready for registration
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* ```typescript
|
|
52
|
+
* const metadata = collectJobMetadata(EmailJobs);
|
|
53
|
+
* // Returns:
|
|
54
|
+
* // [
|
|
55
|
+
* // { fullName: "email.send", method: "sendEmail", opts: {}, isCron: false },
|
|
56
|
+
* // { fullName: "email.daily-digest", method: "sendDailyDigest", opts: {}, isCron: true, cronPattern: "0 9 * * *" }
|
|
57
|
+
* // ]
|
|
58
|
+
* ```
|
|
59
|
+
*/
|
|
60
|
+
export function collectJobMetadata(
|
|
61
|
+
target: new (...args: unknown[]) => unknown,
|
|
62
|
+
): CollectedJobMetadata[] {
|
|
63
|
+
const store = Store.from(target);
|
|
64
|
+
const jobStore = store.get<JobStore>(MONQUE);
|
|
65
|
+
|
|
66
|
+
if (!jobStore) {
|
|
67
|
+
return [];
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const results: CollectedJobMetadata[] = [];
|
|
71
|
+
const namespace = jobStore.namespace;
|
|
72
|
+
|
|
73
|
+
// Collect regular jobs
|
|
74
|
+
for (const job of jobStore.jobs) {
|
|
75
|
+
results.push({
|
|
76
|
+
fullName: buildJobName(namespace, job.name),
|
|
77
|
+
method: job.method,
|
|
78
|
+
opts: job.opts,
|
|
79
|
+
isCron: false,
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Collect cron jobs
|
|
84
|
+
for (const cron of jobStore.cronJobs) {
|
|
85
|
+
results.push({
|
|
86
|
+
fullName: buildJobName(namespace, cron.name),
|
|
87
|
+
method: cron.method,
|
|
88
|
+
opts: cron.opts,
|
|
89
|
+
isCron: true,
|
|
90
|
+
cronPattern: cron.pattern,
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return results;
|
|
95
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generate a unique token for a job controller.
|
|
3
|
+
*
|
|
4
|
+
* Used internally by Ts.ED DI to identify job controller providers.
|
|
5
|
+
* The token is based on the class name for debugging purposes.
|
|
6
|
+
*
|
|
7
|
+
* @param target - The class constructor
|
|
8
|
+
* @returns A Symbol token unique to this job controller
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```typescript
|
|
12
|
+
* @JobController("email")
|
|
13
|
+
* class EmailJobs {}
|
|
14
|
+
*
|
|
15
|
+
* const token = getJobToken(EmailJobs);
|
|
16
|
+
* // Symbol("monque:job:EmailJobs")
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
import { MonqueError } from '@monque/core';
|
|
20
|
+
|
|
21
|
+
export function getJobToken(target: new (...args: unknown[]) => unknown): symbol {
|
|
22
|
+
const name = target.name?.trim();
|
|
23
|
+
|
|
24
|
+
if (!name) {
|
|
25
|
+
throw new MonqueError('Job class must have a non-empty name');
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return Symbol.for(`monque:job:${name}`);
|
|
29
|
+
}
|
package/src/utils/index.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
export { buildJobName } from './build-job-name.js';
|
|
2
2
|
export {
|
|
3
|
-
type
|
|
4
|
-
|
|
5
|
-
} from './collect-
|
|
6
|
-
export {
|
|
3
|
+
type CollectedJobMetadata,
|
|
4
|
+
collectJobMetadata,
|
|
5
|
+
} from './collect-job-metadata.js';
|
|
6
|
+
export { getJobToken } from './get-job-token.js';
|
|
7
7
|
export {
|
|
8
8
|
isMongooseConnection,
|
|
9
9
|
isMongooseService,
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* Multi-strategy database resolution for flexible MongoDB connection handling.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
+
import { ConnectionError } from '@monque/core';
|
|
7
8
|
import type { TokenProvider } from '@tsed/di';
|
|
8
9
|
import type { Db } from 'mongodb';
|
|
9
10
|
|
|
@@ -66,7 +67,7 @@ export async function resolveDatabase(
|
|
|
66
67
|
// Strategy 3: DI token resolution
|
|
67
68
|
if (config.dbToken) {
|
|
68
69
|
if (!injectorFn) {
|
|
69
|
-
throw new
|
|
70
|
+
throw new ConnectionError(
|
|
70
71
|
'MonqueTsedConfig.dbToken requires an injector function to resolve the database',
|
|
71
72
|
);
|
|
72
73
|
}
|
|
@@ -74,7 +75,7 @@ export async function resolveDatabase(
|
|
|
74
75
|
const resolved = injectorFn(config.dbToken);
|
|
75
76
|
|
|
76
77
|
if (!resolved) {
|
|
77
|
-
throw new
|
|
78
|
+
throw new ConnectionError(
|
|
78
79
|
`Could not resolve database from token: ${String(config.dbToken)}. ` +
|
|
79
80
|
'Make sure the provider is registered in the DI container.',
|
|
80
81
|
);
|
|
@@ -87,7 +88,7 @@ export async function resolveDatabase(
|
|
|
87
88
|
const connection = resolved.get(connectionId);
|
|
88
89
|
|
|
89
90
|
if (!connection) {
|
|
90
|
-
throw new
|
|
91
|
+
throw new ConnectionError(
|
|
91
92
|
`MongooseService resolved from token "${String(config.dbToken)}" returned no connection for ID "${connectionId}". ` +
|
|
92
93
|
'Ensure the connection ID is correct and the connection is established.',
|
|
93
94
|
);
|
|
@@ -106,7 +107,7 @@ export async function resolveDatabase(
|
|
|
106
107
|
|
|
107
108
|
// Default: Assume it is a native Db instance
|
|
108
109
|
if (typeof resolved !== 'object' || resolved === null || !('collection' in resolved)) {
|
|
109
|
-
throw new
|
|
110
|
+
throw new ConnectionError(
|
|
110
111
|
`Resolved value from token "${String(config.dbToken)}" does not appear to be a valid MongoDB Db instance.`,
|
|
111
112
|
);
|
|
112
113
|
}
|
|
@@ -115,5 +116,5 @@ export async function resolveDatabase(
|
|
|
115
116
|
}
|
|
116
117
|
|
|
117
118
|
// No strategy provided
|
|
118
|
-
throw new
|
|
119
|
+
throw new ConnectionError("MonqueTsedConfig requires 'db', 'dbFactory', or 'dbToken' to be set");
|
|
119
120
|
}
|
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Collect worker metadata utility
|
|
3
|
-
*
|
|
4
|
-
* Collects all worker metadata from a class decorated with @WorkerController.
|
|
5
|
-
* Used by MonqueModule to discover and register all workers.
|
|
6
|
-
*/
|
|
7
|
-
import { Store } from '@tsed/core';
|
|
8
|
-
|
|
9
|
-
import { MONQUE } from '@/constants';
|
|
10
|
-
import type { CronDecoratorOptions, WorkerDecoratorOptions, WorkerStore } from '@/decorators';
|
|
11
|
-
|
|
12
|
-
import { buildJobName } from './build-job-name.js';
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Collected worker registration info ready for Monque.register()
|
|
16
|
-
*/
|
|
17
|
-
export interface CollectedWorkerMetadata {
|
|
18
|
-
/**
|
|
19
|
-
* Full job name (with namespace prefix if applicable)
|
|
20
|
-
*/
|
|
21
|
-
fullName: string;
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Method name on the controller class
|
|
25
|
-
*/
|
|
26
|
-
method: string;
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Worker options to pass to Monque.register()
|
|
30
|
-
*/
|
|
31
|
-
opts: WorkerDecoratorOptions | CronDecoratorOptions;
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Whether this is a cron job
|
|
35
|
-
*/
|
|
36
|
-
isCron: boolean;
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Cron pattern (only for cron jobs)
|
|
40
|
-
*/
|
|
41
|
-
cronPattern?: string;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Collect all worker metadata from a class.
|
|
46
|
-
*
|
|
47
|
-
* @param target - The class constructor (decorated with @WorkerController)
|
|
48
|
-
* @returns Array of collected worker metadata ready for registration
|
|
49
|
-
*
|
|
50
|
-
* @example
|
|
51
|
-
* ```typescript
|
|
52
|
-
* const metadata = collectWorkerMetadata(EmailWorkers);
|
|
53
|
-
* // Returns:
|
|
54
|
-
* // [
|
|
55
|
-
* // { fullName: "email.send", method: "sendEmail", opts: {}, isCron: false },
|
|
56
|
-
* // { fullName: "email.daily-digest", method: "sendDailyDigest", opts: {}, isCron: true, cronPattern: "0 9 * * *" }
|
|
57
|
-
* // ]
|
|
58
|
-
* ```
|
|
59
|
-
*/
|
|
60
|
-
export function collectWorkerMetadata(
|
|
61
|
-
target: new (...args: unknown[]) => unknown,
|
|
62
|
-
): CollectedWorkerMetadata[] {
|
|
63
|
-
const store = Store.from(target);
|
|
64
|
-
const workerStore = store.get<WorkerStore>(MONQUE);
|
|
65
|
-
|
|
66
|
-
if (!workerStore) {
|
|
67
|
-
return [];
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
const results: CollectedWorkerMetadata[] = [];
|
|
71
|
-
const namespace = workerStore.namespace;
|
|
72
|
-
|
|
73
|
-
// Collect regular workers
|
|
74
|
-
for (const worker of workerStore.workers) {
|
|
75
|
-
results.push({
|
|
76
|
-
fullName: buildJobName(namespace, worker.name),
|
|
77
|
-
method: worker.method,
|
|
78
|
-
opts: worker.opts,
|
|
79
|
-
isCron: false,
|
|
80
|
-
});
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
// Collect cron jobs
|
|
84
|
-
for (const cron of workerStore.cronJobs) {
|
|
85
|
-
results.push({
|
|
86
|
-
fullName: buildJobName(namespace, cron.name),
|
|
87
|
-
method: cron.method,
|
|
88
|
-
opts: cron.opts,
|
|
89
|
-
isCron: true,
|
|
90
|
-
cronPattern: cron.pattern,
|
|
91
|
-
});
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
return results;
|
|
95
|
-
}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Generate a unique token for a worker controller.
|
|
3
|
-
*
|
|
4
|
-
* Used internally by Ts.ED DI to identify worker controller providers.
|
|
5
|
-
* The token is based on the class name for debugging purposes.
|
|
6
|
-
*
|
|
7
|
-
* @param target - The class constructor
|
|
8
|
-
* @returns A Symbol token unique to this worker controller
|
|
9
|
-
*
|
|
10
|
-
* @example
|
|
11
|
-
* ```typescript
|
|
12
|
-
* @WorkerController("email")
|
|
13
|
-
* class EmailWorkers {}
|
|
14
|
-
*
|
|
15
|
-
* const token = getWorkerToken(EmailWorkers);
|
|
16
|
-
* // Symbol("monque:worker:EmailWorkers")
|
|
17
|
-
* ```
|
|
18
|
-
*/
|
|
19
|
-
export function getWorkerToken(target: new (...args: unknown[]) => unknown): symbol {
|
|
20
|
-
const name = target.name?.trim();
|
|
21
|
-
|
|
22
|
-
if (!name) {
|
|
23
|
-
throw new Error('Worker class must have a non-empty name');
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
return Symbol.for(`monque:worker:${name}`);
|
|
27
|
-
}
|