@pmouli/isy-matter-server
Version:
Service to expose an ISY device as a Matter Border router
222 lines • 15.1 kB
JavaScript
import { factory } from "typescript";
import ts from "typescript";
import { UnitOfMeasure } from "../Definitions/Global/UOM.js";
import { EnumDefinitionMap } from "../Model/EnumDefinition.js";
import { loggers } from "winston";
import { pascalCase } from 'moderndash';
import { Family } from '../Definitions/index.js';
const logger = loggers.get("EnumFactory");
export function buildEnums(map) {
let enums = [];
for (const indexId in map) {
enums.push(createEnum(map[indexId]));
}
return enums;
}
export function createEnum(enumDef) {
try {
const enumNode = factory.createEnumDeclaration([factory.createToken(ts.SyntaxKind.ExportKeyword)], factory.createIdentifier(enumDef.name), [
...Object.entries(enumDef.values).map(([name, value]) => factory.createEnumMember(createMemberName(name), factory.createNumericLiteral(value))),
]);
return {
family: enumDef.family,
name: enumDef.name,
path: `/${Family[enumDef.family]}/generated/${enumDef.name}.ts`,
id: enumDef.id,
statements: [enumNode]
};
}
catch (e) {
if (logger)
logger.error(`Error creating ${Family[enumDef.family]} ${enumDef.name} enum: ${e.message}`, e.stack);
else {
throw e;
}
}
}
class CodeFactory {
}
export class EnumFactory extends CodeFactory {
static generateEnumsForFamily(family) {
return buildEnums(EnumDefinitionMap.get(family));
}
static generateAll() {
let t = [];
for (const key of EnumDefinitionMap.keys()) {
try {
let e = this.generateEnumsForFamily(key);
t.push(...e);
t.push(buildEnumIndex(key, e));
}
catch (e) {
if (logger)
logger.error(`Error generating enums for ${Family[key]}: ${e.message}`, e.stack);
else {
throw e;
}
}
}
return t;
}
}
function buildEnumIndex(family, enums) {
return {
family,
path: `/${Family[family]}/generated/index.ts`,
statements: [
...enums.map((p) => factory.createExportDeclaration(undefined, false, undefined, factory.createStringLiteral(`./${p.name}.js`), undefined)),
],
};
}
function createDriverInitializationStatement(def) {
return factory.createExpressionStatement(factory.createBinaryExpression(factory.createPropertyAccessExpression(factory.createPropertyAccessExpression(factory.createThis(), factory.createIdentifier("drivers")), factory.createIdentifier(def.id)), factory.createToken(ts.SyntaxKind.EqualsToken), factory.createCallExpression(factory.createPropertyAccessExpression(factory.createIdentifier("Driver"), factory.createIdentifier("create")), undefined, [
factory.createStringLiteral("ST"),
factory.createThis(),
factory.createAsExpression(factory.createPropertyAccessExpression(factory.createIdentifier("nodeInfo"), factory.createIdentifier("property")), factory.createTypeReferenceNode(factory.createIdentifier("DriverState"), undefined)),
factory.createObjectLiteralExpression([
factory.createPropertyAssignment(factory.createIdentifier("uom"), factory.createPropertyAccessExpression(factory.createIdentifier("UnitOfMeasure"), factory.createIdentifier(UnitOfMeasure[def.dataType[0]?.uom] ?? "Unknown"))),
factory.createPropertyAssignment(factory.createIdentifier("label"), factory.createStringLiteral(def.label)),
factory.createPropertyAssignment(factory.createIdentifier("name"), factory.createStringLiteral(def.name)),
], false),
])));
}
function createDriverSignatureReturnType(def) {
if (def.enum) {
return factory.createUnionTypeNode(Object.keys(def.values).map((p) => factory.createLiteralTypeNode(factory.createNumericLiteral(p))));
}
else
return factory.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword);
}
function createDriverPropertyReturnType(def) {
if (def.enum) {
{
if (Object.keys(def.values).length == 2) {
return factory.createKeywordTypeNode(ts.SyntaxKind.BooleanKeyword);
}
return factory.createUnionTypeNode(Object.keys(def.values).map((p) => factory.createLiteralTypeNode(factory.createNumericLiteral(p))));
// return factory.createUnionTypeNode(
// Object.values(def.values).map((p) => factory.createTypeReferenceNode(
// factory.createQualifiedName(
// factory.createIdentifier("UnitOfMeasure"),
// factory.createIdentifier(UnitOfMeasure)
// ),
// undefined
// )))
}
}
else
return factory.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword);
}
function createParameterSignature(def) {
return factory.createParameterDeclaration(undefined, undefined, factory.createIdentifier(def.id ?? "value"), undefined, undefined, undefined);
}
function createCommandSignature(def) {
return factory.createPropertySignature(undefined, factory.createIdentifier(def.id), undefined, factory.createFunctionTypeNode(undefined, def.parameters ? Object.values(def.parameters).map(createParameterSignature) : [], factory.createTypeReferenceNode(factory.createIdentifier("Promise"), [
factory.createKeywordTypeNode(ts.SyntaxKind.BooleanKeyword),
])));
}
function createDriverSignature(def) {
return factory.createPropertySignature(undefined, factory.createIdentifier(def.id), factory.createToken(ts.SyntaxKind.QuestionToken), factory.createTypeLiteralNode([
factory.createPropertySignature(undefined, factory.createIdentifier("uom"), undefined, def.dataType
? factory.createUnionTypeNode(Object.values(def.dataType).map((p) => createTypeNodeForUOM(p.uom)))
: factory.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword)),
factory.createPropertySignature(undefined, factory.createIdentifier("value"), undefined, def.dataType
? factory.createUnionTypeNode(Object.values(def.dataType).map(createDriverSignatureReturnType))
: factory.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword)),
]));
}
function createTypeNodeForUOM(uom) {
return factory.createTypeReferenceNode(factory.createQualifiedName(factory.createIdentifier("UnitOfMeasure"), factory.createIdentifier(UnitOfMeasure[uom] ?? "Unknown")));
}
function createParameterDeclarationSignature(def) {
return factory.createParameterDeclaration(undefined, undefined, factory.createIdentifier(def.name ?? "value"), undefined, undefined, undefined);
}
function createCommandMethodDeclaration(def) {
return factory.createMethodDeclaration([factory.createToken(ts.SyntaxKind.AsyncKeyword)], undefined, factory.createIdentifier(def.name), undefined, undefined, def.parameters ? Object.values(def.parameters).map(createParameterDeclarationSignature) : undefined, undefined, factory.createBlock([
factory.createExpressionStatement(factory.createCallExpression(factory.createPropertyAccessExpression(factory.createThis(), factory.createIdentifier("sendCommand")), undefined, [
factory.createStringLiteral(def.id),
...(def.parameters
? [
factory.createObjectLiteralExpression([
...Object.values(def.parameters).map((p) => factory.createPropertyAssignment(factory.createIdentifier(p.id ?? "value"), factory.createIdentifier(p.name ?? "value"))),
], false),
]
: []),
])),
], true));
}
function createDriverGetDeclaration(def) {
return factory.createGetAccessorDeclaration([factory.createToken(ts.SyntaxKind.PublicKeyword)], factory.createIdentifier(def.name), [], factory.createUnionTypeNode(Object.values(def.dataType).map(createDriverPropertyReturnType)), factory.createBlock([
factory.createReturnStatement(factory.createPropertyAccessChain(factory.createPropertyAccessExpression(factory.createPropertyAccessExpression(factory.createThis(), factory.createIdentifier("drivers")), factory.createIdentifier(def.id)), factory.createToken(ts.SyntaxKind.QuestionDotToken), factory.createIdentifier("value"))),
], true));
}
export function createNodeClass(nodeClassDef) {
return {
name: nodeClassDef.name,
id: nodeClassDef.id,
statements: [
factory.createImportDeclaration(undefined, factory.createImportClause(false, undefined, factory.createNamedImports([
factory.createImportSpecifier(false, undefined, factory.createIdentifier("UnitOfMeasure")),
])), factory.createStringLiteral("../../../Definitions/Global/UOM.js"), undefined),
factory.createImportDeclaration(undefined, factory.createImportClause(false, undefined, factory.createNamedImports([
factory.createImportSpecifier(false, undefined, factory.createIdentifier("Family")),
])), factory.createStringLiteral("../../../Definitions/Global/Families.js"), undefined),
factory.createImportDeclaration(undefined, factory.createImportClause(true, undefined, factory.createNamedImports([
factory.createImportSpecifier(false, undefined, factory.createIdentifier("NodeInfo")),
])), factory.createStringLiteral("../../../Definitions/NodeInfo.js"), undefined),
factory.createImportDeclaration(undefined, factory.createImportClause(true, undefined, factory.createNamedImports([factory.createImportSpecifier(false, undefined, factory.createIdentifier("ISY"))])), factory.createStringLiteral("../../../ISY.js"), undefined),
factory.createImportDeclaration(undefined, factory.createImportClause(false, undefined, factory.createNamedImports([
factory.createImportSpecifier(false, undefined, factory.createIdentifier("ISYDeviceNode")),
])), factory.createStringLiteral("../../../ISYNode.js"), undefined),
factory.createImportDeclaration(undefined, factory.createImportClause(false, undefined, factory.createNamedImports([
factory.createImportSpecifier(false, undefined, factory.createIdentifier("Driver")),
])), factory.createStringLiteral("../../../Definitions/Global/Drivers.js"), undefined),
factory.createImportDeclaration(undefined, factory.createImportClause(true, undefined, factory.createNamedImports([
factory.createImportSpecifier(false, undefined, factory.createIdentifier("DriverState")),
])), factory.createStringLiteral("../../../Model/DriverState.js"), undefined),
factory.createVariableStatement([factory.createToken(ts.SyntaxKind.ExportKeyword)], factory.createVariableDeclarationList([
factory.createVariableDeclaration(factory.createIdentifier("nodeDefId"), undefined, undefined, factory.createStringLiteral(nodeClassDef.id)),
], ts.NodeFlags.Const)),
factory.createTypeAliasDeclaration(undefined, factory.createIdentifier("Commands"), undefined, factory.createTypeLiteralNode([...Object.values(nodeClassDef.commands).map(createCommandSignature)])),
factory.createTypeAliasDeclaration(undefined, factory.createIdentifier("Drivers"), undefined, factory.createTypeLiteralNode([...Object.values(nodeClassDef.drivers).map(createDriverSignature)])),
factory.createClassDeclaration([factory.createToken(ts.SyntaxKind.ExportKeyword)], factory.createIdentifier(nodeClassDef.name), undefined, [
factory.createHeritageClause(ts.SyntaxKind.ExtendsKeyword, [
factory.createExpressionWithTypeArguments(factory.createIdentifier("ISYDeviceNode"), [
factory.createTypeReferenceNode(factory.createQualifiedName(factory.createIdentifier("Family"), factory.createIdentifier(Family[nodeClassDef.family])), undefined),
factory.createTypeOperatorNode(ts.SyntaxKind.KeyOfKeyword, factory.createTypeReferenceNode(factory.createIdentifier("Drivers"), undefined)),
factory.createTypeOperatorNode(ts.SyntaxKind.KeyOfKeyword, factory.createTypeReferenceNode(factory.createIdentifier("Commands"), undefined)),
]),
]),
], [
factory.createPropertyDeclaration([factory.createToken(ts.SyntaxKind.PublicKeyword), factory.createToken(ts.SyntaxKind.ReadonlyKeyword)], factory.createIdentifier("commands"), undefined, factory.createTypeReferenceNode(factory.createIdentifier("Commands"), undefined), factory.createObjectLiteralExpression([
...Object.values(nodeClassDef.commands).map((c) => factory.createPropertyAssignment(factory.createIdentifier(c.id), factory.createPropertyAccessExpression(factory.createThis(), factory.createIdentifier(c.name)))),
], true)),
factory.createPropertyDeclaration([factory.createToken(ts.SyntaxKind.PublicKeyword)], factory.createIdentifier("drivers"), undefined, factory.createTypeReferenceNode(factory.createIdentifier("Drivers"), undefined), factory.createObjectLiteralExpression([], false)),
factory.createPropertyDeclaration([factory.createToken(ts.SyntaxKind.StaticKeyword)], factory.createIdentifier("nodeDefId"), undefined, undefined, factory.createStringLiteral(nodeClassDef.id)),
factory.createConstructorDeclaration(undefined, [
factory.createParameterDeclaration(undefined, undefined, factory.createIdentifier("isy"), undefined, factory.createTypeReferenceNode(factory.createIdentifier("ISY"), undefined), undefined),
factory.createParameterDeclaration(undefined, undefined, factory.createIdentifier("nodeInfo"), undefined, factory.createTypeReferenceNode(factory.createIdentifier("NodeInfo"), undefined), undefined),
], factory.createBlock([
factory.createExpressionStatement(factory.createCallExpression(factory.createSuper(), undefined, [
factory.createIdentifier("isy"),
factory.createIdentifier("nodeInfo"),
])),
...Object.values(nodeClassDef.drivers).map(createDriverInitializationStatement),
], true)),
...Object.values(nodeClassDef.commands).map(createCommandMethodDeclaration),
...Object.values(nodeClassDef.drivers).map(createDriverGetDeclaration),
]),
],
};
}
export function createMemberName(name, mapNullishTo = 'Unknown') {
let label = pascalCase(name) ?? 'Unknown';
if (!label.substring(0, 1).match(/[a-zA-Z]/)) {
if (!isNaN(Number.parseInt(label))) {
return factory.createIdentifier(`_${label}`);
}
return factory.createStringLiteral(label);
}
return factory.createIdentifier(label);
}
//# sourceMappingURL=EnumFactory.js.map