@akash-chowdhury-24/deployhub 1.0.7 → 1.0.8

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@akash-chowdhury-24/deployhub",
3
- "version": "1.0.7",
3
+ "version": "1.0.8",
4
4
  "description": "Zero-configuration deployment and artifact manager",
5
5
  "type": "module",
6
6
  "main": "./src/cli/index.js",
@@ -14,6 +14,7 @@ import { getProjectVersion } from '../utils/version.js';
14
14
  import {
15
15
  writeWorkflowFile,
16
16
  getRequiredSecrets,
17
+ generateEnvExampleContent,
17
18
  guessCliGithubRepo,
18
19
  addDeployhubToPackageJson,
19
20
  } from '../utils/github-actions.js';
@@ -288,25 +289,6 @@ function buildServerEnvEntry(
288
289
  return envEntry;
289
290
  }
290
291
 
291
- /**
292
- * @returns {Promise<string>}
293
- */
294
- async function getEnvExampleContent() {
295
- const possiblePaths = [
296
- path.join(path.dirname(process.execPath), '.env.example'),
297
- path.join(process.cwd(), '.env.example'),
298
- new URL('../../.env.example', import.meta.url).pathname,
299
- ];
300
- for (const p of possiblePaths) {
301
- try {
302
- return await fs.readFile(p, 'utf-8');
303
- } catch {
304
- // try next path
305
- }
306
- }
307
- return '# Add your environment variables here\n';
308
- }
309
-
310
292
  /**
311
293
  * @param {Record<string, unknown>} config
312
294
  * @param {Record<string, Record<string, unknown>>} environments
@@ -780,7 +762,12 @@ export function registerInitCommand(program) {
780
762
  await generateProjectScaffold(config, environments, cwd);
781
763
 
782
764
  const envExampleDest = path.join(cwd, '.env.example');
783
- const envExampleContent = await getEnvExampleContent();
765
+ const envExampleContent = generateEnvExampleContent(
766
+ config.storage,
767
+ deploy,
768
+ environments,
769
+ config
770
+ );
784
771
  await fs.writeFile(envExampleDest, envExampleContent);
785
772
 
786
773
  const secrets = getRequiredSecrets(config.storage, deploy, environments, config);
@@ -1,6 +1,11 @@
1
1
  import fs from 'fs-extra';
2
2
  import path from 'path';
3
- import { PLATFORM_ENV_MAP, PLATFORM_CLI_MAP } from './platform-env.js';
3
+ import {
4
+ PLATFORM_ENV_MAP,
5
+ PLATFORM_CLI_MAP,
6
+ PLATFORM_CHOICES,
7
+ getPlatformEnvExample,
8
+ } from './platform-env.js';
4
9
  import { getWorkflowHeaderComment } from './author.js';
5
10
 
6
11
  /** @typedef {'aws'|'azure'|'gcp'|'gdrive'|'dropbox'|'local'|'ftp'|'ssh'} ProviderEnvKey */
@@ -32,6 +37,28 @@ const BACKEND_SSH_ENV_VARS = [
32
37
  'SSH_PORT',
33
38
  ];
34
39
 
40
+ const PROVIDER_LABELS = {
41
+ aws: 'AWS S3',
42
+ azure: 'Azure Blob',
43
+ gcp: 'GCP',
44
+ gdrive: 'Google Drive',
45
+ dropbox: 'Dropbox',
46
+ ftp: 'FTP',
47
+ ssh: 'SSH Deployment',
48
+ };
49
+
50
+ const PLATFORM_LABELS = Object.fromEntries(
51
+ PLATFORM_CHOICES.map(({ name, value }) => [value, name])
52
+ );
53
+
54
+ const ENV_VAR_DEFAULTS = {
55
+ AWS_REGION: 'us-east-1',
56
+ FTP_PORT: '21',
57
+ FTP_PATH: '/uploads',
58
+ SSH_DEPLOY_PATH: '/var/www/app',
59
+ SMTP_PORT: '587',
60
+ };
61
+
35
62
  const NPM_PACKAGE = '@akash-chowdhury-24/deployhub';
36
63
  const DEFAULT_NPM_CLI_SOURCE = `npm:${NPM_PACKAGE}`;
37
64
 
