Browse Source

strongly typed AnkiConnect

main
parent
commit
9516f287c8
2 changed files with 214 additions and 1 deletions
  1. +37
    -0
      src/anki.ts
  2. +177
    -1
      src/ankiconnect.ts

+ 37
- 0
src/anki.ts View File

@ -0,0 +1,37 @@
export interface IAnkiCard {
sortf: number;
did: number;
latexPre: string;
latexPost: string;
mod: number;
usn: number;
vers: number[];
type: number;
css: string;
name: string;
flds: IAnkiField[];
tmpls: IAnkiTemplate[];
tags: string[];
id: number | string;
req: unknown[];
}
export interface IAnkiField {
name: string;
ord: number;
sticky: boolean;
rtl: boolean;
font: string;
size: number;
media: unknown[];
}
export interface IAnkiTemplate {
name: string;
ord: number;
qfmt: string;
afmt: string;
did: number | null;
bqfmt: string;
bamt: string;
}

+ 177
- 1
src/ankiconnect.ts View File

@ -1,5 +1,12 @@
import axios, { AxiosInstance } from 'axios';
import { IAnkiCard } from './anki';
export interface IAnkiConnectResponse<K extends keyof IAnkiConnectActions> {
result: IAnkiConnectActions[K];
error: string | null;
}
export interface IAnkiConnectActions
extends Record<
string,
@ -81,6 +88,152 @@ export interface IAnkiConnectActions
};
result: null;
};
// Miscellaneous Actions
exportPackage: {
/**
* Exports a given deck in .apkg format.
* Returns true if successful or false otherwise.
*/
params: {
deck: string;
path: string;
/**
* The optional property includeSched (default is false) can be specified to include the cards scheduling data.
*/
includeSched?: boolean;
};
result: boolean;
};
importPackage: {
/**
* Imports a file in .apkg format into the collection.
* Returns true if successful or false otherwise.
*/
params: {
/**
* Note that the file path is relative to Ankis collection.media folder, not to the client.
*/
path: string;
};
result: boolean;
};
reloadCollection: {
result: null;
};
// Model Actions
modelNames: {
result: string[];
};
modelNamesAndIds: {
result: {
[modelName: string]: number;
};
};
modelFieldNames: {
params: {
modelName: string;
};
result: string[];
};
modelFieldsOnTemplates: {
params: {
modelName: string;
};
result: {
[side: string]: [string[], string[]];
};
};
createModel: {
params: {
modelName: string;
inOrderFields: string[];
/**
* Default to built-in CSS
*/
css?: string;
isCloze?: boolean;
cardTemplates: IAnkiConnectCardTemplate[];
};
result: IAnkiCard;
};
modelTemplates: {
params: {
modelName: string;
};
result: {
[side: string]: {
Front: string;
Back: string;
};
};
};
modelStyling: {
params: {
modelName: string;
};
result: {
css: string;
};
};
updateModelTemplates: {
/**
* Modify the templates of an existing model by name.
* Only specifies cards and specified sides will be modified.
*
* If an existing card or side is not included in the request, it will be left unchanged.
*/
params: {
model: {
name: string;
templates: {
[side: string]: {
Front?: string;
Back?: string;
};
};
};
};
result: null;
};
updateModelStyling: {
params: {
model: {
name: string;
css: string;
};
};
result: null;
};
findAndReplaceInModels: {
params: {
model: {
modelName: string;
findText: string;
replaceText: string;
front?: boolean;
back?: boolean;
css?: boolean;
};
};
result: number;
};
// Note Actions
addNote: {
params: {};
result: number;
};
}
export interface IAnkiConnectCardTemplate {
/**
* By default the card names will be Card 1, Card 2, and so on.
*/
Name?: string;
Front: string;
Back: string;
}
export class AnkiConnect {
@ -95,8 +248,31 @@ export class AnkiConnect {
async api<A extends keyof IAnkiConnectActions>(
action: A,
params: IAnkiConnectActions[A]['params'],
version?: number,
): Promise<IAnkiConnectActions[A]['result']>;
async api<Results extends IAnkiConnectResponse<any>[]>(
action: 'multi',
params: {
actions: Array<
{
[A in keyof IAnkiConnectActions]: {
action: A;
params: IAnkiConnectActions[A]['params'];
};
}[keyof IAnkiConnectActions]
>;
},
version?: number,
): Promise<{
result: Results;
}>;
async api<A extends keyof IAnkiConnectActions | 'multi'>(
action: A,
params: unknown,
version = this.version,
): Promise<IAnkiConnectActions[A]['result']> {
) {
const { data: response } = await this.$axios.post<{
result: any;
error: string | null;

Loading…
Cancel
Save