@itssergio91/sandman 0.1.2 → 0.2.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 (80) hide show
  1. package/dist/cli/commands/connect.d.ts +5 -1
  2. package/dist/cli/commands/connect.d.ts.map +1 -1
  3. package/dist/cli/commands/connect.js +22 -20
  4. package/dist/cli/commands/connect.js.map +1 -1
  5. package/dist/cli/commands/create.d.ts +3 -2
  6. package/dist/cli/commands/create.d.ts.map +1 -1
  7. package/dist/cli/commands/create.js +53 -16
  8. package/dist/cli/commands/create.js.map +1 -1
  9. package/dist/cli/commands/destroy.d.ts +1 -0
  10. package/dist/cli/commands/destroy.d.ts.map +1 -1
  11. package/dist/cli/commands/destroy.js +15 -6
  12. package/dist/cli/commands/destroy.js.map +1 -1
  13. package/dist/cli/commands/enable.d.ts +5 -1
  14. package/dist/cli/commands/enable.d.ts.map +1 -1
  15. package/dist/cli/commands/enable.js +29 -14
  16. package/dist/cli/commands/enable.js.map +1 -1
  17. package/dist/cli/commands/init.d.ts +6 -1
  18. package/dist/cli/commands/init.d.ts.map +1 -1
  19. package/dist/cli/commands/init.js +13 -6
  20. package/dist/cli/commands/init.js.map +1 -1
  21. package/dist/cli/commands/status.d.ts +1 -1
  22. package/dist/cli/commands/status.d.ts.map +1 -1
  23. package/dist/cli/commands/status.js +34 -23
  24. package/dist/cli/commands/status.js.map +1 -1
  25. package/dist/cli/index.d.ts.map +1 -1
  26. package/dist/cli/index.js +14 -9
  27. package/dist/cli/index.js.map +1 -1
  28. package/dist/core/state-store.d.ts +3 -3
  29. package/dist/core/state-store.d.ts.map +1 -1
  30. package/dist/core/state-store.js +1 -1
  31. package/dist/core/state-store.js.map +1 -1
  32. package/dist/providers/aws/adapter.d.ts +3 -0
  33. package/dist/providers/aws/adapter.d.ts.map +1 -1
  34. package/dist/providers/aws/adapter.js +331 -9
  35. package/dist/providers/aws/adapter.js.map +1 -1
  36. package/dist/providers/aws/adapter.test.js +107 -0
  37. package/dist/providers/aws/adapter.test.js.map +1 -1
  38. package/dist/providers/base.d.ts +2 -0
  39. package/dist/providers/base.d.ts.map +1 -1
  40. package/dist/providers/base.js +14 -0
  41. package/dist/providers/base.js.map +1 -1
  42. package/dist/providers/cloudflare/adapter.d.ts +12 -0
  43. package/dist/providers/cloudflare/adapter.d.ts.map +1 -0
  44. package/dist/providers/cloudflare/adapter.js +85 -0
  45. package/dist/providers/cloudflare/adapter.js.map +1 -0
  46. package/dist/providers/cloudflare/adapter.test.d.ts +2 -0
  47. package/dist/providers/cloudflare/adapter.test.d.ts.map +1 -0
  48. package/dist/providers/cloudflare/adapter.test.js +178 -0
  49. package/dist/providers/cloudflare/adapter.test.js.map +1 -0
  50. package/dist/providers/gcp/adapter.d.ts +3 -0
  51. package/dist/providers/gcp/adapter.d.ts.map +1 -1
  52. package/dist/providers/gcp/adapter.js +150 -18
  53. package/dist/providers/gcp/adapter.js.map +1 -1
  54. package/dist/providers/gcp/adapter.test.js +122 -15
  55. package/dist/providers/gcp/adapter.test.js.map +1 -1
  56. package/dist/providers/index.d.ts +4 -0
  57. package/dist/providers/index.d.ts.map +1 -0
  58. package/dist/providers/index.js +13 -0
  59. package/dist/providers/index.js.map +1 -0
  60. package/dist/providers/vercel/adapter.d.ts +12 -0
  61. package/dist/providers/vercel/adapter.d.ts.map +1 -0
  62. package/dist/providers/vercel/adapter.js +74 -0
  63. package/dist/providers/vercel/adapter.js.map +1 -0
  64. package/dist/providers/vercel/adapter.test.d.ts +2 -0
  65. package/dist/providers/vercel/adapter.test.d.ts.map +1 -0
  66. package/dist/providers/vercel/adapter.test.js +166 -0
  67. package/dist/providers/vercel/adapter.test.js.map +1 -0
  68. package/dist/types/index.d.ts +21 -21
  69. package/dist/types/index.d.ts.map +1 -1
  70. package/dist/types/index.js +18 -4
  71. package/dist/types/index.js.map +1 -1
  72. package/dist/utils/cost-estimator.d.ts +36 -0
  73. package/dist/utils/cost-estimator.d.ts.map +1 -0
  74. package/dist/utils/cost-estimator.js +87 -0
  75. package/dist/utils/cost-estimator.js.map +1 -0
  76. package/dist/utils/cost-estimator.test.d.ts +2 -0
  77. package/dist/utils/cost-estimator.test.d.ts.map +1 -0
  78. package/dist/utils/cost-estimator.test.js +77 -0
  79. package/dist/utils/cost-estimator.test.js.map +1 -0
  80. package/package.json +1 -1
@@ -1,3 +1,7 @@
1
1
  import { StateStore } from '../../core/state-store.js';
