const esbuild = require("esbuild") const fs = require("fs") const path = require("path") const production = process.argv.includes("--production") const watch = process.argv.includes("--watch") /** * @type {import('esbuild').Plugin} */ const aliasResolverPlugin = { name: "alias-resolver", setup(build) { const aliases = { "@": path.resolve(__dirname, "src"), "@api": path.resolve(__dirname, "src/api"), "@core": path.resolve(__dirname, "src/core"), "@integrations": path.resolve(__dirname, "src/integrations"), "@services": path.resolve(__dirname, "src/services"), "@shared": path.resolve(__dirname, "src/shared"), "@utils": path.resolve(__dirname, "src/utils"), "@packages": path.resolve(__dirname, "src/packages"), } // For each alias entry, create a resolver Object.entries(aliases).forEach(([alias, aliasPath]) => { const aliasRegex = new RegExp(`^${alias}($|/.*)`) build.onResolve({ filter: aliasRegex }, (args) => { const importPath = args.path.replace(alias, aliasPath) // First, check if the path exists as is if (fs.existsSync(importPath)) { const stats = fs.statSync(importPath) if (stats.isDirectory()) { // If it's a directory, try to find index files const extensions = [".ts", ".tsx", ".js", ".jsx"] for (const ext of extensions) { const indexFile = path.join(importPath, `index${ext}`) if (fs.existsSync(indexFile)) { return { path: indexFile } } } } else { // It's a file that exists, so return it return { path: importPath } } } // If the path doesn't exist, try appending extensions const extensions = [".ts", ".tsx", ".js", ".jsx"] for (const ext of extensions) { const pathWithExtension = `${importPath}${ext}` if (fs.existsSync(pathWithExtension)) { return { path: pathWithExtension } } } // If nothing worked, return the original path and let esbuild handle the error return { path: importPath } }) }) }, } const esbuildProblemMatcherPlugin = { name: "esbuild-problem-matcher", setup(build) { build.onStart(() => { console.log("[watch] build started") }) build.onEnd((result) => { result.errors.forEach(({ text, location }) => { console.error(`✘ [ERROR] ${text}`) console.error(` ${location.file}:${location.line}:${location.column}:`) }) console.log("[watch] build finished") }) }, } const copyWasmFiles = { name: "copy-wasm-files", setup(build) { build.onEnd(() => { // tree sitter const sourceDir = path.join(__dirname, "node_modules", "web-tree-sitter") const targetDir = path.join(__dirname, "dist") // Copy tree-sitter.wasm fs.copyFileSync(path.join(sourceDir, "tree-sitter.wasm"), path.join(targetDir, "tree-sitter.wasm")) // Copy language-specific WASM files const languageWasmDir = path.join(__dirname, "node_modules", "tree-sitter-wasms", "out") const languages = [ "typescript", "tsx", "python", "rust", "javascript", "go", "cpp", "c", "c_sharp", "ruby", "java", "php", "swift", "kotlin", ] languages.forEach((lang) => { const filename = `tree-sitter-${lang}.wasm` fs.copyFileSync(path.join(languageWasmDir, filename), path.join(targetDir, filename)) }) }) }, } const extensionConfig = { bundle: true, minify: production, sourcemap: !production, logLevel: "silent", define: { "process.env.IS_DEV": JSON.stringify(!production), }, tsconfig: path.resolve(__dirname, "tsconfig.json"), plugins: [ copyWasmFiles, aliasResolverPlugin, /* add to the end of plugins array */ esbuildProblemMatcherPlugin, { name: "alias-plugin", setup(build) { build.onResolve({ filter: /^pkce-challenge$/ }, (args) => { return { path: require.resolve("pkce-challenge/dist/index.browser.js") } }) }, }, ], entryPoints: ["src/extension.ts"], format: "cjs", sourcesContent: false, platform: "node", outfile: "dist/extension.js", external: ["vscode"], } async function main() { const extensionCtx = await esbuild.context(extensionConfig) if (watch) { await extensionCtx.watch() } else { await extensionCtx.rebuild() await extensionCtx.dispose() } } main().catch((e) => { console.error(e) process.exit(1) })