td-web-cli 0.1.5 → 0.1.7

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.
@@ -0,0 +1,7 @@
1
+ export declare const getData: <T>(url: string, params?: Record<string, unknown>, headers?: Record<string, string>) => Promise<T>;
2
+ export declare const postData: <T, R>(url: string, params: T, headers?: Record<string, string>) => Promise<R>;
3
+ export declare const postStream: <T>(url: string, params: T, headers: Record<string, string> | undefined, onData: (chunk: string) => void, onError?: (error: Error) => void, onComplete?: () => void, signal?: AbortSignal) => Promise<void>;
4
+ export declare const postSSE: <T>(url: string, params: T, headers: Record<string, string> | undefined, onMessage: (event: string, data: string) => void, onError?: (error: Error) => void, signal?: AbortSignal) => Promise<void>;
5
+ export declare const putData: <T, R>(url: string, params: T, headers?: Record<string, string>) => Promise<R>;
6
+ export declare const deleteData: <T>(url: string, params?: Record<string, unknown>, headers?: Record<string, string>) => Promise<T>;
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/api/index.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,OAAO,GAAU,CAAC,EAC7B,KAAK,MAAM,EACX,SAAQ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EACpC,UAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,KACnC,OAAO,CAAC,CAAC,CAGX,CAAC;AAGF,eAAO,MAAM,QAAQ,GAAU,CAAC,EAAE,CAAC,EACjC,KAAK,MAAM,EACX,QAAQ,CAAC,EACT,UAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,KACnC,OAAO,CAAC,CAAC,CAKX,CAAC;AAGF,eAAO,MAAM,UAAU,GAAU,CAAC,EAChC,KAAK,MAAM,EACX,QAAQ,CAAC,EACT,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,YAAK,EACpC,QAAQ,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,EAC/B,UAAU,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,EAChC,aAAa,MAAM,IAAI,EACvB,SAAS,WAAW,KACnB,OAAO,CAAC,IAAI,CAwDd,CAAC;AAGF,eAAO,MAAM,OAAO,GAAU,CAAC,EAC7B,KAAK,MAAM,EACX,QAAQ,CAAC,EACT,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,YAAK,EACpC,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,EAChD,UAAU,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,EAChC,SAAS,WAAW,KACnB,OAAO,CAAC,IAAI,CAiEd,CAAC;AAGF,eAAO,MAAM,OAAO,GAAU,CAAC,EAAE,CAAC,EAChC,KAAK,MAAM,EACX,QAAQ,CAAC,EACT,UAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,KACnC,OAAO,CAAC,CAAC,CAKX,CAAC;AAGF,eAAO,MAAM,UAAU,GAAU,CAAC,EAChC,KAAK,MAAM,EACX,SAAQ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EACpC,UAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,KACnC,OAAO,CAAC,CAAC,CAGX,CAAC"}
@@ -0,0 +1,6 @@
1
+ declare const api: {
2
+ LANGUAGE_TOOL_V2_LANGUAGES: string;
3
+ LANGUAGE_TOOL_V2_CHECK: string;
4
+ };
5
+ export default api;
6
+ //# sourceMappingURL=interface.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../src/api/interface.ts"],"names":[],"mappings":"AAAA,QAAA,MAAM,GAAG;;;CAGR,CAAC;AAEF,eAAe,GAAG,CAAC"}
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * CLI入口脚本
4
+ * 通过交互式选择执行不同模块功能
5
+ */
6
+ export {};
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;GAGG"}
@@ -0,0 +1,9 @@
1
+ import { Command } from 'commander';
2
+ /**
3
+ * excel转json功能主函数
4
+ * 读取用户输入的excel路径,解析内容,根据配置生成多语言json文件
5
+ * 并对配置文件中所有语言对应的词条进行语言检测
6
+ * @param program Commander命令行实例
7
+ */
8
+ export declare function excel2json(program: Command): Promise<void>;
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/modules/i18n/excel2json/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAyLpC;;;;;GAKG;AACH,wBAAsB,UAAU,CAAC,OAAO,EAAE,OAAO,iBA8ThD"}
@@ -95,6 +95,45 @@ async function batchCheckTexts(texts, language) {
95
95
  }
