@aws-mdaa/dataops-job-l3-construct 1.5.0 → 1.6.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 (90) hide show
  1. package/.jsii +38 -28
  2. package/README.md +5 -0
  3. package/lib/dataops-job-l3-construct.d.ts +8 -1
  4. package/lib/dataops-job-l3-construct.js +40 -13
  5. package/node_modules/@aws-mdaa/config/README.md +3 -0
  6. package/node_modules/@aws-mdaa/config/lib/blueprint-value-transformer.d.ts +20 -0
  7. package/node_modules/@aws-mdaa/config/lib/blueprint-value-transformer.js +70 -0
  8. package/node_modules/@aws-mdaa/config/lib/blueprint-value-transformer.ts +88 -0
  9. package/node_modules/@aws-mdaa/config/lib/config.d.ts +87 -0
  10. package/node_modules/@aws-mdaa/config/lib/config.js +7 -0
  11. package/node_modules/@aws-mdaa/config/lib/config.ts +92 -0
  12. package/node_modules/@aws-mdaa/config/lib/index.d.ts +11 -0
  13. package/node_modules/@aws-mdaa/config/lib/index.js +28 -0
  14. package/node_modules/@aws-mdaa/config/lib/index.ts +12 -0
  15. package/node_modules/@aws-mdaa/config/lib/param-transformer.d.ts +49 -0
  16. package/node_modules/@aws-mdaa/config/lib/param-transformer.js +160 -0
  17. package/node_modules/@aws-mdaa/config/lib/param-transformer.ts +159 -0
  18. package/node_modules/@aws-mdaa/config/lib/path-value-transformer.d.ts +10 -0
  19. package/node_modules/@aws-mdaa/config/lib/path-value-transformer.js +30 -0
  20. package/node_modules/@aws-mdaa/config/lib/path-value-transformer.ts +27 -0
  21. package/node_modules/@aws-mdaa/config/lib/ref-value-transformer.d.ts +44 -0
  22. package/node_modules/@aws-mdaa/config/lib/ref-value-transformer.js +243 -0
  23. package/node_modules/@aws-mdaa/config/lib/ref-value-transformer.ts +302 -0
  24. package/node_modules/@aws-mdaa/config/lib/ssm-ref-transformer.d.ts +8 -0
  25. package/node_modules/@aws-mdaa/config/lib/ssm-ref-transformer.js +22 -0
  26. package/node_modules/@aws-mdaa/config/lib/ssm-ref-transformer.ts +21 -0
  27. package/node_modules/@aws-mdaa/config/lib/transformer.d.ts +35 -0
  28. package/node_modules/@aws-mdaa/config/lib/transformer.js +66 -0
  29. package/node_modules/@aws-mdaa/config/lib/transformer.ts +74 -0
  30. package/node_modules/@aws-mdaa/config/package.json +42 -0
  31. package/node_modules/@aws-mdaa/config/test/blueprint-value-transformer.test.js +224 -0
  32. package/node_modules/@aws-mdaa/config/test/blueprint-value-transformer.test.ts +259 -0
  33. package/node_modules/@aws-mdaa/config/test/config-nt.test.d.ts +5 -0
  34. package/node_modules/@aws-mdaa/config/test/config-nt.test.js +129 -0
  35. package/node_modules/@aws-mdaa/config/test/config-nt.test.ts +163 -0
  36. package/node_modules/@aws-mdaa/config/test/config.test.d.ts +5 -0
  37. package/node_modules/@aws-mdaa/config/test/config.test.js +409 -0
  38. package/node_modules/@aws-mdaa/config/test/config.test.ts +517 -0
  39. package/node_modules/@aws-mdaa/config/test/param-transformer.test.d.ts +5 -0
  40. package/node_modules/@aws-mdaa/config/test/param-transformer.test.js +216 -0
  41. package/node_modules/@aws-mdaa/config/test/param-transformer.test.ts +234 -0
  42. package/node_modules/@aws-mdaa/config/test/path-value-transformer.test.d.ts +5 -0
  43. package/node_modules/@aws-mdaa/config/test/path-value-transformer.test.js +59 -0
  44. package/node_modules/@aws-mdaa/config/test/path-value-transformer.test.ts +68 -0
  45. package/node_modules/@aws-mdaa/config/test/ref-value-transformer.test.d.ts +5 -0
  46. package/node_modules/@aws-mdaa/config/test/ref-value-transformer.test.js +254 -0
  47. package/node_modules/@aws-mdaa/config/test/ref-value-transformer.test.ts +304 -0
  48. package/node_modules/@aws-mdaa/config/test/ssm-ref-transformer.test.d.ts +5 -0
  49. package/node_modules/@aws-mdaa/config/test/ssm-ref-transformer.test.js +66 -0
  50. package/node_modules/@aws-mdaa/config/test/ssm-ref-transformer.test.ts +79 -0
  51. package/node_modules/@aws-mdaa/config/tsconfig.tsbuildinfo +1 -0
  52. package/node_modules/lodash/README.md +2 -2
  53. package/node_modules/lodash/_baseOrderBy.js +1 -1
  54. package/node_modules/lodash/_baseUnset.js +7 -20
  55. package/node_modules/lodash/_setCacheHas.js +1 -1
  56. package/node_modules/lodash/compact.js +1 -1
  57. package/node_modules/lodash/core.js +3 -3
  58. package/node_modules/lodash/core.min.js +26 -25
  59. package/node_modules/lodash/fromPairs.js +3 -1
  60. package/node_modules/lodash/lodash.js +38 -27
  61. package/node_modules/lodash/lodash.min.js +125 -129
  62. package/node_modules/lodash/package.json +4 -2
  63. package/node_modules/lodash/random.js +9 -0
  64. package/node_modules/lodash/template.js +16 -4
  65. package/node_modules/lodash/templateSettings.js +4 -0
  66. package/package.json +27 -32
  67. package/node_modules/@aws-mdaa/s3-bucketpolicy-helper/README.md +0 -185
  68. package/node_modules/@aws-mdaa/s3-bucketpolicy-helper/lib/index.d.ts +0 -57
  69. package/node_modules/@aws-mdaa/s3-bucketpolicy-helper/lib/index.js +0 -198
  70. package/node_modules/@aws-mdaa/s3-bucketpolicy-helper/lib/index.ts +0 -241
  71. package/node_modules/@aws-mdaa/s3-bucketpolicy-helper/package.json +0 -44
  72. package/node_modules/@aws-mdaa/s3-bucketpolicy-helper/test/bucketpolicy-helper.test.js +0 -200
  73. package/node_modules/@aws-mdaa/s3-bucketpolicy-helper/test/bucketpolicy-helper.test.ts +0 -215
  74. package/node_modules/@aws-mdaa/s3-bucketpolicy-helper/tsconfig.tsbuildinfo +0 -1
  75. package/node_modules/@aws-mdaa/s3-inventory-helper/.npmignore +0 -34
  76. package/node_modules/@aws-mdaa/s3-inventory-helper/README.md +0 -3
  77. package/node_modules/@aws-mdaa/s3-inventory-helper/jest.config.js +0 -5
  78. package/node_modules/@aws-mdaa/s3-inventory-helper/lib/index.d.ts +0 -48
  79. package/node_modules/@aws-mdaa/s3-inventory-helper/lib/index.js +0 -213
  80. package/node_modules/@aws-mdaa/s3-inventory-helper/lib/index.ts +0 -241
  81. package/node_modules/@aws-mdaa/s3-inventory-helper/package.json +0 -44
  82. package/node_modules/@aws-mdaa/s3-inventory-helper/test/TODO +0 -0
  83. package/node_modules/@aws-mdaa/s3-inventory-helper/tsconfig.json +0 -40
  84. package/node_modules/@aws-mdaa/s3-inventory-helper/tsconfig.tsbuildinfo +0 -1
  85. package/node_modules/@aws-mdaa/s3-inventory-helper/typedoc.json +0 -7
  86. /package/node_modules/@aws-mdaa/{s3-bucketpolicy-helper → config}/.npmignore +0 -0
  87. /package/node_modules/@aws-mdaa/{s3-bucketpolicy-helper → config}/jest.config.js +0 -0
  88. /package/node_modules/@aws-mdaa/{s3-bucketpolicy-helper/test/bucketpolicy-helper.test.d.ts → config/test/blueprint-value-transformer.test.d.ts} +0 -0
  89. /package/node_modules/@aws-mdaa/{s3-bucketpolicy-helper → config}/tsconfig.json +0 -0
  90. /package/node_modules/@aws-mdaa/{s3-bucketpolicy-helper → config}/typedoc.json +0 -0
