cdd-cli 2.0.3 → 3.0.1

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.
@@ -1,59 +1,147 @@
1
+ function _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); }
2
+ function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
3
+ function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
4
+ function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); }
5
+ function _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray(r); }
6
+ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
1
7
  function _regenerator() { /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/babel/babel/blob/main/packages/babel-helpers/LICENSE */ var e, t, r = "function" == typeof Symbol ? Symbol : {}, n = r.iterator || "@@iterator", o = r.toStringTag || "@@toStringTag"; function i(r, n, o, i) { var c = n && n.prototype instanceof Generator ? n : Generator, u = Object.create(c.prototype); return _regeneratorDefine2(u, "_invoke", function (r, n, o) { var i, c, u, f = 0, p = o || [], y = !1, G = { p: 0, n: 0, v: e, a: d, f: d.bind(e, 4), d: function d(t, r) { return i = t, c = 0, u = e, G.n = r, a; } }; function d(r, n) { for (c = r, u = n, t = 0; !y && f && !o && t < p.length; t++) { var o, i = p[t], d = G.p, l = i[2]; r > 3 ? (o = l === n) && (u = i[(c = i[4]) ? 5 : (c = 3, 3)], i[4] = i[5] = e) : i[0] <= d && ((o = r < 2 && d < i[1]) ? (c = 0, G.v = n, G.n = i[1]) : d < l && (o = r < 3 || i[0] > n || n > l) && (i[4] = r, i[5] = n, G.n = l, c = 0)); } if (o || r > 1) return a; throw y = !0, n; } return function (o, p, l) { if (f > 1) throw TypeError("Generator is already running"); for (y && 1 === p && d(p, l), c = p, u = l; (t = c < 2 ? e : u) || !y;) { i || (c ? c < 3 ? (c > 1 && (G.n = -1), d(c, u)) : G.n = u : G.v = u); try { if (f = 2, i) { if (c || (o = "next"), t = i[o]) { if (!(t = t.call(i, u))) throw TypeError("iterator result is not an object"); if (!t.done) return t; u = t.value, c < 2 && (c = 0); } else 1 === c && (t = i["return"]) && t.call(i), c < 2 && (u = TypeError("The iterator does not provide a '" + o + "' method"), c = 1); i = e; } else if ((t = (y = G.n < 0) ? u : r.call(n, G)) !== a) break; } catch (t) { i = e, c = 1, u = t; } finally { f = 1; } } return { value: t, done: y }; }; }(r, o, i), !0), u; } var a = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} t = Object.getPrototypeOf; var c = [][n] ? t(t([][n]())) : (_regeneratorDefine2(t = {}, n, function () { return this; }), t), u = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(c); function f(e) { return Object.setPrototypeOf ? Object.setPrototypeOf(e, GeneratorFunctionPrototype) : (e.__proto__ = GeneratorFunctionPrototype, _regeneratorDefine2(e, o, "GeneratorFunction")), e.prototype = Object.create(u), e; } return GeneratorFunction.prototype = GeneratorFunctionPrototype, _regeneratorDefine2(u, "constructor", GeneratorFunctionPrototype), _regeneratorDefine2(GeneratorFunctionPrototype, "constructor", GeneratorFunction), GeneratorFunction.displayName = "GeneratorFunction", _regeneratorDefine2(GeneratorFunctionPrototype, o, "GeneratorFunction"), _regeneratorDefine2(u), _regeneratorDefine2(u, o, "Generator"), _regeneratorDefine2(u, n, function () { return this; }), _regeneratorDefine2(u, "toString", function () { return "[object Generator]"; }), (_regenerator = function _regenerator() { return { w: i, m: f }; })(); }
2
8
  function _regeneratorDefine2(e, r, n, t) { var i = Object.defineProperty; try { i({}, "", {}); } catch (e) { i = 0; } _regeneratorDefine2 = function _regeneratorDefine(e, r, n, t) { function o(r, n) { _regeneratorDefine2(e, r, function (e) { return this._invoke(r, n, e); }); } r ? i ? i(e, r, { value: n, enumerable: !t, configurable: !t, writable: !t }) : e[r] = n : (o("next", 0), o("throw", 1), o("return", 2)); }, _regeneratorDefine2(e, r, n, t); }
