@switchbot/openapi-cli 3.1.1 → 3.2.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.
Files changed (113) hide show
  1. package/README.md +3 -3
  2. package/dist/index.js +56945 -169
  3. package/dist/policy/schema/v0.2.json +1 -1
  4. package/package.json +3 -2
  5. package/dist/api/client.js +0 -235
  6. package/dist/auth.js +0 -20
  7. package/dist/commands/agent-bootstrap.js +0 -182
  8. package/dist/commands/auth.js +0 -354
  9. package/dist/commands/batch.js +0 -413
  10. package/dist/commands/cache.js +0 -126
  11. package/dist/commands/capabilities.js +0 -385
  12. package/dist/commands/catalog.js +0 -359
  13. package/dist/commands/completion.js +0 -385
  14. package/dist/commands/config.js +0 -376
  15. package/dist/commands/daemon.js +0 -410
  16. package/dist/commands/device-meta.js +0 -159
  17. package/dist/commands/devices.js +0 -948
  18. package/dist/commands/doctor.js +0 -1015
  19. package/dist/commands/events.js +0 -563
  20. package/dist/commands/expand.js +0 -130
  21. package/dist/commands/explain.js +0 -139
  22. package/dist/commands/health.js +0 -113
  23. package/dist/commands/history.js +0 -320
  24. package/dist/commands/identity.js +0 -59
  25. package/dist/commands/install.js +0 -246
  26. package/dist/commands/mcp.js +0 -2017
  27. package/dist/commands/plan.js +0 -653
  28. package/dist/commands/policy.js +0 -586
  29. package/dist/commands/quota.js +0 -78
  30. package/dist/commands/rules.js +0 -875
  31. package/dist/commands/scenes.js +0 -264
  32. package/dist/commands/schema.js +0 -177
  33. package/dist/commands/status-sync.js +0 -131
  34. package/dist/commands/uninstall.js +0 -237
  35. package/dist/commands/upgrade-check.js +0 -107
  36. package/dist/commands/watch.js +0 -194
  37. package/dist/commands/webhook.js +0 -182
  38. package/dist/config.js +0 -258
  39. package/dist/credentials/backends/file.js +0 -101
  40. package/dist/credentials/backends/linux.js +0 -129
  41. package/dist/credentials/backends/macos.js +0 -129
  42. package/dist/credentials/backends/windows.js +0 -215
  43. package/dist/credentials/keychain.js +0 -88
  44. package/dist/credentials/prime.js +0 -52
  45. package/dist/devices/cache.js +0 -293
  46. package/dist/devices/catalog.js +0 -767
  47. package/dist/devices/device-meta.js +0 -56
  48. package/dist/devices/history-agg.js +0 -138
  49. package/dist/devices/history-query.js +0 -181
  50. package/dist/devices/param-validator.js +0 -433
  51. package/dist/devices/resources.js +0 -270
  52. package/dist/install/default-steps.js +0 -257
  53. package/dist/install/preflight.js +0 -212
  54. package/dist/install/steps.js +0 -67
  55. package/dist/lib/command-keywords.js +0 -17
  56. package/dist/lib/daemon-state.js +0 -46
  57. package/dist/lib/destructive-mode.js +0 -12
  58. package/dist/lib/devices.js +0 -382
  59. package/dist/lib/idempotency.js +0 -106
  60. package/dist/lib/plan-store.js +0 -68
  61. package/dist/lib/request-context.js +0 -12
  62. package/dist/lib/scenes.js +0 -10
  63. package/dist/logger.js +0 -16
  64. package/dist/mcp/device-history.js +0 -145
  65. package/dist/mcp/events-subscription.js +0 -213
  66. package/dist/mqtt/client.js +0 -180
  67. package/dist/mqtt/credential.js +0 -30
  68. package/dist/policy/add-rule.js +0 -124
  69. package/dist/policy/diff.js +0 -91
  70. package/dist/policy/format.js +0 -57
  71. package/dist/policy/load.js +0 -61
  72. package/dist/policy/migrate.js +0 -67
  73. package/dist/policy/schema.js +0 -18
  74. package/dist/policy/validate.js +0 -262
  75. package/dist/rules/action.js +0 -216
  76. package/dist/rules/audit-query.js +0 -89
  77. package/dist/rules/conflict-analyzer.js +0 -214
  78. package/dist/rules/cron-scheduler.js +0 -186
  79. package/dist/rules/destructive.js +0 -52
  80. package/dist/rules/engine.js +0 -757
  81. package/dist/rules/matcher.js +0 -230
  82. package/dist/rules/pid-file.js +0 -95
  83. package/dist/rules/quiet-hours.js +0 -45
  84. package/dist/rules/suggest.js +0 -95
  85. package/dist/rules/throttle.js +0 -116
  86. package/dist/rules/types.js +0 -34
  87. package/dist/rules/webhook-listener.js +0 -223
  88. package/dist/rules/webhook-token.js +0 -90
  89. package/dist/schema/field-aliases.js +0 -131
  90. package/dist/sinks/dispatcher.js +0 -12
  91. package/dist/sinks/file.js +0 -19
  92. package/dist/sinks/format.js +0 -56
  93. package/dist/sinks/homeassistant.js +0 -44
  94. package/dist/sinks/openclaw.js +0 -33
  95. package/dist/sinks/stdout.js +0 -5
  96. package/dist/sinks/telegram.js +0 -28
  97. package/dist/sinks/types.js +0 -1
  98. package/dist/sinks/webhook.js +0 -22
  99. package/dist/status-sync/manager.js +0 -268
  100. package/dist/utils/arg-parsers.js +0 -66
  101. package/dist/utils/audit.js +0 -121
  102. package/dist/utils/filter.js +0 -189
  103. package/dist/utils/flags.js +0 -186
  104. package/dist/utils/format.js +0 -117
  105. package/dist/utils/health.js +0 -101
  106. package/dist/utils/help-json.js +0 -54
  107. package/dist/utils/name-resolver.js +0 -137
  108. package/dist/utils/output.js +0 -404
  109. package/dist/utils/quota.js +0 -227
  110. package/dist/utils/redact.js +0 -68
  111. package/dist/utils/retry.js +0 -140
  112. package/dist/utils/string.js +0 -22
  113. package/dist/version.js +0 -4
