Skip to content

Commit 008578a

Browse files
committed
✨ define device types using zod for config validation
1 parent 7638747 commit 008578a

1 file changed

Lines changed: 84 additions & 50 deletions

File tree

src/types/devices.ts

Lines changed: 84 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
* this program. If not, see <https://www.gnu.org/licenses/>.
1414
*/
1515

16+
import { z } from "zod"
1617
import { DeviceMetadata } from "./device-metadata"
1718

1819
export enum DeviceCommand {
@@ -49,17 +50,21 @@ export type DeviceAnalogInfo = {
4950
distance: number
5051
}
5152

52-
export type DeviceCalibration = {
53-
initialRestValue: number
54-
initialBottomOutThreshold: number
55-
}
53+
export const deviceCalibrationSchema = z.object({
54+
initialRestValue: z.number().int().min(0),
55+
initialBottomOutThreshold: z.number().int().min(0),
56+
})
5657

57-
export type DeviceActuation = {
58-
actuationPoint: number
59-
rtDown: number
60-
rtUp: number
61-
continuous: boolean
62-
}
58+
export type DeviceCalibration = z.infer<typeof deviceCalibrationSchema>
59+
60+
export const deviceActuationSchema = z.object({
61+
actuationPoint: z.number().int().min(0).max(255),
62+
rtDown: z.number().int().min(0).max(255),
63+
rtUp: z.number().int().min(0).max(255),
64+
continuous: z.boolean(),
65+
})
66+
67+
export type DeviceActuation = z.infer<typeof deviceActuationSchema>
6368

6469
export enum DeviceAKType {
6570
NONE = 0,
@@ -69,9 +74,11 @@ export enum DeviceAKType {
6974
TOGGLE,
7075
}
7176

72-
export type DeviceAKNone = {
73-
type: DeviceAKType.NONE
74-
}
77+
export const deviceAKNoneSchema = z.object({
78+
type: z.literal(DeviceAKType.NONE),
79+
})
80+
81+
export type DeviceAKNone = z.infer<typeof deviceAKNoneSchema>
7582

7683
export enum DeviceNullBindBehavior {
7784
LAST = 0,
@@ -81,12 +88,18 @@ export enum DeviceNullBindBehavior {
8188
DISTANCE,
8289
}
8390

84-
export type DeviceAKNullBind = {
85-
type: DeviceAKType.NULL_BIND
86-
secondaryKey: number
87-
behavior: DeviceNullBindBehavior
88-
bottomOutPoint: number
89-
}
91+
export const deviceAKNullBind = z.object({
92+
type: z.literal(DeviceAKType.NULL_BIND),
93+
secondaryKey: z.number().min(0).max(255),
94+
behavior: z
95+
.number()
96+
.refine((val) => Object.values(DeviceNullBindBehavior).includes(val), {
97+
error: "Invalid Null Bind behavior",
98+
}),
99+
bottomOutPoint: z.number().min(0).max(255),
100+
})
101+
102+
export type DeviceAKNullBind = z.infer<typeof deviceAKNullBind>
90103

91104
export enum DeviceDKSAction {
92105
HOLD = 0,
@@ -95,37 +108,58 @@ export enum DeviceDKSAction {
95108
TAP,
96109
}
97110

98-
export type DeviceAKDynamicKeystroke = {
99-
type: DeviceAKType.DYNAMIC_KEYSTROKE
100-
keycodes: number[]
101-
bitmap: DeviceDKSAction[][]
102-
bottomOutPoint: number
103-
}
104-
105-
export type DeviceAKTapHold = {
106-
type: DeviceAKType.TAP_HOLD
107-
tapKeycode: number
108-
holdKeycode: number
109-
tappingTerm: number
110-
holdOnOtherKeyPress: boolean
111-
}
112-
113-
export type DeviceAKToggle = {
114-
type: DeviceAKType.TOGGLE
115-
keycode: number
116-
tappingTerm: number
117-
}
118-
119-
export type DeviceAdvancedKey = {
120-
layer: number
121-
key: number
122-
ak:
123-
| DeviceAKNone
124-
| DeviceAKNullBind
125-
| DeviceAKDynamicKeystroke
126-
| DeviceAKTapHold
127-
| DeviceAKToggle
128-
}
111+
export const deviceAKDynamicKeystroke = z.object({
112+
type: z.literal(DeviceAKType.DYNAMIC_KEYSTROKE),
113+
keycodes: z.array(z.number().int().min(0).max(255)).length(4),
114+
bitmap: z
115+
.array(
116+
z
117+
.array(
118+
z
119+
.number()
120+
.refine((val) => Object.values(DeviceDKSAction).includes(val), {
121+
error: "Invalid Dynamic Keystroke action",
122+
}),
123+
)
124+
.length(4),
125+
)
126+
.length(4),
127+
bottomOutPoint: z.number().int().min(0).max(255),
128+
})
129+
130+
export type DeviceAKDynamicKeystroke = z.infer<typeof deviceAKDynamicKeystroke>
131+
132+
export const deviceAKTapHold = z.object({
133+
type: z.literal(DeviceAKType.TAP_HOLD),
134+
tapKeycode: z.number().int().min(0).max(255),
135+
holdKeycode: z.number().int().min(0).max(255),
136+
tappingTerm: z.number().int().min(0).max(65535),
137+
holdOnOtherKeyPress: z.boolean(),
138+
})
139+
140+
export type DeviceAKTapHold = z.infer<typeof deviceAKTapHold>
141+
142+
export const deviceAKToggle = z.object({
143+
type: z.literal(DeviceAKType.TOGGLE),
144+
keycode: z.number().int().min(0).max(255),
145+
tappingTerm: z.number().int().min(0).max(65535),
146+
})
147+
148+
export type DeviceAKToggle = z.infer<typeof deviceAKToggle>
149+
150+
export const deviceAdvancedKeySchema = z.object({
151+
layer: z.number().int().min(0).max(7),
152+
key: z.number().int().min(0).max(255),
153+
ak: z.union([
154+
deviceAKNoneSchema,
155+
deviceAKNullBind,
156+
deviceAKDynamicKeystroke,
157+
deviceAKTapHold,
158+
deviceAKToggle,
159+
]),
160+
})
161+
162+
export type DeviceAdvancedKey = z.infer<typeof deviceAdvancedKeySchema>
129163

130164
export type DeviceAction = {
131165
connect(): Promise<void>

0 commit comments

Comments
 (0)