@hed-hog/cli 0.0.88 → 0.0.91

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hed-hog/cli",
3
- "version": "0.0.88",
3
+ "version": "0.0.91",
4
4
  "description": "HedHog CLI tool",
5
5
  "author": "HedHog",
6
6
  "private": false,
@@ -28,8 +28,11 @@ export declare class DeveloperService {
28
28
  private generateRandomHexSecret;
29
29
  private generateRandomBase64Secret;
30
30
  private maskDatabaseUrl;
31
+ private extractGithubRepositoryFromValue;
32
+ private detectGithubRepository;
31
33
  private resolveGithubRepository;
32
34
  private promptForDatabaseUrl;
35
+ private promptForDigitalOceanAccessToken;
33
36
  private setGithubSecret;
34
37
  private promptToConfigureGithubSecrets;
35
38
  private checkHelm;
@@ -188,7 +188,7 @@ let DeveloperService = class DeveloperService {
188
188
  spinner.succeed(chalk.green('Deployment configuration completed successfully!'));
189
189
  // Display summary
190
190
  this.displayDeploymentSummary(config);
191
- await this.promptToConfigureGithubSecrets(path, repo);
191
+ await this.promptToConfigureGithubSecrets(path, repo, config.provider);
192
192
  }
193
193
  catch (error) {
194
194
  spinner.fail('Failed to configure deployment.');
@@ -247,20 +247,52 @@ let DeveloperService = class DeveloperService {
247
247
  maskDatabaseUrl(databaseUrl) {
248
248
  return databaseUrl.replace(/:\/\/([^:/?#]+):([^@]*)@/, '://$1:***@');
249
249
  }
250
- async resolveGithubRepository(path, repo) {
251
- if (repo?.trim()) {
252
- return repo.trim();
250
+ extractGithubRepositoryFromValue(value) {
251
+ const normalizedValue = String(value || '').trim();
252
+ if (!normalizedValue) {
253
+ return undefined;
254
+ }
255
+ if (/^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/.test(normalizedValue)) {
256
+ return normalizedValue;
253
257
  }
258
+ const match = normalizedValue.match(/github\.com[:/]([^/\s]+\/[^/\s]+?)(?:\.git)?(?:[/?#].*)?$/i);
259
+ return match?.[1]?.replace(/\.git$/i, '');
260
+ }
261
+ async detectGithubRepository(path) {
254
262
  try {
255
263
  const result = await this.runner.executeCommand(runner_service_1.ProgramName.GIT, ['remote', 'get-url', 'origin'], { cwd: path }, true);
256
- const remoteUrl = result.stdout.trim();
257
- const match = remoteUrl.match(/github\.com[:/]([^/]+\/[^/.]+?)(?:\.git)?$/i);
258
- if (match?.[1]) {
259
- return match[1];
264
+ const detectedRepo = this.extractGithubRepositoryFromValue(result.stdout.trim());
265
+ if (detectedRepo) {
266
+ return detectedRepo;
260
267
  }
261
268
  }
262
269
  catch {
263
- // Fall through to prompt.
270
+ // Fall through to local project metadata.
271
+ }
272
+ try {
273
+ const packageJsonPath = pathModule.join(path, 'package.json');
274
+ if (!(0, fs_1.existsSync)(packageJsonPath)) {
275
+ return undefined;
276
+ }
277
+ const packageJsonRaw = await (0, promises_1.readFile)(packageJsonPath, 'utf8');
278
+ const packageJson = JSON.parse(packageJsonRaw);
279
+ const repositoryValue = typeof packageJson.repository === 'string'
280
+ ? packageJson.repository
281
+ : packageJson.repository?.url;
282
+ return this.extractGithubRepositoryFromValue(repositoryValue);
283
+ }
284
+ catch {
285
+ return undefined;
286
+ }
287
+ }
288
+ async resolveGithubRepository(path, repo) {
289
+ const explicitRepo = this.extractGithubRepositoryFromValue(repo);
290
+ if (explicitRepo) {
291
+ return explicitRepo;
292
+ }
293
+ const detectedRepo = await this.detectGithubRepository(path);
294
+ if (detectedRepo) {
295
+ return detectedRepo;
264
296
  }
265
297
  while (true) {
266
298
  const answers = await inquirer_1.default.prompt([
@@ -276,7 +308,7 @@ let DeveloperService = class DeveloperService {
276
308
  },
277
309
  },
278
310
  ]);
279
- const resolvedRepo = String(answers.repo || '').trim();
311
+ const resolvedRepo = this.extractGithubRepositoryFromValue(answers.repo);
280
312
  if (resolvedRepo) {
281
313
  return resolvedRepo;
282
314
  }
@@ -299,10 +331,28 @@ let DeveloperService = class DeveloperService {
299
331
  }
300
332
  }
301
333
  }
334
+ async promptForDigitalOceanAccessToken() {
335
+ while (true) {
336
+ const answers = await inquirer_1.default.prompt([
337
+ {
338
+ type: 'password',
339
+ name: 'digitaloceanAccessToken',
340
+ message: 'Enter DIGITALOCEAN_ACCESS_TOKEN:',
341
+ mask: '*',
342
+ validate: (input) => String(input || '').trim().length > 0 ||
343
+ 'DIGITALOCEAN_ACCESS_TOKEN is required.',
344
+ },
345
+ ]);
346
+ const token = String(answers.digitaloceanAccessToken || '').trim();
347
+ if (token) {
348
+ return token;
349
+ }
350
+ }
351
+ }
302
352
  async setGithubSecret(secretName, secretValue, repo) {
303
353
  await this.runner.executeCommand(runner_service_1.ProgramName.GH, ['secret', 'set', secretName, '--repo', repo, '--body', secretValue], {}, true);
304
354
  }
305
- async promptToConfigureGithubSecrets(path, repo) {
355
+ async promptToConfigureGithubSecrets(path, repo, provider) {
306
356
  const { configureSecrets } = await inquirer_1.default.prompt([
307
357
  {
308
358
  type: 'confirm',
@@ -317,9 +367,13 @@ let DeveloperService = class DeveloperService {
317
367
  }
318
368
  console.log(chalk.blue.bold('\nšŸ” GitHub Secrets Setup\n'));
319
369
  await this.ensureGhAuthenticated();
370
+ const requiresDigitalOceanToken = provider === 'digitalocean';
320
371
  const resolvedRepo = await this.resolveGithubRepository(path, repo);
321
372
  const secretsConfig = {
322
373
  databaseUrl: await this.promptForDatabaseUrl(),
374
+ digitaloceanAccessToken: requiresDigitalOceanToken
375
+ ? await this.promptForDigitalOceanAccessToken()
376
+ : undefined,
323
377
  jwtSecret: this.generateRandomHexSecret(32),
324
378
  encryptionSecret: this.generateRandomBase64Secret(32),
325
379
  pepper: this.generateRandomBase64Secret(16),
@@ -327,6 +381,9 @@ let DeveloperService = class DeveloperService {
327
381
  const maskedDatabaseUrl = this.maskDatabaseUrl(secretsConfig.databaseUrl);
328
382
  console.log(chalk.gray(`Repository: ${chalk.cyan(resolvedRepo)}`));
329
383
  console.log(chalk.white(`DATABASE_URL: ${maskedDatabaseUrl}`));
384
+ if (secretsConfig.digitaloceanAccessToken) {
385
+ console.log(chalk.white('DIGITALOCEAN_ACCESS_TOKEN: [provided] (hidden for safety)'));
386
+ }
330
387
  console.log(chalk.white(`JWT_SECRET: ${secretsConfig.jwtSecret.substring(0, 16)}... (64 chars hex)`));
331
388
  console.log(chalk.white(`ENCRYPTION_SECRET: ${secretsConfig.encryptionSecret.substring(0, 16)}... (base64, 32 bytes)`));
332
389
  console.log(chalk.white(`PEPPER: ${secretsConfig.pepper.substring(0, 8)}... (base64, 16 bytes)`));
@@ -349,6 +406,9 @@ let DeveloperService = class DeveloperService {
349
406
  await this.setGithubSecret('JWT_SECRET', secretsConfig.jwtSecret, resolvedRepo);
350
407
  await this.setGithubSecret('ENCRYPTION_SECRET', secretsConfig.encryptionSecret, resolvedRepo);
351
408
  await this.setGithubSecret('PEPPER', secretsConfig.pepper, resolvedRepo);
409
+ if (secretsConfig.digitaloceanAccessToken) {
410
+ await this.setGithubSecret('DIGITALOCEAN_ACCESS_TOKEN', secretsConfig.digitaloceanAccessToken, resolvedRepo);
411
+ }
352
412
  spinner.succeed(chalk.green(`GitHub secrets configured successfully for ${resolvedRepo}.`));
353
413
  console.log(chalk.gray(`Verify with: gh secret list --repo ${resolvedRepo}`));
354
414
  console.log('');