@monque/tsed 0.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/LICENSE +15 -0
- package/README.md +222 -0
- package/dist/CHANGELOG.md +19 -0
- package/dist/LICENSE +15 -0
- package/dist/README.md +222 -0
- package/dist/index.cjs +712 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +582 -0
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.mts +582 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +691 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +98 -0
- package/src/config/config.ts +60 -0
- package/src/config/index.ts +2 -0
- package/src/config/types.ts +114 -0
- package/src/constants/constants.ts +12 -0
- package/src/constants/index.ts +2 -0
- package/src/constants/types.ts +21 -0
- package/src/decorators/cron.ts +58 -0
- package/src/decorators/index.ts +10 -0
- package/src/decorators/types.ts +131 -0
- package/src/decorators/worker-controller.ts +55 -0
- package/src/decorators/worker.ts +66 -0
- package/src/index.ts +20 -0
- package/src/monque-module.ts +199 -0
- package/src/services/index.ts +1 -0
- package/src/services/monque-service.ts +267 -0
- package/src/utils/build-job-name.ts +17 -0
- package/src/utils/collect-worker-metadata.ts +95 -0
- package/src/utils/get-worker-token.ts +27 -0
- package/src/utils/guards.ts +62 -0
- package/src/utils/index.ts +13 -0
- package/src/utils/resolve-database.ts +119 -0
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @monque/tsed - Type Guards
|
|
3
|
+
*
|
|
4
|
+
* Utilities for duck-typing Mongoose and MongoDB related objects
|
|
5
|
+
* to avoid hard dependencies on @tsed/mongoose.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { Db } from 'mongodb';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Interface representing a Mongoose Connection object.
|
|
12
|
+
* We only care that it has a `db` property which is a MongoDB Db instance.
|
|
13
|
+
*/
|
|
14
|
+
export interface MongooseConnection {
|
|
15
|
+
db: Db;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Interface representing the @tsed/mongoose MongooseService.
|
|
20
|
+
* It acts as a registry/factory for connections.
|
|
21
|
+
*/
|
|
22
|
+
export interface MongooseService {
|
|
23
|
+
/**
|
|
24
|
+
* Get a connection by its ID (configuration key).
|
|
25
|
+
* @param id The connection ID (default: "default")
|
|
26
|
+
*/
|
|
27
|
+
get(id?: string): MongooseConnection | undefined;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Type guard to check if an object acts like a Mongoose Service.
|
|
32
|
+
*
|
|
33
|
+
* Checks if the object has a `get` method.
|
|
34
|
+
*
|
|
35
|
+
* @param value The value to check
|
|
36
|
+
*/
|
|
37
|
+
export function isMongooseService(value: unknown): value is MongooseService {
|
|
38
|
+
return (
|
|
39
|
+
typeof value === 'object' &&
|
|
40
|
+
value !== null &&
|
|
41
|
+
'get' in value &&
|
|
42
|
+
typeof (value as MongooseService).get === 'function'
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Type guard to check if an object acts like a Mongoose Connection.
|
|
48
|
+
*
|
|
49
|
+
* Checks if the object has a `db` property.
|
|
50
|
+
*
|
|
51
|
+
* @param value The value to check
|
|
52
|
+
*/
|
|
53
|
+
export function isMongooseConnection(value: unknown): value is MongooseConnection {
|
|
54
|
+
return (
|
|
55
|
+
typeof value === 'object' &&
|
|
56
|
+
value !== null &&
|
|
57
|
+
'db' in value &&
|
|
58
|
+
typeof (value as MongooseConnection).db === 'object' &&
|
|
59
|
+
(value as MongooseConnection).db !== null &&
|
|
60
|
+
typeof (value as MongooseConnection).db.collection === 'function'
|
|
61
|
+
);
|
|
62
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export { buildJobName } from './build-job-name.js';
|
|
2
|
+
export {
|
|
3
|
+
type CollectedWorkerMetadata,
|
|
4
|
+
collectWorkerMetadata,
|
|
5
|
+
} from './collect-worker-metadata.js';
|
|
6
|
+
export { getWorkerToken } from './get-worker-token.js';
|
|
7
|
+
export {
|
|
8
|
+
isMongooseConnection,
|
|
9
|
+
isMongooseService,
|
|
10
|
+
type MongooseConnection,
|
|
11
|
+
type MongooseService,
|
|
12
|
+
} from './guards.js';
|
|
13
|
+
export { type InjectorFn, resolveDatabase } from './resolve-database.js';
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @monque/tsed - Database Resolution Utility
|
|
3
|
+
*
|
|
4
|
+
* Multi-strategy database resolution for flexible MongoDB connection handling.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { TokenProvider } from '@tsed/di';
|
|
8
|
+
import type { Db } from 'mongodb';
|
|
9
|
+
|
|
10
|
+
import type { MonqueTsedConfig } from '@/config';
|
|
11
|
+
|
|
12
|
+
import { isMongooseConnection, isMongooseService } from './guards.js';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Type for the injector function used to resolve DI tokens.
|
|
16
|
+
*/
|
|
17
|
+
export type InjectorFn = <T>(token: TokenProvider<T>) => T | undefined;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Resolve the MongoDB database instance from the configuration.
|
|
21
|
+
*
|
|
22
|
+
* Supports three resolution strategies:
|
|
23
|
+
* 1. **Direct `db`**: Returns the provided Db instance directly
|
|
24
|
+
* 2. **Factory `dbFactory`**: Calls the factory function (supports async)
|
|
25
|
+
* 3. **DI Token `dbToken`**: Resolves the Db from the DI container
|
|
26
|
+
*
|
|
27
|
+
* @param config - The Monque configuration containing database settings
|
|
28
|
+
* @param injectorFn - Optional function to resolve DI tokens (required for dbToken strategy)
|
|
29
|
+
* @returns The resolved MongoDB Db instance
|
|
30
|
+
* @throws Error if no database strategy is provided or if DI resolution fails
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* ```typescript
|
|
34
|
+
* // Direct Db instance
|
|
35
|
+
* const db = await resolveDatabase({ db: mongoDb });
|
|
36
|
+
*
|
|
37
|
+
* // Factory function
|
|
38
|
+
* const db = await resolveDatabase({
|
|
39
|
+
* dbFactory: async () => {
|
|
40
|
+
* const client = await MongoClient.connect(uri);
|
|
41
|
+
* return client.db("myapp");
|
|
42
|
+
* }
|
|
43
|
+
* });
|
|
44
|
+
*
|
|
45
|
+
* // DI token
|
|
46
|
+
* const db = await resolveDatabase(
|
|
47
|
+
* { dbToken: "MONGODB_DATABASE" },
|
|
48
|
+
* (token) => injector.get(token)
|
|
49
|
+
* );
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
52
|
+
export async function resolveDatabase(
|
|
53
|
+
config: MonqueTsedConfig,
|
|
54
|
+
injectorFn?: InjectorFn,
|
|
55
|
+
): Promise<Db> {
|
|
56
|
+
// Strategy 1: Direct Db instance
|
|
57
|
+
if (config.db) {
|
|
58
|
+
return config.db;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Strategy 2: Factory function (sync or async)
|
|
62
|
+
if (config.dbFactory) {
|
|
63
|
+
return config.dbFactory();
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Strategy 3: DI token resolution
|
|
67
|
+
if (config.dbToken) {
|
|
68
|
+
if (!injectorFn) {
|
|
69
|
+
throw new Error(
|
|
70
|
+
'MonqueTsedConfig.dbToken requires an injector function to resolve the database',
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const resolved = injectorFn(config.dbToken);
|
|
75
|
+
|
|
76
|
+
if (!resolved) {
|
|
77
|
+
throw new Error(
|
|
78
|
+
`Could not resolve database from token: ${String(config.dbToken)}. ` +
|
|
79
|
+
'Make sure the provider is registered in the DI container.',
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (isMongooseService(resolved)) {
|
|
84
|
+
// Check for Mongoose Service (duck typing)
|
|
85
|
+
// It has a get() method that returns a connection
|
|
86
|
+
const connectionId = config.mongooseConnectionId || 'default';
|
|
87
|
+
const connection = resolved.get(connectionId);
|
|
88
|
+
|
|
89
|
+
if (!connection) {
|
|
90
|
+
throw new Error(
|
|
91
|
+
`MongooseService resolved from token "${String(config.dbToken)}" returned no connection for ID "${connectionId}". ` +
|
|
92
|
+
'Ensure the connection ID is correct and the connection is established.',
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if ('db' in connection && connection.db) {
|
|
97
|
+
return connection.db as Db;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (isMongooseConnection(resolved)) {
|
|
102
|
+
// Check for Mongoose Connection (duck typing)
|
|
103
|
+
// It has a db property that is the native Db instance
|
|
104
|
+
return resolved.db as Db;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Default: Assume it is a native Db instance
|
|
108
|
+
if (typeof resolved !== 'object' || resolved === null || !('collection' in resolved)) {
|
|
109
|
+
throw new Error(
|
|
110
|
+
`Resolved value from token "${String(config.dbToken)}" does not appear to be a valid MongoDB Db instance.`,
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
return resolved as Db;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// No strategy provided
|
|
118
|
+
throw new Error("MonqueTsedConfig requires 'db', 'dbFactory', or 'dbToken' to be set");
|
|
119
|
+
}
|