@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
@@ -15,23 +15,23 @@
15
15
  * }
16
16
  */
17
17
 
18
- import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'node:fs'
19
- import { dirname } from 'node:path'
20
- import { createHash } from 'node:crypto'
21
- import Ajv from 'ajv'
22
- import { minimatch } from 'minimatch'
23
- import deploymentEntrySchema from './deployment-entry-schema.js'
18
+ import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'node:fs';
19
+ import { dirname } from 'node:path';
20
+ import { createHash } from 'node:crypto';
21
+ import Ajv from 'ajv';
22
+ import { minimatch } from 'minimatch';
23
+ import deploymentEntrySchema from './deployment-entry-schema.js';
24
24
 
25
- const CURRENT_SCHEMA_VERSION = '2026-03-20'
25
+ const CURRENT_SCHEMA_VERSION = '2026-03-20';
26
26
 
27
27
  export default class DeploymentRegistry {
28
28
  /**
29
29
  * @param {string} registryPath - Absolute path to the registry JSON file
30
30
  */
31
31
  constructor(registryPath) {
32
- this.registryPath = registryPath
33
- this._ajv = new Ajv({ allErrors: true, strict: false })
34
- this._validate = this._ajv.compile(deploymentEntrySchema)
32
+ this.registryPath = registryPath;
33
+ this._ajv = new Ajv({ allErrors: true, strict: false });
34
+ this._validate = this._ajv.compile(deploymentEntrySchema);
35
35
  }
36
36
 
37
37
  /**
@@ -46,27 +46,27 @@ export default class DeploymentRegistry {
46
46
  */
47
47
  _readRegistry() {
48
48
  if (!existsSync(this.registryPath)) {
49
- return []
49
+ return [];
50
50
  }
51
51
 
52
- const raw = readFileSync(this.registryPath, 'utf8')
52
+ const raw = readFileSync(this.registryPath, 'utf8');
53
53
 
54
- let data
54
+ let data;
55
55
  try {
56
- data = JSON.parse(raw)
56
+ data = JSON.parse(raw);
57
57
  } catch (err) {
58
- throw new Error(`Invalid JSON in registry file ${this.registryPath}: ${err.message}`)
58
+ throw new Error(`Invalid JSON in registry file ${this.registryPath}: ${err.message}`);
59
59
  }
60
60
 
61
- const migrated = this._migrateIfNeeded(data)
61
+ const migrated = this._migrateIfNeeded(data);
62
62
 
63
63
  if (!migrated.schemaVersion) {
64
- console.warn(`Warning: Registry file ${this.registryPath} has no schemaVersion. Attempting best-effort read.`)
64
+ console.warn(`Warning: Registry file ${this.registryPath} has no schemaVersion. Attempting best-effort read.`);
65
65
  } else if (migrated.schemaVersion !== CURRENT_SCHEMA_VERSION) {
66
- console.warn(`Warning: Registry file ${this.registryPath} has unrecognized schemaVersion "${migrated.schemaVersion}". Attempting best-effort read.`)
66
+ console.warn(`Warning: Registry file ${this.registryPath} has unrecognized schemaVersion "${migrated.schemaVersion}". Attempting best-effort read.`);
67
67
  }
68
68
 
69
- return Array.isArray(migrated.entries) ? migrated.entries : []
69
+ return Array.isArray(migrated.entries) ? migrated.entries : [];
70
70
  }
71
71
 
72
72
  /**
@@ -78,17 +78,17 @@ export default class DeploymentRegistry {
78
78
  * @param {Array<Object>} entries - The entries array to write
79
79
  */
80
80
  _writeRegistry(entries) {
81
- const dir = dirname(this.registryPath)
81
+ const dir = dirname(this.registryPath);
82
82
  if (!existsSync(dir)) {
83
- mkdirSync(dir, { recursive: true })
83
+ mkdirSync(dir, { recursive: true });
84
84
  }
85
85
 
86
86
  const envelope = {
87
87
  schemaVersion: CURRENT_SCHEMA_VERSION,
88
88
  entries
89
- }
89
+ };
90
90
 
91
- writeFileSync(this.registryPath, JSON.stringify(envelope, null, 2) + '\n')
91
+ writeFileSync(this.registryPath, `${JSON.stringify(envelope, null, 2) }\n`);
92
92
  }
93
93
 
94
94
  /**
@@ -100,17 +100,17 @@ export default class DeploymentRegistry {
100
100
  * @returns {string} 8-character hex string
101
101
  */