96
96
  return results;
97
97
  }
98
+ /**
99
+ * 将语言检测结果转换成每条词条对应的错误描述数组
100
+ * @param checkResult 语言检测结果
101
+ * @param texts 词条数组(对应检测文本)
102
+ * @returns 按词条分割的检测错误描述数组,顺序对应输入texts
103
+ */
104
+ function parseCheckResultPerEntry(checkResult, texts) {
105
+ // 初始化每条词条对应的错误信息数组
106
+ const entryErrors = new Array(texts.length).fill('').map(() => '');
107
+ // 语言检测返回的matches是针对整个拼接文本的,需要拆分到对应词条
108
+ // 计算每条词条在拼接文本中的起始位置和结束位置
109
+ const positions = [];
110
+ let pos = 0;
111
+ for (const text of texts) {
112
+ const len = text.length;
113
+ positions.push({ start: pos, end: pos + len });
114
+ pos += len + 1; // +1是换行符长度
115
+ }
116
+ // 遍历所有错误匹配项,将错误信息分配到对应词条
117
+ for (const match of checkResult.matches) {
118
+ const errorOffset = match.offset;
119
+ // 找出错误所在的词条索引
120
+ const idx = positions.findIndex((range) => errorOffset >= range.start && errorOffset < range.end);
121
+ if (idx === -1)
122
+ continue;
123
+ // 生成错误信息字符串
124
+ const errMsg = `错误: ${match.message}\n出错句子: ${match.sentence}\n建议替换: ${match.replacements
125
+ .map((r) => r.value)
126
+ .join(', ')}`;
127
+ // 多条错误用换行分隔
128
+ if (entryErrors[idx]) {
129
+ entryErrors[idx] += '\n' + errMsg;
130
+ }
131
+ else {
132
+ entryErrors[idx] = errMsg;
133
+ }
134
+ }
135
+ return entryErrors;
136
+ }
98
137
  /**
99
138
  * excel转json功能主函数
100
139
  * 读取用户输入的excel路径,解析内容,根据配置生成多语言json文件
@@ -108,9 +147,9 @@ export async function excel2json(program) {
108
147
  let i18nConfig;
109
148
  // 加载配置文件
110
149
  try {
111
- logger.info(`开始加载配置文件:${configPath}`);
150
+ logger.info(`开始加载配置文件:${configPath}`, true);
112
151
  i18nConfig = loadConfig(configPath);
113
- logger.info('配置文件加载成功');
152
+ logger.info('配置文件加载成功', true);
114
153
  }
115
154
  catch (error) {
116
155
  const msg = `读取配置文件失败:${normalizeError(error).stack},程序已退出`;
@@ -120,9 +159,9 @@ export async function excel2json(program) {
120
159
  }
121
160
  // 尝试调用接口获取支持的语言列表,更新 longCodes
122
161
  try {
123
- logger.info('尝试获取在线支持的语言列表...');
162
+ logger.info('尝试获取在线支持的语言列表...', true);
124
163
  const languageTools = await getLanguageTool();
125
- logger.info(`成功获取语言列表,覆盖配置文件中的 longCodes`);
164
+ logger.info(`成功获取语言列表,覆盖配置文件中的 longCodes`, true);
126
165
  // 构建新的 longCodes 映射
127
166
  const newLongCodes = {};
128
167
  // 语言标识对应语言名称列表,方便匹配
@@ -146,6 +185,7 @@ export async function excel2json(program) {
146
185
  }
147
186
  catch (error) {
148
187
  logger.warn(`获取在线语言列表失败,使用本地配置 longCodes,错误:${normalizeError(error).stack}`);
188
+ console.warn('获取在线语言列表失败,使用本地配置 longCodes');
149
189
  }
150
190
  // 交互式输入excel文件路径并校验
151
191
  const answer = await input({
@@ -164,7 +204,7 @@ export async function excel2json(program) {
164
204
  // 规范化路径,支持相对路径转绝对路径,去除首尾引号
165
205
  const excelPath = path.resolve(process.cwd(), answer.trim().replace(/^['"]|['"]$/g, ''));
166
206
  try {
167
- logger.info(`开始读取excel文件:${excelPath}`);
207
+ logger.info(`开始读取excel文件:${excelPath}`, true);
168
208
  // 读取excel文件
169
209
  const workbook = XLSX.readFile(excelPath);
170
210
  const firstSheetName = workbook.SheetNames[0];
@@ -181,7 +221,7 @@ export async function excel2json(program) {
181
221
  console.error('程序执行时发生异常,已记录日志,程序已退出');
182
222
  process.exit(1);
183
223
  }
184
- logger.info('开始解析表头');
224
+ logger.info('开始解析表头', true);
185
225
  // 处理表头行,去除空格,转成字符串
186
226
  const headerRow = rows[0].map((cell) => (cell ? String(cell).trim() : ''));
187
227
  // 根据表头匹配语言列,建立列索引到语言key的映射
@@ -206,7 +246,7 @@ export async function excel2json(program) {
206
246
  Object.values(colIndexToLangKey).forEach((langKey) => {
207
247
  langTranslations[langKey] = {};
208
248
  });
209
- logger.info('开始解析数据行');
249
+ logger.info('开始解析数据行', true);
210
250
  // 遍历数据行,提取所有语言词条
211
251
  // key统一用默认语言列的值,其他语言对应的列为翻译内容
212
252
  const langKeysMap = {}; // 语言key => 词条数组
@@ -237,31 +277,47 @@ export async function excel2json(program) {
237
277
  langTranslations[langKey][key] = valStr;
238
278
  langKeysMap[langKey].push(valStr);
239
279
  }
280
+ else {
281
+ // 确保检测结果数组长度一致,填空字符串
282
+ langKeysMap[langKey].push('');
283
+ }
240
284
  }
241
285
  }
286
+ // 语言检测结果映射,语言key => 每条词条的错误描述数组
287
+ const langCheckErrorsMap = {};
242
288
  // 对所有语言词条批量进行语言检测(包括默认语言)
243
- for (const [langKey, texts] of Object.entries(langKeysMap)) {
289
+ const langKeysEntries = Object.entries(langKeysMap);
290
+ for (let idx = 0; idx < langKeysEntries.length; idx++) {
291
+ const [langKey, texts] = langKeysEntries[idx];
244
292
  const longCode = i18nConfig.longCodes[langKey];
245
293
  if (!longCode) {
246
- logger.warn(`语言(${langKey})未配置 longCode,跳过检测`);
294
+ logger.warn(`语言(${langKey})未配置 longCode,跳过检测`, true);
295
+ langCheckErrorsMap[langKey] =
296
+ texts.length > 0 ? texts.map(() => '') : [];
247
297
  continue;
248
298
  }
249
299
  if (texts.length === 0) {
250
- logger.info(`语言(${langKey})无词条,跳过检测`);
300
+ logger.info(`语言(${langKey})无词条,跳过检测`, true);
301
+ langCheckErrorsMap[langKey] = [];
251
302
  continue;
252
303
  }
253
- logger.info(`开始对语言(${langKey})词条进行语言检测,词条数量:${texts.length}`);
304
+ logger.info(`开始对语言(${langKey})词条进行语言检测,词条数量:${texts.length} (${idx + 1}/${langKeysEntries.length})`, true);
254
305
  const checkResults = await batchCheckTexts(texts, longCode);
255
306
  if (!checkResults || checkResults.length === 0 || !checkResults[0]) {
256
- logger.error(`语言(${langKey})词条检测失败`);
307
+ logger.error(`语言(${langKey})词条检测失败`, true);
308
+ langCheckErrorsMap[langKey] = texts.map(() => '');
257
309
  continue;
258
310
  }
259
311
  const result = checkResults[0];
260
312
  if (result.matches.length === 0) {
261
- logger.info(`语言(${langKey})词条检测无错误`);
313
+ logger.info(`语言(${langKey})词条检测无错误`, true);
314
+ langCheckErrorsMap[langKey] = texts.map(() => '');
262
315
  }
263
316
  else {
264
- logger.info(`语言(${langKey})词条检测发现问题,词条数量: ${result.matches.length}`);
317
+ logger.info(`语言(${langKey})词条检测发现问题,词条数量: ${result.matches.length}`, true);
318
+ // 解析检测结果,拆分到每条词条
319
+ langCheckErrorsMap[langKey] = parseCheckResultPerEntry(result, texts);
320
+ // 详细日志输出
265
321
  for (const match of result.matches) {
266
322
  logger.info(`- 错误: ${match.message}\n 出错句子: ${match.sentence}\n 建议替换: ${match.replacements
267
323
  .map((r) => r.value)
@@ -276,13 +332,13 @@ export async function excel2json(program) {
276
332
  if (!fs.existsSync(outputRoot)) {
277
333
  fs.mkdirSync(outputRoot, { recursive: true });
278
334
  }
279
- logger.info(`开始生成语言文件,输出目录:${outputRoot}`);
335
+ logger.info(`开始生成语言文件,输出目录:${outputRoot}`, true);
280
336
  // 按语言生成对应的json文件,默认语言的key=value不生成文件
281
337
  for (const [langKey, translations] of Object.entries(langTranslations)) {
282
338
  if (Object.keys(translations).length === 0)
283
339
  continue;
284
340
  if (langKey === defaultLang) {
285
- logger.info(`跳过默认语言(${langKey})的json文件生成`);
341
+ logger.info(`跳过默认语言(${langKey})的json文件生成`, true);
286
342
  continue; // 跳过默认语言文件生成
287
343
  }
288
344
  const langDir = path.join(outputRoot, langKey);
@@ -293,9 +349,54 @@ export async function excel2json(program) {
293
349
  fs.writeFileSync(filePath, JSON.stringify(translations, null, 2), {
294
350
  encoding: 'utf-8',
295
351
  });
296
- logger.info(`已生成语言文件:${filePath}`);
352
+ logger.info(`已生成语言文件:${filePath}`, true);
353
+ }
354
+ // 生成语言检测结果excel文件
355
+ logger.info('开始生成语言检测结果excel文件', true);
356
+ // 构造检测结果excel的表头:默认语言列 + 其他语言列(对应原文列名)
357
+ // 这里表头用原excel的表头中对应语言列的值
358
+ const errorSheetHeader = [];
359
+ // 按列索引顺序遍历,匹配语言key,构造表头
360
+ Object.entries(colIndexToLangKey)
361
+ .sort((a, b) => Number(a[0]) - Number(b[0]))
362
+ .forEach(([colIdxStr, langKey]) => {
363
+ const colIdx = Number(colIdxStr);
364
+ // 表头为原excel表头中对应列的文字
365
+ errorSheetHeader.push(headerRow[colIdx]);
366
+ });
367
+ // 构造检测结果excel的内容,每一列对应语言检测错误描述
368
+ // 每行对应原excel中一条数据行
369
+ const dataRowCount = rows.length - 1;
370
+ const errorSheetData = [errorSheetHeader];
371
+ for (let i = 0; i < dataRowCount; i++) {
372
+ const rowErrors = [];
373
+ // 按列索引顺序遍历,填充对应语言的检测错误
374
+ Object.entries(colIndexToLangKey)
375
+ .sort((a, b) => Number(a[0]) - Number(b[0]))
376
+ .forEach(([colIdxStr, langKey]) => {
377
+ var _a;
378
+ const errorsArr = langCheckErrorsMap[langKey];
379
+ if (errorsArr && errorsArr.length > i) {
380
+ // 只展示检测错误,空字符串视为空白
381
+ const err = (_a = errorsArr[i]) === null || _a === void 0 ? void 0 : _a.trim();
382
+ rowErrors.push(err && err.length > 0 ? err : '');
383
+ }
384
+ else {
385
+ rowErrors.push('');
386
+ }
387
+ });
388
+ errorSheetData.push(rowErrors);
297
389
  }
298
- logger.info('全部转换完成', true);
390
+ // 生成excel工作簿和工作表
391
+ const errorWorkbook = XLSX.utils.book_new();
392
+ const errorSheet = XLSX.utils.aoa_to_sheet(errorSheetData);
393
+ XLSX.utils.book_append_sheet(errorWorkbook, errorSheet, 'LanguageCheckResults');
394
+ // 写入检测结果excel文件,固定文件名 lang_check_results.xlsx
395
+ const errorExcelPath = path.join(outputRoot, `lang_check_results.xlsx`);
396
+ XLSX.writeFile(errorWorkbook, errorExcelPath);
397
+ logger.info(`语言检测结果excel文件已生成:${errorExcelPath}`, true);
398
+ // 最终完成提示,包含输出目录
399
+ logger.info(`全部转换完成,语言文件输出目录:${outputRoot}`, true);
299
400
  }
300
401
  catch (error) {
301
402
  // 记录错误日志,方便排查
@@ -0,0 +1,2 @@
1
+ export declare function run(): void;
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/modules/i18n/extractEntry/index.ts"],"names":[],"mappings":"AAAA,wBAAgB,GAAG,SAElB"}
@@ -0,0 +1,8 @@
1
+ import { Command } from 'commander';
2
+ /**
3
+ * 国际化模块主入口
4
+ * 提供多个国际化相关功能的交互式选择
5
+ * @param program Commander命令行实例,用于传递参数和配置
6
+ */
7
+ export declare function i18n(program: Command): Promise<void>;
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/modules/i18n/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC;;;;GAIG;AACH,wBAAsB,IAAI,CAAC,OAAO,EAAE,OAAO,iBAmE1C"}
@@ -0,0 +1,2 @@
1
+ export declare function run(): void;
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/modules/i18n/json2excel/index.ts"],"names":[],"mappings":"AAAA,wBAAgB,GAAG,SAElB"}
@@ -0,0 +1,2 @@
1
+ export declare function run(): void;
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/modules/i18n/jsonMerge/index.ts"],"names":[],"mappings":"AAAA,wBAAgB,GAAG,SAElB"}
@@ -0,0 +1,151 @@
1
+ /**
2
+ * 获取当前时间戳字符串,格式为:YYYYMMDDHHMMSS
3
+ * 例如:20260123135500 表示 2026年01月23日 13点55分00秒
4
+ *
5
+ * @returns {string} 格式化后的时间戳字符串
6
+ */
7
+ export declare function getTimestamp(): string;
8
+ /**
9
+ * 日志级别类型
10
+ */
11
+ type LogLevel = 'INFO' | 'WARN' | 'ERROR';
12
+ /**
13
+ * 日志配置接口
14
+ */
15
+ interface LoggerOptions {
16
+ /**
17
+ * 日志目录,默认根目录下的 logs 文件夹
18
+ */
19
+ logsDir?: string;
20
+ /**
21
+ * 日志文件名格式函数,接收当前日期,返回文件名字符串
22
+ * 默认格式为 YYYYMMDD.txt
23
+ */
24
+ filenameFormatter?: (date: Date) => string;
25
+ /**
26
+ * 当前环境,默认 process.env.NODE_ENV
27
+ */
28
+ env?: string;
29
+ }
30
+ /**
31
+ * 统一日志处理类
32
+ * 支持写入日志文件和控制台打印
33
+ */
34
+ export declare class Logger {
35
+ private logsDir;
36
+ private filenameFormatter;
37
+ private env;
38
+ /**
39
+ * 构造函数,初始化日志配置
40
+ * @param options 配置项,可选
41
+ */
42
+ constructor(options?: LoggerOptions);
43
+ /**
44
+ * 写日志主函数
45
+ * @param level 日志级别
46
+ * @param message 日志内容,支持字符串或对象
47
+ * @param printConsole 是否打印到控制台,默认 false
48
+ */
49
+ log(level: LogLevel, message: unknown, printConsole?: boolean): void;
50
+ /**
51
+ * 记录信息级别日志
52
+ * @param message 日志内容
53
+ * @param printConsole 是否打印到控制台,默认 false
54
+ */
55
+ info(message: unknown, printConsole?: boolean): void;
56
+ /**
57
+ * 记录警告级别日志
58
+ * @param message 日志内容
59
+ * @param printConsole 是否打印到控制台,默认 false
60
+ */
61
+ warn(message: unknown, printConsole?: boolean): void;
62
+ /**
63
+ * 记录错误级别日志
64
+ * @param message 日志内容
65
+ * @param printConsole 是否打印到控制台,默认 false
66
+ */
67
+ error(message: unknown, printConsole?: boolean): void;
68
+ }
69
+ /**
70
+ * 默认导出单例 logger,方便直接使用
71
+ * 默认不打印控制台日志
72
+ */
73
+ export declare const logger: Logger;
74
+ /**
75
+ * 通用错误日志记录函数
76
+ * @param error 捕获的错误对象
77
+ * @param logger 日志对象,需包含 error 方法
78
+ * @param prefix 日志前缀,方便区分来源,默认值为 '程序执行时发生错误'
79
+ * @param printConsole 是否打印错误日志到控制台,默认 false
80
+ */
81
+ export declare function loggerError(error: unknown, logger: {
82
+ error: (msg: string, printConsole?: boolean) => void;
83
+ }, prefix?: string, printConsole?: boolean): void;
84
+ /**
85
+ * 将任意错误对象规范化为 Error 类型。
86
+ * @param err - 可能是 Error、字符串或其他任意类型
87
+ * @returns 标准的 Error 对象
88
+ */
89
+ export declare const normalizeError: (err: unknown) => Error;
90
+ /**
91
+ * 语言工具接口返回的语言列表类型
92
+ * 数组中每个元素包含语言名称、简写代码和长代码
93
+ */
94
+ export type LanguageTool = {
95
+ name: string;
96
+ code: string;
97
+ longCode: string;
98
+ }[];
99
+ /**
100
+ * 获取支持的语言列表
101
+ * 调用语言工具接口,返回所有支持的语言信息数组
102
+ * @returns Promise<LanguageTool> 返回语言列表的 Promise
103
+ * @throws 接口请求失败时抛出错误,错误信息包含接口地址和异常堆栈
104
+ */
105
+ export declare function getLanguageTool(): Promise<LanguageTool>;
106
+ /**
107
+ * 替换建议类型
108
+ */
109
+ export interface Replacement {
110
+ value: string;
111
+ }
112
+ /**
113
+ * 语言检测结果中的单条匹配错误信息
114
+ */
115
+ export interface Match {
116
+ message: string;
117
+ shortMessage: string;
118
+ offset: number;
119
+ length: number;
120
+ replacements: Replacement[];
121
+ sentence: string;
122
+ rule: {
123
+ id: string;
124
+ description: string;
125
+ };
126
+ }
127
+ /**
128
+ * 语言检测接口返回的完整结果类型
129
+ */
130
+ export interface CheckResult {
131
+ matches: Match[];
132
+ language: {
133
+ name: string;
134
+ code: string;
135
+ };
136
+ software: {
137
+ name: string;
138
+ version: string;
139
+ premium: boolean;
140
+ };
141
+ }
142
+ /**
143
+ * 调用语言检测接口,检测文本中的语言错误
144
+ * @param text 待检测文本
145
+ * @param language 语言代码,默认 'en-US'
146
+ * @returns Promise<CheckResult> 返回检测结果的 Promise
147
+ * @throws 接口请求失败时抛出错误,错误信息包含接口地址和异常堆栈
148
+ */
149
+ export declare function languageToolCheck(text: string, language?: string): Promise<CheckResult>;
150
+ export {};
151
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAMA;;;;;GAKG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAmBrC;AAED;;GAEG;AACH,KAAK,QAAQ,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAE1C;;GAEG;AACH,UAAU,aAAa;IACrB;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,MAAM,CAAC;IAE3C;;OAEG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AA8ED;;;GAGG;AACH,qBAAa,MAAM;IACjB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,iBAAiB,CAAyB;IAClD,OAAO,CAAC,GAAG,CAAS;IAEpB;;;OAGG;gBACS,OAAO,CAAC,EAAE,aAAa;IAUnC;;;;;OAKG;IACH,GAAG,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY,UAAQ,GAAG,IAAI;IAsClE;;;;OAIG;IACH,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,YAAY,UAAQ,GAAG,IAAI;IAIlD;;;;OAIG;IACH,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,YAAY,UAAQ,GAAG,IAAI;IAIlD;;;;OAIG;IACH,KAAK,CAAC,OAAO,EAAE,OAAO,EAAE,YAAY,UAAQ,GAAG,IAAI;CAGpD;AAED;;;GAGG;AACH,eAAO,MAAM,MAAM,QAEjB,CAAC;AAEH;;;;;;GAMG;AACH,wBAAgB,WAAW,CACzB,KAAK,EAAE,OAAO,EACd,MAAM,EAAE;IAAE,KAAK,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,OAAO,KAAK,IAAI,CAAA;CAAE,EAChE,MAAM,SAAc,EACpB,YAAY,UAAQ,GACnB,IAAI,CAEN;AAED;;;;GAIG;AACH,eAAO,MAAM,cAAc,GAAI,KAAK,OAAO,KAAG,KAW7C,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB,EAAE,CAAC;AAEJ;;;;;GAKG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,YAAY,CAAC,CAS7D;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,KAAK;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,WAAW,EAAE,CAAC;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE;QAEJ,EAAE,EAAE,MAAM,CAAC;QACX,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,KAAK,EAAE,CAAC;IACjB,QAAQ,EAAE;QAER,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;IACF,QAAQ,EAAE;QAER,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,EAAE,OAAO,CAAC;KAClB,CAAC;CACH;AAED;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,MAAM,EACZ,QAAQ,SAAU,GACjB,OAAO,CAAC,WAAW,CAAC,CAetB"}
@@ -27,32 +27,32 @@ export function getTimestamp() {
27
27
  return `${year}${month}${day}${hour}${minute}${second}`;
28
28
  }
