UNPKG

@pmouli/isy-matter-server

Version:

Service to expose an ISY device as a Matter Border router

148 lines (103 loc) 3.65 kB
import { Driver } from '../Definitions/Global/Drivers.js' import type { MaybeArray } from '../Utils.js'; export interface DriverDef { id: Driver.Type; editor: string; hide?: string; }; export interface SendCommandDef { id: string; } export interface ParamDef { id: string; editor: string; init: string; optional?: string; } export interface AcceptCommandDef { name?: string; id?: string; p?: MaybeArray<ParamDef>; } export interface NodeDef extends Nested<"st">{ id: string; nls: string; nodeType: string; eventMap: string; links: Link; sts: {st: MaybeArray<DriverDef>} cmds: { sends: {cmd: MaybeArray<SendCommandDef>}; accepts: {cmd: MaybeArray<AcceptCommandDef>}; }; } export interface Accept { cmd: Cmd[]; } export interface Cmd { accepts: Accept; } export interface Link { linkdef: string; } export interface Rsp { link: Link[]; } export interface Link { ctl: string; rsp: Rsp; } export interface NodeDefs { nodeDef: MaybeArray<NodeDef>; } type n = NestedObject<"nodeDef">; type s = ReturnType<typeof flattenNestedObject<"nodeDef",NestedObject<"nodeDef">>>; type NestedObject<Label extends string> = { [x in `${Label}s`]: {[y in `${Label}`]: any }}; type Singular<T> = T extends `${infer R}s` ? R : never; type PickNestedProperties<T> = { [P in keyof T]: T[P] extends {[Y in Singular<P>]:any} ? T[P] : never}; type PickStrings<T> = {[P in keyof T]: T[P] & P extends string ? P : never}[keyof T]; type PickProperties<T> = {[P in keyof T]: T[P] & P extends {[y in keyof P]: P[y]} ? P : never}[keyof T]; type GetPropertyTypes<T,Y extends keyof T = keyof T> = T extends {[x in Y]: infer R} ? R : never; type NodeDefProperties = PickNestedProperties<NodeDef>; type FlattenedNestedObject<T> = T extends NestedObject<infer R> ? R : never; // ? // Omit<T, `${R}s`> & { [x in `${R}s`]: GetPropertyTypes<T[`${R}s`]> } // : T; type FlattenedNestedNodeDef = FlattenedNestedObject<NodeDef>; function isNested<T extends string,objType extends object>(property: T, input: any): input is NestedObject<T> { let prop = `${property}s`; return input.hasOwnProperty(prop) ? input[prop].hasOwnProperty(property) : false; } type Nested<T extends string> = { [x in T]: {[y in Singular<x>]: any }}; type isNested<T> = T extends Nested<infer R> ? true : false; //type isNestedNodeDef = isNested<NodeDef>; export function flattenNestedProperty<T extends string>(input: NestedObject<T>, property: T) { if(isNested(property, input)) { //@ts-expect-error return { ...input, [`${property}s`]: input[`${property}s`][property] }; } } // for (const key in Object.keys(input)) { // const subkey = key.left(key.length - 1); // if (isNested(subkey, input)) { // const newValue = input[key][subkey]; // clone[key] = newValue; //isArray(newValue) ? newValue.map(flattenNestedObject) : flattenNestedObject(newValue); // } else { // clone[key] = input[key]; // } // } // return clone; // } export function flattenNestedObject<Label extends string,T = unknown> (input: NestedObject<Label>) : Omit<typeof input,Label> & {[x in `${Label}s`]: MaybeArray<T> | T | T[]}{ let clone = {} as Omit<typeof input,Label> & {[x in `${Label}s`]: MaybeArray<T> | T | T[]}; for (const key in Object.keys(input)) { const subkey = key.left(key.length - 1); if (isNested(subkey, input)) { const newValue = input[key][subkey]; clone[key] = newValue; //isArray(newValue) ? newValue.map(flattenNestedObject) : flattenNestedObject(newValue); } else { clone[key] = input[key]; } } return clone; }