yomitan-core 1.1.0 → 1.2.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.
- package/dist/anki-connect-B2UXtiUS.js +6 -0
- package/dist/anki-connect-BXvjYYm0.cjs +6 -0
- package/dist/{anki-connect-B_YpChhu.cjs → anki-connect-DGx7Gr0H.cjs} +3 -3
- package/dist/{anki-connect-B_YpChhu.cjs.map → anki-connect-DGx7Gr0H.cjs.map} +1 -1
- package/dist/{anki-connect-697E04LF.js → anki-connect-Dau8nAXZ.js} +3 -3
- package/dist/{anki-connect-697E04LF.js.map → anki-connect-Dau8nAXZ.js.map} +1 -1
- package/dist/anki.cjs +5 -5
- package/dist/anki.d.ts +2 -2
- package/dist/anki.js +6 -6
- package/dist/{audio-ZuaDkaUZ.d.ts → audio-DN-FhZ5k.d.ts} +1 -1
- package/dist/{audio-ZuaDkaUZ.d.ts.map → audio-DN-FhZ5k.d.ts.map} +1 -1
- package/dist/{audio-url-generator-CgTMaTM2.js → audio-url-generator-C7mkxYeq.js} +2 -2
- package/dist/{audio-url-generator-CfXaxZ47.cjs → audio-url-generator-CZECihX-.cjs} +2 -2
- package/dist/{audio-url-generator-C23AXVj1.cjs → audio-url-generator-CorFRyBU.cjs} +2 -2
- package/dist/{audio-url-generator-C23AXVj1.cjs.map → audio-url-generator-CorFRyBU.cjs.map} +1 -1
- package/dist/{audio-url-generator-DykdzZJu.js → audio-url-generator-_6Qk0i3T.js} +2 -2
- package/dist/{audio-url-generator-DykdzZJu.js.map → audio-url-generator-_6Qk0i3T.js.map} +1 -1
- package/dist/audio.cjs +2 -2
- package/dist/audio.d.ts +2 -2
- package/dist/audio.js +2 -2
- package/dist/{batch-processor-CXZZhx5t.js → batch-processor-BR-gB3H3.js} +1 -1
- package/dist/{batch-processor-CXZZhx5t.js.map → batch-processor-BR-gB3H3.js.map} +1 -1
- package/dist/batch-processor-CSF1acTw.cjs +3 -0
- package/dist/{batch-processor-C8pSzqRE.cjs → batch-processor-DFqM_L-_.cjs} +1 -1
- package/dist/{batch-processor-C8pSzqRE.cjs.map → batch-processor-DFqM_L-_.cjs.map} +1 -1
- package/dist/batch-processor-Quo9jUyf.js +3 -0
- package/dist/{core-C_0QjRBI.d.ts → core-CRjMTF7c.d.ts} +1 -1
- package/dist/{core-C_0QjRBI.d.ts.map → core-CRjMTF7c.d.ts.map} +1 -1
- package/dist/database.d.ts +3 -3
- package/dist/debug-I2dyAd2e.cjs +51 -0
- package/dist/debug-I2dyAd2e.cjs.map +1 -0
- package/dist/debug-hF63AFkq.js +38 -0
- package/dist/debug-hF63AFkq.js.map +1 -0
- package/dist/{dictionary-CfzEFbXZ.d.ts → dictionary-DdxghSJP.d.ts} +1 -1
- package/dist/{dictionary-CfzEFbXZ.d.ts.map → dictionary-DdxghSJP.d.ts.map} +1 -1
- package/dist/{dictionary-data-util-BY_72f3u.cjs → dictionary-data-util-DmLJMtGc.cjs} +1 -1
- package/dist/{dictionary-data-util-BY_72f3u.cjs.map → dictionary-data-util-DmLJMtGc.cjs.map} +1 -1
- package/dist/{dictionary-data-util-CKDT7n2t.js → dictionary-data-util-gUUD9ElK.js} +1 -1
- package/dist/{dictionary-data-util-CKDT7n2t.js.map → dictionary-data-util-gUUD9ElK.js.map} +1 -1
- package/dist/{dictionary-database-BRAqOF_M.d.ts → dictionary-database-D0lvK2n3.d.ts} +2 -2
- package/dist/{dictionary-database-BRAqOF_M.d.ts.map → dictionary-database-D0lvK2n3.d.ts.map} +1 -1
- package/dist/{dictionary-importer-C7mNL5CJ.js → dictionary-importer-BPlLeF5R.js} +5 -5
- package/dist/{dictionary-importer-C7mNL5CJ.js.map → dictionary-importer-BPlLeF5R.js.map} +1 -1
- package/dist/{dictionary-importer-CbMwsqEX.cjs → dictionary-importer-BvgP1Fs9.cjs} +5 -5
- package/dist/{dictionary-importer-CbMwsqEX.cjs.map → dictionary-importer-BvgP1Fs9.cjs.map} +1 -1
- package/dist/{dictionary-importer-C-AlWsIN.d.ts → dictionary-importer-CDbCAbwG.d.ts} +2 -2
- package/dist/{dictionary-importer-C-AlWsIN.d.ts.map → dictionary-importer-CDbCAbwG.d.ts.map} +1 -1
- package/dist/dictionary-importer-DEMVqTjR.js +8 -0
- package/dist/dictionary-importer-Luz6usUQ.cjs +8 -0
- package/dist/{dictionary-update-checker-DE2ymYcs.js → dictionary-update-checker-CLbtQ48X.js} +2 -2
- package/dist/{dictionary-update-checker-DE2ymYcs.js.map → dictionary-update-checker-CLbtQ48X.js.map} +1 -1
- package/dist/dictionary-update-checker-CsS7MxK_.js +4 -0
- package/dist/{dictionary-update-checker-CU3q0aoP.cjs → dictionary-update-checker-DgjPsURI.cjs} +2 -2
- package/dist/{dictionary-update-checker-xIwF77-R.cjs → dictionary-update-checker-DmiIUoKw.cjs} +2 -2
- package/dist/{dictionary-update-checker-xIwF77-R.cjs.map → dictionary-update-checker-DmiIUoKw.cjs.map} +1 -1
- package/dist/{display-generator-vxdAYHeK.js → display-generator-BAEJDrHT.js} +6 -6
- package/dist/{display-generator-vxdAYHeK.js.map → display-generator-BAEJDrHT.js.map} +1 -1
- package/dist/display-generator-D5fkD0JI.cjs +10 -0
- package/dist/display-generator-DZLMaVuP.js +10 -0
- package/dist/{display-generator-CSWA_AMa.cjs → display-generator-D_0chBzj.cjs} +5 -5
- package/dist/{display-generator-CSWA_AMa.cjs.map → display-generator-D_0chBzj.cjs.map} +1 -1
- package/dist/{errors-ZI2FcGUl.cjs → errors-0pIJI6N2.cjs} +1 -1
- package/dist/{errors-ZI2FcGUl.cjs.map → errors-0pIJI6N2.cjs.map} +1 -1
- package/dist/{errors-D2JfYV-C.js → errors-DvKlMRXC.js} +1 -1
- package/dist/{errors-D2JfYV-C.js.map → errors-DvKlMRXC.js.map} +1 -1
- package/dist/frequency-ranking-BXjfhhUQ.js +3 -0
- package/dist/{frequency-ranking-DmNIoxut.cjs → frequency-ranking-Cx1kkIrw.cjs} +1 -1
- package/dist/{frequency-ranking-DzbdZghE.js → frequency-ranking-DEJMTMdg.js} +1 -1
- package/dist/{frequency-ranking-DzbdZghE.js.map → frequency-ranking-DEJMTMdg.js.map} +1 -1
- package/dist/{frequency-ranking-Dm6xCMkY.cjs → frequency-ranking-DVYxTXN-.cjs} +1 -1
- package/dist/{frequency-ranking-Dm6xCMkY.cjs.map → frequency-ranking-DVYxTXN-.cjs.map} +1 -1
- package/dist/furigana-MU_j_m5i.cjs +5 -0
- package/dist/{furigana-dSFngFbc.cjs → furigana-SZuBaUyl.cjs} +1 -1
- package/dist/{furigana-dSFngFbc.cjs.map → furigana-SZuBaUyl.cjs.map} +1 -1
- package/dist/furigana-ZCs0Xs0b.js +5 -0
- package/dist/{furigana-BpFJbm9M.js → furigana-h18vaQ7a.js} +2 -2
- package/dist/{furigana-BpFJbm9M.js.map → furigana-h18vaQ7a.js.map} +1 -1
- package/dist/import.cjs +6 -6
- package/dist/import.d.ts +3 -3
- package/dist/import.js +6 -6
- package/dist/index.cjs +34 -15
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +8 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +36 -17
- package/dist/index.js.map +1 -1
- package/dist/{japanese-CKPyY5k_.js → japanese-OKEGf_i4.js} +2 -2
- package/dist/{japanese-CKPyY5k_.js.map → japanese-OKEGf_i4.js.map} +1 -1
- package/dist/{json-CyQBn52D.cjs → json-Cdj6aIOQ.cjs} +1 -1
- package/dist/{json-CyQBn52D.cjs.map → json-Cdj6aIOQ.cjs.map} +1 -1
- package/dist/{json-DTq_IXXF.js → json-rIgOFqVY.js} +1 -1
- package/dist/{json-DTq_IXXF.js.map → json-rIgOFqVY.js.map} +1 -1
- package/dist/{language-DFFp_7nc.d.ts → language-DMwuc2-C.d.ts} +1 -1
- package/dist/{language-DFFp_7nc.d.ts.map → language-DMwuc2-C.d.ts.map} +1 -1
- package/dist/language.cjs +2 -2
- package/dist/language.d.ts +3 -3
- package/dist/language.js +4 -4
- package/dist/lookup.cjs +5 -4
- package/dist/lookup.d.ts +4 -4
- package/dist/lookup.js +7 -6
- package/dist/{media-loader-CMEuD0fn.js → media-loader-C1WZVVaA.js} +1 -1
- package/dist/{media-loader-CMEuD0fn.js.map → media-loader-C1WZVVaA.js.map} +1 -1
- package/dist/media-loader-CWNb22gc.cjs +3 -0
- package/dist/media-loader-CrQnDnSp.js +3 -0
- package/dist/{media-loader-DS2ZXpSI.cjs → media-loader-RE32nGs3.cjs} +1 -1
- package/dist/{media-loader-DS2ZXpSI.cjs.map → media-loader-RE32nGs3.cjs.map} +1 -1
- package/dist/{multi-language-transformer-CjLO0S8V.d.ts → multi-language-transformer-CFu0CVWY.d.ts} +3 -3
- package/dist/{multi-language-transformer-CjLO0S8V.d.ts.map → multi-language-transformer-CFu0CVWY.d.ts.map} +1 -1
- package/dist/{multi-language-transformer-DvjBcuyp.js → multi-language-transformer-Dk8S4W6j.js} +2 -2
- package/dist/{multi-language-transformer-DvjBcuyp.js.map → multi-language-transformer-Dk8S4W6j.js.map} +1 -1
- package/dist/{pronunciation-generator-cNtAQi5s.js → pronunciation-generator-BXcwS3By.js} +2 -2
- package/dist/{pronunciation-generator-cNtAQi5s.js.map → pronunciation-generator-BXcwS3By.js.map} +1 -1
- package/dist/{pronunciation-generator-CPwnr43z.cjs → pronunciation-generator-CP1kjYje.cjs} +1 -1
- package/dist/{pronunciation-generator-B8y__W7I.cjs → pronunciation-generator-CeC3LFPU.cjs} +1 -1
- package/dist/{pronunciation-generator-B8y__W7I.cjs.map → pronunciation-generator-CeC3LFPU.cjs.map} +1 -1
- package/dist/{pronunciation-generator-BvTbUlOy.js → pronunciation-generator-I1xpdJu0.js} +1 -1
- package/dist/render.cjs +6 -6
- package/dist/render.d.ts +2 -2
- package/dist/render.js +7 -7
- package/dist/{sentence-parser-ZSC_ntAi.cjs → sentence-parser-8i1Y_OGS.cjs} +57 -5
- package/dist/sentence-parser-8i1Y_OGS.cjs.map +1 -0
- package/dist/sentence-parser-BQpu2oSA.d.cts.map +1 -1
- package/dist/{sentence-parser-C8OC1Ix_.js → sentence-parser-CXDs4R_c.js} +58 -6
- package/dist/sentence-parser-CXDs4R_c.js.map +1 -0
- package/dist/{sentence-parser-DnY0NA5g.d.ts → sentence-parser-CmsHUc_p.d.ts} +3 -3
- package/dist/{sentence-parser-DnY0NA5g.d.ts.map → sentence-parser-CmsHUc_p.d.ts.map} +1 -1
- package/dist/sentence-parser-DQccqSpq.cjs +6 -0
- package/dist/sentence-parser-DsleseSI.js +6 -0
- package/dist/structured-content-generator-BhEkwa0T.js +4 -0
- package/dist/{structured-content-generator-C5Hhaurz.cjs → structured-content-generator-CokLKgrb.cjs} +2 -2
- package/dist/{structured-content-generator-C5Hhaurz.cjs.map → structured-content-generator-CokLKgrb.cjs.map} +1 -1
- package/dist/{structured-content-generator-D48bLhPA.cjs → structured-content-generator-_z5dJECG.cjs} +2 -2
- package/dist/{structured-content-generator-aJieXElq.js → structured-content-generator-gnjtdBcC.js} +2 -2
- package/dist/{structured-content-generator-aJieXElq.js.map → structured-content-generator-gnjtdBcC.js.map} +1 -1
- package/dist/{text-utilities-CFDC9Bkr.cjs → text-utilities-CTsN1Bq8.cjs} +1 -1
- package/dist/{text-utilities-CFDC9Bkr.cjs.map → text-utilities-CTsN1Bq8.cjs.map} +1 -1
- package/dist/{text-utilities-D5eno9GK.js → text-utilities-DjLdStjv.js} +1 -1
- package/dist/{text-utilities-D5eno9GK.js.map → text-utilities-DjLdStjv.js.map} +1 -1
- package/dist/translator-BGI37WRC.js +7 -0
- package/dist/{translator-DAL8ugoC.cjs → translator-Cd1ECBM1.cjs} +1 -1
- package/dist/{translator-CYvu9gr1.cjs → translator-ClzybVmi.cjs} +1 -1
- package/dist/{translator-CYvu9gr1.cjs.map → translator-ClzybVmi.cjs.map} +1 -1
- package/dist/{translator-COZI9EQT.js → translator-jFVzLjEs.js} +2 -2
- package/dist/{translator-COZI9EQT.js.map → translator-jFVzLjEs.js.map} +1 -1
- package/package.json +1 -1
- package/dist/anki-connect-D-02BbHi.cjs +0 -6
- package/dist/anki-connect-Vn-cnxs8.js +0 -6
- package/dist/batch-processor-DItpL6Pp.js +0 -3
- package/dist/batch-processor-fiLvFS2_.cjs +0 -3
- package/dist/dictionary-importer-B9M3SD2y.js +0 -8
- package/dist/dictionary-importer-DnR8Bsai.cjs +0 -8
- package/dist/dictionary-update-checker-Cnjz4tQD.js +0 -4
- package/dist/display-generator-BegC-lK-.cjs +0 -10
- package/dist/display-generator-CEJQTOYP.js +0 -10
- package/dist/frequency-ranking-B-kvnxro.js +0 -3
- package/dist/furigana-C3JCmlrA.js +0 -5
- package/dist/furigana-q-DH5eJV.cjs +0 -5
- package/dist/media-loader-BBTESZXn.cjs +0 -3
- package/dist/media-loader-CNKoAjQs.js +0 -3
- package/dist/sentence-parser-C8OC1Ix_.js.map +0 -1
- package/dist/sentence-parser-CUoYJvJv.cjs +0 -5
- package/dist/sentence-parser-DG_7Th_q.js +0 -5
- package/dist/sentence-parser-ZSC_ntAi.cjs.map +0 -1
- package/dist/structured-content-generator-Dww8IT7Y.js +0 -4
- package/dist/translator-B5InyZJa.js +0 -7
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
const require_utilities = require('./utilities-C-lbZaJE.cjs');
|
|
3
|
-
const require_errors = require('./errors-
|
|
4
|
-
const require_json = require('./json-
|
|
3
|
+
const require_errors = require('./errors-0pIJI6N2.cjs');
|
|
4
|
+
const require_json = require('./json-Cdj6aIOQ.cjs');
|
|
5
5
|
|
|
6
6
|
//#region src/util/anki-util.ts
|
|
7
7
|
const markerPattern = /\{([\p{Letter}\p{Number}_-]+)\}/gu;
|
|
@@ -510,4 +510,4 @@ Object.defineProperty(exports, 'getRootDeckName', {
|
|
|
510
510
|
return getRootDeckName;
|
|
511
511
|
}
|
|
512
512
|
});
|
|
513
|
-
//# sourceMappingURL=anki-connect-
|
|
513
|
+
//# sourceMappingURL=anki-connect-DGx7Gr0H.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"anki-connect-B_YpChhu.cjs","names":["deckName: string","global: boolean","config?: { server?: string; apiKey?: string }","value: string","value: boolean","value: string | null","note: Note","notes: Note[]","noteWithId: Note & { id?: NoteId }","noteIds: NoteId[]","cardIds: CardId[]","modelName: string","query: string","noteId: NoteId","fileName: string","content: string","actions: { action: string; params: Record<string, unknown> }[]","actionsTargetsList: NoteId[][][]","allNoteIds: NoteId[][]","scopes: string[]","actions: string[] | null","action: string","error: Error","YomitanError","params: Record<string, unknown>","body: MessageBody","response: Response","responseText: string | null","result: unknown","text: string","fields: Record<string, string>","message: string","data: unknown","expectedType: string","context?: string","value: unknown","expectedCount: number","type: 'boolean' | 'string' | 'number'","result2: (NoteInfo | null)[]","fields2: { [key: string]: NoteFieldInfo }","item2: NoteInfo","result2: (CardInfo | null)[]","item2: CardInfo","result2: CanAddNotesDetail[]"],"sources":["../src/util/anki-util.ts","../src/anki/anki-connect.ts"],"sourcesContent":["const markerPattern = /\\{([\\p{Letter}\\p{Number}_-]+)\\}/gu;\n\n/**\n * Gets the root deck name of a full deck name.\n */\nexport function getRootDeckName(deckName: string): string {\n const index = deckName.indexOf('::');\n return index >= 0 ? deckName.substring(0, index) : deckName;\n}\n\n/**\n * Checks whether or not any marker is contained in a string.\n */\nexport function stringContainsAnyFieldMarker(string: string): boolean {\n const result = markerPattern.test(string);\n markerPattern.lastIndex = 0;\n return result;\n}\n\n/**\n * Gets a list of all markers that are contained in a string.\n */\nexport function getFieldMarkers(string: string): string[] {\n const pattern = markerPattern;\n const markers: string[] = [];\n while (true) {\n const match = pattern.exec(string);\n if (match === null) {\n break;\n }\n markers.push(match[1]);\n }\n return markers;\n}\n\n/**\n * Returns a regular expression which can be used to find markers in a string.\n */\nexport function cloneFieldMarkerPattern(global: boolean): RegExp {\n return new RegExp(markerPattern.source, global ? 'gu' : 'u');\n}\n\n/**\n * Checks whether or not a note object is valid.\n */\nexport function isNoteDataValid(note: {\n fields: Record<string, string>;\n deckName: string;\n modelName: string;\n}): boolean {\n const { fields, deckName, modelName } = note;\n return (\n typeof deckName === 'string' &&\n deckName.length > 0 &&\n typeof modelName === 'string' &&\n modelName.length > 0 &&\n Object.entries(fields).length > 0\n );\n}\n\nexport const INVALID_NOTE_ID = -1;\n\n/**\n * Generates a file name for Anki note media.\n */\nexport function generateAnkiNoteMediaFileName(prefix: string, extension: string, timestamp: number): string {\n let fileName = prefix;\n fileName += `_${ankNoteDateToString(new Date(timestamp))}`;\n fileName += extension;\n fileName = replaceInvalidFileNameCharacters(fileName);\n return fileName;\n}\n\nfunction replaceInvalidFileNameCharacters(fileName: string): string {\n // eslint-disable-next-line no-control-regex\n return fileName.replace(/[<>:\"/\\\\|?*\\u0000-\\u001F]/g, '-');\n}\n\nfunction ankNoteDateToString(date: Date): string {\n const year = date.getUTCFullYear();\n const month = date.getUTCMonth().toString().padStart(2, '0');\n const day = date.getUTCDate().toString().padStart(2, '0');\n const hours = date.getUTCHours().toString().padStart(2, '0');\n const minutes = date.getUTCMinutes().toString().padStart(2, '0');\n const seconds = date.getUTCSeconds().toString().padStart(2, '0');\n const milliseconds = date.getUTCMilliseconds().toString().padStart(3, '0');\n return `${year}-${month}-${day}-${hours}-${minutes}-${seconds}-${milliseconds}`;\n}\n","import type {\n ApiReflectResult,\n CanAddNotesDetail,\n CardId,\n CardInfo,\n MessageBody,\n Note,\n NoteFieldInfo,\n NoteId,\n NoteInfo,\n} from '../types/anki';\nimport { getRootDeckName } from '../util/anki-util';\nimport { YomitanError } from '../util/errors';\nimport { parseJson } from '../util/json';\nimport { isObjectNotArray } from '../util/utilities';\n\n/**\n * This class controls communication with Anki via the AnkiConnect plugin.\n */\nexport class AnkiConnect {\n private _enabled: boolean;\n private _server: string | null;\n private _localVersion: number;\n private _remoteVersion: number;\n private _versionCheckPromise: Promise<number> | null;\n private _apiKey: string | null;\n\n constructor(config?: { server?: string; apiKey?: string }) {\n this._enabled = false;\n this._server = config?.server ?? null;\n this._localVersion = 2;\n this._remoteVersion = 0;\n this._versionCheckPromise = null;\n this._apiKey = config?.apiKey ?? null;\n }\n\n get server(): string | null {\n return this._server;\n }\n\n set server(value: string) {\n this._server = value;\n }\n\n get enabled(): boolean {\n return this._enabled;\n }\n\n set enabled(value: boolean) {\n this._enabled = value;\n }\n\n get apiKey(): string | null {\n return this._apiKey;\n }\n\n set apiKey(value: string | null) {\n this._apiKey = value;\n }\n\n /**\n * Checks whether a connection to AnkiConnect can be established.\n */\n async isConnected(): Promise<boolean> {\n try {\n await this._getVersion();\n return true;\n } catch (_e) {\n return false;\n }\n }\n\n /**\n * Gets the AnkiConnect API version number.\n */\n async getVersion(): Promise<number | null> {\n if (!this._enabled) {\n return null;\n }\n await this._checkVersion();\n return await this._getVersion();\n }\n\n async addNote(note: Note): Promise<NoteId | null> {\n if (!this._enabled) {\n return null;\n }\n await this._checkVersion();\n const result = await this._invoke('addNote', { note });\n if (result !== null && typeof result !== 'number') {\n throw this._createUnexpectedResultError('number|null', result);\n }\n return result as NoteId | null;\n }\n\n async addNotes(notes: Note[]): Promise<(number | null)[] | null> {\n if (!this._enabled) {\n return null;\n }\n await this._checkVersion();\n const result = await this._invoke('addNotes', { notes });\n if (result !== null && !Array.isArray(result)) {\n throw this._createUnexpectedResultError('(number | null)[] | null', result);\n }\n return result as (number | null)[] | null;\n }\n\n async updateNoteFields(noteWithId: Note & { id?: NoteId }): Promise<null> {\n if (!this._enabled) {\n return null;\n }\n await this._checkVersion();\n const result = await this._invoke('updateNoteFields', { note: noteWithId });\n if (result !== null) {\n throw this._createUnexpectedResultError('null', result);\n }\n return result;\n }\n\n async canAddNotes(notes: Note[]): Promise<boolean[]> {\n if (!this._enabled) {\n return new Array(notes.length).fill(false) as boolean[];\n }\n await this._checkVersion();\n const result = await this._invoke('canAddNotes', { notes });\n return this._normalizeArray<boolean>(result, notes.length, 'boolean');\n }\n\n async canAddNotesWithErrorDetail(notes: Note[]): Promise<CanAddNotesDetail[]> {\n if (!this._enabled) {\n return notes.map(() => ({ canAdd: false, error: null }));\n }\n await this._checkVersion();\n const result = await this._invoke('canAddNotesWithErrorDetail', { notes });\n return this._normalizeCanAddNotesWithErrorDetailArray(result, notes.length);\n }\n\n async notesInfo(noteIds: NoteId[]): Promise<(NoteInfo | null)[]> {\n if (!this._enabled) {\n return [];\n }\n await this._checkVersion();\n const result = await this._invoke('notesInfo', { notes: noteIds });\n return this._normalizeNoteInfoArray(result);\n }\n\n async cardsInfo(cardIds: CardId[]): Promise<(CardInfo | null)[]> {\n if (!this._enabled) {\n return [];\n }\n await this._checkVersion();\n const result = await this._invoke('cardsInfo', { cards: cardIds });\n return this._normalizeCardInfoArray(result);\n }\n\n async getDeckNames(): Promise<string[]> {\n if (!this._enabled) {\n return [];\n }\n await this._checkVersion();\n const result = await this._invoke('deckNames', {});\n return this._normalizeArray<string>(result, -1, 'string');\n }\n\n async getModelNames(): Promise<string[]> {\n if (!this._enabled) {\n return [];\n }\n await this._checkVersion();\n const result = await this._invoke('modelNames', {});\n return this._normalizeArray<string>(result, -1, 'string');\n }\n\n async getModelFieldNames(modelName: string): Promise<string[]> {\n if (!this._enabled) {\n return [];\n }\n await this._checkVersion();\n const result = await this._invoke('modelFieldNames', { modelName });\n return this._normalizeArray<string>(result, -1, 'string');\n }\n\n async guiBrowse(query: string): Promise<CardId[]> {\n if (!this._enabled) {\n return [];\n }\n await this._checkVersion();\n const result = await this._invoke('guiBrowse', { query });\n return this._normalizeArray<CardId>(result, -1, 'number');\n }\n\n async guiBrowseNote(noteId: NoteId): Promise<CardId[]> {\n return await this.guiBrowse(`nid:${noteId}`);\n }\n\n async guiBrowseNotes(noteIds: NoteId[]): Promise<CardId[]> {\n return await this.guiBrowse(`nid:${noteIds.join(',')}`);\n }\n\n async guiEditNote(noteId: NoteId): Promise<void> {\n await this._invoke('guiEditNote', { note: noteId });\n }\n\n /**\n * Stores a file with the specified base64-encoded content inside Anki's media folder.\n */\n async storeMediaFile(fileName: string, content: string): Promise<string | null> {\n if (!this._enabled) {\n throw new Error('AnkiConnect not enabled');\n }\n await this._checkVersion();\n const result = await this._invoke('storeMediaFile', { filename: fileName, data: content });\n if (result !== null && typeof result !== 'string') {\n throw this._createUnexpectedResultError('string|null', result);\n }\n return result as string | null;\n }\n\n /**\n * Finds notes matching a query.\n */\n async findNotes(query: string): Promise<NoteId[]> {\n if (!this._enabled) {\n return [];\n }\n await this._checkVersion();\n const result = await this._invoke('findNotes', { query });\n return this._normalizeArray<NoteId>(result, -1, 'number');\n }\n\n async findNoteIds(notes: Note[]): Promise<NoteId[][]> {\n if (!this._enabled) {\n return [];\n }\n await this._checkVersion();\n\n const actions: { action: string; params: Record<string, unknown> }[] = [];\n const actionsTargetsList: NoteId[][][] = [];\n const actionsTargetsMap = new Map<string, NoteId[][]>();\n const allNoteIds: NoteId[][] = [];\n\n for (const note of notes) {\n const query = this._getNoteQuery(note);\n let actionsTargets = actionsTargetsMap.get(query);\n if (typeof actionsTargets === 'undefined') {\n actionsTargets = [];\n actionsTargetsList.push(actionsTargets);\n actionsTargetsMap.set(query, actionsTargets);\n actions.push({ action: 'findNotes', params: { query } });\n }\n const noteIds: NoteId[] = [];\n allNoteIds.push(noteIds);\n actionsTargets.push(noteIds);\n }\n\n const result = await this._invokeMulti(actions);\n for (let i = 0, ii = Math.min(result.length, actionsTargetsList.length); i < ii; ++i) {\n const noteIds = this._normalizeArray<number>(result[i], -1, 'number');\n for (const actionsTargets of actionsTargetsList[i]) {\n for (const noteId of noteIds) {\n actionsTargets.push(noteId);\n }\n }\n }\n return allNoteIds;\n }\n\n async suspendCards(cardIds: CardId[]): Promise<boolean> {\n if (!this._enabled) {\n return false;\n }\n await this._checkVersion();\n const result = await this._invoke('suspend', { cards: cardIds });\n return typeof result === 'boolean' && result;\n }\n\n async findCards(query: string): Promise<CardId[]> {\n if (!this._enabled) {\n return [];\n }\n await this._checkVersion();\n const result = await this._invoke('findCards', { query });\n return this._normalizeArray<CardId>(result, -1, 'number');\n }\n\n async findCardsForNote(noteId: NoteId): Promise<CardId[]> {\n return await this.findCards(`nid:${noteId}`);\n }\n\n /**\n * Gets information about the AnkiConnect APIs available.\n */\n async apiReflect(scopes: string[], actions: string[] | null = null): Promise<ApiReflectResult> {\n const result = await this._invoke('apiReflect', { scopes, actions });\n if (!(typeof result === 'object' && result !== null)) {\n throw this._createUnexpectedResultError('object', result);\n }\n const { scopes: resultScopes, actions: resultActions } = result as Record<string, unknown>;\n const resultScopes2 = this._normalizeArray<string>(resultScopes, -1, 'string', ', field scopes');\n const resultActions2 = this._normalizeArray<string>(resultActions, -1, 'string', ', field actions');\n return {\n scopes: resultScopes2,\n actions: resultActions2,\n };\n }\n\n /**\n * Checks whether a specific API action exists.\n */\n async apiExists(action: string): Promise<boolean> {\n const { actions } = await this.apiReflect(['actions'], [action]);\n return actions.includes(action);\n }\n\n /**\n * Checks if a specific error object corresponds to an unsupported action.\n */\n isErrorUnsupportedAction(error: Error): boolean {\n if (error instanceof YomitanError) {\n const { data } = error;\n if (\n typeof data === 'object' &&\n data !== null &&\n (data as Record<string, unknown>).apiError === 'unsupported action'\n ) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Makes Anki sync.\n */\n async makeAnkiSync(): Promise<unknown | null> {\n if (!this._enabled) {\n return null;\n }\n const version = await this._checkVersion();\n const result = await this._invoke('sync', { version });\n return result === null;\n }\n\n // Private\n\n private async _checkVersion(): Promise<void> {\n if (this._remoteVersion < this._localVersion) {\n if (this._versionCheckPromise === null) {\n const promise = this._getVersion();\n promise\n .catch(() => {})\n .finally(() => {\n this._versionCheckPromise = null;\n });\n this._versionCheckPromise = promise;\n }\n this._remoteVersion = await this._versionCheckPromise;\n if (this._remoteVersion < this._localVersion) {\n throw new Error('Extension and plugin versions incompatible');\n }\n }\n }\n\n private async _invoke(action: string, params: Record<string, unknown>): Promise<unknown> {\n const body: MessageBody = { action, params, version: this._localVersion };\n if (this._apiKey !== null) {\n body.key = this._apiKey;\n }\n let response: Response;\n try {\n if (this._server === null) {\n throw new Error('Server URL is null');\n }\n response = await fetch(this._server, {\n method: 'POST',\n mode: 'cors',\n cache: 'default',\n credentials: 'omit',\n headers: {\n 'Content-Type': 'application/json',\n },\n redirect: 'follow',\n referrerPolicy: 'no-referrer',\n body: JSON.stringify(body),\n });\n } catch (e) {\n const error = new YomitanError('Anki connection failure');\n error.data = { action, params, originalError: e };\n throw error;\n }\n\n if (!response.ok) {\n const error = new YomitanError(`Anki connection error: ${response.status}`);\n error.data = { action, params, status: response.status };\n throw error;\n }\n\n let responseText: string | null = null;\n let result: unknown;\n try {\n responseText = await response.text();\n result = parseJson(responseText);\n } catch (e) {\n const error = new YomitanError('Invalid Anki response');\n error.data = { action, params, status: response.status, responseText, originalError: e };\n throw error;\n }\n\n if (typeof result === 'object' && result !== null && !Array.isArray(result)) {\n const apiError = (result as Record<string, unknown>).error;\n if (typeof apiError !== 'undefined') {\n const error = new YomitanError(`Anki error: ${apiError}`);\n error.data = {\n action,\n params,\n status: response.status,\n apiError: typeof apiError === 'string' ? apiError : `${apiError}`,\n };\n throw error;\n }\n }\n\n return result;\n }\n\n private async _invokeMulti(actions: { action: string; params: Record<string, unknown> }[]): Promise<unknown[]> {\n const result = await this._invoke('multi', { actions });\n if (!Array.isArray(result)) {\n throw this._createUnexpectedResultError('array', result);\n }\n return result as unknown[];\n }\n\n private _escapeQuery(text: string): string {\n return text.replace(/\"/g, '');\n }\n\n private _fieldsToQuery(fields: Record<string, string>): string {\n const fieldNames = Object.keys(fields);\n if (fieldNames.length === 0) {\n return '';\n }\n\n const key = fieldNames[0];\n return `\"${key.toLowerCase()}:${this._escapeQuery(fields[key])}\"`;\n }\n\n private _getDuplicateScopeFromNote(note: Note): 'collection' | 'deck' | 'deck-root' | null {\n const { options } = note;\n if (typeof options === 'object' && options !== null) {\n const { duplicateScope } = options;\n if (typeof duplicateScope !== 'undefined') {\n return duplicateScope as 'collection' | 'deck' | 'deck-root';\n }\n }\n return null;\n }\n\n private _getNoteQuery(note: Note): string {\n let query = '';\n switch (this._getDuplicateScopeFromNote(note)) {\n case 'deck':\n query = `\"deck:${this._escapeQuery(note.deckName)}\" `;\n break;\n case 'deck-root':\n query = `\"deck:${this._escapeQuery(getRootDeckName(note.deckName))}\" `;\n break;\n }\n query += this._fieldsToQuery(note.fields);\n return query;\n }\n\n private async _getVersion(): Promise<number> {\n const version = await this._invoke('version', {});\n return typeof version === 'number' ? version : 0;\n }\n\n private _createError(message: string, data: unknown): YomitanError {\n return new YomitanError(message, data);\n }\n\n private _createUnexpectedResultError(expectedType: string, result: unknown, context?: string): YomitanError {\n return this._createError(\n `Unexpected type${typeof context === 'string' ? context : ''}: expected ${expectedType}, received ${this._getTypeName(result)}`,\n result,\n );\n }\n\n private _getTypeName(value: unknown): string {\n if (value === null) {\n return 'null';\n }\n return Array.isArray(value) ? 'array' : typeof value;\n }\n\n private _normalizeArray<T = unknown>(\n result: unknown,\n expectedCount: number,\n type: 'boolean' | 'string' | 'number',\n context?: string,\n ): T[] {\n if (!Array.isArray(result)) {\n throw this._createUnexpectedResultError(`${type}[]`, result, context);\n }\n if (expectedCount < 0) {\n expectedCount = result.length;\n } else if (expectedCount !== result.length) {\n throw this._createError(\n `Unexpected result array size${context ?? ''}: expected ${expectedCount}, received ${result.length}`,\n result,\n );\n }\n for (let i = 0; i < expectedCount; ++i) {\n const item = result[i] as unknown;\n if (typeof item !== type) {\n throw this._createError(\n `Unexpected result type at index ${i}${context ?? ''}: expected ${type}, received ${this._getTypeName(item)}`,\n result,\n );\n }\n }\n return result as T[];\n }\n\n private _normalizeNoteInfoArray(result: unknown): (NoteInfo | null)[] {\n if (!Array.isArray(result)) {\n throw this._createUnexpectedResultError('array', result, '');\n }\n const result2: (NoteInfo | null)[] = [];\n for (let i = 0, ii = result.length; i < ii; ++i) {\n const item = result[i] as unknown;\n if (item === null || typeof item !== 'object') {\n throw this._createError(\n `Unexpected result type at index ${i}: expected Notes.NoteInfo, received ${this._getTypeName(item)}`,\n result,\n );\n }\n const { noteId } = item as Record<string, unknown>;\n if (typeof noteId !== 'number') {\n result2.push(null);\n continue;\n }\n\n const { tags, fields, modelName, cards } = item as Record<string, unknown>;\n if (typeof modelName !== 'string') {\n throw this._createError(\n `Unexpected result type at index ${i}, field modelName: expected string, received ${this._getTypeName(modelName)}`,\n result,\n );\n }\n if (!isObjectNotArray(fields)) {\n throw this._createError(\n `Unexpected result type at index ${i}, field fields: expected object, received ${this._getTypeName(fields)}`,\n result,\n );\n }\n const tags2 = this._normalizeArray<string>(tags, -1, 'string', ', field tags');\n const cards2 = this._normalizeArray<number>(cards, -1, 'number', ', field cards');\n const fields2: { [key: string]: NoteFieldInfo } = {};\n for (const [key, fieldInfo] of Object.entries(fields)) {\n if (!isObjectNotArray(fieldInfo)) {\n continue;\n }\n const { value, order } = fieldInfo;\n if (typeof value !== 'string' || typeof order !== 'number') {\n continue;\n }\n fields2[key] = { value, order };\n }\n const item2: NoteInfo = {\n noteId,\n tags: tags2,\n fields: fields2,\n modelName,\n cards: cards2,\n cardsInfo: [],\n };\n result2.push(item2);\n }\n return result2;\n }\n\n private _normalizeCardInfoArray(result: unknown): (CardInfo | null)[] {\n if (!Array.isArray(result)) {\n throw this._createUnexpectedResultError('array', result, '');\n }\n const result2: (CardInfo | null)[] = [];\n for (let i = 0, ii = result.length; i < ii; ++i) {\n const item = result[i] as unknown;\n if (item === null || typeof item !== 'object') {\n throw this._createError(\n `Unexpected result type at index ${i}: expected Cards.CardInfo, received ${this._getTypeName(item)}`,\n result,\n );\n }\n const { cardId } = item as Record<string, unknown>;\n if (typeof cardId !== 'number') {\n result2.push(null);\n continue;\n }\n const { note, flags, queue } = item as Record<string, unknown>;\n if (typeof note !== 'number') {\n result2.push(null);\n continue;\n }\n\n const item2: CardInfo = {\n noteId: note,\n cardId,\n flags: typeof flags === 'number' ? flags : 0,\n cardState: typeof queue === 'number' ? queue : 0,\n };\n result2.push(item2);\n }\n return result2;\n }\n\n private _normalizeCanAddNotesWithErrorDetailArray(result: unknown, expectedCount: number): CanAddNotesDetail[] {\n if (!Array.isArray(result)) {\n throw this._createUnexpectedResultError('array', result, '');\n }\n if (expectedCount !== result.length) {\n throw this._createError(\n `Unexpected result array size: expected ${expectedCount}, received ${result.length}`,\n result,\n );\n }\n const result2: CanAddNotesDetail[] = [];\n for (let i = 0; i < expectedCount; ++i) {\n const item = result[i] as unknown;\n if (item === null || typeof item !== 'object') {\n throw this._createError(\n `Unexpected result type at index ${i}: expected object, received ${this._getTypeName(item)}`,\n result,\n );\n }\n\n const { canAdd, error } = item as Record<string, unknown>;\n if (typeof canAdd !== 'boolean') {\n throw this._createError(\n `Unexpected result type at index ${i}, field canAdd: expected boolean, received ${this._getTypeName(canAdd)}`,\n result,\n );\n }\n\n const item2 = {\n canAdd,\n error: typeof error === 'string' ? error : null,\n };\n\n result2.push(item2);\n }\n return result2;\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"anki-connect-DGx7Gr0H.cjs","names":["deckName: string","global: boolean","config?: { server?: string; apiKey?: string }","value: string","value: boolean","value: string | null","note: Note","notes: Note[]","noteWithId: Note & { id?: NoteId }","noteIds: NoteId[]","cardIds: CardId[]","modelName: string","query: string","noteId: NoteId","fileName: string","content: string","actions: { action: string; params: Record<string, unknown> }[]","actionsTargetsList: NoteId[][][]","allNoteIds: NoteId[][]","scopes: string[]","actions: string[] | null","action: string","error: Error","YomitanError","params: Record<string, unknown>","body: MessageBody","response: Response","responseText: string | null","result: unknown","text: string","fields: Record<string, string>","message: string","data: unknown","expectedType: string","context?: string","value: unknown","expectedCount: number","type: 'boolean' | 'string' | 'number'","result2: (NoteInfo | null)[]","fields2: { [key: string]: NoteFieldInfo }","item2: NoteInfo","result2: (CardInfo | null)[]","item2: CardInfo","result2: CanAddNotesDetail[]"],"sources":["../src/util/anki-util.ts","../src/anki/anki-connect.ts"],"sourcesContent":["const markerPattern = /\\{([\\p{Letter}\\p{Number}_-]+)\\}/gu;\n\n/**\n * Gets the root deck name of a full deck name.\n */\nexport function getRootDeckName(deckName: string): string {\n const index = deckName.indexOf('::');\n return index >= 0 ? deckName.substring(0, index) : deckName;\n}\n\n/**\n * Checks whether or not any marker is contained in a string.\n */\nexport function stringContainsAnyFieldMarker(string: string): boolean {\n const result = markerPattern.test(string);\n markerPattern.lastIndex = 0;\n return result;\n}\n\n/**\n * Gets a list of all markers that are contained in a string.\n */\nexport function getFieldMarkers(string: string): string[] {\n const pattern = markerPattern;\n const markers: string[] = [];\n while (true) {\n const match = pattern.exec(string);\n if (match === null) {\n break;\n }\n markers.push(match[1]);\n }\n return markers;\n}\n\n/**\n * Returns a regular expression which can be used to find markers in a string.\n */\nexport function cloneFieldMarkerPattern(global: boolean): RegExp {\n return new RegExp(markerPattern.source, global ? 'gu' : 'u');\n}\n\n/**\n * Checks whether or not a note object is valid.\n */\nexport function isNoteDataValid(note: {\n fields: Record<string, string>;\n deckName: string;\n modelName: string;\n}): boolean {\n const { fields, deckName, modelName } = note;\n return (\n typeof deckName === 'string' &&\n deckName.length > 0 &&\n typeof modelName === 'string' &&\n modelName.length > 0 &&\n Object.entries(fields).length > 0\n );\n}\n\nexport const INVALID_NOTE_ID = -1;\n\n/**\n * Generates a file name for Anki note media.\n */\nexport function generateAnkiNoteMediaFileName(prefix: string, extension: string, timestamp: number): string {\n let fileName = prefix;\n fileName += `_${ankNoteDateToString(new Date(timestamp))}`;\n fileName += extension;\n fileName = replaceInvalidFileNameCharacters(fileName);\n return fileName;\n}\n\nfunction replaceInvalidFileNameCharacters(fileName: string): string {\n // eslint-disable-next-line no-control-regex\n return fileName.replace(/[<>:\"/\\\\|?*\\u0000-\\u001F]/g, '-');\n}\n\nfunction ankNoteDateToString(date: Date): string {\n const year = date.getUTCFullYear();\n const month = date.getUTCMonth().toString().padStart(2, '0');\n const day = date.getUTCDate().toString().padStart(2, '0');\n const hours = date.getUTCHours().toString().padStart(2, '0');\n const minutes = date.getUTCMinutes().toString().padStart(2, '0');\n const seconds = date.getUTCSeconds().toString().padStart(2, '0');\n const milliseconds = date.getUTCMilliseconds().toString().padStart(3, '0');\n return `${year}-${month}-${day}-${hours}-${minutes}-${seconds}-${milliseconds}`;\n}\n","import type {\n ApiReflectResult,\n CanAddNotesDetail,\n CardId,\n CardInfo,\n MessageBody,\n Note,\n NoteFieldInfo,\n NoteId,\n NoteInfo,\n} from '../types/anki';\nimport { getRootDeckName } from '../util/anki-util';\nimport { YomitanError } from '../util/errors';\nimport { parseJson } from '../util/json';\nimport { isObjectNotArray } from '../util/utilities';\n\n/**\n * This class controls communication with Anki via the AnkiConnect plugin.\n */\nexport class AnkiConnect {\n private _enabled: boolean;\n private _server: string | null;\n private _localVersion: number;\n private _remoteVersion: number;\n private _versionCheckPromise: Promise<number> | null;\n private _apiKey: string | null;\n\n constructor(config?: { server?: string; apiKey?: string }) {\n this._enabled = false;\n this._server = config?.server ?? null;\n this._localVersion = 2;\n this._remoteVersion = 0;\n this._versionCheckPromise = null;\n this._apiKey = config?.apiKey ?? null;\n }\n\n get server(): string | null {\n return this._server;\n }\n\n set server(value: string) {\n this._server = value;\n }\n\n get enabled(): boolean {\n return this._enabled;\n }\n\n set enabled(value: boolean) {\n this._enabled = value;\n }\n\n get apiKey(): string | null {\n return this._apiKey;\n }\n\n set apiKey(value: string | null) {\n this._apiKey = value;\n }\n\n /**\n * Checks whether a connection to AnkiConnect can be established.\n */\n async isConnected(): Promise<boolean> {\n try {\n await this._getVersion();\n return true;\n } catch (_e) {\n return false;\n }\n }\n\n /**\n * Gets the AnkiConnect API version number.\n */\n async getVersion(): Promise<number | null> {\n if (!this._enabled) {\n return null;\n }\n await this._checkVersion();\n return await this._getVersion();\n }\n\n async addNote(note: Note): Promise<NoteId | null> {\n if (!this._enabled) {\n return null;\n }\n await this._checkVersion();\n const result = await this._invoke('addNote', { note });\n if (result !== null && typeof result !== 'number') {\n throw this._createUnexpectedResultError('number|null', result);\n }\n return result as NoteId | null;\n }\n\n async addNotes(notes: Note[]): Promise<(number | null)[] | null> {\n if (!this._enabled) {\n return null;\n }\n await this._checkVersion();\n const result = await this._invoke('addNotes', { notes });\n if (result !== null && !Array.isArray(result)) {\n throw this._createUnexpectedResultError('(number | null)[] | null', result);\n }\n return result as (number | null)[] | null;\n }\n\n async updateNoteFields(noteWithId: Note & { id?: NoteId }): Promise<null> {\n if (!this._enabled) {\n return null;\n }\n await this._checkVersion();\n const result = await this._invoke('updateNoteFields', { note: noteWithId });\n if (result !== null) {\n throw this._createUnexpectedResultError('null', result);\n }\n return result;\n }\n\n async canAddNotes(notes: Note[]): Promise<boolean[]> {\n if (!this._enabled) {\n return new Array(notes.length).fill(false) as boolean[];\n }\n await this._checkVersion();\n const result = await this._invoke('canAddNotes', { notes });\n return this._normalizeArray<boolean>(result, notes.length, 'boolean');\n }\n\n async canAddNotesWithErrorDetail(notes: Note[]): Promise<CanAddNotesDetail[]> {\n if (!this._enabled) {\n return notes.map(() => ({ canAdd: false, error: null }));\n }\n await this._checkVersion();\n const result = await this._invoke('canAddNotesWithErrorDetail', { notes });\n return this._normalizeCanAddNotesWithErrorDetailArray(result, notes.length);\n }\n\n async notesInfo(noteIds: NoteId[]): Promise<(NoteInfo | null)[]> {\n if (!this._enabled) {\n return [];\n }\n await this._checkVersion();\n const result = await this._invoke('notesInfo', { notes: noteIds });\n return this._normalizeNoteInfoArray(result);\n }\n\n async cardsInfo(cardIds: CardId[]): Promise<(CardInfo | null)[]> {\n if (!this._enabled) {\n return [];\n }\n await this._checkVersion();\n const result = await this._invoke('cardsInfo', { cards: cardIds });\n return this._normalizeCardInfoArray(result);\n }\n\n async getDeckNames(): Promise<string[]> {\n if (!this._enabled) {\n return [];\n }\n await this._checkVersion();\n const result = await this._invoke('deckNames', {});\n return this._normalizeArray<string>(result, -1, 'string');\n }\n\n async getModelNames(): Promise<string[]> {\n if (!this._enabled) {\n return [];\n }\n await this._checkVersion();\n const result = await this._invoke('modelNames', {});\n return this._normalizeArray<string>(result, -1, 'string');\n }\n\n async getModelFieldNames(modelName: string): Promise<string[]> {\n if (!this._enabled) {\n return [];\n }\n await this._checkVersion();\n const result = await this._invoke('modelFieldNames', { modelName });\n return this._normalizeArray<string>(result, -1, 'string');\n }\n\n async guiBrowse(query: string): Promise<CardId[]> {\n if (!this._enabled) {\n return [];\n }\n await this._checkVersion();\n const result = await this._invoke('guiBrowse', { query });\n return this._normalizeArray<CardId>(result, -1, 'number');\n }\n\n async guiBrowseNote(noteId: NoteId): Promise<CardId[]> {\n return await this.guiBrowse(`nid:${noteId}`);\n }\n\n async guiBrowseNotes(noteIds: NoteId[]): Promise<CardId[]> {\n return await this.guiBrowse(`nid:${noteIds.join(',')}`);\n }\n\n async guiEditNote(noteId: NoteId): Promise<void> {\n await this._invoke('guiEditNote', { note: noteId });\n }\n\n /**\n * Stores a file with the specified base64-encoded content inside Anki's media folder.\n */\n async storeMediaFile(fileName: string, content: string): Promise<string | null> {\n if (!this._enabled) {\n throw new Error('AnkiConnect not enabled');\n }\n await this._checkVersion();\n const result = await this._invoke('storeMediaFile', { filename: fileName, data: content });\n if (result !== null && typeof result !== 'string') {\n throw this._createUnexpectedResultError('string|null', result);\n }\n return result as string | null;\n }\n\n /**\n * Finds notes matching a query.\n */\n async findNotes(query: string): Promise<NoteId[]> {\n if (!this._enabled) {\n return [];\n }\n await this._checkVersion();\n const result = await this._invoke('findNotes', { query });\n return this._normalizeArray<NoteId>(result, -1, 'number');\n }\n\n async findNoteIds(notes: Note[]): Promise<NoteId[][]> {\n if (!this._enabled) {\n return [];\n }\n await this._checkVersion();\n\n const actions: { action: string; params: Record<string, unknown> }[] = [];\n const actionsTargetsList: NoteId[][][] = [];\n const actionsTargetsMap = new Map<string, NoteId[][]>();\n const allNoteIds: NoteId[][] = [];\n\n for (const note of notes) {\n const query = this._getNoteQuery(note);\n let actionsTargets = actionsTargetsMap.get(query);\n if (typeof actionsTargets === 'undefined') {\n actionsTargets = [];\n actionsTargetsList.push(actionsTargets);\n actionsTargetsMap.set(query, actionsTargets);\n actions.push({ action: 'findNotes', params: { query } });\n }\n const noteIds: NoteId[] = [];\n allNoteIds.push(noteIds);\n actionsTargets.push(noteIds);\n }\n\n const result = await this._invokeMulti(actions);\n for (let i = 0, ii = Math.min(result.length, actionsTargetsList.length); i < ii; ++i) {\n const noteIds = this._normalizeArray<number>(result[i], -1, 'number');\n for (const actionsTargets of actionsTargetsList[i]) {\n for (const noteId of noteIds) {\n actionsTargets.push(noteId);\n }\n }\n }\n return allNoteIds;\n }\n\n async suspendCards(cardIds: CardId[]): Promise<boolean> {\n if (!this._enabled) {\n return false;\n }\n await this._checkVersion();\n const result = await this._invoke('suspend', { cards: cardIds });\n return typeof result === 'boolean' && result;\n }\n\n async findCards(query: string): Promise<CardId[]> {\n if (!this._enabled) {\n return [];\n }\n await this._checkVersion();\n const result = await this._invoke('findCards', { query });\n return this._normalizeArray<CardId>(result, -1, 'number');\n }\n\n async findCardsForNote(noteId: NoteId): Promise<CardId[]> {\n return await this.findCards(`nid:${noteId}`);\n }\n\n /**\n * Gets information about the AnkiConnect APIs available.\n */\n async apiReflect(scopes: string[], actions: string[] | null = null): Promise<ApiReflectResult> {\n const result = await this._invoke('apiReflect', { scopes, actions });\n if (!(typeof result === 'object' && result !== null)) {\n throw this._createUnexpectedResultError('object', result);\n }\n const { scopes: resultScopes, actions: resultActions } = result as Record<string, unknown>;\n const resultScopes2 = this._normalizeArray<string>(resultScopes, -1, 'string', ', field scopes');\n const resultActions2 = this._normalizeArray<string>(resultActions, -1, 'string', ', field actions');\n return {\n scopes: resultScopes2,\n actions: resultActions2,\n };\n }\n\n /**\n * Checks whether a specific API action exists.\n */\n async apiExists(action: string): Promise<boolean> {\n const { actions } = await this.apiReflect(['actions'], [action]);\n return actions.includes(action);\n }\n\n /**\n * Checks if a specific error object corresponds to an unsupported action.\n */\n isErrorUnsupportedAction(error: Error): boolean {\n if (error instanceof YomitanError) {\n const { data } = error;\n if (\n typeof data === 'object' &&\n data !== null &&\n (data as Record<string, unknown>).apiError === 'unsupported action'\n ) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Makes Anki sync.\n */\n async makeAnkiSync(): Promise<unknown | null> {\n if (!this._enabled) {\n return null;\n }\n const version = await this._checkVersion();\n const result = await this._invoke('sync', { version });\n return result === null;\n }\n\n // Private\n\n private async _checkVersion(): Promise<void> {\n if (this._remoteVersion < this._localVersion) {\n if (this._versionCheckPromise === null) {\n const promise = this._getVersion();\n promise\n .catch(() => {})\n .finally(() => {\n this._versionCheckPromise = null;\n });\n this._versionCheckPromise = promise;\n }\n this._remoteVersion = await this._versionCheckPromise;\n if (this._remoteVersion < this._localVersion) {\n throw new Error('Extension and plugin versions incompatible');\n }\n }\n }\n\n private async _invoke(action: string, params: Record<string, unknown>): Promise<unknown> {\n const body: MessageBody = { action, params, version: this._localVersion };\n if (this._apiKey !== null) {\n body.key = this._apiKey;\n }\n let response: Response;\n try {\n if (this._server === null) {\n throw new Error('Server URL is null');\n }\n response = await fetch(this._server, {\n method: 'POST',\n mode: 'cors',\n cache: 'default',\n credentials: 'omit',\n headers: {\n 'Content-Type': 'application/json',\n },\n redirect: 'follow',\n referrerPolicy: 'no-referrer',\n body: JSON.stringify(body),\n });\n } catch (e) {\n const error = new YomitanError('Anki connection failure');\n error.data = { action, params, originalError: e };\n throw error;\n }\n\n if (!response.ok) {\n const error = new YomitanError(`Anki connection error: ${response.status}`);\n error.data = { action, params, status: response.status };\n throw error;\n }\n\n let responseText: string | null = null;\n let result: unknown;\n try {\n responseText = await response.text();\n result = parseJson(responseText);\n } catch (e) {\n const error = new YomitanError('Invalid Anki response');\n error.data = { action, params, status: response.status, responseText, originalError: e };\n throw error;\n }\n\n if (typeof result === 'object' && result !== null && !Array.isArray(result)) {\n const apiError = (result as Record<string, unknown>).error;\n if (typeof apiError !== 'undefined') {\n const error = new YomitanError(`Anki error: ${apiError}`);\n error.data = {\n action,\n params,\n status: response.status,\n apiError: typeof apiError === 'string' ? apiError : `${apiError}`,\n };\n throw error;\n }\n }\n\n return result;\n }\n\n private async _invokeMulti(actions: { action: string; params: Record<string, unknown> }[]): Promise<unknown[]> {\n const result = await this._invoke('multi', { actions });\n if (!Array.isArray(result)) {\n throw this._createUnexpectedResultError('array', result);\n }\n return result as unknown[];\n }\n\n private _escapeQuery(text: string): string {\n return text.replace(/\"/g, '');\n }\n\n private _fieldsToQuery(fields: Record<string, string>): string {\n const fieldNames = Object.keys(fields);\n if (fieldNames.length === 0) {\n return '';\n }\n\n const key = fieldNames[0];\n return `\"${key.toLowerCase()}:${this._escapeQuery(fields[key])}\"`;\n }\n\n private _getDuplicateScopeFromNote(note: Note): 'collection' | 'deck' | 'deck-root' | null {\n const { options } = note;\n if (typeof options === 'object' && options !== null) {\n const { duplicateScope } = options;\n if (typeof duplicateScope !== 'undefined') {\n return duplicateScope as 'collection' | 'deck' | 'deck-root';\n }\n }\n return null;\n }\n\n private _getNoteQuery(note: Note): string {\n let query = '';\n switch (this._getDuplicateScopeFromNote(note)) {\n case 'deck':\n query = `\"deck:${this._escapeQuery(note.deckName)}\" `;\n break;\n case 'deck-root':\n query = `\"deck:${this._escapeQuery(getRootDeckName(note.deckName))}\" `;\n break;\n }\n query += this._fieldsToQuery(note.fields);\n return query;\n }\n\n private async _getVersion(): Promise<number> {\n const version = await this._invoke('version', {});\n return typeof version === 'number' ? version : 0;\n }\n\n private _createError(message: string, data: unknown): YomitanError {\n return new YomitanError(message, data);\n }\n\n private _createUnexpectedResultError(expectedType: string, result: unknown, context?: string): YomitanError {\n return this._createError(\n `Unexpected type${typeof context === 'string' ? context : ''}: expected ${expectedType}, received ${this._getTypeName(result)}`,\n result,\n );\n }\n\n private _getTypeName(value: unknown): string {\n if (value === null) {\n return 'null';\n }\n return Array.isArray(value) ? 'array' : typeof value;\n }\n\n private _normalizeArray<T = unknown>(\n result: unknown,\n expectedCount: number,\n type: 'boolean' | 'string' | 'number',\n context?: string,\n ): T[] {\n if (!Array.isArray(result)) {\n throw this._createUnexpectedResultError(`${type}[]`, result, context);\n }\n if (expectedCount < 0) {\n expectedCount = result.length;\n } else if (expectedCount !== result.length) {\n throw this._createError(\n `Unexpected result array size${context ?? ''}: expected ${expectedCount}, received ${result.length}`,\n result,\n );\n }\n for (let i = 0; i < expectedCount; ++i) {\n const item = result[i] as unknown;\n if (typeof item !== type) {\n throw this._createError(\n `Unexpected result type at index ${i}${context ?? ''}: expected ${type}, received ${this._getTypeName(item)}`,\n result,\n );\n }\n }\n return result as T[];\n }\n\n private _normalizeNoteInfoArray(result: unknown): (NoteInfo | null)[] {\n if (!Array.isArray(result)) {\n throw this._createUnexpectedResultError('array', result, '');\n }\n const result2: (NoteInfo | null)[] = [];\n for (let i = 0, ii = result.length; i < ii; ++i) {\n const item = result[i] as unknown;\n if (item === null || typeof item !== 'object') {\n throw this._createError(\n `Unexpected result type at index ${i}: expected Notes.NoteInfo, received ${this._getTypeName(item)}`,\n result,\n );\n }\n const { noteId } = item as Record<string, unknown>;\n if (typeof noteId !== 'number') {\n result2.push(null);\n continue;\n }\n\n const { tags, fields, modelName, cards } = item as Record<string, unknown>;\n if (typeof modelName !== 'string') {\n throw this._createError(\n `Unexpected result type at index ${i}, field modelName: expected string, received ${this._getTypeName(modelName)}`,\n result,\n );\n }\n if (!isObjectNotArray(fields)) {\n throw this._createError(\n `Unexpected result type at index ${i}, field fields: expected object, received ${this._getTypeName(fields)}`,\n result,\n );\n }\n const tags2 = this._normalizeArray<string>(tags, -1, 'string', ', field tags');\n const cards2 = this._normalizeArray<number>(cards, -1, 'number', ', field cards');\n const fields2: { [key: string]: NoteFieldInfo } = {};\n for (const [key, fieldInfo] of Object.entries(fields)) {\n if (!isObjectNotArray(fieldInfo)) {\n continue;\n }\n const { value, order } = fieldInfo;\n if (typeof value !== 'string' || typeof order !== 'number') {\n continue;\n }\n fields2[key] = { value, order };\n }\n const item2: NoteInfo = {\n noteId,\n tags: tags2,\n fields: fields2,\n modelName,\n cards: cards2,\n cardsInfo: [],\n };\n result2.push(item2);\n }\n return result2;\n }\n\n private _normalizeCardInfoArray(result: unknown): (CardInfo | null)[] {\n if (!Array.isArray(result)) {\n throw this._createUnexpectedResultError('array', result, '');\n }\n const result2: (CardInfo | null)[] = [];\n for (let i = 0, ii = result.length; i < ii; ++i) {\n const item = result[i] as unknown;\n if (item === null || typeof item !== 'object') {\n throw this._createError(\n `Unexpected result type at index ${i}: expected Cards.CardInfo, received ${this._getTypeName(item)}`,\n result,\n );\n }\n const { cardId } = item as Record<string, unknown>;\n if (typeof cardId !== 'number') {\n result2.push(null);\n continue;\n }\n const { note, flags, queue } = item as Record<string, unknown>;\n if (typeof note !== 'number') {\n result2.push(null);\n continue;\n }\n\n const item2: CardInfo = {\n noteId: note,\n cardId,\n flags: typeof flags === 'number' ? flags : 0,\n cardState: typeof queue === 'number' ? queue : 0,\n };\n result2.push(item2);\n }\n return result2;\n }\n\n private _normalizeCanAddNotesWithErrorDetailArray(result: unknown, expectedCount: number): CanAddNotesDetail[] {\n if (!Array.isArray(result)) {\n throw this._createUnexpectedResultError('array', result, '');\n }\n if (expectedCount !== result.length) {\n throw this._createError(\n `Unexpected result array size: expected ${expectedCount}, received ${result.length}`,\n result,\n );\n }\n const result2: CanAddNotesDetail[] = [];\n for (let i = 0; i < expectedCount; ++i) {\n const item = result[i] as unknown;\n if (item === null || typeof item !== 'object') {\n throw this._createError(\n `Unexpected result type at index ${i}: expected object, received ${this._getTypeName(item)}`,\n result,\n );\n }\n\n const { canAdd, error } = item as Record<string, unknown>;\n if (typeof canAdd !== 'boolean') {\n throw this._createError(\n `Unexpected result type at index ${i}, field canAdd: expected boolean, received ${this._getTypeName(canAdd)}`,\n result,\n );\n }\n\n const item2 = {\n canAdd,\n error: typeof error === 'string' ? error : null,\n };\n\n result2.push(item2);\n }\n return result2;\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { isObjectNotArray } from "./utilities-bi3EF-q5.js";
|
|
2
|
-
import { YomitanError } from "./errors-
|
|
3
|
-
import { parseJson } from "./json-
|
|
2
|
+
import { YomitanError } from "./errors-DvKlMRXC.js";
|
|
3
|
+
import { parseJson } from "./json-rIgOFqVY.js";
|
|
4
4
|
|
|
5
5
|
//#region src/util/anki-util.ts
|
|
6
6
|
const markerPattern = /\{([\p{Letter}\p{Number}_-]+)\}/gu;
|
|
@@ -492,4 +492,4 @@ var AnkiConnect = class {
|
|
|
492
492
|
|
|
493
493
|
//#endregion
|
|
494
494
|
export { AnkiConnect, cloneFieldMarkerPattern, getRootDeckName };
|
|
495
|
-
//# sourceMappingURL=anki-connect-
|
|
495
|
+
//# sourceMappingURL=anki-connect-Dau8nAXZ.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"anki-connect-697E04LF.js","names":["deckName: string","global: boolean","config?: { server?: string; apiKey?: string }","value: string","value: boolean","value: string | null","note: Note","notes: Note[]","noteWithId: Note & { id?: NoteId }","noteIds: NoteId[]","cardIds: CardId[]","modelName: string","query: string","noteId: NoteId","fileName: string","content: string","actions: { action: string; params: Record<string, unknown> }[]","actionsTargetsList: NoteId[][][]","allNoteIds: NoteId[][]","scopes: string[]","actions: string[] | null","action: string","error: Error","params: Record<string, unknown>","body: MessageBody","response: Response","responseText: string | null","result: unknown","text: string","fields: Record<string, string>","message: string","data: unknown","expectedType: string","context?: string","value: unknown","expectedCount: number","type: 'boolean' | 'string' | 'number'","result2: (NoteInfo | null)[]","fields2: { [key: string]: NoteFieldInfo }","item2: NoteInfo","result2: (CardInfo | null)[]","item2: CardInfo","result2: CanAddNotesDetail[]"],"sources":["../src/util/anki-util.ts","../src/anki/anki-connect.ts"],"sourcesContent":["const markerPattern = /\\{([\\p{Letter}\\p{Number}_-]+)\\}/gu;\n\n/**\n * Gets the root deck name of a full deck name.\n */\nexport function getRootDeckName(deckName: string): string {\n const index = deckName.indexOf('::');\n return index >= 0 ? deckName.substring(0, index) : deckName;\n}\n\n/**\n * Checks whether or not any marker is contained in a string.\n */\nexport function stringContainsAnyFieldMarker(string: string): boolean {\n const result = markerPattern.test(string);\n markerPattern.lastIndex = 0;\n return result;\n}\n\n/**\n * Gets a list of all markers that are contained in a string.\n */\nexport function getFieldMarkers(string: string): string[] {\n const pattern = markerPattern;\n const markers: string[] = [];\n while (true) {\n const match = pattern.exec(string);\n if (match === null) {\n break;\n }\n markers.push(match[1]);\n }\n return markers;\n}\n\n/**\n * Returns a regular expression which can be used to find markers in a string.\n */\nexport function cloneFieldMarkerPattern(global: boolean): RegExp {\n return new RegExp(markerPattern.source, global ? 'gu' : 'u');\n}\n\n/**\n * Checks whether or not a note object is valid.\n */\nexport function isNoteDataValid(note: {\n fields: Record<string, string>;\n deckName: string;\n modelName: string;\n}): boolean {\n const { fields, deckName, modelName } = note;\n return (\n typeof deckName === 'string' &&\n deckName.length > 0 &&\n typeof modelName === 'string' &&\n modelName.length > 0 &&\n Object.entries(fields).length > 0\n );\n}\n\nexport const INVALID_NOTE_ID = -1;\n\n/**\n * Generates a file name for Anki note media.\n */\nexport function generateAnkiNoteMediaFileName(prefix: string, extension: string, timestamp: number): string {\n let fileName = prefix;\n fileName += `_${ankNoteDateToString(new Date(timestamp))}`;\n fileName += extension;\n fileName = replaceInvalidFileNameCharacters(fileName);\n return fileName;\n}\n\nfunction replaceInvalidFileNameCharacters(fileName: string): string {\n // eslint-disable-next-line no-control-regex\n return fileName.replace(/[<>:\"/\\\\|?*\\u0000-\\u001F]/g, '-');\n}\n\nfunction ankNoteDateToString(date: Date): string {\n const year = date.getUTCFullYear();\n const month = date.getUTCMonth().toString().padStart(2, '0');\n const day = date.getUTCDate().toString().padStart(2, '0');\n const hours = date.getUTCHours().toString().padStart(2, '0');\n const minutes = date.getUTCMinutes().toString().padStart(2, '0');\n const seconds = date.getUTCSeconds().toString().padStart(2, '0');\n const milliseconds = date.getUTCMilliseconds().toString().padStart(3, '0');\n return `${year}-${month}-${day}-${hours}-${minutes}-${seconds}-${milliseconds}`;\n}\n","import type {\n ApiReflectResult,\n CanAddNotesDetail,\n CardId,\n CardInfo,\n MessageBody,\n Note,\n NoteFieldInfo,\n NoteId,\n NoteInfo,\n} from '../types/anki';\nimport { getRootDeckName } from '../util/anki-util';\nimport { YomitanError } from '../util/errors';\nimport { parseJson } from '../util/json';\nimport { isObjectNotArray } from '../util/utilities';\n\n/**\n * This class controls communication with Anki via the AnkiConnect plugin.\n */\nexport class AnkiConnect {\n private _enabled: boolean;\n private _server: string | null;\n private _localVersion: number;\n private _remoteVersion: number;\n private _versionCheckPromise: Promise<number> | null;\n private _apiKey: string | null;\n\n constructor(config?: { server?: string; apiKey?: string }) {\n this._enabled = false;\n this._server = config?.server ?? null;\n this._localVersion = 2;\n this._remoteVersion = 0;\n this._versionCheckPromise = null;\n this._apiKey = config?.apiKey ?? null;\n }\n\n get server(): string | null {\n return this._server;\n }\n\n set server(value: string) {\n this._server = value;\n }\n\n get enabled(): boolean {\n return this._enabled;\n }\n\n set enabled(value: boolean) {\n this._enabled = value;\n }\n\n get apiKey(): string | null {\n return this._apiKey;\n }\n\n set apiKey(value: string | null) {\n this._apiKey = value;\n }\n\n /**\n * Checks whether a connection to AnkiConnect can be established.\n */\n async isConnected(): Promise<boolean> {\n try {\n await this._getVersion();\n return true;\n } catch (_e) {\n return false;\n }\n }\n\n /**\n * Gets the AnkiConnect API version number.\n */\n async getVersion(): Promise<number | null> {\n if (!this._enabled) {\n return null;\n }\n await this._checkVersion();\n return await this._getVersion();\n }\n\n async addNote(note: Note): Promise<NoteId | null> {\n if (!this._enabled) {\n return null;\n }\n await this._checkVersion();\n const result = await this._invoke('addNote', { note });\n if (result !== null && typeof result !== 'number') {\n throw this._createUnexpectedResultError('number|null', result);\n }\n return result as NoteId | null;\n }\n\n async addNotes(notes: Note[]): Promise<(number | null)[] | null> {\n if (!this._enabled) {\n return null;\n }\n await this._checkVersion();\n const result = await this._invoke('addNotes', { notes });\n if (result !== null && !Array.isArray(result)) {\n throw this._createUnexpectedResultError('(number | null)[] | null', result);\n }\n return result as (number | null)[] | null;\n }\n\n async updateNoteFields(noteWithId: Note & { id?: NoteId }): Promise<null> {\n if (!this._enabled) {\n return null;\n }\n await this._checkVersion();\n const result = await this._invoke('updateNoteFields', { note: noteWithId });\n if (result !== null) {\n throw this._createUnexpectedResultError('null', result);\n }\n return result;\n }\n\n async canAddNotes(notes: Note[]): Promise<boolean[]> {\n if (!this._enabled) {\n return new Array(notes.length).fill(false) as boolean[];\n }\n await this._checkVersion();\n const result = await this._invoke('canAddNotes', { notes });\n return this._normalizeArray<boolean>(result, notes.length, 'boolean');\n }\n\n async canAddNotesWithErrorDetail(notes: Note[]): Promise<CanAddNotesDetail[]> {\n if (!this._enabled) {\n return notes.map(() => ({ canAdd: false, error: null }));\n }\n await this._checkVersion();\n const result = await this._invoke('canAddNotesWithErrorDetail', { notes });\n return this._normalizeCanAddNotesWithErrorDetailArray(result, notes.length);\n }\n\n async notesInfo(noteIds: NoteId[]): Promise<(NoteInfo | null)[]> {\n if (!this._enabled) {\n return [];\n }\n await this._checkVersion();\n const result = await this._invoke('notesInfo', { notes: noteIds });\n return this._normalizeNoteInfoArray(result);\n }\n\n async cardsInfo(cardIds: CardId[]): Promise<(CardInfo | null)[]> {\n if (!this._enabled) {\n return [];\n }\n await this._checkVersion();\n const result = await this._invoke('cardsInfo', { cards: cardIds });\n return this._normalizeCardInfoArray(result);\n }\n\n async getDeckNames(): Promise<string[]> {\n if (!this._enabled) {\n return [];\n }\n await this._checkVersion();\n const result = await this._invoke('deckNames', {});\n return this._normalizeArray<string>(result, -1, 'string');\n }\n\n async getModelNames(): Promise<string[]> {\n if (!this._enabled) {\n return [];\n }\n await this._checkVersion();\n const result = await this._invoke('modelNames', {});\n return this._normalizeArray<string>(result, -1, 'string');\n }\n\n async getModelFieldNames(modelName: string): Promise<string[]> {\n if (!this._enabled) {\n return [];\n }\n await this._checkVersion();\n const result = await this._invoke('modelFieldNames', { modelName });\n return this._normalizeArray<string>(result, -1, 'string');\n }\n\n async guiBrowse(query: string): Promise<CardId[]> {\n if (!this._enabled) {\n return [];\n }\n await this._checkVersion();\n const result = await this._invoke('guiBrowse', { query });\n return this._normalizeArray<CardId>(result, -1, 'number');\n }\n\n async guiBrowseNote(noteId: NoteId): Promise<CardId[]> {\n return await this.guiBrowse(`nid:${noteId}`);\n }\n\n async guiBrowseNotes(noteIds: NoteId[]): Promise<CardId[]> {\n return await this.guiBrowse(`nid:${noteIds.join(',')}`);\n }\n\n async guiEditNote(noteId: NoteId): Promise<void> {\n await this._invoke('guiEditNote', { note: noteId });\n }\n\n /**\n * Stores a file with the specified base64-encoded content inside Anki's media folder.\n */\n async storeMediaFile(fileName: string, content: string): Promise<string | null> {\n if (!this._enabled) {\n throw new Error('AnkiConnect not enabled');\n }\n await this._checkVersion();\n const result = await this._invoke('storeMediaFile', { filename: fileName, data: content });\n if (result !== null && typeof result !== 'string') {\n throw this._createUnexpectedResultError('string|null', result);\n }\n return result as string | null;\n }\n\n /**\n * Finds notes matching a query.\n */\n async findNotes(query: string): Promise<NoteId[]> {\n if (!this._enabled) {\n return [];\n }\n await this._checkVersion();\n const result = await this._invoke('findNotes', { query });\n return this._normalizeArray<NoteId>(result, -1, 'number');\n }\n\n async findNoteIds(notes: Note[]): Promise<NoteId[][]> {\n if (!this._enabled) {\n return [];\n }\n await this._checkVersion();\n\n const actions: { action: string; params: Record<string, unknown> }[] = [];\n const actionsTargetsList: NoteId[][][] = [];\n const actionsTargetsMap = new Map<string, NoteId[][]>();\n const allNoteIds: NoteId[][] = [];\n\n for (const note of notes) {\n const query = this._getNoteQuery(note);\n let actionsTargets = actionsTargetsMap.get(query);\n if (typeof actionsTargets === 'undefined') {\n actionsTargets = [];\n actionsTargetsList.push(actionsTargets);\n actionsTargetsMap.set(query, actionsTargets);\n actions.push({ action: 'findNotes', params: { query } });\n }\n const noteIds: NoteId[] = [];\n allNoteIds.push(noteIds);\n actionsTargets.push(noteIds);\n }\n\n const result = await this._invokeMulti(actions);\n for (let i = 0, ii = Math.min(result.length, actionsTargetsList.length); i < ii; ++i) {\n const noteIds = this._normalizeArray<number>(result[i], -1, 'number');\n for (const actionsTargets of actionsTargetsList[i]) {\n for (const noteId of noteIds) {\n actionsTargets.push(noteId);\n }\n }\n }\n return allNoteIds;\n }\n\n async suspendCards(cardIds: CardId[]): Promise<boolean> {\n if (!this._enabled) {\n return false;\n }\n await this._checkVersion();\n const result = await this._invoke('suspend', { cards: cardIds });\n return typeof result === 'boolean' && result;\n }\n\n async findCards(query: string): Promise<CardId[]> {\n if (!this._enabled) {\n return [];\n }\n await this._checkVersion();\n const result = await this._invoke('findCards', { query });\n return this._normalizeArray<CardId>(result, -1, 'number');\n }\n\n async findCardsForNote(noteId: NoteId): Promise<CardId[]> {\n return await this.findCards(`nid:${noteId}`);\n }\n\n /**\n * Gets information about the AnkiConnect APIs available.\n */\n async apiReflect(scopes: string[], actions: string[] | null = null): Promise<ApiReflectResult> {\n const result = await this._invoke('apiReflect', { scopes, actions });\n if (!(typeof result === 'object' && result !== null)) {\n throw this._createUnexpectedResultError('object', result);\n }\n const { scopes: resultScopes, actions: resultActions } = result as Record<string, unknown>;\n const resultScopes2 = this._normalizeArray<string>(resultScopes, -1, 'string', ', field scopes');\n const resultActions2 = this._normalizeArray<string>(resultActions, -1, 'string', ', field actions');\n return {\n scopes: resultScopes2,\n actions: resultActions2,\n };\n }\n\n /**\n * Checks whether a specific API action exists.\n */\n async apiExists(action: string): Promise<boolean> {\n const { actions } = await this.apiReflect(['actions'], [action]);\n return actions.includes(action);\n }\n\n /**\n * Checks if a specific error object corresponds to an unsupported action.\n */\n isErrorUnsupportedAction(error: Error): boolean {\n if (error instanceof YomitanError) {\n const { data } = error;\n if (\n typeof data === 'object' &&\n data !== null &&\n (data as Record<string, unknown>).apiError === 'unsupported action'\n ) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Makes Anki sync.\n */\n async makeAnkiSync(): Promise<unknown | null> {\n if (!this._enabled) {\n return null;\n }\n const version = await this._checkVersion();\n const result = await this._invoke('sync', { version });\n return result === null;\n }\n\n // Private\n\n private async _checkVersion(): Promise<void> {\n if (this._remoteVersion < this._localVersion) {\n if (this._versionCheckPromise === null) {\n const promise = this._getVersion();\n promise\n .catch(() => {})\n .finally(() => {\n this._versionCheckPromise = null;\n });\n this._versionCheckPromise = promise;\n }\n this._remoteVersion = await this._versionCheckPromise;\n if (this._remoteVersion < this._localVersion) {\n throw new Error('Extension and plugin versions incompatible');\n }\n }\n }\n\n private async _invoke(action: string, params: Record<string, unknown>): Promise<unknown> {\n const body: MessageBody = { action, params, version: this._localVersion };\n if (this._apiKey !== null) {\n body.key = this._apiKey;\n }\n let response: Response;\n try {\n if (this._server === null) {\n throw new Error('Server URL is null');\n }\n response = await fetch(this._server, {\n method: 'POST',\n mode: 'cors',\n cache: 'default',\n credentials: 'omit',\n headers: {\n 'Content-Type': 'application/json',\n },\n redirect: 'follow',\n referrerPolicy: 'no-referrer',\n body: JSON.stringify(body),\n });\n } catch (e) {\n const error = new YomitanError('Anki connection failure');\n error.data = { action, params, originalError: e };\n throw error;\n }\n\n if (!response.ok) {\n const error = new YomitanError(`Anki connection error: ${response.status}`);\n error.data = { action, params, status: response.status };\n throw error;\n }\n\n let responseText: string | null = null;\n let result: unknown;\n try {\n responseText = await response.text();\n result = parseJson(responseText);\n } catch (e) {\n const error = new YomitanError('Invalid Anki response');\n error.data = { action, params, status: response.status, responseText, originalError: e };\n throw error;\n }\n\n if (typeof result === 'object' && result !== null && !Array.isArray(result)) {\n const apiError = (result as Record<string, unknown>).error;\n if (typeof apiError !== 'undefined') {\n const error = new YomitanError(`Anki error: ${apiError}`);\n error.data = {\n action,\n params,\n status: response.status,\n apiError: typeof apiError === 'string' ? apiError : `${apiError}`,\n };\n throw error;\n }\n }\n\n return result;\n }\n\n private async _invokeMulti(actions: { action: string; params: Record<string, unknown> }[]): Promise<unknown[]> {\n const result = await this._invoke('multi', { actions });\n if (!Array.isArray(result)) {\n throw this._createUnexpectedResultError('array', result);\n }\n return result as unknown[];\n }\n\n private _escapeQuery(text: string): string {\n return text.replace(/\"/g, '');\n }\n\n private _fieldsToQuery(fields: Record<string, string>): string {\n const fieldNames = Object.keys(fields);\n if (fieldNames.length === 0) {\n return '';\n }\n\n const key = fieldNames[0];\n return `\"${key.toLowerCase()}:${this._escapeQuery(fields[key])}\"`;\n }\n\n private _getDuplicateScopeFromNote(note: Note): 'collection' | 'deck' | 'deck-root' | null {\n const { options } = note;\n if (typeof options === 'object' && options !== null) {\n const { duplicateScope } = options;\n if (typeof duplicateScope !== 'undefined') {\n return duplicateScope as 'collection' | 'deck' | 'deck-root';\n }\n }\n return null;\n }\n\n private _getNoteQuery(note: Note): string {\n let query = '';\n switch (this._getDuplicateScopeFromNote(note)) {\n case 'deck':\n query = `\"deck:${this._escapeQuery(note.deckName)}\" `;\n break;\n case 'deck-root':\n query = `\"deck:${this._escapeQuery(getRootDeckName(note.deckName))}\" `;\n break;\n }\n query += this._fieldsToQuery(note.fields);\n return query;\n }\n\n private async _getVersion(): Promise<number> {\n const version = await this._invoke('version', {});\n return typeof version === 'number' ? version : 0;\n }\n\n private _createError(message: string, data: unknown): YomitanError {\n return new YomitanError(message, data);\n }\n\n private _createUnexpectedResultError(expectedType: string, result: unknown, context?: string): YomitanError {\n return this._createError(\n `Unexpected type${typeof context === 'string' ? context : ''}: expected ${expectedType}, received ${this._getTypeName(result)}`,\n result,\n );\n }\n\n private _getTypeName(value: unknown): string {\n if (value === null) {\n return 'null';\n }\n return Array.isArray(value) ? 'array' : typeof value;\n }\n\n private _normalizeArray<T = unknown>(\n result: unknown,\n expectedCount: number,\n type: 'boolean' | 'string' | 'number',\n context?: string,\n ): T[] {\n if (!Array.isArray(result)) {\n throw this._createUnexpectedResultError(`${type}[]`, result, context);\n }\n if (expectedCount < 0) {\n expectedCount = result.length;\n } else if (expectedCount !== result.length) {\n throw this._createError(\n `Unexpected result array size${context ?? ''}: expected ${expectedCount}, received ${result.length}`,\n result,\n );\n }\n for (let i = 0; i < expectedCount; ++i) {\n const item = result[i] as unknown;\n if (typeof item !== type) {\n throw this._createError(\n `Unexpected result type at index ${i}${context ?? ''}: expected ${type}, received ${this._getTypeName(item)}`,\n result,\n );\n }\n }\n return result as T[];\n }\n\n private _normalizeNoteInfoArray(result: unknown): (NoteInfo | null)[] {\n if (!Array.isArray(result)) {\n throw this._createUnexpectedResultError('array', result, '');\n }\n const result2: (NoteInfo | null)[] = [];\n for (let i = 0, ii = result.length; i < ii; ++i) {\n const item = result[i] as unknown;\n if (item === null || typeof item !== 'object') {\n throw this._createError(\n `Unexpected result type at index ${i}: expected Notes.NoteInfo, received ${this._getTypeName(item)}`,\n result,\n );\n }\n const { noteId } = item as Record<string, unknown>;\n if (typeof noteId !== 'number') {\n result2.push(null);\n continue;\n }\n\n const { tags, fields, modelName, cards } = item as Record<string, unknown>;\n if (typeof modelName !== 'string') {\n throw this._createError(\n `Unexpected result type at index ${i}, field modelName: expected string, received ${this._getTypeName(modelName)}`,\n result,\n );\n }\n if (!isObjectNotArray(fields)) {\n throw this._createError(\n `Unexpected result type at index ${i}, field fields: expected object, received ${this._getTypeName(fields)}`,\n result,\n );\n }\n const tags2 = this._normalizeArray<string>(tags, -1, 'string', ', field tags');\n const cards2 = this._normalizeArray<number>(cards, -1, 'number', ', field cards');\n const fields2: { [key: string]: NoteFieldInfo } = {};\n for (const [key, fieldInfo] of Object.entries(fields)) {\n if (!isObjectNotArray(fieldInfo)) {\n continue;\n }\n const { value, order } = fieldInfo;\n if (typeof value !== 'string' || typeof order !== 'number') {\n continue;\n }\n fields2[key] = { value, order };\n }\n const item2: NoteInfo = {\n noteId,\n tags: tags2,\n fields: fields2,\n modelName,\n cards: cards2,\n cardsInfo: [],\n };\n result2.push(item2);\n }\n return result2;\n }\n\n private _normalizeCardInfoArray(result: unknown): (CardInfo | null)[] {\n if (!Array.isArray(result)) {\n throw this._createUnexpectedResultError('array', result, '');\n }\n const result2: (CardInfo | null)[] = [];\n for (let i = 0, ii = result.length; i < ii; ++i) {\n const item = result[i] as unknown;\n if (item === null || typeof item !== 'object') {\n throw this._createError(\n `Unexpected result type at index ${i}: expected Cards.CardInfo, received ${this._getTypeName(item)}`,\n result,\n );\n }\n const { cardId } = item as Record<string, unknown>;\n if (typeof cardId !== 'number') {\n result2.push(null);\n continue;\n }\n const { note, flags, queue } = item as Record<string, unknown>;\n if (typeof note !== 'number') {\n result2.push(null);\n continue;\n }\n\n const item2: CardInfo = {\n noteId: note,\n cardId,\n flags: typeof flags === 'number' ? flags : 0,\n cardState: typeof queue === 'number' ? queue : 0,\n };\n result2.push(item2);\n }\n return result2;\n }\n\n private _normalizeCanAddNotesWithErrorDetailArray(result: unknown, expectedCount: number): CanAddNotesDetail[] {\n if (!Array.isArray(result)) {\n throw this._createUnexpectedResultError('array', result, '');\n }\n if (expectedCount !== result.length) {\n throw this._createError(\n `Unexpected result array size: expected ${expectedCount}, received ${result.length}`,\n result,\n );\n }\n const result2: CanAddNotesDetail[] = [];\n for (let i = 0; i < expectedCount; ++i) {\n const item = result[i] as unknown;\n if (item === null || typeof item !== 'object') {\n throw this._createError(\n `Unexpected result type at index ${i}: expected object, received ${this._getTypeName(item)}`,\n result,\n );\n }\n\n const { canAdd, error } = item as Record<string, unknown>;\n if (typeof canAdd !== 'boolean') {\n throw this._createError(\n `Unexpected result type at index ${i}, field canAdd: expected boolean, received ${this._getTypeName(canAdd)}`,\n result,\n );\n }\n\n const item2 = {\n canAdd,\n error: typeof error === 'string' ? error : null,\n };\n\n result2.push(item2);\n }\n return result2;\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"anki-connect-Dau8nAXZ.js","names":["deckName: string","global: boolean","config?: { server?: string; apiKey?: string }","value: string","value: boolean","value: string | null","note: Note","notes: Note[]","noteWithId: Note & { id?: NoteId }","noteIds: NoteId[]","cardIds: CardId[]","modelName: string","query: string","noteId: NoteId","fileName: string","content: string","actions: { action: string; params: Record<string, unknown> }[]","actionsTargetsList: NoteId[][][]","allNoteIds: NoteId[][]","scopes: string[]","actions: string[] | null","action: string","error: Error","params: Record<string, unknown>","body: MessageBody","response: Response","responseText: string | null","result: unknown","text: string","fields: Record<string, string>","message: string","data: unknown","expectedType: string","context?: string","value: unknown","expectedCount: number","type: 'boolean' | 'string' | 'number'","result2: (NoteInfo | null)[]","fields2: { [key: string]: NoteFieldInfo }","item2: NoteInfo","result2: (CardInfo | null)[]","item2: CardInfo","result2: CanAddNotesDetail[]"],"sources":["../src/util/anki-util.ts","../src/anki/anki-connect.ts"],"sourcesContent":["const markerPattern = /\\{([\\p{Letter}\\p{Number}_-]+)\\}/gu;\n\n/**\n * Gets the root deck name of a full deck name.\n */\nexport function getRootDeckName(deckName: string): string {\n const index = deckName.indexOf('::');\n return index >= 0 ? deckName.substring(0, index) : deckName;\n}\n\n/**\n * Checks whether or not any marker is contained in a string.\n */\nexport function stringContainsAnyFieldMarker(string: string): boolean {\n const result = markerPattern.test(string);\n markerPattern.lastIndex = 0;\n return result;\n}\n\n/**\n * Gets a list of all markers that are contained in a string.\n */\nexport function getFieldMarkers(string: string): string[] {\n const pattern = markerPattern;\n const markers: string[] = [];\n while (true) {\n const match = pattern.exec(string);\n if (match === null) {\n break;\n }\n markers.push(match[1]);\n }\n return markers;\n}\n\n/**\n * Returns a regular expression which can be used to find markers in a string.\n */\nexport function cloneFieldMarkerPattern(global: boolean): RegExp {\n return new RegExp(markerPattern.source, global ? 'gu' : 'u');\n}\n\n/**\n * Checks whether or not a note object is valid.\n */\nexport function isNoteDataValid(note: {\n fields: Record<string, string>;\n deckName: string;\n modelName: string;\n}): boolean {\n const { fields, deckName, modelName } = note;\n return (\n typeof deckName === 'string' &&\n deckName.length > 0 &&\n typeof modelName === 'string' &&\n modelName.length > 0 &&\n Object.entries(fields).length > 0\n );\n}\n\nexport const INVALID_NOTE_ID = -1;\n\n/**\n * Generates a file name for Anki note media.\n */\nexport function generateAnkiNoteMediaFileName(prefix: string, extension: string, timestamp: number): string {\n let fileName = prefix;\n fileName += `_${ankNoteDateToString(new Date(timestamp))}`;\n fileName += extension;\n fileName = replaceInvalidFileNameCharacters(fileName);\n return fileName;\n}\n\nfunction replaceInvalidFileNameCharacters(fileName: string): string {\n // eslint-disable-next-line no-control-regex\n return fileName.replace(/[<>:\"/\\\\|?*\\u0000-\\u001F]/g, '-');\n}\n\nfunction ankNoteDateToString(date: Date): string {\n const year = date.getUTCFullYear();\n const month = date.getUTCMonth().toString().padStart(2, '0');\n const day = date.getUTCDate().toString().padStart(2, '0');\n const hours = date.getUTCHours().toString().padStart(2, '0');\n const minutes = date.getUTCMinutes().toString().padStart(2, '0');\n const seconds = date.getUTCSeconds().toString().padStart(2, '0');\n const milliseconds = date.getUTCMilliseconds().toString().padStart(3, '0');\n return `${year}-${month}-${day}-${hours}-${minutes}-${seconds}-${milliseconds}`;\n}\n","import type {\n ApiReflectResult,\n CanAddNotesDetail,\n CardId,\n CardInfo,\n MessageBody,\n Note,\n NoteFieldInfo,\n NoteId,\n NoteInfo,\n} from '../types/anki';\nimport { getRootDeckName } from '../util/anki-util';\nimport { YomitanError } from '../util/errors';\nimport { parseJson } from '../util/json';\nimport { isObjectNotArray } from '../util/utilities';\n\n/**\n * This class controls communication with Anki via the AnkiConnect plugin.\n */\nexport class AnkiConnect {\n private _enabled: boolean;\n private _server: string | null;\n private _localVersion: number;\n private _remoteVersion: number;\n private _versionCheckPromise: Promise<number> | null;\n private _apiKey: string | null;\n\n constructor(config?: { server?: string; apiKey?: string }) {\n this._enabled = false;\n this._server = config?.server ?? null;\n this._localVersion = 2;\n this._remoteVersion = 0;\n this._versionCheckPromise = null;\n this._apiKey = config?.apiKey ?? null;\n }\n\n get server(): string | null {\n return this._server;\n }\n\n set server(value: string) {\n this._server = value;\n }\n\n get enabled(): boolean {\n return this._enabled;\n }\n\n set enabled(value: boolean) {\n this._enabled = value;\n }\n\n get apiKey(): string | null {\n return this._apiKey;\n }\n\n set apiKey(value: string | null) {\n this._apiKey = value;\n }\n\n /**\n * Checks whether a connection to AnkiConnect can be established.\n */\n async isConnected(): Promise<boolean> {\n try {\n await this._getVersion();\n return true;\n } catch (_e) {\n return false;\n }\n }\n\n /**\n * Gets the AnkiConnect API version number.\n */\n async getVersion(): Promise<number | null> {\n if (!this._enabled) {\n return null;\n }\n await this._checkVersion();\n return await this._getVersion();\n }\n\n async addNote(note: Note): Promise<NoteId | null> {\n if (!this._enabled) {\n return null;\n }\n await this._checkVersion();\n const result = await this._invoke('addNote', { note });\n if (result !== null && typeof result !== 'number') {\n throw this._createUnexpectedResultError('number|null', result);\n }\n return result as NoteId | null;\n }\n\n async addNotes(notes: Note[]): Promise<(number | null)[] | null> {\n if (!this._enabled) {\n return null;\n }\n await this._checkVersion();\n const result = await this._invoke('addNotes', { notes });\n if (result !== null && !Array.isArray(result)) {\n throw this._createUnexpectedResultError('(number | null)[] | null', result);\n }\n return result as (number | null)[] | null;\n }\n\n async updateNoteFields(noteWithId: Note & { id?: NoteId }): Promise<null> {\n if (!this._enabled) {\n return null;\n }\n await this._checkVersion();\n const result = await this._invoke('updateNoteFields', { note: noteWithId });\n if (result !== null) {\n throw this._createUnexpectedResultError('null', result);\n }\n return result;\n }\n\n async canAddNotes(notes: Note[]): Promise<boolean[]> {\n if (!this._enabled) {\n return new Array(notes.length).fill(false) as boolean[];\n }\n await this._checkVersion();\n const result = await this._invoke('canAddNotes', { notes });\n return this._normalizeArray<boolean>(result, notes.length, 'boolean');\n }\n\n async canAddNotesWithErrorDetail(notes: Note[]): Promise<CanAddNotesDetail[]> {\n if (!this._enabled) {\n return notes.map(() => ({ canAdd: false, error: null }));\n }\n await this._checkVersion();\n const result = await this._invoke('canAddNotesWithErrorDetail', { notes });\n return this._normalizeCanAddNotesWithErrorDetailArray(result, notes.length);\n }\n\n async notesInfo(noteIds: NoteId[]): Promise<(NoteInfo | null)[]> {\n if (!this._enabled) {\n return [];\n }\n await this._checkVersion();\n const result = await this._invoke('notesInfo', { notes: noteIds });\n return this._normalizeNoteInfoArray(result);\n }\n\n async cardsInfo(cardIds: CardId[]): Promise<(CardInfo | null)[]> {\n if (!this._enabled) {\n return [];\n }\n await this._checkVersion();\n const result = await this._invoke('cardsInfo', { cards: cardIds });\n return this._normalizeCardInfoArray(result);\n }\n\n async getDeckNames(): Promise<string[]> {\n if (!this._enabled) {\n return [];\n }\n await this._checkVersion();\n const result = await this._invoke('deckNames', {});\n return this._normalizeArray<string>(result, -1, 'string');\n }\n\n async getModelNames(): Promise<string[]> {\n if (!this._enabled) {\n return [];\n }\n await this._checkVersion();\n const result = await this._invoke('modelNames', {});\n return this._normalizeArray<string>(result, -1, 'string');\n }\n\n async getModelFieldNames(modelName: string): Promise<string[]> {\n if (!this._enabled) {\n return [];\n }\n await this._checkVersion();\n const result = await this._invoke('modelFieldNames', { modelName });\n return this._normalizeArray<string>(result, -1, 'string');\n }\n\n async guiBrowse(query: string): Promise<CardId[]> {\n if (!this._enabled) {\n return [];\n }\n await this._checkVersion();\n const result = await this._invoke('guiBrowse', { query });\n return this._normalizeArray<CardId>(result, -1, 'number');\n }\n\n async guiBrowseNote(noteId: NoteId): Promise<CardId[]> {\n return await this.guiBrowse(`nid:${noteId}`);\n }\n\n async guiBrowseNotes(noteIds: NoteId[]): Promise<CardId[]> {\n return await this.guiBrowse(`nid:${noteIds.join(',')}`);\n }\n\n async guiEditNote(noteId: NoteId): Promise<void> {\n await this._invoke('guiEditNote', { note: noteId });\n }\n\n /**\n * Stores a file with the specified base64-encoded content inside Anki's media folder.\n */\n async storeMediaFile(fileName: string, content: string): Promise<string | null> {\n if (!this._enabled) {\n throw new Error('AnkiConnect not enabled');\n }\n await this._checkVersion();\n const result = await this._invoke('storeMediaFile', { filename: fileName, data: content });\n if (result !== null && typeof result !== 'string') {\n throw this._createUnexpectedResultError('string|null', result);\n }\n return result as string | null;\n }\n\n /**\n * Finds notes matching a query.\n */\n async findNotes(query: string): Promise<NoteId[]> {\n if (!this._enabled) {\n return [];\n }\n await this._checkVersion();\n const result = await this._invoke('findNotes', { query });\n return this._normalizeArray<NoteId>(result, -1, 'number');\n }\n\n async findNoteIds(notes: Note[]): Promise<NoteId[][]> {\n if (!this._enabled) {\n return [];\n }\n await this._checkVersion();\n\n const actions: { action: string; params: Record<string, unknown> }[] = [];\n const actionsTargetsList: NoteId[][][] = [];\n const actionsTargetsMap = new Map<string, NoteId[][]>();\n const allNoteIds: NoteId[][] = [];\n\n for (const note of notes) {\n const query = this._getNoteQuery(note);\n let actionsTargets = actionsTargetsMap.get(query);\n if (typeof actionsTargets === 'undefined') {\n actionsTargets = [];\n actionsTargetsList.push(actionsTargets);\n actionsTargetsMap.set(query, actionsTargets);\n actions.push({ action: 'findNotes', params: { query } });\n }\n const noteIds: NoteId[] = [];\n allNoteIds.push(noteIds);\n actionsTargets.push(noteIds);\n }\n\n const result = await this._invokeMulti(actions);\n for (let i = 0, ii = Math.min(result.length, actionsTargetsList.length); i < ii; ++i) {\n const noteIds = this._normalizeArray<number>(result[i], -1, 'number');\n for (const actionsTargets of actionsTargetsList[i]) {\n for (const noteId of noteIds) {\n actionsTargets.push(noteId);\n }\n }\n }\n return allNoteIds;\n }\n\n async suspendCards(cardIds: CardId[]): Promise<boolean> {\n if (!this._enabled) {\n return false;\n }\n await this._checkVersion();\n const result = await this._invoke('suspend', { cards: cardIds });\n return typeof result === 'boolean' && result;\n }\n\n async findCards(query: string): Promise<CardId[]> {\n if (!this._enabled) {\n return [];\n }\n await this._checkVersion();\n const result = await this._invoke('findCards', { query });\n return this._normalizeArray<CardId>(result, -1, 'number');\n }\n\n async findCardsForNote(noteId: NoteId): Promise<CardId[]> {\n return await this.findCards(`nid:${noteId}`);\n }\n\n /**\n * Gets information about the AnkiConnect APIs available.\n */\n async apiReflect(scopes: string[], actions: string[] | null = null): Promise<ApiReflectResult> {\n const result = await this._invoke('apiReflect', { scopes, actions });\n if (!(typeof result === 'object' && result !== null)) {\n throw this._createUnexpectedResultError('object', result);\n }\n const { scopes: resultScopes, actions: resultActions } = result as Record<string, unknown>;\n const resultScopes2 = this._normalizeArray<string>(resultScopes, -1, 'string', ', field scopes');\n const resultActions2 = this._normalizeArray<string>(resultActions, -1, 'string', ', field actions');\n return {\n scopes: resultScopes2,\n actions: resultActions2,\n };\n }\n\n /**\n * Checks whether a specific API action exists.\n */\n async apiExists(action: string): Promise<boolean> {\n const { actions } = await this.apiReflect(['actions'], [action]);\n return actions.includes(action);\n }\n\n /**\n * Checks if a specific error object corresponds to an unsupported action.\n */\n isErrorUnsupportedAction(error: Error): boolean {\n if (error instanceof YomitanError) {\n const { data } = error;\n if (\n typeof data === 'object' &&\n data !== null &&\n (data as Record<string, unknown>).apiError === 'unsupported action'\n ) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Makes Anki sync.\n */\n async makeAnkiSync(): Promise<unknown | null> {\n if (!this._enabled) {\n return null;\n }\n const version = await this._checkVersion();\n const result = await this._invoke('sync', { version });\n return result === null;\n }\n\n // Private\n\n private async _checkVersion(): Promise<void> {\n if (this._remoteVersion < this._localVersion) {\n if (this._versionCheckPromise === null) {\n const promise = this._getVersion();\n promise\n .catch(() => {})\n .finally(() => {\n this._versionCheckPromise = null;\n });\n this._versionCheckPromise = promise;\n }\n this._remoteVersion = await this._versionCheckPromise;\n if (this._remoteVersion < this._localVersion) {\n throw new Error('Extension and plugin versions incompatible');\n }\n }\n }\n\n private async _invoke(action: string, params: Record<string, unknown>): Promise<unknown> {\n const body: MessageBody = { action, params, version: this._localVersion };\n if (this._apiKey !== null) {\n body.key = this._apiKey;\n }\n let response: Response;\n try {\n if (this._server === null) {\n throw new Error('Server URL is null');\n }\n response = await fetch(this._server, {\n method: 'POST',\n mode: 'cors',\n cache: 'default',\n credentials: 'omit',\n headers: {\n 'Content-Type': 'application/json',\n },\n redirect: 'follow',\n referrerPolicy: 'no-referrer',\n body: JSON.stringify(body),\n });\n } catch (e) {\n const error = new YomitanError('Anki connection failure');\n error.data = { action, params, originalError: e };\n throw error;\n }\n\n if (!response.ok) {\n const error = new YomitanError(`Anki connection error: ${response.status}`);\n error.data = { action, params, status: response.status };\n throw error;\n }\n\n let responseText: string | null = null;\n let result: unknown;\n try {\n responseText = await response.text();\n result = parseJson(responseText);\n } catch (e) {\n const error = new YomitanError('Invalid Anki response');\n error.data = { action, params, status: response.status, responseText, originalError: e };\n throw error;\n }\n\n if (typeof result === 'object' && result !== null && !Array.isArray(result)) {\n const apiError = (result as Record<string, unknown>).error;\n if (typeof apiError !== 'undefined') {\n const error = new YomitanError(`Anki error: ${apiError}`);\n error.data = {\n action,\n params,\n status: response.status,\n apiError: typeof apiError === 'string' ? apiError : `${apiError}`,\n };\n throw error;\n }\n }\n\n return result;\n }\n\n private async _invokeMulti(actions: { action: string; params: Record<string, unknown> }[]): Promise<unknown[]> {\n const result = await this._invoke('multi', { actions });\n if (!Array.isArray(result)) {\n throw this._createUnexpectedResultError('array', result);\n }\n return result as unknown[];\n }\n\n private _escapeQuery(text: string): string {\n return text.replace(/\"/g, '');\n }\n\n private _fieldsToQuery(fields: Record<string, string>): string {\n const fieldNames = Object.keys(fields);\n if (fieldNames.length === 0) {\n return '';\n }\n\n const key = fieldNames[0];\n return `\"${key.toLowerCase()}:${this._escapeQuery(fields[key])}\"`;\n }\n\n private _getDuplicateScopeFromNote(note: Note): 'collection' | 'deck' | 'deck-root' | null {\n const { options } = note;\n if (typeof options === 'object' && options !== null) {\n const { duplicateScope } = options;\n if (typeof duplicateScope !== 'undefined') {\n return duplicateScope as 'collection' | 'deck' | 'deck-root';\n }\n }\n return null;\n }\n\n private _getNoteQuery(note: Note): string {\n let query = '';\n switch (this._getDuplicateScopeFromNote(note)) {\n case 'deck':\n query = `\"deck:${this._escapeQuery(note.deckName)}\" `;\n break;\n case 'deck-root':\n query = `\"deck:${this._escapeQuery(getRootDeckName(note.deckName))}\" `;\n break;\n }\n query += this._fieldsToQuery(note.fields);\n return query;\n }\n\n private async _getVersion(): Promise<number> {\n const version = await this._invoke('version', {});\n return typeof version === 'number' ? version : 0;\n }\n\n private _createError(message: string, data: unknown): YomitanError {\n return new YomitanError(message, data);\n }\n\n private _createUnexpectedResultError(expectedType: string, result: unknown, context?: string): YomitanError {\n return this._createError(\n `Unexpected type${typeof context === 'string' ? context : ''}: expected ${expectedType}, received ${this._getTypeName(result)}`,\n result,\n );\n }\n\n private _getTypeName(value: unknown): string {\n if (value === null) {\n return 'null';\n }\n return Array.isArray(value) ? 'array' : typeof value;\n }\n\n private _normalizeArray<T = unknown>(\n result: unknown,\n expectedCount: number,\n type: 'boolean' | 'string' | 'number',\n context?: string,\n ): T[] {\n if (!Array.isArray(result)) {\n throw this._createUnexpectedResultError(`${type}[]`, result, context);\n }\n if (expectedCount < 0) {\n expectedCount = result.length;\n } else if (expectedCount !== result.length) {\n throw this._createError(\n `Unexpected result array size${context ?? ''}: expected ${expectedCount}, received ${result.length}`,\n result,\n );\n }\n for (let i = 0; i < expectedCount; ++i) {\n const item = result[i] as unknown;\n if (typeof item !== type) {\n throw this._createError(\n `Unexpected result type at index ${i}${context ?? ''}: expected ${type}, received ${this._getTypeName(item)}`,\n result,\n );\n }\n }\n return result as T[];\n }\n\n private _normalizeNoteInfoArray(result: unknown): (NoteInfo | null)[] {\n if (!Array.isArray(result)) {\n throw this._createUnexpectedResultError('array', result, '');\n }\n const result2: (NoteInfo | null)[] = [];\n for (let i = 0, ii = result.length; i < ii; ++i) {\n const item = result[i] as unknown;\n if (item === null || typeof item !== 'object') {\n throw this._createError(\n `Unexpected result type at index ${i}: expected Notes.NoteInfo, received ${this._getTypeName(item)}`,\n result,\n );\n }\n const { noteId } = item as Record<string, unknown>;\n if (typeof noteId !== 'number') {\n result2.push(null);\n continue;\n }\n\n const { tags, fields, modelName, cards } = item as Record<string, unknown>;\n if (typeof modelName !== 'string') {\n throw this._createError(\n `Unexpected result type at index ${i}, field modelName: expected string, received ${this._getTypeName(modelName)}`,\n result,\n );\n }\n if (!isObjectNotArray(fields)) {\n throw this._createError(\n `Unexpected result type at index ${i}, field fields: expected object, received ${this._getTypeName(fields)}`,\n result,\n );\n }\n const tags2 = this._normalizeArray<string>(tags, -1, 'string', ', field tags');\n const cards2 = this._normalizeArray<number>(cards, -1, 'number', ', field cards');\n const fields2: { [key: string]: NoteFieldInfo } = {};\n for (const [key, fieldInfo] of Object.entries(fields)) {\n if (!isObjectNotArray(fieldInfo)) {\n continue;\n }\n const { value, order } = fieldInfo;\n if (typeof value !== 'string' || typeof order !== 'number') {\n continue;\n }\n fields2[key] = { value, order };\n }\n const item2: NoteInfo = {\n noteId,\n tags: tags2,\n fields: fields2,\n modelName,\n cards: cards2,\n cardsInfo: [],\n };\n result2.push(item2);\n }\n return result2;\n }\n\n private _normalizeCardInfoArray(result: unknown): (CardInfo | null)[] {\n if (!Array.isArray(result)) {\n throw this._createUnexpectedResultError('array', result, '');\n }\n const result2: (CardInfo | null)[] = [];\n for (let i = 0, ii = result.length; i < ii; ++i) {\n const item = result[i] as unknown;\n if (item === null || typeof item !== 'object') {\n throw this._createError(\n `Unexpected result type at index ${i}: expected Cards.CardInfo, received ${this._getTypeName(item)}`,\n result,\n );\n }\n const { cardId } = item as Record<string, unknown>;\n if (typeof cardId !== 'number') {\n result2.push(null);\n continue;\n }\n const { note, flags, queue } = item as Record<string, unknown>;\n if (typeof note !== 'number') {\n result2.push(null);\n continue;\n }\n\n const item2: CardInfo = {\n noteId: note,\n cardId,\n flags: typeof flags === 'number' ? flags : 0,\n cardState: typeof queue === 'number' ? queue : 0,\n };\n result2.push(item2);\n }\n return result2;\n }\n\n private _normalizeCanAddNotesWithErrorDetailArray(result: unknown, expectedCount: number): CanAddNotesDetail[] {\n if (!Array.isArray(result)) {\n throw this._createUnexpectedResultError('array', result, '');\n }\n if (expectedCount !== result.length) {\n throw this._createError(\n `Unexpected result array size: expected ${expectedCount}, received ${result.length}`,\n result,\n );\n }\n const result2: CanAddNotesDetail[] = [];\n for (let i = 0; i < expectedCount; ++i) {\n const item = result[i] as unknown;\n if (item === null || typeof item !== 'object') {\n throw this._createError(\n `Unexpected result type at index ${i}: expected object, received ${this._getTypeName(item)}`,\n result,\n );\n }\n\n const { canAdd, error } = item as Record<string, unknown>;\n if (typeof canAdd !== 'boolean') {\n throw this._createError(\n `Unexpected result type at index ${i}, field canAdd: expected boolean, received ${this._getTypeName(canAdd)}`,\n result,\n );\n }\n\n const item2 = {\n canAdd,\n error: typeof error === 'string' ? error : null,\n };\n\n result2.push(item2);\n }\n return result2;\n }\n}\n"],"mappings":"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"}
|
package/dist/anki.cjs
CHANGED
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
const require_utilities = require('./utilities-C-lbZaJE.cjs');
|
|
3
3
|
require('./cjk-util-Dp0ZU0sh.cjs');
|
|
4
4
|
const require_japanese = require('./japanese-C83fmEfb.cjs');
|
|
5
|
-
const require_errors = require('./errors-
|
|
6
|
-
const require_dictionary_data_util = require('./dictionary-data-util-
|
|
7
|
-
require('./json-
|
|
8
|
-
require('./furigana-
|
|
9
|
-
const require_anki_connect = require('./anki-connect-
|
|
5
|
+
const require_errors = require('./errors-0pIJI6N2.cjs');
|
|
6
|
+
const require_dictionary_data_util = require('./dictionary-data-util-DmLJMtGc.cjs');
|
|
7
|
+
require('./json-Cdj6aIOQ.cjs');
|
|
8
|
+
require('./furigana-SZuBaUyl.cjs');
|
|
9
|
+
const require_anki_connect = require('./anki-connect-DGx7Gr0H.cjs');
|
|
10
10
|
|
|
11
11
|
//#region src/anki/anki-note-builder.ts
|
|
12
12
|
/**
|
package/dist/anki.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { ApiReflectResult, CanAddNotesDetail, CardId, CardInfo, Note, NoteId, NoteInfo, SerializableObject } from "./core-
|
|
2
|
-
import { DictionaryEntry, InflectionRuleChainCandidate, KanjiDictionaryEntry, Tag, TermDictionaryEntry, TermGlossaryContent } from "./dictionary-
|
|
1
|
+
import { ApiReflectResult, CanAddNotesDetail, CardId, CardInfo, Note, NoteId, NoteInfo, SerializableObject } from "./core-CRjMTF7c.js";
|
|
2
|
+
import { DictionaryEntry, InflectionRuleChainCandidate, KanjiDictionaryEntry, Tag, TermDictionaryEntry, TermGlossaryContent } from "./dictionary-DdxghSJP.js";
|
|
3
3
|
|
|
4
4
|
//#region src/anki/anki-connect.d.ts
|
|
5
5
|
/**
|
package/dist/anki.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { deferPromise } from "./utilities-bi3EF-q5.js";
|
|
2
2
|
import "./cjk-util-DubXBGDG.js";
|
|
3
|
-
import { distributeFurigana } from "./japanese-
|
|
4
|
-
import { YomitanError } from "./errors-
|
|
5
|
-
import { getDisambiguations, getGroupedPronunciations, getPronunciationsOfType, getTermFrequency, groupTermTags, isNonNounVerbOrAdjective } from "./dictionary-data-util-
|
|
6
|
-
import "./json-
|
|
7
|
-
import "./furigana-
|
|
8
|
-
import { AnkiConnect, cloneFieldMarkerPattern, getRootDeckName } from "./anki-connect-
|
|
3
|
+
import { distributeFurigana } from "./japanese-OKEGf_i4.js";
|
|
4
|
+
import { YomitanError } from "./errors-DvKlMRXC.js";
|
|
5
|
+
import { getDisambiguations, getGroupedPronunciations, getPronunciationsOfType, getTermFrequency, groupTermTags, isNonNounVerbOrAdjective } from "./dictionary-data-util-gUUD9ElK.js";
|
|
6
|
+
import "./json-rIgOFqVY.js";
|
|
7
|
+
import "./furigana-h18vaQ7a.js";
|
|
8
|
+
import { AnkiConnect, cloneFieldMarkerPattern, getRootDeckName } from "./anki-connect-Dau8nAXZ.js";
|
|
9
9
|
|
|
10
10
|
//#region src/anki/anki-note-builder.ts
|
|
11
11
|
/**
|
|
@@ -45,4 +45,4 @@ type CustomAudioList = {
|
|
|
45
45
|
|
|
46
46
|
//# sourceMappingURL=audio.d.ts.map
|
|
47
47
|
export { AudioInfo, AudioSourceInfo, AudioSourceType, AudioTtsInfo, AudioUrlInfo, CustomAudioList, WikimediaCommonsFileResponse, WikimediaCommonsLookupResponse };
|
|
48
|
-
//# sourceMappingURL=audio-
|
|
48
|
+
//# sourceMappingURL=audio-DN-FhZ5k.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audio-
|
|
1
|
+
{"version":3,"file":"audio-DN-FhZ5k.d.ts","names":[],"sources":["../src/types/audio.ts"],"sourcesContent":null,"mappings":";KAAY,eAAA;AAAA,KAWA,eAAA,GAXe;EAWf,IAAA,EACF,eADiB;EAMf,GAAA,EAAA,MAAA;EAMA,KAAA,EAAA,MAAA;AAMZ,CAAA;AAAqB,KAZT,YAAA,GAYS;EAAA,IAAG,EAAA,KAAA;EAAY,GAAG,EAAA,MAAA;EAAY,IAAA,CAAA,EAAA,MAAA;AAEnD,CAAA;AAMY,KAdA,YAAA,GAcA;EAUA,IAAA,EAAA,KAAA;;;;KAlBA,SAAA,GAAY,eAAe;KAE3B,8BAAA;;;;;;;KAMA,4BAAA;;;;;;;;;;;;KAUA,eAAA"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import "./json-
|
|
2
|
-
import { AudioUrlGenerator, NativeSimpleDOMParser, getRequiredAudioSourceList, getRequiredAudioSources } from "./audio-url-generator-
|
|
1
|
+
import "./json-rIgOFqVY.js";
|
|
2
|
+
import { AudioUrlGenerator, NativeSimpleDOMParser, getRequiredAudioSourceList, getRequiredAudioSources } from "./audio-url-generator-_6Qk0i3T.js";
|
|
3
3
|
|
|
4
4
|
export { AudioUrlGenerator };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
require('./json-
|
|
2
|
-
const require_audio_url_generator = require('./audio-url-generator-
|
|
1
|
+
require('./json-Cdj6aIOQ.cjs');
|
|
2
|
+
const require_audio_url_generator = require('./audio-url-generator-CorFRyBU.cjs');
|
|
3
3
|
|
|
4
4
|
exports.AudioUrlGenerator = require_audio_url_generator.AudioUrlGenerator
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
const require_json = require('./json-
|
|
2
|
+
const require_json = require('./json-Cdj6aIOQ.cjs');
|
|
3
3
|
|
|
4
4
|
//#region src/audio/audio-url-generator.ts
|
|
5
5
|
/**
|
|
@@ -411,4 +411,4 @@ Object.defineProperty(exports, 'getRequiredAudioSources', {
|
|
|
411
411
|
return getRequiredAudioSources;
|
|
412
412
|
}
|
|
413
413
|
});
|
|
414
|
-
//# sourceMappingURL=audio-url-generator-
|
|
414
|
+
//# sourceMappingURL=audio-url-generator-CorFRyBU.cjs.map
|