Keep type definition for flow-estree up to date (#19969)

This commit is contained in:
fisker Cheung authored and GitHub committed 2026-09-02 16:23:09 +08:00
1 parent d4126e8c97
commit f78e8a64fa
4 files changed
+936 -901

No files matched your search

+8 -13
View File
@@ -2,8 +2,9 @@ const fs = require("node:fs");
const path = require("node:path"); const path = require("node:path");
const root = path.join(__dirname, "../../"); const root = path.join(__dirname, "../../");
const NODE_JS_MAJOR_VERSION = Number(process.versions.node.split(".", 1)[0]);
function setupVscode() { async function setupVscode() {
const vscodeDirectory = path.join(root, ".vscode/"); const vscodeDirectory = path.join(root, ".vscode/");
const settingsFile = path.join(vscodeDirectory, "settings.json"); const settingsFile = path.join(vscodeDirectory, "settings.json");
const settingsExampleFile = path.join( const settingsExampleFile = path.join(
@@ -15,14 +16,7 @@ function setupVscode() {
return; return;
} }
fs.copyFileSync(settingsExampleFile, settingsFile); await fs.promises.copyFile(settingsExampleFile, settingsFile);
}
async function buildBabelCodeFrameForTest() {
const { buildBabelCodeFrameForTest } =
await import("../../scripts/build-babel-code-frame-for-test.js");
await buildBabelCodeFrameForTest();
} }
module.exports = { module.exports = {
@@ -45,10 +39,11 @@ module.exports = {
return; return;
} }
setupVscode(); await Promise[NODE_JS_MAJOR_VERSION < 20 ? "allSettled" : "all"]([
try { setupVscode(),
await buildBabelCodeFrameForTest(); import("../../scripts/build-babel-code-frame-for-test.js"),
} catch {} import("../../scripts/generate-flow-estree-type-definition.js"),
]);
}, },
}, },
}), }),
+3 -1
View File
@@ -1,3 +1,5 @@
#!/usr/bin/env node
import url from "node:url"; import url from "node:url";
import esbuild from "esbuild"; import esbuild from "esbuild";
import { import {
@@ -21,4 +23,4 @@ async function buildBabelCodeFrameForTest() {
}); });
} }
export { buildBabelCodeFrameForTest }; await buildBabelCodeFrameForTest();
+68 -42
View File
@@ -1,9 +1,12 @@
#!/usr/bin/env node
import fs from "node:fs/promises"; import fs from "node:fs/promises";
import url from "node:url"; import url from "node:url";
import { codeFrameColumns } from "@babel/code-frame"; import { codeFrameColumns } from "@babel/code-frame";
import * as ts from "typescript"; import * as ts from "typescript";
import * as prettier from "../node_modules/prettier/index.mjs"; import * as prettier from "../node_modules/prettier/index.mjs";
const buildScriptVersion = "1";
const PROJECT_ROOT = new URL("../", import.meta.url); const PROJECT_ROOT = new URL("../", import.meta.url);
const FLOW_TYPES = new URL( const FLOW_TYPES = new URL(
"./node_modules/flow-estree/dist/types.js.flow", "./node_modules/flow-estree/dist/types.js.flow",
@@ -13,68 +16,89 @@ const FLOW_TYPES_DTS = new URL(
"./src/language-js/types/flow-estree.d.ts", "./src/language-js/types/flow-estree.d.ts",
PROJECT_ROOT, PROJECT_ROOT,
); );
const IS_CI = Boolean(process.env.CI);
let text = await fs.readFile(FLOW_TYPES, "utf8"); async function generateFlowEstreeTypeDefinition() {
text = toDts(text); const {
default: { version },
} = await import("flow-estree/package.json", {
with: { type: "json" },
});
const versionComment = `// flow-estree:v${version}, build-script:v${buildScriptVersion}`;
const getRelativePath = (url) => if (!IS_CI) {
new URL(url).href.slice(PROJECT_ROOT.href.length); try {
text = ` const dtsText = await fs.readFile(FLOW_TYPES_DTS, "utf8");
if (dtsText.includes(versionComment + "\n")) {
return;
}
} catch {
// No op
}
}
let text = await fs.readFile(FLOW_TYPES, "utf8");
text = toDts(text);
const getRelativePath = (url) =>
new URL(url).href.slice(PROJECT_ROOT.href.length);
text = `
// ! Do NOT edit ! // ! Do NOT edit !
// Generated from '${getRelativePath(FLOW_TYPES)}' // Generated from '${getRelativePath(FLOW_TYPES)}'
// Run \`node ${getRelativePath(import.meta.url)}\` to update // Run \`node ${getRelativePath(import.meta.url)}\` to update
${versionComment}
// spell-checker: disable // spell-checker: disable
${text} ${text}
`; `;
text = await prettier.format(text, { text = await prettier.format(text, {
// Bug? should accept URL // Bug? should accept URL
filepath: "flow-estree.d.ts", filepath: "flow-estree.d.ts",
parser: "typescript", parser: "typescript",
}); });
await fs.writeFile(FLOW_TYPES_DTS, text); await fs.writeFile(FLOW_TYPES_DTS, text);
const program = ts.createProgram([url.fileURLToPath(FLOW_TYPES_DTS)], { const program = ts.createProgram([url.fileURLToPath(FLOW_TYPES_DTS)], {
strict: true, strict: true,
}); });
const diagnostics = ts.getPreEmitDiagnostics(program); const diagnostics = ts.getPreEmitDiagnostics(program);
if (diagnostics.length > 0) { if (diagnostics.length > 0) {
await fs.rm(FLOW_TYPES_DTS); await fs.rm(FLOW_TYPES_DTS);
const [diagnostic] = diagnostics; const [diagnostic] = diagnostics;
const { line, character: column } = ts.getLineAndCharacterOfPosition( const { line, character: column } = ts.getLineAndCharacterOfPosition(
diagnostic.file, diagnostic.file,
diagnostic.start, diagnostic.start,
); );
throw new Error( throw new Error(
diagnostic.messageText + diagnostic.messageText +
":\n" + ":\n" +
codeFrameColumns( codeFrameColumns(
text, text,
{ start: { line: line + 1, column } }, { start: { line: line + 1, column } },
{ {
message: `TS${diagnostic.code}: ${diagnostic.messageText}`, message: `TS${diagnostic.code}: ${diagnostic.messageText}`,
}, },
), ),
); );
}
} }
function toDts(text) { function toDts(text) {
// Useless directive // Useless directive
text = text.replaceAll("'use strict';", ""); text = text.replaceAll("'use strict';", "");
// `{+foo: string}` -> `{foo: string}`
text = text.replaceAll(/(?<=\n)(?<indention>[ {2}]+)\+/g, "$<indention>");
// `{foo: interface {}}` -> `{foo: {}}` // `{foo: interface {}}` -> `{foo: {}}`
text = text.replaceAll(": interface {", ": {");
// `{foo: interface extends T {}}` -> `{foo: T & {}}` // `{foo: interface extends T {}}` -> `{foo: T & {}}`
text = text.replaceAll( text = text.replaceAll(
/(?<=: )interface extends (?<type>\w+)(?= \{)/g, /(?<=: )interface(?: extends (?<type>\w+))?(?= \{)/g,
"$<type> & ", (...args) => {
const { type } = args.at(-1);
return type ? `${type} & ` : "";
},
); );
// `ReadonlyArray<?T>` -> `ReadonlyArray<T | null>` // `ReadonlyArray<?T>` -> `ReadonlyArray<T | null>`
@@ -85,9 +109,11 @@ function toDts(text) {
// `{[string]: T}` -> `{[key: string]: T}` // `{[string]: T}` -> `{[key: string]: T}`
text = text.replaceAll( text = text.replaceAll(
/(?<=\n)(?<indention>[ {2}]+)\[(?<type>string)\](?=: )/g, /(?<=\n[ {2}]+\[)(?<type>string)(?=\]: )/g,
"$<indention>[key: $<type>]", "key: $<type>",
); );
return text; return text;
} }
await generateFlowEstreeTypeDefinition();
+857 -845
View File
File diff suppressed because it is too large. Load diff