@cqrs-ddd/pipeline 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (112) hide show
  1. package/COMMERCIAL_LICENSE.txt +34 -0
  2. package/LICENSE +661 -0
  3. package/README.md +42 -0
  4. package/dist/behaviors/logging.behavior.d.ts +195 -0
  5. package/dist/behaviors/logging.behavior.d.ts.map +1 -0
  6. package/dist/behaviors/logging.behavior.js +206 -0
  7. package/dist/behaviors/logging.behavior.js.map +1 -0
  8. package/dist/constants/pipeline-context.constants.d.ts +34 -0
  9. package/dist/constants/pipeline-context.constants.d.ts.map +1 -0
  10. package/dist/constants/pipeline-context.constants.js +34 -0
  11. package/dist/constants/pipeline-context.constants.js.map +1 -0
  12. package/dist/create-pipeline.d.ts +122 -0
  13. package/dist/create-pipeline.d.ts.map +1 -0
  14. package/dist/create-pipeline.js +193 -0
  15. package/dist/create-pipeline.js.map +1 -0
  16. package/dist/entries.d.ts +13 -0
  17. package/dist/entries.d.ts.map +1 -0
  18. package/dist/entries.js +3 -0
  19. package/dist/entries.js.map +1 -0
  20. package/dist/errors/missing-partition.error.d.ts +27 -0
  21. package/dist/errors/missing-partition.error.d.ts.map +1 -0
  22. package/dist/errors/missing-partition.error.js +33 -0
  23. package/dist/errors/missing-partition.error.js.map +1 -0
  24. package/dist/errors/missing-pipeline-item.error.d.ts +8 -0
  25. package/dist/errors/missing-pipeline-item.error.d.ts.map +1 -0
  26. package/dist/errors/missing-pipeline-item.error.js +16 -0
  27. package/dist/errors/missing-pipeline-item.error.js.map +1 -0
  28. package/dist/handler-pipeline.d.ts +62 -0
  29. package/dist/handler-pipeline.d.ts.map +1 -0
  30. package/dist/handler-pipeline.js +74 -0
  31. package/dist/handler-pipeline.js.map +1 -0
  32. package/dist/helpers/behavior-entries.d.ts +34 -0
  33. package/dist/helpers/behavior-entries.d.ts.map +1 -0
  34. package/dist/helpers/behavior-entries.js +50 -0
  35. package/dist/helpers/behavior-entries.js.map +1 -0
  36. package/dist/helpers/behavior-id.d.ts +43 -0
  37. package/dist/helpers/behavior-id.d.ts.map +1 -0
  38. package/dist/helpers/behavior-id.js +38 -0
  39. package/dist/helpers/behavior-id.js.map +1 -0
  40. package/dist/helpers/logging.intent.d.ts +17 -0
  41. package/dist/helpers/logging.intent.d.ts.map +1 -0
  42. package/dist/helpers/logging.intent.js +18 -0
  43. package/dist/helpers/logging.intent.js.map +1 -0
  44. package/dist/helpers/postgres-json.d.ts +25 -0
  45. package/dist/helpers/postgres-json.d.ts.map +1 -0
  46. package/dist/helpers/postgres-json.js +35 -0
  47. package/dist/helpers/postgres-json.js.map +1 -0
  48. package/dist/helpers/replace-request.d.ts +19 -0
  49. package/dist/helpers/replace-request.d.ts.map +1 -0
  50. package/dist/helpers/replace-request.js +29 -0
  51. package/dist/helpers/replace-request.js.map +1 -0
  52. package/dist/helpers/tenant-partition.d.ts +38 -0
  53. package/dist/helpers/tenant-partition.d.ts.map +1 -0
  54. package/dist/helpers/tenant-partition.js +27 -0
  55. package/dist/helpers/tenant-partition.js.map +1 -0
  56. package/dist/index.d.ts +27 -0
  57. package/dist/index.d.ts.map +1 -0
  58. package/dist/index.js +24 -0
  59. package/dist/index.js.map +1 -0
  60. package/dist/interfaces/context-source.interface.d.ts +42 -0
  61. package/dist/interfaces/context-source.interface.d.ts.map +1 -0
  62. package/dist/interfaces/context-source.interface.js +3 -0
  63. package/dist/interfaces/context-source.interface.js.map +1 -0
  64. package/dist/interfaces/pipeline-behavior-contract.interface.d.ts +99 -0
  65. package/dist/interfaces/pipeline-behavior-contract.interface.d.ts.map +1 -0
  66. package/dist/interfaces/pipeline-behavior-contract.interface.js +22 -0
  67. package/dist/interfaces/pipeline-behavior-contract.interface.js.map +1 -0
  68. package/dist/interfaces/pipeline-handler-meta.interface.d.ts +15 -0
  69. package/dist/interfaces/pipeline-handler-meta.interface.d.ts.map +1 -0
  70. package/dist/interfaces/pipeline-handler-meta.interface.js +3 -0
  71. package/dist/interfaces/pipeline-handler-meta.interface.js.map +1 -0
  72. package/dist/interfaces/pipeline.behavior.interface.d.ts +38 -0
  73. package/dist/interfaces/pipeline.behavior.interface.d.ts.map +1 -0
  74. package/dist/interfaces/pipeline.behavior.interface.js +3 -0
  75. package/dist/interfaces/pipeline.behavior.interface.js.map +1 -0
  76. package/dist/interfaces/pipeline.context.interface.d.ts +69 -0
  77. package/dist/interfaces/pipeline.context.interface.d.ts.map +1 -0
  78. package/dist/interfaces/pipeline.context.interface.js +3 -0
  79. package/dist/interfaces/pipeline.context.interface.js.map +1 -0
  80. package/dist/logger.d.ts +45 -0
  81. package/dist/logger.d.ts.map +1 -0
  82. package/dist/logger.js +64 -0
  83. package/dist/logger.js.map +1 -0
  84. package/dist/options/global-behaviors.options.d.ts +57 -0
  85. package/dist/options/global-behaviors.options.d.ts.map +1 -0
  86. package/dist/options/global-behaviors.options.js +3 -0
  87. package/dist/options/global-behaviors.options.js.map +1 -0
  88. package/dist/pipeline-items.d.ts +22 -0
  89. package/dist/pipeline-items.d.ts.map +1 -0
  90. package/dist/pipeline-items.js +34 -0
  91. package/dist/pipeline-items.js.map +1 -0
  92. package/dist/pipeline.context.d.ts +86 -0
  93. package/dist/pipeline.context.d.ts.map +1 -0
  94. package/dist/pipeline.context.js +109 -0
  95. package/dist/pipeline.context.js.map +1 -0
  96. package/dist/services/pipeline-contracts.d.ts +29 -0
  97. package/dist/services/pipeline-contracts.d.ts.map +1 -0
  98. package/dist/services/pipeline-contracts.js +102 -0
  99. package/dist/services/pipeline-contracts.js.map +1 -0
  100. package/dist/services/pipeline-plan.d.ts +49 -0
  101. package/dist/services/pipeline-plan.d.ts.map +1 -0
  102. package/dist/services/pipeline-plan.js +111 -0
  103. package/dist/services/pipeline-plan.js.map +1 -0
  104. package/dist/services/pipeline-runner.d.ts +26 -0
  105. package/dist/services/pipeline-runner.d.ts.map +1 -0
  106. package/dist/services/pipeline-runner.js +68 -0
  107. package/dist/services/pipeline-runner.js.map +1 -0
  108. package/dist/types.d.ts +3 -0
  109. package/dist/types.d.ts.map +1 -0
  110. package/dist/types.js +3 -0
  111. package/dist/types.js.map +1 -0
  112. package/package.json +63 -0
