mirror of
https://github.com/home-assistant/frontend.git
synced 2026-09-28 16:04:00 +01:00
* Remove web components polyfills and ES5 custom elements adapter All supported browsers (legacy floor: Chrome 59, Safari/iOS 12, Firefox 94) have native shadow DOM and custom elements, so the webcomponents bundle, ShadyCSS branch, and lit polyfill-support are unreachable. The legacy build now emits ES2017 classes, so custom-elements-es5-adapter and the window.loadES5Adapter hook (no known third-party consumers) are removed. Also stops shipping the never-loaded dialog-polyfill css and drops both now-unused dependencies. * Remove keyed-es5 Terser workaround The custom keyed directive existed because Terser with ecma: 5 miscompiled the destructured update() parameters (#28732). The legacy build now minifies with ecma: 2017, so the stock lit-html keyed directive works in both builds. * Remove old-browser JS shims and stale ES5 build references Drops the IE-only navigator.msMaxTouchPoints check, replaces the toggleAttribute helper with the native method (polyfilled automatically for Chrome < 69 in the legacy build), and removes babel excludes for the uninstalled proxy-polyfill and unfetch packages. Updates comments that still described the legacy build as ES5. * Remove vendor prefixes for no-longer-supported browsers Deletes -ms- prefixes (IE/EdgeHTML only) and -webkit-/-moz- prefixed declarations that every supported browser understands unprefixed, or that Lightning CSS re-adds automatically from the unprefixed property in production builds. Blocks that only had prefixed user-select now use the standard property (previously Firefox got no user-select there at all). Converts the four -webkit-linear-gradient() declarations - the sole gradient syntax on those sliders - to standard linear-gradient(). * Remove dead html_url custom panel support html_url pointed to an HTML Import, a Polymer-era feature removed from Chrome in 2019 and never shipped elsewhere. The loader has not handled the html type for years (it fell through to a rejection), and core's panel_custom integration no longer accepts the option, so the branch was unreachable. Also drops the ha-panel-${name} legacy tag naming that was keyed on html_url. * Repair list-plugins-and-polyfills script for Babel 8 The audit script died at startup since the Babel 8 update: preset-env no longer exposes lib/debug.js (logPlugin is now inlined locally, built on the public getInclusionReasons helper) and babel-plugin-polyfill-corejs3 v1 no longer ships lib/shipped-proposals.js (list inlined). Instead of invoking the preset with a hand-mocked plugin API - the part that kept drifting - the plugin listing now runs a real transform of an empty file with preset-env in debug mode, declaring the same caller capabilities as babel-loader. The polyfill listing now passes the configured core-js version to core-js-compat, mirroring the provider's own filtering so the report cannot list modules the installed core-js lacks. Output is byte-identical to the direct-invocation approach. Also documents the script in the build-scripts README. * Correct macOS floor for Safari 26 in companion app UA regex Safari 26 ships for macOS 14 Sonoma and 15 Sequoia, not only macOS 26, so the SAFARI_TO_MACOS entry breaking the minimum-supported-macOS pattern would have sent updated macOS 14/15 companion apps to the legacy build once the modern floor reaches Safari 26. * Remove orphaned values left behind by vendor prefix removal * Require macOS 14.6 for Safari 26 in companion app UA regex
367 lines
9.5 KiB
TypeScript
367 lines
9.5 KiB
TypeScript
import type { DurationFormat as FormatJSDurationFormat } from "@formatjs/intl-durationformat";
|
|
import type {
|
|
Auth,
|
|
Connection,
|
|
HassConfig,
|
|
HassEntities,
|
|
HassEntity,
|
|
HassServices,
|
|
HassServiceTarget,
|
|
MessageBase,
|
|
} from "home-assistant-js-websocket";
|
|
import type {
|
|
EntityNameItem,
|
|
EntityNameOptions,
|
|
} from "./common/entity/compute_entity_name_display";
|
|
import type { LocalizeFunc } from "./common/translations/localize";
|
|
import type { AreaRegistryEntry } from "./data/area/area_registry";
|
|
import type { DeviceRegistryEntry } from "./data/device/device_registry";
|
|
import type { EntityRegistryDisplayEntry } from "./data/entity/entity_registry";
|
|
import type { FloorRegistryEntry } from "./data/floor_registry";
|
|
import type {
|
|
CoreFrontendSystemData,
|
|
CoreFrontendUserData,
|
|
} from "./data/frontend";
|
|
import type {
|
|
FrontendLocaleData,
|
|
getHassTranslations,
|
|
} from "./data/translation";
|
|
import type { Themes } from "./data/ws-themes";
|
|
import type { ExternalMessaging } from "./external_app/external_messaging";
|
|
|
|
declare global {
|
|
/* eslint-disable @typescript-eslint/naming-convention */
|
|
var __DEV__: boolean;
|
|
var __DEMO__: boolean;
|
|
var __BUILD__: "modern" | "legacy";
|
|
var __VERSION__: string;
|
|
var __STATIC_PATH__: string;
|
|
var __BACKWARDS_COMPAT__: boolean;
|
|
var __HASS_URL__: string;
|
|
/* eslint-enable @typescript-eslint/naming-convention */
|
|
|
|
interface Window {
|
|
// Custom panel entry point url
|
|
customPanelJS: string;
|
|
}
|
|
|
|
// for fire event
|
|
interface HASSDomEvents {
|
|
"value-changed": {
|
|
value: unknown;
|
|
};
|
|
change: undefined;
|
|
"hass-logout": undefined;
|
|
"config-refresh": undefined;
|
|
"hass-api-called": {
|
|
success: boolean;
|
|
response: unknown;
|
|
};
|
|
}
|
|
|
|
// For loading workers in rspack
|
|
interface ImportMeta {
|
|
url: string;
|
|
}
|
|
|
|
// Intl.DurationFormat is not yet part of the TypeScript standard
|
|
// eslint-disable-next-line @typescript-eslint/no-namespace
|
|
namespace Intl {
|
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
const DurationFormat: typeof FormatJSDurationFormat;
|
|
}
|
|
}
|
|
|
|
export interface ValueChangedEvent<T> extends CustomEvent {
|
|
detail: {
|
|
value: T;
|
|
};
|
|
}
|
|
|
|
export type Constructor<T = any> = new (...args: any[]) => T;
|
|
|
|
export interface ClassElement {
|
|
kind: "field" | "method";
|
|
key: PropertyKey;
|
|
placement: "static" | "prototype" | "own";
|
|
initializer?: (...args) => unknown;
|
|
extras?: ClassElement[];
|
|
finisher?: <T>(cls: Constructor<T>) => undefined | Constructor<T>;
|
|
descriptor?: PropertyDescriptor;
|
|
}
|
|
|
|
export interface Credential {
|
|
auth_provider_type: string;
|
|
auth_provider_id: string;
|
|
}
|
|
|
|
export interface MFAModule {
|
|
id: string;
|
|
name: string;
|
|
enabled: boolean;
|
|
}
|
|
|
|
export interface CurrentUser {
|
|
id: string;
|
|
is_owner: boolean;
|
|
is_admin: boolean;
|
|
name: string;
|
|
credentials: Credential[];
|
|
mfa_modules: MFAModule[];
|
|
}
|
|
|
|
// Currently selected theme and its settings. These are the values stored in local storage.
|
|
// Note: These values are not meant to be used at runtime to check whether dark mode is active
|
|
// or which theme name to use, as this interface represents the config data for the theme picker.
|
|
// The actually active dark mode and theme name can be read from hass.themes.
|
|
export interface ThemeSettings {
|
|
theme: string;
|
|
// Radio box selection for theme picker. Do not use in Lovelace rendering as
|
|
// it can be undefined == auto.
|
|
// Property hass.themes.darkMode carries effective current mode.
|
|
dark?: boolean;
|
|
primaryColor?: string;
|
|
accentColor?: string;
|
|
}
|
|
|
|
export interface PanelInfo<T = Record<string, any> | null> {
|
|
component_name: string;
|
|
config: T;
|
|
icon: string | null;
|
|
title: string | null;
|
|
url_path: string;
|
|
config_panel_domain?: string;
|
|
default_visible?: boolean;
|
|
require_admin?: boolean;
|
|
show_in_sidebar?: boolean;
|
|
}
|
|
|
|
export type Panels = Record<string, PanelInfo>;
|
|
|
|
export interface CalendarViewChanged {
|
|
end: Date;
|
|
start: Date;
|
|
view: string;
|
|
}
|
|
|
|
export type FullCalendarView =
|
|
"dayGridMonth" | "dayGridWeek" | "dayGridDay" | "listWeek";
|
|
|
|
export const THEME_MODES = ["auto", "light", "dark"] as const;
|
|
export type ThemeMode = (typeof THEME_MODES)[number];
|
|
|
|
export interface ToggleButton {
|
|
label: string;
|
|
iconPath?: string;
|
|
value: string;
|
|
}
|
|
|
|
export interface Translation {
|
|
nativeName: string;
|
|
isRTL: boolean;
|
|
hash: string;
|
|
}
|
|
|
|
export interface TranslationMetadata {
|
|
fragments: string[];
|
|
translations: Record<string, Translation>;
|
|
}
|
|
|
|
// eslint-disable-next-line @typescript-eslint/consistent-type-imports
|
|
export type TranslationDict = typeof import("./translations/en.json");
|
|
|
|
export interface IconMetaFile {
|
|
version: string;
|
|
parts: IconMeta[];
|
|
}
|
|
|
|
export interface IconMeta {
|
|
start: string;
|
|
file: string;
|
|
}
|
|
|
|
export interface Notification {
|
|
notification_id: string;
|
|
message: string;
|
|
title: string;
|
|
status: "read" | "unread";
|
|
created_at: string;
|
|
}
|
|
|
|
export type Resources = Record<string, Record<string, string>>;
|
|
|
|
export interface Context {
|
|
id: string;
|
|
parent_id?: string;
|
|
user_id?: string | null;
|
|
}
|
|
|
|
export interface ValuePart {
|
|
type: "value" | "literal" | "unit";
|
|
value: string;
|
|
}
|
|
|
|
export interface ServiceCallResponse<T = any> {
|
|
context: Context;
|
|
response?: T;
|
|
}
|
|
|
|
export interface ServiceCallRequest {
|
|
domain: string;
|
|
service: string;
|
|
serviceData?: Record<string, any>;
|
|
target?: HassServiceTarget;
|
|
}
|
|
|
|
export interface HomeAssistantRegistries {
|
|
entities: Record<string, EntityRegistryDisplayEntry>;
|
|
devices: Record<string, DeviceRegistryEntry>;
|
|
areas: Record<string, AreaRegistryEntry>;
|
|
floors: Record<string, FloorRegistryEntry>;
|
|
}
|
|
|
|
export interface HomeAssistantInternationalization {
|
|
// i18n
|
|
// current effective language in that order:
|
|
// - backend saved user selected language
|
|
// - language in local app storage
|
|
// - browser language
|
|
// - english (en)
|
|
language: string;
|
|
// local stored language, keep that name for backward compatibility
|
|
selectedLanguage: string | null;
|
|
locale: FrontendLocaleData;
|
|
localize: LocalizeFunc;
|
|
translationMetadata: TranslationMetadata;
|
|
loadBackendTranslation(
|
|
category: Parameters<typeof getHassTranslations>[2],
|
|
integrations?: Parameters<typeof getHassTranslations>[3],
|
|
configFlow?: Parameters<typeof getHassTranslations>[4]
|
|
): Promise<LocalizeFunc>;
|
|
loadFragmentTranslation(fragment: string): Promise<LocalizeFunc | undefined>;
|
|
}
|
|
|
|
export type CallWS = <T>(msg: MessageBase) => Promise<T>;
|
|
|
|
export interface HomeAssistantApi {
|
|
callService<T = any>(
|
|
domain: ServiceCallRequest["domain"],
|
|
service: ServiceCallRequest["service"],
|
|
serviceData?: ServiceCallRequest["serviceData"],
|
|
target?: ServiceCallRequest["target"],
|
|
notifyOnError?: boolean,
|
|
returnResponse?: boolean
|
|
): Promise<ServiceCallResponse<T>>;
|
|
callApi<T>(
|
|
method: "GET" | "POST" | "PUT" | "DELETE",
|
|
path: string,
|
|
parameters?: Record<string, any>,
|
|
headers?: Record<string, string>
|
|
): Promise<T>;
|
|
callApiRaw( // introduced in 2024.11
|
|
method: "GET" | "POST" | "PUT" | "DELETE",
|
|
path: string,
|
|
parameters?: Record<string, any>,
|
|
headers?: Record<string, string>,
|
|
signal?: AbortSignal
|
|
): Promise<Response>;
|
|
fetchWithAuth(path: string, init?: Record<string, any>): Promise<Response>;
|
|
sendWS(msg: MessageBase): void;
|
|
callWS: CallWS;
|
|
}
|
|
|
|
export interface HomeAssistantFormatters {
|
|
formatEntityState(stateObj: HassEntity, state?: string): string;
|
|
formatEntityStateToParts(stateObj: HassEntity, state?: string): ValuePart[];
|
|
formatEntityAttributeValue(
|
|
stateObj: HassEntity,
|
|
attribute: string,
|
|
value?: any
|
|
): string;
|
|
formatEntityAttributeValueToParts(
|
|
stateObj: HassEntity,
|
|
attribute: string,
|
|
value?: any
|
|
): ValuePart[];
|
|
formatEntityAttributeName(stateObj: HassEntity, attribute: string): string;
|
|
formatEntityName(
|
|
stateObj: HassEntity,
|
|
type: string | EntityNameItem | EntityNameItem[] | undefined,
|
|
separator?: EntityNameOptions
|
|
): string;
|
|
}
|
|
|
|
export interface HomeAssistantConnection {
|
|
connection: Connection;
|
|
connected: boolean;
|
|
debugConnection: boolean;
|
|
hassUrl(path?): string;
|
|
}
|
|
|
|
export interface HomeAssistantUI {
|
|
themes: Themes;
|
|
selectedTheme: ThemeSettings | null;
|
|
panels: Panels;
|
|
panelUrl: string;
|
|
dockedSidebar: "docked" | "always_hidden" | "auto";
|
|
kioskMode: boolean;
|
|
enableShortcuts: boolean;
|
|
vibrate: boolean;
|
|
suspendWhenHidden: boolean;
|
|
}
|
|
|
|
export type LogFileDisabledReason = "environment";
|
|
|
|
export interface HassLoggingConfig {
|
|
log_file_disabled_reason: LogFileDisabledReason | null;
|
|
}
|
|
|
|
export interface HomeAssistantConfig {
|
|
auth: Auth & { external?: ExternalMessaging };
|
|
config: HassConfig & { logging?: HassLoggingConfig };
|
|
user?: CurrentUser;
|
|
userData?: CoreFrontendUserData;
|
|
systemData?: CoreFrontendSystemData;
|
|
}
|
|
|
|
export interface HomeAssistant
|
|
extends
|
|
HomeAssistantRegistries,
|
|
HomeAssistantInternationalization,
|
|
HomeAssistantApi,
|
|
HomeAssistantFormatters,
|
|
HomeAssistantConnection,
|
|
HomeAssistantUI,
|
|
HomeAssistantConfig {
|
|
states: HassEntities;
|
|
services: HassServices;
|
|
}
|
|
|
|
export interface Route {
|
|
prefix: string;
|
|
path: string;
|
|
}
|
|
|
|
export interface PanelElement extends HTMLElement {
|
|
hass?: HomeAssistant;
|
|
narrow?: boolean;
|
|
route?: Route | null;
|
|
panel?: PanelInfo;
|
|
}
|
|
|
|
export interface LocalizeMixin {
|
|
hass?: HomeAssistant;
|
|
localize: LocalizeFunc;
|
|
}
|
|
|
|
// https://www.jpwilliams.dev/how-to-unpack-the-return-type-of-a-promise-in-typescript
|
|
export type AsyncReturnType<T extends (...args: any) => any> = T extends (
|
|
...args: any
|
|
) => Promise<infer U>
|
|
? U
|
|
: T extends (...args: any) => infer U
|
|
? U
|
|
: never;
|
|
|
|
export type Entries<T> = [keyof T, T[keyof T]][];
|