@aws/ml-container-creator 0.2.1 → 0.2.3

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
package/src/copy-tpl.js CHANGED
@@ -1,10 +1,10 @@
1
1
  // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
 
4
- import ejs from 'ejs'
5
- import { globSync } from 'tinyglobby'
6
- import fs from 'fs'
7
- import path from 'path'
4
+ import ejs from 'ejs';
5
+ import { globSync } from 'tinyglobby';
6
+ import fs from 'fs';
7
+ import path from 'path';
8
8
 
9
9
  /**
10
10
  * Binary file extensions that should be copied without EJS rendering.
@@ -16,7 +16,7 @@ const BINARY_EXTENSIONS = new Set([
16
16
  '.pdf',
17
17
  '.exe', '.dll', '.so', '.dylib',
18
18
  '.pyc', '.pyo', '.class', '.jar', '.war', '.ear'
19
- ])
19
+ ]);
20
20
 
21
21
  /**
22
22
  * Determines whether a file is binary based on its extension.
@@ -25,8 +25,8 @@ const BINARY_EXTENSIONS = new Set([
25
25
  * @returns {boolean} True if the file has a known binary extension
26
26
  */
27
27
  function isBinaryFile(filePath) {
28
- const ext = path.extname(filePath).toLowerCase()
29
- return BINARY_EXTENSIONS.has(ext)
28
+ const ext = path.extname(filePath).toLowerCase();
29
+ return BINARY_EXTENSIONS.has(ext);
30
30
  }
31
31
 
32
32
  /**
@@ -47,31 +47,31 @@ export function copyTpl(templateDir, destDir, vars, ignorePatterns = []) {
47
47
  ignore: ignorePatterns,
48
48
  dot: true,
49
49
  onlyFiles: true
50
- })
50
+ });
51
51
 
52
52
  for (const file of files) {
53
- const src = path.join(templateDir, file)
54
- const dest = path.join(destDir, file)
53
+ const src = path.join(templateDir, file);
54
+ const dest = path.join(destDir, file);
55
55
 
56
- fs.mkdirSync(path.dirname(dest), { recursive: true })
56
+ fs.mkdirSync(path.dirname(dest), { recursive: true });
57
57
 
58
58
  if (isBinaryFile(file)) {
59
- fs.copyFileSync(src, dest)
60
- continue
59
+ fs.copyFileSync(src, dest);
60
+ continue;
61
61
  }
62
62
 
63
- const content = fs.readFileSync(src, 'utf8')
63
+ const content = fs.readFileSync(src, 'utf8');
64
64
 
65
- let rendered
65
+ let rendered;
66
66
  try {
67
- rendered = ejs.render(content, vars, { filename: src })
67
+ rendered = ejs.render(content, vars, { filename: src });
68
68
  } catch (err) {
69
- const line = err.line ? ` (line ${err.line})` : ''
69
+ const line = err.line ? ` (line ${err.line})` : '';
70
70
  throw new Error(
71
71
  `EJS rendering failed for "${file}"${line}: ${err.message}`
72
- )
72
+ );
73
73
  }
74
74
 
75
- fs.writeFileSync(dest, rendered)
75
+ fs.writeFileSync(dest, rendered);
76
76
  }
77
77
  }
@@ -29,11 +29,11 @@
29
29
  * }
30
30
  */
31
31
 
32
- import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'node:fs'
33
- import { join, dirname } from 'node:path'
34
- import { homedir } from 'node:os'
32
+ import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'node:fs';
33
+ import { join, dirname } from 'node:path';
34
+ import { homedir } from 'node:os';
35
35
 
36
- const SCHEMA_VERSION = '2026-05-04'
36
+ const SCHEMA_VERSION = '2026-05-04';
37
37
 
38
38
  const VALID_RESOURCE_TYPES = [
39
39
  'sagemaker-endpoint',
@@ -48,11 +48,11 @@ const VALID_RESOURCE_TYPES = [
48
48
  'sns-topic',
49
49
  'k8s-deployment',
50
50
  'k8s-service'
51
- ]
51
+ ];
52
52
 
53
- const VALID_STATUSES = ['active', 'deleted', 'unknown']
53
+ const VALID_STATUSES = ['active', 'deleted', 'unknown'];
54
54
 
