mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-08 09:56:36 +00:00
Ts all the tests (#1998)
* Convert tests to TypeScript * Add types for tests * Rename files to TS * Fix up test imports * Fix TSC errors * Liiiint * Add types to util method signatures * Some more types
This commit is contained in:
parent
856ef34964
commit
cdb2093ea6
12
package.json
12
package.json
@ -8,8 +8,8 @@
|
|||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "script/build_frontend",
|
"build": "script/build_frontend",
|
||||||
"lint": "eslint src hassio/src gallery/src test-mocha && tslint -c tslint.json 'src/**/*.ts' 'hassio/src/**/*.ts' 'gallery/src/**/*.ts' 'test-mocha/**/*.ts' && polymer lint && tsc",
|
"lint": "eslint src hassio/src gallery/src && tslint 'src/**/*.ts' 'hassio/src/**/*.ts' 'gallery/src/**/*.ts' 'test-mocha/**/*.ts' && polymer lint && tsc",
|
||||||
"mocha": "node_modules/.bin/mocha --opts test-mocha/mocha.opts",
|
"mocha": "node_modules/.bin/ts-mocha -p test-mocha/tsconfig.test.json --opts test-mocha/mocha.opts",
|
||||||
"test": "npm run lint && npm run mocha",
|
"test": "npm run lint && npm run mocha",
|
||||||
"docker_build": "sh ./script/docker_run.sh build $npm_package_version",
|
"docker_build": "sh ./script/docker_run.sh build $npm_package_version",
|
||||||
"bash": "sh ./script/docker_run.sh bash $npm_package_version"
|
"bash": "sh ./script/docker_run.sh bash $npm_package_version"
|
||||||
@ -100,10 +100,12 @@
|
|||||||
"@babel/preset-env": "^7.1.0",
|
"@babel/preset-env": "^7.1.0",
|
||||||
"@babel/preset-typescript": "^7.1.0",
|
"@babel/preset-typescript": "^7.1.0",
|
||||||
"@gfx/zopfli": "^1.0.9",
|
"@gfx/zopfli": "^1.0.9",
|
||||||
|
"@types/chai": "^4.1.7",
|
||||||
|
"@types/mocha": "^5.2.5",
|
||||||
"babel-eslint": "^10",
|
"babel-eslint": "^10",
|
||||||
"babel-loader": "^8.0.4",
|
"babel-loader": "^8.0.4",
|
||||||
"babel-minify-webpack-plugin": "^0.3.1",
|
"babel-minify-webpack-plugin": "^0.3.1",
|
||||||
"chai": "^4.1.2",
|
"chai": "^4.2.0",
|
||||||
"compression-webpack-plugin": "^2.0.0",
|
"compression-webpack-plugin": "^2.0.0",
|
||||||
"copy-webpack-plugin": "^4.5.2",
|
"copy-webpack-plugin": "^4.5.2",
|
||||||
"del": "^3.0.0",
|
"del": "^3.0.0",
|
||||||
@ -126,7 +128,6 @@
|
|||||||
"husky": "^1.1.0",
|
"husky": "^1.1.0",
|
||||||
"lint-staged": "^8.0.2",
|
"lint-staged": "^8.0.2",
|
||||||
"merge-stream": "^1.0.1",
|
"merge-stream": "^1.0.1",
|
||||||
"mocha": "^5.2.0",
|
|
||||||
"parse5": "^5.1.0",
|
"parse5": "^5.1.0",
|
||||||
"polymer-analyzer": "^3.1.2",
|
"polymer-analyzer": "^3.1.2",
|
||||||
"polymer-bundler": "^4.0.2",
|
"polymer-bundler": "^4.0.2",
|
||||||
@ -135,7 +136,8 @@
|
|||||||
"raw-loader": "^0.5.1",
|
"raw-loader": "^0.5.1",
|
||||||
"reify": "^0.18.1",
|
"reify": "^0.18.1",
|
||||||
"require-dir": "^1.0.0",
|
"require-dir": "^1.0.0",
|
||||||
"sinon": "^7.1.0",
|
"sinon": "^7.1.1",
|
||||||
|
"ts-mocha": "^2.0.0",
|
||||||
"tslint": "^5.11.0",
|
"tslint": "^5.11.0",
|
||||||
"tslint-config-prettier": "^1.15.0",
|
"tslint-config-prettier": "^1.15.0",
|
||||||
"tslint-eslint-rules": "^5.4.0",
|
"tslint-eslint-rules": "^5.4.0",
|
||||||
|
@ -1,4 +0,0 @@
|
|||||||
/** Return if a component is loaded. */
|
|
||||||
export default function isComponentLoaded(hass, component) {
|
|
||||||
return hass && hass.config.components.indexOf(component) !== -1;
|
|
||||||
}
|
|
9
src/common/config/is_component_loaded.ts
Normal file
9
src/common/config/is_component_loaded.ts
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
import { HomeAssistant } from "../../types";
|
||||||
|
|
||||||
|
/** Return if a component is loaded. */
|
||||||
|
export default function isComponentLoaded(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
component: string
|
||||||
|
): boolean {
|
||||||
|
return hass && hass.config.components.indexOf(component) !== -1;
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
/** Return if the displaymode is in standalone mode (PWA). */
|
/** Return if the displaymode is in standalone mode (PWA). */
|
||||||
export default function isPwa() {
|
export default function isPwa(): boolean {
|
||||||
return window.matchMedia("(display-mode: standalone)").matches;
|
return window.matchMedia("(display-mode: standalone)").matches;
|
||||||
}
|
}
|
@ -1,4 +0,0 @@
|
|||||||
/** Get the location name from a hass object. */
|
|
||||||
export default function computeLocationName(hass) {
|
|
||||||
return hass && hass.config.location_name;
|
|
||||||
}
|
|
6
src/common/config/location_name.ts
Normal file
6
src/common/config/location_name.ts
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
import { HomeAssistant } from "../../types";
|
||||||
|
|
||||||
|
/** Get the location name from a hass object. */
|
||||||
|
export default function computeLocationName(hass: HomeAssistant): string {
|
||||||
|
return hass && hass.config.location_name;
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
export default function durationToSeconds(duration) {
|
export default function durationToSeconds(duration: string): number {
|
||||||
const parts = duration.split(":").map(Number);
|
const parts = duration.split(":").map(Number);
|
||||||
return parts[0] * 3600 + parts[1] * 60 + parts[2];
|
return parts[0] * 3600 + parts[1] * 60 + parts[2];
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
import fecha from "fecha";
|
import * as fecha from "fecha";
|
||||||
|
|
||||||
// Check for support of native locale string options
|
// Check for support of native locale string options
|
||||||
function toLocaleDateStringSupportsOptions() {
|
function toLocaleDateStringSupportsOptions() {
|
||||||
@ -11,11 +11,10 @@ function toLocaleDateStringSupportsOptions() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default (toLocaleDateStringSupportsOptions()
|
export default (toLocaleDateStringSupportsOptions()
|
||||||
? (dateObj, locales) =>
|
? (dateObj: Date, locales: string) =>
|
||||||
dateObj.toLocaleDateString(locales, {
|
dateObj.toLocaleDateString(locales, {
|
||||||
year: "numeric",
|
year: "numeric",
|
||||||
month: "long",
|
month: "long",
|
||||||
day: "numeric",
|
day: "numeric",
|
||||||
})
|
})
|
||||||
: // eslint-disable-next-line no-unused-vars
|
: (dateObj: Date) => fecha.format(dateObj, "mediumDate"));
|
||||||
(dateObj, locales) => fecha.format(dateObj, "mediumDate"));
|
|
@ -1,4 +1,4 @@
|
|||||||
import fecha from "fecha";
|
import * as fecha from "fecha";
|
||||||
|
|
||||||
// Check for support of native locale string options
|
// Check for support of native locale string options
|
||||||
function toLocaleStringSupportsOptions() {
|
function toLocaleStringSupportsOptions() {
|
||||||
@ -11,7 +11,7 @@ function toLocaleStringSupportsOptions() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default (toLocaleStringSupportsOptions()
|
export default (toLocaleStringSupportsOptions()
|
||||||
? (dateObj, locales) =>
|
? (dateObj: Date, locales: string) =>
|
||||||
dateObj.toLocaleString(locales, {
|
dateObj.toLocaleString(locales, {
|
||||||
year: "numeric",
|
year: "numeric",
|
||||||
month: "long",
|
month: "long",
|
||||||
@ -19,5 +19,4 @@ export default (toLocaleStringSupportsOptions()
|
|||||||
hour: "numeric",
|
hour: "numeric",
|
||||||
minute: "2-digit",
|
minute: "2-digit",
|
||||||
})
|
})
|
||||||
: // eslint-disable-next-line no-unused-vars
|
: (dateObj: Date) => fecha.format(dateObj, "haDateTime"));
|
||||||
(dateObj, locales) => fecha.format(dateObj, "haDateTime"));
|
|
@ -1,4 +1,4 @@
|
|||||||
import fecha from "fecha";
|
import * as fecha from "fecha";
|
||||||
|
|
||||||
// Check for support of native locale string options
|
// Check for support of native locale string options
|
||||||
function toLocaleTimeStringSupportsOptions() {
|
function toLocaleTimeStringSupportsOptions() {
|
||||||
@ -11,10 +11,9 @@ function toLocaleTimeStringSupportsOptions() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default (toLocaleTimeStringSupportsOptions()
|
export default (toLocaleTimeStringSupportsOptions()
|
||||||
? (dateObj, locales) =>
|
? (dateObj: Date, locales: string) =>
|
||||||
dateObj.toLocaleTimeString(locales, {
|
dateObj.toLocaleTimeString(locales, {
|
||||||
hour: "numeric",
|
hour: "numeric",
|
||||||
minute: "2-digit",
|
minute: "2-digit",
|
||||||
})
|
})
|
||||||
: // eslint-disable-next-line no-unused-vars
|
: (dateObj: Date) => fecha.format(dateObj, "shortTime"));
|
||||||
(dateObj, locales) => fecha.format(dateObj, "shortTime"));
|
|
@ -1,33 +0,0 @@
|
|||||||
/** Calculate a string representing a date object as relative time from now.
|
|
||||||
*
|
|
||||||
* Example output: 5 minutes ago, in 3 days.
|
|
||||||
*/
|
|
||||||
const tests = [60, "second", 60, "minute", 24, "hour", 7, "day"];
|
|
||||||
|
|
||||||
export default function relativeTime(dateObj, localize) {
|
|
||||||
let delta = (new Date() - dateObj) / 1000;
|
|
||||||
const tense = delta >= 0 ? "past" : "future";
|
|
||||||
delta = Math.abs(delta);
|
|
||||||
|
|
||||||
for (let i = 0; i < tests.length; i += 2) {
|
|
||||||
if (delta < tests[i]) {
|
|
||||||
delta = Math.floor(delta);
|
|
||||||
const time = localize(
|
|
||||||
`ui.components.relative_time.duration.${tests[i + 1]}`,
|
|
||||||
"count",
|
|
||||||
delta
|
|
||||||
);
|
|
||||||
return localize(`ui.components.relative_time.${tense}`, "time", time);
|
|
||||||
}
|
|
||||||
|
|
||||||
delta /= tests[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
delta = Math.floor(delta);
|
|
||||||
const time = localize(
|
|
||||||
"ui.components.relative_time.duration.week",
|
|
||||||
"count",
|
|
||||||
delta
|
|
||||||
);
|
|
||||||
return localize(`ui.components.relative_time.${tense}`, "time", time);
|
|
||||||
}
|
|
40
src/common/datetime/relative_time.ts
Normal file
40
src/common/datetime/relative_time.ts
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
import { LocalizeFunc } from "../../mixins/localize-base-mixin";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate a string representing a date object as relative time from now.
|
||||||
|
*
|
||||||
|
* Example output: 5 minutes ago, in 3 days.
|
||||||
|
*/
|
||||||
|
const tests = [60, 60, 24, 7];
|
||||||
|
const langKey = ["second", "minute", "hour", "day"];
|
||||||
|
|
||||||
|
export default function relativeTime(
|
||||||
|
dateObj: Date,
|
||||||
|
localize: LocalizeFunc
|
||||||
|
): string {
|
||||||
|
let delta = (new Date().getTime() - dateObj.getTime()) / 1000;
|
||||||
|
const tense = delta >= 0 ? "past" : "future";
|
||||||
|
delta = Math.abs(delta);
|
||||||
|
|
||||||
|
for (let i = 0; i < tests.length; i++) {
|
||||||
|
if (delta < tests[i]) {
|
||||||
|
delta = Math.floor(delta);
|
||||||
|
const timeDesc = localize(
|
||||||
|
`ui.components.relative_time.duration.${langKey[i]}`,
|
||||||
|
"count",
|
||||||
|
delta
|
||||||
|
);
|
||||||
|
return localize(`ui.components.relative_time.${tense}`, "time", timeDesc);
|
||||||
|
}
|
||||||
|
|
||||||
|
delta /= tests[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
delta = Math.floor(delta);
|
||||||
|
const time = localize(
|
||||||
|
"ui.components.relative_time.duration.week",
|
||||||
|
"count",
|
||||||
|
delta
|
||||||
|
);
|
||||||
|
return localize(`ui.components.relative_time.${tense}`, "time", time);
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
const leftPad = (number) => (number < 10 ? `0${number}` : number);
|
const leftPad = (num: number) => (num < 10 ? `0${num}` : num);
|
||||||
|
|
||||||
export default function secondsToDuration(d) {
|
export default function secondsToDuration(d: number) {
|
||||||
const h = Math.floor(d / 3600);
|
const h = Math.floor(d / 3600);
|
||||||
const m = Math.floor((d % 3600) / 60);
|
const m = Math.floor((d % 3600) / 60);
|
||||||
const s = Math.floor((d % 3600) % 60);
|
const s = Math.floor((d % 3600) % 60);
|
@ -1,9 +0,0 @@
|
|||||||
export default function attributeClassNames(stateObj, attributes) {
|
|
||||||
if (!stateObj) return "";
|
|
||||||
return attributes
|
|
||||||
.map(function(attribute) {
|
|
||||||
return attribute in stateObj.attributes ? "has-" + attribute : "";
|
|
||||||
})
|
|
||||||
.filter((attr) => attr !== "")
|
|
||||||
.join(" ");
|
|
||||||
}
|
|
17
src/common/entity/attribute_class_names.ts
Normal file
17
src/common/entity/attribute_class_names.ts
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
import { HassEntity } from "home-assistant-js-websocket";
|
||||||
|
|
||||||
|
export default function attributeClassNames(
|
||||||
|
stateObj: HassEntity,
|
||||||
|
attributes: string[]
|
||||||
|
): string {
|
||||||
|
if (!stateObj) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return attributes
|
||||||
|
.map(
|
||||||
|
(attribute) =>
|
||||||
|
attribute in stateObj.attributes ? "has-" + attribute : ""
|
||||||
|
)
|
||||||
|
.filter((attr) => attr !== "")
|
||||||
|
.join(" ");
|
||||||
|
}
|
@ -1,7 +1,9 @@
|
|||||||
|
import { HassEntity } from "home-assistant-js-websocket";
|
||||||
|
|
||||||
/** Return an icon representing a binary sensor state. */
|
/** Return an icon representing a binary sensor state. */
|
||||||
|
|
||||||
export default function binarySensorIcon(state) {
|
export default function binarySensorIcon(state: HassEntity) {
|
||||||
var activated = state.state && state.state === "off";
|
const activated = state.state && state.state === "off";
|
||||||
switch (state.attributes.device_class) {
|
switch (state.attributes.device_class) {
|
||||||
case "battery":
|
case "battery":
|
||||||
return activated ? "hass:battery" : "hass:battery-outline";
|
return activated ? "hass:battery" : "hass:battery-outline";
|
@ -1,4 +1,6 @@
|
|||||||
export default function canToggleDomain(hass, domain) {
|
import { HomeAssistant } from "../../types";
|
||||||
|
|
||||||
|
export default function canToggleDomain(hass: HomeAssistant, domain: string) {
|
||||||
const services = hass.services[domain];
|
const services = hass.services[domain];
|
||||||
if (!services) {
|
if (!services) {
|
||||||
return false;
|
return false;
|
@ -1,13 +1,19 @@
|
|||||||
|
import { HassEntity } from "home-assistant-js-websocket";
|
||||||
import canToggleDomain from "./can_toggle_domain";
|
import canToggleDomain from "./can_toggle_domain";
|
||||||
import computeStateDomain from "./compute_state_domain";
|
import computeStateDomain from "./compute_state_domain";
|
||||||
|
import { HomeAssistant } from "../../types";
|
||||||
|
|
||||||
export default function canToggleState(hass, stateObj) {
|
export default function canToggleState(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
stateObj: HassEntity
|
||||||
|
) {
|
||||||
const domain = computeStateDomain(stateObj);
|
const domain = computeStateDomain(stateObj);
|
||||||
if (domain === "group") {
|
if (domain === "group") {
|
||||||
return stateObj.state === "on" || stateObj.state === "off";
|
return stateObj.state === "on" || stateObj.state === "off";
|
||||||
}
|
}
|
||||||
if (domain === "climate") {
|
if (domain === "climate") {
|
||||||
return !!((stateObj.attributes || {}).supported_features & 4096);
|
// tslint:disable-next-line
|
||||||
|
return (stateObj.attributes.supported_features! & 4096) !== 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return canToggleDomain(hass, domain);
|
return canToggleDomain(hass, domain);
|
@ -1,3 +0,0 @@
|
|||||||
export default function computeDomain(entityId) {
|
|
||||||
return entityId.substr(0, entityId.indexOf("."));
|
|
||||||
}
|
|
3
src/common/entity/compute_domain.ts
Normal file
3
src/common/entity/compute_domain.ts
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
export default function computeDomain(entityId: string): string {
|
||||||
|
return entityId.substr(0, entityId.indexOf("."));
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
/** Compute the object ID of a state. */
|
/** Compute the object ID of a state. */
|
||||||
export default function computeObjectId(entityId) {
|
export default function computeObjectId(entityId: string): string {
|
||||||
return entityId.substr(entityId.indexOf(".") + 1);
|
return entityId.substr(entityId.indexOf(".") + 1);
|
||||||
}
|
}
|
@ -1,84 +0,0 @@
|
|||||||
import computeStateDomain from "./compute_state_domain";
|
|
||||||
import formatDateTime from "../datetime/format_date_time";
|
|
||||||
import formatDate from "../datetime/format_date";
|
|
||||||
import formatTime from "../datetime/format_time";
|
|
||||||
|
|
||||||
export default function computeStateDisplay(localize, stateObj, language) {
|
|
||||||
if (!stateObj._stateDisplay) {
|
|
||||||
const domain = computeStateDomain(stateObj);
|
|
||||||
if (domain === "binary_sensor") {
|
|
||||||
// Try device class translation, then default binary sensor translation
|
|
||||||
if (stateObj.attributes.device_class) {
|
|
||||||
stateObj._stateDisplay = localize(
|
|
||||||
`state.${domain}.${stateObj.attributes.device_class}.${
|
|
||||||
stateObj.state
|
|
||||||
}`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (!stateObj._stateDisplay) {
|
|
||||||
stateObj._stateDisplay = localize(
|
|
||||||
`state.${domain}.default.${stateObj.state}`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} else if (
|
|
||||||
stateObj.attributes.unit_of_measurement &&
|
|
||||||
!["unknown", "unavailable"].includes(stateObj.state)
|
|
||||||
) {
|
|
||||||
stateObj._stateDisplay =
|
|
||||||
stateObj.state + " " + stateObj.attributes.unit_of_measurement;
|
|
||||||
} else if (domain === "input_datetime") {
|
|
||||||
let date;
|
|
||||||
if (!stateObj.attributes.has_time) {
|
|
||||||
date = new Date(
|
|
||||||
stateObj.attributes.year,
|
|
||||||
stateObj.attributes.month - 1,
|
|
||||||
stateObj.attributes.day
|
|
||||||
);
|
|
||||||
stateObj._stateDisplay = formatDate(date, language);
|
|
||||||
} else if (!stateObj.attributes.has_date) {
|
|
||||||
const now = new Date();
|
|
||||||
date = new Date(
|
|
||||||
// Due to bugs.chromium.org/p/chromium/issues/detail?id=797548
|
|
||||||
// don't use artificial 1970 year.
|
|
||||||
now.getFullYear(),
|
|
||||||
now.getMonth(),
|
|
||||||
now.getDay(),
|
|
||||||
stateObj.attributes.hour,
|
|
||||||
stateObj.attributes.minute
|
|
||||||
);
|
|
||||||
stateObj._stateDisplay = formatTime(date, language);
|
|
||||||
} else {
|
|
||||||
date = new Date(
|
|
||||||
stateObj.attributes.year,
|
|
||||||
stateObj.attributes.month - 1,
|
|
||||||
stateObj.attributes.day,
|
|
||||||
stateObj.attributes.hour,
|
|
||||||
stateObj.attributes.minute
|
|
||||||
);
|
|
||||||
stateObj._stateDisplay = formatDateTime(date, language);
|
|
||||||
}
|
|
||||||
} else if (domain === "zwave") {
|
|
||||||
if (["initializing", "dead"].includes(stateObj.state)) {
|
|
||||||
stateObj._stateDisplay = localize(
|
|
||||||
`state.zwave.query_stage.${stateObj.state}`,
|
|
||||||
"query_stage",
|
|
||||||
stateObj.attributes.query_stage
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
stateObj._stateDisplay = localize(
|
|
||||||
`state.zwave.default.${stateObj.state}`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
stateObj._stateDisplay = localize(`state.${domain}.${stateObj.state}`);
|
|
||||||
}
|
|
||||||
// Fall back to default, component backend translation, or raw state if nothing else matches.
|
|
||||||
stateObj._stateDisplay =
|
|
||||||
stateObj._stateDisplay ||
|
|
||||||
localize(`state.default.${stateObj.state}`) ||
|
|
||||||
localize(`component.${domain}.state.${stateObj.state}`) ||
|
|
||||||
stateObj.state;
|
|
||||||
}
|
|
||||||
|
|
||||||
return stateObj._stateDisplay;
|
|
||||||
}
|
|
91
src/common/entity/compute_state_display.ts
Normal file
91
src/common/entity/compute_state_display.ts
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
import { HassEntity } from "home-assistant-js-websocket";
|
||||||
|
import computeStateDomain from "./compute_state_domain";
|
||||||
|
import formatDateTime from "../datetime/format_date_time";
|
||||||
|
import formatDate from "../datetime/format_date";
|
||||||
|
import formatTime from "../datetime/format_time";
|
||||||
|
import { LocalizeFunc } from "../../mixins/localize-base-mixin";
|
||||||
|
|
||||||
|
type CachedDisplayEntity = HassEntity & {
|
||||||
|
_stateDisplay?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function computeStateDisplay(
|
||||||
|
localize: LocalizeFunc,
|
||||||
|
stateObj: HassEntity,
|
||||||
|
language: string
|
||||||
|
) {
|
||||||
|
const state = stateObj as CachedDisplayEntity;
|
||||||
|
if (!state._stateDisplay) {
|
||||||
|
const domain = computeStateDomain(state);
|
||||||
|
if (domain === "binary_sensor") {
|
||||||
|
// Try device class translation, then default binary sensor translation
|
||||||
|
if (state.attributes.device_class) {
|
||||||
|
state._stateDisplay = localize(
|
||||||
|
`state.${domain}.${state.attributes.device_class}.${state.state}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (!state._stateDisplay) {
|
||||||
|
state._stateDisplay = localize(
|
||||||
|
`state.${domain}.default.${state.state}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else if (
|
||||||
|
state.attributes.unit_of_measurement &&
|
||||||
|
!["unknown", "unavailable"].includes(state.state)
|
||||||
|
) {
|
||||||
|
state._stateDisplay =
|
||||||
|
state.state + " " + state.attributes.unit_of_measurement;
|
||||||
|
} else if (domain === "input_datetime") {
|
||||||
|
let date;
|
||||||
|
if (!state.attributes.has_time) {
|
||||||
|
date = new Date(
|
||||||
|
state.attributes.year,
|
||||||
|
state.attributes.month - 1,
|
||||||
|
state.attributes.day
|
||||||
|
);
|
||||||
|
state._stateDisplay = formatDate(date, language);
|
||||||
|
} else if (!state.attributes.has_date) {
|
||||||
|
const now = new Date();
|
||||||
|
date = new Date(
|
||||||
|
// Due to bugs.chromium.org/p/chromium/issues/detail?id=797548
|
||||||
|
// don't use artificial 1970 year.
|
||||||
|
now.getFullYear(),
|
||||||
|
now.getMonth(),
|
||||||
|
now.getDay(),
|
||||||
|
state.attributes.hour,
|
||||||
|
state.attributes.minute
|
||||||
|
);
|
||||||
|
state._stateDisplay = formatTime(date, language);
|
||||||
|
} else {
|
||||||
|
date = new Date(
|
||||||
|
state.attributes.year,
|
||||||
|
state.attributes.month - 1,
|
||||||
|
state.attributes.day,
|
||||||
|
state.attributes.hour,
|
||||||
|
state.attributes.minute
|
||||||
|
);
|
||||||
|
state._stateDisplay = formatDateTime(date, language);
|
||||||
|
}
|
||||||
|
} else if (domain === "zwave") {
|
||||||
|
if (["initializing", "dead"].includes(state.state)) {
|
||||||
|
state._stateDisplay = localize(
|
||||||
|
`state.zwave.query_stage.${state.state}`,
|
||||||
|
"query_stage",
|
||||||
|
state.attributes.query_stage
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
state._stateDisplay = localize(`state.zwave.default.${state.state}`);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
state._stateDisplay = localize(`state.${domain}.${state.state}`);
|
||||||
|
}
|
||||||
|
// Fall back to default, component backend translation, or raw state if nothing else matches.
|
||||||
|
state._stateDisplay =
|
||||||
|
state._stateDisplay ||
|
||||||
|
localize(`state.default.${state.state}`) ||
|
||||||
|
localize(`component.${domain}.state.${state.state}`) ||
|
||||||
|
state.state;
|
||||||
|
}
|
||||||
|
|
||||||
|
return state._stateDisplay;
|
||||||
|
}
|
@ -1,5 +0,0 @@
|
|||||||
import computeDomain from "./compute_domain";
|
|
||||||
|
|
||||||
export default function computeStateDomain(stateObj) {
|
|
||||||
return computeDomain(stateObj.entity_id);
|
|
||||||
}
|
|
6
src/common/entity/compute_state_domain.ts
Normal file
6
src/common/entity/compute_state_domain.ts
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
import { HassEntity } from "home-assistant-js-websocket";
|
||||||
|
import computeDomain from "./compute_domain";
|
||||||
|
|
||||||
|
export default function computeStateDomain(stateObj: HassEntity) {
|
||||||
|
return computeDomain(stateObj.entity_id);
|
||||||
|
}
|
@ -1,11 +0,0 @@
|
|||||||
import computeObjectId from "./compute_object_id";
|
|
||||||
|
|
||||||
export default function computeStateName(stateObj) {
|
|
||||||
if (stateObj._entityDisplay === undefined) {
|
|
||||||
stateObj._entityDisplay =
|
|
||||||
stateObj.attributes.friendly_name ||
|
|
||||||
computeObjectId(stateObj.entity_id).replace(/_/g, " ");
|
|
||||||
}
|
|
||||||
|
|
||||||
return stateObj._entityDisplay;
|
|
||||||
}
|
|
18
src/common/entity/compute_state_name.ts
Normal file
18
src/common/entity/compute_state_name.ts
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import { HassEntity } from "home-assistant-js-websocket";
|
||||||
|
import computeObjectId from "./compute_object_id";
|
||||||
|
|
||||||
|
type CachedDisplayEntity = HassEntity & {
|
||||||
|
_entityDisplay?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function computeStateName(stateObj: HassEntity) {
|
||||||
|
const state = stateObj as CachedDisplayEntity;
|
||||||
|
|
||||||
|
if (state._entityDisplay === undefined) {
|
||||||
|
state._entityDisplay =
|
||||||
|
state.attributes.friendly_name ||
|
||||||
|
computeObjectId(state.entity_id).replace(/_/g, " ");
|
||||||
|
}
|
||||||
|
|
||||||
|
return state._entityDisplay;
|
||||||
|
}
|
@ -1,8 +1,9 @@
|
|||||||
/** Return an icon representing a cover state. */
|
/** Return an icon representing a cover state. */
|
||||||
|
import { HassEntity } from "home-assistant-js-websocket";
|
||||||
import domainIcon from "./domain_icon";
|
import domainIcon from "./domain_icon";
|
||||||
|
|
||||||
export default function coverIcon(state) {
|
export default function coverIcon(state: HassEntity): string {
|
||||||
var open = state.state && state.state !== "closed";
|
const open = state.state !== "closed";
|
||||||
switch (state.attributes.device_class) {
|
switch (state.attributes.device_class) {
|
||||||
case "garage":
|
case "garage":
|
||||||
return open ? "hass:garage-open" : "hass:garage";
|
return open ? "hass:garage-open" : "hass:garage";
|
@ -44,7 +44,7 @@ const fixedIcons = {
|
|||||||
weblink: "hass:open-in-new",
|
weblink: "hass:open-in-new",
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function domainIcon(domain, state) {
|
export default function domainIcon(domain: string, state?: string): string {
|
||||||
if (domain in fixedIcons) {
|
if (domain in fixedIcons) {
|
||||||
return fixedIcons[domain];
|
return fixedIcons[domain];
|
||||||
}
|
}
|
||||||
@ -93,11 +93,10 @@ export default function domainIcon(domain, state) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
/* eslint-disable no-console */
|
// tslint:disable-next-line
|
||||||
console.warn(
|
console.warn(
|
||||||
"Unable to find icon for domain " + domain + " (" + state + ")"
|
"Unable to find icon for domain " + domain + " (" + state + ")"
|
||||||
);
|
);
|
||||||
/* eslint-enable no-console */
|
|
||||||
return DEFAULT_DOMAIN_ICON;
|
return DEFAULT_DOMAIN_ICON;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,8 +1,9 @@
|
|||||||
|
import { HassEntities, HassEntity } from "home-assistant-js-websocket";
|
||||||
import { DEFAULT_VIEW_ENTITY_ID } from "../const";
|
import { DEFAULT_VIEW_ENTITY_ID } from "../const";
|
||||||
|
|
||||||
// Return an ordered array of available views
|
// Return an ordered array of available views
|
||||||
export default function extractViews(entities) {
|
export default function extractViews(entities: HassEntities): HassEntity[] {
|
||||||
const views = [];
|
const views: HassEntity[] = [];
|
||||||
|
|
||||||
Object.keys(entities).forEach((entityId) => {
|
Object.keys(entities).forEach((entityId) => {
|
||||||
const entity = entities[entityId];
|
const entity = entities[entityId];
|
@ -1,11 +0,0 @@
|
|||||||
// Expects classNames to be an object mapping feature-bit -> className
|
|
||||||
export default function featureClassNames(stateObj, classNames) {
|
|
||||||
if (!stateObj || !stateObj.attributes.supported_features) return "";
|
|
||||||
|
|
||||||
const features = stateObj.attributes.supported_features;
|
|
||||||
|
|
||||||
return Object.keys(classNames)
|
|
||||||
.map((feature) => ((features & feature) !== 0 ? classNames[feature] : ""))
|
|
||||||
.filter((attr) => attr !== "")
|
|
||||||
.join(" ");
|
|
||||||
}
|
|
22
src/common/entity/feature_class_names.ts
Normal file
22
src/common/entity/feature_class_names.ts
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
import { HassEntity } from "home-assistant-js-websocket";
|
||||||
|
|
||||||
|
// Expects classNames to be an object mapping feature-bit -> className
|
||||||
|
export default function featureClassNames(
|
||||||
|
stateObj: HassEntity,
|
||||||
|
classNames: { [feature: number]: string }
|
||||||
|
) {
|
||||||
|
if (!stateObj || !stateObj.attributes.supported_features) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
const features = stateObj.attributes.supported_features;
|
||||||
|
|
||||||
|
return Object.keys(classNames)
|
||||||
|
.map(
|
||||||
|
(feature) =>
|
||||||
|
// tslint:disable-next-line
|
||||||
|
(features & Number(feature)) !== 0 ? classNames[feature] : ""
|
||||||
|
)
|
||||||
|
.filter((attr) => attr !== "")
|
||||||
|
.join(" ");
|
||||||
|
}
|
@ -1,4 +1,10 @@
|
|||||||
export default function getGroupEntities(entities, group) {
|
import { HassEntities } from "home-assistant-js-websocket";
|
||||||
|
import { GroupEntity } from "../../types";
|
||||||
|
|
||||||
|
export default function getGroupEntities(
|
||||||
|
entities: HassEntities,
|
||||||
|
group: GroupEntity
|
||||||
|
) {
|
||||||
const result = {};
|
const result = {};
|
||||||
|
|
||||||
group.attributes.entity_id.forEach((entityId) => {
|
group.attributes.entity_id.forEach((entityId) => {
|
@ -1,9 +1,14 @@
|
|||||||
|
import { HassEntities } from "home-assistant-js-websocket";
|
||||||
import computeDomain from "./compute_domain";
|
import computeDomain from "./compute_domain";
|
||||||
import getGroupEntities from "./get_group_entities";
|
import getGroupEntities from "./get_group_entities";
|
||||||
|
import { GroupEntity } from "../../types";
|
||||||
|
|
||||||
// Return an object containing all entities that the view will show
|
// Return an object containing all entities that the view will show
|
||||||
// including embedded groups.
|
// including embedded groups.
|
||||||
export default function getViewEntities(entities, view) {
|
export default function getViewEntities(
|
||||||
|
entities: HassEntities,
|
||||||
|
view: GroupEntity
|
||||||
|
) {
|
||||||
const viewEntities = {};
|
const viewEntities = {};
|
||||||
|
|
||||||
view.attributes.entity_id.forEach((entityId) => {
|
view.attributes.entity_id.forEach((entityId) => {
|
||||||
@ -13,7 +18,7 @@ export default function getViewEntities(entities, view) {
|
|||||||
viewEntities[entity.entity_id] = entity;
|
viewEntities[entity.entity_id] = entity;
|
||||||
|
|
||||||
if (computeDomain(entity.entity_id) === "group") {
|
if (computeDomain(entity.entity_id) === "group") {
|
||||||
const groupEntities = getGroupEntities(entities, entity);
|
const groupEntities = getGroupEntities(entities, entity as GroupEntity);
|
||||||
|
|
||||||
Object.keys(groupEntities).forEach((grEntityId) => {
|
Object.keys(groupEntities).forEach((grEntityId) => {
|
||||||
const grEntity = groupEntities[grEntityId];
|
const grEntity = groupEntities[grEntityId];
|
@ -1,5 +0,0 @@
|
|||||||
export default function hasLocation(stateObj) {
|
|
||||||
return (
|
|
||||||
"latitude" in stateObj.attributes && "longitude" in stateObj.attributes
|
|
||||||
);
|
|
||||||
}
|
|
7
src/common/entity/has_location.ts
Normal file
7
src/common/entity/has_location.ts
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
import { HassEntity } from "home-assistant-js-websocket";
|
||||||
|
|
||||||
|
export default function hasLocation(stateObj: HassEntity) {
|
||||||
|
return (
|
||||||
|
"latitude" in stateObj.attributes && "longitude" in stateObj.attributes
|
||||||
|
);
|
||||||
|
}
|
@ -1,7 +1,8 @@
|
|||||||
/** Return an icon representing an input datetime state. */
|
/** Return an icon representing an input datetime state. */
|
||||||
import domainIcon from "./domain_icon";
|
import domainIcon from "./domain_icon";
|
||||||
|
import { HassEntity } from "home-assistant-js-websocket";
|
||||||
|
|
||||||
export default function inputDateTimeIcon(state) {
|
export default function inputDateTimeIcon(state: HassEntity): string {
|
||||||
if (!state.attributes.has_date) {
|
if (!state.attributes.has_date) {
|
||||||
return "hass:clock";
|
return "hass:clock";
|
||||||
}
|
}
|
@ -1,4 +1,5 @@
|
|||||||
/** Return an icon representing a sensor state. */
|
/** Return an icon representing a sensor state. */
|
||||||
|
import { HassEntity } from "home-assistant-js-websocket";
|
||||||
import { UNIT_C, UNIT_F } from "../const";
|
import { UNIT_C, UNIT_F } from "../const";
|
||||||
import domainIcon from "./domain_icon";
|
import domainIcon from "./domain_icon";
|
||||||
|
|
||||||
@ -9,17 +10,18 @@ const fixedDeviceClassIcons = {
|
|||||||
pressure: "hass:gauge",
|
pressure: "hass:gauge",
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function sensorIcon(state) {
|
export default function sensorIcon(state: HassEntity) {
|
||||||
const dclass = state.attributes.device_class;
|
const dclass = state.attributes.device_class;
|
||||||
|
|
||||||
if (dclass in fixedDeviceClassIcons) {
|
if (dclass && dclass in fixedDeviceClassIcons) {
|
||||||
return fixedDeviceClassIcons[dclass];
|
return fixedDeviceClassIcons[dclass];
|
||||||
}
|
}
|
||||||
if (dclass === "battery") {
|
if (dclass === "battery") {
|
||||||
if (isNaN(state.state)) {
|
const battery = Number(state.state);
|
||||||
|
if (isNaN(battery)) {
|
||||||
return "hass:battery-unknown";
|
return "hass:battery-unknown";
|
||||||
}
|
}
|
||||||
const batteryRound = Math.round(state.state / 10) * 10;
|
const batteryRound = Math.round(battery / 10) * 10;
|
||||||
if (batteryRound >= 100) {
|
if (batteryRound >= 100) {
|
||||||
return "hass:battery";
|
return "hass:battery";
|
||||||
}
|
}
|
@ -1,11 +1,12 @@
|
|||||||
import computeDomain from "./compute_domain";
|
import computeDomain from "./compute_domain";
|
||||||
|
import { HassEntity, HassEntities } from "home-assistant-js-websocket";
|
||||||
|
|
||||||
// Split a collection into a list of groups and a 'rest' list of ungrouped
|
// Split a collection into a list of groups and a 'rest' list of ungrouped
|
||||||
// entities.
|
// entities.
|
||||||
// Returns { groups: [], ungrouped: {} }
|
// Returns { groups: [], ungrouped: {} }
|
||||||
export default function splitByGroups(entities) {
|
export default function splitByGroups(entities: HassEntities) {
|
||||||
const groups = [];
|
const groups: HassEntity[] = [];
|
||||||
const ungrouped = {};
|
const ungrouped: HassEntities = {};
|
||||||
|
|
||||||
Object.keys(entities).forEach((entityId) => {
|
Object.keys(entities).forEach((entityId) => {
|
||||||
const entity = entities[entityId];
|
const entity = entities[entityId];
|
@ -1,8 +1,13 @@
|
|||||||
|
import { HassEntity } from "home-assistant-js-websocket";
|
||||||
import canToggleState from "./can_toggle_state";
|
import canToggleState from "./can_toggle_state";
|
||||||
import computeStateDomain from "./compute_state_domain";
|
import computeStateDomain from "./compute_state_domain";
|
||||||
import { DOMAINS_WITH_CARD } from "../const";
|
import { DOMAINS_WITH_CARD } from "../const";
|
||||||
|
import { HomeAssistant } from "../../types";
|
||||||
|
|
||||||
export default function stateCardType(hass, stateObj) {
|
export default function stateCardType(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
stateObj: HassEntity
|
||||||
|
) {
|
||||||
if (stateObj.state === "unavailable") {
|
if (stateObj.state === "unavailable") {
|
||||||
return "display";
|
return "display";
|
||||||
}
|
}
|
@ -1,4 +1,5 @@
|
|||||||
/** Return an icon representing a state. */
|
/** Return an icon representing a state. */
|
||||||
|
import { HassEntity } from "home-assistant-js-websocket";
|
||||||
import { DEFAULT_DOMAIN_ICON } from "../const";
|
import { DEFAULT_DOMAIN_ICON } from "../const";
|
||||||
|
|
||||||
import computeDomain from "./compute_domain";
|
import computeDomain from "./compute_domain";
|
||||||
@ -16,7 +17,7 @@ const domainIcons = {
|
|||||||
input_datetime: inputDateTimeIcon,
|
input_datetime: inputDateTimeIcon,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function stateIcon(state) {
|
export default function stateIcon(state: HassEntity) {
|
||||||
if (!state) {
|
if (!state) {
|
||||||
return DEFAULT_DOMAIN_ICON;
|
return DEFAULT_DOMAIN_ICON;
|
||||||
}
|
}
|
@ -1,7 +1,8 @@
|
|||||||
|
import { HassEntity } from "home-assistant-js-websocket";
|
||||||
import computeStateDomain from "./compute_state_domain";
|
import computeStateDomain from "./compute_state_domain";
|
||||||
import { DOMAINS_HIDE_MORE_INFO, DOMAINS_WITH_MORE_INFO } from "../const";
|
import { DOMAINS_HIDE_MORE_INFO, DOMAINS_WITH_MORE_INFO } from "../const";
|
||||||
|
|
||||||
export default function stateMoreInfoType(stateObj) {
|
export default function stateMoreInfoType(stateObj: HassEntity) {
|
||||||
const domain = computeStateDomain(stateObj);
|
const domain = computeStateDomain(stateObj);
|
||||||
|
|
||||||
if (DOMAINS_WITH_MORE_INFO.includes(domain)) {
|
if (DOMAINS_WITH_MORE_INFO.includes(domain)) {
|
@ -5,9 +5,13 @@
|
|||||||
* const states = [state1, state2]
|
* const states = [state1, state2]
|
||||||
* states.sort(statesSortByName);
|
* states.sort(statesSortByName);
|
||||||
*/
|
*/
|
||||||
|
import { HassEntity } from "home-assistant-js-websocket";
|
||||||
import computeStateName from "./compute_state_name";
|
import computeStateName from "./compute_state_name";
|
||||||
|
|
||||||
export default function sortStatesByName(entityA, entityB) {
|
export default function sortStatesByName(
|
||||||
|
entityA: HassEntity,
|
||||||
|
entityB: HassEntity
|
||||||
|
) {
|
||||||
const nameA = computeStateName(entityA);
|
const nameA = computeStateName(entityA);
|
||||||
const nameB = computeStateName(entityB);
|
const nameB = computeStateName(entityB);
|
||||||
if (nameA < nameB) {
|
if (nameA < nameB) {
|
@ -1,11 +1,12 @@
|
|||||||
|
import { HassEntity } from "home-assistant-js-websocket";
|
||||||
import durationToSeconds from "../datetime/duration_to_seconds";
|
import durationToSeconds from "../datetime/duration_to_seconds";
|
||||||
|
|
||||||
export default function timerTimeRemaining(stateObj) {
|
export default function timerTimeRemaining(stateObj: HassEntity) {
|
||||||
let timeRemaining = durationToSeconds(stateObj.attributes.remaining);
|
let timeRemaining = durationToSeconds(stateObj.attributes.remaining);
|
||||||
|
|
||||||
if (stateObj.state === "active") {
|
if (stateObj.state === "active") {
|
||||||
const now = new Date();
|
const now = new Date().getTime();
|
||||||
const madeActive = new Date(stateObj.last_changed);
|
const madeActive = new Date(stateObj.last_changed).getTime();
|
||||||
timeRemaining = Math.max(timeRemaining - (now - madeActive) / 1000, 0);
|
timeRemaining = Math.max(timeRemaining - (now - madeActive) / 1000, 0);
|
||||||
}
|
}
|
||||||
|
|
@ -1,3 +0,0 @@
|
|||||||
export default function validEntityId(entityId) {
|
|
||||||
return /^(\w+)\.(\w+)$/.test(entityId);
|
|
||||||
}
|
|
2
src/common/entity/valid_entity_id.ts
Normal file
2
src/common/entity/valid_entity_id.ts
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
const validEntityId = /^(\w+)\.(\w+)$/;
|
||||||
|
export default validEntityId.test;
|
@ -1,9 +1,11 @@
|
|||||||
export default function parseAspectRatio(input) {
|
export default function parseAspectRatio(input) {
|
||||||
// Handle 16x9, 16:9, 1.78x1, 1.78:1, 1.78
|
// Handle 16x9, 16:9, 1.78x1, 1.78:1, 1.78
|
||||||
// Ignore everything else
|
// Ignore everything else
|
||||||
function parseOrThrow(number) {
|
function parseOrThrow(num) {
|
||||||
const parsed = parseFloat(number);
|
const parsed = parseFloat(num);
|
||||||
if (isNaN(parsed)) throw new Error(`${number} is not a number`);
|
if (isNaN(parsed)) {
|
||||||
|
throw new Error(`${num} is not a number`);
|
||||||
|
}
|
||||||
return parsed;
|
return parsed;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
@ -211,7 +211,11 @@ export class HuiGlanceCard extends hassLocalizeLitMixin(LitElement)
|
|||||||
></state-badge>
|
></state-badge>
|
||||||
${
|
${
|
||||||
this._config!.show_state !== false
|
this._config!.show_state !== false
|
||||||
? html`<div>${computeStateDisplay(this.localize, stateObj)}</div>`
|
? html`<div>${computeStateDisplay(
|
||||||
|
this.localize,
|
||||||
|
stateObj,
|
||||||
|
this.hass!.language
|
||||||
|
)}</div>`
|
||||||
: ""
|
: ""
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
@ -48,7 +48,9 @@ class HuiStateLabelElement extends hassLocalizeLitMixin(LitElement)
|
|||||||
.longPress="${longPress()}"
|
.longPress="${longPress()}"
|
||||||
>
|
>
|
||||||
${this._config.prefix}${
|
${this._config.prefix}${
|
||||||
state ? computeStateDisplay(this.localize, state) : "-"
|
state
|
||||||
|
? computeStateDisplay(this.localize, state, this.hass!.language)
|
||||||
|
: "-"
|
||||||
}${this._config.suffix}
|
}${this._config.suffix}
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
12
src/types.ts
12
src/types.ts
@ -6,6 +6,7 @@ import {
|
|||||||
MessageBase,
|
MessageBase,
|
||||||
HassEntityBase,
|
HassEntityBase,
|
||||||
HassEntityAttributeBase,
|
HassEntityAttributeBase,
|
||||||
|
HassServices,
|
||||||
} from "home-assistant-js-websocket";
|
} from "home-assistant-js-websocket";
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
@ -75,6 +76,7 @@ export interface HomeAssistant {
|
|||||||
connection: Connection;
|
connection: Connection;
|
||||||
connected: boolean;
|
connected: boolean;
|
||||||
states: HassEntities;
|
states: HassEntities;
|
||||||
|
services: HassServices;
|
||||||
config: HassConfig;
|
config: HassConfig;
|
||||||
themes: Themes;
|
themes: Themes;
|
||||||
panels: Panels;
|
panels: Panels;
|
||||||
@ -141,3 +143,13 @@ export type LightEntity = HassEntityBase & {
|
|||||||
hs_color: number[];
|
hs_color: number[];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type GroupEntity = HassEntityBase & {
|
||||||
|
attributes: HassEntityAttributeBase & {
|
||||||
|
entity_id: string[];
|
||||||
|
order: number;
|
||||||
|
auto?: boolean;
|
||||||
|
view?: boolean;
|
||||||
|
control?: "hidden";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
@ -6,12 +6,12 @@ describe("attributeClassNames", () => {
|
|||||||
const attrs = ["mock_attr1", "mock_attr2"];
|
const attrs = ["mock_attr1", "mock_attr2"];
|
||||||
|
|
||||||
it("Skips null states", () => {
|
it("Skips null states", () => {
|
||||||
const stateObj = null;
|
const stateObj: any = null;
|
||||||
assert.strictEqual(attributeClassNames(stateObj, attrs), "");
|
assert.strictEqual(attributeClassNames(stateObj, attrs), "");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Matches no attrbutes", () => {
|
it("Matches no attrbutes", () => {
|
||||||
const stateObj = {
|
const stateObj: any = {
|
||||||
attributes: {
|
attributes: {
|
||||||
other_attr_1: 1,
|
other_attr_1: 1,
|
||||||
other_attr_2: 2,
|
other_attr_2: 2,
|
||||||
@ -21,7 +21,7 @@ describe("attributeClassNames", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("Matches one attrbute", () => {
|
it("Matches one attrbute", () => {
|
||||||
const stateObj = {
|
const stateObj: any = {
|
||||||
attributes: {
|
attributes: {
|
||||||
other_attr_1: 1,
|
other_attr_1: 1,
|
||||||
other_attr_2: 2,
|
other_attr_2: 2,
|
||||||
@ -32,7 +32,7 @@ describe("attributeClassNames", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("Matches two attrbutes", () => {
|
it("Matches two attrbutes", () => {
|
||||||
const stateObj = {
|
const stateObj: any = {
|
||||||
attributes: {
|
attributes: {
|
||||||
other_attr_1: 1,
|
other_attr_1: 1,
|
||||||
other_attr_2: 2,
|
other_attr_2: 2,
|
@ -3,7 +3,7 @@ import { assert } from "chai";
|
|||||||
import canToggleDomain from "../../../src/common/entity/can_toggle_domain";
|
import canToggleDomain from "../../../src/common/entity/can_toggle_domain";
|
||||||
|
|
||||||
describe("canToggleDomain", () => {
|
describe("canToggleDomain", () => {
|
||||||
const hass = {
|
const hass: any = {
|
||||||
services: {
|
services: {
|
||||||
light: {
|
light: {
|
||||||
turn_on: null, // Service keys only need to be present for test
|
turn_on: null, // Service keys only need to be present for test
|
@ -3,7 +3,7 @@ import { assert } from "chai";
|
|||||||
import canToggleState from "../../../src/common/entity/can_toggle_state";
|
import canToggleState from "../../../src/common/entity/can_toggle_state";
|
||||||
|
|
||||||
describe("canToggleState", () => {
|
describe("canToggleState", () => {
|
||||||
const hass = {
|
const hass: any = {
|
||||||
services: {
|
services: {
|
||||||
light: {
|
light: {
|
||||||
turn_on: null, // Service keys only need to be present for test
|
turn_on: null, // Service keys only need to be present for test
|
||||||
@ -13,7 +13,7 @@ describe("canToggleState", () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
it("Detects lights toggle", () => {
|
it("Detects lights toggle", () => {
|
||||||
const stateObj = {
|
const stateObj: any = {
|
||||||
entity_id: "light.bla",
|
entity_id: "light.bla",
|
||||||
state: "on",
|
state: "on",
|
||||||
};
|
};
|
||||||
@ -21,7 +21,7 @@ describe("canToggleState", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("Detects group with toggle", () => {
|
it("Detects group with toggle", () => {
|
||||||
const stateObj = {
|
const stateObj: any = {
|
||||||
entity_id: "group.bla",
|
entity_id: "group.bla",
|
||||||
state: "on",
|
state: "on",
|
||||||
};
|
};
|
||||||
@ -29,7 +29,7 @@ describe("canToggleState", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("Detects group without toggle", () => {
|
it("Detects group without toggle", () => {
|
||||||
const stateObj = {
|
const stateObj: any = {
|
||||||
entity_id: "group.devices",
|
entity_id: "group.devices",
|
||||||
state: "home",
|
state: "home",
|
||||||
};
|
};
|
||||||
@ -37,7 +37,7 @@ describe("canToggleState", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("Detects climate with toggle", () => {
|
it("Detects climate with toggle", () => {
|
||||||
const stateObj = {
|
const stateObj: any = {
|
||||||
entity_id: "climate.bla",
|
entity_id: "climate.bla",
|
||||||
attributes: {
|
attributes: {
|
||||||
supported_features: 4096,
|
supported_features: 4096,
|
||||||
@ -47,8 +47,11 @@ describe("canToggleState", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("Detects climate without toggle", () => {
|
it("Detects climate without toggle", () => {
|
||||||
const stateObj = {
|
const stateObj: any = {
|
||||||
entity_id: "climate.bla",
|
entity_id: "climate.bla",
|
||||||
|
attributes: {
|
||||||
|
supported_features: 0,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
assert.isFalse(canToggleState(hass, stateObj));
|
assert.isFalse(canToggleState(hass, stateObj));
|
||||||
});
|
});
|
@ -3,13 +3,12 @@ import { assert } from "chai";
|
|||||||
import computeStateDisplay from "../../../src/common/entity/compute_state_display";
|
import computeStateDisplay from "../../../src/common/entity/compute_state_display";
|
||||||
|
|
||||||
describe("computeStateDisplay", () => {
|
describe("computeStateDisplay", () => {
|
||||||
const localize = function(message, ...args) {
|
|
||||||
// Mock Localize function for testing
|
// Mock Localize function for testing
|
||||||
return message + (args.length ? ": " + args.join(",") : "");
|
const localize = (message, ...args) =>
|
||||||
};
|
message + (args.length ? ": " + args.join(",") : "");
|
||||||
|
|
||||||
it("Localizes binary sensor defaults", () => {
|
it("Localizes binary sensor defaults", () => {
|
||||||
const stateObj = {
|
const stateObj: any = {
|
||||||
entity_id: "binary_sensor.test",
|
entity_id: "binary_sensor.test",
|
||||||
state: "off",
|
state: "off",
|
||||||
attributes: {},
|
attributes: {},
|
||||||
@ -21,7 +20,7 @@ describe("computeStateDisplay", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("Localizes binary sensor device class", () => {
|
it("Localizes binary sensor device class", () => {
|
||||||
const stateObj = {
|
const stateObj: any = {
|
||||||
entity_id: "binary_sensor.test",
|
entity_id: "binary_sensor.test",
|
||||||
state: "off",
|
state: "off",
|
||||||
attributes: {
|
attributes: {
|
||||||
@ -35,12 +34,13 @@ describe("computeStateDisplay", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("Localizes binary sensor invalid device class", () => {
|
it("Localizes binary sensor invalid device class", () => {
|
||||||
const altLocalize = function(message, ...args) {
|
const altLocalize = (message, ...args) => {
|
||||||
if (message === "state.binary_sensor.invalid_device_class.off")
|
if (message === "state.binary_sensor.invalid_device_class.off") {
|
||||||
return null;
|
return "";
|
||||||
|
}
|
||||||
return localize(message, ...args);
|
return localize(message, ...args);
|
||||||
};
|
};
|
||||||
const stateObj = {
|
const stateObj: any = {
|
||||||
entity_id: "binary_sensor.test",
|
entity_id: "binary_sensor.test",
|
||||||
state: "off",
|
state: "off",
|
||||||
attributes: {
|
attributes: {
|
||||||
@ -54,7 +54,7 @@ describe("computeStateDisplay", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("Localizes sensor value with units", () => {
|
it("Localizes sensor value with units", () => {
|
||||||
const stateObj = {
|
const stateObj: any = {
|
||||||
entity_id: "sensor.test",
|
entity_id: "sensor.test",
|
||||||
state: "123",
|
state: "123",
|
||||||
attributes: {
|
attributes: {
|
||||||
@ -65,11 +65,13 @@ describe("computeStateDisplay", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("Localizes unknown sensor value with units", () => {
|
it("Localizes unknown sensor value with units", () => {
|
||||||
const altLocalize = function(message, ...args) {
|
const altLocalize = (message, ...args) => {
|
||||||
if (message === "state.sensor.unknown") return null;
|
if (message === "state.sensor.unknown") {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
return localize(message, ...args);
|
return localize(message, ...args);
|
||||||
};
|
};
|
||||||
const stateObj = {
|
const stateObj: any = {
|
||||||
entity_id: "sensor.test",
|
entity_id: "sensor.test",
|
||||||
state: "unknown",
|
state: "unknown",
|
||||||
attributes: {
|
attributes: {
|
||||||
@ -83,11 +85,13 @@ describe("computeStateDisplay", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("Localizes unavailable sensor value with units", () => {
|
it("Localizes unavailable sensor value with units", () => {
|
||||||
const altLocalize = function(message, ...args) {
|
const altLocalize = (message, ...args) => {
|
||||||
if (message === "state.sensor.unavailable") return null;
|
if (message === "state.sensor.unavailable") {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
return localize(message, ...args);
|
return localize(message, ...args);
|
||||||
};
|
};
|
||||||
const stateObj = {
|
const stateObj: any = {
|
||||||
entity_id: "sensor.test",
|
entity_id: "sensor.test",
|
||||||
state: "unavailable",
|
state: "unavailable",
|
||||||
attributes: {
|
attributes: {
|
||||||
@ -101,11 +105,13 @@ describe("computeStateDisplay", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("Localizes sensor value with component translation", () => {
|
it("Localizes sensor value with component translation", () => {
|
||||||
const altLocalize = function(message, ...args) {
|
const altLocalize = (message, ...args) => {
|
||||||
if (message !== "component.sensor.state.custom_state") return null;
|
if (message !== "component.sensor.state.custom_state") {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
return localize(message, ...args);
|
return localize(message, ...args);
|
||||||
};
|
};
|
||||||
const stateObj = {
|
const stateObj: any = {
|
||||||
entity_id: "sensor.test",
|
entity_id: "sensor.test",
|
||||||
state: "custom_state",
|
state: "custom_state",
|
||||||
attributes: {},
|
attributes: {},
|
||||||
@ -117,7 +123,7 @@ describe("computeStateDisplay", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("Localizes input_datetime with full date time", () => {
|
it("Localizes input_datetime with full date time", () => {
|
||||||
const stateObj = {
|
const stateObj: any = {
|
||||||
entity_id: "input_datetime.test",
|
entity_id: "input_datetime.test",
|
||||||
state: "123",
|
state: "123",
|
||||||
attributes: {
|
attributes: {
|
||||||
@ -138,7 +144,7 @@ describe("computeStateDisplay", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("Localizes input_datetime with date", () => {
|
it("Localizes input_datetime with date", () => {
|
||||||
const stateObj = {
|
const stateObj: any = {
|
||||||
entity_id: "input_datetime.test",
|
entity_id: "input_datetime.test",
|
||||||
state: "123",
|
state: "123",
|
||||||
attributes: {
|
attributes: {
|
||||||
@ -159,7 +165,7 @@ describe("computeStateDisplay", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("Localizes input_datetime with time", () => {
|
it("Localizes input_datetime with time", () => {
|
||||||
const stateObj = {
|
const stateObj: any = {
|
||||||
entity_id: "input_datetime.test",
|
entity_id: "input_datetime.test",
|
||||||
state: "123",
|
state: "123",
|
||||||
attributes: {
|
attributes: {
|
||||||
@ -180,7 +186,7 @@ describe("computeStateDisplay", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("Localizes zwave ready", () => {
|
it("Localizes zwave ready", () => {
|
||||||
const stateObj = {
|
const stateObj: any = {
|
||||||
entity_id: "zwave.test",
|
entity_id: "zwave.test",
|
||||||
state: "ready",
|
state: "ready",
|
||||||
attributes: {
|
attributes: {
|
||||||
@ -194,7 +200,7 @@ describe("computeStateDisplay", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("Localizes zwave initializing", () => {
|
it("Localizes zwave initializing", () => {
|
||||||
const stateObj = {
|
const stateObj: any = {
|
||||||
entity_id: "zwave.test",
|
entity_id: "zwave.test",
|
||||||
state: "initializing",
|
state: "initializing",
|
||||||
attributes: {
|
attributes: {
|
||||||
@ -208,7 +214,7 @@ describe("computeStateDisplay", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("Localizes cover open", () => {
|
it("Localizes cover open", () => {
|
||||||
const stateObj = {
|
const stateObj: any = {
|
||||||
entity_id: "cover.test",
|
entity_id: "cover.test",
|
||||||
state: "open",
|
state: "open",
|
||||||
attributes: {},
|
attributes: {},
|
||||||
@ -220,11 +226,13 @@ describe("computeStateDisplay", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("Localizes unavailable", () => {
|
it("Localizes unavailable", () => {
|
||||||
const altLocalize = function(message, ...args) {
|
const altLocalize = (message, ...args) => {
|
||||||
if (message === "state.sensor.unavailable") return null;
|
if (message === "state.sensor.unavailable") {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
return localize(message, ...args);
|
return localize(message, ...args);
|
||||||
};
|
};
|
||||||
const stateObj = {
|
const stateObj: any = {
|
||||||
entity_id: "sensor.test",
|
entity_id: "sensor.test",
|
||||||
state: "unavailable",
|
state: "unavailable",
|
||||||
attributes: {},
|
attributes: {},
|
||||||
@ -236,11 +244,11 @@ describe("computeStateDisplay", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("Localizes custom state", () => {
|
it("Localizes custom state", () => {
|
||||||
const altLocalize = function() {
|
const altLocalize = () => {
|
||||||
// No matches can be found
|
// No matches can be found
|
||||||
return null;
|
return "";
|
||||||
};
|
};
|
||||||
const stateObj = {
|
const stateObj: any = {
|
||||||
entity_id: "sensor.test",
|
entity_id: "sensor.test",
|
||||||
state: "My Custom State",
|
state: "My Custom State",
|
||||||
attributes: {},
|
attributes: {},
|
||||||
@ -252,7 +260,7 @@ describe("computeStateDisplay", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("Only calculates state display once per immutable state object", () => {
|
it("Only calculates state display once per immutable state object", () => {
|
||||||
const stateObj = {
|
const stateObj: any = {
|
||||||
entity_id: "cover.test",
|
entity_id: "cover.test",
|
||||||
state: "open",
|
state: "open",
|
||||||
attributes: {},
|
attributes: {},
|
@ -4,7 +4,7 @@ import computeStateDomain from "../../../src/common/entity/compute_state_domain"
|
|||||||
|
|
||||||
describe("computeStateDomain", () => {
|
describe("computeStateDomain", () => {
|
||||||
it("Detects sensor domain", () => {
|
it("Detects sensor domain", () => {
|
||||||
const stateObj = {
|
const stateObj: any = {
|
||||||
entity_id: "sensor.test",
|
entity_id: "sensor.test",
|
||||||
};
|
};
|
||||||
assert.strictEqual(computeStateDomain(stateObj), "sensor");
|
assert.strictEqual(computeStateDomain(stateObj), "sensor");
|
@ -1,4 +1,4 @@
|
|||||||
import assert from "assert";
|
import * as assert from "assert";
|
||||||
|
|
||||||
import extractViews from "../../../src/common/entity/extract_views";
|
import extractViews from "../../../src/common/entity/extract_views";
|
||||||
|
|
@ -1,6 +1,7 @@
|
|||||||
import { assert } from "chai";
|
import { assert } from "chai";
|
||||||
|
|
||||||
import featureClassNames from "../../../src/common/entity/feature_class_names";
|
import featureClassNames from "../../../src/common/entity/feature_class_names";
|
||||||
|
import { HassEntity } from "home-assistant-js-websocket";
|
||||||
|
|
||||||
describe("featureClassNames", () => {
|
describe("featureClassNames", () => {
|
||||||
const classNames = {
|
const classNames = {
|
||||||
@ -12,11 +13,12 @@ describe("featureClassNames", () => {
|
|||||||
|
|
||||||
it("Skips null states", () => {
|
it("Skips null states", () => {
|
||||||
const stateObj = null;
|
const stateObj = null;
|
||||||
assert.strictEqual(featureClassNames(stateObj, classNames), "");
|
assert.strictEqual(featureClassNames(stateObj!, classNames), "");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Matches no features", () => {
|
it("Matches no features", () => {
|
||||||
const stateObj = {
|
// tslint:disable-next-line
|
||||||
|
const stateObj = <HassEntity>{
|
||||||
attributes: {
|
attributes: {
|
||||||
supported_features: 64,
|
supported_features: 64,
|
||||||
},
|
},
|
||||||
@ -25,7 +27,8 @@ describe("featureClassNames", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("Matches one feature", () => {
|
it("Matches one feature", () => {
|
||||||
const stateObj = {
|
// tslint:disable-next-line
|
||||||
|
const stateObj = <HassEntity>{
|
||||||
attributes: {
|
attributes: {
|
||||||
supported_features: 72,
|
supported_features: 72,
|
||||||
},
|
},
|
||||||
@ -37,7 +40,8 @@ describe("featureClassNames", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("Matches two features", () => {
|
it("Matches two features", () => {
|
||||||
const stateObj = {
|
// tslint:disable-next-line
|
||||||
|
const stateObj = <HassEntity>{
|
||||||
attributes: {
|
attributes: {
|
||||||
supported_features: 73,
|
supported_features: 73,
|
||||||
},
|
},
|
@ -1,4 +1,4 @@
|
|||||||
import assert from "assert";
|
import * as assert from "assert";
|
||||||
|
|
||||||
import getGroupEntities from "../../../src/common/entity/get_group_entities";
|
import getGroupEntities from "../../../src/common/entity/get_group_entities";
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
import assert from "assert";
|
import * as assert from "assert";
|
||||||
|
|
||||||
import getViewEntities from "../../../src/common/entity/get_view_entities";
|
import getViewEntities from "../../../src/common/entity/get_view_entities";
|
||||||
|
|
@ -4,7 +4,7 @@ import hasLocation from "../../../src/common/entity/has_location";
|
|||||||
|
|
||||||
describe("hasLocation", () => {
|
describe("hasLocation", () => {
|
||||||
it("flags states with location", () => {
|
it("flags states with location", () => {
|
||||||
const stateObj = {
|
const stateObj: any = {
|
||||||
attributes: {
|
attributes: {
|
||||||
latitude: 12.34,
|
latitude: 12.34,
|
||||||
longitude: 12.34,
|
longitude: 12.34,
|
||||||
@ -13,7 +13,7 @@ describe("hasLocation", () => {
|
|||||||
assert(hasLocation(stateObj));
|
assert(hasLocation(stateObj));
|
||||||
});
|
});
|
||||||
it("does not flag states with only latitude", () => {
|
it("does not flag states with only latitude", () => {
|
||||||
const stateObj = {
|
const stateObj: any = {
|
||||||
attributes: {
|
attributes: {
|
||||||
latitude: 12.34,
|
latitude: 12.34,
|
||||||
},
|
},
|
||||||
@ -21,7 +21,7 @@ describe("hasLocation", () => {
|
|||||||
assert(!hasLocation(stateObj));
|
assert(!hasLocation(stateObj));
|
||||||
});
|
});
|
||||||
it("does not flag states with only longitude", () => {
|
it("does not flag states with only longitude", () => {
|
||||||
const stateObj = {
|
const stateObj: any = {
|
||||||
attributes: {
|
attributes: {
|
||||||
longitude: 12.34,
|
longitude: 12.34,
|
||||||
},
|
},
|
||||||
@ -29,7 +29,7 @@ describe("hasLocation", () => {
|
|||||||
assert(!hasLocation(stateObj));
|
assert(!hasLocation(stateObj));
|
||||||
});
|
});
|
||||||
it("does not flag states with no location", () => {
|
it("does not flag states with no location", () => {
|
||||||
const stateObj = {
|
const stateObj: any = {
|
||||||
attributes: {},
|
attributes: {},
|
||||||
};
|
};
|
||||||
assert(!hasLocation(stateObj));
|
assert(!hasLocation(stateObj));
|
@ -1,4 +1,4 @@
|
|||||||
import assert from "assert";
|
import * as assert from "assert";
|
||||||
|
|
||||||
import splitByGroups from "../../../src/common/entity/split_by_groups";
|
import splitByGroups from "../../../src/common/entity/split_by_groups";
|
||||||
|
|
@ -3,7 +3,7 @@ import { assert } from "chai";
|
|||||||
import stateCardType from "../../../src/common/entity/state_card_type";
|
import stateCardType from "../../../src/common/entity/state_card_type";
|
||||||
|
|
||||||
describe("stateCardType", () => {
|
describe("stateCardType", () => {
|
||||||
const hass = {
|
const hass: any = {
|
||||||
services: {
|
services: {
|
||||||
light: {
|
light: {
|
||||||
turn_on: null, // Service keys only need to be present for test
|
turn_on: null, // Service keys only need to be present for test
|
||||||
@ -13,21 +13,21 @@ describe("stateCardType", () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
it("Returns display for unavailable states", () => {
|
it("Returns display for unavailable states", () => {
|
||||||
const stateObj = {
|
const stateObj: any = {
|
||||||
state: "unavailable",
|
state: "unavailable",
|
||||||
};
|
};
|
||||||
assert.strictEqual(stateCardType(hass, stateObj), "display");
|
assert.strictEqual(stateCardType(hass, stateObj), "display");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Returns media_player for media_player states", () => {
|
it("Returns media_player for media_player states", () => {
|
||||||
const stateObj = {
|
const stateObj: any = {
|
||||||
entity_id: "media_player.bla",
|
entity_id: "media_player.bla",
|
||||||
};
|
};
|
||||||
assert.strictEqual(stateCardType(hass, stateObj), "media_player");
|
assert.strictEqual(stateCardType(hass, stateObj), "media_player");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Returns toggle for states that can toggle", () => {
|
it("Returns toggle for states that can toggle", () => {
|
||||||
const stateObj = {
|
const stateObj: any = {
|
||||||
entity_id: "light.bla",
|
entity_id: "light.bla",
|
||||||
attributes: {},
|
attributes: {},
|
||||||
};
|
};
|
||||||
@ -35,7 +35,7 @@ describe("stateCardType", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("Returns display for states with hidden control", () => {
|
it("Returns display for states with hidden control", () => {
|
||||||
const stateObj = {
|
const stateObj: any = {
|
||||||
entity_id: "light.bla",
|
entity_id: "light.bla",
|
||||||
attributes: {
|
attributes: {
|
||||||
control: "hidden",
|
control: "hidden",
|
||||||
@ -45,7 +45,7 @@ describe("stateCardType", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("Returns display for entities that cannot toggle", () => {
|
it("Returns display for entities that cannot toggle", () => {
|
||||||
const stateObj = {
|
const stateObj: any = {
|
||||||
entity_id: "sensor.bla",
|
entity_id: "sensor.bla",
|
||||||
};
|
};
|
||||||
assert.strictEqual(stateCardType(hass, stateObj), "display");
|
assert.strictEqual(stateCardType(hass, stateObj), "display");
|
@ -4,14 +4,14 @@ import stateMoreInfoType from "../../../src/common/entity/state_more_info_type";
|
|||||||
|
|
||||||
describe("stateMoreInfoType", () => {
|
describe("stateMoreInfoType", () => {
|
||||||
it("Returns media_player for media_player states", () => {
|
it("Returns media_player for media_player states", () => {
|
||||||
const stateObj = {
|
const stateObj: any = {
|
||||||
entity_id: "media_player.bla",
|
entity_id: "media_player.bla",
|
||||||
};
|
};
|
||||||
assert.strictEqual(stateMoreInfoType(stateObj), "media_player");
|
assert.strictEqual(stateMoreInfoType(stateObj), "media_player");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Returns hidden for input_select states", () => {
|
it("Returns hidden for input_select states", () => {
|
||||||
const stateObj = {
|
const stateObj: any = {
|
||||||
entity_id: "input_select.bla",
|
entity_id: "input_select.bla",
|
||||||
attributes: {},
|
attributes: {},
|
||||||
};
|
};
|
||||||
@ -19,7 +19,7 @@ describe("stateMoreInfoType", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("Returns default for switch states", () => {
|
it("Returns default for switch states", () => {
|
||||||
const stateObj = {
|
const stateObj: any = {
|
||||||
entity_id: "switch.bla",
|
entity_id: "switch.bla",
|
||||||
attributes: {},
|
attributes: {},
|
||||||
};
|
};
|
@ -27,7 +27,7 @@ export function createView(entity) {
|
|||||||
return createGroup(entity);
|
return createGroup(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createLightEntity(isOn) {
|
export function createLightEntity(isOn?) {
|
||||||
mockState++;
|
mockState++;
|
||||||
if (isOn === undefined) {
|
if (isOn === undefined) {
|
||||||
isOn = Math.random() > 0.5;
|
isOn = Math.random() > 0.5;
|
@ -1,5 +1,5 @@
|
|||||||
import { assert } from "chai";
|
import { assert } from "chai";
|
||||||
import sinon from "sinon";
|
import * as sinon from "sinon";
|
||||||
|
|
||||||
import timerTimeRemaining from "../../../src/common/entity/timer_time_remaining";
|
import timerTimeRemaining from "../../../src/common/entity/timer_time_remaining";
|
||||||
|
|
||||||
@ -11,7 +11,7 @@ describe("timerTimeRemaining", () => {
|
|||||||
attributes: {
|
attributes: {
|
||||||
remaining: "0:01:05",
|
remaining: "0:01:05",
|
||||||
},
|
},
|
||||||
}),
|
} as any),
|
||||||
65
|
65
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@ -23,7 +23,7 @@ describe("timerTimeRemaining", () => {
|
|||||||
attributes: {
|
attributes: {
|
||||||
remaining: "0:01:05",
|
remaining: "0:01:05",
|
||||||
},
|
},
|
||||||
}),
|
} as any),
|
||||||
65
|
65
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@ -44,7 +44,7 @@ describe("timerTimeRemaining", () => {
|
|||||||
remaining: "0:01:05",
|
remaining: "0:01:05",
|
||||||
},
|
},
|
||||||
last_changed: "2018-01-17T16:15:12Z",
|
last_changed: "2018-01-17T16:15:12Z",
|
||||||
}),
|
} as any),
|
||||||
47
|
47
|
||||||
);
|
);
|
||||||
});
|
});
|
@ -1,4 +1,4 @@
|
|||||||
import assert from "assert";
|
import * as assert from "assert";
|
||||||
|
|
||||||
import parseAspectRatio from "../../../src/common/util/parse-aspect-ratio";
|
import parseAspectRatio from "../../../src/common/util/parse-aspect-ratio";
|
||||||
|
|
@ -1,4 +1,3 @@
|
|||||||
--recursive
|
--recursive
|
||||||
--require reify
|
|
||||||
--timeout 10000
|
--timeout 10000
|
||||||
test-mocha
|
test-mocha/**/*.ts
|
||||||
|
6
test-mocha/tsconfig.test.json
Normal file
6
test-mocha/tsconfig.test.json
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"extends": "../tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"module": "commonjs"
|
||||||
|
}
|
||||||
|
}
|
6
test-mocha/tslint.json
Normal file
6
test-mocha/tslint.json
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"extends": ["../tslint.json"],
|
||||||
|
"rules": {
|
||||||
|
"no-implicit-dependencies": [true, "dev"]
|
||||||
|
}
|
||||||
|
}
|
150
yarn.lock
150
yarn.lock
@ -1372,10 +1372,10 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
any-observable "^0.3.0"
|
any-observable "^0.3.0"
|
||||||
|
|
||||||
"@sinonjs/commons@^1.0.2":
|
"@sinonjs/commons@^1.2.0":
|
||||||
version "1.0.2"
|
version "1.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.0.2.tgz#3e0ac737781627b8844257fadc3d803997d0526e"
|
resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.3.0.tgz#50a2754016b6f30a994ceda6d9a0a8c36adda849"
|
||||||
integrity sha512-WR3dlgqJP4QNrLC4iXN/5/2WaLQQ0VijOOkmflqFGVJ6wLEpbSjo7c0ZeGIdtY8Crk7xBBp87sM6+Mkerz7alw==
|
integrity sha512-j4ZwhaHmwsCb4DlDOIWnI5YyKDNMoNThsmwEpfHx6a1EpsGZ9qYLxP++LMlmBRjtGptGHFsGItJ768snllFWpA==
|
||||||
dependencies:
|
dependencies:
|
||||||
type-detect "4.0.8"
|
type-detect "4.0.8"
|
||||||
|
|
||||||
@ -1449,7 +1449,7 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
"@types/chai" "*"
|
"@types/chai" "*"
|
||||||
|
|
||||||
"@types/chai@*":
|
"@types/chai@*", "@types/chai@^4.1.7":
|
||||||
version "4.1.7"
|
version "4.1.7"
|
||||||
resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.1.7.tgz#1b8e33b61a8c09cbe1f85133071baa0dbf9fa71a"
|
resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.1.7.tgz#1b8e33b61a8c09cbe1f85133071baa0dbf9fa71a"
|
||||||
integrity sha512-2Y8uPt0/jwjhQ6EiluT0XCri1Dbplr0ZxfFXUz+ye13gaqE8u5gL5ppao1JrUYr9cIip5S6MvQzBS7Kke7U9VA==
|
integrity sha512-2Y8uPt0/jwjhQ6EiluT0XCri1Dbplr0ZxfFXUz+ye13gaqE8u5gL5ppao1JrUYr9cIip5S6MvQzBS7Kke7U9VA==
|
||||||
@ -1624,6 +1624,11 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@types/is-windows/-/is-windows-0.2.0.tgz#6f24ee48731d31168ea510610d6dd15e5fc9c6ff"
|
resolved "https://registry.yarnpkg.com/@types/is-windows/-/is-windows-0.2.0.tgz#6f24ee48731d31168ea510610d6dd15e5fc9c6ff"
|
||||||
integrity sha1-byTuSHMdMRaOpRBhDW3RXl/Jxv8=
|
integrity sha1-byTuSHMdMRaOpRBhDW3RXl/Jxv8=
|
||||||
|
|
||||||
|
"@types/json5@^0.0.29":
|
||||||
|
version "0.0.29"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee"
|
||||||
|
integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4=
|
||||||
|
|
||||||
"@types/launchpad@^0.6.0":
|
"@types/launchpad@^0.6.0":
|
||||||
version "0.6.0"
|
version "0.6.0"
|
||||||
resolved "https://registry.yarnpkg.com/@types/launchpad/-/launchpad-0.6.0.tgz#37296109b7f277f6e6c5fd7e0c0706bc918fbb51"
|
resolved "https://registry.yarnpkg.com/@types/launchpad/-/launchpad-0.6.0.tgz#37296109b7f277f6e6c5fd7e0c0706bc918fbb51"
|
||||||
@ -1646,6 +1651,11 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d"
|
resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d"
|
||||||
integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==
|
integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==
|
||||||
|
|
||||||
|
"@types/mocha@^5.2.5":
|
||||||
|
version "5.2.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-5.2.5.tgz#8a4accfc403c124a0bafe8a9fc61a05ec1032073"
|
||||||
|
integrity sha512-lAVp+Kj54ui/vLUFxsJTMtWvZraZxum3w3Nwkble2dNuV5VnPA+Mi2oGX9XYJAaIvZi3tn3cbjS/qcJXRb6Bww==
|
||||||
|
|
||||||
"@types/mz@0.0.29":
|
"@types/mz@0.0.29":
|
||||||
version "0.0.29"
|
version "0.0.29"
|
||||||
resolved "https://registry.yarnpkg.com/@types/mz/-/mz-0.0.29.tgz#bc24728c649973f1c7851e9033f9ce525668c27b"
|
resolved "https://registry.yarnpkg.com/@types/mz/-/mz-0.0.29.tgz#bc24728c649973f1c7851e9033f9ce525668c27b"
|
||||||
@ -3667,11 +3677,6 @@ browser-stdout@1.3.0:
|
|||||||
resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.0.tgz#f351d32969d32fa5d7a5567154263d928ae3bd1f"
|
resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.0.tgz#f351d32969d32fa5d7a5567154263d928ae3bd1f"
|
||||||
integrity sha1-81HTKWnTL6XXpVZxVCY9korjvR8=
|
integrity sha1-81HTKWnTL6XXpVZxVCY9korjvR8=
|
||||||
|
|
||||||
browser-stdout@1.3.1:
|
|
||||||
version "1.3.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60"
|
|
||||||
integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==
|
|
||||||
|
|
||||||
browserify-aes@^1.0.0, browserify-aes@^1.0.4:
|
browserify-aes@^1.0.0, browserify-aes@^1.0.4:
|
||||||
version "1.2.0"
|
version "1.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48"
|
resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48"
|
||||||
@ -3777,7 +3782,7 @@ buffer-fill@^1.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/buffer-fill/-/buffer-fill-1.0.0.tgz#f8f78b76789888ef39f205cd637f68e702122b2c"
|
resolved "https://registry.yarnpkg.com/buffer-fill/-/buffer-fill-1.0.0.tgz#f8f78b76789888ef39f205cd637f68e702122b2c"
|
||||||
integrity sha1-+PeLdniYiO858gXNY39o5wISKyw=
|
integrity sha1-+PeLdniYiO858gXNY39o5wISKyw=
|
||||||
|
|
||||||
buffer-from@^1.0.0:
|
buffer-from@^1.0.0, buffer-from@^1.1.0:
|
||||||
version "1.1.1"
|
version "1.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef"
|
resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef"
|
||||||
integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==
|
integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==
|
||||||
@ -3965,7 +3970,7 @@ chai@^3.5.0:
|
|||||||
deep-eql "^0.1.3"
|
deep-eql "^0.1.3"
|
||||||
type-detect "^1.0.0"
|
type-detect "^1.0.0"
|
||||||
|
|
||||||
chai@^4.1.2:
|
chai@^4.2.0:
|
||||||
version "4.2.0"
|
version "4.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/chai/-/chai-4.2.0.tgz#760aa72cf20e3795e84b12877ce0e83737aa29e5"
|
resolved "https://registry.yarnpkg.com/chai/-/chai-4.2.0.tgz#760aa72cf20e3795e84b12877ce0e83737aa29e5"
|
||||||
integrity sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==
|
integrity sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==
|
||||||
@ -4369,7 +4374,7 @@ command-line-usage@^5.0.5:
|
|||||||
table-layout "^0.4.3"
|
table-layout "^0.4.3"
|
||||||
typical "^2.6.1"
|
typical "^2.6.1"
|
||||||
|
|
||||||
commander@2.15.1, commander@2.15.x, commander@~2.15.0:
|
commander@2.15.x, commander@~2.15.0:
|
||||||
version "2.15.1"
|
version "2.15.1"
|
||||||
resolved "https://registry.yarnpkg.com/commander/-/commander-2.15.1.tgz#df46e867d0fc2aec66a34662b406a9ccafff5b0f"
|
resolved "https://registry.yarnpkg.com/commander/-/commander-2.15.1.tgz#df46e867d0fc2aec66a34662b406a9ccafff5b0f"
|
||||||
integrity sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==
|
integrity sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==
|
||||||
@ -4848,7 +4853,7 @@ debug@2.6.8:
|
|||||||
dependencies:
|
dependencies:
|
||||||
ms "2.0.0"
|
ms "2.0.0"
|
||||||
|
|
||||||
debug@3.1.0, debug@=3.1.0, debug@~3.1.0:
|
debug@=3.1.0, debug@~3.1.0:
|
||||||
version "3.1.0"
|
version "3.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261"
|
resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261"
|
||||||
integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==
|
integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==
|
||||||
@ -4939,6 +4944,11 @@ deep-is@~0.1.3:
|
|||||||
resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34"
|
resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34"
|
||||||
integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=
|
integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=
|
||||||
|
|
||||||
|
deepmerge@^2.0.1:
|
||||||
|
version "2.2.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-2.2.1.tgz#5d3ff22a01c00f645405a2fbc17d0778a1801170"
|
||||||
|
integrity sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA==
|
||||||
|
|
||||||
default-gateway@^2.6.0:
|
default-gateway@^2.6.0:
|
||||||
version "2.7.2"
|
version "2.7.2"
|
||||||
resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-2.7.2.tgz#b7ef339e5e024b045467af403d50348db4642d0f"
|
resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-2.7.2.tgz#b7ef339e5e024b045467af403d50348db4642d0f"
|
||||||
@ -5118,16 +5128,16 @@ diff@3.2.0:
|
|||||||
resolved "https://registry.yarnpkg.com/diff/-/diff-3.2.0.tgz#c9ce393a4b7cbd0b058a725c93df299027868ff9"
|
resolved "https://registry.yarnpkg.com/diff/-/diff-3.2.0.tgz#c9ce393a4b7cbd0b058a725c93df299027868ff9"
|
||||||
integrity sha1-yc45Okt8vQsFinJck98pkCeGj/k=
|
integrity sha1-yc45Okt8vQsFinJck98pkCeGj/k=
|
||||||
|
|
||||||
diff@3.5.0, diff@^3.1.0, diff@^3.2.0, diff@^3.5.0:
|
|
||||||
version "3.5.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12"
|
|
||||||
integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==
|
|
||||||
|
|
||||||
diff@^2.1.2:
|
diff@^2.1.2:
|
||||||
version "2.2.3"
|
version "2.2.3"
|
||||||
resolved "https://registry.yarnpkg.com/diff/-/diff-2.2.3.tgz#60eafd0d28ee906e4e8ff0a52c1229521033bf99"
|
resolved "https://registry.yarnpkg.com/diff/-/diff-2.2.3.tgz#60eafd0d28ee906e4e8ff0a52c1229521033bf99"
|
||||||
integrity sha1-YOr9DSjukG5Oj/ClLBIpUhAzv5k=
|
integrity sha1-YOr9DSjukG5Oj/ClLBIpUhAzv5k=
|
||||||
|
|
||||||
|
diff@^3.1.0, diff@^3.2.0, diff@^3.5.0:
|
||||||
|
version "3.5.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12"
|
||||||
|
integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==
|
||||||
|
|
||||||
diffie-hellman@^5.0.0:
|
diffie-hellman@^5.0.0:
|
||||||
version "5.0.3"
|
version "5.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875"
|
resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875"
|
||||||
@ -6772,18 +6782,6 @@ glob@7.1.1:
|
|||||||
once "^1.3.0"
|
once "^1.3.0"
|
||||||
path-is-absolute "^1.0.0"
|
path-is-absolute "^1.0.0"
|
||||||
|
|
||||||
glob@7.1.2:
|
|
||||||
version "7.1.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15"
|
|
||||||
integrity sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==
|
|
||||||
dependencies:
|
|
||||||
fs.realpath "^1.0.0"
|
|
||||||
inflight "^1.0.4"
|
|
||||||
inherits "2"
|
|
||||||
minimatch "^3.0.4"
|
|
||||||
once "^1.3.0"
|
|
||||||
path-is-absolute "^1.0.0"
|
|
||||||
|
|
||||||
glob@^4.3.1:
|
glob@^4.3.1:
|
||||||
version "4.5.3"
|
version "4.5.3"
|
||||||
resolved "https://registry.yarnpkg.com/glob/-/glob-4.5.3.tgz#c6cb73d3226c1efef04de3c56d012f03377ee15f"
|
resolved "https://registry.yarnpkg.com/glob/-/glob-4.5.3.tgz#c6cb73d3226c1efef04de3c56d012f03377ee15f"
|
||||||
@ -7065,11 +7063,6 @@ grouped-queue@^0.3.0, grouped-queue@^0.3.3:
|
|||||||
dependencies:
|
dependencies:
|
||||||
lodash "^4.17.2"
|
lodash "^4.17.2"
|
||||||
|
|
||||||
growl@1.10.5:
|
|
||||||
version "1.10.5"
|
|
||||||
resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e"
|
|
||||||
integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==
|
|
||||||
|
|
||||||
growl@1.9.2:
|
growl@1.9.2:
|
||||||
version "1.9.2"
|
version "1.9.2"
|
||||||
resolved "https://registry.yarnpkg.com/growl/-/growl-1.9.2.tgz#0ea7743715db8d8de2c5ede1775e1b45ac85c02f"
|
resolved "https://registry.yarnpkg.com/growl/-/growl-1.9.2.tgz#0ea7743715db8d8de2c5ede1775e1b45ac85c02f"
|
||||||
@ -9334,6 +9327,11 @@ make-dir@^1.0.0, make-dir@^1.1.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
pify "^3.0.0"
|
pify "^3.0.0"
|
||||||
|
|
||||||
|
make-error@^1.1.1:
|
||||||
|
version "1.3.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.5.tgz#efe4e81f6db28cadd605c70f29c831b58ef776c8"
|
||||||
|
integrity sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==
|
||||||
|
|
||||||
map-age-cleaner@^0.1.1:
|
map-age-cleaner@^0.1.1:
|
||||||
version "0.1.2"
|
version "0.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/map-age-cleaner/-/map-age-cleaner-0.1.2.tgz#098fb15538fd3dbe461f12745b0ca8568d4e3f74"
|
resolved "https://registry.yarnpkg.com/map-age-cleaner/-/map-age-cleaner-0.1.2.tgz#098fb15538fd3dbe461f12745b0ca8568d4e3f74"
|
||||||
@ -9599,7 +9597,7 @@ minimatch-all@^1.1.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
minimatch "^3.0.2"
|
minimatch "^3.0.2"
|
||||||
|
|
||||||
"minimatch@2 || 3", minimatch@3.0.4, minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4:
|
"minimatch@2 || 3", minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4:
|
||||||
version "3.0.4"
|
version "3.0.4"
|
||||||
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
|
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
|
||||||
integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==
|
integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==
|
||||||
@ -9721,23 +9719,6 @@ mocha@^3.4.2:
|
|||||||
mkdirp "0.5.1"
|
mkdirp "0.5.1"
|
||||||
supports-color "3.1.2"
|
supports-color "3.1.2"
|
||||||
|
|
||||||
mocha@^5.2.0:
|
|
||||||
version "5.2.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/mocha/-/mocha-5.2.0.tgz#6d8ae508f59167f940f2b5b3c4a612ae50c90ae6"
|
|
||||||
integrity sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ==
|
|
||||||
dependencies:
|
|
||||||
browser-stdout "1.3.1"
|
|
||||||
commander "2.15.1"
|
|
||||||
debug "3.1.0"
|
|
||||||
diff "3.5.0"
|
|
||||||
escape-string-regexp "1.0.5"
|
|
||||||
glob "7.1.2"
|
|
||||||
growl "1.10.5"
|
|
||||||
he "1.1.1"
|
|
||||||
minimatch "3.0.4"
|
|
||||||
mkdirp "0.5.1"
|
|
||||||
supports-color "5.4.0"
|
|
||||||
|
|
||||||
moment@^2.10.2, moment@^2.22.0:
|
moment@^2.10.2, moment@^2.22.0:
|
||||||
version "2.22.1"
|
version "2.22.1"
|
||||||
resolved "https://registry.yarnpkg.com/moment/-/moment-2.22.1.tgz#529a2e9bf973f259c9643d237fda84de3a26e8ad"
|
resolved "https://registry.yarnpkg.com/moment/-/moment-2.22.1.tgz#529a2e9bf973f259c9643d237fda84de3a26e8ad"
|
||||||
@ -12321,12 +12302,12 @@ sinon@^2.3.5:
|
|||||||
text-encoding "0.6.4"
|
text-encoding "0.6.4"
|
||||||
type-detect "^4.0.0"
|
type-detect "^4.0.0"
|
||||||
|
|
||||||
sinon@^7.1.0:
|
sinon@^7.1.1:
|
||||||
version "7.1.0"
|
version "7.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/sinon/-/sinon-7.1.0.tgz#819b63002ee09a90a3b50a0da4e0bdecb2e3f345"
|
resolved "https://registry.yarnpkg.com/sinon/-/sinon-7.1.1.tgz#1202f317aa14d93cb9b69ff50b6bd49c0e05ffc9"
|
||||||
integrity sha512-ffASxced8xr8eU0EGyfj9K++bRCtv/NyOFOxl7UBD86YH97oZjVxvecMhObwRlXe27GRUa6rVFEn67khPZ29rQ==
|
integrity sha512-iYagtjLVt1vN3zZY7D8oH7dkjNJEjLjyuzy8daX5+3bbQl8gaohrheB9VfH1O3L6LKuue5WTJvFluHiuZ9y3nQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@sinonjs/commons" "^1.0.2"
|
"@sinonjs/commons" "^1.2.0"
|
||||||
"@sinonjs/formatio" "^3.0.0"
|
"@sinonjs/formatio" "^3.0.0"
|
||||||
"@sinonjs/samsam" "^2.1.2"
|
"@sinonjs/samsam" "^2.1.2"
|
||||||
diff "^3.5.0"
|
diff "^3.5.0"
|
||||||
@ -12503,6 +12484,14 @@ source-map-support@^0.4.15:
|
|||||||
dependencies:
|
dependencies:
|
||||||
source-map "^0.5.6"
|
source-map "^0.5.6"
|
||||||
|
|
||||||
|
source-map-support@^0.5.6:
|
||||||
|
version "0.5.9"
|
||||||
|
resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.9.tgz#41bc953b2534267ea2d605bccfa7bfa3111ced5f"
|
||||||
|
integrity sha512-gR6Rw4MvUlYy83vP0vxoVNzM6t8MUXqNuRsuBmBHQDu1Fh6X015FrLdgoDKcNdkwGubozq0P4N0Q37UyFVr1EA==
|
||||||
|
dependencies:
|
||||||
|
buffer-from "^1.0.0"
|
||||||
|
source-map "^0.6.0"
|
||||||
|
|
||||||
source-map-url@^0.4.0:
|
source-map-url@^0.4.0:
|
||||||
version "0.4.0"
|
version "0.4.0"
|
||||||
resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3"
|
resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3"
|
||||||
@ -12513,7 +12502,7 @@ source-map@0.5.x, source-map@^0.5.0, source-map@^0.5.6, source-map@^0.5.7, sourc
|
|||||||
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
|
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
|
||||||
integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=
|
integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=
|
||||||
|
|
||||||
source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1:
|
source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1:
|
||||||
version "0.6.1"
|
version "0.6.1"
|
||||||
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
|
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
|
||||||
integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
|
integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
|
||||||
@ -12875,7 +12864,7 @@ strip-json-comments@^2.0.1, strip-json-comments@~2.0.1:
|
|||||||
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"
|
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"
|
||||||
integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo=
|
integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo=
|
||||||
|
|
||||||
supports-color@3.1.2, supports-color@5.4.0, supports-color@^0.2.0, supports-color@^2.0.0, supports-color@^5.1.0, supports-color@^5.3.0, supports-color@^5.4.0, supports-color@^5.5.0:
|
supports-color@3.1.2, supports-color@^0.2.0, supports-color@^2.0.0, supports-color@^5.1.0, supports-color@^5.3.0, supports-color@^5.4.0, supports-color@^5.5.0:
|
||||||
version "3.1.2"
|
version "3.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.1.2.tgz#72a262894d9d408b956ca05ff37b2ed8a6e2a2d5"
|
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.1.2.tgz#72a262894d9d408b956ca05ff37b2ed8a6e2a2d5"
|
||||||
integrity sha1-cqJiiU2dQIuVbKBf83su2KbiotU=
|
integrity sha1-cqJiiU2dQIuVbKBf83su2KbiotU=
|
||||||
@ -13251,6 +13240,40 @@ triple-beam@^1.2.0, triple-beam@^1.3.0:
|
|||||||
resolved "https://registry.yarnpkg.com/triple-beam/-/triple-beam-1.3.0.tgz#a595214c7298db8339eeeee083e4d10bd8cb8dd9"
|
resolved "https://registry.yarnpkg.com/triple-beam/-/triple-beam-1.3.0.tgz#a595214c7298db8339eeeee083e4d10bd8cb8dd9"
|
||||||
integrity sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw==
|
integrity sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw==
|
||||||
|
|
||||||
|
ts-mocha@^2.0.0:
|
||||||
|
version "2.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/ts-mocha/-/ts-mocha-2.0.0.tgz#0dbd3cd04671df9933b9303b4aa46347573c5635"
|
||||||
|
integrity sha512-Rj6+vvwKtOTs5GsNO1jLl4DIXUGnyAg5HFt2Yb4SHIRN45clTJkHWpNdTxCSL0u+1oeavSYJah6d1PZ++Ju5pw==
|
||||||
|
dependencies:
|
||||||
|
ts-node "7.0.0"
|
||||||
|
optionalDependencies:
|
||||||
|
tsconfig-paths "^3.5.0"
|
||||||
|
|
||||||
|
ts-node@7.0.0:
|
||||||
|
version "7.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-7.0.0.tgz#a94a13c75e5e1aa6b82814b84c68deb339ba7bff"
|
||||||
|
integrity sha512-klJsfswHP0FuOLsvBZ/zzCfUvakOSSxds78mVeK7I+qP76YWtxf16hEZsp3U+b0kIo82R5UatGFeblYMqabb2Q==
|
||||||
|
dependencies:
|
||||||
|
arrify "^1.0.0"
|
||||||
|
buffer-from "^1.1.0"
|
||||||
|
diff "^3.1.0"
|
||||||
|
make-error "^1.1.1"
|
||||||
|
minimist "^1.2.0"
|
||||||
|
mkdirp "^0.5.1"
|
||||||
|
source-map-support "^0.5.6"
|
||||||
|
yn "^2.0.0"
|
||||||
|
|
||||||
|
tsconfig-paths@^3.5.0:
|
||||||
|
version "3.6.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.6.0.tgz#f14078630d9d6e8b1dc690c1fc0cfb9cd0663891"
|
||||||
|
integrity sha512-mrqQIP2F4e03aMTCiPdedCIT300//+q0ET53o5WqqtQjmEICxP9yfz/sHTpPqXpssuJEzODsEzJaLRaf5J2X1g==
|
||||||
|
dependencies:
|
||||||
|
"@types/json5" "^0.0.29"
|
||||||
|
deepmerge "^2.0.1"
|
||||||
|
json5 "^1.0.1"
|
||||||
|
minimist "^1.2.0"
|
||||||
|
strip-bom "^3.0.0"
|
||||||
|
|
||||||
tslib@1.9.0:
|
tslib@1.9.0:
|
||||||
version "1.9.0"
|
version "1.9.0"
|
||||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.0.tgz#e37a86fda8cbbaf23a057f473c9f4dc64e5fc2e8"
|
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.0.tgz#e37a86fda8cbbaf23a057f473c9f4dc64e5fc2e8"
|
||||||
@ -14645,6 +14668,11 @@ yeoman-generator@^3.1.1:
|
|||||||
through2 "^2.0.0"
|
through2 "^2.0.0"
|
||||||
yeoman-environment "^2.0.5"
|
yeoman-environment "^2.0.5"
|
||||||
|
|
||||||
|
yn@^2.0.0:
|
||||||
|
version "2.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/yn/-/yn-2.0.0.tgz#e5adabc8acf408f6385fc76495684c88e6af689a"
|
||||||
|
integrity sha1-5a2ryKz0CPY4X8dklWhMiOavaJo=
|
||||||
|
|
||||||
zip-stream@^1.2.0:
|
zip-stream@^1.2.0:
|
||||||
version "1.2.0"
|
version "1.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/zip-stream/-/zip-stream-1.2.0.tgz#a8bc45f4c1b49699c6b90198baacaacdbcd4ba04"
|
resolved "https://registry.yarnpkg.com/zip-stream/-/zip-stream-1.2.0.tgz#a8bc45f4c1b49699c6b90198baacaacdbcd4ba04"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user