ai-yuca 1.0.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.
Files changed (62) hide show
  1. package/.eslintrc.js +25 -0
  2. package/CONFIG_UPLOAD.md +154 -0
  3. package/CONTRIBUTING.md +58 -0
  4. package/INSTALLATION.md +192 -0
  5. package/README.md +80 -0
  6. package/bin/cli.js +85 -0
  7. package/bin/cli.ts +302 -0
  8. package/dist/bin/cli.d.ts +2 -0
  9. package/dist/bin/cli.js +297 -0
  10. package/dist/package.json +51 -0
  11. package/dist/src/config.d.ts +56 -0
  12. package/dist/src/config.js +101 -0
  13. package/dist/src/download.d.ts +30 -0
  14. package/dist/src/download.js +214 -0
  15. package/dist/src/index.d.ts +18 -0
  16. package/dist/src/index.js +126 -0
  17. package/dist/src/types/analyze.d.ts +33 -0
  18. package/dist/src/types/analyze.js +5 -0
  19. package/dist/src/types/download.d.ts +60 -0
  20. package/dist/src/types/download.js +2 -0
  21. package/dist/src/types/index.d.ts +8 -0
  22. package/dist/src/types/index.js +28 -0
  23. package/dist/src/types/upload.d.ts +89 -0
  24. package/dist/src/types/upload.js +2 -0
  25. package/dist/src/upload.d.ts +24 -0
  26. package/dist/src/upload.js +252 -0
  27. package/dist/src/uploadWithConfig.d.ts +34 -0
  28. package/dist/src/uploadWithConfig.js +82 -0
  29. package/dist/src/utils/compression.d.ts +16 -0
  30. package/dist/src/utils/compression.js +85 -0
  31. package/dist/test/compression.test.d.ts +1 -0
  32. package/dist/test/compression.test.js +109 -0
  33. package/dist/test/download.test.d.ts +1 -0
  34. package/dist/test/download.test.js +168 -0
  35. package/dist/test/index.test.d.ts +1 -0
  36. package/dist/test/index.test.js +33 -0
  37. package/dist/test/upload.test.d.ts +1 -0
  38. package/dist/test/upload.test.js +140 -0
  39. package/docs/usage.md +223 -0
  40. package/examples/sample.txt +7 -0
  41. package/examples/upload-example.js +53 -0
  42. package/out/test.txt +1 -0
  43. package/package.json +51 -0
  44. package/src/config.ts +104 -0
  45. package/src/download.ts +216 -0
  46. package/src/index.js +88 -0
  47. package/src/index.ts +98 -0
  48. package/src/types/analyze.ts +37 -0
  49. package/src/types/download.ts +67 -0
  50. package/src/types/index.ts +16 -0
  51. package/src/types/upload.ts +97 -0
  52. package/src/upload.js +197 -0
  53. package/src/upload.ts +254 -0
  54. package/src/uploadWithConfig.ts +122 -0
  55. package/src/utils/compression.ts +61 -0
  56. package/test/compression.test.ts +88 -0
  57. package/test/download.test.ts +162 -0
  58. package/test/index.test.js +38 -0
  59. package/test/index.test.ts +39 -0
  60. package/test/upload.test.ts +131 -0
  61. package/tsconfig.json +17 -0
  62. package/vs.config.json +42 -0
