yanki
Version:
A CLI tool and TypeScript library to turn Markdown into Anki flashcards.
2 lines • 9.98 kB
JavaScript
import e from"node:path";import t from"node:process";import{fileURLToPath as n}from"node:url";import r,{execFile as i}from"node:child_process";import a,{constants as o}from"node:fs/promises";import{promisify as s}from"node:util";import c from"node:os";import l from"node:fs";import{Buffer as u}from"node:buffer";let d;function f(){try{return l.statSync(`/.dockerenv`),!0}catch{return!1}}function p(){try{return l.readFileSync(`/proc/self/cgroup`,`utf8`).includes(`docker`)}catch{return!1}}function m(){return d===void 0&&(d=f()||p()),d}let h;const g=()=>{try{return l.statSync(`/run/.containerenv`),!0}catch{return!1}};function _(){return h===void 0&&(h=g()||m()),h}const v=()=>{if(t.platform!==`linux`)return!1;if(c.release().toLowerCase().includes(`microsoft`))return!_();try{if(l.readFileSync(`/proc/version`,`utf8`).toLowerCase().includes(`microsoft`))return!_()}catch{}return l.existsSync(`/proc/sys/fs/binfmt_misc/WSLInterop`)||l.existsSync(`/run/WSL`)?!_():!1};var y=t.env.__IS_WSL_TEST__?v:v();const b=s(r.execFile),x=()=>`${t.env.SYSTEMROOT||t.env.windir||String.raw`C:\Windows`}\\System32\\WindowsPowerShell\\v1.0\\powershell.exe`,S=async(e,t={})=>{let{powerShellPath:n,...r}=t,i=S.encodeCommand(e);return b(n??x(),[...S.argumentsPrefix,i],{encoding:`utf8`,...r})};S.argumentsPrefix=[`-NoProfile`,`-NonInteractive`,`-ExecutionPolicy`,`Bypass`,`-EncodedCommand`],S.encodeCommand=e=>u.from(e,`utf16le`).toString(`base64`),S.escapeArgument=e=>`'${String(e).replaceAll(`'`,`''`)}'`;function ee(e){for(let t of e.split(`
`)){if(/^\s*#/.test(t))continue;let e=/^\s*root\s*=\s*(?<mountPoint>"[^"]*"|'[^']*'|[^#]*)/.exec(t);if(e)return e.groups.mountPoint.trim().replaceAll(/^["']|["']$/g,``)}}const C=s(r.execFile),w=(()=>{let e=`/mnt/`,t;return async function(){if(t)return t;let n=`/etc/wsl.conf`,r=!1;try{await a.access(n,o.F_OK),r=!0}catch{}if(!r)return e;let i=ee(await a.readFile(n,{encoding:`utf8`}));return i===void 0?e:(t=i,t=t.endsWith(`/`)?t:`${t}/`,t)}})(),T=y?async()=>`${await w()}c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe`:x;let E;const D=async()=>(E??=(async()=>{try{let e=await T();return await a.access(e,o.X_OK),!0}catch{return!1}})(),E),O=async()=>{let e=await T(),{stdout:t}=await S(String.raw`(Get-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\http\UserChoice").ProgId`,{powerShellPath:e});return t.trim()},k=async e=>{if(/^[a-z]+:\/\//i.test(e))return e;try{let{stdout:t}=await C(`wslpath`,[`-aw`,e],{encoding:`utf8`});return t.trim()}catch{return e}};function A(e,t,n){let r=n=>Object.defineProperty(e,t,{value:n,enumerable:!0,writable:!0});return Object.defineProperty(e,t,{configurable:!0,enumerable:!0,get(){let e=n();return r(e),e},set(e){r(e)}}),e}const te=s(i);async function ne(){if(t.platform!==`darwin`)throw Error(`macOS only`);let{stdout:e}=await te(`defaults`,[`read`,`com.apple.LaunchServices/com.apple.launchservices.secure`,`LSHandlers`]),n=/LSHandlerRoleAll = "(?!-)(?<id>[^"]+?)";\s+?LSHandlerURLScheme = (?:http|https);/.exec(e)?.groups.id??`com.apple.Safari`;return n===`com.apple.safari`?`com.apple.Safari`:n}const j=s(i);async function M(e,{humanReadableOutput:n=!0,signal:r}={}){if(t.platform!==`darwin`)throw Error(`macOS only`);let i=n?[]:[`-ss`],a={};r&&(a.signal=r);let{stdout:o}=await j(`osascript`,[`-e`,e,i],a);return o.trim()}async function N(e){return M(`tell application "Finder" to set app_path to application file id "${e}" as string\ntell application "System Events" to get value of property list item "CFBundleName" of property list file (app_path & ":Contents:Info.plist")`)}const P=s(i),F={MSEdgeHTM:{name:`Edge`,id:`com.microsoft.edge`},MSEdgeBHTML:{name:`Edge Beta`,id:`com.microsoft.edge.beta`},MSEdgeDHTML:{name:`Edge Dev`,id:`com.microsoft.edge.dev`},AppXq0fevzme2pys62n3e0fbqa7peapykr8v:{name:`Edge`,id:`com.microsoft.edge.old`},ChromeHTML:{name:`Chrome`,id:`com.google.chrome`},ChromeBHTML:{name:`Chrome Beta`,id:`com.google.chrome.beta`},ChromeDHTML:{name:`Chrome Dev`,id:`com.google.chrome.dev`},ChromiumHTM:{name:`Chromium`,id:`org.chromium.Chromium`},BraveHTML:{name:`Brave`,id:`com.brave.Browser`},BraveBHTML:{name:`Brave Beta`,id:`com.brave.Browser.beta`},BraveDHTML:{name:`Brave Dev`,id:`com.brave.Browser.dev`},BraveSSHTM:{name:`Brave Nightly`,id:`com.brave.Browser.nightly`},FirefoxURL:{name:`Firefox`,id:`org.mozilla.firefox`},OperaStable:{name:`Opera`,id:`com.operasoftware.Opera`},VivaldiHTM:{name:`Vivaldi`,id:`com.vivaldi.Vivaldi`},"IE.HTTP":{name:`Internet Explorer`,id:`com.microsoft.ie`}},I=new Map(Object.entries(F));var L=class extends Error{};async function R(e=P){let{stdout:t}=await e(`reg`,[`QUERY`,` HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\Shell\\Associations\\UrlAssociations\\http\\UserChoice`,`/v`,`ProgId`]),n=/ProgId\s*REG_SZ\s*(?<id>\S+)/.exec(t);if(!n)throw new L(`Cannot find Windows browser in stdout: ${JSON.stringify(t)}`);let{id:r}=n.groups,i=r.lastIndexOf(`.`),a=r.lastIndexOf(`-`),o=i===-1?void 0:r.slice(0,i),s=a===-1?void 0:r.slice(0,a);return F[r]??F[o]??F[s]??{name:r,id:r}}const z=s(i),B=e=>e.toLowerCase().replaceAll(/(?:^|\s|-)\S/g,e=>e.toUpperCase());async function V(){if(t.platform===`darwin`){let e=await ne();return{name:await N(e),id:e}}if(t.platform===`linux`){let{stdout:e}=await z(`xdg-mime`,[`query`,`default`,`x-scheme-handler/http`]),t=e.trim();return{name:B(t.replace(/.desktop$/,``).replace(`-`,` `)),id:t}}if(t.platform===`win32`)return R();throw Error(`Only macOS, Linux, and Windows are supported`)}const H=!!(t.env.SSH_CONNECTION||t.env.SSH_CLIENT||t.env.SSH_TTY),U=Symbol(`fallbackAttempt`),W=import.meta.url?e.dirname(n(import.meta.url)):``,G=e.join(W,`xdg-open`),{platform:K,arch:q}=t,J=async(e,t)=>{if(e.length===0)return;let n=[];for(let r of e)try{return await t(r)}catch(e){n.push(e)}throw AggregateError(n,`Failed to open in all supported apps`)},Y=async e=>{e={wait:!1,background:!1,newInstance:!1,allowNonzeroExitCode:!1,...e};let n=e[U]===!0;if(delete e[U],Array.isArray(e.app))return J(e.app,t=>Y({...e,app:t,[U]:!0}));let{name:i,arguments:s=[]}=e.app??{};if(s=[...s],Array.isArray(i))return J(i,t=>Y({...e,app:{name:t,arguments:s},[U]:!0}));if(i===`browser`||i===`browserPrivate`){let t={"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`,"com.apple.safari":`safari`},n={chrome:`--incognito`,brave:`--incognito`,firefox:`--private-window`,edge:`--inPrivate`},r;if(y){let e=await O();r=I.get(e)??{}}else r=await V();if(r.id in t){let a=t[r.id.toLowerCase()];if(i===`browserPrivate`){if(a===`safari`)throw Error(`Safari doesn't support opening in private mode via command line`);s.push(n[a])}return Y({...e,app:{name:$[a],arguments:s}})}throw Error(`${r.name} is not supported as a default browser`)}let c,l=[],u={},d=!1;if(y&&!_()&&!H&&!i&&(d=await D()),K===`darwin`)c=`open`,e.wait&&l.push(`--wait-apps`),e.background&&l.push(`--background`),e.newInstance&&l.push(`--new`),i&&l.push(`-a`,i);else if(K===`win32`||d){c=await T(),l.push(...S.argumentsPrefix),y||(u.windowsVerbatimArguments=!0),y&&e.target&&(e.target=await k(e.target));let t=[`$ProgressPreference = 'SilentlyContinue';`,`Start`];e.wait&&t.push(`-Wait`),i?(t.push(S.escapeArgument(i)),e.target&&s.push(e.target)):e.target&&t.push(S.escapeArgument(e.target)),s.length>0&&(s=s.map(e=>S.escapeArgument(e)),t.push(`-ArgumentList`,s.join(`,`))),e.target=S.encodeCommand(t.join(` `)),e.wait||(u.stdio=`ignore`)}else{if(i)c=i;else{let e=!W||W===`/`,n=!1;try{await a.access(G,o.X_OK),n=!0}catch{}c=t.versions.electron??(K===`android`||e||!n)?`xdg-open`:G}s.length>0&&l.push(...s),e.wait||(u.stdio=`ignore`,u.detached=!0)}K===`darwin`&&s.length>0&&l.push(`--args`,...s),e.target&&l.push(e.target);let f=r.spawn(c,l,u);return e.wait?new Promise((t,n)=>{f.once(`error`,n),f.once(`close`,r=>{if(!e.allowNonzeroExitCode&&r!==0){n(Error(`Exited with code ${r}`));return}t(f)})}):n?new Promise((e,t)=>{f.once(`error`,t),f.once(`spawn`,()=>{f.once(`close`,n=>{if(f.off(`error`,t),n!==0){t(Error(`Exited with code ${n}`));return}f.unref(),e(f)})})}):(f.unref(),new Promise((e,t)=>{f.once(`error`,t),f.once(`spawn`,()=>{f.off(`error`,t),e(f)})}))},X=(e,t)=>{if(typeof e!=`string`&&!Array.isArray(e))throw TypeError("Expected a valid `name`");let{arguments:n=[]}=t??{};if(n!=null&&!Array.isArray(n))throw TypeError("Expected `appArguments` as Array type");return Y({...t,app:{name:e,arguments:n}})};function Z(e){if(typeof e==`string`||Array.isArray(e))return e;let{[q]:t}=e;if(!t)throw Error(`${q} is not supported`);return t}function Q({[K]:e},{wsl:t}={}){if(t&&y)return Z(t);if(!e)throw Error(`${K} is not supported`);return Z(e)}const $={browser:`browser`,browserPrivate:`browserPrivate`};A($,`chrome`,()=>Q({darwin:`google chrome`,win32:`chrome`,linux:[`google-chrome`,`google-chrome-stable`,`chromium`,`chromium-browser`]},{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`]}})),A($,`brave`,()=>Q({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`]}})),A($,`firefox`,()=>Q({darwin:`firefox`,win32:String.raw`C:\Program Files\Mozilla Firefox\firefox.exe`,linux:`firefox`},{wsl:`/mnt/c/Program Files/Mozilla Firefox/firefox.exe`})),A($,`edge`,()=>Q({darwin:`microsoft edge`,win32:`msedge`,linux:[`microsoft-edge`,`microsoft-edge-dev`]},{wsl:`/mnt/c/Program Files (x86)/Microsoft/Edge/Application/msedge.exe`})),A($,`safari`,()=>Q({darwin:`Safari`}));export{X as openApp};