2023-03-13 09:17:24 +08:00
|
|
|
import fs from "node:fs";
|
|
|
|
|
import path from "node:path";
|
|
|
|
|
import url from "node:url";
|
2023-03-23 15:18:10 +08:00
|
|
|
import { isValidIdentifier } from "@babel/types";
|
|
|
|
|
import { outdent } from "outdent";
|
2023-03-28 16:18:53 +08:00
|
|
|
import { PROJECT_ROOT, DIST_DIR, writeFile } from "../utils/index.js";
|
2023-03-13 09:17:24 +08:00
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-23 15:18:10 +08:00
|
|
|
function toPropertyKey(name) {
|
|
|
|
|
return isValidIdentifier(name) ? name : JSON.stringify(name);
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-13 09:17:24 +08:00
|
|
|
async function buildPluginTypes({ file: { input, output } }) {
|
2023-03-23 15:18:10 +08:00
|
|
|
const pluginModule = await import(
|
2023-03-13 09:17:24 +08:00
|
|
|
url.pathToFileURL(path.join(PROJECT_ROOT, input))
|
|
|
|
|
);
|
2023-03-23 15:18:10 +08:00
|
|
|
const plugin = pluginModule.default ?? pluginModule;
|
|
|
|
|
const parserNames = Object.keys(plugin.parsers ?? {});
|
2023-03-13 09:17:24 +08:00
|
|
|
|
2023-03-23 15:18:10 +08:00
|
|
|
// We only add `parsers` to types file, printers should not be used alone
|
2023-07-07 14:05:25 +08:00
|
|
|
// For `estree` plugin, we just export an empty object to ensure it treated as a module
|
2023-03-23 15:18:10 +08:00
|
|
|
const code =
|
|
|
|
|
parserNames.length === 0
|
2023-07-07 14:05:25 +08:00
|
|
|
? "export {};"
|
2023-03-23 15:18:10 +08:00
|
|
|
: outdent`
|
2023-03-13 09:17:24 +08:00
|
|
|
import { Parser } from "../index.js";
|
|
|
|
|
|
2023-03-13 12:34:56 +08:00
|
|
|
export declare const parsers: {
|
2023-03-23 15:18:10 +08:00
|
|
|
${parserNames
|
2023-03-13 09:17:24 +08:00
|
|
|
.map(
|
|
|
|
|
(parserName) =>
|
2023-03-23 15:18:10 +08:00
|
|
|
`${" ".repeat(2)}${toPropertyKey(parserName)}: Parser;`,
|
2023-03-13 09:17:24 +08:00
|
|
|
)
|
|
|
|
|
.join("\n")}
|
2023-07-07 14:05:25 +08:00
|
|
|
};
|
2023-03-23 15:18:10 +08:00
|
|
|
`;
|
|
|
|
|
|
2023-07-07 14:05:25 +08:00
|
|
|
await writeFile(path.join(DIST_DIR, output.file), `${code}\n`);
|
2023-03-13 09:17:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function buildTypes(options) {
|
|
|
|
|
return options.file.isPlugin
|
|
|
|
|
? buildPluginTypes(options)
|
|
|
|
|
: typesFileBuilder(options);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export default buildTypes;
|