3
9
  function asyncGeneratorStep(n, t, e, r, o, a, c) { try { var i = n[a](c), u = i.value; } catch (n) { return void e(n); } i.done ? t(u) : Promise.resolve(u).then(r, o); }
4
10
  function _asyncToGenerator(n) { return function () { var t = this, e = arguments; return new Promise(function (r, o) { var a = n.apply(t, e); function _next(n) { asyncGeneratorStep(a, r, o, _next, _throw, "next", n); } function _throw(n) { asyncGeneratorStep(a, r, o, _next, _throw, "throw", n); } _next(void 0); }); }; }
5
- import Docker from 'dockerode';
11
+ import Docker from "dockerode";
6
12
  var docker = new Docker({
7
- socketPath: '/var/run/docker.sock'
13
+ socketPath: "/var/run/docker.sock"
8
14
  });
15
+ export function getLogsStream(containerId, onData, onEnd, onError) {
16
+ var container = docker.getContainer(containerId);
17
+ container.logs({
18
+ follow: true,
19
+ stdout: true,
20
+ stderr: true,
21
+ tail: 100
22
+ }, function (err, stream) {
23
+ if (err) {
24
+ onError === null || onError === void 0 || onError(err);
25
+ return;
26
+ }
27
+ stream.on('data', function (chunk) {
28
+ return onData === null || onData === void 0 ? void 0 : onData(chunk.toString());
29
+ });
30
+ stream.on('end', function () {
31
+ return onEnd === null || onEnd === void 0 ? void 0 : onEnd();
32
+ });
33
+ stream.on('error', function (err) {
34
+ return onError === null || onError === void 0 ? void 0 : onError(err);
35
+ });
36
+ });
37
+ }
38
+ export function startContainer(_x) {
39
+ return _startContainer.apply(this, arguments);
40
+ }
41
+ function _startContainer() {
42
+ _startContainer = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee(containerId) {
43
+ var container;
44
+ return _regenerator().w(function (_context) {
45
+ while (1) switch (_context.n) {
46
+ case 0:
47
+ container = docker.getContainer(containerId);
48
+ _context.n = 1;
49
+ return container.start();
50
+ case 1:
51
+ return _context.a(2);
52
+ }
53
+ }, _callee);
54
+ }));
55
+ return _startContainer.apply(this, arguments);
56
+ }
57
+ export function stopContainer(_x2) {
58
+ return _stopContainer.apply(this, arguments);
59
+ }
60
+ function _stopContainer() {
61
+ _stopContainer = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee2(containerId) {
62
+ var container;
63
+ return _regenerator().w(function (_context2) {
64
+ while (1) switch (_context2.n) {
65
+ case 0:
66
+ container = docker.getContainer(containerId);
67
+ _context2.n = 1;
68
+ return container.stop();
69
+ case 1:
70
+ return _context2.a(2);
71
+ }
72
+ }, _callee2);
73
+ }));
74
+ return _stopContainer.apply(this, arguments);
75
+ }
76
+ export function restartContainer(_x3) {
77
+ return _restartContainer.apply(this, arguments);
78
+ }
79
+ function _restartContainer() {
80
+ _restartContainer = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee3(containerId) {
81
+ var container;
82
+ return _regenerator().w(function (_context3) {
83
+ while (1) switch (_context3.n) {
84
+ case 0:
85
+ container = docker.getContainer(containerId);
86
+ _context3.n = 1;
87
+ return container.restart();
88
+ case 1:
89
+ return _context3.a(2);
90
+ }
91
+ }, _callee3);
92
+ }));
93
+ return _restartContainer.apply(this, arguments);
94
+ }
9
95
  export function getContainers() {
10
96
  return _getContainers.apply(this, arguments);
11
97
  }
