@nebulahome/package-sdk 0.0.0-stage → 1.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/CHANGELOG.md +26 -0
- package/LICENSE +21 -0
- package/README.md +141 -2
- package/dist/chunks/context.d.ts +369 -0
- package/dist/chunks/host.js +53 -0
- package/dist/chunks/json.d.ts +657 -0
- package/dist/chunks/node-build.js +20009 -0
- package/dist/chunks/props.d.ts +68 -0
- package/dist/chunks/version.js +12 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +3556 -0
- package/dist/components.d.ts +381 -0
- package/dist/components.js +210 -0
- package/dist/index.d.ts +205 -0
- package/dist/index.js +243 -0
- package/dist/server.d.ts +30 -0
- package/dist/server.js +17 -0
- package/dist/styles.css +549 -0
- package/dist/testing.d.ts +117 -0
- package/dist/testing.js +608 -0
- package/dist/ui.d.ts +320 -0
- package/dist/ui.js +180 -0
- package/dist/vite.d.ts +88 -0
- package/dist/vite.js +2 -0
- package/package.json +110 -3
|
@@ -0,0 +1,657 @@
|
|
|
1
|
+
//#region src/entities.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Entity identifiers: `<domain>.<object id>`, as the platform writes them everywhere - in its
|
|
4
|
+
* API, on its bus, in automations. A package never composes one by hand: the server's
|
|
5
|
+
* `ctx.entityId` does, and these read one back.
|
|
6
|
+
*/
|
|
7
|
+
/** The kinds of thing an entity is. */
|
|
8
|
+
declare const ENTITY_DOMAINS: readonly ["light", "switch", "sensor", "binary_sensor", "cover", "lock", "climate", "media_player", "camera", "button", "update", "lawn_mower", "select", "number", "vacuum", "image", "custom", "alias"];
|
|
9
|
+
/** The kind of thing an entity is. */
|
|
10
|
+
type EntityDomain = (typeof ENTITY_DOMAINS)[number];
|
|
11
|
+
/** An entity's identifier: `sensor.weather_temperature`. */
|
|
12
|
+
type EntityId = string;
|
|
13
|
+
/** What an entity identifier is made of. */
|
|
14
|
+
type ParsedEntityId = {
|
|
15
|
+
readonly domain: EntityDomain;
|
|
16
|
+
readonly objectId: string;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Reads an entity identifier.
|
|
20
|
+
*
|
|
21
|
+
* @param entityId - The identifier.
|
|
22
|
+
* @returns Its domain and object id, or undefined when it is not one.
|
|
23
|
+
*/
|
|
24
|
+
declare function parseEntityId(entityId: string): ParsedEntityId | undefined;
|
|
25
|
+
/**
|
|
26
|
+
* Says whether a value is an entity identifier.
|
|
27
|
+
*
|
|
28
|
+
* @param value - The value.
|
|
29
|
+
* @returns True when it is a string the platform would take as one.
|
|
30
|
+
*/
|
|
31
|
+
declare function isEntityId(value: unknown): value is EntityId;
|
|
32
|
+
//#endregion
|
|
33
|
+
//#region src/capabilities.d.ts
|
|
34
|
+
/** Every capability an entity may declare. */
|
|
35
|
+
type CapabilityName = 'on_off' | 'level' | 'color_hs' | 'color_temp' | 'cover' | 'lock' | 'thermostat' | 'sensor_numeric' | 'sensor_binary' | 'sensor_text' | 'media_player' | 'camera' | 'button' | 'update' | 'lawn_mower' | 'select' | 'number' | 'vacuum' | 'image' | 'custom';
|
|
36
|
+
/** How a sensor's readings add up: Home Assistant's state classes, for statistics. */
|
|
37
|
+
type EntityStateClass = 'measurement' | 'total' | 'total_increasing';
|
|
38
|
+
/** The modes a thermostat may be set to. */
|
|
39
|
+
type ThermostatMode = 'off' | 'heat' | 'cool' | 'auto' | 'fan_only' | 'dry';
|
|
40
|
+
/** What a thermostat is doing, which is not the mode it is set to. */
|
|
41
|
+
type ThermostatAction = 'off' | 'idle' | 'heating' | 'cooling' | 'drying' | 'fan';
|
|
42
|
+
/** What a player is doing. */
|
|
43
|
+
type PlaybackState = 'playing' | 'paused' | 'stopped' | 'idle' | 'buffering';
|
|
44
|
+
/** What a robot mower is doing. */
|
|
45
|
+
type LawnMowerActivity = 'mowing' | 'paused' | 'returning' | 'docked' | 'idle' | 'error';
|
|
46
|
+
/** What a robot vacuum is doing. */
|
|
47
|
+
type VacuumActivity = 'cleaning' | 'paused' | 'returning' | 'docked' | 'idle' | 'error';
|
|
48
|
+
/** One room of a robot's map. */
|
|
49
|
+
type VacuumRoom = {
|
|
50
|
+
readonly id: string;
|
|
51
|
+
readonly name: string;
|
|
52
|
+
};
|
|
53
|
+
/** One choice of a select. */
|
|
54
|
+
type SelectOption = {
|
|
55
|
+
readonly value: string;
|
|
56
|
+
readonly label: string;
|
|
57
|
+
};
|
|
58
|
+
/** The pictures an image entity may be. */
|
|
59
|
+
type ImageContentType = 'image/svg+xml' | 'image/png' | 'image/jpeg';
|
|
60
|
+
/** A value of a custom entity's field: a scalar, or nothing yet. */
|
|
61
|
+
type CustomValue = string | number | boolean | null;
|
|
62
|
+
/** Each capability's state, as the house reads it back: every field there. */
|
|
63
|
+
type CapabilityStates = {
|
|
64
|
+
readonly on_off: {
|
|
65
|
+
readonly isOn: boolean;
|
|
66
|
+
};
|
|
67
|
+
readonly level: {
|
|
68
|
+
readonly level: number;
|
|
69
|
+
};
|
|
70
|
+
readonly color_hs: {
|
|
71
|
+
readonly hue: number;
|
|
72
|
+
readonly saturation: number;
|
|
73
|
+
};
|
|
74
|
+
readonly color_temp: {
|
|
75
|
+
readonly mireds: number;
|
|
76
|
+
};
|
|
77
|
+
readonly cover: {
|
|
78
|
+
readonly position: number;
|
|
79
|
+
readonly tilt?: number;
|
|
80
|
+
readonly motion: 'opening' | 'closing' | 'stopped';
|
|
81
|
+
};
|
|
82
|
+
readonly lock: {
|
|
83
|
+
readonly lockState: 'locked' | 'unlocked' | 'jammed';
|
|
84
|
+
};
|
|
85
|
+
readonly thermostat: {
|
|
86
|
+
readonly currentTemperature: number;
|
|
87
|
+
readonly targetTemperature: number;
|
|
88
|
+
readonly mode: ThermostatMode;
|
|
89
|
+
readonly action: ThermostatAction;
|
|
90
|
+
readonly humidity?: number;
|
|
91
|
+
};
|
|
92
|
+
readonly sensor_numeric: {
|
|
93
|
+
readonly value: number;
|
|
94
|
+
};
|
|
95
|
+
readonly sensor_binary: {
|
|
96
|
+
readonly isOn: boolean;
|
|
97
|
+
};
|
|
98
|
+
readonly sensor_text: {
|
|
99
|
+
readonly value: string;
|
|
100
|
+
};
|
|
101
|
+
readonly media_player: {
|
|
102
|
+
readonly playback: PlaybackState;
|
|
103
|
+
readonly volume: number;
|
|
104
|
+
readonly isMuted: boolean;
|
|
105
|
+
readonly source?: string;
|
|
106
|
+
readonly mediaTitle?: string;
|
|
107
|
+
readonly mediaArtist?: string;
|
|
108
|
+
readonly mediaDurationSeconds?: number;
|
|
109
|
+
readonly mediaPositionSeconds?: number;
|
|
110
|
+
};
|
|
111
|
+
readonly camera: {
|
|
112
|
+
readonly isStreamAvailable: boolean;
|
|
113
|
+
readonly snapshotPath?: string;
|
|
114
|
+
readonly isRecording: boolean;
|
|
115
|
+
};
|
|
116
|
+
readonly button: Readonly<Record<never, never>>;
|
|
117
|
+
readonly update: {
|
|
118
|
+
readonly installedVersion: string | null;
|
|
119
|
+
readonly latestVersion: string | null;
|
|
120
|
+
readonly isInstalling: boolean;
|
|
121
|
+
readonly progress: number | null;
|
|
122
|
+
};
|
|
123
|
+
readonly lawn_mower: {
|
|
124
|
+
readonly activity: LawnMowerActivity;
|
|
125
|
+
readonly isResumable: boolean;
|
|
126
|
+
};
|
|
127
|
+
readonly select: {
|
|
128
|
+
readonly option: string | null;
|
|
129
|
+
};
|
|
130
|
+
readonly number: {
|
|
131
|
+
readonly value: number | null;
|
|
132
|
+
};
|
|
133
|
+
readonly vacuum: {
|
|
134
|
+
readonly activity: VacuumActivity;
|
|
135
|
+
readonly rooms: readonly VacuumRoom[];
|
|
136
|
+
readonly isResumable: boolean;
|
|
137
|
+
};
|
|
138
|
+
readonly image: {
|
|
139
|
+
readonly contentType: ImageContentType;
|
|
140
|
+
readonly revision: string;
|
|
141
|
+
readonly width?: number;
|
|
142
|
+
readonly height?: number;
|
|
143
|
+
};
|
|
144
|
+
readonly custom: {
|
|
145
|
+
readonly values: Readonly<Record<string, CustomValue>>;
|
|
146
|
+
};
|
|
147
|
+
};
|
|
148
|
+
/** Each capability's state, as a package reports it: what has a default may be left out. */
|
|
149
|
+
type ReportedStates = Omit<CapabilityStates, 'camera' | 'update' | 'lawn_mower' | 'select' | 'number' | 'vacuum'> & {
|
|
150
|
+
readonly camera: Omit<CapabilityStates['camera'], 'isRecording'> & {
|
|
151
|
+
readonly isRecording?: boolean;
|
|
152
|
+
};
|
|
153
|
+
readonly update: Partial<CapabilityStates['update']>;
|
|
154
|
+
readonly lawn_mower: Omit<CapabilityStates['lawn_mower'], 'isResumable'> & {
|
|
155
|
+
readonly isResumable?: boolean;
|
|
156
|
+
};
|
|
157
|
+
readonly select: Partial<CapabilityStates['select']>;
|
|
158
|
+
readonly number: Partial<CapabilityStates['number']>;
|
|
159
|
+
readonly vacuum: Pick<CapabilityStates['vacuum'], 'activity'> & Partial<Omit<CapabilityStates['vacuum'], 'activity'>>;
|
|
160
|
+
};
|
|
161
|
+
/** An entity's state, read back: one entry per capability it declares. */
|
|
162
|
+
type CapabilityState = { readonly [TName in CapabilityName]?: CapabilityStates[TName]; };
|
|
163
|
+
/** An entity's state, as reported: one entry per capability it declares. */
|
|
164
|
+
type ReportedCapabilityState = { readonly [TName in CapabilityName]?: ReportedStates[TName]; };
|
|
165
|
+
/** Each capability's params: the device's own limits, as an entity declares them. */
|
|
166
|
+
type CapabilityParams = {
|
|
167
|
+
readonly on_off: Readonly<Record<never, never>>;
|
|
168
|
+
readonly level: {
|
|
169
|
+
readonly hasTransition?: boolean;
|
|
170
|
+
};
|
|
171
|
+
readonly color_hs: Readonly<Record<never, never>>;
|
|
172
|
+
readonly color_temp: {
|
|
173
|
+
readonly minMireds: number;
|
|
174
|
+
readonly maxMireds: number;
|
|
175
|
+
};
|
|
176
|
+
readonly cover: {
|
|
177
|
+
readonly hasPosition?: boolean;
|
|
178
|
+
readonly hasTilt?: boolean;
|
|
179
|
+
};
|
|
180
|
+
readonly lock: {
|
|
181
|
+
readonly hasCode?: boolean;
|
|
182
|
+
};
|
|
183
|
+
readonly thermostat: {
|
|
184
|
+
readonly supportedModes: readonly ThermostatMode[];
|
|
185
|
+
readonly minTemperature: number;
|
|
186
|
+
readonly maxTemperature: number;
|
|
187
|
+
readonly temperatureStep?: number;
|
|
188
|
+
};
|
|
189
|
+
readonly sensor_numeric: Readonly<Record<never, never>>;
|
|
190
|
+
readonly sensor_binary: Readonly<Record<never, never>>;
|
|
191
|
+
readonly sensor_text: Readonly<Record<never, never>>;
|
|
192
|
+
readonly media_player: {
|
|
193
|
+
readonly supportedSources?: readonly string[];
|
|
194
|
+
readonly hasSeek?: boolean;
|
|
195
|
+
readonly hasVolume?: boolean;
|
|
196
|
+
};
|
|
197
|
+
readonly camera: {
|
|
198
|
+
readonly hasSnapshot?: boolean;
|
|
199
|
+
readonly hasStream?: boolean;
|
|
200
|
+
readonly hasRecording?: boolean;
|
|
201
|
+
};
|
|
202
|
+
readonly button: Readonly<Record<never, never>>;
|
|
203
|
+
readonly update: {
|
|
204
|
+
readonly canInstall?: boolean;
|
|
205
|
+
readonly hasProgress?: boolean;
|
|
206
|
+
};
|
|
207
|
+
readonly lawn_mower: {
|
|
208
|
+
readonly canPause?: boolean;
|
|
209
|
+
readonly canStop?: boolean;
|
|
210
|
+
readonly canDock?: boolean;
|
|
211
|
+
readonly canResume?: boolean;
|
|
212
|
+
};
|
|
213
|
+
readonly select: {
|
|
214
|
+
readonly options: readonly SelectOption[];
|
|
215
|
+
};
|
|
216
|
+
readonly number: {
|
|
217
|
+
readonly min: number;
|
|
218
|
+
readonly max: number;
|
|
219
|
+
readonly step?: number;
|
|
220
|
+
};
|
|
221
|
+
readonly vacuum: {
|
|
222
|
+
readonly canPause?: boolean;
|
|
223
|
+
readonly canStop?: boolean;
|
|
224
|
+
readonly canDock?: boolean;
|
|
225
|
+
readonly canLocate?: boolean;
|
|
226
|
+
readonly canCleanRooms?: boolean;
|
|
227
|
+
readonly canResume?: boolean;
|
|
228
|
+
};
|
|
229
|
+
readonly image: Readonly<Record<never, never>>;
|
|
230
|
+
readonly custom: {
|
|
231
|
+
readonly packageId: string;
|
|
232
|
+
readonly type: string;
|
|
233
|
+
};
|
|
234
|
+
};
|
|
235
|
+
/** What an entity declares it can do, with the device's own limits for each. */
|
|
236
|
+
type DeclaredCapabilities = { readonly [TName in CapabilityName]?: CapabilityParams[TName]; };
|
|
237
|
+
/** Each capability's commands, as the platform hands them over: checked, defaults applied. */
|
|
238
|
+
type CapabilityCommands = {
|
|
239
|
+
readonly on_off: {
|
|
240
|
+
readonly command: 'turn_on';
|
|
241
|
+
} | {
|
|
242
|
+
readonly command: 'turn_off';
|
|
243
|
+
} | {
|
|
244
|
+
readonly command: 'toggle';
|
|
245
|
+
};
|
|
246
|
+
readonly level: {
|
|
247
|
+
readonly command: 'set_level';
|
|
248
|
+
readonly level: number;
|
|
249
|
+
readonly transitionMs?: number;
|
|
250
|
+
};
|
|
251
|
+
readonly color_hs: {
|
|
252
|
+
readonly command: 'set_color';
|
|
253
|
+
readonly hue: number;
|
|
254
|
+
readonly saturation: number;
|
|
255
|
+
readonly transitionMs?: number;
|
|
256
|
+
};
|
|
257
|
+
readonly color_temp: {
|
|
258
|
+
readonly command: 'set_color_temp';
|
|
259
|
+
readonly mireds: number;
|
|
260
|
+
readonly transitionMs?: number;
|
|
261
|
+
};
|
|
262
|
+
readonly cover: {
|
|
263
|
+
readonly command: 'open';
|
|
264
|
+
} | {
|
|
265
|
+
readonly command: 'close';
|
|
266
|
+
} | {
|
|
267
|
+
readonly command: 'stop';
|
|
268
|
+
} | {
|
|
269
|
+
readonly command: 'set_position';
|
|
270
|
+
readonly position: number;
|
|
271
|
+
} | {
|
|
272
|
+
readonly command: 'set_tilt';
|
|
273
|
+
readonly tilt: number;
|
|
274
|
+
};
|
|
275
|
+
readonly lock: {
|
|
276
|
+
readonly command: 'lock';
|
|
277
|
+
readonly code?: string;
|
|
278
|
+
} | {
|
|
279
|
+
readonly command: 'unlock';
|
|
280
|
+
readonly code?: string;
|
|
281
|
+
};
|
|
282
|
+
readonly thermostat: {
|
|
283
|
+
readonly command: 'set_target';
|
|
284
|
+
readonly temperature: number;
|
|
285
|
+
} | {
|
|
286
|
+
readonly command: 'set_mode';
|
|
287
|
+
readonly mode: ThermostatMode;
|
|
288
|
+
};
|
|
289
|
+
readonly media_player: {
|
|
290
|
+
readonly command: 'play';
|
|
291
|
+
} | {
|
|
292
|
+
readonly command: 'pause';
|
|
293
|
+
} | {
|
|
294
|
+
readonly command: 'stop';
|
|
295
|
+
} | {
|
|
296
|
+
readonly command: 'next';
|
|
297
|
+
} | {
|
|
298
|
+
readonly command: 'previous';
|
|
299
|
+
} | {
|
|
300
|
+
readonly command: 'seek';
|
|
301
|
+
readonly positionSeconds: number;
|
|
302
|
+
} | {
|
|
303
|
+
readonly command: 'set_volume';
|
|
304
|
+
readonly volume: number;
|
|
305
|
+
} | {
|
|
306
|
+
readonly command: 'set_mute';
|
|
307
|
+
readonly isMuted: boolean;
|
|
308
|
+
} | {
|
|
309
|
+
readonly command: 'set_source';
|
|
310
|
+
readonly source: string;
|
|
311
|
+
};
|
|
312
|
+
readonly camera: {
|
|
313
|
+
readonly command: 'snapshot';
|
|
314
|
+
} | {
|
|
315
|
+
readonly command: 'record';
|
|
316
|
+
readonly durationSeconds: number;
|
|
317
|
+
};
|
|
318
|
+
readonly button: {
|
|
319
|
+
readonly command: 'press';
|
|
320
|
+
};
|
|
321
|
+
readonly update: {
|
|
322
|
+
readonly command: 'install';
|
|
323
|
+
};
|
|
324
|
+
readonly lawn_mower: {
|
|
325
|
+
readonly command: 'start';
|
|
326
|
+
} | {
|
|
327
|
+
readonly command: 'pause';
|
|
328
|
+
} | {
|
|
329
|
+
readonly command: 'stop';
|
|
330
|
+
} | {
|
|
331
|
+
readonly command: 'dock';
|
|
332
|
+
} | {
|
|
333
|
+
readonly command: 'resume';
|
|
334
|
+
};
|
|
335
|
+
readonly select: {
|
|
336
|
+
readonly command: 'select_option';
|
|
337
|
+
readonly option: string;
|
|
338
|
+
};
|
|
339
|
+
readonly number: {
|
|
340
|
+
readonly command: 'set_value';
|
|
341
|
+
readonly value: number;
|
|
342
|
+
};
|
|
343
|
+
readonly vacuum: {
|
|
344
|
+
readonly command: 'start';
|
|
345
|
+
} | {
|
|
346
|
+
readonly command: 'pause';
|
|
347
|
+
} | {
|
|
348
|
+
readonly command: 'stop';
|
|
349
|
+
} | {
|
|
350
|
+
readonly command: 'dock';
|
|
351
|
+
} | {
|
|
352
|
+
readonly command: 'locate';
|
|
353
|
+
} | {
|
|
354
|
+
readonly command: 'resume';
|
|
355
|
+
} | {
|
|
356
|
+
readonly command: 'clean_rooms';
|
|
357
|
+
readonly rooms: readonly string[];
|
|
358
|
+
};
|
|
359
|
+
readonly custom: {
|
|
360
|
+
readonly command: string;
|
|
361
|
+
readonly args: Readonly<Record<string, CustomValue>>;
|
|
362
|
+
};
|
|
363
|
+
};
|
|
364
|
+
/** The capabilities that take commands: the others report only. */
|
|
365
|
+
type CommandableCapability = keyof CapabilityCommands;
|
|
366
|
+
/** A command the platform routed to one of the package's entities, typed by its capability. */
|
|
367
|
+
type CapabilityCommand = { readonly [TName in CommandableCapability]: {
|
|
368
|
+
readonly entityId: EntityId;
|
|
369
|
+
readonly capability: TName;
|
|
370
|
+
readonly command: CapabilityCommands[TName];
|
|
371
|
+
}; }[CommandableCapability];
|
|
372
|
+
//#endregion
|
|
373
|
+
//#region src/fields.d.ts
|
|
374
|
+
/**
|
|
375
|
+
* The field builders: one set that describes a package's settings, a card's options, the state
|
|
376
|
+
* of an entity type and the arguments of its commands (PACKAGES_DOCS.md 4.10).
|
|
377
|
+
*
|
|
378
|
+
* Not every kind fits every place - a secret is never a card option, a timestamp is never asked
|
|
379
|
+
* in a form - and the places say which they take: `SettingField`, `OptionField`, `ValueField`.
|
|
380
|
+
* Each builder keeps the literal options it was given, which is what lets `SettingsOf`,
|
|
381
|
+
* `OptionsOf` and `ValuesOf` give a choice the union of its values and know which fields are
|
|
382
|
+
* always there.
|
|
383
|
+
*/
|
|
384
|
+
/** A condition on an earlier field of the same form: asked only while it holds one of these. */
|
|
385
|
+
type ShownWhen = {
|
|
386
|
+
readonly key: string;
|
|
387
|
+
readonly equals: readonly (string | boolean)[];
|
|
388
|
+
};
|
|
389
|
+
/** One choice of a choice field. */
|
|
390
|
+
type ChoiceOption = {
|
|
391
|
+
readonly value: string;
|
|
392
|
+
readonly label: string;
|
|
393
|
+
};
|
|
394
|
+
/** What every field says. */
|
|
395
|
+
type FieldBase = {
|
|
396
|
+
/** Shown beside the control, or as the column of a value; at most 64 characters. */
|
|
397
|
+
readonly label: string;
|
|
398
|
+
/** Shown under it, for what the label cannot say. */
|
|
399
|
+
readonly help?: string;
|
|
400
|
+
};
|
|
401
|
+
/** What a field says when a form asks it: in the settings, or a card's options. */
|
|
402
|
+
type InForm<TValue> = {
|
|
403
|
+
/** What it holds until the owner says otherwise. */
|
|
404
|
+
readonly default?: TValue;
|
|
405
|
+
/** Whether the form may not be saved without it. */
|
|
406
|
+
readonly isRequired?: boolean;
|
|
407
|
+
/** Asked only after an earlier choice or switch. */
|
|
408
|
+
readonly shownWhen?: ShownWhen;
|
|
409
|
+
/** In the settings: a change reaches the running process instead of restarting it. */
|
|
410
|
+
readonly isLive?: boolean;
|
|
411
|
+
};
|
|
412
|
+
/** What a field says as part of an entity type's state, or of a command's arguments. */
|
|
413
|
+
type InEntity = {
|
|
414
|
+
/** Whether it may be missing, or null; required when not said. */
|
|
415
|
+
readonly isOptional?: boolean;
|
|
416
|
+
};
|
|
417
|
+
/** A text's own limits. */
|
|
418
|
+
type TextLimits = {
|
|
419
|
+
readonly pattern?: string;
|
|
420
|
+
readonly patternMessage?: string;
|
|
421
|
+
readonly minLength?: number;
|
|
422
|
+
readonly maxLength?: number;
|
|
423
|
+
};
|
|
424
|
+
/** What `field.text` takes. */
|
|
425
|
+
type TextOptions = FieldBase & InForm<string> & InEntity & TextLimits & {
|
|
426
|
+
readonly placeholder?: string;
|
|
427
|
+
};
|
|
428
|
+
/** What `field.secret` takes: like text, with nothing a form could show back. */
|
|
429
|
+
type SecretOptions = FieldBase & Omit<InForm<string>, 'default'> & TextLimits;
|
|
430
|
+
/** What `field.number` takes. */
|
|
431
|
+
type NumberOptions = FieldBase & InForm<number> & InEntity & {
|
|
432
|
+
readonly min?: number;
|
|
433
|
+
readonly max?: number;
|
|
434
|
+
readonly isInteger?: boolean;
|
|
435
|
+
/** What it is counted in: `min`, `°C`, `MB`. */
|
|
436
|
+
readonly unit?: string;
|
|
437
|
+
/** In a form: below this it warns, without refusing. */
|
|
438
|
+
readonly warnBelow?: number;
|
|
439
|
+
/** What the warning says. */
|
|
440
|
+
readonly warning?: string;
|
|
441
|
+
};
|
|
442
|
+
/** What `field.boolean` takes. */
|
|
443
|
+
type BooleanOptions = FieldBase & InForm<boolean> & InEntity;
|
|
444
|
+
/** What `field.choice` takes. */
|
|
445
|
+
type ChoiceOptions = FieldBase & InForm<string> & InEntity & {
|
|
446
|
+
readonly choices: readonly ChoiceOption[];
|
|
447
|
+
};
|
|
448
|
+
/** What `field.list` takes: several texts, each held to the same pattern. */
|
|
449
|
+
type ListOptions = FieldBase & Omit<InForm<readonly string[]>, 'default'> & {
|
|
450
|
+
readonly placeholder?: string;
|
|
451
|
+
readonly minItems?: number;
|
|
452
|
+
readonly maxItems?: number;
|
|
453
|
+
readonly pattern?: string;
|
|
454
|
+
readonly patternMessage?: string;
|
|
455
|
+
};
|
|
456
|
+
/** What `field.timestamp` takes: an instant, as ISO 8601 text. */
|
|
457
|
+
type TimestampOptions = FieldBase & InEntity;
|
|
458
|
+
/** A text field. */
|
|
459
|
+
type TextField<TOptions extends TextOptions = TextOptions> = TOptions & {
|
|
460
|
+
readonly kind: 'text';
|
|
461
|
+
};
|
|
462
|
+
/** A secret field. */
|
|
463
|
+
type SecretField<TOptions extends SecretOptions = SecretOptions> = TOptions & {
|
|
464
|
+
readonly kind: 'secret';
|
|
465
|
+
};
|
|
466
|
+
/** A number field. */
|
|
467
|
+
type NumberField<TOptions extends NumberOptions = NumberOptions> = TOptions & {
|
|
468
|
+
readonly kind: 'number';
|
|
469
|
+
};
|
|
470
|
+
/** A boolean field. */
|
|
471
|
+
type BooleanField<TOptions extends BooleanOptions = BooleanOptions> = TOptions & {
|
|
472
|
+
readonly kind: 'boolean';
|
|
473
|
+
};
|
|
474
|
+
/** A choice field. */
|
|
475
|
+
type ChoiceField<TOptions extends ChoiceOptions = ChoiceOptions> = TOptions & {
|
|
476
|
+
readonly kind: 'choice';
|
|
477
|
+
};
|
|
478
|
+
/** A list field. */
|
|
479
|
+
type ListField<TOptions extends ListOptions = ListOptions> = TOptions & {
|
|
480
|
+
readonly kind: 'list';
|
|
481
|
+
};
|
|
482
|
+
/** A timestamp field. */
|
|
483
|
+
type TimestampField<TOptions extends TimestampOptions = TimestampOptions> = TOptions & {
|
|
484
|
+
readonly kind: 'timestamp';
|
|
485
|
+
};
|
|
486
|
+
/** Any field. */
|
|
487
|
+
type Field = TextField | SecretField | NumberField | BooleanField | ChoiceField | ListField | TimestampField;
|
|
488
|
+
/** A field the settings may hold: every kind a form asks. */
|
|
489
|
+
type SettingField = (TextField | SecretField | NumberField | BooleanField | ChoiceField | ListField) & {
|
|
490
|
+
readonly isOptional?: never;
|
|
491
|
+
};
|
|
492
|
+
/** A field a card's inspector may ask: a form's kinds, no secret, nothing live. */
|
|
493
|
+
type OptionField = (TextField | NumberField | BooleanField | ChoiceField | ListField) & {
|
|
494
|
+
readonly isOptional?: never;
|
|
495
|
+
readonly isLive?: never;
|
|
496
|
+
};
|
|
497
|
+
/** A field of an entity type's state or of a command's arguments. */
|
|
498
|
+
type ValueField = (TextField | NumberField | BooleanField | ChoiceField | TimestampField) & {
|
|
499
|
+
readonly isRequired?: never;
|
|
500
|
+
readonly default?: never;
|
|
501
|
+
readonly shownWhen?: never;
|
|
502
|
+
readonly isLive?: never;
|
|
503
|
+
};
|
|
504
|
+
/** Fields by their keys: camelCase, a letter first. */
|
|
505
|
+
type Fields<TField extends Field = Field> = Readonly<Record<string, TField>>;
|
|
506
|
+
/** No fields. */
|
|
507
|
+
type NoFields = Readonly<Record<never, never>>;
|
|
508
|
+
/** The value a field holds: the union of its values for a choice. */
|
|
509
|
+
type ValueOfField<TField> = TField extends {
|
|
510
|
+
readonly kind: 'choice';
|
|
511
|
+
readonly choices: readonly {
|
|
512
|
+
readonly value: infer TValue;
|
|
513
|
+
}[];
|
|
514
|
+
} ? TValue : TField extends {
|
|
515
|
+
readonly kind: 'number';
|
|
516
|
+
} ? number : TField extends {
|
|
517
|
+
readonly kind: 'boolean';
|
|
518
|
+
} ? boolean : TField extends {
|
|
519
|
+
readonly kind: 'list';
|
|
520
|
+
} ? readonly string[] : string;
|
|
521
|
+
/** Flattens an intersection, so what it holds reads as one object. */
|
|
522
|
+
type Simplify<TObject> = { [TKey in keyof TObject]: TObject[TKey]; };
|
|
523
|
+
/** The keys of a form whose value is always there: those with a default, and those required. */
|
|
524
|
+
type PresentKeys<TFields> = { [TKey in keyof TFields]: TFields[TKey] extends {
|
|
525
|
+
readonly default: unknown;
|
|
526
|
+
} ? TKey : TFields[TKey] extends {
|
|
527
|
+
readonly isRequired: true;
|
|
528
|
+
} ? TKey : never; }[keyof TFields];
|
|
529
|
+
/** The values a form holds: what has a default or is required always, anything else maybe. */
|
|
530
|
+
type FormValues<TFields> = Simplify<{ readonly [TKey in PresentKeys<TFields>]: ValueOfField<TFields[TKey]>; } & { readonly [TKey in Exclude<keyof TFields, PresentKeys<TFields>>]?: ValueOfField<TFields[TKey]> | undefined; }>;
|
|
531
|
+
/** The keys of an entity's fields that may be missing. */
|
|
532
|
+
type OptionalKeys<TFields> = { [TKey in keyof TFields]: TFields[TKey] extends {
|
|
533
|
+
readonly isOptional: true;
|
|
534
|
+
} ? TKey : never; }[keyof TFields];
|
|
535
|
+
/** The values of an entity's fields, whole: an optional field may be missing, or null. */
|
|
536
|
+
type EntityValues<TFields> = Simplify<{ readonly [TKey in Exclude<keyof TFields, OptionalKeys<TFields>>]: ValueOfField<TFields[TKey]>; } & { readonly [TKey in OptionalKeys<TFields>]?: ValueOfField<TFields[TKey]> | null; }>;
|
|
537
|
+
/** The field builders. */
|
|
538
|
+
declare const field: {
|
|
539
|
+
/**
|
|
540
|
+
* A text: free, or held to a length and a pattern.
|
|
541
|
+
*
|
|
542
|
+
* @param options - Its label and limits.
|
|
543
|
+
* @returns The field.
|
|
544
|
+
*/
|
|
545
|
+
text: <const TOptions extends TextOptions>(options: TOptions) => TextField<TOptions>;
|
|
546
|
+
/**
|
|
547
|
+
* A secret: stored sealed, handed to the process open, never sent to a browser.
|
|
548
|
+
*
|
|
549
|
+
* @param options - Its label and limits.
|
|
550
|
+
* @returns The field.
|
|
551
|
+
*/
|
|
552
|
+
secret: <const TOptions extends SecretOptions>(options: TOptions) => SecretField<TOptions>;
|
|
553
|
+
/**
|
|
554
|
+
* A number, optionally whole and within a range.
|
|
555
|
+
*
|
|
556
|
+
* @param options - Its label, range and unit.
|
|
557
|
+
* @returns The field.
|
|
558
|
+
*/
|
|
559
|
+
number: <const TOptions extends NumberOptions>(options: TOptions) => NumberField<TOptions>;
|
|
560
|
+
/**
|
|
561
|
+
* On or off.
|
|
562
|
+
*
|
|
563
|
+
* @param options - Its label.
|
|
564
|
+
* @returns The field.
|
|
565
|
+
*/
|
|
566
|
+
boolean: <const TOptions extends BooleanOptions>(options: TOptions) => BooleanField<TOptions>;
|
|
567
|
+
/**
|
|
568
|
+
* One of a fixed list.
|
|
569
|
+
*
|
|
570
|
+
* @param options - Its label and its choices, 1 to 64.
|
|
571
|
+
* @returns The field.
|
|
572
|
+
*/
|
|
573
|
+
choice: <const TOptions extends ChoiceOptions>(options: TOptions) => ChoiceField<TOptions>;
|
|
574
|
+
/**
|
|
575
|
+
* Several texts - addresses, topics - each held to the same pattern.
|
|
576
|
+
*
|
|
577
|
+
* @param options - Its label and limits.
|
|
578
|
+
* @returns The field.
|
|
579
|
+
*/
|
|
580
|
+
list: <const TOptions extends ListOptions>(options: TOptions) => ListField<TOptions>;
|
|
581
|
+
/**
|
|
582
|
+
* An instant, as ISO 8601 text: an entity's state or a command's argument, never a form's.
|
|
583
|
+
*
|
|
584
|
+
* @param options - Its label.
|
|
585
|
+
* @returns The field.
|
|
586
|
+
*/
|
|
587
|
+
timestamp: <const TOptions extends TimestampOptions>(options: TOptions) => TimestampField<TOptions>;
|
|
588
|
+
};
|
|
589
|
+
//#endregion
|
|
590
|
+
//#region src/definitions/entity-type.d.ts
|
|
591
|
+
/** A command an entity type takes. */
|
|
592
|
+
type CommandDeclaration = {
|
|
593
|
+
readonly name: string;
|
|
594
|
+
/** Its arguments, at most 8. */
|
|
595
|
+
readonly fields?: Fields<ValueField>;
|
|
596
|
+
};
|
|
597
|
+
/** Commands by their ids. */
|
|
598
|
+
type CommandDeclarations = Readonly<Record<string, CommandDeclaration>>;
|
|
599
|
+
/** An entity type, as declared. */
|
|
600
|
+
type EntityTypeDefinition<TId extends string = string, TState extends Fields<ValueField> = Fields<ValueField>, TCommands extends CommandDeclarations = CommandDeclarations> = {
|
|
601
|
+
readonly kind: 'entityType';
|
|
602
|
+
readonly id: TId;
|
|
603
|
+
readonly name: string;
|
|
604
|
+
/** A catalogue icon id. */
|
|
605
|
+
readonly icon: string;
|
|
606
|
+
/** What its state holds: 1 to 32 fields. */
|
|
607
|
+
readonly state: TState;
|
|
608
|
+
/** The commands it takes, at most 16. */
|
|
609
|
+
readonly commands?: TCommands;
|
|
610
|
+
};
|
|
611
|
+
/** The values of an entity type's state, whole: an optional field may be missing, or null. */
|
|
612
|
+
type ValuesOf<TType> = TType extends EntityTypeDefinition<string, infer TState> ? EntityValues<TState> : never;
|
|
613
|
+
/** The ids of an entity type's commands. */
|
|
614
|
+
type CommandsOf<TType> = TType extends EntityTypeDefinition<string, Fields<ValueField>, infer TCommands> ? keyof TCommands & string : never;
|
|
615
|
+
/** The arguments of one of an entity type's commands. */
|
|
616
|
+
type ArgsOf<TType, TCommand extends CommandsOf<TType>> = TType extends EntityTypeDefinition<string, Fields<ValueField>, infer TCommands> ? TCommands[TCommand] extends {
|
|
617
|
+
readonly fields: infer TFields;
|
|
618
|
+
} ? EntityValues<TFields> : NoFields : never;
|
|
619
|
+
/**
|
|
620
|
+
* Declares an entity type.
|
|
621
|
+
*
|
|
622
|
+
* @param type - Its id, name, icon, state and commands.
|
|
623
|
+
* @returns The type, for `definePackage`'s `entityTypes`, the server's `ctx.custom` and its view.
|
|
624
|
+
*/
|
|
625
|
+
declare function defineEntityType<const TId extends string, const TState extends Fields<ValueField>, const TCommands extends CommandDeclarations = NoFields>(type: Omit<EntityTypeDefinition<TId, TState, TCommands>, 'kind'>): EntityTypeDefinition<TId, TState, TCommands>;
|
|
626
|
+
//#endregion
|
|
627
|
+
//#region src/definitions/settings.d.ts
|
|
628
|
+
/** A package's settings. */
|
|
629
|
+
type SettingsDefinition<TFields extends Fields<SettingField> = Fields<SettingField>> = {
|
|
630
|
+
readonly kind: 'settings';
|
|
631
|
+
readonly fields: TFields;
|
|
632
|
+
};
|
|
633
|
+
/** The values of a package's settings: what has a default or is required is always there. */
|
|
634
|
+
type SettingsOf<TSettings> = TSettings extends SettingsDefinition<infer TFields> ? FormValues<TFields> : never;
|
|
635
|
+
/**
|
|
636
|
+
* Declares a package's settings, at most 32 fields, by their keys.
|
|
637
|
+
*
|
|
638
|
+
* @param fields - The fields, built with `field`.
|
|
639
|
+
* @returns The settings, for `definePackage` and for the types of `ctx.settings`.
|
|
640
|
+
*/
|
|
641
|
+
declare function defineSettings<const TFields extends Fields<SettingField>>(fields: TFields): SettingsDefinition<TFields>;
|
|
642
|
+
//#endregion
|
|
643
|
+
//#region src/json.d.ts
|
|
644
|
+
/**
|
|
645
|
+
* JSON, as the platform passes it between a package and everything else: settings, attributes,
|
|
646
|
+
* the input and output of a method.
|
|
647
|
+
*/
|
|
648
|
+
/** A JSON scalar. */
|
|
649
|
+
type JsonPrimitive = string | number | boolean | null;
|
|
650
|
+
/** Any JSON value. */
|
|
651
|
+
type JsonValue = JsonPrimitive | readonly JsonValue[] | JsonObject;
|
|
652
|
+
/** A JSON object. */
|
|
653
|
+
type JsonObject = {
|
|
654
|
+
readonly [key: string]: JsonValue;
|
|
655
|
+
};
|
|
656
|
+
//#endregion
|
|
657
|
+
export { PlaybackState as $, SecretOptions as A, field as B, ListField as C, NumberOptions as D, NumberField as E, TextOptions as F, CapabilityState as G, CapabilityCommands as H, TimestampField as I, CustomValue as J, CapabilityStates as K, TimestampOptions as L, ShownWhen as M, Simplify as N, OptionField as O, TextField as P, LawnMowerActivity as Q, ValueField as R, FormValues as S, NoFields as T, CapabilityName as U, CapabilityCommand as V, CapabilityParams as W, EntityStateClass as X, DeclaredCapabilities as Y, ImageContentType as Z, ChoiceOption as _, SettingsOf as a, VacuumActivity as at, Field as b, CommandDeclaration as c, EntityDomain as ct, EntityTypeDefinition as d, isEntityId as dt, ReportedCapabilityState as et, ValuesOf as f, parseEntityId as ft, ChoiceField as g, BooleanOptions as h, SettingsDefinition as i, ThermostatMode as it, SettingField as j, SecretField as k, CommandDeclarations as l, EntityId as lt, BooleanField as m, JsonPrimitive as n, SelectOption as nt, defineSettings as o, VacuumRoom as ot, defineEntityType as p, CommandableCapability as q, JsonValue as r, ThermostatAction as rt, ArgsOf as s, ENTITY_DOMAINS as st, JsonObject as t, ReportedStates as tt, CommandsOf as u, ParsedEntityId as ut, ChoiceOptions as v, ListOptions as w, Fields as x, EntityValues as y, ValueOfField as z };
|