@qingchencloud/qy-server 1.0.2
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/README.md +110 -0
- package/bin/qy-server +0 -0
- package/lib/index.js +184 -0
- package/lib/install.js +193 -0
- package/package.json +52 -0
package/README.md
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
# @qingchencloud/qy-server
|
|
2
|
+
|
|
3
|
+
晴云私有代理服务端 - 一个轻量级、高性能的私有代理服务器。
|
|
4
|
+
|
|
5
|
+
## 功能特性
|
|
6
|
+
|
|
7
|
+
- ✅ TLS 1.3 加密 - 流量伪装成 HTTPS
|
|
8
|
+
- ✅ TCP/UDP 代理 - 全协议支持
|
|
9
|
+
- ✅ 端口转发 - 本地端口映射到远程
|
|
10
|
+
- ✅ 内网穿透 - 将内网服务暴露到公网
|
|
11
|
+
- ✅ 流量统计 - 实时监控
|
|
12
|
+
- ✅ 多密钥支持 - 灵活的访问控制
|
|
13
|
+
|
|
14
|
+
## 快速安装
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
# 全局安装
|
|
18
|
+
npm install -g @qingchencloud/qy-server
|
|
19
|
+
|
|
20
|
+
# 或使用 npx 直接运行
|
|
21
|
+
npx @qingchencloud/qy-server
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## 使用方法
|
|
25
|
+
|
|
26
|
+
### 命令行
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
# 显示帮助
|
|
30
|
+
qy-server --help
|
|
31
|
+
|
|
32
|
+
# 使用配置文件启动
|
|
33
|
+
qy-server -c config.yaml
|
|
34
|
+
|
|
35
|
+
# 生成密钥哈希
|
|
36
|
+
qy-server -genkey "my-secret-key"
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### 编程方式
|
|
40
|
+
|
|
41
|
+
```javascript
|
|
42
|
+
const qyServer = require('@qingchencloud/qy-server');
|
|
43
|
+
|
|
44
|
+
// 生成配置文件
|
|
45
|
+
const { configPath, key } = qyServer.generateConfig('./config.yaml', {
|
|
46
|
+
listen: ':443',
|
|
47
|
+
cert: '/path/to/cert.pem',
|
|
48
|
+
keyFile: '/path/to/key.pem'
|
|
49
|
+
});
|
|
50
|
+
console.log('访问密钥:', key);
|
|
51
|
+
|
|
52
|
+
// 启动服务器
|
|
53
|
+
const server = qyServer.start({ config: configPath });
|
|
54
|
+
|
|
55
|
+
// 获取版本
|
|
56
|
+
console.log(qyServer.version());
|
|
57
|
+
|
|
58
|
+
// 生成密钥哈希
|
|
59
|
+
const hash = qyServer.generateKeyHash('my-secret-key');
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## 配置文件示例
|
|
63
|
+
|
|
64
|
+
```yaml
|
|
65
|
+
server:
|
|
66
|
+
listen: ":443"
|
|
67
|
+
cert: "/etc/ssl/cert.pem"
|
|
68
|
+
key: "/etc/ssl/key.pem"
|
|
69
|
+
|
|
70
|
+
auth:
|
|
71
|
+
keys:
|
|
72
|
+
- "your-secret-key"
|
|
73
|
+
|
|
74
|
+
features:
|
|
75
|
+
proxy: true
|
|
76
|
+
port_forward: true
|
|
77
|
+
nat_penetration: true
|
|
78
|
+
|
|
79
|
+
limits:
|
|
80
|
+
max_connections: 1000
|
|
81
|
+
bandwidth_limit: 0
|
|
82
|
+
idle_timeout: 300
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## 客户端配置
|
|
86
|
+
|
|
87
|
+
在 ClashDIY 中添加节点:
|
|
88
|
+
|
|
89
|
+
```yaml
|
|
90
|
+
proxies:
|
|
91
|
+
- name: "我的私有节点"
|
|
92
|
+
type: qyproto
|
|
93
|
+
server: your-server.com
|
|
94
|
+
port: 443
|
|
95
|
+
password: "your-secret-key"
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## 系统要求
|
|
99
|
+
|
|
100
|
+
- Node.js >= 14
|
|
101
|
+
- 支持平台:Windows (x64), Linux (x64/arm64), macOS (x64/arm64)
|
|
102
|
+
|
|
103
|
+
## 许可证
|
|
104
|
+
|
|
105
|
+
MIT
|
|
106
|
+
|
|
107
|
+
## 相关链接
|
|
108
|
+
|
|
109
|
+
- [GitHub](https://github.com/1186258278/QingYun)
|
|
110
|
+
- [问题反馈](https://github.com/1186258278/QingYun/issues)
|
package/bin/qy-server
ADDED
|
Binary file
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* QY-Server NPM 包入口
|
|
4
|
+
* 提供编程方式启动和命令行调用
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const { spawn, execSync } = require('child_process');
|
|
8
|
+
const path = require('path');
|
|
9
|
+
const fs = require('fs');
|
|
10
|
+
|
|
11
|
+
// 获取二进制文件路径
|
|
12
|
+
function getBinaryPath() {
|
|
13
|
+
const ext = process.platform === 'win32' ? '.exe' : '';
|
|
14
|
+
const binaryPath = path.join(__dirname, '..', 'bin', `qy-server${ext}`);
|
|
15
|
+
|
|
16
|
+
if (!fs.existsSync(binaryPath)) {
|
|
17
|
+
throw new Error(
|
|
18
|
+
'二进制文件不存在,请运行: npm run postinstall\n' +
|
|
19
|
+
'或手动下载二进制文件到: ' + binaryPath
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
return binaryPath;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* 启动 QY-Server
|
|
28
|
+
* @param {Object} options 选项
|
|
29
|
+
* @param {string} options.config 配置文件路径
|
|
30
|
+
* @param {boolean} options.daemon 是否后台运行
|
|
31
|
+
* @returns {ChildProcess} 子进程
|
|
32
|
+
*/
|
|
33
|
+
function start(options = {}) {
|
|
34
|
+
const binaryPath = getBinaryPath();
|
|
35
|
+
const args = [];
|
|
36
|
+
|
|
37
|
+
if (options.config) {
|
|
38
|
+
args.push('-c', options.config);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const child = spawn(binaryPath, args, {
|
|
42
|
+
stdio: options.daemon ? 'ignore' : 'inherit',
|
|
43
|
+
detached: options.daemon || false
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
if (options.daemon) {
|
|
47
|
+
child.unref();
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return child;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* 获取版本信息
|
|
55
|
+
* @returns {string} 版本号
|
|
56
|
+
*/
|
|
57
|
+
function version() {
|
|
58
|
+
const binaryPath = getBinaryPath();
|
|
59
|
+
try {
|
|
60
|
+
const output = execSync(`"${binaryPath}" -v`, { encoding: 'utf8' });
|
|
61
|
+
return output.trim();
|
|
62
|
+
} catch (error) {
|
|
63
|
+
return require('../package.json').version;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* 生成密钥哈希
|
|
69
|
+
* @param {string} key 原始密钥
|
|
70
|
+
* @returns {string} SHA256 哈希
|
|
71
|
+
*/
|
|
72
|
+
function generateKeyHash(key) {
|
|
73
|
+
const binaryPath = getBinaryPath();
|
|
74
|
+
try {
|
|
75
|
+
const output = execSync(`"${binaryPath}" -genkey "${key}"`, { encoding: 'utf8' });
|
|
76
|
+
const match = output.match(/SHA256 哈希: ([a-f0-9]+)/);
|
|
77
|
+
return match ? match[1] : null;
|
|
78
|
+
} catch (error) {
|
|
79
|
+
// 如果二进制调用失败,使用 Node.js 计算
|
|
80
|
+
const crypto = require('crypto');
|
|
81
|
+
return crypto.createHash('sha256').update(key).digest('hex');
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* 生成配置文件
|
|
87
|
+
* @param {string} outputPath 输出路径
|
|
88
|
+
* @param {Object} options 配置选项
|
|
89
|
+
*/
|
|
90
|
+
function generateConfig(outputPath, options = {}) {
|
|
91
|
+
const key = options.key || require('crypto').randomBytes(16).toString('hex');
|
|
92
|
+
|
|
93
|
+
const config = `# QY-Server 配置文件
|
|
94
|
+
# 生成时间: ${new Date().toISOString()}
|
|
95
|
+
|
|
96
|
+
server:
|
|
97
|
+
listen: "${options.listen || ':443'}"
|
|
98
|
+
cert: "${options.cert || ''}"
|
|
99
|
+
key: "${options.keyFile || ''}"
|
|
100
|
+
fallback: "${options.fallback || 'https://www.baidu.com'}"
|
|
101
|
+
|
|
102
|
+
auth:
|
|
103
|
+
keys:
|
|
104
|
+
- "${key}"
|
|
105
|
+
|
|
106
|
+
features:
|
|
107
|
+
proxy: ${options.proxy !== false}
|
|
108
|
+
port_forward: ${options.portForward !== false}
|
|
109
|
+
nat_penetration: ${options.natPenetration !== false}
|
|
110
|
+
|
|
111
|
+
limits:
|
|
112
|
+
max_connections: ${options.maxConnections || 1000}
|
|
113
|
+
bandwidth_limit: ${options.bandwidthLimit || 0}
|
|
114
|
+
idle_timeout: ${options.idleTimeout || 300}
|
|
115
|
+
|
|
116
|
+
logging:
|
|
117
|
+
level: "${options.logLevel || 'info'}"
|
|
118
|
+
file: "${options.logFile || ''}"
|
|
119
|
+
`;
|
|
120
|
+
|
|
121
|
+
fs.writeFileSync(outputPath, config, { mode: 0o600 });
|
|
122
|
+
|
|
123
|
+
return { configPath: outputPath, key };
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// 导出 API
|
|
127
|
+
module.exports = {
|
|
128
|
+
start,
|
|
129
|
+
version,
|
|
130
|
+
generateKeyHash,
|
|
131
|
+
generateConfig,
|
|
132
|
+
getBinaryPath
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
// 如果直接运行,执行 CLI
|
|
136
|
+
if (require.main === module) {
|
|
137
|
+
const args = process.argv.slice(2);
|
|
138
|
+
|
|
139
|
+
if (args.includes('--version') || args.includes('-v')) {
|
|
140
|
+
console.log(version());
|
|
141
|
+
process.exit(0);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
if (args.includes('--help') || args.includes('-h')) {
|
|
145
|
+
console.log(`
|
|
146
|
+
QY-Server 晴云私有代理服务端
|
|
147
|
+
|
|
148
|
+
用法:
|
|
149
|
+
qy-server [选项]
|
|
150
|
+
npx @qingchencloud/qy-server [选项]
|
|
151
|
+
|
|
152
|
+
选项:
|
|
153
|
+
-c <path> 配置文件路径 (默认: config.yaml)
|
|
154
|
+
-v 显示版本信息
|
|
155
|
+
-genkey <key> 生成密钥的 SHA256 哈希
|
|
156
|
+
-h, --help 显示帮助信息
|
|
157
|
+
|
|
158
|
+
示例:
|
|
159
|
+
qy-server -c /etc/qy-server/config.yaml
|
|
160
|
+
qy-server -genkey "my-secret-key"
|
|
161
|
+
|
|
162
|
+
更多信息: https://github.com/1186258278/QingYun
|
|
163
|
+
`);
|
|
164
|
+
process.exit(0);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// 传递给二进制执行
|
|
168
|
+
try {
|
|
169
|
+
const binaryPath = getBinaryPath();
|
|
170
|
+
const child = spawn(binaryPath, args, { stdio: 'inherit' });
|
|
171
|
+
|
|
172
|
+
child.on('exit', (code) => {
|
|
173
|
+
process.exit(code || 0);
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
child.on('error', (error) => {
|
|
177
|
+
console.error('启动失败:', error.message);
|
|
178
|
+
process.exit(1);
|
|
179
|
+
});
|
|
180
|
+
} catch (error) {
|
|
181
|
+
console.error(error.message);
|
|
182
|
+
process.exit(1);
|
|
183
|
+
}
|
|
184
|
+
}
|
package/lib/install.js
ADDED
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* QY-Server 安装脚本
|
|
4
|
+
* 在 npm install 后自动下载对应平台的二进制文件
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const https = require('https');
|
|
8
|
+
const http = require('http');
|
|
9
|
+
const fs = require('fs');
|
|
10
|
+
const path = require('path');
|
|
11
|
+
const { execSync } = require('child_process');
|
|
12
|
+
const zlib = require('zlib');
|
|
13
|
+
|
|
14
|
+
// 配置
|
|
15
|
+
const PACKAGE_NAME = '@qingchencloud/qy-server';
|
|
16
|
+
const VERSION = require('../package.json').version;
|
|
17
|
+
const GITHUB_REPO = '1186258278/QingYun';
|
|
18
|
+
|
|
19
|
+
// 获取平台信息
|
|
20
|
+
function getPlatformInfo() {
|
|
21
|
+
const platform = process.platform;
|
|
22
|
+
const arch = process.arch;
|
|
23
|
+
|
|
24
|
+
const platformMap = {
|
|
25
|
+
'darwin': 'darwin',
|
|
26
|
+
'linux': 'linux',
|
|
27
|
+
'win32': 'windows'
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const archMap = {
|
|
31
|
+
'x64': 'amd64',
|
|
32
|
+
'arm64': 'arm64'
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const os = platformMap[platform];
|
|
36
|
+
const cpu = archMap[arch];
|
|
37
|
+
|
|
38
|
+
if (!os || !cpu) {
|
|
39
|
+
throw new Error(`不支持的平台: ${platform}-${arch}`);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const ext = platform === 'win32' ? '.exe' : '';
|
|
43
|
+
const binaryName = `qy-server-${os}-${cpu}${ext}`;
|
|
44
|
+
|
|
45
|
+
return { os, cpu, ext, binaryName, platform, arch };
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// 下载文件
|
|
49
|
+
function downloadFile(url, destPath) {
|
|
50
|
+
return new Promise((resolve, reject) => {
|
|
51
|
+
console.log(`下载: ${url}`);
|
|
52
|
+
|
|
53
|
+
const file = fs.createWriteStream(destPath);
|
|
54
|
+
const protocol = url.startsWith('https') ? https : http;
|
|
55
|
+
|
|
56
|
+
const request = protocol.get(url, (response) => {
|
|
57
|
+
// 处理重定向
|
|
58
|
+
if (response.statusCode === 301 || response.statusCode === 302) {
|
|
59
|
+
file.close();
|
|
60
|
+
fs.unlinkSync(destPath);
|
|
61
|
+
return downloadFile(response.headers.location, destPath)
|
|
62
|
+
.then(resolve)
|
|
63
|
+
.catch(reject);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (response.statusCode !== 200) {
|
|
67
|
+
file.close();
|
|
68
|
+
fs.unlinkSync(destPath);
|
|
69
|
+
reject(new Error(`下载失败: HTTP ${response.statusCode}`));
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const total = parseInt(response.headers['content-length'], 10);
|
|
74
|
+
let downloaded = 0;
|
|
75
|
+
|
|
76
|
+
response.on('data', (chunk) => {
|
|
77
|
+
downloaded += chunk.length;
|
|
78
|
+
if (total) {
|
|
79
|
+
const percent = ((downloaded / total) * 100).toFixed(1);
|
|
80
|
+
process.stdout.write(`\r下载进度: ${percent}%`);
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
response.pipe(file);
|
|
85
|
+
|
|
86
|
+
file.on('finish', () => {
|
|
87
|
+
file.close();
|
|
88
|
+
console.log('\n下载完成');
|
|
89
|
+
resolve();
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
request.on('error', (err) => {
|
|
94
|
+
file.close();
|
|
95
|
+
fs.unlinkSync(destPath);
|
|
96
|
+
reject(err);
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// 获取下载 URL
|
|
102
|
+
function getDownloadUrl(binaryName) {
|
|
103
|
+
// 优先使用 GitHub Releases
|
|
104
|
+
const githubUrl = `https://github.com/${GITHUB_REPO}/releases/download/v${VERSION}/${binaryName}`;
|
|
105
|
+
|
|
106
|
+
// 备用:使用 npm registry 存储(需要额外配置)
|
|
107
|
+
// const npmUrl = `https://registry.npmmirror.com/${PACKAGE_NAME}/-/${binaryName}`;
|
|
108
|
+
|
|
109
|
+
return githubUrl;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// 检查本地编译的二进制文件
|
|
113
|
+
function checkLocalBinary(info) {
|
|
114
|
+
const localPaths = [
|
|
115
|
+
path.join(__dirname, '..', '..', 'dist', info.binaryName),
|
|
116
|
+
path.join(__dirname, '..', '..', info.binaryName),
|
|
117
|
+
path.join(__dirname, '..', '..', `qy-server${info.ext}`)
|
|
118
|
+
];
|
|
119
|
+
|
|
120
|
+
for (const localPath of localPaths) {
|
|
121
|
+
if (fs.existsSync(localPath)) {
|
|
122
|
+
console.log(`使用本地二进制文件: ${localPath}`);
|
|
123
|
+
return localPath;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
return null;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// 主安装函数
|
|
130
|
+
async function install() {
|
|
131
|
+
console.log('========================================');
|
|
132
|
+
console.log(' QY-Server 安装程序');
|
|
133
|
+
console.log('========================================\n');
|
|
134
|
+
|
|
135
|
+
try {
|
|
136
|
+
const info = getPlatformInfo();
|
|
137
|
+
console.log(`平台: ${info.platform} (${info.arch})`);
|
|
138
|
+
console.log(`二进制文件: ${info.binaryName}\n`);
|
|
139
|
+
|
|
140
|
+
const binDir = path.join(__dirname, '..', 'bin');
|
|
141
|
+
const binaryPath = path.join(binDir, `qy-server${info.ext}`);
|
|
142
|
+
|
|
143
|
+
// 确保 bin 目录存在
|
|
144
|
+
if (!fs.existsSync(binDir)) {
|
|
145
|
+
fs.mkdirSync(binDir, { recursive: true });
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// 检查是否已安装
|
|
149
|
+
if (fs.existsSync(binaryPath)) {
|
|
150
|
+
console.log('二进制文件已存在,跳过下载');
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// 检查本地编译的文件
|
|
155
|
+
const localBinary = checkLocalBinary(info);
|
|
156
|
+
if (localBinary) {
|
|
157
|
+
fs.copyFileSync(localBinary, binaryPath);
|
|
158
|
+
fs.chmodSync(binaryPath, 0o755);
|
|
159
|
+
console.log('安装完成(使用本地文件)');
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// 下载二进制文件
|
|
164
|
+
const downloadUrl = getDownloadUrl(info.binaryName);
|
|
165
|
+
|
|
166
|
+
try {
|
|
167
|
+
await downloadFile(downloadUrl, binaryPath);
|
|
168
|
+
fs.chmodSync(binaryPath, 0o755);
|
|
169
|
+
console.log('\n安装完成!');
|
|
170
|
+
} catch (downloadError) {
|
|
171
|
+
console.error(`\n下载失败: ${downloadError.message}`);
|
|
172
|
+
console.log('\n请手动下载或编译二进制文件:');
|
|
173
|
+
console.log(` 1. 从 GitHub Releases 下载: https://github.com/${GITHUB_REPO}/releases`);
|
|
174
|
+
console.log(' 2. 或克隆仓库后运行: go build -o qy-server ./cmd/qy-server');
|
|
175
|
+
console.log(` 3. 将二进制文件复制到: ${binaryPath}`);
|
|
176
|
+
|
|
177
|
+
// 创建一个占位脚本
|
|
178
|
+
const placeholder = info.platform === 'win32'
|
|
179
|
+
? '@echo 请先下载 qy-server 二进制文件\n@exit /b 1'
|
|
180
|
+
: '#!/bin/sh\necho "请先下载 qy-server 二进制文件"\nexit 1';
|
|
181
|
+
|
|
182
|
+
fs.writeFileSync(binaryPath, placeholder);
|
|
183
|
+
fs.chmodSync(binaryPath, 0o755);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
} catch (error) {
|
|
187
|
+
console.error('安装失败:', error.message);
|
|
188
|
+
process.exit(1);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// 运行安装
|
|
193
|
+
install().catch(console.error);
|
package/package.json
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@qingchencloud/qy-server",
|
|
3
|
+
"version": "1.0.2",
|
|
4
|
+
"description": "晴云私有代理服务端 - 支持 TLS 加密、端口转发、内网穿透",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"proxy",
|
|
7
|
+
"vpn",
|
|
8
|
+
"tunnel",
|
|
9
|
+
"nat",
|
|
10
|
+
"port-forward",
|
|
11
|
+
"tls",
|
|
12
|
+
"private-proxy"
|
|
13
|
+
],
|
|
14
|
+
"homepage": "https://github.com/1186258278/QingYun",
|
|
15
|
+
"bugs": {
|
|
16
|
+
"url": "https://github.com/1186258278/QingYun/issues"
|
|
17
|
+
},
|
|
18
|
+
"repository": {
|
|
19
|
+
"type": "git",
|
|
20
|
+
"url": "git+https://github.com/1186258278/QingYun.git"
|
|
21
|
+
},
|
|
22
|
+
"license": "MIT",
|
|
23
|
+
"author": "qingchencloud",
|
|
24
|
+
"main": "lib/index.js",
|
|
25
|
+
"bin": {
|
|
26
|
+
"qy-server": "bin/qy-server"
|
|
27
|
+
},
|
|
28
|
+
"scripts": {
|
|
29
|
+
"postinstall": "node lib/install.js",
|
|
30
|
+
"test": "node lib/index.js --version"
|
|
31
|
+
},
|
|
32
|
+
"files": [
|
|
33
|
+
"bin/",
|
|
34
|
+
"lib/",
|
|
35
|
+
"README.md"
|
|
36
|
+
],
|
|
37
|
+
"engines": {
|
|
38
|
+
"node": ">=14"
|
|
39
|
+
},
|
|
40
|
+
"os": [
|
|
41
|
+
"darwin",
|
|
42
|
+
"linux",
|
|
43
|
+
"win32"
|
|
44
|
+
],
|
|
45
|
+
"cpu": [
|
|
46
|
+
"x64",
|
|
47
|
+
"arm64"
|
|
48
|
+
],
|
|
49
|
+
"publishConfig": {
|
|
50
|
+
"access": "public"
|
|
51
|
+
}
|
|
52
|
+
}
|