Build: Auto generate types files for plugins (#14462)

This commit is contained in:
fisker Cheung authored and GitHub committed 2023-03-13 09:17:24 +08:00
1 parent a07927aa11
commit 18baca62c9
20 files changed
+125 -216

No files matched your search

+63
View File
@@ -0,0 +1,63 @@
import fs from "node:fs";
import path from "node:path";
import url from "node:url";
import { PROJECT_ROOT, DIST_DIR, writeFile } from "../utils/index.mjs";
import { format } from "../../index.js";
async function typesFileBuilder({ file }) {
/**
* @typedef {{ from: string, to: string }} ImportPathReplacement
* @typedef {{ [input: string]: Array<ImportPathReplacement> }} ReplacementMap
*/
/** @type {ReplacementMap} */
const pathReplacementMap = {
"src/index.d.ts": [{ from: "./document/public.js", to: "./doc.js" }],
};
const replacements = pathReplacementMap[file.input] ?? [];
let text = await fs.promises.readFile(file.input, "utf8");
for (const { from, to } of replacements) {
text = text.replaceAll(
new RegExp(` from "${from}";`, "g"),
` from "${to}";`
);
}
await writeFile(path.join(DIST_DIR, file.output.file), text);
}
async function buildPluginTypes({ file: { input, output } }) {
const { default: plugin } = await import(
url.pathToFileURL(path.join(PROJECT_ROOT, input))
);
await writeFile(
path.join(DIST_DIR, output.file),
await format(
/* indent */ `
import { Parser } from "../index.js";
declare const plugin: {
parsers: {
${Object.keys(plugin.parsers)
.map(
(parserName) =>
`${" ".repeat(4)}${JSON.stringify(parserName)}: Parser;`
)
.join("\n")}
};
};
export default plugin;
`,
{ parser: "typescript" }
)
);
}
function buildTypes(options) {
return options.file.isPlugin
? buildPluginTypes(options)
: typesFileBuilder(options);
}
export default buildTypes;
+12 -42
View File
@@ -3,15 +3,11 @@ import url from "node:url";
import fs from "node:fs";
import { createRequire } from "node:module";
import createEsmUtils from "esm-utils";
import {
PROJECT_ROOT,
DIST_DIR,
copyFile,
writeFile,
} from "../utils/index.mjs";
import { PROJECT_ROOT, DIST_DIR, copyFile } from "../utils/index.mjs";
import buildJavascriptModule from "./build-javascript-module.js";
import buildPackageJson from "./build-package-json.js";
import buildLicense from "./build-license.js";
import buildTypes from "./build-types.js";
import modifyTypescriptModule from "./modify-typescript-module.mjs";
import { getPackageFile } from "./utils.js";
@@ -28,41 +24,14 @@ const copyFileBuilder = ({ file }) =>
path.join(DIST_DIR, file.output.file)
);
async function typesFileBuilder({ file }) {
/**
* @typedef {{ from: string, to: string }} ImportPathReplacement
* @typedef {{ [input: string]: Array<ImportPathReplacement> }} ReplacementMap
*/
function getTypesFileConfig({ input: jsFileInput, outputBaseName, isPlugin }) {
let input = jsFileInput;
if (!isPlugin) {
input = jsFileInput.replace(/\.[cm]?js$/, ".d.ts");
/** @type {Array<ImportPathReplacement>} */
const jsParsersImportReplacement = [
{ from: "../../index.js", to: "../index.js" },
];
/** @type {ReplacementMap} */
const pathReplacementMap = {
"src/index.d.ts": [{ from: "./document/public.js", to: "./doc.js" }],
"src/language-js/parse/acorn-and-espree.d.ts": jsParsersImportReplacement,
"src/language-js/parse/angular.d.ts": jsParsersImportReplacement,
"src/language-js/parse/babel.d.ts": jsParsersImportReplacement,
"src/language-js/parse/flow.d.ts": jsParsersImportReplacement,
"src/language-js/parse/meriyah.d.ts": jsParsersImportReplacement,
"src/language-js/parse/typescript.d.ts": jsParsersImportReplacement,
};
const replacements = pathReplacementMap[file.input] ?? [];
let data = await fs.promises.readFile(file.input, "utf8");
for (const { from, to } of replacements) {
data = data.replaceAll(
new RegExp(` from "${from}";`, "g"),
` from "${to}";`
);
}
await writeFile(path.join(DIST_DIR, file.output.file), data);
}
function getTypesFileConfig({ input: jsFileInput, outputBaseName }) {
const input = jsFileInput.replace(/\.[cm]?js$/, ".d.ts");
if (!fs.existsSync(path.join(PROJECT_ROOT, input))) {
return;
if (!fs.existsSync(path.join(PROJECT_ROOT, input))) {
return;
}
}
return {
@@ -71,7 +40,8 @@ function getTypesFileConfig({ input: jsFileInput, outputBaseName }) {
file: outputBaseName + ".d.ts",
},
kind: "types",
build: typesFileBuilder,
isPlugin,
build: buildTypes,
};
}
@@ -464,7 +434,7 @@ const universalFiles = [...nonPluginUniversalFiles, ...pluginFiles].flatMap(
build: buildJavascriptModule,
kind: "javascript",
})),
getTypesFileConfig({ input, outputBaseName }),
getTypesFileConfig({ input, outputBaseName, isPlugin }),
];
}
);
-11
View File
@@ -1,11 +0,0 @@
import { Parser } from "../index.js";
declare const plugin: {
parsers: {
css: Parser;
less: Parser;
scss: Parser;
};
};
export default plugin;
-9
View File
@@ -1,9 +0,0 @@
import { Parser } from "../index.js";
declare const plugin: {
parsers: {
graphql: Parser;
};
};
export default plugin;
-9
View File
@@ -1,9 +0,0 @@
import { Parser } from "../index.js";
declare const plugin: {
parsers: {
glimmer: Parser;
};
};
export default plugin;
-12
View File
@@ -1,12 +0,0 @@
import { Parser } from "../index.js";
declare const plugin: {
parsers: {
html: Parser;
angular: Parser;
vue: Parser;
lwc: Parser;
};
};
export default plugin;
-10
View File
@@ -1,10 +0,0 @@
import { Parser } from "../../index.js";
declare const plugin: {
parsers: {
acorn: Parser;
espree: Parser;
};
};
export default plugin;
-12
View File
@@ -1,12 +0,0 @@
import { Parser } from "../../index.js";
declare const plugin: {
parsers: {
__ng_action: Parser;
__ng_binding: Parser;
__ng_interpolation: Parser;
__ng_directive: Parser;
};
};
export default plugin;
-17
View File
@@ -1,17 +0,0 @@
import { Parser } from "../../index.js";
declare const plugin: {
parsers: {
babel: Parser;
"babel-flow": Parser;
"babel-ts": Parser;
json: Parser;
json5: Parser;
"json-stringify": Parser;
__js_expression: Parser;
__vue_expression: Parser;
__vue_event_binding: Parser;
};
};
export default plugin;
-9
View File
@@ -1,9 +0,0 @@
import { Parser } from "../../index.js";
declare const plugin: {
parsers: {
flow: Parser;
};
};
export default plugin;
-9
View File
@@ -1,9 +0,0 @@
import { Parser } from "../../index.js";
declare const plugin: {
parsers: {
meriyah: Parser;
};
};
export default plugin;
-9
View File
@@ -1,9 +0,0 @@
import { Parser } from "../../index.js";
declare const plugin: {
parsers: {
typescript: Parser;
};
};
export default plugin;
-11
View File
@@ -1,11 +0,0 @@
import { Parser } from "../index.js";
declare const plugin: {
parsers: {
remark: Parser;
markdown: Parser;
mdx: Parser;
};
};
export default plugin;
-9
View File
@@ -1,9 +0,0 @@
import { Parser } from "../index.js";
declare const plugin: {
parsers: {
yaml: Parser;
};
};
export default plugin;
+1 -1
View File
@@ -1,4 +1,4 @@
import * as prettier from "../../../../src/index";
import * as prettier from "../../../../src/index.js";
prettier.format("foo ( );", { semi: false });
prettier.check("foo ( );", { semi: false });
+43 -43
View File
@@ -1,50 +1,50 @@
import * as prettier from "../../../../src/index";
import * as prettier from "../../../../dist/index.js";
import acornEspreeParser from "../../../../src/language-js/parse/acorn-and-espree";
import angularParser from "../../../../src/language-js/parse/angular";
import babelParser from "../../../../src/language-js/parse/babel";
import flowParser from "../../../../src/language-js/parse/flow";
import glimmerParser from "../../../../src/language-handlebars/parser-glimmer";
import graphqlParser from "../../../../src/language-graphql/parser-graphql";
import htmlParser from "../../../../src/language-html/parser-html";
import markdownParser from "../../../../src/language-markdown/parser-markdown";
import meriyahParser from "../../../../src/language-js/parse/meriyah";
import postcssParser from "../../../../src/language-css/parser-postcss";
import typescriptParser from "../../../../src/language-js/parse/typescript";
import yamlParser from "../../../../src/language-yaml/parser-yaml";
import acornEspreePlugin from "../../../../dist/plugins/acorn-and-espree.js";
import angularPlugin from "../../../../dist/plugins/angular.js";
import babelPlugin from "../../../../dist/plugins/babel.js";
import flowPlugin from "../../../../dist/plugins/flow.js";
import glimmerPlugin from "../../../../dist/plugins/glimmer.js";
import graphqlPlugin from "../../../../dist/plugins/graphql.js";
import htmlPlugin from "../../../../dist/plugins/html.js";
import markdownPlugin from "../../../../dist/plugins/markdown.js";
import typescriptPlugin from "../../../../dist/plugins/typescript.js";
import meriyahPlugin from "../../../../dist/plugins/meriyah.js";
import postcssPlugin from "../../../../dist/plugins/postcss.js";
import yamlPlugin from "../../../../dist/plugins/yaml.js";
acornEspreeParser.parsers.acorn.parse;
acornEspreeParser.parsers.espree.parse;
angularParser.parsers.__ng_action.parse;
babelParser.parsers.babel.parse;
flowParser.parsers.flow.parse;
glimmerParser.parsers.glimmer.parse;
graphqlParser.parsers.graphql.parse;
htmlParser.parsers.html.parse;
htmlParser.parsers.vue.parse;
htmlParser.parsers.lwc.parse;
htmlParser.parsers.angular.parse;
markdownParser.parsers.markdown.parse;
markdownParser.parsers.mdx.parse;
meriyahParser.parsers.meriyah.parse;
postcssParser.parsers.css.parse;
postcssParser.parsers.less.parse;
postcssParser.parsers.scss.parse;
typescriptParser.parsers.typescript.parse;
yamlParser.parsers.yaml.parse;
acornEspreePlugin.parsers.acorn.parse;
acornEspreePlugin.parsers.espree.parse;
angularPlugin.parsers.__ng_action.parse;
babelPlugin.parsers.babel.parse;
flowPlugin.parsers.flow.parse;
glimmerPlugin.parsers.glimmer.parse;
graphqlPlugin.parsers.graphql.parse;
htmlPlugin.parsers.html.parse;
htmlPlugin.parsers.vue.parse;
htmlPlugin.parsers.lwc.parse;
htmlPlugin.parsers.angular.parse;
markdownPlugin.parsers.markdown.parse;
markdownPlugin.parsers.mdx.parse;
typescriptPlugin.parsers.typescript.parse;
meriyahPlugin.parsers.meriyah.parse;
postcssPlugin.parsers.css.parse;
postcssPlugin.parsers.less.parse;
postcssPlugin.parsers.scss.parse;
yamlPlugin.parsers.yaml.parse;
prettier.format("hello world", {
plugins: [
acornEspreeParser,
angularParser,
babelParser,
flowParser,
glimmerParser,
htmlParser,
markdownParser,
meriyahParser,
postcssParser,
typescriptParser,
yamlParser,
acornEspreePlugin,
angularPlugin,
babelPlugin,
flowPlugin,
glimmerPlugin,
htmlPlugin,
markdownPlugin,
meriyahPlugin,
postcssPlugin,
typescriptPlugin,
yamlPlugin,
],
});
+1 -1
View File
@@ -1,4 +1,4 @@
import * as prettier from "../../../../src/index";
import * as prettier from "../../../../src/index.js";
import { expectType } from "ts-expect";
interface PluginAST {
+1 -1
View File
@@ -1,4 +1,4 @@
import * as prettier from "../../../../src/index";
import * as prettier from "../../../../src/index.js";
import { expectType } from "ts-expect";
type NestedAst = Nested1 | Nested2 | Nested3;
+1 -1
View File
@@ -1,4 +1,4 @@
import * as prettierStandalone from "../../../../src/standalone";
import * as prettierStandalone from "../../../../src/standalone.js";
prettierStandalone.formatWithCursor(" 1", { cursorOffset: 2, parser: "babel" });
prettierStandalone.formatWithCursor(" 1", {
+3
View File
@@ -3,6 +3,8 @@ import path from "node:path";
import url from "node:url";
import { default as ts } from "typescript";
const isProduction = process.env.NODE_ENV === "production";
describe("Unit tests for dts files", () => {
test("no errors", () => {
const testCasesDirPath = url.fileURLToPath(
@@ -10,6 +12,7 @@ describe("Unit tests for dts files", () => {
);
const testCaseFiles = fs
.readdirSync(testCasesDirPath)
.filter((file) => (isProduction ? true : file !== "parsers.ts"))
.map((file) => path.join(testCasesDirPath, file));
/** @type {import("typescript").CompilerOptions} */