Browse Source

strongly typed AnkiConnect

main
parent
commit
02144f1982
1 changed files with 110 additions and 1 deletions
  1. +110
    -1
      src/ankiconnect.ts

+ 110
- 1
src/ankiconnect.ts View File

@ -1,11 +1,120 @@
import axios, { AxiosInstance } from 'axios';
export interface IAnkiConnectActions
extends Record<
string,
{
params?: Record<string, unknown>;
result: unknown;
}
> {
// Deck Actions
deckNames: {
result: string[];
};
getDecks: {
params: {
cards: number[];
};
result: {
[deckName: string]: number[];
};
};
changeDeck: {
params: {
cards: number[];
deck: string;
};
result: null;
};
// Media Actions
storeMediaFile: {
params: (
| {
/**
* Specified base64-encoded contents
*/
data: string;
}
| {
path: string;
}
| {
url: string;
}
) & {
/**
* To prevent Anki from removing files not used by any cards (e.g. for configuration files),
* prefix the filename with an underscore.
*/
filename: string;
/**
* Any existing file with the same name is deleted by default.
* Set `deleteExisting` to `false` to prevent that by letting Anki give the new file a non-conflicting name.
*/
deleteExisting?: boolean;
};
result: string;
};
retrieveMediaFile: {
/**
* Retrieves the base64-encoded contents of the specified file, returning `false` if the file does not exist.
*/
params: {
filename: string;
};
result: string | false;
};
getMediaFilesNames: {
/**
* Gets the names of media files matched the pattern. Returning all names by default.
*/
params: {
pattern: string;
};
result: string[];
};
deleteMediaFile: {
params: {
filename: string;
};
result: null;
};
}
export class AnkiConnect {
$axios: AxiosInstance;
constructor(public url = 'http://localhost:8765') {
constructor(public url = 'http://localhost:8765', public version = 6) {
this.$axios = axios.create({
baseURL: url,
});
}
async api<A extends keyof IAnkiConnectActions>(
action: A,
params: IAnkiConnectActions[A]['params'],
version = this.version,
): Promise<IAnkiConnectActions[A]['result']> {
const { data: response } = await this.$axios.post<{
result: any;
error: string | null;
}>('/', { action, params, version });
if (Object.getOwnPropertyNames(response).length != 2) {
throw 'response has an unexpected number of fields';
}
if (!response.hasOwnProperty('error')) {
throw 'response is missing required error field';
}
if (!response.hasOwnProperty('result')) {
throw 'response is missing required result field';
}
if (response.error) {
throw response.error;
}
return response.result;
}
}

Loading…
Cancel
Save