UNPKG

@compas/code-gen

Version:

Generate various boring parts of your server

87 lines (73 loc) 2.04 kB
import { AppError, isNil } from "@compas/stdlib"; /** * Collect and format JS imports. We only support ES module style imports for now. */ export class JavascriptImportCollector { /** * Resolve and type the import collector for JS files. * * @param {import("../file/context").GenerateFile}file * @returns {JavascriptImportCollector} */ static getImportCollector(file) { if ( isNil(file.importCollector) || !(file.importCollector instanceof JavascriptImportCollector) ) { throw AppError.serverError({ message: `File is created without an import collector.`, }); } return file.importCollector; } constructor() { /** * @private * @type {Map<string, Set<string>>} */ this.destructuredImports = new Map(); /** * @private * @type {Set<string>} */ this.rawImports = new Set(); } /** * Use a destructure import * * @param {string} path * @param {string} symbol */ destructure(path, symbol) { if (!this.destructuredImports.has(path)) { this.destructuredImports.set(path, new Set()); } this.destructuredImports.get(path)?.add(symbol); } /** * Add a raw import. These are deduplicated, before writing. * * @param {string} importString */ raw(importString) { this.rawImports.add(importString); } toString() { const result = [...this.rawImports]; // Sort the destructure imports, so even without any post formatting it looks pretty // good. const destructureKeys = [...this.destructuredImports.keys()].sort(); for (const key of destructureKeys) { const symbols = [ ...(this.destructuredImports.get(key)?.values() ?? []), ].sort(); const isMultiline = symbols.length > 3; if (isMultiline) { result.push(`import {\n ${symbols.join(",\n ")}\n} from "${key}";`); } else { result.push(`import { ${symbols.join(",")} } from "${key}";`); } } return result.join("\n"); } }