easy-devops 0.1.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 (52) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +325 -0
  3. package/cli/index.js +91 -0
  4. package/cli/managers/domain-manager.js +451 -0
  5. package/cli/managers/nginx-manager.js +329 -0
  6. package/cli/managers/node-manager.js +275 -0
  7. package/cli/managers/ssl-manager.js +397 -0
  8. package/cli/menus/.gitkeep +0 -0
  9. package/cli/menus/dashboard.js +223 -0
  10. package/cli/menus/domains.js +5 -0
  11. package/cli/menus/nginx.js +5 -0
  12. package/cli/menus/nodejs.js +5 -0
  13. package/cli/menus/settings.js +83 -0
  14. package/cli/menus/ssl.js +5 -0
  15. package/core/config.js +37 -0
  16. package/core/db.js +30 -0
  17. package/core/detector.js +257 -0
  18. package/core/nginx-conf-generator.js +309 -0
  19. package/core/shell.js +151 -0
  20. package/dashboard/lib/.gitkeep +0 -0
  21. package/dashboard/lib/cert-reader.js +59 -0
  22. package/dashboard/lib/domains-db.js +51 -0
  23. package/dashboard/lib/nginx-conf-generator.js +16 -0
  24. package/dashboard/lib/nginx-service.js +282 -0
  25. package/dashboard/public/js/app.js +486 -0
  26. package/dashboard/routes/.gitkeep +0 -0
  27. package/dashboard/routes/auth.js +30 -0
  28. package/dashboard/routes/domains.js +300 -0
  29. package/dashboard/routes/nginx.js +151 -0
  30. package/dashboard/routes/settings.js +78 -0
  31. package/dashboard/routes/ssl.js +105 -0
  32. package/dashboard/server.js +79 -0
  33. package/dashboard/views/index.ejs +327 -0
  34. package/dashboard/views/partials/domain-form.ejs +229 -0
  35. package/dashboard/views/partials/domains-panel.ejs +66 -0
  36. package/dashboard/views/partials/login.ejs +50 -0
  37. package/dashboard/views/partials/nginx-panel.ejs +90 -0
  38. package/dashboard/views/partials/overview.ejs +67 -0
  39. package/dashboard/views/partials/settings-panel.ejs +37 -0
  40. package/dashboard/views/partials/sidebar.ejs +45 -0
  41. package/dashboard/views/partials/ssl-panel.ejs +53 -0
  42. package/data/.gitkeep +0 -0
  43. package/install.bat +41 -0
  44. package/install.ps1 +653 -0
  45. package/install.sh +452 -0
  46. package/lib/installer/.gitkeep +0 -0
  47. package/lib/installer/detect.sh +88 -0
  48. package/lib/installer/node-versions.sh +109 -0
  49. package/lib/installer/nvm-bootstrap.sh +77 -0
  50. package/lib/installer/picker.sh +163 -0
  51. package/lib/installer/progress.sh +25 -0
  52. package/package.json +67 -0