102
102
  _generateId(entry, existingEntries = []) {
103
- const baseInput = `${entry.timestamp}:${entry.deployment.deploymentConfig}`
104
- let id = createHash('sha256').update(baseInput).digest('hex').slice(0, 8)
103
+ const baseInput = `${entry.timestamp}:${entry.deployment.deploymentConfig}`;
104
+ let id = createHash('sha256').update(baseInput).digest('hex').slice(0, 8);
105
105
 
106
- const existingIds = new Set(existingEntries.map(e => e.id))
106
+ const existingIds = new Set(existingEntries.map(e => e.id));
107
107
 
108
108
  while (existingIds.has(id)) {
109
- const entropy = Math.random().toString(36).slice(2)
110
- id = createHash('sha256').update(baseInput + entropy).digest('hex').slice(0, 8)
109
+ const entropy = Math.random().toString(36).slice(2);
110
+ id = createHash('sha256').update(baseInput + entropy).digest('hex').slice(0, 8);
111
111
  }
112
112
 
113
- return id
113
+ return id;
114
114
  }
115
115
 
116
116
  /**
@@ -120,11 +120,11 @@ export default class DeploymentRegistry {
120
120
  * @returns {{ valid: boolean, errors: Array|null }} Validation result
121
121
  */
122
122
  _validateEntry(entry) {
123
- const valid = this._validate(entry)
123
+ const valid = this._validate(entry);
124
124
  return {
125
125
  valid: !!valid,
126
126
  errors: valid ? null : this._validate.errors
127
- }
127
+ };
128
128
  }
129
129
 
130
130
  /**
@@ -143,19 +143,19 @@ export default class DeploymentRegistry {
143
143
  return {
144
144
  schemaVersion: CURRENT_SCHEMA_VERSION,
145
145
  entries: data
146
- }
146
+ };
147
147
  }
148
148
 
149
149
  // Already an envelope with schemaVersion and entries
150
150
  if (data && typeof data === 'object' && 'entries' in data) {
151
- return data
151
+ return data;
152
152
  }
153
153
 
154
154
  // Unknown format — wrap in envelope with empty entries
155
155
  return {
156
156
  schemaVersion: undefined,
157
157
  entries: []
158
- }
158
+ };
159
159
  }
160
160
 
161
161
  /**
@@ -169,21 +169,21 @@ export default class DeploymentRegistry {
169
169
  * @throws {Error} If the entry fails schema validation
170
170
  */
171
171
  add(entry) {
172
- const existingEntries = this._readRegistry()
173
- const id = this._generateId(entry, existingEntries)
172
+ const existingEntries = this._readRegistry();
173
+ const id = this._generateId(entry, existingEntries);
174
174
 
175
- const fullEntry = { ...entry, id }
175
+ const fullEntry = { ...entry, id };
176
176
 
177
- const { valid, errors } = this._validateEntry(fullEntry)
177
+ const { valid, errors } = this._validateEntry(fullEntry);
178
178
  if (!valid) {
179
- const details = errors.map(e => `${e.instancePath || '/'} ${e.message}`).join(', ')
180
- throw new Error(`Validation failed: ${details}`)
179
+ const details = errors.map(e => `${e.instancePath || '/'} ${e.message}`).join(', ');
180
+ throw new Error(`Validation failed: ${details}`);
181
181
  }
182
182
 
183
- existingEntries.push(fullEntry)
184
- this._writeRegistry(existingEntries)
183
+ existingEntries.push(fullEntry);
184
+ this._writeRegistry(existingEntries);
185
185
 
186
- return id
186
+ return id;
187
187
  }
188
188
 
189
189
  /**
@@ -193,8 +193,8 @@ export default class DeploymentRegistry {
193
193
  * @returns {Object|null} The matching entry, or null if not found
194
194
  */
195
195
  get(id) {
196
- const entries = this._readRegistry()
197
- return entries.find(e => e.id === id) || null
196
+ const entries = this._readRegistry();
197
+ return entries.find(e => e.id === id) || null;
198
198
  }
199
199
 
200
200
  /**
@@ -204,15 +204,15 @@ export default class DeploymentRegistry {
204
204
  * @returns {boolean} true if an entry was removed, false if not found
205
205
  */