55
- export { SCHEMA_VERSION, VALID_RESOURCE_TYPES, VALID_STATUSES }
55
+ export { SCHEMA_VERSION, VALID_RESOURCE_TYPES, VALID_STATUSES };
56
56
 
57
57
  export default class AssetManager {
58
58
  /**
@@ -62,8 +62,8 @@ export default class AssetManager {
62
62
  * Defaults to ~/.ml-container-creator
63
63
  */
64
64
  constructor(profileName, options = {}) {
65
- this.profileName = profileName
66
- this.configDir = options.configDir || join(homedir(), '.ml-container-creator')
65
+ this.profileName = profileName;
66
+ this.configDir = options.configDir || join(homedir(), '.ml-container-creator');
67
67
  }
68
68
 
69
69
  /**
@@ -72,7 +72,7 @@ export default class AssetManager {
72
72
  * @returns {string} Absolute path to the manifest JSON file
73
73
  */
74
74
  get manifestPath() {
75
- return join(this.configDir, 'manifests', `${this.profileName}.json`)
75
+ return join(this.configDir, 'manifests', `${this.profileName}.json`);
76
76
  }
77
77
 
78
78
  /**
@@ -87,34 +87,34 @@ export default class AssetManager {
87
87
  */
88
88
  _readManifest() {
89
89
  if (!existsSync(this.manifestPath)) {
90
- return { schemaVersion: SCHEMA_VERSION, resources: [] }
90
+ return { schemaVersion: SCHEMA_VERSION, resources: [] };
91
91
  }
92
92
 
93
- const raw = readFileSync(this.manifestPath, 'utf8')
93
+ const raw = readFileSync(this.manifestPath, 'utf8');
94
94
 
95
- let data
95
+ let data;
96
96
  try {
97
- data = JSON.parse(raw)
97
+ data = JSON.parse(raw);
98
98
  } catch (err) {
99
99
  throw new Error(
100
100
  `Invalid JSON in manifest file ${this.manifestPath}: ${err.message}`
101
- )
101
+ );
102
102
  }
103
103
 
104
104
  if (!data.schemaVersion) {
105
105
  console.warn(
106
106
  `Warning: Manifest file ${this.manifestPath} has no schemaVersion. Attempting best-effort read.`
107
- )
107
+ );
108
108
  } else if (data.schemaVersion !== SCHEMA_VERSION) {
109
109
  console.warn(
110
110
  `Warning: Manifest file ${this.manifestPath} has unrecognized schemaVersion "${data.schemaVersion}". Attempting best-effort read.`
111
- )
111
+ );
112
112
  }
113
113
 
114
114
  return {
115
115
  schemaVersion: data.schemaVersion || SCHEMA_VERSION,
116
116
  resources: Array.isArray(data.resources) ? data.resources : []
117
- }
117
+ };
118
118
  }
119
119
 
120
120
  /**
@@ -125,15 +125,15 @@ export default class AssetManager {
125
125
  * @param {{ schemaVersion: string, resources: Array<Object> }} manifest
126
126
  */
127
127
  _writeManifest(manifest) {
128
- const dir = dirname(this.manifestPath)
128
+ const dir = dirname(this.manifestPath);
129
129
  if (!existsSync(dir)) {
130
- mkdirSync(dir, { recursive: true })
130
+ mkdirSync(dir, { recursive: true });
131
131
  }
132
132
 
133
133
  writeFileSync(
134
134
  this.manifestPath,
135
135
  `${JSON.stringify(manifest, null, 2)}\n`
136
- )
136
+ );
137
137
  }
138
138
 
139
139
  /**
@@ -150,7 +150,7 @@ export default class AssetManager {
150
150
  * @returns {{ valid: boolean, errors: string[] }}
151
151
  */
