babaofan-translate-cli 1.0.0 → 1.0.1

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.
Files changed (3) hide show
  1. package/README.md +0 -43
  2. package/package.json +3 -2
  3. package/utils.js +244 -0
package/README.md CHANGED
@@ -89,49 +89,6 @@ npm install
89
89
  - 已安装当前项目依赖
90
90
  - 能访问 Google AI Studio / Gemini 接口
91
91
 
92
- ## 发布到 npm
93
-
94
- 发布前建议先确认:
95
-
96
- - [package.json](./package.json) 中的 `name`、`version`、`description` 已经正确
97
- - [config.js](./config.js) 里不要保留你自己的真实 API Key
98
- - 本地已经执行过测试命令
99
-
100
- ### 1. 登录 npm
101
-
102
- ```bash
103
- npm login
104
- ```
105
-
106
- ### 2. 检查最终会发布哪些文件
107
-
108
- ```bash
109
- npm pack --dry-run
110
- ```
111
-
112
- ### 3. 发布
113
-
114
- 首次发布:
115
-
116
- ```bash
117
- npm publish
118
- ```
119
-
120
- 如果后续发新版本,先改 `version`,再发布:
121
-
122
- ```bash
123
- npm version patch
124
- npm publish
125
- ```
126
-
127
- 你也可以按需使用:
128
-
129
- ```bash
130
- npm version minor
131
- npm version major
132
- ```
133
-
134
- ## 在别的项目里使用
135
92
 
136
93
  ### 安装
137
94
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "private": false,
3
3
  "name": "babaofan-translate-cli",
4
- "version": "1.0.0",
4
+ "version": "1.0.1",
5
5
  "description": "A local CLI for scanning i18n calls, generating semantic keys, translating with Google AI Studio, and updating locale files.",
6
6
  "type": "module",
