yanki 1.0.2 → 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/bin/cli.js +9 -9
- package/dist/{index-Btaa1Oo8.js → index-Dsl0rabV.js} +2 -2
- package/dist/lib/index.d.ts +168 -111
- package/dist/lib/index.js +1 -1
- package/dist/luau-BYt3hdDQ.js +1 -0
- package/dist/move-CWzLDnIf.js +1 -0
- package/dist/{nextflow-fe5whG_E.js → nextflow-pQFAKpIi.js} +1 -1
- package/dist/nushell-Bq8mR-cv.js +1 -0
- package/dist/swift-D8uC5CNv.js +1 -0
- package/dist/{sync-files-Cs3Fq5Hp.js → sync-files-S6DH9ijG.js} +158 -158
- package/package.json +20 -20
- package/readme.md +25 -28
- package/dist/luau-Mu7xYRt8.js +0 -1
- package/dist/move-SS8NmKEm.js +0 -1
- package/dist/nushell-DpdsqGT_.js +0 -1
- package/dist/swift-OqGpEy1F.js +0 -1
package/dist/bin/cli.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
var
|
|
3
|
-
`)):(process.stderr.write(
|
|
4
|
-
`))}).command("list [options]","Utility command to list Yanki-created notes in the Anki database.",e=>e.option(
|
|
5
|
-
`)):(process.stdout.write(
|
|
6
|
-
`))}).command("delete [options]","Utility command to manually delete Yanki-created notes in the Anki database. This is for advanced use cases, usually the `sync` command takes care of deleting files from Anki Database once they're removed from the local file system.",e=>e.option(
|
|
7
|
-
`)):(process.stderr.write(
|
|
8
|
-
`))}).command("style [options]","Utility command to set the CSS stylesheet for all present and future Yanki-created notes.",e=>e.option(
|
|
9
|
-
`)):(process.stderr.write(
|
|
10
|
-
`))}).demandCommand(1).alias("h","help").version(
|
|
2
|
+
var q=Object.defineProperty;var m=(e,o)=>q(e,"name",{value:o,configurable:!0});import{globby as $}from"globby";import G from"node:fs/promises";import W from"node:path";import L from"node:os";import _ from"yargs";import{hideBin as V}from"yargs/helpers";import{w as K,x as h,v as Q,y as O,n as X,m as Z,l as ee,b as te,c as oe,f as ne,s as se,i as ae}from"../sync-files-S6DH9ijG.js";import"process";import"rehype-parse";import"node:crypto";let y,x;function ie(e){if(typeof e!="string")throw new TypeError(`Expected a string, got ${typeof e}`);if(y===void 0&&(y=L.homedir()),y&&/^~(?=$|\/|\\)/.test(e))return e.replace(/^~/,y);const o=e.match(/^~([^/\\]+)(.*)/);if(o&&(x===void 0&&(x=L.userInfo().username),x)){const s=o[1],a=o[2];if(s===x)return y+a}return e}m(ie,"untildify");var re="1.2.0",B={exports:{}},F;function le(){if(F)return B.exports;F=1;let e=process||{},o=e.argv||[],s=e.env||{},a=!(s.NO_COLOR||o.includes("--no-color"))&&(!!s.FORCE_COLOR||o.includes("--color")||e.platform==="win32"||(e.stdout||{}).isTTY&&s.TERM!=="dumb"||!!s.CI),d=m((n,t,l=n)=>c=>{let i=""+c,u=i.indexOf(t,n.length);return~u?n+p(i,t,l,u)+t:n+i+t},"formatter"),p=m((n,t,l,c)=>{let i="",u=0;do i+=n.substring(u,c)+l,u=c+t.length,c=n.indexOf(t,u);while(~c);return i+n.substring(u)},"replaceClose"),r=m((n=a)=>{let t=n?d:()=>String;return{isColorSupported:n,reset:t("\x1B[0m","\x1B[0m"),bold:t("\x1B[1m","\x1B[22m","\x1B[22m\x1B[1m"),dim:t("\x1B[2m","\x1B[22m","\x1B[22m\x1B[2m"),italic:t("\x1B[3m","\x1B[23m"),underline:t("\x1B[4m","\x1B[24m"),inverse:t("\x1B[7m","\x1B[27m"),hidden:t("\x1B[8m","\x1B[28m"),strikethrough:t("\x1B[9m","\x1B[29m"),black:t("\x1B[30m","\x1B[39m"),red:t("\x1B[31m","\x1B[39m"),green:t("\x1B[32m","\x1B[39m"),yellow:t("\x1B[33m","\x1B[39m"),blue:t("\x1B[34m","\x1B[39m"),magenta:t("\x1B[35m","\x1B[39m"),cyan:t("\x1B[36m","\x1B[39m"),white:t("\x1B[37m","\x1B[39m"),gray:t("\x1B[90m","\x1B[39m"),bgBlack:t("\x1B[40m","\x1B[49m"),bgRed:t("\x1B[41m","\x1B[49m"),bgGreen:t("\x1B[42m","\x1B[49m"),bgYellow:t("\x1B[43m","\x1B[49m"),bgBlue:t("\x1B[44m","\x1B[49m"),bgMagenta:t("\x1B[45m","\x1B[49m"),bgCyan:t("\x1B[46m","\x1B[49m"),bgWhite:t("\x1B[47m","\x1B[49m"),blackBright:t("\x1B[90m","\x1B[39m"),redBright:t("\x1B[91m","\x1B[39m"),greenBright:t("\x1B[92m","\x1B[39m"),yellowBright:t("\x1B[93m","\x1B[39m"),blueBright:t("\x1B[94m","\x1B[39m"),magentaBright:t("\x1B[95m","\x1B[39m"),cyanBright:t("\x1B[96m","\x1B[39m"),whiteBright:t("\x1B[97m","\x1B[39m"),bgBlackBright:t("\x1B[100m","\x1B[49m"),bgRedBright:t("\x1B[101m","\x1B[49m"),bgGreenBright:t("\x1B[102m","\x1B[49m"),bgYellowBright:t("\x1B[103m","\x1B[49m"),bgBlueBright:t("\x1B[104m","\x1B[49m"),bgMagentaBright:t("\x1B[105m","\x1B[49m"),bgCyanBright:t("\x1B[106m","\x1B[49m"),bgWhiteBright:t("\x1B[107m","\x1B[49m")}},"createColors");return B.exports=r(),B.exports.createColors=r,B.exports}m(le,"requirePicocolors");var ce=le(),f=K(ce);const T=process?.versions?.node!==void 0,g={verbose:!1,log(...e){if(!this.verbose)return;const o=f.gray("[Log]");T?console.warn(o,...e):console.log(o,...e)},logPrefixed(e,...o){this.info(f.blue(`[${e}]`),...o)},info(...e){if(!this.verbose)return;const o=f.green("[Info]");T?console.warn(o,...e):console.info(o,...e)},infoPrefixed(e,...o){this.info(f.blue(`[${e}]`),...o)},warn(...e){console.warn(f.yellow("[Warning]"),...e)},warnPrefixed(e,...o){this.warn(f.blue(`[${e}]`),...o)},error(...e){console.error(f.red("[Error]"),...e)},errorPrefixed(e,...o){this.error(f.blue(`[${e}]`),...o)}},b={"anki-auto-launch":{alias:"l",default:!1,describe:"Attempt to open the Anki desktop app if it's not already running. (Experimental, macOS only.)",type:"boolean"}},R={"anki-web":{alias:"w",default:!0,describe:'Automatically sync any changes to AnkiWeb after Yanki has finished syncing locally. If false, only local Anki data is updated and you must manually invoke a sync to AnkiWeb. This is the equivalent of pushing the "sync" button in the Anki app.',type:"boolean"}},w={"anki-connect":{default:"http://127.0.0.1:8765",describe:"Host and port of the Anki-Connect server. The default is usually fine. See the Anki-Connect documentation for more information.",type:"string"}},P={verbose:{default:!1,describe:"Enable verbose logging.",type:"boolean"}};function k(e){return{json:{default:!1,describe:e,type:"boolean"}}}m(k,"jsonOption");const N={"dry-run":{alias:"d",default:!1,describe:"Run without making any changes to the Anki database. See a report of what would have been done.",type:"boolean"}};function E(e){return{namespace:{alias:"n",default:h.namespace,describe:e,type:"string"}}}m(E,"namespaceOption");const de={"strict-line-breaks":{alias:"b",default:h.strictLineBreaks,describe:"Set to false to treat single newlines in Markdown as line breaks.",type:"boolean"}};function v(e){const o=Q(e);if(o===void 0)throw new Error(`Invalid AnkiConnect URL: "${e}"`);return o}m(v,"urlToHostAndPortValidated");const C=m(e=>{throw e instanceof Error?(e.cause?.code==="ECONNREFUSED"&&(g.error("Failed to connect to Anki. Make sure Anki is running and AnkiConnect is installed."),process.exitCode=1,process.exit()),e):new Error("Unknown error")},"ankiNotRunningErrorHandler"),U=_(V(process.argv));await U.scriptName("yanki").usage("$0 [command]","Run a Yanki command. Defaults to `sync` if a command is not provided.").command(["$0 <directory> [options]","sync <directory> [options]"],"Perform a one-way synchronization from a local directory of Markdown files to the Anki database. Any Markdown files in subdirectories are included as well.",e=>e.positional("directory",{demandOption:!0,describe:"The path to the local directory of Markdown files to sync.",type:"string"}).option(N).option(E("Advanced option for managing multiple Yanki synchronization groups. Case insensitive. See the readme for more information.")).option(w).option(b).option(R).option("manage-filenames",{alias:"m",choices:["off","prompt","response"],default:h.manageFilenames,describe:'Rename local note files to match their content. Useful if you want to feel have semantically reasonable note file names without managing them by hand. The `"prompt"` option will attempt to create the filename based on the "front" of the card, while `"response"` will prioritize the "back", "Cloze", or "type in the answer" portions of the card. Truncation, sanitization, and deduplication are taken care of.',type:"string"}).option("max-filename-length",{default:void 0,defaultDescription:String(h.maxFilenameLength),describe:"If `manage-filenames` is enabled, this option specifies the maximum length of the filename in characters.",type:"number"}).option("sync-media",{alias:"s",choices:["off","all","local","remote"],default:h.syncMediaAssets,describe:"Sync image, video, and audio assets to Anki's media storage system. Clean up is managed automatically. The `all` argument will save both local and remote assets to Anki, while `local` will only save local assets, `remote` will only save remote assets, and `off` will not save any assets.",type:"string"}).option("strict-matching",{default:h.strictMatching,describe:'Consider notes to be a "match" only if the local Markdown frontmatter `noteId` matches the remote Anki database `noteId` exactly. When disabled, Yanki will attempt to reuse existing Anki notes whose content matches a local Markdown note, even if the local and remote `noteId` differs. This helps preserve study progress in Anki if the local Markdown frontmatter is lost or corrupted. In Yanki 0.17.0 and earlier, `--strict-matching` was the default behavior. Starting with version 0.18.0, it is disabled by default.',type:"boolean"}).option("check-database",{default:h.checkDatabase,describe:'Automatically run Anki\'s "Check Database" command after note model updates that might produce database corruption. In Yanki 1.0.2 and earlier, `--check-database false` was the default behavior. Starting with version 1.1.0, it is enabled by default.',type:"boolean"}).option(de).option(k("Output the sync report as JSON.")).option(P),async({ankiAutoLaunch:e,ankiConnect:o,ankiWeb:s,checkDatabase:a,directory:d,dryRun:p,json:r,manageFilenames:n,maxFilenameLength:t,namespace:l,recursive:c=!0,strictLineBreaks:i,strictMatching:u,syncMedia:D,verbose:M})=>{g.verbose=M;const A=O(ie(d)),J=c?`${A}/**/*.md`:`${A}/*.md`,Y=(await $(J,{absolute:!0})).map(S=>O(S)),z=(await $(`${A}/**/*`,{absolute:!0})).map(S=>O(S));if(Y.length===0){g.error(`No Markdown files found in "${d}".`),process.exitCode=1;return}n==="off"&&t!==void 0&&g.warn("Ignoring `max-filename-length` option because `manage-filenames` is not enabled.");const{host:H,port:j}=v(o),I=await X(Y,{allFilePaths:z,ankiConnectOptions:{autoLaunch:e,host:H,port:j},ankiWeb:s,checkDatabase:a,dryRun:p,manageFilenames:n,maxFilenameLength:t,namespace:l,strictLineBreaks:i,strictMatching:u,syncMediaAssets:D}).catch(C);r?(process.stdout.write(JSON.stringify(I,void 0,2)),process.stdout.write(`
|
|
3
|
+
`)):(process.stderr.write(Z(I,M)),process.stderr.write(`
|
|
4
|
+
`))}).command("list [options]","Utility command to list Yanki-created notes in the Anki database.",e=>e.option(E("Advanced option to list notes in a specific namespace. Case insensitive. Notes from the default internal namespace are listed by default. Pass `'*'` to list all Yanki-created notes in the Anki database.")).options(w).options(b).option(k("Output the list of notes as JSON to stdout.")),async({ankiAutoLaunch:e,ankiConnect:o,json:s,namespace:a})=>{const{host:d,port:p}=v(o),r=await ee({ankiConnectOptions:{autoLaunch:e,host:d,port:p},namespace:a}).catch(C);s?(process.stdout.write(JSON.stringify(r,void 0,2)),process.stdout.write(`
|
|
5
|
+
`)):(process.stdout.write(te(r)),process.stdout.write(`
|
|
6
|
+
`))}).command("delete [options]","Utility command to manually delete Yanki-created notes in the Anki database. This is for advanced use cases, usually the `sync` command takes care of deleting files from Anki Database once they're removed from the local file system.",e=>e.option(N).option(E("Advanced option to list notes in a specific namespace. Case insensitive. Notes from the default internal namespace are listed by default. If you've synced notes to multiple namespaces, Pass `'*'` to delete all Yanki-created notes in the Anki database.")).options(w).options(b).option(R).option(k("Output the list of deleted notes as JSON to stdout.")).option(P),async({ankiAutoLaunch:e,ankiConnect:o,ankiWeb:s,dryRun:a,json:d,namespace:p,verbose:r})=>{const{host:n,port:t}=v(o),l=await oe({ankiConnectOptions:{autoLaunch:e,host:n,port:t},ankiWeb:s,dryRun:a,namespace:p}).catch(C);d?(process.stdout.write(JSON.stringify(l,void 0,2)),process.stdout.write(`
|
|
7
|
+
`)):(process.stderr.write(ne(l,r)),process.stderr.write(`
|
|
8
|
+
`))}).command("style [options]","Utility command to set the CSS stylesheet for all present and future Yanki-created notes.",e=>e.option(N).option("css",{alias:"c",default:void 0,describe:"Path to the CSS stylesheet to set for all Yanki-created notes. If not provided, the default Anki stylesheet is used.",type:"string"}).options(w).options(b).option(R).option(k("Output the list of updated note types / models as JSON to stdout.")).option(P),async({ankiAutoLaunch:e,ankiConnect:o,ankiWeb:s,css:a,dryRun:d,json:p,verbose:r})=>{const{host:n,port:t}=v(o);let l;if(a!==void 0){if(W.extname(a)!==".css"){g.error("The provided CSS file must have a .css extension."),process.exitCode=1;return}try{l=await G.readFile(a,"utf8")}catch(i){i instanceof Error?g.error(`Error loading CSS file: ${i.message}`):g.error(`Unknown error loading CSS file: ${String(i)}`),process.exitCode=1;return}}const c=await se({ankiConnectOptions:{autoLaunch:e,host:n,port:t},ankiWeb:s,css:l??void 0,dryRun:d}).catch(C);p?(process.stdout.write(JSON.stringify(c,void 0,2)),process.stdout.write(`
|
|
9
|
+
`)):(process.stderr.write(ae(c,r)),process.stderr.write(`
|
|
10
|
+
`))}).demandCommand(1).alias("h","help").version(re).alias("v","version").help().wrap(process.stdout.isTTY?Math.min(120,U.terminalWidth()):0).parse();
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var U=Object.defineProperty;var n=(e,r)=>U(e,"name",{value:r,configurable:!0});import
|
|
2
|
-
tell application "System Events" to get value of property list item "CFBundleName" of property list file (app_path & ":Contents:Info.plist")`)}n(Q,"bundleName");const V=w(h),Z={AppXq0fevzme2pys62n3e0fbqa7peapykr8v:{name:"Edge",id:"com.microsoft.edge.old"},MSEdgeDHTML:{name:"Edge",id:"com.microsoft.edge"},MSEdgeHTM:{name:"Edge",id:"com.microsoft.edge"},"IE.HTTP":{name:"Internet Explorer",id:"com.microsoft.ie"},FirefoxURL:{name:"Firefox",id:"org.mozilla.firefox"},ChromeHTML:{name:"Chrome",id:"com.google.chrome"},BraveHTML:{name:"Brave",id:"com.brave.Browser"},BraveBHTML:{name:"Brave Beta",id:"com.brave.Browser.beta"},BraveSSHTM:{name:"Brave Nightly",id:"com.brave.Browser.nightly"}};class
|
|
1
|
+
var U=Object.defineProperty;var n=(e,r)=>U(e,"name",{value:r,configurable:!0});import c from"node:process";import{Buffer as F}from"node:buffer";import C from"node:path";import{fileURLToPath as _}from"node:url";import{promisify as w}from"node:util";import L,{execFile as h}from"node:child_process";import S,{constants as M}from"node:fs/promises";import R from"node:os";import x from"node:fs";let P;function N(){try{return x.statSync("/.dockerenv"),!0}catch{return!1}}n(N,"hasDockerEnv");function z(){try{return x.readFileSync("/proc/self/cgroup","utf8").includes("docker")}catch{return!1}}n(z,"hasDockerCGroup");function D(){return P===void 0&&(P=N()||z()),P}n(D,"isDocker");let b;const G=n(()=>{try{return x.statSync("/run/.containerenv"),!0}catch{return!1}},"hasContainerEnv");function E(){return b===void 0&&(b=G()||D()),b}n(E,"isInsideContainer");const $=n(()=>{if(c.platform!=="linux")return!1;if(R.release().toLowerCase().includes("microsoft"))return!E();try{return x.readFileSync("/proc/version","utf8").toLowerCase().includes("microsoft")?!E():!1}catch{return!1}},"isWsl");var g=c.env.__IS_WSL_TEST__?$:$();const X=(()=>{const e="/mnt/";let r;return async function(){if(r)return r;const o="/etc/wsl.conf";let i=!1;try{await S.access(o,M.F_OK),i=!0}catch{}if(!i)return e;const t=await S.readFile(o,{encoding:"utf8"}),s=/(?<!#.*)root\s*=\s*(?<mountPoint>.*)/g.exec(t);return s?(r=s.groups.mountPoint.trim(),r=r.endsWith("/")?r:`${r}/`,r):e}})(),K=n(async()=>`${await X()}c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe`,"powerShellPathFromWsl"),T=n(async()=>g?K():`${c.env.SYSTEMROOT||c.env.windir||String.raw`C:\Windows`}\\System32\\WindowsPowerShell\\v1.0\\powershell.exe`,"powerShellPath");function u(e,r,o){const i=n(t=>Object.defineProperty(e,r,{value:t,enumerable:!0,writable:!0}),"define");return Object.defineProperty(e,r,{configurable:!0,enumerable:!0,get(){const t=o();return i(t),t},set(t){i(t)}}),e}n(u,"defineLazyProperty");const q=w(h);async function Y(){if(c.platform!=="darwin")throw new Error("macOS only");const{stdout:e}=await q("defaults",["read","com.apple.LaunchServices/com.apple.launchservices.secure","LSHandlers"]);return/LSHandlerRoleAll = "(?!-)(?<id>[^"]+?)";\s+?LSHandlerURLScheme = (?:http|https);/.exec(e)?.groups.id??"com.apple.Safari"}n(Y,"defaultBrowserId");const j=w(h);async function J(e,{humanReadableOutput:r=!0,signal:o}={}){if(c.platform!=="darwin")throw new Error("macOS only");const i=r?[]:["-ss"],t={};o&&(t.signal=o);const{stdout:s}=await j("osascript",["-e",e,i],t);return s.trim()}n(J,"runAppleScript");async function Q(e){return J(`tell application "Finder" to set app_path to application file id "${e}" as string
|
|
2
|
+
tell application "System Events" to get value of property list item "CFBundleName" of property list file (app_path & ":Contents:Info.plist")`)}n(Q,"bundleName");const V=w(h),Z={AppXq0fevzme2pys62n3e0fbqa7peapykr8v:{name:"Edge",id:"com.microsoft.edge.old"},MSEdgeDHTML:{name:"Edge",id:"com.microsoft.edge"},MSEdgeHTM:{name:"Edge",id:"com.microsoft.edge"},"IE.HTTP":{name:"Internet Explorer",id:"com.microsoft.ie"},FirefoxURL:{name:"Firefox",id:"org.mozilla.firefox"},ChromeHTML:{name:"Chrome",id:"com.google.chrome"},BraveHTML:{name:"Brave",id:"com.brave.Browser"},BraveBHTML:{name:"Brave Beta",id:"com.brave.Browser.beta"},BraveSSHTM:{name:"Brave Nightly",id:"com.brave.Browser.nightly"}};class O extends Error{static{n(this,"UnknownBrowserError")}}async function ee(e=V){const{stdout:r}=await e("reg",["QUERY"," HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\Shell\\Associations\\UrlAssociations\\http\\UserChoice","/v","ProgId"]),o=/ProgId\s*REG_SZ\s*(?<id>\S+)/.exec(r);if(!o)throw new O(`Cannot find Windows browser in stdout: ${JSON.stringify(r)}`);const{id:i}=o.groups,t=Z[i];if(!t)throw new O(`Unknown browser ID: ${i}`);return t}n(ee,"defaultBrowser$1");const re=w(h),oe=n(e=>e.toLowerCase().replaceAll(/(?:^|\s|-)\S/g,r=>r.toUpperCase()),"titleize");async function te(){if(c.platform==="darwin"){const e=await Y();return{name:await Q(e),id:e}}if(c.platform==="linux"){const{stdout:e}=await re("xdg-mime",["query","default","x-scheme-handler/http"]),r=e.trim();return{name:oe(r.replace(/.desktop$/,"").replace("-"," ")),id:r}}if(c.platform==="win32")return ee();throw new Error("Only macOS, Linux, and Windows are supported")}n(te,"defaultBrowser");const ne=w(L.execFile),A=C.dirname(_(import.meta.url)),I=C.join(A,"xdg-open"),{platform:d,arch:k}=c;async function ie(){const e=await T(),r=String.raw`(Get-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\http\UserChoice").ProgId`,o=F.from(r,"utf16le").toString("base64"),{stdout:i}=await ne(e,["-NoProfile","-NonInteractive","-ExecutionPolicy","Bypass","-EncodedCommand",o],{encoding:"utf8"}),t=i.trim(),s={ChromeHTML:"com.google.chrome",BraveHTML:"com.brave.Browser",MSEdgeHTM:"com.microsoft.edge",FirefoxURL:"org.mozilla.firefox"};return s[t]?{id:s[t]}:{}}n(ie,"getWindowsDefaultBrowserFromWsl");const W=n(async(e,r)=>{let o;for(const i of e)try{return await r(i)}catch(t){o=t}throw o},"pTryEach"),y=n(async e=>{if(e={wait:!1,background:!1,newInstance:!1,allowNonzeroExitCode:!1,...e},Array.isArray(e.app))return W(e.app,a=>y({...e,app:a}));let{name:r,arguments:o=[]}=e.app??{};if(o=[...o],Array.isArray(r))return W(r,a=>y({...e,app:{name:a,arguments:o}}));if(r==="browser"||r==="browserPrivate"){const a={"com.google.chrome":"chrome","google-chrome.desktop":"chrome","com.brave.Browser":"brave","org.mozilla.firefox":"firefox","firefox.desktop":"firefox","com.microsoft.msedge":"edge","com.microsoft.edge":"edge","com.microsoft.edgemac":"edge","microsoft-edge.desktop":"edge"},l={chrome:"--incognito",brave:"--incognito",firefox:"--private-window",edge:"--inPrivate"},m=g?await ie():await te();if(m.id in a){const B=a[m.id];return r==="browserPrivate"&&o.push(l[B]),y({...e,app:{name:f[B],arguments:o}})}throw new Error(`${m.name} is not supported as a default browser`)}let i;const t=[],s={};if(d==="darwin")i="open",e.wait&&t.push("--wait-apps"),e.background&&t.push("--background"),e.newInstance&&t.push("--new"),r&&t.push("-a",r);else if(d==="win32"||g&&!E()&&!r){i=await T(),t.push("-NoProfile","-NonInteractive","-ExecutionPolicy","Bypass","-EncodedCommand"),g||(s.windowsVerbatimArguments=!0);const a=["Start"];e.wait&&a.push("-Wait"),r?(a.push(`"\`"${r}\`""`),e.target&&o.push(e.target)):e.target&&a.push(`"${e.target}"`),o.length>0&&(o=o.map(l=>`"\`"${l}\`""`),a.push("-ArgumentList",o.join(","))),e.target=F.from(a.join(" "),"utf16le").toString("base64")}else{if(r)i=r;else{const a=!A||A==="/";let l=!1;try{await S.access(I,M.X_OK),l=!0}catch{}i=c.versions.electron??(d==="android"||a||!l)?"xdg-open":I}o.length>0&&t.push(...o),e.wait||(s.stdio="ignore",s.detached=!0)}d==="darwin"&&o.length>0&&t.push("--args",...o),e.target&&t.push(e.target);const p=L.spawn(i,t,s);return e.wait?new Promise((a,l)=>{p.once("error",l),p.once("close",m=>{if(!e.allowNonzeroExitCode&&m>0){l(new Error(`Exited with code ${m}`));return}a(p)})}):(p.unref(),p)},"baseOpen"),ae=n((e,r)=>{if(typeof e!="string"&&!Array.isArray(e))throw new TypeError("Expected a valid `name`");const{arguments:o=[]}=r??{};if(o!=null&&!Array.isArray(o))throw new TypeError("Expected `appArguments` as Array type");return y({...r,app:{name:e,arguments:o}})},"openApp");function H(e){if(typeof e=="string"||Array.isArray(e))return e;const{[k]:r}=e;if(!r)throw new Error(`${k} is not supported`);return r}n(H,"detectArchBinary");function v({[d]:e},{wsl:r}){if(r&&g)return H(r);if(!e)throw new Error(`${d} is not supported`);return H(e)}n(v,"detectPlatformBinary");const f={};u(f,"chrome",()=>v({darwin:"google chrome",win32:"chrome",linux:["google-chrome","google-chrome-stable","chromium"]},{wsl:{ia32:"/mnt/c/Program Files (x86)/Google/Chrome/Application/chrome.exe",x64:["/mnt/c/Program Files/Google/Chrome/Application/chrome.exe","/mnt/c/Program Files (x86)/Google/Chrome/Application/chrome.exe"]}})),u(f,"brave",()=>v({darwin:"brave browser",win32:"brave",linux:["brave-browser","brave"]},{wsl:{ia32:"/mnt/c/Program Files (x86)/BraveSoftware/Brave-Browser/Application/brave.exe",x64:["/mnt/c/Program Files/BraveSoftware/Brave-Browser/Application/brave.exe","/mnt/c/Program Files (x86)/BraveSoftware/Brave-Browser/Application/brave.exe"]}})),u(f,"firefox",()=>v({darwin:"firefox",win32:String.raw`C:\Program Files\Mozilla Firefox\firefox.exe`,linux:"firefox"},{wsl:"/mnt/c/Program Files/Mozilla Firefox/firefox.exe"})),u(f,"edge",()=>v({darwin:"microsoft edge",win32:"msedge",linux:["microsoft-edge","microsoft-edge-dev"]},{wsl:"/mnt/c/Program Files (x86)/Microsoft/Edge/Application/msedge.exe"})),u(f,"browser",()=>"browser"),u(f,"browserPrivate",()=>"browserPrivate");export{f as apps,ae as openApp};
|
package/dist/lib/index.d.ts
CHANGED
|
@@ -12,13 +12,84 @@ type Primitive =
|
|
|
12
12
|
| symbol
|
|
13
13
|
| bigint;
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
15
|
+
/**
|
|
16
|
+
Returns a boolean for whether the given type is `any`.
|
|
17
|
+
|
|
18
|
+
@link https://stackoverflow.com/a/49928360/1490091
|
|
19
|
+
|
|
20
|
+
Useful in type utilities, such as disallowing `any`s to be passed to a function.
|
|
21
|
+
|
|
22
|
+
@example
|
|
23
|
+
```
|
|
24
|
+
import type {IsAny} from 'type-fest';
|
|
25
|
+
|
|
26
|
+
const typedObject = {a: 1, b: 2} as const;
|
|
27
|
+
const anyObject: any = {a: 1, b: 2};
|
|
28
|
+
|
|
29
|
+
function get<O extends (IsAny<O> extends true ? {} : Record<string, number>), K extends keyof O = keyof O>(obj: O, key: K) {
|
|
30
|
+
return obj[key];
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const typedA = get(typedObject, 'a');
|
|
34
|
+
//=> 1
|
|
35
|
+
|
|
36
|
+
const anyA = get(anyObject, 'a');
|
|
37
|
+
//=> any
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
@category Type Guard
|
|
41
|
+
@category Utilities
|
|
42
|
+
*/
|
|
43
|
+
type IsAny<T> = 0 extends 1 & NoInfer<T> ? true : false;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
Returns a boolean for whether the given key is an optional key of type.
|
|
47
|
+
|
|
48
|
+
This is useful when writing utility types or schema validators that need to differentiate `optional` keys.
|
|
49
|
+
|
|
50
|
+
@example
|
|
51
|
+
```
|
|
52
|
+
import type {IsOptionalKeyOf} from 'type-fest';
|
|
53
|
+
|
|
54
|
+
interface User {
|
|
55
|
+
name: string;
|
|
56
|
+
surname: string;
|
|
57
|
+
|
|
58
|
+
luckyNumber?: number;
|
|
20
59
|
}
|
|
21
60
|
|
|
61
|
+
interface Admin {
|
|
62
|
+
name: string;
|
|
63
|
+
surname?: string;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
type T1 = IsOptionalKeyOf<User, 'luckyNumber'>;
|
|
67
|
+
//=> true
|
|
68
|
+
|
|
69
|
+
type T2 = IsOptionalKeyOf<User, 'name'>;
|
|
70
|
+
//=> false
|
|
71
|
+
|
|
72
|
+
type T3 = IsOptionalKeyOf<User, 'name' | 'luckyNumber'>;
|
|
73
|
+
//=> boolean
|
|
74
|
+
|
|
75
|
+
type T4 = IsOptionalKeyOf<User | Admin, 'name'>;
|
|
76
|
+
//=> false
|
|
77
|
+
|
|
78
|
+
type T5 = IsOptionalKeyOf<User | Admin, 'surname'>;
|
|
79
|
+
//=> boolean
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
@category Type Guard
|
|
83
|
+
@category Utilities
|
|
84
|
+
*/
|
|
85
|
+
type IsOptionalKeyOf<Type extends object, Key extends keyof Type> =
|
|
86
|
+
IsAny<Type | Key> extends true ? never
|
|
87
|
+
: Key extends keyof Type
|
|
88
|
+
? Type extends Record<Key, Type[Key]>
|
|
89
|
+
? false
|
|
90
|
+
: true
|
|
91
|
+
: false;
|
|
92
|
+
|
|
22
93
|
/**
|
|
23
94
|
Extract all optional keys from the given type.
|
|
24
95
|
|
|
@@ -52,11 +123,14 @@ const update2: UpdateOperation<User> = {
|
|
|
52
123
|
|
|
53
124
|
@category Utilities
|
|
54
125
|
*/
|
|
55
|
-
type OptionalKeysOf<
|
|
56
|
-
|
|
57
|
-
? (keyof {
|
|
58
|
-
|
|
59
|
-
|
|
126
|
+
type OptionalKeysOf<Type extends object> =
|
|
127
|
+
Type extends unknown // For distributing `Type`
|
|
128
|
+
? (keyof {[Key in keyof Type as
|
|
129
|
+
IsOptionalKeyOf<Type, Key> extends false
|
|
130
|
+
? never
|
|
131
|
+
: Key
|
|
132
|
+
]: never
|
|
133
|
+
}) & keyof Type // Intersect with `keyof Type` to ensure result of `OptionalKeysOf<Type>` is always assignable to `keyof Type`
|
|
60
134
|
: never; // Should never happen
|
|
61
135
|
|
|
62
136
|
/**
|
|
@@ -83,9 +157,9 @@ const validator2 = createValidation<User>('surname', value => value.length < 25)
|
|
|
83
157
|
|
|
84
158
|
@category Utilities
|
|
85
159
|
*/
|
|
86
|
-
type RequiredKeysOf<
|
|
87
|
-
|
|
88
|
-
? Exclude<keyof
|
|
160
|
+
type RequiredKeysOf<Type extends object> =
|
|
161
|
+
Type extends unknown // For distributing `Type`
|
|
162
|
+
? Exclude<keyof Type, OptionalKeysOf<Type>>
|
|
89
163
|
: never; // Should never happen
|
|
90
164
|
|
|
91
165
|
/**
|
|
@@ -132,61 +206,73 @@ endIfEqual('abc', '123');
|
|
|
132
206
|
type IsNever<T> = [T] extends [never] ? true : false;
|
|
133
207
|
|
|
134
208
|
/**
|
|
135
|
-
An if-else-like type that resolves depending on whether the given type is `
|
|
209
|
+
An if-else-like type that resolves depending on whether the given `boolean` type is `true` or `false`.
|
|
210
|
+
|
|
211
|
+
Use-cases:
|
|
212
|
+
- You can use this in combination with `Is*` types to create an if-else-like experience. For example, `If<IsAny<any>, 'is any', 'not any'>`.
|
|
136
213
|
|
|
137
|
-
|
|
214
|
+
Note:
|
|
215
|
+
- Returns a union of if branch and else branch if the given type is `boolean` or `any`. For example, `If<boolean, 'Y', 'N'>` will return `'Y' | 'N'`.
|
|
216
|
+
- Returns the else branch if the given type is `never`. For example, `If<never, 'Y', 'N'>` will return `'N'`.
|
|
138
217
|
|
|
139
218
|
@example
|
|
140
219
|
```
|
|
141
|
-
import
|
|
220
|
+
import {If} from 'type-fest';
|
|
142
221
|
|
|
143
|
-
type
|
|
144
|
-
//=>
|
|
222
|
+
type A = If<true, 'yes', 'no'>;
|
|
223
|
+
//=> 'yes'
|
|
145
224
|
|
|
146
|
-
type
|
|
147
|
-
//=> '
|
|
148
|
-
```
|
|
225
|
+
type B = If<false, 'yes', 'no'>;
|
|
226
|
+
//=> 'no'
|
|
149
227
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
*/
|
|
153
|
-
type IfNever<T, TypeIfNever = true, TypeIfNotNever = false> = (
|
|
154
|
-
IsNever<T> extends true ? TypeIfNever : TypeIfNotNever
|
|
155
|
-
);
|
|
228
|
+
type C = If<boolean, 'yes', 'no'>;
|
|
229
|
+
//=> 'yes' | 'no'
|
|
156
230
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
type NoInfer<T> = T extends infer U ? U : never;
|
|
231
|
+
type D = If<any, 'yes', 'no'>;
|
|
232
|
+
//=> 'yes' | 'no'
|
|
160
233
|
|
|
161
|
-
|
|
162
|
-
|
|
234
|
+
type E = If<never, 'yes', 'no'>;
|
|
235
|
+
//=> 'no'
|
|
236
|
+
```
|
|
163
237
|
|
|
164
|
-
@
|
|
238
|
+
@example
|
|
239
|
+
```
|
|
240
|
+
import {If, IsAny, IsNever} from 'type-fest';
|
|
165
241
|
|
|
166
|
-
|
|
242
|
+
type A = If<IsAny<unknown>, 'is any', 'not any'>;
|
|
243
|
+
//=> 'not any'
|
|
167
244
|
|
|
168
|
-
|
|
245
|
+
type B = If<IsNever<never>, 'is never', 'not never'>;
|
|
246
|
+
//=> 'is never'
|
|
169
247
|
```
|
|
170
|
-
import type {IsAny} from 'type-fest';
|
|
171
248
|
|
|
172
|
-
|
|
173
|
-
|
|
249
|
+
@example
|
|
250
|
+
```
|
|
251
|
+
import {If, IsEqual} from 'type-fest';
|
|
174
252
|
|
|
175
|
-
|
|
176
|
-
return obj[key];
|
|
177
|
-
}
|
|
253
|
+
type IfEqual<T, U, IfBranch, ElseBranch> = If<IsEqual<T, U>, IfBranch, ElseBranch>;
|
|
178
254
|
|
|
179
|
-
|
|
180
|
-
//=>
|
|
255
|
+
type A = IfEqual<string, string, 'equal', 'not equal'>;
|
|
256
|
+
//=> 'equal'
|
|
181
257
|
|
|
182
|
-
|
|
183
|
-
//=>
|
|
258
|
+
type B = IfEqual<string, number, 'equal', 'not equal'>;
|
|
259
|
+
//=> 'not equal'
|
|
184
260
|
```
|
|
185
261
|
|
|
186
262
|
@category Type Guard
|
|
187
263
|
@category Utilities
|
|
188
264
|
*/
|
|
189
|
-
type
|
|
265
|
+
type If<Type extends boolean, IfBranch, ElseBranch> =
|
|
266
|
+
IsNever<Type> extends true
|
|
267
|
+
? ElseBranch
|
|
268
|
+
: Type extends true
|
|
269
|
+
? IfBranch
|
|
270
|
+
: ElseBranch;
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
Matches any primitive, `void`, `Date`, or `RegExp` value.
|
|
274
|
+
*/
|
|
275
|
+
type BuiltIns = Primitive | void | Date | RegExp;
|
|
190
276
|
|
|
191
277
|
/**
|
|
192
278
|
Useful to flatten the type output to improve type hints shown in editors. And also to transform an interface into a type to aide with assignability.
|
|
@@ -435,38 +521,10 @@ export type FooBar = Merge<Foo, Bar>;
|
|
|
435
521
|
*/
|
|
436
522
|
type Merge<Destination, Source> =
|
|
437
523
|
Simplify<
|
|
438
|
-
SimpleMerge<PickIndexSignature<Destination>, PickIndexSignature<Source>>
|
|
439
|
-
& SimpleMerge<OmitIndexSignature<Destination>, OmitIndexSignature<Source>>
|
|
524
|
+
SimpleMerge<PickIndexSignature<Destination>, PickIndexSignature<Source>>
|
|
525
|
+
& SimpleMerge<OmitIndexSignature<Destination>, OmitIndexSignature<Source>>
|
|
440
526
|
>;
|
|
441
527
|
|
|
442
|
-
/**
|
|
443
|
-
An if-else-like type that resolves depending on whether the given type is `any`.
|
|
444
|
-
|
|
445
|
-
@see {@link IsAny}
|
|
446
|
-
|
|
447
|
-
@example
|
|
448
|
-
```
|
|
449
|
-
import type {IfAny} from 'type-fest';
|
|
450
|
-
|
|
451
|
-
type ShouldBeTrue = IfAny<any>;
|
|
452
|
-
//=> true
|
|
453
|
-
|
|
454
|
-
type ShouldBeBar = IfAny<'not any', 'foo', 'bar'>;
|
|
455
|
-
//=> 'bar'
|
|
456
|
-
```
|
|
457
|
-
|
|
458
|
-
@category Type Guard
|
|
459
|
-
@category Utilities
|
|
460
|
-
*/
|
|
461
|
-
type IfAny<T, TypeIfAny = true, TypeIfNotAny = false> = (
|
|
462
|
-
IsAny<T> extends true ? TypeIfAny : TypeIfNotAny
|
|
463
|
-
);
|
|
464
|
-
|
|
465
|
-
/**
|
|
466
|
-
Matches any primitive, `void`, `Date`, or `RegExp` value.
|
|
467
|
-
*/
|
|
468
|
-
type BuiltIns = Primitive | void | Date | RegExp;
|
|
469
|
-
|
|
470
528
|
/**
|
|
471
529
|
Merges user specified options with default options.
|
|
472
530
|
|
|
@@ -524,18 +582,13 @@ type ApplyDefaultOptions<
|
|
|
524
582
|
Defaults extends Simplify<Omit<Required<Options>, RequiredKeysOf<Options>> & Partial<Record<RequiredKeysOf<Options>, never>>>,
|
|
525
583
|
SpecifiedOptions extends Options,
|
|
526
584
|
> =
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
: never
|
|
535
|
-
: Key
|
|
536
|
-
]: SpecifiedOptions[Key]
|
|
537
|
-
}> & Required<Options>> // `& Required<Options>` ensures that `ApplyDefaultOptions<SomeOption, ...>` is always assignable to `Required<SomeOption>`
|
|
538
|
-
>>;
|
|
585
|
+
If<IsAny<SpecifiedOptions>, Defaults,
|
|
586
|
+
If<IsNever<SpecifiedOptions>, Defaults,
|
|
587
|
+
Simplify<Merge<Defaults, {
|
|
588
|
+
[Key in keyof SpecifiedOptions
|
|
589
|
+
as Key extends OptionalKeysOf<Options> ? undefined extends SpecifiedOptions[Key] ? never : Key : Key
|
|
590
|
+
]: SpecifiedOptions[Key]
|
|
591
|
+
}> & Required<Options>>>>;
|
|
539
592
|
|
|
540
593
|
/**
|
|
541
594
|
@see {@link PartialDeep}
|
|
@@ -554,10 +607,10 @@ type PartialDeepOptions = {
|
|
|
554
607
|
- When set to `true`, elements of non-tuple arrays can be `undefined`.
|
|
555
608
|
- When set to `false`, only explicitly defined elements are allowed in non-tuple arrays, ensuring stricter type checking.
|
|
556
609
|
|
|
557
|
-
@default
|
|
610
|
+
@default false
|
|
558
611
|
|
|
559
612
|
@example
|
|
560
|
-
You can
|
|
613
|
+
You can allow `undefined` values in non-tuple arrays by passing `{recurseIntoArrays: true; allowUndefinedInNonTupleArrays: true}` as the second type argument:
|
|
561
614
|
|
|
562
615
|
```
|
|
563
616
|
import type {PartialDeep} from 'type-fest';
|
|
@@ -566,10 +619,9 @@ type PartialDeepOptions = {
|
|
|
566
619
|
languages: string[];
|
|
567
620
|
};
|
|
568
621
|
|
|
569
|
-
declare const partialSettings: PartialDeep<Settings, {recurseIntoArrays: true; allowUndefinedInNonTupleArrays:
|
|
622
|
+
declare const partialSettings: PartialDeep<Settings, {recurseIntoArrays: true; allowUndefinedInNonTupleArrays: true}>;
|
|
570
623
|
|
|
571
|
-
partialSettings.languages = [undefined]; //
|
|
572
|
-
partialSettings.languages = []; // Ok
|
|
624
|
+
partialSettings.languages = [undefined]; // OK
|
|
573
625
|
```
|
|
574
626
|
*/
|
|
575
627
|
readonly allowUndefinedInNonTupleArrays?: boolean;
|
|
@@ -577,7 +629,7 @@ type PartialDeepOptions = {
|
|
|
577
629
|
|
|
578
630
|
type DefaultPartialDeepOptions = {
|
|
579
631
|
recurseIntoArrays: false;
|
|
580
|
-
allowUndefinedInNonTupleArrays:
|
|
632
|
+
allowUndefinedInNonTupleArrays: false;
|
|
581
633
|
};
|
|
582
634
|
|
|
583
635
|
/**
|
|
@@ -591,19 +643,19 @@ Use-cases:
|
|
|
591
643
|
```
|
|
592
644
|
import type {PartialDeep} from 'type-fest';
|
|
593
645
|
|
|
594
|
-
|
|
646
|
+
let settings = {
|
|
595
647
|
textEditor: {
|
|
596
648
|
fontSize: 14,
|
|
597
649
|
fontColor: '#000000',
|
|
598
|
-
fontWeight: 400
|
|
650
|
+
fontWeight: 400,
|
|
599
651
|
},
|
|
600
652
|
autocomplete: false,
|
|
601
|
-
autosave: true
|
|
653
|
+
autosave: true,
|
|
602
654
|
};
|
|
603
655
|
|
|
604
|
-
const applySavedSettings = (savedSettings: PartialDeep<
|
|
605
|
-
|
|
606
|
-
|
|
656
|
+
const applySavedSettings = (savedSettings: PartialDeep<typeof settings>) => (
|
|
657
|
+
{...settings, ...savedSettings, textEditor: {...settings.textEditor, ...savedSettings.textEditor}}
|
|
658
|
+
);
|
|
607
659
|
|
|
608
660
|
settings = applySavedSettings({textEditor: {fontWeight: 500}});
|
|
609
661
|
```
|
|
@@ -613,13 +665,15 @@ By default, this does not affect elements in array and tuple types. You can chan
|
|
|
613
665
|
```
|
|
614
666
|
import type {PartialDeep} from 'type-fest';
|
|
615
667
|
|
|
616
|
-
type
|
|
617
|
-
|
|
618
|
-
}
|
|
668
|
+
type Shape = {
|
|
669
|
+
dimensions: [number, number];
|
|
670
|
+
};
|
|
619
671
|
|
|
620
|
-
const
|
|
621
|
-
|
|
672
|
+
const partialShape: PartialDeep<Shape, {recurseIntoArrays: true}> = {
|
|
673
|
+
dimensions: [], // OK
|
|
622
674
|
};
|
|
675
|
+
|
|
676
|
+
partialShape.dimensions = [15]; // OK
|
|
623
677
|
```
|
|
624
678
|
|
|
625
679
|
@see {@link PartialDeepOptions}
|
|
@@ -683,8 +737,8 @@ type PartialObjectDeep<ObjectType extends object, Options extends Required<Parti
|
|
|
683
737
|
(ObjectType extends (...arguments_: any) => unknown
|
|
684
738
|
? (...arguments_: Parameters<ObjectType>) => ReturnType<ObjectType>
|
|
685
739
|
: {}) & ({
|
|
686
|
-
|
|
687
|
-
|
|
740
|
+
[KeyType in keyof ObjectType]?: _PartialDeep<ObjectType[KeyType], Options>
|
|
741
|
+
});
|
|
688
742
|
|
|
689
743
|
type CardBrowserColumns = 'answer' | 'cardDue' | 'cardEase' | 'cardIvl' | 'cardLapses' | 'cardMod' | 'cardReps' | 'deck' | 'note' | 'noteCrt' | 'noteFld' | 'noteMod' | 'noteTags' | 'question' | 'template' | (string & {});
|
|
690
744
|
type CardValueKeys = 'data' | 'did' | 'due' | 'factor' | 'flags' | 'id' | 'ivl' | 'lapses' | 'left' | 'mod' | 'odid' | 'odue' | 'ord' | 'queue' | 'reps' | 'type' | 'usn';
|
|
@@ -771,7 +825,7 @@ type DeckStats = {
|
|
|
771
825
|
};
|
|
772
826
|
type DeckConfig = {
|
|
773
827
|
autoplay: boolean;
|
|
774
|
-
dyn:
|
|
828
|
+
dyn: 1 | false;
|
|
775
829
|
id: number;
|
|
776
830
|
lapse: {
|
|
777
831
|
delays: number[];
|
|
@@ -1374,6 +1428,8 @@ type GlobalOptions = {
|
|
|
1374
1428
|
ankiWeb: boolean;
|
|
1375
1429
|
/** Override where "/" should resolve to... useful in Obsidian to set the vault path as the "root" */
|
|
1376
1430
|
basePath: string | undefined;
|
|
1431
|
+
/** Run Anki's "Check Database" command after sync updates that might produce card corruption */
|
|
1432
|
+
checkDatabase: boolean;
|
|
1377
1433
|
cwd: string;
|
|
1378
1434
|
dryRun: boolean;
|
|
1379
1435
|
/**
|
|
@@ -1416,7 +1472,7 @@ type CleanResult = Simplify<Pick<GlobalOptions, 'ankiWeb' | 'dryRun' | 'namespac
|
|
|
1416
1472
|
*
|
|
1417
1473
|
* Use with significant caution. Mostly useful for testing.
|
|
1418
1474
|
* @returns The IDs of the notes that were deleted
|
|
1419
|
-
* @throws
|
|
1475
|
+
* @throws {Error} If Anki is unreachable or another error occurs during deletion.
|
|
1420
1476
|
*/
|
|
1421
1477
|
declare function cleanNotes(options?: PartialDeep<CleanOptions>): Promise<CleanResult>;
|
|
1422
1478
|
declare function formatCleanResult(result: CleanResult, verbose?: boolean): string;
|
|
@@ -1477,12 +1533,13 @@ type SyncedNote = {
|
|
|
1477
1533
|
action: 'ankiUnreachable' | 'created' | 'deleted' | 'matched' | 'unchanged' | 'updated';
|
|
1478
1534
|
note: YankiNote;
|
|
1479
1535
|
};
|
|
1480
|
-
type SyncNotesOptions = Pick<GlobalOptions, 'ankiConnectOptions' | 'ankiWeb' | 'dryRun' | 'namespace' | 'strictMatching'>;
|
|
1536
|
+
type SyncNotesOptions = Pick<GlobalOptions, 'ankiConnectOptions' | 'ankiWeb' | 'checkDatabase' | 'dryRun' | 'namespace' | 'strictMatching'>;
|
|
1481
1537
|
declare const defaultSyncNotesOptions: SyncNotesOptions;
|
|
1482
1538
|
type SyncNotesResult = Simplify<Pick<GlobalOptions, 'ankiWeb' | 'dryRun' | 'namespace'> & {
|
|
1483
1539
|
deletedDecks: string[];
|
|
1484
1540
|
deletedMedia: string[];
|
|
1485
1541
|
duration: number;
|
|
1542
|
+
fixedDatabase: boolean;
|
|
1486
1543
|
synced: SyncedNote[];
|
|
1487
1544
|
}>;
|
|
1488
1545
|
/**
|
|
@@ -1512,7 +1569,7 @@ type SyncFilesResult = Simplify<Omit<SyncNotesResult, 'synced'> & {
|
|
|
1512
1569
|
* @param allLocalFilePaths Array of paths to the local markdown files
|
|
1513
1570
|
* @returns The synced files (with new IDs where applicable), plus some stats
|
|
1514
1571
|
* about the sync
|
|
1515
|
-
* @throws
|
|
1572
|
+
* @throws {Error} If syncing fails or file operations encounter an error.
|
|
1516
1573
|
*/
|
|
1517
1574
|
declare function syncFiles(allLocalFilePaths: string[], options?: PartialDeep<SyncFilesOptions>): Promise<SyncFilesResult>;
|
|
1518
1575
|
declare function formatSyncFilesResult(result: SyncFilesResult, verbose?: boolean): string;
|
package/dist/lib/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{c as n,d as i,q as r,g as f,a as m,e as p,h as u,k as d,o as y,f as S,b as O,i as c,m as F,t as N,j as R,u as g,l as k,r as h,s as w,n as A,p as C,v as G}from"../sync-files-
|
|
1
|
+
import{c as n,d as i,q as r,g as f,a as m,e as p,h as u,k as d,o as y,f as S,b as O,i as c,m as F,t as N,j as R,u as g,l as k,r as h,s as w,n as A,p as C,v as G}from"../sync-files-S6DH9ijG.js";import"process";import"rehype-parse";import"node:path";import"node:crypto";export{n as cleanNotes,i as defaultCleanOptions,r as defaultGetNoteFromMarkdownOptions,f as defaultGetStyleOptions,m as defaultListOptions,p as defaultRenameFilesOptions,u as defaultSetStyleOptions,d as defaultSyncFilesOptions,y as defaultSyncNotesOptions,S as formatCleanResult,O as formatListResult,c as formatSetStyleResult,F as formatSyncFilesResult,N as getNoteFromMarkdown,R as getStyle,g as hostAndPortToUrl,k as listNotes,h as renameFiles,w as setStyle,A as syncFiles,C as syncNotes,G as urlToHostAndPort};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const e=Object.freeze(JSON.parse('{"displayName":"Luau","fileTypes":["luau"],"name":"luau","patterns":[{"include":"#function-definition"},{"include":"#number"},{"include":"#string"},{"include":"#shebang"},{"include":"#comment"},{"include":"#local-declaration"},{"include":"#for-loop"},{"include":"#type-function"},{"include":"#type-alias-declaration"},{"include":"#keyword"},{"include":"#language_constant"},{"include":"#standard_library"},{"include":"#identifier"},{"include":"#operator"},{"include":"#parentheses"},{"include":"#table"},{"include":"#type_cast"},{"include":"#type_annotation"},{"include":"#attribute"}],"repository":{"attribute":{"patterns":[{"captures":{"1":{"name":"keyword.operator.attribute.luau"},"2":{"name":"storage.type.attribute.luau"}},"match":"(@)([A-Z_a-z][0-9A-Z_a-z]*)","name":"meta.attribute.luau"}]},"comment":{"patterns":[{"begin":"--\\\\[(=*)\\\\[","end":"]\\\\1]","name":"comment.block.luau","patterns":[{"begin":"(```luau?)\\\\s+","beginCaptures":{"1":{"name":"comment.luau"}},"end":"(```)","endCaptures":{"1":{"name":"comment.luau"}},"name":"keyword.operator.other.luau","patterns":[{"include":"source.luau"}]},{"include":"#doc_comment_tags"}]},{"begin":"---","end":"\\\\n","name":"comment.line.double-dash.documentation.luau","patterns":[{"include":"#doc_comment_tags"}]},{"begin":"--","end":"\\\\n","name":"comment.line.double-dash.luau"}]},"doc_comment_tags":{"patterns":[{"match":"@\\\\w+","name":"storage.type.class.luadoc.luau"},{"captures":{"1":{"name":"storage.type.class.luadoc.luau"},"2":{"name":"variable.parameter.luau"}},"match":"((?<=[!*/\\\\s])[@\\\\\\\\]param)\\\\s+\\\\b(\\\\w+)\\\\b"}]},"for-loop":{"begin":"\\\\b(for)\\\\b","beginCaptures":{"1":{"name":"keyword.control.luau"}},"end":"\\\\b(in)\\\\b|(=)","endCaptures":{"1":{"name":"keyword.control.luau"},"2":{"name":"keyword.operator.assignment.luau"}},"patterns":[{"begin":"(:)","beginCaptures":{"1":{"name":"keyword.operator.type.luau"}},"end":"(?=\\\\s*in\\\\b|\\\\s*[,=]|\\\\s*$)","patterns":[{"include":"#type_literal"}]},{"match":"\\\\b([A-Z_a-z][0-9A-Z_a-z]*)\\\\b","name":"variable.parameter.luau"}]},"function-definition":{"begin":"\\\\b(?:(local)\\\\s+)?(function)\\\\b(?![,:])","beginCaptures":{"1":{"name":"storage.modifier.local.luau"},"2":{"name":"keyword.control.luau"}},"end":"(?<=[-\\\\]\\"\')\\\\[{}])","name":"meta.function.luau","patterns":[{"include":"#comment"},{"include":"#generics-declaration"},{"begin":"(\\\\()","beginCaptures":{"1":{"name":"punctuation.definition.parameters.begin.luau"}},"end":"(\\\\))","endCaptures":{"1":{"name":"punctuation.definition.parameters.end.luau"}},"name":"meta.parameter.luau","patterns":[{"include":"#comment"},{"match":"\\\\.\\\\.\\\\.","name":"variable.parameter.function.varargs.luau"},{"match":"[A-Z_a-z][0-9A-Z_a-z]*","name":"variable.parameter.function.luau"},{"match":",","name":"punctuation.separator.arguments.luau"},{"begin":":","beginCaptures":{"0":{"name":"keyword.operator.type.luau"}},"end":"(?=[),])","patterns":[{"include":"#type_literal"}]}]},{"match":"\\\\b(__(?:add|call|concat|div|eq|index|len??|lt|metatable|mode??|mul|newindex|pow|sub|tostring|unm|iter|idiv))\\\\b","name":"variable.language.metamethod.luau"},{"match":"\\\\b([A-Z_a-z][0-9A-Z_a-z]*)\\\\b","name":"entity.name.function.luau"}]},"generics-declaration":{"begin":"(<)","end":"(>)","patterns":[{"match":"[A-Z_a-z][0-9A-Z_a-z]*","name":"entity.name.type.luau"},{"match":"=","name":"keyword.operator.assignment.luau"},{"include":"#type_literal"}]},"identifier":{"patterns":[{"match":"\\\\b([A-Z_a-z][0-9A-Z_a-z]*)\\\\b(?=\\\\s*(?:[\\"\'({]|\\\\[\\\\[))","name":"entity.name.function.luau"},{"match":"(?<=[^.]\\\\.|:)\\\\b([A-Z_a-z][0-9A-Z_a-z]*)\\\\b","name":"variable.other.property.luau"},{"match":"\\\\b([A-Z_][0-9A-Z_]*)\\\\b","name":"variable.other.constant.luau"},{"match":"\\\\b([A-Z_a-z][0-9A-Z_a-z]*)\\\\b","name":"variable.other.readwrite.luau"}]},"interpolated_string_expression":{"begin":"\\\\{","beginCaptures":{"0":{"name":"punctuation.definition.interpolated-string-expression.begin.luau"}},"contentName":"meta.embedded.line.luau","end":"}","endCaptures":{"0":{"name":"punctuation.definition.interpolated-string-expression.end.luau"}},"name":"meta.template.expression.luau","patterns":[{"include":"source.luau"}]},"keyword":{"patterns":[{"match":"\\\\b(break|do|else|for|if|elseif|return|then|repeat|while|until|end|in|continue)\\\\b","name":"keyword.control.luau"},{"match":"\\\\b(local)\\\\b","name":"storage.modifier.local.luau"},{"match":"\\\\b(function)\\\\b(?![,:])","name":"keyword.control.luau"},{"match":"(?<![^.]\\\\.|:)\\\\b(self)\\\\b","name":"variable.language.self.luau"},{"match":"\\\\b(and|or|not)\\\\b","name":"keyword.operator.logical.luau keyword.operator.wordlike.luau"},{"match":"(?<=[^.]\\\\.|:)\\\\b(__(?:add|call|concat|div|eq|index|len??|lt|metatable|mode??|mul|newindex|pow|sub|tostring|unm))\\\\b","name":"variable.language.metamethod.luau"},{"match":"(?<!\\\\.)\\\\.{3}(?!\\\\.)","name":"keyword.other.unit.luau"}]},"language_constant":{"patterns":[{"match":"(?<![^.]\\\\.|:)\\\\b(false)\\\\b","name":"constant.language.boolean.false.luau"},{"match":"(?<![^.]\\\\.|:)\\\\b(true)\\\\b","name":"constant.language.boolean.true.luau"},{"match":"(?<![^.]\\\\.|:)\\\\b(nil(?!:))\\\\b","name":"constant.language.nil.luau"}]},"local-declaration":{"begin":"\\\\b(local)\\\\b","beginCaptures":{"1":{"name":"storage.modifier.local.luau"}},"end":"(?=\\\\s*do\\\\b|\\\\s*[;=]|\\\\s*$)","patterns":[{"include":"#comment"},{"include":"#attribute"},{"begin":"(:)","beginCaptures":{"1":{"name":"keyword.operator.type.luau"}},"end":"(?=\\\\s*do\\\\b|\\\\s*[,;=]|\\\\s*$)","patterns":[{"include":"#type_literal"}]},{"match":"\\\\b([A-Z_][0-9A-Z_]*)\\\\b","name":"variable.other.constant.luau"},{"match":"\\\\b([A-Z_a-z][0-9A-Z_a-z]*)\\\\b","name":"variable.other.readwrite.luau"}]},"number":{"patterns":[{"match":"\\\\b0_*[Xx]_*[A-F_a-f\\\\d]*(?:[Ee][-+]?_*\\\\d[_\\\\d]*(?:\\\\.[_\\\\d]*)?)?","name":"constant.numeric.hex.luau"},{"match":"\\\\b0_*[Bb][01_]+(?:[Ee][-+]?_*\\\\d[_\\\\d]*(?:\\\\.[_\\\\d]*)?)?","name":"constant.numeric.binary.luau"},{"match":"(?:\\\\d[_\\\\d]*(?:\\\\.[_\\\\d]*)?|\\\\.\\\\d[_\\\\d]*)(?:[Ee][-+]?_*\\\\d[_\\\\d]*(?:\\\\.[_\\\\d]*)?)?","name":"constant.numeric.decimal.luau"}]},"operator":{"patterns":[{"match":"==|~=|!=|<=?|>=?","name":"keyword.operator.comparison.luau"},{"match":"(?:[-+]|//??|[%*^]|\\\\.\\\\.|)=","name":"keyword.operator.assignment.luau"},{"match":"[-%*+]|//|[/^]","name":"keyword.operator.arithmetic.luau"},{"match":"#|(?<!\\\\.)\\\\.{2}(?!\\\\.)","name":"keyword.operator.other.luau"}]},"parentheses":{"begin":"(\\\\()","beginCaptures":{"1":{"name":"punctuation.arguments.begin.luau"}},"end":"(\\\\))","endCaptures":{"1":{"name":"punctuation.arguments.end.luau"}},"patterns":[{"match":",","name":"punctuation.separator.arguments.luau"},{"include":"source.luau"}]},"shebang":{"captures":{"1":{"name":"punctuation.definition.comment.luau"}},"match":"\\\\A(#!).*$\\\\n?","name":"comment.line.shebang.luau"},"standard_library":{"patterns":[{"match":"(?<![^.]\\\\.|:)\\\\b(assert|collectgarbage|error|gcinfo|getfenv|getmetatable|ipairs|loadstring|newproxy|next|pairs|pcall|print|rawequal|rawset|require|select|setfenv|setmetatable|tonumber|tostring|type|typeof|unpack|xpcall)\\\\b","name":"support.function.luau"},{"match":"(?<![^.]\\\\.|:)\\\\b(_(?:G|VERSION))\\\\b","name":"constant.language.luau"},{"match":"(?<![^.]\\\\.|:)\\\\b(bit32\\\\.(?:arshift|band|bnot|bor|btest|bxor|extract|lrotate|lshift|replace|rrotate|rshift|countlz|countrz|byteswap)|coroutine\\\\.(?:create|isyieldable|resume|running|status|wrap|yield|close)|debug\\\\.(?:info|loadmodule|profilebegin|profileend|traceback)|math\\\\.(?:abs|acos|asin|atan2??|ceil|clamp|cosh??|deg|exp|floor|fmod|frexp|ldexp|log|log10|max|min|modf|noise|pow|rad|random|randomseed|round|sign|sinh??|sqrt|tanh??)|os\\\\.(?:clock|date|difftime|time)|string\\\\.(?:byte|char|find|format|gmatch|gsub|len|lower|match|pack|packsize|rep|reverse|split|sub|unpack|upper)|table\\\\.(?:concat|create|find|foreachi??|getn|insert|maxn|move|pack|remove|sort|unpack|clear|freeze|isfrozen|clone)|task\\\\.(?:spawn|synchronize|desynchronize|wait|defer|delay)|utf8\\\\.(?:char|codepoint|codes|graphemes|len|nfcnormalize|nfdnormalize|offset)|buffer\\\\.(?:create|fromstring|tostring|len|readi8|readu8|readi16|readu16|readi32|readu32|readf32|readf64|writei8|writeu8|writei16|writeu16|writei32|writeu32|writef32|writef64|readstring|writestring|copy|fill))\\\\b","name":"support.function.luau"},{"match":"(?<![^.]\\\\.|:)\\\\b(bit32|buffer|coroutine|debug|math(\\\\.(huge|pi))?|os|string|table|task|utf8(\\\\.charpattern)?)\\\\b","name":"support.constant.luau"},{"match":"(?<![^.]\\\\.|:)\\\\b(delay|DebuggerManager|elapsedTime|PluginManager|printidentity|settings|spawn|stats|tick|time|UserSettings|version|wait|warn)\\\\b","name":"support.function.luau"},{"match":"(?<![^.]\\\\.|:)\\\\b(game|plugin|shared|script|workspace|Enum(?:\\\\.\\\\w+){0,2})\\\\b","name":"constant.language.luau"}]},"string":{"patterns":[{"begin":"\\"","end":"\\"","name":"string.quoted.double.luau","patterns":[{"include":"#string_escape"}]},{"begin":"\'","end":"\'","name":"string.quoted.single.luau","patterns":[{"include":"#string_escape"}]},{"begin":"\\\\[(=*)\\\\[","end":"]\\\\1]","name":"string.other.multiline.luau"},{"begin":"`","end":"`","name":"string.interpolated.luau","patterns":[{"include":"#interpolated_string_expression"},{"include":"#string_escape"}]}]},"string_escape":{"patterns":[{"match":"\\\\\\\\[\\"\'\\\\\\\\`abfnrtvz{]","name":"constant.character.escape.luau"},{"match":"\\\\\\\\\\\\d{1,3}","name":"constant.character.escape.luau"},{"match":"\\\\\\\\x\\\\h{2}","name":"constant.character.escape.luau"},{"match":"\\\\\\\\u\\\\{\\\\h*}","name":"constant.character.escape.luau"},{"match":"\\\\\\\\$","name":"constant.character.escape.luau"}]},"table":{"begin":"(\\\\{)","beginCaptures":{"1":{"name":"punctuation.table.begin.luau"}},"end":"(})","endCaptures":{"1":{"name":"punctuation.table.end.luau"}},"patterns":[{"match":"[,;]","name":"punctuation.separator.fields.luau"},{"include":"source.luau"}]},"type-alias-declaration":{"begin":"^\\\\b(?:(export)\\\\s+)?(type)\\\\b","beginCaptures":{"1":{"name":"storage.modifier.visibility.luau"},"2":{"name":"storage.type.luau"}},"end":"(?=\\\\s*$)|(?=\\\\s*;)","patterns":[{"include":"#type_literal"},{"match":"=","name":"keyword.operator.assignment.luau"}]},"type-function":{"begin":"^\\\\b(?:(export)\\\\s+)?(type)\\\\s+(function)\\\\b","beginCaptures":{"1":{"name":"storage.modifier.visibility.luau"},"2":{"name":"storage.type.luau"},"3":{"name":"keyword.control.luau"}},"end":"(?<=[-\\\\]\\"\')\\\\[{}])","name":"meta.function.luau","patterns":[{"include":"#comment"},{"include":"#generics-declaration"},{"begin":"(\\\\()","beginCaptures":{"1":{"name":"punctuation.definition.parameters.begin.luau"}},"end":"(\\\\))","endCaptures":{"1":{"name":"punctuation.definition.parameters.end.luau"}},"name":"meta.parameter.luau","patterns":[{"include":"#comment"},{"match":"\\\\.\\\\.\\\\.","name":"variable.parameter.function.varargs.luau"},{"match":"[A-Z_a-z][0-9A-Z_a-z]*","name":"variable.parameter.function.luau"},{"match":",","name":"punctuation.separator.arguments.luau"},{"begin":":","beginCaptures":{"0":{"name":"keyword.operator.type.luau"}},"end":"(?=[),])","patterns":[{"include":"#type_literal"}]}]},{"match":"\\\\b([A-Z_a-z][0-9A-Z_a-z]*)\\\\b","name":"entity.name.type.luau"}]},"type_annotation":{"begin":":(?!\\\\b([A-Z_a-z][0-9A-Z_a-z]*)\\\\b(?=\\\\s*(?:[\\"\'({]|\\\\[\\\\[)))","end":"(?<=\\\\))(?!\\\\s*->)|[;=]|$|(?=\\\\breturn\\\\b)|(?=\\\\bend\\\\b)","patterns":[{"include":"#comment"},{"include":"#type_literal"}]},"type_cast":{"begin":"(::)","beginCaptures":{"1":{"name":"keyword.operator.typecast.luau"}},"end":"(?=^|[-\\\\])+,:;>?}](?!\\\\s*[\\\\&|])|$|\\\\b(break|do|else|for|if|elseif|return|then|repeat|while|until|end|in|continue)\\\\b)","patterns":[{"include":"#type_literal"}]},"type_literal":{"patterns":[{"include":"#comment"},{"include":"#string"},{"match":"[\\\\&?|]","name":"keyword.operator.type.luau"},{"match":"->","name":"keyword.operator.type.function.luau"},{"match":"\\\\b(false)\\\\b","name":"constant.language.boolean.false.luau"},{"match":"\\\\b(true)\\\\b","name":"constant.language.boolean.true.luau"},{"match":"\\\\b(nil|string|number|boolean|thread|userdata|symbol|vector|buffer|unknown|never|any)\\\\b","name":"support.type.primitive.luau"},{"begin":"\\\\b(typeof)\\\\b(\\\\()","beginCaptures":{"1":{"name":"support.function.luau"},"2":{"name":"punctuation.arguments.begin.typeof.luau"}},"end":"(\\\\))","endCaptures":{"1":{"name":"punctuation.arguments.end.typeof.luau"}},"patterns":[{"include":"source.luau"}]},{"begin":"(<)","beginCaptures":{"1":{"name":"punctuation.definition.typeparameters.begin.luau"}},"end":"(>)","endCaptures":{"1":{"name":"punctuation.definition.typeparameters.end.luau"}},"patterns":[{"match":"=","name":"keyword.operator.assignment.luau"},{"include":"#type_literal"}]},{"match":"\\\\b([A-Z_a-z][0-9A-Z_a-z]*)\\\\b","name":"entity.name.type.luau"},{"begin":"\\\\{","end":"}","patterns":[{"begin":"\\\\[","end":"]","patterns":[{"include":"#type_literal"}]},{"captures":{"1":{"name":"storage.modifier.access.luau"},"2":{"name":"variable.property.luau"},"3":{"name":"keyword.operator.type.luau"}},"match":"\\\\b(?:(read|write)\\\\s+)?([A-Z_a-z][0-9A-Z_a-z]*)\\\\b(:)"},{"include":"#type_literal"},{"match":"[,;]","name":"punctuation.separator.fields.type.luau"}]},{"begin":"\\\\(","end":"\\\\)","patterns":[{"captures":{"1":{"name":"variable.parameter.luau"},"2":{"name":"keyword.operator.type.luau"}},"match":"\\\\b([A-Z_a-z][0-9A-Z_a-z]*)\\\\b(:)","name":"variable.parameter.luau"},{"include":"#type_literal"}]}]}},"scopeName":"source.luau"}'));var a=[e];export{a as default};
|