/
step-output.ts
97 lines (84 loc) · 2.53 KB
/
step-output.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
import { IResolvable, IResolveContext, Token, Tokenization } from '@aws-cdk/core';
import { Step } from './step';
const STEP_OUTPUT_SYM = Symbol.for('@aws-cdk/pipelines.StepOutput');
/**
* A symbolic reference to a value produced by another step
*
* The engine is responsible for defining how these should be rendered.
*/
export class StepOutput implements IResolvable {
/**
* Return true if the given IResolvable is a StepOutput
*/
public static isStepOutput(resolvable: IResolvable): resolvable is StepOutput {
return !!(resolvable as any)[STEP_OUTPUT_SYM];
}
/**
* Find all StepOutputs referenced in the given structure
*/
public static findAll(structure: any): StepOutput[] {
return findAllStepOutputs(structure);
}
public readonly creationStack: string[] = [];
private resolution: any = undefined;
constructor(public readonly step: Step, public readonly engineSpecificInformation: any) {
Object.defineProperty(this, STEP_OUTPUT_SYM, { value: true });
}
/**
* Define the resolved value for this StepOutput.
*
* Should be called by the engine.
*/
public defineResolution(value: any) {
this.resolution = value;
}
public resolve(_context: IResolveContext) {
if (this.resolution === undefined) {
throw new Error(`Output for step ${this.step} not configured. Either the step is not in the pipeline, or this engine does not support Outputs for this step.`);
}
return this.resolution;
}
public toString(): string {
return Token.asString(this);
}
}
function findAllStepOutputs(structure: any): StepOutput[] {
const ret = new Set<StepOutput>();
recurse(structure);
return Array.from(ret);
function checkToken(x?: IResolvable) {
if (x && StepOutput.isStepOutput(x)) {
ret.add(x);
return true;
}
// Return false if it wasn't a Token in the first place (in which case we recurse)
return x !== undefined;
}
function recurse(x: any): void {
if (!x) { return; }
if (Tokenization.isResolvable(x)) {
checkToken(x);
return;
}
if (Array.isArray(x)) {
if (!checkToken(Tokenization.reverseList(x))) {
x.forEach(recurse);
}
return;
}
if (typeof x === 'number') {
checkToken(Tokenization.reverseNumber(x));
return;
}
if (typeof x === 'string') {
Tokenization.reverseString(x).tokens.forEach(checkToken);
return;
}
if (typeof x === 'object') {
for (const [k, v] of Object.entries(x)) {
recurse(k);
recurse(v);
}
}
}
}