@swovohq/fuel 0.2.2-alpha.90 → 0.2.2-alpha.91

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 (95) hide show
  1. package/README.md +107 -107
  2. package/dist/bin/fuel.js +2 -2
  3. package/dist/cleanup/finalize.d.ts.map +1 -1
  4. package/dist/cleanup/finalize.js +11 -3
  5. package/dist/cleanup/finalize.js.map +1 -1
  6. package/dist/commands/config-verify.d.ts.map +1 -1
  7. package/dist/commands/config-verify.js.map +1 -1
  8. package/dist/commands/create-app.d.ts.map +1 -1
  9. package/dist/commands/create-app.js +6 -4
  10. package/dist/commands/create-app.js.map +1 -1
  11. package/dist/commands/infra-deploy.d.ts.map +1 -1
  12. package/dist/commands/infra-deploy.js +37 -20
  13. package/dist/commands/infra-deploy.js.map +1 -1
  14. package/dist/commands/infra-destroy.d.ts.map +1 -1
  15. package/dist/commands/infra-destroy.js +1 -1
  16. package/dist/commands/infra-destroy.js.map +1 -1
  17. package/dist/commands/infra-init.d.ts.map +1 -1
  18. package/dist/commands/infra-init.js +168 -67
  19. package/dist/commands/infra-init.js.map +1 -1
  20. package/dist/commands/infra-pull.d.ts.map +1 -1
  21. package/dist/commands/infra-pull.js +2 -1
  22. package/dist/commands/infra-pull.js.map +1 -1
  23. package/dist/commands/list-modules.d.ts.map +1 -1
  24. package/dist/commands/list-modules.js +10 -3
  25. package/dist/commands/list-modules.js.map +1 -1
  26. package/dist/engines/convention.d.ts.map +1 -1
  27. package/dist/engines/convention.js +2 -2
  28. package/dist/engines/convention.js.map +1 -1
  29. package/dist/engines/dependencies.d.ts.map +1 -1
  30. package/dist/engines/dependencies.js.map +1 -1
  31. package/dist/engines/monorepo.d.ts.map +1 -1
  32. package/dist/engines/monorepo.js.map +1 -1
  33. package/dist/engines/template-source.d.ts.map +1 -1
  34. package/dist/engines/template-source.js +3 -1
  35. package/dist/engines/template-source.js.map +1 -1
  36. package/dist/index.d.ts.map +1 -1
  37. package/dist/index.js.map +1 -1
  38. package/dist/infra/azure-defaults.js +8 -8
  39. package/dist/infra/azure-keyvault-client.d.ts.map +1 -1
  40. package/dist/infra/azure-keyvault-client.js.map +1 -1
  41. package/dist/infra/azure-rbac.d.ts.map +1 -1
  42. package/dist/infra/azure-rbac.js +3 -1
  43. package/dist/infra/azure-rbac.js.map +1 -1
  44. package/dist/infra/azure-state-storage.d.ts.map +1 -1
  45. package/dist/infra/azure-state-storage.js +9 -9
  46. package/dist/infra/azure-state-storage.js.map +1 -1
  47. package/dist/infra/config-loader.d.ts.map +1 -1
  48. package/dist/infra/config-loader.js.map +1 -1
  49. package/dist/infra/config-writer.js +1 -1
  50. package/dist/infra/credentials.d.ts.map +1 -1
  51. package/dist/infra/credentials.js.map +1 -1
  52. package/dist/infra/dependency-checker.d.ts.map +1 -1
  53. package/dist/infra/dependency-checker.js.map +1 -1
  54. package/dist/infra/deployment-detect.d.ts.map +1 -1
  55. package/dist/infra/deployment-detect.js.map +1 -1
  56. package/dist/infra/git-client.d.ts.map +1 -1
  57. package/dist/infra/git-client.js.map +1 -1
  58. package/dist/infra/github-client.d.ts.map +1 -1
  59. package/dist/infra/github-client.js +3 -3
  60. package/dist/infra/github-client.js.map +1 -1
  61. package/dist/infra/github-secrets-client.d.ts.map +1 -1
  62. package/dist/infra/github-secrets-client.js +2 -2
  63. package/dist/infra/github-secrets-client.js.map +1 -1
  64. package/dist/infra/github-token-link.d.ts.map +1 -1
  65. package/dist/infra/github-token-link.js +6 -2
  66. package/dist/infra/github-token-link.js.map +1 -1
  67. package/dist/infra/orchestrator.d.ts.map +1 -1
  68. package/dist/infra/orchestrator.js +20 -15
  69. package/dist/infra/orchestrator.js.map +1 -1
  70. package/dist/infra/port-utils.d.ts.map +1 -1
  71. package/dist/infra/port-utils.js.map +1 -1
  72. package/dist/infra/preflight.d.ts.map +1 -1
  73. package/dist/infra/preflight.js +9 -3
  74. package/dist/infra/preflight.js.map +1 -1
  75. package/dist/infra/s3-state-bucket.d.ts.map +1 -1
  76. package/dist/infra/s3-state-bucket.js +8 -4
  77. package/dist/infra/s3-state-bucket.js.map +1 -1
  78. package/dist/infra/secrets-manager-client.d.ts.map +1 -1
  79. package/dist/infra/secrets-manager-client.js +8 -5
  80. package/dist/infra/secrets-manager-client.js.map +1 -1
  81. package/dist/infra/subprocess.js +1 -1
  82. package/dist/infra/template-engine.d.ts.map +1 -1
  83. package/dist/infra/template-engine.js +17 -5
  84. package/dist/infra/template-engine.js.map +1 -1
  85. package/dist/infra/tofu-runner.d.ts.map +1 -1
  86. package/dist/infra/tofu-runner.js +8 -11
  87. package/dist/infra/tofu-runner.js.map +1 -1
  88. package/dist/infra/types.d.ts +1 -1
  89. package/dist/infra/types.d.ts.map +1 -1
  90. package/dist/infra/types.js +299 -91
  91. package/dist/infra/types.js.map +1 -1
  92. package/dist/infra-templates/TODO-azure-prod.md +16 -8
  93. package/dist/infra-templates/templates/azure/MANUAL_DEPLOY.md +1 -1
  94. package/dist/infra-templates/templates/ecs/README.md +92 -82
  95. package/package.json +1 -1
