@deconz-community/ddf-validator 1.3.0 → 2.0.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,474 +1,80 @@
1
1
  import { z as t } from "zod";
2
- const s = [
3
- "attr/class",
4
- "attr/configid",
5
- "attr/extaddress",
6
- "attr/groupaddress",
7
- "attr/id",
8
- "attr/lastannounced",
9
- "attr/lastseen",
10
- "attr/levelmin",
11
- "attr/manufacturername",
12
- "attr/modelid",
13
- "attr/name",
14
- "attr/nwkaddress",
15
- "attr/poweronct",
16
- "attr/poweronlevel",
17
- "attr/powerup",
18
- "attr/productid",
19
- "attr/productname",
20
- "attr/swconfigid",
21
- "attr/swversion",
22
- "attr/type",
23
- "attr/uniqueid",
24
- "state/action",
25
- "state/airquality",
26
- "state/airqualityppb",
27
- "state/alarm",
28
- "state/alert",
29
- "state/all_on",
30
- "state/angle",
31
- "state/any_on",
32
- "state/armstate",
33
- "state/battery",
34
- "state/bri",
35
- "state/buttonevent",
36
- "state/carbonmonoxide",
37
- "state/charging",
38
- "state/colormode",
39
- "state/consumption",
40
- "state/consumption_2",
41
- "state/ct",
42
- "state/current",
43
- "state/current_P1",
44
- "state/current_P2",
45
- "state/current_P3",
46
- "state/dark",
47
- "state/daylight",
48
- "state/deviceruntime",
49
- "state/effect",
50
- "state/errorcode",
51
- "state/eventduration",
52
- "state/expectedeventduration",
53
- "state/expectedrotation",
54
- "state/filterruntime",
55
- "state/fire",
56
- "state/flag",
57
- "state/floortemperature",
58
- "state/gpd_frame_counter",
59
- "state/gpd_last_pair",
60
- "state/gesture",
61
- "state/gradient",
62
- "state/heating",
63
- "state/hue",
64
- "state/humidity",
65
- "state/lastcheckin",
66
- "state/lastset",
67
- "state/lastupdated",
68
- "state/lift",
69
- "state/lightlevel",
70
- "state/localtime",
71
- "state/lockstate",
72
- "state/lowbattery",
73
- "state/lux",
74
- "state/moisture",
75
- "state/mountingmodeactive",
76
- "state/on",
77
- "state/open",
78
- "state/orientation_x",
79
- "state/orientation_y",
80
- "state/orientation_z",
81
- "state/pm2_5",
82
- "state/panel",
83
- "state/power",
84
- "state/presence",
85
- "state/presenceevent",
86
- "state/pressure",
87
- "state/production",
88
- "state/reachable",
89
- "state/replacefilter",
90
- "state/rotaryevent",
91
- "state/sat",
92
- "state/seconds_remaining",
93
- "state/spectral_x",
94
- "state/spectral_y",
95
- "state/spectral_z",
96
- "state/speed",
97
- "state/status",
98
- "state/sunrise",
99
- "state/sunset",
100
- "state/tampered",
101
- "state/temperature",
102
- "state/test",
103
- "state/tilt",
104
- "state/tiltangle",
105
- "state/utc",
106
- "state/valve",
107
- "state/vibration",
108
- "state/vibrationstrength",
109
- "state/voltage",
110
- "state/water",
111
- "state/windowopen",
112
- "state/x",
113
- "state/y",
114
- "cap/alert/trigger_effect",
115
- "cap/bri/min_dim_level",
116
- "cap/bri/move_with_onoff",
117
- "cap/color/capabilities",
118
- "cap/color/ct/computes_xy",
119
- "cap/color/ct/max",
120
- "cap/color/ct/min",
121
- "cap/color/effects",
122
- "cap/color/gamut_type",
123
- "cap/color/gradient/max_segments",
124
- "cap/color/gradient/pixel_count",
125
- "cap/color/gradient/pixel_length",
126
- "cap/color/gradient/styles",
127
- "cap/color/xy/blue_x",
128
- "cap/color/xy/blue_y",
129
- "cap/color/xy/green_x",
130
- "cap/color/xy/green_y",
131
- "cap/color/xy/red_x",
132
- "cap/color/xy/red_y",
133
- "cap/groups/not_supported",
134
- "cap/on/off_with_effect",
135
- "cap/sleeper",
136
- "cap/transition_block",
137
- "config/alarmsystemid",
138
- "config/alert",
139
- "config/allowtouchlink",
140
- "config/armmode",
141
- "config/armed_away_entry_delay",
142
- "config/armed_away_exit_delay",
143
- "config/armed_away_trigger_duration",
144
- "config/armed_night_entry_delay",
145
- "config/armed_night_exit_delay",
146
- "config/armed_night_trigger_duration",
147
- "config/armed_stay_entry_delay",
148
- "config/armed_stay_exit_delay",
149
- "config/armed_stay_trigger_duration",
150
- "config/battery",
151
- "config/bri/execute_if_off",
152
- "config/bri/max",
153
- "config/bri/min",
154
- "config/bri/on_level",
155
- "config/bri/onoff_transitiontime",
156
- "config/bri/startup",
157
- "config/checkin",
158
- "config/clickmode",
159
- "config/colorcapabilities",
160
- "config/color/ct/startup",
161
- "config/color/execute_if_off",
162
- "config/color/gradient/reversed",
163
- "config/color/xy/startup_x",
164
- "config/color/xy/startup_y",
165
- "config/configured",
166
- "config/controlsequence",
167
- "config/coolsetpoint",
168
- "config/ctmax",
169
- "config/ctmin",
170
- "config/delay",
171
- "config/devicemode",
172
- "config/disarmed_entry_delay",
173
- "config/disarmed_exit_delay",
174
- "config/displayflipped",
175
- "config/duration",
176
- "config/enrolled",
177
- "config/externalsensortemp",
178
- "config/externalwindowopen",
179
- "config/fanmode",
180
- "config/filterlifetime",
181
- "config/gpd_device_id",
182
- "config/gpd_key",
183
- "config/group",
184
- "config/heatsetpoint",
185
- "config/hostflags",
186
- "config/humiditymaxthreshold",
187
- "config/humidityminthreshold",
188
- "config/interfacemode",
189
- "config/lastchange_amount",
190
- "config/lastchange_source",
191
- "config/lastchange_time",
192
- "config/lat",
193
- "config/ledindication",
194
- "config/localtime",
195
- "config/lock",
196
- "config/locked",
197
- "config/long",
198
- "config/melody",
199
- "config/mode",
200
- "config/mountingmode",
201
- "config/offset",
202
- "config/on",
203
- "config/on/startup",
204
- "config/pending",
205
- "config/preset",
206
- "config/pulseconfiguration",
207
- "config/reachable",
208
- "config/resetpresence",
209
- "config/schedule",
210
- "config/schedule_on",
211
- "config/selftest",
212
- "config/sensitivity",
213
- "config/sensitivitymax",
214
- "config/setvalve",
215
- "config/sunriseoffset",
216
- "config/sunsetoffset",
217
- "config/swingmode",
218
- "config/temperaturemaxthreshold",
219
- "config/temperatureminthreshold",
220
- "config/temperature",
221
- "config/temperaturemeasurement",
222
- "config/tholddark",
223
- "config/tholdoffset",
224
- "config/unoccupiedheatsetpoint",
225
- "config/triggerdistance",
226
- "config/ubisys_j1_additionalsteps",
227
- "config/ubisys_j1_configurationandstatus",
228
- "config/ubisys_j1_inactivepowerthreshold",
229
- "config/ubisys_j1_installedclosedlimitlift",
230
- "config/ubisys_j1_installedclosedlimittilt",
231
- "config/ubisys_j1_installedopenlimitlift",
232
- "config/ubisys_j1_installedopenlimittilt",
233
- "config/ubisys_j1_lifttotilttransitionsteps",
234
- "config/ubisys_j1_lifttotilttransitionsteps2",
235
- "config/ubisys_j1_mode",
236
- "config/ubisys_j1_startupsteps",
237
- "config/ubisys_j1_totalsteps",
238
- "config/ubisys_j1_totalsteps2",
239
- "config/ubisys_j1_turnaroundguardtime",
240
- "config/ubisys_j1_windowcoveringtype",
241
- "config/url",
242
- "config/usertest",
243
- "config/volume",
244
- "config/windowcoveringtype",
245
- "config/windowopen_set",
246
- // Missing from resource.cpp
247
- "attr/mode",
248
- "state/orientation",
249
- // Just present in at least one DDF
250
- "state/airqualityformaldehyde",
251
- "state/airqualityco2"
252
- ], c = [
253
- "$TYPE_AIR_PURIFIER",
254
- "$TYPE_AIR_QUALITY_SENSOR",
255
- "$TYPE_ALARM_SENSOR",
256
- "$TYPE_BATTERY_SENSOR",
257
- "$TYPE_COLOR_DIMMABLE_LIGHT",
258
- "$TYPE_COLOR_LIGHT",
259
- "$TYPE_COLOR_TEMPERATURE_LIGHT",
260
- "$TYPE_CONSUMPTION_SENSOR",
261
- "$TYPE_DIMMABLE_LIGHT",
262
- "$TYPE_DIMMABLE_PLUGIN_UNIT",
263
- "$TYPE_DIMMER_SWITCH",
264
- "$TYPE_DOOR_LOCK",
265
- "$TYPE_DOOR_LOCK_CONTROLLER",
266
- "$TYPE_EXTENDED_COLOR_LIGHT",
267
- "$TYPE_FIRE_SENSOR",
268
- "$TYPE_HUMIDITY_SENSOR",
269
- "$TYPE_LIGHT_LEVEL_SENSOR",
270
- "$TYPE_ON_OFF_LIGHT",
271
- "$TYPE_ON_OFF_OUTPUT",
272
- "$TYPE_ON_OFF_PLUGIN_UNIT",
273
- "$TYPE_OPEN_CLOSE_SENSOR",
274
- "$TYPE_POWER_SENSOR",
275
- "$TYPE_PRESENCE_SENSOR",
276
- "$TYPE_PRESSURE_SENSOR",
277
- "$TYPE_RANGE_EXTENDER",
278
- "$TYPE_RELATIVE_ROTARY",
279
- "$TYPE_SMART_PLUG",
280
- "$TYPE_SPECTRAL_SENSOR",
281
- "$TYPE_SWITCH",
282
- "$TYPE_TEMPERATURE_SENSOR",
283
- "$TYPE_THERMOSTAT",
284
- "$TYPE_VIBRATION_SENSOR",
285
- "$TYPE_WARNING_DEVICE",
286
- "$TYPE_WATER_LEAK_SENSOR",
287
- "$TYPE_WINDOW_COVERING_DEVICE",
288
- "$TYPE_ZGP_SWITCH",
289
- "Color dimmable light",
290
- "Color light",
291
- "Color temperature light",
292
- "Dimmable light",
293
- "Dimmable plug-in unit",
294
- "Dimmer switch",
295
- "Door lock controller",
296
- "Door Lock",
297
- "Extended color light",
298
- "On/Off light",
299
- "On/Off output",
300
- "On/Off plug-in unit",
301
- "Range extender",
302
- "Smart plug",
303
- "Warning device",
304
- "Window covering device",
305
- "ZGPSwitch",
306
- "ZHAAirPurifier",
307
- "ZHAAirQuality",
308
- "ZHAAlarm",
309
- "ZHAAncillaryControl",
310
- "ZHABattery",
311
- "ZHACarbonMonoxide",
312
- "ZHAConsumption",
313
- "ZHADoorLock",
314
- "ZHAFire",
315
- "ZHAHumidity",
316
- "ZHALightLevel",
317
- "ZHAOpenClose",
318
- "ZHAPower",
319
- "ZHAPresence",
320
- "ZHAPressure",
321
- "ZHARelativeRotary",
322
- "ZHASpectral",
323
- "ZHASwitch",
324
- "ZHATemperature",
325
- "ZHAThermostat",
326
- "ZHATime",
327
- "ZHAVibration",
328
- "ZHAWater"
329
- ];
330
- function e(n = void 0) {
331
- return n === void 0 ? t.string() : t.string().length(2 + n);
2
+ function v(e) {
3
+ return t.strictObject({
4
+ $schema: t.optional(t.string()),
5
+ schema: t.literal("constants1.schema.json"),
6
+ manufacturers: t.record(t.string().startsWith("$MF_"), t.string()),
7
+ "device-types": t.record(t.string().startsWith("$TYPE_"), t.string())
8
+ });
332
9
  }
333
- function o() {
334
- return t.string();
10
+ function m() {
11
+ return t.string().regex(
12
+ // Regex for AAAA-MM-JJ
13
+ /^(\d{4})-(?:(?:0[1-9])|(?:1[0-2]))-(?:(?:0[1-9])|(?:[12][0-9])|(?:3[01]))$/,
14
+ "Invalid date value"
15
+ );
335
16
  }
336
- function l() {
337
- return t.string();
17
+ function n(e = void 0) {
18
+ const i = "Invalid hexadecimal value";
19
+ return e === void 0 ? t.string().regex(/^0x[0-9a-fA-F]+$/, i) : t.string().regex(new RegExp(`^0x[0-9a-fA-F]{${e}}$`), i);
338
20
  }
339
- function i() {
21
+ function a() {
340
22
  return t.union([
341
- e(2),
23
+ n(2),
342
24
  t.number().min(0).max(255)
343
25
  ]);
344
26
  }
345
- function a() {
346
- return t.string();
347
- }
348
- function _() {
349
- return t.custom((n) => {
350
- if (!Array.isArray(n) || n.length % 2 !== 0)
27
+ function g() {
28
+ return t.custom((e) => {
29
+ if (!Array.isArray(e) || e.length % 2 !== 0)
351
30
  return !1;
352
- for (let r = 0; r < n.length; r += 2) {
353
- const m = n[r], d = n[r + 1];
354
- if (typeof m != "number" || typeof d != "string")
31
+ for (let i = 0; i < e.length; i += 2) {
32
+ const l = e[i], p = e[i + 1];
33
+ if (typeof l != "number" || typeof p != "string")
355
34
  return !1;
356
35
  }
357
36
  return !0;
358
37
  }, "The value must be an array with an even number of values and alternating between number and string.");
359
38
  }
360
- function p() {
39
+ function d() {
361
40
  return t.union([
362
41
  t.tuple([
363
42
  t.literal("$address.ext"),
364
- e(2)
43
+ n(2)
365
44
  ]),
366
45
  t.tuple([
367
46
  t.literal("$address.ext"),
368
- e(2),
369
- e(4)
47
+ n(2),
48
+ n(4)
370
49
  ])
371
50
  ]);
372
51
  }
373
- function A(n) {
374
- return b().parse(n);
375
- }
376
- function b() {
377
- return t.discriminatedUnion("schema", [
378
- y(),
379
- v(),
380
- O(),
381
- P()
382
- ]);
383
- }
384
- function y() {
385
- return t.strictObject({
386
- $schema: t.optional(t.string()),
387
- schema: t.literal("devcap1.schema.json"),
388
- "doc:path": t.optional(t.string()),
389
- "doc:hdr": t.optional(t.string()),
390
- "md:known_issues": t.optional(t.array(t.string())),
391
- manufacturername: t.string().or(t.array(t.string())),
392
- modelid: t.string().or(t.array(t.string())),
393
- vendor: t.optional(t.string()),
394
- comment: t.optional(t.string()),
395
- matchexpr: t.optional(o()),
396
- path: t.optional(a()),
397
- product: t.optional(t.string()),
398
- sleeper: t.optional(t.boolean()),
399
- supportsMgmtBind: t.optional(t.boolean()),
400
- status: t.enum(["Draft", "Bronze", "Silver", "Gold"]).describe("The code quality of the DDF file."),
401
- subdevices: t.array(h()),
402
- bindings: t.optional(t.array(T()))
403
- }).refine((n) => typeof n.manufacturername == "string" && typeof n.modelid == "string" || Array.isArray(n.manufacturername) && Array.isArray(n.modelid) && n.manufacturername.length === n.modelid.length, {
404
- message: "manufacturername and modelid should be both strings or arrays with the same length.",
405
- path: ["manufacturername", "modelid"]
406
- }).innerType();
407
- }
408
- function h() {
409
- return t.strictObject({
410
- type: t.enum(c),
411
- restapi: t.enum(["/lights", "/sensors"]),
412
- uuid: p(),
413
- fingerprint: t.optional(t.strictObject({
414
- profile: e(4),
415
- device: e(4),
416
- endpoint: i(),
417
- in: t.optional(t.array(e(4))),
418
- out: t.optional(t.array(e(4)))
419
- })),
420
- meta: t.optional(t.strictObject({
421
- // TODO validate this
422
- values: t.any(),
423
- "group.endpoints": t.optional(t.array(t.number()))
424
- })),
425
- // TODO validate this
426
- buttons: t.optional(t.any()),
427
- // TODO validate this
428
- buttonevents: t.optional(t.any()),
429
- items: t.array(E()),
430
- example: t.optional(t.unknown())
431
- });
52
+ function o() {
53
+ return t.string();
432
54
  }
433
- function E() {
434
- return t.strictObject({
435
- name: t.enum(s),
436
- description: t.optional(t.string()),
437
- comment: t.optional(t.string()),
438
- public: t.optional(t.boolean()),
439
- static: t.optional(t.union([t.string(), t.number(), t.boolean()])),
440
- range: t.optional(t.tuple([t.number(), t.number()])),
441
- deprecated: t.optional(l()),
442
- access: t.optional(t.literal("R")),
443
- read: t.optional(u()),
444
- parse: t.optional(f()),
445
- write: t.optional(g()),
446
- awake: t.optional(t.boolean()),
447
- default: t.optional(t.unknown()),
448
- values: t.optional(t.unknown()),
449
- "refresh.interval": t.optional(t.number())
450
- });
55
+ function r() {
56
+ return t.string();
451
57
  }
452
- function u() {
58
+ function b() {
453
59
  return t.discriminatedUnion("fn", [
454
60
  t.strictObject({
455
61
  fn: t.literal("none")
456
62
  }),
457
63
  t.strictObject({
458
64
  fn: t.undefined(),
459
- at: t.optional(e(4).or(t.array(e(4)))),
460
- cl: e(4),
461
- ep: t.optional(i()),
462
- mf: t.optional(e(4)),
463
- eval: t.optional(o())
65
+ at: t.optional(n(4).or(t.array(n(4)))),
66
+ cl: n(4),
67
+ ep: t.optional(a()),
68
+ mf: t.optional(n(4)),
69
+ eval: t.optional(r())
464
70
  }),
465
71
  t.strictObject({
466
72
  fn: t.literal("zcl"),
467
- at: t.optional(e(4).or(t.array(e(4)))),
468
- cl: e(4),
469
- ep: t.optional(i()),
470
- mf: t.optional(e(4)),
471
- eval: t.optional(o())
73
+ at: t.optional(n(4).or(t.array(n(4)))),
74
+ cl: n(4),
75
+ ep: t.optional(a()),
76
+ mf: t.optional(n(4)),
77
+ eval: t.optional(r())
472
78
  }),
473
79
  t.strictObject({
474
80
  fn: t.literal("tuya")
@@ -479,28 +85,28 @@ function f() {
479
85
  return t.discriminatedUnion("fn", [
480
86
  t.strictObject({
481
87
  fn: t.undefined(),
482
- at: t.optional(e(4)),
483
- cl: e(4),
88
+ at: t.optional(n(4)),
89
+ cl: n(4),
484
90
  cppsrc: t.optional(t.string()),
485
- ep: t.optional(i()),
486
- cmd: t.optional(e(2)),
487
- mf: t.optional(e(4)),
488
- eval: t.optional(o()),
489
- script: t.optional(a())
490
- }).refine((n) => !("eval" in n && "script" in n), {
91
+ ep: t.optional(a()),
92
+ cmd: t.optional(n(2)),
93
+ mf: t.optional(n(4)),
94
+ eval: t.optional(r()),
95
+ script: t.optional(o())
96
+ }).refine((e) => !("eval" in e && "script" in e), {
491
97
  message: "eval and script should not both be present"
492
98
  }).innerType(),
493
99
  t.strictObject({
494
100
  fn: t.literal("zcl"),
495
- at: t.optional(e(4)),
496
- cl: e(4),
101
+ at: t.optional(n(4)),
102
+ cl: n(4),
497
103
  cppsrc: t.optional(t.string()),
498
- ep: t.optional(i()),
499
- cmd: t.optional(e(2)),
500
- mf: t.optional(e(4)),
501
- eval: t.optional(o()),
502
- script: t.optional(a())
503
- }).refine((n) => !("eval" in n && "script" in n), {
104
+ ep: t.optional(a()),
105
+ cmd: t.optional(n(2)),
106
+ mf: t.optional(n(4)),
107
+ eval: t.optional(r()),
108
+ script: t.optional(o())
109
+ }).refine((e) => !("eval" in e && "script" in e), {
504
110
  message: "eval and script should not both be present"
505
111
  }).innerType(),
506
112
  t.strictObject({
@@ -511,114 +117,177 @@ function f() {
511
117
  fn: t.literal("numtostr"),
512
118
  srcitem: t.enum(["state/airqualityppb", "state/pm2_5"]),
513
119
  op: t.literal("le"),
514
- to: _()
120
+ to: g()
515
121
  }),
516
122
  t.strictObject({
517
123
  fn: t.literal("time")
518
124
  }),
519
125
  t.strictObject({
520
126
  fn: t.literal("xiaomi:special"),
521
- ep: t.optional(i()),
522
- at: t.optional(e(4)),
523
- idx: e(2),
524
- eval: t.optional(o()),
525
- script: t.optional(a())
526
- }).refine((n) => !("eval" in n && "script" in n), {
127
+ ep: t.optional(a()),
128
+ at: t.optional(n(4)),
129
+ idx: n(2),
130
+ eval: t.optional(r()),
131
+ script: t.optional(o())
132
+ }).refine((e) => !("eval" in e && "script" in e), {
527
133
  message: "eval and script should not both be present"
528
134
  }).innerType(),
529
135
  t.strictObject({
530
136
  fn: t.literal("tuya"),
531
137
  dpid: t.number(),
532
- eval: t.optional(o()),
533
- script: t.optional(a())
534
- }).refine((n) => !("eval" in n && "script" in n), {
138
+ eval: t.optional(r()),
139
+ script: t.optional(o())
140
+ }).refine((e) => !("eval" in e && "script" in e), {
535
141
  message: "eval and script should not both be present"
536
142
  }).innerType()
537
143
  ]);
538
144
  }
539
- function g() {
145
+ function h() {
540
146
  return t.discriminatedUnion("fn", [
541
147
  t.strictObject({
542
148
  fn: t.literal("none")
543
149
  }),
544
150
  t.strictObject({
545
151
  fn: t.undefined(),
546
- at: t.optional(e(4).or(t.array(e(4)))),
152
+ at: t.optional(n(4).or(t.array(n(4)))),
547
153
  "state.timeout": t.optional(t.number()),
548
154
  "change.timeout": t.optional(t.number()),
549
- cl: e(4),
550
- dt: e(2),
551
- ep: t.optional(i()),
552
- mf: t.optional(e(4)),
553
- eval: t.optional(o()),
554
- script: t.optional(a())
555
- }).refine((n) => !("eval" in n && "script" in n), {
155
+ cl: n(4),
156
+ dt: n(2),
157
+ ep: t.optional(a()),
158
+ mf: t.optional(n(4)),
159
+ eval: t.optional(r()),
160
+ script: t.optional(o())
161
+ }).refine((e) => !("eval" in e && "script" in e), {
556
162
  message: "eval and script should not both be present"
557
163
  }).innerType(),
558
164
  t.strictObject({
559
165
  fn: t.literal("zcl"),
560
- at: t.optional(e(4).or(t.array(e(4)))),
166
+ at: t.optional(n(4).or(t.array(n(4)))),
561
167
  "state.timeout": t.optional(t.number()),
562
168
  "change.timeout": t.optional(t.number()),
563
- cl: e(4),
564
- dt: e(2),
565
- ep: t.optional(i()),
566
- mf: t.optional(e(4)),
567
- eval: t.optional(o()),
568
- script: t.optional(a())
569
- }).refine((n) => !("eval" in n && "script" in n), {
169
+ cl: n(4),
170
+ dt: n(2),
171
+ ep: t.optional(a()),
172
+ mf: t.optional(n(4)),
173
+ eval: t.optional(r()),
174
+ script: t.optional(o())
175
+ }).refine((e) => !("eval" in e && "script" in e), {
570
176
  message: "eval and script should not both be present"
571
177
  }).innerType(),
572
178
  t.strictObject({
573
179
  fn: t.literal("tuya"),
574
180
  dpid: t.number(),
575
- dt: e(2),
576
- eval: t.optional(o()),
577
- script: t.optional(a())
578
- }).refine((n) => !("eval" in n && "script" in n), {
181
+ dt: n(2),
182
+ eval: t.optional(r()),
183
+ script: t.optional(o())
184
+ }).refine((e) => !("eval" in e && "script" in e), {
579
185
  message: "eval and script should not both be present"
580
186
  }).innerType()
581
187
  ]);
582
188
  }
583
- function T() {
189
+ function y(e) {
190
+ return t.strictObject({
191
+ $schema: t.optional(t.string()),
192
+ schema: t.literal("devcap1.schema.json"),
193
+ "doc:path": t.optional(t.string()),
194
+ "doc:hdr": t.optional(t.string()),
195
+ "md:known_issues": t.optional(t.array(t.string())),
196
+ manufacturername: t.string().or(t.array(t.string())),
197
+ modelid: t.string().or(t.array(t.string())),
198
+ vendor: t.optional(t.string()),
199
+ comment: t.optional(t.string()),
200
+ matchexpr: t.optional(r()),
201
+ path: t.optional(o()),
202
+ product: t.optional(t.string()),
203
+ sleeper: t.optional(t.boolean()),
204
+ supportsMgmtBind: t.optional(t.boolean()),
205
+ status: t.enum(["Draft", "Bronze", "Silver", "Gold"]).describe("The code quality of the DDF file."),
206
+ subdevices: t.array(j(e)),
207
+ bindings: t.optional(t.array(T()))
208
+ }).refine((i) => typeof i.manufacturername == "string" && typeof i.modelid == "string" || Array.isArray(i.manufacturername) && Array.isArray(i.modelid) && i.manufacturername.length === i.modelid.length, {
209
+ message: "manufacturername and modelid should be both strings or arrays with the same length.",
210
+ path: ["manufacturername", "modelid"]
211
+ }).innerType();
212
+ }
213
+ function j(e) {
214
+ return t.strictObject({
215
+ type: t.union([
216
+ t.enum(Object.keys(e.deviceTypes)),
217
+ t.enum(Object.values(e.deviceTypes))
218
+ ]),
219
+ restapi: t.enum(["/lights", "/sensors"]),
220
+ uuid: d(),
221
+ fingerprint: t.optional(t.strictObject({
222
+ profile: n(4),
223
+ device: n(4),
224
+ endpoint: a(),
225
+ in: t.optional(t.array(n(4))),
226
+ out: t.optional(t.array(n(4)))
227
+ })),
228
+ meta: t.optional(t.strictObject({
229
+ // TODO validate this
230
+ values: t.any(),
231
+ "group.endpoints": t.optional(t.array(t.number()))
232
+ })),
233
+ // TODO validate this
234
+ buttons: t.optional(t.any()),
235
+ // TODO validate this
236
+ buttonevents: t.optional(t.any()),
237
+ items: t.array(O(e)),
238
+ example: t.optional(t.unknown())
239
+ });
240
+ }
241
+ function O(e) {
242
+ return t.strictObject({
243
+ name: t.enum(e.attributes),
244
+ description: t.optional(t.string()),
245
+ comment: t.optional(t.string()),
246
+ public: t.optional(t.boolean()),
247
+ static: t.optional(t.union([t.string(), t.number(), t.boolean()])),
248
+ range: t.optional(t.tuple([t.number(), t.number()])),
249
+ deprecated: t.optional(m()),
250
+ access: t.optional(t.literal("R")),
251
+ read: t.optional(b()),
252
+ parse: t.optional(f()),
253
+ write: t.optional(h()),
254
+ awake: t.optional(t.boolean()),
255
+ default: t.optional(t.unknown()),
256
+ values: t.optional(t.unknown()),
257
+ "refresh.interval": t.optional(t.number())
258
+ });
259
+ }
260
+ function T(e) {
584
261
  return t.discriminatedUnion("bind", [
585
262
  t.strictObject({
586
263
  bind: t.literal("unicast"),
587
- "src.ep": i(),
588
- "dst.ep": t.optional(i()),
589
- cl: e(4),
264
+ "src.ep": a(),
265
+ "dst.ep": t.optional(a()),
266
+ cl: n(4),
590
267
  report: t.optional(t.array(t.strictObject({
591
- at: e(4),
592
- dt: e(2),
593
- mf: t.optional(e(4)),
268
+ at: n(4),
269
+ dt: n(2),
270
+ mf: t.optional(n(4)),
594
271
  min: t.number(),
595
272
  max: t.number(),
596
- change: t.optional(e().or(t.number()))
273
+ change: t.optional(n().or(t.number()))
597
274
  })))
598
275
  }),
599
276
  t.strictObject({
600
277
  bind: t.literal("groupcast"),
601
- "src.ep": i(),
602
- cl: e(4),
278
+ "src.ep": a(),
279
+ cl: n(4),
603
280
  "config.group": t.number()
604
281
  })
605
282
  ]);
606
283
  }
607
- function v() {
608
- return t.strictObject({
609
- $schema: t.optional(t.string()),
610
- schema: t.literal("constants1.schema.json"),
611
- manufacturers: t.record(t.string().startsWith("$MF_"), t.string()),
612
- "device-types": t.record(t.string().startsWith("$TYPE_"), t.string())
613
- });
614
- }
615
- function O() {
284
+ function w(e) {
616
285
  return t.strictObject({
617
286
  $schema: t.optional(t.string()),
618
287
  schema: t.literal("resourceitem1.schema.json"),
619
288
  id: t.string(),
620
289
  description: t.string(),
621
- deprecated: t.optional(l()),
290
+ deprecated: t.optional(m()),
622
291
  datatype: t.enum(["String", "Bool", "Int8", "Int16", "Int32", "Int64", "UInt8", "UInt16", "UInt32", "UInt64", "Array", "Array[3]", "ISO 8601 timestamp"]),
623
292
  access: t.enum(["R", "W", "RW"]),
624
293
  public: t.boolean(),
@@ -627,8 +296,8 @@ function O() {
627
296
  static: t.optional(t.boolean()),
628
297
  virtual: t.optional(t.boolean()),
629
298
  parse: t.optional(f()),
630
- read: t.optional(u()),
631
- write: t.optional(g()),
299
+ read: t.optional(b()),
300
+ write: t.optional(h()),
632
301
  "refresh.interval": t.optional(t.number()),
633
302
  // TODO Validate this
634
303
  values: t.optional(t.unknown()),
@@ -636,18 +305,54 @@ function O() {
636
305
  default: t.optional(t.unknown())
637
306
  });
638
307
  }
639
- function P() {
308
+ function x(e) {
640
309
  return t.strictObject({
641
310
  $schema: t.optional(t.string()),
642
311
  schema: t.literal("subdevice1.schema.json"),
643
- type: t.enum(c),
644
- name: t.string(),
312
+ type: t.enum(Object.keys(e.deviceTypes)),
313
+ name: t.enum(Object.values(e.deviceTypes)),
645
314
  restapi: t.enum(["/lights", "/sensors"]),
646
315
  order: t.number(),
647
- uuid: p(),
648
- items: t.array(t.enum(s))
316
+ uuid: d(),
317
+ items: t.array(t.enum(e.attributes))
649
318
  });
650
319
  }
320
+ function u(e) {
321
+ return t.discriminatedUnion("schema", [
322
+ y(e),
323
+ v(),
324
+ w(),
325
+ x(e)
326
+ ]);
327
+ }
328
+ function I(e = { attributes: [], manufacturers: {}, deviceTypes: {} }) {
329
+ let i = u(e);
330
+ const l = () => {
331
+ i = u(e);
332
+ };
333
+ return { generics: e, loadGeneric: (c) => {
334
+ const s = i.parse(c);
335
+ switch (s.schema) {
336
+ case "constants1.schema.json":
337
+ e.manufacturers = {
338
+ ...e.manufacturers,
339
+ ...s.manufacturers
340
+ }, e.deviceTypes = {
341
+ ...e.deviceTypes,
342
+ ...s["device-types"]
343
+ };
344
+ break;
345
+ case "resourceitem1.schema.json":
346
+ e.attributes.includes(s.id) || e.attributes.push(s.id);
347
+ break;
348
+ case "subdevice1.schema.json":
349
+ break;
350
+ case "devcap1.schema.json":
351
+ throw new Error("Got invalid generic file, got data with schema 'devcap1.schema.json'.");
352
+ }
353
+ return l(), s;
354
+ }, validate: (c) => i.parse(c), getSchema: () => i };
355
+ }
651
356
  export {
652
- A as validate
357
+ I as createValidator
653
358
  };