UNPKG

@picturelink/barrelsby

Version:

Automatic TypeScript barrels for your entire code base

114 lines (106 loc) 3.17 kB
import path from "path"; import { buildImportPath } from "../builder"; import { BaseUrl } from "../options/baseUrl"; import { Logger } from "../options/logger"; import { SemicolonCharacter } from "../options/noSemicolon"; import { QuoteCharacter } from "../options/quoteCharacter"; import { Directory, indentation, Location, nonAlphaNumeric } from "../utilities"; function stringify( structure: ExportStructure, previousIndentation: string ): string { const nextIndentation = previousIndentation + indentation; let content = ""; for (const key of Object.keys(structure).sort()) { content += ` ${nextIndentation}${key}: `; const exported = structure[key]; if (typeof exported === "string") { content += exported; } else { content += stringify(exported, nextIndentation); } content += ","; } return `{${content} ${previousIndentation}}`; } interface ExportStructure { [directoryName: string]: ExportStructure | string; } function buildStructureSubsection( structure: ExportStructure, pathParts: string[], name: string, reference: string ) { const pathPart = pathParts.shift() as string; let subsection: ExportStructure = pathPart === "." ? structure : (structure[pathPart] as ExportStructure); if (!subsection) { subsection = {}; structure[pathPart] = subsection; } if (pathParts.length === 0) { subsection[name] = reference; } else { buildStructureSubsection(subsection, pathParts, name, reference); } } interface Import { module: Location; path: string; } // Comparator for alphabetically sorting imports by path. // Does not need to check for equality, will only be used on distinct paths. function compareImports(a: Import, b: Import): number { return a.path < b.path ? -1 : 1; } export function buildFileSystemBarrel( directory: Directory, modules: Location[], quoteCharacter: QuoteCharacter, semicolonCharacter: SemicolonCharacter, _: Logger, // Not used baseUrl: BaseUrl ): string { const structure: ExportStructure = {}; let content = ""; modules .map( (module: Location): Import => ({ module, path: buildImportPath(directory, module, baseUrl) }) ) .sort(compareImports) .forEach((imported: Import): void => { const relativePath = path.relative(directory.path, imported.module.path); const directoryPath = path.dirname(relativePath); const parts = directoryPath.split(path.sep); const alias = relativePath.replace(nonAlphaNumeric, ""); content += `import * as ${alias} from ${quoteCharacter}${imported.path}${quoteCharacter}${semicolonCharacter} `; const fileName = path.basename(imported.module.name, ".ts"); buildStructureSubsection(structure, parts, fileName, alias); }); for (const key of Object.keys(structure).sort()) { const exported = structure[key]; if (typeof exported === "string") { content += `export {${exported} as ${key}}${semicolonCharacter} `; } else { content += `export const ${key} = ${stringify( exported, "" )}${semicolonCharacter} `; } } return content; }