@aws/ml-container-creator 0.2.1 → 0.2.2

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 (36) hide show
  1. package/bin/cli.js +88 -86
  2. package/config/bootstrap-stack.json +211 -0
  3. package/config/parameter-schema.json +88 -0
  4. package/infra/ci-harness/bin/ci-harness.ts +26 -0
  5. package/infra/ci-harness/buildspec.yml +352 -0
  6. package/infra/ci-harness/cdk.json +27 -0
  7. package/infra/ci-harness/lambda/scanner/index.ts +199 -0
  8. package/infra/ci-harness/lib/ci-harness-stack.ts +609 -0
  9. package/infra/ci-harness/package-lock.json +3979 -0
  10. package/infra/ci-harness/package.json +32 -0
  11. package/infra/ci-harness/tsconfig.json +38 -0
  12. package/package.json +13 -3
  13. package/src/app.js +318 -318
  14. package/src/copy-tpl.js +19 -19
  15. package/src/lib/asset-manager.js +74 -74
  16. package/src/lib/aws-profile-parser.js +45 -45
  17. package/src/lib/bootstrap-command-handler.js +560 -547
  18. package/src/lib/bootstrap-config.js +45 -45
  19. package/src/lib/ci-register-helpers.js +19 -19
  20. package/src/lib/ci-report-helpers.js +37 -37
  21. package/src/lib/ci-stage-helpers.js +49 -49
  22. package/src/lib/comment-generator.js +4 -4
  23. package/src/lib/config-manager.js +105 -105
  24. package/src/lib/deployment-config-resolver.js +10 -10
  25. package/src/lib/deployment-registry.js +153 -153
  26. package/src/lib/engine-prefix-resolver.js +8 -8
  27. package/src/lib/key-value-parser.js +6 -6
  28. package/src/lib/manifest-cli.js +108 -108
  29. package/src/lib/prompt-runner.js +224 -224
  30. package/src/lib/prompts.js +121 -121
  31. package/src/lib/registry-command-handler.js +174 -174
  32. package/src/lib/registry-loader.js +52 -52
  33. package/src/lib/sensitive-redactor.js +9 -9
  34. package/src/lib/template-engine.js +1 -1
  35. package/src/lib/template-manager.js +62 -62
  36. package/src/prompt-adapter.js +18 -18
@@ -24,13 +24,13 @@ export const STAGE_ORDER = [
24
24
  'register',
25
25
  'teardown',
26
26
  'update'
27
- ]
27
+ ];
28
28
 
29
29
  /**
30
30
  * Stages that always execute regardless of prior failures.
31
31
  * Teardown cleans up resources; Update writes results to DynamoDB.
32
32
  */
33
- export const ALWAYS_RUN_STAGES = ['teardown', 'update']
33
+ export const ALWAYS_RUN_STAGES = ['teardown', 'update'];
34
34
 
35
35
  /**
36
36
  * Parse a DynamoDB-format stageResults map into plain JavaScript objects.
@@ -45,14 +45,14 @@ export const ALWAYS_RUN_STAGES = ['teardown', 'update']
45
45
  */
46
46
  export function parseStageResults(stageResultsMap) {
47
47
  if (!stageResultsMap || typeof stageResultsMap !== 'object') {
48
- return {}
48
+ return {};
49
49
  }
50
50
 
51
- const result = {}
51
+ const result = {};
52
52
 
53
53
  for (const [stageName, stageValue] of Object.entries(stageResultsMap)) {
54
54
  // Handle DynamoDB M (map) wrapper
55
- const inner = stageValue && stageValue.M ? stageValue.M : stageValue
55
+ const inner = stageValue && stageValue.M ? stageValue.M : stageValue;
56
56
 
57
57
  if (!inner || typeof inner !== 'object') {
58
58
  result[stageName] = {
@@ -60,8 +60,8 @@ export function parseStageResults(stageResultsMap) {
60
60
  durationSeconds: 0,
61
61
  logPointer: '',
62
62
  errorSummary: ''
63
- }
64
- continue
63
+ };
64
+ continue;
65
65
  }
66
66
 
67
67
  result[stageName] = {
@@ -69,10 +69,10 @@ export function parseStageResults(stageResultsMap) {
69
69
  durationSeconds: extractNumber(inner.durationSeconds, 0),
70
70
  logPointer: extractString(inner.logPointer, ''),
71
71
  errorSummary: extractString(inner.errorSummary, '')
72
- }
72
+ };
73
73
  }
74
74
 
75
- return result
75
+ return result;
76
76
  }
77
77
 
78
78
  /**
@@ -87,17 +87,17 @@ export function parseStageResults(stageResultsMap) {
87
87
  */
