Skip to Content
QMD Search SDKEigene Plugins entwickeln

Eigene Plugins entwickeln

Das SDK kann mit eigenen Content-Source und Auth-Plugins erweitert werden.

Content-Source-Plugin

Laedt Dateien aus einer externen Quelle (z.B. Confluence, S3, Datenbank).

Interface

interface ContentSourcePlugin { name: string; fetch(config: Record<string, unknown>): Promise<FetchResult>; validate?(config: Record<string, unknown>): boolean; } interface FetchResult { files: FetchedFile[]; stats: FetchStats; } interface FetchedFile { path: string; // Relativer Pfad content: string; // Datei-Inhalt collection: string; // Ziel-Collection metadata?: Record<string, unknown>; }

Beispiel: Confluence

import type { ContentSourcePlugin, FetchResult } from '@processcube-io/qmd-search'; export const confluenceSource: ContentSourcePlugin = { name: 'confluence', validate(config) { return typeof config.baseUrl === 'string' && typeof config.spaceKey === 'string'; }, async fetch(config): Promise<FetchResult> { const { baseUrl, spaceKey, token } = config as { baseUrl: string; spaceKey: string; token: string; }; const res = await fetch( `${baseUrl}/rest/api/content?spaceKey=${spaceKey}&expand=body.storage`, { headers: { Authorization: `Bearer ${token}` } }, ); const data = await res.json(); return { files: data.results.map((page: any) => ({ path: `${page.title.toLowerCase().replace(/\s+/g, '-')}.md`, content: page.body.storage.value, collection: spaceKey.toLowerCase(), })), stats: { fetched: data.results.length, failed: 0, skipped: 0 }, }; }, };

Registrierung

import { createIndexer } from '@processcube-io/qmd-search'; import { confluenceSource } from './confluence-source'; const indexer = createIndexer({ dbPath: './data/index.sqlite', collections: [ { name: 'wiki', path: './wiki', pattern: '**/*.md', context: 'Wiki' }, ], contentSources: [ { plugin: 'confluence', config: { baseUrl: 'https://wiki.example.com', spaceKey: 'DOCS', token: process.env.CONFLUENCE_TOKEN, }}, ], plugins: [confluenceSource], });

Auth-Plugin

Prueft API-Keys fuer den Standalone-Server.

Interface

interface AuthPlugin { name: string; resolve(req: Request): Promise<AuthResult>; } interface AuthResult { valid: boolean; customerId?: string; scopes?: string[]; error?: string; }

Beispiel: JWT-Validierung

import type { AuthPlugin, AuthResult } from '@processcube-io/qmd-search'; export function createJwtAuth(secret: string): AuthPlugin { return { name: 'jwt', async resolve(req: Request): Promise<AuthResult> { const auth = req.headers.get('authorization'); if (!auth?.startsWith('Bearer ')) { return { valid: false, error: 'Bearer Token erwartet' }; } try { // JWT verifizieren (z.B. mit jose) const token = auth.slice(7); const payload = await verifyJwt(token, secret); return { valid: true, customerId: payload.sub, scopes: payload.scopes, }; } catch { return { valid: false, error: 'Ungueltiger Token' }; } }, }; }

Verwendung

import { startServer } from '@processcube-io/qmd-search/adapters/standalone'; import { createJwtAuth } from './jwt-auth'; await startServer(store, { auth: createJwtAuth(process.env.JWT_SECRET!), });

Beispiel: REST-API als Content-Source

Zeigt wie eine beliebige REST-API als Datenquelle angebunden werden kann:

import type { ContentSourcePlugin, FetchResult } from '@processcube-io/qmd-search'; export const restApiSource: ContentSourcePlugin = { name: 'rest-api', async fetch(config): Promise<FetchResult> { const { baseUrl, endpoint, collection, headers } = config as { baseUrl: string; endpoint: string; collection: string; headers?: Record<string, string>; }; const res = await fetch(`${baseUrl}${endpoint}`, { headers }); if (!res.ok) { return { files: [], stats: { fetched: 0, failed: 1, skipped: 0 } }; } const items = await res.json() as { id: string; title: string; content: string }[]; return { files: items.map((item) => ({ path: `${item.id}.md`, content: `# ${item.title}\n\n${item.content}`, collection, })), stats: { fetched: items.length, failed: 0, skipped: 0 }, }; }, }; // Verwendung: // { plugin: 'rest-api', config: { // baseUrl: 'https://api.example.com', // endpoint: '/articles', // collection: 'articles', // headers: { Authorization: 'Bearer ...' }, // }}

Built-in Plugins

PluginTypImport
filesystemSourceContent-Source@processcube-io/qmd-search
githubSourceContent-Source@processcube-io/qmd-search
createEnvAuth()Auth@processcube-io/qmd-search/auth/env-auth
createOdooAuth()Auth@processcube-io/qmd-search/auth/odoo-auth