devicely 2.1.6 → 2.1.7

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.
@@ -0,0 +1,38 @@
1
+ #!/bin/bash
2
+
3
+ # This script adds QUIET mode to all shell scripts
4
+ # In QUIET mode, only errors and final success/failure are shown
5
+
6
+ add_quiet_mode() {
7
+ local script="$1"
8
+ echo "Processing: $script"
9
+
10
+ # Backup original
11
+ cp "$script" "$script.bak"
12
+
13
+ # Add QUIET mode at the beginning (after shebang)
14
+ sed -i '' '2i\
15
+ # Production mode - minimal logging\
16
+ QUIET_MODE="${DEVICELY_QUIET:-false}"\
17
+ log_info() { [ "$QUIET_MODE" != "true" ] && echo "$@"; }\
18
+ log_success() { echo "$@"; } # Always show success\
19
+ log_error() { echo "$@" >&2; } # Always show errors
20
+ ' "$script"
21
+
22
+ # Replace echo with log_info for non-critical messages
23
+ # Keep ✅ and ❌ messages visible (success/error)
24
+ sed -i '' 's/echo "\(.*[^✅❌].*\)"/log_info "\1"/g' "$script"
25
+
26
+ echo "✓ Updated: $script"
27
+ }
28
+
29
+ # Process main scripts
30
+ for script in connect_ios_usb_multi_final.sh android_device_control.sh ios_device_control.sh; do
31
+ if [ -f "$script" ]; then
32
+ add_quiet_mode "$script"
33
+ fi
34
+ done
35
+
36
+ echo ""
37
+ echo "✅ Scripts updated with QUIET mode"
38
+ echo "To enable: export DEVICELY_QUIET=true"
@@ -0,0 +1,93 @@
1
+ #!/bin/bash
2
+
3
+ # Install UIAutomator2 APKs on Android device
4
+
5
+ DEVICE_ID=$1
6
+
7
+ if [ -z "$DEVICE_ID" ]; then
8
+ echo "Usage: $0 <device_id>"
9
+ echo "Example: $0 100.87.246.132:5555"
10
+ exit 1
11
+ fi
12
+
13
+ echo "🔍 Looking for UIAutomator2 APKs..."
14
+
15
+ # Find APKs
16
+ APK_PATH="$HOME/.appium/node_modules/appium-uiautomator2-driver/node_modules/appium-uiautomator2-server/apks"
17
+
18
+ if [ ! -d "$APK_PATH" ]; then
19
+ echo "❌ UIAutomator2 APKs not found!"
20
+ echo "Please run: appium driver install uiautomator2"
21
+ exit 1
22
+ fi
23
+
24
+ SERVER_APK=$(ls "$APK_PATH"/appium-uiautomator2-server-v*.apk 2>/dev/null | head -1)
25
+ TEST_APK="$APK_PATH/appium-uiautomator2-server-debug-androidTest.apk"
26
+
27
+ if [ -z "$SERVER_APK" ] || [ ! -f "$TEST_APK" ]; then
28
+ echo "❌ APK files not found!"
29
+ exit 1
30
+ fi
31
+
32
+ echo "✅ Found APKs:"
33
+ echo " Server: $SERVER_APK"
34
+ echo " Test: $TEST_APK"
35
+ echo ""
36
+
37
+ # Check if device is connected
38
+ adb -s "$DEVICE_ID" get-state >/dev/null 2>&1
39
+ if [ $? -ne 0 ]; then
40
+ echo "❌ Device $DEVICE_ID not connected!"
41
+ exit 1
42
+ fi
43
+
44
+ echo "📱 Device connected: $DEVICE_ID"
45
+ echo ""
46
+ echo "⚠️ IMPORTANT: On your device, you may see installation prompts."
47
+ echo " Please ALLOW the installation!"
48
+ echo ""
49
+ echo "📦 Installing UIAutomator2 Server..."
50
+
51
+ # Try to install with -g flag to grant all permissions
52
+ adb -s "$DEVICE_ID" install -r -g "$SERVER_APK"
53
+ if [ $? -ne 0 ]; then
54
+ echo ""
55
+ echo "⚠️ Installation failed or was canceled."
56
+ echo ""
57
+ echo "Please make sure:"
58
+ echo " 1. USB debugging is enabled"
59
+ echo " 2. 'Install via USB' is enabled in Developer Options"
60
+ echo " 3. You allowed the installation prompt on the device"
61
+ echo ""
62
+ echo "On Xiaomi/MIUI devices:"
63
+ echo " Settings → Additional Settings → Developer Options"
64
+ echo " → Enable 'Install via USB' AND 'USB debugging (Security settings)'"
65
+ echo ""
66
+ read -p "Press Enter to retry..."
67
+ adb -s "$DEVICE_ID" install -r -g "$SERVER_APK"
68
+ fi
69
+
70
+ echo ""
71
+ echo "📦 Installing UIAutomator2 Test APK..."
72
+
73
+ adb -s "$DEVICE_ID" install -r -g "$TEST_APK"
74
+ if [ $? -ne 0 ]; then
75
+ echo ""
76
+ echo "⚠️ Test APK installation failed."
77
+ read -p "Press Enter to retry..."
78
+ adb -s "$DEVICE_ID" install -r -g "$TEST_APK"
79
+ fi
80
+
81
+ echo ""
82
+ echo "🎉 UIAutomator2 installation complete!"
83
+ echo ""
84
+ echo "Verifying installation..."
85
+ adb -s "$DEVICE_ID" shell pm list packages | grep io.appium.uiautomator2
86
+
87
+ if [ $? -eq 0 ]; then
88
+ echo "✅ UIAutomator2 is now installed!"
89
+ echo "You can now use the 'getLocators' command."
90
+ else
91
+ echo "❌ Verification failed. Please try manual installation."
92
+ fi
93
+
@@ -0,0 +1,220 @@
1
+ #!/bin/bash
2
+ # iOS Device Control - Restart/Shutdown/Status
3
+ # Supports both USB and Wireless devices
4
+
5
+ WDA_PORT=8100
6
+
7
+ show_usage() {
8
+ echo "Usage: $0 [restart|shutdown|status] [device_name|UDID]"
9
+ echo ""
10
+ echo "Commands:"
11
+ echo " restart - Restart the device"
12
+ echo " shutdown - Shutdown the device (USB only)"
13
+ echo " status - Show device status"
14
+ echo ""
15
+ echo "Examples:"
16
+ echo " $0 restart iphone16p"
17
+ echo " $0 status"
18
+ echo " $0 shutdown 00008140-001C24361E41801C"
19
+ exit 1
20
+ }
21
+
22
+ COMMAND=$1
23
+ DEVICE_ID=$2
24
+
25
+ if [ -z "$COMMAND" ]; then
26
+ show_usage
27
+ fi
28
+
29
+ # Load devices.conf
30
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
31
+ DEVICES_CONF="$SCRIPT_DIR/devices.conf"
32
+
33
+ # Find device info
34
+ find_device() {
35
+ local search_term=$1
36
+
37
+ # Check USB devices first
38
+ if command -v idevice_id >/dev/null 2>&1; then
39
+ USB_UDIDS=($(idevice_id -l 2>/dev/null))
40
+ for udid in "${USB_UDIDS[@]}"; do
41
+ if [[ "$udid" == "$search_term"* ]] || [ -z "$search_term" ]; then
42
+ echo "usb|$udid|local"
43
+ return 0
44
+ fi
45
+ # Get device name
46
+ DEV_NAME=$(ideviceinfo -u "$udid" -k DeviceName 2>/dev/null | tr -d '\n')
47
+ if [ "$DEV_NAME" == "$search_term" ]; then
48
+ echo "usb|$udid|local"
49
+ return 0
50
+ fi
51
+ done
52
+ fi
53
+
54
+ # Check wireless devices from config
55
+ if [ -f "$DEVICES_CONF" ]; then
56
+ while IFS=',' read -r name udid ip || [ -n "$name" ]; do
57
+ # Skip comments and empty lines
58
+ [[ "$name" =~ ^#.*$ ]] && continue
59
+ [ -z "$name" ] && continue
60
+
61
+ # Trim whitespace
62
+ name=$(echo "$name" | xargs)
63
+ udid=$(echo "$udid" | xargs)
64
+ ip=$(echo "$ip" | xargs)
65
+
66
+ if [ "$name" == "$search_term" ] || [ "$udid" == "$search_term" ] || [ -z "$search_term" ]; then
67
+ echo "wireless|$udid|$ip"
68
+ return 0
69
+ fi
70
+ done < "$DEVICES_CONF"
71
+ fi
72
+
73
+ echo "not_found||"
74
+ return 1
75
+ }
76
+
77
+ restart_device() {
78
+ local device_info=$(find_device "$DEVICE_ID")
79
+ IFS='|' read -r dev_type udid ip <<< "$device_info"
80
+
81
+ if [ "$dev_type" == "not_found" ]; then
82
+ echo "❌ Device not found: $DEVICE_ID"
83
+ exit 1
84
+ fi
85
+
86
+ echo "🔄 Restarting device: $DEVICE_ID"
87
+
88
+ if [ "$dev_type" == "usb" ]; then
89
+ echo "→ Using USB restart methods..."
90
+
91
+ # Try idevicediagnostics first
92
+ if command -v idevicediagnostics >/dev/null 2>&1; then
93
+ if idevicediagnostics -u "$udid" restart 2>/dev/null; then
94
+ echo "✅ Device restart initiated (idevicediagnostics)"
95
+ return 0
96
+ fi
97
+ fi
98
+
99
+ # Try devicectl (Xcode)
100
+ if command -v xcrun >/dev/null 2>&1; then
101
+ DC_OUT=$(xcrun devicectl device reboot --device "$udid" 2>&1)
102
+ if echo "$DC_OUT" | grep -qi "restart\|reboot\|success" || [ $? -eq 0 ]; then
103
+ echo "✅ Device restart initiated (devicectl)"
104
+ return 0
105
+ fi
106
+ fi
107
+
108
+ echo "❌ All restart methods failed"
109
+ return 1
110
+ else
111
+ # Wireless - use WDA
112
+ echo "→ Using WDA restart (wireless)..."
113
+ R=$(curl -s -X POST "http://${ip}:${WDA_PORT}/wda/device/restart" \
114
+ -H 'Content-Type: application/json' -d '{}' -m 10)
115
+
116
+ if echo "$R" | grep -q '"value"'; then
117
+ echo "✅ Device restart initiated (WDA)"
118
+ return 0
119
+ else
120
+ echo "❌ WDA restart failed"
121
+ return 1
122
+ fi
123
+ fi
124
+ }
125
+
126
+ shutdown_device() {
127
+ local device_info=$(find_device "$DEVICE_ID")
128
+ IFS='|' read -r dev_type udid ip <<< "$device_info"
129
+
130
+ if [ "$dev_type" == "not_found" ]; then
131
+ echo "❌ Device not found: $DEVICE_ID"
132
+ exit 1
133
+ fi
134
+
135
+ if [ "$dev_type" != "usb" ]; then
136
+ echo "❌ Shutdown only supported for USB devices"
137
+ echo " Use 'restart' command for wireless devices"
138
+ exit 1
139
+ fi
140
+
141
+ echo "⚠️ Shutting down device: $DEVICE_ID"
142
+ echo " This will power off the device completely"
143
+
144
+ if command -v idevicediagnostics >/dev/null 2>&1; then
145
+ if idevicediagnostics -u "$udid" shutdown 2>/dev/null; then
146
+ echo "✅ Device shutdown initiated"
147
+ return 0
148
+ fi
149
+ fi
150
+
151
+ echo "❌ Shutdown failed - libimobiledevice not available"
152
+ return 1
153
+ }
154
+
155
+ show_status() {
156
+ echo "📱 Device Status"
157
+ echo ""
158
+
159
+ # USB Devices
160
+ if command -v idevice_id >/dev/null 2>&1; then
161
+ USB_UDIDS=($(idevice_id -l 2>/dev/null))
162
+ if [ ${#USB_UDIDS[@]} -gt 0 ]; then
163
+ echo "USB Devices:"
164
+ for udid in "${USB_UDIDS[@]}"; do
165
+ DEV_NAME=$(ideviceinfo -u "$udid" -k DeviceName 2>/dev/null)
166
+ DEV_VERSION=$(ideviceinfo -u "$udid" -k ProductVersion 2>/dev/null)
167
+ echo " 🔌 $DEV_NAME"
168
+ echo " UDID: $udid"
169
+ echo " iOS: $DEV_VERSION"
170
+ echo ""
171
+ done
172
+ else
173
+ echo "USB Devices: None"
174
+ echo ""
175
+ fi
176
+ else
177
+ echo "⚠️ libimobiledevice not installed (USB detection disabled)"
178
+ echo " Install: brew install libimobiledevice"
179
+ echo ""
180
+ fi
181
+
182
+ # Wireless Devices
183
+ if [ -f "$DEVICES_CONF" ]; then
184
+ echo "Wireless Devices (from config):"
185
+ while IFS=',' read -r name udid ip || [ -n "$name" ]; do
186
+ [[ "$name" =~ ^#.*$ ]] && continue
187
+ [ -z "$name" ] && continue
188
+
189
+ name=$(echo "$name" | xargs)
190
+ ip=$(echo "$ip" | xargs)
191
+
192
+ # Check connectivity
193
+ if curl -s --connect-timeout 2 "http://${ip}:${WDA_PORT}/status" | grep -q '"state"'; then
194
+ echo " 📡 $name ✅ Online"
195
+ else
196
+ echo " 📡 $name ⚠️ Offline"
197
+ fi
198
+ echo " IP: $ip"
199
+ echo ""
200
+ done < "$DEVICES_CONF"
201
+ else
202
+ echo "No devices.conf found"
203
+ fi
204
+ }
205
+
206
+ case "$COMMAND" in
207
+ restart|reboot)
208
+ restart_device
209
+ ;;
210
+ shutdown|poweroff)
211
+ shutdown_device
212
+ ;;
213
+ status)
214
+ show_status
215
+ ;;
216
+ *)
217
+ echo "❌ Unknown command: $COMMAND"
218
+ show_usage
219
+ ;;
220
+ esac
@@ -0,0 +1,59 @@
1
+ #!/bin/bash
2
+ # Project Organization Script
3
+
4
+ echo "📁 Organizing Devicely Project Structure..."
5
+ echo ""
6
+
7
+ # Create directory structure
8
+ mkdir -p docs/fixes
9
+ mkdir -p docs/guides
10
+ mkdir -p scripts/utilities
11
+ mkdir -p scripts/testing
12
+ mkdir -p .archive
13
+
14
+ # Move documentation files
15
+ echo "📄 Organizing documentation..."
16
+ mv *_FIX*.md docs/fixes/ 2>/dev/null
17
+ mv *_FIXES.md docs/fixes/ 2>/dev/null
18
+ mv AI_*.md docs/fixes/ 2>/dev/null
19
+ mv IMPLEMENTATION*.md docs/fixes/ 2>/dev/null
20
+ mv FINAL_*.md docs/fixes/ 2>/dev/null
21
+
22
+ mv *_GUIDE*.md docs/guides/ 2>/dev/null
23
+ mv TROUBLESHOOTING.md docs/guides/ 2>/dev/null
24
+ mv HOW_TO_*.md docs/guides/ 2>/dev/null
25
+
26
+ # Move test scripts
27
+ echo "🧪 Organizing test scripts..."
28
+ mv test_*.sh scripts/testing/ 2>/dev/null
29
+ mv test_*.js scripts/testing/ 2>/dev/null
30
+ mv validate-*.js scripts/testing/ 2>/dev/null
31
+
32
+ # Move utility scripts
33
+ echo "🔧 Organizing utility scripts..."
34
+ mv clean_*.sh scripts/utilities/ 2>/dev/null
35
+ mv clean_*.js scripts/utilities/ 2>/dev/null
36
+ mv find_*.sh scripts/utilities/ 2>/dev/null
37
+ mv diagnose_*.sh scripts/utilities/ 2>/dev/null
38
+ mv verify_*.sh scripts/utilities/ 2>/dev/null
39
+
40
+ # Move old/obsolete files to archive
41
+ echo "📦 Archiving obsolete files..."
42
+ mv connect_android_usb.sh .archive/ 2>/dev/null
43
+ mv connect_ios_usb.sh .archive/ 2>/dev/null
44
+ mv setup_android.sh .archive/ 2>/dev/null
45
+
46
+ # Keep important files in root
47
+ echo "✅ Keeping in root:"
48
+ echo " - README.md"
49
+ echo " - start.sh"
50
+ echo " - setup.sh"
51
+ echo " - devices.conf"
52
+ echo " - apps_presets.conf"
53
+ echo " - Core control scripts"
54
+
55
+ echo ""
56
+ echo "✅ Project organized!"
57
+ echo ""
58
+ echo "📊 New structure:"
59
+ tree -L 2 -d . 2>/dev/null || ls -la
@@ -0,0 +1,238 @@
1
+ #!/bin/bash
2
+
3
+ ###############################################################################
4
+ # Pre-Publish Verification Script
5
+ # Ensures the npm package is ready for publishing with all protections applied
6
+ ###############################################################################
7
+
8
+ echo "🔍 Pre-Publish Verification Starting..."
9
+ echo ""
10
+
11
+ DIST_DIR="npm-package/dist"
12
+ ERRORS=0
13
+ WARNINGS=0
14
+
15
+ # Color codes
16
+ RED='\033[0;31m'
17
+ GREEN='\033[0;32m'
18
+ YELLOW='\033[1;33m'
19
+ BLUE='\033[0;34m'
20
+ NC='\033[0m' # No Color
21
+
22
+ # Check functions
23
+ check_pass() {
24
+ echo -e "${GREEN}✅ PASS${NC}: $1"
25
+ }
26
+
27
+ check_fail() {
28
+ echo -e "${RED}❌ FAIL${NC}: $1"
29
+ ((ERRORS++))
30
+ }
31
+
32
+ check_warn() {
33
+ echo -e "${YELLOW}⚠️ WARN${NC}: $1"
34
+ ((WARNINGS++))
35
+ }
36
+
37
+ check_info() {
38
+ echo -e "${BLUE}ℹ️ INFO${NC}: $1"
39
+ }
40
+
41
+ echo "═══════════════════════════════════════════════════════════════"
42
+ echo "1️⃣ Checking Distribution Directory"
43
+ echo "═══════════════════════════════════════════════════════════════"
44
+
45
+ if [ ! -d "$DIST_DIR" ]; then
46
+ check_fail "Distribution directory not found: $DIST_DIR"
47
+ echo ""
48
+ echo "Run: cd npm-package && npm run build:obfuscated"
49
+ exit 1
50
+ else
51
+ check_pass "Distribution directory exists"
52
+ fi
53
+
54
+ echo ""
55
+ echo "═══════════════════════════════════════════════════════════════"
56
+ echo "2️⃣ Verifying Package Structure"
57
+ echo "═══════════════════════════════════════════════════════════════"
58
+
59
+ # Required directories
60
+ for dir in "bin" "lib" "scripts" "config"; do
61
+ if [ -d "$DIST_DIR/$dir" ]; then
62
+ check_pass "Directory exists: $dir/"
63
+ else
64
+ check_fail "Missing directory: $dir/"
65
+ fi
66
+ done
67
+
68
+ # Required files
69
+ for file in "package.json" "README.md" "LICENSE"; do
70
+ if [ -f "$DIST_DIR/$file" ]; then
71
+ check_pass "File exists: $file"
72
+ else
73
+ check_fail "Missing file: $file"
74
+ fi
75
+ done
76
+
77
+ echo ""
78
+ echo "═══════════════════════════════════════════════════════════════"
79
+ echo "3️⃣ Verifying JavaScript Obfuscation"
80
+ echo "═══════════════════════════════════════════════════════════════"
81
+
82
+ # Check if JS files are obfuscated (should not contain readable comments/formatting)
83
+ js_count=$(find "$DIST_DIR/lib" -name "*.js" 2>/dev/null | wc -l | tr -d ' ')
84
+ check_info "Found $js_count JavaScript files"
85
+
86
+ # Sample a file to check obfuscation
87
+ if [ -f "$DIST_DIR/lib/server.js" ]; then
88
+ if head -5 "$DIST_DIR/lib/server.js" | grep -q "function\s\+[a-zA-Z_]" 2>/dev/null; then
89
+ check_warn "JavaScript files may not be fully obfuscated"
90
+ else
91
+ check_pass "JavaScript files appear obfuscated"
92
+ fi
93
+ fi
94
+
95
+ echo ""
96
+ echo "═══════════════════════════════════════════════════════════════"
97
+ echo "4️⃣ Verifying Shell Script Protection"
98
+ echo "═══════════════════════════════════════════════════════════════"
99
+
100
+ sh_count=$(find "$DIST_DIR/scripts/shell" -name "*.sh" 2>/dev/null | wc -l | tr -d ' ')
101
+ binary_count=$(find "$DIST_DIR/scripts/shell" -type f -perm +111 2>/dev/null | wc -l | tr -d ' ')
102
+
103
+ if [ "$sh_count" -eq 0 ]; then
104
+ check_pass "No .sh files in distribution (fully protected)"
105
+ else
106
+ check_fail "Found $sh_count .sh files (should be 0)"
107
+ fi
108
+
109
+ if [ "$binary_count" -gt 0 ]; then
110
+ check_pass "Found $binary_count compiled binary executables"
111
+ else
112
+ check_fail "No binary executables found"
113
+ fi
114
+
115
+ # Verify binaries are actually compiled
116
+ if [ "$binary_count" -gt 0 ]; then
117
+ sample_binary=$(find "$DIST_DIR/scripts/shell" -type f -perm +111 2>/dev/null | head -1)
118
+ if [ -n "$sample_binary" ]; then
119
+ if file "$sample_binary" | grep -q "executable"; then
120
+ check_pass "Binaries are properly compiled executables"
121
+ else
122
+ check_warn "Binaries may not be properly compiled"
123
+ fi
124
+ fi
125
+ fi
126
+
127
+ echo ""
128
+ echo "═══════════════════════════════════════════════════════════════"
129
+ echo "5️⃣ Checking Package.json"
130
+ echo "═══════════════════════════════════════════════════════════════"
131
+
132
+ if [ -f "$DIST_DIR/package.json" ]; then
133
+ # Check name
134
+ pkg_name=$(grep -o '"name":\s*"[^"]*"' "$DIST_DIR/package.json" | cut -d'"' -f4)
135
+ check_info "Package name: $pkg_name"
136
+
137
+ # Check version
138
+ pkg_version=$(grep -o '"version":\s*"[^"]*"' "$DIST_DIR/package.json" | cut -d'"' -f4)
139
+ check_info "Package version: $pkg_version"
140
+
141
+ # Check main entry
142
+ pkg_main=$(grep -o '"main":\s*"[^"]*"' "$DIST_DIR/package.json" | cut -d'"' -f4)
143
+ if [ -f "$DIST_DIR/$pkg_main" ]; then
144
+ check_pass "Main entry point exists: $pkg_main"
145
+ else
146
+ check_fail "Main entry point missing: $pkg_main"
147
+ fi
148
+
149
+ # Check bin entry
150
+ if grep -q '"bin"' "$DIST_DIR/package.json"; then
151
+ check_pass "Binary entry point defined"
152
+ else
153
+ check_warn "No binary entry point defined"
154
+ fi
155
+
156
+ # Check if devDependencies removed
157
+ if grep -q '"devDependencies"' "$DIST_DIR/package.json"; then
158
+ check_warn "devDependencies still present (should be removed)"
159
+ else
160
+ check_pass "devDependencies removed from distribution"
161
+ fi
162
+ fi
163
+
164
+ echo ""
165
+ echo "═══════════════════════════════════════════════════════════════"
166
+ echo "6️⃣ Checking for Sensitive Data"
167
+ echo "═══════════════════════════════════════════════════════════════"
168
+
169
+ # Check for .env files (should not be in distribution)
170
+ if find "$DIST_DIR" -name ".env*" 2>/dev/null | grep -q .; then
171
+ check_fail ".env files found in distribution"
172
+ else
173
+ check_pass "No .env files in distribution"
174
+ fi
175
+
176
+ # Check for real API keys in config files (not in obfuscated code)
177
+ if grep -r "OPENAI_API_KEY\s*=\s*['\"]sk-" "$DIST_DIR/config" 2>/dev/null >/dev/null; then
178
+ check_fail "Real API keys found in config files"
179
+ else
180
+ check_pass "No API keys in config files"
181
+ fi
182
+
183
+ echo ""
184
+ echo "═══════════════════════════════════════════════════════════════"
185
+ echo "7️⃣ Checking File Sizes"
186
+ echo "═══════════════════════════════════════════════════════════════"
187
+
188
+ total_size=$(du -sh "$DIST_DIR" 2>/dev/null | cut -f1)
189
+ check_info "Total package size: $total_size"
190
+
191
+ # Check if package is too large
192
+ size_bytes=$(du -sb "$DIST_DIR" 2>/dev/null | cut -f1)
193
+ if [ "$size_bytes" -gt 52428800 ]; then # 50MB
194
+ check_warn "Package size is large (>50MB). Consider optimization."
195
+ else
196
+ check_pass "Package size is reasonable"
197
+ fi
198
+
199
+ echo ""
200
+ echo "═══════════════════════════════════════════════════════════════"
201
+ echo "8️⃣ Testing Package Installation"
202
+ echo "═══════════════════════════════════════════════════════════════"
203
+
204
+ # Test if package.json is valid
205
+ if node -e "JSON.parse(require('fs').readFileSync('$DIST_DIR/package.json', 'utf8'))" 2>/dev/null; then
206
+ check_pass "package.json is valid JSON"
207
+ else
208
+ check_fail "package.json has JSON syntax errors"
209
+ fi
210
+
211
+ # Check if main entry can be required
212
+ if [ -f "$DIST_DIR/$pkg_main" ]; then
213
+ if node -e "require('$DIST_DIR/$pkg_main')" 2>/dev/null; then
214
+ check_pass "Main entry point can be loaded"
215
+ else
216
+ check_warn "Main entry point may have runtime issues"
217
+ fi
218
+ fi
219
+
220
+ echo ""
221
+ echo "═══════════════════════════════════════════════════════════════"
222
+ echo "📊 Summary"
223
+ echo "═══════════════════════════════════════════════════════════════"
224
+
225
+ if [ $ERRORS -eq 0 ] && [ $WARNINGS -eq 0 ]; then
226
+ echo -e "${GREEN}✅ All checks passed! Package is ready for publishing.${NC}"
227
+ echo ""
228
+ echo "📝 Next steps:"
229
+ echo " cd npm-package/dist"
230
+ echo " npm publish --access public"
231
+ exit 0
232
+ elif [ $ERRORS -eq 0 ]; then
233
+ echo -e "${YELLOW}⚠️ $WARNINGS warning(s) found. Review before publishing.${NC}"
234
+ exit 0
235
+ else
236
+ echo -e "${RED}❌ $ERRORS error(s) and $WARNINGS warning(s) found. Fix issues before publishing.${NC}"
237
+ exit 1
238
+ fi