@aws-cdk/toolkit-lib 1.23.0 → 1.25.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 (92) hide show
  1. package/build-info.json +2 -2
  2. package/db.json.gz +0 -0
  3. package/lib/actions/deploy/index.d.ts +15 -1
  4. package/lib/actions/deploy/index.js +1 -1
  5. package/lib/actions/deploy/private/deployment-method.d.ts +5 -9
  6. package/lib/actions/deploy/private/deployment-method.js +8 -1
  7. package/lib/actions/diagnose/index.d.ts +89 -0
  8. package/lib/actions/diagnose/index.js +3 -0
  9. package/lib/actions/diff/private/helpers.js +12 -15
  10. package/lib/actions/index.d.ts +2 -0
  11. package/lib/actions/index.js +3 -1
  12. package/lib/actions/orphan/index.d.ts +18 -0
  13. package/lib/actions/orphan/index.js +3 -0
  14. package/lib/api/aws-auth/sdk.d.ts +2 -1
  15. package/lib/api/aws-auth/sdk.js +2 -1
  16. package/lib/api/bootstrap/bootstrap-environment.js +4 -4
  17. package/lib/api/bootstrap/bootstrap-template.yaml +5 -16
  18. package/lib/api/bootstrap/deploy-bootstrap.js +9 -1
  19. package/lib/api/cloud-assembly/stack-selector.d.ts +1 -1
  20. package/lib/api/cloud-assembly/stack-selector.js +1 -1
  21. package/lib/api/cloudformation/index.d.ts +1 -0
  22. package/lib/api/cloudformation/index.js +2 -1
  23. package/lib/api/cloudformation/logical-id-map.d.ts +24 -0
  24. package/lib/api/cloudformation/logical-id-map.js +45 -0
  25. package/lib/api/cloudformation/stack-helpers.d.ts +6 -0
  26. package/lib/api/cloudformation/stack-helpers.js +12 -1
  27. package/lib/api/deployments/cfn-api.d.ts +9 -17
  28. package/lib/api/deployments/cfn-api.js +82 -71
  29. package/lib/api/deployments/deploy-stack.d.ts +6 -2
  30. package/lib/api/deployments/deploy-stack.js +43 -60
  31. package/lib/api/deployments/deployments.d.ts +3 -2
  32. package/lib/api/deployments/deployments.js +31 -7
  33. package/lib/api/diagnosing/diagnosis-formatting.d.ts +13 -0
  34. package/lib/api/diagnosing/diagnosis-formatting.js +139 -0
  35. package/lib/api/diagnosing/early-validation.d.ts +49 -0
  36. package/lib/api/diagnosing/early-validation.js +81 -0
  37. package/lib/api/diagnosing/stack-diagnoser.d.ts +99 -0
  38. package/lib/api/diagnosing/stack-diagnoser.js +338 -0
  39. package/lib/api/diagnosing/tree-builder.d.ts +12 -0
  40. package/lib/api/diagnosing/tree-builder.js +86 -0
  41. package/lib/api/diagnosing/tree.d.ts +13 -0
  42. package/lib/api/diagnosing/tree.js +61 -0
  43. package/lib/api/diff/diff-formatter.js +8 -12
  44. package/lib/api/drift/drift-formatter.d.ts +0 -1
  45. package/lib/api/drift/drift-formatter.js +3 -10
  46. package/lib/api/hotswap/hotswap-deployments.js +14 -2
  47. package/lib/api/hotswap/hotswap-template-cache.d.ts +19 -0
  48. package/lib/api/hotswap/hotswap-template-cache.js +96 -0
  49. package/lib/api/index.d.ts +1 -0
  50. package/lib/api/index.js +2 -1
  51. package/lib/api/io/private/messages.d.ts +5 -0
  52. package/lib/api/io/private/messages.js +23 -1
  53. package/lib/api/io/toolkit-action.d.ts +1 -1
  54. package/lib/api/io/toolkit-action.js +1 -1
  55. package/lib/api/orphan/orphaner.d.ts +75 -0
  56. package/lib/api/orphan/orphaner.js +246 -0
  57. package/lib/api/orphan/private/helpers.d.ts +56 -0
  58. package/lib/api/orphan/private/helpers.js +219 -0
  59. package/lib/api/orphan/private/index.d.ts +2 -0
  60. package/lib/api/orphan/private/index.js +18 -0
  61. package/lib/api/resource-import/importer.d.ts +8 -1
  62. package/lib/api/resource-import/importer.js +35 -14
  63. package/lib/api/settings.d.ts +3 -1
  64. package/lib/api/settings.js +16 -3
  65. package/lib/api/source-tracing/index.d.ts +2 -0
  66. package/lib/api/source-tracing/index.js +18 -0
  67. package/lib/api/source-tracing/private/source-tracing.d.ts +16 -0
  68. package/lib/api/source-tracing/private/source-tracing.js +8 -0
  69. package/lib/api/source-tracing/private/stack-source-tracing.d.ts +32 -0
  70. package/lib/api/source-tracing/private/stack-source-tracing.js +134 -0
  71. package/lib/api/source-tracing/types.d.ts +9 -0
  72. package/lib/api/source-tracing/types.js +3 -0
  73. package/lib/api/stack-events/resource-errors.d.ts +82 -0
  74. package/lib/api/stack-events/resource-errors.js +129 -0
  75. package/lib/api/stack-events/stack-activity-monitor.d.ts +2 -29
  76. package/lib/api/stack-events/stack-activity-monitor.js +5 -94
  77. package/lib/api/stack-events/stack-event-poller.d.ts +71 -8
  78. package/lib/api/stack-events/stack-event-poller.js +107 -13
  79. package/lib/api/work-graph/work-graph.d.ts +4 -0
  80. package/lib/api/work-graph/work-graph.js +6 -1
  81. package/lib/index.d.ts +1 -0
  82. package/lib/index.js +2 -1
  83. package/lib/index_bg.wasm +0 -0
  84. package/lib/toolkit/toolkit.d.ts +17 -1
  85. package/lib/toolkit/toolkit.js +226 -84
  86. package/lib/util/arrays.d.ts +1 -0
  87. package/lib/util/arrays.js +23 -1
  88. package/lib/util/type-brands.d.ts +1 -1
  89. package/lib/util/type-brands.js +1 -1
  90. package/package.json +11 -11
  91. package/lib/api/deployments/early-validation.d.ts +0 -17
  92. package/lib/api/deployments/early-validation.js +0 -54
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EarlyValidationReporter = void 0;
4
+ /**
5
+ * A ValidationReporter that checks for early validation errors right after
6
+ * creating the change set.
7
+ */
8
+ class EarlyValidationReporter {
9
+ sdk;
10
+ envResources;
11
+ constructor(sdk, envResources) {
12
+ this.sdk = sdk;
13
+ this.envResources = envResources;
14
+ }
15
+ /**
16
+ * Fetch the details and return them as a string.
17
+ *
18
+ * If the details could not be fetched, log that as a warning using the IoHelper.
19
+ */
20
+ async fetchDetailsString(changeSetName, stackName, ioHelper) {
21
+ const summary = `Early validation failed for stack '${stackName}' (ChangeSet '${changeSetName}')`;
22
+ const result = await this.fetchDetailsStructured(changeSetName, stackName);
23
+ switch (result.type) {
24
+ case 'could-not-check':
25
+ await ioHelper.defaults.warn(result.message);
26
+ return summary;
27
+ case 'resource-errors':
28
+ if (result.errors.length === 0) {
29
+ return summary;
30
+ }
31
+ return [
32
+ `${summary}:`,
33
+ ...result.errors.map(e => ` - ${e.message} (at ${e.documentPath})`),
34
+ ].join('\n');
35
+ }
36
+ }
37
+ /**
38
+ * Fetch the details and return them in structured form.
39
+ */
40
+ async fetchDetailsStructured(changeSetName, stackName) {
41
+ let operationEvents = [];
42
+ try {
43
+ operationEvents = await this.getFailedEvents(stackName, changeSetName);
44
+ }
45
+ catch (error) {
46
+ let currentVersion = undefined;
47
+ try {
48
+ currentVersion = (await this.envResources?.lookupToolkit())?.version;
49
+ }
50
+ catch (e) {
51
+ }
52
+ return {
53
+ type: 'could-not-check',
54
+ message: `Could not retrieve additional details about early validation errors (${error}). Make sure you have permissions to call the DescribeEvents API, or re-bootstrap your environment by running 'cdk bootstrap' to update the Bootstrap CDK Toolkit stack. Bootstrap toolkit stack version 30 or later is needed; current version: ${currentVersion ?? 'unknown'}.`,
55
+ };
56
+ }
57
+ return {
58
+ type: 'resource-errors',
59
+ errors: operationEvents.map((ev) => ({
60
+ eventType: ev.EventType ?? '',
61
+ logicalId: ev.LogicalResourceId ?? '',
62
+ message: ev.ValidationStatusReason ?? '',
63
+ physicalId: ev.PhysicalResourceId ? ev.PhysicalResourceId : undefined,
64
+ validationName: ev.ValidationName ?? '',
65
+ documentPath: ev.ValidationPath ?? '',
66
+ resourceType: ev.ResourceType,
67
+ })),
68
+ };
69
+ }
70
+ async getFailedEvents(stackName, changeSetName) {
71
+ return this.sdk.cloudFormation().paginatedDescribeEvents({
72
+ StackName: stackName,
73
+ ChangeSetName: changeSetName,
74
+ Filters: {
75
+ FailedEvents: true,
76
+ },
77
+ });
78
+ }
79
+ }
80
+ exports.EarlyValidationReporter = EarlyValidationReporter;
81
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWFybHktdmFsaWRhdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImVhcmx5LXZhbGlkYXRpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBS0E7OztHQUdHO0FBQ0gsTUFBYSx1QkFBdUI7SUFDTDtJQUEyQjtJQUF4RCxZQUE2QixHQUFRLEVBQW1CLFlBQW1DO1FBQTlELFFBQUcsR0FBSCxHQUFHLENBQUs7UUFBbUIsaUJBQVksR0FBWixZQUFZLENBQXVCO0lBQzNGLENBQUM7SUFFRDs7OztPQUlHO0lBQ0ksS0FBSyxDQUFDLGtCQUFrQixDQUFDLGFBQXFCLEVBQUUsU0FBaUIsRUFBRSxRQUFrQjtRQUMxRixNQUFNLE9BQU8sR0FBRyxzQ0FBc0MsU0FBUyxpQkFBaUIsYUFBYSxJQUFJLENBQUM7UUFDbEcsTUFBTSxNQUFNLEdBQUcsTUFBTSxJQUFJLENBQUMsc0JBQXNCLENBQUMsYUFBYSxFQUFFLFNBQVMsQ0FBQyxDQUFDO1FBRTNFLFFBQVEsTUFBTSxDQUFDLElBQUksRUFBRSxDQUFDO1lBQ3BCLEtBQUssaUJBQWlCO2dCQUNwQixNQUFNLFFBQVEsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQztnQkFDN0MsT0FBTyxPQUFPLENBQUM7WUFFakIsS0FBSyxpQkFBaUI7Z0JBQ3BCLElBQUksTUFBTSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLENBQUM7b0JBQy9CLE9BQU8sT0FBTyxDQUFDO2dCQUNqQixDQUFDO2dCQUNELE9BQU87b0JBQ0wsR0FBRyxPQUFPLEdBQUc7b0JBQ2IsR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLE9BQU8sQ0FBQyxDQUFDLE9BQU8sUUFBUSxDQUFDLENBQUMsWUFBWSxHQUFHLENBQUM7aUJBQ3JFLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ2pCLENBQUM7SUFDSCxDQUFDO0lBRUQ7O09BRUc7SUFDSSxLQUFLLENBQUMsc0JBQXNCLENBQUMsYUFBcUIsRUFBRSxTQUFpQjtRQUMxRSxJQUFJLGVBQWUsR0FBcUIsRUFBRSxDQUFDO1FBQzNDLElBQUksQ0FBQztZQUNILGVBQWUsR0FBRyxNQUFNLElBQUksQ0FBQyxlQUFlLENBQUMsU0FBUyxFQUFFLGFBQWEsQ0FBQyxDQUFDO1FBQ3pFLENBQUM7UUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1lBQ2YsSUFBSSxjQUFjLEdBQXVCLFNBQVMsQ0FBQztZQUNuRCxJQUFJLENBQUM7Z0JBQ0gsY0FBYyxHQUFHLENBQUMsTUFBTSxJQUFJLENBQUMsWUFBWSxFQUFFLGFBQWEsRUFBRSxDQUFDLEVBQUUsT0FBTyxDQUFDO1lBQ3ZFLENBQUM7WUFBQyxPQUFPLENBQUMsRUFBRSxDQUFDO1lBQ2IsQ0FBQztZQUVELE9BQU87Z0JBQ0wsSUFBSSxFQUFFLGlCQUFpQjtnQkFDdkIsT0FBTyxFQUFFLHdFQUF3RSxLQUFLLG9QQUFvUCxjQUFjLElBQUksU0FBUyxHQUFHO2FBQ3pXLENBQUM7UUFDSixDQUFDO1FBRUQsT0FBTztZQUNMLElBQUksRUFBRSxpQkFBaUI7WUFDdkIsTUFBTSxFQUFFLGVBQWUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUM7Z0JBQ25DLFNBQVMsRUFBRSxFQUFFLENBQUMsU0FBUyxJQUFJLEVBQUU7Z0JBQzdCLFNBQVMsRUFBRSxFQUFFLENBQUMsaUJBQWlCLElBQUksRUFBRTtnQkFDckMsT0FBTyxFQUFFLEVBQUUsQ0FBQyxzQkFBc0IsSUFBSSxFQUFFO2dCQUN4QyxVQUFVLEVBQUUsRUFBRSxDQUFDLGtCQUFrQixDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsa0JBQWtCLENBQUMsQ0FBQyxDQUFDLFNBQVM7Z0JBQ3JFLGNBQWMsRUFBRSxFQUFFLENBQUMsY0FBYyxJQUFJLEVBQUU7Z0JBQ3ZDLFlBQVksRUFBRSxFQUFFLENBQUMsY0FBYyxJQUFJLEVBQUU7Z0JBQ3JDLFlBQVksRUFBRSxFQUFFLENBQUMsWUFBWTthQUNFLENBQUEsQ0FBQztTQUNuQyxDQUFDO0lBQ0osQ0FBQztJQUVPLEtBQUssQ0FBQyxlQUFlLENBQUMsU0FBaUIsRUFBRSxhQUFxQjtRQUNwRSxPQUFPLElBQUksQ0FBQyxHQUFHLENBQUMsY0FBYyxFQUFFLENBQUMsdUJBQXVCLENBQUM7WUFDdkQsU0FBUyxFQUFFLFNBQVM7WUFDcEIsYUFBYSxFQUFFLGFBQWE7WUFDNUIsT0FBTyxFQUFFO2dCQUNQLFlBQVksRUFBRSxJQUFJO2FBQ25CO1NBQ0YsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztDQUNGO0FBeEVELDBEQXdFQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0eXBlIHsgT3BlcmF0aW9uRXZlbnQgfSBmcm9tICdAYXdzLXNkay9jbGllbnQtY2xvdWRmb3JtYXRpb24nO1xuaW1wb3J0IHR5cGUgeyBTREsgfSBmcm9tICcuLi9hd3MtYXV0aC9zZGsnO1xuaW1wb3J0IHR5cGUgeyBFbnZpcm9ubWVudFJlc291cmNlcyB9IGZyb20gJy4uL2Vudmlyb25tZW50JztcbmltcG9ydCB0eXBlIHsgSW9IZWxwZXIgfSBmcm9tICcuLi9pby9wcml2YXRlL2lvLWhlbHBlcic7XG5cbi8qKlxuICogQSBWYWxpZGF0aW9uUmVwb3J0ZXIgdGhhdCBjaGVja3MgZm9yIGVhcmx5IHZhbGlkYXRpb24gZXJyb3JzIHJpZ2h0IGFmdGVyXG4gKiBjcmVhdGluZyB0aGUgY2hhbmdlIHNldC5cbiAqL1xuZXhwb3J0IGNsYXNzIEVhcmx5VmFsaWRhdGlvblJlcG9ydGVyIHtcbiAgY29uc3RydWN0b3IocHJpdmF0ZSByZWFkb25seSBzZGs6IFNESywgcHJpdmF0ZSByZWFkb25seSBlbnZSZXNvdXJjZXM/OiBFbnZpcm9ubWVudFJlc291cmNlcykge1xuICB9XG5cbiAgLyoqXG4gICAqIEZldGNoIHRoZSBkZXRhaWxzIGFuZCByZXR1cm4gdGhlbSBhcyBhIHN0cmluZy5cbiAgICpcbiAgICogSWYgdGhlIGRldGFpbHMgY291bGQgbm90IGJlIGZldGNoZWQsIGxvZyB0aGF0IGFzIGEgd2FybmluZyB1c2luZyB0aGUgSW9IZWxwZXIuXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgZmV0Y2hEZXRhaWxzU3RyaW5nKGNoYW5nZVNldE5hbWU6IHN0cmluZywgc3RhY2tOYW1lOiBzdHJpbmcsIGlvSGVscGVyOiBJb0hlbHBlcik6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgY29uc3Qgc3VtbWFyeSA9IGBFYXJseSB2YWxpZGF0aW9uIGZhaWxlZCBmb3Igc3RhY2sgJyR7c3RhY2tOYW1lfScgKENoYW5nZVNldCAnJHtjaGFuZ2VTZXROYW1lfScpYDtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0aGlzLmZldGNoRGV0YWlsc1N0cnVjdHVyZWQoY2hhbmdlU2V0TmFtZSwgc3RhY2tOYW1lKTtcblxuICAgIHN3aXRjaCAocmVzdWx0LnR5cGUpIHtcbiAgICAgIGNhc2UgJ2NvdWxkLW5vdC1jaGVjayc6XG4gICAgICAgIGF3YWl0IGlvSGVscGVyLmRlZmF1bHRzLndhcm4ocmVzdWx0Lm1lc3NhZ2UpO1xuICAgICAgICByZXR1cm4gc3VtbWFyeTtcblxuICAgICAgY2FzZSAncmVzb3VyY2UtZXJyb3JzJzpcbiAgICAgICAgaWYgKHJlc3VsdC5lcnJvcnMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgcmV0dXJuIHN1bW1hcnk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFtcbiAgICAgICAgICBgJHtzdW1tYXJ5fTpgLFxuICAgICAgICAgIC4uLnJlc3VsdC5lcnJvcnMubWFwKGUgPT4gYCAgLSAke2UubWVzc2FnZX0gKGF0ICR7ZS5kb2N1bWVudFBhdGh9KWApLFxuICAgICAgICBdLmpvaW4oJ1xcbicpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBGZXRjaCB0aGUgZGV0YWlscyBhbmQgcmV0dXJuIHRoZW0gaW4gc3RydWN0dXJlZCBmb3JtLlxuICAgKi9cbiAgcHVibGljIGFzeW5jIGZldGNoRGV0YWlsc1N0cnVjdHVyZWQoY2hhbmdlU2V0TmFtZTogc3RyaW5nLCBzdGFja05hbWU6IHN0cmluZyk6IFByb21pc2U8RWFybHlWYWxpZGF0aW9uQ2hlY2tSZXN1bHQ+IHtcbiAgICBsZXQgb3BlcmF0aW9uRXZlbnRzOiBPcGVyYXRpb25FdmVudFtdID0gW107XG4gICAgdHJ5IHtcbiAgICAgIG9wZXJhdGlvbkV2ZW50cyA9IGF3YWl0IHRoaXMuZ2V0RmFpbGVkRXZlbnRzKHN0YWNrTmFtZSwgY2hhbmdlU2V0TmFtZSk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGxldCBjdXJyZW50VmVyc2lvbjogbnVtYmVyIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuICAgICAgdHJ5IHtcbiAgICAgICAgY3VycmVudFZlcnNpb24gPSAoYXdhaXQgdGhpcy5lbnZSZXNvdXJjZXM/Lmxvb2t1cFRvb2xraXQoKSk/LnZlcnNpb247XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIHR5cGU6ICdjb3VsZC1ub3QtY2hlY2snLFxuICAgICAgICBtZXNzYWdlOiBgQ291bGQgbm90IHJldHJpZXZlIGFkZGl0aW9uYWwgZGV0YWlscyBhYm91dCBlYXJseSB2YWxpZGF0aW9uIGVycm9ycyAoJHtlcnJvcn0pLiBNYWtlIHN1cmUgeW91IGhhdmUgcGVybWlzc2lvbnMgdG8gY2FsbCB0aGUgRGVzY3JpYmVFdmVudHMgQVBJLCBvciByZS1ib290c3RyYXAgeW91ciBlbnZpcm9ubWVudCBieSBydW5uaW5nICdjZGsgYm9vdHN0cmFwJyB0byB1cGRhdGUgdGhlIEJvb3RzdHJhcCBDREsgVG9vbGtpdCBzdGFjay4gQm9vdHN0cmFwIHRvb2xraXQgc3RhY2sgdmVyc2lvbiAzMCBvciBsYXRlciBpcyBuZWVkZWQ7IGN1cnJlbnQgdmVyc2lvbjogJHtjdXJyZW50VmVyc2lvbiA/PyAndW5rbm93bid9LmAsXG4gICAgICB9O1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICB0eXBlOiAncmVzb3VyY2UtZXJyb3JzJyxcbiAgICAgIGVycm9yczogb3BlcmF0aW9uRXZlbnRzLm1hcCgoZXYpID0+ICh7XG4gICAgICAgIGV2ZW50VHlwZTogZXYuRXZlbnRUeXBlID8/ICcnLFxuICAgICAgICBsb2dpY2FsSWQ6IGV2LkxvZ2ljYWxSZXNvdXJjZUlkID8/ICcnLFxuICAgICAgICBtZXNzYWdlOiBldi5WYWxpZGF0aW9uU3RhdHVzUmVhc29uID8/ICcnLFxuICAgICAgICBwaHlzaWNhbElkOiBldi5QaHlzaWNhbFJlc291cmNlSWQgPyBldi5QaHlzaWNhbFJlc291cmNlSWQgOiB1bmRlZmluZWQsXG4gICAgICAgIHZhbGlkYXRpb25OYW1lOiBldi5WYWxpZGF0aW9uTmFtZSA/PyAnJyxcbiAgICAgICAgZG9jdW1lbnRQYXRoOiBldi5WYWxpZGF0aW9uUGF0aCA/PyAnJyxcbiAgICAgICAgcmVzb3VyY2VUeXBlOiBldi5SZXNvdXJjZVR5cGUsXG4gICAgICB9IHNhdGlzZmllcyBFYXJseVZhbGlkYXRpb25FcnJvcikpLFxuICAgIH07XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGdldEZhaWxlZEV2ZW50cyhzdGFja05hbWU6IHN0cmluZywgY2hhbmdlU2V0TmFtZTogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMuc2RrLmNsb3VkRm9ybWF0aW9uKCkucGFnaW5hdGVkRGVzY3JpYmVFdmVudHMoe1xuICAgICAgU3RhY2tOYW1lOiBzdGFja05hbWUsXG4gICAgICBDaGFuZ2VTZXROYW1lOiBjaGFuZ2VTZXROYW1lLFxuICAgICAgRmlsdGVyczoge1xuICAgICAgICBGYWlsZWRFdmVudHM6IHRydWUsXG4gICAgICB9LFxuICAgIH0pO1xuICB9XG59XG5cbmV4cG9ydCB0eXBlIEVhcmx5VmFsaWRhdGlvbkNoZWNrUmVzdWx0ID1cbiAgfCB7IHR5cGU6ICdjb3VsZC1ub3QtY2hlY2snOyBtZXNzYWdlOiBzdHJpbmcgfVxuICB8IHsgdHlwZTogJ3Jlc291cmNlLWVycm9ycyc7IGVycm9yczogRWFybHlWYWxpZGF0aW9uRXJyb3JbXSB9O1xuXG5leHBvcnQgaW50ZXJmYWNlIEVhcmx5VmFsaWRhdGlvbkVycm9yIHtcbiAgcmVhZG9ubHkgbG9naWNhbElkOiBzdHJpbmc7XG4gIHJlYWRvbmx5IHBoeXNpY2FsSWQ/OiBzdHJpbmc7XG4gIHJlYWRvbmx5IG1lc3NhZ2U6IHN0cmluZztcblxuICByZWFkb25seSByZXNvdXJjZVR5cGU/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEV4YW1wbGU6IGBWQUxJREFUSU9OX0VSUk9SYFxuICAgKi9cbiAgcmVhZG9ubHkgZXZlbnRUeXBlOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEV4YW1wbGU6IGBOQU1FX0NPTkZMSUNUX1ZBTElEQVRJT05gXG4gICAqL1xuICByZWFkb25seSB2YWxpZGF0aW9uTmFtZTogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBFeGFtcGxlOiBgL1Jlc291cmNlcy9Tb21lQnVja2V0RDVCNzA3MDRgXG4gICAqL1xuICByZWFkb25seSBkb2N1bWVudFBhdGg6IHN0cmluZztcbn1cbiJdfQ==
@@ -0,0 +1,99 @@
1
+ import type { ChangeSetSummary, Stack } from '@aws-sdk/client-cloudformation';
2
+ import type { StackDiagnosis } from '../../actions/diagnose';
3
+ import type { SDK } from '../aws-auth/sdk';
4
+ import type { EnvironmentResources } from '../environment';
5
+ import type { IoHelper } from '../io/private/io-helper';
6
+ import type { ISourceTracer } from '../source-tracing/private/source-tracing';
7
+ import type { ResourceErrors } from '../stack-events/resource-errors';
8
+ export interface CloudFormationStackDiagnoserProps {
9
+ readonly sdk: SDK;
10
+ readonly envResources?: EnvironmentResources;
11
+ readonly sourceTracer: ISourceTracer;
12
+ readonly ioHelper: IoHelper;
13
+ readonly topLevelStackHierarchicalId: string;
14
+ }
15
+ /**
16
+ * Diagnose a stack's failed state
17
+ *
18
+ * - First, determine the stack's state.
19
+ * - If it is in a failed state, we started a deployment that failed. Describe the stack
20
+ * events, and try to determine the root cause from that.
21
+ * - If it is in a normal state, see if there are any failed change sets. Either
22
+ * get the failure message from the change set, or get the failure events from
23
+ * the change set (early validation).
24
+ *
25
+ * This class works at the CloudFormation level, and does not deal with tracing
26
+ * CloudFormation errors to construct code sources yet.
27
+ */
28
+ export declare class CloudFormationStackDiagnoser {
29
+ private readonly props;
30
+ private readonly cfn;
31
+ private parentStackLogicalIds;
32
+ constructor(props: CloudFormationStackDiagnoserProps);
33
+ /**
34
+ * Diagnose a stack's root cause given no pre-existing state
35
+ */
36
+ diagnoseFromFresh(stackName: string): Promise<StackDiagnosis>;
37
+ /**
38
+ * Diagnose potential problems with the change set
39
+ */
40
+ diagnoseChangeSet(changeSet: ChangeSetSummary): Promise<StackDiagnosis>;
41
+ /**
42
+ * Diagnose potential problems with the change set
43
+ */
44
+ diagnoseFromErrorCollection(errors: ResourceErrors, stack: Stack): Promise<StackDiagnosis>;
45
+ /**
46
+ * Diagnose a deployment failure via stack events
47
+ *
48
+ * This is the same logic that the deployment monitor uses.
49
+ */
50
+ private _diagnoseViaStackEvents;
51
+ private _diagnoseChangeSetFailureFromStackName;
52
+ /**
53
+ * Try to diagnose the reason that caused a changeset to fail to create
54
+ *
55
+ * There are a couple of different reasons this can happen, and we go through each of them in order.
56
+ *
57
+ * Usually this starts from trying to detect an error message pattern in the change set status reason,
58
+ * and then potentially going to fetch additional information using additional API calls.
59
+ */
60
+ private _diagnoseChangeSetFailure;
61
+ private addErrorTraces;
62
+ private addErrorTrace;
63
+ /**
64
+ * Build a generic stack error from the given change set information
65
+ *
66
+ * We can't point to a specific resource.
67
+ */
68
+ private _nonSpecificChangeSetError;
69
+ /**
70
+ * Look for nested change sets that have failed, and diagnose those.
71
+ */
72
+ private _diagnoseNestedChangeSetFailure;
73
+ private _findFailedNestedStack;
74
+ /**
75
+ * Try to parse failed auto-imports out from a change set status
76
+ *
77
+ * The pattern looks like this:
78
+ *
79
+ * ```
80
+ * CloudFormation is attempting to import some resources because they already exist in your account. The resources must have the DeletionPolicy attribute set to 'Retain' or 'RetainExceptOnCreate' in the template for successful import. The affected resources are SomeBucketD5B70704 ({BucketName=zomaareenbucket})
81
+ * ```
82
+ *
83
+ * Followed by
84
+ *
85
+ * ```
86
+ * LogicalID ({Prop=Value,Prop=Value}), LogicalID ({Prop=Value}), ...
87
+ * ```
88
+ */
89
+ private _tryDetectFailedAutoImport;
90
+ }
91
+ /**
92
+ * Return true if the given change set has no changes
93
+ *
94
+ * This must be determined from the status, not the 'Changes' array on the
95
+ * object; the latter can be empty because no resources were changed, but if
96
+ * there are changes to Outputs, the change set can still be executed.
97
+ */
98
+ export declare function changeSetHasNoChanges(description: ChangeSetSummary): boolean;
99
+ //# sourceMappingURL=stack-diagnoser.d.ts.map
@@ -0,0 +1,338 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CloudFormationStackDiagnoser = void 0;
4
+ exports.changeSetHasNoChanges = changeSetHasNoChanges;
5
+ const client_cloudformation_1 = require("@aws-sdk/client-cloudformation");
6
+ const early_validation_1 = require("./early-validation");
7
+ const stack_events_1 = require("../stack-events");
8
+ const stack_status_1 = require("../stack-events/stack-status");
9
+ /**
10
+ * Diagnose a stack's failed state
11
+ *
12
+ * - First, determine the stack's state.
13
+ * - If it is in a failed state, we started a deployment that failed. Describe the stack
14
+ * events, and try to determine the root cause from that.
15
+ * - If it is in a normal state, see if there are any failed change sets. Either
16
+ * get the failure message from the change set, or get the failure events from
17
+ * the change set (early validation).
18
+ *
19
+ * This class works at the CloudFormation level, and does not deal with tracing
20
+ * CloudFormation errors to construct code sources yet.
21
+ */
22
+ class CloudFormationStackDiagnoser {
23
+ props;
24
+ cfn;
25
+ parentStackLogicalIds;
26
+ constructor(props) {
27
+ this.props = props;
28
+ this.cfn = this.props.sdk.cloudFormation();
29
+ this.parentStackLogicalIds = [];
30
+ }
31
+ /**
32
+ * Diagnose a stack's root cause given no pre-existing state
33
+ */
34
+ async diagnoseFromFresh(stackName) {
35
+ try {
36
+ const response = await this.cfn.describeStacks({ StackName: stackName });
37
+ const stack = response.Stacks?.[0];
38
+ if (!stack) {
39
+ return {
40
+ type: 'error-diagnosing',
41
+ message: `Stack with name ${stackName} not found`,
42
+ };
43
+ }
44
+ const status = stack_status_1.StackStatus.fromStackDescription(stack);
45
+ if (status.isInProgress) {
46
+ return {
47
+ type: 'error-diagnosing',
48
+ message: `Stack with name ${stackName} is currently being updated (${status.name}). Try again when it's finished.`,
49
+ };
50
+ }
51
+ if (status.isFailure) {
52
+ return await this._diagnoseViaStackEvents(stackName, stack);
53
+ }
54
+ return await this._diagnoseChangeSetFailureFromStackName(stackName);
55
+ }
56
+ catch (e) {
57
+ return { type: 'error-diagnosing', message: e.message };
58
+ }
59
+ }
60
+ /**
61
+ * Diagnose potential problems with the change set
62
+ */
63
+ async diagnoseChangeSet(changeSet) {
64
+ try {
65
+ return await this._diagnoseChangeSetFailure(changeSet);
66
+ }
67
+ catch (e) {
68
+ return { type: 'error-diagnosing', message: e.message };
69
+ }
70
+ }
71
+ /**
72
+ * Diagnose potential problems with the change set
73
+ */
74
+ async diagnoseFromErrorCollection(errors, stack) {
75
+ if (errors.isEmpty()) {
76
+ return { type: 'no-problem' };
77
+ }
78
+ return {
79
+ type: 'problem',
80
+ detectedBy: {
81
+ type: 'deployment',
82
+ stackStatus: stack.StackStatus ?? '',
83
+ statusReason: stack.StackStatusReason ?? '',
84
+ },
85
+ problems: await this.addErrorTraces(errors.all),
86
+ };
87
+ }
88
+ /**
89
+ * Diagnose a deployment failure via stack events
90
+ *
91
+ * This is the same logic that the deployment monitor uses.
92
+ */
93
+ async _diagnoseViaStackEvents(stackName, stack) {
94
+ const poller = new stack_events_1.StackEventPoller(this.cfn, {
95
+ stackName,
96
+ initialPollRange: stack_events_1.PollRange.mostRecentOperation(),
97
+ });
98
+ // We don't need the resulting events of polling. Polling will automatically update the error collection,
99
+ // which is the thing we care about.
100
+ await poller.poll();
101
+ return this.diagnoseFromErrorCollection(poller.errors, stack);
102
+ }
103
+ async _diagnoseChangeSetFailureFromStackName(stackName) {
104
+ const cs = (await this.cfn.listChangeSets({
105
+ StackName: stackName,
106
+ })).Summaries ?? [];
107
+ const pending = cs.filter(x => x.Status === client_cloudformation_1.ChangeSetStatus.CREATE_IN_PROGRESS || x.Status === client_cloudformation_1.ChangeSetStatus.CREATE_PENDING);
108
+ if (pending.length > 0) {
109
+ return {
110
+ type: 'error-diagnosing',
111
+ message: `Stack with name ${stackName} has change sets currently being created (${pending[0].ChangeSetName}). Try again when it's finished.`,
112
+ };
113
+ }
114
+ const failed = cs.filter(x => x.Status === client_cloudformation_1.ChangeSetStatus.FAILED);
115
+ if (failed.length === 0) {
116
+ return { type: 'no-problem' };
117
+ }
118
+ return this._diagnoseChangeSetFailure(failed[0]);
119
+ }
120
+ /**
121
+ * Try to diagnose the reason that caused a changeset to fail to create
122
+ *
123
+ * There are a couple of different reasons this can happen, and we go through each of them in order.
124
+ *
125
+ * Usually this starts from trying to detect an error message pattern in the change set status reason,
126
+ * and then potentially going to fetch additional information using additional API calls.
127
+ */
128
+ async _diagnoseChangeSetFailure(changeSet) {
129
+ if (changeSet.Status !== client_cloudformation_1.ChangeSetStatus.FAILED) {
130
+ return { type: 'no-problem' };
131
+ }
132
+ if (changeSetHasNoChanges(changeSet)) {
133
+ // This will lead to a change set that is FAILED but it's not actually a problem
134
+ return { type: 'no-problem' };
135
+ }
136
+ const isEarlyValidationError = changeSet.StatusReason?.includes('AWS::EarlyValidation');
137
+ if (isEarlyValidationError) {
138
+ const ev = await new early_validation_1.EarlyValidationReporter(this.props.sdk, this.props.envResources)
139
+ .fetchDetailsStructured(changeSet.ChangeSetName, changeSet.StackName);
140
+ switch (ev.type) {
141
+ case 'could-not-check':
142
+ // Emit the warning here and otherwise just return an empty error block
143
+ await this.props.ioHelper.defaults.warn(ev.message);
144
+ return {
145
+ type: 'problem',
146
+ detectedBy: {
147
+ type: 'early-validation',
148
+ changeSetName: changeSet.ChangeSetName ?? '',
149
+ },
150
+ problems: [],
151
+ };
152
+ case 'resource-errors':
153
+ return {
154
+ type: 'problem',
155
+ detectedBy: {
156
+ type: 'early-validation',
157
+ changeSetName: changeSet.ChangeSetName ?? '',
158
+ },
159
+ problems: await this.addErrorTraces(ev.errors.map((e) => resourceErrorFromEarlyValidationError(changeSet.StackId ?? '', this.parentStackLogicalIds, e))),
160
+ };
161
+ }
162
+ }
163
+ if (changeSet.StatusReason?.includes('Nested change set')) {
164
+ return this._diagnoseNestedChangeSetFailure(changeSet);
165
+ }
166
+ const failedAutoErrors = this._tryDetectFailedAutoImport(changeSet);
167
+ if (failedAutoErrors) {
168
+ return {
169
+ type: 'problem',
170
+ detectedBy: {
171
+ type: 'change-set',
172
+ changeSetStatus: changeSet.Status ?? '',
173
+ changeSetName: changeSet.ChangeSetName ?? '',
174
+ statusReason: changeSet.StatusReason ?? '',
175
+ },
176
+ problems: await this.addErrorTraces(failedAutoErrors),
177
+ };
178
+ }
179
+ return this._nonSpecificChangeSetError(changeSet);
180
+ }
181
+ async addErrorTraces(errs) {
182
+ // eslint-disable-next-line @cdklabs/promiseall-no-unbounded-parallelism
183
+ return Promise.all(errs.map((e) => this.addErrorTrace(e)));
184
+ }
185
+ async addErrorTrace(err) {
186
+ let sourceTrace;
187
+ if (err.logicalId) {
188
+ sourceTrace = await this.props.sourceTracer.traceResource(err.stackArn, err.parentStackLogicalIds, err.logicalId);
189
+ }
190
+ else {
191
+ sourceTrace = await this.props.sourceTracer.traceStack(err.stackArn, err.parentStackLogicalIds);
192
+ }
193
+ return { ...err, sourceTrace, topLevelStackHierarchicalId: this.props.topLevelStackHierarchicalId };
194
+ }
195
+ /**
196
+ * Build a generic stack error from the given change set information
197
+ *
198
+ * We can't point to a specific resource.
199
+ */
200
+ async _nonSpecificChangeSetError(changeSet) {
201
+ return {
202
+ type: 'problem',
203
+ detectedBy: {
204
+ type: 'change-set',
205
+ changeSetName: changeSet.ChangeSetName ?? '',
206
+ changeSetStatus: changeSet.Status ?? '',
207
+ statusReason: changeSet.StatusReason ?? '',
208
+ },
209
+ problems: [
210
+ await this.addErrorTrace({
211
+ // It's about a stack
212
+ logicalId: undefined,
213
+ message: changeSet.StatusReason ?? '',
214
+ parentStackLogicalIds: this.parentStackLogicalIds,
215
+ stackArn: changeSet.StackId ?? '',
216
+ physicalId: changeSet.StackId,
217
+ resourceType: 'AWS::CloudFormation::Stack',
218
+ }),
219
+ ],
220
+ };
221
+ }
222
+ /**
223
+ * Look for nested change sets that have failed, and diagnose those.
224
+ */
225
+ async _diagnoseNestedChangeSetFailure(changeSet) {
226
+ const nested = await this._findFailedNestedStack(changeSet);
227
+ if (!nested) {
228
+ // That's weird. Let's return the change set's status reason as a non-specific error
229
+ return this._nonSpecificChangeSetError(changeSet);
230
+ }
231
+ const nestedCs = await this.cfn.describeChangeSet({
232
+ ChangeSetName: nested.changeSetName,
233
+ StackName: nested.stackName,
234
+ });
235
+ const nestedDiag = new CloudFormationStackDiagnoser(this.props);
236
+ nestedDiag.parentStackLogicalIds = [...this.parentStackLogicalIds, nested.logicalId];
237
+ return nestedDiag._diagnoseChangeSetFailure(nestedCs);
238
+ }
239
+ async _findFailedNestedStack(changeSet) {
240
+ // The status reason only includes the change set ID, but we also need the stack name. The way to get this is
241
+ // describe the current change set, then from the Changes find the stack whose ChangeSetId is mentioned in the
242
+ // status reason, then look up that change set and recurse into a regular change set diagnosis.
243
+ let nextToken = undefined;
244
+ do {
245
+ // Changes in this response might be paginated
246
+ const resp = await this.cfn.describeChangeSet({
247
+ StackName: changeSet.StackName,
248
+ ChangeSetName: changeSet.ChangeSetName,
249
+ ...nextToken ? { NextToken: nextToken } : {},
250
+ });
251
+ for (const change of resp.Changes ?? []) {
252
+ if (change.Type === client_cloudformation_1.ChangeType.Resource && change.ResourceChange?.ResourceType === 'AWS::CloudFormation::Stack' && change.ResourceChange?.ChangeSetId && changeSet.StatusReason?.includes(change.ResourceChange?.ChangeSetId)) {
253
+ return {
254
+ changeSetName: change.ResourceChange.ChangeSetId,
255
+ stackName: change.ResourceChange.PhysicalResourceId ?? '',
256
+ logicalId: change.ResourceChange.LogicalResourceId ?? '',
257
+ };
258
+ }
259
+ }
260
+ nextToken = resp.NextToken;
261
+ } while (nextToken);
262
+ return undefined;
263
+ }
264
+ /**
265
+ * Try to parse failed auto-imports out from a change set status
266
+ *
267
+ * The pattern looks like this:
268
+ *
269
+ * ```
270
+ * CloudFormation is attempting to import some resources because they already exist in your account. The resources must have the DeletionPolicy attribute set to 'Retain' or 'RetainExceptOnCreate' in the template for successful import. The affected resources are SomeBucketD5B70704 ({BucketName=zomaareenbucket})
271
+ * ```
272
+ *
273
+ * Followed by
274
+ *
275
+ * ```
276
+ * LogicalID ({Prop=Value,Prop=Value}), LogicalID ({Prop=Value}), ...
277
+ * ```
278
+ */
279
+ _tryDetectFailedAutoImport(changeSet) {
280
+ const message = changeSet.StatusReason;
281
+ // Only enhance the specific CFN error about importing existing resources
282
+ if (!message?.includes('CloudFormation is attempting to import some resources because they already exist in your account')) {
283
+ return undefined;
284
+ }
285
+ const marker = 'The affected resources are ';
286
+ const markerIndex = message.indexOf(marker);
287
+ if (markerIndex === -1) {
288
+ return undefined;
289
+ }
290
+ const ret = [];
291
+ let remaining = message.slice(markerIndex + marker.length);
292
+ while (remaining) {
293
+ const endIx = remaining.indexOf('), ');
294
+ const thisResource = endIx > -1 ? remaining.slice(0, endIx + 1) : remaining;
295
+ remaining = remaining.slice(thisResource.length + 2);
296
+ // thisResource = "LogicalId ({Prop=Value, Prop=Value})"
297
+ const openParen = thisResource.indexOf('(');
298
+ const logicalId = openParen > -1 ? thisResource.slice(0, openParen).trim() : undefined;
299
+ ret.push({
300
+ message: `Automatic import of existing resource ${thisResource} needs a DeletionPolicy of \'Retain\' or \'RetainExceptOnCreate\'. Set the removal policy to \'RemovalPolicy.RETAIN\' or \'RemovalPolicy.RETAIN_ON_UPDATE_OR_DELETE\' (See https://docs.aws.amazon.com/cdk/v2/guide/resources.html#resources-removal)`,
301
+ parentStackLogicalIds: this.parentStackLogicalIds,
302
+ stackArn: changeSet.StackId ?? '',
303
+ errorCode: 'AutomaticImportNeedsRetain',
304
+ logicalId,
305
+ });
306
+ }
307
+ return ret;
308
+ }
309
+ }
310
+ exports.CloudFormationStackDiagnoser = CloudFormationStackDiagnoser;
311
+ /**
312
+ * Return true if the given change set has no changes
313
+ *
314
+ * This must be determined from the status, not the 'Changes' array on the
315
+ * object; the latter can be empty because no resources were changed, but if
316
+ * there are changes to Outputs, the change set can still be executed.
317
+ */
318
+ function changeSetHasNoChanges(description) {
319
+ const noChangeErrorPrefixes = [
320
+ // Error message for a regular template
321
+ "The submitted information didn't contain changes.",
322
+ // Error message when a Transform is involved (see #10650)
323
+ 'No updates are to be performed.',
324
+ ];
325
+ return (description.Status === 'FAILED' && noChangeErrorPrefixes.some((p) => (description.StatusReason ?? '').startsWith(p)));
326
+ }
327
+ function resourceErrorFromEarlyValidationError(stackId, parentStackLogicalIds, ev) {
328
+ return {
329
+ logicalId: ev.logicalId,
330
+ physicalId: ev.physicalId,
331
+ resourceType: ev.resourceType,
332
+ message: `${ev.message} (at ${ev.documentPath})`,
333
+ errorCode: `${ev.validationName}_${ev.eventType}`,
334
+ parentStackLogicalIds,
335
+ stackArn: stackId,
336
+ };
337
+ }
338
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhY2stZGlhZ25vc2VyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsic3RhY2stZGlhZ25vc2VyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQThXQSxzREFXQztBQXhYRCwwRUFBNkU7QUFFN0UseURBQTZEO0FBTTdELGtEQUE4RDtBQUU5RCwrREFBMkQ7QUFVM0Q7Ozs7Ozs7Ozs7OztHQVlHO0FBQ0gsTUFBYSw0QkFBNEI7SUFJVjtJQUhaLEdBQUcsQ0FBd0I7SUFDcEMscUJBQXFCLENBQVc7SUFFeEMsWUFBNkIsS0FBd0M7UUFBeEMsVUFBSyxHQUFMLEtBQUssQ0FBbUM7UUFDbkUsSUFBSSxDQUFDLEdBQUcsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxjQUFjLEVBQUUsQ0FBQztRQUMzQyxJQUFJLENBQUMscUJBQXFCLEdBQUcsRUFBRSxDQUFDO0lBQ2xDLENBQUM7SUFFRDs7T0FFRztJQUNJLEtBQUssQ0FBQyxpQkFBaUIsQ0FBQyxTQUFpQjtRQUM5QyxJQUFJLENBQUM7WUFDSCxNQUFNLFFBQVEsR0FBRyxNQUFNLElBQUksQ0FBQyxHQUFHLENBQUMsY0FBYyxDQUFDLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxDQUFDLENBQUM7WUFDekUsTUFBTSxLQUFLLEdBQUcsUUFBUSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ25DLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztnQkFDWCxPQUFPO29CQUNMLElBQUksRUFBRSxrQkFBa0I7b0JBQ3hCLE9BQU8sRUFBRSxtQkFBbUIsU0FBUyxZQUFZO2lCQUNsRCxDQUFDO1lBQ0osQ0FBQztZQUVELE1BQU0sTUFBTSxHQUFHLDBCQUFXLENBQUMsb0JBQW9CLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDdkQsSUFBSSxNQUFNLENBQUMsWUFBWSxFQUFFLENBQUM7Z0JBQ3hCLE9BQU87b0JBQ0wsSUFBSSxFQUFFLGtCQUFrQjtvQkFDeEIsT0FBTyxFQUFF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QUFFLENBQUMsWUFBWSxHQUFHO1FBQ2hELFNBQVMsRUFBRSxHQUFHLEVBQUUsQ0FBQyxjQUFjLElBQUksRUFBRSxDQUFDLFNBQVMsRUFBRTtRQUNqRCxxQkFBcUI7UUFDckIsUUFBUSxFQUFFLE9BQU87S0FDbEIsQ0FBQztBQUNKLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgdHlwZSB7IENoYW5nZVNldFN1bW1hcnksIFN0YWNrIH0gZnJvbSAnQGF3cy1zZGsvY2xpZW50LWNsb3VkZm9ybWF0aW9uJztcbmltcG9ydCB7IENoYW5nZVNldFN0YXR1cywgQ2hhbmdlVHlwZSB9IGZyb20gJ0Bhd3Mtc2RrL2NsaWVudC1jbG91ZGZvcm1hdGlvbic7XG5pbXBvcnQgdHlwZSB7IEVhcmx5VmFsaWRhdGlvbkVycm9yIH0gZnJvbSAnLi9lYXJseS12YWxpZGF0aW9uJztcbmltcG9ydCB7IEVhcmx5VmFsaWRhdGlvblJlcG9ydGVyIH0gZnJvbSAnLi9lYXJseS12YWxpZGF0aW9uJztcbmltcG9ydCB0eXBlIHsgU3RhY2tEaWFnbm9zaXMsIFRyYWNlZFJlc291cmNlRXJyb3IgfSBmcm9tICcuLi8uLi9hY3Rpb25zL2RpYWdub3NlJztcbmltcG9ydCB0eXBlIHsgSUNsb3VkRm9ybWF0aW9uQ2xpZW50LCBTREsgfSBmcm9tICcuLi9hd3MtYXV0aC9zZGsnO1xuaW1wb3J0IHR5cGUgeyBFbnZpcm9ubWVudFJlc291cmNlcyB9IGZyb20gJy4uL2Vudmlyb25tZW50JztcbmltcG9ydCB0eXBlIHsgSW9IZWxwZXIgfSBmcm9tICcuLi9pby9wcml2YXRlL2lvLWhlbHBlcic7XG5pbXBvcnQgdHlwZSB7IElTb3VyY2VUcmFjZXIgfSBmcm9tICcuLi9zb3VyY2UtdHJhY2luZy9wcml2YXRlL3NvdXJjZS10cmFjaW5nJztcbmltcG9ydCB7IFBvbGxSYW5nZSwgU3RhY2tFdmVudFBvbGxlciB9IGZyb20gJy4uL3N0YWNrLWV2ZW50cyc7XG5pbXBvcnQgdHlwZSB7IFJlc291cmNlRXJyb3IsIFJlc291cmNlRXJyb3JzIH0gZnJvbSAnLi4vc3RhY2stZXZlbnRzL3Jlc291cmNlLWVycm9ycyc7XG5pbXBvcnQgeyBTdGFja1N0YXR1cyB9IGZyb20gJy4uL3N0YWNrLWV2ZW50cy9zdGFjay1zdGF0dXMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIENsb3VkRm9ybWF0aW9uU3RhY2tEaWFnbm9zZXJQcm9wcyB7XG4gIHJlYWRvbmx5IHNkazogU0RLO1xuICByZWFkb25seSBlbnZSZXNvdXJjZXM/OiBFbnZpcm9ubWVudFJlc291cmNlcztcbiAgcmVhZG9ubHkgc291cmNlVHJhY2VyOiBJU291cmNlVHJhY2VyO1xuICByZWFkb25seSBpb0hlbHBlcjogSW9IZWxwZXI7XG4gIHJlYWRvbmx5IHRvcExldmVsU3RhY2tIaWVyYXJjaGljYWxJZDogc3RyaW5nO1xufVxuXG4vKipcbiAqIERpYWdub3NlIGEgc3RhY2sncyBmYWlsZWQgc3RhdGVcbiAqXG4gKiAtIEZpcnN0LCBkZXRlcm1pbmUgdGhlIHN0YWNrJ3Mgc3RhdGUuXG4gKiAtIElmIGl0IGlzIGluIGEgZmFpbGVkIHN0YXRlLCB3ZSBzdGFydGVkIGEgZGVwbG95bWVudCB0aGF0IGZhaWxlZC4gRGVzY3JpYmUgdGhlIHN0YWNrXG4gKiAgIGV2ZW50cywgYW5kIHRyeSB0byBkZXRlcm1pbmUgdGhlIHJvb3QgY2F1c2UgZnJvbSB0aGF0LlxuICogLSBJZiBpdCBpcyBpbiBhIG5vcm1hbCBzdGF0ZSwgc2VlIGlmIHRoZXJlIGFyZSBhbnkgZmFpbGVkIGNoYW5nZSBzZXRzLiBFaXRoZXJcbiAqICAgZ2V0IHRoZSBmYWlsdXJlIG1lc3NhZ2UgZnJvbSB0aGUgY2hhbmdlIHNldCwgb3IgZ2V0IHRoZSBmYWlsdXJlIGV2ZW50cyBmcm9tXG4gKiAgIHRoZSBjaGFuZ2Ugc2V0IChlYXJseSB2YWxpZGF0aW9uKS5cbiAqXG4gKiBUaGlzIGNsYXNzIHdvcmtzIGF0IHRoZSBDbG91ZEZvcm1hdGlvbiBsZXZlbCwgYW5kIGRvZXMgbm90IGRlYWwgd2l0aCB0cmFjaW5nXG4gKiBDbG91ZEZvcm1hdGlvbiBlcnJvcnMgdG8gY29uc3RydWN0IGNvZGUgc291cmNlcyB5ZXQuXG4gKi9cbmV4cG9ydCBjbGFzcyBDbG91ZEZvcm1hdGlvblN0YWNrRGlhZ25vc2VyIHtcbiAgcHJpdmF0ZSByZWFkb25seSBjZm46IElDbG91ZEZvcm1hdGlvbkNsaWVudDtcbiAgcHJpdmF0ZSBwYXJlbnRTdGFja0xvZ2ljYWxJZHM6IHN0cmluZ1tdO1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgcmVhZG9ubHkgcHJvcHM6IENsb3VkRm9ybWF0aW9uU3RhY2tEaWFnbm9zZXJQcm9wcykge1xuICAgIHRoaXMuY2ZuID0gdGhpcy5wcm9wcy5zZGsuY2xvdWRGb3JtYXRpb24oKTtcbiAgICB0aGlzLnBhcmVudFN0YWNrTG9naWNhbElkcyA9IFtdO1xuICB9XG5cbiAgLyoqXG4gICAqIERpYWdub3NlIGEgc3RhY2sncyByb290IGNhdXNlIGdpdmVuIG5vIHByZS1leGlzdGluZyBzdGF0ZVxuICAgKi9cbiAgcHVibGljIGFzeW5jIGRpYWdub3NlRnJvbUZyZXNoKHN0YWNrTmFtZTogc3RyaW5nKTogUHJvbWlzZTxTdGFja0RpYWdub3Npcz4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMuY2ZuLmRlc2NyaWJlU3RhY2tzKHsgU3RhY2tOYW1lOiBzdGFja05hbWUgfSk7XG4gICAgICBjb25zdCBzdGFjayA9IHJlc3BvbnNlLlN0YWNrcz8uWzBdO1xuICAgICAgaWYgKCFzdGFjaykge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHR5cGU6ICdlcnJvci1kaWFnbm9zaW5nJyxcbiAgICAgICAgICBtZXNzYWdlOiBgU3RhY2sgd2l0aCBuYW1lICR7c3RhY2tOYW1lfSBub3QgZm91bmRgLFxuICAgICAgICB9O1xuICAgICAgfVxuXG4gICAgICBjb25zdCBzdGF0dXMgPSBTdGFja1N0YXR1cy5mcm9tU3RhY2tEZXNjcmlwdGlvbihzdGFjayk7XG4gICAgICBpZiAoc3RhdHVzLmlzSW5Qcm9ncmVzcykge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHR5cGU6ICdlcnJvci1kaWFnbm9zaW5nJyxcbiAgICAgICAgICBtZXNzYWdlOiBgU3RhY2sgd2l0aCBuYW1lICR7c3RhY2tOYW1lfSBpcyBjdXJyZW50bHkgYmVpbmcgdXBkYXRlZCAoJHtzdGF0dXMubmFtZX0pLiBUcnkgYWdhaW4gd2hlbiBpdCdzIGZpbmlzaGVkLmAsXG4gICAgICAgIH07XG4gICAgICB9XG5cbiAgICAgIGlmIChzdGF0dXMuaXNGYWlsdXJlKSB7XG4gICAgICAgIHJldHVybiBhd2FpdCB0aGlzLl9kaWFnbm9zZVZpYVN0YWNrRXZlbnRzKHN0YWNrTmFtZSwgc3RhY2spO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy5fZGlhZ25vc2VDaGFuZ2VTZXRGYWlsdXJlRnJvbVN0YWNrTmFtZShzdGFja05hbWUpO1xuICAgIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgICAgcmV0dXJuIHsgdHlwZTogJ2Vycm9yLWRpYWdub3NpbmcnLCBtZXNzYWdlOiBlLm1lc3NhZ2UgfTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogRGlhZ25vc2UgcG90ZW50aWFsIHByb2JsZW1zIHdpdGggdGhlIGNoYW5nZSBzZXRcbiAgICovXG4gIHB1YmxpYyBhc3luYyBkaWFnbm9zZUNoYW5nZVNldChjaGFuZ2VTZXQ6IENoYW5nZVNldFN1bW1hcnkpOiBQcm9taXNlPFN0YWNrRGlhZ25vc2lzPiB7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiBhd2FpdCB0aGlzLl9kaWFnbm9zZUNoYW5nZVNldEZhaWx1cmUoY2hhbmdlU2V0KTtcbiAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgIHJldHVybiB7IHR5cGU6ICdlcnJvci1kaWFnbm9zaW5nJywgbWVzc2FnZTogZS5tZXNzYWdlIH07XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIERpYWdub3NlIHBvdGVudGlhbCBwcm9ibGVtcyB3aXRoIHRoZSBjaGFuZ2Ugc2V0XG4gICAqL1xuICBwdWJsaWMgYXN5bmMgZGlhZ25vc2VGcm9tRXJyb3JDb2xsZWN0aW9uKGVycm9yczogUmVzb3VyY2VFcnJvcnMsIHN0YWNrOiBTdGFjayk6IFByb21pc2U8U3RhY2tEaWFnbm9zaXM+IHtcbiAgICBpZiAoZXJyb3JzLmlzRW1wdHkoKSkge1xuICAgICAgcmV0dXJuIHsgdHlwZTogJ25vLXByb2JsZW0nIH07XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIHR5cGU6ICdwcm9ibGVtJyxcbiAgICAgIGRldGVjdGVkQnk6IHtcbiAgICAgICAgdHlwZTogJ2RlcGxveW1lbnQnLFxuICAgICAgICBzdGFja1N0YXR1czogc3RhY2suU3RhY2tTdGF0dXMgPz8gJycsXG4gICAgICAgIHN0YXR1c1JlYXNvbjogc3RhY2suU3RhY2tTdGF0dXNSZWFzb24gPz8gJycsXG4gICAgICB9LFxuICAgICAgcHJvYmxlbXM6IGF3YWl0IHRoaXMuYWRkRXJyb3JUcmFjZXMoZXJyb3JzLmFsbCksXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEaWFnbm9zZSBhIGRlcGxveW1lbnQgZmFpbHVyZSB2aWEgc3RhY2sgZXZlbnRzXG4gICAqXG4gICAqIFRoaXMgaXMgdGhlIHNhbWUgbG9naWMgdGhhdCB0aGUgZGVwbG95bWVudCBtb25pdG9yIHVzZXMuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIF9kaWFnbm9zZVZpYVN0YWNrRXZlbnRzKHN0YWNrTmFtZTogc3RyaW5nLCBzdGFjazogU3RhY2spOiBQcm9taXNlPFN0YWNrRGlhZ25vc2lzPiB7XG4gICAgY29uc3QgcG9sbGVyID0gbmV3IFN0YWNrRXZlbnRQb2xsZXIodGhpcy5jZm4sIHtcbiAgICAgIHN0YWNrTmFtZSxcbiAgICAgIGluaXRpYWxQb2xsUmFuZ2U6IFBvbGxSYW5nZS5tb3N0UmVjZW50T3BlcmF0aW9uKCksXG4gICAgfSk7XG5cbiAgICAvLyBXZSBkb24ndCBuZWVkIHRoZSByZXN1bHRpbmcgZXZlbnRzIG9mIHBvbGxpbmcuIFBvbGxpbmcgd2lsbCBhdXRvbWF0aWNhbGx5IHVwZGF0ZSB0aGUgZXJyb3IgY29sbGVjdGlvbixcbiAgICAvLyB3aGljaCBpcyB0aGUgdGhpbmcgd2UgY2FyZSBhYm91dC5cbiAgICBhd2FpdCBwb2xsZXIucG9sbCgpO1xuXG4gICAgcmV0dXJuIHRoaXMuZGlhZ25vc2VGcm9tRXJyb3JDb2xsZWN0aW9uKHBvbGxlci5lcnJvcnMsIHN0YWNrKTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgX2RpYWdub3NlQ2hhbmdlU2V0RmFpbHVyZUZyb21TdGFja05hbWUoc3RhY2tOYW1lOiBzdHJpbmcpOiBQcm9taXNlPFN0YWNrRGlhZ25vc2lzPiB7XG4gICAgY29uc3QgY3MgPSAoYXdhaXQgdGhpcy5jZm4ubGlzdENoYW5nZVNldHMoe1xuICAgICAgU3RhY2tOYW1lOiBzdGFja05hbWUsXG4gICAgfSkpLlN1bW1hcmllcyA/PyBbXTtcblxuICAgIGNvbnN0IHBlbmRpbmcgPSBjcy5maWx0ZXIoeCA9PiB4LlN0YXR1cyA9PT0gQ2hhbmdlU2V0U3RhdHVzLkNSRUFURV9JTl9QUk9HUkVTUyB8fCB4LlN0YXR1cyA9PT0gQ2hhbmdlU2V0U3RhdHVzLkNSRUFURV9QRU5ESU5HKTtcbiAgICBpZiAocGVuZGluZy5sZW5ndGggPiAwKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB0eXBlOiAnZXJyb3ItZGlhZ25vc2luZycsXG4gICAgICAgIG1lc3NhZ2U6IGBTdGFjayB3aXRoIG5hbWUgJHtzdGFja05hbWV9IGhhcyBjaGFuZ2Ugc2V0cyBjdXJyZW50bHkgYmVpbmcgY3JlYXRlZCAoJHtwZW5kaW5nWzBdLkNoYW5nZVNldE5hbWV9KS4gVHJ5IGFnYWluIHdoZW4gaXQncyBmaW5pc2hlZC5gLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICBjb25zdCBmYWlsZWQgPSBjcy5maWx0ZXIoeCA9PiB4LlN0YXR1cyA9PT0gQ2hhbmdlU2V0U3RhdHVzLkZBSUxFRCk7XG4gICAgaWYgKGZhaWxlZC5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiB7IHR5cGU6ICduby1wcm9ibGVtJyB9O1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLl9kaWFnbm9zZUNoYW5nZVNldEZhaWx1cmUoZmFpbGVkWzBdKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUcnkgdG8gZGlhZ25vc2UgdGhlIHJlYXNvbiB0aGF0IGNhdXNlZCBhIGNoYW5nZXNldCB0byBmYWlsIHRvIGNyZWF0ZVxuICAgKlxuICAgKiBUaGVyZSBhcmUgYSBjb3VwbGUgb2YgZGlmZmVyZW50IHJlYXNvbnMgdGhpcyBjYW4gaGFwcGVuLCBhbmQgd2UgZ28gdGhyb3VnaCBlYWNoIG9mIHRoZW0gaW4gb3JkZXIuXG4gICAqXG4gICAqIFVzdWFsbHkgdGhpcyBzdGFydHMgZnJvbSB0cnlpbmcgdG8gZGV0ZWN0IGFuIGVycm9yIG1lc3NhZ2UgcGF0dGVybiBpbiB0aGUgY2hhbmdlIHNldCBzdGF0dXMgcmVhc29uLFxuICAgKiBhbmQgdGhlbiBwb3RlbnRpYWxseSBnb2luZyB0byBmZXRjaCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHVzaW5nIGFkZGl0aW9uYWwgQVBJIGNhbGxzLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBfZGlhZ25vc2VDaGFuZ2VTZXRGYWlsdXJlKGNoYW5nZVNldDogQ2hhbmdlU2V0U3VtbWFyeSk6IFByb21pc2U8U3RhY2tEaWFnbm9zaXM+IHtcbiAgICBpZiAoY2hhbmdlU2V0LlN0YXR1cyAhPT0gQ2hhbmdlU2V0U3RhdHVzLkZBSUxFRCkge1xuICAgICAgcmV0dXJuIHsgdHlwZTogJ25vLXByb2JsZW0nIH07XG4gICAgfVxuXG4gICAgaWYgKGNoYW5nZVNldEhhc05vQ2hhbmdlcyhjaGFuZ2VTZXQpKSB7XG4gICAgICAvLyBUaGlzIHdpbGwgbGVhZCB0byBhIGNoYW5nZSBzZXQgdGhhdCBpcyBGQUlMRUQgYnV0IGl0J3Mgbm90IGFjdHVhbGx5IGEgcHJvYmxlbVxuICAgICAgcmV0dXJuIHsgdHlwZTogJ25vLXByb2JsZW0nIH07XG4gICAgfVxuXG4gICAgY29uc3QgaXNFYXJseVZhbGlkYXRpb25FcnJvciA9IGNoYW5nZVNldC5TdGF0dXNSZWFzb24/LmluY2x1ZGVzKCdBV1M6OkVhcmx5VmFsaWRhdGlvbicpO1xuICAgIGlmIChpc0Vhcmx5VmFsaWRhdGlvbkVycm9yKSB7XG4gICAgICBjb25zdCBldiA9IGF3YWl0IG5ldyBFYXJseVZhbGlkYXRpb25SZXBvcnRlcih0aGlzLnByb3BzLnNkaywgdGhpcy5wcm9wcy5lbnZSZXNvdXJjZXMpXG4gICAgICAgIC5mZXRjaERldGFpbHNTdHJ1Y3R1cmVkKGNoYW5nZVNldC5DaGFuZ2VTZXROYW1lISwgY2hhbmdlU2V0LlN0YWNrTmFtZSEpO1xuICAgICAgc3dpdGNoIChldi50eXBlKSB7XG4gICAgICAgIGNhc2UgJ2NvdWxkLW5vdC1jaGVjayc6XG4gICAgICAgICAgLy8gRW1pdCB0aGUgd2FybmluZyBoZXJlIGFuZCBvdGhlcndpc2UganVzdCByZXR1cm4gYW4gZW1wdHkgZXJyb3IgYmxvY2tcbiAgICAgICAgICBhd2FpdCB0aGlzLnByb3BzLmlvSGVscGVyLmRlZmF1bHRzLndhcm4oZXYubWVzc2FnZSk7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHR5cGU6ICdwcm9ibGVtJyxcbiAgICAgICAgICAgIGRldGVjdGVkQnk6IHtcbiAgICAgICAgICAgICAgdHlwZTogJ2Vhcmx5LXZhbGlkYXRpb24nLFxuICAgICAgICAgICAgICBjaGFuZ2VTZXROYW1lOiBjaGFuZ2VTZXQuQ2hhbmdlU2V0TmFtZSA/PyAnJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBwcm9ibGVtczogW10sXG4gICAgICAgICAgfTtcbiAgICAgICAgY2FzZSAncmVzb3VyY2UtZXJyb3JzJzpcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdHlwZTogJ3Byb2JsZW0nLFxuICAgICAgICAgICAgZGV0ZWN0ZWRCeToge1xuICAgICAgICAgICAgICB0eXBlOiAnZWFybHktdmFsaWRhdGlvbicsXG4gICAgICAgICAgICAgIGNoYW5nZVNldE5hbWU6IGNoYW5nZVNldC5DaGFuZ2VTZXROYW1lID8/ICcnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHByb2JsZW1zOiBhd2FpdCB0aGlzLmFkZEVycm9yVHJhY2VzKGV2LmVycm9ycy5tYXAoKGUpID0+IHJlc291cmNlRXJyb3JGcm9tRWFybHlWYWxpZGF0aW9uRXJyb3IoY2hhbmdlU2V0LlN0YWNrSWQgPz8gJycsIHRoaXMucGFyZW50U3RhY2tMb2dpY2FsSWRzLCBlKSkpLFxuICAgICAgICAgIH07XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGNoYW5nZVNldC5TdGF0dXNSZWFzb24/LmluY2x1ZGVzKCdOZXN0ZWQgY2hhbmdlIHNldCcpKSB7XG4gICAgICByZXR1cm4gdGhpcy5fZGlhZ25vc2VOZXN0ZWRDaGFuZ2VTZXRGYWlsdXJlKGNoYW5nZVNldCk7XG4gICAgfVxuXG4gICAgY29uc3QgZmFpbGVkQXV0b0Vycm9ycyA9IHRoaXMuX3RyeURldGVjdEZhaWxlZEF1dG9JbXBvcnQoY2hhbmdlU2V0KTtcbiAgICBpZiAoZmFpbGVkQXV0b0Vycm9ycykge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdHlwZTogJ3Byb2JsZW0nLFxuICAgICAgICBkZXRlY3RlZEJ5OiB7XG4gICAgICAgICAgdHlwZTogJ2NoYW5nZS1zZXQnLFxuICAgICAgICAgIGNoYW5nZVNldFN0YXR1czogY2hhbmdlU2V0LlN0YXR1cyA/PyAnJyxcbiAgICAgICAgICBjaGFuZ2VTZXROYW1lOiBjaGFuZ2VTZXQuQ2hhbmdlU2V0TmFtZSA/PyAnJyxcbiAgICAgICAgICBzdGF0dXNSZWFzb246IGNoYW5nZVNldC5TdGF0dXNSZWFzb24gPz8gJycsXG4gICAgICAgIH0sXG4gICAgICAgIHByb2JsZW1zOiBhd2FpdCB0aGlzLmFkZEVycm9yVHJhY2VzKGZhaWxlZEF1dG9FcnJvcnMpLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5fbm9uU3BlY2lmaWNDaGFuZ2VTZXRFcnJvcihjaGFuZ2VTZXQpO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBhZGRFcnJvclRyYWNlcyhlcnJzOiByZWFkb25seSBSZXNvdXJjZUVycm9yW10pOiBQcm9taXNlPFRyYWNlZFJlc291cmNlRXJyb3JbXT4ge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAY2RrbGFicy9wcm9taXNlYWxsLW5vLXVuYm91bmRlZC1wYXJhbGxlbGlzbVxuICAgIHJldHVybiBQcm9taXNlLmFsbChlcnJzLm1hcCgoZSkgPT4gdGhpcy5hZGRFcnJvclRyYWNlKGUpKSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGFkZEVycm9yVHJhY2UoZXJyOiBSZXNvdXJjZUVycm9yKTogUHJvbWlzZTxUcmFjZWRSZXNvdXJjZUVycm9yPiB7XG4gICAgbGV0IHNvdXJjZVRyYWNlO1xuICAgIGlmIChlcnIubG9naWNhbElkKSB7XG4gICAgICBzb3VyY2VUcmFjZSA9IGF3YWl0IHRoaXMucHJvcHMuc291cmNlVHJhY2VyLnRyYWNlUmVzb3VyY2UoZXJyLnN0YWNrQXJuLCBlcnIucGFyZW50U3RhY2tMb2dpY2FsSWRzLCBlcnIubG9naWNhbElkKTtcbiAgICB9IGVsc2Uge1xuICAgICAgc291cmNlVHJhY2UgPSBhd2FpdCB0aGlzLnByb3BzLnNvdXJjZVRyYWNlci50cmFjZVN0YWNrKGVyci5zdGFja0FybiwgZXJyLnBhcmVudFN0YWNrTG9naWNhbElkcyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHsgLi4uZXJyLCBzb3VyY2VUcmFjZSwgdG9wTGV2ZWxTdGFja0hpZXJhcmNoaWNhbElkOiB0aGlzLnByb3BzLnRvcExldmVsU3RhY2tIaWVyYXJjaGljYWxJZCB9O1xuICB9XG5cbiAgLyoqXG4gICAqIEJ1aWxkIGEgZ2VuZXJpYyBzdGFjayBlcnJvciBmcm9tIHRoZSBnaXZlbiBjaGFuZ2Ugc2V0IGluZm9ybWF0aW9uXG4gICAqXG4gICAqIFdlIGNhbid0IHBvaW50IHRvIGEgc3BlY2lmaWMgcmVzb3VyY2UuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIF9ub25TcGVjaWZpY0NoYW5nZVNldEVycm9yKGNoYW5nZVNldDogQ2hhbmdlU2V0U3VtbWFyeSk6IFByb21pc2U8U3RhY2tEaWFnbm9zaXM+IHtcbiAgICByZXR1cm4ge1xuICAgICAgdHlwZTogJ3Byb2JsZW0nLFxuICAgICAgZGV0ZWN0ZWRCeToge1xuICAgICAgICB0eXBlOiAnY2hhbmdlLXNldCcsXG4gICAgICAgIGNoYW5nZVNldE5hbWU6IGNoYW5nZVNldC5DaGFuZ2VTZXROYW1lID8/ICcnLFxuICAgICAgICBjaGFuZ2VTZXRTdGF0dXM6IGNoYW5nZVNldC5TdGF0dXMgPz8gJycsXG4gICAgICAgIHN0YXR1c1JlYXNvbjogY2hhbmdlU2V0LlN0YXR1c1JlYXNvbiA/PyAnJyxcbiAgICAgIH0sXG4gICAgICBwcm9ibGVtczogW1xuICAgICAgICBhd2FpdCB0aGlzLmFkZEVycm9yVHJhY2Uoe1xuICAgICAgICAgIC8vIEl0J3MgYWJvdXQgYSBzdGFja1xuICAgICAgICAgIGxvZ2ljYWxJZDogdW5kZWZpbmVkLFxuICAgICAgICAgIG1lc3NhZ2U6IGNoYW5nZVNldC5TdGF0dXNSZWFzb24gPz8gJycsXG4gICAgICAgICAgcGFyZW50U3RhY2tMb2dpY2FsSWRzOiB0aGlzLnBhcmVudFN0YWNrTG9naWNhbElkcyxcbiAgICAgICAgICBzdGFja0FybjogY2hhbmdlU2V0LlN0YWNrSWQgPz8gJycsXG4gICAgICAgICAgcGh5c2ljYWxJZDogY2hhbmdlU2V0LlN0YWNrSWQsXG4gICAgICAgICAgcmVzb3VyY2VUeXBlOiAnQVdTOjpDbG91ZEZvcm1hdGlvbjo6U3RhY2snLFxuICAgICAgICB9KSxcbiAgICAgIF0sXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBMb29rIGZvciBuZXN0ZWQgY2hhbmdlIHNldHMgdGhhdCBoYXZlIGZhaWxlZCwgYW5kIGRpYWdub3NlIHRob3NlLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBfZGlhZ25vc2VOZXN0ZWRDaGFuZ2VTZXRGYWlsdXJlKGNoYW5nZVNldDogQ2hhbmdlU2V0U3VtbWFyeSk6IFByb21pc2U8U3RhY2tEaWFnbm9zaXM+IHtcbiAgICBjb25zdCBuZXN0ZWQgPSBhd2FpdCB0aGlzLl9maW5kRmFpbGVkTmVzdGVkU3RhY2soY2hhbmdlU2V0KTtcbiAgICBpZiAoIW5lc3RlZCkge1xuICAgICAgLy8gVGhhdCdzIHdlaXJkLiBMZXQncyByZXR1cm4gdGhlIGNoYW5nZSBzZXQncyBzdGF0dXMgcmVhc29uIGFzIGEgbm9uLXNwZWNpZmljIGVycm9yXG4gICAgICByZXR1cm4gdGhpcy5fbm9uU3BlY2lmaWNDaGFuZ2VTZXRFcnJvcihjaGFuZ2VTZXQpO1xuICAgIH1cblxuICAgIGNvbnN0IG5lc3RlZENzID0gYXdhaXQgdGhpcy5jZm4uZGVzY3JpYmVDaGFuZ2VTZXQoe1xuICAgICAgQ2hhbmdlU2V0TmFtZTogbmVzdGVkLmNoYW5nZVNldE5hbWUsXG4gICAgICBTdGFja05hbWU6IG5lc3RlZC5zdGFja05hbWUsXG4gICAgfSk7XG5cbiAgICBjb25zdCBuZXN0ZWREaWFnID0gbmV3IENsb3VkRm9ybWF0aW9uU3RhY2tEaWFnbm9zZXIodGhpcy5wcm9wcyk7XG4gICAgbmVzdGVkRGlhZy5wYXJlbnRTdGFja0xvZ2ljYWxJZHMgPSBbLi4udGhpcy5wYXJlbnRTdGFja0xvZ2ljYWxJZHMsIG5lc3RlZC5sb2dpY2FsSWRdO1xuICAgIHJldHVybiBuZXN0ZWREaWFnLl9kaWFnbm9zZUNoYW5nZVNldEZhaWx1cmUobmVzdGVkQ3MpO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBfZmluZEZhaWxlZE5lc3RlZFN0YWNrKGNoYW5nZVNldDogQ2hhbmdlU2V0U3VtbWFyeSk6IFByb21pc2U8e1xuICAgIHN0YWNrTmFtZTogc3RyaW5nO1xuICAgIGNoYW5nZVNldE5hbWU6IHN0cmluZztcbiAgICBsb2dpY2FsSWQ6IHN0cmluZztcbiAgfSB8IHVuZGVmaW5lZD4ge1xuICAgIC8vIFRoZSBzdGF0dXMgcmVhc29uIG9ubHkgaW5jbHVkZXMgdGhlIGNoYW5nZSBzZXQgSUQsIGJ1dCB3ZSBhbHNvIG5lZWQgdGhlIHN0YWNrIG5hbWUuIFRoZSB3YXkgdG8gZ2V0IHRoaXMgaXNcbiAgICAvLyBkZXNjcmliZSB0aGUgY3VycmVudCBjaGFuZ2Ugc2V0LCB0aGVuIGZyb20gdGhlIENoYW5nZXMgZmluZCB0aGUgc3RhY2sgd2hvc2UgQ2hhbmdlU2V0SWQgaXMgbWVudGlvbmVkIGluIHRoZVxuICAgIC8vIHN0YXR1cyByZWFzb24sIHRoZW4gbG9vayB1cCB0aGF0IGNoYW5nZSBzZXQgYW5kIHJlY3Vyc2UgaW50byBhIHJlZ3VsYXIgY2hhbmdlIHNldCBkaWFnbm9zaXMuXG4gICAgbGV0IG5leHRUb2tlbiA9IHVuZGVmaW5lZDtcbiAgICBkbyB7XG4gICAgICAvLyBDaGFuZ2VzIGluIHRoaXMgcmVzcG9uc2UgbWlnaHQgYmUgcGFnaW5hdGVkXG4gICAgICBjb25zdCByZXNwID0gYXdhaXQgdGhpcy5jZm4uZGVzY3JpYmVDaGFuZ2VTZXQoe1xuICAgICAgICBTdGFja05hbWU6IGNoYW5nZVNldC5TdGFja05hbWUsXG4gICAgICAgIENoYW5nZVNldE5hbWU6IGNoYW5nZVNldC5DaGFuZ2VTZXROYW1lLFxuICAgICAgICAuLi5uZXh0VG9rZW4gPyB7IE5leHRUb2tlbjogbmV4dFRva2VuIH0gOiB7fSxcbiAgICAgIH0pO1xuXG4gICAgICBmb3IgKGNvbnN0IGNoYW5nZSBvZiByZXNwLkNoYW5nZXMgPz8gW10pIHtcbiAgICAgICAgaWYgKGNoYW5nZS5UeXBlID09PSBDaGFuZ2VUeXBlLlJlc291cmNlICYmIGNoYW5nZS5SZXNvdXJjZUNoYW5nZT8uUmVzb3VyY2VUeXBlID09PSAnQVdTOjpDbG91ZEZvcm1hdGlvbjo6U3RhY2snICYmIGNoYW5nZS5SZXNvdXJjZUNoYW5nZT8uQ2hhbmdlU2V0SWQgJiYgY2hhbmdlU2V0LlN0YXR1c1JlYXNvbj8uaW5jbHVkZXMoY2hhbmdlLlJlc291cmNlQ2hhbmdlPy5DaGFuZ2VTZXRJZCkpIHtcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgY2hhbmdlU2V0TmFtZTogY2hhbmdlLlJlc291cmNlQ2hhbmdlLkNoYW5nZVNldElkLFxuICAgICAgICAgICAgc3RhY2tOYW1lOiBjaGFuZ2UuUmVzb3VyY2VDaGFuZ2UuUGh5c2ljYWxSZXNvdXJjZUlkID8/ICcnLFxuICAgICAgICAgICAgbG9naWNhbElkOiBjaGFuZ2UuUmVzb3VyY2VDaGFuZ2UuTG9naWNhbFJlc291cmNlSWQgPz8gJycsXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBuZXh0VG9rZW4gPSByZXNwLk5leHRUb2tlbjtcbiAgICB9IHdoaWxlIChuZXh0VG9rZW4pO1xuXG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIC8qKlxuICAgKiBUcnkgdG8gcGFyc2UgZmFpbGVkIGF1dG8taW1wb3J0cyBvdXQgZnJvbSBhIGNoYW5nZSBzZXQgc3RhdHVzXG4gICAqXG4gICAqIFRoZSBwYXR0ZXJuIGxvb2tzIGxpa2UgdGhpczpcbiAgICpcbiAgICogYGBgXG4gICAqIENsb3VkRm9ybWF0aW9uIGlzIGF0dGVtcHRpbmcgdG8gaW1wb3J0IHNvbWUgcmVzb3VyY2VzIGJlY2F1c2UgdGhleSBhbHJlYWR5IGV4aXN0IGluIHlvdXIgYWNjb3VudC4gVGhlIHJlc291cmNlcyBtdXN0IGhhdmUgdGhlIERlbGV0aW9uUG9saWN5IGF0dHJpYnV0ZSBzZXQgdG8gJ1JldGFpbicgb3IgJ1JldGFpbkV4Y2VwdE9uQ3JlYXRlJyBpbiB0aGUgdGVtcGxhdGUgZm9yIHN1Y2Nlc3NmdWwgaW1wb3J0LiBUaGUgYWZmZWN0ZWQgcmVzb3VyY2VzIGFyZSBTb21lQnVja2V0RDVCNzA3MDQgKHtCdWNrZXROYW1lPXpvbWFhcmVlbmJ1Y2tldH0pXG4gICAqIGBgYFxuICAgKlxuICAgKiBGb2xsb3dlZCBieVxuICAgKlxuICAgKiBgYGBcbiAgICogTG9naWNhbElEICh7UHJvcD1WYWx1ZSxQcm9wPVZhbHVlfSksIExvZ2ljYWxJRCAoe1Byb3A9VmFsdWV9KSwgLi4uXG4gICAqIGBgYFxuICAgKi9cbiAgcHJpdmF0ZSBfdHJ5RGV0ZWN0RmFpbGVkQXV0b0ltcG9ydChjaGFuZ2VTZXQ6IENoYW5nZVNldFN1bW1hcnkpOiBSZXNvdXJjZUVycm9yW10gfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IG1lc3NhZ2UgPSBjaGFuZ2VTZXQuU3RhdHVzUmVhc29uO1xuICAgIC8vIE9ubHkgZW5oYW5jZSB0aGUgc3BlY2lmaWMgQ0ZOIGVycm9yIGFib3V0IGltcG9ydGluZyBleGlzdGluZyByZXNvdXJjZXNcbiAgICBpZiAoIW1lc3NhZ2U/LmluY2x1ZGVzKCdDbG91ZEZvcm1hdGlvbiBpcyBhdHRlbXB0aW5nIHRvIGltcG9ydCBzb21lIHJlc291cmNlcyBiZWNhdXNlIHRoZXkgYWxyZWFkeSBleGlzdCBpbiB5b3VyIGFjY291bnQnKSkge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBjb25zdCBtYXJrZXIgPSAnVGhlIGFmZmVjdGVkIHJlc291cmNlcyBhcmUgJztcbiAgICBjb25zdCBtYXJrZXJJbmRleCA9IG1lc3NhZ2UuaW5kZXhPZihtYXJrZXIpO1xuICAgIGlmIChtYXJrZXJJbmRleCA9PT0gLTEpIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgY29uc3QgcmV0OiBSZXNvdXJjZUVycm9yW10gPSBbXTtcbiAgICBsZXQgcmVtYWluaW5nID0gbWVzc2FnZS5zbGljZShtYXJrZXJJbmRleCArIG1hcmtlci5sZW5ndGgpO1xuICAgIHdoaWxlIChyZW1haW5pbmcpIHtcbiAgICAgIGNvbnN0IGVuZEl4ID0gcmVtYWluaW5nLmluZGV4T2YoJyksICcpO1xuICAgICAgY29uc3QgdGhpc1Jlc291cmNlID0gZW5kSXggPiAtMSA/IHJlbWFpbmluZy5zbGljZSgwLCBlbmRJeCArIDEpIDogcmVtYWluaW5nO1xuICAgICAgcmVtYWluaW5nID0gcmVtYWluaW5nLnNsaWNlKHRoaXNSZXNvdXJjZS5sZW5ndGggKyAyKTtcblxuICAgICAgLy8gdGhpc1Jlc291cmNlID0gXCJMb2dpY2FsSWQgKHtQcm9wPVZhbHVlLCBQcm9wPVZhbHVlfSlcIlxuICAgICAgY29uc3Qgb3BlblBhcmVuID0gdGhpc1Jlc291cmNlLmluZGV4T2YoJygnKTtcbiAgICAgIGNvbnN0IGxvZ2ljYWxJZCA9IG9wZW5QYXJlbiA+IC0xID8gdGhpc1Jlc291cmNlLnNsaWNlKDAsIG9wZW5QYXJlbikudHJpbSgpIDogdW5kZWZpbmVkO1xuXG4gICAgICByZXQucHVzaCh7XG4gICAgICAgIG1lc3NhZ2U6IGBBdXRvbWF0aWMgaW1wb3J0IG9mIGV4aXN0aW5nIHJlc291cmNlICR7dGhpc1Jlc291cmNlfSBuZWVkcyBhIERlbGV0aW9uUG9saWN5IG9mIFxcJ1JldGFpblxcJyBvciBcXCdSZXRhaW5FeGNlcHRPbkNyZWF0ZVxcJy4gU2V0IHRoZSByZW1vdmFsIHBvbGljeSB0byBcXCdSZW1vdmFsUG9saWN5LlJFVEFJTlxcJyBvciBcXCdSZW1vdmFsUG9saWN5LlJFVEFJTl9PTl9VUERBVEVfT1JfREVMRVRFXFwnIChTZWUgaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2Nkay92Mi9ndWlkZS9yZXNvdXJjZXMuaHRtbCNyZXNvdXJjZXMtcmVtb3ZhbClgLFxuICAgICAgICBwYXJlbnRTdGFja0xvZ2ljYWxJZHM6IHRoaXMucGFyZW50U3RhY2tMb2dpY2FsSWRzLFxuICAgICAgICBzdGFja0FybjogY2hhbmdlU2V0LlN0YWNrSWQgPz8gJycsXG4gICAgICAgIGVycm9yQ29kZTogJ0F1dG9tYXRpY0ltcG9ydE5lZWRzUmV0YWluJyxcbiAgICAgICAgbG9naWNhbElkLFxuICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiByZXQ7XG4gIH1cbn1cblxuLyoqXG4gKiBSZXR1cm4gdHJ1ZSBpZiB0aGUgZ2l2ZW4gY2hhbmdlIHNldCBoYXMgbm8gY2hhbmdlc1xuICpcbiAqIFRoaXMgbXVzdCBiZSBkZXRlcm1pbmVkIGZyb20gdGhlIHN0YXR1cywgbm90IHRoZSAnQ2hhbmdlcycgYXJyYXkgb24gdGhlXG4gKiBvYmplY3Q7IHRoZSBsYXR0ZXIgY2FuIGJlIGVtcHR5IGJlY2F1c2Ugbm8gcmVzb3VyY2VzIHdlcmUgY2hhbmdlZCwgYnV0IGlmXG4gKiB0aGVyZSBhcmUgY2hhbmdlcyB0byBPdXRwdXRzLCB0aGUgY2hhbmdlIHNldCBjYW4gc3RpbGwgYmUgZXhlY3V0ZWQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjaGFuZ2VTZXRIYXNOb0NoYW5nZXMoZGVzY3JpcHRpb246IENoYW5nZVNldFN1bW1hcnkpIHtcbiAgY29uc3Qgbm9DaGFuZ2VFcnJvclByZWZpeGVzID0gW1xuICAgIC8vIEVycm9yIG1lc3NhZ2UgZm9yIGEgcmVndWxhciB0ZW1wbGF0ZVxuICAgIFwiVGhlIHN1Ym1pdHRlZCBpbmZvcm1hdGlvbiBkaWRuJ3QgY29udGFpbiBjaGFuZ2VzLlwiLFxuICAgIC8vIEVycm9yIG1lc3NhZ2Ugd2hlbiBhIFRyYW5zZm9ybSBpcyBpbnZvbHZlZCAoc2VlICMxMDY1MClcbiAgICAnTm8gdXBkYXRlcyBhcmUgdG8gYmUgcGVyZm9ybWVkLicsXG4gIF07XG5cbiAgcmV0dXJuIChcbiAgICBkZXNjcmlwdGlvbi5TdGF0dXMgPT09ICdGQUlMRUQnICYmIG5vQ2hhbmdlRXJyb3JQcmVmaXhlcy5zb21lKChwKSA9PiAoZGVzY3JpcHRpb24uU3RhdHVzUmVhc29uID8/ICcnKS5zdGFydHNXaXRoKHApKVxuICApO1xufVxuXG5mdW5jdGlvbiByZXNvdXJjZUVycm9yRnJvbUVhcmx5VmFsaWRhdGlvbkVycm9yKHN0YWNrSWQ6IHN0cmluZywgcGFyZW50U3RhY2tMb2dpY2FsSWRzOiBzdHJpbmdbXSwgZXY6IEVhcmx5VmFsaWRhdGlvbkVycm9yKTogUmVzb3VyY2VFcnJvciB7XG4gIHJldHVybiB7XG4gICAgbG9naWNhbElkOiBldi5sb2dpY2FsSWQsXG4gICAgcGh5c2ljYWxJZDogZXYucGh5c2ljYWxJZCxcbiAgICByZXNvdXJjZVR5cGU6IGV2LnJlc291cmNlVHlwZSxcbiAgICBtZXNzYWdlOiBgJHtldi5tZXNzYWdlfSAoYXQgJHtldi5kb2N1bWVudFBhdGh9KWAsXG4gICAgZXJyb3JDb2RlOiBgJHtldi52YWxpZGF0aW9uTmFtZX1fJHtldi5ldmVudFR5cGV9YCxcbiAgICBwYXJlbnRTdGFja0xvZ2ljYWxJZHMsXG4gICAgc3RhY2tBcm46IHN0YWNrSWQsXG4gIH07XG59XG4iXX0=
@@ -0,0 +1,12 @@
1
+ export declare class TreeBuilder {
2
+ private readonly rootText;
3
+ private readonly root;
4
+ constructor(rootText: string);
5
+ setNodeText(constructPath: string, nodeText: string): void;
6
+ render(): string;
7
+ toString(): string;
8
+ private obtainNode;
9
+ }
10
+ export declare function sideBySide(left: string[], sep: string, right: string[]): string[];
11
+ export declare function wrapText(n: number, text: string): string[];
12
+ //# sourceMappingURL=tree-builder.d.ts.map