Rename service_data to data to maintain HA compatibility.
This commit is contained in:
+123
-316
@@ -2,40 +2,24 @@ import cloneDeep from 'lodash-es/cloneDeep';
|
||||
import get from 'lodash-es/get';
|
||||
import isEqual from 'lodash-es/isEqual';
|
||||
import set from 'lodash-es/set';
|
||||
import {
|
||||
BUTTON_SIZE_MIN,
|
||||
RawFrigateCardConfig,
|
||||
THUMBNAIL_WIDTH_MAX,
|
||||
THUMBNAIL_WIDTH_MIN,
|
||||
} from './config/types';
|
||||
import unset from 'lodash-es/unset';
|
||||
import { RawFrigateCardConfig } from './config/types';
|
||||
import {
|
||||
CONF_CAMERAS,
|
||||
CONF_CAMERAS_GLOBAL_IMAGE,
|
||||
CONF_CAMERAS_GLOBAL_JSMPEG,
|
||||
CONF_CAMERAS_GLOBAL_WEBRTC_CARD,
|
||||
CONF_ELEMENTS,
|
||||
CONF_LIVE_AUTO_UNMUTE,
|
||||
CONF_LIVE_CONTROLS_NEXT_PREVIOUS_SIZE,
|
||||
CONF_LIVE_CONTROLS_THUMBNAILS_SIZE,
|
||||
CONF_LIVE_LAZY_UNLOAD,
|
||||
CONF_MEDIA_GALLERY,
|
||||
CONF_MEDIA_VIEWER,
|
||||
CONF_MENU_BUTTONS_CAMERAS,
|
||||
CONF_MENU_BUTTONS_CAMERA_UI,
|
||||
CONF_MENU_BUTTONS_CLIPS,
|
||||
CONF_MENU_BUTTONS_DOWNLOAD,
|
||||
CONF_MENU_BUTTONS_FRIGATE,
|
||||
CONF_MENU_BUTTONS_FULLSCREEN,
|
||||
CONF_MENU_BUTTONS_IMAGE,
|
||||
CONF_MENU_BUTTONS_LIVE,
|
||||
CONF_MENU_BUTTONS_SNAPSHOTS,
|
||||
CONF_MENU_BUTTON_SIZE,
|
||||
CONF_MENU_POSITION,
|
||||
CONF_MENU_STYLE,
|
||||
CONF_OVERRIDES,
|
||||
} from './const';
|
||||
import { arrayify } from './utils/basic';
|
||||
|
||||
// *************************************************************************
|
||||
// General Config Management Functions
|
||||
// *************************************************************************
|
||||
|
||||
/**
|
||||
* Set a configuration value.
|
||||
* @param obj The configuration.
|
||||
@@ -71,19 +55,33 @@ export const getConfigValue = (
|
||||
* @param obj The configuration.
|
||||
* @param key The key to the property to delete.
|
||||
*/
|
||||
export const deleteConfigValue = (obj: RawFrigateCardConfig, key: string): void => {
|
||||
let id = key;
|
||||
let targetObj: unknown = obj;
|
||||
if (key && key.split && key.includes('.')) {
|
||||
const keys = key.split('.');
|
||||
id = keys[keys.length - 1];
|
||||
targetObj = getConfigValue(obj, keys.slice(0, -1).join('.'));
|
||||
}
|
||||
if (targetObj && typeof targetObj === 'object') {
|
||||
delete targetObj[id];
|
||||
}
|
||||
export const deleteConfigValue = (obj: RawFrigateCardConfig, path: string): void => {
|
||||
unset(obj, path);
|
||||
};
|
||||
|
||||
/**
|
||||
* Copy a configuration.
|
||||
* @param obj Configuration to copy.
|
||||
* @returns A new deeply-copied configuration.
|
||||
*/
|
||||
export const copyConfig = <T>(obj: T): T => {
|
||||
return cloneDeep(obj);
|
||||
};
|
||||
|
||||
/**
|
||||
* Given an array path, return a true path.
|
||||
* @param path The array path (should have a '#').
|
||||
* @param index The numeric array index to use.
|
||||
* @returns The true config path.
|
||||
*/
|
||||
export const getArrayConfigPath = (path: string, index: number): string => {
|
||||
return path.replace('#', `[${index.toString()}]`);
|
||||
};
|
||||
|
||||
// *************************************************************************
|
||||
// Upgrade Related Functions
|
||||
// *************************************************************************
|
||||
|
||||
/**
|
||||
* Upgrade a configuration.
|
||||
* @param obj The configuration to upgrade.
|
||||
@@ -106,67 +104,6 @@ export const isConfigUpgradeable = function (obj: RawFrigateCardConfig): boolean
|
||||
return upgradeConfig(copyConfig(obj));
|
||||
};
|
||||
|
||||
/**
|
||||
* Copy a configuration.
|
||||
* @param obj Configuration to copy.
|
||||
* @returns A new deeply-copied configuration.
|
||||
*/
|
||||
export const copyConfig = <T>(obj: T): T => {
|
||||
return cloneDeep(obj);
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a transform that will cap a numeric value.
|
||||
* @param value The value.
|
||||
* @returns A number or null.
|
||||
*/
|
||||
const createRangedTransform = function (
|
||||
transform: (value: unknown) => unknown,
|
||||
min?: number,
|
||||
max?: number,
|
||||
): (valueIn: unknown) => unknown {
|
||||
return (value: unknown): unknown => {
|
||||
let transformed = transform(value);
|
||||
if (typeof transformed !== 'number') {
|
||||
return transformed;
|
||||
}
|
||||
transformed = min ? Math.max(min, transformed as number) : transformed;
|
||||
transformed = max ? Math.min(max, transformed as number) : transformed;
|
||||
return transformed;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Convert a value from 'XXpx' to XX (as a number).
|
||||
* @param value Incoming value.
|
||||
* @returns A number, null if the property should be deleted or undefined if it
|
||||
* should be ignored.
|
||||
*/
|
||||
const toPixelsOrDelete = function (value: unknown): number | null | undefined {
|
||||
// Ignore the value if it's a number.
|
||||
if (typeof value === 'number') {
|
||||
return undefined;
|
||||
}
|
||||
// Delete the value if it's not a string.
|
||||
if (typeof value !== 'string') {
|
||||
return null;
|
||||
}
|
||||
// Remove 'px' and return the number, unless it's an invalid number -- then
|
||||
// delete it.
|
||||
value = value.replace(/px$/i, '');
|
||||
return isNaN(value as number) ? null : Number(value);
|
||||
};
|
||||
|
||||
/**
|
||||
* Request a property be deleted.
|
||||
* @param _value Inbound value (not required).
|
||||
* @returns `null` to request the property be deleted.
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const deleteProperty = function (_value: unknown): number | null | undefined {
|
||||
return null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Move a property from one location to another.
|
||||
* @param obj The configuration object in which the property resides.
|
||||
@@ -175,7 +112,7 @@ const deleteProperty = function (_value: unknown): number | null | undefined {
|
||||
* @param transform An optional transform for the value.
|
||||
* @returns `true` if the configuration was modified.
|
||||
*/
|
||||
const moveConfigValue = (
|
||||
export const moveConfigValue = (
|
||||
obj: RawFrigateCardConfig,
|
||||
oldPath: string,
|
||||
newPath: string,
|
||||
@@ -209,16 +146,6 @@ const moveConfigValue = (
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Given an array path, return a true path.
|
||||
* @param path The array path (should have a '#').
|
||||
* @param index The numeric array index to use.
|
||||
* @returns The true config path.
|
||||
*/
|
||||
export const getArrayConfigPath = (path: string, index: number): string => {
|
||||
return path.replace('#', `[${index.toString()}]`);
|
||||
};
|
||||
|
||||
/**
|
||||
* Upgrade by moving a property from one location to another.
|
||||
* @param oldPath The old property path.
|
||||
@@ -226,7 +153,7 @@ export const getArrayConfigPath = (path: string, index: number): string => {
|
||||
* @param transform An optional transform for the value.
|
||||
* @returns `true` if the configuration was modified.
|
||||
*/
|
||||
const upgradeMoveTo = function (
|
||||
export const upgradeMoveTo = function (
|
||||
oldPath: string,
|
||||
newPath: string,
|
||||
options?: {
|
||||
@@ -247,7 +174,7 @@ const upgradeMoveTo = function (
|
||||
* @param transform An optional transform for the value.
|
||||
* @returns A function that returns `true` if the configuration was modified.
|
||||
*/
|
||||
const upgradeMoveToWithOverrides = function (
|
||||
export const upgradeMoveToWithOverrides = function (
|
||||
oldPath: string,
|
||||
newPath: string,
|
||||
options?: {
|
||||
@@ -258,7 +185,7 @@ const upgradeMoveToWithOverrides = function (
|
||||
return function (obj: RawFrigateCardConfig): boolean {
|
||||
let modified = upgradeMoveTo(oldPath, newPath, options)(obj);
|
||||
modified =
|
||||
upgradeArrayValue(
|
||||
upgradeArrayOfObjects(
|
||||
CONF_OVERRIDES,
|
||||
upgradeMoveTo(oldPath, newPath, options),
|
||||
(obj) => obj.overrides as RawFrigateCardConfig | undefined,
|
||||
@@ -273,26 +200,13 @@ const upgradeMoveToWithOverrides = function (
|
||||
* @param transform An optional transform for the value.
|
||||
* @returns A function that returns `true` if the configuration was modified.
|
||||
*/
|
||||
const upgradeWithOverrides = function (
|
||||
export const upgradeWithOverrides = function (
|
||||
path: string,
|
||||
transform: (valueIn: unknown) => unknown,
|
||||
): (obj: RawFrigateCardConfig) => boolean {
|
||||
return upgradeMoveToWithOverrides(path, path, { transform: transform });
|
||||
};
|
||||
|
||||
/**
|
||||
* Upgrade a property in place without overrides.
|
||||
* @param path The old property path.
|
||||
* @param transform An optional transform for the value.
|
||||
* @returns A function that returns `true` if the configuration was modified.
|
||||
*/
|
||||
const upgrade = function (
|
||||
path: string,
|
||||
transform: (valueIn: unknown) => unknown,
|
||||
): (obj: RawFrigateCardConfig) => boolean {
|
||||
return upgradeMoveTo(path, path, { transform: transform });
|
||||
};
|
||||
|
||||
/**
|
||||
* Given a path to an array, apply an upgrade to each object in the array.
|
||||
* @param arrayPath The path to the array to upgrade.
|
||||
@@ -301,7 +215,7 @@ const upgrade = function (
|
||||
* returns the object to modify within it.
|
||||
* @returns A function that returns `true` if the configuration was modified.
|
||||
*/
|
||||
const upgradeArrayValue = function (
|
||||
export const upgradeArrayOfObjects = function (
|
||||
arrayPath: string,
|
||||
upgrade: (obj: RawFrigateCardConfig) => boolean,
|
||||
getObject?: (obj: RawFrigateCardConfig) => RawFrigateCardConfig | undefined,
|
||||
@@ -321,127 +235,13 @@ const upgradeArrayValue = function (
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Upgrade from a menu-mode to a style & position.
|
||||
* @returns An upgrade function.
|
||||
*/
|
||||
const upgradeMenuModeToStyleAndPosition = (): ((
|
||||
obj: RawFrigateCardConfig,
|
||||
) => boolean) => {
|
||||
return function (obj: RawFrigateCardConfig): boolean {
|
||||
let modified = false;
|
||||
|
||||
// Change the 'start' of the mode into a style.
|
||||
modified =
|
||||
upgradeMoveToWithOverrides('menu.mode', CONF_MENU_STYLE, {
|
||||
transform: (mode: unknown): string | undefined => {
|
||||
if (typeof mode === 'string') {
|
||||
const result = mode.match(/^(hover|hidden|overlay|above|below|none)/);
|
||||
if (result) {
|
||||
switch (result[1]) {
|
||||
case 'hover':
|
||||
case 'hidden':
|
||||
case 'overlay':
|
||||
case 'none':
|
||||
return result[1];
|
||||
case 'above':
|
||||
case 'below':
|
||||
return 'outside';
|
||||
}
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
keepOriginal: true,
|
||||
})(obj) || modified;
|
||||
|
||||
// Change the 'end' of the mode into a position.
|
||||
modified =
|
||||
upgradeMoveToWithOverrides('menu.mode', CONF_MENU_POSITION, {
|
||||
transform: (mode: unknown): string | undefined => {
|
||||
if (typeof mode === 'string') {
|
||||
const result = mode.match(/(above|below|left|right|top|bottom)$/);
|
||||
if (result) {
|
||||
switch (result[1]) {
|
||||
case 'left':
|
||||
case 'right':
|
||||
case 'top':
|
||||
case 'bottom':
|
||||
return result[1];
|
||||
case 'above':
|
||||
return 'top';
|
||||
case 'below':
|
||||
return 'bottom';
|
||||
}
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
keepOriginal: true,
|
||||
})(obj) || modified;
|
||||
|
||||
// Delete the old `menu.mode` .
|
||||
return upgradeWithOverrides('menu.mode', deleteProperty)(obj) || modified;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Transform a menu button from a boolean to a priority.
|
||||
* @param value The boolean true/false for show/hide the switch.
|
||||
* @returns A priority value.
|
||||
*/
|
||||
const menuButtonBooleanToObject = function (
|
||||
value: unknown,
|
||||
): { enabled: boolean } | null | undefined {
|
||||
if (typeof value === 'object') {
|
||||
return undefined;
|
||||
}
|
||||
// If it's not a boolean remove it.
|
||||
if (typeof value !== 'boolean') {
|
||||
return null;
|
||||
}
|
||||
return { enabled: value };
|
||||
};
|
||||
|
||||
/**
|
||||
* Upgrade from a show_controls key to individual favorite/timeline keys.
|
||||
* @returns An upgrade function.
|
||||
*/
|
||||
const upgradeThumbnailShowControlsToIndividualControls = (
|
||||
thumbnailsBasePath: string,
|
||||
): ((obj: RawFrigateCardConfig) => boolean) => {
|
||||
const thumbnailsShowControlsPath = `${thumbnailsBasePath}.show_controls`;
|
||||
|
||||
return function (obj: RawFrigateCardConfig): boolean {
|
||||
let modified = false;
|
||||
modified =
|
||||
upgradeMoveToWithOverrides(
|
||||
thumbnailsShowControlsPath,
|
||||
`${thumbnailsBasePath}.show_favorite_control`,
|
||||
{ keepOriginal: true },
|
||||
)(obj) || modified;
|
||||
|
||||
modified =
|
||||
upgradeMoveToWithOverrides(
|
||||
thumbnailsShowControlsPath,
|
||||
`${thumbnailsBasePath}.show_timeline_control`,
|
||||
{ keepOriginal: true },
|
||||
)(obj) || modified;
|
||||
|
||||
// Delete the old `show_controls`.
|
||||
return (
|
||||
upgradeWithOverrides(thumbnailsShowControlsPath, deleteProperty)(obj) || modified
|
||||
);
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Recursively upgrade an object.
|
||||
* @param transform A transform applied to each object recursively.
|
||||
* @param getObject A function to get the object to be upgraded.
|
||||
* @returns An upgrade function.
|
||||
*/
|
||||
const recursiveUpgradeObject = (
|
||||
export const upgradeObjectRecursively = (
|
||||
transform: (data: RawFrigateCardConfig) => boolean,
|
||||
getObject?: (data: RawFrigateCardConfig) => RawFrigateCardConfig | undefined | null,
|
||||
): ((data: RawFrigateCardConfig) => boolean) => {
|
||||
@@ -453,17 +253,13 @@ const recursiveUpgradeObject = (
|
||||
result = transform(object) || result;
|
||||
}
|
||||
if (Array.isArray(data)) {
|
||||
data
|
||||
.filter((item) => typeof item === 'object')
|
||||
.forEach((item: RawFrigateCardConfig) => {
|
||||
result = recurse(item) || result;
|
||||
});
|
||||
data.forEach((item: RawFrigateCardConfig) => {
|
||||
result = recurse(item) || result;
|
||||
});
|
||||
} else {
|
||||
Object.keys(data)
|
||||
.filter((key) => typeof data[key] === 'object')
|
||||
.forEach((key) => {
|
||||
result = recurse(data[key] as RawFrigateCardConfig) || result;
|
||||
});
|
||||
Object.keys(data).forEach((key) => {
|
||||
result = recurse(data[key] as RawFrigateCardConfig) || result;
|
||||
});
|
||||
}
|
||||
}
|
||||
return result;
|
||||
@@ -471,12 +267,51 @@ const recursiveUpgradeObject = (
|
||||
return recurse;
|
||||
};
|
||||
|
||||
// *************************************************************************
|
||||
// Upgrade Related Functions: Generic Transforms
|
||||
// *************************************************************************
|
||||
|
||||
/**
|
||||
* Create a transform that will cap a numeric value.
|
||||
* @param value The value.
|
||||
* @returns A number or null.
|
||||
*/
|
||||
export const createRangedTransform = function (
|
||||
transform: (value: unknown) => unknown,
|
||||
min?: number,
|
||||
max?: number,
|
||||
): (valueIn: unknown) => unknown {
|
||||
return (value: unknown): unknown => {
|
||||
let transformed = transform(value);
|
||||
if (typeof transformed !== 'number') {
|
||||
return transformed;
|
||||
}
|
||||
transformed = min !== undefined ? Math.max(min, transformed as number) : transformed;
|
||||
transformed = max !== undefined ? Math.min(max, transformed as number) : transformed;
|
||||
return transformed;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Request a property be deleted.
|
||||
* @param _value Inbound value (not required).
|
||||
* @returns `null` to request the property be deleted.
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
export const deleteTransform = function (_value: unknown): number | null | undefined {
|
||||
return null;
|
||||
};
|
||||
|
||||
// *************************************************************************
|
||||
// Upgrade Related Functions: Specific Transforms
|
||||
// *************************************************************************
|
||||
|
||||
/**
|
||||
* Transform mediaLoaded -> media_loaded
|
||||
* @param data Input data.
|
||||
* @returns `true` if the configuration was modified.
|
||||
*/
|
||||
const transformConditionMediaLoaded = (data: unknown): boolean => {
|
||||
const conditionMediaLoadedTransform = (data: unknown): boolean => {
|
||||
if (typeof data === 'object' && data && data['mediaLoaded'] !== undefined) {
|
||||
data['media_loaded'] = data['mediaLoaded'];
|
||||
delete data['mediaLoaded'];
|
||||
@@ -485,12 +320,34 @@ const transformConditionMediaLoaded = (data: unknown): boolean => {
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Transform service_data -> data
|
||||
* See: https://github.com/dermotduffy/frigate-hass-card/issues/1103
|
||||
* @param data Input data.
|
||||
* @returns `true` if the configuration was modified.
|
||||
*/
|
||||
const serviceDataToDataTransform = (data: unknown): boolean => {
|
||||
if (
|
||||
typeof data === 'object' &&
|
||||
data &&
|
||||
data['action'] === 'call-service' &&
|
||||
data['service'] !== undefined &&
|
||||
data['service_data'] !== undefined &&
|
||||
data['data'] === undefined
|
||||
) {
|
||||
data['data'] = data['service_data'];
|
||||
delete data['service_data'];
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Transform action frigate_ui -> camera_ui
|
||||
* @param data Input data.
|
||||
* @returns `true` if the configuration was modified.
|
||||
*/
|
||||
const transformFrigateUIAction = (data: unknown): boolean => {
|
||||
const frigateUIActionTransform = (data: unknown): boolean => {
|
||||
if (
|
||||
typeof data === 'object' &&
|
||||
data &&
|
||||
@@ -504,101 +361,51 @@ const transformFrigateUIAction = (data: unknown): boolean => {
|
||||
};
|
||||
|
||||
const UPGRADES = [
|
||||
// v3.0.0 -> v4.0.0-rc.1
|
||||
upgradeWithOverrides(
|
||||
CONF_LIVE_CONTROLS_THUMBNAILS_SIZE,
|
||||
createRangedTransform(toPixelsOrDelete, THUMBNAIL_WIDTH_MIN, THUMBNAIL_WIDTH_MAX),
|
||||
),
|
||||
upgradeWithOverrides(
|
||||
'event_viewer.controls.thumbnails.size',
|
||||
createRangedTransform(toPixelsOrDelete, THUMBNAIL_WIDTH_MIN, THUMBNAIL_WIDTH_MAX),
|
||||
),
|
||||
upgradeWithOverrides(
|
||||
CONF_LIVE_CONTROLS_NEXT_PREVIOUS_SIZE,
|
||||
createRangedTransform(toPixelsOrDelete, BUTTON_SIZE_MIN),
|
||||
),
|
||||
upgradeWithOverrides(
|
||||
'event_viewer.controls.next_previous.size',
|
||||
createRangedTransform(toPixelsOrDelete, BUTTON_SIZE_MIN),
|
||||
),
|
||||
upgradeWithOverrides(
|
||||
CONF_MENU_BUTTON_SIZE,
|
||||
createRangedTransform(toPixelsOrDelete, BUTTON_SIZE_MIN),
|
||||
),
|
||||
upgradeWithOverrides('event_gallery.min_columns', deleteProperty),
|
||||
upgradeMenuModeToStyleAndPosition(),
|
||||
upgradeWithOverrides(CONF_MENU_BUTTONS_FRIGATE, menuButtonBooleanToObject),
|
||||
upgradeWithOverrides(CONF_MENU_BUTTONS_CAMERAS, menuButtonBooleanToObject),
|
||||
upgradeWithOverrides(CONF_MENU_BUTTONS_LIVE, menuButtonBooleanToObject),
|
||||
upgradeWithOverrides(CONF_MENU_BUTTONS_CLIPS, menuButtonBooleanToObject),
|
||||
upgradeWithOverrides(CONF_MENU_BUTTONS_SNAPSHOTS, menuButtonBooleanToObject),
|
||||
upgradeWithOverrides(CONF_MENU_BUTTONS_IMAGE, menuButtonBooleanToObject),
|
||||
upgradeWithOverrides(CONF_MENU_BUTTONS_DOWNLOAD, menuButtonBooleanToObject),
|
||||
upgradeWithOverrides('menu.buttons.frigate_ui', menuButtonBooleanToObject),
|
||||
upgradeWithOverrides(CONF_MENU_BUTTONS_FULLSCREEN, menuButtonBooleanToObject),
|
||||
upgrade(CONF_LIVE_LAZY_UNLOAD, (val) =>
|
||||
typeof val === 'boolean' ? (val ? 'all' : 'never') : undefined,
|
||||
),
|
||||
upgrade(CONF_LIVE_AUTO_UNMUTE, (val) =>
|
||||
typeof val === 'boolean' ? (val ? 'all' : 'never') : undefined,
|
||||
),
|
||||
upgrade('event_viewer.auto_play', (val) =>
|
||||
typeof val === 'boolean' ? (val ? 'all' : 'never') : undefined,
|
||||
),
|
||||
upgrade('event_viewer.auto_unmute', (val) =>
|
||||
typeof val === 'boolean' ? (val ? 'all' : 'never') : undefined,
|
||||
),
|
||||
upgradeMoveToWithOverrides('event_viewer', CONF_MEDIA_VIEWER),
|
||||
upgradeArrayValue(CONF_CAMERAS, upgradeMoveTo('camera_name', 'frigate.camera_name')),
|
||||
upgradeArrayValue(CONF_CAMERAS, upgradeMoveTo('client_id', 'frigate.client_id')),
|
||||
upgradeArrayValue(CONF_CAMERAS, upgradeMoveTo('label', 'frigate.label')),
|
||||
upgradeArrayValue(CONF_CAMERAS, upgradeMoveTo('frigate_url', 'frigate.url')),
|
||||
upgradeArrayValue(CONF_CAMERAS, upgradeMoveTo('zone', 'frigate.zone')),
|
||||
|
||||
// v4.0.0-rc.1 -> v4.0.0-rc.3
|
||||
upgradeThumbnailShowControlsToIndividualControls('event_gallery.controls.thumbnails'),
|
||||
upgradeThumbnailShowControlsToIndividualControls('media_viewer.controls.thumbnails'),
|
||||
upgradeThumbnailShowControlsToIndividualControls('live.controls.thumbnails'),
|
||||
upgradeThumbnailShowControlsToIndividualControls('timeline.controls.thumbnails'),
|
||||
|
||||
// v4.0.0 -> v4.1.0
|
||||
upgradeArrayValue(
|
||||
upgradeArrayOfObjects(
|
||||
CONF_OVERRIDES,
|
||||
transformConditionMediaLoaded,
|
||||
conditionMediaLoadedTransform,
|
||||
(data) => data.conditions as RawFrigateCardConfig | undefined,
|
||||
),
|
||||
(data: unknown): boolean => {
|
||||
return recursiveUpgradeObject(
|
||||
transformConditionMediaLoaded,
|
||||
return upgradeObjectRecursively(
|
||||
conditionMediaLoadedTransform,
|
||||
(data) => data.conditions as RawFrigateCardConfig | undefined,
|
||||
)(typeof data === 'object' && data ? data[CONF_ELEMENTS] : {});
|
||||
},
|
||||
upgradeMoveToWithOverrides('event_gallery', CONF_MEDIA_GALLERY),
|
||||
upgradeMoveToWithOverrides('menu.buttons.frigate_ui', CONF_MENU_BUTTONS_CAMERA_UI),
|
||||
(data: unknown): boolean => {
|
||||
return recursiveUpgradeObject(transformFrigateUIAction)(
|
||||
return upgradeObjectRecursively(frigateUIActionTransform)(
|
||||
typeof data === 'object' && data ? <RawFrigateCardConfig>data : {},
|
||||
);
|
||||
},
|
||||
upgradeArrayValue(
|
||||
upgradeArrayOfObjects(
|
||||
CONF_CAMERAS,
|
||||
upgradeWithOverrides('live_provider', (val) =>
|
||||
val === 'frigate-jsmpeg' ? 'jsmpeg' : val,
|
||||
),
|
||||
),
|
||||
upgradeMoveToWithOverrides('live.image', CONF_CAMERAS_GLOBAL_IMAGE),
|
||||
upgradeMoveToWithOverrides('live.jsmpeg', CONF_CAMERAS_GLOBAL_JSMPEG),
|
||||
upgradeMoveToWithOverrides('live.image', CONF_CAMERAS_GLOBAL_IMAGE),
|
||||
upgradeMoveToWithOverrides('live.webrtc_card', CONF_CAMERAS_GLOBAL_WEBRTC_CARD),
|
||||
upgradeArrayValue(
|
||||
upgradeArrayOfObjects(
|
||||
CONF_CAMERAS,
|
||||
upgradeMoveToWithOverrides('frigate.zone', 'frigate.zones', {
|
||||
transform: (zone) => arrayify(zone),
|
||||
}),
|
||||
),
|
||||
upgradeArrayValue(
|
||||
upgradeArrayOfObjects(
|
||||
CONF_CAMERAS,
|
||||
upgradeMoveToWithOverrides('frigate.label', 'frigate.labels', {
|
||||
transform: (label) => arrayify(label),
|
||||
}),
|
||||
),
|
||||
|
||||
// v5.2.0 -> v6.0.0
|
||||
(data: unknown): boolean => {
|
||||
return upgradeObjectRecursively(serviceDataToDataTransform)(
|
||||
typeof data === 'object' && data ? <RawFrigateCardConfig>data : {},
|
||||
);
|
||||
},
|
||||
];
|
||||
|
||||
Reference in New Issue
Block a user