@guaracloud/cli 0.1.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 (160) hide show
  1. package/bin/dev.js +4 -0
  2. package/bin/run.js +4 -0
  3. package/dist/commands/config/get.d.ts +10 -0
  4. package/dist/commands/config/get.d.ts.map +1 -0
  5. package/dist/commands/config/get.js +21 -0
  6. package/dist/commands/config/get.js.map +1 -0
  7. package/dist/commands/config/list.d.ts +7 -0
  8. package/dist/commands/config/list.d.ts.map +1 -0
  9. package/dist/commands/config/list.js +31 -0
  10. package/dist/commands/config/list.js.map +1 -0
  11. package/dist/commands/config/reset.d.ts +7 -0
  12. package/dist/commands/config/reset.d.ts.map +1 -0
  13. package/dist/commands/config/reset.js +25 -0
  14. package/dist/commands/config/reset.js.map +1 -0
  15. package/dist/commands/config/set.d.ts +11 -0
  16. package/dist/commands/config/set.d.ts.map +1 -0
  17. package/dist/commands/config/set.js +29 -0
  18. package/dist/commands/config/set.js.map +1 -0
  19. package/dist/commands/deploy.d.ts +25 -0
  20. package/dist/commands/deploy.d.ts.map +1 -0
  21. package/dist/commands/deploy.js +115 -0
  22. package/dist/commands/deploy.js.map +1 -0
  23. package/dist/commands/deployments/list.d.ts +7 -0
  24. package/dist/commands/deployments/list.d.ts.map +1 -0
  25. package/dist/commands/deployments/list.js +40 -0
  26. package/dist/commands/deployments/list.js.map +1 -0
  27. package/dist/commands/domains/add.d.ts +17 -0
  28. package/dist/commands/domains/add.d.ts.map +1 -0
  29. package/dist/commands/domains/add.js +41 -0
  30. package/dist/commands/domains/add.js.map +1 -0
  31. package/dist/commands/domains/list.d.ts +7 -0
  32. package/dist/commands/domains/list.d.ts.map +1 -0
  33. package/dist/commands/domains/list.js +32 -0
  34. package/dist/commands/domains/list.js.map +1 -0
  35. package/dist/commands/domains/remove.d.ts +17 -0
  36. package/dist/commands/domains/remove.d.ts.map +1 -0
  37. package/dist/commands/domains/remove.js +60 -0
  38. package/dist/commands/domains/remove.js.map +1 -0
  39. package/dist/commands/env/list.d.ts +7 -0
  40. package/dist/commands/env/list.d.ts.map +1 -0
  41. package/dist/commands/env/list.js +32 -0
  42. package/dist/commands/env/list.js.map +1 -0
  43. package/dist/commands/env/set.d.ts +18 -0
  44. package/dist/commands/env/set.d.ts.map +1 -0
  45. package/dist/commands/env/set.js +70 -0
  46. package/dist/commands/env/set.js.map +1 -0
  47. package/dist/commands/env/unset.d.ts +8 -0
  48. package/dist/commands/env/unset.d.ts.map +1 -0
  49. package/dist/commands/env/unset.js +36 -0
  50. package/dist/commands/env/unset.js.map +1 -0
  51. package/dist/commands/link.d.ts +16 -0
  52. package/dist/commands/link.d.ts.map +1 -0
  53. package/dist/commands/link.js +123 -0
  54. package/dist/commands/link.js.map +1 -0
  55. package/dist/commands/login.d.ts +28 -0
  56. package/dist/commands/login.d.ts.map +1 -0
  57. package/dist/commands/login.js +190 -0
  58. package/dist/commands/login.js.map +1 -0
  59. package/dist/commands/logout.d.ts +7 -0
  60. package/dist/commands/logout.d.ts.map +1 -0
  61. package/dist/commands/logout.js +33 -0
  62. package/dist/commands/logout.js.map +1 -0
  63. package/dist/commands/logs.d.ts +24 -0
  64. package/dist/commands/logs.d.ts.map +1 -0
  65. package/dist/commands/logs.js +174 -0
  66. package/dist/commands/logs.js.map +1 -0
  67. package/dist/commands/open.d.ts +17 -0
  68. package/dist/commands/open.d.ts.map +1 -0
  69. package/dist/commands/open.js +78 -0
  70. package/dist/commands/open.js.map +1 -0
  71. package/dist/commands/projects/create.d.ts +19 -0
  72. package/dist/commands/projects/create.d.ts.map +1 -0
  73. package/dist/commands/projects/create.js +79 -0
  74. package/dist/commands/projects/create.js.map +1 -0
  75. package/dist/commands/projects/info.d.ts +7 -0
  76. package/dist/commands/projects/info.d.ts.map +1 -0
  77. package/dist/commands/projects/info.js +39 -0
  78. package/dist/commands/projects/info.js.map +1 -0
  79. package/dist/commands/projects/list.d.ts +7 -0
  80. package/dist/commands/projects/list.d.ts.map +1 -0
  81. package/dist/commands/projects/list.js +38 -0
  82. package/dist/commands/projects/list.js.map +1 -0
  83. package/dist/commands/rollback.d.ts +17 -0
  84. package/dist/commands/rollback.d.ts.map +1 -0
  85. package/dist/commands/rollback.js +63 -0
  86. package/dist/commands/rollback.js.map +1 -0
  87. package/dist/commands/scale.d.ts +18 -0
  88. package/dist/commands/scale.d.ts.map +1 -0
  89. package/dist/commands/scale.js +96 -0
  90. package/dist/commands/scale.js.map +1 -0
  91. package/dist/commands/services/create.d.ts +23 -0
  92. package/dist/commands/services/create.d.ts.map +1 -0
  93. package/dist/commands/services/create.js +146 -0
  94. package/dist/commands/services/create.js.map +1 -0
  95. package/dist/commands/services/delete.d.ts +7 -0
  96. package/dist/commands/services/delete.d.ts.map +1 -0
  97. package/dist/commands/services/delete.js +41 -0
  98. package/dist/commands/services/delete.js.map +1 -0
  99. package/dist/commands/services/info.d.ts +7 -0
  100. package/dist/commands/services/info.d.ts.map +1 -0
  101. package/dist/commands/services/info.js +46 -0
  102. package/dist/commands/services/info.js.map +1 -0
  103. package/dist/commands/services/list.d.ts +7 -0
  104. package/dist/commands/services/list.d.ts.map +1 -0
  105. package/dist/commands/services/list.js +40 -0
  106. package/dist/commands/services/list.js.map +1 -0
  107. package/dist/commands/services/restart.d.ts +7 -0
  108. package/dist/commands/services/restart.d.ts.map +1 -0
  109. package/dist/commands/services/restart.js +27 -0
  110. package/dist/commands/services/restart.js.map +1 -0
  111. package/dist/commands/services/start.d.ts +7 -0
  112. package/dist/commands/services/start.d.ts.map +1 -0
  113. package/dist/commands/services/start.js +27 -0
  114. package/dist/commands/services/start.js.map +1 -0
  115. package/dist/commands/services/stop.d.ts +7 -0
  116. package/dist/commands/services/stop.d.ts.map +1 -0
  117. package/dist/commands/services/stop.js +27 -0
  118. package/dist/commands/services/stop.js.map +1 -0
  119. package/dist/commands/status.d.ts +11 -0
  120. package/dist/commands/status.d.ts.map +1 -0
  121. package/dist/commands/status.js +87 -0
  122. package/dist/commands/status.js.map +1 -0
  123. package/dist/commands/unlink.d.ts +7 -0
  124. package/dist/commands/unlink.d.ts.map +1 -0
  125. package/dist/commands/unlink.js +43 -0
  126. package/dist/commands/unlink.js.map +1 -0
  127. package/dist/commands/whoami.d.ts +7 -0
  128. package/dist/commands/whoami.d.ts.map +1 -0
  129. package/dist/commands/whoami.js +46 -0
  130. package/dist/commands/whoami.js.map +1 -0
  131. package/dist/index.d.ts +2 -0
  132. package/dist/index.d.ts.map +1 -0
  133. package/dist/index.js +2 -0
  134. package/dist/index.js.map +1 -0
  135. package/dist/lib/api-client.d.ts +96 -0
  136. package/dist/lib/api-client.d.ts.map +1 -0
  137. package/dist/lib/api-client.js +256 -0
  138. package/dist/lib/api-client.js.map +1 -0
  139. package/dist/lib/auth.d.ts +68 -0
  140. package/dist/lib/auth.d.ts.map +1 -0
  141. package/dist/lib/auth.js +180 -0
  142. package/dist/lib/auth.js.map +1 -0
  143. package/dist/lib/base-command.d.ts +94 -0
  144. package/dist/lib/base-command.d.ts.map +1 -0
  145. package/dist/lib/base-command.js +184 -0
  146. package/dist/lib/base-command.js.map +1 -0
  147. package/dist/lib/context.d.ts +58 -0
  148. package/dist/lib/context.d.ts.map +1 -0
  149. package/dist/lib/context.js +147 -0
  150. package/dist/lib/context.js.map +1 -0
  151. package/dist/lib/errors.d.ts +34 -0
  152. package/dist/lib/errors.d.ts.map +1 -0
  153. package/dist/lib/errors.js +143 -0
  154. package/dist/lib/errors.js.map +1 -0
  155. package/dist/lib/output.d.ts +19 -0
  156. package/dist/lib/output.d.ts.map +1 -0
  157. package/dist/lib/output.js +75 -0
  158. package/dist/lib/output.js.map +1 -0
  159. package/oclif.manifest.json +2880 -0
  160. package/package.json +92 -0
