@futurewindai/wotchi 0.1.0-beta.2 → 0.1.0-beta.6
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 +178 -47
- package/SECURITY.md +2 -2
- package/dist/cjs/core/admission.js +22 -0
- package/dist/cjs/core/client.js +416 -21
- package/dist/cjs/core/config.js +193 -18
- package/dist/cjs/core/diagnostics.js +16 -1
- package/dist/cjs/core/group-store.js +22 -9
- package/dist/cjs/core/incident-builder.js +18 -0
- package/dist/cjs/core/incident-policy.js +2 -7
- package/dist/cjs/core/limits.js +17 -0
- package/dist/cjs/core/normalize.js +16 -6
- package/dist/cjs/core/notification-queue.js +92 -6
- package/dist/cjs/core/prometheus.js +129 -0
- package/dist/cjs/core/redact.js +57 -8
- package/dist/cjs/core/runtime-monitor.js +109 -0
- package/dist/cjs/index.js +8 -1
- package/dist/cjs/integrations/express/error-handler.js +21 -4
- package/dist/cjs/integrations/express/index.js +2 -1
- package/dist/cjs/integrations/express/status-observer.js +6 -0
- package/dist/cjs/integrations/nest/capture.js +21 -0
- package/dist/cjs/integrations/nest/exception-filter.js +64 -8
- package/dist/cjs/integrations/nest/filter-wrapper.js +17 -0
- package/dist/cjs/integrations/nest/index.js +7 -1
- package/dist/cjs/integrations/nest/module.js +44 -0
- package/dist/cjs/integrations/nest/register.js +15 -1
- package/dist/cjs/integrations/request-context.js +83 -1
- package/dist/cjs/notifiers/alert-payload.js +20 -0
- package/dist/cjs/notifiers/console.js +85 -15
- package/dist/cjs/notifiers/telegram-format.js +75 -5
- package/dist/cjs/notifiers/webhook-http.js +394 -0
- package/dist/cjs/notifiers/webhook.js +28 -0
- package/dist/esm/core/admission.js +19 -0
- package/dist/esm/core/client.js +416 -21
- package/dist/esm/core/config.js +193 -18
- package/dist/esm/core/diagnostics.js +16 -1
- package/dist/esm/core/group-store.js +22 -9
- package/dist/esm/core/incident-builder.js +18 -0
- package/dist/esm/core/incident-policy.js +2 -7
- package/dist/esm/core/limits.js +14 -0
- package/dist/esm/core/normalize.js +16 -6
- package/dist/esm/core/notification-queue.js +92 -6
- package/dist/esm/core/prometheus.js +125 -0
- package/dist/esm/core/redact.js +57 -8
- package/dist/esm/core/runtime-monitor.js +106 -0
- package/dist/esm/index.js +4 -1
- package/dist/esm/integrations/express/error-handler.js +21 -4
- package/dist/esm/integrations/express/index.js +1 -1
- package/dist/esm/integrations/express/status-observer.js +6 -0
- package/dist/esm/integrations/nest/capture.js +17 -0
- package/dist/esm/integrations/nest/exception-filter.js +65 -9
- package/dist/esm/integrations/nest/filter-wrapper.js +14 -0
- package/dist/esm/integrations/nest/index.js +3 -1
- package/dist/esm/integrations/nest/module.js +41 -0
- package/dist/esm/integrations/nest/register.js +15 -1
- package/dist/esm/integrations/request-context.js +83 -1
- package/dist/esm/notifiers/alert-payload.js +16 -0
- package/dist/esm/notifiers/console.js +85 -15
- package/dist/esm/notifiers/telegram-format.js +75 -5
- package/dist/esm/notifiers/webhook-http.js +387 -0
- package/dist/esm/notifiers/webhook.js +24 -0
- package/dist/types/core/admission.d.ts +10 -0
- package/dist/types/core/config.d.ts +17 -1
- package/dist/types/core/diagnostics.d.ts +7 -1
- package/dist/types/core/incident-policy.d.ts +1 -1
- package/dist/types/core/limits.d.ts +14 -0
- package/dist/types/core/notification-queue.d.ts +14 -1
- package/dist/types/core/prometheus.d.ts +7 -0
- package/dist/types/core/runtime-monitor.d.ts +15 -0
- package/dist/types/core/types.d.ts +111 -2
- package/dist/types/index.d.ts +8 -2
- package/dist/types/integrations/express/index.d.ts +2 -2
- package/dist/types/integrations/nest/capture.d.ts +4 -0
- package/dist/types/integrations/nest/exception-filter.d.ts +6 -2
- package/dist/types/integrations/nest/filter-wrapper.d.ts +7 -0
- package/dist/types/integrations/nest/index.d.ts +6 -2
- package/dist/types/integrations/nest/module.d.ts +9 -0
- package/dist/types/integrations/nest/register.d.ts +3 -0
- package/dist/types/integrations/request-context.d.ts +3 -0
- package/dist/types/notifiers/alert-payload.d.ts +5 -0
- package/dist/types/notifiers/webhook-http.d.ts +37 -0
- package/dist/types/notifiers/webhook.d.ts +4 -0
- package/dist/types-cjs/core/admission.d.cts +10 -0
- package/dist/types-cjs/core/config.d.cts +17 -1
- package/dist/types-cjs/core/diagnostics.d.cts +7 -1
- package/dist/types-cjs/core/incident-policy.d.cts +1 -1
- package/dist/types-cjs/core/limits.d.cts +14 -0
- package/dist/types-cjs/core/notification-queue.d.cts +14 -1
- package/dist/types-cjs/core/prometheus.d.cts +7 -0
- package/dist/types-cjs/core/runtime-monitor.d.cts +15 -0
- package/dist/types-cjs/core/types.d.cts +111 -2
- package/dist/types-cjs/index.d.cts +8 -2
- package/dist/types-cjs/integrations/express/index.d.cts +2 -2
- package/dist/types-cjs/integrations/nest/capture.d.cts +4 -0
- package/dist/types-cjs/integrations/nest/exception-filter.d.cts +6 -2
- package/dist/types-cjs/integrations/nest/filter-wrapper.d.cts +7 -0
- package/dist/types-cjs/integrations/nest/index.d.cts +6 -2
- package/dist/types-cjs/integrations/nest/module.d.cts +9 -0
- package/dist/types-cjs/integrations/nest/register.d.cts +3 -0
- package/dist/types-cjs/integrations/request-context.d.cts +3 -0
- package/dist/types-cjs/notifiers/alert-payload.d.cts +5 -0
- package/dist/types-cjs/notifiers/webhook-http.d.cts +37 -0
- package/dist/types-cjs/notifiers/webhook.d.cts +4 -0
- package/package.json +17 -4
package/README.md
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
# Wotchi
|
|
2
2
|
|
|
3
|
-
>
|
|
3
|
+
> Low-noise error alerts for Node.js services.
|
|
4
4
|
|
|
5
|
-
> **Status:** Public beta (`0.1.0-beta.
|
|
5
|
+
> **Status:** Public beta (`0.1.0-beta.6`). The API may evolve before the first stable release.
|
|
6
6
|
|
|
7
7
|
[](https://github.com/FutureWindAI/Wotchi/actions/workflows/ci.yml)
|
|
8
8
|
[](https://github.com/FutureWindAI/Wotchi/actions/workflows/codeql.yml)
|
|
9
9
|
[](https://www.npmjs.com/package/@futurewindai/wotchi)
|
|
10
|
-
[](LICENSE)
|
|
11
|
-
[](https://github.com/FutureWindAI/Wotchi/blob/v0.1.0-beta.6/LICENSE)
|
|
11
|
+
[](https://nodejs.org/en/about/previous-releases)
|
|
12
12
|
|
|
13
|
-
Wotchi captures application errors in-process, removes sensitive values, groups repeated failures, and delivers bounded console or
|
|
13
|
+
Wotchi captures application errors in-process, removes sensitive values, groups repeated failures, and delivers bounded console, Telegram, or HTTPS webhook alerts without changing framework response handling. It is a signal-conditioning layer, not a replacement for a full observability platform.
|
|
14
14
|
|
|
15
15
|
## Quick start
|
|
16
16
|
|
|
@@ -34,6 +34,8 @@ await wotchi.flush();
|
|
|
34
34
|
|
|
35
35
|
The example uses a threshold of one so the alert is visible immediately. The default policy groups three matching errors in one minute and suppresses duplicate alerts during the cooldown. Capture is synchronous; call `flush()` when the host needs to wait for notifier work.
|
|
36
36
|
|
|
37
|
+
To validate a notifier without deliberately throwing an application error, call `const result = await wotchi.testAlert()` in a controlled setup. The structured result reports whether the alert was queued, flushed, delivered, or rejected by a notifier; configuration errors still throw during `createWotchi`.
|
|
38
|
+
|
|
37
39
|
Example console output:
|
|
38
40
|
|
|
39
41
|
```text
|
|
@@ -54,26 +56,66 @@ notifier.
|
|
|
54
56
|
|
|
55
57
|
## What you get
|
|
56
58
|
|
|
57
|
-
| Capability | Result
|
|
58
|
-
| ----------------------------------------- |
|
|
59
|
-
| Bounded capture and queueing | Repeated failures cannot create unbounded in-memory work.
|
|
60
|
-
| Redaction before processing | Sensitive values are removed before grouping, logging, or transmission.
|
|
61
|
-
| Grouping and cooldowns | Repeated failures produce a small number of useful alerts.
|
|
62
|
-
| Express 4/5 and NestJS 10/11 adapters | Errors are observed while the framework keeps response ownership.
|
|
63
|
-
| ESM, CommonJS, and TypeScript types | Use the package with common Node.js module setups.
|
|
64
|
-
| Console and optional Telegram notifiers | Start locally or self-host delivery without a Wotchi control plane.
|
|
65
|
-
|
|
|
59
|
+
| Capability | Result |
|
|
60
|
+
| ----------------------------------------- | -------------------------------------------------------------------------------------------------------------- |
|
|
61
|
+
| Bounded capture and queueing | Repeated failures cannot create unbounded in-memory work. |
|
|
62
|
+
| Redaction before processing | Sensitive values are removed before grouping, logging, or transmission. |
|
|
63
|
+
| Grouping and cooldowns | Repeated failures produce a small number of useful alerts. |
|
|
64
|
+
| Express 4/5 and NestJS 10/11 adapters | Errors are observed while the framework keeps response ownership. |
|
|
65
|
+
| ESM, CommonJS, and TypeScript types | Use the package with common Node.js module setups. |
|
|
66
|
+
| Console and optional Telegram notifiers | Start locally or self-host delivery without a Wotchi control plane. |
|
|
67
|
+
| Generic HTTPS webhook notifier | Route bounded JSON alerts to an existing internal alert destination. |
|
|
68
|
+
| Actionable context and trace passthrough | Include route, release, request/correlation IDs, operation/job, safe tags, links, and existing trace/span IDs. |
|
|
69
|
+
| Optional status observation and JSON logs | Observe direct `401`/`403`/`429`/`5xx` responses and emit collector-friendly JSON. |
|
|
70
|
+
| Optional diagnostics exporter | Expose aggregate Wotchi health counters to an existing Prometheus-compatible `/metrics` endpoint. |
|
|
71
|
+
| Optional overload admission | Drop capture work before normalization at a measured rate and emit one sanitized overload signal. |
|
|
72
|
+
| Notifier isolation and shutdown | Bound slow destinations, open circuits after repeated failures, and drain safely during termination. |
|
|
73
|
+
| Optional runtime pressure watcher | Threshold CPU, RSS, heap, event-loop delay, or pending alerts with numeric-only local samples. |
|
|
74
|
+
|
|
75
|
+
## When to use Wotchi
|
|
76
|
+
|
|
77
|
+
Use Wotchi when an Express or NestJS service needs low-noise, privacy-conscious alerts without
|
|
78
|
+
adding a collector, database, or hosted account. Keep a full observability platform when you need
|
|
79
|
+
durable incident history, cross-replica deduplication, dashboards, traces, or paging workflows.
|
|
80
|
+
|
|
81
|
+
## Performance evidence
|
|
82
|
+
|
|
83
|
+
The package has zero direct runtime dependencies and keeps capture, grouping, and notification work
|
|
84
|
+
bounded. On a Node.js 22/macOS arm64 benchmark run of beta.6, capture p95/p99 was
|
|
85
|
+
`0.036 ms`/`0.036 ms`, duplicate-storm retained heap was `0.194 MiB`, and the packed artifact was
|
|
86
|
+
`60,534 bytes`. Prometheus rendering p95 was `0.0048 ms`. The queue benchmark admitted `101` alerts while a notifier was blocked, capped
|
|
87
|
+
pending work at `100`, and kept Express and NestJS responses completing. These are reproducible local
|
|
88
|
+
measurements, not production guarantees; repeat `npm run benchmark` and `npm run benchmark:queue`
|
|
89
|
+
on your runtime and workload. See [performance evidence](docs/PERFORMANCE.md).
|
|
90
|
+
|
|
91
|
+
The exporter does not open a server or send data. Attach it to a protected endpoint owned
|
|
92
|
+
by the host application:
|
|
93
|
+
|
|
94
|
+
```ts
|
|
95
|
+
import { createWotchiPrometheusExporter } from "@futurewindai/wotchi";
|
|
96
|
+
|
|
97
|
+
const metrics = createWotchiPrometheusExporter(wotchi);
|
|
98
|
+
app.get("/metrics", (_request, response) => {
|
|
99
|
+
response.setHeader("Content-Type", metrics.contentType);
|
|
100
|
+
response.send(metrics.render());
|
|
101
|
+
});
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Beta.6 also supports opt-in admission control, notifier timeouts/circuits, graceful shutdown, and a
|
|
105
|
+
numeric-only runtime watcher.
|
|
106
|
+
|
|
107
|
+
It emits only aggregate counters and queue/group gauges. Prometheus, Grafana, or another existing
|
|
108
|
+
collector remains responsible for scraping, authentication, retention, and dashboards.
|
|
66
109
|
|
|
67
110
|
## How it works
|
|
68
111
|
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
E --> G[Telegram]
|
|
112
|
+
```text
|
|
113
|
+
Application error
|
|
114
|
+
-> normalize and redact
|
|
115
|
+
-> stable fingerprint and optional user rule
|
|
116
|
+
-> threshold and cooldown
|
|
117
|
+
-> bounded notification queue
|
|
118
|
+
-> console, Telegram, or HTTPS webhook
|
|
77
119
|
```
|
|
78
120
|
|
|
79
121
|
The same bounded capture path can be called from HTTP handlers, background workers, and queue
|
|
@@ -99,15 +141,30 @@ const wotchi = createWotchi({
|
|
|
99
141
|
app.use(wotchiErrorHandler(wotchi));
|
|
100
142
|
```
|
|
101
143
|
|
|
102
|
-
NestJS applications register
|
|
144
|
+
NestJS applications can register Wotchi from the root module, keeping `main.ts` focused on
|
|
145
|
+
application bootstrap:
|
|
103
146
|
|
|
104
147
|
```ts
|
|
105
|
-
import {
|
|
106
|
-
|
|
107
|
-
|
|
148
|
+
import { Module } from "@nestjs/common";
|
|
149
|
+
import { consoleNotifier } from "@futurewindai/wotchi";
|
|
150
|
+
import { WotchiModule } from "@futurewindai/wotchi/nest";
|
|
151
|
+
|
|
152
|
+
@Module({
|
|
153
|
+
imports: [
|
|
154
|
+
WotchiModule.forRoot({
|
|
155
|
+
service: "orders-api",
|
|
156
|
+
environment: "production",
|
|
157
|
+
notifiers: [consoleNotifier()],
|
|
158
|
+
}),
|
|
159
|
+
],
|
|
160
|
+
})
|
|
161
|
+
export class AppModule {}
|
|
108
162
|
```
|
|
109
163
|
|
|
110
|
-
|
|
164
|
+
For a custom dependency-injected `APP_FILTER`, keep its response and logging behavior, disable the
|
|
165
|
+
automatic Wotchi filter, and wrap it with `withWotchiNestFilter`. See the [NestJS API](docs/API.md#nestjs-entry-point).
|
|
166
|
+
|
|
167
|
+
The package keeps compatibility with Node.js `>=18.18.0` and is tested across Node.js 18–26. Node.js 22 or 24 LTS is recommended for production. Express and NestJS adapters are optional subpath integrations, so applications only load the framework adapter they use.
|
|
111
168
|
|
|
112
169
|
## Telegram alerts
|
|
113
170
|
|
|
@@ -122,14 +179,88 @@ const wotchi = createWotchi({
|
|
|
122
179
|
notifiers: [
|
|
123
180
|
consoleNotifier(),
|
|
124
181
|
telegramNotifier({
|
|
125
|
-
botToken:
|
|
126
|
-
chatId:
|
|
182
|
+
botToken: requiredEnv("WOTCHI_TELEGRAM_BOT_TOKEN"),
|
|
183
|
+
chatId: requiredEnv("WOTCHI_TELEGRAM_CHAT_ID"),
|
|
184
|
+
}),
|
|
185
|
+
],
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
function requiredEnv(name: string): string {
|
|
189
|
+
const value = process.env[name];
|
|
190
|
+
if (value === undefined || value.trim() === "") {
|
|
191
|
+
throw new Error(`${name} must be configured before enabling Telegram`);
|
|
192
|
+
}
|
|
193
|
+
return value;
|
|
194
|
+
}
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
Wotchi does not ship a shared bot token. Delivery is queued outside the request path and sends only the sanitized incident alert. See [configuration](https://github.com/FutureWindAI/Wotchi/blob/main/docs/CONFIGURATION.md) for notifier and security options.
|
|
198
|
+
|
|
199
|
+
## HTTPS webhook alerts
|
|
200
|
+
|
|
201
|
+
Use the generic webhook when an existing internal alerting or automation endpoint accepts JSON. Wotchi requires HTTPS by default, bounds headers and payloads, emits a versioned `{ version: 1, type: "incident.alert", sentAt, alert }` envelope, times out delivery, and retries one `429`/`5xx` response. Explicit loopback HTTP can be enabled for a local collector with `allowHttpLoopback: true`:
|
|
202
|
+
|
|
203
|
+
```ts
|
|
204
|
+
import { createWotchi, webhookNotifier } from "@futurewindai/wotchi";
|
|
205
|
+
|
|
206
|
+
const wotchi = createWotchi({
|
|
207
|
+
service: "orders-api",
|
|
208
|
+
environment: "production",
|
|
209
|
+
notifiers: [
|
|
210
|
+
webhookNotifier({
|
|
211
|
+
url: requiredEnv("WOTCHI_WEBHOOK_URL"),
|
|
212
|
+
headers: { Authorization: requiredEnv("WOTCHI_WEBHOOK_AUTH") },
|
|
213
|
+
payloadBuilder: (alert) => ({
|
|
214
|
+
incident: alert.fingerprint,
|
|
215
|
+
summary: alert.summary,
|
|
216
|
+
}),
|
|
127
217
|
}),
|
|
128
218
|
],
|
|
129
219
|
});
|
|
220
|
+
|
|
221
|
+
function requiredEnv(name: string): string {
|
|
222
|
+
const value = process.env[name];
|
|
223
|
+
if (value === undefined || value.trim() === "") {
|
|
224
|
+
throw new Error(`${name} must be configured before enabling the webhook`);
|
|
225
|
+
}
|
|
226
|
+
return value;
|
|
227
|
+
}
|
|
130
228
|
```
|
|
131
229
|
|
|
132
|
-
|
|
230
|
+
Keep the URL and authentication header outside source control. `payloadBuilder` receives a frozen, sanitized alert and its output is redacted and bounded before transport; it is not a hosted Wotchi collector.
|
|
231
|
+
|
|
232
|
+
## Context, filtering, and existing traces
|
|
233
|
+
|
|
234
|
+
Pass safe operational context and an existing OpenTelemetry trace/span ID explicitly; Wotchi does not install an OpenTelemetry SDK:
|
|
235
|
+
|
|
236
|
+
```ts
|
|
237
|
+
wotchi.captureEvent({
|
|
238
|
+
level: "error",
|
|
239
|
+
message: "payment provider failed",
|
|
240
|
+
error,
|
|
241
|
+
request: {
|
|
242
|
+
method: "POST",
|
|
243
|
+
route: "/orders/:id",
|
|
244
|
+
requestId: "req-123",
|
|
245
|
+
correlationId: "corr-456",
|
|
246
|
+
trace: { traceId, spanId },
|
|
247
|
+
},
|
|
248
|
+
operation: "orders.pay",
|
|
249
|
+
job: "payment-retry",
|
|
250
|
+
tags: { component: "checkout" },
|
|
251
|
+
context: { provider: "stripe" },
|
|
252
|
+
});
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
Use `filter`, `fingerprint`, `beforeSend`, and bounded exact-match `rules` for service-specific noise and grouping controls. `filter` and fingerprint callbacks receive frozen, normalized, redacted events. `beforeSend` receives a frozen, sanitized `IncidentAlert`; return `null` to suppress it or a bounded alert to transform it. Hook failures are isolated and counted in diagnostics. Optional `links.log` and `links.trace` templates can use placeholders such as `{{service}}`, `{{requestId}}`, and `{{traceId}}`.
|
|
256
|
+
|
|
257
|
+
## Deployment boundaries
|
|
258
|
+
|
|
259
|
+
Wotchi keeps grouping and cooldown state in one process. Replicas have independent state, restarts
|
|
260
|
+
reset groups, and a serverless instance can terminate before asynchronous delivery completes. An
|
|
261
|
+
in-process SDK cannot reliably detect an OOM kill, frozen event loop, host failure, or unavailable
|
|
262
|
+
network. Pair it with an external uptime monitor and keep graceful shutdown explicit; see the
|
|
263
|
+
[production recipe](https://github.com/FutureWindAI/Wotchi/blob/main/examples/production-recipe/README.md).
|
|
133
264
|
|
|
134
265
|
## Process monitoring
|
|
135
266
|
|
|
@@ -147,31 +278,31 @@ const monitor = registerWotchiProcessMonitor(wotchi);
|
|
|
147
278
|
- A full observability, APM, or log-management platform.
|
|
148
279
|
- A hosted dashboard, collector, or persistent incident database.
|
|
149
280
|
- An AI-generated incident-summary service in this release.
|
|
150
|
-
- A Slack, Discord, email, or
|
|
281
|
+
- A Slack, Discord, email, or full incident-workflow platform.
|
|
151
282
|
- A Docker, Kubernetes, or Helm collector bundled into the npm SDK.
|
|
152
283
|
- An automatic-remediation system.
|
|
153
284
|
|
|
154
285
|
## Documentation
|
|
155
286
|
|
|
156
|
-
- [Getting started](docs/GETTING_STARTED.md)
|
|
157
|
-
- [Examples](docs/EXAMPLES.md)
|
|
158
|
-
- [API reference](docs/API.md)
|
|
159
|
-
- [Configuration](docs/CONFIGURATION.md)
|
|
160
|
-
- [Compatibility](docs/COMPATIBILITY.md)
|
|
161
|
-
- [Performance](docs/PERFORMANCE.md)
|
|
162
|
-
- [Architecture](docs/ARCHITECTURE.md)
|
|
163
|
-
- [Roadmap](docs/ROADMAP.md)
|
|
164
|
-
- [Troubleshooting](docs/TROUBLESHOOTING.md)
|
|
165
|
-
- [FAQ](docs/FAQ.md)
|
|
166
|
-
- [Security and privacy](docs/SECURITY.md)
|
|
167
|
-
- [Threat model](docs/THREAT_MODEL.md)
|
|
168
|
-
- [Contributing](CONTRIBUTING.md)
|
|
169
|
-
- [Changelog](CHANGELOG.md)
|
|
287
|
+
- [Getting started](https://github.com/FutureWindAI/Wotchi/blob/main/docs/GETTING_STARTED.md)
|
|
288
|
+
- [Examples](https://github.com/FutureWindAI/Wotchi/blob/main/docs/EXAMPLES.md)
|
|
289
|
+
- [API reference](https://github.com/FutureWindAI/Wotchi/blob/main/docs/API.md)
|
|
290
|
+
- [Configuration](https://github.com/FutureWindAI/Wotchi/blob/main/docs/CONFIGURATION.md)
|
|
291
|
+
- [Compatibility](https://github.com/FutureWindAI/Wotchi/blob/main/docs/COMPATIBILITY.md)
|
|
292
|
+
- [Performance](https://github.com/FutureWindAI/Wotchi/blob/main/docs/PERFORMANCE.md)
|
|
293
|
+
- [Architecture](https://github.com/FutureWindAI/Wotchi/blob/main/docs/ARCHITECTURE.md)
|
|
294
|
+
- [Roadmap](https://github.com/FutureWindAI/Wotchi/blob/main/docs/ROADMAP.md)
|
|
295
|
+
- [Troubleshooting](https://github.com/FutureWindAI/Wotchi/blob/main/docs/TROUBLESHOOTING.md)
|
|
296
|
+
- [FAQ](https://github.com/FutureWindAI/Wotchi/blob/main/docs/FAQ.md)
|
|
297
|
+
- [Security and privacy](https://github.com/FutureWindAI/Wotchi/blob/main/docs/SECURITY.md)
|
|
298
|
+
- [Threat model](https://github.com/FutureWindAI/Wotchi/blob/main/docs/THREAT_MODEL.md)
|
|
299
|
+
- [Contributing](https://github.com/FutureWindAI/Wotchi/blob/main/CONTRIBUTING.md)
|
|
300
|
+
- [Changelog](https://github.com/FutureWindAI/Wotchi/blob/main/CHANGELOG.md)
|
|
170
301
|
- [GitHub releases](https://github.com/FutureWindAI/Wotchi/releases)
|
|
171
|
-
- [Apache License 2.0](LICENSE)
|
|
302
|
+
- [Apache License 2.0](https://github.com/FutureWindAI/Wotchi/blob/main/LICENSE)
|
|
172
303
|
|
|
173
304
|
## Security
|
|
174
305
|
|
|
175
|
-
Do not include real secrets or customer error data in issues, examples, or test fixtures. Report security vulnerabilities privately using [
|
|
306
|
+
Do not include real secrets or customer error data in issues, examples, or test fixtures. Report security vulnerabilities privately using the [security policy](https://github.com/FutureWindAI/Wotchi/blob/main/SECURITY.md).
|
|
176
307
|
|
|
177
308
|
Wotchi is open source and maintained by FutureWind AI.
|
package/SECURITY.md
CHANGED
|
@@ -4,13 +4,13 @@
|
|
|
4
4
|
|
|
5
5
|
Wotchi targets applications running Node.js `>=18.18.0` and is built and tested across the Node.js 18–26 matrix. Node.js versions below 18.18 are not supported.
|
|
6
6
|
|
|
7
|
-
The current package contains the framework-independent capture core, console and
|
|
7
|
+
The current package contains the framework-independent capture core, console, Telegram, and generic HTTPS webhook notifiers, Express 4/5 middleware, NestJS 10/11 exception-filter integration, optional HTTP status observation, and opt-in process monitoring. Supported runtime and framework combinations are documented after packed-tarball compatibility and release-security checks.
|
|
8
8
|
|
|
9
9
|
## Reporting a Vulnerability
|
|
10
10
|
|
|
11
11
|
Do not disclose a suspected vulnerability, exploit detail, credential, token, or real customer error in a public issue, discussion, pull request, or example.
|
|
12
12
|
|
|
13
|
-
Use [GitHub private vulnerability reporting](https://github.com/FutureWindAI/
|
|
13
|
+
Use [GitHub private vulnerability reporting](https://github.com/FutureWindAI/Wotchi/security/advisories/new). Do not open a public issue for a suspected vulnerability.
|
|
14
14
|
|
|
15
15
|
Include only the minimum sanitized information needed to reproduce the problem. Remove application secrets, personal data, proprietary source, production URLs, and raw customer payloads.
|
|
16
16
|
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createCaptureAdmission = createCaptureAdmission;
|
|
4
|
+
/** A small token bucket used before normalization to bound overload work. */
|
|
5
|
+
function createCaptureAdmission(options) {
|
|
6
|
+
const now = options.now ?? Date.now;
|
|
7
|
+
let tokens = options.burst;
|
|
8
|
+
let lastRefill = now();
|
|
9
|
+
return {
|
|
10
|
+
tryAcquire: () => {
|
|
11
|
+
const timestamp = now();
|
|
12
|
+
const elapsedMs = Math.max(0, timestamp - lastRefill);
|
|
13
|
+
tokens = Math.min(options.burst, tokens + (elapsedMs * options.maxEventsPerSecond) / 1_000);
|
|
14
|
+
lastRefill = timestamp;
|
|
15
|
+
if (tokens < 1) {
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
tokens -= 1;
|
|
19
|
+
return true;
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
}
|