SnowCat 雪猫底层全源码:NapCat 4.18.28 底座 + SnowLuma 能力移植 + V8 通道适配 9.9.37
26 包 monorepo(TS 全源码): - snowcat-core: NT 内核 API 封装 + listener(含 9.9.37 六回调适配)+ Packet 发包 - snowcat-onebot: OneBot v11 全动作 + MCP Streamable HTTP 适配器 + 稳定线 - snowcat-webui-frontend/backend: 雪猫控制台(React+HeroUI) - snowcat-shell: 单文件 bundle 出口(vite inlineDynamicImports) - snowcat-native: napi2native / MoeHoo / ffmpeg / pty 运行时 - 56 项 SnowLuma 独门动作移植(qzone 全家桶/群相册/装扮/闪照/收藏) - 工具件: 解包器/启动器/便携制作器/doctor GitHub 关联已全量指向 DandanLLab/SnowCatQQ
This commit is contained in:
commit
b9655a5ab1
1048 files changed
+130851
No files matched your search
@@ -0,0 +1,13 @@
|
||||
// 复制 cp README.md dist/ && cp package.public.json dist/package.json
|
||||
import { copyFile } from 'node:fs/promises';
|
||||
import { join } from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
const __dirname = fileURLToPath(new URL('../', import.meta.url));
|
||||
await copyFile(
|
||||
join(__dirname, 'package.public.json'),
|
||||
join(__dirname, 'dist', 'package.json')
|
||||
);
|
||||
await copyFile(
|
||||
join(__dirname, 'README.md'),
|
||||
join(__dirname, 'dist', 'README.md')
|
||||
);
|
||||
@@ -0,0 +1,118 @@
|
||||
import { readdir, readFile, writeFile, rename } from 'node:fs/promises';
|
||||
import { join } from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
|
||||
const __dirname = fileURLToPath(new URL('../', import.meta.url));
|
||||
const distDir = join(__dirname, 'dist');
|
||||
|
||||
// 允许保留的包(白名单)
|
||||
const ALLOWED_PACKAGES = [
|
||||
'@sinclair/typebox',
|
||||
'node:', // node: 前缀的内置模块
|
||||
];
|
||||
|
||||
function isAllowedImport (importPath) {
|
||||
return ALLOWED_PACKAGES.some(pkg => importPath.startsWith(pkg));
|
||||
}
|
||||
|
||||
function removeExternalImports (content) {
|
||||
const lines = content.split('\n');
|
||||
const resultLines = [];
|
||||
|
||||
for (const line of lines) {
|
||||
// 匹配 import 语句
|
||||
const importMatch = line.match(/^import\s+.*\s+from\s+['"]([^'"]+)['"]/);
|
||||
if (importMatch) {
|
||||
const importPath = importMatch[1];
|
||||
// 如果是相对路径或白名单包,保留
|
||||
if (importPath.startsWith('.') || importPath.startsWith('/') || isAllowedImport(importPath)) {
|
||||
resultLines.push(line);
|
||||
}
|
||||
// 否则移除该 import
|
||||
continue;
|
||||
}
|
||||
resultLines.push(line);
|
||||
}
|
||||
|
||||
return resultLines.join('\n');
|
||||
}
|
||||
|
||||
function replaceExternalTypes (content) {
|
||||
let result = content;
|
||||
|
||||
// 替换带泛型的类型(先处理复杂的)
|
||||
result = result.replace(/NapProtoDecodeStructType<[^>]+>/g, 'any');
|
||||
result = result.replace(/NapProtoEncodeStructType<[^>]+>/g, 'any');
|
||||
result = result.replace(/ValidateFunction<[^>]+>/g, 'any');
|
||||
|
||||
// 替换 winston.Logger 等带命名空间的类型
|
||||
result = result.replace(/winston\.Logger/g, 'any');
|
||||
result = result.replace(/winston\.transport/g, 'any');
|
||||
result = result.replace(/express\.Express/g, 'any');
|
||||
result = result.replace(/express\.Application/g, 'any');
|
||||
result = result.replace(/express\.Router/g, 'any');
|
||||
|
||||
// 替换独立的类型名(需要小心不要替换变量名)
|
||||
// 使用类型上下文的模式匹配
|
||||
const typeContextPatterns = [
|
||||
// : Type
|
||||
/:\s*(WebSocket|WebSocketServer|RawData|Container|NapProtoDecodeStructType|NapProtoEncodeStructType|Express|Request|Response|NextFunction)(?=\s*[;,)\]}|&]|$)/g,
|
||||
// <Type>
|
||||
/<(WebSocket|WebSocketServer|RawData|Container|NapProtoDecodeStructType|NapProtoEncodeStructType|Express|Request|Response|NextFunction)>/g,
|
||||
// Type[]
|
||||
/(WebSocket|WebSocketServer|RawData|Container|NapProtoDecodeStructType|NapProtoEncodeStructType|Express|Request|Response|NextFunction)\[\]/g,
|
||||
// extends Type
|
||||
/extends\s+(WebSocket|WebSocketServer|RawData|Container|NapProtoDecodeStructType|NapProtoEncodeStructType|Express|Request|Response|NextFunction)(?=\s*[{,])/g,
|
||||
// implements Type
|
||||
/implements\s+(WebSocket|WebSocketServer|RawData|Container|NapProtoDecodeStructType|NapProtoEncodeStructType|Express|Request|Response|NextFunction)(?=\s*[{,])/g,
|
||||
];
|
||||
|
||||
for (const pattern of typeContextPatterns) {
|
||||
result = result.replace(pattern, (match, typeName) => {
|
||||
return match.replace(typeName, 'any');
|
||||
});
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
async function traverseDirectory (dir) {
|
||||
const entries = await readdir(dir, { withFileTypes: true });
|
||||
|
||||
for (const entry of entries) {
|
||||
const fullPath = join(dir, entry.name);
|
||||
|
||||
if (entry.isDirectory()) {
|
||||
await traverseDirectory(fullPath);
|
||||
} else if (entry.isFile() && entry.name.endsWith('.d.ts')) {
|
||||
await processFile(fullPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function processFile (filePath) {
|
||||
// Read file content
|
||||
let content = await readFile(filePath, 'utf-8');
|
||||
|
||||
// 1. 移除外部包的 import
|
||||
content = removeExternalImports(content);
|
||||
|
||||
// 2. 替换外部类型为 any
|
||||
content = replaceExternalTypes(content);
|
||||
|
||||
// 3. Replace "export declare enum" with "export enum"
|
||||
content = content.replace(/export declare enum/g, 'export enum');
|
||||
|
||||
// Write back the modified content
|
||||
await writeFile(filePath, content, 'utf-8');
|
||||
|
||||
// Rename .d.ts to .ts
|
||||
const newPath = filePath.replace(/\.d\.ts$/, '.ts');
|
||||
await rename(filePath, newPath);
|
||||
|
||||
// console.log(`Processed: ${basename(filePath)} -> ${basename(newPath)}`);
|
||||
}
|
||||
|
||||
console.log('Starting post-build processing...');
|
||||
await traverseDirectory(distDir);
|
||||
console.log('Post-build processing completed!');
|
||||
Reference in new issue
Block a user