@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.
Files changed (92) hide show
  1. package/.env.template +2 -0
  2. package/.yarn/install-state.gz +0 -0
  3. package/README.md +22 -3
  4. package/RELEASE_NOTES.MD +38 -0
  5. package/dist/constants/authorization.constants.js +12 -3
  6. package/dist/constants/authorization.constants.js.map +1 -1
  7. package/dist/constants/server-settings.constants.js +4 -2
  8. package/dist/constants/server-settings.constants.js.map +1 -1
  9. package/dist/container.js +2 -0
  10. package/dist/container.js.map +1 -1
  11. package/dist/container.tokens.js +1 -0
  12. package/dist/container.tokens.js.map +1 -1
  13. package/dist/controllers/file-storage.controller.js +90 -19
  14. package/dist/controllers/file-storage.controller.js.map +1 -1
  15. package/dist/controllers/printer-maintenance-log.controller.js +174 -0
  16. package/dist/controllers/printer-maintenance-log.controller.js.map +1 -0
  17. package/dist/controllers/settings.controller.js +70 -2
  18. package/dist/controllers/settings.controller.js.map +1 -1
  19. package/dist/controllers/slicer-compat.controller.js +4 -0
  20. package/dist/controllers/slicer-compat.controller.js.map +1 -1
  21. package/dist/data-source.js +8 -8
  22. package/dist/data-source.js.map +1 -1
  23. package/dist/entities/index.js +4 -0
  24. package/dist/entities/index.js.map +1 -1
  25. package/dist/entities/print-job.entity.js +5 -1
  26. package/dist/entities/print-job.entity.js.map +1 -1
  27. package/dist/entities/printer-maintenance-log.entity.js +142 -0
  28. package/dist/entities/printer-maintenance-log.entity.js.map +1 -0
  29. package/dist/entities/printer.entity.js +2 -1
  30. package/dist/entities/printer.entity.js.map +1 -1
  31. package/dist/entities/settings.entity.js.map +1 -1
  32. package/dist/handlers/logging/file-logging.transport.js +2 -2
  33. package/dist/handlers/logging/file-logging.transport.js.map +1 -1
  34. package/dist/index.js +11 -5
  35. package/dist/index.js.map +1 -1
  36. package/dist/middleware/slicer-api-key.middleware.js +29 -0
  37. package/dist/middleware/slicer-api-key.middleware.js.map +1 -0
  38. package/dist/migrations/1767909428129-AddPrinterMaintenanceLog.js +52 -0
  39. package/dist/migrations/1767909428129-AddPrinterMaintenanceLog.js.map +1 -0
  40. package/dist/server.constants.js +13 -9
  41. package/dist/server.constants.js.map +1 -1
  42. package/dist/server.core.js +7 -4
  43. package/dist/server.core.js.map +1 -1
  44. package/dist/server.env.js +13 -32
  45. package/dist/server.env.js.map +1 -1
  46. package/dist/server.host.js +1 -1
  47. package/dist/server.host.js.map +1 -1
  48. package/dist/services/bambu/bambu-ftp.adapter.js +1 -1
  49. package/dist/services/bambu/bambu-ftp.adapter.js.map +1 -1
  50. package/dist/services/core/client-bundle.service.js +10 -11
  51. package/dist/services/core/client-bundle.service.js.map +1 -1
  52. package/dist/services/core/config.service.js +3 -5
  53. package/dist/services/core/config.service.js.map +1 -1
  54. package/dist/services/core/logs-manager.service.js +9 -10
  55. package/dist/services/core/logs-manager.service.js.map +1 -1
  56. package/dist/services/core/multer.service.js +2 -2
  57. package/dist/services/core/multer.service.js.map +1 -1
  58. package/dist/services/core/yaml.service.js +23 -3
  59. package/dist/services/core/yaml.service.js.map +1 -1
  60. package/dist/services/file-storage.service.js +4 -3
  61. package/dist/services/file-storage.service.js.map +1 -1
  62. package/dist/services/interfaces/printer-maintenance-log.dto.js +6 -0
  63. package/dist/services/interfaces/printer-maintenance-log.dto.js.map +1 -0
  64. package/dist/services/interfaces/printer.dto.js.map +1 -1
  65. package/dist/services/orm/printer-maintenance-log.service.js +151 -0
  66. package/dist/services/orm/printer-maintenance-log.service.js.map +1 -0
  67. package/dist/services/orm/printer.service.js +8 -2
  68. package/dist/services/orm/printer.service.js.map +1 -1
  69. package/dist/services/orm/settings.service.js +9 -2
  70. package/dist/services/orm/settings.service.js.map +1 -1
  71. package/dist/services/typeorm/typeorm.service.js +5 -5
  72. package/dist/services/typeorm/typeorm.service.js.map +1 -1
  73. package/dist/services/validators/printer-maintenance-log.validation.js +41 -0
  74. package/dist/services/validators/printer-maintenance-log.validation.js.map +1 -0
  75. package/dist/services/validators/printer-service.validation.js +2 -3
  76. package/dist/services/validators/printer-service.validation.js.map +1 -1
  77. package/dist/services/validators/settings-service.validation.js +23 -4
  78. package/dist/services/validators/settings-service.validation.js.map +1 -1
  79. package/dist/services/validators/yaml-service.validation.js +2 -0
  80. package/dist/services/validators/yaml-service.validation.js.map +1 -1
  81. package/dist/shared/runtime-settings.migration.js +10 -0
  82. package/dist/shared/runtime-settings.migration.js.map +1 -1
  83. package/dist/state/settings.store.js +38 -5
  84. package/dist/state/settings.store.js.map +1 -1
  85. package/dist/utils/env.utils.js +5 -4
  86. package/dist/utils/env.utils.js.map +1 -1
  87. package/dist/utils/fs.utils.js +37 -11
  88. package/dist/utils/fs.utils.js.map +1 -1
  89. package/dist/utils/swagger/swagger.js +1 -1
  90. package/dist/utils/swagger/swagger.js.map +1 -1
  91. package/install.sh +559 -0
  92. 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.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.1.0",
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.18.3",
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.1.4",
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",