ai-yuca 1.5.2 → 1.5.3

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/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ai-yuca",
3
- "version": "1.5.2",
3
+ "version": "1.5.3",
4
4
  "description": "一个用AI生成的开发辅助工具",
5
5
  "main": "dist/src/index.js",
6
6
  "types": "dist/src/index.d.ts",
package/dist/src/gKeys.js CHANGED
@@ -40,6 +40,52 @@ exports.gKeys = gKeys;
40
40
  const fs = __importStar(require("fs"));
41
41
  const path = __importStar(require("path"));
42
42
  const fast_glob_1 = __importDefault(require("fast-glob"));
43
+ // 解析 tsconfig.json 中的 paths
44
+ function getTsconfigPaths(cwd) {
45
+ try {
46
+ const tsconfigPath = path.join(cwd, 'tsconfig.json');
47
+ if (fs.existsSync(tsconfigPath)) {
48
+ // 简单移除注释和尾随逗号再解析
49
+ const content = fs.readFileSync(tsconfigPath, 'utf8');
50
+ const cleanContent = content
51
+ .replace(/\/\*[\s\S]*?\*\/|\/\/.*/g, '')
52
+ .replace(/,\s*([\]}])/g, '$1');
53
+ const tsconfig = JSON.parse(cleanContent);
54
+ if (tsconfig.compilerOptions && tsconfig.compilerOptions.paths) {
55
+ return {
56
+ paths: tsconfig.compilerOptions.paths,
57
+ baseUrl: tsconfig.compilerOptions.baseUrl || '.'
58
+ };
59
+ }
60
+ }
61
+ }
62
+ catch (e) {
63
+ // 忽略解析错误
64
+ }
65
+ return null;
66
+ }
67
+ // 匹配路径别名
68
+ function resolveAliasPath(importPath, config, cwd) {
69
+ if (config.paths) {
70
+ for (const [aliasPattern, targetPaths] of Object.entries(config.paths)) {
71
+ if (!targetPaths || targetPaths.length === 0)
72
+ continue;
73
+ // 把 alias 结尾的 /* 去掉
74
+ const aliasBase = aliasPattern.replace(/\/\*$/, '');
75
+ // 如果 importPath 等于 aliasBase 或者以 aliasBase/ 开头
76
+ if (importPath === aliasBase || importPath.startsWith(aliasBase + '/')) {
77
+ const targetBase = targetPaths[0].replace(/\/\*$/, '');
78
+ const relativePath = importPath.substring(aliasBase.length);
79
+ return path.resolve(cwd, config.baseUrl, targetBase, relativePath.replace(/^\//, ''));
80
+ }
81
+ }
82
+ }
83
+ // 尝试直接基于 baseUrl 解析(非相对路径)
84
+ if (!importPath.startsWith('.') && !importPath.startsWith('/')) {
85
+ return path.resolve(cwd, config.baseUrl, importPath);
86
+ }
87
+ return null;
88
+ }
43
89
  async function gKeys(options) {
44
90
  const { source, regex, config: configPath } = options;
45
91
  if (!source) {
@@ -75,6 +121,7 @@ async function gKeys(options) {
75
121
  }
76
122
  // 默认正则匹配 {#...#}
77
123
  const regexPattern = regex ? new RegExp(regex, 'g') : /\{#(.+?)#\}/g;
124
+ const tsconfigPaths = getTsconfigPaths(process.cwd());
78
125
  console.log(`🚀 开始扫描 Pages: ${sourceAbs}`);
79
126
  console.log(`🔍 正则表达式: ${regexPattern}`);
80
127
  // 1. 找到所有 .tsx 入口文件
@@ -110,7 +157,7 @@ async function gKeys(options) {
110
157
  const keys = new Set();
111
158
  const processedFiles = new Set();
112
159
  // 递归处理文件,传入 keysDirAbs 用于忽略
113
- await processFile(entryFile, regexPattern, keys, processedFiles, sourceAbs, keysDirAbs);
160
+ await processFile(entryFile, regexPattern, keys, processedFiles, sourceAbs, keysDirAbs, tsconfigPaths);
114
161
  if (keys.size > 0) {
115
162
  const sortedKeys = Array.from(keys).sort();
116
163
  // 收集结果
@@ -150,8 +197,8 @@ function generateLangFile(filePath, data) {
150
197
  fs.writeFileSync(filePath, content, 'utf8');
151
198
  console.log(`\n🎉 已生成全局语言文件: ${filePath}`);
152
199
  }
153
- async function processFile(filePath, regex, keys, processedFiles, rootContext, ignoreDir // 需要忽略的目录路径 (config.crowdin.keysDir)
154
- ) {
200
+ async function processFile(filePath, regex, keys, processedFiles, rootContext, ignoreDir, // 需要忽略的目录路径 (config.crowdin.keysDir)
201
+ tsconfigPaths) {
155
202
  // 忽略 keysDir 目录下的文件,防止循环引用
156
203
  if (ignoreDir && path.resolve(filePath).startsWith(ignoreDir)) {
157
204
  return;
@@ -173,30 +220,44 @@ async function processFile(filePath, regex, keys, processedFiles, rootContext, i
173
220
  }
174
221
  }
175
222
  // 2. 分析 import 引用,递归处理
176
- const importRegex = /import\s+(?:(?:[\w{}\s,*]+)\s+from\s+)?['"]([^'"]+)['"]/g;
177
- let importMatch;
178
- while ((importMatch = importRegex.exec(content)) !== null) {
179
- let importPath = importMatch[1];
180
- let targetPath = '';
181
- // 处理 @ 别名
182
- if (importPath.startsWith('@/')) {
183
- // 假设 @ 指向 src 目录
184
- // 我们需要找到项目根目录下的 src
185
- // rootContext 是 sourceAbs,通常是 pages 目录
186
- // 假设项目结构是 root/src/pages
187
- // 所以 rootContext 往上两级可能是 root?或者 rootContext 本身就在 src 下?
188
- // 更稳妥的方式是查找 tsconfig.json 或 jsconfig.json 中的 paths 配置
189
- // 但为了简单,我们假设 @ -> process.cwd() + /src
190
- targetPath = path.join(process.cwd(), 'src', importPath.substring(2));
223
+ const importPaths = new Set();
224
+ const regexes = [
225
+ /import\s+[^'"]*?from\s+['"]([^'"]+)['"]/g,
226
+ /export\s+[^'"]*?from\s+['"]([^'"]+)['"]/g,
227
+ /import\s+['"]([^'"]+)['"]/g,
228
+ /import\s*\(\s*[^'"]*?['"]([^'"]+)['"][^)]*?\)/g,
229
+ /require\s*\(\s*[^'"]*?['"]([^'"]+)['"][^)]*?\)/g
230
+ ];
231
+ for (const rx of regexes) {
232
+ let match;
233
+ rx.lastIndex = 0;
234
+ while ((match = rx.exec(content)) !== null) {
235
+ if (match[1]) {
236
+ importPaths.add(match[1]);
237
+ }
191
238
  }
192
- else if (importPath.startsWith('.')) {
193
- // 解析相对路径
194
- const currentDir = path.dirname(filePath);
195
- targetPath = path.resolve(currentDir, importPath);
239
+ }
240
+ for (const importPath of importPaths) {
241
+ let targetPath = '';
242
+ // 处理路径别名或相对路径
243
+ if (tsconfigPaths) {
244
+ const resolvedAlias = resolveAliasPath(importPath, tsconfigPaths, process.cwd());
245
+ if (resolvedAlias) {
246
+ targetPath = resolvedAlias;
247
+ }
196
248
  }
197
- else {
198
- // 忽略非相对路径 (node_modules)
199
- continue;
249
+ if (!targetPath) {
250
+ if (importPath.startsWith('@/')) {
251
+ targetPath = path.join(process.cwd(), 'src', importPath.substring(2));
252
+ }
253
+ else if (importPath.startsWith('.')) {
254
+ const currentDir = path.dirname(filePath);
255
+ targetPath = path.resolve(currentDir, importPath);
256
+ }
257
+ else {
258
+ // 忽略非相对路径 (node_modules)
259
+ continue;
260
+ }
200
261
  }
201
262
  // 忽略样式/图片文件
202
263
  if (importPath.match(/\.(css|less|scss|sass|png|jpg|jpeg|gif|svg)$/))
@@ -229,7 +290,7 @@ async function processFile(filePath, regex, keys, processedFiles, rootContext, i
229
290
  }
230
291
  }
231
292
  if (resolvedPath) {
232
- await processFile(resolvedPath, regex, keys, processedFiles, rootContext, ignoreDir);
293
+ await processFile(resolvedPath, regex, keys, processedFiles, rootContext, ignoreDir, tsconfigPaths);
233
294
  }
234
295
  }
235
296
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ai-yuca",
3
- "version": "1.5.2",
3
+ "version": "1.5.3",
4
4
  "description": "一个用AI生成的开发辅助工具",
5
5
  "main": "dist/src/index.js",
6
6
  "types": "dist/src/index.d.ts",