strongly typed AnkiConnect
This commit is contained in:
1 parent
16f3e28690
commit
02144f1982
1 file changed
+110
-1
+110
-1
@@ -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;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user