@devalade/shipnode 2.0.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 (189) hide show
  1. package/dist/cli/commands/backup.d.ts +14 -0
  2. package/dist/cli/commands/backup.d.ts.map +1 -0
  3. package/dist/cli/commands/backup.js +144 -0
  4. package/dist/cli/commands/backup.js.map +1 -0
  5. package/dist/cli/commands/ci.d.ts +5 -0
  6. package/dist/cli/commands/ci.d.ts.map +1 -0
  7. package/dist/cli/commands/ci.js +222 -0
  8. package/dist/cli/commands/ci.js.map +1 -0
  9. package/dist/cli/commands/cloudflare.d.ts +10 -0
  10. package/dist/cli/commands/cloudflare.d.ts.map +1 -0
  11. package/dist/cli/commands/cloudflare.js +166 -0
  12. package/dist/cli/commands/cloudflare.js.map +1 -0
  13. package/dist/cli/commands/config.d.ts +10 -0
  14. package/dist/cli/commands/config.d.ts.map +1 -0
  15. package/dist/cli/commands/config.js +99 -0
  16. package/dist/cli/commands/config.js.map +1 -0
  17. package/dist/cli/commands/deploy.d.ts +6 -0
  18. package/dist/cli/commands/deploy.d.ts.map +1 -0
  19. package/dist/cli/commands/deploy.js +95 -0
  20. package/dist/cli/commands/deploy.js.map +1 -0
  21. package/dist/cli/commands/doctor.d.ts +5 -0
  22. package/dist/cli/commands/doctor.d.ts.map +1 -0
  23. package/dist/cli/commands/doctor.js +86 -0
  24. package/dist/cli/commands/doctor.js.map +1 -0
  25. package/dist/cli/commands/eject.d.ts +2 -0
  26. package/dist/cli/commands/eject.d.ts.map +1 -0
  27. package/dist/cli/commands/eject.js +74 -0
  28. package/dist/cli/commands/eject.js.map +1 -0
  29. package/dist/cli/commands/env.d.ts +4 -0
  30. package/dist/cli/commands/env.d.ts.map +1 -0
  31. package/dist/cli/commands/env.js +50 -0
  32. package/dist/cli/commands/env.js.map +1 -0
  33. package/dist/cli/commands/harden.d.ts +4 -0
  34. package/dist/cli/commands/harden.d.ts.map +1 -0
  35. package/dist/cli/commands/harden.js +110 -0
  36. package/dist/cli/commands/harden.js.map +1 -0
  37. package/dist/cli/commands/help.d.ts +2 -0
  38. package/dist/cli/commands/help.d.ts.map +1 -0
  39. package/dist/cli/commands/help.js +99 -0
  40. package/dist/cli/commands/help.js.map +1 -0
  41. package/dist/cli/commands/init.d.ts +5 -0
  42. package/dist/cli/commands/init.d.ts.map +1 -0
  43. package/dist/cli/commands/init.js +246 -0
  44. package/dist/cli/commands/init.js.map +1 -0
  45. package/dist/cli/commands/logs.d.ts +5 -0
  46. package/dist/cli/commands/logs.d.ts.map +1 -0
  47. package/dist/cli/commands/logs.js +17 -0
  48. package/dist/cli/commands/logs.js.map +1 -0
  49. package/dist/cli/commands/metrics.d.ts +4 -0
  50. package/dist/cli/commands/metrics.d.ts.map +1 -0
  51. package/dist/cli/commands/metrics.js +21 -0
  52. package/dist/cli/commands/metrics.js.map +1 -0
  53. package/dist/cli/commands/migrate.d.ts +4 -0
  54. package/dist/cli/commands/migrate.d.ts.map +1 -0
  55. package/dist/cli/commands/migrate.js +71 -0
  56. package/dist/cli/commands/migrate.js.map +1 -0
  57. package/dist/cli/commands/restart.d.ts +4 -0
  58. package/dist/cli/commands/restart.d.ts.map +1 -0
  59. package/dist/cli/commands/restart.js +14 -0
  60. package/dist/cli/commands/restart.js.map +1 -0
  61. package/dist/cli/commands/rollback.d.ts +5 -0
  62. package/dist/cli/commands/rollback.d.ts.map +1 -0
  63. package/dist/cli/commands/rollback.js +49 -0
  64. package/dist/cli/commands/rollback.js.map +1 -0
  65. package/dist/cli/commands/run.d.ts +5 -0
  66. package/dist/cli/commands/run.d.ts.map +1 -0
  67. package/dist/cli/commands/run.js +69 -0
  68. package/dist/cli/commands/run.js.map +1 -0
  69. package/dist/cli/commands/setup.d.ts +4 -0
  70. package/dist/cli/commands/setup.d.ts.map +1 -0
  71. package/dist/cli/commands/setup.js +46 -0
  72. package/dist/cli/commands/setup.js.map +1 -0
  73. package/dist/cli/commands/status.d.ts +4 -0
  74. package/dist/cli/commands/status.d.ts.map +1 -0
  75. package/dist/cli/commands/status.js +49 -0
  76. package/dist/cli/commands/status.js.map +1 -0
  77. package/dist/cli/commands/stop.d.ts +4 -0
  78. package/dist/cli/commands/stop.d.ts.map +1 -0
  79. package/dist/cli/commands/stop.js +14 -0
  80. package/dist/cli/commands/stop.js.map +1 -0
  81. package/dist/cli/commands/unlock.d.ts +4 -0
  82. package/dist/cli/commands/unlock.d.ts.map +1 -0
  83. package/dist/cli/commands/unlock.js +27 -0
  84. package/dist/cli/commands/unlock.js.map +1 -0
  85. package/dist/cli/commands/upgrade.d.ts +2 -0
  86. package/dist/cli/commands/upgrade.d.ts.map +1 -0
  87. package/dist/cli/commands/upgrade.js +63 -0
  88. package/dist/cli/commands/upgrade.js.map +1 -0
  89. package/dist/cli/commands/user.d.ts +17 -0
  90. package/dist/cli/commands/user.d.ts.map +1 -0
  91. package/dist/cli/commands/user.js +98 -0
  92. package/dist/cli/commands/user.js.map +1 -0
  93. package/dist/cli/index.d.ts +3 -0
  94. package/dist/cli/index.d.ts.map +1 -0
  95. package/dist/cli/index.js +218 -0
  96. package/dist/cli/index.js.map +1 -0
  97. package/dist/cli/prompt.d.ts +2 -0
  98. package/dist/cli/prompt.d.ts.map +1 -0
  99. package/dist/cli/prompt.js +11 -0
  100. package/dist/cli/prompt.js.map +1 -0
  101. package/dist/cli/runner.d.ts +34 -0
  102. package/dist/cli/runner.d.ts.map +1 -0
  103. package/dist/cli/runner.js +44 -0
  104. package/dist/cli/runner.js.map +1 -0
  105. package/dist/cli/ui.d.ts +9 -0
  106. package/dist/cli/ui.d.ts.map +1 -0
  107. package/dist/cli/ui.js +26 -0
  108. package/dist/cli/ui.js.map +1 -0
  109. package/dist/config/assembly.d.ts +14 -0
  110. package/dist/config/assembly.d.ts.map +1 -0
  111. package/dist/config/assembly.js +62 -0
  112. package/dist/config/assembly.js.map +1 -0
  113. package/dist/config/builder.d.ts +33 -0
  114. package/dist/config/builder.d.ts.map +1 -0
  115. package/dist/config/builder.js +119 -0
  116. package/dist/config/builder.js.map +1 -0
  117. package/dist/config/loader.d.ts +3 -0
  118. package/dist/config/loader.d.ts.map +1 -0
  119. package/dist/config/loader.js +20 -0
  120. package/dist/config/loader.js.map +1 -0
  121. package/dist/config/schema.d.ts +416 -0
  122. package/dist/config/schema.d.ts.map +1 -0
  123. package/dist/config/schema.js +75 -0
  124. package/dist/config/schema.js.map +1 -0
  125. package/dist/domain/deploy/backend-strategy.d.ts +15 -0
  126. package/dist/domain/deploy/backend-strategy.d.ts.map +1 -0
  127. package/dist/domain/deploy/backend-strategy.js +110 -0
  128. package/dist/domain/deploy/backend-strategy.js.map +1 -0
  129. package/dist/domain/deploy/frontend-strategy.d.ts +13 -0
  130. package/dist/domain/deploy/frontend-strategy.d.ts.map +1 -0
  131. package/dist/domain/deploy/frontend-strategy.js +64 -0
  132. package/dist/domain/deploy/frontend-strategy.js.map +1 -0
  133. package/dist/domain/deploy/orchestrator.d.ts +34 -0
  134. package/dist/domain/deploy/orchestrator.d.ts.map +1 -0
  135. package/dist/domain/deploy/orchestrator.js +149 -0
  136. package/dist/domain/deploy/orchestrator.js.map +1 -0
  137. package/dist/domain/deploy/strategy.d.ts +44 -0
  138. package/dist/domain/deploy/strategy.d.ts.map +1 -0
  139. package/dist/domain/deploy/strategy.js +2 -0
  140. package/dist/domain/deploy/strategy.js.map +1 -0
  141. package/dist/domain/framework/detector.d.ts +7 -0
  142. package/dist/domain/framework/detector.d.ts.map +1 -0
  143. package/dist/domain/framework/detector.js +109 -0
  144. package/dist/domain/framework/detector.js.map +1 -0
  145. package/dist/domain/release/manager.d.ts +22 -0
  146. package/dist/domain/release/manager.d.ts.map +1 -0
  147. package/dist/domain/release/manager.js +100 -0
  148. package/dist/domain/release/manager.js.map +1 -0
  149. package/dist/domain/remote/executor.d.ts +16 -0
  150. package/dist/domain/remote/executor.d.ts.map +1 -0
  151. package/dist/domain/remote/executor.js +2 -0
  152. package/dist/domain/remote/executor.js.map +1 -0
  153. package/dist/domain/validation/ip.d.ts +5 -0
  154. package/dist/domain/validation/ip.d.ts.map +1 -0
  155. package/dist/domain/validation/ip.js +38 -0
  156. package/dist/domain/validation/ip.js.map +1 -0
  157. package/dist/index.d.ts +6 -0
  158. package/dist/index.d.ts.map +1 -0
  159. package/dist/index.js +4 -0
  160. package/dist/index.js.map +1 -0
  161. package/dist/infrastructure/ssh/connection.d.ts +19 -0
  162. package/dist/infrastructure/ssh/connection.d.ts.map +1 -0
  163. package/dist/infrastructure/ssh/connection.js +89 -0
  164. package/dist/infrastructure/ssh/connection.js.map +1 -0
  165. package/dist/services/caddy.service.d.ts +12 -0
  166. package/dist/services/caddy.service.d.ts.map +1 -0
  167. package/dist/services/caddy.service.js +56 -0
  168. package/dist/services/caddy.service.js.map +1 -0
  169. package/dist/services/deploy.service.d.ts +19 -0
  170. package/dist/services/deploy.service.d.ts.map +1 -0
  171. package/dist/services/deploy.service.js +53 -0
  172. package/dist/services/deploy.service.js.map +1 -0
  173. package/dist/services/health.service.d.ts +13 -0
  174. package/dist/services/health.service.d.ts.map +1 -0
  175. package/dist/services/health.service.js +38 -0
  176. package/dist/services/health.service.js.map +1 -0
  177. package/dist/shared/constants.d.ts +127 -0
  178. package/dist/shared/constants.d.ts.map +1 -0
  179. package/dist/shared/constants.js +85 -0
  180. package/dist/shared/constants.js.map +1 -0
  181. package/dist/shared/errors.d.ts +27 -0
  182. package/dist/shared/errors.d.ts.map +1 -0
  183. package/dist/shared/errors.js +53 -0
  184. package/dist/shared/errors.js.map +1 -0
  185. package/dist/shared/types.d.ts +116 -0
  186. package/dist/shared/types.d.ts.map +1 -0
  187. package/dist/shared/types.js +2 -0
  188. package/dist/shared/types.js.map +1 -0
  189. package/package.json +53 -0
