@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,102 @@
1
+ /* Copyright (C) 2026-present Aristotelis — see repository license. */
2
+ import { untyped } from '@cqrs-ddd/untyped';
3
+ import { getBehaviorId } from '../helpers/behavior-id.js';
4
+ import { PIPELINE_BEHAVIOR_CONTRACT, } from '../interfaces/pipeline-behavior-contract.interface.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 function validateBehaviorContracts(params) {
17
+ const { handlerType, handlerName, requestKind, behaviorTypes, resolvedBehaviors, mergedOptions, handlerOptions, globalOptions, handlerBehaviorTypes, globalBehaviorIds, diagnostics, } = params;
18
+ for (let i = 0; i < behaviorTypes.length; i++) {
19
+ const BehaviorClass = behaviorTypes[i];
20
+ const id = getBehaviorId(BehaviorClass);
21
+ const instance = resolvedBehaviors.get(i);
22
+ const contract = (instance &&
23
+ untyped(instance)[PIPELINE_BEHAVIOR_CONTRACT]) ??
24
+ untyped(BehaviorClass)[PIPELINE_BEHAVIOR_CONTRACT];
25
+ if (!contract)
26
+ continue;
27
+ const isHandlerDeclared = (handlerBehaviorTypes ?? []).some((t) => getBehaviorId(t) === id);
28
+ const isGlobalDeclared = globalBehaviorIds.has(id);
29
+ const declarationSource = isHandlerDeclared && isGlobalDeclared
30
+ ? 'both'
31
+ : isHandlerDeclared
32
+ ? 'handler'
33
+ : 'global';
34
+ const rawMerged = mergedOptions.get(id);
35
+ const effectiveOptions = instance && resolvesOptions(instance)
36
+ ? instance.resolveEffectiveOptions(rawMerged)
37
+ : rawMerged;
38
+ const validationCtx = {
39
+ handlerType,
40
+ handlerName: handlerName,
41
+ requestKind,
42
+ declarationSource,
43
+ effectiveOptions,
44
+ handlerOptions: handlerOptions?.get(id),
45
+ globalOptions: globalOptions.get(id),
46
+ effectiveBehaviorTypes: behaviorTypes,
47
+ behaviorInstance: instance,
48
+ };
49
+ // 1. Validate ordering constraints
50
+ const orderRule = typeof contract.order === 'function'
51
+ ? contract.order(validationCtx)
52
+ : contract.order;
53
+ if (orderRule) {
54
+ const edges = [];
55
+ if (orderRule.after) {
56
+ for (const target of orderRule.after) {
57
+ edges.push({ target, direction: 'after' });
58
+ }
59
+ }
60
+ if (orderRule.before) {
61
+ for (const target of orderRule.before) {
62
+ edges.push({ target, direction: 'before' });
63
+ }
64
+ }
65
+ for (const { target, direction } of edges) {
66
+ const targetIdx = behaviorTypes.findIndex((b) => typeof target === 'string'
67
+ ? getBehaviorId(b) === target || b.name === target
68
+ : b === target || getBehaviorId(b) === getBehaviorId(target));
69
+ // Relative position only: an absent target has no position to
70
+ // violate. A behavior that needs a peer to exist checks
71
+ // effectiveBehaviorTypes in its own validate().
72
+ if (targetIdx === -1)
73
+ continue;
74
+ const isViolation = direction === 'after' ? i <= targetIdx : i >= targetIdx;
75
+ if (isViolation) {
76
+ const targetName = behaviorTypes[targetIdx].name;
77
+ diagnostics.push({
78
+ handlerName: handlerName,
79
+ behaviorName: BehaviorClass.name,
80
+ message: direction === 'after'
81
+ ? `${BehaviorClass.name} is positioned before ${targetName} in the pipeline chain, but must execute after it`
82
+ : `${BehaviorClass.name} is positioned after ${targetName} in the pipeline chain, but must execute before it`,
83
+ fix: direction === 'after'
84
+ ? `Reorder the pipeline behaviors so that ${targetName} runs before ${BehaviorClass.name}.`
85
+ : `Reorder the pipeline behaviors so that ${BehaviorClass.name} runs before ${targetName}.`,
86
+ });
87
+ }
88
+ }
89
+ }
90
+ // 2. Validate behavior options and intent
91
+ if (typeof contract.validate === 'function') {
92
+ const result = contract.validate(validationCtx);
93
+ if (Array.isArray(result))
94
+ diagnostics.push(...result);
95
+ }
96
+ }
97
+ }
98
+ function resolvesOptions(instance) {
99
+ return (typeof instance
100
+ .resolveEffectiveOptions === 'function');
101
+ }
102
+ //# sourceMappingURL=pipeline-contracts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pipeline-contracts.js","sourceRoot":"","sources":["../../src/services/pipeline-contracts.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,49 @@
1
+ import { type BehaviorId } from '../helpers/behavior-id.js';
2
+ import type { IPipelineBehavior } from '../interfaces/pipeline.behavior.interface.js';
3
+ import type { GlobalBehaviorsOptions } from '../options/global-behaviors.options.js';
4
+ import type { Constructor } from '../types.js';
5
+ /** The request kinds a pipeline distinguishes; `unknown` matches only `scope: 'all'`. */
6
+ export type RequestKind = 'command' | 'query' | 'event' | 'unknown';
7
+ /** What a handler, or a wrapped function, declares for its pipeline. */
8
+ export interface PipelineDeclaration {
9
+ /** Name used in configuration error messages. */
10
+ handlerName: string;
11
+ requestKind: RequestKind;
12
+ /** Behaviors declared on the handler, deduplicated, in order. */
13
+ handlerBehaviorTypes?: Constructor<IPipelineBehavior>[];
14
+ /** Options of the handler's tuple entries. */
15
+ handlerOptions?: Map<BehaviorId, Record<string, unknown>>;
16
+ /** Global behaviors the handler opts out of. */
17
+ skippedBehaviorTypes?: Constructor<IPipelineBehavior>[];
18
+ globalBehaviors?: GlobalBehaviorsOptions | GlobalBehaviorsOptions[];
19
+ }
20
+ /**
21
+ * Compiles a pipeline declaration into its effective, ordered behaviors and merged
22
+ * options, without resolving instances. Global `before` behaviors come first, then
23
+ * the handler's own, then global `after` ones; a handler entry for a global behavior
24
+ * supplies options at the global position.
25
+ *
26
+ * @throws Error when one behavior is both skipped and declared.
27
+ * @example
28
+ * ```ts
29
+ * const plan = compilePipelinePlan({
30
+ * handlerName: 'getPrice',
31
+ * requestKind: 'query',
32
+ * handlerBehaviorTypes: [CacheBehavior],
33
+ * globalBehaviors: { before: [LoggingBehavior] },
34
+ * });
35
+ * plan.behaviorTypes; // [LoggingBehavior, CacheBehavior]
36
+ * ```
37
+ */
38
+ export declare function compilePipelinePlan(declaration: PipelineDeclaration): {
39
+ behaviorTypes: Constructor<IPipelineBehavior<unknown, unknown>>[];
40
+ mergedOptions: Map<BehaviorId, Record<string, unknown>>;
41
+ hasPipeline: boolean;
42
+ handlerOptions: Map<BehaviorId, Record<string, unknown>> | undefined;
43
+ globalOptions: Map<BehaviorId, Record<string, unknown>>;
44
+ handlerBehaviorTypes: Constructor<IPipelineBehavior<unknown, unknown>>[] | undefined;
45
+ globalBehaviorIds: Set<BehaviorId>;
46
+ };
47
+ /** Normalizes the single-object and array forms of `globalBehaviors`. */
48
+ export declare function toGlobalConfigs(globalBehaviors: GlobalBehaviorsOptions | GlobalBehaviorsOptions[] | undefined): GlobalBehaviorsOptions[];
49
+ //# sourceMappingURL=pipeline-plan.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pipeline-plan.d.ts","sourceRoot":"","sources":["../../src/services/pipeline-plan.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,KAAK,UAAU,EAAiB,MAAM,2BAA2B,CAAC;AAC3E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,8CAA8C,CAAC;AACtF,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,wCAAwC,CAAC;AACrF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C,yFAAyF;AACzF,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,OAAO,GAAG,OAAO,GAAG,SAAS,CAAC;AAEpE,wEAAwE;AACxE,MAAM,WAAW,mBAAmB;IAClC,iDAAiD;IACjD,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,WAAW,CAAC;IACzB,iEAAiE;IACjE,oBAAoB,CAAC,EAAE,WAAW,CAAC,iBAAiB,CAAC,EAAE,CAAC;IACxD,8CAA8C;IAC9C,cAAc,CAAC,EAAE,GAAG,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAC1D,gDAAgD;IAChD,oBAAoB,CAAC,EAAE,WAAW,CAAC,iBAAiB,CAAC,EAAE,CAAC;IACxD,eAAe,CAAC,EAAE,sBAAsB,GAAG,sBAAsB,EAAE,CAAC;CACrE;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,mBAAmB;;;;;;;;EAkFnE;AAED,yEAAyE;AACzE,wBAAgB,eAAe,CAC7B,eAAe,EACX,sBAAsB,GACtB,sBAAsB,EAAE,GACxB,SAAS,GACZ,sBAAsB,EAAE,CAG1B"}
@@ -0,0 +1,111 @@
1
+ /* Copyright (C) 2026-present Aristotelis — see repository license. */
2
+ import { normalizeBehaviorEntries, } from '../helpers/behavior-entries.js';
3
+ import { getBehaviorId } from '../helpers/behavior-id.js';
4
+ /**
5
+ * Compiles a pipeline declaration into its effective, ordered behaviors and merged
6
+ * options, without resolving instances. Global `before` behaviors come first, then
7
+ * the handler's own, then global `after` ones; a handler entry for a global behavior
8
+ * supplies options at the global position.
9
+ *
10
+ * @throws Error when one behavior is both skipped and declared.
11
+ * @example
12
+ * ```ts
13
+ * const plan = compilePipelinePlan({
14
+ * handlerName: 'getPrice',
15
+ * requestKind: 'query',
16
+ * handlerBehaviorTypes: [CacheBehavior],
17
+ * globalBehaviors: { before: [LoggingBehavior] },
18
+ * });
19
+ * plan.behaviorTypes; // [LoggingBehavior, CacheBehavior]
20
+ * ```
21
+ */
22
+ export function compilePipelinePlan(declaration) {
23
+ const { handlerName, requestKind, handlerBehaviorTypes, handlerOptions, skippedBehaviorTypes, globalBehaviors, } = declaration;
24
+ if (skippedBehaviorTypes && skippedBehaviorTypes.length > 0) {
25
+ const handlerBehaviorIds = new Set((handlerBehaviorTypes ?? []).map(getBehaviorId));
26
+ for (const skippedType of skippedBehaviorTypes) {
27
+ const id = getBehaviorId(skippedType);
28
+ if (handlerBehaviorIds.has(id) || handlerOptions?.has(id)) {
29
+ throw new Error(`Handler ${handlerName} has contradictory pipeline configuration: ` +
30
+ `behavior ${skippedType.name} is both skipped and declared. ` +
31
+ `Remove either the skip or the declaration.`);
32
+ }
33
+ }
34
+ }
35
+ const { beforeTypes, afterTypes, globalOptions } = resolveGlobalBehaviors(globalBehaviors, requestKind);
36
+ const skippedBehaviorIds = new Set((skippedBehaviorTypes ?? []).map(getBehaviorId));
37
+ const effectiveBeforeTypes = beforeTypes.filter((type) => !skippedBehaviorIds.has(getBehaviorId(type)));
38
+ const effectiveAfterTypes = afterTypes.filter((type) => !skippedBehaviorIds.has(getBehaviorId(type)));
39
+ // Handler declarations override options for a global behavior of the same
40
+ // class, but must not relocate it. A global security guard configured in
41
+ // `before` must remain outside handler-level cache/idempotency behaviors
42
+ // that can short-circuit without calling next().
43
+ const globalBehaviorIds = new Set([...effectiveBeforeTypes, ...effectiveAfterTypes].map(getBehaviorId));
44
+ const handlerOnlyTypes = (handlerBehaviorTypes ?? []).filter((type) => !globalBehaviorIds.has(getBehaviorId(type)));
45
+ // Effective order: globalBefore → non-global handler behaviors → globalAfter.
46
+ // Matching handler entries supply options at their original global position.
47
+ const behaviorTypes = [
48
+ ...effectiveBeforeTypes,
49
+ ...handlerOnlyTypes,
50
+ ...effectiveAfterTypes,
51
+ ];
52
+ // Handler options shallowly override global options; nested values are replaced.
53
+ const mergedOptions = new Map(globalOptions);
54
+ for (const [id, options] of handlerOptions ?? []) {
55
+ const inherited = mergedOptions.get(id);
56
+ mergedOptions.set(id, inherited ? { ...inherited, ...options } : options);
57
+ }
58
+ for (const skippedId of skippedBehaviorIds) {
59
+ mergedOptions.delete(skippedId);
60
+ }
61
+ return {
62
+ behaviorTypes,
63
+ mergedOptions,
64
+ hasPipeline: behaviorTypes.length > 0,
65
+ handlerOptions,
66
+ globalOptions,
67
+ handlerBehaviorTypes,
68
+ globalBehaviorIds,
69
+ };
70
+ }
71
+ /** Normalizes the single-object and array forms of `globalBehaviors`. */
72
+ export function toGlobalConfigs(globalBehaviors) {
73
+ if (!globalBehaviors)
74
+ return [];
75
+ return Array.isArray(globalBehaviors) ? globalBehaviors : [globalBehaviors];
76
+ }
77
+ /**
78
+ * Resolves global before/after behaviors that match the given handler kind.
79
+ * `globalBehaviors` may be a single `GlobalBehaviorsOptions` object or an array.
80
+ * Each entry is filtered by its `scope` ('all' | 'commands' | 'queries' | 'events').
81
+ * Matching entries are merged — behaviors accumulate across all matching configs.
82
+ *
83
+ * @returns Behavior types to prepend/append plus any inline options from tuple entries.
84
+ */
85
+ function resolveGlobalBehaviors(globalBehaviors, requestKind) {
86
+ const configs = toGlobalConfigs(globalBehaviors);
87
+ const beforeTypes = [];
88
+ const afterTypes = [];
89
+ // One accumulator pair across every matching config and both chain positions,
90
+ // so the first occurrence fixes placement while a later tuple can still
91
+ // supply options without the behavior running more than once.
92
+ const accumulators = {
93
+ seen: new Set(),
94
+ options: new Map(),
95
+ };
96
+ const parseEntries = (entries) => normalizeBehaviorEntries(entries, `globalBehaviors for ${requestKind}`, true, accumulators).types;
97
+ for (const config of configs) {
98
+ const scope = config.scope ?? 'all';
99
+ // Scope filtering — skip entries that don't match the handler kind
100
+ if (scope === 'commands' && requestKind !== 'command')
101
+ continue;
102
+ if (scope === 'queries' && requestKind !== 'query')
103
+ continue;
104
+ if (scope === 'events' && requestKind !== 'event')
105
+ continue;
106
+ beforeTypes.push(...parseEntries(config.before ?? []));
107
+ afterTypes.push(...parseEntries(config.after ?? []));
108
+ }
109
+ return { beforeTypes, afterTypes, globalOptions: accumulators.options };
110
+ }
111
+ //# sourceMappingURL=pipeline-plan.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pipeline-plan.js","sourceRoot":"","sources":["../../src/services/pipeline-plan.ts"],"names":[],"mappings":"AAAA,sEAAsE;AAGtE,OAAO,EAEL,wBAAwB,GACzB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAmB,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAsB3E;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,mBAAmB,CAAC,WAAgC;IAClE,MAAM,EACJ,WAAW,EACX,WAAW,EACX,oBAAoB,EACpB,cAAc,EACd,oBAAoB,EACpB,eAAe,GAChB,GAAG,WAAW,CAAC;IAEhB,IAAI,oBAAoB,IAAI,oBAAoB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC5D,MAAM,kBAAkB,GAAG,IAAI,GAAG,CAChC,CAAC,oBAAoB,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,aAAa,CAAC,CAChD,CAAC;QACF,KAAK,MAAM,WAAW,IAAI,oBAAoB,EAAE,CAAC;YAC/C,MAAM,EAAE,GAAG,aAAa,CAAC,WAAW,CAAC,CAAC;YACtC,IAAI,kBAAkB,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,cAAc,EAAE,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;gBAC1D,MAAM,IAAI,KAAK,CACb,WAAW,WAAW,6CAA6C;oBACjE,YAAY,WAAW,CAAC,IAAI,iCAAiC;oBAC7D,4CAA4C,CAC/C,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,EAAE,WAAW,EAAE,UAAU,EAAE,aAAa,EAAE,GAAG,sBAAsB,CACvE,eAAe,EACf,WAAW,CACZ,CAAC;IAEF,MAAM,kBAAkB,GAAG,IAAI,GAAG,CAChC,CAAC,oBAAoB,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,aAAa,CAAC,CAChD,CAAC;IAEF,MAAM,oBAAoB,GAAG,WAAW,CAAC,MAAM,CAC7C,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,kBAAkB,CAAC,GAAG,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CACvD,CAAC;IACF,MAAM,mBAAmB,GAAG,UAAU,CAAC,MAAM,CAC3C,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,kBAAkB,CAAC,GAAG,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CACvD,CAAC;IAEF,0EAA0E;IAC1E,yEAAyE;IACzE,yEAAyE;IACzE,iDAAiD;IACjD,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAC/B,CAAC,GAAG,oBAAoB,EAAE,GAAG,mBAAmB,CAAC,CAAC,GAAG,CAAC,aAAa,CAAC,CACrE,CAAC;IACF,MAAM,gBAAgB,GAAG,CAAC,oBAAoB,IAAI,EAAE,CAAC,CAAC,MAAM,CAC1D,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,iBAAiB,CAAC,GAAG,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CACtD,CAAC;IAEF,8EAA8E;IAC9E,6EAA6E;IAC7E,MAAM,aAAa,GAAqC;QACtD,GAAG,oBAAoB;QACvB,GAAG,gBAAgB;QACnB,GAAG,mBAAmB;KACvB,CAAC;IAEF,iFAAiF;IACjF,MAAM,aAAa,GAAG,IAAI,GAAG,CAC3B,aAAa,CACd,CAAC;IACF,KAAK,MAAM,CAAC,EAAE,EAAE,OAAO,CAAC,IAAI,cAAc,IAAI,EAAE,EAAE,CAAC;QACjD,MAAM,SAAS,GAAG,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACxC,aAAa,CAAC,GAAG,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,GAAG,SAAS,EAAE,GAAG,OAAO,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;IAC5E,CAAC;IACD,KAAK,MAAM,SAAS,IAAI,kBAAkB,EAAE,CAAC;QAC3C,aAAa,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IAClC,CAAC;IAED,OAAO;QACL,aAAa;QACb,aAAa;QACb,WAAW,EAAE,aAAa,CAAC,MAAM,GAAG,CAAC;QACrC,cAAc;QACd,aAAa;QACb,oBAAoB;QACpB,iBAAiB;KAClB,CAAC;AACJ,CAAC;AAED,yEAAyE;AACzE,MAAM,UAAU,eAAe,CAC7B,eAGa;IAEb,IAAI,CAAC,eAAe;QAAE,OAAO,EAAE,CAAC;IAChC,OAAO,KAAK,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC;AAC9E,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,sBAAsB,CAC7B,eAGa,EACb,WAAwB;IAMxB,MAAM,OAAO,GAAG,eAAe,CAAC,eAAe,CAAC,CAAC;IAEjD,MAAM,WAAW,GAAqC,EAAE,CAAC;IACzD,MAAM,UAAU,GAAqC,EAAE,CAAC;IAExD,8EAA8E;IAC9E,wEAAwE;IACxE,8DAA8D;IAC9D,MAAM,YAAY,GAA8B;QAC9C,IAAI,EAAE,IAAI,GAAG,EAAc;QAC3B,OAAO,EAAE,IAAI,GAAG,EAAuC;KACxD,CAAC;IAEF,MAAM,YAAY,GAAG,CAAC,OAAgC,EAAE,EAAE,CACxD,wBAAwB,CACtB,OAAO,EACP,uBAAuB,WAAW,EAAE,EACpC,IAAI,EACJ,YAAY,CACb,CAAC,KAAK,CAAC;IAEV,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,KAAK,CAAC;QAEpC,mEAAmE;QACnE,IAAI,KAAK,KAAK,UAAU,IAAI,WAAW,KAAK,SAAS;YAAE,SAAS;QAChE,IAAI,KAAK,KAAK,SAAS,IAAI,WAAW,KAAK,OAAO;YAAE,SAAS;QAC7D,IAAI,KAAK,KAAK,QAAQ,IAAI,WAAW,KAAK,OAAO;YAAE,SAAS;QAE5D,WAAW,CAAC,IAAI,CAAC,GAAG,YAAY,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,CAAC;QACvD,UAAU,CAAC,IAAI,CAAC,GAAG,YAAY,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC;IACvD,CAAC;IAED,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,aAAa,EAAE,YAAY,CAAC,OAAO,EAAE,CAAC;AAC1E,CAAC"}
@@ -0,0 +1,26 @@
1
+ import type { ContextSources } from '../interfaces/context-source.interface.js';
2
+ import type { IPipelineBehavior } from '../interfaces/pipeline.behavior.interface.js';
3
+ import type { PipelineHandlerMeta } from '../interfaces/pipeline-handler-meta.interface.js';
4
+ /**
5
+ * Runs one execution: `request` is what behaviors see; `args`, when given, are the
6
+ * arguments the handler receives instead of `request` alone.
7
+ */
8
+ export type PipelineRunner = (self: unknown, request: unknown, args?: readonly unknown[]) => Promise<unknown>;
9
+ /**
10
+ * Builds the runner of one handler: each call creates a pipeline context, takes the
11
+ * tenant and correlation id from `sources` or the enclosing pipeline, composes the
12
+ * behaviors around the handler, and runs them inside those values. Framework adapters
13
+ * use it; `createPipeline()` is the entry point for applications.
14
+ *
15
+ * @param behaviors - Resolved instances, or a resolver called per execution (a
16
+ * framework adapter's request-scoped instances).
17
+ * @param meta - Fixed handler metadata, or a function deriving it from the request and
18
+ * the receiver of the call.
19
+ * @example
20
+ * ```ts
21
+ * const run = createPipelineRunner(handler.execute, meta, [logging], true, sources);
22
+ * await run(handler, command);
23
+ * ```
24
+ */
25
+ export declare function createPipelineRunner(originalMethod: (this: unknown, ...args: any[]) => unknown, meta: PipelineHandlerMeta | ((request: unknown, self: unknown) => PipelineHandlerMeta), behaviors: readonly IPipelineBehavior[] | ((self: unknown, request: unknown) => Promise<IPipelineBehavior[]>), hasPipeline: boolean, sources?: ContextSources): PipelineRunner;
26
+ //# sourceMappingURL=pipeline-runner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pipeline-runner.d.ts","sourceRoot":"","sources":["../../src/services/pipeline-runner.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAEV,cAAc,EACf,MAAM,2CAA2C,CAAC;AACnD,OAAO,KAAK,EACV,iBAAiB,EAElB,MAAM,8CAA8C,CAAC;AACtD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kDAAkD,CAAC;AAG5F;;;GAGG;AACH,MAAM,MAAM,cAAc,GAAG,CAC3B,IAAI,EAAE,OAAO,EACb,OAAO,EAAE,OAAO,EAChB,IAAI,CAAC,EAAE,SAAS,OAAO,EAAE,KACtB,OAAO,CAAC,OAAO,CAAC,CAAC;AAEtB;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,oBAAoB,CAElC,cAAc,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,EAC1D,IAAI,EACA,mBAAmB,GACnB,CAAC,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,KAAK,mBAAmB,CAAC,EAC9D,SAAS,EACL,SAAS,iBAAiB,EAAE,GAC5B,CAAC,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAAC,EACvE,WAAW,EAAE,OAAO,EACpB,OAAO,GAAE,cAAmB,GAC3B,cAAc,CA2DhB"}
@@ -0,0 +1,68 @@
1
+ /* Copyright (C) 2026-present Aristotelis — see repository license. */
2
+ import { uuidv7 } from '@cqrs-ddd/uuidv7';
3
+ import { pipelineStore, SET_CORRELATION_ID, SET_RESPONSE, SET_TENANT_ID, } from '../constants/pipeline-context.constants.js';
4
+ import { PipelineContext } from '../pipeline.context.js';
5
+ /**
6
+ * Builds the runner of one handler: each call creates a pipeline context, takes the
7
+ * tenant and correlation id from `sources` or the enclosing pipeline, composes the
8
+ * behaviors around the handler, and runs them inside those values. Framework adapters
9
+ * use it; `createPipeline()` is the entry point for applications.
10
+ *
11
+ * @param behaviors - Resolved instances, or a resolver called per execution (a
12
+ * framework adapter's request-scoped instances).
13
+ * @param meta - Fixed handler metadata, or a function deriving it from the request and
14
+ * the receiver of the call.
15
+ * @example
16
+ * ```ts
17
+ * const run = createPipelineRunner(handler.execute, meta, [logging], true, sources);
18
+ * await run(handler, command);
19
+ * ```
20
+ */
21
+ export function createPipelineRunner(
22
+ // biome-ignore lint/suspicious/noExplicitAny: the handler's arguments are opaque here
23
+ originalMethod, meta, behaviors, hasPipeline, sources = {}) {
24
+ const invoke = (self, request, args) => args
25
+ ? originalMethod.apply(self, [...args])
26
+ : originalMethod.call(self, request);
27
+ return async (self, request, args) => {
28
+ if (!hasPipeline)
29
+ return invoke(self, request, args);
30
+ const context = new PipelineContext(request, typeof meta === 'function' ? meta(request, self) : meta);
31
+ const localBehaviors = typeof behaviors === 'function'
32
+ ? await behaviors(self, request)
33
+ : behaviors;
34
+ const parent = pipelineStore.getStore();
35
+ const { tenantId: tenant, correlationId: correlation } = sources;
36
+ const tenantId = tenant ? tenant.current() : parent?.tenantId;
37
+ const correlationId = correlation
38
+ ? (correlation.current() ?? correlation.create())
39
+ : (parent?.correlationId ?? uuidv7());
40
+ context[SET_CORRELATION_ID](correlationId);
41
+ if (tenantId !== undefined)
42
+ context[SET_TENANT_ID](tenantId);
43
+ let chain = async () => {
44
+ // A behavior that replaced the request hands the handler the replacement.
45
+ const current = context.request;
46
+ const replaced = current !== request;
47
+ const result = await invoke(self, current, args && replaced
48
+ ? args.length === 1
49
+ ? [current]
50
+ : current
51
+ : args);
52
+ context[SET_RESPONSE](result);
53
+ return result;
54
+ };
55
+ for (let i = localBehaviors.length - 1; i >= 0; i--) {
56
+ const behavior = localBehaviors[i];
57
+ const nextInChain = chain;
58
+ chain = () => behavior.handle(context, nextInChain);
59
+ }
60
+ // Behaviors and the handler run inside this execution's values, so a
61
+ // nested dispatch inherits them and cannot see a different tenant.
62
+ return pipelineStore.run(context, () => within(tenant, context.tenantId, () => within(correlation, context.correlationId, chain)));
63
+ };
64
+ }
65
+ function within(source, value, fn) {
66
+ return source ? source.run(value, fn) : fn();
67
+ }
68
+ //# sourceMappingURL=pipeline-runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pipeline-runner.js","sourceRoot":"","sources":["../../src/services/pipeline-runner.ts"],"names":[],"mappings":"AAAA,sEAAsE;AAEtE,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EACL,aAAa,EACb,kBAAkB,EAClB,YAAY,EACZ,aAAa,GACd,MAAM,4CAA4C,CAAC;AAUpD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAYzD;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,oBAAoB;AAClC,sFAAsF;AACtF,cAA0D,EAC1D,IAE8D,EAC9D,SAEuE,EACvE,WAAoB,EACpB,OAAO,GAAmB,EAAE;IAE5B,MAAM,MAAM,GAAG,CACb,IAAa,EACb,OAAgB,EAChB,IAAyB,EACzB,EAAE,CACF,IAAI;QACF,CAAC,CAAC,cAAc,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC;QACvC,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACzC,OAAO,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE;QACnC,IAAI,CAAC,WAAW;YAAE,OAAO,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;QACrD,MAAM,OAAO,GAAG,IAAI,eAAe,CACjC,OAAO,EACP,OAAO,IAAI,KAAK,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CACxD,CAAC;QACF,MAAM,cAAc,GAClB,OAAO,SAAS,KAAK,UAAU;YAC7B,CAAC,CAAC,MAAM,SAAS,CAAC,IAAI,EAAE,OAAO,CAAC;YAChC,CAAC,CAAC,SAAS,CAAC;QAChB,MAAM,MAAM,GAAG,aAAa,CAAC,QAAQ,EAAE,CAAC;QACxC,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,aAAa,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC;QACjE,MAAM,QAAQ,GAAG,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,MAAM,EAAE,QAAQ,CAAC;QAC9D,MAAM,aAAa,GAAG,WAAW;YAC/B,CAAC,CAAC,CAAC,WAAW,CAAC,OAAO,EAAE,IAAI,WAAW,CAAC,MAAM,EAAE,CAAC;YACjD,CAAC,CAAC,CAAC,MAAM,EAAE,aAAa,IAAI,MAAM,EAAE,CAAC,CAAC;QACxC,OAAO,CAAC,kBAAkB,CAAC,CAAC,aAAa,CAAC,CAAC;QAC3C,IAAI,QAAQ,KAAK,SAAS;YAAE,OAAO,CAAC,aAAa,CAAC,CAAC,QAAQ,CAAC,CAAC;QAE7D,IAAI,KAAK,GAAiB,KAAK,IAAI,EAAE;YACnC,0EAA0E;YAC1E,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;YAChC,MAAM,QAAQ,GAAG,OAAO,KAAK,OAAO,CAAC;YACrC,MAAM,MAAM,GAAG,MAAM,MAAM,CACzB,IAAI,EACJ,OAAO,EACP,IAAI,IAAI,QAAQ;gBACd,CAAC,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC;oBACjB,CAAC,CAAC,CAAC,OAAO,CAAC;oBACX,CAAC,CAAE,OAAqB;gBAC1B,CAAC,CAAC,IAAI,CACT,CAAC;YACF,OAAO,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC;YAC9B,OAAO,MAAM,CAAC;QAChB,CAAC,CAAC;QAEF,KAAK,IAAI,CAAC,GAAG,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YACpD,MAAM,QAAQ,GAAG,cAAc,CAAC,CAAC,CAAC,CAAC;YACnC,MAAM,WAAW,GAAG,KAAK,CAAC;YAC1B,KAAK,GAAG,GAAG,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;QACtD,CAAC;QAED,qEAAqE;QACrE,mEAAmE;QACnE,OAAO,aAAa,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,EAAE,CACrC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,QAAQ,EAAE,GAAG,EAAE,CACpC,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,aAAa,EAAE,KAAK,CAAC,CAClD,CACF,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC;AAED,SAAS,MAAM,CACb,MAAiC,EACjC,KAAyB,EACzB,EAAW;IAEX,OAAO,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;AAC/C,CAAC"}
@@ -0,0 +1,3 @@
1
+ /** A class, as `new` accepts it. Behaviors, requests and handlers are identified by theirs. */
2
+ export type Constructor<T = unknown> = new (...args: any[]) => T;
3
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAEA,+FAA+F;AAE/F,MAAM,MAAM,WAAW,CAAC,CAAC,GAAG,OAAO,IAAI,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC"}
package/dist/types.js ADDED
@@ -0,0 +1,3 @@
1
+ /* Copyright (C) 2026-present Aristotelis — see repository license. */
2
+ export {};
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,sEAAsE"}
package/package.json ADDED
@@ -0,0 +1,63 @@
1
+ {
2
+ "name": "@cqrs-ddd/pipeline",
3
+ "version": "0.5.0",
4
+ "description": "Framework-neutral pipeline engine: wrap functions and methods with behaviors such as logging, caching or idempotency",
5
+ "author": "Aristotelis",
6
+ "license": "SEE LICENSE IN LICENSE",
7
+ "type": "module",
8
+ "engines": {
9
+ "node": ">=22.12.0"
10
+ },
11
+ "repository": {
12
+ "type": "git",
13
+ "url": "git+https://github.com/aristoteliss/ddd-cqrs.git",
14
+ "directory": "packages/pipeline"
15
+ },
16
+ "homepage": "https://aristoteliss.github.io/ddd-cqrs/packages/pipeline/",
17
+ "bugs": {
18
+ "url": "https://github.com/aristoteliss/ddd-cqrs/issues"
19
+ },
20
+ "keywords": [
21
+ "pipeline",
22
+ "behaviors",
23
+ "cqrs",
24
+ "ddd",
25
+ "decorators",
26
+ "middleware"
27
+ ],
28
+ "exports": {
29
+ ".": {
30
+ "types": "./dist/index.d.ts",
31
+ "default": "./dist/index.js"
32
+ },
33
+ "./package.json": "./package.json"
34
+ },
35
+ "main": "dist/index.js",
36
+ "types": "dist/index.d.ts",
37
+ "files": [
38
+ "dist",
39
+ "LICENSE",
40
+ "COMMERCIAL_LICENSE.txt"
41
+ ],
42
+ "publishConfig": {
43
+ "access": "public"
44
+ },
45
+ "dependencies": {
46
+ "@cqrs-ddd/safe-stringify": "^0.5.0",
47
+ "@cqrs-ddd/uuidv7": "^0.5.0",
48
+ "@cqrs-ddd/untyped": "^0.5.0"
49
+ },
50
+ "devDependencies": {
51
+ "@vitest/coverage-v8": "^5.0.3",
52
+ "vitest": "^5.0.3"
53
+ },
54
+ "scripts": {
55
+ "build": "tsc -p tsconfig.build.json",
56
+ "build:watch": "tsc -p tsconfig.build.json --watch",
57
+ "clean": "rm -rf dist tsconfig.tsbuildinfo",
58
+ "rebuild": "pnpm run clean && pnpm run build",
59
+ "lint": "tsc --noEmit",
60
+ "test": "vitest run",
61
+ "test:watch": "vitest"
62
+ }
63
+ }