@dbos-inc/dbos-sdk 2.7.27-preview → 2.7.34
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/context.d.ts +3 -1
- package/dist/src/context.d.ts.map +1 -1
- package/dist/src/context.js +0 -1
- package/dist/src/context.js.map +1 -1
- package/dist/src/dbos-executor.d.ts +1 -0
- package/dist/src/dbos-executor.d.ts.map +1 -1
- package/dist/src/dbos-executor.js.map +1 -1
- package/dist/src/dbos-runtime/config.d.ts.map +1 -1
- package/dist/src/dbos-runtime/config.js +21 -9
- package/dist/src/dbos-runtime/config.js.map +1 -1
- package/dist/src/dbos-runtime/reset.d.ts.map +1 -1
- package/dist/src/dbos-runtime/reset.js +2 -16
- package/dist/src/dbos-runtime/reset.js.map +1 -1
- package/dist/src/dbos.d.ts +310 -7
- package/dist/src/dbos.d.ts.map +1 -1
- package/dist/src/dbos.js +309 -22
- package/dist/src/dbos.js.map +1 -1
- package/dist/src/decorators.d.ts +32 -0
- package/dist/src/decorators.d.ts.map +1 -1
- package/dist/src/decorators.js +35 -0
- package/dist/src/decorators.js.map +1 -1
- package/dist/src/httpServer/handler.d.ts +12 -0
- package/dist/src/httpServer/handler.d.ts.map +1 -1
- package/dist/src/httpServer/handler.js +5 -0
- package/dist/src/httpServer/handler.js.map +1 -1
- package/dist/src/httpServer/server.d.ts.map +1 -1
- package/dist/src/httpServer/server.js +8 -1
- package/dist/src/httpServer/server.js.map +1 -1
- package/dist/src/index.d.ts +25 -15
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +71 -60
- package/dist/src/index.js.map +1 -1
- package/dist/src/procedure.d.ts +7 -0
- package/dist/src/procedure.d.ts.map +1 -1
- package/dist/src/procedure.js.map +1 -1
- package/dist/src/step.d.ts +7 -0
- package/dist/src/step.d.ts.map +1 -1
- package/dist/src/step.js.map +1 -1
- package/dist/src/telemetry/exporters.d.ts +4 -4
- package/dist/src/telemetry/exporters.d.ts.map +1 -1
- package/dist/src/telemetry/exporters.js +28 -16
- package/dist/src/telemetry/exporters.js.map +1 -1
- package/dist/src/testing/testing_runtime.d.ts +2 -0
- package/dist/src/testing/testing_runtime.d.ts.map +1 -1
- package/dist/src/testing/testing_runtime.js +1 -0
- package/dist/src/testing/testing_runtime.js.map +1 -1
- package/dist/src/transaction.d.ts +7 -0
- package/dist/src/transaction.d.ts.map +1 -1
- package/dist/src/transaction.js.map +1 -1
- package/dist/src/wfqueue.d.ts.map +1 -1
- package/dist/src/wfqueue.js +4 -0
- package/dist/src/wfqueue.js.map +1 -1
- package/dist/src/workflow.d.ts +7 -0
- package/dist/src/workflow.d.ts.map +1 -1
- package/dist/src/workflow.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
package/dist/src/dbos.js
CHANGED
@@ -71,6 +71,11 @@ class DBOS {
|
|
71
71
|
: dbos_executor_1.DebugMode.ENABLED
|
72
72
|
: dbos_executor_1.DebugMode.DISABLED;
|
73
73
|
}
|
74
|
+
/**
|
75
|
+
* Set configuration of `DBOS` prior to `launch`
|
76
|
+
* @param config - configuration of services needed by DBOS
|
77
|
+
* @param runtimeConfig - configuration of runtime access to DBOS
|
78
|
+
*/
|
74
79
|
static setConfig(config, runtimeConfig) {
|
75
80
|
DBOS.dbosConfig = config;
|
76
81
|
DBOS.runtimeConfig = runtimeConfig;
|
@@ -85,13 +90,20 @@ class DBOS {
|
|
85
90
|
}
|
86
91
|
}
|
87
92
|
}
|
88
|
-
|
93
|
+
/**
|
94
|
+
* @deprecated For unit testing purposes only
|
95
|
+
* Use `setConfig`
|
96
|
+
*/
|
89
97
|
static setAppConfig(key, newValue) {
|
90
98
|
const conf = DBOS.dbosConfig?.application;
|
91
99
|
if (!conf)
|
92
100
|
throw new error_1.DBOSExecutorNotInitializedError();
|
93
101
|
(0, lodash_1.set)(conf, key, newValue);
|
94
102
|
}
|
103
|
+
/**
|
104
|
+
* Drop DBOS system database.
|
105
|
+
* USE IN TESTS ONLY - ALL WORKFLOWS, QUEUES, ETC. WILL BE LOST.
|
106
|
+
*/
|
95
107
|
static async dropSystemDB() {
|
96
108
|
if (!DBOS.dbosConfig) {
|
97
109
|
DBOS.dbosConfig = (0, config_1.parseConfigFile)()[0];
|
@@ -99,11 +111,17 @@ class DBOS {
|
|
99
111
|
DBOS.translateConfig();
|
100
112
|
return system_database_1.PostgresSystemDatabase.dropSystemDB(DBOS.dbosConfig);
|
101
113
|
}
|
102
|
-
/**
|
114
|
+
/**
|
115
|
+
* Use ORMEntities to set up database schema.
|
116
|
+
* Only relevant for TypeORM, and for testing purposes only, not production
|
117
|
+
*/
|
103
118
|
static async createUserSchema() {
|
104
119
|
return dbos_executor_1.DBOSExecutor.globalInstance?.userDatabase.createSchema();
|
105
120
|
}
|
106
|
-
/**
|
121
|
+
/**
|
122
|
+
* Use ORMEntities to drop database schema.
|
123
|
+
* Only relevant for TypeORM, and for testing purposes only, not production
|
124
|
+
*/
|
107
125
|
static async dropUserSchema() {
|
108
126
|
return dbos_executor_1.DBOSExecutor.globalInstance?.userDatabase.dropSchema();
|
109
127
|
}
|
@@ -111,9 +129,20 @@ class DBOS {
|
|
111
129
|
static async loadClasses(dbosEntrypointFiles) {
|
112
130
|
return await runtime_1.DBOSRuntime.loadClasses(dbosEntrypointFiles);
|
113
131
|
}
|
132
|
+
/**
|
133
|
+
* Check if DBOS has been `launch`ed (and not `shutdown`)
|
134
|
+
* @returns `true` if DBOS has been launched, or `false` otherwise
|
135
|
+
*/
|
136
|
+
static isInitialized() {
|
137
|
+
return !!dbos_executor_1.DBOSExecutor.globalInstance;
|
138
|
+
}
|
139
|
+
/**
|
140
|
+
* Launch DBOS, starting recovery and request handling
|
141
|
+
* @param options - Launch options for connecting to DBOS Conductor
|
142
|
+
*/
|
114
143
|
static async launch(options) {
|
115
144
|
// Do nothing is DBOS is already initialized
|
116
|
-
if (
|
145
|
+
if (DBOS.isInitialized())
|
117
146
|
return;
|
118
147
|
const debugMode = options?.debugMode ?? DBOS.getDebugModeFromEnv();
|
119
148
|
const isDebugging = debugMode !== dbos_executor_1.DebugMode.DISABLED;
|
@@ -211,6 +240,13 @@ class DBOS {
|
|
211
240
|
}
|
212
241
|
(0, decorators_1.recordDBOSLaunch)();
|
213
242
|
}
|
243
|
+
/**
|
244
|
+
* Logs all workflows that can be invoked externally, rather than directly by the applicaton.
|
245
|
+
* This includes:
|
246
|
+
* All DBOS event receiver entrypoints (message queues, URLs, etc.)
|
247
|
+
* Scheduled workflows
|
248
|
+
* Queues
|
249
|
+
*/
|
214
250
|
static logRegisteredEndpoints() {
|
215
251
|
if (!dbos_executor_1.DBOSExecutor.globalInstance)
|
216
252
|
return;
|
@@ -221,6 +257,12 @@ class DBOS {
|
|
221
257
|
evtRcvr.logRegisteredEndpoints();
|
222
258
|
}
|
223
259
|
}
|
260
|
+
/**
|
261
|
+
* Shut down DBOS processing:
|
262
|
+
* Stops receiving external workflow requests
|
263
|
+
* Disconnects from administration / Conductor
|
264
|
+
* Stops workflow processing and disconnects from databases
|
265
|
+
*/
|
224
266
|
static async shutdown() {
|
225
267
|
// Stop the app server
|
226
268
|
if (DBOS.appServer) {
|
@@ -253,18 +295,28 @@ class DBOS {
|
|
253
295
|
utils_1.globalParams.executorID = process.env.DBOS__VMID || 'local';
|
254
296
|
(0, decorators_1.recordDBOSShutdown)();
|
255
297
|
}
|
298
|
+
/** Stop listening for external events (for testing) */
|
256
299
|
static async deactivateEventReceivers() {
|
257
300
|
return dbos_executor_1.DBOSExecutor.globalInstance?.deactivateEventReceivers();
|
258
301
|
}
|
302
|
+
/** Start listening for external events (for testing) */
|
259
303
|
static async initEventReceivers() {
|
260
304
|
return dbos_executor_1.DBOSExecutor.globalInstance?.initEventReceivers();
|
261
305
|
}
|
306
|
+
/**
|
307
|
+
* Global DBOS executor instance
|
308
|
+
*/
|
262
309
|
static get executor() {
|
263
310
|
if (!dbos_executor_1.DBOSExecutor.globalInstance) {
|
264
311
|
throw new error_1.DBOSExecutorNotInitializedError();
|
265
312
|
}
|
266
313
|
return dbos_executor_1.DBOSExecutor.globalInstance;
|
267
314
|
}
|
315
|
+
/**
|
316
|
+
* Creates a node.js HTTP handler for all entrypoints registered with `@DBOS.getApi`
|
317
|
+
* and other decorators. The handler can be retrieved with `DBOS.getHTTPHandlersCallback()`.
|
318
|
+
* This method does not start listening for requests. For that, call `DBOS.launchAppHTTPServer()`.
|
319
|
+
*/
|
268
320
|
static setUpHandlerCallback() {
|
269
321
|
if (!dbos_executor_1.DBOSExecutor.globalInstance) {
|
270
322
|
throw new error_1.DBOSExecutorNotInitializedError();
|
@@ -274,6 +326,11 @@ class DBOS {
|
|
274
326
|
const server = new server_1.DBOSHttpServer(dbos_executor_1.DBOSExecutor.globalInstance);
|
275
327
|
return server;
|
276
328
|
}
|
329
|
+
/**
|
330
|
+
* Creates a node.js HTTP handler for all entrypoints registered with `@DBOS.getApi`
|
331
|
+
* and other decorators. This method also starts listening for requests, on the port
|
332
|
+
* specified in the `DBOSRuntimeConfig`.
|
333
|
+
*/
|
277
334
|
static async launchAppHTTPServer() {
|
278
335
|
const server = DBOS.setUpHandlerCallback();
|
279
336
|
if (DBOS.runtimeConfig) {
|
@@ -281,16 +338,19 @@ class DBOS {
|
|
281
338
|
DBOS.appServer = await server.appListen(DBOS.runtimeConfig.port);
|
282
339
|
}
|
283
340
|
}
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
341
|
+
/**
|
342
|
+
* Retrieves the HTTP handlers callback for DBOS HTTP.
|
343
|
+
* (This is the one that handles the @DBOS.getApi, etc., methods.)
|
344
|
+
* Useful for testing purposes, or to combine the DBOS service with other
|
345
|
+
* node.js HTTP server frameworks.
|
346
|
+
*/
|
288
347
|
static getHTTPHandlersCallback() {
|
289
348
|
if (!server_1.DBOSHttpServer.instance) {
|
290
349
|
return undefined;
|
291
350
|
}
|
292
351
|
return server_1.DBOSHttpServer.instance.app.callback();
|
293
352
|
}
|
353
|
+
/** For unit testing of admin server (do not call) */
|
294
354
|
static getAdminCallback() {
|
295
355
|
if (!server_1.DBOSHttpServer.instance) {
|
296
356
|
return undefined;
|
@@ -307,6 +367,7 @@ class DBOS {
|
|
307
367
|
//////
|
308
368
|
// Context
|
309
369
|
//////
|
370
|
+
/** Get the current DBOS Logger, appropriate to the current context */
|
310
371
|
static get logger() {
|
311
372
|
const ctx = (0, context_1.getCurrentDBOSContext)();
|
312
373
|
if (ctx)
|
@@ -316,33 +377,40 @@ class DBOS {
|
|
316
377
|
return executor.logger;
|
317
378
|
return new logs_1.GlobalLogger();
|
318
379
|
}
|
380
|
+
/** Get the current DBOS tracing span, appropriate to the current context */
|
319
381
|
static get span() {
|
320
382
|
const ctx = (0, context_1.getCurrentDBOSContext)();
|
321
383
|
if (ctx)
|
322
384
|
return ctx.span;
|
323
385
|
return undefined;
|
324
386
|
}
|
387
|
+
/** Get the current HTTP request (within `@DBOS.getApi` et al) */
|
325
388
|
static getRequest() {
|
326
389
|
return (0, context_1.getCurrentDBOSContext)()?.request;
|
327
390
|
}
|
391
|
+
/** Get the current HTTP request (within `@DBOS.getApi` et al) */
|
328
392
|
static get request() {
|
329
393
|
const r = DBOS.getRequest();
|
330
394
|
if (!r)
|
331
395
|
throw new error_1.DBOSError('`DBOS.request` accessed from outside of HTTP requests');
|
332
396
|
return r;
|
333
397
|
}
|
398
|
+
/** Get the current Koa context (within `@DBOS.getApi` et al) */
|
334
399
|
static getKoaContext() {
|
335
400
|
return (0, context_1.getCurrentDBOSContext)()?.koaContext;
|
336
401
|
}
|
402
|
+
/** Get the current Koa context (within `@DBOS.getApi` et al) */
|
337
403
|
static get koaContext() {
|
338
404
|
const r = DBOS.getKoaContext();
|
339
405
|
if (!r)
|
340
406
|
throw new error_1.DBOSError('`DBOS.koaContext` accessed from outside koa request');
|
341
407
|
return r;
|
342
408
|
}
|
409
|
+
/** Get the current workflow ID */
|
343
410
|
static get workflowID() {
|
344
411
|
return (0, context_1.getCurrentDBOSContext)()?.workflowUUID;
|
345
412
|
}
|
413
|
+
/** Get the current step number, within the current workflow */
|
346
414
|
static get stepID() {
|
347
415
|
if (DBOS.isInStep()) {
|
348
416
|
return (0, context_1.getCurrentContextStore)()?.curStepFunctionId;
|
@@ -357,37 +425,57 @@ class DBOS {
|
|
357
425
|
static get stepStatus() {
|
358
426
|
return (0, context_1.getCurrentContextStore)()?.stepStatus;
|
359
427
|
}
|
428
|
+
/** Get the current authenticated user */
|
360
429
|
static get authenticatedUser() {
|
361
430
|
return (0, context_1.getCurrentDBOSContext)()?.authenticatedUser ?? '';
|
362
431
|
}
|
432
|
+
/** Get the roles granted to the current authenticated user */
|
363
433
|
static get authenticatedRoles() {
|
364
434
|
return (0, context_1.getCurrentDBOSContext)()?.authenticatedRoles ?? [];
|
365
435
|
}
|
436
|
+
/** Get the role assumed by the current user giving authorization to execute the current function */
|
366
437
|
static get assumedRole() {
|
367
438
|
return (0, context_1.getCurrentDBOSContext)()?.assumedRole ?? '';
|
368
439
|
}
|
440
|
+
/** @returns true if called from within a transaction, false otherwise */
|
369
441
|
static isInTransaction() {
|
370
442
|
return (0, context_1.getCurrentContextStore)()?.curTxFunctionId !== undefined;
|
371
443
|
}
|
444
|
+
/** @returns true if called from within a stored procedure, false otherwise */
|
372
445
|
static isInStoredProc() {
|
373
446
|
return (0, context_1.getCurrentContextStore)()?.isInStoredProc ?? false;
|
374
447
|
}
|
448
|
+
/** @returns true if called from within a step, false otherwise */
|
375
449
|
static isInStep() {
|
376
450
|
return (0, context_1.getCurrentContextStore)()?.curStepFunctionId !== undefined;
|
377
451
|
}
|
452
|
+
/**
|
453
|
+
* @returns true if called from within a workflow
|
454
|
+
* (regardless of whether the workflow is currently executing a step,
|
455
|
+
* transaction, or procedure), false otherwise
|
456
|
+
*/
|
378
457
|
static isWithinWorkflow() {
|
379
458
|
return (0, context_1.getCurrentContextStore)()?.workflowId !== undefined;
|
380
459
|
}
|
460
|
+
/**
|
461
|
+
* @returns true if called from within a workflow that is not currently executing
|
462
|
+
* a step, transaction, or procedure, or false otherwise
|
463
|
+
*/
|
381
464
|
static isInWorkflow() {
|
382
|
-
return DBOS.isWithinWorkflow() && !DBOS.isInTransaction() && !DBOS.isInStep();
|
465
|
+
return DBOS.isWithinWorkflow() && !DBOS.isInTransaction() && !DBOS.isInStep() && !DBOS.isInStoredProc();
|
383
466
|
}
|
384
467
|
// sql session (various forms)
|
468
|
+
/** @returns the current SQL client; only allowed within `@DBOS.transaction` functions */
|
385
469
|
static get sqlClient() {
|
386
470
|
if (!DBOS.isInTransaction())
|
387
471
|
throw new error_1.DBOSInvalidWorkflowTransitionError('Invalid use of `DBOS.sqlClient` outside of a `transaction`');
|
388
472
|
const ctx = (0, context_1.assertCurrentDBOSContext)();
|
389
473
|
return ctx.client;
|
390
474
|
}
|
475
|
+
/**
|
476
|
+
* @returns the current PG SQL client;
|
477
|
+
* only allowed within `@DBOS.transaction` functions when a `PGNODE` user database is in use
|
478
|
+
*/
|
391
479
|
static get pgClient() {
|
392
480
|
const client = DBOS.sqlClient;
|
393
481
|
if (!DBOS.isInStoredProc() && DBOS.dbosConfig?.userDbclient !== user_database_1.UserDatabaseName.PGNODE) {
|
@@ -395,6 +483,10 @@ class DBOS {
|
|
395
483
|
}
|
396
484
|
return client;
|
397
485
|
}
|
486
|
+
/**
|
487
|
+
* @returns the current Knex SQL client;
|
488
|
+
* only allowed within `@DBOS.transaction` functions when a `KNEX` user database is in use
|
489
|
+
*/
|
398
490
|
static get knexClient() {
|
399
491
|
if (DBOS.isInStoredProc()) {
|
400
492
|
throw new error_1.DBOSInvalidWorkflowTransitionError(`Requested 'DBOS.knexClient' from within a stored procedure`);
|
@@ -405,6 +497,10 @@ class DBOS {
|
|
405
497
|
const client = DBOS.sqlClient;
|
406
498
|
return client;
|
407
499
|
}
|
500
|
+
/**
|
501
|
+
* @returns the current Prisma SQL client;
|
502
|
+
* only allowed within `@DBOS.transaction` functions when a `PRISMA` user database is in use
|
503
|
+
*/
|
408
504
|
static get prismaClient() {
|
409
505
|
if (DBOS.isInStoredProc()) {
|
410
506
|
throw new error_1.DBOSInvalidWorkflowTransitionError(`Requested 'DBOS.prismaClient' from within a stored procedure`);
|
@@ -415,6 +511,10 @@ class DBOS {
|
|
415
511
|
const client = DBOS.sqlClient;
|
416
512
|
return client;
|
417
513
|
}
|
514
|
+
/**
|
515
|
+
* @returns the current TypeORM SQL client;
|
516
|
+
* only allowed within `@DBOS.transaction` functions when the `TYPEORM` user database is in use
|
517
|
+
*/
|
418
518
|
static get typeORMClient() {
|
419
519
|
if (DBOS.isInStoredProc()) {
|
420
520
|
throw new error_1.DBOSInvalidWorkflowTransitionError(`Requested 'DBOS.typeORMClient' from within a stored procedure`);
|
@@ -425,6 +525,10 @@ class DBOS {
|
|
425
525
|
const client = DBOS.sqlClient;
|
426
526
|
return client;
|
427
527
|
}
|
528
|
+
/**
|
529
|
+
* @returns the current Drizzle SQL client;
|
530
|
+
* only allowed within `@DBOS.transaction` functions when the `DRIZZLE` user database is in use
|
531
|
+
*/
|
428
532
|
static get drizzleClient() {
|
429
533
|
if (DBOS.isInStoredProc()) {
|
430
534
|
throw new error_1.DBOSInvalidWorkflowTransitionError(`Requested 'DBOS.drizzleClient' from within a stored procedure`);
|
@@ -435,6 +539,12 @@ class DBOS {
|
|
435
539
|
const client = DBOS.sqlClient;
|
436
540
|
return client;
|
437
541
|
}
|
542
|
+
/**
|
543
|
+
* Gets configuration information from the `application` section
|
544
|
+
* of `DBOSConfig`
|
545
|
+
* @param key - name of configuration item
|
546
|
+
* @param defaultValue - value to return if `key` does not exist in the configuration
|
547
|
+
*/
|
438
548
|
static getConfig(key, defaultValue) {
|
439
549
|
const ctx = (0, context_1.getCurrentDBOSContext)();
|
440
550
|
if (ctx && defaultValue)
|
@@ -445,6 +555,13 @@ class DBOS {
|
|
445
555
|
return DBOS.executor.getConfig(key, defaultValue);
|
446
556
|
return defaultValue;
|
447
557
|
}
|
558
|
+
/**
|
559
|
+
* Query the current application database
|
560
|
+
* @param sql - parameterized SQL statement (string) to execute
|
561
|
+
* @param params - parameter values for `sql`
|
562
|
+
* @template T - Type for the returned records
|
563
|
+
* @returns Array of records returned by the SQL statement
|
564
|
+
*/
|
448
565
|
static async queryUserDB(sql, params) {
|
449
566
|
if (DBOS.isWithinWorkflow() && !DBOS.isInStep()) {
|
450
567
|
throw new error_1.DBOSInvalidWorkflowTransitionError('Invalid call to `queryUserDB` inside a `workflow`, without being in a `step`');
|
@@ -454,12 +571,24 @@ class DBOS {
|
|
454
571
|
//////
|
455
572
|
// Workflow and other operations
|
456
573
|
//////
|
574
|
+
/**
|
575
|
+
* Get the workflow status given a workflow ID
|
576
|
+
* @param workflowID - ID of the workflow
|
577
|
+
* @returns status of the workflow as `WorkflowStatus`, or `null` if there is no workflow with `workflowID`
|
578
|
+
*/
|
457
579
|
static getWorkflowStatus(workflowID) {
|
458
580
|
if (DBOS.isWithinWorkflow() && !DBOS.isInStep()) {
|
459
581
|
throw new error_1.DBOSInvalidWorkflowTransitionError('Invalid call to `getWorkflowStatus` inside a `workflow`, without being in a `step`');
|
460
582
|
}
|
461
583
|
return DBOS.executor.getWorkflowStatus(workflowID);
|
462
584
|
}
|
585
|
+
/**
|
586
|
+
* Create a workflow handle with a given workflow ID.
|
587
|
+
* This call always returns a handle, even if the workflow does not exist.
|
588
|
+
* The resulting handle will check the database to provide any workflow information.
|
589
|
+
* @param workflowID - ID of the workflow
|
590
|
+
* @returns `WorkflowHandle` that can be used to poll for the status or result of any workflow with `workflowID`
|
591
|
+
*/
|
463
592
|
static retrieveWorkflow(workflowID) {
|
464
593
|
if (DBOS.isWithinWorkflow()) {
|
465
594
|
if (!DBOS.isInWorkflow()) {
|
@@ -469,25 +598,51 @@ class DBOS {
|
|
469
598
|
}
|
470
599
|
return DBOS.executor.retrieveWorkflow(workflowID);
|
471
600
|
}
|
601
|
+
/**
|
602
|
+
* Query the system database for all workflows matching the provided predicate
|
603
|
+
* @param input - `GetWorkflowsInput` predicate for filtering returned workflows
|
604
|
+
* @returns `GetWorkflowsOutput` listing the workflow IDs of matching workflows
|
605
|
+
*/
|
472
606
|
static async getWorkflows(input) {
|
473
607
|
if (DBOS.isWithinWorkflow() && !DBOS.isInStep()) {
|
474
608
|
throw new error_1.DBOSInvalidWorkflowTransitionError('Invalid call to `getWorkflows` inside a `workflow`, without being in a `step`');
|
475
609
|
}
|
476
610
|
return await DBOS.executor.getWorkflows(input);
|
477
611
|
}
|
478
|
-
|
479
|
-
|
612
|
+
/**
|
613
|
+
* Cancel a workflow given its ID.
|
614
|
+
* If the workflow is currently running, `DBOSWorkflowCancelledError` will be
|
615
|
+
* thrown from its next DBOS call.
|
616
|
+
* @param workflowID - ID of the workflow
|
617
|
+
*/
|
618
|
+
static async cancelWorkflow(workflowID) {
|
619
|
+
await DBOS.executor.cancelWorkflow(workflowID);
|
480
620
|
}
|
481
|
-
|
482
|
-
|
621
|
+
/**
|
622
|
+
* Resume a workflow given its ID.
|
623
|
+
* @param workflowID - ID of the workflow
|
624
|
+
*/
|
625
|
+
static async resumeWorkflow(workflowID) {
|
626
|
+
return await DBOS.executor.resumeWorkflow(workflowID);
|
483
627
|
}
|
628
|
+
/**
|
629
|
+
* Retrieve the contents of a workflow queue.
|
630
|
+
* @param input - Filter predicate, containing the queue name and other criteria
|
631
|
+
*/
|
484
632
|
static async getWorkflowQueue(input) {
|
485
633
|
if (DBOS.isWithinWorkflow() && !DBOS.isInStep()) {
|
486
634
|
throw new error_1.DBOSInvalidWorkflowTransitionError('Invalid call to `getWorkflows` inside a `workflow`, without being in a `step`');
|
487
635
|
}
|
488
636
|
return await DBOS.executor.getWorkflowQueue(input);
|
489
637
|
}
|
490
|
-
|
638
|
+
/**
|
639
|
+
* Sleep for the specified amount of time.
|
640
|
+
* If called from within a workflow, the sleep is "durable",
|
641
|
+
* meaning that the workflow will sleep until the wakeup time
|
642
|
+
* (calculated by adding `durationMS` to the original invocation time),
|
643
|
+
* regardless of workflow recovery.
|
644
|
+
* @param durationMS - Length of sleep, in milliseconds.
|
645
|
+
*/
|
491
646
|
static async sleepms(durationMS) {
|
492
647
|
if (DBOS.isWithinWorkflow() && !DBOS.isInStep()) {
|
493
648
|
if (DBOS.isInTransaction()) {
|
@@ -497,18 +652,27 @@ class DBOS {
|
|
497
652
|
}
|
498
653
|
await (0, utils_1.sleepms)(durationMS);
|
499
654
|
}
|
655
|
+
/** @see sleepms */
|
500
656
|
static async sleepSeconds(durationSec) {
|
501
657
|
return DBOS.sleepms(durationSec * 1000);
|
502
658
|
}
|
659
|
+
/** @see sleepms */
|
503
660
|
static async sleep(durationMS) {
|
504
661
|
return DBOS.sleepms(durationMS);
|
505
662
|
}
|
506
|
-
|
663
|
+
/**
|
664
|
+
* Use the provided `workflowID` as the identifier for first workflow started
|
665
|
+
* within the `callback` function.
|
666
|
+
* @param workflowID - ID to assign to the first workflow started
|
667
|
+
* @param callback - Function to run, which would start a workflow
|
668
|
+
* @returns - Return value from `callback`
|
669
|
+
*/
|
670
|
+
static async withNextWorkflowID(workflowID, callback) {
|
507
671
|
const pctx = (0, context_1.getCurrentContextStore)();
|
508
672
|
if (pctx) {
|
509
673
|
const pcwfid = pctx.idAssignedForNextWorkflow;
|
510
674
|
try {
|
511
|
-
pctx.idAssignedForNextWorkflow =
|
675
|
+
pctx.idAssignedForNextWorkflow = workflowID;
|
512
676
|
return callback();
|
513
677
|
}
|
514
678
|
finally {
|
@@ -516,9 +680,18 @@ class DBOS {
|
|
516
680
|
}
|
517
681
|
}
|
518
682
|
else {
|
519
|
-
return (0, context_1.runWithTopContext)({ idAssignedForNextWorkflow:
|
683
|
+
return (0, context_1.runWithTopContext)({ idAssignedForNextWorkflow: workflowID }, callback);
|
520
684
|
}
|
521
685
|
}
|
686
|
+
/**
|
687
|
+
* Use the provided `callerName`, `span`, and `request` as context for any
|
688
|
+
* DBOS functions called within the `callback` function.
|
689
|
+
* @param callerName - Tracing caller name
|
690
|
+
* @param span - Tracing span
|
691
|
+
* @param request - HTTP request that initiated the call
|
692
|
+
* @param callback - Function to run with tracing context in place
|
693
|
+
* @returns - Return value from `callback`
|
694
|
+
*/
|
522
695
|
static async withTracedContext(callerName, span, request, callback) {
|
523
696
|
const pctx = (0, context_1.getCurrentContextStore)();
|
524
697
|
if (pctx) {
|
@@ -531,6 +704,15 @@ class DBOS {
|
|
531
704
|
return (0, context_1.runWithTopContext)({ span, request }, callback);
|
532
705
|
}
|
533
706
|
}
|
707
|
+
/**
|
708
|
+
* Use the provided `authedUser` and `authedRoles` as the authenticated user for
|
709
|
+
* any security checks or calls to `DBOS.authenticatedUser`
|
710
|
+
* or `DBOS.authenticatedRoles` placed within the `callback` function.
|
711
|
+
* @param authedUser - Authenticated user
|
712
|
+
* @param authedRoles - Authenticated roles
|
713
|
+
* @param callback - Function to run with authentication context in place
|
714
|
+
* @returns - Return value from `callback`
|
715
|
+
*/
|
534
716
|
static async withAuthedContext(authedUser, authedRoles, callback) {
|
535
717
|
const pctx = (0, context_1.getCurrentContextStore)();
|
536
718
|
if (pctx) {
|
@@ -542,7 +724,13 @@ class DBOS {
|
|
542
724
|
return (0, context_1.runWithTopContext)({ authenticatedUser: authedUser, authenticatedRoles: authedRoles }, callback);
|
543
725
|
}
|
544
726
|
}
|
545
|
-
|
727
|
+
/**
|
728
|
+
* This generic setter helps users calling DBOS operation to pass a name,
|
729
|
+
* later used in seeding a parent OTel span for the operation.
|
730
|
+
* @param callerName - Tracing caller name
|
731
|
+
* @param callback - Function to run with tracing context in place
|
732
|
+
* @returns - Return value from `callback`
|
733
|
+
*/
|
546
734
|
static async withNamedContext(callerName, callback) {
|
547
735
|
const pctx = (0, context_1.getCurrentContextStore)();
|
548
736
|
if (pctx) {
|
@@ -553,12 +741,18 @@ class DBOS {
|
|
553
741
|
return (0, context_1.runWithTopContext)({ operationCaller: callerName }, callback);
|
554
742
|
}
|
555
743
|
}
|
556
|
-
|
744
|
+
/**
|
745
|
+
* Use queue named `queueName` for any workflows started within the `callback`.
|
746
|
+
* @param queueName - Name of queue upon which qll workflows called or started within `callback` will be run
|
747
|
+
* @param callback - Function to run, which would call or start workflows
|
748
|
+
* @returns - Return value from `callback`
|
749
|
+
*/
|
750
|
+
static async withWorkflowQueue(queueName, callback) {
|
557
751
|
const pctx = (0, context_1.getCurrentContextStore)();
|
558
752
|
if (pctx) {
|
559
753
|
const pcwfq = pctx.queueAssignedForWorkflows;
|
560
754
|
try {
|
561
|
-
pctx.queueAssignedForWorkflows =
|
755
|
+
pctx.queueAssignedForWorkflows = queueName;
|
562
756
|
return callback();
|
563
757
|
}
|
564
758
|
finally {
|
@@ -566,7 +760,7 @@ class DBOS {
|
|
566
760
|
}
|
567
761
|
}
|
568
762
|
else {
|
569
|
-
return (0, context_1.runWithTopContext)({ queueAssignedForWorkflows:
|
763
|
+
return (0, context_1.runWithTopContext)({ queueAssignedForWorkflows: queueName }, callback);
|
570
764
|
}
|
571
765
|
}
|
572
766
|
static startWorkflow(target, params) {
|
@@ -766,6 +960,17 @@ class DBOS {
|
|
766
960
|
return proxy;
|
767
961
|
}
|
768
962
|
}
|
963
|
+
/**
|
964
|
+
* Send `message` on optional `topic` to the workflow with `destinationID`
|
965
|
+
* This can be done from inside or outside of DBOS workflow functions
|
966
|
+
* Use the optional `idempotencyKey` to guarantee that the message is sent exactly once
|
967
|
+
* @see `DBOS.recv`
|
968
|
+
*
|
969
|
+
* @param destinationID - ID of the workflow that will `recv` the message
|
970
|
+
* @param message - Message to send, which must be serializable as JSON
|
971
|
+
* @param topic - Optional topic; if specified the `recv` command can specify the same topic to receive selectively
|
972
|
+
* @param idempotencyKey - Optional key for sending the message exactly once
|
973
|
+
*/
|
769
974
|
static async send(destinationID, message, topic, idempotencyKey) {
|
770
975
|
if (DBOS.isWithinWorkflow()) {
|
771
976
|
if (!DBOS.isInWorkflow()) {
|
@@ -778,6 +983,18 @@ class DBOS {
|
|
778
983
|
}
|
779
984
|
return DBOS.executor.send(destinationID, message, topic, idempotencyKey);
|
780
985
|
}
|
986
|
+
/**
|
987
|
+
* Receive a message on optional `topic` from within a workflow.
|
988
|
+
* This must be called from within a workflow; this workflow's ID is used to check for messages sent by `DBOS.send`
|
989
|
+
* This can be configured to time out.
|
990
|
+
* Messages are received in the order in which they are sent (per-sender / causal order).
|
991
|
+
* @see `DBOS.send`
|
992
|
+
*
|
993
|
+
* @param topic - Optional topic; if specified the `recv` command can specify the same topic to receive selectively
|
994
|
+
* @param timeoutSeconds - Optional timeout; if no message is received before the timeout, `null` will be returned
|
995
|
+
* @template T - The type of message that is expected to be received
|
996
|
+
* @returns Any message received, or `null` if the timeout expires
|
997
|
+
*/
|
781
998
|
static async recv(topic, timeoutSeconds) {
|
782
999
|
if (DBOS.isWithinWorkflow()) {
|
783
1000
|
if (!DBOS.isInWorkflow()) {
|
@@ -787,6 +1004,15 @@ class DBOS {
|
|
787
1004
|
}
|
788
1005
|
throw new error_1.DBOSInvalidWorkflowTransitionError('Attempt to call `DBOS.recv` outside of a workflow'); // Only workflows can recv
|
789
1006
|
}
|
1007
|
+
/**
|
1008
|
+
* Set an event, from within a DBOS workflow. This value can be retrieved with `DBOS.getEvent`.
|
1009
|
+
* If the event `key` already exists, its `value` is updated.
|
1010
|
+
* This function can only be called from within a workflow.
|
1011
|
+
* @see `DBOS.getEvent`
|
1012
|
+
*
|
1013
|
+
* @param key - The key for the event; at most one value is associated with a key at any given time.
|
1014
|
+
* @param value - The value to associate with `key`
|
1015
|
+
*/
|
790
1016
|
static async setEvent(key, value) {
|
791
1017
|
if (DBOS.isWithinWorkflow()) {
|
792
1018
|
if (!DBOS.isInWorkflow()) {
|
@@ -796,6 +1022,18 @@ class DBOS {
|
|
796
1022
|
}
|
797
1023
|
throw new error_1.DBOSInvalidWorkflowTransitionError('Attempt to call `DBOS.setEvent` outside of a workflow'); // Only workflows can set event
|
798
1024
|
}
|
1025
|
+
/**
|
1026
|
+
* Get the value of a workflow event, or wait for it to be set.
|
1027
|
+
* This function can be called inside or outside of DBOS workflow functions.
|
1028
|
+
* If this function is called from within a workflow, its result is durably checkpointed.
|
1029
|
+
* @see `DBOS.setEvent`
|
1030
|
+
*
|
1031
|
+
* @param workflowID - The ID of the workflow with the corresponding `setEvent`
|
1032
|
+
* @param key - The key for the event; at most one value is associated with a key at any given time.
|
1033
|
+
* @param timeoutSeconds - Optional timeout; if a value for `key` is not set before the timeout, `null` will be returned
|
1034
|
+
* @template T - The expected type for the value assigned to `key`
|
1035
|
+
* @returns The value to associate with `key`, or `null` if the timeout is hit
|
1036
|
+
*/
|
799
1037
|
static async getEvent(workflowID, key, timeoutSeconds) {
|
800
1038
|
if (DBOS.isWithinWorkflow()) {
|
801
1039
|
if (!DBOS.isInWorkflow()) {
|
@@ -808,6 +1046,10 @@ class DBOS {
|
|
808
1046
|
//////
|
809
1047
|
// Decorators
|
810
1048
|
//////
|
1049
|
+
/**
|
1050
|
+
* Decorator associating a class static method with an invocation schedule
|
1051
|
+
* @param schedulerConfig - The schedule, consisting of a crontab and policy for "make-up work"
|
1052
|
+
*/
|
811
1053
|
static scheduled(schedulerConfig) {
|
812
1054
|
function scheddec(target, propertyKey, inDescriptor) {
|
813
1055
|
const { descriptor, registration } = (0, decorators_1.registerAndWrapDBOSFunction)(target, propertyKey, inDescriptor);
|
@@ -817,6 +1059,12 @@ class DBOS {
|
|
817
1059
|
}
|
818
1060
|
return scheddec;
|
819
1061
|
}
|
1062
|
+
/**
|
1063
|
+
* Decorator designating a method as a DBOS workflow
|
1064
|
+
* Durable execution will be applied within calls to the workflow function
|
1065
|
+
* This also registers the function so that it is available during recovery
|
1066
|
+
* @param config - Configuration information for the workflow
|
1067
|
+
*/
|
820
1068
|
static workflow(config = {}) {
|
821
1069
|
function decorator(target, propertyKey, inDescriptor) {
|
822
1070
|
const { descriptor, registration } = (0, decorators_1.registerAndWrapDBOSFunction)(target, propertyKey, inDescriptor);
|
@@ -894,6 +1142,12 @@ class DBOS {
|
|
894
1142
|
}
|
895
1143
|
return decorator;
|
896
1144
|
}
|
1145
|
+
/**
|
1146
|
+
* Decorator designating a method as a DBOS transaction, making SQL clients available.
|
1147
|
+
* A durable execution checkpoint will be applied to to the underlying database transaction
|
1148
|
+
* @see `DBOS.sqlClient`
|
1149
|
+
* @param config - Configuration information for the transaction, particularly its isolation mode
|
1150
|
+
*/
|
897
1151
|
static transaction(config = {}) {
|
898
1152
|
function decorator(target, propertyKey, inDescriptor) {
|
899
1153
|
const { descriptor, registration } = (0, decorators_1.registerAndWrapDBOSFunction)(target, propertyKey, inDescriptor);
|
@@ -957,6 +1211,12 @@ class DBOS {
|
|
957
1211
|
}
|
958
1212
|
return decorator;
|
959
1213
|
}
|
1214
|
+
/**
|
1215
|
+
* Decorator designating a method as a DBOS stored procedure.
|
1216
|
+
* Within the procedure, `DBOS.sqlClient` is available for database operations.
|
1217
|
+
* A durable execution checkpoint will be applied to to the underlying database transaction
|
1218
|
+
* @param config - Configuration information for the stored procedure, particularly its execution mode
|
1219
|
+
*/
|
960
1220
|
static storedProcedure(config = {}) {
|
961
1221
|
function decorator(target, propertyKey, inDescriptor) {
|
962
1222
|
const { descriptor, registration } = (0, decorators_1.registerAndWrapDBOSFunction)(target, propertyKey, inDescriptor);
|
@@ -1006,6 +1266,14 @@ class DBOS {
|
|
1006
1266
|
}
|
1007
1267
|
return decorator;
|
1008
1268
|
}
|
1269
|
+
/**
|
1270
|
+
* Decorator designating a method as a DBOS step.
|
1271
|
+
* A durable checkpoint will be made after the step completes
|
1272
|
+
* This ensures "at least once" execution of the step, and that the step will not
|
1273
|
+
* be executed again once the checkpoint is recorded
|
1274
|
+
*
|
1275
|
+
* @param config - Configuration information for the step, particularly the retry policy
|
1276
|
+
*/
|
1009
1277
|
static step(config = {}) {
|
1010
1278
|
function decorator(target, propertyKey, inDescriptor) {
|
1011
1279
|
const { descriptor, registration } = (0, decorators_1.registerAndWrapDBOSFunction)(target, propertyKey, inDescriptor);
|
@@ -1070,21 +1338,31 @@ class DBOS {
|
|
1070
1338
|
}
|
1071
1339
|
return decorator;
|
1072
1340
|
}
|
1341
|
+
/** Decorator indicating that the method is the target of HTTP GET operations for `url` */
|
1073
1342
|
static getApi(url) {
|
1074
1343
|
return httpApiDec(handlerTypes_1.APITypes.GET, url);
|
1075
1344
|
}
|
1345
|
+
/** Decorator indicating that the method is the target of HTTP POST operations for `url` */
|
1076
1346
|
static postApi(url) {
|
1077
1347
|
return httpApiDec(handlerTypes_1.APITypes.POST, url);
|
1078
1348
|
}
|
1349
|
+
/** Decorator indicating that the method is the target of HTTP PUT operations for `url` */
|
1079
1350
|
static putApi(url) {
|
1080
1351
|
return httpApiDec(handlerTypes_1.APITypes.PUT, url);
|
1081
1352
|
}
|
1353
|
+
/** Decorator indicating that the method is the target of HTTP PATCH operations for `url` */
|
1082
1354
|
static patchApi(url) {
|
1083
1355
|
return httpApiDec(handlerTypes_1.APITypes.PATCH, url);
|
1084
1356
|
}
|
1357
|
+
/** Decorator indicating that the method is the target of HTTP DELETE operations for `url` */
|
1085
1358
|
static deleteApi(url) {
|
1086
1359
|
return httpApiDec(handlerTypes_1.APITypes.DELETE, url);
|
1087
1360
|
}
|
1361
|
+
/**
|
1362
|
+
* Decorate a class with the default list of required roles.
|
1363
|
+
* This class-level default can be overridden on a per-function basis with `requiredRole`.
|
1364
|
+
* @param anyOf - The list of roles allowed access; authorization is granted if the authenticated user has any role on the list
|
1365
|
+
*/
|
1088
1366
|
static defaultRequiredRole(anyOf) {
|
1089
1367
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
1090
1368
|
function clsdec(ctor) {
|
@@ -1093,6 +1371,11 @@ class DBOS {
|
|
1093
1371
|
}
|
1094
1372
|
return clsdec;
|
1095
1373
|
}
|
1374
|
+
/**
|
1375
|
+
* Decorate a method with the default list of required roles.
|
1376
|
+
* @see `DBOS.defaultRequiredRole`
|
1377
|
+
* @param anyOf - The list of roles allowed access; authorization is granted if the authenticated user has any role on the list
|
1378
|
+
*/
|
1096
1379
|
static requiredRole(anyOf) {
|
1097
1380
|
function apidec(target, propertyKey, inDescriptor) {
|
1098
1381
|
const { descriptor, registration } = (0, decorators_1.registerAndWrapDBOSFunction)(target, propertyKey, inDescriptor);
|
@@ -1107,20 +1390,23 @@ class DBOS {
|
|
1107
1390
|
/**
|
1108
1391
|
* Construct and register an object.
|
1109
1392
|
* Calling this is not necessary; calling the constructor of any `ConfiguredInstance` subclass is sufficient
|
1393
|
+
* @deprecated Use `new` directly
|
1110
1394
|
*/
|
1111
1395
|
static configureInstance(cls, name, ...args) {
|
1112
1396
|
return (0, decorators_1.configureInstance)(cls, name, ...args);
|
1113
1397
|
}
|
1114
|
-
// Function registration
|
1398
|
+
// Function registration - for internal use
|
1115
1399
|
static registerAndWrapDBOSFunction(target, propertyKey, descriptor) {
|
1116
1400
|
return (0, decorators_1.registerAndWrapDBOSFunction)(target, propertyKey, descriptor);
|
1117
1401
|
}
|
1402
|
+
// For internal and testing purposes
|
1118
1403
|
static async executeWorkflowById(workflowId, startNewWorkflow = false) {
|
1119
1404
|
if (!dbos_executor_1.DBOSExecutor.globalInstance) {
|
1120
1405
|
throw new error_1.DBOSExecutorNotInitializedError();
|
1121
1406
|
}
|
1122
1407
|
return dbos_executor_1.DBOSExecutor.globalInstance.executeWorkflowUUID(workflowId, startNewWorkflow);
|
1123
1408
|
}
|
1409
|
+
// For internal and testing purposes
|
1124
1410
|
static async recoverPendingWorkflows(executorIDs = ['local']) {
|
1125
1411
|
if (!dbos_executor_1.DBOSExecutor.globalInstance) {
|
1126
1412
|
throw new error_1.DBOSExecutorNotInitializedError();
|
@@ -1129,6 +1415,7 @@ class DBOS {
|
|
1129
1415
|
}
|
1130
1416
|
}
|
1131
1417
|
exports.DBOS = DBOS;
|
1418
|
+
/** @deprecated */
|
1132
1419
|
class InitContext {
|
1133
1420
|
createUserSchema() {
|
1134
1421
|
DBOS.logger.warn('Schema synchronization is deprecated and unsafe for production use. Please use migrations instead: https://typeorm.io/migrations');
|