@tomorrowos/sdk 0.6.0 → 0.6.2
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/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/store/postgres-store.js +253 -253
- package/dist/store/sqlite-store.js +249 -249
- package/dist/tomorrowos.d.ts +14 -0
- package/dist/tomorrowos.d.ts.map +1 -1
- package/dist/tomorrowos.js +108 -0
- package/package.json +1 -1
- package/templates/cms-starter/.env.example +12 -12
- package/templates/cms-starter/package.json +2 -2
- package/templates/cms-starter/public/index.html +12 -0
- package/templates/cms-starter/public/methods.js +66 -0
- package/templates/cms-starter/public/panel.css +14 -0
|
@@ -35,90 +35,90 @@ export class SQLiteStore {
|
|
|
35
35
|
this.db.pragma("foreign_keys = ON");
|
|
36
36
|
this.db.pragma("journal_mode = WAL");
|
|
37
37
|
this.db.pragma("busy_timeout = 5000");
|
|
38
|
-
this.db.exec(`
|
|
39
|
-
CREATE TABLE IF NOT EXISTS schema_migrations (
|
|
40
|
-
id INTEGER PRIMARY KEY,
|
|
41
|
-
name TEXT NOT NULL UNIQUE,
|
|
42
|
-
applied_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
43
|
-
);
|
|
44
|
-
|
|
45
|
-
CREATE TABLE IF NOT EXISTS pending_codes (
|
|
46
|
-
code TEXT PRIMARY KEY,
|
|
47
|
-
device_id TEXT NOT NULL,
|
|
48
|
-
created_at INTEGER NOT NULL
|
|
49
|
-
);
|
|
50
|
-
|
|
51
|
-
CREATE TABLE IF NOT EXISTS device_registry (
|
|
52
|
-
device_id TEXT PRIMARY KEY,
|
|
53
|
-
permanent_pairing_code TEXT NOT NULL UNIQUE,
|
|
54
|
-
code_created_at INTEGER NOT NULL,
|
|
55
|
-
serial_number TEXT,
|
|
56
|
-
first_seen_at INTEGER,
|
|
57
|
-
last_hello_at INTEGER
|
|
58
|
-
);
|
|
59
|
-
|
|
60
|
-
CREATE TABLE IF NOT EXISTS paired_devices (
|
|
61
|
-
device_id TEXT PRIMARY KEY,
|
|
62
|
-
pairing_token TEXT NOT NULL,
|
|
63
|
-
paired_at TEXT NOT NULL,
|
|
64
|
-
device_name TEXT,
|
|
65
|
-
platform TEXT,
|
|
66
|
-
system TEXT,
|
|
67
|
-
player_version TEXT,
|
|
68
|
-
last_boot_at TEXT,
|
|
69
|
-
last_online_at TEXT,
|
|
70
|
-
last_offline_at TEXT,
|
|
71
|
-
last_policy_push_at TEXT
|
|
72
|
-
);
|
|
73
|
-
|
|
74
|
-
CREATE TABLE IF NOT EXISTS playlists (
|
|
75
|
-
id TEXT PRIMARY KEY,
|
|
76
|
-
name TEXT NOT NULL,
|
|
77
|
-
schedule_json TEXT,
|
|
78
|
-
items_json TEXT NOT NULL DEFAULT '[]',
|
|
79
|
-
version INTEGER NOT NULL,
|
|
80
|
-
updated_at TEXT NOT NULL,
|
|
81
|
-
retired INTEGER NOT NULL DEFAULT 0,
|
|
82
|
-
retired_at TEXT
|
|
83
|
-
);
|
|
84
|
-
|
|
85
|
-
CREATE UNIQUE INDEX IF NOT EXISTS playlists_active_name_unique
|
|
86
|
-
ON playlists (lower(trim(name)))
|
|
87
|
-
WHERE retired = 0;
|
|
88
|
-
|
|
89
|
-
CREATE TABLE IF NOT EXISTS device_assignments (
|
|
90
|
-
device_id TEXT NOT NULL,
|
|
91
|
-
playlist_id TEXT NOT NULL,
|
|
92
|
-
sort_order INTEGER NOT NULL,
|
|
93
|
-
published_version INTEGER NOT NULL,
|
|
94
|
-
published_at TEXT NOT NULL,
|
|
95
|
-
snapshot_json TEXT NOT NULL,
|
|
96
|
-
PRIMARY KEY (device_id, playlist_id)
|
|
97
|
-
);
|
|
98
|
-
|
|
99
|
-
CREATE INDEX IF NOT EXISTS device_assignments_device_order_idx
|
|
100
|
-
ON device_assignments (device_id, sort_order);
|
|
101
|
-
|
|
102
|
-
CREATE TABLE IF NOT EXISTS uploaded_assets (
|
|
103
|
-
id TEXT PRIMARY KEY,
|
|
104
|
-
sha256 TEXT NOT NULL,
|
|
105
|
-
storage_provider TEXT NOT NULL,
|
|
106
|
-
storage_key TEXT NOT NULL,
|
|
107
|
-
url TEXT NOT NULL,
|
|
108
|
-
original_filename TEXT,
|
|
109
|
-
mime_type TEXT,
|
|
110
|
-
resource_type TEXT,
|
|
111
|
-
bytes INTEGER,
|
|
112
|
-
created_at TEXT NOT NULL,
|
|
113
|
-
updated_at TEXT NOT NULL,
|
|
114
|
-
UNIQUE (storage_provider, sha256)
|
|
115
|
-
);
|
|
116
|
-
|
|
117
|
-
CREATE INDEX IF NOT EXISTS uploaded_assets_sha256_idx
|
|
118
|
-
ON uploaded_assets (sha256);
|
|
119
|
-
|
|
120
|
-
INSERT OR IGNORE INTO schema_migrations (id, name)
|
|
121
|
-
VALUES (1, 'initial_tomorrowos_store');
|
|
38
|
+
this.db.exec(`
|
|
39
|
+
CREATE TABLE IF NOT EXISTS schema_migrations (
|
|
40
|
+
id INTEGER PRIMARY KEY,
|
|
41
|
+
name TEXT NOT NULL UNIQUE,
|
|
42
|
+
applied_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
CREATE TABLE IF NOT EXISTS pending_codes (
|
|
46
|
+
code TEXT PRIMARY KEY,
|
|
47
|
+
device_id TEXT NOT NULL,
|
|
48
|
+
created_at INTEGER NOT NULL
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
CREATE TABLE IF NOT EXISTS device_registry (
|
|
52
|
+
device_id TEXT PRIMARY KEY,
|
|
53
|
+
permanent_pairing_code TEXT NOT NULL UNIQUE,
|
|
54
|
+
code_created_at INTEGER NOT NULL,
|
|
55
|
+
serial_number TEXT,
|
|
56
|
+
first_seen_at INTEGER,
|
|
57
|
+
last_hello_at INTEGER
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
CREATE TABLE IF NOT EXISTS paired_devices (
|
|
61
|
+
device_id TEXT PRIMARY KEY,
|
|
62
|
+
pairing_token TEXT NOT NULL,
|
|
63
|
+
paired_at TEXT NOT NULL,
|
|
64
|
+
device_name TEXT,
|
|
65
|
+
platform TEXT,
|
|
66
|
+
system TEXT,
|
|
67
|
+
player_version TEXT,
|
|
68
|
+
last_boot_at TEXT,
|
|
69
|
+
last_online_at TEXT,
|
|
70
|
+
last_offline_at TEXT,
|
|
71
|
+
last_policy_push_at TEXT
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
CREATE TABLE IF NOT EXISTS playlists (
|
|
75
|
+
id TEXT PRIMARY KEY,
|
|
76
|
+
name TEXT NOT NULL,
|
|
77
|
+
schedule_json TEXT,
|
|
78
|
+
items_json TEXT NOT NULL DEFAULT '[]',
|
|
79
|
+
version INTEGER NOT NULL,
|
|
80
|
+
updated_at TEXT NOT NULL,
|
|
81
|
+
retired INTEGER NOT NULL DEFAULT 0,
|
|
82
|
+
retired_at TEXT
|
|
83
|
+
);
|
|
84
|
+
|
|
85
|
+
CREATE UNIQUE INDEX IF NOT EXISTS playlists_active_name_unique
|
|
86
|
+
ON playlists (lower(trim(name)))
|
|
87
|
+
WHERE retired = 0;
|
|
88
|
+
|
|
89
|
+
CREATE TABLE IF NOT EXISTS device_assignments (
|
|
90
|
+
device_id TEXT NOT NULL,
|
|
91
|
+
playlist_id TEXT NOT NULL,
|
|
92
|
+
sort_order INTEGER NOT NULL,
|
|
93
|
+
published_version INTEGER NOT NULL,
|
|
94
|
+
published_at TEXT NOT NULL,
|
|
95
|
+
snapshot_json TEXT NOT NULL,
|
|
96
|
+
PRIMARY KEY (device_id, playlist_id)
|
|
97
|
+
);
|
|
98
|
+
|
|
99
|
+
CREATE INDEX IF NOT EXISTS device_assignments_device_order_idx
|
|
100
|
+
ON device_assignments (device_id, sort_order);
|
|
101
|
+
|
|
102
|
+
CREATE TABLE IF NOT EXISTS uploaded_assets (
|
|
103
|
+
id TEXT PRIMARY KEY,
|
|
104
|
+
sha256 TEXT NOT NULL,
|
|
105
|
+
storage_provider TEXT NOT NULL,
|
|
106
|
+
storage_key TEXT NOT NULL,
|
|
107
|
+
url TEXT NOT NULL,
|
|
108
|
+
original_filename TEXT,
|
|
109
|
+
mime_type TEXT,
|
|
110
|
+
resource_type TEXT,
|
|
111
|
+
bytes INTEGER,
|
|
112
|
+
created_at TEXT NOT NULL,
|
|
113
|
+
updated_at TEXT NOT NULL,
|
|
114
|
+
UNIQUE (storage_provider, sha256)
|
|
115
|
+
);
|
|
116
|
+
|
|
117
|
+
CREATE INDEX IF NOT EXISTS uploaded_assets_sha256_idx
|
|
118
|
+
ON uploaded_assets (sha256);
|
|
119
|
+
|
|
120
|
+
INSERT OR IGNORE INTO schema_migrations (id, name)
|
|
121
|
+
VALUES (1, 'initial_tomorrowos_store');
|
|
122
122
|
`);
|
|
123
123
|
this.addColumnIfMissing("paired_devices", "player_version TEXT");
|
|
124
124
|
}
|
|
@@ -136,19 +136,19 @@ export class SQLiteStore {
|
|
|
136
136
|
this.db.close();
|
|
137
137
|
}
|
|
138
138
|
async setPendingCode(code, record) {
|
|
139
|
-
this.db.prepare(`
|
|
140
|
-
INSERT INTO pending_codes (code, device_id, created_at)
|
|
141
|
-
VALUES (?, ?, ?)
|
|
142
|
-
ON CONFLICT(code) DO UPDATE SET
|
|
143
|
-
device_id = excluded.device_id,
|
|
144
|
-
created_at = excluded.created_at
|
|
139
|
+
this.db.prepare(`
|
|
140
|
+
INSERT INTO pending_codes (code, device_id, created_at)
|
|
141
|
+
VALUES (?, ?, ?)
|
|
142
|
+
ON CONFLICT(code) DO UPDATE SET
|
|
143
|
+
device_id = excluded.device_id,
|
|
144
|
+
created_at = excluded.created_at
|
|
145
145
|
`).run(code, record.deviceId, record.createdAt);
|
|
146
146
|
}
|
|
147
147
|
async getPendingCode(code) {
|
|
148
|
-
const row = this.db.prepare(`
|
|
149
|
-
SELECT device_id, created_at
|
|
150
|
-
FROM pending_codes
|
|
151
|
-
WHERE code = ?
|
|
148
|
+
const row = this.db.prepare(`
|
|
149
|
+
SELECT device_id, created_at
|
|
150
|
+
FROM pending_codes
|
|
151
|
+
WHERE code = ?
|
|
152
152
|
`).get(code);
|
|
153
153
|
if (!row)
|
|
154
154
|
return undefined;
|
|
@@ -158,10 +158,10 @@ export class SQLiteStore {
|
|
|
158
158
|
this.db.prepare("DELETE FROM pending_codes WHERE code = ?").run(code);
|
|
159
159
|
}
|
|
160
160
|
async listPendingCodes() {
|
|
161
|
-
const rows = this.db.prepare(`
|
|
162
|
-
SELECT code, device_id, created_at
|
|
163
|
-
FROM pending_codes
|
|
164
|
-
ORDER BY created_at ASC
|
|
161
|
+
const rows = this.db.prepare(`
|
|
162
|
+
SELECT code, device_id, created_at
|
|
163
|
+
FROM pending_codes
|
|
164
|
+
ORDER BY created_at ASC
|
|
165
165
|
`).all();
|
|
166
166
|
return rows.map((row) => ({
|
|
167
167
|
code: row.code,
|
|
@@ -169,37 +169,37 @@ export class SQLiteStore {
|
|
|
169
169
|
}));
|
|
170
170
|
}
|
|
171
171
|
async getDeviceRegistry(deviceId) {
|
|
172
|
-
const row = this.db.prepare(`
|
|
173
|
-
SELECT *
|
|
174
|
-
FROM device_registry
|
|
175
|
-
WHERE device_id = ?
|
|
172
|
+
const row = this.db.prepare(`
|
|
173
|
+
SELECT *
|
|
174
|
+
FROM device_registry
|
|
175
|
+
WHERE device_id = ?
|
|
176
176
|
`).get(deviceId);
|
|
177
177
|
return row ? this.mapDeviceRegistryRow(row) : undefined;
|
|
178
178
|
}
|
|
179
179
|
async setDeviceRegistry(deviceId, record) {
|
|
180
|
-
this.db.prepare(`
|
|
181
|
-
INSERT INTO device_registry (
|
|
182
|
-
device_id,
|
|
183
|
-
permanent_pairing_code,
|
|
184
|
-
code_created_at,
|
|
185
|
-
serial_number,
|
|
186
|
-
first_seen_at,
|
|
187
|
-
last_hello_at
|
|
188
|
-
)
|
|
189
|
-
VALUES (?, ?, ?, ?, ?, ?)
|
|
190
|
-
ON CONFLICT(device_id) DO UPDATE SET
|
|
191
|
-
permanent_pairing_code = excluded.permanent_pairing_code,
|
|
192
|
-
code_created_at = excluded.code_created_at,
|
|
193
|
-
serial_number = excluded.serial_number,
|
|
194
|
-
first_seen_at = excluded.first_seen_at,
|
|
195
|
-
last_hello_at = excluded.last_hello_at
|
|
180
|
+
this.db.prepare(`
|
|
181
|
+
INSERT INTO device_registry (
|
|
182
|
+
device_id,
|
|
183
|
+
permanent_pairing_code,
|
|
184
|
+
code_created_at,
|
|
185
|
+
serial_number,
|
|
186
|
+
first_seen_at,
|
|
187
|
+
last_hello_at
|
|
188
|
+
)
|
|
189
|
+
VALUES (?, ?, ?, ?, ?, ?)
|
|
190
|
+
ON CONFLICT(device_id) DO UPDATE SET
|
|
191
|
+
permanent_pairing_code = excluded.permanent_pairing_code,
|
|
192
|
+
code_created_at = excluded.code_created_at,
|
|
193
|
+
serial_number = excluded.serial_number,
|
|
194
|
+
first_seen_at = excluded.first_seen_at,
|
|
195
|
+
last_hello_at = excluded.last_hello_at
|
|
196
196
|
`).run(deviceId, record.permanentPairingCode, record.codeCreatedAt, record.serialNumber ?? null, record.firstSeenAt ?? null, record.lastHelloAt ?? null);
|
|
197
197
|
}
|
|
198
198
|
async getDeviceRegistryByCode(code) {
|
|
199
|
-
const row = this.db.prepare(`
|
|
200
|
-
SELECT *
|
|
201
|
-
FROM device_registry
|
|
202
|
-
WHERE permanent_pairing_code = ?
|
|
199
|
+
const row = this.db.prepare(`
|
|
200
|
+
SELECT *
|
|
201
|
+
FROM device_registry
|
|
202
|
+
WHERE permanent_pairing_code = ?
|
|
203
203
|
`).get(code);
|
|
204
204
|
if (!row)
|
|
205
205
|
return undefined;
|
|
@@ -209,10 +209,10 @@ export class SQLiteStore {
|
|
|
209
209
|
};
|
|
210
210
|
}
|
|
211
211
|
async listDeviceRegistry() {
|
|
212
|
-
const rows = this.db.prepare(`
|
|
213
|
-
SELECT *
|
|
214
|
-
FROM device_registry
|
|
215
|
-
ORDER BY code_created_at ASC
|
|
212
|
+
const rows = this.db.prepare(`
|
|
213
|
+
SELECT *
|
|
214
|
+
FROM device_registry
|
|
215
|
+
ORDER BY code_created_at ASC
|
|
216
216
|
`).all();
|
|
217
217
|
return rows.map((row) => ({
|
|
218
218
|
deviceId: row.device_id,
|
|
@@ -220,39 +220,39 @@ export class SQLiteStore {
|
|
|
220
220
|
}));
|
|
221
221
|
}
|
|
222
222
|
async setPairedDevice(deviceId, record) {
|
|
223
|
-
this.db.prepare(`
|
|
224
|
-
INSERT INTO paired_devices (
|
|
225
|
-
device_id,
|
|
226
|
-
pairing_token,
|
|
227
|
-
paired_at,
|
|
228
|
-
device_name,
|
|
229
|
-
platform,
|
|
230
|
-
system,
|
|
231
|
-
player_version,
|
|
232
|
-
last_boot_at,
|
|
233
|
-
last_online_at,
|
|
234
|
-
last_offline_at,
|
|
235
|
-
last_policy_push_at
|
|
236
|
-
)
|
|
237
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
238
|
-
ON CONFLICT(device_id) DO UPDATE SET
|
|
239
|
-
pairing_token = excluded.pairing_token,
|
|
240
|
-
paired_at = excluded.paired_at,
|
|
241
|
-
device_name = excluded.device_name,
|
|
242
|
-
platform = excluded.platform,
|
|
243
|
-
system = excluded.system,
|
|
244
|
-
player_version = excluded.player_version,
|
|
245
|
-
last_boot_at = excluded.last_boot_at,
|
|
246
|
-
last_online_at = excluded.last_online_at,
|
|
247
|
-
last_offline_at = excluded.last_offline_at,
|
|
248
|
-
last_policy_push_at = excluded.last_policy_push_at
|
|
223
|
+
this.db.prepare(`
|
|
224
|
+
INSERT INTO paired_devices (
|
|
225
|
+
device_id,
|
|
226
|
+
pairing_token,
|
|
227
|
+
paired_at,
|
|
228
|
+
device_name,
|
|
229
|
+
platform,
|
|
230
|
+
system,
|
|
231
|
+
player_version,
|
|
232
|
+
last_boot_at,
|
|
233
|
+
last_online_at,
|
|
234
|
+
last_offline_at,
|
|
235
|
+
last_policy_push_at
|
|
236
|
+
)
|
|
237
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
238
|
+
ON CONFLICT(device_id) DO UPDATE SET
|
|
239
|
+
pairing_token = excluded.pairing_token,
|
|
240
|
+
paired_at = excluded.paired_at,
|
|
241
|
+
device_name = excluded.device_name,
|
|
242
|
+
platform = excluded.platform,
|
|
243
|
+
system = excluded.system,
|
|
244
|
+
player_version = excluded.player_version,
|
|
245
|
+
last_boot_at = excluded.last_boot_at,
|
|
246
|
+
last_online_at = excluded.last_online_at,
|
|
247
|
+
last_offline_at = excluded.last_offline_at,
|
|
248
|
+
last_policy_push_at = excluded.last_policy_push_at
|
|
249
249
|
`).run(deviceId, record.pairingToken, record.pairedAt, record.deviceName ?? null, record.platform ?? null, record.system ?? null, record.playerVersion ?? null, record.lastBootAt ?? null, record.lastOnlineAt ?? null, record.lastOfflineAt ?? null, record.lastPolicyPushAt ?? null);
|
|
250
250
|
}
|
|
251
251
|
async getPairedDevice(deviceId) {
|
|
252
|
-
const row = this.db.prepare(`
|
|
253
|
-
SELECT *
|
|
254
|
-
FROM paired_devices
|
|
255
|
-
WHERE device_id = ?
|
|
252
|
+
const row = this.db.prepare(`
|
|
253
|
+
SELECT *
|
|
254
|
+
FROM paired_devices
|
|
255
|
+
WHERE device_id = ?
|
|
256
256
|
`).get(deviceId);
|
|
257
257
|
return row ? this.mapPairedDeviceRow(row) : undefined;
|
|
258
258
|
}
|
|
@@ -260,10 +260,10 @@ export class SQLiteStore {
|
|
|
260
260
|
this.db.prepare("DELETE FROM paired_devices WHERE device_id = ?").run(deviceId);
|
|
261
261
|
}
|
|
262
262
|
async listPairedDevices() {
|
|
263
|
-
const rows = this.db.prepare(`
|
|
264
|
-
SELECT *
|
|
265
|
-
FROM paired_devices
|
|
266
|
-
ORDER BY paired_at ASC
|
|
263
|
+
const rows = this.db.prepare(`
|
|
264
|
+
SELECT *
|
|
265
|
+
FROM paired_devices
|
|
266
|
+
ORDER BY paired_at ASC
|
|
267
267
|
`).all();
|
|
268
268
|
return rows.map((row) => ({
|
|
269
269
|
deviceId: row.device_id,
|
|
@@ -271,121 +271,121 @@ export class SQLiteStore {
|
|
|
271
271
|
}));
|
|
272
272
|
}
|
|
273
273
|
async listPlaylists() {
|
|
274
|
-
const rows = this.db.prepare(`
|
|
275
|
-
SELECT *
|
|
276
|
-
FROM playlists
|
|
277
|
-
ORDER BY updated_at DESC
|
|
274
|
+
const rows = this.db.prepare(`
|
|
275
|
+
SELECT *
|
|
276
|
+
FROM playlists
|
|
277
|
+
ORDER BY updated_at DESC
|
|
278
278
|
`).all();
|
|
279
279
|
return rows.map((row) => this.mapPlaylistRow(row));
|
|
280
280
|
}
|
|
281
281
|
async getPlaylist(id) {
|
|
282
|
-
const row = this.db.prepare(`
|
|
283
|
-
SELECT *
|
|
284
|
-
FROM playlists
|
|
285
|
-
WHERE id = ?
|
|
282
|
+
const row = this.db.prepare(`
|
|
283
|
+
SELECT *
|
|
284
|
+
FROM playlists
|
|
285
|
+
WHERE id = ?
|
|
286
286
|
`).get(id);
|
|
287
287
|
return row ? this.mapPlaylistRow(row) : undefined;
|
|
288
288
|
}
|
|
289
289
|
async setPlaylist(record) {
|
|
290
|
-
this.db.prepare(`
|
|
291
|
-
INSERT INTO playlists (
|
|
292
|
-
id,
|
|
293
|
-
name,
|
|
294
|
-
schedule_json,
|
|
295
|
-
items_json,
|
|
296
|
-
version,
|
|
297
|
-
updated_at,
|
|
298
|
-
retired,
|
|
299
|
-
retired_at
|
|
300
|
-
)
|
|
301
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
302
|
-
ON CONFLICT(id) DO UPDATE SET
|
|
303
|
-
name = excluded.name,
|
|
304
|
-
schedule_json = excluded.schedule_json,
|
|
305
|
-
items_json = excluded.items_json,
|
|
306
|
-
version = excluded.version,
|
|
307
|
-
updated_at = excluded.updated_at,
|
|
308
|
-
retired = excluded.retired,
|
|
309
|
-
retired_at = excluded.retired_at
|
|
290
|
+
this.db.prepare(`
|
|
291
|
+
INSERT INTO playlists (
|
|
292
|
+
id,
|
|
293
|
+
name,
|
|
294
|
+
schedule_json,
|
|
295
|
+
items_json,
|
|
296
|
+
version,
|
|
297
|
+
updated_at,
|
|
298
|
+
retired,
|
|
299
|
+
retired_at
|
|
300
|
+
)
|
|
301
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
302
|
+
ON CONFLICT(id) DO UPDATE SET
|
|
303
|
+
name = excluded.name,
|
|
304
|
+
schedule_json = excluded.schedule_json,
|
|
305
|
+
items_json = excluded.items_json,
|
|
306
|
+
version = excluded.version,
|
|
307
|
+
updated_at = excluded.updated_at,
|
|
308
|
+
retired = excluded.retired,
|
|
309
|
+
retired_at = excluded.retired_at
|
|
310
310
|
`).run(record.id, record.name, record.schedule ? JSON.stringify(record.schedule) : null, JSON.stringify(record.items ?? []), record.version, record.updatedAt, record.retired ? 1 : 0, record.retiredAt ?? null);
|
|
311
311
|
}
|
|
312
312
|
async isPlaylistNameTaken(name, excludeId) {
|
|
313
313
|
const target = name.trim().toLowerCase();
|
|
314
314
|
if (!target)
|
|
315
315
|
return false;
|
|
316
|
-
const row = this.db.prepare(`
|
|
317
|
-
SELECT id
|
|
318
|
-
FROM playlists
|
|
319
|
-
WHERE retired = 0
|
|
320
|
-
AND lower(trim(name)) = ?
|
|
321
|
-
AND (? IS NULL OR id != ?)
|
|
322
|
-
LIMIT 1
|
|
316
|
+
const row = this.db.prepare(`
|
|
317
|
+
SELECT id
|
|
318
|
+
FROM playlists
|
|
319
|
+
WHERE retired = 0
|
|
320
|
+
AND lower(trim(name)) = ?
|
|
321
|
+
AND (? IS NULL OR id != ?)
|
|
322
|
+
LIMIT 1
|
|
323
323
|
`).get(target, excludeId ?? null, excludeId ?? null);
|
|
324
324
|
return !!row;
|
|
325
325
|
}
|
|
326
326
|
async getUploadedAsset(id) {
|
|
327
|
-
const row = this.db.prepare(`
|
|
328
|
-
SELECT *
|
|
329
|
-
FROM uploaded_assets
|
|
330
|
-
WHERE id = ?
|
|
327
|
+
const row = this.db.prepare(`
|
|
328
|
+
SELECT *
|
|
329
|
+
FROM uploaded_assets
|
|
330
|
+
WHERE id = ?
|
|
331
331
|
`).get(id);
|
|
332
332
|
return row ? this.mapUploadedAssetRow(row) : undefined;
|
|
333
333
|
}
|
|
334
334
|
async getUploadedAssetBySha256(sha256, storageProvider) {
|
|
335
|
-
const row = this.db.prepare(`
|
|
336
|
-
SELECT *
|
|
337
|
-
FROM uploaded_assets
|
|
338
|
-
WHERE sha256 = ?
|
|
339
|
-
AND (? IS NULL OR storage_provider = ?)
|
|
340
|
-
LIMIT 1
|
|
335
|
+
const row = this.db.prepare(`
|
|
336
|
+
SELECT *
|
|
337
|
+
FROM uploaded_assets
|
|
338
|
+
WHERE sha256 = ?
|
|
339
|
+
AND (? IS NULL OR storage_provider = ?)
|
|
340
|
+
LIMIT 1
|
|
341
341
|
`).get(sha256, storageProvider ?? null, storageProvider ?? null);
|
|
342
342
|
return row ? this.mapUploadedAssetRow(row) : undefined;
|
|
343
343
|
}
|
|
344
344
|
async setUploadedAsset(record) {
|
|
345
|
-
this.db.prepare(`
|
|
346
|
-
INSERT INTO uploaded_assets (
|
|
347
|
-
id,
|
|
348
|
-
sha256,
|
|
349
|
-
storage_provider,
|
|
350
|
-
storage_key,
|
|
351
|
-
url,
|
|
352
|
-
original_filename,
|
|
353
|
-
mime_type,
|
|
354
|
-
resource_type,
|
|
355
|
-
bytes,
|
|
356
|
-
created_at,
|
|
357
|
-
updated_at
|
|
358
|
-
)
|
|
359
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
360
|
-
ON CONFLICT(id) DO UPDATE SET
|
|
361
|
-
sha256 = excluded.sha256,
|
|
362
|
-
storage_provider = excluded.storage_provider,
|
|
363
|
-
storage_key = excluded.storage_key,
|
|
364
|
-
url = excluded.url,
|
|
365
|
-
original_filename = excluded.original_filename,
|
|
366
|
-
mime_type = excluded.mime_type,
|
|
367
|
-
resource_type = excluded.resource_type,
|
|
368
|
-
bytes = excluded.bytes,
|
|
369
|
-
updated_at = excluded.updated_at
|
|
345
|
+
this.db.prepare(`
|
|
346
|
+
INSERT INTO uploaded_assets (
|
|
347
|
+
id,
|
|
348
|
+
sha256,
|
|
349
|
+
storage_provider,
|
|
350
|
+
storage_key,
|
|
351
|
+
url,
|
|
352
|
+
original_filename,
|
|
353
|
+
mime_type,
|
|
354
|
+
resource_type,
|
|
355
|
+
bytes,
|
|
356
|
+
created_at,
|
|
357
|
+
updated_at
|
|
358
|
+
)
|
|
359
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
360
|
+
ON CONFLICT(id) DO UPDATE SET
|
|
361
|
+
sha256 = excluded.sha256,
|
|
362
|
+
storage_provider = excluded.storage_provider,
|
|
363
|
+
storage_key = excluded.storage_key,
|
|
364
|
+
url = excluded.url,
|
|
365
|
+
original_filename = excluded.original_filename,
|
|
366
|
+
mime_type = excluded.mime_type,
|
|
367
|
+
resource_type = excluded.resource_type,
|
|
368
|
+
bytes = excluded.bytes,
|
|
369
|
+
updated_at = excluded.updated_at
|
|
370
370
|
`).run(record.id, record.sha256, record.storageProvider, record.storageKey, record.url, record.originalFilename ?? null, record.mimeType ?? null, record.resourceType ?? null, record.bytes ?? null, record.createdAt, record.updatedAt);
|
|
371
371
|
}
|
|
372
372
|
async deleteUploadedAsset(id) {
|
|
373
373
|
this.db.prepare("DELETE FROM uploaded_assets WHERE id = ?").run(id);
|
|
374
374
|
}
|
|
375
375
|
async listUploadedAssets() {
|
|
376
|
-
const rows = this.db.prepare(`
|
|
377
|
-
SELECT *
|
|
378
|
-
FROM uploaded_assets
|
|
379
|
-
ORDER BY created_at ASC
|
|
376
|
+
const rows = this.db.prepare(`
|
|
377
|
+
SELECT *
|
|
378
|
+
FROM uploaded_assets
|
|
379
|
+
ORDER BY created_at ASC
|
|
380
380
|
`).all();
|
|
381
381
|
return rows.map((row) => this.mapUploadedAssetRow(row));
|
|
382
382
|
}
|
|
383
383
|
async getDeviceAssignments(deviceId) {
|
|
384
|
-
const rows = this.db.prepare(`
|
|
385
|
-
SELECT playlist_id, published_version, published_at, snapshot_json
|
|
386
|
-
FROM device_assignments
|
|
387
|
-
WHERE device_id = ?
|
|
388
|
-
ORDER BY sort_order ASC
|
|
384
|
+
const rows = this.db.prepare(`
|
|
385
|
+
SELECT playlist_id, published_version, published_at, snapshot_json
|
|
386
|
+
FROM device_assignments
|
|
387
|
+
WHERE device_id = ?
|
|
388
|
+
ORDER BY sort_order ASC
|
|
389
389
|
`).all(deviceId);
|
|
390
390
|
return rows.map((row) => ({
|
|
391
391
|
playlistId: row.playlist_id,
|
|
@@ -402,16 +402,16 @@ export class SQLiteStore {
|
|
|
402
402
|
async setDeviceAssignments(deviceId, assignments) {
|
|
403
403
|
const replaceAssignments = this.db.transaction(() => {
|
|
404
404
|
this.db.prepare("DELETE FROM device_assignments WHERE device_id = ?").run(deviceId);
|
|
405
|
-
const insert = this.db.prepare(`
|
|
406
|
-
INSERT INTO device_assignments (
|
|
407
|
-
device_id,
|
|
408
|
-
playlist_id,
|
|
409
|
-
sort_order,
|
|
410
|
-
published_version,
|
|
411
|
-
published_at,
|
|
412
|
-
snapshot_json
|
|
413
|
-
)
|
|
414
|
-
VALUES (?, ?, ?, ?, ?, ?)
|
|
405
|
+
const insert = this.db.prepare(`
|
|
406
|
+
INSERT INTO device_assignments (
|
|
407
|
+
device_id,
|
|
408
|
+
playlist_id,
|
|
409
|
+
sort_order,
|
|
410
|
+
published_version,
|
|
411
|
+
published_at,
|
|
412
|
+
snapshot_json
|
|
413
|
+
)
|
|
414
|
+
VALUES (?, ?, ?, ?, ?, ?)
|
|
415
415
|
`);
|
|
416
416
|
assignments.forEach((assignment, index) => {
|
|
417
417
|
insert.run(deviceId, assignment.playlistId, index, assignment.publishedVersion, assignment.publishedAt, JSON.stringify(assignment.snapshot));
|
package/dist/tomorrowos.d.ts
CHANGED
|
@@ -63,6 +63,14 @@ export interface DeviceLogEntry {
|
|
|
63
63
|
source?: string;
|
|
64
64
|
details?: unknown;
|
|
65
65
|
}
|
|
66
|
+
export interface DeviceScreenshotInfo {
|
|
67
|
+
deviceId: string;
|
|
68
|
+
url: string;
|
|
69
|
+
capturedAt: string;
|
|
70
|
+
mimeType: string;
|
|
71
|
+
width?: number;
|
|
72
|
+
height?: number;
|
|
73
|
+
}
|
|
66
74
|
export declare class TomorrowOS extends EventEmitter {
|
|
67
75
|
readonly brand: TomorrowOSBrand;
|
|
68
76
|
private readonly store;
|
|
@@ -131,6 +139,12 @@ export declare class TomorrowOS extends EventEmitter {
|
|
|
131
139
|
private deleteUploadedAssetIfUnreferenced;
|
|
132
140
|
private refreshResolvedBrandLogo;
|
|
133
141
|
private tryServeStatic;
|
|
142
|
+
private getScreenshotsDir;
|
|
143
|
+
private screenshotBaseName;
|
|
144
|
+
private screenshotExtension;
|
|
145
|
+
private saveDeviceScreenshot;
|
|
146
|
+
private getLatestDeviceScreenshot;
|
|
147
|
+
private captureDeviceScreenshot;
|
|
134
148
|
private handleHttp;
|
|
135
149
|
private handleDeviceHttp;
|
|
136
150
|
private sendBrandSnapshot;
|
package/dist/tomorrowos.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tomorrowos.d.ts","sourceRoot":"","sources":["../src/tomorrowos.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAEtC,OAAO,IAAI,MAAM,MAAM,CAAC;AAYxB,OAAO,EAAE,eAAe,EAAE,KAAK,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAChF,OAAO,KAAK,EAKV,eAAe,EAGhB,MAAM,kBAAkB,CAAC;AAc1B,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,eAAe,CAAC;IACvB,6EAA6E;IAC7E,KAAK,CAAC,EAAE,eAAe,CAAC;CACzB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;;OAKG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAkED,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,2EAA2E;IAC3E,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,kBAAkB,EAAE,OAAO,CAAC;IAC5B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,mEAAmE;IACnE,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,kBAAkB,EAAE,KAAK,CAAC;QACxB,UAAU,EAAE,MAAM,CAAC;QACnB,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC,CAAC;IACH,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;CACnC;AAED,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;
|
|
1
|
+
{"version":3,"file":"tomorrowos.d.ts","sourceRoot":"","sources":["../src/tomorrowos.ts"],"names":[],"mappings":"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"}
|