ts-oak-plugin/lib/index.js

129 lines
5.5 KiB
JavaScript

"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
const languageServiceProxy_1 = require("./languageServiceProxy");
const checker_1 = require("./core/checker");
const diagnosticConverter_1 = require("./diagnosticConverter");
const path = __importStar(require("path"));
function init(modules) {
const ts = modules.typescript;
function create(info) {
const logger = (msg) => info.project.projectService.logger.info(`[oak-tsc-plugin] ${msg}`);
logger('Plugin starting...');
// 读取配置
const config = info.config || {};
logger(`Config: ${JSON.stringify(config)}`);
// 检查是否禁用
if (process.env['OAK_TSC_PLUGIN_DISABLED']) {
logger('Plugin disabled by environment variable');
return info.languageService;
}
// 获取项目目录
const projectDir = path.dirname(info.project.getProjectName());
logger(`Project directory: ${projectDir}`);
// 创建检查器实例
let checker = null;
const getChecker = () => {
const program = info.languageService.getProgram();
if (!program) {
throw new Error('Program not available');
}
// 如果 program 变化,重新创建 checker
if (!checker || checker['program'] !== program) {
logger('Creating new checker instance');
checker = new checker_1.OakCustomChecker(projectDir, config, program, program.getTypeChecker(), ts);
}
return checker;
};
// 构建代理
const proxy = new languageServiceProxy_1.LanguageServiceProxyBuilder(info)
.wrap('getSemanticDiagnostics', (delegate) => {
return (fileName) => {
logger(`Getting diagnostics for ${fileName}`);
try {
// 获取原始诊断
const original = delegate(fileName);
// 执行自定义检查
const checker = getChecker();
const fileVersion = info.languageServiceHost.getScriptVersion(fileName);
const customDiagnostics = checker.checkFile(fileName, fileVersion);
// 转换并合并诊断
const tsDiagnostics = (0, diagnosticConverter_1.convertToTsDiagnostics)(customDiagnostics);
logger(`Found ${customDiagnostics.length} custom diagnostics`);
return [...original, ...tsDiagnostics];
}
catch (error) {
logger(`Error: ${error instanceof Error ? error.message : String(error)}`);
if (error instanceof Error && error.stack) {
logger(error.stack);
}
return delegate(fileName);
}
};
})
.wrap('getCodeFixesAtPosition', (delegate) => {
return (fileName, start, end, errorCodes, formatOptions, preferences) => {
const original = delegate(fileName, start, end, errorCodes, formatOptions, preferences);
// TODO: 为自定义诊断提供 code fixes
// 例如:自动添加 await、自动添加 @oak-ignore 注释等
return original;
};
})
.wrap('getSupportedCodeFixes', (delegate) => {
return (fileName) => {
const original = delegate(fileName);
// 添加自定义错误代码
return [...original, '9100', '9101', '9200', '9300'];
};
})
.build();
// 监听配置文件变化
const configFiles = ['.oakrc', 'oak.config.json'];
configFiles.forEach((configFile) => {
const configPath = path.resolve(projectDir, configFile);
info.serverHost.watchFile(configPath, () => {
logger(`Config file changed: ${configFile}`);
// 清除缓存
if (checker) {
checker.clearCache();
}
}, 50);
});
logger('Plugin initialized successfully');
return proxy;
}
return { create };
}
module.exports = init;
//# sourceMappingURL=index.js.map