7
7
  "bin": {
@@ -13,7 +13,8 @@
13
13
  "files": [
14
14
  "bin",
15
15
  "config.js",
16
- "README.md"
16
+ "README.md",
17
+ "utils.js"
17
18
  ],
18
19
  "keywords": [
19
20
  "i18n",
package/utils.js ADDED
@@ -0,0 +1,244 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * 公共工具函数模块
5
+ * 提供跨脚本使用的通用功能
6
+ */
7
+
8
+ import chalk from "chalk";
9
+ import path from "path";
10
+ import fs from "fs";
11
+ import { execSync } from "child_process";
12
+ import os from "os";
13
+
14
+ // ============================================================================
15
+ // 路径工具
16
+ // ============================================================================
17
+
18
+ /**
19
+ * 获取项目根目录
20
+ * @returns {string} 项目根目录路径
21
+ */
22
+ function getProjectRoot() {
23
+ // return "/Users/jiangshuai/Desktop/coding/cool/uniapp/cool-unix";
24
+ return process.cwd();
25
+ }
26
+
27
+ /**
28
+ * 获取相对于项目根目录的路径
29
+ * @param {string} absolutePath - 绝对路径
30
+ * @param {string} projectRoot - 项目根目录(可选)
31
+ * @returns {string} 相对路径
32
+ */
33
+ function getRelativePath(absolutePath, projectRoot = getProjectRoot()) {
34
+ return absolutePath.replace(projectRoot, "").replace(/^\//, "");
35
+ }
36
+
37
+ // ============================================================================
38
+ // 文件系统工具
39
+ // ============================================================================
40
+
41
+ /**
42
+ * 确保目录存在,不存在则创建
43
+ * @param {string} filePath - 文件路径或目录路径
44
+ */
45
+ function ensureDirectoryExists(filePath) {
46
+ const dirPath = path.dirname(filePath);
47
+ if (!fs.existsSync(dirPath)) {
48
+ fs.mkdirSync(dirPath, { recursive: true });
49
+ }
50
+ }
51
+
52
+ /**
53
+ * 递归复制目录/文件(覆盖模式)
54
+ * @param {string} src - 源路径
55
+ * @param {string} dest - 目标路径
56
+ */
57
+ function copyRecursive(src, dest) {
58
+ const stat = fs.statSync(src);
59
+
60
+ if (fs.existsSync(dest)) {
61
+ fs.rmSync(dest, { recursive: true, force: true });
62
+ }
63
+
64
+ if (stat.isDirectory()) {
65
+ fs.mkdirSync(dest, { recursive: true });
66
+ const items = fs.readdirSync(src);
67
+ for (const item of items) {
68
+ const srcPath = path.join(src, item);
69
+ const destPath = path.join(dest, item);
70
+ copyRecursive(srcPath, destPath);
71
+ }
72
+ } else {
73
+ fs.copyFileSync(src, dest);
74
+ }
75
+ }
76
+
77
+ /**
78
+ * 清理目录
79
+ * @param {string} dirPath - 目录路径
80
+ * @returns {boolean} 是否成功清理
81
+ */
82
+ function cleanDirectory(dirPath) {
83
+ if (fs.existsSync(dirPath)) {
84
+ fs.rmSync(dirPath, { recursive: true, force: true });
85
+ return true;
86
+ }
87
+ return false;
88
+ }
89
+
90
+ // ============================================================================
91
+ // 终端日志工具
92
+ // ============================================================================
93
+
94
+ /**
95
+ * 统一的日志工具类
96
+ */
97
+ const logger = {
98
+ /**
99
+ * 打印标题
100
+ * @param {string} text - 标题文本
101
+ */
102
+ title(text) {
103
+ console.log();
104
+ console.log(chalk.white.bold(text));
105
+ console.log(chalk.gray("─".repeat(50)));
106
+ },
107
+
108
+ /**
109
+ * 打印信息
110
+ * @param {string} label - 标签
111
+ * @param {string} value - 值
112
+ */
113
+ info(label, value) {
114
+ console.log(chalk.gray(" ●"), chalk.white(label), chalk.cyan(value));
115
+ },
116
+
117
+ /**
118
+ * 打印成功消息
119
+ * @param {string} text - 消息文本
120
+ */
121
+ success(text) {
122
+ console.log(chalk.green(" ✓"), chalk.white(text));
123
+ },
124
+
125
+ /**
126
+ * 打印警告消息
127
+ * @param {string} text - 警告文本
128
+ */
129
+ warn(text) {
130
+ console.log(chalk.yellow(" ⚠"), chalk.white(text));
131
+ },
132
+
133
+ /**
134
+ * 打印错误消息
135
+ * @param {string} text - 错误文本
136
+ */
137
+ error(text) {
138
+ console.error(chalk.red(" ✗"), chalk.white(text));
139
+ },
140
+
141
+ /**
142
+ * 打印文件路径
143
+ * @param {string} filePath - 文件路径
144
+ * @param {string} projectRoot - 项目根目录(可选)
145
+ */
146
+ file(filePath, projectRoot = getProjectRoot()) {
147
+ const relativePath = getRelativePath(filePath, projectRoot);
148
+ console.log(chalk.gray(" +"), chalk.green(relativePath));
149
+ },
150
+
151
+ /**
152
+ * 打印分隔线
153
+ */
154
+ divider() {
155
+ console.log(chalk.gray("─".repeat(50)));
156
+ },
157
+
158
+ /**
159
+ * 打印空行
160
+ */
161
+ newline() {
162
+ console.log();
163
+ }
164
+ };
165
+
166
+ // ============================================================================
167
+ // 命令行工具
168
+ // ============================================================================
169
+
170
+ /**
171
+ * 跨平台检测命令是否存在
172
+ * @param {string} command - 要检测的命令
173
+ * @returns {boolean} 命令是否存在
174
+ */
175
+ function commandExists(command) {
176
+ const isWindows = os.platform() === "win32";
177
+
178
+ try {
179
+ if (isWindows) {
180
+ try {
181
+ execSync(`where ${command}`, { stdio: "ignore", shell: "cmd.exe" });
182
+ return true;
183
+ } catch {
184
+ execSync(`${command} --version`, {
185
+ stdio: "ignore",
186
+ shell: "cmd.exe",
187
+ timeout: 3000
188
+ });
189
+ return true;
190
+ }
191
+ } else {
192
+ try {
193
+ execSync(`which ${command}`, { stdio: "ignore" });
194
+ return true;
195
+ } catch {
196
+ execSync(`${command} --version`, {
197
+ stdio: "ignore",
198
+ timeout: 3000
199
+ });
200
+ return true;
201
+ }
202
+ }
203
+ } catch {
204
+ return false;
205
+ }
206
+ }
207
+
208
+ // ============================================================================
209
+ // 字符串工具
210
+ // ============================================================================
211
+
212
+ /**
213
+ * 将连字符命名转换为驼峰命名
214
+ * @param {string} str - 连字符字符串
215
+ * @returns {string} 驼峰命名字符串
216
+ */
217
+ function toCamelCase(str) {
218
+ return str.replace(/-([a-z])/g, (_match, letter) => letter.toUpperCase());
219
+ }
220
+
221
+ /**
222
+ * 将驼峰命名转换为连字符命名
223
+ * @param {string} str - 驼峰字符串
224
+ * @returns {string} 连字符命名字符串
225
+ */
226
+ function toKebabCase(str) {
227
+ return str.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase();
228
+ }
229
+
230
+ // ============================================================================
231
+ // 导出
232
+ // ============================================================================
233
+
234
+ export {
235
+ getProjectRoot,
236
+ getRelativePath,
237
+ ensureDirectoryExists,
238
+ copyRecursive,
239
+ cleanDirectory,
240
+ logger,
241
+ commandExists,
242
+ toCamelCase,
243
+ toKebabCase
244
+ };