@singhak/nodeui-core 0.1.0 → 0.3.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/README.md CHANGED
@@ -2,30 +2,38 @@
2
2
 
3
3
  Framework-neutral engine for the NodeUI developer console: observability
4
4
  providers, the REST contract, the safety gate, and the static console server.
5
- The Express and NestJS adapters build on this package; you normally consume
6
- those instead of using `@singhak/nodeui-core` directly.
5
+ The Express, Fastify and NestJS adapters build on this package; you normally
6
+ consume those instead of using `@singhak/nodeui-core` directly. Use core
7
+ directly to integrate a framework without an adapter (Koa, Hono, plain `http`).
7
8
 
8
9
  ## Providers
9
10
 
10
11
  Each provider exposes one panel through `GET {path}/api/{id}`:
11
12
 
12
- | id | Panel | Notes |
13
- | --------------- | -------------- | ------------------------------------------------ |
14
- | `health` | Health | Derives status from event-loop + memory samples. |
15
- | `memory` | Memory | Samples process + OS memory on start. |
16
- | `cpu` | CPU | Process CPU percent from `/proc`-style clocks. |
17
- | `event-loop` | Event-loop lag | Drift vs. a 1ms `setInterval`, last 600 samples. |
18
- | `heap-snapshot` | Heap snapshot | Writes `nodeui-heap-<pid>-<ts>.heapsnapshot`. |
19
- | `startup` | Startup | Timing marks recorded via `server.mark(name)`. |
20
- | `requests` | Requests | Ring buffer of app HTTP requests (default 500). |
13
+ | id | Panel | Notes |
14
+ | --------------- | -------------- | ---------------------------------------------------------- |
15
+ | `health` | Health | Event-loop + memory status, plus your `healthChecks`. |
16
+ | `memory` | Memory | Samples process + OS memory on start. |
17
+ | `cpu` | CPU | Process CPU percent from `process.cpuUsage()`. |
18
+ | `event-loop` | Event-loop lag | Drift vs. a 1ms `setInterval`, last 600 samples. |
19
+ | `heap-snapshot` | Heap snapshot | Writes `nodeui-heap-<pid>-<ts>.heapsnapshot` (owner-only). |
20
+ | `startup` | Startup | Timing marks recorded via `server.mark(name)`. |
21
+ | `requests` | Requests | Ring buffer of app HTTP requests (default 500). |
22
+ | `metrics` | Metrics | Requests/errors per second for the last minute. |
23
+ | `env` | Environment | `process.env` + your `config`, masked. |
24
+ | `routes` | Routes | Express router introspection, or `server.setRoutes()`. |
25
+ | `logs` | Logs | `console.*` capture plus `server.addLogSource()`. |
26
+ | `outgoing` | Outgoing HTTP | `http`/`https`/`fetch` calls made by the app. |
27
+ | _your id_ | _your title_ | Custom panels via the `plugins` option (see below). |
21
28
 
22
29
  ## API
23
30
 
24
31
  All endpoints live under `{path}/api` and return
25
32
  `{ ok: true, data } | { ok: false, error: { code, message } }`:
26
33
 
27
- - `GET /config` — effective configuration.
28
- - `GET /{provider-id}` — panel data for the seven ids above.
34
+ - `GET /config` — effective configuration, panel list and plugin titles.
35
+ - `GET /{panel-id}` — panel data for every id above.
36
+ - `GET /live?panels=a,b` — Server-Sent Events stream (capped by `maxSseClients`).
29
37
  - `POST /confirmations` — issue a single-use nonce.
30
38
  - `POST /heap-snapshot` — capture a snapshot; must send
31
39
  `x-nodeui-confirm: <nonce>` from a fresh confirmation. A missing, expired, or
@@ -36,10 +44,18 @@ All endpoints live under `{path}/api` and return
36
44
  ## Safety
37
45
 
38
46
  - **Activation:** active when `NODE_ENV` is non-production, or when
39
- `NODEUI_ENABLED=true` forces it; fail-closed in production.
40
- - **Loopback-only:** remote hosts are rejected with `403`.
41
- - **Secret masking:** keys matching `TOKEN|KEY|SECRET|PASSWORD` have their
42
- values replaced with `[REDACTED]` in every API payload.
47
+ `NODEUI_ENABLED=true` forces it; fail-closed in production (a warning is logged if forced on).
48
+ - **Loopback-only:** remote hosts are rejected with `403`. Extra clients can be allow-listed
49
+ (`allowedRemoteAddresses`, exact IPs or IPv4 CIDRs, e.g. the Docker bridge).
50
+ - **Host / Origin validation:** blocks DNS-rebinding and cross-site requests. Extra names via
51
+ `allowedHosts` / `allowedOrigins`. `X-Forwarded-*` requests are rejected unless `trustProxy`.
52
+ - **Access token (optional):** `authToken` / `NODEUI_TOKEN`; send `Authorization: Bearer <token>`,
53
+ or open `{path}/?token=<token>` once to get an HttpOnly cookie.
54
+ - **Secret masking:** values under keys such as `token`, `key`, `secret`, `password`, `auth`,
55
+ `cookie`, `dsn`, `database_url` are replaced with `[REDACTED]`; credentials inside text
56
+ (URLs, bearer tokens, JWTs, `password=...`) are scrubbed too, in REST and SSE. Disable with
57
+ `maskSecrets: false`.
58
+ - **Headers:** CSP, `X-Content-Type-Options`, `X-Frame-Options`, `Referrer-Policy` on every response.
43
59
  - **Read-only default:** the heap snapshot is the only mutating action and is
