posthog-node 4.11.2 → 4.11.3
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 +5 -3
- package/lib/index.cjs.js +89 -62
- package/lib/index.cjs.js.map +1 -1
- package/lib/index.esm.js +89 -62
- package/lib/index.esm.js.map +1 -1
- package/lib/posthog-node/src/extensions/error-tracking/context-lines.d.ts +2 -0
- package/package.json +1 -1
- package/src/extensions/error-tracking/context-lines.ts +97 -64
package/CHANGELOG.md
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
|
+
# 4.11.3 - 2025-04-08
|
|
2
|
+
|
|
3
|
+
1. fix: do not access `fs` or `readline` in when not available e.g. edge environments
|
|
4
|
+
|
|
1
5
|
# 4.11.2 - 2025-04-07
|
|
2
6
|
|
|
3
7
|
1. chore: bump axios to 1.8.2 (fixes [CVE-2025-27152](https://github.com/advisories/GHSA-jr5f-v2jv-69x6))
|
|
4
8
|
|
|
5
|
-
|
|
6
9
|
# 4.11.1 - 2025-03-28
|
|
7
10
|
|
|
8
11
|
## Fixed
|
|
@@ -28,7 +31,6 @@
|
|
|
28
31
|
1. Fix: only set `platform` on PostHog exception frame properties
|
|
29
32
|
1. Fix: prevent fetch floods when rate-limited.
|
|
30
33
|
|
|
31
|
-
|
|
32
34
|
# 4.10.0 – 2025-03-06
|
|
33
35
|
|
|
34
36
|
1. Attach requestId to $feature_flag_called if present in /decide response
|
|
@@ -320,4 +322,4 @@ Breaking changes:
|
|
|
320
322
|
What's new:
|
|
321
323
|
|
|
322
324
|
1. You can now evaluate feature flags locally (i.e. without sending a request to your PostHog servers) by setting a personal API key, and passing in groups and person properties to `isFeatureEnabled` and `getFeatureFlag` calls.
|
|
323
|
-
2. Introduces a `getAllFlags` method that returns all feature flags. This is useful for when you want to seed your frontend with some initial flags, given a user ID.
|
|
325
|
+
2. Introduces a `getAllFlags` method that returns all feature flags. This is useful for when you want to seed your frontend with some initial flags, given a user ID.
|
package/lib/index.cjs.js
CHANGED
|
@@ -2,8 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
|
-
var node_fs = require('node:fs');
|
|
6
|
-
var node_readline = require('node:readline');
|
|
7
5
|
var node_path = require('node:path');
|
|
8
6
|
|
|
9
7
|
function _interopNamespace(e) {
|
|
@@ -24,7 +22,7 @@ function _interopNamespace(e) {
|
|
|
24
22
|
return Object.freeze(n);
|
|
25
23
|
}
|
|
26
24
|
|
|
27
|
-
var version = "4.11.
|
|
25
|
+
var version = "4.11.3";
|
|
28
26
|
|
|
29
27
|
var PostHogPersistedProperty;
|
|
30
28
|
(function (PostHogPersistedProperty) {
|
|
@@ -2536,6 +2534,26 @@ class ReduceableCache {
|
|
|
2536
2534
|
}
|
|
2537
2535
|
}
|
|
2538
2536
|
|
|
2537
|
+
const nodeFs = new Lazy(async () => {
|
|
2538
|
+
try {
|
|
2539
|
+
return await Promise.resolve().then(function () { return /*#__PURE__*/_interopNamespace(require('node:fs')); });
|
|
2540
|
+
} catch {
|
|
2541
|
+
return undefined;
|
|
2542
|
+
}
|
|
2543
|
+
});
|
|
2544
|
+
async function getNodeFs() {
|
|
2545
|
+
return await nodeFs.getValue();
|
|
2546
|
+
}
|
|
2547
|
+
const nodeReadline = new Lazy(async () => {
|
|
2548
|
+
try {
|
|
2549
|
+
return await Promise.resolve().then(function () { return /*#__PURE__*/_interopNamespace(require('node:readline')); });
|
|
2550
|
+
} catch {
|
|
2551
|
+
return undefined;
|
|
2552
|
+
}
|
|
2553
|
+
});
|
|
2554
|
+
async function getNodeReadline() {
|
|
2555
|
+
return await nodeReadline.getValue();
|
|
2556
|
+
}
|
|
2539
2557
|
const LRU_FILE_CONTENTS_CACHE = new ReduceableCache(25);
|
|
2540
2558
|
const LRU_FILE_CONTENTS_FS_READ_FAILED = new ReduceableCache(20);
|
|
2541
2559
|
const DEFAULT_LINES_OF_CONTEXT = 7;
|
|
@@ -2603,70 +2621,79 @@ async function addSourceContext(frames) {
|
|
|
2603
2621
|
*/
|
|
2604
2622
|
function getContextLinesFromFile(path, ranges, output) {
|
|
2605
2623
|
return new Promise(resolve => {
|
|
2606
|
-
//
|
|
2607
|
-
//
|
|
2608
|
-
//
|
|
2609
|
-
|
|
2610
|
-
|
|
2611
|
-
|
|
2612
|
-
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
stream.
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
|
|
2622
|
-
|
|
2623
|
-
|
|
2624
|
-
|
|
2625
|
-
|
|
2626
|
-
|
|
2627
|
-
|
|
2628
|
-
|
|
2629
|
-
|
|
2630
|
-
|
|
2631
|
-
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
|
|
2635
|
-
LRU_FILE_CONTENTS_FS_READ_FAILED.set(path, 1);
|
|
2636
|
-
lineReaded.close();
|
|
2637
|
-
lineReaded.removeAllListeners();
|
|
2638
|
-
destroyStreamAndResolve();
|
|
2639
|
-
}
|
|
2640
|
-
// We need to handle the error event to prevent the process from crashing in < Node 16
|
|
2641
|
-
// https://github.com/nodejs/node/pull/31603
|
|
2642
|
-
stream.on('error', onStreamError);
|
|
2643
|
-
lineReaded.on('error', onStreamError);
|
|
2644
|
-
lineReaded.on('close', destroyStreamAndResolve);
|
|
2645
|
-
lineReaded.on('line', line => {
|
|
2646
|
-
lineNumber++;
|
|
2647
|
-
if (lineNumber < rangeStart) {
|
|
2624
|
+
// KLUDGE: edge runtimes do not support node:fs or node:readline
|
|
2625
|
+
// until we have separate packages for each environment this will skip
|
|
2626
|
+
// trying to access the filesystem when not accessible
|
|
2627
|
+
Promise.all([getNodeFs(), getNodeReadline()]).then(([nodeFs, nodeReadline]) => {
|
|
2628
|
+
if (!nodeFs || !nodeReadline) {
|
|
2629
|
+
resolve();
|
|
2630
|
+
return;
|
|
2631
|
+
}
|
|
2632
|
+
// It is important *not* to have any async code between createInterface and the 'line' event listener
|
|
2633
|
+
// as it will cause the 'line' event to
|
|
2634
|
+
// be emitted before the listener is attached.
|
|
2635
|
+
const stream = nodeFs.createReadStream(path);
|
|
2636
|
+
const lineReaded = nodeReadline.createInterface({
|
|
2637
|
+
input: stream
|
|
2638
|
+
});
|
|
2639
|
+
// We need to explicitly destroy the stream to prevent memory leaks,
|
|
2640
|
+
// removing the listeners on the readline interface is not enough.
|
|
2641
|
+
// See: https://github.com/nodejs/node/issues/9002 and https://github.com/getsentry/sentry-javascript/issues/14892
|
|
2642
|
+
function destroyStreamAndResolve() {
|
|
2643
|
+
stream.destroy();
|
|
2644
|
+
resolve();
|
|
2645
|
+
}
|
|
2646
|
+
// Init at zero and increment at the start of the loop because lines are 1 indexed.
|
|
2647
|
+
let lineNumber = 0;
|
|
2648
|
+
let currentRangeIndex = 0;
|
|
2649
|
+
const range = ranges[currentRangeIndex];
|
|
2650
|
+
if (range === undefined) {
|
|
2651
|
+
// We should never reach this point, but if we do, we should resolve the promise to prevent it from hanging.
|
|
2652
|
+
destroyStreamAndResolve();
|
|
2648
2653
|
return;
|
|
2649
2654
|
}
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
if
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
2655
|
+
let rangeStart = range[0];
|
|
2656
|
+
let rangeEnd = range[1];
|
|
2657
|
+
// We use this inside Promise.all, so we need to resolve the promise even if there is an error
|
|
2658
|
+
// to prevent Promise.all from short circuiting the rest.
|
|
2659
|
+
function onStreamError() {
|
|
2660
|
+
// Mark file path as failed to read and prevent multiple read attempts.
|
|
2661
|
+
LRU_FILE_CONTENTS_FS_READ_FAILED.set(path, 1);
|
|
2662
|
+
lineReaded.close();
|
|
2663
|
+
lineReaded.removeAllListeners();
|
|
2664
|
+
destroyStreamAndResolve();
|
|
2665
|
+
}
|
|
2666
|
+
// We need to handle the error event to prevent the process from crashing in < Node 16
|
|
2667
|
+
// https://github.com/nodejs/node/pull/31603
|
|
2668
|
+
stream.on('error', onStreamError);
|
|
2669
|
+
lineReaded.on('error', onStreamError);
|
|
2670
|
+
lineReaded.on('close', destroyStreamAndResolve);
|
|
2671
|
+
lineReaded.on('line', line => {
|
|
2672
|
+
lineNumber++;
|
|
2673
|
+
if (lineNumber < rangeStart) {
|
|
2657
2674
|
return;
|
|
2658
2675
|
}
|
|
2659
|
-
|
|
2660
|
-
|
|
2661
|
-
if (
|
|
2662
|
-
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
|
|
2676
|
+
// !Warning: This mutates the cache by storing the snipped line into the cache.
|
|
2677
|
+
output[lineNumber] = snipLine(line, 0);
|
|
2678
|
+
if (lineNumber >= rangeEnd) {
|
|
2679
|
+
if (currentRangeIndex === ranges.length - 1) {
|
|
2680
|
+
// We need to close the file stream and remove listeners, else the reader will continue to run our listener;
|
|
2681
|
+
lineReaded.close();
|
|
2682
|
+
lineReaded.removeAllListeners();
|
|
2683
|
+
return;
|
|
2684
|
+
}
|
|
2685
|
+
currentRangeIndex++;
|
|
2686
|
+
const range = ranges[currentRangeIndex];
|
|
2687
|
+
if (range === undefined) {
|
|
2688
|
+
// This should never happen as it means we have a bug in the context.
|
|
2689
|
+
lineReaded.close();
|
|
2690
|
+
lineReaded.removeAllListeners();
|
|
2691
|
+
return;
|
|
2692
|
+
}
|
|
2693
|
+
rangeStart = range[0];
|
|
2694
|
+
rangeEnd = range[1];
|
|
2666
2695
|
}
|
|
2667
|
-
|
|
2668
|
-
rangeEnd = range[1];
|
|
2669
|
-
}
|
|
2696
|
+
});
|
|
2670
2697
|
});
|
|
2671
2698
|
});
|
|
2672
2699
|
}
|