Last active
November 16, 2023 18:09
-
-
Save reosablo/c679a6cff340c5a6c007c2e6e697d7f6 to your computer and use it in GitHub Desktop.
esubild plugin for Typia
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // @ts-check | |
| /** | |
| * @file esbuild plugin for transforming TypeScript code using Typia | |
| * | |
| * CAUTION: this plugin will break the output source map. | |
| * | |
| * @example | |
| * ```js:build.mjs | |
| * import { build } from "esbuild"; | |
| * import typia from "./esbuild-plugin-typia.mjs"; | |
| * | |
| * await build({ | |
| * entryPoints: ["./src/main.ts"], | |
| * outfile: "./dist/main.js", | |
| * bundle: true, | |
| * format: "esm", | |
| * platform: "node", | |
| * // sourcemap: "inline", | |
| * plugins: [typia()], | |
| * }); | |
| * ``` | |
| */ | |
| import ts from "typescript"; | |
| import { transform } from "typia/lib/transform.js"; | |
| function getCompilerOptions() { | |
| const configPath = ts.findConfigFile("./", ts.sys.fileExists); | |
| if (configPath === undefined) { | |
| return undefined; | |
| } | |
| const { config } = ts.readConfigFile(configPath, ts.sys.readFile); | |
| const { options } = ts.parseJsonConfigFileContent(config, ts.sys, configPath); | |
| return options; | |
| } | |
| /** | |
| * same function exists in [TypiaProgrammer.ts](https://github.com/samchon/typia/blob/master/src/programmers/TypiaProgrammer.ts) | |
| * | |
| * @param {string} content | |
| */ | |
| function emend(content) { | |
| if ( | |
| content.indexOf("typia.") === -1 || | |
| content.indexOf("import typia") !== -1 || | |
| content.indexOf("import * as typia") !== -1 | |
| ) return content; | |
| return `import typia from "typia";\n\n${content}`; | |
| } | |
| /** | |
| * esbuild plugin for transforming TypeScript code using Typia | |
| * | |
| * CAUTION: this plugin will break the output source map. | |
| * | |
| * @param {object} [options] - An optional object containing plugin options. | |
| * @param {RegExp} [options.filter=/\.[cm]?ts$/] - A regular expression used to filter the files that should be transformed. | |
| * | |
| * @returns {import("esbuild").Plugin} | |
| */ | |
| export default function typia(options = {}) { | |
| /** @type {ts.CompilerOptions | undefined} */ | |
| let compilerOptions; | |
| /** @type {import("esbuild").OnLoadOptions} */ | |
| const onLoadOptions = { filter: options.filter ?? /\.[cm]?ts$/ }; | |
| return { | |
| name: "typia", | |
| setup(build) { | |
| build.onLoad(onLoadOptions, ({ path }) => { | |
| // similar process exists in TypiaProgrammer.ts | |
| // CREATE PROGRAM | |
| compilerOptions ??= getCompilerOptions() ?? {}; | |
| const typiaPlugin = /** @type {?*[]} */ (compilerOptions.plugins)?.find( | |
| (p) => p.transform === "typia/lib/transform", | |
| ); | |
| const program = ts.createProgram([path], compilerOptions); | |
| const sourceFile = program.getSourceFile(path); | |
| if (sourceFile === undefined) { | |
| throw new Error("source file not found"); | |
| } | |
| // DO TRANSFORM | |
| /** @type {ts.Diagnostic[]} */ | |
| const diagnostics = []; | |
| const typiaTransformer = transform(program, typiaPlugin, { | |
| addDiagnostic: (diag) => diagnostics.push(diag), | |
| }); | |
| const transformedFile = ts.transform(sourceFile, [typiaTransformer]) | |
| .transformed | |
| .find((file) => file.fileName === path); | |
| // TRACE ERRORS | |
| if (diagnostics.length > 0) { | |
| throw new Error(ts.formatDiagnostics(diagnostics, { | |
| getCanonicalFileName: (path) => path, | |
| getCurrentDirectory: ts.sys.getCurrentDirectory, | |
| getNewLine: () => ts.sys.newLine, | |
| })); | |
| } | |
| if (transformedFile === undefined) { | |
| throw new Error("transformed file not found"); | |
| } | |
| // EMIT TRANSFORMED FILE CONTENTS | |
| const printer = ts.createPrinter(); | |
| const code = printer.printFile(transformedFile); | |
| return { contents: emend(code), loader: "ts" }; | |
| }); | |
| }, | |
| }; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| { | |
| "private": true, | |
| "license": "CC0-1.0", | |
| "peerDependencies": { | |
| "esbuild": "*", | |
| "typescript": "*", | |
| "typia": ">=5" | |
| }, | |
| "devDependencies": { | |
| "esbuild": "^0.19.5", | |
| "typescript": "^5.2.2", | |
| "typia": "^5.2.6" | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment