UNPKG

node-red-contrib-home-assistant-websocket

Version:
195 lines (194 loc) 7.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.shouldInclude = shouldInclude; exports.shouldIncludeEvent = shouldIncludeEvent; exports.toCamelCase = toCamelCase; exports.getWaitStatusText = getWaitStatusText; exports.getTimeInMilliseconds = getTimeInMilliseconds; exports.isValidDate = isValidDate; exports.parseTime = parseTime; exports.getEntitiesFromJsonata = getEntitiesFromJsonata; exports.addEventListeners = addEventListeners; exports.removeEventListeners = removeEventListeners; exports.validEntityId = validEntityId; exports.isNodeRedEnvVar = isNodeRedEnvVar; exports.checkValidServerConfig = checkValidServerConfig; exports.containsMustache = containsMustache; const globals_1 = require("../globals"); function shouldInclude(targetString, includeRegex, excludeRegex) { if (!targetString || (!includeRegex && !excludeRegex)) { return true; } // If include regex isn't passed then include everything since test will be skipped // otherwise default to false and set in regex test let shouldIncludeTest = !includeRegex; let shouldExcludeTest = false; if (includeRegex && includeRegex.test(targetString)) { shouldIncludeTest = true; } if (excludeRegex && excludeRegex.test(targetString)) { shouldExcludeTest = true; } return shouldIncludeTest && !shouldExcludeTest; } function shouldIncludeEvent(eventId, filter, filterType) { if (!filter) return true; if (typeof filter === 'string') { if (filterType === 'substring') { return eventId.includes(filter); } if (filterType === 'regex') { return new RegExp(filter).test(eventId); } } if (Array.isArray(filter)) { return filter.includes(eventId); } return eventId === filter; } /** * Converts a string to camel case. * @param str - The string to convert. * @returns The camel case string. */ function toCamelCase(str) { var _a; const wordPattern = /[A-Z][a-z]+|[A-Z]+(?=[A-Z][a-z])|[A-Z]+|[a-z]+|[0-9]+/g; const upperFirst = (str) => str.charAt(0).toUpperCase() + str.slice(1); return ((_a = str.match(wordPattern)) !== null && _a !== void 0 ? _a : []) .map((word, index) => index === 0 ? word.toLocaleLowerCase() : upperFirst(word.toLowerCase())) .join(''); } /** * Returns a string describing the wait status based on the provided timeout and units. * @param timeout - The amount of time to wait. * @param timeoutUnits - The units of time for the timeout (milliseconds, minutes, hours, or days). * @returns A string describing the wait status. */ function getWaitStatusText(timeout, timeoutUnits) { const timeoutMs = getTimeInMilliseconds(timeout, timeoutUnits); switch (timeoutUnits) { case 'milliseconds': return `waiting for ${timeout} milliseconds`; case 'hours': case 'days': return `waiting until ${timeoutStatus(timeoutMs)}`; case 'minutes': default: return `waiting for ${timeout} ${timeoutUnits}: ${timeoutStatus(timeoutMs)}`; } } /** * Converts a time value in various units to milliseconds. * @param value - The time value to convert. * @param valueUnits - The units of the time value. * @returns The time value in milliseconds. */ function getTimeInMilliseconds(value, valueUnits) { switch (valueUnits) { case 'milliseconds': return value; case 'minutes': return value * 60000; case 'hours': return value * 3.6e6; case 'days': return value * 8.64e7; default: return value * 1000; } } /** * Returns a formatted string representing a timeout date and time. * @param milliseconds - The number of milliseconds until the timeout. * @returns A string representing the timeout date and time in the format "MMM d, HH:mm:ss". */ function timeoutStatus(milliseconds = 0) { const timeout = Date.now() + milliseconds; const timeoutStr = new Date(timeout).toLocaleDateString('en-US', { month: 'short', day: 'numeric', hour12: false, hour: 'numeric', minute: 'numeric', second: 'numeric', }); return timeoutStr; } /** * Checks if a given value is a valid date. * @param val - The value to check. * @returns True if the value is a valid date, false otherwise. */ function isValidDate(val) { const d = new Date(val); return d instanceof Date && !isNaN(d.getTime()); } /** * Parses a string representing a time in the format "HH:mm:ss" and returns an object with the hour, minutes, and seconds. * @param time - The time string to parse. * @returns An object with the hour, minutes, and seconds, or undefined if the input string is not in the correct format. */ function parseTime(time) { const regex = /^(0?\d|1\d|2[0-3]):([0-5]\d)(?::([0-5]\d))?$/; const matches = time.match(regex); if (!matches) return; const [, hour, minutes, seconds = 0] = matches; return { hour: Number(hour), minutes: Number(minutes), seconds: Number(seconds), }; } function getEntitiesFromJsonata(jsonata) { // This regular expression matches the pattern $entities('...') or $entities("...") in a string. // It is used to extract all entity names from a JSONata expression that uses the $entities function. // The regular expression has a global flag (g) which means it will find all matches in the string, not just the first one. const regex = /\$entities\((?:'([^']*)'|"([^"]*)")\)/g; const matches = jsonata.matchAll(regex); return new Set(Array.from(matches) .map((match) => match[1] || match[2]) .filter((entityId) => validEntityId(entityId))); } function addEventListeners(eventListeners, emitter) { if (!emitter) return; eventListeners.forEach(([event, callback]) => { emitter.on(event, callback); }); } function removeEventListeners(eventListeners, emitter) { if (!emitter) return; eventListeners.forEach(([event, callback]) => { emitter.off(event, callback); }); } // https://github.com/home-assistant/core/blob/77ee72cbb9fed55779b0ee58443c3f41e5b35f5a/homeassistant/core.py#L125 function validEntityId(entityId) { return /^(?!.+__)(?!_)[\da-z_]+(?<!_)\.(?!_)[\da-z_]+(?<!_)$/.test(entityId); } function isNodeRedEnvVar(envVar) { // Check for ${env-var} return /^\$\{[a-zA-Z_][a-zA-Z0-9_]*\}$/.test(envVar); } function checkValidServerConfig(node, serverNodeId) { const serverConfigNode = globals_1.RED.nodes.getNode(serverNodeId !== null && serverNodeId !== void 0 ? serverNodeId : ''); if (!serverConfigNode) { node.status({ fill: 'red', shape: 'dot', text: globals_1.RED._('home-assistant.status.error'), }); throw new Error('Server config node not found'); } return true; } function containsMustache(str) { const regex = /{{(?:(?!}}).+)}}/g; return regex.test(str); }