206
206
  remove(id) {
207
- const entries = this._readRegistry()
208
- const filtered = entries.filter(e => e.id !== id)
207
+ const entries = this._readRegistry();
208
+ const filtered = entries.filter(e => e.id !== id);
209
209
 
210
210
  if (filtered.length === entries.length) {
211
- return false
211
+ return false;
212
212
  }
213
213
 
214
- this._writeRegistry(filtered)
215
- return true
214
+ this._writeRegistry(filtered);
215
+ return true;
216
216
  }
217
217
 
218
218
  /**
@@ -231,36 +231,36 @@ export default class DeploymentRegistry {
231
231
  */
232
232
  _matchesFilters(entry, filters) {
233
233
  if (!filters || typeof filters !== 'object') {
234
- return true
234
+ return true;
235
235
  }
236
236
 
237
237
  for (const [key, value] of Object.entries(filters)) {
238
238
  if (value === undefined || value === null) {
239
- continue
239
+ continue;
240
240
  }
241
241
 
242
242
  switch (key) {
243
- case 'backend':
244
- if (entry.deployment?.backend !== value) return false
245
- break
246
- case 'architecture':
247
- if (entry.deployment?.architecture !== value) return false
248
- break
249
- case 'model':
250
- if (!entry.model?.modelName?.toLowerCase().includes(value.toLowerCase())) return false
251
- break
252
- case 'instance-type':
253
- if (entry.infrastructure?.instanceType !== value) return false
254
- break
255
- case 'status':
256
- if (entry.status !== value) return false
257
- break
258
- default:
259
- break
243
+ case 'backend':
244
+ if (entry.deployment?.backend !== value) return false;
245
+ break;
246
+ case 'architecture':
247
+ if (entry.deployment?.architecture !== value) return false;
248
+ break;
249
+ case 'model':
250
+ if (!entry.model?.modelName?.toLowerCase().includes(value.toLowerCase())) return false;
251
+ break;
252
+ case 'instance-type':
253
+ if (entry.infrastructure?.instanceType !== value) return false;
254
+ break;
255
+ case 'status':
256
+ if (entry.status !== value) return false;
257
+ break;
258
+ default:
259
+ break;
260
260
  }
261
261
  }
262
262
 
263
- return true
263
+ return true;
264
264
  }
265
265
 
266
266
  /**
@@ -273,13 +273,13 @@ export default class DeploymentRegistry {
273
273
  * @returns {Array<Object>} Matching entries
274
274
  */
275
275
  list(filters) {
276
- const entries = this._readRegistry()
276
+ const entries = this._readRegistry();
277
277
 
278
278
  if (!filters || Object.keys(filters).length === 0) {
279
- return entries
279
+ return entries;
280
280
  }
281
281
 
282
- return entries.filter(entry => this._matchesFilters(entry, filters))
282
+ return entries.filter(entry => this._matchesFilters(entry, filters));
283
283
  }
284
284
 
285
285
  /**
@@ -292,41 +292,41 @@ export default class DeploymentRegistry {
292
292
  * @returns {Array<Object>} Matching entries
293
293
  */
294
294
  search(query) {
295
- const entries = this._readRegistry()
295
+ const entries = this._readRegistry();
296
296
 
297
297
  if (!query || Object.keys(query).length === 0) {
298
- return entries
298
+ return entries;
299
299
  }
300
300
 
301
301
  return entries.filter(entry => {
302
302
  for (const [key, value] of Object.entries(query)) {
303
303
  if (value === undefined || value === null) {
304
- continue
304
+ continue;
305
305
  }
306
306
 
307
307
  switch (key) {
308
- case 'model':
309
- if (!entry.model?.modelName || !minimatch(entry.model.modelName, value)) return false
310
- break
311
- case 'backend':
312
- if (entry.deployment?.backend !== value) return false
313
- break
314
- case 'architecture':
315
- if (entry.deployment?.architecture !== value) return false
316
- break
317
- case 'instance-type':
318
- if (entry.infrastructure?.instanceType !== value) return false
319
- break
320
- case 'status':
321
- if (entry.status !== value) return false
322
- break
323
- default:
324
- break
308
+ case 'model':
309
+ if (!entry.model?.modelName || !minimatch(entry.model.modelName, value)) return false;
310
+ break;
311
+ case 'backend':
312
+ if (entry.deployment?.backend !== value) return false;
313
+ break;
314
+ case 'architecture':
315
+ if (entry.deployment?.architecture !== value) return false;
316
+ break;
317
+ case 'instance-type':
318
+ if (entry.infrastructure?.instanceType !== value) return false;
319
+ break;
320
+ case 'status':
321
+ if (entry.status !== value) return false;
322
+ break;
323
+ default:
324
+ break;
325
325
  }
326
326
  }
327
327
 
328
- return true
329
- })
328
+ return true;
329
+ });
330
330
  }
