cdd-cli 3.1.2 → 3.1.3
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/AUDIT_REPORT.md +1004 -0
- package/CHANGELOG.md +22 -0
- package/FIXES_APPLIED.md +421 -0
- package/dist/App.js +7 -9
- package/dist/components/ContainerCreationPrompt.js +1 -1
- package/dist/components/ContainerList.js +2 -4
- package/dist/components/ContainerRow.js +20 -14
- package/dist/components/ContainerSection.js +1 -1
- package/dist/helpers/actionHelpers.js +14 -1
- package/dist/helpers/dockerService/dockerService.js +6 -3
- package/dist/helpers/dockerService/serviceComponents/containerActions.js +60 -10
- package/dist/helpers/dockerService/serviceComponents/containerList.js +7 -2
- package/dist/helpers/dockerService/serviceComponents/containerLogs.js +33 -20
- package/dist/helpers/dockerService/serviceComponents/containerStats.js +12 -3
- package/dist/helpers/dockerService/serviceComponents/imageUtils.js +12 -0
- package/dist/helpers/exitWithMessage.js +11 -0
- package/dist/helpers/validationHelpers.js +15 -2
- package/dist/hooks/creation/useContainerCreation.js +2 -6
- package/dist/hooks/useContainers.js +1 -3
- package/dist/hooks/useControls.js +27 -2
- package/dist/hooks/useLogsStream.js +6 -0
- package/dist/index.js +1 -4
- package/package.json +1 -1
- package/src/components/ContainerRow.jsx +17 -5
- package/src/helpers/actionHelpers.js +1 -1
- package/src/helpers/dockerService/dockerService.js +7 -1
- package/src/helpers/dockerService/serviceComponents/containerActions.js +25 -9
- package/src/helpers/dockerService/serviceComponents/containerList.js +1 -1
- package/src/helpers/dockerService/serviceComponents/containerLogs.js +19 -15
- package/src/helpers/dockerService/serviceComponents/containerStats.js +9 -1
- package/src/helpers/validationHelpers.js +14 -2
- package/src/hooks/creation/useContainerCreation.js +2 -6
- package/src/hooks/useControls.js +5 -1
- package/test/validationHelpers.test.js +32 -0
|
@@ -15,7 +15,15 @@ export async function getStats(containerId) {
|
|
|
15
15
|
stream.precpu_stats.cpu_usage.total_usage;
|
|
16
16
|
const systemDelta =
|
|
17
17
|
stream.cpu_stats.system_cpu_usage - stream.precpu_stats.system_cpu_usage;
|
|
18
|
-
|
|
18
|
+
|
|
19
|
+
// Get number of CPUs for proper normalization
|
|
20
|
+
const numCpus = stream.cpu_stats.online_cpus ||
|
|
21
|
+
stream.cpu_stats.cpu_usage.percpu_usage?.length || 1;
|
|
22
|
+
|
|
23
|
+
// Calculate normalized CPU percentage
|
|
24
|
+
const cpuPercent = systemDelta > 0
|
|
25
|
+
? ((cpuDelta / systemDelta) * numCpus * 100)
|
|
26
|
+
: 0;
|
|
19
27
|
|
|
20
28
|
const memUsage = stream.memory_stats.usage || 0;
|
|
21
29
|
const memLimit = stream.memory_stats.limit || 1;
|
|
@@ -11,6 +11,18 @@ export function validatePorts(portInput) {
|
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
export function validateEnvVars(envInput) {
|
|
14
|
-
//
|
|
15
|
-
|
|
14
|
+
if (!envInput || !envInput.trim()) return true; // Empty is valid
|
|
15
|
+
|
|
16
|
+
const vars = envInput.split(",").map(v => v.trim()).filter(Boolean);
|
|
17
|
+
const invalid = vars.find(v => {
|
|
18
|
+
const parts = v.split("=");
|
|
19
|
+
// Must have at least VAR=value format
|
|
20
|
+
if (parts.length < 2) return true;
|
|
21
|
+
const varName = parts[0].trim();
|
|
22
|
+
// Variable names should be alphanumeric with underscores
|
|
23
|
+
if (!/^[A-Z_][A-Z0-9_]*$/i.test(varName)) return true;
|
|
24
|
+
return false;
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
return !invalid;
|
|
16
28
|
}
|
|
@@ -42,12 +42,8 @@ export function useContainerCreation({ onCreate, onCancel, dbImages = [] }) {
|
|
|
42
42
|
return;
|
|
43
43
|
}
|
|
44
44
|
if (step === 2) {
|
|
45
|
-
if
|
|
46
|
-
|
|
47
|
-
setMessageColor("red");
|
|
48
|
-
return;
|
|
49
|
-
}
|
|
50
|
-
if (!validatePorts(portInput)) {
|
|
45
|
+
// Ports are now optional - only validate if provided
|
|
46
|
+
if (portInput.trim() && !validatePorts(portInput)) {
|
|
51
47
|
setMessage("Port format must be host:container and both must be numbers (e.g. 8080:80)");
|
|
52
48
|
setMessageColor("red");
|
|
53
49
|
return;
|
package/src/hooks/useControls.js
CHANGED
|
@@ -200,7 +200,11 @@ export function useControls(containers = []) {
|
|
|
200
200
|
logsViewer.openLogs();
|
|
201
201
|
getLogsStream(
|
|
202
202
|
containers[selected].id,
|
|
203
|
-
(data) => logsViewer.setLogs((prev) =>
|
|
203
|
+
(data) => logsViewer.setLogs((prev) => {
|
|
204
|
+
const newLogs = [...prev, ...data.split("\n").filter(Boolean)];
|
|
205
|
+
// Limit to last 1000 lines to prevent memory leak
|
|
206
|
+
return newLogs.slice(-1000);
|
|
207
|
+
}),
|
|
204
208
|
() => {},
|
|
205
209
|
(err) => logsViewer.setLogs((prev) => [...prev, `Error: ${err.message}`])
|
|
206
210
|
);
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
let validatePorts;
|
|
2
|
+
let validateEnvVars;
|
|
2
3
|
|
|
3
4
|
beforeAll(async () => {
|
|
4
5
|
const mod = await import('../src/helpers/validationHelpers.js');
|
|
5
6
|
validatePorts = mod.validatePorts;
|
|
7
|
+
validateEnvVars = mod.validateEnvVars;
|
|
6
8
|
});
|
|
7
9
|
|
|
8
10
|
describe('validatePorts', () => {
|
|
@@ -26,3 +28,33 @@ describe('validatePorts', () => {
|
|
|
26
28
|
expect(validatePorts('')).toBe(false);
|
|
27
29
|
});
|
|
28
30
|
});
|
|
31
|
+
|
|
32
|
+
describe('validateEnvVars', () => {
|
|
33
|
+
test('empty input is valid', () => {
|
|
34
|
+
expect(validateEnvVars('')).toBe(true);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
test('valid single env var', () => {
|
|
38
|
+
expect(validateEnvVars('NODE_ENV=production')).toBe(true);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
test('valid multiple env vars', () => {
|
|
42
|
+
expect(validateEnvVars('NODE_ENV=production,PORT=3000')).toBe(true);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
test('valid env var with underscores', () => {
|
|
46
|
+
expect(validateEnvVars('MY_VAR_NAME=value')).toBe(true);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
test('invalid env var without equals sign', () => {
|
|
50
|
+
expect(validateEnvVars('NOEQUALS')).toBe(false);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
test('invalid env var with invalid name', () => {
|
|
54
|
+
expect(validateEnvVars('123INVALID=value')).toBe(false);
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
test('invalid env var with special characters in name', () => {
|
|
58
|
+
expect(validateEnvVars('MY-VAR=value')).toBe(false);
|
|
59
|
+
});
|
|
60
|
+
});
|