@dbos-inc/dbos-sdk 2.10.22 → 2.11.5-preview.ga519d145ea

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 (62) hide show
  1. package/dist/src/authdecorators.d.ts +9 -0
  2. package/dist/src/authdecorators.d.ts.map +1 -0
  3. package/dist/src/authdecorators.js +71 -0
  4. package/dist/src/authdecorators.js.map +1 -0
  5. package/dist/src/context.d.ts +8 -3
  6. package/dist/src/context.d.ts.map +1 -1
  7. package/dist/src/context.js.map +1 -1
  8. package/dist/src/dbos-executor.d.ts +1 -1
  9. package/dist/src/dbos-executor.d.ts.map +1 -1
  10. package/dist/src/dbos-executor.js +45 -22
  11. package/dist/src/dbos-executor.js.map +1 -1
  12. package/dist/src/dbos-runtime/cloudutils/databases.d.ts +1 -1
  13. package/dist/src/dbos-runtime/migrate.d.ts +2 -2
  14. package/dist/src/dbos-runtime/workflow_management.d.ts +1 -0
  15. package/dist/src/dbos-runtime/workflow_management.d.ts.map +1 -1
  16. package/dist/src/dbos-runtime/workflow_management.js +12 -1
  17. package/dist/src/dbos-runtime/workflow_management.js.map +1 -1
  18. package/dist/src/dbos.d.ts +59 -4
  19. package/dist/src/dbos.d.ts.map +1 -1
  20. package/dist/src/dbos.js +82 -18
  21. package/dist/src/dbos.js.map +1 -1
  22. package/dist/src/decorators.d.ts +73 -52
  23. package/dist/src/decorators.d.ts.map +1 -1
  24. package/dist/src/decorators.js +297 -246
  25. package/dist/src/decorators.js.map +1 -1
  26. package/dist/src/httpServer/handler.d.ts.map +1 -1
  27. package/dist/src/httpServer/handler.js +3 -2
  28. package/dist/src/httpServer/handler.js.map +1 -1
  29. package/dist/src/httpServer/middleware.d.ts +2 -4
  30. package/dist/src/httpServer/middleware.d.ts.map +1 -1
  31. package/dist/src/httpServer/middleware.js +3 -3
  32. package/dist/src/httpServer/middleware.js.map +1 -1
  33. package/dist/src/httpServer/server.d.ts +2 -0
  34. package/dist/src/httpServer/server.d.ts.map +1 -1
  35. package/dist/src/httpServer/server.js +205 -185
  36. package/dist/src/httpServer/server.js.map +1 -1
  37. package/dist/src/index.d.ts +5 -3
  38. package/dist/src/index.d.ts.map +1 -1
  39. package/dist/src/index.js +25 -20
  40. package/dist/src/index.js.map +1 -1
  41. package/dist/src/paramdecorators.d.ts +30 -0
  42. package/dist/src/paramdecorators.d.ts.map +1 -0
  43. package/dist/src/paramdecorators.js +362 -0
  44. package/dist/src/paramdecorators.js.map +1 -0
  45. package/dist/src/system_database.d.ts +3 -2
  46. package/dist/src/system_database.d.ts.map +1 -1
  47. package/dist/src/system_database.js +27 -0
  48. package/dist/src/system_database.js.map +1 -1
  49. package/dist/src/testing/testing_runtime.d.ts +1 -2
  50. package/dist/src/testing/testing_runtime.d.ts.map +1 -1
  51. package/dist/src/testing/testing_runtime.js +1 -0
  52. package/dist/src/testing/testing_runtime.js.map +1 -1
  53. package/dist/src/workflow.d.ts +2 -2
  54. package/dist/src/workflow.d.ts.map +1 -1
  55. package/dist/src/workflow.js +1 -1
  56. package/dist/src/workflow.js.map +1 -1
  57. package/dist/tsconfig.tsbuildinfo +1 -1
  58. package/package.json +1 -1
  59. package/dist/src/data_validation.d.ts +0 -3
  60. package/dist/src/data_validation.d.ts.map +0 -1
  61. package/dist/src/data_validation.js +0 -185
  62. package/dist/src/data_validation.js.map +0 -1
@@ -1,34 +1,56 @@
1
1
  "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || function (mod) {
