@rainbow-o23/n1 1.0.58-alpha.3 → 1.0.59

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.cjs CHANGED
@@ -604,6 +604,115 @@ class AbstractPipelineExecution {
604
604
  }
605
605
  }
606
606
 
607
+ class PipelineExecutionContext {
608
+ _authorization;
609
+ _traceId;
610
+ _scopedTraceIds;
611
+ _others = {};
612
+ constructor(authorization, traceId, scopedTraceIds) {
613
+ this._authorization = authorization;
614
+ this._traceId = traceId || nanoid.nanoid(16);
615
+ this._scopedTraceIds = scopedTraceIds || {};
616
+ }
617
+ get authorization() {
618
+ return this._authorization;
619
+ }
620
+ get traceId() {
621
+ return this._traceId;
622
+ }
623
+ get scopedTraceIds() {
624
+ return Object.values(this._scopedTraceIds).reduce((acc, [name, value]) => {
625
+ if (value != null && value.trim().length !== 0) {
626
+ acc[name] = value;
627
+ }
628
+ return acc;
629
+ }, {});
630
+ }
631
+ findScopedTraceId(scopeKey) {
632
+ return this._scopedTraceIds[scopeKey];
633
+ }
634
+ setScopedTraceId(scopeKey, name, value) {
635
+ this._scopedTraceIds[scopeKey] = [name, value];
636
+ }
637
+ findOther(key) {
638
+ return this._others[key];
639
+ }
640
+ setOther(key, value) {
641
+ this._others[key] = value;
642
+ }
643
+ shallowClone(...omittedKeys) {
644
+ const cloned = new PipelineExecutionContext(this.authorization, this.traceId, this._scopedTraceIds);
645
+ Object.keys(this._others).forEach(key => {
646
+ if (omittedKeys.includes(key)) {
647
+ return;
648
+ }
649
+ cloned.setOther(key, this.findOther(key));
650
+ });
651
+ return cloned;
652
+ }
653
+ clone(...omittedKeys) {
654
+ const cloned = new PipelineExecutionContext(this.authorization, this.traceId);
655
+ Object.keys(this._others).forEach(key => {
656
+ if (omittedKeys.includes(key)) {
657
+ return;
658
+ }
659
+ cloned.setOther(key, this.findOther(key));
660
+ });
661
+ return cloned;
662
+ }
663
+ temporaryWith(temporaryContext) {
664
+ return new TemporaryExecutionContext(this, temporaryContext);
665
+ }
666
+ }
667
+ class TemporaryExecutionContext extends PipelineExecutionContext {
668
+ _parent;
669
+ _temporaryContext;
670
+ _temporaryKeys;
671
+ constructor(parent, temporaryContext) {
672
+ super();
673
+ this._parent = parent;
674
+ this._temporaryContext = temporaryContext ?? {};
675
+ this._temporaryKeys = Object.keys(this._temporaryContext);
676
+ }
677
+ get parent() {
678
+ return this._parent;
679
+ }
680
+ get authorization() {
681
+ return this.parent.authorization;
682
+ }
683
+ get traceId() {
684
+ return this.parent.traceId;
685
+ }
686
+ get scopedTraceIds() {
687
+ return this.parent.scopedTraceIds;
688
+ }
689
+ findScopedTraceId(scopeKey) {
690
+ return this.parent.findScopedTraceId(scopeKey);
691
+ }
692
+ setScopedTraceId(scopeKey, name, value) {
693
+ this.parent.setScopedTraceId(scopeKey, name, value);
694
+ }
695
+ get temporaryContext() {
696
+ return this._temporaryContext;
697
+ }
698
+ findOther(key) {
699
+ if (this._temporaryKeys.includes(key)) {
700
+ return this.temporaryContext[key];
701
+ }
702
+ else {
703
+ return super.findOther(key);
704
+ }
705
+ }
706
+ setOther(key, value) {
707
+ if (this._temporaryKeys.includes(key)) {
708
+ this.temporaryContext[key] = value;
709
+ }
710
+ else {
711
+ super.setOther(key, value);
712
+ }
713
+ }
714
+ }
715
+
607
716
  class PipelineStepDateHelper {
608
717
  _dateTimeFormat;
609
718
  constructor(config) {
@@ -705,13 +814,19 @@ class AbstractPipeline extends AbstractPipelineExecution {
705
814
  return await Promise.all(this.getStepBuilders().map(async (builder) => await builder.create(options)));
706
815
  }
707
816
  convertRequestToPipelineData(request) {
708
- return { content: request.payload };
817
+ return {
818
+ content: request.payload,
819
+ $context: request.$context
820
+ };
709
821
  }
710
822
  convertPipelineDataToResponse(result) {
711
- return { payload: result.content };
823
+ return {
824
+ payload: result.content,
825
+ $context: result.$context
826
+ };
712
827
  }
713
828
  createTraceId(request) {
714
- const { traceId } = request;
829
+ const { traceId } = request.$context ?? {};
715
830
  if (traceId == null || traceId.trim().length === 0) {
716
831
  return nanoid.nanoid(16);
717
832
  }
@@ -720,8 +835,8 @@ class AbstractPipeline extends AbstractPipelineExecution {
720
835
  }
721
836
  }
722
837
  async perform(request) {
723
- const traceId = this.createTraceId(request);
724
- const authorization = request.authorization;
838
+ const $context = request.$context;
839
+ const traceId = $context.traceId;
725
840
  const response = await this.measurePerformance(traceId, 'PIPELINE')
726
841
  .execute(async () => {
727
842
  this.traceRequest(traceId, request);
@@ -731,9 +846,7 @@ class AbstractPipeline extends AbstractPipelineExecution {
731
846
  return await this.measurePerformance(traceId, 'STEP', step.constructor.name)
732
847
  .execute(async () => {
733
848
  this.traceStepIn(traceId, step, request);
734
- const response = await step.perform({
735
- ...request, $context: { ...request.$context, authorization, traceId }
736
- });
849
+ const response = await step.perform({ ...request, $context });
737
850
  this.traceStepOut(traceId, step, response);
738
851
  return this.returnOrContinueOrClear(request, response);
739
852
  });
@@ -818,8 +931,10 @@ exports.LoggerUtils = LoggerUtils;
818
931
  exports.PIPELINE_STEP_FILE_SYMBOL = PIPELINE_STEP_FILE_SYMBOL;
819
932
  exports.PIPELINE_STEP_RETURN_NULL = PIPELINE_STEP_RETURN_NULL;
820
933
  exports.PerformanceExecution = PerformanceExecution;
934
+ exports.PipelineExecutionContext = PipelineExecutionContext;
821
935
  exports.PipelineRepository = PipelineRepository;
822
936
  exports.PipelineStepDateHelper = PipelineStepDateHelper;
937
+ exports.TemporaryExecutionContext = TemporaryExecutionContext;
823
938
  exports.UncatchableError = UncatchableError;
824
939
  exports.createConfig = createConfig;
825
940
  exports.createLogger = createLogger;
package/index.js CHANGED
@@ -602,6 +602,115 @@ class AbstractPipelineExecution {
602
602
  }
603
603
  }
604
604
 
605
+ class PipelineExecutionContext {
606
+ _authorization;
607
+ _traceId;
608
+ _scopedTraceIds;
609
+ _others = {};
610
+ constructor(authorization, traceId, scopedTraceIds) {
611
+ this._authorization = authorization;
612
+ this._traceId = traceId || nanoid(16);
613
+ this._scopedTraceIds = scopedTraceIds || {};
614
+ }
615
+ get authorization() {
616
+ return this._authorization;
617
+ }
618
+ get traceId() {
619
+ return this._traceId;
620
+ }
621
+ get scopedTraceIds() {
622
+ return Object.values(this._scopedTraceIds).reduce((acc, [name, value]) => {
623
+ if (value != null && value.trim().length !== 0) {
624
+ acc[name] = value;
625
+ }
626
+ return acc;
627
+ }, {});
628
+ }
629
+ findScopedTraceId(scopeKey) {
630
+ return this._scopedTraceIds[scopeKey];
631
+ }
632
+ setScopedTraceId(scopeKey, name, value) {
633
+ this._scopedTraceIds[scopeKey] = [name, value];
634
+ }
635
+ findOther(key) {
636
+ return this._others[key];
637
+ }
638
+ setOther(key, value) {
639
+ this._others[key] = value;
640
+ }
641
+ shallowClone(...omittedKeys) {
642
+ const cloned = new PipelineExecutionContext(this.authorization, this.traceId, this._scopedTraceIds);
643
+ Object.keys(this._others).forEach(key => {
644
+ if (omittedKeys.includes(key)) {
645
+ return;
646
+ }
647
+ cloned.setOther(key, this.findOther(key));
648
+ });
649
+ return cloned;
650
+ }
651
+ clone(...omittedKeys) {
652
+ const cloned = new PipelineExecutionContext(this.authorization, this.traceId);
653
+ Object.keys(this._others).forEach(key => {
654
+ if (omittedKeys.includes(key)) {
655
+ return;
656
+ }
657
+ cloned.setOther(key, this.findOther(key));
658
+ });
659
+ return cloned;
660
+ }
661
+ temporaryWith(temporaryContext) {
662
+ return new TemporaryExecutionContext(this, temporaryContext);
663
+ }
664
+ }
665
+ class TemporaryExecutionContext extends PipelineExecutionContext {
666
+ _parent;
667
+ _temporaryContext;
668
+ _temporaryKeys;
669
+ constructor(parent, temporaryContext) {
670
+ super();
671
+ this._parent = parent;
672
+ this._temporaryContext = temporaryContext ?? {};
673
+ this._temporaryKeys = Object.keys(this._temporaryContext);
674
+ }
675
+ get parent() {
676
+ return this._parent;
677
+ }
678
+ get authorization() {
679
+ return this.parent.authorization;
680
+ }
681
+ get traceId() {
682
+ return this.parent.traceId;
683
+ }
684
+ get scopedTraceIds() {
685
+ return this.parent.scopedTraceIds;
686
+ }
687
+ findScopedTraceId(scopeKey) {
688
+ return this.parent.findScopedTraceId(scopeKey);
689
+ }
690
+ setScopedTraceId(scopeKey, name, value) {
691
+ this.parent.setScopedTraceId(scopeKey, name, value);
692
+ }
693
+ get temporaryContext() {
694
+ return this._temporaryContext;
695
+ }
696
+ findOther(key) {
697
+ if (this._temporaryKeys.includes(key)) {
698
+ return this.temporaryContext[key];
699
+ }
700
+ else {
701
+ return super.findOther(key);
702
+ }
703
+ }
704
+ setOther(key, value) {
705
+ if (this._temporaryKeys.includes(key)) {
706
+ this.temporaryContext[key] = value;
707
+ }
708
+ else {
709
+ super.setOther(key, value);
710
+ }
711
+ }
712
+ }
713
+
605
714
  class PipelineStepDateHelper {
606
715
  _dateTimeFormat;
607
716
  constructor(config) {
@@ -703,13 +812,19 @@ class AbstractPipeline extends AbstractPipelineExecution {
703
812
  return await Promise.all(this.getStepBuilders().map(async (builder) => await builder.create(options)));
704
813
  }
705
814
  convertRequestToPipelineData(request) {
706
- return { content: request.payload };
815
+ return {
816
+ content: request.payload,
817
+ $context: request.$context
818
+ };
707
819
  }
708
820
  convertPipelineDataToResponse(result) {
709
- return { payload: result.content };
821
+ return {
822
+ payload: result.content,
823
+ $context: result.$context
824
+ };
710
825
  }
711
826
  createTraceId(request) {
712
- const { traceId } = request;
827
+ const { traceId } = request.$context ?? {};
713
828
  if (traceId == null || traceId.trim().length === 0) {
714
829
  return nanoid(16);
715
830
  }
@@ -718,8 +833,8 @@ class AbstractPipeline extends AbstractPipelineExecution {
718
833
  }
719
834
  }
720
835
  async perform(request) {
721
- const traceId = this.createTraceId(request);
722
- const authorization = request.authorization;
836
+ const $context = request.$context;
837
+ const traceId = $context.traceId;
723
838
  const response = await this.measurePerformance(traceId, 'PIPELINE')
724
839
  .execute(async () => {
725
840
  this.traceRequest(traceId, request);
@@ -729,9 +844,7 @@ class AbstractPipeline extends AbstractPipelineExecution {
729
844
  return await this.measurePerformance(traceId, 'STEP', step.constructor.name)
730
845
  .execute(async () => {
731
846
  this.traceStepIn(traceId, step, request);
732
- const response = await step.perform({
733
- ...request, $context: { ...request.$context, authorization, traceId }
734
- });
847
+ const response = await step.perform({ ...request, $context });
735
848
  this.traceStepOut(traceId, step, response);
736
849
  return this.returnOrContinueOrClear(request, response);
737
850
  });
@@ -795,4 +908,4 @@ class PipelineRepository {
795
908
  }
796
909
  }
797
910
 
798
- export { AbstractPipeline, AbstractPipelineExecution, AbstractPipelineStep, AbstractStaticPipeline, CatchableError, Config, ConsoleLogger, DefaultPipelineBuilder, DefaultPipelineStepBuilder, ERR_DUPLICATED_ERROR_CODE, ERR_PIPELINE_NOT_FOUND, ERR_TRIM_NON_STRING, ERR_UNKNOWN, EnhancedLogger, ErrorCodes, ExposedUncatchableError, LoggerPerformanceSaver, LoggerUtils, PIPELINE_STEP_FILE_SYMBOL, PIPELINE_STEP_RETURN_NULL, PerformanceExecution, PipelineRepository, PipelineStepDateHelper, StepHelpersUtils, UncatchableError, createConfig, createLogger, createStepHelpers, registerToStepHelpers, saveLoggerPerformance };
911
+ export { AbstractPipeline, AbstractPipelineExecution, AbstractPipelineStep, AbstractStaticPipeline, CatchableError, Config, ConsoleLogger, DefaultPipelineBuilder, DefaultPipelineStepBuilder, ERR_DUPLICATED_ERROR_CODE, ERR_PIPELINE_NOT_FOUND, ERR_TRIM_NON_STRING, ERR_UNKNOWN, EnhancedLogger, ErrorCodes, ExposedUncatchableError, LoggerPerformanceSaver, LoggerUtils, PIPELINE_STEP_FILE_SYMBOL, PIPELINE_STEP_RETURN_NULL, PerformanceExecution, PipelineExecutionContext, PipelineRepository, PipelineStepDateHelper, StepHelpersUtils, TemporaryExecutionContext, UncatchableError, createConfig, createLogger, createStepHelpers, registerToStepHelpers, saveLoggerPerformance };
@@ -1,4 +1,5 @@
1
1
  export * from './pipeline-execution';
2
+ export * from './pipeline-execution-context';
2
3
  export * from './pipeline-step';
3
4
  export * from './pipeline';
4
5
  export * from './step-helpers-utils';
@@ -0,0 +1,42 @@
1
+ export interface PipelineRequestAuthorizationRole {
2
+ code?: string;
3
+ [key: string]: any | undefined;
4
+ }
5
+ export interface PipelineRequestAuthorization<A = any> {
6
+ readonly authorized: boolean;
7
+ readonly authentication?: A;
8
+ readonly roles: Array<PipelineRequestAuthorizationRole>;
9
+ readonly headers?: Record<string, string>;
10
+ }
11
+ export declare class PipelineExecutionContext {
12
+ private readonly _authorization?;
13
+ private readonly _traceId;
14
+ private readonly _scopedTraceIds;
15
+ private readonly _others;
16
+ constructor(authorization?: PipelineRequestAuthorization, traceId?: string, scopedTraceIds?: Record<string, [string, string]>);
17
+ get authorization(): PipelineRequestAuthorization;
18
+ get traceId(): string;
19
+ get scopedTraceIds(): Record<string, string>;
20
+ findScopedTraceId(scopeKey: string): [string, string] | undefined;
21
+ setScopedTraceId(scopeKey: string, name: string, value: string): void;
22
+ findOther(key: string): any | undefined;
23
+ setOther(key: string, value: any): void;
24
+ shallowClone(...omittedKeys: Array<string>): PipelineExecutionContext;
25
+ clone(...omittedKeys: Array<string>): PipelineExecutionContext;
26
+ temporaryWith(temporaryContext: Record<string, any>): PipelineExecutionContext;
27
+ }
28
+ export declare class TemporaryExecutionContext extends PipelineExecutionContext {
29
+ private readonly _parent;
30
+ private readonly _temporaryContext;
31
+ private readonly _temporaryKeys;
32
+ constructor(parent: PipelineExecutionContext, temporaryContext: Record<string, any>);
33
+ protected get parent(): PipelineExecutionContext;
34
+ get authorization(): PipelineRequestAuthorization;
35
+ get traceId(): string;
36
+ get scopedTraceIds(): Record<string, string>;
37
+ findScopedTraceId(scopeKey: string): [string, string] | undefined;
38
+ setScopedTraceId(scopeKey: string, name: string, value: string): void;
39
+ get temporaryContext(): Record<string, any>;
40
+ findOther(key: string): any;
41
+ setOther(key: string, value: any): void;
42
+ }
@@ -1,15 +1,11 @@
1
1
  import { Config, Logger } from '../utils';
2
- import { PipelineRequestAuthorization } from './pipeline';
3
2
  import { AbstractPipelineExecution, PipelineExecutionOptions } from './pipeline-execution';
3
+ import { PipelineExecutionContext } from './pipeline-execution-context';
4
4
  import { PipelineStepHelpers } from './step-helpers';
5
5
  export type PipelineStepCode = string;
6
6
  export type PipelineStepPayload = any;
7
- export interface PipelineStepContext {
8
- authorization?: PipelineRequestAuthorization;
9
- traceId?: string;
10
- }
11
- export interface PipelineStepData<C = PipelineStepPayload, CTX = PipelineStepContext> {
12
- $context?: CTX;
7
+ export interface PipelineStepData<C = PipelineStepPayload, CTX = PipelineExecutionContext> {
8
+ $context: CTX;
13
9
  content: C;
14
10
  }
15
11
  export interface PipelineStep<In = any, Out = any> {
@@ -1,25 +1,16 @@
1
1
  import { Config, Logger } from '../utils';
2
2
  import { AbstractPipelineExecution, PipelineExecutionOptions } from './pipeline-execution';
3
+ import { PipelineExecutionContext } from './pipeline-execution-context';
3
4
  import { PipelineStep, PipelineStepBuilder, PipelineStepData, PipelineStepOptions, PipelineStepType } from './pipeline-step';
4
5
  export type PipelineRequestPayload = any;
5
- export interface PipelineRequestAuthorizationRole {
6
- code?: string;
7
- [key: string]: any | undefined;
8
- }
9
- export interface PipelineRequestAuthorization<A = any> {
10
- readonly authorized: boolean;
11
- readonly authentication?: A;
12
- readonly roles: Array<PipelineRequestAuthorizationRole>;
13
- readonly headers?: Record<string, string>;
14
- }
15
6
  export interface PipelineRequest<C = PipelineRequestPayload> {
16
7
  payload: C;
17
- authorization?: PipelineRequestAuthorization;
18
- traceId?: string;
8
+ $context: PipelineExecutionContext;
19
9
  }
20
10
  export type PipelineResponsePayload = any;
21
11
  export interface PipelineResponse<C = PipelineResponsePayload> {
22
12
  payload: C;
13
+ $context: PipelineExecutionContext;
23
14
  }
24
15
  export type PipelineCode = string;
25
16
  export interface Pipeline<In = any, Out = any> {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rainbow-o23/n1",
3
- "version": "1.0.58-alpha.3",
3
+ "version": "1.0.59",
4
4
  "description": "o23 interfaces",
5
5
  "main": "index.cjs",
6
6
  "module": "index.js",
@@ -1,4 +1,5 @@
1
1
  export * from './pipeline-execution';
2
+ export * from './pipeline-execution-context';
2
3
  export * from './pipeline-step';
3
4
  export * from './pipeline';
4
5
 
@@ -0,0 +1,166 @@
1
+ import {nanoid} from 'nanoid';
2
+
3
+ export interface PipelineRequestAuthorizationRole {
4
+ code?: string;
5
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
6
+ [key: string]: any | undefined;
7
+ }
8
+
9
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
10
+ export interface PipelineRequestAuthorization<A = any> {
11
+ readonly authorized: boolean;
12
+ /** undefined when authorized is false */
13
+ readonly authentication?: A;
14
+ /** empty array when authorized is false */
15
+ readonly roles: Array<PipelineRequestAuthorizationRole>;
16
+ /** headers should be added to response */
17
+ readonly headers?: Record<string, string>;
18
+ }
19
+
20
+ export class PipelineExecutionContext {
21
+ private readonly _authorization?: PipelineRequestAuthorization;
22
+ private readonly _traceId: string;
23
+ /*
24
+ * typically, when calling a remote service, and which is from some microservices group,
25
+ * there might be some trace ids brought in.
26
+ * therefore, these trace ids should be collected and put into pipeline context.
27
+ * the key is tracing group, and value is trace id of this tracing group.
28
+ * Record<scope key, [name, value]>
29
+ */
30
+ private readonly _scopedTraceIds: Record<string, [string, string]>;
31
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
32
+ private readonly _others: Record<string, any> = {};
33
+
34
+ constructor(authorization?: PipelineRequestAuthorization, traceId?: string, scopedTraceIds?: Record<string, [string, string]>) {
35
+ this._authorization = authorization;
36
+ this._traceId = traceId || nanoid(16);
37
+ this._scopedTraceIds = scopedTraceIds || {};
38
+ }
39
+
40
+ get authorization(): PipelineRequestAuthorization {
41
+ return this._authorization;
42
+ }
43
+
44
+ get traceId(): string {
45
+ return this._traceId;
46
+ }
47
+
48
+ get scopedTraceIds(): Record<string, string> {
49
+ return Object.values(this._scopedTraceIds).reduce((acc, [name, value]) => {
50
+ if (value != null && value.trim().length !== 0) {
51
+ acc[name] = value;
52
+ }
53
+ return acc;
54
+ }, {});
55
+ }
56
+
57
+ findScopedTraceId(scopeKey: string): [string, string] | undefined {
58
+ return this._scopedTraceIds[scopeKey];
59
+ }
60
+
61
+ setScopedTraceId(scopeKey: string, name: string, value: string): void {
62
+ this._scopedTraceIds[scopeKey] = [name, value];
63
+ }
64
+
65
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
66
+ findOther(key: string): any | undefined {
67
+ return this._others[key];
68
+ }
69
+
70
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
71
+ setOther(key: string, value: any): void {
72
+ this._others[key] = value;
73
+ }
74
+
75
+ shallowClone(...omittedKeys: Array<string>): PipelineExecutionContext {
76
+ const cloned = new PipelineExecutionContext(this.authorization, this.traceId, this._scopedTraceIds);
77
+ Object.keys(this._others).forEach(key => {
78
+ if (omittedKeys.includes(key)) {
79
+ return;
80
+ }
81
+ cloned.setOther(key, this.findOther(key));
82
+ });
83
+ return cloned;
84
+ }
85
+
86
+ clone(...omittedKeys: Array<string>): PipelineExecutionContext {
87
+ const cloned = new PipelineExecutionContext(this.authorization, this.traceId);
88
+ Object.keys(this._others).forEach(key => {
89
+ if (omittedKeys.includes(key)) {
90
+ return;
91
+ }
92
+ cloned.setOther(key, this.findOther(key));
93
+ });
94
+ return cloned;
95
+ }
96
+
97
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
98
+ temporaryWith(temporaryContext: Record<string, any>): PipelineExecutionContext {
99
+ return new TemporaryExecutionContext(this, temporaryContext);
100
+ }
101
+ }
102
+
103
+ /**
104
+ * everything same as parent context, except things in given temporary context
105
+ */
106
+ export class TemporaryExecutionContext extends PipelineExecutionContext {
107
+ private readonly _parent: PipelineExecutionContext;
108
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
109
+ private readonly _temporaryContext: Record<string, any>;
110
+ private readonly _temporaryKeys: Array<string>;
111
+
112
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
113
+ constructor(parent: PipelineExecutionContext, temporaryContext: Record<string, any>) {
114
+ super();
115
+ this._parent = parent;
116
+ this._temporaryContext = temporaryContext ?? {};
117
+ this._temporaryKeys = Object.keys(this._temporaryContext);
118
+ }
119
+
120
+ protected get parent(): PipelineExecutionContext {
121
+ return this._parent;
122
+ }
123
+
124
+ get authorization(): PipelineRequestAuthorization {
125
+ return this.parent.authorization;
126
+ }
127
+
128
+ get traceId(): string {
129
+ return this.parent.traceId;
130
+ }
131
+
132
+ get scopedTraceIds(): Record<string, string> {
133
+ return this.parent.scopedTraceIds;
134
+ }
135
+
136
+ findScopedTraceId(scopeKey: string): [string, string] | undefined {
137
+ return this.parent.findScopedTraceId(scopeKey);
138
+ }
139
+
140
+ setScopedTraceId(scopeKey: string, name: string, value: string) {
141
+ this.parent.setScopedTraceId(scopeKey, name, value);
142
+ }
143
+
144
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
145
+ get temporaryContext(): Record<string, any> {
146
+ return this._temporaryContext;
147
+ }
148
+
149
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
150
+ findOther(key: string): any {
151
+ if (this._temporaryKeys.includes(key)) {
152
+ return this.temporaryContext[key];
153
+ } else {
154
+ return super.findOther(key);
155
+ }
156
+ }
157
+
158
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
159
+ setOther(key: string, value: any) {
160
+ if (this._temporaryKeys.includes(key)) {
161
+ this.temporaryContext[key] = value;
162
+ } else {
163
+ super.setOther(key, value);
164
+ }
165
+ }
166
+ }
@@ -1,6 +1,6 @@
1
1
  import {Config, Logger} from '../utils';
2
- import {PipelineRequestAuthorization} from './pipeline';
3
2
  import {AbstractPipelineExecution, PipelineExecutionOptions} from './pipeline-execution';
3
+ import {PipelineExecutionContext} from './pipeline-execution-context';
4
4
  import {createStepHelpers, PipelineStepHelpers} from './step-helpers';
5
5
 
6
6
  export type PipelineStepCode = string;
@@ -8,14 +8,9 @@ export type PipelineStepCode = string;
8
8
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
9
9
  export type PipelineStepPayload = any;
10
10
 
11
- export interface PipelineStepContext {
12
- authorization?: PipelineRequestAuthorization;
13
- traceId?: string;
14
- }
15
-
16
- export interface PipelineStepData<C = PipelineStepPayload, CTX = PipelineStepContext> {
11
+ export interface PipelineStepData<C = PipelineStepPayload, CTX = PipelineExecutionContext> {
17
12
  /** this is runtime context */
18
- $context?: CTX;
13
+ $context: CTX;
19
14
  content: C;
20
15
  }
21
16
 
@@ -1,6 +1,7 @@
1
1
  import {nanoid} from 'nanoid';
2
2
  import {Config, Logger} from '../utils';
3
3
  import {AbstractPipelineExecution, PipelineExecutionOptions} from './pipeline-execution';
4
+ import {PipelineExecutionContext} from './pipeline-execution-context';
4
5
  import {
5
6
  DefaultPipelineStepBuilder,
6
7
  PipelineStep,
@@ -13,27 +14,9 @@ import {
13
14
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
14
15
  export type PipelineRequestPayload = any;
15
16
 
16
- export interface PipelineRequestAuthorizationRole {
17
- code?: string;
18
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
19
- [key: string]: any | undefined;
20
- }
21
-
22
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
23
- export interface PipelineRequestAuthorization<A = any> {
24
- readonly authorized: boolean;
25
- /** undefined when authorized is false */
26
- readonly authentication?: A;
27
- /** empty array when authorized is false */
28
- readonly roles: Array<PipelineRequestAuthorizationRole>;
29
- /** headers should be added to response */
30
- readonly headers?: Record<string, string>;
31
- }
32
-
33
17
  export interface PipelineRequest<C = PipelineRequestPayload> {
34
18
  payload: C;
35
- authorization?: PipelineRequestAuthorization;
36
- traceId?: string;
19
+ $context: PipelineExecutionContext;
37
20
  }
38
21
 
39
22
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -41,6 +24,7 @@ export type PipelineResponsePayload = any;
41
24
 
42
25
  export interface PipelineResponse<C = PipelineResponsePayload> {
43
26
  payload: C;
27
+ $context: PipelineExecutionContext;
44
28
  }
45
29
 
46
30
  export type PipelineCode = string;
@@ -95,15 +79,21 @@ export abstract class AbstractPipeline<In = any, Out = any> extends AbstractPipe
95
79
  }
96
80
 
97
81
  public convertRequestToPipelineData<I, FirstStepIn>(request: PipelineRequest<I>): PipelineStepData<FirstStepIn> {
98
- return {content: request.payload as unknown as FirstStepIn};
82
+ return {
83
+ content: request.payload as unknown as FirstStepIn,
84
+ $context: request.$context
85
+ };
99
86
  }
100
87
 
101
88
  public convertPipelineDataToResponse<LastStepOut, O>(result: PipelineStepData<LastStepOut>): PipelineResponse<O> {
102
- return {payload: result.content as unknown as O};
89
+ return {
90
+ payload: result.content as unknown as O,
91
+ $context: result.$context
92
+ };
103
93
  }
104
94
 
105
95
  protected createTraceId(request: PipelineRequest<In>): string {
106
- const {traceId} = request;
96
+ const {traceId} = request.$context ?? {};
107
97
  if (traceId == null || traceId.trim().length === 0) {
108
98
  return nanoid(16);
109
99
  } else {
@@ -118,8 +108,8 @@ export abstract class AbstractPipeline<In = any, Out = any> extends AbstractPipe
118
108
  * - use last step's result as response.
119
109
  */
120
110
  public async perform(request: PipelineRequest<In>): Promise<PipelineResponse<Out>> {
121
- const traceId = this.createTraceId(request);
122
- const authorization = request.authorization;
111
+ const $context = request.$context;
112
+ const traceId = $context.traceId;
123
113
  const response = await this.measurePerformance(traceId, 'PIPELINE')
124
114
  .execute(async () => {
125
115
  this.traceRequest(traceId, request);
@@ -129,9 +119,7 @@ export abstract class AbstractPipeline<In = any, Out = any> extends AbstractPipe
129
119
  return await this.measurePerformance(traceId, 'STEP', step.constructor.name)
130
120
  .execute(async () => {
131
121
  this.traceStepIn(traceId, step, request);
132
- const response = await step.perform({
133
- ...request, $context: {...request.$context, authorization, traceId}
134
- });
122
+ const response = await step.perform({...request, $context});
135
123
  this.traceStepOut(traceId, step, response);
136
124
  // if no response returned, keep using request for next
137
125
  return this.returnOrContinueOrClear(request, response);