mirror of
https://github.com/qaiu/netdisk-fast-download.git
synced 2025-12-17 12:53:02 +00:00
168 lines
5.5 KiB
JavaScript
168 lines
5.5 KiB
JavaScript
import * as ts from 'typescript';
|
||
|
||
/**
|
||
* TypeScript编译器工具类
|
||
* 用于在浏览器中将TypeScript代码编译为ES5 JavaScript
|
||
*/
|
||
|
||
/**
|
||
* 编译TypeScript代码为ES5 JavaScript
|
||
* @param {string} sourceCode - TypeScript源代码
|
||
* @param {string} fileName - 文件名(默认为script.ts)
|
||
* @returns {Object} 编译结果 { success: boolean, code: string, errors: Array }
|
||
*/
|
||
export function compileToES5(sourceCode, fileName = 'script.ts') {
|
||
try {
|
||
// 编译选项
|
||
const compilerOptions = {
|
||
target: ts.ScriptTarget.ES5, // 目标版本:ES5
|
||
module: ts.ModuleKind.None, // 不使用模块系统
|
||
lib: ['lib.es5.d.ts', 'lib.dom.d.ts'], // 包含ES5和DOM类型定义
|
||
removeComments: false, // 保留注释
|
||
noEmitOnError: false, // 即使有错误也生成代码
|
||
noImplicitAny: false, // 允许隐式any类型
|
||
strictNullChecks: false, // 不进行严格的null检查
|
||
suppressImplicitAnyIndexErrors: true, // 抑制隐式any索引错误
|
||
downlevelIteration: true, // 支持ES5迭代器降级
|
||
esModuleInterop: true, // 启用ES模块互操作性
|
||
allowJs: true, // 允许编译JavaScript文件
|
||
checkJs: false // 不检查JavaScript文件
|
||
};
|
||
|
||
// 执行编译
|
||
const result = ts.transpileModule(sourceCode, {
|
||
compilerOptions,
|
||
fileName,
|
||
reportDiagnostics: true
|
||
});
|
||
|
||
// 检查是否有诊断信息(错误/警告)
|
||
const diagnostics = result.diagnostics || [];
|
||
const errors = diagnostics.map(diagnostic => {
|
||
const message = ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n');
|
||
let location = '';
|
||
if (diagnostic.file && diagnostic.start !== undefined) {
|
||
const { line, character } = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start);
|
||
location = `(${line + 1},${character + 1})`;
|
||
}
|
||
return {
|
||
message,
|
||
location,
|
||
category: ts.DiagnosticCategory[diagnostic.category],
|
||
code: diagnostic.code
|
||
};
|
||
});
|
||
|
||
// 过滤出真正的错误(不包括警告)
|
||
const realErrors = errors.filter(e => e.category === 'Error');
|
||
|
||
return {
|
||
success: realErrors.length === 0,
|
||
code: result.outputText || '',
|
||
errors: errors,
|
||
hasWarnings: errors.some(e => e.category === 'Warning'),
|
||
sourceMap: result.sourceMapText
|
||
};
|
||
} catch (error) {
|
||
return {
|
||
success: false,
|
||
code: '',
|
||
errors: [{
|
||
message: error.message || '编译失败',
|
||
location: '',
|
||
category: 'Error',
|
||
code: 0
|
||
}]
|
||
};
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 检查代码是否为TypeScript代码
|
||
* 简单的启发式检查,看是否包含TypeScript特有的语法
|
||
* @param {string} code - 代码字符串
|
||
* @returns {boolean} 是否为TypeScript代码
|
||
*/
|
||
export function isTypeScriptCode(code) {
|
||
if (!code || typeof code !== 'string') {
|
||
return false;
|
||
}
|
||
|
||
// TypeScript特有的语法模式
|
||
const tsPatterns = [
|
||
/:\s*(string|number|boolean|any|void|never|unknown|object)\b/, // 类型注解
|
||
/interface\s+\w+/, // interface声明
|
||
/type\s+\w+\s*=/, // type别名
|
||
/enum\s+\w+/, // enum声明
|
||
/<\w+>/, // 泛型
|
||
/implements\s+\w+/, // implements关键字
|
||
/as\s+(string|number|boolean|any|const)/, // as类型断言
|
||
/public|private|protected|readonly/, // 访问修饰符
|
||
/:\s*\w+\[\]/, // 数组类型注解
|
||
/\?\s*:/ // 可选属性
|
||
];
|
||
|
||
// 如果匹配任何TypeScript特有模式,则认为是TypeScript代码
|
||
return tsPatterns.some(pattern => pattern.test(code));
|
||
}
|
||
|
||
/**
|
||
* 格式化编译错误信息
|
||
* @param {Array} errors - 错误数组
|
||
* @returns {string} 格式化后的错误信息
|
||
*/
|
||
export function formatCompileErrors(errors) {
|
||
if (!errors || errors.length === 0) {
|
||
return '';
|
||
}
|
||
|
||
return errors.map((error, index) => {
|
||
const prefix = `[${error.category}]`;
|
||
const location = error.location ? ` ${error.location}` : '';
|
||
const code = error.code ? ` (TS${error.code})` : '';
|
||
return `${index + 1}. ${prefix}${location}${code}: ${error.message}`;
|
||
}).join('\n');
|
||
}
|
||
|
||
/**
|
||
* 验证编译后的代码是否为有效的ES5
|
||
* @param {string} code - 编译后的代码
|
||
* @returns {Object} { valid: boolean, error: string }
|
||
*/
|
||
export function validateES5Code(code) {
|
||
try {
|
||
// 尝试使用Function构造函数验证语法
|
||
// eslint-disable-next-line no-new-func
|
||
new Function(code);
|
||
return { valid: true, error: null };
|
||
} catch (error) {
|
||
return { valid: false, error: error.message };
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 提取代码中的元数据注释
|
||
* @param {string} code - 代码字符串
|
||
* @returns {Object} 元数据对象
|
||
*/
|
||
export function extractMetadata(code) {
|
||
const metadata = {};
|
||
const metaRegex = /\/\/\s*@(\w+)\s+(.+)/g;
|
||
let match;
|
||
|
||
while ((match = metaRegex.exec(code)) !== null) {
|
||
const [, key, value] = match;
|
||
metadata[key] = value.trim();
|
||
}
|
||
|
||
return metadata;
|
||
}
|
||
|
||
export default {
|
||
compileToES5,
|
||
isTypeScriptCode,
|
||
formatCompileErrors,
|
||
validateES5Code,
|
||
extractMetadata
|
||
};
|