@@ -0,0 +1,7 @@
1
+ import { BaseCommand } from '../../lib/base-command.js';
2
+ export default class EnvList extends BaseCommand {
3
+ static description: string;
4
+ static examples: string[];
5
+ run(): Promise<void>;
6
+ }
7
+ //# sourceMappingURL=list.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../src/commands/env/list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAoB,MAAM,2BAA2B,CAAC;AAG1E,MAAM,CAAC,OAAO,OAAO,OAAQ,SAAQ,WAAW;IAC9C,OAAgB,WAAW,SAA+C;IAE1E,OAAgB,QAAQ,WAItB;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CA+B3B"}
@@ -0,0 +1,32 @@
1
+ import { BaseCommand } from '../../lib/base-command.js';
2
+ import { formatTable } from '../../lib/output.js';
3
+ export default class EnvList extends BaseCommand {
4
+ static description = 'List environment variables for a service.';
5
+ static examples = [
6
+ '<%= config.bin %> env list --project my-project --service my-api',
7
+ '<%= config.bin %> env list --json',
8
+ '<%= config.bin %> env list --quiet',
9
+ ];
10
+ async run() {
11
+ const { flags } = await this.parse(EnvList);
12
+ const typedFlags = flags;
13
+ const client = await this.initApiClient(typedFlags);
14
+ const [projectId, serviceId] = await this.requireService(typedFlags, client);
15
+ const response = await client.getEnvVars(projectId, serviceId);
16
+ const variables = response.data.variables;
17
+ if (typedFlags.json) {
18
+ this.outputJson(variables);
19
+ return;
20
+ }
21
+ if (typedFlags.quiet) {
22
+ this.outputQuiet(variables.map((v) => v.key));
23
+ return;
24
+ }
25
+ if (variables.length === 0) {
26
+ this.log('No environment variables set. Add one with `guara env set KEY=value`.');
27
+ return;
28
+ }
29
+ this.log(formatTable(['Key', 'Value'], variables.map((v) => [v.key, v.value])));
30
+ }
31
+ }
32
+ //# sourceMappingURL=list.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.js","sourceRoot":"","sources":["../../../src/commands/env/list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAoB,MAAM,2BAA2B,CAAC;AAC1E,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAElD,MAAM,CAAC,OAAO,OAAO,OAAQ,SAAQ,WAAW;IAC9C,MAAM,CAAU,WAAW,GAAG,2CAA2C,CAAC;IAE1E,MAAM,CAAU,QAAQ,GAAG;QACzB,kEAAkE;QAClE,mCAAmC;QACnC,oCAAoC;KACrC,CAAC;IAEF,KAAK,CAAC,GAAG;QACP,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC5C,MAAM,UAAU,GAAG,KAAoB,CAAC;QAExC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;QACpD,MAAM,CAAC,SAAS,EAAE,SAAS,CAAC,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;QAC7E,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;QAC/D,MAAM,SAAS,GAAG,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC;QAE1C,IAAI,UAAU,CAAC,IAAI,EAAE,CAAC;YACpB,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;YAC3B,OAAO;QACT,CAAC;QAED,IAAI,UAAU,CAAC,KAAK,EAAE,CAAC;YACrB,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YAC9C,OAAO;QACT,CAAC;QAED,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC3B,IAAI,CAAC,GAAG,CAAC,uEAAuE,CAAC,CAAC;YAClF,OAAO;QACT,CAAC;QAED,IAAI,CAAC,GAAG,CACN,WAAW,CACT,CAAC,KAAK,EAAE,OAAO,CAAC,EAChB,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CACvC,CACF,CAAC;IACJ,CAAC"}
@@ -0,0 +1,18 @@
1
+ import { BaseCommand } from '../../lib/base-command.js';
2
+ export default class EnvSet extends BaseCommand {
3
+ static description: string;
4
+ static examples: string[];
5
+ static strict: boolean;
6
+ static flags: {
7
+ 'from-file': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
8
+ json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
9
+ quiet: import("@oclif/core/interfaces").BooleanFlag<boolean>;
10
+ 'api-key': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
11
+ 'api-url': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
12
+ project: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
13
+ service: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
14
+ yes: import("@oclif/core/interfaces").BooleanFlag<boolean>;
15
+ };
16
+ run(): Promise<void>;
17
+ }
18
+ //# sourceMappingURL=set.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"set.d.ts","sourceRoot":"","sources":["../../../src/commands/env/set.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,WAAW,EAAoB,MAAM,2BAA2B,CAAC;AAI1E,MAAM,CAAC,OAAO,OAAO,MAAO,SAAQ,WAAW;IAC7C,OAAgB,WAAW,SAA6D;IAExF,OAAgB,QAAQ,WAItB;IAEF,OAAgB,MAAM,UAAS;IAE/B,OAAgB,KAAK;;;;;;;;;MAKnB;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAiE3B"}
@@ -0,0 +1,70 @@
1
+ import { readFileSync } from 'node:fs';
2
+ import { Flags } from '@oclif/core';
3
+ import { BaseCommand } from '../../lib/base-command.js';
4
+ import { CliError } from '../../lib/errors.js';
5
+ import { successMessage } from '../../lib/output.js';
6
+ export default class EnvSet extends BaseCommand {
7
+ static description = 'Set environment variables (triggers a rolling restart).';
8
+ static examples = [
9
+ '<%= config.bin %> env set KEY=value --project my-project --service my-api',
10
+ '<%= config.bin %> env set KEY1=value1 KEY2=value2',
11
+ '<%= config.bin %> env set --from-file .env',
12
+ ];
13
+ static strict = false;
14
+ static flags = {
15
+ ...BaseCommand.baseFlags,
16
+ 'from-file': Flags.string({
17
+ description: 'Read KEY=VALUE pairs from a .env file.',
18
+ }),
19
+ };
20
+ async run() {
21
+ const { flags, argv } = await this.parse(EnvSet);
22
+ const typedFlags = flags;
23
+ const client = await this.initApiClient(typedFlags);
24
+ const [projectId, serviceId] = await this.requireService(typedFlags, client);
25
+ // ── Collect new variables ──────────────────────────────────────────────
26
+ const newVars = new Map();
27
+ if (typedFlags['from-file']) {
28
+ const content = readFileSync(typedFlags['from-file'], 'utf-8');
29
+ for (const line of content.split('\n')) {
30
+ const trimmed = line.trim();
31
+ if (!trimmed || trimmed.startsWith('#'))
32
+ continue;
33
+ const eqIdx = trimmed.indexOf('=');
34
+ if (eqIdx === -1)
35
+ continue;
36
+ newVars.set(trimmed.slice(0, eqIdx), trimmed.slice(eqIdx + 1));
37
+ }
38
+ }
39
+ for (const arg of argv) {
40
+ const eqIdx = arg.indexOf('=');
41
+ if (eqIdx === -1) {
42
+ throw new CliError(`Invalid format: "${arg}". Use KEY=value.`, 1, 'Each argument must be in KEY=value format, e.g. `guara env set PORT=3000`.');
43
+ }
44
+ newVars.set(arg.slice(0, eqIdx), arg.slice(eqIdx + 1));
45
+ }
46
+ if (newVars.size === 0) {
47
+ throw new CliError('No environment variables specified.', 1, 'Pass KEY=value arguments or use --from-file to load from a .env file.');
48
+ }
49
+ // ── Merge with existing vars ───────────────────────────────────────────
50
+ const { data: existing } = await client.getEnvVars(projectId, serviceId);
51
+ const merged = new Map(existing.variables.map((v) => [v.key, v.value]));
52
+ for (const [key, value] of newVars) {
53
+ merged.set(key, value);
54
+ }
55
+ await client.updateEnvVars(projectId, serviceId, {
56
+ variables: Array.from(merged.entries()).map(([key, value]) => ({ key, value })),
57
+ });
58
+ if (typedFlags.json) {
59
+ this.outputJson({ set: Array.from(newVars.keys()), total: merged.size });
60
+ return;
61
+ }
62
+ if (typedFlags.quiet) {
63
+ this.outputQuiet('ok');
64
+ return;
65
+ }
66
+ this.log(successMessage(`Set ${String(newVars.size)} environment variable(s).`));
67
+ this.log(' This triggers a rolling restart of the service.');
68
+ }
69
+ }
70
+ //# sourceMappingURL=set.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"set.js","sourceRoot":"","sources":["../../../src/commands/env/set.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import { BaseCommand } from '../../lib/base-command.js';
2
+ export default class EnvUnset extends BaseCommand {
3
+ static description: string;
4
+ static examples: string[];
5
+ static strict: boolean;
6
+ run(): Promise<void>;
7
+ }
8
+ //# sourceMappingURL=unset.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unset.d.ts","sourceRoot":"","sources":["../../../src/commands/env/unset.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAoB,MAAM,2BAA2B,CAAC;AAI1E,MAAM,CAAC,OAAO,OAAO,QAAS,SAAQ,WAAW;IAC/C,OAAgB,WAAW,SAAgE;IAE3F,OAAgB,QAAQ,WAGtB;IAEF,OAAgB,MAAM,UAAS;IAEzB,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAmC3B"}
@@ -0,0 +1,36 @@
1
+ import { BaseCommand } from '../../lib/base-command.js';
2
+ import { CliError } from '../../lib/errors.js';
3
+ import { successMessage } from '../../lib/output.js';
4
+ export default class EnvUnset extends BaseCommand {
5
+ static description = 'Remove environment variables (triggers a rolling restart).';
6
+ static examples = [
7
+ '<%= config.bin %> env unset DATABASE_URL --project my-project --service my-api',
8
+ '<%= config.bin %> env unset DATABASE_URL REDIS_URL',
9
+ ];
10
+ static strict = false;
11
+ async run() {
12
+ const { flags, argv } = await this.parse(EnvUnset);
13
+ const typedFlags = flags;
14
+ const client = await this.initApiClient(typedFlags);
15
+ const [projectId, serviceId] = await this.requireService(typedFlags, client);
16
+ const keysToRemove = new Set(argv);
17
+ if (keysToRemove.size === 0) {
18
+ throw new CliError('No keys specified.', 1, 'Pass one or more key names to remove, e.g. `guara env unset DATABASE_URL`.');
19
+ }
20
+ // ── Fetch existing, filter out removed keys, PUT remaining ─────────────
21
+ const { data: existing } = await client.getEnvVars(projectId, serviceId);
22
+ const remaining = existing.variables.filter((v) => !keysToRemove.has(v.key));
23
+ await client.updateEnvVars(projectId, serviceId, { variables: remaining });
24
+ if (typedFlags.json) {
25
+ this.outputJson({ removed: Array.from(keysToRemove) });
26
+ return;
27
+ }
28
+ if (typedFlags.quiet) {
29
+ this.outputQuiet('ok');
30
+ return;
31
+ }
32
+ this.log(successMessage(`Removed ${String(keysToRemove.size)} environment variable(s).`));
33
+ this.log(' This triggers a rolling restart of the service.');
34
+ }
35
+ }
36
+ //# sourceMappingURL=unset.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unset.js","sourceRoot":"","sources":["../../../src/commands/env/unset.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAoB,MAAM,2BAA2B,CAAC;AAC1E,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAErD,MAAM,CAAC,OAAO,OAAO,QAAS,SAAQ,WAAW;IAC/C,MAAM,CAAU,WAAW,GAAG,4DAA4D,CAAC;IAE3F,MAAM,CAAU,QAAQ,GAAG;QACzB,gFAAgF;QAChF,oDAAoD;KACrD,CAAC;IAEF,MAAM,CAAU,MAAM,GAAG,KAAK,CAAC;IAE/B,KAAK,CAAC,GAAG;QACP,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QACnD,MAAM,UAAU,GAAG,KAAoB,CAAC;QAExC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;QACpD,MAAM,CAAC,SAAS,EAAE,SAAS,CAAC,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;QAE7E,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,IAAgB,CAAC,CAAC;QAC/C,IAAI,YAAY,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;YAC5B,MAAM,IAAI,QAAQ,CAChB,oBAAoB,EACpB,CAAC,EACD,4EAA4E,CAC7E,CAAC;QACJ,CAAC;QAED,0EAA0E;QAC1E,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;QACzE,MAAM,SAAS,GAAG,QAAQ,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAE7E,MAAM,MAAM,CAAC,aAAa,CAAC,SAAS,EAAE,SAAS,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC,CAAC;QAE3E,IAAI,UAAU,CAAC,IAAI,EAAE,CAAC;YACpB,IAAI,CAAC,UAAU,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;YACvD,OAAO;QACT,CAAC;QAED,IAAI,UAAU,CAAC,KAAK,EAAE,CAAC;YACrB,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;YACvB,OAAO;QACT,CAAC;QAED,IAAI,CAAC,GAAG,CAAC,cAAc,CAAC,WAAW,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC,CAAC;QAC1F,IAAI,CAAC,GAAG,CAAC,mDAAmD,CAAC,CAAC;IAChE,CAAC"}
@@ -0,0 +1,16 @@
1
+ import { BaseCommand } from '../lib/base-command.js';
2
+ export default class Link extends BaseCommand {
3
+ static description: string;
4
+ static examples: string[];
5
+ static flags: {
6
+ project: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
7
+ service: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
8
+ json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
9
+ quiet: import("@oclif/core/interfaces").BooleanFlag<boolean>;
10
+ 'api-key': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
11
+ 'api-url': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
12
+ yes: import("@oclif/core/interfaces").BooleanFlag<boolean>;
13
+ };
14
+ run(): Promise<void>;
15
+ }
16
+ //# sourceMappingURL=link.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"link.d.ts","sourceRoot":"","sources":["../../src/commands/link.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,WAAW,EAAoB,MAAM,wBAAwB,CAAC;AAevE,MAAM,CAAC,OAAO,OAAO,IAAK,SAAQ,WAAW;IAC3C,OAAgB,WAAW,SACwD;IAEnF,OAAgB,QAAQ,WAKtB;IAEF,OAAgB,KAAK;;;;;;;;MAcnB;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAwH3B"}
@@ -0,0 +1,123 @@
1
+ import * as clack from '@clack/prompts';
2
+ import { Flags } from '@oclif/core';
3
+ import chalk from 'chalk';
4
+ import { BaseCommand } from '../lib/base-command.js';
5
+ import { writeLinkFile, readLinkFile } from '../lib/context.js';
6
+ import { CliError } from '../lib/errors.js';
7
+ import { successMessage } from '../lib/output.js';
8
+ // ─── Command ────────────────────────────────────────────────────────────────
9
+ export default class Link extends BaseCommand {
10
+ static description = 'Link the current directory to a GuaraCloud project (and optionally a service).';
11
+ static examples = [
12
+ '<%= config.bin %> link',
13
+ '<%= config.bin %> link --project my-project',
14
+ '<%= config.bin %> link --project my-project --service my-api',
15
+ '<%= config.bin %> link --yes',
16
+ ];
17
+ static flags = {
18
+ ...BaseCommand.baseFlags,
19
+ project: Flags.string({
20
+ char: 'p',
21
+ description: 'Project slug (skips interactive picker).',
22
+ env: 'GUARA_PROJECT',
23
+ helpGroup: 'GLOBAL',
24
+ }),
25
+ service: Flags.string({
26
+ char: 's',
27
+ description: 'Service slug (skips interactive picker).',
28
+ env: 'GUARA_SERVICE',
29
+ helpGroup: 'GLOBAL',
30
+ }),
31
+ };
32
+ async run() {
33
+ const { flags } = await this.parse(Link);
34
+ const typedFlags = flags;
35
+ const client = await this.initApiClient(typedFlags);
36
+ const cwd = process.cwd();
37
+ // Check for existing link file
38
+ const existingLink = await readLinkFile(cwd);
39
+ if (existingLink && !typedFlags.yes && !typedFlags.json && !typedFlags.quiet) {
40
+ const shouldOverwrite = await clack.confirm({
41
+ message: `This directory is already linked to project "${existingLink.project}"${existingLink.service ? ` / service "${existingLink.service}"` : ''}. Overwrite?`,
42
+ });
43
+ if (clack.isCancel(shouldOverwrite) || !shouldOverwrite) {
44
+ throw new CliError('Link cancelled.', 0);
45
+ }
46
+ }
47
+ // ── Resolve project ──────────────────────────────────────────────────
48
+ let projectSlug = typedFlags.project;
49
+ if (!projectSlug) {
50
+ if (typedFlags.json || typedFlags.quiet) {
51
+ throw new CliError('No project specified.', 1, 'Pass --project <slug> when using --json or --quiet.');
52
+ }
53
+ const projectsResponse = await client.listProjects({ limit: 100 });
54
+ const projects = projectsResponse.data;
55
+ if (projects.length === 0) {
56
+ throw new CliError('No projects found.', 1, 'Create a project first at app.guaracloud.com or with `guara projects create`.');
57
+ }
58
+ const selectedProject = await clack.select({
59
+ message: 'Select a project:',
60
+ options: projects.map((p) => ({
61
+ value: p.slug,
62
+ label: p.name,
63
+ hint: p.slug,
64
+ })),
65
+ });
66
+ if (clack.isCancel(selectedProject)) {
67
+ throw new CliError('Link cancelled.', 0);
68
+ }
69
+ projectSlug = selectedProject;
70
+ }
71
+ // ── Resolve service (optional) ───────────────────────────────────────
72
+ let serviceSlug = typedFlags.service;
73
+ if (!serviceSlug && !typedFlags.json && !typedFlags.quiet) {
74
+ const servicesResponse = await client.listServices(projectSlug, { limit: 100 });
75
+ const services = servicesResponse.data;
76
+ if (services.length > 0) {
77
+ const selectedService = await clack.select({
78
+ message: 'Select a service (optional):',
79
+ options: [
80
+ { value: '__none__', label: 'No service (project only)' },
81
+ ...services.map((s) => ({
82
+ value: s.slug,
83
+ label: s.name,
84
+ hint: s.slug,
85
+ })),
86
+ ],
87
+ });
88
+ if (clack.isCancel(selectedService)) {
89
+ throw new CliError('Link cancelled.', 0);
90
+ }
91
+ if (selectedService !== '__none__') {
92
+ serviceSlug = selectedService;
93
+ }
94
+ }
95
+ }
96
+ // ── Write link file ──────────────────────────────────────────────────
97
+ const link = { project: projectSlug };
98
+ if (serviceSlug) {
99
+ link.service = serviceSlug;
100
+ }
101
+ const filePath = await writeLinkFile(cwd, link);
102
+ const result = {
103
+ project: projectSlug,
104
+ service: serviceSlug,
105
+ path: filePath,
106
+ };
107
+ if (typedFlags.json) {
108
+ this.outputJson(result);
109
+ return;
110
+ }
111
+ if (typedFlags.quiet) {
112
+ const quietValue = serviceSlug ? `${projectSlug}/${serviceSlug}` : projectSlug;
113
+ this.outputQuiet(quietValue);
114
+ return;
115
+ }
116
+ const target = serviceSlug
117
+ ? `${chalk.bold(projectSlug)} / ${chalk.bold(serviceSlug)}`
118
+ : chalk.bold(projectSlug);
119
+ this.log(successMessage(`Linked to ${target}`));
120
+ this.log(chalk.dim(` ${filePath}`));
121
+ }
122
+ }
123
+ //# sourceMappingURL=link.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"link.js","sourceRoot":"","sources":["../../src/commands/link.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import { BaseCommand } from '../lib/base-command.js';
2
+ export default class Login extends BaseCommand {
3
+ static description: string;
4
+ static examples: string[];
5
+ static flags: {
6
+ 'api-key': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
7
+ browser: import("@oclif/core/interfaces").BooleanFlag<boolean>;
8
+ json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
9
+ quiet: import("@oclif/core/interfaces").BooleanFlag<boolean>;
10
+ 'api-url': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
11
+ project: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
12
+ service: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
13
+ yes: import("@oclif/core/interfaces").BooleanFlag<boolean>;
14
+ };
15
+ run(): Promise<void>;
16
+ private validateAndSaveKey;
17
+ /**
18
+ * Browser-based login flow.
19
+ *
20
+ * 1. Starts a local HTTP server on a random port
21
+ * 2. Opens `app.guaracloud.com/cli/auth` with callback_port, state, and hostname
22
+ * 3. User authorises in the browser → web app redirects to localhost callback
23
+ * 4. Local server receives the API key, validates the state token (CSRF protection)
24
+ * 5. Key is validated via `whoami` and persisted
25
+ */
26
+ private loginWithBrowser;
27
+ }
28
+ //# sourceMappingURL=login.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,WAAW,EAAoB,MAAM,wBAAwB,CAAC;AA+DvE,MAAM,CAAC,OAAO,OAAO,KAAM,SAAQ,WAAW;IAC5C,OAAgB,WAAW,SAAmC;IAE9D,OAAgB,QAAQ,WAItB;IAEF,OAAgB,KAAK;;;;;;;;;MAWnB;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;YAeZ,kBAAkB;IAoChC;;;;;;;;OAQG;YACW,gBAAgB;CA8F/B"}
@@ -0,0 +1,190 @@
1
+ import { randomBytes } from 'node:crypto';
2
+ import { hostname as osHostname } from 'node:os';
3
+ import { Flags } from '@oclif/core';
4
+ import chalk from 'chalk';
5
+ import { saveApiKey } from '../lib/auth.js';
6
+ import { BaseCommand } from '../lib/base-command.js';
7
+ import { CliError } from '../lib/errors.js';
8
+ import { successMessage } from '../lib/output.js';
9
+ // ─── Constants ──────────────────────────────────────────────────────────────
10
+ const DEFAULT_APP_URL = 'https://app.guaracloud.com';
11
+ const LOGIN_TIMEOUT_MS = 120_000;
12
+ const SUCCESS_HTML = `<!DOCTYPE html>
13
+ <html>
14
+ <head><title>GuaraCloud CLI</title></head>
15
+ <body style="font-family:system-ui;display:flex;justify-content:center;align-items:center;height:100vh;margin:0;background:#0a0a0a;color:#fafafa">
16
+ <div style="text-align:center">
17
+ <h1 style="font-size:1.5rem;margin-bottom:0.5rem">Authenticated</h1>
18
+ <p style="color:#888">You can close this tab and return to your terminal.</p>
19
+ </div>
20
+ </body>
21
+ </html>`;
22
+ const ERROR_HTML = (msg) => `<!DOCTYPE html>
23
+ <html>
24
+ <head><title>GuaraCloud CLI</title></head>
25
+ <body style="font-family:system-ui;display:flex;justify-content:center;align-items:center;height:100vh;margin:0;background:#0a0a0a;color:#fafafa">
26
+ <div style="text-align:center">
27
+ <h1 style="font-size:1.5rem;color:#ef4444;margin-bottom:0.5rem">Error</h1>
28
+ <p style="color:#888">${msg}</p>
29
+ </div>
30
+ </body>
31
+ </html>`;
32
+ // ─── Helpers ────────────────────────────────────────────────────────────────
33
+ /**
34
+ * Derive the web app URL from the API URL.
35
+ *
36
+ * Maps `api.guaracloud.com` → `app.guaracloud.com`, etc.
37
+ * Falls back to the default app URL if the API URL doesn't follow the convention.
38
+ */
39
+ function deriveAppUrl(apiUrl) {
40
+ try {
41
+ const url = new URL(apiUrl);
42
+ if (url.hostname.startsWith('api.')) {
43
+ url.hostname = url.hostname.replace(/^api\./, 'app.');
44
+ return url.origin;
45
+ }
46
+ return DEFAULT_APP_URL;
47
+ }
48
+ catch {
49
+ return DEFAULT_APP_URL;
50
+ }
51
+ }
52
+ // ─── Command ────────────────────────────────────────────────────────────────
53
+ export default class Login extends BaseCommand {
54
+ static description = 'Authenticate with GuaraCloud.';
55
+ static examples = [
56
+ '<%= config.bin %> login',
57
+ '<%= config.bin %> login --api-key gk_live_xxxxx', // gitleaks:allow
58
+ '<%= config.bin %> login --browser',
59
+ ];
60
+ static flags = {
61
+ ...BaseCommand.baseFlags,
62
+ 'api-key': Flags.string({
63
+ description: 'Authenticate directly with an API key.',
64
+ env: 'GUARA_API_KEY',
65
+ helpGroup: 'GLOBAL',
66
+ }),
67
+ browser: Flags.boolean({
68
+ description: 'Force browser-based OAuth login.',
69
+ default: false,
70
+ }),
71
+ };
72
+ async run() {
73
+ const { flags } = await this.parse(Login);
74
+ const typedFlags = flags;
75
+ const apiKeyValue = typedFlags['api-key'];
76
+ if (apiKeyValue) {
77
+ await this.validateAndSaveKey(apiKeyValue, 'api-key', typedFlags);
78
+ }
79
+ else {
80
+ await this.loginWithBrowser(typedFlags);
81
+ }
82
+ }
83
+ // ─── Shared key validation & persistence ────────────────────────────────
84
+ async validateAndSaveKey(apiKey, method, flags) {
85
+ const client = await this.initApiClient({ ...flags, 'api-key': apiKey });
86
+ const { data: user } = await client.whoami();
87
+ const storage = await saveApiKey(apiKey);
88
+ const result = {
89
+ authenticated: true,
90
+ method,
91
+ storage,
92
+ email: user.email,
93
+ };
94
+ if (flags.json) {
95
+ this.outputJson(result);
96
+ return;
97
+ }
98
+ if (flags.quiet) {
99
+ this.outputQuiet(user.email);
100
+ return;
101
+ }
102
+ this.log(successMessage(`Authenticated as ${chalk.bold(user.email)}`));
103
+ this.log(chalk.dim(` API key stored in ${storage === 'keychain' ? 'system keychain' : 'config file'}.`));
104
+ }
105
+ // ─── Browser login ──────────────────────────────────────────────────────
106
+ /**
107
+ * Browser-based login flow.
108
+ *
109
+ * 1. Starts a local HTTP server on a random port
110
+ * 2. Opens `app.guaracloud.com/cli/auth` with callback_port, state, and hostname
111
+ * 3. User authorises in the browser → web app redirects to localhost callback
112
+ * 4. Local server receives the API key, validates the state token (CSRF protection)
113
+ * 5. Key is validated via `whoami` and persisted
114
+ */
115
+ async loginWithBrowser(flags) {
116
+ if (!process.stdin.isTTY && !flags.browser) {
117
+ throw new CliError('No API key provided and no interactive terminal available.', 1, 'Pass --api-key <key> for non-interactive authentication.');
118
+ }
119
+ const { default: open } = await import('open');
120
+ const http = await import('node:http');
121
+ const apiUrl = flags['api-url'] ?? 'https://api.guaracloud.com';
122
+ const appUrl = deriveAppUrl(apiUrl);
123
+ const state = randomBytes(16).toString('hex');
124
+ const machineHostname = osHostname();
125
+ // Start a local callback server to receive the API key from the browser redirect
126
+ const apiKey = await new Promise((resolve, reject) => {
127
+ const server = http.createServer((req, res) => {
128
+ try {
129
+ const url = new URL(req.url ?? '/', 'http://localhost');
130
+ // CSRF protection: validate the state token matches
131
+ const returnedState = url.searchParams.get('state');
132
+ if (returnedState !== state) {
133
+ res.writeHead(400, { 'Content-Type': 'text/html' });
134
+ res.end(ERROR_HTML('Invalid state parameter. Please try again.'));
135
+ server.close();
136
+ reject(new CliError('Browser login failed: state mismatch.', 1, 'Run `guara login` again.'));
137
+ return;
138
+ }
139
+ const key = url.searchParams.get('key');
140
+ if (!key) {
141
+ res.writeHead(400, { 'Content-Type': 'text/html' });
142
+ res.end(ERROR_HTML('No API key received from the server.'));
143
+ server.close();
144
+ reject(new CliError('Browser login failed: no API key received.'));
145
+ return;
146
+ }
147
+ res.writeHead(200, { 'Content-Type': 'text/html' });
148
+ res.end(SUCCESS_HTML);
149
+ server.close();
150
+ resolve(key);
151
+ }
152
+ catch (err) {
153
+ server.close();
154
+ reject(err instanceof Error ? err : new CliError('Browser login failed unexpectedly.'));
155
+ }
156
+ });
157
+ server.listen(0, '127.0.0.1', () => {
158
+ const address = server.address();
159
+ if (!address || typeof address === 'string') {
160
+ server.close();
161
+ reject(new CliError('Failed to start local callback server.'));
162
+ return;
163
+ }
164
+ const port = address.port;
165
+ const loginUrl = `${appUrl}/cli/auth?callback_port=${String(port)}&state=${encodeURIComponent(state)}&hostname=${encodeURIComponent(machineHostname)}`;
166
+ if (!flags.quiet) {
167
+ this.log('Opening browser to authenticate...');
168
+ this.log(chalk.dim(` ${loginUrl}`));
169
+ }
170
+ open(loginUrl).catch(() => {
171
+ if (!flags.quiet) {
172
+ this.log(chalk.yellow('Could not open browser automatically.'));
173
+ this.log(` Open this URL manually: ${loginUrl}`);
174
+ }
175
+ });
176
+ });
177
+ // Timeout after 2 minutes
178
+ const timeout = setTimeout(() => {
179
+ server.close();
180
+ reject(new CliError('Browser login timed out after 120 seconds.', 1, 'Run `guara login` again.'));
181
+ }, LOGIN_TIMEOUT_MS);
182
+ server.on('close', () => {
183
+ clearTimeout(timeout);
184
+ });
185
+ });
186
+ // Validate the received key and persist it
187
+ await this.validateAndSaveKey(apiKey, 'browser', flags);
188
+ }
189
+ }
190
+ //# sourceMappingURL=login.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import { BaseCommand } from '../lib/base-command.js';
2
+ export default class Logout extends BaseCommand {
3
+ static description: string;
4
+ static examples: string[];
5
+ run(): Promise<void>;
6
+ }
7
+ //# sourceMappingURL=logout.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logout.d.ts","sourceRoot":"","sources":["../../src/commands/logout.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,WAAW,EAAoB,MAAM,wBAAwB,CAAC;AAYvE,MAAM,CAAC,OAAO,OAAO,MAAO,SAAQ,WAAW;IAC7C,OAAgB,WAAW,SAA0D;IAErF,OAAgB,QAAQ,WAAgC;IAElD,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CA2B3B"}