@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.
- package/dist/ddf-validator.cjs +1 -1
- package/dist/ddf-validator.mjs +226 -224
- package/package.json +16 -19
package/dist/ddf-validator.cjs
CHANGED
|
@@ -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;
|
package/dist/ddf-validator.mjs
CHANGED
|
@@ -1,64 +1,62 @@
|
|
|
1
1
|
import { z as e } from "zod";
|
|
2
|
-
const E = "2.
|
|
2
|
+
const E = "2.14.0", y = {
|
|
3
3
|
"devcap1.schema.json": [
|
|
4
4
|
O,
|
|
5
5
|
_,
|
|
6
6
|
$,
|
|
7
|
-
|
|
7
|
+
w,
|
|
8
8
|
C
|
|
9
9
|
],
|
|
10
10
|
"constants2.schema.json": [
|
|
11
|
-
|
|
11
|
+
T
|
|
12
12
|
]
|
|
13
13
|
};
|
|
14
|
-
function O(t,
|
|
15
|
-
const
|
|
16
|
-
if (
|
|
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
|
|
19
|
-
if (
|
|
20
|
-
|
|
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
|
-
(
|
|
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,
|
|
33
|
+
function _(t, a, d) {
|
|
34
34
|
if (!t.bindings)
|
|
35
35
|
return;
|
|
36
|
-
const
|
|
37
|
-
t.bindings.forEach((
|
|
38
|
-
|
|
39
|
-
|
|
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((
|
|
42
|
-
|
|
43
|
-
var
|
|
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 =
|
|
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}.${
|
|
48
|
-
|
|
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 (${
|
|
51
|
-
path: ["subdevices",
|
|
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,
|
|
59
|
-
|
|
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
|
|
74
|
+
description: 'a device with "state/ct" need the "min" and "max" values for capability.',
|
|
77
75
|
if: {
|
|
78
|
-
|
|
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
|
-
"
|
|
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 "
|
|
87
|
+
description: 'a device with "cap/color/ct/computes_xy" need the corresponding state/{x,y} items',
|
|
94
88
|
if: {
|
|
95
|
-
item:
|
|
89
|
+
item: "cap/color/ct/computes_xy"
|
|
96
90
|
},
|
|
97
91
|
need: {
|
|
98
92
|
item: [
|
|
99
|
-
"
|
|
100
|
-
"
|
|
101
|
-
|
|
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,
|
|
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
|
-
|
|
110
|
-
|
|
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
|
|
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
|
-
|
|
132
|
-
|
|
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
|
-
|
|
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((
|
|
143
|
-
const
|
|
144
|
-
|
|
145
|
-
(Object.keys(
|
|
146
|
-
|
|
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 (
|
|
156
|
+
return c(h, (b) => b === s.type);
|
|
150
157
|
case "item":
|
|
151
|
-
return
|
|
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
|
-
})) &&
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
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
|
|
169
|
-
const
|
|
170
|
-
t.subdevices.forEach((
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
const
|
|
174
|
-
|
|
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",
|
|
178
|
-
}),
|
|
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",
|
|
183
|
+
path: ["subdevices", s, "items", i, u]
|
|
182
184
|
}));
|
|
183
185
|
});
|
|
184
186
|
});
|
|
185
187
|
});
|
|
186
188
|
}
|
|
187
|
-
function
|
|
188
|
-
const
|
|
189
|
-
Object.keys(t).forEach((
|
|
190
|
-
if (!Object.keys(
|
|
191
|
-
if (!["$MF_", "$TYPE_"].some((
|
|
192
|
-
|
|
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: [
|
|
197
|
+
path: [c]
|
|
196
198
|
});
|
|
197
199
|
return;
|
|
198
200
|
}
|
|
199
|
-
typeof t[
|
|
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: [
|
|
204
|
+
path: [c]
|
|
203
205
|
});
|
|
204
206
|
}
|
|
205
207
|
});
|
|
206
208
|
}
|
|
207
|
-
function C(t,
|
|
208
|
-
t.
|
|
209
|
-
const
|
|
210
|
-
if (!
|
|
211
|
-
|
|
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 "${
|
|
214
|
-
path: ["subdevices",
|
|
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
|
|
219
|
-
|
|
220
|
-
|
|
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 "${
|
|
223
|
-
path: ["subdevices",
|
|
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
|
|
250
|
-
const
|
|
251
|
-
return t === void 0 ? e.string().regex(/^0x[0-9a-fA-F]+$/,
|
|
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
|
-
|
|
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
|
|
264
|
-
const
|
|
265
|
-
if (typeof
|
|
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
|
-
|
|
277
|
+
r(2)
|
|
276
278
|
]),
|
|
277
279
|
e.tuple([
|
|
278
280
|
e.literal("$address.ext"),
|
|
279
|
-
|
|
280
|
-
|
|
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
|
|
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:
|
|
298
|
-
cl:
|
|
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(
|
|
301
|
-
eval: e.optional(
|
|
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:
|
|
306
|
-
cl:
|
|
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(
|
|
309
|
-
eval: e.optional(
|
|
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:
|
|
315
|
-
cl:
|
|
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(
|
|
318
|
-
eval: e.optional(
|
|
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:
|
|
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(
|
|
326
|
-
cmd: e.optional(
|
|
327
|
-
eval: e.optional(
|
|
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(
|
|
342
|
-
cl:
|
|
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(
|
|
346
|
-
mf: e.optional(
|
|
347
|
-
eval: e.optional(
|
|
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(
|
|
353
|
-
cl:
|
|
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(
|
|
357
|
-
mf: e.optional(
|
|
358
|
-
eval: e.optional(
|
|
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:
|
|
364
|
-
cl:
|
|
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(
|
|
367
|
-
eval: e.optional(
|
|
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:
|
|
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(
|
|
375
|
-
cmd: e.optional(
|
|
376
|
-
eval: e.optional(
|
|
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(
|
|
397
|
-
at: e.optional(
|
|
398
|
-
idx:
|
|
399
|
-
eval: e.optional(
|
|
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(
|
|
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(
|
|
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:
|
|
423
|
-
dt:
|
|
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(
|
|
426
|
-
eval: e.optional(
|
|
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(
|
|
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:
|
|
435
|
-
dt:
|
|
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(
|
|
438
|
-
eval: e.optional(
|
|
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:
|
|
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:
|
|
447
|
-
dt:
|
|
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(
|
|
450
|
-
eval: e.optional(
|
|
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:
|
|
456
|
-
dt:
|
|
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(
|
|
459
|
-
cmd: e.optional(
|
|
460
|
-
eval: e.optional(
|
|
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:
|
|
467
|
-
eval: e.optional(
|
|
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(
|
|
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(
|
|
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: (
|
|
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:
|
|
561
|
-
device:
|
|
562
|
+
profile: r(4),
|
|
563
|
+
device: r(4),
|
|
562
564
|
endpoint: l(),
|
|
563
|
-
in: e.optional(e.array(
|
|
564
|
-
out: e.optional(e.array(
|
|
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(
|
|
577
|
+
items: e.array(z(t)),
|
|
576
578
|
example: e.optional(e.unknown())
|
|
577
579
|
});
|
|
578
580
|
}
|
|
579
|
-
function
|
|
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: (
|
|
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
|
|
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:
|
|
598
|
+
cl: r(4).describe("Cluster."),
|
|
597
599
|
report: e.optional(e.array(
|
|
598
600
|
e.strictObject({
|
|
599
|
-
at:
|
|
600
|
-
dt:
|
|
601
|
-
mf: e.optional(
|
|
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(
|
|
605
|
-
}).refine((
|
|
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:
|
|
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
|
|
619
|
+
const a = e.array(
|
|
618
620
|
e.enum(t.attributes, {
|
|
619
|
-
errorMap: (
|
|
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: (
|
|
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:
|
|
636
|
-
items_optional: e.optional(
|
|
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((
|
|
647
|
-
switch (
|
|
648
|
+
]).superRefine((a, d) => {
|
|
649
|
+
switch (a.schema) {
|
|
648
650
|
case "devcap1.schema.json":
|
|
649
|
-
y[
|
|
651
|
+
y[a.schema].map((o) => o(a, d, t));
|
|
650
652
|
break;
|
|
651
653
|
case "constants2.schema.json":
|
|
652
|
-
y[
|
|
654
|
+
y[a.schema].map((o) => o(a, d, t));
|
|
653
655
|
break;
|
|
654
656
|
}
|
|
655
657
|
});
|
|
656
658
|
}
|
|
657
|
-
function
|
|
659
|
+
function P(t = {
|
|
658
660
|
attributes: [],
|
|
659
661
|
manufacturers: {},
|
|
660
662
|
deviceTypes: {},
|
|
661
663
|
resources: {},
|
|
662
664
|
subDevices: {}
|
|
663
665
|
}) {
|
|
664
|
-
let
|
|
665
|
-
const
|
|
666
|
-
|
|
666
|
+
let a = x(t);
|
|
667
|
+
const d = () => {
|
|
668
|
+
a = x(t);
|
|
667
669
|
};
|
|
668
|
-
return { generics: t, loadGeneric: (
|
|
669
|
-
const
|
|
670
|
-
switch (
|
|
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
|
-
...
|
|
676
|
+
...n.manufacturers
|
|
675
677
|
}, t.deviceTypes = {
|
|
676
678
|
...t.deviceTypes,
|
|
677
|
-
...
|
|
679
|
+
...n["device-types"]
|
|
678
680
|
};
|
|
679
681
|
break;
|
|
680
682
|
case "constants2.schema.json": {
|
|
681
|
-
Object.keys(
|
|
682
|
-
t.manufacturers[i] =
|
|
683
|
-
}), Object.keys(
|
|
684
|
-
t.deviceTypes[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(
|
|
690
|
-
throw new Error(`Got duplicate resource item with attribute id '${
|
|
691
|
-
const i =
|
|
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[
|
|
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
|
|
702
|
-
}, validate: (
|
|
703
|
+
return d(), !0;
|
|
704
|
+
}, validate: (s) => a.parse(s), getSchema: () => a, version: E };
|
|
703
705
|
}
|
|
704
706
|
export {
|
|
705
|
-
|
|
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.
|
|
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.
|
|
56
|
+
"packageManager": "pnpm@8.7.4",
|
|
57
57
|
"devDependencies": {
|
|
58
|
-
"@types/jsdom": "^21.1.
|
|
59
|
-
"@types/node": "^20.
|
|
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.
|
|
62
|
-
"@typescript-eslint/parser": "^6.
|
|
61
|
+
"@typescript-eslint/eslint-plugin": "^6.6.0",
|
|
62
|
+
"@typescript-eslint/parser": "^6.6.0",
|
|
63
63
|
"degit": "^2.8.4",
|
|
64
|
-
"eslint": "^8.
|
|
65
|
-
"
|
|
66
|
-
"
|
|
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.
|
|
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.
|
|
77
|
-
"vite": "^4.4.
|
|
78
|
-
"vitest": "^0.34.
|
|
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.
|
|
81
|
-
"zod-validation-error": "^1.
|
|
77
|
+
"zod-to-ts": "^1.2.0",
|
|
78
|
+
"zod-validation-error": "^1.5.0"
|
|
82
79
|
},
|
|
83
80
|
"dependencies": {
|
|
84
|
-
"zod": "^3.
|
|
81
|
+
"zod": "^3.22.2"
|
|
85
82
|
},
|
|
86
83
|
"scripts": {
|
|
87
84
|
"build": "pnpm run build:vite && pnpm run build:dts",
|