331
331
 
332
332
  /**
@@ -344,19 +344,19 @@ export default class DeploymentRegistry {
344
344
  * @returns {Object} A sanitized deep copy of the entry
345
345
  */
346
346
  _stripSensitiveFields(entry) {
347
- const copy = JSON.parse(JSON.stringify(entry))
347
+ const copy = JSON.parse(JSON.stringify(entry));
348
348
 
349
349
  if (copy.infrastructure) {
350
- delete copy.infrastructure.roleArn
351
- delete copy.infrastructure.region
350
+ delete copy.infrastructure.roleArn;
351
+ delete copy.infrastructure.region;
352
352
  }
353
353
 
354
354
  if (copy.configuration?.parameters) {
355
- delete copy.configuration.parameters.HF_TOKEN
356
- delete copy.configuration.parameters.NGC_API_KEY
355
+ delete copy.configuration.parameters.HF_TOKEN;
356
+ delete copy.configuration.parameters.NGC_API_KEY;
357
357
  }
358
358
 
359
- return copy
359
+ return copy;
360
360
  }
361
361
 
362
362
  /**
@@ -373,25 +373,25 @@ export default class DeploymentRegistry {
373
373
  * @returns {Object} Export_Format object with version, exportedAt, exportedBy, entries
374
374
  */
375
375
  exportEntries(id, options = {}) {
376
- const entries = this._readRegistry()
377
- const statusFilter = options.status || 'success'
376
+ const entries = this._readRegistry();
377
+ const statusFilter = options.status || 'success';
378
378
 
379
- let filtered
379
+ let filtered;
380
380
  if (id) {
381
- const entry = entries.find(e => e.id === id)
382
- filtered = entry ? [entry] : []
381
+ const entry = entries.find(e => e.id === id);
382
+ filtered = entry ? [entry] : [];
383
383
  } else {
384
- filtered = entries.filter(e => e.status === statusFilter)
384
+ filtered = entries.filter(e => e.status === statusFilter);
385
385
  }
386
386
 
387
- const sanitized = filtered.map(e => this._stripSensitiveFields(e))
387
+ const sanitized = filtered.map(e => this._stripSensitiveFields(e));
388
388
 
389
389
  return {
390
390
  version: '1.0',
391
391
  exportedAt: new Date().toISOString(),
392
392
  exportedBy: 'anonymous',
393
393
  entries: sanitized
394
- }
394
+ };
395
395
  }
396
396
 
397
397
  /**
@@ -403,7 +403,7 @@ export default class DeploymentRegistry {
403
403
  * @returns {Object} CLI flag key-value pairs
404
404
  */
405
405
  reconstructReplayFlags(entry, overrides = {}) {
406
- return reconstructReplayFlags(entry, overrides)
406
+ return reconstructReplayFlags(entry, overrides);
407
407
  }
408
408
 
409
409
  /**
@@ -428,61 +428,61 @@ export default class DeploymentRegistry {
428
428
  */
