@deconz-community/ddf-validator 2.15.0 → 2.16.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.
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("zod"),D="2.15.0",g={"devcap1.schema.json":[O,E,_,$,T],"constants2.schema.json":[w]};function O(t,a,d){const o=typeof t.manufacturername=="string"&&typeof t.modelid=="string";if(o)return;const c=Array.isArray(t.manufacturername)&&Array.isArray(t.modelid);if(c&&t.manufacturername.length!==t.modelid.length){a.addIssue({code:e.z.ZodIssueCode.invalid_intersection_types,message:"When 'manufacturername' and 'modelid' are both arrays they should be the same length",path:["manufacturername","modelid"]});return}(o||c)===!1&&a.addIssue({code:e.z.ZodIssueCode.invalid_intersection_types,message:"Invalid properties 'manufacturername' and 'modelid' should have the same type",path:["manufacturername","modelid"]})}function E(t,a,d){if(!t.bindings)return;const o=s=>`0x${(typeof s=="number"?s:Number.parseInt(s,16)).toString(16)}`,c={};t.bindings.forEach(s=>{s.bind==="unicast"&&s.report&&s.report.forEach(n=>{n.max!==65535&&(c[`${o(s["src.ep"])}.${o(s.cl)}.${o(n.at)}`]=n.max)})}),t.subdevices.forEach((s,n)=>{s.items.forEach((i,u)=>{var m;if(i["refresh.interval"]&&i.read&&i.read.fn==="zcl"){const z=o(i.read.ep??((m=s.fingerprint)==null?void 0:m.endpoint)??s.uuid[1]),b=Array.isArray(i.read.at)?i.read.at:[i.read.at];for(let h=0;h<b.length;h++){const v=`${z}.${o(i.read.cl)}.${o(b[h])}`;c[v]!==void 0&&i["refresh.interval"]-60<c[v]&&a.addIssue({code:e.z.ZodIssueCode.custom,message:`The refresh interval (${i["refresh.interval"]} - 60 = ${i["refresh.interval"]-60}) should be greater than the binding max refresh value (${c[v]}) with a margin of 60 seconds`,path:["subdevices",n,"items",u,"refresh.interval"]})}}})})}function _(t,a,d){const o=[{description:'a device with "state/ct" need the "min" and "max" values for capability.',if:{item:"state/ct"},need:{item:["cap/color/ct/min","cap/color/ct/max"]}},{description:'a device with "cap/color/ct/computes_xy" need the corresponding state/{x,y} items',if:{item:"cap/color/ct/computes_xy"},need:{item:["state/x","state/y","state/ct"]}},{description:'a device with "state/x" or "state/y" need the corresponding cap/color/xy/{red,green,blue}/{x,y} items',if:{item:{or:["state/x","state/y"]}},need:{item:["state/x","state/y","cap/color/xy/red_x","cap/color/xy/green_x","cap/color/xy/blue_x","cap/color/xy/red_y","cap/color/xy/green_y","cap/color/xy/blue_y"]}},{description:'a "(Extended) Color light" need ("state/x" and "state/y") or/and ("state/hue" and "state/sat") .',if:{type:{or:["$TYPE_EXTENDED_COLOR_LIGHT","Extended color light","$TYPE_COLOR_LIGHT","Color light"]}},need:{item:{or:[["state/x","state/y"],["state/hue","state/sat"]]}}}],c=(s,n)=>typeof s=="string"?n(s):Array.isArray(s)?s.every(i=>c(i,n)):"and"in s?s.and.every(i=>c(i,n)):"or"in s?s.or.some(i=>c(i,n)):!1;t.subdevices.forEach((s,n)=>{const i=s.items.map(u=>u.name);o.forEach(u=>{(Object.keys(u.if).length===0||Object.entries(u.if).some(([m,z])=>{switch(m){case"type":return c(z,b=>b===s.type);case"item":return c(z,b=>i.includes(b));default:return!1}}))&&(c(u.need.item,m=>i.includes(m))||a.addIssue({code:e.z.ZodIssueCode.custom,message:`The device is missing some items because ${u.description}`,path:["subdevices",n,"items"]}))})})}function $(t,a,d){const o=["parse","write"];t.subdevices.forEach((c,s)=>{c.items.forEach((n,i)=>{o.forEach(u=>{const m=n[u];m!==void 0&&(m.fn===void 0||m.fn==="zcl"||m.fn==="zcl:attr"||m.fn==="zcl:cmd")&&(m.eval===void 0&&m.script===void 0&&a.addIssue({code:e.z.ZodIssueCode.custom,message:`The '${u}' function is missing 'eval' or 'script' option.`,path:["subdevices",s,"items",i,u]}),m.eval!==void 0&&m.script!==void 0&&a.addIssue({code:e.z.ZodIssueCode.custom,message:`The '${u}' function is having both 'eval' and 'script' option.`,path:["subdevices",s,"items",i,u]}))})})})}function w(t,a,d){const o=x();Object.keys(t).forEach(c=>{if(!Object.keys(o.shape).includes(c)){if(!["$MF_","$TYPE_"].some(s=>c.startsWith(s))){a.addIssue({code:e.z.ZodIssueCode.custom,message:"The constant key should start with '$MF_' or '$TYPE_'",path:[c]});return}typeof t[c]!="string"&&a.addIssue({code:e.z.ZodIssueCode.custom,message:"The constant value should be a string",path:[c]})}})}function T(t,a,d){t.subdevices.forEach((o,c)=>{const s=d.subDevices[o.type];if(!s){a.addIssue({code:e.z.ZodIssueCode.custom,message:`The device is missing the device definition for the type "${o.type}"`,path:["subdevices",c,"items"]});return}let n=s.items;s.items_optional&&(n=n.filter(i=>!s.items_optional.includes(i))),n.forEach(i=>{o.items.find(u=>u.name===i)||a.addIssue({code:e.z.ZodIssueCode.custom,message:`The device should have the item "${i}" because it is mandatory for devices of type "${o.type}"`,path:["subdevices",c,"items"]})})})}function C(t){return e.z.strictObject({$schema:e.z.optional(e.z.string()),schema:e.z.literal("constants1.schema.json"),manufacturers:e.z.record(e.z.string().startsWith("$MF_"),e.z.string()),"device-types":e.z.record(e.z.string().startsWith("$TYPE_"),e.z.string())})}function x(t){return e.z.object({$schema:e.z.optional(e.z.string()),schema:e.z.literal("constants2.schema.json")}).passthrough()}function A(){return e.z.string().regex(/^(\d{4})-(?:(?:0[1-9])|(?:1[0-2]))-(?:(?:0[1-9])|(?:[12][0-9])|(?:3[01]))$/,"Invalid date value")}function r(t=void 0){const a="Invalid hexadecimal value";return t===void 0?e.z.string().regex(/^0x[0-9a-fA-F]+$/,a):e.z.string().regex(new RegExp(`^0x[0-9a-fA-F]{${t}}$`),a)}function l(){return e.z.union([r(2),e.z.number().min(0).max(255)])}function M(){return e.z.custom(t=>{if(!Array.isArray(t)||t.length%2!==0)return!1;for(let a=0;a<t.length;a+=2){const d=t[a],o=t[a+1];if(typeof d!="number"||typeof o!="string")return!1}return!0},"The value must be an array with an even number of values and alternating between number and string.")}function I(){return e.z.union([e.z.tuple([e.z.literal("$address.ext"),r(2)]),e.z.tuple([e.z.literal("$address.ext"),r(2),r(4)])])}function f(){return e.z.string()}function p(){return e.z.string()}function S(){return e.z.discriminatedUnion("fn",[e.z.strictObject({fn:e.z.literal("none")}),e.z.strictObject({fn:e.z.undefined().describe("Generic function to read ZCL attributes."),at:r(4).or(e.z.array(r(4))).describe("Attribute ID."),cl:r(4).describe("Cluster ID."),ep:e.z.optional(l()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),mf:e.z.optional(r(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),eval:e.z.optional(p()).describe("Javascript expression to transform the raw value.")}),e.z.strictObject({fn:e.z.literal("zcl").describe("Generic function to read ZCL attributes."),at:r(4).or(e.z.array(r(4))).describe("Attribute ID."),cl:r(4).describe("Cluster ID."),ep:e.z.optional(l()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),mf:e.z.optional(r(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),eval:e.z.optional(p()).describe("Javascript expression to transform the raw value."),script:e.z.optional(f()).describe("Relative path of a Javascript .js file.")}).describe("Deprecated"),e.z.strictObject({fn:e.z.literal("zcl:attr").describe("Generic function to parse ZCL values from read/report commands."),at:r(4).or(e.z.array(r(4))).describe("String hex value or array of string hex values."),cl:r(4).describe("Cluster ID."),ep:e.z.optional(l()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),mf:e.z.optional(r(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),eval:e.z.optional(p()).describe("Javascript expression to transform the attribute value to the Item value."),script:e.z.optional(f()).describe("Relative path of a Javascript .js file.")}),e.z.strictObject({fn:e.z.literal("zcl:cmd").describe("Generic function to parse ZCL values from read/report commands."),cl:r(4).describe("Cluster ID."),ep:e.z.optional(l()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),mf:e.z.optional(r(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),cmd:e.z.optional(r(2)).describe("Zigbee command."),eval:e.z.optional(p()).describe("Javascript expression to transform the attribute value to the Item value."),fc:e.z.optional(r(2).or(e.z.number())).describe("Zigbee command frame control."),script:e.z.optional(f()).describe("Relative path of a Javascript .js file.")}),e.z.strictObject({fn:e.z.literal("tuya").describe("Generic function to read all Tuya datapoints. It has no parameters.")})]).refine(t=>!("eval"in t&&"script"in t),{message:"eval and script should not both be present"})}function J(){return e.z.discriminatedUnion("fn",[e.z.strictObject({fn:e.z.undefined().describe("Generic function to parse ZCL attributes and commands."),at:e.z.optional(r(4).or(e.z.array(r(4)))).describe("Attribute ID."),cl:r(4).describe("Cluster ID."),cppsrc:e.z.optional(e.z.string()),ep:e.z.optional(l()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),cmd:e.z.optional(r(2)).describe("Zigbee command."),mf:e.z.optional(r(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),eval:e.z.optional(p()).describe("Javascript expression to transform the raw value."),script:e.z.optional(f()).describe("Relative path of a Javascript .js file.")}),e.z.strictObject({fn:e.z.literal("zcl").describe("Generic function to parse ZCL attributes and commands."),at:e.z.optional(r(4).or(e.z.array(r(4)))).describe("Attribute ID."),cl:r(4).describe("Cluster ID."),cppsrc:e.z.optional(e.z.string()),ep:e.z.optional(l()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),cmd:e.z.optional(r(2)).describe("Zigbee command."),mf:e.z.optional(r(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),eval:e.z.optional(p()).describe("Javascript expression to transform the raw value."),script:e.z.optional(f()).describe("Relative path of a Javascript .js file.")}).describe("Deprecated"),e.z.strictObject({fn:e.z.literal("zcl:attr").describe("Generic function to parse ZCL values from read/report commands."),at:r(4).or(e.z.array(r(4))).describe("String hex value or array of string hex values."),cl:r(4).describe("Cluster ID."),ep:e.z.optional(l()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),mf:e.z.optional(r(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),eval:e.z.optional(p()).describe("Javascript expression to transform the attribute value to the Item value."),script:e.z.optional(f()).describe("Relative path of a Javascript .js file.")}),e.z.strictObject({fn:e.z.literal("zcl:cmd").describe("Generic function to parse ZCL values from read/report commands."),cl:r(4).describe("Cluster ID."),ep:e.z.optional(l()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),mf:e.z.optional(r(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),cmd:e.z.optional(r(2)).describe("Zigbee command."),eval:e.z.optional(p()).describe("Javascript expression to transform the attribute value to the Item value."),script:e.z.optional(f()).describe("Relative path of a Javascript .js file.")}),e.z.strictObject({fn:e.z.literal("ias:zonestatus").describe("Generic function to parse IAS ZONE status change notifications or zone status from read/report command."),mask:e.z.optional(e.z.enum(["alarm1","alarm2"]).or(e.z.literal("alarm1,alarm2"))).describe("Sets the bitmask for Alert1 and Alert2 item of the IAS Zone status.")}),e.z.strictObject({fn:e.z.literal("numtostr").describe("Generic function to to convert number to string."),srcitem:e.z.enum(["state/airqualityppb","state/pm2_5"]).describe("The source item holding the number."),op:e.z.enum(["lt","le","eq","gt","ge"]).describe("Comparison operator (lt | le | eq | gt | ge)"),to:M().describe("Array of (num, string) mappings")}),e.z.strictObject({fn:e.z.literal("time").describe("Specialized function to parse time, local and last set time from read/report commands of the time cluster and auto-sync time if needed.")}),e.z.strictObject({fn:e.z.literal("xiaomi:special").describe("Generic function to parse custom Xiaomi attributes and commands."),ep:e.z.optional(l()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),mf:e.z.optional(r(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),at:e.z.optional(r(4)).describe("Attribute ID. The attribute to parse, shall be 0xff01, 0xff02 or 0x00f7"),idx:r(2).describe("A 8-bit string hex value."),eval:e.z.optional(p()).describe("Javascript expression to transform the raw value."),script:e.z.optional(f()).describe("Relative path of a Javascript .js file.")}),e.z.strictObject({fn:e.z.literal("tuya").describe("Generic function to parse Tuya data."),dpid:e.z.number().describe("Data point ID. 1-255 the datapoint ID."),eval:e.z.optional(p()).describe("Javascript expression to transform the raw value."),script:e.z.optional(f()).describe("Relative path of a Javascript .js file.")})]).refine(t=>!("eval"in t&&"script"in t),{message:"eval and script should not both be present"})}function Z(){return e.z.discriminatedUnion("fn",[e.z.strictObject({fn:e.z.literal("none")}),e.z.strictObject({fn:e.z.undefined(),at:e.z.optional(r(4).or(e.z.array(r(4)))).describe("Attribute ID."),"state.timeout":e.z.optional(e.z.number()),"change.timeout":e.z.optional(e.z.number()),cl:r(4).describe("Cluster ID."),dt:r(2).describe("Data type."),ep:e.z.optional(l()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),mf:e.z.optional(r(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),eval:e.z.optional(p()).describe("Javascript expression to transform the raw value."),script:e.z.optional(f()).describe("Relative path of a Javascript .js file.")}),e.z.strictObject({fn:e.z.literal("zcl"),at:e.z.optional(r(4).or(e.z.array(r(4)))).describe("Attribute ID."),"state.timeout":e.z.optional(e.z.number()),"change.timeout":e.z.optional(e.z.number()),cl:r(4).describe("Cluster ID."),dt:r(2).describe("Data type."),ep:e.z.optional(l()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),mf:e.z.optional(r(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),eval:e.z.optional(p()).describe("Javascript expression to transform the raw value."),script:e.z.optional(f()).describe("Relative path of a Javascript .js file.")}).describe("Deprecated"),e.z.strictObject({fn:e.z.literal("zcl:attr").describe("Generic function to parse ZCL values from read/report commands."),at:r(4).or(e.z.array(r(4))).describe("String hex value or array of string hex values."),"state.timeout":e.z.optional(e.z.number()),"change.timeout":e.z.optional(e.z.number()),cl:r(4).describe("Cluster ID."),dt:r(2).describe("Data type."),ep:e.z.optional(l()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),mf:e.z.optional(r(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),eval:e.z.optional(p()).describe("Javascript expression to transform the attribute value to the Item value."),script:e.z.optional(f()).describe("Relative path of a Javascript .js file.")}),e.z.strictObject({fn:e.z.literal("zcl:cmd").describe("Generic function to parse ZCL values from read/report commands."),cl:r(4).describe("Cluster ID."),ep:e.z.optional(l()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),mf:e.z.optional(r(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),cmd:e.z.optional(r(2)).describe("Zigbee command."),eval:e.z.optional(p()).describe("Javascript expression to transform the attribute value to the Item value."),script:e.z.optional(f()).describe("Relative path of a Javascript .js file.")}),e.z.strictObject({fn:e.z.literal("tuya").describe("Generic function to write Tuya data."),dpid:e.z.number().describe("Data point ID. 1-255 the datapoint ID."),dt:r(2).describe("Data type."),eval:e.z.optional(p()).describe("Javascript expression to transform the raw value."),script:e.z.optional(f()).describe("Relative path of a Javascript .js file.")})]).refine(t=>!("eval"in t&&"script"in t),{message:"eval and script should not both be present"})}function j(t){return e.z.strictObject({$schema:e.z.optional(e.z.string()),schema:e.z.literal("resourceitem1.schema.json"),id:e.z.string(),description:e.z.optional(e.z.string()).describe("Item description, better to do not use it."),comment:e.z.optional(e.z.string()).describe("TODO: What is this ? What the difference with description ?"),deprecated:e.z.optional(A()).describe("Date of deprecation, if the item is deprecated, it's better to use the new one."),datatype:e.z.optional(e.z.enum(["String","Bool","Int8","Int16","Int32","Int64","UInt8","UInt16","UInt32","UInt64","Double","Array","Array[3]","ISO 8601 timestamp"])).describe("Data type of the item."),access:e.z.optional(e.z.enum(["R","W","RW"])).describe("Access mode for this item, some of them are not editable."),public:e.z.optional(e.z.boolean()).describe("Item visible on the API."),implicit:e.z.optional(e.z.boolean()).describe("TODO: What is this ?"),managed:e.z.optional(e.z.boolean()).describe("TODO: What is this ?"),awake:e.z.optional(e.z.boolean()).describe("The device is considered awake when this item is set due a incoming command."),static:e.z.optional(e.z.union([e.z.string(),e.z.number(),e.z.boolean()])).describe("A static default value is fixed and can be not changed."),range:e.z.optional(e.z.tuple([e.z.number(),e.z.number()])).describe("Values range limit."),virtual:e.z.optional(e.z.boolean()).describe("TODO: What is this ?"),read:e.z.optional(S()).describe("Fonction used to read value."),parse:e.z.optional(J()).describe("Fonction used to parse incoming values."),write:e.z.optional(Z()).describe("Fonction used to write value."),"refresh.interval":e.z.optional(e.z.number()).describe("Refresh interval used for read fonction, NEED to be superior at value used in binding part."),values:e.z.optional(e.z.unknown()).describe("TODO: What is this ?"),default:e.z.optional(e.z.unknown()).describe("Defaut value.")})}function R(t){return e.z.strictObject({$schema:e.z.optional(e.z.string()),schema:e.z.literal("devcap1.schema.json"),uuid:e.z.optional(e.z.string()),version:e.z.optional(e.z.string()),version_deconz:e.z.optional(e.z.string()),"doc:path":e.z.optional(e.z.string()),"doc:hdr":e.z.optional(e.z.string()),"md:known_issues":e.z.optional(e.z.array(e.z.string())).describe("Know issues for this device, markdown file."),manufacturername:e.z.union([e.z.enum(Object.keys(t.manufacturers)),e.z.string().regex(/^(?!\$MF_).*/g,"The manufacturer name start with $MF_ but is not present in constants.json"),e.z.array(e.z.union([e.z.enum(Object.keys(t.manufacturers)),e.z.string().regex(/^(?!\$MF_).*/g,"The manufacturer name start with $MF_ but is not present in constants.json")]))]).describe("Manufacturer name from Basic Cluster."),modelid:e.z.string().or(e.z.array(e.z.string())).describe("Model ID from Basic Cluster."),vendor:e.z.optional(e.z.string()).describe("Friendly name of the manufacturer."),comment:e.z.optional(e.z.string()),matchexpr:e.z.optional(p()).describe("Need to return true for the DDF be used."),path:e.z.optional(f()).describe("DDF path, useless, can be removed."),product:e.z.optional(e.z.string()).describe("Complements the model id to be shown in the UI."),sleeper:e.z.optional(e.z.boolean()).describe("Sleeping devices can only receive when awake."),supportsMgmtBind:e.z.optional(e.z.boolean()),status:e.z.enum(["Draft","Bronze","Silver","Gold"]).describe("The code quality of the DDF file."),subdevices:e.z.array(G(t)).describe("Devices section."),bindings:e.z.optional(e.z.array(k())).describe("Bindings section.")})}function G(t){return e.z.strictObject({type:e.z.union([e.z.enum(Object.keys(t.deviceTypes),{errorMap:(a,d)=>a.code==="invalid_enum_value"?{message:`Invalid enum value. Expected type from generic attributes definition, received '${a.received}'`}:{message:d.defaultError}}),e.z.string().regex(/^(?!\$TYPE_).*/g,"The type start with $TYPE_ but is not present in constants.json")]),restapi:e.z.enum(["/lights","/sensors"]),uuid:I(),fingerprint:e.z.optional(e.z.strictObject({profile:r(4),device:r(4),endpoint:l(),in:e.z.optional(e.z.array(r(4))),out:e.z.optional(e.z.array(r(4)))})),meta:e.z.optional(e.z.strictObject({values:e.z.any(),"group.endpoints":e.z.optional(e.z.array(e.z.number()))})),buttons:e.z.optional(e.z.any()),buttonevents:e.z.optional(e.z.any()),items:e.z.array(F(t)),example:e.z.optional(e.z.unknown())})}function F(t){return j().omit({$schema:!0,schema:!0,id:!0}).extend({name:e.z.enum(t.attributes,{errorMap:(a,d)=>a.code==="invalid_enum_value"?{message:`Invalid enum value. Expected item from generic attributes definition, received '${a.received}'`}:{message:d.defaultError}}).describe("Item name.")})}function k(t){return e.z.discriminatedUnion("bind",[e.z.strictObject({bind:e.z.literal("unicast"),"src.ep":l().describe("Source endpoint."),"dst.ep":e.z.optional(l()).describe("Destination endpoint, generaly 0x01."),cl:r(4).describe("Cluster."),report:e.z.optional(e.z.array(e.z.strictObject({at:r(4),dt:r(2),mf:e.z.optional(r(4)),min:e.z.number(),max:e.z.number(),change:e.z.optional(r().or(e.z.number()))}).refine(a=>a.min<=a.max,{message:"invalid report time, min should be smaller than max"})))}),e.z.strictObject({bind:e.z.literal("groupcast"),"src.ep":l().describe("Source endpoint."),cl:r(4).describe("Cluster."),"config.group":e.z.number().min(0).max(255)})])}function L(t){const a=e.z.array(e.z.enum(t.attributes,{errorMap:(d,o)=>d.code==="invalid_enum_value"?{message:`Invalid enum value. Expected item from generic attributes definition, received '${d.received}'`}:{message:o.defaultError}}));return e.z.strictObject({$schema:e.z.optional(e.z.string()),schema:e.z.literal("subdevice1.schema.json"),type:e.z.union([e.z.enum(Object.keys(t.deviceTypes),{errorMap:(d,o)=>d.code==="invalid_enum_value"?{message:`Invalid enum value. Expected type from generic attributes definition, received '${d.received}'`}:{message:o.defaultError}}),e.z.string().regex(/^(?!\$TYPE_).*/g,"The type start with $TYPE_ but is not present in constants.json")]),name:e.z.string(),restapi:e.z.enum(["/lights","/sensors"]),order:e.z.number(),uuid:I(),items:a,items_optional:e.z.optional(a)})}function y(t){return e.z.discriminatedUnion("schema",[R(t),C(),x(),j(),L(t)]).superRefine((a,d)=>{switch(a.schema){case"devcap1.schema.json":g[a.schema].map(o=>o(a,d,t));break;case"constants2.schema.json":g[a.schema].map(o=>o(a,d,t));break}})}function W(t={attributes:[],manufacturers:{},deviceTypes:{},resources:{},subDevices:{}}){let a=y(t);const d=()=>{a=y(t)};return{generics:t,loadGeneric:s=>{const n=a.parse(s);switch(n.schema){case"constants1.schema.json":t.manufacturers={...t.manufacturers,...n.manufacturers},t.deviceTypes={...t.deviceTypes,...n["device-types"]};break;case"constants2.schema.json":{Object.keys(n).filter(i=>i.startsWith("$MF_")).forEach(i=>{t.manufacturers[i]=n[i]}),Object.keys(n).filter(i=>i.startsWith("$TYPE_")).forEach(i=>{t.deviceTypes[i]=n[i]});break}case"resourceitem1.schema.json":{if(t.attributes.includes(n.id))throw new Error(`Got duplicate resource item with attribute id '${n.id}'.`);const i=n,u=n.id;delete i.$schema,delete i.schema,delete i.id,t.resources[u]=i,t.attributes.push(u);break}case"subdevice1.schema.json":t.subDevices[n.type]=n,t.subDevices[n.name]=n;break;case"devcap1.schema.json":throw new Error("Got invalid generic file, got data with schema 'devcap1.schema.json'.")}return d(),!0},validate:s=>a.parse(s),getSchema:()=>a,version:D}}exports.createValidator=W;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("zod"),D="2.16.0",g={"devcap1.schema.json":[O,E,_,$,T],"constants2.schema.json":[w]};function O(t,a,u){const n=typeof t.manufacturername=="string"&&typeof t.modelid=="string";if(n)return;const c=Array.isArray(t.manufacturername)&&Array.isArray(t.modelid);if(c&&t.manufacturername.length!==t.modelid.length){a.addIssue({code:e.z.ZodIssueCode.invalid_intersection_types,message:"When 'manufacturername' and 'modelid' are both arrays they should be the same length",path:["manufacturername","modelid"]});return}(n||c)===!1&&a.addIssue({code:e.z.ZodIssueCode.invalid_intersection_types,message:"Invalid properties 'manufacturername' and 'modelid' should have the same type",path:["manufacturername","modelid"]})}function E(t,a,u){if(!t.bindings)return;const n=s=>`0x${(typeof s=="number"?s:Number.parseInt(s,16)).toString(16)}`,c={};t.bindings.forEach(s=>{s.bind==="unicast"&&s.report&&s.report.forEach(d=>{d.max!==65535&&(c[`${n(s["src.ep"])}.${n(s.cl)}.${n(d.at)}`]=d.max)})}),t.subdevices.forEach((s,d)=>{s.items.forEach((i,o)=>{var l;if(i["refresh.interval"]&&i.read&&i.read.fn==="zcl"){const z=n(i.read.ep??((l=s.fingerprint)==null?void 0:l.endpoint)??s.uuid[1]),b=Array.isArray(i.read.at)?i.read.at:[i.read.at];for(let h=0;h<b.length;h++){const v=`${z}.${n(i.read.cl)}.${n(b[h])}`;c[v]!==void 0&&i["refresh.interval"]-60<c[v]&&a.addIssue({code:e.z.ZodIssueCode.custom,message:`The refresh interval (${i["refresh.interval"]} - 60 = ${i["refresh.interval"]-60}) should be greater than the binding max refresh value (${c[v]}) with a margin of 60 seconds`,path:["subdevices",d,"items",o,"refresh.interval"]})}}})})}function _(t,a,u){const n=[{description:'a device with "state/ct" need the "min" and "max" values for capability.',if:{item:"state/ct"},need:{item:["cap/color/ct/min","cap/color/ct/max"]}},{description:'a device with "cap/color/ct/computes_xy" need the corresponding state/{x,y} items',if:{item:"cap/color/ct/computes_xy"},need:{item:["state/x","state/y","state/ct"]}},{description:'a device with "state/x" or "state/y" need the corresponding cap/color/xy/{red,green,blue}/{x,y} items',if:{item:{or:["state/x","state/y"]}},need:{item:["state/x","state/y","cap/color/xy/red_x","cap/color/xy/green_x","cap/color/xy/blue_x","cap/color/xy/red_y","cap/color/xy/green_y","cap/color/xy/blue_y"]}},{description:'a "(Extended) Color light" need ("state/x" and "state/y") or/and ("state/hue" and "state/sat") .',if:{type:{or:["$TYPE_EXTENDED_COLOR_LIGHT","Extended color light","$TYPE_COLOR_LIGHT","Color light"]}},need:{item:{or:[["state/x","state/y"],["state/hue","state/sat"]]}}}],c=(s,d)=>typeof s=="string"?d(s):Array.isArray(s)?s.every(i=>c(i,d)):"and"in s?s.and.every(i=>c(i,d)):"or"in s?s.or.some(i=>c(i,d)):!1;t.subdevices.forEach((s,d)=>{const i=s.items.map(o=>o.name);n.forEach(o=>{(Object.keys(o.if).length===0||Object.entries(o.if).some(([l,z])=>{switch(l){case"type":return c(z,b=>b===s.type);case"item":return c(z,b=>i.includes(b));default:return!1}}))&&(c(o.need.item,l=>i.includes(l))||a.addIssue({code:e.z.ZodIssueCode.custom,message:`The device is missing some items because ${o.description}`,path:["subdevices",d,"items"]}))})})}function $(t,a,u){const n=["parse","write"];t.subdevices.forEach((c,s)=>{c.items.forEach((d,i)=>{n.forEach(o=>{const l=d[o];l!==void 0&&(l.fn===void 0||l.fn==="zcl"||l.fn==="zcl:attr"||l.fn==="zcl:cmd")&&(l.eval===void 0&&l.script===void 0&&a.addIssue({code:e.z.ZodIssueCode.custom,message:`The '${o}' function is missing 'eval' or 'script' option.`,path:["subdevices",s,"items",i,o]}),l.eval!==void 0&&l.script!==void 0&&a.addIssue({code:e.z.ZodIssueCode.custom,message:`The '${o}' function is having both 'eval' and 'script' option.`,path:["subdevices",s,"items",i,o]}))})})})}function w(t,a,u){const n=x();Object.keys(t).forEach(c=>{if(!Object.keys(n.shape).includes(c)){if(!["$MF_","$TYPE_"].some(s=>c.startsWith(s))){a.addIssue({code:e.z.ZodIssueCode.custom,message:"The constant key should start with '$MF_' or '$TYPE_'",path:[c]});return}typeof t[c]!="string"&&a.addIssue({code:e.z.ZodIssueCode.custom,message:"The constant value should be a string",path:[c]})}})}function T(t,a,u){t.subdevices.forEach((n,c)=>{const s=u.subDevices[n.type];if(!s){a.addIssue({code:e.z.ZodIssueCode.custom,message:`The device is missing the device definition for the type "${n.type}"`,path:["subdevices",c,"items"]});return}let d=s.items;s.items_optional&&(d=d.filter(i=>!s.items_optional.includes(i))),d.forEach(i=>{n.items.find(o=>o.name===i)||a.addIssue({code:e.z.ZodIssueCode.custom,message:`The device should have the item "${i}" because it is mandatory for devices of type "${n.type}"`,path:["subdevices",c,"items"]})})})}function C(t){return e.z.strictObject({$schema:e.z.optional(e.z.string()),schema:e.z.literal("constants1.schema.json"),manufacturers:e.z.record(e.z.string().startsWith("$MF_"),e.z.string()),"device-types":e.z.record(e.z.string().startsWith("$TYPE_"),e.z.string())})}function x(t){return e.z.object({$schema:e.z.optional(e.z.string()),schema:e.z.literal("constants2.schema.json")}).passthrough()}function A(){return e.z.string().regex(/^(\d{4})-(?:(?:0[1-9])|(?:1[0-2]))-(?:(?:0[1-9])|(?:[12][0-9])|(?:3[01]))$/,"Invalid date value")}function r(t=void 0){const a="Invalid hexadecimal value";return t===void 0?e.z.string().regex(/^0x[0-9a-fA-F]+$/,a):e.z.string().regex(new RegExp(`^0x[0-9a-fA-F]{${t}}$`),a)}function m(){return e.z.union([r(2),e.z.number().min(0).max(255)])}function M(){return e.z.custom(t=>{if(!Array.isArray(t)||t.length%2!==0)return!1;for(let a=0;a<t.length;a+=2){const u=t[a],n=t[a+1];if(typeof u!="number"||typeof n!="string")return!1}return!0},"The value must be an array with an even number of values and alternating between number and string.")}function I(){return e.z.union([e.z.tuple([e.z.literal("$address.ext"),r(2)]),e.z.tuple([e.z.literal("$address.ext"),r(2),r(4)])])}function f(){return e.z.string()}function p(){return e.z.string()}function S(){return e.z.discriminatedUnion("fn",[e.z.strictObject({fn:e.z.literal("none")}),e.z.strictObject({fn:e.z.undefined().describe("Generic function to read ZCL attributes."),at:r(4).or(e.z.array(r(4))).describe("Attribute ID."),cl:r(4).describe("Cluster ID."),ep:e.z.optional(m()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),mf:e.z.optional(r(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),eval:e.z.optional(p()).describe("Javascript expression to transform the raw value.")}),e.z.strictObject({fn:e.z.literal("zcl").describe("Generic function to read ZCL attributes."),at:r(4).or(e.z.array(r(4))).describe("Attribute ID."),cl:r(4).describe("Cluster ID."),ep:e.z.optional(m()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),mf:e.z.optional(r(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),eval:e.z.optional(p()).describe("Javascript expression to transform the raw value."),script:e.z.optional(f()).describe("Relative path of a Javascript .js file.")}).describe("Deprecated"),e.z.strictObject({fn:e.z.literal("zcl:attr").describe("Generic function to parse ZCL values from read/report commands."),at:r(4).or(e.z.array(r(4))).describe("String hex value or array of string hex values."),cl:r(4).describe("Cluster ID."),ep:e.z.optional(m()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),mf:e.z.optional(r(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),eval:e.z.optional(p()).describe("Javascript expression to transform the attribute value to the Item value."),script:e.z.optional(f()).describe("Relative path of a Javascript .js file.")}),e.z.strictObject({fn:e.z.literal("zcl:cmd").describe("Generic function to parse ZCL values from read/report commands."),cl:r(4).describe("Cluster ID."),ep:e.z.optional(m()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),mf:e.z.optional(r(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),cmd:e.z.optional(r(2)).describe("Zigbee command."),eval:e.z.optional(p()).describe("Javascript expression to transform the attribute value to the Item value."),fc:e.z.optional(r(2).or(e.z.number())).describe("Zigbee command frame control."),script:e.z.optional(f()).describe("Relative path of a Javascript .js file.")}),e.z.strictObject({fn:e.z.literal("tuya").describe("Generic function to read all Tuya datapoints. It has no parameters.")})]).refine(t=>!("eval"in t&&"script"in t),{message:"eval and script should not both be present"})}function J(){return e.z.discriminatedUnion("fn",[e.z.strictObject({fn:e.z.undefined().describe("Generic function to parse ZCL attributes and commands."),at:e.z.optional(r(4).or(e.z.array(r(4)))).describe("Attribute ID."),cl:r(4).describe("Cluster ID."),cppsrc:e.z.optional(e.z.string()),ep:e.z.optional(m()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),cmd:e.z.optional(r(2)).describe("Zigbee command."),mf:e.z.optional(r(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),eval:e.z.optional(p()).describe("Javascript expression to transform the raw value."),script:e.z.optional(f()).describe("Relative path of a Javascript .js file.")}),e.z.strictObject({fn:e.z.literal("zcl").describe("Generic function to parse ZCL attributes and commands."),at:e.z.optional(r(4).or(e.z.array(r(4)))).describe("Attribute ID."),cl:r(4).describe("Cluster ID."),cppsrc:e.z.optional(e.z.string()),ep:e.z.optional(m()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),cmd:e.z.optional(r(2)).describe("Zigbee command."),mf:e.z.optional(r(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),eval:e.z.optional(p()).describe("Javascript expression to transform the raw value."),script:e.z.optional(f()).describe("Relative path of a Javascript .js file.")}).describe("Deprecated"),e.z.strictObject({fn:e.z.literal("zcl:attr").describe("Generic function to parse ZCL values from read/report commands."),at:r(4).or(e.z.array(r(4))).describe("String hex value or array of string hex values."),cl:r(4).describe("Cluster ID."),ep:e.z.optional(m()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),mf:e.z.optional(r(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),eval:e.z.optional(p()).describe("Javascript expression to transform the attribute value to the Item value."),script:e.z.optional(f()).describe("Relative path of a Javascript .js file.")}),e.z.strictObject({fn:e.z.literal("zcl:cmd").describe("Generic function to parse ZCL values from read/report commands."),cl:r(4).describe("Cluster ID."),ep:e.z.optional(m()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),mf:e.z.optional(r(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),cmd:e.z.optional(r(2)).describe("Zigbee command."),eval:e.z.optional(p()).describe("Javascript expression to transform the attribute value to the Item value."),script:e.z.optional(f()).describe("Relative path of a Javascript .js file.")}),e.z.strictObject({fn:e.z.literal("ias:zonestatus").describe("Generic function to parse IAS ZONE status change notifications or zone status from read/report command."),mask:e.z.optional(e.z.enum(["alarm1","alarm2"]).or(e.z.literal("alarm1,alarm2"))).describe("Sets the bitmask for Alert1 and Alert2 item of the IAS Zone status.")}),e.z.strictObject({fn:e.z.literal("numtostr").describe("Generic function to to convert number to string."),srcitem:e.z.enum(["state/airqualityppb","state/pm2_5"]).describe("The source item holding the number."),op:e.z.enum(["lt","le","eq","gt","ge"]).describe("Comparison operator (lt | le | eq | gt | ge)"),to:M().describe("Array of (num, string) mappings")}),e.z.strictObject({fn:e.z.literal("time").describe("Specialized function to parse time, local and last set time from read/report commands of the time cluster and auto-sync time if needed.")}),e.z.strictObject({fn:e.z.literal("xiaomi:special").describe("Generic function to parse custom Xiaomi attributes and commands."),ep:e.z.optional(m()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),mf:e.z.optional(r(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),at:e.z.optional(r(4)).describe("Attribute ID. The attribute to parse, shall be 0xff01, 0xff02 or 0x00f7"),idx:r(2).describe("A 8-bit string hex value."),eval:e.z.optional(p()).describe("Javascript expression to transform the raw value."),script:e.z.optional(f()).describe("Relative path of a Javascript .js file.")}),e.z.strictObject({fn:e.z.literal("tuya").describe("Generic function to parse Tuya data."),dpid:e.z.number().describe("Data point ID. 1-255 the datapoint ID."),eval:e.z.optional(p()).describe("Javascript expression to transform the raw value."),script:e.z.optional(f()).describe("Relative path of a Javascript .js file.")})]).refine(t=>!("eval"in t&&"script"in t),{message:"eval and script should not both be present"})}function Z(){return e.z.discriminatedUnion("fn",[e.z.strictObject({fn:e.z.literal("none")}),e.z.strictObject({fn:e.z.undefined(),at:e.z.optional(r(4).or(e.z.array(r(4)))).describe("Attribute ID."),"state.timeout":e.z.optional(e.z.number()),"change.timeout":e.z.optional(e.z.number()),cl:r(4).describe("Cluster ID."),dt:r(2).describe("Data type."),ep:e.z.optional(m()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),mf:e.z.optional(r(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),eval:e.z.optional(p()).describe("Javascript expression to transform the raw value."),script:e.z.optional(f()).describe("Relative path of a Javascript .js file.")}),e.z.strictObject({fn:e.z.literal("zcl"),at:e.z.optional(r(4).or(e.z.array(r(4)))).describe("Attribute ID."),"state.timeout":e.z.optional(e.z.number()),"change.timeout":e.z.optional(e.z.number()),cl:r(4).describe("Cluster ID."),dt:r(2).describe("Data type."),ep:e.z.optional(m()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),mf:e.z.optional(r(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),eval:e.z.optional(p()).describe("Javascript expression to transform the raw value."),script:e.z.optional(f()).describe("Relative path of a Javascript .js file.")}).describe("Deprecated"),e.z.strictObject({fn:e.z.literal("zcl:attr").describe("Generic function to parse ZCL values from read/report commands."),at:r(4).or(e.z.array(r(4))).describe("String hex value or array of string hex values."),"state.timeout":e.z.optional(e.z.number()),"change.timeout":e.z.optional(e.z.number()),cl:r(4).describe("Cluster ID."),dt:r(2).describe("Data type."),ep:e.z.optional(m()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),mf:e.z.optional(r(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),eval:e.z.optional(p()).describe("Javascript expression to transform the attribute value to the Item value."),script:e.z.optional(f()).describe("Relative path of a Javascript .js file.")}),e.z.strictObject({fn:e.z.literal("zcl:cmd").describe("Generic function to parse ZCL values from read/report commands."),cl:r(4).describe("Cluster ID."),ep:e.z.optional(m()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),mf:e.z.optional(r(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),cmd:e.z.optional(r(2)).describe("Zigbee command."),eval:e.z.optional(p()).describe("Javascript expression to transform the attribute value to the Item value."),script:e.z.optional(f()).describe("Relative path of a Javascript .js file.")}),e.z.strictObject({fn:e.z.literal("tuya").describe("Generic function to write Tuya data."),dpid:e.z.number().describe("Data point ID. 1-255 the datapoint ID."),dt:r(2).describe("Data type."),eval:e.z.optional(p()).describe("Javascript expression to transform the raw value."),script:e.z.optional(f()).describe("Relative path of a Javascript .js file.")})]).refine(t=>!("eval"in t&&"script"in t),{message:"eval and script should not both be present"})}function j(t){return e.z.strictObject({$schema:e.z.optional(e.z.string()),schema:e.z.literal("resourceitem1.schema.json"),id:e.z.string(),description:e.z.optional(e.z.string()).describe("Item description, better to do not use it."),comment:e.z.optional(e.z.string()).describe("TODO: What is this ? What the difference with description ?"),deprecated:e.z.optional(A()).describe("Date of deprecation, if the item is deprecated, it's better to use the new one."),datatype:e.z.optional(e.z.enum(["String","Bool","Int8","Int16","Int32","Int64","UInt8","UInt16","UInt32","UInt64","Double","Array","Array[3]","ISO 8601 timestamp"])).describe("Data type of the item."),access:e.z.optional(e.z.enum(["R","W","RW"])).describe("Access mode for this item, some of them are not editable."),public:e.z.optional(e.z.boolean()).describe("Item visible on the API."),implicit:e.z.optional(e.z.boolean()).describe("TODO: What is this ?"),managed:e.z.optional(e.z.boolean()).describe("TODO: What is this ?"),awake:e.z.optional(e.z.boolean()).describe("The device is considered awake when this item is set due a incoming command."),static:e.z.optional(e.z.union([e.z.string(),e.z.number(),e.z.boolean()])).describe("A static default value is fixed and can be not changed."),range:e.z.optional(e.z.tuple([e.z.number(),e.z.number()])).describe("Values range limit."),virtual:e.z.optional(e.z.boolean()).describe("TODO: What is this ?"),read:e.z.optional(S()).describe("Fonction used to read value."),parse:e.z.optional(J()).describe("Fonction used to parse incoming values."),write:e.z.optional(Z()).describe("Fonction used to write value."),"refresh.interval":e.z.optional(e.z.number()).describe("Refresh interval used for read fonction, NEED to be superior at value used in binding part."),values:e.z.optional(e.z.unknown()).describe("TODO: What is this ?"),default:e.z.optional(e.z.unknown()).describe("Defaut value.")})}function G(t){return e.z.strictObject({$schema:e.z.optional(e.z.string()),schema:e.z.literal("devcap1.schema.json"),uuid:e.z.optional(e.z.string()),version:e.z.optional(e.z.string()),version_deconz:e.z.optional(e.z.string()),"doc:path":e.z.optional(e.z.string()),"doc:hdr":e.z.optional(e.z.string()),"md:known_issues":e.z.optional(e.z.array(e.z.string())).describe("Know issues for this device, markdown file."),manufacturername:e.z.union([e.z.enum(Object.keys(t.manufacturers)),e.z.string().regex(/^(?!\$MF_).*/g,"The manufacturer name start with $MF_ but is not present in constants.json"),e.z.array(e.z.union([e.z.enum(Object.keys(t.manufacturers)),e.z.string().regex(/^(?!\$MF_).*/g,"The manufacturer name start with $MF_ but is not present in constants.json")]))]).describe("Manufacturer name from Basic Cluster."),modelid:e.z.string().or(e.z.array(e.z.string())).describe("Model ID from Basic Cluster."),vendor:e.z.optional(e.z.string()).describe("Friendly name of the manufacturer."),comment:e.z.optional(e.z.string()),matchexpr:e.z.optional(p()).describe("Need to return true for the DDF be used."),path:e.z.optional(f()).describe("DDF path, useless, can be removed."),product:e.z.optional(e.z.string()).describe("Complements the model id to be shown in the UI."),sleeper:e.z.optional(e.z.boolean()).describe("Sleeping devices can only receive when awake."),supportsMgmtBind:e.z.optional(e.z.boolean()),status:e.z.enum(["Draft","Bronze","Silver","Gold"]).describe("The code quality of the DDF file."),subdevices:e.z.array(R(t)).describe("Devices section."),bindings:e.z.optional(e.z.array(k())).describe("Bindings section.")})}function R(t){return e.z.strictObject({type:e.z.union([e.z.enum(Object.keys(t.deviceTypes),{errorMap:(a,u)=>a.code==="invalid_enum_value"?{message:`Invalid enum value. Expected type from generic attributes definition, received '${a.received}'`}:{message:u.defaultError}}),e.z.string().regex(/^(?!\$TYPE_).*/g,"The type start with $TYPE_ but is not present in constants.json")]),restapi:e.z.enum(["/lights","/sensors"]),uuid:I(),fingerprint:e.z.optional(e.z.strictObject({profile:r(4),device:r(4),endpoint:m(),in:e.z.optional(e.z.array(r(4))),out:e.z.optional(e.z.array(r(4)))})),meta:e.z.optional(e.z.strictObject({values:e.z.any(),"group.endpoints":e.z.optional(e.z.array(e.z.number()))})),buttons:e.z.optional(e.z.any()),buttonevents:e.z.optional(e.z.any()),items:e.z.array(F(t)),example:e.z.optional(e.z.unknown())})}function F(t){return j().omit({$schema:!0,schema:!0,id:!0}).extend({name:e.z.enum(t.attributes,{errorMap:(a,u)=>a.code==="invalid_enum_value"?{message:`Invalid enum value. Expected item from generic attributes definition, received '${a.received}'`}:{message:u.defaultError}}).describe("Item name.")})}function k(t){return e.z.discriminatedUnion("bind",[e.z.strictObject({bind:e.z.literal("unicast"),"src.ep":m().describe("Source endpoint."),"dst.ep":e.z.optional(m()).describe("Destination endpoint, generaly 0x01."),cl:r(4).describe("Cluster."),report:e.z.optional(e.z.array(e.z.strictObject({at:r(4),dt:r(2),mf:e.z.optional(r(4)),min:e.z.number(),max:e.z.number(),change:e.z.optional(r().or(e.z.number()))}).refine(a=>a.min<=a.max,{message:"invalid report time, min should be smaller than max"})))}),e.z.strictObject({bind:e.z.literal("groupcast"),"src.ep":m().describe("Source endpoint."),cl:r(4).describe("Cluster."),"config.group":e.z.number().min(0).max(255)})])}function L(t){const a=e.z.array(e.z.enum(t.attributes,{errorMap:(u,n)=>u.code==="invalid_enum_value"?{message:`Invalid enum value. Expected item from generic attributes definition, received '${u.received}'`}:{message:n.defaultError}}));return e.z.strictObject({$schema:e.z.optional(e.z.string()),schema:e.z.literal("subdevice1.schema.json"),type:e.z.union([e.z.enum(Object.keys(t.deviceTypes),{errorMap:(u,n)=>u.code==="invalid_enum_value"?{message:`Invalid enum value. Expected type from generic attributes definition, received '${u.received}'`}:{message:n.defaultError}}),e.z.string().regex(/^(?!\$TYPE_).*/g,"The type start with $TYPE_ but is not present in constants.json")]),name:e.z.string(),restapi:e.z.enum(["/lights","/sensors"]),order:e.z.number(),uuid:I(),items:a,items_optional:e.z.optional(a)})}function y(t){return e.z.discriminatedUnion("schema",[G(t),C(),x(),j(),L(t)]).superRefine((a,u)=>{switch(a.schema){case"devcap1.schema.json":g[a.schema].map(n=>n(a,u,t));break;case"constants2.schema.json":g[a.schema].map(n=>n(a,u,t));break}})}function W(t={attributes:[],manufacturers:{},deviceTypes:{},resources:{},subDevices:{}}){let a=y(t);const u=()=>{a=y(t)};return{generics:t,loadGeneric:d=>{const i=a.parse(d);switch(i.schema){case"constants1.schema.json":t.manufacturers={...t.manufacturers,...i.manufacturers},t.deviceTypes={...t.deviceTypes,...i["device-types"]};break;case"constants2.schema.json":{Object.keys(i).filter(o=>o.startsWith("$MF_")).forEach(o=>{t.manufacturers[o]=i[o]}),Object.keys(i).filter(o=>o.startsWith("$TYPE_")).forEach(o=>{t.deviceTypes[o]=i[o]});break}case"resourceitem1.schema.json":{if(t.attributes.includes(i.id))throw new Error(`Got duplicate resource item with attribute id '${i.id}'.`);const o=i,l=i.id;delete o.$schema,delete o.schema,delete o.id,t.resources[l]=o,t.attributes.push(l);break}case"subdevice1.schema.json":t.subDevices[i.type]=i,t.subDevices[i.name]=i;break;default:throw new Error(`Got invalid generic file, got data with schema '${i.schema}'.`)}return u(),!0},validate:d=>a.parse(d),getSchema:()=>a,version:D,isGeneric:d=>["constants1.schema.json","constants2.schema.json","resourceitem1.schema.json","subdevice1.schema.json"].includes(d)}}exports.createValidator=W;
@@ -1,5 +1,5 @@
1
1
  import { z as e } from "zod";
2
- const E = "2.15.0", y = {
2
+ const E = "2.16.0", y = {
3
3
  "devcap1.schema.json": [
4
4
  O,
5
5
  _,
@@ -11,9 +11,9 @@ const E = "2.15.0", y = {
11
11
  T
12
12
  ]
13
13
  };
14
- function O(t, a, d) {
15
- const o = typeof t.manufacturername == "string" && typeof t.modelid == "string";
16
- if (o)
14
+ function O(t, a, u) {
15
+ const n = typeof t.manufacturername == "string" && typeof t.modelid == "string";
16
+ if (n)
17
17
  return;
18
18
  const c = Array.isArray(t.manufacturername) && Array.isArray(t.modelid);
19
19
  if (c && t.manufacturername.length !== t.modelid.length) {
@@ -24,39 +24,39 @@ function O(t, a, d) {
24
24
  });
25
25
  return;
26
26
  }
27
- (o || c) === !1 && a.addIssue({
27
+ (n || c) === !1 && a.addIssue({
28
28
  code: e.ZodIssueCode.invalid_intersection_types,
29
29
  message: "Invalid properties 'manufacturername' and 'modelid' should have the same type",
30
30
  path: ["manufacturername", "modelid"]
31
31
  });
32
32
  }
33
- function _(t, a, d) {
33
+ function _(t, a, u) {
34
34
  if (!t.bindings)
35
35
  return;
36
- const o = (s) => `0x${(typeof s == "number" ? s : Number.parseInt(s, 16)).toString(16)}`, c = {};
36
+ const n = (s) => `0x${(typeof s == "number" ? s : Number.parseInt(s, 16)).toString(16)}`, c = {};
37
37
  t.bindings.forEach((s) => {
38
- s.bind === "unicast" && s.report && s.report.forEach((n) => {
39
- n.max !== 65535 && (c[`${o(s["src.ep"])}.${o(s.cl)}.${o(n.at)}`] = n.max);
38
+ s.bind === "unicast" && s.report && s.report.forEach((d) => {
39
+ d.max !== 65535 && (c[`${n(s["src.ep"])}.${n(s.cl)}.${n(d.at)}`] = d.max);
40
40
  });
41
- }), t.subdevices.forEach((s, n) => {
42
- s.items.forEach((i, u) => {
43
- var m;
41
+ }), t.subdevices.forEach((s, d) => {
42
+ s.items.forEach((i, o) => {
43
+ var l;
44
44
  if (i["refresh.interval"] && i.read && i.read.fn === "zcl") {
45
- const h = o(i.read.ep ?? ((m = s.fingerprint) == null ? void 0 : m.endpoint) ?? s.uuid[1]), b = Array.isArray(i.read.at) ? i.read.at : [i.read.at];
45
+ const h = n(i.read.ep ?? ((l = s.fingerprint) == null ? void 0 : l.endpoint) ?? s.uuid[1]), b = Array.isArray(i.read.at) ? i.read.at : [i.read.at];
46
46
  for (let v = 0; v < b.length; v++) {
47
- const g = `${h}.${o(i.read.cl)}.${o(b[v])}`;
47
+ const g = `${h}.${n(i.read.cl)}.${n(b[v])}`;
48
48
  c[g] !== void 0 && i["refresh.interval"] - 60 < c[g] && a.addIssue({
49
49
  code: e.ZodIssueCode.custom,
50
50
  message: `The refresh interval (${i["refresh.interval"]} - 60 = ${i["refresh.interval"] - 60}) should be greater than the binding max refresh value (${c[g]}) with a margin of 60 seconds`,
51
- path: ["subdevices", n, "items", u, "refresh.interval"]
51
+ path: ["subdevices", d, "items", o, "refresh.interval"]
52
52
  });
53
53
  }
54
54
  }
55
55
  });
56
56
  });
57
57
  }
58
- function $(t, a, d) {
59
- const o = [
58
+ function $(t, a, u) {
59
+ const n = [
60
60
  /*
61
61
  {
62
62
  description: 'a device should always have basic attributes.',
@@ -146,12 +146,12 @@ function $(t, a, d) {
146
146
  }
147
147
  }
148
148
  }
149
- ], c = (s, n) => typeof s == "string" ? n(s) : Array.isArray(s) ? s.every((i) => c(i, n)) : "and" in s ? s.and.every((i) => c(i, n)) : "or" in s ? s.or.some((i) => c(i, n)) : !1;
150
- t.subdevices.forEach((s, n) => {
151
- const i = s.items.map((u) => u.name);
152
- o.forEach((u) => {
153
- (Object.keys(u.if).length === 0 || Object.entries(u.if).some(([m, h]) => {
154
- switch (m) {
149
+ ], c = (s, d) => typeof s == "string" ? d(s) : Array.isArray(s) ? s.every((i) => c(i, d)) : "and" in s ? s.and.every((i) => c(i, d)) : "or" in s ? s.or.some((i) => c(i, d)) : !1;
150
+ t.subdevices.forEach((s, d) => {
151
+ const i = s.items.map((o) => o.name);
152
+ n.forEach((o) => {
153
+ (Object.keys(o.if).length === 0 || Object.entries(o.if).some(([l, h]) => {
154
+ switch (l) {
155
155
  case "type":
156
156
  return c(h, (b) => b === s.type);
157
157
  case "item":
@@ -159,37 +159,37 @@ function $(t, a, d) {
159
159
  default:
160
160
  return !1;
161
161
  }
162
- })) && (c(u.need.item, (m) => i.includes(m)) || a.addIssue({
162
+ })) && (c(o.need.item, (l) => i.includes(l)) || a.addIssue({
163
163
  code: e.ZodIssueCode.custom,
164
- message: `The device is missing some items because ${u.description}`,
165
- path: ["subdevices", n, "items"]
164
+ message: `The device is missing some items because ${o.description}`,
165
+ path: ["subdevices", d, "items"]
166
166
  }));
167
167
  });
168
168
  });
169
169
  }
170
- function w(t, a, d) {
171
- const o = ["parse", "write"];
170
+ function w(t, a, u) {
171
+ const n = ["parse", "write"];
172
172
  t.subdevices.forEach((c, s) => {
173
- c.items.forEach((n, i) => {
174
- o.forEach((u) => {
175
- const m = n[u];
176
- m !== void 0 && (m.fn === void 0 || m.fn === "zcl" || m.fn === "zcl:attr" || m.fn === "zcl:cmd") && (m.eval === void 0 && m.script === void 0 && a.addIssue({
173
+ c.items.forEach((d, i) => {
174
+ n.forEach((o) => {
175
+ const l = d[o];
176
+ l !== void 0 && (l.fn === void 0 || l.fn === "zcl" || l.fn === "zcl:attr" || l.fn === "zcl:cmd") && (l.eval === void 0 && l.script === void 0 && a.addIssue({
177
177
  code: e.ZodIssueCode.custom,
178
- message: `The '${u}' function is missing 'eval' or 'script' option.`,
179
- path: ["subdevices", s, "items", i, u]
180
- }), m.eval !== void 0 && m.script !== void 0 && a.addIssue({
178
+ message: `The '${o}' function is missing 'eval' or 'script' option.`,
179
+ path: ["subdevices", s, "items", i, o]
180
+ }), l.eval !== void 0 && l.script !== void 0 && a.addIssue({
181
181
  code: e.ZodIssueCode.custom,
182
- message: `The '${u}' function is having both 'eval' and 'script' option.`,
183
- path: ["subdevices", s, "items", i, u]
182
+ message: `The '${o}' function is having both 'eval' and 'script' option.`,
183
+ path: ["subdevices", s, "items", i, o]
184
184
  }));
185
185
  });
186
186
  });
187
187
  });
188
188
  }
189
- function T(t, a, d) {
190
- const o = I();
189
+ function T(t, a, u) {
190
+ const n = I();
191
191
  Object.keys(t).forEach((c) => {
192
- if (!Object.keys(o.shape).includes(c)) {
192
+ if (!Object.keys(n.shape).includes(c)) {
193
193
  if (!["$MF_", "$TYPE_"].some((s) => c.startsWith(s))) {
194
194
  a.addIssue({
195
195
  code: e.ZodIssueCode.custom,
@@ -206,22 +206,22 @@ function T(t, a, d) {
206
206
  }
207
207
  });
208
208
  }
209
- function C(t, a, d) {
210
- t.subdevices.forEach((o, c) => {
211
- const s = d.subDevices[o.type];
209
+ function C(t, a, u) {
210
+ t.subdevices.forEach((n, c) => {
211
+ const s = u.subDevices[n.type];
212
212
  if (!s) {
213
213
  a.addIssue({
214
214
  code: e.ZodIssueCode.custom,
215
- message: `The device is missing the device definition for the type "${o.type}"`,
215
+ message: `The device is missing the device definition for the type "${n.type}"`,
216
216
  path: ["subdevices", c, "items"]
217
217
  });
218
218
  return;
219
219
  }
220
- let n = s.items;
221
- s.items_optional && (n = n.filter((i) => !s.items_optional.includes(i))), n.forEach((i) => {
222
- o.items.find((u) => u.name === i) || a.addIssue({
220
+ let d = s.items;
221
+ s.items_optional && (d = d.filter((i) => !s.items_optional.includes(i))), d.forEach((i) => {
222
+ n.items.find((o) => o.name === i) || a.addIssue({
223
223
  code: e.ZodIssueCode.custom,
224
- message: `The device should have the item "${i}" because it is mandatory for devices of type "${o.type}"`,
224
+ message: `The device should have the item "${i}" because it is mandatory for devices of type "${n.type}"`,
225
225
  path: ["subdevices", c, "items"]
226
226
  });
227
227
  });
@@ -252,7 +252,7 @@ function r(t = void 0) {
252
252
  const a = "Invalid hexadecimal value";
253
253
  return t === void 0 ? e.string().regex(/^0x[0-9a-fA-F]+$/, a) : e.string().regex(new RegExp(`^0x[0-9a-fA-F]{${t}}$`), a);
254
254
  }
255
- function l() {
255
+ function m() {
256
256
  return e.union([
257
257
  r(2),
258
258
  e.number().min(0).max(255)
@@ -263,8 +263,8 @@ function S() {
263
263
  if (!Array.isArray(t) || t.length % 2 !== 0)
264
264
  return !1;
265
265
  for (let a = 0; a < t.length; a += 2) {
266
- const d = t[a], o = t[a + 1];
267
- if (typeof d != "number" || typeof o != "string")
266
+ const u = t[a], n = t[a + 1];
267
+ if (typeof u != "number" || typeof n != "string")
268
268
  return !1;
269
269
  }
270
270
  return !0;
@@ -298,7 +298,7 @@ function J() {
298
298
  fn: e.undefined().describe("Generic function to read ZCL attributes."),
299
299
  at: r(4).or(e.array(r(4))).describe("Attribute ID."),
300
300
  cl: r(4).describe("Cluster ID."),
301
- ep: e.optional(l()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),
301
+ ep: e.optional(m()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),
302
302
  mf: e.optional(r(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),
303
303
  eval: e.optional(p()).describe("Javascript expression to transform the raw value.")
304
304
  }),
@@ -306,7 +306,7 @@ function J() {
306
306
  fn: e.literal("zcl").describe("Generic function to read ZCL attributes."),
307
307
  at: r(4).or(e.array(r(4))).describe("Attribute ID."),
308
308
  cl: r(4).describe("Cluster ID."),
309
- ep: e.optional(l()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),
309
+ ep: e.optional(m()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),
310
310
  mf: e.optional(r(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),
311
311
  eval: e.optional(p()).describe("Javascript expression to transform the raw value."),
312
312
  script: e.optional(f()).describe("Relative path of a Javascript .js file.")
@@ -315,7 +315,7 @@ function J() {
315
315
  fn: e.literal("zcl:attr").describe("Generic function to parse ZCL values from read/report commands."),
316
316
  at: r(4).or(e.array(r(4))).describe("String hex value or array of string hex values."),
317
317
  cl: r(4).describe("Cluster ID."),
318
- ep: e.optional(l()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),
318
+ ep: e.optional(m()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),
319
319
  mf: e.optional(r(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),
320
320
  eval: e.optional(p()).describe("Javascript expression to transform the attribute value to the Item value."),
321
321
  script: e.optional(f()).describe("Relative path of a Javascript .js file.")
@@ -323,7 +323,7 @@ function J() {
323
323
  e.strictObject({
324
324
  fn: e.literal("zcl:cmd").describe("Generic function to parse ZCL values from read/report commands."),
325
325
  cl: r(4).describe("Cluster ID."),
326
- ep: e.optional(l()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),
326
+ ep: e.optional(m()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),
327
327
  mf: e.optional(r(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),
328
328
  cmd: e.optional(r(2)).describe("Zigbee command."),
329
329
  eval: e.optional(p()).describe("Javascript expression to transform the attribute value to the Item value."),
@@ -344,7 +344,7 @@ function Z() {
344
344
  at: e.optional(r(4).or(e.array(r(4)))).describe("Attribute ID."),
345
345
  cl: r(4).describe("Cluster ID."),
346
346
  cppsrc: e.optional(e.string()),
347
- ep: e.optional(l()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),
347
+ ep: e.optional(m()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),
348
348
  cmd: e.optional(r(2)).describe("Zigbee command."),
349
349
  mf: e.optional(r(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),
350
350
  eval: e.optional(p()).describe("Javascript expression to transform the raw value."),
@@ -355,7 +355,7 @@ function Z() {
355
355
  at: e.optional(r(4).or(e.array(r(4)))).describe("Attribute ID."),
356
356
  cl: r(4).describe("Cluster ID."),
357
357
  cppsrc: e.optional(e.string()),
358
- ep: e.optional(l()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),
358
+ ep: e.optional(m()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),
359
359
  cmd: e.optional(r(2)).describe("Zigbee command."),
360
360
  mf: e.optional(r(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),
361
361
  eval: e.optional(p()).describe("Javascript expression to transform the raw value."),
@@ -365,7 +365,7 @@ function Z() {
365
365
  fn: e.literal("zcl:attr").describe("Generic function to parse ZCL values from read/report commands."),
366
366
  at: r(4).or(e.array(r(4))).describe("String hex value or array of string hex values."),
367
367
  cl: r(4).describe("Cluster ID."),
368
- ep: e.optional(l()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),
368
+ ep: e.optional(m()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),
369
369
  mf: e.optional(r(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),
370
370
  eval: e.optional(p()).describe("Javascript expression to transform the attribute value to the Item value."),
371
371
  script: e.optional(f()).describe("Relative path of a Javascript .js file.")
@@ -373,7 +373,7 @@ function Z() {
373
373
  e.strictObject({
374
374
  fn: e.literal("zcl:cmd").describe("Generic function to parse ZCL values from read/report commands."),
375
375
  cl: r(4).describe("Cluster ID."),
376
- ep: e.optional(l()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),
376
+ ep: e.optional(m()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),
377
377
  mf: e.optional(r(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),
378
378
  cmd: e.optional(r(2)).describe("Zigbee command."),
379
379
  eval: e.optional(p()).describe("Javascript expression to transform the attribute value to the Item value."),
@@ -395,7 +395,7 @@ function Z() {
395
395
  }),
396
396
  e.strictObject({
397
397
  fn: e.literal("xiaomi:special").describe("Generic function to parse custom Xiaomi attributes and commands."),
398
- ep: e.optional(l()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),
398
+ ep: e.optional(m()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),
399
399
  mf: e.optional(r(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),
400
400
  at: e.optional(r(4)).describe("Attribute ID. The attribute to parse, shall be 0xff01, 0xff02 or 0x00f7"),
401
401
  idx: r(2).describe("A 8-bit string hex value."),
@@ -412,7 +412,7 @@ function Z() {
412
412
  message: "eval and script should not both be present"
413
413
  });
414
414
  }
415
- function R() {
415
+ function G() {
416
416
  return e.discriminatedUnion("fn", [
417
417
  e.strictObject({
418
418
  fn: e.literal("none")
@@ -424,7 +424,7 @@ function R() {
424
424
  "change.timeout": e.optional(e.number()),
425
425
  cl: r(4).describe("Cluster ID."),
426
426
  dt: r(2).describe("Data type."),
427
- ep: e.optional(l()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),
427
+ ep: e.optional(m()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),
428
428
  mf: e.optional(r(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),
429
429
  eval: e.optional(p()).describe("Javascript expression to transform the raw value."),
430
430
  script: e.optional(f()).describe("Relative path of a Javascript .js file.")
@@ -436,7 +436,7 @@ function R() {
436
436
  "change.timeout": e.optional(e.number()),
437
437
  cl: r(4).describe("Cluster ID."),
438
438
  dt: r(2).describe("Data type."),
439
- ep: e.optional(l()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),
439
+ ep: e.optional(m()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),
440
440
  mf: e.optional(r(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),
441
441
  eval: e.optional(p()).describe("Javascript expression to transform the raw value."),
442
442
  script: e.optional(f()).describe("Relative path of a Javascript .js file.")
@@ -448,7 +448,7 @@ function R() {
448
448
  "change.timeout": e.optional(e.number()),
449
449
  cl: r(4).describe("Cluster ID."),
450
450
  dt: r(2).describe("Data type."),
451
- ep: e.optional(l()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),
451
+ ep: e.optional(m()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),
452
452
  mf: e.optional(r(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),
453
453
  eval: e.optional(p()).describe("Javascript expression to transform the attribute value to the Item value."),
454
454
  script: e.optional(f()).describe("Relative path of a Javascript .js file.")
@@ -456,7 +456,7 @@ function R() {
456
456
  e.strictObject({
457
457
  fn: e.literal("zcl:cmd").describe("Generic function to parse ZCL values from read/report commands."),
458
458
  cl: r(4).describe("Cluster ID."),
459
- ep: e.optional(l()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),
459
+ ep: e.optional(m()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),
460
460
  mf: e.optional(r(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),
461
461
  cmd: e.optional(r(2)).describe("Zigbee command."),
462
462
  eval: e.optional(p()).describe("Javascript expression to transform the attribute value to the Item value."),
@@ -507,7 +507,7 @@ function D(t) {
507
507
  virtual: e.optional(e.boolean()).describe("TODO: What is this ?"),
508
508
  read: e.optional(J()).describe("Fonction used to read value."),
509
509
  parse: e.optional(Z()).describe("Fonction used to parse incoming values."),
510
- write: e.optional(R()).describe("Fonction used to write value."),
510
+ write: e.optional(G()).describe("Fonction used to write value."),
511
511
  "refresh.interval": e.optional(e.number()).describe("Refresh interval used for read fonction, NEED to be superior at value used in binding part."),
512
512
  // TODO Validate this
513
513
  values: e.optional(e.unknown()).describe("TODO: What is this ?"),
@@ -515,7 +515,7 @@ function D(t) {
515
515
  default: e.optional(e.unknown()).describe("Defaut value.")
516
516
  });
517
517
  }
518
- function G(t) {
518
+ function R(t) {
519
519
  return e.strictObject({
520
520
  $schema: e.optional(e.string()),
521
521
  schema: e.literal("devcap1.schema.json"),
@@ -552,7 +552,7 @@ function F(t) {
552
552
  return e.strictObject({
553
553
  type: e.union([
554
554
  e.enum(Object.keys(t.deviceTypes), {
555
- errorMap: (a, d) => a.code === "invalid_enum_value" ? { message: `Invalid enum value. Expected type from generic attributes definition, received '${a.received}'` } : { message: d.defaultError }
555
+ errorMap: (a, u) => a.code === "invalid_enum_value" ? { message: `Invalid enum value. Expected type from generic attributes definition, received '${a.received}'` } : { message: u.defaultError }
556
556
  }),
557
557
  e.string().regex(/^(?!\$TYPE_).*/g, "The type start with $TYPE_ but is not present in constants.json")
558
558
  ]),
@@ -561,7 +561,7 @@ function F(t) {
561
561
  fingerprint: e.optional(e.strictObject({
562
562
  profile: r(4),
563
563
  device: r(4),
564
- endpoint: l(),
564
+ endpoint: m(),
565
565
  in: e.optional(e.array(r(4))),
566
566
  out: e.optional(e.array(r(4)))
567
567
  })),
@@ -585,7 +585,7 @@ function z(t) {
585
585
  id: !0
586
586
  }).extend({
587
587
  name: e.enum(t.attributes, {
588
- errorMap: (a, d) => a.code === "invalid_enum_value" ? { message: `Invalid enum value. Expected item from generic attributes definition, received '${a.received}'` } : { message: d.defaultError }
588
+ errorMap: (a, u) => a.code === "invalid_enum_value" ? { message: `Invalid enum value. Expected item from generic attributes definition, received '${a.received}'` } : { message: u.defaultError }
589
589
  }).describe("Item name.")
590
590
  });
591
591
  }
@@ -593,8 +593,8 @@ function k(t) {
593
593
  return e.discriminatedUnion("bind", [
594
594
  e.strictObject({
595
595
  bind: e.literal("unicast"),
596
- "src.ep": l().describe("Source endpoint."),
597
- "dst.ep": e.optional(l()).describe("Destination endpoint, generaly 0x01."),
596
+ "src.ep": m().describe("Source endpoint."),
597
+ "dst.ep": e.optional(m()).describe("Destination endpoint, generaly 0x01."),
598
598
  cl: r(4).describe("Cluster."),
599
599
  report: e.optional(e.array(
600
600
  e.strictObject({
@@ -609,7 +609,7 @@ function k(t) {
609
609
  }),
610
610
  e.strictObject({
611
611
  bind: e.literal("groupcast"),
612
- "src.ep": l().describe("Source endpoint."),
612
+ "src.ep": m().describe("Source endpoint."),
613
613
  cl: r(4).describe("Cluster."),
614
614
  "config.group": e.number().min(0).max(255)
615
615
  })
@@ -618,7 +618,7 @@ function k(t) {
618
618
  function L(t) {
619
619
  const a = e.array(
620
620
  e.enum(t.attributes, {
621
- errorMap: (d, o) => d.code === "invalid_enum_value" ? { message: `Invalid enum value. Expected item from generic attributes definition, received '${d.received}'` } : { message: o.defaultError }
621
+ errorMap: (u, n) => u.code === "invalid_enum_value" ? { message: `Invalid enum value. Expected item from generic attributes definition, received '${u.received}'` } : { message: n.defaultError }
622
622
  })
623
623
  );
624
624
  return e.strictObject({
@@ -626,7 +626,7 @@ function L(t) {
626
626
  schema: e.literal("subdevice1.schema.json"),
627
627
  type: e.union([
628
628
  e.enum(Object.keys(t.deviceTypes), {
629
- errorMap: (d, o) => d.code === "invalid_enum_value" ? { message: `Invalid enum value. Expected type from generic attributes definition, received '${d.received}'` } : { message: o.defaultError }
629
+ errorMap: (u, n) => u.code === "invalid_enum_value" ? { message: `Invalid enum value. Expected type from generic attributes definition, received '${u.received}'` } : { message: n.defaultError }
630
630
  }),
631
631
  e.string().regex(/^(?!\$TYPE_).*/g, "The type start with $TYPE_ but is not present in constants.json")
632
632
  ]),
@@ -640,18 +640,18 @@ function L(t) {
640
640
  }
641
641
  function x(t) {
642
642
  return e.discriminatedUnion("schema", [
643
- G(t),
643
+ R(t),
644
644
  A(),
645
645
  I(),
646
646
  D(),
647
647
  L(t)
648
- ]).superRefine((a, d) => {
648
+ ]).superRefine((a, u) => {
649
649
  switch (a.schema) {
650
650
  case "devcap1.schema.json":
651
- y[a.schema].map((o) => o(a, d, t));
651
+ y[a.schema].map((n) => n(a, u, t));
652
652
  break;
653
653
  case "constants2.schema.json":
654
- y[a.schema].map((o) => o(a, d, t));
654
+ y[a.schema].map((n) => n(a, u, t));
655
655
  break;
656
656
  }
657
657
  });
@@ -664,44 +664,49 @@ function P(t = {
664
664
  subDevices: {}
665
665
  }) {
666
666
  let a = x(t);
667
- const d = () => {
667
+ const u = () => {
668
668
  a = x(t);
669
669
  };
670
- return { generics: t, loadGeneric: (s) => {
671
- const n = a.parse(s);
672
- switch (n.schema) {
670
+ return { generics: t, loadGeneric: (d) => {
671
+ const i = a.parse(d);
672
+ switch (i.schema) {
673
673
  case "constants1.schema.json":
674
674
  t.manufacturers = {
675
675
  ...t.manufacturers,
676
- ...n.manufacturers
676
+ ...i.manufacturers
677
677
  }, t.deviceTypes = {
678
678
  ...t.deviceTypes,
679
- ...n["device-types"]
679
+ ...i["device-types"]
680
680
  };
681
681
  break;
682
682
  case "constants2.schema.json": {
683
- Object.keys(n).filter((i) => i.startsWith("$MF_")).forEach((i) => {
684
- t.manufacturers[i] = n[i];
685
- }), Object.keys(n).filter((i) => i.startsWith("$TYPE_")).forEach((i) => {
686
- t.deviceTypes[i] = n[i];
683
+ Object.keys(i).filter((o) => o.startsWith("$MF_")).forEach((o) => {
684
+ t.manufacturers[o] = i[o];
685
+ }), Object.keys(i).filter((o) => o.startsWith("$TYPE_")).forEach((o) => {
686
+ t.deviceTypes[o] = i[o];
687
687
  });
688
688
  break;
689
689
  }
690
690
  case "resourceitem1.schema.json": {
691
- if (t.attributes.includes(n.id))
692
- throw new Error(`Got duplicate resource item with attribute id '${n.id}'.`);
693
- const i = n, u = n.id;
694
- delete i.$schema, delete i.schema, delete i.id, t.resources[u] = i, t.attributes.push(u);
691
+ if (t.attributes.includes(i.id))
692
+ throw new Error(`Got duplicate resource item with attribute id '${i.id}'.`);
693
+ const o = i, l = i.id;
694
+ delete o.$schema, delete o.schema, delete o.id, t.resources[l] = o, t.attributes.push(l);
695
695
  break;
696
696
  }
697
697
  case "subdevice1.schema.json":
698
- t.subDevices[n.type] = n, t.subDevices[n.name] = n;
698
+ t.subDevices[i.type] = i, t.subDevices[i.name] = i;
699
699
  break;
700
- case "devcap1.schema.json":
701
- throw new Error("Got invalid generic file, got data with schema 'devcap1.schema.json'.");
700
+ default:
701
+ throw new Error(`Got invalid generic file, got data with schema '${i.schema}'.`);
702
702
  }
703
- return d(), !0;
704
- }, validate: (s) => a.parse(s), getSchema: () => a, version: E };
703
+ return u(), !0;
704
+ }, validate: (d) => a.parse(d), getSchema: () => a, version: E, isGeneric: (d) => [
705
+ "constants1.schema.json",
706
+ "constants2.schema.json",
707
+ "resourceitem1.schema.json",
708
+ "subdevice1.schema.json"
709
+ ].includes(d) };
705
710
  }
706
711
  export {
707
712
  P as createValidator
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deconz-community/ddf-validator",
3
- "version": "2.15.0",
3
+ "version": "2.16.0",
4
4
  "description": "Validating DDF files for deconz",
5
5
  "keywords": [
6
6
  "deconz",