@@ -1,186 +0,0 @@
1
- /**
2
- * Cron trigger scheduler for the rules engine.
3
- *
4
- * Each cron rule gets its own scheduler entry. On every tick the
5
- * scheduler synthesises an `EngineEvent` with `source: 'cron'` and hands
6
- * it to the same dispatch path the MQTT pipeline uses, so conditions,
7
- * throttle, and action execution behave identically regardless of
8
- * trigger source.
9
- *
10
- * Tests can drive the scheduler deterministically via `fireNowForTest()`
11
- * — the scheduler's internal timer still uses `setTimeout`, which means
12
- * `vi.useFakeTimers()` plus `vi.advanceTimersByTime()` also work. Croner
13
- * is used only for `nextRun(fromDate)` calculations; we own the
14
- * timer/dispatch loop so the engine can drain events through a single
15
- * serialised queue.
16
- */
17
- import { Cron } from 'croner';
18
- /** Maps JS getDay() (0=Sun) to 3-letter abbreviation. */
19
- const JS_DAY_TO_ABBR = ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat'];
20
- /** Expand a days[] entry to its canonical 3-letter abbr so comparisons are O(1). */
21
- function normaliseDay(d) {
22
- return d.toLowerCase().slice(0, 3);
23
- }
24
- /** Return true if `t` falls on one of the listed days (or days is absent/empty). */
25
- export function matchesDayFilter(days, t) {
26
- if (!days || days.length === 0)
27
- return true;
28
- const todayAbbr = JS_DAY_TO_ABBR[t.getDay()];
29
- return days.some((d) => normaliseDay(d) === todayAbbr);
30
- }
31
- export class CronScheduler {
32
- opts;
33
- entries = new Map();
34
- started = false;
35
- stopped = false;
36
- constructor(opts) {
37
- this.opts = opts;
38
- }
39
- getScheduledFor(ruleName) {
40
- const s = this.entries.get(ruleName);
41
- if (!s)
42
- return null;
43
- return { schedule: s.schedule, nextAt: s.nextAt };
44
- }
45
- hasRegistered(ruleName) {
46
- return this.entries.has(ruleName);
47
- }
48
- /**
49
- * Register a cron rule. Validates the pattern eagerly — an invalid
50
- * schedule throws synchronously so engine start can surface the error.
51
- */
52
- register(rule) {
53
- if (rule.when.source !== 'cron') {
54
- throw new Error(`CronScheduler.register called for non-cron rule "${rule.name}"`);
55
- }
56
- if (this.entries.has(rule.name)) {
57
- throw new Error(`CronScheduler: duplicate rule name "${rule.name}"`);
58
- }
59
- const schedule = rule.when.schedule;
60
- let pattern;
61
- try {
62
- pattern = new Cron(schedule, { paused: true });
63
- }
64
- catch (err) {
65
- throw new Error(`CronScheduler: invalid cron expression for rule "${rule.name}": ${schedule} (${err instanceof Error ? err.message : String(err)})`);
66
- }
67
- const entry = {
68
- rule,
69
- schedule,
70
- pattern,
71
- timer: null,
72
- nextAt: null,
73
- };
74
- this.entries.set(rule.name, entry);
75
- if (this.started && !this.stopped)
76
- this.arm(entry);
77
- }
78
- unregister(ruleName) {
79
- const e = this.entries.get(ruleName);
80
- if (!e)
81
- return;
82
- if (e.timer)
83
- clearTimeout(e.timer);
84
- try {
85
- e.pattern.stop();
86
- }
87
- catch {
88
- // croner throws when already stopped — ignore.
89
- }
90
- this.entries.delete(ruleName);
91
- }
92
- start() {
93
- if (this.stopped) {
94
- throw new Error('CronScheduler: cannot start after stop().');
95
- }
96
- if (this.started)
97
- return;
98
- this.started = true;
99
- for (const entry of this.entries.values())
100
- this.arm(entry);
101
- }
102
- stop() {
103
- if (this.stopped)
104
- return;
105
- this.stopped = true;
106
- this.started = false;
107
- for (const e of this.entries.values()) {
108
- if (e.timer)
109
- clearTimeout(e.timer);
110
- e.timer = null;
111
- try {
112
- e.pattern.stop();
113
- }
114
- catch {
115
- // ignore
116
- }
117
- }
118
- }
119
- /**
120
- * Test helper — compute the pattern's next run after a reference
121
- * timestamp without actually scheduling it. Handy for regression tests.
122
- */
123
- nextRunAfter(ruleName, after) {
124
- const e = this.entries.get(ruleName);
125
- if (!e)
126
- return null;
127
- return e.pattern.nextRun(after) ?? null;
128
- }
129
- /**
130
- * Test helper — fire a rule immediately, bypassing the timer. Used by
131
- * unit tests to skip vi.advanceTimersByTime logic when the focus is on
132
- * dispatch behaviour, not scheduling accuracy.
133
- */
134
- async fireNowForTest(ruleName) {
135
- const e = this.entries.get(ruleName);
136
- if (!e)
137
- throw new Error(`CronScheduler.fireNowForTest: no rule "${ruleName}"`);
138
- await this.fire(e);
139
- }
140
- nowDate() {
141
- return this.opts.now ? this.opts.now() : new Date();
142
- }
143
- arm(entry) {
144
- if (this.stopped)
145
- return;
146
- const now = this.nowDate();
147
- const next = entry.pattern.nextRun(now);
148
- if (!next) {
149
- entry.nextAt = null;
150
- return;
151
- }
152
- entry.nextAt = next;
153
- const delayMs = Math.max(0, next.getTime() - now.getTime());
154
- entry.timer = setTimeout(() => {
155
- entry.timer = null;
156
- // Fire and then re-arm, regardless of outcome — we never want one
157
- // misbehaving rule to kill its own future ticks.
158
- this.fire(entry)
159
- .catch(() => undefined)
160
- .finally(() => {
161
- if (!this.stopped && this.entries.has(entry.rule.name))
162
- this.arm(entry);
163
- });
164
- }, delayMs);
165
- // Unref so a process with only cron rules still exits on SIGINT when
166
- // the user expects (e.g. in integration tests).
167
- if (typeof entry.timer.unref === 'function') {
168
- entry.timer.unref();
169
- }
170
- }
171
- async fire(entry) {
172
- const when = this.nowDate();
173
- // Apply the optional day-of-week filter before dispatching.
174
- const trigger = entry.rule.when;
175
- if (trigger.source === 'cron' && !matchesDayFilter(trigger.days, when)) {
176
- return;
177
- }
178
- const event = {
179
- source: 'cron',
180
- event: entry.schedule,
181
- t: when,
182
- payload: { schedule: entry.schedule },
183
- };
184
- await this.opts.dispatch(entry.rule, event);
185
- }
186
- }
@@ -1,52 +0,0 @@
1
- /**
2
- * Destructive command parsing — single source of truth shared between the
3
- * policy validator post-hook (rejects destructive commands inside
4
- * `automation.rules[].then[].command`) and the runtime executor (second-
5
- * line guard that refuses to shell out even if validation was bypassed).
6
- */
7
- export const DESTRUCTIVE_COMMANDS = [
8
- 'lock',
9
- 'unlock',
10
- 'deleteWebhook',
11
- 'deleteScene',
12
- 'factoryReset',
13
- ];
14
- /**
15
- * Parse the verb out of a rule action command string. The expected form
16
- * mirrors what the engine will eventually build: `devices command <id> <verb> [args...]`.
17
- * We also accept scene shorthands (`scenes run <id>`, `webhooks delete <id>`).
18
- *
19
- * Returns null for anything we cannot confidently attribute to a known verb
20
- * slot — the validator treats null as "probably fine, let the engine's own
21
- * guard handle it if it's not."
22
- */
23
- export function extractVerb(cmd) {
24
- const trimmed = cmd.trim();
25
- if (!trimmed)
26
- return null;
27
- const tokens = trimmed.split(/\s+/);
28
- // `devices command <id> <verb> [args]`
29
- if (tokens[0] === 'devices' && tokens[1] === 'command' && tokens.length >= 4) {
30
- return tokens[3];
31
- }
32
- // `webhooks delete <id>` → verb is "deleteWebhook"
33
- if (tokens[0] === 'webhooks' && tokens[1] === 'delete')
34
- return 'deleteWebhook';
35
- // `scenes delete <id>` → verb is "deleteScene"
36
- if (tokens[0] === 'scenes' && tokens[1] === 'delete')
37
- return 'deleteScene';
38
- return null;
39
- }
40
- export function isDestructiveCommand(cmd) {
41
- const verb = extractVerb(cmd);
42
- if (!verb)
43
- return false;
44
- return DESTRUCTIVE_COMMANDS.includes(verb);
45
- }
46
- export function destructiveVerbOf(cmd) {
47
- const verb = extractVerb(cmd);
48
- if (verb && DESTRUCTIVE_COMMANDS.includes(verb)) {
49
- return verb;
50
- }
51
- return null;
52
- }