429
429
  importEntries(json, strategy = 'skip', filename = 'unknown') {
430
430
  if (!json || typeof json !== 'object' || !json.version || !Array.isArray(json.entries)) {
431
- throw new Error('Invalid export format: missing required "version" or "entries" fields')
431
+ throw new Error('Invalid export format: missing required "version" or "entries" fields');
432
432
  }
433
433
 
434
- const existingEntries = this._readRegistry()
435
- let added = 0
436
- let skipped = 0
437
- let conflicts = 0
434
+ const existingEntries = this._readRegistry();
435
+ let added = 0;
436
+ let skipped = 0;
437
+ let conflicts = 0;
438
438
 
439
439
  for (const importedEntry of json.entries) {
440
- const entry = JSON.parse(JSON.stringify(importedEntry))
440
+ const entry = JSON.parse(JSON.stringify(importedEntry));
441
441
 
442
442
  if (!entry.metadata) {
443
- entry.metadata = {}
443
+ entry.metadata = {};
444
444
  }
445
- entry.metadata.source = 'imported'
446
- entry.metadata.importedFrom = filename
445
+ entry.metadata.source = 'imported';
446
+ entry.metadata.importedFrom = filename;
447
447
 
448
448
  const isConflict = existingEntries.some(existing =>
449
449
  existing.model?.modelName === entry.model?.modelName &&
450
450
  existing.deployment?.backend === entry.deployment?.backend &&
451
451
  existing.infrastructure?.instanceType === entry.infrastructure?.instanceType &&
452
452
  JSON.stringify(existing.configuration?.parameters) === JSON.stringify(entry.configuration?.parameters)
453
- )
453
+ );
454
454
 
455
455
  if (isConflict) {
456
- conflicts++
456
+ conflicts++;
457
457
  if (strategy === 'merge') {
458
- const id = this._generateId(entry, existingEntries)
459
- entry.id = id
460
- existingEntries.push(entry)
458
+ const id = this._generateId(entry, existingEntries);
459
+ entry.id = id;
460
+ existingEntries.push(entry);
461
461
  } else if (strategy === 'replace') {
462
462
  const conflictIndex = existingEntries.findIndex(existing =>
463
463
  existing.model?.modelName === entry.model?.modelName &&
464
464
  existing.deployment?.backend === entry.deployment?.backend &&
465
465
  existing.infrastructure?.instanceType === entry.infrastructure?.instanceType &&
466
466
  JSON.stringify(existing.configuration?.parameters) === JSON.stringify(entry.configuration?.parameters)
467
- )
467
+ );
468
468
  if (conflictIndex !== -1) {
469
- entry.id = existingEntries[conflictIndex].id
470
- existingEntries[conflictIndex] = entry
469
+ entry.id = existingEntries[conflictIndex].id;
470
+ existingEntries[conflictIndex] = entry;
471
471
  }
472
472
  } else {
473
- skipped++
473
+ skipped++;
474
474
  }
475
475
  } else {
476
- const id = this._generateId(entry, existingEntries)
477
- entry.id = id
478
- existingEntries.push(entry)
479
- added++
476
+ const id = this._generateId(entry, existingEntries);
477
+ entry.id = id;
478
+ existingEntries.push(entry);
479
+ added++;
480
480
  }
481
481
  }
482
482
 
483
- this._writeRegistry(existingEntries)
483
+ this._writeRegistry(existingEntries);
484
484
 
485
- return { added, skipped, conflicts }
485
+ return { added, skipped, conflicts };
486
486
  }
487
487
 
488
488
  }
