posthog-node 5.30.7 → 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/dist/extensions/express.d.ts +3 -0
- package/dist/extensions/express.d.ts.map +1 -1
- package/dist/extensions/express.js +48 -12
- package/dist/extensions/express.mjs +45 -12
- package/dist/extensions/nestjs.d.ts.map +1 -1
- package/dist/extensions/nestjs.js +17 -15
- package/dist/extensions/nestjs.mjs +17 -15
- package/dist/extensions/tracing-headers.d.ts +16 -0
- package/dist/extensions/tracing-headers.d.ts.map +1 -0
- package/dist/extensions/tracing-headers.js +85 -0
- package/dist/extensions/tracing-headers.mjs +39 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/version.mjs +1 -1
- package/package.json +2 -2
- package/src/extensions/express.ts +50 -11
- package/src/extensions/nestjs.ts +17 -17
- package/src/extensions/tracing-headers.ts +65 -0
- package/src/version.ts +1 -1
|
@@ -10,6 +10,9 @@ interface MiddlewareError extends Error {
|
|
|
10
10
|
statusCode?: number | string;
|
|
11
11
|
};
|
|
12
12
|
}
|
|
13
|
+
export declare function setupExpressRequestContext(_posthog: PostHogBackendClient, app: {
|
|
14
|
+
use: (middleware: ExpressMiddleware) => unknown;
|
|
15
|
+
}): void;
|
|
13
16
|
export declare function setupExpressErrorHandler(_posthog: PostHogBackendClient, app: {
|
|
14
17
|
use: (middleware: ExpressMiddleware | ExpressErrorMiddleware) => unknown;
|
|
15
18
|
}): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"express.d.ts","sourceRoot":"","sources":["../../src/extensions/express.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAA;
|
|
1
|
+
{"version":3,"file":"express.d.ts","sourceRoot":"","sources":["../../src/extensions/express.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAA;AAGhD,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAGhD,KAAK,iBAAiB,GAAG,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,IAAI,KAAK,IAAI,CAAA;AAEhF,KAAK,sBAAsB,GAAG,CAC5B,KAAK,EAAE,eAAe,EACtB,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,QAAQ,EACb,IAAI,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,KACnC,IAAI,CAAA;AAET,UAAU,eAAgB,SAAQ,KAAK;IACrC,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACxB,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IAC5B,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IAC7B,MAAM,CAAC,EAAE;QACP,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;KAC7B,CAAA;CACF;AA4BD,wBAAgB,0BAA0B,CACxC,QAAQ,EAAE,oBAAoB,EAC9B,GAAG,EAAE;IACH,GAAG,EAAE,CAAC,UAAU,EAAE,iBAAiB,KAAK,OAAO,CAAA;CAChD,GACA,IAAI,CAEN;AAQD,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,oBAAoB,EAC9B,GAAG,EAAE;IACH,GAAG,EAAE,CAAC,UAAU,EAAE,iBAAiB,GAAG,sBAAsB,KAAK,OAAO,CAAA;CACzE,GACA,IAAI,CAEN"}
|
|
@@ -33,18 +33,53 @@ var __webpack_require__ = {};
|
|
|
33
33
|
var __webpack_exports__ = {};
|
|
34
34
|
__webpack_require__.r(__webpack_exports__);
|
|
35
35
|
__webpack_require__.d(__webpack_exports__, {
|
|
36
|
+
setupExpressRequestContext: ()=>setupExpressRequestContext,
|
|
36
37
|
setupExpressErrorHandler: ()=>setupExpressErrorHandler
|
|
37
38
|
});
|
|
38
39
|
const index_js_namespaceObject = require("./error-tracking/index.js");
|
|
39
40
|
var index_js_default = /*#__PURE__*/ __webpack_require__.n(index_js_namespaceObject);
|
|
41
|
+
const external_tracing_headers_js_namespaceObject = require("./tracing-headers.js");
|
|
42
|
+
function getClientIp(req) {
|
|
43
|
+
const forwarded = (0, external_tracing_headers_js_namespaceObject.getFirstHeaderValue)(req.headers['x-forwarded-for']);
|
|
44
|
+
if (forwarded) {
|
|
45
|
+
const ip = forwarded.split(',')[0].trim();
|
|
46
|
+
if (ip) return ip;
|
|
47
|
+
}
|
|
48
|
+
return req.socket?.remoteAddress;
|
|
49
|
+
}
|
|
50
|
+
function buildRequestContextData(req) {
|
|
51
|
+
const { sessionId, distinctId } = (0, external_tracing_headers_js_namespaceObject.getPostHogTracingHeaderValues)(req.headers);
|
|
52
|
+
const properties = {};
|
|
53
|
+
(0, external_tracing_headers_js_namespaceObject.addProperty)(properties, '$current_url', req.originalUrl || req.url);
|
|
54
|
+
(0, external_tracing_headers_js_namespaceObject.addProperty)(properties, '$request_method', req.method);
|
|
55
|
+
(0, external_tracing_headers_js_namespaceObject.addProperty)(properties, '$request_path', req.path);
|
|
56
|
+
(0, external_tracing_headers_js_namespaceObject.addProperty)(properties, '$user_agent', (0, external_tracing_headers_js_namespaceObject.getFirstHeaderValue)(req.headers['user-agent']));
|
|
57
|
+
(0, external_tracing_headers_js_namespaceObject.addProperty)(properties, '$ip', getClientIp(req));
|
|
58
|
+
return {
|
|
59
|
+
...void 0 !== sessionId ? {
|
|
60
|
+
sessionId
|
|
61
|
+
} : {},
|
|
62
|
+
...void 0 !== distinctId ? {
|
|
63
|
+
distinctId
|
|
64
|
+
} : {},
|
|
65
|
+
properties
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
function setupExpressRequestContext(_posthog, app) {
|
|
69
|
+
app.use(posthogRequestContext(_posthog));
|
|
70
|
+
}
|
|
71
|
+
function posthogRequestContext(posthog) {
|
|
72
|
+
return (req, _res, next)=>{
|
|
73
|
+
posthog.withContext(buildRequestContextData(req), ()=>next());
|
|
74
|
+
};
|
|
75
|
+
}
|
|
40
76
|
function setupExpressErrorHandler(_posthog, app) {
|
|
41
77
|
app.use(posthogErrorHandler(_posthog));
|
|
42
78
|
}
|
|
43
79
|
function posthogErrorHandler(posthog) {
|
|
44
80
|
return (error, req, res, next)=>{
|
|
45
81
|
if (index_js_default().isPreviouslyCapturedError(error)) return void next(error);
|
|
46
|
-
const
|
|
47
|
-
const distinctId = req.headers['x-posthog-distinct-id'];
|
|
82
|
+
const contextData = buildRequestContextData(req);
|
|
48
83
|
const syntheticException = new Error('Synthetic exception');
|
|
49
84
|
const hint = {
|
|
50
85
|
mechanism: {
|
|
@@ -53,23 +88,24 @@ function posthogErrorHandler(posthog) {
|
|
|
53
88
|
},
|
|
54
89
|
syntheticException
|
|
55
90
|
};
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
$
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
}).then((msg)=>{
|
|
91
|
+
const additionalProperties = {
|
|
92
|
+
...void 0 !== contextData.sessionId ? {
|
|
93
|
+
$session_id: contextData.sessionId
|
|
94
|
+
} : {},
|
|
95
|
+
...contextData.properties || {},
|
|
96
|
+
$response_status_code: res.statusCode
|
|
97
|
+
};
|
|
98
|
+
posthog.addPendingPromise(index_js_default().buildEventMessage(error, hint, contextData.distinctId, additionalProperties).then((msg)=>{
|
|
65
99
|
posthog.capture(msg);
|
|
66
100
|
}));
|
|
67
101
|
next(error);
|
|
68
102
|
};
|
|
69
103
|
}
|
|
70
104
|
exports.setupExpressErrorHandler = __webpack_exports__.setupExpressErrorHandler;
|
|
105
|
+
exports.setupExpressRequestContext = __webpack_exports__.setupExpressRequestContext;
|
|
71
106
|
for(var __webpack_i__ in __webpack_exports__)if (-1 === [
|
|
72
|
-
"setupExpressErrorHandler"
|
|
107
|
+
"setupExpressErrorHandler",
|
|
108
|
+
"setupExpressRequestContext"
|
|
73
109
|
].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
|
|
74
110
|
Object.defineProperty(exports, '__esModule', {
|
|
75
111
|
value: true
|
|
@@ -1,12 +1,46 @@
|
|
|
1
1
|
import error_tracking from "./error-tracking/index.mjs";
|
|
2
|
+
import { addProperty, getFirstHeaderValue, getPostHogTracingHeaderValues } from "./tracing-headers.mjs";
|
|
3
|
+
function getClientIp(req) {
|
|
4
|
+
const forwarded = getFirstHeaderValue(req.headers['x-forwarded-for']);
|
|
5
|
+
if (forwarded) {
|
|
6
|
+
const ip = forwarded.split(',')[0].trim();
|
|
7
|
+
if (ip) return ip;
|
|
8
|
+
}
|
|
9
|
+
return req.socket?.remoteAddress;
|
|
10
|
+
}
|
|
11
|
+
function buildRequestContextData(req) {
|
|
12
|
+
const { sessionId, distinctId } = getPostHogTracingHeaderValues(req.headers);
|
|
13
|
+
const properties = {};
|
|
14
|
+
addProperty(properties, '$current_url', req.originalUrl || req.url);
|
|
15
|
+
addProperty(properties, '$request_method', req.method);
|
|
16
|
+
addProperty(properties, '$request_path', req.path);
|
|
17
|
+
addProperty(properties, '$user_agent', getFirstHeaderValue(req.headers['user-agent']));
|
|
18
|
+
addProperty(properties, '$ip', getClientIp(req));
|
|
19
|
+
return {
|
|
20
|
+
...void 0 !== sessionId ? {
|
|
21
|
+
sessionId
|
|
22
|
+
} : {},
|
|
23
|
+
...void 0 !== distinctId ? {
|
|
24
|
+
distinctId
|
|
25
|
+
} : {},
|
|
26
|
+
properties
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
function setupExpressRequestContext(_posthog, app) {
|
|
30
|
+
app.use(posthogRequestContext(_posthog));
|
|
31
|
+
}
|
|
32
|
+
function posthogRequestContext(posthog) {
|
|
33
|
+
return (req, _res, next)=>{
|
|
34
|
+
posthog.withContext(buildRequestContextData(req), ()=>next());
|
|
35
|
+
};
|
|
36
|
+
}
|
|
2
37
|
function setupExpressErrorHandler(_posthog, app) {
|
|
3
38
|
app.use(posthogErrorHandler(_posthog));
|
|
4
39
|
}
|
|
5
40
|
function posthogErrorHandler(posthog) {
|
|
6
41
|
return (error, req, res, next)=>{
|
|
7
42
|
if (error_tracking.isPreviouslyCapturedError(error)) return void next(error);
|
|
8
|
-
const
|
|
9
|
-
const distinctId = req.headers['x-posthog-distinct-id'];
|
|
43
|
+
const contextData = buildRequestContextData(req);
|
|
10
44
|
const syntheticException = new Error('Synthetic exception');
|
|
11
45
|
const hint = {
|
|
12
46
|
mechanism: {
|
|
@@ -15,18 +49,17 @@ function posthogErrorHandler(posthog) {
|
|
|
15
49
|
},
|
|
16
50
|
syntheticException
|
|
17
51
|
};
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
$
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
}).then((msg)=>{
|
|
52
|
+
const additionalProperties = {
|
|
53
|
+
...void 0 !== contextData.sessionId ? {
|
|
54
|
+
$session_id: contextData.sessionId
|
|
55
|
+
} : {},
|
|
56
|
+
...contextData.properties || {},
|
|
57
|
+
$response_status_code: res.statusCode
|
|
58
|
+
};
|
|
59
|
+
posthog.addPendingPromise(error_tracking.buildEventMessage(error, hint, contextData.distinctId, additionalProperties).then((msg)=>{
|
|
27
60
|
posthog.capture(msg);
|
|
28
61
|
}));
|
|
29
62
|
next(error);
|
|
30
63
|
};
|
|
31
64
|
}
|
|
32
|
-
export { setupExpressErrorHandler };
|
|
65
|
+
export { setupExpressErrorHandler, setupExpressRequestContext };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nestjs.d.ts","sourceRoot":"","sources":["../../src/extensions/nestjs.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"nestjs.d.ts","sourceRoot":"","sources":["../../src/extensions/nestjs.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAc,MAAM,MAAM,CAAA;AAK7C,OAAO,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAA;AAGhD,UAAU,iBAAiB;IACzB,UAAU,CAAC,CAAC,GAAG,GAAG,KAAK,CAAC,CAAA;IACxB,WAAW,CAAC,CAAC,GAAG,GAAG,KAAK,CAAC,CAAA;CAC1B;AAED,UAAU,gBAAgB;IACxB,YAAY,IAAI,iBAAiB,CAAA;CAClC;AAED,UAAU,WAAW,CAAC,CAAC,GAAG,GAAG;IAC3B,MAAM,IAAI,UAAU,CAAC,CAAC,CAAC,CAAA;CACxB;AAED,UAAU,eAAe,CAAC,CAAC,GAAG,GAAG,EAAE,CAAC,GAAG,GAAG;IACxC,SAAS,CAAC,OAAO,EAAE,gBAAgB,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,CAAA;CAC1E;AAED,MAAM,WAAW,uBAAuB;IACtC,+GAA+G;IAC/G,kBAAkB,CAAC,EAAE,MAAM,CAAA;CAC5B;AAED,MAAM,WAAW,yBAAyB;IACxC,mGAAmG;IACnG,iBAAiB,CAAC,EAAE,OAAO,GAAG,uBAAuB,CAAA;CACtD;AAwBD,qBAAa,kBAAmB,YAAW,eAAe;IACxD,OAAO,CAAC,OAAO,CAAsB;IACrC,OAAO,CAAC,iBAAiB,CAAS;IAClC,OAAO,CAAC,kBAAkB,CAAQ;gBAEtB,OAAO,EAAE,oBAAoB,EAAE,OAAO,CAAC,EAAE,yBAAyB;IAO9E,SAAS,CAAC,OAAO,EAAE,gBAAgB,EAAE,IAAI,EAAE,WAAW,GAAG,UAAU,CAAC,GAAG,CAAC;CA+CzE"}
|
|
@@ -39,10 +39,11 @@ const external_rxjs_namespaceObject = require("rxjs");
|
|
|
39
39
|
const operators_namespaceObject = require("rxjs/operators");
|
|
40
40
|
const index_js_namespaceObject = require("./error-tracking/index.js");
|
|
41
41
|
var index_js_default = /*#__PURE__*/ __webpack_require__.n(index_js_namespaceObject);
|
|
42
|
+
const external_tracing_headers_js_namespaceObject = require("./tracing-headers.js");
|
|
42
43
|
function getClientIp(headers, request) {
|
|
43
|
-
const forwarded = headers['x-forwarded-for'];
|
|
44
|
+
const forwarded = (0, external_tracing_headers_js_namespaceObject.getFirstHeaderValue)(headers['x-forwarded-for']);
|
|
44
45
|
if (forwarded) {
|
|
45
|
-
const ip =
|
|
46
|
+
const ip = forwarded.split(',')[0].trim();
|
|
46
47
|
if (ip) return ip;
|
|
47
48
|
}
|
|
48
49
|
return request?.socket?.remoteAddress;
|
|
@@ -65,20 +66,21 @@ class PostHogInterceptor {
|
|
|
65
66
|
const request = httpHost.getRequest();
|
|
66
67
|
const response = httpHost.getResponse();
|
|
67
68
|
const headers = request?.headers ?? {};
|
|
68
|
-
const sessionId = headers
|
|
69
|
-
const
|
|
70
|
-
|
|
69
|
+
const { sessionId, distinctId } = (0, external_tracing_headers_js_namespaceObject.getPostHogTracingHeaderValues)(headers);
|
|
70
|
+
const properties = {};
|
|
71
|
+
(0, external_tracing_headers_js_namespaceObject.addProperty)(properties, '$current_url', request?.url);
|
|
72
|
+
(0, external_tracing_headers_js_namespaceObject.addProperty)(properties, '$request_method', request?.method);
|
|
73
|
+
(0, external_tracing_headers_js_namespaceObject.addProperty)(properties, '$request_path', request?.path ?? request?.url);
|
|
74
|
+
(0, external_tracing_headers_js_namespaceObject.addProperty)(properties, '$user_agent', (0, external_tracing_headers_js_namespaceObject.getFirstHeaderValue)(headers['user-agent']));
|
|
75
|
+
(0, external_tracing_headers_js_namespaceObject.addProperty)(properties, '$ip', getClientIp(headers, request));
|
|
71
76
|
const contextData = {
|
|
72
|
-
sessionId
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
$user_agent: headers['user-agent'],
|
|
80
|
-
$ip: getClientIp(headers, request)
|
|
81
|
-
}
|
|
77
|
+
...void 0 !== sessionId ? {
|
|
78
|
+
sessionId
|
|
79
|
+
} : {},
|
|
80
|
+
...void 0 !== distinctId ? {
|
|
81
|
+
distinctId
|
|
82
|
+
} : {},
|
|
83
|
+
properties
|
|
82
84
|
};
|
|
83
85
|
this.posthog.enterContext(contextData);
|
|
84
86
|
let source = next.handle();
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { throwError } from "rxjs";
|
|
2
2
|
import { catchError } from "rxjs/operators";
|
|
3
3
|
import error_tracking from "./error-tracking/index.mjs";
|
|
4
|
+
import { addProperty, getFirstHeaderValue, getPostHogTracingHeaderValues } from "./tracing-headers.mjs";
|
|
4
5
|
function getClientIp(headers, request) {
|
|
5
|
-
const forwarded = headers['x-forwarded-for'];
|
|
6
|
+
const forwarded = getFirstHeaderValue(headers['x-forwarded-for']);
|
|
6
7
|
if (forwarded) {
|
|
7
|
-
const ip =
|
|
8
|
+
const ip = forwarded.split(',')[0].trim();
|
|
8
9
|
if (ip) return ip;
|
|
9
10
|
}
|
|
10
11
|
return request?.socket?.remoteAddress;
|
|
@@ -27,20 +28,21 @@ class PostHogInterceptor {
|
|
|
27
28
|
const request = httpHost.getRequest();
|
|
28
29
|
const response = httpHost.getResponse();
|
|
29
30
|
const headers = request?.headers ?? {};
|
|
30
|
-
const sessionId = headers
|
|
31
|
-
const
|
|
32
|
-
|
|
31
|
+
const { sessionId, distinctId } = getPostHogTracingHeaderValues(headers);
|
|
32
|
+
const properties = {};
|
|
33
|
+
addProperty(properties, '$current_url', request?.url);
|
|
34
|
+
addProperty(properties, '$request_method', request?.method);
|
|
35
|
+
addProperty(properties, '$request_path', request?.path ?? request?.url);
|
|
36
|
+
addProperty(properties, '$user_agent', getFirstHeaderValue(headers['user-agent']));
|
|
37
|
+
addProperty(properties, '$ip', getClientIp(headers, request));
|
|
33
38
|
const contextData = {
|
|
34
|
-
sessionId
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
$user_agent: headers['user-agent'],
|
|
42
|
-
$ip: getClientIp(headers, request)
|
|
43
|
-
}
|
|
39
|
+
...void 0 !== sessionId ? {
|
|
40
|
+
sessionId
|
|
41
|
+
} : {},
|
|
42
|
+
...void 0 !== distinctId ? {
|
|
43
|
+
distinctId
|
|
44
|
+
} : {},
|
|
45
|
+
properties
|
|
44
46
|
};
|
|
45
47
|
this.posthog.enterContext(contextData);
|
|
46
48
|
let source = next.handle();
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { IncomingHttpHeaders } from 'node:http';
|
|
2
|
+
type HeaderValue = IncomingHttpHeaders[string];
|
|
3
|
+
export declare const POSTHOG_TRACING_HEADERS: {
|
|
4
|
+
readonly sessionId: "x-posthog-session-id";
|
|
5
|
+
readonly distinctId: "x-posthog-distinct-id";
|
|
6
|
+
};
|
|
7
|
+
export interface PostHogTracingHeaderValues {
|
|
8
|
+
sessionId?: string;
|
|
9
|
+
distinctId?: string;
|
|
10
|
+
}
|
|
11
|
+
export declare function addProperty(properties: Record<string, any>, key: string, value: unknown): void;
|
|
12
|
+
export declare function getFirstHeaderValue(value: HeaderValue): string | undefined;
|
|
13
|
+
export declare function sanitizeTracingHeaderValue(value: HeaderValue): string | undefined;
|
|
14
|
+
export declare function getPostHogTracingHeaderValues(headers?: IncomingHttpHeaders): PostHogTracingHeaderValues;
|
|
15
|
+
export {};
|
|
16
|
+
//# sourceMappingURL=tracing-headers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tracing-headers.d.ts","sourceRoot":"","sources":["../../src/extensions/tracing-headers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAA;AAOpD,KAAK,WAAW,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAA;AAE9C,eAAO,MAAM,uBAAuB;;;CAG1B,CAAA;AAEV,MAAM,WAAW,0BAA0B;IACzC,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAED,wBAAgB,WAAW,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAI9F;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,GAAG,SAAS,CAE1E;AAED,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,GAAG,SAAS,CAqBjF;AAED,wBAAgB,6BAA6B,CAAC,OAAO,CAAC,EAAE,mBAAmB,GAAG,0BAA0B,CAYvG"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __webpack_require__ = {};
|
|
3
|
+
(()=>{
|
|
4
|
+
__webpack_require__.d = (exports1, definition)=>{
|
|
5
|
+
for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: definition[key]
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
})();
|
|
11
|
+
(()=>{
|
|
12
|
+
__webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
|
|
13
|
+
})();
|
|
14
|
+
(()=>{
|
|
15
|
+
__webpack_require__.r = (exports1)=>{
|
|
16
|
+
if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
|
|
17
|
+
value: 'Module'
|
|
18
|
+
});
|
|
19
|
+
Object.defineProperty(exports1, '__esModule', {
|
|
20
|
+
value: true
|
|
21
|
+
});
|
|
22
|
+
};
|
|
23
|
+
})();
|
|
24
|
+
var __webpack_exports__ = {};
|
|
25
|
+
__webpack_require__.r(__webpack_exports__);
|
|
26
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
27
|
+
POSTHOG_TRACING_HEADERS: ()=>POSTHOG_TRACING_HEADERS,
|
|
28
|
+
addProperty: ()=>addProperty,
|
|
29
|
+
getFirstHeaderValue: ()=>getFirstHeaderValue,
|
|
30
|
+
getPostHogTracingHeaderValues: ()=>getPostHogTracingHeaderValues,
|
|
31
|
+
sanitizeTracingHeaderValue: ()=>sanitizeTracingHeaderValue
|
|
32
|
+
});
|
|
33
|
+
const TRACING_HEADER_MAX_LENGTH = 1000;
|
|
34
|
+
const TRACING_HEADER_CONTROL_CHARS_REGEX = /[\x00-\x1f\x7f-\x9f]/g;
|
|
35
|
+
const POSTHOG_TRACING_HEADERS = {
|
|
36
|
+
sessionId: 'x-posthog-session-id',
|
|
37
|
+
distinctId: 'x-posthog-distinct-id'
|
|
38
|
+
};
|
|
39
|
+
function addProperty(properties, key, value) {
|
|
40
|
+
if (null != value && '' !== value) properties[key] = value;
|
|
41
|
+
}
|
|
42
|
+
function getFirstHeaderValue(value) {
|
|
43
|
+
return Array.isArray(value) ? value[0] : value;
|
|
44
|
+
}
|
|
45
|
+
function sanitizeTracingHeaderValue(value) {
|
|
46
|
+
if (Array.isArray(value)) {
|
|
47
|
+
for (const item of value){
|
|
48
|
+
const sanitized = sanitizeTracingHeaderValue(item);
|
|
49
|
+
if (void 0 !== sanitized) return sanitized;
|
|
50
|
+
}
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
if ('string' != typeof value) return;
|
|
54
|
+
const sanitized = value.replace(TRACING_HEADER_CONTROL_CHARS_REGEX, '').trim();
|
|
55
|
+
if (!sanitized) return;
|
|
56
|
+
return sanitized.length > TRACING_HEADER_MAX_LENGTH ? sanitized.slice(0, TRACING_HEADER_MAX_LENGTH) : sanitized;
|
|
57
|
+
}
|
|
58
|
+
function getPostHogTracingHeaderValues(headers) {
|
|
59
|
+
if (!headers) return {};
|
|
60
|
+
const sessionId = sanitizeTracingHeaderValue(headers[POSTHOG_TRACING_HEADERS.sessionId]);
|
|
61
|
+
const distinctId = sanitizeTracingHeaderValue(headers[POSTHOG_TRACING_HEADERS.distinctId]);
|
|
62
|
+
return {
|
|
63
|
+
...void 0 !== sessionId ? {
|
|
64
|
+
sessionId
|
|
65
|
+
} : {},
|
|
66
|
+
...void 0 !== distinctId ? {
|
|
67
|
+
distinctId
|
|
68
|
+
} : {}
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
exports.POSTHOG_TRACING_HEADERS = __webpack_exports__.POSTHOG_TRACING_HEADERS;
|
|
72
|
+
exports.addProperty = __webpack_exports__.addProperty;
|
|
73
|
+
exports.getFirstHeaderValue = __webpack_exports__.getFirstHeaderValue;
|
|
74
|
+
exports.getPostHogTracingHeaderValues = __webpack_exports__.getPostHogTracingHeaderValues;
|
|
75
|
+
exports.sanitizeTracingHeaderValue = __webpack_exports__.sanitizeTracingHeaderValue;
|
|
76
|
+
for(var __webpack_i__ in __webpack_exports__)if (-1 === [
|
|
77
|
+
"POSTHOG_TRACING_HEADERS",
|
|
78
|
+
"addProperty",
|
|
79
|
+
"getFirstHeaderValue",
|
|
80
|
+
"getPostHogTracingHeaderValues",
|
|
81
|
+
"sanitizeTracingHeaderValue"
|
|
82
|
+
].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
|
|
83
|
+
Object.defineProperty(exports, '__esModule', {
|
|
84
|
+
value: true
|
|
85
|
+
});
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
const TRACING_HEADER_MAX_LENGTH = 1000;
|
|
2
|
+
const TRACING_HEADER_CONTROL_CHARS_REGEX = /[\x00-\x1f\x7f-\x9f]/g;
|
|
3
|
+
const POSTHOG_TRACING_HEADERS = {
|
|
4
|
+
sessionId: 'x-posthog-session-id',
|
|
5
|
+
distinctId: 'x-posthog-distinct-id'
|
|
6
|
+
};
|
|
7
|
+
function addProperty(properties, key, value) {
|
|
8
|
+
if (null != value && '' !== value) properties[key] = value;
|
|
9
|
+
}
|
|
10
|
+
function getFirstHeaderValue(value) {
|
|
11
|
+
return Array.isArray(value) ? value[0] : value;
|
|
12
|
+
}
|
|
13
|
+
function sanitizeTracingHeaderValue(value) {
|
|
14
|
+
if (Array.isArray(value)) {
|
|
15
|
+
for (const item of value){
|
|
16
|
+
const sanitized = sanitizeTracingHeaderValue(item);
|
|
17
|
+
if (void 0 !== sanitized) return sanitized;
|
|
18
|
+
}
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
if ('string' != typeof value) return;
|
|
22
|
+
const sanitized = value.replace(TRACING_HEADER_CONTROL_CHARS_REGEX, '').trim();
|
|
23
|
+
if (!sanitized) return;
|
|
24
|
+
return sanitized.length > TRACING_HEADER_MAX_LENGTH ? sanitized.slice(0, TRACING_HEADER_MAX_LENGTH) : sanitized;
|
|
25
|
+
}
|
|
26
|
+
function getPostHogTracingHeaderValues(headers) {
|
|
27
|
+
if (!headers) return {};
|
|
28
|
+
const sessionId = sanitizeTracingHeaderValue(headers[POSTHOG_TRACING_HEADERS.sessionId]);
|
|
29
|
+
const distinctId = sanitizeTracingHeaderValue(headers[POSTHOG_TRACING_HEADERS.distinctId]);
|
|
30
|
+
return {
|
|
31
|
+
...void 0 !== sessionId ? {
|
|
32
|
+
sessionId
|
|
33
|
+
} : {},
|
|
34
|
+
...void 0 !== distinctId ? {
|
|
35
|
+
distinctId
|
|
36
|
+
} : {}
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
export { POSTHOG_TRACING_HEADERS, addProperty, getFirstHeaderValue, getPostHogTracingHeaderValues, sanitizeTracingHeaderValue };
|
package/dist/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const version = "5.
|
|
1
|
+
export declare const version = "5.31.0";
|
|
2
2
|
//# sourceMappingURL=version.d.ts.map
|
package/dist/version.js
CHANGED
|
@@ -26,7 +26,7 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
26
26
|
__webpack_require__.d(__webpack_exports__, {
|
|
27
27
|
version: ()=>version
|
|
28
28
|
});
|
|
29
|
-
const version = '5.
|
|
29
|
+
const version = '5.31.0';
|
|
30
30
|
exports.version = __webpack_exports__.version;
|
|
31
31
|
for(var __webpack_i__ in __webpack_exports__)if (-1 === [
|
|
32
32
|
"version"
|
package/dist/version.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const version = '5.
|
|
1
|
+
const version = '5.31.0';
|
|
2
2
|
export { version };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "posthog-node",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.31.0",
|
|
4
4
|
"description": "PostHog Node.js integration",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"module": "dist/entrypoints/index.node.mjs",
|
|
26
26
|
"types": "dist/entrypoints/index.node.d.ts",
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@posthog/core": "1.27.
|
|
28
|
+
"@posthog/core": "1.27.9"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
31
|
"@edge-runtime/jest-environment": "^4.0.0",
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import ErrorTracking from './error-tracking'
|
|
2
2
|
import { PostHogBackendClient } from '../client'
|
|
3
3
|
import { ErrorTracking as CoreErrorTracking } from '@posthog/core'
|
|
4
|
+
import { addProperty, getFirstHeaderValue, getPostHogTracingHeaderValues } from './tracing-headers'
|
|
4
5
|
import type { Request, Response } from 'express'
|
|
6
|
+
import type { ContextData } from './context/types'
|
|
5
7
|
|
|
6
8
|
type ExpressMiddleware = (req: Request, res: Response, next: () => void) => void
|
|
7
9
|
|
|
@@ -21,6 +23,47 @@ interface MiddlewareError extends Error {
|
|
|
21
23
|
}
|
|
22
24
|
}
|
|
23
25
|
|
|
26
|
+
function getClientIp(req: Request): string | undefined {
|
|
27
|
+
const forwarded = getFirstHeaderValue(req.headers['x-forwarded-for'])
|
|
28
|
+
if (forwarded) {
|
|
29
|
+
const ip = forwarded.split(',')[0].trim()
|
|
30
|
+
if (ip) return ip
|
|
31
|
+
}
|
|
32
|
+
return req.socket?.remoteAddress
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function buildRequestContextData(req: Request): Partial<ContextData> {
|
|
36
|
+
const { sessionId, distinctId } = getPostHogTracingHeaderValues(req.headers)
|
|
37
|
+
const properties: Record<string, any> = {}
|
|
38
|
+
|
|
39
|
+
addProperty(properties, '$current_url', req.originalUrl || req.url)
|
|
40
|
+
addProperty(properties, '$request_method', req.method)
|
|
41
|
+
addProperty(properties, '$request_path', req.path)
|
|
42
|
+
addProperty(properties, '$user_agent', getFirstHeaderValue(req.headers['user-agent']))
|
|
43
|
+
addProperty(properties, '$ip', getClientIp(req))
|
|
44
|
+
|
|
45
|
+
return {
|
|
46
|
+
...(sessionId !== undefined ? { sessionId } : {}),
|
|
47
|
+
...(distinctId !== undefined ? { distinctId } : {}),
|
|
48
|
+
properties,
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export function setupExpressRequestContext(
|
|
53
|
+
_posthog: PostHogBackendClient,
|
|
54
|
+
app: {
|
|
55
|
+
use: (middleware: ExpressMiddleware) => unknown
|
|
56
|
+
}
|
|
57
|
+
): void {
|
|
58
|
+
app.use(posthogRequestContext(_posthog))
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function posthogRequestContext(posthog: PostHogBackendClient): ExpressMiddleware {
|
|
62
|
+
return (req, _res, next): void => {
|
|
63
|
+
posthog.withContext(buildRequestContextData(req), () => next())
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
24
67
|
export function setupExpressErrorHandler(
|
|
25
68
|
_posthog: PostHogBackendClient,
|
|
26
69
|
app: {
|
|
@@ -37,21 +80,17 @@ function posthogErrorHandler(posthog: PostHogBackendClient): ExpressErrorMiddlew
|
|
|
37
80
|
return
|
|
38
81
|
}
|
|
39
82
|
|
|
40
|
-
const
|
|
41
|
-
const distinctId: string | undefined = req.headers['x-posthog-distinct-id'] as string | undefined
|
|
83
|
+
const contextData = buildRequestContextData(req)
|
|
42
84
|
const syntheticException = new Error('Synthetic exception')
|
|
43
85
|
const hint: CoreErrorTracking.EventHint = { mechanism: { type: 'middleware', handled: false }, syntheticException }
|
|
86
|
+
const additionalProperties: Record<string, any> = {
|
|
87
|
+
...(contextData.sessionId !== undefined ? { $session_id: contextData.sessionId } : {}),
|
|
88
|
+
...(contextData.properties || {}),
|
|
89
|
+
$response_status_code: res.statusCode,
|
|
90
|
+
}
|
|
44
91
|
|
|
45
92
|
posthog.addPendingPromise(
|
|
46
|
-
ErrorTracking.buildEventMessage(error, hint, distinctId, {
|
|
47
|
-
$session_id: sessionId,
|
|
48
|
-
$current_url: req.url,
|
|
49
|
-
$request_method: req.method,
|
|
50
|
-
$request_path: req.path,
|
|
51
|
-
$user_agent: req.headers['user-agent'],
|
|
52
|
-
$response_status_code: res.statusCode,
|
|
53
|
-
$ip: req.headers['x-forwarded-for'] || req?.socket?.remoteAddress,
|
|
54
|
-
}).then((msg) => {
|
|
93
|
+
ErrorTracking.buildEventMessage(error, hint, contextData.distinctId, additionalProperties).then((msg) => {
|
|
55
94
|
posthog.capture(msg)
|
|
56
95
|
})
|
|
57
96
|
)
|
package/src/extensions/nestjs.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import type { IncomingHttpHeaders } from 'node:http'
|
|
1
2
|
import { Observable, throwError } from 'rxjs'
|
|
2
3
|
import { catchError } from 'rxjs/operators'
|
|
3
4
|
|
|
4
5
|
import ErrorTracking from './error-tracking'
|
|
6
|
+
import { addProperty, getFirstHeaderValue, getPostHogTracingHeaderValues } from './tracing-headers'
|
|
5
7
|
import { PostHogBackendClient } from '../client'
|
|
6
8
|
|
|
7
9
|
// Local interfaces to avoid runtime dependency on @nestjs/common
|
|
@@ -32,10 +34,10 @@ export interface PostHogInterceptorOptions {
|
|
|
32
34
|
captureExceptions?: boolean | ExceptionCaptureOptions
|
|
33
35
|
}
|
|
34
36
|
|
|
35
|
-
function getClientIp(headers:
|
|
36
|
-
const forwarded = headers['x-forwarded-for']
|
|
37
|
+
function getClientIp(headers: IncomingHttpHeaders, request: any): string | undefined {
|
|
38
|
+
const forwarded = getFirstHeaderValue(headers['x-forwarded-for'])
|
|
37
39
|
if (forwarded) {
|
|
38
|
-
const ip =
|
|
40
|
+
const ip = forwarded.split(',')[0].trim()
|
|
39
41
|
if (ip) return ip
|
|
40
42
|
}
|
|
41
43
|
return request?.socket?.remoteAddress
|
|
@@ -71,22 +73,20 @@ export class PostHogInterceptor implements NestInterceptor {
|
|
|
71
73
|
const request = httpHost.getRequest()
|
|
72
74
|
const response = httpHost.getResponse()
|
|
73
75
|
|
|
74
|
-
const headers = request?.headers ?? {}
|
|
75
|
-
const sessionId
|
|
76
|
-
|
|
77
|
-
const
|
|
76
|
+
const headers = (request?.headers ?? {}) as IncomingHttpHeaders
|
|
77
|
+
const { sessionId, distinctId } = getPostHogTracingHeaderValues(headers)
|
|
78
|
+
|
|
79
|
+
const properties: Record<string, any> = {}
|
|
80
|
+
addProperty(properties, '$current_url', request?.url)
|
|
81
|
+
addProperty(properties, '$request_method', request?.method)
|
|
82
|
+
addProperty(properties, '$request_path', request?.path ?? request?.url)
|
|
83
|
+
addProperty(properties, '$user_agent', getFirstHeaderValue(headers['user-agent']))
|
|
84
|
+
addProperty(properties, '$ip', getClientIp(headers, request))
|
|
78
85
|
|
|
79
86
|
const contextData = {
|
|
80
|
-
sessionId,
|
|
81
|
-
distinctId,
|
|
82
|
-
properties
|
|
83
|
-
$current_url: request?.url,
|
|
84
|
-
$request_method: request?.method,
|
|
85
|
-
$request_path: request?.path ?? request?.url,
|
|
86
|
-
$window_id: windowId,
|
|
87
|
-
$user_agent: headers['user-agent'],
|
|
88
|
-
$ip: getClientIp(headers, request),
|
|
89
|
-
},
|
|
87
|
+
...(sessionId !== undefined ? { sessionId } : {}),
|
|
88
|
+
...(distinctId !== undefined ? { distinctId } : {}),
|
|
89
|
+
properties,
|
|
90
90
|
}
|
|
91
91
|
|
|
92
92
|
// Use enterContext so the context propagates through RxJS Observable
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import type { IncomingHttpHeaders } from 'node:http'
|
|
2
|
+
|
|
3
|
+
const TRACING_HEADER_MAX_LENGTH = 1000
|
|
4
|
+
// Remove C0 controls, DEL, and C1 controls from PostHog tracing IDs only.
|
|
5
|
+
// eslint-disable-next-line no-control-regex
|
|
6
|
+
const TRACING_HEADER_CONTROL_CHARS_REGEX = /[\x00-\x1f\x7f-\x9f]/g
|
|
7
|
+
|
|
8
|
+
type HeaderValue = IncomingHttpHeaders[string]
|
|
9
|
+
|
|
10
|
+
export const POSTHOG_TRACING_HEADERS = {
|
|
11
|
+
sessionId: 'x-posthog-session-id',
|
|
12
|
+
distinctId: 'x-posthog-distinct-id',
|
|
13
|
+
} as const
|
|
14
|
+
|
|
15
|
+
export interface PostHogTracingHeaderValues {
|
|
16
|
+
sessionId?: string
|
|
17
|
+
distinctId?: string
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function addProperty(properties: Record<string, any>, key: string, value: unknown): void {
|
|
21
|
+
if (value !== undefined && value !== null && value !== '') {
|
|
22
|
+
properties[key] = value
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function getFirstHeaderValue(value: HeaderValue): string | undefined {
|
|
27
|
+
return Array.isArray(value) ? value[0] : value
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function sanitizeTracingHeaderValue(value: HeaderValue): string | undefined {
|
|
31
|
+
if (Array.isArray(value)) {
|
|
32
|
+
for (const item of value) {
|
|
33
|
+
const sanitized = sanitizeTracingHeaderValue(item)
|
|
34
|
+
if (sanitized !== undefined) {
|
|
35
|
+
return sanitized
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return undefined
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (typeof value !== 'string') {
|
|
42
|
+
return undefined
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const sanitized = value.replace(TRACING_HEADER_CONTROL_CHARS_REGEX, '').trim()
|
|
46
|
+
if (!sanitized) {
|
|
47
|
+
return undefined
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return sanitized.length > TRACING_HEADER_MAX_LENGTH ? sanitized.slice(0, TRACING_HEADER_MAX_LENGTH) : sanitized
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export function getPostHogTracingHeaderValues(headers?: IncomingHttpHeaders): PostHogTracingHeaderValues {
|
|
54
|
+
if (!headers) {
|
|
55
|
+
return {}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const sessionId = sanitizeTracingHeaderValue(headers[POSTHOG_TRACING_HEADERS.sessionId])
|
|
59
|
+
const distinctId = sanitizeTracingHeaderValue(headers[POSTHOG_TRACING_HEADERS.distinctId])
|
|
60
|
+
|
|
61
|
+
return {
|
|
62
|
+
...(sessionId !== undefined ? { sessionId } : {}),
|
|
63
|
+
...(distinctId !== undefined ? { distinctId } : {}),
|
|
64
|
+
}
|
|
65
|
+
}
|
package/src/version.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const version = '5.
|
|
1
|
+
export const version = '5.31.0'
|