mirror of
https://github.com/home-assistant/frontend.git
synced 2026-05-26 02:57:02 +00:00
Compare commits
18 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 54a8e6c294 | |||
| bfec22d828 | |||
| cde6450cfc | |||
| ab39e70629 | |||
| 69f209e3c3 | |||
| f4c5561a54 | |||
| 5147937a6f | |||
| ee39605aa7 | |||
| 4af4f1dc51 | |||
| a2d8859d94 | |||
| afea8180c4 | |||
| b9c077489d | |||
| 440bb32056 | |||
| 8f371621ad | |||
| 61815b20e3 | |||
| 1942fa3a77 | |||
| 865e67a06f | |||
| 412dce4c1f |
@@ -41,14 +41,14 @@ jobs:
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@68bde559dea0fdcac2102bfdf6230c5f70eb485e # v4.35.4
|
||||
uses: github/codeql-action/init@9e0d7b8d25671d64c341c19c0152d693099fb5ba # v4.35.5
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||
# If this step fails, then you should remove it and run the build manually (see below)
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@68bde559dea0fdcac2102bfdf6230c5f70eb485e # v4.35.4
|
||||
uses: github/codeql-action/autobuild@9e0d7b8d25671d64c341c19c0152d693099fb5ba # v4.35.5
|
||||
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 https://git.io/JvXDl
|
||||
@@ -62,4 +62,4 @@ jobs:
|
||||
# make release
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@68bde559dea0fdcac2102bfdf6230c5f70eb485e # v4.35.4
|
||||
uses: github/codeql-action/analyze@9e0d7b8d25671d64c341c19c0152d693099fb5ba # v4.35.5
|
||||
|
||||
+248
-248
File diff suppressed because one or more lines are too long
+1
-1
@@ -13,4 +13,4 @@ nodeLinker: node-modules
|
||||
|
||||
npmMinimalAgeGate: 3d
|
||||
|
||||
yarnPath: .yarn/releases/yarn-4.14.1.cjs
|
||||
yarnPath: .yarn/releases/yarn-4.15.0.cjs
|
||||
|
||||
+10
-10
@@ -38,7 +38,7 @@
|
||||
"@codemirror/search": "6.7.0",
|
||||
"@codemirror/state": "6.6.0",
|
||||
"@codemirror/view": "6.43.0",
|
||||
"@date-fns/tz": "1.4.1",
|
||||
"@date-fns/tz": "1.5.0",
|
||||
"@egjs/hammerjs": "2.0.17",
|
||||
"@formatjs/intl-datetimeformat": "7.4.6",
|
||||
"@formatjs/intl-displaynames": "7.3.8",
|
||||
@@ -90,15 +90,15 @@
|
||||
"deep-clone-simple": "1.1.1",
|
||||
"deep-freeze": "0.0.1",
|
||||
"dialog-polyfill": "0.5.6",
|
||||
"echarts": "6.1.0",
|
||||
"echarts": "6.0.0",
|
||||
"element-internals-polyfill": "3.0.2",
|
||||
"fuse.js": "7.3.0",
|
||||
"google-timezones-json": "1.2.0",
|
||||
"gulp-zopfli-green": "7.0.0",
|
||||
"hls.js": "1.6.16",
|
||||
"home-assistant-js-websocket": "9.6.0",
|
||||
"idb-keyval": "6.2.2",
|
||||
"intl-messageformat": "11.2.6",
|
||||
"idb-keyval": "6.2.4",
|
||||
"intl-messageformat": "11.2.7",
|
||||
"js-yaml": "4.1.1",
|
||||
"leaflet": "1.9.4",
|
||||
"leaflet-draw": "patch:leaflet-draw@npm%3A1.0.4#./.yarn/patches/leaflet-draw-npm-1.0.4-0ca0ebcf65.patch",
|
||||
@@ -118,7 +118,7 @@
|
||||
"sortablejs": "patch:sortablejs@npm%3A1.15.6#~/.yarn/patches/sortablejs-npm-1.15.6-3235a8f83b.patch",
|
||||
"stacktrace-js": "2.0.2",
|
||||
"superstruct": "2.0.2",
|
||||
"tinykeys": "3.1.0",
|
||||
"tinykeys": "4.0.0",
|
||||
"weekstart": "2.0.0",
|
||||
"workbox-cacheable-response": "7.4.1",
|
||||
"workbox-core": "7.4.1",
|
||||
@@ -141,7 +141,7 @@
|
||||
"@octokit/plugin-retry": "8.1.0",
|
||||
"@octokit/rest": "22.0.1",
|
||||
"@rsdoctor/rspack-plugin": "1.5.11",
|
||||
"@rspack/core": "2.0.3",
|
||||
"@rspack/core": "2.0.4",
|
||||
"@rspack/dev-server": "2.0.1",
|
||||
"@types/babel__plugin-transform-runtime": "7.9.5",
|
||||
"@types/chromecast-caf-receiver": "6.0.26",
|
||||
@@ -160,7 +160,7 @@
|
||||
"@types/sortablejs": "1.15.9",
|
||||
"@types/tar": "7.0.87",
|
||||
"@types/webspeechapi": "0.0.29",
|
||||
"@vitest/coverage-v8": "4.1.6",
|
||||
"@vitest/coverage-v8": "4.1.7",
|
||||
"babel-loader": "10.1.1",
|
||||
"babel-plugin-template-html-minifier": "4.1.0",
|
||||
"browserslist-useragent-regexp": "4.1.4",
|
||||
@@ -175,7 +175,7 @@
|
||||
"eslint-plugin-wc": "3.1.0",
|
||||
"fancy-log": "2.0.0",
|
||||
"fs-extra": "11.3.5",
|
||||
"generate-license-file": "4.1.1",
|
||||
"generate-license-file": "4.2.1",
|
||||
"glob": "13.0.6",
|
||||
"globals": "17.6.0",
|
||||
"gulp": "5.0.1",
|
||||
@@ -203,7 +203,7 @@
|
||||
"typescript": "6.0.3",
|
||||
"typescript-eslint": "8.59.4",
|
||||
"vite-tsconfig-paths": "6.1.1",
|
||||
"vitest": "4.1.6",
|
||||
"vitest": "4.1.7",
|
||||
"webpack-stats-plugin": "1.1.3",
|
||||
"webpackbar": "7.0.0",
|
||||
"workbox-build": "patch:workbox-build@npm%3A7.4.1#~/.yarn/patches/workbox-build-npm-7.4.1-c84561662c.patch"
|
||||
@@ -219,7 +219,7 @@
|
||||
"@material/mwc-list@^0.27.0": "patch:@material/mwc-list@npm%3A0.27.0#~/.yarn/patches/@material-mwc-list-npm-0.27.0-5344fc9de4.patch",
|
||||
"glob@^10.2.2": "^10.5.0"
|
||||
},
|
||||
"packageManager": "yarn@4.14.1",
|
||||
"packageManager": "yarn@4.15.0",
|
||||
"volta": {
|
||||
"node": "24.16.0"
|
||||
}
|
||||
|
||||
@@ -128,7 +128,9 @@ export class HaAutomationRow extends LitElement {
|
||||
}
|
||||
.row {
|
||||
display: flex;
|
||||
padding: 0 0 0 var(--ha-space-3);
|
||||
padding-left: var(--ha-space-3);
|
||||
padding-inline-start: var(--ha-space-3);
|
||||
padding-inline-end: initial;
|
||||
min-height: 48px;
|
||||
align-items: flex-start;
|
||||
cursor: pointer;
|
||||
@@ -144,6 +146,8 @@ export class HaAutomationRow extends LitElement {
|
||||
transition: transform 150ms cubic-bezier(0.4, 0, 0.2, 1);
|
||||
color: var(--ha-color-on-neutral-quiet);
|
||||
margin-left: calc(var(--ha-space-2) * -1);
|
||||
margin-inline-start: calc(var(--ha-space-2) * -1);
|
||||
margin-inline-end: initial;
|
||||
}
|
||||
:host([building-block]) .leading-icon-wrapper {
|
||||
background-color: var(--ha-color-fill-neutral-loud-resting);
|
||||
|
||||
@@ -109,6 +109,8 @@ export class HaGenericPicker extends PickerMixin(LitElement) {
|
||||
@property({ attribute: "custom-value-label" })
|
||||
public customValueLabel?: string;
|
||||
|
||||
@property({ type: Boolean, attribute: "no-sort" }) public noSort = false;
|
||||
|
||||
@query(".container") private _containerElement?: HTMLDivElement;
|
||||
|
||||
@query("ha-picker-combo-box") private _comboBox?: HaPickerComboBox;
|
||||
@@ -271,6 +273,7 @@ export class HaGenericPicker extends PickerMixin(LitElement) {
|
||||
.selectedSection=${this.selectedSection}
|
||||
.searchKeys=${this.searchKeys}
|
||||
.customValueLabel=${this.customValueLabel}
|
||||
.noSort=${this.noSort}
|
||||
></ha-picker-combo-box>
|
||||
`;
|
||||
}
|
||||
|
||||
@@ -167,6 +167,8 @@ export class HaPickerComboBox extends ScrollableFadeMixin(LitElement) {
|
||||
|
||||
@property({ type: Boolean, reflect: true }) public clearable = false;
|
||||
|
||||
@property({ type: Boolean, attribute: "no-sort" }) public noSort = false;
|
||||
|
||||
@query("lit-virtualizer") public virtualizerElement?: LitVirtualizer;
|
||||
|
||||
@query("ha-input-search") private _searchFieldElement?: HaInputSearch;
|
||||
@@ -342,7 +344,7 @@ export class HaPickerComboBox extends ScrollableFadeMixin(LitElement) {
|
||||
private _getItems = () => {
|
||||
let items = [...(this.getItems(this._search, this._selectedSection) || [])];
|
||||
|
||||
if (!this.sections?.length) {
|
||||
if (!this.sections?.length && !this.noSort) {
|
||||
items = items.sort((entityA, entityB) => {
|
||||
const sortLabelA =
|
||||
typeof entityA === "string" ? entityA : entityA.sorting_label;
|
||||
|
||||
@@ -199,6 +199,7 @@ export class HaSelectSelector extends LitElement {
|
||||
: nothing}
|
||||
|
||||
<ha-generic-picker
|
||||
no-sort
|
||||
.hass=${this.hass}
|
||||
.helper=${this.helper}
|
||||
.disabled=${this.disabled}
|
||||
@@ -215,6 +216,7 @@ export class HaSelectSelector extends LitElement {
|
||||
if (this.selector.select?.custom_value) {
|
||||
return html`
|
||||
<ha-generic-picker
|
||||
no-sort
|
||||
.hass=${this.hass}
|
||||
.label=${this.label}
|
||||
.helper=${this.helper}
|
||||
|
||||
+11
-2
@@ -17,6 +17,7 @@ export interface BluetoothDeviceData extends DataTableRowData {
|
||||
source: string;
|
||||
time: number;
|
||||
tx_power: number;
|
||||
raw: string | null;
|
||||
}
|
||||
|
||||
export interface BluetoothConnectionData extends DataTableRowData {
|
||||
@@ -58,13 +59,21 @@ export interface BluetoothAllocationsData {
|
||||
allocated: string[];
|
||||
}
|
||||
|
||||
export type BluetoothScannerMode = "active" | "passive";
|
||||
|
||||
export type BluetoothScannerRequestedMode = BluetoothScannerMode | "auto";
|
||||
|
||||
export interface BluetoothScannerState {
|
||||
source: string;
|
||||
adapter: string;
|
||||
current_mode: "active" | "passive" | null;
|
||||
requested_mode: "active" | "passive" | null;
|
||||
current_mode: BluetoothScannerMode | null;
|
||||
requested_mode: BluetoothScannerRequestedMode | null;
|
||||
}
|
||||
|
||||
export const isScannerStateMismatch = (state: BluetoothScannerState): boolean =>
|
||||
state.requested_mode !== "auto" &&
|
||||
state.current_mode !== state.requested_mode;
|
||||
|
||||
export const subscribeBluetoothScannersDetailsUpdates = (
|
||||
conn: Connection,
|
||||
store: Store<BluetoothScannersDetails>
|
||||
|
||||
@@ -343,9 +343,9 @@ export class HaVoiceAssistantSetupDialog extends LitElement {
|
||||
this._step = this._previousSteps.pop()!;
|
||||
}
|
||||
|
||||
private _goToNextStep(ev?: CustomEvent) {
|
||||
private async _goToNextStep(ev?: CustomEvent) {
|
||||
if (ev?.detail?.updateConfig) {
|
||||
this._fetchAssistConfiguration();
|
||||
await this._fetchAssistConfiguration();
|
||||
}
|
||||
if (ev?.detail?.nextStep) {
|
||||
this._nextStep = ev.detail.nextStep;
|
||||
|
||||
+9
-3
@@ -19,6 +19,7 @@ import type {
|
||||
HaScannerType,
|
||||
} from "../../../../../data/bluetooth";
|
||||
import {
|
||||
isScannerStateMismatch,
|
||||
subscribeBluetoothConnectionAllocations,
|
||||
subscribeBluetoothScannerState,
|
||||
subscribeBluetoothScannersDetails,
|
||||
@@ -285,9 +286,7 @@ export class BluetoothAdapterInfoPage extends LitElement {
|
||||
const scannerType: HaScannerType =
|
||||
scannerDetails?.scanner_type ?? "unknown";
|
||||
const isRemoteScanner = scannerType === "remote";
|
||||
const hasMismatch =
|
||||
scannerState &&
|
||||
scannerState.current_mode !== scannerState.requested_mode;
|
||||
const hasMismatch = scannerState && isScannerStateMismatch(scannerState);
|
||||
|
||||
const allocations = scannerDetails
|
||||
? this._connectionAllocationData.find(
|
||||
@@ -438,6 +437,13 @@ export class BluetoothAdapterInfoPage extends LitElement {
|
||||
);
|
||||
}
|
||||
|
||||
if (scannerState.requested_mode === "auto") {
|
||||
return this.hass.localize(
|
||||
"ui.panel.config.bluetooth.scanning_mode_auto_with_current",
|
||||
{ current: this._formatMode(scannerState.current_mode) }
|
||||
);
|
||||
}
|
||||
|
||||
return this._formatModeLabel(scannerState.current_mode);
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -23,6 +23,7 @@ import type {
|
||||
BluetoothScannerState,
|
||||
} from "../../../../../data/bluetooth";
|
||||
import {
|
||||
isScannerStateMismatch,
|
||||
subscribeBluetoothAdvertisements,
|
||||
subscribeBluetoothConnectionAllocations,
|
||||
subscribeBluetoothScannerState,
|
||||
@@ -144,7 +145,7 @@ export class BluetoothConfigDashboard extends LitElement {
|
||||
0
|
||||
);
|
||||
const hasMismatch = Object.values(this._scannerStates).some(
|
||||
(s) => s.current_mode !== s.requested_mode
|
||||
isScannerStateMismatch
|
||||
);
|
||||
const isOffline = adapterCount === 0;
|
||||
const status = isOffline ? "offline" : hasMismatch ? "warning" : "online";
|
||||
|
||||
+23
-2
@@ -1,5 +1,5 @@
|
||||
import type { TemplateResult } from "lit";
|
||||
import { html, LitElement, nothing } from "lit";
|
||||
import type { CSSResultGroup, TemplateResult } from "lit";
|
||||
import { css, html, LitElement, nothing } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { fireEvent } from "../../../../../common/dom/fire_event";
|
||||
import { copyToClipboard } from "../../../../../common/util/copy-clipboard";
|
||||
@@ -121,6 +121,19 @@ class DialogBluetoothDeviceInfo extends LitElement {
|
||||
)}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
${this._params.entry.raw
|
||||
? html`
|
||||
<h4>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.bluetooth.raw_advertisement"
|
||||
)}
|
||||
</h4>
|
||||
<div class="raw">
|
||||
${this.showDataAsHex(this._params.entry.raw)}
|
||||
</div>
|
||||
`
|
||||
: nothing}
|
||||
<ha-dialog-footer slot="footer">
|
||||
<ha-button
|
||||
slot="secondaryAction"
|
||||
@@ -133,6 +146,14 @@ class DialogBluetoothDeviceInfo extends LitElement {
|
||||
</ha-dialog>
|
||||
`;
|
||||
}
|
||||
|
||||
static readonly styles: CSSResultGroup = css`
|
||||
.raw {
|
||||
word-break: break-all;
|
||||
font-family: var(--ha-font-family-code);
|
||||
font-size: var(--ha-font-size-s);
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
||||
declare global {
|
||||
|
||||
@@ -229,9 +229,6 @@ export class HuiEntityEditor extends LitElement {
|
||||
}
|
||||
|
||||
static styles = css`
|
||||
ha-entity-picker {
|
||||
margin-top: 8px;
|
||||
}
|
||||
.entity {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -253,6 +250,11 @@ export class HuiEntityEditor extends LitElement {
|
||||
ha-md-list {
|
||||
gap: 8px;
|
||||
padding-top: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
ha-md-list:has(> *) {
|
||||
margin-bottom: var(--ha-space-2);
|
||||
}
|
||||
ha-md-list-item {
|
||||
border: 1px solid var(--divider-color);
|
||||
|
||||
@@ -2,6 +2,7 @@ import { consume } from "@lit/context";
|
||||
import {
|
||||
mdiChevronDown,
|
||||
mdiChevronRight,
|
||||
mdiChevronLeft,
|
||||
mdiMagnify,
|
||||
mdiTextureBox,
|
||||
} from "@mdi/js";
|
||||
@@ -16,6 +17,7 @@ import { computeEntityName } from "../../../../common/entity/compute_entity_name
|
||||
import { computeStateName } from "../../../../common/entity/compute_state_name";
|
||||
import { computeRTL } from "../../../../common/util/compute_rtl";
|
||||
import { debounce } from "../../../../common/util/debounce";
|
||||
import { mainWindow } from "../../../../common/dom/get_main_window";
|
||||
import "../../../../components/entity/state-badge";
|
||||
import "../../../../components/ha-combo-box-item";
|
||||
import "../../../../components/ha-domain-icon";
|
||||
@@ -294,7 +296,11 @@ export class HuiSuggestionEntityTree extends LitElement {
|
||||
private _renderChevron(expanded: boolean): TemplateResult {
|
||||
return html`<ha-svg-icon
|
||||
class="chevron"
|
||||
.path=${expanded ? mdiChevronDown : mdiChevronRight}
|
||||
.path=${expanded
|
||||
? mdiChevronDown
|
||||
: mainWindow.document.dir === "rtl"
|
||||
? mdiChevronLeft
|
||||
: mdiChevronRight}
|
||||
></ha-svg-icon>`;
|
||||
}
|
||||
|
||||
|
||||
@@ -313,8 +313,7 @@ export const connectionMixin = <T extends Constructor<HassBaseEl>>(
|
||||
});
|
||||
clearInterval(this.__backendPingInterval);
|
||||
|
||||
// Fetch the brands access token on initial connect and schedule refresh
|
||||
fetchAndScheduleBrandsAccessToken(this.hass!);
|
||||
this._refreshBrandsAccessToken();
|
||||
|
||||
this.__backendPingInterval = setInterval(() => {
|
||||
if (this.hass?.connected) {
|
||||
@@ -340,8 +339,7 @@ export const connectionMixin = <T extends Constructor<HassBaseEl>>(
|
||||
this._updateHass({ connected: true });
|
||||
broadcastConnectionStatus("connected");
|
||||
|
||||
// Refresh the brands access token on reconnect and restart refresh schedule
|
||||
fetchAndScheduleBrandsAccessToken(this.hass!);
|
||||
this._refreshBrandsAccessToken();
|
||||
|
||||
// on reconnect always fetch config as we might miss an update while we were disconnected
|
||||
// @ts-ignore
|
||||
@@ -362,4 +360,15 @@ export const connectionMixin = <T extends Constructor<HassBaseEl>>(
|
||||
clearInterval(this.__backendPingInterval);
|
||||
clearBrandsTokenRefresh();
|
||||
}
|
||||
|
||||
private async _refreshBrandsAccessToken() {
|
||||
// The brands WS handler may not be registered yet after a server restart;
|
||||
// fetchAndScheduleBrandsAccessToken retries internally. If the token
|
||||
// changed, re-render so any brand <img> elements that rendered against a
|
||||
// different (or missing) token recompute their src and re-fetch.
|
||||
const changed = await fetchAndScheduleBrandsAccessToken(this.hass!);
|
||||
if (changed) {
|
||||
this._updateHass({});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -7132,6 +7132,7 @@
|
||||
"scanning_mode_passive": "passive",
|
||||
"scanning_mode_active_label": "Active scanning",
|
||||
"scanning_mode_passive_label": "Passive scanning",
|
||||
"scanning_mode_auto_with_current": "Auto ({current})",
|
||||
"scanning_mode_none_label": "No scanning",
|
||||
"scanner_mode_mismatch": "{name} requested {requested} mode but is operating in {current} mode. The scanner is in a bad state and needs to be power cycled.",
|
||||
"scanner_mode_mismatch_remote": "For proxies: reboot the device",
|
||||
@@ -7149,6 +7150,7 @@
|
||||
"manufacturer_data": "Manufacturer data",
|
||||
"service_data": "Service data",
|
||||
"service_uuids": "Service UUIDs",
|
||||
"raw_advertisement": "Raw advertisement",
|
||||
"copy_to_clipboard": "[%key:ui::panel::config::automation::editor::copy_to_clipboard%]",
|
||||
"area": "Area",
|
||||
"scanners": "Scanners",
|
||||
|
||||
+28
-7
@@ -1,3 +1,4 @@
|
||||
import { waitForMs } from "../common/util/wait";
|
||||
import type { HomeAssistant } from "../types";
|
||||
|
||||
export interface BrandsOptions {
|
||||
@@ -20,15 +21,35 @@ let _brandsRefreshInterval: ReturnType<typeof setInterval> | undefined;
|
||||
// Re-fetch every 30 minutes to always have a valid token.
|
||||
const TOKEN_REFRESH_MS = 30 * 60 * 1000;
|
||||
|
||||
export const fetchAndScheduleBrandsAccessToken = (
|
||||
// Delays before each attempt. The first attempt fires immediately; subsequent
|
||||
// ones back off to ride through the window after a Home Assistant restart
|
||||
// where the WebSocket server accepts connections but the brands integration
|
||||
// hasn't registered its WS handler yet. On older backends without the command,
|
||||
// every attempt fails and we give up.
|
||||
const FETCH_DELAYS_MS = [0, 500, 1000, 2000, 5000, 10000, 15000];
|
||||
|
||||
// Returns true if the cached token changed as a result of this call, so
|
||||
// callers can decide whether they need to trigger a re-render.
|
||||
export const fetchAndScheduleBrandsAccessToken = async (
|
||||
hass: HomeAssistant
|
||||
): Promise<void> =>
|
||||
fetchBrandsAccessToken(hass).then(
|
||||
() => scheduleBrandsTokenRefresh(hass),
|
||||
() => {
|
||||
// Ignore failures; older backends may not support this command
|
||||
): Promise<boolean> => {
|
||||
const previousToken = _brandsAccessToken;
|
||||
/* eslint-disable no-await-in-loop -- retries are intentionally sequential */
|
||||
for (const delay of FETCH_DELAYS_MS) {
|
||||
if (delay) {
|
||||
await waitForMs(delay);
|
||||
}
|
||||
);
|
||||
try {
|
||||
await fetchBrandsAccessToken(hass);
|
||||
scheduleBrandsTokenRefresh(hass);
|
||||
return _brandsAccessToken !== previousToken;
|
||||
} catch {
|
||||
// try next delay
|
||||
}
|
||||
}
|
||||
/* eslint-enable no-await-in-loop */
|
||||
return false;
|
||||
};
|
||||
|
||||
export const fetchBrandsAccessToken = async (
|
||||
hass: HomeAssistant
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import type { BluetoothScannerState } from "../../src/data/bluetooth";
|
||||
import { isScannerStateMismatch } from "../../src/data/bluetooth";
|
||||
|
||||
const state = (
|
||||
overrides: Partial<BluetoothScannerState>
|
||||
): BluetoothScannerState => ({
|
||||
source: "AA:BB:CC:DD:EE:FF",
|
||||
adapter: "hci0",
|
||||
current_mode: null,
|
||||
requested_mode: null,
|
||||
...overrides,
|
||||
});
|
||||
|
||||
describe("isScannerStateMismatch", () => {
|
||||
it("is never a mismatch when requested mode is auto", () => {
|
||||
expect(
|
||||
isScannerStateMismatch(
|
||||
state({ requested_mode: "auto", current_mode: "passive" })
|
||||
)
|
||||
).toBe(false);
|
||||
expect(
|
||||
isScannerStateMismatch(
|
||||
state({ requested_mode: "auto", current_mode: "active" })
|
||||
)
|
||||
).toBe(false);
|
||||
expect(
|
||||
isScannerStateMismatch(
|
||||
state({ requested_mode: "auto", current_mode: null })
|
||||
)
|
||||
).toBe(false);
|
||||
});
|
||||
|
||||
it("flags a mismatch when requested and current differ", () => {
|
||||
expect(
|
||||
isScannerStateMismatch(
|
||||
state({ requested_mode: "active", current_mode: "passive" })
|
||||
)
|
||||
).toBe(true);
|
||||
expect(
|
||||
isScannerStateMismatch(
|
||||
state({ requested_mode: "passive", current_mode: "active" })
|
||||
)
|
||||
).toBe(true);
|
||||
expect(
|
||||
isScannerStateMismatch(
|
||||
state({ requested_mode: "active", current_mode: null })
|
||||
)
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
it("is not a mismatch when requested and current agree", () => {
|
||||
expect(
|
||||
isScannerStateMismatch(
|
||||
state({ requested_mode: "active", current_mode: "active" })
|
||||
)
|
||||
).toBe(false);
|
||||
expect(
|
||||
isScannerStateMismatch(
|
||||
state({ requested_mode: "passive", current_mode: "passive" })
|
||||
)
|
||||
).toBe(false);
|
||||
});
|
||||
});
|
||||
@@ -4,6 +4,7 @@ import {
|
||||
addBrandsAuth,
|
||||
brandsUrl,
|
||||
clearBrandsTokenRefresh,
|
||||
fetchAndScheduleBrandsAccessToken,
|
||||
fetchBrandsAccessToken,
|
||||
scheduleBrandsTokenRefresh,
|
||||
} from "../../src/util/brands-url";
|
||||
@@ -169,3 +170,83 @@ describe("scheduleBrandsTokenRefresh", () => {
|
||||
assert.strictEqual(callCount, 1);
|
||||
});
|
||||
});
|
||||
|
||||
describe("fetchAndScheduleBrandsAccessToken", () => {
|
||||
afterEach(() => {
|
||||
clearBrandsTokenRefresh();
|
||||
vi.restoreAllMocks();
|
||||
vi.useRealTimers();
|
||||
});
|
||||
|
||||
it("retries with backoff until the WS call succeeds, returns true when the token changed", async () => {
|
||||
vi.useFakeTimers();
|
||||
let callCount = 0;
|
||||
const mockHass = {
|
||||
callWS: async () => {
|
||||
callCount++;
|
||||
if (callCount < 3) {
|
||||
throw new Error("unknown_command");
|
||||
}
|
||||
return { token: `retry-token-${callCount}` };
|
||||
},
|
||||
} as unknown as HomeAssistant;
|
||||
|
||||
const promise = fetchAndScheduleBrandsAccessToken(mockHass);
|
||||
|
||||
// First attempt fires immediately, fails
|
||||
await vi.advanceTimersByTimeAsync(0);
|
||||
assert.strictEqual(callCount, 1);
|
||||
|
||||
// 500ms backoff → second attempt fails
|
||||
await vi.advanceTimersByTimeAsync(500);
|
||||
assert.strictEqual(callCount, 2);
|
||||
|
||||
// 1000ms backoff → third attempt succeeds
|
||||
await vi.advanceTimersByTimeAsync(1000);
|
||||
|
||||
const changed = await promise;
|
||||
assert.strictEqual(changed, true);
|
||||
assert.strictEqual(callCount, 3);
|
||||
assert.strictEqual(
|
||||
brandsUrl(
|
||||
{ domain: "test", type: "icon" },
|
||||
"http://homeassistant.local:8123"
|
||||
),
|
||||
"http://homeassistant.local:8123/api/brands/integration/test/icon.png?token=retry-token-3"
|
||||
);
|
||||
});
|
||||
|
||||
it("returns false when the backend returns the same token (no UI change needed)", async () => {
|
||||
const mockHass = {
|
||||
callWS: async () => ({ token: "stable-token" }),
|
||||
} as unknown as HomeAssistant;
|
||||
|
||||
// Prime the cached token
|
||||
await fetchBrandsAccessToken(mockHass);
|
||||
|
||||
// Same token returned → no change
|
||||
const changed = await fetchAndScheduleBrandsAccessToken(mockHass);
|
||||
assert.strictEqual(changed, false);
|
||||
});
|
||||
|
||||
it("returns false after all retries fail (e.g. older backend)", async () => {
|
||||
vi.useFakeTimers();
|
||||
let callCount = 0;
|
||||
const mockHass = {
|
||||
callWS: async () => {
|
||||
callCount++;
|
||||
throw new Error("unknown_command");
|
||||
},
|
||||
} as unknown as HomeAssistant;
|
||||
|
||||
const promise = fetchAndScheduleBrandsAccessToken(mockHass);
|
||||
|
||||
// Exhaust all retry delays: 500 + 1000 + 2000 + 5000 + 10000 + 15000
|
||||
await vi.advanceTimersByTimeAsync(33500);
|
||||
|
||||
const changed = await promise;
|
||||
assert.strictEqual(changed, false);
|
||||
// 1 immediate attempt + 6 retries = 7 attempts
|
||||
assert.strictEqual(callCount, 7);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# Manual changes might be lost - proceed with caution!
|
||||
|
||||
__metadata:
|
||||
version: 9
|
||||
version: 10
|
||||
cacheKey: 10
|
||||
|
||||
"@apideck/better-ajv-errors@npm:^0.3.1":
|
||||
@@ -1469,10 +1469,10 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@date-fns/tz@npm:1.4.1":
|
||||
version: 1.4.1
|
||||
resolution: "@date-fns/tz@npm:1.4.1"
|
||||
checksum: 10/062097590005cce3da4c7d9880f9c77d386cff5b4dd58fa3dde3c346a8b2e4f4a8025a613306351a7cad8eb71178a0f67b4840d5884f73aa4c759085fac92063
|
||||
"@date-fns/tz@npm:1.5.0":
|
||||
version: 1.5.0
|
||||
resolution: "@date-fns/tz@npm:1.5.0"
|
||||
checksum: 10/a629879b1f307429e0a00a92dea71e19f63398ba304ee0f58f4d141d50c3058d678c4095b25962f7e5fda508c70502811dd565e58df99e5632dc16097da184a8
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -1660,12 +1660,12 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@formatjs/icu-messageformat-parser@npm:3.5.9":
|
||||
version: 3.5.9
|
||||
resolution: "@formatjs/icu-messageformat-parser@npm:3.5.9"
|
||||
"@formatjs/icu-messageformat-parser@npm:3.5.10":
|
||||
version: 3.5.10
|
||||
resolution: "@formatjs/icu-messageformat-parser@npm:3.5.10"
|
||||
dependencies:
|
||||
"@formatjs/icu-skeleton-parser": "npm:2.1.9"
|
||||
checksum: 10/b2543274b8359873ea279139c9da3ab0f42421651b28855c63d2ca7768a747e662f30ff3d296a1807425d08f1b3ae84376372289749da2fb17ba342e9686673a
|
||||
checksum: 10/44392248b9247cf83a21b43c749025bfbc23acd63782b9a1b7dc47bf5520b686f8a5dccfa56716bc81fe0680000029aba22f5eb5c821ec529646758bd2d6af79
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -3676,51 +3676,51 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@rspack/binding-darwin-arm64@npm:2.0.3":
|
||||
version: 2.0.3
|
||||
resolution: "@rspack/binding-darwin-arm64@npm:2.0.3"
|
||||
"@rspack/binding-darwin-arm64@npm:2.0.4":
|
||||
version: 2.0.4
|
||||
resolution: "@rspack/binding-darwin-arm64@npm:2.0.4"
|
||||
conditions: os=darwin & cpu=arm64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@rspack/binding-darwin-x64@npm:2.0.3":
|
||||
version: 2.0.3
|
||||
resolution: "@rspack/binding-darwin-x64@npm:2.0.3"
|
||||
"@rspack/binding-darwin-x64@npm:2.0.4":
|
||||
version: 2.0.4
|
||||
resolution: "@rspack/binding-darwin-x64@npm:2.0.4"
|
||||
conditions: os=darwin & cpu=x64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@rspack/binding-linux-arm64-gnu@npm:2.0.3":
|
||||
version: 2.0.3
|
||||
resolution: "@rspack/binding-linux-arm64-gnu@npm:2.0.3"
|
||||
"@rspack/binding-linux-arm64-gnu@npm:2.0.4":
|
||||
version: 2.0.4
|
||||
resolution: "@rspack/binding-linux-arm64-gnu@npm:2.0.4"
|
||||
conditions: os=linux & cpu=arm64 & libc=glibc
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@rspack/binding-linux-arm64-musl@npm:2.0.3":
|
||||
version: 2.0.3
|
||||
resolution: "@rspack/binding-linux-arm64-musl@npm:2.0.3"
|
||||
"@rspack/binding-linux-arm64-musl@npm:2.0.4":
|
||||
version: 2.0.4
|
||||
resolution: "@rspack/binding-linux-arm64-musl@npm:2.0.4"
|
||||
conditions: os=linux & cpu=arm64 & libc=musl
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@rspack/binding-linux-x64-gnu@npm:2.0.3":
|
||||
version: 2.0.3
|
||||
resolution: "@rspack/binding-linux-x64-gnu@npm:2.0.3"
|
||||
"@rspack/binding-linux-x64-gnu@npm:2.0.4":
|
||||
version: 2.0.4
|
||||
resolution: "@rspack/binding-linux-x64-gnu@npm:2.0.4"
|
||||
conditions: os=linux & cpu=x64 & libc=glibc
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@rspack/binding-linux-x64-musl@npm:2.0.3":
|
||||
version: 2.0.3
|
||||
resolution: "@rspack/binding-linux-x64-musl@npm:2.0.3"
|
||||
"@rspack/binding-linux-x64-musl@npm:2.0.4":
|
||||
version: 2.0.4
|
||||
resolution: "@rspack/binding-linux-x64-musl@npm:2.0.4"
|
||||
conditions: os=linux & cpu=x64 & libc=musl
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@rspack/binding-wasm32-wasi@npm:2.0.3":
|
||||
version: 2.0.3
|
||||
resolution: "@rspack/binding-wasm32-wasi@npm:2.0.3"
|
||||
"@rspack/binding-wasm32-wasi@npm:2.0.4":
|
||||
version: 2.0.4
|
||||
resolution: "@rspack/binding-wasm32-wasi@npm:2.0.4"
|
||||
dependencies:
|
||||
"@emnapi/core": "npm:1.10.0"
|
||||
"@emnapi/runtime": "npm:1.10.0"
|
||||
@@ -3729,41 +3729,41 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@rspack/binding-win32-arm64-msvc@npm:2.0.3":
|
||||
version: 2.0.3
|
||||
resolution: "@rspack/binding-win32-arm64-msvc@npm:2.0.3"
|
||||
"@rspack/binding-win32-arm64-msvc@npm:2.0.4":
|
||||
version: 2.0.4
|
||||
resolution: "@rspack/binding-win32-arm64-msvc@npm:2.0.4"
|
||||
conditions: os=win32 & cpu=arm64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@rspack/binding-win32-ia32-msvc@npm:2.0.3":
|
||||
version: 2.0.3
|
||||
resolution: "@rspack/binding-win32-ia32-msvc@npm:2.0.3"
|
||||
"@rspack/binding-win32-ia32-msvc@npm:2.0.4":
|
||||
version: 2.0.4
|
||||
resolution: "@rspack/binding-win32-ia32-msvc@npm:2.0.4"
|
||||
conditions: os=win32 & cpu=ia32
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@rspack/binding-win32-x64-msvc@npm:2.0.3":
|
||||
version: 2.0.3
|
||||
resolution: "@rspack/binding-win32-x64-msvc@npm:2.0.3"
|
||||
"@rspack/binding-win32-x64-msvc@npm:2.0.4":
|
||||
version: 2.0.4
|
||||
resolution: "@rspack/binding-win32-x64-msvc@npm:2.0.4"
|
||||
conditions: os=win32 & cpu=x64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@rspack/binding@npm:2.0.3":
|
||||
version: 2.0.3
|
||||
resolution: "@rspack/binding@npm:2.0.3"
|
||||
"@rspack/binding@npm:2.0.4":
|
||||
version: 2.0.4
|
||||
resolution: "@rspack/binding@npm:2.0.4"
|
||||
dependencies:
|
||||
"@rspack/binding-darwin-arm64": "npm:2.0.3"
|
||||
"@rspack/binding-darwin-x64": "npm:2.0.3"
|
||||
"@rspack/binding-linux-arm64-gnu": "npm:2.0.3"
|
||||
"@rspack/binding-linux-arm64-musl": "npm:2.0.3"
|
||||
"@rspack/binding-linux-x64-gnu": "npm:2.0.3"
|
||||
"@rspack/binding-linux-x64-musl": "npm:2.0.3"
|
||||
"@rspack/binding-wasm32-wasi": "npm:2.0.3"
|
||||
"@rspack/binding-win32-arm64-msvc": "npm:2.0.3"
|
||||
"@rspack/binding-win32-ia32-msvc": "npm:2.0.3"
|
||||
"@rspack/binding-win32-x64-msvc": "npm:2.0.3"
|
||||
"@rspack/binding-darwin-arm64": "npm:2.0.4"
|
||||
"@rspack/binding-darwin-x64": "npm:2.0.4"
|
||||
"@rspack/binding-linux-arm64-gnu": "npm:2.0.4"
|
||||
"@rspack/binding-linux-arm64-musl": "npm:2.0.4"
|
||||
"@rspack/binding-linux-x64-gnu": "npm:2.0.4"
|
||||
"@rspack/binding-linux-x64-musl": "npm:2.0.4"
|
||||
"@rspack/binding-wasm32-wasi": "npm:2.0.4"
|
||||
"@rspack/binding-win32-arm64-msvc": "npm:2.0.4"
|
||||
"@rspack/binding-win32-ia32-msvc": "npm:2.0.4"
|
||||
"@rspack/binding-win32-x64-msvc": "npm:2.0.4"
|
||||
dependenciesMeta:
|
||||
"@rspack/binding-darwin-arm64":
|
||||
optional: true
|
||||
@@ -3785,15 +3785,15 @@ __metadata:
|
||||
optional: true
|
||||
"@rspack/binding-win32-x64-msvc":
|
||||
optional: true
|
||||
checksum: 10/21b7510a6945ebab50db8bd54ae5b1e19fb3caf51016c2c21238fe37beb30eacc569f84d17cca924955a9a3b7e6dbed2818b6246b00e7dffbd6d30b164c45874
|
||||
checksum: 10/55832bec03a4c94d6c60a16ebb6484e9c32a6e88cf820874f9873293787d1cbb95ee4276acf5dbf5b6bf6e63d6c9f8e3023efd40f8c2526a52324927b41a9316
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@rspack/core@npm:2.0.3":
|
||||
version: 2.0.3
|
||||
resolution: "@rspack/core@npm:2.0.3"
|
||||
"@rspack/core@npm:2.0.4":
|
||||
version: 2.0.4
|
||||
resolution: "@rspack/core@npm:2.0.4"
|
||||
dependencies:
|
||||
"@rspack/binding": "npm:2.0.3"
|
||||
"@rspack/binding": "npm:2.0.4"
|
||||
peerDependencies:
|
||||
"@module-federation/runtime-tools": ^0.24.1 || ^2.0.0
|
||||
"@swc/helpers": ">=0.5.1"
|
||||
@@ -3802,7 +3802,7 @@ __metadata:
|
||||
optional: true
|
||||
"@swc/helpers":
|
||||
optional: true
|
||||
checksum: 10/71da00e09299a65c7503f775380c66126dfcfbc9a03efb50fab10573db6009b90cccd824fdbbf39c1dc141cb61cd1b66e68b06cfba6abf913b1fba7c860bd02d
|
||||
checksum: 10/49249480a403259e5ee862cbd4694920da1b6ca5aba82146b31e4868430954eccb8a81e93fa730514dd3a39b65aa3fd52dbf0583bce1213086e6aec1a23ff9d1
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -5032,12 +5032,12 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@vitest/coverage-v8@npm:4.1.6":
|
||||
version: 4.1.6
|
||||
resolution: "@vitest/coverage-v8@npm:4.1.6"
|
||||
"@vitest/coverage-v8@npm:4.1.7":
|
||||
version: 4.1.7
|
||||
resolution: "@vitest/coverage-v8@npm:4.1.7"
|
||||
dependencies:
|
||||
"@bcoe/v8-coverage": "npm:^1.0.2"
|
||||
"@vitest/utils": "npm:4.1.6"
|
||||
"@vitest/utils": "npm:4.1.7"
|
||||
ast-v8-to-istanbul: "npm:^1.0.0"
|
||||
istanbul-lib-coverage: "npm:^3.2.2"
|
||||
istanbul-lib-report: "npm:^3.0.1"
|
||||
@@ -5047,34 +5047,34 @@ __metadata:
|
||||
std-env: "npm:^4.0.0-rc.1"
|
||||
tinyrainbow: "npm:^3.1.0"
|
||||
peerDependencies:
|
||||
"@vitest/browser": 4.1.6
|
||||
vitest: 4.1.6
|
||||
"@vitest/browser": 4.1.7
|
||||
vitest: 4.1.7
|
||||
peerDependenciesMeta:
|
||||
"@vitest/browser":
|
||||
optional: true
|
||||
checksum: 10/351ddb5ccebc57ba290b669676db1e24960e4becd9c776a49e2a1ddb02cc2c644870a88010ff044f557fd9082dbe291b8c5e868d562fac93bd02c40d4bedf6bd
|
||||
checksum: 10/ebfe69453f635946449303356fd7b41d6db5ef2449c7e50fe4789930d4b386685c5d8e3587c0fb8ce4010463371dad195471dda2efad673ee26b58d6ff5b7fbe
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@vitest/expect@npm:4.1.6":
|
||||
version: 4.1.6
|
||||
resolution: "@vitest/expect@npm:4.1.6"
|
||||
"@vitest/expect@npm:4.1.7":
|
||||
version: 4.1.7
|
||||
resolution: "@vitest/expect@npm:4.1.7"
|
||||
dependencies:
|
||||
"@standard-schema/spec": "npm:^1.1.0"
|
||||
"@types/chai": "npm:^5.2.2"
|
||||
"@vitest/spy": "npm:4.1.6"
|
||||
"@vitest/utils": "npm:4.1.6"
|
||||
"@vitest/spy": "npm:4.1.7"
|
||||
"@vitest/utils": "npm:4.1.7"
|
||||
chai: "npm:^6.2.2"
|
||||
tinyrainbow: "npm:^3.1.0"
|
||||
checksum: 10/20de26292c543f7f5076b59fd50a5fa89217755402de89b62e5d8c104c90441413b87b5c1d310a682a310418c76c0d4bd309dd1faf13b1b2dec79dc3bb90fef0
|
||||
checksum: 10/a609af6c0497cd510ce8aed099f18faf6d6642bc8eb3432b688f2b39d7354a04d1c4ee9dc28bcfb9d4be701ceac88384d586592a520a324b3773ea43e8a1e677
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@vitest/mocker@npm:4.1.6":
|
||||
version: 4.1.6
|
||||
resolution: "@vitest/mocker@npm:4.1.6"
|
||||
"@vitest/mocker@npm:4.1.7":
|
||||
version: 4.1.7
|
||||
resolution: "@vitest/mocker@npm:4.1.7"
|
||||
dependencies:
|
||||
"@vitest/spy": "npm:4.1.6"
|
||||
"@vitest/spy": "npm:4.1.7"
|
||||
estree-walker: "npm:^3.0.3"
|
||||
magic-string: "npm:^0.30.21"
|
||||
peerDependencies:
|
||||
@@ -5085,56 +5085,56 @@ __metadata:
|
||||
optional: true
|
||||
vite:
|
||||
optional: true
|
||||
checksum: 10/d0669d0b1a8822ec3bc83b5261ead6b05a7e5d8c2077d1f8b9eb0c8507967e54347f16027894be28ca26cf8993e544b8269230a3b78c4eb50c8feb780cb4c688
|
||||
checksum: 10/124d0ec9cc099fde1fca4b065b81a389e9ba2204ecba9729751a0a022d0ffaa34609d9dc60c1f8494ee972c2209035a4476ff1dddc1790e07d1ca28a1103b30d
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@vitest/pretty-format@npm:4.1.6":
|
||||
version: 4.1.6
|
||||
resolution: "@vitest/pretty-format@npm:4.1.6"
|
||||
"@vitest/pretty-format@npm:4.1.7":
|
||||
version: 4.1.7
|
||||
resolution: "@vitest/pretty-format@npm:4.1.7"
|
||||
dependencies:
|
||||
tinyrainbow: "npm:^3.1.0"
|
||||
checksum: 10/28dc121181fdf619e4a9ea4a3279a63974e54567fc59f82462d3b11d4b72d893cd7966f8a7c1a9365c62eae6dee4c6fb08353074486f708aee50b80462d0bd37
|
||||
checksum: 10/79c86c39173577250955744c3444d8c0c9304c95c7d351b91a916229252c3733a0e969741a8f3441a5c4777b5a4371707ecb747ea4bfd2c07e72ddf1ef621293
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@vitest/runner@npm:4.1.6":
|
||||
version: 4.1.6
|
||||
resolution: "@vitest/runner@npm:4.1.6"
|
||||
"@vitest/runner@npm:4.1.7":
|
||||
version: 4.1.7
|
||||
resolution: "@vitest/runner@npm:4.1.7"
|
||||
dependencies:
|
||||
"@vitest/utils": "npm:4.1.6"
|
||||
"@vitest/utils": "npm:4.1.7"
|
||||
pathe: "npm:^2.0.3"
|
||||
checksum: 10/0e175bb61b10ca6cb79a0734a45b3d8b1570806078d53b4f2aa7dbfabd10307c9566460ee8f263a34ac909e8481da614551eee28eaff834fbecd86b4902b845b
|
||||
checksum: 10/429f1e0cc93f66a681d8acc816e21ac41258b07550f9139d004aab103bb06be53e3d91fc66886cef1ba1460a120f5fe4b12d6fe32dafdb1b06740dd119d70f7e
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@vitest/snapshot@npm:4.1.6":
|
||||
version: 4.1.6
|
||||
resolution: "@vitest/snapshot@npm:4.1.6"
|
||||
"@vitest/snapshot@npm:4.1.7":
|
||||
version: 4.1.7
|
||||
resolution: "@vitest/snapshot@npm:4.1.7"
|
||||
dependencies:
|
||||
"@vitest/pretty-format": "npm:4.1.6"
|
||||
"@vitest/utils": "npm:4.1.6"
|
||||
"@vitest/pretty-format": "npm:4.1.7"
|
||||
"@vitest/utils": "npm:4.1.7"
|
||||
magic-string: "npm:^0.30.21"
|
||||
pathe: "npm:^2.0.3"
|
||||
checksum: 10/167b96971ae6e31a8a7c42063abf3d48590908bdea8ae24d9e5035cd08690e47e15a12ab96cc017e5ddd6324a994b8096c901c8e87ac6e5e617910a2814717fd
|
||||
checksum: 10/ef7001add6724c025772891616338e6081ecdb11a92c084ca1d09c4662cf632e5877bec4cb38056aabc311f29fbe149c89fbf332975829087f3817554fe92cde
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@vitest/spy@npm:4.1.6":
|
||||
version: 4.1.6
|
||||
resolution: "@vitest/spy@npm:4.1.6"
|
||||
checksum: 10/6c1bddbf1eaae42af96d66e31f8c14837203707552f60e7a0f512dc2513d285e3de1fdcf057a79a5588fd20ee382ce5a53c1a69430b2a79eb623fd3517d54878
|
||||
"@vitest/spy@npm:4.1.7":
|
||||
version: 4.1.7
|
||||
resolution: "@vitest/spy@npm:4.1.7"
|
||||
checksum: 10/49a9959c615f45ec593379a6d1a238190d08524857a6c4819b724134ce8a1a96d94e20144723d245941ce1ada54d8b00552573810d629880ecb8c3ff03b6d1ad
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@vitest/utils@npm:4.1.6":
|
||||
version: 4.1.6
|
||||
resolution: "@vitest/utils@npm:4.1.6"
|
||||
"@vitest/utils@npm:4.1.7":
|
||||
version: 4.1.7
|
||||
resolution: "@vitest/utils@npm:4.1.7"
|
||||
dependencies:
|
||||
"@vitest/pretty-format": "npm:4.1.6"
|
||||
"@vitest/pretty-format": "npm:4.1.7"
|
||||
convert-source-map: "npm:^2.0.0"
|
||||
tinyrainbow: "npm:^3.1.0"
|
||||
checksum: 10/a81506e9f167389e771503ba5bee91a61cd4f09ac386867815b65c12c9c236051fab6450d686c69b41e3fd028461d0195ee4c4ae47fd22ead649716ddb7777b3
|
||||
checksum: 10/9cc729618dade24de3ad6862c288c22e9daac3fda5cae0abc9b6ce87035cc8e7efa2b66c3c124ae08beef462b36761b062e792bbc619798b832a7ea9382ed12a
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -6999,13 +6999,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"echarts@npm:6.1.0":
|
||||
version: 6.1.0
|
||||
resolution: "echarts@npm:6.1.0"
|
||||
"echarts@npm:6.0.0":
|
||||
version: 6.0.0
|
||||
resolution: "echarts@npm:6.0.0"
|
||||
dependencies:
|
||||
tslib: "npm:2.3.0"
|
||||
zrender: "npm:6.1.0"
|
||||
checksum: 10/ae294b6050a2d7eb377609ae392f76a2db9463b322d12a861c017f5bbab192d59c2b7d618fa2b683cadafd3f37616bb65c5de8ed220421c648bbdb7b4b4c32ea
|
||||
zrender: "npm:6.0.0"
|
||||
checksum: 10/8dbb160cf22e99a2bce04174db756b73e52ba5c00048901c5dbda0c10e6e7b514e5344daa49aa2cdd9c620c9dcc2f4eb15c0614bb2d8a97d9d33e17552ae3655
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -8070,9 +8070,9 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"generate-license-file@npm:4.1.1":
|
||||
version: 4.1.1
|
||||
resolution: "generate-license-file@npm:4.1.1"
|
||||
"generate-license-file@npm:4.2.1":
|
||||
version: 4.2.1
|
||||
resolution: "generate-license-file@npm:4.2.1"
|
||||
dependencies:
|
||||
"@commander-js/extra-typings": "npm:^14.0.0"
|
||||
"@npmcli/arborist": "npm:^9.0.0"
|
||||
@@ -8080,14 +8080,14 @@ __metadata:
|
||||
commander: "npm:^14.0.2"
|
||||
cosmiconfig: "npm:^9.0.0"
|
||||
enquirer: "npm:^2.3.6"
|
||||
glob: "npm:^11.0.0"
|
||||
glob: "npm:^13.0.0"
|
||||
json5: "npm:^2.2.3"
|
||||
ora: "npm:^5.4.1"
|
||||
tslib: "npm:^2.3.0"
|
||||
zod: "npm:^3.21.4"
|
||||
zod: "npm:^4.0.0"
|
||||
bin:
|
||||
generate-license-file: bin/generate-license-file
|
||||
checksum: 10/8a9ed962a5cc8f4851d79df7cd8babbc7dec8fbcc2fe25b6a85babfb497572d933ef5189d6bffc204e31e74aa131760ca0b8a90039997cb9a11df7e948b3edf8
|
||||
checksum: 10/03876abeba28efea39a0fbd4d048e2c0fe1f59477c14e3a5e9f7022235f9197a3f451b7f26124dc09da5cc63140376f53b4ee9167f238eee58241ab954e62efd
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -8272,7 +8272,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"glob@npm:^11.0.0, glob@npm:^11.0.1":
|
||||
"glob@npm:^11.0.1":
|
||||
version: 11.1.0
|
||||
resolution: "glob@npm:11.1.0"
|
||||
dependencies:
|
||||
@@ -8568,7 +8568,7 @@ __metadata:
|
||||
"@codemirror/search": "npm:6.7.0"
|
||||
"@codemirror/state": "npm:6.6.0"
|
||||
"@codemirror/view": "npm:6.43.0"
|
||||
"@date-fns/tz": "npm:1.4.1"
|
||||
"@date-fns/tz": "npm:1.5.0"
|
||||
"@egjs/hammerjs": "npm:2.0.17"
|
||||
"@eslint/js": "npm:10.0.1"
|
||||
"@formatjs/intl-datetimeformat": "npm:7.4.6"
|
||||
@@ -8609,7 +8609,7 @@ __metadata:
|
||||
"@octokit/rest": "npm:22.0.1"
|
||||
"@replit/codemirror-indentation-markers": "npm:6.5.3"
|
||||
"@rsdoctor/rspack-plugin": "npm:1.5.11"
|
||||
"@rspack/core": "npm:2.0.3"
|
||||
"@rspack/core": "npm:2.0.4"
|
||||
"@rspack/dev-server": "npm:2.0.1"
|
||||
"@swc/helpers": "npm:0.5.21"
|
||||
"@thomasloven/round-slider": "npm:0.6.0"
|
||||
@@ -8633,7 +8633,7 @@ __metadata:
|
||||
"@types/tar": "npm:7.0.87"
|
||||
"@types/webspeechapi": "npm:0.0.29"
|
||||
"@vibrant/color": "npm:4.0.4"
|
||||
"@vitest/coverage-v8": "npm:4.1.6"
|
||||
"@vitest/coverage-v8": "npm:4.1.7"
|
||||
"@webcomponents/scoped-custom-element-registry": "npm:0.0.10"
|
||||
"@webcomponents/webcomponentsjs": "npm:2.8.0"
|
||||
babel-loader: "npm:10.1.1"
|
||||
@@ -8651,7 +8651,7 @@ __metadata:
|
||||
deep-freeze: "npm:0.0.1"
|
||||
del: "npm:8.0.1"
|
||||
dialog-polyfill: "npm:0.5.6"
|
||||
echarts: "npm:6.1.0"
|
||||
echarts: "npm:6.0.0"
|
||||
element-internals-polyfill: "npm:3.0.2"
|
||||
eslint: "npm:10.4.0"
|
||||
eslint-config-prettier: "npm:10.1.8"
|
||||
@@ -8664,7 +8664,7 @@ __metadata:
|
||||
fancy-log: "npm:2.0.0"
|
||||
fs-extra: "npm:11.3.5"
|
||||
fuse.js: "npm:7.3.0"
|
||||
generate-license-file: "npm:4.1.1"
|
||||
generate-license-file: "npm:4.2.1"
|
||||
glob: "npm:13.0.6"
|
||||
globals: "npm:17.6.0"
|
||||
google-timezones-json: "npm:1.2.0"
|
||||
@@ -8677,8 +8677,8 @@ __metadata:
|
||||
home-assistant-js-websocket: "npm:9.6.0"
|
||||
html-minifier-terser: "npm:7.2.0"
|
||||
husky: "npm:9.1.7"
|
||||
idb-keyval: "npm:6.2.2"
|
||||
intl-messageformat: "npm:11.2.6"
|
||||
idb-keyval: "npm:6.2.4"
|
||||
intl-messageformat: "npm:11.2.7"
|
||||
js-yaml: "npm:4.1.1"
|
||||
jsdom: "npm:29.1.1"
|
||||
jszip: "npm:3.10.1"
|
||||
@@ -8713,12 +8713,12 @@ __metadata:
|
||||
superstruct: "npm:2.0.2"
|
||||
tar: "npm:7.5.15"
|
||||
terser-webpack-plugin: "npm:5.6.0"
|
||||
tinykeys: "npm:3.1.0"
|
||||
tinykeys: "npm:4.0.0"
|
||||
ts-lit-plugin: "npm:2.0.2"
|
||||
typescript: "npm:6.0.3"
|
||||
typescript-eslint: "npm:8.59.4"
|
||||
vite-tsconfig-paths: "npm:6.1.1"
|
||||
vitest: "npm:4.1.6"
|
||||
vitest: "npm:4.1.7"
|
||||
webpack-stats-plugin: "npm:1.1.3"
|
||||
webpackbar: "npm:7.0.0"
|
||||
weekstart: "npm:2.0.0"
|
||||
@@ -8900,10 +8900,10 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"idb-keyval@npm:6.2.2":
|
||||
version: 6.2.2
|
||||
resolution: "idb-keyval@npm:6.2.2"
|
||||
checksum: 10/8c22342d94deba01066460fe6593f29c78027d0935a6ed7a1da68b28a7a68b89d0830dada4b30d51b779ed1dc1e362007a8939cda651b9ad0807176bd841e8cb
|
||||
"idb-keyval@npm:6.2.4":
|
||||
version: 6.2.4
|
||||
resolution: "idb-keyval@npm:6.2.4"
|
||||
checksum: 10/b1bc874eb582c6bed89dd40a07fe5ca593238b37cded9c604e0cb74b396d2b8caa850519af4467e5ca1b4628682a6102150299db69a393702d0a0718945bc5ec
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -9023,13 +9023,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"intl-messageformat@npm:11.2.6":
|
||||
version: 11.2.6
|
||||
resolution: "intl-messageformat@npm:11.2.6"
|
||||
"intl-messageformat@npm:11.2.7":
|
||||
version: 11.2.7
|
||||
resolution: "intl-messageformat@npm:11.2.7"
|
||||
dependencies:
|
||||
"@formatjs/fast-memoize": "npm:3.1.5"
|
||||
"@formatjs/icu-messageformat-parser": "npm:3.5.9"
|
||||
checksum: 10/a93a33c607be110715d76f532f74c0f34f1a4e39e28822333d8dd801d0e5e3f4f9a82e2d88895c179b7583d4a9135b1e6bb4044a8ce84c17fd67f2d78cfd84e1
|
||||
"@formatjs/icu-messageformat-parser": "npm:3.5.10"
|
||||
checksum: 10/ccd566358c90c7d33fbc71206d46501c18e66dac10cfdab1ea226bc16c3b31d25d987619ef355ca24c5b9f415075d2abe5cf383c69dbbe758bd78e7f72017ab9
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -13434,10 +13434,10 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"tinykeys@npm:3.1.0":
|
||||
version: 3.1.0
|
||||
resolution: "tinykeys@npm:3.1.0"
|
||||
checksum: 10/472c1350b71ff4043acbe158b72431aaf4cecf879a85b4372fdd36871cfd3eb9dbc1e4a7976380a3239066551c027f13d6c6ac5b620f183d61a53707bae9be4c
|
||||
"tinykeys@npm:4.0.0":
|
||||
version: 4.0.0
|
||||
resolution: "tinykeys@npm:4.0.0"
|
||||
checksum: 10/e31dd0345098bffc87c4df2469f9dcc9cf9a519c592f0d774592f1eeee46798adc66e40058dcaad0c2697eec0f3212c09876c480f3b0ae32e938cb080e664651
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -14191,17 +14191,17 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"vitest@npm:4.1.6":
|
||||
version: 4.1.6
|
||||
resolution: "vitest@npm:4.1.6"
|
||||
"vitest@npm:4.1.7":
|
||||
version: 4.1.7
|
||||
resolution: "vitest@npm:4.1.7"
|
||||
dependencies:
|
||||
"@vitest/expect": "npm:4.1.6"
|
||||
"@vitest/mocker": "npm:4.1.6"
|
||||
"@vitest/pretty-format": "npm:4.1.6"
|
||||
"@vitest/runner": "npm:4.1.6"
|
||||
"@vitest/snapshot": "npm:4.1.6"
|
||||
"@vitest/spy": "npm:4.1.6"
|
||||
"@vitest/utils": "npm:4.1.6"
|
||||
"@vitest/expect": "npm:4.1.7"
|
||||
"@vitest/mocker": "npm:4.1.7"
|
||||
"@vitest/pretty-format": "npm:4.1.7"
|
||||
"@vitest/runner": "npm:4.1.7"
|
||||
"@vitest/snapshot": "npm:4.1.7"
|
||||
"@vitest/spy": "npm:4.1.7"
|
||||
"@vitest/utils": "npm:4.1.7"
|
||||
es-module-lexer: "npm:^2.0.0"
|
||||
expect-type: "npm:^1.3.0"
|
||||
magic-string: "npm:^0.30.21"
|
||||
@@ -14219,12 +14219,12 @@ __metadata:
|
||||
"@edge-runtime/vm": "*"
|
||||
"@opentelemetry/api": ^1.9.0
|
||||
"@types/node": ^20.0.0 || ^22.0.0 || >=24.0.0
|
||||
"@vitest/browser-playwright": 4.1.6
|
||||
"@vitest/browser-preview": 4.1.6
|
||||
"@vitest/browser-webdriverio": 4.1.6
|
||||
"@vitest/coverage-istanbul": 4.1.6
|
||||
"@vitest/coverage-v8": 4.1.6
|
||||
"@vitest/ui": 4.1.6
|
||||
"@vitest/browser-playwright": 4.1.7
|
||||
"@vitest/browser-preview": 4.1.7
|
||||
"@vitest/browser-webdriverio": 4.1.7
|
||||
"@vitest/coverage-istanbul": 4.1.7
|
||||
"@vitest/coverage-v8": 4.1.7
|
||||
"@vitest/ui": 4.1.7
|
||||
happy-dom: "*"
|
||||
jsdom: "*"
|
||||
vite: ^6.0.0 || ^7.0.0 || ^8.0.0
|
||||
@@ -14255,7 +14255,7 @@ __metadata:
|
||||
optional: false
|
||||
bin:
|
||||
vitest: vitest.mjs
|
||||
checksum: 10/3816121537930455e5338b5b3305179fa6c68d6cbba50e5d8ca8dcb2c0410887ed38aca61e0d2da9f673af1cc1f20278eef941fc4756644e6f8f96366822b8e6
|
||||
checksum: 10/23ce0ce8bf81856c1acf983c6138efda5d01b60cbdc5734abd0948f3b39cde14ea7bf0981a2ec8a6b05fe7f3658b211116997fd658fcd20c2f5740b5465502ca
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -15099,19 +15099,19 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"zod@npm:^3.21.4":
|
||||
version: 3.25.76
|
||||
resolution: "zod@npm:3.25.76"
|
||||
checksum: 10/f0c963ec40cd96858451d1690404d603d36507c1fc9682f2dae59ab38b578687d542708a7fdbf645f77926f78c9ed558f57c3d3aa226c285f798df0c4da16995
|
||||
"zod@npm:^4.0.0":
|
||||
version: 4.4.3
|
||||
resolution: "zod@npm:4.4.3"
|
||||
checksum: 10/804b9a42aa8f35f2b3c5a8dff906291cb749115f83ee2afe3576d70b5b5c53c965365c7f4967690647a9c54af9838ff232a85ff9577a0a36c44b68bc6cdefe36
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"zrender@npm:6.1.0":
|
||||
version: 6.1.0
|
||||
resolution: "zrender@npm:6.1.0"
|
||||
"zrender@npm:6.0.0":
|
||||
version: 6.0.0
|
||||
resolution: "zrender@npm:6.0.0"
|
||||
dependencies:
|
||||
tslib: "npm:2.3.0"
|
||||
checksum: 10/c6bc87252127ef430cbbd47aa8476b0f8ecec1abade26928c2a46b2b01b0be93818b8741cfe0cfd7a48ffd82816dd9b5169801d6e6f98d1d5f0e08ce9e67d875
|
||||
checksum: 10/d7b6572ebe400d40d9dc6e066a3a5841d4da1fdea3a9c1fd605239e116ffe05553002a351cbb236bcfbf516a41d3bd67f85ef39a43ccc7ffdc5b70a0ceec6aa8
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
||||
Reference in New Issue
Block a user