From db60365b0e9ac3abb97d96c6b1c1ec4d8cd07f5c Mon Sep 17 00:00:00 2001 From: sudacode Date: Sun, 17 May 2026 19:18:12 -0700 Subject: [PATCH] fix: normalize anki deck sample size --- src/anki-connect.test.ts | 30 ++++++++++++++++++++++++++++++ src/anki-connect.ts | 8 +++++++- 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/src/anki-connect.test.ts b/src/anki-connect.test.ts index 51edeb3d..a31ea362 100644 --- a/src/anki-connect.test.ts +++ b/src/anki-connect.test.ts @@ -124,6 +124,36 @@ test('AnkiConnectClient derives field names from sampled notes in a deck', async }); }); +test('AnkiConnectClient treats negative deck note sample sizes as empty samples', async () => { + const client = new AnkiConnectClient('http://127.0.0.1:8765') as unknown as { + client: { post: (url: string, body: { action: string; params: unknown }) => Promise }; + }; + const calls: Array<{ action: string; params: unknown }> = []; + client.client = { + post: async (_url, body) => { + calls.push({ action: body.action, params: body.params }); + if (body.action === 'findNotes') { + return { data: { result: [3, 1, 2], error: null } }; + } + if (body.action === 'notesInfo') { + return { + data: { + result: [{ fields: { Sentence: { value: 'x' } } }], + error: null, + }, + }; + } + return { data: { result: [], error: null } }; + }, + }; + + assert.deepEqual(await (client as unknown as AnkiConnectClient).fieldNamesForDeck('Mining', -1), []); + assert.deepEqual( + calls.map((call) => call.action), + ['findNotes'], + ); +}); + test('AnkiConnectClient derives model names from sampled notes in a deck', async () => { const client = new AnkiConnectClient('http://127.0.0.1:8765') as unknown as { client: { post: (url: string, body: { action: string; params: unknown }) => Promise }; diff --git a/src/anki-connect.ts b/src/anki-connect.ts index 98853375..6d5f1f52 100644 --- a/src/anki-connect.ts +++ b/src/anki-connect.ts @@ -187,7 +187,13 @@ export class AnkiConnectClient { return []; } - return this.notesInfo(noteIds.slice(0, sampleSize)); + const finiteSampleSize = Number.isFinite(sampleSize) ? sampleSize : 0; + const normalizedSampleSize = Math.min(noteIds.length, Math.max(0, Math.floor(finiteSampleSize))); + if (normalizedSampleSize === 0) { + return []; + } + + return this.notesInfo(noteIds.slice(0, normalizedSampleSize)); } async fieldNamesForDeck(deckName: string, sampleSize = 100): Promise {