@@ -58,11 +58,16 @@ function httpsGetJson(url, headers) {
58
58
  return new Promise((resolve, reject) => {
59
59
  const req = https.get(url, { headers }, (res) => {
60
60
  let body = '';
61
- res.on('data', (chunk) => { body += chunk.toString(); });
61
+ res.on('data', (chunk) => {
62
+ body += chunk.toString();
63
+ });
62
64
  res.on('end', () => resolve({ status: res.statusCode ?? 0, body }));
63
65
  });
64
66
  req.on('error', reject);
65
- req.setTimeout(10000, () => { req.destroy(); reject(new Error('Request timed out')); });
67
+ req.setTimeout(10000, () => {
68
+ req.destroy();
69
+ reject(new Error('Request timed out'));
70
+ });
66
71
  });
67
72
  }
68
73
  exports.CONFIG_TEMPLATE = {
@@ -86,7 +91,7 @@ exports.CONFIG_TEMPLATE = {
86
91
  db_instance_type: 'db.t3.small',
87
92
  db_allocated_storage: 30,
88
93
  variables: {},
89
- workers: [],
94
+ workers: []
90
95
  },
91
96
  {
92
97
  name: 'my-app-web',
@@ -99,10 +104,10 @@ exports.CONFIG_TEMPLATE = {
99
104
  cpu_units: 1024,
100
105
  memory_units: 2048,
101
106
  build_env: {
102
- NEXT_PUBLIC_API_HOST: 'https://api.example.com',
103
- },
104
- },
105
- ],
107
+ NEXT_PUBLIC_API_HOST: 'https://api.example.com'
108
+ }
109
+ }
110
+ ]
106
111
  };
