@fjall/deploy-core 0.89.5 → 0.94.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 (198) hide show
  1. package/LICENSE +50 -21
  2. package/README.md +25 -0
  3. package/dist/.minified +1 -0
  4. package/dist/src/__test-utils__/awsMockHelpers.d.ts +20 -0
  5. package/dist/src/__test-utils__/awsMockHelpers.js +1 -0
  6. package/dist/src/__test-utils__/index.d.ts +1 -0
  7. package/dist/src/__test-utils__/index.js +1 -0
  8. package/dist/src/aws/AwsProvider.js +0 -1
  9. package/dist/src/aws/SimpleAwsProvider.js +1 -70
  10. package/dist/src/aws/index.d.ts +4 -2
  11. package/dist/src/aws/index.js +1 -3
  12. package/dist/src/aws/organisations/accounts.js +10 -10
  13. package/dist/src/aws/organisations/backup.js +4 -2
  14. package/dist/src/aws/organisations/costAllocation.js +4 -2
  15. package/dist/src/aws/organisations/delegatedAdmin.d.ts +9 -0
  16. package/dist/src/aws/organisations/delegatedAdmin.js +43 -0
  17. package/dist/src/aws/organisations/identityCentre.d.ts +1 -1
  18. package/dist/src/aws/organisations/identityCentre.js +6 -2
  19. package/dist/src/aws/organisations/index.d.ts +4 -3
  20. package/dist/src/aws/organisations/index.js +1 -12
  21. package/dist/src/aws/organisations/ipam.js +4 -2
  22. package/dist/src/aws/organisations/organisation.js +27 -18
  23. package/dist/src/aws/organisations/organisationalUnits.d.ts +26 -6
  24. package/dist/src/aws/organisations/organisationalUnits.js +149 -35
  25. package/dist/src/aws/organisations/policies.js +4 -3
  26. package/dist/src/aws/organisations/ram.js +6 -2
  27. package/dist/src/aws/organisations/serviceAccess.js +12 -6
  28. package/dist/src/aws/organisations/trustedAccess.js +6 -2
  29. package/dist/src/aws/organisations/types.d.ts +23 -1
  30. package/dist/src/aws/organisations/types.js +1 -16
  31. package/dist/src/aws/utils/__tests__/cloudformationTestHelpers.d.ts +6 -0
  32. package/dist/src/aws/utils/__tests__/cloudformationTestHelpers.js +1 -0
  33. package/dist/src/aws/utils/cloudformationEventHelpers.d.ts +48 -0
  34. package/dist/src/aws/utils/cloudformationEventHelpers.js +1 -0
  35. package/dist/src/aws/utils/cloudformationEventTypes.d.ts +45 -0
  36. package/dist/src/aws/utils/cloudformationEventTypes.js +1 -0
  37. package/dist/src/aws/utils/cloudformationEvents.d.ts +8 -54
  38. package/dist/src/aws/utils/cloudformationEvents.js +1 -596
  39. package/dist/src/aws/utils/index.d.ts +5 -0
  40. package/dist/src/aws/utils/index.js +1 -0
  41. package/dist/src/aws/utils/stackStatus.js +1 -90
  42. package/dist/src/events/index.d.ts +13 -0
  43. package/dist/src/events/index.js +1 -0
  44. package/dist/src/index.d.ts +34 -17
  45. package/dist/src/index.js +41 -21
  46. package/dist/src/orchestration/__tests__/cascadeTestHelpers.d.ts +12 -0
  47. package/dist/src/orchestration/__tests__/cascadeTestHelpers.js +78 -0
  48. package/dist/src/orchestration/activeDeploymentGuard.d.ts +10 -0
  49. package/dist/src/orchestration/activeDeploymentGuard.js +39 -0
  50. package/dist/src/orchestration/applicationDeploy.js +46 -229
  51. package/dist/src/orchestration/applicationDeployHelpers.d.ts +39 -0
  52. package/dist/src/orchestration/applicationDeployHelpers.js +223 -0
  53. package/dist/src/orchestration/applicationDestroy.d.ts +14 -0
  54. package/dist/src/orchestration/applicationDestroy.js +131 -0
  55. package/dist/src/orchestration/builders/dockerBuilder.d.ts +17 -0
  56. package/dist/src/orchestration/builders/dockerBuilder.js +98 -0
  57. package/dist/src/orchestration/builders/frameworkRegistry.d.ts +23 -0
  58. package/dist/src/orchestration/builders/frameworkRegistry.js +1 -0
  59. package/dist/src/orchestration/builders/index.d.ts +4 -0
  60. package/dist/src/orchestration/builders/index.js +1 -0
  61. package/dist/src/orchestration/builders/openNextBuilder.d.ts +21 -0
  62. package/dist/src/orchestration/builders/openNextBuilder.js +144 -0
  63. package/dist/src/orchestration/cascadeDestroyHelpers.d.ts +30 -0
  64. package/dist/src/orchestration/cascadeDestroyHelpers.js +1 -0
  65. package/dist/src/orchestration/cascadeHelpers.d.ts +46 -0
  66. package/dist/src/orchestration/cascadeHelpers.js +160 -0
  67. package/dist/src/orchestration/contextHelpers.d.ts +46 -2
  68. package/dist/src/orchestration/contextHelpers.js +93 -1
  69. package/dist/src/orchestration/destroy.d.ts +13 -0
  70. package/dist/src/orchestration/destroy.js +67 -0
  71. package/dist/src/orchestration/detectionPipeline.d.ts +2 -11
  72. package/dist/src/orchestration/detectionPipeline.js +29 -10
  73. package/dist/src/orchestration/dockerBuildHelper.d.ts +10 -0
  74. package/dist/src/orchestration/dockerBuildHelper.js +49 -0
  75. package/dist/src/orchestration/dockerInterface.d.ts +4 -2
  76. package/dist/src/orchestration/index.d.ts +8 -1
  77. package/dist/src/orchestration/index.js +1 -3
  78. package/dist/src/orchestration/manifestSecretParser.d.ts +11 -0
  79. package/dist/src/orchestration/manifestSecretParser.js +1 -0
  80. package/dist/src/orchestration/openNextBuild.d.ts +28 -0
  81. package/dist/src/orchestration/openNextBuild.js +243 -0
  82. package/dist/src/orchestration/organisationDeploy.js +110 -233
  83. package/dist/src/orchestration/organisationDestroy.d.ts +24 -0
  84. package/dist/src/orchestration/organisationDestroy.js +189 -0
  85. package/dist/src/orchestration/organisationSetup.d.ts +6 -4
  86. package/dist/src/orchestration/organisationSetup.js +28 -8
  87. package/dist/src/orchestration/resolveOperation.js +68 -6
  88. package/dist/src/orchestration/serviceFactory.d.ts +4 -0
  89. package/dist/src/orchestration/serviceFactory.js +1 -16
  90. package/dist/src/orchestration/spawnHelpers.d.ts +47 -0
  91. package/dist/src/orchestration/spawnHelpers.js +1 -0
  92. package/dist/src/orchestration/stackCleanup.d.ts +39 -0
  93. package/dist/src/orchestration/stackCleanup.js +1 -0
  94. package/dist/src/orchestration/welcomeImageHelper.d.ts +15 -0
  95. package/dist/src/orchestration/welcomeImageHelper.js +64 -0
  96. package/dist/src/services/application/ApplicationStackService.d.ts +21 -30
  97. package/dist/src/services/application/ApplicationStackService.js +16 -234
  98. package/dist/src/services/application/applicationStackHelpers.d.ts +46 -0
  99. package/dist/src/services/application/applicationStackHelpers.js +248 -0
  100. package/dist/src/services/application/index.d.ts +1 -0
  101. package/dist/src/services/application/index.js +1 -1
  102. package/dist/src/services/index.d.ts +6 -0
  103. package/dist/src/services/index.js +1 -0
  104. package/dist/src/services/infrastructure/CdkArgumentBuilder.js +1 -67
  105. package/dist/src/services/infrastructure/CdkCommandRunner.d.ts +10 -2
  106. package/dist/src/services/infrastructure/CdkCommandRunner.js +18 -15
  107. package/dist/src/services/infrastructure/CdkErrorFormatter.js +16 -194
  108. package/dist/src/services/infrastructure/CdkEventMonitoring.js +1 -41
  109. package/dist/src/services/infrastructure/CdkOutputAnalyser.js +1 -1
  110. package/dist/src/services/infrastructure/CdkOutputParser.js +2 -33
  111. package/dist/src/services/infrastructure/CdkProcessManager.d.ts +5 -0
  112. package/dist/src/services/infrastructure/CdkProcessManager.js +81 -47
  113. package/dist/src/services/infrastructure/CdkService.d.ts +7 -53
  114. package/dist/src/services/infrastructure/CdkService.js +41 -83
  115. package/dist/src/services/infrastructure/CdkServiceTypes.d.ts +50 -0
  116. package/dist/src/services/infrastructure/CdkServiceTypes.js +0 -0
  117. package/dist/src/services/infrastructure/CloudFormationService.js +9 -10
  118. package/dist/src/services/infrastructure/ICdkProcessManager.d.ts +27 -0
  119. package/dist/src/services/infrastructure/ICdkProcessManager.js +1 -0
  120. package/dist/src/services/infrastructure/__tests__/cloudFormationTestHelpers.d.ts +9 -0
  121. package/dist/src/services/infrastructure/__tests__/cloudFormationTestHelpers.js +1 -0
  122. package/dist/src/services/infrastructure/cdkServiceHelpers.d.ts +9 -0
  123. package/dist/src/services/infrastructure/cdkServiceHelpers.js +1 -0
  124. package/dist/src/services/infrastructure/constructMapEnrichment.d.ts +7 -0
  125. package/dist/src/services/infrastructure/constructMapEnrichment.js +1 -0
  126. package/dist/src/services/infrastructure/index.d.ts +3 -1
  127. package/dist/src/services/infrastructure/index.js +1 -7
  128. package/dist/src/services/supporting/TemplateHashService.js +1 -1
  129. package/dist/src/services/supporting/helpers.js +1 -81
  130. package/dist/src/services/supporting/index.js +1 -3
  131. package/dist/src/steps/index.d.ts +1 -0
  132. package/dist/src/steps/index.js +1 -0
  133. package/dist/src/steps/stepRegistry.d.ts +71 -0
  134. package/dist/src/steps/stepRegistry.js +505 -0
  135. package/dist/src/types/FjallState.js +1 -118
  136. package/dist/src/types/ProgressEvent.js +1 -48
  137. package/dist/src/types/application/ApplicationServiceTypes.js +1 -30
  138. package/dist/src/types/application/index.js +1 -1
  139. package/dist/src/types/callbacks.d.ts +76 -4
  140. package/dist/src/types/callbacks.js +0 -1
  141. package/dist/src/types/constants.d.ts +2 -0
  142. package/dist/src/types/constants.js +1 -6
  143. package/dist/src/types/credentials.js +0 -1
  144. package/dist/src/types/deployment/DeploymentServiceTypes.d.ts +5 -2
  145. package/dist/src/types/deployment/DeploymentServiceTypes.js +1 -1
  146. package/dist/src/types/deployment/DeploymentTypes.js +0 -1
  147. package/dist/src/types/deployment/cloudformation.js +0 -1
  148. package/dist/src/types/deployment/index.d.ts +3 -1
  149. package/dist/src/types/deployment/index.js +1 -1
  150. package/dist/src/types/deployment/parallel.js +1 -10
  151. package/dist/src/types/deploymentEventSchema.d.ts +158 -0
  152. package/dist/src/types/deploymentEventSchema.js +1 -0
  153. package/dist/src/types/detection.d.ts +22 -0
  154. package/dist/src/types/detection.js +1 -0
  155. package/dist/src/types/entitlements.d.ts +31 -0
  156. package/dist/src/types/entitlements.js +0 -0
  157. package/dist/src/types/errors/CdkError.js +1 -20
  158. package/dist/src/types/errors/ServiceError.d.ts +2 -1
  159. package/dist/src/types/errors/ServiceError.js +1 -119
  160. package/dist/src/types/errors/index.d.ts +2 -0
  161. package/dist/src/types/errors/index.js +1 -0
  162. package/dist/src/types/events.d.ts +3 -9
  163. package/dist/src/types/events.js +0 -5
  164. package/dist/src/types/frameworkBuilder.d.ts +96 -0
  165. package/dist/src/types/frameworkBuilder.js +8 -0
  166. package/dist/src/types/index.d.ts +19 -4
  167. package/dist/src/types/index.js +1 -9
  168. package/dist/src/types/operations.d.ts +3 -2
  169. package/dist/src/types/operations.js +1 -285
  170. package/dist/src/types/orgConfig.d.ts +2 -10
  171. package/dist/src/types/orgConfig.js +0 -11
  172. package/dist/src/types/params.d.ts +60 -1
  173. package/dist/src/types/patternDetection.d.ts +14 -16
  174. package/dist/src/types/patternDetection.js +14 -18
  175. package/dist/src/types/patternTypes.d.ts +19 -0
  176. package/dist/src/types/patternTypes.js +1 -0
  177. package/dist/src/types/stepDefinitions.d.ts +163 -0
  178. package/dist/src/types/stepDefinitions.js +98 -0
  179. package/dist/src/types/validation.js +0 -1
  180. package/dist/src/util/dockerfileDetection.d.ts +5 -0
  181. package/dist/src/util/dockerfileDetection.js +1 -0
  182. package/dist/src/util/index.d.ts +4 -3
  183. package/dist/src/util/index.js +1 -3
  184. package/dist/src/util/sequencedCallbacks.d.ts +44 -0
  185. package/dist/src/util/sequencedCallbacks.js +1 -0
  186. package/package.json +49 -8
  187. package/dist/src/aws/utils/CloudFormationFailureAnalyser.d.ts +0 -32
  188. package/dist/src/aws/utils/CloudFormationFailureAnalyser.js +0 -228
  189. package/dist/src/aws/utils/errors.d.ts +0 -26
  190. package/dist/src/aws/utils/errors.js +0 -59
  191. package/dist/src/util/fsHelpers.d.ts +0 -4
  192. package/dist/src/util/fsHelpers.js +0 -16
  193. package/dist/src/util/securityHelpers.d.ts +0 -31
  194. package/dist/src/util/securityHelpers.js +0 -124
  195. package/dist/src/util/singleton.d.ts +0 -2
  196. package/dist/src/util/singleton.js +0 -9
  197. package/dist/src/util/sleep.d.ts +0 -4
  198. package/dist/src/util/sleep.js +0 -4
