@deconz-community/ddf-validator 2.18.0 → 2.20.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,63 +1,63 @@
1
1
  import { z as e } from "zod";
2
- const E = "2.18.0", y = {
2
+ const M = "2.20.0", O = {
3
3
  "devcap1.schema.json": [
4
- O,
5
- _,
6
- $,
7
- w,
8
- C,
9
- A
4
+ z,
5
+ P,
6
+ W,
7
+ L,
8
+ N,
9
+ Y
10
10
  ],
11
11
  "constants2.schema.json": [
12
- T
12
+ R
13
13
  ]
14
14
  };
15
- function O(t, a, u) {
16
- const n = typeof t.manufacturername == "string" && typeof t.modelid == "string";
17
- if (n)
15
+ function z(t, r, u) {
16
+ const i = typeof t.manufacturername == "string" && typeof t.modelid == "string";
17
+ if (i)
18
18
  return;
19
- const d = Array.isArray(t.manufacturername) && Array.isArray(t.modelid);
20
- if (d && t.manufacturername.length !== t.modelid.length) {
21
- a.addIssue({
19
+ const c = Array.isArray(t.manufacturername) && Array.isArray(t.modelid);
20
+ if (c && t.manufacturername.length !== t.modelid.length) {
21
+ r.addIssue({
22
22
  code: e.ZodIssueCode.invalid_intersection_types,
23
23
  message: "When 'manufacturername' and 'modelid' are both arrays they should be the same length",
24
24
  path: ["manufacturername", "modelid"]
25
25
  });
26
26
  return;
27
27
  }
28
- (n || d) === !1 && a.addIssue({
28
+ (i || c) === !1 && r.addIssue({
29
29
  code: e.ZodIssueCode.invalid_intersection_types,
30
30
  message: "Invalid properties 'manufacturername' and 'modelid' should have the same type",
31
31
  path: ["manufacturername", "modelid"]
32
32
  });
33
33
  }
34
- function _(t, a, u) {
34
+ function P(t, r, u) {
35
35
  if (!t.bindings)
36
36
  return;
37
- const n = (i) => `0x${(typeof i == "number" ? i : Number.parseInt(i, 16)).toString(16)}`, d = {};
38
- t.bindings.forEach((i) => {
39
- i.bind === "unicast" && i.report && i.report.forEach((l) => {
40
- l.max !== 65535 && (d[`${n(i["src.ep"])}.${n(i.cl)}.${n(l.at)}`] = l.max);
37
+ const i = (n) => `0x${(typeof n == "number" ? n : Number.parseInt(n, 16)).toString(16)}`, c = {};
38
+ t.bindings.forEach((n) => {
39
+ n.bind === "unicast" && n.report && n.report.forEach((d) => {
40
+ d.max !== 65535 && (c[`${i(n["src.ep"])}.${i(n.cl)}.${i(d.at)}`] = d.max);
41
41
  });
42
- }), t.subdevices.forEach((i, l) => {
43
- i.items.forEach((s, o) => {
44
- var c;
45
- if (s["refresh.interval"] && s.read && s.read.fn === "zcl") {
46
- const b = n(s.read.ep ?? ((c = i.fingerprint) == null ? void 0 : c.endpoint) ?? i.uuid[1]), h = Array.isArray(s.read.at) ? s.read.at : [s.read.at];
47
- for (let v = 0; v < h.length; v++) {
48
- const g = `${b}.${n(s.read.cl)}.${n(h[v])}`;
49
- d[g] !== void 0 && s["refresh.interval"] - 60 < d[g] && a.addIssue({
42
+ }), t.subdevices.forEach((n, d) => {
43
+ n.items.forEach((a, m) => {
44
+ var s;
45
+ if (a["refresh.interval"] && a.read && a.read.fn === "zcl:attr" && a.read.at) {
46
+ const o = i(a.read.ep ?? ((s = n.fingerprint) == null ? void 0 : s.endpoint) ?? n.uuid[1]), p = Array.isArray(a.read.at) ? a.read.at : [a.read.at];
47
+ for (let b = 0; b < p.length; b++) {
48
+ const h = `${o}.${i(a.read.cl)}.${i(p[b])}`;
49
+ c[h] !== void 0 && a["refresh.interval"] - 60 < c[h] && r.addIssue({
50
50
  code: e.ZodIssueCode.custom,
51
- message: `The refresh interval (${s["refresh.interval"]} - 60 = ${s["refresh.interval"] - 60}) should be greater than the binding max refresh value (${d[g]}) with a margin of 60 seconds`,
52
- path: ["subdevices", l, "items", o, "refresh.interval"]
51
+ message: `The refresh interval (${a["refresh.interval"]} - 60 = ${a["refresh.interval"] - 60}) should be greater than the binding max refresh value (${c[h]}) with a margin of 60 seconds`,
52
+ path: ["subdevices", d, "items", m, "refresh.interval"]
53
53
  });
54
54
  }
55
55
  }
56
56
  });
57
57
  });
58
58
  }
59
- function $(t, a, u) {
60
- const n = [
59
+ function W(t, r, u) {
60
+ const i = [
61
61
  /*
62
62
  {
63
63
  description: 'a device should always have basic attributes.',
@@ -147,201 +147,195 @@ function $(t, a, u) {
147
147
  }
148
148
  }
149
149
  }
150
- ], d = (i, l) => typeof i == "string" ? l(i) : Array.isArray(i) ? i.every((s) => d(s, l)) : "and" in i ? i.and.every((s) => d(s, l)) : "or" in i ? i.or.some((s) => d(s, l)) : !1;
151
- t.subdevices.forEach((i, l) => {
152
- const s = i.items.map((o) => o.name);
153
- n.forEach((o) => {
154
- (Object.keys(o.if).length === 0 || Object.entries(o.if).some(([c, b]) => {
155
- switch (c) {
150
+ ], c = (n, d) => typeof n == "string" ? d(n) : Array.isArray(n) ? n.every((a) => c(a, d)) : "and" in n ? n.and.every((a) => c(a, d)) : "or" in n ? n.or.some((a) => c(a, d)) : !1;
151
+ t.subdevices.forEach((n, d) => {
152
+ const a = n.items.map((m) => m.name);
153
+ i.forEach((m) => {
154
+ (Object.keys(m.if).length === 0 || Object.entries(m.if).some(([s, o]) => {
155
+ switch (s) {
156
156
  case "type":
157
- return d(b, (h) => h === i.type);
157
+ return c(o, (p) => p === n.type);
158
158
  case "item":
159
- return d(b, (h) => s.includes(h));
159
+ return c(o, (p) => a.includes(p));
160
160
  default:
161
161
  return !1;
162
162
  }
163
- })) && (d(o.need.item, (c) => s.includes(c)) || a.addIssue({
163
+ })) && (c(m.need.item, (s) => a.includes(s)) || r.addIssue({
164
164
  code: e.ZodIssueCode.custom,
165
- message: `The device is missing some items because ${o.description}`,
166
- path: ["subdevices", l, "items"]
165
+ message: `The device is missing some items because ${m.description}`,
166
+ path: ["subdevices", d, "items"]
167
167
  }));
168
168
  });
169
169
  });
170
170
  }
171
- function w(t, a, u) {
172
- const n = ["parse", "write"];
173
- t.subdevices.forEach((d, i) => {
174
- d.items.forEach((l, s) => {
175
- n.forEach((o) => {
176
- const c = l[o];
177
- c !== void 0 && (c.fn === void 0 || c.fn === "zcl" || c.fn === "zcl:attr" || c.fn === "zcl:cmd") && (c.eval === void 0 && c.script === void 0 && a.addIssue({
171
+ function L(t, r, u) {
172
+ const i = ["parse", "write"];
173
+ t.subdevices.forEach((c, n) => {
174
+ c.items.forEach((d, a) => {
175
+ i.forEach((m) => {
176
+ const s = d[m];
177
+ s !== void 0 && (s.fn === void 0 || s.fn === "zcl:attr" || s.fn === "zcl:cmd") && (s.eval === void 0 && s.script === void 0 && r.addIssue({
178
178
  code: e.ZodIssueCode.custom,
179
- message: `The '${o}' function is missing 'eval' or 'script' option.`,
180
- path: ["subdevices", i, "items", s, o]
181
- }), c.eval !== void 0 && c.script !== void 0 && a.addIssue({
179
+ message: `The '${m}' function is missing 'eval' or 'script' option.`,
180
+ path: ["subdevices", n, "items", a, m]
181
+ }), s.eval !== void 0 && s.script !== void 0 && r.addIssue({
182
182
  code: e.ZodIssueCode.custom,
183
- message: `The '${o}' function is having both 'eval' and 'script' option.`,
184
- path: ["subdevices", i, "items", s, o]
183
+ message: `The '${m}' function is having both 'eval' and 'script' option.`,
184
+ path: ["subdevices", n, "items", a, m]
185
185
  }));
186
186
  });
187
187
  });
188
188
  });
189
189
  }
190
- function T(t, a, u) {
191
- const n = I();
192
- Object.keys(t).forEach((d) => {
193
- if (!Object.keys(n.shape).includes(d)) {
194
- if (!["$MF_", "$TYPE_"].some((i) => d.startsWith(i))) {
195
- a.addIssue({
190
+ function R(t, r, u) {
191
+ const i = C();
192
+ Object.keys(t).forEach((c) => {
193
+ if (!Object.keys(i.shape).includes(c)) {
194
+ if (!["$MF_", "$TYPE_"].some((n) => c.startsWith(n))) {
195
+ r.addIssue({
196
196
  code: e.ZodIssueCode.custom,
197
197
  message: "The constant key should start with '$MF_' or '$TYPE_'",
198
- path: [d]
198
+ path: [c]
199
199
  });
200
200
  return;
201
201
  }
202
- typeof t[d] != "string" && a.addIssue({
202
+ typeof t[c] != "string" && r.addIssue({
203
203
  code: e.ZodIssueCode.custom,
204
204
  message: "The constant value should be a string",
205
- path: [d]
205
+ path: [c]
206
206
  });
207
207
  }
208
208
  });
209
209
  }
210
- function C(t, a, u) {
211
- t.subdevices.forEach((n, d) => {
212
- const i = u.subDevices[n.type];
213
- if (!i) {
214
- a.addIssue({
210
+ function N(t, r, u) {
211
+ t.subdevices.forEach((i, c) => {
212
+ const n = u.subDevices[i.type];
213
+ if (!n) {
214
+ r.addIssue({
215
215
  code: e.ZodIssueCode.custom,
216
- message: `The device is missing the device definition for the type "${n.type}"`,
217
- path: ["subdevices", d, "items"]
216
+ message: `The device is missing the device definition for the type "${i.type}"`,
217
+ path: ["subdevices", c, "items"]
218
218
  });
219
219
  return;
220
220
  }
221
- let l = i.items;
222
- i.items_optional && (l = l.filter((s) => !i.items_optional.includes(s))), l.forEach((s) => {
223
- n.items.find((o) => o.name === s) || a.addIssue({
221
+ let d = n.items;
222
+ n.items_optional && (d = d.filter((a) => !n.items_optional.includes(a))), d.forEach((a) => {
223
+ i.items.find((m) => m.name === a) || r.addIssue({
224
224
  code: e.ZodIssueCode.custom,
225
- message: `The device should have the item "${s}" because it is mandatory for devices of type "${n.type}"`,
226
- path: ["subdevices", d, "items"]
225
+ message: `The device should have the item "${a}" because it is mandatory for devices of type "${i.type}"`,
226
+ path: ["subdevices", c, "items"]
227
227
  });
228
228
  });
229
229
  });
230
230
  }
231
- function A(t, a, u) {
232
- t.subdevices.forEach((n, d) => {
233
- const i = n.items.map((l) => l.name);
234
- n.items.forEach((l, s) => {
235
- l.parse && l.parse.fn === "numtostr" && (i.includes(l.parse.srcitem) || a.addIssue({
231
+ function Y(t, r, u) {
232
+ t.subdevices.forEach((i, c) => {
233
+ const n = i.items.map((d) => d.name);
234
+ i.items.forEach((d, a) => {
235
+ d.parse && d.parse.fn === "numtostr" && (n.includes(d.parse.srcitem) || r.addIssue({
236
236
  code: e.ZodIssueCode.custom,
237
- message: `The device should have the item "${l.parse.srcitem}" because it is used in the 'numtostr' function`,
238
- path: ["subdevices", d, "items", s, "parse", "srcitem"]
237
+ message: `The device should have the item "${d.parse.srcitem}" because it is used in the 'numtostr' function`,
238
+ path: ["subdevices", c, "items", a, "parse", "srcitem"]
239
239
  }));
240
240
  });
241
241
  });
242
242
  }
243
- function M(t) {
243
+ function B(t) {
244
244
  return e.strictObject({
245
245
  $schema: e.optional(e.string()),
246
246
  schema: e.literal("constants1.schema.json"),
247
+ ddfvalidate: e.optional(e.boolean()),
247
248
  manufacturers: e.record(e.string().startsWith("$MF_"), e.string()),
248
249
  "device-types": e.record(e.string().startsWith("$TYPE_"), e.string())
249
250
  });
250
251
  }
251
- function I(t) {
252
+ function C(t) {
252
253
  return e.object({
253
254
  $schema: e.optional(e.string()),
254
- schema: e.literal("constants2.schema.json")
255
+ schema: e.literal("constants2.schema.json"),
256
+ ddfvalidate: e.optional(e.boolean())
255
257
  }).passthrough();
256
258
  }
257
- function S() {
259
+ function U() {
258
260
  return e.string().regex(
259
261
  // Regex for AAAA-MM-JJ
260
262
  /^(\d{4})-(?:(?:0[1-9])|(?:1[0-2]))-(?:(?:0[1-9])|(?:[12][0-9])|(?:3[01]))$/,
261
263
  "Invalid date value"
262
264
  );
263
265
  }
264
- function r(t = void 0) {
265
- const a = "Invalid hexadecimal value";
266
- 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);
266
+ function l(t = void 0) {
267
+ const r = "Invalid hexadecimal value";
268
+ 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);
267
269
  }
268
- function m() {
270
+ function g() {
269
271
  return e.union([
270
- r(2),
272
+ l(2),
271
273
  e.number().min(0).max(255)
272
274
  ]);
273
275
  }
274
- function J() {
276
+ function k() {
275
277
  return e.custom((t) => {
276
278
  if (!Array.isArray(t) || t.length % 2 !== 0)
277
279
  return !1;
278
- for (let a = 0; a < t.length; a += 2) {
279
- const u = t[a], n = t[a + 1];
280
- if (typeof u != "number" || typeof n != "string")
280
+ for (let r = 0; r < t.length; r += 2) {
281
+ const u = t[r], i = t[r + 1];
282
+ if (typeof u != "number" || typeof i != "string")
281
283
  return !1;
282
284
  }
283
285
  return !0;
284
286
  }, "The value must be an array with an even number of values and alternating between number and string.");
285
287
  }
286
- function j() {
288
+ function S() {
287
289
  return e.union([
288
290
  e.tuple([
289
291
  e.literal("$address.ext"),
290
- r(2)
292
+ l(2)
291
293
  ]),
292
294
  e.tuple([
293
295
  e.literal("$address.ext"),
294
- r(2),
295
- r(4)
296
+ l(2),
297
+ l(4)
296
298
  ])
297
299
  ]);
298
300
  }
299
- function f() {
301
+ function A() {
300
302
  return e.string();
301
303
  }
302
- function p() {
304
+ function F() {
303
305
  return e.string();
304
306
  }
305
- function Z() {
307
+ const x = e.strictObject({
308
+ ep: e.optional(g()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),
309
+ cl: l(4).describe("Cluster ID."),
310
+ at: e.optional(l(4).or(e.array(l(4)))).describe("Attribute ID."),
311
+ mf: e.optional(l(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),
312
+ cmd: e.optional(l(2)).describe("Zigbee command."),
313
+ eval: e.optional(F()).describe("Javascript expression to transform the attribute value to the Item value."),
314
+ script: e.optional(A()).describe("Relative path of a Javascript .js file.")
315
+ }), f = {
316
+ read: x.extend({
317
+ fc: e.optional(l(2).or(e.number())).describe("Zigbee command frame control.")
318
+ }),
319
+ parse: x.extend({}),
320
+ write: x.extend({
321
+ "state.timeout": e.optional(e.number()),
322
+ "change.timeout": e.optional(e.number()),
323
+ dt: e.optional(l(2)).describe("Data type.")
324
+ })
325
+ };
326
+ function V() {
306
327
  return e.discriminatedUnion("fn", [
307
328
  e.strictObject({
308
329
  fn: e.literal("none")
309
330
  }),
310
- e.strictObject({
311
- fn: e.undefined().describe("Generic function to read ZCL attributes."),
312
- at: r(4).or(e.array(r(4))).describe("Attribute ID."),
313
- cl: r(4).describe("Cluster ID."),
314
- ep: e.optional(m()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),
315
- mf: e.optional(r(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),
316
- eval: e.optional(p()).describe("Javascript expression to transform the raw value.")
331
+ f.read.extend({
332
+ fn: e.undefined().describe("Generic function to read ZCL attributes.")
317
333
  }),
318
- e.strictObject({
319
- fn: e.literal("zcl").describe("Generic function to read ZCL attributes."),
320
- at: r(4).or(e.array(r(4))).describe("Attribute ID."),
321
- cl: r(4).describe("Cluster ID."),
322
- ep: e.optional(m()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),
323
- mf: e.optional(r(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),
324
- eval: e.optional(p()).describe("Javascript expression to transform the raw value."),
325
- script: e.optional(f()).describe("Relative path of a Javascript .js file.")
326
- }).describe("Deprecated"),
327
- e.strictObject({
328
- fn: e.literal("zcl:attr").describe("Generic function to parse ZCL values from read/report commands."),
329
- at: r(4).or(e.array(r(4))).describe("String hex value or array of string hex values."),
330
- cl: r(4).describe("Cluster ID."),
331
- ep: e.optional(m()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),
332
- mf: e.optional(r(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),
333
- eval: e.optional(p()).describe("Javascript expression to transform the attribute value to the Item value."),
334
- script: e.optional(f()).describe("Relative path of a Javascript .js file.")
334
+ f.read.extend({
335
+ fn: e.literal("zcl:attr").describe("Generic function to parse ZCL values from read/report commands.")
335
336
  }),
336
- e.strictObject({
337
- fn: e.literal("zcl:cmd").describe("Generic function to parse ZCL values from read/report commands."),
338
- cl: r(4).describe("Cluster ID."),
339
- ep: e.optional(m()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),
340
- mf: e.optional(r(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),
341
- cmd: e.optional(r(2)).describe("Zigbee command."),
342
- eval: e.optional(p()).describe("Javascript expression to transform the attribute value to the Item value."),
343
- fc: e.optional(r(2).or(e.number())).describe("Zigbee command frame control."),
344
- script: e.optional(f()).describe("Relative path of a Javascript .js file.")
337
+ f.read.extend({
338
+ fn: e.literal("zcl:cmd").describe("Generic function to parse ZCL values from read/report commands.")
345
339
  }),
346
340
  e.strictObject({
347
341
  fn: e.literal("tuya").describe("Generic function to read all Tuya datapoints. It has no parameters.")
@@ -350,47 +344,17 @@ function Z() {
350
344
  message: "eval and script should not both be present"
351
345
  });
352
346
  }
353
- function G(t) {
347
+ function q(t) {
354
348
  return e.discriminatedUnion("fn", [
355
- e.strictObject({
356
- fn: e.undefined().describe("Generic function to parse ZCL attributes and commands."),
357
- at: e.optional(r(4).or(e.array(r(4)))).describe("Attribute ID."),
358
- cl: r(4).describe("Cluster ID."),
359
- cppsrc: e.optional(e.string()),
360
- ep: e.optional(m()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),
361
- cmd: e.optional(r(2)).describe("Zigbee command."),
362
- mf: e.optional(r(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),
363
- eval: e.optional(p()).describe("Javascript expression to transform the raw value."),
364
- script: e.optional(f()).describe("Relative path of a Javascript .js file.")
349
+ f.parse.extend({
350
+ fn: e.undefined().describe("Generic function to read ZCL attributes."),
351
+ cppsrc: e.optional(e.string())
365
352
  }),
366
- e.strictObject({
367
- fn: e.literal("zcl").describe("Generic function to parse ZCL attributes and commands."),
368
- at: e.optional(r(4).or(e.array(r(4)))).describe("Attribute ID."),
369
- cl: r(4).describe("Cluster ID."),
370
- cppsrc: e.optional(e.string()),
371
- ep: e.optional(m()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),
372
- cmd: e.optional(r(2)).describe("Zigbee command."),
373
- mf: e.optional(r(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),
374
- eval: e.optional(p()).describe("Javascript expression to transform the raw value."),
375
- script: e.optional(f()).describe("Relative path of a Javascript .js file.")
376
- }).describe("Deprecated"),
377
- e.strictObject({
378
- fn: e.literal("zcl:attr").describe("Generic function to parse ZCL values from read/report commands."),
379
- at: r(4).or(e.array(r(4))).describe("String hex value or array of string hex values."),
380
- cl: r(4).describe("Cluster ID."),
381
- ep: e.optional(m()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),
382
- mf: e.optional(r(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),
383
- eval: e.optional(p()).describe("Javascript expression to transform the attribute value to the Item value."),
384
- script: e.optional(f()).describe("Relative path of a Javascript .js file.")
353
+ f.parse.extend({
354
+ fn: e.literal("zcl:attr").describe("Generic function to parse ZCL values from read/report commands.")
385
355
  }),
386
- e.strictObject({
387
- fn: e.literal("zcl:cmd").describe("Generic function to parse ZCL values from read/report commands."),
388
- cl: r(4).describe("Cluster ID."),
389
- ep: e.optional(m()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),
390
- mf: e.optional(r(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),
391
- cmd: e.optional(r(2)).describe("Zigbee command."),
392
- eval: e.optional(p()).describe("Javascript expression to transform the attribute value to the Item value."),
393
- script: e.optional(f()).describe("Relative path of a Javascript .js file.")
356
+ f.parse.extend({
357
+ fn: e.literal("zcl:cmd").describe("Generic function to parse ZCL values from read/report commands.")
394
358
  }),
395
359
  e.strictObject({
396
360
  fn: e.literal("ias:zonestatus").describe("Generic function to parse IAS ZONE status change notifications or zone status from read/report command."),
@@ -399,102 +363,65 @@ function G(t) {
399
363
  e.strictObject({
400
364
  fn: e.literal("numtostr").describe("Generic function to to convert number to string."),
401
365
  srcitem: e.enum(t.attributes, {
402
- errorMap: (a, u) => a.code === "invalid_enum_value" ? { message: `Invalid enum value. Expected item from generic attributes definition, received '${a.received}'` } : { message: u.defaultError }
366
+ errorMap: (r, u) => r.code === "invalid_enum_value" ? { message: `Invalid enum value. Expected item from generic attributes definition, received '${r.received}'` } : { message: u.defaultError }
403
367
  }).describe("The source item holding the number."),
404
368
  op: e.enum(["lt", "le", "eq", "gt", "ge"]).describe("Comparison operator (lt | le | eq | gt | ge)"),
405
- to: J().describe("Array of (num, string) mappings")
369
+ to: k().describe("Array of (num, string) mappings")
406
370
  }),
407
371
  e.strictObject({
408
372
  fn: e.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.")
409
373
  }),
410
- e.strictObject({
374
+ f.parse.pick({
375
+ ep: !0,
376
+ at: !0,
377
+ mf: !0,
378
+ eval: !0,
379
+ script: !0
380
+ }).extend({
411
381
  fn: e.literal("xiaomi:special").describe("Generic function to parse custom Xiaomi attributes and commands."),
412
- ep: e.optional(m()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),
413
- mf: e.optional(r(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),
414
- at: e.optional(r(4)).describe("Attribute ID. The attribute to parse, shall be 0xff01, 0xff02 or 0x00f7"),
415
- idx: r(2).describe("A 8-bit string hex value."),
416
- eval: e.optional(p()).describe("Javascript expression to transform the raw value."),
417
- script: e.optional(f()).describe("Relative path of a Javascript .js file.")
382
+ idx: l(2).describe("A 8-bit string hex value.")
418
383
  }),
419
- e.strictObject({
384
+ f.parse.pick({ eval: !0, script: !0 }).extend({
420
385
  fn: e.literal("tuya").describe("Generic function to parse Tuya data."),
421
- dpid: e.number().describe("Data point ID. 1-255 the datapoint ID."),
422
- eval: e.optional(p()).describe("Javascript expression to transform the raw value."),
423
- script: e.optional(f()).describe("Relative path of a Javascript .js file.")
386
+ dpid: e.number().describe("Data point ID. 1-255 the datapoint ID.")
424
387
  })
425
- ]).refine((a) => !("eval" in a && "script" in a), {
388
+ ]).refine((r) => !("eval" in r && "script" in r), {
426
389
  message: "eval and script should not both be present"
427
390
  });
428
391
  }
429
- function R() {
392
+ function H() {
430
393
  return e.discriminatedUnion("fn", [
431
394
  e.strictObject({
432
395
  fn: e.literal("none")
433
396
  }),
434
- e.strictObject({
435
- fn: e.undefined(),
436
- at: e.optional(r(4).or(e.array(r(4)))).describe("Attribute ID."),
437
- "state.timeout": e.optional(e.number()),
438
- "change.timeout": e.optional(e.number()),
439
- cl: r(4).describe("Cluster ID."),
440
- dt: r(2).describe("Data type."),
441
- ep: e.optional(m()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),
442
- mf: e.optional(r(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),
443
- eval: e.optional(p()).describe("Javascript expression to transform the raw value."),
444
- script: e.optional(f()).describe("Relative path of a Javascript .js file.")
397
+ f.write.extend({
398
+ fn: e.undefined().describe("Generic function to read ZCL attributes."),
399
+ cppsrc: e.optional(e.string())
445
400
  }),
446
- e.strictObject({
447
- fn: e.literal("zcl"),
448
- at: e.optional(r(4).or(e.array(r(4)))).describe("Attribute ID."),
449
- "state.timeout": e.optional(e.number()),
450
- "change.timeout": e.optional(e.number()),
451
- cl: r(4).describe("Cluster ID."),
452
- dt: r(2).describe("Data type."),
453
- ep: e.optional(m()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),
454
- mf: e.optional(r(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),
455
- eval: e.optional(p()).describe("Javascript expression to transform the raw value."),
456
- script: e.optional(f()).describe("Relative path of a Javascript .js file.")
457
- }).describe("Deprecated"),
458
- e.strictObject({
459
- fn: e.literal("zcl:attr").describe("Generic function to parse ZCL values from read/report commands."),
460
- at: r(4).or(e.array(r(4))).describe("String hex value or array of string hex values."),
461
- "state.timeout": e.optional(e.number()),
462
- "change.timeout": e.optional(e.number()),
463
- cl: r(4).describe("Cluster ID."),
464
- dt: r(2).describe("Data type."),
465
- ep: e.optional(m()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),
466
- mf: e.optional(r(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),
467
- eval: e.optional(p()).describe("Javascript expression to transform the attribute value to the Item value."),
468
- script: e.optional(f()).describe("Relative path of a Javascript .js file.")
401
+ f.write.extend({
402
+ fn: e.literal("zcl:attr").describe("Generic function to parse ZCL values from read/report commands.")
469
403
  }),
470
- e.strictObject({
471
- fn: e.literal("zcl:cmd").describe("Generic function to parse ZCL values from read/report commands."),
472
- cl: r(4).describe("Cluster ID."),
473
- ep: e.optional(m()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),
474
- mf: e.optional(r(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),
475
- cmd: e.optional(r(2)).describe("Zigbee command."),
476
- eval: e.optional(p()).describe("Javascript expression to transform the attribute value to the Item value."),
477
- script: e.optional(f()).describe("Relative path of a Javascript .js file.")
404
+ f.write.extend({
405
+ fn: e.literal("zcl:cmd").describe("Generic function to parse ZCL values from read/report commands.")
478
406
  }),
479
- e.strictObject({
407
+ f.write.pick({ eval: !0, script: !0 }).extend({
480
408
  fn: e.literal("tuya").describe("Generic function to write Tuya data."),
481
409
  dpid: e.number().describe("Data point ID. 1-255 the datapoint ID."),
482
- dt: r(2).describe("Data type."),
483
- eval: e.optional(p()).describe("Javascript expression to transform the raw value."),
484
- script: e.optional(f()).describe("Relative path of a Javascript .js file.")
410
+ dt: l(2).describe("Data type.")
485
411
  })
486
412
  ]).refine((t) => !("eval" in t && "script" in t), {
487
413
  message: "eval and script should not both be present"
488
414
  });
489
415
  }
490
- function D(t) {
416
+ function Z(t) {
491
417
  return e.strictObject({
492
418
  $schema: e.optional(e.string()),
493
419
  schema: e.literal("resourceitem1.schema.json"),
494
420
  id: e.string(),
421
+ ddfvalidate: e.optional(e.boolean()),
495
422
  description: e.optional(e.string()).describe("Item description, better to do not use it."),
496
423
  comment: e.optional(e.string()).describe("TODO: What is this ? What the difference with description ?"),
497
- deprecated: e.optional(S()).describe("Date of deprecation, if the item is deprecated, it's better to use the new one."),
424
+ deprecated: e.optional(U()).describe("Date of deprecation, if the item is deprecated, it's better to use the new one."),
498
425
  datatype: e.optional(e.enum([
499
426
  "String",
500
427
  "Bool",
@@ -519,9 +446,9 @@ function D(t) {
519
446
  static: e.optional(e.union([e.string(), e.number(), e.boolean()])).describe("A static default value is fixed and can be not changed."),
520
447
  range: e.optional(e.tuple([e.number(), e.number()])).describe("Values range limit."),
521
448
  virtual: e.optional(e.boolean()).describe("TODO: What is this ?"),
522
- read: e.optional(Z()).describe("Fonction used to read value."),
523
- parse: e.optional(G(t)).describe("Fonction used to parse incoming values."),
524
- write: e.optional(R()).describe("Fonction used to write value."),
449
+ read: e.optional(V()).describe("Fonction used to read value."),
450
+ parse: e.optional(q(t)).describe("Fonction used to parse incoming values."),
451
+ write: e.optional(H()).describe("Fonction used to write value."),
525
452
  "refresh.interval": e.optional(e.number()).describe("Refresh interval used for read fonction, NEED to be superior at value used in binding part."),
526
453
  // TODO Validate this
527
454
  values: e.optional(e.unknown()).describe("TODO: What is this ?"),
@@ -529,11 +456,12 @@ function D(t) {
529
456
  default: e.optional(e.unknown()).describe("Defaut value.")
530
457
  });
531
458
  }
532
- function F(t) {
459
+ function J(t) {
533
460
  return e.strictObject({
534
461
  $schema: e.optional(e.string()),
535
462
  schema: e.literal("devcap1.schema.json"),
536
463
  uuid: e.optional(e.string()),
464
+ ddfvalidate: e.optional(e.boolean()),
537
465
  version: e.optional(e.string()),
538
466
  version_deconz: e.optional(e.string()),
539
467
  "doc:path": e.optional(e.string()),
@@ -552,32 +480,32 @@ function F(t) {
552
480
  modelid: e.string().or(e.array(e.string())).describe("Model ID from Basic Cluster."),
553
481
  vendor: e.optional(e.string()).describe("Friendly name of the manufacturer."),
554
482
  comment: e.optional(e.string()),
555
- matchexpr: e.optional(p()).describe("Need to return true for the DDF be used."),
556
- path: e.optional(f()).describe("DDF path, useless, can be removed."),
483
+ matchexpr: e.optional(F()).describe("Need to return true for the DDF be used."),
484
+ path: e.optional(A()).describe("DDF path, useless, can be removed."),
557
485
  product: e.optional(e.string()).describe("Complements the model id to be shown in the UI."),
558
486
  sleeper: e.optional(e.boolean()).describe("Sleeping devices can only receive when awake."),
559
487
  supportsMgmtBind: e.optional(e.boolean()),
560
488
  status: e.enum(["Draft", "Bronze", "Silver", "Gold"]).describe("The code quality of the DDF file."),
561
- subdevices: e.array(z(t)).describe("Devices section."),
562
- bindings: e.optional(e.array(L())).describe("Bindings section.")
489
+ subdevices: e.array(X(t)).describe("Devices section."),
490
+ bindings: e.optional(e.array(Q())).describe("Bindings section.")
563
491
  });
564
492
  }
565
- function z(t) {
493
+ function X(t) {
566
494
  return e.strictObject({
567
495
  type: e.union([
568
496
  e.enum(Object.keys(t.deviceTypes), {
569
- errorMap: (a, u) => a.code === "invalid_enum_value" ? { message: `Invalid enum value. Expected type from generic attributes definition, received '${a.received}'` } : { message: u.defaultError }
497
+ errorMap: (r, u) => r.code === "invalid_enum_value" ? { message: `Invalid enum value. Expected type from generic attributes definition, received '${r.received}'` } : { message: u.defaultError }
570
498
  }),
571
499
  e.string().regex(/^(?!\$TYPE_).*/g, "The type start with $TYPE_ but is not present in constants.json")
572
500
  ]),
573
501
  restapi: e.enum(["/lights", "/sensors"]),
574
- uuid: j(),
502
+ uuid: S(),
575
503
  fingerprint: e.optional(e.strictObject({
576
- profile: r(4),
577
- device: r(4),
578
- endpoint: m(),
579
- in: e.optional(e.array(r(4))),
580
- out: e.optional(e.array(r(4)))
504
+ profile: l(4),
505
+ device: l(4),
506
+ endpoint: g(),
507
+ in: e.optional(e.array(l(4))),
508
+ out: e.optional(e.array(l(4)))
581
509
  })),
582
510
  meta: e.optional(e.strictObject({
583
511
  // TODO validate this
@@ -588,140 +516,164 @@ function z(t) {
588
516
  buttons: e.optional(e.any()),
589
517
  // TODO validate this
590
518
  buttonevents: e.optional(e.any()),
591
- items: e.array(k(t)),
519
+ items: e.array(K(t)),
592
520
  example: e.optional(e.unknown())
593
521
  });
594
522
  }
595
- function k(t) {
596
- return D(t).omit({
523
+ function K(t) {
524
+ return Z(t).omit({
597
525
  $schema: !0,
598
526
  schema: !0,
599
527
  id: !0
600
528
  }).extend({
601
529
  name: e.enum(t.attributes, {
602
- errorMap: (a, u) => a.code === "invalid_enum_value" ? { message: `Invalid enum value. Expected item from generic attributes definition, received '${a.received}'` } : { message: u.defaultError }
530
+ errorMap: (r, u) => r.code === "invalid_enum_value" ? { message: `Invalid enum value. Expected item from generic attributes definition, received '${r.received}'` } : { message: u.defaultError }
603
531
  }).describe("Item name.")
604
532
  });
605
533
  }
606
- function L(t) {
534
+ function Q(t) {
607
535
  return e.discriminatedUnion("bind", [
608
536
  e.strictObject({
609
537
  bind: e.literal("unicast"),
610
- "src.ep": m().describe("Source endpoint."),
611
- "dst.ep": e.optional(m()).describe("Destination endpoint, generaly 0x01."),
612
- cl: r(4).describe("Cluster."),
538
+ "src.ep": g().describe("Source endpoint."),
539
+ "dst.ep": e.optional(g()).describe("Destination endpoint, generaly 0x01."),
540
+ cl: l(4).describe("Cluster."),
613
541
  report: e.optional(e.array(
614
542
  e.strictObject({
615
- at: r(4),
616
- dt: r(2),
617
- mf: e.optional(r(4)),
543
+ at: l(4),
544
+ dt: l(2),
545
+ mf: e.optional(l(4)),
618
546
  min: e.number(),
619
547
  max: e.number(),
620
- change: e.optional(r().or(e.number()))
621
- }).refine((a) => a.min <= a.max, { message: "invalid report time, min should be smaller than max" })
548
+ change: e.optional(l().or(e.number()))
549
+ }).refine((r) => r.min <= r.max, { message: "invalid report time, min should be smaller than max" })
622
550
  ))
623
551
  }),
624
552
  e.strictObject({
625
553
  bind: e.literal("groupcast"),
626
- "src.ep": m().describe("Source endpoint."),
627
- cl: r(4).describe("Cluster."),
554
+ "src.ep": g().describe("Source endpoint."),
555
+ cl: l(4).describe("Cluster."),
628
556
  "config.group": e.number().min(0).max(255)
629
557
  })
630
558
  ]);
631
559
  }
632
- function W(t) {
633
- const a = e.array(
560
+ function ee(t) {
561
+ const r = e.array(
634
562
  e.enum(t.attributes, {
635
- errorMap: (u, n) => u.code === "invalid_enum_value" ? { message: `Invalid enum value. Expected item from generic attributes definition, received '${u.received}'` } : { message: n.defaultError }
563
+ errorMap: (u, i) => u.code === "invalid_enum_value" ? { message: `Invalid enum value. Expected item from generic attributes definition, received '${u.received}'` } : { message: i.defaultError }
636
564
  })
637
565
  );
638
566
  return e.strictObject({
639
567
  $schema: e.optional(e.string()),
640
568
  schema: e.literal("subdevice1.schema.json"),
569
+ ddfvalidate: e.optional(e.boolean()),
641
570
  type: e.union([
642
571
  e.enum(Object.keys(t.deviceTypes), {
643
- errorMap: (u, n) => u.code === "invalid_enum_value" ? { message: `Invalid enum value. Expected type from generic attributes definition, received '${u.received}'` } : { message: n.defaultError }
572
+ errorMap: (u, i) => u.code === "invalid_enum_value" ? { message: `Invalid enum value. Expected type from generic attributes definition, received '${u.received}'` } : { message: i.defaultError }
644
573
  }),
645
574
  e.string().regex(/^(?!\$TYPE_).*/g, "The type start with $TYPE_ but is not present in constants.json")
646
575
  ]),
647
576
  name: e.string(),
648
577
  restapi: e.enum(["/lights", "/sensors"]),
649
578
  order: e.number(),
650
- uuid: j(),
651
- items: a,
652
- items_optional: e.optional(a)
579
+ uuid: S(),
580
+ items: r,
581
+ items_optional: e.optional(r)
653
582
  });
654
583
  }
655
- function x(t) {
584
+ function D(t) {
656
585
  return e.discriminatedUnion("schema", [
657
- F(t),
658
- M(),
659
- I(),
660
- D(t),
661
- W(t)
662
- ]).superRefine((a, u) => {
663
- switch (a.schema) {
586
+ J(t),
587
+ B(),
588
+ C(),
589
+ Z(t),
590
+ ee(t)
591
+ ]).superRefine((r, u) => {
592
+ switch (r.schema) {
664
593
  case "devcap1.schema.json":
665
- y[a.schema].map((n) => n(a, u, t));
594
+ O[r.schema].map((i) => i(r, u, t));
666
595
  break;
667
596
  case "constants2.schema.json":
668
- y[a.schema].map((n) => n(a, u, t));
597
+ O[r.schema].map((i) => i(r, u, t));
669
598
  break;
670
599
  }
671
600
  });
672
601
  }
673
- function B(t = {
602
+ function re(t = {
674
603
  attributes: [],
675
604
  manufacturers: {},
676
605
  deviceTypes: {},
677
606
  resources: {},
678
607
  subDevices: {}
679
608
  }) {
680
- let a = x(t);
609
+ let r = D(t);
681
610
  const u = () => {
682
- a = x(t);
683
- };
684
- return { generics: t, loadGeneric: (s) => {
685
- const o = a.parse(s);
686
- switch (o.schema) {
611
+ r = D(t);
612
+ }, i = (m) => [
613
+ "constants1.schema.json",
614
+ "constants2.schema.json",
615
+ "resourceitem1.schema.json",
616
+ "subdevice1.schema.json"
617
+ ].includes(m), c = (m) => m === "devcap1.schema.json", n = (m) => {
618
+ const s = r.parse(m);
619
+ switch (s.schema) {
687
620
  case "constants1.schema.json":
688
621
  t.manufacturers = {
689
622
  ...t.manufacturers,
690
- ...o.manufacturers
623
+ ...s.manufacturers
691
624
  }, t.deviceTypes = {
692
625
  ...t.deviceTypes,
693
- ...o["device-types"]
626
+ ...s["device-types"]
694
627
  };
695
628
  break;
696
629
  case "constants2.schema.json": {
697
- Object.keys(o).filter((c) => c.startsWith("$MF_")).forEach((c) => {
698
- t.manufacturers[c] = o[c];
699
- }), Object.keys(o).filter((c) => c.startsWith("$TYPE_")).forEach((c) => {
700
- t.deviceTypes[c] = o[c];
630
+ Object.keys(s).filter((o) => o.startsWith("$MF_")).forEach((o) => {
631
+ t.manufacturers[o] = s[o];
632
+ }), Object.keys(s).filter((o) => o.startsWith("$TYPE_")).forEach((o) => {
633
+ t.deviceTypes[o] = s[o];
701
634
  });
702
635
  break;
703
636
  }
704
637
  case "resourceitem1.schema.json": {
705
- if (t.attributes.includes(o.id))
706
- throw new Error(`Got duplicate resource item with attribute id '${o.id}'.`);
707
- const c = o, b = o.id;
708
- delete c.$schema, delete c.schema, delete c.id, t.resources[b] = c, t.attributes.push(b);
638
+ if (t.attributes.includes(s.id))
639
+ throw new Error(`Got duplicate resource item with attribute id '${s.id}'.`);
640
+ const o = s, p = s.id;
641
+ delete o.$schema, delete o.schema, delete o.id, t.resources[p] = o, t.attributes.push(p);
709
642
  break;
710
643
  }
711
644
  case "subdevice1.schema.json":
712
- t.subDevices[o.type] = o, t.subDevices[o.name] = o;
645
+ t.subDevices[s.type] = s, t.subDevices[s.name] = s;
713
646
  break;
714
647
  default:
715
- throw new Error(`Got invalid generic file, got data with schema '${o.schema}'.`);
648
+ throw new Error(`Got invalid generic file, got data with schema '${s.schema}'.`);
716
649
  }
717
650
  return u(), !0;
718
- }, validate: (s) => a.parse(s), getSchema: () => a, version: E, isGeneric: (s) => [
719
- "constants1.schema.json",
720
- "constants2.schema.json",
721
- "resourceitem1.schema.json",
722
- "subdevice1.schema.json"
723
- ].includes(s), isDDF: (s) => s === "devcap1.schema.json" };
651
+ }, d = (m) => r.parse(m);
652
+ return { generics: t, loadGeneric: n, validate: d, bulkValidate: (m, s, o = {}) => {
653
+ const p = (b, h) => {
654
+ var E, j, T;
655
+ let I = 0, _ = Number.POSITIVE_INFINITY, $ = b, v = [];
656
+ for ((E = o.onSectionStart) == null || E.call(o, h, b.length); v = [], (j = o.onSectionProgress) == null || j.call(o, h, 1, b.length), $.forEach((y) => {
657
+ var w;
658
+ (w = o.onSectionProgress) == null || w.call(o, h, I++, b.length);
659
+ try {
660
+ h === "generic" ? n(y.data) : h === "ddf" && d(y.data);
661
+ } catch (G) {
662
+ v.push({
663
+ ...y,
664
+ error: G
665
+ });
666
+ }
667
+ }), !(v.length === 0 || v.length >= _); )
668
+ I -= v.length, $ = v, _ = v.length;
669
+ return (T = o.onSectionEnd) == null || T.call(o, h, b.length, v), v;
670
+ };
671
+ return [
672
+ ...p(m, "generic"),
673
+ ...p(s, "ddf")
674
+ ];
675
+ }, getSchema: () => r, version: M, isGeneric: i, isDDF: c };
724
676
  }
725
677
  export {
726
- B as createValidator
678
+ re as createValidator
727
679
  };