shyp 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 (123) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +218 -0
  3. package/dist/cli.d.ts +3 -0
  4. package/dist/cli.d.ts.map +1 -0
  5. package/dist/cli.js +64 -0
  6. package/dist/cli.js.map +1 -0
  7. package/dist/commands/add.d.ts +9 -0
  8. package/dist/commands/add.d.ts.map +1 -0
  9. package/dist/commands/add.js +69 -0
  10. package/dist/commands/add.js.map +1 -0
  11. package/dist/commands/deploy.d.ts +4 -0
  12. package/dist/commands/deploy.d.ts.map +1 -0
  13. package/dist/commands/deploy.js +104 -0
  14. package/dist/commands/deploy.js.map +1 -0
  15. package/dist/commands/doctor.d.ts +2 -0
  16. package/dist/commands/doctor.d.ts.map +1 -0
  17. package/dist/commands/doctor.js +97 -0
  18. package/dist/commands/doctor.js.map +1 -0
  19. package/dist/commands/index.d.ts +10 -0
  20. package/dist/commands/index.d.ts.map +1 -0
  21. package/dist/commands/index.js +10 -0
  22. package/dist/commands/index.js.map +1 -0
  23. package/dist/commands/init.d.ts +4 -0
  24. package/dist/commands/init.d.ts.map +1 -0
  25. package/dist/commands/init.js +150 -0
  26. package/dist/commands/init.js.map +1 -0
  27. package/dist/commands/logs.d.ts +5 -0
  28. package/dist/commands/logs.d.ts.map +1 -0
  29. package/dist/commands/logs.js +56 -0
  30. package/dist/commands/logs.js.map +1 -0
  31. package/dist/commands/ports.d.ts +2 -0
  32. package/dist/commands/ports.d.ts.map +1 -0
  33. package/dist/commands/ports.js +73 -0
  34. package/dist/commands/ports.js.map +1 -0
  35. package/dist/commands/start.d.ts +2 -0
  36. package/dist/commands/start.d.ts.map +1 -0
  37. package/dist/commands/start.js +11 -0
  38. package/dist/commands/start.js.map +1 -0
  39. package/dist/commands/status.d.ts +2 -0
  40. package/dist/commands/status.d.ts.map +1 -0
  41. package/dist/commands/status.js +73 -0
  42. package/dist/commands/status.js.map +1 -0
  43. package/dist/commands/sync.d.ts +4 -0
  44. package/dist/commands/sync.d.ts.map +1 -0
  45. package/dist/commands/sync.js +95 -0
  46. package/dist/commands/sync.js.map +1 -0
  47. package/dist/index.d.ts +4 -0
  48. package/dist/index.d.ts.map +1 -0
  49. package/dist/index.js +6 -0
  50. package/dist/index.js.map +1 -0
  51. package/dist/lib/config.d.ts +10 -0
  52. package/dist/lib/config.d.ts.map +1 -0
  53. package/dist/lib/config.js +116 -0
  54. package/dist/lib/config.js.map +1 -0
  55. package/dist/lib/deploy.d.ts +12 -0
  56. package/dist/lib/deploy.d.ts.map +1 -0
  57. package/dist/lib/deploy.js +288 -0
  58. package/dist/lib/deploy.js.map +1 -0
  59. package/dist/lib/git.d.ts +24 -0
  60. package/dist/lib/git.d.ts.map +1 -0
  61. package/dist/lib/git.js +82 -0
  62. package/dist/lib/git.js.map +1 -0
  63. package/dist/lib/index.d.ts +7 -0
  64. package/dist/lib/index.d.ts.map +1 -0
  65. package/dist/lib/index.js +7 -0
  66. package/dist/lib/index.js.map +1 -0
  67. package/dist/lib/nginx.d.ts +16 -0
  68. package/dist/lib/nginx.d.ts.map +1 -0
  69. package/dist/lib/nginx.js +312 -0
  70. package/dist/lib/nginx.js.map +1 -0
  71. package/dist/lib/pm2.d.ts +25 -0
  72. package/dist/lib/pm2.d.ts.map +1 -0
  73. package/dist/lib/pm2.js +106 -0
  74. package/dist/lib/pm2.js.map +1 -0
  75. package/dist/lib/state.d.ts +12 -0
  76. package/dist/lib/state.d.ts.map +1 -0
  77. package/dist/lib/state.js +112 -0
  78. package/dist/lib/state.js.map +1 -0
  79. package/dist/schemas/app.d.ts +272 -0
  80. package/dist/schemas/app.d.ts.map +1 -0
  81. package/dist/schemas/app.js +79 -0
  82. package/dist/schemas/app.js.map +1 -0
  83. package/dist/schemas/config.d.ts +508 -0
  84. package/dist/schemas/config.d.ts.map +1 -0
  85. package/dist/schemas/config.js +62 -0
  86. package/dist/schemas/config.js.map +1 -0
  87. package/dist/schemas/engine.d.ts +772 -0
  88. package/dist/schemas/engine.d.ts.map +1 -0
  89. package/dist/schemas/engine.js +93 -0
  90. package/dist/schemas/engine.js.map +1 -0
  91. package/dist/schemas/index.d.ts +5 -0
  92. package/dist/schemas/index.d.ts.map +1 -0
  93. package/dist/schemas/index.js +5 -0
  94. package/dist/schemas/index.js.map +1 -0
  95. package/dist/schemas/state.d.ts +416 -0
  96. package/dist/schemas/state.d.ts.map +1 -0
  97. package/dist/schemas/state.js +56 -0
  98. package/dist/schemas/state.js.map +1 -0
  99. package/dist/server/index.d.ts +2 -0
  100. package/dist/server/index.d.ts.map +1 -0
  101. package/dist/server/index.js +51 -0
  102. package/dist/server/index.js.map +1 -0
  103. package/dist/server/webhook.d.ts +6 -0
  104. package/dist/server/webhook.d.ts.map +1 -0
  105. package/dist/server/webhook.js +163 -0
  106. package/dist/server/webhook.js.map +1 -0
  107. package/dist/utils/index.d.ts +4 -0
  108. package/dist/utils/index.d.ts.map +1 -0
  109. package/dist/utils/index.js +4 -0
  110. package/dist/utils/index.js.map +1 -0
  111. package/dist/utils/logger.d.ts +17 -0
  112. package/dist/utils/logger.d.ts.map +1 -0
  113. package/dist/utils/logger.js +25 -0
  114. package/dist/utils/logger.js.map +1 -0
  115. package/dist/utils/paths.d.ts +37 -0
  116. package/dist/utils/paths.d.ts.map +1 -0
  117. package/dist/utils/paths.js +35 -0
  118. package/dist/utils/paths.js.map +1 -0
  119. package/dist/utils/spinner.d.ts +4 -0
  120. package/dist/utils/spinner.d.ts.map +1 -0
  121. package/dist/utils/spinner.js +20 -0
  122. package/dist/utils/spinner.js.map +1 -0
  123. package/package.json +58 -0