19
- if (mod && mod.__esModule) return mod;
20
- var result = {};
21
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
- __setModuleDefault(result, mod);
23
- return result;
24
- };
25
2
  Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.DBOSDeploy = exports.DBOSInitializer = exports.OrmEntities = exports.Step = exports.StoredProcedure = exports.Transaction = exports.Workflow = exports.RequiredRole = exports.configureInstance = exports.DefaultArgOptional = exports.DefaultArgValidate = exports.DefaultArgRequired = exports.DefaultRequiredRole = exports.ArgVarchar = exports.ArgDate = exports.ArgName = exports.LogMask = exports.SkipLogging = exports.ArgOptional = exports.ArgRequired = exports.associateMethodWithEventReceiver = exports.associateClassWithEventReceiver = exports.getOrCreateClassRegistration = exports.getAllRegisteredClasses = exports.registerAndWrapDBOSFunction = exports.registerAndWrapFunctionTakingContext = exports.getOrCreateMethodArgsRegistration = exports.getConfiguredInstance = exports.getRegisteredOperations = exports.registerFunctionWrapper = exports.getRegisteredMethodName = exports.getRegisteredMethodClassName = exports.ensureDBOSIsNotLaunched = exports.recordDBOSShutdown = exports.recordDBOSLaunch = exports.ClassRegistration = exports.ConfiguredInstance = exports.MethodRegistration = exports.MethodParameter = exports.ArgRequiredOptions = exports.LogMasks = exports.DBOSDataType = void 0;
3
+ exports.DBOSDeploy = exports.DBOSInitializer = exports.OrmEntities = exports.Step = exports.StoredProcedure = exports.Transaction = exports.Workflow = exports.configureInstance = exports.ArgName = exports.getRegistrationsForExternal = exports.associateParameterWithExternal = exports.associateMethodWithExternal = exports.associateMethodWithEventReceiver = exports.associateClassWithExternal = exports.associateClassWithEventReceiver = exports.getOrCreateClassRegistration = exports.getClassRegistrationByName = exports.getAllRegisteredClassNames = exports.getNameForClass = exports.registerAndWrapDBOSFunctionByName = exports.registerAndWrapDBOSFunction = exports.registerAndWrapFunctionTakingContext = exports.getOrCreateMethodArgsRegistration = exports.getConfiguredInstance = exports.getRegisteredOperationsByClassname = exports.getRegisteredOperations = exports.getRegistrationForFunction = exports.registerFunctionWrapper = exports.getRegisteredMethodName = exports.getRegisteredMethodClassName = exports.ensureDBOSIsNotLaunched = exports.recordDBOSShutdown = exports.recordDBOSLaunch = exports.ClassRegistration = exports.ConfiguredInstance = exports.MethodRegistration = exports.DBOS_AUTH = exports.MethodParameter = exports.DBOSDataType = exports.insertAllMiddleware = exports.registerMiddlewareInserter = exports.getLifecycleListeners = exports.registerLifecycleCallback = exports.DBOSLifecycleCallback = void 0;
27
4
  require("reflect-metadata");
28
- const crypto = __importStar(require("crypto"));
29
- const context_1 = require("./context");
30
5
  const error_1 = require("./error");
31
- const data_validation_1 = require("./data_validation");
6
+ /**
7
+ * Interface for integrating into the DBOS startup/shutdown lifecycle
8
+ */
9
+ class DBOSLifecycleCallback {
10
+ /** Called back during DBOS launch */
11
+ initialize() {
12
+ return Promise.resolve();
13
+ }
14
+ /** Called back upon shutdown (usually in tests) to close connections and free resources */
15
+ destroy() {
16
+ return Promise.resolve();
17
+ }
18
+ /** Called at launch; Implementers should emit a diagnostic list of all registrations */
19
+ logRegisteredEndpoints() { }
20
+ }
21
+ exports.DBOSLifecycleCallback = DBOSLifecycleCallback;
22
+ const lifecycleListeners = [];
23
+ function registerLifecycleCallback(lcl) {
24
+ if (!lifecycleListeners.includes(lcl))
25
+ lifecycleListeners.push(lcl);
26
+ }
27
+ exports.registerLifecycleCallback = registerLifecycleCallback;
28
+ function getLifecycleListeners() {
29
+ return lifecycleListeners;
30
+ }
31
+ exports.getLifecycleListeners = getLifecycleListeners;
32
+ let installedMiddleware = false;
33
+ const middlewareInserters = [];
34
+ function registerMiddlewareInserter(i) {
35
+ if (installedMiddleware)
36
+ throw new TypeError('Attempt to provide method middleware after insertion was performed');
37
+ if (!middlewareInserters.includes(i))
38
+ middlewareInserters.push(i);
39
+ }
40
+ exports.registerMiddlewareInserter = registerMiddlewareInserter;
41
+ function insertAllMiddleware() {
42
+ if (installedMiddleware)
43
+ return;
44
+ installedMiddleware = true;
45
+ for (const [_cn, c] of classesByName) {
46
+ for (const [_fn, f] of c.reg.registeredOperations) {
47
+ for (const i of middlewareInserters) {
48
+ i.installMiddleware(f);
49
+ }
50
+ }
51
+ }
52
+ }
53
+ exports.insertAllMiddleware = insertAllMiddleware;
32
54
  class DBOSDataType {
33
55
  dataType = 'text';
34
56
  length = -1;
@@ -188,41 +210,48 @@ function getArgNames(func) {
188
210
  }
189
211
  return args;
190
212
  }