152
152
  _validateRecord(record) {
153
- const errors = []
153
+ const errors = [];
154
154
 
155
155
  const requiredFields = [
156
156
  'resourceId',
@@ -160,11 +160,11 @@ export default class AssetManager {
160
160
  'project',
161
161
  'status',
162
162
  'metadata'
163
- ]
163
+ ];
164
164
 
165
165
  for (const field of requiredFields) {
166
166
  if (record[field] === undefined || record[field] === null) {
167
- errors.push(`Missing required field: ${field}`)
167
+ errors.push(`Missing required field: ${field}`);
168
168
  }
169
169
  }
170
170
 
@@ -172,7 +172,7 @@ export default class AssetManager {
172
172
  if (!VALID_RESOURCE_TYPES.includes(record.resourceType)) {
173
173
  errors.push(
174
174
  `Invalid resourceType: "${record.resourceType}". Must be one of: ${VALID_RESOURCE_TYPES.join(', ')}`
175
- )
175
+ );
176
176
  }
177
177
  }
178
178
 
@@ -180,7 +180,7 @@ export default class AssetManager {
180
180
  if (!VALID_STATUSES.includes(record.status)) {
181
181
  errors.push(
182
182
  `Invalid status: "${record.status}". Must be one of: ${VALID_STATUSES.join(', ')}`
183
- )
183
+ );
184
184
  }
185
185
  }
186
186
 
@@ -188,7 +188,7 @@ export default class AssetManager {
188
188
  if (!_isValidISO8601(record.createdAt)) {
189
189
  errors.push(
190
190
  `Invalid createdAt: "${record.createdAt}". Must be a valid ISO 8601 timestamp.`
191
- )
191
+ );
192
192
  }
193
193
  }
194
194
 
@@ -196,17 +196,17 @@ export default class AssetManager {
196
196
  if (!_isValidISO8601(record.lastUpdatedAt)) {
197
197
  errors.push(
198
198
  `Invalid lastUpdatedAt: "${record.lastUpdatedAt}". Must be a valid ISO 8601 timestamp.`
199
- )
199
+ );
200
200
  }
201
201
  }
202
202
 
203
203
  if (record.metadata !== undefined && record.metadata !== null) {
204
204
  if (typeof record.metadata !== 'object' || Array.isArray(record.metadata)) {
205
- errors.push('Invalid metadata: must be a non-null object.')
205
+ errors.push('Invalid metadata: must be a non-null object.');
206
206
  }
207
207
  }
208
208
 
209
- return { valid: errors.length === 0, errors }
209
+ return { valid: errors.length === 0, errors };
210
210
  }
211
211
 
212
212
  /**
@@ -219,24 +219,24 @@ export default class AssetManager {
219
219
  * @throws {Error} If the record fails validation
220
220
  */
221
221
  addResource(record) {
222
- const { valid, errors } = this._validateRecord(record)
222
+ const { valid, errors } = this._validateRecord(record);
223
223
  if (!valid) {
224
- throw new Error(`Invalid asset record: ${errors.join('; ')}`)
224
+ throw new Error(`Invalid asset record: ${errors.join('; ')}`);
225
225
  }
226
226
 
227
- const manifest = this._readManifest()
227
+ const manifest = this._readManifest();
228
228
  const existingIndex = manifest.resources.findIndex(
229
229
  r => r.resourceId === record.resourceId
230
- )
230
+ );
231
231
 
232
232
  if (existingIndex !== -1) {
233
- manifest.resources[existingIndex].lastUpdatedAt = record.lastUpdatedAt
234
- manifest.resources[existingIndex].status = record.status
233
+ manifest.resources[existingIndex].lastUpdatedAt = record.lastUpdatedAt;
234
+ manifest.resources[existingIndex].status = record.status;
235
235
  } else {
236
- manifest.resources.push(record)
236
+ manifest.resources.push(record);
237
237
  }
238
238
 
239
- this._writeManifest(manifest)
239
+ this._writeManifest(manifest);
240
240
  }
241
241
 
242
242
  /**
@@ -247,17 +247,17 @@ export default class AssetManager {
247
247
  * @returns {boolean} true if the resource was found and updated, false otherwise
248
248
  */
