mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-24 16:03:02 +00:00
feat(plugins): lifecycle polish — uninstall, error log, egress guard, widget slot (M8)
- Uninstall with data disposition: POST /api/admin/plugins/:id/uninstall kills the plugin, removes its code + DB metadata, and (deleteData) drops its data dir, error log and per-user settings. - Error log: GET/DELETE /api/admin/plugins/:id/errors — the plugin's own crash / request-failure log, surfaced in the admin panel. - Egress guard: the isolated child wraps global fetch and refuses any outbound host not in the plugin's declared egress[]; with none declared, all outbound is blocked. Process-level defense in depth (the container runtime enforces it at the network layer in v2). - Admin → Plugins is now actionable: activate / deactivate / uninstall, a registry browser (install), and per-plugin error log. i18n across all locales. - Dashboard widget slot: active widget plugins render as sandboxed cards. The trek:request core-data bridge + photo/calendar hook consumers remain follow-ups.
This commit is contained in:
@@ -85,3 +85,20 @@ describe('scaffold + validate CLIs', () => {
|
||||
expect(validatePluginDir(tmp).ok).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('reference plugin (examples/trip-countdown)', () => {
|
||||
const dir = path.resolve(import.meta.dirname, '..', 'examples', 'trip-countdown');
|
||||
|
||||
it('passes the same validation authors run', () => {
|
||||
const r = validatePluginDir(dir);
|
||||
expect(r.errors).toEqual([]);
|
||||
expect(r.ok).toBe(true);
|
||||
});
|
||||
|
||||
it('has a valid, minimal-permission manifest', () => {
|
||||
const manifest = JSON.parse(fs.readFileSync(path.join(dir, 'trek-plugin.json'), 'utf8'));
|
||||
const res = validateManifest(manifest);
|
||||
expect(res.ok).toBe(true);
|
||||
expect(res.manifest?.permissions).toEqual(['db:read:trips']);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user