import { promises as fs } from "fs";
import path from "path";
import { fileURLToPath } from "url";
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
interface DocSection {
title: string;
url: string;
content: string;
category: string;
source?: string; // 'vega-lite' or 'deneb'
}
interface SearchResult {
results: DocSection[];
query: string;
totalResults: number;
sources: string[]; // Which sources were searched
}
/**
* Search through Vega-Lite and Deneb documentation
*/
export async function searchDocs(query: string): Promise<SearchResult> {
const vegaLitePath = path.join(__dirname, "..", "data", "documentation.json");
const denebPath = path.join(__dirname, "..", "data", "deneb-documentation.json");
let allDocs: DocSection[] = [];
const sources: string[] = [];
try {
// Try to load Vega-Lite documentation
const vegaLiteData = await fs.readFile(vegaLitePath, "utf-8");
const vegaLiteDocs: DocSection[] = JSON.parse(vegaLiteData);
vegaLiteDocs.forEach(doc => doc.source = 'vega-lite');
allDocs = allDocs.concat(vegaLiteDocs);
sources.push('vega-lite');
} catch (error) {
// Vega-Lite docs not available, will use fallback
}
try {
// Try to load Deneb documentation
const denebData = await fs.readFile(denebPath, "utf-8");
const denebDocs: DocSection[] = JSON.parse(denebData);
denebDocs.forEach(doc => doc.source = 'deneb');
allDocs = allDocs.concat(denebDocs);
sources.push('deneb');
} catch (error) {
// Deneb docs not available, will use fallback
}
// If no docs loaded, use fallback
if (allDocs.length === 0) {
return getFallbackDocs(query);
}
// Simple text search (case-insensitive)
const lowerQuery = query.toLowerCase();
const results = allDocs.filter((doc) => {
return (
doc.title.toLowerCase().includes(lowerQuery) ||
doc.content.toLowerCase().includes(lowerQuery) ||
doc.category.toLowerCase().includes(lowerQuery)
);
});
// Sort by relevance (simple: title matches first, then content matches)
results.sort((a, b) => {
const aTitle = a.title.toLowerCase().includes(lowerQuery);
const bTitle = b.title.toLowerCase().includes(lowerQuery);
if (aTitle && !bTitle) return -1;
if (!aTitle && bTitle) return 1;
return 0;
});
return {
results: results.slice(0, 10), // Return top 10 results
query,
totalResults: results.length,
sources,
};
}
/**
* Fallback documentation when data files don't exist
*/
function getFallbackDocs(query: string): SearchResult {
return {
results: [
{
title: "Getting Started with Vega-Lite",
url: "https://vega.github.io/vega-lite/docs/",
content: "Vega-Lite is a high-level grammar of interactive graphics. It provides a concise, declarative JSON syntax to create an expressive range of visualizations for data analysis and presentation.",
category: "introduction",
source: "vega-lite",
},
{
title: "Mark Types",
url: "https://vega.github.io/vega-lite/docs/mark.html",
content: "Marks are the basic visual building blocks of a visualization. Common mark types include: bar, line, point, area, circle, square, tick, rect, rule, and text.",
category: "marks",
source: "vega-lite",
},
{
title: "Encoding Channels",
url: "https://vega.github.io/vega-lite/docs/encoding.html",
content: "Encodings map data fields to visual properties (channels) such as x, y, color, size, shape, and opacity. Each encoding channel can be customized with scales, axes, and legends.",
category: "encoding",
source: "vega-lite",
},
{
title: "Getting Started with Deneb for Power BI",
url: "https://deneb.guide/docs/getting-started",
content: "Deneb is a certified custom visual for Microsoft Power BI that allows you to create your own data visualizations using the declarative Vega or Vega-Lite languages. It's perfect for Power BI users who want to go beyond standard visuals.",
category: "introduction",
source: "deneb",
},
{
title: "Deneb and Power BI Integration",
url: "https://deneb.guide/docs/",
content: "Deneb provides seamless integration with Power BI, including cross-filtering, tooltips, and data interaction. You can use Power BI fields directly in your Vega-Lite specifications.",
category: "power-bi",
source: "deneb",
},
],
query,
totalResults: 5,
sources: ['vega-lite', 'deneb'],
};
}