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.
- package/LICENSE +21 -0
- package/README.md +218 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +64 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/add.d.ts +9 -0
- package/dist/commands/add.d.ts.map +1 -0
- package/dist/commands/add.js +69 -0
- package/dist/commands/add.js.map +1 -0
- package/dist/commands/deploy.d.ts +4 -0
- package/dist/commands/deploy.d.ts.map +1 -0
- package/dist/commands/deploy.js +104 -0
- package/dist/commands/deploy.js.map +1 -0
- package/dist/commands/doctor.d.ts +2 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +97 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/index.d.ts +10 -0
- package/dist/commands/index.d.ts.map +1 -0
- package/dist/commands/index.js +10 -0
- package/dist/commands/index.js.map +1 -0
- package/dist/commands/init.d.ts +4 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +150 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/logs.d.ts +5 -0
- package/dist/commands/logs.d.ts.map +1 -0
- package/dist/commands/logs.js +56 -0
- package/dist/commands/logs.js.map +1 -0
- package/dist/commands/ports.d.ts +2 -0
- package/dist/commands/ports.d.ts.map +1 -0
- package/dist/commands/ports.js +73 -0
- package/dist/commands/ports.js.map +1 -0
- package/dist/commands/start.d.ts +2 -0
- package/dist/commands/start.d.ts.map +1 -0
- package/dist/commands/start.js +11 -0
- package/dist/commands/start.js.map +1 -0
- package/dist/commands/status.d.ts +2 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +73 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/sync.d.ts +4 -0
- package/dist/commands/sync.d.ts.map +1 -0
- package/dist/commands/sync.js +95 -0
- package/dist/commands/sync.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/config.d.ts +10 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +116 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/deploy.d.ts +12 -0
- package/dist/lib/deploy.d.ts.map +1 -0
- package/dist/lib/deploy.js +288 -0
- package/dist/lib/deploy.js.map +1 -0
- package/dist/lib/git.d.ts +24 -0
- package/dist/lib/git.d.ts.map +1 -0
- package/dist/lib/git.js +82 -0
- package/dist/lib/git.js.map +1 -0
- package/dist/lib/index.d.ts +7 -0
- package/dist/lib/index.d.ts.map +1 -0
- package/dist/lib/index.js +7 -0
- package/dist/lib/index.js.map +1 -0
- package/dist/lib/nginx.d.ts +16 -0
- package/dist/lib/nginx.d.ts.map +1 -0
- package/dist/lib/nginx.js +312 -0
- package/dist/lib/nginx.js.map +1 -0
- package/dist/lib/pm2.d.ts +25 -0
- package/dist/lib/pm2.d.ts.map +1 -0
- package/dist/lib/pm2.js +106 -0
- package/dist/lib/pm2.js.map +1 -0
- package/dist/lib/state.d.ts +12 -0
- package/dist/lib/state.d.ts.map +1 -0
- package/dist/lib/state.js +112 -0
- package/dist/lib/state.js.map +1 -0
- package/dist/schemas/app.d.ts +272 -0
- package/dist/schemas/app.d.ts.map +1 -0
- package/dist/schemas/app.js +79 -0
- package/dist/schemas/app.js.map +1 -0
- package/dist/schemas/config.d.ts +508 -0
- package/dist/schemas/config.d.ts.map +1 -0
- package/dist/schemas/config.js +62 -0
- package/dist/schemas/config.js.map +1 -0
- package/dist/schemas/engine.d.ts +772 -0
- package/dist/schemas/engine.d.ts.map +1 -0
- package/dist/schemas/engine.js +93 -0
- package/dist/schemas/engine.js.map +1 -0
- package/dist/schemas/index.d.ts +5 -0
- package/dist/schemas/index.d.ts.map +1 -0
- package/dist/schemas/index.js +5 -0
- package/dist/schemas/index.js.map +1 -0
- package/dist/schemas/state.d.ts +416 -0
- package/dist/schemas/state.d.ts.map +1 -0
- package/dist/schemas/state.js +56 -0
- package/dist/schemas/state.js.map +1 -0
- package/dist/server/index.d.ts +2 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +51 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/webhook.d.ts +6 -0
- package/dist/server/webhook.d.ts.map +1 -0
- package/dist/server/webhook.js +163 -0
- package/dist/server/webhook.js.map +1 -0
- package/dist/utils/index.d.ts +4 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +4 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/logger.d.ts +17 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +25 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/paths.d.ts +37 -0
- package/dist/utils/paths.d.ts.map +1 -0
- package/dist/utils/paths.js +35 -0
- package/dist/utils/paths.js.map +1 -0
- package/dist/utils/spinner.d.ts +4 -0
- package/dist/utils/spinner.d.ts.map +1 -0
- package/dist/utils/spinner.js +20 -0
- package/dist/utils/spinner.js.map +1 -0
- 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"}
|
package/dist/lib/pm2.js
ADDED
|
@@ -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":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,OAAO,CAAA;AAY7B,4BAA4B;AAC5B,MAAM,CAAC,KAAK,UAAU,aAAa;IACjC,IAAI,CAAC;QACH,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,KAAK,CAAC,KAAK,EAAE,CAAC,OAAO,CAAC,CAAC,CAAA;QAChD,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;QAEpC,OAAO,SAAS,CAAC,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC;YAChC,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,KAAK,EAAE,CAAC,CAAC,KAAK;YACd,MAAM,EAAE,CAAC,CAAC,OAAO,EAAE,MAAM,IAAI,SAAS;YACtC,MAAM,EAAE,CAAC,CAAC,KAAK,EAAE,MAAM,IAAI,CAAC;YAC5B,GAAG,EAAE,CAAC,CAAC,KAAK,EAAE,GAAG,IAAI,CAAC;YACtB,MAAM,EAAE,CAAC,CAAC,OAAO,EAAE,SAAS,IAAI,CAAC;YACjC,QAAQ,EAAE,CAAC,CAAC,OAAO,EAAE,YAAY,IAAI,CAAC;SACvC,CAAC,CAAC,CAAA;IACL,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAA;IACX,CAAC;AACH,CAAC;AAED,iCAAiC;AACjC,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,IAAY;IAC3C,MAAM,SAAS,GAAG,MAAM,aAAa,EAAE,CAAA;IACvC,OAAO,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,IAAI,CAAA;AACrD,CAAC;AAED,kBAAkB;AAClB,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,IAAY,EACZ,MAAc,EACd,UAKI,EAAE;IAEN,MAAM,IAAI,GAAG;QACX,OAAO,EAAE,MAAM;QACf,QAAQ,EAAE,IAAI;KACf,CAAA;IAED,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;QACtB,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAA;IAC5C,CAAC;IAED,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;QACtB,IAAI,CAAC,IAAI,CAAC,sBAAsB,EAAE,OAAO,CAAC,SAAS,CAAC,CAAA;IACtD,CAAC;IAED,MAAM,KAAK,CAAC,KAAK,EAAE,IAAI,EAAE;QACvB,GAAG,EAAE,OAAO,CAAC,GAAG;QAChB,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE;KACxC,CAAC,CAAA;AACJ,CAAC;AAED,iBAAiB;AACjB,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,IAAY;IAC5C,IAAI,CAAC;QACH,MAAM,KAAK,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAA;IACpC,CAAC;IAAC,MAAM,CAAC;QACP,qCAAqC;IACvC,CAAC;AACH,CAAC;AAED,oBAAoB;AACpB,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,IAAY;IAC/C,MAAM,KAAK,CAAC,KAAK,EAAE,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC,CAAA;AACvC,CAAC;AAED,mBAAmB;AACnB,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,IAAY;IAC9C,IAAI,CAAC;QACH,MAAM,KAAK,CAAC,KAAK,EAAE,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAA;IACtC,CAAC;IAAC,MAAM,CAAC;QACP,qCAAqC;IACvC,CAAC;AACH,CAAC;AAED,wBAAwB;AACxB,MAAM,CAAC,KAAK,UAAU,eAAe;IACnC,MAAM,KAAK,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,CAAC,CAAA;AAC9B,CAAC;AAED,4BAA4B;AAC5B,MAAM,CAAC,KAAK,UAAU,cAAc;IAClC,IAAI,CAAC;QACH,MAAM,KAAK,CAAC,KAAK,EAAE,CAAC,WAAW,CAAC,CAAC,CAAA;QACjC,OAAO,IAAI,CAAA;IACb,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAA;IACd,CAAC;AACH,CAAC;AAED,4BAA4B;AAC5B,MAAM,UAAU,YAAY,CAAC,KAAa;IACxC,IAAI,KAAK,GAAG,IAAI;QAAE,OAAO,GAAG,KAAK,GAAG,CAAA;IACpC,IAAI,KAAK,GAAG,IAAI,GAAG,IAAI;QAAE,OAAO,GAAG,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAA;IAChE,IAAI,KAAK,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI;QAAE,OAAO,GAAG,CAAC,KAAK,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAA;IAChF,OAAO,GAAG,CAAC,KAAK,GAAG,CAAC,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAA;AACzD,CAAC;AAED,4BAA4B;AAC5B,MAAM,UAAU,YAAY,CAAC,SAAiB;IAC5C,IAAI,CAAC,SAAS;QAAE,OAAO,GAAG,CAAA;IAE1B,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAA;IACnC,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,CAAA;IACvC,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,EAAE,CAAC,CAAA;IACxC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,EAAE,CAAC,CAAA;IACtC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,EAAE,CAAC,CAAA;IAEnC,IAAI,IAAI,GAAG,CAAC;QAAE,OAAO,GAAG,IAAI,KAAK,KAAK,GAAG,EAAE,GAAG,CAAA;IAC9C,IAAI,KAAK,GAAG,CAAC;QAAE,OAAO,GAAG,KAAK,KAAK,OAAO,GAAG,EAAE,GAAG,CAAA;IAClD,IAAI,OAAO,GAAG,CAAC;QAAE,OAAO,GAAG,OAAO,KAAK,OAAO,GAAG,EAAE,GAAG,CAAA;IACtD,OAAO,GAAG,OAAO,GAAG,CAAA;AACtB,CAAC"}
|
|
@@ -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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"}
|