@hyperdrive.bot/cli 1.0.13 → 1.0.17

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 (157) hide show
  1. package/README.md +4526 -780
  2. package/dist/commands/deploy.d.ts +18 -0
  3. package/dist/commands/deploy.js +239 -0
  4. package/dist/commands/deployment/create.js +10 -2
  5. package/dist/commands/domain/{switch.d.ts → set-production.d.ts} +1 -1
  6. package/dist/commands/domain/set-production.js +27 -0
  7. package/dist/commands/git/list-open-prs.d.ts +12 -0
  8. package/dist/commands/git/list-open-prs.js +87 -0
  9. package/dist/commands/hook/add.d.ts +22 -0
  10. package/dist/commands/hook/add.js +299 -0
  11. package/dist/commands/hook/list.d.ts +11 -0
  12. package/dist/commands/hook/list.js +111 -0
  13. package/dist/commands/hook/logs.d.ts +13 -0
  14. package/dist/commands/hook/logs.js +124 -0
  15. package/dist/commands/hook/remove.d.ts +12 -0
  16. package/dist/commands/hook/remove.js +115 -0
  17. package/dist/commands/hook/toggle.d.ts +12 -0
  18. package/dist/commands/hook/toggle.js +125 -0
  19. package/dist/commands/init.d.ts +1 -1
  20. package/dist/commands/init.js +49 -9
  21. package/dist/commands/module/bindings.d.ts +14 -0
  22. package/dist/commands/module/bindings.js +125 -0
  23. package/dist/commands/module/create.d.ts +3 -0
  24. package/dist/commands/module/create.js +156 -78
  25. package/dist/commands/module/list.d.ts +1 -0
  26. package/dist/commands/module/list.js +22 -1
  27. package/dist/commands/module/sync.d.ts +29 -0
  28. package/dist/commands/module/sync.js +409 -0
  29. package/dist/commands/module/unlink.d.ts +11 -0
  30. package/dist/commands/module/unlink.js +77 -0
  31. package/dist/commands/module/update.d.ts +10 -0
  32. package/dist/commands/module/update.js +168 -5
  33. package/dist/commands/network/discover.d.ts +12 -0
  34. package/dist/commands/network/discover.js +210 -0
  35. package/dist/commands/network/get.d.ts +13 -0
  36. package/dist/commands/network/get.js +90 -0
  37. package/dist/commands/{auth/logout.d.ts → network/list.d.ts} +2 -9
  38. package/dist/commands/network/list.js +71 -0
  39. package/dist/commands/network/register.d.ts +16 -0
  40. package/dist/commands/network/register.js +144 -0
  41. package/dist/commands/parameter/sync.d.ts +13 -0
  42. package/dist/commands/parameter/sync.js +69 -1
  43. package/dist/commands/project/sync.d.ts +5 -11
  44. package/dist/commands/project/sync.js +12 -381
  45. package/dist/commands/seed.d.ts +93 -0
  46. package/dist/commands/seed.js +324 -0
  47. package/dist/commands/service/backup.d.ts +17 -0
  48. package/dist/commands/service/backup.js +156 -0
  49. package/dist/commands/service/backups.d.ts +14 -0
  50. package/dist/commands/service/backups.js +110 -0
  51. package/dist/commands/service/bind.d.ts +16 -0
  52. package/dist/commands/service/bind.js +106 -0
  53. package/dist/commands/service/bindings.d.ts +13 -0
  54. package/dist/commands/service/bindings.js +78 -0
  55. package/dist/commands/service/clone.d.ts +19 -0
  56. package/dist/commands/service/clone.js +153 -0
  57. package/dist/commands/service/create.d.ts +16 -0
  58. package/dist/commands/service/create.js +212 -0
  59. package/dist/commands/service/get.d.ts +13 -0
  60. package/dist/commands/service/get.js +97 -0
  61. package/dist/commands/service/list.d.ts +12 -0
  62. package/dist/commands/service/list.js +86 -0
  63. package/dist/commands/service/register.d.ts +21 -0
  64. package/dist/commands/service/register.js +215 -0
  65. package/dist/commands/service/restore.d.ts +19 -0
  66. package/dist/commands/service/restore.js +158 -0
  67. package/dist/commands/service/seed.d.ts +17 -0
  68. package/dist/commands/service/seed.js +173 -0
  69. package/dist/commands/service/templates.d.ts +10 -0
  70. package/dist/commands/service/templates.js +66 -0
  71. package/dist/commands/service/unbind.d.ts +15 -0
  72. package/dist/commands/service/unbind.js +74 -0
  73. package/dist/commands/stage/create.d.ts +23 -0
  74. package/dist/commands/stage/create.js +145 -6
  75. package/dist/commands/stage/delete.d.ts +11 -0
  76. package/dist/commands/stage/delete.js +85 -0
  77. package/dist/commands/stage/deploy.d.ts +34 -0
  78. package/dist/commands/stage/deploy.js +294 -0
  79. package/dist/commands/stage/ensure-branches.d.ts +23 -0
  80. package/dist/commands/stage/ensure-branches.js +101 -0
  81. package/dist/commands/stage/list.js +4 -0
  82. package/dist/commands/stage/status.d.ts +14 -0
  83. package/dist/commands/stage/status.js +100 -0
  84. package/dist/commands/{jira → tracker}/connect.js +32 -23
  85. package/dist/commands/tracker/hook/add.d.ts +25 -0
  86. package/dist/commands/tracker/hook/add.js +284 -0
  87. package/dist/commands/{jira → tracker}/hook/list.js +20 -11
  88. package/dist/commands/{jira/hook/add.d.ts → tracker/hook/logs.d.ts} +2 -3
  89. package/dist/commands/tracker/hook/logs.js +126 -0
  90. package/dist/commands/{jira → tracker}/hook/remove.js +9 -8
  91. package/dist/commands/{jira → tracker}/hook/toggle.js +14 -12
  92. package/dist/commands/tracker/project/init.d.ts +17 -0
  93. package/dist/commands/tracker/project/init.js +178 -0
  94. package/dist/commands/tracker/project/link-module.d.ts +17 -0
  95. package/dist/commands/tracker/project/link-module.js +287 -0
  96. package/dist/commands/tracker/project/list-modules.d.ts +11 -0
  97. package/dist/commands/tracker/project/list-modules.js +117 -0
  98. package/dist/commands/tracker/project/list.d.ts +10 -0
  99. package/dist/commands/tracker/project/list.js +90 -0
  100. package/dist/commands/tracker/project/status.d.ts +13 -0
  101. package/dist/commands/tracker/project/status.js +168 -0
  102. package/dist/commands/tracker/project/unlink-module.d.ts +13 -0
  103. package/dist/commands/tracker/project/unlink-module.js +251 -0
  104. package/dist/commands/{jira → tracker}/status.js +3 -3
  105. package/dist/lib/ensure-branches.d.ts +53 -0
  106. package/dist/lib/ensure-branches.js +149 -0
  107. package/dist/lib/git-providers/github.d.ts +16 -0
  108. package/dist/lib/git-providers/github.js +157 -0
  109. package/dist/lib/git-providers/gitlab.d.ts +16 -0
  110. package/dist/lib/git-providers/gitlab.js +148 -0
  111. package/dist/lib/git-providers/index.d.ts +67 -0
  112. package/dist/lib/git-providers/index.js +39 -0
  113. package/dist/lib/lambda-warmer.d.ts +106 -0
  114. package/dist/lib/lambda-warmer.js +189 -0
  115. package/dist/services/hyperdrive-sigv4.d.ts +359 -5
  116. package/dist/services/hyperdrive-sigv4.js +177 -12
  117. package/dist/utils/hook-flow.d.ts +60 -3
  118. package/dist/utils/hook-flow.js +437 -2
  119. package/dist/utils/hook-normalize.d.ts +6 -0
  120. package/dist/utils/hook-normalize.js +33 -0
  121. package/dist/utils/lifecycle-poller.d.ts +32 -0
  122. package/dist/utils/lifecycle-poller.js +72 -0
  123. package/dist/utils/retry.d.ts +43 -0
  124. package/dist/utils/retry.js +88 -0
  125. package/dist/utils/summary-display.js +1 -1
  126. package/dist/utils/tracker-project-flow.d.ts +84 -0
  127. package/dist/utils/tracker-project-flow.js +564 -0
  128. package/package.json +41 -13
  129. package/dist/commands/auth/login.d.ts +0 -16
  130. package/dist/commands/auth/login.js +0 -179
  131. package/dist/commands/auth/logout.js +0 -116
  132. package/dist/commands/auth/refresh.d.ts +0 -6
  133. package/dist/commands/auth/refresh.js +0 -66
  134. package/dist/commands/auth/status.d.ts +0 -6
  135. package/dist/commands/auth/status.js +0 -63
  136. package/dist/commands/config/get.d.ts +0 -9
  137. package/dist/commands/config/get.js +0 -37
  138. package/dist/commands/config/set.d.ts +0 -10
  139. package/dist/commands/config/set.js +0 -48
  140. package/dist/commands/config/show.d.ts +0 -6
  141. package/dist/commands/config/show.js +0 -10
  142. package/dist/commands/domain/current.d.ts +0 -6
  143. package/dist/commands/domain/current.js +0 -18
  144. package/dist/commands/domain/list.d.ts +0 -6
  145. package/dist/commands/domain/list.js +0 -42
  146. package/dist/commands/domain/switch.js +0 -40
  147. package/dist/commands/jira/hook/add.js +0 -147
  148. package/dist/services/tenant-service.d.ts +0 -127
  149. package/dist/services/tenant-service.js +0 -396
  150. package/dist/utils/auth-flow.d.ts +0 -147
  151. package/dist/utils/auth-flow.js +0 -479
  152. package/oclif.manifest.json +0 -3519
  153. /package/dist/commands/{jira → tracker}/connect.d.ts +0 -0
  154. /package/dist/commands/{jira → tracker}/hook/list.d.ts +0 -0
  155. /package/dist/commands/{jira → tracker}/hook/remove.d.ts +0 -0
  156. /package/dist/commands/{jira → tracker}/hook/toggle.d.ts +0 -0
  157. /package/dist/commands/{jira → tracker}/status.d.ts +0 -0
