fcuni 1.0.9 → 1.1.0

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/bin/index.js ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env node
2
+ import process from 'node:process'
3
+
4
+ // 导入主程序
5
+ import('../dist/index.js').catch((err) => {
6
+ console.error('Failed to load CLI:', err)
7
+ process.exit(1)
8
+ })
package/dist/index.js ADDED
@@ -0,0 +1,117 @@
1
+ #!/usr/bin/env node
2
+ import minimist from 'minimist';
3
+ import { pkg } from './info.js';
4
+ import { createFilesFromResponse, deleteModules } from './request.js';
5
+
6
+ // 显示帮助信息
7
+ function logHelp() {
8
+ console.log('\n-----fcuni命令-----\n');
9
+ console.log('创建模块:');
10
+ console.log(' 网络请求 : fcuni c request');
11
+ console.log(' 网络上传 : fcuni c upload');
12
+ console.log(' 网络下载 : fcuni c download');
13
+ console.log(' WebSocket : fcuni c websocket');
14
+ console.log(' 国际化 : fcuni c locale');
15
+ console.log(' 权限申请 : fcuni c authorize');
16
+ console.log(' 应用更新 : fcuni c updated');
17
+ console.log(' 极光推送 : fcuni c jgPush');
18
+ console.log(' 实用工具 : fcuni c utils\n');
19
+ console.log('更新模块:');
20
+ console.log(' 网络请求 : fcuni u request');
21
+ console.log(' 网络上传 : fcuni u upload');
22
+ console.log(' 网络下载 : fcuni u download');
23
+ console.log(' WebSocket : fcuni u websocket');
24
+ console.log(' 国际化 : fcuni u locale');
25
+ console.log(' 权限申请 : fcuni u authorize');
26
+ console.log(' 应用更新 : fcuni u updated');
27
+ console.log(' 极光推送 : fcuni u jgPush');
28
+ console.log(' 实用工具 : fcuni u utils\n');
29
+ console.log('移除模块:');
30
+ console.log(' 网络请求 : fcuni d request');
31
+ console.log(' 网络上传 : fcuni d upload');
32
+ console.log(' 网络下载 : fcuni d download');
33
+ console.log(' WebSocket : fcuni d websocket');
34
+ console.log(' 国际化 : fcuni d locale');
35
+ console.log(' 权限申请 : fcuni d authorize');
36
+ console.log(' 应用更新 : fcuni d updated');
37
+ console.log(' 极光推送 : fcuni d jgPush');
38
+ console.log(' 实用工具 : fcuni d utils\n');
39
+ console.log('自动生成代码:');
40
+ console.log(' 生成api代码(本地文件) : fcuni api [文件路径]');
41
+ console.log(' 生成api代码(网络接口) : fcuni api [project_id] [api-token]\n');
42
+ }
43
+
44
+ // 安装模块
45
+ async function installModules(modules) {
46
+ try {
47
+
48
+ const result = await createFilesFromResponse(modules);
49
+
50
+ if (result.success) {
51
+ return true;
52
+ } else {
53
+ const failedModules = Object.entries(result.failures)
54
+ .filter(([_, failed]) => failed)
55
+ .map(([module]) => module);
56
+
57
+ return failedModules;
58
+ }
59
+ } catch (error) {
60
+ throw new Error(`模块安装失败: ${error.message}`);
61
+ }
62
+ }
63
+
64
+ // 主函数
65
+ async function main() {
66
+ const args = minimist(process.argv.slice(2));
67
+ // 显示版本或帮助
68
+ if (args.v || args.version) {
69
+ console.log(pkg.version);
70
+ return;
71
+ }
72
+ if (args.h || args.help) {
73
+ logHelp();
74
+ return;
75
+ }
76
+
77
+ // 获取输入参数
78
+ const command = args._[0];
79
+ const subCommands = args._.slice(1); // 获取从第二个参数开始的所有参数
80
+ if (!command || subCommands.length === 0) {
81
+ console.error('❌ 命令行错误,可以输入 fcuni -h 查看帮助');
82
+ return;
83
+ }
84
+
85
+ // 解析子命令
86
+ if (command === 'c' || command === 'create' || command === 'u' || command === 'update') {
87
+ const failedModules = await installModules(subCommands);
88
+ if (failedModules.length > 0) {
89
+ console.error(`❌ 以下模块安装失败: ${failedModules.join(', ')}`);
90
+ } else {
91
+ console.log(`✅ ${subCommands.join(', ')} 模块安装成功`);
92
+ }
93
+ } else if (command === 'd' || command === 'delete') {
94
+ const failedModules = deleteModules(subCommands);
95
+ if (failedModules.length !== 0) {
96
+ console.error(`❌ ${failedModules.join(', ')} 模块移除失败`);
97
+ } else {
98
+ console.log(`✅ ${subCommands.join(', ')} 模块移除成功`);
99
+ }
100
+ } else {
101
+ console.error('❌ 命令行错误');
102
+ logHelp();
103
+ return;
104
+ }
105
+ }
106
+
107
+ // 错误处理
108
+ process.on('unhandledRejection', (reason) => {
109
+ console.log(`致命错误: ${reason.message || reason}`);
110
+ process.exit(1);
111
+ });
112
+
113
+ // 执行主函数
114
+ main().catch(err => {
115
+ console.log(err.message);
116
+ process.exit(1);
117
+ });
package/dist/info.js ADDED
@@ -0,0 +1,10 @@
1
+ import { readFileSync } from 'node:fs';
2
+ import { fileURLToPath } from 'node:url';
3
+ import path from 'node:path';
4
+
5
+ const __filename = fileURLToPath(import.meta.url);
6
+ const __dirname = path.dirname(__filename);
7
+
8
+ const pkgPath = path.join(__dirname, '../package.json');
9
+ const pkgContent = readFileSync(pkgPath, 'utf8');
10
+ export const pkg = JSON.parse(pkgContent);
@@ -0,0 +1,139 @@
1
+ import { promises as fs } from 'fs';
2
+ import { existsSync, lstatSync, rmSync, unlinkSync } from 'fs';
3
+ import { dirname, resolve, join } from 'path';
4
+
5
+ // 网络请求URL
6
+ const apiUrl = "https://mock.apipost.net/mock/570d229f6088000/?apipost_id=2fd1a15d3c950f";
7
+
8
+ // 模块注释配置
9
+ const MODULE_COMMENTS = {
10
+ request: [7, 33],
11
+ upload: [8, 35],
12
+ download: [9, 37],
13
+ websocket: [10, 39],
14
+ locale: [4, 27],
15
+ updated: [5, 29],
16
+ utils: [6, 31],
17
+ authorize: [12, 42],
18
+ jgpush: [13, 44]
19
+ };
20
+
21
+ // 网络请求
22
+ async function httpRequest(module) {
23
+ try {
24
+ const response = await fetch(apiUrl, {
25
+ method: 'POST',
26
+ headers: { 'Content-Type': 'application/json' },
27
+ body: JSON.stringify({ modules: module })
28
+ });
29
+
30
+ if (!response.ok) throw new Error(`请求失败,状态码: ${response.status}`);
31
+ return await response.json();
32
+ } catch (error) {
33
+ console.error(`模块 ${module} 请求失败:`, error.message);
34
+ return null;
35
+ }
36
+ }
37
+
38
+ // 创建文件
39
+ async function createFile(projectDir, filePath, content) {
40
+ const fullPath = resolve(projectDir, filePath);
41
+
42
+ // 如果文件路径以 src 开头,则检查文件是否存在
43
+ if (filePath.startsWith('src')) {
44
+ try {
45
+ await fs.access(fullPath);
46
+ // 文件已存在,不创建
47
+ return;
48
+ } catch {
49
+ // 文件不存在,继续创建流程
50
+ }
51
+ }
52
+
53
+ await fs.mkdir(dirname(fullPath), { recursive: true });
54
+ await fs.writeFile(fullPath, content || '');
55
+ }
56
+
57
+ // 修改注释
58
+ async function toggleComments(projectDir, indices) {
59
+ const indexPath = resolve(projectDir, 'fcuni/index.ts');
60
+ if (!(await fs.stat(indexPath).catch(() => false))) return;
61
+
62
+ const content = await fs.readFile(indexPath, 'utf8');
63
+ const lines = content.split('\n');
64
+
65
+ for (const index of indices) {
66
+ const lineNum = index - 1;
67
+ if (!lines[lineNum]) continue;
68
+
69
+ // 移除行首注释
70
+ lines[lineNum] = lines[lineNum].replace(/^\s*\/\//, '').trim();
71
+ }
72
+
73
+ await fs.writeFile(indexPath, lines.join('\n'));
74
+ }
75
+
76
+ // 主函数
77
+ export async function createFilesFromResponse(modules) {
78
+
79
+ const projectDir = join(process.cwd(), '');
80
+
81
+ const results = { success: true, failures: {} };
82
+
83
+ for (const module of modules) {
84
+ try {
85
+ const response = await httpRequest(module);
86
+ if (!response) throw new Error('无响应数据');
87
+
88
+ // 创建文件
89
+ await Promise.all(
90
+ Object.entries(response).map(([file, content]) =>
91
+ createFile(projectDir, file, content)
92
+ )
93
+ );
94
+
95
+ // 处理注释
96
+ if (MODULE_COMMENTS[module]) {
97
+ await toggleComments(projectDir, MODULE_COMMENTS[module]);
98
+ }
99
+ } catch (error) {
100
+ console.error(`模块 ${module} 处理失败:`, error.message);
101
+ results.failures[module] = true;
102
+ results.success = false;
103
+ }
104
+ }
105
+
106
+ return results;
107
+ }
108
+
109
+ // 安全删除(文件/目录)
110
+ export function deleteModules(modules) {
111
+
112
+ const projectDir = join(process.cwd(), 'fcuni');
113
+
114
+ let failureModules = []; // 记录删除失败的模块
115
+
116
+ for (const module of modules) {
117
+ const resolvedPath = join(projectDir, module);
118
+
119
+ try {
120
+ if (existsSync(resolvedPath)) {
121
+ const stats = lstatSync(resolvedPath);
122
+
123
+ if (stats.isDirectory()) {
124
+ // 递归删除目录
125
+ rmSync(resolvedPath, { recursive: true, force: true });
126
+ } else {
127
+ // 删除文件
128
+ unlinkSync(resolvedPath);
129
+ }
130
+ } else {
131
+ failureModules.push(module);
132
+ }
133
+ } catch (err) {
134
+ failureModules.push(module);
135
+ }
136
+ }
137
+
138
+ return failureModules;
139
+ }
package/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "fcuni",
3
- "version": "1.0.9",
3
+ "version": "1.1.0",
4
4
  "description": "配合fc-uniapp项目使用的命令行工具",
5
5
  "bin": {
6
- "fcuni": "./os.js"
6
+ "fcuni": "bin/index.js"
7
7
  },
8
8
  "preferGlobal": true,
9
9
  "keywords": [
@@ -17,5 +17,12 @@
17
17
  "license": "Apache-2.0",
18
18
  "main": "lib/index.ts",
19
19
  "module": "lib/index.ts",
20
- "types": "lib/type.d.ts"
20
+ "types": "lib/type.d.ts",
21
+ "type": "module",
22
+ "dependencies": {
23
+ "minimist": "^1.2.8"
24
+ },
25
+ "devDependencies": {
26
+ "@types/minimist": "^1.2.5"
27
+ }
21
28
  }
package/os.js DELETED
@@ -1,298 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- // 文件操作
4
- const fs = require('fs');
5
- const path = require('path');
6
- // 使用当前工作目
7
- const libPath = path.join(process.cwd(), 'fcuni');
8
- const indexTsPath = path.join(libPath, 'index.ts');
9
- // 命令参数解析
10
- const [command, target] = process.argv.slice(2);
11
- const apiUrl = "https://mock.apipost.net/mock/570d229f6088000/?apipost_id=bb72a593c9089";
12
- const modules = ['request', 'upload', 'download', 'websocket', 'locale', 'authorize', 'updated', 'jgpush', 'utils'];
13
-
14
- // 网络请求,确保 Node.js 版本是 18 或更高
15
- async function makeRequest() {
16
- try {
17
- const fetchOptions = {
18
- method: 'POST',
19
- headers: {
20
- 'Content-Type': 'application/json',
21
- 'Access-Control-Allow-Origin': '*'
22
- },
23
- body: JSON.stringify({
24
- "modules": target
25
- })
26
- };
27
-
28
- const response = await fetch(apiUrl, fetchOptions);
29
-
30
- if (!response.ok) {
31
- throw new Error(`HTTP error! status: ${response.status}`);
32
- }
33
-
34
- const data = await response.json();
35
- return data;
36
- } catch (error) {
37
- console.error('请求失败:', error.message);
38
- return null;
39
- }
40
- }
41
-
42
- // 创建文件(自动创建父目录)
43
- const createFile = (filePath, content = '') => {
44
- const resolvedPath = path.resolve(filePath);
45
- const dir = path.dirname(resolvedPath);
46
-
47
- // 确保父目录存在
48
- if (!fs.existsSync(dir)) {
49
- fs.mkdirSync(dir, { recursive: true });
50
- }
51
-
52
- fs.writeFileSync(resolvedPath, content);
53
- console.log(`✅ ${target} 模块创建成功`);
54
- return true;
55
- };
56
-
57
- // 安全删除(文件/目录)
58
- const deleteItem = (itemPath) => {
59
- const resolvedPath = path.resolve(itemPath);
60
-
61
- if (!fs.existsSync(resolvedPath)) {
62
- console.warn(`⚠️ ${target} 模块不存在`);
63
- return false;
64
- }
65
-
66
- // 预防删除关键目录(根据项目调整)
67
- const protectedPaths = [
68
- process.cwd(), // 项目根目录
69
- path.join(process.cwd(), 'node_modules'),
70
- path.join(process.cwd(), '.git')
71
- ];
72
-
73
- if (protectedPaths.includes(resolvedPath)) {
74
- throw new Error(`❌ 禁止移除受保护模块`);
75
- }
76
-
77
- try {
78
- const stats = fs.lstatSync(resolvedPath);
79
-
80
- if (stats.isDirectory()) {
81
- // 递归删除目录
82
- fs.rmSync(resolvedPath, { recursive: true, force: true });
83
- } else {
84
- // 删除文件
85
- fs.unlinkSync(resolvedPath);
86
- }
87
- console.log(`✅ 模块已移除: ${target}`);
88
- return true;
89
- } catch (err) {
90
- console.error(`❌ 模块移除失败: ${err.message}`);
91
- return false;
92
- }
93
- };
94
-
95
- // 命令解析
96
- if (
97
- command == "help"
98
- || !command
99
- || !['c', 'cre', 'create', 'd', 'dle', 'delete', 'u', 'upd', 'update', 'help'].includes(command)
100
- || !modules.includes(target)
101
- ) {
102
- console.log('\n-----fcuni命令-----\n');
103
- console.log('创建模块:');
104
- console.log(' 网络请求 : fcuni c request');
105
- console.log(' 网络上传 : fcuni c upload');
106
- console.log(' 网络下载 : fcuni c download');
107
- console.log(' WebSocket : fcuni c websocket');
108
- console.log(' 国际化 : fcuni c locale');
109
- console.log(' 权限申请 : fcuni c authorize');
110
- console.log(' 应用更新 : fcuni c updated');
111
- console.log(' 极光推送 : fcuni c jgPush');
112
- console.log(' 实用工具 : fcuni c utils\n');
113
- console.log('更新模块:');
114
- console.log(' 网络请求 : fcuni u request');
115
- console.log(' 网络上传 : fcuni u upload');
116
- console.log(' 网络下载 : fcuni u download');
117
- console.log(' WebSocket : fcuni u websocket');
118
- console.log(' 国际化 : fcuni u locale');
119
- console.log(' 权限申请 : fcuni u authorize');
120
- console.log(' 应用更新 : fcuni u updated');
121
- console.log(' 极光推送 : fcuni u jgPush');
122
- console.log(' 实用工具 : fcuni u utils\n');
123
- console.log('删除模块:');
124
- console.log(' 网络请求 : fcuni d request');
125
- console.log(' 网络上传 : fcuni d upload');
126
- console.log(' 网络下载 : fcuni d download');
127
- console.log(' WebSocket : fcuni d websocket');
128
- console.log(' 国际化 : fcuni d locale');
129
- console.log(' 权限申请 : fcuni d authorize');
130
- console.log(' 应用更新 : fcuni d updated');
131
- console.log(' 极光推送 : fcuni d jgPush');
132
- console.log(' 实用工具 : fcuni d utils\n');
133
- process.exit(1);
134
- }
135
-
136
- // 根据 API 响应数据动态创建文件的函数
137
- async function createFilesFromResponse() {
138
- try {
139
- const response = await makeRequest();
140
-
141
- if (response && typeof response === 'object') {
142
- // 遍历响应对象的键值对,为每个键值对创建一个文件
143
- for (const [filePath, content] of Object.entries(response)) {
144
- createFile(path.join(libPath, target, filePath), content);
145
- }
146
- } else {
147
- console.error(`❌ network:${target} 模块创建失败,请重试`);
148
- }
149
- } catch (error) {
150
- console.error(`❌ network:${target} 模块创建失败: ${error.message}`);
151
- }
152
- }
153
-
154
- // 为index.ts添加或移除模块和注释
155
- function addOrRemoveComment(indices) {
156
- if (command === 'c' || command === 'cre' || command === 'create') {
157
- try {
158
- // 调用 API 并根据返回结果创建文件
159
- createFilesFromResponse();
160
-
161
- if (!indices || indices.length === 0) {
162
- console.log(`✅ 已添加 ${target} 模块`);
163
- return;
164
- }
165
-
166
- const content = fs.readFileSync(indexTsPath, 'utf8');
167
- const lines = content.split('\n');
168
- let successCount = 0;
169
- let alreadyExistsCount = 0;
170
-
171
- for (const index of indices) {
172
- const line = index - 1;
173
- if (lines[line]) {
174
- // 使用正则表达式保持缩进结构
175
- const lineContent = lines[line];
176
- const match = lineContent.match(/^(\s*)(\/\/)?(.*)$/);
177
- if (match) {
178
- const [full, indent, comment, rest] = match;
179
- if (comment) {
180
- // 删除注释符号和后面的空格,保持缩进
181
- lines[line] = indent + rest.trim();
182
- successCount++;
183
- } else {
184
- alreadyExistsCount++;
185
- }
186
- }
187
- } else {
188
- alreadyExistsCount++;
189
- }
190
- }
191
-
192
- if (successCount > 0) {
193
- fs.writeFileSync(indexTsPath, lines.join('\n'));
194
- console.log(`✅ 已添加 ${target} 模块`);
195
- }
196
-
197
- if (alreadyExistsCount > 0) {
198
- console.warn(`⚠️ ${target} 模块已经存在`);
199
- }
200
-
201
- } catch (err) {
202
- console.error(`❌ 操作${target} 模块失败: ${err.message}`);
203
- }
204
- } else if (command === 'd' || command === 'dle' || command === 'delete') {
205
- try {
206
- // 删除 lib 目录下的模块文件
207
- deleteItem(path.join(libPath, target));
208
-
209
- if (!indices || indices.length === 0) {
210
- console.log(`✅ 已移除 ${target} 模块`);
211
- return;
212
- }
213
-
214
- const content = fs.readFileSync(indexTsPath, 'utf8');
215
- const lines = content.split('\n');
216
- let successCount = 0;
217
- let alreadyRemovedCount = 0;
218
-
219
- for (const index of indices) {
220
- const line = index - 1;
221
- if (lines[line]) {
222
- // 使用正则表达式保持缩进结构
223
- const lineContent = lines[line];
224
- const match = lineContent.match(/^(\s*)(\/\/)?(.*)$/);
225
- if (match) {
226
- const [full, indent, comment, rest] = match;
227
- if (!comment) {
228
- // 添加注释符号,保持缩进
229
- lines[line] = indent + '// ' + rest;
230
- successCount++;
231
- } else {
232
- alreadyRemovedCount++;
233
- }
234
- }
235
- } else {
236
- alreadyRemovedCount++;
237
- }
238
- }
239
-
240
- if (successCount > 0) {
241
- fs.writeFileSync(indexTsPath, lines.join('\n'));
242
- console.log(`✅ 已移除 ${target} 模块`);
243
- }
244
-
245
- if (alreadyRemovedCount > 0) {
246
- console.warn(`⚠️ ${target} 模块已经移除`);
247
- }
248
-
249
- } catch (err) {
250
- console.error(`❌ 操作${target} 模块失败: ${err.message}`);
251
- }
252
- } else if (command === 'u' || command === 'upd' || command === 'update') {
253
- createFilesFromResponse();
254
- } else {
255
- console.error(`❌ 命令行错误,可以输入 fcuni help 查看帮助`);
256
- }
257
- }
258
-
259
- try {
260
- if (!target) throw new Error('缺少目标路径参数');
261
- console.log(`✅ 执行 ${target} 模块操作`);
262
-
263
- switch (target) {
264
- case 'request':
265
- addOrRemoveComment([7, 33]);
266
- break;
267
- case 'upload':
268
- addOrRemoveComment([8, 35]);
269
- break;
270
- case 'download':
271
- addOrRemoveComment([9, 37]);
272
- break;
273
- case 'websocket':
274
- addOrRemoveComment([10, 39]);
275
- break;
276
- case 'locale':
277
- addOrRemoveComment([4, 27]);
278
- break;
279
- case 'updated':
280
- addOrRemoveComment([5, 29]);
281
- break;
282
- case 'utils':
283
- addOrRemoveComment([6, 31]);
284
- break;
285
- case 'authorize':
286
- addOrRemoveComment([12, 42]);
287
- break;
288
- case 'jgpush':
289
- addOrRemoveComment([13, 44]);
290
- break;
291
-
292
- default:
293
- break;
294
- }
295
- } catch (err) {
296
- console.error(`❌ 错误: ${err.message}`);
297
- process.exit(1);
298
- }