@kairosinternational/watchman-nextjs 0.1.2 → 0.2.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/dist/config.d.ts +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/middleware.d.ts.map +1 -1
- package/dist/middleware.js +11 -0
- package/dist/middleware.js.map +1 -1
- package/dist/route-handler.d.ts.map +1 -1
- package/dist/route-handler.js +11 -0
- package/dist/route-handler.js.map +1 -1
- package/dist/telemetry-session.d.ts +37 -0
- package/dist/telemetry-session.d.ts.map +1 -0
- package/dist/telemetry-session.js +80 -0
- package/dist/telemetry-session.js.map +1 -0
- package/dist/types.d.ts +16 -0
- package/dist/types.d.ts.map +1 -1
- package/kairosinternational-watchman-nextjs-0.1.2.tgz +0 -0
- package/package.json +2 -2
- package/src/config.ts +4 -1
- package/src/index.ts +1 -0
- package/src/middleware.ts +16 -0
- package/src/route-handler.ts +16 -0
- package/src/telemetry-session.ts +133 -0
- package/src/types.ts +18 -0
package/dist/config.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { WatchmanMiddlewareConfig } from './types.js';
|
|
2
|
-
export declare const DEFAULT_MIDDLEWARE_CONFIG: Required<Omit<WatchmanMiddlewareConfig, 'projectRoot' | 'onFinding' | 'onColdStartComplete'>>;
|
|
2
|
+
export declare const DEFAULT_MIDDLEWARE_CONFIG: Required<Omit<WatchmanMiddlewareConfig, 'projectRoot' | 'onFinding' | 'onColdStartComplete' | 'telemetry'>>;
|
|
3
3
|
export declare function resolveConfig(user?: WatchmanMiddlewareConfig): WatchmanMiddlewareConfig & typeof DEFAULT_MIDDLEWARE_CONFIG;
|
|
4
4
|
//# sourceMappingURL=config.d.ts.map
|
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAC;AAE3D,eAAO,MAAM,yBAAyB,EAAE,QAAQ,CAC9C,IAAI,
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAC;AAE3D,eAAO,MAAM,yBAAyB,EAAE,QAAQ,CAC9C,IAAI,CACF,wBAAwB,EACxB,aAAa,GAAG,WAAW,GAAG,qBAAqB,GAAG,WAAW,CAClE,CAUF,CAAC;AAEF,wBAAgB,aAAa,CAC3B,IAAI,GAAE,wBAA6B,GAClC,wBAAwB,GAAG,OAAO,yBAAyB,CAM7D"}
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":";;;AAkBA,sCAQC;AAxBY,QAAA,yBAAyB,GAKlC;IACF,OAAO,EAAE,UAAU;IACnB,MAAM,EAAE,MAAM;IACd,QAAQ,EAAE,IAAI;IACd,WAAW,EAAE,IAAI;IACjB,OAAO,EAAE,IAAI;IACb,aAAa,EAAE,IAAI;IACnB,SAAS,EAAE,CAAC,QAAQ,EAAE,cAAc,EAAE,SAAS,CAAC;IAChD,KAAK,EAAE,KAAK;CACb,CAAC;AAEF,SAAgB,aAAa,CAC3B,OAAiC,EAAE;IAEnC,OAAO;QACL,GAAG,iCAAyB;QAC5B,WAAW,EAAE,IAAI,CAAC,WAAW,IAAI,OAAO,CAAC,GAAG,EAAE;QAC9C,GAAG,IAAI;KACR,CAAC;AACJ,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { withWatchman, scanRequest, scanString } from './middleware.js';
|
|
2
2
|
export { withWatchmanRoute } from './route-handler.js';
|
|
3
3
|
export { DEFAULT_MIDDLEWARE_CONFIG, resolveConfig } from './config.js';
|
|
4
|
-
export type { WatchmanMiddlewareConfig, RequestFinding, ScanOutcome, ScanTarget, Severity, Finding, WatchmanReport, } from './types.js';
|
|
4
|
+
export type { WatchmanMiddlewareConfig, NextjsTelemetryConfig, RequestFinding, ScanOutcome, ScanTarget, Severity, Finding, WatchmanReport, } from './types.js';
|
|
5
5
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AACxE,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,yBAAyB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACvE,YAAY,EACV,wBAAwB,EACxB,cAAc,EACd,WAAW,EACX,UAAU,EACV,QAAQ,EACR,OAAO,EACP,cAAc,GACf,MAAM,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AACxE,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,yBAAyB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACvE,YAAY,EACV,wBAAwB,EACxB,qBAAqB,EACrB,cAAc,EACd,WAAW,EACX,UAAU,EACV,QAAQ,EACR,OAAO,EACP,cAAc,GACf,MAAM,YAAY,CAAC"}
|
package/dist/middleware.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../src/middleware.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,WAAW,EAAE,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;AAOlF,OAAO,EAAiB,yBAAyB,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../src/middleware.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,WAAW,EAAE,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;AAOlF,OAAO,EAAiB,yBAAyB,EAAE,MAAM,aAAa,CAAC;AAEvE,OAAO,KAAK,EACV,wBAAwB,EACxB,cAAc,EACd,WAAW,EACX,UAAU,EACX,MAAM,YAAY,CAAC;AAkCpB;;;GAGG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,cAAc,EAAE,CAiC9E;AAED;;;GAGG;AACH,wBAAsB,WAAW,CAC/B,OAAO,EAAE,WAAW,EACpB,MAAM,EAAE,wBAAwB,GAAG,OAAO,yBAAyB,GAClE,OAAO,CAAC,WAAW,CAAC,CAsCtB;AA8DD;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAC1B,UAAU,GAAE,wBAA6B,GACxC,cAAc,CA+EhB"}
|
package/dist/middleware.js
CHANGED
|
@@ -6,6 +6,7 @@ exports.withWatchman = withWatchman;
|
|
|
6
6
|
const server_1 = require("next/server");
|
|
7
7
|
const patterns_1 = require("@kairosinternational/watchman/patterns");
|
|
8
8
|
const config_js_1 = require("./config.js");
|
|
9
|
+
const telemetry_session_js_1 = require("./telemetry-session.js");
|
|
9
10
|
function randomId() {
|
|
10
11
|
// Use Web Crypto API (Edge-compatible) with Node.js fallback
|
|
11
12
|
if (typeof globalThis.crypto?.randomUUID === 'function') {
|
|
@@ -177,6 +178,16 @@ function withWatchman(userConfig = {}) {
|
|
|
177
178
|
await config.onFinding(finding);
|
|
178
179
|
}
|
|
179
180
|
}
|
|
181
|
+
for (const finding of outcome.findings) {
|
|
182
|
+
(0, telemetry_session_js_1.reportFindingIfConfigured)({
|
|
183
|
+
rule: finding.rule,
|
|
184
|
+
severity: finding.severity,
|
|
185
|
+
target: finding.target,
|
|
186
|
+
label: finding.label,
|
|
187
|
+
message: finding.message,
|
|
188
|
+
evidence: finding.evidence,
|
|
189
|
+
}, config.telemetry, config.quiet);
|
|
190
|
+
}
|
|
180
191
|
if (outcome.shouldBlock) {
|
|
181
192
|
if (!config.quiet) {
|
|
182
193
|
console.warn(`[watchman] BLOCKED ${request.method} ${pathname} -- ${outcome.maxSeverity}: ${outcome.findings.length} findings`);
|
package/dist/middleware.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"middleware.js","sourceRoot":"","sources":["../src/middleware.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"middleware.js","sourceRoot":"","sources":["../src/middleware.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"route-handler.d.ts","sourceRoot":"","sources":["../src/route-handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"route-handler.d.ts","sourceRoot":"","sources":["../src/route-handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAK/C,OAAO,KAAK,EACV,wBAAwB,EAIzB,MAAM,YAAY,CAAC;AAEpB,KAAK,YAAY,GAAG,CAClB,OAAO,EAAE,WAAW,EACpB,OAAO,CAAC,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,CAAA;CAAE,KACpD,OAAO,CAAC,QAAQ,CAAC,GAAG,QAAQ,CAAC;AA+DlC;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,SAAS,YAAY,EACtD,OAAO,EAAE,CAAC,EACV,UAAU,GAAE,wBAA6B,GACxC,CAAC,CAkEH"}
|
package/dist/route-handler.js
CHANGED
|
@@ -4,6 +4,7 @@ exports.withWatchmanRoute = withWatchmanRoute;
|
|
|
4
4
|
const server_1 = require("next/server");
|
|
5
5
|
const config_js_1 = require("./config.js");
|
|
6
6
|
const middleware_js_1 = require("./middleware.js");
|
|
7
|
+
const telemetry_session_js_1 = require("./telemetry-session.js");
|
|
7
8
|
const SEVERITY_ORDER = {
|
|
8
9
|
critical: 4,
|
|
9
10
|
high: 3,
|
|
@@ -72,6 +73,16 @@ function withWatchmanRoute(handler, userConfig = {}) {
|
|
|
72
73
|
await config.onFinding(finding);
|
|
73
74
|
}
|
|
74
75
|
}
|
|
76
|
+
for (const finding of outcome.findings) {
|
|
77
|
+
(0, telemetry_session_js_1.reportFindingIfConfigured)({
|
|
78
|
+
rule: finding.rule,
|
|
79
|
+
severity: finding.severity,
|
|
80
|
+
target: finding.target,
|
|
81
|
+
label: finding.label,
|
|
82
|
+
message: finding.message,
|
|
83
|
+
evidence: finding.evidence,
|
|
84
|
+
}, config.telemetry, config.quiet);
|
|
85
|
+
}
|
|
75
86
|
if (outcome.shouldBlock) {
|
|
76
87
|
if (!config.quiet) {
|
|
77
88
|
console.warn(`[watchman] BLOCKED route handler ${request.method} ${new URL(request.url).pathname} -- ${outcome.maxSeverity}`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"route-handler.js","sourceRoot":"","sources":["../src/route-handler.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"route-handler.js","sourceRoot":"","sources":["../src/route-handler.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { type TelemetryReporter } from '@kairosinternational/watchman/telemetry';
|
|
2
|
+
import type { NextjsTelemetryConfig } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Memoized per-process telemetry session. A Next.js process (or Vercel
|
|
5
|
+
* Function instance) calls startSession once on first use, then reuses
|
|
6
|
+
* the same sessionId for every request scanned by this instance.
|
|
7
|
+
*
|
|
8
|
+
* Sessions are never explicitly ended from Next.js — Fluid Compute
|
|
9
|
+
* recycles instances without a clean shutdown. A server-side reaper
|
|
10
|
+
* marks stale sessions as completed.
|
|
11
|
+
*/
|
|
12
|
+
interface RuntimeState {
|
|
13
|
+
reporter: TelemetryReporter;
|
|
14
|
+
sessionIdPromise: Promise<string | null>;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Get or initialize the session. Safe to call on every request —
|
|
18
|
+
* the startSession RPC runs at most once per process.
|
|
19
|
+
*/
|
|
20
|
+
export declare function ensureSession(config?: NextjsTelemetryConfig, quiet?: boolean): RuntimeState | null;
|
|
21
|
+
/**
|
|
22
|
+
* Fire-and-forget finding report. Resolves the memoized session ID
|
|
23
|
+
* first; if session-open failed, findings are silently dropped.
|
|
24
|
+
*/
|
|
25
|
+
export declare function reportFindingIfConfigured(finding: {
|
|
26
|
+
scanner?: string;
|
|
27
|
+
rule: string;
|
|
28
|
+
severity: import('@kairosinternational/watchman/telemetry').TelemetryFinding['severity'];
|
|
29
|
+
target?: string;
|
|
30
|
+
label?: string;
|
|
31
|
+
message: string;
|
|
32
|
+
evidence?: string;
|
|
33
|
+
}, config?: NextjsTelemetryConfig, quiet?: boolean): void;
|
|
34
|
+
/** Test-only helper — resets module state between tests. */
|
|
35
|
+
export declare function __resetSessionState(): void;
|
|
36
|
+
export {};
|
|
37
|
+
//# sourceMappingURL=telemetry-session.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"telemetry-session.d.ts","sourceRoot":"","sources":["../src/telemetry-session.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,iBAAiB,EACvB,MAAM,yCAAyC,CAAC;AACjD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAExD;;;;;;;;GAQG;AAEH,UAAU,YAAY;IACpB,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,gBAAgB,EAAE,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CAC1C;AAuCD;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,MAAM,CAAC,EAAE,qBAAqB,EAC9B,KAAK,UAAQ,GACZ,YAAY,GAAG,IAAI,CAwBrB;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CACvC,OAAO,EAAE;IACP,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,yCAAyC,EAAE,gBAAgB,CAAC,UAAU,CAAC,CAAC;IACzF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,EACD,MAAM,CAAC,EAAE,qBAAqB,EAC9B,KAAK,UAAQ,GACZ,IAAI,CAmBN;AAED,4DAA4D;AAC5D,wBAAgB,mBAAmB,IAAI,IAAI,CAG1C"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ensureSession = ensureSession;
|
|
4
|
+
exports.reportFindingIfConfigured = reportFindingIfConfigured;
|
|
5
|
+
exports.__resetSessionState = __resetSessionState;
|
|
6
|
+
const telemetry_1 = require("@kairosinternational/watchman/telemetry");
|
|
7
|
+
let state = null;
|
|
8
|
+
let skippedLogged = false;
|
|
9
|
+
function resolveTelemetryConfig(config) {
|
|
10
|
+
const apiKey = config?.apiKey ?? process.env['WATCHMAN_API_KEY'];
|
|
11
|
+
const endpoint = config?.endpoint ?? process.env['WATCHMAN_ENDPOINT'];
|
|
12
|
+
if (!apiKey || !endpoint)
|
|
13
|
+
return null;
|
|
14
|
+
const projectSlug = config?.projectSlug ??
|
|
15
|
+
process.env['WATCHMAN_PROJECT_SLUG'] ??
|
|
16
|
+
process.env['VERCEL_GIT_REPO_SLUG'] ??
|
|
17
|
+
'nextjs-app';
|
|
18
|
+
return { apiKey, endpoint, projectSlug };
|
|
19
|
+
}
|
|
20
|
+
function detectEnv(config) {
|
|
21
|
+
return {
|
|
22
|
+
commitSha: config?.commitSha ?? process.env['VERCEL_GIT_COMMIT_SHA'] ?? undefined,
|
|
23
|
+
branch: config?.branch ?? process.env['VERCEL_GIT_COMMIT_REF'] ?? undefined,
|
|
24
|
+
environment: config?.environment ??
|
|
25
|
+
process.env['WATCHMAN_ENVIRONMENT'] ??
|
|
26
|
+
process.env['VERCEL_ENV'] ??
|
|
27
|
+
'nextjs-middleware',
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Get or initialize the session. Safe to call on every request —
|
|
32
|
+
* the startSession RPC runs at most once per process.
|
|
33
|
+
*/
|
|
34
|
+
function ensureSession(config, quiet = false) {
|
|
35
|
+
if (state)
|
|
36
|
+
return state;
|
|
37
|
+
const resolved = resolveTelemetryConfig(config);
|
|
38
|
+
if (!resolved) {
|
|
39
|
+
if (!quiet && !skippedLogged) {
|
|
40
|
+
console.info('[watchman] telemetry disabled (no apiKey/endpoint)');
|
|
41
|
+
skippedLogged = true;
|
|
42
|
+
}
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
const reporter = (0, telemetry_1.createTelemetryReporter)({
|
|
46
|
+
apiKey: resolved.apiKey,
|
|
47
|
+
endpoint: resolved.endpoint,
|
|
48
|
+
});
|
|
49
|
+
const sessionIdPromise = reporter.startSession(resolved.projectSlug, detectEnv(config));
|
|
50
|
+
state = { reporter, sessionIdPromise };
|
|
51
|
+
return state;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Fire-and-forget finding report. Resolves the memoized session ID
|
|
55
|
+
* first; if session-open failed, findings are silently dropped.
|
|
56
|
+
*/
|
|
57
|
+
function reportFindingIfConfigured(finding, config, quiet = false) {
|
|
58
|
+
const runtime = ensureSession(config, quiet);
|
|
59
|
+
if (!runtime)
|
|
60
|
+
return;
|
|
61
|
+
void runtime.sessionIdPromise.then((sessionId) => {
|
|
62
|
+
if (!sessionId)
|
|
63
|
+
return;
|
|
64
|
+
runtime.reporter.reportFinding({
|
|
65
|
+
scanner: finding.scanner ?? 'nextjs-middleware',
|
|
66
|
+
rule: finding.rule,
|
|
67
|
+
severity: finding.severity,
|
|
68
|
+
target: finding.target,
|
|
69
|
+
label: finding.label,
|
|
70
|
+
message: finding.message,
|
|
71
|
+
evidence: finding.evidence,
|
|
72
|
+
}, sessionId);
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
/** Test-only helper — resets module state between tests. */
|
|
76
|
+
function __resetSessionState() {
|
|
77
|
+
state = null;
|
|
78
|
+
skippedLogged = false;
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=telemetry-session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"telemetry-session.js","sourceRoot":"","sources":["../src/telemetry-session.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -9,9 +9,25 @@ export interface RequestFinding {
|
|
|
9
9
|
message: string;
|
|
10
10
|
evidence: string;
|
|
11
11
|
}
|
|
12
|
+
export interface NextjsTelemetryConfig {
|
|
13
|
+
/** Watchman API key (raw). Falls back to WATCHMAN_API_KEY env. */
|
|
14
|
+
apiKey?: string;
|
|
15
|
+
/** Watchman endpoint, e.g. "https://watchman.guide". Falls back to WATCHMAN_ENDPOINT env. */
|
|
16
|
+
endpoint?: string;
|
|
17
|
+
/** Project slug. Falls back to WATCHMAN_PROJECT_SLUG, then VERCEL_GIT_REPO_SLUG. */
|
|
18
|
+
projectSlug?: string;
|
|
19
|
+
/** Commit SHA. Falls back to VERCEL_GIT_COMMIT_SHA. */
|
|
20
|
+
commitSha?: string;
|
|
21
|
+
/** Branch. Falls back to VERCEL_GIT_COMMIT_REF. */
|
|
22
|
+
branch?: string;
|
|
23
|
+
/** Environment label. Falls back to WATCHMAN_ENVIRONMENT, then VERCEL_ENV. */
|
|
24
|
+
environment?: string;
|
|
25
|
+
}
|
|
12
26
|
export interface WatchmanMiddlewareConfig {
|
|
13
27
|
/** Project root for cold-start file scanning. Defaults to process.cwd() */
|
|
14
28
|
projectRoot?: string;
|
|
29
|
+
/** Optional telemetry — stream findings to a Watchman server. */
|
|
30
|
+
telemetry?: NextjsTelemetryConfig;
|
|
15
31
|
/** Severity at or above which to block the request. Default: 'critical' */
|
|
16
32
|
blockAt?: Severity;
|
|
17
33
|
/** Severity at or above which to attach a warning header. Default: 'high' */
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,+BAA+B,CAAC;AAEvF,MAAM,MAAM,UAAU,GAAG,KAAK,GAAG,SAAS,GAAG,MAAM,GAAG,UAAU,CAAC;AAEjE,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,UAAU,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,QAAQ,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,wBAAwB;IACvC,2EAA2E;IAC3E,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,2EAA2E;IAC3E,OAAO,CAAC,EAAE,QAAQ,CAAC;IAEnB,6EAA6E;IAC7E,MAAM,CAAC,EAAE,QAAQ,CAAC;IAElB,iEAAiE;IACjE,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB,0CAA0C;IAC1C,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB,uDAAuD;IACvD,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB,0FAA0F;IAC1F,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB,kEAAkE;IAClE,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IAErB,oDAAoD;IACpD,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE9D,iDAAiD;IACjD,mBAAmB,CAAC,EAAE,CAAC,MAAM,EAAE,cAAc,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvE,6DAA6D;IAC7D,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,cAAc,EAAE,CAAC;IAC3B,WAAW,EAAE,QAAQ,GAAG,IAAI,CAAC;IAC7B,WAAW,EAAE,OAAO,CAAC;IACrB,UAAU,EAAE,OAAO,CAAC;CACrB;AAED,YAAY,EAAE,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,CAAC"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,+BAA+B,CAAC;AAEvF,MAAM,MAAM,UAAU,GAAG,KAAK,GAAG,SAAS,GAAG,MAAM,GAAG,UAAU,CAAC;AAEjE,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,UAAU,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,QAAQ,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,qBAAqB;IACpC,kEAAkE;IAClE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,6FAA6F;IAC7F,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oFAAoF;IACpF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,uDAAuD;IACvD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mDAAmD;IACnD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,8EAA8E;IAC9E,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,wBAAwB;IACvC,2EAA2E;IAC3E,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,iEAAiE;IACjE,SAAS,CAAC,EAAE,qBAAqB,CAAC;IAElC,2EAA2E;IAC3E,OAAO,CAAC,EAAE,QAAQ,CAAC;IAEnB,6EAA6E;IAC7E,MAAM,CAAC,EAAE,QAAQ,CAAC;IAElB,iEAAiE;IACjE,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB,0CAA0C;IAC1C,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB,uDAAuD;IACvD,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB,0FAA0F;IAC1F,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB,kEAAkE;IAClE,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IAErB,oDAAoD;IACpD,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE9D,iDAAiD;IACjD,mBAAmB,CAAC,EAAE,CAAC,MAAM,EAAE,cAAc,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvE,6DAA6D;IAC7D,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,cAAc,EAAE,CAAC;IAC3B,WAAW,EAAE,QAAQ,GAAG,IAAI,CAAC;IAC7B,WAAW,EAAE,OAAO,CAAC;IACrB,UAAU,EAAE,OAAO,CAAC;CACrB;AAED,YAAY,EAAE,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,CAAC"}
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kairosinternational/watchman-nextjs",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Next.js 14 App Router adapter for @kairosinternational/watchman",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"node": ">=18"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@kairosinternational/watchman": "0.
|
|
28
|
+
"@kairosinternational/watchman": "0.2.0"
|
|
29
29
|
},
|
|
30
30
|
"peerDependencies": {
|
|
31
31
|
"next": "^14.0.0"
|
package/src/config.ts
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import type { WatchmanMiddlewareConfig } from './types.js';
|
|
2
2
|
|
|
3
3
|
export const DEFAULT_MIDDLEWARE_CONFIG: Required<
|
|
4
|
-
Omit<
|
|
4
|
+
Omit<
|
|
5
|
+
WatchmanMiddlewareConfig,
|
|
6
|
+
'projectRoot' | 'onFinding' | 'onColdStartComplete' | 'telemetry'
|
|
7
|
+
>
|
|
5
8
|
> = {
|
|
6
9
|
blockAt: 'critical',
|
|
7
10
|
warnAt: 'high',
|
package/src/index.ts
CHANGED
package/src/middleware.ts
CHANGED
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
type WatchmanReport,
|
|
7
7
|
} from '@kairosinternational/watchman/patterns';
|
|
8
8
|
import { resolveConfig, DEFAULT_MIDDLEWARE_CONFIG } from './config.js';
|
|
9
|
+
import { reportFindingIfConfigured } from './telemetry-session.js';
|
|
9
10
|
import type {
|
|
10
11
|
WatchmanMiddlewareConfig,
|
|
11
12
|
RequestFinding,
|
|
@@ -224,6 +225,21 @@ export function withWatchman(
|
|
|
224
225
|
}
|
|
225
226
|
}
|
|
226
227
|
|
|
228
|
+
for (const finding of outcome.findings) {
|
|
229
|
+
reportFindingIfConfigured(
|
|
230
|
+
{
|
|
231
|
+
rule: finding.rule,
|
|
232
|
+
severity: finding.severity,
|
|
233
|
+
target: finding.target,
|
|
234
|
+
label: finding.label,
|
|
235
|
+
message: finding.message,
|
|
236
|
+
evidence: finding.evidence,
|
|
237
|
+
},
|
|
238
|
+
config.telemetry,
|
|
239
|
+
config.quiet,
|
|
240
|
+
);
|
|
241
|
+
}
|
|
242
|
+
|
|
227
243
|
if (outcome.shouldBlock) {
|
|
228
244
|
if (!config.quiet) {
|
|
229
245
|
console.warn(
|
package/src/route-handler.ts
CHANGED
|
@@ -2,6 +2,7 @@ import type { NextRequest } from 'next/server';
|
|
|
2
2
|
import { NextResponse } from 'next/server';
|
|
3
3
|
import { resolveConfig } from './config.js';
|
|
4
4
|
import { scanString } from './middleware.js';
|
|
5
|
+
import { reportFindingIfConfigured } from './telemetry-session.js';
|
|
5
6
|
import type {
|
|
6
7
|
WatchmanMiddlewareConfig,
|
|
7
8
|
RequestFinding,
|
|
@@ -99,6 +100,21 @@ export function withWatchmanRoute<H extends RouteHandler>(
|
|
|
99
100
|
}
|
|
100
101
|
}
|
|
101
102
|
|
|
103
|
+
for (const finding of outcome.findings) {
|
|
104
|
+
reportFindingIfConfigured(
|
|
105
|
+
{
|
|
106
|
+
rule: finding.rule,
|
|
107
|
+
severity: finding.severity,
|
|
108
|
+
target: finding.target,
|
|
109
|
+
label: finding.label,
|
|
110
|
+
message: finding.message,
|
|
111
|
+
evidence: finding.evidence,
|
|
112
|
+
},
|
|
113
|
+
config.telemetry,
|
|
114
|
+
config.quiet,
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
|
|
102
118
|
if (outcome.shouldBlock) {
|
|
103
119
|
if (!config.quiet) {
|
|
104
120
|
console.warn(
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createTelemetryReporter,
|
|
3
|
+
type TelemetryReporter,
|
|
4
|
+
} from '@kairosinternational/watchman/telemetry';
|
|
5
|
+
import type { NextjsTelemetryConfig } from './types.js';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Memoized per-process telemetry session. A Next.js process (or Vercel
|
|
9
|
+
* Function instance) calls startSession once on first use, then reuses
|
|
10
|
+
* the same sessionId for every request scanned by this instance.
|
|
11
|
+
*
|
|
12
|
+
* Sessions are never explicitly ended from Next.js — Fluid Compute
|
|
13
|
+
* recycles instances without a clean shutdown. A server-side reaper
|
|
14
|
+
* marks stale sessions as completed.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
interface RuntimeState {
|
|
18
|
+
reporter: TelemetryReporter;
|
|
19
|
+
sessionIdPromise: Promise<string | null>;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
let state: RuntimeState | null = null;
|
|
23
|
+
let skippedLogged = false;
|
|
24
|
+
|
|
25
|
+
function resolveTelemetryConfig(
|
|
26
|
+
config?: NextjsTelemetryConfig,
|
|
27
|
+
): { apiKey: string; endpoint: string; projectSlug: string } | null {
|
|
28
|
+
const apiKey = config?.apiKey ?? process.env['WATCHMAN_API_KEY'];
|
|
29
|
+
const endpoint = config?.endpoint ?? process.env['WATCHMAN_ENDPOINT'];
|
|
30
|
+
if (!apiKey || !endpoint) return null;
|
|
31
|
+
|
|
32
|
+
const projectSlug =
|
|
33
|
+
config?.projectSlug ??
|
|
34
|
+
process.env['WATCHMAN_PROJECT_SLUG'] ??
|
|
35
|
+
process.env['VERCEL_GIT_REPO_SLUG'] ??
|
|
36
|
+
'nextjs-app';
|
|
37
|
+
|
|
38
|
+
return { apiKey, endpoint, projectSlug };
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function detectEnv(config?: NextjsTelemetryConfig): {
|
|
42
|
+
commitSha?: string;
|
|
43
|
+
branch?: string;
|
|
44
|
+
environment?: string;
|
|
45
|
+
} {
|
|
46
|
+
return {
|
|
47
|
+
commitSha:
|
|
48
|
+
config?.commitSha ?? process.env['VERCEL_GIT_COMMIT_SHA'] ?? undefined,
|
|
49
|
+
branch:
|
|
50
|
+
config?.branch ?? process.env['VERCEL_GIT_COMMIT_REF'] ?? undefined,
|
|
51
|
+
environment:
|
|
52
|
+
config?.environment ??
|
|
53
|
+
process.env['WATCHMAN_ENVIRONMENT'] ??
|
|
54
|
+
process.env['VERCEL_ENV'] ??
|
|
55
|
+
'nextjs-middleware',
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Get or initialize the session. Safe to call on every request —
|
|
61
|
+
* the startSession RPC runs at most once per process.
|
|
62
|
+
*/
|
|
63
|
+
export function ensureSession(
|
|
64
|
+
config?: NextjsTelemetryConfig,
|
|
65
|
+
quiet = false,
|
|
66
|
+
): RuntimeState | null {
|
|
67
|
+
if (state) return state;
|
|
68
|
+
|
|
69
|
+
const resolved = resolveTelemetryConfig(config);
|
|
70
|
+
if (!resolved) {
|
|
71
|
+
if (!quiet && !skippedLogged) {
|
|
72
|
+
console.info('[watchman] telemetry disabled (no apiKey/endpoint)');
|
|
73
|
+
skippedLogged = true;
|
|
74
|
+
}
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const reporter = createTelemetryReporter({
|
|
79
|
+
apiKey: resolved.apiKey,
|
|
80
|
+
endpoint: resolved.endpoint,
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
const sessionIdPromise = reporter.startSession(
|
|
84
|
+
resolved.projectSlug,
|
|
85
|
+
detectEnv(config),
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
state = { reporter, sessionIdPromise };
|
|
89
|
+
return state;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Fire-and-forget finding report. Resolves the memoized session ID
|
|
94
|
+
* first; if session-open failed, findings are silently dropped.
|
|
95
|
+
*/
|
|
96
|
+
export function reportFindingIfConfigured(
|
|
97
|
+
finding: {
|
|
98
|
+
scanner?: string;
|
|
99
|
+
rule: string;
|
|
100
|
+
severity: import('@kairosinternational/watchman/telemetry').TelemetryFinding['severity'];
|
|
101
|
+
target?: string;
|
|
102
|
+
label?: string;
|
|
103
|
+
message: string;
|
|
104
|
+
evidence?: string;
|
|
105
|
+
},
|
|
106
|
+
config?: NextjsTelemetryConfig,
|
|
107
|
+
quiet = false,
|
|
108
|
+
): void {
|
|
109
|
+
const runtime = ensureSession(config, quiet);
|
|
110
|
+
if (!runtime) return;
|
|
111
|
+
|
|
112
|
+
void runtime.sessionIdPromise.then((sessionId) => {
|
|
113
|
+
if (!sessionId) return;
|
|
114
|
+
runtime.reporter.reportFinding(
|
|
115
|
+
{
|
|
116
|
+
scanner: finding.scanner ?? 'nextjs-middleware',
|
|
117
|
+
rule: finding.rule,
|
|
118
|
+
severity: finding.severity,
|
|
119
|
+
target: finding.target,
|
|
120
|
+
label: finding.label,
|
|
121
|
+
message: finding.message,
|
|
122
|
+
evidence: finding.evidence,
|
|
123
|
+
},
|
|
124
|
+
sessionId,
|
|
125
|
+
);
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/** Test-only helper — resets module state between tests. */
|
|
130
|
+
export function __resetSessionState(): void {
|
|
131
|
+
state = null;
|
|
132
|
+
skippedLogged = false;
|
|
133
|
+
}
|
package/src/types.ts
CHANGED
|
@@ -12,10 +12,28 @@ export interface RequestFinding {
|
|
|
12
12
|
evidence: string;
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
+
export interface NextjsTelemetryConfig {
|
|
16
|
+
/** Watchman API key (raw). Falls back to WATCHMAN_API_KEY env. */
|
|
17
|
+
apiKey?: string;
|
|
18
|
+
/** Watchman endpoint, e.g. "https://watchman.guide". Falls back to WATCHMAN_ENDPOINT env. */
|
|
19
|
+
endpoint?: string;
|
|
20
|
+
/** Project slug. Falls back to WATCHMAN_PROJECT_SLUG, then VERCEL_GIT_REPO_SLUG. */
|
|
21
|
+
projectSlug?: string;
|
|
22
|
+
/** Commit SHA. Falls back to VERCEL_GIT_COMMIT_SHA. */
|
|
23
|
+
commitSha?: string;
|
|
24
|
+
/** Branch. Falls back to VERCEL_GIT_COMMIT_REF. */
|
|
25
|
+
branch?: string;
|
|
26
|
+
/** Environment label. Falls back to WATCHMAN_ENVIRONMENT, then VERCEL_ENV. */
|
|
27
|
+
environment?: string;
|
|
28
|
+
}
|
|
29
|
+
|
|
15
30
|
export interface WatchmanMiddlewareConfig {
|
|
16
31
|
/** Project root for cold-start file scanning. Defaults to process.cwd() */
|
|
17
32
|
projectRoot?: string;
|
|
18
33
|
|
|
34
|
+
/** Optional telemetry — stream findings to a Watchman server. */
|
|
35
|
+
telemetry?: NextjsTelemetryConfig;
|
|
36
|
+
|
|
19
37
|
/** Severity at or above which to block the request. Default: 'critical' */
|
|
20
38
|
blockAt?: Severity;
|
|
21
39
|
|