@@ -0,0 +1,69 @@
1
+ import type { Constructor } from '../types.js';
2
+ /**
3
+ * Rich context available to every pipeline behavior during execution.
4
+ *
5
+ * Behaviors should type-hint against this **interface** to stay decoupled.
6
+ * The concrete implementation ({@link BasePipelineContext}) provides shared
7
+ * logic; extend it only when you need a custom context variant.
8
+ */
9
+ export interface IPipelineContext<TRequest = unknown, TResponse = unknown> {
10
+ /**
11
+ * Immutable correlation ID for distributed tracing: the current correlation
12
+ * id when the pipeline starts (from `@cqrs-ddd/pipeline-correlation`, or the
13
+ * enclosing pipeline), otherwise a new one from the correlation source's
14
+ * `create()` (`uuidv7()` without one). Nested dispatches
15
+ * inherit it.
16
+ */
17
+ readonly correlationId: string;
18
+ /**
19
+ * Tenant of this execution: the current tenant when the pipeline starts
20
+ * (from `@cqrs-ddd/pipeline-tenant`, or the enclosing pipeline), which nested
21
+ * dispatches inherit. Absent when there is none; tenant-scoped behaviors
22
+ * then fail closed.
23
+ */
24
+ readonly tenantId?: string;
25
+ /** The command/query/event instance with all its property values. */
26
+ readonly request: TRequest;
27
+ /** The class (constructor) of the command/query/event. */
28
+ readonly requestType: Constructor<TRequest>;
29
+ /** The class name string, e.g. "CreateUserCommand". */
30
+ readonly requestName: string;
31
+ /** The handler class (constructor) that will process this request. */
32
+ readonly handlerType: Constructor;
33
+ /** The handler class name string, e.g. "CreateUserHandler". */
34
+ readonly handlerName: string;
35
+ /** 'command', 'query', or 'event': declared when wrapping, or read from the request's brand. */
36
+ readonly requestKind: 'command' | 'query' | 'event' | 'unknown';
37
+ /** UTC timestamp when the pipeline execution started. */
38
+ readonly startedAt: Date;
39
+ /**
40
+ * The handler's return value, set automatically after the real handler executes.
41
+ * Available to behaviors in their post-`next()` code path.
42
+ * `undefined` before the handler runs or for event handlers that return void.
43
+ */
44
+ readonly response: TResponse | undefined;
45
+ /**
46
+ * Bag for sharing arbitrary data between behaviors in the same execution.
47
+ * Use createPipelineItem and the typed item accessors for compile-time value checks.
48
+ * Raw map access remains supported and bypasses those checks.
49
+ *
50
+ * Keys can be strings or exported `unique symbol` constants. Exported symbols
51
+ * are strongly recommended to prevent collision between behaviors or third-party packages.
52
+ *
53
+ * @example
54
+ * ```ts
55
+ * export const MY_ITEM = Symbol('MY_ITEM');
56
+ * context.items.set(MY_ITEM, customData);
57
+ * const val = context.items.get(MY_ITEM);
58
+ * ```
59
+ */
60
+ readonly items: Map<string | symbol, unknown>;
61
+ /**
62
+ * Returns the options for a behavior on this handler: the options from a
63
+ * global `[Behavior, opts]` tuple, shallowly overridden by the options of the
64
+ * call site's `[Behavior, opts]` entry. Returns undefined when
65
+ * neither supplies options for that behavior.
66
+ */
67
+ getBehaviorOptions<T = Record<string, unknown>>(behaviorType: Constructor): T | undefined;
68
+ }
69
+ //# sourceMappingURL=pipeline.context.interface.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pipeline.context.interface.d.ts","sourceRoot":"","sources":["../../src/interfaces/pipeline.context.interface.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C;;;;;;GAMG;AACH,MAAM,WAAW,gBAAgB,CAAC,QAAQ,GAAG,OAAO,EAAE,SAAS,GAAG,OAAO;IACvE;;;;;;OAMG;IACH,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAE/B;;;;;OAKG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAE3B,qEAAqE;IACrE,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC;IAE3B,0DAA0D;IAC1D,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC,QAAQ,CAAC,CAAC;IAE5C,uDAAuD;IACvD,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAE7B,sEAAsE;IACtE,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC;IAElC,+DAA+D;IAC/D,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAE7B,gGAAgG;IAChG,QAAQ,CAAC,WAAW,EAAE,SAAS,GAAG,OAAO,GAAG,OAAO,GAAG,SAAS,CAAC;IAEhE,yDAAyD;IACzD,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC;IAEzB;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,EAAE,SAAS,GAAG,SAAS,CAAC;IAEzC;;;;;;;;;;;;;;OAcG;IACH,QAAQ,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,GAAG,MAAM,EAAE,OAAO,CAAC,CAAC;IAE9C;;;;;OAKG;IACH,kBAAkB,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5C,YAAY,EAAE,WAAW,GACxB,CAAC,GAAG,SAAS,CAAC;CAClB"}
@@ -0,0 +1,3 @@
1
+ /* Copyright (C) 2026-present Aristotelis — see repository license. */
2
+ export {};
3
+ //# sourceMappingURL=pipeline.context.interface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pipeline.context.interface.js","sourceRoot":"","sources":["../../src/interfaces/pipeline.context.interface.ts"],"names":[],"mappings":"AAAA,sEAAsE"}
@@ -0,0 +1,45 @@
1
+ /** The levels behaviors log at, named as NestJS names them. */
2
+ export type LogLevel = 'log' | 'error' | 'warn' | 'debug' | 'verbose' | 'fatal';
3
+ /**
4
+ * The logger a behavior writes through. `console` satisfies it, and so does a NestJS
5
+ * `LoggerService`; a pino logger does through {@link pinoLogger}. A missing optional
6
+ * method makes that level silent.
7
+ */
8
+ export interface PipelineLogger {
9
+ log(message: unknown, ...optionalParams: unknown[]): unknown;
10
+ error(message: unknown, ...optionalParams: unknown[]): unknown;
11
+ warn(message: unknown, ...optionalParams: unknown[]): unknown;
12
+ debug?(message: unknown, ...optionalParams: unknown[]): unknown;
13
+ verbose?(message: unknown, ...optionalParams: unknown[]): unknown;
14
+ fatal?(message: unknown, ...optionalParams: unknown[]): unknown;
15
+ }
16
+ /** The methods of a pino logger that {@link pinoLogger} calls. */
17
+ export interface PinoLike {
18
+ trace(fields: object, message?: string): unknown;
19
+ debug(fields: object, message?: string): unknown;
20
+ info(fields: object, message?: string): unknown;
21
+ warn(fields: object, message?: string): unknown;
22
+ error(fields: object, message?: string): unknown;
23
+ fatal(fields: object, message?: string): unknown;
24
+ }
25
+ /**
26
+ * Adapts a pino logger to {@link PipelineLogger}, so behaviors write structured records:
27
+ * `log` writes at pino's `info` and `verbose` at `trace`; the last string argument of a
28
+ * call with more than one is the `context` field, as NestJS passes it; on `error`, a string
29
+ * before it is the `stack` field; an `Error` message becomes `err`; an object message, such
30
+ * as `LoggingBehavior`'s `logFormat: 'structured'` records, becomes the record's fields;
31
+ * other arguments go to `params`.
32
+ *
33
+ * @example
34
+ * ```ts
35
+ * import pino from 'pino';
36
+ *
37
+ * const logger = pinoLogger(pino());
38
+ * const pipeline = createPipeline({
39
+ * logger,
40
+ * globalBehaviors: { before: [logging({ logFormat: 'structured' })] },
41
+ * });
42
+ * ```
43
+ */
44
+ export declare function pinoLogger(pino: PinoLike): Required<PipelineLogger>;
45
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAEA,+DAA+D;AAC/D,MAAM,MAAM,QAAQ,GAAG,KAAK,GAAG,OAAO,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,GAAG,OAAO,CAAC;AAEhF;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC7B,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,cAAc,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;IAC7D,KAAK,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,cAAc,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;IAC/D,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,cAAc,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;IAC9D,KAAK,CAAC,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,cAAc,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;IAChE,OAAO,CAAC,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,cAAc,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;IAClE,KAAK,CAAC,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,cAAc,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;CACjE;AAED,kEAAkE;AAClE,MAAM,WAAW,QAAQ;IACvB,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACjD,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACjD,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAChD,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAChD,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACjD,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;CAClD;AAWD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,QAAQ,GAAG,QAAQ,CAAC,cAAc,CAAC,CAiCnE"}
package/dist/logger.js ADDED
@@ -0,0 +1,64 @@
1
+ /* Copyright (C) 2026-present Aristotelis — see repository license. */
2
+ const PINO_LEVEL = {
3
+ log: 'info',
4
+ error: 'error',
5
+ warn: 'warn',
6
+ debug: 'debug',
7
+ verbose: 'trace',
8
+ fatal: 'fatal',
9
+ };
10
+ /**
11
+ * Adapts a pino logger to {@link PipelineLogger}, so behaviors write structured records:
12
+ * `log` writes at pino's `info` and `verbose` at `trace`; the last string argument of a
13
+ * call with more than one is the `context` field, as NestJS passes it; on `error`, a string
14
+ * before it is the `stack` field; an `Error` message becomes `err`; an object message, such
15
+ * as `LoggingBehavior`'s `logFormat: 'structured'` records, becomes the record's fields;
16
+ * other arguments go to `params`.
17
+ *
18
+ * @example
19
+ * ```ts
20
+ * import pino from 'pino';
21
+ *
22
+ * const logger = pinoLogger(pino());
23
+ * const pipeline = createPipeline({
24
+ * logger,
25
+ * globalBehaviors: { before: [logging({ logFormat: 'structured' })] },
26
+ * });
27
+ * ```
28
+ */
29
+ export function pinoLogger(pino) {
30
+ const write = (level) => (message, ...params) => {
31
+ const last = params.at(-1);
32
+ const context = params.length > 0 && typeof last === 'string' ? last : undefined;
33
+ const rest = context === undefined ? params : params.slice(0, -1);
34
+ const stack = level === 'error' && typeof rest[0] === 'string'
35
+ ? rest.shift()
36
+ : undefined;
37
+ const fields = {};
38
+ if (context !== undefined)
39
+ fields.context = context;
40
+ if (stack !== undefined)
41
+ fields.stack = stack;
42
+ if (rest.length > 0)
43
+ fields.params = rest;
44
+ const target = PINO_LEVEL[level];
45
+ if (message instanceof Error) {
46
+ pino[target]({ ...fields, err: message }, message.message);
47
+ }
48
+ else if (typeof message === 'object' && message !== null) {
49
+ pino[target]({ ...fields, ...message });
50
+ }
51
+ else {
52
+ pino[target](fields, String(message));
53
+ }
54
+ };
55
+ return {
56
+ log: write('log'),
57
+ error: write('error'),
58
+ warn: write('warn'),
59
+ debug: write('debug'),
60
+ verbose: write('verbose'),
61
+ fatal: write('fatal'),
62
+ };
63
+ }
64
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA,sEAAsE;AA6BtE,MAAM,UAAU,GAAG;IACjB,GAAG,EAAE,MAAM;IACX,KAAK,EAAE,OAAO;IACd,IAAI,EAAE,MAAM;IACZ,KAAK,EAAE,OAAO;IACd,OAAO,EAAE,OAAO;IAChB,KAAK,EAAE,OAAO;CACN,CAAC;AAEX;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,UAAU,CAAC,IAAc;IACvC,MAAM,KAAK,GACT,CAAC,KAAe,EAAE,EAAE,CACpB,CAAC,OAAgB,EAAE,GAAG,MAAiB,EAAQ,EAAE;QAC/C,MAAM,IAAI,GAAG,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAC3B,MAAM,OAAO,GACX,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;QACnE,MAAM,IAAI,GAAG,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAClE,MAAM,KAAK,GACT,KAAK,KAAK,OAAO,IAAI,OAAO,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ;YAC9C,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE;YACd,CAAC,CAAC,SAAS,CAAC;QAChB,MAAM,MAAM,GAA4B,EAAE,CAAC;QAC3C,IAAI,OAAO,KAAK,SAAS;YAAE,MAAM,CAAC,OAAO,GAAG,OAAO,CAAC;QACpD,IAAI,KAAK,KAAK,SAAS;YAAE,MAAM,CAAC,KAAK,GAAG,KAAK,CAAC;QAC9C,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC;YAAE,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC;QAC1C,MAAM,MAAM,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;QACjC,IAAI,OAAO,YAAY,KAAK,EAAE,CAAC;YAC7B,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,GAAG,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;QAC7D,CAAC;aAAM,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;YAC3D,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,GAAG,MAAM,EAAE,GAAG,OAAO,EAAE,CAAC,CAAC;QAC1C,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;QACxC,CAAC;IACH,CAAC,CAAC;IACJ,OAAO;QACL,GAAG,EAAE,KAAK,CAAC,KAAK,CAAC;QACjB,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC;QACrB,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC;QACnB,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC;QACrB,OAAO,EAAE,KAAK,CAAC,SAAS,CAAC;QACzB,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC;KACtB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,57 @@
1
+ import type { PipelineBehaviorEntry } from '../entries.js';
2
+ /** Determines which handler kinds global behaviors apply to. */
3
+ export type GlobalBehaviorScope = 'commands' | 'queries' | 'events' | 'all';
4
+ /**
5
+ * Configuration for behaviors that are automatically applied to all
6
+ * Commands, Queries, and/or Events, regardless of the entries declared at a call site.
7
+ *
8
+ * Execution order:
9
+ * `[before] → [call-site behaviors] → [after] → handler`. If the same
10
+ * behavior class is declared globally and at a call site, it runs once at its
11
+ * global position with the call-site options merged over the global ones.
12
+ *
13
+ * @example
14
+ * ```ts
15
+ * // Single object
16
+ * createPipeline({
17
+ * globalBehaviors: {
18
+ * scope: 'all',
19
+ * before: [LoggingBehavior, [MetricsBehavior, { meterName: 'api' }]],
20
+ * after: [AuditBehavior],
21
+ * },
22
+ * });
23
+ *
24
+ * // Array — different scopes for different request kinds
25
+ * createPipeline({
26
+ * globalBehaviors: [
27
+ * { scope: 'commands', before: [AuditBehavior] },
28
+ * { scope: 'queries', before: [CacheBehavior] },
29
+ * { scope: 'all', after: [LoggingBehavior] },
30
+ * ],
31
+ * });
32
+ * ```
33
+ */
34
+ export interface GlobalBehaviorsOptions {
35
+ /**
36
+ * Which handler kinds these behaviors apply to.
37
+ * - `'commands'` — only command handlers
38
+ * - `'queries'` — only query handlers
39
+ * - `'events'` — only event handlers
40
+ * - `'all'` — commands, queries, and events
41
+ *
42
+ * @default 'all'
43
+ */
44
+ scope?: GlobalBehaviorScope;
45
+ /**
46
+ * Behaviors prepended BEFORE the behaviors declared at the call site.
47
+ * These run first (outermost) in the pipeline chain.
48
+ */
49
+ before?: PipelineBehaviorEntry[];
50
+ /**
51
+ * Behaviors appended AFTER the behaviors declared at the call site
52
+ * (still before the actual handler execution).
53
+ * These run closest to the handler, after all other behaviors.
54
+ */
55
+ after?: PipelineBehaviorEntry[];
56
+ }
57
+ //# sourceMappingURL=global-behaviors.options.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"global-behaviors.options.d.ts","sourceRoot":"","sources":["../../src/options/global-behaviors.options.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAE3D,gEAAgE;AAChE,MAAM,MAAM,mBAAmB,GAAG,UAAU,GAAG,SAAS,GAAG,QAAQ,GAAG,KAAK,CAAC;AAE5E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,MAAM,WAAW,sBAAsB;IACrC;;;;;;;;OAQG;IACH,KAAK,CAAC,EAAE,mBAAmB,CAAC;IAE5B;;;OAGG;IACH,MAAM,CAAC,EAAE,qBAAqB,EAAE,CAAC;IAEjC;;;;OAIG;IACH,KAAK,CAAC,EAAE,qBAAqB,EAAE,CAAC;CACjC"}
@@ -0,0 +1,3 @@
1
+ /* Copyright (C) 2026-present Aristotelis — see repository license. */
2
+ export {};
3
+ //# sourceMappingURL=global-behaviors.options.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"global-behaviors.options.js","sourceRoot":"","sources":["../../src/options/global-behaviors.options.ts"],"names":[],"mappings":"AAAA,sEAAsE"}
@@ -0,0 +1,22 @@
1
+ import type { IPipelineContext } from './interfaces/pipeline.context.interface.js';
2
+ /** Associates a context map key with its compile-time value type. */
3
+ export interface PipelineItemToken<T> {
4
+ readonly key: string | symbol;
5
+ readonly name: string;
6
+ readonly __itemType?: T;
7
+ }
8
+ /** Creates a unique symbol-backed token, or wraps an existing interoperability key. */
9
+ export declare function createPipelineItem<T>(name: string, key?: string | symbol): PipelineItemToken<T>;
10
+ /** Reads an item without runtime type validation. Raw keys require a caller-supplied type. */
11
+ export declare function getPipelineItem<T>(context: IPipelineContext, token: PipelineItemToken<T> | string | symbol): T | undefined;
12
+ /** Writes an item using the token's value type; raw keys remain unchecked. */
13
+ export declare function setPipelineItem<T>(context: IPipelineContext, token: PipelineItemToken<T> | string | symbol, value: NoInfer<T>): void;
14
+ /**
15
+ * Reads a required item, throwing MissingPipelineItemError for absent or undefined values.
16
+ * Null and other falsy values are returned unchanged. No runtime type validation occurs.
17
+ * The optional custom message supplements the item, request and handler diagnostic.
18
+ */
19
+ export declare function requirePipelineItem<T>(context: IPipelineContext, token: PipelineItemToken<T> | string | symbol, customMessage?: string): T;
20
+ /** Checks key presence, including entries explicitly set to undefined. */
21
+ export declare function hasPipelineItem<T>(context: IPipelineContext, token: PipelineItemToken<T> | string | symbol): boolean;
22
+ //# sourceMappingURL=pipeline-items.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pipeline-items.d.ts","sourceRoot":"","sources":["../src/pipeline-items.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4CAA4C,CAAC;AAEnF,qEAAqE;AACrE,MAAM,WAAW,iBAAiB,CAAC,CAAC;IAClC,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;CACzB;AAED,uFAAuF;AACvF,wBAAgB,kBAAkB,CAAC,CAAC,EAClC,IAAI,EAAE,MAAM,EACZ,GAAG,GAAE,MAAM,GAAG,MAAqB,GAClC,iBAAiB,CAAC,CAAC,CAAC,CAEtB;AAQD,8FAA8F;AAC9F,wBAAgB,eAAe,CAAC,CAAC,EAC/B,OAAO,EAAE,gBAAgB,EACzB,KAAK,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAAG,MAAM,GAAG,MAAM,GAC5C,CAAC,GAAG,SAAS,CAEf;AAED,8EAA8E;AAC9E,wBAAgB,eAAe,CAAC,CAAC,EAC/B,OAAO,EAAE,gBAAgB,EACzB,KAAK,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAAG,MAAM,GAAG,MAAM,EAC7C,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,GAChB,IAAI,CAEN;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,EACnC,OAAO,EAAE,gBAAgB,EACzB,KAAK,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAAG,MAAM,GAAG,MAAM,EAC7C,aAAa,CAAC,EAAE,MAAM,GACrB,CAAC,CAWH;AAED,0EAA0E;AAC1E,wBAAgB,eAAe,CAAC,CAAC,EAC/B,OAAO,EAAE,gBAAgB,EACzB,KAAK,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAAG,MAAM,GAAG,MAAM,GAC5C,OAAO,CAET"}
@@ -0,0 +1,34 @@
1
+ /* Copyright (C) 2026-present Aristotelis — see repository license. */
2
+ import { MissingPipelineItemError } from './errors/missing-pipeline-item.error.js';
3
+ /** Creates a unique symbol-backed token, or wraps an existing interoperability key. */
4
+ export function createPipelineItem(name, key = Symbol(name)) {
5
+ return { key, name };
6
+ }
7
+ function itemKey(token) {
8
+ return typeof token === 'object' ? token.key : token;
9
+ }
10
+ /** Reads an item without runtime type validation. Raw keys require a caller-supplied type. */
11
+ export function getPipelineItem(context, token) {
12
+ return context.items.get(itemKey(token));
13
+ }
14
+ /** Writes an item using the token's value type; raw keys remain unchecked. */
15
+ export function setPipelineItem(context, token, value) {
16
+ context.items.set(itemKey(token), value);
17
+ }
18
+ /**
19
+ * Reads a required item, throwing MissingPipelineItemError for absent or undefined values.
20
+ * Null and other falsy values are returned unchanged. No runtime type validation occurs.
21
+ * The optional custom message supplements the item, request and handler diagnostic.
22
+ */
23
+ export function requirePipelineItem(context, token, customMessage) {
24
+ const value = getPipelineItem(context, token);
25
+ if (value === undefined) {
26
+ throw new MissingPipelineItemError(typeof token === 'object' ? token.name : String(token), context.requestName, context.handlerName, customMessage);
27
+ }
28
+ return value;
29
+ }
30
+ /** Checks key presence, including entries explicitly set to undefined. */
31
+ export function hasPipelineItem(context, token) {
32
+ return context.items.has(itemKey(token));
33
+ }
34
+ //# sourceMappingURL=pipeline-items.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pipeline-items.js","sourceRoot":"","sources":["../src/pipeline-items.ts"],"names":[],"mappings":"AAAA,sEAAsE;AAEtE,OAAO,EAAE,wBAAwB,EAAE,MAAM,yCAAyC,CAAC;AAUnF,uFAAuF;AACvF,MAAM,UAAU,kBAAkB,CAChC,IAAY,EACZ,GAAG,GAAoB,MAAM,CAAC,IAAI,CAAC;IAEnC,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC;AACvB,CAAC;AAED,SAAS,OAAO,CACd,KAA6C;IAE7C,OAAO,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC;AACvD,CAAC;AAED,8FAA8F;AAC9F,MAAM,UAAU,eAAe,CAC7B,OAAyB,EACzB,KAA6C;IAE7C,OAAO,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAkB,CAAC;AAC5D,CAAC;AAED,8EAA8E;AAC9E,MAAM,UAAU,eAAe,CAC7B,OAAyB,EACzB,KAA6C,EAC7C,KAAiB;IAEjB,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,CAAC;AAC3C,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CACjC,OAAyB,EACzB,KAA6C,EAC7C,aAAsB;IAEtB,MAAM,KAAK,GAAG,eAAe,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IAC9C,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,MAAM,IAAI,wBAAwB,CAChC,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EACtD,OAAO,CAAC,WAAW,EACnB,OAAO,CAAC,WAAW,EACnB,aAAa,CACd,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,eAAe,CAC7B,OAAyB,EACzB,KAA6C;IAE7C,OAAO,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;AAC3C,CAAC"}
@@ -0,0 +1,86 @@
1
+ import { SET_CORRELATION_ID, SET_REQUEST, SET_RESPONSE, SET_TENANT_ID } from './constants/pipeline-context.constants.js';
2
+ import { type BehaviorId } from './helpers/behavior-id.js';
3
+ import { IPipelineContext } from './interfaces/pipeline.context.interface.js';
4
+ import { PipelineHandlerMeta } from './interfaces/pipeline-handler-meta.interface.js';
5
+ import type { Constructor } from './types.js';
6
+ /**
7
+ * Abstract base class with shared implementation for all pipeline contexts.
8
+ *
9
+ * Provides default implementations for:
10
+ * - `getBehaviorOptions()` — reads from the pre-computed options map
11
+ * - `response` — readonly holder for the handler's return value (set via Symbol)
12
+ * - Common fields (correlationId, startedAt, items)
13
+ *
14
+ * Extend this class to create custom context variants for specialized pipelines.
15
+ * Behaviors should still type-hint against {@link IPipelineContext} (the interface).
16
+ */
17
+ export declare abstract class BasePipelineContext<TRequest = unknown, TResponse = unknown> implements IPipelineContext<TRequest, TResponse> {
18
+ private _correlationId;
19
+ get correlationId(): string;
20
+ /** @internal Assigns the ID before the behavior chain starts. */
21
+ [SET_CORRELATION_ID](value: string): void;
22
+ private _tenantId;
23
+ /**
24
+ * Active tenant identifier for multi-tenant pipeline executions.
25
+ */
26
+ get tenantId(): string | undefined;
27
+ /**
28
+ * Assigns the tenant once per execution. A different value after one is set
29
+ * (by the runner, from the tenant source or the enclosing pipeline)
30
+ * throws, so a behavior cannot move an execution to another tenant after an
31
+ * earlier behavior has used it.
32
+ */
33
+ [SET_TENANT_ID](value: string | undefined): void;
34
+ abstract readonly request: TRequest;
35
+ abstract readonly requestType: Constructor<TRequest>;
36
+ abstract readonly requestName: string;
37
+ abstract readonly handlerType: Constructor;
38
+ abstract readonly handlerName: string;
39
+ abstract readonly requestKind: 'command' | 'query' | 'event' | 'unknown';
40
+ readonly startedAt: Date;
41
+ /**
42
+ * Bag for sharing arbitrary data between behaviors in the same execution.
43
+ * Supports string and unique symbol keys.
44
+ */
45
+ readonly items: Map<string | symbol, unknown>;
46
+ /** Backing field for `response` — only writable via `[SET_RESPONSE]()`. */
47
+ private _response;
48
+ /** The handler's return value. Read-only for behaviors. */
49
+ get response(): TResponse | undefined;
50
+ /**
51
+ * Symbol-keyed setter — only callable by code that imports `SET_RESPONSE`.
52
+ * This keeps `response` effectively readonly for behaviors.
53
+ */
54
+ [SET_RESPONSE](value: TResponse | undefined): void;
55
+ /**
56
+ * Options per behavior for this handler: global `[Behavior, opts]` tuple
57
+ * options, shallowly overridden by the call site's options.
58
+ */
59
+ protected abstract readonly behaviorOptionsMap: Map<BehaviorId, Record<string, unknown>> | undefined;
60
+ constructor();
61
+ /**
62
+ * Returns the options for a behavior on this handler: the options from a
63
+ * global `[Behavior, opts]` tuple, shallowly overridden by the options of the
64
+ * call site's `[Behavior, opts]` entry.
65
+ */
66
+ getBehaviorOptions<T = Record<string, unknown>>(behaviorType: Constructor): T | undefined;
67
+ }
68
+ /**
69
+ * Concrete pipeline context created per request.
70
+ * Pre-computed handler metadata is injected via {@link PipelineHandlerMeta}.
71
+ */
72
+ export declare class PipelineContext<TRequest = unknown, TResponse = unknown> extends BasePipelineContext<TRequest, TResponse> {
73
+ readonly requestType: Constructor<TRequest>;
74
+ readonly requestName: string;
75
+ readonly handlerType: Constructor;
76
+ readonly handlerName: string;
77
+ readonly requestKind: 'command' | 'query' | 'event' | 'unknown';
78
+ protected readonly behaviorOptionsMap: Map<BehaviorId, Record<string, unknown>> | undefined;
79
+ private _request;
80
+ /** The input of this execution, or the replacement a behavior handed in. */
81
+ get request(): TRequest;
82
+ /** Replaces the input the handler receives; see `replaceRequest`. */
83
+ [SET_REQUEST](value: TRequest): void;
84
+ constructor(request: TRequest, meta: PipelineHandlerMeta);
85
+ }
86
+ //# sourceMappingURL=pipeline.context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pipeline.context.d.ts","sourceRoot":"","sources":["../src/pipeline.context.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,109 @@
1
+ /* Copyright (C) 2026-present Aristotelis — see repository license. */
2
+ import { untyped } from '@cqrs-ddd/untyped';
3
+ import { SET_CORRELATION_ID, SET_REQUEST, SET_RESPONSE, SET_TENANT_ID, } from './constants/pipeline-context.constants.js';
4
+ import { getBehaviorId } from './helpers/behavior-id.js';
5
+ /**
6
+ * Abstract base class with shared implementation for all pipeline contexts.
7
+ *
8
+ * Provides default implementations for:
9
+ * - `getBehaviorOptions()` — reads from the pre-computed options map
10
+ * - `response` — readonly holder for the handler's return value (set via Symbol)
11
+ * - Common fields (correlationId, startedAt, items)
12
+ *
13
+ * Extend this class to create custom context variants for specialized pipelines.
14
+ * Behaviors should still type-hint against {@link IPipelineContext} (the interface).
15
+ */
16
+ export class BasePipelineContext {
17
+ _correlationId = '';
18
+ get correlationId() {
19
+ return this._correlationId;
20
+ }
21
+ /** @internal Assigns the ID before the behavior chain starts. */
22
+ [SET_CORRELATION_ID](value) {
23
+ this._correlationId = value;
24
+ }
25
+ _tenantId = undefined;
26
+ /**
27
+ * Active tenant identifier for multi-tenant pipeline executions.
28
+ */
29
+ get tenantId() {
30
+ return this._tenantId;
31
+ }
32
+ /**
33
+ * Assigns the tenant once per execution. A different value after one is set
34
+ * (by the runner, from the tenant source or the enclosing pipeline)
35
+ * throws, so a behavior cannot move an execution to another tenant after an
36
+ * earlier behavior has used it.
37
+ */
38
+ [SET_TENANT_ID](value) {
39
+ if (this._tenantId !== undefined && this._tenantId !== value) {
40
+ throw new Error('PipelineContext tenantId is already assigned and cannot be changed');
41
+ }
42
+ this._tenantId = value;
43
+ }
44
+ startedAt;
45
+ /**
46
+ * Bag for sharing arbitrary data between behaviors in the same execution.
47
+ * Supports string and unique symbol keys.
48
+ */
49
+ items;
50
+ /** Backing field for `response` — only writable via `[SET_RESPONSE]()`. */
51
+ _response = undefined;
52
+ /** The handler's return value. Read-only for behaviors. */
53
+ get response() {
54
+ return this._response;
55
+ }
56
+ /**
57
+ * Symbol-keyed setter — only callable by code that imports `SET_RESPONSE`.
58
+ * This keeps `response` effectively readonly for behaviors.
59
+ */
60
+ [SET_RESPONSE](value) {
61
+ this._response = value;
62
+ }
63
+ constructor() {
64
+ this.startedAt = new Date();
65
+ this.items = new Map();
66
+ }
67
+ /**
68
+ * Returns the options for a behavior on this handler: the options from a
69
+ * global `[Behavior, opts]` tuple, shallowly overridden by the options of the
70
+ * call site's `[Behavior, opts]` entry.
71
+ */
72
+ getBehaviorOptions(behaviorType) {
73
+ return this.behaviorOptionsMap?.get(getBehaviorId(behaviorType));
74
+ }
75
+ }
76
+ /**
77
+ * Concrete pipeline context created per request.
78
+ * Pre-computed handler metadata is injected via {@link PipelineHandlerMeta}.
79
+ */
80
+ export class PipelineContext extends BasePipelineContext {
81
+ requestType;
82
+ requestName;
83
+ handlerType;
84
+ handlerName;
85
+ requestKind;
86
+ behaviorOptionsMap;
87
+ _request;
88
+ /** The input of this execution, or the replacement a behavior handed in. */
89
+ get request() {
90
+ return this._request;
91
+ }
92
+ /** Replaces the input the handler receives; see `replaceRequest`. */
93
+ [SET_REQUEST](value) {
94
+ this._request = value;
95
+ }
96
+ constructor(request, meta) {
97
+ super();
98
+ this._request = request;
99
+ this.requestType = (request === null || request === undefined
100
+ ? Object
101
+ : untyped(request).constructor);
102
+ this.requestName = meta.requestName ?? this.requestType.name;
103
+ this.handlerType = meta.handlerType;
104
+ this.handlerName = meta.handlerName;
105
+ this.requestKind = meta.requestKind;
106
+ this.behaviorOptionsMap = meta.behaviorOptions;
107
+ }
108
+ }
109
+ //# sourceMappingURL=pipeline.context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pipeline.context.js","sourceRoot":"","sources":["../src/pipeline.context.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ import { type BehaviorId } from '../helpers/behavior-id.js';
2
+ import type { IPipelineBehavior } from '../interfaces/pipeline.behavior.interface.js';
3
+ import { type PipelineBehaviorDiagnostic } from '../interfaces/pipeline-behavior-contract.interface.js';
4
+ import type { Constructor } from '../types.js';
5
+ /**
6
+ * Validates the ordering rules and option contracts that behavior classes declare
7
+ * through `PIPELINE_BEHAVIOR_CONTRACT`, appending a diagnostic per violation. Framework
8
+ * adapters call it at bootstrap; `createPipeline()` calls it when a function is wrapped.
9
+ *
10
+ * @example
11
+ * ```ts
12
+ * const diagnostics: PipelineBehaviorDiagnostic[] = [];
13
+ * validateBehaviorContracts({ ...plan, handlerType, handlerName, requestKind, resolvedBehaviors, diagnostics });
14
+ * ```
15
+ */
16
+ export declare function validateBehaviorContracts(params: {
17
+ handlerType: Constructor;
18
+ handlerName: string;
19
+ requestKind: 'command' | 'query' | 'event';
20
+ behaviorTypes: Constructor<IPipelineBehavior>[];
21
+ resolvedBehaviors: Map<number, IPipelineBehavior>;
22
+ mergedOptions: Map<BehaviorId, Record<string, unknown>>;
23
+ handlerOptions?: Map<BehaviorId, Record<string, unknown>>;
24
+ globalOptions: Map<BehaviorId, Record<string, unknown>>;
25
+ handlerBehaviorTypes?: Constructor<IPipelineBehavior>[];
26
+ globalBehaviorIds: Set<BehaviorId>;
27
+ diagnostics: PipelineBehaviorDiagnostic[];
28
+ }): void;
29
+ //# sourceMappingURL=pipeline-contracts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pipeline-contracts.d.ts","sourceRoot":"","sources":["../../src/services/pipeline-contracts.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,UAAU,EAAiB,MAAM,2BAA2B,CAAC;AAC3E,OAAO,KAAK,EACV,iBAAiB,EAElB,MAAM,8CAA8C,CAAC;AACtD,OAAO,EAGL,KAAK,0BAA0B,EAEhC,MAAM,uDAAuD,CAAC;AAC/D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C;;;;;;;;;;GAUG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE;IAChD,WAAW,EAAE,WAAW,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,SAAS,GAAG,OAAO,GAAG,OAAO,CAAC;IAC3C,aAAa,EAAE,WAAW,CAAC,iBAAiB,CAAC,EAAE,CAAC;IAChD,iBAAiB,EAAE,GAAG,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;IAClD,aAAa,EAAE,GAAG,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACxD,cAAc,CAAC,EAAE,GAAG,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAC1D,aAAa,EAAE,GAAG,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACxD,oBAAoB,CAAC,EAAE,WAAW,CAAC,iBAAiB,CAAC,EAAE,CAAC;IACxD,iBAAiB,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC;IACnC,WAAW,EAAE,0BAA0B,EAAE,CAAC;CAC3C,GAAG,IAAI,CAyHP"}