UNPKG

@tanstack/cli

Version:
145 lines (144 loc) 4.99 kB
import { z } from 'zod'; const TANSTACK_API_BASE = 'https://tanstack.com/api/data'; const LibrarySchema = z.object({ id: z.string(), name: z.string(), tagline: z.string(), description: z.string().optional(), frameworks: z.array(z.string()), latestVersion: z.string(), latestBranch: z.string().optional(), availableVersions: z.array(z.string()), repo: z.string(), docsRoot: z.string().optional(), defaultDocs: z.string().optional(), docsUrl: z.string().optional(), githubUrl: z.string().optional(), }); const LibrariesResponseSchema = z.object({ libraries: z.array(LibrarySchema), groups: z.record(z.array(z.string())), groupNames: z.record(z.string()), }); const PartnerSchema = z.object({ id: z.string(), name: z.string(), tagline: z.string().optional(), description: z.string(), category: z.string(), categoryLabel: z.string(), libraries: z.array(z.string()), url: z.string(), }); const PartnersResponseSchema = z.object({ partners: z.array(PartnerSchema), categories: z.array(z.string()), categoryLabels: z.record(z.string()), }); export const LIBRARY_GROUPS = ['state', 'headlessUI', 'performance', 'tooling']; // Algolia config (public read-only keys) const ALGOLIA_APP_ID = 'FQ0DQ6MA3C'; const ALGOLIA_API_KEY = '10c34d6a5c89f6048cf644d601e65172'; const ALGOLIA_INDEX = 'tanstack-test'; export async function fetchLibraries() { const response = await fetch(`${TANSTACK_API_BASE}/libraries`); if (!response.ok) { throw new Error(`Failed to fetch libraries: ${response.statusText}`); } const data = await response.json(); return LibrariesResponseSchema.parse(data); } export async function fetchPartners() { const response = await fetch(`${TANSTACK_API_BASE}/partners`); if (!response.ok) { throw new Error(`Failed to fetch partners: ${response.statusText}`); } const data = await response.json(); return PartnersResponseSchema.parse(data); } export async function fetchDocContent(repo, branch, filePath) { const url = `https://raw.githubusercontent.com/${repo}/${branch}/${filePath}`; const response = await fetch(url, { headers: { 'User-Agent': 'tanstack-cli' }, }); if (!response.ok) { if (response.status === 404) { return null; } throw new Error(`Failed to fetch doc: ${response.statusText}`); } return response.text(); } export async function searchTanStackDocs({ query, library, framework, limit = 10, }) { const ALL_LIBRARIES = [ 'config', 'form', 'optimistic', 'pacer', 'query', 'ranger', 'react-charts', 'router', 'start', 'store', 'table', 'virtual', 'db', 'devtools', ]; const ALL_FRAMEWORKS = ['react', 'vue', 'solid', 'svelte', 'angular']; const filterParts = ['version:latest']; if (library) { const otherLibraries = ALL_LIBRARIES.filter((l) => l !== library); const exclusions = otherLibraries.map((l) => `NOT library:${l}`).join(' AND '); if (exclusions) filterParts.push(`(${exclusions})`); } if (framework) { const otherFrameworks = ALL_FRAMEWORKS.filter((f) => f !== framework); const exclusions = otherFrameworks.map((f) => `NOT framework:${f}`).join(' AND '); if (exclusions) filterParts.push(`(${exclusions})`); } const searchParams = { requests: [ { indexName: ALGOLIA_INDEX, query, hitsPerPage: Math.min(limit, 50), filters: filterParts.join(' AND '), attributesToRetrieve: ['hierarchy', 'url', 'content', 'library'], attributesToSnippet: ['content:80'], }, ], }; const response = await fetch(`https://${ALGOLIA_APP_ID}-dsn.algolia.net/1/indexes/*/queries`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-Algolia-Application-Id': ALGOLIA_APP_ID, 'X-Algolia-API-Key': ALGOLIA_API_KEY, }, body: JSON.stringify(searchParams), }); if (!response.ok) { throw new Error(`Algolia search failed: ${response.statusText}`); } const searchResponse = (await response.json()); const searchResult = searchResponse.results[0]; const results = searchResult.hits.map((hit) => { const breadcrumb = Object.values(hit.hierarchy).filter((v) => Boolean(v)); return { title: hit.hierarchy.lvl1 || hit.hierarchy.lvl0 || 'Untitled', url: hit.url, snippet: hit._snippetResult?.content?.value || hit.content || '', library: hit.library || 'unknown', breadcrumb, }; }); return { query, totalHits: searchResult.nbHits || results.length, results, }; }