249
249
  updateStatus(resourceId, newStatus) {
250
- const manifest = this._readManifest()
251
- const resource = manifest.resources.find(r => r.resourceId === resourceId)
250
+ const manifest = this._readManifest();
251
+ const resource = manifest.resources.find(r => r.resourceId === resourceId);
252
252
 
253
253
  if (!resource) {
254
- return false
254
+ return false;
255
255
  }
256
256
 
257
- resource.status = newStatus
258
- resource.lastUpdatedAt = new Date().toISOString()
259
- this._writeManifest(manifest)
260
- return true
257
+ resource.status = newStatus;
258
+ resource.lastUpdatedAt = new Date().toISOString();
259
+ this._writeManifest(manifest);
260
+ return true;
261
261
  }
262
262
 
263
263
  /**
@@ -267,8 +267,8 @@ export default class AssetManager {
267
267
  * @returns {Object|null} The matching Asset_Record, or null if not found
268
268
  */
269
269
  getResource(resourceId) {
270
- const manifest = this._readManifest()
271
- return manifest.resources.find(r => r.resourceId === resourceId) || null
270
+ const manifest = this._readManifest();
271
+ return manifest.resources.find(r => r.resourceId === resourceId) || null;
272
272
  }
273
273
 
274
274
  /**
@@ -278,18 +278,18 @@ export default class AssetManager {
278
278
  * @returns {boolean} true if the resource was found and removed, false otherwise
279
279
  */
280
280
  removeResource(resourceId) {
281
- const manifest = this._readManifest()
282
- const originalLength = manifest.resources.length
281
+ const manifest = this._readManifest();
282
+ const originalLength = manifest.resources.length;
283
283
  manifest.resources = manifest.resources.filter(
284
284
  r => r.resourceId !== resourceId
285
- )
285
+ );
286
286
 
287
287
  if (manifest.resources.length === originalLength) {
288
- return false
288
+ return false;
289
289
  }
290
290
 
291
- this._writeManifest(manifest)
292
- return true
291
+ this._writeManifest(manifest);
292
+ return true;
293
293
  }
294
294
 
295
295
  /**
@@ -302,24 +302,24 @@ export default class AssetManager {
302
302
  * @returns {Array<Object>} Matching Asset_Records
303
303
  */
304
304
  listResources(filters = {}) {
305
- const manifest = this._readManifest()
305
+ const manifest = this._readManifest();
306
306
 
307
307
  if (!filters || Object.keys(filters).length === 0) {
308
- return manifest.resources
308
+ return manifest.resources;
309
309
  }
310
310
 
311
311
  return manifest.resources.filter(resource => {
312
312
  if (filters.resourceType && resource.resourceType !== filters.resourceType) {
313
- return false
313
+ return false;
314
314
  }
315
315
  if (filters.project && resource.project !== filters.project) {
316
- return false
316
+ return false;
317
317
  }
318
318
  if (filters.status && resource.status !== filters.status) {
319
- return false
319
+ return false;
320
320
  }
321
- return true
322
- })
321
+ return true;
322
+ });
323
323
  }
324
324
 
325
325
  /**
@@ -328,18 +328,18 @@ export default class AssetManager {
328
328
  * @returns {Map<string, Array<Object>>} Map of project name → Asset_Record array
329
329
  */
330
330
  getResourcesByProject() {
331
- const manifest = this._readManifest()
332
- const grouped = new Map()
331
+ const manifest = this._readManifest();
332
+ const grouped = new Map();
333
333
 
334
334
  for (const resource of manifest.resources) {
335
- const project = resource.project
335
+ const project = resource.project;
336
336
  if (!grouped.has(project)) {
337
- grouped.set(project, [])
337
+ grouped.set(project, []);
338
338
  }
339
- grouped.get(project).push(resource)
339
+ grouped.get(project).push(resource);
340
340
  }
341
341
 
342
- return grouped
342
+ return grouped;
343
343
  }
344
344
 
345
345
  /**
@@ -348,16 +348,16 @@ export default class AssetManager {
348
348
  * @returns {{ active: number, deleted: number, unknown: number }}
349
349
  */
350
350
  getStatusCounts() {
351
- const manifest = this._readManifest()
352
- const counts = { active: 0, deleted: 0, unknown: 0 }
351
+ const manifest = this._readManifest();
352
+ const counts = { active: 0, deleted: 0, unknown: 0 };
353
353
 
354
354
  for (const resource of manifest.resources) {
355
355
  if (resource.status in counts) {
356
- counts[resource.status]++
356
+ counts[resource.status]++;
357
357
  }
358
358
  }
359
359
 
360
- return counts
360
+ return counts;
361
361
  }
