@globalart/nestjs-temporal 1.0.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 +11 -0
- package/dist/index.cjs +464 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +297 -0
- package/dist/index.d.mts +297 -0
- package/dist/index.mjs +448 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +65 -0
package/README.md
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# @globalart/nestjs-temporal
|
|
2
|
+
|
|
3
|
+
A NestJS module for working with Temporal workflows and activities. Provides a convenient API for creating Temporal workers, registering activities, and using Temporal clients to start workflows.
|
|
4
|
+
|
|
5
|
+
## Documentation
|
|
6
|
+
|
|
7
|
+
For complete documentation, examples, and API reference, please visit the [official documentation](https://globalart.js.org/packages/nestjs-temporal).
|
|
8
|
+
|
|
9
|
+
## License
|
|
10
|
+
|
|
11
|
+
MIT
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,464 @@
|
|
|
1
|
+
let _nestjs_common = require("@nestjs/common");
|
|
2
|
+
let _nestjs_core = require("@nestjs/core");
|
|
3
|
+
let _temporalio_worker = require("@temporalio/worker");
|
|
4
|
+
let _temporalio_client = require("@temporalio/client");
|
|
5
|
+
let _nestjs_common_constants = require("@nestjs/common/constants");
|
|
6
|
+
|
|
7
|
+
//#region src/temporal.constants.ts
|
|
8
|
+
const TEMPORAL_MODULE_ACTIVITIES = "_temporal_module_activities";
|
|
9
|
+
const TEMPORAL_MODULE_ACTIVITY = "_temporal_module_activity";
|
|
10
|
+
const TEMPORAL_MODULE_WORKFLOW = "_temporal_module_workFlow";
|
|
11
|
+
const TEMPORAL_MODULE_WORKFLOW_METHOD = "_temporal_module_workflow_method";
|
|
12
|
+
|
|
13
|
+
//#endregion
|
|
14
|
+
//#region \0@oxc-project+runtime@0.107.0/helpers/decorateMetadata.js
|
|
15
|
+
function __decorateMetadata(k, v) {
|
|
16
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
//#endregion
|
|
20
|
+
//#region \0@oxc-project+runtime@0.107.0/helpers/decorate.js
|
|
21
|
+
function __decorate(decorators, target, key, desc) {
|
|
22
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
23
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
24
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
25
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
//#endregion
|
|
29
|
+
//#region src/temporal-metadata.accessors.ts
|
|
30
|
+
var _ref$1;
|
|
31
|
+
let TemporalMetadataAccessor = class TemporalMetadataAccessor$1 {
|
|
32
|
+
constructor(reflector) {
|
|
33
|
+
this.reflector = reflector;
|
|
34
|
+
}
|
|
35
|
+
isActivities(target) {
|
|
36
|
+
if (!target) return false;
|
|
37
|
+
return !!this.reflector.get(TEMPORAL_MODULE_ACTIVITIES, target);
|
|
38
|
+
}
|
|
39
|
+
getActivities(target) {
|
|
40
|
+
return this.reflector.get(TEMPORAL_MODULE_ACTIVITIES, target);
|
|
41
|
+
}
|
|
42
|
+
isActivity(target) {
|
|
43
|
+
if (!target) return false;
|
|
44
|
+
return !!this.reflector.get(TEMPORAL_MODULE_ACTIVITY, target);
|
|
45
|
+
}
|
|
46
|
+
getActivity(target) {
|
|
47
|
+
return this.reflector.get(TEMPORAL_MODULE_ACTIVITY, target);
|
|
48
|
+
}
|
|
49
|
+
isWorkflows(target) {
|
|
50
|
+
if (!target) return false;
|
|
51
|
+
return !!this.reflector.get(TEMPORAL_MODULE_WORKFLOW, target);
|
|
52
|
+
}
|
|
53
|
+
getWorkflows(target) {
|
|
54
|
+
return this.reflector.get(TEMPORAL_MODULE_WORKFLOW, target);
|
|
55
|
+
}
|
|
56
|
+
isWorkflowMethod(target) {
|
|
57
|
+
if (!target) return false;
|
|
58
|
+
return !!this.reflector.get(TEMPORAL_MODULE_WORKFLOW_METHOD, target);
|
|
59
|
+
}
|
|
60
|
+
getWorkflowMethod(target) {
|
|
61
|
+
return this.reflector.get(TEMPORAL_MODULE_WORKFLOW_METHOD, target);
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
TemporalMetadataAccessor = __decorate([(0, _nestjs_common.Injectable)(), __decorateMetadata("design:paramtypes", [typeof (_ref$1 = typeof _nestjs_core.Reflector !== "undefined" && _nestjs_core.Reflector) === "function" ? _ref$1 : Object])], TemporalMetadataAccessor);
|
|
65
|
+
|
|
66
|
+
//#endregion
|
|
67
|
+
//#region src/temporal.module-definition.ts
|
|
68
|
+
const { ConfigurableModuleClass, MODULE_OPTIONS_TOKEN: TEMPORAL_MODULE_OPTIONS_TOKEN, OPTIONS_TYPE: TEMPORAL_MODULE_OPTIONS_TYPE, ASYNC_OPTIONS_TYPE: TEMPORAL_MODULE_ASYNC_OPTIONS_TYPE } = new _nestjs_common.ConfigurableModuleBuilder().setClassMethodName("registerWorker").build();
|
|
69
|
+
|
|
70
|
+
//#endregion
|
|
71
|
+
//#region src/temporal.explorer.ts
|
|
72
|
+
var _ref, _ref2, _ref3, _TemporalExplorer;
|
|
73
|
+
let TemporalExplorer = _TemporalExplorer = class TemporalExplorer$1 {
|
|
74
|
+
options;
|
|
75
|
+
logger = new _nestjs_common.Logger(_TemporalExplorer.name);
|
|
76
|
+
worker;
|
|
77
|
+
workerRunPromise;
|
|
78
|
+
constructor(discoveryService, metadataAccessor, metadataScanner) {
|
|
79
|
+
this.discoveryService = discoveryService;
|
|
80
|
+
this.metadataAccessor = metadataAccessor;
|
|
81
|
+
this.metadataScanner = metadataScanner;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Initializes the module by exploring and setting up the Temporal worker.
|
|
85
|
+
*/
|
|
86
|
+
async onModuleInit() {
|
|
87
|
+
await this.explore();
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Shuts down the Temporal worker when the module is destroyed.
|
|
91
|
+
*/
|
|
92
|
+
async onModuleDestroy() {
|
|
93
|
+
if (!this.worker) return;
|
|
94
|
+
try {
|
|
95
|
+
this.worker.shutdown();
|
|
96
|
+
if (this.workerRunPromise) await this.workerRunPromise;
|
|
97
|
+
} catch (err) {
|
|
98
|
+
this.logger.warn("Temporal worker was not cleanly shutdown.", { err: err instanceof Error ? err.message : String(err) });
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Starts the Temporal worker when the application is fully bootstrapped.
|
|
103
|
+
*/
|
|
104
|
+
onApplicationBootstrap() {
|
|
105
|
+
if (this.worker) this.workerRunPromise = this.worker.run();
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Explores the application for Temporal activities and creates the worker.
|
|
109
|
+
* This method is called during module initialization.
|
|
110
|
+
*/
|
|
111
|
+
async explore() {
|
|
112
|
+
const workerConfig = this.getWorkerConfigOptions();
|
|
113
|
+
const runTimeOptions = this.getRuntimeOptions();
|
|
114
|
+
const connectionOptions = this.getNativeConnectionOptions();
|
|
115
|
+
if (!workerConfig.taskQueue) {
|
|
116
|
+
this.logger.warn("Temporal worker configuration missing taskQueue. Worker will not be created.");
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
this.findDuplicateActivityMethods();
|
|
120
|
+
const activitiesFunc = await this.handleActivities();
|
|
121
|
+
if (runTimeOptions) {
|
|
122
|
+
this.logger.verbose("Instantiating a new Runtime object");
|
|
123
|
+
_temporalio_worker.Runtime.install(runTimeOptions);
|
|
124
|
+
}
|
|
125
|
+
const workerOptions = { activities: activitiesFunc };
|
|
126
|
+
if (connectionOptions) {
|
|
127
|
+
this.logger.verbose("Connecting to the Temporal server");
|
|
128
|
+
workerOptions.connection = await _temporalio_worker.NativeConnection.connect(connectionOptions);
|
|
129
|
+
}
|
|
130
|
+
this.logger.verbose("Creating a new Worker");
|
|
131
|
+
this.worker = await _temporalio_worker.Worker.create({
|
|
132
|
+
...workerConfig,
|
|
133
|
+
...workerOptions
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Gets the worker configuration options.
|
|
138
|
+
*/
|
|
139
|
+
getWorkerConfigOptions() {
|
|
140
|
+
return this.options.workerOptions;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Gets the native connection options for the Temporal server.
|
|
144
|
+
*/
|
|
145
|
+
getNativeConnectionOptions() {
|
|
146
|
+
return this.options.connectionOptions;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Gets the runtime options for the Temporal worker.
|
|
150
|
+
*/
|
|
151
|
+
getRuntimeOptions() {
|
|
152
|
+
return this.options.runtimeOptions;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Gets the activity classes to register with this worker.
|
|
156
|
+
* If undefined, all discovered activities will be registered.
|
|
157
|
+
* Can be either class constructors or InstanceWrappers.
|
|
158
|
+
*/
|
|
159
|
+
getActivityClasses() {
|
|
160
|
+
return this.options.activityClasses;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Validates that activity method names are unique across all activity classes.
|
|
164
|
+
* Throws an error if duplicates are found and errorOnDuplicateActivities is enabled.
|
|
165
|
+
*/
|
|
166
|
+
findDuplicateActivityMethods() {
|
|
167
|
+
if (!this.options.errorOnDuplicateActivities) return;
|
|
168
|
+
const activityClasses = this.getActivityClasses();
|
|
169
|
+
if (!activityClasses || activityClasses.length === 0) return;
|
|
170
|
+
const activityMethods = {};
|
|
171
|
+
activityClasses.forEach((classOrWrapper) => {
|
|
172
|
+
const wrapper = classOrWrapper;
|
|
173
|
+
const instance = "instance" in wrapper && wrapper.instance ? wrapper.instance : new classOrWrapper();
|
|
174
|
+
this.metadataScanner.getAllMethodNames(Object.getPrototypeOf(instance)).forEach((key) => {
|
|
175
|
+
if (this.metadataAccessor.isActivity(instance[key])) activityMethods[key] = (activityMethods[key] || []).concat(instance.constructor.name);
|
|
176
|
+
});
|
|
177
|
+
});
|
|
178
|
+
const violations = Object.entries(activityMethods).filter(([, classes]) => classes.length > 1);
|
|
179
|
+
if (violations.length > 0) {
|
|
180
|
+
const message = `Activity names must be unique across all Activity classes. Identified activities with conflicting names: ${JSON.stringify(Object.fromEntries(violations))}`;
|
|
181
|
+
this.logger.error(message);
|
|
182
|
+
throw new Error(message);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Discovers and binds all activity methods from classes decorated with @Activities().
|
|
187
|
+
* Returns an object mapping activity method names to their bound implementations.
|
|
188
|
+
*/
|
|
189
|
+
async handleActivities() {
|
|
190
|
+
const activitiesMethod = {};
|
|
191
|
+
const activityClasses = this.getActivityClasses();
|
|
192
|
+
this.discoveryService.getProviders().filter((wrapper) => this.metadataAccessor.isActivities(!wrapper.metatype || wrapper.inject ? wrapper.instance?.constructor : wrapper.metatype) && (!activityClasses || activityClasses.some((cls) => cls === wrapper.metatype || cls instanceof Object && "metatype" in cls && cls.metatype === wrapper.metatype))).forEach((wrapper) => {
|
|
193
|
+
const { instance } = wrapper;
|
|
194
|
+
const isRequestScoped = !wrapper.isDependencyTreeStatic();
|
|
195
|
+
this.metadataScanner.scanFromPrototype(instance, Object.getPrototypeOf(instance), (key) => {
|
|
196
|
+
if (this.metadataAccessor.isActivity(instance[key])) {
|
|
197
|
+
if (isRequestScoped) this.logger.warn(`Request-scoped activities are not yet fully supported. Activity "${key}" from class "${instance.constructor.name}" may not work correctly.`);
|
|
198
|
+
activitiesMethod[key] = instance[key].bind(instance);
|
|
199
|
+
}
|
|
200
|
+
});
|
|
201
|
+
});
|
|
202
|
+
return activitiesMethod;
|
|
203
|
+
}
|
|
204
|
+
};
|
|
205
|
+
__decorate([(0, _nestjs_common.Inject)(TEMPORAL_MODULE_OPTIONS_TOKEN), __decorateMetadata("design:type", Object)], TemporalExplorer.prototype, "options", void 0);
|
|
206
|
+
TemporalExplorer = _TemporalExplorer = __decorate([(0, _nestjs_common.Injectable)(), __decorateMetadata("design:paramtypes", [
|
|
207
|
+
typeof (_ref = typeof _nestjs_core.DiscoveryService !== "undefined" && _nestjs_core.DiscoveryService) === "function" ? _ref : Object,
|
|
208
|
+
typeof (_ref2 = typeof TemporalMetadataAccessor !== "undefined" && TemporalMetadataAccessor) === "function" ? _ref2 : Object,
|
|
209
|
+
typeof (_ref3 = typeof _nestjs_core.MetadataScanner !== "undefined" && _nestjs_core.MetadataScanner) === "function" ? _ref3 : Object
|
|
210
|
+
])], TemporalExplorer);
|
|
211
|
+
|
|
212
|
+
//#endregion
|
|
213
|
+
//#region src/utils/get-queue-token.util.ts
|
|
214
|
+
function getQueueToken(name) {
|
|
215
|
+
return name ? `TemporalQueue_${name}` : "TemporalQueue_default";
|
|
216
|
+
}
|
|
217
|
+
function getAsyncQueueToken(name) {
|
|
218
|
+
return name ? `TemporalAsyncQueue_${name}` : "TemporalAsyncQueue_default";
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
//#endregion
|
|
222
|
+
//#region src/utils/client.util.ts
|
|
223
|
+
/**
|
|
224
|
+
* Assigns an application shutdown hook to a WorkflowClient to ensure
|
|
225
|
+
* the connection is properly closed when the application shuts down.
|
|
226
|
+
*
|
|
227
|
+
* @param client - The WorkflowClient instance
|
|
228
|
+
* @returns The client with shutdown hook assigned
|
|
229
|
+
*/
|
|
230
|
+
function assignOnAppShutdownHook(client) {
|
|
231
|
+
client.onApplicationShutdown = async () => {
|
|
232
|
+
try {
|
|
233
|
+
await client.connection?.close();
|
|
234
|
+
} catch (reason) {
|
|
235
|
+
const errorMessage = reason instanceof Error ? reason.message : String(reason);
|
|
236
|
+
console.error(`Temporal client connection was not cleanly closed: ${errorMessage}`);
|
|
237
|
+
}
|
|
238
|
+
};
|
|
239
|
+
return client;
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Creates a new WorkflowClient instance with application shutdown hook.
|
|
243
|
+
*
|
|
244
|
+
* @param options - Optional WorkflowClient configuration options
|
|
245
|
+
* @returns A WorkflowClient instance with shutdown hook
|
|
246
|
+
*/
|
|
247
|
+
function getWorkflowClient(options) {
|
|
248
|
+
return assignOnAppShutdownHook(new _temporalio_client.WorkflowClient(options));
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
//#endregion
|
|
252
|
+
//#region src/utils/provider.util.ts
|
|
253
|
+
function createAsyncProvider(provide, options) {
|
|
254
|
+
if (options?.useFactory) {
|
|
255
|
+
const { useFactory, inject } = options;
|
|
256
|
+
return {
|
|
257
|
+
provide,
|
|
258
|
+
useFactory,
|
|
259
|
+
inject: inject || []
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
return {
|
|
263
|
+
provide,
|
|
264
|
+
useValue: options?.useValue || null
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
function createClientAsyncProvider(asyncOptions) {
|
|
268
|
+
const name = asyncOptions.name ? asyncOptions.name : void 0;
|
|
269
|
+
const optionsProvide = getAsyncQueueToken(name);
|
|
270
|
+
const clientProvide = getQueueToken(name);
|
|
271
|
+
return [createAsyncProvider(optionsProvide, asyncOptions), {
|
|
272
|
+
provide: clientProvide,
|
|
273
|
+
useFactory: (options) => getWorkflowClient(options),
|
|
274
|
+
inject: [optionsProvide]
|
|
275
|
+
}];
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
//#endregion
|
|
279
|
+
//#region src/temporal.providers.ts
|
|
280
|
+
/**
|
|
281
|
+
* Builds a WorkflowClient from the provided options.
|
|
282
|
+
* If connection options are provided, establishes a connection first.
|
|
283
|
+
*
|
|
284
|
+
* @param option - Temporal module options containing connection and workflow options
|
|
285
|
+
* @returns A configured WorkflowClient instance
|
|
286
|
+
*/
|
|
287
|
+
async function buildClient(option) {
|
|
288
|
+
if (option.connection) {
|
|
289
|
+
const connection = await _temporalio_client.Connection.connect(option.connection);
|
|
290
|
+
return getWorkflowClient({
|
|
291
|
+
...option.workflowOptions,
|
|
292
|
+
connection
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
return getWorkflowClient(option.workflowOptions);
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* Creates providers for Temporal WorkflowClients.
|
|
299
|
+
* Each option in the array will create a separate client provider.
|
|
300
|
+
*
|
|
301
|
+
* @param options - Array of Temporal module options
|
|
302
|
+
* @returns Array of NestJS providers for WorkflowClients
|
|
303
|
+
*/
|
|
304
|
+
function createClientProviders(options) {
|
|
305
|
+
return options.map((option) => ({
|
|
306
|
+
provide: getQueueToken(option?.name || void 0),
|
|
307
|
+
useFactory: async () => {
|
|
308
|
+
return buildClient(option || {});
|
|
309
|
+
}
|
|
310
|
+
}));
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
//#endregion
|
|
314
|
+
//#region src/temporal.module.ts
|
|
315
|
+
var _TemporalModule;
|
|
316
|
+
let TemporalModule = _TemporalModule = class TemporalModule$1 extends ConfigurableModuleClass {
|
|
317
|
+
/**
|
|
318
|
+
* Create a new Temporal worker.
|
|
319
|
+
*
|
|
320
|
+
* @deprecated Use registerWorker instead.
|
|
321
|
+
* @param options - Worker configuration options
|
|
322
|
+
* @returns Dynamic module configuration
|
|
323
|
+
*/
|
|
324
|
+
static forRoot(options) {
|
|
325
|
+
return _TemporalModule.registerWorker(options);
|
|
326
|
+
}
|
|
327
|
+
/**
|
|
328
|
+
* Create a new Temporal worker asynchronously.
|
|
329
|
+
*
|
|
330
|
+
* @deprecated Use registerWorkerAsync instead.
|
|
331
|
+
* @param options - Async worker configuration options
|
|
332
|
+
* @returns Dynamic module configuration
|
|
333
|
+
*/
|
|
334
|
+
static forRootAsync(options) {
|
|
335
|
+
return _TemporalModule.registerWorkerAsync(options);
|
|
336
|
+
}
|
|
337
|
+
/**
|
|
338
|
+
* Registers a Temporal worker synchronously.
|
|
339
|
+
* The worker will discover and register all activities decorated with @Activities() and @Activity().
|
|
340
|
+
*
|
|
341
|
+
* @param options - Worker configuration options
|
|
342
|
+
* @returns Dynamic module configuration
|
|
343
|
+
*/
|
|
344
|
+
static registerWorker(options) {
|
|
345
|
+
const superDynamicModule = super.registerWorker(options);
|
|
346
|
+
superDynamicModule.imports = [_nestjs_core.DiscoveryModule];
|
|
347
|
+
superDynamicModule.providers.push(TemporalExplorer, TemporalMetadataAccessor);
|
|
348
|
+
return superDynamicModule;
|
|
349
|
+
}
|
|
350
|
+
/**
|
|
351
|
+
* Registers a Temporal worker asynchronously.
|
|
352
|
+
* Useful when configuration depends on other async providers (e.g., ConfigService).
|
|
353
|
+
*
|
|
354
|
+
* @param options - Async worker configuration options
|
|
355
|
+
* @returns Dynamic module configuration
|
|
356
|
+
*/
|
|
357
|
+
static registerWorkerAsync(options) {
|
|
358
|
+
const superDynamicModule = super.registerWorkerAsync(options);
|
|
359
|
+
superDynamicModule.imports.push(_nestjs_core.DiscoveryModule);
|
|
360
|
+
superDynamicModule.providers.push(TemporalExplorer, TemporalMetadataAccessor);
|
|
361
|
+
return superDynamicModule;
|
|
362
|
+
}
|
|
363
|
+
/**
|
|
364
|
+
* Registers a Temporal WorkflowClient synchronously.
|
|
365
|
+
* The client can be injected using @InjectTemporalClient() decorator.
|
|
366
|
+
*
|
|
367
|
+
* @param options - Client configuration options (optional)
|
|
368
|
+
* @returns Dynamic module configuration
|
|
369
|
+
*/
|
|
370
|
+
static registerClient(options) {
|
|
371
|
+
const createClientProvider = createClientProviders([].concat(options));
|
|
372
|
+
return {
|
|
373
|
+
global: true,
|
|
374
|
+
module: _TemporalModule,
|
|
375
|
+
providers: createClientProvider,
|
|
376
|
+
exports: createClientProvider
|
|
377
|
+
};
|
|
378
|
+
}
|
|
379
|
+
/**
|
|
380
|
+
* Registers a Temporal WorkflowClient asynchronously.
|
|
381
|
+
* Useful when configuration depends on other async providers (e.g., ConfigService).
|
|
382
|
+
*
|
|
383
|
+
* @param asyncSharedWorkflowClientOptions - Async client configuration options
|
|
384
|
+
* @returns Dynamic module configuration
|
|
385
|
+
*/
|
|
386
|
+
static registerClientAsync(asyncSharedWorkflowClientOptions) {
|
|
387
|
+
const providers = createClientAsyncProvider(asyncSharedWorkflowClientOptions);
|
|
388
|
+
return {
|
|
389
|
+
global: true,
|
|
390
|
+
module: _TemporalModule,
|
|
391
|
+
providers,
|
|
392
|
+
exports: providers
|
|
393
|
+
};
|
|
394
|
+
}
|
|
395
|
+
};
|
|
396
|
+
TemporalModule = _TemporalModule = __decorate([(0, _nestjs_common.Module)({})], TemporalModule);
|
|
397
|
+
|
|
398
|
+
//#endregion
|
|
399
|
+
//#region src/decorators/workflows.decorator.ts
|
|
400
|
+
function Workflows(nameOrOptions) {
|
|
401
|
+
const options = nameOrOptions && typeof nameOrOptions === "object" ? nameOrOptions : { name: nameOrOptions };
|
|
402
|
+
return (target) => {
|
|
403
|
+
(0, _nestjs_common.SetMetadata)(_nestjs_common_constants.SCOPE_OPTIONS_METADATA, options)(target);
|
|
404
|
+
(0, _nestjs_common.SetMetadata)(TEMPORAL_MODULE_WORKFLOW, options)(target);
|
|
405
|
+
};
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
//#endregion
|
|
409
|
+
//#region src/decorators/workflow.decorator.ts
|
|
410
|
+
function WorkflowMethod(nameOrOptions) {
|
|
411
|
+
return (0, _nestjs_common.SetMetadata)(TEMPORAL_MODULE_WORKFLOW_METHOD, (nameOrOptions && typeof nameOrOptions === "object" ? nameOrOptions : { name: nameOrOptions }) || {});
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
//#endregion
|
|
415
|
+
//#region src/decorators/activities.decorator.ts
|
|
416
|
+
function Activities(queueNameOrOptions) {
|
|
417
|
+
const options = queueNameOrOptions && typeof queueNameOrOptions === "object" ? queueNameOrOptions : { name: queueNameOrOptions };
|
|
418
|
+
return (target) => {
|
|
419
|
+
(0, _nestjs_common.SetMetadata)(_nestjs_common_constants.SCOPE_OPTIONS_METADATA, options)(target);
|
|
420
|
+
(0, _nestjs_common.SetMetadata)(TEMPORAL_MODULE_ACTIVITIES, options)(target);
|
|
421
|
+
};
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
//#endregion
|
|
425
|
+
//#region src/decorators/activity.decorator.ts
|
|
426
|
+
function Activity(nameOrOptions) {
|
|
427
|
+
return (0, _nestjs_common.SetMetadata)(TEMPORAL_MODULE_ACTIVITY, (nameOrOptions && typeof nameOrOptions === "object" ? nameOrOptions : { name: nameOrOptions }) || {});
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
//#endregion
|
|
431
|
+
//#region src/decorators/inject-temporal-client.decorator.ts
|
|
432
|
+
/**
|
|
433
|
+
* Injects a Temporal WorkflowClient instance.
|
|
434
|
+
* Use this decorator to inject the client registered via TemporalModule.registerClient().
|
|
435
|
+
*
|
|
436
|
+
* @param name - Optional name of the client instance (for named clients)
|
|
437
|
+
* @returns Parameter decorator for dependency injection
|
|
438
|
+
*
|
|
439
|
+
* @example
|
|
440
|
+
* ```typescript
|
|
441
|
+
* constructor(@InjectTemporalClient() private client: WorkflowClient) {}
|
|
442
|
+
* ```
|
|
443
|
+
*/
|
|
444
|
+
const InjectTemporalClient = (name) => (0, _nestjs_common.Inject)(getQueueToken(name));
|
|
445
|
+
|
|
446
|
+
//#endregion
|
|
447
|
+
exports.Activities = Activities;
|
|
448
|
+
exports.Activity = Activity;
|
|
449
|
+
exports.InjectTemporalClient = InjectTemporalClient;
|
|
450
|
+
Object.defineProperty(exports, 'TemporalExplorer', {
|
|
451
|
+
enumerable: true,
|
|
452
|
+
get: function () {
|
|
453
|
+
return TemporalExplorer;
|
|
454
|
+
}
|
|
455
|
+
});
|
|
456
|
+
Object.defineProperty(exports, 'TemporalModule', {
|
|
457
|
+
enumerable: true,
|
|
458
|
+
get: function () {
|
|
459
|
+
return TemporalModule;
|
|
460
|
+
}
|
|
461
|
+
});
|
|
462
|
+
exports.WorkflowMethod = WorkflowMethod;
|
|
463
|
+
exports.Workflows = Workflows;
|
|
464
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["TemporalMetadataAccessor","ConfigurableModuleBuilder","TemporalExplorer","Logger","NativeConnection","Worker","WorkflowClient","Connection","TemporalModule","DiscoveryModule","SCOPE_OPTIONS_METADATA","SCOPE_OPTIONS_METADATA"],"sources":["../src/temporal.constants.ts","../src/temporal-metadata.accessors.ts","../src/temporal.module-definition.ts","../src/temporal.explorer.ts","../src/utils/get-queue-token.util.ts","../src/utils/client.util.ts","../src/utils/provider.util.ts","../src/temporal.providers.ts","../src/temporal.module.ts","../src/decorators/workflows.decorator.ts","../src/decorators/workflow.decorator.ts","../src/decorators/activities.decorator.ts","../src/decorators/activity.decorator.ts","../src/decorators/inject-temporal-client.decorator.ts"],"sourcesContent":["export const TEMPORAL_MODULE_ACTIVITIES = '_temporal_module_activities';\nexport const TEMPORAL_MODULE_ACTIVITY = '_temporal_module_activity';\nexport const TEMPORAL_MODULE_WORKFLOW = '_temporal_module_workFlow';\nexport const TEMPORAL_MODULE_WORKFLOW_METHOD =\n '_temporal_module_workflow_method';\n","import { Injectable, Type } from '@nestjs/common';\nimport { Reflector } from '@nestjs/core';\n\nimport {\n TEMPORAL_MODULE_ACTIVITIES,\n TEMPORAL_MODULE_ACTIVITY,\n TEMPORAL_MODULE_WORKFLOW,\n TEMPORAL_MODULE_WORKFLOW_METHOD,\n} from './temporal.constants';\n\n/**\n * TemporalMetadataAccessor provides methods to check and retrieve Temporal decorator metadata.\n * It uses NestJS Reflector to access metadata set by @Activities(), @Activity(), @Workflows(), and @WorkflowMethod() decorators.\n */\n@Injectable()\nexport class TemporalMetadataAccessor {\n constructor(private readonly reflector: Reflector) {}\n\n isActivities(target: Type<unknown> | Function | null | undefined): boolean {\n if (!target) return false;\n return !!this.reflector.get(TEMPORAL_MODULE_ACTIVITIES, target);\n }\n\n getActivities(target: Type<unknown> | Function): unknown {\n return this.reflector.get(TEMPORAL_MODULE_ACTIVITIES, target);\n }\n\n isActivity(target: Type<unknown> | Function | null | undefined): boolean {\n if (!target) return false;\n return !!this.reflector.get(TEMPORAL_MODULE_ACTIVITY, target);\n }\n\n getActivity(target: Type<unknown> | Function): unknown {\n return this.reflector.get(TEMPORAL_MODULE_ACTIVITY, target);\n }\n\n isWorkflows(target: Type<unknown> | Function | null | undefined): boolean {\n if (!target) return false;\n return !!this.reflector.get(TEMPORAL_MODULE_WORKFLOW, target);\n }\n\n getWorkflows(target: Type<unknown> | Function): unknown {\n return this.reflector.get(TEMPORAL_MODULE_WORKFLOW, target);\n }\n\n isWorkflowMethod(\n target: Type<unknown> | Function | null | undefined,\n ): boolean {\n if (!target) return false;\n return !!this.reflector.get(TEMPORAL_MODULE_WORKFLOW_METHOD, target);\n }\n\n getWorkflowMethod(target: Type<unknown> | Function): unknown {\n return this.reflector.get(TEMPORAL_MODULE_WORKFLOW_METHOD, target);\n }\n}\n","import {\n NativeConnectionOptions,\n RuntimeOptions,\n WorkerOptions,\n} from '@temporalio/worker';\nimport { ConfigurableModuleBuilder } from '@nestjs/common';\n\nexport interface TemporalModuleOptions {\n workerOptions: WorkerOptions;\n connectionOptions?: NativeConnectionOptions;\n runtimeOptions?: RuntimeOptions;\n activityClasses?: object[];\n errorOnDuplicateActivities?: boolean;\n}\n\nexport const {\n ConfigurableModuleClass,\n MODULE_OPTIONS_TOKEN: TEMPORAL_MODULE_OPTIONS_TOKEN,\n OPTIONS_TYPE: TEMPORAL_MODULE_OPTIONS_TYPE,\n ASYNC_OPTIONS_TYPE: TEMPORAL_MODULE_ASYNC_OPTIONS_TYPE,\n} = new ConfigurableModuleBuilder<TemporalModuleOptions>()\n .setClassMethodName('registerWorker')\n .build();\n","import {\n Inject,\n Injectable,\n Logger,\n OnApplicationBootstrap,\n OnModuleDestroy,\n OnModuleInit,\n} from \"@nestjs/common\";\nimport { DiscoveryService, MetadataScanner } from \"@nestjs/core\";\nimport { InstanceWrapper } from \"@nestjs/core/injector/instance-wrapper\";\nimport {\n NativeConnection,\n NativeConnectionOptions,\n Runtime,\n RuntimeOptions,\n Worker,\n WorkerOptions,\n} from \"@temporalio/worker\";\nimport { TemporalMetadataAccessor } from \"./temporal-metadata.accessors\";\nimport {\n TEMPORAL_MODULE_OPTIONS_TOKEN,\n type TemporalModuleOptions,\n} from \"./temporal.module-definition\";\n\n/**\n * TemporalExplorer is responsible for discovering and registering Temporal activities\n * and creating the Temporal worker instance.\n *\n * It scans the NestJS application for classes decorated with @Activities() and methods\n * decorated with @Activity(), then registers them with the Temporal worker.\n */\n@Injectable()\nexport class TemporalExplorer\n implements OnModuleInit, OnModuleDestroy, OnApplicationBootstrap\n{\n @Inject(TEMPORAL_MODULE_OPTIONS_TOKEN)\n private readonly options!: TemporalModuleOptions;\n private readonly logger = new Logger(TemporalExplorer.name);\n private worker?: Worker;\n private workerRunPromise?: Promise<void>;\n\n constructor(\n private readonly discoveryService: DiscoveryService,\n private readonly metadataAccessor: TemporalMetadataAccessor,\n private readonly metadataScanner: MetadataScanner\n ) {}\n\n /**\n * Initializes the module by exploring and setting up the Temporal worker.\n */\n async onModuleInit(): Promise<void> {\n await this.explore();\n }\n\n /**\n * Shuts down the Temporal worker when the module is destroyed.\n */\n async onModuleDestroy(): Promise<void> {\n if (!this.worker) {\n return;\n }\n\n try {\n this.worker.shutdown();\n if (this.workerRunPromise) {\n await this.workerRunPromise;\n }\n } catch (err: unknown) {\n this.logger.warn(\"Temporal worker was not cleanly shutdown.\", {\n err: err instanceof Error ? err.message : String(err),\n });\n }\n }\n\n /**\n * Starts the Temporal worker when the application is fully bootstrapped.\n */\n onApplicationBootstrap(): void {\n if (this.worker) {\n this.workerRunPromise = this.worker.run();\n }\n }\n\n /**\n * Explores the application for Temporal activities and creates the worker.\n * This method is called during module initialization.\n */\n async explore(): Promise<void> {\n const workerConfig = this.getWorkerConfigOptions();\n const runTimeOptions = this.getRuntimeOptions();\n const connectionOptions = this.getNativeConnectionOptions();\n\n // Worker must have a taskQueue configured\n if (!workerConfig.taskQueue) {\n this.logger.warn(\n \"Temporal worker configuration missing taskQueue. Worker will not be created.\"\n );\n return;\n }\n\n this.findDuplicateActivityMethods();\n\n const activitiesFunc = await this.handleActivities();\n\n if (runTimeOptions) {\n this.logger.verbose(\"Instantiating a new Runtime object\");\n Runtime.install(runTimeOptions);\n }\n\n const workerOptions: Partial<WorkerOptions> = {\n activities: activitiesFunc,\n };\n\n if (connectionOptions) {\n this.logger.verbose(\"Connecting to the Temporal server\");\n workerOptions.connection = await NativeConnection.connect(\n connectionOptions\n );\n }\n\n this.logger.verbose(\"Creating a new Worker\");\n this.worker = await Worker.create({\n ...workerConfig,\n ...workerOptions,\n } as WorkerOptions);\n }\n\n /**\n * Gets the worker configuration options.\n */\n getWorkerConfigOptions(): WorkerOptions {\n return this.options.workerOptions;\n }\n\n /**\n * Gets the native connection options for the Temporal server.\n */\n getNativeConnectionOptions(): NativeConnectionOptions | undefined {\n return this.options.connectionOptions;\n }\n\n /**\n * Gets the runtime options for the Temporal worker.\n */\n getRuntimeOptions(): RuntimeOptions | undefined {\n return this.options.runtimeOptions;\n }\n\n /**\n * Gets the activity classes to register with this worker.\n * If undefined, all discovered activities will be registered.\n * Can be either class constructors or InstanceWrappers.\n */\n private getActivityClasses(): (InstanceWrapper | Function)[] | undefined {\n return this.options.activityClasses as\n | (InstanceWrapper | Function)[]\n | undefined;\n }\n\n /**\n * Validates that activity method names are unique across all activity classes.\n * Throws an error if duplicates are found and errorOnDuplicateActivities is enabled.\n */\n findDuplicateActivityMethods(): void {\n if (!this.options.errorOnDuplicateActivities) {\n return;\n }\n\n const activityClasses = this.getActivityClasses();\n if (!activityClasses || activityClasses.length === 0) {\n return;\n }\n\n const activityMethods: Record<string, string[]> = {};\n\n activityClasses.forEach((classOrWrapper: InstanceWrapper | Function) => {\n // Handle both InstanceWrapper and class constructor\n const wrapper = classOrWrapper as InstanceWrapper;\n const instance =\n \"instance\" in wrapper && wrapper.instance\n ? wrapper.instance\n : new (classOrWrapper as new () => unknown)();\n\n this.metadataScanner\n .getAllMethodNames(Object.getPrototypeOf(instance))\n .forEach((key) => {\n if (this.metadataAccessor.isActivity(instance[key])) {\n activityMethods[key] = (activityMethods[key] || []).concat(\n instance.constructor.name\n );\n }\n });\n });\n\n const violations = Object.entries(activityMethods).filter(\n ([, classes]) => classes.length > 1\n );\n\n if (violations.length > 0) {\n const message = `Activity names must be unique across all Activity classes. Identified activities with conflicting names: ${JSON.stringify(\n Object.fromEntries(violations)\n )}`;\n this.logger.error(message);\n throw new Error(message);\n }\n }\n\n /**\n * Discovers and binds all activity methods from classes decorated with @Activities().\n * Returns an object mapping activity method names to their bound implementations.\n */\n async handleActivities(): Promise<Record<string, Function>> {\n const activitiesMethod: Record<string, Function> = {};\n\n const activityClasses = this.getActivityClasses();\n const activities: InstanceWrapper[] = this.discoveryService\n .getProviders()\n .filter(\n (wrapper: InstanceWrapper) =>\n this.metadataAccessor.isActivities(\n !wrapper.metatype || wrapper.inject\n ? wrapper.instance?.constructor\n : wrapper.metatype\n ) &&\n (!activityClasses ||\n activityClasses.some(\n (cls) =>\n cls === wrapper.metatype ||\n (cls instanceof Object &&\n \"metatype\" in cls &&\n (cls as InstanceWrapper).metatype === wrapper.metatype)\n ))\n );\n\n activities.forEach((wrapper: InstanceWrapper) => {\n const { instance } = wrapper;\n const isRequestScoped = !wrapper.isDependencyTreeStatic();\n\n this.metadataScanner.scanFromPrototype(\n instance,\n Object.getPrototypeOf(instance),\n (key: string) => {\n if (this.metadataAccessor.isActivity(instance[key])) {\n if (isRequestScoped) {\n this.logger.warn(\n `Request-scoped activities are not yet fully supported. Activity \"${key}\" from class \"${instance.constructor.name}\" may not work correctly.`\n );\n }\n activitiesMethod[key] = instance[key].bind(instance);\n }\n }\n );\n });\n\n return activitiesMethod;\n }\n}\n","export function getQueueToken(name?: string): string {\n return name ? `TemporalQueue_${name}` : 'TemporalQueue_default';\n}\n\nexport function getAsyncQueueToken(name?: string): string {\n return name ? `TemporalAsyncQueue_${name}` : 'TemporalAsyncQueue_default';\n}\n","import { OnApplicationShutdown } from '@nestjs/common';\nimport { WorkflowClient, WorkflowClientOptions } from '@temporalio/client';\n\n/**\n * Assigns an application shutdown hook to a WorkflowClient to ensure\n * the connection is properly closed when the application shuts down.\n *\n * @param client - The WorkflowClient instance\n * @returns The client with shutdown hook assigned\n */\nexport function assignOnAppShutdownHook(\n client: WorkflowClient,\n): WorkflowClient {\n (client as unknown as OnApplicationShutdown).onApplicationShutdown =\n async () => {\n try {\n await client.connection?.close();\n } catch (reason: unknown) {\n const errorMessage =\n reason instanceof Error ? reason.message : String(reason);\n console.error(\n `Temporal client connection was not cleanly closed: ${errorMessage}`,\n );\n }\n };\n return client;\n}\n\n/**\n * Creates a new WorkflowClient instance with application shutdown hook.\n *\n * @param options - Optional WorkflowClient configuration options\n * @returns A WorkflowClient instance with shutdown hook\n */\nexport function getWorkflowClient(\n options?: WorkflowClientOptions,\n): WorkflowClient {\n const client = new WorkflowClient(options);\n return assignOnAppShutdownHook(client);\n}\n","import { Provider } from '@nestjs/common';\nimport { WorkflowClientOptions } from '@temporalio/client';\n\nimport { SharedWorkflowClientOptions } from '../interfaces/shared-workflow-client-options.interface';\nimport {\n SharedConnectionAsyncConfiguration,\n SharedRuntimeAsyncConfiguration,\n SharedWorkerAsyncConfiguration,\n} from '../interfaces';\nimport { getWorkflowClient } from './client.util';\nimport { getAsyncQueueToken, getQueueToken } from './get-queue-token.util';\n\nexport function createAsyncProvider(\n provide: string,\n options?:\n | SharedWorkerAsyncConfiguration\n | SharedRuntimeAsyncConfiguration\n | SharedConnectionAsyncConfiguration\n | SharedWorkflowClientOptions,\n): Provider {\n if (options?.useFactory) {\n const { useFactory, inject } = options;\n return {\n provide,\n useFactory,\n inject: inject || [],\n };\n }\n return {\n provide,\n useValue: options?.useValue || null,\n };\n}\n\nexport function createClientAsyncProvider(\n asyncOptions: SharedWorkflowClientOptions,\n): Provider[] {\n const name = asyncOptions.name ? asyncOptions.name : undefined;\n const optionsProvide = getAsyncQueueToken(name);\n const clientProvide = getQueueToken(name);\n return [\n createAsyncProvider(optionsProvide, asyncOptions),\n {\n provide: clientProvide,\n useFactory: (options?: WorkflowClientOptions) =>\n getWorkflowClient(options),\n inject: [optionsProvide],\n },\n ];\n}\n","import { Provider } from '@nestjs/common';\nimport { Connection, WorkflowClient } from '@temporalio/client';\n\nimport { TemporalModuleOptions } from './interfaces';\nimport { getQueueToken, getWorkflowClient } from './utils';\n\n/**\n * Builds a WorkflowClient from the provided options.\n * If connection options are provided, establishes a connection first.\n *\n * @param option - Temporal module options containing connection and workflow options\n * @returns A configured WorkflowClient instance\n */\nexport async function buildClient(\n option: TemporalModuleOptions,\n): Promise<WorkflowClient> {\n if (option.connection) {\n const connection = await Connection.connect(option.connection);\n return getWorkflowClient({\n ...option.workflowOptions,\n connection,\n });\n }\n\n return getWorkflowClient(option.workflowOptions);\n}\n\n/**\n * Creates providers for Temporal WorkflowClients.\n * Each option in the array will create a separate client provider.\n *\n * @param options - Array of Temporal module options\n * @returns Array of NestJS providers for WorkflowClients\n */\nexport function createClientProviders(\n options: TemporalModuleOptions[],\n): Provider[] {\n return options.map((option) => ({\n provide: getQueueToken(option?.name || undefined),\n useFactory: async (): Promise<WorkflowClient> => {\n return buildClient(option || {});\n },\n }));\n}\n","import { DynamicModule, Module } from '@nestjs/common';\nimport { DiscoveryModule } from '@nestjs/core';\n\nimport { TemporalMetadataAccessor } from './temporal-metadata.accessors';\nimport { TemporalExplorer } from './temporal.explorer';\nimport {\n SharedWorkflowClientOptions,\n TemporalModuleOptions,\n} from './interfaces';\nimport { createClientProviders } from './temporal.providers';\nimport { createClientAsyncProvider } from './utils';\nimport {\n ConfigurableModuleClass,\n TEMPORAL_MODULE_ASYNC_OPTIONS_TYPE,\n TEMPORAL_MODULE_OPTIONS_TYPE,\n} from './temporal.module-definition';\n\n/**\n * TemporalModule provides integration between NestJS and Temporal workflow orchestration.\n *\n * Use registerWorker() or registerWorkerAsync() to register Temporal workers that execute activities.\n * Use registerClient() or registerClientAsync() to register Temporal clients for starting workflows.\n */\n@Module({})\nexport class TemporalModule extends ConfigurableModuleClass {\n /**\n * Create a new Temporal worker.\n *\n * @deprecated Use registerWorker instead.\n * @param options - Worker configuration options\n * @returns Dynamic module configuration\n */\n static forRoot(options: typeof TEMPORAL_MODULE_OPTIONS_TYPE): DynamicModule {\n return TemporalModule.registerWorker(options);\n }\n\n /**\n * Create a new Temporal worker asynchronously.\n *\n * @deprecated Use registerWorkerAsync instead.\n * @param options - Async worker configuration options\n * @returns Dynamic module configuration\n */\n static forRootAsync(\n options: typeof TEMPORAL_MODULE_ASYNC_OPTIONS_TYPE,\n ): DynamicModule {\n return TemporalModule.registerWorkerAsync(options);\n }\n\n /**\n * Registers a Temporal worker synchronously.\n * The worker will discover and register all activities decorated with @Activities() and @Activity().\n *\n * @param options - Worker configuration options\n * @returns Dynamic module configuration\n */\n static registerWorker(\n options: typeof TEMPORAL_MODULE_OPTIONS_TYPE,\n ): DynamicModule {\n const superDynamicModule = super.registerWorker(options);\n superDynamicModule.imports = [DiscoveryModule];\n superDynamicModule.providers.push(\n TemporalExplorer,\n TemporalMetadataAccessor,\n );\n return superDynamicModule;\n }\n\n /**\n * Registers a Temporal worker asynchronously.\n * Useful when configuration depends on other async providers (e.g., ConfigService).\n *\n * @param options - Async worker configuration options\n * @returns Dynamic module configuration\n */\n static registerWorkerAsync(\n options: typeof TEMPORAL_MODULE_ASYNC_OPTIONS_TYPE,\n ): DynamicModule {\n const superDynamicModule = super.registerWorkerAsync(options);\n superDynamicModule.imports.push(DiscoveryModule);\n superDynamicModule.providers.push(\n TemporalExplorer,\n TemporalMetadataAccessor,\n );\n return superDynamicModule;\n }\n\n /**\n * Registers a Temporal WorkflowClient synchronously.\n * The client can be injected using @InjectTemporalClient() decorator.\n *\n * @param options - Client configuration options (optional)\n * @returns Dynamic module configuration\n */\n static registerClient(options?: TemporalModuleOptions): DynamicModule {\n const createClientProvider = createClientProviders([].concat(options));\n return {\n global: true,\n module: TemporalModule,\n providers: createClientProvider,\n exports: createClientProvider,\n };\n }\n /**\n * Registers a Temporal WorkflowClient asynchronously.\n * Useful when configuration depends on other async providers (e.g., ConfigService).\n *\n * @param asyncSharedWorkflowClientOptions - Async client configuration options\n * @returns Dynamic module configuration\n */\n static registerClientAsync(\n asyncSharedWorkflowClientOptions: SharedWorkflowClientOptions,\n ): DynamicModule {\n const providers = createClientAsyncProvider(\n asyncSharedWorkflowClientOptions,\n );\n\n return {\n global: true,\n module: TemporalModule,\n providers,\n exports: providers,\n };\n }\n}\n","import { Scope, SetMetadata } from '@nestjs/common';\nimport { SCOPE_OPTIONS_METADATA } from '@nestjs/common/constants';\n\nimport { TEMPORAL_MODULE_WORKFLOW } from '../temporal.constants';\n\nexport interface WorkflowsOptions {\n /**\n * Specifies the name of the queue to subscribe to.\n */\n name?: string;\n /**\n * Specifies the lifetime of an injected Processor.\n */\n scope?: Scope;\n}\n\nexport function Workflows(): ClassDecorator;\nexport function Workflows(name: string): ClassDecorator;\nexport function Workflows(options: WorkflowsOptions): ClassDecorator;\nexport function Workflows(\n nameOrOptions?: string | WorkflowsOptions,\n): ClassDecorator {\n const options =\n nameOrOptions && typeof nameOrOptions === 'object'\n ? nameOrOptions\n : { name: nameOrOptions };\n return (target: Function) => {\n SetMetadata(SCOPE_OPTIONS_METADATA, options)(target);\n SetMetadata(TEMPORAL_MODULE_WORKFLOW, options)(target);\n };\n}\n","import { SetMetadata } from '@nestjs/common';\n\nimport { TEMPORAL_MODULE_WORKFLOW_METHOD } from '../temporal.constants';\n\nexport interface WorkflowMethodOptions {\n name?: string;\n}\n\nexport function WorkflowMethod(): MethodDecorator;\nexport function WorkflowMethod(name: string): MethodDecorator;\nexport function WorkflowMethod(options: WorkflowMethodOptions): MethodDecorator;\nexport function WorkflowMethod(\n nameOrOptions?: string | WorkflowMethodOptions,\n): MethodDecorator {\n const options =\n nameOrOptions && typeof nameOrOptions === 'object'\n ? nameOrOptions\n : { name: nameOrOptions };\n\n return SetMetadata(TEMPORAL_MODULE_WORKFLOW_METHOD, options || {});\n}\n","import { Scope, SetMetadata } from '@nestjs/common';\nimport { SCOPE_OPTIONS_METADATA } from '@nestjs/common/constants';\nimport { ActivityOptions } from '@temporalio/workflow';\n\nimport { TEMPORAL_MODULE_ACTIVITIES } from '../temporal.constants';\n\n/**\n * Options for the @Activities() decorator.\n */\nexport interface ActivitiesOptions extends ActivityOptions {\n /**\n * Specifies the name of the queue to subscribe to.\n */\n name?: string;\n /**\n * Specifies the lifetime of an injected Activities class.\n */\n scope?: Scope;\n}\n\n/**\n * Marks a class as containing Temporal activities.\n * Methods within this class decorated with @Activity() will be registered as Temporal activities.\n *\n * @param queueNameOrOptions - Optional queue name (string) or options object\n * @returns Class decorator\n *\n * @example\n * ```typescript\n * @Injectable()\n * @Activities()\n * export class MyActivities {\n * @Activity()\n * async doSomething() { }\n * }\n * ```\n */\nexport function Activities(): ClassDecorator;\nexport function Activities(queueName: string): ClassDecorator;\nexport function Activities(\n activitiesOptions: ActivitiesOptions,\n): ClassDecorator;\nexport function Activities(\n queueNameOrOptions?: string | ActivitiesOptions,\n): ClassDecorator {\n const options =\n queueNameOrOptions && typeof queueNameOrOptions === 'object'\n ? queueNameOrOptions\n : { name: queueNameOrOptions };\n return (target: Function) => {\n SetMetadata(SCOPE_OPTIONS_METADATA, options)(target);\n SetMetadata(TEMPORAL_MODULE_ACTIVITIES, options)(target);\n };\n}\n","import { SetMetadata } from '@nestjs/common';\n\nimport { TEMPORAL_MODULE_ACTIVITY } from '../temporal.constants';\n\n/**\n * Options for the @Activity() decorator.\n */\nexport interface ActivityOptions {\n /**\n * Custom name for the activity. If not provided, the method name is used.\n */\n name?: string;\n}\n\n/**\n * Marks a method as a Temporal activity.\n * The method must be within a class decorated with @Activities().\n *\n * @param nameOrOptions - Optional activity name (string) or options object\n * @returns Method decorator\n *\n * @example\n * ```typescript\n * @Activity()\n * async processOrder(orderId: string) { }\n *\n * @Activity('custom-activity-name')\n * async anotherActivity() { }\n * ```\n */\nexport function Activity(): MethodDecorator;\nexport function Activity(name: string): MethodDecorator;\nexport function Activity(options: ActivityOptions): MethodDecorator;\nexport function Activity(\n nameOrOptions?: string | ActivityOptions,\n): MethodDecorator {\n const options =\n nameOrOptions && typeof nameOrOptions === 'object'\n ? nameOrOptions\n : { name: nameOrOptions };\n\n return SetMetadata(TEMPORAL_MODULE_ACTIVITY, options || {});\n}\n","import { Inject } from '@nestjs/common';\n\nimport { getQueueToken } from '../utils';\n\n/**\n * Injects a Temporal WorkflowClient instance.\n * Use this decorator to inject the client registered via TemporalModule.registerClient().\n *\n * @param name - Optional name of the client instance (for named clients)\n * @returns Parameter decorator for dependency injection\n *\n * @example\n * ```typescript\n * constructor(@InjectTemporalClient() private client: WorkflowClient) {}\n * ```\n */\nexport const InjectTemporalClient = (name?: string): ParameterDecorator =>\n Inject(getQueueToken(name));\n"],"mappings":"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"}
|