@ankinize/sdk 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/README.md +78 -2
  2. package/dist/batch.d.ts +157 -0
  3. package/dist/batch.js +263 -0
  4. package/dist/gen/client/client.gen.d.ts +2 -0
  5. package/dist/gen/client/client.gen.js +216 -0
  6. package/dist/gen/client/index.d.ts +10 -0
  7. package/dist/gen/client/index.js +6 -0
  8. package/dist/gen/client/types.gen.d.ts +120 -0
  9. package/dist/gen/client/types.gen.js +2 -0
  10. package/dist/gen/client/utils.gen.d.ts +37 -0
  11. package/dist/gen/client/utils.gen.js +228 -0
  12. package/dist/gen/client.gen.d.ts +12 -0
  13. package/dist/gen/client.gen.js +4 -0
  14. package/dist/gen/core/auth.gen.d.ts +25 -0
  15. package/dist/gen/core/auth.gen.js +14 -0
  16. package/dist/gen/core/bodySerializer.gen.d.ts +25 -0
  17. package/dist/gen/core/bodySerializer.gen.js +57 -0
  18. package/dist/gen/core/params.gen.d.ts +43 -0
  19. package/dist/gen/core/params.gen.js +109 -0
  20. package/dist/gen/core/pathSerializer.gen.d.ts +33 -0
  21. package/dist/gen/core/pathSerializer.gen.js +106 -0
  22. package/dist/gen/core/queryKeySerializer.gen.d.ts +18 -0
  23. package/dist/gen/core/queryKeySerializer.gen.js +92 -0
  24. package/dist/gen/core/serverSentEvents.gen.d.ts +71 -0
  25. package/dist/gen/core/serverSentEvents.gen.js +132 -0
  26. package/dist/gen/core/types.gen.d.ts +83 -0
  27. package/dist/gen/core/types.gen.js +2 -0
  28. package/dist/gen/core/utils.gen.d.ts +19 -0
  29. package/dist/gen/core/utils.gen.js +87 -0
  30. package/dist/gen/public.gen.d.ts +1 -0
  31. package/dist/gen/public.gen.js +2 -0
  32. package/dist/gen/sdk.gen.d.ts +504 -0
  33. package/dist/gen/sdk.gen.js +880 -0
  34. package/dist/gen/types.gen.d.ts +3452 -0
  35. package/dist/gen/types.gen.js +2 -0
  36. package/dist/index.d.ts +6 -0
  37. package/dist/index.js +5 -0
  38. package/dist/runtime.d.ts +19 -0
  39. package/dist/runtime.js +57 -0
  40. package/dist/typed.d.ts +90 -0
  41. package/dist/typed.js +51 -0
  42. package/package.json +38 -5
