Files
2026-05-23 14:05:22 +08:00

143 lines
4.7 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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();