@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.
Files changed (57) hide show
  1. package/dist/src/context.d.ts +3 -1
  2. package/dist/src/context.d.ts.map +1 -1
  3. package/dist/src/context.js +0 -1
  4. package/dist/src/context.js.map +1 -1
  5. package/dist/src/dbos-executor.d.ts +1 -0
  6. package/dist/src/dbos-executor.d.ts.map +1 -1
  7. package/dist/src/dbos-executor.js.map +1 -1
  8. package/dist/src/dbos-runtime/config.d.ts.map +1 -1
  9. package/dist/src/dbos-runtime/config.js +21 -9
  10. package/dist/src/dbos-runtime/config.js.map +1 -1
  11. package/dist/src/dbos-runtime/reset.d.ts.map +1 -1
  12. package/dist/src/dbos-runtime/reset.js +2 -16
  13. package/dist/src/dbos-runtime/reset.js.map +1 -1
  14. package/dist/src/dbos.d.ts +310 -7
  15. package/dist/src/dbos.d.ts.map +1 -1
  16. package/dist/src/dbos.js +309 -22
  17. package/dist/src/dbos.js.map +1 -1
  18. package/dist/src/decorators.d.ts +32 -0
  19. package/dist/src/decorators.d.ts.map +1 -1
  20. package/dist/src/decorators.js +35 -0
  21. package/dist/src/decorators.js.map +1 -1
  22. package/dist/src/httpServer/handler.d.ts +12 -0
  23. package/dist/src/httpServer/handler.d.ts.map +1 -1
  24. package/dist/src/httpServer/handler.js +5 -0
  25. package/dist/src/httpServer/handler.js.map +1 -1
  26. package/dist/src/httpServer/server.d.ts.map +1 -1
  27. package/dist/src/httpServer/server.js +8 -1
  28. package/dist/src/httpServer/server.js.map +1 -1
  29. package/dist/src/index.d.ts +25 -15
  30. package/dist/src/index.d.ts.map +1 -1
  31. package/dist/src/index.js +71 -60
  32. package/dist/src/index.js.map +1 -1
  33. package/dist/src/procedure.d.ts +7 -0
  34. package/dist/src/procedure.d.ts.map +1 -1
  35. package/dist/src/procedure.js.map +1 -1
  36. package/dist/src/step.d.ts +7 -0
  37. package/dist/src/step.d.ts.map +1 -1
  38. package/dist/src/step.js.map +1 -1
  39. package/dist/src/telemetry/exporters.d.ts +4 -4
  40. package/dist/src/telemetry/exporters.d.ts.map +1 -1
  41. package/dist/src/telemetry/exporters.js +28 -16
  42. package/dist/src/telemetry/exporters.js.map +1 -1
  43. package/dist/src/testing/testing_runtime.d.ts +2 -0
  44. package/dist/src/testing/testing_runtime.d.ts.map +1 -1
  45. package/dist/src/testing/testing_runtime.js +1 -0
  46. package/dist/src/testing/testing_runtime.js.map +1 -1
  47. package/dist/src/transaction.d.ts +7 -0
  48. package/dist/src/transaction.d.ts.map +1 -1
  49. package/dist/src/transaction.js.map +1 -1
  50. package/dist/src/wfqueue.d.ts.map +1 -1
  51. package/dist/src/wfqueue.js +4 -0
  52. package/dist/src/wfqueue.js.map +1 -1
  53. package/dist/src/workflow.d.ts +7 -0
  54. package/dist/src/workflow.d.ts.map +1 -1
  55. package/dist/src/workflow.js.map +1 -1
  56. package/dist/tsconfig.tsbuildinfo +1 -1
  57. 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
- // For unit testing purposes only
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
- /** Only relevant for TypeORM, and for testing purposes only, not production */
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
- /** Only relevant for TypeORM, and for testing purposes only, not production */
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 (dbos_executor_1.DBOSExecutor.globalInstance)
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
- // This retrieves the HTTP handlers callback for DBOS HTTP.
285
- // (This is the one that handles the @DBOS.getApi, etc., methods.)
286
- // Useful for testing purposes, or to combine the DBOS service with routes.
287
- // If you are using your own HTTP server, this won't return anything.
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
- static async cancelWorkflow(wfid) {
479
- await DBOS.executor.cancelWorkflow(wfid);
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
- static async resumeWorkflow(wfid) {
482
- return await DBOS.executor.resumeWorkflow(wfid);
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
- // durable sleep when called from within workflows
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
- static async withNextWorkflowID(wfid, callback) {
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 = wfid;
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: wfid }, callback);
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
- // This generic setter helps users calling DBOS operation to pass a name, later used in seeding a parent OTel span for the operation.
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
- static async withWorkflowQueue(wfq, callback) {
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 = wfq;
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: wfq }, callback);
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');