document mod.js, prepare to load

This commit is contained in:
dragonwocky 2020-07-14 13:01:07 +10:00
parent 2131e4e19d
commit c60299ed85
Signed by: dragonwocky
GPG Key ID: C7A48B7846AA706D
5 changed files with 109 additions and 56 deletions

View File

@ -1,4 +1,4 @@
# readme placeholder # documentation placeholder
ended up here? this is a wip version of the enhancer, and this file is yet to be completed. ended up here? this is a wip version of the enhancer, and this file is yet to be completed.
if you're interested in using the project, switch back to the [master branch](https://github.com/dragonwocky/notion-enhancer). if you're interested in using the project, switch back to the [master branch](https://github.com/dragonwocky/notion-enhancer).
@ -8,6 +8,12 @@ want to contribute? check the the [contribution guidelines](CONTRIBUTING.md).
## module creation ## 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._
each directory in the `mods` folder is considered a module, with the entry point `mod.js`. each directory in the `mods` folder is considered a module, with the entry point `mod.js`.
this file must have its exports set to an object that defines metadata, this file must have its exports set to an object that defines metadata,
configurable options for the menu, code to be run in both the back- and front- ends of the app, configurable options for the menu, code to be run in both the back- and front- ends of the app,
@ -15,51 +21,57 @@ and styling.
`module.exports =` `module.exports =`
| key | value | required | | key | value | desc | required |
| ------- | ---------------------------------- | -------- | | -------- | ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------- | -------- |
| id | uuidv4 string | ✔️ | | id | uuidv4 string | | ✔️ |
| meta | { meta: see below } | ✔️ | | type | 'extension', 'theme' | | ✔️ |
| options | [ array of { option: see below } ] | | | name | string | | ✔️ |
| code | { code: see below } | ✔️ | | desc | string | | |
| version | semver string (e.g. '0.3.7') | | ✔️ |
`meta: { }` | author | github username string | | ✔️ |
| thumb | relative file string, url | | |
| key | value | required | | options | [ array of { option: see below } ] | options made available in the enhancer menu (accessible from the tray) | |
| ------- | ---------------------------- | -------- | | styles | relative file string | css file automatically inserted into each app window via the `enhancement://` protocol | |
| type | 'extension', 'theme' | ✔️ | | main | function(store, electron) | executed on app launch in the "main" process (singular, shared between all apps - consider it a backend) | |
| name | string | ✔️ | | renderer | function(store) | executed on window launch in the "renderer" process (per-window, the client-side js one might expect to run on a website) | |
| version | semver string (e.g. '0.3.7') | ✔️ | | hack | function(store, helpers) | executed on enhancement (useful for e.g. find/replace on files, modding that can't be done just through insertion) | |
| author | github username string | ✔️ |
| thumb | relative file string, url | |
`{ option }` `{ option }`
| key | value | required | | key | value | desc | required |
| ----- | -------------------------------------------------------------------------------- | -------- | | ----- | -------------------------------------------------------------------------------- | ---------------------------------------------------- | -------- |
| name | string | ✔️ | | name | string | key to save value to the mod **`store`** (see below) | ✔️ |
| type | 'toggle', 'select', 'input', 'file' | ✔️ | | type | 'toggle', 'select', 'input', 'file' | | ✔️ |
| value | type.toggle = true, false. type.select = [array of strings]. type.input = string | | | value | type.toggle = true, false. type.select = [array of strings]. type.input = string | default value or possible values | |
`code: {}` the **`store`** argument allows access to the module settings/options, saved to `~/.notion-enhancer/id.json`.
it can be initialised with `store(defaults)`, then used as if it were a normal object.
it will automatically sync with the JSON file.
| key | value | required | the **`helpers`** argument exposes the shared variables/classes/functions in the `helpers.js` file.
| -------- | -------------------- | -------- |
| styles | relative file string | |
| main | function | |
| renderer | function | |
| hack | function | |
_styles_ should be a css file, which is automatically inserted into each app window via the `enhancement://` protocol. ```js
{
// 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
data_folder,
// wait for console input, returns keys when enter pressed.
readline(),
// gets possible system notion app filepaths.
getNotion(),
// read JSON from a file, fall back to empty obj.
getJSON(file),
// promisified https://nodejs.org/api/child_process.html#child_process_child_process_exec_command_options_callback
exec(command, options),
}
```
_main_ code is executed on app launch in the "main" process (singular, shared between all apps - consider it a backend). the **`electron`** argument provides access to the [electron](https://www.npmjs.com/package/electron) module.
_renderer_ code is executed on window launch in the "renderer" process
(per-window, the client-side js one might expect to run on a website).
note that as this code is inserted into notion's app, it may not work to `require()` modules that are not ## theming
already installed for the app. in future a fix for this is planned.
_hack_ code is executed on enhancement. this can be useful for things that require modding pre-existing parts of the app, css vars to be documented
and can't just be overruled (e.g. making the window frameless).
to make the best use of these, check out [the electron docs](https://www.electronjs.org/docs/)
and explore the contents of your local extracted `app.asar`.

View File

@ -6,18 +6,15 @@
module.exports = { module.exports = {
id: '0f0bf8b6-eae6-4273-b307-8fc43f2ee082', id: '0f0bf8b6-eae6-4273-b307-8fc43f2ee082',
meta: { type: 'core',
type: 'extension', name: 'notion-enhancer',
name: 'notion-enhancer core',
version: require('../../package.json').version, version: require('../../package.json').version,
author: 'dragonwocky', author: 'dragonwocky',
thumb: thumb:
'https://camo.githubusercontent.com/5c5bca9e987d986b8cc7e51066f90c6f8a84af08/68747470733a2f2f63646e2e646973636f72646170702e636f6d2f6174746163686d656e74732f3733313634373938343332333931393933332f3733313732373235393239353032333132342f494d475f323137302e6a7067', 'https://camo.githubusercontent.com/5c5bca9e987d986b8cc7e51066f90c6f8a84af08/68747470733a2f2f63646e2e646973636f72646170702e636f6d2f6174746163686d656e74732f3733313634373938343332333931393933332f3733313732373235393239353032333132342f494d475f323137302e6a7067',
},
options: [], options: [],
code: {
styles: 'styles.css', styles: 'styles.css',
electron: () => {}, electron: () => {},
client: () => {}, client: () => {},
}, hack: () => {},
}; };

View File

@ -25,7 +25,7 @@ module.exports = async function ({ overwrite_version } = {}) {
await fs.ensureDir(helpers.data_folder); await fs.ensureDir(helpers.data_folder);
// handle pre-existing installations: app.asar present? version set in data folder? overwrite? // handle pre-existing installations: app.asar present? version set in data folder? overwrite?
const check_app = require('./check.js')(); const check_app = await require('./check.js')();
switch (check_app.code) { switch (check_app.code) {
case 1: case 1:
console.log(`~~ notion-enhancer v${version} already applied.`); console.log(`~~ notion-enhancer v${version} already applied.`);
@ -92,7 +92,51 @@ module.exports = async function ({ overwrite_version } = {}) {
} }
} }
const mods = await fs.readdir(path.join(__dirname, '..', 'mods')),
invalid_mods = [],
loaded_mods = [];
for (let dir of mods) {
try {
const mod = require(`../mods/${dir}/mod.js`);
if (
!mod.id ||
!mod.name ||
!mod.version ||
!mod.author ||
!['extension', 'theme', 'core'].includes(mod.type)
)
throw Error;
loaded_mods.push(mod.name);
} catch (err) {
invalid_mods.push(dir);
}
}
if (loaded_mods.length)
console.log(` ...mods loaded: ${loaded_mods.join(', ')}.`);
if (invalid_mods.length)
console.log(` * invalid mods found: ${invalid_mods.join(', ')}.`);
// module.exports = {
// id: '0f0bf8b6-eae6-4273-b307-8fc43f2ee082',
// meta: {
// type: 'extension',
// name: 'notion-enhancer core',
// version: require('../../package.json').version,
// author: 'dragonwocky',
// thumb:
// 'https://camo.githubusercontent.com/5c5bca9e987d986b8cc7e51066f90c6f8a84af08/68747470733a2f2f63646e2e646973636f72646170702e636f6d2f6174746163686d656e74732f3733313634373938343332333931393933332f3733313732373235393239353032333132342f494d475f323137302e6a7067',
// },
// options: [],
// code: {
// styles: 'styles.css',
// electron: () => {},
// client: () => {},
// hack: () => {},
// },
// };
// not resolved, nothing depends on it so it's just a "let it do its thing" // not resolved, nothing depends on it so it's just a "let it do its thing"
console.info(' ...recording enhancement version.');
fs.outputFile(path.join(__notion, 'app', 'ENHANCER_VERSION.txt'), version); fs.outputFile(path.join(__notion, 'app', 'ENHANCER_VERSION.txt'), version);
fs.outputFile(path.join(helpers.data_folder, 'version.txt'), version); fs.outputFile(path.join(helpers.data_folder, 'version.txt'), version);

View File

@ -13,7 +13,7 @@ const fs = require('fs-extra'),
// handle pre-existing installations: app.asar modded? with which enhancer version? // handle pre-existing installations: app.asar modded? with which enhancer version?
let __notion = helpers.getNotion(); let __notion = helpers.getNotion();
module.exports = async function ({ overwrite_version } = {}) { module.exports = async function () {
__notion = await __notion; __notion = await __notion;
const version_path = path.join(__notion, 'app', 'ENHANCER_VERSION.txt'), const version_path = path.join(__notion, 'app', 'ENHANCER_VERSION.txt'),

View File

@ -10,7 +10,7 @@ const os = require('os'),
fs = require('fs-extra'), fs = require('fs-extra'),
exec = require('util').promisify(require('child_process').exec); exec = require('util').promisify(require('child_process').exec);
// used to differentiate between informative errors and "enhancer-is-dying" errors. // used to differentiate between "enhancer failed" and "code broken" errors.
class EnhancerError extends Error { class EnhancerError extends Error {
constructor(message) { constructor(message) {
super(message); super(message);