@@ -1,396 +0,0 @@
1
- import axios from 'axios';
2
- import chalk from 'chalk';
3
- import { existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from 'fs';
4
- import { homedir } from 'os';
5
- import { join } from 'path';
6
- /**
7
- * Tenant Service for CLI
8
- *
9
- * Handles tenant resolution and Cognito configuration discovery via bootstrap endpoint.
10
- * Supports environment variables and config file overrides.
11
- */
12
- export class TenantService {
13
- configDir;
14
- configPath;
15
- defaultBootstrapUrl = 'https://api.hyperdrive.bot/tenant/bootstrap';
16
- defaultDomainPath;
17
- domain;
18
- constructor(domain) {
19
- this.configDir = join(homedir(), '.hyperdrive');
20
- this.configPath = join(this.configDir, 'config.json');
21
- this.defaultDomainPath = join(this.configDir, 'default-domain');
22
- this.domain = domain;
23
- }
24
- /**
25
- * Clear cached tenant configuration
26
- */
27
- clearCache() {
28
- const config = this.loadConfigFile();
29
- if (config) {
30
- // Remove tenant-specific settings but keep custom URLs
31
- const { tenantDomain, ...rest } = config;
32
- this.saveConfig(rest);
33
- }
34
- }
35
- /**
36
- * Fetch tenant configuration from bootstrap endpoint
37
- */
38
- async fetchTenantConfig(tenantDomain) {
39
- const domain = tenantDomain || this.getTenantDomain();
40
- if (!domain) {
41
- throw new Error('Tenant not configured. Run `hd init` to set up your environment.');
42
- }
43
- const bootstrapUrl = this.getBootstrapUrl();
44
- try {
45
- console.log(chalk.gray(`🔗 Fetching tenant config for: ${domain}`));
46
- console.log(chalk.gray(`📍 Using bootstrap endpoint: ${bootstrapUrl}`));
47
- const response = await axios.get(bootstrapUrl, {
48
- headers: {
49
- 'Accept': 'application/json',
50
- 'X-Tenant-Domain': domain,
51
- },
52
- });
53
- const bootstrap = response.data;
54
- if (!bootstrap.amplifyConfig) {
55
- throw new Error('Tenant authentication not configured');
56
- }
57
- const { Cognito } = bootstrap.amplifyConfig.Auth;
58
- const region = Cognito.region;
59
- // Extract Cognito domain from OAuth config or construct from tenant ID
60
- // The bootstrap response may provide either:
61
- // - Just the prefix (e.g., "api-tenants-dev-semana-43-a1c4ea06")
62
- // - Full domain (e.g., "api-tenants-dev-devsquad-804677f8.auth.sa-east-1.amazoncognito.com")
63
- let cognitoDomain;
64
- if (Cognito.loginWith?.oauth?.domain) {
65
- const oauthDomain = Cognito.loginWith.oauth.domain;
66
- // Check if domain already includes amazoncognito.com (full domain provided)
67
- if (oauthDomain.includes('.amazoncognito.com')) {
68
- cognitoDomain = oauthDomain;
69
- }
70
- else {
71
- cognitoDomain = `${oauthDomain}.auth.${region}.amazoncognito.com`;
72
- }
73
- }
74
- else {
75
- // Fallback: construct from tenant ID
76
- cognitoDomain = `${bootstrap.tenantId}.auth.${region}.amazoncognito.com`;
77
- }
78
- // Extract all additional API URLs from bootstrap (services self-serve by key)
79
- const additionalApiUrls = this.extractAdditionalApiUrls(bootstrap.amplifyConfig.API);
80
- const config = {
81
- apiUrl: this.getApiUrl(region, bootstrap.amplifyConfig.API, domain),
82
- cognitoClientId: Cognito.userPoolClientId,
83
- cognitoDomain,
84
- cognitoIdentityPoolId: Cognito.identityPoolId || '',
85
- cognitoUserPoolId: Cognito.userPoolId,
86
- displayName: bootstrap.displayName,
87
- region,
88
- tenantDomain: domain,
89
- tenantId: bootstrap.tenantId,
90
- additionalApiUrls: Object.keys(additionalApiUrls).length > 0 ? additionalApiUrls : undefined,
91
- };
92
- // Cache the tenant domain for future use
93
- this.saveTenantDomainToConfig(domain);
94
- // Set as default domain if no default exists
95
- if (!this.getDefaultDomain()) {
96
- this.setDefaultDomain(domain);
97
- }
98
- return config;
99
- }
100
- catch (error) {
101
- if (axios.isAxiosError(error)) {
102
- if (error.response?.status === 404) {
103
- throw new Error(`Tenant not found: ${domain}`);
104
- }
105
- throw new Error(`Failed to fetch tenant config: ${error.response?.data?.message || error.message}`);
106
- }
107
- throw error;
108
- }
109
- }
110
- /**
111
- * Get all configured domains
112
- */
113
- getConfiguredDomains() {
114
- const config = this.loadConfigFile();
115
- const domains = new Set();
116
- // Add legacy single domain if exists
117
- if (config?.tenantDomain) {
118
- domains.add(config.tenantDomain);
119
- }
120
- // Add multi-domain entries
121
- if (config?.domains) {
122
- Object.keys(config.domains).forEach(d => domains.add(d));
123
- }
124
- return Array.from(domains);
125
- }
126
- /**
127
- * Get current tenant configuration (from cache or fetch)
128
- */
129
- async getCurrentTenant() {
130
- return this.fetchTenantConfig();
131
- }
132
- /**
133
- * Get default domain from file
134
- */
135
- getDefaultDomain() {
136
- try {
137
- if (!existsSync(this.defaultDomainPath)) {
138
- return null;
139
- }
140
- return readFileSync(this.defaultDomainPath, 'utf8').trim();
141
- }
142
- catch (error) {
143
- return null;
144
- }
145
- }
146
- /**
147
- * Get tenant domain with fallback chain:
148
- * 1. Constructor domain parameter (from --domain flag)
149
- * 2. Environment variable
150
- * 3. Default domain file
151
- * 4. Legacy single domain from config
152
- * 5. Return null (caller should prompt user interactively)
153
- */
154
- getTenantDomain() {
155
- // Priority 1: Explicit domain parameter (from --domain flag)
156
- if (this.domain) {
157
- return this.domain;
158
- }
159
- // Priority 2: Environment variable
160
- if (process.env.HYPERDRIVE_TENANT_DOMAIN) {
161
- return process.env.HYPERDRIVE_TENANT_DOMAIN;
162
- }
163
- // Priority 3: Default domain file
164
- const defaultDomain = this.getDefaultDomain();
165
- if (defaultDomain) {
166
- return defaultDomain;
167
- }
168
- // Priority 4: Legacy single domain from config file
169
- const config = this.loadConfigFile();
170
- if (config?.tenantDomain) {
171
- return config.tenantDomain;
172
- }
173
- // Priority 5: Return null to trigger interactive prompt
174
- return null;
175
- }
176
- /**
177
- * Save CLI configuration to file
178
- */
179
- saveConfig(config) {
180
- try {
181
- if (!existsSync(this.configDir)) {
182
- mkdirSync(this.configDir, { recursive: true });
183
- }
184
- writeFileSync(this.configPath, JSON.stringify(config, null, 2), { mode: 0o600 });
185
- console.log(chalk.gray(`✓ Configuration saved to ${this.configPath}`));
186
- }
187
- catch (error) {
188
- console.error(chalk.red('Failed to save configuration:'), error);
189
- }
190
- }
191
- /**
192
- * Clear the default domain file
193
- */
194
- clearDefaultDomain() {
195
- try {
196
- if (existsSync(this.defaultDomainPath)) {
197
- unlinkSync(this.defaultDomainPath);
198
- }
199
- }
200
- catch (error) {
201
- console.error(chalk.red('Failed to clear default domain:'), error);
202
- }
203
- }
204
- /**
205
- * Remove a specific domain from config.json domains map
206
- */
207
- removeDomainConfig(domain) {
208
- const config = this.loadConfigFile();
209
- if (!config)
210
- return;
211
- if (config.domains?.[domain]) {
212
- delete config.domains[domain];
213
- }
214
- // If this was the legacy tenantDomain, clear it too
215
- if (config.tenantDomain === domain) {
216
- delete config.tenantDomain;
217
- }
218
- this.saveConfig(config);
219
- }
220
- /**
221
- * Remove the entire config file and default-domain file
222
- */
223
- clearAllConfig() {
224
- try {
225
- if (existsSync(this.configPath)) {
226
- unlinkSync(this.configPath);
227
- }
228
- this.clearDefaultDomain();
229
- }
230
- catch (error) {
231
- console.error(chalk.red('Failed to clear config:'), error);
232
- }
233
- }
234
- /**
235
- * Set default domain
236
- */
237
- setDefaultDomain(domain) {
238
- try {
239
- if (!existsSync(this.configDir)) {
240
- mkdirSync(this.configDir, { recursive: true });
241
- }
242
- writeFileSync(this.defaultDomainPath, domain, { mode: 0o600 });
243
- console.log(chalk.gray(`✓ Default domain set to ${domain}`));
244
- }
245
- catch (error) {
246
- console.error(chalk.red('Failed to set default domain:'), error);
247
- }
248
- }
249
- /**
250
- * Set tenant domain in config file
251
- *
252
- * Public method for init wizard to persist tenant domain configuration.
253
- * Creates config directory if needed and applies 0o600 permissions.
254
- *
255
- * @param domain - The tenant domain to save
256
- */
257
- setTenantDomain(domain) {
258
- this.saveTenantDomainToConfig(domain);
259
- }
260
- /**
261
- * Display current configuration
262
- */
263
- showConfig() {
264
- const config = this.loadConfigFile();
265
- const tenantDomain = this.getTenantDomain();
266
- const bootstrapUrl = this.getBootstrapUrl();
267
- console.log(chalk.blue('🔧 Current Configuration'));
268
- console.log('');
269
- console.log(chalk.white('Bootstrap URL:'), chalk.cyan(bootstrapUrl));
270
- console.log(chalk.white('Source:'), process.env.HYPERDRIVE_BOOTSTRAP_URL
271
- ? chalk.yellow('ENV')
272
- : config?.bootstrapUrl
273
- ? chalk.green('Config File')
274
- : chalk.gray('Default'));
275
- console.log('');
276
- console.log(chalk.white('Tenant Domain:'), tenantDomain ? chalk.cyan(tenantDomain) : chalk.gray('Not set'));
277
- if (tenantDomain) {
278
- console.log(chalk.white('Source:'), process.env.HYPERDRIVE_TENANT_DOMAIN
279
- ? chalk.yellow('ENV')
280
- : config?.tenantDomain
281
- ? chalk.green('Config File')
282
- : chalk.gray('Unknown'));
283
- }
284
- console.log('');
285
- console.log(chalk.gray('Config file: ' + this.configPath));
286
- }
287
- /**
288
- * Get API URL for a region
289
- */
290
- getApiUrl(region, apiConfig, domain) {
291
- // Priority 1: Environment variable (for testing/override)
292
- if (process.env.HYPERDRIVE_API_URL) {
293
- console.log(chalk.gray(`✓ Using API endpoint from environment: ${process.env.HYPERDRIVE_API_URL}`));
294
- return process.env.HYPERDRIVE_API_URL;
295
- }
296
- // Priority 2: Domain-specific config (for multi-domain setups)
297
- const config = this.loadConfigFile();
298
- if (domain && config?.domains?.[domain]?.apiUrl) {
299
- const domainApiUrl = config.domains[domain].apiUrl;
300
- console.log(chalk.gray(`✓ Using API endpoint from domain config: ${domainApiUrl}`));
301
- return domainApiUrl;
302
- }
303
- // Priority 3: Legacy global config file (for manual override)
304
- if (config?.apiUrl) {
305
- console.log(chalk.gray(`✓ Using API endpoint from config: ${config.apiUrl}`));
306
- return config.apiUrl;
307
- }
308
- // Priority 4: From bootstrap API config (REQUIRED - no fallback)
309
- if (apiConfig?.REST?.hyperdrive?.endpoint) {
310
- console.log(chalk.gray(`✓ Using API endpoint from bootstrap: ${apiConfig.REST.hyperdrive.endpoint}`));
311
- return apiConfig.REST.hyperdrive.endpoint;
312
- }
313
- // No hyperdrive endpoint found - user doesn't have access
314
- throw new Error('Hyperdrive API not available for this tenant.\n\n' +
315
- chalk.yellow('This tenant does not have access to Hyperdrive.\n') +
316
- chalk.gray('Please contact your administrator to enable the Hyperdrive module.'));
317
- }
318
- /**
319
- * Extract all additional API URLs from bootstrap REST config.
320
- * Returns a map of module name → endpoint URL for every REST API
321
- * beyond the primary 'hyperdrive' endpoint. Services self-serve
322
- * by looking up the key they need (e.g., 'hyperdrive-projects', 'user-groups').
323
- */
324
- extractAdditionalApiUrls(apiConfig) {
325
- const urls = {};
326
- if (!apiConfig?.REST)
327
- return urls;
328
- for (const [apiName, config] of Object.entries(apiConfig.REST)) {
329
- if (apiName !== 'hyperdrive' && config.endpoint) {
330
- console.log(chalk.gray(`✓ Discovered API endpoint: ${apiName} → ${config.endpoint}`));
331
- urls[apiName] = config.endpoint;
332
- }
333
- }
334
- return urls;
335
- }
336
- /**
337
- * Get bootstrap URL with fallback chain:
338
- * 1. Environment variable
339
- * 2. Config file
340
- * 3. Construct from tenant domain
341
- * 4. Default URL
342
- */
343
- getBootstrapUrl() {
344
- // Priority 1: Environment variable
345
- if (process.env.HYPERDRIVE_BOOTSTRAP_URL) {
346
- return process.env.HYPERDRIVE_BOOTSTRAP_URL;
347
- }
348
- // Priority 2: Config file
349
- const config = this.loadConfigFile();
350
- if (config?.bootstrapUrl) {
351
- return config.bootstrapUrl;
352
- }
353
- // Priority 3: Construct from tenant domain if configured
354
- const tenantDomain = this.getTenantDomain();
355
- if (tenantDomain) {
356
- return `https://${tenantDomain}/tenant/bootstrap`;
357
- }
358
- // Priority 4: Default
359
- return this.defaultBootstrapUrl;
360
- }
361
- /**
362
- * Load CLI configuration from file
363
- */
364
- loadConfigFile() {
365
- try {
366
- if (!existsSync(this.configPath)) {
367
- return null;
368
- }
369
- const data = readFileSync(this.configPath, 'utf8');
370
- return JSON.parse(data);
371
- }
372
- catch (error) {
373
- console.error(chalk.yellow('⚠️ Failed to load config file, using defaults'));
374
- return null;
375
- }
376
- }
377
- /**
378
- * Save tenant domain to config file for future use
379
- */
380
- saveTenantDomainToConfig(tenantDomain) {
381
- const existingConfig = this.loadConfigFile() || {};
382
- // Initialize domains object if it doesn't exist
383
- if (!existingConfig.domains) {
384
- existingConfig.domains = {};
385
- }
386
- // Add this domain to the domains map (even if just an empty object for now)
387
- if (!existingConfig.domains[tenantDomain]) {
388
- existingConfig.domains[tenantDomain] = {};
389
- }
390
- // Also keep legacy tenantDomain for backward compatibility
391
- this.saveConfig({
392
- ...existingConfig,
393
- tenantDomain,
394
- });
395
- }
396
- }
@@ -1,147 +0,0 @@
1
- import { TenantConfig } from '../services/tenant-service.js';
2
- /**
3
- * Options for executing the OAuth PKCE authentication flow
4
- */
5
- export interface AuthFlowOptions {
6
- callbackPort?: number;
7
- logger?: (message: string) => void;
8
- tenantDomain: string;
9
- timeout?: number;
10
- }
11
- /**
12
- * Result of the authentication flow
13
- */
14
- export interface AuthResult {
15
- error?: string;
16
- skipped?: boolean;
17
- success: boolean;
18
- }
19
- /**
20
- * Cognito tokens received from OAuth token exchange
21
- */
22
- export interface CognitoTokens {
23
- access_token: string;
24
- expires_in: number;
25
- id_token: string;
26
- refresh_token: string;
27
- token_type: string;
28
- }
29
- /**
30
- * AWS credentials obtained from Cognito Identity Pool
31
- */
32
- export interface AWSCredentials {
33
- accessKeyId: string;
34
- expiration: Date;
35
- secretAccessKey: string;
36
- sessionToken: string;
37
- }
38
- /**
39
- * Cognito configuration for storing with credentials
40
- */
41
- export interface CognitoConfig {
42
- clientId: string;
43
- domain: string;
44
- identityPoolId: string;
45
- userPoolId: string;
46
- }
47
- /**
48
- * Complete stored credentials including tokens and AWS credentials
49
- */
50
- export interface StoredCredentials extends CognitoTokens {
51
- additionalApiUrls?: Record<string, string>;
52
- apiUrl: string;
53
- awsCredentials: AWSCredentials;
54
- cognitoConfig: CognitoConfig;
55
- obtainedAt: string;
56
- region: string;
57
- tenantDomain: string;
58
- tenantId: string;
59
- }
60
- /**
61
- * Generate PKCE code verifier (random base64url string)
62
- */
63
- export declare function generateCodeVerifier(): string;
64
- /**
65
- * Generate PKCE code challenge (SHA256 hash of verifier)
66
- */
67
- export declare function generateCodeChallenge(verifier: string): string;
68
- /**
69
- * Build Cognito authorization URL with PKCE parameters
70
- */
71
- export declare function buildAuthUrl(tenantConfig: TenantConfig, codeChallenge: string, port: number): string;
72
- /**
73
- * Start local HTTP server to receive OAuth callback
74
- * Returns a promise that resolves with the authorization code
75
- */
76
- export declare function startCallbackServer(port: number, timeout: number): Promise<string>;
77
- /**
78
- * Exchange authorization code for Cognito tokens
79
- */
80
- export declare function exchangeCodeForTokens(tenantConfig: TenantConfig, code: string, codeVerifier: string, port: number): Promise<CognitoTokens>;
81
- /**
82
- * Get AWS credentials from Cognito Identity Pool
83
- */
84
- export declare function getAWSCredentials(tenantConfig: TenantConfig, idToken: string): Promise<AWSCredentials>;
85
- /**
86
- * Save credentials to domain-specific path (always required)
87
- */
88
- export declare function saveCredentials(credentials: StoredCredentials, domain: string): void;
89
- /**
90
- * Get the path to the credentials file for a domain
91
- */
92
- export declare function getCredentialsPath(domain: string): string;
93
- /**
94
- * Execute the complete OAuth PKCE authentication flow
95
- *
96
- * This function orchestrates the entire authentication flow:
97
- * 1. Bootstrap tenant to get Cognito config
98
- * 2. Generate PKCE codes
99
- * 3. Start callback server
100
- * 4. Open browser for authentication
101
- * 5. Wait for callback with timeout
102
- * 6. Exchange code for tokens
103
- * 7. Get AWS credentials from Identity Pool
104
- * 8. Save credentials to file
105
- *
106
- * @param options - Configuration options for the auth flow
107
- * @returns AuthResult indicating success or failure
108
- */
109
- export declare function executeAuthFlow(options: AuthFlowOptions): Promise<AuthResult>;
110
- /**
111
- * Options for CI authentication flow
112
- */
113
- export interface CIAuthOptions {
114
- logger?: (message: string) => void;
115
- password: string;
116
- tenantDomain: string;
117
- username: string;
118
- }
119
- /**
120
- * Execute CI authentication flow using USER_PASSWORD_AUTH
121
- *
122
- * This is for non-interactive CI/CD environments where browser-based
123
- * OAuth is not possible. Uses Cognito's USER_PASSWORD_AUTH flow.
124
- *
125
- * @param options - CI authentication options
126
- * @returns AuthResult indicating success or failure
127
- */
128
- export declare function executeCIAuthFlow(options: CIAuthOptions): Promise<AuthResult>;
129
- /**
130
- * Check if running in a CI environment
131
- */
132
- export declare function isCI(): boolean;
133
- /**
134
- * Decode a CI token into username and password
135
- * Token format: hd_sk_{base64url(username:password)}
136
- */
137
- export declare function decodeToken(token: string): {
138
- password: string;
139
- username: string;
140
- } | null;
141
- /**
142
- * Get CI credentials from HD_TOKEN environment variable
143
- */
144
- export declare function getCICredentials(): {
145
- password: string;
146
- username: string;
147
- } | null;