easy-vps 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/bin/cli.js +180 -0
- package/client/assets/index-C4GZ_uMC.js +104 -0
- package/client/assets/index-Dq-W19hL.css +2 -0
- package/client/assets/poppins-devanagari-400-normal-CJDn6rn8.woff2 +0 -0
- package/client/assets/poppins-devanagari-400-normal-CqVvlrh5.woff +0 -0
- package/client/assets/poppins-latin-400-normal-BOb3E3N0.woff +0 -0
- package/client/assets/poppins-latin-400-normal-cpxAROuN.woff2 +0 -0
- package/client/assets/poppins-latin-ext-400-normal-DaBSavcJ.woff +0 -0
- package/client/assets/poppins-latin-ext-400-normal-by3JarPu.woff2 +0 -0
- package/client/favicon.svg +1 -0
- package/client/icons.svg +24 -0
- package/client/index.html +14 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.js +143 -0
- package/dist/routes/async-route.d.ts +3 -0
- package/dist/routes/async-route.js +9 -0
- package/dist/routes/auth.d.ts +5 -0
- package/dist/routes/auth.js +101 -0
- package/dist/routes/database.d.ts +2 -0
- package/dist/routes/database.js +192 -0
- package/dist/routes/deploy.d.ts +2 -0
- package/dist/routes/deploy.js +161 -0
- package/dist/routes/domain.d.ts +2 -0
- package/dist/routes/domain.js +54 -0
- package/dist/routes/firewall.d.ts +2 -0
- package/dist/routes/firewall.js +63 -0
- package/dist/routes/instances.d.ts +2 -0
- package/dist/routes/instances.js +77 -0
- package/dist/routes/logs.d.ts +2 -0
- package/dist/routes/logs.js +67 -0
- package/dist/routes/system.d.ts +2 -0
- package/dist/routes/system.js +83 -0
- package/dist/services/auth.d.ts +25 -0
- package/dist/services/auth.js +128 -0
- package/dist/services/backup-config.d.ts +16 -0
- package/dist/services/backup-config.js +51 -0
- package/dist/services/backup-scheduler.d.ts +2 -0
- package/dist/services/backup-scheduler.js +104 -0
- package/dist/services/daemon.d.ts +28 -0
- package/dist/services/daemon.js +180 -0
- package/dist/services/database.d.ts +60 -0
- package/dist/services/database.js +540 -0
- package/dist/services/deploy.d.ts +102 -0
- package/dist/services/deploy.js +540 -0
- package/dist/services/domain.d.ts +26 -0
- package/dist/services/domain.js +170 -0
- package/dist/services/firewall.d.ts +24 -0
- package/dist/services/firewall.js +64 -0
- package/dist/services/instances.d.ts +17 -0
- package/dist/services/instances.js +67 -0
- package/dist/services/logs.d.ts +8 -0
- package/dist/services/logs.js +61 -0
- package/dist/services/metrics-history.d.ts +13 -0
- package/dist/services/metrics-history.js +36 -0
- package/dist/services/packages.d.ts +22 -0
- package/dist/services/packages.js +124 -0
- package/dist/services/s3.d.ts +17 -0
- package/dist/services/s3.js +93 -0
- package/dist/services/ssh.d.ts +78 -0
- package/dist/services/ssh.js +309 -0
- package/dist/services/system.d.ts +74 -0
- package/dist/services/system.js +286 -0
- package/package.json +55 -0
- package/scripts/dev.js +88 -0
- package/scripts/postinstall.js +123 -0
- package/scripts/preuninstall.js +21 -0
- package/scripts/try-install.sh +65 -0
- package/scripts/ui.js +54 -0
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
const express_1 = require("express");
|
|
37
|
+
const database = __importStar(require("../services/database"));
|
|
38
|
+
const backup_config_1 = require("../services/backup-config");
|
|
39
|
+
const async_route_1 = require("./async-route");
|
|
40
|
+
const router = (0, express_1.Router)();
|
|
41
|
+
router.get('/', (0, async_route_1.asyncRoute)(async (req, res) => {
|
|
42
|
+
res.json(await database.list(req.remote));
|
|
43
|
+
}));
|
|
44
|
+
router.post('/', (0, async_route_1.asyncRoute)(async (req, res) => {
|
|
45
|
+
const result = await database.createDatabase(req.remote, req.body);
|
|
46
|
+
res.status(201).json(result);
|
|
47
|
+
}));
|
|
48
|
+
router.delete('/:name', (0, async_route_1.asyncRoute)(async (req, res) => {
|
|
49
|
+
await database.removeDatabase(req.remote, req.params.name);
|
|
50
|
+
res.json({ ok: true });
|
|
51
|
+
}));
|
|
52
|
+
// Provision a connection pooler for an existing database (no recreation needed).
|
|
53
|
+
router.post('/:name/pooler', (0, async_route_1.asyncRoute)(async (req, res) => {
|
|
54
|
+
const databases = await database.list(req.remote);
|
|
55
|
+
const db = databases.find((d) => d.name === req.params.name);
|
|
56
|
+
if (!db) {
|
|
57
|
+
res.status(404).json({ error: 'Database not found' });
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
if (db.pooledPort > 0) {
|
|
61
|
+
res.json({ pooledPort: db.pooledPort });
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
const config = {
|
|
65
|
+
name: db.name,
|
|
66
|
+
engine: db.engine,
|
|
67
|
+
user: db.user,
|
|
68
|
+
password: db.password,
|
|
69
|
+
port: db.port,
|
|
70
|
+
poolSize: db.poolSize || 10,
|
|
71
|
+
};
|
|
72
|
+
const pooledPort = await database.startPooler(req.remote, config);
|
|
73
|
+
res.json({ pooledPort });
|
|
74
|
+
}));
|
|
75
|
+
// Backup settings
|
|
76
|
+
router.get('/:name/backup-settings', (0, async_route_1.asyncRoute)(async (req, res) => {
|
|
77
|
+
res.json((0, backup_config_1.getBackupConfig)(req.params.name));
|
|
78
|
+
}));
|
|
79
|
+
router.put('/:name/backup-settings', (0, async_route_1.asyncRoute)(async (req, res) => {
|
|
80
|
+
const { enabled, retention, s3 } = req.body ?? {};
|
|
81
|
+
// Store SSH credentials from current session for automated backups
|
|
82
|
+
const sshCreds = {
|
|
83
|
+
host: req.remote.creds.host,
|
|
84
|
+
port: req.remote.creds.port,
|
|
85
|
+
username: req.remote.creds.username,
|
|
86
|
+
password: req.remote.creds.password,
|
|
87
|
+
privateKey: req.remote.creds.privateKey,
|
|
88
|
+
passphrase: req.remote.creds.passphrase,
|
|
89
|
+
};
|
|
90
|
+
const config = (0, backup_config_1.setBackupConfig)(req.params.name, {
|
|
91
|
+
...(enabled !== undefined && { enabled }),
|
|
92
|
+
...(retention !== undefined && { retention }),
|
|
93
|
+
...(s3 !== undefined && { s3 }),
|
|
94
|
+
ssh: sshCreds,
|
|
95
|
+
});
|
|
96
|
+
res.json(config);
|
|
97
|
+
}));
|
|
98
|
+
// Backup operations
|
|
99
|
+
router.post('/:name/backup', (0, async_route_1.asyncRoute)(async (req, res) => {
|
|
100
|
+
// Get database engine from the list
|
|
101
|
+
const databases = await database.list(req.remote);
|
|
102
|
+
const db = databases.find((d) => d.name === req.params.name);
|
|
103
|
+
if (!db) {
|
|
104
|
+
res.status(404).json({ error: 'Database not found' });
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
const result = await database.backupToS3(req.remote, req.params.name, db.engine);
|
|
108
|
+
res.json(result);
|
|
109
|
+
}));
|
|
110
|
+
// Streaming backup with SSE
|
|
111
|
+
router.post('/:name/backup/stream', (req, res) => {
|
|
112
|
+
const name = req.params.name;
|
|
113
|
+
res.writeHead(200, {
|
|
114
|
+
'Content-Type': 'text/event-stream',
|
|
115
|
+
'Cache-Control': 'no-cache',
|
|
116
|
+
Connection: 'keep-alive',
|
|
117
|
+
});
|
|
118
|
+
const send = (event, data) => {
|
|
119
|
+
res.write(`event: ${event}\ndata: ${JSON.stringify(data)}\n\n`);
|
|
120
|
+
};
|
|
121
|
+
// Get database engine from the list
|
|
122
|
+
database.list(req.remote).then((databases) => {
|
|
123
|
+
const db = databases.find((d) => d.name === name);
|
|
124
|
+
if (!db) {
|
|
125
|
+
send('failed', 'Database not found');
|
|
126
|
+
res.end();
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
const cancel = database.backupStream(req.remote, name, db.engine, {
|
|
130
|
+
onOutput: (line) => send('log', line),
|
|
131
|
+
onDone: () => {
|
|
132
|
+
send('done', 'ok');
|
|
133
|
+
res.end();
|
|
134
|
+
},
|
|
135
|
+
onError: (msg) => {
|
|
136
|
+
send('failed', msg);
|
|
137
|
+
res.end();
|
|
138
|
+
},
|
|
139
|
+
});
|
|
140
|
+
req.on('close', cancel);
|
|
141
|
+
}).catch((err) => {
|
|
142
|
+
send('failed', err.message);
|
|
143
|
+
res.end();
|
|
144
|
+
});
|
|
145
|
+
});
|
|
146
|
+
// Download backup from S3
|
|
147
|
+
router.get('/:name/download', (0, async_route_1.asyncRoute)(async (req, res) => {
|
|
148
|
+
const { key } = req.query;
|
|
149
|
+
if (!key || typeof key !== 'string') {
|
|
150
|
+
res.status(400).json({ error: 'key query parameter is required' });
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
// Get database engine from the list
|
|
154
|
+
const databases = await database.list(req.remote);
|
|
155
|
+
const db = databases.find((d) => d.name === req.params.name);
|
|
156
|
+
if (!db) {
|
|
157
|
+
res.status(404).json({ error: 'Database not found' });
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
const { buffer, fileName } = await database.readBackupFromS3(req.params.name, db.engine, key);
|
|
161
|
+
res.setHeader('Content-Type', 'application/gzip');
|
|
162
|
+
res.setHeader('Content-Disposition', `attachment; filename="${fileName}"`);
|
|
163
|
+
res.send(buffer);
|
|
164
|
+
}));
|
|
165
|
+
router.get('/:name/backups', (0, async_route_1.asyncRoute)(async (req, res) => {
|
|
166
|
+
// Get database engine from the list
|
|
167
|
+
const databases = await database.list(req.remote);
|
|
168
|
+
const db = databases.find((d) => d.name === req.params.name);
|
|
169
|
+
if (!db) {
|
|
170
|
+
res.status(404).json({ error: 'Database not found' });
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
const backups = await database.listBackupsFromS3(req.params.name, db.engine);
|
|
174
|
+
res.json(backups);
|
|
175
|
+
}));
|
|
176
|
+
router.post('/:name/restore', (0, async_route_1.asyncRoute)(async (req, res) => {
|
|
177
|
+
const { s3Key } = req.body ?? {};
|
|
178
|
+
if (!s3Key) {
|
|
179
|
+
res.status(400).json({ error: 's3Key is required' });
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
// Get database engine from the list
|
|
183
|
+
const databases = await database.list(req.remote);
|
|
184
|
+
const db = databases.find((d) => d.name === req.params.name);
|
|
185
|
+
if (!db) {
|
|
186
|
+
res.status(404).json({ error: 'Database not found' });
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
await database.restoreFromS3(req.remote, req.params.name, db.engine, s3Key);
|
|
190
|
+
res.json({ ok: true });
|
|
191
|
+
}));
|
|
192
|
+
exports.default = router;
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
const express_1 = require("express");
|
|
37
|
+
const deploy = __importStar(require("../services/deploy"));
|
|
38
|
+
const async_route_1 = require("./async-route");
|
|
39
|
+
const router = (0, express_1.Router)();
|
|
40
|
+
router.get('/', (0, async_route_1.asyncRoute)(async (req, res) => {
|
|
41
|
+
res.json(await deploy.list(req.remote));
|
|
42
|
+
}));
|
|
43
|
+
/**
|
|
44
|
+
* Queues a deploy and hands back its id. The work itself runs on the stream
|
|
45
|
+
* below — an EventSource cannot POST, so the config is parked here first.
|
|
46
|
+
*/
|
|
47
|
+
router.post('/', (req, res) => {
|
|
48
|
+
try {
|
|
49
|
+
const id = deploy.createJob(req.session.id, req.body);
|
|
50
|
+
res.status(201).json({ id });
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
res.status(400).json({ error: error.message });
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
/** Live output of one queued job. Each id may be streamed once. */
|
|
57
|
+
router.get('/jobs/:id/stream', (req, res) => {
|
|
58
|
+
const job = deploy.takeJob(req.params.id, req.session.id);
|
|
59
|
+
if (!job) {
|
|
60
|
+
res.status(404).json({ error: 'Deploy job not found or already started' });
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
res.writeHead(200, {
|
|
64
|
+
'Content-Type': 'text/event-stream',
|
|
65
|
+
'Cache-Control': 'no-cache',
|
|
66
|
+
Connection: 'keep-alive',
|
|
67
|
+
});
|
|
68
|
+
const send = (event, data) => {
|
|
69
|
+
res.write(`event: ${event}\ndata: ${JSON.stringify(data)}\n\n`);
|
|
70
|
+
};
|
|
71
|
+
const streamHandlers = {
|
|
72
|
+
onOutput: (line) => send('log', line),
|
|
73
|
+
onDone: () => {
|
|
74
|
+
send('done', 'ok');
|
|
75
|
+
res.end();
|
|
76
|
+
},
|
|
77
|
+
onError: (message) => {
|
|
78
|
+
send('failed', message);
|
|
79
|
+
res.end();
|
|
80
|
+
},
|
|
81
|
+
};
|
|
82
|
+
const cancel = job.kind === 'rebuild'
|
|
83
|
+
? deploy.rebuildStream(req.remote, job.config, streamHandlers)
|
|
84
|
+
: deploy.deployStream(req.remote, job.config, streamHandlers);
|
|
85
|
+
req.on('close', cancel);
|
|
86
|
+
});
|
|
87
|
+
router.post('/:name/stop', (0, async_route_1.asyncRoute)(async (req, res) => {
|
|
88
|
+
await deploy.stop(req.params.name);
|
|
89
|
+
res.json({ ok: true });
|
|
90
|
+
}));
|
|
91
|
+
router.delete('/:name', (0, async_route_1.asyncRoute)(async (req, res) => {
|
|
92
|
+
await deploy.remove(req.remote, req.params.name);
|
|
93
|
+
res.json({ ok: true });
|
|
94
|
+
}));
|
|
95
|
+
/** Pulls the latest commit, reinstalls, rebuilds, and recreates the process. */
|
|
96
|
+
router.post('/:name/redeploy', (0, async_route_1.asyncRoute)(async (req, res) => {
|
|
97
|
+
const id = await deploy.requeueJob(req.remote, req.session.id, req.params.name, 'deploy');
|
|
98
|
+
if (!id) {
|
|
99
|
+
res.status(400).json({
|
|
100
|
+
error: 'No previous deploy found for this site — deploy it again from the create form.',
|
|
101
|
+
});
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
res.status(201).json({ id });
|
|
105
|
+
}));
|
|
106
|
+
/** Rebuilds against the existing clone and restarts in place — no pull. */
|
|
107
|
+
router.post('/:name/rebuild', (0, async_route_1.asyncRoute)(async (req, res) => {
|
|
108
|
+
const id = await deploy.requeueJob(req.remote, req.session.id, req.params.name, 'rebuild');
|
|
109
|
+
if (!id) {
|
|
110
|
+
res.status(400).json({
|
|
111
|
+
error: 'No previous deploy found for this site — deploy it again from the create form.',
|
|
112
|
+
});
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
res.status(201).json({ id });
|
|
116
|
+
}));
|
|
117
|
+
router.get('/:name/history', (0, async_route_1.asyncRoute)(async (req, res) => {
|
|
118
|
+
res.json(deploy.deploymentHistory(req.params.name));
|
|
119
|
+
}));
|
|
120
|
+
router.get('/:name/env', (0, async_route_1.asyncRoute)(async (req, res) => {
|
|
121
|
+
const content = await deploy.readEnv(req.remote, req.params.name);
|
|
122
|
+
res.json({ content });
|
|
123
|
+
}));
|
|
124
|
+
router.put('/:name/env', (req, res, next) => {
|
|
125
|
+
deploy
|
|
126
|
+
.writeEnv(req.remote, req.params.name, String(req.body?.content ?? ''))
|
|
127
|
+
.then(() => res.json({ ok: true }))
|
|
128
|
+
.catch((error) => {
|
|
129
|
+
// Missing/undeployed project is a client error, not a server failure.
|
|
130
|
+
if (/has not been deployed|Invalid project name/.test(error.message)) {
|
|
131
|
+
res.status(400).json({ error: error.message });
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
next(error);
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
});
|
|
138
|
+
/** Live tail of a deployed site's own pm2 or Docker log. */
|
|
139
|
+
router.get('/:name/logs/stream', (req, res) => {
|
|
140
|
+
res.writeHead(200, {
|
|
141
|
+
'Content-Type': 'text/event-stream',
|
|
142
|
+
'Cache-Control': 'no-cache',
|
|
143
|
+
Connection: 'keep-alive',
|
|
144
|
+
});
|
|
145
|
+
const send = (event, data) => {
|
|
146
|
+
res.write(`event: ${event}\ndata: ${JSON.stringify(data)}\n\n`);
|
|
147
|
+
};
|
|
148
|
+
const cancel = deploy.logStream(req.remote, req.params.name, {
|
|
149
|
+
onOutput: (line) => send('log', line),
|
|
150
|
+
onDone: () => {
|
|
151
|
+
send('done', 'ok');
|
|
152
|
+
res.end();
|
|
153
|
+
},
|
|
154
|
+
onError: (message) => {
|
|
155
|
+
send('failed', message);
|
|
156
|
+
res.end();
|
|
157
|
+
},
|
|
158
|
+
});
|
|
159
|
+
req.on('close', cancel);
|
|
160
|
+
});
|
|
161
|
+
exports.default = router;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
const express_1 = require("express");
|
|
37
|
+
const domain = __importStar(require("../services/domain"));
|
|
38
|
+
const async_route_1 = require("./async-route");
|
|
39
|
+
const router = (0, express_1.Router)();
|
|
40
|
+
router.get('/', (0, async_route_1.asyncRoute)(async (req, res) => {
|
|
41
|
+
res.json(await domain.list(req.remote));
|
|
42
|
+
}));
|
|
43
|
+
router.post('/', (0, async_route_1.asyncRoute)(async (req, res) => {
|
|
44
|
+
res.status(201).json(await domain.addDomain(req.remote, req.body));
|
|
45
|
+
}));
|
|
46
|
+
router.delete('/:domain', (0, async_route_1.asyncRoute)(async (req, res) => {
|
|
47
|
+
await domain.removeDomain(req.remote, req.params.domain);
|
|
48
|
+
res.json({ ok: true });
|
|
49
|
+
}));
|
|
50
|
+
router.post('/:domain/ssl', (0, async_route_1.asyncRoute)(async (req, res) => {
|
|
51
|
+
await domain.issueCertificate(req.remote, req.params.domain);
|
|
52
|
+
res.json({ ok: true });
|
|
53
|
+
}));
|
|
54
|
+
exports.default = router;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
const express_1 = require("express");
|
|
37
|
+
const async_route_1 = require("./async-route");
|
|
38
|
+
const firewall = __importStar(require("../services/firewall"));
|
|
39
|
+
const router = (0, express_1.Router)();
|
|
40
|
+
router.get('/status', (0, async_route_1.asyncRoute)(async (req, res) => {
|
|
41
|
+
res.json(await firewall.getStatus(req.remote));
|
|
42
|
+
}));
|
|
43
|
+
router.post('/rules', (0, async_route_1.asyncRoute)(async (req, res) => {
|
|
44
|
+
const port = Number(req.body?.port);
|
|
45
|
+
const protocol = req.body?.protocol === 'udp' ? 'udp' : 'tcp';
|
|
46
|
+
await firewall.allowPort(req.remote, port, protocol);
|
|
47
|
+
res.json({ ok: true });
|
|
48
|
+
}));
|
|
49
|
+
router.delete('/rules/:number', (0, async_route_1.asyncRoute)(async (req, res) => {
|
|
50
|
+
const number = Number(req.params.number);
|
|
51
|
+
await firewall.deleteRule(req.remote, number);
|
|
52
|
+
res.json({ ok: true });
|
|
53
|
+
}));
|
|
54
|
+
router.post('/state', (0, async_route_1.asyncRoute)(async (req, res) => {
|
|
55
|
+
if (req.body?.enabled) {
|
|
56
|
+
await firewall.enableFirewall(req.remote);
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
await firewall.disableFirewall(req.remote);
|
|
60
|
+
}
|
|
61
|
+
res.json({ ok: true });
|
|
62
|
+
}));
|
|
63
|
+
exports.default = router;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
const express_1 = require("express");
|
|
37
|
+
const instances = __importStar(require("../services/instances"));
|
|
38
|
+
const async_route_1 = require("./async-route");
|
|
39
|
+
const router = (0, express_1.Router)();
|
|
40
|
+
router.get('/', (0, async_route_1.asyncRoute)(async (req, res) => {
|
|
41
|
+
res.json(await instances.list(req.remote));
|
|
42
|
+
}));
|
|
43
|
+
router.post('/:name/restart', (0, async_route_1.asyncRoute)(async (req, res) => {
|
|
44
|
+
await instances.restart(req.remote, req.params.name);
|
|
45
|
+
res.json({ ok: true });
|
|
46
|
+
}));
|
|
47
|
+
router.post('/:name/stop', (0, async_route_1.asyncRoute)(async (req, res) => {
|
|
48
|
+
await instances.stop(req.remote, req.params.name);
|
|
49
|
+
res.json({ ok: true });
|
|
50
|
+
}));
|
|
51
|
+
router.delete('/:name', (0, async_route_1.asyncRoute)(async (req, res) => {
|
|
52
|
+
await instances.remove(req.remote, req.params.name);
|
|
53
|
+
res.json({ ok: true });
|
|
54
|
+
}));
|
|
55
|
+
router.get('/:name/logs/stream', (req, res) => {
|
|
56
|
+
res.writeHead(200, {
|
|
57
|
+
'Content-Type': 'text/event-stream',
|
|
58
|
+
'Cache-Control': 'no-cache',
|
|
59
|
+
Connection: 'keep-alive',
|
|
60
|
+
});
|
|
61
|
+
const send = (event, data) => {
|
|
62
|
+
res.write(`event: ${event}\ndata: ${JSON.stringify(data)}\n\n`);
|
|
63
|
+
};
|
|
64
|
+
const cancel = instances.logStream(req.remote, req.params.name, {
|
|
65
|
+
onOutput: (line) => send('log', line),
|
|
66
|
+
onDone: () => {
|
|
67
|
+
send('done', 'ok');
|
|
68
|
+
res.end();
|
|
69
|
+
},
|
|
70
|
+
onError: (message) => {
|
|
71
|
+
send('failed', message);
|
|
72
|
+
res.end();
|
|
73
|
+
},
|
|
74
|
+
});
|
|
75
|
+
req.on('close', cancel);
|
|
76
|
+
});
|
|
77
|
+
exports.default = router;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
const express_1 = require("express");
|
|
37
|
+
const logs = __importStar(require("../services/logs"));
|
|
38
|
+
const router = (0, express_1.Router)();
|
|
39
|
+
/** SSE stream of runtime logs for the given source. */
|
|
40
|
+
router.get('/:sourceId/stream', (req, res) => {
|
|
41
|
+
const { sourceId } = req.params;
|
|
42
|
+
if (!logs.isValidSource(sourceId)) {
|
|
43
|
+
res.status(400).json({ error: `Unknown log source: ${sourceId}` });
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
res.writeHead(200, {
|
|
47
|
+
'Content-Type': 'text/event-stream',
|
|
48
|
+
'Cache-Control': 'no-cache',
|
|
49
|
+
Connection: 'keep-alive',
|
|
50
|
+
});
|
|
51
|
+
const send = (event, data) => {
|
|
52
|
+
res.write(`event: ${event}\ndata: ${JSON.stringify(data)}\n\n`);
|
|
53
|
+
};
|
|
54
|
+
const cancel = logs.stream(req.remote, sourceId, {
|
|
55
|
+
onOutput: (line) => send('log', line),
|
|
56
|
+
onDone: () => {
|
|
57
|
+
send('done', 'ok');
|
|
58
|
+
res.end();
|
|
59
|
+
},
|
|
60
|
+
onError: (message) => {
|
|
61
|
+
send('failed', message);
|
|
62
|
+
res.end();
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
req.on('close', cancel);
|
|
66
|
+
});
|
|
67
|
+
exports.default = router;
|