88
88
  export function computeTestStatus(stageResults) {
89
89
  if (!stageResults || typeof stageResults !== 'object') {
90
- return 'pass'
90
+ return 'pass';
91
91
  }
92
92
 
93
93
  for (const stage of STAGE_ORDER) {
94
- const result = stageResults[stage]
94
+ const result = stageResults[stage];
95
95
  if (result && result.status === 'fail') {
96
- return `fail-${stage}`
96
+ return `fail-${stage}`;
97
97
  }
98
98
  }
99
99
 
100
- return 'pass'
100
+ return 'pass';
101
101
  }
102
102
 
103
103
  /**
@@ -113,29 +113,29 @@ export function computeTestStatus(stageResults) {
113
113
  */
114
114
  export function applySkipLogic(stageResults, failedStage) {
115
115
  if (!failedStage || !stageResults) {
116
- return stageResults || {}
116
+ return stageResults || {};
117
117
  }
118
118
 
119
- const failedIndex = STAGE_ORDER.indexOf(failedStage)
119
+ const failedIndex = STAGE_ORDER.indexOf(failedStage);
120
120
  if (failedIndex === -1) {
121
- return stageResults
121
+ return stageResults;
122
122
  }
123
123
 
124
124
  // Skip all stages after the failed one, except always-run stages
125
125
  for (let i = failedIndex + 1; i < STAGE_ORDER.length; i++) {
126
- const stage = STAGE_ORDER[i]
126
+ const stage = STAGE_ORDER[i];
127
127
  if (ALWAYS_RUN_STAGES.includes(stage)) {
128
- continue
128
+ continue;
129
129
  }
130
130
  stageResults[stage] = {
131
131
  status: 'skip',
132
132
  durationSeconds: 0,
133
133
  logPointer: '',
134
134
  errorSummary: ''
135
- }
135
+ };
136
136
  }
137
137
 
138
- return stageResults
138
+ return stageResults;
139
139
  }
140
140
 
141
141
  /**
@@ -151,66 +151,66 @@ export function applySkipLogic(stageResults, failedStage) {
151
151
  * @returns {string[]} return.errors - Array of validation error messages
152
152
  */
153
153
  export function validateStageResultStructure(stageResults) {
154
- const errors = []
154
+ const errors = [];
155
155
 
156
156
  if (!stageResults || typeof stageResults !== 'object') {
157
- return { valid: false, errors: ['stageResults is null or not an object'] }
157
+ return { valid: false, errors: ['stageResults is null or not an object'] };
158
158
  }
159
159
 
160
- const stageKeys = Object.keys(stageResults)
160
+ const stageKeys = Object.keys(stageResults);
161
161
 
162
162
  // Check for exactly 7 entries
163
163
  if (stageKeys.length !== 7) {
164
- errors.push(`Expected 7 stage entries, found ${stageKeys.length}`)
164
+ errors.push(`Expected 7 stage entries, found ${stageKeys.length}`);
165
165
  }
166
166
 
167
167
  // Check all required stages are present
168
168
  for (const stage of STAGE_ORDER) {
169
169
  if (!(stage in stageResults)) {
170
- errors.push(`Missing required stage: ${stage}`)
170
+ errors.push(`Missing required stage: ${stage}`);
171
171
  }
172
172
  }
173
173
 
174
174
  // Check for unexpected stages
175
175
  for (const key of stageKeys) {
176
176
  if (!STAGE_ORDER.includes(key)) {
177
- errors.push(`Unexpected stage: ${key}`)
177
+ errors.push(`Unexpected stage: ${key}`);
178
178
  }
179
179
  }
180
180
 
181
181
  // Validate each stage entry has required fields
182
182
  for (const stage of STAGE_ORDER) {
183
- const entry = stageResults[stage]
184
- if (!entry) continue
183
+ const entry = stageResults[stage];
184
+ if (!entry) continue;
185
185
 
186
186
  if (!('status' in entry)) {
187
- errors.push(`Stage '${stage}' missing required field: status`)
187
+ errors.push(`Stage '${stage}' missing required field: status`);
188
188
  } else if (!['pass', 'fail', 'skip'].includes(entry.status)) {
189
- errors.push(`Stage '${stage}' has invalid status: '${entry.status}'`)
189
+ errors.push(`Stage '${stage}' has invalid status: '${entry.status}'`);
190
190
  }
191
191
 
192
192
  if (!('durationSeconds' in entry)) {
193
- errors.push(`Stage '${stage}' missing required field: durationSeconds`)
193
+ errors.push(`Stage '${stage}' missing required field: durationSeconds`);
194
194
  } else if (typeof entry.durationSeconds !== 'number' || entry.durationSeconds < 0) {
195
- errors.push(`Stage '${stage}' has invalid durationSeconds: ${entry.durationSeconds}`)
195
+ errors.push(`Stage '${stage}' has invalid durationSeconds: ${entry.durationSeconds}`);
196
196
  }
197
197
 
198
198
  if (!('logPointer' in entry)) {
199
- errors.push(`Stage '${stage}' missing required field: logPointer`)
199
+ errors.push(`Stage '${stage}' missing required field: logPointer`);
200
200
  }
201
201
 
202
202
  // errorSummary is required when status is 'fail'
203
203
  if (entry.status === 'fail' && !('errorSummary' in entry)) {
204
- errors.push(`Stage '${stage}' has status 'fail' but missing errorSummary`)
204
+ errors.push(`Stage '${stage}' has status 'fail' but missing errorSummary`);
205
205
  }
206
206
 
207
207
  // errorSummary must be at most 500 characters
208
208
  if (entry.errorSummary && entry.errorSummary.length > 500) {
209
- errors.push(`Stage '${stage}' errorSummary exceeds 500 characters (${entry.errorSummary.length})`)
209
+ errors.push(`Stage '${stage}' errorSummary exceeds 500 characters (${entry.errorSummary.length})`);
210
210
  }
211
211
  }
212
212
 
213
- return { valid: errors.length === 0, errors }
213
+ return { valid: errors.length === 0, errors };
214
214
  }