2
- export declare function connectEnvironment(name: string, store: StateStore): Promise<void>;
2
+ interface ConnectOptions {
3
+ json?: boolean;
4
+ }
5
+ export declare function connectEnvironment(name: string, store: StateStore, options?: ConnectOptions): Promise<void>;
6
+ export {};
3
7
  //# sourceMappingURL=connect.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"connect.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/connect.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAKvD,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,UAAU,GAChB,OAAO,CAAC,IAAI,CAAC,CAkEf"}
1
+ {"version":3,"file":"connect.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/connect.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAIvD,UAAU,cAAc;IACtB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,UAAU,EACjB,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC,IAAI,CAAC,CAqEf"}
@@ -1,23 +1,28 @@
1
1
  import chalk from 'chalk';
2
2
  import ora from 'ora';
3
- import { AwsAdapter } from '../../providers/aws/adapter.js';
4
- import { GcpAdapter } from '../../providers/gcp/adapter.js';
5
- export async function connectEnvironment(name, store) {
3
+ import { getAdapter } from '../../providers/index.js';
4
+ export async function connectEnvironment(name, store, options = {}) {
6
5
  const env = await store.getEnvironment(name);
7
6
  if (!env) {
7
+ if (options.json) {
8
+ console.log(JSON.stringify({ success: false, error: `Environment "${name}" not found.` }));
9
+ process.exit(1);
10
+ }
8
11
  console.log(chalk.red(`Environment "${name}" not found.`));
9
12
  process.exit(1);
10
13
  }
11
- if (env.status !== 'active') {
14
+ if (!options.json && env.status !== 'active') {
12
15
  console.log(chalk.yellow(`Environment "${name}" is not active (status: ${env.status}).`));
13
16
  }
14
- const spinner = ora(`Connecting to ${name}...`).start();
17
+ const spinner = options.json ? null : ora(`Connecting to ${name}...`).start();
15
18
  try {
16
- const adapter = env.provider === 'aws'
17
- ? new AwsAdapter()
18
- : new GcpAdapter();
19
+ const adapter = getAdapter(env.provider);
19
20
  const credentials = await adapter.connect(env);
20
- spinner.stop();
21
+ spinner?.stop();
22
+ if (options.json) {
23
+ console.log(JSON.stringify({ success: true, credentials }));
24
+ return;
25
+ }
21
26
  console.log(chalk.bold(`\nConnecting to environment: ${name}\n`));
22
27
  if (env.provider === 'gcp') {
23
28
  console.log(chalk.gray('# GCP Configuration'));
@@ -41,21 +46,18 @@ export async function connectEnvironment(name, store) {
41
46
  }
42
47
  console.log(chalk.gray('\n# Copy to .env:'));
43
48
  console.log(chalk.cyan('SANDMAN_ENV=' + name));
44
- if (credentials.GCP_PROJECT) {
45
- console.log(chalk.cyan('GCP_PROJECT=' + credentials.GCP_PROJECT));
46
- }
47
- if (credentials.AWS_ACCOUNT_ID) {
48
- console.log(chalk.cyan('AWS_ACCOUNT_ID=' + credentials.AWS_ACCOUNT_ID));
49
- }
50
- if (credentials.AWS_REGION) {
51
- console.log(chalk.cyan('AWS_REGION=' + credentials.AWS_REGION));
52
- }
53
- if (credentials.AWS_S3_BUCKET) {
54
- console.log(chalk.cyan('AWS_S3_BUCKET=' + credentials.AWS_S3_BUCKET));
49
+ for (const [key, value] of Object.entries(credentials)) {
50
+ if (key !== 'provider') {
51
+ console.log(chalk.cyan(`${key}=${value}`));
52
+ }
55
53
  }
56
54
  console.log(chalk.green('\n✓ Environment configured'));
57
55
  }
58
56
  catch (error) {
57
+ if (options.json) {
58
+ console.log(JSON.stringify({ success: false, error: error.message }));
59
+ process.exit(1);
60
+ }
59
61
  spinner?.fail?.(chalk.red('Failed to connect'));
60
62
  console.log(chalk.red(`Error: ${error.message}`));
61
63
  process.exit(1);
@@ -1 +1 @@
1
- {"version":3,"file":"connect.js","sourceRoot":"","sources":["../../../src/cli/commands/connect.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,GAAG,MAAM,KAAK,CAAC;AAEtB,OAAO,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAC;AAC5D,OAAO,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAC;AAG5D,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,IAAY,EACZ,KAAiB;IAEjB,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;IAE7C,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,gBAAgB,IAAI,cAAc,CAAC,CAAC,CAAC;QAC3D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,GAAG,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC5B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,gBAAgB,IAAI,4BAA4B,GAAG,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC;IAC5F,CAAC;IAED,MAAM,OAAO,GAAG,GAAG,CAAC,iBAAiB,IAAI,KAAK,CAAC,CAAC,KAAK,EAAE,CAAC;IAExD,IAAI,CAAC;QACH,MAAM,OAAO,GAAoB,GAAG,CAAC,QAAQ,KAAK,KAAK;YACrD,CAAC,CAAC,IAAI,UAAU,EAAE;YAClB,CAAC,CAAC,IAAI,UAAU,EAAE,CAAC;QAErB,MAAM,WAAW,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAE/C,OAAO,CAAC,IAAI,EAAE,CAAC;QAEf,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,gCAAgC,IAAI,IAAI,CAAC,CAAC,CAAC;QAElE,IAAI,GAAG,CAAC,QAAQ,KAAK,KAAK,EAAE,CAAC;YAC3B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC,CAAC;YAC/C,IAAI,WAAW,CAAC,WAAW,EAAE,CAAC;gBAC5B,OAAO,CAAC,GAAG,CAAC,sBAAsB,WAAW,CAAC,WAAW,EAAE,CAAC,CAAC;YAC/D,CAAC;YACD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC,CAAC;YAChD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,6BAA6B,WAAW,CAAC,WAAW,IAAI,cAAc,EAAE,CAAC,CAAC,CAAC;YAClG,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,uCAAuC,CAAC,CAAC,CAAC;QACnE,CAAC;aAAM,IAAI,GAAG,CAAC,QAAQ,KAAK,KAAK,EAAE,CAAC;YAClC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC,CAAC;YAC/C,IAAI,WAAW,CAAC,cAAc,EAAE,CAAC;gBAC/B,OAAO,CAAC,GAAG,CAAC,yBAAyB,WAAW,CAAC,cAAc,EAAE,CAAC,CAAC;YACrE,CAAC;YACD,IAAI,WAAW,CAAC,UAAU,EAAE,CAAC;gBAC3B,OAAO,CAAC,GAAG,CAAC,qBAAqB,WAAW,CAAC,UAAU,EAAE,CAAC,CAAC;YAC7D,CAAC;YACD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC,CAAC;YACjD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC;QAC3C,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC;QAC7C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC,CAAC;QAC/C,IAAI,WAAW,CAAC,WAAW,EAAE,CAAC;YAC5B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,cAAc,GAAG,WAAW,CAAC,WAAW,CAAC,CAAC,CAAC;QACpE,CAAC;QACD,IAAI,WAAW,CAAC,cAAc,EAAE,CAAC;YAC/B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,iBAAiB,GAAG,WAAW,CAAC,cAAc,CAAC,CAAC,CAAC;QAC1E,CAAC;QACD,IAAI,WAAW,CAAC,UAAU,EAAE,CAAC;YAC3B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,aAAa,GAAG,WAAW,CAAC,UAAU,CAAC,CAAC,CAAC;QAClE,CAAC;QACD,IAAI,WAAW,CAAC,aAAa,EAAE,CAAC;YAC9B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,gBAAgB,GAAG,WAAW,CAAC,aAAa,CAAC,CAAC,CAAC;QACxE,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,4BAA4B,CAAC,CAAC,CAAC;IACzD,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QACpB,OAAO,EAAE,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC,CAAC;QAChD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QAClD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"connect.js","sourceRoot":"","sources":["../../../src/cli/commands/connect.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,8 @@
1
- import { StateStore } from '../../core/state-store.js';
2
- import { CreateOptions } from '../../types/index.js';
1
+ import { StateStore } from "../../core/state-store.js";
2
+ import { CreateOptions } from "../../types/index.js";
3
3
  interface CreateParams {
4
4
  dryRun?: boolean;
5
+ json?: boolean;
5
6
  }
6
7
  export declare function createEnvironment(name: string, options: CreateOptions, store: StateStore, params: CreateParams): Promise<void>;
7
8
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/create.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AACvD,OAAO,EAAqB,aAAa,EAAe,MAAM,sBAAsB,CAAC;AAKrF,UAAU,YAAY;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,aAAa,EACtB,KAAK,EAAE,UAAU,EACjB,MAAM,EAAE,YAAY,GACnB,OAAO,CAAC,IAAI,CAAC,CA+Cf"}
1
+ {"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/create.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AACvD,OAAO,EAAE,aAAa,EAAgB,MAAM,sBAAsB,CAAC;AAOnE,UAAU,YAAY;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,aAAa,EACtB,KAAK,EAAE,UAAU,EACjB,MAAM,EAAE,YAAY,GACnB,OAAO,CAAC,IAAI,CAAC,CAyGf"}
@@ -1,43 +1,80 @@
1
- import chalk from 'chalk';
2
- import ora from 'ora';
3
- import { AwsAdapter } from '../../providers/aws/adapter.js';
4
- import { GcpAdapter } from '../../providers/gcp/adapter.js';
1
+ import chalk from "chalk";
2
+ import ora from "ora";
3
+ import { getAdapter } from "../../providers/index.js";
4
+ import { calculateEstimate, formatHourlyRate, } from "../../utils/cost-estimator.js";
5
5
  export async function createEnvironment(name, options, store, params) {
6
6
  const providerConfig = await store.getProvider();
7
- const providerType = options.provider || providerConfig.provider;
7
+ const providerType = (options.provider || providerConfig.provider);
8
8
  if (!providerType) {
9
- console.log(chalk.red('Error: No provider specified.'));
9
+ if (params.json) {
10
+ console.log(JSON.stringify({
11
+ success: false,
12
+ error: 'No provider specified. Run "sandman init <provider>" first.',
13
+ }));
14
+ process.exit(1);
15
+ }
16
+ console.log(chalk.red("Error: No provider specified."));
10
17
  console.log(chalk.gray('Run "sandman init aws" or "sandman init gcp" first.'));
11
18
  process.exit(1);
12
19
  }
13
20
  const existing = await store.getEnvironment(name);
14
21
  if (existing) {
22
+ if (params.json) {
23
+ console.log(JSON.stringify({
24
+ success: false,
25
+ error: `Environment "${name}" already exists.`,
26
+ }));
27
+ process.exit(1);
28
+ }
15
29
  console.log(chalk.red(`Environment "${name}" already exists.`));
16
30
  process.exit(1);
17
31
  }
18
- console.log(chalk.blue(`\nCreating environment "${name}" on ${providerType}...`));
19
- console.log(chalk.yellow(`⚠ Estimated cost: ~$0.10/hour`));
20
- console.log(chalk.gray('⚠ Run "sandman destroy ' + name + '" when finished to avoid ongoing charges\n'));
21
32
  if (params.dryRun) {
22
- console.log(chalk.cyan('[DRY RUN] Would create:'));
33
+ const dryRunResult = {
34
+ dryRun: true,
35
+ name,
36
+ provider: providerType,
37
+ region: options.region || providerConfig.region || "default",
38
+ };
39
+ if (params.json) {
40
+ console.log(JSON.stringify(dryRunResult));
41
+ return;
42
+ }
43
+ console.log(chalk.cyan("[DRY RUN] Would create:"));
23
44
  console.log(chalk.gray(` - Environment: ${name}`));
24
45
  console.log(chalk.gray(` - Provider: ${providerType}`));
25
- console.log(chalk.gray(` - Region: ${options.region || providerConfig.region || 'default'}`));
46
+ console.log(chalk.gray(` - Region: ${dryRunResult.region}`));
26
47
  return;
27
48
  }
28
- const spinner = ora('Creating environment...').start();
49
+ // Calculate estimated cost
50
+ const costEstimate = calculateEstimate(providerType, []);
51
+ const costDisplay = formatHourlyRate(costEstimate.hourlyRate);
52
+ if (!params.json) {
53
+ console.log(chalk.blue(`\nCreating environment "${name}" on ${providerType}...`));
54
+ console.log(chalk.yellow(`⚠ Estimated cost: ${costDisplay}`));
55
+ console.log(chalk.gray('⚠ Run "sandman destroy ' +
56
+ name +
57
+ '" when finished to avoid ongoing charges\n'));
58
+ }
59
+ const spinner = params.json ? null : ora("Creating environment...").start();
29
60
  try {
30
- const adapter = providerType === 'aws'
31
- ? new AwsAdapter()
32
- : new GcpAdapter();
61
+ const adapter = getAdapter(providerType);
33
62
  const env = await adapter.createEnvironment(name);
34
63
  await store.saveEnvironment(env);
64
+ if (params.json) {
65
+ console.log(JSON.stringify({ success: true, environment: env }));
66
+ return;
67
+ }
35
68
  spinner.succeed(chalk.green(`Environment "${name}" created successfully!`));
36
69
  console.log(chalk.cyan(`\n→ Run "sandman status ${name}" to see details`));
37
70
  console.log(chalk.cyan(`→ Run "sandman enable <services> -e ${name}" to enable services`));
38
71
  }
39
72
  catch (error) {
40
- spinner.fail(chalk.red('Failed to create environment'));
73
+ if (params.json) {
74
+ console.log(JSON.stringify({ success: false, error: error.message }));
75
+ process.exit(1);
76
+ }
77
+ spinner.fail(chalk.red("Failed to create environment"));
41
78
  console.log(chalk.red(`Error: ${error.message}`));
42
79
  process.exit(1);
43
80
  }
@@ -1 +1 @@
1
- {"version":3,"file":"create.js","sourceRoot":"","sources":["../../../src/cli/commands/create.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,GAAG,MAAM,KAAK,CAAC;AAGtB,OAAO,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAC;AAC5D,OAAO,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAC;AAO5D,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,IAAY,EACZ,OAAsB,EACtB,KAAiB,EACjB,MAAoB;IAEpB,MAAM,cAAc,GAAG,MAAM,KAAK,CAAC,WAAW,EAAE,CAAC;IACjD,MAAM,YAAY,GAAG,OAAO,CAAC,QAAQ,IAAI,cAAc,CAAC,QAAQ,CAAC;IAEjE,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAC,CAAC;QACxD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,qDAAqD,CAAC,CAAC,CAAC;QAC/E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;IAClD,IAAI,QAAQ,EAAE,CAAC;QACb,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,gBAAgB,IAAI,mBAAmB,CAAC,CAAC,CAAC;QAChE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,2BAA2B,IAAI,QAAQ,YAAY,KAAK,CAAC,CAAC,CAAC;IAClF,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,+BAA+B,CAAC,CAAC,CAAC;IAC3D,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,yBAAyB,GAAG,IAAI,GAAG,4CAA4C,CAAC,CAAC,CAAC;IAEzG,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;QAClB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC,CAAC;QACnD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,oBAAoB,IAAI,EAAE,CAAC,CAAC,CAAC;QACpD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,iBAAiB,YAAY,EAAE,CAAC,CAAC,CAAC;QACzD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,eAAe,OAAO,CAAC,MAAM,IAAI,cAAc,CAAC,MAAM,IAAI,SAAS,EAAE,CAAC,CAAC,CAAC;QAC/F,OAAO;IACT,CAAC;IAED,MAAM,OAAO,GAAG,GAAG,CAAC,yBAAyB,CAAC,CAAC,KAAK,EAAE,CAAC;IAEvD,IAAI,CAAC;QACH,MAAM,OAAO,GAAoB,YAAY,KAAK,KAAK;YACrD,CAAC,CAAC,IAAI,UAAU,EAAE;YAClB,CAAC,CAAC,IAAI,UAAU,EAAE,CAAC;QAErB,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;QAElD,MAAM,KAAK,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC;QAEjC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,gBAAgB,IAAI,yBAAyB,CAAC,CAAC,CAAC;QAC5E,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,2BAA2B,IAAI,kBAAkB,CAAC,CAAC,CAAC;QAC3E,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,uCAAuC,IAAI,sBAAsB,CAAC,CAAC,CAAC;IAC7F,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QACpB,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAC,CAAC;QACxD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QAClD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"create.js","sourceRoot":"","sources":["../../../src/cli/commands/create.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,7 @@
1
1
  import { StateStore } from '../../core/state-store.js';
2
2
  interface DestroyParams {
3
3
  confirmed: boolean;
4
+ json?: boolean;
4
5
  }
5
6
  export declare function destroyEnvironment(name: string, store: StateStore, params?: DestroyParams): Promise<void>;
6
7
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"destroy.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/destroy.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAKvD,UAAU,aAAa;IACrB,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,UAAU,EACjB,MAAM,GAAE,aAAoC,GAC3C,OAAO,CAAC,IAAI,CAAC,CAqDf"}
1
+ {"version":3,"file":"destroy.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/destroy.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAIvD,UAAU,aAAa;IACrB,SAAS,EAAE,OAAO,CAAC;IACnB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,UAAU,EACjB,MAAM,GAAE,aAAoC,GAC3C,OAAO,CAAC,IAAI,CAAC,CA+Df"}
@@ -1,10 +1,13 @@
1
1
  import chalk from 'chalk';
2
2
  import ora from 'ora';
3
- import { AwsAdapter } from '../../providers/aws/adapter.js';
4
- import { GcpAdapter } from '../../providers/gcp/adapter.js';
3
+ import { getAdapter } from '../../providers/index.js';
5
4
  export async function destroyEnvironment(name, store, params = { confirmed: false }) {
6
5
  const env = await store.getEnvironment(name);
7
6
  if (!env) {
7
+ if (params.json) {
8
+ console.log(JSON.stringify({ success: false, error: `Environment "${name}" not found.` }));
9
+ process.exit(1);
10
+ }
8
11
  console.log(chalk.red(`Environment "${name}" not found.`));
9
12
  process.exit(1);
10
13
  }
@@ -27,20 +30,26 @@ export async function destroyEnvironment(name, store, params = { confirmed: fals
27
30
  return;
28
31
  }
29
32
  }
30
- const spinner = ora(`Destroying environment "${name}"...`).start();
33
+ const spinner = params.json ? null : ora(`Destroying environment "${name}"...`).start();
31
34
  try {
32
- const adapter = env.provider === 'aws'
33
- ? new AwsAdapter()
34
- : new GcpAdapter();
35
+ const adapter = getAdapter(env.provider);
35
36
  await adapter.destroyEnvironment(env);
36
37
  const now = new Date().toISOString();
37
38
  env.status = 'destroyed';
38
39
  env.updatedAt = now;
39
40
  await store.saveEnvironment(env);
41
+ if (params.json) {
42
+ console.log(JSON.stringify({ success: true, name, status: 'destroyed' }));
43
+ return;
44
+ }
40
45
  spinner.succeed(chalk.green(`✓ Environment "${name}" destroyed.`));
41
46
  console.log(chalk.gray('Cloud resources cleaned up.'));
42
47
  }
43
48
  catch (error) {
49
+ if (params.json) {
50
+ console.log(JSON.stringify({ success: false, error: error.message }));
51
+ process.exit(1);
52
+ }
44
53
  spinner.fail(chalk.red('Failed to destroy environment'));
45
54
  console.log(chalk.red(`Error: ${error.message}`));
46
55
  process.exit(1);
@@ -1 +1 @@
1
- {"version":3,"file":"destroy.js","sourceRoot":"","sources":["../../../src/cli/commands/destroy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,GAAG,MAAM,KAAK,CAAC;AAEtB,OAAO,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAC;AAC5D,OAAO,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAC;AAO5D,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,IAAY,EACZ,KAAiB,EACjB,SAAwB,EAAE,SAAS,EAAE,KAAK,EAAE;IAE5C,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;IAE7C,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,gBAAgB,IAAI,cAAc,CAAC,CAAC,CAAC;QAC3D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;QACtB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,wCAAwC,IAAI,QAAQ,GAAG,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC;QAC/F,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,8CAA8C,CAAC,CAAC,CAAC;QAExE,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,CAAC;QAC1C,MAAM,EAAE,GAAG,QAAQ,CAAC,eAAe,CAAC;YAClC,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,MAAM,EAAE,OAAO,CAAC,MAAM;SACvB,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,MAAM,IAAI,OAAO,CAAS,CAAC,OAAO,EAAE,EAAE;YACnD,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,0BAA0B,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE;gBAC5D,EAAE,CAAC,KAAK,EAAE,CAAC;gBACX,OAAO,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC;YAC7B,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,IAAI,MAAM,KAAK,KAAK,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;YACvC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC,CAAC;YAC9C,OAAO;QACT,CAAC;IACH,CAAC;IAED,MAAM,OAAO,GAAG,GAAG,CAAC,2BAA2B,IAAI,MAAM,CAAC,CAAC,KAAK,EAAE,CAAC;IAEnE,IAAI,CAAC;QACH,MAAM,OAAO,GAAoB,GAAG,CAAC,QAAQ,KAAK,KAAK;YACrD,CAAC,CAAC,IAAI,UAAU,EAAE;YAClB,CAAC,CAAC,IAAI,UAAU,EAAE,CAAC;QAErB,MAAM,OAAO,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC;QAEtC,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QACrC,GAAG,CAAC,MAAM,GAAG,WAAW,CAAC;QACzB,GAAG,CAAC,SAAS,GAAG,GAAG,CAAC;QAEpB,MAAM,KAAK,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC;QAEjC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,kBAAkB,IAAI,cAAc,CAAC,CAAC,CAAC;QACnE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC,CAAC;IACzD,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QACpB,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAC,CAAC;QACzD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QAClD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"destroy.js","sourceRoot":"","sources":["../../../src/cli/commands/destroy.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,8 @@
1
1
  import { StateStore } from "../../core/state-store.js";
2
2
  import { ServiceName } from "../../types/index.js";
3
- export declare function enableServices(servicesInput: ServiceName[], environmentName: string | undefined, store: StateStore): Promise<void>;
3
+ interface EnableOptions {
4
+ json?: boolean;
5
+ }
6
+ export declare function enableServices(servicesInput: ServiceName[], environmentName: string | undefined, store: StateStore, options?: EnableOptions): Promise<void>;
7
+ export {};
4
8
  //# sourceMappingURL=enable.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"enable.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/enable.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAkBnD,wBAAsB,cAAc,CAClC,aAAa,EAAE,WAAW,EAAE,EAC5B,eAAe,EAAE,MAAM,GAAG,SAAS,EACnC,KAAK,EAAE,UAAU,GAChB,OAAO,CAAC,IAAI,CAAC,CA2Df"}
1
+ {"version":3,"file":"enable.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/enable.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AACvD,OAAO,EAAE,WAAW,EAAgB,MAAM,sBAAsB,CAAC;AAQjE,UAAU,aAAa;IACrB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,wBAAsB,cAAc,CAClC,aAAa,EAAE,WAAW,EAAE,EAC5B,eAAe,EAAE,MAAM,GAAG,SAAS,EACnC,KAAK,EAAE,UAAU,EACjB,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC,IAAI,CAAC,CA8Ef"}
@@ -1,24 +1,19 @@
1
1
  import chalk from "chalk";
2
2
  import ora from "ora";
3
- import { AwsAdapter } from "../../providers/aws/adapter.js";
4
- import { GcpAdapter } from "../../providers/gcp/adapter.js";
3
+ import { getAdapter } from "../../providers/index.js";
5
4
  const VALID_SERVICES = {
6
- gcp: [
7
- "compute",
8
- "storage",
9
- "cloudrun",
10
- "iam",
11
- "pubsub",
12
- "container",
13
- "artifactregistry",
14
- ],
5
+ gcp: ["compute", "storage", "cloudrun", "iam", "pubsub", "container", "artifactregistry"],
15
6
  aws: ["ec2", "s3", "lambda", "iam"],
16
7
  };
17
- export async function enableServices(servicesInput, environmentName, store) {
8
+ export async function enableServices(servicesInput, environmentName, store, options = {}) {
18
9
  let env;
19
10
  if (environmentName) {
20
11
  env = await store.getEnvironment(environmentName);
21
12
  if (!env) {
13
+ if (options.json) {
14
+ console.log(JSON.stringify({ success: false, error: `Environment "${environmentName}" not found.` }));
15
+ process.exit(1);
16
+ }
22
17
  console.log(chalk.red(`Environment "${environmentName}" not found.`));
23
18
  process.exit(1);
24
19
  }
@@ -27,10 +22,18 @@ export async function enableServices(servicesInput, environmentName, store) {
27
22
  const environments = await store.listEnvironments();
28
23
  const active = environments.filter((e) => e.status === "active");
29
24
  if (active.length === 0) {
25
+ if (options.json) {
26
+ console.log(JSON.stringify({ success: false, error: "No active environments found." }));
27
+ process.exit(1);
28
+ }
30
29
  console.log(chalk.red("No active environments found."));
31
30
  process.exit(1);
32
31
  }
33
32
  if (active.length > 1) {
33
+ if (options.json) {
34
+ console.log(JSON.stringify({ success: false, error: "Multiple environments found. Specify one with -e.", environments: active.map(e => e.name) }));
35
+ process.exit(1);
36
+ }
34
37
  console.log(chalk.yellow("Multiple environments found. Specify one:"));
35
38
  for (const e of active) {
36
39
  console.log(chalk.gray(` - ${e.name}`));
@@ -42,21 +45,33 @@ export async function enableServices(servicesInput, environmentName, store) {
42
45
  const validServices = VALID_SERVICES[env.provider];
43
46
  const invalid = servicesInput.filter((s) => !validServices.includes(s));
44
47
  if (invalid.length > 0) {
48
+ if (options.json) {
49
+ console.log(JSON.stringify({ success: false, error: `Invalid services for ${env.provider}: ${invalid.join(", ")}`, validServices }));
50
+ process.exit(1);
51
+ }
45
52
  console.log(chalk.red(`Invalid services for ${env.provider}: ${invalid.join(", ")}`));
46
53
  console.log(chalk.gray(`Valid services: ${validServices.join(", ")}`));
47
54
  process.exit(1);
48
55
  }
49
- const spinner = ora(`Enabling services on ${env.name}...`).start();
56
+ const spinner = options.json ? null : ora(`Enabling services on ${env.name}...`).start();
50
57
  try {
51
- const adapter = env.provider === "aws" ? new AwsAdapter() : new GcpAdapter();
58
+ const adapter = getAdapter(env.provider);
52
59
  await adapter.enableServices(env, servicesInput);
53
60
  const now = new Date().toISOString();
54
61
  env.services = [...new Set([...env.services, ...servicesInput])];
55
62
  env.updatedAt = now;
56
63
  await store.saveEnvironment(env);
64
+ if (options.json) {
65
+ console.log(JSON.stringify({ success: true, environment: env.name, services: env.services }));
66
+ return;
67
+ }
57
68
  spinner.succeed(chalk.green(`✓ Services enabled: ${servicesInput.join(", ")}`));
58
69
  }
59
70
  catch (error) {
71
+ if (options.json) {
72
+ console.log(JSON.stringify({ success: false, error: error.message }));
73
+ process.exit(1);
74
+ }
60
75
  spinner.fail(chalk.red("Failed to enable services"));
61
76
  console.log(chalk.red(`Error: ${error.message}`));
62
77
  process.exit(1);
@@ -1 +1 @@
1
- {"version":3,"file":"enable.js","sourceRoot":"","sources":["../../../src/cli/commands/enable.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"enable.js","sourceRoot":"","sources":["../../../src/cli/commands/enable.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,8 @@
1
1
  import { StateStore } from '../../core/state-store.js';
2
- export declare function initProvider(providerType: 'aws' | 'gcp', region: string | undefined, store: StateStore): Promise<void>;
2
+ import { ProviderType } from '../../types/index.js';
3
+ interface InitOptions {
4
+ json?: boolean;
5
+ }
6
+ export declare function initProvider(providerType: ProviderType, region: string | undefined, store: StateStore, options?: InitOptions): Promise<void>;
7
+ export {};
3
8
  //# sourceMappingURL=init.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/init.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAIvD,wBAAsB,YAAY,CAChC,YAAY,EAAE,KAAK,GAAG,KAAK,EAC3B,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,KAAK,EAAE,UAAU,GAChB,OAAO,CAAC,IAAI,CAAC,CAqBf"}
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/init.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAGpD,UAAU,WAAW;IACnB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,wBAAsB,YAAY,CAChC,YAAY,EAAE,YAAY,EAC1B,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,KAAK,EAAE,UAAU,EACjB,OAAO,GAAE,WAAgB,GACxB,OAAO,CAAC,IAAI,CAAC,CA6Bf"}
@@ -1,20 +1,27 @@
1
1
  import chalk from 'chalk';
2
2
  import ora from 'ora';
3
- import { AwsAdapter } from '../../providers/aws/adapter.js';
4
- import { GcpAdapter } from '../../providers/gcp/adapter.js';
5
- export async function initProvider(providerType, region, store) {
6
- const spinner = ora(`Initializing ${providerType}...`).start();
3
+ import { getAdapter } from '../../providers/index.js';
4
+ export async function initProvider(providerType, region, store, options = {}) {
5
+ const spinner = options.json ? null : ora(`Initializing ${providerType}...`).start();
7
6
  try {
8
- const adapter = providerType === 'aws' ? new AwsAdapter() : new GcpAdapter();
7
+ const adapter = getAdapter(providerType);
9
8
  await adapter.init();
10
- spinner.succeed(chalk.green(`✓ ${providerType} initialized successfully`));
11
9
  await store.setProvider(providerType, region);
10
+ if (options.json) {
11
+ console.log(JSON.stringify({ success: true, provider: providerType, region: region || null }));
12
+ return;
13
+ }
14
+ spinner.succeed(chalk.green(`✓ ${providerType} initialized successfully`));
12
15
  console.log(chalk.gray(`Default region: ${region || 'not set'}`));
13
16
  if (providerType === 'gcp') {
14
17
  console.log(chalk.cyan('\n→ Run "sandman create <name>" to create an environment'));
15
18
  }
16
19
  }
17
20
  catch (error) {
21
+ if (options.json) {
22
+ console.log(JSON.stringify({ success: false, provider: providerType, error: error.message }));
23
+ process.exit(1);
24
+ }
18
25
  spinner.fail(chalk.red(`Failed to initialize ${providerType}`));
19
26
  console.log(chalk.red(`Error: ${error.message}`));
20
27
  process.exit(1);
@@ -1 +1 @@
1
- {"version":3,"file":"init.js","sourceRoot":"","sources":["../../../src/cli/commands/init.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,GAAG,MAAM,KAAK,CAAC;AAEtB,OAAO,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAC;AAC5D,OAAO,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAC;AAE5D,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,YAA2B,EAC3B,MAA0B,EAC1B,KAAiB;IAEjB,MAAM,OAAO,GAAG,GAAG,CAAC,gBAAgB,YAAY,KAAK,CAAC,CAAC,KAAK,EAAE,CAAC;IAE/D,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,YAAY,KAAK,KAAK,CAAC,CAAC,CAAC,IAAI,UAAU,EAAE,CAAC,CAAC,CAAC,IAAI,UAAU,EAAE,CAAC;QAE7E,MAAM,OAAO,CAAC,IAAI,EAAE,CAAC;QAErB,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,YAAY,2BAA2B,CAAC,CAAC,CAAC;QAE3E,MAAM,KAAK,CAAC,WAAW,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;QAC9C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,mBAAmB,MAAM,IAAI,SAAS,EAAE,CAAC,CAAC,CAAC;QAElE,IAAI,YAAY,KAAK,KAAK,EAAE,CAAC;YAC3B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,0DAA0D,CAAC,CAAC,CAAC;QACtF,CAAC;IACH,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QACpB,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,wBAAwB,YAAY,EAAE,CAAC,CAAC,CAAC;QAChE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QAClD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../../src/cli/commands/init.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,GAAG,MAAM,KAAK,CAAC;AAGtB,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAMtD,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,YAA0B,EAC1B,MAA0B,EAC1B,KAAiB,EACjB,UAAuB,EAAE;IAEzB,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,gBAAgB,YAAY,KAAK,CAAC,CAAC,KAAK,EAAE,CAAC;IAErF,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,UAAU,CAAC,YAAY,CAAC,CAAC;QACzC,MAAM,OAAO,CAAC,IAAI,EAAE,CAAC;QAErB,MAAM,KAAK,CAAC,WAAW,CAAC,YAAmB,EAAE,MAAM,CAAC,CAAC;QAErD,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;YACjB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC;YAC/F,OAAO;QACT,CAAC;QAED,OAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,YAAY,2BAA2B,CAAC,CAAC,CAAC;QAC5E,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,mBAAmB,MAAM,IAAI,SAAS,EAAE,CAAC,CAAC,CAAC;QAElE,IAAI,YAAY,KAAK,KAAK,EAAE,CAAC;YAC3B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,0DAA0D,CAAC,CAAC,CAAC;QACtF,CAAC;IACH,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QACpB,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;YACjB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,KAAK,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;YAC9F,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QACD,OAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,wBAAwB,YAAY,EAAE,CAAC,CAAC,CAAC;QACjE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QAClD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
@@ -1,4 +1,4 @@
1
- import { StateStore } from '../../core/state-store.js';
1
+ import { StateStore } from "../../core/state-store.js";
2
2
  interface StatusOptions {
3
3
  json?: boolean;
4
4
  }
@@ -1 +1 @@
1
- {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/status.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAQvD,UAAU,aAAa;IACrB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,UAAU,EACjB,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC,IAAI,CAAC,CAoDf"}
1
+ {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/status.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAQvD,UAAU,aAAa;IACrB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,UAAU,EACjB,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC,IAAI,CAAC,CA4Ff"}
@@ -1,47 +1,58 @@
1
- import chalk from 'chalk';
2
- const COST_ESTIMATES = {
3
- gcp: { hourly: '~$0.01-0.05/hour', description: 'Project base + APIs enabled' },
4
- aws: { hourly: '~$0.01-0.10/hour', description: 'S3 storage + Lambda requests' },
5
- };
1
+ import chalk from "chalk";
2
+ import { calculateRunningCost, formatCost, formatHourlyRate, } from "../../utils/cost-estimator.js";
6
3
  export async function statusEnvironment(name, store, options = {}) {
7
4
  const env = await store.getEnvironment(name);
8
5
  if (!env) {
9
6
  console.log(chalk.red(`Environment "${name}" not found.`));
10
7
  process.exit(1);
11
8
  }
12
- if (options.json) {
13
- console.log(JSON.stringify(env, null, 2));
14
- return;
15
- }
16
- const cost = COST_ESTIMATES[env.provider] || { hourly: 'Unknown', description: '' };
9
+ // Calculate running costs
10
+ const runningCost = calculateRunningCost(env.provider, env.services, env.createdAt);
17
11
  const age = Date.now() - new Date(env.createdAt).getTime();
18
12
  const hours = Math.floor(age / (1000 * 60 * 60));
19
13
  const minutes = Math.floor((age % (1000 * 60 * 60)) / (1000 * 60));
14
+ if (options.json) {
15
+ console.log(JSON.stringify({
16
+ ...env,
17
+ costEstimate: {
18
+ hourlyRate: runningCost.hourlyRate,
19
+ hoursRunning: runningCost.hoursRunning,
20
+ totalCost: runningCost.totalCost,
21
+ estimatedDaily: runningCost.estimatedDaily,
22
+ estimatedMonthly: runningCost.estimatedMonthly,
23
+ },
24
+ }, null, 2));
25
+ return;
26
+ }
20
27
  console.log(chalk.bold(`\nEnvironment: ${env.name}\n`));
21
- console.log(` ${chalk.gray('Provider:')} ${env.provider}`);
22
- console.log(` ${chalk.gray('Status:')} ${env.status === 'active' ? chalk.green(env.status) : chalk.red(env.status)}`);
23
- console.log(` ${chalk.gray('Created:')} ${new Date(env.createdAt).toLocaleString()}`);
24
- console.log(` ${chalk.gray('Age:')} ${hours}h ${minutes}m`);
28
+ console.log(` ${chalk.gray("Provider:")} ${env.provider}`);
29
+ console.log(` ${chalk.gray("Status:")} ${env.status === "active" ? chalk.green(env.status) : chalk.red(env.status)}`);
30
+ console.log(` ${chalk.gray("Created:")} ${new Date(env.createdAt).toLocaleString()}`);
31
+ console.log(` ${chalk.gray("Age:")} ${hours}h ${minutes}m`);
25
32
  if (env.projectId) {
26
- console.log(` ${chalk.gray('Project ID:')} ${env.projectId}`);
33
+ console.log(` ${chalk.gray("Project ID:")} ${env.projectId}`);
27
34
  }
28
35
  if (env.accountId) {
29
- console.log(` ${chalk.gray('Account ID:')} ${env.accountId}`);
36
+ console.log(` ${chalk.gray("Account ID:")} ${env.accountId}`);
30
37
  }
31
38
  if (env.region) {
32
- console.log(` ${chalk.gray('Region:')} ${env.region}`);
39
+ console.log(` ${chalk.gray("Region:")} ${env.region}`);
33
40
  }
34
41
  if (env.services.length > 0) {
35
- console.log(` ${chalk.gray('Services:')} ${env.services.join(', ')}`);
42
+ console.log(` ${chalk.gray("Services:")} ${env.services.join(", ")}`);
36
43
  }
37
44
  const resourceCount = Object.keys(env.resources).length;
38
45
  if (resourceCount > 0) {
39
- console.log(` ${chalk.gray('Resources:')} ${resourceCount} created`);
40
- }
41
- console.log(`\n ${chalk.gray('Est. cost:')} ${cost.hourly}`);
42
- console.log(chalk.gray(` ${cost.description}`));
46
+ console.log(` ${chalk.gray("Resources:")} ${resourceCount} created`);
47
+ }
48
+ console.log(`\n ${chalk.gray("Cost Estimate:")}`);
49
+ console.log(` ${chalk.gray("Hourly rate:")} ${formatHourlyRate(runningCost.hourlyRate)}`);
50
+ console.log(` ${chalk.gray("Hours running:")} ${runningCost.hoursRunning}h`);
51
+ console.log(` ${chalk.yellow("Current cost:")} ${formatCost(runningCost.totalCost)}`);
52
+ console.log(` ${chalk.gray("Est. daily:")} ${formatCost(runningCost.estimatedDaily)}`);
53
+ console.log(` ${chalk.gray("Est. monthly:")} ${formatCost(runningCost.estimatedMonthly)}`);
43
54
  if (env.error) {
44
- console.log(`\n ${chalk.red('Error:')} ${env.error}`);
55
+ console.log(`\n ${chalk.red("Error:")} ${env.error}`);
45
56
  }
46
57
  console.log(chalk.cyan(`\n→ Run "sandman connect ${name}" to get credentials`));
47
58
  console.log(chalk.cyan(`→ Run "sandman destroy ${name}" to clean up`));