@@ -505,35 +505,35 @@ export default class DeploymentRegistry {
505
505
  * @returns {Object} CLI flag key-value pairs
506
506
  */
507
507
  export function reconstructReplayFlags(entry, overrides = {}) {
508
- const flags = {}
508
+ const flags = {};
509
509
 
510
510
  const mappings = [
511
511
  { field: entry?.deployment?.deploymentConfig, flag: '--deployment-config' },
512
512
  { field: entry?.model?.modelName, flag: '--model-name' },
513
513
  { field: entry?.infrastructure?.instanceType, flag: '--instance-type' },
514
- { field: entry?.infrastructure?.region, flag: '--region' },
515
- ]
514
+ { field: entry?.infrastructure?.region, flag: '--region' }
515
+ ];
516
516
 
517
517
  for (const { field, flag } of mappings) {
518
- if (field != null) {
519
- flags[flag] = field
518
+ if (field !== null && field !== undefined) {
519
+ flags[flag] = field;
520
520
  }
521
521
  }
522
522
 
523
523
  // Omit --model-format for transformers architecture
524
- const isTransformers = entry?.deployment?.architecture === 'transformers'
525
- if (!isTransformers && entry?.model?.modelFormat != null) {
526
- flags['--model-format'] = entry.model.modelFormat
524
+ const isTransformers = entry?.deployment?.architecture === 'transformers';
525
+ if (!isTransformers && entry?.model?.modelFormat !== null && entry?.model?.modelFormat !== undefined) {
526
+ flags['--model-format'] = entry.model.modelFormat;
527
527
  }
528
528
 
529
529
  // Apply user overrides with higher precedence
530
530
  for (const [key, value] of Object.entries(overrides)) {
531
- if (value != null) {
532
- flags[key] = value
531
+ if (value !== null && value !== undefined) {
532
+ flags[key] = value;
533
533
  }
534
534
  }
535
535
 
536
- return flags
536
+ return flags;
537
537
  }
538
538
 
539
539
  /**
@@ -551,8 +551,8 @@ const HTTP_SYSTEM_VARS = new Set([
551
551
  'PYTHON_PIP_VERSION',
552
552
  'PYTHON_SETUPTOOLS_VERSION',
553
553
  'PYTHON_GET_PIP_URL',
554
- 'PYTHON_GET_PIP_SHA256',
555
- ])
554
+ 'PYTHON_GET_PIP_SHA256'
555
+ ]);
556
556
 
557
557
  /**
558
558
  * Filter environment variables for transformer architecture deployments.
@@ -565,15 +565,15 @@ const HTTP_SYSTEM_VARS = new Set([
565
565
  * @returns {Object} Filtered key-value pairs
566
566
  */
567
567
  export function filterTransformerEnvVars(envVars, enginePrefix) {
568
- const result = {}
568
+ const result = {};
569
569
 
570
570
  for (const [key, value] of Object.entries(envVars)) {
571
571
  if (key.startsWith(enginePrefix) || key === 'HF_TOKEN' || key === 'HF_MODEL_ID') {
572
- result[key] = value
572
+ result[key] = value;
573
573
  }
574
574
  }
575
575
 
576
- return result
576
+ return result;
577
577
  }
578
578
 
579
579
  /**
@@ -586,13 +586,13 @@ export function filterTransformerEnvVars(envVars, enginePrefix) {
586
586
  * @returns {Object} Filtered key-value pairs with system vars removed
587
587
  */
588
588
  export function filterHttpEnvVars(envVars) {
589
- const result = {}
589
+ const result = {};
590
590
 
591
591
  for (const [key, value] of Object.entries(envVars)) {
592
592
  if (!HTTP_SYSTEM_VARS.has(key)) {
593
- result[key] = value
593
+ result[key] = value;
594
594
  }
595
595
  }
596
596
 
597
- return result
597
+ return result;
598
598
  }
@@ -23,7 +23,7 @@ export const ENGINE_PREFIX_MAP = {
23
23
  'tensorrt-llm': 'TRTLLM_',
24
24
  'lmi': 'LMI_',
25
25
  'djl': 'DJL_'
26
- }
26
+ };
27
27
 
28
28
  /**
29
29
  * Resolve the prefixed key for a given engine and user-provided key.
@@ -35,11 +35,11 @@ export const ENGINE_PREFIX_MAP = {
35
35
  * @returns {string} The resolved key with engine prefix applied (or unchanged)
36
36
  */
37
37
  export function resolvePrefix(engine, key) {
38
- const prefix = ENGINE_PREFIX_MAP[engine]
38
+ const prefix = ENGINE_PREFIX_MAP[engine];
39
39
  if (prefix) {
40
- return `${prefix}${key}`
40
+ return `${prefix}${key}`;
41
41
  }
42
- return key
42
+ return key;
43
43
  }
44
44
 
45
45
  /**
@@ -51,10 +51,10 @@ export function resolvePrefix(engine, key) {
51
51
  * @returns {Object<string, string>} New object with prefixed keys and original values
52
52
  */
53
53
  export function resolvePrefixedEnvVars(engine, serverEnvVars) {
54
- const result = {}
54
+ const result = {};
55
55
  for (const [key, value] of Object.entries(serverEnvVars)) {
56
- const prefixedKey = resolvePrefix(engine, key)
57
- result[prefixedKey] = value
56
+ const prefixedKey = resolvePrefix(engine, key);
57
+ result[prefixedKey] = value;
58
58
  }
59
- return result
59
+ return result;
60
60
  }
@@ -11,7 +11,7 @@
11
11
  * Requirements: 3.4, 3.5, 4.4, 4.5
12
12
  */
13
13
 
14
- import { ValidationError } from './config-manager.js'
14
+ import { ValidationError } from './config-manager.js';
15
15
 
16
16
  /**
17
17
  * Parse a KEY=VALUE string, splitting only on the first '=' character.
@@ -20,18 +20,18 @@ import { ValidationError } from './config-manager.js'
20
20
  * @throws {ValidationError} if no '=' is present
21
21
  */
22
22
  export function parseKeyValue(input) {
23
- const idx = input.indexOf('=')
23
+ const idx = input.indexOf('=');
24
24
 
25
25
  if (idx === -1) {
26
26
  throw new ValidationError(
27
27
  `Invalid format for env var: expected KEY=VALUE, got '${input}'`,
28
28
  'env',
29
29
  input
30
- )
30
+ );
31
31
  }
32
32
 
33
- const key = input.substring(0, idx)
34
- const value = input.substring(idx + 1)
33
+ const key = input.substring(0, idx);
34
+ const value = input.substring(idx + 1);
35
35
 
36
- return { key, value }
36
+ return { key, value };
37
37
  }