362
362
  }
363
363
 
@@ -374,12 +374,12 @@ export default class AssetManager {
374
374
  */
375
375
  function _isValidISO8601(str) {
376
376
  if (typeof str !== 'string' || str.length === 0) {
377
- return false
377
+ return false;
378
378
  }
379
- const date = new Date(str)
379
+ const date = new Date(str);
380
380
  if (isNaN(date.getTime())) {
381
- return false
381
+ return false;
382
382
  }
383
383
  // Ensure the string looks like an ISO 8601 timestamp (not just any parseable date string)
384
- return /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/.test(str)
384
+ return /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/.test(str);
385
385
  }
@@ -15,9 +15,9 @@
15
15
  * - 'default' is always sorted first if present
16
16
  */
17
17
 
18
- import { readFileSync, existsSync } from 'node:fs'
19
- import { join } from 'node:path'
20
- import { homedir } from 'node:os'
18
+ import { readFileSync, existsSync } from 'node:fs';
19
+ import { join } from 'node:path';
20
+ import { homedir } from 'node:os';
21
21
 
22
22
  export default class AwsProfileParser {
23
23
  /**
@@ -26,8 +26,8 @@ export default class AwsProfileParser {
26
26
  * @param {string} [options.credentialsPath] - Override path to ~/.aws/credentials
27
27
  */
28
28
  constructor(options = {}) {
29
- this._configPath = options.configPath || null
30
- this._credentialsPath = options.credentialsPath || null
29
+ this._configPath = options.configPath || null;
30
+ this._credentialsPath = options.credentialsPath || null;
31
31
  }
32
32
 
33
33
  /**
@@ -37,18 +37,18 @@ export default class AwsProfileParser {
37
37
  * @returns {string[]} Profile names, with 'default' first if it exists
38
38
  */
39
39
  getProfiles() {
40
- const configProfiles = this._getProfilesFromConfig()
41
- const credentialsProfiles = this._getProfilesFromCredentials()
40
+ const configProfiles = this._getProfilesFromConfig();
41
+ const credentialsProfiles = this._getProfilesFromCredentials();
42
42
 
43
- const allNames = new Set([...configProfiles, ...credentialsProfiles])
43
+ const allNames = new Set([...configProfiles, ...credentialsProfiles]);
44
44
 
45
45
  const sorted = [...allNames].sort((a, b) => {
46
- if (a === 'default') return -1
47
- if (b === 'default') return 1
48
- return a.localeCompare(b)
49
- })
46
+ if (a === 'default') return -1;
47
+ if (b === 'default') return 1;
48
+ return a.localeCompare(b);
49
+ });
50
50
 
51
- return sorted
51
+ return sorted;
52
52
  }
53
53
 
54
54
  /**
@@ -58,52 +58,52 @@ export default class AwsProfileParser {
58
58
  * @returns {Map<string, Object>} Map of section names to parsed key-value pairs
59
59
  */
60
60
  _parseIniFile(filePath) {
61
- const sections = new Map()
61
+ const sections = new Map();
62
62
 
63
63
  if (!existsSync(filePath)) {
64
- return sections
64
+ return sections;
65
65
  }
66
66
 
67
- let content
67
+ let content;
68
68
  try {
69
- content = readFileSync(filePath, 'utf8')
69
+ content = readFileSync(filePath, 'utf8');
70
70
  } catch {
71
- return sections
71
+ return sections;
72
72
  }
73
73
 
74
- let currentSection = null
75
- const lines = content.split(/\r?\n/)
74
+ let currentSection = null;
75
+ const lines = content.split(/\r?\n/);
76
76
 
77
77
  for (const rawLine of lines) {
78
- const line = rawLine.trim()
78
+ const line = rawLine.trim();
79
79
 
80
80
  // Skip empty lines and comments
81
81
  if (!line || line.startsWith('#') || line.startsWith(';')) {
82
- continue
82
+ continue;
83
83
  }
84
84
 
85
85
  // Check for section header
86
- const sectionMatch = line.match(/^\[([^\]]+)\]$/)
86
+ const sectionMatch = line.match(/^\[([^\]]+)\]$/);
87
87
  if (sectionMatch) {
88
- currentSection = sectionMatch[1].trim()
88
+ currentSection = sectionMatch[1].trim();
89
89
  if (!sections.has(currentSection)) {
90
- sections.set(currentSection, {})
90
+ sections.set(currentSection, {});
91
91
  }
92
- continue
92
+ continue;
93
93
  }