@@ -0,0 +1,218 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from 'commander';
3
+ import { cmdInit } from './commands/init.js';
4
+ import { cmdDeploy } from './commands/deploy.js';
5
+ import { cmdSetup } from './commands/setup.js';
6
+ import { cmdDoctor } from './commands/doctor.js';
7
+ import { cmdStatus } from './commands/status.js';
8
+ import { cmdRollback } from './commands/rollback.js';
9
+ import { cmdEnv } from './commands/env.js';
10
+ import { cmdUnlock } from './commands/unlock.js';
11
+ import { cmdRun } from './commands/run.js';
12
+ import { cmdHarden } from './commands/harden.js';
13
+ import { cmdMigrate } from './commands/migrate.js';
14
+ import { cmdCiGithub, cmdCiEnvSync } from './commands/ci.js';
15
+ import { cmdConfigShow, cmdConfigValidate, cmdConfigPath } from './commands/config.js';
16
+ import { cmdLogs } from './commands/logs.js';
17
+ import { cmdRestart } from './commands/restart.js';
18
+ import { cmdStop } from './commands/stop.js';
19
+ import { cmdMetrics } from './commands/metrics.js';
20
+ import { cmdEject } from './commands/eject.js';
21
+ import { cmdHelp } from './commands/help.js';
22
+ import { cmdUserSync, cmdUserList, cmdUserRemove } from './commands/user.js';
23
+ import { cmdUpgrade } from './commands/upgrade.js';
24
+ import { cmdBackupSetup, cmdBackupRun, cmdBackupStatus, cmdBackupList } from './commands/backup.js';
25
+ import { cmdCloudflareInit, cmdCloudflareAudit, cmdCloudflareStatus } from './commands/cloudflare.js';
26
+ const program = new Command();
27
+ program
28
+ .name('shipnode')
29
+ .description('Deploy Node.js apps to a single VPS')
30
+ .version('2.0.0');
31
+ // ── Core ──────────────────────────────────────────────────────────
32
+ program
33
+ .command('init')
34
+ .description('Initialize a new shipnode.config.ts')
35
+ .option('--non-interactive', 'Generate config without prompts')
36
+ .option('--print', 'Print config to stdout without writing file')
37
+ .action((opts) => cmdInit(process.cwd(), opts));
38
+ program
39
+ .command('setup')
40
+ .description('Setup a new server with required dependencies')
41
+ .option('--config <path>', 'Use a specific config file')
42
+ .action((opts) => cmdSetup(process.cwd(), opts));
43
+ program
44
+ .command('deploy')
45
+ .description('Deploy your application')
46
+ .option('--dry-run', 'Show what would be deployed without making changes')
47
+ .option('--skip-build', 'Skip the build step')
48
+ .option('--config <path>', 'Use a specific config file')
49
+ .action((opts) => cmdDeploy(process.cwd(), opts));
50
+ program
51
+ .command('doctor')
52
+ .description('Check local and remote configuration')
53
+ .option('--security', 'Run security audit instead of standard checks')
54
+ .option('--config <path>', 'Use a specific config file')
55
+ .action((opts) => cmdDoctor(process.cwd(), opts));
56
+ program
57
+ .command('status')
58
+ .description('Check application status')
59
+ .option('--config <path>', 'Use a specific config file')
60
+ .action((opts) => cmdStatus(process.cwd(), opts));
61
+ // ── Release management ────────────────────────────────────────────
62
+ program
63
+ .command('rollback')
64
+ .description('Roll back to a previous release')
65
+ .option('--steps <n>', 'Number of releases to go back', '1')
66
+ .option('--config <path>', 'Use a specific config file')
67
+ .action((opts) => cmdRollback(process.cwd(), { steps: parseInt(opts.steps, 10), config: opts.config }));
68
+ program
69
+ .command('migrate')
70
+ .description('Migrate existing deploy to zero-downtime release structure')
71
+ .option('--config <path>', 'Use a specific config file')
72
+ .action((opts) => cmdMigrate(process.cwd(), opts));
73
+ // ── Environment ───────────────────────────────────────────────────
74
+ program
75
+ .command('env')
76
+ .description('Upload local .env file to the server')
77
+ .option('--config <path>', 'Use a specific config file')
78
+ .action((opts) => cmdEnv(process.cwd(), opts));
79
+ program
80
+ .command('run [cmd...]')
81
+ .description('Run a one-off command on the production server')
82
+ .option('--tty', 'Force interactive TTY mode')
83
+ .option('--config <path>', 'Use a specific config file')
84
+ .action((cmdArgs, opts) => cmdRun(process.cwd(), opts, cmdArgs));
85
+ // ── Process management ────────────────────────────────────────────
86
+ program
87
+ .command('logs')
88
+ .description('Show application logs')
89
+ .option('--lines <n>', 'Number of log lines to show', '100')
90
+ .option('--config <path>', 'Use a specific config file')
91
+ .action((opts) => cmdLogs(process.cwd(), { lines: parseInt(opts.lines, 10), config: opts.config }));
92
+ program
93
+ .command('restart')
94
+ .description('Restart the application')
95
+ .option('--config <path>', 'Use a specific config file')
96
+ .action((opts) => cmdRestart(process.cwd(), opts));
97
+ program
98
+ .command('stop')
99
+ .description('Stop the application')
100
+ .option('--config <path>', 'Use a specific config file')
101
+ .action((opts) => cmdStop(process.cwd(), opts));
102
+ program
103
+ .command('metrics')
104
+ .description('Open PM2 monitoring dashboard')
105
+ .option('--config <path>', 'Use a specific config file')
106
+ .action((opts) => cmdMetrics(process.cwd(), opts));
107
+ // ── Security & maintenance ────────────────────────────────────────
108
+ program
109
+ .command('harden')
110
+ .description('Apply server security hardening (SSH, firewall, fail2ban)')
111
+ .option('--config <path>', 'Use a specific config file')
112
+ .action((opts) => cmdHarden(process.cwd(), opts));
113
+ program
114
+ .command('unlock')
115
+ .description('Clear a stuck deployment lock')
116
+ .option('--config <path>', 'Use a specific config file')
117
+ .action((opts) => cmdUnlock(process.cwd(), opts));
118
+ // ── CI/CD ─────────────────────────────────────────────────────────
119
+ const ci = program.command('ci').description('CI/CD integration');
120
+ ci.command('github')
121
+ .description('Generate GitHub Actions deploy workflow')
122
+ .action(() => cmdCiGithub(process.cwd()));
123
+ ci.command('env-sync')
124
+ .description('Sync .env and config to GitHub repository secrets')
125
+ .option('--all', 'Sync all .env variables without confirmation')
126
+ .action((opts) => cmdCiEnvSync(process.cwd(), opts));
127
+ // ── Config ────────────────────────────────────────────────────────
128
+ const config = program.command('config').description('Manage configuration');
129
+ config.command('show')
130
+ .description('Show resolved configuration')
131
+ .option('--config <path>', 'Use a specific config file')
132
+ .action((opts) => cmdConfigShow(process.cwd(), opts));
133
+ config.command('validate')
134
+ .description('Validate configuration file')
135
+ .option('--config <path>', 'Use a specific config file')
136
+ .action((opts) => cmdConfigValidate(process.cwd(), opts));
137
+ config.command('path')
138
+ .description('Print path to config file')
139
+ .option('--config <path>', 'Use a specific config file')
140
+ .action((opts) => cmdConfigPath(process.cwd(), opts));
141
+ // ── Users ─────────────────────────────────────────────────────────
142
+ const user = program.command('user').description('Manage server users');
143
+ user.command('sync')
144
+ .description('Sync users from .shipnode/users.yml to server')
145
+ .option('--config <path>', 'Use a specific config file')
146
+ .action((opts) => cmdUserSync(process.cwd(), opts));
147
+ user.command('list')
148
+ .description('List non-system users on server')
149
+ .option('--config <path>', 'Use a specific config file')
150
+ .action((opts) => cmdUserList(process.cwd(), opts));
151
+ user.command('remove <username>')
152
+ .description('Remove a user from the server')
153
+ .option('--config <path>', 'Use a specific config file')
154
+ .action((username, opts) => cmdUserRemove(process.cwd(), username, opts));
155
+ // ── Backup ────────────────────────────────────────────────────────
156
+ const backup = program.command('backup').description('Database & file backups to S3');
157
+ backup.command('setup')
158
+ .description('Install backup script and systemd timer on server')
159
+ .option('--config <path>', 'Use a specific config file')
160
+ .action((opts) => cmdBackupSetup(process.cwd(), opts));
161
+ backup.command('run')
162
+ .description('Run a backup immediately')
163
+ .option('--config <path>', 'Use a specific config file')
164
+ .action((opts) => cmdBackupRun(process.cwd(), opts));
165
+ backup.command('status')
166
+ .description('Show backup timer and last run status')
167
+ .option('--config <path>', 'Use a specific config file')
168
+ .action((opts) => cmdBackupStatus(process.cwd(), opts));
169
+ backup.command('list')
170
+ .description('List recent backups in S3')
171
+ .option('--config <path>', 'Use a specific config file')
172
+ .action((opts) => cmdBackupList(process.cwd(), opts));
173
+ // ── Cloudflare ────────────────────────────────────────────────────
174
+ const cloudflare = program.command('cloudflare').description('Cloudflare Tunnel integration');
175
+ cloudflare.command('init')
176
+ .description('Install cloudflared and configure tunnel/DNS/Access')
177
+ .option('--config <path>', 'Use a specific config file')
178
+ .action((opts) => cmdCloudflareInit(process.cwd(), opts));
179
+ cloudflare.command('audit')
180
+ .description('Verify Cloudflare DNS and tunnel configuration')
181
+ .option('--config <path>', 'Use a specific config file')
182
+ .action((opts) => cmdCloudflareAudit(process.cwd(), opts));
183
+ cloudflare.command('status')
184
+ .description('Show cloudflared service and tunnel status')
185
+ .option('--config <path>', 'Use a specific config file')
186
+ .action((opts) => cmdCloudflareStatus(process.cwd(), opts));
187
+ // ── Self-update ───────────────────────────────────────────────────
188
+ program
189
+ .command('upgrade')
190
+ .description('Upgrade shipnode to the latest version')
191
+ .action(() => cmdUpgrade());
192
+ // ── Customization ─────────────────────────────────────────────────
193
+ program
194
+ .command('eject [target]')
195
+ .description('Eject PM2/Caddy templates for customization (pm2, caddy, all)')
196
+ .action((target = 'all') => {
197
+ const valid = ['pm2', 'caddy', 'all'];
198
+ if (!valid.includes(target)) {
199
+ console.error(`Unknown eject target: ${target}. Use: pm2, caddy, all`);
200
+ process.exit(1);
201
+ }
202
+ return cmdEject(process.cwd(), target);
203
+ });
204
+ // ── Help ──────────────────────────────────────────────────────────
205
+ program
206
+ .command('help')
207
+ .description('Show help')
208
+ .action(() => cmdHelp());
209
+ program.on('command:*', () => {
210
+ console.error(`Unknown command. Run 'shipnode help' for usage.`);
211
+ process.exit(1);
212
+ });
213
+ if (process.argv.length <= 2) {
214
+ cmdHelp();
215
+ process.exit(0);
216
+ }
217
+ program.parse();
218
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function confirm(question: string): Promise<boolean>;
2
+ //# sourceMappingURL=prompt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../../src/cli/prompt.ts"],"names":[],"mappings":"AAEA,wBAAgB,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAQ1D"}
@@ -0,0 +1,11 @@
1
+ import { createInterface } from 'readline';
2
+ export function confirm(question) {
3
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
4
+ return new Promise((resolve) => {
5
+ rl.question(`${question} (y/N) `, (answer) => {
6
+ rl.close();
7
+ resolve(answer.trim().toLowerCase() === 'y');
8
+ });
9
+ });
10
+ }
11
+ //# sourceMappingURL=prompt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../src/cli/prompt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAE3C,MAAM,UAAU,OAAO,CAAC,QAAgB;IACtC,MAAM,EAAE,GAAG,eAAe,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAC7E,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,EAAE,CAAC,QAAQ,CAAC,GAAG,QAAQ,SAAS,EAAE,CAAC,MAAM,EAAE,EAAE;YAC3C,EAAE,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,KAAK,GAAG,CAAC,CAAC;QAC/C,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,34 @@
1
+ import type { ShipnodeConfig } from '../shared/types.js';
2
+ import type { RemoteExecutor } from '../domain/remote/executor.js';
3
+ /**
4
+ * A command that operates against a remote host through an executor.
5
+ *
6
+ * Implementations are pure business logic: they do not manage
7
+ * connection lifecycle or process exit. The runner owns both.
8
+ */
9
+ export interface RemoteCommand {
10
+ (ctx: {
11
+ config: ShipnodeConfig;
12
+ executor: RemoteExecutor;
13
+ }): Promise<void>;
14
+ }
15
+ /**
16
+ * Run a remote command with full lifecycle management.
17
+ *
18
+ * Loads config, establishes an SSH connection, delegates to the
19
+ * command, and guarantees cleanup. If the command throws, the error
20
+ * is presented and the process exits with code 1.
21
+ */
22
+ export declare function runRemoteCommand(cwd: string, command: RemoteCommand, options?: {
23
+ configPath?: string;
24
+ }): Promise<void>;
25
+ /**
26
+ * Run a local command that does not need a remote connection.
27
+ *
28
+ * Loads config and delegates to the command. Handles errors
29
+ * and process exit consistently with remote commands.
30
+ */
31
+ export declare function runLocalCommand(cwd: string, command: (config: ShipnodeConfig) => Promise<void>, options?: {
32
+ configPath?: string;
33
+ }): Promise<void>;
34
+ //# sourceMappingURL=runner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/cli/runner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEzD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAInE;;;;;GAKG;AACH,MAAM,WAAW,aAAa;IAC5B,CAAC,GAAG,EAAE;QAAE,MAAM,EAAE,cAAc,CAAC;QAAC,QAAQ,EAAE,cAAc,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5E;AAED;;;;;;GAMG;AACH,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,aAAa,EACtB,OAAO,GAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAA;CAAO,GACpC,OAAO,CAAC,IAAI,CAAC,CAcf;AAED;;;;;GAKG;AACH,wBAAsB,eAAe,CACnC,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,CAAC,MAAM,EAAE,cAAc,KAAK,OAAO,CAAC,IAAI,CAAC,EAClD,OAAO,GAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAA;CAAO,GACpC,OAAO,CAAC,IAAI,CAAC,CAUf"}
@@ -0,0 +1,44 @@
1
+ import { SshConnection } from '../infrastructure/ssh/connection.js';
2
+ import { loadConfig } from '../config/loader.js';
3
+ import { ui } from './ui.js';
4
+ /**
5
+ * Run a remote command with full lifecycle management.
6
+ *
7
+ * Loads config, establishes an SSH connection, delegates to the
8
+ * command, and guarantees cleanup. If the command throws, the error
9
+ * is presented and the process exits with code 1.
10
+ */
11
+ export async function runRemoteCommand(cwd, command, options = {}) {
12
+ const config = await loadConfig(cwd, options.configPath);
13
+ const ssh = new SshConnection();
14
+ try {
15
+ await ssh.connect(config.ssh);
16
+ await command({ config, executor: ssh });
17
+ }
18
+ catch (error) {
19
+ const message = error instanceof Error ? error.message : String(error);
20
+ ui.error(message);
21
+ process.exit(1);
22
+ }
23
+ finally {
24
+ ssh.disconnect();
25
+ }
26
+ }
27
+ /**
28
+ * Run a local command that does not need a remote connection.
29
+ *
30
+ * Loads config and delegates to the command. Handles errors
31
+ * and process exit consistently with remote commands.
32
+ */
33
+ export async function runLocalCommand(cwd, command, options = {}) {
34
+ const config = await loadConfig(cwd, options.configPath);
35
+ try {
36
+ await command(config);
37
+ }
38
+ catch (error) {
39
+ const message = error instanceof Error ? error.message : String(error);
40
+ ui.error(message);
41
+ process.exit(1);
42
+ }
43
+ }
44
+ //# sourceMappingURL=runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner.js","sourceRoot":"","sources":["../../src/cli/runner.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,qCAAqC,CAAC;AAEpE,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAY7B;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,GAAW,EACX,OAAsB,EACtB,UAAmC,EAAE;IAErC,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,GAAG,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC;IACzD,MAAM,GAAG,GAAG,IAAI,aAAa,EAAE,CAAC;IAEhC,IAAI,CAAC;QACH,MAAM,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC9B,MAAM,OAAO,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC;IAC3C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACvE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAClB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;YAAS,CAAC;QACT,GAAG,CAAC,UAAU,EAAE,CAAC;IACnB,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,GAAW,EACX,OAAkD,EAClD,UAAmC,EAAE;IAErC,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,GAAG,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC;IAEzD,IAAI,CAAC;QACH,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IACxB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACvE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAClB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
@@ -0,0 +1,9 @@
1
+ export declare const ui: {
2
+ info(msg: string): void;
3
+ success(msg: string): void;
4
+ warn(msg: string): void;
5
+ error(msg: string): void;
6
+ heading(msg: string): void;
7
+ section(title: string, items: [string, string][]): void;
8
+ };
9
+ //# sourceMappingURL=ui.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ui.d.ts","sourceRoot":"","sources":["../../src/cli/ui.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,EAAE;cACH,MAAM;iBAGH,MAAM;cAGT,MAAM;eAGL,MAAM;iBAGJ,MAAM;mBAGJ,MAAM,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,GAAG,IAAI;CAOxD,CAAC"}
package/dist/cli/ui.js ADDED
@@ -0,0 +1,26 @@
1
+ import chalk from 'chalk';
2
+ export const ui = {
3
+ info(msg) {
4
+ console.log(`${chalk.blue('→')} ${msg}`);
5
+ },
6
+ success(msg) {
7
+ console.log(`${chalk.green('✓')} ${msg}`);
8
+ },
9
+ warn(msg) {
10
+ console.log(`${chalk.yellow('⚠')} ${msg}`);
11
+ },
12
+ error(msg) {
13
+ console.error(`${chalk.red('Error:')} ${msg}`);
14
+ },
15
+ heading(msg) {
16
+ console.log(`\n${chalk.blue.bold(msg)}\n`);
17
+ },
18
+ section(title, items) {
19
+ console.log(chalk.bold(title));
20
+ for (const [key, value] of items) {
21
+ console.log(` ${chalk.dim(key.padEnd(20))} ${value}`);
22
+ }
23
+ console.log();
24
+ },
25
+ };
26
+ //# sourceMappingURL=ui.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ui.js","sourceRoot":"","sources":["../../src/cli/ui.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,CAAC,MAAM,EAAE,GAAG;IAChB,IAAI,CAAC,GAAW;QACd,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC;IAC3C,CAAC;IACD,OAAO,CAAC,GAAW;QACjB,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC;IAC5C,CAAC;IACD,IAAI,CAAC,GAAW;QACd,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC;IAC7C,CAAC;IACD,KAAK,CAAC,GAAW;QACf,OAAO,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC;IACjD,CAAC;IACD,OAAO,CAAC,GAAW;QACjB,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC7C,CAAC;IACD,OAAO,CAAC,KAAa,EAAE,KAAyB;QAC9C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;QAC/B,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,KAAK,EAAE,CAAC;YACjC,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC;QACzD,CAAC;QACD,OAAO,CAAC,GAAG,EAAE,CAAC;IAChB,CAAC;CACF,CAAC"}
@@ -0,0 +1,14 @@
1
+ import type { ShipnodeConfig } from '../shared/types.js';
2
+ /**
3
+ * Assemble a partial config into a fully-validated ShipnodeConfig.
4
+ *
5
+ * This is the single place where raw user intent becomes a trusted
6
+ * configuration object. Defaults are applied first, then the schema
7
+ * validates every field.
8
+ *
9
+ * Both the builder and the loader must route through here so that
10
+ * defaults and validation are identical regardless of how the config
11
+ * was produced.
12
+ */
13
+ export declare function assembleConfig(partial: Partial<ShipnodeConfig>): ShipnodeConfig;
14
+ //# sourceMappingURL=assembly.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assembly.d.ts","sourceRoot":"","sources":["../../src/config/assembly.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAA+C,MAAM,oBAAoB,CAAC;AA+BtG;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,CAAC,cAAc,CAAC,GAAG,cAAc,CAwB/E"}
@@ -0,0 +1,62 @@
1
+ import { ShipnodeConfigSchema } from './schema.js';
2
+ import { DEFAULTS } from '../shared/constants.js';
3
+ function defaultSshConfig(overrides) {
4
+ return {
5
+ host: '',
6
+ user: '',
7
+ port: DEFAULTS.SSH_PORT,
8
+ ...overrides,
9
+ };
10
+ }
11
+ function defaultBackendConfig(overrides) {
12
+ return {
13
+ port: DEFAULTS.BACKEND_PORT,
14
+ ...overrides,
15
+ };
16
+ }
17
+ function defaultHealthCheckConfig(overrides) {
18
+ return {
19
+ enabled: DEFAULTS.HEALTH_CHECK_ENABLED,
20
+ path: DEFAULTS.HEALTH_CHECK_PATH,
21
+ timeout: DEFAULTS.HEALTH_CHECK_TIMEOUT,
22
+ retries: DEFAULTS.HEALTH_CHECK_RETRIES,
23
+ startupDelay: DEFAULTS.HEALTH_CHECK_STARTUP_DELAY,
24
+ ...overrides,
25
+ };
26
+ }
27
+ /**
28
+ * Assemble a partial config into a fully-validated ShipnodeConfig.
29
+ *
30
+ * This is the single place where raw user intent becomes a trusted
31
+ * configuration object. Defaults are applied first, then the schema
32
+ * validates every field.
33
+ *
34
+ * Both the builder and the loader must route through here so that
35
+ * defaults and validation are identical regardless of how the config
36
+ * was produced.
37
+ */
38
+ export function assembleConfig(partial) {
39
+ const withDefaults = {
40
+ app: partial.app ?? 'backend',
41
+ ssh: partial.ssh ?? defaultSshConfig(),
42
+ remotePath: partial.remotePath ?? '/var/www/app',
43
+ pm2: partial.pm2,
44
+ backend: partial.backend ?? defaultBackendConfig(),
45
+ domain: partial.domain,
46
+ zeroDowntime: partial.zeroDowntime ?? DEFAULTS.ZERO_DOWNTIME,
47
+ keepReleases: partial.keepReleases ?? DEFAULTS.KEEP_RELEASES,
48
+ healthCheck: defaultHealthCheckConfig(partial.healthCheck),
49
+ envFile: partial.envFile ?? DEFAULTS.ENV_FILE,
50
+ nodeVersion: partial.nodeVersion ?? DEFAULTS.NODE_VERSION,
51
+ pkgManager: partial.pkgManager,
52
+ sharedDirs: partial.sharedDirs,
53
+ sharedFiles: partial.sharedFiles,
54
+ buildDir: partial.buildDir,
55
+ database: partial.database,
56
+ backup: partial.backup,
57
+ cloudflare: partial.cloudflare,
58
+ hooks: partial.hooks,
59
+ };
60
+ return ShipnodeConfigSchema.parse(withDefaults);
61
+ }
62
+ //# sourceMappingURL=assembly.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assembly.js","sourceRoot":"","sources":["../../src/config/assembly.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAElD,SAAS,gBAAgB,CAAC,SAA8B;IACtD,OAAO;QACL,IAAI,EAAE,EAAE;QACR,IAAI,EAAE,EAAE;QACR,IAAI,EAAE,QAAQ,CAAC,QAAQ;QACvB,GAAG,SAAS;KACb,CAAC;AACJ,CAAC;AAED,SAAS,oBAAoB,CAAC,SAAkC;IAC9D,OAAO;QACL,IAAI,EAAE,QAAQ,CAAC,YAAY;QAC3B,GAAG,SAAS;KACb,CAAC;AACJ,CAAC;AAED,SAAS,wBAAwB,CAAC,SAAsC;IACtE,OAAO;QACL,OAAO,EAAE,QAAQ,CAAC,oBAAoB;QACtC,IAAI,EAAE,QAAQ,CAAC,iBAAiB;QAChC,OAAO,EAAE,QAAQ,CAAC,oBAAoB;QACtC,OAAO,EAAE,QAAQ,CAAC,oBAAoB;QACtC,YAAY,EAAE,QAAQ,CAAC,0BAA0B;QACjD,GAAG,SAAS;KACb,CAAC;AACJ,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,cAAc,CAAC,OAAgC;IAC7D,MAAM,YAAY,GAAG;QACnB,GAAG,EAAE,OAAO,CAAC,GAAG,IAAI,SAAS;QAC7B,GAAG,EAAE,OAAO,CAAC,GAAG,IAAI,gBAAgB,EAAE;QACtC,UAAU,EAAE,OAAO,CAAC,UAAU,IAAI,cAAc;QAChD,GAAG,EAAE,OAAO,CAAC,GAAG;QAChB,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,oBAAoB,EAAE;QAClD,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,YAAY,EAAE,OAAO,CAAC,YAAY,IAAI,QAAQ,CAAC,aAAa;QAC5D,YAAY,EAAE,OAAO,CAAC,YAAY,IAAI,QAAQ,CAAC,aAAa;QAC5D,WAAW,EAAE,wBAAwB,CAAC,OAAO,CAAC,WAAW,CAAC;QAC1D,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,QAAQ,CAAC,QAAQ;QAC7C,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,QAAQ,CAAC,YAAY;QACzD,UAAU,EAAE,OAAO,CAAC,UAAU;QAC9B,UAAU,EAAE,OAAO,CAAC,UAAU;QAC9B,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,UAAU,EAAE,OAAO,CAAC,UAAU;QAC9B,KAAK,EAAE,OAAO,CAAC,KAAK;KACrB,CAAC;IAEF,OAAO,oBAAoB,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;AAClD,CAAC"}
@@ -0,0 +1,33 @@
1
+ import type { ShipnodeConfig, SshConfig, Pm2Config, HealthCheckConfig, DatabaseConfig, BackupConfig, CloudflareConfig, HookFn, PkgManager } from '../shared/types.js';
2
+ export declare class ShipnodeBuilder {
3
+ private config;
4
+ backend(): this;
5
+ frontend(): this;
6
+ ssh(opts: SshConfig): this;
7
+ cloudflareAccess(proxyCommand?: string): this;
8
+ deployTo(path: string): this;
9
+ pm2(name: string, opts?: Omit<Pm2Config, 'name'>): this;
10
+ port(n: number): this;
11
+ domain(d: string): this;
12
+ zeroDowntime(opts?: {
13
+ keepReleases?: number;
14
+ }): this;
15
+ legacy(): this;
16
+ sharedDirs(dirs: string[]): this;
17
+ sharedFiles(files: string[]): this;
18
+ healthCheck(path: string, opts?: Partial<HealthCheckConfig>): this;
19
+ noHealthCheck(): this;
20
+ envFile(f: string): this;
21
+ nodeVersion(v: string): this;
22
+ pkgManager(pm: PkgManager): this;
23
+ buildDir(dir: string): this;
24
+ database(opts: DatabaseConfig): this;
25
+ backup(opts: BackupConfig): this;
26
+ cloudflare(opts: CloudflareConfig): this;
27
+ preDeploy(fn: HookFn): this;
28
+ postDeploy(fn: HookFn): this;
29
+ build(): ShipnodeConfig;
30
+ }
31
+ export declare const shipnode: ShipnodeBuilder;
32
+ export declare function defineConfig(builder: ShipnodeBuilder): ShipnodeBuilder;
33
+ //# sourceMappingURL=builder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../../src/config/builder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EACd,SAAS,EACT,SAAS,EACT,iBAAiB,EACjB,cAAc,EACd,YAAY,EACZ,gBAAgB,EAChB,MAAM,EACN,UAAU,EACX,MAAM,oBAAoB,CAAC;AAG5B,qBAAa,eAAe;IAC1B,OAAO,CAAC,MAAM,CAA+B;IAE7C,OAAO,IAAI,IAAI;IAKf,QAAQ,IAAI,IAAI;IAKhB,GAAG,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI;IAK1B,gBAAgB,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI;IAU7C,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAK5B,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC,GAAG,IAAI;IAKvD,IAAI,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI;IAKrB,MAAM,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI;IAKvB,YAAY,CAAC,IAAI,CAAC,EAAE;QAAE,YAAY,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAQpD,MAAM,IAAI,IAAI;IAKd,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI;IAKhC,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI;IAKlC,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,CAAC,iBAAiB,CAAC,GAAG,IAAI;IAYlE,aAAa,IAAI,IAAI;IAKrB,OAAO,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI;IAKxB,WAAW,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI;IAK5B,UAAU,CAAC,EAAE,EAAE,UAAU,GAAG,IAAI;IAKhC,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAK3B,QAAQ,CAAC,IAAI,EAAE,cAAc,GAAG,IAAI;IAKpC,MAAM,CAAC,IAAI,EAAE,YAAY,GAAG,IAAI;IAKhC,UAAU,CAAC,IAAI,EAAE,gBAAgB,GAAG,IAAI;IAKxC,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAK3B,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAK5B,KAAK,IAAI,cAAc;CAGxB;AAED,eAAO,MAAM,QAAQ,iBAAwB,CAAC;AAE9C,wBAAgB,YAAY,CAAC,OAAO,EAAE,eAAe,GAAG,eAAe,CAEtE"}
@@ -0,0 +1,119 @@
1
+ import { assembleConfig } from './assembly.js';
2
+ export class ShipnodeBuilder {
3
+ config = {};
4
+ backend() {
5
+ this.config.app = 'backend';
6
+ return this;
7
+ }
8
+ frontend() {
9
+ this.config.app = 'frontend';
10
+ return this;
11
+ }
12
+ ssh(opts) {
13
+ this.config.ssh = { ...this.config.ssh, ...opts };
14
+ return this;
15
+ }
16
+ cloudflareAccess(proxyCommand) {
17
+ const existing = this.config.ssh ?? { host: '', user: '', port: 22 };
18
+ this.config.ssh = {
19
+ ...existing,
20
+ proxyMode: 'cloudflare',
21
+ proxyCommand: proxyCommand ?? existing.proxyCommand,
22
+ };
23
+ return this;
24
+ }
25
+ deployTo(path) {
26
+ this.config.remotePath = path;
27
+ return this;
28
+ }
29
+ pm2(name, opts) {
30
+ this.config.pm2 = { name, ...opts };
31
+ return this;
32
+ }
33
+ port(n) {
34
+ this.config.backend = { ...(this.config.backend ?? {}), port: n };
35
+ return this;
36
+ }
37
+ domain(d) {
38
+ this.config.domain = d;
39
+ return this;
40
+ }
41
+ zeroDowntime(opts) {
42
+ this.config.zeroDowntime = true;
43
+ if (opts?.keepReleases !== undefined) {
44
+ this.config.keepReleases = opts.keepReleases;
45
+ }
46
+ return this;
47
+ }
48
+ legacy() {
49
+ this.config.zeroDowntime = false;
50
+ return this;
51
+ }
52
+ sharedDirs(dirs) {
53
+ this.config.sharedDirs = dirs;
54
+ return this;
55
+ }
56
+ sharedFiles(files) {
57
+ this.config.sharedFiles = files;
58
+ return this;
59
+ }
60
+ healthCheck(path, opts) {
61
+ this.config.healthCheck = {
62
+ ...(this.config.healthCheck ?? {}),
63
+ enabled: true,
64
+ path,
65
+ timeout: opts?.timeout ?? 30,
66
+ retries: opts?.retries ?? 3,
67
+ startupDelay: opts?.startupDelay ?? 3,
68
+ };
69
+ return this;
70
+ }
71
+ noHealthCheck() {
72
+ this.config.healthCheck = { enabled: false, path: '/health', timeout: 30, retries: 3, startupDelay: 3 };
73
+ return this;
74
+ }
75
+ envFile(f) {
76
+ this.config.envFile = f;
77
+ return this;
78
+ }
79
+ nodeVersion(v) {
80
+ this.config.nodeVersion = v;
81
+ return this;
82
+ }
83
+ pkgManager(pm) {
84
+ this.config.pkgManager = pm;
85
+ return this;
86
+ }
87
+ buildDir(dir) {
88
+ this.config.buildDir = dir;
89
+ return this;
90
+ }
91
+ database(opts) {
92
+ this.config.database = opts;
93
+ return this;
94
+ }
95
+ backup(opts) {
96
+ this.config.backup = opts;
97
+ return this;
98
+ }
99
+ cloudflare(opts) {
100
+ this.config.cloudflare = opts;
101
+ return this;
102
+ }
103
+ preDeploy(fn) {
104
+ this.config.hooks = { ...(this.config.hooks ?? {}), preDeploy: fn };
105
+ return this;
106
+ }
107
+ postDeploy(fn) {
108
+ this.config.hooks = { ...(this.config.hooks ?? {}), postDeploy: fn };
109
+ return this;
110
+ }
111
+ build() {
112
+ return assembleConfig(this.config);
113
+ }
114
+ }
115
+ export const shipnode = new ShipnodeBuilder();
116
+ export function defineConfig(builder) {
117
+ return builder;
118
+ }
119
+ //# sourceMappingURL=builder.js.map