191
- var LogMasks;
192
- (function (LogMasks) {
193
- LogMasks["NONE"] = "NONE";
194
- LogMasks["HASH"] = "HASH";
195
- LogMasks["SKIP"] = "SKIP";
196
- })(LogMasks || (exports.LogMasks = LogMasks = {}));
197
- var ArgRequiredOptions;
198
- (function (ArgRequiredOptions) {
199
- ArgRequiredOptions["REQUIRED"] = "REQUIRED";
200
- ArgRequiredOptions["OPTIONAL"] = "OPTIONAL";
201
- ArgRequiredOptions["DEFAULT"] = "DEFAULT";
202
- })(ArgRequiredOptions || (exports.ArgRequiredOptions = ArgRequiredOptions = {}));
203
213
  class MethodParameter {
204
214
  name = '';
205
- required = ArgRequiredOptions.DEFAULT;
206
- validate = true;
207
- logMask = LogMasks.NONE;
208
- // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
209
- argType = undefined; // This comes from reflect-metadata, if we have it
210
- dataType;
211
215
  index = -1;
216
+ externalRegInfo = new Map();
217
+ getRegisteredInfo(reg) {
218
+ if (!this.externalRegInfo.has(reg)) {
219
+ this.externalRegInfo.set(reg, {});
220
+ }
221
+ return this.externalRegInfo.get(reg);
222
+ }
223
+ get dataType() {
224
+ return this.getRegisteredInfo('type').dataType;
225
+ }
226
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
227
+ initializeBaseType(at) {
228
+ if (!this.externalRegInfo.has('type')) {
229
+ this.externalRegInfo.set('type', {});
230
+ }
231
+ const adt = this.externalRegInfo.get('type');
232
+ adt.dataType = DBOSDataType.fromArg(at);
233
+ }
212
234
  // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
213
235
  constructor(idx, at) {
214
236
  this.index = idx;
215
- this.argType = at;
216
- this.dataType = DBOSDataType.fromArg(at);
237
+ this.initializeBaseType(at);
217
238
  }
218
239
  }
219
240
  exports.MethodParameter = MethodParameter;
