@kezh/my-custom-js-converter 1.6.0 → 1.6.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.
@@ -1,302 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- /**
4
- * 人工审批测试脚本
5
- *
6
- * 运行 encode → decode 流程,将原文件、编码后文件、解码后文件并排展示,
7
- * 由人工比对确认转换结果是否正确。
8
- *
9
- * 用法:
10
- * node test/manual_review.js
11
- * npm run test:manual
12
- */
13
-
14
- const fs = require('fs');
15
- const path = require('path');
16
- const { execSync } = require('child_process');
17
- const os = require('os');
18
- const readline = require('readline');
19
-
20
- // ─── Constants ───────────────────────────────────────────────────────────────
21
- const PROJECT_ROOT = path.resolve(__dirname, '..');
22
- const COMPILED_CORE = path.join(PROJECT_ROOT, 'core');
23
- const FIXTURE_DIR = path.join(PROJECT_ROOT, 'test', 'fixtures', 'sample_project');
24
-
25
- // ─── Helpers ─────────────────────────────────────────────────────────────────
26
- let tempDir = '';
27
-
28
- function log(section, msg) {
29
- console.log(`\n[${section}] ${msg}`);
30
- }
31
-
32
- function setupTempProject() {
33
- tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'converter-review-'));
34
- log('SETUP', `临时项目: ${tempDir}`);
35
-
36
- const srcDir = path.join(tempDir, 'src');
37
- const utilDir = path.join(srcDir, 'util');
38
- fs.mkdirSync(utilDir, { recursive: true });
39
- // libs 目录(通用依赖库,对应 config.libs: ["@/util"])
40
- const libUtilDir = path.join(tempDir, 'util');
41
- fs.mkdirSync(libUtilDir, { recursive: true });
42
-
43
- // 复制 fixture 源文件
44
- fs.copyFileSync(
45
- path.join(FIXTURE_DIR, 'src', 'index.js'),
46
- path.join(srcDir, 'index.js')
47
- );
48
- fs.copyFileSync(
49
- path.join(FIXTURE_DIR, 'src', 'util', 'index.js'),
50
- path.join(utilDir, 'index.js')
51
- );
52
- fs.copyFileSync(
53
- path.join(FIXTURE_DIR, 'src', 'helper.js'),
54
- path.join(srcDir, 'helper.js')
55
- );
56
- // 复制 libs 依赖文件
57
- fs.copyFileSync(
58
- path.join(FIXTURE_DIR, 'util', 'drawer.js'),
59
- path.join(libUtilDir, 'drawer.js')
60
- );
61
- fs.copyFileSync(
62
- path.join(FIXTURE_DIR, 'util', 'form.js'),
63
- path.join(libUtilDir, 'form.js')
64
- );
65
-
66
- // 复制 config.json 并动态设置 baseDir
67
- const configPath = path.join(tempDir, 'config.json');
68
- fs.copyFileSync(
69
- path.join(FIXTURE_DIR, 'config.json'),
70
- configPath
71
- );
72
- const configData = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
73
- configData.baseDir = tempDir;
74
- fs.writeFileSync(configPath, JSON.stringify(configData, null, 2), 'utf-8');
75
-
76
- // 创建 node_modules 符号链接
77
- const modDir = path.join(tempDir, 'node_modules', '@kezh', 'my-custom-js-converter');
78
- fs.mkdirSync(modDir, { recursive: true });
79
-
80
- const coreLink = path.join(modDir, 'core');
81
- if (os.platform() === 'win32') {
82
- fs.symlinkSync(COMPILED_CORE, coreLink, 'junction');
83
- } else {
84
- fs.symlinkSync(COMPILED_CORE, coreLink);
85
- }
86
-
87
- const pkgLink = path.join(modDir, 'package.json');
88
- if (os.platform() === 'win32') {
89
- fs.copyFileSync(path.join(PROJECT_ROOT, 'package.json'), pkgLink);
90
- } else {
91
- fs.symlinkSync(path.join(PROJECT_ROOT, 'package.json'), pkgLink);
92
- }
93
-
94
- log('SETUP', '临时项目创建完成');
95
- }
96
-
97
- function cleanup() {
98
- if (tempDir && fs.existsSync(tempDir)) {
99
- fs.rmSync(tempDir, { recursive: true, force: true });
100
- log('CLEANUP', `已清理 ${tempDir}`);
101
- }
102
- }
103
-
104
- function runEncode() {
105
- const encodeBin = path.join(tempDir, 'node_modules', '@kezh', 'my-custom-js-converter', 'core', 'encode', 'index.js');
106
- log('ENCODE', `执行: node ${encodeBin}`);
107
- const output = execSync(`node "${encodeBin}"`, {
108
- cwd: tempDir,
109
- encoding: 'utf-8',
110
- timeout: 30000
111
- });
112
- log('ENCODE', output);
113
- }
114
-
115
- function runDecode() {
116
- const decodeBin = path.join(tempDir, 'node_modules', '@kezh', 'my-custom-js-converter', 'core', 'decode', 'index.js');
117
- log('DECODE', `执行: node ${decodeBin}`);
118
- const output = execSync(`node "${decodeBin}"`, {
119
- cwd: tempDir,
120
- encoding: 'utf-8',
121
- timeout: 30000
122
- });
123
- log('DECODE', output);
124
- }
125
-
126
- // ─── Display helpers ─────────────────────────────────────────────────────────
127
-
128
- const TERMINAL_COLORS = {
129
- reset: '\x1b[0m',
130
- bold: '\x1b[1m',
131
- dim: '\x1b[2m',
132
- red: '\x1b[31m',
133
- green: '\x1b[32m',
134
- yellow: '\x1b[33m',
135
- blue: '\x1b[34m',
136
- cyan: '\x1b[36m',
137
- white: '\x1b[37m',
138
- bgBlue: '\x1b[44m',
139
- bgGreen: '\x1b[42m',
140
- bgRed: '\x1b[41m',
141
- bgYellow: '\x1b[43m',
142
- };
143
-
144
- function color(text, ...colors) {
145
- return colors.join('') + text + TERMINAL_COLORS.reset;
146
- }
147
-
148
- function divider(title, width = 80) {
149
- const pad = Math.max(0, width - title.length - 2);
150
- const left = Math.floor(pad / 2);
151
- const right = pad - left;
152
- return color('─'.repeat(left) + ' ' + title + ' ' + '─'.repeat(right), TERMINAL_COLORS.dim);
153
- }
154
-
155
- function numberedLines(content) {
156
- const lines = content.split(/\r?\n/);
157
- const maxNum = lines.length;
158
- const width = String(maxNum).length;
159
- return lines.map((line, i) => {
160
- const num = String(i + 1).padStart(width, ' ');
161
- return color(num + ' │ ', TERMINAL_COLORS.dim) + line;
162
- }).join('\n');
163
- }
164
-
165
- function showFile(label, filePath) {
166
- console.log('\n' + divider(label));
167
- if (!fs.existsSync(filePath)) {
168
- console.log(color(` 文件不存在: ${filePath}`, TERMINAL_COLORS.red));
169
- return;
170
- }
171
- const content = fs.readFileSync(filePath, 'utf-8');
172
- console.log(numberedLines(content));
173
- console.log(color(` (${filePath})`, TERMINAL_COLORS.dim));
174
- }
175
-
176
- function showMapFile(filePath) {
177
- console.log('\n' + divider('mod.map (依赖映射)'));
178
- if (!fs.existsSync(filePath)) {
179
- console.log(color(` 文件不存在: ${filePath}`, TERMINAL_COLORS.red));
180
- return;
181
- }
182
- const content = fs.readFileSync(filePath, 'utf-8');
183
- console.log(numberedLines(content));
184
- console.log(color(` (${filePath})`, TERMINAL_COLORS.dim));
185
- }
186
-
187
- // ─── Interactive prompt ──────────────────────────────────────────────────────
188
-
189
- function askQuestion(query) {
190
- const rl = readline.createInterface({
191
- input: process.stdin,
192
- output: process.stdout
193
- });
194
- return new Promise(resolve => {
195
- rl.question(query, answer => {
196
- rl.close();
197
- resolve(answer.trim());
198
- });
199
- });
200
- }
201
-
202
- // ─── Main ────────────────────────────────────────────────────────────────────
203
-
204
- async function main() {
205
- console.log(color('╔══════════════════════════════════════════════════════════╗', TERMINAL_COLORS.cyan));
206
- console.log(color('║ my-custom-js-converter 人工审批测试 ║', TERMINAL_COLORS.cyan));
207
- console.log(color('╚══════════════════════════════════════════════════════════╝', TERMINAL_COLORS.cyan));
208
-
209
- // 检查编译产物
210
- if (!fs.existsSync(COMPILED_CORE)) {
211
- console.error(color('\n错误: 项目未编译,请先运行 npm run build', TERMINAL_COLORS.red));
212
- process.exit(1);
213
- }
214
-
215
- try {
216
- // 1. 设置临时项目
217
- setupTempProject();
218
-
219
- // 2. 展示原始文件
220
- console.log('\n' + color('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━', TERMINAL_COLORS.bold));
221
- console.log(color(' 第一步: 查看原始文件', TERMINAL_COLORS.bold + TERMINAL_COLORS.bgBlue + TERMINAL_COLORS.white));
222
- console.log(color('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━', TERMINAL_COLORS.bold));
223
-
224
- showFile('原始文件: src/index.js (入口)', path.join(tempDir, 'src', 'index.js'));
225
- showFile('原始文件: src/util/index.js (依赖模块)', path.join(tempDir, 'src', 'util', 'index.js'));
226
- showFile('原始文件: src/helper.js (依赖模块)', path.join(tempDir, 'src', 'helper.js'));
227
- showFile('原始文件: util/drawer.js (libs 依赖)', path.join(tempDir, 'util', 'drawer.js'));
228
- showFile('原始文件: util/form.js (libs 依赖)', path.join(tempDir, 'util', 'form.js'));
229
-
230
- await askQuestion(color('\n按 Enter 继续执行 encode ...', TERMINAL_COLORS.yellow));
231
-
232
- // 3. 执行 encode
233
- console.log('\n' + color('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━', TERMINAL_COLORS.bold));
234
- console.log(color(' 第二步: 执行 encode 并查看编码结果', TERMINAL_COLORS.bold + TERMINAL_COLORS.bgBlue + TERMINAL_COLORS.white));
235
- console.log(color('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━', TERMINAL_COLORS.bold));
236
-
237
- runEncode();
238
-
239
- showFile('编码后: src/coded.js', path.join(tempDir, 'src', 'coded.js'));
240
- showMapFile(path.join(tempDir, 'src', '.setting', 'mod.map'));
241
-
242
- await askQuestion(color('\n按 Enter 继续执行 decode ...', TERMINAL_COLORS.yellow));
243
-
244
- // 4. 执行 decode
245
- console.log('\n' + color('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━', TERMINAL_COLORS.bold));
246
- console.log(color(' 第三步: 执行 decode 并查看解码结果', TERMINAL_COLORS.bold + TERMINAL_COLORS.bgBlue + TERMINAL_COLORS.white));
247
- console.log(color('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━', TERMINAL_COLORS.bold));
248
-
249
- runDecode();
250
-
251
- showFile('解码后: src/decoded.js', path.join(tempDir, 'src', 'decoded.js'));
252
-
253
- // 5. 并排对比: 原始 vs 解码
254
- console.log('\n' + color('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━', TERMINAL_COLORS.bold));
255
- console.log(color(' 第四步: 原始文件 vs 解码文件 对比', TERMINAL_COLORS.bold + TERMINAL_COLORS.bgBlue + TERMINAL_COLORS.white));
256
- console.log(color('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━', TERMINAL_COLORS.bold));
257
-
258
- const originalContent = fs.readFileSync(path.join(tempDir, 'src', 'index.js'), 'utf-8');
259
- const decodedContent = fs.readFileSync(path.join(tempDir, 'src', 'decoded.js'), 'utf-8');
260
-
261
- console.log('\n' + divider('原始文件: src/index.js'));
262
- console.log(numberedLines(originalContent));
263
-
264
- console.log('\n' + divider('解码文件: src/decoded.js'));
265
- console.log(numberedLines(decodedContent));
266
-
267
- // 6. 人工审批
268
- console.log('\n' + color('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━', TERMINAL_COLORS.bold));
269
- console.log(color(' 人工审批', TERMINAL_COLORS.bold + TERMINAL_COLORS.bgYellow + TERMINAL_COLORS.white));
270
- console.log(color('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━', TERMINAL_COLORS.bold));
271
-
272
- console.log('\n请比对以上文件内容,确认转换结果是否正确:');
273
- console.log(color(' • 原始文件中的 require() 语句是否在解码后恢复', TERMINAL_COLORS.cyan));
274
- console.log(color(' • 编码后的 __modName 后缀是否在解码后正确移除', TERMINAL_COLORS.cyan));
275
- console.log(color(' • 依赖模块方法是否在解码后从内联中移除', TERMINAL_COLORS.cyan));
276
- console.log(color(' • 自身模块方法是否在编码/解码后保持不变', TERMINAL_COLORS.cyan));
277
- console.log(color(' • this.method() 调用是否正确还原为 dep.method()', TERMINAL_COLORS.cyan));
278
-
279
- const answer = await askQuestion(
280
- color('\n审批结果 [y=通过 / n=不通过 / s=跳过]: ', TERMINAL_COLORS.yellow)
281
- );
282
-
283
- if (answer.toLowerCase() === 'y') {
284
- console.log(color('\n✓ 人工审批通过', TERMINAL_COLORS.green));
285
- } else if (answer.toLowerCase() === 'n') {
286
- console.log(color('\n✗ 人工审批未通过', TERMINAL_COLORS.red));
287
- cleanup();
288
- process.exit(1);
289
- } else {
290
- console.log(color('\n- 人工审批已跳过', TERMINAL_COLORS.yellow));
291
- }
292
-
293
- } catch (err) {
294
- console.error(color('\n执行出错: ' + err.message, TERMINAL_COLORS.red));
295
- cleanup();
296
- process.exit(1);
297
- } finally {
298
- cleanup();
299
- }
300
- }
301
-
302
- main();