107
112
  exports.CONFIG_TEMPLATE_AZURE = {
108
113
  name: 'my-app',
@@ -111,7 +116,12 @@ exports.CONFIG_TEMPLATE_AZURE = {
111
116
  location: 'eastus2',
112
117
  monitor: { daily_data_cap_gb: 1, retention_days: 90, dashboard_count: 0 },
113
118
  front_door: { sku_name: 'Standard_AzureFrontDoor' },
114
- storage_account: { account_kind: 'BlockBlobStorage', account_tier: 'Premium', account_replication_type: 'LRS', access_tier: 'Hot' },
119
+ storage_account: {
120
+ account_kind: 'BlockBlobStorage',
121
+ account_tier: 'Premium',
122
+ account_replication_type: 'LRS',
123
+ access_tier: 'Hot'
124
+ },
115
125
  key_vault: { sku_name: 'standard' },
116
126
  apps: [
117
127
  {
@@ -124,9 +134,15 @@ exports.CONFIG_TEMPLATE_AZURE = {
124
134
  branch: 'main',
125
135
  database: { enabled: true, engine: 'mssql', sku_name: 'GP_S_Gen5_4' },
126
136
  redis: { enabled: false, sku_name: 'Balanced_B0' },
127
- container_app: { cpu: 1, memory: '2Gi', concurrent_requests: 20, min_replicas: 0, max_replicas: 3 },
137
+ container_app: {
138
+ cpu: 1,
139
+ memory: '2Gi',
140
+ concurrent_requests: 20,
141
+ min_replicas: 0,
142
+ max_replicas: 3
143
+ },
128
144
  variables: {},
129
- workers: [],
145
+ workers: []
130
146
  },
131
147
  {
132
148
  name: 'my-app-web',
@@ -137,10 +153,10 @@ exports.CONFIG_TEMPLATE_AZURE = {
137
153
  port: 3000,
138
154
  branch: 'main',
139
155
  build_env: {
140
- NEXT_PUBLIC_API_HOST: 'https://api.example.com',
141
- },
142
- },
143
- ],
156
+ NEXT_PUBLIC_API_HOST: 'https://api.example.com'
157
+ }
158
+ }
159
+ ]
144
160
  };
145
161
  // --- Private prompt helpers ---
146
162
  async function ask(rl, label, defaultVal) {
@@ -238,7 +254,7 @@ async function askGitHubOrganizationFor(rl, token) {
238
254
  const { status, body } = await httpsGetJson('https://api.github.com/user/orgs', {
239
255
  Authorization: `Bearer ${token}`,
240
256
  'User-Agent': 'fuel-cli',
241
- Accept: 'application/vnd.github+json',
257
+ Accept: 'application/vnd.github+json'
242
258
  });
243
259
  if (status === 200) {
244
260
  const orgs = JSON.parse(body);
@@ -262,12 +278,15 @@ async function tryGetGithubUser(credentials) {
262
278
  const { status, body } = await httpsGetJson('https://api.github.com/user', {
263
279
  Authorization: `Bearer ${credentials.GITHUB_TOKEN}`,
264
280
  'User-Agent': 'fuel-cli',
265
- Accept: 'application/vnd.github+json',
281
+ Accept: 'application/vnd.github+json'
266
282
  });
267
283
  const data = JSON.parse(body);
268
284
  if (status !== 200)
269
285
  return { error: data.message ?? `HTTP ${status}` };
270
- return { login: data.login ?? '(unknown)', email: data.email ?? '(private)' };
286
+ return {
287
+ login: data.login ?? '(unknown)',
288
+ email: data.email ?? '(private)'
289
+ };
271
290
  }
272
291
  catch (err) {
273
292
  return { error: err instanceof Error ? err.message : String(err) };
@@ -282,7 +301,7 @@ async function tryGetGithubOrg(credentials) {
282
301
  const { status, body } = await httpsGetJson(`https://api.github.com/orgs/${encodeURIComponent(org)}`, {
283
302
  Authorization: `Bearer ${credentials.GITHUB_TOKEN}`,
284
303
  'User-Agent': 'fuel-cli',
285
- Accept: 'application/vnd.github+json',
304
+ Accept: 'application/vnd.github+json'
286
305
  });
287
306
  const data = JSON.parse(body);
288
307
  if (status !== 200)
@@ -301,9 +320,9 @@ async function tryGetAwsAccountId(credentials) {
301
320
  ...process.env,
302
321
  AWS_ACCESS_KEY_ID: credentials.AWS_ACCESS_KEY_ID,
303
322
  AWS_SECRET_ACCESS_KEY: credentials.AWS_SECRET_ACCESS_KEY,
304
- AWS_REGION: credentials.AWS_REGION,
323
+ AWS_REGION: credentials.AWS_REGION
305
324
  },
306
- timeout: 10000,
325
+ timeout: 10000
307
326
  });
308
327
  const accountId = JSON.parse(stdout).Account ?? '';
309
328
  return { accountId };
@@ -311,7 +330,10 @@ async function tryGetAwsAccountId(credentials) {
311
330
  catch (err) {
312
331
  const e = err;
313
332
  const raw = e.stderr ?? e.message ?? String(err);
314
- const firstLine = raw.split('\n').map((l) => l.trim()).find((l) => l.length > 0) ?? raw;
333
+ const firstLine = raw
334
+ .split('\n')
335
+ .map((l) => l.trim())
336
+ .find((l) => l.length > 0) ?? raw;
315
337
  return { error: firstLine };
316
338
  }
317
339
  }
@@ -323,20 +345,23 @@ async function tryGetAcmCertificate(arn, credentials) {
323
345
  ...process.env,
324
346
  AWS_ACCESS_KEY_ID: credentials.AWS_ACCESS_KEY_ID,
325
347
  AWS_SECRET_ACCESS_KEY: credentials.AWS_SECRET_ACCESS_KEY,
326
- AWS_REGION: credentials.AWS_REGION,
348
+ AWS_REGION: credentials.AWS_REGION
327
349
  },
328
- timeout: 10000,
350
+ timeout: 10000
329
351
  });
330
352
  const cert = JSON.parse(stdout).Certificate;
331
353
  return {
332
354
  domainName: cert?.DomainName ?? '(unknown)',
333
- status: cert?.Status ?? '(unknown)',
355
+ status: cert?.Status ?? '(unknown)'
334
356
  };
335
357
  }
