smart-home-engine 1.0.10 → 1.1.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/dist/web/assets/{index-B_L247qc.css → index-DKIgEFlE.css} +1 -1
- package/dist/web/assets/index-YxGnpZAh.js +230 -0
- package/dist/web/assets/{tsMode-D1vQpxKE.js → tsMode-DAKcfE4c.js} +1 -1
- package/dist/web/index.html +16 -6
- package/package.json +1 -1
- package/src/index.js +4 -0
- package/src/lib/ca.js +474 -0
- package/src/lib/dynsec.js +295 -0
- package/src/lib/mosquitto-conf.js +287 -0
- package/src/lib/ssh-deploy.js +216 -0
- package/src/sandbox/broker-sandbox.js +113 -0
- package/src/sandbox/stdlib.js +1 -4
- package/src/web/ai-api.js +21 -11
- package/src/web/broker-api.js +761 -0
- package/src/web/config-api.js +6 -4
- package/src/web/deps-api.js +4 -5
- package/src/web/git-api.js +2 -8
- package/src/web/log-ws.js +1 -1
- package/src/web/scripts-api.js +8 -2
- package/src/web/server.js +8 -2
- package/dist/web/assets/index-DPRSyXE_.js +0 -230
package/src/web/config-api.js
CHANGED
|
@@ -30,7 +30,11 @@ router.put('/', (req, res) => {
|
|
|
30
30
|
const configPath = req.app.locals.configPath || DEFAULT_CONFIG_PATH;
|
|
31
31
|
try {
|
|
32
32
|
let oldConfig = {};
|
|
33
|
-
try {
|
|
33
|
+
try {
|
|
34
|
+
oldConfig = JSON.parse(fs.readFileSync(configPath, 'utf8'));
|
|
35
|
+
} catch {
|
|
36
|
+
/* ok — file may not exist yet */
|
|
37
|
+
}
|
|
34
38
|
|
|
35
39
|
fs.mkdirSync(path.dirname(configPath), { recursive: true });
|
|
36
40
|
fs.writeFileSync(configPath, JSON.stringify(req.body, null, 2), 'utf8');
|
|
@@ -38,9 +42,7 @@ router.put('/', (req, res) => {
|
|
|
38
42
|
// Restart is only required when a daemon-critical key changed.
|
|
39
43
|
const newConfig = req.body || {};
|
|
40
44
|
const allKeys = new Set([...Object.keys(oldConfig), ...Object.keys(newConfig)]);
|
|
41
|
-
const restartRequired = [...allKeys].some(
|
|
42
|
-
(k) => !FRONTEND_ONLY_KEYS.has(k) && JSON.stringify(oldConfig[k]) !== JSON.stringify(newConfig[k]),
|
|
43
|
-
);
|
|
45
|
+
const restartRequired = [...allKeys].some((k) => !FRONTEND_ONLY_KEYS.has(k) && JSON.stringify(oldConfig[k]) !== JSON.stringify(newConfig[k]));
|
|
44
46
|
|
|
45
47
|
res.json({ ok: true, restartRequired, configPath });
|
|
46
48
|
} catch (err) {
|
package/src/web/deps-api.js
CHANGED
|
@@ -33,7 +33,9 @@ function _checkOutdated() {
|
|
|
33
33
|
for (const [name, info] of Object.entries(data)) {
|
|
34
34
|
_outdated[name] = { current: info.current, latest: info.latest };
|
|
35
35
|
}
|
|
36
|
-
} catch {
|
|
36
|
+
} catch {
|
|
37
|
+
/* ignore parse errors */
|
|
38
|
+
}
|
|
37
39
|
resolve(_outdated ?? {});
|
|
38
40
|
});
|
|
39
41
|
});
|
|
@@ -164,10 +166,7 @@ router.get('/search', (req, res) => {
|
|
|
164
166
|
obj.package.links?.homepage ||
|
|
165
167
|
obj.package.links?.npm ||
|
|
166
168
|
`https://www.npmjs.com/package/${encodeURIComponent(obj.package.name)}`,
|
|
167
|
-
author:
|
|
168
|
-
obj.package.publisher?.username ||
|
|
169
|
-
obj.package.author?.name ||
|
|
170
|
-
(obj.package.maintainers?.[0]?.username ?? null),
|
|
169
|
+
author: obj.package.publisher?.username || obj.package.author?.name || (obj.package.maintainers?.[0]?.username ?? null),
|
|
171
170
|
date: obj.package.date ?? null,
|
|
172
171
|
}));
|
|
173
172
|
res.json(results);
|
package/src/web/git-api.js
CHANGED
|
@@ -219,10 +219,7 @@ router.get('/log', async (req, res) => {
|
|
|
219
219
|
const relToRoot = path.relative(gitRoot, abs).replace(/\\/g, '/');
|
|
220
220
|
|
|
221
221
|
try {
|
|
222
|
-
const { stdout } = await git(
|
|
223
|
-
['log', '--follow', '--format=%H%x1f%s%x1f%an%x1f%ai', `-n`, String(limit), '--', relToRoot],
|
|
224
|
-
gitRoot,
|
|
225
|
-
);
|
|
222
|
+
const { stdout } = await git(['log', '--follow', '--format=%H%x1f%s%x1f%an%x1f%ai', `-n`, String(limit), '--', relToRoot], gitRoot);
|
|
226
223
|
const commits = stdout
|
|
227
224
|
.split('\n')
|
|
228
225
|
.filter(Boolean)
|
|
@@ -242,10 +239,7 @@ router.get('/log', async (req, res) => {
|
|
|
242
239
|
*/
|
|
243
240
|
async function getHistoricPath(gitRoot, relToRoot, hash) {
|
|
244
241
|
try {
|
|
245
|
-
const { stdout } = await git(
|
|
246
|
-
['log', '--follow', '--format=COMMIT:%H', '--name-only', '--', relToRoot],
|
|
247
|
-
gitRoot,
|
|
248
|
-
);
|
|
242
|
+
const { stdout } = await git(['log', '--follow', '--format=COMMIT:%H', '--name-only', '--', relToRoot], gitRoot);
|
|
249
243
|
let currentHash = null;
|
|
250
244
|
for (const line of stdout.split('\n')) {
|
|
251
245
|
const trimmed = line.trim();
|
package/src/web/log-ws.js
CHANGED
|
@@ -46,7 +46,7 @@ function attachWss(httpServer, authCheck = () => true) {
|
|
|
46
46
|
for (const provider of _welcomeProviders) {
|
|
47
47
|
const msgs = provider();
|
|
48
48
|
if (!msgs) continue;
|
|
49
|
-
for (const msg of
|
|
49
|
+
for (const msg of Array.isArray(msgs) ? msgs : [msgs]) {
|
|
50
50
|
ws.send(JSON.stringify(msg));
|
|
51
51
|
}
|
|
52
52
|
}
|
package/src/web/scripts-api.js
CHANGED
|
@@ -38,9 +38,15 @@ async function maybeAutoCommit(req, message) {
|
|
|
38
38
|
await git(['add', scriptDirRel + '/'], gitRoot);
|
|
39
39
|
await git(['commit', '-m', message], gitRoot);
|
|
40
40
|
if (autoPush) {
|
|
41
|
-
try {
|
|
41
|
+
try {
|
|
42
|
+
await git(['push', 'origin'], gitRoot, 60000);
|
|
43
|
+
} catch {
|
|
44
|
+
/* ignore push errors */
|
|
45
|
+
}
|
|
42
46
|
}
|
|
43
|
-
} catch {
|
|
47
|
+
} catch {
|
|
48
|
+
/* nothing to commit or other transient error — ignore */
|
|
49
|
+
}
|
|
44
50
|
}
|
|
45
51
|
|
|
46
52
|
/**
|
package/src/web/server.js
CHANGED
|
@@ -13,6 +13,7 @@ const { router: mqttRouter } = require('./mqtt-api');
|
|
|
13
13
|
const { router: depsRouter } = require('./deps-api');
|
|
14
14
|
const { router: gitRouter } = require('./git-api');
|
|
15
15
|
const { router: aiRouter } = require('./ai-api');
|
|
16
|
+
const { router: brokerRouter } = require('./broker-api');
|
|
16
17
|
const { attachWss, closeWss } = require('./log-ws');
|
|
17
18
|
const { init: initAuth, authMiddleware, checkAuth, router: authRouter } = require('./auth');
|
|
18
19
|
|
|
@@ -57,6 +58,9 @@ app.use('/she/git', gitRouter);
|
|
|
57
58
|
// AI assistant proxy: /she/ai/*
|
|
58
59
|
app.use('/she/ai', aiRouter);
|
|
59
60
|
|
|
61
|
+
// Broker management: /she/broker/*
|
|
62
|
+
app.use('/she/broker', brokerRouter);
|
|
63
|
+
|
|
60
64
|
// Graceful daemon restart
|
|
61
65
|
// When running under systemd, delegate to `sudo systemctl restart` so the
|
|
62
66
|
// service actually comes back up. Otherwise fall back to exit(0) and let
|
|
@@ -80,8 +84,10 @@ async function _checkNpmVersion() {
|
|
|
80
84
|
try {
|
|
81
85
|
const res = await fetch('https://registry.npmjs.org/smart-home-engine/latest');
|
|
82
86
|
const data = await res.json();
|
|
83
|
-
_latestNpmVersion =
|
|
84
|
-
} catch {
|
|
87
|
+
_latestNpmVersion = data.version && semverCompare(pkg.version, data.version) < 0 ? data.version : null;
|
|
88
|
+
} catch {
|
|
89
|
+
/* best-effort */
|
|
90
|
+
}
|
|
85
91
|
}
|
|
86
92
|
_checkNpmVersion();
|
|
87
93
|
setInterval(_checkNpmVersion, 24 * 60 * 60 * 1000);
|