package/bin/cli.ts ADDED
@@ -0,0 +1,302 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { Command } from 'commander';
4
+ import * as pkg from '../package.json';
5
+ import * as fs from 'fs';
6
+ import * as path from 'path';
7
+ import { analyze } from '../src/index';
8
+ import { createStorageClient, uploadFiles } from '../src/upload';
9
+ import { downloadFiles } from '../src/download';
10
+ import { uploadFilesWithConfig, getConfigSummary } from '../src/uploadWithConfig';
11
+ import { AnalyzeOptions, UploadFilesResult, UploadCommandOptions, DownloadCommandOptions, UploadWithConfigOptions } from '../src/types';
12
+
13
+ const program = new Command();
14
+
15
+ // 设置版本和描述
16
+ program
17
+ .version(pkg.version, '-v, --version')
18
+ .description(pkg.description);
19
+
20
+ // 添加analyze命令
21
+ program
22
+ .command('analyze')
23
+ .description('分析文本内容')
24
+ .option('-f, --file <path>', '指定要分析的文件路径')
25
+ .option('-t, --text <text>', '直接分析提供的文本')
26
+ .action((options: AnalyzeOptions) => {
27
+ analyze(options);
28
+ });
29
+
30
+ // 使用从types导入的UploadCommandOptions接口
31
+
32
+ // 添加upload命令
33
+ program
34
+ .command('upload')
35
+ .description('上传文件到GCP存储桶')
36
+ .option('-s, --source <paths...>', '指定要上传的文件或目录路径(支持多个)')
37
+ .option('-b, --bucket <name>', 'GCP存储桶名称')
38
+ .option('-d, --destination <path>', '目标路径(存储桶中的路径)')
39
+ .option('-k, --key-file <path>', 'GCP服务账号密钥文件路径(可选,不提供则使用应用默认凭证)')
40
+ .option('-r, --recursive', '递归上传目录中的文件', false)
41
+ .option('-c, --no-compression', '禁用GZIP压缩(默认对js、css、json、html、woff文件启用压缩)')
42
+ .action(async (options: UploadCommandOptions) => {
43
+ try {
44
+ const { source, bucket, destination, keyFile, recursive, compression = true } = options;
45
+
46
+ if (!source || !bucket) {
47
+ console.error('错误: 必须提供源文件路径和存储桶名称');
48
+ process.exit(1);
49
+ }
50
+
51
+ // 创建存储客户端
52
+ const storageClient = keyFile
53
+ ? createStorageClient({ keyFilename: keyFile })
54
+ : createStorageClient(); // 使用应用默认凭证
55
+
56
+ console.log('开始上传文件...');
57
+
58
+ // 执行上传
59
+ const results = await uploadFiles({
60
+ bucketName: bucket,
61
+ sourcePath: source,
62
+ destination,
63
+ storageClient,
64
+ recursive,
65
+ enableCompression: compression
66
+ });
67
+
68
+ // 输出结果
69
+ console.log('\n上传完成!');
70
+ console.log(`成功: ${results.success.length} 个文件`);
71
+ console.log(`失败: ${results.failed.length} 个文件`);
72
+
73
+ if (results.success.length > 0) {
74
+ console.log('\n成功上传的文件:');
75
+ results.success.forEach(file => {
76
+ console.log(`- ${file.file} (${file.url})`);
77
+ });
78
+ }
79
+
80
+ if (results.failed.length > 0) {
81
+ console.log('\n上传失败的文件:');
82
+ results.failed.forEach(file => {
83
+ console.log(`- ${file.file}: ${file.error}`);
84
+ });
85
+ }
86
+ } catch (err) {
87
+ console.error(`上传错误: ${err instanceof Error ? err.message : String(err)}`);
88
+ process.exit(1);
89
+ }
90
+ });
91
+
92
+ // 添加download命令
93
+ program
94
+ .command('download')
95
+ .description('从GCP存储桶下载文件或文件夹')
96
+ .option('-s, --source <path>', '指定要下载的GCP存储桶中的文件或目录路径')
97
+ .option('-b, --bucket <name>', 'GCP存储桶名称')
98
+ .option('-d, --destination <path>', '本地目标路径(下载到本地的路径)')
99
+ .option('-k, --key-file <path>', 'GCP服务账号密钥文件路径(可选,不提供则使用应用默认凭证)')
100
+ .option('-r, --recursive', '递归下载目录中的文件', false)
101
+ .action(async (options: DownloadCommandOptions) => {
102
+ try {
103
+ const { source, bucket, destination, keyFile, recursive } = options;
104
+
105
+ if (!source || !bucket || !destination) {
106
+ console.error('错误: 必须提供源路径、存储桶名称和目标路径');
107
+ process.exit(1);
108
+ }
109
+
110
+ // 创建存储客户端
111
+ const storageClient = keyFile
112
+ ? createStorageClient({ keyFilename: keyFile })
113
+ : createStorageClient(); // 使用应用默认凭证
114
+
115
+ console.log('开始下载文件...');
116
+
117
+ // 执行下载
118
+ const results = await downloadFiles({
119
+ bucketName: bucket,
120
+ sourcePath: source,
121
+ destinationPath: destination,
122
+ storageClient,
123
+ recursive
124
+ });
125
+
126
+ // 输出结果
127
+ console.log('\n下载完成!');
128
+ console.log(`成功: ${results.success.length} 个文件`);
129
+ console.log(`失败: ${results.failed.length} 个文件`);
130
+
131
+ if (results.success.length > 0) {
132
+ console.log('\n成功下载的文件:');
133
+ results.success.forEach(file => {
134
+ console.log(`- ${file.file} -> ${file.localPath}`);
135
+ });
136
+ }
137
+
138
+ if (results.failed.length > 0) {
139
+ console.log('\n下载失败的文件:');
140
+ results.failed.forEach(file => {
141
+ console.log(`- ${file.file}: ${file.error}`);
142
+ });
143
+ }
144
+ } catch (err) {
145
+ console.error(`下载错误: ${err instanceof Error ? err.message : String(err)}`);
146
+ process.exit(1);
147
+ }
148
+ });
149
+
150
+ // 添加基于配置文件的上传命令
151
+ program
152
+ .command('upload-config')
153
+ .description('基于vs.config.json配置文件上传文件到GCP存储桶')
154
+ .option('-c, --config <path>', '指定配置文件路径(默认为项目根目录下的vs.config.json)')
155
+ .option('-k, --key-file <path>', 'GCP服务账号密钥文件路径(可选,不提供则使用应用默认凭证)')
156
+ .option('-s, --source <path>', '自定义源路径(覆盖配置文件中的uploadPath)')
157
+ .option('-d, --destination <path>', '自定义目标路径(覆盖配置文件中的目标路径)')
158
+ .option('--no-recursive', '禁用递归上传目录中的文件')
159
+ .option('--no-compression', '禁用GZIP压缩')
160
+ .option('--show-config', '仅显示配置信息,不执行上传')
161
+ .action(async (options: any) => {
162
+ try {
163
+ const {
164
+ config: configPath,
165
+ keyFile,
166
+ source: customSourcePath,
167
+ destination: customDestination,
168
+ recursive = true,
169
+ compression = true,
170
+ showConfig = false
171
+ } = options;
172
+
173
+ // 如果只是显示配置信息
174
+ if (showConfig) {
175
+ try {
176
+ const configSummary = getConfigSummary(configPath);
177
+ console.log('配置信息:');
178
+ console.log(` 桶名称: ${configSummary.bucketName}`);
179
+ console.log(` 源路径: ${configSummary.sourcePath}`);
180
+ console.log(` 目标路径: ${configSummary.destination}`);
181
+ return;
182
+ } catch (err) {
183
+ console.error(`读取配置失败: ${err instanceof Error ? err.message : String(err)}`);
184
+ process.exit(1);
185
+ }
186
+ }
187
+
188
+ // 执行上传
189
+ const uploadOptions: UploadWithConfigOptions = {
190
+ configPath,
191
+ storageClientOptions: keyFile ? { keyFilename: keyFile } : {},
192
+ customSourcePath,
193
+ customDestination,
194
+ recursive,
195
+ enableCompression: compression
196
+ };
197
+
198
+ const result = await uploadFilesWithConfig(uploadOptions);
199
+
200
+ if (result.success.length > 0) {
201
+ console.log('\n上传成功的文件:');
202
+ result.success.forEach((file) => {
203
+ console.log(` ✓ ${file.file} -> ${file.url}`);
204
+ });
205
+ }
206
+
207
+ if (result.failed.length > 0) {
208
+ console.log('\n上传失败的文件:');
209
+ result.failed.forEach((file) => {
210
+ console.log(` ✗ ${file.file}: ${file.error}`);
211
+ });
212
+ }
213
+
214
+ } catch (err) {
215
+ console.error(`上传错误: ${err instanceof Error ? err.message : String(err)}`);
216
+ process.exit(1);
217
+ }
218
+ });
219
+
220
+ // 添加init命令
221
+ program
222
+ .command('init')
223
+ .description('在当前目录生成vs.config.json配置文件')
224
+ .option('-f, --force', '强制覆盖已存在的配置文件')
225
+ .action(async (options: any) => {
226
+ try {
227
+ const { force = false } = options;
228
+ const configPath = path.join(process.cwd(), 'vs.config.json');
229
+
230
+ // 检查文件是否已存在
231
+ if (fs.existsSync(configPath) && !force) {
232
+ console.error('错误: vs.config.json 文件已存在。使用 --force 选项强制覆盖。');
233
+ process.exit(1);
234
+ }
235
+
236
+ // 默认配置数据
237
+ const defaultConfig = {
238
+ "upload": {
239
+ "uploadPath": "out",
240
+ "s3Static": "static/aiAgent"
241
+ },
242
+ "deploy": {
243
+ "baseUrlExample": "baseUrl: ['/', 'en-us/', 'zh-hk/', 'test/']",
244
+ "baseUrl": [
245
+ "/",
246
+ "en-us/",
247
+ "zh-cn/",
248
+ "de-de/",
249
+ "it-it/",
250
+ "pt-pt/",
251
+ "es-es/",
252
+ "fr-fr/",
253
+ "ru-ru/",
254
+ "error/",
255
+ "download-v2/"
256
+ ],
257
+ "host": "https://www.china2u.xyz",
258
+ "testHost": "https://ai.decom.valleysound.xyz"
259
+ },
260
+ "aws": {
261
+ "Bucket": "decom-cdn",
262
+ "prefix": "fed",
263
+ "Region": "us-east-1",
264
+ "HostName": "https://cdn.cn2u.xyz"
265
+ },
266
+ "crowdin": {
267
+ "project": "fed-buy-buy-buy-home",
268
+ "langMap": ["zh-cn","en-us", "de-de", "pt-pt", "fr-fr", "es-es", "it-it", "ru-ru"],
269
+ "workDir": "src",
270
+ "reg": "{#(.+?)#}",
271
+ "keysDir": "src/_i18n",
272
+ "Bucket": "mall-rocket-cdn",
273
+ "prefix": "fed",
274
+ "Region": "us-east-1",
275
+ "FromIni": "mall",
276
+ "HostName": "https://cdn.alvinclub.ca"
277
+ }
278
+ };
279
+
280
+ // 写入配置文件
281
+ fs.writeFileSync(configPath, JSON.stringify(defaultConfig, null, 2), 'utf-8');
282
+
283
+ console.log(`✓ 成功生成配置文件: ${configPath}`);
284
+ console.log('\n配置文件内容:');
285
+ console.log(` 桶名称: ${defaultConfig.aws.Bucket}`);
286
+ console.log(` 源路径: ${defaultConfig.upload.uploadPath}`);
287
+ console.log(` 目标路径: ${defaultConfig.aws.prefix}/${defaultConfig.upload.s3Static}`);
288
+ console.log('\n您可以根据需要修改配置文件中的值。');
289
+
290
+ } catch (err) {
291
+ console.error(`生成配置文件失败: ${err instanceof Error ? err.message : String(err)}`);
292
+ process.exit(1);
293
+ }
294
+ });
295
+
296
+ // 解析命令行参数
297
+ program.parse(process.argv);
298
+
299
+ // 如果没有提供任何命令,显示帮助信息
300
+ if (!process.argv.slice(2).length) {
301
+ program.outputHelp();
302
+ }
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
@@ -0,0 +1,297 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
+ if (k2 === undefined) k2 = k;
5
+ var desc = Object.getOwnPropertyDescriptor(m, k);
6
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
+ desc = { enumerable: true, get: function() { return m[k]; } };
8
+ }
9
+ Object.defineProperty(o, k2, desc);
10
+ }) : (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ o[k2] = m[k];
13
+ }));
14
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
15
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
16
+ }) : function(o, v) {
17
+ o["default"] = v;
18
+ });
19
+ var __importStar = (this && this.__importStar) || (function () {
20
+ var ownKeys = function(o) {
21
+ ownKeys = Object.getOwnPropertyNames || function (o) {
22
+ var ar = [];
23
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
24
+ return ar;
25
+ };
26
+ return ownKeys(o);
27
+ };
28
+ return function (mod) {
29
+ if (mod && mod.__esModule) return mod;
30
+ var result = {};
31
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
32
+ __setModuleDefault(result, mod);
33
+ return result;
34
+ };
35
+ })();
36
+ Object.defineProperty(exports, "__esModule", { value: true });
37
+ const commander_1 = require("commander");
38
+ const pkg = __importStar(require("../package.json"));
39
+ const fs = __importStar(require("fs"));
40
+ const path = __importStar(require("path"));
41
+ const index_1 = require("../src/index");
42
+ const upload_1 = require("../src/upload");
43
+ const download_1 = require("../src/download");
44
+ const uploadWithConfig_1 = require("../src/uploadWithConfig");
45
+ const program = new commander_1.Command();
46
+ // 设置版本和描述
47
+ program
48
+ .version(pkg.version, '-v, --version')
49
+ .description(pkg.description);
50
+ // 添加analyze命令
51
+ program
52
+ .command('analyze')
53
+ .description('分析文本内容')
54
+ .option('-f, --file <path>', '指定要分析的文件路径')
55
+ .option('-t, --text <text>', '直接分析提供的文本')
56
+ .action((options) => {
57
+ (0, index_1.analyze)(options);
58
+ });
59
+ // 使用从types导入的UploadCommandOptions接口
60
+ // 添加upload命令
61
+ program
62
+ .command('upload')
63
+ .description('上传文件到GCP存储桶')
64
+ .option('-s, --source <paths...>', '指定要上传的文件或目录路径(支持多个)')
65
+ .option('-b, --bucket <name>', 'GCP存储桶名称')
66
+ .option('-d, --destination <path>', '目标路径(存储桶中的路径)')
67
+ .option('-k, --key-file <path>', 'GCP服务账号密钥文件路径(可选,不提供则使用应用默认凭证)')
68
+ .option('-r, --recursive', '递归上传目录中的文件', false)
69
+ .option('-c, --no-compression', '禁用GZIP压缩(默认对js、css、json、html、woff文件启用压缩)')
70
+ .action(async (options) => {
71
+ try {
72
+ const { source, bucket, destination, keyFile, recursive, compression = true } = options;
73
+ if (!source || !bucket) {
74
+ console.error('错误: 必须提供源文件路径和存储桶名称');
75
+ process.exit(1);
76
+ }
77
+ // 创建存储客户端
78
+ const storageClient = keyFile
79
+ ? (0, upload_1.createStorageClient)({ keyFilename: keyFile })
80
+ : (0, upload_1.createStorageClient)(); // 使用应用默认凭证
81
+ console.log('开始上传文件...');
82
+ // 执行上传
83
+ const results = await (0, upload_1.uploadFiles)({
84
+ bucketName: bucket,
85
+ sourcePath: source,
86
+ destination,
87
+ storageClient,
88
+ recursive,
89
+ enableCompression: compression
90
+ });
91
+ // 输出结果
92
+ console.log('\n上传完成!');
93
+ console.log(`成功: ${results.success.length} 个文件`);
94
+ console.log(`失败: ${results.failed.length} 个文件`);
95
+ if (results.success.length > 0) {
96
+ console.log('\n成功上传的文件:');
97
+ results.success.forEach(file => {
98
+ console.log(`- ${file.file} (${file.url})`);
99
+ });
100
+ }
101
+ if (results.failed.length > 0) {
102
+ console.log('\n上传失败的文件:');
103
+ results.failed.forEach(file => {
104
+ console.log(`- ${file.file}: ${file.error}`);
105
+ });
106
+ }
107
+ }
108
+ catch (err) {
109
+ console.error(`上传错误: ${err instanceof Error ? err.message : String(err)}`);
110
+ process.exit(1);
111
+ }
112
+ });
113
+ // 添加download命令
114
+ program
115
+ .command('download')
116
+ .description('从GCP存储桶下载文件或文件夹')
117
+ .option('-s, --source <path>', '指定要下载的GCP存储桶中的文件或目录路径')
118
+ .option('-b, --bucket <name>', 'GCP存储桶名称')
119
+ .option('-d, --destination <path>', '本地目标路径(下载到本地的路径)')
120
+ .option('-k, --key-file <path>', 'GCP服务账号密钥文件路径(可选,不提供则使用应用默认凭证)')
121
+ .option('-r, --recursive', '递归下载目录中的文件', false)
122
+ .action(async (options) => {
123
+ try {
124
+ const { source, bucket, destination, keyFile, recursive } = options;
125
+ if (!source || !bucket || !destination) {
126
+ console.error('错误: 必须提供源路径、存储桶名称和目标路径');
127
+ process.exit(1);
128
+ }
129
+ // 创建存储客户端
130
+ const storageClient = keyFile
131
+ ? (0, upload_1.createStorageClient)({ keyFilename: keyFile })
132
+ : (0, upload_1.createStorageClient)(); // 使用应用默认凭证
133
+ console.log('开始下载文件...');
134
+ // 执行下载
135
+ const results = await (0, download_1.downloadFiles)({
136
+ bucketName: bucket,
137
+ sourcePath: source,
138
+ destinationPath: destination,
139
+ storageClient,
140
+ recursive
141
+ });
142
+ // 输出结果
143
+ console.log('\n下载完成!');
144
+ console.log(`成功: ${results.success.length} 个文件`);
145
+ console.log(`失败: ${results.failed.length} 个文件`);
146
+ if (results.success.length > 0) {
147
+ console.log('\n成功下载的文件:');
148
+ results.success.forEach(file => {
149
+ console.log(`- ${file.file} -> ${file.localPath}`);
150
+ });
151
+ }
152
+ if (results.failed.length > 0) {
153
+ console.log('\n下载失败的文件:');
154
+ results.failed.forEach(file => {
155
+ console.log(`- ${file.file}: ${file.error}`);
156
+ });
157
+ }
158
+ }
159
+ catch (err) {
160
+ console.error(`下载错误: ${err instanceof Error ? err.message : String(err)}`);
161
+ process.exit(1);
162
+ }
163
+ });
164
+ // 添加基于配置文件的上传命令
165
+ program
166
+ .command('upload-config')
167
+ .description('基于vs.config.json配置文件上传文件到GCP存储桶')
168
+ .option('-c, --config <path>', '指定配置文件路径(默认为项目根目录下的vs.config.json)')
169
+ .option('-k, --key-file <path>', 'GCP服务账号密钥文件路径(可选,不提供则使用应用默认凭证)')
170
+ .option('-s, --source <path>', '自定义源路径(覆盖配置文件中的uploadPath)')
171
+ .option('-d, --destination <path>', '自定义目标路径(覆盖配置文件中的目标路径)')
172
+ .option('--no-recursive', '禁用递归上传目录中的文件')
173
+ .option('--no-compression', '禁用GZIP压缩')
174
+ .option('--show-config', '仅显示配置信息,不执行上传')
175
+ .action(async (options) => {
176
+ try {
177
+ const { config: configPath, keyFile, source: customSourcePath, destination: customDestination, recursive = true, compression = true, showConfig = false } = options;
178
+ // 如果只是显示配置信息
179
+ if (showConfig) {
180
+ try {
181
+ const configSummary = (0, uploadWithConfig_1.getConfigSummary)(configPath);
182
+ console.log('配置信息:');
183
+ console.log(` 桶名称: ${configSummary.bucketName}`);
184
+ console.log(` 源路径: ${configSummary.sourcePath}`);
185
+ console.log(` 目标路径: ${configSummary.destination}`);
186
+ return;
187
+ }
188
+ catch (err) {
189
+ console.error(`读取配置失败: ${err instanceof Error ? err.message : String(err)}`);
190
+ process.exit(1);
191
+ }
192
+ }
193
+ // 执行上传
194
+ const uploadOptions = {
195
+ configPath,
196
+ storageClientOptions: keyFile ? { keyFilename: keyFile } : {},
197
+ customSourcePath,
198
+ customDestination,
199
+ recursive,
200
+ enableCompression: compression
201
+ };
202
+ const result = await (0, uploadWithConfig_1.uploadFilesWithConfig)(uploadOptions);
203
+ if (result.success.length > 0) {
204
+ console.log('\n上传成功的文件:');
205
+ result.success.forEach((file) => {
206
+ console.log(` ✓ ${file.file} -> ${file.url}`);
207
+ });
208
+ }
209
+ if (result.failed.length > 0) {
210
+ console.log('\n上传失败的文件:');
211
+ result.failed.forEach((file) => {
212
+ console.log(` ✗ ${file.file}: ${file.error}`);
213
+ });
214
+ }
215
+ }
216
+ catch (err) {
217
+ console.error(`上传错误: ${err instanceof Error ? err.message : String(err)}`);
218
+ process.exit(1);
219
+ }
220
+ });
221
+ // 添加init命令
222
+ program
223
+ .command('init')
224
+ .description('在当前目录生成vs.config.json配置文件')
225
+ .option('-f, --force', '强制覆盖已存在的配置文件')
226
+ .action(async (options) => {
227
+ try {
228
+ const { force = false } = options;
229
+ const configPath = path.join(process.cwd(), 'vs.config.json');
230
+ // 检查文件是否已存在
231
+ if (fs.existsSync(configPath) && !force) {
232
+ console.error('错误: vs.config.json 文件已存在。使用 --force 选项强制覆盖。');
233
+ process.exit(1);
234
+ }
235
+ // 默认配置数据
236
+ const defaultConfig = {
237
+ "upload": {
238
+ "uploadPath": "out",
239
+ "s3Static": "static/aiAgent"
240
+ },
241
+ "deploy": {
242
+ "baseUrlExample": "baseUrl: ['/', 'en-us/', 'zh-hk/', 'test/']",
243
+ "baseUrl": [
244
+ "/",
245
+ "en-us/",
246
+ "zh-cn/",
247
+ "de-de/",
248
+ "it-it/",
249
+ "pt-pt/",
250
+ "es-es/",
251
+ "fr-fr/",
252
+ "ru-ru/",
253
+ "error/",
254
+ "download-v2/"
255
+ ],
256
+ "host": "https://www.china2u.xyz",
257
+ "testHost": "https://ai.decom.valleysound.xyz"
258
+ },
259
+ "aws": {
260
+ "Bucket": "decom-cdn",
261
+ "prefix": "fed",
262
+ "Region": "us-east-1",
263
+ "HostName": "https://cdn.cn2u.xyz"
264
+ },
265
+ "crowdin": {
266
+ "project": "fed-buy-buy-buy-home",
267
+ "langMap": ["zh-cn", "en-us", "de-de", "pt-pt", "fr-fr", "es-es", "it-it", "ru-ru"],
268
+ "workDir": "src",
269
+ "reg": "{#(.+?)#}",
270
+ "keysDir": "src/_i18n",
271
+ "Bucket": "mall-rocket-cdn",
272
+ "prefix": "fed",
273
+ "Region": "us-east-1",
274
+ "FromIni": "mall",
275
+ "HostName": "https://cdn.alvinclub.ca"
276
+ }
277
+ };
278
+ // 写入配置文件
279
+ fs.writeFileSync(configPath, JSON.stringify(defaultConfig, null, 2), 'utf-8');
280
+ console.log(`✓ 成功生成配置文件: ${configPath}`);
281
+ console.log('\n配置文件内容:');
282
+ console.log(` 桶名称: ${defaultConfig.aws.Bucket}`);
283
+ console.log(` 源路径: ${defaultConfig.upload.uploadPath}`);
284
+ console.log(` 目标路径: ${defaultConfig.aws.prefix}/${defaultConfig.upload.s3Static}`);
285
+ console.log('\n您可以根据需要修改配置文件中的值。');
286
+ }
287
+ catch (err) {
288
+ console.error(`生成配置文件失败: ${err instanceof Error ? err.message : String(err)}`);
289
+ process.exit(1);
290
+ }
291
+ });
292
+ // 解析命令行参数
293
+ program.parse(process.argv);
294
+ // 如果没有提供任何命令,显示帮助信息
295
+ if (!process.argv.slice(2).length) {
296
+ program.outputHelp();
297
+ }
@@ -0,0 +1,51 @@
1
+ {
2
+ "name": "ai-yuca",
3
+ "version": "1.0.0",
4
+ "description": "一个实用的AI辅助工具",
5
+ "main": "dist/src/index.js",
6
+ "types": "dist/src/index.d.ts",
7
+ "bin": {
8
+ "ai-yuca": "./dist/bin/cli.js"
9
+ },
10
+ "directories": {
11
+ "test": "test"
12
+ },
13
+ "scripts": {
14
+ "build": "tsc",
15
+ "test": "mocha -r ts-node/register 'test/**/*.ts'",
16
+ "start": "ts-node src/index.ts",
17
+ "lint": "eslint . --ext .ts",
18
+ "dev": "ts-node bin/cli.ts",
19
+ "prepublishOnly": "npm run build"
20
+ },
21
+ "keywords": [
22
+ "ai",
23
+ "tool",
24
+ "utility",
25
+ "cli"
26
+ ],
27
+ "author": "",
28
+ "license": "MIT",
29
+ "engines": {
30
+ "node": ">=14.0.0"
31
+ },
32
+ "dependencies": {
33
+ "@google-cloud/storage": "^7.17.1",
34
+ "commander": "^10.0.0"
35
+ },
36
+ "devDependencies": {
37
+ "@types/chai": "^5.2.2",
38
+ "@types/google-cloud__storage": "^2.3.1",
39
+ "@types/mocha": "^10.0.10",
40
+ "@types/node": "^24.3.1",
41
+ "@types/sinon": "^17.0.4",
42
+ "@typescript-eslint/eslint-plugin": "^8.43.0",
43
+ "@typescript-eslint/parser": "^8.43.0",
44
+ "chai": "^4.3.4",
45
+ "eslint": "^9.35.0",
46
+ "mocha": "^11.7.2",
47
+ "sinon": "^21.0.0",
48
+ "ts-node": "^10.9.2",
49
+ "typescript": "^5.9.2"
50
+ }
51
+ }