Files

143 lines
4.7 KiB
JavaScript
Raw Permalink Normal View History

2026-05-23 14:05:22 +08:00
import { execFileSync } from 'node:child_process';
import fs from 'node:fs';
import { createRequire } from 'node:module';
import path from 'node:path';
import process from 'node:process';
import { fileURLToPath } from 'node:url';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const appRoot = path.resolve(__dirname, '..');
const repoRoot = path.resolve(appRoot, '../..');
const requireFromApp = createRequire(path.join(appRoot, 'package.json'));
const monacoDtsDir = path.join(appRoot, 'monaco.dts');
const cacheDir = path.join(monacoDtsDir, '.cache');
const legacyOutputFile = path.join(monacoDtsDir, 'index.d.ts');
const outputFile = path.join(
repoRoot,
'packages/form-designer/src/utils/user-script/context/monaco/index.d.ts',
);
const globalLsBlock = [
'declare global {',
' const ls: MonacoLsTypes.LsGlobal;',
'}',
].join('\n');
const banner = [
'// Auto-generated by `pnpm run monaco:dts:build`.',
'// Do not edit this file directly.',
'',
].join('\n');
function readJsonFile(filePath) {
return JSON.parse(fs.readFileSync(filePath, 'utf8'));
}
function findPackageRoot(packageName) {
let entryPath;
try {
entryPath = requireFromApp.resolve(packageName);
} catch (error) {
throw new Error(
`[monaco:dts:build] 无法解析依赖 ${packageName}。请先在仓库根目录执行 pnpm install`
+ `并确认 apps/lcdp/package.json 已声明该依赖。原始错误:${error.message}`,
);
}
let currentDir = path.dirname(entryPath);
while (currentDir !== path.dirname(currentDir)) {
const packageJsonPath = path.join(currentDir, 'package.json');
if (fs.existsSync(packageJsonPath)) {
const packageJson = readJsonFile(packageJsonPath);
if (packageJson.name === packageName) {
return { root: currentDir, packageJson };
}
}
currentDir = path.dirname(currentDir);
}
throw new Error(`[monaco:dts:build] 已解析 ${packageName},但无法找到对应 package.json。`);
}
function resolvePackageBin(packageName, binName) {
const { root, packageJson } = findPackageRoot(packageName);
const binConfig = packageJson.bin;
const binPath = typeof binConfig === 'string' ? binConfig : binConfig?.[binName];
if (!binPath) {
throw new Error(`[monaco:dts:build] ${packageName} 未声明 bin.${binName}`);
}
const resolvedBinPath = path.resolve(root, binPath);
if (!fs.existsSync(resolvedBinPath)) {
throw new Error(`[monaco:dts:build] ${packageName} 的 bin.${binName} 不存在:${resolvedBinPath}`);
}
return resolvedBinPath;
}
// 通过 package.json 的 bin 字段定位 CLI,避免写死深层子路径或依赖 Windows/macOS 不一致的 .bin shim。
const tscBin = resolvePackageBin('typescript', 'tsc');
const apiExtractorBin = resolvePackageBin('@microsoft/api-extractor', 'api-extractor');
function runNodeScript(scriptPath, args) {
execFileSync(process.execPath, [scriptPath, ...args], {
cwd: appRoot,
stdio: 'inherit',
env: {
...process.env,
},
});
}
function validateOutput() {
const content = fs.readFileSync(outputFile, 'utf8');
const hasImportLikeLine = content.split('\n').some((line) => {
const trimmed = line.trim();
return trimmed.startsWith('import ')
|| (trimmed.startsWith('export ') && trimmed.includes(' from '));
});
if (hasImportLikeLine) {
throw new Error('Generated Monaco d.ts still contains import/export-from statements.');
}
if (/\b(?:typeof\s+)?import\((['"]).+?\1\)/.test(content)) {
throw new Error('Generated Monaco d.ts still contains external import type references.');
}
if (!content.includes('const ls: MonacoLsTypes.LsGlobal;')) {
throw new Error('Generated Monaco d.ts is missing the global ls declaration.');
}
}
function ensureGlobalLs() {
const content = fs.readFileSync(outputFile, 'utf8');
if (!content.includes('declare global {')) {
const footer = 'export { }';
const body = content.trimEnd().endsWith(footer)
? content.trimEnd().slice(0, -footer.length).trimEnd()
: content.trimEnd();
fs.writeFileSync(outputFile, `${body}\n\n${globalLsBlock}\n\nexport { }\n`);
}
}
function addBanner() {
const content = fs.readFileSync(outputFile, 'utf8');
if (!content.startsWith('// Auto-generated')) {
fs.writeFileSync(outputFile, `${banner}${content}`);
}
}
function main() {
fs.rmSync(cacheDir, { recursive: true, force: true });
fs.rmSync(legacyOutputFile, { force: true });
fs.rmSync(outputFile, { force: true });
runNodeScript(tscBin, ['-p', 'monaco-types/tsconfig.json']);
runNodeScript(apiExtractorBin, ['run', '--local', '--config', 'api-extractor.monaco.json']);
ensureGlobalLs();
validateOutput();
addBanner();
fs.rmSync(cacheDir, { recursive: true, force: true });
}
main();