29
29
  /**
30
- * 获取程序入口文件路径(兼容 ES Module)
31
- * @returns 程序入口文件的绝对路径
30
+ * 获取项目根目录路径,兼容 ESM
31
+ * @returns 根目录绝对路径
32
32
  */
33
- function getEntryFilePath() {
34
- try {
35
- // 当前模块文件路径
36
- return fileURLToPath(import.meta.url);
37
- }
38
- catch {
39
- // 兜底:使用 process.argv[1]
40
- if (process.argv.length > 1) {
41
- return path.resolve(process.cwd(), process.argv[1]);
42
- }
43
- // 最终兜底
44
- return '';
45
- }
33
+ function getRootDir() {
34
+ // 当前模块文件路径
35
+ const __filename = fileURLToPath(import.meta.url);
36
+ // 当前模块目录
37
+ const __dirname = path.dirname(__filename);
38
+ // 根目录为当前模块目录的上两级,视项目结构调整
39
+ return path.resolve(__dirname, '../../');
46
40
  }
47
41
  /**
48
42
  * 默认日志配置
49
- * logsDir 默认设置为程序入口文件所在目录的上级目录的 logs 文件夹
43
+ * logsDir 默认设置为项目根目录的 logs 文件夹
50
44
  */
51
45
  const defaultOptions = {
52
- logsDir: '',
53
- filenameFormatter: (date) => date.toISOString().slice(0, 10).replace(/-/g, '') + '.txt',
46
+ logsDir: path.resolve(getRootDir(), 'logs'),
47
+ filenameFormatter: (date) => {
48
+ // 使用本地时间格式化,格式 YYYYMMDD.txt
49
+ const pad = (n) => n.toString().padStart(2, '0');
50
+ const year = date.getFullYear();
51
+ const month = pad(date.getMonth() + 1);
52
+ const day = pad(date.getDate());
53
+ return `${year}${month}${day}.txt`;
54
+ },
54
55
  env: process.env.NODE_ENV || 'production',
55
- entryFilePath: getEntryFilePath(),
56
56
  };
57
57
  /**
58
58
  * 格式化日志内容,支持字符串或对象
@@ -62,7 +62,24 @@ const defaultOptions = {
62
62
  * @returns 格式化后的日志字符串
63
63
  */
64
64
  function formatLogLine(level, message, date) {
65
- const timeStr = date.toISOString();
65
+ // 使用本地时间格式化为 ISO-like 字符串(带时区偏移)
66
+ // 格式示例:2026-01-23T13:55:00+08:00
67
+ function formatLocalISO(date) {
68
+ const pad = (n) => n.toString().padStart(2, '0');
69
+ const year = date.getFullYear();
70
+ const month = pad(date.getMonth() + 1);
71
+ const day = pad(date.getDate());
72
+ const hour = pad(date.getHours());
73
+ const minute = pad(date.getMinutes());
74
+ const second = pad(date.getSeconds());
75
+ // 计算时区偏移,单位分钟
76
+ const tzOffset = -date.getTimezoneOffset();
77
+ const sign = tzOffset >= 0 ? '+' : '-';
78
+ const tzHour = pad(Math.floor(Math.abs(tzOffset) / 60));
79
+ const tzMinute = pad(Math.abs(tzOffset) % 60);
80
+ return `${year}-${month}-${day}T${hour}:${minute}:${second}${sign}${tzHour}:${tzMinute}`;
81
+ }
82
+ const timeStr = formatLocalISO(date);
66
83
  let msgStr;
67
84
  if (typeof message === 'string') {
68
85
  msgStr = message;
@@ -89,10 +106,8 @@ export class Logger {
89
106
  constructor(options) {
90
107
  var _a, _b;
91
108
  const opts = { ...defaultOptions, ...options };
92
- // 如果未传 logsDir,则默认设置为入口文件所在目录的上级目录的 logs 文件夹
93
- this.logsDir =
94
- opts.logsDir ||
95
- path.resolve(path.dirname(opts.entryFilePath), '..', 'logs');
109
+ // 如果未传 logsDir,则默认设置为根目录的 logs 文件夹
110
+ this.logsDir = opts.logsDir;
96
111
  this.filenameFormatter =
97
112
  (_a = opts.filenameFormatter) !== null && _a !== void 0 ? _a : defaultOptions.filenameFormatter;
98
113
  this.env = (_b = opts.env) !== null && _b !== void 0 ? _b : defaultOptions.env;
package/package.json CHANGED
@@ -1,12 +1,15 @@
1
1
  {
2
2
  "name": "td-web-cli",
3
- "version": "0.1.5",
3
+ "version": "0.1.7",
4
4
  "description": "A CLI tool for efficiency",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",
7
7
  "bin": {
8
8
  "td-web-cli": "dist/index.js"
9
9
  },
10
+ "files": [
11
+ "dist"
12
+ ],
10
13
  "scripts": {
11
14
  "build": "tsc",
12
15
  "format": "prettier --write \"src/**/*.{js,ts,tsx,json,md}\""
package/.prettierignore DELETED
@@ -1,2 +0,0 @@
1
- node_modules
2
- dist
package/.prettierrc DELETED
@@ -1,7 +0,0 @@
1
- {
2
- "semi": true,
3
- "singleQuote": true,
4
- "printWidth": 80,
5
- "tabWidth": 2,
6
- "trailingComma": "es5"
7
- }
package/setting.json DELETED
@@ -1,47 +0,0 @@
1
- {
2
- "i18n": {
3
- "defaultKey": "en",
4
- "langs": {
5
- "cn": ["简体中文"],
6
- "zh": ["繁体中文"],
7
- "en": ["英语"],
8
- "it": ["意大利语"],
9
- "brpt": ["巴西葡语"],
10
- "uk": ["乌克兰语"],
11
- "ru": ["俄语"],
12
- "es": ["欧洲西语"],
13
- "hu": ["匈牙利语"],
14
- "pl": ["波兰语"],
15
- "tr": ["土耳其语"],
16
- "de": ["德语"],
17
- "fr": ["法语"],
18
- "ro": ["罗马尼亚语"],
19
- "ko": ["韩语"],
20
- "cs": ["捷克语"],
21
- "laes": ["拉美西语"],
22
- "pt": ["欧洲葡语"],
23
- "nl": ["荷兰语"]
24
- },
25
- "longCodes": {
26
- "cn": "zh-CN",
27
- "zh": "zh-TW",
28
- "en": "en-US",
29
- "it": "it-IT",
30
- "brpt": "pt-BR",
31
- "uk": "uk-UA",
32
- "ru": "ru-RU",
33
- "es": "es-ES",
34
- "hu": "hu-HU",
35
- "pl": "pl-PL",
36
- "tr": "tr-TR",
37
- "de": "de-DE",
38
- "fr": "fr-FR",
39
- "ro": "ro-RO",
40
- "ko": "ko-KR",
41
- "cs": "cs-CZ",
42
- "laes": "es-MX",
43
- "pt": "pt-PT",
44
- "nl": "nl-NL"
45
- }
46
- }
47
- }