@@ -0,0 +1,504 @@
1
+ import { type Client, type ClientMeta, type Options as Options2, type RequestResult, type TDataShape } from './client/index.js';
2
+ import type { AnswerCardErrors, AnswerCardResponses, CreateDeckErrors, CreateDeckResponses, CreateNoteErrors, CreateNoteInput, CreateNoteResponses, CreateNotesBatchErrors, CreateNotesBatchResponses, CreateNoteTypeErrors, CreateNoteTypeResponses, CreateTagErrors, CreateTagResponses, CreateTagsBatchErrors, CreateTagsBatchResponses, DeleteCardErrors, DeleteCardResponses, DeleteCardsBatchErrors, DeleteCardsBatchResponses, DeleteDeckErrors, DeleteDeckResponses, DeleteMediaErrors, DeleteMediaResponses, DeleteNoteErrors, DeleteNoteResponses, DeleteNotesBatchErrors, DeleteNotesBatchResponses, DeleteNoteTypeErrors, DeleteNoteTypeResponses, DeleteTagErrors, DeleteTagResponses, DeleteTagsBatchErrors, DeleteTagsBatchResponses, GetCardErrors, GetCardResponses, GetCardSchedulingErrors, GetCardSchedulingResponses, GetDeckErrors, GetDeckResponses, GetMediaErrors, GetMediaResponses, GetNoteErrors, GetNoteResponses, GetNoteTypeErrors, GetNoteTypeResponses, GetStatsErrors, GetStatsResponses, GetStudyQueueErrors, GetStudyQueueResponses, GetTagErrors, GetTagResponses, ListCardsErrors, ListCardsResponses, ListDecksErrors, ListDecksResponses, ListMediaErrors, ListMediaResponses, ListNotesErrors, ListNotesResponses, ListNoteTypesErrors, ListNoteTypesResponses, ListTagsErrors, ListTagsResponses, PutMediaErrors, PutMediaResponses, RenameDeckErrors, RenameDeckResponses, RenameTagErrors, RenameTagResponses, RenderCardErrors, RenderCardResponses, UpdateCardErrors, UpdateCardInput, UpdateCardResponses, UpdateCardsBatchErrors, UpdateCardsBatchResponses, UpdateNoteErrors, UpdateNoteResponses, UpdateNotesBatchEntry, UpdateNotesBatchErrors, UpdateNotesBatchResponses, UpdateNoteTypeErrors, UpdateNoteTypeResponses, UpdateTagsBatchEntry, UpdateTagsBatchErrors, UpdateTagsBatchResponses } from './types.gen.js';
3
+ export type Options<TData extends TDataShape = TDataShape, ThrowOnError extends boolean = boolean, TResponse = unknown> = Options2<TData, ThrowOnError, TResponse> & {
4
+ /**
5
+ * You can provide a client instance returned by `createClient()` instead of
6
+ * individual options. This might be also useful if you want to implement a
7
+ * custom client.
8
+ */
9
+ client?: Client;
10
+ /**
11
+ * You can pass arbitrary values through the `meta` object. This can be
12
+ * used to access values that aren't defined as part of the SDK function.
13
+ */
14
+ meta?: keyof ClientMeta extends never ? Record<string, unknown> : ClientMeta;
15
+ };
16
+ /**
17
+ * List all decks
18
+ *
19
+ * Returns every deck in the collection, including the built-in `Default` deck and nested decks. A nested deck's name is its full path, such as `Languages::German`.
20
+ */
21
+ export declare const listDecks: <ThrowOnError extends boolean = true>(options?: Options<never, ThrowOnError>) => RequestResult<ListDecksResponses, ListDecksErrors, ThrowOnError, 'data'>;
22
+ /**
23
+ * Create a deck
24
+ *
25
+ * Creates a deck and returns it. Use `::` in the name to nest it under a parent, for example `Languages::German`.
26
+ */
27
+ export declare const createDeck: <ThrowOnError extends boolean = true>(parameters: {
28
+ idempotencyKey?: string;
29
+ name: string;
30
+ }, options?: Options<never, ThrowOnError>) => RequestResult<CreateDeckResponses, CreateDeckErrors, ThrowOnError, 'data'>;
31
+ /**
32
+ * Delete a deck and its subdecks
33
+ *
34
+ * Deletes the deck, all of its subdecks and every card in them. Notes left with no cards are removed too.
35
+ *
36
+ * This cannot be undone. The response lists exactly which decks and cards were removed. Deleting is still allowed while the account is over its storage quota.
37
+ */
38
+ export declare const deleteDeck: <ThrowOnError extends boolean = true>(parameters: {
39
+ idempotencyKey?: string;
40
+ id: number;
41
+ }, options?: Options<never, ThrowOnError>) => RequestResult<DeleteDeckResponses, DeleteDeckErrors, ThrowOnError, 'data'>;
42
+ /**
43
+ * Get a deck by ID
44
+ *
45
+ * Returns one deck by its numeric id.
46
+ */
47
+ export declare const getDeck: <ThrowOnError extends boolean = true>(parameters: {
48
+ id: number;
49
+ }, options?: Options<never, ThrowOnError>) => RequestResult<GetDeckResponses, GetDeckErrors, ThrowOnError, 'data'>;
50
+ /**
51
+ * Rename a deck
52
+ *
53
+ * Changes a deck's name. The deck keeps its id and its cards, and its subdecks are renamed with it.
54
+ */
55
+ export declare const renameDeck: <ThrowOnError extends boolean = true>(parameters: {
56
+ idempotencyKey?: string;
57
+ id: number;
58
+ name: string;
59
+ }, options?: Options<never, ThrowOnError>) => RequestResult<RenameDeckResponses, RenameDeckErrors, ThrowOnError, 'data'>;
60
+ /**
61
+ * List notes with pagination and filters
62
+ *
63
+ * Returns notes in ascending id order, one page at a time. Filters combine with AND.
64
+ *
65
+ * To read the next page, send the previous response's `nextCursor` as `cursor`. `nextCursor` is `null` on the last page.
66
+ */
67
+ export declare const listNotes: <ThrowOnError extends boolean = true>(parameters?: {
68
+ deckId?: number;
69
+ notetypeId?: number;
70
+ tag?: string;
71
+ cursor?: string;
72
+ limit?: number;
73
+ }, options?: Options<never, ThrowOnError>) => RequestResult<ListNotesResponses, ListNotesErrors, ThrowOnError, 'data'>;
74
+ /**
75
+ * Create a note and generate its cards
76
+ *
77
+ * Creates a note and generates its cards from the note type's templates.
78
+ *
79
+ * Name the note type with `notetypeName` and the deck with `deckName` (compared ignoring case; a nested deck is `Languages::German`), or send `notetypeId` and `deckId` instead. Exactly one of `notetypeName` and `notetypeId` is needed; without a deck the note goes to the `Default` deck. A name that matches nothing is `404`.
80
+ *
81
+ * `fields` is an object with one entry per field of the note type, keyed by the field's name in camelCase: `Back Extra` is `backExtra`. Each field of a note type shows its `key` in [Get a note type](#getNoteType). The field's exact name works as a key too. A field you leave out is empty; a key that names no field is `400 invalid_input` and lists the valid keys.
82
+ *
83
+ * Send a `guid` only when you import notes from somewhere else and need to keep a stable identity; otherwise one is generated. All fields together may not exceed 5 MiB.
84
+ */
85
+ export declare const createNote: <ThrowOnError extends boolean = true>(parameters: {
86
+ idempotencyKey?: string;
87
+ notetypeName?: string;
88
+ notetypeId?: number;
89
+ deckName?: string;
90
+ deckId?: number;
91
+ fields: {
92
+ [key: string]: string;
93
+ };
94
+ tags?: Array<string>;
95
+ guid?: string;
96
+ }, options?: Options<never, ThrowOnError>) => RequestResult<CreateNoteResponses, CreateNoteErrors, ThrowOnError, 'data'>;
97
+ /**
98
+ * Create many notes in one call
99
+ *
100
+ * Creates up to 200 notes in one call. It does what [Create a note](#createNote) does for each entry (also naming note types and decks by name), but in one transaction and with the note types, decks and tags looked up once, so importing is far faster than one request per note.
101
+ *
102
+ * The answer is `200` with one entry in `results` per note you sent, in the same order (`index`). An entry the collection refuses, such as an unknown deck or a key that names no field, is reported as `ok: false` with an `error`, and the others are still written. Send `atomic: true` to write all or nothing: if any entry is refused, nothing is written and the answer is `422` with the same body.
103
+ *
104
+ * A batch counts as one request per 10 notes (at least one) against your plan's rate limit. At most 2 batches run at once on the server; when it is busy the answer is `503` with `Retry-After`, and nothing was changed.
105
+ */
106
+ export declare const createNotesBatch: <ThrowOnError extends boolean = true>(parameters: {
107
+ idempotencyKey?: string;
108
+ notes: Array<CreateNoteInput>;
109
+ atomic?: boolean;
110
+ }, options?: Options<never, ThrowOnError>) => RequestResult<CreateNotesBatchResponses, CreateNotesBatchErrors, ThrowOnError, 'data'>;
111
+ /**
112
+ * Edit many notes in one call
113
+ *
114
+ * Edits up to 200 notes in one call. It does what [Edit a note](#updateNote) does for each entry, but in one transaction with note types, decks and tags looked up once. Each entry names a note by `id` and may send `fields`, `tags`, or the tag edits `addTags` and `removeTags`; what it leaves out stays as it was. `tags` replaces all tags and can not be sent with `addTags` or `removeTags`. `removeTags` works as in Anki: a tag is matched ignoring case, and removing `lang` also removes `lang::de` and the other tags below it (`*` is not a wildcard). A note may appear once per call.
115
+ *
116
+ * The answer is `200` with one entry in `results` per entry you sent, in the same order (`index`). An entry the collection refuses, such as an unknown note or the wrong number of fields, is reported as `ok: false` with an `error`, and the others are still written. Send `atomic: true` to write all or nothing: if any entry is refused, nothing is written and the answer is `422` with the same body. `changed` counts notes that differed from what was stored.
117
+ *
118
+ * A batch counts as one request per 10 entries (at least one) against your plan's rate limit.
119
+ */
120
+ export declare const updateNotesBatch: <ThrowOnError extends boolean = true>(parameters: {
121
+ idempotencyKey?: string;
122
+ updates: Array<UpdateNotesBatchEntry>;
123
+ atomic?: boolean;
124
+ }, options?: Options<never, ThrowOnError>) => RequestResult<UpdateNotesBatchResponses, UpdateNotesBatchErrors, ThrowOnError, 'data'>;
125
+ /**
126
+ * Delete many notes in one call
127
+ *
128
+ * Deletes up to 1000 notes and every card made from them, in one transaction. Ids that do not exist are not an error; they are listed in `missingNoteIds`. This cannot be undone. Deleting is still allowed while the account is over its storage quota.
129
+ *
130
+ * A batch counts as one request per 10 ids (at least one) against your plan's rate limit.
131
+ */
132
+ export declare const deleteNotesBatch: <ThrowOnError extends boolean = true>(parameters: {
133
+ idempotencyKey?: string;
134
+ ids: Array<number>;
135
+ }, options?: Options<never, ThrowOnError>) => RequestResult<DeleteNotesBatchResponses, DeleteNotesBatchErrors, ThrowOnError, 'data'>;
136
+ /**
137
+ * Delete a note and its cards
138
+ *
139
+ * Deletes a note and every card made from it. This cannot be undone. Deleting is still allowed while the account is over its storage quota.
140
+ */
141
+ export declare const deleteNote: <ThrowOnError extends boolean = true>(parameters: {
142
+ idempotencyKey?: string;
143
+ id: number;
144
+ }, options?: Options<never, ThrowOnError>) => RequestResult<DeleteNoteResponses, DeleteNoteErrors, ThrowOnError, 'data'>;
145
+ /**
146
+ * Get note by ID with cards
147
+ *
148
+ * Returns one note, including the cards it produced.
149
+ */
150
+ export declare const getNote: <ThrowOnError extends boolean = true>(parameters: {
151
+ id: number;
152
+ }, options?: Options<never, ThrowOnError>) => RequestResult<GetNoteResponses, GetNoteErrors, ThrowOnError, 'data'>;
153
+ /**
154
+ * Update note fields or tags
155
+ *
156
+ * Changes a note's fields, its tags, or both. Anything you leave out stays as it was, including each field missing from `fields`: send only the fields that change. If the new field content makes a template produce a card it did not before, the new cards are returned in `newCards`.
157
+ *
158
+ * `changed` is `false` when the request matched what was already stored, and nothing is written.
159
+ */
160
+ export declare const updateNote: <ThrowOnError extends boolean = true>(parameters: {
161
+ idempotencyKey?: string;
162
+ id: number;
163
+ fields?: {
164
+ [key: string]: string;
165
+ };
166
+ tags?: Array<string>;
167
+ }, options?: Options<never, ThrowOnError>) => RequestResult<UpdateNoteResponses, UpdateNoteErrors, ThrowOnError, 'data'>;
168
+ /**
169
+ * List all note types
170
+ *
171
+ * Returns the id and name of every note type. Use [Get a note type](#getNoteType) for its fields and templates.
172
+ */
173
+ export declare const listNoteTypes: <ThrowOnError extends boolean = true>(options?: Options<never, ThrowOnError>) => RequestResult<ListNoteTypesResponses, ListNoteTypesErrors, ThrowOnError, 'data'>;
174
+ /**
175
+ * Create note type (stock or custom)
176
+ *
177
+ * Creates a note type, either from one of Anki's stock designs or from your own fields and templates.
178
+ *
179
+ * Send `stock` (`basic`, `basic-and-reversed`, `basic-optional-reversed`, `basic-type-in-answer`, `cloze` or `image-occlusion`) to start from a stock design, and optionally `name` to rename it. Or send `fields` and `templates` to define it yourself.
180
+ */
181
+ export declare const createNoteType: <ThrowOnError extends boolean = true>(parameters?: {
182
+ idempotencyKey?: string;
183
+ stock?: string;
184
+ name?: string;
185
+ kind?: 'normal' | 'cloze';
186
+ fields?: Array<{
187
+ [key: string]: unknown;
188
+ }>;
189
+ templates?: Array<{
190
+ [key: string]: unknown;
191
+ }>;
192
+ css?: string;
193
+ sortFieldIdx?: number;
194
+ }, options?: Options<never, ThrowOnError>) => RequestResult<CreateNoteTypeResponses, CreateNoteTypeErrors, ThrowOnError, 'data'>;
195
+ /**
196
+ * Delete a note type
197
+ *
198
+ * Deletes a note type and every note that uses it.
199
+ *
200
+ * This changes the collection's schema, so it needs `?acceptFullSync=true` (otherwise `409 full_sync_required`) and *Allow destructive schema changes via API* turned on under Settings → Developer (otherwise `403 destructive_change_disabled`).
201
+ */
202
+ export declare const deleteNoteType: <ThrowOnError extends boolean = true>(parameters: {
203
+ idempotencyKey?: string;
204
+ id: number;
205
+ acceptFullSync?: boolean;
206
+ }, options?: Options<never, ThrowOnError>) => RequestResult<DeleteNoteTypeResponses, DeleteNoteTypeErrors, ThrowOnError, 'data'>;
207
+ /**
208
+ * Get note type details with fields and templates
209
+ *
210
+ * Returns a note type with its fields and card templates, its CSS and its sort field.
211
+ */
212
+ export declare const getNoteType: <ThrowOnError extends boolean = true>(parameters: {
213
+ id: number;
214
+ }, options?: Options<never, ThrowOnError>) => RequestResult<GetNoteTypeResponses, GetNoteTypeErrors, ThrowOnError, 'data'>;
215
+ /**
216
+ * Update note type fields, templates, or styling
217
+ *
218
+ * Changes a note type's name, CSS, sort field, fields or templates.
219
+ *
220
+ * Adding, reordering or renaming fields and templates is safe. Removing a field or template, or changing which fields a template needs, changes the collection's schema, so every device has to download the whole collection again on its next sync (a *full sync*). The request is refused with `409 full_sync_required` until you add `?acceptFullSync=true`.
221
+ *
222
+ * Removing a field or template also needs *Allow destructive schema changes via API* turned on under Settings → Developer, or the answer is `403 destructive_change_disabled`.
223
+ */
224
+ export declare const updateNoteType: <ThrowOnError extends boolean = true>(parameters: {
225
+ idempotencyKey?: string;
226
+ id: number;
227
+ acceptFullSync?: boolean;
228
+ name?: string;
229
+ css?: string;
230
+ sortFieldIdx?: number;
231
+ fields?: Array<{
232
+ [key: string]: unknown;
233
+ }>;
234
+ templates?: Array<{
235
+ [key: string]: unknown;
236
+ }>;
237
+ }, options?: Options<never, ThrowOnError>) => RequestResult<UpdateNoteTypeResponses, UpdateNoteTypeErrors, ThrowOnError, 'data'>;
238
+ /**
239
+ * Get the study queue of a deck
240
+ *
241
+ * Returns the cards Anki would show next in a deck, in the order it would show them: the deck (and its subdecks) is searched for learning cards due now, then reviews and day-learning cards, then new cards, under the daily limits of every deck preset and deck (including *New cards ignore review limit* and *Apply all parent limits*), with new-card gather and sort order, review order, FSRS orders, burying of siblings and the mixes of new cards and day-learning cards with reviews. The result matches the desktop client's queue for the same collection and moment.
242
+ *
243
+ * `counts` is what Anki shows above the buttons (new, learning, review). `cards` holds the first `limit` cards, each with a `kind` of `new`, `learning` or `review`; `total` is the length of the whole queue. Learning cards that are due within the preset's learn-ahead limit are listed at the end. Nothing is written, so asking again before you answer gives the same queue; after `POST /api/v1/cards/{id}/answer` ask again.
244
+ *
245
+ * Without `deckId` the collection's current deck is used. Only the v3 scheduler is supported (`409 card_state_error` otherwise). A filtered deck is queued with unlimited counts, in the order it was built in Anki (its cards keep that position).
246
+ */
247
+ export declare const getStudyQueue: <ThrowOnError extends boolean = true>(parameters?: {
248
+ deckId?: number;
249
+ limit?: number;
250
+ }, options?: Options<never, ThrowOnError>) => RequestResult<GetStudyQueueResponses, GetStudyQueueErrors, ThrowOnError, 'data'>;
251
+ /**
252
+ * List all tags
253
+ *
254
+ * Returns every tag in the collection, sorted by name. A nested tag keeps Anki's `::` separator, such as `Languages::German`; searching `tag:Languages` also finds the notes tagged with the nested ones.
255
+ */
256
+ export declare const listTags: <ThrowOnError extends boolean = true>(options?: Options<never, ThrowOnError>) => RequestResult<ListTagsResponses, ListTagsErrors, ThrowOnError, 'data'>;
257
+ /**
258
+ * Create a tag
259
+ *
260
+ * Creates a tag without putting it on a note, as Anki registers a tag when a note brings it. A name that is already used (ignoring case) answers `200` with `created: false` and the spelling that is stored, so sending it twice is safe. A nested name keeps the spelling of a parent that exists, as in Anki.
261
+ *
262
+ * A tag no note carries is removed by Anki's *Check Database* and *Clear Unused Tags*.
263
+ */
264
+ export declare const createTag: <ThrowOnError extends boolean = true>(parameters: {
265
+ idempotencyKey?: string;
266
+ name: string;
267
+ }, options?: Options<never, ThrowOnError>) => RequestResult<CreateTagResponses, CreateTagErrors, ThrowOnError, 'data'>;
268
+ /**
269
+ * Delete a tag
270
+ *
271
+ * Removes a tag and the tags nested under it from every note and from the list. The notes keep everything else. This cannot be undone. Deleting is still allowed while the account is over its storage quota.
272
+ */
273
+ export declare const deleteTag: <ThrowOnError extends boolean = true>(parameters: {
274
+ idempotencyKey?: string;
275
+ name: string;
276
+ }, options?: Options<never, ThrowOnError>) => RequestResult<DeleteTagResponses, DeleteTagErrors, ThrowOnError, 'data'>;
277
+ /**
278
+ * Get a tag by name
279
+ *
280
+ * Returns a tag and `noteCount`, the notes that carry it or one of its nested tags (the notes `tag:name` finds). A tag exists when it is in the list, when a nested tag is, or when a note carries it. The `name` in the path is the tag, percent-encoded, and is compared ignoring case.
281
+ */
282
+ export declare const getTag: <ThrowOnError extends boolean = true>(parameters: {
283
+ name: string;
284
+ }, options?: Options<never, ThrowOnError>) => RequestResult<GetTagResponses, GetTagErrors, ThrowOnError, 'data'>;
285
+ /**
286
+ * Rename a tag
287
+ *
288
+ * Renames a tag and every tag nested under it on all notes: renaming `Languages` to `Lang` makes `Languages::German` into `Lang::German`. The notes that change get a new modification time, so they sync. If the new name is already a tag, the two are merged, and a note that ends up with the tag twice keeps it once. Renaming a tag that no note carries renames it in the list.
289
+ *
290
+ * `notes` is how many notes were looked at and changed.
291
+ */
292
+ export declare const renameTag: <ThrowOnError extends boolean = true>(parameters: {
293
+ idempotencyKey?: string;
294
+ name: string;
295
+ newName: string;
296
+ }, options?: Options<never, ThrowOnError>) => RequestResult<RenameTagResponses, RenameTagErrors, ThrowOnError, 'data'>;
297
+ /**
298
+ * Create many tags in one call
299
+ *
300
+ * Creates up to 200 tags in one call, in one transaction. It does what [Create a tag](#createTag) does for each name. The answer is `200` with one entry in `results` per name, in order; a name that is refused (such as one with a space) is `ok: false` with an `error` and the others are still created. Send `atomic: true` to write all or nothing: then the answer is `422` with the same body.
301
+ *
302
+ * A batch counts as one request per 10 names against your plan's rate limit.
303
+ */
304
+ export declare const createTagsBatch: <ThrowOnError extends boolean = true>(parameters: {
305
+ idempotencyKey?: string;
306
+ names: Array<string>;
307
+ atomic?: boolean;
308
+ }, options?: Options<never, ThrowOnError>) => RequestResult<CreateTagsBatchResponses, CreateTagsBatchErrors, ThrowOnError, 'data'>;
309
+ /**
310
+ * Rename many tags in one call
311
+ *
312
+ * Renames up to 200 tags in one call, in one pass over the notes. Each entry names a tag by `name` and gives its `newName`, as [Rename a tag](#renameTag) does. Two entries may use the same `newName` (that merges the tags), but an entry that touches another one (a `name` that is, contains or lies inside another entry's `name` or `newName`) is refused with `invalid_input`, because the result would depend on the order. Entries are reported in `results` as in [Create many notes](#createNotesBatch); `atomic: true` writes all or nothing.
313
+ */
314
+ export declare const updateTagsBatch: <ThrowOnError extends boolean = true>(parameters: {
315
+ idempotencyKey?: string;
316
+ updates: Array<UpdateTagsBatchEntry>;
317
+ atomic?: boolean;
318
+ }, options?: Options<never, ThrowOnError>) => RequestResult<UpdateTagsBatchResponses, UpdateTagsBatchErrors, ThrowOnError, 'data'>;
319
+ /**
320
+ * Delete many tags in one call
321
+ *
322
+ * Deletes up to 1000 tags, with the tags nested under them, from every note and from the list, in one transaction. Names that do not exist are not an error; they are listed in `missingNames`. This cannot be undone. Deleting is still allowed while the account is over its storage quota.
323
+ */
324
+ export declare const deleteTagsBatch: <ThrowOnError extends boolean = true>(parameters: {
325
+ idempotencyKey?: string;
326
+ names: Array<string>;
327
+ }, options?: Options<never, ThrowOnError>) => RequestResult<DeleteTagsBatchResponses, DeleteTagsBatchErrors, ThrowOnError, 'data'>;
328
+ /**
329
+ * Get the statistics of a search
330
+ *
331
+ * Returns the graphs of Anki's statistics screen for the cards a search matches (`q`, default every card) and the last `days` days of review history (`0`, the default, is all of it). The numbers are Anki's: the same counts, buckets and averages the desktop client draws, computed from the review log and the cards in place. Nothing is copied into another database. A request reads the review log once, so a big collection takes a moment; one that takes longer than 20 seconds is refused with `400 invalid_input` (narrow the search or the days). The server keeps the graphs of a search in memory for up to five minutes, and never past the end of the day, while the collection is unchanged, so a repeat request is answered without reading the collection again; any change to the collection ends that.
332
+ *
333
+ * Days are counted from the end of the current day, so `0` is today, `-1` yesterday and `1` tomorrow; a day starts at the collection's `rollover` hour and is read in its `localOffset` (UTC when unset), as `timing` says. `buttons`, `hours` and `trueRetention` count answers over a month, three months, a year and all time. `cardCounts` counts cards by kind, with suspended and buried cards counted separately or together. `eases` (SM-2) and `difficulty`, `stability` and `retrievability` (FSRS) cover the cards that have the data; `fsrs` says whether the collection has FSRS turned on. `retrievability` is the chance of recalling each card now, from its memory state and the time since its last review. Keys of the count objects are numbers: a day, a percent bin or an interval in days.
334
+ */
335
+ export declare const getStats: <ThrowOnError extends boolean = true>(parameters?: {
336
+ q?: string;
337
+ days?: number;
338
+ }, options?: Options<never, ThrowOnError>) => RequestResult<GetStatsResponses, GetStatsErrors, ThrowOnError, 'data'>;
339
+ /**
340
+ * List media files
341
+ *
342
+ * Lists the collection's media files by name, 100 at a time (`limit` up to 1000). `prefix` keeps only the names that start with it. When `nextCursor` is not null, pass it as `cursor` to get the next page. Each item has the file's `size`, its `sha1` and `sha256`, the `contentType` it is served as, and the `usn` of its last change, which is the number the Anki media sync uses.
343
+ */
344
+ export declare const listMedia: <ThrowOnError extends boolean = true>(parameters?: {
345
+ prefix?: string;
346
+ limit?: number;
347
+ cursor?: string;
348
+ }, options?: Options<never, ThrowOnError>) => RequestResult<ListMediaResponses, ListMediaErrors, ThrowOnError, 'data'>;
349
+ /**
350
+ * Delete a media file
351
+ *
352
+ * Deletes the file. Your devices are told on their next media sync, as when a file is deleted in Anki. The storage it used is freed once no other name uses the same bytes. A name that is not there is `404`.
353
+ */
354
+ export declare const deleteMedia: <ThrowOnError extends boolean = true>(parameters: {
355
+ name: string;
356
+ }, options?: Options<never, ThrowOnError>) => RequestResult<DeleteMediaResponses, DeleteMediaErrors, ThrowOnError, 'data'>;
357
+ /**
358
+ * Download a media file
359
+ *
360
+ * Returns the file's bytes. The type comes from the file name's extension only, never from the bytes, and every response says `X-Content-Type-Options: nosniff` and a `Content-Security-Policy` with `sandbox`, so a file from your collection cannot run script on this origin. Images, audio, video and fonts are shown inline; SVG, PDF and any other type are offered as downloads (`Content-Disposition: attachment`).
361
+ *
362
+ * The `ETag` is the file's SHA-256, so `If-None-Match` answers `304`. `Range: bytes=...` (one range) answers `206`, which lets a browser seek in audio and video; a range past the end is `416`.
363
+ *
364
+ * Instead of a key, the request may carry the `u`, `exp` and `sig` query parameters of a signed link. A signed link opens that one file for reading until it expires, which is how a card shown in a sandboxed frame loads its pictures: `GET /api/v1/cards/{id}/render` puts such links into the card unless you pass `mediaBaseUrl`. The links last an hour.
365
+ */
366
+ export declare const getMedia: <ThrowOnError extends boolean = true>(parameters: {
367
+ Range?: string;
368
+ name: string;
369
+ }, options?: Options<never, ThrowOnError>) => RequestResult<GetMediaResponses, GetMediaErrors, ThrowOnError, 'data'>;
370
+ /**
371
+ * Store a media file
372
+ *
373
+ * Stores the request body as the file, creating it or replacing it. Send the bytes as they are (any `Content-Type`) with a `Content-Length` header; chunked uploads are refused with `411`. A file is at most 100 MiB and not empty.
374
+ *
375
+ * The name must be one Anki clients would keep as it is: at most 120 bytes of UTF-8, in Unicode NFC, with none of `[ ] < > : " / ? * ^ \ |` or control characters, no Windows device name (`CON`, `NUL`, `LPT1`...), and not ending in a space or a dot. A client rewrites any other name when it syncs, so the file would never settle between devices; the `422 invalid_media_name` says the name to use. `Thumbs.db` and `.DS_Store` are never synced and are refused as well.
376
+ *
377
+ * `201` means the file is new; `200` means it replaced a file (`created` is false) or the bytes were the same (`unchanged` is true, and the `usn` stays). A new or changed file gets the next `usn`, so the media sync sends it to your devices. A file that would take the storage over the quota is `403 over_quota`, and a collection already holding the most file names it may (deleted names count) is `403 media_entry_limit`; replacing a name never adds one.
378
+ */
379
+ export declare const putMedia: <ThrowOnError extends boolean = true>(parameters: {
380
+ name: string;
381
+ body: Blob | File;
382
+ }, options?: Options<never, ThrowOnError>) => RequestResult<PutMediaResponses, PutMediaErrors, ThrowOnError, 'data'>;
383
+ /**
384
+ * List cards with pagination and filters
385
+ *
386
+ * Returns the cards that match a search (`q`; every card when it is empty), in ascending id order, one page at a time. You can also filter by deck or by note. Paginate with `nextCursor` as for notes, with one difference: a search that has to look at every card, such as a regular expression or `prop:s`, stops after about 10,000 cards and returns what it found so far together with a `nextCursor`. A page can therefore hold fewer than `limit` cards, or none, while `nextCursor` is not `null`; keep following it until it is.
387
+ */
388
+ export declare const listCards: <ThrowOnError extends boolean = true>(parameters?: {
389
+ q?: string;
390
+ deckId?: number;
391
+ noteId?: number;
392
+ cursor?: string;
393
+ limit?: number;
394
+ }, options?: Options<never, ThrowOnError>) => RequestResult<ListCardsResponses, ListCardsErrors, ThrowOnError, 'data'>;
395
+ /**
396
+ * Edit many cards in one call
397
+ *
398
+ * Applies one change to up to 1000 cards, in one transaction: set a flag, move them to a deck, suspend or bury them. It does what [Edit a card](#updateCard) does for each id, with the same rules for `patch`.
399
+ *
400
+ * The answer is `200` with one entry in `results` per distinct id. A card that does not exist, or that sits in a filtered deck and so can not be moved, is reported as `ok: false`, and the others are still changed. Send `atomic: true` to write all or nothing: if any card is refused, nothing is written and the answer is `422` with the same body. `changed` counts the cards that differed from what was stored.
401
+ *
402
+ * A batch counts as one request per 10 ids (at least one) against your plan's rate limit.
403
+ */
404
+ export declare const updateCardsBatch: <ThrowOnError extends boolean = true>(parameters: {
405
+ idempotencyKey?: string;
406
+ ids: Array<number>;
407
+ patch: UpdateCardInput;
408
+ atomic?: boolean;
409
+ }, options?: Options<never, ThrowOnError>) => RequestResult<UpdateCardsBatchResponses, UpdateCardsBatchErrors, ThrowOnError, 'data'>;
410
+ /**
411
+ * Delete many cards in one call
412
+ *
413
+ * Deletes up to 1000 cards in one transaction. A note whose last card is deleted is deleted with it. Ids that do not exist are not an error; they are listed in `missingCardIds`. This cannot be undone. Deleting is still allowed while the account is over its storage quota.
414
+ *
415
+ * A batch counts as one request per 10 ids (at least one) against your plan's rate limit.
416
+ */
417
+ export declare const deleteCardsBatch: <ThrowOnError extends boolean = true>(parameters: {
418
+ idempotencyKey?: string;
419
+ ids: Array<number>;
420
+ }, options?: Options<never, ThrowOnError>) => RequestResult<DeleteCardsBatchResponses, DeleteCardsBatchErrors, ThrowOnError, 'data'>;
421
+ /**
422
+ * Delete a card
423
+ *
424
+ * Deletes one card. If it was the last card of its note, the note is removed too. This cannot be undone. Deleting is still allowed while the account is over its storage quota.
425
+ */
426
+ export declare const deleteCard: <ThrowOnError extends boolean = true>(parameters: {
427
+ idempotencyKey?: string;
428
+ id: number;
429
+ }, options?: Options<never, ThrowOnError>) => RequestResult<DeleteCardResponses, DeleteCardErrors, ThrowOnError, 'data'>;
430
+ /**
431
+ * Get card details by ID
432
+ *
433
+ * Returns one card with its scheduling state: queue, due, interval, ease factor, repetitions and lapses.
434
+ */
435
+ export declare const getCard: <ThrowOnError extends boolean = true>(parameters: {
436
+ id: number;
437
+ }, options?: Options<never, ThrowOnError>) => RequestResult<GetCardResponses, GetCardErrors, ThrowOnError, 'data'>;
438
+ /**
439
+ * Edit a card
440
+ *
441
+ * Changes a card's flag, moves it to another deck, or suspends or buries it. Anything you leave out stays as it was.
442
+ *
443
+ * `flag` is 0 (none) to 7. `suspended` and `buried` cannot both be sent. Suspending keeps a card out of review until you send `suspended: false`; burying hides it only until the next day or until you unbury it. A suspended card is never buried. Moving a card clears its FSRS memory state; it is replayed from the review history with the new deck's parameters the next time the card is shown or answered. Cards in a filtered deck can neither be moved nor moved into one (`409 card_state_error`).
444
+ *
445
+ * `changed` is `false` when the request matched what was already stored.
446
+ */
447
+ export declare const updateCard: <ThrowOnError extends boolean = true>(parameters: {
448
+ idempotencyKey?: string;
449
+ id: number;
450
+ deckId?: number;
451
+ flag?: number;
452
+ suspended?: boolean;
453
+ buried?: boolean;
454
+ }, options?: Options<never, ThrowOnError>) => RequestResult<UpdateCardResponses, UpdateCardErrors, ThrowOnError, 'data'>;
455
+ /**
456
+ * Render a card's front and back
457
+ *
458
+ * Renders the card as Anki shows it: the note's fields are put into the card template, so the question and the answer are ready to display. The answer includes the question above a divider, as in Anki.
459
+ *
460
+ * Everything is sanitized on the server before it is returned: scripts, event handlers, iframes, forms, `javascript:` links and remote styles are removed, and CSS is limited to a safe subset. The result is still *content from your collection*, so display it in a sandboxed `<iframe sandbox>` or `srcdoc` and not straight into your page.
461
+ *
462
+ * With `format=json` (the default) you get `question`, `answer` and `css`. With `format=html` you get one complete HTML document, with a `Content-Security-Policy` that allows no script and the `sandbox` directive, which is meant for `<iframe sandbox srcdoc>`: fetch it with your key and put the text in `srcdoc` (an iframe's `src` cannot send the key, and this server refuses to be framed). Media in a card is referred to by file name and listed in `media`. The file names in the question and answer are turned into signed links to `GET /api/v1/media/{name}` that last an hour, so the card shows its pictures and plays its audio from a sandboxed frame; or pass `mediaBaseUrl` (an `http(s)` URL ending in `/`) to have them point at files you host instead.
463
+ *
464
+ * **Typing the answer.** For `{{type:Field}}`, `{{type:nc:Field}}` (accents ignored) and `{{type:cloze:Field}}` the question holds `<div class="typeans" data-field="Field"></div>`, where your own input goes. Pass what the learner typed as `typedAnswer` (up to 1000 characters) and the answer shows the comparison Anki shows, computed the same way: a `<code id="typeans">` with the typed text and the expected text as `typeGood`, `typeBad` and `typeMissed` spans around an arrow, in the font and size of the field. The classes carry no colors, so style them in your page. Without `typedAnswer` the answer shows the expected text. A text too long to compare is shown as one change.
465
+ *
466
+ * **Formulas.** `\(...\)` and `\[...\]` are returned as written. Anki's `[$]...[/$]` and `[$$]...[/$$]` tags are rewritten to them, and `[latex]...[/latex]` becomes display math; images are not generated, because that needs a TeX installation. `math` is true when the question or the answer holds a formula. Typeset it in your page with MathJax 3 after inserting the HTML (`format=html` allows no script, so a formula stays as text there). TeX that is not math, such as packages or TikZ, is not supported.
467
+ *
468
+ * A template that cannot be rendered is `422 render_error`.
469
+ */
470
+ export declare const renderCard: <ThrowOnError extends boolean = true>(parameters: {
471
+ id: number;
472
+ format?: 'json' | 'html';
473
+ typedAnswer?: string;
474
+ mediaBaseUrl?: string;
475
+ }, options?: Options<never, ThrowOnError>) => RequestResult<RenderCardResponses, RenderCardErrors, ThrowOnError, 'data'>;
476
+ /**
477
+ * Preview the four answer buttons
478
+ *
479
+ * Shows what each answer button would do, without answering: the time until the card would next be due after Again, Hard, Good and Easy. This is the preview Anki shows above its buttons.
480
+ *
481
+ * Only the v3 scheduler is supported. The card must be answerable: not suspended or buried (`409 card_state_error`). A card in a filtered deck is previewed as Anki does: in a deck that reschedules, the buttons are the home deck preset's, and a review that comes before it was due is scheduled from the days it was early; in a deck that does not reschedule, the buttons are the preview delays (Again, Hard and Good come back after the deck's delays, a delay of 0 ends the preview, and Easy always ends it) and show `0` seconds when they end it.
482
+ *
483
+ * Review intervals are fuzzed and load balanced like Anki's: the day is drawn within the fuzz range, weighted towards days with fewer cards of the same preset due, the preset's Easy Days and (if it buries siblings) days away from the card's siblings. The draw is fixed by the card and its review count, so the preview, the answer and a repeat of either agree.
484
+ */
485
+ export declare const getCardScheduling: <ThrowOnError extends boolean = true>(parameters: {
486
+ id: number;
487
+ }, options?: Options<never, ThrowOnError>) => RequestResult<GetCardSchedulingResponses, GetCardSchedulingErrors, ThrowOnError, 'data'>;
488
+ /**
489
+ * Answer (review) a card
490
+ *
491
+ * Answers a card, the same as pressing a button in Anki's reviewer. The card is rescheduled with the deck preset's v3 scheduler (or FSRS when the preset turns it on), a review-log entry is written, the deck's daily counts go up, and siblings are buried if the preset says so. A card that reaches the leech threshold gets the `leech` tag and, if the preset says so, is suspended.
492
+ *
493
+ * `rating` is `again`, `hard`, `good` or `easy` (or 1 to 4). `timeTakenMs` is how long the learner looked at the card, capped by the preset. Send an `Idempotency-Key` so a retry does not answer twice.
494
+ *
495
+ * The card must not be suspended or buried, and the collection must use the v3 scheduler; otherwise the answer is `409 card_state_error`. A card in a filtered deck is answered as Anki does. The preset, the answer-time cap and burying come from the card's home deck, the daily counts go to the filtered deck and its parents, and the review log records an answer given before the card was due (or in a deck that does not reschedule) with type 3 (*filtered*). In a deck that reschedules, a review card that is passed returns to its home deck, and a learning card stays in the filtered deck until it graduates; in a deck that does not reschedule, nothing is rescheduled: Again, Hard and Good bring the card back after the deck's preview delay, and the card returns to its home deck in its old state when the preview ends. The legacy schedulers are not supported. A card that has no FSRS memory state yet (for example one that was just moved into an FSRS deck) gets one replayed from its review history, as Anki does, and from its SM-2 ease and interval when the history is too short.
496
+ *
497
+ * The load balancer is applied to review intervals as in Anki (see `GET /api/v1/cards/{id}/scheduling`). It reads the cards due in the next 99 days when the card is answered (Anki reads them once when it builds a queue), and the weekday used for Easy Days is taken in the collection's `localOffset` (UTC when unset).
498
+ */
499
+ export declare const answerCard: <ThrowOnError extends boolean = true>(parameters: {
500
+ idempotencyKey?: string;
501
+ id: number;
502
+ rating: 'again' | 'hard' | 'good' | 'easy' | number;
503
+ timeTakenMs?: number;
504
+ }, options?: Options<never, ThrowOnError>) => RequestResult<AnswerCardResponses, AnswerCardErrors, ThrowOnError, 'data'>;