@deconz-community/ddf-validator 2.13.0 → 2.14.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.13.0",g={"devcap1.schema.json":[E,O,_,$,w],"constants2.schema.json":[T]};function E(t,r,c){const n=typeof t.manufacturername=="string"&&typeof t.modelid=="string";if(n)return;const d=Array.isArray(t.manufacturername)&&Array.isArray(t.modelid);if(d&&t.manufacturername.length!==t.modelid.length){r.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||d)===!1&&r.addIssue({code:e.z.ZodIssueCode.invalid_intersection_types,message:"Invalid properties 'manufacturername' and 'modelid' should have the same type",path:["manufacturername","modelid"]})}function O(t,r,c){if(!t.bindings)return;const n=o=>`0x${(typeof o=="number"?o:Number.parseInt(o,16)).toString(16)}`,d={};t.bindings.forEach(o=>{o.bind==="unicast"&&o.report&&o.report.forEach(s=>{s.max!==65535&&(d[`${n(o["src.ep"])}.${n(o.cl)}.${n(s.at)}`]=s.max)})}),t.subdevices.forEach((o,s)=>{o.items.forEach((i,u)=>{var p;if(i["refresh.interval"]&&i.read&&i.read.fn==="zcl"){const z=n(i.read.ep??((p=o.fingerprint)==null?void 0:p.endpoint)??o.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])}`;d[v]!==void 0&&i["refresh.interval"]-60<d[v]&&r.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 (${d[v]}) with a margin of 60 seconds`,path:["subdevices",s,"items",u,"refresh.interval"]})}}})})}function _(t,r,c){if(!t.bindings)return;const n=[{description:'a color light should always have "state/ct" item.',if:{type:["$TYPE_COLOR_TEMPERATURE_LIGHT","Color Temperature Light","$TYPE_EXTENDED_COLOR_LIGHT","Extended Color Light"]},need:{item:["state/ct"]}},{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 "state/x" or "state/y" need the corresponding red, green and blue x and y values.',if:{item:["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 ZHAOpenClose should always have "state/open" item.',if:{type:["$TYPE_OPEN_CLOSE_SENSOR","ZHAOpenClose"]},need:{item:["state/open"]}}];t.subdevices.forEach((d,o)=>{const s=d.items.map(i=>i.name);n.forEach(i=>{(Object.keys(i.if).length===0||Object.keys(i.if).some(u=>{var p;switch(u){case"type":return(p=i.if[u])==null?void 0:p.includes(d.type);case"item":return s.some(z=>{var b;return(b=i.if[u])==null?void 0:b.includes(z)});default:return!1}}))&&i.need.item.forEach(u=>{s.includes(u)||r.addIssue({code:e.z.ZodIssueCode.custom,message:`The device should have the item "${u}" because ${i.description}`,path:["subdevices",o,"items"]})})})})}function $(t,r,c){const n=["parse","write"];t.subdevices.forEach((d,o)=>{d.items.forEach((s,i)=>{n.forEach(u=>{const p=s[u];p!==void 0&&(p.fn===void 0||p.fn==="zcl"||p.fn==="zcl:attr"||p.fn==="zcl:cmd")&&(p.eval===void 0&&p.script===void 0&&r.addIssue({code:e.z.ZodIssueCode.custom,message:`The '${u}' function is missing 'eval' or 'script' option.`,path:["subdevices",o,"items",i,u]}),p.eval!==void 0&&p.script!==void 0&&r.addIssue({code:e.z.ZodIssueCode.custom,message:`The '${u}' function is having both 'eval' and 'script' option.`,path:["subdevices",o,"items",i,u]}))})})})}function T(t,r,c){const n=I();Object.keys(t).forEach(d=>{if(!Object.keys(n.shape).includes(d)){if(!["$MF_","$TYPE_"].some(o=>d.startsWith(o))){r.addIssue({code:e.z.ZodIssueCode.custom,message:"The constant key should start with '$MF_' or '$TYPE_'",path:[d]});return}typeof t[d]!="string"&&r.addIssue({code:e.z.ZodIssueCode.custom,message:"The constant value should be a string",path:[d]})}})}function w(t,r,c){t.bindings&&t.subdevices.forEach((n,d)=>{const o=c.subDevices[n.type];if(!o){r.addIssue({code:e.z.ZodIssueCode.custom,message:`The device is missing the device definition for the type "${n.type}"`,path:["subdevices",d,"items"]});return}let s=o.items;o.items_optional&&(s=s.filter(i=>!o.items_optional.includes(i))),s.forEach(i=>{n.items.find(u=>u.name===i)||r.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",d,"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 I(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 a(t=void 0){const r="Invalid hexadecimal value";return t===void 0?e.z.string().regex(/^0x[0-9a-fA-F]+$/,r):e.z.string().regex(new RegExp(`^0x[0-9a-fA-F]{${t}}$`),r)}function l(){return e.z.union([a(2),e.z.number().min(0).max(255)])}function S(){return e.z.custom(t=>{if(!Array.isArray(t)||t.length%2!==0)return!1;for(let r=0;r<t.length;r+=2){const c=t[r],n=t[r+1];if(typeof c!="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 x(){return e.z.union([e.z.tuple([e.z.literal("$address.ext"),a(2)]),e.z.tuple([e.z.literal("$address.ext"),a(2),a(4)])])}function f(){return e.z.string()}function m(){return e.z.string()}function M(){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:a(4).or(e.z.array(a(4))).describe("Attribute ID."),cl:a(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(a(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),eval:e.z.optional(m()).describe("Javascript expression to transform the raw value.")}),e.z.strictObject({fn:e.z.literal("zcl").describe("Generic function to read ZCL attributes."),at:a(4).or(e.z.array(a(4))).describe("Attribute ID."),cl:a(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(a(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),eval:e.z.optional(m()).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:a(4).or(e.z.array(a(4))).describe("String hex value or array of string hex values."),cl:a(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(a(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),eval:e.z.optional(m()).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:a(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(a(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),cmd:e.z.optional(a(2)).describe("Zigbee command."),eval:e.z.optional(m()).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 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(a(4).or(e.z.array(a(4)))).describe("Attribute ID."),cl:a(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(a(2)).describe("Zigbee command."),mf:e.z.optional(a(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),eval:e.z.optional(m()).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(a(4).or(e.z.array(a(4)))).describe("Attribute ID."),cl:a(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(a(2)).describe("Zigbee command."),mf:e.z.optional(a(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),eval:e.z.optional(m()).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:a(4).or(e.z.array(a(4))).describe("String hex value or array of string hex values."),cl:a(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(a(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),eval:e.z.optional(m()).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:a(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(a(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),cmd:e.z.optional(a(2)).describe("Zigbee command."),eval:e.z.optional(m()).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:S().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(a(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),at:e.z.optional(a(4)).describe("Attribute ID. The attribute to parse, shall be 0xff01, 0xff02 or 0x00f7"),idx:a(2).describe("A 8-bit string hex value."),eval:e.z.optional(m()).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(m()).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(a(4).or(e.z.array(a(4)))).describe("Attribute ID."),"state.timeout":e.z.optional(e.z.number()),"change.timeout":e.z.optional(e.z.number()),cl:a(4).describe("Cluster ID."),dt:a(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(a(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),eval:e.z.optional(m()).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(a(4).or(e.z.array(a(4)))).describe("Attribute ID."),"state.timeout":e.z.optional(e.z.number()),"change.timeout":e.z.optional(e.z.number()),cl:a(4).describe("Cluster ID."),dt:a(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(a(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),eval:e.z.optional(m()).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:a(4).or(e.z.array(a(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:a(4).describe("Cluster ID."),dt:a(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(a(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),eval:e.z.optional(m()).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:a(4).describe("Cluster ID."),dt:a(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(a(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),cmd:e.z.optional(a(2)).describe("Zigbee command."),eval:e.z.optional(m()).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:a(2).describe("Data type."),eval:e.z.optional(m()).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(M()).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(m()).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:(r,c)=>r.code==="invalid_enum_value"?{message:`Invalid enum value. Expected type from generic attributes definition, received '${r.received}'`}:{message:c.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:x(),fingerprint:e.z.optional(e.z.strictObject({profile:a(4),device:a(4),endpoint:l(),in:e.z.optional(e.z.array(a(4))),out:e.z.optional(e.z.array(a(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:(r,c)=>r.code==="invalid_enum_value"?{message:`Invalid enum value. Expected item from generic attributes definition, received '${r.received}'`}:{message:c.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:a(4).describe("Cluster."),report:e.z.optional(e.z.array(e.z.strictObject({at:a(4),dt:a(2),mf:e.z.optional(a(4)),min:e.z.number(),max:e.z.number(),change:e.z.optional(a().or(e.z.number()))}).refine(r=>r.min<=r.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:a(4).describe("Cluster."),"config.group":e.z.number().min(0).max(255)})])}function L(t){const r=e.z.array(e.z.enum(t.attributes,{errorMap:(c,n)=>c.code==="invalid_enum_value"?{message:`Invalid enum value. Expected item from generic attributes definition, received '${c.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:(c,n)=>c.code==="invalid_enum_value"?{message:`Invalid enum value. Expected type from generic attributes definition, received '${c.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:x(),items:r,items_optional:e.z.optional(r)})}function y(t){return e.z.discriminatedUnion("schema",[R(t),C(),I(),j(),L(t)]).superRefine((r,c)=>{switch(r.schema){case"devcap1.schema.json":g[r.schema].map(n=>n(r,c,t));break;case"constants2.schema.json":g[r.schema].map(n=>n(r,c,t));break}})}function P(t={attributes:[],manufacturers:{},deviceTypes:{},resources:{},subDevices:{}}){let r=y(t);const c=()=>{r=y(t)};return{generics:t,loadGeneric:o=>{const s=r.parse(o);switch(s.schema){case"constants1.schema.json":t.manufacturers={...t.manufacturers,...s.manufacturers},t.deviceTypes={...t.deviceTypes,...s["device-types"]};break;case"constants2.schema.json":{Object.keys(s).filter(i=>i.startsWith("$MF_")).forEach(i=>{t.manufacturers[i]=s[i]}),Object.keys(s).filter(i=>i.startsWith("$TYPE_")).forEach(i=>{t.deviceTypes[i]=s[i]});break}case"resourceitem1.schema.json":{if(t.attributes.includes(s.id))throw new Error(`Got duplicate resource item with attribute id '${s.id}'.`);const i=s,u=s.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[s.type]=s,t.subDevices[s.name]=s;break;case"devcap1.schema.json":throw new Error("Got invalid generic file, got data with schema 'devcap1.schema.json'.")}return c(),!0},validate:o=>r.parse(o),getSchema:()=>r,version:D}}exports.createValidator=P;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("zod"),D="2.14.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."),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."),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."),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,64 +1,62 @@
1
1
  import { z as e } from "zod";
2
- const E = "2.13.0", y = {
2
+ const E = "2.14.0", y = {
3
3
  "devcap1.schema.json": [
4
4
  O,
5
5
  _,
6
6
  $,
7
- T,
7
+ w,
8
8
  C
9
9
  ],
10
10
  "constants2.schema.json": [
11
- w
11
+ T
12
12
  ]
13
13
  };
14
- function O(t, r, c) {
15
- const n = typeof t.manufacturername == "string" && typeof t.modelid == "string";
16
- if (n)
14
+ function O(t, a, d) {
15
+ const o = typeof t.manufacturername == "string" && typeof t.modelid == "string";
16
+ if (o)
17
17
  return;
18
- const d = Array.isArray(t.manufacturername) && Array.isArray(t.modelid);
19
- if (d && t.manufacturername.length !== t.modelid.length) {
20
- r.addIssue({
18
+ const c = Array.isArray(t.manufacturername) && Array.isArray(t.modelid);
19
+ if (c && t.manufacturername.length !== t.modelid.length) {
20
+ a.addIssue({
21
21
  code: e.ZodIssueCode.invalid_intersection_types,
22
22
  message: "When 'manufacturername' and 'modelid' are both arrays they should be the same length",
23
23
  path: ["manufacturername", "modelid"]
24
24
  });
25
25
  return;
26
26
  }
27
- (n || d) === !1 && r.addIssue({
27
+ (o || 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, r, c) {
33
+ function _(t, a, d) {
34
34
  if (!t.bindings)
35
35
  return;
36
- const n = (o) => `0x${(typeof o == "number" ? o : Number.parseInt(o, 16)).toString(16)}`, d = {};
37
- t.bindings.forEach((o) => {
38
- o.bind === "unicast" && o.report && o.report.forEach((s) => {
39
- s.max !== 65535 && (d[`${n(o["src.ep"])}.${n(o.cl)}.${n(s.at)}`] = s.max);
36
+ const o = (s) => `0x${(typeof s == "number" ? s : Number.parseInt(s, 16)).toString(16)}`, c = {};
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);
40
40
  });
41
- }), t.subdevices.forEach((o, s) => {
42
- o.items.forEach((i, u) => {
43
- var p;
41
+ }), t.subdevices.forEach((s, n) => {
42
+ s.items.forEach((i, u) => {
43
+ var m;
44
44
  if (i["refresh.interval"] && i.read && i.read.fn === "zcl") {
45
- const h = n(i.read.ep ?? ((p = o.fingerprint) == null ? void 0 : p.endpoint) ?? o.uuid[1]), b = Array.isArray(i.read.at) ? i.read.at : [i.read.at];
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];
46
46
  for (let v = 0; v < b.length; v++) {
47
- const g = `${h}.${n(i.read.cl)}.${n(b[v])}`;
48
- d[g] !== void 0 && i["refresh.interval"] - 60 < d[g] && r.addIssue({
47
+ const g = `${h}.${o(i.read.cl)}.${o(b[v])}`;
48
+ c[g] !== void 0 && i["refresh.interval"] - 60 < c[g] && a.addIssue({
49
49
  code: e.ZodIssueCode.custom,
50
- message: `The refresh interval (${i["refresh.interval"]} - 60 = ${i["refresh.interval"] - 60}) should be greater than the binding max refresh value (${d[g]}) with a margin of 60 seconds`,
51
- path: ["subdevices", s, "items", u, "refresh.interval"]
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"]
52
52
  });
53
53
  }
54
54
  }
55
55
  });
56
56
  });
57
57
  }
58
- function $(t, r, c) {
59
- if (!t.bindings)
60
- return;
61
- const n = [
58
+ function $(t, a, d) {
59
+ const o = [
62
60
  /*
63
61
  {
64
62
  description: 'a device should always have basic attributes.',
@@ -73,42 +71,40 @@ function $(t, r, c) {
73
71
  },
74
72
  */
75
73
  {
76
- description: 'a color light should always have "state/ct" item.',
74
+ description: 'a device with "state/ct" need the "min" and "max" values for capability.',
77
75
  if: {
78
- type: [
79
- // TODO Use the constants file to resolve the types too
80
- "$TYPE_COLOR_TEMPERATURE_LIGHT",
81
- "Color Temperature Light",
82
- "$TYPE_EXTENDED_COLOR_LIGHT",
83
- "Extended Color Light"
84
- ]
76
+ item: "state/ct"
85
77
  },
86
78
  need: {
87
79
  item: [
88
- "state/ct"
80
+ "cap/color/ct/min",
81
+ "cap/color/ct/max"
82
+ // 'config/color/ct/startup',
89
83
  ]
90
84
  }
91
85
  },
92
86
  {
93
- description: 'a device with "state/ct" need the "min" and "max" values for capability.',
87
+ description: 'a device with "cap/color/ct/computes_xy" need the corresponding state/{x,y} items',
94
88
  if: {
95
- item: ["state/ct"]
89
+ item: "cap/color/ct/computes_xy"
96
90
  },
97
91
  need: {
98
92
  item: [
99
- "cap/color/ct/min",
100
- "cap/color/ct/max"
101
- // 'config/color/ct/startup',
93
+ "state/x",
94
+ "state/y",
95
+ "state/ct"
102
96
  ]
103
97
  }
104
98
  },
105
99
  {
106
- description: 'a device with "state/x" or "state/y" need the corresponding red, green and blue x and y values.',
100
+ description: 'a device with "state/x" or "state/y" need the corresponding cap/color/xy/{red,green,blue}/{x,y} items',
107
101
  if: {
108
- item: [
109
- "state/x",
110
- "state/y"
111
- ]
102
+ item: {
103
+ or: [
104
+ "state/x",
105
+ "state/y"
106
+ ]
107
+ }
112
108
  },
113
109
  need: {
114
110
  item: [
@@ -120,107 +116,113 @@ function $(t, r, c) {
120
116
  "cap/color/xy/red_y",
121
117
  "cap/color/xy/green_y",
122
118
  "cap/color/xy/blue_y"
123
- // 'cap/color/ct/computes_xy',
124
119
  ]
125
120
  }
126
121
  },
127
122
  {
128
- description: 'a ZHAOpenClose should always have "state/open" item.',
123
+ description: 'a "(Extended) Color light" need ("state/x" and "state/y") or/and ("state/hue" and "state/sat") .',
129
124
  if: {
130
- type: [
131
- "$TYPE_OPEN_CLOSE_SENSOR",
132
- "ZHAOpenClose"
133
- ]
125
+ type: {
126
+ or: [
127
+ "$TYPE_EXTENDED_COLOR_LIGHT",
128
+ "Extended color light",
129
+ "$TYPE_COLOR_LIGHT",
130
+ "Color light"
131
+ ]
132
+ }
134
133
  },
135
134
  need: {
136
- item: [
137
- "state/open"
138
- ]
135
+ item: {
136
+ or: [
137
+ [
138
+ "state/x",
139
+ "state/y"
140
+ ],
141
+ [
142
+ "state/hue",
143
+ "state/sat"
144
+ ]
145
+ ]
146
+ }
139
147
  }
140
148
  }
141
- ];
142
- t.subdevices.forEach((d, o) => {
143
- const s = d.items.map((i) => i.name);
144
- n.forEach((i) => {
145
- (Object.keys(i.if).length === 0 || Object.keys(i.if).some((u) => {
146
- var p;
147
- switch (u) {
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) {
148
155
  case "type":
149
- return (p = i.if[u]) == null ? void 0 : p.includes(d.type);
156
+ return c(h, (b) => b === s.type);
150
157
  case "item":
151
- return s.some((h) => {
152
- var b;
153
- return (b = i.if[u]) == null ? void 0 : b.includes(h);
154
- });
158
+ return c(h, (b) => i.includes(b));
155
159
  default:
156
160
  return !1;
157
161
  }
158
- })) && i.need.item.forEach((u) => {
159
- s.includes(u) || r.addIssue({
160
- code: e.ZodIssueCode.custom,
161
- message: `The device should have the item "${u}" because ${i.description}`,
162
- path: ["subdevices", o, "items"]
163
- });
164
- });
162
+ })) && (c(u.need.item, (m) => i.includes(m)) || a.addIssue({
163
+ code: e.ZodIssueCode.custom,
164
+ message: `The device is missing some items because ${u.description}`,
165
+ path: ["subdevices", n, "items"]
166
+ }));
165
167
  });
166
168
  });
167
169
  }
168
- function T(t, r, c) {
169
- const n = ["parse", "write"];
170
- t.subdevices.forEach((d, o) => {
171
- d.items.forEach((s, i) => {
172
- n.forEach((u) => {
173
- const p = s[u];
174
- p !== void 0 && (p.fn === void 0 || p.fn === "zcl" || p.fn === "zcl:attr" || p.fn === "zcl:cmd") && (p.eval === void 0 && p.script === void 0 && r.addIssue({
170
+ function w(t, a, d) {
171
+ const o = ["parse", "write"];
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({
175
177
  code: e.ZodIssueCode.custom,
176
178
  message: `The '${u}' function is missing 'eval' or 'script' option.`,
177
- path: ["subdevices", o, "items", i, u]
178
- }), p.eval !== void 0 && p.script !== void 0 && r.addIssue({
179
+ path: ["subdevices", s, "items", i, u]
180
+ }), m.eval !== void 0 && m.script !== void 0 && a.addIssue({
179
181
  code: e.ZodIssueCode.custom,
180
182
  message: `The '${u}' function is having both 'eval' and 'script' option.`,
181
- path: ["subdevices", o, "items", i, u]
183
+ path: ["subdevices", s, "items", i, u]
182
184
  }));
183
185
  });
184
186
  });
185
187
  });
186
188
  }
187
- function w(t, r, c) {
188
- const n = I();
189
- Object.keys(t).forEach((d) => {
190
- if (!Object.keys(n.shape).includes(d)) {
191
- if (!["$MF_", "$TYPE_"].some((o) => d.startsWith(o))) {
192
- r.addIssue({
189
+ function T(t, a, d) {
190
+ const o = I();
191
+ Object.keys(t).forEach((c) => {
192
+ if (!Object.keys(o.shape).includes(c)) {
193
+ if (!["$MF_", "$TYPE_"].some((s) => c.startsWith(s))) {
194
+ a.addIssue({
193
195
  code: e.ZodIssueCode.custom,
194
196
  message: "The constant key should start with '$MF_' or '$TYPE_'",
195
- path: [d]
197
+ path: [c]
196
198
  });
197
199
  return;
198
200
  }
199
- typeof t[d] != "string" && r.addIssue({
201
+ typeof t[c] != "string" && a.addIssue({
200
202
  code: e.ZodIssueCode.custom,
201
203
  message: "The constant value should be a string",
202
- path: [d]
204
+ path: [c]
203
205
  });
204
206
  }
205
207
  });
206
208
  }
207
- function C(t, r, c) {
208
- t.bindings && t.subdevices.forEach((n, d) => {
209
- const o = c.subDevices[n.type];
210
- if (!o) {
211
- r.addIssue({
209
+ function C(t, a, d) {
210
+ t.subdevices.forEach((o, c) => {
211
+ const s = d.subDevices[o.type];
212
+ if (!s) {
213
+ a.addIssue({
212
214
  code: e.ZodIssueCode.custom,
213
- message: `The device is missing the device definition for the type "${n.type}"`,
214
- path: ["subdevices", d, "items"]
215
+ message: `The device is missing the device definition for the type "${o.type}"`,
216
+ path: ["subdevices", c, "items"]
215
217
  });
216
218
  return;
217
219
  }
218
- let s = o.items;
219
- o.items_optional && (s = s.filter((i) => !o.items_optional.includes(i))), s.forEach((i) => {
220
- n.items.find((u) => u.name === i) || r.addIssue({
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({
221
223
  code: e.ZodIssueCode.custom,
222
- message: `The device should have the item "${i}" because it is mandatory for devices of type "${n.type}"`,
223
- path: ["subdevices", d, "items"]
224
+ message: `The device should have the item "${i}" because it is mandatory for devices of type "${o.type}"`,
225
+ path: ["subdevices", c, "items"]
224
226
  });
225
227
  });
226
228
  });
@@ -246,13 +248,13 @@ function M() {
246
248
  "Invalid date value"
247
249
  );
248
250
  }
249
- function a(t = void 0) {
250
- const r = "Invalid hexadecimal value";
251
- return t === void 0 ? e.string().regex(/^0x[0-9a-fA-F]+$/, r) : e.string().regex(new RegExp(`^0x[0-9a-fA-F]{${t}}$`), r);
251
+ function r(t = void 0) {
252
+ const a = "Invalid hexadecimal value";
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);
252
254
  }
253
255
  function l() {
254
256
  return e.union([
255
- a(2),
257
+ r(2),
256
258
  e.number().min(0).max(255)
257
259
  ]);
258
260
  }
@@ -260,9 +262,9 @@ function S() {
260
262
  return e.custom((t) => {
261
263
  if (!Array.isArray(t) || t.length % 2 !== 0)
262
264
  return !1;
263
- for (let r = 0; r < t.length; r += 2) {
264
- const c = t[r], n = t[r + 1];
265
- if (typeof c != "number" || typeof n != "string")
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
268
  return !1;
267
269
  }
268
270
  return !0;
@@ -272,19 +274,19 @@ function j() {
272
274
  return e.union([
273
275
  e.tuple([
274
276
  e.literal("$address.ext"),
275
- a(2)
277
+ r(2)
276
278
  ]),
277
279
  e.tuple([
278
280
  e.literal("$address.ext"),
279
- a(2),
280
- a(4)
281
+ r(2),
282
+ r(4)
281
283
  ])
282
284
  ]);
283
285
  }
284
286
  function f() {
285
287
  return e.string();
286
288
  }
287
- function m() {
289
+ function p() {
288
290
  return e.string();
289
291
  }
290
292
  function J() {
@@ -294,37 +296,37 @@ function J() {
294
296
  }),
295
297
  e.strictObject({
296
298
  fn: e.undefined().describe("Generic function to read ZCL attributes."),
297
- at: a(4).or(e.array(a(4))).describe("Attribute ID."),
298
- cl: a(4).describe("Cluster ID."),
299
+ at: r(4).or(e.array(r(4))).describe("Attribute ID."),
300
+ cl: r(4).describe("Cluster ID."),
299
301
  ep: e.optional(l()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),
300
- mf: e.optional(a(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),
301
- eval: e.optional(m()).describe("Javascript expression to transform the raw value.")
302
+ mf: e.optional(r(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),
303
+ eval: e.optional(p()).describe("Javascript expression to transform the raw value.")
302
304
  }),
303
305
  e.strictObject({
304
306
  fn: e.literal("zcl").describe("Generic function to read ZCL attributes."),
305
- at: a(4).or(e.array(a(4))).describe("Attribute ID."),
306
- cl: a(4).describe("Cluster ID."),
307
+ at: r(4).or(e.array(r(4))).describe("Attribute ID."),
308
+ cl: r(4).describe("Cluster ID."),
307
309
  ep: e.optional(l()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),
308
- mf: e.optional(a(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),
309
- eval: e.optional(m()).describe("Javascript expression to transform the raw value."),
310
+ mf: e.optional(r(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),
311
+ eval: e.optional(p()).describe("Javascript expression to transform the raw value."),
310
312
  script: e.optional(f()).describe("Relative path of a Javascript .js file.")
311
313
  }).describe("Deprecated"),
312
314
  e.strictObject({
313
315
  fn: e.literal("zcl:attr").describe("Generic function to parse ZCL values from read/report commands."),
314
- at: a(4).or(e.array(a(4))).describe("String hex value or array of string hex values."),
315
- cl: a(4).describe("Cluster ID."),
316
+ at: r(4).or(e.array(r(4))).describe("String hex value or array of string hex values."),
317
+ cl: r(4).describe("Cluster ID."),
316
318
  ep: e.optional(l()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),
317
- mf: e.optional(a(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),
318
- eval: e.optional(m()).describe("Javascript expression to transform the attribute value to the Item value."),
319
+ mf: e.optional(r(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),
320
+ eval: e.optional(p()).describe("Javascript expression to transform the attribute value to the Item value."),
319
321
  script: e.optional(f()).describe("Relative path of a Javascript .js file.")
320
322
  }),
321
323
  e.strictObject({
322
324
  fn: e.literal("zcl:cmd").describe("Generic function to parse ZCL values from read/report commands."),
323
- cl: a(4).describe("Cluster ID."),
325
+ cl: r(4).describe("Cluster ID."),
324
326
  ep: e.optional(l()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),
325
- mf: e.optional(a(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),
326
- cmd: e.optional(a(2)).describe("Zigbee command."),
327
- eval: e.optional(m()).describe("Javascript expression to transform the attribute value to the Item value."),
327
+ mf: e.optional(r(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),
328
+ cmd: e.optional(r(2)).describe("Zigbee command."),
329
+ eval: e.optional(p()).describe("Javascript expression to transform the attribute value to the Item value."),
328
330
  script: e.optional(f()).describe("Relative path of a Javascript .js file.")
329
331
  }),
330
332
  e.strictObject({
@@ -338,42 +340,42 @@ function Z() {
338
340
  return e.discriminatedUnion("fn", [
339
341
  e.strictObject({
340
342
  fn: e.undefined().describe("Generic function to parse ZCL attributes and commands."),
341
- at: e.optional(a(4).or(e.array(a(4)))).describe("Attribute ID."),
342
- cl: a(4).describe("Cluster ID."),
343
+ at: e.optional(r(4).or(e.array(r(4)))).describe("Attribute ID."),
344
+ cl: r(4).describe("Cluster ID."),
343
345
  cppsrc: e.optional(e.string()),
344
346
  ep: e.optional(l()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),
345
- cmd: e.optional(a(2)).describe("Zigbee command."),
346
- mf: e.optional(a(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),
347
- eval: e.optional(m()).describe("Javascript expression to transform the raw value."),
347
+ cmd: e.optional(r(2)).describe("Zigbee command."),
348
+ mf: e.optional(r(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),
349
+ eval: e.optional(p()).describe("Javascript expression to transform the raw value."),
348
350
  script: e.optional(f()).describe("Relative path of a Javascript .js file.")
349
351
  }),
350
352
  e.strictObject({
351
353
  fn: e.literal("zcl").describe("Generic function to parse ZCL attributes and commands."),
352
- at: e.optional(a(4).or(e.array(a(4)))).describe("Attribute ID."),
353
- cl: a(4).describe("Cluster ID."),
354
+ at: e.optional(r(4).or(e.array(r(4)))).describe("Attribute ID."),
355
+ cl: r(4).describe("Cluster ID."),
354
356
  cppsrc: e.optional(e.string()),
355
357
  ep: e.optional(l()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),
356
- cmd: e.optional(a(2)).describe("Zigbee command."),
357
- mf: e.optional(a(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),
358
- eval: e.optional(m()).describe("Javascript expression to transform the raw value."),
358
+ cmd: e.optional(r(2)).describe("Zigbee command."),
359
+ mf: e.optional(r(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),
360
+ eval: e.optional(p()).describe("Javascript expression to transform the raw value."),
359
361
  script: e.optional(f()).describe("Relative path of a Javascript .js file.")
360
362
  }).describe("Deprecated"),
361
363
  e.strictObject({
362
364
  fn: e.literal("zcl:attr").describe("Generic function to parse ZCL values from read/report commands."),
363
- at: a(4).or(e.array(a(4))).describe("String hex value or array of string hex values."),
364
- cl: a(4).describe("Cluster ID."),
365
+ at: r(4).or(e.array(r(4))).describe("String hex value or array of string hex values."),
366
+ cl: r(4).describe("Cluster ID."),
365
367
  ep: e.optional(l()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),
366
- mf: e.optional(a(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),
367
- eval: e.optional(m()).describe("Javascript expression to transform the attribute value to the Item value."),
368
+ mf: e.optional(r(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),
369
+ eval: e.optional(p()).describe("Javascript expression to transform the attribute value to the Item value."),
368
370
  script: e.optional(f()).describe("Relative path of a Javascript .js file.")
369
371
  }),
370
372
  e.strictObject({
371
373
  fn: e.literal("zcl:cmd").describe("Generic function to parse ZCL values from read/report commands."),
372
- cl: a(4).describe("Cluster ID."),
374
+ cl: r(4).describe("Cluster ID."),
373
375
  ep: e.optional(l()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),
374
- mf: e.optional(a(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),
375
- cmd: e.optional(a(2)).describe("Zigbee command."),
376
- eval: e.optional(m()).describe("Javascript expression to transform the attribute value to the Item value."),
376
+ mf: e.optional(r(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),
377
+ cmd: e.optional(r(2)).describe("Zigbee command."),
378
+ eval: e.optional(p()).describe("Javascript expression to transform the attribute value to the Item value."),
377
379
  script: e.optional(f()).describe("Relative path of a Javascript .js file.")
378
380
  }),
379
381
  e.strictObject({
@@ -393,16 +395,16 @@ function Z() {
393
395
  e.strictObject({
394
396
  fn: e.literal("xiaomi:special").describe("Generic function to parse custom Xiaomi attributes and commands."),
395
397
  ep: e.optional(l()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),
396
- mf: e.optional(a(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),
397
- at: e.optional(a(4)).describe("Attribute ID. The attribute to parse, shall be 0xff01, 0xff02 or 0x00f7"),
398
- idx: a(2).describe("A 8-bit string hex value."),
399
- eval: e.optional(m()).describe("Javascript expression to transform the raw value."),
398
+ mf: e.optional(r(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),
399
+ at: e.optional(r(4)).describe("Attribute ID. The attribute to parse, shall be 0xff01, 0xff02 or 0x00f7"),
400
+ idx: r(2).describe("A 8-bit string hex value."),
401
+ eval: e.optional(p()).describe("Javascript expression to transform the raw value."),
400
402
  script: e.optional(f()).describe("Relative path of a Javascript .js file.")
401
403
  }),
402
404
  e.strictObject({
403
405
  fn: e.literal("tuya").describe("Generic function to parse Tuya data."),
404
406
  dpid: e.number().describe("Data point ID. 1-255 the datapoint ID."),
405
- eval: e.optional(m()).describe("Javascript expression to transform the raw value."),
407
+ eval: e.optional(p()).describe("Javascript expression to transform the raw value."),
406
408
  script: e.optional(f()).describe("Relative path of a Javascript .js file.")
407
409
  })
408
410
  ]).refine((t) => !("eval" in t && "script" in t), {
@@ -416,55 +418,55 @@ function R() {
416
418
  }),
417
419
  e.strictObject({
418
420
  fn: e.undefined(),
419
- at: e.optional(a(4).or(e.array(a(4)))).describe("Attribute ID."),
421
+ at: e.optional(r(4).or(e.array(r(4)))).describe("Attribute ID."),
420
422
  "state.timeout": e.optional(e.number()),
421
423
  "change.timeout": e.optional(e.number()),
422
- cl: a(4).describe("Cluster ID."),
423
- dt: a(2).describe("Data type."),
424
+ cl: r(4).describe("Cluster ID."),
425
+ dt: r(2).describe("Data type."),
424
426
  ep: e.optional(l()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),
425
- mf: e.optional(a(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),
426
- eval: e.optional(m()).describe("Javascript expression to transform the raw value."),
427
+ mf: e.optional(r(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),
428
+ eval: e.optional(p()).describe("Javascript expression to transform the raw value."),
427
429
  script: e.optional(f()).describe("Relative path of a Javascript .js file.")
428
430
  }),
429
431
  e.strictObject({
430
432
  fn: e.literal("zcl"),
431
- at: e.optional(a(4).or(e.array(a(4)))).describe("Attribute ID."),
433
+ at: e.optional(r(4).or(e.array(r(4)))).describe("Attribute ID."),
432
434
  "state.timeout": e.optional(e.number()),
433
435
  "change.timeout": e.optional(e.number()),
434
- cl: a(4).describe("Cluster ID."),
435
- dt: a(2).describe("Data type."),
436
+ cl: r(4).describe("Cluster ID."),
437
+ dt: r(2).describe("Data type."),
436
438
  ep: e.optional(l()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),
437
- mf: e.optional(a(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),
438
- eval: e.optional(m()).describe("Javascript expression to transform the raw value."),
439
+ mf: e.optional(r(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),
440
+ eval: e.optional(p()).describe("Javascript expression to transform the raw value."),
439
441
  script: e.optional(f()).describe("Relative path of a Javascript .js file.")
440
442
  }).describe("Deprecated"),
441
443
  e.strictObject({
442
444
  fn: e.literal("zcl:attr").describe("Generic function to parse ZCL values from read/report commands."),
443
- at: a(4).or(e.array(a(4))).describe("String hex value or array of string hex values."),
445
+ at: r(4).or(e.array(r(4))).describe("String hex value or array of string hex values."),
444
446
  "state.timeout": e.optional(e.number()),
445
447
  "change.timeout": e.optional(e.number()),
446
- cl: a(4).describe("Cluster ID."),
447
- dt: a(2).describe("Data type."),
448
+ cl: r(4).describe("Cluster ID."),
449
+ dt: r(2).describe("Data type."),
448
450
  ep: e.optional(l()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),
449
- mf: e.optional(a(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),
450
- eval: e.optional(m()).describe("Javascript expression to transform the attribute value to the Item value."),
451
+ mf: e.optional(r(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),
452
+ eval: e.optional(p()).describe("Javascript expression to transform the attribute value to the Item value."),
451
453
  script: e.optional(f()).describe("Relative path of a Javascript .js file.")
452
454
  }),
453
455
  e.strictObject({
454
456
  fn: e.literal("zcl:cmd").describe("Generic function to parse ZCL values from read/report commands."),
455
- cl: a(4).describe("Cluster ID."),
456
- dt: a(2).describe("Data type."),
457
+ cl: r(4).describe("Cluster ID."),
458
+ dt: r(2).describe("Data type."),
457
459
  ep: e.optional(l()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),
458
- mf: e.optional(a(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),
459
- cmd: e.optional(a(2)).describe("Zigbee command."),
460
- eval: e.optional(m()).describe("Javascript expression to transform the attribute value to the Item value."),
460
+ mf: e.optional(r(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),
461
+ cmd: e.optional(r(2)).describe("Zigbee command."),
462
+ eval: e.optional(p()).describe("Javascript expression to transform the attribute value to the Item value."),
461
463
  script: e.optional(f()).describe("Relative path of a Javascript .js file.")
462
464
  }),
463
465
  e.strictObject({
464
466
  fn: e.literal("tuya").describe("Generic function to write Tuya data."),
465
467
  dpid: e.number().describe("Data point ID. 1-255 the datapoint ID."),
466
- dt: a(2).describe("Data type."),
467
- eval: e.optional(m()).describe("Javascript expression to transform the raw value."),
468
+ dt: r(2).describe("Data type."),
469
+ eval: e.optional(p()).describe("Javascript expression to transform the raw value."),
468
470
  script: e.optional(f()).describe("Relative path of a Javascript .js file.")
469
471
  })
470
472
  ]).refine((t) => !("eval" in t && "script" in t), {
@@ -536,32 +538,32 @@ function G(t) {
536
538
  modelid: e.string().or(e.array(e.string())).describe("Model ID from Basic Cluster."),
537
539
  vendor: e.optional(e.string()).describe("Friendly name of the manufacturer."),
538
540
  comment: e.optional(e.string()),
539
- matchexpr: e.optional(m()).describe("Need to return true for the DDF be used."),
541
+ matchexpr: e.optional(p()).describe("Need to return true for the DDF be used."),
540
542
  path: e.optional(f()).describe("DDF path, useless, can be removed."),
541
543
  product: e.optional(e.string()).describe("Complements the model id to be shown in the UI."),
542
544
  sleeper: e.optional(e.boolean()).describe("Sleeping devices can only receive when awake."),
543
545
  supportsMgmtBind: e.optional(e.boolean()),
544
546
  status: e.enum(["Draft", "Bronze", "Silver", "Gold"]).describe("The code quality of the DDF file."),
545
547
  subdevices: e.array(F(t)).describe("Devices section."),
546
- bindings: e.optional(e.array(z())).describe("Bindings section.")
548
+ bindings: e.optional(e.array(k())).describe("Bindings section.")
547
549
  });
548
550
  }
549
551
  function F(t) {
550
552
  return e.strictObject({
551
553
  type: e.union([
552
554
  e.enum(Object.keys(t.deviceTypes), {
553
- errorMap: (r, c) => r.code === "invalid_enum_value" ? { message: `Invalid enum value. Expected type from generic attributes definition, received '${r.received}'` } : { message: c.defaultError }
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 }
554
556
  }),
555
557
  e.string().regex(/^(?!\$TYPE_).*/g, "The type start with $TYPE_ but is not present in constants.json")
556
558
  ]),
557
559
  restapi: e.enum(["/lights", "/sensors"]),
558
560
  uuid: j(),
559
561
  fingerprint: e.optional(e.strictObject({
560
- profile: a(4),
561
- device: a(4),
562
+ profile: r(4),
563
+ device: r(4),
562
564
  endpoint: l(),
563
- in: e.optional(e.array(a(4))),
564
- out: e.optional(e.array(a(4)))
565
+ in: e.optional(e.array(r(4))),
566
+ out: e.optional(e.array(r(4)))
565
567
  })),
566
568
  meta: e.optional(e.strictObject({
567
569
  // TODO validate this
@@ -572,51 +574,51 @@ function F(t) {
572
574
  buttons: e.optional(e.any()),
573
575
  // TODO validate this
574
576
  buttonevents: e.optional(e.any()),
575
- items: e.array(k(t)),
577
+ items: e.array(z(t)),
576
578
  example: e.optional(e.unknown())
577
579
  });
578
580
  }
579
- function k(t) {
581
+ function z(t) {
580
582
  return D().omit({
581
583
  $schema: !0,
582
584
  schema: !0,
583
585
  id: !0
584
586
  }).extend({
585
587
  name: e.enum(t.attributes, {
586
- errorMap: (r, c) => r.code === "invalid_enum_value" ? { message: `Invalid enum value. Expected item from generic attributes definition, received '${r.received}'` } : { message: c.defaultError }
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 }
587
589
  }).describe("Item name.")
588
590
  });
589
591
  }
590
- function z(t) {
592
+ function k(t) {
591
593
  return e.discriminatedUnion("bind", [
592
594
  e.strictObject({
593
595
  bind: e.literal("unicast"),
594
596
  "src.ep": l().describe("Source endpoint."),
595
597
  "dst.ep": e.optional(l()).describe("Destination endpoint, generaly 0x01."),
596
- cl: a(4).describe("Cluster."),
598
+ cl: r(4).describe("Cluster."),
597
599
  report: e.optional(e.array(
598
600
  e.strictObject({
599
- at: a(4),
600
- dt: a(2),
601
- mf: e.optional(a(4)),
601
+ at: r(4),
602
+ dt: r(2),
603
+ mf: e.optional(r(4)),
602
604
  min: e.number(),
603
605
  max: e.number(),
604
- change: e.optional(a().or(e.number()))
605
- }).refine((r) => r.min <= r.max, { message: "invalid report time, min should be smaller than max" })
606
+ change: e.optional(r().or(e.number()))
607
+ }).refine((a) => a.min <= a.max, { message: "invalid report time, min should be smaller than max" })
606
608
  ))
607
609
  }),
608
610
  e.strictObject({
609
611
  bind: e.literal("groupcast"),
610
612
  "src.ep": l().describe("Source endpoint."),
611
- cl: a(4).describe("Cluster."),
613
+ cl: r(4).describe("Cluster."),
612
614
  "config.group": e.number().min(0).max(255)
613
615
  })
614
616
  ]);
615
617
  }
616
618
  function L(t) {
617
- const r = e.array(
619
+ const a = e.array(
618
620
  e.enum(t.attributes, {
619
- errorMap: (c, n) => c.code === "invalid_enum_value" ? { message: `Invalid enum value. Expected item from generic attributes definition, received '${c.received}'` } : { message: n.defaultError }
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 }
620
622
  })
621
623
  );
622
624
  return e.strictObject({
@@ -624,7 +626,7 @@ function L(t) {
624
626
  schema: e.literal("subdevice1.schema.json"),
625
627
  type: e.union([
626
628
  e.enum(Object.keys(t.deviceTypes), {
627
- errorMap: (c, n) => c.code === "invalid_enum_value" ? { message: `Invalid enum value. Expected type from generic attributes definition, received '${c.received}'` } : { message: n.defaultError }
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 }
628
630
  }),
629
631
  e.string().regex(/^(?!\$TYPE_).*/g, "The type start with $TYPE_ but is not present in constants.json")
630
632
  ]),
@@ -632,8 +634,8 @@ function L(t) {
632
634
  restapi: e.enum(["/lights", "/sensors"]),
633
635
  order: e.number(),
634
636
  uuid: j(),
635
- items: r,
636
- items_optional: e.optional(r)
637
+ items: a,
638
+ items_optional: e.optional(a)
637
639
  });
638
640
  }
639
641
  function x(t) {
@@ -643,64 +645,64 @@ function x(t) {
643
645
  I(),
644
646
  D(),
645
647
  L(t)
646
- ]).superRefine((r, c) => {
647
- switch (r.schema) {
648
+ ]).superRefine((a, d) => {
649
+ switch (a.schema) {
648
650
  case "devcap1.schema.json":
649
- y[r.schema].map((n) => n(r, c, t));
651
+ y[a.schema].map((o) => o(a, d, t));
650
652
  break;
651
653
  case "constants2.schema.json":
652
- y[r.schema].map((n) => n(r, c, t));
654
+ y[a.schema].map((o) => o(a, d, t));
653
655
  break;
654
656
  }
655
657
  });
656
658
  }
657
- function W(t = {
659
+ function P(t = {
658
660
  attributes: [],
659
661
  manufacturers: {},
660
662
  deviceTypes: {},
661
663
  resources: {},
662
664
  subDevices: {}
663
665
  }) {
664
- let r = x(t);
665
- const c = () => {
666
- r = x(t);
666
+ let a = x(t);
667
+ const d = () => {
668
+ a = x(t);
667
669
  };
668
- return { generics: t, loadGeneric: (o) => {
669
- const s = r.parse(o);
670
- switch (s.schema) {
670
+ return { generics: t, loadGeneric: (s) => {
671
+ const n = a.parse(s);
672
+ switch (n.schema) {
671
673
  case "constants1.schema.json":
672
674
  t.manufacturers = {
673
675
  ...t.manufacturers,
674
- ...s.manufacturers
676
+ ...n.manufacturers
675
677
  }, t.deviceTypes = {
676
678
  ...t.deviceTypes,
677
- ...s["device-types"]
679
+ ...n["device-types"]
678
680
  };
679
681
  break;
680
682
  case "constants2.schema.json": {
681
- Object.keys(s).filter((i) => i.startsWith("$MF_")).forEach((i) => {
682
- t.manufacturers[i] = s[i];
683
- }), Object.keys(s).filter((i) => i.startsWith("$TYPE_")).forEach((i) => {
684
- t.deviceTypes[i] = s[i];
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];
685
687
  });
686
688
  break;
687
689
  }
688
690
  case "resourceitem1.schema.json": {
689
- if (t.attributes.includes(s.id))
690
- throw new Error(`Got duplicate resource item with attribute id '${s.id}'.`);
691
- const i = s, u = s.id;
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;
692
694
  delete i.$schema, delete i.schema, delete i.id, t.resources[u] = i, t.attributes.push(u);
693
695
  break;
694
696
  }
695
697
  case "subdevice1.schema.json":
696
- t.subDevices[s.type] = s, t.subDevices[s.name] = s;
698
+ t.subDevices[n.type] = n, t.subDevices[n.name] = n;
697
699
  break;
698
700
  case "devcap1.schema.json":
699
701
  throw new Error("Got invalid generic file, got data with schema 'devcap1.schema.json'.");
700
702
  }
701
- return c(), !0;
702
- }, validate: (o) => r.parse(o), getSchema: () => r, version: E };
703
+ return d(), !0;
704
+ }, validate: (s) => a.parse(s), getSchema: () => a, version: E };
703
705
  }
704
706
  export {
705
- W as createValidator
707
+ P as createValidator
706
708
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deconz-community/ddf-validator",
3
- "version": "2.13.0",
3
+ "version": "2.14.0",
4
4
  "description": "Validating DDF files for deconz",
5
5
  "keywords": [
6
6
  "deconz",
@@ -53,35 +53,32 @@
53
53
  "pnpm": ">=8.6.8",
54
54
  "node": ">=16.0.0"
55
55
  },
56
- "packageManager": "pnpm@8.6.12",
56
+ "packageManager": "pnpm@8.7.4",
57
57
  "devDependencies": {
58
- "@types/jsdom": "^21.1.1",
59
- "@types/node": "^20.4.8",
58
+ "@types/jsdom": "^21.1.2",
59
+ "@types/node": "^20.6.0",
60
60
  "@types/pako": "^2.0.0",
61
- "@typescript-eslint/eslint-plugin": "^6.2.1",
62
- "@typescript-eslint/parser": "^6.2.1",
61
+ "@typescript-eslint/eslint-plugin": "^6.6.0",
62
+ "@typescript-eslint/parser": "^6.6.0",
63
63
  "degit": "^2.8.4",
64
- "eslint": "^8.46.0",
65
- "eslint-config-prettier": "^9.0.0",
66
- "eslint-plugin-prettier": "^5.0.0",
67
- "glob": "^10.3.3",
68
- "lint-staged": "^13.2.3",
69
- "prettier": "^3.0.1",
64
+ "eslint": "^8.49.0",
65
+ "glob": "^10.3.4",
66
+ "lint-staged": "^14.0.1",
70
67
  "rimraf": "^5.0.1",
71
- "stylelint": "^15.10.2",
68
+ "stylelint": "^15.10.3",
72
69
  "stylelint-config-recommended": "^13.0.0",
73
70
  "stylelint-config-sass-guidelines": "^10.0.0",
74
71
  "taze": "^0.11.2",
75
72
  "ts-node": "^10.9.1",
76
- "typescript": "^5.1.6",
77
- "vite": "^4.4.8",
78
- "vitest": "^0.34.1",
73
+ "typescript": "^5.2.2",
74
+ "vite": "^4.4.9",
75
+ "vitest": "^0.34.4",
79
76
  "zod-to-json-schema": "^3.21.4",
80
- "zod-to-ts": "^1.1.4",
81
- "zod-validation-error": "^1.3.1"
77
+ "zod-to-ts": "^1.2.0",
78
+ "zod-validation-error": "^1.5.0"
82
79
  },
83
80
  "dependencies": {
84
- "zod": "^3.21.4"
81
+ "zod": "^3.22.2"
85
82
  },
86
83
  "scripts": {
87
84
  "build": "pnpm run build:vite && pnpm run build:dts",