@deconz-community/ddf-validator 1.2.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.
- package/README.md +134 -19
- package/dist/ddf-schema.json +1 -1
- package/dist/ddf-validator.cjs +1 -1
- package/dist/ddf-validator.d.ts +157 -4
- package/dist/ddf-validator.mjs +266 -255
- package/package.json +1 -2
package/README.md
CHANGED
|
@@ -21,19 +21,47 @@ Example :
|
|
|
21
21
|
import { readFile } from 'fs/promises'
|
|
22
22
|
import glob from 'glob'
|
|
23
23
|
import { fromZodError } from 'zod-validation-error'
|
|
24
|
-
import {
|
|
24
|
+
import { validator } from '@deconz-community/ddf-validator'
|
|
25
25
|
|
|
26
26
|
(async () => {
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
|
|
28
|
+
const validator = createValidator()
|
|
29
|
+
|
|
30
|
+
const genericFiles = await glob('test-data/generic/**/*.json')
|
|
31
|
+
const ddfFiles = await glob('test-data/**/*.json', {
|
|
32
|
+
ignore: '**/generic/**',
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
const genericFilesData = await Promise.all(genericFiles.map(
|
|
36
|
+
async (filePath) => {
|
|
37
|
+
const data = await readFile(filePath, 'utf-8')
|
|
38
|
+
const decoded = JSON.parse(data)
|
|
39
|
+
return { path: filePath, data: decoded }
|
|
40
|
+
},
|
|
41
|
+
))
|
|
42
|
+
|
|
43
|
+
// Sort to load consts first
|
|
44
|
+
genericFilesData.sort((a, b) => a.data.schema.localeCompare(b.data.schema))
|
|
45
|
+
|
|
46
|
+
genericFilesData.forEach((file) => {
|
|
47
|
+
try {
|
|
48
|
+
const result = validator.loadGeneric(file.data)
|
|
49
|
+
console.log(`Loaded generic file${file.path}`)
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
console.error(`Error while loading file ${file.path} : ${fromZodError(error).message}`)
|
|
53
|
+
}
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
ddfFiles.forEach((filePath) => {
|
|
29
57
|
const data = await readFile(filePath, 'utf-8')
|
|
30
58
|
const decoded = JSON.parse(data)
|
|
31
59
|
try {
|
|
32
|
-
const result = validate(decoded)
|
|
33
|
-
console.log(
|
|
60
|
+
const result = validator.validate(decoded)
|
|
61
|
+
console.log(`Validated file ${file.path}`)
|
|
34
62
|
}
|
|
35
63
|
catch (error) {
|
|
36
|
-
|
|
64
|
+
console.error(`Error while validating file ${file.path} : ${fromZodError(error).message}`)
|
|
37
65
|
}
|
|
38
66
|
})
|
|
39
67
|
})()
|
|
@@ -41,35 +69,122 @@ import { validate } from '@deconz-community/ddf-validator'
|
|
|
41
69
|
|
|
42
70
|
## API
|
|
43
71
|
|
|
44
|
-
###
|
|
72
|
+
### createValidator()
|
|
45
73
|
|
|
46
74
|
Main function to validate the DDF data object.
|
|
47
75
|
|
|
48
76
|
#### Arguments
|
|
49
|
-
- `
|
|
77
|
+
- `generics` - : GenericsData; Base generic data to validate DDF.
|
|
78
|
+
|
|
79
|
+
#### Return
|
|
80
|
+
Return a new validator instance.
|
|
50
81
|
|
|
51
82
|
#### Example
|
|
52
83
|
|
|
53
84
|
```typescript
|
|
54
|
-
import {
|
|
55
|
-
|
|
85
|
+
import { createValidator } from '@deconz-community/ddf-validator'
|
|
86
|
+
|
|
87
|
+
const validator = createValidator({
|
|
88
|
+
attributes: ['attr/id']
|
|
89
|
+
manufacturers: { "$MF_FOO": "Foo inc." }
|
|
90
|
+
deviceTypes: { "$TYPE_COLOR_LIGHT": "Color light" }
|
|
91
|
+
})
|
|
92
|
+
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
### validator.generics
|
|
97
|
+
|
|
98
|
+
Currently loaded generics.
|
|
99
|
+
|
|
100
|
+
#### Return
|
|
101
|
+
- `generics` - : GenericsData; Generic data to validate DDF.
|
|
102
|
+
|
|
103
|
+
### validator.loadGeneric()
|
|
104
|
+
|
|
105
|
+
Load generic data from an object.
|
|
106
|
+
Support files with schema `constants1.schema.json`, `resourceitem1.schema.json` and `subdevice1.schema.json`.
|
|
107
|
+
|
|
108
|
+
#### Arguments
|
|
109
|
+
- `data` - : object; File data.
|
|
110
|
+
|
|
111
|
+
#### Return
|
|
112
|
+
- `data` - : object; File data.
|
|
56
113
|
|
|
57
|
-
|
|
114
|
+
Or throw [Zod Error](https://github.com/colinhacks/zod/blob/master/ERROR_HANDLING.md)
|
|
115
|
+
|
|
116
|
+
#### Example
|
|
117
|
+
|
|
118
|
+
```typescript
|
|
119
|
+
import { createValidator } from '@deconz-community/ddf-validator'
|
|
120
|
+
|
|
121
|
+
const validator = createValidator()
|
|
122
|
+
validator.loadGeneric({
|
|
123
|
+
"schema": "constants1.schema.json",
|
|
124
|
+
"manufacturers" : {
|
|
125
|
+
"$MF_FOO": "Foo inc."
|
|
126
|
+
},
|
|
127
|
+
"device-types": {
|
|
128
|
+
"$TYPE_COLOR_LIGHT": "Color light"
|
|
129
|
+
}
|
|
130
|
+
})
|
|
131
|
+
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### validator.validate()
|
|
135
|
+
|
|
136
|
+
Validate DDF data from an object.
|
|
137
|
+
Support files with schema `constants1.schema.json`, `resourceitem1.schema.json`, `subdevice1.schema.json` and `devcap1.schema.json`.
|
|
138
|
+
Make sure to load any need generic first.
|
|
139
|
+
|
|
140
|
+
#### Arguments
|
|
141
|
+
- `data` - : object; File data.
|
|
142
|
+
|
|
143
|
+
#### Return
|
|
144
|
+
- `data` - : object; File data.
|
|
145
|
+
|
|
146
|
+
Or throw [Zod Error](https://github.com/colinhacks/zod/blob/master/ERROR_HANDLING.md)
|
|
147
|
+
|
|
148
|
+
#### Example
|
|
149
|
+
|
|
150
|
+
```typescript
|
|
151
|
+
import { createValidator } from '@deconz-community/ddf-validator'
|
|
152
|
+
|
|
153
|
+
const validator = createValidator()
|
|
154
|
+
validator.validate({
|
|
155
|
+
"schema": "constants1.schema.json",
|
|
156
|
+
"manufacturers" : {
|
|
157
|
+
"$MF_FOO": "Foo inc."
|
|
158
|
+
},
|
|
159
|
+
"device-types": {
|
|
160
|
+
"$TYPE_COLOR_LIGHT": "Color light"
|
|
161
|
+
}
|
|
162
|
+
})
|
|
163
|
+
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
### validator.getSchema()
|
|
167
|
+
|
|
168
|
+
Return Zod schema with loaded generic data.
|
|
169
|
+
|
|
170
|
+
#### Return
|
|
171
|
+
- `schema` - : ZodType<DDF>; Zod Schema.
|
|
172
|
+
|
|
173
|
+
#### Example
|
|
174
|
+
|
|
175
|
+
```typescript
|
|
176
|
+
import { createValidator } from '@deconz-community/ddf-validator'
|
|
177
|
+
import { zodToJsonSchema } from 'zod-to-json-schema'
|
|
58
178
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
console.log(result) // DDF type
|
|
62
|
-
}
|
|
63
|
-
catch (error) {
|
|
64
|
-
throw new Error(fromZodError(error).message)
|
|
65
|
-
}
|
|
179
|
+
const validator = createValidator()
|
|
180
|
+
const schemaJson = zodToJsonSchema(validator.getSchema(), 'DDF')
|
|
66
181
|
```
|
|
67
182
|
|
|
68
183
|
### Type definition
|
|
69
184
|
|
|
70
185
|
### DDF
|
|
71
186
|
|
|
72
|
-
The type definition of a valid DDF file.
|
|
187
|
+
The type definition of a valid DDF file. Contain union type for `constants1.schema.json`, `resourceitem1.schema.json`, `subdevice1.schema.json` and `devcap1.schema.json`.
|
|
73
188
|
|
|
74
189
|
#### Example
|
|
75
190
|
|
package/dist/ddf-schema.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"$ref":"#/definitions/DDF","definitions":{"DDF":{"anyOf":[{"type":"object","properties":{"$schema":{"type":"string"},"schema":{"type":"string","const":"devcap1.schema.json"},"doc:path":{"type":"string"},"doc:hdr":{"type":"string"},"md:known_issues":{"type":"array","items":{"type":"string"}},"manufacturername":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]},"modelid":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]},"vendor":{"type":"string"},"comment":{"type":"string"},"matchexpr":{"type":"string"},"path":{"type":"string"},"product":{"type":"string"},"sleeper":{"type":"boolean"},"supportsMgmtBind":{"type":"boolean"},"status":{"type":"string","enum":["Draft","Bronze","Silver","Gold"],"description":"The code quality of the DDF file."},"subdevices":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","enum":["$TYPE_AIR_PURIFIER","$TYPE_AIR_QUALITY_SENSOR","$TYPE_ALARM_SENSOR","$TYPE_BATTERY_SENSOR","$TYPE_COLOR_DIMMABLE_LIGHT","$TYPE_COLOR_LIGHT","$TYPE_COLOR_TEMPERATURE_LIGHT","$TYPE_CONSUMPTION_SENSOR","$TYPE_DIMMABLE_LIGHT","$TYPE_DIMMABLE_PLUGIN_UNIT","$TYPE_DIMMER_SWITCH","$TYPE_DOOR_LOCK_CONTROLLER","$TYPE_DOOR_LOCK","$TYPE_EXTENDED_COLOR_LIGHT","$TYPE_FIRE_SENSOR","$TYPE_HUMIDITY_SENSOR","$TYPE_LIGHT_LEVEL_SENSOR","$TYPE_ON_OFF_LIGHT","$TYPE_ON_OFF_OUTPUT","$TYPE_ON_OFF_PLUGIN_UNIT","$TYPE_OPEN_CLOSE_SENSOR","$TYPE_POWER_SENSOR","$TYPE_PRESENCE_SENSOR","$TYPE_PRESSURE_SENSOR","$TYPE_RANGE_EXTENDER","$TYPE_RELATIVE_ROTARY","$TYPE_SMART_PLUG","$TYPE_SPECTRAL_SENSOR","$TYPE_SWITCH","$TYPE_TEMPERATURE_SENSOR","$TYPE_THERMOSTAT","$TYPE_VIBRATION_SENSOR","$TYPE_WARNING_DEVICE","$TYPE_WATER_LEAK_SENSOR","$TYPE_WINDOW_COVERING_DEVICE","$TYPE_ZGP_SWITCH","ZHAAirPurifier","ZHAAirQuality","ZHAAlarm","ZHABattery","Color dimmable light","Color light","Color temperature light","ZHAConsumption","Dimmable light","Dimmable plug-in unit","Dimmer switch","Door lock controller","Door Lock","Extended color light","ZHAFire","ZHAHumidity","ZHALightLevel","On/Off light","On/Off output","On/Off plug-in unit","ZHAOpenClose","ZHAPower","ZHAPresence","ZHAPressure","Range extender","ZHARelativeRotary","Smart plug","ZHASpectral","ZHASwitch","ZHATemperature","ZHAThermostat","ZHAVibration","Warning device","ZHAWater","Window covering device","ZGPSwitch","ZHAAncillaryControl","ZHATime","ZHACarbonMonoxide","ZHADoorLock"]},"restapi":{"type":"string","enum":["/lights","/sensors"]},"uuid":{"anyOf":[{"type":"array","minItems":2,"maxItems":2,"items":[{"type":"string","const":"$address.ext"},{"type":"string","minLength":4,"maxLength":4}]},{"type":"array","minItems":3,"maxItems":3,"items":[{"type":"string","const":"$address.ext"},{"type":"string","minLength":4,"maxLength":4},{"type":"string","minLength":6,"maxLength":6}]}]},"fingerprint":{"type":"object","properties":{"profile":{"type":"string","minLength":6,"maxLength":6},"device":{"type":"string","minLength":6,"maxLength":6},"endpoint":{"anyOf":[{"type":"string","minLength":4,"maxLength":4},{"type":"number","minimum":0,"maximum":255}]},"in":{"type":"array","items":{"type":"string","minLength":6,"maxLength":6}},"out":{"type":"array","items":{"type":"string","minLength":6,"maxLength":6}}},"required":["profile","device","endpoint"],"additionalProperties":false},"meta":{"type":"object","properties":{"values":{},"group.endpoints":{"type":"array","items":{"type":"number"}}},"additionalProperties":false},"buttons":{},"buttonevents":{},"items":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"description":{"type":"string"},"comment":{"type":"string"},"public":{"type":"boolean"},"static":{"type":["string","number","boolean"]},"range":{"type":"array","minItems":2,"maxItems":2,"items":[{"type":"number"},{"type":"number"}]},"deprecated":{"type":"string"},"access":{"type":"string","const":"R"},"read":{"anyOf":[{"type":"object","properties":{"fn":{"type":"string","const":"none"}},"required":["fn"],"additionalProperties":false},{"type":"object","properties":{"fn":{"not":{}},"at":{"anyOf":[{"type":"string","minLength":6,"maxLength":6},{"type":"array","items":{"type":"string","minLength":6,"maxLength":6}}]},"cl":{"type":"string","minLength":6,"maxLength":6},"ep":{"anyOf":[{"type":"string","minLength":4,"maxLength":4},{"type":"number","minimum":0,"maximum":255}]},"mf":{"type":"string","minLength":6,"maxLength":6},"eval":{"type":"string"}},"required":["cl"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"zcl"},"at":{"anyOf":[{"type":"string","minLength":6,"maxLength":6},{"type":"array","items":{"type":"string","minLength":6,"maxLength":6}}]},"cl":{"type":"string","minLength":6,"maxLength":6},"ep":{"anyOf":[{"type":"string","minLength":4,"maxLength":4},{"type":"number","minimum":0,"maximum":255}]},"mf":{"type":"string","minLength":6,"maxLength":6},"eval":{"type":"string"}},"required":["fn","cl"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"tuya"}},"required":["fn"],"additionalProperties":false}]},"parse":{"anyOf":[{"type":"object","properties":{"fn":{"not":{}},"at":{"type":"string","minLength":6,"maxLength":6},"cl":{"type":"string","minLength":6,"maxLength":6},"cppsrc":{"type":"string"},"ep":{"anyOf":[{"type":"string","minLength":4,"maxLength":4},{"type":"number","minimum":0,"maximum":255}]},"cmd":{"type":"string","minLength":4,"maxLength":4},"mf":{"type":"string","minLength":6,"maxLength":6},"eval":{"type":"string"},"script":{"type":"string"}},"required":["cl"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"zcl"},"at":{"type":"string","minLength":6,"maxLength":6},"cl":{"type":"string","minLength":6,"maxLength":6},"cppsrc":{"type":"string"},"ep":{"anyOf":[{"type":"string","minLength":4,"maxLength":4},{"type":"number","minimum":0,"maximum":255}]},"cmd":{"type":"string","minLength":4,"maxLength":4},"mf":{"type":"string","minLength":6,"maxLength":6},"eval":{"type":"string"},"script":{"type":"string"}},"required":["fn","cl"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"ias:zonestatus"},"mask":{"type":"string","enum":["alarm1","alarm2"]}},"required":["fn","mask"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"numtostr"},"srcitem":{"type":"string","enum":["state/airqualityppb","state/pm2_5"]},"op":{"type":"string","const":"le"},"to":{}},"required":["fn","srcitem","op","to"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"xiaomi:special"},"ep":{"anyOf":[{"type":"string","minLength":4,"maxLength":4},{"type":"number","minimum":0,"maximum":255}]},"at":{"type":"string","minLength":6,"maxLength":6},"idx":{"type":"string","minLength":4,"maxLength":4},"eval":{"type":"string"},"script":{"type":"string"}},"required":["fn","idx"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"tuya"},"dpid":{"type":"number"},"eval":{"type":"string"},"script":{"type":"string"}},"required":["fn","dpid"],"additionalProperties":false}]},"write":{"anyOf":[{"type":"object","properties":{"fn":{"type":"string","const":"none"}},"required":["fn"],"additionalProperties":false},{"type":"object","properties":{"fn":{"not":{}},"at":{"anyOf":[{"type":"string","minLength":6,"maxLength":6},{"type":"array","items":{"type":"string","minLength":6,"maxLength":6}}]},"state.timeout":{"type":"number"},"change.timeout":{"type":"number"},"cl":{"type":"string","minLength":6,"maxLength":6},"dt":{"type":"string","minLength":4,"maxLength":4},"ep":{"anyOf":[{"type":"string","minLength":4,"maxLength":4},{"type":"number","minimum":0,"maximum":255}]},"mf":{"type":"string","minLength":6,"maxLength":6},"eval":{"type":"string"},"script":{"type":"string"}},"required":["cl","dt"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"zcl"},"at":{"anyOf":[{"type":"string","minLength":6,"maxLength":6},{"type":"array","items":{"type":"string","minLength":6,"maxLength":6}}]},"state.timeout":{"type":"number"},"change.timeout":{"type":"number"},"cl":{"type":"string","minLength":6,"maxLength":6},"dt":{"type":"string","minLength":4,"maxLength":4},"ep":{"anyOf":[{"type":"string","minLength":4,"maxLength":4},{"type":"number","minimum":0,"maximum":255}]},"mf":{"type":"string","minLength":6,"maxLength":6},"eval":{"type":"string"},"script":{"type":"string"}},"required":["fn","cl","dt"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"tuya"},"dpid":{"type":"number"},"dt":{"type":"string","minLength":4,"maxLength":4},"eval":{"type":"string"},"script":{"type":"string"}},"required":["fn","dpid","dt"],"additionalProperties":false}]},"awake":{"type":"boolean"},"default":{},"values":{},"refresh.interval":{"type":"number"}},"required":["name"],"additionalProperties":false}},"example":{}},"required":["type","restapi","uuid","items"],"additionalProperties":false}},"bindings":{"type":"array","items":{"anyOf":[{"type":"object","properties":{"bind":{"type":"string","const":"unicast"},"src.ep":{"anyOf":[{"type":"string","minLength":4,"maxLength":4},{"type":"number","minimum":0,"maximum":255}]},"dst.ep":{"anyOf":[{"type":"string","minLength":4,"maxLength":4},{"type":"number","minimum":0,"maximum":255}]},"cl":{"type":"string","minLength":6,"maxLength":6},"report":{"type":"array","items":{"type":"object","properties":{"at":{"type":"string","minLength":6,"maxLength":6},"dt":{"type":"string","minLength":4,"maxLength":4},"mf":{"type":"string","minLength":6,"maxLength":6},"min":{"type":"number"},"max":{"type":"number"},"change":{"type":["string","number"]}},"required":["at","dt","min","max"],"additionalProperties":false}}},"required":["bind","src.ep","cl"],"additionalProperties":false},{"type":"object","properties":{"bind":{"type":"string","const":"groupcast"},"src.ep":{"anyOf":[{"type":"string","minLength":4,"maxLength":4},{"type":"number","minimum":0,"maximum":255}]},"cl":{"type":"string","minLength":6,"maxLength":6},"config.group":{"type":"number"}},"required":["bind","src.ep","cl","config.group"],"additionalProperties":false}]}}},"required":["schema","manufacturername","modelid","status","subdevices"],"additionalProperties":false}]}},"$schema":"http://json-schema.org/draft-07/schema#"}
|
|
1
|
+
{"$ref":"#/definitions/DDF","definitions":{"DDF":{"anyOf":[{"type":"object","properties":{"$schema":{"type":"string"},"schema":{"type":"string","const":"devcap1.schema.json"},"doc:path":{"type":"string"},"doc:hdr":{"type":"string"},"md:known_issues":{"type":"array","items":{"type":"string"}},"manufacturername":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]},"modelid":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]},"vendor":{"type":"string"},"comment":{"type":"string"},"matchexpr":{"type":"string"},"path":{"type":"string"},"product":{"type":"string"},"sleeper":{"type":"boolean"},"supportsMgmtBind":{"type":"boolean"},"status":{"type":"string","enum":["Draft","Bronze","Silver","Gold"],"description":"The code quality of the DDF file."},"subdevices":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","enum":["$TYPE_AIR_PURIFIER","$TYPE_AIR_QUALITY_SENSOR","$TYPE_ALARM_SENSOR","$TYPE_ANCILLARY_CONTROL","$TYPE_BATTERY_SENSOR","$TYPE_CARBON_MONOXIDE","$TYPE_COLOR_DIMMABLE_LIGHT","$TYPE_COLOR_LIGHT","$TYPE_COLOR_TEMPERATURE_LIGHT","$TYPE_CONSUMPTION_SENSOR","$TYPE_DIMMABLE_LIGHT","$TYPE_DIMMABLE_PLUGIN_UNIT","$TYPE_DIMMER_SWITCH","$TYPE_DOOR_LOCK_CONTROLLER","$TYPE_DOOR_LOCK","$TYPE_EXTENDED_COLOR_LIGHT","$TYPE_FIRE_SENSOR","$TYPE_HUMIDITY_SENSOR","$TYPE_LIGHT_LEVEL_SENSOR","$TYPE_ON_OFF_LIGHT","$TYPE_ON_OFF_OUTPUT","$TYPE_ON_OFF_PLUGIN_UNIT","$TYPE_OPEN_CLOSE_SENSOR","$TYPE_POWER_SENSOR","$TYPE_PRESENCE_SENSOR","$TYPE_PRESSURE_SENSOR","$TYPE_RANGE_EXTENDER","$TYPE_RELATIVE_ROTARY","$TYPE_SMART_PLUG","$TYPE_SPECTRAL_SENSOR","$TYPE_SWITCH","$TYPE_TEMPERATURE_SENSOR","$TYPE_THERMOSTAT","$TYPE_TIME","$TYPE_VIBRATION_SENSOR","$TYPE_WARNING_DEVICE","$TYPE_WATER_LEAK_SENSOR","$TYPE_WINDOW_COVERING_DEVICE","$TYPE_ZGP_SWITCH","ZHAAirPurifier","ZHAAirQuality","ZHAAlarm","ZHAAncillaryControl","ZHABattery","ZHACarbonMonoxide","Color dimmable light","Color light","Color temperature light","ZHAConsumption","Dimmable light","Dimmable plug-in unit","Dimmer switch","Door lock controller","ZHADoorLock","Extended color light","ZHAFire","ZHAHumidity","ZHALightLevel","On/Off light","On/Off output","On/Off plug-in unit","ZHAOpenClose","ZHAPower","ZHAPresence","ZHAPressure","Range extender","ZHARelativeRotary","Smart plug","ZHASpectral","ZHASwitch","ZHATemperature","ZHAThermostat","ZHATime","ZHAVibration","Warning device","ZHAWater","Window covering device","ZGPSwitch"]},"restapi":{"type":"string","enum":["/lights","/sensors"]},"uuid":{"anyOf":[{"type":"array","minItems":2,"maxItems":2,"items":[{"type":"string","const":"$address.ext"},{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"}]},{"type":"array","minItems":3,"maxItems":3,"items":[{"type":"string","const":"$address.ext"},{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"}]}]},"fingerprint":{"type":"object","properties":{"profile":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},"device":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},"endpoint":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},{"type":"number","minimum":0,"maximum":255}]},"in":{"type":"array","items":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"}},"out":{"type":"array","items":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"}}},"required":["profile","device","endpoint"],"additionalProperties":false},"meta":{"type":"object","properties":{"values":{},"group.endpoints":{"type":"array","items":{"type":"number"}}},"additionalProperties":false},"buttons":{},"buttonevents":{},"items":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string","enum":["state/windowopen","state/water","state/voltage","state/vibrationstrength","state/vibration","state/valve","state/utc","state/tiltangle","state/tilt","state/test","state/temperature","state/tampered","state/speed","state/seconds_remaining","state/sat","state/rotaryevent","state/replacefilter","state/reachable","state/production","state/pressure","state/presenceevent","state/presence","state/power","state/pm2_5","state/panel","state/orientation_z","state/orientation_y","state/orientation_x","state/orientation","state/open","state/on","state/mountingmodeactive","state/lux","state/lowbattery","state/lockstate","state/localtime","state/lightlevel","state/lift","state/lastupdated","state/lastset","state/lastcheckin","state/humidity","state/hue","state/heating","state/gradient","state/gesture","state/fire","state/filterruntime","state/expectedrotation","state/expectedeventduration","state/eventduration","state/errorcode","state/effect","state/deviceruntime","state/daylight","state/dark","state/current","state/current_P3","state/current_P2","state/current_P1","state/ct","state/consumption","state/consumption_2","state/y","state/x","state/colormode","state/charging","state/carbonmonoxide","state/buttonevent","state/bri","state/battery","state/angle","state/alert","state/alarm","state/airqualityppb","state/airquality","state/action","config/windowopen_set","config/windowcoveringtype","config/usertest","config/unoccupiedheatsetpoint","config/triggerdistance","config/tholdoffset","config/tholddark","config/temperature","config/swingmode","config/sensitivitymax","config/sensitivity","config/selftest","config/schedule_on","config/schedule","config/resetpresence","config/reachable","config/pulseconfiguration","config/preset","config/pending","config/on/startup","config/on","config/offset","config/mountingmode","config/mode","config/locked","config/lock","config/ledindication","config/interfacemode","config/heatsetpoint","config/group","config/filterlifetime","config/fanmode","config/externalwindowopen","config/externalsensortemp","config/enrolled","config/duration","config/displayflipped","config/devicemode","config/delay","config/ctmin","config/ctmax","config/coolsetpoint","config/controlsequence","config/configured","config/colorcapabilities","config/color/xy/startup_y","config/color/xy/startup_x","config/color/gradient/reversed","config/color/execute_if_off","config/color/ct/startup","config/clickmode","config/checkin","config/bri/startup","config/bri/onoff_transitiontime","config/bri/on_level","config/bri/min","config/bri/max","config/bri/execute_if_off","config/battery","config/allowtouchlink","config/alert","cap/transition_block","cap/sleeper","cap/on/off_with_effect","cap/groups/not_supported","cap/color/xy/red_y","cap/color/xy/red_x","cap/color/xy/green_y","cap/color/xy/green_x","cap/color/xy/blue_y","cap/color/xy/blue_x","cap/color/gradient/styles","cap/color/gradient/pixel_length","cap/color/gradient/pixel_count","cap/color/gradient/max_segments","cap/color/gamut_type","cap/color/effects","cap/color/ct/min","cap/color/ct/max","cap/color/ct/computes_xy","cap/color/capabilities","cap/bri/move_with_onoff","cap/bri/min_dim_level","cap/alert/trigger_effect","attr/uniqueid","attr/type","attr/swversion","attr/swconfigid","attr/productname","attr/productid","attr/powerup","attr/poweronlevel","attr/poweronct","attr/name","attr/modelid","attr/mode","attr/manufacturername","attr/lastseen","attr/lastannounced","attr/id"]},"description":{"type":"string"},"comment":{"type":"string"},"public":{"type":"boolean"},"static":{"type":["string","number","boolean"]},"range":{"type":"array","minItems":2,"maxItems":2,"items":[{"type":"number"},{"type":"number"}]},"deprecated":{"type":"string","pattern":"^(\\d{4})-(?:(?:0[1-9])|(?:1[0-2]))-(?:(?:0[1-9])|(?:[12][0-9])|(?:3[01]))$"},"access":{"type":"string","const":"R"},"read":{"anyOf":[{"type":"object","properties":{"fn":{"type":"string","const":"none"}},"required":["fn"],"additionalProperties":false},{"type":"object","properties":{"fn":{"not":{}},"at":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},{"type":"array","items":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"}}]},"cl":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},"ep":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},{"type":"number","minimum":0,"maximum":255}]},"mf":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},"eval":{"type":"string"}},"required":["cl"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"zcl"},"at":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},{"type":"array","items":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"}}]},"cl":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},"ep":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},{"type":"number","minimum":0,"maximum":255}]},"mf":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},"eval":{"type":"string"}},"required":["fn","cl"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"tuya"}},"required":["fn"],"additionalProperties":false}]},"parse":{"anyOf":[{"type":"object","properties":{"fn":{"not":{}},"at":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},"cl":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},"cppsrc":{"type":"string"},"ep":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},{"type":"number","minimum":0,"maximum":255}]},"cmd":{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},"mf":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},"eval":{"type":"string"},"script":{"type":"string"}},"required":["cl"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"zcl"},"at":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},"cl":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},"cppsrc":{"type":"string"},"ep":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},{"type":"number","minimum":0,"maximum":255}]},"cmd":{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},"mf":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},"eval":{"type":"string"},"script":{"type":"string"}},"required":["fn","cl"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"ias:zonestatus"},"mask":{"anyOf":[{"type":"string","enum":["alarm1","alarm2"]},{"type":"string","const":"alarm1,alarm2"}]}},"required":["fn"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"numtostr"},"srcitem":{"type":"string","enum":["state/airqualityppb","state/pm2_5"]},"op":{"type":"string","const":"le"},"to":{}},"required":["fn","srcitem","op","to"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"time"}},"required":["fn"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"xiaomi:special"},"ep":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},{"type":"number","minimum":0,"maximum":255}]},"at":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},"idx":{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},"eval":{"type":"string"},"script":{"type":"string"}},"required":["fn","idx"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"tuya"},"dpid":{"type":"number"},"eval":{"type":"string"},"script":{"type":"string"}},"required":["fn","dpid"],"additionalProperties":false}]},"write":{"anyOf":[{"type":"object","properties":{"fn":{"type":"string","const":"none"}},"required":["fn"],"additionalProperties":false},{"type":"object","properties":{"fn":{"not":{}},"at":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},{"type":"array","items":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"}}]},"state.timeout":{"type":"number"},"change.timeout":{"type":"number"},"cl":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},"dt":{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},"ep":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},{"type":"number","minimum":0,"maximum":255}]},"mf":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},"eval":{"type":"string"},"script":{"type":"string"}},"required":["cl","dt"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"zcl"},"at":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},{"type":"array","items":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"}}]},"state.timeout":{"type":"number"},"change.timeout":{"type":"number"},"cl":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},"dt":{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},"ep":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},{"type":"number","minimum":0,"maximum":255}]},"mf":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},"eval":{"type":"string"},"script":{"type":"string"}},"required":["fn","cl","dt"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"tuya"},"dpid":{"type":"number"},"dt":{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},"eval":{"type":"string"},"script":{"type":"string"}},"required":["fn","dpid","dt"],"additionalProperties":false}]},"awake":{"type":"boolean"},"default":{},"values":{},"refresh.interval":{"type":"number"}},"required":["name"],"additionalProperties":false}},"example":{}},"required":["type","restapi","uuid","items"],"additionalProperties":false}},"bindings":{"type":"array","items":{"anyOf":[{"type":"object","properties":{"bind":{"type":"string","const":"unicast"},"src.ep":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},{"type":"number","minimum":0,"maximum":255}]},"dst.ep":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},{"type":"number","minimum":0,"maximum":255}]},"cl":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},"report":{"type":"array","items":{"type":"object","properties":{"at":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},"dt":{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},"mf":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},"min":{"type":"number"},"max":{"type":"number"},"change":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]+$"},{"type":"number"}]}},"required":["at","dt","min","max"],"additionalProperties":false}}},"required":["bind","src.ep","cl"],"additionalProperties":false},{"type":"object","properties":{"bind":{"type":"string","const":"groupcast"},"src.ep":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},{"type":"number","minimum":0,"maximum":255}]},"cl":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},"config.group":{"type":"number"}},"required":["bind","src.ep","cl","config.group"],"additionalProperties":false}]}}},"required":["schema","manufacturername","modelid","status","subdevices"],"additionalProperties":false},{"type":"object","properties":{"$schema":{"type":"string"},"schema":{"type":"string","const":"constants1.schema.json"},"manufacturers":{"type":"object","additionalProperties":{"type":"string"},"propertyNames":{"pattern":"^\\$MF\\_"}},"device-types":{"type":"object","additionalProperties":{"type":"string"},"propertyNames":{"pattern":"^\\$TYPE\\_"}}},"required":["schema","manufacturers","device-types"],"additionalProperties":false},{"type":"object","properties":{"$schema":{"type":"string"},"schema":{"type":"string","const":"resourceitem1.schema.json"},"id":{"type":"string"},"description":{"type":"string"},"deprecated":{"type":"string","pattern":"^(\\d{4})-(?:(?:0[1-9])|(?:1[0-2]))-(?:(?:0[1-9])|(?:[12][0-9])|(?:3[01]))$"},"datatype":{"type":"string","enum":["String","Bool","Int8","Int16","Int32","Int64","UInt8","UInt16","UInt32","UInt64","Array","Array[3]","ISO 8601 timestamp"]},"access":{"type":"string","enum":["R","W","RW"]},"public":{"type":"boolean"},"implicit":{"type":"boolean"},"managed":{"type":"boolean"},"static":{"type":"boolean"},"virtual":{"type":"boolean"},"parse":{"anyOf":[{"type":"object","properties":{"fn":{"not":{}},"at":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},"cl":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},"cppsrc":{"type":"string"},"ep":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},{"type":"number","minimum":0,"maximum":255}]},"cmd":{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},"mf":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},"eval":{"type":"string"},"script":{"type":"string"}},"required":["cl"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"zcl"},"at":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},"cl":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},"cppsrc":{"type":"string"},"ep":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},{"type":"number","minimum":0,"maximum":255}]},"cmd":{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},"mf":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},"eval":{"type":"string"},"script":{"type":"string"}},"required":["fn","cl"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"ias:zonestatus"},"mask":{"anyOf":[{"type":"string","enum":["alarm1","alarm2"]},{"type":"string","const":"alarm1,alarm2"}]}},"required":["fn"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"numtostr"},"srcitem":{"type":"string","enum":["state/airqualityppb","state/pm2_5"]},"op":{"type":"string","const":"le"},"to":{}},"required":["fn","srcitem","op","to"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"time"}},"required":["fn"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"xiaomi:special"},"ep":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},{"type":"number","minimum":0,"maximum":255}]},"at":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},"idx":{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},"eval":{"type":"string"},"script":{"type":"string"}},"required":["fn","idx"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"tuya"},"dpid":{"type":"number"},"eval":{"type":"string"},"script":{"type":"string"}},"required":["fn","dpid"],"additionalProperties":false}]},"read":{"anyOf":[{"type":"object","properties":{"fn":{"type":"string","const":"none"}},"required":["fn"],"additionalProperties":false},{"type":"object","properties":{"fn":{"not":{}},"at":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},{"type":"array","items":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"}}]},"cl":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},"ep":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},{"type":"number","minimum":0,"maximum":255}]},"mf":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},"eval":{"type":"string"}},"required":["cl"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"zcl"},"at":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},{"type":"array","items":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"}}]},"cl":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},"ep":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},{"type":"number","minimum":0,"maximum":255}]},"mf":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},"eval":{"type":"string"}},"required":["fn","cl"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"tuya"}},"required":["fn"],"additionalProperties":false}]},"write":{"anyOf":[{"type":"object","properties":{"fn":{"type":"string","const":"none"}},"required":["fn"],"additionalProperties":false},{"type":"object","properties":{"fn":{"not":{}},"at":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},{"type":"array","items":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"}}]},"state.timeout":{"type":"number"},"change.timeout":{"type":"number"},"cl":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},"dt":{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},"ep":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},{"type":"number","minimum":0,"maximum":255}]},"mf":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},"eval":{"type":"string"},"script":{"type":"string"}},"required":["cl","dt"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"zcl"},"at":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},{"type":"array","items":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"}}]},"state.timeout":{"type":"number"},"change.timeout":{"type":"number"},"cl":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},"dt":{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},"ep":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},{"type":"number","minimum":0,"maximum":255}]},"mf":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},"eval":{"type":"string"},"script":{"type":"string"}},"required":["fn","cl","dt"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"tuya"},"dpid":{"type":"number"},"dt":{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},"eval":{"type":"string"},"script":{"type":"string"}},"required":["fn","dpid","dt"],"additionalProperties":false}]},"refresh.interval":{"type":"number"},"values":{},"range":{"type":"array","minItems":2,"maxItems":2,"items":[{"type":"number"},{"type":"number"}]},"default":{}},"required":["schema","id","description","datatype","access","public"],"additionalProperties":false},{"type":"object","properties":{"$schema":{"type":"string"},"schema":{"type":"string","const":"subdevice1.schema.json"},"type":{"type":"string","enum":["$TYPE_AIR_PURIFIER","$TYPE_AIR_QUALITY_SENSOR","$TYPE_ALARM_SENSOR","$TYPE_ANCILLARY_CONTROL","$TYPE_BATTERY_SENSOR","$TYPE_CARBON_MONOXIDE","$TYPE_COLOR_DIMMABLE_LIGHT","$TYPE_COLOR_LIGHT","$TYPE_COLOR_TEMPERATURE_LIGHT","$TYPE_CONSUMPTION_SENSOR","$TYPE_DIMMABLE_LIGHT","$TYPE_DIMMABLE_PLUGIN_UNIT","$TYPE_DIMMER_SWITCH","$TYPE_DOOR_LOCK_CONTROLLER","$TYPE_DOOR_LOCK","$TYPE_EXTENDED_COLOR_LIGHT","$TYPE_FIRE_SENSOR","$TYPE_HUMIDITY_SENSOR","$TYPE_LIGHT_LEVEL_SENSOR","$TYPE_ON_OFF_LIGHT","$TYPE_ON_OFF_OUTPUT","$TYPE_ON_OFF_PLUGIN_UNIT","$TYPE_OPEN_CLOSE_SENSOR","$TYPE_POWER_SENSOR","$TYPE_PRESENCE_SENSOR","$TYPE_PRESSURE_SENSOR","$TYPE_RANGE_EXTENDER","$TYPE_RELATIVE_ROTARY","$TYPE_SMART_PLUG","$TYPE_SPECTRAL_SENSOR","$TYPE_SWITCH","$TYPE_TEMPERATURE_SENSOR","$TYPE_THERMOSTAT","$TYPE_TIME","$TYPE_VIBRATION_SENSOR","$TYPE_WARNING_DEVICE","$TYPE_WATER_LEAK_SENSOR","$TYPE_WINDOW_COVERING_DEVICE","$TYPE_ZGP_SWITCH"]},"name":{"type":"string","enum":["ZHAAirPurifier","ZHAAirQuality","ZHAAlarm","ZHAAncillaryControl","ZHABattery","ZHACarbonMonoxide","Color dimmable light","Color light","Color temperature light","ZHAConsumption","Dimmable light","Dimmable plug-in unit","Dimmer switch","Door lock controller","ZHADoorLock","Extended color light","ZHAFire","ZHAHumidity","ZHALightLevel","On/Off light","On/Off output","On/Off plug-in unit","ZHAOpenClose","ZHAPower","ZHAPresence","ZHAPressure","Range extender","ZHARelativeRotary","Smart plug","ZHASpectral","ZHASwitch","ZHATemperature","ZHAThermostat","ZHATime","ZHAVibration","Warning device","ZHAWater","Window covering device","ZGPSwitch"]},"restapi":{"type":"string","enum":["/lights","/sensors"]},"order":{"type":"number"},"uuid":{"anyOf":[{"type":"array","minItems":2,"maxItems":2,"items":[{"type":"string","const":"$address.ext"},{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"}]},{"type":"array","minItems":3,"maxItems":3,"items":[{"type":"string","const":"$address.ext"},{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"}]}]},"items":{"type":"array","items":{"type":"string","enum":["state/windowopen","state/water","state/voltage","state/vibrationstrength","state/vibration","state/valve","state/utc","state/tiltangle","state/tilt","state/test","state/temperature","state/tampered","state/speed","state/seconds_remaining","state/sat","state/rotaryevent","state/replacefilter","state/reachable","state/production","state/pressure","state/presenceevent","state/presence","state/power","state/pm2_5","state/panel","state/orientation_z","state/orientation_y","state/orientation_x","state/orientation","state/open","state/on","state/mountingmodeactive","state/lux","state/lowbattery","state/lockstate","state/localtime","state/lightlevel","state/lift","state/lastupdated","state/lastset","state/lastcheckin","state/humidity","state/hue","state/heating","state/gradient","state/gesture","state/fire","state/filterruntime","state/expectedrotation","state/expectedeventduration","state/eventduration","state/errorcode","state/effect","state/deviceruntime","state/daylight","state/dark","state/current","state/current_P3","state/current_P2","state/current_P1","state/ct","state/consumption","state/consumption_2","state/y","state/x","state/colormode","state/charging","state/carbonmonoxide","state/buttonevent","state/bri","state/battery","state/angle","state/alert","state/alarm","state/airqualityppb","state/airquality","state/action","config/windowopen_set","config/windowcoveringtype","config/usertest","config/unoccupiedheatsetpoint","config/triggerdistance","config/tholdoffset","config/tholddark","config/temperature","config/swingmode","config/sensitivitymax","config/sensitivity","config/selftest","config/schedule_on","config/schedule","config/resetpresence","config/reachable","config/pulseconfiguration","config/preset","config/pending","config/on/startup","config/on","config/offset","config/mountingmode","config/mode","config/locked","config/lock","config/ledindication","config/interfacemode","config/heatsetpoint","config/group","config/filterlifetime","config/fanmode","config/externalwindowopen","config/externalsensortemp","config/enrolled","config/duration","config/displayflipped","config/devicemode","config/delay","config/ctmin","config/ctmax","config/coolsetpoint","config/controlsequence","config/configured","config/colorcapabilities","config/color/xy/startup_y","config/color/xy/startup_x","config/color/gradient/reversed","config/color/execute_if_off","config/color/ct/startup","config/clickmode","config/checkin","config/bri/startup","config/bri/onoff_transitiontime","config/bri/on_level","config/bri/min","config/bri/max","config/bri/execute_if_off","config/battery","config/allowtouchlink","config/alert","cap/transition_block","cap/sleeper","cap/on/off_with_effect","cap/groups/not_supported","cap/color/xy/red_y","cap/color/xy/red_x","cap/color/xy/green_y","cap/color/xy/green_x","cap/color/xy/blue_y","cap/color/xy/blue_x","cap/color/gradient/styles","cap/color/gradient/pixel_length","cap/color/gradient/pixel_count","cap/color/gradient/max_segments","cap/color/gamut_type","cap/color/effects","cap/color/ct/min","cap/color/ct/max","cap/color/ct/computes_xy","cap/color/capabilities","cap/bri/move_with_onoff","cap/bri/min_dim_level","cap/alert/trigger_effect","attr/uniqueid","attr/type","attr/swversion","attr/swconfigid","attr/productname","attr/productid","attr/powerup","attr/poweronlevel","attr/poweronct","attr/name","attr/modelid","attr/mode","attr/manufacturername","attr/lastseen","attr/lastannounced","attr/id"]}}},"required":["schema","type","name","restapi","order","uuid","items"],"additionalProperties":false}]}},"$schema":"http://json-schema.org/draft-07/schema#"}
|
package/dist/ddf-validator.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("zod")
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("zod");function h(e){return t.z.strictObject({$schema:t.z.optional(t.z.string()),schema:t.z.literal("constants1.schema.json"),manufacturers:t.z.record(t.z.string().startsWith("$MF_"),t.z.string()),"device-types":t.z.record(t.z.string().startsWith("$TYPE_"),t.z.string())})}function u(){return t.z.string().regex(/^(\d{4})-(?:(?:0[1-9])|(?:1[0-2]))-(?:(?:0[1-9])|(?:[12][0-9])|(?:3[01]))$/,"Invalid date value")}function n(e=void 0){const i="Invalid hexadecimal value";return e===void 0?t.z.string().regex(/^0x[0-9a-fA-F]+$/,i):t.z.string().regex(new RegExp(`^0x[0-9a-fA-F]{${e}}$`),i)}function a(){return t.z.union([n(2),t.z.number().min(0).max(255)])}function v(){return t.z.custom(e=>{if(!Array.isArray(e)||e.length%2!==0)return!1;for(let i=0;i<e.length;i+=2){const l=e[i],c=e[i+1];if(typeof l!="number"||typeof c!="string")return!1}return!0},"The value must be an array with an even number of values and alternating between number and string.")}function m(){return t.z.union([t.z.tuple([t.z.literal("$address.ext"),n(2)]),t.z.tuple([t.z.literal("$address.ext"),n(2),n(4)])])}function o(){return t.z.string()}function r(){return t.z.string()}function d(){return t.z.discriminatedUnion("fn",[t.z.strictObject({fn:t.z.literal("none")}),t.z.strictObject({fn:t.z.undefined(),at:t.z.optional(n(4).or(t.z.array(n(4)))),cl:n(4),ep:t.z.optional(a()),mf:t.z.optional(n(4)),eval:t.z.optional(r())}),t.z.strictObject({fn:t.z.literal("zcl"),at:t.z.optional(n(4).or(t.z.array(n(4)))),cl:n(4),ep:t.z.optional(a()),mf:t.z.optional(n(4)),eval:t.z.optional(r())}),t.z.strictObject({fn:t.z.literal("tuya")})])}function b(){return t.z.discriminatedUnion("fn",[t.z.strictObject({fn:t.z.undefined(),at:t.z.optional(n(4)),cl:n(4),cppsrc:t.z.optional(t.z.string()),ep:t.z.optional(a()),cmd:t.z.optional(n(2)),mf:t.z.optional(n(4)),eval:t.z.optional(r()),script:t.z.optional(o())}).refine(e=>!("eval"in e&&"script"in e),{message:"eval and script should not both be present"}).innerType(),t.z.strictObject({fn:t.z.literal("zcl"),at:t.z.optional(n(4)),cl:n(4),cppsrc:t.z.optional(t.z.string()),ep:t.z.optional(a()),cmd:t.z.optional(n(2)),mf:t.z.optional(n(4)),eval:t.z.optional(r()),script:t.z.optional(o())}).refine(e=>!("eval"in e&&"script"in e),{message:"eval and script should not both be present"}).innerType(),t.z.strictObject({fn:t.z.literal("ias:zonestatus"),mask:t.z.optional(t.z.enum(["alarm1","alarm2"]).or(t.z.literal("alarm1,alarm2")))}),t.z.strictObject({fn:t.z.literal("numtostr"),srcitem:t.z.enum(["state/airqualityppb","state/pm2_5"]),op:t.z.literal("le"),to:v()}),t.z.strictObject({fn:t.z.literal("time")}),t.z.strictObject({fn:t.z.literal("xiaomi:special"),ep:t.z.optional(a()),at:t.z.optional(n(4)),idx:n(2),eval:t.z.optional(r()),script:t.z.optional(o())}).refine(e=>!("eval"in e&&"script"in e),{message:"eval and script should not both be present"}).innerType(),t.z.strictObject({fn:t.z.literal("tuya"),dpid:t.z.number(),eval:t.z.optional(r()),script:t.z.optional(o())}).refine(e=>!("eval"in e&&"script"in e),{message:"eval and script should not both be present"}).innerType()])}function f(){return t.z.discriminatedUnion("fn",[t.z.strictObject({fn:t.z.literal("none")}),t.z.strictObject({fn:t.z.undefined(),at:t.z.optional(n(4).or(t.z.array(n(4)))),"state.timeout":t.z.optional(t.z.number()),"change.timeout":t.z.optional(t.z.number()),cl:n(4),dt:n(2),ep:t.z.optional(a()),mf:t.z.optional(n(4)),eval:t.z.optional(r()),script:t.z.optional(o())}).refine(e=>!("eval"in e&&"script"in e),{message:"eval and script should not both be present"}).innerType(),t.z.strictObject({fn:t.z.literal("zcl"),at:t.z.optional(n(4).or(t.z.array(n(4)))),"state.timeout":t.z.optional(t.z.number()),"change.timeout":t.z.optional(t.z.number()),cl:n(4),dt:n(2),ep:t.z.optional(a()),mf:t.z.optional(n(4)),eval:t.z.optional(r()),script:t.z.optional(o())}).refine(e=>!("eval"in e&&"script"in e),{message:"eval and script should not both be present"}).innerType(),t.z.strictObject({fn:t.z.literal("tuya"),dpid:t.z.number(),dt:n(2),eval:t.z.optional(r()),script:t.z.optional(o())}).refine(e=>!("eval"in e&&"script"in e),{message:"eval and script should not both be present"}).innerType()])}function g(e){return t.z.strictObject({$schema:t.z.optional(t.z.string()),schema:t.z.literal("devcap1.schema.json"),"doc:path":t.z.optional(t.z.string()),"doc:hdr":t.z.optional(t.z.string()),"md:known_issues":t.z.optional(t.z.array(t.z.string())),manufacturername:t.z.string().or(t.z.array(t.z.string())),modelid:t.z.string().or(t.z.array(t.z.string())),vendor:t.z.optional(t.z.string()),comment:t.z.optional(t.z.string()),matchexpr:t.z.optional(r()),path:t.z.optional(o()),product:t.z.optional(t.z.string()),sleeper:t.z.optional(t.z.boolean()),supportsMgmtBind:t.z.optional(t.z.boolean()),status:t.z.enum(["Draft","Bronze","Silver","Gold"]).describe("The code quality of the DDF file."),subdevices:t.z.array(y(e)),bindings:t.z.optional(t.z.array(O()))}).refine(i=>typeof i.manufacturername=="string"&&typeof i.modelid=="string"||Array.isArray(i.manufacturername)&&Array.isArray(i.modelid)&&i.manufacturername.length===i.modelid.length,{message:"manufacturername and modelid should be both strings or arrays with the same length.",path:["manufacturername","modelid"]}).innerType()}function y(e){return t.z.strictObject({type:t.z.union([t.z.enum(Object.keys(e.deviceTypes)),t.z.enum(Object.values(e.deviceTypes))]),restapi:t.z.enum(["/lights","/sensors"]),uuid:m(),fingerprint:t.z.optional(t.z.strictObject({profile:n(4),device:n(4),endpoint:a(),in:t.z.optional(t.z.array(n(4))),out:t.z.optional(t.z.array(n(4)))})),meta:t.z.optional(t.z.strictObject({values:t.z.any(),"group.endpoints":t.z.optional(t.z.array(t.z.number()))})),buttons:t.z.optional(t.z.any()),buttonevents:t.z.optional(t.z.any()),items:t.z.array(j(e)),example:t.z.optional(t.z.unknown())})}function j(e){return t.z.strictObject({name:t.z.enum(e.attributes),description:t.z.optional(t.z.string()),comment:t.z.optional(t.z.string()),public:t.z.optional(t.z.boolean()),static:t.z.optional(t.z.union([t.z.string(),t.z.number(),t.z.boolean()])),range:t.z.optional(t.z.tuple([t.z.number(),t.z.number()])),deprecated:t.z.optional(u()),access:t.z.optional(t.z.literal("R")),read:t.z.optional(d()),parse:t.z.optional(b()),write:t.z.optional(f()),awake:t.z.optional(t.z.boolean()),default:t.z.optional(t.z.unknown()),values:t.z.optional(t.z.unknown()),"refresh.interval":t.z.optional(t.z.number())})}function O(e){return t.z.discriminatedUnion("bind",[t.z.strictObject({bind:t.z.literal("unicast"),"src.ep":a(),"dst.ep":t.z.optional(a()),cl:n(4),report:t.z.optional(t.z.array(t.z.strictObject({at:n(4),dt:n(2),mf:t.z.optional(n(4)),min:t.z.number(),max:t.z.number(),change:t.z.optional(n().or(t.z.number()))})))}),t.z.strictObject({bind:t.z.literal("groupcast"),"src.ep":a(),cl:n(4),"config.group":t.z.number()})])}function T(e){return t.z.strictObject({$schema:t.z.optional(t.z.string()),schema:t.z.literal("resourceitem1.schema.json"),id:t.z.string(),description:t.z.string(),deprecated:t.z.optional(u()),datatype:t.z.enum(["String","Bool","Int8","Int16","Int32","Int64","UInt8","UInt16","UInt32","UInt64","Array","Array[3]","ISO 8601 timestamp"]),access:t.z.enum(["R","W","RW"]),public:t.z.boolean(),implicit:t.z.optional(t.z.boolean()),managed:t.z.optional(t.z.boolean()),static:t.z.optional(t.z.boolean()),virtual:t.z.optional(t.z.boolean()),parse:t.z.optional(b()),read:t.z.optional(d()),write:t.z.optional(f()),"refresh.interval":t.z.optional(t.z.number()),values:t.z.optional(t.z.unknown()),range:t.z.optional(t.z.tuple([t.z.number(),t.z.number()])),default:t.z.optional(t.z.unknown())})}function w(e){return t.z.strictObject({$schema:t.z.optional(t.z.string()),schema:t.z.literal("subdevice1.schema.json"),type:t.z.enum(Object.keys(e.deviceTypes)),name:t.z.enum(Object.values(e.deviceTypes)),restapi:t.z.enum(["/lights","/sensors"]),order:t.z.number(),uuid:m(),items:t.z.array(t.z.enum(e.attributes))})}function p(e){return t.z.discriminatedUnion("schema",[g(e),h(),T(),w(e)])}function S(e={attributes:[],manufacturers:{},deviceTypes:{}}){let i=p(e);const l=()=>{i=p(e)};return{generics:e,loadGeneric:z=>{const s=i.parse(z);switch(s.schema){case"constants1.schema.json":e.manufacturers={...e.manufacturers,...s.manufacturers},e.deviceTypes={...e.deviceTypes,...s["device-types"]};break;case"resourceitem1.schema.json":e.attributes.includes(s.id)||e.attributes.push(s.id);break;case"subdevice1.schema.json":break;case"devcap1.schema.json":throw new Error("Got invalid generic file, got data with schema 'devcap1.schema.json'.")}return l(),s},validate:z=>i.parse(z),getSchema:()=>i}}exports.createValidator=S;
|
package/dist/ddf-validator.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ZodType } from "zod";
|
|
1
2
|
|
|
2
3
|
export type DDF = {
|
|
3
4
|
$schema?: string | undefined;
|
|
@@ -17,7 +18,7 @@ export type DDF = {
|
|
|
17
18
|
/** The code quality of the DDF file. */
|
|
18
19
|
status: "Draft" | "Bronze" | "Silver" | "Gold";
|
|
19
20
|
subdevices: {
|
|
20
|
-
type: "$TYPE_AIR_PURIFIER" | "$TYPE_AIR_QUALITY_SENSOR" | "$TYPE_ALARM_SENSOR" | "$TYPE_BATTERY_SENSOR" | "$TYPE_COLOR_DIMMABLE_LIGHT" | "$TYPE_COLOR_LIGHT" | "$TYPE_COLOR_TEMPERATURE_LIGHT" | "$TYPE_CONSUMPTION_SENSOR" | "$TYPE_DIMMABLE_LIGHT" | "$TYPE_DIMMABLE_PLUGIN_UNIT" | "$TYPE_DIMMER_SWITCH" | "$TYPE_DOOR_LOCK_CONTROLLER" | "$TYPE_DOOR_LOCK" | "$TYPE_EXTENDED_COLOR_LIGHT" | "$TYPE_FIRE_SENSOR" | "$TYPE_HUMIDITY_SENSOR" | "$TYPE_LIGHT_LEVEL_SENSOR" | "$TYPE_ON_OFF_LIGHT" | "$TYPE_ON_OFF_OUTPUT" | "$TYPE_ON_OFF_PLUGIN_UNIT" | "$TYPE_OPEN_CLOSE_SENSOR" | "$TYPE_POWER_SENSOR" | "$TYPE_PRESENCE_SENSOR" | "$TYPE_PRESSURE_SENSOR" | "$TYPE_RANGE_EXTENDER" | "$TYPE_RELATIVE_ROTARY" | "$TYPE_SMART_PLUG" | "$TYPE_SPECTRAL_SENSOR" | "$TYPE_SWITCH" | "$TYPE_TEMPERATURE_SENSOR" | "$TYPE_THERMOSTAT" | "$TYPE_VIBRATION_SENSOR" | "$TYPE_WARNING_DEVICE" | "$TYPE_WATER_LEAK_SENSOR" | "$TYPE_WINDOW_COVERING_DEVICE" | "$TYPE_ZGP_SWITCH" | "ZHAAirPurifier" | "ZHAAirQuality" | "ZHAAlarm" | "ZHABattery" | "Color dimmable light" | "Color light" | "Color temperature light" | "ZHAConsumption" | "Dimmable light" | "Dimmable plug-in unit" | "Dimmer switch" | "Door lock controller" | "
|
|
21
|
+
type: ("$TYPE_AIR_PURIFIER" | "$TYPE_AIR_QUALITY_SENSOR" | "$TYPE_ALARM_SENSOR" | "$TYPE_ANCILLARY_CONTROL" | "$TYPE_BATTERY_SENSOR" | "$TYPE_CARBON_MONOXIDE" | "$TYPE_COLOR_DIMMABLE_LIGHT" | "$TYPE_COLOR_LIGHT" | "$TYPE_COLOR_TEMPERATURE_LIGHT" | "$TYPE_CONSUMPTION_SENSOR" | "$TYPE_DIMMABLE_LIGHT" | "$TYPE_DIMMABLE_PLUGIN_UNIT" | "$TYPE_DIMMER_SWITCH" | "$TYPE_DOOR_LOCK_CONTROLLER" | "$TYPE_DOOR_LOCK" | "$TYPE_EXTENDED_COLOR_LIGHT" | "$TYPE_FIRE_SENSOR" | "$TYPE_HUMIDITY_SENSOR" | "$TYPE_LIGHT_LEVEL_SENSOR" | "$TYPE_ON_OFF_LIGHT" | "$TYPE_ON_OFF_OUTPUT" | "$TYPE_ON_OFF_PLUGIN_UNIT" | "$TYPE_OPEN_CLOSE_SENSOR" | "$TYPE_POWER_SENSOR" | "$TYPE_PRESENCE_SENSOR" | "$TYPE_PRESSURE_SENSOR" | "$TYPE_RANGE_EXTENDER" | "$TYPE_RELATIVE_ROTARY" | "$TYPE_SMART_PLUG" | "$TYPE_SPECTRAL_SENSOR" | "$TYPE_SWITCH" | "$TYPE_TEMPERATURE_SENSOR" | "$TYPE_THERMOSTAT" | "$TYPE_TIME" | "$TYPE_VIBRATION_SENSOR" | "$TYPE_WARNING_DEVICE" | "$TYPE_WATER_LEAK_SENSOR" | "$TYPE_WINDOW_COVERING_DEVICE" | "$TYPE_ZGP_SWITCH") | ("ZHAAirPurifier" | "ZHAAirQuality" | "ZHAAlarm" | "ZHAAncillaryControl" | "ZHABattery" | "ZHACarbonMonoxide" | "Color dimmable light" | "Color light" | "Color temperature light" | "ZHAConsumption" | "Dimmable light" | "Dimmable plug-in unit" | "Dimmer switch" | "Door lock controller" | "ZHADoorLock" | "Extended color light" | "ZHAFire" | "ZHAHumidity" | "ZHALightLevel" | "On/Off light" | "On/Off output" | "On/Off plug-in unit" | "ZHAOpenClose" | "ZHAPower" | "ZHAPresence" | "ZHAPressure" | "Range extender" | "ZHARelativeRotary" | "Smart plug" | "ZHASpectral" | "ZHASwitch" | "ZHATemperature" | "ZHAThermostat" | "ZHATime" | "ZHAVibration" | "Warning device" | "ZHAWater" | "Window covering device" | "ZGPSwitch");
|
|
21
22
|
restapi: "/lights" | "/sensors";
|
|
22
23
|
uuid: [
|
|
23
24
|
"$address.ext",
|
|
@@ -41,7 +42,7 @@ export type DDF = {
|
|
|
41
42
|
buttons?: any | undefined;
|
|
42
43
|
buttonevents?: any | undefined;
|
|
43
44
|
items: {
|
|
44
|
-
name:
|
|
45
|
+
name: "state/windowopen" | "state/water" | "state/voltage" | "state/vibrationstrength" | "state/vibration" | "state/valve" | "state/utc" | "state/tiltangle" | "state/tilt" | "state/test" | "state/temperature" | "state/tampered" | "state/speed" | "state/seconds_remaining" | "state/sat" | "state/rotaryevent" | "state/replacefilter" | "state/reachable" | "state/production" | "state/pressure" | "state/presenceevent" | "state/presence" | "state/power" | "state/pm2_5" | "state/panel" | "state/orientation_z" | "state/orientation_y" | "state/orientation_x" | "state/orientation" | "state/open" | "state/on" | "state/mountingmodeactive" | "state/lux" | "state/lowbattery" | "state/lockstate" | "state/localtime" | "state/lightlevel" | "state/lift" | "state/lastupdated" | "state/lastset" | "state/lastcheckin" | "state/humidity" | "state/hue" | "state/heating" | "state/gradient" | "state/gesture" | "state/fire" | "state/filterruntime" | "state/expectedrotation" | "state/expectedeventduration" | "state/eventduration" | "state/errorcode" | "state/effect" | "state/deviceruntime" | "state/daylight" | "state/dark" | "state/current" | "state/current_P3" | "state/current_P2" | "state/current_P1" | "state/ct" | "state/consumption" | "state/consumption_2" | "state/y" | "state/x" | "state/colormode" | "state/charging" | "state/carbonmonoxide" | "state/buttonevent" | "state/bri" | "state/battery" | "state/angle" | "state/alert" | "state/alarm" | "state/airqualityppb" | "state/airquality" | "state/action" | "config/windowopen_set" | "config/windowcoveringtype" | "config/usertest" | "config/unoccupiedheatsetpoint" | "config/triggerdistance" | "config/tholdoffset" | "config/tholddark" | "config/temperature" | "config/swingmode" | "config/sensitivitymax" | "config/sensitivity" | "config/selftest" | "config/schedule_on" | "config/schedule" | "config/resetpresence" | "config/reachable" | "config/pulseconfiguration" | "config/preset" | "config/pending" | "config/on/startup" | "config/on" | "config/offset" | "config/mountingmode" | "config/mode" | "config/locked" | "config/lock" | "config/ledindication" | "config/interfacemode" | "config/heatsetpoint" | "config/group" | "config/filterlifetime" | "config/fanmode" | "config/externalwindowopen" | "config/externalsensortemp" | "config/enrolled" | "config/duration" | "config/displayflipped" | "config/devicemode" | "config/delay" | "config/ctmin" | "config/ctmax" | "config/coolsetpoint" | "config/controlsequence" | "config/configured" | "config/colorcapabilities" | "config/color/xy/startup_y" | "config/color/xy/startup_x" | "config/color/gradient/reversed" | "config/color/execute_if_off" | "config/color/ct/startup" | "config/clickmode" | "config/checkin" | "config/bri/startup" | "config/bri/onoff_transitiontime" | "config/bri/on_level" | "config/bri/min" | "config/bri/max" | "config/bri/execute_if_off" | "config/battery" | "config/allowtouchlink" | "config/alert" | "cap/transition_block" | "cap/sleeper" | "cap/on/off_with_effect" | "cap/groups/not_supported" | "cap/color/xy/red_y" | "cap/color/xy/red_x" | "cap/color/xy/green_y" | "cap/color/xy/green_x" | "cap/color/xy/blue_y" | "cap/color/xy/blue_x" | "cap/color/gradient/styles" | "cap/color/gradient/pixel_length" | "cap/color/gradient/pixel_count" | "cap/color/gradient/max_segments" | "cap/color/gamut_type" | "cap/color/effects" | "cap/color/ct/min" | "cap/color/ct/max" | "cap/color/ct/computes_xy" | "cap/color/capabilities" | "cap/bri/move_with_onoff" | "cap/bri/min_dim_level" | "cap/alert/trigger_effect" | "attr/uniqueid" | "attr/type" | "attr/swversion" | "attr/swconfigid" | "attr/productname" | "attr/productid" | "attr/powerup" | "attr/poweronlevel" | "attr/poweronct" | "attr/name" | "attr/modelid" | "attr/mode" | "attr/manufacturername" | "attr/lastseen" | "attr/lastannounced" | "attr/id";
|
|
45
46
|
description?: string | undefined;
|
|
46
47
|
comment?: string | undefined;
|
|
47
48
|
public?: boolean | undefined;
|
|
@@ -93,12 +94,14 @@ export type DDF = {
|
|
|
93
94
|
script?: string | undefined;
|
|
94
95
|
} | {
|
|
95
96
|
fn: "ias:zonestatus";
|
|
96
|
-
mask
|
|
97
|
+
mask?: (("alarm1" | "alarm2") | "alarm1,alarm2") | undefined;
|
|
97
98
|
} | {
|
|
98
99
|
fn: "numtostr";
|
|
99
100
|
srcitem: "state/airqualityppb" | "state/pm2_5";
|
|
100
101
|
op: "le";
|
|
101
102
|
to: any;
|
|
103
|
+
} | {
|
|
104
|
+
fn: "time";
|
|
102
105
|
} | {
|
|
103
106
|
fn: "xiaomi:special";
|
|
104
107
|
ep?: (string | number) | undefined;
|
|
@@ -169,8 +172,158 @@ export type DDF = {
|
|
|
169
172
|
cl: string;
|
|
170
173
|
"config.group": number;
|
|
171
174
|
})[] | undefined;
|
|
175
|
+
} | {
|
|
176
|
+
$schema?: string | undefined;
|
|
177
|
+
schema: "constants1.schema.json";
|
|
178
|
+
manufacturers: {
|
|
179
|
+
[x: string]: string;
|
|
180
|
+
};
|
|
181
|
+
"device-types": {
|
|
182
|
+
[x: string]: string;
|
|
183
|
+
};
|
|
184
|
+
} | {
|
|
185
|
+
$schema?: string | undefined;
|
|
186
|
+
schema: "resourceitem1.schema.json";
|
|
187
|
+
id: string;
|
|
188
|
+
description: string;
|
|
189
|
+
deprecated?: string | undefined;
|
|
190
|
+
datatype: "String" | "Bool" | "Int8" | "Int16" | "Int32" | "Int64" | "UInt8" | "UInt16" | "UInt32" | "UInt64" | "Array" | "Array[3]" | "ISO 8601 timestamp";
|
|
191
|
+
access: "R" | "W" | "RW";
|
|
192
|
+
public: boolean;
|
|
193
|
+
implicit?: boolean | undefined;
|
|
194
|
+
managed?: boolean | undefined;
|
|
195
|
+
static?: boolean | undefined;
|
|
196
|
+
virtual?: boolean | undefined;
|
|
197
|
+
parse?: ({
|
|
198
|
+
fn?: undefined;
|
|
199
|
+
at?: string | undefined;
|
|
200
|
+
cl: string;
|
|
201
|
+
cppsrc?: string | undefined;
|
|
202
|
+
ep?: (string | number) | undefined;
|
|
203
|
+
cmd?: string | undefined;
|
|
204
|
+
mf?: string | undefined;
|
|
205
|
+
eval?: string | undefined;
|
|
206
|
+
script?: string | undefined;
|
|
207
|
+
} | {
|
|
208
|
+
fn: "zcl";
|
|
209
|
+
at?: string | undefined;
|
|
210
|
+
cl: string;
|
|
211
|
+
cppsrc?: string | undefined;
|
|
212
|
+
ep?: (string | number) | undefined;
|
|
213
|
+
cmd?: string | undefined;
|
|
214
|
+
mf?: string | undefined;
|
|
215
|
+
eval?: string | undefined;
|
|
216
|
+
script?: string | undefined;
|
|
217
|
+
} | {
|
|
218
|
+
fn: "ias:zonestatus";
|
|
219
|
+
mask?: (("alarm1" | "alarm2") | "alarm1,alarm2") | undefined;
|
|
220
|
+
} | {
|
|
221
|
+
fn: "numtostr";
|
|
222
|
+
srcitem: "state/airqualityppb" | "state/pm2_5";
|
|
223
|
+
op: "le";
|
|
224
|
+
to: any;
|
|
225
|
+
} | {
|
|
226
|
+
fn: "time";
|
|
227
|
+
} | {
|
|
228
|
+
fn: "xiaomi:special";
|
|
229
|
+
ep?: (string | number) | undefined;
|
|
230
|
+
at?: string | undefined;
|
|
231
|
+
idx: string;
|
|
232
|
+
eval?: string | undefined;
|
|
233
|
+
script?: string | undefined;
|
|
234
|
+
} | {
|
|
235
|
+
fn: "tuya";
|
|
236
|
+
dpid: number;
|
|
237
|
+
eval?: string | undefined;
|
|
238
|
+
script?: string | undefined;
|
|
239
|
+
}) | undefined;
|
|
240
|
+
read?: ({
|
|
241
|
+
fn: "none";
|
|
242
|
+
} | {
|
|
243
|
+
fn?: undefined;
|
|
244
|
+
at?: (string | string[]) | undefined;
|
|
245
|
+
cl: string;
|
|
246
|
+
ep?: (string | number) | undefined;
|
|
247
|
+
mf?: string | undefined;
|
|
248
|
+
eval?: string | undefined;
|
|
249
|
+
} | {
|
|
250
|
+
fn: "zcl";
|
|
251
|
+
at?: (string | string[]) | undefined;
|
|
252
|
+
cl: string;
|
|
253
|
+
ep?: (string | number) | undefined;
|
|
254
|
+
mf?: string | undefined;
|
|
255
|
+
eval?: string | undefined;
|
|
256
|
+
} | {
|
|
257
|
+
fn: "tuya";
|
|
258
|
+
}) | undefined;
|
|
259
|
+
write?: ({
|
|
260
|
+
fn: "none";
|
|
261
|
+
} | {
|
|
262
|
+
fn?: undefined;
|
|
263
|
+
at?: (string | string[]) | undefined;
|
|
264
|
+
"state.timeout"?: number | undefined;
|
|
265
|
+
"change.timeout"?: number | undefined;
|
|
266
|
+
cl: string;
|
|
267
|
+
dt: string;
|
|
268
|
+
ep?: (string | number) | undefined;
|
|
269
|
+
mf?: string | undefined;
|
|
270
|
+
eval?: string | undefined;
|
|
271
|
+
script?: string | undefined;
|
|
272
|
+
} | {
|
|
273
|
+
fn: "zcl";
|
|
274
|
+
at?: (string | string[]) | undefined;
|
|
275
|
+
"state.timeout"?: number | undefined;
|
|
276
|
+
"change.timeout"?: number | undefined;
|
|
277
|
+
cl: string;
|
|
278
|
+
dt: string;
|
|
279
|
+
ep?: (string | number) | undefined;
|
|
280
|
+
mf?: string | undefined;
|
|
281
|
+
eval?: string | undefined;
|
|
282
|
+
script?: string | undefined;
|
|
283
|
+
} | {
|
|
284
|
+
fn: "tuya";
|
|
285
|
+
dpid: number;
|
|
286
|
+
dt: string;
|
|
287
|
+
eval?: string | undefined;
|
|
288
|
+
script?: string | undefined;
|
|
289
|
+
}) | undefined;
|
|
290
|
+
"refresh.interval"?: number | undefined;
|
|
291
|
+
values?: unknown | undefined;
|
|
292
|
+
range?: [
|
|
293
|
+
number,
|
|
294
|
+
number
|
|
295
|
+
] | undefined;
|
|
296
|
+
default?: unknown | undefined;
|
|
297
|
+
} | {
|
|
298
|
+
$schema?: string | undefined;
|
|
299
|
+
schema: "subdevice1.schema.json";
|
|
300
|
+
type: "$TYPE_AIR_PURIFIER" | "$TYPE_AIR_QUALITY_SENSOR" | "$TYPE_ALARM_SENSOR" | "$TYPE_ANCILLARY_CONTROL" | "$TYPE_BATTERY_SENSOR" | "$TYPE_CARBON_MONOXIDE" | "$TYPE_COLOR_DIMMABLE_LIGHT" | "$TYPE_COLOR_LIGHT" | "$TYPE_COLOR_TEMPERATURE_LIGHT" | "$TYPE_CONSUMPTION_SENSOR" | "$TYPE_DIMMABLE_LIGHT" | "$TYPE_DIMMABLE_PLUGIN_UNIT" | "$TYPE_DIMMER_SWITCH" | "$TYPE_DOOR_LOCK_CONTROLLER" | "$TYPE_DOOR_LOCK" | "$TYPE_EXTENDED_COLOR_LIGHT" | "$TYPE_FIRE_SENSOR" | "$TYPE_HUMIDITY_SENSOR" | "$TYPE_LIGHT_LEVEL_SENSOR" | "$TYPE_ON_OFF_LIGHT" | "$TYPE_ON_OFF_OUTPUT" | "$TYPE_ON_OFF_PLUGIN_UNIT" | "$TYPE_OPEN_CLOSE_SENSOR" | "$TYPE_POWER_SENSOR" | "$TYPE_PRESENCE_SENSOR" | "$TYPE_PRESSURE_SENSOR" | "$TYPE_RANGE_EXTENDER" | "$TYPE_RELATIVE_ROTARY" | "$TYPE_SMART_PLUG" | "$TYPE_SPECTRAL_SENSOR" | "$TYPE_SWITCH" | "$TYPE_TEMPERATURE_SENSOR" | "$TYPE_THERMOSTAT" | "$TYPE_TIME" | "$TYPE_VIBRATION_SENSOR" | "$TYPE_WARNING_DEVICE" | "$TYPE_WATER_LEAK_SENSOR" | "$TYPE_WINDOW_COVERING_DEVICE" | "$TYPE_ZGP_SWITCH";
|
|
301
|
+
name: "ZHAAirPurifier" | "ZHAAirQuality" | "ZHAAlarm" | "ZHAAncillaryControl" | "ZHABattery" | "ZHACarbonMonoxide" | "Color dimmable light" | "Color light" | "Color temperature light" | "ZHAConsumption" | "Dimmable light" | "Dimmable plug-in unit" | "Dimmer switch" | "Door lock controller" | "ZHADoorLock" | "Extended color light" | "ZHAFire" | "ZHAHumidity" | "ZHALightLevel" | "On/Off light" | "On/Off output" | "On/Off plug-in unit" | "ZHAOpenClose" | "ZHAPower" | "ZHAPresence" | "ZHAPressure" | "Range extender" | "ZHARelativeRotary" | "Smart plug" | "ZHASpectral" | "ZHASwitch" | "ZHATemperature" | "ZHAThermostat" | "ZHATime" | "ZHAVibration" | "Warning device" | "ZHAWater" | "Window covering device" | "ZGPSwitch";
|
|
302
|
+
restapi: "/lights" | "/sensors";
|
|
303
|
+
order: number;
|
|
304
|
+
uuid: [
|
|
305
|
+
"$address.ext",
|
|
306
|
+
string
|
|
307
|
+
] | [
|
|
308
|
+
"$address.ext",
|
|
309
|
+
string,
|
|
310
|
+
string
|
|
311
|
+
];
|
|
312
|
+
items: ("state/windowopen" | "state/water" | "state/voltage" | "state/vibrationstrength" | "state/vibration" | "state/valve" | "state/utc" | "state/tiltangle" | "state/tilt" | "state/test" | "state/temperature" | "state/tampered" | "state/speed" | "state/seconds_remaining" | "state/sat" | "state/rotaryevent" | "state/replacefilter" | "state/reachable" | "state/production" | "state/pressure" | "state/presenceevent" | "state/presence" | "state/power" | "state/pm2_5" | "state/panel" | "state/orientation_z" | "state/orientation_y" | "state/orientation_x" | "state/orientation" | "state/open" | "state/on" | "state/mountingmodeactive" | "state/lux" | "state/lowbattery" | "state/lockstate" | "state/localtime" | "state/lightlevel" | "state/lift" | "state/lastupdated" | "state/lastset" | "state/lastcheckin" | "state/humidity" | "state/hue" | "state/heating" | "state/gradient" | "state/gesture" | "state/fire" | "state/filterruntime" | "state/expectedrotation" | "state/expectedeventduration" | "state/eventduration" | "state/errorcode" | "state/effect" | "state/deviceruntime" | "state/daylight" | "state/dark" | "state/current" | "state/current_P3" | "state/current_P2" | "state/current_P1" | "state/ct" | "state/consumption" | "state/consumption_2" | "state/y" | "state/x" | "state/colormode" | "state/charging" | "state/carbonmonoxide" | "state/buttonevent" | "state/bri" | "state/battery" | "state/angle" | "state/alert" | "state/alarm" | "state/airqualityppb" | "state/airquality" | "state/action" | "config/windowopen_set" | "config/windowcoveringtype" | "config/usertest" | "config/unoccupiedheatsetpoint" | "config/triggerdistance" | "config/tholdoffset" | "config/tholddark" | "config/temperature" | "config/swingmode" | "config/sensitivitymax" | "config/sensitivity" | "config/selftest" | "config/schedule_on" | "config/schedule" | "config/resetpresence" | "config/reachable" | "config/pulseconfiguration" | "config/preset" | "config/pending" | "config/on/startup" | "config/on" | "config/offset" | "config/mountingmode" | "config/mode" | "config/locked" | "config/lock" | "config/ledindication" | "config/interfacemode" | "config/heatsetpoint" | "config/group" | "config/filterlifetime" | "config/fanmode" | "config/externalwindowopen" | "config/externalsensortemp" | "config/enrolled" | "config/duration" | "config/displayflipped" | "config/devicemode" | "config/delay" | "config/ctmin" | "config/ctmax" | "config/coolsetpoint" | "config/controlsequence" | "config/configured" | "config/colorcapabilities" | "config/color/xy/startup_y" | "config/color/xy/startup_x" | "config/color/gradient/reversed" | "config/color/execute_if_off" | "config/color/ct/startup" | "config/clickmode" | "config/checkin" | "config/bri/startup" | "config/bri/onoff_transitiontime" | "config/bri/on_level" | "config/bri/min" | "config/bri/max" | "config/bri/execute_if_off" | "config/battery" | "config/allowtouchlink" | "config/alert" | "cap/transition_block" | "cap/sleeper" | "cap/on/off_with_effect" | "cap/groups/not_supported" | "cap/color/xy/red_y" | "cap/color/xy/red_x" | "cap/color/xy/green_y" | "cap/color/xy/green_x" | "cap/color/xy/blue_y" | "cap/color/xy/blue_x" | "cap/color/gradient/styles" | "cap/color/gradient/pixel_length" | "cap/color/gradient/pixel_count" | "cap/color/gradient/max_segments" | "cap/color/gamut_type" | "cap/color/effects" | "cap/color/ct/min" | "cap/color/ct/max" | "cap/color/ct/computes_xy" | "cap/color/capabilities" | "cap/bri/move_with_onoff" | "cap/bri/min_dim_level" | "cap/alert/trigger_effect" | "attr/uniqueid" | "attr/type" | "attr/swversion" | "attr/swconfigid" | "attr/productname" | "attr/productid" | "attr/powerup" | "attr/poweronlevel" | "attr/poweronct" | "attr/name" | "attr/modelid" | "attr/mode" | "attr/manufacturername" | "attr/lastseen" | "attr/lastannounced" | "attr/id")[];
|
|
172
313
|
};
|
|
173
314
|
|
|
174
|
-
export
|
|
315
|
+
export interface GenericsData {
|
|
316
|
+
attributes: string[]
|
|
317
|
+
manufacturers: Record<string, string>
|
|
318
|
+
deviceTypes: Record<string, string>
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
|
|
322
|
+
export declare function createValidator(generics?: GenericsData): {
|
|
323
|
+
generics: GenericsData;
|
|
324
|
+
loadGeneric: (data: unknown) => DDF;
|
|
325
|
+
validate: (data: unknown) => DDF;
|
|
326
|
+
getSchema: () => ZodType<DDF>;
|
|
327
|
+
};
|
|
175
328
|
|
|
176
329
|
export {};
|
package/dist/ddf-validator.mjs
CHANGED
|
@@ -1,121 +1,192 @@
|
|
|
1
1
|
import { z as t } from "zod";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
"$TYPE_COLOR_TEMPERATURE_LIGHT",
|
|
10
|
-
"$TYPE_CONSUMPTION_SENSOR",
|
|
11
|
-
"$TYPE_DIMMABLE_LIGHT",
|
|
12
|
-
"$TYPE_DIMMABLE_PLUGIN_UNIT",
|
|
13
|
-
"$TYPE_DIMMER_SWITCH",
|
|
14
|
-
"$TYPE_DOOR_LOCK_CONTROLLER",
|
|
15
|
-
"$TYPE_DOOR_LOCK",
|
|
16
|
-
"$TYPE_EXTENDED_COLOR_LIGHT",
|
|
17
|
-
"$TYPE_FIRE_SENSOR",
|
|
18
|
-
"$TYPE_HUMIDITY_SENSOR",
|
|
19
|
-
"$TYPE_LIGHT_LEVEL_SENSOR",
|
|
20
|
-
"$TYPE_ON_OFF_LIGHT",
|
|
21
|
-
"$TYPE_ON_OFF_OUTPUT",
|
|
22
|
-
"$TYPE_ON_OFF_PLUGIN_UNIT",
|
|
23
|
-
"$TYPE_OPEN_CLOSE_SENSOR",
|
|
24
|
-
"$TYPE_POWER_SENSOR",
|
|
25
|
-
"$TYPE_PRESENCE_SENSOR",
|
|
26
|
-
"$TYPE_PRESSURE_SENSOR",
|
|
27
|
-
"$TYPE_RANGE_EXTENDER",
|
|
28
|
-
"$TYPE_RELATIVE_ROTARY",
|
|
29
|
-
"$TYPE_SMART_PLUG",
|
|
30
|
-
"$TYPE_SPECTRAL_SENSOR",
|
|
31
|
-
"$TYPE_SWITCH",
|
|
32
|
-
"$TYPE_TEMPERATURE_SENSOR",
|
|
33
|
-
"$TYPE_THERMOSTAT",
|
|
34
|
-
"$TYPE_VIBRATION_SENSOR",
|
|
35
|
-
"$TYPE_WARNING_DEVICE",
|
|
36
|
-
"$TYPE_WATER_LEAK_SENSOR",
|
|
37
|
-
"$TYPE_WINDOW_COVERING_DEVICE",
|
|
38
|
-
"$TYPE_ZGP_SWITCH",
|
|
39
|
-
"ZHAAirPurifier",
|
|
40
|
-
"ZHAAirQuality",
|
|
41
|
-
"ZHAAlarm",
|
|
42
|
-
"ZHABattery",
|
|
43
|
-
"Color dimmable light",
|
|
44
|
-
"Color light",
|
|
45
|
-
"Color temperature light",
|
|
46
|
-
"ZHAConsumption",
|
|
47
|
-
"Dimmable light",
|
|
48
|
-
"Dimmable plug-in unit",
|
|
49
|
-
"Dimmer switch",
|
|
50
|
-
"Door lock controller",
|
|
51
|
-
"Door Lock",
|
|
52
|
-
"Extended color light",
|
|
53
|
-
"ZHAFire",
|
|
54
|
-
"ZHAHumidity",
|
|
55
|
-
"ZHALightLevel",
|
|
56
|
-
"On/Off light",
|
|
57
|
-
"On/Off output",
|
|
58
|
-
"On/Off plug-in unit",
|
|
59
|
-
"ZHAOpenClose",
|
|
60
|
-
"ZHAPower",
|
|
61
|
-
"ZHAPresence",
|
|
62
|
-
"ZHAPressure",
|
|
63
|
-
"Range extender",
|
|
64
|
-
"ZHARelativeRotary",
|
|
65
|
-
"Smart plug",
|
|
66
|
-
"ZHASpectral",
|
|
67
|
-
"ZHASwitch",
|
|
68
|
-
"ZHATemperature",
|
|
69
|
-
"ZHAThermostat",
|
|
70
|
-
"ZHAVibration",
|
|
71
|
-
"Warning device",
|
|
72
|
-
"ZHAWater",
|
|
73
|
-
"Window covering device",
|
|
74
|
-
"ZGPSwitch",
|
|
75
|
-
"ZHAAncillaryControl",
|
|
76
|
-
"ZHATime",
|
|
77
|
-
"ZHACarbonMonoxide",
|
|
78
|
-
"ZHADoorLock"
|
|
79
|
-
];
|
|
80
|
-
function n(e = void 0) {
|
|
81
|
-
return e === void 0 ? t.string() : t.string().length(2 + e);
|
|
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
|
+
});
|
|
82
9
|
}
|
|
83
|
-
function
|
|
84
|
-
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
|
+
);
|
|
85
16
|
}
|
|
86
|
-
function
|
|
87
|
-
|
|
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);
|
|
88
20
|
}
|
|
89
|
-
function
|
|
21
|
+
function a() {
|
|
90
22
|
return t.union([
|
|
91
23
|
n(2),
|
|
92
24
|
t.number().min(0).max(255)
|
|
93
25
|
]);
|
|
94
26
|
}
|
|
95
|
-
function
|
|
96
|
-
return t.string();
|
|
97
|
-
}
|
|
98
|
-
function u() {
|
|
27
|
+
function g() {
|
|
99
28
|
return t.custom((e) => {
|
|
100
29
|
if (!Array.isArray(e) || e.length % 2 !== 0)
|
|
101
30
|
return !1;
|
|
102
|
-
for (let
|
|
103
|
-
const l = e[
|
|
104
|
-
if (typeof l != "number" || typeof
|
|
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")
|
|
105
34
|
return !1;
|
|
106
35
|
}
|
|
107
36
|
return !0;
|
|
108
37
|
}, "The value must be an array with an even number of values and alternating between number and string.");
|
|
109
38
|
}
|
|
110
|
-
function
|
|
111
|
-
return
|
|
39
|
+
function d() {
|
|
40
|
+
return t.union([
|
|
41
|
+
t.tuple([
|
|
42
|
+
t.literal("$address.ext"),
|
|
43
|
+
n(2)
|
|
44
|
+
]),
|
|
45
|
+
t.tuple([
|
|
46
|
+
t.literal("$address.ext"),
|
|
47
|
+
n(2),
|
|
48
|
+
n(4)
|
|
49
|
+
])
|
|
50
|
+
]);
|
|
112
51
|
}
|
|
113
|
-
function
|
|
114
|
-
return t.
|
|
115
|
-
|
|
52
|
+
function o() {
|
|
53
|
+
return t.string();
|
|
54
|
+
}
|
|
55
|
+
function r() {
|
|
56
|
+
return t.string();
|
|
57
|
+
}
|
|
58
|
+
function b() {
|
|
59
|
+
return t.discriminatedUnion("fn", [
|
|
60
|
+
t.strictObject({
|
|
61
|
+
fn: t.literal("none")
|
|
62
|
+
}),
|
|
63
|
+
t.strictObject({
|
|
64
|
+
fn: t.undefined(),
|
|
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())
|
|
70
|
+
}),
|
|
71
|
+
t.strictObject({
|
|
72
|
+
fn: t.literal("zcl"),
|
|
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())
|
|
78
|
+
}),
|
|
79
|
+
t.strictObject({
|
|
80
|
+
fn: t.literal("tuya")
|
|
81
|
+
})
|
|
116
82
|
]);
|
|
117
83
|
}
|
|
118
|
-
function
|
|
84
|
+
function f() {
|
|
85
|
+
return t.discriminatedUnion("fn", [
|
|
86
|
+
t.strictObject({
|
|
87
|
+
fn: t.undefined(),
|
|
88
|
+
at: t.optional(n(4)),
|
|
89
|
+
cl: n(4),
|
|
90
|
+
cppsrc: t.optional(t.string()),
|
|
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), {
|
|
97
|
+
message: "eval and script should not both be present"
|
|
98
|
+
}).innerType(),
|
|
99
|
+
t.strictObject({
|
|
100
|
+
fn: t.literal("zcl"),
|
|
101
|
+
at: t.optional(n(4)),
|
|
102
|
+
cl: n(4),
|
|
103
|
+
cppsrc: t.optional(t.string()),
|
|
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), {
|
|
110
|
+
message: "eval and script should not both be present"
|
|
111
|
+
}).innerType(),
|
|
112
|
+
t.strictObject({
|
|
113
|
+
fn: t.literal("ias:zonestatus"),
|
|
114
|
+
mask: t.optional(t.enum(["alarm1", "alarm2"]).or(t.literal("alarm1,alarm2")))
|
|
115
|
+
}),
|
|
116
|
+
t.strictObject({
|
|
117
|
+
fn: t.literal("numtostr"),
|
|
118
|
+
srcitem: t.enum(["state/airqualityppb", "state/pm2_5"]),
|
|
119
|
+
op: t.literal("le"),
|
|
120
|
+
to: g()
|
|
121
|
+
}),
|
|
122
|
+
t.strictObject({
|
|
123
|
+
fn: t.literal("time")
|
|
124
|
+
}),
|
|
125
|
+
t.strictObject({
|
|
126
|
+
fn: t.literal("xiaomi:special"),
|
|
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), {
|
|
133
|
+
message: "eval and script should not both be present"
|
|
134
|
+
}).innerType(),
|
|
135
|
+
t.strictObject({
|
|
136
|
+
fn: t.literal("tuya"),
|
|
137
|
+
dpid: t.number(),
|
|
138
|
+
eval: t.optional(r()),
|
|
139
|
+
script: t.optional(o())
|
|
140
|
+
}).refine((e) => !("eval" in e && "script" in e), {
|
|
141
|
+
message: "eval and script should not both be present"
|
|
142
|
+
}).innerType()
|
|
143
|
+
]);
|
|
144
|
+
}
|
|
145
|
+
function h() {
|
|
146
|
+
return t.discriminatedUnion("fn", [
|
|
147
|
+
t.strictObject({
|
|
148
|
+
fn: t.literal("none")
|
|
149
|
+
}),
|
|
150
|
+
t.strictObject({
|
|
151
|
+
fn: t.undefined(),
|
|
152
|
+
at: t.optional(n(4).or(t.array(n(4)))),
|
|
153
|
+
"state.timeout": t.optional(t.number()),
|
|
154
|
+
"change.timeout": t.optional(t.number()),
|
|
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), {
|
|
162
|
+
message: "eval and script should not both be present"
|
|
163
|
+
}).innerType(),
|
|
164
|
+
t.strictObject({
|
|
165
|
+
fn: t.literal("zcl"),
|
|
166
|
+
at: t.optional(n(4).or(t.array(n(4)))),
|
|
167
|
+
"state.timeout": t.optional(t.number()),
|
|
168
|
+
"change.timeout": t.optional(t.number()),
|
|
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), {
|
|
176
|
+
message: "eval and script should not both be present"
|
|
177
|
+
}).innerType(),
|
|
178
|
+
t.strictObject({
|
|
179
|
+
fn: t.literal("tuya"),
|
|
180
|
+
dpid: t.number(),
|
|
181
|
+
dt: n(2),
|
|
182
|
+
eval: t.optional(r()),
|
|
183
|
+
script: t.optional(o())
|
|
184
|
+
}).refine((e) => !("eval" in e && "script" in e), {
|
|
185
|
+
message: "eval and script should not both be present"
|
|
186
|
+
}).innerType()
|
|
187
|
+
]);
|
|
188
|
+
}
|
|
189
|
+
function y(e) {
|
|
119
190
|
return t.strictObject({
|
|
120
191
|
$schema: t.optional(t.string()),
|
|
121
192
|
schema: t.literal("devcap1.schema.json"),
|
|
@@ -126,38 +197,31 @@ function E() {
|
|
|
126
197
|
modelid: t.string().or(t.array(t.string())),
|
|
127
198
|
vendor: t.optional(t.string()),
|
|
128
199
|
comment: t.optional(t.string()),
|
|
129
|
-
matchexpr: t.optional(
|
|
130
|
-
path: t.optional(
|
|
200
|
+
matchexpr: t.optional(r()),
|
|
201
|
+
path: t.optional(o()),
|
|
131
202
|
product: t.optional(t.string()),
|
|
132
203
|
sleeper: t.optional(t.boolean()),
|
|
133
204
|
supportsMgmtBind: t.optional(t.boolean()),
|
|
134
205
|
status: t.enum(["Draft", "Bronze", "Silver", "Gold"]).describe("The code quality of the DDF file."),
|
|
135
|
-
subdevices: t.array(
|
|
136
|
-
bindings: t.optional(t.array(
|
|
137
|
-
}).refine((
|
|
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, {
|
|
138
209
|
message: "manufacturername and modelid should be both strings or arrays with the same length.",
|
|
139
210
|
path: ["manufacturername", "modelid"]
|
|
140
|
-
});
|
|
211
|
+
}).innerType();
|
|
141
212
|
}
|
|
142
|
-
function
|
|
213
|
+
function j(e) {
|
|
143
214
|
return t.strictObject({
|
|
144
|
-
type: t.
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
t.tuple([
|
|
148
|
-
t.literal("$address.ext"),
|
|
149
|
-
n(2)
|
|
150
|
-
]),
|
|
151
|
-
t.tuple([
|
|
152
|
-
t.literal("$address.ext"),
|
|
153
|
-
n(2),
|
|
154
|
-
n(4)
|
|
155
|
-
])
|
|
215
|
+
type: t.union([
|
|
216
|
+
t.enum(Object.keys(e.deviceTypes)),
|
|
217
|
+
t.enum(Object.values(e.deviceTypes))
|
|
156
218
|
]),
|
|
219
|
+
restapi: t.enum(["/lights", "/sensors"]),
|
|
220
|
+
uuid: d(),
|
|
157
221
|
fingerprint: t.optional(t.strictObject({
|
|
158
222
|
profile: n(4),
|
|
159
223
|
device: n(4),
|
|
160
|
-
endpoint:
|
|
224
|
+
endpoint: a(),
|
|
161
225
|
in: t.optional(t.array(n(4))),
|
|
162
226
|
out: t.optional(t.array(n(4)))
|
|
163
227
|
})),
|
|
@@ -170,160 +234,35 @@ function d() {
|
|
|
170
234
|
buttons: t.optional(t.any()),
|
|
171
235
|
// TODO validate this
|
|
172
236
|
buttonevents: t.optional(t.any()),
|
|
173
|
-
items: t.array(
|
|
237
|
+
items: t.array(O(e)),
|
|
174
238
|
example: t.optional(t.unknown())
|
|
175
239
|
});
|
|
176
240
|
}
|
|
177
|
-
function
|
|
241
|
+
function O(e) {
|
|
178
242
|
return t.strictObject({
|
|
179
|
-
name: t.
|
|
243
|
+
name: t.enum(e.attributes),
|
|
180
244
|
description: t.optional(t.string()),
|
|
181
245
|
comment: t.optional(t.string()),
|
|
182
246
|
public: t.optional(t.boolean()),
|
|
183
247
|
static: t.optional(t.union([t.string(), t.number(), t.boolean()])),
|
|
184
248
|
range: t.optional(t.tuple([t.number(), t.number()])),
|
|
185
|
-
deprecated: t.optional(
|
|
249
|
+
deprecated: t.optional(m()),
|
|
186
250
|
access: t.optional(t.literal("R")),
|
|
187
|
-
read: t.optional(
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
fn: t.literal("none")
|
|
191
|
-
}),
|
|
192
|
-
t.strictObject({
|
|
193
|
-
fn: t.undefined(),
|
|
194
|
-
at: t.optional(n(4).or(t.array(n(4)))),
|
|
195
|
-
cl: n(4),
|
|
196
|
-
ep: t.optional(i()),
|
|
197
|
-
mf: t.optional(n(4)),
|
|
198
|
-
eval: t.optional(o())
|
|
199
|
-
}),
|
|
200
|
-
t.strictObject({
|
|
201
|
-
fn: t.literal("zcl"),
|
|
202
|
-
at: t.optional(n(4).or(t.array(n(4)))),
|
|
203
|
-
cl: n(4),
|
|
204
|
-
ep: t.optional(i()),
|
|
205
|
-
mf: t.optional(n(4)),
|
|
206
|
-
eval: t.optional(o())
|
|
207
|
-
}),
|
|
208
|
-
t.strictObject({
|
|
209
|
-
fn: t.literal("tuya")
|
|
210
|
-
})
|
|
211
|
-
])
|
|
212
|
-
),
|
|
213
|
-
parse: t.optional(
|
|
214
|
-
t.discriminatedUnion("fn", [
|
|
215
|
-
t.strictObject({
|
|
216
|
-
fn: t.undefined(),
|
|
217
|
-
at: t.optional(n(4)),
|
|
218
|
-
cl: n(4),
|
|
219
|
-
cppsrc: t.optional(t.string()),
|
|
220
|
-
ep: t.optional(i()),
|
|
221
|
-
cmd: t.optional(n(2)),
|
|
222
|
-
mf: t.optional(n(4)),
|
|
223
|
-
eval: t.optional(o()),
|
|
224
|
-
script: t.optional(r())
|
|
225
|
-
}).refine((e) => !("eval" in e && "script" in e), {
|
|
226
|
-
message: "eval and script should not both be present"
|
|
227
|
-
}).innerType(),
|
|
228
|
-
t.strictObject({
|
|
229
|
-
fn: t.literal("zcl"),
|
|
230
|
-
at: t.optional(n(4)),
|
|
231
|
-
cl: n(4),
|
|
232
|
-
cppsrc: t.optional(t.string()),
|
|
233
|
-
ep: t.optional(i()),
|
|
234
|
-
cmd: t.optional(n(2)),
|
|
235
|
-
mf: t.optional(n(4)),
|
|
236
|
-
eval: t.optional(o()),
|
|
237
|
-
script: t.optional(r())
|
|
238
|
-
}).refine((e) => !("eval" in e && "script" in e), {
|
|
239
|
-
message: "eval and script should not both be present"
|
|
240
|
-
}).innerType(),
|
|
241
|
-
t.strictObject({
|
|
242
|
-
fn: t.literal("ias:zonestatus"),
|
|
243
|
-
mask: t.enum(["alarm1", "alarm2"])
|
|
244
|
-
}),
|
|
245
|
-
t.strictObject({
|
|
246
|
-
fn: t.literal("numtostr"),
|
|
247
|
-
srcitem: t.enum(["state/airqualityppb", "state/pm2_5"]),
|
|
248
|
-
op: t.literal("le"),
|
|
249
|
-
to: u()
|
|
250
|
-
}),
|
|
251
|
-
t.strictObject({
|
|
252
|
-
fn: t.literal("xiaomi:special"),
|
|
253
|
-
ep: t.optional(i()),
|
|
254
|
-
at: t.optional(n(4)),
|
|
255
|
-
idx: n(2),
|
|
256
|
-
eval: t.optional(o()),
|
|
257
|
-
script: t.optional(r())
|
|
258
|
-
}).refine((e) => !("eval" in e && "script" in e), {
|
|
259
|
-
message: "eval and script should not both be present"
|
|
260
|
-
}).innerType(),
|
|
261
|
-
t.strictObject({
|
|
262
|
-
fn: t.literal("tuya"),
|
|
263
|
-
dpid: t.number(),
|
|
264
|
-
eval: t.optional(o()),
|
|
265
|
-
script: t.optional(r())
|
|
266
|
-
}).refine((e) => !("eval" in e && "script" in e), {
|
|
267
|
-
message: "eval and script should not both be present"
|
|
268
|
-
}).innerType()
|
|
269
|
-
])
|
|
270
|
-
),
|
|
271
|
-
write: t.optional(
|
|
272
|
-
t.discriminatedUnion("fn", [
|
|
273
|
-
t.strictObject({
|
|
274
|
-
fn: t.literal("none")
|
|
275
|
-
}),
|
|
276
|
-
t.strictObject({
|
|
277
|
-
fn: t.undefined(),
|
|
278
|
-
at: t.optional(n(4).or(t.array(n(4)))),
|
|
279
|
-
"state.timeout": t.optional(t.number()),
|
|
280
|
-
"change.timeout": t.optional(t.number()),
|
|
281
|
-
cl: n(4),
|
|
282
|
-
dt: n(2),
|
|
283
|
-
ep: t.optional(i()),
|
|
284
|
-
mf: t.optional(n(4)),
|
|
285
|
-
eval: t.optional(o()),
|
|
286
|
-
script: t.optional(r())
|
|
287
|
-
}).refine((e) => !("eval" in e && "script" in e), {
|
|
288
|
-
message: "eval and script should not both be present"
|
|
289
|
-
}).innerType(),
|
|
290
|
-
t.strictObject({
|
|
291
|
-
fn: t.literal("zcl"),
|
|
292
|
-
at: t.optional(n(4).or(t.array(n(4)))),
|
|
293
|
-
"state.timeout": t.optional(t.number()),
|
|
294
|
-
"change.timeout": t.optional(t.number()),
|
|
295
|
-
cl: n(4),
|
|
296
|
-
dt: n(2),
|
|
297
|
-
ep: t.optional(i()),
|
|
298
|
-
mf: t.optional(n(4)),
|
|
299
|
-
eval: t.optional(o()),
|
|
300
|
-
script: t.optional(r())
|
|
301
|
-
}).refine((e) => !("eval" in e && "script" in e), {
|
|
302
|
-
message: "eval and script should not both be present"
|
|
303
|
-
}).innerType(),
|
|
304
|
-
t.strictObject({
|
|
305
|
-
fn: t.literal("tuya"),
|
|
306
|
-
dpid: t.number(),
|
|
307
|
-
dt: n(2),
|
|
308
|
-
eval: t.optional(o()),
|
|
309
|
-
script: t.optional(r())
|
|
310
|
-
}).refine((e) => !("eval" in e && "script" in e), {
|
|
311
|
-
message: "eval and script should not both be present"
|
|
312
|
-
}).innerType()
|
|
313
|
-
])
|
|
314
|
-
),
|
|
251
|
+
read: t.optional(b()),
|
|
252
|
+
parse: t.optional(f()),
|
|
253
|
+
write: t.optional(h()),
|
|
315
254
|
awake: t.optional(t.boolean()),
|
|
316
255
|
default: t.optional(t.unknown()),
|
|
317
256
|
values: t.optional(t.unknown()),
|
|
318
257
|
"refresh.interval": t.optional(t.number())
|
|
319
258
|
});
|
|
320
259
|
}
|
|
321
|
-
function
|
|
260
|
+
function T(e) {
|
|
322
261
|
return t.discriminatedUnion("bind", [
|
|
323
262
|
t.strictObject({
|
|
324
263
|
bind: t.literal("unicast"),
|
|
325
|
-
"src.ep":
|
|
326
|
-
"dst.ep": t.optional(
|
|
264
|
+
"src.ep": a(),
|
|
265
|
+
"dst.ep": t.optional(a()),
|
|
327
266
|
cl: n(4),
|
|
328
267
|
report: t.optional(t.array(t.strictObject({
|
|
329
268
|
at: n(4),
|
|
@@ -336,12 +275,84 @@ function _() {
|
|
|
336
275
|
}),
|
|
337
276
|
t.strictObject({
|
|
338
277
|
bind: t.literal("groupcast"),
|
|
339
|
-
"src.ep":
|
|
278
|
+
"src.ep": a(),
|
|
340
279
|
cl: n(4),
|
|
341
280
|
"config.group": t.number()
|
|
342
281
|
})
|
|
343
282
|
]);
|
|
344
283
|
}
|
|
284
|
+
function w(e) {
|
|
285
|
+
return t.strictObject({
|
|
286
|
+
$schema: t.optional(t.string()),
|
|
287
|
+
schema: t.literal("resourceitem1.schema.json"),
|
|
288
|
+
id: t.string(),
|
|
289
|
+
description: t.string(),
|
|
290
|
+
deprecated: t.optional(m()),
|
|
291
|
+
datatype: t.enum(["String", "Bool", "Int8", "Int16", "Int32", "Int64", "UInt8", "UInt16", "UInt32", "UInt64", "Array", "Array[3]", "ISO 8601 timestamp"]),
|
|
292
|
+
access: t.enum(["R", "W", "RW"]),
|
|
293
|
+
public: t.boolean(),
|
|
294
|
+
implicit: t.optional(t.boolean()),
|
|
295
|
+
managed: t.optional(t.boolean()),
|
|
296
|
+
static: t.optional(t.boolean()),
|
|
297
|
+
virtual: t.optional(t.boolean()),
|
|
298
|
+
parse: t.optional(f()),
|
|
299
|
+
read: t.optional(b()),
|
|
300
|
+
write: t.optional(h()),
|
|
301
|
+
"refresh.interval": t.optional(t.number()),
|
|
302
|
+
// TODO Validate this
|
|
303
|
+
values: t.optional(t.unknown()),
|
|
304
|
+
range: t.optional(t.tuple([t.number(), t.number()])),
|
|
305
|
+
default: t.optional(t.unknown())
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
function x(e) {
|
|
309
|
+
return t.strictObject({
|
|
310
|
+
$schema: t.optional(t.string()),
|
|
311
|
+
schema: t.literal("subdevice1.schema.json"),
|
|
312
|
+
type: t.enum(Object.keys(e.deviceTypes)),
|
|
313
|
+
name: t.enum(Object.values(e.deviceTypes)),
|
|
314
|
+
restapi: t.enum(["/lights", "/sensors"]),
|
|
315
|
+
order: t.number(),
|
|
316
|
+
uuid: d(),
|
|
317
|
+
items: t.array(t.enum(e.attributes))
|
|
318
|
+
});
|
|
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
|
+
}
|
|
345
356
|
export {
|
|
346
|
-
|
|
357
|
+
I as createValidator
|
|
347
358
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@deconz-community/ddf-validator",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "Validating DDF files for deconz",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"deconz",
|
|
@@ -56,7 +56,6 @@
|
|
|
56
56
|
"@typescript-eslint/eslint-plugin": "^5.51.0",
|
|
57
57
|
"@typescript-eslint/parser": "^5.51.0",
|
|
58
58
|
"degit": "^2.8.4",
|
|
59
|
-
"dts-bundle-generator": "^7.2.0",
|
|
60
59
|
"eslint": "^8.33.0",
|
|
61
60
|
"eslint-config-prettier": "^8.6.0",
|
|
62
61
|
"eslint-plugin-prettier": "^4.2.1",
|