44
60
  gated behind a fresh nonce.
45
61
  - **Zero-cost when disabled:** the middleware is a pass-through; no timers or
@@ -48,31 +64,44 @@ All endpoints live under `{path}/api` and return
48
64
  ## Configuration
49
65
 
50
66
  Environment variables are read at `createNodeUI()` time (overridable via the
51
- `options.env` map for tests):
52
-
53
- | Variable | Default | Description |
54
- | ------------------------------ | ----------- | --------------------------------- |
55
- | `NODEUI_ENABLED` | unset | Force activation (`true`). |
56
- | `NODEUI_HOST` | `127.0.0.1` | Loopback host the console trusts. |
57
- | `NODEUI_PATH` | `/nodeui` | URL prefix for console + API. |
58
- | `NODEUI_REQUEST_LOG_SIZE` | `500` | Request ring-buffer capacity. |
59
- | `NODEUI_POLL_INTERVAL_MS` | `2000` | Sampling interval. |
60
- | `NODEUI_INACTIVITY_TIMEOUT_MS` | `60000` | Provider idle timeout. |
61
- | `NODEUI_CONFIRM_TTL_MS` | `60000` | Nonce lifetime. |
62
- | `NODEUI_HEAP_SNAPSHOT_DIR` | OS tmpdir | Snapshot output directory. |
67
+ `options.env` map for tests); each also has a typed option of the same meaning.
68
+
69
+ | Variable | Default | Description |
70
+ | ------------------------------ | ------------------- | ---------------------------------------- |
71
+ | `NODEUI_ENABLED` | unset | Force activation (`true`) / disable. |
72
+ | `NODEUI_HOST` | `127.0.0.1` | Loopback host the console trusts. |
73
+ | `NODEUI_PATH` | `/nodeui` | URL prefix for console + API. |
74
+ | `NODEUI_REQUEST_LOG_SIZE` | `500` | Request ring-buffer capacity. |
75
+ | `NODEUI_LOG_SIZE` | `500` | Log ring-buffer capacity. |
76
+ | `NODEUI_POLL_INTERVAL_MS` | `2000` | Sampling interval. |
77
+ | `NODEUI_INACTIVITY_TIMEOUT_MS` | `60000` | Provider idle timeout. |
78
+ | `NODEUI_CONFIRM_TTL_MS` | `60000` | Nonce lifetime. |
79
+ | `NODEUI_HEAP_SNAPSHOT_DIR` | `<tmp>/nodeui-heap` | Snapshot output directory. |
80
+ | `NODEUI_TOKEN` | unset | Require an access token. |
81
+ | `NODEUI_ALLOWED_HOSTS` | unset | Comma-separated extra `Host` names. |
82
+ | `NODEUI_ALLOWED_ORIGINS` | unset | Comma-separated extra `Origin` values. |
83
+ | `NODEUI_ALLOWED_REMOTE` | unset | Comma-separated client IPs / IPv4 CIDRs. |
84
+ | `NODEUI_TRUST_PROXY` | `false` | Accept `X-Forwarded-*` requests. |
85
+ | `NODEUI_MAX_SSE_CLIENTS` | `10` | Concurrent live streams. |
63
86
 
64
87
  ## Usage
65
88
 
66
89
  ```ts
67
90
  import { createNodeUI, type NodeUIServer } from '@singhak/nodeui-core';
68
91
 
69
- const server: NodeUIServer = createNodeUI();
92
+ const server: NodeUIServer = createNodeUI({
93
+ plugins: [{ id: 'queues', title: 'Queues', get: async () => ({ ok: true, data: await jobs() }) }],
94
+ healthChecks: { db: () => pool.query('select 1') },
95
+ });
70
96
  const middleware = server.middleware();
71
97
  // middleware is (req, res, next) => void; mount it before your routes.
72
98
  server.mark('listening');
73
99
  server.shutdown();
74
100
  ```
75
101
 
102
+ Plugin ids are lowercase letters, digits and `-`, and must not collide with a built-in panel.
103
+ Without an Express router, feed the routes panel with `server.setRoutes([...])`.
104
+
76
105
  ## Development
77
106
 
78
107
  ```bash