fnva 0.0.20 → 0.0.22
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/package.json
CHANGED
package/platforms/fnva
CHANGED
|
Binary file
|
package/platforms/fnva.exe
CHANGED
|
Binary file
|
|
@@ -4,7 +4,7 @@ const fs = require('fs');
|
|
|
4
4
|
const path = require('path');
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
|
-
* 检查platforms目录中二进制文件的权限
|
|
7
|
+
* 检查 platforms 目录中二进制文件的权限
|
|
8
8
|
*/
|
|
9
9
|
function checkPermissions() {
|
|
10
10
|
console.log('🔍 检查二进制文件权限...');
|
|
@@ -12,13 +12,14 @@ function checkPermissions() {
|
|
|
12
12
|
const platformsDir = path.join(__dirname, '..', 'platforms');
|
|
13
13
|
|
|
14
14
|
if (!fs.existsSync(platformsDir)) {
|
|
15
|
-
console.log('❌ platforms目录不存在');
|
|
15
|
+
console.log('❌ platforms 目录不存在');
|
|
16
16
|
process.exit(1);
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
const platforms = fs.readdirSync(platformsDir);
|
|
20
20
|
let allGood = true;
|
|
21
21
|
|
|
22
|
+
// 优先检查新的 platform-arch 目录结构
|
|
22
23
|
for (const platform of platforms) {
|
|
23
24
|
const platformDir = path.join(platformsDir, platform);
|
|
24
25
|
|
|
@@ -43,6 +44,22 @@ function checkPermissions() {
|
|
|
43
44
|
}
|
|
44
45
|
}
|
|
45
46
|
|
|
47
|
+
// 额外检查一次扁平结构: platforms/fnva
|
|
48
|
+
const flatBinaryName = process.platform === 'win32' ? 'fnva.exe' : 'fnva';
|
|
49
|
+
const flatBinaryPath = path.join(platformsDir, flatBinaryName);
|
|
50
|
+
|
|
51
|
+
if (fs.existsSync(flatBinaryPath)) {
|
|
52
|
+
const stats = fs.statSync(flatBinaryPath);
|
|
53
|
+
const hasExecPermission = (stats.mode & 0o111) !== 0;
|
|
54
|
+
const mode = stats.mode.toString(8).padStart(4, '0');
|
|
55
|
+
|
|
56
|
+
console.log(` (legacy)/${flatBinaryName}: ${mode} ${hasExecPermission ? '✅' : '❌'}`);
|
|
57
|
+
|
|
58
|
+
if (!hasExecPermission && flatBinaryName !== 'fnva.exe') {
|
|
59
|
+
allGood = false;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
46
63
|
console.log(`\n${allGood ? '✅' : '❌'} 权限检查${allGood ? '通过' : '失败'}`);
|
|
47
64
|
|
|
48
65
|
if (!allGood) {
|
|
@@ -56,4 +73,5 @@ if (require.main === module) {
|
|
|
56
73
|
checkPermissions();
|
|
57
74
|
}
|
|
58
75
|
|
|
59
|
-
module.exports = { checkPermissions };
|
|
76
|
+
module.exports = { checkPermissions };
|
|
77
|
+
|
|
@@ -4,8 +4,8 @@ const fs = require('fs');
|
|
|
4
4
|
const path = require('path');
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
|
-
* 确保fnva二进制文件有可执行权限
|
|
8
|
-
*
|
|
7
|
+
* 确保 fnva 二进制文件有可执行权限
|
|
8
|
+
* 这是一个全局的 postinstall 脚本,处理本地安装和全局安装的权限问题
|
|
9
9
|
*/
|
|
10
10
|
function ensureExecutablePermissions() {
|
|
11
11
|
try {
|
|
@@ -13,47 +13,119 @@ function ensureExecutablePermissions() {
|
|
|
13
13
|
const projectRoot = path.resolve(scriptDir, '..');
|
|
14
14
|
const platformsDir = path.join(projectRoot, 'platforms');
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
console.log('✅ Ensuring fnva binary permissions...');
|
|
17
|
+
|
|
18
|
+
// 如果没有 platforms 目录,说明是开发模式,不需要处理
|
|
17
19
|
if (!fs.existsSync(platformsDir)) {
|
|
20
|
+
console.log('ℹ️ No platforms directory found, skipping permission check');
|
|
18
21
|
return;
|
|
19
22
|
}
|
|
20
23
|
|
|
21
|
-
// 检测当前平台
|
|
22
24
|
const platform = process.platform;
|
|
23
25
|
const arch = process.arch === 'arm64' ? 'arm64' : 'x64';
|
|
24
26
|
const platformDir = `${platform}-${arch}`;
|
|
25
27
|
|
|
26
|
-
// 确定二进制文件名和路径
|
|
27
28
|
const binaryName = platform === 'win32' ? 'fnva.exe' : 'fnva';
|
|
28
|
-
const
|
|
29
|
+
const archBinaryPath = path.join(platformsDir, platformDir, binaryName);
|
|
30
|
+
const flatBinaryPath = path.join(platformsDir, binaryName);
|
|
29
31
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
+
/**
|
|
33
|
+
* 确保指定路径的二进制文件具有可执行权限,并做一次简单的运行测试
|
|
34
|
+
*/
|
|
35
|
+
function ensureExecutable(binaryPath, label) {
|
|
32
36
|
try {
|
|
33
37
|
const stats = fs.statSync(binaryPath);
|
|
34
38
|
const hasExecPermission = (stats.mode & 0o111) !== 0;
|
|
35
39
|
|
|
40
|
+
console.log(`📍 Checking binary (${label}): ${binaryPath}`);
|
|
41
|
+
console.log(` Current permissions: ${(stats.mode & 0o777).toString(8)}`);
|
|
42
|
+
|
|
36
43
|
if (!hasExecPermission) {
|
|
44
|
+
console.log('🔧 Setting executable permissions...');
|
|
37
45
|
fs.chmodSync(binaryPath, 0o755); // rwxr-xr-x
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
46
|
+
|
|
47
|
+
const newStats = fs.statSync(binaryPath);
|
|
48
|
+
const newHasExecPermission = (newStats.mode & 0o111) !== 0;
|
|
49
|
+
|
|
50
|
+
if (newHasExecPermission) {
|
|
51
|
+
console.log(`✅ Successfully set executable permissions (${label})`);
|
|
52
|
+
} else {
|
|
53
|
+
console.log(`❌ Failed to set executable permissions (${label})`);
|
|
54
|
+
console.log(` New permissions: ${(newStats.mode & 0o777).toString(8)}`);
|
|
55
|
+
console.log(` Manual fix may be required: chmod +x "${binaryPath}"`);
|
|
56
|
+
}
|
|
57
|
+
} else {
|
|
58
|
+
console.log(`✅ fnva binary already has executable permissions (${label})`);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// 尝试执行一次 --version 做简单验证
|
|
62
|
+
try {
|
|
63
|
+
const { spawnSync } = require('child_process');
|
|
64
|
+
const testResult = spawnSync(binaryPath, ['--version'], {
|
|
65
|
+
encoding: 'utf8',
|
|
66
|
+
timeout: 3000,
|
|
67
|
+
stdio: 'pipe',
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
if (testResult.status === 0 || testResult.status === 1) {
|
|
71
|
+
console.log('✅ fnva binary is executable and responding');
|
|
72
|
+
} else if (testResult.error && testResult.error.code === 'EACCES') {
|
|
73
|
+
console.log('❌ fnva binary still has permission issues');
|
|
74
|
+
console.log(` Manual fix required: chmod +x "${binaryPath}"`);
|
|
41
75
|
}
|
|
76
|
+
} catch {
|
|
77
|
+
// 测试失败不视为致命错误,可能是二进制本身的问题
|
|
42
78
|
}
|
|
43
79
|
} catch (error) {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
80
|
+
console.warn(`⚠️ Could not fix binary permissions (${label}): ${error.message}`);
|
|
81
|
+
console.log(` Manual fix required: chmod +x "${binaryPath}"`);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Windows 不需要 chmod,可直接跳过
|
|
86
|
+
if (platform === 'win32') {
|
|
87
|
+
console.log('ℹ️ Windows platform detected, skipping permission check');
|
|
88
|
+
} else if (fs.existsSync(archBinaryPath)) {
|
|
89
|
+
// 优先处理新的平台子目录结构: platforms/<platform>-<arch>/fnva
|
|
90
|
+
ensureExecutable(archBinaryPath, platformDir);
|
|
91
|
+
} else if (fs.existsSync(flatBinaryPath)) {
|
|
92
|
+
// 兼容旧版本扁平结构: platforms/fnva
|
|
93
|
+
console.log('ℹ️ Platform-specific binary not found, falling back to legacy flat layout');
|
|
94
|
+
ensureExecutable(flatBinaryPath, 'platforms/fnva');
|
|
95
|
+
} else {
|
|
96
|
+
console.log(`❌ Binary not found: ${archBinaryPath}`);
|
|
97
|
+
console.log(` Also checked legacy path: ${flatBinaryPath}`);
|
|
98
|
+
console.log(' This might indicate an incomplete installation');
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// 额外检查:如果是全局安装,也尝试检查路径上的 fnva 权限
|
|
102
|
+
if (process.env.npm_config_global === 'true') {
|
|
103
|
+
try {
|
|
104
|
+
const { execSync } = require('child_process');
|
|
105
|
+
const globalFnvaPath = execSync('which fnva', { encoding: 'utf8' }).trim();
|
|
106
|
+
|
|
107
|
+
if (globalFnvaPath && fs.existsSync(globalFnvaPath)) {
|
|
108
|
+
console.log(`📍 Checking globally installed binary: ${globalFnvaPath}`);
|
|
109
|
+
|
|
110
|
+
const globalStats = fs.statSync(globalFnvaPath);
|
|
111
|
+
const globalHasExecPermission = (globalStats.mode & 0o111) !== 0;
|
|
112
|
+
|
|
113
|
+
if (!globalHasExecPermission) {
|
|
114
|
+
console.log('❌ Global fnva binary lacks executable permissions');
|
|
115
|
+
console.log(` Please run: sudo chmod +x "${globalFnvaPath}"`);
|
|
116
|
+
} else {
|
|
117
|
+
console.log('✅ Global fnva binary has correct permissions');
|
|
118
|
+
}
|
|
47
119
|
}
|
|
120
|
+
} catch {
|
|
121
|
+
console.log('ℹ️ Could not verify global installation');
|
|
48
122
|
}
|
|
49
123
|
}
|
|
50
124
|
} catch (error) {
|
|
51
|
-
|
|
52
|
-
if (process.env.DEBUG || process.env.NPM_DEBUG) {
|
|
53
|
-
console.warn(`⚠️ Permission check failed: ${error.message}`);
|
|
54
|
-
}
|
|
125
|
+
console.warn(`⚠️ Permission check failed: ${error.message}`);
|
|
55
126
|
}
|
|
56
127
|
}
|
|
57
128
|
|
|
58
129
|
// 运行权限检查
|
|
59
|
-
ensureExecutablePermissions();
|
|
130
|
+
ensureExecutablePermissions();
|
|
131
|
+
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# fnva权限修复脚本 - 临时解决方案
|
|
4
|
+
# 适用于Mac/Linux系统的全局安装权限修复
|
|
5
|
+
|
|
6
|
+
set -e
|
|
7
|
+
|
|
8
|
+
echo "🔧 fnva权限修复工具"
|
|
9
|
+
echo "=================="
|
|
10
|
+
|
|
11
|
+
# 检查fnva是否已安装
|
|
12
|
+
if ! command -v fnva &> /dev/null; then
|
|
13
|
+
echo "❌ fnva未找到,请先安装: npm install -g fnva"
|
|
14
|
+
exit 1
|
|
15
|
+
fi
|
|
16
|
+
|
|
17
|
+
# 获取fnva路径
|
|
18
|
+
FNVA_PATH=$(which fnva)
|
|
19
|
+
echo "📍 找到fnva: $FNVA_PATH"
|
|
20
|
+
|
|
21
|
+
# 检查权限
|
|
22
|
+
if [ -x "$FNVA_PATH" ]; then
|
|
23
|
+
echo "✅ fnva已有可执行权限"
|
|
24
|
+
echo "🧪 测试fnva是否正常工作..."
|
|
25
|
+
if fnva --version &> /dev/null || [ $? -eq 1 ]; then
|
|
26
|
+
echo "✅ fnva正常工作!"
|
|
27
|
+
exit 0
|
|
28
|
+
else
|
|
29
|
+
echo "⚠️ fnva有权限但执行仍有问题"
|
|
30
|
+
fi
|
|
31
|
+
else
|
|
32
|
+
echo "❌ fnva缺少可执行权限"
|
|
33
|
+
fi
|
|
34
|
+
|
|
35
|
+
# 尝试修复权限
|
|
36
|
+
echo "🔧 修复fnva权限..."
|
|
37
|
+
if sudo chmod +x "$FNVA_PATH"; then
|
|
38
|
+
echo "✅ 权限修复成功"
|
|
39
|
+
|
|
40
|
+
# 验证修复结果
|
|
41
|
+
echo "🧪 验证fnva是否正常工作..."
|
|
42
|
+
if fnva --version &> /dev/null || [ $? -eq 1 ]; then
|
|
43
|
+
echo "🎉 fnva权限修复完成!现在可以使用fnva了"
|
|
44
|
+
exit 0
|
|
45
|
+
else
|
|
46
|
+
echo "⚠️ 权限已修复但执行仍有问题"
|
|
47
|
+
fi
|
|
48
|
+
else
|
|
49
|
+
echo "❌ 权限修复失败"
|
|
50
|
+
fi
|
|
51
|
+
|
|
52
|
+
# 如果上述方法失败,尝试其他方法
|
|
53
|
+
echo ""
|
|
54
|
+
echo "🔄 尝试其他修复方法..."
|
|
55
|
+
|
|
56
|
+
# 方法1: 查找所有fnva二进制文件
|
|
57
|
+
echo "🔍 查找所有fnva二进制文件..."
|
|
58
|
+
FNVA_FILES=$(find /usr/local /opt /home -name "fnva" -type f 2>/dev/null || true)
|
|
59
|
+
|
|
60
|
+
if [ -n "$FNVA_FILES" ]; then
|
|
61
|
+
echo "📁 找到以下fnva文件:"
|
|
62
|
+
echo "$FNVA_FILES"
|
|
63
|
+
echo ""
|
|
64
|
+
|
|
65
|
+
echo "🔧 修复所有fnva文件的权限..."
|
|
66
|
+
echo "$FNVA_FILES" | while read -r file; do
|
|
67
|
+
if [ -f "$file" ]; then
|
|
68
|
+
echo " 修复: $file"
|
|
69
|
+
sudo chmod +x "$file"
|
|
70
|
+
fi
|
|
71
|
+
done
|
|
72
|
+
else
|
|
73
|
+
echo "📁 未找到其他fnva文件"
|
|
74
|
+
fi
|
|
75
|
+
|
|
76
|
+
# 方法2: 查找npm全局目录中的fnva
|
|
77
|
+
echo ""
|
|
78
|
+
echo "🔍 检查npm全局安装目录..."
|
|
79
|
+
NPM_GLOBAL_ROOT=$(npm root -g 2>/dev/null || echo "")
|
|
80
|
+
if [ -n "$NPM_GLOBAL_ROOT" ]; then
|
|
81
|
+
FNVA_MODULE_PATH="$NPM_GLOBAL_ROOT/fnva"
|
|
82
|
+
if [ -d "$FNVA_MODULE_PATH" ]; then
|
|
83
|
+
echo "📁 找到fnva模块: $FNVA_MODULE_PATH"
|
|
84
|
+
echo "🔧 修复模块中的二进制文件权限..."
|
|
85
|
+
|
|
86
|
+
# 查找模块中的所有fnva文件
|
|
87
|
+
find "$FNVA_MODULE_PATH" -name "fnva" -type f -exec sudo chmod +x {} \; 2>/dev/null || true
|
|
88
|
+
fi
|
|
89
|
+
fi
|
|
90
|
+
|
|
91
|
+
# 最终测试
|
|
92
|
+
echo ""
|
|
93
|
+
echo "🧪 最终测试..."
|
|
94
|
+
if fnva --version &> /dev/null || [ $? -eq 1 ]; then
|
|
95
|
+
echo "🎉 修复成功!fnva现在可以正常使用"
|
|
96
|
+
exit 0
|
|
97
|
+
else
|
|
98
|
+
echo "❌ 修复失败,请尝试以下方法:"
|
|
99
|
+
echo " 1. 重新安装: npm uninstall -g fnva && npm install -g fnva --force"
|
|
100
|
+
echo " 2. 手动找到fnva文件并修复权限"
|
|
101
|
+
echo " 3. 使用 FNVA_AUTO_MODE=1 fnva list 使用Node.js模式"
|
|
102
|
+
exit 1
|
|
103
|
+
fi
|