@@ -400,4 +427,113 @@ export function getRequiredSecrets(
400
427
  return Array.from(secrets);
401
428
  }
402
429
 
430
+ /**
431
+ * @param {string} title
432
+ * @param {string[]} keys
433
+ * @param {Record<string, string>} [defaults]
434
+ * @param {Set<string>} seenKeys
435
+ * @returns {string}
436
+ */
437
+ function formatEnvSection(title, keys, defaults, seenKeys) {
438
+ const newKeys = keys.filter((key) => !seenKeys.has(key));
439
+ if (newKeys.length === 0) return '';
440
+
441
+ for (const key of newKeys) {
442
+ seenKeys.add(key);
443
+ }
444
+
445
+ const lines = newKeys.map((key) => {
446
+ const value = defaults?.[key] ?? ENV_VAR_DEFAULTS[key] ?? '';
447
+ return value ? `${key}=${value}` : `${key}=`;
448
+ });
449
+
450
+ return `# ${title}\n${lines.join('\n')}\n`;
451
+ }
452
+
453
+ /**
454
+ * @param {string[]} storageProviders
455
+ * @param {string[]} deployEnvironments
456
+ * @param {Record<string, Record<string, unknown>>} environments
457
+ * @param {import('../core/config.js').DeployHubConfig} [config]
458
+ * @returns {string}
459
+ */
460
+ export function generateEnvExampleContent(
461
+ storageProviders,
462
+ deployEnvironments,
463
+ environments,
464
+ config = null
465
+ ) {
466
+ /** @type {Set<string>} */
467
+ const seenKeys = new Set();
468
+ /** @type {string[]} */
469
+ const sections = [];
470
+
471
+ const addSection = (title, keys, defaults = {}) => {
472
+ const section = formatEnvSection(title, keys, defaults, seenKeys);
473
+ if (section) sections.push(section);
474
+ };
475
+
476
+ for (const provider of storageProviders) {
477
+ const keys = PROVIDER_ENV_MAP[provider] || [];
478
+ if (keys.length > 0) {
479
+ addSection(PROVIDER_LABELS[provider] || provider, keys);
480
+ }
481
+ }
482
+
483
+ for (const envName of deployEnvironments) {
484
+ const env = environments[envName];
485
+ if (!env) continue;
486
+
487
+ if (env.deploymentType === 'platform' || env.frontendDeploymentType === 'platform') {
488
+ const platform = env.platform;
489
+ if (platform) {
490
+ const examples = getPlatformEnvExample(platform);
491
+ addSection(
492
+ PLATFORM_LABELS[platform] || platform,
493
+ Object.keys(examples),
494
+ examples
495
+ );
496
+ }
497
+ continue;
498
+ }
499
+
500
+ const keys = PROVIDER_ENV_MAP[env.type] || [];
501
+ if (keys.length > 0) {
502
+ addSection(PROVIDER_LABELS[env.type] || env.type, keys);
503
+ }
504
+
505
+ if (env.type === 'ssh' && config) {
506
+ const projectType = config.projectType || 'frontend';
507
+ if (projectType === 'backend' || projectType === 'both') {
508
+ addSection('SSH Deployment (backend)', BACKEND_SSH_ENV_VARS);
509
+ }
510
+ }
511
+ }
512
+
513
+ if (config?.notifications) {
514
+ if (config.notifications.slack) {
515
+ addSection('Notifications', ['SLACK_WEBHOOK_URL']);
516
+ }
517
+ if (config.notifications.webhook) {
518
+ addSection('Notifications', ['WEBHOOK_URL']);
519
+ }
520
+ if (config.notifications.email) {
521
+ addSection('Email (SMTP)', [
522
+ 'SMTP_HOST',
523
+ 'SMTP_PORT',
524
+ 'SMTP_USER',
525
+ 'SMTP_PASS',
526
+ 'NOTIFICATION_EMAIL',
527
+ 'NOTIFY_EMAIL_TO',
528
+ ]);
529
+ }
530
+ }
531
+
532
+ if (sections.length === 0) {
533
+ return '# Add your environment variables here\n';
534
+ }
535
+
536
+ return `${sections.join('\n')}\n`;
537
+ }
538
+
403
539
  export { PROVIDER_ENV_MAP };