@tomorrowos/sdk 0.1.2 → 0.1.4
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/tomorrowos.d.ts +1 -0
- package/dist/tomorrowos.d.ts.map +1 -1
- package/dist/tomorrowos.js +11 -0
- package/package.json +1 -1
- package/templates/cms-starter/assets/logo.svg +4 -4
- package/templates/cms-starter/package.json +3 -3
- package/templates/cms-starter/public/index.html +58 -0
- package/templates/cms-starter/public/methods.js +124 -0
- package/templates/cms-starter/server.ts +2 -1
package/dist/tomorrowos.d.ts
CHANGED
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;AAKxB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAGxD,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;AAmDD,qBAAa,UAAW,SAAQ,YAAY;IAC1C,QAAQ,CAAC,KAAK,EAAE,eAAe,CAAC;IAChC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAkB;IACxC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAmC;IAC3D,OAAO,CAAC,UAAU,CAA4B;IAC9C,OAAO,CAAC,GAAG,CAAgC;IAC3C,OAAO,CAAC,UAAU,CAAuB;IACzC,OAAO,CAAC,eAAe,CAAgB;gBAE3B,OAAO,EAAE,iBAAiB;IAMtC,oEAAoE;IAC9D,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IAiChE,OAAO;uBACU,MAAM;sBAlCgC,MAAM;;MAmC3D;IAEF,MAAM,CAAC,QAAQ,EAAE,MAAM;oBAGD,CAAC,oBACT,MAAM,WACN,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,OAAO,CAAC;YAAE,MAAM,EAAE,MAAM,CAAC;YAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAAC,KAAK,CAAC,EAAE,MAAM,CAAC;YAAC,KAAK,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;;IAU5E,OAAO,CAAC,mBAAmB;IA6D3B,MAAM,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI,CAAC,MAAM;YAgD7B,cAAc;YAmCd,UAAU;YAgDV,gBAAgB;IAgE9B,OAAO,CAAC,gBAAgB;
|
|
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;AAKxB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAGxD,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;AAmDD,qBAAa,UAAW,SAAQ,YAAY;IAC1C,QAAQ,CAAC,KAAK,EAAE,eAAe,CAAC;IAChC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAkB;IACxC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAmC;IAC3D,OAAO,CAAC,UAAU,CAA4B;IAC9C,OAAO,CAAC,GAAG,CAAgC;IAC3C,OAAO,CAAC,UAAU,CAAuB;IACzC,OAAO,CAAC,eAAe,CAAgB;gBAE3B,OAAO,EAAE,iBAAiB;IAMtC,oEAAoE;IAC9D,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IAiChE,OAAO;uBACU,MAAM;sBAlCgC,MAAM;;MAmC3D;IAEF,MAAM,CAAC,QAAQ,EAAE,MAAM;oBAGD,CAAC,oBACT,MAAM,WACN,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,OAAO,CAAC;YAAE,MAAM,EAAE,MAAM,CAAC;YAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAAC,KAAK,CAAC,EAAE,MAAM,CAAC;YAAC,KAAK,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;;IAU5E,OAAO,CAAC,mBAAmB;IA6D3B,MAAM,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI,CAAC,MAAM;YAgD7B,cAAc;YAmCd,UAAU;YAgDV,gBAAgB;IAgE9B,OAAO,CAAC,iBAAiB;IAWzB,OAAO,CAAC,gBAAgB;CAgFzB"}
|
package/dist/tomorrowos.js
CHANGED
|
@@ -310,6 +310,15 @@ export class TomorrowOS extends EventEmitter {
|
|
|
310
310
|
sendJson(res, 500, { status: "failed", error: msg });
|
|
311
311
|
}
|
|
312
312
|
}
|
|
313
|
+
sendBrandSnapshot(ws) {
|
|
314
|
+
if (ws.readyState !== WebSocket.OPEN)
|
|
315
|
+
return;
|
|
316
|
+
ws.send(JSON.stringify({
|
|
317
|
+
type: "brand.snapshot",
|
|
318
|
+
method: "tomorrowos.brand.snapshot",
|
|
319
|
+
brand: this.brand
|
|
320
|
+
}));
|
|
321
|
+
}
|
|
313
322
|
handleConnection(ws) {
|
|
314
323
|
ws.on("message", (raw) => {
|
|
315
324
|
let msg;
|
|
@@ -337,6 +346,7 @@ export class TomorrowOS extends EventEmitter {
|
|
|
337
346
|
code,
|
|
338
347
|
deviceId
|
|
339
348
|
}));
|
|
349
|
+
this.sendBrandSnapshot(ws);
|
|
340
350
|
this.emit("device.online", { deviceId });
|
|
341
351
|
return;
|
|
342
352
|
}
|
|
@@ -359,6 +369,7 @@ export class TomorrowOS extends EventEmitter {
|
|
|
359
369
|
method: "tomorrowos.pairing.resume",
|
|
360
370
|
deviceId
|
|
361
371
|
}));
|
|
372
|
+
this.sendBrandSnapshot(ws);
|
|
362
373
|
this.emit("device.online", { deviceId });
|
|
363
374
|
})();
|
|
364
375
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tomorrowos/sdk",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"description": "TomorrowOS CMS server SDK — WebSocket transport, pairing, device commands, optional static CMS UI. Includes CLI (tomorrowos init / build) and starter templates.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="160" height="40" viewBox="0 0 160 40" role="img" aria-label="Logo placeholder">
|
|
2
|
-
<rect width="160" height="40" rx="6" fill="#FF8A3D"/>
|
|
3
|
-
<text x="80" y="26" text-anchor="middle" fill="#ffffff" font-family="system-ui,sans-serif" font-size="14" font-weight="600">Your logo</text>
|
|
4
|
-
</svg>
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="160" height="40" viewBox="0 0 160 40" role="img" aria-label="Logo placeholder">
|
|
2
|
+
<rect width="160" height="40" rx="6" fill="#FF8A3D"/>
|
|
3
|
+
<text x="80" y="26" text-anchor="middle" fill="#ffffff" font-family="system-ui,sans-serif" font-size="14" font-weight="600">Your logo</text>
|
|
4
|
+
</svg>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
|
-
"name": "my-
|
|
3
|
-
"version": "0.1.
|
|
2
|
+
"name": "my-cms",
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "CMS server on @tomorrowos/sdk. Add your UI (React, static files, etc.) alongside this server.",
|
|
5
5
|
"private": true,
|
|
6
6
|
"type": "module",
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"build-player": "tomorrowos build --platform tizen"
|
|
11
11
|
},
|
|
12
12
|
"dependencies": {
|
|
13
|
-
"@tomorrowos/sdk": "^0.1.
|
|
13
|
+
"@tomorrowos/sdk": "^0.1.3"
|
|
14
14
|
},
|
|
15
15
|
"devDependencies": {
|
|
16
16
|
"@types/node": "^20.0.0",
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8" />
|
|
5
|
+
<title>TomorrowOS SDK Smoke</title>
|
|
6
|
+
</head>
|
|
7
|
+
<body style="font-family: sans-serif; padding: 40px;">
|
|
8
|
+
<h1>TomorrowOS SDK Smoke Panel</h1>
|
|
9
|
+
<p>Same-origin API as this server — open this page after <code>npm start</code>.</p>
|
|
10
|
+
|
|
11
|
+
<h2>Pair Device</h2>
|
|
12
|
+
<input id="code" maxlength="6" placeholder="Enter 6 digit code" />
|
|
13
|
+
<button onclick="verify()">Verify</button>
|
|
14
|
+
<input type="hidden" id="deviceId" />
|
|
15
|
+
|
|
16
|
+
<h2>Get Device Info</h2>
|
|
17
|
+
<button onclick="getInfo()">Get Info</button>
|
|
18
|
+
|
|
19
|
+
<h2>Get Capabilities</h2>
|
|
20
|
+
<button onclick="getCapabilities()">Get Capabilities</button>
|
|
21
|
+
|
|
22
|
+
<h2>Reboot Device</h2>
|
|
23
|
+
<button onclick="reboot()">Reboot</button>
|
|
24
|
+
|
|
25
|
+
<h2>Set Content</h2>
|
|
26
|
+
<button onclick="setContent()">Set</button>
|
|
27
|
+
|
|
28
|
+
<h3>Set Policy JSON (required)</h3>
|
|
29
|
+
<textarea
|
|
30
|
+
id="policyJson"
|
|
31
|
+
rows="16"
|
|
32
|
+
cols="100"
|
|
33
|
+
placeholder='{
|
|
34
|
+
"policy": {
|
|
35
|
+
"playlists": [
|
|
36
|
+
{
|
|
37
|
+
"id": "default",
|
|
38
|
+
"items": [
|
|
39
|
+
{ "url": "https://example.com/a.jpg", "type": "image", "durationMs": 8000 },
|
|
40
|
+
{ "url": "https://example.com/b.mp4", "type": "video", "durationMs": 30000 }
|
|
41
|
+
]
|
|
42
|
+
}
|
|
43
|
+
],
|
|
44
|
+
"fallback": { "type": "brand" }
|
|
45
|
+
}
|
|
46
|
+
}'></textarea>
|
|
47
|
+
|
|
48
|
+
<h2>Clear Content</h2>
|
|
49
|
+
<button onclick="clearContent()">Clear</button>
|
|
50
|
+
|
|
51
|
+
<br />
|
|
52
|
+
<br />
|
|
53
|
+
|
|
54
|
+
<pre id="result"></pre>
|
|
55
|
+
|
|
56
|
+
<script src="./methods.js" defer></script>
|
|
57
|
+
</body>
|
|
58
|
+
</html>
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
async function verify() {
|
|
2
|
+
const code = document.getElementById("code").value;
|
|
3
|
+
|
|
4
|
+
const res = await fetch("/pairing/verify", {
|
|
5
|
+
method: "POST",
|
|
6
|
+
headers: { "Content-Type": "application/json" },
|
|
7
|
+
body: JSON.stringify({ code })
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
const data = await res.json();
|
|
11
|
+
|
|
12
|
+
document.getElementById("result").textContent = JSON.stringify(data, null, 2);
|
|
13
|
+
|
|
14
|
+
if (data.deviceId) {
|
|
15
|
+
document.getElementById("deviceId").value = data.deviceId;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
async function getInfo() {
|
|
20
|
+
const deviceId = document.getElementById("deviceId").value;
|
|
21
|
+
|
|
22
|
+
if (!deviceId) {
|
|
23
|
+
alert("Please pair a device first.");
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const res = await fetch("/device/" + deviceId + "/get-info", {
|
|
28
|
+
method: "POST"
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
const data = await res.json();
|
|
32
|
+
|
|
33
|
+
document.getElementById("result").textContent = JSON.stringify(data, null, 2);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
async function getCapabilities() {
|
|
37
|
+
const deviceId = document.getElementById("deviceId").value;
|
|
38
|
+
|
|
39
|
+
if (!deviceId) {
|
|
40
|
+
alert("Please pair a device first.");
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const res = await fetch(`/device/${deviceId}/get-capabilities`, {
|
|
45
|
+
method: "POST"
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
const data = await res.json();
|
|
49
|
+
document.getElementById("result").textContent = JSON.stringify(data, null, 2);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
async function reboot() {
|
|
53
|
+
const deviceId = document.getElementById("deviceId").value;
|
|
54
|
+
|
|
55
|
+
if (!deviceId) {
|
|
56
|
+
alert("Please pair a device first.");
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (!confirm("Are you sure you want to reboot this device?")) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const res = await fetch("/device/" + deviceId + "/reboot", {
|
|
65
|
+
method: "POST"
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
const data = await res.json();
|
|
69
|
+
|
|
70
|
+
document.getElementById("result").textContent = JSON.stringify(data, null, 2);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
async function setContent() {
|
|
74
|
+
const deviceId = document.getElementById("deviceId").value;
|
|
75
|
+
const policyJsonText = document.getElementById("policyJson")?.value?.trim();
|
|
76
|
+
|
|
77
|
+
if (!deviceId) {
|
|
78
|
+
alert("Please pair a device first.");
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (!policyJsonText) {
|
|
83
|
+
alert("Please enter policy JSON object.");
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
let payload = null;
|
|
88
|
+
try {
|
|
89
|
+
payload = JSON.parse(policyJsonText);
|
|
90
|
+
} catch (err) {
|
|
91
|
+
alert("Policy JSON is invalid: " + err.message);
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (!payload || typeof payload !== "object" || Array.isArray(payload)) {
|
|
96
|
+
alert("Policy payload must be a JSON object.");
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const res = await fetch(`/device/${deviceId}/content/set-policy`, {
|
|
101
|
+
method: "POST",
|
|
102
|
+
headers: { "Content-Type": "application/json" },
|
|
103
|
+
body: JSON.stringify(payload)
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
const data = await res.json();
|
|
107
|
+
document.getElementById("result").textContent = JSON.stringify(data, null, 2);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
async function clearContent() {
|
|
111
|
+
const deviceId = document.getElementById("deviceId").value;
|
|
112
|
+
|
|
113
|
+
if (!deviceId) {
|
|
114
|
+
alert("Please pair a device first.");
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const res = await fetch(`/device/${deviceId}/content/clear`, {
|
|
119
|
+
method: "POST"
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
const data = await res.json();
|
|
123
|
+
document.getElementById("result").textContent = JSON.stringify(data, null, 2);
|
|
124
|
+
}
|