yanki-connect
Version:
A fully-typed Anki-Connect API client.
1 lines • 7.69 kB
JavaScript
const e=typeof window>`u`?typeof process>`u`?`other`:`node`:`browser`,t=e===`browser`?/windows/i.test(navigator.userAgent)?`windows`:/mac/i.test(navigator.userAgent)?`mac`:`other`:e===`node`?process.platform===`win32`?`windows`:process.platform===`darwin`?`mac`:`other`:`other`;let n=0,r=0;async function i(){if(t===`mac`&&e===`node`){let{openApp:e}=await import(`open`);if(r>=100){console.warn(`Too many Anki App launch attempts this session, ignoring`);return}(n===0||Date.now()-n>5e3)&&(console.warn(`Attempting to launch Anki app`),n=Date.now(),r++,await e(`/Applications/Anki.app`,{background:!0,newInstance:!1,wait:!1}))}else console.warn(`Automatic Anki App launch is only supported on Mac OS in Node.js environment`)}const a={autoLaunch:!1,fetchAdapter:fetch.bind(globalThis),host:`http://127.0.0.1`,key:void 0,port:8765,version:6};var o=class{card={answerCards:this.build(`answerCards`),areDue:this.build(`areDue`),areSuspended:this.build(`areSuspended`),cardsInfo:this.build(`cardsInfo`),cardsModTime:this.build(`cardsModTime`),cardsToNotes:this.build(`cardsToNotes`),findCards:this.build(`findCards`),forgetCards:this.build(`forgetCards`),getEaseFactors:this.build(`getEaseFactors`),getIntervals:this.build(`getIntervals`),relearnCards:this.build(`relearnCards`),setDueDate:this.build(`setDueDate`),setEaseFactors:this.build(`setEaseFactors`),setSpecificValueOfCard:this.build(`setSpecificValueOfCard`),suspend:this.build(`suspend`),suspended:this.build(`suspended`),unsuspend:this.build(`unsuspend`)};deck={changeDeck:this.build(`changeDeck`),cloneDeckConfigId:this.build(`cloneDeckConfigId`),createDeck:this.build(`createDeck`),deckNames:this.build(`deckNames`),deckNamesAndIds:this.build(`deckNamesAndIds`),deleteDecks:this.build(`deleteDecks`),getDeckConfig:this.build(`getDeckConfig`),getDecks:this.build(`getDecks`),getDeckStats:this.build(`getDeckStats`),removeDeckConfigId:this.build(`removeDeckConfigId`),saveDeckConfig:this.build(`saveDeckConfig`),setDeckConfigId:this.build(`setDeckConfigId`)};graphical={guiAddCards:this.build(`guiAddCards`),guiAnswerCard:this.build(`guiAnswerCard`),guiBrowse:this.build(`guiBrowse`),guiCheckDatabase:this.build(`guiCheckDatabase`),guiCurrentCard:this.build(`guiCurrentCard`),guiDeckBrowser:this.build(`guiDeckBrowser`),guiDeckOverview:this.build(`guiDeckOverview`),guiDeckReview:this.build(`guiDeckReview`),guiEditNote:this.build(`guiEditNote`),guiExitAnki:this.build(`guiExitAnki`),guiImportFile:this.build(`guiImportFile`),guiPlayAudio:this.build(`guiPlayAudio`),guiSelectCard:this.build(`guiSelectCard`),guiSelectedNotes:this.build(`guiSelectedNotes`),guiSelectNote:this.build(`guiSelectNote`),guiShowAnswer:this.build(`guiShowAnswer`),guiShowQuestion:this.build(`guiShowQuestion`),guiStartCardTimer:this.build(`guiStartCardTimer`),guiUndo:this.build(`guiUndo`)};media={deleteMediaFile:this.build(`deleteMediaFile`),getMediaDirPath:this.build(`getMediaDirPath`),getMediaFilesNames:this.build(`getMediaFilesNames`),retrieveMediaFile:this.build(`retrieveMediaFile`),storeMediaFile:this.build(`storeMediaFile`)};miscellaneous={apiReflect:this.build(`apiReflect`),exportPackage:this.build(`exportPackage`),getActiveProfile:this.build(`getActiveProfile`),getProfiles:this.build(`getProfiles`),importPackage:this.build(`importPackage`),loadProfile:this.build(`loadProfile`),multi:this.build(`multi`),reloadCollection:this.build(`reloadCollection`),requestPermission:this.build(`requestPermission`),sync:this.build(`sync`),version:this.build(`version`)};model={createModel:this.build(`createModel`),findAndReplaceInModels:this.build(`findAndReplaceInModels`),findModelsById:this.build(`findModelsById`),findModelsByName:this.build(`findModelsByName`),modelFieldAdd:this.build(`modelFieldAdd`),modelFieldDescriptions:this.build(`modelFieldDescriptions`),modelFieldFonts:this.build(`modelFieldFonts`),modelFieldNames:this.build(`modelFieldNames`),modelFieldRemove:this.build(`modelFieldRemove`),modelFieldRename:this.build(`modelFieldRename`),modelFieldReposition:this.build(`modelFieldReposition`),modelFieldSetDescription:this.build(`modelFieldSetDescription`),modelFieldSetFont:this.build(`modelFieldSetFont`),modelFieldSetFontSize:this.build(`modelFieldSetFontSize`),modelFieldsOnTemplates:this.build(`modelFieldsOnTemplates`),modelNames:this.build(`modelNames`),modelNamesAndIds:this.build(`modelNamesAndIds`),modelStyling:this.build(`modelStyling`),modelTemplateAdd:this.build(`modelTemplateAdd`),modelTemplateRemove:this.build(`modelTemplateRemove`),modelTemplateRename:this.build(`modelTemplateRename`),modelTemplateReposition:this.build(`modelTemplateReposition`),modelTemplates:this.build(`modelTemplates`),updateModelStyling:this.build(`updateModelStyling`),updateModelTemplates:this.build(`updateModelTemplates`)};note={addNote:this.build(`addNote`),addNotes:this.build(`addNotes`),addTags:this.build(`addTags`),canAddNotes:this.build(`canAddNotes`),canAddNotesWithErrorDetail:this.build(`canAddNotesWithErrorDetail`),clearUnusedTags:this.build(`clearUnusedTags`),deleteNotes:this.build(`deleteNotes`),findNotes:this.build(`findNotes`),getNoteTags:this.build(`getNoteTags`),getTags:this.build(`getTags`),notesInfo:this.build(`notesInfo`),notesModTime:this.build(`notesInfo`),removeEmptyNotes:this.build(`removeEmptyNotes`),removeTags:this.build(`removeTags`),replaceTags:this.build(`replaceTags`),replaceTagsInAllNotes:this.build(`replaceTagsInAllNotes`),updateNote:this.build(`updateNote`),updateNoteFields:this.build(`updateNoteFields`),updateNoteModel:this.build(`updateNoteModel`),updateNoteTags:this.build(`updateNoteTags`)};statistic={cardReviews:this.build(`cardReviews`),getCollectionStatsHTML:this.build(`getCollectionStatsHTML`),getLatestReviewID:this.build(`getLatestReviewID`),getNumCardsReviewedByDay:this.build(`getNumCardsReviewedByDay`),getNumCardsReviewedToday:this.build(`getNumCardsReviewedToday`),getReviewsOfCards:this.build(`getReviewsOfCards`),insertReviews:this.build(`insertReviews`)};autoLaunch;fetchAdapter;host;key;port;version;constructor(n){if(this.host=n?.host??a.host,this.port=n?.port??a.port,this.version=n?.version??a.version,this.key=n?.key??a.key,this.autoLaunch=n?.autoLaunch??a.autoLaunch,a.fetchAdapter===void 0)throw Error(`A fetch implementation is required`);if(this.fetchAdapter=n?.fetchAdapter??a.fetchAdapter,(t!==`mac`||e!==`node`)&&this.autoLaunch!==!1&&(console.warn(`The autoLaunch option is only supported in a Node environment on macOS`),this.autoLaunch=!1),this.version!==6)throw Error(`YankiConnect currently only supports Anki-Connect API version 6`);this.autoLaunch===`immediately`&&i()}async invoke(e,t){let n,r;try{if(n=await this.fetchAdapter(`${this.host}:${this.port}`,{body:JSON.stringify({action:e,...this.key===void 0?{}:{key:this.key},params:t,version:this.version}),headers:{"Access-Control-Allow-Origin":`*`,"Content-Type":`application/json`},method:`POST`,mode:`cors`}),n===void 0)throw Error(`Anki-Connect response is undefined`);if(n.status!==200)throw Error(`Anki-Connect response status is ${n.status}`);if(r=await n.json(),this.autoLaunch!==!1&&r.error===`collection is not available`)throw Error(r.error)}catch(n){if(this.autoLaunch!==!1)return console.warn(`Can't connect to Anki app, retrying with auto-launch...`),await i(),await new Promise(e=>{setTimeout(e,500)}),t===void 0?this.invoke(e):this.invoke(e,t);throw n}if(!(`error`in r))throw Error(`response is missing required error field`);if(!(`result`in r))throw Error(`response is missing required result field`);return r}build(e){return async t=>{let n=await this.invoke(e,t);if(n.error!==null)throw Error(n.error);return n.result}}};export{o as YankiConnect,a as defaultYankiConnectOptions};