yoto-nodejs-client 0.0.1
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/LICENSE +21 -0
- package/README.md +736 -0
- package/bin/auth.d.ts +3 -0
- package/bin/auth.d.ts.map +1 -0
- package/bin/auth.js +130 -0
- package/bin/content.d.ts +3 -0
- package/bin/content.d.ts.map +1 -0
- package/bin/content.js +117 -0
- package/bin/devices.d.ts +3 -0
- package/bin/devices.d.ts.map +1 -0
- package/bin/devices.js +239 -0
- package/bin/groups.d.ts +3 -0
- package/bin/groups.d.ts.map +1 -0
- package/bin/groups.js +80 -0
- package/bin/icons.d.ts +3 -0
- package/bin/icons.d.ts.map +1 -0
- package/bin/icons.js +100 -0
- package/bin/lib/cli-helpers.d.ts +21 -0
- package/bin/lib/cli-helpers.d.ts.map +1 -0
- package/bin/lib/cli-helpers.js +140 -0
- package/bin/lib/token-helpers.d.ts +14 -0
- package/bin/lib/token-helpers.d.ts.map +1 -0
- package/bin/lib/token-helpers.js +151 -0
- package/bin/refresh-token.d.ts +3 -0
- package/bin/refresh-token.d.ts.map +1 -0
- package/bin/refresh-token.js +168 -0
- package/bin/token-info.d.ts +3 -0
- package/bin/token-info.d.ts.map +1 -0
- package/bin/token-info.js +351 -0
- package/index.d.ts +218 -0
- package/index.d.ts.map +1 -0
- package/index.js +689 -0
- package/lib/api-endpoints/auth.d.ts +56 -0
- package/lib/api-endpoints/auth.d.ts.map +1 -0
- package/lib/api-endpoints/auth.js +209 -0
- package/lib/api-endpoints/auth.test.js +27 -0
- package/lib/api-endpoints/constants.d.ts +6 -0
- package/lib/api-endpoints/constants.d.ts.map +1 -0
- package/lib/api-endpoints/constants.js +31 -0
- package/lib/api-endpoints/content.d.ts +275 -0
- package/lib/api-endpoints/content.d.ts.map +1 -0
- package/lib/api-endpoints/content.js +518 -0
- package/lib/api-endpoints/content.test.js +250 -0
- package/lib/api-endpoints/devices.d.ts +202 -0
- package/lib/api-endpoints/devices.d.ts.map +1 -0
- package/lib/api-endpoints/devices.js +404 -0
- package/lib/api-endpoints/devices.test.js +483 -0
- package/lib/api-endpoints/family-library-groups.d.ts +75 -0
- package/lib/api-endpoints/family-library-groups.d.ts.map +1 -0
- package/lib/api-endpoints/family-library-groups.js +247 -0
- package/lib/api-endpoints/family-library-groups.test.js +272 -0
- package/lib/api-endpoints/family.d.ts +39 -0
- package/lib/api-endpoints/family.d.ts.map +1 -0
- package/lib/api-endpoints/family.js +166 -0
- package/lib/api-endpoints/family.test.js +184 -0
- package/lib/api-endpoints/helpers.d.ts +29 -0
- package/lib/api-endpoints/helpers.d.ts.map +1 -0
- package/lib/api-endpoints/helpers.js +104 -0
- package/lib/api-endpoints/icons.d.ts +62 -0
- package/lib/api-endpoints/icons.d.ts.map +1 -0
- package/lib/api-endpoints/icons.js +201 -0
- package/lib/api-endpoints/icons.test.js +118 -0
- package/lib/api-endpoints/media.d.ts +37 -0
- package/lib/api-endpoints/media.d.ts.map +1 -0
- package/lib/api-endpoints/media.js +155 -0
- package/lib/api-endpoints/test-helpers.d.ts +7 -0
- package/lib/api-endpoints/test-helpers.d.ts.map +1 -0
- package/lib/api-endpoints/test-helpers.js +64 -0
- package/lib/mqtt/client.d.ts +124 -0
- package/lib/mqtt/client.d.ts.map +1 -0
- package/lib/mqtt/client.js +558 -0
- package/lib/mqtt/commands.d.ts +69 -0
- package/lib/mqtt/commands.d.ts.map +1 -0
- package/lib/mqtt/commands.js +238 -0
- package/lib/mqtt/factory.d.ts +12 -0
- package/lib/mqtt/factory.d.ts.map +1 -0
- package/lib/mqtt/factory.js +107 -0
- package/lib/mqtt/index.d.ts +5 -0
- package/lib/mqtt/index.d.ts.map +1 -0
- package/lib/mqtt/index.js +81 -0
- package/lib/mqtt/mqtt.test.js +168 -0
- package/lib/mqtt/topics.d.ts +34 -0
- package/lib/mqtt/topics.d.ts.map +1 -0
- package/lib/mqtt/topics.js +295 -0
- package/lib/pkg.cjs +3 -0
- package/lib/pkg.d.cts +70 -0
- package/lib/pkg.d.cts.map +1 -0
- package/lib/token.d.ts +29 -0
- package/lib/token.d.ts.map +1 -0
- package/lib/token.js +240 -0
- package/package.json +91 -0
- package/yoto.png +0 -0
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
import test from 'node:test'
|
|
2
|
+
import assert from 'node:assert'
|
|
3
|
+
import { getContent, getUserMyoContent } from './content.js'
|
|
4
|
+
import { YotoAPIError } from './helpers.js'
|
|
5
|
+
import { loadTestTokens, logResponse } from './test-helpers.js'
|
|
6
|
+
|
|
7
|
+
const { accessToken } = loadTestTokens()
|
|
8
|
+
|
|
9
|
+
test('getUserMyoContent', async (t) => {
|
|
10
|
+
await t.test('should fetch user MYO cards', async () => {
|
|
11
|
+
const response = await getUserMyoContent({
|
|
12
|
+
accessToken
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
// Log response for type verification and documentation
|
|
16
|
+
logResponse('GET /content/mine', response)
|
|
17
|
+
|
|
18
|
+
// Validate response structure matches YotoMyoContentResponse
|
|
19
|
+
assert.ok(response, 'Response should exist')
|
|
20
|
+
assert.ok(Array.isArray(response.cards), 'Response should have cards array')
|
|
21
|
+
assert.ok(response.cards.length > 0, 'User should have at least one card')
|
|
22
|
+
|
|
23
|
+
// Validate card structure
|
|
24
|
+
const card = response.cards[0]
|
|
25
|
+
assert.ok(card, 'Card should exist')
|
|
26
|
+
assert.ok(typeof card.cardId === 'string', 'Card should have cardId string')
|
|
27
|
+
assert.ok(typeof card.title === 'string', 'Card should have title string')
|
|
28
|
+
assert.ok(typeof card.createdAt === 'string', 'Card should have createdAt string')
|
|
29
|
+
assert.ok(typeof card.updatedAt === 'string', 'Card should have updatedAt string')
|
|
30
|
+
assert.ok(typeof card.userId === 'string', 'Card should have userId string')
|
|
31
|
+
assert.ok(card.content, 'Card should have content object')
|
|
32
|
+
assert.ok(card.metadata, 'Card should have metadata object')
|
|
33
|
+
assert.ok(card.metadata.media, 'Metadata should have media object')
|
|
34
|
+
assert.ok(typeof card.metadata.media.duration === 'number', 'Media should have duration number')
|
|
35
|
+
|
|
36
|
+
// Validate metadata category enum if present and non-empty
|
|
37
|
+
if (card.metadata.category && card.metadata.category.length > 0) {
|
|
38
|
+
const validCategories = ['none', 'stories', 'music', 'radio', 'podcast', 'sfx', 'activities', 'alarms']
|
|
39
|
+
assert.ok(validCategories.includes(card.metadata.category), `Metadata category should be valid: ${card.metadata.category}`)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Validate optional metadata fields if present
|
|
43
|
+
if (card.metadata.languages) {
|
|
44
|
+
const validLanguages = ['en', 'en-gb', 'en-us', 'fr', 'fr-fr', 'es', 'es-es', 'es-419', 'de', 'it']
|
|
45
|
+
assert.ok(Array.isArray(card.metadata.languages), 'Metadata languages should be array')
|
|
46
|
+
card.metadata.languages.forEach(lang => {
|
|
47
|
+
assert.ok(validLanguages.includes(lang), `Language should be valid: ${lang}`)
|
|
48
|
+
})
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (card.metadata.status) {
|
|
52
|
+
const validStatuses = ['new', 'inprogress', 'complete', 'live', 'archived']
|
|
53
|
+
assert.ok(validStatuses.includes(card.metadata.status.name), `Status name should be valid: ${card.metadata.status.name}`)
|
|
54
|
+
assert.ok(typeof card.metadata.status.updatedAt === 'string', 'Status should have updatedAt string')
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (card.metadata.playbackDirection) {
|
|
58
|
+
assert.ok(['DESC', 'ASC'].includes(card.metadata.playbackDirection), 'Playback direction should be DESC or ASC')
|
|
59
|
+
}
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
await t.test('should accept showDeleted parameter', async () => {
|
|
63
|
+
const response = await getUserMyoContent({
|
|
64
|
+
accessToken,
|
|
65
|
+
showDeleted: true
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
assert.ok(response, 'Response should exist')
|
|
69
|
+
assert.ok(Array.isArray(response.cards), 'Response should have cards array')
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
await t.test('should fail with invalid token', async () => {
|
|
73
|
+
await assert.rejects(
|
|
74
|
+
async () => {
|
|
75
|
+
await getUserMyoContent({
|
|
76
|
+
accessToken: 'invalid-token'
|
|
77
|
+
})
|
|
78
|
+
},
|
|
79
|
+
(err) => {
|
|
80
|
+
assert.ok(err instanceof YotoAPIError, 'Should throw YotoAPIError')
|
|
81
|
+
assert.ok(err.statusCode === 401 || err.statusCode === 403, 'Should return 401 or 403 for invalid token')
|
|
82
|
+
assert.ok(err.body, 'Error should have body')
|
|
83
|
+
return true
|
|
84
|
+
}
|
|
85
|
+
)
|
|
86
|
+
})
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
test('getContent', async (t) => {
|
|
90
|
+
/** @type {string[]} */
|
|
91
|
+
let testCardIds = []
|
|
92
|
+
|
|
93
|
+
// Get real card IDs to test with
|
|
94
|
+
await t.test('setup - get card IDs from user content', async () => {
|
|
95
|
+
const response = await getUserMyoContent({
|
|
96
|
+
accessToken
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
assert.ok(response.cards.length > 0, 'User should have at least one card for getContent tests')
|
|
100
|
+
|
|
101
|
+
testCardIds = response.cards.slice(0, 3).map(card => card.cardId).filter(Boolean)
|
|
102
|
+
assert.ok(testCardIds.length > 0, 'Should have extracted at least one card ID')
|
|
103
|
+
})
|
|
104
|
+
|
|
105
|
+
await t.test('should fetch content for valid card IDs', async () => {
|
|
106
|
+
// Test with multiple cards to ensure consistency
|
|
107
|
+
for (const cardId of testCardIds) {
|
|
108
|
+
const content = await getContent({
|
|
109
|
+
accessToken,
|
|
110
|
+
cardId
|
|
111
|
+
})
|
|
112
|
+
|
|
113
|
+
// Log response for type verification and documentation
|
|
114
|
+
logResponse(`GET /content/${cardId}`, content)
|
|
115
|
+
|
|
116
|
+
// Validate response structure matches YotoContentResponse
|
|
117
|
+
assert.ok(content, 'Response should exist')
|
|
118
|
+
assert.ok(content.card, 'Response should have card property')
|
|
119
|
+
assert.strictEqual(content.card.cardId, cardId, 'Returned card ID should match requested ID')
|
|
120
|
+
assert.ok(typeof content.card.title === 'string', 'Card should have title')
|
|
121
|
+
assert.ok(typeof content.card.createdAt === 'string', 'Card should have createdAt')
|
|
122
|
+
assert.ok(typeof content.card.updatedAt === 'string', 'Card should have updatedAt')
|
|
123
|
+
assert.ok(content.card.content, 'Card should have content property')
|
|
124
|
+
assert.ok(Array.isArray(content.card.content.chapters), 'Content should have chapters array')
|
|
125
|
+
assert.ok(content.card.metadata, 'Card should have metadata')
|
|
126
|
+
|
|
127
|
+
// Validate metadata category enum if present and non-empty
|
|
128
|
+
if (content.card.metadata.category && content.card.metadata.category.length > 0) {
|
|
129
|
+
const validCategories = ['none', 'stories', 'music', 'radio', 'podcast', 'sfx', 'activities', 'alarms']
|
|
130
|
+
assert.ok(validCategories.includes(content.card.metadata.category), `Metadata category should be valid: ${content.card.metadata.category}`)
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Validate optional playbackType if present
|
|
134
|
+
if (content.card.content.playbackType) {
|
|
135
|
+
const validPlaybackTypes = ['linear', 'interactive']
|
|
136
|
+
assert.ok(validPlaybackTypes.includes(content.card.content.playbackType), `Playback type should be valid: ${content.card.content.playbackType}`)
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
})
|
|
140
|
+
|
|
141
|
+
await t.test('should include chapters in content', async () => {
|
|
142
|
+
const cardId = testCardIds[0]
|
|
143
|
+
assert.ok(cardId, 'Card ID should exist')
|
|
144
|
+
|
|
145
|
+
const content = await getContent({
|
|
146
|
+
accessToken,
|
|
147
|
+
cardId
|
|
148
|
+
})
|
|
149
|
+
|
|
150
|
+
// Chapters array should exist (may be empty for some cards)
|
|
151
|
+
assert.ok(Array.isArray(content.card.content.chapters), 'Should have chapters array')
|
|
152
|
+
|
|
153
|
+
// If chapters exist, validate their structure matches YotoChapter type
|
|
154
|
+
if (content.card.content.chapters.length > 0) {
|
|
155
|
+
const chapter = content.card.content.chapters[0]
|
|
156
|
+
assert.ok(chapter, 'Chapter should exist')
|
|
157
|
+
|
|
158
|
+
// Validate chapter structure
|
|
159
|
+
assert.ok(typeof chapter.key === 'string', 'Chapter should have key string')
|
|
160
|
+
assert.ok(typeof chapter.title === 'string', 'Chapter should have title string')
|
|
161
|
+
assert.ok(typeof chapter.overlayLabel === 'string', 'Chapter should have overlayLabel string')
|
|
162
|
+
assert.ok(Array.isArray(chapter.tracks), 'Chapter should have tracks array')
|
|
163
|
+
assert.ok(chapter.display, 'Chapter should have display object')
|
|
164
|
+
assert.ok(typeof chapter.display.icon16x16 === 'string', 'Chapter display should have icon16x16 string')
|
|
165
|
+
assert.ok(typeof chapter.duration === 'number', 'Chapter should have duration number')
|
|
166
|
+
assert.ok(typeof chapter.fileSize === 'number', 'Chapter should have fileSize number')
|
|
167
|
+
assert.ok('availableFrom' in chapter, 'Chapter should have availableFrom property')
|
|
168
|
+
assert.ok('ambient' in chapter, 'Chapter should have ambient property')
|
|
169
|
+
assert.ok('defaultTrackDisplay' in chapter, 'Chapter should have defaultTrackDisplay property')
|
|
170
|
+
assert.ok('defaultTrackAmbient' in chapter, 'Chapter should have defaultTrackAmbient property')
|
|
171
|
+
|
|
172
|
+
// If tracks exist, validate their structure matches YotoTrack type
|
|
173
|
+
if (chapter.tracks.length > 0) {
|
|
174
|
+
const track = chapter.tracks[0]
|
|
175
|
+
assert.ok(track, 'Track should exist')
|
|
176
|
+
|
|
177
|
+
// Validate track structure
|
|
178
|
+
assert.ok(typeof track.key === 'string', 'Track should have key string')
|
|
179
|
+
assert.ok(typeof track.title === 'string', 'Track should have title string')
|
|
180
|
+
assert.ok(typeof track.trackUrl === 'string', 'Track should have trackUrl string')
|
|
181
|
+
assert.ok(track.trackUrl.startsWith('yoto:#'), 'Track URL should start with "yoto:#"')
|
|
182
|
+
assert.ok(typeof track.format === 'string', 'Track should have format string')
|
|
183
|
+
|
|
184
|
+
// Validate audio format enum
|
|
185
|
+
const validFormats = ['mp3', 'aac', 'opus', 'ogg']
|
|
186
|
+
assert.ok(validFormats.includes(track.format), `Track format should be valid: ${track.format}`)
|
|
187
|
+
|
|
188
|
+
assert.ok(track.type === 'audio' || track.type === 'stream', 'Track type should be "audio" or "stream"')
|
|
189
|
+
assert.ok(typeof track.overlayLabel === 'string', 'Track should have overlayLabel string')
|
|
190
|
+
assert.ok(typeof track.duration === 'number', 'Track should have duration number')
|
|
191
|
+
assert.ok(typeof track.fileSize === 'number', 'Track should have fileSize number')
|
|
192
|
+
assert.ok(track.channels === 'stereo' || track.channels === 'mono', 'Track channels should be "stereo" or "mono"')
|
|
193
|
+
assert.ok('ambient' in track, 'Track should have ambient property')
|
|
194
|
+
assert.ok(track.display, 'Track should have display object')
|
|
195
|
+
assert.ok(typeof track.display.icon16x16 === 'string', 'Track display should have icon16x16 string')
|
|
196
|
+
assert.ok(track.display.icon16x16.startsWith('yoto:#'), 'Track display icon should start with "yoto:#"')
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
})
|
|
200
|
+
|
|
201
|
+
await t.test('should accept timezone parameter for podcast content', async () => {
|
|
202
|
+
const cardId = testCardIds[0]
|
|
203
|
+
assert.ok(cardId, 'Card ID should exist')
|
|
204
|
+
|
|
205
|
+
const content = await getContent({
|
|
206
|
+
accessToken,
|
|
207
|
+
cardId,
|
|
208
|
+
timezone: 'Pacific/Auckland'
|
|
209
|
+
})
|
|
210
|
+
|
|
211
|
+
// Log response with timezone parameter
|
|
212
|
+
logResponse('GET /content/{cardId}?timezone=Pacific/Auckland', content)
|
|
213
|
+
|
|
214
|
+
assert.ok(content.card, 'Should return content with timezone parameter')
|
|
215
|
+
assert.strictEqual(content.card.cardId, cardId, 'Should return correct card')
|
|
216
|
+
})
|
|
217
|
+
|
|
218
|
+
await t.test('should accept playable parameter for signed URLs', async () => {
|
|
219
|
+
const cardId = testCardIds[0]
|
|
220
|
+
assert.ok(cardId, 'Card ID should exist')
|
|
221
|
+
|
|
222
|
+
const content = await getContent({
|
|
223
|
+
accessToken,
|
|
224
|
+
cardId,
|
|
225
|
+
playable: true,
|
|
226
|
+
signingType: 's3'
|
|
227
|
+
})
|
|
228
|
+
|
|
229
|
+
// Log response with playable URLs
|
|
230
|
+
logResponse('GET /content/{cardId}?playable=true&signingType=s3', content)
|
|
231
|
+
|
|
232
|
+
assert.ok(content.card, 'Should return content with playable URLs')
|
|
233
|
+
assert.strictEqual(content.card.cardId, cardId, 'Should return correct card')
|
|
234
|
+
})
|
|
235
|
+
})
|
|
236
|
+
|
|
237
|
+
// TODO: Add tests for createOrUpdateContent
|
|
238
|
+
// - should create new content without cardId
|
|
239
|
+
// - should return created card with generated cardId
|
|
240
|
+
// - should update existing content with cardId
|
|
241
|
+
// - should validate response structure matches YotoCreateOrUpdateContentResponse
|
|
242
|
+
// - should fail with invalid token
|
|
243
|
+
// - should accept all content fields (chapters, config, metadata)
|
|
244
|
+
|
|
245
|
+
// TODO: Add tests for deleteContent
|
|
246
|
+
// - should delete content successfully
|
|
247
|
+
// - should return status 'ok'
|
|
248
|
+
// - should fail with 404 for non-existent cardId
|
|
249
|
+
// - should fail with 404 when trying to delete content user didn't create
|
|
250
|
+
// - should fail with invalid token
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
export function getDevices({ accessToken, userAgent, requestOptions }: {
|
|
2
|
+
accessToken: string;
|
|
3
|
+
userAgent?: string | undefined;
|
|
4
|
+
requestOptions?: ({
|
|
5
|
+
dispatcher?: import("undici").Dispatcher;
|
|
6
|
+
} & Omit<import("undici").Dispatcher.RequestOptions<unknown>, "origin" | "path" | "method"> & Partial<Pick<import("undici").Dispatcher.RequestOptions<null>, "method">>) | undefined;
|
|
7
|
+
}): Promise<YotoDevicesResponse>;
|
|
8
|
+
export function getDeviceStatus({ accessToken, userAgent, deviceId, requestOptions }: {
|
|
9
|
+
accessToken: string;
|
|
10
|
+
deviceId: string;
|
|
11
|
+
userAgent?: string | undefined;
|
|
12
|
+
requestOptions?: ({
|
|
13
|
+
dispatcher?: import("undici").Dispatcher;
|
|
14
|
+
} & Omit<import("undici").Dispatcher.RequestOptions<unknown>, "origin" | "path" | "method"> & Partial<Pick<import("undici").Dispatcher.RequestOptions<null>, "method">>) | undefined;
|
|
15
|
+
}): Promise<YotoDeviceStatusResponse>;
|
|
16
|
+
export function getDeviceConfig({ accessToken, userAgent, deviceId, requestOptions }: {
|
|
17
|
+
accessToken: string;
|
|
18
|
+
deviceId: string;
|
|
19
|
+
userAgent?: string | undefined;
|
|
20
|
+
requestOptions?: ({
|
|
21
|
+
dispatcher?: import("undici").Dispatcher;
|
|
22
|
+
} & Omit<import("undici").Dispatcher.RequestOptions<unknown>, "origin" | "path" | "method"> & Partial<Pick<import("undici").Dispatcher.RequestOptions<null>, "method">>) | undefined;
|
|
23
|
+
}): Promise<YotoDeviceConfigResponse>;
|
|
24
|
+
export function updateDeviceConfig({ accessToken, userAgent, deviceId, configUpdate, requestOptions }: {
|
|
25
|
+
accessToken: string;
|
|
26
|
+
deviceId: string;
|
|
27
|
+
configUpdate: YotoUpdateDeviceConfigRequest;
|
|
28
|
+
userAgent?: string | undefined;
|
|
29
|
+
requestOptions?: ({
|
|
30
|
+
dispatcher?: import("undici").Dispatcher;
|
|
31
|
+
} & Omit<import("undici").Dispatcher.RequestOptions<unknown>, "origin" | "path" | "method"> & Partial<Pick<import("undici").Dispatcher.RequestOptions<null>, "method">>) | undefined;
|
|
32
|
+
}): Promise<YotoUpdateDeviceConfigResponse>;
|
|
33
|
+
export function updateDeviceShortcuts({ accessToken, userAgent, deviceId, shortcutsUpdate, requestOptions }: {
|
|
34
|
+
accessToken: string;
|
|
35
|
+
deviceId: string;
|
|
36
|
+
shortcutsUpdate: YotoUpdateShortcutsRequest;
|
|
37
|
+
userAgent?: string | undefined;
|
|
38
|
+
requestOptions?: ({
|
|
39
|
+
dispatcher?: import("undici").Dispatcher;
|
|
40
|
+
} & Omit<import("undici").Dispatcher.RequestOptions<unknown>, "origin" | "path" | "method"> & Partial<Pick<import("undici").Dispatcher.RequestOptions<null>, "method">>) | undefined;
|
|
41
|
+
}): Promise<YotoUpdateShortcutsResponse>;
|
|
42
|
+
export function sendDeviceCommand({ accessToken, userAgent, deviceId, command, requestOptions }: {
|
|
43
|
+
accessToken: string;
|
|
44
|
+
deviceId: string;
|
|
45
|
+
command: YotoDeviceCommand;
|
|
46
|
+
userAgent?: string | undefined;
|
|
47
|
+
requestOptions?: ({
|
|
48
|
+
dispatcher?: import("undici").Dispatcher;
|
|
49
|
+
} & Omit<import("undici").Dispatcher.RequestOptions<unknown>, "origin" | "path" | "method"> & Partial<Pick<import("undici").Dispatcher.RequestOptions<null>, "method">>) | undefined;
|
|
50
|
+
}): Promise<YotoDeviceCommandResponse>;
|
|
51
|
+
export type YotoDevicesResponse = {
|
|
52
|
+
devices: YotoDevice[];
|
|
53
|
+
};
|
|
54
|
+
export type YotoDevice = {
|
|
55
|
+
deviceId: string;
|
|
56
|
+
name: string;
|
|
57
|
+
description: string;
|
|
58
|
+
online: boolean;
|
|
59
|
+
releaseChannel: string;
|
|
60
|
+
deviceType: string;
|
|
61
|
+
deviceFamily: string;
|
|
62
|
+
deviceGroup: string;
|
|
63
|
+
generation?: string;
|
|
64
|
+
formFactor?: string;
|
|
65
|
+
};
|
|
66
|
+
export type YotoDeviceStatusResponse = {
|
|
67
|
+
deviceId: string;
|
|
68
|
+
activeCard?: string;
|
|
69
|
+
ambientLightSensorReading?: number;
|
|
70
|
+
averageDownloadSpeedBytesSecond?: number;
|
|
71
|
+
batteryLevelPercentage?: number;
|
|
72
|
+
batteryLevelPercentageRaw?: number;
|
|
73
|
+
buzzErrors?: number;
|
|
74
|
+
cardInsertionState?: 0 | 1 | 2;
|
|
75
|
+
dayMode?: -1 | 0 | 1;
|
|
76
|
+
errorsLogged?: number;
|
|
77
|
+
firmwareVersion?: string;
|
|
78
|
+
freeDiskSpaceBytes?: number;
|
|
79
|
+
isAudioDeviceConnected?: boolean;
|
|
80
|
+
isBackgroundDownloadActive?: boolean;
|
|
81
|
+
isBluetoothAudioConnected?: boolean;
|
|
82
|
+
isCharging?: boolean;
|
|
83
|
+
isNfcLocked?: number;
|
|
84
|
+
isOnline?: boolean;
|
|
85
|
+
networkSsid?: string;
|
|
86
|
+
nightlightMode?: string;
|
|
87
|
+
playingSource?: number;
|
|
88
|
+
powerCapabilities?: string | null;
|
|
89
|
+
powerSource?: 0 | 1 | 2 | 3;
|
|
90
|
+
systemVolumePercentage?: number;
|
|
91
|
+
taskWatchdogTimeoutCount?: number;
|
|
92
|
+
temperatureCelcius?: number | string;
|
|
93
|
+
totalDiskSpaceBytes?: number;
|
|
94
|
+
updatedAt?: string;
|
|
95
|
+
uptime?: number;
|
|
96
|
+
userVolumePercentage?: number;
|
|
97
|
+
utcOffsetSeconds?: number;
|
|
98
|
+
utcTime?: number;
|
|
99
|
+
wifiStrength?: number;
|
|
100
|
+
};
|
|
101
|
+
export type YotoDeviceConfigResponse = {
|
|
102
|
+
device: YotoDeviceConfigDevice;
|
|
103
|
+
};
|
|
104
|
+
export type YotoDeviceConfigDevice = {
|
|
105
|
+
config: YotoDeviceConfig;
|
|
106
|
+
deviceFamily: string;
|
|
107
|
+
deviceGroup: string;
|
|
108
|
+
deviceId: string;
|
|
109
|
+
deviceType: string;
|
|
110
|
+
errorCode: any;
|
|
111
|
+
geoTimezone: string;
|
|
112
|
+
getPosix: string;
|
|
113
|
+
mac: string;
|
|
114
|
+
name: string;
|
|
115
|
+
online: boolean;
|
|
116
|
+
registrationCode: string;
|
|
117
|
+
activationPopCode: string;
|
|
118
|
+
popCode: string;
|
|
119
|
+
releaseChannelId: string;
|
|
120
|
+
releaseChannelVersion: string;
|
|
121
|
+
fwVersion: string;
|
|
122
|
+
status?: any;
|
|
123
|
+
shortcuts?: YotoDeviceShortcuts;
|
|
124
|
+
};
|
|
125
|
+
export type YotoDeviceConfig = {
|
|
126
|
+
alarms?: string[];
|
|
127
|
+
ambientColour: string;
|
|
128
|
+
bluetoothEnabled: string;
|
|
129
|
+
btHeadphonesEnabled: boolean;
|
|
130
|
+
clockFace?: string;
|
|
131
|
+
dayDisplayBrightness: string;
|
|
132
|
+
dayTime: string;
|
|
133
|
+
dayYotoDaily: string;
|
|
134
|
+
dayYotoRadio: string;
|
|
135
|
+
daySoundsOff?: string;
|
|
136
|
+
displayDimBrightness?: string;
|
|
137
|
+
displayDimTimeout: string;
|
|
138
|
+
headphonesVolumeLimited: boolean;
|
|
139
|
+
hourFormat?: string;
|
|
140
|
+
logLevel?: string;
|
|
141
|
+
locale?: string;
|
|
142
|
+
maxVolumeLimit: string;
|
|
143
|
+
nightAmbientColour: string;
|
|
144
|
+
nightDisplayBrightness: string;
|
|
145
|
+
nightMaxVolumeLimit: string;
|
|
146
|
+
nightTime: string;
|
|
147
|
+
nightYotoDaily: string;
|
|
148
|
+
nightYotoRadio: string;
|
|
149
|
+
nightSoundsOff?: string;
|
|
150
|
+
pausePowerButton?: boolean;
|
|
151
|
+
pauseVolumeDown?: boolean;
|
|
152
|
+
repeatAll: boolean;
|
|
153
|
+
showDiagnostics?: boolean;
|
|
154
|
+
shutdownTimeout: string;
|
|
155
|
+
systemVolume?: string;
|
|
156
|
+
timezone?: string;
|
|
157
|
+
volumeLevel?: string;
|
|
158
|
+
};
|
|
159
|
+
export type YotoDeviceShortcuts = {
|
|
160
|
+
modes: YotoShortcutModes;
|
|
161
|
+
versionId: string;
|
|
162
|
+
};
|
|
163
|
+
export type YotoShortcutModes = {
|
|
164
|
+
day: YotoShortcutMode;
|
|
165
|
+
night: YotoShortcutMode;
|
|
166
|
+
};
|
|
167
|
+
export type YotoShortcutMode = {
|
|
168
|
+
content: YotoShortcutContent[];
|
|
169
|
+
};
|
|
170
|
+
export type YotoShortcutContent = {
|
|
171
|
+
cmd: string;
|
|
172
|
+
params: YotoShortcutParams;
|
|
173
|
+
};
|
|
174
|
+
export type YotoShortcutParams = {
|
|
175
|
+
card: string;
|
|
176
|
+
chapter: string;
|
|
177
|
+
track: string;
|
|
178
|
+
};
|
|
179
|
+
export type YotoUpdateDeviceConfigRequest = {
|
|
180
|
+
name?: string;
|
|
181
|
+
config: Partial<YotoDeviceConfig>;
|
|
182
|
+
};
|
|
183
|
+
export type YotoUpdateDeviceConfigResponse = {
|
|
184
|
+
status: string;
|
|
185
|
+
};
|
|
186
|
+
export type YotoUpdateShortcutsRequest = {
|
|
187
|
+
shortcuts: YotoDeviceShortcuts;
|
|
188
|
+
};
|
|
189
|
+
export type YotoUpdateShortcutsResponse = {
|
|
190
|
+
status: string;
|
|
191
|
+
};
|
|
192
|
+
export type YotoDeviceCommandResponse = {
|
|
193
|
+
status: string;
|
|
194
|
+
};
|
|
195
|
+
export type YotoDeviceCommand = YotoVolumeCommand | YotoAmbientCommand | YotoSleepTimerCommand | YotoCardStartCommand | YotoBluetoothCommand | YotoDisplayPreviewCommand | {};
|
|
196
|
+
import type { YotoVolumeCommand } from '../mqtt/commands.js';
|
|
197
|
+
import type { YotoAmbientCommand } from '../mqtt/commands.js';
|
|
198
|
+
import type { YotoSleepTimerCommand } from '../mqtt/commands.js';
|
|
199
|
+
import type { YotoCardStartCommand } from '../mqtt/commands.js';
|
|
200
|
+
import type { YotoBluetoothCommand } from '../mqtt/commands.js';
|
|
201
|
+
import type { YotoDisplayPreviewCommand } from '../mqtt/commands.js';
|
|
202
|
+
//# sourceMappingURL=devices.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"devices.d.ts","sourceRoot":"","sources":["devices.js"],"names":[],"mappings":"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"}
|