"feat: 同步功能增强与配置优化,支持多类型同步及日志分级"

This commit is contained in:
2025-05-12 23:53:45 +08:00
parent eaccbf5ada
commit 785bd7b004
13 changed files with 278 additions and 35 deletions

View File

@@ -1,7 +1,9 @@
import path from 'node:path';
import fs from 'node:fs';
import { Config, SyncList } from './type.ts';
import { Config, SyncList, SyncConfigType, SyncConfig } from './type.ts';
import { fileIsExist } from '@/uitls/file.ts';
import { getHash } from '@/uitls/hash.ts';
import glob from 'fast-glob';
export type SyncOptions = {
dir?: string;
@@ -28,6 +30,15 @@ export class SyncBase {
const filepath = path.join(dir, filename);
if (!fileIsExist(filepath)) throw new Error('config file not found');
const config = JSON.parse(fs.readFileSync(filepath, 'utf-8'));
const sync = config.sync || {};
const keys = Object.keys(sync);
const newConfigSync: any = {};
for (let key of keys) {
const keyPath = path.join(dir, key);
const newKey = path.relative(dir, keyPath);
newConfigSync[newKey] = sync[key];
}
config.sync = newConfigSync;
this.config = config;
return config;
} catch (err) {
@@ -35,10 +46,15 @@ export class SyncBase {
return {} as Config;
}
}
async getSyncList(): Promise<SyncList[]> {
async canDone(syncType: SyncConfigType, type?: SyncConfigType) {
if (syncType === 'sync') return true;
return syncType === type;
}
async getSyncList(opts?: { getFile?: boolean }): Promise<SyncList[]> {
const config = this.config!;
const sync = config?.sync || {};
let sync = config?.sync || {};
const syncDirectory = await this.getSyncDirectoryList();
sync = this.getMergeSync(sync, syncDirectory.sync);
const syncKeys = Object.keys(sync);
const baseURL = this.baseURL;
const syncList = syncKeys.map((key) => {
@@ -52,21 +68,92 @@ export class SyncBase {
return false;
};
if (typeof value === 'string') {
const auth = checkAuth(value, baseURL);
const type = auth ? 'sync' : 'none';
return {
key,
type: type as any,
filepath,
url: value,
auth: checkAuth(value, baseURL),
auth,
};
}
const auth = checkAuth(value.url, baseURL);
const type = auth ? 'sync' : 'none';
return {
key,
filepath,
...value,
type: value?.type ?? type,
auth: checkAuth(value.url, baseURL),
};
});
if (opts?.getFile) {
return this.getSyncListFile(syncList);
}
return syncList;
}
getMergeSync(sync: Config['sync'] = {}, fileSync: Config['sync'] = {}) {
const syncFileSyncKeys = Object.keys(fileSync);
const syncKeys = Object.keys(sync);
const keys = [...syncKeys, ...syncFileSyncKeys];
const obj: Config['sync'] = {};
for (let key of keys) {
const value = sync[key] ?? fileSync[key];
obj[key] = value;
}
return obj;
}
async getSyncDirectoryList() {
const config = this.config;
const syncDirectory = config?.syncDirectory || [];
let obj: Record<string, string> = {};
const keys: string[] = [];
for (let item of syncDirectory) {
const { registry, ignore = [], files, replace = {} } = item;
const cwd = this.#dir;
const glob_files = await glob(files, {
ignore,
onlyFiles: true,
cwd,
dot: true,
absolute: true,
});
for (let file of glob_files) {
const key = path.relative(cwd, file);
const _registryURL = new URL(registry);
const replaceKeys = Object.keys(replace);
let newKey = key;
for (let replaceKey of replaceKeys) {
if (newKey.startsWith(replaceKey)) {
newKey = key.replace(replaceKey, replace[replaceKey]);
}
}
const pathname = path.join(_registryURL.pathname, newKey);
_registryURL.pathname = pathname;
keys.push(key);
obj[key] = _registryURL.toString();
}
}
return { sync: obj, keys };
}
async getSyncListFile(syncList: SyncList[]) {
let syncListFile: SyncList[] = [];
for (let item of syncList) {
const { filepath, auth } = item;
if (filepath && fileIsExist(filepath) && auth) {
syncListFile.push({
...item,
exist: true,
hash: getHash(filepath),
});
} else {
syncListFile.push({ ...item, exist: false });
}
}
return syncListFile;
}
getHash = getHash;
async getDir(filepath: string, check = false) {
const dir = path.dirname(filepath);
if (check) {