12
98
  function _getContainers() {
13
- _getContainers = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee() {
99
+ _getContainers = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee4() {
14
100
  var containers;
15
- return _regenerator().w(function (_context) {
16
- while (1) switch (_context.n) {
101
+ return _regenerator().w(function (_context4) {
102
+ while (1) switch (_context4.n) {
17
103
  case 0:
18
- _context.n = 1;
104
+ _context4.n = 1;
19
105
  return docker.listContainers({
20
106
  all: true
21
107
  });
22
108
  case 1:
23
- containers = _context.v;
24
- return _context.a(2, containers.map(function (container) {
109
+ containers = _context4.v;
110
+ return _context4.a(2, containers.map(function (container) {
25
111
  return {
26
112
  id: container.Id,
27
- name: container.Names[0].replace('/', ''),
113
+ name: container.Names[0].replace("/", ""),
28
114
  image: container.Image,
29
115
  state: container.State,
30
116
  status: container.Status,
31
- ports: container.Ports.map(function (port) {
32
- return "".concat(port.PublicPort || '', ":").concat(port.PrivatePort);
33
- }).join(', ') || '-'
117
+ ports: _toConsumableArray(new Set(container.Ports.filter(function (port) {
118
+ return port.PublicPort;
119
+ }).map(function (port) {
120
+ return "".concat(port.PublicPort, ":").concat(port.PrivatePort);
121
+ })))
34
122
  };
35
123
  }));
36
124
  }
37
- }, _callee);
125
+ }, _callee4);
38
126
  }));
39
127
  return _getContainers.apply(this, arguments);
40
128
  }
41
- export function getStats(_x) {
129
+ export function getStats(_x4) {
42
130
  return _getStats.apply(this, arguments);
43
131
  }
44
132
  function _getStats() {
45
- _getStats = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee2(containerId) {
133
+ _getStats = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee5(containerId) {
46
134
  var container, stream, cpuDelta, systemDelta, cpuPercent, memUsage, memLimit, memPercent, rx, tx;
47
- return _regenerator().w(function (_context2) {
48
- while (1) switch (_context2.n) {
135
+ return _regenerator().w(function (_context5) {
136
+ while (1) switch (_context5.n) {
49
137
  case 0:
50
138
  container = docker.getContainer(containerId);
51
- _context2.n = 1;
139
+ _context5.n = 1;
52
140
  return container.stats({
53
141
  stream: false
54
142
  });
55
143
  case 1:
56
- stream = _context2.v;
144
+ stream = _context5.v;
57
145
  cpuDelta = stream.cpu_stats.cpu_usage.total_usage - stream.precpu_stats.cpu_usage.total_usage;
58
146
  systemDelta = stream.cpu_stats.system_cpu_usage - stream.precpu_stats.system_cpu_usage;
59
147
  cpuPercent = systemDelta > 0 ? cpuDelta / systemDelta * 100 : 0;
@@ -70,7 +158,7 @@ function _getStats() {
70
158
  }).reduce(function (a, b) {
71
159
  return a + b;
72
160
  }, 0) : 0;
73
- return _context2.a(2, {
161
+ return _context5.a(2, {
74
162
  cpuPercent: cpuPercent.toFixed(1),
75
163
  memPercent: memPercent.toFixed(1),
76
164
  netIO: {
@@ -79,7 +167,7 @@ function _getStats() {
79
167
  }
80
168
  });
81
169
  }
82
- }, _callee2);
170
+ }, _callee5);
83
171
  }));
84
172
  return _getStats.apply(this, arguments);
85
173
  }
@@ -0,0 +1,26 @@
1
+ import { spawn } from "child_process";
2
+ export function exitWithMessage(_ref) {
3
+ var setMessage = _ref.setMessage,
4
+ setMessageColor = _ref.setMessageColor,
5
+ _ref$message = _ref.message,
6
+ message = _ref$message === void 0 ? "Exiting..." : _ref$message,
7
+ _ref$color = _ref.color,
8
+ color = _ref$color === void 0 ? "yellow" : _ref$color,
9
+ _ref$delay = _ref.delay,
10
+ delay = _ref$delay === void 0 ? 1500 : _ref$delay;
11
+ setMessage(message);
12
+ setMessageColor(color);
13
+ setTimeout(function () {
14
+ setMessage("");
15
+ if (process.platform === "win32") {
16
+ spawn("cmd", ["/c", "cls"], {
17
+ stdio: "inherit"
18
+ });
19
+ } else {
20
+ spawn("clear", [], {
21
+ stdio: "inherit"
22
+ });
23
+ }
24
+ process.exit();
25
+ }, delay);
26
+ }
@@ -9,7 +9,7 @@ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length)
9
9
  function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
10
10
  function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
11
11
  import React, { useState, useEffect } from "react";
12
- import { getContainers } from "../dockerService.js";
12
+ import { getContainers } from "../helpers/dockerService.js";
13
13
  export function useContainers() {
14
14
  var _useState = useState([]),
15
15
  _useState2 = _slicedToArray(_useState, 2),
@@ -0,0 +1,142 @@
1
+ function _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); }
2
+ function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
3
+ function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); }
4
+ function _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray(r); }
5
+ function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
6
+ function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
7
+ function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
8
+ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
9
+ function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
10
+ function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
11
+ import React, { useState, useRef } from "react";
12
+ import { useInput } from "ink";
13
+ import { startContainer, stopContainer, restartContainer, getLogsStream } from "../helpers/dockerService.js";
14
+ import { handleAction } from "../helpers/actionHelpers.js";
15
+ import { exitWithMessage } from "../helpers/exitWithMessage.js";
16
+ export function useControls() {
17
+ var containers = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
18
+ var _useState = useState(0),
19
+ _useState2 = _slicedToArray(_useState, 2),
20
+ selected = _useState2[0],
21
+ setSelected = _useState2[1];
22
+ var _useState3 = useState(""),
23
+ _useState4 = _slicedToArray(_useState3, 2),
24
+ message = _useState4[0],
25
+ setMessage = _useState4[1];
26
+ var _useState5 = useState("yellow"),
27
+ _useState6 = _slicedToArray(_useState5, 2),
28
+ messageColor = _useState6[0],
29
+ setMessageColor = _useState6[1];
30
+ var _useState7 = useState(false),
31
+ _useState8 = _slicedToArray(_useState7, 2),
32
+ showLogs = _useState8[0],
33
+ setShowLogs = _useState8[1];
34
+ var _useState9 = useState([]),
35
+ _useState0 = _slicedToArray(_useState9, 2),
36
+ logs = _useState0[0],
37
+ setLogs = _useState0[1];
38
+ var logsStreamRef = useRef(null);
39
+ var total = containers.length;
40
+
41
+ // Handler para salir de la vista de logs
42
+ var exitLogs = function exitLogs() {
43
+ setShowLogs(false);
44
+ setLogs([]);
45
+ if (logsStreamRef.current) {
46
+ var _logsStreamRef$curren, _logsStreamRef$curren2;
47
+ (_logsStreamRef$curren = (_logsStreamRef$curren2 = logsStreamRef.current).destroy) === null || _logsStreamRef$curren === void 0 || _logsStreamRef$curren.call(_logsStreamRef$curren2);
48
+ logsStreamRef.current = null;
49
+ }
50
+ };
51
+ useInput(function (input, key) {
52
+ if (showLogs) {
53
+ if (input === "q" || key.escape) {
54
+ exitLogs();
55
+ }
56
+ return;
57
+ }
58
+
59
+ //==========================================================
60
+ // Menu Navigation
61
+ //==========================================================
62
+ if (key.upArrow && total > 0) {
63
+ setSelected(function (i) {
64
+ return i === 0 ? total - 1 : i - 1;
65
+ });
66
+ }
67
+ if (key.downArrow && total > 0) {
68
+ setSelected(function (i) {
69
+ return i === total - 1 ? 0 : i + 1;
70
+ });
71
+ }
72
+ if (input === "q") {
73
+ exitWithMessage({
74
+ setMessage: setMessage,
75
+ setMessageColor: setMessageColor
76
+ });
77
+ return;
78
+ }
79
+
80
+ //==========================================================
81
+ // Docker commands
82
+ //==========================================================
83
+ if (input === "i") {
84
+ handleAction({
85
+ containers: containers,
86
+ selected: selected,
87
+ actionFn: startContainer,
88
+ actionLabel: "Starting",
89
+ setMessage: setMessage,
90
+ setMessageColor: setMessageColor,
91
+ stateCheck: function stateCheck(c) {
92
+ return (c.state === "running" || c.status === "running") && "Container is already running.";
93
+ }
94
+ });
95
+ }
96
+ if (input === "p") {
97
+ handleAction({
98
+ containers: containers,
99
+ selected: selected,
100
+ actionFn: stopContainer,
101
+ actionLabel: "Stopping",
102
+ setMessage: setMessage,
103
+ setMessageColor: setMessageColor,
104
+ stateCheck: function stateCheck(c) {
105
+ return (c.state === "exited" || c.status === "exited" || c.state === "stopped" || c.status === "stopped") && "Container is already stopped.";
106
+ }
107
+ });
108
+ }
109
+ if (input === "r") {
110
+ handleAction({
111
+ containers: containers,
112
+ selected: selected,
113
+ actionFn: restartContainer,
114
+ actionLabel: "Restarting",
115
+ setMessage: setMessage,
116
+ setMessageColor: setMessageColor
117
+ });
118
+ }
119
+ if (input === "l" && containers[selected]) {
120
+ setShowLogs(true);
121
+ setLogs([]);
122
+ getLogsStream(containers[selected].id, function (data) {
123
+ return setLogs(function (prev) {
124
+ return [].concat(_toConsumableArray(prev), _toConsumableArray(data.split("\n").filter(Boolean)));
125
+ });
126
+ }, function () {}, function (err) {
127
+ return setLogs(function (prev) {
128
+ return [].concat(_toConsumableArray(prev), ["Error: ".concat(err.message)]);
129
+ });
130
+ });
131
+ }
132
+ });
133
+ return {
134
+ selected: selected,
135
+ setSelected: setSelected,
136
+ message: message,
137
+ messageColor: messageColor,
138
+ showLogs: showLogs,
139
+ logs: logs,
140
+ exitLogs: exitLogs
141
+ };
142
+ }
@@ -0,0 +1,34 @@
1
+ function _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); }
2
+ function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
3
+ function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
4
+ function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); }
5
+ function _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray(r); }
6
+ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
7
+ import React, { useRef, useCallback } from "react";
8
+ import { getLogsStream } from "../helpers/dockerService.js";
9
+ export function useLogsStream() {
10
+ var logsStreamRef = useRef(null);
11
+ var openLogs = useCallback(function (containerId, setLogs) {
12
+ setLogs([]);
13
+ logsStreamRef.current = getLogsStream(containerId, function (data) {
14
+ return setLogs(function (prev) {
15
+ return [].concat(_toConsumableArray(prev), _toConsumableArray(data.split("\n").filter(Boolean)));
16
+ });
17
+ }, function () {}, function (err) {
18
+ return setLogs(function (prev) {
19
+ return [].concat(_toConsumableArray(prev), ["Error: ".concat(err.message)]);
20
+ });
21
+ });
22
+ }, []);
23
+ var closeLogs = useCallback(function () {
24
+ if (logsStreamRef.current) {
25
+ var _logsStreamRef$curren, _logsStreamRef$curren2;
26
+ (_logsStreamRef$curren = (_logsStreamRef$curren2 = logsStreamRef.current).destroy) === null || _logsStreamRef$curren === void 0 || _logsStreamRef$curren.call(_logsStreamRef$curren2);
27
+ logsStreamRef.current = null;
28
+ }
29
+ }, []);
30
+ return {
31
+ openLogs: openLogs,
32
+ closeLogs: closeLogs
33
+ };
34
+ }
@@ -0,0 +1,54 @@
1
+ function _regenerator() { /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/babel/babel/blob/main/packages/babel-helpers/LICENSE */ var e, t, r = "function" == typeof Symbol ? Symbol : {}, n = r.iterator || "@@iterator", o = r.toStringTag || "@@toStringTag"; function i(r, n, o, i) { var c = n && n.prototype instanceof Generator ? n : Generator, u = Object.create(c.prototype); return _regeneratorDefine2(u, "_invoke", function (r, n, o) { var i, c, u, f = 0, p = o || [], y = !1, G = { p: 0, n: 0, v: e, a: d, f: d.bind(e, 4), d: function d(t, r) { return i = t, c = 0, u = e, G.n = r, a; } }; function d(r, n) { for (c = r, u = n, t = 0; !y && f && !o && t < p.length; t++) { var o, i = p[t], d = G.p, l = i[2]; r > 3 ? (o = l === n) && (u = i[(c = i[4]) ? 5 : (c = 3, 3)], i[4] = i[5] = e) : i[0] <= d && ((o = r < 2 && d < i[1]) ? (c = 0, G.v = n, G.n = i[1]) : d < l && (o = r < 3 || i[0] > n || n > l) && (i[4] = r, i[5] = n, G.n = l, c = 0)); } if (o || r > 1) return a; throw y = !0, n; } return function (o, p, l) { if (f > 1) throw TypeError("Generator is already running"); for (y && 1 === p && d(p, l), c = p, u = l; (t = c < 2 ? e : u) || !y;) { i || (c ? c < 3 ? (c > 1 && (G.n = -1), d(c, u)) : G.n = u : G.v = u); try { if (f = 2, i) { if (c || (o = "next"), t = i[o]) { if (!(t = t.call(i, u))) throw TypeError("iterator result is not an object"); if (!t.done) return t; u = t.value, c < 2 && (c = 0); } else 1 === c && (t = i["return"]) && t.call(i), c < 2 && (u = TypeError("The iterator does not provide a '" + o + "' method"), c = 1); i = e; } else if ((t = (y = G.n < 0) ? u : r.call(n, G)) !== a) break; } catch (t) { i = e, c = 1, u = t; } finally { f = 1; } } return { value: t, done: y }; }; }(r, o, i), !0), u; } var a = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} t = Object.getPrototypeOf; var c = [][n] ? t(t([][n]())) : (_regeneratorDefine2(t = {}, n, function () { return this; }), t), u = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(c); function f(e) { return Object.setPrototypeOf ? Object.setPrototypeOf(e, GeneratorFunctionPrototype) : (e.__proto__ = GeneratorFunctionPrototype, _regeneratorDefine2(e, o, "GeneratorFunction")), e.prototype = Object.create(u), e; } return GeneratorFunction.prototype = GeneratorFunctionPrototype, _regeneratorDefine2(u, "constructor", GeneratorFunctionPrototype), _regeneratorDefine2(GeneratorFunctionPrototype, "constructor", GeneratorFunction), GeneratorFunction.displayName = "GeneratorFunction", _regeneratorDefine2(GeneratorFunctionPrototype, o, "GeneratorFunction"), _regeneratorDefine2(u), _regeneratorDefine2(u, o, "Generator"), _regeneratorDefine2(u, n, function () { return this; }), _regeneratorDefine2(u, "toString", function () { return "[object Generator]"; }), (_regenerator = function _regenerator() { return { w: i, m: f }; })(); }
2
+ function _regeneratorDefine2(e, r, n, t) { var i = Object.defineProperty; try { i({}, "", {}); } catch (e) { i = 0; } _regeneratorDefine2 = function _regeneratorDefine(e, r, n, t) { function o(r, n) { _regeneratorDefine2(e, r, function (e) { return this._invoke(r, n, e); }); } r ? i ? i(e, r, { value: n, enumerable: !t, configurable: !t, writable: !t }) : e[r] = n : (o("next", 0), o("throw", 1), o("return", 2)); }, _regeneratorDefine2(e, r, n, t); }
3
+ function asyncGeneratorStep(n, t, e, r, o, a, c) { try { var i = n[a](c), u = i.value; } catch (n) { return void e(n); } i.done ? t(u) : Promise.resolve(u).then(r, o); }
4
+ function _asyncToGenerator(n) { return function () { var t = this, e = arguments; return new Promise(function (r, o) { var a = n.apply(t, e); function _next(n) { asyncGeneratorStep(a, r, o, _next, _throw, "next", n); } function _throw(n) { asyncGeneratorStep(a, r, o, _next, _throw, "throw", n); } _next(void 0); }); }; }
5
+ import React, { useEffect } from "react";
6
+ export function useStatsPolling(_ref) {
7
+ var showStats = _ref.showStats,
8
+ selected = _ref.selected,
9
+ containers = _ref.containers,
10
+ setStats = _ref.setStats;
11
+ useEffect(function () {
12
+ var intervalId;
13
+ var mounted = true;
14
+ function fetchStats() {
15
+ return _fetchStats.apply(this, arguments);
16
+ }
17
+ function _fetchStats() {
18
+ _fetchStats = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee() {
19
+ var _yield$import, getStats, statsData;
20
+ return _regenerator().w(function (_context) {
21
+ while (1) switch (_context.n) {
22
+ case 0:
23
+ if (!(showStats && containers[selected])) {
24
+ _context.n = 3;
25
+ break;
26
+ }
27
+ _context.n = 1;
28
+ return import("../helpers/dockerService.js");
29
+ case 1:
30
+ _yield$import = _context.v;
31
+ getStats = _yield$import.getStats;
32
+ _context.n = 2;
33
+ return getStats(containers[selected].id);
34
+ case 2:
35
+ statsData = _context.v;
36
+ if (mounted) setStats(statsData);
37
+ case 3:
38
+ return _context.a(2);
39
+ }
40
+ }, _callee);
41
+ }));
42
+ return _fetchStats.apply(this, arguments);
43
+ }
44
+ if (showStats && containers[selected]) {
45
+ setStats(null);
46
+ fetchStats();
47
+ intervalId = setInterval(fetchStats, 2000);
48
+ }
49
+ return function () {
50
+ mounted = false;
51
+ if (intervalId) clearInterval(intervalId);
52
+ };
53
+ }, [showStats, selected, containers, setStats]);
54
+ }
@@ -0,0 +1,167 @@
1
+ # README (ENGLISH)
2
+ *Generated: 2025-10-13*
3
+
4
+ ## Table of Contents
5
+ - [Project Scope](#project-scope)
6
+ - [Objectives & Roadmap](#objectives--roadmap)
7
+ - [Requirements](#requirements)
8
+ - [Installation](#installation)
9
+ - [Quick Start](#quick-start)
10
+ - [Use Cases](#use-cases)
11
+ - [Technical Documentation](#technical-documentation)
12
+ - [API Reference](#api-reference)
13
+ - [License](#license)
14
+ - [Contributing](#contributing)
15
+ - [Code of Conduct](#code-of-conduct)
16
+ - [Changelog](#changelog)
17
+ - [FAQ](#faq)
18
+ - [Publishing & Maintenance](#publishing--maintenance)
19
+
20
+ ---
21
+
22
+ ## Project Scope
23
+ This project is a cross-platform CLI tool for managing Docker containers with real-time log streaming and keyboard shortcuts. It is designed for developers and DevOps engineers who need fast, scriptable, and interactive container management from the terminal.
24
+
25
+ **What it does:**
26
+ - Lists, starts, stops, and removes Docker containers.
27
+ - Streams logs in real time.
28
+ - Provides keyboard shortcuts for common actions.
29
+ - Offers feedback and stats in the terminal.
30
+
31
+ **What it does NOT do:**
32
+ - Does not replace Docker Compose or advanced orchestration tools.
33
+ - Does not manage images or networks directly.
34
+ - No GUI; terminal only.
35
+
36
+ ## Objectives & Roadmap
37
+ **Short-term (3 months):**
38
+ - Polish CLI UX and error handling.
39
+ - Add more keyboard shortcuts.
40
+ - Improve documentation and add more use cases.
41
+
42
+ **Medium-term (6 months):**
43
+ - Add plugin system for custom actions.
44
+ - Support for container stats export (JSON/CSV).
45
+ - Integration with CI/CD pipelines.
46
+
47
+ **Known limitations:**
48
+ - Requires Docker daemon running locally.
49
+ - Only supports local containers (no remote).
50
+ - Limited to Node.js LTS versions.
51
+
52
+ ## Requirements
53
+ | Requirement | Minimum | Recommended |
54
+ |--------------------|----------------|-----------------|
55
+ | Node.js | 16.x | 18.x+ |
56
+ | npm | 7.x | 8.x+ |
57
+ | OS | Linux, macOS, Windows | Linux, macOS |
58
+ | Docker | 20.x | Latest stable |
59
+ | Permissions | Docker group or sudo | Docker group |
60
+
61
+ **Development:**
62
+ - ESLint, Prettier
63
+ - Jest or Mocha for tests
64
+ - GitHub Actions for CI
65
+
66
+ **Production:**
67
+ - Only Node.js and Docker required
68
+
69
+ ## Installation
70
+ ### Global install
71
+ ```bash
72
+ npm install -g cdd-cli
73
+ ```
74
+
75
+ ### Update
76
+ ```bash
77
+ npm update -g cdd-cli
78
+ ```
79
+
80
+ ### Uninstall
81
+ ```bash
82
+ npm uninstall -g cdd-cli
83
+ ```
84
+
85
+ ### Check version
86
+ ```bash
87
+ cdd -v
88
+ cdd --version
89
+ ```
90
+
91
+ #### Notes
92
+ - On Linux/macOS, you may need `sudo` for global install.
93
+ - Ensure your global npm bin is in your PATH.
94
+ - On Windows, use an Administrator terminal if needed.
95
+
96
+ ## Quick Start
97
+ ```bash
98
+ cdd list
99
+ cdd logs <container>
100
+ cdd start <container>
101
+ cdd stop <container>
102
+ cdd remove <container>
103
+ ```
104
+
105
+ ## Use Cases
106
+ 1. **List all containers**
107
+ - `cdd list`
108
+ - *Shows all containers with status.*
109
+ 2. **Start a container**
110
+ - `cdd start my_container`
111
+ - *Starts the specified container.*
112
+ 3. **Stop a container**
113
+ - `cdd stop my_container`
114
+ - *Stops the specified container.*
115
+ 4. **Stream logs in real time**
116
+ - `cdd logs my_container`
117
+ - *Shows live logs with color highlighting.*
118
+ 5. **Remove a container**
119
+ - `cdd remove my_container`
120
+ - *Deletes the container after confirmation.*
121
+ 6. **Use keyboard shortcuts**
122
+ - While viewing logs, press `q` to quit, `r` to restart, etc.
123
+
124
+ ## Technical Documentation
125
+ See inline JSDoc comments in source files. Example:
126
+ ```js
127
+ /**
128
+ * Start a Docker container by name.
129
+ * @param {string} name - Container name
130
+ * @returns {Promise<boolean>} True if started
131
+ * @throws {Error} If Docker is not running
132
+ * @example
133
+ * await startContainer('my_container');
134
+ */
135
+ ```
136
+
137
+ ## API Reference
138
+ See [API Reference](./api.md) for all exported functions and CLI commands.
139
+
140
+ ## License
141
+ MIT License. See [LICENSE](../../LICENSE).
142
+
143
+ ## Contributing
144
+ See [CONTRIBUTING.md](../../CONTRIBUTING.md).
145
+
146
+ ## Code of Conduct
147
+ See [CODE_OF_CONDUCT.md](../../CODE_OF_CONDUCT.md).
148
+
149
+ ## Changelog
150
+ See [CHANGELOG.md](../../CHANGELOG.md).
151
+
152
+ ## FAQ
153
+ - **Does it work with Docker Desktop?**
154
+ - Yes, as long as Docker CLI is available.
155
+ - **Can I use it in CI?**
156
+ - Yes, see examples below.
157
+ - **How do I add my own commands?**
158
+ - Plugin system coming soon.
159
+
160
+ ## Publishing & Maintenance
161
+ To publish to npm:
162
+ ```bash
163
+ npm login
164
+ npm publish --access public
165
+ ```
166
+
167
+ Keep documentation updated with every release. See CONTRIBUTING.md for details.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cdd-cli",
3
- "version": "2.0.3",
3
+ "version": "3.0.1",
4
4
  "description": "CLI Docker Dashboard",
5
5
  "main": "index.js",
6
6
  "scripts": {