home-assistant-javascript-templates 7.0.0 → 7.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -1
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.js +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -1
- package/package.json +9 -14
package/README.md
CHANGED
|
@@ -220,12 +220,20 @@ is_state('device_tracker.paulus', ['not_home', 'work']) // check for a list of v
|
|
|
220
220
|
|
|
221
221
|
#### state_attr
|
|
222
222
|
|
|
223
|
-
Method to return the value of
|
|
223
|
+
Method to return the value of a state attribute of an entity or `undefined` if the entity doesn’t exist.
|
|
224
224
|
|
|
225
225
|
```javascript
|
|
226
226
|
state_attr('device_tracker.paulus', 'battery')
|
|
227
227
|
```
|
|
228
228
|
|
|
229
|
+
#### state_attr_translated
|
|
230
|
+
|
|
231
|
+
Method to return the translated value of a state attribute of an entity or `undefined` if the entity doesn’t exist.
|
|
232
|
+
|
|
233
|
+
```javascript
|
|
234
|
+
state_attr_translated('device_tracker.paulus', 'battery')
|
|
235
|
+
```
|
|
236
|
+
|
|
229
237
|
#### is_state_attr
|
|
230
238
|
|
|
231
239
|
Method to test if the given entity attribute is the specified state. It returns a `boolean`, if the entity doesn‘t exist it returns `false`.
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -41,6 +41,7 @@ interface Hass {
|
|
|
41
41
|
user: User;
|
|
42
42
|
language: string;
|
|
43
43
|
formatEntityState: (state: State) => string | undefined;
|
|
44
|
+
formatEntityAttributeValue: (state: State, attr: string) => string | undefined;
|
|
44
45
|
}
|
|
45
46
|
interface HomeAssistant extends HTMLElement {
|
|
46
47
|
hass: Hass;
|
package/dist/esm/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{getPromisableResult as e}from"get-promisable-result";const t="[home-assistant-javascript-templates]",s=/^([a-z_]+)\.(\w+)$/;var i,a,n,r;!function(e){e.UNKNOWN="unknown",e.UNAVAILABLE="unavailable"}(i||(i={})),function(e){e.AREA_ID="area_id",e.NAME="name"}(a||(a={})),function(e){e.PANEL_URL="panel_url",e.LANG="lang"}(n||(n={})),function(e){e.LOCATION_CHANGED="location-changed",e.TRANSLATIONS_UPDATED="translations-updated",e.POPSTATE="popstate",e.SUBSCRIBE_EVENTS="subscribe_events",e.STATE_CHANGE_EVENT="state_changed"}(r||(r={}));const d="refs",o=e=>e.reduce((e,t)=>{const[i,a]=t;return e[i.replace(s,"$2")]=a,e},{}),c=e=>e.includes("."),h="ref",_="value",u="toJSON",p=e=>`${h}.${e}`;function l(e,s,d){const l=()=>Object.entries(e.hass.areas),v=()=>Object.entries(e.hass.devices),b=()=>Object.entries(e.hass.entities),f=new Set,g=new Map,m=(e,t)=>{d&&console.warn(`${e} ${t} used in a JavaScript template doesn't exist`)},w=e=>m("Entity",e),E=e=>m("Domain",e),y=e=>{const t=new SyntaxError(e);if(s)throw t;d&&console.warn(t)},A=t=>{e.hass.states[t]?f.add(t):w(t)},N=e=>{f.add(e)},T=(t,s)=>{const{with_unit:i=!1,rounded:a=!1}=s;if(t){const s=t.state,n=t.attributes.unit_of_measurement,r=Number(a),d=!1===a||isNaN(Number(s))?s:new Intl.NumberFormat(e.hass.language,{minimumFractionDigits:r,maximumFractionDigits:r}).format(Number(s));return i&&n?`${d} ${n}`:d}},S=e=>new Proxy(e,{get:(e,t)=>"state_with_unit"===t?T(e,{rounded:!0,with_unit:!0}):e[t]});return{get hass(){return e.hass},states:new Proxy((s,i={})=>{if(c(s))return A(s),T(e.hass.states[s],i);throw SyntaxError(`${t}: states method cannot be used with a domain, use it as an object instead.`)},{get(t,s){if(c(s))return A(s),S(e.hass.states[s]);const i=Object.entries(e.hass.states).filter(([e])=>e.startsWith(s));return i.length||E(s),new Proxy(o(i),{get:(e,t)=>(A(`${s}.${t}`),S(e[t]))})}}),state_translated(t){if(A(t),e.hass.states[t])return e.hass.formatEntityState(e.hass.states[t])},is_state(t,s){var i;return A(t),Array.isArray(s)?s.some(s=>{var i;return(null===(i=e.hass.states[t])||void 0===i?void 0:i.state)===s}):(null===(i=e.hass.states[t])||void 0===i?void 0:i.state)===s},state_attr(t,s){var i,a;return A(t),null===(a=null===(i=e.hass.states[t])||void 0===i?void 0:i.attributes)||void 0===a?void 0:a[s]},is_state_attr(e,t,s){return this.state_attr(e,t)===s},has_value(e){return this.states(e)?!(this.is_state(e,i.UNKNOWN)||this.is_state(e,i.UNAVAILABLE)):(w(e),!1)},entities:new Proxy(t=>{if(void 0===t)return e.hass.entities;if(c(t))return A(t),e.hass.entities[t];const s=b().filter(([e])=>e.startsWith(t));return s.length||E(t),new Proxy(o(s),{get:(e,s)=>(A(`${t}.${s}`),e[s])})},{get:(e,t)=>e(t)}),entity_prop(t,s){var i;return A(t),null===(i=e.hass.entities[t])||void 0===i?void 0:i[s]},is_entity_prop(e,t,s){return this.entity_prop(e,t)===s},devices:new Proxy(s=>{if(void 0===s)return e.hass.devices;if(c(s))throw SyntaxError(`${t}: devices method cannot be used with an entity id, you should use a device id instead.`);return e.hass.devices[s]},{get(s,i){if(c(i))throw SyntaxError(`${t}: devices cannot be accesed using an entity id, you should use a device id instead.`);return e.hass.devices[i]}}),device_attr(t,s){var i,a,n;if(c(t)){A(t);const n=null===(i=e.hass.entities[t])||void 0===i?void 0:i.device_id;return null===(a=e.hass.devices[n])||void 0===a?void 0:a[s]}return null===(n=e.hass.devices[t])||void 0===n?void 0:n[s]},is_device_attr(e,t,s){return this.device_attr(e,t)===s},device_id(t){var s;if(c(t))return A(t),null===(s=e.hass.entities[t])||void 0===s?void 0:s.device_id;const i=v().find(e=>e[1].name===t);return null==i?void 0:i[0]},device_name(t){var s,i,a,n,r;if(c(t)){A(t);const n=null===(s=e.hass.entities[t])||void 0===s?void 0:s.device_id;return null!==(a=null===(i=e.hass.devices[n])||void 0===i?void 0:i.name)&&void 0!==a?a:void 0}return null!==(r=null===(n=e.hass.devices[t])||void 0===n?void 0:n.name)&&void 0!==r?r:void 0},areas:()=>l().map(([,e])=>e.area_id),area_id(t){var s,i;if(t in e.hass.devices)return this.device_attr(t,a.AREA_ID);const n=null===(s=e.hass.entities[t])||void 0===s?void 0:s.device_id;if(n)return this.device_attr(n,a.AREA_ID);const r=l().find(([,e])=>e.name===t);return null===(i=null==r?void 0:r[1])||void 0===i?void 0:i.area_id},area_name(t){var s,i;let n;t in e.hass.devices&&(n=this.device_attr(t,a.AREA_ID));const r=null===(s=e.hass.entities[t])||void 0===s?void 0:s.device_id;r&&(n=this.device_attr(r,a.AREA_ID));const d=l().find(([,e])=>e.area_id===t||e.area_id===n);return null===(i=null==d?void 0:d[1])||void 0===i?void 0:i.name},area_entities(e){const t=l().find(([,t])=>t.area_id===e||t.name===e);return t?b().filter(([,e])=>e.area_id===t[1].area_id).map(([e])=>e):[]},area_devices(e){const t=l().find(([,t])=>t.area_id===e||t.name===e);return t?v().filter(([,e])=>e.area_id===t[1].area_id).map(([,e])=>e.id):[]},get user_name(){return e.hass.user.name},get user_is_admin(){return e.hass.user.is_admin},get user_is_owner(){return e.hass.user.is_owner},get user_agent(){return window.navigator.userAgent},get tracked(){return f},cleanTracked(){f.clear()},ref(e,t,s=void 0){const i=p(t);if(g.has(t))return g.get(t);const a=new Proxy({[_]:s,[u](){return this[_]}},{get(e,t,s){if(t===_||t===u)return N(i),Reflect.get(e,t,s);y(`${t} is not a valid ${h} property. A ${h} only exposes a "${_}" property`)},set(t,s,a){if(s===_){const s=t[_];return t[_]=a,e({event_type:r.STATE_CHANGE_EVENT,data:{entity_id:i,old_state:{state:JSON.stringify(s)},new_state:{state:JSON.stringify(a)}}}),!0}return y(`property "${s}" cannot be set in a ${h}`),!1}});return g.set(t,a),a},unref(e,t){const s=p(t);g.has(t)?(g.delete(t),e(s)):y(`${t} is not a ref or it has been unrefed already`)},refs(e,t,s={}){const i=this.ref,a=this.unref,n=new Proxy(s,{get:(t,s)=>i(e,s).value,set:(t,s,a)=>(i(e,s).value=a,!0)});return Object.entries(s).forEach(s=>{const[n,r]=s;g.has(n)&&a(t,n),i(e,n,r)}),n},cleanRefs(e){Array.from(g.keys()).forEach(t=>{this.unref(e,t)})},clientSideProxy:new Proxy({},{get(t,s){switch(Object.values(n).includes(s)&&N(s),s){case n.PANEL_URL:return window.location.pathname;case n.LANG:return e.hass.language}d&&console.warn(`clientSideProxy should only be used to access these variables: ${Object.values(n).join(", ")}`)}})}}class v{constructor(e,t){const{throwErrors:s=!1,throwWarnings:i=!0,variables:a={},refs:r={},refsVariableName:o=d,autoReturn:c=!0}=t;this._throwErrors=s,this._throwWarnings=i,this._variables=a,this._refsVariableName=o,this._autoReturn=c,this._subscriptions=new Map,this._clientSideEntitiesRegExp=new RegExp(`(^|[ \\?(+:\\{\\[><,])(${Object.values(n).join("|")})($|[ \\?)+:\\}\\]><.,])`,"gm"),this._scopped=l(e,s,i),this.refs=r,this._watchForPanelUrlChange(),this._watchForEntitiesChange(),this._watchForLanguageChange()}_executeRenderingFunctions(e){this._subscriptions.get(e).forEach((e,t)=>{e.forEach((e,s)=>{this.trackTemplate(t,s,e)})})}_watchForPanelUrlChange(){window.addEventListener(r.LOCATION_CHANGED,()=>{this._panelUrlWatchCallback()}),window.addEventListener(r.POPSTATE,()=>{this._panelUrlWatchCallback()})}_panelUrlWatchCallback(){this._subscriptions.has(n.PANEL_URL)&&this._executeRenderingFunctions(n.PANEL_URL)}_watchForEntitiesChange(){window.hassConnection.then(e=>{e.conn.subscribeMessage(e=>this._entityWatchCallback(e),{type:r.SUBSCRIBE_EVENTS,event_type:r.STATE_CHANGE_EVENT})})}_watchForLanguageChange(){window.addEventListener(r.TRANSLATIONS_UPDATED,()=>{this._subscriptions.has(n.LANG)&&this._executeRenderingFunctions(n.LANG)})}_entityWatchCallback(e){if(this._subscriptions.size){const t=e.data.entity_id;this._subscriptions.has(t)&&this._executeRenderingFunctions(t)}}_storeTracked(e,t,s){this._scopped.tracked.forEach(i=>{const a=[t,s];if(this._subscriptions.has(i)){const s=this._subscriptions.get(i);if(s.has(e)){const i=s.get(e);i.has(t)||i.set(...a)}else s.set(e,new Map([a]))}else this._subscriptions.set(i,new Map([[e,new Map([a])]]))})}_untrackTemplate(e,t){this._subscriptions.forEach((s,i)=>{if(s.has(e)){const a=s.get(e);a.delete(t),0===a.size&&(s.delete(e),0===s.size&&this._subscriptions.delete(i))}})}renderTemplate(e,t={}){try{const{variables:s={},refs:i={}}=t,a=new Map(Object.entries(Object.assign(Object.assign({},this._variables),s))),n=e.trim().replace(this._clientSideEntitiesRegExp,"$1clientSide.$2$3"),r=n.includes("return")||!this._autoReturn?n:`return ${n}`;return new Function("hass","states","state_translated","is_state","state_attr","is_state_attr","has_value","entities","entity_prop","is_entity_prop","devices","device_attr","is_device_attr","device_id","device_name","areas","area_id","area_name","area_entities","area_devices","user_name","user_is_admin","user_is_owner","user_agent","clientSide","ref","unref",this._refsVariableName,...Array.from(a.keys()),`"use strict"; ${r}`)(this._scopped.hass,this._scopped.states,this._scopped.state_translated.bind(this._scopped),this._scopped.is_state.bind(this._scopped),this._scopped.state_attr.bind(this._scopped),this._scopped.is_state_attr.bind(this._scopped),this._scopped.has_value.bind(this._scopped),this._scopped.entities,this._scopped.entity_prop,this._scopped.is_entity_prop.bind(this._scopped),this._scopped.devices,this._scopped.device_attr.bind(this._scopped),this._scopped.is_device_attr.bind(this._scopped),this._scopped.device_id.bind(this._scopped),this._scopped.device_name.bind(this._scopped),this._scopped.areas.bind(this._scopped),this._scopped.area_id.bind(this._scopped),this._scopped.area_name.bind(this._scopped),this._scopped.area_entities.bind(this._scopped),this._scopped.area_devices.bind(this._scopped),this._scopped.user_name,this._scopped.user_is_admin,this._scopped.user_is_owner,this._scopped.user_agent,this._scopped.clientSideProxy,this._scopped.ref.bind(this._scopped,this._entityWatchCallback.bind(this)),this._scopped.unref.bind(this._scopped,this.cleanTracked.bind(this)),this._scopped.refs(this._entityWatchCallback.bind(this),this.cleanTracked.bind(this),i),...Array.from(a.values()))}catch(e){if(this._throwErrors)throw e;return void(this._throwWarnings&&console.warn(e))}}trackTemplate(e,t,s={}){this._scopped.cleanTracked();const i=this.renderTemplate(e,s);return this._storeTracked(e,t,s),t(i),()=>this._untrackTemplate(e,t)}cleanTracked(e){e?this._subscriptions.has(e)&&this._subscriptions.delete(e):this._subscriptions.clear()}get variables(){return this._variables}set variables(e){this._variables=e}get refs(){return this._scopped.refs(this._entityWatchCallback.bind(this),this.cleanTracked.bind(this))}set refs(e){this._scopped.cleanRefs(this.cleanTracked.bind(this)),this._scopped.refs(this._entityWatchCallback.bind(this),this.cleanTracked.bind(this),e)}}class b{constructor(t,s={}){this._renderer=e(()=>t.hass,e=>!!(e&&e.areas&&e.devices&&e.entities&&e.states&&e.user),{retries:100,delay:50,rejectMessage:"The provided element doesn't contain a proper or initialised hass object"}).then(()=>new v(t,s))}getRenderer(){return this._renderer}}export{b as default};
|
|
1
|
+
import{getPromisableResult as e}from"get-promisable-result";const t="[home-assistant-javascript-templates]",s=/^([a-z_]+)\.(\w+)$/;var i,a,r,n;!function(e){e.UNKNOWN="unknown",e.UNAVAILABLE="unavailable"}(i||(i={})),function(e){e.AREA_ID="area_id",e.NAME="name"}(a||(a={})),function(e){e.PANEL_URL="panel_url",e.LANG="lang"}(r||(r={})),function(e){e.LOCATION_CHANGED="location-changed",e.TRANSLATIONS_UPDATED="translations-updated",e.POPSTATE="popstate",e.SUBSCRIBE_EVENTS="subscribe_events",e.STATE_CHANGE_EVENT="state_changed"}(n||(n={}));const d="refs",o=e=>e.reduce((e,t)=>{const[i,a]=t;return e[i.replace(s,"$2")]=a,e},{}),c=e=>e.includes("."),h="ref",_="value",u="toJSON",p=e=>`${h}.${e}`;function l(e,s,d){const l=()=>Object.entries(e.hass.areas),v=()=>Object.entries(e.hass.devices),b=()=>Object.entries(e.hass.entities),f=new Set,g=new Map,m=(e,t)=>{d&&console.warn(`${e} ${t} used in a JavaScript template doesn't exist`)},w=e=>m("Entity",e),E=e=>m("Domain",e),y=e=>{const t=new SyntaxError(e);if(s)throw t;d&&console.warn(t)},A=t=>{e.hass.states[t]?f.add(t):w(t)},N=e=>{f.add(e)},T=(t,s)=>{const{with_unit:i=!1,rounded:a=!1}=s;if(t){const s=t.state,r=t.attributes.unit_of_measurement,n=Number(a),d=!1===a||isNaN(Number(s))?s:new Intl.NumberFormat(e.hass.language,{minimumFractionDigits:n,maximumFractionDigits:n}).format(Number(s));return i&&r?`${d} ${r}`:d}},S=e=>new Proxy(e,{get:(e,t)=>"state_with_unit"===t?T(e,{rounded:!0,with_unit:!0}):e[t]});return{get hass(){return e.hass},states:new Proxy((s,i={})=>{if(c(s))return A(s),T(e.hass.states[s],i);throw SyntaxError(`${t}: states method cannot be used with a domain, use it as an object instead.`)},{get(t,s){if(c(s))return A(s),S(e.hass.states[s]);const i=Object.entries(e.hass.states).filter(([e])=>e.startsWith(s));return i.length||E(s),new Proxy(o(i),{get:(e,t)=>(A(`${s}.${t}`),S(e[t]))})}}),state_translated(t){if(A(t),e.hass.states[t])return e.hass.formatEntityState(e.hass.states[t])},is_state(t,s){var i;return A(t),Array.isArray(s)?s.some(s=>{var i;return(null===(i=e.hass.states[t])||void 0===i?void 0:i.state)===s}):(null===(i=e.hass.states[t])||void 0===i?void 0:i.state)===s},state_attr(t,s){var i,a;return A(t),null===(a=null===(i=e.hass.states[t])||void 0===i?void 0:i.attributes)||void 0===a?void 0:a[s]},state_attr_translated(t,s){if(A(t),e.hass.states[t])return e.hass.formatEntityAttributeValue(e.hass.states[t],s)},is_state_attr(e,t,s){return this.state_attr(e,t)===s},has_value(e){return this.states(e)?!(this.is_state(e,i.UNKNOWN)||this.is_state(e,i.UNAVAILABLE)):(w(e),!1)},entities:new Proxy(t=>{if(void 0===t)return e.hass.entities;if(c(t))return A(t),e.hass.entities[t];const s=b().filter(([e])=>e.startsWith(t));return s.length||E(t),new Proxy(o(s),{get:(e,s)=>(A(`${t}.${s}`),e[s])})},{get:(e,t)=>e(t)}),entity_prop(t,s){var i;return A(t),null===(i=e.hass.entities[t])||void 0===i?void 0:i[s]},is_entity_prop(e,t,s){return this.entity_prop(e,t)===s},devices:new Proxy(s=>{if(void 0===s)return e.hass.devices;if(c(s))throw SyntaxError(`${t}: devices method cannot be used with an entity id, you should use a device id instead.`);return e.hass.devices[s]},{get(s,i){if(c(i))throw SyntaxError(`${t}: devices cannot be accesed using an entity id, you should use a device id instead.`);return e.hass.devices[i]}}),device_attr(t,s){var i,a,r;if(c(t)){A(t);const r=null===(i=e.hass.entities[t])||void 0===i?void 0:i.device_id;return null===(a=e.hass.devices[r])||void 0===a?void 0:a[s]}return null===(r=e.hass.devices[t])||void 0===r?void 0:r[s]},is_device_attr(e,t,s){return this.device_attr(e,t)===s},device_id(t){var s;if(c(t))return A(t),null===(s=e.hass.entities[t])||void 0===s?void 0:s.device_id;const i=v().find(e=>e[1].name===t);return null==i?void 0:i[0]},device_name(t){var s,i,a,r,n;if(c(t)){A(t);const r=null===(s=e.hass.entities[t])||void 0===s?void 0:s.device_id;return null!==(a=null===(i=e.hass.devices[r])||void 0===i?void 0:i.name)&&void 0!==a?a:void 0}return null!==(n=null===(r=e.hass.devices[t])||void 0===r?void 0:r.name)&&void 0!==n?n:void 0},areas:()=>l().map(([,e])=>e.area_id),area_id(t){var s,i;if(t in e.hass.devices)return this.device_attr(t,a.AREA_ID);const r=null===(s=e.hass.entities[t])||void 0===s?void 0:s.device_id;if(r)return this.device_attr(r,a.AREA_ID);const n=l().find(([,e])=>e.name===t);return null===(i=null==n?void 0:n[1])||void 0===i?void 0:i.area_id},area_name(t){var s,i;let r;t in e.hass.devices&&(r=this.device_attr(t,a.AREA_ID));const n=null===(s=e.hass.entities[t])||void 0===s?void 0:s.device_id;n&&(r=this.device_attr(n,a.AREA_ID));const d=l().find(([,e])=>e.area_id===t||e.area_id===r);return null===(i=null==d?void 0:d[1])||void 0===i?void 0:i.name},area_entities(e){const t=l().find(([,t])=>t.area_id===e||t.name===e);return t?b().filter(([,e])=>e.area_id===t[1].area_id).map(([e])=>e):[]},area_devices(e){const t=l().find(([,t])=>t.area_id===e||t.name===e);return t?v().filter(([,e])=>e.area_id===t[1].area_id).map(([,e])=>e.id):[]},get user_name(){return e.hass.user.name},get user_is_admin(){return e.hass.user.is_admin},get user_is_owner(){return e.hass.user.is_owner},get user_agent(){return window.navigator.userAgent},get tracked(){return f},cleanTracked(){f.clear()},ref(e,t,s=void 0){const i=p(t);if(g.has(t))return g.get(t);const a=new Proxy({[_]:s,[u](){return this[_]}},{get(e,t,s){if(t===_||t===u)return N(i),Reflect.get(e,t,s);y(`${t} is not a valid ${h} property. A ${h} only exposes a "${_}" property`)},set(t,s,a){if(s===_){const s=t[_];return t[_]=a,e({event_type:n.STATE_CHANGE_EVENT,data:{entity_id:i,old_state:{state:JSON.stringify(s)},new_state:{state:JSON.stringify(a)}}}),!0}return y(`property "${s}" cannot be set in a ${h}`),!1}});return g.set(t,a),a},unref(e,t){const s=p(t);g.has(t)?(g.delete(t),e(s)):y(`${t} is not a ref or it has been unrefed already`)},refs(e,t,s={}){const i=this.ref,a=this.unref,r=new Proxy(s,{get:(t,s)=>i(e,s).value,set:(t,s,a)=>(i(e,s).value=a,!0)});return Object.entries(s).forEach(s=>{const[r,n]=s;g.has(r)&&a(t,r),i(e,r,n)}),r},cleanRefs(e){Array.from(g.keys()).forEach(t=>{this.unref(e,t)})},clientSideProxy:new Proxy({},{get(t,s){switch(Object.values(r).includes(s)&&N(s),s){case r.PANEL_URL:return window.location.pathname;case r.LANG:return e.hass.language}d&&console.warn(`clientSideProxy should only be used to access these variables: ${Object.values(r).join(", ")}`)}})}}class v{constructor(e,t){const{throwErrors:s=!1,throwWarnings:i=!0,variables:a={},refs:n={},refsVariableName:o=d,autoReturn:c=!0}=t;this._throwErrors=s,this._throwWarnings=i,this._variables=a,this._refsVariableName=o,this._autoReturn=c,this._subscriptions=new Map,this._clientSideEntitiesRegExp=new RegExp(`(^|[ \\?(+:\\{\\[><,])(${Object.values(r).join("|")})($|[ \\?)+:\\}\\]><.,])`,"gm"),this._scopped=l(e,s,i),this.refs=n,this._watchForPanelUrlChange(),this._watchForEntitiesChange(),this._watchForLanguageChange()}_executeRenderingFunctions(e){this._subscriptions.get(e).forEach((e,t)=>{e.forEach((e,s)=>{this.trackTemplate(t,s,e)})})}_watchForPanelUrlChange(){window.addEventListener(n.LOCATION_CHANGED,()=>{this._panelUrlWatchCallback()}),window.addEventListener(n.POPSTATE,()=>{this._panelUrlWatchCallback()})}_panelUrlWatchCallback(){this._subscriptions.has(r.PANEL_URL)&&this._executeRenderingFunctions(r.PANEL_URL)}_watchForEntitiesChange(){window.hassConnection.then(e=>{e.conn.subscribeMessage(e=>this._entityWatchCallback(e),{type:n.SUBSCRIBE_EVENTS,event_type:n.STATE_CHANGE_EVENT})})}_watchForLanguageChange(){window.addEventListener(n.TRANSLATIONS_UPDATED,()=>{this._subscriptions.has(r.LANG)&&this._executeRenderingFunctions(r.LANG)})}_entityWatchCallback(e){if(this._subscriptions.size){const t=e.data.entity_id;this._subscriptions.has(t)&&this._executeRenderingFunctions(t)}}_storeTracked(e,t,s){this._scopped.tracked.forEach(i=>{const a=[t,s];if(this._subscriptions.has(i)){const s=this._subscriptions.get(i);if(s.has(e)){const i=s.get(e);i.has(t)||i.set(...a)}else s.set(e,new Map([a]))}else this._subscriptions.set(i,new Map([[e,new Map([a])]]))})}_untrackTemplate(e,t){this._subscriptions.forEach((s,i)=>{if(s.has(e)){const a=s.get(e);a.delete(t),0===a.size&&(s.delete(e),0===s.size&&this._subscriptions.delete(i))}})}renderTemplate(e,t={}){try{const{variables:s={},refs:i={}}=t,a=new Map(Object.entries(Object.assign(Object.assign({},this._variables),s))),r=e.trim().replace(this._clientSideEntitiesRegExp,"$1clientSide.$2$3"),n=r.includes("return")||!this._autoReturn?r:`return ${r}`;return new Function("hass","states","state_translated","is_state","state_attr","state_attr_translated","is_state_attr","has_value","entities","entity_prop","is_entity_prop","devices","device_attr","is_device_attr","device_id","device_name","areas","area_id","area_name","area_entities","area_devices","user_name","user_is_admin","user_is_owner","user_agent","clientSide","ref","unref",this._refsVariableName,...Array.from(a.keys()),`"use strict"; ${n}`)(this._scopped.hass,this._scopped.states,this._scopped.state_translated.bind(this._scopped),this._scopped.is_state.bind(this._scopped),this._scopped.state_attr.bind(this._scopped),this._scopped.state_attr_translated.bind(this._scopped),this._scopped.is_state_attr.bind(this._scopped),this._scopped.has_value.bind(this._scopped),this._scopped.entities,this._scopped.entity_prop,this._scopped.is_entity_prop.bind(this._scopped),this._scopped.devices,this._scopped.device_attr.bind(this._scopped),this._scopped.is_device_attr.bind(this._scopped),this._scopped.device_id.bind(this._scopped),this._scopped.device_name.bind(this._scopped),this._scopped.areas.bind(this._scopped),this._scopped.area_id.bind(this._scopped),this._scopped.area_name.bind(this._scopped),this._scopped.area_entities.bind(this._scopped),this._scopped.area_devices.bind(this._scopped),this._scopped.user_name,this._scopped.user_is_admin,this._scopped.user_is_owner,this._scopped.user_agent,this._scopped.clientSideProxy,this._scopped.ref.bind(this._scopped,this._entityWatchCallback.bind(this)),this._scopped.unref.bind(this._scopped,this.cleanTracked.bind(this)),this._scopped.refs(this._entityWatchCallback.bind(this),this.cleanTracked.bind(this),i),...Array.from(a.values()))}catch(e){if(this._throwErrors)throw e;return void(this._throwWarnings&&console.warn(e))}}trackTemplate(e,t,s={}){this._scopped.cleanTracked();const i=this.renderTemplate(e,s);return this._storeTracked(e,t,s),t(i),()=>this._untrackTemplate(e,t)}cleanTracked(e){e?this._subscriptions.has(e)&&this._subscriptions.delete(e):this._subscriptions.clear()}get variables(){return this._variables}set variables(e){this._variables=e}get refs(){return this._scopped.refs(this._entityWatchCallback.bind(this),this.cleanTracked.bind(this))}set refs(e){this._scopped.cleanRefs(this.cleanTracked.bind(this)),this._scopped.refs(this._entityWatchCallback.bind(this),this.cleanTracked.bind(this),e)}}class b{constructor(t,s={}){this._renderer=e(()=>t.hass,e=>!!(e&&e.areas&&e.devices&&e.entities&&e.states&&e.user),{retries:100,delay:50,rejectMessage:"The provided element doesn't contain a proper or initialised hass object"}).then(()=>new v(t,s))}getRenderer(){return this._renderer}}export{b as default};
|
package/dist/index.d.ts
CHANGED
|
@@ -41,6 +41,7 @@ interface Hass {
|
|
|
41
41
|
user: User;
|
|
42
42
|
language: string;
|
|
43
43
|
formatEntityState: (state: State) => string | undefined;
|
|
44
|
+
formatEntityAttributeValue: (state: State, attr: string) => string | undefined;
|
|
44
45
|
}
|
|
45
46
|
interface HomeAssistant extends HTMLElement {
|
|
46
47
|
hass: Hass;
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var e=require("get-promisable-result");const t="[home-assistant-javascript-templates]",s=/^([a-z_]+)\.(\w+)$/;var i,a,n,r;!function(e){e.UNKNOWN="unknown",e.UNAVAILABLE="unavailable"}(i||(i={})),function(e){e.AREA_ID="area_id",e.NAME="name"}(a||(a={})),function(e){e.PANEL_URL="panel_url",e.LANG="lang"}(n||(n={})),function(e){e.LOCATION_CHANGED="location-changed",e.TRANSLATIONS_UPDATED="translations-updated",e.POPSTATE="popstate",e.SUBSCRIBE_EVENTS="subscribe_events",e.STATE_CHANGE_EVENT="state_changed"}(r||(r={}));const d="refs",o=e=>e.reduce((e,t)=>{const[i,a]=t;return e[i.replace(s,"$2")]=a,e},{}),c=e=>e.includes("."),h="ref",_="value",u="toJSON",p=e=>`${h}.${e}`;function l(e,s,d){const l=()=>Object.entries(e.hass.areas),v=()=>Object.entries(e.hass.devices),b=()=>Object.entries(e.hass.entities),f=new Set,g=new Map,m=(e,t)=>{d&&console.warn(`${e} ${t} used in a JavaScript template doesn't exist`)},w=e=>m("Entity",e),E=e=>m("Domain",e),y=e=>{const t=new SyntaxError(e);if(s)throw t;d&&console.warn(t)},A=t=>{e.hass.states[t]?f.add(t):w(t)},N=e=>{f.add(e)},T=(t,s)=>{const{with_unit:i=!1,rounded:a=!1}=s;if(t){const s=t.state,n=t.attributes.unit_of_measurement,r=Number(a),d=!1===a||isNaN(Number(s))?s:new Intl.NumberFormat(e.hass.language,{minimumFractionDigits:r,maximumFractionDigits:r}).format(Number(s));return i&&n?`${d} ${n}`:d}},S=e=>new Proxy(e,{get:(e,t)=>"state_with_unit"===t?T(e,{rounded:!0,with_unit:!0}):e[t]});return{get hass(){return e.hass},states:new Proxy((s,i={})=>{if(c(s))return A(s),T(e.hass.states[s],i);throw SyntaxError(`${t}: states method cannot be used with a domain, use it as an object instead.`)},{get(t,s){if(c(s))return A(s),S(e.hass.states[s]);const i=Object.entries(e.hass.states).filter(([e])=>e.startsWith(s));return i.length||E(s),new Proxy(o(i),{get:(e,t)=>(A(`${s}.${t}`),S(e[t]))})}}),state_translated(t){if(A(t),e.hass.states[t])return e.hass.formatEntityState(e.hass.states[t])},is_state(t,s){var i;return A(t),Array.isArray(s)?s.some(s=>{var i;return(null===(i=e.hass.states[t])||void 0===i?void 0:i.state)===s}):(null===(i=e.hass.states[t])||void 0===i?void 0:i.state)===s},state_attr(t,s){var i,a;return A(t),null===(a=null===(i=e.hass.states[t])||void 0===i?void 0:i.attributes)||void 0===a?void 0:a[s]},is_state_attr(e,t,s){return this.state_attr(e,t)===s},has_value(e){return this.states(e)?!(this.is_state(e,i.UNKNOWN)||this.is_state(e,i.UNAVAILABLE)):(w(e),!1)},entities:new Proxy(t=>{if(void 0===t)return e.hass.entities;if(c(t))return A(t),e.hass.entities[t];const s=b().filter(([e])=>e.startsWith(t));return s.length||E(t),new Proxy(o(s),{get:(e,s)=>(A(`${t}.${s}`),e[s])})},{get:(e,t)=>e(t)}),entity_prop(t,s){var i;return A(t),null===(i=e.hass.entities[t])||void 0===i?void 0:i[s]},is_entity_prop(e,t,s){return this.entity_prop(e,t)===s},devices:new Proxy(s=>{if(void 0===s)return e.hass.devices;if(c(s))throw SyntaxError(`${t}: devices method cannot be used with an entity id, you should use a device id instead.`);return e.hass.devices[s]},{get(s,i){if(c(i))throw SyntaxError(`${t}: devices cannot be accesed using an entity id, you should use a device id instead.`);return e.hass.devices[i]}}),device_attr(t,s){var i,a,n;if(c(t)){A(t);const n=null===(i=e.hass.entities[t])||void 0===i?void 0:i.device_id;return null===(a=e.hass.devices[n])||void 0===a?void 0:a[s]}return null===(n=e.hass.devices[t])||void 0===n?void 0:n[s]},is_device_attr(e,t,s){return this.device_attr(e,t)===s},device_id(t){var s;if(c(t))return A(t),null===(s=e.hass.entities[t])||void 0===s?void 0:s.device_id;const i=v().find(e=>e[1].name===t);return null==i?void 0:i[0]},device_name(t){var s,i,a,n,r;if(c(t)){A(t);const n=null===(s=e.hass.entities[t])||void 0===s?void 0:s.device_id;return null!==(a=null===(i=e.hass.devices[n])||void 0===i?void 0:i.name)&&void 0!==a?a:void 0}return null!==(r=null===(n=e.hass.devices[t])||void 0===n?void 0:n.name)&&void 0!==r?r:void 0},areas:()=>l().map(([,e])=>e.area_id),area_id(t){var s,i;if(t in e.hass.devices)return this.device_attr(t,a.AREA_ID);const n=null===(s=e.hass.entities[t])||void 0===s?void 0:s.device_id;if(n)return this.device_attr(n,a.AREA_ID);const r=l().find(([,e])=>e.name===t);return null===(i=null==r?void 0:r[1])||void 0===i?void 0:i.area_id},area_name(t){var s,i;let n;t in e.hass.devices&&(n=this.device_attr(t,a.AREA_ID));const r=null===(s=e.hass.entities[t])||void 0===s?void 0:s.device_id;r&&(n=this.device_attr(r,a.AREA_ID));const d=l().find(([,e])=>e.area_id===t||e.area_id===n);return null===(i=null==d?void 0:d[1])||void 0===i?void 0:i.name},area_entities(e){const t=l().find(([,t])=>t.area_id===e||t.name===e);return t?b().filter(([,e])=>e.area_id===t[1].area_id).map(([e])=>e):[]},area_devices(e){const t=l().find(([,t])=>t.area_id===e||t.name===e);return t?v().filter(([,e])=>e.area_id===t[1].area_id).map(([,e])=>e.id):[]},get user_name(){return e.hass.user.name},get user_is_admin(){return e.hass.user.is_admin},get user_is_owner(){return e.hass.user.is_owner},get user_agent(){return window.navigator.userAgent},get tracked(){return f},cleanTracked(){f.clear()},ref(e,t,s=void 0){const i=p(t);if(g.has(t))return g.get(t);const a=new Proxy({[_]:s,[u](){return this[_]}},{get(e,t,s){if(t===_||t===u)return N(i),Reflect.get(e,t,s);y(`${t} is not a valid ${h} property. A ${h} only exposes a "${_}" property`)},set(t,s,a){if(s===_){const s=t[_];return t[_]=a,e({event_type:r.STATE_CHANGE_EVENT,data:{entity_id:i,old_state:{state:JSON.stringify(s)},new_state:{state:JSON.stringify(a)}}}),!0}return y(`property "${s}" cannot be set in a ${h}`),!1}});return g.set(t,a),a},unref(e,t){const s=p(t);g.has(t)?(g.delete(t),e(s)):y(`${t} is not a ref or it has been unrefed already`)},refs(e,t,s={}){const i=this.ref,a=this.unref,n=new Proxy(s,{get:(t,s)=>i(e,s).value,set:(t,s,a)=>(i(e,s).value=a,!0)});return Object.entries(s).forEach(s=>{const[n,r]=s;g.has(n)&&a(t,n),i(e,n,r)}),n},cleanRefs(e){Array.from(g.keys()).forEach(t=>{this.unref(e,t)})},clientSideProxy:new Proxy({},{get(t,s){switch(Object.values(n).includes(s)&&N(s),s){case n.PANEL_URL:return window.location.pathname;case n.LANG:return e.hass.language}d&&console.warn(`clientSideProxy should only be used to access these variables: ${Object.values(n).join(", ")}`)}})}}class v{constructor(e,t){const{throwErrors:s=!1,throwWarnings:i=!0,variables:a={},refs:r={},refsVariableName:o=d,autoReturn:c=!0}=t;this._throwErrors=s,this._throwWarnings=i,this._variables=a,this._refsVariableName=o,this._autoReturn=c,this._subscriptions=new Map,this._clientSideEntitiesRegExp=new RegExp(`(^|[ \\?(+:\\{\\[><,])(${Object.values(n).join("|")})($|[ \\?)+:\\}\\]><.,])`,"gm"),this._scopped=l(e,s,i),this.refs=r,this._watchForPanelUrlChange(),this._watchForEntitiesChange(),this._watchForLanguageChange()}_executeRenderingFunctions(e){this._subscriptions.get(e).forEach((e,t)=>{e.forEach((e,s)=>{this.trackTemplate(t,s,e)})})}_watchForPanelUrlChange(){window.addEventListener(r.LOCATION_CHANGED,()=>{this._panelUrlWatchCallback()}),window.addEventListener(r.POPSTATE,()=>{this._panelUrlWatchCallback()})}_panelUrlWatchCallback(){this._subscriptions.has(n.PANEL_URL)&&this._executeRenderingFunctions(n.PANEL_URL)}_watchForEntitiesChange(){window.hassConnection.then(e=>{e.conn.subscribeMessage(e=>this._entityWatchCallback(e),{type:r.SUBSCRIBE_EVENTS,event_type:r.STATE_CHANGE_EVENT})})}_watchForLanguageChange(){window.addEventListener(r.TRANSLATIONS_UPDATED,()=>{this._subscriptions.has(n.LANG)&&this._executeRenderingFunctions(n.LANG)})}_entityWatchCallback(e){if(this._subscriptions.size){const t=e.data.entity_id;this._subscriptions.has(t)&&this._executeRenderingFunctions(t)}}_storeTracked(e,t,s){this._scopped.tracked.forEach(i=>{const a=[t,s];if(this._subscriptions.has(i)){const s=this._subscriptions.get(i);if(s.has(e)){const i=s.get(e);i.has(t)||i.set(...a)}else s.set(e,new Map([a]))}else this._subscriptions.set(i,new Map([[e,new Map([a])]]))})}_untrackTemplate(e,t){this._subscriptions.forEach((s,i)=>{if(s.has(e)){const a=s.get(e);a.delete(t),0===a.size&&(s.delete(e),0===s.size&&this._subscriptions.delete(i))}})}renderTemplate(e,t={}){try{const{variables:s={},refs:i={}}=t,a=new Map(Object.entries(Object.assign(Object.assign({},this._variables),s))),n=e.trim().replace(this._clientSideEntitiesRegExp,"$1clientSide.$2$3"),r=n.includes("return")||!this._autoReturn?n:`return ${n}`;return new Function("hass","states","state_translated","is_state","state_attr","is_state_attr","has_value","entities","entity_prop","is_entity_prop","devices","device_attr","is_device_attr","device_id","device_name","areas","area_id","area_name","area_entities","area_devices","user_name","user_is_admin","user_is_owner","user_agent","clientSide","ref","unref",this._refsVariableName,...Array.from(a.keys()),`"use strict"; ${r}`)(this._scopped.hass,this._scopped.states,this._scopped.state_translated.bind(this._scopped),this._scopped.is_state.bind(this._scopped),this._scopped.state_attr.bind(this._scopped),this._scopped.is_state_attr.bind(this._scopped),this._scopped.has_value.bind(this._scopped),this._scopped.entities,this._scopped.entity_prop,this._scopped.is_entity_prop.bind(this._scopped),this._scopped.devices,this._scopped.device_attr.bind(this._scopped),this._scopped.is_device_attr.bind(this._scopped),this._scopped.device_id.bind(this._scopped),this._scopped.device_name.bind(this._scopped),this._scopped.areas.bind(this._scopped),this._scopped.area_id.bind(this._scopped),this._scopped.area_name.bind(this._scopped),this._scopped.area_entities.bind(this._scopped),this._scopped.area_devices.bind(this._scopped),this._scopped.user_name,this._scopped.user_is_admin,this._scopped.user_is_owner,this._scopped.user_agent,this._scopped.clientSideProxy,this._scopped.ref.bind(this._scopped,this._entityWatchCallback.bind(this)),this._scopped.unref.bind(this._scopped,this.cleanTracked.bind(this)),this._scopped.refs(this._entityWatchCallback.bind(this),this.cleanTracked.bind(this),i),...Array.from(a.values()))}catch(e){if(this._throwErrors)throw e;return void(this._throwWarnings&&console.warn(e))}}trackTemplate(e,t,s={}){this._scopped.cleanTracked();const i=this.renderTemplate(e,s);return this._storeTracked(e,t,s),t(i),()=>this._untrackTemplate(e,t)}cleanTracked(e){e?this._subscriptions.has(e)&&this._subscriptions.delete(e):this._subscriptions.clear()}get variables(){return this._variables}set variables(e){this._variables=e}get refs(){return this._scopped.refs(this._entityWatchCallback.bind(this),this.cleanTracked.bind(this))}set refs(e){this._scopped.cleanRefs(this.cleanTracked.bind(this)),this._scopped.refs(this._entityWatchCallback.bind(this),this.cleanTracked.bind(this),e)}}module.exports=class{constructor(t,s={}){this._renderer=e.getPromisableResult(()=>t.hass,e=>!!(e&&e.areas&&e.devices&&e.entities&&e.states&&e.user),{retries:100,delay:50,rejectMessage:"The provided element doesn't contain a proper or initialised hass object"}).then(()=>new v(t,s))}getRenderer(){return this._renderer}};
|
|
1
|
+
"use strict";var e=require("get-promisable-result");const t="[home-assistant-javascript-templates]",s=/^([a-z_]+)\.(\w+)$/;var i,a,r,n;!function(e){e.UNKNOWN="unknown",e.UNAVAILABLE="unavailable"}(i||(i={})),function(e){e.AREA_ID="area_id",e.NAME="name"}(a||(a={})),function(e){e.PANEL_URL="panel_url",e.LANG="lang"}(r||(r={})),function(e){e.LOCATION_CHANGED="location-changed",e.TRANSLATIONS_UPDATED="translations-updated",e.POPSTATE="popstate",e.SUBSCRIBE_EVENTS="subscribe_events",e.STATE_CHANGE_EVENT="state_changed"}(n||(n={}));const d="refs",o=e=>e.reduce((e,t)=>{const[i,a]=t;return e[i.replace(s,"$2")]=a,e},{}),c=e=>e.includes("."),h="ref",_="value",u="toJSON",p=e=>`${h}.${e}`;function l(e,s,d){const l=()=>Object.entries(e.hass.areas),v=()=>Object.entries(e.hass.devices),b=()=>Object.entries(e.hass.entities),f=new Set,g=new Map,m=(e,t)=>{d&&console.warn(`${e} ${t} used in a JavaScript template doesn't exist`)},w=e=>m("Entity",e),E=e=>m("Domain",e),y=e=>{const t=new SyntaxError(e);if(s)throw t;d&&console.warn(t)},A=t=>{e.hass.states[t]?f.add(t):w(t)},N=e=>{f.add(e)},T=(t,s)=>{const{with_unit:i=!1,rounded:a=!1}=s;if(t){const s=t.state,r=t.attributes.unit_of_measurement,n=Number(a),d=!1===a||isNaN(Number(s))?s:new Intl.NumberFormat(e.hass.language,{minimumFractionDigits:n,maximumFractionDigits:n}).format(Number(s));return i&&r?`${d} ${r}`:d}},S=e=>new Proxy(e,{get:(e,t)=>"state_with_unit"===t?T(e,{rounded:!0,with_unit:!0}):e[t]});return{get hass(){return e.hass},states:new Proxy((s,i={})=>{if(c(s))return A(s),T(e.hass.states[s],i);throw SyntaxError(`${t}: states method cannot be used with a domain, use it as an object instead.`)},{get(t,s){if(c(s))return A(s),S(e.hass.states[s]);const i=Object.entries(e.hass.states).filter(([e])=>e.startsWith(s));return i.length||E(s),new Proxy(o(i),{get:(e,t)=>(A(`${s}.${t}`),S(e[t]))})}}),state_translated(t){if(A(t),e.hass.states[t])return e.hass.formatEntityState(e.hass.states[t])},is_state(t,s){var i;return A(t),Array.isArray(s)?s.some(s=>{var i;return(null===(i=e.hass.states[t])||void 0===i?void 0:i.state)===s}):(null===(i=e.hass.states[t])||void 0===i?void 0:i.state)===s},state_attr(t,s){var i,a;return A(t),null===(a=null===(i=e.hass.states[t])||void 0===i?void 0:i.attributes)||void 0===a?void 0:a[s]},state_attr_translated(t,s){if(A(t),e.hass.states[t])return e.hass.formatEntityAttributeValue(e.hass.states[t],s)},is_state_attr(e,t,s){return this.state_attr(e,t)===s},has_value(e){return this.states(e)?!(this.is_state(e,i.UNKNOWN)||this.is_state(e,i.UNAVAILABLE)):(w(e),!1)},entities:new Proxy(t=>{if(void 0===t)return e.hass.entities;if(c(t))return A(t),e.hass.entities[t];const s=b().filter(([e])=>e.startsWith(t));return s.length||E(t),new Proxy(o(s),{get:(e,s)=>(A(`${t}.${s}`),e[s])})},{get:(e,t)=>e(t)}),entity_prop(t,s){var i;return A(t),null===(i=e.hass.entities[t])||void 0===i?void 0:i[s]},is_entity_prop(e,t,s){return this.entity_prop(e,t)===s},devices:new Proxy(s=>{if(void 0===s)return e.hass.devices;if(c(s))throw SyntaxError(`${t}: devices method cannot be used with an entity id, you should use a device id instead.`);return e.hass.devices[s]},{get(s,i){if(c(i))throw SyntaxError(`${t}: devices cannot be accesed using an entity id, you should use a device id instead.`);return e.hass.devices[i]}}),device_attr(t,s){var i,a,r;if(c(t)){A(t);const r=null===(i=e.hass.entities[t])||void 0===i?void 0:i.device_id;return null===(a=e.hass.devices[r])||void 0===a?void 0:a[s]}return null===(r=e.hass.devices[t])||void 0===r?void 0:r[s]},is_device_attr(e,t,s){return this.device_attr(e,t)===s},device_id(t){var s;if(c(t))return A(t),null===(s=e.hass.entities[t])||void 0===s?void 0:s.device_id;const i=v().find(e=>e[1].name===t);return null==i?void 0:i[0]},device_name(t){var s,i,a,r,n;if(c(t)){A(t);const r=null===(s=e.hass.entities[t])||void 0===s?void 0:s.device_id;return null!==(a=null===(i=e.hass.devices[r])||void 0===i?void 0:i.name)&&void 0!==a?a:void 0}return null!==(n=null===(r=e.hass.devices[t])||void 0===r?void 0:r.name)&&void 0!==n?n:void 0},areas:()=>l().map(([,e])=>e.area_id),area_id(t){var s,i;if(t in e.hass.devices)return this.device_attr(t,a.AREA_ID);const r=null===(s=e.hass.entities[t])||void 0===s?void 0:s.device_id;if(r)return this.device_attr(r,a.AREA_ID);const n=l().find(([,e])=>e.name===t);return null===(i=null==n?void 0:n[1])||void 0===i?void 0:i.area_id},area_name(t){var s,i;let r;t in e.hass.devices&&(r=this.device_attr(t,a.AREA_ID));const n=null===(s=e.hass.entities[t])||void 0===s?void 0:s.device_id;n&&(r=this.device_attr(n,a.AREA_ID));const d=l().find(([,e])=>e.area_id===t||e.area_id===r);return null===(i=null==d?void 0:d[1])||void 0===i?void 0:i.name},area_entities(e){const t=l().find(([,t])=>t.area_id===e||t.name===e);return t?b().filter(([,e])=>e.area_id===t[1].area_id).map(([e])=>e):[]},area_devices(e){const t=l().find(([,t])=>t.area_id===e||t.name===e);return t?v().filter(([,e])=>e.area_id===t[1].area_id).map(([,e])=>e.id):[]},get user_name(){return e.hass.user.name},get user_is_admin(){return e.hass.user.is_admin},get user_is_owner(){return e.hass.user.is_owner},get user_agent(){return window.navigator.userAgent},get tracked(){return f},cleanTracked(){f.clear()},ref(e,t,s=void 0){const i=p(t);if(g.has(t))return g.get(t);const a=new Proxy({[_]:s,[u](){return this[_]}},{get(e,t,s){if(t===_||t===u)return N(i),Reflect.get(e,t,s);y(`${t} is not a valid ${h} property. A ${h} only exposes a "${_}" property`)},set(t,s,a){if(s===_){const s=t[_];return t[_]=a,e({event_type:n.STATE_CHANGE_EVENT,data:{entity_id:i,old_state:{state:JSON.stringify(s)},new_state:{state:JSON.stringify(a)}}}),!0}return y(`property "${s}" cannot be set in a ${h}`),!1}});return g.set(t,a),a},unref(e,t){const s=p(t);g.has(t)?(g.delete(t),e(s)):y(`${t} is not a ref or it has been unrefed already`)},refs(e,t,s={}){const i=this.ref,a=this.unref,r=new Proxy(s,{get:(t,s)=>i(e,s).value,set:(t,s,a)=>(i(e,s).value=a,!0)});return Object.entries(s).forEach(s=>{const[r,n]=s;g.has(r)&&a(t,r),i(e,r,n)}),r},cleanRefs(e){Array.from(g.keys()).forEach(t=>{this.unref(e,t)})},clientSideProxy:new Proxy({},{get(t,s){switch(Object.values(r).includes(s)&&N(s),s){case r.PANEL_URL:return window.location.pathname;case r.LANG:return e.hass.language}d&&console.warn(`clientSideProxy should only be used to access these variables: ${Object.values(r).join(", ")}`)}})}}class v{constructor(e,t){const{throwErrors:s=!1,throwWarnings:i=!0,variables:a={},refs:n={},refsVariableName:o=d,autoReturn:c=!0}=t;this._throwErrors=s,this._throwWarnings=i,this._variables=a,this._refsVariableName=o,this._autoReturn=c,this._subscriptions=new Map,this._clientSideEntitiesRegExp=new RegExp(`(^|[ \\?(+:\\{\\[><,])(${Object.values(r).join("|")})($|[ \\?)+:\\}\\]><.,])`,"gm"),this._scopped=l(e,s,i),this.refs=n,this._watchForPanelUrlChange(),this._watchForEntitiesChange(),this._watchForLanguageChange()}_executeRenderingFunctions(e){this._subscriptions.get(e).forEach((e,t)=>{e.forEach((e,s)=>{this.trackTemplate(t,s,e)})})}_watchForPanelUrlChange(){window.addEventListener(n.LOCATION_CHANGED,()=>{this._panelUrlWatchCallback()}),window.addEventListener(n.POPSTATE,()=>{this._panelUrlWatchCallback()})}_panelUrlWatchCallback(){this._subscriptions.has(r.PANEL_URL)&&this._executeRenderingFunctions(r.PANEL_URL)}_watchForEntitiesChange(){window.hassConnection.then(e=>{e.conn.subscribeMessage(e=>this._entityWatchCallback(e),{type:n.SUBSCRIBE_EVENTS,event_type:n.STATE_CHANGE_EVENT})})}_watchForLanguageChange(){window.addEventListener(n.TRANSLATIONS_UPDATED,()=>{this._subscriptions.has(r.LANG)&&this._executeRenderingFunctions(r.LANG)})}_entityWatchCallback(e){if(this._subscriptions.size){const t=e.data.entity_id;this._subscriptions.has(t)&&this._executeRenderingFunctions(t)}}_storeTracked(e,t,s){this._scopped.tracked.forEach(i=>{const a=[t,s];if(this._subscriptions.has(i)){const s=this._subscriptions.get(i);if(s.has(e)){const i=s.get(e);i.has(t)||i.set(...a)}else s.set(e,new Map([a]))}else this._subscriptions.set(i,new Map([[e,new Map([a])]]))})}_untrackTemplate(e,t){this._subscriptions.forEach((s,i)=>{if(s.has(e)){const a=s.get(e);a.delete(t),0===a.size&&(s.delete(e),0===s.size&&this._subscriptions.delete(i))}})}renderTemplate(e,t={}){try{const{variables:s={},refs:i={}}=t,a=new Map(Object.entries(Object.assign(Object.assign({},this._variables),s))),r=e.trim().replace(this._clientSideEntitiesRegExp,"$1clientSide.$2$3"),n=r.includes("return")||!this._autoReturn?r:`return ${r}`;return new Function("hass","states","state_translated","is_state","state_attr","state_attr_translated","is_state_attr","has_value","entities","entity_prop","is_entity_prop","devices","device_attr","is_device_attr","device_id","device_name","areas","area_id","area_name","area_entities","area_devices","user_name","user_is_admin","user_is_owner","user_agent","clientSide","ref","unref",this._refsVariableName,...Array.from(a.keys()),`"use strict"; ${n}`)(this._scopped.hass,this._scopped.states,this._scopped.state_translated.bind(this._scopped),this._scopped.is_state.bind(this._scopped),this._scopped.state_attr.bind(this._scopped),this._scopped.state_attr_translated.bind(this._scopped),this._scopped.is_state_attr.bind(this._scopped),this._scopped.has_value.bind(this._scopped),this._scopped.entities,this._scopped.entity_prop,this._scopped.is_entity_prop.bind(this._scopped),this._scopped.devices,this._scopped.device_attr.bind(this._scopped),this._scopped.is_device_attr.bind(this._scopped),this._scopped.device_id.bind(this._scopped),this._scopped.device_name.bind(this._scopped),this._scopped.areas.bind(this._scopped),this._scopped.area_id.bind(this._scopped),this._scopped.area_name.bind(this._scopped),this._scopped.area_entities.bind(this._scopped),this._scopped.area_devices.bind(this._scopped),this._scopped.user_name,this._scopped.user_is_admin,this._scopped.user_is_owner,this._scopped.user_agent,this._scopped.clientSideProxy,this._scopped.ref.bind(this._scopped,this._entityWatchCallback.bind(this)),this._scopped.unref.bind(this._scopped,this.cleanTracked.bind(this)),this._scopped.refs(this._entityWatchCallback.bind(this),this.cleanTracked.bind(this),i),...Array.from(a.values()))}catch(e){if(this._throwErrors)throw e;return void(this._throwWarnings&&console.warn(e))}}trackTemplate(e,t,s={}){this._scopped.cleanTracked();const i=this.renderTemplate(e,s);return this._storeTracked(e,t,s),t(i),()=>this._untrackTemplate(e,t)}cleanTracked(e){e?this._subscriptions.has(e)&&this._subscriptions.delete(e):this._subscriptions.clear()}get variables(){return this._variables}set variables(e){this._variables=e}get refs(){return this._scopped.refs(this._entityWatchCallback.bind(this),this.cleanTracked.bind(this))}set refs(e){this._scopped.cleanRefs(this.cleanTracked.bind(this)),this._scopped.refs(this._entityWatchCallback.bind(this),this.cleanTracked.bind(this),e)}}module.exports=class{constructor(t,s={}){this._renderer=e.getPromisableResult(()=>t.hass,e=>!!(e&&e.areas&&e.devices&&e.entities&&e.states&&e.user),{retries:100,delay:50,rejectMessage:"The provided element doesn't contain a proper or initialised hass object"}).then(()=>new v(t,s))}getRenderer(){return this._renderer}};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "home-assistant-javascript-templates",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.1.0",
|
|
4
4
|
"description": "A JavaScript utility to render Home Assistant JavaScript templates",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"home-assistant",
|
|
@@ -48,27 +48,22 @@
|
|
|
48
48
|
"@rollup/plugin-terser": "^1.0.0",
|
|
49
49
|
"@rollup/plugin-typescript": "^12.3.0",
|
|
50
50
|
"@types/jest": "^30.0.0",
|
|
51
|
-
"@types/node": "^25.
|
|
51
|
+
"@types/node": "^25.6.2",
|
|
52
52
|
"get-promisable-result": "^1.0.2",
|
|
53
|
-
"jest": "^30.
|
|
54
|
-
"jest-environment-jsdom": "^30.
|
|
53
|
+
"jest": "^30.4.2",
|
|
54
|
+
"jest-environment-jsdom": "^30.4.1",
|
|
55
55
|
"jest-location-mock": "^3.0.0",
|
|
56
|
-
"rollup": "^4.60.
|
|
56
|
+
"rollup": "^4.60.3",
|
|
57
57
|
"rollup-plugin-dts": "^6.4.1",
|
|
58
58
|
"rollup-plugin-tsconfig-paths": "^1.5.2",
|
|
59
|
-
"ts-jest": "^29.4.
|
|
59
|
+
"ts-jest": "^29.4.9",
|
|
60
60
|
"tslib": "^2.8.1",
|
|
61
|
-
"typescript": "^6.0.
|
|
61
|
+
"typescript": "^6.0.3"
|
|
62
62
|
},
|
|
63
63
|
"dependencies": {
|
|
64
|
-
"get-promisable-result": "^
|
|
64
|
+
"get-promisable-result": "^2.0.0"
|
|
65
65
|
},
|
|
66
66
|
"peerDependencies": {
|
|
67
|
-
"get-promisable-result": "^
|
|
68
|
-
},
|
|
69
|
-
"pnpm": {
|
|
70
|
-
"overrides": {
|
|
71
|
-
"@isaacs/brace-expansion@<=5.0.0": ">=5.0.1"
|
|
72
|
-
}
|
|
67
|
+
"get-promisable-result": "^2.0.0"
|
|
73
68
|
}
|
|
74
69
|
}
|