cdd-cli 3.1.7 → 3.1.9
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/.eslintrc.json +1 -1
- package/.github/workflows/ci.yml +3 -0
- package/.github/workflows/docs.yml +8 -1
- package/CHANGELOG.md +23 -0
- package/CONTRIBUTING.md +28 -15
- package/README.md +56 -88
- package/babel.config.cjs +18 -1
- package/dist/components/ContainerRow.js +5 -78
- package/dist/components/LogViewer.js +4 -9
- package/dist/helpers/containerOptionsBuilder.js +58 -0
- package/dist/hooks/creation/useContainerCreation.js +16 -1
- package/dist/hooks/debug/useDebugLogs.js +46 -0
- package/dist/hooks/navigation/useContainerSelection.js +36 -0
- package/dist/hooks/useContainerCommandRouter.js +151 -0
- package/dist/{helpers/actionHelpers.js → hooks/useContainerStats.js} +76 -78
- package/dist/hooks/useControls.js +83 -342
- package/dist/hooks/useEraseConfirmation.js +47 -0
- package/dist/hooks/useExitHandler.js +68 -0
- package/jest.config.cjs +1 -1
- package/package.json +2 -3
- package/src/components/ContainerRow.jsx +3 -38
- package/src/components/LogViewer.jsx +4 -10
- package/src/helpers/containerOptionsBuilder.js +42 -0
- package/src/hooks/creation/useContainerCreation.js +15 -0
- package/src/hooks/debug/useDebugLogs.js +29 -0
- package/src/hooks/navigation/useContainerSelection.js +25 -0
- package/src/hooks/useContainerCommandRouter.js +110 -0
- package/src/hooks/useContainerStats.js +44 -0
- package/src/hooks/useControls.js +68 -272
- package/src/hooks/useEraseConfirmation.js +39 -0
- package/src/hooks/useExitHandler.js +66 -0
- package/test/useContainerCreation.dom.test.js +3 -0
- package/.babelrc +0 -6
- package/FIXES_APPLIED.md +0 -419
- package/SECURITY.md +0 -5
- package/dist/hooks/useLogsStream.js +0 -41
- package/docs/_config.yml +0 -13
- package/docs/components_ContainerCreationPrompt.jsx.html +0 -114
- package/docs/components_ContainerRow.jsx.html +0 -151
- package/docs/components_ContainerSection.jsx.html +0 -75
- package/docs/components_Footer.jsx.html +0 -66
- package/docs/components_Header.jsx.html +0 -84
- package/docs/components_LogViewer.jsx.html +0 -91
- package/docs/components_MessageFeedback.jsx.html +0 -76
- package/docs/components_PromptField.jsx.html +0 -99
- package/docs/components_StatsBar.jsx.html +0 -105
- package/docs/components_UsageMenu.jsx.html +0 -73
- package/docs/fonts/OpenSans-Bold-webfont.eot +0 -0
- package/docs/fonts/OpenSans-Bold-webfont.svg +0 -1830
- package/docs/fonts/OpenSans-Bold-webfont.woff +0 -0
- package/docs/fonts/OpenSans-BoldItalic-webfont.eot +0 -0
- package/docs/fonts/OpenSans-BoldItalic-webfont.svg +0 -1830
- package/docs/fonts/OpenSans-BoldItalic-webfont.woff +0 -0
- package/docs/fonts/OpenSans-Italic-webfont.eot +0 -0
- package/docs/fonts/OpenSans-Italic-webfont.svg +0 -1830
- package/docs/fonts/OpenSans-Italic-webfont.woff +0 -0
- package/docs/fonts/OpenSans-Light-webfont.eot +0 -0
- package/docs/fonts/OpenSans-Light-webfont.svg +0 -1831
- package/docs/fonts/OpenSans-Light-webfont.woff +0 -0
- package/docs/fonts/OpenSans-LightItalic-webfont.eot +0 -0
- package/docs/fonts/OpenSans-LightItalic-webfont.svg +0 -1835
- package/docs/fonts/OpenSans-LightItalic-webfont.woff +0 -0
- package/docs/fonts/OpenSans-Regular-webfont.eot +0 -0
- package/docs/fonts/OpenSans-Regular-webfont.svg +0 -1831
- package/docs/fonts/OpenSans-Regular-webfont.woff +0 -0
- package/docs/global.html +0 -6145
- package/docs/helpers_actionHelpers.js.html +0 -94
- package/docs/helpers_constants.js.html +0 -81
- package/docs/helpers_dockerService_dockerService.js.html +0 -79
- package/docs/helpers_dockerService_serviceComponents_containerActions.js.html +0 -153
- package/docs/helpers_dockerService_serviceComponents_containerList.js.html +0 -81
- package/docs/helpers_dockerService_serviceComponents_containerLogs.js.html +0 -85
- package/docs/helpers_dockerService_serviceComponents_containerStats.js.html +0 -107
- package/docs/helpers_dockerService_serviceComponents_imageUtils.js.html +0 -82
- package/docs/helpers_exitWithMessage.js.html +0 -77
- package/docs/helpers_safeCall.js.html +0 -68
- package/docs/helpers_validationHelpers.js.html +0 -96
- package/docs/hooks_creation_useContainerActions.js.html +0 -120
- package/docs/hooks_creation_useContainerCreation.js.html +0 -152
- package/docs/hooks_creation_useLogsViewer.js.html +0 -102
- package/docs/hooks_useControls.js.html +0 -298
- package/docs/hooks_useLogsStream.js.html +0 -82
- package/docs/index.html +0 -65
- package/docs/index.js.html +0 -65
- package/docs/module-index.html +0 -171
- package/docs/scripts/linenumber.js +0 -25
- package/docs/scripts/prettify/Apache-License-2.0.txt +0 -202
- package/docs/scripts/prettify/lang-css.js +0 -2
- package/docs/scripts/prettify/prettify.js +0 -28
- package/docs/styles/jsdoc-default.css +0 -358
- package/docs/styles/prettify-jsdoc.css +0 -111
- package/docs/styles/prettify-tomorrow.css +0 -132
- package/esbuild.config.cjs +0 -11
- package/src/helpers/actionHelpers.js +0 -52
- package/src/hooks/useLogsStream.js +0 -31
- package/test/actionHelpers.test.js +0 -106
|
@@ -1,152 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="utf-8">
|
|
5
|
-
<title>JSDoc: Source: hooks/creation/useContainerCreation.js</title>
|
|
6
|
-
|
|
7
|
-
<script src="scripts/prettify/prettify.js"> </script>
|
|
8
|
-
<script src="scripts/prettify/lang-css.js"> </script>
|
|
9
|
-
<!--[if lt IE 9]>
|
|
10
|
-
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
|
|
11
|
-
<![endif]-->
|
|
12
|
-
<link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
|
|
13
|
-
<link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
|
|
14
|
-
</head>
|
|
15
|
-
|
|
16
|
-
<body>
|
|
17
|
-
|
|
18
|
-
<div id="main">
|
|
19
|
-
|
|
20
|
-
<h1 class="page-title">Source: hooks/creation/useContainerCreation.js</h1>
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
<section>
|
|
28
|
-
<article>
|
|
29
|
-
<pre class="prettyprint source linenums"><code>import { useState } from "react";
|
|
30
|
-
import { validatePorts } from "../../helpers/validationHelpers.js";
|
|
31
|
-
import { safeCall } from "../../helpers/safeCall";
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Custom hook to manage the container creation flow, step by step.
|
|
35
|
-
* Handles input, validation, and feedback for each creation step.
|
|
36
|
-
*
|
|
37
|
-
* @param {Object} params
|
|
38
|
-
* @param {Function} params.onCreate - Callback when creation is confirmed
|
|
39
|
-
* @param {Function} params.onCancel - Callback when creation is cancelled
|
|
40
|
-
* @param {Array<string>} params.dbImages - List of DB image names for env var warning
|
|
41
|
-
* @returns {Object} Creation state, setters, and helpers
|
|
42
|
-
*/
|
|
43
|
-
export function useContainerCreation({ onCreate, onCancel, dbImages = [] }) {
|
|
44
|
-
const [step, setStep] = useState(0); // 0: image, 1: name, 2: ports, 3: env
|
|
45
|
-
const [imageName, setImageName] = useState("");
|
|
46
|
-
const [containerName, setContainerName] = useState("");
|
|
47
|
-
const [portInput, setPortInput] = useState("");
|
|
48
|
-
const [envInput, setEnvInput] = useState("");
|
|
49
|
-
const [message, setMessage] = useState("");
|
|
50
|
-
const [messageColor, setMessageColor] = useState("yellow");
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* Advances to the next step, with validation and feedback.
|
|
54
|
-
*/
|
|
55
|
-
function nextStep() {
|
|
56
|
-
if (step === 0) {
|
|
57
|
-
if (!imageName.trim()) {
|
|
58
|
-
setMessage("Image name cannot be empty.");
|
|
59
|
-
setMessageColor("red");
|
|
60
|
-
return;
|
|
61
|
-
}
|
|
62
|
-
setStep(1);
|
|
63
|
-
setMessage("Optional: Enter container name or leave empty and press Enter");
|
|
64
|
-
setMessageColor("yellow");
|
|
65
|
-
return;
|
|
66
|
-
}
|
|
67
|
-
if (step === 1) {
|
|
68
|
-
setStep(2);
|
|
69
|
-
setMessage("Optional: Enter ports (format 8080:80,443:443) or leave empty and press Enter");
|
|
70
|
-
setMessageColor("yellow");
|
|
71
|
-
return;
|
|
72
|
-
}
|
|
73
|
-
if (step === 2) {
|
|
74
|
-
// Ports are now optional - only validate if provided
|
|
75
|
-
if (portInput.trim() && !validatePorts(portInput)) {
|
|
76
|
-
setMessage("Port format must be host:container and both must be numbers (e.g. 8080:80)");
|
|
77
|
-
setMessageColor("red");
|
|
78
|
-
return;
|
|
79
|
-
}
|
|
80
|
-
setStep(3);
|
|
81
|
-
const isDb = dbImages.some(db => imageName.trim().toLowerCase().includes(db));
|
|
82
|
-
if (isDb) {
|
|
83
|
-
setMessage("Warning: This image usually requires environment variables (e.g. MYSQL_ROOT_PASSWORD=my-secret-pw for MySQL, POSTGRES_PASSWORD=yourpassword for Postgres). Enter them as VAR=val,VAR2=val2 or leave empty and press Enter.");
|
|
84
|
-
setMessageColor("yellow");
|
|
85
|
-
} else {
|
|
86
|
-
setMessage("Optional: Enter environment variables (format VAR1=val1,VAR2=val2) or leave empty and press Enter");
|
|
87
|
-
setMessageColor("yellow");
|
|
88
|
-
}
|
|
89
|
-
return;
|
|
90
|
-
}
|
|
91
|
-
if (step === 3) {
|
|
92
|
-
// Final step: call onCreate with all data (safely)
|
|
93
|
-
safeCall(onCreate, { imageName, containerName, portInput, envInput });
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* Cancels the creation process and resets state.
|
|
99
|
-
*/
|
|
100
|
-
function cancelCreation() {
|
|
101
|
-
setStep(0);
|
|
102
|
-
setImageName("");
|
|
103
|
-
setContainerName("");
|
|
104
|
-
setPortInput("");
|
|
105
|
-
setEnvInput("");
|
|
106
|
-
setMessage("");
|
|
107
|
-
setMessageColor("yellow");
|
|
108
|
-
safeCall(onCancel);
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
return {
|
|
112
|
-
step,
|
|
113
|
-
setStep,
|
|
114
|
-
imageName,
|
|
115
|
-
setImageName,
|
|
116
|
-
containerName,
|
|
117
|
-
setContainerName,
|
|
118
|
-
portInput,
|
|
119
|
-
setPortInput,
|
|
120
|
-
envInput,
|
|
121
|
-
setEnvInput,
|
|
122
|
-
message,
|
|
123
|
-
setMessage,
|
|
124
|
-
messageColor,
|
|
125
|
-
setMessageColor,
|
|
126
|
-
nextStep,
|
|
127
|
-
cancelCreation,
|
|
128
|
-
};
|
|
129
|
-
}
|
|
130
|
-
</code></pre>
|
|
131
|
-
</article>
|
|
132
|
-
</section>
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
</div>
|
|
138
|
-
|
|
139
|
-
<nav>
|
|
140
|
-
<h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-index.html">index</a></li></ul><h3>Global</h3><ul><li><a href="global.html#EXIT_DELAY">EXIT_DELAY</a></li><li><a href="global.html#MESSAGE_TIMEOUTS">MESSAGE_TIMEOUTS</a></li><li><a href="global.html#PromptField">PromptField</a></li><li><a href="global.html#PromptMessage">PromptMessage</a></li><li><a href="global.html#REFRESH_INTERVALS">REFRESH_INTERVALS</a></li><li><a href="global.html#TIMEOUTS">TIMEOUTS</a></li><li><a href="global.html#colorize">colorize</a></li><li><a href="global.html#createContainer">createContainer</a></li><li><a href="global.html#docker">docker</a></li><li><a href="global.html#exitWithMessage">exitWithMessage</a></li><li><a href="global.html#getContainers">getContainers</a></li><li><a href="global.html#getLogsStream">getLogsStream</a></li><li><a href="global.html#getStats">getStats</a></li><li><a href="global.html#handleAction">handleAction</a></li><li><a href="global.html#imageExists">imageExists</a></li><li><a href="global.html#makeBar">makeBar</a></li><li><a href="global.html#pullImage">pullImage</a></li><li><a href="global.html#removeContainer">removeContainer</a></li><li><a href="global.html#restartContainer">restartContainer</a></li><li><a href="global.html#safeCall">safeCall</a></li><li><a href="global.html#startContainer">startContainer</a></li><li><a href="global.html#stopContainer">stopContainer</a></li><li><a href="global.html#useContainerActions">useContainerActions</a></li><li><a href="global.html#useContainerCreation">useContainerCreation</a></li><li><a href="global.html#useControls">useControls</a></li><li><a href="global.html#useLogsStream">useLogsStream</a></li><li><a href="global.html#useLogsViewer">useLogsViewer</a></li><li><a href="global.html#validateEnvVars">validateEnvVars</a></li><li><a href="global.html#validatePorts">validatePorts</a></li><li><a href="global.html#withTimeout">withTimeout</a></li></ul>
|
|
141
|
-
</nav>
|
|
142
|
-
|
|
143
|
-
<br class="clear">
|
|
144
|
-
|
|
145
|
-
<footer>
|
|
146
|
-
Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.5</a> on Fri Oct 17 2025 16:07:18 GMT-0500 (hora estándar de Colombia)
|
|
147
|
-
</footer>
|
|
148
|
-
|
|
149
|
-
<script> prettyPrint(); </script>
|
|
150
|
-
<script src="scripts/linenumber.js"> </script>
|
|
151
|
-
</body>
|
|
152
|
-
</html>
|
|
@@ -1,102 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="utf-8">
|
|
5
|
-
<title>JSDoc: Source: hooks/creation/useLogsViewer.js</title>
|
|
6
|
-
|
|
7
|
-
<script src="scripts/prettify/prettify.js"> </script>
|
|
8
|
-
<script src="scripts/prettify/lang-css.js"> </script>
|
|
9
|
-
<!--[if lt IE 9]>
|
|
10
|
-
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
|
|
11
|
-
<![endif]-->
|
|
12
|
-
<link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
|
|
13
|
-
<link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
|
|
14
|
-
</head>
|
|
15
|
-
|
|
16
|
-
<body>
|
|
17
|
-
|
|
18
|
-
<div id="main">
|
|
19
|
-
|
|
20
|
-
<h1 class="page-title">Source: hooks/creation/useLogsViewer.js</h1>
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
<section>
|
|
28
|
-
<article>
|
|
29
|
-
<pre class="prettyprint source linenums"><code>import { useState, useRef } from "react";
|
|
30
|
-
import { safeCall } from "../../helpers/safeCall";
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Custom hook to manage the logs viewer state and stream reference.
|
|
34
|
-
* Handles showing/hiding logs and storing log lines.
|
|
35
|
-
*
|
|
36
|
-
* @returns {Object} Logs viewer state and helpers
|
|
37
|
-
* @property {boolean} showLogs - Whether the logs viewer is open
|
|
38
|
-
* @property {function} setShowLogs - Setter for showLogs
|
|
39
|
-
* @property {Array<string>} logs - Array of log lines
|
|
40
|
-
* @property {function} setLogs - Setter for logs
|
|
41
|
-
* @property {object} logsStreamRef - Ref to the logs stream (for cleanup)
|
|
42
|
-
* @property {function} openLogs - Helper to open logs for a container
|
|
43
|
-
* @property {function} closeLogs - Helper to close logs and cleanup
|
|
44
|
-
*/
|
|
45
|
-
export function useLogsViewer() {
|
|
46
|
-
const [showLogs, setShowLogs] = useState(false);
|
|
47
|
-
const [logs, setLogs] = useState([]);
|
|
48
|
-
const logsStreamRef = useRef(null);
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* Opens the logs viewer and resets logs.
|
|
52
|
-
*/
|
|
53
|
-
function openLogs() {
|
|
54
|
-
setShowLogs(true);
|
|
55
|
-
setLogs([]);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Closes the logs viewer and cleans up the stream.
|
|
60
|
-
*/
|
|
61
|
-
function closeLogs() {
|
|
62
|
-
setShowLogs(false);
|
|
63
|
-
setLogs([]);
|
|
64
|
-
if (logsStreamRef.current) {
|
|
65
|
-
safeCall(logsStreamRef.current.destroy?.bind(logsStreamRef.current));
|
|
66
|
-
logsStreamRef.current = null;
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
return {
|
|
71
|
-
showLogs,
|
|
72
|
-
setShowLogs,
|
|
73
|
-
logs,
|
|
74
|
-
setLogs,
|
|
75
|
-
logsStreamRef,
|
|
76
|
-
openLogs,
|
|
77
|
-
closeLogs,
|
|
78
|
-
};
|
|
79
|
-
}
|
|
80
|
-
</code></pre>
|
|
81
|
-
</article>
|
|
82
|
-
</section>
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
</div>
|
|
88
|
-
|
|
89
|
-
<nav>
|
|
90
|
-
<h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-index.html">index</a></li></ul><h3>Global</h3><ul><li><a href="global.html#EXIT_DELAY">EXIT_DELAY</a></li><li><a href="global.html#MESSAGE_TIMEOUTS">MESSAGE_TIMEOUTS</a></li><li><a href="global.html#PromptField">PromptField</a></li><li><a href="global.html#PromptMessage">PromptMessage</a></li><li><a href="global.html#REFRESH_INTERVALS">REFRESH_INTERVALS</a></li><li><a href="global.html#TIMEOUTS">TIMEOUTS</a></li><li><a href="global.html#colorize">colorize</a></li><li><a href="global.html#createContainer">createContainer</a></li><li><a href="global.html#docker">docker</a></li><li><a href="global.html#exitWithMessage">exitWithMessage</a></li><li><a href="global.html#getContainers">getContainers</a></li><li><a href="global.html#getLogsStream">getLogsStream</a></li><li><a href="global.html#getStats">getStats</a></li><li><a href="global.html#handleAction">handleAction</a></li><li><a href="global.html#imageExists">imageExists</a></li><li><a href="global.html#makeBar">makeBar</a></li><li><a href="global.html#pullImage">pullImage</a></li><li><a href="global.html#removeContainer">removeContainer</a></li><li><a href="global.html#restartContainer">restartContainer</a></li><li><a href="global.html#safeCall">safeCall</a></li><li><a href="global.html#startContainer">startContainer</a></li><li><a href="global.html#stopContainer">stopContainer</a></li><li><a href="global.html#useContainerActions">useContainerActions</a></li><li><a href="global.html#useContainerCreation">useContainerCreation</a></li><li><a href="global.html#useControls">useControls</a></li><li><a href="global.html#useLogsStream">useLogsStream</a></li><li><a href="global.html#useLogsViewer">useLogsViewer</a></li><li><a href="global.html#validateEnvVars">validateEnvVars</a></li><li><a href="global.html#validatePorts">validatePorts</a></li><li><a href="global.html#withTimeout">withTimeout</a></li></ul>
|
|
91
|
-
</nav>
|
|
92
|
-
|
|
93
|
-
<br class="clear">
|
|
94
|
-
|
|
95
|
-
<footer>
|
|
96
|
-
Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.5</a> on Fri Oct 17 2025 16:07:18 GMT-0500 (hora estándar de Colombia)
|
|
97
|
-
</footer>
|
|
98
|
-
|
|
99
|
-
<script> prettyPrint(); </script>
|
|
100
|
-
<script src="scripts/linenumber.js"> </script>
|
|
101
|
-
</body>
|
|
102
|
-
</html>
|
|
@@ -1,298 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="utf-8">
|
|
5
|
-
<title>JSDoc: Source: hooks/useControls.js</title>
|
|
6
|
-
|
|
7
|
-
<script src="scripts/prettify/prettify.js"> </script>
|
|
8
|
-
<script src="scripts/prettify/lang-css.js"> </script>
|
|
9
|
-
<!--[if lt IE 9]>
|
|
10
|
-
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
|
|
11
|
-
<![endif]-->
|
|
12
|
-
<link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
|
|
13
|
-
<link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
|
|
14
|
-
</head>
|
|
15
|
-
|
|
16
|
-
<body>
|
|
17
|
-
|
|
18
|
-
<div id="main">
|
|
19
|
-
|
|
20
|
-
<h1 class="page-title">Source: hooks/useControls.js</h1>
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
<section>
|
|
28
|
-
<article>
|
|
29
|
-
<pre class="prettyprint source linenums"><code>import React from "react";
|
|
30
|
-
import { useContainerActions } from "./creation/useContainerActions";
|
|
31
|
-
import { useContainerCreation } from "./creation/useContainerCreation";
|
|
32
|
-
import { useLogsViewer } from "./creation/useLogsViewer";
|
|
33
|
-
import { useInput } from "ink";
|
|
34
|
-
import { getLogsStream } from "../helpers/dockerService/serviceComponents/containerLogs.js";
|
|
35
|
-
import { EXIT_DELAY } from "../helpers/constants";
|
|
36
|
-
import { createContainer as svcCreateContainer } from "../helpers/dockerService/serviceComponents/containerActions.js";
|
|
37
|
-
|
|
38
|
-
// Principal hook to manage user inputs and control the app state
|
|
39
|
-
/**
|
|
40
|
-
* Main hook that wires user input, creation, actions and logs viewing.
|
|
41
|
-
* It coordinates the modular hooks and exposes a compact API consumed by the App.
|
|
42
|
-
*
|
|
43
|
-
* @param {Array<Object>} containers - Current list of Docker containers
|
|
44
|
-
* @returns {Object} controls - API for the App component
|
|
45
|
-
* @property {number} selected - Index of the currently selected container
|
|
46
|
-
* @property {function} setSelected - Setter for selected index
|
|
47
|
-
* @property {string} message - Current feedback message (creation or actions)
|
|
48
|
-
* @property {string} messageColor - Color to show for the feedback message
|
|
49
|
-
* @property {boolean} showLogs - Whether the logs viewer is active
|
|
50
|
-
* @property {Array<string>} logs - Array of log lines currently collected
|
|
51
|
-
* @property {function} exitLogs - Helper to close the logs viewer
|
|
52
|
-
* @property {boolean} creatingContainer - Whether the create-container prompt is open
|
|
53
|
-
* @property {number} creationStep - Current step in the creation flow
|
|
54
|
-
* @property {string} imageNameInput - Current value of the image name field
|
|
55
|
-
* @property {string} containerNameInput - Current value of the container name field
|
|
56
|
-
* @property {string} portInput - Current value of the port input field
|
|
57
|
-
* @property {string} envInput - Current value of the env input field
|
|
58
|
-
* @property {Object} creation - The creation hook API (setters and helpers)
|
|
59
|
-
* @property {Object} actions - The actions hook API (helpers to start/stop/remove)
|
|
60
|
-
* @property {Object} logsViewer - The logs viewer hook API
|
|
61
|
-
*/
|
|
62
|
-
export function useControls(containers = []) {
|
|
63
|
-
const [selected, setSelected] = React.useState(0);
|
|
64
|
-
const [creatingContainer, setCreatingContainer] = React.useState(false);
|
|
65
|
-
const [confirmErase, setConfirmErase] = React.useState(false);
|
|
66
|
-
const total = containers.length;
|
|
67
|
-
|
|
68
|
-
// Modular hooks
|
|
69
|
-
const actions = useContainerActions({ containers });
|
|
70
|
-
const creation = useContainerCreation({
|
|
71
|
-
onCreate: async ({ imageName, containerName, portInput, envInput }) => {
|
|
72
|
-
// Build Docker options
|
|
73
|
-
const env = (envInput || "").split(",").map(s => s.trim()).filter(Boolean);
|
|
74
|
-
const ports = (portInput || "").split(",").map(s => s.trim()).filter(Boolean);
|
|
75
|
-
const ExposedPorts = {};
|
|
76
|
-
const PortBindings = {};
|
|
77
|
-
ports.forEach(pair => {
|
|
78
|
-
const [host, cont] = pair.split(":");
|
|
79
|
-
if (!host || !cont) return;
|
|
80
|
-
const key = `${cont}/tcp`;
|
|
81
|
-
ExposedPorts[key] = {};
|
|
82
|
-
PortBindings[key] = PortBindings[key] || [];
|
|
83
|
-
PortBindings[key].push({ HostPort: `${host}` });
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
const options = {
|
|
87
|
-
Tty: true,
|
|
88
|
-
};
|
|
89
|
-
if (Object.keys(ExposedPorts).length) options.ExposedPorts = ExposedPorts;
|
|
90
|
-
if (Object.keys(PortBindings).length) options.HostConfig = { PortBindings };
|
|
91
|
-
if (env.length) options.Env = env;
|
|
92
|
-
if (containerName) options.name = containerName;
|
|
93
|
-
|
|
94
|
-
actions.setMessage(`Creating container ${imageName}...`);
|
|
95
|
-
actions.setMessageColor("yellow");
|
|
96
|
-
try {
|
|
97
|
-
const id = await svcCreateContainer(imageName, options);
|
|
98
|
-
actions.setMessage(`Created container ${id}`);
|
|
99
|
-
actions.setMessageColor("green");
|
|
100
|
-
} catch (err) {
|
|
101
|
-
actions.setMessage(`Error creating container: ${err.message}`);
|
|
102
|
-
actions.setMessageColor("red");
|
|
103
|
-
} finally {
|
|
104
|
-
setCreatingContainer(false);
|
|
105
|
-
}
|
|
106
|
-
},
|
|
107
|
-
onCancel: () => setCreatingContainer(false),
|
|
108
|
-
dbImages: ["mysql", "mariadb", "postgres", "mongo", "mssql", "redis"]
|
|
109
|
-
});
|
|
110
|
-
const logsViewer = useLogsViewer();
|
|
111
|
-
|
|
112
|
-
// Handler to exit logs (delegated to logsViewer)
|
|
113
|
-
const exitLogs = logsViewer.closeLogs;
|
|
114
|
-
|
|
115
|
-
useInput((input, key) => {
|
|
116
|
-
// Erase confirmation
|
|
117
|
-
if (confirmErase) {
|
|
118
|
-
if (input === "y" || input === "Y") {
|
|
119
|
-
actions.handleAction({
|
|
120
|
-
actionFn: async (id) => await actions.removeContainer(id),
|
|
121
|
-
actionLabel: "Erasing",
|
|
122
|
-
selected,
|
|
123
|
-
});
|
|
124
|
-
setConfirmErase(false);
|
|
125
|
-
actions.setMessageColor("yellow");
|
|
126
|
-
return;
|
|
127
|
-
} else if (input === "n" || input === "N" || key.escape) {
|
|
128
|
-
setConfirmErase(false);
|
|
129
|
-
actions.setMessage("");
|
|
130
|
-
actions.setMessageColor("");
|
|
131
|
-
return;
|
|
132
|
-
} else {
|
|
133
|
-
actions.setMessage("Are you sure you want to erase this container? (y/n)");
|
|
134
|
-
actions.setMessageColor("yellow");
|
|
135
|
-
return;
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
// Logs viewer
|
|
140
|
-
if (logsViewer.showLogs) {
|
|
141
|
-
if (input === "q" || key.escape) {
|
|
142
|
-
logsViewer.closeLogs();
|
|
143
|
-
}
|
|
144
|
-
return;
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
// Container creation flow: delegate input to creation hook
|
|
148
|
-
if (creatingContainer) {
|
|
149
|
-
const step = creation.step;
|
|
150
|
-
const appendCharToField = (setter, value, ch) => {
|
|
151
|
-
setter((value || "") + ch);
|
|
152
|
-
};
|
|
153
|
-
// Escape -> cancel
|
|
154
|
-
if (key.escape) {
|
|
155
|
-
creation.cancelCreation();
|
|
156
|
-
setCreatingContainer(false);
|
|
157
|
-
return;
|
|
158
|
-
}
|
|
159
|
-
// Enter -> next step
|
|
160
|
-
if (input === "\r" || input === "\n") {
|
|
161
|
-
creation.nextStep();
|
|
162
|
-
return;
|
|
163
|
-
}
|
|
164
|
-
// Backspace/Delete support
|
|
165
|
-
if (key.backspace || key.delete) {
|
|
166
|
-
if (step === 0) creation.setImageName((v) => (v || "").slice(0, -1));
|
|
167
|
-
if (step === 1) creation.setContainerName((v) => (v || "").slice(0, -1));
|
|
168
|
-
if (step === 2) creation.setPortInput((v) => (v || "").slice(0, -1));
|
|
169
|
-
if (step === 3) creation.setEnvInput((v) => (v || "").slice(0, -1));
|
|
170
|
-
return;
|
|
171
|
-
}
|
|
172
|
-
// Printable character input (append)
|
|
173
|
-
if (input && input.length === 1 && !key.ctrl && !key.meta) {
|
|
174
|
-
if (step === 0) appendCharToField(creation.setImageName, creation.imageName, input);
|
|
175
|
-
if (step === 1) appendCharToField(creation.setContainerName, creation.containerName, input);
|
|
176
|
-
if (step === 2) appendCharToField(creation.setPortInput, creation.portInput, input);
|
|
177
|
-
if (step === 3) appendCharToField(creation.setEnvInput, creation.envInput, input);
|
|
178
|
-
return;
|
|
179
|
-
}
|
|
180
|
-
// Otherwise ignore
|
|
181
|
-
return;
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
//==========================================================
|
|
185
|
-
// Menu Navigation
|
|
186
|
-
//==========================================================
|
|
187
|
-
if (key.upArrow && total > 0) setSelected((i) => (i === 0 ? total - 1 : i - 1));
|
|
188
|
-
if (key.downArrow && total > 0) setSelected((i) => (i === total - 1 ? 0 : i + 1));
|
|
189
|
-
if (input === "q") {
|
|
190
|
-
actions.setMessage("Exiting...");
|
|
191
|
-
actions.setMessageColor("yellow");
|
|
192
|
-
setTimeout(() => process.exit(0), EXIT_DELAY);
|
|
193
|
-
return;
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
//==========================================================
|
|
197
|
-
// Docker commands
|
|
198
|
-
//==========================================================
|
|
199
|
-
if (input === "i") {
|
|
200
|
-
actions.handleAction({
|
|
201
|
-
actionFn: async (id) => await actions.startContainer(id),
|
|
202
|
-
actionLabel: "Starting",
|
|
203
|
-
selected,
|
|
204
|
-
stateCheck: (c) => (c.state === "running" || c.status === "running") && "Container is already running."
|
|
205
|
-
});
|
|
206
|
-
}
|
|
207
|
-
if (input === "p") {
|
|
208
|
-
actions.handleAction({
|
|
209
|
-
actionFn: async (id) => await actions.stopContainer(id),
|
|
210
|
-
actionLabel: "Stopping",
|
|
211
|
-
selected,
|
|
212
|
-
stateCheck: (c) => (c.state === "exited" || c.status === "exited" || c.state === "stopped" || c.status === "stopped") && "Container is already stopped."
|
|
213
|
-
});
|
|
214
|
-
}
|
|
215
|
-
if (input === "r") {
|
|
216
|
-
actions.handleAction({
|
|
217
|
-
actionFn: async (id) => await actions.restartContainer(id),
|
|
218
|
-
actionLabel: "Restarting",
|
|
219
|
-
selected,
|
|
220
|
-
});
|
|
221
|
-
}
|
|
222
|
-
if (input === "e" && containers[selected]) {
|
|
223
|
-
setConfirmErase(true);
|
|
224
|
-
actions.setMessage("Are you sure you want to erase this container? (y/n)");
|
|
225
|
-
actions.setMessageColor("yellow");
|
|
226
|
-
return;
|
|
227
|
-
}
|
|
228
|
-
if (input === "l" && containers[selected]) {
|
|
229
|
-
logsViewer.openLogs();
|
|
230
|
-
getLogsStream(
|
|
231
|
-
containers[selected].id,
|
|
232
|
-
(data) => logsViewer.setLogs((prev) => {
|
|
233
|
-
const newLogs = [...prev, ...data.split("\n").filter(Boolean)];
|
|
234
|
-
// Limit to last 1000 lines to prevent memory leak
|
|
235
|
-
return newLogs.slice(-1000);
|
|
236
|
-
}),
|
|
237
|
-
() => {},
|
|
238
|
-
(err) => logsViewer.setLogs((prev) => [...prev, `Error: ${err.message}`])
|
|
239
|
-
);
|
|
240
|
-
return;
|
|
241
|
-
}
|
|
242
|
-
if (input === "c") {
|
|
243
|
-
setCreatingContainer(true);
|
|
244
|
-
creation.setStep(0);
|
|
245
|
-
creation.setImageName("");
|
|
246
|
-
creation.setContainerName("");
|
|
247
|
-
creation.setPortInput("");
|
|
248
|
-
creation.setEnvInput("");
|
|
249
|
-
creation.setMessage("Insert the name of the image to create: ");
|
|
250
|
-
creation.setMessageColor("yellow");
|
|
251
|
-
}
|
|
252
|
-
});
|
|
253
|
-
|
|
254
|
-
return {
|
|
255
|
-
selected,
|
|
256
|
-
setSelected,
|
|
257
|
-
// Map messaging to creation when creating, otherwise to actions
|
|
258
|
-
message: creatingContainer ? creation.message : actions.message,
|
|
259
|
-
messageColor: creatingContainer ? creation.messageColor : actions.messageColor,
|
|
260
|
-
showLogs: logsViewer.showLogs,
|
|
261
|
-
logs: logsViewer.logs,
|
|
262
|
-
exitLogs,
|
|
263
|
-
creatingContainer,
|
|
264
|
-
// Expose creation fields in the shape App expects
|
|
265
|
-
creationStep: creation.step,
|
|
266
|
-
imageNameInput: creation.imageName,
|
|
267
|
-
containerNameInput: creation.containerName,
|
|
268
|
-
portInput: creation.portInput,
|
|
269
|
-
envInput: creation.envInput,
|
|
270
|
-
creation,
|
|
271
|
-
actions,
|
|
272
|
-
logsViewer,
|
|
273
|
-
confirmErase,
|
|
274
|
-
};
|
|
275
|
-
}
|
|
276
|
-
</code></pre>
|
|
277
|
-
</article>
|
|
278
|
-
</section>
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
</div>
|
|
284
|
-
|
|
285
|
-
<nav>
|
|
286
|
-
<h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-index.html">index</a></li></ul><h3>Global</h3><ul><li><a href="global.html#EXIT_DELAY">EXIT_DELAY</a></li><li><a href="global.html#MESSAGE_TIMEOUTS">MESSAGE_TIMEOUTS</a></li><li><a href="global.html#PromptField">PromptField</a></li><li><a href="global.html#PromptMessage">PromptMessage</a></li><li><a href="global.html#REFRESH_INTERVALS">REFRESH_INTERVALS</a></li><li><a href="global.html#TIMEOUTS">TIMEOUTS</a></li><li><a href="global.html#colorize">colorize</a></li><li><a href="global.html#createContainer">createContainer</a></li><li><a href="global.html#docker">docker</a></li><li><a href="global.html#exitWithMessage">exitWithMessage</a></li><li><a href="global.html#getContainers">getContainers</a></li><li><a href="global.html#getLogsStream">getLogsStream</a></li><li><a href="global.html#getStats">getStats</a></li><li><a href="global.html#handleAction">handleAction</a></li><li><a href="global.html#imageExists">imageExists</a></li><li><a href="global.html#makeBar">makeBar</a></li><li><a href="global.html#pullImage">pullImage</a></li><li><a href="global.html#removeContainer">removeContainer</a></li><li><a href="global.html#restartContainer">restartContainer</a></li><li><a href="global.html#safeCall">safeCall</a></li><li><a href="global.html#startContainer">startContainer</a></li><li><a href="global.html#stopContainer">stopContainer</a></li><li><a href="global.html#useContainerActions">useContainerActions</a></li><li><a href="global.html#useContainerCreation">useContainerCreation</a></li><li><a href="global.html#useControls">useControls</a></li><li><a href="global.html#useLogsStream">useLogsStream</a></li><li><a href="global.html#useLogsViewer">useLogsViewer</a></li><li><a href="global.html#validateEnvVars">validateEnvVars</a></li><li><a href="global.html#validatePorts">validatePorts</a></li><li><a href="global.html#withTimeout">withTimeout</a></li></ul>
|
|
287
|
-
</nav>
|
|
288
|
-
|
|
289
|
-
<br class="clear">
|
|
290
|
-
|
|
291
|
-
<footer>
|
|
292
|
-
Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.5</a> on Fri Oct 17 2025 16:07:18 GMT-0500 (hora estándar de Colombia)
|
|
293
|
-
</footer>
|
|
294
|
-
|
|
295
|
-
<script> prettyPrint(); </script>
|
|
296
|
-
<script src="scripts/linenumber.js"> </script>
|
|
297
|
-
</body>
|
|
298
|
-
</html>
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="utf-8">
|
|
5
|
-
<title>JSDoc: Source: hooks/useLogsStream.js</title>
|
|
6
|
-
|
|
7
|
-
<script src="scripts/prettify/prettify.js"> </script>
|
|
8
|
-
<script src="scripts/prettify/lang-css.js"> </script>
|
|
9
|
-
<!--[if lt IE 9]>
|
|
10
|
-
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
|
|
11
|
-
<![endif]-->
|
|
12
|
-
<link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
|
|
13
|
-
<link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
|
|
14
|
-
</head>
|
|
15
|
-
|
|
16
|
-
<body>
|
|
17
|
-
|
|
18
|
-
<div id="main">
|
|
19
|
-
|
|
20
|
-
<h1 class="page-title">Source: hooks/useLogsStream.js</h1>
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
<section>
|
|
28
|
-
<article>
|
|
29
|
-
<pre class="prettyprint source linenums"><code>import React, { useRef, useCallback } from "react";
|
|
30
|
-
import { getLogsStream } from "../helpers/dockerService/serviceComponents/containerLogs";
|
|
31
|
-
import { safeCall } from "../helpers/safeCall";
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Hook that manages opening and closing a logs stream for a container.
|
|
35
|
-
*
|
|
36
|
-
* @returns {Object} { openLogs, closeLogs }
|
|
37
|
-
*/
|
|
38
|
-
export function useLogsStream() {
|
|
39
|
-
const logsStreamRef = useRef(null);
|
|
40
|
-
|
|
41
|
-
const openLogs = useCallback((containerId, setLogs) => {
|
|
42
|
-
setLogs([]);
|
|
43
|
-
logsStreamRef.current = getLogsStream(
|
|
44
|
-
containerId,
|
|
45
|
-
(data) => setLogs((prev) => ([...prev, ...data.split("\n").filter(Boolean)])),
|
|
46
|
-
() => {},
|
|
47
|
-
(err) => setLogs((prev) => ([...prev, `Error: ${err.message}`]))
|
|
48
|
-
);
|
|
49
|
-
}, []);
|
|
50
|
-
|
|
51
|
-
const closeLogs = useCallback(() => {
|
|
52
|
-
if (logsStreamRef.current) {
|
|
53
|
-
safeCall(logsStreamRef.current.destroy?.bind(logsStreamRef.current));
|
|
54
|
-
logsStreamRef.current = null;
|
|
55
|
-
}
|
|
56
|
-
}, []);
|
|
57
|
-
|
|
58
|
-
return { openLogs, closeLogs };
|
|
59
|
-
}
|
|
60
|
-
</code></pre>
|
|
61
|
-
</article>
|
|
62
|
-
</section>
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
</div>
|
|
68
|
-
|
|
69
|
-
<nav>
|
|
70
|
-
<h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-index.html">index</a></li></ul><h3>Global</h3><ul><li><a href="global.html#EXIT_DELAY">EXIT_DELAY</a></li><li><a href="global.html#MESSAGE_TIMEOUTS">MESSAGE_TIMEOUTS</a></li><li><a href="global.html#PromptField">PromptField</a></li><li><a href="global.html#PromptMessage">PromptMessage</a></li><li><a href="global.html#REFRESH_INTERVALS">REFRESH_INTERVALS</a></li><li><a href="global.html#TIMEOUTS">TIMEOUTS</a></li><li><a href="global.html#colorize">colorize</a></li><li><a href="global.html#createContainer">createContainer</a></li><li><a href="global.html#docker">docker</a></li><li><a href="global.html#exitWithMessage">exitWithMessage</a></li><li><a href="global.html#getContainers">getContainers</a></li><li><a href="global.html#getLogsStream">getLogsStream</a></li><li><a href="global.html#getStats">getStats</a></li><li><a href="global.html#handleAction">handleAction</a></li><li><a href="global.html#imageExists">imageExists</a></li><li><a href="global.html#makeBar">makeBar</a></li><li><a href="global.html#pullImage">pullImage</a></li><li><a href="global.html#removeContainer">removeContainer</a></li><li><a href="global.html#restartContainer">restartContainer</a></li><li><a href="global.html#safeCall">safeCall</a></li><li><a href="global.html#startContainer">startContainer</a></li><li><a href="global.html#stopContainer">stopContainer</a></li><li><a href="global.html#useContainerActions">useContainerActions</a></li><li><a href="global.html#useContainerCreation">useContainerCreation</a></li><li><a href="global.html#useControls">useControls</a></li><li><a href="global.html#useLogsStream">useLogsStream</a></li><li><a href="global.html#useLogsViewer">useLogsViewer</a></li><li><a href="global.html#validateEnvVars">validateEnvVars</a></li><li><a href="global.html#validatePorts">validatePorts</a></li><li><a href="global.html#withTimeout">withTimeout</a></li></ul>
|
|
71
|
-
</nav>
|
|
72
|
-
|
|
73
|
-
<br class="clear">
|
|
74
|
-
|
|
75
|
-
<footer>
|
|
76
|
-
Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.5</a> on Fri Oct 17 2025 16:07:18 GMT-0500 (hora estándar de Colombia)
|
|
77
|
-
</footer>
|
|
78
|
-
|
|
79
|
-
<script> prettyPrint(); </script>
|
|
80
|
-
<script src="scripts/linenumber.js"> </script>
|
|
81
|
-
</body>
|
|
82
|
-
</html>
|