@shepherdjerred/home-assistant 0.1.0-dev.14474
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/CHANGELOG.md +8 -0
- package/LICENSE +674 -0
- package/README.md +126 -0
- package/demos/codegen-fixture.cast +40 -0
- package/demos/home-assistant-fixture.json +33 -0
- package/demos/record-codegen-demo.sh +119 -0
- package/dist/codegen/cli.d.ts +3 -0
- package/dist/codegen/cli.d.ts.map +1 -0
- package/dist/codegen/cli.js +118 -0
- package/dist/codegen/cli.js.map +1 -0
- package/dist/codegen/emit.d.ts +8 -0
- package/dist/codegen/emit.d.ts.map +1 -0
- package/dist/codegen/emit.js +143 -0
- package/dist/codegen/emit.js.map +1 -0
- package/dist/codegen/introspect.d.ts +193 -0
- package/dist/codegen/introspect.d.ts.map +1 -0
- package/dist/codegen/introspect.js +131 -0
- package/dist/codegen/introspect.js.map +1 -0
- package/dist/codegen/known-events.d.ts +10 -0
- package/dist/codegen/known-events.d.ts.map +1 -0
- package/dist/codegen/known-events.js +25 -0
- package/dist/codegen/known-events.js.map +1 -0
- package/dist/codegen/selector-to-ts.d.ts +15 -0
- package/dist/codegen/selector-to-ts.d.ts.map +1 -0
- package/dist/codegen/selector-to-ts.js +110 -0
- package/dist/codegen/selector-to-ts.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/rest/client.d.ts +34 -0
- package/dist/rest/client.d.ts.map +1 -0
- package/dist/rest/client.js +112 -0
- package/dist/rest/client.js.map +1 -0
- package/dist/rest/errors.d.ts +12 -0
- package/dist/rest/errors.d.ts.map +1 -0
- package/dist/rest/errors.js +23 -0
- package/dist/rest/errors.js.map +1 -0
- package/dist/rest/schemas.d.ts +124 -0
- package/dist/rest/schemas.d.ts.map +1 -0
- package/dist/rest/schemas.js +64 -0
- package/dist/rest/schemas.js.map +1 -0
- package/dist/schema/types.d.ts +138 -0
- package/dist/schema/types.d.ts.map +1 -0
- package/dist/schema/types.js +12 -0
- package/dist/schema/types.js.map +1 -0
- package/dist/shared/config.d.ts +6 -0
- package/dist/shared/config.d.ts.map +1 -0
- package/dist/shared/config.js +4 -0
- package/dist/shared/config.js.map +1 -0
- package/dist/ws/client.d.ts +58 -0
- package/dist/ws/client.d.ts.map +1 -0
- package/dist/ws/client.js +343 -0
- package/dist/ws/client.js.map +1 -0
- package/dist/ws/errors.d.ts +14 -0
- package/dist/ws/errors.d.ts.map +1 -0
- package/dist/ws/errors.js +27 -0
- package/dist/ws/errors.js.map +1 -0
- package/dist/ws/messages.d.ts +130 -0
- package/dist/ws/messages.d.ts.map +1 -0
- package/dist/ws/messages.js +79 -0
- package/dist/ws/messages.js.map +1 -0
- package/dist/ws/socket-helpers.d.ts +23 -0
- package/dist/ws/socket-helpers.d.ts.map +1 -0
- package/dist/ws/socket-helpers.js +73 -0
- package/dist/ws/socket-helpers.js.map +1 -0
- package/dist/ws/subscriptions.d.ts +37 -0
- package/dist/ws/subscriptions.d.ts.map +1 -0
- package/dist/ws/subscriptions.js +58 -0
- package/dist/ws/subscriptions.js.map +1 -0
- package/examples/basic-client.mjs +18 -0
- package/examples/codegen-fixture.mjs +95 -0
- package/package.json +69 -0
|
@@ -0,0 +1,343 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { EntityState as EntityStateSchema } from "../rest/schemas.js";
|
|
3
|
+
import { HaWebSocketAuthError, HaWebSocketClosedError, HaWebSocketError, HaWebSocketResultError, } from "./errors.js";
|
|
4
|
+
import { AuthMessage, EntityRegistryEntry, ServerMessage } from "./messages.js";
|
|
5
|
+
import { buildWsUrl, extractEventData, MessageDataString, wait, waitForFirstMessage, waitForOpen, } from "./socket-helpers.js";
|
|
6
|
+
import { SubscriptionRegistry } from "./subscriptions.js";
|
|
7
|
+
const DEFAULTS = {
|
|
8
|
+
initialReconnectDelayMs: 1000,
|
|
9
|
+
maxReconnectDelayMs: 30_000,
|
|
10
|
+
pingIntervalMs: 30_000,
|
|
11
|
+
};
|
|
12
|
+
export class HomeAssistantEventClient {
|
|
13
|
+
wsUrl;
|
|
14
|
+
token;
|
|
15
|
+
opts;
|
|
16
|
+
webSocketImpl;
|
|
17
|
+
subscriptions = new SubscriptionRegistry();
|
|
18
|
+
pending = new Map();
|
|
19
|
+
stateListeners = new Set();
|
|
20
|
+
socket;
|
|
21
|
+
nextId = 1;
|
|
22
|
+
closedByUser = false;
|
|
23
|
+
reconnectAttempt = 0;
|
|
24
|
+
pingTimer;
|
|
25
|
+
constructor(config, options = {}) {
|
|
26
|
+
this.wsUrl = buildWsUrl(config.baseUrl);
|
|
27
|
+
this.token = config.token;
|
|
28
|
+
this.opts = {
|
|
29
|
+
reconnect: options.reconnect ?? true,
|
|
30
|
+
initialReconnectDelayMs: options.initialReconnectDelayMs ?? DEFAULTS.initialReconnectDelayMs,
|
|
31
|
+
maxReconnectDelayMs: options.maxReconnectDelayMs ?? DEFAULTS.maxReconnectDelayMs,
|
|
32
|
+
pingIntervalMs: options.pingIntervalMs ?? DEFAULTS.pingIntervalMs,
|
|
33
|
+
};
|
|
34
|
+
this.webSocketImpl = options.webSocketImpl ?? WebSocket;
|
|
35
|
+
}
|
|
36
|
+
onConnectionChange(listener) {
|
|
37
|
+
this.stateListeners.add(listener);
|
|
38
|
+
return () => {
|
|
39
|
+
this.stateListeners.delete(listener);
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
async connect() {
|
|
43
|
+
this.closedByUser = false;
|
|
44
|
+
await this.openAndAuth();
|
|
45
|
+
await this.resubscribeAll();
|
|
46
|
+
}
|
|
47
|
+
async close() {
|
|
48
|
+
this.closedByUser = true;
|
|
49
|
+
this.stopPingTimer();
|
|
50
|
+
this.failAllPending(new HaWebSocketClosedError());
|
|
51
|
+
const socket = this.socket;
|
|
52
|
+
if (socket !== undefined) {
|
|
53
|
+
this.socket = undefined;
|
|
54
|
+
socket.close();
|
|
55
|
+
}
|
|
56
|
+
this.setState("closed");
|
|
57
|
+
await Promise.resolve();
|
|
58
|
+
}
|
|
59
|
+
async subscribeEvents(eventType, handler) {
|
|
60
|
+
const subscription = { kind: "event", eventType, handler };
|
|
61
|
+
const clientKey = this.subscriptions.register(subscription);
|
|
62
|
+
try {
|
|
63
|
+
await this.subscribeOnServer(clientKey, subscription);
|
|
64
|
+
}
|
|
65
|
+
catch (error) {
|
|
66
|
+
this.subscriptions.unregister(clientKey);
|
|
67
|
+
throw error;
|
|
68
|
+
}
|
|
69
|
+
return async () => {
|
|
70
|
+
await this.unsubscribe(clientKey);
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
async subscribeTrigger(trigger, handler) {
|
|
74
|
+
const subscription = { kind: "trigger", trigger, handler };
|
|
75
|
+
const clientKey = this.subscriptions.register(subscription);
|
|
76
|
+
try {
|
|
77
|
+
await this.subscribeOnServer(clientKey, subscription);
|
|
78
|
+
}
|
|
79
|
+
catch (error) {
|
|
80
|
+
this.subscriptions.unregister(clientKey);
|
|
81
|
+
throw error;
|
|
82
|
+
}
|
|
83
|
+
return async () => {
|
|
84
|
+
await this.unsubscribe(clientKey);
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
async callService(domain, service, data, target) {
|
|
88
|
+
const payload = {
|
|
89
|
+
type: "call_service",
|
|
90
|
+
domain,
|
|
91
|
+
service,
|
|
92
|
+
};
|
|
93
|
+
if (data !== undefined) {
|
|
94
|
+
payload["service_data"] = data;
|
|
95
|
+
}
|
|
96
|
+
if (target !== undefined) {
|
|
97
|
+
payload["target"] = target;
|
|
98
|
+
}
|
|
99
|
+
const { result } = this.sendRequest(payload);
|
|
100
|
+
return result;
|
|
101
|
+
}
|
|
102
|
+
async getStates() {
|
|
103
|
+
const { result } = this.sendRequest({ type: "get_states" });
|
|
104
|
+
return z.array(EntityStateSchema).parse(await result);
|
|
105
|
+
}
|
|
106
|
+
async getEntityRegistry() {
|
|
107
|
+
const { result } = this.sendRequest({
|
|
108
|
+
type: "config/entity_registry/list",
|
|
109
|
+
});
|
|
110
|
+
return z.array(EntityRegistryEntry).parse(await result);
|
|
111
|
+
}
|
|
112
|
+
async openAndAuth() {
|
|
113
|
+
this.setState("connecting");
|
|
114
|
+
// Close any prior socket before replacing it, so its handlers can't
|
|
115
|
+
// trigger a second concurrent reconnect loop once it eventually closes.
|
|
116
|
+
const previous = this.socket;
|
|
117
|
+
if (previous !== undefined) {
|
|
118
|
+
this.socket = undefined;
|
|
119
|
+
previous.close();
|
|
120
|
+
}
|
|
121
|
+
const socket = new this.webSocketImpl(this.wsUrl);
|
|
122
|
+
this.socket = socket;
|
|
123
|
+
this.nextId = 1;
|
|
124
|
+
this.pending.clear();
|
|
125
|
+
this.subscriptions.clearServerIds();
|
|
126
|
+
await waitForOpen(socket);
|
|
127
|
+
await this.performAuth(socket);
|
|
128
|
+
this.attachMessageHandler(socket);
|
|
129
|
+
this.attachCloseHandler(socket);
|
|
130
|
+
this.setState("authenticated");
|
|
131
|
+
this.reconnectAttempt = 0;
|
|
132
|
+
this.startPingTimer();
|
|
133
|
+
}
|
|
134
|
+
attachMessageHandler(socket) {
|
|
135
|
+
socket.addEventListener("message", (event) => {
|
|
136
|
+
if (this.socket !== socket) {
|
|
137
|
+
// Orphaned socket — ignore any late messages.
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
const parsed = MessageDataString.safeParse(extractEventData(event));
|
|
141
|
+
if (!parsed.success || parsed.data === "") {
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
this.handleRawMessage(parsed.data);
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
attachCloseHandler(socket) {
|
|
148
|
+
socket.addEventListener("close", () => {
|
|
149
|
+
if (this.socket !== socket) {
|
|
150
|
+
// Orphaned socket closing (superseded by a reconnect or by close());
|
|
151
|
+
// the current socket — if any — has its own handler.
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
this.socket = undefined;
|
|
155
|
+
this.stopPingTimer();
|
|
156
|
+
this.failAllPending(new HaWebSocketClosedError());
|
|
157
|
+
if (this.closedByUser) {
|
|
158
|
+
// close() already ran setState("closed"); don't double-emit.
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
this.setState("closed");
|
|
162
|
+
if (this.opts.reconnect) {
|
|
163
|
+
void this.scheduleReconnect();
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
socket.addEventListener("error", (event) => {
|
|
167
|
+
if (this.socket !== socket) {
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
this.setState("error", event);
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
handleRawMessage(raw) {
|
|
174
|
+
let parsed;
|
|
175
|
+
try {
|
|
176
|
+
parsed = JSON.parse(raw);
|
|
177
|
+
}
|
|
178
|
+
catch {
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
const result = ServerMessage.safeParse(parsed);
|
|
182
|
+
if (!result.success) {
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
const message = result.data;
|
|
186
|
+
if (message.type === "event") {
|
|
187
|
+
this.dispatchEvent(message);
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
if (message.type === "result") {
|
|
191
|
+
this.dispatchResult(message);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
dispatchEvent(message) {
|
|
195
|
+
const subscription = this.subscriptions.getByServerId(message.id);
|
|
196
|
+
if (subscription === undefined) {
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
void Promise.resolve(subscription.handler(message.event)).catch((error) => {
|
|
200
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
201
|
+
this.emitError(`Subscription handler threw: ${detail}`);
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
dispatchResult(message) {
|
|
205
|
+
const pending = this.pending.get(message.id);
|
|
206
|
+
if (pending === undefined) {
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
this.pending.delete(message.id);
|
|
210
|
+
if (message.success) {
|
|
211
|
+
pending.resolve(message.result);
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
const error = new HaWebSocketResultError(message.error?.message ?? "Home Assistant returned an error result", message.error?.code);
|
|
215
|
+
pending.reject(error);
|
|
216
|
+
}
|
|
217
|
+
async performAuth(socket) {
|
|
218
|
+
const raw = await waitForFirstMessage(socket);
|
|
219
|
+
const first = AuthMessage.parse(JSON.parse(raw));
|
|
220
|
+
if (first.type !== "auth_required") {
|
|
221
|
+
throw new HaWebSocketAuthError(`Unexpected first message type: ${first.type}`);
|
|
222
|
+
}
|
|
223
|
+
socket.send(JSON.stringify({ type: "auth", access_token: this.token }));
|
|
224
|
+
const nextRaw = await waitForFirstMessage(socket);
|
|
225
|
+
const next = AuthMessage.parse(JSON.parse(nextRaw));
|
|
226
|
+
if (next.type === "auth_invalid") {
|
|
227
|
+
throw new HaWebSocketAuthError(next.message);
|
|
228
|
+
}
|
|
229
|
+
if (next.type !== "auth_ok") {
|
|
230
|
+
throw new HaWebSocketAuthError(`Unexpected auth response: ${next.type}`);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
async resubscribeAll() {
|
|
234
|
+
// clearServerIds already ran in openAndAuth, so server-id bindings are
|
|
235
|
+
// empty here; the clientKey → subscription map still holds every caller-
|
|
236
|
+
// registered subscription. Rebind each to a fresh server id and keep
|
|
237
|
+
// going on individual failures so one bad resubscribe doesn't drop the
|
|
238
|
+
// rest. Subscriptions that fail stay in the registry and get retried on
|
|
239
|
+
// the next reconnect.
|
|
240
|
+
for (const [clientKey, subscription] of this.subscriptions.snapshot()) {
|
|
241
|
+
try {
|
|
242
|
+
await this.subscribeOnServer(clientKey, subscription);
|
|
243
|
+
}
|
|
244
|
+
catch (error) {
|
|
245
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
246
|
+
this.emitError(`Resubscribe failed: ${detail}`);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
async subscribeOnServer(clientKey, subscription) {
|
|
251
|
+
const payload = subscription.kind === "event"
|
|
252
|
+
? { type: "subscribe_events", event_type: subscription.eventType }
|
|
253
|
+
: { type: "subscribe_trigger", trigger: subscription.trigger };
|
|
254
|
+
const { id, result } = this.sendRequest(payload);
|
|
255
|
+
this.subscriptions.bindServerId(clientKey, id);
|
|
256
|
+
await result;
|
|
257
|
+
}
|
|
258
|
+
async unsubscribe(clientKey) {
|
|
259
|
+
const removed = this.subscriptions.unregister(clientKey);
|
|
260
|
+
if (removed?.serverId === undefined) {
|
|
261
|
+
// No active server binding (e.g. disconnected before resubscribe
|
|
262
|
+
// completed); caller-side registry entry is gone, nothing more to do.
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
const { result } = this.sendRequest({
|
|
266
|
+
type: "unsubscribe_events",
|
|
267
|
+
subscription: removed.serverId,
|
|
268
|
+
});
|
|
269
|
+
await result;
|
|
270
|
+
}
|
|
271
|
+
sendRequest(payload) {
|
|
272
|
+
const socket = this.requireOpenSocket();
|
|
273
|
+
const id = this.nextId;
|
|
274
|
+
this.nextId += 1;
|
|
275
|
+
const result = new Promise((resolve, reject) => {
|
|
276
|
+
this.pending.set(id, { resolve, reject });
|
|
277
|
+
});
|
|
278
|
+
socket.send(JSON.stringify({ id, ...payload }));
|
|
279
|
+
return { id, result };
|
|
280
|
+
}
|
|
281
|
+
requireOpenSocket() {
|
|
282
|
+
const socket = this.socket;
|
|
283
|
+
if (socket === undefined || socket.readyState !== socket.OPEN) {
|
|
284
|
+
throw new HaWebSocketClosedError();
|
|
285
|
+
}
|
|
286
|
+
return socket;
|
|
287
|
+
}
|
|
288
|
+
async scheduleReconnect() {
|
|
289
|
+
const delay = Math.min(this.opts.initialReconnectDelayMs * 2 ** this.reconnectAttempt, this.opts.maxReconnectDelayMs);
|
|
290
|
+
this.reconnectAttempt += 1;
|
|
291
|
+
await wait(delay);
|
|
292
|
+
if (this.closedByUser) {
|
|
293
|
+
return;
|
|
294
|
+
}
|
|
295
|
+
try {
|
|
296
|
+
await this.openAndAuth();
|
|
297
|
+
await this.resubscribeAll();
|
|
298
|
+
}
|
|
299
|
+
catch (error) {
|
|
300
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
301
|
+
this.emitError(`Reconnect failed: ${detail}`);
|
|
302
|
+
void this.scheduleReconnect();
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
startPingTimer() {
|
|
306
|
+
this.stopPingTimer();
|
|
307
|
+
this.pingTimer = setInterval(() => {
|
|
308
|
+
const socket = this.socket;
|
|
309
|
+
if (socket === undefined || socket.readyState !== socket.OPEN) {
|
|
310
|
+
return;
|
|
311
|
+
}
|
|
312
|
+
const id = this.nextId;
|
|
313
|
+
this.nextId += 1;
|
|
314
|
+
socket.send(JSON.stringify({ id, type: "ping" }));
|
|
315
|
+
}, this.opts.pingIntervalMs);
|
|
316
|
+
}
|
|
317
|
+
stopPingTimer() {
|
|
318
|
+
if (this.pingTimer !== undefined) {
|
|
319
|
+
clearInterval(this.pingTimer);
|
|
320
|
+
this.pingTimer = undefined;
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
failAllPending(error) {
|
|
324
|
+
for (const [, pending] of this.pending) {
|
|
325
|
+
pending.reject(error);
|
|
326
|
+
}
|
|
327
|
+
this.pending.clear();
|
|
328
|
+
}
|
|
329
|
+
setState(state, detail) {
|
|
330
|
+
for (const listener of this.stateListeners) {
|
|
331
|
+
try {
|
|
332
|
+
listener(state, detail);
|
|
333
|
+
}
|
|
334
|
+
catch {
|
|
335
|
+
// ignore listener errors
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
emitError(message) {
|
|
340
|
+
this.setState("error", new HaWebSocketError(message));
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/ws/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export declare class HaWebSocketError extends Error {
|
|
2
|
+
constructor(message: string);
|
|
3
|
+
}
|
|
4
|
+
export declare class HaWebSocketAuthError extends HaWebSocketError {
|
|
5
|
+
constructor(detail: string);
|
|
6
|
+
}
|
|
7
|
+
export declare class HaWebSocketClosedError extends HaWebSocketError {
|
|
8
|
+
constructor();
|
|
9
|
+
}
|
|
10
|
+
export declare class HaWebSocketResultError extends HaWebSocketError {
|
|
11
|
+
readonly code: string | undefined;
|
|
12
|
+
constructor(message: string, code: string | undefined);
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/ws/errors.ts"],"names":[],"mappings":"AAAA,qBAAa,gBAAiB,SAAQ,KAAK;IACzC,YAAmB,OAAO,EAAE,MAAM,EAGjC;CACF;AAED,qBAAa,oBAAqB,SAAQ,gBAAgB;IACxD,YAAmB,MAAM,EAAE,MAAM,EAGhC;CACF;AAED,qBAAa,sBAAuB,SAAQ,gBAAgB;IAC1D,cAGC;CACF;AAED,qBAAa,sBAAuB,SAAQ,gBAAgB;IAC1D,SAAgB,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IAEzC,YAAmB,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,SAAS,EAI3D;CACF"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export class HaWebSocketError extends Error {
|
|
2
|
+
constructor(message) {
|
|
3
|
+
super(message);
|
|
4
|
+
this.name = "HaWebSocketError";
|
|
5
|
+
}
|
|
6
|
+
}
|
|
7
|
+
export class HaWebSocketAuthError extends HaWebSocketError {
|
|
8
|
+
constructor(detail) {
|
|
9
|
+
super(`Home Assistant WebSocket auth failed: ${detail}`);
|
|
10
|
+
this.name = "HaWebSocketAuthError";
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
export class HaWebSocketClosedError extends HaWebSocketError {
|
|
14
|
+
constructor() {
|
|
15
|
+
super("Home Assistant WebSocket is closed");
|
|
16
|
+
this.name = "HaWebSocketClosedError";
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
export class HaWebSocketResultError extends HaWebSocketError {
|
|
20
|
+
code;
|
|
21
|
+
constructor(message, code) {
|
|
22
|
+
super(message);
|
|
23
|
+
this.name = "HaWebSocketResultError";
|
|
24
|
+
this.code = code;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/ws/errors.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,gBAAiB,SAAQ,KAAK;IACzC,YAAmB,OAAe;QAChC,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,kBAAkB,CAAC;IACjC,CAAC;CACF;AAED,MAAM,OAAO,oBAAqB,SAAQ,gBAAgB;IACxD,YAAmB,MAAc;QAC/B,KAAK,CAAC,yCAAyC,MAAM,EAAE,CAAC,CAAC;QACzD,IAAI,CAAC,IAAI,GAAG,sBAAsB,CAAC;IACrC,CAAC;CACF;AAED,MAAM,OAAO,sBAAuB,SAAQ,gBAAgB;IAC1D;QACE,KAAK,CAAC,oCAAoC,CAAC,CAAC;QAC5C,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAC;IACvC,CAAC;CACF;AAED,MAAM,OAAO,sBAAuB,SAAQ,gBAAgB;IAC1C,IAAI,CAAqB;IAEzC,YAAmB,OAAe,EAAE,IAAwB;QAC1D,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAC;QACrC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;CACF"}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const AuthRequired: z.ZodObject<{
|
|
3
|
+
type: z.ZodLiteral<"auth_required">;
|
|
4
|
+
ha_version: z.ZodOptional<z.ZodString>;
|
|
5
|
+
}, z.core.$strip>;
|
|
6
|
+
export declare const AuthOk: z.ZodObject<{
|
|
7
|
+
type: z.ZodLiteral<"auth_ok">;
|
|
8
|
+
ha_version: z.ZodOptional<z.ZodString>;
|
|
9
|
+
}, z.core.$strip>;
|
|
10
|
+
export declare const AuthInvalid: z.ZodObject<{
|
|
11
|
+
type: z.ZodLiteral<"auth_invalid">;
|
|
12
|
+
message: z.ZodString;
|
|
13
|
+
}, z.core.$strip>;
|
|
14
|
+
export declare const AuthMessage: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
15
|
+
type: z.ZodLiteral<"auth_required">;
|
|
16
|
+
ha_version: z.ZodOptional<z.ZodString>;
|
|
17
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
18
|
+
type: z.ZodLiteral<"auth_ok">;
|
|
19
|
+
ha_version: z.ZodOptional<z.ZodString>;
|
|
20
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
21
|
+
type: z.ZodLiteral<"auth_invalid">;
|
|
22
|
+
message: z.ZodString;
|
|
23
|
+
}, z.core.$strip>], "type">;
|
|
24
|
+
export type AuthMessage = z.infer<typeof AuthMessage>;
|
|
25
|
+
export declare const ResultError: z.ZodObject<{
|
|
26
|
+
code: z.ZodOptional<z.ZodString>;
|
|
27
|
+
message: z.ZodOptional<z.ZodString>;
|
|
28
|
+
}, z.core.$strip>;
|
|
29
|
+
export declare const ResultMessage: z.ZodObject<{
|
|
30
|
+
id: z.ZodNumber;
|
|
31
|
+
type: z.ZodLiteral<"result">;
|
|
32
|
+
success: z.ZodBoolean;
|
|
33
|
+
result: z.ZodOptional<z.ZodUnknown>;
|
|
34
|
+
error: z.ZodOptional<z.ZodObject<{
|
|
35
|
+
code: z.ZodOptional<z.ZodString>;
|
|
36
|
+
message: z.ZodOptional<z.ZodString>;
|
|
37
|
+
}, z.core.$strip>>;
|
|
38
|
+
}, z.core.$strip>;
|
|
39
|
+
export type ResultMessage = z.infer<typeof ResultMessage>;
|
|
40
|
+
export declare const EventContext: z.ZodObject<{
|
|
41
|
+
id: z.ZodOptional<z.ZodString>;
|
|
42
|
+
parent_id: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
43
|
+
user_id: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
44
|
+
}, z.core.$loose>;
|
|
45
|
+
export declare const EventEnvelope: z.ZodObject<{
|
|
46
|
+
data: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
47
|
+
event_type: z.ZodOptional<z.ZodString>;
|
|
48
|
+
time_fired: z.ZodOptional<z.ZodString>;
|
|
49
|
+
origin: z.ZodOptional<z.ZodString>;
|
|
50
|
+
context: z.ZodOptional<z.ZodObject<{
|
|
51
|
+
id: z.ZodOptional<z.ZodString>;
|
|
52
|
+
parent_id: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
53
|
+
user_id: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
54
|
+
}, z.core.$loose>>;
|
|
55
|
+
variables: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
56
|
+
}, z.core.$strip>;
|
|
57
|
+
export type EventEnvelope = z.infer<typeof EventEnvelope>;
|
|
58
|
+
export declare const EventMessage: z.ZodObject<{
|
|
59
|
+
id: z.ZodNumber;
|
|
60
|
+
type: z.ZodLiteral<"event">;
|
|
61
|
+
event: z.ZodObject<{
|
|
62
|
+
data: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
63
|
+
event_type: z.ZodOptional<z.ZodString>;
|
|
64
|
+
time_fired: z.ZodOptional<z.ZodString>;
|
|
65
|
+
origin: z.ZodOptional<z.ZodString>;
|
|
66
|
+
context: z.ZodOptional<z.ZodObject<{
|
|
67
|
+
id: z.ZodOptional<z.ZodString>;
|
|
68
|
+
parent_id: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
69
|
+
user_id: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
70
|
+
}, z.core.$loose>>;
|
|
71
|
+
variables: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
72
|
+
}, z.core.$strip>;
|
|
73
|
+
}, z.core.$strip>;
|
|
74
|
+
export type EventMessage = z.infer<typeof EventMessage>;
|
|
75
|
+
export declare const PongMessage: z.ZodObject<{
|
|
76
|
+
id: z.ZodNumber;
|
|
77
|
+
type: z.ZodLiteral<"pong">;
|
|
78
|
+
}, z.core.$strip>;
|
|
79
|
+
export declare const ServerMessage: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
80
|
+
id: z.ZodNumber;
|
|
81
|
+
type: z.ZodLiteral<"result">;
|
|
82
|
+
success: z.ZodBoolean;
|
|
83
|
+
result: z.ZodOptional<z.ZodUnknown>;
|
|
84
|
+
error: z.ZodOptional<z.ZodObject<{
|
|
85
|
+
code: z.ZodOptional<z.ZodString>;
|
|
86
|
+
message: z.ZodOptional<z.ZodString>;
|
|
87
|
+
}, z.core.$strip>>;
|
|
88
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
89
|
+
id: z.ZodNumber;
|
|
90
|
+
type: z.ZodLiteral<"event">;
|
|
91
|
+
event: z.ZodObject<{
|
|
92
|
+
data: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
93
|
+
event_type: z.ZodOptional<z.ZodString>;
|
|
94
|
+
time_fired: z.ZodOptional<z.ZodString>;
|
|
95
|
+
origin: z.ZodOptional<z.ZodString>;
|
|
96
|
+
context: z.ZodOptional<z.ZodObject<{
|
|
97
|
+
id: z.ZodOptional<z.ZodString>;
|
|
98
|
+
parent_id: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
99
|
+
user_id: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
100
|
+
}, z.core.$loose>>;
|
|
101
|
+
variables: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
102
|
+
}, z.core.$strip>;
|
|
103
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
104
|
+
id: z.ZodNumber;
|
|
105
|
+
type: z.ZodLiteral<"pong">;
|
|
106
|
+
}, z.core.$strip>], "type">;
|
|
107
|
+
export type ServerMessage = z.infer<typeof ServerMessage>;
|
|
108
|
+
export type StateChangedEvent = {
|
|
109
|
+
entity_id: string;
|
|
110
|
+
new_state: unknown;
|
|
111
|
+
old_state: unknown;
|
|
112
|
+
};
|
|
113
|
+
export declare const EntityRegistryEntry: z.ZodObject<{
|
|
114
|
+
entity_id: z.ZodString;
|
|
115
|
+
unique_id: z.ZodString;
|
|
116
|
+
platform: z.ZodString;
|
|
117
|
+
config_entry_id: z.ZodNullable<z.ZodString>;
|
|
118
|
+
device_id: z.ZodNullable<z.ZodString>;
|
|
119
|
+
area_id: z.ZodNullable<z.ZodString>;
|
|
120
|
+
name: z.ZodNullable<z.ZodString>;
|
|
121
|
+
original_name: z.ZodNullable<z.ZodString>;
|
|
122
|
+
disabled_by: z.ZodNullable<z.ZodString>;
|
|
123
|
+
}, z.core.$loose>;
|
|
124
|
+
export type EntityRegistryEntry = z.infer<typeof EntityRegistryEntry>;
|
|
125
|
+
export declare const StateChangedEventData: z.ZodObject<{
|
|
126
|
+
entity_id: z.ZodString;
|
|
127
|
+
new_state: z.ZodOptional<z.ZodUnknown>;
|
|
128
|
+
old_state: z.ZodOptional<z.ZodUnknown>;
|
|
129
|
+
}, z.core.$loose>;
|
|
130
|
+
//# sourceMappingURL=messages.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../src/ws/messages.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,YAAY;;;iBAGvB,CAAC;AAEH,eAAO,MAAM,MAAM;;;iBAGjB,CAAC;AAEH,eAAO,MAAM,WAAW;;;iBAGtB,CAAC;AAEH,eAAO,MAAM,WAAW;;;;;;;;;2BAItB,CAAC;AAEH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAC;AAEtD,eAAO,MAAM,WAAW;;;iBAGtB,CAAC;AAEH,eAAO,MAAM,aAAa;;;;;;;;;iBAMxB,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC;AAE1D,eAAO,MAAM,YAAY;;;;iBAMf,CAAC;AAEX,eAAO,MAAM,aAAa;;;;;;;;;;;iBAOxB,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC;AAE1D,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;iBAIvB,CAAC;AAEH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AAExD,eAAO,MAAM,WAAW;;;iBAGtB,CAAC;AAEH,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;2BAIxB,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC;AAE1D,MAAM,MAAM,iBAAiB,GAAG;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF,eAAO,MAAM,mBAAmB;;;;;;;;;;iBAYtB,CAAC;AAEX,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEtE,eAAO,MAAM,qBAAqB;;;;iBAMxB,CAAC"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export const AuthRequired = z.object({
|
|
3
|
+
type: z.literal("auth_required"),
|
|
4
|
+
ha_version: z.string().optional(),
|
|
5
|
+
});
|
|
6
|
+
export const AuthOk = z.object({
|
|
7
|
+
type: z.literal("auth_ok"),
|
|
8
|
+
ha_version: z.string().optional(),
|
|
9
|
+
});
|
|
10
|
+
export const AuthInvalid = z.object({
|
|
11
|
+
type: z.literal("auth_invalid"),
|
|
12
|
+
message: z.string(),
|
|
13
|
+
});
|
|
14
|
+
export const AuthMessage = z.discriminatedUnion("type", [
|
|
15
|
+
AuthRequired,
|
|
16
|
+
AuthOk,
|
|
17
|
+
AuthInvalid,
|
|
18
|
+
]);
|
|
19
|
+
export const ResultError = z.object({
|
|
20
|
+
code: z.string().optional(),
|
|
21
|
+
message: z.string().optional(),
|
|
22
|
+
});
|
|
23
|
+
export const ResultMessage = z.object({
|
|
24
|
+
id: z.number(),
|
|
25
|
+
type: z.literal("result"),
|
|
26
|
+
success: z.boolean(),
|
|
27
|
+
result: z.unknown().optional(),
|
|
28
|
+
error: ResultError.optional(),
|
|
29
|
+
});
|
|
30
|
+
export const EventContext = z
|
|
31
|
+
.object({
|
|
32
|
+
id: z.string().optional(),
|
|
33
|
+
parent_id: z.string().nullable().optional(),
|
|
34
|
+
user_id: z.string().nullable().optional(),
|
|
35
|
+
})
|
|
36
|
+
.loose();
|
|
37
|
+
export const EventEnvelope = z.object({
|
|
38
|
+
data: z.record(z.string(), z.unknown()).optional(),
|
|
39
|
+
event_type: z.string().optional(),
|
|
40
|
+
time_fired: z.string().optional(),
|
|
41
|
+
origin: z.string().optional(),
|
|
42
|
+
context: EventContext.optional(),
|
|
43
|
+
variables: z.record(z.string(), z.unknown()).optional(),
|
|
44
|
+
});
|
|
45
|
+
export const EventMessage = z.object({
|
|
46
|
+
id: z.number(),
|
|
47
|
+
type: z.literal("event"),
|
|
48
|
+
event: EventEnvelope,
|
|
49
|
+
});
|
|
50
|
+
export const PongMessage = z.object({
|
|
51
|
+
id: z.number(),
|
|
52
|
+
type: z.literal("pong"),
|
|
53
|
+
});
|
|
54
|
+
export const ServerMessage = z.discriminatedUnion("type", [
|
|
55
|
+
ResultMessage,
|
|
56
|
+
EventMessage,
|
|
57
|
+
PongMessage,
|
|
58
|
+
]);
|
|
59
|
+
export const EntityRegistryEntry = z
|
|
60
|
+
.object({
|
|
61
|
+
entity_id: z.string().min(1),
|
|
62
|
+
unique_id: z.string().min(1),
|
|
63
|
+
platform: z.string().min(1),
|
|
64
|
+
config_entry_id: z.string().min(1).nullable(),
|
|
65
|
+
device_id: z.string().min(1).nullable(),
|
|
66
|
+
area_id: z.string().min(1).nullable(),
|
|
67
|
+
name: z.string().nullable(),
|
|
68
|
+
original_name: z.string().nullable(),
|
|
69
|
+
disabled_by: z.string().nullable(),
|
|
70
|
+
})
|
|
71
|
+
.loose();
|
|
72
|
+
export const StateChangedEventData = z
|
|
73
|
+
.object({
|
|
74
|
+
entity_id: z.string(),
|
|
75
|
+
new_state: z.unknown().optional(),
|
|
76
|
+
old_state: z.unknown().optional(),
|
|
77
|
+
})
|
|
78
|
+
.loose();
|
|
79
|
+
//# sourceMappingURL=messages.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"messages.js","sourceRoot":"","sources":["../../src/ws/messages.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/**
|
|
3
|
+
* Minimal structural shape of the WebSocket API the client consumes. Narrow
|
|
4
|
+
* enough that test doubles (see test/fake-websocket.ts) can satisfy it
|
|
5
|
+
* without type assertions, but wide enough that the DOM `WebSocket` global
|
|
6
|
+
* is structurally assignable.
|
|
7
|
+
*/
|
|
8
|
+
export type WebSocketLike = {
|
|
9
|
+
readonly readyState: number;
|
|
10
|
+
readonly OPEN: number;
|
|
11
|
+
send: (data: string) => void;
|
|
12
|
+
close: (code?: number, reason?: string) => void;
|
|
13
|
+
addEventListener: (type: string, listener: (event: unknown) => void) => void;
|
|
14
|
+
removeEventListener: (type: string, listener: (event: unknown) => void) => void;
|
|
15
|
+
};
|
|
16
|
+
export type WebSocketLikeCtor = new (url: string) => WebSocketLike;
|
|
17
|
+
export declare function wait(ms: number): Promise<void>;
|
|
18
|
+
export declare function waitForOpen(socket: WebSocketLike): Promise<void>;
|
|
19
|
+
export declare const MessageDataString: z.ZodString;
|
|
20
|
+
export declare function extractEventData(event: unknown): unknown;
|
|
21
|
+
export declare function waitForFirstMessage(socket: WebSocketLike): Promise<string>;
|
|
22
|
+
export declare function buildWsUrl(baseUrl: string): string;
|
|
23
|
+
//# sourceMappingURL=socket-helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"socket-helpers.d.ts","sourceRoot":"","sources":["../../src/ws/socket-helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB;;;;;GAKG;AACH,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7B,KAAK,EAAE,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAChD,gBAAgB,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,KAAK,IAAI,CAAC;IAC7E,mBAAmB,EAAE,CACnB,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,KAC/B,IAAI,CAAC;CACX,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG,KAAK,GAAG,EAAE,MAAM,KAAK,aAAa,CAAC;AAEnE,wBAAgB,IAAI,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE9C;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CA8BhE;AAED,eAAO,MAAM,iBAAiB,aAAa,CAAC;AAI5C,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAGxD;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CAkB1E;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CASlD"}
|