@warlock.js/devtools 5.29.0 → 5.31.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/CHANGELOG.md +12 -0
- package/cjs/index.cjs +14 -14
- package/cjs/index.cjs.map +1 -1
- package/cjs/{server-6mVWfWkG.cjs → server-CQ0qhO8c.cjs} +13 -13
- package/cjs/server-CQ0qhO8c.cjs.map +1 -0
- package/esm/caller-location.mjs +1 -1
- package/esm/caller-location.mjs.map +1 -1
- package/esm/collector.mjs +1 -1
- package/esm/collector.mjs.map +1 -1
- package/esm/current-request-id.mjs +1 -1
- package/esm/current-request-id.mjs.map +1 -1
- package/esm/devtools-connector.d.mts +1 -1
- package/esm/devtools-connector.d.mts.map +1 -1
- package/esm/devtools-connector.mjs +1 -1
- package/esm/devtools-connector.mjs.map +1 -1
- package/esm/n-plus-one.mjs +1 -1
- package/esm/n-plus-one.mjs.map +1 -1
- package/esm/options.mjs +1 -1
- package/esm/options.mjs.map +1 -1
- package/esm/query-shape.mjs +1 -1
- package/esm/query-shape.mjs.map +1 -1
- package/esm/safe-value.mjs +1 -1
- package/esm/safe-value.mjs.map +1 -1
- package/esm/server/background-routes.mjs +1 -1
- package/esm/server/background-routes.mjs.map +1 -1
- package/esm/server/explain-route.mjs +1 -1
- package/esm/server/explain-route.mjs.map +1 -1
- package/esm/server/guard.mjs +1 -1
- package/esm/server/guard.mjs.map +1 -1
- package/esm/server/index.mjs +1 -1
- package/esm/server/index.mjs.map +1 -1
- package/esm/server/log-routes.mjs +1 -1
- package/esm/server/log-routes.mjs.map +1 -1
- package/esm/server/mail-routes.mjs +1 -1
- package/esm/server/mail-routes.mjs.map +1 -1
- package/esm/server/openapi-routes.mjs +1 -1
- package/esm/server/openapi-routes.mjs.map +1 -1
- package/esm/server/requests-routes.mjs +1 -1
- package/esm/server/requests-routes.mjs.map +1 -1
- package/esm/server/route-routes.mjs +1 -1
- package/esm/server/route-routes.mjs.map +1 -1
- package/esm/server/stream-route.mjs +1 -1
- package/esm/server/stream-route.mjs.map +1 -1
- package/esm/server/ui-assets.mjs +1 -1
- package/esm/server/ui-assets.mjs.map +1 -1
- package/esm/sources/cache-source.mjs +1 -1
- package/esm/sources/cache-source.mjs.map +1 -1
- package/esm/sources/log-source.mjs +1 -1
- package/esm/sources/log-source.mjs.map +1 -1
- package/esm/sources/mail-source.mjs +1 -1
- package/esm/sources/mail-source.mjs.map +1 -1
- package/esm/sources/query-source.mjs +1 -1
- package/esm/sources/query-source.mjs.map +1 -1
- package/esm/sources/tracing-source.mjs +1 -1
- package/esm/sources/tracing-source.mjs.map +1 -1
- package/esm/types.d.mts +1 -1
- package/esm/types.d.mts.map +1 -1
- package/esm/ui-root.mjs +1 -1
- package/esm/ui-root.mjs.map +1 -1
- package/llms-full.txt +22 -10
- package/package.json +7 -6
- package/skills/devtools-overview/SKILL.md +22 -10
- package/ui/app.css +1 -6
- package/cjs/server-6mVWfWkG.cjs.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"query-source.mjs","names":[],"sources":["
|
|
1
|
+
{"version":3,"file":"query-source.mjs","names":[],"sources":["../../../../../../../../packages/devtools/src/sources/query-source.ts"],"sourcesContent":["import { applyRedact, log } from \"@warlock.js/logger\";\nimport { captureCallerLocation } from \"../caller-location\";\nimport { currentRequestId } from \"../current-request-id\";\nimport { toSafeValue } from \"../safe-value\";\nimport type { DevtoolsCollector, DevtoolsDisposer } from \"../types\";\n\n/** The shape of the event `dataSourceRegistry` emits for `\"query\"`. */\ntype QueryEvent = {\n connection: string;\n driver: \"postgres\" | \"mongodb\";\n sql?: string;\n bindings?: unknown[];\n collection?: string;\n command?: string;\n pipeline?: unknown;\n durationMs: number;\n startedAt: number;\n rowCount?: number;\n error?: unknown;\n};\n\n/** Redacts query bindings through the logger's redaction rules. */\nfunction redactBindings(bindings: unknown[] | undefined): unknown[] | undefined {\n if (!bindings) return bindings;\n\n const redacted = applyRedact(\n {\n type: \"debug\",\n module: \"devtools\",\n action: \"query\",\n message: undefined,\n context: { bindings },\n },\n log.getRedact(),\n );\n\n return (redacted.context as { bindings: unknown[] }).bindings;\n}\n\n/**\n * Feeds every settled database query, from cascade's data source registry,\n * into the collector. A no-op when `@warlock.js/cascade` isn't installed —\n * it is an optional peer.\n */\nexport async function attachQuerySource(collector: DevtoolsCollector): Promise<DevtoolsDisposer> {\n let dataSourceRegistry: {\n on(event: \"query\", listener: (event: QueryEvent) => void): void;\n off(event: \"query\", listener: (event: QueryEvent) => void): void;\n };\n\n try {\n ({ dataSourceRegistry } = await import(\"@warlock.js/cascade\"));\n } catch {\n return () => {};\n }\n\n const listener = (event: QueryEvent) => {\n collector.addQuery(currentRequestId(), {\n connection: event.connection,\n driver: event.driver,\n sql: event.sql,\n bindings: toSafeValue(redactBindings(event.bindings)) as unknown[] | undefined,\n collection: event.collection,\n command: event.command,\n pipeline: event.pipeline,\n startedAt: event.startedAt,\n durationMs: event.durationMs,\n rowCount: event.rowCount,\n error:\n event.error === undefined\n ? undefined\n : event.error instanceof Error\n ? event.error.message\n : String(event.error),\n caller: captureCallerLocation(),\n });\n };\n\n dataSourceRegistry.on(\"query\", listener);\n\n return () => dataSourceRegistry.off(\"query\", listener);\n}\n"],"mappings":";;;;;;;AAsBA,SAAS,eAAe,UAAwD;CAC9E,IAAI,CAAC,UAAU,OAAO;CAatB,OAXiB,YACf;EACE,MAAM;EACN,QAAQ;EACR,QAAQ;EACR,SAAS;EACT,SAAS,EAAE,SAAS;CACtB,GACA,IAAI,UAAU,CAGD,CAAC,CAAC,QAAoC;AACvD;;;;;;AAOA,eAAsB,kBAAkB,WAAyD;CAC/F,IAAI;CAKJ,IAAI;EACF,CAAC,CAAE,sBAAuB,MAAM,OAAO;CACzC,QAAQ;EACN,aAAa,CAAC;CAChB;CAEA,MAAM,YAAY,UAAsB;EACtC,UAAU,SAAS,iBAAiB,GAAG;GACrC,YAAY,MAAM;GAClB,QAAQ,MAAM;GACd,KAAK,MAAM;GACX,UAAU,YAAY,eAAe,MAAM,QAAQ,CAAC;GACpD,YAAY,MAAM;GAClB,SAAS,MAAM;GACf,UAAU,MAAM;GAChB,WAAW,MAAM;GACjB,YAAY,MAAM;GAClB,UAAU,MAAM;GAChB,OACE,MAAM,UAAU,SACZ,SACA,MAAM,iBAAiB,QACrB,MAAM,MAAM,UACZ,OAAO,MAAM,KAAK;GAC1B,QAAQ,sBAAsB;EAChC,CAAC;CACH;CAEA,mBAAmB,GAAG,SAAS,QAAQ;CAEvC,aAAa,mBAAmB,IAAI,SAAS,QAAQ;AACvD"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { toSafeValue } from "../safe-value.mjs";
|
|
2
2
|
|
|
3
|
-
//#region
|
|
3
|
+
//#region ../../packages/devtools/src/sources/tracing-source.ts
|
|
4
4
|
/**
|
|
5
5
|
* Feeds request timelines from core's tracing hooks into the collector: one
|
|
6
6
|
* `startRequest`/`endRequest` pair per HTTP request, with every named phase
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tracing-source.mjs","names":[],"sources":["
|
|
1
|
+
{"version":3,"file":"tracing-source.mjs","names":[],"sources":["../../../../../../../../packages/devtools/src/sources/tracing-source.ts"],"sourcesContent":["import type { TracingContext, TracingPhaseInfo, TracingRequestEndInfo } from \"@warlock.js/core\";\nimport { toSafeValue } from \"../safe-value\";\nimport type { DevtoolsCollector, DevtoolsDisposer, ResolvedDevtoolsOptions } from \"../types\";\n\n/**\n * Feeds request timelines from core's tracing hooks into the collector: one\n * `startRequest`/`endRequest` pair per HTTP request, with every named phase\n * in between. Requests to the dashboard's own path are never recorded, so\n * the dashboard never watches itself.\n */\nexport async function attachTracingSource(\n collector: DevtoolsCollector,\n options: ResolvedDevtoolsOptions,\n): Promise<DevtoolsDisposer> {\n const { registerTracingHooks } = await import(\"@warlock.js/core\");\n\n const isDashboardPath = (path: string): boolean => path.startsWith(options.path);\n\n return registerTracingHooks({\n onRequestStart(ctx: TracingContext) {\n if (isDashboardPath(ctx.path)) return;\n\n collector.startRequest({\n id: ctx.requestId,\n method: ctx.method,\n path: ctx.path,\n route: ctx.route,\n startedAt: performance.timeOrigin + performance.now(),\n });\n },\n onPhase(ctx: TracingContext, phase: TracingPhaseInfo) {\n if (isDashboardPath(ctx.path)) return;\n\n collector.addPhase(ctx.requestId, {\n name: phase.name,\n durationMs: phase.durationMs,\n startedAt: phase.startedAt ?? performance.timeOrigin + performance.now() - phase.durationMs,\n attrs:\n phase.attrs === undefined\n ? undefined\n : (toSafeValue(phase.attrs) as Record<string, unknown>),\n });\n },\n onRequestEnd(ctx: TracingContext, result: TracingRequestEndInfo) {\n if (isDashboardPath(ctx.path)) return;\n\n collector.endRequest(ctx.requestId, {\n status: result.status,\n durationMs: result.durationMs,\n error:\n result.error === undefined\n ? undefined\n : result.error instanceof Error\n ? result.error.message\n : String(result.error),\n route: ctx.route,\n });\n },\n });\n}\n"],"mappings":";;;;;;;;;AAUA,eAAsB,oBACpB,WACA,SAC2B;CAC3B,MAAM,EAAE,yBAAyB,MAAM,OAAO;CAE9C,MAAM,mBAAmB,SAA0B,KAAK,WAAW,QAAQ,IAAI;CAE/E,OAAO,qBAAqB;EAC1B,eAAe,KAAqB;GAClC,IAAI,gBAAgB,IAAI,IAAI,GAAG;GAE/B,UAAU,aAAa;IACrB,IAAI,IAAI;IACR,QAAQ,IAAI;IACZ,MAAM,IAAI;IACV,OAAO,IAAI;IACX,WAAW,YAAY,aAAa,YAAY,IAAI;GACtD,CAAC;EACH;EACA,QAAQ,KAAqB,OAAyB;GACpD,IAAI,gBAAgB,IAAI,IAAI,GAAG;GAE/B,UAAU,SAAS,IAAI,WAAW;IAChC,MAAM,MAAM;IACZ,YAAY,MAAM;IAClB,WAAW,MAAM,aAAa,YAAY,aAAa,YAAY,IAAI,IAAI,MAAM;IACjF,OACE,MAAM,UAAU,SACZ,SACC,YAAY,MAAM,KAAK;GAChC,CAAC;EACH;EACA,aAAa,KAAqB,QAA+B;GAC/D,IAAI,gBAAgB,IAAI,IAAI,GAAG;GAE/B,UAAU,WAAW,IAAI,WAAW;IAClC,QAAQ,OAAO;IACf,YAAY,OAAO;IACnB,OACE,OAAO,UAAU,SACb,SACA,OAAO,iBAAiB,QACtB,OAAO,MAAM,UACb,OAAO,OAAO,KAAK;IAC3B,OAAO,IAAI;GACb,CAAC;EACH;CACF,CAAC;AACH"}
|
package/esm/types.d.mts
CHANGED
package/esm/types.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.mts","names":[],"sources":["
|
|
1
|
+
{"version":3,"file":"types.d.mts","names":[],"sources":["../../../../../../../packages/devtools/src/types.ts"],"mappings":"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"}
|
package/esm/ui-root.mjs
CHANGED
|
@@ -2,7 +2,7 @@ import { fileURLToPath } from "node:url";
|
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { existsSync, readFileSync } from "node:fs";
|
|
4
4
|
|
|
5
|
-
//#region
|
|
5
|
+
//#region ../../packages/devtools/src/ui-root.ts
|
|
6
6
|
let cachedUiRoot;
|
|
7
7
|
/** Whether `dir` is this package's root: it has `ui/index.html` beside a `package.json` named `@warlock.js/devtools`. */
|
|
8
8
|
function isPackageRoot(dir) {
|
package/esm/ui-root.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ui-root.mjs","names":[],"sources":["
|
|
1
|
+
{"version":3,"file":"ui-root.mjs","names":[],"sources":["../../../../../../../packages/devtools/src/ui-root.ts"],"sourcesContent":["import { existsSync, readFileSync } from \"node:fs\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nlet cachedUiRoot: string | undefined;\n\n/** Whether `dir` is this package's root: it has `ui/index.html` beside a `package.json` named `@warlock.js/devtools`. */\nfunction isPackageRoot(dir: string): boolean {\n const indexHtml = path.join(dir, \"ui\", \"index.html\");\n const packageJson = path.join(dir, \"package.json\");\n\n if (!existsSync(indexHtml) || !existsSync(packageJson)) {\n return false;\n }\n\n try {\n const parsed = JSON.parse(readFileSync(packageJson, \"utf8\")) as { name?: string };\n return parsed.name === \"@warlock.js/devtools\";\n } catch {\n return false;\n }\n}\n\n/**\n * Locate this package's `ui/` directory by walking up from the current\n * module's directory. Works from `src/` in development and from the built\n * `esm/`/`cjs/` output, since both sit beside `ui/` and `package.json` at\n * the package root.\n */\nexport function resolveUiRoot(): string {\n if (cachedUiRoot) {\n return cachedUiRoot;\n }\n\n let dir = path.dirname(fileURLToPath(import.meta.url));\n\n while (true) {\n if (isPackageRoot(dir)) {\n cachedUiRoot = path.join(dir, \"ui\");\n return cachedUiRoot;\n }\n\n const parent = path.dirname(dir);\n if (parent === dir) {\n throw new Error(\n \"Could not locate the devtools UI directory: no ancestor of \" +\n \"this module has a ui/index.html beside a package.json named \" +\n \"@warlock.js/devtools.\",\n );\n }\n\n dir = parent;\n }\n}\n"],"mappings":";;;;;AAIA,IAAI;;AAGJ,SAAS,cAAc,KAAsB;CAC3C,MAAM,YAAY,KAAK,KAAK,KAAK,MAAM,YAAY;CACnD,MAAM,cAAc,KAAK,KAAK,KAAK,cAAc;CAEjD,IAAI,CAAC,WAAW,SAAS,KAAK,CAAC,WAAW,WAAW,GACnD,OAAO;CAGT,IAAI;EAEF,OADe,KAAK,MAAM,aAAa,aAAa,MAAM,CAC9C,CAAC,CAAC,SAAS;CACzB,QAAQ;EACN,OAAO;CACT;AACF;;;;;;;AAQA,SAAgB,gBAAwB;CACtC,IAAI,cACF,OAAO;CAGT,IAAI,MAAM,KAAK,QAAQ,cAAc,OAAO,KAAK,GAAG,CAAC;CAErD,OAAO,MAAM;EACX,IAAI,cAAc,GAAG,GAAG;GACtB,eAAe,KAAK,KAAK,KAAK,IAAI;GAClC,OAAO;EACT;EAEA,MAAM,SAAS,KAAK,QAAQ,GAAG;EAC/B,IAAI,WAAW,KACb,MAAM,IAAI,MACR,8IAGF;EAGF,MAAM;CACR;AACF"}
|
package/llms-full.txt
CHANGED
|
@@ -44,16 +44,16 @@ of it would fail to resolve there.
|
|
|
44
44
|
|
|
45
45
|
## What each panel shows
|
|
46
46
|
|
|
47
|
-
| Panel
|
|
48
|
-
|
|
49
|
-
| **Requests** | Each request with its status, duration and query count. Click one for a waterfall: router middleware, `page.middleware`, loaders, `page.cache` hit/miss, `render.shell`, `defer.settle`, with queries and cache ops placed on the same time axis. | core `registerTracingHooks()`
|
|
50
|
-
| **Queries**
|
|
51
|
-
| **N+1**
|
|
52
|
-
| **Mail**
|
|
53
|
-
| **Logs**
|
|
54
|
-
| **Cache**
|
|
55
|
-
| **Routes**
|
|
56
|
-
| **API**
|
|
47
|
+
| Panel | What you see | Where it comes from |
|
|
48
|
+
| ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------- |
|
|
49
|
+
| **Requests** | Each request with its status, duration and query count. Click one for a waterfall: router middleware, `page.middleware`, loaders, `page.cache` hit/miss, `render.shell`, `defer.settle`, with queries and cache ops placed on the same time axis. | core `registerTracingHooks()` |
|
|
50
|
+
| **Queries** | SQL + bindings or the Mongo command, duration, rows, and an **Explain** button (Postgres `SELECT` only; runs `EXPLAIN (FORMAT JSON)`, never `ANALYZE`) | cascade `dataSourceRegistry.on("query")` |
|
|
51
|
+
| **N+1** | `⚠ N+1: 12× "select … where post_id = $1" — src/app/posts/services/list-posts.service.ts:18`, shown on the request and printed in the terminal | same query shape ≥ 5 times in one request |
|
|
52
|
+
| **Mail** | Every mail sent in development: headers, HTML (sandboxed) and text, attachment names | core `mailEvents.onCaptured()` |
|
|
53
|
+
| **Logs** | Log entries per request, filterable by level and module | a logger channel |
|
|
54
|
+
| **Cache** | hit / miss / set / removed / `invalidated` (tags, keys removed) | cache `cache.on(...)` |
|
|
55
|
+
| **Routes** | Every HTTP route with its method, path, name and middleware | core router |
|
|
56
|
+
| **API** | The app's API reference: every route with its parameters, request body, responses and auth | core `getDevelopmentOpenApiDocument()` |
|
|
57
57
|
|
|
58
58
|
Work outside a request (boot, scheduler ticks, queue jobs) goes to a separate
|
|
59
59
|
background list, so it never clutters a request's timeline.
|
|
@@ -75,6 +75,18 @@ background list, so it never clutters a request's timeline.
|
|
|
75
75
|
kept, and an N+1 threshold of 5. Everything lives in memory and is gone on
|
|
76
76
|
restart.
|
|
77
77
|
|
|
78
|
+
## From the terminal (agents)
|
|
79
|
+
|
|
80
|
+
`npx warlock trace POST /posts --body '{"title":"Hi"}' --json` sends one
|
|
81
|
+
request to the running dev server and prints this dashboard's record of it as
|
|
82
|
+
JSON — middleware, validation result, queries with N+1 flags, logs, response
|
|
83
|
+
and timings. See the `warlock-trace` skill of `@warlock.js/core`.
|
|
84
|
+
|
|
85
|
+
`npx warlock mcp` (or `npx warlock dev --mcp`) gives a coding agent the same
|
|
86
|
+
records through its `requests_recent` tool: the newest requests with their
|
|
87
|
+
phases, queries flagged `nPlusOne`, warnings, logs and timings. See the
|
|
88
|
+
`warlock-mcp` skill of `@warlock.js/core`.
|
|
89
|
+
|
|
78
90
|
## Secrets
|
|
79
91
|
|
|
80
92
|
Query bindings and log context go through the logger's redaction rules
|
package/package.json
CHANGED
|
@@ -5,10 +5,10 @@
|
|
|
5
5
|
"environment": "server"
|
|
6
6
|
},
|
|
7
7
|
"peerDependencies": {
|
|
8
|
-
"@warlock.js/cache": "5.
|
|
9
|
-
"@warlock.js/cascade": "5.
|
|
10
|
-
"@warlock.js/core": "5.
|
|
11
|
-
"@warlock.js/logger": "5.
|
|
8
|
+
"@warlock.js/cache": "5.31.0",
|
|
9
|
+
"@warlock.js/cascade": "5.31.0",
|
|
10
|
+
"@warlock.js/core": "5.31.0",
|
|
11
|
+
"@warlock.js/logger": "5.31.0"
|
|
12
12
|
},
|
|
13
13
|
"peerDependenciesMeta": {
|
|
14
14
|
"@warlock.js/cache": {
|
|
@@ -20,7 +20,8 @@
|
|
|
20
20
|
},
|
|
21
21
|
"repository": {
|
|
22
22
|
"type": "git",
|
|
23
|
-
"url": "https://github.com/warlockjs/
|
|
23
|
+
"url": "git+https://github.com/warlockjs/framework.git",
|
|
24
|
+
"directory": "packages/devtools"
|
|
24
25
|
},
|
|
25
26
|
"keywords": [
|
|
26
27
|
"warlock.js",
|
|
@@ -33,7 +34,7 @@
|
|
|
33
34
|
],
|
|
34
35
|
"author": "hassanzohdy",
|
|
35
36
|
"license": "MIT",
|
|
36
|
-
"version": "5.
|
|
37
|
+
"version": "5.31.0",
|
|
37
38
|
"main": "./cjs/index.cjs",
|
|
38
39
|
"module": "./esm/index.mjs",
|
|
39
40
|
"types": "./esm/index.d.mts",
|
|
@@ -36,16 +36,16 @@ of it would fail to resolve there.
|
|
|
36
36
|
|
|
37
37
|
## What each panel shows
|
|
38
38
|
|
|
39
|
-
| Panel
|
|
40
|
-
|
|
41
|
-
| **Requests** | Each request with its status, duration and query count. Click one for a waterfall: router middleware, `page.middleware`, loaders, `page.cache` hit/miss, `render.shell`, `defer.settle`, with queries and cache ops placed on the same time axis. | core `registerTracingHooks()`
|
|
42
|
-
| **Queries**
|
|
43
|
-
| **N+1**
|
|
44
|
-
| **Mail**
|
|
45
|
-
| **Logs**
|
|
46
|
-
| **Cache**
|
|
47
|
-
| **Routes**
|
|
48
|
-
| **API**
|
|
39
|
+
| Panel | What you see | Where it comes from |
|
|
40
|
+
| ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------- |
|
|
41
|
+
| **Requests** | Each request with its status, duration and query count. Click one for a waterfall: router middleware, `page.middleware`, loaders, `page.cache` hit/miss, `render.shell`, `defer.settle`, with queries and cache ops placed on the same time axis. | core `registerTracingHooks()` |
|
|
42
|
+
| **Queries** | SQL + bindings or the Mongo command, duration, rows, and an **Explain** button (Postgres `SELECT` only; runs `EXPLAIN (FORMAT JSON)`, never `ANALYZE`) | cascade `dataSourceRegistry.on("query")` |
|
|
43
|
+
| **N+1** | `⚠ N+1: 12× "select … where post_id = $1" — src/app/posts/services/list-posts.service.ts:18`, shown on the request and printed in the terminal | same query shape ≥ 5 times in one request |
|
|
44
|
+
| **Mail** | Every mail sent in development: headers, HTML (sandboxed) and text, attachment names | core `mailEvents.onCaptured()` |
|
|
45
|
+
| **Logs** | Log entries per request, filterable by level and module | a logger channel |
|
|
46
|
+
| **Cache** | hit / miss / set / removed / `invalidated` (tags, keys removed) | cache `cache.on(...)` |
|
|
47
|
+
| **Routes** | Every HTTP route with its method, path, name and middleware | core router |
|
|
48
|
+
| **API** | The app's API reference: every route with its parameters, request body, responses and auth | core `getDevelopmentOpenApiDocument()` |
|
|
49
49
|
|
|
50
50
|
Work outside a request (boot, scheduler ticks, queue jobs) goes to a separate
|
|
51
51
|
background list, so it never clutters a request's timeline.
|
|
@@ -67,6 +67,18 @@ background list, so it never clutters a request's timeline.
|
|
|
67
67
|
kept, and an N+1 threshold of 5. Everything lives in memory and is gone on
|
|
68
68
|
restart.
|
|
69
69
|
|
|
70
|
+
## From the terminal (agents)
|
|
71
|
+
|
|
72
|
+
`npx warlock trace POST /posts --body '{"title":"Hi"}' --json` sends one
|
|
73
|
+
request to the running dev server and prints this dashboard's record of it as
|
|
74
|
+
JSON — middleware, validation result, queries with N+1 flags, logs, response
|
|
75
|
+
and timings. See the `warlock-trace` skill of `@warlock.js/core`.
|
|
76
|
+
|
|
77
|
+
`npx warlock mcp` (or `npx warlock dev --mcp`) gives a coding agent the same
|
|
78
|
+
records through its `requests_recent` tool: the newest requests with their
|
|
79
|
+
phases, queries flagged `nPlusOne`, warnings, logs and timings. See the
|
|
80
|
+
`warlock-mcp` skill of `@warlock.js/core`.
|
|
81
|
+
|
|
70
82
|
## Secrets
|
|
71
83
|
|
|
72
84
|
Query bindings and log context go through the logger's redaction rules
|
package/ui/app.css
CHANGED
|
@@ -11,12 +11,7 @@
|
|
|
11
11
|
--bad: #b42318;
|
|
12
12
|
--code: #20242d;
|
|
13
13
|
--bar: #5b7cfa;
|
|
14
|
-
font-family:
|
|
15
|
-
system-ui,
|
|
16
|
-
-apple-system,
|
|
17
|
-
BlinkMacSystemFont,
|
|
18
|
-
"Segoe UI",
|
|
19
|
-
sans-serif;
|
|
14
|
+
font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
|
20
15
|
}
|
|
21
16
|
@media (prefers-color-scheme: dark) {
|
|
22
17
|
:root {
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"server-6mVWfWkG.cjs","names":["path","path","path"],"sources":["../../../../../../devtools/src/server/background-routes.ts","../../../../../../devtools/src/server/explain-route.ts","../../../../../../devtools/src/server/guard.ts","../../../../../../devtools/src/server/log-routes.ts","../../../../../../devtools/src/server/mail-routes.ts","../../../../../../devtools/src/ui-root.ts","../../../../../../devtools/src/server/ui-assets.ts","../../../../../../devtools/src/server/openapi-routes.ts","../../../../../../devtools/src/server/requests-routes.ts","../../../../../../devtools/src/server/route-routes.ts","../../../../../../devtools/src/server/stream-route.ts","../../../../../../devtools/src/server/index.ts"],"sourcesContent":["import type { FastifyInstance } from \"fastify\";\nimport type { MountDevtoolsRoutesDeps } from \"./types\";\n\n/** Registers the route that returns work recorded outside any request. */\nexport function registerBackgroundRoutes(\n server: FastifyInstance,\n deps: MountDevtoolsRoutesDeps,\n): void {\n server.get(\"/api/background\", async () => deps.collector.getBackground());\n}\n","import type { FastifyInstance } from \"fastify\";\nimport type { MountDevtoolsRoutesDeps } from \"./types\";\n\n/**\n * The value the logger's redaction substitutes for a censored leaf\n * (`logger/src/redact/redact.ts`, `DEFAULT_CENSOR`). Not exported from\n * `@warlock.js/logger`, so matched by literal here.\n */\nconst REDACTED_PLACEHOLDER = \"[REDACTED]\";\n\nfunction isExplainableSql(sql: string | undefined): boolean {\n return /^\\s*(select|with)\\b/i.test(sql ?? \"\");\n}\n\n/** Registers the EXPLAIN route: Postgres `SELECT`/`WITH` queries only. */\nexport function registerExplainRoute(server: FastifyInstance, deps: MountDevtoolsRoutesDeps): void {\n server.post<{ Params: { requestId: string; queryId: string } }>(\n \"/api/requests/:requestId/queries/:queryId/explain\",\n async (request, reply) => {\n const found = deps.collector.getRequest(request.params.requestId);\n const query = found?.queries.find((item) => item.id === request.params.queryId);\n\n if (!query) {\n reply.code(404).send();\n return;\n }\n\n if (query.driver !== \"postgres\" || !isExplainableSql(query.sql) || !deps.explain) {\n reply.code(400).send({ error: \"Only Postgres SELECT or WITH queries can be explained\" });\n return;\n }\n\n if (query.bindings?.some((binding) => binding === REDACTED_PLACEHOLDER)) {\n reply.code(400).send({ error: \"bindings redacted\" });\n return;\n }\n\n try {\n const plan = await deps.explain(query);\n return { plan };\n } catch (error) {\n reply.code(500).send({ error: error instanceof Error ? error.message : String(error) });\n }\n },\n );\n}\n","import type { FastifyInstance, FastifyReply, FastifyRequest } from \"fastify\";\nimport type { MountDevtoolsRoutesDeps } from \"./types\";\n\nconst LOOPBACK_ADDRESSES = new Set([\"127.0.0.1\", \"::1\", \"::ffff:127.0.0.1\"]);\n\n/**\n * Whether `address` is a loopback address. Deliberately reads\n * `request.socket.remoteAddress` rather than `request.ip`, which honours\n * `X-Forwarded-For` when the app trusts a proxy — a header any client can\n * set.\n */\nfunction isLoopbackAddress(address: string | undefined): boolean {\n return address !== undefined && LOOPBACK_ADDRESSES.has(address);\n}\n\n/**\n * Registers the dev-only, loopback-only guard as an `onRequest` hook on\n * `server`. Callers must register this inside an encapsulated Fastify\n * context (a plugin/prefix) so the hook never reaches routes outside the\n * dashboard.\n */\nexport function registerDevtoolsGuard(\n server: FastifyInstance,\n deps: MountDevtoolsRoutesDeps,\n): void {\n server.addHook(\"onRequest\", async (request: FastifyRequest, reply: FastifyReply) => {\n if (!deps.isDevelopment() || !isLoopbackAddress(request.socket.remoteAddress)) {\n // Returning the reply is what stops the lifecycle in an async hook;\n // without it Fastify still runs the handler after the 404 is sent.\n return reply.code(404).send();\n }\n });\n}\n","import type { FastifyInstance } from \"fastify\";\nimport type { DevtoolsLogEntry } from \"../types\";\nimport type { MountDevtoolsRoutesDeps } from \"./types\";\n\ntype LogsQuery = { level?: DevtoolsLogEntry[\"level\"]; module?: string };\n\n/** Registers the log listing route, filterable by `level` and `module`. */\nexport function registerLogRoutes(server: FastifyInstance, deps: MountDevtoolsRoutesDeps): void {\n server.get<{ Querystring: LogsQuery }>(\"/api/logs\", async (request) =>\n deps.collector.listLogs({ level: request.query.level, module: request.query.module }),\n );\n}\n","import type { FastifyInstance } from \"fastify\";\nimport type { MountDevtoolsRoutesDeps } from \"./types\";\n\nconst MAIL_HTML_CSP =\n \"sandbox; default-src 'none'; img-src data: https: http:; style-src 'unsafe-inline'\";\n\n/** Registers the mailbox list, single-mail detail, and mail HTML routes. */\nexport function registerMailRoutes(server: FastifyInstance, deps: MountDevtoolsRoutesDeps): void {\n server.get(\"/api/mails\", async () => deps.collector.listMails());\n\n server.get<{ Params: { id: string } }>(\"/api/mails/:id\", async (request, reply) => {\n const mail = deps.collector.getMail(request.params.id);\n\n if (!mail) {\n reply.code(404).send();\n return;\n }\n\n const { html, ...rest } = mail;\n return rest;\n });\n\n server.get<{ Params: { id: string } }>(\"/api/mails/:id/html\", async (request, reply) => {\n const mail = deps.collector.getMail(request.params.id);\n\n if (!mail || !mail.html) {\n reply.code(404).send();\n return;\n }\n\n reply\n .header(\"Content-Security-Policy\", MAIL_HTML_CSP)\n .header(\"X-Content-Type-Options\", \"nosniff\")\n .header(\"Content-Type\", \"text/html; charset=utf-8\")\n .send(mail.html);\n });\n}\n","import { existsSync, readFileSync } from \"node:fs\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nlet cachedUiRoot: string | undefined;\n\n/** Whether `dir` is this package's root: it has `ui/index.html` beside a `package.json` named `@warlock.js/devtools`. */\nfunction isPackageRoot(dir: string): boolean {\n const indexHtml = path.join(dir, \"ui\", \"index.html\");\n const packageJson = path.join(dir, \"package.json\");\n\n if (!existsSync(indexHtml) || !existsSync(packageJson)) {\n return false;\n }\n\n try {\n const parsed = JSON.parse(readFileSync(packageJson, \"utf8\")) as { name?: string };\n return parsed.name === \"@warlock.js/devtools\";\n } catch {\n return false;\n }\n}\n\n/**\n * Locate this package's `ui/` directory by walking up from the current\n * module's directory. Works from `src/` in development and from the built\n * `esm/`/`cjs/` output, since both sit beside `ui/` and `package.json` at\n * the package root.\n */\nexport function resolveUiRoot(): string {\n if (cachedUiRoot) {\n return cachedUiRoot;\n }\n\n let dir = path.dirname(fileURLToPath(import.meta.url));\n\n while (true) {\n if (isPackageRoot(dir)) {\n cachedUiRoot = path.join(dir, \"ui\");\n return cachedUiRoot;\n }\n\n const parent = path.dirname(dir);\n if (parent === dir) {\n throw new Error(\n \"Could not locate the devtools UI directory: no ancestor of \" +\n \"this module has a ui/index.html beside a package.json named \" +\n \"@warlock.js/devtools.\",\n );\n }\n\n dir = parent;\n }\n}\n","import { readFileSync } from \"node:fs\";\nimport path from \"node:path\";\nimport type { FastifyInstance, FastifyReply } from \"fastify\";\nimport { resolveUiRoot } from \"../ui-root\";\n\n/**\n * Where an asset's bytes come from: a file in this package's `ui/` folder.\n */\ntype UiAsset = {\n contentType: string;\n file: () => string;\n};\n\nconst uiFile = (name: string) => () => path.join(resolveUiRoot(), name);\n\n/**\n * The only assets that can be requested. The request's asset name is looked\n * up here and never joined into a filesystem path.\n */\nconst UI_ASSETS: Record<string, UiAsset> = {\n \"app.js\": { contentType: \"text/javascript; charset=utf-8\", file: uiFile(\"app.js\") },\n \"app.css\": { contentType: \"text/css; charset=utf-8\", file: uiFile(\"app.css\") },\n \"scalar.js\": {\n contentType: \"text/javascript; charset=utf-8\",\n file: uiFile(\"vendor/scalar/standalone.js\"),\n },\n \"swagger-ui-bundle.js\": {\n contentType: \"text/javascript; charset=utf-8\",\n file: uiFile(\"vendor/swagger-ui/swagger-ui-bundle.js\"),\n },\n \"swagger-ui.css\": {\n contentType: \"text/css; charset=utf-8\",\n file: uiFile(\"vendor/swagger-ui/swagger-ui.css\"),\n },\n \"docs-swagger.js\": {\n contentType: \"text/javascript; charset=utf-8\",\n file: uiFile(\"docs-swagger.js\"),\n },\n};\n\n/** Sends `file` with `contentType` and no caching. */\nexport function sendFile(reply: FastifyReply, file: string, contentType: string): void {\n reply\n .header(\"Cache-Control\", \"no-store\")\n .header(\"Content-Type\", contentType)\n .send(readFileSync(file));\n}\n\n/**\n * Serves the static dashboard: `index.html` at the dashboard root and the\n * whitelisted assets (`app.js`, `app.css`, the vendored Scalar bundle as\n * `scalar.js`, and the vendored Swagger UI files plus their init script). The asset name is matched against a fixed whitelist — never\n * joined into a filesystem path — so no request can traverse outside it.\n */\nexport function registerUiAssets(server: FastifyInstance): void {\n const serveIndex = (_request: unknown, reply: FastifyReply): void => {\n sendFile(reply, path.join(resolveUiRoot(), \"index.html\"), \"text/html; charset=utf-8\");\n };\n\n server.get(\"/\", serveIndex);\n\n server.get<{ Params: { name: string } }>(\"/assets/:name\", (request, reply) => {\n const asset = Object.hasOwn(UI_ASSETS, request.params.name)\n ? UI_ASSETS[request.params.name]\n : undefined;\n\n if (!asset) {\n reply.code(404).header(\"Cache-Control\", \"no-store\").send();\n return;\n }\n\n sendFile(reply, asset.file(), asset.contentType);\n });\n}\n","import path from \"node:path\";\nimport type { FastifyInstance } from \"fastify\";\nimport { resolveUiRoot } from \"../ui-root\";\nimport type { MountDevtoolsRoutesDeps } from \"./types\";\nimport { sendFile } from \"./ui-assets\";\n\n/**\n * Registers the API docs: `GET /api/openapi.json` returns the document core\n * builds from the registered routes (`deps.getOpenApiDocument`), and\n * `GET /docs` serves the page that renders it with Scalar and\n * `GET /docs/swagger` the same document in Swagger UI;\n * `GET /api/postman.json` returns the Postman collection core builds\n * (`deps.getPostmanCollection`). The pages use relative URLs, so it works under whatever base path the dashboard is\n * mounted on.\n */\nexport function registerOpenApiRoutes(\n server: FastifyInstance,\n deps: MountDevtoolsRoutesDeps,\n): void {\n server.get(\"/api/openapi.json\", async (_request, reply) => {\n if (!deps.getOpenApiDocument) {\n return reply.code(503).header(\"Cache-Control\", \"no-store\").send({\n error: \"The OpenAPI document is not available: the host did not provide a generator.\",\n });\n }\n\n reply.header(\"Cache-Control\", \"no-store\");\n\n return deps.getOpenApiDocument();\n });\n\n server.get(\"/api/postman.json\", async (_request, reply) => {\n if (!deps.getPostmanCollection) {\n return reply.code(503).header(\"Cache-Control\", \"no-store\").send({\n error: \"The Postman collection is not available: the host did not provide a generator.\",\n });\n }\n\n reply.header(\"Cache-Control\", \"no-store\");\n\n return deps.getPostmanCollection();\n });\n\n server.get(\"/docs\", (_request, reply) => {\n sendFile(reply, path.join(resolveUiRoot(), \"docs.html\"), \"text/html; charset=utf-8\");\n });\n\n server.get(\"/docs/swagger\", (_request, reply) => {\n sendFile(reply, path.join(resolveUiRoot(), \"docs-swagger.html\"), \"text/html; charset=utf-8\");\n });\n}\n","import type { FastifyInstance } from \"fastify\";\nimport type { MountDevtoolsRoutesDeps } from \"./types\";\n\n/** Registers the request list, single-request detail, and clear routes. */\nexport function registerRequestsRoutes(\n server: FastifyInstance,\n deps: MountDevtoolsRoutesDeps,\n): void {\n server.get(\"/api/requests\", async () => deps.collector.listRequests());\n\n server.get<{ Params: { id: string } }>(\"/api/requests/:id\", async (request, reply) => {\n const found = deps.collector.getRequest(request.params.id);\n\n if (!found) {\n reply.code(404).send();\n return;\n }\n\n return found;\n });\n\n server.delete(\"/api/requests\", async (_request, reply) => {\n deps.collector.clear();\n reply.code(204).send();\n });\n}\n","import type { FastifyInstance } from \"fastify\";\nimport type { MountDevtoolsRoutesDeps } from \"./types\";\n\n/** Registers the route map, sourced from core's router via `deps.listRoutes`. */\nexport function registerRouteRoutes(server: FastifyInstance, deps: MountDevtoolsRoutesDeps): void {\n server.get(\"/api/routes\", async () => (deps.listRoutes ? deps.listRoutes() : []));\n}\n","import type { FastifyInstance } from \"fastify\";\nimport type { MountDevtoolsRoutesDeps } from \"./types\";\n\nconst PING_INTERVAL_MS = 15_000;\n\n/**\n * Registers the SSE stream: one `event: <type>\\ndata: <json>\\n\\n` frame per\n * collector event, plus a `: ping` comment every 15s to keep intermediaries\n * from closing an idle connection. The reply is hijacked so Fastify never\n * tries to serialize or close the response itself.\n */\nexport function registerStreamRoute(server: FastifyInstance, deps: MountDevtoolsRoutesDeps): void {\n server.get(\"/api/stream\", async (request, reply) => {\n reply.hijack();\n const res = reply.raw;\n\n res.writeHead(200, {\n \"Content-Type\": \"text/event-stream\",\n \"Cache-Control\": \"no-store\",\n Connection: \"keep-alive\",\n });\n\n const dispose = deps.collector.subscribe((event) => {\n res.write(`event: ${event.type}\\ndata: ${JSON.stringify(event.data)}\\n\\n`);\n });\n\n const pingTimer = setInterval(() => res.write(\": ping\\n\\n\"), PING_INTERVAL_MS);\n pingTimer.unref();\n\n request.raw.on(\"close\", () => {\n clearInterval(pingTimer);\n dispose();\n });\n });\n}\n","import type { FastifyError, FastifyInstance } from \"fastify\";\nimport { registerBackgroundRoutes } from \"./background-routes\";\nimport { registerExplainRoute } from \"./explain-route\";\nimport { registerDevtoolsGuard } from \"./guard\";\nimport { registerLogRoutes } from \"./log-routes\";\nimport { registerMailRoutes } from \"./mail-routes\";\nimport { registerOpenApiRoutes } from \"./openapi-routes\";\nimport { registerRequestsRoutes } from \"./requests-routes\";\nimport { registerRouteRoutes } from \"./route-routes\";\nimport { registerStreamRoute } from \"./stream-route\";\nimport type { MountDevtoolsRoutesDeps } from \"./types\";\nimport { registerUiAssets } from \"./ui-assets\";\n\nexport type { DevtoolsRouteRow, MountDevtoolsRoutesDeps } from \"./types\";\n\n/**\n * Mounts the devtools dashboard and its API under `deps.options.path` on\n * `server`. Every route is registered inside a single encapsulated Fastify\n * context so the dev-only, loopback-only guard never reaches the app's\n * other routes.\n */\nexport function mountDevtoolsRoutes(server: FastifyInstance, deps: MountDevtoolsRoutesDeps): void {\n server.register(\n async (instance) => {\n registerDevtoolsGuard(instance, deps);\n\n instance.setErrorHandler((error: FastifyError, _request, reply) => {\n reply.code(error.statusCode ?? 500).send({ error: error.message });\n });\n\n registerUiAssets(instance);\n registerRequestsRoutes(instance, deps);\n registerBackgroundRoutes(instance, deps);\n registerMailRoutes(instance, deps);\n registerLogRoutes(instance, deps);\n registerRouteRoutes(instance, deps);\n registerOpenApiRoutes(instance, deps);\n registerExplainRoute(instance, deps);\n registerStreamRoute(instance, deps);\n },\n { prefix: deps.options.path },\n );\n}\n"],"mappings":"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"}
|