@glasshome/sync-layer 0.2.0 → 0.2.2
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/dist/index.d.ts
CHANGED
|
@@ -43,7 +43,7 @@ export { fetchForecast, fetchForecastData, fetchForecasts } from "./weather/fetc
|
|
|
43
43
|
export { getForecast, getForecasts, refreshForecast, refreshForecasts } from "./weather/query";
|
|
44
44
|
export type { EntityForecastQueryOptions, ForecastQueryOptions, ForecastResult, ForecastsResult, ForecastType, WeatherForecast, WeatherForecastData, WeatherForecasts, WeatherForecastsData, } from "./weather/types";
|
|
45
45
|
export { applyDemoServiceCall, createDemoFixtures, isDemoMode, loadDemoData, startDemoEnergyTicker, stopDemoEnergyTicker, unloadDemoData, } from "./demo/demo-provider";
|
|
46
|
-
export declare const VERSION = "0.2.
|
|
46
|
+
export declare const VERSION = "0.2.1";
|
|
47
47
|
export { applyBridgeConnState, attachBridgeToStore, detachBridgeFromStore, reloadAfterBridgeReconnect, } from "./connection/bridged";
|
|
48
48
|
export { BridgeNeedsAuthError, createHaBridge, type BridgeConnectOptions, type BridgeEvents, type HaBridge, } from "./worker/bridge-client";
|
|
49
49
|
export type { AuthMode, ConnState, OAuthTokenData } from "./worker/protocol";
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ENERGY_ENTITY_IDS, createDemoFixtures, demoEnergyPreferences, energyEntityValue, formatEnergyState, isEnergyEntity, isSunUp, resetStore, setState, simulateEnergy, state, sunEvents, synthesizeEnergyHistory, synthesizeEnergyStatistics } from "./demo-data-CavpxBw3.js";
|
|
2
|
-
import { runHaBridgeWorker } from "./worker-main-
|
|
2
|
+
import { runHaBridgeWorker } from "./worker-main-BYGgbA7k.js";
|
|
3
3
|
import { createConnection, createLongLivedTokenAuth, getAuth } from "home-assistant-js-websocket";
|
|
4
4
|
import { produce, reconcile } from "solid-js/store";
|
|
5
5
|
|
|
@@ -2870,7 +2870,8 @@ function createHaBridge(worker, events = {}) {
|
|
|
2870
2870
|
k: "connect",
|
|
2871
2871
|
url: opts.url,
|
|
2872
2872
|
mode: opts.mode,
|
|
2873
|
-
proxyWsPath: opts.proxyWsPath
|
|
2873
|
+
proxyWsPath: opts.proxyWsPath,
|
|
2874
|
+
proxyTicket: opts.proxyTicket
|
|
2874
2875
|
});
|
|
2875
2876
|
});
|
|
2876
2877
|
},
|
|
@@ -2915,7 +2916,7 @@ function createHaBridge(worker, events = {}) {
|
|
|
2915
2916
|
|
|
2916
2917
|
//#endregion
|
|
2917
2918
|
//#region src/index.ts
|
|
2918
|
-
const VERSION = "0.2.
|
|
2919
|
+
const VERSION = "0.2.1";
|
|
2919
2920
|
|
|
2920
2921
|
//#endregion
|
|
2921
2922
|
export { BridgeNeedsAuthError, DOMAINS_USE_LAST_UPDATED, LINE_ATTRIBUTES_TO_KEEP, MAX_HISTORY_POINTS, NEED_ATTRIBUTE_DOMAINS, VERSION, addDebugIncomingMessageListener, addDebugOutgoingMessageListener, appendHistoryPoint, applyBridgeConnState, applyDemoServiceCall, area, areas, attachBridgeToStore, authenticateWithOAuth, authenticateWithToken, batchEntityUpdates, batchServiceCalls, buildAreaView, buildDeviceView, buildEntityView, bulkAppendHistoryPoints, callService, createDemoFixtures, createHaBridge, detachBridgeFromStore, disconnect, entities, entitiesByAreaAndDomain, entitiesWhere, entity, entityIdHistoryNeedsAttributes, entityViewEquals, extractDomain, fetchEnergyPreferences, fetchEntityHistory, fetchForecast, fetchForecastData, fetchForecasts, fetchHistory, fetchStatisticsDuringPeriod, fetchStream, fetchStreamData, getAllEntityViews, getAreaView, getAreaViews, getConnection, getConnectionState, getEntityView, getEntityViews, getForecast, getForecasts, getStream, getWebRtcClientConfig, historyStateToTimeline, initConnection, isAuthValid, isConnected, isDemoMode, isHistoryTracked, loadDemoData, normalizeStatisticTime, refreshAuth, refreshForecast, refreshForecasts, refreshStream, registerEntity, reloadAfterBridgeReconnect, resetStore, runHaBridgeWorker, searchEntities, sendCommand, sendWebRtcCandidate, setState, startDemoEnergyTicker, startWebRtcSession, state, stopDemoEnergyTicker, toggle, trackEntityHistory, turnOff, turnOn, unloadDemoData, untrackEntityHistory, updateEntity };
|
|
@@ -31,8 +31,13 @@ export type MainToWorker = {
|
|
|
31
31
|
k: "connect";
|
|
32
32
|
url: string;
|
|
33
33
|
mode: AuthMode;
|
|
34
|
-
/**
|
|
34
|
+
/** Proxy WS endpoint to use instead of the HA host. A path (web, resolved
|
|
35
|
+
* same-origin) or an absolute ws(s)/http(s) URL (native, where the worker
|
|
36
|
+
* origin is localhost, not dash-server). */
|
|
35
37
|
proxyWsPath?: string;
|
|
38
|
+
/** Short-lived ticket authorizing the proxy WS + broker mint when a
|
|
39
|
+
* cross-origin cookie/bearer can't ride them (native). */
|
|
40
|
+
proxyTicket?: string;
|
|
36
41
|
} | {
|
|
37
42
|
k: "send";
|
|
38
43
|
id: number;
|
|
@@ -129,13 +129,21 @@ function isHaWireMessage(value) {
|
|
|
129
129
|
return typeof value === "object" && value !== null && typeof value.type === "string";
|
|
130
130
|
}
|
|
131
131
|
var BrokeredAuth = class extends Auth {
|
|
132
|
-
constructor(mintUrl, data) {
|
|
132
|
+
constructor(mintUrl, data, ticket) {
|
|
133
133
|
super(data);
|
|
134
134
|
this.mintUrl = mintUrl;
|
|
135
|
+
this.ticket = ticket;
|
|
135
136
|
}
|
|
136
137
|
async refreshAccessToken() {
|
|
137
|
-
const res = await fetch(this.mintUrl, {
|
|
138
|
+
const res = await fetch(this.mintUrl, {
|
|
139
|
+
credentials: "include",
|
|
140
|
+
headers: {
|
|
141
|
+
accept: "application/json",
|
|
142
|
+
...this.ticket ? { "x-proxy-ticket": this.ticket } : {}
|
|
143
|
+
}
|
|
144
|
+
});
|
|
138
145
|
if (!res.ok) throw new Error(`Token broker responded ${res.status}`);
|
|
146
|
+
if (!res.headers.get("content-type")?.includes("application/json")) throw new Error(`Token broker did not return JSON (is ${this.mintUrl} reachable?)`);
|
|
139
147
|
const broker = await res.json();
|
|
140
148
|
this.data = {
|
|
141
149
|
...this.data,
|
|
@@ -148,6 +156,19 @@ var BrokeredAuth = class extends Auth {
|
|
|
148
156
|
};
|
|
149
157
|
}
|
|
150
158
|
};
|
|
159
|
+
/** Resolve the proxy WS endpoint. Accepts a same-origin path (web) or an
|
|
160
|
+
* absolute ws(s)/http(s) URL (native), and appends the auth ticket if given. */
|
|
161
|
+
function buildProxyWsUrl(scope, proxyWsPath, ticket) {
|
|
162
|
+
let base;
|
|
163
|
+
if (/^wss?:\/\//i.test(proxyWsPath)) base = proxyWsPath;
|
|
164
|
+
else if (/^https?:\/\//i.test(proxyWsPath)) base = proxyWsPath.replace(/^http/i, "ws");
|
|
165
|
+
else {
|
|
166
|
+
const proto = scope.location.protocol === "https:" ? "wss:" : "ws:";
|
|
167
|
+
base = `${proto}//${scope.location.host}${proxyWsPath}`;
|
|
168
|
+
}
|
|
169
|
+
if (ticket) base += `${base.includes("?") ? "&" : "?"}ticket=${encodeURIComponent(ticket)}`;
|
|
170
|
+
return base;
|
|
171
|
+
}
|
|
151
172
|
function runHaBridgeWorker(scope) {
|
|
152
173
|
let conn = null;
|
|
153
174
|
const widgets = /* @__PURE__ */ new Map();
|
|
@@ -260,7 +281,7 @@ function runHaBridgeWorker(scope) {
|
|
|
260
281
|
resumeVisible = null;
|
|
261
282
|
}
|
|
262
283
|
}
|
|
263
|
-
async function buildAuth(url, mode) {
|
|
284
|
+
async function buildAuth(url, mode, ticket) {
|
|
264
285
|
switch (mode.kind) {
|
|
265
286
|
case "token": return new Auth({
|
|
266
287
|
hassUrl: url,
|
|
@@ -277,7 +298,7 @@ function runHaBridgeWorker(scope) {
|
|
|
277
298
|
refresh_token: "",
|
|
278
299
|
expires: 0,
|
|
279
300
|
expires_in: 0
|
|
280
|
-
});
|
|
301
|
+
}, ticket);
|
|
281
302
|
case "oauth": {
|
|
282
303
|
const data = mode.data ?? await loadTokens();
|
|
283
304
|
if (!data) return "needs-auth";
|
|
@@ -288,8 +309,8 @@ function runHaBridgeWorker(scope) {
|
|
|
288
309
|
}
|
|
289
310
|
}
|
|
290
311
|
}
|
|
291
|
-
async function connect(url, mode, proxyWsPath) {
|
|
292
|
-
const auth = await buildAuth(url, mode);
|
|
312
|
+
async function connect(url, mode, proxyWsPath, proxyTicket) {
|
|
313
|
+
const auth = await buildAuth(url, mode, proxyTicket);
|
|
293
314
|
if (auth === "needs-auth") {
|
|
294
315
|
post({
|
|
295
316
|
k: "connect_result",
|
|
@@ -308,9 +329,9 @@ function runHaBridgeWorker(scope) {
|
|
|
308
329
|
});
|
|
309
330
|
return;
|
|
310
331
|
}
|
|
311
|
-
const
|
|
312
|
-
|
|
313
|
-
const proxied = new Proxy(options.auth, { get: (target, prop) => prop === "wsUrl" ?
|
|
332
|
+
const proxyWsUrl = proxyWsPath ? buildProxyWsUrl(scope, proxyWsPath, proxyTicket) : null;
|
|
333
|
+
const socketFactory = proxyWsUrl ? (options) => {
|
|
334
|
+
const proxied = new Proxy(options.auth, { get: (target, prop) => prop === "wsUrl" ? proxyWsUrl : Reflect.get(target, prop) });
|
|
314
335
|
return createSocket({
|
|
315
336
|
...options,
|
|
316
337
|
auth: proxied
|
|
@@ -364,7 +385,7 @@ function runHaBridgeWorker(scope) {
|
|
|
364
385
|
const msg = ev.data;
|
|
365
386
|
switch (msg.k) {
|
|
366
387
|
case "connect":
|
|
367
|
-
await connect(msg.url, msg.mode, msg.proxyWsPath);
|
|
388
|
+
await connect(msg.url, msg.mode, msg.proxyWsPath, msg.proxyTicket);
|
|
368
389
|
break;
|
|
369
390
|
case "send": {
|
|
370
391
|
if (!conn || !isHaWireMessage(msg.message)) {
|