@@ -0,0 +1,77 @@
1
+ #!/usr/bin/env bash
2
+ # nvm-bootstrap.sh — Download, install, and activate nvm
3
+ # Sourced by install.sh; not executed directly.
4
+ # Requires: progress.sh sourced first (uses step_* helpers).
5
+ #
6
+ # Functions:
7
+ # bootstrap_nvm — install nvm if absent, then source it into the current session
8
+ #
9
+ # Respects:
10
+ # NVM_DIR (default: ~/.nvm)
11
+
12
+ bootstrap_nvm() {
13
+ local nvm_dir="${NVM_DIR:-$HOME/.nvm}"
14
+ local nvm_install_url="https://raw.githubusercontent.com/nvm-sh/nvm/HEAD/install.sh"
15
+
16
+ # ------------------------------------------------------------------
17
+ # Step 1: Install nvm if not already present
18
+ # ------------------------------------------------------------------
19
+ if [ -f "$nvm_dir/nvm.sh" ]; then
20
+ step_done "nvm already installed at $nvm_dir — skipping download"
21
+ else
22
+ step_running "Downloading and installing nvm…"
23
+
24
+ local install_ok=false
25
+ if command -v curl >/dev/null 2>&1; then
26
+ if curl -fsSL --max-time 60 "$nvm_install_url" | bash >/dev/null 2>&1; then
27
+ install_ok=true
28
+ fi
29
+ fi
30
+ if [ "$install_ok" = "false" ] && command -v wget >/dev/null 2>&1; then
31
+ if wget -qO- --timeout=60 "$nvm_install_url" | bash >/dev/null 2>&1; then
32
+ install_ok=true
33
+ fi
34
+ fi
35
+
36
+ if [ "$install_ok" = "false" ]; then
37
+ step_failed "nvm download failed"
38
+ printf '\nManual recovery:\n' >&2
39
+ printf ' curl -o- %s | bash\n' "$nvm_install_url" >&2
40
+ printf ' Then run: source ~/.nvm/nvm.sh\n' >&2
41
+ return 1
42
+ fi
43
+
44
+ step_done "nvm installed at $nvm_dir"
45
+ fi
46
+
47
+ # ------------------------------------------------------------------
48
+ # Step 2: Source nvm into the current shell session
49
+ # ------------------------------------------------------------------
50
+ # shellcheck source=/dev/null
51
+ if [ -f "$nvm_dir/nvm.sh" ]; then
52
+ export NVM_DIR="$nvm_dir"
53
+ . "$nvm_dir/nvm.sh"
54
+ fi
55
+
56
+ # Verify nvm command is now available
57
+ if ! command -v nvm >/dev/null 2>&1; then
58
+ # nvm is a function, not a binary; try sourcing from common shell rc files
59
+ for rc in "$HOME/.bashrc" "$HOME/.bash_profile" "$HOME/.profile" "$HOME/.zshrc"; do
60
+ if [ -f "$rc" ]; then
61
+ # shellcheck source=/dev/null
62
+ . "$rc" 2>/dev/null || true
63
+ command -v nvm >/dev/null 2>&1 && break
64
+ fi
65
+ done
66
+ fi
67
+
68
+ if ! command -v nvm >/dev/null 2>&1; then
69
+ step_failed "nvm command not available after install"
70
+ printf '\nManual recovery:\n' >&2
71
+ printf ' source ~/.nvm/nvm.sh\n' >&2
72
+ printf ' Then re-run: bash install.sh\n' >&2
73
+ return 1
74
+ fi
75
+
76
+ step_done "nvm is active in this session"
77
+ }
@@ -0,0 +1,163 @@
1
+ #!/usr/bin/env bash
2
+ # picker.sh — Interactive Node.js version picker
3
+ # Sourced by install.sh; not executed directly.
4
+ # Requires: node-versions.sh sourced first (uses NODE_RELEASES global array).
5
+ #
6
+ # Functions:
7
+ # pick_version [current_version]
8
+ #
9
+ # Uses NODE_RELEASES global array (set by fetch_node_versions).
10
+ # Sets PICKED_VERSION to the chosen version string (e.g., "20.11.1").
11
+ # Returns 2 if the user cancels (presses q / Ctrl-C).
12
+
13
+ pick_version() {
14
+ local current_ver="${1:-}"
15
+ local count="${#NODE_RELEASES[@]}"
16
+
17
+ if [ "$count" -eq 0 ]; then
18
+ printf 'Error: No Node.js releases available to pick from.\n' >&2
19
+ return 1
20
+ fi
21
+
22
+ # Build display labels (mark currently installed version)
23
+ PICKER_LABELS=()
24
+ local i
25
+ for (( i=0; i<count; i++ )); do
26
+ local entry="${NODE_RELEASES[$i]}"
27
+ local ver label
28
+ ver="$( printf '%s' "$entry" | cut -d'|' -f1)"
29
+ label="$( printf '%s' "$entry" | cut -d'|' -f4)"
30
+ if [ -n "$current_ver" ] && [ "$ver" = "$current_ver" ]; then
31
+ PICKER_LABELS+=("${label} [currently installed]")
32
+ else
33
+ PICKER_LABELS+=("$label")
34
+ fi
35
+ done
36
+
37
+ # ------------------------------------------------------------------
38
+ # TTY path: arrow-key picker using stty raw + ANSI escape codes
39
+ # ------------------------------------------------------------------
40
+ if [ -t 0 ] && [ -t 1 ]; then
41
+ _pick_tty
42
+ return $?
43
+ fi
44
+
45
+ # ------------------------------------------------------------------
46
+ # Non-TTY / scripted path: numbered select list
47
+ # ------------------------------------------------------------------
48
+ _pick_numbered
49
+ }
50
+
51
+ # Internal: TTY arrow-key picker
52
+ _pick_tty() {
53
+ local count="${#PICKER_LABELS[@]}"
54
+ local selected=0
55
+
56
+ # ANSI sequences
57
+ local CLEAR_LINE BOLD RESET HIGHLIGHT
58
+ CLEAR_LINE="\033[2K\r"
59
+ BOLD="\033[1m"
60
+ RESET="\033[0m"
61
+ HIGHLIGHT="\033[7m"
62
+
63
+ # Hide cursor
64
+ printf '\033[?25l'
65
+
66
+ # Save terminal state and restore on exit
67
+ local old_stty
68
+ old_stty="$(stty -g 2>/dev/null || true)"
69
+
70
+ # Cleanup function
71
+ _tty_cleanup() {
72
+ stty "$old_stty" 2>/dev/null || true
73
+ printf '\033[?25h' # show cursor
74
+ }
75
+ trap '_tty_cleanup; return 2' INT TERM
76
+
77
+ printf '\nSelect a Node.js version (up/down arrows, Enter to confirm, q to quit):\n\n'
78
+
79
+ # Draw initial list
80
+ local j
81
+ for (( j=0; j<count; j++ )); do
82
+ if [ "$j" -eq "$selected" ]; then
83
+ printf " ${HIGHLIGHT}${BOLD}> %s${RESET}\n" "${PICKER_LABELS[$j]}"
84
+ else
85
+ printf " %s\n" "${PICKER_LABELS[$j]}"
86
+ fi
87
+ done
88
+
89
+ # Enable raw mode for single-key reading
90
+ stty raw -echo 2>/dev/null || true
91
+
92
+ while true; do
93
+ local ch seq1 seq2
94
+ IFS= read -r -s -n1 ch 2>/dev/null || true
95
+
96
+ if [ "$ch" = $'\x1b' ]; then
97
+ IFS= read -r -s -n1 -t 0.1 seq1 2>/dev/null || seq1=""
98
+ IFS= read -r -s -n1 -t 0.1 seq2 2>/dev/null || seq2=""
99
+ if [ "$seq1" = "[" ]; then
100
+ case "$seq2" in
101
+ A) [ "$selected" -gt 0 ] && selected=$(( selected - 1 )) ;;
102
+ B) [ "$selected" -lt $(( count - 1 )) ] && selected=$(( selected + 1 )) ;;
103
+ esac
104
+ fi
105
+ elif [ "$ch" = $'\n' ] || [ "$ch" = $'\r' ] || [ -z "$ch" ]; then
106
+ break
107
+ elif [ "$ch" = "q" ] || [ "$ch" = "Q" ]; then
108
+ _tty_cleanup
109
+ trap - INT TERM
110
+ printf '\n'
111
+ return 2
112
+ fi
113
+
114
+ # Redraw: move cursor up count lines
115
+ local k
116
+ for (( k=0; k<count; k++ )); do
117
+ printf "${CLEAR_LINE}\033[1A"
118
+ done
119
+ printf "${CLEAR_LINE}"
120
+ for (( k=0; k<count; k++ )); do
121
+ if [ "$k" -eq "$selected" ]; then
122
+ printf " ${HIGHLIGHT}${BOLD}> %s${RESET}\n" "${PICKER_LABELS[$k]}"
123
+ else
124
+ printf " %s\n" "${PICKER_LABELS[$k]}"
125
+ fi
126
+ done
127
+ done
128
+
129
+ _tty_cleanup
130
+ trap - INT TERM
131
+ printf '\n'
132
+
133
+ PICKED_VERSION="$(printf '%s' "${NODE_RELEASES[$selected]}" | cut -d'|' -f1)"
134
+ }
135
+
136
+ # Internal: numbered list fallback (non-TTY)
137
+ _pick_numbered() {
138
+ local count="${#PICKER_LABELS[@]}"
139
+
140
+ printf '\nAvailable Node.js versions:\n\n'
141
+ local j
142
+ for (( j=0; j<count; j++ )); do
143
+ printf ' %d) %s\n' $(( j + 1 )) "${PICKER_LABELS[$j]}"
144
+ done
145
+ printf '\n'
146
+
147
+ local choice
148
+ while true; do
149
+ printf 'Enter number (1-%d), or q to quit: ' "$count"
150
+ IFS= read -r choice
151
+ if [ "$choice" = "q" ] || [ "$choice" = "Q" ]; then
152
+ return 2
153
+ fi
154
+ if printf '%s' "$choice" | grep -qE '^[0-9]+$'; then
155
+ if [ "$choice" -ge 1 ] && [ "$choice" -le "$count" ]; then
156
+ local idx=$(( choice - 1 ))
157
+ PICKED_VERSION="$(printf '%s' "${NODE_RELEASES[$idx]}" | cut -d'|' -f1)"
158
+ return 0
159
+ fi
160
+ fi
161
+ printf 'Invalid selection. Please enter a number between 1 and %d.\n' "$count" >&2
162
+ done
163
+ }
@@ -0,0 +1,25 @@
1
+ #!/usr/bin/env bash
2
+ # progress.sh — Step progress display helpers
3
+ # Sourced by install.sh; not executed directly.
4
+ #
5
+ # Functions:
6
+ # step_pending <label> — print "[ ] <label>" to stdout
7
+ # step_running <label> — print "[→] <label>" to stdout
8
+ # step_done <label> — print "[✓] <label>" to stdout
9
+ # step_failed <label> — print "[✗] <label>" to stderr
10
+
11
+ step_pending() {
12
+ printf '[ ] %s\n' "$1"
13
+ }
14
+
15
+ step_running() {
16
+ printf '[→] %s\n' "$1"
17
+ }
18
+
19
+ step_done() {
20
+ printf '[✓] %s\n' "$1"
21
+ }
22
+
23
+ step_failed() {
24
+ printf '[✗] %s\n' "$1" >&2
25
+ }
package/package.json ADDED
@@ -0,0 +1,67 @@
1
+ {
2
+ "name": "easy-devops",
3
+ "version": "0.1.0",
4
+ "description": "A unified DevOps management tool with CLI and web dashboard for managing Nginx, SSL certificates, and Node.js on Linux and Windows servers.",
5
+ "keywords": [
6
+ "devops",
7
+ "nginx",
8
+ "ssl",
9
+ "certbot",
10
+ "letsencrypt",
11
+ "nodejs",
12
+ "dashboard",
13
+ "cli",
14
+ "server-management",
15
+ "reverse-proxy",
16
+ "certificate-management",
17
+ "sysadmin"
18
+ ],
19
+ "author": {
20
+ "name": "Omar Farghaly",
21
+ "url": "https://github.com/omar00050"
22
+ },
23
+ "license": "MIT",
24
+ "repository": {
25
+ "type": "git",
26
+ "url": "git+https://github.com/omar00050/Easy-DevOps.git"
27
+ },
28
+ "bugs": {
29
+ "url": "https://github.com/omar00050/Easy-DevOps/issues"
30
+ },
31
+ "homepage": "https://github.com/omar00050/Easy-DevOps#readme",
32
+ "type": "module",
33
+ "main": "cli/index.js",
34
+ "bin": {
35
+ "easy-devops": "cli/index.js"
36
+ },
37
+ "files": [
38
+ "cli/",
39
+ "core/",
40
+ "dashboard/",
41
+ "lib/",
42
+ "data/.gitkeep",
43
+ "install.bat",
44
+ "install.ps1",
45
+ "install.sh"
46
+ ],
47
+ "scripts": {
48
+ "start": "node cli/index.js",
49
+ "test": "echo \" no test specified\"",
50
+ "dashboard": "node dashboard/server.js",
51
+ "system-info": "node cli/index.js system-info"
52
+ },
53
+ "engines": {
54
+ "node": ">=18.0.0"
55
+ },
56
+ "dependencies": {
57
+ "chalk": "^5.3.0",
58
+ "cli-table3": "^0.6.5",
59
+ "ejs": "^5.0.1",
60
+ "express": "^5.2.1",
61
+ "express-session": "^1.17.3",
62
+ "good.db": "^2.4.6",
63
+ "inquirer": "^9.2.12",
64
+ "ora": "^7.0.1",
65
+ "socket.io": "^4.8.3"
66
+ }
67
+ }