RFC 40 - Dendron Plugins

This proposal is currently a draft and is not yet finalized.

Goals

Dendron has some extension points, such as Note Lifecycle Hooks and Note Traits, and Pods.

However, there is no easy way to manage and share these extensions. This RFC proposes a standard way for creating, packaging, and distributing Dendron plugins that can interface with these extension points.

Context

Hooks and Note Traits, currently just open a javascript file for users to write their code in. This is not ideal: there is no way for users to import in libraries or even split their code into multiple files.

Pods do allow custom pods, but the custom pods can't be used in the extension, and sharing one is difficult.

For all of these, they only can be written in javascript and not in languages that compile to javascript, such as TypeScript or ClojureScript.

Proposal

Plugins

Dendron plugins are zip files that contain a dendron-plugin.json file, one or more .js files, and an optional readme.md file.

The dendron-plugin.json contains the information about the plugin (plugin metadata), and will look like this:

{
    id: "@jane.doe/example-plugin", // required
    name: "Example Plugin", // required
    description: "Does many useful things", // required, short description of what the plugin does
    version: "1.2.3", // required, version of the plugin itself
    supportedDendronVersion: "^0.80", // required, supports Dendron 0.80 or newer
    developers: ["Jane Doe <jane.doe@example.com>"], // required, one or more developers of this plugin. email is optional.
    license: "MIT", // required, the license that the plugin is released under or PROPRIETARY if it's not free open source software
    repository: "github.com/jane.doe/example-plugin", // required, the repository where the plugin can be downloaded
    branch: "main", // required, the branch of the repository to use when getting the latest version
    website: "https://example.com", // optional, a page for the plugin
    conflicts: [], // optional, list of plugin IDs this one can't be installed along with at the same time
    provides: {
        hooks: "hook.js", // optional, the name of the file inside the zip that provides hooks
        traits: { // optional, one or more traits provided by this plugin
            "trait-name": "traits.js", // optional, the name of the file inside the zip that provides trait actions
        },
        pods: { // optional, one or more pods provided by this plugin
            "pod-name": "pod.js" // optional, the name of the file inside the zip that provides the pod
        }
    },
}

The readme.md is a simple markdown file, which should describe the plugin and the features it provides.

.js files referenced in the plugin metadata should be included with the same name. These javascript files may be run in the plugin, or the CLI.

repository

The repository this extension is hosted at. Only supported repositories may be used (Github, Gitlab).

Plugin Templates

Dendron should provide templates for these plugins using Yeoman. The template should be set up to bundle the plugin code into single js files, and package everything into the plugin zip.

Yeoman supports prompting a user for options, which can be used to get the data like name and description for the plugin metadata. Yeoman templates can also accept arguments, which could be used to select whether the plugin will provide hooks, traits, pods, or a combination of these.

Dendron should provide a template for at least JavaScript and TypeScript.

Plugin Registry

Dendron should have a registry for plugins. This registry will be a Github repository containing a registry.json file, which will contain a map that maps plugin ids to plugin metadata. The file will look like this:

{
    "@jane.doe/example-plugin": { // id of the plugin
        name: "Example Plugin",
        description: "Does many useful things",
        repository: "github.com/jane.doe/example-plugin", // required, the repository where the plugin can be downloaded
        branch: "main",
        developers: ["Jane Doe <jane.doe@example.com>"], // required, one or more developers of this plugin. email is optional.
        license: "MIT", // required, the license that the plugin is released under or PROPRIETARY if it's not free open source software
        website: "https://example.com", // optional, a page for the plugin
        conflicts: [], // optional, list of plugin IDs this one can't be installed along with at the same time
        provides: { // optional, should match the file
            hooks: "hook.js", // optional, the name of the file inside the zip that provides hooks
            traits: { // optional, one or more traits provided by this plugin
                "trait-name": "traits.js", // optional, the name of the file inside the zip that provides trait actions
            },
            pods: { // optional, one or more pods provided by this plugin
                "pod-name": "pod.js" // optional, the name of the file inside the zip that provides the pod
            }
        },
    },
    // ... more extensions
}

Contributions

Contributions to the registry will be accepted through pull requests to the registry repository. The namespace in the id must match the username or the organization name that's hosting the plugin.

Registry user interface

Dendron should provide user interfaces for this registry through the Dendron plugin, the Dendron CLI, and a web page.

The plugin and CLI will download the registry.json file from Github, then display an interface listing all plugins and allowing search.

The web page should be statically built from the registry with a Github action. It should display the available plugins.

Details

The registry should take care to avoid Zip Bombs.

Example

Tradeoffs

Discussion

See the discusson on Github if you have any suggestions.


Backlinks