@agentcash/telemetry 0.3.1 → 0.3.2
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/{chunk-CIAESB2C.js → chunk-FOVQCGAH.js} +20 -11
- package/dist/chunk-FOVQCGAH.js.map +1 -0
- package/dist/{chunk-YAHKVH4T.mjs → chunk-OHOHTH2I.mjs} +20 -11
- package/dist/chunk-OHOHTH2I.mjs.map +1 -0
- package/dist/index.d.mts +4 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +2 -2
- package/dist/index.mjs +1 -1
- package/dist/siwx.js +2 -2
- package/dist/siwx.mjs +1 -1
- package/package.json +1 -1
- package/dist/chunk-CIAESB2C.js.map +0 -1
- package/dist/chunk-YAHKVH4T.mjs.map +0 -1
|
@@ -6,6 +6,7 @@ var _chunk2EFPFJCBjs = require('./chunk-2EFPFJCB.js');
|
|
|
6
6
|
|
|
7
7
|
// src/telemetry.ts
|
|
8
8
|
var _server = require('next/server');
|
|
9
|
+
|
|
9
10
|
function withTelemetry(handler) {
|
|
10
11
|
return async (request) => {
|
|
11
12
|
const meta = _chunk2EFPFJCBjs.extractRequestMeta.call(void 0, request);
|
|
@@ -31,17 +32,25 @@ function withTelemetry(handler) {
|
|
|
31
32
|
response = _server.NextResponse.json({ success: false, error: message }, { status: 500 });
|
|
32
33
|
}
|
|
33
34
|
}
|
|
34
|
-
let responseBodyString = null;
|
|
35
|
-
try {
|
|
36
|
-
responseBodyString = await response.clone().text();
|
|
37
|
-
} catch (e2) {
|
|
38
|
-
}
|
|
39
35
|
if (response.status !== 402) {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
36
|
+
const status = response.status;
|
|
37
|
+
const responseHeaders = JSON.stringify(Object.fromEntries(response.headers.entries()));
|
|
38
|
+
const contentType = _nullishCoalesce(response.headers.get("content-type"), () => ( null));
|
|
39
|
+
let responseBodyString = null;
|
|
40
|
+
try {
|
|
41
|
+
responseBodyString = await response.clone().text();
|
|
42
|
+
} catch (e2) {
|
|
43
|
+
}
|
|
44
|
+
_server.after.call(void 0, () => {
|
|
45
|
+
try {
|
|
46
|
+
_chunk2EFPFJCBjs.recordInvocation.call(void 0, meta, requestBodyString, {
|
|
47
|
+
status,
|
|
48
|
+
body: responseBodyString,
|
|
49
|
+
headers: responseHeaders,
|
|
50
|
+
contentType
|
|
51
|
+
});
|
|
52
|
+
} catch (e3) {
|
|
53
|
+
}
|
|
45
54
|
});
|
|
46
55
|
}
|
|
47
56
|
if (handlerError && !(handlerError instanceof _server.NextResponse)) {
|
|
@@ -54,4 +63,4 @@ function withTelemetry(handler) {
|
|
|
54
63
|
|
|
55
64
|
|
|
56
65
|
exports.withTelemetry = withTelemetry;
|
|
57
|
-
//# sourceMappingURL=chunk-
|
|
66
|
+
//# sourceMappingURL=chunk-FOVQCGAH.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["/home/runner/work/agentcash-telemetry/agentcash-telemetry/dist/chunk-FOVQCGAH.js","../src/telemetry.ts"],"names":[],"mappings":"AAAA;AACE;AACA;AACA;AACF,sDAA4B;AAC5B;AACA;ACAA,qCAA+C;AAC/C;AAkBO,SAAS,aAAA,CAAc,OAAA,EAA2B;AACvD,EAAA,OAAO,MAAA,CAAO,OAAA,EAAA,GAAgD;AAC5D,IAAA,MAAM,KAAA,EAAO,iDAAA,OAA0B,CAAA;AACvC,IAAA,MAAM,IAAA,EAAM,oDAAA,IAA0B,CAAA;AAGtC,IAAA,IAAI,kBAAA,EAAmC,IAAA;AACvC,IAAA,GAAA,CAAI,IAAA,CAAK,OAAA,IAAW,OAAA,GAAU,IAAA,CAAK,OAAA,IAAW,MAAA,GAAS,IAAA,CAAK,OAAA,IAAW,OAAA,EAAS;AAC9E,MAAA,IAAI;AACF,QAAA,MAAM,KAAA,EAAO,MAAM,OAAA,CAAQ,KAAA,CAAM,CAAA,CAAE,IAAA,CAAK,CAAA;AACxC,QAAA,GAAA,CAAI,IAAA,EAAM,kBAAA,EAAoB,IAAA;AAAA,MAChC,EAAA,UAAQ;AAAA,MAER;AAAA,IACF;AAGA,IAAA,IAAI,QAAA;AACJ,IAAA,IAAI,aAAA,EAAwB,IAAA;AAE5B,IAAA,IAAI;AACF,MAAA,SAAA,EAAW,MAAM,OAAA,CAAQ,OAAA,EAAS,GAAG,CAAA;AAAA,IACvC,EAAA,MAAA,CAAS,KAAA,EAAgB;AACvB,MAAA,aAAA,EAAe,KAAA;AACf,MAAA,GAAA,CAAI,MAAA,WAAiB,oBAAA,EAAc;AACjC,QAAA,SAAA,EAAW,KAAA;AAAA,MACb,EAAA,KAAO;AACL,QAAA,MAAM,QAAA,EAAU,MAAA,WAAiB,MAAA,EAAQ,KAAA,CAAM,QAAA,EAAU,uBAAA;AACzD,QAAA,SAAA,EAAW,oBAAA,CAAa,IAAA,CAAK,EAAE,OAAA,EAAS,KAAA,EAAO,KAAA,EAAO,QAAQ,CAAA,EAAG,EAAE,MAAA,EAAQ,IAAI,CAAC,CAAA;AAAA,MAClF;AAAA,IACF;AAGA,IAAA,GAAA,CAAI,QAAA,CAAS,OAAA,IAAW,GAAA,EAAK;AAG3B,MAAA,MAAM,OAAA,EAAS,QAAA,CAAS,MAAA;AACxB,MAAA,MAAM,gBAAA,EAAkB,IAAA,CAAK,SAAA,CAAU,MAAA,CAAO,WAAA,CAAY,QAAA,CAAS,OAAA,CAAQ,OAAA,CAAQ,CAAC,CAAC,CAAA;AACrF,MAAA,MAAM,YAAA,mBAAc,QAAA,CAAS,OAAA,CAAQ,GAAA,CAAI,cAAc,CAAA,UAAK,MAAA;AAC5D,MAAA,IAAI,mBAAA,EAAoC,IAAA;AACxC,MAAA,IAAI;AACF,QAAA,mBAAA,EAAqB,MAAM,QAAA,CAAS,KAAA,CAAM,CAAA,CAAE,IAAA,CAAK,CAAA;AAAA,MACnD,EAAA,WAAQ;AAAA,MAER;AAIA,MAAA,2BAAA,CAAM,EAAA,GAAM;AACV,QAAA,IAAI;AACF,UAAA,+CAAA,IAAiB,EAAM,iBAAA,EAAmB;AAAA,YACxC,MAAA;AAAA,YACA,IAAA,EAAM,kBAAA;AAAA,YACN,OAAA,EAAS,eAAA;AAAA,YACT;AAAA,UACF,CAAC,CAAA;AAAA,QACH,EAAA,WAAQ;AAAA,QAER;AAAA,MACF,CAAC,CAAA;AAAA,IACH;AAGA,IAAA,GAAA,CAAI,aAAA,GAAgB,CAAA,CAAE,aAAA,WAAwB,oBAAA,CAAA,EAAe;AAC3D,MAAA,MAAM,YAAA;AAAA,IACR;AAEA,IAAA,OAAO,QAAA;AAAA,EACT,CAAA;AACF;ADjCA;AACA;AACE;AACF,sCAAC","file":"/home/runner/work/agentcash-telemetry/agentcash-telemetry/dist/chunk-FOVQCGAH.js","sourcesContent":[null,"/**\n * Core telemetry wrapper for Next.js route handlers.\n * Extracts identity headers, logs to ClickHouse, extracts verified wallet.\n * This is a passive observer — it never influences the response.\n */\n\nimport { type NextRequest, NextResponse } from 'next/server';\nimport { after } from 'next/server';\nimport type { TelemetryContext } from './types';\nimport { extractRequestMeta, buildTelemetryContext, recordInvocation } from './telemetry-core';\n\ntype TelemetryHandler = (request: NextRequest, ctx: TelemetryContext) => Promise<NextResponse>;\n\n/**\n * Wrap a Next.js route handler with telemetry.\n * Extracts identity headers, logs the invocation to ClickHouse,\n * and auto-extracts verified wallet from x402 payment headers.\n *\n * Uses Next.js after() to defer the ClickHouse insert until after\n * the response is sent. On Vercel this keeps the Lambda alive until\n * the insert completes, avoiding frozen in-flight promises.\n *\n * The entire telemetry code path is wrapped in try/catch.\n * Telemetry failures never affect the response.\n */\nexport function withTelemetry(handler: TelemetryHandler) {\n return async (request: NextRequest): Promise<NextResponse> => {\n const meta = extractRequestMeta(request);\n const ctx = buildTelemetryContext(meta);\n\n // Capture request body for logging (only for methods with bodies)\n let requestBodyString: string | null = null;\n if (meta.method === 'POST' || meta.method === 'PUT' || meta.method === 'PATCH') {\n try {\n const body = await request.clone().text();\n if (body) requestBodyString = body;\n } catch {\n // Body read failed — that's fine\n }\n }\n\n // Execute the actual handler\n let response: NextResponse;\n let handlerError: unknown = null;\n\n try {\n response = await handler(request, ctx);\n } catch (error: unknown) {\n handlerError = error;\n if (error instanceof NextResponse) {\n response = error;\n } else {\n const message = error instanceof Error ? error.message : 'Internal server error';\n response = NextResponse.json({ success: false, error: message }, { status: 500 });\n }\n }\n\n // 402 is the x402/MPP payment challenge — not a real invocation, skip logging\n if (response.status !== 402) {\n // Capture all response data before returning — response.clone() must happen\n // before Next.js consumes the body to send it to the client.\n const status = response.status;\n const responseHeaders = JSON.stringify(Object.fromEntries(response.headers.entries()));\n const contentType = response.headers.get('content-type') ?? null;\n let responseBodyString: string | null = null;\n try {\n responseBodyString = await response.clone().text();\n } catch {\n // Response body read failed — that's fine\n }\n\n // Defer the ClickHouse insert until after the response is sent.\n // On Vercel, after() keeps the Lambda alive until the insert completes.\n after(() => {\n try {\n recordInvocation(meta, requestBodyString, {\n status,\n body: responseBodyString,\n headers: responseHeaders,\n contentType,\n });\n } catch {\n // Telemetry never affects the response\n }\n });\n }\n\n // Re-throw the original error if it wasn't a NextResponse\n if (handlerError && !(handlerError instanceof NextResponse)) {\n throw handlerError;\n }\n\n return response;\n };\n}\n"]}
|
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
|
|
7
7
|
// src/telemetry.ts
|
|
8
8
|
import { NextResponse } from "next/server";
|
|
9
|
+
import { after } from "next/server";
|
|
9
10
|
function withTelemetry(handler) {
|
|
10
11
|
return async (request) => {
|
|
11
12
|
const meta = extractRequestMeta(request);
|
|
@@ -31,17 +32,25 @@ function withTelemetry(handler) {
|
|
|
31
32
|
response = NextResponse.json({ success: false, error: message }, { status: 500 });
|
|
32
33
|
}
|
|
33
34
|
}
|
|
34
|
-
let responseBodyString = null;
|
|
35
|
-
try {
|
|
36
|
-
responseBodyString = await response.clone().text();
|
|
37
|
-
} catch {
|
|
38
|
-
}
|
|
39
35
|
if (response.status !== 402) {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
36
|
+
const status = response.status;
|
|
37
|
+
const responseHeaders = JSON.stringify(Object.fromEntries(response.headers.entries()));
|
|
38
|
+
const contentType = response.headers.get("content-type") ?? null;
|
|
39
|
+
let responseBodyString = null;
|
|
40
|
+
try {
|
|
41
|
+
responseBodyString = await response.clone().text();
|
|
42
|
+
} catch {
|
|
43
|
+
}
|
|
44
|
+
after(() => {
|
|
45
|
+
try {
|
|
46
|
+
recordInvocation(meta, requestBodyString, {
|
|
47
|
+
status,
|
|
48
|
+
body: responseBodyString,
|
|
49
|
+
headers: responseHeaders,
|
|
50
|
+
contentType
|
|
51
|
+
});
|
|
52
|
+
} catch {
|
|
53
|
+
}
|
|
45
54
|
});
|
|
46
55
|
}
|
|
47
56
|
if (handlerError && !(handlerError instanceof NextResponse)) {
|
|
@@ -54,4 +63,4 @@ function withTelemetry(handler) {
|
|
|
54
63
|
export {
|
|
55
64
|
withTelemetry
|
|
56
65
|
};
|
|
57
|
-
//# sourceMappingURL=chunk-
|
|
66
|
+
//# sourceMappingURL=chunk-OHOHTH2I.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/telemetry.ts"],"sourcesContent":["/**\n * Core telemetry wrapper for Next.js route handlers.\n * Extracts identity headers, logs to ClickHouse, extracts verified wallet.\n * This is a passive observer — it never influences the response.\n */\n\nimport { type NextRequest, NextResponse } from 'next/server';\nimport { after } from 'next/server';\nimport type { TelemetryContext } from './types';\nimport { extractRequestMeta, buildTelemetryContext, recordInvocation } from './telemetry-core';\n\ntype TelemetryHandler = (request: NextRequest, ctx: TelemetryContext) => Promise<NextResponse>;\n\n/**\n * Wrap a Next.js route handler with telemetry.\n * Extracts identity headers, logs the invocation to ClickHouse,\n * and auto-extracts verified wallet from x402 payment headers.\n *\n * Uses Next.js after() to defer the ClickHouse insert until after\n * the response is sent. On Vercel this keeps the Lambda alive until\n * the insert completes, avoiding frozen in-flight promises.\n *\n * The entire telemetry code path is wrapped in try/catch.\n * Telemetry failures never affect the response.\n */\nexport function withTelemetry(handler: TelemetryHandler) {\n return async (request: NextRequest): Promise<NextResponse> => {\n const meta = extractRequestMeta(request);\n const ctx = buildTelemetryContext(meta);\n\n // Capture request body for logging (only for methods with bodies)\n let requestBodyString: string | null = null;\n if (meta.method === 'POST' || meta.method === 'PUT' || meta.method === 'PATCH') {\n try {\n const body = await request.clone().text();\n if (body) requestBodyString = body;\n } catch {\n // Body read failed — that's fine\n }\n }\n\n // Execute the actual handler\n let response: NextResponse;\n let handlerError: unknown = null;\n\n try {\n response = await handler(request, ctx);\n } catch (error: unknown) {\n handlerError = error;\n if (error instanceof NextResponse) {\n response = error;\n } else {\n const message = error instanceof Error ? error.message : 'Internal server error';\n response = NextResponse.json({ success: false, error: message }, { status: 500 });\n }\n }\n\n // 402 is the x402/MPP payment challenge — not a real invocation, skip logging\n if (response.status !== 402) {\n // Capture all response data before returning — response.clone() must happen\n // before Next.js consumes the body to send it to the client.\n const status = response.status;\n const responseHeaders = JSON.stringify(Object.fromEntries(response.headers.entries()));\n const contentType = response.headers.get('content-type') ?? null;\n let responseBodyString: string | null = null;\n try {\n responseBodyString = await response.clone().text();\n } catch {\n // Response body read failed — that's fine\n }\n\n // Defer the ClickHouse insert until after the response is sent.\n // On Vercel, after() keeps the Lambda alive until the insert completes.\n after(() => {\n try {\n recordInvocation(meta, requestBodyString, {\n status,\n body: responseBodyString,\n headers: responseHeaders,\n contentType,\n });\n } catch {\n // Telemetry never affects the response\n }\n });\n }\n\n // Re-throw the original error if it wasn't a NextResponse\n if (handlerError && !(handlerError instanceof NextResponse)) {\n throw handlerError;\n }\n\n return response;\n };\n}\n"],"mappings":";;;;;;;AAMA,SAA2B,oBAAoB;AAC/C,SAAS,aAAa;AAkBf,SAAS,cAAc,SAA2B;AACvD,SAAO,OAAO,YAAgD;AAC5D,UAAM,OAAO,mBAAmB,OAAO;AACvC,UAAM,MAAM,sBAAsB,IAAI;AAGtC,QAAI,oBAAmC;AACvC,QAAI,KAAK,WAAW,UAAU,KAAK,WAAW,SAAS,KAAK,WAAW,SAAS;AAC9E,UAAI;AACF,cAAM,OAAO,MAAM,QAAQ,MAAM,EAAE,KAAK;AACxC,YAAI,KAAM,qBAAoB;AAAA,MAChC,QAAQ;AAAA,MAER;AAAA,IACF;AAGA,QAAI;AACJ,QAAI,eAAwB;AAE5B,QAAI;AACF,iBAAW,MAAM,QAAQ,SAAS,GAAG;AAAA,IACvC,SAAS,OAAgB;AACvB,qBAAe;AACf,UAAI,iBAAiB,cAAc;AACjC,mBAAW;AAAA,MACb,OAAO;AACL,cAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU;AACzD,mBAAW,aAAa,KAAK,EAAE,SAAS,OAAO,OAAO,QAAQ,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,MAClF;AAAA,IACF;AAGA,QAAI,SAAS,WAAW,KAAK;AAG3B,YAAM,SAAS,SAAS;AACxB,YAAM,kBAAkB,KAAK,UAAU,OAAO,YAAY,SAAS,QAAQ,QAAQ,CAAC,CAAC;AACrF,YAAM,cAAc,SAAS,QAAQ,IAAI,cAAc,KAAK;AAC5D,UAAI,qBAAoC;AACxC,UAAI;AACF,6BAAqB,MAAM,SAAS,MAAM,EAAE,KAAK;AAAA,MACnD,QAAQ;AAAA,MAER;AAIA,YAAM,MAAM;AACV,YAAI;AACF,2BAAiB,MAAM,mBAAmB;AAAA,YACxC;AAAA,YACA,MAAM;AAAA,YACN,SAAS;AAAA,YACT;AAAA,UACF,CAAC;AAAA,QACH,QAAQ;AAAA,QAER;AAAA,MACF,CAAC;AAAA,IACH;AAGA,QAAI,gBAAgB,EAAE,wBAAwB,eAAe;AAC3D,YAAM;AAAA,IACR;AAEA,WAAO;AAAA,EACT;AACF;","names":[]}
|
package/dist/index.d.mts
CHANGED
|
@@ -38,6 +38,10 @@ type TelemetryHandler = (request: NextRequest, ctx: TelemetryContext) => Promise
|
|
|
38
38
|
* Extracts identity headers, logs the invocation to ClickHouse,
|
|
39
39
|
* and auto-extracts verified wallet from x402 payment headers.
|
|
40
40
|
*
|
|
41
|
+
* Uses Next.js after() to defer the ClickHouse insert until after
|
|
42
|
+
* the response is sent. On Vercel this keeps the Lambda alive until
|
|
43
|
+
* the insert completes, avoiding frozen in-flight promises.
|
|
44
|
+
*
|
|
41
45
|
* The entire telemetry code path is wrapped in try/catch.
|
|
42
46
|
* Telemetry failures never affect the response.
|
|
43
47
|
*/
|
package/dist/index.d.ts
CHANGED
|
@@ -38,6 +38,10 @@ type TelemetryHandler = (request: NextRequest, ctx: TelemetryContext) => Promise
|
|
|
38
38
|
* Extracts identity headers, logs the invocation to ClickHouse,
|
|
39
39
|
* and auto-extracts verified wallet from x402 payment headers.
|
|
40
40
|
*
|
|
41
|
+
* Uses Next.js after() to defer the ClickHouse insert until after
|
|
42
|
+
* the response is sent. On Vercel this keeps the Lambda alive until
|
|
43
|
+
* the insert completes, avoiding frozen in-flight promises.
|
|
44
|
+
*
|
|
41
45
|
* The entire telemetry code path is wrapped in try/catch.
|
|
42
46
|
* Telemetry failures never affect the response.
|
|
43
47
|
*/
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";Object.defineProperty(exports, "__esModule", {value: true});
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var _chunkFOVQCGAHjs = require('./chunk-FOVQCGAH.js');
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
|
|
@@ -10,5 +10,5 @@ require('./chunk-QEJ7ZGGH.js');
|
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
|
|
13
|
-
exports.extractVerifiedWallet = _chunk2EFPFJCBjs.extractVerifiedWallet; exports.initTelemetry = _chunk2EFPFJCBjs.initTelemetry; exports.withTelemetry =
|
|
13
|
+
exports.extractVerifiedWallet = _chunk2EFPFJCBjs.extractVerifiedWallet; exports.initTelemetry = _chunk2EFPFJCBjs.initTelemetry; exports.withTelemetry = _chunkFOVQCGAHjs.withTelemetry;
|
|
14
14
|
//# sourceMappingURL=index.js.map
|
package/dist/index.mjs
CHANGED
package/dist/siwx.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } }
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var _chunkFOVQCGAHjs = require('./chunk-FOVQCGAH.js');
|
|
4
4
|
require('./chunk-2EFPFJCB.js');
|
|
5
5
|
require('./chunk-QEJ7ZGGH.js');
|
|
6
6
|
|
|
@@ -15,7 +15,7 @@ var _crypto = require('crypto');
|
|
|
15
15
|
var _signinwithx = require('@x402/extensions/sign-in-with-x');
|
|
16
16
|
var _http = require('@x402/core/http');
|
|
17
17
|
function withSiwxTelemetry(handler) {
|
|
18
|
-
return
|
|
18
|
+
return _chunkFOVQCGAHjs.withTelemetry.call(void 0, async (request, ctx) => {
|
|
19
19
|
const header = _nullishCoalesce(request.headers.get("SIGN-IN-WITH-X"), () => ( request.headers.get("sign-in-with-x")));
|
|
20
20
|
if (!header) {
|
|
21
21
|
return buildSiwxChallengeResponse(request);
|
package/dist/siwx.mjs
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agentcash/telemetry",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.2",
|
|
4
4
|
"description": "ClickHouse telemetry plugin for @agentcash/router. Logs request lifecycle, payments, settlements, and provider quota to ClickHouse.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["/home/runner/work/agentcash-telemetry/agentcash-telemetry/dist/chunk-CIAESB2C.js","../src/telemetry.ts"],"names":[],"mappings":"AAAA;AACE;AACA;AACA;AACF,sDAA4B;AAC5B;AACA;ACAA,qCAA+C;AAcxC,SAAS,aAAA,CAAc,OAAA,EAA2B;AACvD,EAAA,OAAO,MAAA,CAAO,OAAA,EAAA,GAAgD;AAC5D,IAAA,MAAM,KAAA,EAAO,iDAAA,OAA0B,CAAA;AACvC,IAAA,MAAM,IAAA,EAAM,oDAAA,IAA0B,CAAA;AAGtC,IAAA,IAAI,kBAAA,EAAmC,IAAA;AACvC,IAAA,GAAA,CAAI,IAAA,CAAK,OAAA,IAAW,OAAA,GAAU,IAAA,CAAK,OAAA,IAAW,MAAA,GAAS,IAAA,CAAK,OAAA,IAAW,OAAA,EAAS;AAC9E,MAAA,IAAI;AACF,QAAA,MAAM,KAAA,EAAO,MAAM,OAAA,CAAQ,KAAA,CAAM,CAAA,CAAE,IAAA,CAAK,CAAA;AACxC,QAAA,GAAA,CAAI,IAAA,EAAM,kBAAA,EAAoB,IAAA;AAAA,MAChC,EAAA,UAAQ;AAAA,MAER;AAAA,IACF;AAGA,IAAA,IAAI,QAAA;AACJ,IAAA,IAAI,aAAA,EAAwB,IAAA;AAE5B,IAAA,IAAI;AACF,MAAA,SAAA,EAAW,MAAM,OAAA,CAAQ,OAAA,EAAS,GAAG,CAAA;AAAA,IACvC,EAAA,MAAA,CAAS,KAAA,EAAgB;AACvB,MAAA,aAAA,EAAe,KAAA;AACf,MAAA,GAAA,CAAI,MAAA,WAAiB,oBAAA,EAAc;AACjC,QAAA,SAAA,EAAW,KAAA;AAAA,MACb,EAAA,KAAO;AACL,QAAA,MAAM,QAAA,EAAU,MAAA,WAAiB,MAAA,EAAQ,KAAA,CAAM,QAAA,EAAU,uBAAA;AACzD,QAAA,SAAA,EAAW,oBAAA,CAAa,IAAA,CAAK,EAAE,OAAA,EAAS,KAAA,EAAO,KAAA,EAAO,QAAQ,CAAA,EAAG,EAAE,MAAA,EAAQ,IAAI,CAAC,CAAA;AAAA,MAClF;AAAA,IACF;AAGA,IAAA,IAAI,mBAAA,EAAoC,IAAA;AACxC,IAAA,IAAI;AACF,MAAA,mBAAA,EAAqB,MAAM,QAAA,CAAS,KAAA,CAAM,CAAA,CAAE,IAAA,CAAK,CAAA;AAAA,IACnD,EAAA,WAAQ;AAAA,IAER;AAGA,IAAA,GAAA,CAAI,QAAA,CAAS,OAAA,IAAW,GAAA,EAAK;AAC3B,MAAA,+CAAA,IAAiB,EAAM,iBAAA,EAAmB;AAAA,QACxC,MAAA,EAAQ,QAAA,CAAS,MAAA;AAAA,QACjB,IAAA,EAAM,kBAAA;AAAA,QACN,OAAA,EAAS,IAAA,CAAK,SAAA,CAAU,MAAA,CAAO,WAAA,CAAY,QAAA,CAAS,OAAA,CAAQ,OAAA,CAAQ,CAAC,CAAC,CAAA;AAAA,QACtE,WAAA,mBAAa,QAAA,CAAS,OAAA,CAAQ,GAAA,CAAI,cAAc,CAAA,UAAK;AAAA,MACvD,CAAC,CAAA;AAAA,IACH;AAGA,IAAA,GAAA,CAAI,aAAA,GAAgB,CAAA,CAAE,aAAA,WAAwB,oBAAA,CAAA,EAAe;AAC3D,MAAA,MAAM,YAAA;AAAA,IACR;AAEA,IAAA,OAAO,QAAA;AAAA,EACT,CAAA;AACF;ADzBA;AACA;AACE;AACF,sCAAC","file":"/home/runner/work/agentcash-telemetry/agentcash-telemetry/dist/chunk-CIAESB2C.js","sourcesContent":[null,"/**\n * Core telemetry wrapper for Next.js route handlers.\n * Extracts identity headers, logs to ClickHouse, extracts verified wallet.\n * This is a passive observer — it never influences the response.\n */\n\nimport { type NextRequest, NextResponse } from 'next/server';\nimport type { TelemetryContext } from './types';\nimport { extractRequestMeta, buildTelemetryContext, recordInvocation } from './telemetry-core';\n\ntype TelemetryHandler = (request: NextRequest, ctx: TelemetryContext) => Promise<NextResponse>;\n\n/**\n * Wrap a Next.js route handler with telemetry.\n * Extracts identity headers, logs the invocation to ClickHouse,\n * and auto-extracts verified wallet from x402 payment headers.\n *\n * The entire telemetry code path is wrapped in try/catch.\n * Telemetry failures never affect the response.\n */\nexport function withTelemetry(handler: TelemetryHandler) {\n return async (request: NextRequest): Promise<NextResponse> => {\n const meta = extractRequestMeta(request);\n const ctx = buildTelemetryContext(meta);\n\n // Capture request body for logging (only for methods with bodies)\n let requestBodyString: string | null = null;\n if (meta.method === 'POST' || meta.method === 'PUT' || meta.method === 'PATCH') {\n try {\n const body = await request.clone().text();\n if (body) requestBodyString = body;\n } catch {\n // Body read failed — that's fine\n }\n }\n\n // Execute the actual handler\n let response: NextResponse;\n let handlerError: unknown = null;\n\n try {\n response = await handler(request, ctx);\n } catch (error: unknown) {\n handlerError = error;\n if (error instanceof NextResponse) {\n response = error;\n } else {\n const message = error instanceof Error ? error.message : 'Internal server error';\n response = NextResponse.json({ success: false, error: message }, { status: 500 });\n }\n }\n\n // Log to ClickHouse (fire-and-forget)\n let responseBodyString: string | null = null;\n try {\n responseBodyString = await response.clone().text();\n } catch {\n // Response body read failed — that's fine\n }\n\n // 402 is the x402/MPP payment challenge — not a real invocation, skip logging\n if (response.status !== 402) {\n recordInvocation(meta, requestBodyString, {\n status: response.status,\n body: responseBodyString,\n headers: JSON.stringify(Object.fromEntries(response.headers.entries())),\n contentType: response.headers.get('content-type') ?? null,\n });\n }\n\n // Re-throw the original error if it wasn't a NextResponse\n if (handlerError && !(handlerError instanceof NextResponse)) {\n throw handlerError;\n }\n\n return response;\n };\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/telemetry.ts"],"sourcesContent":["/**\n * Core telemetry wrapper for Next.js route handlers.\n * Extracts identity headers, logs to ClickHouse, extracts verified wallet.\n * This is a passive observer — it never influences the response.\n */\n\nimport { type NextRequest, NextResponse } from 'next/server';\nimport type { TelemetryContext } from './types';\nimport { extractRequestMeta, buildTelemetryContext, recordInvocation } from './telemetry-core';\n\ntype TelemetryHandler = (request: NextRequest, ctx: TelemetryContext) => Promise<NextResponse>;\n\n/**\n * Wrap a Next.js route handler with telemetry.\n * Extracts identity headers, logs the invocation to ClickHouse,\n * and auto-extracts verified wallet from x402 payment headers.\n *\n * The entire telemetry code path is wrapped in try/catch.\n * Telemetry failures never affect the response.\n */\nexport function withTelemetry(handler: TelemetryHandler) {\n return async (request: NextRequest): Promise<NextResponse> => {\n const meta = extractRequestMeta(request);\n const ctx = buildTelemetryContext(meta);\n\n // Capture request body for logging (only for methods with bodies)\n let requestBodyString: string | null = null;\n if (meta.method === 'POST' || meta.method === 'PUT' || meta.method === 'PATCH') {\n try {\n const body = await request.clone().text();\n if (body) requestBodyString = body;\n } catch {\n // Body read failed — that's fine\n }\n }\n\n // Execute the actual handler\n let response: NextResponse;\n let handlerError: unknown = null;\n\n try {\n response = await handler(request, ctx);\n } catch (error: unknown) {\n handlerError = error;\n if (error instanceof NextResponse) {\n response = error;\n } else {\n const message = error instanceof Error ? error.message : 'Internal server error';\n response = NextResponse.json({ success: false, error: message }, { status: 500 });\n }\n }\n\n // Log to ClickHouse (fire-and-forget)\n let responseBodyString: string | null = null;\n try {\n responseBodyString = await response.clone().text();\n } catch {\n // Response body read failed — that's fine\n }\n\n // 402 is the x402/MPP payment challenge — not a real invocation, skip logging\n if (response.status !== 402) {\n recordInvocation(meta, requestBodyString, {\n status: response.status,\n body: responseBodyString,\n headers: JSON.stringify(Object.fromEntries(response.headers.entries())),\n contentType: response.headers.get('content-type') ?? null,\n });\n }\n\n // Re-throw the original error if it wasn't a NextResponse\n if (handlerError && !(handlerError instanceof NextResponse)) {\n throw handlerError;\n }\n\n return response;\n };\n}\n"],"mappings":";;;;;;;AAMA,SAA2B,oBAAoB;AAcxC,SAAS,cAAc,SAA2B;AACvD,SAAO,OAAO,YAAgD;AAC5D,UAAM,OAAO,mBAAmB,OAAO;AACvC,UAAM,MAAM,sBAAsB,IAAI;AAGtC,QAAI,oBAAmC;AACvC,QAAI,KAAK,WAAW,UAAU,KAAK,WAAW,SAAS,KAAK,WAAW,SAAS;AAC9E,UAAI;AACF,cAAM,OAAO,MAAM,QAAQ,MAAM,EAAE,KAAK;AACxC,YAAI,KAAM,qBAAoB;AAAA,MAChC,QAAQ;AAAA,MAER;AAAA,IACF;AAGA,QAAI;AACJ,QAAI,eAAwB;AAE5B,QAAI;AACF,iBAAW,MAAM,QAAQ,SAAS,GAAG;AAAA,IACvC,SAAS,OAAgB;AACvB,qBAAe;AACf,UAAI,iBAAiB,cAAc;AACjC,mBAAW;AAAA,MACb,OAAO;AACL,cAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU;AACzD,mBAAW,aAAa,KAAK,EAAE,SAAS,OAAO,OAAO,QAAQ,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,MAClF;AAAA,IACF;AAGA,QAAI,qBAAoC;AACxC,QAAI;AACF,2BAAqB,MAAM,SAAS,MAAM,EAAE,KAAK;AAAA,IACnD,QAAQ;AAAA,IAER;AAGA,QAAI,SAAS,WAAW,KAAK;AAC3B,uBAAiB,MAAM,mBAAmB;AAAA,QACxC,QAAQ,SAAS;AAAA,QACjB,MAAM;AAAA,QACN,SAAS,KAAK,UAAU,OAAO,YAAY,SAAS,QAAQ,QAAQ,CAAC,CAAC;AAAA,QACtE,aAAa,SAAS,QAAQ,IAAI,cAAc,KAAK;AAAA,MACvD,CAAC;AAAA,IACH;AAGA,QAAI,gBAAgB,EAAE,wBAAwB,eAAe;AAC3D,YAAM;AAAA,IACR;AAEA,WAAO;AAAA,EACT;AACF;","names":[]}
|