@fdm-monster/server 2.0.0 → 2.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.template +2 -0
- package/.yarn/install-state.gz +0 -0
- package/README.md +22 -3
- package/RELEASE_NOTES.MD +38 -0
- package/dist/constants/authorization.constants.js +12 -3
- package/dist/constants/authorization.constants.js.map +1 -1
- package/dist/constants/server-settings.constants.js +4 -2
- package/dist/constants/server-settings.constants.js.map +1 -1
- package/dist/container.js +2 -0
- package/dist/container.js.map +1 -1
- package/dist/container.tokens.js +1 -0
- package/dist/container.tokens.js.map +1 -1
- package/dist/controllers/file-storage.controller.js +90 -19
- package/dist/controllers/file-storage.controller.js.map +1 -1
- package/dist/controllers/printer-maintenance-log.controller.js +174 -0
- package/dist/controllers/printer-maintenance-log.controller.js.map +1 -0
- package/dist/controllers/settings.controller.js +70 -2
- package/dist/controllers/settings.controller.js.map +1 -1
- package/dist/controllers/slicer-compat.controller.js +4 -0
- package/dist/controllers/slicer-compat.controller.js.map +1 -1
- package/dist/data-source.js +8 -8
- package/dist/data-source.js.map +1 -1
- package/dist/entities/index.js +4 -0
- package/dist/entities/index.js.map +1 -1
- package/dist/entities/print-job.entity.js +5 -1
- package/dist/entities/print-job.entity.js.map +1 -1
- package/dist/entities/printer-maintenance-log.entity.js +142 -0
- package/dist/entities/printer-maintenance-log.entity.js.map +1 -0
- package/dist/entities/printer.entity.js +2 -1
- package/dist/entities/printer.entity.js.map +1 -1
- package/dist/entities/settings.entity.js.map +1 -1
- package/dist/handlers/logging/file-logging.transport.js +2 -2
- package/dist/handlers/logging/file-logging.transport.js.map +1 -1
- package/dist/index.js +11 -5
- package/dist/index.js.map +1 -1
- package/dist/middleware/slicer-api-key.middleware.js +29 -0
- package/dist/middleware/slicer-api-key.middleware.js.map +1 -0
- package/dist/migrations/1767909428129-AddPrinterMaintenanceLog.js +52 -0
- package/dist/migrations/1767909428129-AddPrinterMaintenanceLog.js.map +1 -0
- package/dist/server.constants.js +13 -9
- package/dist/server.constants.js.map +1 -1
- package/dist/server.core.js +7 -4
- package/dist/server.core.js.map +1 -1
- package/dist/server.env.js +13 -32
- package/dist/server.env.js.map +1 -1
- package/dist/server.host.js +1 -1
- package/dist/server.host.js.map +1 -1
- package/dist/services/bambu/bambu-ftp.adapter.js +1 -1
- package/dist/services/bambu/bambu-ftp.adapter.js.map +1 -1
- package/dist/services/core/client-bundle.service.js +10 -11
- package/dist/services/core/client-bundle.service.js.map +1 -1
- package/dist/services/core/config.service.js +3 -5
- package/dist/services/core/config.service.js.map +1 -1
- package/dist/services/core/logs-manager.service.js +9 -10
- package/dist/services/core/logs-manager.service.js.map +1 -1
- package/dist/services/core/multer.service.js +2 -2
- package/dist/services/core/multer.service.js.map +1 -1
- package/dist/services/core/yaml.service.js +23 -3
- package/dist/services/core/yaml.service.js.map +1 -1
- package/dist/services/file-storage.service.js +4 -3
- package/dist/services/file-storage.service.js.map +1 -1
- package/dist/services/interfaces/printer-maintenance-log.dto.js +6 -0
- package/dist/services/interfaces/printer-maintenance-log.dto.js.map +1 -0
- package/dist/services/interfaces/printer.dto.js.map +1 -1
- package/dist/services/orm/printer-maintenance-log.service.js +151 -0
- package/dist/services/orm/printer-maintenance-log.service.js.map +1 -0
- package/dist/services/orm/printer.service.js +8 -2
- package/dist/services/orm/printer.service.js.map +1 -1
- package/dist/services/orm/settings.service.js +9 -2
- package/dist/services/orm/settings.service.js.map +1 -1
- package/dist/services/typeorm/typeorm.service.js +5 -5
- package/dist/services/typeorm/typeorm.service.js.map +1 -1
- package/dist/services/validators/printer-maintenance-log.validation.js +41 -0
- package/dist/services/validators/printer-maintenance-log.validation.js.map +1 -0
- package/dist/services/validators/printer-service.validation.js +2 -3
- package/dist/services/validators/printer-service.validation.js.map +1 -1
- package/dist/services/validators/settings-service.validation.js +23 -4
- package/dist/services/validators/settings-service.validation.js.map +1 -1
- package/dist/services/validators/yaml-service.validation.js +2 -0
- package/dist/services/validators/yaml-service.validation.js.map +1 -1
- package/dist/shared/runtime-settings.migration.js +10 -0
- package/dist/shared/runtime-settings.migration.js.map +1 -1
- package/dist/state/settings.store.js +38 -5
- package/dist/state/settings.store.js.map +1 -1
- package/dist/utils/env.utils.js +5 -4
- package/dist/utils/env.utils.js.map +1 -1
- package/dist/utils/fs.utils.js +37 -11
- package/dist/utils/fs.utils.js.map +1 -1
- package/dist/utils/swagger/swagger.js +1 -1
- package/dist/utils/swagger/swagger.js.map +1 -1
- package/install.sh +559 -0
- package/package.json +6 -6
package/install.sh
ADDED
|
@@ -0,0 +1,559 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# FDM Monster One-Click Installer for Linux
|
|
3
|
+
# Usage: curl -fsSL https://raw.githubusercontent.com/fdm-monster/fdm-monster/main/install.sh | bash
|
|
4
|
+
|
|
5
|
+
set -e
|
|
6
|
+
|
|
7
|
+
# Colors
|
|
8
|
+
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; BLUE='\033[0;34m'; NC='\033[0m'
|
|
9
|
+
|
|
10
|
+
# Configuration
|
|
11
|
+
CLI_VERSION="1.0.4"
|
|
12
|
+
NODE_VERSION="24.12.0"
|
|
13
|
+
NPM_PACKAGE="@fdm-monster/server"
|
|
14
|
+
INSTALL_DIR="$HOME/.fdm-monster"
|
|
15
|
+
DATA_DIR="$HOME/.fdm-monster-data"
|
|
16
|
+
DEFAULT_PORT=4000
|
|
17
|
+
INSTALL_SCRIPT_URL="https://raw.githubusercontent.com/fdm-monster/fdm-monster/main/install.sh"
|
|
18
|
+
|
|
19
|
+
# Helper functions
|
|
20
|
+
print_banner() {
|
|
21
|
+
echo -e "${BLUE}"
|
|
22
|
+
cat << "EOF"
|
|
23
|
+
___________ __ ___ __ ___ __
|
|
24
|
+
/ ____/ __ \/ |/ / / |/ /___ ____ _____/ /____ _____
|
|
25
|
+
/ /_ / / / / /|_/ / / /|_/ / __ \/ __ \/ ___/ __/ _ \/ ___/
|
|
26
|
+
/ __/ / /_/ / / / / / / / / /_/ / / / (__ ) /_/ __/ /
|
|
27
|
+
/_/ /_____/_/ /_/ /_/ /_/\____/_/ /_/____/\__/\___/_/
|
|
28
|
+
|
|
29
|
+
EOF
|
|
30
|
+
echo -e "${NC}${GREEN}FDM Monster One-Click Installer${NC}\n${BLUE}https://fdm-monster.net${NC}\n"
|
|
31
|
+
return 0
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
print_success() {
|
|
35
|
+
local message="$1"
|
|
36
|
+
echo -e "${GREEN}✓${NC} $message"
|
|
37
|
+
return 0
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
print_error() {
|
|
41
|
+
local message="$1"
|
|
42
|
+
echo -e "${RED}✗${NC} $message"
|
|
43
|
+
return 0
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
print_warning() {
|
|
47
|
+
local message="$1"
|
|
48
|
+
echo -e "${YELLOW}!${NC} $message"
|
|
49
|
+
return 0
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
print_info() {
|
|
53
|
+
local message="$1"
|
|
54
|
+
echo -e "${BLUE}ℹ${NC} $message"
|
|
55
|
+
return 0
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
check_root() {
|
|
59
|
+
if [[ "$EUID" -eq 0 ]]; then
|
|
60
|
+
print_error "Do not run as root"
|
|
61
|
+
exit 1
|
|
62
|
+
fi
|
|
63
|
+
return 0
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
detect_platform() {
|
|
67
|
+
OS=$(uname -s | tr '[:upper:]' '[:lower:]')
|
|
68
|
+
ARCH=$(uname -m)
|
|
69
|
+
|
|
70
|
+
[[ ! "$OS" =~ ^(linux|darwin) ]] && { print_error "Unsupported OS: $OS"; exit 1; }
|
|
71
|
+
OS="linux"
|
|
72
|
+
|
|
73
|
+
case $ARCH in
|
|
74
|
+
x86_64|amd64) ARCH="x64" ;;
|
|
75
|
+
aarch64|arm64) ARCH="arm64" ;;
|
|
76
|
+
armv7l) ARCH="armv7l" ;;
|
|
77
|
+
*) print_error "Unsupported architecture: $ARCH"; exit 1 ;;
|
|
78
|
+
esac
|
|
79
|
+
|
|
80
|
+
print_success "Detected platform: $OS/$ARCH"
|
|
81
|
+
return 0
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
install_nodejs() {
|
|
85
|
+
print_info "Installing Node.js $NODE_VERSION..."
|
|
86
|
+
|
|
87
|
+
local NODE_URL="https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-${OS}-${ARCH}.tar.xz"
|
|
88
|
+
local NODE_DIR="$INSTALL_DIR/nodejs"
|
|
89
|
+
|
|
90
|
+
mkdir -p "$NODE_DIR"
|
|
91
|
+
curl -fsSL "$NODE_URL" | tar -xJ -C "$NODE_DIR" --strip-components=1
|
|
92
|
+
|
|
93
|
+
export PATH="$NODE_DIR/bin:$PATH"
|
|
94
|
+
|
|
95
|
+
print_success "Node.js $NODE_VERSION installed"
|
|
96
|
+
return 0
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
ensure_nodejs() {
|
|
100
|
+
if command -v node &> /dev/null; then
|
|
101
|
+
local CURRENT_VERSION=$(node -v | cut -d'v' -f2 | cut -d'.' -f1)
|
|
102
|
+
if [[ "$CURRENT_VERSION" -ge 22 ]]; then
|
|
103
|
+
print_success "Node.js $(node -v) detected"
|
|
104
|
+
return 0
|
|
105
|
+
fi
|
|
106
|
+
print_warning "Node.js $CURRENT_VERSION too old, installing Node.js 24..."
|
|
107
|
+
fi
|
|
108
|
+
|
|
109
|
+
install_nodejs
|
|
110
|
+
|
|
111
|
+
# Persist PATH for future sessions
|
|
112
|
+
local SHELL_RC="$HOME/.bashrc"
|
|
113
|
+
[[ -f "$HOME/.zshrc" ]] && SHELL_RC="$HOME/.zshrc"
|
|
114
|
+
grep -q "$INSTALL_DIR/nodejs/bin" "$SHELL_RC" 2>/dev/null || \
|
|
115
|
+
echo "export PATH=\"$INSTALL_DIR/nodejs/bin:\$PATH\"" >> "$SHELL_RC"
|
|
116
|
+
return 0
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
setup_yarn() {
|
|
120
|
+
print_info "Setting up Yarn via corepack..."
|
|
121
|
+
|
|
122
|
+
# Enable corepack
|
|
123
|
+
corepack enable
|
|
124
|
+
|
|
125
|
+
# Prepare yarn latest
|
|
126
|
+
corepack prepare yarn@stable --activate
|
|
127
|
+
|
|
128
|
+
print_success "Yarn $(yarn --version) ready"
|
|
129
|
+
return 0
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
install_fdm_monster() {
|
|
133
|
+
print_info "Installing $NPM_PACKAGE..."
|
|
134
|
+
|
|
135
|
+
mkdir -p "$INSTALL_DIR" "$DATA_DIR/media" "$DATA_DIR/database"
|
|
136
|
+
cd "$INSTALL_DIR"
|
|
137
|
+
|
|
138
|
+
# Create package.json if it doesn't exist
|
|
139
|
+
if [[ ! -f "package.json" ]]; then
|
|
140
|
+
cat > package.json << EOF
|
|
141
|
+
{
|
|
142
|
+
"name": "fdm-monster-install",
|
|
143
|
+
"private": true,
|
|
144
|
+
"dependencies": {}
|
|
145
|
+
}
|
|
146
|
+
EOF
|
|
147
|
+
fi
|
|
148
|
+
|
|
149
|
+
# Install the package
|
|
150
|
+
YARN_NODE_LINKER=node-modules yarn add "$NPM_PACKAGE"
|
|
151
|
+
|
|
152
|
+
# Create .env file in install dir if it doesn't exist
|
|
153
|
+
local ENV_FILE="$INSTALL_DIR/.env"
|
|
154
|
+
if [[ ! -f "$ENV_FILE" ]]; then
|
|
155
|
+
touch "$ENV_FILE"
|
|
156
|
+
fi
|
|
157
|
+
|
|
158
|
+
print_success "$NPM_PACKAGE installed"
|
|
159
|
+
return 0
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
create_systemd_service() {
|
|
163
|
+
if ! command -v systemctl &> /dev/null; then
|
|
164
|
+
print_warning "systemd not available, service won't auto-start on boot"
|
|
165
|
+
return
|
|
166
|
+
fi
|
|
167
|
+
|
|
168
|
+
print_info "Creating systemd service..."
|
|
169
|
+
|
|
170
|
+
local SERVICE_FILE="/etc/systemd/system/fdm-monster.service"
|
|
171
|
+
sudo tee "$SERVICE_FILE" > /dev/null << EOF
|
|
172
|
+
[Unit]
|
|
173
|
+
Description=FDM Monster - 3D Printer Farm Manager
|
|
174
|
+
After=network.target
|
|
175
|
+
|
|
176
|
+
[Service]
|
|
177
|
+
Type=simple
|
|
178
|
+
User=$USER
|
|
179
|
+
WorkingDirectory=$DATA_DIR
|
|
180
|
+
Environment="NODE_ENV=development"
|
|
181
|
+
Environment="SERVER_PORT=$DEFAULT_PORT"
|
|
182
|
+
Environment="ENV_FILE=$INSTALL_DIR/.env"
|
|
183
|
+
Environment="DATABASE_PATH=$DATA_DIR/database"
|
|
184
|
+
Environment="MEDIA_PATH=$DATA_DIR/media"
|
|
185
|
+
ExecStart=$INSTALL_DIR/nodejs/bin/node $INSTALL_DIR/node_modules/$NPM_PACKAGE/dist/index.js
|
|
186
|
+
Restart=always
|
|
187
|
+
RestartSec=10
|
|
188
|
+
|
|
189
|
+
[Install]
|
|
190
|
+
WantedBy=multi-user.target
|
|
191
|
+
EOF
|
|
192
|
+
|
|
193
|
+
sudo systemctl daemon-reload
|
|
194
|
+
sudo systemctl enable fdm-monster
|
|
195
|
+
sudo systemctl start fdm-monster
|
|
196
|
+
|
|
197
|
+
print_success "systemd service created and started"
|
|
198
|
+
return 0
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
create_cli_wrapper() {
|
|
202
|
+
print_info "Creating CLI wrapper..."
|
|
203
|
+
|
|
204
|
+
local BIN_DIR="$HOME/.local/bin"
|
|
205
|
+
mkdir -p "$BIN_DIR"
|
|
206
|
+
|
|
207
|
+
cp "$0" "$BIN_DIR/fdm-monster" 2>/dev/null || curl -fsSL "$INSTALL_SCRIPT_URL" -o "$BIN_DIR/fdm-monster"
|
|
208
|
+
chmod +x "$BIN_DIR/fdm-monster"
|
|
209
|
+
|
|
210
|
+
cp "$BIN_DIR/fdm-monster" "$BIN_DIR/fdmm"
|
|
211
|
+
chmod +x "$BIN_DIR/fdmm"
|
|
212
|
+
|
|
213
|
+
if [[ ":$PATH:" != *":$BIN_DIR:"* ]]; then
|
|
214
|
+
local SHELL_RC="$HOME/.bashrc"
|
|
215
|
+
[[ -f "$HOME/.zshrc" ]] && SHELL_RC="$HOME/.zshrc"
|
|
216
|
+
|
|
217
|
+
echo "export PATH=\"\$PATH:$BIN_DIR\"" >> "$SHELL_RC"
|
|
218
|
+
|
|
219
|
+
print_success "CLI installed! To use immediately, copy and run:"
|
|
220
|
+
echo ""
|
|
221
|
+
echo -e "\033[1;32m export PATH=\"\$PATH:$BIN_DIR\"\033[0m"
|
|
222
|
+
echo ""
|
|
223
|
+
print_info "(Or restart your terminal)"
|
|
224
|
+
else
|
|
225
|
+
print_success "CLI created at $BIN_DIR/fdm-monster (alias: fdmm)"
|
|
226
|
+
fi
|
|
227
|
+
return 0
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
# CLI command handler
|
|
231
|
+
handle_command() {
|
|
232
|
+
local command_arg="$1"
|
|
233
|
+
case "$command_arg" in
|
|
234
|
+
start)
|
|
235
|
+
if command -v systemctl &> /dev/null; then
|
|
236
|
+
sudo systemctl start fdm-monster
|
|
237
|
+
else
|
|
238
|
+
cd "$DATA_DIR"
|
|
239
|
+
nohup "$INSTALL_DIR/nodejs/bin/node" "$INSTALL_DIR/node_modules/$NPM_PACKAGE/dist/index.js" > "$DATA_DIR/media/logs/fdm-monster.log" 2>&1 &
|
|
240
|
+
echo "FDM Monster started (PID: $!)"
|
|
241
|
+
fi
|
|
242
|
+
;;
|
|
243
|
+
stop)
|
|
244
|
+
if command -v systemctl &> /dev/null; then
|
|
245
|
+
sudo systemctl stop fdm-monster
|
|
246
|
+
else
|
|
247
|
+
pkill -f "$NPM_PACKAGE/dist/index.js" || echo "FDM Monster not running"
|
|
248
|
+
fi
|
|
249
|
+
;;
|
|
250
|
+
restart)
|
|
251
|
+
if command -v systemctl &> /dev/null; then
|
|
252
|
+
sudo systemctl restart fdm-monster
|
|
253
|
+
else
|
|
254
|
+
$0 stop && sleep 2 && $0 start
|
|
255
|
+
fi
|
|
256
|
+
;;
|
|
257
|
+
status)
|
|
258
|
+
if command -v systemctl &> /dev/null; then
|
|
259
|
+
sudo systemctl status fdm-monster
|
|
260
|
+
else
|
|
261
|
+
if pgrep -f "$NPM_PACKAGE/dist/index.js" > /dev/null; then
|
|
262
|
+
print_success "FDM Monster is running (PID: $(pgrep -f "$NPM_PACKAGE/dist/index.js"))"
|
|
263
|
+
if curl -s "http://localhost:$DEFAULT_PORT" > /dev/null 2>&1; then
|
|
264
|
+
print_success "Service is responding at http://localhost:$DEFAULT_PORT"
|
|
265
|
+
else
|
|
266
|
+
print_warning "Process is running but not responding on port $DEFAULT_PORT"
|
|
267
|
+
fi
|
|
268
|
+
else
|
|
269
|
+
print_error "FDM Monster is not running"
|
|
270
|
+
exit 1
|
|
271
|
+
fi
|
|
272
|
+
fi
|
|
273
|
+
;;
|
|
274
|
+
logs)
|
|
275
|
+
if command -v systemctl &> /dev/null; then
|
|
276
|
+
journalctl -u fdm-monster -f
|
|
277
|
+
else
|
|
278
|
+
tail -f "$DATA_DIR/media/logs/fdm-monster.log"
|
|
279
|
+
fi
|
|
280
|
+
;;
|
|
281
|
+
upgrade)
|
|
282
|
+
local TARGET_VERSION="$2"
|
|
283
|
+
local VERSION_DISPLAY="latest version"
|
|
284
|
+
|
|
285
|
+
# Validate version if specified
|
|
286
|
+
if [[ -n "$TARGET_VERSION" ]]; then
|
|
287
|
+
local MAJOR_VERSION=$(echo "$TARGET_VERSION" | cut -d'.' -f1)
|
|
288
|
+
if [[ "$MAJOR_VERSION" =~ ^[0-9]+$ ]] && [[ "$MAJOR_VERSION" -lt 2 ]]; then
|
|
289
|
+
print_error "Cannot upgrade to version $TARGET_VERSION - minimum supported version is 2.0.0"
|
|
290
|
+
exit 1
|
|
291
|
+
fi
|
|
292
|
+
VERSION_DISPLAY="version $TARGET_VERSION"
|
|
293
|
+
fi
|
|
294
|
+
|
|
295
|
+
print_info "Upgrading FDM Monster to $VERSION_DISPLAY..."
|
|
296
|
+
$0 stop
|
|
297
|
+
cd "$INSTALL_DIR"
|
|
298
|
+
|
|
299
|
+
# Install package with or without version
|
|
300
|
+
if [[ -n "$TARGET_VERSION" ]]; then
|
|
301
|
+
YARN_NODE_LINKER=node-modules yarn add "$NPM_PACKAGE@$TARGET_VERSION"
|
|
302
|
+
else
|
|
303
|
+
YARN_NODE_LINKER=node-modules yarn add "$NPM_PACKAGE"
|
|
304
|
+
fi
|
|
305
|
+
|
|
306
|
+
# Recreate systemd service with updated configuration
|
|
307
|
+
create_systemd_service
|
|
308
|
+
|
|
309
|
+
# Get and display installed version
|
|
310
|
+
local INSTALLED_VERSION=$(node -p "require('./node_modules/$NPM_PACKAGE/package.json').version" 2>/dev/null || echo "unknown")
|
|
311
|
+
print_success "Upgraded to version $INSTALLED_VERSION"
|
|
312
|
+
;;
|
|
313
|
+
backup)
|
|
314
|
+
local BACKUP_DIR="$HOME/.fdm-monster-backups"
|
|
315
|
+
local TIMESTAMP=$(date +%Y%m%d-%H%M%S)
|
|
316
|
+
local BACKUP_FILE="$BACKUP_DIR/fdm-monster-$TIMESTAMP.tar.gz"
|
|
317
|
+
|
|
318
|
+
mkdir -p "$BACKUP_DIR"
|
|
319
|
+
|
|
320
|
+
if [[ ! -d "$DATA_DIR" ]]; then
|
|
321
|
+
print_error "Data directory does not exist: $DATA_DIR"
|
|
322
|
+
exit 1
|
|
323
|
+
fi
|
|
324
|
+
|
|
325
|
+
print_info "Backing up FDM Monster data..."
|
|
326
|
+
tar -czf "$BACKUP_FILE" -C "$(dirname "$DATA_DIR")" "$(basename "$DATA_DIR")" 2>/dev/null
|
|
327
|
+
|
|
328
|
+
if [[ $? -eq 0 ]]; then
|
|
329
|
+
local SIZE=$(du -h "$BACKUP_FILE" | cut -f1)
|
|
330
|
+
print_success "Backup created: $BACKUP_FILE ($SIZE)"
|
|
331
|
+
else
|
|
332
|
+
print_error "Backup failed"
|
|
333
|
+
exit 1
|
|
334
|
+
fi
|
|
335
|
+
;;
|
|
336
|
+
update-cli)
|
|
337
|
+
local CUSTOM_URL="$2"
|
|
338
|
+
local UPDATE_URL="${CUSTOM_URL:-$INSTALL_SCRIPT_URL}"
|
|
339
|
+
|
|
340
|
+
print_info "Updating FDM Monster CLI (current: v$CLI_VERSION)..."
|
|
341
|
+
if [[ -n "$CUSTOM_URL" ]]; then
|
|
342
|
+
print_info "Using custom URL: $CUSTOM_URL"
|
|
343
|
+
fi
|
|
344
|
+
|
|
345
|
+
local BIN_DIR="$HOME/.local/bin"
|
|
346
|
+
local TEMP_FILE="/tmp/fdm-monster-cli-update.sh"
|
|
347
|
+
|
|
348
|
+
curl -fsSL "$UPDATE_URL" -o "$TEMP_FILE"
|
|
349
|
+
|
|
350
|
+
if [[ $? -eq 0 ]]; then
|
|
351
|
+
# Extract new version from downloaded script
|
|
352
|
+
local NEW_VERSION=$(grep '^CLI_VERSION=' "$TEMP_FILE" | cut -d'"' -f2)
|
|
353
|
+
|
|
354
|
+
mv "$TEMP_FILE" "$BIN_DIR/fdm-monster"
|
|
355
|
+
chmod +x "$BIN_DIR/fdm-monster"
|
|
356
|
+
cp "$BIN_DIR/fdm-monster" "$BIN_DIR/fdmm"
|
|
357
|
+
chmod +x "$BIN_DIR/fdmm"
|
|
358
|
+
|
|
359
|
+
if [[ -n "$NEW_VERSION" ]]; then
|
|
360
|
+
print_success "CLI updated successfully to v$NEW_VERSION"
|
|
361
|
+
else
|
|
362
|
+
print_success "CLI updated successfully"
|
|
363
|
+
fi
|
|
364
|
+
else
|
|
365
|
+
print_error "Failed to download CLI update"
|
|
366
|
+
exit 1
|
|
367
|
+
fi
|
|
368
|
+
;;
|
|
369
|
+
version|--version|-v)
|
|
370
|
+
echo "FDM Monster CLI v$CLI_VERSION"
|
|
371
|
+
;;
|
|
372
|
+
install)
|
|
373
|
+
print_banner
|
|
374
|
+
check_root
|
|
375
|
+
detect_platform
|
|
376
|
+
ensure_nodejs
|
|
377
|
+
setup_yarn
|
|
378
|
+
install_fdm_monster
|
|
379
|
+
create_systemd_service
|
|
380
|
+
create_cli_wrapper
|
|
381
|
+
wait_for_service
|
|
382
|
+
print_instructions
|
|
383
|
+
;;
|
|
384
|
+
uninstall)
|
|
385
|
+
print_warning "Uninstalling FDM Monster..."
|
|
386
|
+
$0 stop
|
|
387
|
+
if command -v systemctl &> /dev/null; then
|
|
388
|
+
sudo systemctl disable fdm-monster 2>/dev/null || true
|
|
389
|
+
sudo rm -f /etc/systemd/system/fdm-monster.service
|
|
390
|
+
sudo systemctl daemon-reload
|
|
391
|
+
fi
|
|
392
|
+
|
|
393
|
+
# Remove install directory and CLI
|
|
394
|
+
rm -rf "$INSTALL_DIR"
|
|
395
|
+
rm -f "$HOME/.local/bin/fdm-monster" "$HOME/.local/bin/fdmm"
|
|
396
|
+
|
|
397
|
+
# Ask about data directory
|
|
398
|
+
echo ""
|
|
399
|
+
echo -e "${YELLOW}Do you want to remove the data directory?${NC}"
|
|
400
|
+
echo -e " ${BLUE}Location:${NC} $DATA_DIR"
|
|
401
|
+
echo -e " ${BLUE}Contains:${NC} databases, logs, uploaded files"
|
|
402
|
+
read -p "Remove data directory? [y/N]: " -n 1 -r
|
|
403
|
+
echo ""
|
|
404
|
+
|
|
405
|
+
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
|
406
|
+
rm -rf "$DATA_DIR"
|
|
407
|
+
print_success "FDM Monster uninstalled (including data)"
|
|
408
|
+
else
|
|
409
|
+
print_success "FDM Monster uninstalled (data preserved at $DATA_DIR)"
|
|
410
|
+
fi
|
|
411
|
+
;;
|
|
412
|
+
*)
|
|
413
|
+
echo "FDM Monster CLI v$CLI_VERSION"
|
|
414
|
+
echo ""
|
|
415
|
+
echo "Usage: fdm-monster {install|start|stop|restart|status|logs|upgrade [version]|backup|update-cli [url]|version|uninstall}"
|
|
416
|
+
echo "Alias: fdmm"
|
|
417
|
+
echo ""
|
|
418
|
+
echo "Commands:"
|
|
419
|
+
echo " install - (Re)install FDM Monster"
|
|
420
|
+
echo " start - Start FDM Monster"
|
|
421
|
+
echo " stop - Stop FDM Monster"
|
|
422
|
+
echo " restart - Restart FDM Monster"
|
|
423
|
+
echo " status - Check if FDM Monster is running"
|
|
424
|
+
echo " logs - View logs"
|
|
425
|
+
echo " upgrade [ver] - Upgrade to latest or specified version"
|
|
426
|
+
echo " backup - Backup data directory to ~/.fdm-monster-backups"
|
|
427
|
+
echo " update-cli [url] - Update the CLI tool itself (optionally from custom URL)"
|
|
428
|
+
echo " version - Show CLI version"
|
|
429
|
+
echo " uninstall - Remove FDM Monster"
|
|
430
|
+
echo ""
|
|
431
|
+
echo "Examples:"
|
|
432
|
+
echo " fdmm install # (Re)install FDM Monster"
|
|
433
|
+
echo " fdmm status # Check status"
|
|
434
|
+
echo " fdmm backup # Create backup"
|
|
435
|
+
echo " fdmm upgrade # Upgrade to latest"
|
|
436
|
+
echo " fdmm upgrade 1.2.3 # Upgrade to specific version"
|
|
437
|
+
echo " fdmm update-cli # Update CLI tool from default URL"
|
|
438
|
+
echo " fdmm update-cli https://example.com/cli # Update CLI from custom URL"
|
|
439
|
+
echo " fdmm version # Show CLI version"
|
|
440
|
+
exit 1
|
|
441
|
+
;;
|
|
442
|
+
esac
|
|
443
|
+
|
|
444
|
+
return 0
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
wait_for_service() {
|
|
448
|
+
print_info "Waiting for FDM Monster to start..."
|
|
449
|
+
|
|
450
|
+
for i in {1..10}; do
|
|
451
|
+
if curl -s "http://localhost:$DEFAULT_PORT" > /dev/null 2>&1; then
|
|
452
|
+
print_success "FDM Monster is ready!"
|
|
453
|
+
return 0
|
|
454
|
+
fi
|
|
455
|
+
sleep 1
|
|
456
|
+
done
|
|
457
|
+
|
|
458
|
+
print_warning "Service did not respond within 10 seconds"
|
|
459
|
+
print_info "Checking service status..."
|
|
460
|
+
echo ""
|
|
461
|
+
|
|
462
|
+
if command -v systemctl &> /dev/null; then
|
|
463
|
+
sudo systemctl status fdm-monster --no-pager
|
|
464
|
+
else
|
|
465
|
+
if pgrep -f "$NPM_PACKAGE/dist/index.js" > /dev/null; then
|
|
466
|
+
print_info "Process is running (PID: $(pgrep -f "$NPM_PACKAGE/dist/index.js"))"
|
|
467
|
+
print_info "Service may still be initializing"
|
|
468
|
+
else
|
|
469
|
+
print_error "Process is not running"
|
|
470
|
+
fi
|
|
471
|
+
fi
|
|
472
|
+
|
|
473
|
+
echo ""
|
|
474
|
+
print_info "Check logs with: fdm-monster logs"
|
|
475
|
+
return 0
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
get_network_addresses() {
|
|
479
|
+
# Get all non-loopback IPv4 addresses
|
|
480
|
+
if command -v ip &> /dev/null; then
|
|
481
|
+
ip -4 addr show | grep -oP '(?<=inet\s)\d+(\.\d+){3}' | grep -v '127.0.0.1'
|
|
482
|
+
elif command -v ifconfig &> /dev/null; then
|
|
483
|
+
ifconfig | grep -oP '(?<=inet\s)\d+(\.\d+){3}' | grep -v '127.0.0.1'
|
|
484
|
+
elif command -v hostname &> /dev/null; then
|
|
485
|
+
hostname -I 2>/dev/null | tr ' ' '\n' | grep -v '^$'
|
|
486
|
+
fi
|
|
487
|
+
|
|
488
|
+
return 0
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
print_instructions() {
|
|
492
|
+
echo ""
|
|
493
|
+
echo -e "${GREEN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
|
494
|
+
echo -e "${GREEN} Installation Complete!${NC}"
|
|
495
|
+
echo -e "${GREEN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
|
496
|
+
echo ""
|
|
497
|
+
echo -e " ${BLUE}Access FDM Monster at:${NC}"
|
|
498
|
+
echo -e " ${GREEN}http://localhost:$DEFAULT_PORT${NC}"
|
|
499
|
+
|
|
500
|
+
# Show network addresses if available
|
|
501
|
+
local ADDRESSES=$(get_network_addresses)
|
|
502
|
+
if [[ -n "$ADDRESSES" ]]; then
|
|
503
|
+
while IFS= read -r addr; do
|
|
504
|
+
[[ -n "$addr" ]] && echo -e " ${GREEN}http://$addr:$DEFAULT_PORT${NC}"
|
|
505
|
+
done <<< "$ADDRESSES"
|
|
506
|
+
fi
|
|
507
|
+
|
|
508
|
+
echo ""
|
|
509
|
+
echo -e " ${BLUE}Management commands:${NC} ${YELLOW}(use 'fdm-monster' or 'fdmm' - CLI v$CLI_VERSION)${NC}"
|
|
510
|
+
echo -e " ${YELLOW}fdmm install${NC} - (Re)install FDM Monster"
|
|
511
|
+
echo -e " ${YELLOW}fdmm start${NC} - Start FDM Monster"
|
|
512
|
+
echo -e " ${YELLOW}fdmm stop${NC} - Stop FDM Monster"
|
|
513
|
+
echo -e " ${YELLOW}fdmm restart${NC} - Restart FDM Monster"
|
|
514
|
+
echo -e " ${YELLOW}fdmm status${NC} - Check if FDM Monster is running"
|
|
515
|
+
echo -e " ${YELLOW}fdmm logs${NC} - View logs"
|
|
516
|
+
echo -e " ${YELLOW}fdmm upgrade [version]${NC} - Upgrade to latest or specified version"
|
|
517
|
+
echo -e " ${YELLOW}fdmm backup${NC} - Backup data directory"
|
|
518
|
+
echo -e " ${YELLOW}fdmm update-cli [url]${NC} - Update CLI tool (optionally from custom URL)"
|
|
519
|
+
echo -e " ${YELLOW}fdmm version${NC} - Show CLI version"
|
|
520
|
+
echo -e " ${YELLOW}fdmm uninstall${NC} - Remove FDM Monster"
|
|
521
|
+
echo ""
|
|
522
|
+
echo -e " ${BLUE}Data directory:${NC} $DATA_DIR"
|
|
523
|
+
echo -e " ${BLUE}Install directory:${NC} $INSTALL_DIR"
|
|
524
|
+
echo ""
|
|
525
|
+
echo -e " ${BLUE}Documentation:${NC} https://docs.fdm-monster.net"
|
|
526
|
+
echo -e " ${BLUE}Discord:${NC} https://discord.gg/mwA8uP8CMc"
|
|
527
|
+
echo ""
|
|
528
|
+
echo -e "${GREEN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
|
529
|
+
echo ""
|
|
530
|
+
|
|
531
|
+
return 0
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
# Main function - handles both install and CLI commands
|
|
535
|
+
main() {
|
|
536
|
+
# If called with a command argument, handle it as CLI
|
|
537
|
+
if [[ $# -gt 0 ]]; then
|
|
538
|
+
handle_command "$@"
|
|
539
|
+
exit $?
|
|
540
|
+
fi
|
|
541
|
+
|
|
542
|
+
# Otherwise, run installer
|
|
543
|
+
print_banner
|
|
544
|
+
check_root
|
|
545
|
+
detect_platform
|
|
546
|
+
ensure_nodejs
|
|
547
|
+
setup_yarn
|
|
548
|
+
install_fdm_monster
|
|
549
|
+
create_systemd_service
|
|
550
|
+
create_cli_wrapper
|
|
551
|
+
wait_for_service
|
|
552
|
+
print_instructions
|
|
553
|
+
|
|
554
|
+
return 0
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
# Run main function with all arguments
|
|
558
|
+
main "$@"
|
|
559
|
+
|
package/package.json
CHANGED
|
@@ -6,10 +6,10 @@
|
|
|
6
6
|
},
|
|
7
7
|
"author": "David Zwart",
|
|
8
8
|
"license": "AGPL-3.0-or-later",
|
|
9
|
-
"version": "2.0.
|
|
9
|
+
"version": "2.0.3",
|
|
10
10
|
"bin": {
|
|
11
|
-
"fdm-monster": "dist/index.js",
|
|
12
|
-
"fdmm": "dist/index.js"
|
|
11
|
+
"fdm-monster-server": "dist/index.js",
|
|
12
|
+
"fdmm-server": "dist/index.js"
|
|
13
13
|
},
|
|
14
14
|
"description": "FDM Monster is a bulk OctoPrint, Klipper, PrusaLink and BambuLab manager to set up, configure and monitor 3D printers. Our aim is to provide neat overview over your farm.",
|
|
15
15
|
"main": "dist/index.js",
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
"tr46": "6.0.0"
|
|
61
61
|
},
|
|
62
62
|
"dependencies": {
|
|
63
|
-
"@fdm-monster/client-next": "2.
|
|
63
|
+
"@fdm-monster/client-next": "2.2.0",
|
|
64
64
|
"@octokit/plugin-throttling": "8.2.0",
|
|
65
65
|
"@sentry/node": "10.32.1",
|
|
66
66
|
"adm-zip": "0.5.16",
|
|
@@ -99,7 +99,7 @@
|
|
|
99
99
|
"uuid": "11.1.0",
|
|
100
100
|
"winston": "3.19.0",
|
|
101
101
|
"winston-loki": "6.1.3",
|
|
102
|
-
"ws": "8.
|
|
102
|
+
"ws": "8.19.0",
|
|
103
103
|
"zod": "3.25.76"
|
|
104
104
|
},
|
|
105
105
|
"devDependencies": {
|
|
@@ -133,7 +133,7 @@
|
|
|
133
133
|
"nock": "13.5.6",
|
|
134
134
|
"openapi3-ts": "4.5.0",
|
|
135
135
|
"selfsigned": "5.4.0",
|
|
136
|
-
"supertest": "7.
|
|
136
|
+
"supertest": "7.2.2",
|
|
137
137
|
"swagger-ui-dist": "5.31.0",
|
|
138
138
|
"ts-node": "10.9.2",
|
|
139
139
|
"tsconfig-paths": "4.2.0",
|