diff --git a/DOCUMENTATION.md b/DOCUMENTATION.md index 3dab99b..ee43fe9 100644 --- a/DOCUMENTATION.md +++ b/DOCUMENTATION.md @@ -6,13 +6,15 @@ for support, contact me on discord `dragonwocky#8449` or open an issue here in t want to contribute? check the the [contribution guidelines](CONTRIBUTING.md). +--- + ## module creation _to understand best how notion's app works, check out [the electron docs](https://www.electronjs.org/docs/)_ _and explore the contents of your local extracted `app.asar`._ -_explore out [the existing modules](https://github.com/dragonwocky/notion-enhancer/tree/js/mods/)_ -_for examples of how the below is implemented._ +_explore [the existing modules](https://github.com/dragonwocky/notion-enhancer/tree/js/mods/)_ +_for examples of implementing what's described below._ each directory in the `mods` folder is considered a module, and consist of 5 files: @@ -24,9 +26,11 @@ each directory in the `mods` folder is considered a module, and consist of 5 fil | `renderer.js` | **optional:** executed on window launch in the "renderer" process (per-window, the client-side js one might expect to run on a website) of `app/renderer/preload.js` | | `styles.css` | **optional:** css file automatically inserted into each app window via the `enhancement://` protocol | +--- + ### meta -`module.exports =` +`module.exports = {}` | key | value | type | | --------- | ----------------------------------------------------------------------------------------------- | ----------------- | @@ -39,23 +43,23 @@ each directory in the `mods` folder is considered a module, and consist of 5 fil | thumbnail | **optional:** image: relative file or url | _string_ | | options | **optional:** see below: options made available in the enhancer menu (accessible from the tray) | _array\_ | -`module.exports.options =` +`module.exports.options = {}` | key | value | type | | ----- | ------------------------------------------------------------- | --------- | | key | **required:** key to save value to the mod `store` | _string_ | -| type | **required:** 'toggle', 'select', 'input' or 'file' | _string_ | | label | **required:** short description of option to be shown in menu | _string_ | +| type | **required:** input type (see below) | _string_ | | value | **optional:** default or possible value/s for option | see below | -`module.exports.options.value =` +| type | value | +| ------ | ----------------- | +| toggle | _boolean_ | +| select | _array\_ | +| input | _string_ | +| file | none | -| option type | value | -| ----------- | --------------- | -| toggle | _boolean_ | -| select | _array_ | -| input | _string_ | -| file | none | +--- ### scripting @@ -79,34 +83,151 @@ the **`__notion`** argument gives the filepath of the app parent folder. use it for e.g. find/replace on pre-existing app code in `__notion/app/renderer/createWindow.js` to make the window frameless. -shared variables/classes/functions in the `helpers.js` file: for consistency of error handling and -cross-platform functionality these **should** be used to achieve their purpose. +#### shell output + +`hack.js` files may communicate with the user during enhancement. + +these communications should be in the following format: ```js -require('../../pkg/helpers.js'); +// used by modules +console.info(' ...information.'); +console.warn(' * warning.'); +console.warn(' > prompt?'); +console.warn(' -- response to user input.'); +// used internally +console.info('=== title ==='); +console.error('### error ###'); +(console.error || console.info)(' ~~ exit.'); +``` -{ - // used to differentiate between "enhancer failed" and "code broken" errors. - class EnhancerError {}, - // checks if being run on the windows subsystem for linux: - // used to modify windows notion app. - is_wsl, - // ~/.notion-enhancer absolute path. - data_folder, - // transform a wsl filepath to its relative windows filepath if necessary. - // every file path inserted by hack.js should be put through this. - realpath(wsl_path), - // wait for console input, returns keys when enter pressed. - readline(), - // gets notion app filepath (the __notion argument above). - getNotion(), - // attempts to read a JSON file, falls back to empty object. - getJSON(file), - // promisified https://nodejs.org/api/child_process.html#child_process_child_process_exec_command_options_callback - exec(command, options), +#### helpers + +```js +const helpers = require('../../pkg/helpers.js'); +``` + +shared variables/classes/functions can be found in the `helpers.js` file: for consistency of error handling and +cross-platform functionality these **should** be used to achieve their purpose. + +--- + +```js +class EnhancerError(message) {} +``` + +use `throw new helpers.EnhancerError(message)` if ever something occurs that would cause enhancement to fail, +but is not caused by faulty programming: e.g. if a file that is known to exist cannot be found. + +--- + +```js +const is_wsl; +``` + +use `helpers.is_wsl` to check if the enhancer was run from the windows subsystem for linux. + +primarily used for internal handling of filepaths (e.g. in the `helpers.realpath` and `helpers.getNotion` functions). + +--- + +```js +const data_folder; +``` + +use `helpers.data_folder` to get the absolute path of the directory configuration/version +data is saved to by the enhancer. + +if used immediately after being accessed, it should always work. however, if fetching its value during enhancement +and then inserting it into something that will not be executed until the app is opened, it must be put through +`helpers.realpath` before insertion. + +--- + +```js +function realpath(hack_path) { + return runtime_path; } ``` +use `helpers.realpath(hack_path)` to transform a path valid at enhancement time into one valid when the app is opened. +this is particularly useful for wsl compatibility, so every filepath that is fetched during enhancement +and then inserted into something that will not be executed until the app is opened should be put through this. + +primarily used for internal handling of filepaths (e.g. for the modloader). + +--- + +```js +async function getNotion() { + return notion_app_path; +} +``` + +use `await helpers.getNotion()` to get the notion app parent folder path +(used to acquire the \_\_notion argument above). + +primarily used for internal modding of the app (e.g. to apply the modloader and patch launch scripts). + +--- + +```js +function getJSON(from) { + return data; +} +``` + +use `helpers.getJSON(from)` to read/parse a JSON file. if the file has invalid contents or does not exist, +an empty object will be returned. + +primarily used for internal data management (e.g. in the module `store()`). + +--- + +```js +function readline() { + return Promise(input); +} +``` + +use `helpers.readline()` to receive user input from the terminal/shell/prompt during enhancement. + +example usage: + +```js +// situation: conflicting file found. +let overwrite; +do { + // using stdout.write means that there is no newline + // between prompt and input. + process.stdout.write(' > overwrite? [Y/n]: '); + overwrite = await helpers.readline(); + // ask for a Y/n until a valid answer is received. + // pressing enter without input is assumed to be a "yes". +} while (overwrite && !['y', 'n'].includes(overwrite.toLowerCase())); +overwrite = !overwrite || overwrite.toLowerCase() == 'y'; +if (overwrite) { + console.info(' -- overwriting file.'); + // do stuff +} else console.info(' -- keeping file: skipping step.'); +``` + +--- + +```js +async function exec(command[, options]) { + return child_process; +} +``` + +use `helpers.exec()` to execute shell commands. it is a promisified version of node.js's +[child_process.exec(command[, options][, callback])](https://nodejs.org/api/child_process.html#child_process_child_process_exec_command_options_callback). + +primarily used for internal processes (e.g. unpacking asar, fetching windows app path from the wsl). +for security reasons this should not be used by modules. + +--- + #### styling css vars to be documented diff --git a/pkg/helpers.js b/pkg/helpers.js index c2c3fd9..16b0032 100644 --- a/pkg/helpers.js +++ b/pkg/helpers.js @@ -28,26 +28,13 @@ const is_wsl = // transform a wsl filepath to its relative windows filepath if necessary. // every file path inserted by hack.js should be put through this. -function realpath(wsl_path) { - if (!is_wsl) return wsl_path; - wsl_path = fs.realpathSync(wsl_path); - if (wsl_path.startsWith('/mnt/')) { - wsl_path = `${wsl_path[5].toUpperCase()}:${wsl_path.slice(6)}`; - } else wsl_path = `//wsl$/${process.env.WSL_DISTRO_NAME}${wsl_path}`; - return wsl_path; -} - -// wait for console input, returns keys when enter pressed. -function readline() { - return new Promise((res, rej) => { - process.stdin.resume(); - process.stdin.setEncoding('utf8'); - process.stdin.on('data', (key) => { - if (key === '\u0003') process.exit(); // CTRL+C - process.stdin.pause(); - res(key.trim()); - }); - }); +function realpath(hack_path) { + if (!is_wsl) return hack_path; + hack_path = fs.realpathSync(hack_path); + if (hack_path.startsWith('/mnt/')) { + hack_path = `${hack_path[5].toUpperCase()}:${hack_path.slice(6)}`; + } else hack_path = `//wsl$/${process.env.WSL_DISTRO_NAME}${hack_path}`; + return hack_path; } // gets possible system notion app filepaths. @@ -113,13 +100,26 @@ function getJSON(from) { } } +// wait for console input, returns keys when enter pressed. +function readline() { + return new Promise((res, rej) => { + process.stdin.resume(); + process.stdin.setEncoding('utf8'); + process.stdin.on('data', (key) => { + if (key === '\u0003') process.exit(); // CTRL+C + process.stdin.pause(); + res(key.trim()); + }); + }); +} + module.exports = { EnhancerError, is_wsl, data_folder, realpath, - readline, getNotion, getJSON, + readline, exec, };