ai-yuca 1.1.7 → 1.1.8
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/bin/cli.ts +20 -1
- package/dist/bin/cli.js +18 -1
- package/dist/package.json +1 -1
- package/dist/src/deploy.js +30 -17
- package/dist/src/types/deploy.d.ts +1 -1
- package/dist/src/types/upload.d.ts +4 -0
- package/dist/src/upload.d.ts +9 -1
- package/dist/src/upload.js +45 -1
- package/dist/src/uploadWithConfig.js +27 -2
- package/out/ss/dd/index.js +0 -0
- package/out/ss/dd.js +0 -0
- package/package.json +1 -1
- package/src/deploy.ts +28 -16
- package/src/types/deploy.ts +1 -1
- package/src/types/upload.ts +4 -0
- package/src/upload.ts +51 -2
- package/src/uploadWithConfig.ts +29 -3
package/bin/cli.ts
CHANGED
|
@@ -97,7 +97,7 @@ program
|
|
|
97
97
|
console.log('开始上传文件...');
|
|
98
98
|
|
|
99
99
|
// 处理多个源路径
|
|
100
|
-
let allResults: UploadFilesResult = { success: [], failed: [] };
|
|
100
|
+
let allResults: UploadFilesResult = { success: [], failed: [], files: [] };
|
|
101
101
|
|
|
102
102
|
for (const sourcePath of source) {
|
|
103
103
|
console.log(`\n处理路径: ${sourcePath}`);
|
|
@@ -134,6 +134,9 @@ program
|
|
|
134
134
|
// 合并结果
|
|
135
135
|
allResults.success = allResults.success.concat(results.success);
|
|
136
136
|
allResults.failed = allResults.failed.concat(results.failed);
|
|
137
|
+
if (results.files) {
|
|
138
|
+
allResults.files = allResults.files!.concat(results.files);
|
|
139
|
+
}
|
|
137
140
|
}
|
|
138
141
|
|
|
139
142
|
const results = allResults;
|
|
@@ -156,6 +159,14 @@ program
|
|
|
156
159
|
console.log(`- ${file.file}: ${file.error}`);
|
|
157
160
|
});
|
|
158
161
|
}
|
|
162
|
+
|
|
163
|
+
// 如果有files字段,显示目录下的所有文件
|
|
164
|
+
if (results.files && results.files.length > 0) {
|
|
165
|
+
console.log('\n目录下的所有文件:');
|
|
166
|
+
results.files.forEach(file => {
|
|
167
|
+
console.log(`- ${file}`);
|
|
168
|
+
});
|
|
169
|
+
}
|
|
159
170
|
} catch (err) {
|
|
160
171
|
console.error(`上传错误: ${err instanceof Error ? err.message : String(err)}`);
|
|
161
172
|
process.exit(1);
|
|
@@ -289,6 +300,14 @@ program
|
|
|
289
300
|
console.log(` ✗ ${file.file}: ${file.error}`);
|
|
290
301
|
});
|
|
291
302
|
}
|
|
303
|
+
|
|
304
|
+
// 显示目录下的所有文件
|
|
305
|
+
if (result.files && result.files.length > 0) {
|
|
306
|
+
console.log('\n目录下的所有文件:');
|
|
307
|
+
result.files.forEach((file) => {
|
|
308
|
+
console.log(`- ${file}`);
|
|
309
|
+
});
|
|
310
|
+
}
|
|
292
311
|
|
|
293
312
|
} catch (err) {
|
|
294
313
|
console.error(`上传错误: ${err instanceof Error ? err.message : String(err)}`);
|
package/dist/bin/cli.js
CHANGED
|
@@ -120,7 +120,7 @@ program
|
|
|
120
120
|
: (0, upload_1.createStorageClient)(); // 使用应用默认凭证
|
|
121
121
|
console.log('开始上传文件...');
|
|
122
122
|
// 处理多个源路径
|
|
123
|
-
let allResults = { success: [], failed: [] };
|
|
123
|
+
let allResults = { success: [], failed: [], files: [] };
|
|
124
124
|
for (const sourcePath of source) {
|
|
125
125
|
console.log(`\n处理路径: ${sourcePath}`);
|
|
126
126
|
// 检查路径是否存在
|
|
@@ -153,6 +153,9 @@ program
|
|
|
153
153
|
// 合并结果
|
|
154
154
|
allResults.success = allResults.success.concat(results.success);
|
|
155
155
|
allResults.failed = allResults.failed.concat(results.failed);
|
|
156
|
+
if (results.files) {
|
|
157
|
+
allResults.files = allResults.files.concat(results.files);
|
|
158
|
+
}
|
|
156
159
|
}
|
|
157
160
|
const results = allResults;
|
|
158
161
|
// 输出结果
|
|
@@ -171,6 +174,13 @@ program
|
|
|
171
174
|
console.log(`- ${file.file}: ${file.error}`);
|
|
172
175
|
});
|
|
173
176
|
}
|
|
177
|
+
// 如果有files字段,显示目录下的所有文件
|
|
178
|
+
if (results.files && results.files.length > 0) {
|
|
179
|
+
console.log('\n目录下的所有文件:');
|
|
180
|
+
results.files.forEach(file => {
|
|
181
|
+
console.log(`- ${file}`);
|
|
182
|
+
});
|
|
183
|
+
}
|
|
174
184
|
}
|
|
175
185
|
catch (err) {
|
|
176
186
|
console.error(`上传错误: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -283,6 +293,13 @@ program
|
|
|
283
293
|
console.log(` ✗ ${file.file}: ${file.error}`);
|
|
284
294
|
});
|
|
285
295
|
}
|
|
296
|
+
// 显示目录下的所有文件
|
|
297
|
+
if (result.files && result.files.length > 0) {
|
|
298
|
+
console.log('\n目录下的所有文件:');
|
|
299
|
+
result.files.forEach((file) => {
|
|
300
|
+
console.log(`- ${file}`);
|
|
301
|
+
});
|
|
302
|
+
}
|
|
286
303
|
}
|
|
287
304
|
catch (err) {
|
|
288
305
|
console.error(`上传错误: ${err instanceof Error ? err.message : String(err)}`);
|
package/dist/package.json
CHANGED
package/dist/src/deploy.js
CHANGED
|
@@ -198,18 +198,26 @@ async function updateEnvironmentConfig(env, projectName, versionInfo, config, ke
|
|
|
198
198
|
let projectConfig = envConfig.projects.find((p) => p.name === projectName);
|
|
199
199
|
if (!projectConfig) {
|
|
200
200
|
projectConfig = {
|
|
201
|
+
baseUrl: versionInfo.baseUrl,
|
|
202
|
+
s3Static: config.upload.s3Static,
|
|
203
|
+
branch: versionInfo.branch,
|
|
204
|
+
links: versionInfo.links,
|
|
201
205
|
name: projectName,
|
|
202
206
|
latestVersion: versionInfo.cdnKey,
|
|
203
|
-
|
|
207
|
+
cdnVersion: versionInfo.cdnKey,
|
|
204
208
|
};
|
|
205
209
|
envConfig.projects.push(projectConfig);
|
|
206
210
|
}
|
|
207
211
|
else {
|
|
208
|
-
projectConfig
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
212
|
+
projectConfig = {
|
|
213
|
+
baseUrl: versionInfo.baseUrl,
|
|
214
|
+
s3Static: config.upload.s3Static,
|
|
215
|
+
branch: versionInfo.branch,
|
|
216
|
+
links: versionInfo.links,
|
|
217
|
+
name: projectName,
|
|
218
|
+
latestVersion: versionInfo.cdnKey,
|
|
219
|
+
cdnVersion: versionInfo.cdnKey,
|
|
220
|
+
};
|
|
213
221
|
}
|
|
214
222
|
// 上传更新后的环境配置
|
|
215
223
|
const configPath = `${config.aws.prefix}/static/config/${env}.config.json`;
|
|
@@ -230,6 +238,7 @@ async function updateEnvironmentConfig(env, projectName, versionInfo, config, ke
|
|
|
230
238
|
* 执行deploy命令
|
|
231
239
|
*/
|
|
232
240
|
async function deployFiles(options) {
|
|
241
|
+
var _a;
|
|
233
242
|
try {
|
|
234
243
|
console.log('🚀 开始部署流程...');
|
|
235
244
|
// 1. 配置校验阶段
|
|
@@ -237,12 +246,16 @@ async function deployFiles(options) {
|
|
|
237
246
|
const config = validateConfig(options.config);
|
|
238
247
|
// 2. 执行upload-config阶段
|
|
239
248
|
console.log('📤 执行upload-config上传配置文件...');
|
|
249
|
+
let files = [];
|
|
240
250
|
try {
|
|
241
|
-
await (0, uploadWithConfig_1.uploadFilesWithConfig)({
|
|
251
|
+
const res = await (0, uploadWithConfig_1.uploadFilesWithConfig)({
|
|
242
252
|
configPath: options.config,
|
|
243
253
|
storageClientOptions: options.keyFile ? { keyFilename: options.keyFile } : {},
|
|
244
254
|
enableCache: true
|
|
245
255
|
});
|
|
256
|
+
if ((_a = res.files) === null || _a === void 0 ? void 0 : _a.length) {
|
|
257
|
+
files = res.files;
|
|
258
|
+
}
|
|
246
259
|
}
|
|
247
260
|
catch (error) {
|
|
248
261
|
console.warn(`⚠️ upload-config执行失败: ${error instanceof Error ? error.message : String(error)}`);
|
|
@@ -258,18 +271,18 @@ async function deployFiles(options) {
|
|
|
258
271
|
const projectInfo = getProjectInfo();
|
|
259
272
|
console.log('🔍 筛选目标文件...');
|
|
260
273
|
const sourcePath = options.source || uploadConfig.sourcePath;
|
|
261
|
-
const
|
|
262
|
-
const cdnFiles =
|
|
274
|
+
const htmlFiles = filterHtmlFiles(sourcePath);
|
|
275
|
+
const cdnFiles = htmlFiles.map(file => ({ key: path.relative(sourcePath, file) }));
|
|
263
276
|
console.log('📁 定义基础路径...');
|
|
264
277
|
const prefix = `${config.aws.prefix}/${config.upload.s3Static}`;
|
|
265
|
-
if (
|
|
278
|
+
if (htmlFiles.length === 0) {
|
|
266
279
|
throw new Error('未找到需要上传的HTML文件');
|
|
267
280
|
}
|
|
268
281
|
// 5. 文件处理与上传阶段
|
|
269
282
|
console.log('📤 上传原始HTML文件...');
|
|
270
283
|
const uploadedFiles = [];
|
|
271
284
|
// 使用Promise.all并行上传文件
|
|
272
|
-
const uploadPromises =
|
|
285
|
+
const uploadPromises = htmlFiles.map(file => {
|
|
273
286
|
const relativePath = path.relative(sourcePath, file);
|
|
274
287
|
const destination = `${prefix}/${cdnKey}/${relativePath}`;
|
|
275
288
|
console.log(` 上传: ${relativePath}`);
|
|
@@ -294,18 +307,18 @@ async function deployFiles(options) {
|
|
|
294
307
|
}
|
|
295
308
|
// 6. 发布配置文件上传阶段
|
|
296
309
|
console.log('📝 生成发布信息对象...');
|
|
297
|
-
const langCdnHtml = []; // 多语言HTML文件,暂时为空
|
|
298
310
|
const obj = {
|
|
299
311
|
cdnVersion: cdnKey,
|
|
300
312
|
name: projectInfo.name,
|
|
301
313
|
baseUrl: config.deploy.baseUrl,
|
|
302
|
-
links:
|
|
314
|
+
links: uploadedFiles,
|
|
303
315
|
s3Static: config.upload.s3Static,
|
|
304
|
-
branch: getBranchName()
|
|
316
|
+
branch: getBranchName(),
|
|
317
|
+
files
|
|
305
318
|
};
|
|
306
319
|
console.log('📤 上传版本配置文件...');
|
|
307
320
|
const versionConfigPath = `${config.aws.prefix}/static/config/${options.env}/${projectInfo.name}/${cdnKey}.json`;
|
|
308
|
-
const versionConfigContent = JSON.stringify(
|
|
321
|
+
const versionConfigContent = JSON.stringify(obj, null, 2);
|
|
309
322
|
// 创建临时文件上传JSON内容
|
|
310
323
|
const tempVersionFile = path.join(process.cwd(), `.temp-version-${cdnKey}.json`);
|
|
311
324
|
fs.writeFileSync(tempVersionFile, versionConfigContent);
|
|
@@ -332,7 +345,7 @@ async function deployFiles(options) {
|
|
|
332
345
|
// 这里应该从GCP读取现有版本列表,暂时跳过
|
|
333
346
|
versionList = [cdnKey]; // 简化处理
|
|
334
347
|
}
|
|
335
|
-
catch (
|
|
348
|
+
catch (_b) {
|
|
336
349
|
versionList = [cdnKey];
|
|
337
350
|
}
|
|
338
351
|
// 保留最近50个版本
|
|
@@ -387,7 +400,7 @@ async function deployFiles(options) {
|
|
|
387
400
|
baseUrl: Array.isArray(config.deploy.baseUrl) ? config.deploy.baseUrl[0] : config.deploy.baseUrl,
|
|
388
401
|
branch: getBranchName(),
|
|
389
402
|
timestamp: Date.now(),
|
|
390
|
-
|
|
403
|
+
links: obj.links
|
|
391
404
|
};
|
|
392
405
|
const projectConfigUpdate = await updateEnvironmentConfig(options.env, projectInfo.name, versionInfo, config, options.keyFile);
|
|
393
406
|
console.log('项目配置信息上传结果:', JSON.stringify(projectConfigUpdate));
|
|
@@ -72,6 +72,10 @@ export type UploadResult = UploadSuccessResult | UploadFailedResult;
|
|
|
72
72
|
export interface UploadFilesResult {
|
|
73
73
|
success: UploadSuccessResult[];
|
|
74
74
|
failed: UploadFailedResult[];
|
|
75
|
+
/**
|
|
76
|
+
* 当源路径为目录时,返回该目录下所有文件的相对路径
|
|
77
|
+
*/
|
|
78
|
+
files?: string[];
|
|
75
79
|
}
|
|
76
80
|
/**
|
|
77
81
|
* CLI上传命令选项接口
|
package/dist/src/upload.d.ts
CHANGED
|
@@ -3,6 +3,14 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import { Storage } from '@google-cloud/storage';
|
|
5
5
|
import { StorageClientOptions, UploadFileOptions, UploadFilesOptions, UploadResult, UploadFilesResult } from './types/upload';
|
|
6
|
+
/**
|
|
7
|
+
* 递归收集目录下所有文件的相对路径
|
|
8
|
+
* @param dirPath - 目录路径
|
|
9
|
+
* @param basePath - 基础路径,用于计算相对路径
|
|
10
|
+
* @param recursive - 是否递归
|
|
11
|
+
* @returns 文件相对路径数组
|
|
12
|
+
*/
|
|
13
|
+
declare function collectFiles(dirPath: string, basePath: string, recursive?: boolean): Promise<string[]>;
|
|
6
14
|
/**
|
|
7
15
|
* 创建GCP存储客户端
|
|
8
16
|
* @param options - 配置选项
|
|
@@ -21,4 +29,4 @@ declare function uploadFile(options: UploadFileOptions): Promise<UploadResult>;
|
|
|
21
29
|
* @returns 上传结果
|
|
22
30
|
*/
|
|
23
31
|
declare function uploadFiles(options: UploadFilesOptions): Promise<UploadFilesResult>;
|
|
24
|
-
export { createStorageClient, uploadFile, uploadFiles };
|
|
32
|
+
export { createStorageClient, uploadFile, uploadFiles, collectFiles };
|
package/dist/src/upload.js
CHANGED
|
@@ -36,6 +36,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
36
36
|
exports.createStorageClient = createStorageClient;
|
|
37
37
|
exports.uploadFile = uploadFile;
|
|
38
38
|
exports.uploadFiles = uploadFiles;
|
|
39
|
+
exports.collectFiles = collectFiles;
|
|
39
40
|
/**
|
|
40
41
|
* GCP上传功能模块
|
|
41
42
|
*/
|
|
@@ -47,6 +48,32 @@ const compression_1 = require("./utils/compression");
|
|
|
47
48
|
const config_1 = require("./config");
|
|
48
49
|
const readdir = util.promisify(fs.readdir);
|
|
49
50
|
const stat = util.promisify(fs.stat);
|
|
51
|
+
/**
|
|
52
|
+
* 递归收集目录下所有文件的相对路径
|
|
53
|
+
* @param dirPath - 目录路径
|
|
54
|
+
* @param basePath - 基础路径,用于计算相对路径
|
|
55
|
+
* @param recursive - 是否递归
|
|
56
|
+
* @returns 文件相对路径数组
|
|
57
|
+
*/
|
|
58
|
+
async function collectFiles(dirPath, basePath, recursive = false) {
|
|
59
|
+
const files = [];
|
|
60
|
+
const items = await readdir(dirPath);
|
|
61
|
+
for (const item of items) {
|
|
62
|
+
const itemPath = path.join(dirPath, item);
|
|
63
|
+
const itemStats = await stat(itemPath);
|
|
64
|
+
if (itemStats.isFile()) {
|
|
65
|
+
// 计算相对于basePath的相对路径
|
|
66
|
+
const relativePath = path.relative(basePath, itemPath);
|
|
67
|
+
files.push(relativePath);
|
|
68
|
+
}
|
|
69
|
+
else if (recursive && itemStats.isDirectory()) {
|
|
70
|
+
// 递归收集子目录中的文件
|
|
71
|
+
const subFiles = await collectFiles(itemPath, basePath, recursive);
|
|
72
|
+
files.push(...subFiles);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return files;
|
|
76
|
+
}
|
|
50
77
|
/**
|
|
51
78
|
* 创建GCP存储客户端
|
|
52
79
|
* @param options - 配置选项
|
|
@@ -186,11 +213,20 @@ async function uploadFiles(options) {
|
|
|
186
213
|
}
|
|
187
214
|
const results = {
|
|
188
215
|
success: [],
|
|
189
|
-
failed: []
|
|
216
|
+
failed: [],
|
|
217
|
+
files: []
|
|
190
218
|
};
|
|
191
219
|
try {
|
|
192
220
|
// 如果sourcePath是数组,批量上传多个文件
|
|
193
221
|
if (Array.isArray(sourcePath)) {
|
|
222
|
+
for (const filePath of sourcePath) {
|
|
223
|
+
const stats = await stat(filePath);
|
|
224
|
+
if (stats.isDirectory()) {
|
|
225
|
+
// 如果是目录,收集其中的文件
|
|
226
|
+
const dirFiles = await collectFiles(filePath, filePath, recursive);
|
|
227
|
+
results.files = results.files.concat(dirFiles);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
194
230
|
const uploadPromises = sourcePath.map(filePath => uploadFile({
|
|
195
231
|
bucketName,
|
|
196
232
|
filePath,
|
|
@@ -228,6 +264,9 @@ async function uploadFiles(options) {
|
|
|
228
264
|
}
|
|
229
265
|
}
|
|
230
266
|
else if (stats.isDirectory()) {
|
|
267
|
+
// 收集目录下所有文件的相对路径
|
|
268
|
+
const allFiles = await collectFiles(sourcePath, sourcePath, recursive);
|
|
269
|
+
results.files = allFiles;
|
|
231
270
|
// 上传目录中的文件
|
|
232
271
|
const files = await readdir(sourcePath);
|
|
233
272
|
// 分离文件和目录
|
|
@@ -278,6 +317,11 @@ async function uploadFiles(options) {
|
|
|
278
317
|
for (const subResults of dirResults) {
|
|
279
318
|
results.success = results.success.concat(subResults.success);
|
|
280
319
|
results.failed = results.failed.concat(subResults.failed);
|
|
320
|
+
// 合并子目录的files字段
|
|
321
|
+
if (subResults.files) {
|
|
322
|
+
results.files = results.files || [];
|
|
323
|
+
results.files = results.files.concat(subResults.files);
|
|
324
|
+
}
|
|
281
325
|
}
|
|
282
326
|
}
|
|
283
327
|
}
|
|
@@ -161,7 +161,7 @@ async function uploadFilesWithConfig(options = {}) {
|
|
|
161
161
|
// 如果没有文件需要上传,直接返回
|
|
162
162
|
if (filesToUpload.length === 0) {
|
|
163
163
|
console.log('所有文件都已上传,无需重复上传。');
|
|
164
|
-
|
|
164
|
+
const result = {
|
|
165
165
|
success: skippedFiles.map(file => ({
|
|
166
166
|
success: true,
|
|
167
167
|
file,
|
|
@@ -171,8 +171,21 @@ async function uploadFilesWithConfig(options = {}) {
|
|
|
171
171
|
contentType: 'application/octet-stream',
|
|
172
172
|
timeCreated: new Date().toISOString()
|
|
173
173
|
})),
|
|
174
|
-
failed: []
|
|
174
|
+
failed: [],
|
|
175
|
+
files: []
|
|
175
176
|
};
|
|
177
|
+
// 收集目录下所有文件的相对路径
|
|
178
|
+
try {
|
|
179
|
+
const stats = await stat(sourcePath);
|
|
180
|
+
if (stats.isDirectory()) {
|
|
181
|
+
const allFiles = await (0, upload_1.collectFiles)(sourcePath, sourcePath, recursive);
|
|
182
|
+
result.files = allFiles;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
catch (error) {
|
|
186
|
+
console.warn('收集文件列表时出错:', error);
|
|
187
|
+
}
|
|
188
|
+
return result;
|
|
176
189
|
}
|
|
177
190
|
}
|
|
178
191
|
// 执行批量上传
|
|
@@ -221,6 +234,18 @@ async function uploadFilesWithConfig(options = {}) {
|
|
|
221
234
|
}));
|
|
222
235
|
result.success.push(...skippedResults);
|
|
223
236
|
}
|
|
237
|
+
// 收集目录下所有文件的相对路径
|
|
238
|
+
try {
|
|
239
|
+
const stats = await stat(sourcePath);
|
|
240
|
+
if (stats.isDirectory()) {
|
|
241
|
+
const allFiles = await (0, upload_1.collectFiles)(sourcePath, sourcePath, recursive);
|
|
242
|
+
result.files = allFiles;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
catch (error) {
|
|
246
|
+
// 如果收集文件失败,不影响主要功能
|
|
247
|
+
console.warn('收集文件列表时出错:', error);
|
|
248
|
+
}
|
|
224
249
|
return result;
|
|
225
250
|
}
|
|
226
251
|
catch (error) {
|
|
File without changes
|
package/out/ss/dd.js
ADDED
|
File without changes
|
package/package.json
CHANGED
package/src/deploy.ts
CHANGED
|
@@ -205,17 +205,25 @@ async function updateEnvironmentConfig(
|
|
|
205
205
|
|
|
206
206
|
if (!projectConfig) {
|
|
207
207
|
projectConfig = {
|
|
208
|
+
baseUrl: versionInfo.baseUrl,
|
|
209
|
+
s3Static:config.upload.s3Static,
|
|
210
|
+
branch: versionInfo.branch,
|
|
211
|
+
links: versionInfo.links,
|
|
208
212
|
name: projectName,
|
|
209
213
|
latestVersion: versionInfo.cdnKey,
|
|
210
|
-
|
|
214
|
+
cdnVersion: versionInfo.cdnKey,
|
|
211
215
|
};
|
|
212
216
|
envConfig.projects.push(projectConfig);
|
|
213
217
|
} else {
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
218
|
+
projectConfig = {
|
|
219
|
+
baseUrl: versionInfo.baseUrl,
|
|
220
|
+
s3Static:config.upload.s3Static,
|
|
221
|
+
branch: versionInfo.branch,
|
|
222
|
+
links: versionInfo.links,
|
|
223
|
+
name: projectName,
|
|
224
|
+
latestVersion: versionInfo.cdnKey,
|
|
225
|
+
cdnVersion: versionInfo.cdnKey,
|
|
226
|
+
};
|
|
219
227
|
}
|
|
220
228
|
|
|
221
229
|
// 上传更新后的环境配置
|
|
@@ -252,12 +260,16 @@ export async function deployFiles(options: DeployCommandOptions): Promise<Deploy
|
|
|
252
260
|
|
|
253
261
|
// 2. 执行upload-config阶段
|
|
254
262
|
console.log('📤 执行upload-config上传配置文件...');
|
|
263
|
+
let files: string[] = [];
|
|
255
264
|
try {
|
|
256
|
-
|
|
265
|
+
const res = await uploadFilesWithConfig({
|
|
257
266
|
configPath: options.config,
|
|
258
267
|
storageClientOptions: options.keyFile ? { keyFilename: options.keyFile } : {},
|
|
259
268
|
enableCache: true
|
|
260
269
|
});
|
|
270
|
+
if (res.files?.length){
|
|
271
|
+
files = res.files;
|
|
272
|
+
}
|
|
261
273
|
} catch (error) {
|
|
262
274
|
console.warn(`⚠️ upload-config执行失败: ${error instanceof Error ? error.message : String(error)}`);
|
|
263
275
|
}
|
|
@@ -276,13 +288,13 @@ export async function deployFiles(options: DeployCommandOptions): Promise<Deploy
|
|
|
276
288
|
|
|
277
289
|
console.log('🔍 筛选目标文件...');
|
|
278
290
|
const sourcePath = options.source || uploadConfig.sourcePath;
|
|
279
|
-
const
|
|
280
|
-
const cdnFiles =
|
|
291
|
+
const htmlFiles = filterHtmlFiles(sourcePath);
|
|
292
|
+
const cdnFiles = htmlFiles.map(file => ({ key: path.relative(sourcePath, file) }));
|
|
281
293
|
|
|
282
294
|
console.log('📁 定义基础路径...');
|
|
283
295
|
const prefix = `${config.aws.prefix}/${config.upload.s3Static}`;
|
|
284
296
|
|
|
285
|
-
if (
|
|
297
|
+
if (htmlFiles.length === 0) {
|
|
286
298
|
throw new Error('未找到需要上传的HTML文件');
|
|
287
299
|
}
|
|
288
300
|
|
|
@@ -291,7 +303,7 @@ export async function deployFiles(options: DeployCommandOptions): Promise<Deploy
|
|
|
291
303
|
const uploadedFiles: string[] = [];
|
|
292
304
|
|
|
293
305
|
// 使用Promise.all并行上传文件
|
|
294
|
-
const uploadPromises =
|
|
306
|
+
const uploadPromises = htmlFiles.map(file => {
|
|
295
307
|
const relativePath = path.relative(sourcePath, file);
|
|
296
308
|
const destination = `${prefix}/${cdnKey}/${relativePath}`;
|
|
297
309
|
|
|
@@ -319,19 +331,19 @@ export async function deployFiles(options: DeployCommandOptions): Promise<Deploy
|
|
|
319
331
|
|
|
320
332
|
// 6. 发布配置文件上传阶段
|
|
321
333
|
console.log('📝 生成发布信息对象...');
|
|
322
|
-
const langCdnHtml: string[] = []; // 多语言HTML文件,暂时为空
|
|
323
334
|
const obj = {
|
|
324
335
|
cdnVersion: cdnKey,
|
|
325
336
|
name: projectInfo.name,
|
|
326
337
|
baseUrl: config.deploy.baseUrl,
|
|
327
|
-
links:
|
|
338
|
+
links: uploadedFiles,
|
|
328
339
|
s3Static: config.upload.s3Static,
|
|
329
|
-
branch: getBranchName()
|
|
340
|
+
branch: getBranchName(),
|
|
341
|
+
files
|
|
330
342
|
};
|
|
331
343
|
|
|
332
344
|
console.log('📤 上传版本配置文件...');
|
|
333
345
|
const versionConfigPath = `${config.aws.prefix}/static/config/${options.env}/${projectInfo.name}/${cdnKey}.json`;
|
|
334
|
-
const versionConfigContent = JSON.stringify(
|
|
346
|
+
const versionConfigContent = JSON.stringify(obj, null, 2);
|
|
335
347
|
|
|
336
348
|
// 创建临时文件上传JSON内容
|
|
337
349
|
const tempVersionFile = path.join(process.cwd(), `.temp-version-${cdnKey}.json`);
|
|
@@ -422,7 +434,7 @@ export async function deployFiles(options: DeployCommandOptions): Promise<Deploy
|
|
|
422
434
|
baseUrl: Array.isArray(config.deploy.baseUrl) ? config.deploy.baseUrl[0] : config.deploy.baseUrl,
|
|
423
435
|
branch: getBranchName(),
|
|
424
436
|
timestamp: Date.now(),
|
|
425
|
-
|
|
437
|
+
links: obj.links
|
|
426
438
|
};
|
|
427
439
|
|
|
428
440
|
const projectConfigUpdate = await updateEnvironmentConfig(options.env, projectInfo.name, versionInfo, config, options.keyFile);
|
package/src/types/deploy.ts
CHANGED
package/src/types/upload.ts
CHANGED
|
@@ -79,6 +79,10 @@ export type UploadResult = UploadSuccessResult | UploadFailedResult;
|
|
|
79
79
|
export interface UploadFilesResult {
|
|
80
80
|
success: UploadSuccessResult[];
|
|
81
81
|
failed: UploadFailedResult[];
|
|
82
|
+
/**
|
|
83
|
+
* 当源路径为目录时,返回该目录下所有文件的相对路径
|
|
84
|
+
*/
|
|
85
|
+
files?: string[];
|
|
82
86
|
}
|
|
83
87
|
|
|
84
88
|
/**
|
package/src/upload.ts
CHANGED
|
@@ -20,6 +20,35 @@ import { loadConfig } from './config';
|
|
|
20
20
|
const readdir = util.promisify(fs.readdir);
|
|
21
21
|
const stat = util.promisify(fs.stat);
|
|
22
22
|
|
|
23
|
+
/**
|
|
24
|
+
* 递归收集目录下所有文件的相对路径
|
|
25
|
+
* @param dirPath - 目录路径
|
|
26
|
+
* @param basePath - 基础路径,用于计算相对路径
|
|
27
|
+
* @param recursive - 是否递归
|
|
28
|
+
* @returns 文件相对路径数组
|
|
29
|
+
*/
|
|
30
|
+
async function collectFiles(dirPath: string, basePath: string, recursive: boolean = false): Promise<string[]> {
|
|
31
|
+
const files: string[] = [];
|
|
32
|
+
const items = await readdir(dirPath);
|
|
33
|
+
|
|
34
|
+
for (const item of items) {
|
|
35
|
+
const itemPath = path.join(dirPath, item);
|
|
36
|
+
const itemStats = await stat(itemPath);
|
|
37
|
+
|
|
38
|
+
if (itemStats.isFile()) {
|
|
39
|
+
// 计算相对于basePath的相对路径
|
|
40
|
+
const relativePath = path.relative(basePath, itemPath);
|
|
41
|
+
files.push(relativePath);
|
|
42
|
+
} else if (recursive && itemStats.isDirectory()) {
|
|
43
|
+
// 递归收集子目录中的文件
|
|
44
|
+
const subFiles = await collectFiles(itemPath, basePath, recursive);
|
|
45
|
+
files.push(...subFiles);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return files;
|
|
50
|
+
}
|
|
51
|
+
|
|
23
52
|
/**
|
|
24
53
|
* 创建GCP存储客户端
|
|
25
54
|
* @param options - 配置选项
|
|
@@ -177,12 +206,22 @@ async function uploadFiles(options: UploadFilesOptions): Promise<UploadFilesResu
|
|
|
177
206
|
|
|
178
207
|
const results: UploadFilesResult = {
|
|
179
208
|
success: [],
|
|
180
|
-
failed: []
|
|
209
|
+
failed: [],
|
|
210
|
+
files: []
|
|
181
211
|
};
|
|
182
212
|
|
|
183
213
|
try {
|
|
184
214
|
// 如果sourcePath是数组,批量上传多个文件
|
|
185
215
|
if (Array.isArray(sourcePath)) {
|
|
216
|
+
for (const filePath of sourcePath) {
|
|
217
|
+
const stats = await stat(filePath);
|
|
218
|
+
if (stats.isDirectory()) {
|
|
219
|
+
// 如果是目录,收集其中的文件
|
|
220
|
+
const dirFiles = await collectFiles(filePath, filePath, recursive);
|
|
221
|
+
results.files = results.files!.concat(dirFiles);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
186
225
|
const uploadPromises = sourcePath.map(filePath =>
|
|
187
226
|
uploadFile({
|
|
188
227
|
bucketName,
|
|
@@ -224,6 +263,10 @@ async function uploadFiles(options: UploadFilesOptions): Promise<UploadFilesResu
|
|
|
224
263
|
results.failed.push(result);
|
|
225
264
|
}
|
|
226
265
|
} else if (stats.isDirectory()) {
|
|
266
|
+
// 收集目录下所有文件的相对路径
|
|
267
|
+
const allFiles = await collectFiles(sourcePath, sourcePath, recursive);
|
|
268
|
+
results.files = allFiles;
|
|
269
|
+
|
|
227
270
|
// 上传目录中的文件
|
|
228
271
|
const files = await readdir(sourcePath);
|
|
229
272
|
|
|
@@ -283,6 +326,11 @@ async function uploadFiles(options: UploadFilesOptions): Promise<UploadFilesResu
|
|
|
283
326
|
for (const subResults of dirResults) {
|
|
284
327
|
results.success = results.success.concat(subResults.success);
|
|
285
328
|
results.failed = results.failed.concat(subResults.failed);
|
|
329
|
+
// 合并子目录的files字段
|
|
330
|
+
if (subResults.files) {
|
|
331
|
+
results.files = results.files || [];
|
|
332
|
+
results.files = results.files.concat(subResults.files);
|
|
333
|
+
}
|
|
286
334
|
}
|
|
287
335
|
}
|
|
288
336
|
}
|
|
@@ -296,5 +344,6 @@ async function uploadFiles(options: UploadFilesOptions): Promise<UploadFilesResu
|
|
|
296
344
|
export {
|
|
297
345
|
createStorageClient,
|
|
298
346
|
uploadFile,
|
|
299
|
-
uploadFiles
|
|
347
|
+
uploadFiles,
|
|
348
|
+
collectFiles
|
|
300
349
|
};
|
package/src/uploadWithConfig.ts
CHANGED
|
@@ -6,7 +6,7 @@ import * as path from 'path';
|
|
|
6
6
|
import * as fs from 'fs';
|
|
7
7
|
import chalk from 'chalk';
|
|
8
8
|
import { StorageClientOptions, UploadFilesResult } from './types/upload';
|
|
9
|
-
import { uploadFiles } from './upload';
|
|
9
|
+
import { uploadFiles, collectFiles } from './upload';
|
|
10
10
|
import { loadConfig, getBucketName, getUploadDestination, getUploadSourcePath, VSConfig } from './config';
|
|
11
11
|
import { CacheManager, createCacheManager } from './cache';
|
|
12
12
|
|
|
@@ -171,7 +171,7 @@ export async function uploadFilesWithConfig(options: UploadWithConfigOptions = {
|
|
|
171
171
|
// 如果没有文件需要上传,直接返回
|
|
172
172
|
if (filesToUpload.length === 0) {
|
|
173
173
|
console.log('所有文件都已上传,无需重复上传。');
|
|
174
|
-
|
|
174
|
+
const result = {
|
|
175
175
|
success: skippedFiles.map(file => ({
|
|
176
176
|
success: true as const,
|
|
177
177
|
file,
|
|
@@ -181,8 +181,22 @@ export async function uploadFilesWithConfig(options: UploadWithConfigOptions = {
|
|
|
181
181
|
contentType: 'application/octet-stream',
|
|
182
182
|
timeCreated: new Date().toISOString()
|
|
183
183
|
})),
|
|
184
|
-
failed: []
|
|
184
|
+
failed: [],
|
|
185
|
+
files: [] as string[]
|
|
185
186
|
};
|
|
187
|
+
|
|
188
|
+
// 收集目录下所有文件的相对路径
|
|
189
|
+
try {
|
|
190
|
+
const stats = await stat(sourcePath);
|
|
191
|
+
if (stats.isDirectory()) {
|
|
192
|
+
const allFiles = await collectFiles(sourcePath, sourcePath, recursive);
|
|
193
|
+
result.files = allFiles;
|
|
194
|
+
}
|
|
195
|
+
} catch (error) {
|
|
196
|
+
console.warn('收集文件列表时出错:', error);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
return result;
|
|
186
200
|
}
|
|
187
201
|
}
|
|
188
202
|
|
|
@@ -236,6 +250,18 @@ export async function uploadFilesWithConfig(options: UploadWithConfigOptions = {
|
|
|
236
250
|
result.success.push(...skippedResults);
|
|
237
251
|
}
|
|
238
252
|
|
|
253
|
+
// 收集目录下所有文件的相对路径
|
|
254
|
+
try {
|
|
255
|
+
const stats = await stat(sourcePath);
|
|
256
|
+
if (stats.isDirectory()) {
|
|
257
|
+
const allFiles = await collectFiles(sourcePath, sourcePath, recursive);
|
|
258
|
+
result.files = allFiles;
|
|
259
|
+
}
|
|
260
|
+
} catch (error) {
|
|
261
|
+
// 如果收集文件失败,不影响主要功能
|
|
262
|
+
console.warn('收集文件列表时出错:', error);
|
|
263
|
+
}
|
|
264
|
+
|
|
239
265
|
return result;
|
|
240
266
|
} catch (error) {
|
|
241
267
|
throw new Error(`基于配置文件的上传失败: ${error instanceof Error ? error.message : String(error)}`);
|