@supernovaio/cli
Version:
Supernova.io Command Line Interface
138 lines (136 loc) • 6.99 kB
JavaScript
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="b50fc534-4b84-5040-8926-d07e094776f1")}catch(e){}}();
import * as ts from "typescript";
import { resolveModuleSpecifierFromFile } from "../../../utils/module-resolution.js";
import { Parser } from "./parser.js";
import { filterDuplicates } from "./utils/filter-duplicates.js";
function applyExportType(componentDocs, exportType) {
return componentDocs.map(componentDoc => ({ ...componentDoc, exportType }));
}
export class ModuleParser {
checker;
entryFilePath;
parser;
program;
constructor(program, entryFilePath, parserOptions = {}) {
this.program = program;
this.parser = new Parser(program, parserOptions);
this.entryFilePath = entryFilePath;
this.checker = program.getTypeChecker();
}
parseModule() {
const sourceFile = this.program.getSourceFile(this.entryFilePath);
if (!sourceFile) {
throw new Error(`Could not find source file for path ${this.entryFilePath}`);
}
const componentsInfo = this.parseFile(sourceFile);
return filterDuplicates(componentsInfo);
}
parseResolvedNamedReExport(scannedSource, modulePath, unresolvedExports, exportType) {
const resolvedPath = resolveModuleSpecifierFromFile(scannedSource.fileName, modulePath);
if (!resolvedPath) {
return [];
}
const newScannedSource = this.program.getSourceFile(resolvedPath);
if (!newScannedSource) {
return [];
}
const moduleSymbol = this.checker.getSymbolAtLocation(newScannedSource);
if (!moduleSymbol) {
return [];
}
const exportsByName = new Map(this.checker.getExportsOfModule(moduleSymbol).map(symbol => [symbol.getName(), symbol]));
const componentDocs = [];
for (const binding of unresolvedExports) {
const symbol = exportsByName.get(binding.importedName);
if (!symbol) {
continue;
}
const parsedDocs = applyExportType(this.parser.parseExportSymbol(symbol, newScannedSource), exportType).map(componentDoc => binding.exportedName === componentDoc.exportName
? componentDoc
: { ...componentDoc, exportName: binding.exportedName });
componentDocs.push(...parsedDocs);
}
return componentDocs;
}
parseFile(scannedSource, exportType = "explicit-export") {
const componentsInfo = [];
const moduleSymbol = this.checker.getSymbolAtLocation(scannedSource);
if (!moduleSymbol) {
throw new Error(`Could not find module symbol for source file: ${scannedSource.fileName}`);
}
ts.forEachChild(scannedSource, node => {
if (ts.isExportDeclaration(node) && node.exportClause && ts.isNamedExports(node.exportClause)) {
const unresolvedReExports = [];
for (const exportSpecifier of node.exportClause.elements) {
if (node.isTypeOnly || exportSpecifier.isTypeOnly) {
continue;
}
const importedName = exportSpecifier.propertyName?.text ?? exportSpecifier.name.text;
const exportedName = exportSpecifier.name.text;
const symbol = this.checker.getSymbolAtLocation(exportSpecifier.name);
let parsedDocs = [];
if (symbol) {
parsedDocs = this.parser.parseExportSymbol(symbol, scannedSource);
if (parsedDocs.length > 0) {
componentsInfo.push(...applyExportType(parsedDocs, exportType));
}
}
if (parsedDocs.length === 0 && node.moduleSpecifier && ts.isStringLiteral(node.moduleSpecifier)) {
unresolvedReExports.push({ exportedName, importedName });
}
}
if (node.moduleSpecifier && ts.isStringLiteral(node.moduleSpecifier) && unresolvedReExports.length > 0) {
componentsInfo.push(...this.parseResolvedNamedReExport(scannedSource, node.moduleSpecifier.text, unresolvedReExports, exportType));
}
return;
}
if ((ts.isClassDeclaration(node) || ts.isFunctionDeclaration(node)) && hasExportModifier(node)) {
const symbol = node.name ? this.checker.getSymbolAtLocation(node.name) : undefined;
if (symbol) {
componentsInfo.push(...applyExportType(this.parser.parseExportSymbol(symbol, scannedSource), exportType));
}
return;
}
if (ts.isVariableStatement(node) && hasExportModifier(node)) {
for (const declaration of node.declarationList.declarations) {
if (ts.isIdentifier(declaration.name)) {
const symbol = this.checker.getSymbolAtLocation(declaration.name);
if (symbol) {
componentsInfo.push(...applyExportType(this.parser.parseExportSymbol(symbol, scannedSource), exportType));
}
}
}
return;
}
if (ts.isExportAssignment(node)) {
const symbol = this.checker.getSymbolAtLocation(node.expression);
if (symbol) {
componentsInfo.push(...applyExportType(this.parser.parseExportSymbol(symbol, scannedSource), exportType));
}
return;
}
if (ts.isExportDeclaration(node) && node.moduleSpecifier && ts.isStringLiteral(node.moduleSpecifier)) {
const modulePath = node.moduleSpecifier.text;
const isStarExport = !node.exportClause;
if (!isStarExport) {
return;
}
const resolvedPath = resolveModuleSpecifierFromFile(scannedSource.fileName, modulePath);
if (!resolvedPath) {
return;
}
const newScannedSource = this.program.getSourceFile(resolvedPath);
if (newScannedSource) {
const newComponents = this.parseFile(newScannedSource, "star-export");
componentsInfo.push(...newComponents);
}
}
});
return componentsInfo;
}
}
function hasExportModifier(node) {
return (ts.canHaveModifiers(node) && node.modifiers?.some(mod => mod.kind === ts.SyntaxKind.ExportKeyword)) || false;
}
//# sourceMappingURL=module-parser.js.map
//# debugId=b50fc534-4b84-5040-8926-d07e094776f1