Plugins

Add your own actions to Mantidb with small, signed JavaScript plugins.

Plugins add actions to Mantidb's context menus. A plugin is a small JavaScript program that can read the table or rows you right-clicked, run queries (with your permission), copy text and show messages. Every plugin is signed, and you decide which ones to trust.

Manage plugins

Open Mantidb ▸ Settings… (⌘,) and choose Plugins.

The Installed list shows each plugin's name, version and author, description and signing status. For each plugin you can:

  • Turn it on or off with the Enabled switch.
  • Click Review… when a plugin needs your trust before it can run (see Signing and trust).
  • Click Remove to uninstall it.

The pane also has these buttons:

  • Install… — choose a .mantidbplugin folder to install.
  • Install Example — installs the example plugin.
  • Show in Finder — opens the plugins folder.

Plugins are installed to ~/Library/Application Support/Mantidb/Plugins/.

Use a plugin

Plugin actions appear in two places, depending on the plugin:

  • Tables — right-click a table or view in the sidebar.
  • Rows — right-click rows in the data grid. The action receives the row you clicked, or the selected rows.

Plugin structure

A plugin is a folder named <id>.mantidbplugin:

com.example.tools.mantidbplugin/
├── manifest.json
├── signature.json
└── main.js
  • manifest.json describes the plugin.
  • signature.json holds its signature.
  • main.js (or the file named in main) is the plugin's code.

manifest.json

FieldDescription
idA unique reverse-DNS identifier, such as com.example.tools.
nameThe name shown in Settings.
versionThe plugin's version.
authorWho made it.
descriptionA short description.
mainThe JavaScript file to run. Defaults to main.js.
permissionsAny of query, write and clipboard. write requires query.
actionsThe actions the plugin adds, each with an id, a title and its contexts.
filesThe SHA-256 hash of every file in the plugin.

Each action's contexts lists where it appears: table for the sidebar menu of tables and views, rows for the grid menu.

{
  "id": "com.example.tools",
  "name": "Example Tools",
  "version": "1.0.0",
  "author": "You",
  "description": "Copies rows as JSON and counts the rows of a table.",
  "main": "main.js",
  "permissions": ["query", "clipboard"],
  "actions": [
    { "id": "copy-json", "title": "Copy as JSON", "contexts": ["rows"] },
    { "id": "count-rows", "title": "Count Rows", "contexts": ["table"] }
  ],
  "files": {
    "main.js": "<sha-256 of main.js>"
  }
}

You don't fill in files by hand: mantidb-plugin sign writes the hashes and the signature for you (see The mantidb-plugin tool).

Signing and trust

Every plugin must be signed with an Ed25519 key. The signature covers the exact bytes of manifest.json, and the manifest lists the SHA-256 hash of every file. Mantidb refuses a plugin that is unsigned, has been modified, contains files that aren't listed, or contains symbolic links.

The first time you enable a plugin, Mantidb asks Trust “<name>”? and shows its key fingerprint (SHA256:…), the permissions it requests and the actions it adds. Click Trust and Enable to allow it.

Mantidb asks again when:

  • the plugin is signed with a different key, or
  • an update requests more permissions.

JavaScript API

Register a function for each action declared in the manifest. Rows arrive as arrays of values, in the same order as ctx.columns:

mantidb.registerAction("copy-json", async (ctx) => {
  const names = ctx.columns.map((column) => column.name);
  const objects = ctx.rows.map((row) =>
    Object.fromEntries(row.map((value, i) => [names[i], value]))
  );
  await mantidb.copyToClipboard(JSON.stringify(objects, null, 2));
  await mantidb.showMessage(`Copied ${ctx.rows.length} rows as JSON.`);
});

mantidb.registerAction("count-rows", async (ctx) => {
  // qualifiedName is already quoted for the connection's dialect.
  const result = await mantidb.query(`SELECT COUNT(*) FROM ${ctx.table.qualifiedName}`);
  await mantidb.showMessage(`${ctx.table.name} has ${result.rows[0][0]} rows.`);
});

The context object

PropertyDescription
kindWhere the action was called from.
connectionname, driver, environment and safeMode of the connection.
schemaThe current schema.
tableschema, name, kind and qualifiedName of the table.
columnsThe columns of the rows.
rowsThe rows the action was called on.

Functions

FunctionDescription
mantidb.registerAction(id, fn)Runs fn(ctx) when the user picks the action id.
mantidb.query(sql)Runs one statement. Returns a promise with columns, columnTypes, rows, affectedRows and truncated. Needs the query permission.
mantidb.copyToClipboard(text)Copies text. Needs the clipboard permission.
mantidb.showMessage(text)Shows a message to the user.
mantidb.log(...) / console.log(...)Writes to the log.

Writes with mantidb.query need the write permission, and Mantidb always asks you to approve each one, whatever the connection's safe mode.

Limits

  • Each run can take up to 120 seconds, with at most 10 seconds of continuous synchronous work.
  • Plugins have no network access, no file access, no timers and no require.

Plugin actions can't be assigned keyboard shortcuts, and they don't appear in the SQL editor or in query results.

Example plugin

Click Install Example in Settings ▸ Plugins to install Markdown Tools (example). It adds two actions:

  • Copy as Markdown Table — in the data grid's context menu.
  • Count Rows — in the sidebar's context menu for tables.

It's a good starting point for your own plugin: click Show in Finder to look at its files.

The mantidb-plugin tool

Use the mantidb-plugin command-line tool to create a signing key, sign your plugin and check it before you share it:

# Create a signing key (once)
mantidb-plugin keygen ~/keys/plugins.key

# Sign the plugin after every change
mantidb-plugin sign com.example.tools.mantidbplugin ~/keys/plugins.key

# Check the signature and file hashes
mantidb-plugin verify com.example.tools.mantidbplugin

Keep your key file private: anyone who has it can sign plugins as you. If you sign with a different key, users are asked to trust the plugin again.