@@ -0,0 +1,159 @@
1
+ /*!
2
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+
6
+ import { CfnParameter, CfnParameterProps, Stack } from 'aws-cdk-lib';
7
+ import { MdaaConfigRefValueTransformerProps, MdaaConfigRefValueTransformer } from './ref-value-transformer';
8
+
9
+ export interface MdaaConfigParamRefValueTransformerProps extends MdaaConfigRefValueTransformerProps {
10
+ readonly paramProps: { [name: string]: CfnParameterProps };
11
+ }
12
+ export class MdaaConfigParamRefValueTransformer extends MdaaConfigRefValueTransformer {
13
+ private readonly paramProps: { [name: string]: CfnParameterProps };
14
+ constructor(props: MdaaConfigParamRefValueTransformerProps) {
15
+ super(props);
16
+ this.paramProps = props.paramProps;
17
+ }
18
+ protected override parseRef(value: string, refMatch: string[]): string | number {
19
+ /**
20
+ * Handle base case where we resolve and return a single naked parameter value,
21
+ * Important as we need to avoid building a string if we have a standalone numerical value
22
+ */
23
+ const standaloneParam = this.resolveStandaloneParam(value, refMatch);
24
+ if (standaloneParam) {
25
+ return standaloneParam;
26
+ }
27
+ // In all other cases, return a recursively substituted string
28
+ let toReturn: string = value;
29
+ refMatch.forEach(ref => {
30
+ let resolvedValue: string | undefined;
31
+ const refInner = this.transformValue(ref).toString();
32
+ if (refInner.startsWith('param:') && this.props.scope instanceof Stack) {
33
+ resolvedValue = this.createParam(refInner).toString();
34
+ }
35
+ toReturn = resolvedValue ? toReturn.replace(`{{${ref}}}`, resolvedValue) : toReturn;
36
+ });
37
+ return toReturn;
38
+ }
39
+ /**
40
+ * Resolve standalone parameters with no other content in the value.
41
+ * "Standalone" means it is not embedded in a string value.
42
+ * Important as this can be a case where a number should be returned instead of a string.
43
+ * @param value
44
+ * @param refMatch
45
+ * @returns
46
+ */
47
+ private resolveStandaloneParam(value: string, refMatch: string[]): string | number | undefined {
48
+ if (refMatch.length === 1) {
49
+ const strippedValue = value.replace(`{{${refMatch[0]}}}`, '').trim();
50
+ if (strippedValue.length === 0) {
51
+ const refInner = this.transformValue(refMatch[0]);
52
+ if (typeof refInner === 'string') {
53
+ if (refInner.startsWith('param:') && this.props.scope instanceof Stack) {
54
+ return this.createParam(refInner);
55
+ }
56
+ }
57
+ }
58
+ }
59
+ return undefined;
60
+ }
61
+ /**
62
+ * Create new or resolve existing parameter for a given parameter reference
63
+ * @param refInner
64
+ * @returns Value of CfnParameter
65
+ */
66
+ private createParam(refInner: string): string | number {
67
+ if (!this.props.scope) {
68
+ throw new Error('Unable to create parameters outside of a Construct');
69
+ }
70
+ const stack = Stack.of(this.props.scope);
71
+ const paramBase = refInner.replace(/^param:/, '');
72
+ const paramName = paramBase
73
+ .replace(/^string:/, '')
74
+ .replace(/^number:/, '')
75
+ .replace(/^list:/, '');
76
+ const paramProps = this.getParamProps(paramName);
77
+ const exists = stack.node.tryFindChild(paramName) as CfnParameter;
78
+ // Return values for existing parameter if it already exists
79
+ if (exists?.type) {
80
+ if (this.isStringType(exists.type)) return exists.valueAsString;
81
+ else if (this.isNumberType(exists.type)) return exists.valueAsNumber;
82
+ else if (this.isListType(exists.type)) return exists.valueAsList.join(',');
83
+ }
84
+ // If parameter exists, but we weren't able to infer a type, return it as a string
85
+ if (exists) {
86
+ return exists.valueAsString;
87
+ }
88
+ // If parameter properties are present, use them to infer the parameter type if possible
89
+ if (paramProps?.type) {
90
+ return this.createParamUsingProps(paramName, paramProps.type, paramProps);
91
+ }
92
+ // If no paramProps type was found, create a new parameter based on type labels if present
93
+ return this.createParamUsingTypeLabels(paramBase, paramName, paramProps);
94
+ }
95
+ private createParamUsingProps(paramName: string, paramType: string, paramProps: CfnParameterProps) {
96
+ if (!this.props.scope) {
97
+ throw new Error('Unable to create params outside of a Construct');
98
+ }
99
+ if (this.isNumberType(paramType)) {
100
+ return new CfnParameter(this.props.scope, paramName, paramProps).valueAsNumber;
101
+ } else if (this.isStringType(paramType)) {
102
+ return new CfnParameter(this.props.scope, paramName, paramProps).valueAsString;
103
+ } else if (this.isListType(paramType)) {
104
+ return new CfnParameter(this.props.scope, paramName, paramProps).valueAsList.join(',');
105
+ } else {
106
+ throw new Error(
107
+ `Invalid parameter type passed to paramProps: "${paramType}". Type must be one of ['String', 'Number', 'CommaDelimitedList']`,
108
+ );
109
+ }
110
+ }
111
+ protected createParamUsingTypeLabels(
112
+ paramBase: string,
113
+ paramName: string,
114
+ paramProps: CfnParameterProps | undefined,
115
+ ) {
116
+ if (!this.props.scope) {
117
+ throw new Error('Unable to create params outside of a Construct');
118
+ }
119
+ if (paramBase.startsWith('string:')) {
120
+ const typedProps = { ...paramProps, type: 'String' };
121
+ return new CfnParameter(this.props.scope, paramName, typedProps).valueAsString;
122
+ } else if (paramBase.startsWith('number')) {
123
+ const typedProps = { ...paramProps, type: 'Number' };
124
+ return new CfnParameter(this.props.scope, paramName, typedProps).valueAsNumber;
125
+ } else if (paramBase.startsWith('list')) {
126
+ const typedProps = { ...paramProps, type: 'CommaDelimitedList' };
127
+ return new CfnParameter(this.props.scope, paramName, typedProps).valueAsList.join(',');
128
+ }
129
+ // If no type is specified in paramProps, then assume that the parameter is a string
130
+ return new CfnParameter(this.props.scope, paramName, paramProps).valueAsString;
131
+ }
132
+ /**
133
+ * Whether the given parameter type is a list type
134
+ * Follows conventions of CfnParameter internal functions
135
+ */
136
+ private isListType(type: string) {
137
+ return type.includes('List<') || type.includes('CommaDelimitedList');
138
+ }
139
+ /**
140
+ * Whether the given parameter type is a number type
141
+ * Follows conventions of CfnParameter internal functions
142
+ */
143
+ private isNumberType(type: string) {
144
+ return type === 'Number';
145
+ }
146
+ /**
147
+ * Whether the given parameter type is a string type
148
+ * Follows conventions of CfnParameter internal functions
149
+ */
150
+ private isStringType(type: string) {
151
+ return !this.isListType(type) && !this.isNumberType(type);
152
+ }
153
+ private getParamProps(paramName: string): CfnParameterProps | undefined {
154
+ if (this.paramProps[paramName]) {
155
+ return this.paramProps[paramName];
156
+ }
157
+ return undefined;
158
+ }
159
+ }
@@ -0,0 +1,10 @@
1
+ /*!
2
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+ import { IMdaaConfigValueTransformer } from './transformer';
6
+ export declare class ConfigConfigPathValueTransformer implements IMdaaConfigValueTransformer {
7
+ private readonly baseDir;
8
+ constructor(baseDir: string);
9
+ transformValue(value: string): string;
10
+ }
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ /*!
3
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.ConfigConfigPathValueTransformer = void 0;
8
+ const path = require("path");
9
+ class ConfigConfigPathValueTransformer {
10
+ constructor(baseDir) {
11
+ this.baseDir = baseDir;
12
+ }
13
+ transformValue(value) {
14
+ if (value.startsWith('../')) {
15
+ // Resolve to baseDir's parent path
16
+ // nosemgrep
17
+ return path.resolve(this.baseDir, value);
18
+ }
19
+ else if (value.startsWith('./')) {
20
+ // Resolve relative to baseDir
21
+ // nosemgrep
22
+ return path.resolve(value.replace(/^\./, this.baseDir));
23
+ }
24
+ else {
25
+ return value;
26
+ }
27
+ }
28
+ }
29
+ exports.ConfigConfigPathValueTransformer = ConfigConfigPathValueTransformer;
30
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGF0aC12YWx1ZS10cmFuc2Zvcm1lci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInBhdGgtdmFsdWUtdHJhbnNmb3JtZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7R0FHRzs7O0FBRUgsNkJBQTZCO0FBRzdCLE1BQWEsZ0NBQWdDO0lBRTNDLFlBQVksT0FBZTtRQUN6QixJQUFJLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQztJQUN6QixDQUFDO0lBQ00sY0FBYyxDQUFDLEtBQWE7UUFDakMsSUFBSSxLQUFLLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDNUIsbUNBQW1DO1lBQ25DLFlBQVk7WUFDWixPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxLQUFLLENBQUMsQ0FBQztRQUMzQyxDQUFDO2FBQU0sSUFBSSxLQUFLLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7WUFDbEMsOEJBQThCO1lBQzlCLFlBQVk7WUFDWixPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7UUFDMUQsQ0FBQzthQUFNLENBQUM7WUFDTixPQUFPLEtBQUssQ0FBQztRQUNmLENBQUM7SUFDSCxDQUFDO0NBQ0Y7QUFsQkQsNEVBa0JDIiwic291cmNlc0NvbnRlbnQiOlsiLyohXG4gKiBDb3B5cmlnaHQgQW1hem9uLmNvbSwgSW5jLiBvciBpdHMgYWZmaWxpYXRlcy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG4gKi9cblxuaW1wb3J0ICogYXMgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCB7IElNZGFhQ29uZmlnVmFsdWVUcmFuc2Zvcm1lciB9IGZyb20gJy4vdHJhbnNmb3JtZXInO1xuXG5leHBvcnQgY2xhc3MgQ29uZmlnQ29uZmlnUGF0aFZhbHVlVHJhbnNmb3JtZXIgaW1wbGVtZW50cyBJTWRhYUNvbmZpZ1ZhbHVlVHJhbnNmb3JtZXIge1xuICBwcml2YXRlIHJlYWRvbmx5IGJhc2VEaXI6IHN0cmluZztcbiAgY29uc3RydWN0b3IoYmFzZURpcjogc3RyaW5nKSB7XG4gICAgdGhpcy5iYXNlRGlyID0gYmFzZURpcjtcbiAgfVxuICBwdWJsaWMgdHJhbnNmb3JtVmFsdWUodmFsdWU6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgaWYgKHZhbHVlLnN0YXJ0c1dpdGgoJy4uLycpKSB7XG4gICAgICAvLyBSZXNvbHZlIHRvIGJhc2VEaXIncyBwYXJlbnQgcGF0aFxuICAgICAgLy8gbm9zZW1ncmVwXG4gICAgICByZXR1cm4gcGF0aC5yZXNvbHZlKHRoaXMuYmFzZURpciwgdmFsdWUpO1xuICAgIH0gZWxzZSBpZiAodmFsdWUuc3RhcnRzV2l0aCgnLi8nKSkge1xuICAgICAgLy8gUmVzb2x2ZSByZWxhdGl2ZSB0byBiYXNlRGlyXG4gICAgICAvLyBub3NlbWdyZXBcbiAgICAgIHJldHVybiBwYXRoLnJlc29sdmUodmFsdWUucmVwbGFjZSgvXlxcLi8sIHRoaXMuYmFzZURpcikpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxuICB9XG59XG4iXX0=
@@ -0,0 +1,27 @@
1
+ /*!
2
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+
6
+ import * as path from 'path';
7
+ import { IMdaaConfigValueTransformer } from './transformer';
8
+
9
+ export class ConfigConfigPathValueTransformer implements IMdaaConfigValueTransformer {
10
+ private readonly baseDir: string;
11
+ constructor(baseDir: string) {
12
+ this.baseDir = baseDir;
13
+ }
14
+ public transformValue(value: string): string {
15
+ if (value.startsWith('../')) {
16
+ // Resolve to baseDir's parent path
17
+ // nosemgrep
18
+ return path.resolve(this.baseDir, value);
19
+ } else if (value.startsWith('./')) {
20
+ // Resolve relative to baseDir
21
+ // nosemgrep
22
+ return path.resolve(value.replace(/^\./, this.baseDir));
23
+ } else {
24
+ return value;
25
+ }
26
+ }
27
+ }
@@ -0,0 +1,44 @@
1
+ /*!
2
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+ import { Construct } from 'constructs';
6
+ import { IMdaaResourceNaming } from '@aws-mdaa/naming';
7
+ import { ConfigurationElement } from './config';
8
+ import { IMdaaConfigValueTransformer, TransformResult } from './transformer';
9
+ export interface AwsEnvironment {
10
+ readonly partition?: string;
11
+ readonly region?: string;
12
+ readonly account?: string;
13
+ }
14
+ export interface MdaaConfigRefValueTransformerProps {
15
+ readonly naming?: IMdaaResourceNaming;
16
+ readonly org: string;
17
+ readonly domain: string;
18
+ readonly env: string;
19
+ readonly module_name: string;
20
+ readonly scope?: Construct;
21
+ readonly context?: ConfigurationElement;
22
+ readonly awsEnvironment?: AwsEnvironment;
23
+ }
24
+ export declare class MdaaConfigRefValueTransformer implements IMdaaConfigValueTransformer {
25
+ protected props: MdaaConfigRefValueTransformerProps;
26
+ constructor(props: MdaaConfigRefValueTransformerProps);
27
+ transformValue(value: string): TransformResult;
28
+ protected parseRef(value: string, refMatch: string[]): string | number | object;
29
+ private isNakedReference;
30
+ private handleNakedReference;
31
+ private substituteReferences;
32
+ private convertToString;
33
+ private resolveReference;
34
+ private resolveRef;
35
+ private generateLogicalId;
36
+ private getSimpleRefMap;
37
+ private resolveContextReference;
38
+ private resolveEnvVar;
39
+ private extractSsmValue;
40
+ private resolveSsmPartialPathReference;
41
+ private resolveDirectSsm;
42
+ private getSsmValue;
43
+ private parseContext;
44
+ }
@@ -0,0 +1,243 @@
1
+ "use strict";
2
+ /*!
3
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.MdaaConfigRefValueTransformer = void 0;
8
+ const construct_1 = require("@aws-mdaa/construct");
9
+ const aws_cdk_lib_1 = require("aws-cdk-lib");
10
+ const constructs_1 = require("constructs");
11
+ const XRegExp = require("xregexp");
12
+ class MdaaConfigRefValueTransformer {
13
+ constructor(props) {
14
+ this.props = props;
15
+ }
16
+ transformValue(value) {
17
+ const refMatch = XRegExp.matchRecursive(value, '{{', '}}', 'g', {
18
+ unbalanced: 'skip',
19
+ });
20
+ if (refMatch.length > 0) {
21
+ return this.parseRef(value, refMatch);
22
+ }
23
+ else {
24
+ return value;
25
+ }
26
+ }
27
+ parseRef(value, refMatch) {
28
+ const isNakedReference = this.isNakedReference(value, refMatch);
29
+ // Handle naked references that might return objects/arrays
30
+ if (isNakedReference) {
31
+ const nakedResult = this.handleNakedReference(refMatch[0]);
32
+ if (nakedResult !== undefined) {
33
+ return nakedResult;
34
+ }
35
+ }
36
+ // Substitute all references in the string
37
+ return this.substituteReferences(value, refMatch, isNakedReference);
38
+ }
39
+ isNakedReference(value, refMatch) {
40
+ return refMatch.length === 1 && value === `{{${refMatch[0]}}}`;
41
+ }
42
+ handleNakedReference(ref) {
43
+ const refInner = this.transformValue(ref).toString();
44
+ if (refInner.startsWith('context:')) {
45
+ const resolvedValue = this.parseContext(refInner);
46
+ // If it's an object or array, return it directly
47
+ if (typeof resolvedValue === 'object' && resolvedValue !== null) {
48
+ return resolvedValue;
49
+ }
50
+ }
51
+ // For env_var refs, attempt to parse JSON arrays/objects so that
52
+ // env vars containing '["a","b"]' resolve to actual arrays rather than strings.
53
+ if (refInner.startsWith('env_var:')) {
54
+ const envValue = this.resolveEnvVar(refInner);
55
+ if (envValue && (envValue.startsWith('[') || envValue.startsWith('{'))) {
56
+ try {
57
+ const parsed = JSON.parse(envValue);
58
+ if (typeof parsed === 'object' && parsed !== null) {
59
+ return parsed;
60
+ }
61
+ }
62
+ catch {
63
+ // Not valid JSON — fall through to string substitution
64
+ }
65
+ }
66
+ }
67
+ return undefined;
68
+ }
69
+ substituteReferences(value, refMatch, isNakedReference) {
70
+ return refMatch.reduce((result, ref) => {
71
+ const refInner = this.transformValue(ref).toString();
72
+ const resolvedValue = this.resolveReference(refInner, isNakedReference);
73
+ if (resolvedValue === undefined) {
74
+ return result;
75
+ }
76
+ const stringValue = this.convertToString(resolvedValue);
77
+ return result.replace(`{{${ref}}}`, stringValue);
78
+ }, value);
79
+ }
80
+ convertToString(value) {
81
+ if (typeof value === 'string') {
82
+ return value;
83
+ }
84
+ if (typeof value === 'number' || typeof value === 'boolean') {
85
+ return String(value);
86
+ }
87
+ // For objects, use JSON.stringify as a safe fallback
88
+ return JSON.stringify(value);
89
+ }
90
+ resolveReference(refInner, isNakedReference) {
91
+ const simpleRefMap = this.getSimpleRefMap();
92
+ if (simpleRefMap[refInner]) {
93
+ return simpleRefMap[refInner];
94
+ }
95
+ if (refInner.startsWith('context:')) {
96
+ return this.resolveContextReference(refInner, isNakedReference);
97
+ }
98
+ if (refInner.startsWith('env_var:')) {
99
+ return this.resolveEnvVar(refInner);
100
+ }
101
+ if (refInner.startsWith('ssm-org:')) {
102
+ return this.resolveSsmPartialPathReference(refInner);
103
+ }
104
+ if (refInner.startsWith('ssm-domain:')) {
105
+ return this.resolveSsmPartialPathReference(refInner);
106
+ }
107
+ if (refInner.startsWith('ssm-env:')) {
108
+ return this.resolveSsmPartialPathReference(refInner);
109
+ }
110
+ if (refInner.startsWith('resolve:ssm:')) {
111
+ return this.resolveDirectSsm(refInner);
112
+ }
113
+ if (refInner.startsWith('ref:')) {
114
+ return this.resolveRef(refInner);
115
+ }
116
+ return undefined;
117
+ }
118
+ resolveRef(refInner) {
119
+ const dummyStack = new aws_cdk_lib_1.Stack(undefined);
120
+ const withoutPrefix = refInner.replace(/^ref:/, '');
121
+ const parts = withoutPrefix.split(':');
122
+ // Remove leading slash if present from the path
123
+ const pathWithSlash = parts[0];
124
+ const path = pathWithSlash.startsWith('/') ? pathWithSlash.slice(1) : pathWithSlash;
125
+ const attr = parts[1]; // Will be undefined if no attribute specified
126
+ const logicalId = this.generateLogicalId(dummyStack, path);
127
+ if (attr) {
128
+ return aws_cdk_lib_1.Fn.getAtt(logicalId, attr).toString();
129
+ }
130
+ else {
131
+ return aws_cdk_lib_1.Fn.ref(logicalId).toString();
132
+ }
133
+ }
134
+ generateLogicalId(parentScope, path) {
135
+ const pathComponents = path.split('/');
136
+ const construct = new constructs_1.Construct(parentScope, pathComponents[0]);
137
+ if (pathComponents.length == 1) {
138
+ return aws_cdk_lib_1.Names.nodeUniqueId(construct.node);
139
+ }
140
+ else {
141
+ return this.generateLogicalId(construct, pathComponents.slice(1).join('/'));
142
+ }
143
+ }
144
+ getSimpleRefMap() {
145
+ const scopeStack = this.props.scope ? aws_cdk_lib_1.Stack.of(this.props.scope) : undefined;
146
+ return {
147
+ org: this.props.org,
148
+ env: this.props.env,
149
+ domain: this.props.domain,
150
+ module_name: this.props.module_name,
151
+ partition: this.props.awsEnvironment?.partition ?? scopeStack?.partition,
152
+ region: this.props.awsEnvironment?.region ?? scopeStack?.region,
153
+ account: this.props.awsEnvironment?.account ?? scopeStack?.account,
154
+ };
155
+ }
156
+ resolveContextReference(refInner, isNakedReference) {
157
+ const resolvedValue = this.parseContext(refInner);
158
+ // If the resolved value is an object or array, and we're not in a naked reference
159
+ if (typeof resolvedValue === 'object' && resolvedValue !== null && !isNakedReference) {
160
+ throw new Error('Cannot embed array or object context value in string');
161
+ }
162
+ return resolvedValue;
163
+ }
164
+ resolveEnvVar(refInner) {
165
+ const envVar = refInner.replace(/^env_var:/, '');
166
+ return process.env[envVar];
167
+ }
168
+ extractSsmValue(refInner, prefix) {
169
+ const extracted = refInner.replace(new RegExp(String.raw `^${prefix}:\s*`), '');
170
+ // Remove leading slash to prevent double slashes in the path
171
+ return extracted.startsWith('/') ? extracted.slice(1) : extracted;
172
+ }
173
+ resolveSsmPartialPathReference(refInner) {
174
+ if (!this.props.naming) {
175
+ throw new Error(`Unable to resolve ${refInner} ssm param outside of a naming context`);
176
+ }
177
+ if (refInner.startsWith('ssm-org:')) {
178
+ const ssmPath = this.props.naming.ssmOrgPath(this.extractSsmValue(refInner, 'ssm-org'));
179
+ return `{{resolve:ssm:${ssmPath}}}`;
180
+ }
181
+ if (refInner.startsWith('ssm-domain:')) {
182
+ const ssmPath = this.props.naming.ssmDomainPath(this.extractSsmValue(refInner, 'ssm-domain'));
183
+ return `{{resolve:ssm:${ssmPath}}}`;
184
+ }
185
+ if (refInner.startsWith('ssm-env:')) {
186
+ const ssmPath = this.props.naming.ssmEnvPath(this.extractSsmValue(refInner, 'ssm-env'));
187
+ return `{{resolve:ssm:${ssmPath}}}`;
188
+ }
189
+ return refInner;
190
+ }
191
+ resolveDirectSsm(refInner) {
192
+ if (!this.props.scope) {
193
+ throw new Error('Unable to resolve ssm param outside of a Construct');
194
+ }
195
+ const ssmPath = refInner.replace(/^resolve:ssm:/, '');
196
+ console.log(`Resolving SSM: ${ssmPath}`);
197
+ return this.getSsmValue(ssmPath);
198
+ }
199
+ getSsmValue(ssmPath) {
200
+ if (!this.props.scope) {
201
+ throw new Error('Unable to resolve ssm param outside of a Construct');
202
+ }
203
+ //Handle full arn-based SSM paths (for referencing RAM shared SSM params from other accounts)
204
+ if (ssmPath.startsWith('arn:')) {
205
+ const stack = aws_cdk_lib_1.Stack.of(this.props.scope);
206
+ const exists = stack.node.tryFindChild(ssmPath);
207
+ if (exists) {
208
+ return exists.stringValue;
209
+ }
210
+ return construct_1.MdaaStringParameter.fromStringParameterArn(aws_cdk_lib_1.Stack.of(this.props.scope), ssmPath, ssmPath).stringValue;
211
+ }
212
+ return this.props.scope.node.tryGetContext('@mdaaLookupSSMValues')
213
+ ? construct_1.MdaaStringParameter.valueFromLookup(aws_cdk_lib_1.Stack.of(this.props.scope), ssmPath)
214
+ : construct_1.MdaaStringParameter.valueForStringParameter(aws_cdk_lib_1.Stack.of(this.props.scope), ssmPath);
215
+ }
216
+ parseContext(refInner) {
217
+ const refInnerContext = refInner.replace(/^context:/, '');
218
+ const scopeContextValue = this.props.scope?.node.tryGetContext(refInnerContext);
219
+ const scopeInnerContextValue = this.props.context ? this.props.context[refInnerContext] : undefined;
220
+ const contextValue = scopeContextValue ?? scopeInnerContextValue;
221
+ if (!contextValue) {
222
+ throw new Error(`Failed to resolve context: ${refInnerContext}`);
223
+ }
224
+ if (typeof contextValue === 'string') {
225
+ // Check if the value is encoded with quotes (from CLI encoding)
226
+ if (contextValue.startsWith('"') && contextValue.endsWith('"')) {
227
+ // Remove outer quotes
228
+ const unquoted = contextValue.slice(1, -1);
229
+ if (unquoted.startsWith('obj:')) {
230
+ // Parse object: "obj:{...}" -> {...}
231
+ return JSON.parse(unquoted.replace(/^obj:/, ''));
232
+ }
233
+ else if (unquoted.startsWith('list:')) {
234
+ // Parse array: "list:[...]" -> [...]
235
+ return JSON.parse(unquoted.replace(/^list:/, ''));
236
+ }
237
+ }
238
+ }
239
+ return contextValue;
240
+ }
241
+ }
242
+ exports.MdaaConfigRefValueTransformer = MdaaConfigRefValueTransformer;
243
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVmLXZhbHVlLXRyYW5zZm9ybWVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsicmVmLXZhbHVlLXRyYW5zZm9ybWVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTs7O0dBR0c7OztBQUVILG1EQUEwRDtBQUMxRCw2Q0FBK0M7QUFDL0MsMkNBQXVDO0FBR3ZDLG1DQUFtQztBQXNCbkMsTUFBYSw2QkFBNkI7SUFHeEMsWUFBWSxLQUF5QztRQUNuRCxJQUFJLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQztJQUNyQixDQUFDO0lBRU0sY0FBYyxDQUFDLEtBQWE7UUFDakMsTUFBTSxRQUFRLEdBQUcsT0FBTyxDQUFDLGNBQWMsQ0FBQyxLQUFLLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxHQUFHLEVBQUU7WUFDOUQsVUFBVSxFQUFFLE1BQU07U0FDbkIsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxRQUFRLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQ3hCLE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLEVBQUUsUUFBUSxDQUFvQixDQUFDO1FBQzNELENBQUM7YUFBTSxDQUFDO1lBQ04sT0FBTyxLQUFLLENBQUM7UUFDZixDQUFDO0lBQ0gsQ0FBQztJQUVTLFFBQVEsQ0FBQyxLQUFhLEVBQUUsUUFBa0I7UUFDbEQsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsS0FBSyxFQUFFLFFBQVEsQ0FBQyxDQUFDO1FBRWhFLDJEQUEyRDtRQUMzRCxJQUFJLGdCQUFnQixFQUFFLENBQUM7WUFDckIsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLG9CQUFvQixDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzNELElBQUksV0FBVyxLQUFLLFNBQVMsRUFBRSxDQUFDO2dCQUM5QixPQUFPLFdBQVcsQ0FBQztZQUNyQixDQUFDO1FBQ0gsQ0FBQztRQUNELDBDQUEwQztRQUMxQyxPQUFPLElBQUksQ0FB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dGVudCI6WyIvKiFcbiAqIENvcHlyaWdodCBBbWF6b24uY29tLCBJbmMuIG9yIGl0cyBhZmZpbGlhdGVzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcbiAqL1xuXG5pbXBvcnQgeyBNZGFhU3RyaW5nUGFyYW1ldGVyIH0gZnJvbSAnQGF3cy1tZGFhL2NvbnN0cnVjdCc7XG5pbXBvcnQgeyBGbiwgTmFtZXMsIFN0YWNrIH0gZnJvbSAnYXdzLWNkay1saWInO1xuaW1wb3J0IHsgQ29uc3RydWN0IH0gZnJvbSAnY29uc3RydWN0cyc7XG4vLyBub3NlbWdyZXBcbmltcG9ydCB7IElNZGFhUmVzb3VyY2VOYW1pbmcgfSBmcm9tICdAYXdzLW1kYWEvbmFtaW5nJztcbmltcG9ydCAqIGFzIFhSZWdFeHAgZnJvbSAneHJlZ2V4cCc7XG5pbXBvcnQgeyBDb25maWd1cmF0aW9uRWxlbWVudCB9IGZyb20gJy4vY29uZmlnJztcbmltcG9ydCB7IElNZGFhQ29uZmlnVmFsdWVUcmFuc2Zvcm1lciwgVHJhbnNmb3JtUmVzdWx0IH0gZnJvbSAnLi90cmFuc2Zvcm1lcic7XG5pbXBvcnQgeyBJU3RyaW5nUGFyYW1ldGVyIH0gZnJvbSAnYXdzLWNkay1saWIvYXdzLXNzbSc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgQXdzRW52aXJvbm1lbnQge1xuICByZWFkb25seSBwYXJ0aXRpb24/OiBzdHJpbmc7XG4gIHJlYWRvbmx5IHJlZ2lvbj86IHN0cmluZztcbiAgcmVhZG9ubHkgYWNjb3VudD86IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBNZGFhQ29uZmlnUmVmVmFsdWVUcmFuc2Zvcm1lclByb3BzIHtcbiAgcmVhZG9ubHkgbmFtaW5nPzogSU1kYWFSZXNvdXJjZU5hbWluZztcbiAgcmVhZG9ubHkgb3JnOiBzdHJpbmc7XG4gIHJlYWRvbmx5IGRvbWFpbjogc3RyaW5nO1xuICByZWFkb25seSBlbnY6IHN0cmluZztcbiAgcmVhZG9ubHkgbW9kdWxlX25hbWU6IHN0cmluZztcbiAgcmVhZG9ubHkgc2NvcGU/OiBDb25zdHJ1Y3Q7XG4gIHJlYWRvbmx5IGNvbnRleHQ/OiBDb25maWd1cmF0aW9uRWxlbWVudDtcbiAgcmVhZG9ubHkgYXdzRW52aXJvbm1lbnQ/OiBBd3NFbnZpcm9ubWVudDtcbn1cblxuZXhwb3J0IGNsYXNzIE1kYWFDb25maWdSZWZWYWx1ZVRyYW5zZm9ybWVyIGltcGxlbWVudHMgSU1kYWFDb25maWdWYWx1ZVRyYW5zZm9ybWVyIHtcbiAgcHJvdGVjdGVkIHByb3BzOiBNZGFhQ29uZmlnUmVmVmFsdWVUcmFuc2Zvcm1lclByb3BzO1xuXG4gIGNvbnN0cnVjdG9yKHByb3BzOiBNZGFhQ29uZmlnUmVmVmFsdWVUcmFuc2Zvcm1lclByb3BzKSB7XG4gICAgdGhpcy5wcm9wcyA9IHByb3BzO1xuICB9XG5cbiAgcHVibGljIHRyYW5zZm9ybVZhbHVlKHZhbHVlOiBzdHJpbmcpOiBUcmFuc2Zvcm1SZXN1bHQge1xuICAgIGNvbnN0IHJlZk1hdGNoID0gWFJlZ0V4cC5tYXRjaFJlY3Vyc2l2ZSh2YWx1ZSwgJ3t7JywgJ319JywgJ2cnLCB7XG4gICAgICB1bmJhbGFuY2VkOiAnc2tpcCcsXG4gICAgfSk7XG4gICAgaWYgKHJlZk1hdGNoLmxlbmd0aCA+IDApIHtcbiAgICAgIHJldHVybiB0aGlzLnBhcnNlUmVmKHZhbHVlLCByZWZNYXRjaCkgYXMgVHJhbnNmb3JtUmVzdWx0O1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxuICB9XG5cbiAgcHJvdGVjdGVkIHBhcnNlUmVmKHZhbHVlOiBzdHJpbmcsIHJlZk1hdGNoOiBzdHJpbmdbXSk6IHN0cmluZyB8IG51bWJlciB8IG9iamVjdCB7XG4gICAgY29uc3QgaXNOYWtlZFJlZmVyZW5jZSA9IHRoaXMuaXNOYWtlZFJlZmVyZW5jZSh2YWx1ZSwgcmVmTWF0Y2gpO1xuXG4gICAgLy8gSGFuZGxlIG5ha2VkIHJlZmVyZW5jZXMgdGhhdCBtaWdodCByZXR1cm4gb2JqZWN0cy9hcnJheXNcbiAgICBpZiAoaXNOYWtlZFJlZmVyZW5jZSkge1xuICAgICAgY29uc3QgbmFrZWRSZXN1bHQgPSB0aGlzLmhhbmRsZU5ha2VkUmVmZXJlbmNlKHJlZk1hdGNoWzBdKTtcbiAgICAgIGlmIChuYWtlZFJlc3VsdCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiBuYWtlZFJlc3VsdDtcbiAgICAgIH1cbiAgICB9XG4gICAgLy8gU3Vic3RpdHV0ZSBhbGwgcmVmZXJlbmNlcyBpbiB0aGUgc3RyaW5nXG4gICAgcmV0dXJuIHRoaXMuc3Vic3RpdHV0ZVJlZmVyZW5jZXModmFsdWUsIHJlZk1hdGNoLCBpc05ha2VkUmVmZXJlbmNlKTtcbiAgfVxuXG4gIHByaXZhdGUgaXNOYWtlZFJlZmVyZW5jZSh2YWx1ZTogc3RyaW5nLCByZWZNYXRjaDogc3RyaW5nW10pOiBib29sZWFuIHtcbiAgICByZXR1cm4gcmVmTWF0Y2gubGVuZ3RoID09PSAxICYmIHZhbHVlID09PSBge3ske3JlZk1hdGNoWzBdfX19YDtcbiAgfVxuXG4gIHByaXZhdGUgaGFuZGxlTmFrZWRSZWZlcmVuY2UocmVmOiBzdHJpbmcpIHtcbiAgICBjb25zdCByZWZJbm5lciA9IHRoaXMudHJhbnNmb3JtVmFsdWUocmVmKS50b1N0cmluZygpO1xuXG4gICAgaWYgKHJlZklubmVyLnN0YXJ0c1dpdGgoJ2NvbnRleHQ6JykpIHtcbiAgICAgIGNvbnN0IHJlc29sdmVkVmFsdWUgPSB0aGlzLnBhcnNlQ29udGV4dChyZWZJbm5lcik7XG4gICAgICAvLyBJZiBpdCdzIGFuIG9iamVjdCBvciBhcnJheSwgcmV0dXJuIGl0IGRpcmVjdGx5XG4gICAgICBpZiAodHlwZW9mIHJlc29sdmVkVmFsdWUgPT09ICdvYmplY3QnICYmIHJlc29sdmVkVmFsdWUgIT09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIHJlc29sdmVkVmFsdWU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gRm9yIGVudl92YXIgcmVmcywgYXR0ZW1wdCB0byBwYXJzZSBKU09OIGFycmF5cy9vYmplY3RzIHNvIHRoYXRcbiAgICAvLyBlbnYgdmFycyBjb250YWluaW5nICdbXCJhXCIsXCJiXCJdJyByZXNvbHZlIHRvIGFjdHVhbCBhcnJheXMgcmF0aGVyIHRoYW4gc3RyaW5ncy5cbiAgICBpZiAocmVmSW5uZXIuc3RhcnRzV2l0aCgnZW52X3ZhcjonKSkge1xuICAgICAgY29uc3QgZW52VmFsdWUgPSB0aGlzLnJlc29sdmVFbnZWYXIocmVmSW5uZXIpO1xuICAgICAgaWYgKGVudlZhbHVlICYmIChlbnZWYWx1ZS5zdGFydHNXaXRoKCdbJykgfHwgZW52VmFsdWUuc3RhcnRzV2l0aCgneycpKSkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGNvbnN0IHBhcnNlZCA9IEpTT04ucGFyc2UoZW52VmFsdWUpO1xuICAgICAgICAgIGlmICh0eXBlb2YgcGFyc2VkID09PSAnb2JqZWN0JyAmJiBwYXJzZWQgIT09IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybiBwYXJzZWQ7XG4gICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIHtcbiAgICAgICAgICAvLyBOb3QgdmFsaWQgSlNPTiDigJQgZmFsbCB0aHJvdWdoIHRvIHN0cmluZyBzdWJzdGl0dXRpb25cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICBwcml2YXRlIHN1YnN0aXR1dGVSZWZlcmVuY2VzKHZhbHVlOiBzdHJpbmcsIHJlZk1hdGNoOiBzdHJpbmdbXSwgaXNOYWtlZFJlZmVyZW5jZTogYm9vbGVhbik6IHN0cmluZyB7XG4gICAgcmV0dXJuIHJlZk1hdGNoLnJlZHVjZSgocmVzdWx0LCByZWYpID0+IHtcbiAgICAgIGNvbnN0IHJlZklubmVyID0gdGhpcy50cmFuc2Zvcm1WYWx1ZShyZWYpLnRvU3RyaW5nKCk7XG4gICAgICBjb25zdCByZXNvbHZlZFZhbHVlID0gdGhpcy5yZXNvbHZlUmVmZXJlbmNlKHJlZklubmVyLCBpc05ha2VkUmVmZXJlbmNlKTtcblxuICAgICAgaWYgKHJlc29sdmVkVmFsdWUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgfVxuXG4gICAgICBjb25zdCBzdHJpbmdWYWx1ZSA9IHRoaXMuY29udmVydFRvU3RyaW5nKHJlc29sdmVkVmFsdWUpO1xuICAgICAgcmV0dXJuIHJlc3VsdC5yZXBsYWNlKGB7eyR7cmVmfX19YCwgc3RyaW5nVmFsdWUpO1xuICAgIH0sIHZhbHVlKTtcbiAgfVxuXG4gIHByaXZhdGUgY29udmVydFRvU3RyaW5nKHZhbHVlOiB1bmtub3duKTogc3RyaW5nIHtcbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykge1xuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH1cbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJyB8fCB0eXBlb2YgdmFsdWUgPT09ICdib29sZWFuJykge1xuICAgICAgcmV0dXJuIFN0cmluZyh2YWx1ZSk7XG4gICAgfVxuICAgIC8vIEZvciBvYmplY3RzLCB1c2UgSlNPTi5zdHJpbmdpZnkgYXMgYSBzYWZlIGZhbGxiYWNrXG4gICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHZhbHVlKTtcbiAgfVxuXG4gIHByaXZhdGUgcmVzb2x2ZVJlZmVyZW5jZShyZWZJbm5lcjogc3RyaW5nLCBpc05ha2VkUmVmZXJlbmNlOiBib29sZWFuKSB7XG4gICAgY29uc3Qgc2ltcGxlUmVmTWFwID0gdGhpcy5nZXRTaW1wbGVSZWZNYXAoKTtcblxuICAgIGlmIChzaW1wbGVSZWZNYXBbcmVmSW5uZXJdKSB7XG4gICAgICByZXR1cm4gc2ltcGxlUmVmTWFwW3JlZklubmVyXTtcbiAgICB9XG5cbiAgICBpZiAocmVmSW5uZXIuc3RhcnRzV2l0aCgnY29udGV4dDonKSkge1xuICAgICAgcmV0dXJuIHRoaXMucmVzb2x2ZUNvbnRleHRSZWZlcmVuY2UocmVmSW5uZXIsIGlzTmFrZWRSZWZlcmVuY2UpO1xuICAgIH1cblxuICAgIGlmIChyZWZJbm5lci5zdGFydHNXaXRoKCdlbnZfdmFyOicpKSB7XG4gICAgICByZXR1cm4gdGhpcy5yZXNvbHZlRW52VmFyKHJlZklubmVyKTtcbiAgICB9XG5cbiAgICBpZiAocmVmSW5uZXIuc3RhcnRzV2l0aCgnc3NtLW9yZzonKSkge1xuICAgICAgcmV0dXJuIHRoaXMucmVzb2x2ZVNzbVBhcnRpYWxQYXRoUmVmZXJlbmNlKHJlZklubmVyKTtcbiAgICB9XG5cbiAgICBpZiAocmVmSW5uZXIuc3RhcnRzV2l0aCgnc3NtLWRvbWFpbjonKSkge1xuICAgICAgcmV0dXJuIHRoaXMucmVzb2x2ZVNzbVBhcnRpYWxQYXRoUmVmZXJlbmNlKHJlZklubmVyKTtcbiAgICB9XG5cbiAgICBpZiAocmVmSW5uZXIuc3RhcnRzV2l0aCgnc3NtLWVudjonKSkge1xuICAgICAgcmV0dXJuIHRoaXMucmVzb2x2ZVNzbVBhcnRpYWxQYXRoUmVmZXJlbmNlKHJlZklubmVyKTtcbiAgICB9XG5cbiAgICBpZiAocmVmSW5uZXIuc3RhcnRzV2l0aCgncmVzb2x2ZTpzc206JykpIHtcbiAgICAgIHJldHVybiB0aGlzLnJlc29sdmVEaXJlY3RTc20ocmVmSW5uZXIpO1xuICAgIH1cblxuICAgIGlmIChyZWZJbm5lci5zdGFydHNXaXRoKCdyZWY6JykpIHtcbiAgICAgIHJldHVybiB0aGlzLnJlc29sdmVSZWYocmVmSW5uZXIpO1xuICAgIH1cblxuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICBwcml2YXRlIHJlc29sdmVSZWYocmVmSW5uZXI6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgY29uc3QgZHVtbXlTdGFjayA9IG5ldyBTdGFjayh1bmRlZmluZWQpO1xuICAgIGNvbnN0IHdpdGhvdXRQcmVmaXggPSByZWZJbm5lci5yZXBsYWNlKC9ecmVmOi8sICcnKTtcbiAgICBjb25zdCBwYXJ0cyA9IHdpdGhvdXRQcmVmaXguc3BsaXQoJzonKTtcblxuICAgIC8vIFJlbW92ZSBsZWFkaW5nIHNsYXNoIGlmIHByZXNlbnQgZnJvbSB0aGUgcGF0aFxuICAgIGNvbnN0IHBhdGhXaXRoU2xhc2ggPSBwYXJ0c1swXTtcbiAgICBjb25zdCBwYXRoID0gcGF0aFdpdGhTbGFzaC5zdGFydHNXaXRoKCcvJykgPyBwYXRoV2l0aFNsYXNoLnNsaWNlKDEpIDogcGF0aFdpdGhTbGFzaDtcbiAgICBjb25zdCBhdHRyID0gcGFydHNbMV07IC8vIFdpbGwgYmUgdW5kZWZpbmVkIGlmIG5vIGF0dHJpYnV0ZSBzcGVjaWZpZWRcblxuICAgIGNvbnN0IGxvZ2ljYWxJZCA9IHRoaXMuZ2VuZXJhdGVMb2dpY2FsSWQoZHVtbXlTdGFjaywgcGF0aCk7XG5cbiAgICBpZiAoYXR0cikge1xuICAgICAgcmV0dXJuIEZuLmdldEF0dChsb2dpY2FsSWQsIGF0dHIpLnRvU3RyaW5nKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBGbi5yZWYobG9naWNhbElkKS50b1N0cmluZygpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgZ2VuZXJhdGVMb2dpY2FsSWQocGFyZW50U2NvcGU6IENvbnN0cnVjdCwgcGF0aDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBjb25zdCBwYXRoQ29tcG9uZW50cyA9IHBhdGguc3BsaXQoJy8nKTtcbiAgICBjb25zdCBjb25zdHJ1Y3QgPSBuZXcgQ29uc3RydWN0KHBhcmVudFNjb3BlLCBwYXRoQ29tcG9uZW50c1swXSk7XG4gICAgaWYgKHBhdGhDb21wb25lbnRzLmxlbmd0aCA9PSAxKSB7XG4gICAgICByZXR1cm4gTmFtZXMubm9kZVVuaXF1ZUlkKGNvbnN0cnVjdC5ub2RlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHRoaXMuZ2VuZXJhdGVMb2dpY2FsSWQoY29uc3RydWN0LCBwYXRoQ29tcG9uZW50cy5zbGljZSgxKS5qb2luKCcvJykpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgZ2V0U2ltcGxlUmVmTWFwKCk6IHsgW2tleTogc3RyaW5nXTogc3RyaW5nIHwgdW5kZWZpbmVkIH0ge1xuICAgIGNvbnN0IHNjb3BlU3RhY2sgPSB0aGlzLnByb3BzLnNjb3BlID8gU3RhY2sub2YodGhpcy5wcm9wcy5zY29wZSkgOiB1bmRlZmluZWQ7XG4gICAgcmV0dXJuIHtcbiAgICAgIG9yZzogdGhpcy5wcm9wcy5vcmcsXG4gICAgICBlbnY6IHRoaXMucHJvcHMuZW52LFxuICAgICAgZG9tYWluOiB0aGlzLnByb3BzLmRvbWFpbixcbiAgICAgIG1vZHVsZV9uYW1lOiB0aGlzLnByb3BzLm1vZHVsZV9uYW1lLFxuICAgICAgcGFydGl0aW9uOiB0aGlzLnByb3BzLmF3c0Vudmlyb25tZW50Py5wYXJ0aXRpb24gPz8gc2NvcGVTdGFjaz8ucGFydGl0aW9uLFxuICAgICAgcmVnaW9uOiB0aGlzLnByb3BzLmF3c0Vudmlyb25tZW50Py5yZWdpb24gPz8gc2NvcGVTdGFjaz8ucmVnaW9uLFxuICAgICAgYWNjb3VudDogdGhpcy5wcm9wcy5hd3NFbnZpcm9ubWVudD8uYWNjb3VudCA/PyBzY29wZVN0YWNrPy5hY2NvdW50LFxuICAgIH07XG4gIH1cblxuICBwcml2YXRlIHJlc29sdmVDb250ZXh0UmVmZXJlbmNlKHJlZklubmVyOiBzdHJpbmcsIGlzTmFrZWRSZWZlcmVuY2U6IGJvb2xlYW4pIHtcbiAgICBjb25zdCByZXNvbHZlZFZhbHVlID0gdGhpcy5wYXJzZUNvbnRleHQocmVmSW5uZXIpO1xuXG4gICAgLy8gSWYgdGhlIHJlc29sdmVkIHZhbHVlIGlzIGFuIG9iamVjdCBvciBhcnJheSwgYW5kIHdlJ3JlIG5vdCBpbiBhIG5ha2VkIHJlZmVyZW5jZVxuICAgIGlmICh0eXBlb2YgcmVzb2x2ZWRWYWx1ZSA9PT0gJ29iamVjdCcgJiYgcmVzb2x2ZWRWYWx1ZSAhPT0gbnVsbCAmJiAhaXNOYWtlZFJlZmVyZW5jZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdDYW5ub3QgZW1iZWQgYXJyYXkgb3Igb2JqZWN0IGNvbnRleHQgdmFsdWUgaW4gc3RyaW5nJyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc29sdmVkVmFsdWU7XG4gIH1cblxuICBwcml2YXRlIHJlc29sdmVFbnZWYXIocmVmSW5uZXI6IHN0cmluZyk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3QgZW52VmFyID0gcmVmSW5uZXIucmVwbGFjZSgvXmVudl92YXI6LywgJycpO1xuICAgIHJldHVybiBwcm9jZXNzLmVudltlbnZWYXJdO1xuICB9XG5cbiAgcHJpdmF0ZSBleHRyYWN0U3NtVmFsdWUocmVmSW5uZXI6IHN0cmluZywgcHJlZml4OiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGNvbnN0IGV4dHJhY3RlZCA9IHJlZklubmVyLnJlcGxhY2UobmV3IFJlZ0V4cChTdHJpbmcucmF3YF4ke3ByZWZpeH06XFxzKmApLCAnJyk7XG4gICAgLy8gUmVtb3ZlIGxlYWRpbmcgc2xhc2ggdG8gcHJldmVudCBkb3VibGUgc2xhc2hlcyBpbiB0aGUgcGF0aFxuICAgIHJldHVybiBleHRyYWN0ZWQuc3RhcnRzV2l0aCgnLycpID8gZXh0cmFjdGVkLnNsaWNlKDEpIDogZXh0cmFjdGVkO1xuICB9XG5cbiAgcHJpdmF0ZSByZXNvbHZlU3NtUGFydGlhbFBhdGhSZWZlcmVuY2UocmVmSW5uZXI6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgaWYgKCF0aGlzLnByb3BzLm5hbWluZykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmFibGUgdG8gcmVzb2x2ZSAke3JlZklubmVyfSBzc20gcGFyYW0gb3V0c2lkZSBvZiBhIG5hbWluZyBjb250ZXh0YCk7XG4gICAgfVxuXG4gICAgaWYgKHJlZklubmVyLnN0YXJ0c1dpdGgoJ3NzbS1vcmc6JykpIHtcbiAgICAgIGNvbnN0IHNzbVBhdGggPSB0aGlzLnByb3BzLm5hbWluZy5zc21PcmdQYXRoKHRoaXMuZXh0cmFjdFNzbVZhbHVlKHJlZklubmVyLCAnc3NtLW9yZycpKTtcbiAgICAgIHJldHVybiBge3tyZXNvbHZlOnNzbToke3NzbVBhdGh9fX1gO1xuICAgIH1cblxuICAgIGlmIChyZWZJbm5lci5zdGFydHNXaXRoKCdzc20tZG9tYWluOicpKSB7XG4gICAgICBjb25zdCBzc21QYXRoID0gdGhpcy5wcm9wcy5uYW1pbmcuc3NtRG9tYWluUGF0aCh0aGlzLmV4dHJhY3RTc21WYWx1ZShyZWZJbm5lciwgJ3NzbS1kb21haW4nKSk7XG4gICAgICByZXR1cm4gYHt7cmVzb2x2ZTpzc206JHtzc21QYXRofX19YDtcbiAgICB9XG5cbiAgICBpZiAocmVmSW5uZXIuc3RhcnRzV2l0aCgnc3NtLWVudjonKSkge1xuICAgICAgY29uc3Qgc3NtUGF0aCA9IHRoaXMucHJvcHMubmFtaW5nLnNzbUVudlBhdGgodGhpcy5leHRyYWN0U3NtVmFsdWUocmVmSW5uZXIsICdzc20tZW52JykpO1xuICAgICAgcmV0dXJuIGB7e3Jlc29sdmU6c3NtOiR7c3NtUGF0aH19fWA7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlZklubmVyO1xuICB9XG5cbiAgcHJpdmF0ZSByZXNvbHZlRGlyZWN0U3NtKHJlZklubmVyOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGlmICghdGhpcy5wcm9wcy5zY29wZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbmFibGUgdG8gcmVzb2x2ZSBzc20gcGFyYW0gb3V0c2lkZSBvZiBhIENvbnN0cnVjdCcpO1xuICAgIH1cblxuICAgIGNvbnN0IHNzbVBhdGggPSByZWZJbm5lci5yZXBsYWNlKC9ecmVzb2x2ZTpzc206LywgJycpO1xuICAgIGNvbnNvbGUubG9nKGBSZXNvbHZpbmcgU1NNOiAke3NzbVBhdGh9YCk7XG4gICAgcmV0dXJuIHRoaXMuZ2V0U3NtVmFsdWUoc3NtUGF0aCk7XG4gIH1cblxuICBwcml2YXRlIGdldFNzbVZhbHVlKHNzbVBhdGg6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgaWYgKCF0aGlzLnByb3BzLnNjb3BlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1VuYWJsZSB0byByZXNvbHZlIHNzbSBwYXJhbSBvdXRzaWRlIG9mIGEgQ29uc3RydWN0Jyk7XG4gICAgfVxuICAgIC8vSGFuZGxlIGZ1bGwgYXJuLWJhc2VkIFNTTSBwYXRocyAoZm9yIHJlZmVyZW5jaW5nIFJBTSBzaGFyZWQgU1NNIHBhcmFtcyBmcm9tIG90aGVyIGFjY291bnRzKVxuICAgIGlmIChzc21QYXRoLnN0YXJ0c1dpdGgoJ2FybjonKSkge1xuICAgICAgY29uc3Qgc3RhY2sgPSBTdGFjay5vZih0aGlzLnByb3BzLnNjb3BlKTtcbiAgICAgIGNvbnN0IGV4aXN0cyA9IHN0YWNrLm5vZGUudHJ5RmluZENoaWxkKHNzbVBhdGgpIGFzIElTdHJpbmdQYXJhbWV0ZXI7XG4gICAgICBpZiAoZXhpc3RzKSB7XG4gICAgICAgIHJldHVybiBleGlzdHMuc3RyaW5nVmFsdWU7XG4gICAgICB9XG4gICAgICByZXR1cm4gTWRhYVN0cmluZ1BhcmFtZXRlci5mcm9tU3RyaW5nUGFyYW1ldGVyQXJuKFN0YWNrLm9mKHRoaXMucHJvcHMuc2NvcGUpLCBzc21QYXRoLCBzc21QYXRoKS5zdHJpbmdWYWx1ZTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMucHJvcHMuc2NvcGUubm9kZS50cnlHZXRDb250ZXh0KCdAbWRhYUxvb2t1cFNTTVZhbHVlcycpXG4gICAgICA/IE1kYWFTdHJpbmdQYXJhbWV0ZXIudmFsdWVGcm9tTG9va3VwKFN0YWNrLm9mKHRoaXMucHJvcHMuc2NvcGUpLCBzc21QYXRoKVxuICAgICAgOiBNZGFhU3RyaW5nUGFyYW1ldGVyLnZhbHVlRm9yU3RyaW5nUGFyYW1ldGVyKFN0YWNrLm9mKHRoaXMucHJvcHMuc2NvcGUpLCBzc21QYXRoKTtcbiAgfVxuXG4gIHByaXZhdGUgcGFyc2VDb250ZXh0KHJlZklubmVyOiBzdHJpbmcpIHtcbiAgICBjb25zdCByZWZJbm5lckNvbnRleHQgPSByZWZJbm5lci5yZXBsYWNlKC9eY29udGV4dDovLCAnJyk7XG4gICAgY29uc3Qgc2NvcGVDb250ZXh0VmFsdWUgPSB0aGlzLnByb3BzLnNjb3BlPy5ub2RlLnRyeUdldENvbnRleHQocmVmSW5uZXJDb250ZXh0KTtcbiAgICBjb25zdCBzY29wZUlubmVyQ29udGV4dFZhbHVlID0gdGhpcy5wcm9wcy5jb250ZXh0ID8gdGhpcy5wcm9wcy5jb250ZXh0W3JlZklubmVyQ29udGV4dF0gOiB1bmRlZmluZWQ7XG4gICAgY29uc3QgY29udGV4dFZhbHVlID0gc2NvcGVDb250ZXh0VmFsdWUgPz8gc2NvcGVJbm5lckNvbnRleHRWYWx1ZTtcbiAgICBpZiAoIWNvbnRleHRWYWx1ZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBGYWlsZWQgdG8gcmVzb2x2ZSBjb250ZXh0OiAke3JlZklubmVyQ29udGV4dH1gKTtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBjb250ZXh0VmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgICAvLyBDaGVjayBpZiB0aGUgdmFsdWUgaXMgZW5jb2RlZCB3aXRoIHF1b3RlcyAoZnJvbSBDTEkgZW5jb2RpbmcpXG4gICAgICBpZiAoY29udGV4dFZhbHVlLnN0YXJ0c1dpdGgoJ1wiJykgJiYgY29udGV4dFZhbHVlLmVuZHNXaXRoKCdcIicpKSB7XG4gICAgICAgIC8vIFJlbW92ZSBvdXRlciBxdW90ZXNcbiAgICAgICAgY29uc3QgdW5xdW90ZWQgPSBjb250ZXh0VmFsdWUuc2xpY2UoMSwgLTEpO1xuXG4gICAgICAgIGlmICh1bnF1b3RlZC5zdGFydHNXaXRoKCdvYmo6JykpIHtcbiAgICAgICAgICAvLyBQYXJzZSBvYmplY3Q6IFwib2JqOnsuLi59XCIgLT4gey4uLn1cbiAgICAgICAgICByZXR1cm4gSlNPTi5wYXJzZSh1bnF1b3RlZC5yZXBsYWNlKC9eb2JqOi8sICcnKSkgYXMgQ29uZmlndXJhdGlvbkVsZW1lbnQ7XG4gICAgICAgIH0gZWxzZSBpZiAodW5xdW90ZWQuc3RhcnRzV2l0aCgnbGlzdDonKSkge1xuICAgICAgICAgIC8vIFBhcnNlIGFycmF5OiBcImxpc3Q6Wy4uLl1cIiAtPiBbLi4uXVxuICAgICAgICAgIHJldHVybiBKU09OLnBhcnNlKHVucXVvdGVkLnJlcGxhY2UoL15saXN0Oi8sICcnKSkgYXMgdW5rbm93bltdO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBjb250ZXh0VmFsdWU7XG4gIH1cbn1cbiJdfQ==