107 lines
3.1 KiB
TypeScript
107 lines
3.1 KiB
TypeScript
// lib/fs-utils.ts
|
||
import fs from 'fs/promises';
|
||
import path from 'path';
|
||
import { RESOURCE_PATH } from './constants';
|
||
|
||
/**
|
||
* 获取所有项目目录
|
||
*/
|
||
export async function getProjects(): Promise<string[]> {
|
||
const dirs = await fs.readdir(RESOURCE_PATH);
|
||
const projectDirs = dirs.filter(dir => {
|
||
const dirPath = path.join(RESOURCE_PATH, dir);
|
||
// 检查是否是目录
|
||
return fs.stat(dirPath).then(stats => stats.isDirectory()).catch(() => false);
|
||
});
|
||
return projectDirs;
|
||
}
|
||
|
||
/**
|
||
* 获取指定项目的所有版本目录
|
||
*/
|
||
export async function getVersions(project: string): Promise<string[]> {
|
||
const projectPath = path.join(RESOURCE_PATH, project);
|
||
const dirs = await fs.readdir(projectPath);
|
||
const versionDirs = dirs.filter(dir => {
|
||
const dirPath = path.join(projectPath, dir);
|
||
return fs.stat(dirPath).then(stats => stats.isDirectory()).catch(() => false);
|
||
});
|
||
return versionDirs.sort();
|
||
}
|
||
|
||
/**
|
||
* 获取指定项目版本的 APK 文件列表
|
||
*/
|
||
export async function getApks(project: string, version: string, commitId?: string): Promise<{
|
||
name: string;
|
||
commit: string | null;
|
||
size: number;
|
||
modifiedAt: Date;
|
||
}[]> {
|
||
const apksPath = path.join(RESOURCE_PATH, project, version, 'apks');
|
||
|
||
try {
|
||
const files = await fs.readdir(apksPath);
|
||
const apkFiles = files.filter(file => file.endsWith('.apk'));
|
||
|
||
const apks = await Promise.all(
|
||
apkFiles.map(async (file) => {
|
||
const filePath = path.join(apksPath, file);
|
||
const stats = await fs.stat(filePath);
|
||
|
||
// 提取 commit id (假设文件名格式为 xxx-{commit}-xxx.apk)
|
||
const commitMatch = file.match(/([a-f0-9]{7,})/i);
|
||
const commit = commitMatch ? commitMatch[1] : null;
|
||
|
||
return {
|
||
name: file,
|
||
commit,
|
||
size: stats.size,
|
||
modifiedAt: stats.mtime,
|
||
};
|
||
})
|
||
);
|
||
|
||
// 如果指定了 commit id,进行过滤
|
||
if (commitId) {
|
||
return apks.filter(apk =>
|
||
apk.commit && apk.commit.toLowerCase().includes(commitId.toLowerCase())
|
||
);
|
||
}
|
||
|
||
return apks.sort((a, b) => b.modifiedAt.getTime() - a.modifiedAt.getTime());
|
||
} catch (error) {
|
||
// 如果 apks 目录不存在,返回空数组
|
||
return [];
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 格式化版本号显示 (0_42 -> 0.42)
|
||
*/
|
||
export function formatVersion(version: string): string {
|
||
return version.replace('_', '.');
|
||
}
|
||
|
||
/**
|
||
* 格式化文件大小
|
||
*/
|
||
export function formatFileSize(bytes: number): string {
|
||
if (bytes < 1024) return bytes + ' B';
|
||
if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(2) + ' KB';
|
||
if (bytes < 1024 * 1024 * 1024) return (bytes / (1024 * 1024)).toFixed(2) + ' MB';
|
||
return (bytes / (1024 * 1024 * 1024)).toFixed(2) + ' GB';
|
||
}
|
||
|
||
/**
|
||
* 格式化日期时间
|
||
*/
|
||
export function formatDateTime(date: Date): string {
|
||
const year = date.getFullYear();
|
||
const month = String(date.getMonth() + 1).padStart(2, '0');
|
||
const day = String(date.getDate()).padStart(2, '0');
|
||
const hours = String(date.getHours()).padStart(2, '0');
|
||
const minutes = String(date.getMinutes()).padStart(2, '0');
|
||
return `${year}-${month}-${day} ${hours}:${minutes}`;
|
||
}
|