241
+ //////////////////////////////////////////
242
+ /* REGISTRATION OBJECTS and read access */
243
+ //////////////////////////////////////////
244
+ exports.DBOS_AUTH = 'auth';
220
245
  class MethodRegistration {
221
246
  defaults;
222
247
  name = '';
223
248
  className = '';
224
- requiredRole = undefined;
225
- performArgValidation = false;
249
+ // Interceptors
250
+ onEnter = [];
251
+ addEntryInterceptor(func, seqNum = 10) {
252
+ this.onEnter.push({ seqNum, func });
253
+ this.onEnter.sort((a, b) => a.seqNum - b.seqNum);
254
+ }
226
255
  args = [];
227
256
  passContext = false;
228
257
  constructor(origFunc, isInstance, passContext) {
@@ -241,6 +270,13 @@ class MethodRegistration {
241
270
  procConfig;
242
271
  regLocation;
243
272
  eventReceiverInfo = new Map();
273
+ externalRegInfo = new Map();
274
+ getRegisteredInfo(reg) {
275
+ if (!this.externalRegInfo.has(reg)) {
276
+ this.externalRegInfo.set(reg, {});
277
+ }
278
+ return this.externalRegInfo.get(reg);
279
+ }
244
280
  getAssignedType() {
245
281
  if (this.txnConfig)
246
282
  return 'Transaction';
@@ -289,13 +325,16 @@ class MethodRegistration {
289
325
  }
290
326
  init = false;
291
327
  invoke(pthis, args) {
292
- return this.registeredFunction.call(pthis, ...args);
328
+ const f = this.wrappedFunction ?? this.registeredFunction ?? this.origFunction;
329
+ return f.call(pthis, ...args);
293
330
  }
294
331
  getRequiredRoles() {
295
- if (this.requiredRole) {
296
- return this.requiredRole;
332
+ const rr = this.getRegisteredInfo(exports.DBOS_AUTH);
333
+ if (rr?.requiredRole) {
334
+ return rr.requiredRole;
297
335
  }
298
- return this.defaults?.requiredRole || [];
336
+ const drr = this.defaults?.getRegisteredInfo(exports.DBOS_AUTH);
337
+ return drr?.requiredRole || [];
299
338
  }
300
339
  }
301
340
  exports.MethodRegistration = MethodRegistration;
@@ -327,10 +366,6 @@ class ConfiguredInstance {
327
366
  exports.ConfiguredInstance = ConfiguredInstance;
328
367
  class ClassRegistration {
329
368
  name = '';
330
- requiredRole;
331
- argRequiredEnabled = false;
332
- defaultArgRequired = ArgRequiredOptions.REQUIRED;
333
- defaultArgValidate = false;
334
369
  needsInitialized = true;
335
370
  // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
336
371
  ormEntities = [];
@@ -338,10 +373,14 @@ class ClassRegistration {
338
373
  configuredInstances = new Map();
339
374
  configuredInstanceRegLocs = new Map();
340
375
  eventReceiverInfo = new Map();
341
- ctor;
342
- constructor(ctor) {
343
- this.ctor = ctor;
376
+ externalRegInfo = new Map();
377
+ getRegisteredInfo(reg) {
378
+ if (!this.externalRegInfo.has(reg)) {
379
+ this.externalRegInfo.set(reg, {});
380
+ }
381
+ return this.externalRegInfo.get(reg);
344
382
  }
383
+ constructor() { }
345
384
  }
346
385
  exports.ClassRegistration = ClassRegistration;
347
386
  class StackGrabber extends Error {
@@ -393,12 +432,16 @@ function registerFunctionWrapper(func, reg) {
393
432
  methodToRegistration.set(func, reg);
394
433
  }
395
434
  exports.registerFunctionWrapper = registerFunctionWrapper;
435
+ function getRegistrationForFunction(func) {
436
+ return methodToRegistration.get(func);
437
+ }
438
+ exports.getRegistrationForFunction = getRegistrationForFunction;
396
439
  function getRegisteredOperations(target) {
397
440
  const registeredOperations = [];
398
441
  if (typeof target === 'function') {
399
442
  // Constructor case
400
443
  const classReg = classesByName.get(target.name);
401
- classReg?.registeredOperations?.forEach((m) => registeredOperations.push(m));
444
+ classReg?.reg?.registeredOperations?.forEach((m) => registeredOperations.push(m));
402
445
  }
403
446
  else {
404
447
  let current = target;
@@ -413,8 +456,15 @@ function getRegisteredOperations(target) {
413
456
  return registeredOperations;
414
457
  }
415
458
  exports.getRegisteredOperations = getRegisteredOperations;
459
+ function getRegisteredOperationsByClassname(target) {
460
+ const registeredOperations = [];
461
+ const cls = getClassRegistrationByName(target);
462
+ cls.registeredOperations?.forEach((m) => registeredOperations.push(m));
463
+ return registeredOperations;
464
+ }
465
+ exports.getRegisteredOperationsByClassname = getRegisteredOperationsByClassname;
416
466
  function getConfiguredInstance(clsname, cfgname) {
417
- const classReg = classesByName.get(clsname);
467
+ const classReg = classesByName.get(clsname)?.reg;
418
468
  if (!classReg)
419
469
  return null;
420
470
  return classReg.configuredInstances.get(cfgname) ?? null;
@@ -427,52 +477,66 @@ exports.getConfiguredInstance = getConfiguredInstance;
427
477
  // initialization time.
428
478
  ////////////////////////////////////////////////////////////////////////////////
429
479
  const methodArgsByFunction = new Map();
430
- function getOrCreateMethodArgsRegistration(target, propertyKey) {
480
+ function getOrCreateMethodArgsRegistration(target, className, funcName, func) {
431
481
  let regtarget = target;
432
- if (typeof regtarget !== 'function') {
482
+ if (regtarget && typeof regtarget !== 'function') {
433
483
  regtarget = regtarget.constructor;
434
484
  }
435
- // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
436
- const mkey = regtarget.name + '|' + propertyKey.toString();
485
+ className = className ?? (target ? getNameForClass(target) : '');
486
+ const mkey = className + '|' + funcName.toString();
437
487
  let mParameters = methodArgsByFunction.get(mkey);
438
488
  if (mParameters === undefined) {
439
489
  // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
440
- const designParamTypes = Reflect.getMetadata('design:paramtypes', target, propertyKey);
490
+ let designParamTypes = undefined;
491
+ if (target) {
492
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
493
+ designParamTypes = Reflect.getMetadata('design:paramtypes', target, funcName);
494
+ }
441
495
  if (designParamTypes) {
442
496
  mParameters = designParamTypes.map((value, index) => new MethodParameter(index, value));
443
497
  }
444
498
  else {
445
- const descriptor = Object.getOwnPropertyDescriptor(target, propertyKey);
446
- // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
447
- const argnames = getArgNames(descriptor?.value);
448
- mParameters = argnames.map((_value, index) => new MethodParameter(index));
499
+ if (func) {
500
+ const argnames = getArgNames(func);
501
+ mParameters = argnames.map((_value, index) => new MethodParameter(index));
502
+ }
503
+ else {
504
+ const descriptor = Object.getOwnPropertyDescriptor(target, funcName);
505
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
506
+ const argnames = getArgNames(descriptor?.value);
507
+ mParameters = argnames.map((_value, index) => new MethodParameter(index));
508
+ }
449
509
  }
450
510
  methodArgsByFunction.set(mkey, mParameters);
451
511
  }
452
512
  return mParameters;
453
513
  }
454
514
  exports.getOrCreateMethodArgsRegistration = getOrCreateMethodArgsRegistration;
455
- function generateSaltedHash(data, salt) {
456
- const hash = crypto.createHash('sha256'); // You can use other algorithms like 'md5', 'sha512', etc.
457
- hash.update(data + salt);
458
- return hash.digest('hex');
459
- }
460
- function getOrCreateMethodRegistration(target, propertyKey, descriptor, passContext) {
461
- let regtarget;
515
+ function getOrCreateMethodRegistration(target, className, propertyKey, func, passContext) {
516
+ let regtarget = undefined;
462
517
  let isInstance = false;
463
- if (typeof target === 'function') {
464
- // Static method case
465
- regtarget = target;
518
+ if (target) {
519
+ if (typeof target === 'function') {
520
+ // Static method case
521
+ regtarget = target;
522
+ }
523
+ else {
524
+ // Instance method case
525
+ regtarget = target.constructor;
526
+ isInstance = true;
527
+ }
466
528
  }
467
- else {
468
- // Instance method case
469
- regtarget = target.constructor;
470
- isInstance = true;
529
+ if (!className) {
530
+ if (regtarget)
531
+ className = regtarget.name;
471
532
  }
472
- const classReg = getOrCreateClassRegistration(regtarget);
533
+ if (!className) {
534
+ className = '';
535
+ }
536
+ const classReg = getClassRegistrationByName(className, true);
473
537
  const fname = propertyKey.toString();
474
538
  if (!classReg.registeredOperations.has(fname)) {
475
- classReg.registeredOperations.set(fname, new MethodRegistration(descriptor.value, isInstance, passContext));
539
+ classReg.registeredOperations.set(fname, new MethodRegistration(func, isInstance, passContext));
476
540
  }
477
541
  const methReg = classReg.registeredOperations.get(fname);
478
542
  // Note: We cannot tell if the method takes a context or not.
@@ -486,86 +550,25 @@ function getOrCreateMethodRegistration(target, propertyKey, descriptor, passCont
486
550
  methReg.name = fname;
487
551
  methReg.className = classReg.name;
488
552
  methReg.defaults = classReg;
489
- methReg.args = getOrCreateMethodArgsRegistration(target, propertyKey);
490
- const argNames = getArgNames(descriptor.value);
553
+ methReg.args = getOrCreateMethodArgsRegistration(target, className, propertyKey, func);
554
+ const argNames = getArgNames(func);
491
555
  methReg.args.forEach((e) => {
492
- if (e.required !== ArgRequiredOptions.DEFAULT) {
493
- classReg.argRequiredEnabled = true;
494
- }
495
556
  if (!e.name) {
496
557
  if (e.index < argNames.length) {
497
558
  e.name = argNames[e.index];
498
559
  }
499
- if (e.index === 0 && passContext) {
500
- // The first argument is always the context.
501
- e.logMask = LogMasks.SKIP;
502
- }
503
- // TODO else warn/log something
504
560
  }
505
561
  });
506
562
  const wrappedMethod = async function (...rawArgs) {
507
- let opCtx = undefined;
508
- if (passContext) {
509
- opCtx = rawArgs[0];
510
- }
511
- else {
512
- opCtx = (0, context_1.getCurrentDBOSContext)();
563
+ let validatedArgs = rawArgs;
564
+ for (const vf of methReg.onEnter) {
565
+ validatedArgs = vf.func(methReg, validatedArgs);
513
566
  }
514
- // Validate the user authentication and populate the role field
515
- const requiredRoles = methReg.getRequiredRoles();
516
- if (requiredRoles.length > 0) {
517
- opCtx.span.setAttribute('requiredRoles', requiredRoles);
518
- const curRoles = opCtx.authenticatedRoles;
519
- let authorized = false;
520
- const set = new Set(curRoles);
521
- for (const role of requiredRoles) {
522
- if (set.has(role)) {
523
- authorized = true;
524
- opCtx.assumedRole = role;
525
- break;
526
- }
527
- }
528
- if (!authorized) {
529
- const err = new error_1.DBOSNotAuthorizedError(`User does not have a role with permission to call ${methReg.name}`, 403);
530
- opCtx.span.addEvent('DBOSNotAuthorizedError', { message: err.message });
531
- throw err;
532
- }
533
- }
534
- const validatedArgs = (0, data_validation_1.validateMethodArgs)(methReg, rawArgs);
535
- // Argument logging
536
- validatedArgs.forEach((argValue, idx) => {
537
- let isCtx = false;
538
- // TODO: we assume the first argument is always a context, need a more robust way to test it.
539
- if (idx === 0 && passContext) {
540
- // Context -- I suppose we could just instanceof
541
- opCtx = validatedArgs[0];
542
- isCtx = true;
543
- }
544
- let loggedArgValue = argValue;
545
- if (isCtx || methReg.args[idx].logMask === LogMasks.SKIP) {
546
- return;
547
- }
548
- else {
549
- if (methReg.args[idx].logMask !== LogMasks.NONE) {
550
- // For now this means hash
551
- if (methReg.args[idx].dataType?.dataType === 'json') {
552
- loggedArgValue = generateSaltedHash(JSON.stringify(argValue), 'JSONSALT');
553
- }
554
- else {
555
- // Yes, we are doing the same as above for now.
556
- // It can be better if we have verified the type of the data
557
- loggedArgValue = generateSaltedHash(JSON.stringify(argValue), 'DBOSSALT');
558
- }
559
- }
560
- opCtx?.span.setAttribute(methReg.args[idx].name, loggedArgValue);
561
- }
562
- });
563
567
  return methReg.origFunction.call(this, ...validatedArgs);
564
568
  };
565
569
  Object.defineProperty(wrappedMethod, 'name', {
566
570
  value: methReg.name,
567
571
  });
568
- descriptor.value = wrappedMethod;
569
572
  methReg.registeredFunction = wrappedMethod;
570
573
  methodToRegistration.set(methReg.registeredFunction, methReg);
571
574
  methodToRegistration.set(methReg.origFunction, methReg);
@@ -577,7 +580,8 @@ function registerAndWrapFunctionTakingContext(target, propertyKey, descriptor) {
577
580
  if (!descriptor.value) {
578
581
  throw Error('Use of decorator when original method is undefined');
579
582
  }
580
- const registration = getOrCreateMethodRegistration(target, propertyKey, descriptor, true);
583
+ const registration = getOrCreateMethodRegistration(target, undefined, propertyKey, descriptor.value, true);
584
+ descriptor.value = registration.wrappedFunction ?? registration.registeredFunction;
581
585
  return { descriptor, registration };
582
586
  }
583
587
  exports.registerAndWrapFunctionTakingContext = registerAndWrapFunctionTakingContext;
@@ -586,25 +590,63 @@ function registerAndWrapDBOSFunction(target, propertyKey, descriptor) {
586
590
  if (!descriptor.value) {
587
591
  throw Error('Use of decorator when original method is undefined');
588
592
  }
589
- const registration = getOrCreateMethodRegistration(target, propertyKey, descriptor, false);
593
+ const registration = getOrCreateMethodRegistration(target, undefined, propertyKey, descriptor.value, false);
594
+ descriptor.value = registration.wrappedFunction ?? registration.registeredFunction;
590
595
  return { descriptor, registration };
591
596
  }
592
597
  exports.registerAndWrapDBOSFunction = registerAndWrapDBOSFunction;
598
+ function registerAndWrapDBOSFunctionByName(target, className, funcName, func) {
599
+ ensureDBOSIsNotLaunched();
600
+ const registration = getOrCreateMethodRegistration(target, className, funcName, func, false);
601
+ return { registration };
602
+ }
603
+ exports.registerAndWrapDBOSFunctionByName = registerAndWrapDBOSFunctionByName;
593
604
  const classesByName = new Map();
594
- function getAllRegisteredClasses() {
595
- const ctors = [];
596
- for (const [_cn, creg] of classesByName) {
597
- ctors.push(creg.ctor);
605
+ const classesByCtor = new Map();
606
+ function getNameForClass(ctor) {
607
+ let regtarget;
608
+ if (typeof ctor === 'function') {
609
+ // Static method case
610
+ regtarget = ctor;
598
611
  }
599
- return ctors;
612
+ else {
613
+ // Instance method case
614
+ regtarget = ctor.constructor;
615
+ }
616
+ if (!classesByCtor.has(regtarget))
617
+ return regtarget.name;
618
+ return classesByCtor.get(regtarget).name;
600
619
  }
601
- exports.getAllRegisteredClasses = getAllRegisteredClasses;
620
+ exports.getNameForClass = getNameForClass;
621
+ function getAllRegisteredClassNames() {
622
+ const cnames = [];
623
+ for (const [cn, _creg] of classesByName) {
624
+ cnames.push(cn);
625
+ }
626
+ return cnames;
627
+ }
628
+ exports.getAllRegisteredClassNames = getAllRegisteredClassNames;
629
+ function getClassRegistrationByName(name, create = false) {
630
+ if (!classesByName.has(name) && !create) {
631
+ throw new error_1.DBOSNotRegisteredError(name, `Class '${name}' is not registered`);
632
+ }
633
+ if (!classesByName.has(name)) {
634
+ classesByName.set(name, { reg: new ClassRegistration() });
635
+ }
636
+ const clsReg = classesByName.get(name).reg;
637
+ if (clsReg.needsInitialized) {
638
+ clsReg.name = name;
639
+ clsReg.needsInitialized = false;
640
+ }
641
+ return clsReg;
642
+ }
643
+ exports.getClassRegistrationByName = getClassRegistrationByName;
602
644
  function getOrCreateClassRegistration(ctor) {
603
- const name = ctor.name;
645
+ const name = getNameForClass(ctor);
604
646
  if (!classesByName.has(name)) {
605
- classesByName.set(name, new ClassRegistration(ctor));
647
+ classesByName.set(name, { ctor, reg: new ClassRegistration() });
606
648
  }
607
- const clsReg = classesByName.get(name);
649
+ const clsReg = classesByName.get(name).reg;
608
650
  if (clsReg.needsInitialized) {
609
651
  clsReg.name = name;
610
652
  clsReg.needsInitialized = false;
@@ -629,6 +671,12 @@ function associateClassWithEventReceiver(rcvr, ctor) {
629
671
  return clsReg.eventReceiverInfo.get(rcvr);
630
672
  }
631
673
  exports.associateClassWithEventReceiver = associateClassWithEventReceiver;
674
+ function associateClassWithExternal(external, cls) {
675
+ const clsn = typeof cls === 'string' ? cls : getNameForClass(cls);
676
+ const clsreg = getClassRegistrationByName(clsn, true);
677
+ return clsreg.getRegisteredInfo(external);
678
+ }
679
+ exports.associateClassWithExternal = associateClassWithExternal;
632
680
  /**
633
681
  * Associates a workflow method with a `DBOSEventReceiver` which will be in charge of calling the method
634
682
  * in response to received events.
@@ -648,91 +696,104 @@ function associateMethodWithEventReceiver(rcvr, target, propertyKey, inDescripto
648
696
  return { descriptor, registration, receiverInfo: registration.eventReceiverInfo.get(rcvr) };
649
697
  }
650
698
  exports.associateMethodWithEventReceiver = associateMethodWithEventReceiver;
699
+ /*
700
+ * Associates a DBOS function or method with an external class or object.
701
+ * Likely, this will be invoking or intercepting the method.
702
+ */
703
+ function associateMethodWithExternal(external, target, className, funcName, func) {
704
+ const { registration } = registerAndWrapDBOSFunctionByName(target, className, funcName, func);
705
+ if (!registration.externalRegInfo.has(external)) {
706
+ registration.externalRegInfo.set(external, {});
707
+ }
708
+ return { registration, regInfo: registration.externalRegInfo.get(external) };
709
+ }
710
+ exports.associateMethodWithExternal = associateMethodWithExternal;
711
+ /*
712
+ * Associates a DBOS function or method with an external class or object.
713
+ * Likely, this will be invoking or intercepting the method.
714
+ */
715
+ function associateParameterWithExternal(external, target, className, funcName, func, paramId) {
716
+ if (!func) {
717
+ func = Object.getOwnPropertyDescriptor(target, funcName).value;
718
+ }
719
+ const { registration } = registerAndWrapDBOSFunctionByName(target, className, funcName, func);
720
+ let param;
721
+ if (typeof paramId === 'number') {
722
+ param = registration.args[paramId];
723
+ }
724
+ else {
725
+ param = registration.args.find((p) => p.name === paramId);
726
+ }
727
+ if (!param)
728
+ return undefined;
729
+ if (!param.externalRegInfo.has(external)) {
730
+ param.externalRegInfo.set(external, {});
731
+ }
732
+ return param.externalRegInfo.get(external);
733
+ }
734
+ exports.associateParameterWithExternal = associateParameterWithExternal;
735
+ function getRegistrationsForExternal(external, cls, funcName) {
736
+ const res = [];
737
+ if (cls) {
738
+ const clsname = typeof cls === 'string' ? cls : getNameForClass(cls);
739
+ const c = classesByName.get(clsname);
740
+ if (c) {
741
+ if (funcName) {
742
+ const f = c.reg.registeredOperations.get(funcName);
743
+ if (f) {
744
+ collectRegForFunction(f);
745
+ }
746
+ }
747
+ else {
748
+ collectRegForClass(c);
749
+ }
750
+ }
751
+ }
752
+ else {
753
+ for (const [_cn, c] of classesByName) {
754
+ collectRegForClass(c);
755
+ }
756
+ }
757
+ return res;
758
+ function collectRegForClass(c) {
759
+ for (const [_fn, f] of c.reg.registeredOperations) {
760
+ collectRegForFunction(f);
761
+ }
762
+ }
763
+ function collectRegForFunction(f) {
764
+ const methodConfig = f.externalRegInfo.get(external);
765
+ const classConfig = f.defaults?.externalRegInfo.get(external);
766
+ const paramConfig = [];
767
+ let hasParamConfig = false;
768
+ for (const arg of f.args) {
769
+ if (arg.externalRegInfo.has(external))
770
+ hasParamConfig = true;
771
+ paramConfig.push({
772
+ name: arg.name,
773
+ index: arg.index,
774
+ paramConfig: arg.externalRegInfo.get(external),
775
+ });
776
+ }
777
+ if (!methodConfig && !classConfig && !hasParamConfig)
778
+ return;
779
+ res.push({ methodReg: f, methodConfig, classConfig: classConfig ?? {}, paramConfig });
780
+ }
781
+ }
782
+ exports.getRegistrationsForExternal = getRegistrationsForExternal;
651
783
  //////////////////////////
652
784
  /* PARAMETER DECORATORS */
653
785
  //////////////////////////
654
- function ArgRequired(target, propertyKey, parameterIndex) {
655
- const existingParameters = getOrCreateMethodArgsRegistration(target, propertyKey);
656
- const curParam = existingParameters[parameterIndex];
657
- curParam.required = ArgRequiredOptions.REQUIRED;
658
- }
659
- exports.ArgRequired = ArgRequired;
660
- function ArgOptional(target, propertyKey, parameterIndex) {
661
- const existingParameters = getOrCreateMethodArgsRegistration(target, propertyKey);
662
- const curParam = existingParameters[parameterIndex];
663
- curParam.required = ArgRequiredOptions.OPTIONAL;
664
- }
665
- exports.ArgOptional = ArgOptional;
666
- function SkipLogging(target, propertyKey, parameterIndex) {
667
- const existingParameters = getOrCreateMethodArgsRegistration(target, propertyKey);
668
- const curParam = existingParameters[parameterIndex];
669
- curParam.logMask = LogMasks.SKIP;
670
- }
671
- exports.SkipLogging = SkipLogging;
672
- function LogMask(mask) {
673
- return function (target, propertyKey, parameterIndex) {
674
- const existingParameters = getOrCreateMethodArgsRegistration(target, propertyKey);
675
- const curParam = existingParameters[parameterIndex];
676
- curParam.logMask = mask;
677
- };
678
- }
679
- exports.LogMask = LogMask;
680
786
  function ArgName(name) {
681
787
  return function (target, propertyKey, parameterIndex) {
682
- const existingParameters = getOrCreateMethodArgsRegistration(target, propertyKey);
788
+ const existingParameters = getOrCreateMethodArgsRegistration(target, undefined, propertyKey);
683
789
  const curParam = existingParameters[parameterIndex];
684
790
  curParam.name = name;
685
791
  };
686
792
  }
687
793
  exports.ArgName = ArgName;
688
- function ArgDate() {
689
- // TODO a little more info about it - is it a date or timestamp precision?
690
- return function (target, propertyKey, parameterIndex) {
691
- const existingParameters = getOrCreateMethodArgsRegistration(target, propertyKey);
692
- const curParam = existingParameters[parameterIndex];
693
- if (!curParam.dataType)
694
- curParam.dataType = new DBOSDataType();
695
- curParam.dataType.dataType = 'timestamp';
696
- };
697
- }
698
- exports.ArgDate = ArgDate;
699
- function ArgVarchar(length) {
700
- return function (target, propertyKey, parameterIndex) {
701
- const existingParameters = getOrCreateMethodArgsRegistration(target, propertyKey);
702
- const curParam = existingParameters[parameterIndex];
703
- curParam.dataType = DBOSDataType.varchar(length);
704
- };
705
- }
706
- exports.ArgVarchar = ArgVarchar;
707
794
  ///////////////////////
708
795
  /* CLASS DECORATORS */
709
796
  ///////////////////////
710
- function DefaultRequiredRole(anyOf) {
711
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
712
- function clsdec(ctor) {
713
- const clsreg = getOrCreateClassRegistration(ctor);
714
- clsreg.requiredRole = anyOf;
715
- }
716
- return clsdec;
717
- }
718
- exports.DefaultRequiredRole = DefaultRequiredRole;
719
- function DefaultArgRequired(ctor) {
720
- const clsreg = getOrCreateClassRegistration(ctor);
721
- clsreg.defaultArgRequired = ArgRequiredOptions.REQUIRED;
722
- clsreg.argRequiredEnabled = true;
723
- }
724
- exports.DefaultArgRequired = DefaultArgRequired;
725
- function DefaultArgValidate(ctor) {
726
- const clsreg = getOrCreateClassRegistration(ctor);
727
- clsreg.defaultArgValidate = true;
728
- }
729
- exports.DefaultArgValidate = DefaultArgValidate;
730
- function DefaultArgOptional(ctor) {
731
- const clsreg = getOrCreateClassRegistration(ctor);
732
- clsreg.defaultArgRequired = ArgRequiredOptions.OPTIONAL;
733
- clsreg.argRequiredEnabled = true;
734
- }
735
- exports.DefaultArgOptional = DefaultArgOptional;
736
797
  /** @deprecated Use `new` */
737
798
  function configureInstance(cls, name, ...args) {
738
799
  const inst = new cls(name, ...args);
@@ -742,16 +803,6 @@ exports.configureInstance = configureInstance;
742
803
  ///////////////////////
743
804
  /* METHOD DECORATORS */
744
805
  ///////////////////////
745
- /** @see `DBOS.requiredRole` */
746
- function RequiredRole(anyOf) {
747
- function apidec(target, propertyKey, inDescriptor) {
748
- const { descriptor, registration } = registerAndWrapDBOSFunction(target, propertyKey, inDescriptor);
749
- registration.requiredRole = anyOf;
750
- return descriptor;
751
- }
752
- return apidec;
753
- }
754
- exports.RequiredRole = RequiredRole;
755
806
  /**
756
807
  * @deprecated Use `@DBOS.workflow`
757
808
  * To upgrade to DBOS 2.0+ syntax: