conditions
Adds tests for Only if that return true or false, implemented in an extension.
Details #
A condition is a test a macro can put under Only if. You declare it under adds.conditions in switchboard.json and implement it with condition(id, handler). When the macro reaches the test, Switchboard calls your handler with the params the person filled in. The handler answers true (carry on) or false (stop here).
Once the extension is installed, the condition shows in the Only if chooser under the extension's name. Its type is <extension id>.<condition id>.
{
"adds": {
"conditions": [{
"id": "on-vpn", "title": "VPN is connected",
"params": { "type": "object", "properties": { "name": { "type": "string" } } }
}]
}
}
import { defineExtension, condition } from '@switchboard/sdk';
export default defineExtension({
conditions: [
condition('on-vpn', async (p: { name?: string }, ctx) => {
const r = await ctx.exec('/usr/sbin/scutil', ['--nc', 'list']);
return r.stdout.includes('(Connected)') && (!p.name || r.stdout.includes(p.name));
}),
],
});
The ctx.exec call above needs this in the manifest:
{ "permissions": { "exec": { "commands": ["/usr/sbin/scutil"] } } }
The declaration and the code must match. An extension that declares a condition it does not implement, or implements one it does not declare, is refused when it loads.
Gotchas #
Return
false, not nothing, for "does not match". Anything that is not a boolean or an object withpassedis an error ("must answer true or false").A call that takes more than 10 seconds is cut off and the condition fails.
Anything the handler does outside the sandbox (network, files, clipboard, running a program) needs a permission in the manifest. Without it the call fails with
permission denied.A sensor (sensors) is also usable as a condition, with no code of yours: it tests the sensor's latest value.
What the handler gets and returns #
Input: the condition's params, as saved in the macro.
Return: a boolean. The engine also accepts an object with a boolean
passed(the other fields are kept as "what was compared" for the run log), but the SDK types the handler as returning a boolean, so the plain form is simplest.Throw an
Errorfor input you cannot use. The run reports the message and the macro stops with an error, which is different fromfalse.
Full example #
The sample below has two conditions: a time window that can cross midnight, and a text pattern test. You can download it from the Full example section and edit it into your own.