isy-nodejs
Version:
Node.js wrapper for ISY interface including websockets for change notifications. Fork of isy-js by Rod Toll. Designed to be used in a node.js application.
133 lines (105 loc) • 3.6 kB
text/typescript
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;
}