@shaferllc/keel 0.66.0 → 0.74.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/AGENTS.md +169 -0
- package/README.md +44 -6
- package/bin/keel-mcp.mjs +9 -0
- package/dist/api/api.config.stub +9 -0
- package/dist/api/config.d.ts +13 -0
- package/dist/api/config.js +14 -0
- package/dist/api/index.d.ts +16 -0
- package/dist/api/index.js +13 -0
- package/dist/api/provider.d.ts +10 -0
- package/dist/api/provider.js +17 -0
- package/dist/api/query.d.ts +35 -0
- package/dist/api/query.js +42 -0
- package/dist/api/resource.d.ts +91 -0
- package/dist/api/resource.js +188 -0
- package/dist/core/application.d.ts +5 -5
- package/dist/core/application.js +8 -2
- package/dist/core/cache.d.ts +81 -5
- package/dist/core/cache.js +188 -23
- package/dist/core/cli/stubs.d.ts +26 -0
- package/dist/core/cli/stubs.js +225 -0
- package/dist/core/console-prompt.d.ts +79 -0
- package/dist/core/console-prompt.js +239 -0
- package/dist/core/console-ui.d.ts +96 -0
- package/dist/core/console-ui.js +187 -0
- package/dist/core/console.d.ts +188 -0
- package/dist/core/console.js +395 -0
- package/dist/core/database.d.ts +70 -1
- package/dist/core/database.js +174 -15
- package/dist/core/env.d.ts +96 -0
- package/dist/core/env.js +140 -0
- package/dist/core/events.d.ts +129 -5
- package/dist/core/events.js +165 -7
- package/dist/core/health.d.ts +141 -0
- package/dist/core/health.js +226 -0
- package/dist/core/helpers.d.ts +9 -3
- package/dist/core/helpers.js +11 -3
- package/dist/core/http/kernel.d.ts +2 -0
- package/dist/core/http/kernel.js +48 -0
- package/dist/core/http/router.d.ts +5 -5
- package/dist/core/http/router.js +5 -5
- package/dist/core/i18n.d.ts +162 -0
- package/dist/core/i18n.js +472 -0
- package/dist/core/index.d.ts +39 -13
- package/dist/core/index.js +19 -6
- package/dist/core/instrumentation.d.ts +113 -0
- package/dist/core/instrumentation.js +52 -0
- package/dist/core/lock.d.ts +139 -0
- package/dist/core/lock.js +215 -0
- package/dist/core/logger.d.ts +89 -4
- package/dist/core/logger.js +167 -22
- package/dist/core/mail.d.ts +128 -7
- package/dist/core/mail.js +264 -16
- package/dist/core/notification.js +10 -1
- package/dist/core/package.d.ts +120 -0
- package/dist/core/package.js +169 -0
- package/dist/core/pages.d.ts +108 -0
- package/dist/core/pages.js +199 -0
- package/dist/core/queue.d.ts +134 -9
- package/dist/core/queue.js +325 -14
- package/dist/core/repl.d.ts +33 -0
- package/dist/core/repl.js +88 -0
- package/dist/core/scheduler.js +6 -0
- package/dist/core/social.d.ts +4 -4
- package/dist/core/social.js +4 -4
- package/dist/core/storage.d.ts +159 -6
- package/dist/core/storage.js +299 -7
- package/dist/core/telemetry.d.ts +208 -0
- package/dist/core/telemetry.js +383 -0
- package/dist/core/template.d.ts +2 -3
- package/dist/core/template.js +2 -3
- package/dist/core/testing.d.ts +170 -1
- package/dist/core/testing.js +504 -2
- package/dist/db/d1.js +13 -0
- package/dist/db/pg.d.ts +13 -0
- package/dist/db/pg.js +46 -4
- package/dist/mcp/server.d.ts +19 -0
- package/dist/mcp/server.js +355 -0
- package/dist/openapi/config.d.ts +28 -0
- package/dist/openapi/config.js +25 -0
- package/dist/openapi/doc.d.ts +40 -0
- package/dist/openapi/doc.js +20 -0
- package/dist/openapi/export.d.ts +8 -0
- package/dist/openapi/export.js +19 -0
- package/dist/openapi/gate.d.ts +15 -0
- package/dist/openapi/gate.js +27 -0
- package/dist/openapi/index.d.ts +19 -0
- package/dist/openapi/index.js +15 -0
- package/dist/openapi/openapi.config.stub +29 -0
- package/dist/openapi/provider.d.ts +18 -0
- package/dist/openapi/provider.js +35 -0
- package/dist/openapi/routes.d.ts +9 -0
- package/dist/openapi/routes.js +23 -0
- package/dist/openapi/spec.d.ts +23 -0
- package/dist/openapi/spec.js +132 -0
- package/dist/openapi/ui.d.ts +8 -0
- package/dist/openapi/ui.js +31 -0
- package/dist/openapi/zod.d.ts +12 -0
- package/dist/openapi/zod.js +46 -0
- package/dist/watch/config.d.ts +33 -0
- package/dist/watch/config.js +38 -0
- package/dist/watch/entry.d.ts +53 -0
- package/dist/watch/entry.js +105 -0
- package/dist/watch/gate.d.ts +20 -0
- package/dist/watch/gate.js +32 -0
- package/dist/watch/index.d.ts +21 -0
- package/dist/watch/index.js +17 -0
- package/dist/watch/migration.d.ts +7 -0
- package/dist/watch/migration.js +20 -0
- package/dist/watch/provider.d.ts +22 -0
- package/dist/watch/provider.js +58 -0
- package/dist/watch/prune.d.ts +11 -0
- package/dist/watch/prune.js +20 -0
- package/dist/watch/recorder.d.ts +24 -0
- package/dist/watch/recorder.js +39 -0
- package/dist/watch/routes.d.ts +13 -0
- package/dist/watch/routes.js +55 -0
- package/dist/watch/store.d.ts +54 -0
- package/dist/watch/store.js +158 -0
- package/dist/watch/ui/dist/watch.css +1 -0
- package/dist/watch/ui/dist/watch.js +555 -0
- package/dist/watch/ui-shell.d.ts +12 -0
- package/dist/watch/ui-shell.js +24 -0
- package/dist/watch/watch.config.stub +47 -0
- package/dist/watch/watchers.d.ts +12 -0
- package/dist/watch/watchers.js +156 -0
- package/docs/ai-manifest.json +3206 -0
- package/docs/ai.md +128 -0
- package/docs/api-resources.md +118 -0
- package/docs/architecture.md +331 -0
- package/docs/authentication.md +453 -0
- package/docs/authorization.md +167 -0
- package/docs/broadcasting.md +137 -0
- package/docs/broker.md +500 -0
- package/docs/cache.md +558 -0
- package/docs/configuration.md +385 -0
- package/docs/console.md +536 -0
- package/docs/container.md +467 -0
- package/docs/controllers.md +265 -0
- package/docs/cors.md +51 -0
- package/docs/database.md +631 -0
- package/docs/debugging.md +129 -0
- package/docs/decorators.md +127 -0
- package/docs/errors.md +395 -0
- package/docs/events.md +496 -0
- package/docs/examples/architecture-app.ts +27 -0
- package/docs/examples/authentication.ts +61 -0
- package/docs/examples/authorization.ts +79 -0
- package/docs/examples/broadcasting.ts +60 -0
- package/docs/examples/broker-cache-validate.ts +34 -0
- package/docs/examples/broker-fault-tolerance.ts +29 -0
- package/docs/examples/broker-middleware.ts +27 -0
- package/docs/examples/broker.ts +203 -0
- package/docs/examples/cache.ts +222 -0
- package/docs/examples/configuration.ts +121 -0
- package/docs/examples/console.ts +134 -0
- package/docs/examples/container.ts +134 -0
- package/docs/examples/controllers.ts +86 -0
- package/docs/examples/database.ts +208 -0
- package/docs/examples/debugging.ts +41 -0
- package/docs/examples/decorators.ts +40 -0
- package/docs/examples/errors.ts +121 -0
- package/docs/examples/events.ts +204 -0
- package/docs/examples/factories.ts +84 -0
- package/docs/examples/hashing.ts +71 -0
- package/docs/examples/health.ts +94 -0
- package/docs/examples/helpers.ts +171 -0
- package/docs/examples/hooks.ts +54 -0
- package/docs/examples/i18n.ts +117 -0
- package/docs/examples/inertia.ts +81 -0
- package/docs/examples/locks.ts +120 -0
- package/docs/examples/logger.ts +166 -0
- package/docs/examples/mail.ts +263 -0
- package/docs/examples/middleware.ts +119 -0
- package/docs/examples/migrations.ts +126 -0
- package/docs/examples/models.ts +239 -0
- package/docs/examples/notification.ts +124 -0
- package/docs/examples/pages.ts +82 -0
- package/docs/examples/providers.ts +123 -0
- package/docs/examples/queues.ts +254 -0
- package/docs/examples/rate-limiting.ts +42 -0
- package/docs/examples/redis.ts +99 -0
- package/docs/examples/request-response.ts +197 -0
- package/docs/examples/routing.ts +186 -0
- package/docs/examples/scheduling.ts +62 -0
- package/docs/examples/sessions.ts +102 -0
- package/docs/examples/static-files.ts +63 -0
- package/docs/examples/storage.ts +132 -0
- package/docs/examples/telemetry.ts +127 -0
- package/docs/examples/templates.ts +58 -0
- package/docs/examples/testing.ts +215 -0
- package/docs/examples/transformer.ts +141 -0
- package/docs/examples/transformers.ts +49 -0
- package/docs/examples/url-builder.ts +86 -0
- package/docs/examples/validation.ts +102 -0
- package/docs/examples/views.tsx +62 -0
- package/docs/examples/vite.ts +106 -0
- package/docs/factories.md +166 -0
- package/docs/getting-started.md +290 -0
- package/docs/hashing.md +259 -0
- package/docs/health.md +225 -0
- package/docs/helpers.md +347 -0
- package/docs/hono.md +186 -0
- package/docs/hooks.md +118 -0
- package/docs/i18n.md +302 -0
- package/docs/inertia.md +241 -0
- package/docs/locks.md +323 -0
- package/docs/logger.md +436 -0
- package/docs/mail.md +751 -0
- package/docs/middleware.md +425 -0
- package/docs/migrations.md +476 -0
- package/docs/models.md +810 -0
- package/docs/notifications.md +474 -0
- package/docs/openapi.md +111 -0
- package/docs/packages.md +118 -0
- package/docs/pages.md +217 -0
- package/docs/providers.md +363 -0
- package/docs/queues.md +679 -0
- package/docs/rate-limiting.md +155 -0
- package/docs/redis.md +178 -0
- package/docs/request-response.md +953 -0
- package/docs/routing.md +804 -0
- package/docs/scheduling.md +110 -0
- package/docs/security.md +85 -0
- package/docs/sessions.md +354 -0
- package/docs/social-auth.md +174 -0
- package/docs/static-files.md +211 -0
- package/docs/storage.md +452 -0
- package/docs/telemetry.md +263 -0
- package/docs/templates.md +314 -0
- package/docs/testing.md +376 -0
- package/docs/transformers.md +381 -0
- package/docs/url-builder.md +295 -0
- package/docs/validation.md +288 -0
- package/docs/views.md +267 -0
- package/docs/vite.md +434 -0
- package/docs/watch.md +118 -0
- package/llms-full.txt +19816 -0
- package/llms.txt +127 -0
- package/package.json +42 -7
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The watchers. Each subscribes to one instrumentation seam and turns it into a
|
|
3
|
+
* recorded entry — the whole reason the framework emits those events. None of
|
|
4
|
+
* them patch anything: they're just listeners, so installing Watch changes no
|
|
5
|
+
* behaviour, only observation.
|
|
6
|
+
*
|
|
7
|
+
* `installWatchers` wires up every enabled watcher and hands back a single
|
|
8
|
+
* teardown function (used on shutdown and in tests).
|
|
9
|
+
*/
|
|
10
|
+
import { listen, events } from "../core/helpers.js";
|
|
11
|
+
import { tapLogs } from "../core/logger.js";
|
|
12
|
+
import { familyHash, redactHeaders, sqlShape } from "./entry.js";
|
|
13
|
+
/** Events the Event watcher ignores — the instrumentation stream and things with
|
|
14
|
+
* their own dedicated watcher, so they aren't recorded twice. */
|
|
15
|
+
const OWN_EVENTS = new Set([
|
|
16
|
+
"db.query",
|
|
17
|
+
"request.handled",
|
|
18
|
+
"exception",
|
|
19
|
+
"job.processing",
|
|
20
|
+
"job.processed",
|
|
21
|
+
"job.failed",
|
|
22
|
+
"cache.hit",
|
|
23
|
+
"cache.miss",
|
|
24
|
+
"notification.sent",
|
|
25
|
+
"schedule.task.run",
|
|
26
|
+
"mail.sending",
|
|
27
|
+
"mail.sent",
|
|
28
|
+
"mail.queued",
|
|
29
|
+
]);
|
|
30
|
+
export function installWatchers(recorder, config) {
|
|
31
|
+
const off = [];
|
|
32
|
+
const dash = "/" + config.path.replace(/^\/|\/$/g, "");
|
|
33
|
+
const ignorePath = (path) => path === dash ||
|
|
34
|
+
path.startsWith(`${dash}/`) ||
|
|
35
|
+
config.ignorePaths.some((p) => path.startsWith(p));
|
|
36
|
+
/* ------------------------------- requests ------------------------------- */
|
|
37
|
+
if (recorder.enabledFor("request")) {
|
|
38
|
+
off.push(listen("request.handled", (e) => {
|
|
39
|
+
if (ignorePath(e.path))
|
|
40
|
+
return;
|
|
41
|
+
recorder.record("request", {
|
|
42
|
+
method: e.method,
|
|
43
|
+
path: e.path,
|
|
44
|
+
status: e.status,
|
|
45
|
+
durationMs: e.durationMs,
|
|
46
|
+
headers: redactHeaders(e.headers),
|
|
47
|
+
...(e.ip ? { ip: e.ip } : {}),
|
|
48
|
+
}, [
|
|
49
|
+
`status:${e.status}`,
|
|
50
|
+
`method:${e.method}`,
|
|
51
|
+
e.status >= 500 ? "failed" : e.status >= 400 ? "client-error" : "ok",
|
|
52
|
+
], { batchId: e.id, familyHash: familyHash(`${e.method} ${e.path}`) });
|
|
53
|
+
}));
|
|
54
|
+
}
|
|
55
|
+
/* -------------------------------- queries ------------------------------- */
|
|
56
|
+
if (recorder.enabledFor("query")) {
|
|
57
|
+
off.push(listen("db.query", (e) => {
|
|
58
|
+
// Never record the store's own reads/writes — that would be a loop.
|
|
59
|
+
if (e.sql.includes(config.table))
|
|
60
|
+
return;
|
|
61
|
+
const slow = e.durationMs >= config.slowQueryMs;
|
|
62
|
+
recorder.record("query", {
|
|
63
|
+
sql: e.sql,
|
|
64
|
+
bindings: e.bindings,
|
|
65
|
+
durationMs: e.durationMs,
|
|
66
|
+
connection: e.connection,
|
|
67
|
+
kind: e.kind,
|
|
68
|
+
}, [`connection:${e.connection}`, e.kind, ...(slow ? ["slow"] : [])], {
|
|
69
|
+
...(e.requestId ? { batchId: e.requestId } : {}),
|
|
70
|
+
familyHash: familyHash(sqlShape(e.sql)),
|
|
71
|
+
});
|
|
72
|
+
}));
|
|
73
|
+
}
|
|
74
|
+
/* ------------------------------ exceptions ------------------------------ */
|
|
75
|
+
if (recorder.enabledFor("exception")) {
|
|
76
|
+
off.push(listen("exception", (e) => {
|
|
77
|
+
const err = e.error;
|
|
78
|
+
const cls = err instanceof Error ? err.name : "Error";
|
|
79
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
80
|
+
recorder.record("exception", {
|
|
81
|
+
class: cls,
|
|
82
|
+
message,
|
|
83
|
+
status: e.status,
|
|
84
|
+
...(e.method ? { method: e.method } : {}),
|
|
85
|
+
...(e.path ? { path: e.path } : {}),
|
|
86
|
+
stack: err instanceof Error ? (err.stack ?? "").split("\n").map((l) => l.trim()) : [],
|
|
87
|
+
}, [`status:${e.status}`, cls], {
|
|
88
|
+
...(e.requestId ? { batchId: e.requestId } : {}),
|
|
89
|
+
familyHash: familyHash(`${cls}:${message}`),
|
|
90
|
+
});
|
|
91
|
+
}));
|
|
92
|
+
}
|
|
93
|
+
/* --------------------------------- logs --------------------------------- */
|
|
94
|
+
if (recorder.enabledFor("log")) {
|
|
95
|
+
off.push(tapLogs((record) => {
|
|
96
|
+
recorder.record("log", { level: record.level, message: record.msg, time: record.time, context: record.fields }, [`level:${record.level}`]);
|
|
97
|
+
}));
|
|
98
|
+
}
|
|
99
|
+
/* --------------------------------- mail --------------------------------- */
|
|
100
|
+
if (recorder.enabledFor("mail")) {
|
|
101
|
+
off.push(listen("mail.sent", (msg) => {
|
|
102
|
+
const m = msg ?? {};
|
|
103
|
+
recorder.record("mail", {
|
|
104
|
+
to: m.to,
|
|
105
|
+
from: m.from,
|
|
106
|
+
...(m.cc ? { cc: m.cc } : {}),
|
|
107
|
+
...(m.bcc ? { bcc: m.bcc } : {}),
|
|
108
|
+
subject: m.subject,
|
|
109
|
+
...(typeof m.text === "string" ? { text: m.text } : {}),
|
|
110
|
+
...(typeof m.html === "string" ? { html: m.html } : {}),
|
|
111
|
+
}, ["mail:sent"]);
|
|
112
|
+
}));
|
|
113
|
+
}
|
|
114
|
+
/* --------------------------------- jobs --------------------------------- */
|
|
115
|
+
if (recorder.enabledFor("job")) {
|
|
116
|
+
off.push(listen("job.processed", (e) => {
|
|
117
|
+
recorder.record("job", { job: e.job, status: "processed", ...(e.durationMs != null ? { durationMs: e.durationMs } : {}) }, ["job:processed", e.job], e.requestId ? { batchId: e.requestId } : {});
|
|
118
|
+
}));
|
|
119
|
+
off.push(listen("job.failed", (e) => {
|
|
120
|
+
recorder.record("job", { job: e.job, status: "failed", error: e.error }, ["job:failed", e.job], e.requestId ? { batchId: e.requestId } : {});
|
|
121
|
+
}));
|
|
122
|
+
}
|
|
123
|
+
/* ----------------------------- notifications ---------------------------- */
|
|
124
|
+
if (recorder.enabledFor("notification")) {
|
|
125
|
+
off.push(listen("notification.sent", (e) => {
|
|
126
|
+
recorder.record("notification", { notification: e.notification, channels: e.channels, notifiable: e.notifiable }, ["notification:sent", ...e.channels.map((c) => `channel:${c}`)], e.requestId ? { batchId: e.requestId } : {});
|
|
127
|
+
}));
|
|
128
|
+
}
|
|
129
|
+
/* -------------------------------- cache --------------------------------- */
|
|
130
|
+
if (recorder.enabledFor("cache")) {
|
|
131
|
+
const cacheEntry = (hit) => (e) => recorder.record("cache", { key: e.key, hit, store: e.store }, [hit ? "cache:hit" : "cache:miss"], e.requestId ? { batchId: e.requestId } : {});
|
|
132
|
+
off.push(listen("cache.hit", cacheEntry(true)));
|
|
133
|
+
off.push(listen("cache.miss", cacheEntry(false)));
|
|
134
|
+
}
|
|
135
|
+
/* -------------------------------- events -------------------------------- */
|
|
136
|
+
if (recorder.enabledFor("event")) {
|
|
137
|
+
off.push(events().onAny((name, payload) => {
|
|
138
|
+
if (OWN_EVENTS.has(name))
|
|
139
|
+
return;
|
|
140
|
+
recorder.record("event", { name, payload }, [`event:${name}`]);
|
|
141
|
+
}));
|
|
142
|
+
}
|
|
143
|
+
/* ------------------------------- schedule ------------------------------- */
|
|
144
|
+
if (recorder.enabledFor("schedule")) {
|
|
145
|
+
off.push(listen("schedule.task.run", (e) => {
|
|
146
|
+
recorder.record("schedule", { task: e.task, durationMs: e.durationMs }, [
|
|
147
|
+
"schedule:run",
|
|
148
|
+
e.task,
|
|
149
|
+
]);
|
|
150
|
+
}));
|
|
151
|
+
}
|
|
152
|
+
return () => {
|
|
153
|
+
for (const unsub of off)
|
|
154
|
+
unsub();
|
|
155
|
+
};
|
|
156
|
+
}
|