cdd-cli 3.1.7 → 3.2.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.
Files changed (136) hide show
  1. package/.eslintrc.json +1 -1
  2. package/.github/workflows/ci.yml +3 -0
  3. package/.github/workflows/docs.yml +8 -1
  4. package/CHANGELOG.md +40 -0
  5. package/CONTRIBUTING.md +28 -15
  6. package/README.md +56 -88
  7. package/babel.config.cjs +18 -1
  8. package/coverage/clover.xml +604 -0
  9. package/coverage/coverage-final.json +17 -0
  10. package/coverage/lcov-report/base.css +224 -0
  11. package/coverage/lcov-report/block-navigation.js +87 -0
  12. package/coverage/lcov-report/favicon.png +0 -0
  13. package/coverage/lcov-report/helpers/constants.js.html +235 -0
  14. package/coverage/lcov-report/helpers/containerOptionsBuilder.js.html +211 -0
  15. package/coverage/lcov-report/helpers/dockerService/serviceComponents/containerActions.js.html +853 -0
  16. package/coverage/lcov-report/helpers/dockerService/serviceComponents/containerList.js.html +289 -0
  17. package/coverage/lcov-report/helpers/dockerService/serviceComponents/index.html +131 -0
  18. package/coverage/lcov-report/helpers/index.html +176 -0
  19. package/coverage/lcov-report/helpers/logger.js.html +424 -0
  20. package/coverage/lcov-report/helpers/safeCall.js.html +139 -0
  21. package/coverage/lcov-report/helpers/validationHelpers.js.html +394 -0
  22. package/coverage/lcov-report/hooks/creation/index.html +146 -0
  23. package/coverage/lcov-report/hooks/creation/useContainerActions.js.html +292 -0
  24. package/coverage/lcov-report/hooks/creation/useContainerCreation.js.html +478 -0
  25. package/coverage/lcov-report/hooks/creation/useLogsViewer.js.html +238 -0
  26. package/coverage/lcov-report/hooks/debug/index.html +116 -0
  27. package/coverage/lcov-report/hooks/debug/useDebugLogs.js.html +172 -0
  28. package/coverage/lcov-report/hooks/index.html +161 -0
  29. package/coverage/lcov-report/hooks/navigation/index.html +116 -0
  30. package/coverage/lcov-report/hooks/navigation/useContainerSelection.js.html +160 -0
  31. package/coverage/lcov-report/hooks/useContainerCommandRouter.js.html +415 -0
  32. package/coverage/lcov-report/hooks/useControls.js.html +685 -0
  33. package/coverage/lcov-report/hooks/useEraseConfirmation.js.html +202 -0
  34. package/coverage/lcov-report/hooks/useExitHandler.js.html +283 -0
  35. package/coverage/lcov-report/index.html +191 -0
  36. package/coverage/lcov-report/prettify.css +1 -0
  37. package/coverage/lcov-report/prettify.js +2 -0
  38. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  39. package/coverage/lcov-report/sorter.js +210 -0
  40. package/coverage/lcov.info +1216 -0
  41. package/dist/components/ContainerRow.js +5 -78
  42. package/dist/components/LogViewer.js +4 -9
  43. package/dist/helpers/containerOptionsBuilder.js +58 -0
  44. package/dist/hooks/creation/useContainerCreation.js +16 -1
  45. package/dist/hooks/debug/useDebugLogs.js +46 -0
  46. package/dist/hooks/navigation/useContainerSelection.js +36 -0
  47. package/dist/hooks/useContainerCommandRouter.js +151 -0
  48. package/dist/{helpers/actionHelpers.js → hooks/useContainerStats.js} +76 -78
  49. package/dist/hooks/useControls.js +83 -342
  50. package/dist/hooks/useEraseConfirmation.js +47 -0
  51. package/dist/hooks/useExitHandler.js +68 -0
  52. package/jest.config.cjs +1 -1
  53. package/package.json +2 -3
  54. package/src/components/ContainerRow.jsx +3 -38
  55. package/src/components/LogViewer.jsx +4 -10
  56. package/src/helpers/constants.js +20 -0
  57. package/src/helpers/containerOptionsBuilder.js +42 -0
  58. package/src/helpers/dockerService/serviceComponents/containerActions.js +55 -8
  59. package/src/helpers/validationHelpers.js +75 -18
  60. package/src/hooks/creation/useContainerCreation.js +34 -4
  61. package/src/hooks/debug/useDebugLogs.js +29 -0
  62. package/src/hooks/navigation/useContainerSelection.js +25 -0
  63. package/src/hooks/useContainerCommandRouter.js +110 -0
  64. package/src/hooks/useContainerStats.js +44 -0
  65. package/src/hooks/useControls.js +75 -274
  66. package/src/hooks/useEraseConfirmation.js +39 -0
  67. package/src/hooks/useExitHandler.js +66 -0
  68. package/test/containerActions.test.js +104 -13
  69. package/test/containerOptionsBuilder.test.js +36 -0
  70. package/test/useContainerCreation.dom.test.js +46 -2
  71. package/test/useControls.dom.test.js +117 -0
  72. package/test/validationHelpers.test.js +51 -0
  73. package/.babelrc +0 -6
  74. package/FIXES_APPLIED.md +0 -419
  75. package/SECURITY.md +0 -5
  76. package/dist/hooks/useLogsStream.js +0 -41
  77. package/docs/_config.yml +0 -13
  78. package/docs/components_ContainerCreationPrompt.jsx.html +0 -114
  79. package/docs/components_ContainerRow.jsx.html +0 -151
  80. package/docs/components_ContainerSection.jsx.html +0 -75
  81. package/docs/components_Footer.jsx.html +0 -66
  82. package/docs/components_Header.jsx.html +0 -84
  83. package/docs/components_LogViewer.jsx.html +0 -91
  84. package/docs/components_MessageFeedback.jsx.html +0 -76
  85. package/docs/components_PromptField.jsx.html +0 -99
  86. package/docs/components_StatsBar.jsx.html +0 -105
  87. package/docs/components_UsageMenu.jsx.html +0 -73
  88. package/docs/fonts/OpenSans-Bold-webfont.eot +0 -0
  89. package/docs/fonts/OpenSans-Bold-webfont.svg +0 -1830
  90. package/docs/fonts/OpenSans-Bold-webfont.woff +0 -0
  91. package/docs/fonts/OpenSans-BoldItalic-webfont.eot +0 -0
  92. package/docs/fonts/OpenSans-BoldItalic-webfont.svg +0 -1830
  93. package/docs/fonts/OpenSans-BoldItalic-webfont.woff +0 -0
  94. package/docs/fonts/OpenSans-Italic-webfont.eot +0 -0
  95. package/docs/fonts/OpenSans-Italic-webfont.svg +0 -1830
  96. package/docs/fonts/OpenSans-Italic-webfont.woff +0 -0
  97. package/docs/fonts/OpenSans-Light-webfont.eot +0 -0
  98. package/docs/fonts/OpenSans-Light-webfont.svg +0 -1831
  99. package/docs/fonts/OpenSans-Light-webfont.woff +0 -0
  100. package/docs/fonts/OpenSans-LightItalic-webfont.eot +0 -0
  101. package/docs/fonts/OpenSans-LightItalic-webfont.svg +0 -1835
  102. package/docs/fonts/OpenSans-LightItalic-webfont.woff +0 -0
  103. package/docs/fonts/OpenSans-Regular-webfont.eot +0 -0
  104. package/docs/fonts/OpenSans-Regular-webfont.svg +0 -1831
  105. package/docs/fonts/OpenSans-Regular-webfont.woff +0 -0
  106. package/docs/global.html +0 -6145
  107. package/docs/helpers_actionHelpers.js.html +0 -94
  108. package/docs/helpers_constants.js.html +0 -81
  109. package/docs/helpers_dockerService_dockerService.js.html +0 -79
  110. package/docs/helpers_dockerService_serviceComponents_containerActions.js.html +0 -153
  111. package/docs/helpers_dockerService_serviceComponents_containerList.js.html +0 -81
  112. package/docs/helpers_dockerService_serviceComponents_containerLogs.js.html +0 -85
  113. package/docs/helpers_dockerService_serviceComponents_containerStats.js.html +0 -107
  114. package/docs/helpers_dockerService_serviceComponents_imageUtils.js.html +0 -82
  115. package/docs/helpers_exitWithMessage.js.html +0 -77
  116. package/docs/helpers_safeCall.js.html +0 -68
  117. package/docs/helpers_validationHelpers.js.html +0 -96
  118. package/docs/hooks_creation_useContainerActions.js.html +0 -120
  119. package/docs/hooks_creation_useContainerCreation.js.html +0 -152
  120. package/docs/hooks_creation_useLogsViewer.js.html +0 -102
  121. package/docs/hooks_useControls.js.html +0 -298
  122. package/docs/hooks_useLogsStream.js.html +0 -82
  123. package/docs/index.html +0 -65
  124. package/docs/index.js.html +0 -65
  125. package/docs/module-index.html +0 -171
  126. package/docs/scripts/linenumber.js +0 -25
  127. package/docs/scripts/prettify/Apache-License-2.0.txt +0 -202
  128. package/docs/scripts/prettify/lang-css.js +0 -2
  129. package/docs/scripts/prettify/prettify.js +0 -28
  130. package/docs/styles/jsdoc-default.css +0 -358
  131. package/docs/styles/prettify-jsdoc.css +0 -111
  132. package/docs/styles/prettify-tomorrow.css +0 -132
  133. package/esbuild.config.cjs +0 -11
  134. package/src/helpers/actionHelpers.js +0 -52
  135. package/src/hooks/useLogsStream.js +0 -31
  136. 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&lt;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() &amp;&amp; !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&lt;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&lt;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&lt;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 &amp;&amp; input.length === 1 &amp;&amp; !key.ctrl &amp;&amp; !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 &amp;&amp; total > 0) setSelected((i) => (i === 0 ? total - 1 : i - 1));
188
- if (key.downArrow &amp;&amp; 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") &amp;&amp; "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") &amp;&amp; "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" &amp;&amp; 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" &amp;&amp; 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>