336
358
  catch (err) {
337
359
  const e = err;
338
360
  const raw = e.stderr ?? e.message ?? String(err);
339
- const firstLine = raw.split('\n').map((l) => l.trim()).find((l) => l.length > 0) ?? raw;
361
+ const firstLine = raw
362
+ .split('\n')
363
+ .map((l) => l.trim())
364
+ .find((l) => l.length > 0) ?? raw;
340
365
  return { error: firstLine };
341
366
  }
342
367
  }
@@ -401,12 +426,12 @@ async function collectAnswers(rl) {
401
426
  const credFilePath = path.resolve('.fuel-credentials');
402
427
  if (await fs.pathExists(credFilePath)) {
403
428
  try {
404
- const existing = await fs.readJson(credFilePath);
429
+ const existing = (await fs.readJson(credFilePath));
405
430
  console.log('\n Found existing .fuel-credentials');
406
431
  const [stsResult, ghUserResult, ghOrgResult] = await Promise.all([
407
432
  tryGetAwsAccountId(existing),
408
433
  tryGetGithubUser(existing),
409
- tryGetGithubOrg(existing),
434
+ tryGetGithubOrg(existing)
410
435
  ]);
411
436
  if ('accountId' in stsResult) {
412
437
  console.log(` AWS Account: ${chalk_1.default.green(stsResult.accountId)}`);
@@ -439,7 +464,8 @@ async function collectAnswers(rl) {
439
464
  credentials = existing;
440
465
  }
441
466
  catch (e) {
442
- if (e instanceof Error && e.message.startsWith('Credential verification failed'))
467
+ if (e instanceof Error &&
468
+ e.message.startsWith('Credential verification failed'))
443
469
  throw e;
444
470
  console.log(' Could not read .fuel-credentials — prompting for credentials.');
445
471
  }
@@ -456,7 +482,7 @@ async function collectAnswers(rl) {
456
482
  const [stsResult, ghUserResult, ghOrgResult] = await Promise.all([
457
483
  tryGetAwsAccountId(credentials),
458
484
  tryGetGithubUser(credentials),
459
- tryGetGithubOrg(credentials),
485
+ tryGetGithubOrg(credentials)
460
486
  ]);
461
487
  if ('accountId' in stsResult) {
462
488
  console.log(` AWS Account: ${chalk_1.default.green(stsResult.accountId)}`);
@@ -533,9 +559,18 @@ async function collectAnswers(rl) {
533
559
  const cpuUnits = await askInt(rl, 'CPU units', 1024);
534
560
  const memoryUnits = await askInt(rl, 'Memory (MB)', 2048);
535
561
  appTypes.push({
536
- suffix: 'api', dockerfile, port, healthCheckPath,
537
- postgres, redis, cpuUnits, memoryUnits,
538
- dbInstanceType, dbAllocatedStorage, redisInstanceType, variables: {},
562
+ suffix: 'api',
563
+ dockerfile,
564
+ port,
565
+ healthCheckPath,
566
+ postgres,
567
+ redis,
568
+ cpuUnits,
569
+ memoryUnits,
570
+ dbInstanceType,
571
+ dbAllocatedStorage,
572
+ redisInstanceType,
573
+ variables: {}
539
574
  });
540
575
  }
541
576
  if (includeWeb) {
@@ -546,10 +581,18 @@ async function collectAnswers(rl) {
546
581
  const cpuUnits = await askInt(rl, 'CPU units', 1024);
547
582
  const memoryUnits = await askInt(rl, 'Memory (MB)', 2048);
548
583
  appTypes.push({
549
- suffix: 'web', dockerfile, port, healthCheckPath,
550
- postgres: false, redis: false, cpuUnits, memoryUnits,
551
- dbInstanceType: 'db.t3.small', dbAllocatedStorage: 30,
552
- redisInstanceType: 'cache.t3.small', variables: {},
584
+ suffix: 'web',
585
+ dockerfile,
586
+ port,
587
+ healthCheckPath,
588
+ postgres: false,
589
+ redis: false,
590
+ cpuUnits,
591
+ memoryUnits,
592
+ dbInstanceType: 'db.t3.small',
593
+ dbAllocatedStorage: 30,
594
+ redisInstanceType: 'cache.t3.small',
595
+ variables: {}
553
596
  });
554
597
  }
555
598
  console.log('');
@@ -559,7 +602,7 @@ async function collectAnswers(rl) {
559
602
  const envPresets = {
560
603
  'production only': ['production'],
561
604
  'dev + production': ['dev', 'production'],
562
- 'dev + staging + production': ['dev', 'staging', 'production'],
605
+ 'dev + staging + production': ['dev', 'staging', 'production']
563
606
  };
564
607
  const envChoice = await askSelect(rl, 'Environments', Object.keys(envPresets), 3);
565
608
  const environments = envPresets[envChoice];
@@ -573,7 +616,9 @@ async function collectAnswers(rl) {
573
616
  for (const appType of appTypes) {
574
617
  domains[appType.suffix] = {};
575
618
  for (const env of environments) {
576
- const suggestion = baseDomain ? defaultDomain(projectName, appType.suffix, env, baseDomain) : '';
619
+ const suggestion = baseDomain
620
+ ? defaultDomain(projectName, appType.suffix, env, baseDomain)
621
+ : '';
577
622
  const appFullName = `${projectName}-${appType.suffix}-${env}`;
578
623
  domains[appType.suffix][env] = await ask(rl, appFullName, suggestion || undefined);
579
624
  }
@@ -592,7 +637,16 @@ async function collectAnswers(rl) {
592
637
  }
593
638
  }
594
639
  console.log('');
595
- return { credentials, projectName, ssl, slackWebhookUrl, appTypes, environments, baseDomain, domains };
640
+ return {
641
+ credentials,
642
+ projectName,
643
+ ssl,
644
+ slackWebhookUrl,
645
+ appTypes,
646
+ environments,
647
+ baseDomain,
648
+ domains
649
+ };
596
650
  }
597
651
  // --- collectAzureAnswers ---
598
652
  async function collectAzureAnswers(rl) {
@@ -604,12 +658,12 @@ async function collectAzureAnswers(rl) {
604
658
  const credFilePath = path.resolve('.fuel-credentials');
605
659
  if (await fs.pathExists(credFilePath)) {
606
660
  try {
607
- const existing = await fs.readJson(credFilePath);
661
+ const existing = (await fs.readJson(credFilePath));
608
662
  console.log('\n Found existing .fuel-credentials');
609
663
  const [azResult, ghUserResult, ghOrgResult] = await Promise.all([
610
664
  tryGetAzureAccountInfo(existing),
611
665
  tryGetGithubUser(existing),
612
- tryGetGithubOrg(existing),
666
+ tryGetGithubOrg(existing)
613
667
  ]);
614
668
  if ('subscriptionId' in azResult) {
615
669
  console.log(` Azure Subscription: ${chalk_1.default.green(azResult.subscriptionId)}`);
@@ -639,7 +693,8 @@ async function collectAzureAnswers(rl) {
639
693
  credentials = existing;
640
694
  }
641
695
  catch (e) {
642
- if (e instanceof Error && e.message.startsWith('Credential verification failed'))
696
+ if (e instanceof Error &&
697
+ e.message.startsWith('Credential verification failed'))
643
698
  throw e;
644
699
  console.log(' Could not read .fuel-credentials — prompting for credentials.');
645
700
  }
@@ -657,7 +712,7 @@ async function collectAzureAnswers(rl) {
657
712
  const [azResult, ghUserResult, ghOrgResult] = await Promise.all([
658
713
  tryGetAzureAccountInfo(credentials),
659
714
  tryGetGithubUser(credentials),
660
- tryGetGithubOrg(credentials),
715
+ tryGetGithubOrg(credentials)
661
716
  ]);
662
717
  if ('subscriptionId' in azResult) {
663
718
  console.log(` Azure Subscription: ${chalk_1.default.green(azResult.subscriptionId)}`);
@@ -710,8 +765,14 @@ async function collectAzureAnswers(rl) {
710
765
  }
711
766
  const redisEnabled = await askYesNo(rl, 'Include Redis?', false);
712
767
  appTypes.push({
713
- suffix: 'api', dockerfile, port, healthCheckPath,
714
- databaseEnabled, databaseEngine, redisEnabled, variables: {},
768
+ suffix: 'api',
769
+ dockerfile,
770
+ port,
771
+ healthCheckPath,
772
+ databaseEnabled,
773
+ databaseEngine,
774
+ redisEnabled,
775
+ variables: {}
715
776
  });
716
777
  }
717
778
  if (includeWeb) {
@@ -720,8 +781,14 @@ async function collectAzureAnswers(rl) {
720
781
  const port = await askInt(rl, 'Port', 3000);
721
782
  const healthCheckPath = await ask(rl, 'Health check path', '/health');
722
783
  appTypes.push({
723
- suffix: 'web', dockerfile, port, healthCheckPath,
724
- databaseEnabled: false, databaseEngine: 'mssql', redisEnabled: false, variables: {},
784
+ suffix: 'web',
785
+ dockerfile,
786
+ port,
787
+ healthCheckPath,
788
+ databaseEnabled: false,
789
+ databaseEngine: 'mssql',
790
+ redisEnabled: false,
791
+ variables: {}
725
792
  });
726
793
  }
727
794
  console.log('');
@@ -731,7 +798,7 @@ async function collectAzureAnswers(rl) {
731
798
  const envPresets = {
732
799
  'production only': ['production'],
733
800
  'dev + production': ['dev', 'production'],
734
- 'dev + staging + production': ['dev', 'staging', 'production'],
801
+ 'dev + staging + production': ['dev', 'staging', 'production']
735
802
  };
736
803
  const envChoice = await askSelect(rl, 'Environments', Object.keys(envPresets), 3);
737
804
  const environments = envPresets[envChoice];
@@ -745,7 +812,9 @@ async function collectAzureAnswers(rl) {
745
812
  for (const appType of appTypes) {
746
813
  domains[appType.suffix] = {};
747
814
  for (const env of environments) {
748
- const suggestion = baseDomain ? defaultDomain(projectName, appType.suffix, env, baseDomain) : '';
815
+ const suggestion = baseDomain
816
+ ? defaultDomain(projectName, appType.suffix, env, baseDomain)
817
+ : '';
749
818
  const appFullName = `${projectName}-${appType.suffix}-${env}`;
750
819
  domains[appType.suffix][env] = await ask(rl, appFullName, suggestion || undefined);
751
820
  }
@@ -764,7 +833,16 @@ async function collectAzureAnswers(rl) {
764
833
  }
765
834
  }
766
835
  console.log('');
767
- return { credentials, projectName, slackWebhookUrl, location, appTypes, environments, baseDomain, domains };
836
+ return {
837
+ credentials,
838
+ projectName,
839
+ slackWebhookUrl,
840
+ location,
841
+ appTypes,
842
+ environments,
843
+ baseDomain,
844
+ domains
845
+ };
768
846
  }
769
847
  // --- applyInfraInitAnswers ---
770
848
  async function applyInfraInitAnswers(answers, opts) {
@@ -808,7 +886,7 @@ async function applyInfraInitAnswers(answers, opts) {
808
886
  memory_units: appType.memoryUnits,
809
887
  variables: {},
810
888
  build_env: {},
811
- workers: [],
889
+ workers: []
812
890
  };
813
891
  if (isApi) {
814
892
  app.postgres = appType.postgres;
@@ -841,10 +919,12 @@ async function applyInfraInitAnswers(answers, opts) {
841
919
  deployment: 'ecs',
842
920
  ssl: answers.ssl,
843
921
  slack_webhook_url: answers.slackWebhookUrl || '',
844
- apps,
922
+ apps
845
923
  };
846
924
  // 4. Guard against overwriting existing config
847
- const outputPath = opts.output ? path.resolve(opts.output) : path.resolve('fuel.yml');
925
+ const outputPath = opts.output
926
+ ? path.resolve(opts.output)
927
+ : path.resolve('fuel.yml');
848
928
  if (await fs.pathExists(outputPath)) {
849
929
  throw new Error(`${outputPath} already exists. Remove it first or use --output <path>.`);
850
930
  }
@@ -899,11 +979,14 @@ async function applyAzureInfraInitAnswers(answers, opts) {
899
979
  branch,
900
980
  variables: {},
901
981
  build_env: {},
902
- workers: [],
982
+ workers: []
903
983
  };
904
984
  if (isApi) {
905
985
  app.variables = appType.variables[env] ?? {};
906
- app.database = { enabled: appType.databaseEnabled, engine: appType.databaseEngine };
986
+ app.database = {
987
+ enabled: appType.databaseEnabled,
988
+ engine: appType.databaseEngine
989
+ };
907
990
  app.redis = { enabled: appType.redisEnabled };
908
991
  }
909
992
  else {
@@ -916,7 +999,10 @@ async function applyAzureInfraInitAnswers(answers, opts) {
916
999
  if (apiDomain)
917
1000
  autoBuildEnv['NEXT_PUBLIC_API_HOST'] = `https://${apiDomain}`;
918
1001
  app.build_env = { ...autoBuildEnv, ...(appType.variables[env] ?? {}) };
919
- app.database = { enabled: false, engine: azure_defaults_1.AZURE_DEFAULTS.database.engine };
1002
+ app.database = {
1003
+ enabled: false,
1004
+ engine: azure_defaults_1.AZURE_DEFAULTS.database.engine
1005
+ };
920
1006
  app.redis = { enabled: false };
921
1007
  }
922
1008
  app.container_app = {
@@ -924,7 +1010,7 @@ async function applyAzureInfraInitAnswers(answers, opts) {
924
1010
  memory: azure_defaults_1.AZURE_DEFAULTS.containerApp.memory,
925
1011
  concurrent_requests: azure_defaults_1.AZURE_DEFAULTS.containerApp.concurrentRequests,
926
1012
  min_replicas: azure_defaults_1.AZURE_DEFAULTS.containerApp.minReplicas,
927
- max_replicas: azure_defaults_1.AZURE_DEFAULTS.containerApp.maxReplicas,
1013
+ max_replicas: azure_defaults_1.AZURE_DEFAULTS.containerApp.maxReplicas
928
1014
  };
929
1015
  apps.push(app);
930
1016
  }
@@ -934,10 +1020,12 @@ async function applyAzureInfraInitAnswers(answers, opts) {
934
1020
  deployment: 'azure',
935
1021
  location: answers.location,
936
1022
  slack_webhook_url: answers.slackWebhookUrl || '',
937
- apps,
1023
+ apps
938
1024
  };
939
1025
  // 4. Guard against overwriting existing config
940
- const outputPath = opts.output ? path.resolve(opts.output) : path.resolve('fuel.yml');
1026
+ const outputPath = opts.output
1027
+ ? path.resolve(opts.output)
1028
+ : path.resolve('fuel.yml');
941
1029
  if (await fs.pathExists(outputPath)) {
942
1030
  throw new Error(`${outputPath} already exists. Remove it first or use --output <path>.`);
943
1031
  }
@@ -961,11 +1049,13 @@ async function collectCredentialsOnly(rl, cloud) {
961
1049
  const credFilePath = path.resolve('.fuel-credentials');
962
1050
  if (await fs.pathExists(credFilePath)) {
963
1051
  try {
964
- const existing = await fs.readJson(credFilePath);
1052
+ const existing = (await fs.readJson(credFilePath));
965
1053
  console.log('\n Found existing .fuel-credentials');
966
1054
  if (cloud === 'aws') {
967
1055
  const [stsResult, ghUserResult, ghOrgResult] = await Promise.all([
968
- tryGetAwsAccountId(existing), tryGetGithubUser(existing), tryGetGithubOrg(existing),
1056
+ tryGetAwsAccountId(existing),
1057
+ tryGetGithubUser(existing),
1058
+ tryGetGithubOrg(existing)
969
1059
  ]);
970
1060
  if ('accountId' in stsResult)
971
1061
  console.log(` AWS Account: ${chalk_1.default.green(stsResult.accountId)}`);
@@ -977,7 +1067,9 @@ async function collectCredentialsOnly(rl, cloud) {
977
1067
  }
978
1068
  else {
979
1069
  const [azResult, ghUserResult, ghOrgResult] = await Promise.all([
980
- tryGetAzureAccountInfo(existing), tryGetGithubUser(existing), tryGetGithubOrg(existing),
1070
+ tryGetAzureAccountInfo(existing),
1071
+ tryGetGithubUser(existing),
1072
+ tryGetGithubOrg(existing)
981
1073
  ]);
982
1074
  if ('subscriptionId' in azResult)
983
1075
  console.log(` Azure Subscription: ${chalk_1.default.green(azResult.subscriptionId)}`);
@@ -995,7 +1087,8 @@ async function collectCredentialsOnly(rl, cloud) {
995
1087
  }
996
1088
  }
997
1089
  catch (e) {
998
- if (e instanceof Error && e.message.startsWith('Credential verification failed'))
1090
+ if (e instanceof Error &&
1091
+ e.message.startsWith('Credential verification failed'))
999
1092
  throw e;
1000
1093
  console.log(' Could not read .fuel-credentials — prompting for credentials.');
1001
1094
  }
@@ -1018,7 +1111,9 @@ async function collectCredentialsOnly(rl, cloud) {
1018
1111
  console.log('\n Verifying credentials...');
1019
1112
  if (cloud === 'aws') {
1020
1113
  const [stsResult, ghUserResult, ghOrgResult] = await Promise.all([
1021
- tryGetAwsAccountId(credentials), tryGetGithubUser(credentials), tryGetGithubOrg(credentials),
1114
+ tryGetAwsAccountId(credentials),
1115
+ tryGetGithubUser(credentials),
1116
+ tryGetGithubOrg(credentials)
1022
1117
  ]);
1023
1118
  if ('accountId' in stsResult)
1024
1119
  console.log(` AWS Account: ${chalk_1.default.green(stsResult.accountId)}`);
@@ -1030,7 +1125,9 @@ async function collectCredentialsOnly(rl, cloud) {
1030
1125
  }
1031
1126
  else {
1032
1127
  const [azResult, ghUserResult, ghOrgResult] = await Promise.all([
1033
- tryGetAzureAccountInfo(credentials), tryGetGithubUser(credentials), tryGetGithubOrg(credentials),
1128
+ tryGetAzureAccountInfo(credentials),
1129
+ tryGetGithubUser(credentials),
1130
+ tryGetGithubOrg(credentials)
1034
1131
  ]);
1035
1132
  if ('subscriptionId' in azResult)
1036
1133
  console.log(` Azure Subscription: ${chalk_1.default.green(azResult.subscriptionId)}`);
@@ -1057,7 +1154,9 @@ async function collectCredentialsOnly(rl, cloud) {
1057
1154
  }
1058
1155
  async function infraInit(opts) {
1059
1156
  if (opts.template) {
1060
- const outputPath = opts.output ? path.resolve(opts.output) : path.resolve('fuel.yml');
1157
+ const outputPath = opts.output
1158
+ ? path.resolve(opts.output)
1159
+ : path.resolve('fuel.yml');
1061
1160
  if (await fs.pathExists(outputPath)) {
1062
1161
  throw new Error(`${outputPath} already exists. Remove it first or use --output <path>.`);
1063
1162
  }
@@ -1071,7 +1170,9 @@ async function infraInit(opts) {
1071
1170
  }
1072
1171
  const rl = (0, promises_1.createInterface)({ input: process.stdin, output: process.stdout });
1073
1172
  try {
1074
- const cloud = opts.azure ? 'azure' : await askCloudChoice(rl);
1173
+ const cloud = opts.azure
1174
+ ? 'azure'
1175
+ : await askCloudChoice(rl);
1075
1176
  if (opts.credentialsOnly) {
1076
1177
  await collectCredentialsOnly(rl, cloud);
1077
1178
  return;