@switchbot/openapi-cli 3.2.1 → 3.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -1
- package/dist/index.js +57419 -170
- package/package.json +9 -5
- package/dist/api/client.d.ts +0 -31
- package/dist/api/client.js +0 -236
- package/dist/api/client.js.map +0 -1
- package/dist/auth.d.ts +0 -1
- package/dist/auth.js +0 -21
- package/dist/auth.js.map +0 -1
- package/dist/commands/agent-bootstrap.d.ts +0 -10
- package/dist/commands/agent-bootstrap.js +0 -200
- package/dist/commands/agent-bootstrap.js.map +0 -1
- package/dist/commands/auth.d.ts +0 -18
- package/dist/commands/auth.js +0 -355
- package/dist/commands/auth.js.map +0 -1
- package/dist/commands/batch.d.ts +0 -2
- package/dist/commands/batch.js +0 -414
- package/dist/commands/batch.js.map +0 -1
- package/dist/commands/cache.d.ts +0 -2
- package/dist/commands/cache.js +0 -127
- package/dist/commands/cache.js.map +0 -1
- package/dist/commands/capabilities.d.ts +0 -31
- package/dist/commands/capabilities.js +0 -383
- package/dist/commands/capabilities.js.map +0 -1
- package/dist/commands/catalog.d.ts +0 -2
- package/dist/commands/catalog.js +0 -360
- package/dist/commands/catalog.js.map +0 -1
- package/dist/commands/completion.d.ts +0 -2
- package/dist/commands/completion.js +0 -386
- package/dist/commands/completion.js.map +0 -1
- package/dist/commands/config.d.ts +0 -21
- package/dist/commands/config.js +0 -377
- package/dist/commands/config.js.map +0 -1
- package/dist/commands/daemon.d.ts +0 -2
- package/dist/commands/daemon.js +0 -411
- package/dist/commands/daemon.js.map +0 -1
- package/dist/commands/device-meta.d.ts +0 -2
- package/dist/commands/device-meta.js +0 -160
- package/dist/commands/device-meta.js.map +0 -1
- package/dist/commands/devices.d.ts +0 -2
- package/dist/commands/devices.js +0 -949
- package/dist/commands/devices.js.map +0 -1
- package/dist/commands/doctor.d.ts +0 -3
- package/dist/commands/doctor.js +0 -1016
- package/dist/commands/doctor.js.map +0 -1
- package/dist/commands/events.d.ts +0 -31
- package/dist/commands/events.js +0 -564
- package/dist/commands/events.js.map +0 -1
- package/dist/commands/expand.d.ts +0 -2
- package/dist/commands/expand.js +0 -131
- package/dist/commands/expand.js.map +0 -1
- package/dist/commands/explain.d.ts +0 -2
- package/dist/commands/explain.js +0 -140
- package/dist/commands/explain.js.map +0 -1
- package/dist/commands/health.d.ts +0 -8
- package/dist/commands/health.js +0 -114
- package/dist/commands/health.js.map +0 -1
- package/dist/commands/history.d.ts +0 -2
- package/dist/commands/history.js +0 -321
- package/dist/commands/history.js.map +0 -1
- package/dist/commands/identity.d.ts +0 -45
- package/dist/commands/identity.js +0 -60
- package/dist/commands/identity.js.map +0 -1
- package/dist/commands/install.d.ts +0 -20
- package/dist/commands/install.js +0 -247
- package/dist/commands/install.js.map +0 -1
- package/dist/commands/mcp.d.ts +0 -14
- package/dist/commands/mcp.js +0 -2018
- package/dist/commands/mcp.js.map +0 -1
- package/dist/commands/plan.d.ts +0 -51
- package/dist/commands/plan.js +0 -654
- package/dist/commands/plan.js.map +0 -1
- package/dist/commands/policy.d.ts +0 -24
- package/dist/commands/policy.js +0 -587
- package/dist/commands/policy.js.map +0 -1
- package/dist/commands/quota.d.ts +0 -2
- package/dist/commands/quota.js +0 -79
- package/dist/commands/quota.js.map +0 -1
- package/dist/commands/rules.d.ts +0 -2
- package/dist/commands/rules.js +0 -876
- package/dist/commands/rules.js.map +0 -1
- package/dist/commands/scenes.d.ts +0 -2
- package/dist/commands/scenes.js +0 -265
- package/dist/commands/scenes.js.map +0 -1
- package/dist/commands/schema.d.ts +0 -2
- package/dist/commands/schema.js +0 -185
- package/dist/commands/schema.js.map +0 -1
- package/dist/commands/status-sync.d.ts +0 -2
- package/dist/commands/status-sync.js +0 -132
- package/dist/commands/status-sync.js.map +0 -1
- package/dist/commands/uninstall.d.ts +0 -20
- package/dist/commands/uninstall.js +0 -238
- package/dist/commands/uninstall.js.map +0 -1
- package/dist/commands/upgrade-check.d.ts +0 -2
- package/dist/commands/upgrade-check.js +0 -107
- package/dist/commands/upgrade-check.js.map +0 -1
- package/dist/commands/watch.d.ts +0 -2
- package/dist/commands/watch.js +0 -195
- package/dist/commands/watch.js.map +0 -1
- package/dist/commands/webhook.d.ts +0 -2
- package/dist/commands/webhook.js +0 -183
- package/dist/commands/webhook.js.map +0 -1
- package/dist/config.d.ts +0 -57
- package/dist/config.js +0 -259
- package/dist/config.js.map +0 -1
- package/dist/credentials/backends/file.d.ts +0 -18
- package/dist/credentials/backends/file.js +0 -102
- package/dist/credentials/backends/file.js.map +0 -1
- package/dist/credentials/backends/linux.d.ts +0 -16
- package/dist/credentials/backends/linux.js +0 -130
- package/dist/credentials/backends/linux.js.map +0 -1
- package/dist/credentials/backends/macos.d.ts +0 -18
- package/dist/credentials/backends/macos.js +0 -130
- package/dist/credentials/backends/macos.js.map +0 -1
- package/dist/credentials/backends/windows.d.ts +0 -23
- package/dist/credentials/backends/windows.js +0 -216
- package/dist/credentials/backends/windows.js.map +0 -1
- package/dist/credentials/keychain.d.ts +0 -83
- package/dist/credentials/keychain.js +0 -89
- package/dist/credentials/keychain.js.map +0 -1
- package/dist/credentials/prime.d.ts +0 -32
- package/dist/credentials/prime.js +0 -53
- package/dist/credentials/prime.js.map +0 -1
- package/dist/devices/cache.d.ts +0 -79
- package/dist/devices/cache.js +0 -294
- package/dist/devices/cache.js.map +0 -1
- package/dist/devices/catalog.d.ts +0 -138
- package/dist/devices/catalog.js +0 -768
- package/dist/devices/catalog.js.map +0 -1
- package/dist/devices/device-meta.d.ts +0 -15
- package/dist/devices/device-meta.js +0 -57
- package/dist/devices/device-meta.js.map +0 -1
- package/dist/devices/history-agg.d.ts +0 -37
- package/dist/devices/history-agg.js +0 -139
- package/dist/devices/history-agg.js.map +0 -1
- package/dist/devices/history-query.d.ts +0 -45
- package/dist/devices/history-query.js +0 -182
- package/dist/devices/history-query.js.map +0 -1
- package/dist/devices/param-validator.d.ts +0 -40
- package/dist/devices/param-validator.js +0 -434
- package/dist/devices/param-validator.js.map +0 -1
- package/dist/devices/resources.d.ts +0 -74
- package/dist/devices/resources.js +0 -271
- package/dist/devices/resources.js.map +0 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.js.map +0 -1
- package/dist/install/default-steps.d.ts +0 -66
- package/dist/install/default-steps.js +0 -258
- package/dist/install/default-steps.js.map +0 -1
- package/dist/install/preflight.d.ts +0 -60
- package/dist/install/preflight.js +0 -213
- package/dist/install/preflight.js.map +0 -1
- package/dist/install/steps.d.ts +0 -61
- package/dist/install/steps.js +0 -68
- package/dist/install/steps.js.map +0 -1
- package/dist/lib/command-keywords.d.ts +0 -5
- package/dist/lib/command-keywords.js +0 -18
- package/dist/lib/command-keywords.js.map +0 -1
- package/dist/lib/daemon-state.d.ts +0 -24
- package/dist/lib/daemon-state.js +0 -47
- package/dist/lib/daemon-state.js.map +0 -1
- package/dist/lib/destructive-mode.d.ts +0 -2
- package/dist/lib/destructive-mode.js +0 -13
- package/dist/lib/destructive-mode.js.map +0 -1
- package/dist/lib/devices.d.ts +0 -151
- package/dist/lib/devices.js +0 -383
- package/dist/lib/devices.js.map +0 -1
- package/dist/lib/idempotency.d.ts +0 -46
- package/dist/lib/idempotency.js +0 -107
- package/dist/lib/idempotency.js.map +0 -1
- package/dist/lib/plan-store.d.ts +0 -19
- package/dist/lib/plan-store.js +0 -69
- package/dist/lib/plan-store.js.map +0 -1
- package/dist/lib/request-context.d.ts +0 -7
- package/dist/lib/request-context.js +0 -13
- package/dist/lib/request-context.js.map +0 -1
- package/dist/lib/scenes.d.ts +0 -7
- package/dist/lib/scenes.js +0 -11
- package/dist/lib/scenes.js.map +0 -1
- package/dist/logger.d.ts +0 -4
- package/dist/logger.js +0 -17
- package/dist/logger.js.map +0 -1
- package/dist/mcp/device-history.d.ts +0 -36
- package/dist/mcp/device-history.js +0 -146
- package/dist/mcp/device-history.js.map +0 -1
- package/dist/mcp/events-subscription.d.ts +0 -45
- package/dist/mcp/events-subscription.js +0 -214
- package/dist/mcp/events-subscription.js.map +0 -1
- package/dist/mqtt/client.d.ts +0 -25
- package/dist/mqtt/client.js +0 -181
- package/dist/mqtt/client.js.map +0 -1
- package/dist/mqtt/credential.d.ts +0 -16
- package/dist/mqtt/credential.js +0 -31
- package/dist/mqtt/credential.js.map +0 -1
- package/dist/policy/add-rule.d.ts +0 -21
- package/dist/policy/add-rule.js +0 -125
- package/dist/policy/add-rule.js.map +0 -1
- package/dist/policy/diff.d.ts +0 -21
- package/dist/policy/diff.js +0 -92
- package/dist/policy/diff.js.map +0 -1
- package/dist/policy/format.d.ts +0 -6
- package/dist/policy/format.js +0 -58
- package/dist/policy/format.js.map +0 -1
- package/dist/policy/load.d.ts +0 -32
- package/dist/policy/load.js +0 -62
- package/dist/policy/load.js.map +0 -1
- package/dist/policy/migrate.d.ts +0 -21
- package/dist/policy/migrate.js +0 -68
- package/dist/policy/migrate.js.map +0 -1
- package/dist/policy/schema.d.ts +0 -5
- package/dist/policy/schema.js +0 -19
- package/dist/policy/schema.js.map +0 -1
- package/dist/policy/validate.d.ts +0 -19
- package/dist/policy/validate.js +0 -263
- package/dist/policy/validate.js.map +0 -1
- package/dist/rules/action.d.ts +0 -65
- package/dist/rules/action.js +0 -217
- package/dist/rules/action.js.map +0 -1
- package/dist/rules/audit-query.d.ts +0 -51
- package/dist/rules/audit-query.js +0 -90
- package/dist/rules/audit-query.js.map +0 -1
- package/dist/rules/conflict-analyzer.d.ts +0 -57
- package/dist/rules/conflict-analyzer.js +0 -215
- package/dist/rules/conflict-analyzer.js.map +0 -1
- package/dist/rules/cron-scheduler.d.ts +0 -62
- package/dist/rules/cron-scheduler.js +0 -187
- package/dist/rules/cron-scheduler.js.map +0 -1
- package/dist/rules/destructive.d.ts +0 -20
- package/dist/rules/destructive.js +0 -53
- package/dist/rules/destructive.js.map +0 -1
- package/dist/rules/engine.d.ts +0 -193
- package/dist/rules/engine.js +0 -758
- package/dist/rules/engine.js.map +0 -1
- package/dist/rules/matcher.d.ts +0 -56
- package/dist/rules/matcher.js +0 -231
- package/dist/rules/matcher.js.map +0 -1
- package/dist/rules/pid-file.d.ts +0 -43
- package/dist/rules/pid-file.js +0 -96
- package/dist/rules/pid-file.js.map +0 -1
- package/dist/rules/quiet-hours.d.ts +0 -26
- package/dist/rules/quiet-hours.js +0 -46
- package/dist/rules/quiet-hours.js.map +0 -1
- package/dist/rules/suggest.d.ts +0 -20
- package/dist/rules/suggest.js +0 -96
- package/dist/rules/suggest.js.map +0 -1
- package/dist/rules/throttle.d.ts +0 -61
- package/dist/rules/throttle.js +0 -117
- package/dist/rules/throttle.js.map +0 -1
- package/dist/rules/types.d.ts +0 -117
- package/dist/rules/types.js +0 -35
- package/dist/rules/types.js.map +0 -1
- package/dist/rules/webhook-listener.d.ts +0 -63
- package/dist/rules/webhook-listener.js +0 -224
- package/dist/rules/webhook-listener.js.map +0 -1
- package/dist/rules/webhook-token.d.ts +0 -50
- package/dist/rules/webhook-token.js +0 -91
- package/dist/rules/webhook-token.js.map +0 -1
- package/dist/schema/field-aliases.d.ts +0 -34
- package/dist/schema/field-aliases.js +0 -132
- package/dist/schema/field-aliases.js.map +0 -1
- package/dist/sinks/dispatcher.d.ts +0 -7
- package/dist/sinks/dispatcher.js +0 -13
- package/dist/sinks/dispatcher.js.map +0 -1
- package/dist/sinks/file.d.ts +0 -6
- package/dist/sinks/file.js +0 -20
- package/dist/sinks/file.js.map +0 -1
- package/dist/sinks/format.d.ts +0 -20
- package/dist/sinks/format.js +0 -57
- package/dist/sinks/format.js.map +0 -1
- package/dist/sinks/homeassistant.d.ts +0 -18
- package/dist/sinks/homeassistant.js +0 -45
- package/dist/sinks/homeassistant.js.map +0 -1
- package/dist/sinks/openclaw.d.ts +0 -13
- package/dist/sinks/openclaw.js +0 -34
- package/dist/sinks/openclaw.js.map +0 -1
- package/dist/sinks/stdout.d.ts +0 -4
- package/dist/sinks/stdout.js +0 -6
- package/dist/sinks/stdout.js.map +0 -1
- package/dist/sinks/telegram.d.ts +0 -11
- package/dist/sinks/telegram.js +0 -29
- package/dist/sinks/telegram.js.map +0 -1
- package/dist/sinks/types.d.ts +0 -13
- package/dist/sinks/types.js +0 -2
- package/dist/sinks/types.js.map +0 -1
- package/dist/sinks/webhook.d.ts +0 -6
- package/dist/sinks/webhook.js +0 -23
- package/dist/sinks/webhook.js.map +0 -1
- package/dist/status-sync/manager.d.ts +0 -48
- package/dist/status-sync/manager.js +0 -269
- package/dist/status-sync/manager.js.map +0 -1
- package/dist/utils/arg-parsers.d.ts +0 -16
- package/dist/utils/arg-parsers.js +0 -67
- package/dist/utils/arg-parsers.js.map +0 -1
- package/dist/utils/audit.d.ts +0 -69
- package/dist/utils/audit.js +0 -122
- package/dist/utils/audit.js.map +0 -1
- package/dist/utils/filter.d.ts +0 -81
- package/dist/utils/filter.js +0 -190
- package/dist/utils/filter.js.map +0 -1
- package/dist/utils/flags.d.ts +0 -72
- package/dist/utils/flags.js +0 -187
- package/dist/utils/flags.js.map +0 -1
- package/dist/utils/format.d.ts +0 -9
- package/dist/utils/format.js +0 -118
- package/dist/utils/format.js.map +0 -1
- package/dist/utils/health.d.ts +0 -48
- package/dist/utils/health.js +0 -102
- package/dist/utils/health.js.map +0 -1
- package/dist/utils/help-json.d.ts +0 -39
- package/dist/utils/help-json.js +0 -55
- package/dist/utils/help-json.js.map +0 -1
- package/dist/utils/name-resolver.d.ts +0 -26
- package/dist/utils/name-resolver.js +0 -138
- package/dist/utils/name-resolver.js.map +0 -1
- package/dist/utils/output.d.ts +0 -73
- package/dist/utils/output.js +0 -405
- package/dist/utils/output.js.map +0 -1
- package/dist/utils/quota.d.ts +0 -61
- package/dist/utils/quota.js +0 -228
- package/dist/utils/quota.js.map +0 -1
- package/dist/utils/redact.d.ts +0 -23
- package/dist/utils/redact.js +0 -69
- package/dist/utils/redact.js.map +0 -1
- package/dist/utils/retry.d.ts +0 -72
- package/dist/utils/retry.js +0 -141
- package/dist/utils/retry.js.map +0 -1
- package/dist/utils/string.d.ts +0 -2
- package/dist/utils/string.js +0 -23
- package/dist/utils/string.js.map +0 -1
- package/dist/version.d.ts +0 -2
- package/dist/version.js +0 -5
- package/dist/version.js.map +0 -1
package/dist/policy/validate.js
DELETED
|
@@ -1,263 +0,0 @@
|
|
|
1
|
-
import { createRequire } from 'node:module';
|
|
2
|
-
import { Ajv2020 } from 'ajv/dist/2020.js';
|
|
3
|
-
import { isMap, isSeq, isScalar } from 'yaml';
|
|
4
|
-
import { loadPolicyFile } from './load.js';
|
|
5
|
-
import { loadPolicySchema, CURRENT_POLICY_SCHEMA_VERSION, SUPPORTED_POLICY_SCHEMA_VERSIONS, isSupportedPolicySchemaVersion, } from './schema.js';
|
|
6
|
-
import { destructiveVerbOf, DESTRUCTIVE_COMMANDS } from '../rules/destructive.js';
|
|
7
|
-
const require = createRequire(import.meta.url);
|
|
8
|
-
const addFormats = require('ajv-formats');
|
|
9
|
-
const validators = new Map();
|
|
10
|
-
function getValidator(version) {
|
|
11
|
-
const cached = validators.get(version);
|
|
12
|
-
if (cached)
|
|
13
|
-
return cached;
|
|
14
|
-
const ajv = new Ajv2020({ allErrors: true, strict: false, allowUnionTypes: true });
|
|
15
|
-
addFormats(ajv);
|
|
16
|
-
const schema = loadPolicySchema(version);
|
|
17
|
-
const validate = ajv.compile(schema);
|
|
18
|
-
const compiled = { ajv, validate };
|
|
19
|
-
validators.set(version, compiled);
|
|
20
|
-
return compiled;
|
|
21
|
-
}
|
|
22
|
-
function instancePathToSegments(instancePath) {
|
|
23
|
-
if (!instancePath)
|
|
24
|
-
return [];
|
|
25
|
-
return instancePath
|
|
26
|
-
.slice(1)
|
|
27
|
-
.split('/')
|
|
28
|
-
.map((s) => s.replace(/~1/g, '/').replace(/~0/g, '~'));
|
|
29
|
-
}
|
|
30
|
-
function getNodeAt(doc, segments) {
|
|
31
|
-
let current = doc.contents;
|
|
32
|
-
for (const seg of segments) {
|
|
33
|
-
if (isMap(current)) {
|
|
34
|
-
const pair = current.items.find((p) => {
|
|
35
|
-
const k = p.key;
|
|
36
|
-
if (isScalar(k))
|
|
37
|
-
return String(k.value) === seg;
|
|
38
|
-
return false;
|
|
39
|
-
});
|
|
40
|
-
if (!pair)
|
|
41
|
-
return null;
|
|
42
|
-
current = pair.value;
|
|
43
|
-
}
|
|
44
|
-
else if (isSeq(current)) {
|
|
45
|
-
const idx = Number(seg);
|
|
46
|
-
if (!Number.isInteger(idx))
|
|
47
|
-
return null;
|
|
48
|
-
current = current.items[idx];
|
|
49
|
-
}
|
|
50
|
-
else {
|
|
51
|
-
return null;
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
return current ?? null;
|
|
55
|
-
}
|
|
56
|
-
function getKeyNodeAt(doc, parentSegments, key) {
|
|
57
|
-
const parent = parentSegments.length === 0 ? doc.contents : getNodeAt(doc, parentSegments);
|
|
58
|
-
if (!parent || !isMap(parent))
|
|
59
|
-
return null;
|
|
60
|
-
const pair = parent.items.find((p) => isScalar(p.key) && String(p.key.value) === key);
|
|
61
|
-
return pair?.key ?? null;
|
|
62
|
-
}
|
|
63
|
-
function locateError(doc, lineCounter, err) {
|
|
64
|
-
const segments = instancePathToSegments(err.instancePath);
|
|
65
|
-
if (err.keyword === 'additionalProperties') {
|
|
66
|
-
const bad = err.params.additionalProperty;
|
|
67
|
-
if (bad) {
|
|
68
|
-
const keyNode = getKeyNodeAt(doc, segments, bad);
|
|
69
|
-
const range = keyNode?.range;
|
|
70
|
-
if (range) {
|
|
71
|
-
const pos = lineCounter.linePos(range[0]);
|
|
72
|
-
return { line: pos.line, col: pos.col };
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
if (err.keyword === 'required' || err.keyword === 'dependentRequired') {
|
|
77
|
-
const node = getNodeAt(doc, segments);
|
|
78
|
-
const range = node?.range;
|
|
79
|
-
if (range) {
|
|
80
|
-
const pos = lineCounter.linePos(range[0]);
|
|
81
|
-
return { line: pos.line, col: pos.col };
|
|
82
|
-
}
|
|
83
|
-
return { line: 1, col: 1 };
|
|
84
|
-
}
|
|
85
|
-
const node = getNodeAt(doc, segments);
|
|
86
|
-
const range = node?.range;
|
|
87
|
-
if (!range)
|
|
88
|
-
return {};
|
|
89
|
-
const pos = lineCounter.linePos(range[0]);
|
|
90
|
-
return { line: pos.line, col: pos.col };
|
|
91
|
-
}
|
|
92
|
-
function humanMessage(err) {
|
|
93
|
-
const path = err.instancePath || '(root)';
|
|
94
|
-
switch (err.keyword) {
|
|
95
|
-
case 'required':
|
|
96
|
-
return `missing required property "${err.params.missingProperty}"`;
|
|
97
|
-
case 'additionalProperties':
|
|
98
|
-
return `unknown property "${err.params.additionalProperty}"`;
|
|
99
|
-
case 'dependentRequired': {
|
|
100
|
-
const { property, missingProperty } = err.params;
|
|
101
|
-
const parent = path === '(root)' ? '' : `${path}: `;
|
|
102
|
-
return `${parent}when "${property}" is set, "${missingProperty}" is also required`;
|
|
103
|
-
}
|
|
104
|
-
case 'pattern':
|
|
105
|
-
return `${path} does not match pattern ${err.params.pattern}`;
|
|
106
|
-
case 'const':
|
|
107
|
-
return `${path} must be exactly ${JSON.stringify(err.params.allowedValue)}`;
|
|
108
|
-
case 'enum':
|
|
109
|
-
return `${path} must be one of ${JSON.stringify(err.params.allowedValues)}`;
|
|
110
|
-
case 'type':
|
|
111
|
-
return `${path} must be ${err.params.type}`;
|
|
112
|
-
case 'not':
|
|
113
|
-
return `${path} is not allowed here`;
|
|
114
|
-
default:
|
|
115
|
-
return `${path} ${err.message ?? 'is invalid'}`;
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
function hintFor(err) {
|
|
119
|
-
if (err.keyword === 'pattern' && err.instancePath.startsWith('/aliases/')) {
|
|
120
|
-
return 'paste the deviceId from `switchbot devices list --format=tsv`, e.g. 01-202407090924-26354212';
|
|
121
|
-
}
|
|
122
|
-
if (err.keyword === 'not' && err.instancePath.startsWith('/confirmations/never_confirm/')) {
|
|
123
|
-
return 'destructive actions (lock/unlock/delete*/factoryReset) cannot be pre-approved in policy.yaml';
|
|
124
|
-
}
|
|
125
|
-
if (err.keyword === 'const' && err.instancePath === '/version') {
|
|
126
|
-
const supported = SUPPORTED_POLICY_SCHEMA_VERSIONS.map((v) => `"${v}"`).join(' / ');
|
|
127
|
-
return `this CLI supports policy schema versions ${supported}; run \`switchbot policy migrate\` to upgrade an older file`;
|
|
128
|
-
}
|
|
129
|
-
if (err.keyword === 'required' && err.instancePath === '') {
|
|
130
|
-
const missing = err.params.missingProperty;
|
|
131
|
-
if (missing === 'version')
|
|
132
|
-
return `add \`version: "${CURRENT_POLICY_SCHEMA_VERSION}"\` at the top of the file`;
|
|
133
|
-
}
|
|
134
|
-
return undefined;
|
|
135
|
-
}
|
|
136
|
-
function readDeclaredVersion(data) {
|
|
137
|
-
if (data && typeof data === 'object' && 'version' in data) {
|
|
138
|
-
const v = data.version;
|
|
139
|
-
if (typeof v === 'string')
|
|
140
|
-
return v;
|
|
141
|
-
}
|
|
142
|
-
return undefined;
|
|
143
|
-
}
|
|
144
|
-
function unsupportedVersionResult(loaded, declared) {
|
|
145
|
-
const supported = SUPPORTED_POLICY_SCHEMA_VERSIONS.map((v) => `"${v}"`).join(' / ');
|
|
146
|
-
const isLegacy = declared === '0.1';
|
|
147
|
-
const hint = isLegacy
|
|
148
|
-
? `v0.1 policy support was removed in v3.0. Run \`switchbot policy migrate\` with CLI ≤2.15 first, then upgrade.`
|
|
149
|
-
: `supported versions: ${supported}. upgrade the CLI or downgrade the file.`;
|
|
150
|
-
return {
|
|
151
|
-
policyPath: loaded.path,
|
|
152
|
-
schemaVersion: CURRENT_POLICY_SCHEMA_VERSION,
|
|
153
|
-
valid: false,
|
|
154
|
-
errors: [
|
|
155
|
-
{
|
|
156
|
-
path: '/version',
|
|
157
|
-
line: 1,
|
|
158
|
-
col: 1,
|
|
159
|
-
keyword: 'unsupported-version',
|
|
160
|
-
message: `policy schema version "${declared}" is not supported by this CLI`,
|
|
161
|
-
hint,
|
|
162
|
-
schemaPath: '#/properties/version',
|
|
163
|
-
},
|
|
164
|
-
],
|
|
165
|
-
};
|
|
166
|
-
}
|
|
167
|
-
/**
|
|
168
|
-
* Walk `automation.rules[].then[]` and flag any command string whose verb
|
|
169
|
-
* appears in DESTRUCTIVE_COMMANDS. Uses the YAML doc (not the data tree) to
|
|
170
|
-
* get accurate line/col on the offending node.
|
|
171
|
-
*
|
|
172
|
-
* This is deliberately a post-ajv pass rather than a schema rule because
|
|
173
|
-
* JSON Schema cannot parse a command string and compare the verb slot to a
|
|
174
|
-
* blocklist. Keeping it in JS also lets `src/rules/destructive.ts` be the
|
|
175
|
-
* single source of truth shared with the runtime executor.
|
|
176
|
-
*/
|
|
177
|
-
function collectDestructiveRuleErrors(loaded) {
|
|
178
|
-
const data = loaded.data;
|
|
179
|
-
const rules = data?.automation?.rules;
|
|
180
|
-
if (!Array.isArray(rules))
|
|
181
|
-
return [];
|
|
182
|
-
const out = [];
|
|
183
|
-
for (let ri = 0; ri < rules.length; ri++) {
|
|
184
|
-
const rule = rules[ri];
|
|
185
|
-
const actions = Array.isArray(rule?.then) ? rule.then : [];
|
|
186
|
-
for (let ai = 0; ai < actions.length; ai++) {
|
|
187
|
-
const cmd = actions[ai]?.command;
|
|
188
|
-
if (typeof cmd !== 'string')
|
|
189
|
-
continue;
|
|
190
|
-
const verb = destructiveVerbOf(cmd);
|
|
191
|
-
if (!verb)
|
|
192
|
-
continue;
|
|
193
|
-
const instancePath = `/automation/rules/${ri}/then/${ai}/command`;
|
|
194
|
-
const segments = instancePath.slice(1).split('/');
|
|
195
|
-
const node = getNodeAt(loaded.doc, segments);
|
|
196
|
-
const range = node?.range;
|
|
197
|
-
let line;
|
|
198
|
-
let col;
|
|
199
|
-
if (range) {
|
|
200
|
-
const pos = loaded.lineCounter.linePos(range[0]);
|
|
201
|
-
line = pos.line;
|
|
202
|
-
col = pos.col;
|
|
203
|
-
}
|
|
204
|
-
const ruleName = typeof rule?.name === 'string' ? rule.name : `#${ri}`;
|
|
205
|
-
out.push({
|
|
206
|
-
path: instancePath,
|
|
207
|
-
line,
|
|
208
|
-
col,
|
|
209
|
-
keyword: 'rule-destructive-action',
|
|
210
|
-
message: `rule "${ruleName}" action #${ai} uses destructive command "${verb}"`,
|
|
211
|
-
hint: `destructive verbs (${DESTRUCTIVE_COMMANDS.join(', ')}) cannot be pre-approved in automation rules; run them via the interactive CLI so the confirmation gate fires`,
|
|
212
|
-
schemaPath: '#/properties/automation/properties/rules/items/properties/then/items/properties/command',
|
|
213
|
-
});
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
return out;
|
|
217
|
-
}
|
|
218
|
-
export function validateLoadedPolicy(loaded) {
|
|
219
|
-
const declared = readDeclaredVersion(loaded.data);
|
|
220
|
-
if (declared !== undefined && !isSupportedPolicySchemaVersion(declared)) {
|
|
221
|
-
return unsupportedVersionResult(loaded, declared);
|
|
222
|
-
}
|
|
223
|
-
const version = isSupportedPolicySchemaVersion(declared)
|
|
224
|
-
? declared
|
|
225
|
-
: CURRENT_POLICY_SCHEMA_VERSION;
|
|
226
|
-
const { validate } = getValidator(version);
|
|
227
|
-
const ok = validate(loaded.data);
|
|
228
|
-
const errors = [];
|
|
229
|
-
if (!ok && validate.errors) {
|
|
230
|
-
for (const err of validate.errors) {
|
|
231
|
-
const { line, col } = locateError(loaded.doc, loaded.lineCounter, err);
|
|
232
|
-
errors.push({
|
|
233
|
-
path: err.instancePath || '',
|
|
234
|
-
line,
|
|
235
|
-
col,
|
|
236
|
-
keyword: err.keyword,
|
|
237
|
-
message: humanMessage(err),
|
|
238
|
-
hint: hintFor(err),
|
|
239
|
-
schemaPath: err.schemaPath,
|
|
240
|
-
});
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
// v0.2-only post-hook: destructive verbs like `unlock` / `factoryReset`
|
|
244
|
-
// cannot be pre-approved via rules, even if ajv considers the command
|
|
245
|
-
// string well-formed. Schema can't express this because `command` is a
|
|
246
|
-
// free-form string; we parse the verb in JS and append errors.
|
|
247
|
-
if (version === '0.2') {
|
|
248
|
-
const ruleErrors = collectDestructiveRuleErrors(loaded);
|
|
249
|
-
errors.push(...ruleErrors);
|
|
250
|
-
}
|
|
251
|
-
const valid = ok === true && errors.length === 0;
|
|
252
|
-
return {
|
|
253
|
-
policyPath: loaded.path,
|
|
254
|
-
schemaVersion: version,
|
|
255
|
-
valid,
|
|
256
|
-
errors,
|
|
257
|
-
};
|
|
258
|
-
}
|
|
259
|
-
export function validatePolicyFile(policyPath) {
|
|
260
|
-
const loaded = loadPolicyFile(policyPath);
|
|
261
|
-
return validateLoadedPolicy(loaded);
|
|
262
|
-
}
|
|
263
|
-
//# sourceMappingURL=validate.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/policy/validate.ts"],"names":[],"mappings":"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"}
|
package/dist/rules/action.d.ts
DELETED
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Rule action executor — the only place that calls into `executeCommand`
|
|
3
|
-
* from the rules pipeline.
|
|
4
|
-
*
|
|
5
|
-
* Responsibilities:
|
|
6
|
-
* 1. Parse the `command` string into a `{ deviceId, verb, parameter }`
|
|
7
|
-
* tuple, rejecting shapes the PoC doesn't understand.
|
|
8
|
-
* 2. Enforce the destructive-command blocklist as a second line of
|
|
9
|
-
* defence (the validator should have caught it at load time — this
|
|
10
|
-
* protects against hand-crafted engine inputs).
|
|
11
|
-
* 3. Resolve `action.device` (alias or deviceId) into the `<id>`
|
|
12
|
-
* slot.
|
|
13
|
-
* 4. Branch on `dry_run`: dry-run writes audit with kind
|
|
14
|
-
* `rule-fire-dry` and returns without touching the API.
|
|
15
|
-
* 5. Live run delegates to `executeCommand`, then re-writes audit
|
|
16
|
-
* with the rule-scoped kind + fireId so `rules tail` / `replay`
|
|
17
|
-
* can correlate multi-action fires.
|
|
18
|
-
*/
|
|
19
|
-
import type { AxiosInstance } from 'axios';
|
|
20
|
-
import type { Action, Rule } from './types.js';
|
|
21
|
-
export interface RuleActionContext {
|
|
22
|
-
/** Rule the action belongs to — used for audit correlation. */
|
|
23
|
-
rule: Rule;
|
|
24
|
-
/** UUID correlating every audit line of one trigger fire. */
|
|
25
|
-
fireId: string;
|
|
26
|
-
/** Policy-level aliases: friendly name → deviceId. */
|
|
27
|
-
aliases: Record<string, string>;
|
|
28
|
-
/** Optional axios client (prod path); omit in tests. */
|
|
29
|
-
httpClient?: AxiosInstance;
|
|
30
|
-
/** Global dry-run override (from `switchbot rules run --dry-run`). */
|
|
31
|
-
globalDryRun?: boolean;
|
|
32
|
-
/** When true, do not actually call `executeCommand` even if live.
|
|
33
|
-
* Exposed separately from `globalDryRun` so tests can exercise the
|
|
34
|
-
* "would call executeCommand" branch without mocking axios. */
|
|
35
|
-
skipApiCall?: boolean;
|
|
36
|
-
}
|
|
37
|
-
export interface RuleActionResult {
|
|
38
|
-
ok: boolean;
|
|
39
|
-
deviceId?: string;
|
|
40
|
-
verb?: string;
|
|
41
|
-
error?: string;
|
|
42
|
-
/** True when the action was refused for safety (destructive verb). */
|
|
43
|
-
blocked?: boolean;
|
|
44
|
-
/** True when the action wrote a dry-run audit instead of calling the API. */
|
|
45
|
-
dryRun?: boolean;
|
|
46
|
-
}
|
|
47
|
-
interface ParsedCommand {
|
|
48
|
-
deviceIdSlot: string | null;
|
|
49
|
-
verb: string;
|
|
50
|
-
parameterTokens: string[];
|
|
51
|
-
}
|
|
52
|
-
export declare function parseRuleCommand(cmd: string): ParsedCommand | null;
|
|
53
|
-
/** Alias-first resolver — falls back to the raw value (assumed deviceId). */
|
|
54
|
-
export declare function resolveActionDevice(explicit: string | undefined, slot: string | null, aliases: Record<string, string>): string | null;
|
|
55
|
-
export declare function executeRuleAction(action: Action, ctx: RuleActionContext): Promise<RuleActionResult>;
|
|
56
|
-
/**
|
|
57
|
-
* Extract the raw deviceId from an action object without alias resolution.
|
|
58
|
-
* Prefers `action.device` over the deviceId embedded in the command string.
|
|
59
|
-
* Use resolveActionDevice() when alias resolution is needed.
|
|
60
|
-
*/
|
|
61
|
-
export declare function extractDeviceIdFromAction(action: {
|
|
62
|
-
command: string;
|
|
63
|
-
device?: string;
|
|
64
|
-
}): string | null;
|
|
65
|
-
export {};
|
package/dist/rules/action.js
DELETED
|
@@ -1,217 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Rule action executor — the only place that calls into `executeCommand`
|
|
3
|
-
* from the rules pipeline.
|
|
4
|
-
*
|
|
5
|
-
* Responsibilities:
|
|
6
|
-
* 1. Parse the `command` string into a `{ deviceId, verb, parameter }`
|
|
7
|
-
* tuple, rejecting shapes the PoC doesn't understand.
|
|
8
|
-
* 2. Enforce the destructive-command blocklist as a second line of
|
|
9
|
-
* defence (the validator should have caught it at load time — this
|
|
10
|
-
* protects against hand-crafted engine inputs).
|
|
11
|
-
* 3. Resolve `action.device` (alias or deviceId) into the `<id>`
|
|
12
|
-
* slot.
|
|
13
|
-
* 4. Branch on `dry_run`: dry-run writes audit with kind
|
|
14
|
-
* `rule-fire-dry` and returns without touching the API.
|
|
15
|
-
* 5. Live run delegates to `executeCommand`, then re-writes audit
|
|
16
|
-
* with the rule-scoped kind + fireId so `rules tail` / `replay`
|
|
17
|
-
* can correlate multi-action fires.
|
|
18
|
-
*/
|
|
19
|
-
import { executeCommand } from '../lib/devices.js';
|
|
20
|
-
import { writeAudit } from '../utils/audit.js';
|
|
21
|
-
import { isDestructiveCommand } from './destructive.js';
|
|
22
|
-
const DEVICES_COMMAND_RE = /^devices\s+command\s+(\S+)\s+(\S+)(?:\s+(.*))?$/;
|
|
23
|
-
export function parseRuleCommand(cmd) {
|
|
24
|
-
const m = DEVICES_COMMAND_RE.exec(cmd.trim());
|
|
25
|
-
if (!m)
|
|
26
|
-
return null;
|
|
27
|
-
const deviceIdSlot = m[1];
|
|
28
|
-
const verb = m[2];
|
|
29
|
-
const rest = (m[3] ?? '').trim();
|
|
30
|
-
return {
|
|
31
|
-
deviceIdSlot,
|
|
32
|
-
verb,
|
|
33
|
-
parameterTokens: rest.length === 0 ? [] : rest.split(/\s+/),
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
/** Alias-first resolver — falls back to the raw value (assumed deviceId). */
|
|
37
|
-
export function resolveActionDevice(explicit, slot, aliases) {
|
|
38
|
-
// Explicit device field on the action wins.
|
|
39
|
-
const candidate = explicit ?? (slot && slot !== '<id>' ? slot : null);
|
|
40
|
-
if (!candidate)
|
|
41
|
-
return null;
|
|
42
|
-
if (aliases[candidate])
|
|
43
|
-
return aliases[candidate];
|
|
44
|
-
return candidate;
|
|
45
|
-
}
|
|
46
|
-
/**
|
|
47
|
-
* Render a parameter for SwitchBot's command API. For the PoC we pass
|
|
48
|
-
* the raw token string for single-token args, join with `:` for
|
|
49
|
-
* multi-token args (matches the CLI's `devices command` convention),
|
|
50
|
-
* and `undefined` when no tokens were supplied (the SDK substitutes
|
|
51
|
-
* `'default'`).
|
|
52
|
-
*/
|
|
53
|
-
function renderParameter(tokens) {
|
|
54
|
-
if (tokens.length === 0)
|
|
55
|
-
return undefined;
|
|
56
|
-
if (tokens.length === 1)
|
|
57
|
-
return tokens[0];
|
|
58
|
-
return tokens.join(':');
|
|
59
|
-
}
|
|
60
|
-
export async function executeRuleAction(action, ctx) {
|
|
61
|
-
const parsed = parseRuleCommand(action.command);
|
|
62
|
-
if (!parsed) {
|
|
63
|
-
writeAudit({
|
|
64
|
-
t: new Date().toISOString(),
|
|
65
|
-
kind: 'rule-fire',
|
|
66
|
-
deviceId: 'unknown',
|
|
67
|
-
command: action.command,
|
|
68
|
-
parameter: null,
|
|
69
|
-
commandType: 'command',
|
|
70
|
-
dryRun: true,
|
|
71
|
-
result: 'error',
|
|
72
|
-
error: 'unparseable-command',
|
|
73
|
-
rule: {
|
|
74
|
-
name: ctx.rule.name,
|
|
75
|
-
triggerSource: ctx.rule.when.source,
|
|
76
|
-
fireId: ctx.fireId,
|
|
77
|
-
reason: 'unparseable-command',
|
|
78
|
-
},
|
|
79
|
-
});
|
|
80
|
-
return { ok: false, error: 'unparseable-command', blocked: true };
|
|
81
|
-
}
|
|
82
|
-
if (isDestructiveCommand(action.command)) {
|
|
83
|
-
writeAudit({
|
|
84
|
-
t: new Date().toISOString(),
|
|
85
|
-
kind: 'rule-fire',
|
|
86
|
-
deviceId: resolveActionDevice(action.device, parsed.deviceIdSlot, ctx.aliases) ?? 'unknown',
|
|
87
|
-
command: action.command,
|
|
88
|
-
parameter: null,
|
|
89
|
-
commandType: 'command',
|
|
90
|
-
dryRun: true,
|
|
91
|
-
result: 'error',
|
|
92
|
-
error: `destructive-verb:${parsed.verb}`,
|
|
93
|
-
rule: {
|
|
94
|
-
name: ctx.rule.name,
|
|
95
|
-
triggerSource: ctx.rule.when.source,
|
|
96
|
-
fireId: ctx.fireId,
|
|
97
|
-
reason: `destructive verb "${parsed.verb}" refused at runtime`,
|
|
98
|
-
},
|
|
99
|
-
});
|
|
100
|
-
return { ok: false, error: `destructive-verb:${parsed.verb}`, blocked: true, verb: parsed.verb };
|
|
101
|
-
}
|
|
102
|
-
const deviceId = resolveActionDevice(action.device, parsed.deviceIdSlot, ctx.aliases);
|
|
103
|
-
if (!deviceId || deviceId === '<id>') {
|
|
104
|
-
writeAudit({
|
|
105
|
-
t: new Date().toISOString(),
|
|
106
|
-
kind: 'rule-fire',
|
|
107
|
-
deviceId: 'unknown',
|
|
108
|
-
command: action.command,
|
|
109
|
-
parameter: null,
|
|
110
|
-
commandType: 'command',
|
|
111
|
-
dryRun: true,
|
|
112
|
-
result: 'error',
|
|
113
|
-
error: 'missing-device',
|
|
114
|
-
rule: {
|
|
115
|
-
name: ctx.rule.name,
|
|
116
|
-
triggerSource: ctx.rule.when.source,
|
|
117
|
-
fireId: ctx.fireId,
|
|
118
|
-
reason: 'action omitted `device` and command used `<id>` placeholder',
|
|
119
|
-
},
|
|
120
|
-
});
|
|
121
|
-
return { ok: false, error: 'missing-device', verb: parsed.verb };
|
|
122
|
-
}
|
|
123
|
-
const dryRun = ctx.globalDryRun === true || ctx.rule.dry_run === true;
|
|
124
|
-
const parameter = renderParameter(parsed.parameterTokens);
|
|
125
|
-
if (dryRun) {
|
|
126
|
-
writeAudit({
|
|
127
|
-
t: new Date().toISOString(),
|
|
128
|
-
kind: 'rule-fire-dry',
|
|
129
|
-
deviceId,
|
|
130
|
-
command: parsed.verb,
|
|
131
|
-
parameter: parameter ?? 'default',
|
|
132
|
-
commandType: 'command',
|
|
133
|
-
dryRun: true,
|
|
134
|
-
result: 'ok',
|
|
135
|
-
rule: {
|
|
136
|
-
name: ctx.rule.name,
|
|
137
|
-
triggerSource: ctx.rule.when.source,
|
|
138
|
-
matchedDevice: deviceId,
|
|
139
|
-
fireId: ctx.fireId,
|
|
140
|
-
},
|
|
141
|
-
});
|
|
142
|
-
return { ok: true, dryRun: true, deviceId, verb: parsed.verb };
|
|
143
|
-
}
|
|
144
|
-
if (ctx.skipApiCall) {
|
|
145
|
-
writeAudit({
|
|
146
|
-
t: new Date().toISOString(),
|
|
147
|
-
kind: 'rule-fire',
|
|
148
|
-
deviceId,
|
|
149
|
-
command: parsed.verb,
|
|
150
|
-
parameter: parameter ?? 'default',
|
|
151
|
-
commandType: 'command',
|
|
152
|
-
dryRun: false,
|
|
153
|
-
result: 'ok',
|
|
154
|
-
rule: {
|
|
155
|
-
name: ctx.rule.name,
|
|
156
|
-
triggerSource: ctx.rule.when.source,
|
|
157
|
-
matchedDevice: deviceId,
|
|
158
|
-
fireId: ctx.fireId,
|
|
159
|
-
reason: 'api-skipped',
|
|
160
|
-
},
|
|
161
|
-
});
|
|
162
|
-
return { ok: true, deviceId, verb: parsed.verb };
|
|
163
|
-
}
|
|
164
|
-
try {
|
|
165
|
-
await executeCommand(deviceId, parsed.verb, parameter, 'command', ctx.httpClient);
|
|
166
|
-
writeAudit({
|
|
167
|
-
t: new Date().toISOString(),
|
|
168
|
-
kind: 'rule-fire',
|
|
169
|
-
deviceId,
|
|
170
|
-
command: parsed.verb,
|
|
171
|
-
parameter: parameter ?? 'default',
|
|
172
|
-
commandType: 'command',
|
|
173
|
-
dryRun: false,
|
|
174
|
-
result: 'ok',
|
|
175
|
-
rule: {
|
|
176
|
-
name: ctx.rule.name,
|
|
177
|
-
triggerSource: ctx.rule.when.source,
|
|
178
|
-
matchedDevice: deviceId,
|
|
179
|
-
fireId: ctx.fireId,
|
|
180
|
-
},
|
|
181
|
-
});
|
|
182
|
-
return { ok: true, deviceId, verb: parsed.verb };
|
|
183
|
-
}
|
|
184
|
-
catch (err) {
|
|
185
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
186
|
-
writeAudit({
|
|
187
|
-
t: new Date().toISOString(),
|
|
188
|
-
kind: 'rule-fire',
|
|
189
|
-
deviceId,
|
|
190
|
-
command: parsed.verb,
|
|
191
|
-
parameter: parameter ?? 'default',
|
|
192
|
-
commandType: 'command',
|
|
193
|
-
dryRun: false,
|
|
194
|
-
result: 'error',
|
|
195
|
-
error: msg,
|
|
196
|
-
rule: {
|
|
197
|
-
name: ctx.rule.name,
|
|
198
|
-
triggerSource: ctx.rule.when.source,
|
|
199
|
-
matchedDevice: deviceId,
|
|
200
|
-
fireId: ctx.fireId,
|
|
201
|
-
},
|
|
202
|
-
});
|
|
203
|
-
return { ok: false, error: msg, deviceId, verb: parsed.verb };
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
/**
|
|
207
|
-
* Extract the raw deviceId from an action object without alias resolution.
|
|
208
|
-
* Prefers `action.device` over the deviceId embedded in the command string.
|
|
209
|
-
* Use resolveActionDevice() when alias resolution is needed.
|
|
210
|
-
*/
|
|
211
|
-
export function extractDeviceIdFromAction(action) {
|
|
212
|
-
if (action.device)
|
|
213
|
-
return action.device;
|
|
214
|
-
const m = /\bdevices\s+command\s+(\S+)/.exec(action.command ?? '');
|
|
215
|
-
return m ? m[1] : null;
|
|
216
|
-
}
|
|
217
|
-
//# sourceMappingURL=action.js.map
|
package/dist/rules/action.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"action.js","sourceRoot":"","sources":["../../src/rules/action.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Shared filters + aggregations over the audit log for
|
|
3
|
-
* `switchbot rules tail` and `switchbot rules replay`.
|
|
4
|
-
*
|
|
5
|
-
* All functions are pure — no I/O, no clock reads — so they can be
|
|
6
|
-
* unit-tested with fixture arrays. The CLI entry points handle file
|
|
7
|
-
* reading, `--follow` tailing, and human vs JSON rendering.
|
|
8
|
-
*/
|
|
9
|
-
import type { AuditEntry, AuditEntryKind } from '../utils/audit.js';
|
|
10
|
-
/** The subset of audit kinds the rules engine emits. */
|
|
11
|
-
export declare const RULE_AUDIT_KINDS: readonly AuditEntryKind[];
|
|
12
|
-
export interface RuleAuditFilter {
|
|
13
|
-
/** Filter entries with `t >= sinceMs`. Unbounded when undefined. */
|
|
14
|
-
sinceMs?: number;
|
|
15
|
-
/** Filter to a single rule name (matched against entry.rule?.name). */
|
|
16
|
-
ruleName?: string;
|
|
17
|
-
/** Only these kinds are returned. Defaults to RULE_AUDIT_KINDS. */
|
|
18
|
-
kinds?: readonly AuditEntryKind[];
|
|
19
|
-
}
|
|
20
|
-
/** Keep entries that are rule-engine emitted and match the filter. */
|
|
21
|
-
export declare function filterRuleAudits(entries: readonly AuditEntry[], filter?: RuleAuditFilter): AuditEntry[];
|
|
22
|
-
export interface RuleSummary {
|
|
23
|
-
/** Rule name as recorded in the audit entry. */
|
|
24
|
-
rule: string;
|
|
25
|
-
/** Number of real (non-dry) fires. */
|
|
26
|
-
fires: number;
|
|
27
|
-
/** Number of dry fires. */
|
|
28
|
-
driesFires: number;
|
|
29
|
-
/** Number of throttled skips. */
|
|
30
|
-
throttled: number;
|
|
31
|
-
/** Number of entries whose `result === 'error'`. */
|
|
32
|
-
errors: number;
|
|
33
|
-
/** fires where result === 'ok' divided by fires + driesFires + errors fired. */
|
|
34
|
-
errorRate: number;
|
|
35
|
-
/** Earliest timestamp observed for this rule (ISO). */
|
|
36
|
-
firstAt: string | null;
|
|
37
|
-
/** Latest timestamp observed for this rule (ISO). */
|
|
38
|
-
lastAt: string | null;
|
|
39
|
-
/** Trigger source observed — 'mixed' if the same rule name spans sources. */
|
|
40
|
-
triggerSource: 'mqtt' | 'cron' | 'webhook' | 'mixed' | null;
|
|
41
|
-
}
|
|
42
|
-
export interface ReplayReport {
|
|
43
|
-
/** Total entries (after filter) considered. */
|
|
44
|
-
total: number;
|
|
45
|
-
/** Per-rule summaries, sorted by `fires + driesFires` descending. */
|
|
46
|
-
summaries: RuleSummary[];
|
|
47
|
-
/** Count of rule-webhook-rejected entries with no rule name. */
|
|
48
|
-
webhookRejectedCount: number;
|
|
49
|
-
}
|
|
50
|
-
/** Aggregate a filtered stream into per-rule counters. */
|
|
51
|
-
export declare function aggregateRuleAudits(entries: readonly AuditEntry[]): ReplayReport;
|