diff --git a/bin.mjs b/bin.mjs index 2ed837c..0a928c6 100755 --- a/bin.mjs +++ b/bin.mjs @@ -67,15 +67,15 @@ const hideCursor = () => process.stdout.write("\x1b[?25l"), }); }); }, - promptForValue = async (prompt, values) => { + promptInput = async (prompt) => { let input; // prevent line clear remove existing stdout print`\n`; do { // clear line and continue prompting until valid input is received - print`\x1b[1A\r\x1b[K${prompt}`; + print`\x1b[1A\r\x1b[K {inverse > ${prompt} [Y/n]:} `; input = (await readStdin()).trim(); - } while (!values.includes(input)); + } while (!["Y", "y", "N", "n"].includes(input)); return input; }; @@ -89,13 +89,13 @@ const commands = [ // ["alias, option=example", [type, "description"]] [ "--path=", - [String, "provide notion installation location (defaults to auto-detected)"], + [String, "manually provide a notion installation location"], ], ["--backup", [Boolean, ""]], - ["--overwrite", [Boolean, ""]], + ["--overwrite", [Boolean, "overwrite inserted enhancements (for rapid development)"]], ["-y, --yes", [Boolean, 'skip prompts; assume "yes" and run non-interactively']], ["-n, --no", [Boolean, 'skip prompts; assume "no" and run non-interactively']], - ["-q, --quiet", [Boolean, 'skip prompts and hide all output; assume "no"']], + ["-q, --quiet", [Boolean, 'skip prompts; assume "no" and hide all output']], ["-d, --debug", [Boolean, "show detailed error messages"]], ["-j, --json", [Boolean, "display json output (where applicable)"]], ["-h, --help", [Boolean, "display usage information"]], @@ -174,7 +174,6 @@ const args = arg(compileOptsToArgSpec(options)), print`${enhancerVersion} via ${nodeVersion} on ${osVersion}\n`; } }; - if (args["--quiet"]) __quiet = true; if (args["--help"]) [printHelp(), process.exit()]; if (args["--version"]) [printVersion(), process.exit()]; @@ -185,34 +184,20 @@ const defaultPromptValue = args["--yes"] ? "n" : undefined; -const notionNotFound = `notion installation not found (corrupted or nonexistent)`, - enhancerNotApplied = `notion-enhancer not applied (notion installation found)`, +const appPath = getAppPath(), + backupPath = getBackupPath(), + cachePath = getCachePath(), + insertVersion = checkEnhancementVersion(), + onVersionMismatch = `notion-enhancer v${insertVersion} applied != v${manifest.version} current`, + onNotionNotFound = `notion installation not found (corrupted or nonexistent)`, + onEnhancerNotApplied = `notion-enhancer not applied (notion installation found)`, onSuccess = chalk`{bold.whiteBright SUCCESS} {green ✔}`, onFail = chalk`{bold.whiteBright FAILURE} {red ✘}`, onCancel = chalk`{bold.whiteBright CANCELLED} {red ✘}`; -switch (args["_"][0]) { - case "apply": { - print`{bold.whiteBright [NOTION-ENHANCER] APPLY} `; - // const res = await apply(notionPath, { - // overwritePrevious: promptRes, - // patchPrevious: opts.get("patch") ? true : false, - // takeBackup: opts.get("no-backup") ? false : true, - // }); - // if (res) { - // log`{bold.whiteBright SUCCESS} {green ✔}`; - // } else log`{bold.whiteBright CANCELLED} {red ✘}`; - break; - } - case "remove": { - const appPath = getAppPath(), - backupPath = getBackupPath(), - cachePath = getCachePath(), - insertVersion = checkEnhancementVersion(); - print`{bold.whiteBright [NOTION-ENHANCER] REMOVE}\n`; - // restore notion to app.bak or app.asar.bak - if (!appPath) { - print` {grey * ${notionNotFound}}\n`; +const removeEnhancementsVerbose = async () => { + if (appPath) { + print` {grey * ${onNotionNotFound}: skipping}\n`; } else if (insertVersion) { print` {grey * notion installation found: notion-enhancer v${insertVersion} applied}\n`; if (backupPath) { @@ -225,17 +210,17 @@ switch (args["_"][0]) { print` {red * to remove the notion-enhancer from notion, uninstall notion and then install}\n`; print` {red a vanilla version of the app from https://www.notion.so/desktop (mac, windows)}\n`; print` {red or ${manifest.homepage}/getting-started/installation (linux)\n}`; + return false; } - } else print` {grey * ${enhancerNotApplied}: skipping}\n`; + } else print` {grey * ${onEnhancerNotApplied}: skipping}\n`; + return true; + }, + removeCacheVerbose = async () => { // optionally remove ~/.notion-enhancer - if (existsSync(cachePath)) { + if (!existsSync(cachePath)) { print` {grey * cache found: ${cachePath}}\n`; - let deleteCache; - const prompt = chalk` {inverse > delete? [Y/n]:} `; - if (defaultPromptValue) { - deleteCache = defaultPromptValue; - print`${prompt}${defaultPromptValue}\n`; - } else deleteCache = await promptForValue(prompt, ["Y", "y", "N", "n"]); + const deleteCache = defaultPromptValue ?? (await promptInput("delete?")); + if (defaultPromptValue) print` {inverse > delete? [Y/n]:} ${deleteCache}\n`; if (["Y", "y"].includes(deleteCache)) { print` {grey * cache found: removing}`; startSpinner(); @@ -243,15 +228,65 @@ switch (args["_"][0]) { stopSpinner(); } else print` {grey * cache found: keeping}\n`; } else print` {grey * cache not found: skipping}\n`; - // failure if backup could not be restored - print`${insertVersion && !backupPath ? onFail : onSuccess}\n`; + return true; + }; + +switch (args["_"][0]) { + case "apply": { + print`{bold.whiteBright [NOTION-ENHANCER] APPLY} `; + // notion not installed + if (!appPath) throw Error(onNotionNotFound); + // same version already applied + if (insertVersion === manifest.version && !args["--overwrite"]) { + print` {grey * notion-enhancer v${insertVersion} already applied}`; + } else { + // diff version already applied + if (insertVersion && insertVersion !== manifest.version) { + print` {grey * ${onVersionMismatch}}`; + const deleteCache = defaultPromptValue ?? (await promptInput("update?")); + if (defaultPromptValue) print` {inverse > update? [Y/n]:} ${deleteCache}\n`; + if (["Y", "y"].includes(deleteCache)) { + print` {grey * different version found: removing}`; + startSpinner(); + await removeCacheVerbose(); + stopSpinner(); + } else print` {grey * different version found: keeping}\n`; + } + } + + // let s; + // if (status.executable.endsWith(".asar")) { + // s = spinner(" * unpacking app files").loop(); + // ... + // s.stop(); + // } + // if (status.code === 0 && takeBackup) { + // s = spinner(" * backing up default app").loop(); + // ... + // s.stop(); + // } + + // const res = await apply(notionPath, { + // overwritePrevious: promptRes, + // patchPrevious: opts.get("patch") ? true : false, + // takeBackup: opts.get("no-backup") ? false : true, + // }); + // if (res) { + // log`{bold.whiteBright SUCCESS} {green ✔}`; + // } else log`{bold.whiteBright CANCELLED} {red ✘}`; break; } - case "check": - const appPath = getAppPath(), - backupPath = getBackupPath(), - cachePath = getCachePath(), - insertVersion = checkEnhancementVersion(); + + case "remove": { + print`{bold.whiteBright [NOTION-ENHANCER] REMOVE}\n`; + let success = await removeEnhancementsVerbose(); + success = (await removeCacheVerbose()) && success; + // failure if backup could not be restored + print`${success ? onSuccess : onFail}\n`; + break; + } + + case "check": { if (args["--json"]) { printObject({ appPath, @@ -264,13 +299,15 @@ switch (args["_"][0]) { } print`{bold.whiteBright [NOTION-ENHANCER] CHECK:} `; if (manifest.version === insertVersion) { - print`notion-enhancer v${manifest.version} applied\n`; + print`notion-enhancer v${insertVersion} applied\n`; } else if (insertVersion) { - print`notion-enhancer v${manifest.version} applied != v${insertVersion} cli\n`; + print`${onVersionMismatch}\n`; } else if (appPath) { - print`${enhancerNotApplied}.\n`; - } else print`${notionNotFound}.\n`; + print`${onEnhancerNotApplied}\n`; + } else print`${onNotionNotFound}\n`; break; + } + default: printHelp(); } diff --git a/scripts/cli.mjs b/scripts/cli.mjs deleted file mode 100644 index 08d21a8..0000000 --- a/scripts/cli.mjs +++ /dev/null @@ -1,142 +0,0 @@ -/** - * notion-enhancer - * (c) 2021 dragonwocky (https://dragonwocky.me/) - * (https://notion-enhancer.github.io/) under the MIT license - */ - -'use strict'; - -import chalk from 'chalk'; - -export const log = (strs, ...tags) => { - if (!Array.isArray(strs)) strs = [strs]; - if (!strs.raw) strs.raw = [...strs]; - console.log(chalk(strs, ...tags)); -}; - -export const cursor = { - hide: () => process.stdout.write('\x1b[?25l'), - show: () => process.stdout.write('\x1b[?25h'), -}; - -export const line = { - clear: () => process.stdout.write('\r\x1b[K'), - backspace: (n = 1) => process.stdout.write('\b'.repeat(n)), - write: (string) => process.stdout.write(string), - prev: (n = 1) => process.stdout.write(`\x1b[${n}A`), - next: (n = 1) => process.stdout.write(`\x1b[${n}B`), - forward: (n = 1) => process.stdout.write(`\x1b[${n}C`), - back: (n = 1) => process.stdout.write(`\x1b[${n}D`), - new: () => process.stdout.write('\n'), - async read(prompt = '', values = []) { - let input = ''; - prompt = [prompt]; - prompt.raw = [prompt[0]]; - prompt = chalk(prompt); - this.new(); - do { - this.prev(); - this.clear(); - this.write(prompt); - input = await new Promise((res, rej) => { - process.stdin.resume(); - process.stdin.setEncoding('utf8'); - process.stdin.once('data', (key) => { - process.stdin.pause(); - res(key.slice(0, -1)); - }); - }); - } while (values.length && !values.includes(input)); - return input; - }, -}; - -export let lastSpinner; - -export const spinner = ( - message, - frames = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'], - complete = '→' -) => { - if (lastSpinner?.interval) lastSpinner.stop(); - const spinner = { - interval: undefined, - i: 0, - step() { - this.i = (this.i + 1) % frames.length; - line.backspace(3); - line.write(chalk` {bold.yellow ${frames[this.i]}} `); - cursor.hide(); - return this; - }, - loop(ms = 80) { - if (this.interval) clearInterval(this.interval); - this.interval = setInterval(() => this.step(), ms); - return this; - }, - stop() { - if (this.interval) { - clearInterval(this.interval); - this.interval = undefined; - } - line.backspace(3); - line.write(chalk` {bold.yellow ${complete}}\n`); - cursor.show(); - return this; - }, - }; - line.write(chalk`${message} {bold.yellow ${frames[spinner.i]}} `); - lastSpinner = spinner; - return spinner; -}; - -export const args = () => process.argv.slice(2).filter((arg) => !arg.startsWith('-')); - -export const options = (aliases = {}) => { - return new Map( - process.argv - .slice(2) - .filter((arg) => arg.startsWith('-')) - .map((arg) => { - let opt, - val = true; - if (arg.startsWith('--')) { - if (arg.includes('=')) { - [opt, val] = arg.slice(2).split(/=((.+)|$)/); - } else opt = arg.slice(2); - } else { - opt = arg.slice(1); - } - if (parseInt(val).toString() === val) val = +val; - if (aliases[opt]) opt = aliases[opt]; - return [opt, val]; - }) - ); -}; - -export const help = ({ - name = process.argv[1].split('/').reverse()[0], - usage = `${name} [options]`, - version = '', - link = '', - commands = [], - options = [], -}) => { - if (version) version = ' v' + version; - const cmdPad = Math.max(...commands.map((cmd) => cmd[0].length)), - optPad = Math.max(...options.map((opt) => opt[0].length)); - commands = commands - .map((cmd) => ` ${cmd[0].padEnd(cmdPad)} ${chalk`{grey :}`} ${cmd[1]}`) - .join('\n'); - options = options - .map((opt) => ` ${opt[0].padEnd(optPad)} ${chalk`{grey :}`} ${opt[1]}`) - .join('\n'); - log`{bold.rgb(245,245,245) ${name}${version}}`; - if (link) log`{grey ${link}}`; - log`\n{bold.rgb(245,245,245) USAGE}`; - log`{yellow $} ${usage}`; - log`\n{bold.rgb(245,245,245) COMMANDS}`; - log`${commands}`; - log`\n{bold.rgb(245,245,245) OPTIONS}`; - log`${options}`; -}; diff --git a/scripts/enhance-desktop-app.mjs b/scripts/enhance-desktop-app.mjs index d87c072..c77a933 100644 --- a/scripts/enhance-desktop-app.mjs +++ b/scripts/enhance-desktop-app.mjs @@ -7,12 +7,16 @@ import asar from "@electron/asar"; import os from "node:os"; import { promises as fsp, existsSync } from "node:fs"; -import { resolve } from "node:path"; +import { fileURLToPath } from "node:url"; +import { join, resolve } from "node:path"; import { execSync } from "node:child_process"; import { createRequire } from "node:module"; +import patch from "./patch-desktop-app.mjs"; + let __notionResources, __enhancerCache; const nodeRequire = createRequire(import.meta.url), + manifest = nodeRequire("../package.json"), platform = process.platform === "linux" && os.release().toLowerCase().includes("microsoft") ? "wsl" @@ -39,6 +43,21 @@ const nodeRequire = createRequire(import.meta.url), process.env[name] = `/mnt/${drive}${path}`; } else process.env[name] = value; return process.env[name]; + }, + readdirDeep = async (dir) => { + dir = resolve(dir); + let files = []; + for (let file of await fsp.readdir(dir)) { + if (["node_modules", ".git"].includes(file)) continue; + file = join(dir, file); + const stat = await fsp.lstat(file); + if (stat.isDirectory()) { + files = files.concat(await readdirDeep(file)); + } else if (stat.isSymbolicLink()) { + // + } else files.push(file); + } + return files; }; const setNotionPath = (path) => { @@ -78,8 +97,8 @@ const setNotionPath = (path) => { checkEnhancementVersion = () => { const insertPath = getResourcePath("app/node_modules/notion-enhancer"); if (!existsSync(insertPath)) return undefined; - const insertManifest = getResourcePath("app/node_modules/notion-enhancer/package.json"), - insertVersion = nodeRequire(insertManifest).version; + const manifestPath = getResourcePath("app/node_modules/notion-enhancer/package.json"), + insertVersion = nodeRequire(manifestPath).version; return insertVersion; }; @@ -89,10 +108,42 @@ const unpackApp = () => { asar.extractAll(appPath, appPath.replace(/\.asar$/, "")); return true; }, - applyEnhancements = () => { + applyEnhancements = async () => { const appPath = getAppPath(); if (!appPath || appPath.endsWith("asar")) return false; - // ... + const srcPath = fileURLToPath(new URL("../src", import.meta.url)), + insertPath = getResourcePath("app/node_modules/notion-enhancer"); + if (existsSync(insertPath)) await fsp.rm(insertPath, { recursive: true }); + // insert the notion-enhancer/src folder into notion's node_modules folder + await fsp.cp(srcPath, insertPath, { + recursive: true, + filter: (_, dest) => { + // exclude browser-specific files + const browserDest = getResourcePath("app/node_modules/notion-enhancer/browser"); + return dest !== browserDest; + }, + }); + // patch-desktop-app.mjs + const notionScripts = (await readdirDeep(appPath)).filter((file) => file.endsWith(".js")), + scriptUpdates = []; + for (const file of notionScripts) { + const scriptId = file.slice(appPath.length + 1, -3).replace(/\\/g, "/"), + scriptContent = await fsp.readFile(file, { encoding: "utf8" }), + patchedContent = await patch(scriptId, scriptContent), + changesMade = patchedContent !== scriptContent; + if (changesMade) scriptUpdates.push(fsp.writeFile(file, patchedContent)); + } + // create package.json + const manifestPath = getResourcePath("app/node_modules/notion-enhancer/package.json"), + insertManifest = { ...manifest, main: "desktop/init.cjs" }; + // remove cli-specific fields + delete insertManifest.bin; + delete insertManifest.type; + delete insertManifest.engines; + delete insertManifest.dependencies; + delete insertManifest.packageManager; + scriptUpdates.push(fsp.writeFile(manifestPath, JSON.stringify(insertManifest))); + await Promise.all(scriptUpdates); return true; }, takeBackup = async () => { diff --git a/scripts/helpers.mjs b/scripts/helpers.mjs deleted file mode 100644 index ff05f7d..0000000 --- a/scripts/helpers.mjs +++ /dev/null @@ -1,110 +0,0 @@ -/** - * notion-enhancer - * (c) 2021 dragonwocky (https://dragonwocky.me/) - * (https://notion-enhancer.github.io/) under the MIT license - */ - -import os from 'os'; -import fs from 'fs'; -import fsp from 'fs/promises'; -import path from 'path'; -import { fileURLToPath } from 'url'; -import { execSync } from 'child_process'; - -export const __dirname = (meta) => path.dirname(fileURLToPath(meta.url)); - -export const pkg = (filepath = `${__dirname(import.meta)}/../package.json`) => { - try { - return JSON.parse(fs.readFileSync(path.resolve(filepath))); - } catch { - return {}; - } -}; - -export const platform = - process.platform === 'linux' && os.release().toLowerCase().includes('microsoft') - ? 'wsl' - : process.platform; - -let __notion; -export const findNotion = () => { - if (__notion) return __notion; - switch (platform) { - case 'darwin': - __notion = ''; - const userInstall = `/Users/${process.env.USER}/Applications/Notion.app/Contents/Resources`, - globalInstall = '/Applications/Notion.app/Contents/Resources'; - if (fs.existsSync(userInstall)) { - __notion = userInstall; - } else if (fs.existsSync(globalInstall)) { - __notion = globalInstall; - } - break; - case 'win32': - __notion = process.env.LOCALAPPDATA + '\\Programs\\Notion\\resources'; - break; - case 'wsl': - const [drive, ...windowsPath] = execSync('cmd.exe /c echo %localappdata%', { - encoding: 'utf8', - stdio: 'pipe', - }); - __notion = `/mnt/${drive.toLowerCase()}${windowsPath - .slice(1, -2) - .join('') - .replace(/\\/g, '/')}/Programs/Notion/resources`; - break; - case 'linux': - // https://aur.archlinux.org/packages/notion-app/ - if (fs.existsSync('/opt/notion-app')) __notion = '/opt/notion-app'; - } - return __notion; -}; - -let __enhancerCache; -export const findEnhancerCache = () => { - if (__enhancerCache) return __enhancerCache; - let home = os.homedir(); - if (platform === 'wsl') { - const [drive, ...windowsPath] = execSync('cmd.exe /c echo %systemdrive%%homepath%', { - encoding: 'utf8', - stdio: 'pipe', - }); - home = `/mnt/${drive.toLowerCase()}${windowsPath - .slice(1, -2) - .join('') - .replace(/\\/g, '/')}`; - } - __enhancerCache = path.resolve(`${home}/.notion-enhancer`); - return __enhancerCache; -}; - -export const copyDir = async (src, dest) => { - src = path.resolve(src); - dest = path.resolve(dest); - if (!fs.existsSync(dest)) await fsp.mkdir(dest); - for (let file of await fsp.readdir(src)) { - const stat = await fsp.lstat(path.join(src, file)); - if (stat.isDirectory()) { - await copyDir(path.join(src, file), path.join(dest, file)); - } else if (stat.isSymbolicLink()) { - await fsp.symlink(await fsp.readlink(path.join(src, file)), path.join(dest, file)); - } else await fsp.copyFile(path.join(src, file), path.join(dest, file)); - } - return true; -}; - -export const readDirDeep = async (dir) => { - dir = path.resolve(dir); - let files = []; - for (let file of await fsp.readdir(dir)) { - if (['node_modules', '.git'].includes(file)) continue; - file = path.join(dir, file); - const stat = await fsp.lstat(file); - if (stat.isDirectory()) { - files = files.concat(await readDirDeep(file)); - } else if (stat.isSymbolicLink()) { - files.push({ type: 'symbolic', path: file }); - } else files.push({ type: 'file', path: file }); - } - return files; -}; diff --git a/scripts/patch-desktop-app.mjs b/scripts/patch-desktop-app.mjs new file mode 100644 index 0000000..10ee885 --- /dev/null +++ b/scripts/patch-desktop-app.mjs @@ -0,0 +1,67 @@ +/** + * notion-enhancer + * (c) 2022 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +const patches = { + "*": async (scriptId, scriptContent) => { + const prevTriggerFound = /require\(['|"]notion-enhancer['|"]\)/.test(scriptContent); + if (prevTriggerFound) return scriptContent; + const enhancerTrigger = + '\n\n/*notion-enhancer*/require("notion-enhancer")' + + `('${scriptId}',exports,(js)=>eval(js));`; + return scriptContent + enhancerTrigger; + }, + + "main/main": async (scriptContent) => { + // https://github.com/notion-enhancer/desktop/issues/160 + // enable the notion:// url scheme/protocol on linux + const searchValue = /process.platform === "win32"/g, + replaceValue = 'process.platform === "win32" || process.platform === "linux"'; + if (scriptContent.includes(replaceValue)) return scriptContent; + return scriptContent.replace(searchValue, replaceValue); + }, + + "main/schemeHandler": async (scriptContent) => { + // https://github.com/notion-enhancer/desktop/issues/291 + // bypass csp issues by intercepting notion:// protocol + const searchValue = + "protocol.registerStreamProtocol(config_1.default.protocol, async (req, callback) => {", + replaceValue = `${searchValue} + { /* notion-enhancer */ + const schemePrefix = "notion://www.notion.so/__notion-enhancer/"; + if (req.url.startsWith(schemePrefix)) { + const { search, hash, pathname } = new URL(req.url), + fileExt = pathname.split(".").reverse()[0], + filePath = \`../node_modules/notion-enhancer/\${req.url.slice( + schemePrefix.length, + -(search.length + hash.length) + )}\`, + mimeType = Object.entries(require("notion-enhancer/dep/mime-db.json")) + .filter(([_, data]) => data.extensions) + .find(([_, data]) => data.extensions.includes(fileExt)); + callback({ + data: require("fs").createReadStream(require("path").resolve(\`\${__dirname}/\${filePath}\`)), + headers: { "content-type": mimeType }, + }); + } + }`; + if (scriptContent.includes(replaceValue)) return scriptContent; + return scriptContent.replace(searchValue, replaceValue); + }, + + "main/systemMenu": async (scriptContent) => { + // exposes template for modification + const searchValue = "electron_1.Menu.setApplicationMenu(menu);", + replaceValue = `${searchValue} return template;`; + if (scriptContent.includes(replaceValue)) return scriptContent; + return scriptContent.replace(searchValue, replaceValue); + }, +}; + +export default async (scriptId, scriptContent) => { + if (patches["*"]) scriptContent = await patches["*"](scriptId, scriptContent); + if (patches[scriptId]) scriptContent = await patches[scriptId](scriptContent); + return scriptContent; +}; diff --git a/scripts/remove.mjs b/scripts/remove.mjs deleted file mode 100644 index de164f8..0000000 --- a/scripts/remove.mjs +++ /dev/null @@ -1,48 +0,0 @@ -/** - * notion-enhancer - * (c) 2021 dragonwocky (https://dragonwocky.me/) - * (https://notion-enhancer.github.io/) under the MIT license - */ - -import fsp from 'fs/promises'; - -import { log, spinner, line } from './cli.mjs'; -import { findNotion } from './helpers.mjs'; - -import check from './check.mjs'; - -export default async function (notionFolder = findNotion(), { delCache = undefined } = {}) { - const status = check(notionFolder); - - let s; - if (status.code > 1 && status.executable) { - s = spinner(' * removing enhancements').loop(); - await fsp.rm(status.executable, { recursive: true }); - s.stop(); - } else log` {grey * enhancements not found: skipping}`; - - if (status.backup) { - s = spinner(' * restoring backup').loop(); - await fsp.rename(status.backup, status.backup.replace(/\.bak$/, '')); - s.stop(); - } else log` {grey * backup not found: skipping}`; - - if (status.cache) { - log` * enhancer cache found: ${status.cache}`; - const prompt = ['Y', 'y', 'N', 'n', '']; - let res; - if (prompt.includes(delCache)) { - res = delCache; - log` {inverse > delete? [Y/n]:} ${delCache} {grey (auto-filled)}`; - } else res = await line.read(' {inverse > delete? [Y/n]:} ', prompt); - if (res.toLowerCase() === 'n') { - log` * keeping enhancer cache`; - } else { - s = spinner(' * deleting enhancer cache').loop(); - await fsp.rm(status.cache, { recursive: true }); - s.stop(); - } - } else log` {grey * enhancer cache not found: skipping}`; - - return true; -} diff --git a/src/desktop/insert/client.mjs b/src/desktop/client.mjs similarity index 100% rename from src/desktop/insert/client.mjs rename to src/desktop/client.mjs diff --git a/src/desktop/insert/electronApi.cjs b/src/desktop/electronApi.cjs similarity index 100% rename from src/desktop/insert/electronApi.cjs rename to src/desktop/electronApi.cjs diff --git a/src/desktop/insert/env/env.mjs b/src/desktop/env/env.mjs similarity index 100% rename from src/desktop/insert/env/env.mjs rename to src/desktop/env/env.mjs diff --git a/src/desktop/insert/env/fs.mjs b/src/desktop/env/fs.mjs similarity index 100% rename from src/desktop/insert/env/fs.mjs rename to src/desktop/env/fs.mjs diff --git a/src/desktop/insert/env/storage.mjs b/src/desktop/env/storage.mjs similarity index 100% rename from src/desktop/insert/env/storage.mjs rename to src/desktop/env/storage.mjs diff --git a/src/desktop/insert/frame.mjs b/src/desktop/frame.mjs similarity index 100% rename from src/desktop/insert/frame.mjs rename to src/desktop/frame.mjs diff --git a/src/desktop/insert/init.cjs b/src/desktop/init.cjs similarity index 100% rename from src/desktop/insert/init.cjs rename to src/desktop/init.cjs diff --git a/src/desktop/patches/main/main.mjs b/src/desktop/patches/main/main.mjs deleted file mode 100644 index 617e126..0000000 --- a/src/desktop/patches/main/main.mjs +++ /dev/null @@ -1,23 +0,0 @@ -/** - * notion-enhancer - * (c) 2021 dragonwocky (https://dragonwocky.me/) - * (https://notion-enhancer.github.io/) under the MIT license - */ - -'use strict'; - -import fsp from 'fs/promises'; - -export default async function (filepath) { - // https://github.com/notion-enhancer/desktop/issues/160 - // enable the notion:// url scheme/protocol on linux - const contents = await fsp.readFile(filepath, 'utf8'); - await fsp.writeFile( - filepath, - contents.replace( - /process.platform === "win32"/g, - 'process.platform === "win32" || process.platform === "linux"' - ) - ); - return true; -} diff --git a/src/desktop/patches/main/schemeHandler.mjs b/src/desktop/patches/main/schemeHandler.mjs deleted file mode 100644 index 02251dd..0000000 --- a/src/desktop/patches/main/schemeHandler.mjs +++ /dev/null @@ -1,45 +0,0 @@ -/** - * notion-enhancer - * (c) 2021 dragonwocky (https://dragonwocky.me/) - * (https://notion-enhancer.github.io/) under the MIT license - */ - -'use strict'; - -import fsp from 'fs/promises'; - -export default async function (filepath) { - // https://github.com/notion-enhancer/desktop/issues/291 - // bypass csp issues by intercepting notion:// protocol - const contents = await fsp.readFile(filepath, 'utf8'); - await fsp.writeFile( - filepath, - contents.replace( - /const success = protocol\.registerStreamProtocol\(config_1.default.protocol, async \(req, callback\) => \{/, - `const success = protocol.registerStreamProtocol(config_1.default.protocol, async (req, callback) => { - { - // notion-enhancer - const schemePrefix = 'notion://www.notion.so/__notion-enhancer/'; - if (req.url.startsWith(schemePrefix)) { - const { search, hash, pathname } = new URL(req.url), - resolvePath = (path) => require('path').resolve(\`\${__dirname}/\${path}\`), - fileExt = pathname.split('.').reverse()[0], - mimeDB = Object.entries(require('notion-enhancer/dep/mime-db.json')), - mimeType = mimeDB - .filter(([mime, data]) => data.extensions) - .find(([mime, data]) => data.extensions.includes(fileExt)); - let filePath = '../node_modules/notion-enhancer/'; - filePath += req.url.slice(schemePrefix.length); - if (search) filePath = filePath.slice(0, -search.length); - if (hash) filePath = filePath.slice(0, -hash.length); - callback({ - data: require('fs').createReadStream(resolvePath(filePath)), - headers: { 'content-type': mimeType }, - }); - } - }` - ) - ); - - return true; -} diff --git a/src/desktop/patches/main/systemMenu.mjs b/src/desktop/patches/main/systemMenu.mjs deleted file mode 100644 index f5d18ea..0000000 --- a/src/desktop/patches/main/systemMenu.mjs +++ /dev/null @@ -1,22 +0,0 @@ -/** - * notion-enhancer - * (c) 2021 dragonwocky (https://dragonwocky.me/) - * (https://notion-enhancer.github.io/) under the MIT license - */ - -'use strict'; - -import fsp from 'fs/promises'; - -export default async function (filepath) { - // so that e.g. tabs access and modify the template - const contents = await fsp.readFile(filepath, 'utf8'); - await fsp.writeFile( - filepath, - contents.replace( - /electron_1\.Menu\.setApplicationMenu\(menu\);/g, - 'electron_1.Menu.setApplicationMenu(menu); return template;' - ) - ); - return true; -} diff --git a/src/desktop/insert/worker.cjs b/src/desktop/worker.cjs similarity index 100% rename from src/desktop/insert/worker.cjs rename to src/desktop/worker.cjs