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