@@ -0,0 +1,312 @@
1
+ import { writeFile, symlink, unlink } from 'fs/promises';
2
+ import { existsSync } from 'fs';
3
+ import { join } from 'path';
4
+ import { execa } from 'execa';
5
+ import { NGINX_AVAILABLE, NGINX_ENABLED } from '../utils/paths.js';
6
+ // Generate nginx config for a proxy app
7
+ export function generateProxyConfig(config) {
8
+ const domain = config.domain;
9
+ const port = config.port;
10
+ const nginx = config.nginx || {};
11
+ const aliases = config.aliases?.length
12
+ ? ' ' + config.aliases.join(' ')
13
+ : '';
14
+ const clientMaxBody = nginx.client_max_body_size || '10M';
15
+ const readTimeout = nginx.proxy_read_timeout || 60;
16
+ const sendTimeout = nginx.proxy_send_timeout || 60;
17
+ let websocketConfig = '';
18
+ if (nginx.websocket_path) {
19
+ websocketConfig = `
20
+ # WebSocket support
21
+ location ${nginx.websocket_path} {
22
+ proxy_pass http://127.0.0.1:${port};
23
+ proxy_http_version 1.1;
24
+ proxy_set_header Upgrade $http_upgrade;
25
+ proxy_set_header Connection "upgrade";
26
+ proxy_set_header Host $host;
27
+ proxy_read_timeout 86400;
28
+ proxy_send_timeout 86400;
29
+ }
30
+ `;
31
+ }
32
+ return `# Generated by Shyp - ${config.name}
33
+ # Do not edit manually
34
+
35
+ server {
36
+ listen 80;
37
+ listen [::]:80;
38
+ server_name ${domain}${aliases};
39
+
40
+ return 301 https://$server_name$request_uri;
41
+ }
42
+
43
+ server {
44
+ listen 443 ssl http2;
45
+ listen [::]:443 ssl http2;
46
+ server_name ${domain}${aliases};
47
+
48
+ ssl_certificate /etc/letsencrypt/live/${domain}/fullchain.pem;
49
+ ssl_certificate_key /etc/letsencrypt/live/${domain}/privkey.pem;
50
+ include /etc/letsencrypt/options-ssl-nginx.conf;
51
+ ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
52
+
53
+ # Security headers
54
+ add_header X-Frame-Options "SAMEORIGIN" always;
55
+ add_header X-Content-Type-Options "nosniff" always;
56
+ add_header X-XSS-Protection "1; mode=block" always;
57
+ add_header Referrer-Policy "strict-origin-when-cross-origin" always;
58
+
59
+ client_max_body_size ${clientMaxBody};
60
+
61
+ # Proxy to Node.js app
62
+ location / {
63
+ proxy_pass http://127.0.0.1:${port};
64
+ proxy_http_version 1.1;
65
+ proxy_set_header Upgrade $http_upgrade;
66
+ proxy_set_header Connection "upgrade";
67
+ proxy_set_header Host $host;
68
+ proxy_set_header X-Real-IP $remote_addr;
69
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
70
+ proxy_set_header X-Forwarded-Proto $scheme;
71
+ proxy_read_timeout ${readTimeout};
72
+ proxy_send_timeout ${sendTimeout};
73
+ }
74
+ ${websocketConfig}
75
+ # Cache Next.js static assets
76
+ location /_next/static {
77
+ proxy_pass http://127.0.0.1:${port};
78
+ proxy_cache_valid 200 60m;
79
+ add_header Cache-Control "public, max-age=31536000, immutable";
80
+ }
81
+
82
+ # Gzip compression
83
+ gzip on;
84
+ gzip_vary on;
85
+ gzip_min_length 1024;
86
+ gzip_types text/plain text/css text/xml text/javascript application/x-javascript application/xml+rss application/json application/javascript image/svg+xml;
87
+
88
+ access_log /var/log/nginx/${config.name}-access.log;
89
+ error_log /var/log/nginx/${config.name}-error.log;
90
+ }
91
+ `;
92
+ }
93
+ // Generate nginx config for a static site
94
+ export function generateStaticConfig(config) {
95
+ const domain = config.domain;
96
+ const root = config.path;
97
+ const nginx = config.nginx || {};
98
+ const aliases = config.aliases?.length
99
+ ? ' ' + config.aliases.join(' ')
100
+ : '';
101
+ // For Next.js static exports, serve from /out
102
+ const staticRoot = config.type === 'nextjs' ? `${root}/out` : root;
103
+ return `# Generated by Shyp - ${config.name} (static)
104
+ # Do not edit manually
105
+
106
+ server {
107
+ listen 80;
108
+ listen [::]:80;
109
+ server_name ${domain}${aliases};
110
+
111
+ return 301 https://$server_name$request_uri;
112
+ }
113
+
114
+ server {
115
+ listen 443 ssl http2;
116
+ listen [::]:443 ssl http2;
117
+ server_name ${domain}${aliases};
118
+
119
+ ssl_certificate /etc/letsencrypt/live/${domain}/fullchain.pem;
120
+ ssl_certificate_key /etc/letsencrypt/live/${domain}/privkey.pem;
121
+ include /etc/letsencrypt/options-ssl-nginx.conf;
122
+ ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
123
+
124
+ # Security headers
125
+ add_header X-Frame-Options "SAMEORIGIN" always;
126
+ add_header X-Content-Type-Options "nosniff" always;
127
+ add_header X-XSS-Protection "1; mode=block" always;
128
+ add_header Referrer-Policy "strict-origin-when-cross-origin" always;
129
+
130
+ root ${staticRoot};
131
+ index index.html;
132
+
133
+ # Handle routing (SPA/Next.js static export)
134
+ location / {
135
+ try_files $uri $uri/ $uri.html /index.html;
136
+ }
137
+
138
+ # Cache Next.js static assets aggressively
139
+ location /_next/static {
140
+ expires 1y;
141
+ add_header Cache-Control "public, max-age=31536000, immutable";
142
+ }
143
+
144
+ # Cache public assets
145
+ location /assets {
146
+ expires 1M;
147
+ add_header Cache-Control "public, max-age=2592000";
148
+ }
149
+
150
+ # Cache other static files
151
+ location ~* \\.(ico|css|js|gif|jpeg|jpg|png|woff|woff2|ttf|svg|eot|webp)$ {
152
+ expires 1M;
153
+ add_header Cache-Control "public, max-age=2592000";
154
+ }
155
+
156
+ # Gzip compression
157
+ gzip on;
158
+ gzip_vary on;
159
+ gzip_min_length 1024;
160
+ gzip_types text/plain text/css text/xml text/javascript application/x-javascript application/xml+rss application/json application/javascript image/svg+xml;
161
+
162
+ access_log /var/log/nginx/${config.name}-access.log;
163
+ error_log /var/log/nginx/${config.name}-error.log;
164
+ }
165
+ `;
166
+ }
167
+ // Generate nginx config for an engine module
168
+ export function generateModuleConfig(engine, moduleName, moduleConfig) {
169
+ const domain = moduleConfig.domain;
170
+ const port = moduleConfig.port;
171
+ const nginx = moduleConfig.nginx || {};
172
+ const aliases = moduleConfig.aliases?.length
173
+ ? ' ' + moduleConfig.aliases.join(' ')
174
+ : '';
175
+ // Shared engine services (WebSocket, API)
176
+ let sharedServices = '';
177
+ if (nginx.websocket_path && nginx.websocket_port) {
178
+ sharedServices += `
179
+ # Engine WebSocket (shared)
180
+ location ${nginx.websocket_path} {
181
+ proxy_pass http://127.0.0.1:${nginx.websocket_port};
182
+ proxy_http_version 1.1;
183
+ proxy_set_header Upgrade $http_upgrade;
184
+ proxy_set_header Connection "upgrade";
185
+ proxy_set_header Host $host;
186
+ proxy_read_timeout 86400;
187
+ proxy_send_timeout 86400;
188
+ }
189
+ `;
190
+ }
191
+ if (nginx.api_path && nginx.api_port) {
192
+ sharedServices += `
193
+ # Engine API (shared)
194
+ location ${nginx.api_path} {
195
+ proxy_pass http://127.0.0.1:${nginx.api_port};
196
+ proxy_http_version 1.1;
197
+ proxy_set_header Host $host;
198
+ proxy_set_header X-Real-IP $remote_addr;
199
+ }
200
+ `;
201
+ }
202
+ return `# Generated by Shyp - ${engine.name}/${moduleName}
203
+ # Do not edit manually
204
+
205
+ server {
206
+ listen 80;
207
+ listen [::]:80;
208
+ server_name ${domain}${aliases};
209
+
210
+ return 301 https://$server_name$request_uri;
211
+ }
212
+
213
+ server {
214
+ listen 443 ssl http2;
215
+ listen [::]:443 ssl http2;
216
+ server_name ${domain}${aliases};
217
+
218
+ ssl_certificate /etc/letsencrypt/live/${domain}/fullchain.pem;
219
+ ssl_certificate_key /etc/letsencrypt/live/${domain}/privkey.pem;
220
+ include /etc/letsencrypt/options-ssl-nginx.conf;
221
+ ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
222
+
223
+ # Security headers
224
+ add_header X-Frame-Options "SAMEORIGIN" always;
225
+ add_header X-Content-Type-Options "nosniff" always;
226
+ add_header X-XSS-Protection "1; mode=block" always;
227
+ add_header Referrer-Policy "strict-origin-when-cross-origin" always;
228
+
229
+ # Module frontend
230
+ location / {
231
+ proxy_pass http://127.0.0.1:${port};
232
+ proxy_http_version 1.1;
233
+ proxy_set_header Upgrade $http_upgrade;
234
+ proxy_set_header Connection "upgrade";
235
+ proxy_set_header Host $host;
236
+ proxy_set_header X-Real-IP $remote_addr;
237
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
238
+ proxy_set_header X-Forwarded-Proto $scheme;
239
+ }
240
+ ${sharedServices}
241
+ # Gzip compression
242
+ gzip on;
243
+ gzip_vary on;
244
+ gzip_min_length 1024;
245
+ gzip_types text/plain text/css text/xml text/javascript application/x-javascript application/xml+rss application/json application/javascript image/svg+xml;
246
+
247
+ access_log /var/log/nginx/${engine.name}-${moduleName}-access.log;
248
+ error_log /var/log/nginx/${engine.name}-${moduleName}-error.log;
249
+ }
250
+ `;
251
+ }
252
+ // Generate nginx config based on app type
253
+ export function generateNginxConfig(config) {
254
+ if (config.type === 'static') {
255
+ return generateStaticConfig(config);
256
+ }
257
+ return generateProxyConfig(config);
258
+ }
259
+ // Get nginx config file name
260
+ export function getNginxConfigName(name) {
261
+ return `shyp-${name}.conf`;
262
+ }
263
+ // Write nginx config to sites-available
264
+ export async function writeNginxConfig(name, content) {
265
+ const filename = getNginxConfigName(name);
266
+ const path = join(NGINX_AVAILABLE, filename);
267
+ await writeFile(path, content);
268
+ }
269
+ // Enable nginx config (symlink to sites-enabled)
270
+ export async function enableNginxConfig(name) {
271
+ const filename = getNginxConfigName(name);
272
+ const availablePath = join(NGINX_AVAILABLE, filename);
273
+ const enabledPath = join(NGINX_ENABLED, filename);
274
+ // Remove existing symlink if present
275
+ if (existsSync(enabledPath)) {
276
+ await unlink(enabledPath);
277
+ }
278
+ await symlink(availablePath, enabledPath);
279
+ }
280
+ // Disable nginx config
281
+ export async function disableNginxConfig(name) {
282
+ const filename = getNginxConfigName(name);
283
+ const enabledPath = join(NGINX_ENABLED, filename);
284
+ if (existsSync(enabledPath)) {
285
+ await unlink(enabledPath);
286
+ }
287
+ }
288
+ // Test nginx configuration
289
+ export async function testNginxConfig() {
290
+ try {
291
+ await execa('nginx', ['-t']);
292
+ return { valid: true };
293
+ }
294
+ catch (error) {
295
+ return { valid: false, error: error.stderr || error.message };
296
+ }
297
+ }
298
+ // Reload nginx
299
+ export async function reloadNginx() {
300
+ await execa('systemctl', ['reload', 'nginx']);
301
+ }
302
+ // Check if nginx is available
303
+ export async function isNginxAvailable() {
304
+ try {
305
+ await execa('nginx', ['-v']);
306
+ return true;
307
+ }
308
+ catch {
309
+ return false;
310
+ }
311
+ }
312
+ //# sourceMappingURL=nginx.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nginx.js","sourceRoot":"","sources":["../../src/lib/nginx.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ export interface PM2Process {
2
+ name: string;
3
+ pm_id: number;
4
+ status: 'online' | 'stopped' | 'errored' | 'launching';
5
+ memory: number;
6
+ cpu: number;
7
+ uptime: number;
8
+ restarts: number;
9
+ }
10
+ export declare function listProcesses(): Promise<PM2Process[]>;
11
+ export declare function getProcess(name: string): Promise<PM2Process | null>;
12
+ export declare function startProcess(name: string, script: string, options?: {
13
+ cwd?: string;
14
+ env?: Record<string, string>;
15
+ instances?: number;
16
+ maxMemory?: string;
17
+ }): Promise<void>;
18
+ export declare function stopProcess(name: string): Promise<void>;
19
+ export declare function restartProcess(name: string): Promise<void>;
20
+ export declare function deleteProcess(name: string): Promise<void>;
21
+ export declare function saveProcessList(): Promise<void>;
22
+ export declare function isPM2Available(): Promise<boolean>;
23
+ export declare function formatMemory(bytes: number): string;
24
+ export declare function formatUptime(startTime: number): string;
25
+ //# sourceMappingURL=pm2.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pm2.d.ts","sourceRoot":"","sources":["../../src/lib/pm2.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,QAAQ,GAAG,SAAS,GAAG,SAAS,GAAG,WAAW,CAAA;IACtD,MAAM,EAAE,MAAM,CAAA;IACd,GAAG,EAAE,MAAM,CAAA;IACX,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;CACjB;AAGD,wBAAsB,aAAa,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC,CAiB3D;AAGD,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAGzE;AAGD,wBAAsB,YAAY,CAChC,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,OAAO,GAAE;IACP,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,SAAS,CAAC,EAAE,MAAM,CAAA;CACd,GACL,OAAO,CAAC,IAAI,CAAC,CAkBf;AAGD,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAM7D;AAGD,wBAAsB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAEhE;AAGD,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAM/D;AAGD,wBAAsB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CAErD;AAGD,wBAAsB,cAAc,IAAI,OAAO,CAAC,OAAO,CAAC,CAOvD;AAGD,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAKlD;AAGD,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAatD"}
@@ -0,0 +1,106 @@
1
+ import { execa } from 'execa';
2
+ // Get list of PM2 processes
3
+ export async function listProcesses() {
4
+ try {
5
+ const { stdout } = await execa('pm2', ['jlist']);
6
+ const processes = JSON.parse(stdout);
7
+ return processes.map((p) => ({
8
+ name: p.name,
9
+ pm_id: p.pm_id,
10
+ status: p.pm2_env?.status || 'stopped',
11
+ memory: p.monit?.memory || 0,
12
+ cpu: p.monit?.cpu || 0,
13
+ uptime: p.pm2_env?.pm_uptime || 0,
14
+ restarts: p.pm2_env?.restart_time || 0,
15
+ }));
16
+ }
17
+ catch {
18
+ return [];
19
+ }
20
+ }
21
+ // Get a specific process by name
22
+ export async function getProcess(name) {
23
+ const processes = await listProcesses();
24
+ return processes.find(p => p.name === name) || null;
25
+ }
26
+ // Start a process
27
+ export async function startProcess(name, script, options = {}) {
28
+ const args = [
29
+ 'start', script,
30
+ '--name', name,
31
+ ];
32
+ if (options.instances) {
33
+ args.push('-i', String(options.instances));
34
+ }
35
+ if (options.maxMemory) {
36
+ args.push('--max-memory-restart', options.maxMemory);
37
+ }
38
+ await execa('pm2', args, {
39
+ cwd: options.cwd,
40
+ env: { ...process.env, ...options.env },
41
+ });
42
+ }
43
+ // Stop a process
44
+ export async function stopProcess(name) {
45
+ try {
46
+ await execa('pm2', ['stop', name]);
47
+ }
48
+ catch {
49
+ // Process might not exist, that's ok
50
+ }
51
+ }
52
+ // Restart a process
53
+ export async function restartProcess(name) {
54
+ await execa('pm2', ['restart', name]);
55
+ }
56
+ // Delete a process
57
+ export async function deleteProcess(name) {
58
+ try {
59
+ await execa('pm2', ['delete', name]);
60
+ }
61
+ catch {
62
+ // Process might not exist, that's ok
63
+ }
64
+ }
65
+ // Save PM2 process list
66
+ export async function saveProcessList() {
67
+ await execa('pm2', ['save']);
68
+ }
69
+ // Check if PM2 is available
70
+ export async function isPM2Available() {
71
+ try {
72
+ await execa('pm2', ['--version']);
73
+ return true;
74
+ }
75
+ catch {
76
+ return false;
77
+ }
78
+ }
79
+ // Format memory for display
80
+ export function formatMemory(bytes) {
81
+ if (bytes < 1024)
82
+ return `${bytes}B`;
83
+ if (bytes < 1024 * 1024)
84
+ return `${(bytes / 1024).toFixed(1)}KB`;
85
+ if (bytes < 1024 * 1024 * 1024)
86
+ return `${(bytes / (1024 * 1024)).toFixed(1)}MB`;
87
+ return `${(bytes / (1024 * 1024 * 1024)).toFixed(1)}GB`;
88
+ }
89
+ // Format uptime for display
90
+ export function formatUptime(startTime) {
91
+ if (!startTime)
92
+ return '-';
93
+ const diff = Date.now() - startTime;
94
+ const seconds = Math.floor(diff / 1000);
95
+ const minutes = Math.floor(seconds / 60);
96
+ const hours = Math.floor(minutes / 60);
97
+ const days = Math.floor(hours / 24);
98
+ if (days > 0)
99
+ return `${days}d ${hours % 24}h`;
100
+ if (hours > 0)
101
+ return `${hours}h ${minutes % 60}m`;
102
+ if (minutes > 0)
103
+ return `${minutes}m ${seconds % 60}s`;
104
+ return `${seconds}s`;
105
+ }
106
+ //# sourceMappingURL=pm2.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pm2.js","sourceRoot":"","sources":["../../src/lib/pm2.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import { type PortAllocations, type DeploymentsState, type HealthState, type DeploymentRecord } from '../schemas/index.js';
2
+ export declare function loadPortAllocations(): Promise<PortAllocations>;
3
+ export declare function savePortAllocations(state: PortAllocations): Promise<void>;
4
+ export declare function allocatePort(appName: string, range?: 'standard' | 'games' | 'special'): Promise<number>;
5
+ export declare function loadDeployments(): Promise<DeploymentsState>;
6
+ export declare function saveDeployments(state: DeploymentsState): Promise<void>;
7
+ export declare function recordDeployment(appName: string, record: DeploymentRecord): Promise<void>;
8
+ export declare function getLastSuccessfulDeployment(state: DeploymentsState, appName: string): DeploymentRecord | null;
9
+ export declare function loadHealth(): Promise<HealthState>;
10
+ export declare function saveHealth(state: HealthState): Promise<void>;
11
+ export declare function generateDeploymentId(): string;
12
+ //# sourceMappingURL=state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../src/lib/state.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,KAAK,WAAW,EAChB,KAAK,gBAAgB,EAItB,MAAM,qBAAqB,CAAA;AAiD5B,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,eAAe,CAAC,CAEpE;AAGD,wBAAsB,mBAAmB,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAE/E;AAGD,wBAAsB,YAAY,CAChC,OAAO,EAAE,MAAM,EACf,KAAK,GAAE,UAAU,GAAG,OAAO,GAAG,SAAsB,GACnD,OAAO,CAAC,MAAM,CAAC,CAmCjB;AAGD,wBAAsB,eAAe,IAAI,OAAO,CAAC,gBAAgB,CAAC,CAEjE;AAGD,wBAAsB,eAAe,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAE5E;AAGD,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,gBAAgB,GACvB,OAAO,CAAC,IAAI,CAAC,CAcf;AAGD,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,gBAAgB,EACvB,OAAO,EAAE,MAAM,GACd,gBAAgB,GAAG,IAAI,CAGzB;AAGD,wBAAsB,UAAU,IAAI,OAAO,CAAC,WAAW,CAAC,CAEvD;AAGD,wBAAsB,UAAU,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAElE;AAGD,wBAAgB,oBAAoB,IAAI,MAAM,CAG7C"}
@@ -0,0 +1,112 @@
1
+ import { readFile, writeFile, mkdir } from 'fs/promises';
2
+ import { existsSync } from 'fs';
3
+ import { PortAllocationsSchema, DeploymentsStateSchema, HealthStateSchema, } from '../schemas/index.js';
4
+ import { STATE_DIR, PORTS_FILE, DEPLOYMENTS_FILE, HEALTH_FILE, PORT_RANGES, } from '../utils/paths.js';
5
+ // Ensure state directory exists
6
+ async function ensureStateDir() {
7
+ if (!existsSync(STATE_DIR)) {
8
+ await mkdir(STATE_DIR, { recursive: true });
9
+ }
10
+ }
11
+ // Load JSON state file
12
+ async function loadStateFile(path, schema, defaultValue) {
13
+ if (!existsSync(path)) {
14
+ return defaultValue;
15
+ }
16
+ const content = await readFile(path, 'utf-8');
17
+ const data = JSON.parse(content);
18
+ return schema.parse(data);
19
+ }
20
+ // Save JSON state file
21
+ async function saveStateFile(path, data) {
22
+ await ensureStateDir();
23
+ await writeFile(path, JSON.stringify(data, null, 2));
24
+ }
25
+ // Default port allocations
26
+ const defaultPortAllocations = {
27
+ allocations: {},
28
+ reserved: [4040, 8080, 9000], // Wyrt HTTP, WS, webhook
29
+ engine_managed: {},
30
+ ranges: {
31
+ standard: { ...PORT_RANGES.standard, next: PORT_RANGES.standard.start },
32
+ games: { ...PORT_RANGES.games, next: PORT_RANGES.games.start },
33
+ special: { ...PORT_RANGES.special, next: PORT_RANGES.special.start },
34
+ },
35
+ };
36
+ // Load port allocations
37
+ export async function loadPortAllocations() {
38
+ return loadStateFile(PORTS_FILE, PortAllocationsSchema, defaultPortAllocations);
39
+ }
40
+ // Save port allocations
41
+ export async function savePortAllocations(state) {
42
+ await saveStateFile(PORTS_FILE, state);
43
+ }
44
+ // Allocate a port for an app
45
+ export async function allocatePort(appName, range = 'standard') {
46
+ const state = await loadPortAllocations();
47
+ // Check if already allocated
48
+ if (state.allocations[appName]) {
49
+ return state.allocations[appName];
50
+ }
51
+ // Find next available port
52
+ const rangeConfig = state.ranges?.[range] || defaultPortAllocations.ranges[range];
53
+ let port = rangeConfig.next;
54
+ // Skip reserved and already allocated ports
55
+ const usedPorts = new Set([
56
+ ...Object.values(state.allocations),
57
+ ...state.reserved,
58
+ ...Object.values(state.engine_managed).flat(),
59
+ ]);
60
+ while (usedPorts.has(port) && port <= rangeConfig.end) {
61
+ port++;
62
+ }
63
+ if (port > rangeConfig.end) {
64
+ throw new Error(`No available ports in ${range} range (${rangeConfig.start}-${rangeConfig.end})`);
65
+ }
66
+ // Update state
67
+ state.allocations[appName] = port;
68
+ if (state.ranges) {
69
+ state.ranges[range].next = port + 1;
70
+ }
71
+ await savePortAllocations(state);
72
+ return port;
73
+ }
74
+ // Load deployments state
75
+ export async function loadDeployments() {
76
+ return loadStateFile(DEPLOYMENTS_FILE, DeploymentsStateSchema, {});
77
+ }
78
+ // Save deployments state
79
+ export async function saveDeployments(state) {
80
+ await saveStateFile(DEPLOYMENTS_FILE, state);
81
+ }
82
+ // Record a deployment
83
+ export async function recordDeployment(appName, record) {
84
+ const state = await loadDeployments();
85
+ if (!state[appName]) {
86
+ state[appName] = { history: [] };
87
+ }
88
+ state[appName].current = record.id;
89
+ state[appName].history.unshift(record);
90
+ // Keep only recent deployments
91
+ state[appName].history = state[appName].history.slice(0, 10);
92
+ await saveDeployments(state);
93
+ }
94
+ // Get last successful deployment
95
+ export function getLastSuccessfulDeployment(state, appName) {
96
+ const history = state[appName]?.history || [];
97
+ return history.find(d => d.status === 'success') || null;
98
+ }
99
+ // Load health state
100
+ export async function loadHealth() {
101
+ return loadStateFile(HEALTH_FILE, HealthStateSchema, {});
102
+ }
103
+ // Save health state
104
+ export async function saveHealth(state) {
105
+ await saveStateFile(HEALTH_FILE, state);
106
+ }
107
+ // Generate deployment ID (timestamp-based)
108
+ export function generateDeploymentId() {
109
+ const now = new Date();
110
+ return now.toISOString().replace(/[-:T]/g, '').slice(0, 14);
111
+ }
112
+ //# sourceMappingURL=state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.js","sourceRoot":"","sources":["../../src/lib/state.ts"],"names":[],"mappings":"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"}