// 記憶體版 KbdbClient — 模擬基本盤 API,供插件單元測試(不打真網路、不碰 D1)。 // 只實作插件實際用到的方法,行為對齊 arcrun/kbdb 契約。 import type { KbdbClient, BaseEntry, BaseRecord } from '../src/lib/kbdb-client'; export class MockKbdbClient { private entries = new Map(); private templates = new Map(); private records = new Map; owner_id?: string }>(); private seq = 0; private id(prefix: string): string { this.seq += 1; return `${prefix}-${this.seq}`; } async createEntry(input: any): Promise { const id = this.id('entry'); const entry: BaseEntry = { id, content: input.content ?? null, entry_type: input.entry_type, owner_id: input.owner_id ?? null }; this.entries.set(id, entry); return entry; } async getEntry(id: string): Promise { return this.entries.get(id) ?? null; } async listEntries(filters: any = {}): Promise { return [...this.entries.values()].filter( (e) => (!filters.entry_type || e.entry_type === filters.entry_type) && (!filters.owner_id || e.owner_id === filters.owner_id), ); } async searchEntries(q: string, owner_id?: string): Promise { const needle = q.toLowerCase(); return [...this.entries.values()].filter( (e) => (e.content ?? '').toLowerCase().includes(needle) && (!owner_id || e.owner_id === owner_id), ); } async updateEntry(id: string, patch: any): Promise { const e = this.entries.get(id); if (!e) return null; Object.assign(e, patch); return e; } async deleteEntry(id: string): Promise { this.entries.delete(id); } async ensureTemplate(name: string, slots: string[]): Promise { // 對齊真 client 的 slot-diff 行為:既有 template 補缺 slot(不 early-return)。 const have = this.templates.get(name); if (!have) { this.templates.set(name, [...slots]); return; } const set = new Set(have); for (const s of slots) if (!set.has(s)) have.push(s); } async createRecord(template: string, values: Record, owner_id?: string): Promise { const id = this.id('rec'); this.records.set(id, { template, values: { ...values }, owner_id }); return id; } async getRecord(recordId: string): Promise { const r = this.records.get(recordId); if (!r) return null; return { record_id: recordId, template: r.template, values: r.values }; } async updateRecord(recordId: string, values: Record): Promise { const r = this.records.get(recordId); if (r) Object.assign(r.values, values); } async listRecordsByTemplate(template: string, owner_id?: string): Promise { return [...this.records.entries()] .filter(([, r]) => r.template === template && (!owner_id || r.owner_id === owner_id)) .map(([record_id, r]) => ({ record_id, template: r.template, values: r.values })); } } /** 轉成 KbdbClient 型別供 action 接受。 */ export function mockClient(): KbdbClient { return new MockKbdbClient() as unknown as KbdbClient; }