94
94
 
95
95
  // Parse key = value pairs
96
96
  if (currentSection) {
97
- const kvMatch = line.match(/^([^=]+?)=(.*)$/)
97
+ const kvMatch = line.match(/^([^=]+?)=(.*)$/);
98
98
  if (kvMatch) {
99
- const key = kvMatch[1].trim()
100
- const value = kvMatch[2].trim()
101
- sections.get(currentSection)[key] = value
99
+ const key = kvMatch[1].trim();
100
+ const value = kvMatch[2].trim();
101
+ sections.get(currentSection)[key] = value;
102
102
  }
103
103
  }
104
104
  }
105
105
 
106
- return sections
106
+ return sections;
107
107
  }
108
108
 
109
109
  /**
@@ -115,26 +115,26 @@ export default class AwsProfileParser {
115
115
  * @returns {string[]} Array of profile names
116
116
  */
117
117
  _extractProfileNames(parsed, isConfig = false) {
118
- const names = []
118
+ const names = [];
119
119
 
120
120
  for (const sectionName of parsed.keys()) {
121
121
  if (isConfig) {
122
122
  // ~/.aws/config uses [profile name] except for [default]
123
123
  if (sectionName === 'default') {
124
- names.push('default')
124
+ names.push('default');
125
125
  } else if (sectionName.startsWith('profile ')) {
126
- const name = sectionName.slice('profile '.length).trim()
126
+ const name = sectionName.slice('profile '.length).trim();
127
127
  if (name) {
128
- names.push(name)
128
+ names.push(name);
129
129
  }
130
130
  }
131
131
  } else {
132
132
  // ~/.aws/credentials uses [name] directly
133
- names.push(sectionName)
133
+ names.push(sectionName);
134
134
  }
135
135
  }
136
136
 
137
- return names
137
+ return names;
138
138
  }
139
139
 
140
140
  /**
@@ -143,7 +143,7 @@ export default class AwsProfileParser {
143
143
  * @returns {string} Absolute path to ~/.aws/config
144
144
  */
145
145
  _getConfigPath() {
146
- return this._configPath || join(homedir(), '.aws', 'config')
146
+ return this._configPath || join(homedir(), '.aws', 'config');
147
147
  }
148
148
 
149
149
  /**
@@ -152,7 +152,7 @@ export default class AwsProfileParser {
152
152
  * @returns {string} Absolute path to ~/.aws/credentials
153
153
  */
154
154
  _getCredentialsPath() {
155
- return this._credentialsPath || join(homedir(), '.aws', 'credentials')
155
+ return this._credentialsPath || join(homedir(), '.aws', 'credentials');
156
156
  }
157
157
 
158
158
  /**
@@ -162,9 +162,9 @@ export default class AwsProfileParser {
162
162
  * @private
163
163
  */
164
164
  _getProfilesFromConfig() {
165
- const configPath = this._getConfigPath()
166
- const parsed = this._parseIniFile(configPath)
167
- return this._extractProfileNames(parsed, true)
165
+ const configPath = this._getConfigPath();
166
+ const parsed = this._parseIniFile(configPath);
167
+ return this._extractProfileNames(parsed, true);
168
168
  }
169
169
 
170
170
  /**
@@ -174,8 +174,8 @@ export default class AwsProfileParser {
174
174
  * @private
175
175
  */
176
176
  _getProfilesFromCredentials() {
177
- const credentialsPath = this._getCredentialsPath()
178
- const parsed = this._parseIniFile(credentialsPath)
179
- return this._extractProfileNames(parsed, false)
177
+ const credentialsPath = this._getCredentialsPath();
178
+ const parsed = this._parseIniFile(credentialsPath);
179
+ return this._extractProfileNames(parsed, false);
180
180
  }
181
181
  }