ctx-sync 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/audit.d.ts +76 -0
- package/dist/commands/audit.d.ts.map +1 -0
- package/dist/commands/audit.js +367 -0
- package/dist/commands/audit.js.map +1 -0
- package/dist/commands/config.d.ts +58 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +114 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/dir.d.ts +56 -0
- package/dist/commands/dir.d.ts.map +1 -0
- package/dist/commands/dir.js +172 -0
- package/dist/commands/dir.js.map +1 -0
- package/dist/commands/docker.d.ts +140 -0
- package/dist/commands/docker.d.ts.map +1 -0
- package/dist/commands/docker.js +380 -0
- package/dist/commands/docker.js.map +1 -0
- package/dist/commands/env.d.ts +96 -0
- package/dist/commands/env.d.ts.map +1 -0
- package/dist/commands/env.js +352 -0
- package/dist/commands/env.js.map +1 -0
- package/dist/commands/init.d.ts +89 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +272 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/key.d.ts +92 -0
- package/dist/commands/key.d.ts.map +1 -0
- package/dist/commands/key.js +274 -0
- package/dist/commands/key.js.map +1 -0
- package/dist/commands/list.d.ts +38 -0
- package/dist/commands/list.d.ts.map +1 -0
- package/dist/commands/list.js +84 -0
- package/dist/commands/list.js.map +1 -0
- package/dist/commands/note.d.ts +151 -0
- package/dist/commands/note.d.ts.map +1 -0
- package/dist/commands/note.js +411 -0
- package/dist/commands/note.js.map +1 -0
- package/dist/commands/pull.d.ts +47 -0
- package/dist/commands/pull.d.ts.map +1 -0
- package/dist/commands/pull.js +94 -0
- package/dist/commands/pull.js.map +1 -0
- package/dist/commands/push.d.ts +40 -0
- package/dist/commands/push.d.ts.map +1 -0
- package/dist/commands/push.js +94 -0
- package/dist/commands/push.js.map +1 -0
- package/dist/commands/restore.d.ts +116 -0
- package/dist/commands/restore.d.ts.map +1 -0
- package/dist/commands/restore.js +336 -0
- package/dist/commands/restore.js.map +1 -0
- package/dist/commands/service.d.ts +83 -0
- package/dist/commands/service.d.ts.map +1 -0
- package/dist/commands/service.js +259 -0
- package/dist/commands/service.js.map +1 -0
- package/dist/commands/show.d.ts +63 -0
- package/dist/commands/show.d.ts.map +1 -0
- package/dist/commands/show.js +243 -0
- package/dist/commands/show.js.map +1 -0
- package/dist/commands/status.d.ts +53 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +150 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/sync.d.ts +105 -0
- package/dist/commands/sync.d.ts.map +1 -0
- package/dist/commands/sync.js +243 -0
- package/dist/commands/sync.js.map +1 -0
- package/dist/commands/team.d.ts +79 -0
- package/dist/commands/team.d.ts.map +1 -0
- package/dist/commands/team.js +233 -0
- package/dist/commands/team.js.map +1 -0
- package/dist/commands/track.d.ts +109 -0
- package/dist/commands/track.d.ts.map +1 -0
- package/dist/commands/track.js +406 -0
- package/dist/commands/track.js.map +1 -0
- package/dist/core/command-validator.d.ts +100 -0
- package/dist/core/command-validator.d.ts.map +1 -0
- package/dist/core/command-validator.js +299 -0
- package/dist/core/command-validator.js.map +1 -0
- package/dist/core/config-store.d.ts +76 -0
- package/dist/core/config-store.d.ts.map +1 -0
- package/dist/core/config-store.js +148 -0
- package/dist/core/config-store.js.map +1 -0
- package/dist/core/directories-handler.d.ts +116 -0
- package/dist/core/directories-handler.d.ts.map +1 -0
- package/dist/core/directories-handler.js +199 -0
- package/dist/core/directories-handler.js.map +1 -0
- package/dist/core/docker-handler.d.ts +183 -0
- package/dist/core/docker-handler.d.ts.map +1 -0
- package/dist/core/docker-handler.js +515 -0
- package/dist/core/docker-handler.js.map +1 -0
- package/dist/core/encryption.d.ts +79 -0
- package/dist/core/encryption.d.ts.map +1 -0
- package/dist/core/encryption.js +111 -0
- package/dist/core/encryption.js.map +1 -0
- package/dist/core/env-handler.d.ts +128 -0
- package/dist/core/env-handler.d.ts.map +1 -0
- package/dist/core/env-handler.js +272 -0
- package/dist/core/env-handler.js.map +1 -0
- package/dist/core/git-sync.d.ts +88 -0
- package/dist/core/git-sync.d.ts.map +1 -0
- package/dist/core/git-sync.js +143 -0
- package/dist/core/git-sync.js.map +1 -0
- package/dist/core/key-store.d.ts +51 -0
- package/dist/core/key-store.d.ts.map +1 -0
- package/dist/core/key-store.js +108 -0
- package/dist/core/key-store.js.map +1 -0
- package/dist/core/log-sanitizer.d.ts +72 -0
- package/dist/core/log-sanitizer.d.ts.map +1 -0
- package/dist/core/log-sanitizer.js +202 -0
- package/dist/core/log-sanitizer.js.map +1 -0
- package/dist/core/path-validator.d.ts +37 -0
- package/dist/core/path-validator.d.ts.map +1 -0
- package/dist/core/path-validator.js +127 -0
- package/dist/core/path-validator.js.map +1 -0
- package/dist/core/recipients.d.ts +99 -0
- package/dist/core/recipients.d.ts.map +1 -0
- package/dist/core/recipients.js +206 -0
- package/dist/core/recipients.js.map +1 -0
- package/dist/core/services-handler.d.ts +113 -0
- package/dist/core/services-handler.d.ts.map +1 -0
- package/dist/core/services-handler.js +176 -0
- package/dist/core/services-handler.js.map +1 -0
- package/dist/core/state-manager.d.ts +96 -0
- package/dist/core/state-manager.d.ts.map +1 -0
- package/dist/core/state-manager.js +165 -0
- package/dist/core/state-manager.js.map +1 -0
- package/dist/core/transport.d.ts +28 -0
- package/dist/core/transport.d.ts.map +1 -0
- package/dist/core/transport.js +79 -0
- package/dist/core/transport.js.map +1 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +80 -0
- package/dist/index.js.map +1 -0
- package/dist/types/index.d.ts +5 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/errors.d.ts +81 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +191 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/secure-memory.d.ts +65 -0
- package/dist/utils/secure-memory.d.ts.map +1 -0
- package/dist/utils/secure-memory.js +86 -0
- package/dist/utils/secure-memory.js.map +1 -0
- package/package.json +58 -0
|
@@ -0,0 +1,515 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Docker handler module.
|
|
3
|
+
*
|
|
4
|
+
* Detects Docker Compose files, parses their service definitions,
|
|
5
|
+
* queries Docker for running container state, and saves/loads
|
|
6
|
+
* encrypted Docker state.
|
|
7
|
+
*
|
|
8
|
+
* **Graceful degradation:** If Docker is not installed or compose files
|
|
9
|
+
* are missing, the module returns empty/null results rather than throwing.
|
|
10
|
+
*
|
|
11
|
+
* @module core/docker-handler
|
|
12
|
+
*/
|
|
13
|
+
import * as fs from 'node:fs';
|
|
14
|
+
import * as path from 'node:path';
|
|
15
|
+
import { execSync } from 'node:child_process';
|
|
16
|
+
import { readState, writeState } from './state-manager.js';
|
|
17
|
+
/**
|
|
18
|
+
* Known Docker Compose file names (in priority order).
|
|
19
|
+
*/
|
|
20
|
+
export const COMPOSE_FILE_NAMES = [
|
|
21
|
+
'docker-compose.yml',
|
|
22
|
+
'docker-compose.yaml',
|
|
23
|
+
'compose.yml',
|
|
24
|
+
'compose.yaml',
|
|
25
|
+
];
|
|
26
|
+
/**
|
|
27
|
+
* Detect a Docker Compose file in the given project directory.
|
|
28
|
+
*
|
|
29
|
+
* Searches for known compose file names in priority order. Does not
|
|
30
|
+
* throw if none is found — returns `found: false`.
|
|
31
|
+
*
|
|
32
|
+
* @param projectDir - Absolute path to the project directory.
|
|
33
|
+
* @returns Detection result with file path if found.
|
|
34
|
+
*/
|
|
35
|
+
export function detectDockerCompose(projectDir) {
|
|
36
|
+
for (const fileName of COMPOSE_FILE_NAMES) {
|
|
37
|
+
const filePath = path.join(projectDir, fileName);
|
|
38
|
+
if (fs.existsSync(filePath)) {
|
|
39
|
+
return {
|
|
40
|
+
found: true,
|
|
41
|
+
filePath,
|
|
42
|
+
fileName,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return {
|
|
47
|
+
found: false,
|
|
48
|
+
filePath: null,
|
|
49
|
+
fileName: null,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Parse a Docker Compose file and extract service definitions.
|
|
54
|
+
*
|
|
55
|
+
* Uses a simple YAML parser (line-based) to extract services, ports,
|
|
56
|
+
* images, volumes, and networks without requiring a full YAML library.
|
|
57
|
+
* This handles common compose file patterns.
|
|
58
|
+
*
|
|
59
|
+
* @param filePath - Absolute path to the compose file.
|
|
60
|
+
* @returns Parsed services and networks.
|
|
61
|
+
* @throws If the file cannot be read.
|
|
62
|
+
*/
|
|
63
|
+
export function parseComposeFile(filePath) {
|
|
64
|
+
if (!fs.existsSync(filePath)) {
|
|
65
|
+
throw new Error(`Compose file not found: ${filePath}`);
|
|
66
|
+
}
|
|
67
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
68
|
+
return parseComposeContent(content);
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Parse Docker Compose YAML content.
|
|
72
|
+
*
|
|
73
|
+
* Simple line-based parser that handles common compose file patterns.
|
|
74
|
+
* Extracts service name, image, container_name, ports, volumes,
|
|
75
|
+
* healthcheck, and top-level networks.
|
|
76
|
+
*
|
|
77
|
+
* @param content - The raw YAML content.
|
|
78
|
+
* @returns Parsed services and networks.
|
|
79
|
+
*/
|
|
80
|
+
export function parseComposeContent(content) {
|
|
81
|
+
const lines = content.split('\n');
|
|
82
|
+
const services = [];
|
|
83
|
+
const networks = [];
|
|
84
|
+
let inServices = false;
|
|
85
|
+
let inNetworks = false;
|
|
86
|
+
let currentService = null;
|
|
87
|
+
let currentServiceName = null;
|
|
88
|
+
let inPorts = false;
|
|
89
|
+
let inVolumes = false;
|
|
90
|
+
let inHealthcheck = false;
|
|
91
|
+
let servicesIndent = -1;
|
|
92
|
+
let serviceIndent = -1;
|
|
93
|
+
for (const rawLine of lines) {
|
|
94
|
+
// Skip comments and empty lines
|
|
95
|
+
const commentIdx = rawLine.indexOf('#');
|
|
96
|
+
const line = commentIdx >= 0 ? rawLine.slice(0, commentIdx) : rawLine;
|
|
97
|
+
if (line.trim() === '')
|
|
98
|
+
continue;
|
|
99
|
+
const indent = line.length - line.trimStart().length;
|
|
100
|
+
const trimmed = line.trim();
|
|
101
|
+
// Top-level section detection
|
|
102
|
+
if (indent === 0) {
|
|
103
|
+
// Flush current service before switching sections
|
|
104
|
+
if (currentService && currentServiceName) {
|
|
105
|
+
services.push(finalizeService(currentServiceName, currentService));
|
|
106
|
+
currentService = null;
|
|
107
|
+
currentServiceName = null;
|
|
108
|
+
}
|
|
109
|
+
inPorts = false;
|
|
110
|
+
inVolumes = false;
|
|
111
|
+
inHealthcheck = false;
|
|
112
|
+
if (trimmed === 'services:' || trimmed.startsWith('services:')) {
|
|
113
|
+
inServices = true;
|
|
114
|
+
inNetworks = false;
|
|
115
|
+
servicesIndent = 0;
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
118
|
+
else if (trimmed === 'networks:' || trimmed.startsWith('networks:')) {
|
|
119
|
+
inServices = false;
|
|
120
|
+
inNetworks = true;
|
|
121
|
+
continue;
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
inServices = false;
|
|
125
|
+
inNetworks = false;
|
|
126
|
+
continue;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
// Parse networks section
|
|
130
|
+
if (inNetworks && indent > 0) {
|
|
131
|
+
// Network names are keys at the first indent level
|
|
132
|
+
if (trimmed.endsWith(':') && !trimmed.includes(' ')) {
|
|
133
|
+
networks.push(trimmed.slice(0, -1));
|
|
134
|
+
}
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
// Parse services section
|
|
138
|
+
if (inServices) {
|
|
139
|
+
// Detect a new service (one level deeper than 'services:')
|
|
140
|
+
if (indent > servicesIndent &&
|
|
141
|
+
(serviceIndent === -1 || indent <= serviceIndent) &&
|
|
142
|
+
trimmed.endsWith(':') &&
|
|
143
|
+
!trimmed.includes(' ')) {
|
|
144
|
+
// Flush previous service
|
|
145
|
+
if (currentService && currentServiceName) {
|
|
146
|
+
services.push(finalizeService(currentServiceName, currentService));
|
|
147
|
+
}
|
|
148
|
+
currentServiceName = trimmed.slice(0, -1);
|
|
149
|
+
currentService = {
|
|
150
|
+
volumes: [],
|
|
151
|
+
};
|
|
152
|
+
serviceIndent = indent;
|
|
153
|
+
inPorts = false;
|
|
154
|
+
inVolumes = false;
|
|
155
|
+
inHealthcheck = false;
|
|
156
|
+
continue;
|
|
157
|
+
}
|
|
158
|
+
if (!currentService)
|
|
159
|
+
continue;
|
|
160
|
+
// Within a service definition
|
|
161
|
+
if (indent > serviceIndent) {
|
|
162
|
+
// Check if we're ending a list context
|
|
163
|
+
if (!trimmed.startsWith('-') && !trimmed.startsWith('#')) {
|
|
164
|
+
if (inPorts && !trimmed.startsWith('-')) {
|
|
165
|
+
inPorts = false;
|
|
166
|
+
}
|
|
167
|
+
if (inVolumes && !trimmed.startsWith('-')) {
|
|
168
|
+
inVolumes = false;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
// Parse ports list items
|
|
172
|
+
if (inPorts && trimmed.startsWith('-')) {
|
|
173
|
+
const portMapping = trimmed.slice(1).trim().replace(/['"]/g, '');
|
|
174
|
+
const hostPort = parseHostPort(portMapping);
|
|
175
|
+
if (hostPort > 0 && !currentService.port) {
|
|
176
|
+
currentService.port = hostPort;
|
|
177
|
+
}
|
|
178
|
+
continue;
|
|
179
|
+
}
|
|
180
|
+
// Parse volumes list items
|
|
181
|
+
if (inVolumes && trimmed.startsWith('-')) {
|
|
182
|
+
const volume = trimmed.slice(1).trim().replace(/['"]/g, '');
|
|
183
|
+
if (volume) {
|
|
184
|
+
currentService.volumes = currentService.volumes ?? [];
|
|
185
|
+
currentService.volumes.push(volume);
|
|
186
|
+
}
|
|
187
|
+
continue;
|
|
188
|
+
}
|
|
189
|
+
// Parse healthcheck test
|
|
190
|
+
if (inHealthcheck) {
|
|
191
|
+
if (trimmed.startsWith('test:')) {
|
|
192
|
+
const testValue = trimmed.slice(5).trim();
|
|
193
|
+
if (testValue) {
|
|
194
|
+
// Could be inline array: ["CMD", "pg_isready"] or a string
|
|
195
|
+
currentService.healthCheck = parseHealthcheckValue(testValue);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
else if (trimmed.startsWith('-') && !currentService.healthCheck) {
|
|
199
|
+
// Array form (multi-line): take the command part (skip CMD or CMD-SHELL)
|
|
200
|
+
const item = trimmed.slice(1).trim().replace(/['"]/g, '');
|
|
201
|
+
if (item !== 'CMD' && item !== 'CMD-SHELL') {
|
|
202
|
+
currentService.healthCheck = item;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
// Stay in healthcheck context until we get to a key at the service indent level
|
|
206
|
+
const nextKeyMatch = trimmed.match(/^[a-z_]+:/i);
|
|
207
|
+
if (nextKeyMatch &&
|
|
208
|
+
!trimmed.startsWith('test:') &&
|
|
209
|
+
!trimmed.startsWith('interval:') &&
|
|
210
|
+
!trimmed.startsWith('timeout:') &&
|
|
211
|
+
!trimmed.startsWith('retries:') &&
|
|
212
|
+
!trimmed.startsWith('start_period:')) {
|
|
213
|
+
inHealthcheck = false;
|
|
214
|
+
}
|
|
215
|
+
else {
|
|
216
|
+
continue;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
// Parse key-value pairs
|
|
220
|
+
if (trimmed.startsWith('image:')) {
|
|
221
|
+
currentService.image = cleanYamlValue(trimmed.slice(6));
|
|
222
|
+
}
|
|
223
|
+
else if (trimmed.startsWith('container_name:')) {
|
|
224
|
+
currentService.container = cleanYamlValue(trimmed.slice(15));
|
|
225
|
+
}
|
|
226
|
+
else if (trimmed.startsWith('ports:')) {
|
|
227
|
+
inPorts = true;
|
|
228
|
+
// Handle inline ports: ["5432:5432"]
|
|
229
|
+
const inlineValue = trimmed.slice(6).trim();
|
|
230
|
+
if (inlineValue) {
|
|
231
|
+
const ports = parseInlineList(inlineValue);
|
|
232
|
+
for (const portMapping of ports) {
|
|
233
|
+
const hostPort = parseHostPort(portMapping);
|
|
234
|
+
if (hostPort > 0 && !currentService.port) {
|
|
235
|
+
currentService.port = hostPort;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
inPorts = false;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
else if (trimmed.startsWith('volumes:')) {
|
|
242
|
+
inVolumes = true;
|
|
243
|
+
// Handle inline volumes
|
|
244
|
+
const inlineValue = trimmed.slice(8).trim();
|
|
245
|
+
if (inlineValue) {
|
|
246
|
+
const vols = parseInlineList(inlineValue);
|
|
247
|
+
currentService.volumes = currentService.volumes ?? [];
|
|
248
|
+
currentService.volumes.push(...vols);
|
|
249
|
+
inVolumes = false;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
else if (trimmed.startsWith('healthcheck:')) {
|
|
253
|
+
inHealthcheck = true;
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
// Flush the last service
|
|
259
|
+
if (currentService && currentServiceName) {
|
|
260
|
+
services.push(finalizeService(currentServiceName, currentService));
|
|
261
|
+
}
|
|
262
|
+
return { services, networks };
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Clean a YAML value: strip quotes and whitespace.
|
|
266
|
+
*/
|
|
267
|
+
function cleanYamlValue(raw) {
|
|
268
|
+
return raw.trim().replace(/^['"]|['"]$/g, '');
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* Parse a healthcheck test value.
|
|
272
|
+
*
|
|
273
|
+
* Handles:
|
|
274
|
+
* - Inline array: `["CMD", "pg_isready"]` → `pg_isready`
|
|
275
|
+
* - Inline array: `["CMD-SHELL", "curl -f http://localhost:3000/health || exit 1"]` → `curl ...`
|
|
276
|
+
* - Plain string: `curl -f http://localhost/health || exit 1` → as-is
|
|
277
|
+
*/
|
|
278
|
+
function parseHealthcheckValue(raw) {
|
|
279
|
+
const trimmed = raw.trim();
|
|
280
|
+
// Inline array form: ["CMD", "pg_isready"] or ["CMD-SHELL", "..."]
|
|
281
|
+
if (trimmed.startsWith('[') && trimmed.endsWith(']')) {
|
|
282
|
+
const items = trimmed
|
|
283
|
+
.slice(1, -1)
|
|
284
|
+
.split(',')
|
|
285
|
+
.map((s) => s.trim().replace(/^['"]|['"]$/g, ''));
|
|
286
|
+
// Filter out CMD / CMD-SHELL and return the rest joined
|
|
287
|
+
const commandParts = items.filter((item) => item !== 'CMD' && item !== 'CMD-SHELL');
|
|
288
|
+
return commandParts.join(' ').trim() || trimmed;
|
|
289
|
+
}
|
|
290
|
+
return cleanYamlValue(trimmed);
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* Parse an inline YAML list like ["a", "b"] or [a, b].
|
|
294
|
+
*/
|
|
295
|
+
function parseInlineList(raw) {
|
|
296
|
+
const trimmed = raw.trim();
|
|
297
|
+
if (trimmed.startsWith('[') && trimmed.endsWith(']')) {
|
|
298
|
+
return trimmed
|
|
299
|
+
.slice(1, -1)
|
|
300
|
+
.split(',')
|
|
301
|
+
.map((s) => s.trim().replace(/^['"]|['"]$/g, ''))
|
|
302
|
+
.filter(Boolean);
|
|
303
|
+
}
|
|
304
|
+
return [];
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* Parse a host port from a port mapping string.
|
|
308
|
+
*
|
|
309
|
+
* Handles formats like:
|
|
310
|
+
* - "5432:5432"
|
|
311
|
+
* - "5432:5432/tcp"
|
|
312
|
+
* - "0.0.0.0:5432:5432"
|
|
313
|
+
* - "8080:80"
|
|
314
|
+
*
|
|
315
|
+
* Returns the **host** port (left side).
|
|
316
|
+
*/
|
|
317
|
+
export function parseHostPort(mapping) {
|
|
318
|
+
const clean = mapping.replace(/\/\w+$/, '').trim(); // Remove /tcp, /udp suffix
|
|
319
|
+
const parts = clean.split(':');
|
|
320
|
+
if (parts.length === 0)
|
|
321
|
+
return 0;
|
|
322
|
+
// "5432:5432" or "8080:80" → host port is parts[0]
|
|
323
|
+
// "0.0.0.0:5432:5432" → host port is parts[1]
|
|
324
|
+
if (parts.length === 3) {
|
|
325
|
+
return parseInt(parts[1] ?? '0', 10) || 0;
|
|
326
|
+
}
|
|
327
|
+
if (parts.length === 2) {
|
|
328
|
+
return parseInt(parts[0] ?? '0', 10) || 0;
|
|
329
|
+
}
|
|
330
|
+
if (parts.length === 1) {
|
|
331
|
+
return parseInt(parts[0] ?? '0', 10) || 0;
|
|
332
|
+
}
|
|
333
|
+
return 0;
|
|
334
|
+
}
|
|
335
|
+
/**
|
|
336
|
+
* Finalize a partially parsed service into a full ParsedService.
|
|
337
|
+
*/
|
|
338
|
+
function finalizeService(name, partial) {
|
|
339
|
+
return {
|
|
340
|
+
name,
|
|
341
|
+
image: partial.image ?? '',
|
|
342
|
+
container: partial.container ?? `${name}`,
|
|
343
|
+
port: partial.port ?? 0,
|
|
344
|
+
volumes: partial.volumes ?? [],
|
|
345
|
+
healthCheck: partial.healthCheck,
|
|
346
|
+
};
|
|
347
|
+
}
|
|
348
|
+
/**
|
|
349
|
+
* Check if Docker is available on this machine.
|
|
350
|
+
*
|
|
351
|
+
* @returns `true` if `docker` CLI is installed and responds to `docker info`.
|
|
352
|
+
*/
|
|
353
|
+
export function isDockerAvailable() {
|
|
354
|
+
try {
|
|
355
|
+
execSync('docker info', { stdio: 'pipe', timeout: 5000 });
|
|
356
|
+
return true;
|
|
357
|
+
}
|
|
358
|
+
catch {
|
|
359
|
+
return false;
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
/**
|
|
363
|
+
* Get running containers for a project directory.
|
|
364
|
+
*
|
|
365
|
+
* Uses `docker compose ps` to query running containers related to
|
|
366
|
+
* the compose file in the given directory.
|
|
367
|
+
*
|
|
368
|
+
* @param projectDir - Absolute path to the project directory.
|
|
369
|
+
* @returns List of running containers, or empty array if Docker is not available.
|
|
370
|
+
*/
|
|
371
|
+
export function getRunningContainers(projectDir) {
|
|
372
|
+
if (!isDockerAvailable()) {
|
|
373
|
+
return [];
|
|
374
|
+
}
|
|
375
|
+
const compose = detectDockerCompose(projectDir);
|
|
376
|
+
if (!compose.found) {
|
|
377
|
+
return [];
|
|
378
|
+
}
|
|
379
|
+
try {
|
|
380
|
+
const output = execSync('docker compose ps --format json', {
|
|
381
|
+
cwd: projectDir,
|
|
382
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
383
|
+
timeout: 10000,
|
|
384
|
+
}).toString();
|
|
385
|
+
if (!output.trim()) {
|
|
386
|
+
return [];
|
|
387
|
+
}
|
|
388
|
+
// docker compose ps --format json outputs one JSON object per line
|
|
389
|
+
const containers = [];
|
|
390
|
+
for (const line of output.trim().split('\n')) {
|
|
391
|
+
const trimmedLine = line.trim();
|
|
392
|
+
if (!trimmedLine)
|
|
393
|
+
continue;
|
|
394
|
+
try {
|
|
395
|
+
const entry = JSON.parse(trimmedLine);
|
|
396
|
+
containers.push({
|
|
397
|
+
id: entry['ID'] ?? '',
|
|
398
|
+
name: entry['Name'] ?? '',
|
|
399
|
+
image: entry['Image'] ?? '',
|
|
400
|
+
status: entry['Status'] ?? '',
|
|
401
|
+
ports: entry['Ports'] ?? entry['Publishers'] ?? '',
|
|
402
|
+
});
|
|
403
|
+
}
|
|
404
|
+
catch {
|
|
405
|
+
// Skip malformed lines
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
return containers;
|
|
409
|
+
}
|
|
410
|
+
catch {
|
|
411
|
+
return [];
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
/**
|
|
415
|
+
* Build a DockerState entry for a project from its compose file.
|
|
416
|
+
*
|
|
417
|
+
* Detects the compose file, parses it, and creates a DockerState entry
|
|
418
|
+
* suitable for encryption and storage.
|
|
419
|
+
*
|
|
420
|
+
* @param projectName - The project name (key in the DockerState map).
|
|
421
|
+
* @param projectDir - Absolute path to the project directory.
|
|
422
|
+
* @param autoStartDefault - Default value for autoStart on each service.
|
|
423
|
+
* @returns The project's Docker state entry, or `null` if no compose file found.
|
|
424
|
+
*/
|
|
425
|
+
export function buildDockerStateEntry(projectName, projectDir, autoStartDefault = true) {
|
|
426
|
+
const compose = detectDockerCompose(projectDir);
|
|
427
|
+
if (!compose.found || !compose.filePath) {
|
|
428
|
+
return null;
|
|
429
|
+
}
|
|
430
|
+
const parsed = parseComposeFile(compose.filePath);
|
|
431
|
+
const services = parsed.services.map((svc) => ({
|
|
432
|
+
name: svc.name,
|
|
433
|
+
container: svc.container,
|
|
434
|
+
image: svc.image,
|
|
435
|
+
port: svc.port,
|
|
436
|
+
volumes: svc.volumes.length > 0 ? svc.volumes : undefined,
|
|
437
|
+
autoStart: autoStartDefault,
|
|
438
|
+
healthCheck: svc.healthCheck,
|
|
439
|
+
}));
|
|
440
|
+
return {
|
|
441
|
+
composeFile: compose.filePath,
|
|
442
|
+
services,
|
|
443
|
+
networks: parsed.networks.length > 0 ? parsed.networks : undefined,
|
|
444
|
+
lastStarted: undefined,
|
|
445
|
+
};
|
|
446
|
+
}
|
|
447
|
+
/**
|
|
448
|
+
* Save Docker state for a project to encrypted storage.
|
|
449
|
+
*
|
|
450
|
+
* Reads existing Docker state, merges the new project entry, and
|
|
451
|
+
* writes the updated state to `docker-state.age`.
|
|
452
|
+
*
|
|
453
|
+
* @param syncDir - The sync directory path.
|
|
454
|
+
* @param projectName - The project name (key in DockerState).
|
|
455
|
+
* @param entry - The Docker state entry for the project.
|
|
456
|
+
* @param publicKey - The Age public key for encryption.
|
|
457
|
+
* @param privateKey - The Age private key for reading existing state.
|
|
458
|
+
*/
|
|
459
|
+
export async function saveDockerState(syncDir, projectName, entry, publicKey, privateKey) {
|
|
460
|
+
// Read existing state
|
|
461
|
+
const existing = await readState(syncDir, privateKey, 'docker-state');
|
|
462
|
+
const dockerState = existing ?? {};
|
|
463
|
+
// Merge the new entry
|
|
464
|
+
dockerState[projectName] = entry;
|
|
465
|
+
// Write encrypted state
|
|
466
|
+
await writeState(syncDir, dockerState, publicKey, 'docker-state');
|
|
467
|
+
}
|
|
468
|
+
/**
|
|
469
|
+
* Load Docker state for a specific project from encrypted storage.
|
|
470
|
+
*
|
|
471
|
+
* @param syncDir - The sync directory path.
|
|
472
|
+
* @param projectName - The project name.
|
|
473
|
+
* @param privateKey - The Age private key for decryption.
|
|
474
|
+
* @returns The project's Docker state, or `null` if not found.
|
|
475
|
+
*/
|
|
476
|
+
export async function loadDockerState(syncDir, projectName, privateKey) {
|
|
477
|
+
const dockerState = await readState(syncDir, privateKey, 'docker-state');
|
|
478
|
+
if (!dockerState)
|
|
479
|
+
return null;
|
|
480
|
+
return dockerState[projectName] ?? null;
|
|
481
|
+
}
|
|
482
|
+
/**
|
|
483
|
+
* Load all Docker state from encrypted storage.
|
|
484
|
+
*
|
|
485
|
+
* @param syncDir - The sync directory path.
|
|
486
|
+
* @param privateKey - The Age private key for decryption.
|
|
487
|
+
* @returns Full Docker state, or `null` if no docker-state.age exists.
|
|
488
|
+
*/
|
|
489
|
+
export async function loadAllDockerState(syncDir, privateKey) {
|
|
490
|
+
return readState(syncDir, privateKey, 'docker-state');
|
|
491
|
+
}
|
|
492
|
+
/**
|
|
493
|
+
* Remove Docker state for a project from encrypted storage.
|
|
494
|
+
*
|
|
495
|
+
* @param syncDir - The sync directory path.
|
|
496
|
+
* @param projectName - The project name to remove.
|
|
497
|
+
* @param publicKey - The Age public key for re-encryption.
|
|
498
|
+
* @param privateKey - The Age private key for decryption.
|
|
499
|
+
* @returns `true` if the project was found and removed.
|
|
500
|
+
*/
|
|
501
|
+
export async function removeDockerState(syncDir, projectName, publicKey, privateKey) {
|
|
502
|
+
const dockerState = await readState(syncDir, privateKey, 'docker-state');
|
|
503
|
+
if (!dockerState || !(projectName in dockerState)) {
|
|
504
|
+
return false;
|
|
505
|
+
}
|
|
506
|
+
const updated = {};
|
|
507
|
+
for (const [key, value] of Object.entries(dockerState)) {
|
|
508
|
+
if (key !== projectName) {
|
|
509
|
+
updated[key] = value;
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
await writeState(syncDir, updated, publicKey, 'docker-state');
|
|
513
|
+
return true;
|
|
514
|
+
}
|
|
515
|
+
//# sourceMappingURL=docker-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"docker-handler.js","sourceRoot":"","sources":["../../src/core/docker-handler.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Age encryption wrapper module.
|
|
3
|
+
*
|
|
4
|
+
* Provides key generation, encryption, and decryption operations
|
|
5
|
+
* using the Age encryption library. All operations are in-memory only —
|
|
6
|
+
* no temporary files are created during crypto operations.
|
|
7
|
+
*
|
|
8
|
+
* @module core/encryption
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Generate a new Age key pair.
|
|
12
|
+
*
|
|
13
|
+
* @returns Object containing the public key (age1...) and private key (AGE-SECRET-KEY-...).
|
|
14
|
+
*/
|
|
15
|
+
export declare function generateKey(): Promise<{
|
|
16
|
+
publicKey: string;
|
|
17
|
+
privateKey: string;
|
|
18
|
+
}>;
|
|
19
|
+
/**
|
|
20
|
+
* Encrypt a plaintext string with an Age public key.
|
|
21
|
+
*
|
|
22
|
+
* @param plaintext - The string to encrypt.
|
|
23
|
+
* @param publicKey - The Age public key (age1...) to encrypt for.
|
|
24
|
+
* @returns ASCII-armored Age ciphertext.
|
|
25
|
+
* @throws If the public key is invalid.
|
|
26
|
+
*/
|
|
27
|
+
export declare function encrypt(plaintext: string, publicKey: string): Promise<string>;
|
|
28
|
+
/**
|
|
29
|
+
* Decrypt an ASCII-armored Age ciphertext with a private key.
|
|
30
|
+
*
|
|
31
|
+
* @param ciphertext - The ASCII-armored Age ciphertext.
|
|
32
|
+
* @param privateKey - The Age private key (AGE-SECRET-KEY-...).
|
|
33
|
+
* @returns The decrypted plaintext string.
|
|
34
|
+
* @throws If the private key cannot decrypt the ciphertext.
|
|
35
|
+
*/
|
|
36
|
+
export declare function decrypt(ciphertext: string, privateKey: string): Promise<string>;
|
|
37
|
+
/**
|
|
38
|
+
* Encrypt a typed data object as JSON into an Age ciphertext blob.
|
|
39
|
+
* The data is serialised to JSON in memory, then encrypted.
|
|
40
|
+
* No plaintext JSON is ever written to disk.
|
|
41
|
+
*
|
|
42
|
+
* @param data - The data to encrypt.
|
|
43
|
+
* @param publicKey - The Age public key to encrypt for.
|
|
44
|
+
* @returns ASCII-armored Age ciphertext containing the serialised JSON.
|
|
45
|
+
*/
|
|
46
|
+
export declare function encryptState<T>(data: T, publicKey: string): Promise<string>;
|
|
47
|
+
/**
|
|
48
|
+
* Decrypt an Age ciphertext blob and parse the JSON back into a typed object.
|
|
49
|
+
*
|
|
50
|
+
* @param ciphertext - The ASCII-armored Age ciphertext.
|
|
51
|
+
* @param privateKey - The Age private key.
|
|
52
|
+
* @returns The decrypted and parsed data.
|
|
53
|
+
* @throws If decryption fails or the JSON is invalid.
|
|
54
|
+
*/
|
|
55
|
+
export declare function decryptState<T>(ciphertext: string, privateKey: string): Promise<T>;
|
|
56
|
+
/**
|
|
57
|
+
* Encrypt a plaintext string for multiple Age recipients.
|
|
58
|
+
*
|
|
59
|
+
* All recipients can independently decrypt the resulting ciphertext
|
|
60
|
+
* using their own private key. This enables team/multi-machine support.
|
|
61
|
+
*
|
|
62
|
+
* @param plaintext - The string to encrypt.
|
|
63
|
+
* @param publicKeys - Array of Age public keys (age1...) to encrypt for.
|
|
64
|
+
* @returns ASCII-armored Age ciphertext.
|
|
65
|
+
* @throws If any public key is invalid or the array is empty.
|
|
66
|
+
*/
|
|
67
|
+
export declare function encryptForRecipients(plaintext: string, publicKeys: string[]): Promise<string>;
|
|
68
|
+
/**
|
|
69
|
+
* Encrypt a typed data object as JSON for multiple Age recipients.
|
|
70
|
+
*
|
|
71
|
+
* Serialises the data to JSON in memory, then encrypts for all recipients.
|
|
72
|
+
* No plaintext JSON is ever written to disk.
|
|
73
|
+
*
|
|
74
|
+
* @param data - The data to encrypt.
|
|
75
|
+
* @param publicKeys - Array of Age public keys to encrypt for.
|
|
76
|
+
* @returns ASCII-armored Age ciphertext containing the serialised JSON.
|
|
77
|
+
*/
|
|
78
|
+
export declare function encryptStateForRecipients<T>(data: T, publicKeys: string[]): Promise<string>;
|
|
79
|
+
//# sourceMappingURL=encryption.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"encryption.d.ts","sourceRoot":"","sources":["../../src/core/encryption.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAKH;;;;GAIG;AACH,wBAAsB,WAAW,IAAI,OAAO,CAAC;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC,CAItF;AAED;;;;;;;GAOG;AACH,wBAAsB,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAKnF;AAED;;;;;;;GAOG;AACH,wBAAsB,OAAO,CAAC,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAKrF;AAED;;;;;;;;GAQG;AACH,wBAAsB,YAAY,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAGjF;AAED;;;;;;;GAOG;AACH,wBAAsB,YAAY,CAAC,CAAC,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAGxF;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,oBAAoB,CACxC,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAAE,GACnB,OAAO,CAAC,MAAM,CAAC,CAWjB;AAED;;;;;;;;;GASG;AACH,wBAAsB,yBAAyB,CAAC,CAAC,EAC/C,IAAI,EAAE,CAAC,EACP,UAAU,EAAE,MAAM,EAAE,GACnB,OAAO,CAAC,MAAM,CAAC,CAGjB"}
|