215
215
 
216
216
  /**
@@ -223,20 +223,20 @@ export function validateStageResultStructure(stageResults) {
223
223
  */
224
224
  export function extractErrorSummaries(stageResults) {
225
225
  if (!stageResults || typeof stageResults !== 'object') {
226
- return []
226
+ return [];
227
227
  }
228
228
 
229
- const summaries = []
229
+ const summaries = [];
230
230
  for (const stage of STAGE_ORDER) {
231
- const entry = stageResults[stage]
231
+ const entry = stageResults[stage];
232
232
  if (entry && entry.status === 'fail' && entry.errorSummary) {
233
233
  summaries.push({
234
234
  stage,
235
235
  errorSummary: entry.errorSummary
236
- })
236
+ });
237
237
  }
238
238
  }
239
- return summaries
239
+ return summaries;
240
240
  }
241
241
 
242
242
  // --- Internal helpers ---
@@ -248,10 +248,10 @@ export function extractErrorSummaries(stageResults) {
248
248
  * @returns {string}
249
249
  */
250
250
  function extractString(value, defaultValue) {
251
- if (value === undefined || value === null) return defaultValue
252
- if (typeof value === 'string') return value
253
- if (value.S !== undefined) return value.S
254
- return defaultValue
251
+ if (value === undefined || value === null) return defaultValue;
252
+ if (typeof value === 'string') return value;
253
+ if (value.S !== undefined) return value.S;
254
+ return defaultValue;
255
255
  }
256
256
 
257
257
  /**
@@ -261,8 +261,8 @@ function extractString(value, defaultValue) {
261
261
  * @returns {number}
262
262
  */
263
263
  function extractNumber(value, defaultValue) {
264
- if (value === undefined || value === null) return defaultValue
265
- if (typeof value === 'number') return value
266
- if (value.N !== undefined) return Number(value.N)
267
- return defaultValue
264
+ if (value === undefined || value === null) return defaultValue;
265
+ if (typeof value === 'number') return value;
266
+ if (value.N !== undefined) return Number(value.N);
267
+ return defaultValue;
268
268
  }
@@ -48,7 +48,7 @@ export default class CommentGenerator {
48
48
  return '# No accelerator requirements specified';
49
49
  }
50
50
 
51
- const frameworkLabel = config.backend || config.framework
51
+ const frameworkLabel = config.backend || config.framework;
52
52
  const lines = [
53
53
  '# Accelerator Compatibility Information',
54
54
  `# Framework: ${frameworkLabel} ${config.version}`,
@@ -108,7 +108,7 @@ export default class CommentGenerator {
108
108
  }
109
109
 
110
110
  // Group environment variables by category
111
- const frameworkLabel = config.backend || config.framework
111
+ const frameworkLabel = config.backend || config.framework;
112
112
  const groups = this._groupEnvVars(config.envVars, frameworkLabel);
113
113
 
114
114
  for (const [category, vars] of Object.entries(groups)) {
@@ -196,7 +196,7 @@ export default class CommentGenerator {
196
196
  ];
197
197
 
198
198
  // Framework-specific tips
199
- const frameworkLabel = config.backend || config.framework
199
+ const frameworkLabel = config.backend || config.framework;
200
200
  const frameworkTips = this._getFrameworkTroubleshootingTips(frameworkLabel);
201
201
  if (frameworkTips.length > 0) {
202
202
  lines.push(`# ${frameworkLabel} Common Issues:`);
@@ -260,7 +260,7 @@ export default class CommentGenerator {
260
260
  * @returns {string} Deployment header comment
261
261
  */
262
262
  generateDeploymentHeader(config) {
263
- const frameworkLabel = config.backend || config.framework
263
+ const frameworkLabel = config.backend || config.framework;
264
264
  const lines = [
265
265
  '#!/bin/bash',
266
266
  '#',