@@ -1,228 +0,0 @@
1
- /**
2
- * CloudFormationFailureAnalyser provides intelligent analysis of deployment failures
3
- * It identifies root causes, dependency chains, and provides actionable remediation
4
- */
5
- export class CloudFormationFailureAnalyser {
6
- knownErrorPatterns = [
7
- {
8
- pattern: /AccessDenied|UnauthorizedOperation|Forbidden/i,
9
- category: "permissions",
10
- remediation: [
11
- "Check IAM permissions for the deployment role",
12
- "Ensure the role has necessary CloudFormation permissions",
13
- "Verify service-linked roles are created if needed"
14
- ]
15
- },
16
- {
17
- pattern: /Invalid.*Parameter|ValidationError|Invalid.*Value/i,
18
- category: "validation",
19
- remediation: [
20
- "Review parameter values in your CDK code",
21
- "Check for typos in resource names or ARNs",
22
- "Ensure all required parameters are provided"
23
- ]
24
- },
25
- {
26
- pattern: /Limit.*Exceeded|Quota.*Exceeded|Maximum.*reached/i,
27
- category: "limit",
28
- remediation: [
29
- "Check AWS service quotas in the Service Quotas console",
30
- "Request a quota increase if needed",
31
- "Consider using a different region with available capacity"
32
- ]
33
- },
34
- {
35
- pattern: /Timeout|Connection.*refused|Network.*unreachable/i,
36
- category: "network",
37
- remediation: [
38
- "Check network connectivity and VPC settings",
39
- "Verify security groups and NACLs",
40
- "Ensure endpoints are accessible"
41
- ]
42
- },
43
- {
44
- pattern: /already exists|Duplicate|ConflictException/i,
45
- category: "validation",
46
- remediation: [
47
- "Resource with this name already exists",
48
- "Consider using a different name or deleting the existing resource",
49
- "Check if you are deploying to the correct account/region"
50
- ]
51
- },
52
- {
53
- pattern: /Role.*not.*found|Role.*does.*not.*exist/i,
54
- category: "dependency",
55
- remediation: [
56
- "Ensure IAM roles are created before dependent resources",
57
- "Check role names and ARNs are correct",
58
- "Verify cross-stack references are properly configured"
59
- ]
60
- }
61
- ];
62
- analyseFailure(eventHistory) {
63
- // Find all failed resources
64
- const failedResources = this.findFailedResources(eventHistory);
65
- if (failedResources.length === 0) {
66
- return null;
67
- }
68
- // Find the root cause
69
- const rootCause = this.findRootCause(failedResources, eventHistory);
70
- // Build dependency chain
71
- const dependencyChain = this.buildDependencyChain(rootCause.resource, failedResources);
72
- // Generate remediation suggestions
73
- const remediation = this.generateRemediation(rootCause);
74
- // Create summary
75
- const summary = this.generateSummary(rootCause, failedResources);
76
- return {
77
- rootCause,
78
- affectedResources: failedResources,
79
- dependencyChain,
80
- summary,
81
- remediation,
82
- errorPattern: rootCause.category
83
- };
84
- }
85
- findFailedResources(eventHistory) {
86
- const failed = [];
87
- for (const [_logicalId, events] of eventHistory) {
88
- // Get the latest event for this resource
89
- const latestEvent = events[events.length - 1];
90
- if (latestEvent && this.isFailedStatus(latestEvent.status)) {
91
- failed.push(latestEvent);
92
- }
93
- }
94
- // Sort by timestamp to find the first failure
95
- return failed.sort((a, b) => a.timestamp.getTime() - b.timestamp.getTime());
96
- }
97
- findRootCause(failedResources, eventHistory) {
98
- if (failedResources.length === 0) {
99
- return {
100
- resource: {
101
- logicalId: "Unknown",
102
- resourceType: "Unknown",
103
- status: "FAILED",
104
- timestamp: new Date()
105
- },
106
- reason: "No failed resources found",
107
- category: "unknown",
108
- isDirectCause: false
109
- };
110
- }
111
- // The first failed resource is usually the root cause
112
- const firstFailed = failedResources[0];
113
- // Analyse the failure reason
114
- const category = this.categoriseError(firstFailed.statusReason || "");
115
- // Check if this is a direct cause or a cascading failure
116
- const isDirectCause = this.isDirectCause(firstFailed, eventHistory);
117
- return {
118
- resource: firstFailed,
119
- reason: firstFailed.statusReason || "Unknown error",
120
- category,
121
- isDirectCause
122
- };
123
- }
124
- categoriseError(errorMessage) {
125
- for (const pattern of this.knownErrorPatterns) {
126
- if (pattern.pattern.test(errorMessage)) {
127
- return pattern.category;
128
- }
129
- }
130
- return "unknown";
131
- }
132
- isDirectCause(resource, eventHistory) {
133
- // If the error mentions another resource, it's likely cascading
134
- const reason = resource.statusReason || "";
135
- // Check for references to other resources
136
- if (reason.includes("depends on") ||
137
- reason.includes("referenced by") ||
138
- reason.includes("required by")) {
139
- return false;
140
- }
141
- // Check if this resource had any successful events before failing
142
- const history = eventHistory.get(resource.logicalId) || [];
143
- const hasSuccessfulEvents = history.some((e) => e.status.includes("COMPLETE") && !e.status.includes("ROLLBACK"));
144
- // If it never succeeded, it's likely a direct cause
145
- return !hasSuccessfulEvents;
146
- }
147
- buildDependencyChain(rootCause, failedResources) {
148
- const chain = [];
149
- // Start with root cause
150
- chain.push(`${rootCause.logicalId} (${rootCause.resourceType}) - ROOT CAUSE`);
151
- // Add cascading failures in chronological order
152
- for (const resource of failedResources) {
153
- if (resource.logicalId !== rootCause.logicalId) {
154
- const reason = resource.statusReason || "";
155
- if (reason.toLowerCase().includes(rootCause.logicalId.toLowerCase())) {
156
- chain.push(` → ${resource.logicalId} (${resource.resourceType}) - Failed due to ${rootCause.logicalId}`);
157
- }
158
- else {
159
- chain.push(` → ${resource.logicalId} (${resource.resourceType})`);
160
- }
161
- }
162
- }
163
- return chain;
164
- }
165
- generateRemediation(rootCause) {
166
- const suggestions = [];
167
- // Add pattern-based suggestions
168
- for (const pattern of this.knownErrorPatterns) {
169
- if (pattern.category === rootCause.category) {
170
- suggestions.push(...pattern.remediation);
171
- break;
172
- }
173
- }
174
- // Add resource-specific suggestions
175
- if (rootCause.resource.resourceType.includes("IAM")) {
176
- suggestions.push("Review IAM policies and trust relationships");
177
- }
178
- else if (rootCause.resource.resourceType.includes("Lambda")) {
179
- suggestions.push("Check Lambda function configuration and runtime");
180
- }
181
- else if (rootCause.resource.resourceType.includes("ECS")) {
182
- suggestions.push("Verify ECS task definition and container configuration");
183
- }
184
- // Add general suggestions if no specific ones found
185
- if (suggestions.length === 0) {
186
- suggestions.push("Review the CloudFormation console for detailed error messages", "Check the resource configuration in your CDK code", "Ensure all dependencies are properly defined");
187
- }
188
- return suggestions;
189
- }
190
- generateSummary(rootCause, failedResources) {
191
- const resourceType = this.simplifyResourceType(rootCause.resource.resourceType);
192
- const failureCount = failedResources.length;
193
- let summary = `Deployment failed: ${resourceType} "${rootCause.resource.logicalId}" `;
194
- switch (rootCause.category) {
195
- case "permissions":
196
- summary += "failed due to insufficient permissions";
197
- break;
198
- case "validation":
199
- summary += "failed validation";
200
- break;
201
- case "dependency":
202
- summary += "has missing or invalid dependencies";
203
- break;
204
- case "limit":
205
- summary += "exceeded AWS service limits";
206
- break;
207
- case "network":
208
- summary += "encountered network issues";
209
- break;
210
- default:
211
- summary += "failed to create";
212
- }
213
- if (failureCount > 1) {
214
- summary += ` (${failureCount - 1} dependent resources also failed)`;
215
- }
216
- return summary;
217
- }
218
- simplifyResourceType(resourceType) {
219
- return resourceType
220
- .replace("AWS::", "")
221
- .replace("::", " ")
222
- .replace(/([A-Z])/g, " $1")
223
- .trim();
224
- }
225
- isFailedStatus(status) {
226
- return status.includes("FAILED");
227
- }
228
- }
@@ -1,26 +0,0 @@
1
- export declare class AWSError extends Error {
2
- readonly code?: string | undefined;
3
- constructor(message: string, code?: string | undefined);
4
- }
5
- export declare class NoRolesFoundError extends AWSError {
6
- constructor(accountId?: string);
7
- }
8
- export declare class InvalidCredentialsError extends AWSError {
9
- constructor(message: string);
10
- }
11
- export declare class SSOTokenExpiredError extends AWSError {
12
- constructor();
13
- }
14
- export declare class MissingRegionError extends AWSError {
15
- constructor();
16
- }
17
- export declare class ProfileNotFoundError extends AWSError {
18
- constructor(profileName: string);
19
- }
20
- export declare function isAWSError(error: unknown): error is AWSError;
21
- export declare function isNoRolesFoundError(error: unknown): error is NoRolesFoundError;
22
- export declare function isSSOUnauthorizedError(error: unknown): boolean;
23
- export declare class CommandError extends AWSError {
24
- readonly tip?: string;
25
- constructor(message: string, tip?: string);
26
- }
@@ -1,59 +0,0 @@
1
- export class AWSError extends Error {
2
- code;
3
- constructor(message, code) {
4
- super(message);
5
- this.code = code;
6
- this.name = this.constructor.name;
7
- Object.setPrototypeOf(this, new.target.prototype);
8
- }
9
- }
10
- export class NoRolesFoundError extends AWSError {
11
- constructor(accountId) {
12
- const message = accountId
13
- ? `No roles found for account ${accountId}`
14
- : "No roles found for this account";
15
- super(message, "NO_ROLES_FOUND");
16
- }
17
- }
18
- export class InvalidCredentialsError extends AWSError {
19
- constructor(message) {
20
- super(message, "INVALID_CREDENTIALS");
21
- }
22
- }
23
- export class SSOTokenExpiredError extends AWSError {
24
- constructor() {
25
- super("SSO token has expired", "SSO_TOKEN_EXPIRED");
26
- }
27
- }
28
- export class MissingRegionError extends AWSError {
29
- constructor() {
30
- super("Region is missing in AWS configuration and environment", "MISSING_REGION");
31
- }
32
- }
33
- export class ProfileNotFoundError extends AWSError {
34
- constructor(profileName) {
35
- super(`AWS profile '${profileName}' not found`, "PROFILE_NOT_FOUND");
36
- }
37
- }
38
- export function isAWSError(error) {
39
- return error instanceof AWSError;
40
- }
41
- export function isNoRolesFoundError(error) {
42
- return error instanceof NoRolesFoundError;
43
- }
44
- export function isSSOUnauthorizedError(error) {
45
- if (!error || typeof error !== "object")
46
- return false;
47
- return (("name" in error && error.name === "UnauthorizedException") ||
48
- ("Code" in error && error.Code === "UnauthorizedException") ||
49
- ("__type" in error &&
50
- typeof error.__type === "string" &&
51
- error.__type.includes("UnauthorizedException")));
52
- }
53
- export class CommandError extends AWSError {
54
- tip;
55
- constructor(message, tip) {
56
- super(message, "COMMAND_ERROR");
57
- this.tip = tip;
58
- }
59
- }
@@ -1,4 +0,0 @@
1
- /**
2
- * Async check for file existence. Replaces blocking existsSync().
3
- */
4
- export declare function fileExists(filePath: string): Promise<boolean>;
@@ -1,16 +0,0 @@
1
- /**
2
- * Async file system helpers.
3
- */
4
- import { access, constants } from "fs/promises";
5
- /**
6
- * Async check for file existence. Replaces blocking existsSync().
7
- */
8
- export async function fileExists(filePath) {
9
- try {
10
- await access(filePath, constants.F_OK);
11
- return true;
12
- }
13
- catch {
14
- return false;
15
- }
16
- }
@@ -1,31 +0,0 @@
1
- /**
2
- * Security helpers for spawn operations
3
- *
4
- * Provides environment variable filtering and credential masking
5
- * to prevent command injection and credential leakage.
6
- */
7
- /**
8
- * Environment variables that MUST NOT be passed from user input to spawned processes.
9
- * These can be exploited for:
10
- * - Code execution hijacking (PATH, NODE_OPTIONS)
11
- * - Dynamic linker injection (LD_PRELOAD, DYLD_INSERT_LIBRARIES)
12
- * - Interpreter code injection (PYTHONPATH, RUBYLIB)
13
- * - Credential/identity hijacking (HOME, AWS_CONFIG_FILE)
14
- * - Shell injection (BASH_ENV, ENV)
15
- */
16
- export declare const DANGEROUS_ENV_VARS: Set<string>;
17
- /**
18
- * Filter dangerous environment variables from a record.
19
- * Returns a new object with only safe environment variables.
20
- */
21
- export declare function filterDangerousEnvVars(env: Record<string, string | undefined>): Record<string, string | undefined>;
22
- /**
23
- * Mask sensitive information in output strings to prevent credential leakage.
24
- * Patterns: postgres://user:pass@host, password=xxx, secret=xxx, apikey=xxx
25
- */
26
- export declare function maskSensitiveOutput(output: string): string;
27
- /**
28
- * Parse a shell command string into an array of arguments.
29
- * Handles single quotes, double quotes, and escaped characters.
30
- */
31
- export declare function parseShellArgs(command: string): string[];
@@ -1,124 +0,0 @@
1
- /**
2
- * Security helpers for spawn operations
3
- *
4
- * Provides environment variable filtering and credential masking
5
- * to prevent command injection and credential leakage.
6
- */
7
- /**
8
- * Environment variables that MUST NOT be passed from user input to spawned processes.
9
- * These can be exploited for:
10
- * - Code execution hijacking (PATH, NODE_OPTIONS)
11
- * - Dynamic linker injection (LD_PRELOAD, DYLD_INSERT_LIBRARIES)
12
- * - Interpreter code injection (PYTHONPATH, RUBYLIB)
13
- * - Credential/identity hijacking (HOME, AWS_CONFIG_FILE)
14
- * - Shell injection (BASH_ENV, ENV)
15
- */
16
- export const DANGEROUS_ENV_VARS = new Set([
17
- // Execution hijacking
18
- // NOTE: PATH is intentionally NOT included here - it's required for spawn() to find executables
19
- // See: aiDocs/patterns/spawn-security-pattern.md for rationale
20
- "NODE_OPTIONS",
21
- "NODE_PATH",
22
- "NODE_EXTRA_CA_CERTS",
23
- "NODE_DEBUG",
24
- "NODE_PRESERVE_SYMLINKS",
25
- // Dynamic linker injection (Linux)
26
- "LD_PRELOAD",
27
- "LD_LIBRARY_PATH",
28
- "LD_AUDIT",
29
- "LD_BIND_NOW",
30
- // Dynamic linker injection (macOS)
31
- "DYLD_INSERT_LIBRARIES",
32
- "DYLD_LIBRARY_PATH",
33
- "DYLD_FRAMEWORK_PATH",
34
- // Interpreter code injection
35
- "PYTHONPATH",
36
- "PYTHONSTARTUP",
37
- "PERL5LIB",
38
- "PERL5OPT",
39
- "RUBYLIB",
40
- "RUBYOPT",
41
- // Credential/identity hijacking
42
- "HOME",
43
- "XDG_CONFIG_HOME",
44
- "AWS_SHARED_CREDENTIALS_FILE",
45
- "AWS_CONFIG_FILE",
46
- // Shell injection
47
- "SHELL",
48
- "BASH_ENV",
49
- "ENV",
50
- "ZDOTDIR"
51
- ]);
52
- /**
53
- * Filter dangerous environment variables from a record.
54
- * Returns a new object with only safe environment variables.
55
- */
56
- export function filterDangerousEnvVars(env) {
57
- return Object.fromEntries(Object.entries(env).filter(([key]) => !DANGEROUS_ENV_VARS.has(key.toUpperCase())));
58
- }
59
- /**
60
- * Mask sensitive information in output strings to prevent credential leakage.
61
- * Patterns: postgres://user:pass@host, password=xxx, secret=xxx, apikey=xxx
62
- */
63
- export function maskSensitiveOutput(output) {
64
- return (output
65
- // Mask postgres/mysql connection strings with credentials
66
- .replace(/(\w+:\/\/[^:]+:)[^@]+(@)/gi, "$1***$2")
67
- // Mask common credential patterns
68
- .replace(/(password|passwd|secret|api[_-]?key|token|auth|credential)[=:]["']?[^\s"']+/gi, "$1=***")
69
- // Mask GitHub tokens (ghu_, ghs_, ghp_, github_pat_) appearing as bare values
70
- .replace(/\b(ghu_|ghs_|ghp_|github_pat_)[A-Za-z0-9_]+/g, "***")
71
- // Mask AWS secret access keys (40 chars, base64-ish) — only when preceded
72
- // by a known credential context to avoid false-positive masking of ARNs,
73
- // physical resource IDs, and other legitimate 40-char strings.
74
- .replace(/(?<=AWS_SECRET_ACCESS_KEY=|SecretAccessKey[=:]\s*|"secretAccessKey":\s*")[A-Za-z0-9/+=]{40}/g, "***"));
75
- }
76
- /**
77
- * Parse a shell command string into an array of arguments.
78
- * Handles single quotes, double quotes, and escaped characters.
79
- */
80
- export function parseShellArgs(command) {
81
- const args = [];
82
- let current = "";
83
- let inSingleQuote = false;
84
- let inDoubleQuote = false;
85
- let escaped = false;
86
- for (const char of command) {
87
- if (escaped) {
88
- current += char;
89
- escaped = false;
90
- continue;
91
- }
92
- if (char === "\\") {
93
- escaped = true;
94
- continue;
95
- }
96
- if (char === "'" && !inDoubleQuote) {
97
- inSingleQuote = !inSingleQuote;
98
- continue;
99
- }
100
- if (char === '"' && !inSingleQuote) {
101
- inDoubleQuote = !inDoubleQuote;
102
- continue;
103
- }
104
- if (char === " " && !inSingleQuote && !inDoubleQuote) {
105
- if (current) {
106
- args.push(current);
107
- current = "";
108
- }
109
- continue;
110
- }
111
- current += char;
112
- }
113
- if (inSingleQuote || inDoubleQuote) {
114
- // Unbalanced quotes — include the partial token. Callers should validate
115
- // their input if quote-balancing is required.
116
- if (current) {
117
- args.push(current);
118
- }
119
- }
120
- else if (current) {
121
- args.push(current);
122
- }
123
- return args;
124
- }
@@ -1,2 +0,0 @@
1
- /** Lazily creates one instance per factory — shared singleton helper. */
2
- export declare function singleton<T>(factory: () => T): () => T;
@@ -1,9 +0,0 @@
1
- /** Lazily creates one instance per factory — shared singleton helper. */
2
- export function singleton(factory) {
3
- let instance;
4
- return () => {
5
- if (instance === undefined)
6
- instance = factory();
7
- return instance;
8
- };
9
- }
@@ -1,4 +0,0 @@
1
- /**
2
- * Delay execution for the given number of milliseconds.
3
- */
4
- export declare const sleep: (ms: number) => Promise<void>;
@@ -1,4 +0,0 @@
1
- /**
2
- * Delay execution for the given number of milliseconds.
3
- */
4
- export const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));