export class ExportDriver {
    /**
     * Add named exports to a source file.
     * If path already has exports, appends. Otherwise creates a new declaration.
     * If items is undefined, creates `export * from 'path'`.
     */
    static createExportItems(sourceFile, modulePath, items) {
        const existingPaths = ExportDriver.getExportPaths(sourceFile);
        // `export * from 'path'`
        if (!items) {
            if (!existingPaths.includes(modulePath)) {
                sourceFile.addExportDeclaration({ moduleSpecifier: modulePath });
            }
            return;
        }
        const itemsToExport = ExportDriver.getUniqueExportItems(sourceFile, items);
        if (itemsToExport.length === 0)
            return;
        if (existingPaths.includes(modulePath)) {
            const exportDecl = sourceFile.getExportDeclaration(modulePath);
            const checked = [];
            for (const item of itemsToExport) {
                const alreadyExported = exportDecl
                    ?.getNamedExports()
                    .some((ne) => ne.getName() === item);
                if (!alreadyExported)
                    checked.push(item);
            }
            if (checked.length > 0)
                exportDecl?.addNamedExports(checked);
        }
        else {
            sourceFile.addExportDeclaration({
                moduleSpecifier: modulePath,
                namedExports: itemsToExport,
            });
        }
    }
    static getExportPaths(sourceFile) {
        return sourceFile
            .getExportDeclarations()
            .map((e) => e.getModuleSpecifier()?.getLiteralValue())
            .filter((p) => p !== undefined);
    }
    static getUniqueExportItems(sourceFile, items) {
        const exported = new Set(sourceFile
            .getExportDeclarations()
            .flatMap((e) => e.getNamedExports().map((ne) => ne.getName())));
        return items.filter((item) => !exported.has(item));
    }
}
