oh-my-opencode 5.0.0-beta.12 → 5.0.0-beta.13
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/.agents/skills/senpi-qa/SKILL.md +80 -0
- package/.agents/skills/senpi-qa/scripts/resolve-evidence-dir.mjs +65 -0
- package/.agents/skills/senpi-qa/scripts/resolve-evidence-dir.test.mjs +171 -0
- package/dist/cli/index.js +6774 -4320
- package/dist/cli-node/index.js +6774 -4320
- package/dist/create-hooks.d.ts +1 -0
- package/dist/features/btw-side/btw-command-draft.d.ts +7 -0
- package/dist/features/btw-side/context-injector.d.ts +15 -0
- package/dist/features/btw-side/index.d.ts +8 -0
- package/dist/features/btw-side/metadata.d.ts +15 -0
- package/dist/features/btw-side/parent-context-budget.d.ts +9 -0
- package/dist/features/btw-side/server-session-registry.d.ts +8 -0
- package/dist/features/btw-side/tui-adoption-cache.d.ts +13 -0
- package/dist/features/btw-side/tui-adoption-guard.d.ts +5 -0
- package/dist/features/btw-side/tui-controller-types.d.ts +63 -0
- package/dist/features/btw-side/tui-controller.d.ts +14 -0
- package/dist/features/btw-side/tui-keymap.d.ts +10 -0
- package/dist/features/btw-side/tui-parent-validator.d.ts +6 -0
- package/dist/features/btw-side/tui-prompt-queue.d.ts +8 -0
- package/dist/features/btw-side/tui-session-bridge.d.ts +11 -0
- package/dist/features/btw-side/tui-side-removal.d.ts +11 -0
- package/dist/features/btw-side/tui-side-start.d.ts +9 -0
- package/dist/features/btw-side/tui-wiring.d.ts +8 -0
- package/dist/hooks/runtime-fallback/chat-message-handler.d.ts +2 -0
- package/dist/hooks/runtime-fallback/retry-model-payload.d.ts +1 -0
- package/dist/hooks/runtime-fallback/runtime-model-settings.d.ts +6 -0
- package/dist/hooks/runtime-fallback/session-status-handler.d.ts +1 -1
- package/dist/hooks/runtime-fallback/types.d.ts +3 -1
- package/dist/index.js +6502 -3850
- package/dist/plugin/event-session-lifecycle.d.ts +1 -0
- package/dist/plugin/hooks/create-core-hooks.d.ts +1 -0
- package/dist/plugin/hooks/create-transform-hooks.d.ts +2 -0
- package/dist/plugin/messages-transform.d.ts +1 -0
- package/dist/shared/index.d.ts +1 -0
- package/dist/shared/runtime-fallback-retry-marker.d.ts +16 -0
- package/dist/tui.js +8092 -6792
- package/package.json +24 -23
- package/packages/git-bash-mcp/dist/cli.js +5 -1
- package/packages/lsp-daemon/dist/cli.js +5 -1
- package/packages/lsp-daemon/dist/client.js +5 -1
- package/packages/lsp-daemon/dist/index.js +5 -1
- package/packages/lsp-tools-mcp/dist/cli.js +5 -1
- package/packages/lsp-tools-mcp/dist/mcp.js +5 -1
- package/packages/omo-codex/plugin/.codex-plugin/plugin.json +1 -1
- package/packages/omo-codex/plugin/components/bootstrap/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
- package/packages/omo-codex/plugin/components/codegraph/dist/cli.js +5 -1
- package/packages/omo-codex/plugin/components/codegraph/dist/serve.js +5 -1
- package/packages/omo-codex/plugin/components/codegraph/package.json +1 -1
- package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/comment-checker/package.json +1 -1
- package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
- package/packages/omo-codex/plugin/components/git-bash/package.json +1 -1
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +1 -1
- package/packages/omo-codex/plugin/components/lsp/dist/.omo-runtime-manifest.json +2 -2
- package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
- package/packages/omo-codex/plugin/components/lsp/package.json +1 -1
- package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
- package/packages/omo-codex/plugin/components/rules/package.json +1 -1
- package/packages/omo-codex/plugin/components/start-work-continuation/hooks/hooks.json +2 -2
- package/packages/omo-codex/plugin/components/start-work-continuation/package.json +1 -1
- package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/teammode/package.json +1 -1
- package/packages/omo-codex/plugin/components/telemetry/dist/cli.js +2242 -381
- package/packages/omo-codex/plugin/components/telemetry/dist/posthog.js +2247 -386
- package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/telemetry/package.json +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/package.json +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +4 -4
- package/packages/omo-codex/plugin/components/ulw-loop/package.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-codegraph-init-guidance.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +1 -1
- package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +1 -1
- package/packages/omo-codex/plugin/hooks/pre-tool-use-guarding-ulw-loop-spawns.json +1 -1
- package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-checking-codegraph-bootstrap.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +1 -1
- package/packages/omo-codex/plugin/hooks/stop-checking-start-work-continuation.json +1 -1
- package/packages/omo-codex/plugin/hooks/stop-checking-ulw-loop-resume.json +1 -1
- package/packages/omo-codex/plugin/hooks/subagent-stop-checking-start-work-continuation.json +1 -1
- package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +1 -1
- package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +1 -1
- package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +1 -1
- package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +1 -1
- package/packages/omo-codex/plugin/package-lock.json +13 -13
- package/packages/omo-codex/plugin/package.json +1 -1
- package/packages/omo-codex/scripts/install-dist/install-local.mjs +2307 -401
|
@@ -338,7 +338,7 @@ function getTelemetryHost(env = process.env, defaultHost = DEFAULT_POSTHOG_HOST)
|
|
|
338
338
|
return env["POSTHOG_HOST"]?.trim() || defaultHost;
|
|
339
339
|
}
|
|
340
340
|
|
|
341
|
-
// ../../../node_modules/.bun/posthog-node@5.
|
|
341
|
+
// ../../../node_modules/.bun/posthog-node@5.49.2/node_modules/posthog-node/dist/extensions/error-tracking/modifiers/module.node.mjs
|
|
342
342
|
import { dirname, posix, sep } from "node:path";
|
|
343
343
|
function createModulerModifier() {
|
|
344
344
|
const getModuleFromFileName = createGetModuleFromFilename();
|
|
@@ -374,7 +374,7 @@ function normalizeWindowsPath(path2) {
|
|
|
374
374
|
return path2.replace(/^[A-Z]:/, "").replace(/\\/g, "/");
|
|
375
375
|
}
|
|
376
376
|
|
|
377
|
-
// ../../../node_modules/.bun/@posthog+core@1.
|
|
377
|
+
// ../../../node_modules/.bun/@posthog+core@1.48.6/node_modules/@posthog/core/dist/featureFlagUtils.mjs
|
|
378
378
|
var normalizeFlagsResponse = (flagsResponse) => {
|
|
379
379
|
if ("flags" in flagsResponse) {
|
|
380
380
|
const featureFlags = getFlagValuesFromFlags(flagsResponse.flags);
|
|
@@ -444,8 +444,69 @@ var parsePayload = (response) => {
|
|
|
444
444
|
return response;
|
|
445
445
|
}
|
|
446
446
|
};
|
|
447
|
+
var MINIMAL_FLAG_CALLED_EVENT_CAMPAIGN_PROPERTIES = [
|
|
448
|
+
"utm_source",
|
|
449
|
+
"utm_medium",
|
|
450
|
+
"utm_campaign",
|
|
451
|
+
"utm_content",
|
|
452
|
+
"utm_term",
|
|
453
|
+
"gad_source",
|
|
454
|
+
"mc_cid",
|
|
455
|
+
"gclid",
|
|
456
|
+
"gclsrc",
|
|
457
|
+
"dclid",
|
|
458
|
+
"gbraid",
|
|
459
|
+
"wbraid",
|
|
460
|
+
"fbclid",
|
|
461
|
+
"msclkid",
|
|
462
|
+
"twclid",
|
|
463
|
+
"li_fat_id",
|
|
464
|
+
"igshid",
|
|
465
|
+
"ttclid",
|
|
466
|
+
"rdt_cid",
|
|
467
|
+
"epik",
|
|
468
|
+
"qclid",
|
|
469
|
+
"sccid",
|
|
470
|
+
"irclid",
|
|
471
|
+
"_kx"
|
|
472
|
+
];
|
|
473
|
+
var MINIMAL_FLAG_CALLED_EVENT_PROPERTIES = [
|
|
474
|
+
"$feature_flag",
|
|
475
|
+
"$feature_flag_response",
|
|
476
|
+
"$feature_flag_has_experiment",
|
|
477
|
+
"$feature_flag_id",
|
|
478
|
+
"$feature_flag_version",
|
|
479
|
+
"$feature_flag_reason",
|
|
480
|
+
"$feature_flag_request_id",
|
|
481
|
+
"$feature_flag_evaluated_at",
|
|
482
|
+
"$feature_flag_error",
|
|
483
|
+
"locally_evaluated",
|
|
484
|
+
"$groups",
|
|
485
|
+
"$process_person_profile",
|
|
486
|
+
"$geoip_disable",
|
|
487
|
+
"$current_url",
|
|
488
|
+
"$pathname",
|
|
489
|
+
"$referring_domain",
|
|
490
|
+
...MINIMAL_FLAG_CALLED_EVENT_CAMPAIGN_PROPERTIES,
|
|
491
|
+
"$session_id",
|
|
492
|
+
"$window_id",
|
|
493
|
+
"$lib",
|
|
494
|
+
"$lib_version",
|
|
495
|
+
"$device_id",
|
|
496
|
+
"$is_server"
|
|
497
|
+
];
|
|
498
|
+
var minimizeFlagCalledEventProperties = (properties, transportKeys = []) => {
|
|
499
|
+
const minimal = {};
|
|
500
|
+
const copyKey = (key) => {
|
|
501
|
+
if (properties[key] !== undefined)
|
|
502
|
+
minimal[key] = properties[key];
|
|
503
|
+
};
|
|
504
|
+
MINIMAL_FLAG_CALLED_EVENT_PROPERTIES.forEach(copyKey);
|
|
505
|
+
transportKeys.forEach(copyKey);
|
|
506
|
+
return minimal;
|
|
507
|
+
};
|
|
447
508
|
|
|
448
|
-
// ../../../node_modules/.bun/@posthog+core@1.
|
|
509
|
+
// ../../../node_modules/.bun/@posthog+core@1.48.6/node_modules/@posthog/core/dist/types.mjs
|
|
449
510
|
var types_PostHogPersistedProperty = /* @__PURE__ */ function(PostHogPersistedProperty) {
|
|
450
511
|
PostHogPersistedProperty["AnonymousId"] = "anonymous_id";
|
|
451
512
|
PostHogPersistedProperty["DistinctId"] = "distinct_id";
|
|
@@ -460,6 +521,8 @@ var types_PostHogPersistedProperty = /* @__PURE__ */ function(PostHogPersistedPr
|
|
|
460
521
|
PostHogPersistedProperty["BootstrapFeatureFlagPayloads"] = "bootstrap_feature_flag_payloads";
|
|
461
522
|
PostHogPersistedProperty["OverrideFeatureFlags"] = "override_feature_flags";
|
|
462
523
|
PostHogPersistedProperty["Queue"] = "queue";
|
|
524
|
+
PostHogPersistedProperty["AiQueue"] = "ai_queue";
|
|
525
|
+
PostHogPersistedProperty["AiCaptureQueue"] = "ai_capture_queue";
|
|
463
526
|
PostHogPersistedProperty["LogsQueue"] = "logs_queue";
|
|
464
527
|
PostHogPersistedProperty["OptedOut"] = "opted_out";
|
|
465
528
|
PostHogPersistedProperty["SessionId"] = "session_id";
|
|
@@ -470,6 +533,8 @@ var types_PostHogPersistedProperty = /* @__PURE__ */ function(PostHogPersistedPr
|
|
|
470
533
|
PostHogPersistedProperty["InstalledAppBuild"] = "installed_app_build";
|
|
471
534
|
PostHogPersistedProperty["InstalledAppVersion"] = "installed_app_version";
|
|
472
535
|
PostHogPersistedProperty["SessionReplay"] = "session_replay";
|
|
536
|
+
PostHogPersistedProperty["PushRegistered"] = "push_registered";
|
|
537
|
+
PostHogPersistedProperty["SessionReplayEventTriggerActivatedSession"] = "session_replay_event_trigger_activated_session";
|
|
473
538
|
PostHogPersistedProperty["SurveyLastSeenDate"] = "survey_last_seen_date";
|
|
474
539
|
PostHogPersistedProperty["SurveysSeen"] = "surveys_seen";
|
|
475
540
|
PostHogPersistedProperty["Surveys"] = "surveys";
|
|
@@ -479,7 +544,7 @@ var types_PostHogPersistedProperty = /* @__PURE__ */ function(PostHogPersistedPr
|
|
|
479
544
|
return PostHogPersistedProperty;
|
|
480
545
|
}({});
|
|
481
546
|
|
|
482
|
-
// ../../../node_modules/.bun/@posthog+core@1.
|
|
547
|
+
// ../../../node_modules/.bun/@posthog+core@1.48.6/node_modules/@posthog/core/dist/gzip.mjs
|
|
483
548
|
function isGzipSupported() {
|
|
484
549
|
return "CompressionStream" in globalThis && "TextEncoder" in globalThis && "Response" in globalThis && typeof Response.prototype.blob == "function";
|
|
485
550
|
}
|
|
@@ -529,7 +594,7 @@ var validateNativeGzip = async (compressed, inputBytes) => {
|
|
|
529
594
|
async function gzipCompress(input, isDebug = true, options) {
|
|
530
595
|
try {
|
|
531
596
|
const inputBytes = new TextEncoder().encode(input);
|
|
532
|
-
const compressedStream = new CompressionStream("gzip");
|
|
597
|
+
const compressedStream = new globalThis.CompressionStream("gzip");
|
|
533
598
|
const writer = compressedStream.writable.getWriter();
|
|
534
599
|
const writePromise = writer.write(inputBytes).then(() => writer.close()).catch(async (err) => {
|
|
535
600
|
try {
|
|
@@ -553,7 +618,7 @@ async function gzipCompress(input, isDebug = true, options) {
|
|
|
553
618
|
}
|
|
554
619
|
}
|
|
555
620
|
|
|
556
|
-
// ../../../node_modules/.bun/@posthog+core@1.
|
|
621
|
+
// ../../../node_modules/.bun/@posthog+core@1.48.6/node_modules/@posthog/core/dist/utils/bot-detection.mjs
|
|
557
622
|
var DEFAULT_BLOCKED_UA_STRS = [
|
|
558
623
|
"amazonbot",
|
|
559
624
|
"amazonproductbot",
|
|
@@ -642,7 +707,31 @@ var isBlockedUA = function(ua, customBlockedUserAgents = []) {
|
|
|
642
707
|
return uaLower.indexOf(blockedUaLower) !== -1;
|
|
643
708
|
});
|
|
644
709
|
};
|
|
645
|
-
// ../../../node_modules/.bun/@posthog+core@1.
|
|
710
|
+
// ../../../node_modules/.bun/@posthog+core@1.48.6/node_modules/@posthog/core/dist/utils/string-utils.mjs
|
|
711
|
+
function safeJsonStringify(value) {
|
|
712
|
+
const ancestors = [];
|
|
713
|
+
return JSON.stringify(value, function(_key, replacementValue) {
|
|
714
|
+
if (typeof replacementValue == "bigint")
|
|
715
|
+
return replacementValue.toString();
|
|
716
|
+
if (typeof replacementValue == "function" || typeof replacementValue == "symbol")
|
|
717
|
+
return;
|
|
718
|
+
if (replacementValue instanceof Error)
|
|
719
|
+
return {
|
|
720
|
+
name: replacementValue.name,
|
|
721
|
+
message: replacementValue.message,
|
|
722
|
+
stack: replacementValue.stack
|
|
723
|
+
};
|
|
724
|
+
if (replacementValue && typeof replacementValue == "object") {
|
|
725
|
+
while (ancestors.length > 0 && ancestors[ancestors.length - 1] !== this)
|
|
726
|
+
ancestors.pop();
|
|
727
|
+
if (ancestors.includes(replacementValue))
|
|
728
|
+
return "[Circular]";
|
|
729
|
+
ancestors.push(replacementValue);
|
|
730
|
+
}
|
|
731
|
+
return replacementValue;
|
|
732
|
+
}) ?? "null";
|
|
733
|
+
}
|
|
734
|
+
// ../../../node_modules/.bun/@posthog+core@1.48.6/node_modules/@posthog/core/dist/utils/type-utils.mjs
|
|
646
735
|
var nativeIsArray = Array.isArray;
|
|
647
736
|
var ObjProto = Object.prototype;
|
|
648
737
|
var type_utils_hasOwnProperty = ObjProto.hasOwnProperty;
|
|
@@ -654,14 +743,27 @@ var isObject = (x) => x === Object(x) && !isArray(x);
|
|
|
654
743
|
var isUndefined = (x) => x === undefined;
|
|
655
744
|
var isString = (x) => type_utils_toString.call(x) == "[object String]";
|
|
656
745
|
var isEmptyString = (x) => isString(x) && x.trim().length === 0;
|
|
746
|
+
var isNull = (x) => x === null;
|
|
657
747
|
var isNumber = (x) => type_utils_toString.call(x) == "[object Number]" && x === x;
|
|
658
|
-
var
|
|
748
|
+
var isBoolean = (x) => type_utils_toString.call(x) === "[object Boolean]";
|
|
659
749
|
function isPrimitive(value) {
|
|
660
750
|
return value === null || typeof value != "object";
|
|
661
751
|
}
|
|
662
752
|
function isBuiltin(candidate, className) {
|
|
663
753
|
return Object.prototype.toString.call(candidate) === `[object ${className}]`;
|
|
664
754
|
}
|
|
755
|
+
function isError(candidate) {
|
|
756
|
+
switch (Object.prototype.toString.call(candidate)) {
|
|
757
|
+
case "[object Error]":
|
|
758
|
+
case "[object Exception]":
|
|
759
|
+
case "[object DOMException]":
|
|
760
|
+
case "[object DOMError]":
|
|
761
|
+
case "[object WebAssembly.Exception]":
|
|
762
|
+
return true;
|
|
763
|
+
default:
|
|
764
|
+
return isInstanceOf(candidate, Error);
|
|
765
|
+
}
|
|
766
|
+
}
|
|
665
767
|
function isErrorEvent(event) {
|
|
666
768
|
return isBuiltin(event, "ErrorEvent");
|
|
667
769
|
}
|
|
@@ -679,7 +781,7 @@ function isInstanceOf(candidate, base) {
|
|
|
679
781
|
}
|
|
680
782
|
}
|
|
681
783
|
|
|
682
|
-
// ../../../node_modules/.bun/@posthog+core@1.
|
|
784
|
+
// ../../../node_modules/.bun/@posthog+core@1.48.6/node_modules/@posthog/core/dist/utils/number-utils.mjs
|
|
683
785
|
function clampToRange(value, min, max, logger, fallbackValue) {
|
|
684
786
|
if (min > max) {
|
|
685
787
|
logger.warn("min cannot be greater than max.");
|
|
@@ -699,8 +801,16 @@ function clampToRange(value, min, max, logger, fallbackValue) {
|
|
|
699
801
|
return clampToRange(fallbackValue || max, min, max, logger);
|
|
700
802
|
}
|
|
701
803
|
|
|
702
|
-
// ../../../node_modules/.bun/@posthog+core@1.
|
|
804
|
+
// ../../../node_modules/.bun/@posthog+core@1.48.6/node_modules/@posthog/core/dist/utils/bucketed-rate-limiter.mjs
|
|
703
805
|
var ONE_DAY_IN_MS = 86400000;
|
|
806
|
+
var DEFAULT_EXCEPTION_RATE_LIMITER_REFILL_RATE = 1;
|
|
807
|
+
var DEFAULT_EXCEPTION_RATE_LIMITER_BUCKET_SIZE = 10;
|
|
808
|
+
function resolveExceptionRateLimiterConfig(config = {}) {
|
|
809
|
+
return {
|
|
810
|
+
refillRate: config.exceptionRateLimiterRefillRate ?? config.__exceptionRateLimiterRefillRate ?? DEFAULT_EXCEPTION_RATE_LIMITER_REFILL_RATE,
|
|
811
|
+
bucketSize: config.exceptionRateLimiterBucketSize ?? config.__exceptionRateLimiterBucketSize ?? DEFAULT_EXCEPTION_RATE_LIMITER_BUCKET_SIZE
|
|
812
|
+
};
|
|
813
|
+
}
|
|
704
814
|
|
|
705
815
|
class BucketedRateLimiter {
|
|
706
816
|
constructor(options) {
|
|
@@ -743,7 +853,10 @@ class BucketedRateLimiter {
|
|
|
743
853
|
this._buckets = {};
|
|
744
854
|
}
|
|
745
855
|
}
|
|
746
|
-
// ../../../node_modules/.bun/@posthog+core@1.
|
|
856
|
+
// ../../../node_modules/.bun/@posthog+core@1.48.6/node_modules/@posthog/core/dist/utils/json-utils.mjs
|
|
857
|
+
var dateGetTime = Date.prototype.getTime;
|
|
858
|
+
var dateToISOString = Date.prototype.toISOString;
|
|
859
|
+
// ../../../node_modules/.bun/@posthog+core@1.48.6/node_modules/@posthog/core/dist/vendor/uuidv7.mjs
|
|
747
860
|
/*! For license information please see uuidv7.mjs.LICENSE.txt */
|
|
748
861
|
var DIGITS = "0123456789abcdef";
|
|
749
862
|
|
|
@@ -921,33 +1034,45 @@ var defaultGenerator;
|
|
|
921
1034
|
var uuidv7 = () => uuidv7obj().toString();
|
|
922
1035
|
var uuidv7obj = () => (defaultGenerator || (defaultGenerator = new V7Generator)).generate();
|
|
923
1036
|
|
|
924
|
-
// ../../../node_modules/.bun/@posthog+core@1.
|
|
1037
|
+
// ../../../node_modules/.bun/@posthog+core@1.48.6/node_modules/@posthog/core/dist/utils/promise-queue.mjs
|
|
925
1038
|
class PromiseQueue {
|
|
926
1039
|
add(promise) {
|
|
927
1040
|
const promiseUUID = uuidv7();
|
|
928
|
-
|
|
1041
|
+
const id = ++this.nextId;
|
|
1042
|
+
this.promiseByIds[promiseUUID] = {
|
|
1043
|
+
id,
|
|
1044
|
+
promise
|
|
1045
|
+
};
|
|
929
1046
|
promise.catch(() => {}).finally(() => {
|
|
930
1047
|
delete this.promiseByIds[promiseUUID];
|
|
931
1048
|
});
|
|
932
1049
|
return promise;
|
|
933
1050
|
}
|
|
934
1051
|
async join() {
|
|
935
|
-
let promises = Object.values(this.promiseByIds);
|
|
1052
|
+
let promises = Object.values(this.promiseByIds).map((item) => item.promise);
|
|
936
1053
|
let length = promises.length;
|
|
937
1054
|
while (length > 0) {
|
|
938
1055
|
await Promise.all(promises);
|
|
939
|
-
promises = Object.values(this.promiseByIds);
|
|
1056
|
+
promises = Object.values(this.promiseByIds).map((item) => item.promise);
|
|
940
1057
|
length = promises.length;
|
|
941
1058
|
}
|
|
942
1059
|
}
|
|
1060
|
+
getPromises(ignoredPromises = [], maxId = this.nextId) {
|
|
1061
|
+
const ignoredPromiseSet = new Set(ignoredPromises);
|
|
1062
|
+
return Object.values(this.promiseByIds).filter((item) => item.id <= maxId && !ignoredPromiseSet.has(item.promise)).map((item) => item.promise);
|
|
1063
|
+
}
|
|
1064
|
+
get maxId() {
|
|
1065
|
+
return this.nextId;
|
|
1066
|
+
}
|
|
943
1067
|
get length() {
|
|
944
1068
|
return Object.keys(this.promiseByIds).length;
|
|
945
1069
|
}
|
|
946
1070
|
constructor() {
|
|
947
1071
|
this.promiseByIds = {};
|
|
1072
|
+
this.nextId = 0;
|
|
948
1073
|
}
|
|
949
1074
|
}
|
|
950
|
-
// ../../../node_modules/.bun/@posthog+core@1.
|
|
1075
|
+
// ../../../node_modules/.bun/@posthog+core@1.48.6/node_modules/@posthog/core/dist/utils/logger.mjs
|
|
951
1076
|
function createConsole(consoleLike = console) {
|
|
952
1077
|
const lockedMethods = {
|
|
953
1078
|
log: consoleLike.log.bind(consoleLike),
|
|
@@ -988,7 +1113,7 @@ var passThrough = (fn) => fn();
|
|
|
988
1113
|
function createLogger(prefix, maybeCall = passThrough) {
|
|
989
1114
|
return _createLogger(prefix, maybeCall, createConsole());
|
|
990
1115
|
}
|
|
991
|
-
// ../../../node_modules/.bun/@posthog+core@1.
|
|
1116
|
+
// ../../../node_modules/.bun/@posthog+core@1.48.6/node_modules/@posthog/core/dist/utils/user-agent-utils.mjs
|
|
992
1117
|
var MOBILE = "Mobile";
|
|
993
1118
|
var IOS = "iOS";
|
|
994
1119
|
var ANDROID = "Android";
|
|
@@ -1031,6 +1156,7 @@ var DUCKDUCKGO = "DuckDuckGo";
|
|
|
1031
1156
|
var PALE_MOON = "Pale Moon";
|
|
1032
1157
|
var WATERFOX = "Waterfox";
|
|
1033
1158
|
var BRAVE = "Brave";
|
|
1159
|
+
var GOOGLE_SEARCH_APP = "Google Search App";
|
|
1034
1160
|
var BROWSER_VERSION_REGEX_SUFFIX = "(\\d+(\\.\\d+)?)";
|
|
1035
1161
|
var DEFAULT_BROWSER_VERSION_REGEX = new RegExp("Version/" + BROWSER_VERSION_REGEX_SUFFIX);
|
|
1036
1162
|
var XBOX_REGEX = new RegExp(XBOX, "i");
|
|
@@ -1118,6 +1244,9 @@ var versionRegexes = {
|
|
|
1118
1244
|
[WATERFOX]: [
|
|
1119
1245
|
new RegExp(WATERFOX + "\\/" + BROWSER_VERSION_REGEX_SUFFIX)
|
|
1120
1246
|
],
|
|
1247
|
+
[GOOGLE_SEARCH_APP]: [
|
|
1248
|
+
new RegExp("GSA\\/" + BROWSER_VERSION_REGEX_SUFFIX)
|
|
1249
|
+
],
|
|
1121
1250
|
[INTERNET_EXPLORER]: [
|
|
1122
1251
|
new RegExp("(rv:|MSIE )" + BROWSER_VERSION_REGEX_SUFFIX)
|
|
1123
1252
|
],
|
|
@@ -1277,8 +1406,15 @@ var osMatchers = [
|
|
|
1277
1406
|
]
|
|
1278
1407
|
];
|
|
1279
1408
|
|
|
1280
|
-
// ../../../node_modules/.bun/@posthog+core@1.
|
|
1409
|
+
// ../../../node_modules/.bun/@posthog+core@1.48.6/node_modules/@posthog/core/dist/utils/index.mjs
|
|
1281
1410
|
var STRING_FORMAT = "utf8";
|
|
1411
|
+
var UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
1412
|
+
function isValidUUID(value) {
|
|
1413
|
+
return typeof value == "string" && UUID_REGEX.test(value);
|
|
1414
|
+
}
|
|
1415
|
+
function getEventUuid(uuid, generateUuid) {
|
|
1416
|
+
return isValidUUID(uuid) ? uuid : generateUuid();
|
|
1417
|
+
}
|
|
1282
1418
|
function removeTrailingSlash(url) {
|
|
1283
1419
|
return url?.replace(/\/+$/, "");
|
|
1284
1420
|
}
|
|
@@ -1306,7 +1442,26 @@ function safeSetTimeout(fn, timeout) {
|
|
|
1306
1442
|
t?.unref && t?.unref();
|
|
1307
1443
|
return t;
|
|
1308
1444
|
}
|
|
1309
|
-
|
|
1445
|
+
async function raceWithTimeout(promise, timeoutMs, onTimeout) {
|
|
1446
|
+
let timeoutHandle;
|
|
1447
|
+
try {
|
|
1448
|
+
return await Promise.race([
|
|
1449
|
+
promise,
|
|
1450
|
+
new Promise((resolve, reject) => {
|
|
1451
|
+
timeoutHandle = safeSetTimeout(() => {
|
|
1452
|
+
try {
|
|
1453
|
+
onTimeout?.();
|
|
1454
|
+
resolve();
|
|
1455
|
+
} catch (error) {
|
|
1456
|
+
reject(error);
|
|
1457
|
+
}
|
|
1458
|
+
}, timeoutMs);
|
|
1459
|
+
})
|
|
1460
|
+
]);
|
|
1461
|
+
} finally {
|
|
1462
|
+
clearTimeout(timeoutHandle);
|
|
1463
|
+
}
|
|
1464
|
+
}
|
|
1310
1465
|
function allSettled(promises) {
|
|
1311
1466
|
return Promise.all(promises.map((p) => (p ?? Promise.resolve()).then((value) => ({
|
|
1312
1467
|
status: "fulfilled",
|
|
@@ -1317,7 +1472,7 @@ function allSettled(promises) {
|
|
|
1317
1472
|
}))));
|
|
1318
1473
|
}
|
|
1319
1474
|
|
|
1320
|
-
// ../../../node_modules/.bun/@posthog+core@1.
|
|
1475
|
+
// ../../../node_modules/.bun/@posthog+core@1.48.6/node_modules/@posthog/core/dist/logs/logs-utils.mjs
|
|
1321
1476
|
var OTLP_SEVERITY_MAP = {
|
|
1322
1477
|
trace: {
|
|
1323
1478
|
text: "TRACE",
|
|
@@ -1345,7 +1500,464 @@ var OTLP_SEVERITY_MAP = {
|
|
|
1345
1500
|
}
|
|
1346
1501
|
};
|
|
1347
1502
|
var DEFAULT_OTLP_SEVERITY = OTLP_SEVERITY_MAP.info;
|
|
1348
|
-
|
|
1503
|
+
function toOtlpAnyValue(value) {
|
|
1504
|
+
if (isBoolean(value))
|
|
1505
|
+
return {
|
|
1506
|
+
boolValue: value
|
|
1507
|
+
};
|
|
1508
|
+
if (typeof value == "number") {
|
|
1509
|
+
if (!Number.isFinite(value))
|
|
1510
|
+
return {
|
|
1511
|
+
stringValue: String(value)
|
|
1512
|
+
};
|
|
1513
|
+
if (Number.isInteger(value))
|
|
1514
|
+
return {
|
|
1515
|
+
intValue: value
|
|
1516
|
+
};
|
|
1517
|
+
return {
|
|
1518
|
+
doubleValue: value
|
|
1519
|
+
};
|
|
1520
|
+
}
|
|
1521
|
+
if (typeof value == "string")
|
|
1522
|
+
return {
|
|
1523
|
+
stringValue: value
|
|
1524
|
+
};
|
|
1525
|
+
if (isArray(value))
|
|
1526
|
+
return {
|
|
1527
|
+
arrayValue: {
|
|
1528
|
+
values: value.map((v) => toOtlpAnyValue(v))
|
|
1529
|
+
}
|
|
1530
|
+
};
|
|
1531
|
+
try {
|
|
1532
|
+
return {
|
|
1533
|
+
stringValue: JSON.stringify(value)
|
|
1534
|
+
};
|
|
1535
|
+
} catch {
|
|
1536
|
+
return {
|
|
1537
|
+
stringValue: String(value)
|
|
1538
|
+
};
|
|
1539
|
+
}
|
|
1540
|
+
}
|
|
1541
|
+
function toOtlpKeyValueList(attrs) {
|
|
1542
|
+
const result = [];
|
|
1543
|
+
for (const key in attrs) {
|
|
1544
|
+
const value = attrs[key];
|
|
1545
|
+
if (!(isNull(value) || isUndefined(value)))
|
|
1546
|
+
result.push({
|
|
1547
|
+
key,
|
|
1548
|
+
value: toOtlpAnyValue(value)
|
|
1549
|
+
});
|
|
1550
|
+
}
|
|
1551
|
+
return result;
|
|
1552
|
+
}
|
|
1553
|
+
|
|
1554
|
+
// ../../../node_modules/.bun/@posthog+core@1.48.6/node_modules/@posthog/core/dist/metrics/metrics-utils.mjs
|
|
1555
|
+
var DEFAULT_HISTOGRAM_BOUNDS = [
|
|
1556
|
+
0,
|
|
1557
|
+
5,
|
|
1558
|
+
10,
|
|
1559
|
+
25,
|
|
1560
|
+
50,
|
|
1561
|
+
75,
|
|
1562
|
+
100,
|
|
1563
|
+
250,
|
|
1564
|
+
500,
|
|
1565
|
+
750,
|
|
1566
|
+
1000,
|
|
1567
|
+
2500,
|
|
1568
|
+
5000,
|
|
1569
|
+
7500,
|
|
1570
|
+
1e4
|
|
1571
|
+
];
|
|
1572
|
+
function msToUnixNano(ms) {
|
|
1573
|
+
return String(ms) + "000000";
|
|
1574
|
+
}
|
|
1575
|
+
function seriesKey(type, name, unit, attributes) {
|
|
1576
|
+
let attrsKey = "";
|
|
1577
|
+
if (attributes) {
|
|
1578
|
+
const keys = Object.keys(attributes).sort();
|
|
1579
|
+
attrsKey = keys.map((k) => `${JSON.stringify(k)}:${JSON.stringify(attributes[k])}`).join(",");
|
|
1580
|
+
}
|
|
1581
|
+
return `${type}\x00${name}\x00${unit ?? ""}\x00${attrsKey}`;
|
|
1582
|
+
}
|
|
1583
|
+
function bucketIndexFor(value, bounds) {
|
|
1584
|
+
for (let i = 0;i < bounds.length; i++)
|
|
1585
|
+
if (value <= bounds[i])
|
|
1586
|
+
return i;
|
|
1587
|
+
return bounds.length;
|
|
1588
|
+
}
|
|
1589
|
+
function buildMetricsResourceAttributes(config, scopeName, scopeVersion) {
|
|
1590
|
+
return {
|
|
1591
|
+
...config.resourceAttributes,
|
|
1592
|
+
"service.name": config.serviceName || "unknown_service",
|
|
1593
|
+
...config.environment && {
|
|
1594
|
+
"deployment.environment": config.environment
|
|
1595
|
+
},
|
|
1596
|
+
...config.serviceVersion && {
|
|
1597
|
+
"service.version": config.serviceVersion
|
|
1598
|
+
},
|
|
1599
|
+
"telemetry.sdk.name": scopeName,
|
|
1600
|
+
"telemetry.sdk.version": scopeVersion
|
|
1601
|
+
};
|
|
1602
|
+
}
|
|
1603
|
+
function buildOtlpMetricsPayload(metrics, resourceAttributes, scopeName, scopeVersion) {
|
|
1604
|
+
return {
|
|
1605
|
+
resourceMetrics: [
|
|
1606
|
+
{
|
|
1607
|
+
resource: {
|
|
1608
|
+
attributes: toOtlpKeyValueList(resourceAttributes)
|
|
1609
|
+
},
|
|
1610
|
+
scopeMetrics: [
|
|
1611
|
+
{
|
|
1612
|
+
scope: {
|
|
1613
|
+
name: scopeName,
|
|
1614
|
+
version: scopeVersion
|
|
1615
|
+
},
|
|
1616
|
+
metrics
|
|
1617
|
+
}
|
|
1618
|
+
]
|
|
1619
|
+
}
|
|
1620
|
+
]
|
|
1621
|
+
};
|
|
1622
|
+
}
|
|
1623
|
+
|
|
1624
|
+
// ../../../node_modules/.bun/@posthog+core@1.48.6/node_modules/@posthog/core/dist/metrics/config.mjs
|
|
1625
|
+
var DEFAULT_FLUSH_INTERVAL_MS = 1e4;
|
|
1626
|
+
var DEFAULT_MAX_SERIES_PER_FLUSH = 1000;
|
|
1627
|
+
function resolveMetricsConfig(config) {
|
|
1628
|
+
const resourceAttributes = config?.resourceAttributes;
|
|
1629
|
+
return {
|
|
1630
|
+
serviceName: resourceAttributes?.["service.name"] ?? config?.serviceName,
|
|
1631
|
+
serviceVersion: resourceAttributes?.["service.version"] ?? config?.serviceVersion,
|
|
1632
|
+
environment: resourceAttributes?.["deployment.environment"] ?? config?.environment,
|
|
1633
|
+
resourceAttributes,
|
|
1634
|
+
beforeSend: config?.beforeSend,
|
|
1635
|
+
flushIntervalMs: config?.flushIntervalMs ?? DEFAULT_FLUSH_INTERVAL_MS,
|
|
1636
|
+
maxSeriesPerFlush: config?.maxSeriesPerFlush ?? DEFAULT_MAX_SERIES_PER_FLUSH
|
|
1637
|
+
};
|
|
1638
|
+
}
|
|
1639
|
+
|
|
1640
|
+
// ../../../node_modules/.bun/@posthog+core@1.48.6/node_modules/@posthog/core/dist/metrics/index.mjs
|
|
1641
|
+
var OTLP_TEMPORALITY_DELTA = 1;
|
|
1642
|
+
|
|
1643
|
+
class PostHogMetrics {
|
|
1644
|
+
constructor(_instance, _config, _logger) {
|
|
1645
|
+
this._instance = _instance;
|
|
1646
|
+
this._config = _config;
|
|
1647
|
+
this._logger = _logger;
|
|
1648
|
+
this._series = new Map;
|
|
1649
|
+
this._flushPromise = null;
|
|
1650
|
+
this._seriesCapWarned = false;
|
|
1651
|
+
this._typeByName = new Map;
|
|
1652
|
+
this._typeCollisionWarned = new Set;
|
|
1653
|
+
this._generation = 0;
|
|
1654
|
+
}
|
|
1655
|
+
count(name, value = 1, options) {
|
|
1656
|
+
this._capture({
|
|
1657
|
+
name,
|
|
1658
|
+
type: "count",
|
|
1659
|
+
value,
|
|
1660
|
+
unit: options?.unit,
|
|
1661
|
+
attributes: options?.attributes
|
|
1662
|
+
});
|
|
1663
|
+
}
|
|
1664
|
+
gauge(name, value, options) {
|
|
1665
|
+
this._capture({
|
|
1666
|
+
name,
|
|
1667
|
+
type: "gauge",
|
|
1668
|
+
value,
|
|
1669
|
+
unit: options?.unit,
|
|
1670
|
+
attributes: options?.attributes
|
|
1671
|
+
});
|
|
1672
|
+
}
|
|
1673
|
+
histogram(name, value, options) {
|
|
1674
|
+
this._capture({
|
|
1675
|
+
name,
|
|
1676
|
+
type: "histogram",
|
|
1677
|
+
value,
|
|
1678
|
+
unit: options?.unit,
|
|
1679
|
+
attributes: options?.attributes
|
|
1680
|
+
});
|
|
1681
|
+
}
|
|
1682
|
+
flush() {
|
|
1683
|
+
const prev = this._flushPromise;
|
|
1684
|
+
const run = async () => {
|
|
1685
|
+
if (prev)
|
|
1686
|
+
await prev.catch(() => {});
|
|
1687
|
+
await this._doFlush();
|
|
1688
|
+
};
|
|
1689
|
+
const p = run().finally(() => {
|
|
1690
|
+
if (this._flushPromise === p)
|
|
1691
|
+
this._flushPromise = null;
|
|
1692
|
+
});
|
|
1693
|
+
this._flushPromise = p;
|
|
1694
|
+
return p;
|
|
1695
|
+
}
|
|
1696
|
+
drainWindow() {
|
|
1697
|
+
if (this._series.size === 0)
|
|
1698
|
+
return null;
|
|
1699
|
+
const window = this._series;
|
|
1700
|
+
this._series = new Map;
|
|
1701
|
+
this._seriesCapWarned = false;
|
|
1702
|
+
this._typeByName = new Map;
|
|
1703
|
+
this._typeCollisionWarned = new Set;
|
|
1704
|
+
return this._buildPayload(window);
|
|
1705
|
+
}
|
|
1706
|
+
reset() {
|
|
1707
|
+
this._generation++;
|
|
1708
|
+
this._clearFlushTimer();
|
|
1709
|
+
this._series = new Map;
|
|
1710
|
+
this._flushPromise = null;
|
|
1711
|
+
this._seriesCapWarned = false;
|
|
1712
|
+
this._typeByName = new Map;
|
|
1713
|
+
this._typeCollisionWarned = new Set;
|
|
1714
|
+
}
|
|
1715
|
+
_capture(sample) {
|
|
1716
|
+
if (this._instance.isDisabled || this._instance.optedOut)
|
|
1717
|
+
return;
|
|
1718
|
+
const filtered = this._runBeforeSend(sample);
|
|
1719
|
+
if (filtered === null)
|
|
1720
|
+
return;
|
|
1721
|
+
if (!filtered.name || typeof filtered.name != "string")
|
|
1722
|
+
return void this._logger.warn("Dropping metric with empty name");
|
|
1723
|
+
if (typeof filtered.value != "number" || !Number.isFinite(filtered.value))
|
|
1724
|
+
return void this._logger.warn(`Dropping metric '${filtered.name}': value must be a finite number`);
|
|
1725
|
+
if (filtered.type === "count" && filtered.value < 0)
|
|
1726
|
+
return void this._logger.warn(`Dropping count '${filtered.name}': counters are monotonic, value must be >= 0`);
|
|
1727
|
+
let attributes;
|
|
1728
|
+
let key;
|
|
1729
|
+
try {
|
|
1730
|
+
attributes = filtered.attributes ? {
|
|
1731
|
+
...filtered.attributes
|
|
1732
|
+
} : undefined;
|
|
1733
|
+
key = seriesKey(filtered.type, filtered.name, filtered.unit, attributes);
|
|
1734
|
+
} catch (e) {
|
|
1735
|
+
this._logger.warn(`Dropping metric '${filtered.name}': attributes could not be serialized`, e);
|
|
1736
|
+
return;
|
|
1737
|
+
}
|
|
1738
|
+
let state = this._series.get(key);
|
|
1739
|
+
if (!state) {
|
|
1740
|
+
if (!this._admitNewSeries())
|
|
1741
|
+
return;
|
|
1742
|
+
state = {
|
|
1743
|
+
name: filtered.name,
|
|
1744
|
+
type: filtered.type,
|
|
1745
|
+
unit: filtered.unit,
|
|
1746
|
+
attributes,
|
|
1747
|
+
windowStartMs: Date.now()
|
|
1748
|
+
};
|
|
1749
|
+
this._series.set(key, state);
|
|
1750
|
+
}
|
|
1751
|
+
const seenType = this._typeByName.get(filtered.name);
|
|
1752
|
+
if (seenType === undefined)
|
|
1753
|
+
this._typeByName.set(filtered.name, filtered.type);
|
|
1754
|
+
else if (seenType !== filtered.type && !this._typeCollisionWarned.has(filtered.name)) {
|
|
1755
|
+
this._typeCollisionWarned.add(filtered.name);
|
|
1756
|
+
this._logger.warn(`Metric name '${filtered.name}' is already used as a ${seenType}; recording it as a ${filtered.type} too will blend both series in charts. Use a distinct name.`);
|
|
1757
|
+
}
|
|
1758
|
+
this._fold(state, filtered.value);
|
|
1759
|
+
this._armFlushTimer();
|
|
1760
|
+
}
|
|
1761
|
+
_admitNewSeries() {
|
|
1762
|
+
if (this._series.size < this._config.maxSeriesPerFlush)
|
|
1763
|
+
return true;
|
|
1764
|
+
if (!this._seriesCapWarned) {
|
|
1765
|
+
this._seriesCapWarned = true;
|
|
1766
|
+
this._logger.warn(`Metric series cap reached (${this._config.maxSeriesPerFlush} per flush window); dropping new series until the next flush. Reduce attribute cardinality.`);
|
|
1767
|
+
}
|
|
1768
|
+
return false;
|
|
1769
|
+
}
|
|
1770
|
+
_fold(state, value) {
|
|
1771
|
+
switch (state.type) {
|
|
1772
|
+
case "count":
|
|
1773
|
+
state.total = (state.total ?? 0) + value;
|
|
1774
|
+
break;
|
|
1775
|
+
case "gauge":
|
|
1776
|
+
state.last = value;
|
|
1777
|
+
break;
|
|
1778
|
+
case "histogram": {
|
|
1779
|
+
if (!state.hist)
|
|
1780
|
+
state.hist = {
|
|
1781
|
+
count: 0,
|
|
1782
|
+
sum: 0,
|
|
1783
|
+
min: value,
|
|
1784
|
+
max: value,
|
|
1785
|
+
bucketCounts: new Array(DEFAULT_HISTOGRAM_BOUNDS.length + 1).fill(0)
|
|
1786
|
+
};
|
|
1787
|
+
const hist = state.hist;
|
|
1788
|
+
hist.count += 1;
|
|
1789
|
+
hist.sum += value;
|
|
1790
|
+
hist.min = Math.min(hist.min, value);
|
|
1791
|
+
hist.max = Math.max(hist.max, value);
|
|
1792
|
+
hist.bucketCounts[bucketIndexFor(value, DEFAULT_HISTOGRAM_BOUNDS)] += 1;
|
|
1793
|
+
break;
|
|
1794
|
+
}
|
|
1795
|
+
}
|
|
1796
|
+
}
|
|
1797
|
+
_runBeforeSend(sample) {
|
|
1798
|
+
const beforeSend = this._config.beforeSend;
|
|
1799
|
+
if (!beforeSend)
|
|
1800
|
+
return sample;
|
|
1801
|
+
const fns = isArray(beforeSend) ? beforeSend : [
|
|
1802
|
+
beforeSend
|
|
1803
|
+
];
|
|
1804
|
+
let result = sample;
|
|
1805
|
+
for (const fn of fns)
|
|
1806
|
+
try {
|
|
1807
|
+
const next = fn(result);
|
|
1808
|
+
if (!next) {
|
|
1809
|
+
this._logger.info("Metric was rejected in beforeSend function");
|
|
1810
|
+
return null;
|
|
1811
|
+
}
|
|
1812
|
+
result = next;
|
|
1813
|
+
} catch (e) {
|
|
1814
|
+
this._logger.error("Error in beforeSend function for metric:", e);
|
|
1815
|
+
return null;
|
|
1816
|
+
}
|
|
1817
|
+
return result;
|
|
1818
|
+
}
|
|
1819
|
+
_armFlushTimer() {
|
|
1820
|
+
if (this._flushTimer)
|
|
1821
|
+
return;
|
|
1822
|
+
this._flushTimer = safeSetTimeout(() => {
|
|
1823
|
+
this._flushTimer = undefined;
|
|
1824
|
+
this.flush().catch((e) => {
|
|
1825
|
+
this._logger.error("Metrics flush failed:", e);
|
|
1826
|
+
});
|
|
1827
|
+
}, this._config.flushIntervalMs);
|
|
1828
|
+
}
|
|
1829
|
+
_clearFlushTimer() {
|
|
1830
|
+
if (this._flushTimer) {
|
|
1831
|
+
clearTimeout(this._flushTimer);
|
|
1832
|
+
this._flushTimer = undefined;
|
|
1833
|
+
}
|
|
1834
|
+
}
|
|
1835
|
+
async _doFlush() {
|
|
1836
|
+
if (this._series.size === 0)
|
|
1837
|
+
return;
|
|
1838
|
+
const window = this._series;
|
|
1839
|
+
this._series = new Map;
|
|
1840
|
+
this._seriesCapWarned = false;
|
|
1841
|
+
this._typeByName = new Map;
|
|
1842
|
+
this._typeCollisionWarned = new Set;
|
|
1843
|
+
const generation = this._generation;
|
|
1844
|
+
const outcome = await this._instance._sendMetricsBatch(this._buildPayload(window));
|
|
1845
|
+
if (generation !== this._generation)
|
|
1846
|
+
return;
|
|
1847
|
+
switch (outcome.kind) {
|
|
1848
|
+
case "ok":
|
|
1849
|
+
return;
|
|
1850
|
+
case "retry-later":
|
|
1851
|
+
this._mergeWindowBack(window);
|
|
1852
|
+
this._armFlushTimer();
|
|
1853
|
+
return;
|
|
1854
|
+
case "too-large":
|
|
1855
|
+
this._logger.warn("Metrics batch exceeded the server size limit and was dropped");
|
|
1856
|
+
return;
|
|
1857
|
+
case "fatal":
|
|
1858
|
+
this._logger.error("Failed to send metrics batch:", outcome.error);
|
|
1859
|
+
return;
|
|
1860
|
+
}
|
|
1861
|
+
}
|
|
1862
|
+
_buildPayload(window) {
|
|
1863
|
+
return buildOtlpMetricsPayload(this._buildMetrics(window), buildMetricsResourceAttributes(this._config, this._instance.getLibraryId(), this._instance.getLibraryVersion()), this._instance.getLibraryId(), this._instance.getLibraryVersion());
|
|
1864
|
+
}
|
|
1865
|
+
_buildMetrics(window) {
|
|
1866
|
+
const nowNano = msToUnixNano(Date.now());
|
|
1867
|
+
const byMetric = new Map;
|
|
1868
|
+
for (const state of window.values()) {
|
|
1869
|
+
const metricKey = seriesKey(state.type, state.name, state.unit, undefined);
|
|
1870
|
+
let metric = byMetric.get(metricKey);
|
|
1871
|
+
if (!metric) {
|
|
1872
|
+
metric = {
|
|
1873
|
+
name: state.name,
|
|
1874
|
+
...state.unit && {
|
|
1875
|
+
unit: state.unit
|
|
1876
|
+
}
|
|
1877
|
+
};
|
|
1878
|
+
if (state.type === "count")
|
|
1879
|
+
metric.sum = {
|
|
1880
|
+
aggregationTemporality: OTLP_TEMPORALITY_DELTA,
|
|
1881
|
+
isMonotonic: true,
|
|
1882
|
+
dataPoints: []
|
|
1883
|
+
};
|
|
1884
|
+
else if (state.type === "gauge")
|
|
1885
|
+
metric.gauge = {
|
|
1886
|
+
dataPoints: []
|
|
1887
|
+
};
|
|
1888
|
+
else
|
|
1889
|
+
metric.histogram = {
|
|
1890
|
+
aggregationTemporality: OTLP_TEMPORALITY_DELTA,
|
|
1891
|
+
dataPoints: []
|
|
1892
|
+
};
|
|
1893
|
+
byMetric.set(metricKey, metric);
|
|
1894
|
+
}
|
|
1895
|
+
const attributes = toOtlpKeyValueList(state.attributes ?? {});
|
|
1896
|
+
const startNano = msToUnixNano(state.windowStartMs);
|
|
1897
|
+
if (state.type === "count") {
|
|
1898
|
+
const dp = {
|
|
1899
|
+
attributes,
|
|
1900
|
+
startTimeUnixNano: startNano,
|
|
1901
|
+
timeUnixNano: nowNano,
|
|
1902
|
+
asDouble: state.total ?? 0
|
|
1903
|
+
};
|
|
1904
|
+
metric.sum.dataPoints.push(dp);
|
|
1905
|
+
} else if (state.type === "gauge") {
|
|
1906
|
+
const dp = {
|
|
1907
|
+
attributes,
|
|
1908
|
+
timeUnixNano: nowNano,
|
|
1909
|
+
asDouble: state.last ?? 0
|
|
1910
|
+
};
|
|
1911
|
+
metric.gauge.dataPoints.push(dp);
|
|
1912
|
+
} else if (state.hist) {
|
|
1913
|
+
const dp = {
|
|
1914
|
+
attributes,
|
|
1915
|
+
startTimeUnixNano: startNano,
|
|
1916
|
+
timeUnixNano: nowNano,
|
|
1917
|
+
count: state.hist.count,
|
|
1918
|
+
sum: state.hist.sum,
|
|
1919
|
+
min: state.hist.min,
|
|
1920
|
+
max: state.hist.max,
|
|
1921
|
+
bucketCounts: state.hist.bucketCounts,
|
|
1922
|
+
explicitBounds: DEFAULT_HISTOGRAM_BOUNDS
|
|
1923
|
+
};
|
|
1924
|
+
metric.histogram.dataPoints.push(dp);
|
|
1925
|
+
}
|
|
1926
|
+
}
|
|
1927
|
+
return Array.from(byMetric.values());
|
|
1928
|
+
}
|
|
1929
|
+
_mergeWindowBack(window) {
|
|
1930
|
+
for (const [key, old] of window) {
|
|
1931
|
+
const current = this._series.get(key);
|
|
1932
|
+
if (!current) {
|
|
1933
|
+
if (this._admitNewSeries())
|
|
1934
|
+
this._series.set(key, old);
|
|
1935
|
+
continue;
|
|
1936
|
+
}
|
|
1937
|
+
current.windowStartMs = Math.min(current.windowStartMs, old.windowStartMs);
|
|
1938
|
+
switch (current.type) {
|
|
1939
|
+
case "count":
|
|
1940
|
+
current.total = (current.total ?? 0) + (old.total ?? 0);
|
|
1941
|
+
break;
|
|
1942
|
+
case "gauge":
|
|
1943
|
+
break;
|
|
1944
|
+
case "histogram":
|
|
1945
|
+
if (old.hist)
|
|
1946
|
+
if (current.hist) {
|
|
1947
|
+
current.hist.count += old.hist.count;
|
|
1948
|
+
current.hist.sum += old.hist.sum;
|
|
1949
|
+
current.hist.min = Math.min(current.hist.min, old.hist.min);
|
|
1950
|
+
current.hist.max = Math.max(current.hist.max, old.hist.max);
|
|
1951
|
+
for (let i = 0;i < current.hist.bucketCounts.length; i++)
|
|
1952
|
+
current.hist.bucketCounts[i] += old.hist.bucketCounts[i];
|
|
1953
|
+
} else
|
|
1954
|
+
current.hist = old.hist;
|
|
1955
|
+
break;
|
|
1956
|
+
}
|
|
1957
|
+
}
|
|
1958
|
+
}
|
|
1959
|
+
}
|
|
1960
|
+
// ../../../node_modules/.bun/@posthog+core@1.48.6/node_modules/@posthog/core/dist/eventemitter.mjs
|
|
1349
1961
|
class SimpleEventEmitter {
|
|
1350
1962
|
constructor() {
|
|
1351
1963
|
this.events = {};
|
|
@@ -1367,7 +1979,7 @@ class SimpleEventEmitter {
|
|
|
1367
1979
|
}
|
|
1368
1980
|
}
|
|
1369
1981
|
|
|
1370
|
-
// ../../../node_modules/.bun/@posthog+core@1.
|
|
1982
|
+
// ../../../node_modules/.bun/@posthog+core@1.48.6/node_modules/@posthog/core/dist/error-tracking/index.mjs
|
|
1371
1983
|
var exports_error_tracking = {};
|
|
1372
1984
|
__export(exports_error_tracking, {
|
|
1373
1985
|
winjsStackLineParser: () => winjsStackLineParser,
|
|
@@ -1378,6 +1990,7 @@ __export(exports_error_tracking, {
|
|
|
1378
1990
|
opera10StackLineParser: () => opera10StackLineParser,
|
|
1379
1991
|
nodeStackLineParser: () => nodeStackLineParser,
|
|
1380
1992
|
getUtf8ByteLength: () => getUtf8ByteLength,
|
|
1993
|
+
getInjectedReleaseId: () => getInjectedReleaseId,
|
|
1381
1994
|
geckoStackLineParser: () => geckoStackLineParser,
|
|
1382
1995
|
createStackParser: () => createStackParser,
|
|
1383
1996
|
createDefaultStackParser: () => createDefaultStackParser,
|
|
@@ -1397,7 +2010,7 @@ __export(exports_error_tracking, {
|
|
|
1397
2010
|
DEFAULT_EXCEPTION_STEPS_CONFIG: () => DEFAULT_EXCEPTION_STEPS_CONFIG
|
|
1398
2011
|
});
|
|
1399
2012
|
|
|
1400
|
-
// ../../../node_modules/.bun/@posthog+core@1.
|
|
2013
|
+
// ../../../node_modules/.bun/@posthog+core@1.48.6/node_modules/@posthog/core/dist/error-tracking/chunk-ids.mjs
|
|
1401
2014
|
var parsedStackResults;
|
|
1402
2015
|
var lastKeysCount;
|
|
1403
2016
|
var cachedFilenameChunkIds;
|
|
@@ -1436,7 +2049,7 @@ function getFilenameToChunkIdMap(stackParser) {
|
|
|
1436
2049
|
return cachedFilenameChunkIds;
|
|
1437
2050
|
}
|
|
1438
2051
|
|
|
1439
|
-
// ../../../node_modules/.bun/@posthog+core@1.
|
|
2052
|
+
// ../../../node_modules/.bun/@posthog+core@1.48.6/node_modules/@posthog/core/dist/error-tracking/error-properties-builder.mjs
|
|
1440
2053
|
var MAX_CAUSE_RECURSION = 4;
|
|
1441
2054
|
|
|
1442
2055
|
class ErrorPropertiesBuilder {
|
|
@@ -1558,14 +2171,16 @@ class ErrorPropertiesBuilder {
|
|
|
1558
2171
|
return context;
|
|
1559
2172
|
}
|
|
1560
2173
|
}
|
|
1561
|
-
// ../../../node_modules/.bun/@posthog+core@1.
|
|
2174
|
+
// ../../../node_modules/.bun/@posthog+core@1.48.6/node_modules/@posthog/core/dist/error-tracking/parsers/base.mjs
|
|
1562
2175
|
var UNKNOWN_FUNCTION = "?";
|
|
2176
|
+
var MASKED_URL_PREFIX = "webkit-masked-url://";
|
|
2177
|
+
var ANONYMOUS_FILENAME = "<anonymous>";
|
|
1563
2178
|
function createFrame(platform, filename, func, lineno, colno) {
|
|
1564
2179
|
const frame = {
|
|
1565
2180
|
platform,
|
|
1566
2181
|
filename,
|
|
1567
2182
|
function: func === "<anonymous>" ? UNKNOWN_FUNCTION : func,
|
|
1568
|
-
in_app:
|
|
2183
|
+
in_app: !filename?.startsWith(MASKED_URL_PREFIX) && filename !== ANONYMOUS_FILENAME
|
|
1569
2184
|
};
|
|
1570
2185
|
if (!isUndefined(lineno))
|
|
1571
2186
|
frame.lineno = lineno;
|
|
@@ -1574,7 +2189,7 @@ function createFrame(platform, filename, func, lineno, colno) {
|
|
|
1574
2189
|
return frame;
|
|
1575
2190
|
}
|
|
1576
2191
|
|
|
1577
|
-
// ../../../node_modules/.bun/@posthog+core@1.
|
|
2192
|
+
// ../../../node_modules/.bun/@posthog+core@1.48.6/node_modules/@posthog/core/dist/error-tracking/parsers/safari.mjs
|
|
1578
2193
|
var extractSafariExtensionDetails = (func, filename) => {
|
|
1579
2194
|
const isSafariExtension = func.indexOf("safari-extension") !== -1;
|
|
1580
2195
|
const isSafariWebExtension = func.indexOf("safari-web-extension") !== -1;
|
|
@@ -1587,7 +2202,7 @@ var extractSafariExtensionDetails = (func, filename) => {
|
|
|
1587
2202
|
];
|
|
1588
2203
|
};
|
|
1589
2204
|
|
|
1590
|
-
// ../../../node_modules/.bun/@posthog+core@1.
|
|
2205
|
+
// ../../../node_modules/.bun/@posthog+core@1.48.6/node_modules/@posthog/core/dist/error-tracking/parsers/chrome.mjs
|
|
1591
2206
|
var chromeRegexNoFnName = /^\s*at (\S+?)(?::(\d+))(?::(\d+))\s*$/i;
|
|
1592
2207
|
var chromeRegex = /^\s*at (?:(.+?\)(?: \[.+\])?|.*?) ?\((?:address at )?)?(?:async )?((?:<anonymous>|[-a-z]+:|.*bundle|\/)?.*?)(?::(\d+))?(?::(\d+))?\)?\s*$/i;
|
|
1593
2208
|
var chromeEvalRegex = /\((\S*)(?::(\d+))(?::(\d+))\)/;
|
|
@@ -1613,7 +2228,7 @@ var chromeStackLineParser = (line, platform) => {
|
|
|
1613
2228
|
}
|
|
1614
2229
|
};
|
|
1615
2230
|
|
|
1616
|
-
// ../../../node_modules/.bun/@posthog+core@1.
|
|
2231
|
+
// ../../../node_modules/.bun/@posthog+core@1.48.6/node_modules/@posthog/core/dist/error-tracking/parsers/gecko.mjs
|
|
1617
2232
|
var geckoREgex = /^\s*(.*?)(?:\((.*?)\))?(?:^|@)?((?:[-a-z]+)?:\/.*?|\[native code\]|[^@]*(?:bundle|\d+\.js)|\/[\w\-. /=]+)(?::(\d+))?(?::(\d+))?\s*$/i;
|
|
1618
2233
|
var geckoEvalRegex = /(\S+) line (\d+)(?: > eval line \d+)* > eval/i;
|
|
1619
2234
|
var geckoStackLineParser = (line, platform) => {
|
|
@@ -1636,14 +2251,14 @@ var geckoStackLineParser = (line, platform) => {
|
|
|
1636
2251
|
}
|
|
1637
2252
|
};
|
|
1638
2253
|
|
|
1639
|
-
// ../../../node_modules/.bun/@posthog+core@1.
|
|
2254
|
+
// ../../../node_modules/.bun/@posthog+core@1.48.6/node_modules/@posthog/core/dist/error-tracking/parsers/winjs.mjs
|
|
1640
2255
|
var winjsRegex = /^\s*at (?:((?:\[object object\])?.+) )?\(?((?:[-a-z]+):.*?):(\d+)(?::(\d+))?\)?\s*$/i;
|
|
1641
2256
|
var winjsStackLineParser = (line, platform) => {
|
|
1642
2257
|
const parts = winjsRegex.exec(line);
|
|
1643
2258
|
return parts ? createFrame(platform, parts[2], parts[1] || UNKNOWN_FUNCTION, +parts[3], parts[4] ? +parts[4] : undefined) : undefined;
|
|
1644
2259
|
};
|
|
1645
2260
|
|
|
1646
|
-
// ../../../node_modules/.bun/@posthog+core@1.
|
|
2261
|
+
// ../../../node_modules/.bun/@posthog+core@1.48.6/node_modules/@posthog/core/dist/error-tracking/parsers/opera.mjs
|
|
1647
2262
|
var opera10Regex = / line (\d+).*script (?:in )?(\S+)(?:: in function (\S+))?$/i;
|
|
1648
2263
|
var opera10StackLineParser = (line, platform) => {
|
|
1649
2264
|
const parts = opera10Regex.exec(line);
|
|
@@ -1655,9 +2270,12 @@ var opera11StackLineParser = (line, platform) => {
|
|
|
1655
2270
|
return parts ? createFrame(platform, parts[5], parts[3] || parts[4] || UNKNOWN_FUNCTION, +parts[1], +parts[2]) : undefined;
|
|
1656
2271
|
};
|
|
1657
2272
|
|
|
1658
|
-
// ../../../node_modules/.bun/@posthog+core@1.
|
|
2273
|
+
// ../../../node_modules/.bun/@posthog+core@1.48.6/node_modules/@posthog/core/dist/error-tracking/parsers/node.mjs
|
|
1659
2274
|
var FILENAME_MATCH = /^\s*[-]{4,}$/;
|
|
1660
2275
|
var FULL_MATCH = /at (?:async )?(?:(.+?)\s+\()?(?:(.+):(\d+):(\d+)?|([^)]+))\)?/;
|
|
2276
|
+
var PROMISE_COMBINATOR = /^Promise\.(?:all|any)$/;
|
|
2277
|
+
var PROMISE_INDEX = /^index \d+$/;
|
|
2278
|
+
var PROMISE_FRAME_FILENAME = "node:internal/promise";
|
|
1661
2279
|
var nodeStackLineParser = (line, platform) => {
|
|
1662
2280
|
const lineMatch = line.match(FULL_MATCH);
|
|
1663
2281
|
if (lineMatch) {
|
|
@@ -1700,6 +2318,8 @@ var nodeStackLineParser = (line, platform) => {
|
|
|
1700
2318
|
filename = filename.slice(1);
|
|
1701
2319
|
if (!filename && lineMatch[5] && !isNative)
|
|
1702
2320
|
filename = lineMatch[5];
|
|
2321
|
+
if (PROMISE_COMBINATOR.test(functionName) && PROMISE_INDEX.test(filename || ""))
|
|
2322
|
+
filename = PROMISE_FRAME_FILENAME;
|
|
1703
2323
|
return {
|
|
1704
2324
|
filename: filename ? decodeURI(filename) : undefined,
|
|
1705
2325
|
module: undefined,
|
|
@@ -1724,7 +2344,7 @@ function _parseIntOrUndefined(input) {
|
|
|
1724
2344
|
return parseInt(input || "", 10) || undefined;
|
|
1725
2345
|
}
|
|
1726
2346
|
|
|
1727
|
-
// ../../../node_modules/.bun/@posthog+core@1.
|
|
2347
|
+
// ../../../node_modules/.bun/@posthog+core@1.48.6/node_modules/@posthog/core/dist/error-tracking/parsers/index.mjs
|
|
1728
2348
|
var WEBPACK_ERROR_REGEXP = /\(error: (.*)\)/;
|
|
1729
2349
|
var STACKTRACE_FRAME_LIMIT = 50;
|
|
1730
2350
|
function reverseAndStripFrames(stack) {
|
|
@@ -1769,7 +2389,7 @@ function createStackParser(platform, ...parsers) {
|
|
|
1769
2389
|
return reverseAndStripFrames(frames);
|
|
1770
2390
|
};
|
|
1771
2391
|
}
|
|
1772
|
-
// ../../../node_modules/.bun/@posthog+core@1.
|
|
2392
|
+
// ../../../node_modules/.bun/@posthog+core@1.48.6/node_modules/@posthog/core/dist/error-tracking/coercers/dom-exception-coercer.mjs
|
|
1773
2393
|
class DOMExceptionCoercer {
|
|
1774
2394
|
match(err) {
|
|
1775
2395
|
return this.isDOMException(err) || this.isDOMError(err);
|
|
@@ -1799,18 +2419,20 @@ class DOMExceptionCoercer {
|
|
|
1799
2419
|
return isBuiltin(err, "DOMError");
|
|
1800
2420
|
}
|
|
1801
2421
|
}
|
|
1802
|
-
// ../../../node_modules/.bun/@posthog+core@1.
|
|
2422
|
+
// ../../../node_modules/.bun/@posthog+core@1.48.6/node_modules/@posthog/core/dist/error-tracking/coercers/error-coercer.mjs
|
|
1803
2423
|
class ErrorCoercer {
|
|
1804
2424
|
match(err) {
|
|
1805
|
-
return
|
|
2425
|
+
return isError(err);
|
|
1806
2426
|
}
|
|
1807
2427
|
coerce(err, ctx) {
|
|
2428
|
+
const stack = this.getStack(err);
|
|
2429
|
+
const synthetic = stack === undefined;
|
|
1808
2430
|
return {
|
|
1809
2431
|
type: this.getType(err),
|
|
1810
2432
|
value: this.getMessage(err, ctx),
|
|
1811
|
-
stack:
|
|
2433
|
+
stack: stack ?? ctx.syntheticException?.stack,
|
|
1812
2434
|
cause: err.cause ? ctx.next(err.cause) : undefined,
|
|
1813
|
-
synthetic
|
|
2435
|
+
synthetic
|
|
1814
2436
|
};
|
|
1815
2437
|
}
|
|
1816
2438
|
getType(err) {
|
|
@@ -1826,25 +2448,41 @@ class ErrorCoercer {
|
|
|
1826
2448
|
return err.stacktrace || err.stack || undefined;
|
|
1827
2449
|
}
|
|
1828
2450
|
}
|
|
1829
|
-
// ../../../node_modules/.bun/@posthog+core@1.
|
|
2451
|
+
// ../../../node_modules/.bun/@posthog+core@1.48.6/node_modules/@posthog/core/dist/error-tracking/coercers/error-event-coercer.mjs
|
|
1830
2452
|
class ErrorEventCoercer {
|
|
1831
2453
|
constructor() {}
|
|
1832
2454
|
match(err) {
|
|
1833
|
-
|
|
2455
|
+
if (!isErrorEvent(err))
|
|
2456
|
+
return false;
|
|
2457
|
+
const errorEvent = err;
|
|
2458
|
+
return errorEvent.error != null || this._hasUsableMessage(errorEvent);
|
|
1834
2459
|
}
|
|
1835
2460
|
coerce(err, ctx) {
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
2461
|
+
if (err.error != null)
|
|
2462
|
+
return ctx.apply(err.error);
|
|
2463
|
+
const exceptionLike = ctx.apply(err.message);
|
|
2464
|
+
return {
|
|
2465
|
+
...exceptionLike,
|
|
2466
|
+
stack: this._buildLocationStack(err) ?? exceptionLike.stack,
|
|
2467
|
+
synthetic: true
|
|
2468
|
+
};
|
|
2469
|
+
}
|
|
2470
|
+
_hasUsableMessage(err) {
|
|
2471
|
+
return isString(err.message) && err.message.length > 0;
|
|
2472
|
+
}
|
|
2473
|
+
_buildLocationStack(err) {
|
|
2474
|
+
const location = err;
|
|
2475
|
+
const lineno = location.lineno ?? 0;
|
|
2476
|
+
const colno = location.colno ?? 0;
|
|
2477
|
+
if (!isString(location.filename) || location.filename.length === 0)
|
|
2478
|
+
return;
|
|
2479
|
+
if (lineno === 0)
|
|
2480
|
+
return;
|
|
2481
|
+
return `Error
|
|
2482
|
+
at ${location.filename}:${lineno}:${colno}`;
|
|
1845
2483
|
}
|
|
1846
2484
|
}
|
|
1847
|
-
// ../../../node_modules/.bun/@posthog+core@1.
|
|
2485
|
+
// ../../../node_modules/.bun/@posthog+core@1.48.6/node_modules/@posthog/core/dist/error-tracking/coercers/string-coercer.mjs
|
|
1848
2486
|
var ERROR_TYPES_PATTERN = /^(?:[Uu]ncaught (?:exception: )?)?(?:((?:Eval|Internal|Range|Reference|Syntax|Type|URI|)Error): )?(.*)$/i;
|
|
1849
2487
|
|
|
1850
2488
|
class StringCoercer {
|
|
@@ -1874,7 +2512,7 @@ class StringCoercer {
|
|
|
1874
2512
|
];
|
|
1875
2513
|
}
|
|
1876
2514
|
}
|
|
1877
|
-
// ../../../node_modules/.bun/@posthog+core@1.
|
|
2515
|
+
// ../../../node_modules/.bun/@posthog+core@1.48.6/node_modules/@posthog/core/dist/error-tracking/types.mjs
|
|
1878
2516
|
var severityLevels = [
|
|
1879
2517
|
"fatal",
|
|
1880
2518
|
"error",
|
|
@@ -1884,7 +2522,7 @@ var severityLevels = [
|
|
|
1884
2522
|
"debug"
|
|
1885
2523
|
];
|
|
1886
2524
|
|
|
1887
|
-
// ../../../node_modules/.bun/@posthog+core@1.
|
|
2525
|
+
// ../../../node_modules/.bun/@posthog+core@1.48.6/node_modules/@posthog/core/dist/error-tracking/coercers/utils.mjs
|
|
1888
2526
|
function extractExceptionKeysForMessage(err, maxLength = 40) {
|
|
1889
2527
|
const keys = Object.keys(err);
|
|
1890
2528
|
keys.sort();
|
|
@@ -1901,7 +2539,7 @@ function extractExceptionKeysForMessage(err, maxLength = 40) {
|
|
|
1901
2539
|
return "";
|
|
1902
2540
|
}
|
|
1903
2541
|
|
|
1904
|
-
// ../../../node_modules/.bun/@posthog+core@1.
|
|
2542
|
+
// ../../../node_modules/.bun/@posthog+core@1.48.6/node_modules/@posthog/core/dist/error-tracking/coercers/object-coercer.mjs
|
|
1905
2543
|
class ObjectCoercer {
|
|
1906
2544
|
match(candidate) {
|
|
1907
2545
|
return typeof candidate == "object" && candidate !== null;
|
|
@@ -1913,13 +2551,16 @@ class ObjectCoercer {
|
|
|
1913
2551
|
return {
|
|
1914
2552
|
type: this.getType(candidate),
|
|
1915
2553
|
value: this.getValue(candidate),
|
|
1916
|
-
stack: ctx.syntheticException?.stack,
|
|
2554
|
+
stack: this.getStack(candidate) ?? ctx.syntheticException?.stack,
|
|
1917
2555
|
level: this.isSeverityLevel(candidate.level) ? candidate.level : "error",
|
|
1918
2556
|
synthetic: true
|
|
1919
2557
|
};
|
|
1920
2558
|
}
|
|
1921
2559
|
getType(err) {
|
|
1922
|
-
|
|
2560
|
+
if (isEvent(err))
|
|
2561
|
+
return err.constructor.name;
|
|
2562
|
+
const name = "name" in err ? err.name : undefined;
|
|
2563
|
+
return isString(name) && !isEmptyString(name) ? name : "Error";
|
|
1923
2564
|
}
|
|
1924
2565
|
getValue(err) {
|
|
1925
2566
|
if ("name" in err && typeof err.name == "string") {
|
|
@@ -1937,6 +2578,15 @@ class ObjectCoercer {
|
|
|
1937
2578
|
isSeverityLevel(x) {
|
|
1938
2579
|
return isString(x) && !isEmptyString(x) && severityLevels.indexOf(x) >= 0;
|
|
1939
2580
|
}
|
|
2581
|
+
getStack(candidate) {
|
|
2582
|
+
try {
|
|
2583
|
+
if (isString(candidate.stacktrace) && candidate.stacktrace.length > 0)
|
|
2584
|
+
return candidate.stacktrace;
|
|
2585
|
+
return isString(candidate.stack) && candidate.stack.length > 0 ? candidate.stack : undefined;
|
|
2586
|
+
} catch {
|
|
2587
|
+
return;
|
|
2588
|
+
}
|
|
2589
|
+
}
|
|
1940
2590
|
getErrorPropertyFromObject(obj) {
|
|
1941
2591
|
for (const prop in obj)
|
|
1942
2592
|
if (Object.prototype.hasOwnProperty.call(obj, prop)) {
|
|
@@ -1954,7 +2604,7 @@ class ObjectCoercer {
|
|
|
1954
2604
|
}
|
|
1955
2605
|
}
|
|
1956
2606
|
}
|
|
1957
|
-
// ../../../node_modules/.bun/@posthog+core@1.
|
|
2607
|
+
// ../../../node_modules/.bun/@posthog+core@1.48.6/node_modules/@posthog/core/dist/error-tracking/coercers/event-coercer.mjs
|
|
1958
2608
|
class EventCoercer {
|
|
1959
2609
|
match(err) {
|
|
1960
2610
|
return isEvent(err);
|
|
@@ -1969,7 +2619,7 @@ class EventCoercer {
|
|
|
1969
2619
|
};
|
|
1970
2620
|
}
|
|
1971
2621
|
}
|
|
1972
|
-
// ../../../node_modules/.bun/@posthog+core@1.
|
|
2622
|
+
// ../../../node_modules/.bun/@posthog+core@1.48.6/node_modules/@posthog/core/dist/error-tracking/coercers/primitive-coercer.mjs
|
|
1973
2623
|
class PrimitiveCoercer {
|
|
1974
2624
|
match(candidate) {
|
|
1975
2625
|
return isPrimitive(candidate);
|
|
@@ -1983,7 +2633,7 @@ class PrimitiveCoercer {
|
|
|
1983
2633
|
};
|
|
1984
2634
|
}
|
|
1985
2635
|
}
|
|
1986
|
-
// ../../../node_modules/.bun/@posthog+core@1.
|
|
2636
|
+
// ../../../node_modules/.bun/@posthog+core@1.48.6/node_modules/@posthog/core/dist/error-tracking/coercers/promise-rejection-event.mjs
|
|
1987
2637
|
class PromiseRejectionEventCoercer {
|
|
1988
2638
|
match(err) {
|
|
1989
2639
|
return isBuiltin(err, "PromiseRejectionEvent") || this.isCustomEventWrappingRejection(err);
|
|
@@ -2019,7 +2669,7 @@ class PromiseRejectionEventCoercer {
|
|
|
2019
2669
|
return error;
|
|
2020
2670
|
}
|
|
2021
2671
|
}
|
|
2022
|
-
// ../../../node_modules/.bun/@posthog+core@1.
|
|
2672
|
+
// ../../../node_modules/.bun/@posthog+core@1.48.6/node_modules/@posthog/core/dist/error-tracking/utils.mjs
|
|
2023
2673
|
class ReduceableCache {
|
|
2024
2674
|
constructor(_maxSize) {
|
|
2025
2675
|
this._maxSize = _maxSize;
|
|
@@ -2044,7 +2694,7 @@ class ReduceableCache {
|
|
|
2044
2694
|
}
|
|
2045
2695
|
}
|
|
2046
2696
|
}
|
|
2047
|
-
// ../../../node_modules/.bun/@posthog+core@1.
|
|
2697
|
+
// ../../../node_modules/.bun/@posthog+core@1.48.6/node_modules/@posthog/core/dist/error-tracking/exception-steps.mjs
|
|
2048
2698
|
var EXCEPTION_STEP_INTERNAL_FIELDS = {
|
|
2049
2699
|
MESSAGE: "$message",
|
|
2050
2700
|
TIMESTAMP: "$timestamp"
|
|
@@ -2139,9 +2789,12 @@ function normalizePositiveInteger(input, fallback) {
|
|
|
2139
2789
|
return normalized;
|
|
2140
2790
|
}
|
|
2141
2791
|
function normalizeAndSerializeStep(step) {
|
|
2142
|
-
|
|
2143
|
-
|
|
2792
|
+
let json;
|
|
2793
|
+
try {
|
|
2794
|
+
json = safeJsonStringify(step);
|
|
2795
|
+
} catch {
|
|
2144
2796
|
return;
|
|
2797
|
+
}
|
|
2145
2798
|
try {
|
|
2146
2799
|
const parsed = JSON.parse(json);
|
|
2147
2800
|
if (!isObject(parsed))
|
|
@@ -2161,33 +2814,6 @@ function normalizeAndSerializeStep(step) {
|
|
|
2161
2814
|
return;
|
|
2162
2815
|
}
|
|
2163
2816
|
}
|
|
2164
|
-
function safeStringify(value) {
|
|
2165
|
-
const seen = new WeakSet;
|
|
2166
|
-
try {
|
|
2167
|
-
return JSON.stringify(value, (_key, replacementValue) => {
|
|
2168
|
-
if (typeof replacementValue == "bigint")
|
|
2169
|
-
return replacementValue.toString();
|
|
2170
|
-
if (typeof replacementValue == "function" || typeof replacementValue == "symbol")
|
|
2171
|
-
return;
|
|
2172
|
-
if (replacementValue instanceof Date)
|
|
2173
|
-
return replacementValue.toISOString();
|
|
2174
|
-
if (replacementValue instanceof Error)
|
|
2175
|
-
return {
|
|
2176
|
-
name: replacementValue.name,
|
|
2177
|
-
message: replacementValue.message,
|
|
2178
|
-
stack: replacementValue.stack
|
|
2179
|
-
};
|
|
2180
|
-
if (replacementValue && typeof replacementValue == "object") {
|
|
2181
|
-
if (seen.has(replacementValue))
|
|
2182
|
-
return "[Circular]";
|
|
2183
|
-
seen.add(replacementValue);
|
|
2184
|
-
}
|
|
2185
|
-
return replacementValue;
|
|
2186
|
-
});
|
|
2187
|
-
} catch {
|
|
2188
|
-
return;
|
|
2189
|
-
}
|
|
2190
|
-
}
|
|
2191
2817
|
function getUtf8ByteLength(value) {
|
|
2192
2818
|
if (typeof TextEncoder != "undefined")
|
|
2193
2819
|
return new TextEncoder().encode(value).length;
|
|
@@ -2201,19 +2827,65 @@ function getUtf8ByteLength(value) {
|
|
|
2201
2827
|
byteLength += 1;
|
|
2202
2828
|
return byteLength;
|
|
2203
2829
|
}
|
|
2204
|
-
// ../../../node_modules/.bun/@posthog+core@1.
|
|
2830
|
+
// ../../../node_modules/.bun/@posthog+core@1.48.6/node_modules/@posthog/core/dist/error-tracking/release.mjs
|
|
2831
|
+
function getInjectedReleaseId() {
|
|
2832
|
+
const injected = globalThis._posthogReleaseId;
|
|
2833
|
+
return typeof injected == "string" && injected.length > 0 ? injected : undefined;
|
|
2834
|
+
}
|
|
2835
|
+
// ../../../node_modules/.bun/@posthog+core@1.48.6/node_modules/@posthog/core/dist/posthog-core-stateless.mjs
|
|
2205
2836
|
class PostHogFetchHttpError extends Error {
|
|
2206
|
-
constructor(response, reqByteLength) {
|
|
2207
|
-
super("HTTP error while fetching PostHog: status=" + response.status + ", reqByteLength=" + reqByteLength), this.response = response, this.reqByteLength = reqByteLength, this.name = "PostHogFetchHttpError";
|
|
2837
|
+
constructor(response, reqByteLength, responseBodyDeadline, abortController) {
|
|
2838
|
+
super("HTTP error while fetching PostHog: status=" + response.status + ", reqByteLength=" + reqByteLength), this.response = response, this.reqByteLength = reqByteLength, this.responseBodyDeadline = responseBodyDeadline, this.abortController = abortController, this.name = "PostHogFetchHttpError", this._bodyReadTimedOut = false;
|
|
2208
2839
|
}
|
|
2209
2840
|
get status() {
|
|
2210
2841
|
return this.response.status;
|
|
2211
2842
|
}
|
|
2843
|
+
get bodyReadTimedOut() {
|
|
2844
|
+
return this._bodyReadTimedOut;
|
|
2845
|
+
}
|
|
2212
2846
|
get text() {
|
|
2213
|
-
|
|
2847
|
+
if (!this.responseBodyTextPromise)
|
|
2848
|
+
if (Date.now() >= this.responseBodyDeadline) {
|
|
2849
|
+
this._bodyReadTimedOut = true;
|
|
2850
|
+
const timeoutError = new Error("Response body read timed out");
|
|
2851
|
+
timeoutError.name = "AbortError";
|
|
2852
|
+
this.cancelResponseBody(timeoutError);
|
|
2853
|
+
this.responseBodyTextPromise = Promise.reject(timeoutError);
|
|
2854
|
+
} else {
|
|
2855
|
+
const responseBodyTimeout = new Promise((_resolve, reject) => {
|
|
2856
|
+
this.responseBodyTimer = safeSetTimeout(() => {
|
|
2857
|
+
this._bodyReadTimedOut = true;
|
|
2858
|
+
const timeoutError = new Error("Response body read timed out");
|
|
2859
|
+
timeoutError.name = "AbortError";
|
|
2860
|
+
reject(timeoutError);
|
|
2861
|
+
this.cancelResponseBody(timeoutError);
|
|
2862
|
+
}, this.responseBodyDeadline - Date.now());
|
|
2863
|
+
});
|
|
2864
|
+
let responseBodyText;
|
|
2865
|
+
try {
|
|
2866
|
+
responseBodyText = Promise.resolve(this.response.text());
|
|
2867
|
+
} catch (error) {
|
|
2868
|
+
responseBodyText = Promise.reject(error);
|
|
2869
|
+
}
|
|
2870
|
+
this.responseBodyTextPromise = Promise.race([
|
|
2871
|
+
responseBodyText,
|
|
2872
|
+
responseBodyTimeout
|
|
2873
|
+
]).finally(() => clearTimeout(this.responseBodyTimer));
|
|
2874
|
+
}
|
|
2875
|
+
return this.responseBodyTextPromise;
|
|
2214
2876
|
}
|
|
2215
2877
|
get json() {
|
|
2216
|
-
return this.
|
|
2878
|
+
return this.text.then((text) => JSON.parse(text));
|
|
2879
|
+
}
|
|
2880
|
+
cancelResponseBody(reason) {
|
|
2881
|
+
clearTimeout(this.responseBodyTimer);
|
|
2882
|
+
if (!this.abortController.signal.aborted)
|
|
2883
|
+
this.abortController.abort(reason);
|
|
2884
|
+
(async () => {
|
|
2885
|
+
try {
|
|
2886
|
+
await this.response.body?.cancel();
|
|
2887
|
+
} catch {}
|
|
2888
|
+
})();
|
|
2217
2889
|
}
|
|
2218
2890
|
}
|
|
2219
2891
|
|
|
@@ -2224,12 +2896,20 @@ class PostHogFetchNetworkError extends Error {
|
|
|
2224
2896
|
} : {}), this.error = error, this.name = "PostHogFetchNetworkError";
|
|
2225
2897
|
}
|
|
2226
2898
|
}
|
|
2899
|
+
var applyCallerFeatureFlagOverrides = (target, callerProperties) => {
|
|
2900
|
+
for (const key of Object.keys(callerProperties))
|
|
2901
|
+
if (key.startsWith("$feature/") || key === "$active_feature_flags")
|
|
2902
|
+
target[key] = callerProperties[key];
|
|
2903
|
+
};
|
|
2227
2904
|
async function logFlushError(err) {
|
|
2228
2905
|
if (err instanceof PostHogFetchHttpError) {
|
|
2229
2906
|
let text = "";
|
|
2230
2907
|
try {
|
|
2231
2908
|
text = await err.text;
|
|
2232
|
-
} catch {
|
|
2909
|
+
} catch {
|
|
2910
|
+
if (err.bodyReadTimedOut)
|
|
2911
|
+
text = "<response body read timed out>";
|
|
2912
|
+
}
|
|
2233
2913
|
console.error(`Error while flushing PostHog: message=${err.message}, response body=${text}`, err);
|
|
2234
2914
|
} else
|
|
2235
2915
|
console.error("Error while flushing PostHog", err);
|
|
@@ -2241,9 +2921,28 @@ function isPostHogFetchError(err) {
|
|
|
2241
2921
|
function isPostHogFetchNetworkError(err) {
|
|
2242
2922
|
return err instanceof PostHogFetchNetworkError;
|
|
2243
2923
|
}
|
|
2924
|
+
function isRetryableFlagsFetchError(err) {
|
|
2925
|
+
if (err instanceof PostHogFetchHttpError)
|
|
2926
|
+
return err.status === 502 || err.status === 504;
|
|
2927
|
+
if (!(err instanceof PostHogFetchNetworkError))
|
|
2928
|
+
return false;
|
|
2929
|
+
const cause = err.error;
|
|
2930
|
+
const code = cause?.code ?? cause?.cause?.code;
|
|
2931
|
+
return code !== "ECONNREFUSED";
|
|
2932
|
+
}
|
|
2244
2933
|
function isPostHogFetchContentTooLargeError(err) {
|
|
2245
2934
|
return typeof err == "object" && err instanceof PostHogFetchHttpError && err.status === 413;
|
|
2246
2935
|
}
|
|
2936
|
+
function isPostHogFetchRetryableError(err) {
|
|
2937
|
+
if (err instanceof PostHogFetchHttpError)
|
|
2938
|
+
return err.status === 408 || err.status === 429 || err.status >= 500;
|
|
2939
|
+
return isPostHogFetchNetworkError(err);
|
|
2940
|
+
}
|
|
2941
|
+
function isPostHogEventProperties(value) {
|
|
2942
|
+
return value !== null && typeof value == "object" && !Array.isArray(value);
|
|
2943
|
+
}
|
|
2944
|
+
var DEFAULT_QUEUE_ROUTE = "default";
|
|
2945
|
+
|
|
2247
2946
|
class PostHogCoreStateless {
|
|
2248
2947
|
getErrorPropertiesBuilder() {
|
|
2249
2948
|
if (!this._errorPropertiesBuilder)
|
|
@@ -2260,6 +2959,9 @@ class PostHogCoreStateless {
|
|
|
2260
2959
|
}
|
|
2261
2960
|
constructor(apiKey, options = {}) {
|
|
2262
2961
|
this.flushPromise = null;
|
|
2962
|
+
this.pendingFlushPromise = null;
|
|
2963
|
+
this.flushPromises = new Set;
|
|
2964
|
+
this._dequeuedMessagesCount = 0;
|
|
2263
2965
|
this.shutdownPromise = null;
|
|
2264
2966
|
this.promiseQueue = new PromiseQueue;
|
|
2265
2967
|
this._events = new SimpleEventEmitter;
|
|
@@ -2282,10 +2984,11 @@ class PostHogCoreStateless {
|
|
|
2282
2984
|
this._retryOptions = {
|
|
2283
2985
|
retryCount: options.fetchRetryCount ?? 3,
|
|
2284
2986
|
retryDelay: options.fetchRetryDelay ?? 3000,
|
|
2285
|
-
retryCheck:
|
|
2987
|
+
retryCheck: isPostHogFetchRetryableError
|
|
2286
2988
|
};
|
|
2287
2989
|
this.requestTimeout = options.requestTimeout ?? 1e4;
|
|
2288
2990
|
this.featureFlagsRequestTimeoutMs = options.featureFlagsRequestTimeoutMs ?? 3000;
|
|
2991
|
+
this.featureFlagsRequestMaxRetries = options.featureFlagsRequestMaxRetries ?? 1;
|
|
2289
2992
|
this.remoteConfigRequestTimeoutMs = options.remoteConfigRequestTimeoutMs ?? 3000;
|
|
2290
2993
|
this.disableGeoip = options.disableGeoip ?? true;
|
|
2291
2994
|
this.disabled = (options.disabled ?? false) || missingApiKey;
|
|
@@ -2347,15 +3050,23 @@ class PostHogCoreStateless {
|
|
|
2347
3050
|
return this.disabled;
|
|
2348
3051
|
}
|
|
2349
3052
|
buildPayload(payload) {
|
|
3053
|
+
const userProperties = payload.properties || {};
|
|
3054
|
+
let properties = {
|
|
3055
|
+
...userProperties,
|
|
3056
|
+
...this.getCommonEventProperties()
|
|
3057
|
+
};
|
|
3058
|
+
applyCallerFeatureFlagOverrides(properties, userProperties);
|
|
3059
|
+
if (payload.event === "$feature_flag_called" && properties.$feature_flag_has_experiment === false && this.isMinimalFlagCalledEventsEnabled())
|
|
3060
|
+
properties = minimizeFlagCalledEventProperties(properties);
|
|
2350
3061
|
return {
|
|
2351
3062
|
distinct_id: payload.distinct_id,
|
|
2352
3063
|
event: payload.event,
|
|
2353
|
-
properties
|
|
2354
|
-
...payload.properties || {},
|
|
2355
|
-
...this.getCommonEventProperties()
|
|
2356
|
-
}
|
|
3064
|
+
properties
|
|
2357
3065
|
};
|
|
2358
3066
|
}
|
|
3067
|
+
isMinimalFlagCalledEventsEnabled() {
|
|
3068
|
+
return false;
|
|
3069
|
+
}
|
|
2359
3070
|
addPendingPromise(promise) {
|
|
2360
3071
|
return this.promiseQueue.add(promise);
|
|
2361
3072
|
}
|
|
@@ -2440,6 +3151,19 @@ class PostHogCoreStateless {
|
|
|
2440
3151
|
this.enqueue("capture", payload, options);
|
|
2441
3152
|
});
|
|
2442
3153
|
}
|
|
3154
|
+
async groupIdentifyStatelessImmediate(groupType, groupKey, groupProperties, options, distinctId, eventProperties) {
|
|
3155
|
+
const payload = this.buildPayload({
|
|
3156
|
+
distinct_id: distinctId || `$${groupType}_${groupKey}`,
|
|
3157
|
+
event: "$groupidentify",
|
|
3158
|
+
properties: {
|
|
3159
|
+
$group_type: groupType,
|
|
3160
|
+
$group_key: groupKey,
|
|
3161
|
+
$group_set: groupProperties || {},
|
|
3162
|
+
...eventProperties || {}
|
|
3163
|
+
}
|
|
3164
|
+
});
|
|
3165
|
+
await this.sendImmediate("capture", payload, options);
|
|
3166
|
+
}
|
|
2443
3167
|
async getRemoteConfig() {
|
|
2444
3168
|
await this._initPromise;
|
|
2445
3169
|
let host = this.host;
|
|
@@ -2456,8 +3180,11 @@ class PostHogCoreStateless {
|
|
|
2456
3180
|
}
|
|
2457
3181
|
};
|
|
2458
3182
|
return this.fetchWithRetry(url, fetchOptions, {
|
|
3183
|
+
type: "required",
|
|
3184
|
+
consume: (response) => response.json()
|
|
3185
|
+
}, {
|
|
2459
3186
|
retryCount: 0
|
|
2460
|
-
}, this.remoteConfigRequestTimeoutMs).
|
|
3187
|
+
}, this.remoteConfigRequestTimeoutMs).catch((error) => {
|
|
2461
3188
|
this._logger.error("Remote config could not be loaded", error);
|
|
2462
3189
|
this._events.emit("error", error);
|
|
2463
3190
|
});
|
|
@@ -2488,8 +3215,12 @@ class PostHogCoreStateless {
|
|
|
2488
3215
|
};
|
|
2489
3216
|
this._logger.info("Flags URL", url);
|
|
2490
3217
|
return this.fetchWithRetry(url, fetchOptions, {
|
|
2491
|
-
|
|
2492
|
-
|
|
3218
|
+
type: "required",
|
|
3219
|
+
consume: (response) => response.json()
|
|
3220
|
+
}, {
|
|
3221
|
+
retryCount: this.featureFlagsRequestMaxRetries,
|
|
3222
|
+
retryCheck: isRetryableFlagsFetchError
|
|
3223
|
+
}, this.featureFlagsRequestTimeoutMs).then((response) => ({
|
|
2493
3224
|
success: true,
|
|
2494
3225
|
response: normalizeFlagsResponse(response)
|
|
2495
3226
|
})).catch((error) => {
|
|
@@ -2589,9 +3320,9 @@ class PostHogCoreStateless {
|
|
|
2589
3320
|
}
|
|
2590
3321
|
async getFeatureFlagDetailsStateless(distinctId, groups = {}, personProperties = {}, groupProperties = {}, disableGeoip, flagKeysToEvaluate) {
|
|
2591
3322
|
await this._initPromise;
|
|
2592
|
-
const extraPayload = {
|
|
2593
|
-
|
|
2594
|
-
|
|
3323
|
+
const extraPayload = {
|
|
3324
|
+
geoip_disable: disableGeoip ?? this.disableGeoip
|
|
3325
|
+
};
|
|
2595
3326
|
if (flagKeysToEvaluate)
|
|
2596
3327
|
extraPayload["flag_keys_to_evaluate"] = flagKeysToEvaluate;
|
|
2597
3328
|
const result = await this.getFlags(distinctId, groups, personProperties, groupProperties, extraPayload);
|
|
@@ -2628,15 +3359,18 @@ class PostHogCoreStateless {
|
|
|
2628
3359
|
"Content-Type": "application/json"
|
|
2629
3360
|
}
|
|
2630
3361
|
};
|
|
2631
|
-
const response = await this.fetchWithRetry(url, fetchOptions
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
|
|
2635
|
-
|
|
2636
|
-
|
|
2637
|
-
|
|
3362
|
+
const response = await this.fetchWithRetry(url, fetchOptions, {
|
|
3363
|
+
type: "required",
|
|
3364
|
+
consume: (response2) => {
|
|
3365
|
+
if (response2.status !== 200 || !response2.json) {
|
|
3366
|
+
const msg = `Surveys API could not be loaded: ${response2.status}`;
|
|
3367
|
+
const error = new Error(msg);
|
|
3368
|
+
this._logger.error(error);
|
|
3369
|
+
this._events.emit("error", new Error(msg));
|
|
3370
|
+
return Promise.resolve(undefined);
|
|
3371
|
+
}
|
|
3372
|
+
return response2.json();
|
|
2638
3373
|
}
|
|
2639
|
-
return response2.json();
|
|
2640
3374
|
}).catch((error) => {
|
|
2641
3375
|
this._logger.error("Surveys API could not be loaded", error);
|
|
2642
3376
|
this._events.emit("error", error);
|
|
@@ -2673,23 +3407,39 @@ class PostHogCoreStateless {
|
|
|
2673
3407
|
return message;
|
|
2674
3408
|
}
|
|
2675
3409
|
async flushStorage() {}
|
|
2676
|
-
|
|
3410
|
+
getQueueRouteKey(_message) {
|
|
3411
|
+
return DEFAULT_QUEUE_ROUTE;
|
|
3412
|
+
}
|
|
3413
|
+
persistedQueueKeyForRoute(_route) {
|
|
3414
|
+
return types_PostHogPersistedProperty.Queue;
|
|
3415
|
+
}
|
|
3416
|
+
getActiveQueueRoutes() {
|
|
3417
|
+
return [
|
|
3418
|
+
DEFAULT_QUEUE_ROUTE
|
|
3419
|
+
];
|
|
3420
|
+
}
|
|
3421
|
+
getRouteQueue(route) {
|
|
3422
|
+
return this.getPersistedProperty(this.persistedQueueKeyForRoute(route)) || [];
|
|
3423
|
+
}
|
|
3424
|
+
enqueue(type, _message, options, explicitRoute) {
|
|
2677
3425
|
this.wrap(() => {
|
|
2678
3426
|
if (this.optedOut)
|
|
2679
3427
|
return void this._events.emit(type, "Library is disabled. Not sending event. To re-enable, call posthog.optIn()");
|
|
2680
|
-
let message = this.prepareMessage(
|
|
3428
|
+
let message = this.prepareMessage(_message, options);
|
|
2681
3429
|
message = this.processBeforeEnqueue(message);
|
|
2682
3430
|
if (message === null)
|
|
2683
3431
|
return;
|
|
2684
|
-
|
|
3432
|
+
message = this.normalizeMessage(message);
|
|
3433
|
+
const queueKey = this.persistedQueueKeyForRoute(explicitRoute ?? this.getQueueRouteKey(message));
|
|
3434
|
+
const queue = this.getPersistedProperty(queueKey) || [];
|
|
2685
3435
|
if (queue.length >= this.maxQueueSize) {
|
|
2686
3436
|
queue.shift();
|
|
2687
|
-
this._logger.
|
|
3437
|
+
this._logger.warn("Queue is full, the oldest event is dropped.");
|
|
2688
3438
|
}
|
|
2689
3439
|
queue.push({
|
|
2690
3440
|
message
|
|
2691
3441
|
});
|
|
2692
|
-
this.setPersistedProperty(
|
|
3442
|
+
this.setPersistedProperty(queueKey, queue);
|
|
2693
3443
|
this._events.emit(type, message);
|
|
2694
3444
|
if (queue.length >= this.flushAt)
|
|
2695
3445
|
this.flushBackground();
|
|
@@ -2697,61 +3447,63 @@ class PostHogCoreStateless {
|
|
|
2697
3447
|
this._flushTimer = safeSetTimeout(() => this.flushBackground(), this.flushInterval);
|
|
2698
3448
|
});
|
|
2699
3449
|
}
|
|
2700
|
-
async sendImmediate(type, _message, options) {
|
|
3450
|
+
async sendImmediate(type, _message, options, explicitRoute) {
|
|
2701
3451
|
if (this.disabled)
|
|
2702
3452
|
return void this._logger.warn("The client is disabled");
|
|
2703
3453
|
if (!this._isInitialized)
|
|
2704
3454
|
await this._initPromise;
|
|
2705
3455
|
if (this.optedOut)
|
|
2706
3456
|
return void this._events.emit(type, "Library is disabled. Not sending event. To re-enable, call posthog.optIn()");
|
|
2707
|
-
let message = this.prepareMessage(
|
|
3457
|
+
let message = this.prepareMessage(_message, options);
|
|
2708
3458
|
message = this.processBeforeEnqueue(message);
|
|
2709
3459
|
if (message === null)
|
|
2710
3460
|
return;
|
|
2711
|
-
|
|
2712
|
-
api_key: this.apiKey,
|
|
2713
|
-
batch: [
|
|
2714
|
-
message
|
|
2715
|
-
],
|
|
2716
|
-
sent_at: currentISOTime()
|
|
2717
|
-
};
|
|
2718
|
-
if (this.historicalMigration)
|
|
2719
|
-
data.historical_migration = true;
|
|
2720
|
-
const payload = JSON.stringify(data);
|
|
2721
|
-
const url = `${this.host}/batch/`;
|
|
2722
|
-
const gzippedPayload = this.disableCompression ? null : await gzipCompress(payload, this.isDebug);
|
|
2723
|
-
const fetchOptions = {
|
|
2724
|
-
method: "POST",
|
|
2725
|
-
headers: {
|
|
2726
|
-
...this.getCustomHeaders(),
|
|
2727
|
-
"Content-Type": "application/json",
|
|
2728
|
-
...gzippedPayload !== null && {
|
|
2729
|
-
"Content-Encoding": "gzip"
|
|
2730
|
-
}
|
|
2731
|
-
},
|
|
2732
|
-
body: gzippedPayload || payload
|
|
2733
|
-
};
|
|
3461
|
+
message = this.normalizeMessage(message);
|
|
2734
3462
|
try {
|
|
2735
|
-
|
|
2736
|
-
|
|
3463
|
+
await this.sendBatch([
|
|
3464
|
+
message
|
|
3465
|
+
], undefined, explicitRoute ?? this.getQueueRouteKey(message));
|
|
2737
3466
|
} catch (err) {
|
|
2738
3467
|
this._events.emit("error", err);
|
|
2739
3468
|
}
|
|
2740
3469
|
}
|
|
2741
|
-
|
|
3470
|
+
normalizeMessage(message) {
|
|
3471
|
+
const { type: _type, library, library_version, ...sanitizedMessage } = message;
|
|
3472
|
+
let properties = isPostHogEventProperties(sanitizedMessage.properties) ? sanitizedMessage.properties : undefined;
|
|
3473
|
+
if (library !== undefined && properties?.$lib === undefined)
|
|
3474
|
+
properties = {
|
|
3475
|
+
...properties || {},
|
|
3476
|
+
$lib: library
|
|
3477
|
+
};
|
|
3478
|
+
if (library_version !== undefined && properties?.$lib_version === undefined)
|
|
3479
|
+
properties = {
|
|
3480
|
+
...properties || {},
|
|
3481
|
+
$lib_version: library_version
|
|
3482
|
+
};
|
|
3483
|
+
if (properties)
|
|
3484
|
+
sanitizedMessage.properties = properties;
|
|
3485
|
+
sanitizedMessage.uuid = getEventUuid(sanitizedMessage.uuid, uuidv7);
|
|
3486
|
+
return sanitizedMessage;
|
|
3487
|
+
}
|
|
3488
|
+
normalizeTimestampForWire(timestamp) {
|
|
3489
|
+
const parsedTimestamp = timestamp instanceof Date ? timestamp : typeof timestamp == "string" ? new Date(timestamp) : null;
|
|
3490
|
+
if (!parsedTimestamp || Number.isNaN(parsedTimestamp.getTime()))
|
|
3491
|
+
return timestamp;
|
|
3492
|
+
const normalized = parsedTimestamp.toISOString();
|
|
3493
|
+
const fractionalSeconds = typeof timestamp == "string" ? timestamp.match(/\.(\d+)(?:Z|[+-]\d{2}:?\d{2})?$/i)?.[1] : undefined;
|
|
3494
|
+
return fractionalSeconds && fractionalSeconds.length > 3 ? normalized.replace(/\.\d{3}Z$/, `.${fractionalSeconds}Z`) : normalized;
|
|
3495
|
+
}
|
|
3496
|
+
prepareMessage(_message, options) {
|
|
2742
3497
|
const message = {
|
|
2743
3498
|
..._message,
|
|
2744
|
-
type,
|
|
2745
|
-
library: this.getLibraryId(),
|
|
2746
|
-
library_version: this.getLibraryVersion(),
|
|
2747
3499
|
timestamp: options?.timestamp ? options?.timestamp : currentISOTime(),
|
|
2748
|
-
uuid: options?.uuid
|
|
3500
|
+
uuid: getEventUuid(options?.uuid, uuidv7)
|
|
2749
3501
|
};
|
|
2750
3502
|
const addGeoipDisableProperty = options?.disableGeoip ?? this.disableGeoip;
|
|
2751
3503
|
if (addGeoipDisableProperty) {
|
|
2752
|
-
if (!message.properties)
|
|
3504
|
+
if (!isPostHogEventProperties(message.properties))
|
|
2753
3505
|
message.properties = {};
|
|
2754
|
-
message
|
|
3506
|
+
message.properties["$geoip_disable"] = true;
|
|
2755
3507
|
}
|
|
2756
3508
|
if (message.distinctId) {
|
|
2757
3509
|
message.distinct_id = message.distinctId;
|
|
@@ -2766,21 +3518,64 @@ class PostHogCoreStateless {
|
|
|
2766
3518
|
}
|
|
2767
3519
|
}
|
|
2768
3520
|
flushBackground() {
|
|
3521
|
+
if (this.pendingFlushPromise)
|
|
3522
|
+
return;
|
|
2769
3523
|
this.flush().catch(async (err) => {
|
|
2770
3524
|
await logFlushError(err);
|
|
2771
3525
|
});
|
|
2772
3526
|
}
|
|
2773
|
-
async
|
|
3527
|
+
async waitForPendingPromises(maxPromiseId, ignoredPromises = []) {
|
|
3528
|
+
const ignoredPendingPromises = ignoredPromises.filter((promise) => !!promise);
|
|
3529
|
+
let iteration = 0;
|
|
3530
|
+
while (true) {
|
|
3531
|
+
const promises = this.promiseQueue.getPromises([
|
|
3532
|
+
...ignoredPendingPromises,
|
|
3533
|
+
...this.flushPromises
|
|
3534
|
+
], maxPromiseId);
|
|
3535
|
+
if (promises.length === 0)
|
|
3536
|
+
return;
|
|
3537
|
+
if (iteration > 0)
|
|
3538
|
+
this._logger.debug(`flush() re-checking ${promises.length} pending promise(s) before flushing`);
|
|
3539
|
+
await Promise.all(promises.map((promise) => promise.catch(() => {})));
|
|
3540
|
+
iteration++;
|
|
3541
|
+
}
|
|
3542
|
+
}
|
|
3543
|
+
flushWithPendingPromises() {
|
|
3544
|
+
return this.flushInternal(true);
|
|
3545
|
+
}
|
|
3546
|
+
flush() {
|
|
3547
|
+
return this.flushInternal(false);
|
|
3548
|
+
}
|
|
3549
|
+
flushInternal(waitForPendingPromises) {
|
|
2774
3550
|
if (this.disabled)
|
|
2775
|
-
return;
|
|
2776
|
-
|
|
2777
|
-
this.
|
|
2778
|
-
|
|
3551
|
+
return Promise.resolve();
|
|
3552
|
+
if (!waitForPendingPromises && this.pendingFlushPromise)
|
|
3553
|
+
return this.pendingFlushPromise;
|
|
3554
|
+
const previousFlushPromise = this.flushPromise;
|
|
3555
|
+
const maxPromiseId = this.promiseQueue.maxId;
|
|
3556
|
+
const nextFlushPromise = Promise.resolve().then(() => {
|
|
3557
|
+
if (waitForPendingPromises)
|
|
3558
|
+
return this.waitForPendingPromises(maxPromiseId, [
|
|
3559
|
+
previousFlushPromise,
|
|
3560
|
+
nextFlushPromise
|
|
3561
|
+
]);
|
|
3562
|
+
}).then(() => allSettled([
|
|
3563
|
+
previousFlushPromise
|
|
3564
|
+
])).then(() => {
|
|
3565
|
+
if (this.pendingFlushPromise === nextFlushPromise)
|
|
3566
|
+
this.pendingFlushPromise = null;
|
|
3567
|
+
return this._flush();
|
|
3568
|
+
});
|
|
3569
|
+
this.pendingFlushPromise = nextFlushPromise;
|
|
2779
3570
|
this.flushPromise = nextFlushPromise;
|
|
3571
|
+
this.flushPromises.add(nextFlushPromise);
|
|
2780
3572
|
this.addPendingPromise(nextFlushPromise);
|
|
2781
3573
|
allSettled([
|
|
2782
3574
|
nextFlushPromise
|
|
2783
3575
|
]).then(() => {
|
|
3576
|
+
this.flushPromises.delete(nextFlushPromise);
|
|
3577
|
+
if (this.pendingFlushPromise === nextFlushPromise)
|
|
3578
|
+
this.pendingFlushPromise = null;
|
|
2784
3579
|
if (this.flushPromise === nextFlushPromise)
|
|
2785
3580
|
this.flushPromise = null;
|
|
2786
3581
|
});
|
|
@@ -2793,55 +3588,102 @@ class PostHogCoreStateless {
|
|
|
2793
3588
|
headers["User-Agent"] = customUserAgent;
|
|
2794
3589
|
return headers;
|
|
2795
3590
|
}
|
|
3591
|
+
compressPayload(payload) {
|
|
3592
|
+
return gzipCompress(payload, this.isDebug);
|
|
3593
|
+
}
|
|
3594
|
+
getBatchEndpointPath(_route) {
|
|
3595
|
+
return "/batch/";
|
|
3596
|
+
}
|
|
3597
|
+
async sendBatch(batchMessages, retryOptions, route = DEFAULT_QUEUE_ROUTE) {
|
|
3598
|
+
const data = {
|
|
3599
|
+
api_key: this.apiKey,
|
|
3600
|
+
batch: batchMessages.map((message) => {
|
|
3601
|
+
if (!message)
|
|
3602
|
+
return message;
|
|
3603
|
+
const timestamp = this.normalizeTimestampForWire(message.timestamp);
|
|
3604
|
+
return timestamp === message.timestamp ? message : {
|
|
3605
|
+
...message,
|
|
3606
|
+
timestamp
|
|
3607
|
+
};
|
|
3608
|
+
}),
|
|
3609
|
+
sent_at: currentISOTime()
|
|
3610
|
+
};
|
|
3611
|
+
if (this.historicalMigration)
|
|
3612
|
+
data.historical_migration = true;
|
|
3613
|
+
const payload = safeJsonStringify(data);
|
|
3614
|
+
const url = `${this.host}${this.getBatchEndpointPath(route)}`;
|
|
3615
|
+
const gzippedPayload = this.disableCompression ? null : await this.compressPayload(payload);
|
|
3616
|
+
const fetchOptions = {
|
|
3617
|
+
method: "POST",
|
|
3618
|
+
headers: {
|
|
3619
|
+
...this.getCustomHeaders(),
|
|
3620
|
+
"Content-Type": "application/json",
|
|
3621
|
+
...gzippedPayload !== null && {
|
|
3622
|
+
"Content-Encoding": "gzip"
|
|
3623
|
+
}
|
|
3624
|
+
},
|
|
3625
|
+
body: gzippedPayload || payload
|
|
3626
|
+
};
|
|
3627
|
+
await this.fetchWithRetry(url, fetchOptions, {
|
|
3628
|
+
type: "successful-write"
|
|
3629
|
+
}, retryOptions);
|
|
3630
|
+
}
|
|
2796
3631
|
async _flush() {
|
|
2797
3632
|
this.clearFlushTimer();
|
|
2798
3633
|
await this._initPromise;
|
|
2799
|
-
|
|
2800
|
-
if (!
|
|
3634
|
+
const routes = this.getActiveQueueRoutes();
|
|
3635
|
+
if (!routes.some((route) => this.getRouteQueue(route).length > 0))
|
|
2801
3636
|
return;
|
|
2802
3637
|
const sentMessages = [];
|
|
3638
|
+
let firstError;
|
|
3639
|
+
for (const route of routes)
|
|
3640
|
+
try {
|
|
3641
|
+
await this._flushRoute(route, sentMessages);
|
|
3642
|
+
} catch (err) {
|
|
3643
|
+
if (firstError === undefined)
|
|
3644
|
+
firstError = err;
|
|
3645
|
+
}
|
|
3646
|
+
if (firstError !== undefined)
|
|
3647
|
+
throw firstError;
|
|
3648
|
+
this._events.emit("flush", sentMessages);
|
|
3649
|
+
}
|
|
3650
|
+
async _flushRoute(route, sentMessages) {
|
|
3651
|
+
const queueKey = this.persistedQueueKeyForRoute(route);
|
|
3652
|
+
let queue = this.getPersistedProperty(queueKey) || [];
|
|
3653
|
+
if (!queue.length)
|
|
3654
|
+
return;
|
|
2803
3655
|
const originalQueueLength = queue.length;
|
|
2804
|
-
|
|
3656
|
+
let sentFromRoute = 0;
|
|
3657
|
+
while (queue.length > 0 && sentFromRoute < originalQueueLength) {
|
|
2805
3658
|
const batchItems = queue.slice(0, this.maxBatchSize);
|
|
2806
|
-
const batchMessages = batchItems.map((item) => item.message);
|
|
3659
|
+
const batchMessages = batchItems.map((item) => item.message === undefined ? item.message : this.normalizeMessage(item.message));
|
|
2807
3660
|
const persistQueueChange = async () => {
|
|
2808
|
-
const refreshedQueue = this.getPersistedProperty(
|
|
2809
|
-
const
|
|
2810
|
-
|
|
3661
|
+
const refreshedQueue = this.getPersistedProperty(queueKey) || [];
|
|
3662
|
+
const remainingBatchItems = [
|
|
3663
|
+
...batchItems
|
|
3664
|
+
];
|
|
3665
|
+
const newQueue = refreshedQueue.filter((item) => {
|
|
3666
|
+
const itemUuid = item.message?.uuid;
|
|
3667
|
+
const batchItemIndex = remainingBatchItems.findIndex((batchItem) => batchItem === item || typeof itemUuid == "string" && itemUuid.length > 0 && batchItem.message?.uuid === itemUuid);
|
|
3668
|
+
if (batchItemIndex === -1)
|
|
3669
|
+
return true;
|
|
3670
|
+
remainingBatchItems.splice(batchItemIndex, 1);
|
|
3671
|
+
return false;
|
|
3672
|
+
});
|
|
3673
|
+
this.setPersistedProperty(queueKey, newQueue);
|
|
2811
3674
|
queue = newQueue;
|
|
3675
|
+
this._dequeuedMessagesCount += batchItems.length;
|
|
2812
3676
|
await this.flushStorage();
|
|
2813
3677
|
};
|
|
2814
|
-
const data = {
|
|
2815
|
-
api_key: this.apiKey,
|
|
2816
|
-
batch: batchMessages,
|
|
2817
|
-
sent_at: currentISOTime()
|
|
2818
|
-
};
|
|
2819
|
-
if (this.historicalMigration)
|
|
2820
|
-
data.historical_migration = true;
|
|
2821
|
-
const payload = JSON.stringify(data);
|
|
2822
|
-
const url = `${this.host}/batch/`;
|
|
2823
|
-
const gzippedPayload = this.disableCompression ? null : await gzipCompress(payload, this.isDebug);
|
|
2824
|
-
const fetchOptions = {
|
|
2825
|
-
method: "POST",
|
|
2826
|
-
headers: {
|
|
2827
|
-
...this.getCustomHeaders(),
|
|
2828
|
-
"Content-Type": "application/json",
|
|
2829
|
-
...gzippedPayload !== null && {
|
|
2830
|
-
"Content-Encoding": "gzip"
|
|
2831
|
-
}
|
|
2832
|
-
},
|
|
2833
|
-
body: gzippedPayload || payload
|
|
2834
|
-
};
|
|
2835
3678
|
const retryOptions = {
|
|
2836
3679
|
retryCheck: (err) => {
|
|
2837
3680
|
if (isPostHogFetchContentTooLargeError(err))
|
|
2838
3681
|
return false;
|
|
2839
|
-
return
|
|
3682
|
+
return isPostHogFetchRetryableError(err);
|
|
2840
3683
|
}
|
|
2841
3684
|
};
|
|
2842
3685
|
try {
|
|
2843
|
-
|
|
2844
|
-
await response.body?.cancel()?.catch(() => {});
|
|
3686
|
+
await this.sendBatch(batchMessages, retryOptions, route);
|
|
2845
3687
|
} catch (err) {
|
|
2846
3688
|
if (isPostHogFetchContentTooLargeError(err) && batchMessages.length > 1) {
|
|
2847
3689
|
this.maxBatchSize = Math.max(1, Math.floor(batchMessages.length / 2));
|
|
@@ -2855,8 +3697,8 @@ class PostHogCoreStateless {
|
|
|
2855
3697
|
}
|
|
2856
3698
|
await persistQueueChange();
|
|
2857
3699
|
sentMessages.push(...batchMessages);
|
|
3700
|
+
sentFromRoute += batchMessages.length;
|
|
2858
3701
|
}
|
|
2859
|
-
this._events.emit("flush", sentMessages);
|
|
2860
3702
|
}
|
|
2861
3703
|
async _sendLogsBatch(payload) {
|
|
2862
3704
|
if (this.disabled)
|
|
@@ -2866,7 +3708,7 @@ class PostHogCoreStateless {
|
|
|
2866
3708
|
};
|
|
2867
3709
|
const serialized = JSON.stringify(payload);
|
|
2868
3710
|
const url = `${this.host}/i/v1/logs?token=${encodeURIComponent(this.apiKey)}`;
|
|
2869
|
-
const gzippedPayload = this.disableCompression ? null : await
|
|
3711
|
+
const gzippedPayload = this.disableCompression ? null : await this.compressPayload(serialized);
|
|
2870
3712
|
const fetchOptions = {
|
|
2871
3713
|
method: "POST",
|
|
2872
3714
|
headers: {
|
|
@@ -2880,10 +3722,12 @@ class PostHogCoreStateless {
|
|
|
2880
3722
|
};
|
|
2881
3723
|
try {
|
|
2882
3724
|
await this.fetchWithRetry(url, fetchOptions, {
|
|
3725
|
+
type: "successful-write"
|
|
3726
|
+
}, {
|
|
2883
3727
|
retryCheck: (err) => {
|
|
2884
3728
|
if (isPostHogFetchContentTooLargeError(err))
|
|
2885
3729
|
return false;
|
|
2886
|
-
return
|
|
3730
|
+
return isPostHogFetchRetryableError(err);
|
|
2887
3731
|
}
|
|
2888
3732
|
});
|
|
2889
3733
|
return {
|
|
@@ -2905,7 +3749,56 @@ class PostHogCoreStateless {
|
|
|
2905
3749
|
};
|
|
2906
3750
|
}
|
|
2907
3751
|
}
|
|
2908
|
-
async
|
|
3752
|
+
async _sendMetricsBatch(payload) {
|
|
3753
|
+
if (this.disabled)
|
|
3754
|
+
return {
|
|
3755
|
+
kind: "fatal",
|
|
3756
|
+
error: new Error("The client is disabled")
|
|
3757
|
+
};
|
|
3758
|
+
const serialized = JSON.stringify(payload);
|
|
3759
|
+
const url = `${this.host}/i/v1/metrics?token=${encodeURIComponent(this.apiKey)}`;
|
|
3760
|
+
const gzippedPayload = this.disableCompression ? null : await this.compressPayload(serialized);
|
|
3761
|
+
const fetchOptions = {
|
|
3762
|
+
method: "POST",
|
|
3763
|
+
headers: {
|
|
3764
|
+
...this.getCustomHeaders(),
|
|
3765
|
+
"Content-Type": "application/json",
|
|
3766
|
+
...gzippedPayload !== null && {
|
|
3767
|
+
"Content-Encoding": "gzip"
|
|
3768
|
+
}
|
|
3769
|
+
},
|
|
3770
|
+
body: gzippedPayload || serialized
|
|
3771
|
+
};
|
|
3772
|
+
try {
|
|
3773
|
+
await this.fetchWithRetry(url, fetchOptions, {
|
|
3774
|
+
type: "successful-write"
|
|
3775
|
+
}, {
|
|
3776
|
+
retryCheck: (err) => {
|
|
3777
|
+
if (isPostHogFetchContentTooLargeError(err))
|
|
3778
|
+
return false;
|
|
3779
|
+
return isPostHogFetchRetryableError(err);
|
|
3780
|
+
}
|
|
3781
|
+
});
|
|
3782
|
+
return {
|
|
3783
|
+
kind: "ok"
|
|
3784
|
+
};
|
|
3785
|
+
} catch (err) {
|
|
3786
|
+
if (isPostHogFetchContentTooLargeError(err))
|
|
3787
|
+
return {
|
|
3788
|
+
kind: "too-large"
|
|
3789
|
+
};
|
|
3790
|
+
if (isPostHogFetchRetryableError(err))
|
|
3791
|
+
return {
|
|
3792
|
+
kind: "retry-later",
|
|
3793
|
+
error: err
|
|
3794
|
+
};
|
|
3795
|
+
return {
|
|
3796
|
+
kind: "fatal",
|
|
3797
|
+
error: err
|
|
3798
|
+
};
|
|
3799
|
+
}
|
|
3800
|
+
}
|
|
3801
|
+
async fetchWithRetry(url, options, responseHandling, retryOptions, requestTimeout) {
|
|
2909
3802
|
const body = options.body ? options.body : "";
|
|
2910
3803
|
let reqByteLength = -1;
|
|
2911
3804
|
try {
|
|
@@ -2918,28 +3811,91 @@ class PostHogCoreStateless {
|
|
|
2918
3811
|
reqByteLength = encoded.length;
|
|
2919
3812
|
}
|
|
2920
3813
|
}
|
|
3814
|
+
const retriableOptions = {
|
|
3815
|
+
...this._retryOptions,
|
|
3816
|
+
...retryOptions
|
|
3817
|
+
};
|
|
3818
|
+
let attempt = 0;
|
|
2921
3819
|
return await retriable(async () => {
|
|
3820
|
+
attempt++;
|
|
2922
3821
|
const ctrl = new AbortController;
|
|
2923
3822
|
const timeoutMs = requestTimeout ?? this.requestTimeout;
|
|
2924
|
-
const
|
|
2925
|
-
let
|
|
3823
|
+
const requestDeadline = Date.now() + timeoutMs;
|
|
3824
|
+
let timer;
|
|
3825
|
+
const deadline = new Promise((_resolve, reject) => {
|
|
3826
|
+
timer = safeSetTimeout(() => {
|
|
3827
|
+
const timeoutError = new Error(`Request timed out after ${timeoutMs}ms`);
|
|
3828
|
+
timeoutError.name = "AbortError";
|
|
3829
|
+
reject(timeoutError);
|
|
3830
|
+
ctrl.abort(timeoutError);
|
|
3831
|
+
}, timeoutMs);
|
|
3832
|
+
});
|
|
3833
|
+
let res;
|
|
3834
|
+
let responseAccepted = false;
|
|
3835
|
+
let cancellation;
|
|
3836
|
+
const cancelBody = () => cancellation ??= (async () => {
|
|
3837
|
+
try {
|
|
3838
|
+
await res?.body?.cancel();
|
|
3839
|
+
} catch {}
|
|
3840
|
+
})();
|
|
2926
3841
|
try {
|
|
2927
|
-
|
|
2928
|
-
|
|
2929
|
-
|
|
2930
|
-
|
|
2931
|
-
|
|
2932
|
-
|
|
3842
|
+
let fetchPromise;
|
|
3843
|
+
try {
|
|
3844
|
+
fetchPromise = this.fetch(url, {
|
|
3845
|
+
signal: ctrl.signal,
|
|
3846
|
+
...options
|
|
3847
|
+
});
|
|
3848
|
+
} catch (e) {
|
|
3849
|
+
throw new PostHogFetchNetworkError(e);
|
|
3850
|
+
}
|
|
3851
|
+
fetchPromise.then((lateResponse) => {
|
|
3852
|
+
if (ctrl.signal.aborted && !responseAccepted)
|
|
3853
|
+
Promise.resolve(lateResponse.body?.cancel()).catch(() => {});
|
|
3854
|
+
}).catch(() => {});
|
|
3855
|
+
try {
|
|
3856
|
+
res = await Promise.race([
|
|
3857
|
+
fetchPromise,
|
|
3858
|
+
deadline
|
|
3859
|
+
]);
|
|
3860
|
+
responseAccepted = true;
|
|
3861
|
+
} catch (e) {
|
|
3862
|
+
throw new PostHogFetchNetworkError(e);
|
|
3863
|
+
}
|
|
3864
|
+
const isNoCors = options.mode === "no-cors";
|
|
3865
|
+
if (!isNoCors && (res.status < 200 || res.status >= 400))
|
|
3866
|
+
throw new PostHogFetchHttpError(res, reqByteLength, requestDeadline, ctrl);
|
|
3867
|
+
if (responseHandling.type === "successful-write") {
|
|
3868
|
+
try {
|
|
3869
|
+
await Promise.race([
|
|
3870
|
+
cancelBody(),
|
|
3871
|
+
deadline
|
|
3872
|
+
]);
|
|
3873
|
+
} catch {}
|
|
3874
|
+
return;
|
|
3875
|
+
}
|
|
3876
|
+
try {
|
|
3877
|
+
return await Promise.race([
|
|
3878
|
+
responseHandling.consume(res),
|
|
3879
|
+
deadline
|
|
3880
|
+
]);
|
|
3881
|
+
} catch (e) {
|
|
3882
|
+
if (ctrl.signal.aborted)
|
|
3883
|
+
throw new PostHogFetchNetworkError(e);
|
|
3884
|
+
throw e;
|
|
3885
|
+
}
|
|
2933
3886
|
} finally {
|
|
2934
3887
|
clearTimeout(timer);
|
|
3888
|
+
if (ctrl.signal.aborted && res)
|
|
3889
|
+
cancelBody();
|
|
2935
3890
|
}
|
|
2936
|
-
const isNoCors = options.mode === "no-cors";
|
|
2937
|
-
if (!isNoCors && (res.status < 200 || res.status >= 400))
|
|
2938
|
-
throw new PostHogFetchHttpError(res, reqByteLength);
|
|
2939
|
-
return res;
|
|
2940
3891
|
}, {
|
|
2941
|
-
...
|
|
2942
|
-
|
|
3892
|
+
...retriableOptions,
|
|
3893
|
+
retryCheck: (error) => {
|
|
3894
|
+
const shouldRetry = retriableOptions.retryCheck(error);
|
|
3895
|
+
if (shouldRetry && attempt <= retriableOptions.retryCount && error instanceof PostHogFetchHttpError)
|
|
3896
|
+
error.cancelResponseBody();
|
|
3897
|
+
return shouldRetry;
|
|
3898
|
+
}
|
|
2943
3899
|
});
|
|
2944
3900
|
}
|
|
2945
3901
|
async _shutdown(shutdownTimeoutMs = 30000) {
|
|
@@ -2952,12 +3908,17 @@ class PostHogCoreStateless {
|
|
|
2952
3908
|
try {
|
|
2953
3909
|
await this.promiseQueue.join();
|
|
2954
3910
|
while (true) {
|
|
2955
|
-
const
|
|
2956
|
-
if (
|
|
3911
|
+
const hasQueuedEvents = this.getActiveQueueRoutes().some((route) => this.getRouteQueue(route).length > 0);
|
|
3912
|
+
if (!hasQueuedEvents)
|
|
2957
3913
|
break;
|
|
3914
|
+
const dequeuedBeforeFlush = this._dequeuedMessagesCount;
|
|
2958
3915
|
await this.flush();
|
|
2959
3916
|
if (hasTimedOut)
|
|
2960
3917
|
break;
|
|
3918
|
+
if (this._dequeuedMessagesCount === dequeuedBeforeFlush) {
|
|
3919
|
+
this._logger.warn("Shutdown flush completed but did not send any queued events. Stopping drain to avoid a loop.");
|
|
3920
|
+
break;
|
|
3921
|
+
}
|
|
2961
3922
|
}
|
|
2962
3923
|
} catch (e) {
|
|
2963
3924
|
if (!isPostHogFetchError(e))
|
|
@@ -2965,21 +3926,12 @@ class PostHogCoreStateless {
|
|
|
2965
3926
|
await logFlushError(e);
|
|
2966
3927
|
}
|
|
2967
3928
|
};
|
|
2968
|
-
|
|
2969
|
-
|
|
2970
|
-
|
|
2971
|
-
|
|
2972
|
-
|
|
2973
|
-
|
|
2974
|
-
hasTimedOut = true;
|
|
2975
|
-
reject("Timeout while shutting down PostHog. Some events may not have been sent.");
|
|
2976
|
-
}, shutdownTimeoutMs);
|
|
2977
|
-
}),
|
|
2978
|
-
doShutdown()
|
|
2979
|
-
]);
|
|
2980
|
-
} finally {
|
|
2981
|
-
clearTimeout(timeoutHandle);
|
|
2982
|
-
}
|
|
3929
|
+
return raceWithTimeout(doShutdown(), shutdownTimeoutMs, () => {
|
|
3930
|
+
this._logger.critical("Timeout while shutting down PostHog. Some events may not have been sent.", {
|
|
3931
|
+
shutdownTimeoutMs
|
|
3932
|
+
});
|
|
3933
|
+
hasTimedOut = true;
|
|
3934
|
+
});
|
|
2983
3935
|
}
|
|
2984
3936
|
async shutdown(shutdownTimeoutMs = 30000) {
|
|
2985
3937
|
if (this.shutdownPromise)
|
|
@@ -2991,21 +3943,30 @@ class PostHogCoreStateless {
|
|
|
2991
3943
|
return this.shutdownPromise;
|
|
2992
3944
|
}
|
|
2993
3945
|
}
|
|
2994
|
-
// ../../../node_modules/.bun/posthog-node@5.
|
|
2995
|
-
import {
|
|
3946
|
+
// ../../../node_modules/.bun/posthog-node@5.49.2/node_modules/posthog-node/dist/extensions/error-tracking/modifiers/context-lines.node.mjs
|
|
3947
|
+
import { constants as constants2 } from "node:fs";
|
|
3948
|
+
import { open as promises_open } from "node:fs/promises";
|
|
3949
|
+
import { isAbsolute } from "node:path";
|
|
2996
3950
|
import { createInterface } from "node:readline";
|
|
2997
3951
|
var LRU_FILE_CONTENTS_CACHE = new exports_error_tracking.ReduceableCache(25);
|
|
2998
3952
|
var LRU_FILE_CONTENTS_FS_READ_FAILED = new exports_error_tracking.ReduceableCache(20);
|
|
2999
3953
|
var DEFAULT_LINES_OF_CONTEXT = 7;
|
|
3000
3954
|
var MAX_CONTEXTLINES_COLNO = 1000;
|
|
3001
3955
|
var MAX_CONTEXTLINES_LINENO = 1e4;
|
|
3002
|
-
|
|
3956
|
+
var MAX_CONTEXTLINES_FILE_SIZE = 10485760;
|
|
3957
|
+
async function addSourceContext(frames, openSourceFile = promises_open, logger2) {
|
|
3003
3958
|
const filesToLines = {};
|
|
3959
|
+
let basePath;
|
|
3960
|
+
try {
|
|
3961
|
+
basePath = process.cwd();
|
|
3962
|
+
} catch {}
|
|
3004
3963
|
for (let i = frames.length - 1;i >= 0; i--) {
|
|
3005
3964
|
const frame = frames[i];
|
|
3006
3965
|
const filename = frame?.filename;
|
|
3007
3966
|
if (!frame || typeof filename != "string" || typeof frame.lineno != "number" || shouldSkipContextLinesForFile(filename) || shouldSkipContextLinesForFrame(frame))
|
|
3008
3967
|
continue;
|
|
3968
|
+
if (!isAbsolute(filename) && basePath === undefined)
|
|
3969
|
+
continue;
|
|
3009
3970
|
const filesToLinesOutput = filesToLines[filename];
|
|
3010
3971
|
if (!filesToLinesOutput)
|
|
3011
3972
|
filesToLines[filename] = [];
|
|
@@ -3016,50 +3977,98 @@ async function addSourceContext(frames) {
|
|
|
3016
3977
|
return frames;
|
|
3017
3978
|
const readlinePromises = [];
|
|
3018
3979
|
for (const file of files) {
|
|
3019
|
-
|
|
3980
|
+
const cacheKey = makeSourceCacheKey(file, basePath);
|
|
3981
|
+
if (cacheKey === undefined)
|
|
3982
|
+
continue;
|
|
3983
|
+
if (LRU_FILE_CONTENTS_FS_READ_FAILED.get(cacheKey))
|
|
3020
3984
|
continue;
|
|
3021
3985
|
const filesToLineRanges = filesToLines[file];
|
|
3022
3986
|
if (!filesToLineRanges)
|
|
3023
3987
|
continue;
|
|
3024
3988
|
filesToLineRanges.sort((a, b) => a - b);
|
|
3025
3989
|
const ranges = makeLineReaderRanges(filesToLineRanges);
|
|
3026
|
-
if (ranges.every((r) => rangeExistsInContentCache(
|
|
3990
|
+
if (ranges.every((r) => rangeExistsInContentCache(cacheKey, r)))
|
|
3027
3991
|
continue;
|
|
3028
|
-
const cache = emplace(LRU_FILE_CONTENTS_CACHE,
|
|
3029
|
-
readlinePromises.push(getContextLinesFromFile(file, ranges, cache));
|
|
3992
|
+
const cache = emplace(LRU_FILE_CONTENTS_CACHE, cacheKey, {});
|
|
3993
|
+
readlinePromises.push(getContextLinesFromFile(file, ranges, cache, cacheKey, openSourceFile, logger2));
|
|
3030
3994
|
}
|
|
3031
3995
|
await Promise.all(readlinePromises).catch(() => {});
|
|
3032
3996
|
if (frames && frames.length > 0)
|
|
3033
|
-
addSourceContextToFrames(frames, LRU_FILE_CONTENTS_CACHE);
|
|
3997
|
+
addSourceContextToFrames(frames, LRU_FILE_CONTENTS_CACHE, basePath);
|
|
3034
3998
|
LRU_FILE_CONTENTS_CACHE.reduce();
|
|
3035
3999
|
return frames;
|
|
3036
4000
|
}
|
|
3037
|
-
function
|
|
4001
|
+
async function openRegularSourceFile(path2, openSourceFile, logger2) {
|
|
4002
|
+
let fileHandle;
|
|
4003
|
+
let isValid = false;
|
|
4004
|
+
try {
|
|
4005
|
+
fileHandle = await openSourceFile(path2, constants2.O_RDONLY | constants2.O_NONBLOCK);
|
|
4006
|
+
const fileStat = await fileHandle.stat();
|
|
4007
|
+
if (!fileStat.isFile())
|
|
4008
|
+
return;
|
|
4009
|
+
if (fileStat.size > MAX_CONTEXTLINES_FILE_SIZE)
|
|
4010
|
+
return void logger2?.debug(`Skipping source context for oversized file ${path2}: ${fileStat.size} bytes exceeds ${MAX_CONTEXTLINES_FILE_SIZE}`);
|
|
4011
|
+
isValid = true;
|
|
4012
|
+
return fileHandle;
|
|
4013
|
+
} catch {
|
|
4014
|
+
return;
|
|
4015
|
+
} finally {
|
|
4016
|
+
if (fileHandle && !isValid)
|
|
4017
|
+
await fileHandle.close().catch(() => {});
|
|
4018
|
+
}
|
|
4019
|
+
}
|
|
4020
|
+
async function getContextLinesFromFile(path2, ranges, output, cacheKey, openSourceFile, logger2) {
|
|
4021
|
+
const fileHandle = await openRegularSourceFile(path2, openSourceFile, logger2);
|
|
4022
|
+
if (fileHandle === undefined)
|
|
4023
|
+
return void LRU_FILE_CONTENTS_FS_READ_FAILED.set(cacheKey, 1);
|
|
4024
|
+
const openedFileHandle = fileHandle;
|
|
3038
4025
|
return new Promise((resolve) => {
|
|
3039
|
-
|
|
3040
|
-
|
|
3041
|
-
|
|
3042
|
-
|
|
3043
|
-
|
|
3044
|
-
|
|
3045
|
-
|
|
4026
|
+
let finished = false;
|
|
4027
|
+
function destroyStreamAndResolve(stream2) {
|
|
4028
|
+
if (finished)
|
|
4029
|
+
return;
|
|
4030
|
+
finished = true;
|
|
4031
|
+
stream2?.destroy();
|
|
4032
|
+
openedFileHandle.close().then(resolve, resolve);
|
|
4033
|
+
}
|
|
4034
|
+
let stream;
|
|
4035
|
+
try {
|
|
4036
|
+
stream = openedFileHandle.createReadStream({
|
|
4037
|
+
autoClose: false,
|
|
4038
|
+
start: 0,
|
|
4039
|
+
end: MAX_CONTEXTLINES_FILE_SIZE - 1
|
|
4040
|
+
});
|
|
4041
|
+
} catch {
|
|
4042
|
+
LRU_FILE_CONTENTS_FS_READ_FAILED.set(cacheKey, 1);
|
|
4043
|
+
destroyStreamAndResolve();
|
|
4044
|
+
return;
|
|
4045
|
+
}
|
|
4046
|
+
let lineReaded;
|
|
4047
|
+
try {
|
|
4048
|
+
lineReaded = createInterface({
|
|
4049
|
+
input: stream
|
|
4050
|
+
});
|
|
4051
|
+
} catch {
|
|
4052
|
+
LRU_FILE_CONTENTS_FS_READ_FAILED.set(cacheKey, 1);
|
|
4053
|
+
destroyStreamAndResolve(stream);
|
|
4054
|
+
return;
|
|
3046
4055
|
}
|
|
3047
4056
|
let lineNumber = 0;
|
|
3048
4057
|
let currentRangeIndex = 0;
|
|
3049
4058
|
const range = ranges[currentRangeIndex];
|
|
3050
4059
|
if (range === undefined)
|
|
3051
|
-
return void destroyStreamAndResolve();
|
|
4060
|
+
return void destroyStreamAndResolve(stream);
|
|
3052
4061
|
let rangeStart = range[0];
|
|
3053
4062
|
let rangeEnd = range[1];
|
|
3054
4063
|
function onStreamError() {
|
|
3055
|
-
LRU_FILE_CONTENTS_FS_READ_FAILED.set(
|
|
4064
|
+
LRU_FILE_CONTENTS_FS_READ_FAILED.set(cacheKey, 1);
|
|
3056
4065
|
lineReaded.close();
|
|
3057
4066
|
lineReaded.removeAllListeners();
|
|
3058
|
-
destroyStreamAndResolve();
|
|
4067
|
+
destroyStreamAndResolve(stream);
|
|
3059
4068
|
}
|
|
3060
4069
|
stream.on("error", onStreamError);
|
|
3061
4070
|
lineReaded.on("error", onStreamError);
|
|
3062
|
-
lineReaded.on("close", destroyStreamAndResolve);
|
|
4071
|
+
lineReaded.on("close", () => destroyStreamAndResolve(stream));
|
|
3063
4072
|
lineReaded.on("line", (line) => {
|
|
3064
4073
|
lineNumber++;
|
|
3065
4074
|
if (lineNumber < rangeStart)
|
|
@@ -3084,10 +4093,11 @@ function getContextLinesFromFile(path2, ranges, output) {
|
|
|
3084
4093
|
});
|
|
3085
4094
|
});
|
|
3086
4095
|
}
|
|
3087
|
-
function addSourceContextToFrames(frames, cache) {
|
|
4096
|
+
function addSourceContextToFrames(frames, cache, basePath) {
|
|
3088
4097
|
for (const frame of frames)
|
|
3089
4098
|
if (frame.filename && frame.context_line === undefined && typeof frame.lineno == "number") {
|
|
3090
|
-
const
|
|
4099
|
+
const cacheKey = makeSourceCacheKey(frame.filename, basePath);
|
|
4100
|
+
const contents = cacheKey === undefined ? undefined : cache.get(cacheKey);
|
|
3091
4101
|
if (contents === undefined)
|
|
3092
4102
|
continue;
|
|
3093
4103
|
addContextToFrame(frame.lineno, frame, contents);
|
|
@@ -3130,8 +4140,19 @@ function shouldSkipContextLinesForFrame(frame) {
|
|
|
3130
4140
|
return true;
|
|
3131
4141
|
return false;
|
|
3132
4142
|
}
|
|
3133
|
-
function
|
|
3134
|
-
|
|
4143
|
+
function makeSourceCacheKey(path2, basePath) {
|
|
4144
|
+
if (isAbsolute(path2))
|
|
4145
|
+
return JSON.stringify([
|
|
4146
|
+
null,
|
|
4147
|
+
path2
|
|
4148
|
+
]);
|
|
4149
|
+
return basePath === undefined ? undefined : JSON.stringify([
|
|
4150
|
+
basePath,
|
|
4151
|
+
path2
|
|
4152
|
+
]);
|
|
4153
|
+
}
|
|
4154
|
+
function rangeExistsInContentCache(cacheKey, range) {
|
|
4155
|
+
const contents = LRU_FILE_CONTENTS_CACHE.get(cacheKey);
|
|
3135
4156
|
if (contents === undefined)
|
|
3136
4157
|
return false;
|
|
3137
4158
|
for (let i = range[0];i <= range[1]; i++)
|
|
@@ -3209,8 +4230,8 @@ function snipLine(line, colno) {
|
|
|
3209
4230
|
return newLine;
|
|
3210
4231
|
}
|
|
3211
4232
|
|
|
3212
|
-
// ../../../node_modules/.bun/posthog-node@5.
|
|
3213
|
-
import { isAbsolute, relative, sep as sep2 } from "node:path";
|
|
4233
|
+
// ../../../node_modules/.bun/posthog-node@5.49.2/node_modules/posthog-node/dist/extensions/error-tracking/modifiers/relative-path.node.mjs
|
|
4234
|
+
import { isAbsolute as isAbsolute2, relative, sep as sep2 } from "node:path";
|
|
3214
4235
|
function createRelativePathModifier(basePath = process.cwd()) {
|
|
3215
4236
|
const isWindows = sep2 === "\\";
|
|
3216
4237
|
const toUnix = (p) => isWindows ? p.replace(/\\/g, "/") : p;
|
|
@@ -3218,17 +4239,17 @@ function createRelativePathModifier(basePath = process.cwd()) {
|
|
|
3218
4239
|
return async (frames) => {
|
|
3219
4240
|
for (const frame of frames)
|
|
3220
4241
|
if (!(!frame.filename || frame.filename.startsWith("node:") || frame.filename.startsWith("data:"))) {
|
|
3221
|
-
if (
|
|
4242
|
+
if (isAbsolute2(frame.filename))
|
|
3222
4243
|
frame.filename = toUnix(relative(normalizedBase, toUnix(frame.filename)));
|
|
3223
4244
|
}
|
|
3224
4245
|
return frames;
|
|
3225
4246
|
};
|
|
3226
4247
|
}
|
|
3227
4248
|
|
|
3228
|
-
// ../../../node_modules/.bun/posthog-node@5.
|
|
3229
|
-
var version = "5.
|
|
4249
|
+
// ../../../node_modules/.bun/posthog-node@5.49.2/node_modules/posthog-node/dist/version.mjs
|
|
4250
|
+
var version = "5.49.2";
|
|
3230
4251
|
|
|
3231
|
-
// ../../../node_modules/.bun/posthog-node@5.
|
|
4252
|
+
// ../../../node_modules/.bun/posthog-node@5.49.2/node_modules/posthog-node/dist/types.mjs
|
|
3232
4253
|
var FeatureFlagError2 = {
|
|
3233
4254
|
ERRORS_WHILE_COMPUTING: "errors_while_computing_flags",
|
|
3234
4255
|
FLAG_MISSING: "flag_missing",
|
|
@@ -3236,7 +4257,7 @@ var FeatureFlagError2 = {
|
|
|
3236
4257
|
UNKNOWN_ERROR: "unknown_error"
|
|
3237
4258
|
};
|
|
3238
4259
|
|
|
3239
|
-
// ../../../node_modules/.bun/posthog-node@5.
|
|
4260
|
+
// ../../../node_modules/.bun/posthog-node@5.49.2/node_modules/posthog-node/dist/feature-flag-evaluations.mjs
|
|
3240
4261
|
class FeatureFlagEvaluations {
|
|
3241
4262
|
constructor(init) {
|
|
3242
4263
|
this._host = init.host;
|
|
@@ -3345,6 +4366,8 @@ class FeatureFlagEvaluations {
|
|
|
3345
4366
|
$feature_flag_request_id: this._requestId,
|
|
3346
4367
|
$feature_flag_evaluated_at: flag?.locallyEvaluated ? Date.now() : this._evaluatedAt
|
|
3347
4368
|
};
|
|
4369
|
+
if (flag?.hasExperiment !== undefined)
|
|
4370
|
+
properties.$feature_flag_has_experiment = flag.hasExperiment;
|
|
3348
4371
|
if (flag?.locallyEvaluated && this._flagDefinitionsLoadedAt !== undefined)
|
|
3349
4372
|
properties.$feature_flag_definitions_loaded_at = this._flagDefinitionsLoadedAt;
|
|
3350
4373
|
const errors = [];
|
|
@@ -3367,7 +4390,7 @@ class FeatureFlagEvaluations {
|
|
|
3367
4390
|
}
|
|
3368
4391
|
}
|
|
3369
4392
|
|
|
3370
|
-
// ../../../node_modules/.bun/posthog-node@5.
|
|
4393
|
+
// ../../../node_modules/.bun/posthog-node@5.49.2/node_modules/posthog-node/dist/extensions/feature-flags/crypto.mjs
|
|
3371
4394
|
async function hashSHA1(text) {
|
|
3372
4395
|
const subtle = globalThis.crypto?.subtle;
|
|
3373
4396
|
if (!subtle)
|
|
@@ -3377,7 +4400,7 @@ async function hashSHA1(text) {
|
|
|
3377
4400
|
return hashArray.map((byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
3378
4401
|
}
|
|
3379
4402
|
|
|
3380
|
-
// ../../../node_modules/.bun/posthog-node@5.
|
|
4403
|
+
// ../../../node_modules/.bun/posthog-node@5.49.2/node_modules/posthog-node/dist/extensions/feature-flags/feature-flags.mjs
|
|
3381
4404
|
var SIXTY_SECONDS = 60000;
|
|
3382
4405
|
var LONG_SCALE = 1152921504606847000;
|
|
3383
4406
|
var NULL_VALUES_ALLOWED_OPERATORS = [
|
|
@@ -3394,22 +4417,23 @@ class ClientError extends Error {
|
|
|
3394
4417
|
Object.setPrototypeOf(this, ClientError.prototype);
|
|
3395
4418
|
}
|
|
3396
4419
|
}
|
|
4420
|
+
function setCustomErrorPrototype(error, constructor) {
|
|
4421
|
+
error.name = constructor.name;
|
|
4422
|
+
Error.captureStackTrace(error, constructor);
|
|
4423
|
+
Object.setPrototypeOf(error, constructor.prototype);
|
|
4424
|
+
}
|
|
3397
4425
|
|
|
3398
4426
|
class InconclusiveMatchError extends Error {
|
|
3399
4427
|
constructor(message) {
|
|
3400
4428
|
super(message);
|
|
3401
|
-
this
|
|
3402
|
-
Error.captureStackTrace(this, this.constructor);
|
|
3403
|
-
Object.setPrototypeOf(this, InconclusiveMatchError.prototype);
|
|
4429
|
+
setCustomErrorPrototype(this, InconclusiveMatchError);
|
|
3404
4430
|
}
|
|
3405
4431
|
}
|
|
3406
4432
|
|
|
3407
4433
|
class RequiresServerEvaluation extends Error {
|
|
3408
4434
|
constructor(message) {
|
|
3409
4435
|
super(message);
|
|
3410
|
-
this
|
|
3411
|
-
Error.captureStackTrace(this, this.constructor);
|
|
3412
|
-
Object.setPrototypeOf(this, RequiresServerEvaluation.prototype);
|
|
4436
|
+
setCustomErrorPrototype(this, RequiresServerEvaluation);
|
|
3413
4437
|
}
|
|
3414
4438
|
}
|
|
3415
4439
|
|
|
@@ -3418,6 +4442,7 @@ class FeatureFlagsPoller {
|
|
|
3418
4442
|
this.debugMode = false;
|
|
3419
4443
|
this.shouldBeginExponentialBackoff = false;
|
|
3420
4444
|
this.backOffCount = 0;
|
|
4445
|
+
this.pollerStopped = false;
|
|
3421
4446
|
this.pollingInterval = pollingInterval;
|
|
3422
4447
|
this.personalApiKey = personalApiKey;
|
|
3423
4448
|
this.featureFlags = [];
|
|
@@ -3433,6 +4458,7 @@ class FeatureFlagsPoller {
|
|
|
3433
4458
|
this.onError = options.onError;
|
|
3434
4459
|
this.customHeaders = customHeaders;
|
|
3435
4460
|
this.onLoad = options.onLoad;
|
|
4461
|
+
this.onMinimalFlagCalledEvents = options.onMinimalFlagCalledEvents;
|
|
3436
4462
|
this.cacheProvider = options.cacheProvider;
|
|
3437
4463
|
this.strictLocalEvaluation = options.strictLocalEvaluation ?? false;
|
|
3438
4464
|
this.loadFeatureFlags();
|
|
@@ -3630,6 +4656,7 @@ class FeatureFlagsPoller {
|
|
|
3630
4656
|
const flagFilters = flag.filters || {};
|
|
3631
4657
|
const flagConditions = flagFilters.groups || [];
|
|
3632
4658
|
const flagAggregation = flagFilters.aggregation_group_type_index;
|
|
4659
|
+
const earlyExitEnabled = flagFilters.early_exit ?? false;
|
|
3633
4660
|
const { groups, groupProperties } = evaluationContext;
|
|
3634
4661
|
let isInconclusive = false;
|
|
3635
4662
|
let result;
|
|
@@ -3653,12 +4680,15 @@ class FeatureFlagsPoller {
|
|
|
3653
4680
|
effectiveBucketingValue = groups[groupName];
|
|
3654
4681
|
}
|
|
3655
4682
|
}
|
|
3656
|
-
|
|
4683
|
+
const matchResult = await this.isConditionMatch(flag, effectiveBucketingValue, condition, effectiveProperties, evaluationContext);
|
|
4684
|
+
if (matchResult === "match") {
|
|
3657
4685
|
const variantOverride = condition.variant;
|
|
3658
4686
|
const flagVariants = flagFilters.multivariate?.variants || [];
|
|
3659
4687
|
result = variantOverride && flagVariants.some((variant) => variant.key === variantOverride) ? variantOverride : await this.getMatchingVariant(flag, effectiveBucketingValue) || true;
|
|
3660
4688
|
break;
|
|
3661
4689
|
}
|
|
4690
|
+
if (earlyExitEnabled && matchResult === "out_of_rollout_bound")
|
|
4691
|
+
return false;
|
|
3662
4692
|
} catch (e) {
|
|
3663
4693
|
if (e instanceof RequiresServerEvaluation)
|
|
3664
4694
|
throw e;
|
|
@@ -3682,16 +4712,20 @@ class FeatureFlagsPoller {
|
|
|
3682
4712
|
for (const prop of condition.properties) {
|
|
3683
4713
|
const propertyType = prop.type;
|
|
3684
4714
|
let matches = false;
|
|
3685
|
-
|
|
4715
|
+
if (propertyType === "cohort") {
|
|
4716
|
+
const inCohort = await matchCohort(prop, properties, this.cohorts, this.debugMode, (depProp) => this.evaluateFlagDependency(depProp, properties, evaluationContext));
|
|
4717
|
+
matches = prop.operator === "not_in" ? !inCohort : inCohort;
|
|
4718
|
+
} else
|
|
4719
|
+
matches = propertyType === "flag" ? await this.evaluateFlagDependency(prop, properties, evaluationContext) : matchProperty(prop, properties, warnFunction);
|
|
3686
4720
|
if (!matches)
|
|
3687
|
-
return
|
|
4721
|
+
return "no_match";
|
|
3688
4722
|
}
|
|
3689
4723
|
if (rolloutPercentage == undefined)
|
|
3690
|
-
return
|
|
4724
|
+
return "match";
|
|
3691
4725
|
}
|
|
3692
4726
|
if (rolloutPercentage != null && await _hash(flag.key, bucketingValue) > rolloutPercentage / 100)
|
|
3693
|
-
return
|
|
3694
|
-
return
|
|
4727
|
+
return "out_of_rollout_bound";
|
|
4728
|
+
return "match";
|
|
3695
4729
|
}
|
|
3696
4730
|
async getMatchingVariant(flag, bucketingValue) {
|
|
3697
4731
|
const hashValue = await _hash(flag.key, bucketingValue, "variant");
|
|
@@ -3722,6 +4756,7 @@ class FeatureFlagsPoller {
|
|
|
3722
4756
|
this.groupTypeMapping = flagData.groupTypeMapping;
|
|
3723
4757
|
this.cohorts = flagData.cohorts;
|
|
3724
4758
|
this.loadedSuccessfullyOnce = true;
|
|
4759
|
+
this.onMinimalFlagCalledEvents?.(flagData.minimalFlagCalledEvents === true);
|
|
3725
4760
|
}
|
|
3726
4761
|
warnAboutExperienceContinuityFlags(flags) {
|
|
3727
4762
|
if (this.strictLocalEvaluation)
|
|
@@ -3785,7 +4820,6 @@ class FeatureFlagsPoller {
|
|
|
3785
4820
|
clearTimeout(this.poller);
|
|
3786
4821
|
this.poller = undefined;
|
|
3787
4822
|
}
|
|
3788
|
-
this.poller = setTimeout(() => this.loadFeatureFlags(true), this.getPollingInterval());
|
|
3789
4823
|
try {
|
|
3790
4824
|
let shouldFetch = true;
|
|
3791
4825
|
if (this.cacheProvider)
|
|
@@ -3813,17 +4847,18 @@ class FeatureFlagsPoller {
|
|
|
3813
4847
|
return;
|
|
3814
4848
|
case 401:
|
|
3815
4849
|
this.beginBackoff();
|
|
3816
|
-
throw new ClientError(`Your project key or
|
|
4850
|
+
throw new ClientError(`Your project key or secret key is invalid. Setting next polling interval to ${this.getPollingInterval()}ms. More information: https://posthog.com/docs/api#rate-limiting`);
|
|
3817
4851
|
case 402:
|
|
3818
4852
|
console.warn("[FEATURE FLAGS] Feature flags quota limit exceeded - unsetting all local flags. Learn more about billing limits at https://posthog.com/docs/billing/limits-alerts");
|
|
3819
4853
|
this.featureFlags = [];
|
|
3820
4854
|
this.featureFlagsByKey = {};
|
|
3821
4855
|
this.groupTypeMapping = {};
|
|
3822
4856
|
this.cohorts = {};
|
|
4857
|
+
this.onMinimalFlagCalledEvents?.(false);
|
|
3823
4858
|
return;
|
|
3824
4859
|
case 403:
|
|
3825
4860
|
this.beginBackoff();
|
|
3826
|
-
throw new ClientError(`Your
|
|
4861
|
+
throw new ClientError(`Your secret key does not have permission to fetch feature flag definitions for local evaluation. Setting next polling interval to ${this.getPollingInterval()}ms. Are you sure you're using the correct secret and Project API key pair? More information: https://posthog.com/docs/api/overview`);
|
|
3827
4862
|
case 429:
|
|
3828
4863
|
this.beginBackoff();
|
|
3829
4864
|
throw new ClientError(`You are being rate limited. Setting next polling interval to ${this.getPollingInterval()}ms. More information: https://posthog.com/docs/api#rate-limiting`);
|
|
@@ -3835,7 +4870,8 @@ class FeatureFlagsPoller {
|
|
|
3835
4870
|
const flagData = {
|
|
3836
4871
|
flags: responseJson.flags ?? [],
|
|
3837
4872
|
groupTypeMapping: responseJson.group_type_mapping || {},
|
|
3838
|
-
cohorts: responseJson.cohorts || {}
|
|
4873
|
+
cohorts: responseJson.cohorts || {},
|
|
4874
|
+
minimalFlagCalledEvents: responseJson.minimal_flag_called_events === true
|
|
3839
4875
|
};
|
|
3840
4876
|
this.updateFlagState(flagData);
|
|
3841
4877
|
this.flagDefinitionsLoadedAt = Date.now();
|
|
@@ -3856,6 +4892,9 @@ class FeatureFlagsPoller {
|
|
|
3856
4892
|
} catch (err) {
|
|
3857
4893
|
if (err instanceof ClientError)
|
|
3858
4894
|
this.onError?.(err);
|
|
4895
|
+
} finally {
|
|
4896
|
+
if (!this.pollerStopped)
|
|
4897
|
+
this.poller = setTimeout(() => this.loadFeatureFlags(true), this.getPollingInterval());
|
|
3859
4898
|
}
|
|
3860
4899
|
}
|
|
3861
4900
|
getPersonalApiKeyRequestOptions(method = "GET", etag) {
|
|
@@ -3871,7 +4910,7 @@ class FeatureFlagsPoller {
|
|
|
3871
4910
|
headers
|
|
3872
4911
|
};
|
|
3873
4912
|
}
|
|
3874
|
-
_requestFeatureFlagDefinitions() {
|
|
4913
|
+
async _requestFeatureFlagDefinitions() {
|
|
3875
4914
|
const url = `${this.host}/flags/definitions?token=${this.projectApiKey}&send_cohorts`;
|
|
3876
4915
|
const options = this.getPersonalApiKeyRequestOptions("GET", this.flagsEtag);
|
|
3877
4916
|
let abortTimeout = null;
|
|
@@ -3882,23 +4921,49 @@ class FeatureFlagsPoller {
|
|
|
3882
4921
|
}, this.timeout);
|
|
3883
4922
|
options.signal = controller.signal;
|
|
3884
4923
|
}
|
|
4924
|
+
const clearAbortTimeout = () => clearTimeout(abortTimeout);
|
|
3885
4925
|
try {
|
|
3886
4926
|
const fetch1 = this.fetch;
|
|
3887
|
-
|
|
3888
|
-
|
|
3889
|
-
|
|
4927
|
+
const res = await fetch1(url, options);
|
|
4928
|
+
if (res.status !== 200) {
|
|
4929
|
+
clearAbortTimeout();
|
|
4930
|
+
return res;
|
|
4931
|
+
}
|
|
4932
|
+
return {
|
|
4933
|
+
status: res.status,
|
|
4934
|
+
headers: res.headers,
|
|
4935
|
+
body: res.body,
|
|
4936
|
+
text: async () => {
|
|
4937
|
+
try {
|
|
4938
|
+
return await res.text();
|
|
4939
|
+
} finally {
|
|
4940
|
+
clearAbortTimeout();
|
|
4941
|
+
}
|
|
4942
|
+
},
|
|
4943
|
+
json: async () => {
|
|
4944
|
+
try {
|
|
4945
|
+
return await res.json();
|
|
4946
|
+
} finally {
|
|
4947
|
+
clearAbortTimeout();
|
|
4948
|
+
}
|
|
4949
|
+
}
|
|
4950
|
+
};
|
|
4951
|
+
} catch (err) {
|
|
4952
|
+
clearAbortTimeout();
|
|
4953
|
+
throw err;
|
|
3890
4954
|
}
|
|
3891
4955
|
}
|
|
3892
4956
|
async stopPoller(timeoutMs = 30000) {
|
|
4957
|
+
this.pollerStopped = true;
|
|
3893
4958
|
clearTimeout(this.poller);
|
|
4959
|
+
this.poller = undefined;
|
|
3894
4960
|
if (this.cacheProvider)
|
|
3895
4961
|
try {
|
|
3896
4962
|
const shutdownResult = this.cacheProvider.shutdown();
|
|
3897
4963
|
if (shutdownResult instanceof Promise)
|
|
3898
|
-
await
|
|
3899
|
-
|
|
3900
|
-
|
|
3901
|
-
]);
|
|
4964
|
+
await raceWithTimeout(shutdownResult, timeoutMs, () => {
|
|
4965
|
+
throw new Error(`Cache shutdown timeout after ${timeoutMs}ms`);
|
|
4966
|
+
});
|
|
3902
4967
|
} catch (err) {
|
|
3903
4968
|
this.onError?.(new Error(`Error during cache shutdown: ${err}`));
|
|
3904
4969
|
}
|
|
@@ -3953,6 +5018,14 @@ function matchProperty(property, propertyValues, warnFunction) {
|
|
|
3953
5018
|
return String(overrideValue).toLowerCase().includes(String(value).toLowerCase());
|
|
3954
5019
|
case "not_icontains":
|
|
3955
5020
|
return !String(overrideValue).toLowerCase().includes(String(value).toLowerCase());
|
|
5021
|
+
case "starts_with":
|
|
5022
|
+
return String(overrideValue).toLowerCase().startsWith(String(value).toLowerCase());
|
|
5023
|
+
case "not_starts_with":
|
|
5024
|
+
return !String(overrideValue).toLowerCase().startsWith(String(value).toLowerCase());
|
|
5025
|
+
case "ends_with":
|
|
5026
|
+
return String(overrideValue).toLowerCase().endsWith(String(value).toLowerCase());
|
|
5027
|
+
case "not_ends_with":
|
|
5028
|
+
return !String(overrideValue).toLowerCase().endsWith(String(value).toLowerCase());
|
|
3956
5029
|
case "regex":
|
|
3957
5030
|
return isValidRegex(String(value)) && String(overrideValue).match(String(value)) !== null;
|
|
3958
5031
|
case "not_regex":
|
|
@@ -4279,19 +5352,75 @@ function relativeDateParseForFeatureFlagMatching(value) {
|
|
|
4279
5352
|
}
|
|
4280
5353
|
}
|
|
4281
5354
|
|
|
4282
|
-
// ../../../node_modules/.bun/posthog-node@5.
|
|
5355
|
+
// ../../../node_modules/.bun/posthog-node@5.49.2/node_modules/posthog-node/dist/extensions/error-tracking/autocapture.mjs
|
|
5356
|
+
var UNHANDLED_REJECTION_OPTION_NAMES = [
|
|
5357
|
+
"--unhandled-rejections",
|
|
5358
|
+
"--unhandled_rejections"
|
|
5359
|
+
];
|
|
5360
|
+
var UNHANDLED_REJECTION_MODES = new Set([
|
|
5361
|
+
"throw",
|
|
5362
|
+
"strict",
|
|
5363
|
+
"warn",
|
|
5364
|
+
"warn-with-error-code",
|
|
5365
|
+
"none"
|
|
5366
|
+
]);
|
|
5367
|
+
var STARTUP_EXEC_ARGV = [
|
|
5368
|
+
...globalThis.process?.execArgv ?? []
|
|
5369
|
+
];
|
|
5370
|
+
var STARTUP_NODE_OPTIONS = globalThis.process?.env?.NODE_OPTIONS;
|
|
5371
|
+
function splitNodeOptions(nodeOptions) {
|
|
5372
|
+
const args = [];
|
|
5373
|
+
let current = "";
|
|
5374
|
+
let isInString = false;
|
|
5375
|
+
for (let index = 0;index < nodeOptions.length; index++) {
|
|
5376
|
+
const character = nodeOptions[index];
|
|
5377
|
+
if (character === "\\" && isInString && index + 1 < nodeOptions.length)
|
|
5378
|
+
current += nodeOptions[++index];
|
|
5379
|
+
else if (character !== " " || isInString)
|
|
5380
|
+
if (character === '"')
|
|
5381
|
+
isInString = !isInString;
|
|
5382
|
+
else
|
|
5383
|
+
current += character;
|
|
5384
|
+
else if (current) {
|
|
5385
|
+
args.push(current);
|
|
5386
|
+
current = "";
|
|
5387
|
+
}
|
|
5388
|
+
}
|
|
5389
|
+
if (current)
|
|
5390
|
+
args.push(current);
|
|
5391
|
+
return args;
|
|
5392
|
+
}
|
|
5393
|
+
function findUnhandledRejectionMode(args) {
|
|
5394
|
+
let mode;
|
|
5395
|
+
for (let index = 0;index < args.length; index++) {
|
|
5396
|
+
const argument = args[index];
|
|
5397
|
+
const optionName = UNHANDLED_REJECTION_OPTION_NAMES.find((name) => argument === name || argument.startsWith(`${name}=`));
|
|
5398
|
+
if (!optionName)
|
|
5399
|
+
continue;
|
|
5400
|
+
const value = argument === optionName ? args[++index] : argument.slice(optionName.length + 1);
|
|
5401
|
+
if (UNHANDLED_REJECTION_MODES.has(value))
|
|
5402
|
+
mode = value;
|
|
5403
|
+
}
|
|
5404
|
+
return mode;
|
|
5405
|
+
}
|
|
5406
|
+
function getUnhandledRejectionMode(execArgv = STARTUP_EXEC_ARGV, nodeOptions = STARTUP_NODE_OPTIONS) {
|
|
5407
|
+
return findUnhandledRejectionMode(execArgv) ?? findUnhandledRejectionMode(splitNodeOptions(nodeOptions ?? "")) ?? "throw";
|
|
5408
|
+
}
|
|
5409
|
+
var STARTUP_UNHANDLED_REJECTION_MODE = getUnhandledRejectionMode();
|
|
5410
|
+
function captureUncaughtException(captureFn, error, origin) {
|
|
5411
|
+
captureFn(error, {
|
|
5412
|
+
mechanism: {
|
|
5413
|
+
type: origin === "unhandledRejection" ? "onunhandledrejection" : "onuncaughtexception",
|
|
5414
|
+
handled: false
|
|
5415
|
+
}
|
|
5416
|
+
});
|
|
5417
|
+
}
|
|
4283
5418
|
function makeUncaughtExceptionHandler(captureFn, onFatalFn) {
|
|
4284
5419
|
let calledFatalError = false;
|
|
4285
|
-
return Object.assign((error) => {
|
|
5420
|
+
return Object.assign((error, origin) => {
|
|
4286
5421
|
const userProvidedListenersCount = global.process.listeners("uncaughtException").filter((listener) => listener.name !== "domainUncaughtExceptionClear" && listener._posthogErrorHandler !== true).length;
|
|
4287
|
-
|
|
4288
|
-
|
|
4289
|
-
mechanism: {
|
|
4290
|
-
type: "onuncaughtexception",
|
|
4291
|
-
handled: false
|
|
4292
|
-
}
|
|
4293
|
-
});
|
|
4294
|
-
if (!calledFatalError && processWouldExit) {
|
|
5422
|
+
captureUncaughtException(captureFn, error, origin);
|
|
5423
|
+
if (!calledFatalError && userProvidedListenersCount === 0) {
|
|
4295
5424
|
calledFatalError = true;
|
|
4296
5425
|
onFatalFn(error);
|
|
4297
5426
|
}
|
|
@@ -4299,29 +5428,38 @@ function makeUncaughtExceptionHandler(captureFn, onFatalFn) {
|
|
|
4299
5428
|
_posthogErrorHandler: true
|
|
4300
5429
|
});
|
|
4301
5430
|
}
|
|
4302
|
-
function addUncaughtExceptionListener(captureFn, onFatalFn) {
|
|
4303
|
-
globalThis.process
|
|
5431
|
+
function addUncaughtExceptionListener(captureFn, onFatalFn, mode = STARTUP_UNHANDLED_REJECTION_MODE) {
|
|
5432
|
+
const process2 = globalThis.process;
|
|
5433
|
+
if (!process2)
|
|
5434
|
+
return;
|
|
5435
|
+
if (mode === "strict")
|
|
5436
|
+
return void process2.on("uncaughtExceptionMonitor", (error, origin) => captureUncaughtException(captureFn, error, origin));
|
|
5437
|
+
process2.on("uncaughtException", makeUncaughtExceptionHandler(captureFn, onFatalFn));
|
|
4304
5438
|
}
|
|
4305
|
-
function addUnhandledRejectionListener(captureFn) {
|
|
4306
|
-
globalThis.process
|
|
4307
|
-
|
|
4308
|
-
|
|
4309
|
-
|
|
4310
|
-
|
|
4311
|
-
|
|
5439
|
+
function addUnhandledRejectionListener(captureFn, mode = STARTUP_UNHANDLED_REJECTION_MODE) {
|
|
5440
|
+
const process2 = globalThis.process;
|
|
5441
|
+
if (!process2 || mode === "throw" || mode === "strict" || mode === "warn-with-error-code")
|
|
5442
|
+
return;
|
|
5443
|
+
process2.on("unhandledRejection", (reason) => {
|
|
5444
|
+
captureFn(reason, {
|
|
5445
|
+
mechanism: {
|
|
5446
|
+
type: "onunhandledrejection",
|
|
5447
|
+
handled: false
|
|
5448
|
+
}
|
|
5449
|
+
});
|
|
5450
|
+
});
|
|
4312
5451
|
}
|
|
4313
5452
|
|
|
4314
|
-
// ../../../node_modules/.bun/posthog-node@5.
|
|
5453
|
+
// ../../../node_modules/.bun/posthog-node@5.49.2/node_modules/posthog-node/dist/extensions/error-tracking/index.mjs
|
|
4315
5454
|
var SHUTDOWN_TIMEOUT = 2000;
|
|
4316
5455
|
|
|
4317
|
-
class
|
|
5456
|
+
class error_tracking_ErrorTracking {
|
|
4318
5457
|
constructor(client, options, _logger) {
|
|
4319
5458
|
this.client = client;
|
|
4320
5459
|
this._exceptionAutocaptureEnabled = options.enableExceptionAutocapture || false;
|
|
4321
5460
|
this._logger = _logger;
|
|
4322
5461
|
this._rateLimiter = new BucketedRateLimiter({
|
|
4323
|
-
|
|
4324
|
-
bucketSize: 10,
|
|
5462
|
+
...resolveExceptionRateLimiterConfig(options),
|
|
4325
5463
|
refillInterval: 1e4,
|
|
4326
5464
|
_logger: this._logger
|
|
4327
5465
|
});
|
|
@@ -4336,6 +5474,9 @@ class ErrorTracking {
|
|
|
4336
5474
|
};
|
|
4337
5475
|
const exceptionProperties = builder.buildFromUnknown(error, hint);
|
|
4338
5476
|
exceptionProperties.$exception_list = await builder.modifyFrames(exceptionProperties.$exception_list);
|
|
5477
|
+
const injectedReleaseId = exports_error_tracking.getInjectedReleaseId();
|
|
5478
|
+
if (injectedReleaseId)
|
|
5479
|
+
properties.$release_id = injectedReleaseId;
|
|
4339
5480
|
return {
|
|
4340
5481
|
event: "$exception",
|
|
4341
5482
|
distinctId,
|
|
@@ -4354,8 +5495,8 @@ class ErrorTracking {
|
|
|
4354
5495
|
}
|
|
4355
5496
|
onException(exception, hint) {
|
|
4356
5497
|
this.client.addPendingPromise((async () => {
|
|
4357
|
-
if (!
|
|
4358
|
-
const eventMessage = await
|
|
5498
|
+
if (!error_tracking_ErrorTracking.isPreviouslyCapturedError(exception)) {
|
|
5499
|
+
const eventMessage = await error_tracking_ErrorTracking.buildEventMessage(this.client.getErrorPropertiesBuilder(), exception, hint);
|
|
4359
5500
|
const exceptionProperties = eventMessage.properties;
|
|
4360
5501
|
const exceptionType = exceptionProperties?.$exception_list[0]?.type ?? "Exception";
|
|
4361
5502
|
const isRateLimited = this._rateLimiter.consumeRateLimit(exceptionType);
|
|
@@ -4363,14 +5504,14 @@ class ErrorTracking {
|
|
|
4363
5504
|
return void this._logger.info("Skipping exception capture because of client rate limiting.", {
|
|
4364
5505
|
exception: exceptionType
|
|
4365
5506
|
});
|
|
4366
|
-
return this.client.
|
|
5507
|
+
return this.client._capturePreparedEvent(eventMessage, false);
|
|
4367
5508
|
}
|
|
4368
5509
|
})());
|
|
4369
5510
|
}
|
|
4370
5511
|
async onFatalError(exception) {
|
|
4371
5512
|
console.error(exception);
|
|
4372
5513
|
await this.client.shutdown(SHUTDOWN_TIMEOUT);
|
|
4373
|
-
process.exit(1);
|
|
5514
|
+
globalThis.process.exit(1);
|
|
4374
5515
|
}
|
|
4375
5516
|
isEnabled() {
|
|
4376
5517
|
return !this.client.isDisabled && this._exceptionAutocaptureEnabled;
|
|
@@ -4380,7 +5521,7 @@ class ErrorTracking {
|
|
|
4380
5521
|
}
|
|
4381
5522
|
}
|
|
4382
5523
|
|
|
4383
|
-
// ../../../node_modules/.bun/posthog-node@5.
|
|
5524
|
+
// ../../../node_modules/.bun/posthog-node@5.49.2/node_modules/posthog-node/dist/storage-memory.mjs
|
|
4384
5525
|
class PostHogMemoryStorage {
|
|
4385
5526
|
getProperty(key) {
|
|
4386
5527
|
return this._memoryStorage[key];
|
|
@@ -4393,7 +5534,452 @@ class PostHogMemoryStorage {
|
|
|
4393
5534
|
}
|
|
4394
5535
|
}
|
|
4395
5536
|
|
|
4396
|
-
// ../../../node_modules/.bun/posthog-node@5.
|
|
5537
|
+
// ../../../node_modules/.bun/posthog-node@5.49.2/node_modules/posthog-node/dist/capture-v1/config.mjs
|
|
5538
|
+
function isCaptureMode(value) {
|
|
5539
|
+
return value === "v0" || value === "v1";
|
|
5540
|
+
}
|
|
5541
|
+
function resolveCaptureMode() {
|
|
5542
|
+
const envMode = typeof process != "undefined" ? process.env?.POSTHOG_CAPTURE_MODE : undefined;
|
|
5543
|
+
return isCaptureMode(envMode) ? envMode : "v0";
|
|
5544
|
+
}
|
|
5545
|
+
|
|
5546
|
+
// ../../../node_modules/.bun/posthog-node@5.49.2/node_modules/posthog-node/dist/capture-v1/routing.mjs
|
|
5547
|
+
var AI_EVENT_PREFIX = "$ai_";
|
|
5548
|
+
var ANALYTICS_ROUTE = "analytics";
|
|
5549
|
+
var AI_ROUTE = "ai";
|
|
5550
|
+
function isLegacyOnlyEvent(message) {
|
|
5551
|
+
return typeof message.event == "string" && message.event.startsWith(AI_EVENT_PREFIX);
|
|
5552
|
+
}
|
|
5553
|
+
|
|
5554
|
+
// ../../../node_modules/.bun/posthog-node@5.49.2/node_modules/posthog-node/dist/capture-v1/errors.mjs
|
|
5555
|
+
class CaptureV1Error extends Error {
|
|
5556
|
+
constructor({ requestId, drops, retryExhausted, cause }) {
|
|
5557
|
+
super(CaptureV1Error.buildMessage(requestId, drops, retryExhausted, cause)), this.name = "CaptureV1Error";
|
|
5558
|
+
this.requestId = requestId;
|
|
5559
|
+
this.drops = drops;
|
|
5560
|
+
this.retryExhausted = retryExhausted;
|
|
5561
|
+
this.cause = cause;
|
|
5562
|
+
}
|
|
5563
|
+
static buildMessage(requestId, drops, retryExhausted, cause) {
|
|
5564
|
+
let message = `Capture V1 batch ${requestId} did not fully deliver: ${drops.length} dropped, ${retryExhausted.length} undelivered`;
|
|
5565
|
+
if (cause instanceof Error)
|
|
5566
|
+
message += ` (${cause.message})`;
|
|
5567
|
+
return message;
|
|
5568
|
+
}
|
|
5569
|
+
}
|
|
5570
|
+
|
|
5571
|
+
// ../../../node_modules/.bun/posthog-node@5.49.2/node_modules/posthog-node/dist/capture-v1/transform.mjs
|
|
5572
|
+
function coerceBool(value) {
|
|
5573
|
+
if (typeof value == "boolean")
|
|
5574
|
+
return value;
|
|
5575
|
+
if (typeof value == "number")
|
|
5576
|
+
return value !== 0;
|
|
5577
|
+
if (typeof value == "string") {
|
|
5578
|
+
const normalized = value.trim().toLowerCase();
|
|
5579
|
+
if (normalized === "true" || normalized === "1")
|
|
5580
|
+
return true;
|
|
5581
|
+
if (normalized === "false" || normalized === "0")
|
|
5582
|
+
return false;
|
|
5583
|
+
}
|
|
5584
|
+
}
|
|
5585
|
+
function coerceString(value) {
|
|
5586
|
+
return typeof value == "string" ? value : undefined;
|
|
5587
|
+
}
|
|
5588
|
+
var OPTION_SENTINELS = [
|
|
5589
|
+
{
|
|
5590
|
+
property: "$cookieless_mode",
|
|
5591
|
+
optionKey: "cookieless_mode",
|
|
5592
|
+
coerce: coerceBool
|
|
5593
|
+
},
|
|
5594
|
+
{
|
|
5595
|
+
property: "$ignore_sent_at",
|
|
5596
|
+
optionKey: "disable_skew_correction",
|
|
5597
|
+
coerce: coerceBool
|
|
5598
|
+
},
|
|
5599
|
+
{
|
|
5600
|
+
property: "$process_person_profile",
|
|
5601
|
+
optionKey: "process_person_profile",
|
|
5602
|
+
coerce: coerceBool
|
|
5603
|
+
},
|
|
5604
|
+
{
|
|
5605
|
+
property: "$product_tour_id",
|
|
5606
|
+
optionKey: "product_tour_id",
|
|
5607
|
+
coerce: coerceString
|
|
5608
|
+
}
|
|
5609
|
+
];
|
|
5610
|
+
var TOPLEVEL_SENTINELS = [
|
|
5611
|
+
{
|
|
5612
|
+
property: "$session_id",
|
|
5613
|
+
field: "session_id"
|
|
5614
|
+
},
|
|
5615
|
+
{
|
|
5616
|
+
property: "$window_id",
|
|
5617
|
+
field: "window_id"
|
|
5618
|
+
}
|
|
5619
|
+
];
|
|
5620
|
+
function isRecord2(value) {
|
|
5621
|
+
return typeof value == "object" && value !== null && !Array.isArray(value);
|
|
5622
|
+
}
|
|
5623
|
+
function toRfc3339(timestamp) {
|
|
5624
|
+
if (typeof timestamp == "string") {
|
|
5625
|
+
const asDate2 = new Date(timestamp);
|
|
5626
|
+
if (Number.isNaN(asDate2.getTime()))
|
|
5627
|
+
return new Date().toISOString();
|
|
5628
|
+
const normalized = asDate2.toISOString();
|
|
5629
|
+
const fractionalSeconds = timestamp.match(/\.(\d+)(?:Z|[+-]\d{2}:?\d{2})?$/i)?.[1];
|
|
5630
|
+
return fractionalSeconds && fractionalSeconds.length > 3 ? normalized.replace(/\.\d{3}Z$/, `.${fractionalSeconds}Z`) : normalized;
|
|
5631
|
+
}
|
|
5632
|
+
if (timestamp instanceof Date)
|
|
5633
|
+
return Number.isNaN(timestamp.getTime()) ? new Date().toISOString() : timestamp.toISOString();
|
|
5634
|
+
const asDate = timestamp == null ? new Date : new Date(timestamp);
|
|
5635
|
+
return Number.isNaN(asDate.getTime()) ? new Date().toISOString() : asDate.toISOString();
|
|
5636
|
+
}
|
|
5637
|
+
function relocateInto(properties, key, value) {
|
|
5638
|
+
if (value !== undefined && !(key in properties))
|
|
5639
|
+
properties[key] = value;
|
|
5640
|
+
}
|
|
5641
|
+
function buildV1Event(message) {
|
|
5642
|
+
const sourceProperties = isRecord2(message.properties) ? message.properties : {};
|
|
5643
|
+
const properties = {
|
|
5644
|
+
...sourceProperties
|
|
5645
|
+
};
|
|
5646
|
+
const options = {};
|
|
5647
|
+
for (const { property, optionKey, coerce } of OPTION_SENTINELS)
|
|
5648
|
+
if (property in properties) {
|
|
5649
|
+
const coerced = coerce(properties[property]);
|
|
5650
|
+
if (coerced !== undefined)
|
|
5651
|
+
options[optionKey] = coerced;
|
|
5652
|
+
delete properties[property];
|
|
5653
|
+
}
|
|
5654
|
+
const topLevel = {};
|
|
5655
|
+
for (const { property, field } of TOPLEVEL_SENTINELS)
|
|
5656
|
+
if (property in properties) {
|
|
5657
|
+
const value = properties[property];
|
|
5658
|
+
if (typeof value == "string")
|
|
5659
|
+
topLevel[field] = value;
|
|
5660
|
+
delete properties[property];
|
|
5661
|
+
}
|
|
5662
|
+
delete properties.$lib;
|
|
5663
|
+
delete properties.$lib_version;
|
|
5664
|
+
relocateInto(properties, "$set", message.$set);
|
|
5665
|
+
relocateInto(properties, "$set_once", message.$set_once);
|
|
5666
|
+
return {
|
|
5667
|
+
event: String(message.event ?? ""),
|
|
5668
|
+
uuid: String(message.uuid ?? ""),
|
|
5669
|
+
distinct_id: String(message.distinct_id ?? ""),
|
|
5670
|
+
timestamp: toRfc3339(message.timestamp),
|
|
5671
|
+
...topLevel,
|
|
5672
|
+
options,
|
|
5673
|
+
properties
|
|
5674
|
+
};
|
|
5675
|
+
}
|
|
5676
|
+
function buildV1Batch(messages, { createdAt, historicalMigration }) {
|
|
5677
|
+
const batch = {
|
|
5678
|
+
created_at: createdAt,
|
|
5679
|
+
batch: messages.map(buildV1Event)
|
|
5680
|
+
};
|
|
5681
|
+
if (historicalMigration)
|
|
5682
|
+
batch.historical_migration = true;
|
|
5683
|
+
return batch;
|
|
5684
|
+
}
|
|
5685
|
+
|
|
5686
|
+
// ../../../node_modules/.bun/posthog-node@5.49.2/node_modules/posthog-node/dist/capture-v1/sender.mjs
|
|
5687
|
+
var V1_ANALYTICS_PATH = "/i/v1/analytics/events";
|
|
5688
|
+
var DEFAULT_MAX_BACKOFF_MS = 30000;
|
|
5689
|
+
var RETRYABLE_STATUSES = new Set([
|
|
5690
|
+
408,
|
|
5691
|
+
500,
|
|
5692
|
+
502,
|
|
5693
|
+
503,
|
|
5694
|
+
504
|
|
5695
|
+
]);
|
|
5696
|
+
|
|
5697
|
+
class V1CaptureSender {
|
|
5698
|
+
constructor(config, hooks) {
|
|
5699
|
+
this.config = config;
|
|
5700
|
+
this.maxBackoffMs = config.maxBackoffMs ?? DEFAULT_MAX_BACKOFF_MS;
|
|
5701
|
+
this.fetchFn = hooks.fetch;
|
|
5702
|
+
this.onError = hooks.onError;
|
|
5703
|
+
this.now = hooks.now ?? Date.now;
|
|
5704
|
+
this.sleep = hooks.sleep ?? ((ms) => new Promise((resolve) => safeSetTimeout(resolve, ms)));
|
|
5705
|
+
this.generateRequestId = hooks.generateRequestId ?? uuidv7;
|
|
5706
|
+
this.compress = hooks.compress ?? gzipCompress;
|
|
5707
|
+
}
|
|
5708
|
+
async sendV1Batch(messages) {
|
|
5709
|
+
if (messages.length === 0)
|
|
5710
|
+
return;
|
|
5711
|
+
const requestId = this.generateRequestId();
|
|
5712
|
+
const createdAt = new Date(this.now()).toISOString();
|
|
5713
|
+
const { batch } = buildV1Batch(messages, {
|
|
5714
|
+
createdAt,
|
|
5715
|
+
historicalMigration: this.config.historicalMigration
|
|
5716
|
+
});
|
|
5717
|
+
const url = `${this.config.host}${V1_ANALYTICS_PATH}`;
|
|
5718
|
+
const drops = [];
|
|
5719
|
+
let pending = batch;
|
|
5720
|
+
const maxAttempts = Math.max(1, this.config.maxAttempts);
|
|
5721
|
+
for (let attempt = 1;attempt <= maxAttempts; attempt++) {
|
|
5722
|
+
const isLastAttempt = attempt === maxAttempts;
|
|
5723
|
+
const payload = safeJsonStringify({
|
|
5724
|
+
created_at: createdAt,
|
|
5725
|
+
...this.config.historicalMigration ? {
|
|
5726
|
+
historical_migration: true
|
|
5727
|
+
} : {},
|
|
5728
|
+
batch: pending
|
|
5729
|
+
});
|
|
5730
|
+
let captureAttempt;
|
|
5731
|
+
let retryDelayMs;
|
|
5732
|
+
try {
|
|
5733
|
+
captureAttempt = await this.sendOnce(url, payload, attempt, requestId);
|
|
5734
|
+
const { response, signal } = captureAttempt;
|
|
5735
|
+
const { status } = response;
|
|
5736
|
+
if (status < 200 || status >= 300)
|
|
5737
|
+
if (!isLastAttempt && RETRYABLE_STATUSES.has(status)) {
|
|
5738
|
+
const retryAfterMs = this.parseRetryAfter(response);
|
|
5739
|
+
await captureAttempt.waitFor(captureAttempt.cancelBody()).catch(() => {});
|
|
5740
|
+
retryDelayMs = this.backoffDelay(attempt, retryAfterMs);
|
|
5741
|
+
} else {
|
|
5742
|
+
const httpError = await this.buildHttpError(response, status, captureAttempt.waitFor);
|
|
5743
|
+
return this.surfaceBatchFailure(requestId, drops, pending, httpError);
|
|
5744
|
+
}
|
|
5745
|
+
else {
|
|
5746
|
+
let parsed;
|
|
5747
|
+
try {
|
|
5748
|
+
parsed = await captureAttempt.waitFor(this.parseResponse(response));
|
|
5749
|
+
} catch (error) {
|
|
5750
|
+
if (signal.aborted)
|
|
5751
|
+
throw error;
|
|
5752
|
+
return this.surfaceBatchFailure(requestId, drops, pending, new Error(`Capture V1 returned an unparseable ${status} response body`));
|
|
5753
|
+
}
|
|
5754
|
+
const retryable = this.classify(pending, parsed, drops);
|
|
5755
|
+
if (retryable.length === 0)
|
|
5756
|
+
return this.surfacePartialDrops(requestId, drops);
|
|
5757
|
+
if (isLastAttempt)
|
|
5758
|
+
return void this.onError(new CaptureV1Error({
|
|
5759
|
+
requestId,
|
|
5760
|
+
drops,
|
|
5761
|
+
retryExhausted: retryable.map((event) => event.uuid)
|
|
5762
|
+
}));
|
|
5763
|
+
pending = retryable;
|
|
5764
|
+
const retryAfterMs = this.parseRetryAfter(response);
|
|
5765
|
+
retryDelayMs = this.backoffDelay(attempt, retryAfterMs);
|
|
5766
|
+
}
|
|
5767
|
+
} catch (transportError) {
|
|
5768
|
+
if (captureAttempt && !captureAttempt.signal.aborted)
|
|
5769
|
+
throw transportError;
|
|
5770
|
+
if (isLastAttempt)
|
|
5771
|
+
return this.surfaceBatchFailure(requestId, drops, pending, transportError);
|
|
5772
|
+
retryDelayMs = this.backoffDelay(attempt);
|
|
5773
|
+
} finally {
|
|
5774
|
+
captureAttempt?.cleanup();
|
|
5775
|
+
}
|
|
5776
|
+
if (retryDelayMs !== undefined)
|
|
5777
|
+
await this.sleep(retryDelayMs);
|
|
5778
|
+
}
|
|
5779
|
+
}
|
|
5780
|
+
async sendOnce(url, payload, attempt, requestId) {
|
|
5781
|
+
const headers = this.buildHeaders(attempt, requestId);
|
|
5782
|
+
let body = payload;
|
|
5783
|
+
if (this.config.compressionEnabled) {
|
|
5784
|
+
const compressed = await this.compress(payload, this.config.isDebug);
|
|
5785
|
+
if (compressed !== null) {
|
|
5786
|
+
body = compressed;
|
|
5787
|
+
headers["Content-Encoding"] = "gzip";
|
|
5788
|
+
}
|
|
5789
|
+
}
|
|
5790
|
+
const controller = new AbortController;
|
|
5791
|
+
let timeoutPhase = "waiting for response headers";
|
|
5792
|
+
let timer;
|
|
5793
|
+
const deadline = new Promise((_resolve, reject) => {
|
|
5794
|
+
timer = safeSetTimeout(() => {
|
|
5795
|
+
const timeoutError = new Error(`Capture V1 request timed out ${timeoutPhase} after ${this.config.requestTimeoutMs}ms`);
|
|
5796
|
+
timeoutError.name = "AbortError";
|
|
5797
|
+
reject(timeoutError);
|
|
5798
|
+
controller.abort(timeoutError);
|
|
5799
|
+
}, this.config.requestTimeoutMs);
|
|
5800
|
+
});
|
|
5801
|
+
try {
|
|
5802
|
+
const fetchPromise = this.fetchFn(url, {
|
|
5803
|
+
method: "POST",
|
|
5804
|
+
headers,
|
|
5805
|
+
body,
|
|
5806
|
+
signal: controller.signal
|
|
5807
|
+
});
|
|
5808
|
+
let responseAccepted = false;
|
|
5809
|
+
fetchPromise.then((lateResponse) => {
|
|
5810
|
+
if (controller.signal.aborted && !responseAccepted)
|
|
5811
|
+
this.cancelBody(lateResponse);
|
|
5812
|
+
}).catch(() => {});
|
|
5813
|
+
const response = await Promise.race([
|
|
5814
|
+
fetchPromise,
|
|
5815
|
+
deadline
|
|
5816
|
+
]);
|
|
5817
|
+
responseAccepted = true;
|
|
5818
|
+
timeoutPhase = "while reading the response body";
|
|
5819
|
+
let cleanedUp = false;
|
|
5820
|
+
let cancellation;
|
|
5821
|
+
const cancelBody = () => cancellation ??= this.cancelBody(response);
|
|
5822
|
+
return {
|
|
5823
|
+
response,
|
|
5824
|
+
signal: controller.signal,
|
|
5825
|
+
waitFor: (operation) => Promise.race([
|
|
5826
|
+
operation,
|
|
5827
|
+
deadline
|
|
5828
|
+
]),
|
|
5829
|
+
cancelBody,
|
|
5830
|
+
cleanup: () => {
|
|
5831
|
+
if (cleanedUp)
|
|
5832
|
+
return;
|
|
5833
|
+
cleanedUp = true;
|
|
5834
|
+
clearTimeout(timer);
|
|
5835
|
+
if (controller.signal.aborted)
|
|
5836
|
+
cancelBody();
|
|
5837
|
+
}
|
|
5838
|
+
};
|
|
5839
|
+
} catch (error) {
|
|
5840
|
+
clearTimeout(timer);
|
|
5841
|
+
throw error;
|
|
5842
|
+
}
|
|
5843
|
+
}
|
|
5844
|
+
buildHeaders(attempt, requestId) {
|
|
5845
|
+
const sdkInfo = `${this.config.libraryId}/${this.config.libraryVersion}`;
|
|
5846
|
+
const headers = {
|
|
5847
|
+
"Content-Type": "application/json",
|
|
5848
|
+
Authorization: `Bearer ${this.config.apiKey}`,
|
|
5849
|
+
"PostHog-Sdk-Info": sdkInfo,
|
|
5850
|
+
"PostHog-Attempt": String(attempt),
|
|
5851
|
+
"PostHog-Request-Id": requestId,
|
|
5852
|
+
"PostHog-Request-Timestamp": new Date(this.now()).toISOString()
|
|
5853
|
+
};
|
|
5854
|
+
if (this.config.userAgent)
|
|
5855
|
+
headers["User-Agent"] = this.config.userAgent;
|
|
5856
|
+
return headers;
|
|
5857
|
+
}
|
|
5858
|
+
classify(pending, parsed, drops) {
|
|
5859
|
+
const results = parsed.results ?? {};
|
|
5860
|
+
const retryable = [];
|
|
5861
|
+
for (const event of pending) {
|
|
5862
|
+
const result = results[event.uuid];
|
|
5863
|
+
if (result) {
|
|
5864
|
+
if (result.result === "drop")
|
|
5865
|
+
drops.push({
|
|
5866
|
+
uuid: event.uuid,
|
|
5867
|
+
details: result.details ?? undefined
|
|
5868
|
+
});
|
|
5869
|
+
else if (result.result === "retry")
|
|
5870
|
+
retryable.push(event);
|
|
5871
|
+
}
|
|
5872
|
+
}
|
|
5873
|
+
return retryable;
|
|
5874
|
+
}
|
|
5875
|
+
backoffDelay(attempt, retryAfterMs) {
|
|
5876
|
+
const exponential = Math.min(this.config.initialRetryDelayMs * 2 ** (attempt - 1), this.maxBackoffMs);
|
|
5877
|
+
if (retryAfterMs === undefined)
|
|
5878
|
+
return exponential;
|
|
5879
|
+
return Math.max(exponential, Math.min(retryAfterMs, this.maxBackoffMs));
|
|
5880
|
+
}
|
|
5881
|
+
parseRetryAfter(response) {
|
|
5882
|
+
const raw = response.headers?.get("Retry-After");
|
|
5883
|
+
if (!raw)
|
|
5884
|
+
return;
|
|
5885
|
+
const trimmed = raw.trim();
|
|
5886
|
+
if (/^\d+$/.test(trimmed)) {
|
|
5887
|
+
const seconds = parseInt(trimmed, 10);
|
|
5888
|
+
return Number.isFinite(seconds) && seconds > 0 ? 1000 * seconds : undefined;
|
|
5889
|
+
}
|
|
5890
|
+
const dateMs = Date.parse(trimmed);
|
|
5891
|
+
if (Number.isNaN(dateMs))
|
|
5892
|
+
return;
|
|
5893
|
+
const delta = dateMs - this.now();
|
|
5894
|
+
return delta > 0 ? delta : undefined;
|
|
5895
|
+
}
|
|
5896
|
+
async parseResponse(response) {
|
|
5897
|
+
const text = await response.text();
|
|
5898
|
+
const parsed = JSON.parse(text);
|
|
5899
|
+
if (typeof parsed != "object" || parsed === null || Array.isArray(parsed))
|
|
5900
|
+
throw new Error("unexpected response shape");
|
|
5901
|
+
const results = parsed.results;
|
|
5902
|
+
if (results !== undefined && (typeof results != "object" || results === null || Array.isArray(results)))
|
|
5903
|
+
throw new Error("unexpected results shape");
|
|
5904
|
+
return {
|
|
5905
|
+
results: results ?? {}
|
|
5906
|
+
};
|
|
5907
|
+
}
|
|
5908
|
+
async buildHttpError(response, status, waitFor) {
|
|
5909
|
+
let bodyText = "";
|
|
5910
|
+
try {
|
|
5911
|
+
bodyText = (await waitFor(response.text())).slice(0, 512);
|
|
5912
|
+
} catch {}
|
|
5913
|
+
const suffix = bodyText ? `: ${bodyText}` : "";
|
|
5914
|
+
return new Error(`Capture V1 request failed with HTTP ${status}${suffix}`);
|
|
5915
|
+
}
|
|
5916
|
+
surfaceBatchFailure(requestId, drops, pending, cause) {
|
|
5917
|
+
this.onError(new CaptureV1Error({
|
|
5918
|
+
requestId,
|
|
5919
|
+
drops,
|
|
5920
|
+
retryExhausted: pending.map((event) => event.uuid),
|
|
5921
|
+
cause
|
|
5922
|
+
}));
|
|
5923
|
+
}
|
|
5924
|
+
surfacePartialDrops(requestId, drops) {
|
|
5925
|
+
if (drops.length > 0)
|
|
5926
|
+
this.onError(new CaptureV1Error({
|
|
5927
|
+
requestId,
|
|
5928
|
+
drops,
|
|
5929
|
+
retryExhausted: []
|
|
5930
|
+
}));
|
|
5931
|
+
}
|
|
5932
|
+
async cancelBody(response) {
|
|
5933
|
+
try {
|
|
5934
|
+
await response.body?.cancel();
|
|
5935
|
+
} catch {}
|
|
5936
|
+
}
|
|
5937
|
+
}
|
|
5938
|
+
|
|
5939
|
+
// ../../../node_modules/.bun/posthog-node@5.49.2/node_modules/posthog-node/dist/ai-capture/routing.mjs
|
|
5940
|
+
var AI_CAPTURE_ROUTE = "ai-capture";
|
|
5941
|
+
var AI_CAPTURE_ENDPOINT_PATH = "/i/v0/ai/batch/";
|
|
5942
|
+
var AI_MAX_EVENT_BYTES = 8388608;
|
|
5943
|
+
var AI_BATCH_TARGET_BYTES = 5242880;
|
|
5944
|
+
|
|
5945
|
+
// ../../../node_modules/.bun/posthog-node@5.49.2/node_modules/posthog-node/dist/ai-capture/batching.mjs
|
|
5946
|
+
var encoder = new TextEncoder;
|
|
5947
|
+
function eventByteSize(message) {
|
|
5948
|
+
return encoder.encode(safeJsonStringify(message)).length;
|
|
5949
|
+
}
|
|
5950
|
+
function partitionAiBatch(messages, maxEventBytes = AI_MAX_EVENT_BYTES, targetBatchBytes = AI_BATCH_TARGET_BYTES) {
|
|
5951
|
+
const batches = [];
|
|
5952
|
+
const dropped = [];
|
|
5953
|
+
let current = [];
|
|
5954
|
+
let currentBytes = 0;
|
|
5955
|
+
for (const message of messages) {
|
|
5956
|
+
if (message === undefined)
|
|
5957
|
+
continue;
|
|
5958
|
+
const bytes = eventByteSize(message);
|
|
5959
|
+
if (bytes > maxEventBytes) {
|
|
5960
|
+
dropped.push({
|
|
5961
|
+
event: typeof message.event == "string" ? message.event : "unknown",
|
|
5962
|
+
bytes
|
|
5963
|
+
});
|
|
5964
|
+
continue;
|
|
5965
|
+
}
|
|
5966
|
+
if (current.length > 0 && currentBytes + bytes > targetBatchBytes) {
|
|
5967
|
+
batches.push(current);
|
|
5968
|
+
current = [];
|
|
5969
|
+
currentBytes = 0;
|
|
5970
|
+
}
|
|
5971
|
+
current.push(message);
|
|
5972
|
+
currentBytes += bytes;
|
|
5973
|
+
}
|
|
5974
|
+
if (current.length > 0)
|
|
5975
|
+
batches.push(current);
|
|
5976
|
+
return {
|
|
5977
|
+
batches,
|
|
5978
|
+
dropped
|
|
5979
|
+
};
|
|
5980
|
+
}
|
|
5981
|
+
|
|
5982
|
+
// ../../../node_modules/.bun/posthog-node@5.49.2/node_modules/posthog-node/dist/client.mjs
|
|
4397
5983
|
var MINIMUM_POLLING_INTERVAL = 100;
|
|
4398
5984
|
var THIRTY_SECONDS = 30000;
|
|
4399
5985
|
var MAX_CACHE_SIZE = 50000;
|
|
@@ -4418,6 +6004,12 @@ function normalizeHost(value) {
|
|
|
4418
6004
|
const normalizedValue = typeof value == "string" ? value.trim() : "";
|
|
4419
6005
|
return normalizedValue || DEFAULT_NODE_HOST;
|
|
4420
6006
|
}
|
|
6007
|
+
function normalizeUnsetPersonProperties(value) {
|
|
6008
|
+
const propertyNames = Array.isArray(value) ? value : [
|
|
6009
|
+
value
|
|
6010
|
+
];
|
|
6011
|
+
return propertyNames.filter((propertyName) => typeof propertyName == "string" && propertyName.trim().length > 0);
|
|
6012
|
+
}
|
|
4421
6013
|
function buildFlagEventProperties(flagValues) {
|
|
4422
6014
|
if (!flagValues)
|
|
4423
6015
|
return {};
|
|
@@ -4435,11 +6027,15 @@ class PostHogBackendClient extends PostHogCoreStateless {
|
|
|
4435
6027
|
const normalizedApiKey = normalizeApiKey(apiKey);
|
|
4436
6028
|
const normalizedOptions = {
|
|
4437
6029
|
...options,
|
|
6030
|
+
maxQueueSize: options.maxQueueSize ?? 1e4,
|
|
6031
|
+
flushInterval: options.flushInterval ?? 5000,
|
|
4438
6032
|
host: normalizeHost(options.host),
|
|
4439
|
-
personalApiKey: normalizePersonalApiKey(options.personalApiKey)
|
|
6033
|
+
personalApiKey: normalizePersonalApiKey(options.secretKey ?? options.personalApiKey)
|
|
4440
6034
|
};
|
|
4441
|
-
super(normalizedApiKey, normalizedOptions), this._memoryStorage = new PostHogMemoryStorage;
|
|
6035
|
+
super(normalizedApiKey, normalizedOptions), this._memoryStorage = new PostHogMemoryStorage, this._aiCaptureRouteActive = false, this._minimalFlagCalledEvents = false;
|
|
4442
6036
|
this.options = normalizedOptions;
|
|
6037
|
+
this.captureMode = resolveCaptureMode();
|
|
6038
|
+
this.enableFullAiCapture = normalizedOptions.enableFullAiCapture === true;
|
|
4443
6039
|
this.context = this.initializeContext();
|
|
4444
6040
|
this.options.featureFlagsPollingInterval = typeof normalizedOptions.featureFlagsPollingInterval == "number" ? Math.max(normalizedOptions.featureFlagsPollingInterval, MINIMUM_POLLING_INTERVAL) : THIRTY_SECONDS;
|
|
4445
6041
|
if (typeof normalizedOptions.waitUntilDebounceMs == "number")
|
|
@@ -4464,21 +6060,24 @@ class PostHogBackendClient extends PostHogCoreStateless {
|
|
|
4464
6060
|
onLoad: (count) => {
|
|
4465
6061
|
this._events.emit("localEvaluationFlagsLoaded", count);
|
|
4466
6062
|
},
|
|
6063
|
+
onMinimalFlagCalledEvents: (enabled) => {
|
|
6064
|
+
this._minimalFlagCalledEvents = enabled;
|
|
6065
|
+
},
|
|
4467
6066
|
customHeaders: this.getCustomHeaders(),
|
|
4468
6067
|
cacheProvider: normalizedOptions.flagDefinitionCacheProvider,
|
|
4469
6068
|
strictLocalEvaluation: normalizedOptions.strictLocalEvaluation
|
|
4470
6069
|
});
|
|
4471
6070
|
}
|
|
4472
|
-
this.errorTracking = new
|
|
6071
|
+
this.errorTracking = new error_tracking_ErrorTracking(this, normalizedOptions, this._logger);
|
|
4473
6072
|
this.distinctIdHasSentFlagCalls = {};
|
|
4474
6073
|
this.maxCacheSize = normalizedOptions.maxCacheSize || MAX_CACHE_SIZE;
|
|
4475
6074
|
}
|
|
4476
|
-
enqueue(type, message, options) {
|
|
4477
|
-
super.enqueue(type, message, options);
|
|
6075
|
+
enqueue(type, message, options, explicitRoute) {
|
|
6076
|
+
super.enqueue(type, message, options, explicitRoute);
|
|
4478
6077
|
this.scheduleDebouncedFlush();
|
|
4479
6078
|
}
|
|
4480
6079
|
async flush() {
|
|
4481
|
-
const flushPromise =
|
|
6080
|
+
const flushPromise = this.flushWithPendingPromises();
|
|
4482
6081
|
const waitUntil = this.options.waitUntil;
|
|
4483
6082
|
if (waitUntil && !this._waitUntilCycle)
|
|
4484
6083
|
try {
|
|
@@ -4531,7 +6130,7 @@ class PostHogBackendClient extends PostHogCoreStateless {
|
|
|
4531
6130
|
async resolveWaitUntilFlush() {
|
|
4532
6131
|
const resolve = this._consumeWaitUntilCycle();
|
|
4533
6132
|
try {
|
|
4534
|
-
await
|
|
6133
|
+
await this.flushWithPendingPromises();
|
|
4535
6134
|
} catch {} finally {
|
|
4536
6135
|
resolve?.();
|
|
4537
6136
|
}
|
|
@@ -4545,12 +6144,103 @@ class PostHogBackendClient extends PostHogCoreStateless {
|
|
|
4545
6144
|
fetch(url, options) {
|
|
4546
6145
|
return this.options.fetch ? this.options.fetch(url, options) : fetch(url, options);
|
|
4547
6146
|
}
|
|
6147
|
+
getQueueRouteKey(message) {
|
|
6148
|
+
return this.captureMode === "v1" && isLegacyOnlyEvent(message) ? AI_ROUTE : ANALYTICS_ROUTE;
|
|
6149
|
+
}
|
|
6150
|
+
persistedQueueKeyForRoute(route) {
|
|
6151
|
+
if (route === AI_CAPTURE_ROUTE)
|
|
6152
|
+
return types_PostHogPersistedProperty.AiCaptureQueue;
|
|
6153
|
+
return route === AI_ROUTE ? types_PostHogPersistedProperty.AiQueue : types_PostHogPersistedProperty.Queue;
|
|
6154
|
+
}
|
|
6155
|
+
getActiveQueueRoutes() {
|
|
6156
|
+
const routes = this.captureMode === "v1" ? [
|
|
6157
|
+
ANALYTICS_ROUTE,
|
|
6158
|
+
AI_ROUTE
|
|
6159
|
+
] : [
|
|
6160
|
+
ANALYTICS_ROUTE
|
|
6161
|
+
];
|
|
6162
|
+
if (this._aiCaptureRouteActive)
|
|
6163
|
+
routes.push(AI_CAPTURE_ROUTE);
|
|
6164
|
+
return routes;
|
|
6165
|
+
}
|
|
6166
|
+
getBatchEndpointPath(route) {
|
|
6167
|
+
return route === AI_CAPTURE_ROUTE ? AI_CAPTURE_ENDPOINT_PATH : super.getBatchEndpointPath(route);
|
|
6168
|
+
}
|
|
6169
|
+
async sendBatch(batchMessages, retryOptions, route = ANALYTICS_ROUTE) {
|
|
6170
|
+
if (route === AI_CAPTURE_ROUTE)
|
|
6171
|
+
return this.sendAiCaptureBatch(batchMessages, retryOptions);
|
|
6172
|
+
if (this.captureMode !== "v1" || route === AI_ROUTE)
|
|
6173
|
+
return super.sendBatch(batchMessages, retryOptions, route);
|
|
6174
|
+
const v1Events = batchMessages.filter((message) => message !== undefined);
|
|
6175
|
+
await this.getV1Sender().sendV1Batch(v1Events);
|
|
6176
|
+
}
|
|
6177
|
+
async sendAiCaptureBatch(batchMessages, retryOptions) {
|
|
6178
|
+
const { batches, dropped } = partitionAiBatch(batchMessages);
|
|
6179
|
+
for (const { event, bytes } of dropped) {
|
|
6180
|
+
const message = `Event ${event} (${bytes} bytes) exceeds the ${AI_MAX_EVENT_BYTES / 1048576}MiB limit for ${AI_CAPTURE_ENDPOINT_PATH}, dropping.`;
|
|
6181
|
+
this._logger.error(message);
|
|
6182
|
+
this._events.emit("error", new Error(message));
|
|
6183
|
+
}
|
|
6184
|
+
for (const batch of batches)
|
|
6185
|
+
await this.sendAiSubBatch(batch, retryOptions);
|
|
6186
|
+
}
|
|
6187
|
+
async sendAiSubBatch(batch, retryOptions) {
|
|
6188
|
+
try {
|
|
6189
|
+
await super.sendBatch(batch, retryOptions, AI_CAPTURE_ROUTE);
|
|
6190
|
+
} catch (err) {
|
|
6191
|
+
if (!isPostHogFetchContentTooLargeError(err))
|
|
6192
|
+
throw err;
|
|
6193
|
+
if (batch.length === 1) {
|
|
6194
|
+
const [event] = batch;
|
|
6195
|
+
const eventName = typeof event.event == "string" ? event.event : "unknown";
|
|
6196
|
+
const message = `Event ${eventName} (${eventByteSize(event)} bytes) was rejected with 413 by ${AI_CAPTURE_ENDPOINT_PATH} on its own, dropping.`;
|
|
6197
|
+
this._logger.error(message);
|
|
6198
|
+
this._events.emit("error", new Error(message));
|
|
6199
|
+
return;
|
|
6200
|
+
}
|
|
6201
|
+
const mid = Math.ceil(batch.length / 2);
|
|
6202
|
+
await this.sendAiSubBatch(batch.slice(0, mid), retryOptions);
|
|
6203
|
+
await this.sendAiSubBatch(batch.slice(mid), retryOptions);
|
|
6204
|
+
}
|
|
6205
|
+
}
|
|
6206
|
+
getV1Sender() {
|
|
6207
|
+
if (!this._v1Sender)
|
|
6208
|
+
this._v1Sender = new V1CaptureSender({
|
|
6209
|
+
host: this.host,
|
|
6210
|
+
apiKey: this.apiKey,
|
|
6211
|
+
libraryId: this.getLibraryId(),
|
|
6212
|
+
libraryVersion: this.getLibraryVersion(),
|
|
6213
|
+
userAgent: this.getCustomUserAgent() || undefined,
|
|
6214
|
+
historicalMigration: this.historicalMigration,
|
|
6215
|
+
compressionEnabled: !this.disableCompression,
|
|
6216
|
+
requestTimeoutMs: this.requestTimeout,
|
|
6217
|
+
maxAttempts: (this.options.fetchRetryCount ?? 3) + 1,
|
|
6218
|
+
initialRetryDelayMs: this.options.fetchRetryDelay ?? 3000,
|
|
6219
|
+
isDebug: this.isDebug
|
|
6220
|
+
}, {
|
|
6221
|
+
fetch: (url, fetchOptions) => this.fetch(url, fetchOptions),
|
|
6222
|
+
onError: (error) => this._events.emit("error", error),
|
|
6223
|
+
compress: (payload) => this.compressPayload(payload)
|
|
6224
|
+
});
|
|
6225
|
+
return this._v1Sender;
|
|
6226
|
+
}
|
|
4548
6227
|
getLibraryVersion() {
|
|
4549
6228
|
return version;
|
|
4550
6229
|
}
|
|
6230
|
+
get metrics() {
|
|
6231
|
+
if (!this._metrics)
|
|
6232
|
+
this._metrics = new PostHogMetrics(this, resolveMetricsConfig(this.options.metrics), this._logger);
|
|
6233
|
+
return this._metrics;
|
|
6234
|
+
}
|
|
4551
6235
|
getCustomUserAgent() {
|
|
4552
6236
|
return `${this.getLibraryId()}/${this.getLibraryVersion()}`;
|
|
4553
6237
|
}
|
|
6238
|
+
getCommonEventProperties() {
|
|
6239
|
+
const commonProperties = super.getCommonEventProperties();
|
|
6240
|
+
if (this.options.isServer ?? true)
|
|
6241
|
+
commonProperties.$is_server = true;
|
|
6242
|
+
return commonProperties;
|
|
6243
|
+
}
|
|
4554
6244
|
enable() {
|
|
4555
6245
|
return super.optIn();
|
|
4556
6246
|
}
|
|
@@ -4561,33 +6251,69 @@ class PostHogBackendClient extends PostHogCoreStateless {
|
|
|
4561
6251
|
super.debug(enabled);
|
|
4562
6252
|
this.featureFlagsPoller?.debug(enabled);
|
|
4563
6253
|
}
|
|
4564
|
-
|
|
6254
|
+
_warnIfInvalidCapture(props, stringArgumentWarning, exceptionCaptureWarning) {
|
|
4565
6255
|
if (typeof props == "string")
|
|
4566
|
-
this._logger.warn(
|
|
6256
|
+
this._logger.warn(stringArgumentWarning);
|
|
4567
6257
|
if (props.event === "$exception" && !props._originatedFromCaptureException)
|
|
4568
|
-
this._logger.warn(
|
|
4569
|
-
|
|
4570
|
-
|
|
4571
|
-
|
|
4572
|
-
|
|
4573
|
-
|
|
6258
|
+
this._logger.warn(exceptionCaptureWarning);
|
|
6259
|
+
}
|
|
6260
|
+
_sendPreparedEvent(type, props, immediate, prepareOptions, explicitRoute) {
|
|
6261
|
+
return this.addPendingPromise(this._prepareEventMessage(props, prepareOptions).then(({ distinctId, event, properties, options }) => {
|
|
6262
|
+
const captureOptions = {
|
|
6263
|
+
timestamp: options.timestamp,
|
|
6264
|
+
disableGeoip: options.disableGeoip,
|
|
6265
|
+
uuid: options.uuid
|
|
6266
|
+
};
|
|
6267
|
+
const message = {
|
|
6268
|
+
distinctId,
|
|
6269
|
+
event,
|
|
6270
|
+
properties: {
|
|
6271
|
+
...properties,
|
|
6272
|
+
...this.getCommonEventProperties()
|
|
6273
|
+
}
|
|
6274
|
+
};
|
|
6275
|
+
return immediate ? this.sendImmediate(type, message, captureOptions, explicitRoute) : this.enqueue(type, message, captureOptions, explicitRoute);
|
|
6276
|
+
}).catch((err) => {
|
|
4574
6277
|
if (err)
|
|
4575
6278
|
console.error(err);
|
|
4576
6279
|
}));
|
|
4577
6280
|
}
|
|
6281
|
+
_capturePreparedEvent(props, immediate) {
|
|
6282
|
+
return this._sendPreparedEvent("capture", props, immediate);
|
|
6283
|
+
}
|
|
6284
|
+
capture(props) {
|
|
6285
|
+
this._warnIfInvalidCapture(props, "Called capture() with a string as the first argument when an object was expected.", "Using `posthog.capture('$exception')` is unreliable because it does not attach required metadata. Use `posthog.captureException(error)` instead, which attaches required metadata automatically.");
|
|
6286
|
+
this._capturePreparedEvent(props, false);
|
|
6287
|
+
}
|
|
4578
6288
|
async captureImmediate(props) {
|
|
4579
|
-
|
|
4580
|
-
|
|
4581
|
-
|
|
4582
|
-
|
|
4583
|
-
|
|
4584
|
-
|
|
4585
|
-
|
|
4586
|
-
|
|
4587
|
-
|
|
4588
|
-
|
|
4589
|
-
|
|
4590
|
-
|
|
6289
|
+
this._warnIfInvalidCapture(props, "Called captureImmediate() with a string as the first argument when an object was expected.", "Capturing a `$exception` event via `posthog.captureImmediate('$exception')` is unreliable because it does not attach required metadata. Use `posthog.captureExceptionImmediate(error)` instead, which attaches this metadata by default.");
|
|
6290
|
+
return this._capturePreparedEvent(props, true);
|
|
6291
|
+
}
|
|
6292
|
+
captureAi(props) {
|
|
6293
|
+
if (this.disabled)
|
|
6294
|
+
return;
|
|
6295
|
+
const uuid = getEventUuid(props.uuid, uuidv7);
|
|
6296
|
+
this._sendPreparedAiEvent({
|
|
6297
|
+
...props,
|
|
6298
|
+
uuid
|
|
6299
|
+
}, false);
|
|
6300
|
+
return uuid;
|
|
6301
|
+
}
|
|
6302
|
+
async captureAiImmediate(props) {
|
|
6303
|
+
if (this.disabled)
|
|
6304
|
+
return;
|
|
6305
|
+
const uuid = getEventUuid(props.uuid, uuidv7);
|
|
6306
|
+
await this._sendPreparedAiEvent({
|
|
6307
|
+
...props,
|
|
6308
|
+
uuid
|
|
6309
|
+
}, true);
|
|
6310
|
+
return uuid;
|
|
6311
|
+
}
|
|
6312
|
+
_sendPreparedAiEvent(props, immediate) {
|
|
6313
|
+
if (typeof props?.event == "string" && !props.event.startsWith("$ai_"))
|
|
6314
|
+
this._logger.debug(`captureAi called with non-AI event ${props.event}; routing it to the AI endpoint anyway.`);
|
|
6315
|
+
this._aiCaptureRouteActive = true;
|
|
6316
|
+
return this._sendPreparedEvent("capture", props, immediate, undefined, AI_CAPTURE_ROUTE);
|
|
4591
6317
|
}
|
|
4592
6318
|
identify({ distinctId, properties = {}, disableGeoip }) {
|
|
4593
6319
|
const { $set, $set_once, $anon_distinct_id, ...rest } = properties;
|
|
@@ -4598,8 +6324,13 @@ class PostHogBackendClient extends PostHogCoreStateless {
|
|
|
4598
6324
|
$set_once: setOnceProps,
|
|
4599
6325
|
$anon_distinct_id: $anon_distinct_id ?? undefined
|
|
4600
6326
|
};
|
|
4601
|
-
|
|
6327
|
+
this._sendPreparedEvent("identify", {
|
|
6328
|
+
distinctId,
|
|
6329
|
+
event: "$identify",
|
|
6330
|
+
properties: eventProperties,
|
|
4602
6331
|
disableGeoip
|
|
6332
|
+
}, false, {
|
|
6333
|
+
includeContextProperties: false
|
|
4603
6334
|
});
|
|
4604
6335
|
}
|
|
4605
6336
|
async identifyImmediate({ distinctId, properties = {}, disableGeoip }) {
|
|
@@ -4611,18 +6342,65 @@ class PostHogBackendClient extends PostHogCoreStateless {
|
|
|
4611
6342
|
$set_once: setOnceProps,
|
|
4612
6343
|
$anon_distinct_id: $anon_distinct_id ?? undefined
|
|
4613
6344
|
};
|
|
4614
|
-
await
|
|
6345
|
+
await this._sendPreparedEvent("identify", {
|
|
6346
|
+
distinctId,
|
|
6347
|
+
event: "$identify",
|
|
6348
|
+
properties: eventProperties,
|
|
4615
6349
|
disableGeoip
|
|
6350
|
+
}, true, {
|
|
6351
|
+
includeContextProperties: false
|
|
6352
|
+
});
|
|
6353
|
+
}
|
|
6354
|
+
setPersonProperties({ distinctId, properties = {}, propertiesOnce = {} }) {
|
|
6355
|
+
if (Object.keys(properties).length === 0 && Object.keys(propertiesOnce).length === 0)
|
|
6356
|
+
return;
|
|
6357
|
+
const eventProperties = {};
|
|
6358
|
+
if (Object.keys(properties).length > 0)
|
|
6359
|
+
eventProperties.$set = properties;
|
|
6360
|
+
if (Object.keys(propertiesOnce).length > 0)
|
|
6361
|
+
eventProperties.$set_once = propertiesOnce;
|
|
6362
|
+
this.capture({
|
|
6363
|
+
distinctId,
|
|
6364
|
+
event: "$set",
|
|
6365
|
+
properties: eventProperties
|
|
6366
|
+
});
|
|
6367
|
+
}
|
|
6368
|
+
unsetPersonProperties({ distinctId, properties }) {
|
|
6369
|
+
const propertyNames = normalizeUnsetPersonProperties(properties);
|
|
6370
|
+
if (propertyNames.length === 0)
|
|
6371
|
+
return;
|
|
6372
|
+
this.capture({
|
|
6373
|
+
distinctId,
|
|
6374
|
+
event: "$set",
|
|
6375
|
+
properties: {
|
|
6376
|
+
$unset: propertyNames
|
|
6377
|
+
}
|
|
4616
6378
|
});
|
|
4617
6379
|
}
|
|
4618
6380
|
alias(data) {
|
|
4619
|
-
|
|
6381
|
+
this._sendPreparedEvent("alias", {
|
|
6382
|
+
distinctId: data.distinctId,
|
|
6383
|
+
event: "$create_alias",
|
|
6384
|
+
properties: {
|
|
6385
|
+
distinct_id: data.distinctId,
|
|
6386
|
+
alias: data.alias
|
|
6387
|
+
},
|
|
4620
6388
|
disableGeoip: data.disableGeoip
|
|
6389
|
+
}, false, {
|
|
6390
|
+
includeContextProperties: false
|
|
4621
6391
|
});
|
|
4622
6392
|
}
|
|
4623
6393
|
async aliasImmediate(data) {
|
|
4624
|
-
await
|
|
6394
|
+
await this._sendPreparedEvent("alias", {
|
|
6395
|
+
distinctId: data.distinctId,
|
|
6396
|
+
event: "$create_alias",
|
|
6397
|
+
properties: {
|
|
6398
|
+
distinct_id: data.distinctId,
|
|
6399
|
+
alias: data.alias
|
|
6400
|
+
},
|
|
4625
6401
|
disableGeoip: data.disableGeoip
|
|
6402
|
+
}, true, {
|
|
6403
|
+
includeContextProperties: false
|
|
4626
6404
|
});
|
|
4627
6405
|
}
|
|
4628
6406
|
isLocalEvaluationReady() {
|
|
@@ -4677,7 +6455,7 @@ class PostHogBackendClient extends PostHogCoreStateless {
|
|
|
4677
6455
|
const adjustedProperties = this.addLocalPersonAndGroupProperties(distinctId, groups, personProperties, groupProperties);
|
|
4678
6456
|
personProperties = adjustedProperties.allPersonProperties;
|
|
4679
6457
|
groupProperties = adjustedProperties.allGroupProperties;
|
|
4680
|
-
const evaluationContext = this.createFeatureFlagEvaluationContext(distinctId, groups, personProperties, groupProperties);
|
|
6458
|
+
const evaluationContext = this.createFeatureFlagEvaluationContext(distinctId, groups, this.personPropertiesForLocalEvaluation(distinctId, personProperties), groupProperties);
|
|
4681
6459
|
if (onlyEvaluateLocally == undefined)
|
|
4682
6460
|
onlyEvaluateLocally = this.options.strictLocalEvaluation ?? false;
|
|
4683
6461
|
let result;
|
|
@@ -4688,6 +6466,7 @@ class PostHogBackendClient extends PostHogCoreStateless {
|
|
|
4688
6466
|
let flagId;
|
|
4689
6467
|
let flagVersion;
|
|
4690
6468
|
let flagReason;
|
|
6469
|
+
let flagHasExperiment;
|
|
4691
6470
|
const localEvaluationEnabled = this.featureFlagsPoller !== undefined;
|
|
4692
6471
|
if (localEvaluationEnabled) {
|
|
4693
6472
|
await this.featureFlagsPoller?.loadFeatureFlags();
|
|
@@ -4702,6 +6481,7 @@ class PostHogBackendClient extends PostHogCoreStateless {
|
|
|
4702
6481
|
const value = localResult.value;
|
|
4703
6482
|
flagId = flag.id;
|
|
4704
6483
|
flagReason = "Evaluated locally";
|
|
6484
|
+
flagHasExperiment = flag.has_experiment;
|
|
4705
6485
|
result = {
|
|
4706
6486
|
key,
|
|
4707
6487
|
enabled: value !== false,
|
|
@@ -4717,12 +6497,13 @@ class PostHogBackendClient extends PostHogCoreStateless {
|
|
|
4717
6497
|
}
|
|
4718
6498
|
}
|
|
4719
6499
|
if (!flagWasLocallyEvaluated && !onlyEvaluateLocally) {
|
|
4720
|
-
const flagsResponse = await super.getFeatureFlagDetailsStateless(evaluationContext.distinctId, evaluationContext.groups,
|
|
6500
|
+
const flagsResponse = await super.getFeatureFlagDetailsStateless(evaluationContext.distinctId, evaluationContext.groups, personProperties, groupProperties, disableGeoip, [
|
|
4721
6501
|
key
|
|
4722
6502
|
]);
|
|
4723
6503
|
if (flagsResponse === undefined)
|
|
4724
6504
|
featureFlagError = FeatureFlagError2.UNKNOWN_ERROR;
|
|
4725
6505
|
else {
|
|
6506
|
+
this._minimalFlagCalledEvents = flagsResponse.minimalFlagCalledEvents === true;
|
|
4726
6507
|
requestId = flagsResponse.requestId;
|
|
4727
6508
|
evaluatedAt = flagsResponse.evaluatedAt;
|
|
4728
6509
|
const errors = [];
|
|
@@ -4737,6 +6518,7 @@ class PostHogBackendClient extends PostHogCoreStateless {
|
|
|
4737
6518
|
flagId = flagDetail.metadata?.id;
|
|
4738
6519
|
flagVersion = flagDetail.metadata?.version;
|
|
4739
6520
|
flagReason = flagDetail.reason?.description ?? flagDetail.reason?.code;
|
|
6521
|
+
flagHasExperiment = flagDetail.metadata?.has_experiment;
|
|
4740
6522
|
let parsedPayload;
|
|
4741
6523
|
if (flagDetail.metadata?.payload !== undefined)
|
|
4742
6524
|
try {
|
|
@@ -4768,6 +6550,8 @@ class PostHogBackendClient extends PostHogCoreStateless {
|
|
|
4768
6550
|
$feature_flag_request_id: requestId,
|
|
4769
6551
|
$feature_flag_evaluated_at: flagWasLocallyEvaluated ? Date.now() : evaluatedAt
|
|
4770
6552
|
};
|
|
6553
|
+
if (flagHasExperiment !== undefined)
|
|
6554
|
+
properties.$feature_flag_has_experiment = flagHasExperiment;
|
|
4771
6555
|
if (flagWasLocallyEvaluated && this.featureFlagsPoller) {
|
|
4772
6556
|
const flagDefinitionsLoadedAt = this.featureFlagsPoller.getFlagDefinitionsLoadedAt();
|
|
4773
6557
|
if (flagDefinitionsLoadedAt !== undefined)
|
|
@@ -4882,7 +6666,7 @@ class PostHogBackendClient extends PostHogCoreStateless {
|
|
|
4882
6666
|
const adjustedProperties = this.addLocalPersonAndGroupProperties(resolvedDistinctId, groups, personProperties, groupProperties);
|
|
4883
6667
|
personProperties = adjustedProperties.allPersonProperties;
|
|
4884
6668
|
groupProperties = adjustedProperties.allGroupProperties;
|
|
4885
|
-
const evaluationContext = this.createFeatureFlagEvaluationContext(resolvedDistinctId, groups, personProperties, groupProperties);
|
|
6669
|
+
const evaluationContext = this.createFeatureFlagEvaluationContext(resolvedDistinctId, groups, this.personPropertiesForLocalEvaluation(resolvedDistinctId, personProperties), groupProperties);
|
|
4886
6670
|
if (onlyEvaluateLocally == undefined)
|
|
4887
6671
|
onlyEvaluateLocally = this.options.strictLocalEvaluation ?? false;
|
|
4888
6672
|
const localEvaluationResult = await this.featureFlagsPoller?.getAllFlagsAndPayloads(evaluationContext, flagKeys);
|
|
@@ -4895,7 +6679,7 @@ class PostHogBackendClient extends PostHogCoreStateless {
|
|
|
4895
6679
|
fallbackToFlags = localEvaluationResult.fallbackToFlags;
|
|
4896
6680
|
}
|
|
4897
6681
|
if (fallbackToFlags && !onlyEvaluateLocally) {
|
|
4898
|
-
const remoteEvaluationResult = await super.getFeatureFlagsAndPayloadsStateless(evaluationContext.distinctId, evaluationContext.groups,
|
|
6682
|
+
const remoteEvaluationResult = await super.getFeatureFlagsAndPayloadsStateless(evaluationContext.distinctId, evaluationContext.groups, personProperties, groupProperties, disableGeoip, flagKeys);
|
|
4899
6683
|
featureFlags = {
|
|
4900
6684
|
...featureFlags,
|
|
4901
6685
|
...remoteEvaluationResult.flags || {}
|
|
@@ -4943,7 +6727,7 @@ class PostHogBackendClient extends PostHogCoreStateless {
|
|
|
4943
6727
|
const adjustedProperties = this.addLocalPersonAndGroupProperties(resolvedDistinctId, groups, personProperties, groupProperties);
|
|
4944
6728
|
personProperties = adjustedProperties.allPersonProperties;
|
|
4945
6729
|
groupProperties = adjustedProperties.allGroupProperties;
|
|
4946
|
-
const evaluationContext = this.createFeatureFlagEvaluationContext(resolvedDistinctId, groups, personProperties, groupProperties);
|
|
6730
|
+
const evaluationContext = this.createFeatureFlagEvaluationContext(resolvedDistinctId, groups, this.personPropertiesForLocalEvaluation(resolvedDistinctId, personProperties), groupProperties);
|
|
4947
6731
|
if (onlyEvaluateLocally == undefined)
|
|
4948
6732
|
onlyEvaluateLocally = this.options.strictLocalEvaluation ?? false;
|
|
4949
6733
|
const records = {};
|
|
@@ -4964,14 +6748,16 @@ class PostHogBackendClient extends PostHogCoreStateless {
|
|
|
4964
6748
|
id: flagDef?.id,
|
|
4965
6749
|
version: undefined,
|
|
4966
6750
|
reason: "Evaluated locally",
|
|
4967
|
-
locallyEvaluated: true
|
|
6751
|
+
locallyEvaluated: true,
|
|
6752
|
+
hasExperiment: flagDef?.has_experiment
|
|
4968
6753
|
};
|
|
4969
6754
|
locallyEvaluatedKeys.add(key);
|
|
4970
6755
|
}
|
|
4971
6756
|
const fallbackToFlags = localResult ? localResult.fallbackToFlags : true;
|
|
4972
6757
|
if (fallbackToFlags && !onlyEvaluateLocally) {
|
|
4973
|
-
const details = await super.getFeatureFlagDetailsStateless(evaluationContext.distinctId, evaluationContext.groups,
|
|
6758
|
+
const details = await super.getFeatureFlagDetailsStateless(evaluationContext.distinctId, evaluationContext.groups, personProperties, groupProperties, disableGeoip, flagKeys);
|
|
4974
6759
|
if (details) {
|
|
6760
|
+
this._minimalFlagCalledEvents = details.minimalFlagCalledEvents === true;
|
|
4975
6761
|
requestId = details.requestId;
|
|
4976
6762
|
evaluatedAt = details.evaluatedAt;
|
|
4977
6763
|
errorsWhileComputing = Boolean(details.errorsWhileComputingFlags);
|
|
@@ -4994,7 +6780,8 @@ class PostHogBackendClient extends PostHogCoreStateless {
|
|
|
4994
6780
|
id: detail.metadata?.id,
|
|
4995
6781
|
version: detail.metadata?.version,
|
|
4996
6782
|
reason: detail.reason?.description ?? detail.reason?.code,
|
|
4997
|
-
locallyEvaluated: false
|
|
6783
|
+
locallyEvaluated: false,
|
|
6784
|
+
hasExperiment: detail.metadata?.has_experiment
|
|
4998
6785
|
};
|
|
4999
6786
|
}
|
|
5000
6787
|
}
|
|
@@ -5014,7 +6801,8 @@ class PostHogBackendClient extends PostHogCoreStateless {
|
|
|
5014
6801
|
id: existing?.id,
|
|
5015
6802
|
version: existing?.version,
|
|
5016
6803
|
reason: existing?.reason,
|
|
5017
|
-
locallyEvaluated: existing?.locallyEvaluated ?? false
|
|
6804
|
+
locallyEvaluated: existing?.locallyEvaluated ?? false,
|
|
6805
|
+
hasExperiment: existing?.hasExperiment
|
|
5018
6806
|
};
|
|
5019
6807
|
}
|
|
5020
6808
|
if (this._payloadOverrides !== undefined)
|
|
@@ -5039,6 +6827,9 @@ class PostHogBackendClient extends PostHogCoreStateless {
|
|
|
5039
6827
|
quotaLimited
|
|
5040
6828
|
});
|
|
5041
6829
|
}
|
|
6830
|
+
_shouldSendMinimalFlagCalledEvent(event, properties) {
|
|
6831
|
+
return event === "$feature_flag_called" && this._minimalFlagCalledEvents && properties.$feature_flag_has_experiment === false;
|
|
6832
|
+
}
|
|
5042
6833
|
_captureFlagCalledEventIfNeeded(params) {
|
|
5043
6834
|
const { distinctId, key, response, groups, disableGeoip, properties } = params;
|
|
5044
6835
|
const groupSuffix = groups && Object.keys(groups).length > 0 ? `_${JSON.stringify(Object.entries(groups).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0))}` : "";
|
|
@@ -5073,9 +6864,32 @@ class PostHogBackendClient extends PostHogCoreStateless {
|
|
|
5073
6864
|
return this._featureFlagEvaluationsHost;
|
|
5074
6865
|
}
|
|
5075
6866
|
groupIdentify({ groupType, groupKey, properties, distinctId, disableGeoip }) {
|
|
5076
|
-
|
|
6867
|
+
this._sendPreparedEvent("capture", {
|
|
6868
|
+
distinctId: distinctId || `$${groupType}_${groupKey}`,
|
|
6869
|
+
event: "$groupidentify",
|
|
6870
|
+
properties: {
|
|
6871
|
+
$group_type: groupType,
|
|
6872
|
+
$group_key: groupKey,
|
|
6873
|
+
$group_set: properties || {}
|
|
6874
|
+
},
|
|
6875
|
+
disableGeoip
|
|
6876
|
+
}, false, {
|
|
6877
|
+
includeContextProperties: false
|
|
6878
|
+
});
|
|
6879
|
+
}
|
|
6880
|
+
async groupIdentifyImmediate({ groupType, groupKey, properties, distinctId, disableGeoip }) {
|
|
6881
|
+
await this._sendPreparedEvent("capture", {
|
|
6882
|
+
distinctId: distinctId || `$${groupType}_${groupKey}`,
|
|
6883
|
+
event: "$groupidentify",
|
|
6884
|
+
properties: {
|
|
6885
|
+
$group_type: groupType,
|
|
6886
|
+
$group_key: groupKey,
|
|
6887
|
+
$group_set: properties || {}
|
|
6888
|
+
},
|
|
5077
6889
|
disableGeoip
|
|
5078
|
-
},
|
|
6890
|
+
}, true, {
|
|
6891
|
+
includeContextProperties: false
|
|
6892
|
+
});
|
|
5079
6893
|
}
|
|
5080
6894
|
async reloadFeatureFlags() {
|
|
5081
6895
|
await this.featureFlagsPoller?.loadFeatureFlags(true);
|
|
@@ -5147,12 +6961,18 @@ class PostHogBackendClient extends PostHogCoreStateless {
|
|
|
5147
6961
|
this.context?.enter(data, options);
|
|
5148
6962
|
}
|
|
5149
6963
|
async _shutdown(shutdownTimeoutMs) {
|
|
6964
|
+
const shutdownDeadlineMs = Date.now() + (shutdownTimeoutMs ?? 30000);
|
|
5150
6965
|
const resolve = this._consumeWaitUntilCycle();
|
|
5151
6966
|
await this.featureFlagsPoller?.stopPoller(shutdownTimeoutMs);
|
|
5152
6967
|
this.errorTracking.shutdown();
|
|
6968
|
+
if (this._metrics) {
|
|
6969
|
+
await raceWithTimeout(this._metrics.flush().catch(() => {}), Math.max(0, shutdownDeadlineMs - Date.now()));
|
|
6970
|
+
this._metrics.reset();
|
|
6971
|
+
}
|
|
5153
6972
|
try {
|
|
5154
|
-
return await super._shutdown(
|
|
6973
|
+
return await super._shutdown(Math.max(0, shutdownDeadlineMs - Date.now()));
|
|
5155
6974
|
} finally {
|
|
6975
|
+
this.distinctIdHasSentFlagCalls = {};
|
|
5156
6976
|
resolve?.();
|
|
5157
6977
|
}
|
|
5158
6978
|
}
|
|
@@ -5247,7 +7067,6 @@ class PostHogBackendClient extends PostHogCoreStateless {
|
|
|
5247
7067
|
}
|
|
5248
7068
|
addLocalPersonAndGroupProperties(distinctId, groups, personProperties, groupProperties) {
|
|
5249
7069
|
const allPersonProperties = {
|
|
5250
|
-
distinct_id: distinctId,
|
|
5251
7070
|
...personProperties || {}
|
|
5252
7071
|
};
|
|
5253
7072
|
const allGroupProperties = {};
|
|
@@ -5262,6 +7081,12 @@ class PostHogBackendClient extends PostHogCoreStateless {
|
|
|
5262
7081
|
allGroupProperties
|
|
5263
7082
|
};
|
|
5264
7083
|
}
|
|
7084
|
+
personPropertiesForLocalEvaluation(distinctId, personProperties) {
|
|
7085
|
+
return {
|
|
7086
|
+
distinct_id: distinctId,
|
|
7087
|
+
...personProperties || {}
|
|
7088
|
+
};
|
|
7089
|
+
}
|
|
5265
7090
|
createFeatureFlagEvaluationContext(distinctId, groups, personProperties, groupProperties) {
|
|
5266
7091
|
return {
|
|
5267
7092
|
distinctId,
|
|
@@ -5272,21 +7097,21 @@ class PostHogBackendClient extends PostHogCoreStateless {
|
|
|
5272
7097
|
};
|
|
5273
7098
|
}
|
|
5274
7099
|
captureException(error, distinctId, additionalProperties, uuid, flags) {
|
|
5275
|
-
if (!
|
|
7100
|
+
if (!error_tracking_ErrorTracking.isPreviouslyCapturedError(error)) {
|
|
5276
7101
|
const syntheticException = new Error("PostHog syntheticException");
|
|
5277
|
-
this.addPendingPromise(
|
|
7102
|
+
this.addPendingPromise(error_tracking_ErrorTracking.buildEventMessage(this.getErrorPropertiesBuilder(), error, {
|
|
5278
7103
|
syntheticException
|
|
5279
|
-
}, distinctId, additionalProperties).then((msg) => this.
|
|
7104
|
+
}, distinctId, additionalProperties).then((msg) => this._capturePreparedEvent({
|
|
5280
7105
|
...msg,
|
|
5281
7106
|
uuid,
|
|
5282
7107
|
flags
|
|
5283
|
-
})));
|
|
7108
|
+
}, false)));
|
|
5284
7109
|
}
|
|
5285
7110
|
}
|
|
5286
7111
|
async captureExceptionImmediate(error, distinctId, additionalProperties, flags) {
|
|
5287
|
-
if (!
|
|
7112
|
+
if (!error_tracking_ErrorTracking.isPreviouslyCapturedError(error)) {
|
|
5288
7113
|
const syntheticException = new Error("PostHog syntheticException");
|
|
5289
|
-
return this.addPendingPromise(
|
|
7114
|
+
return this.addPendingPromise(error_tracking_ErrorTracking.buildEventMessage(this.getErrorPropertiesBuilder(), error, {
|
|
5290
7115
|
syntheticException
|
|
5291
7116
|
}, distinctId, additionalProperties).then((msg) => this.captureImmediate({
|
|
5292
7117
|
...msg,
|
|
@@ -5295,24 +7120,31 @@ class PostHogBackendClient extends PostHogCoreStateless {
|
|
|
5295
7120
|
}
|
|
5296
7121
|
}
|
|
5297
7122
|
async prepareEventMessage(props) {
|
|
7123
|
+
return this._prepareEventMessage(props);
|
|
7124
|
+
}
|
|
7125
|
+
async _prepareEventMessage(props, options = {}) {
|
|
5298
7126
|
const { distinctId, event, properties, groups, flags, sendFeatureFlags, timestamp, disableGeoip, uuid } = props;
|
|
5299
7127
|
const contextData = this.context?.get();
|
|
7128
|
+
const includeContextProperties = options.includeContextProperties ?? true;
|
|
5300
7129
|
let mergedDistinctId = distinctId || contextData?.distinctId;
|
|
5301
|
-
const mergedProperties = {
|
|
7130
|
+
const mergedProperties = includeContextProperties ? {
|
|
5302
7131
|
...this.props,
|
|
5303
7132
|
...contextData?.properties || {},
|
|
5304
7133
|
...properties || {}
|
|
7134
|
+
} : {
|
|
7135
|
+
...properties || {}
|
|
5305
7136
|
};
|
|
5306
7137
|
if (!mergedDistinctId) {
|
|
5307
7138
|
mergedDistinctId = uuidv7();
|
|
5308
7139
|
mergedProperties.$process_person_profile = false;
|
|
5309
7140
|
}
|
|
5310
|
-
if (contextData?.sessionId && !mergedProperties.$session_id)
|
|
7141
|
+
if (includeContextProperties && contextData?.sessionId && !mergedProperties.$session_id)
|
|
5311
7142
|
mergedProperties.$session_id = contextData.sessionId;
|
|
7143
|
+
const finalProperties = this._shouldSendMinimalFlagCalledEvent(event, mergedProperties) ? minimizeFlagCalledEventProperties(mergedProperties) : mergedProperties;
|
|
5312
7144
|
const eventMessage = this._runBeforeSend({
|
|
5313
7145
|
distinctId: mergedDistinctId,
|
|
5314
7146
|
event,
|
|
5315
|
-
properties:
|
|
7147
|
+
properties: finalProperties,
|
|
5316
7148
|
groups,
|
|
5317
7149
|
flags,
|
|
5318
7150
|
sendFeatureFlags,
|
|
@@ -5336,12 +7168,14 @@ class PostHogBackendClient extends PostHogCoreStateless {
|
|
|
5336
7168
|
}
|
|
5337
7169
|
return {};
|
|
5338
7170
|
}).catch(() => ({})).then((additionalProperties) => {
|
|
5339
|
-
const
|
|
7171
|
+
const resolvedGroups = eventMessage.groups || groups;
|
|
7172
|
+
return {
|
|
5340
7173
|
...additionalProperties,
|
|
5341
7174
|
...eventMessage.properties || {},
|
|
5342
|
-
|
|
7175
|
+
...resolvedGroups !== undefined && Object.keys(resolvedGroups).length > 0 ? {
|
|
7176
|
+
$groups: resolvedGroups
|
|
7177
|
+
} : {}
|
|
5343
7178
|
};
|
|
5344
|
-
return props2;
|
|
5345
7179
|
});
|
|
5346
7180
|
if (eventMessage.event === "$pageview" && this.options.__preview_capture_bot_pageviews && typeof eventProperties.$raw_user_agent == "string") {
|
|
5347
7181
|
if (isBlockedUA(eventProperties.$raw_user_agent, this.options.custom_blocked_useragents || [])) {
|
|
@@ -5368,22 +7202,26 @@ class PostHogBackendClient extends PostHogCoreStateless {
|
|
|
5368
7202
|
beforeSend
|
|
5369
7203
|
];
|
|
5370
7204
|
let result = eventMessage;
|
|
5371
|
-
for (const fn of fns)
|
|
5372
|
-
|
|
5373
|
-
|
|
5374
|
-
|
|
7205
|
+
for (const fn of fns)
|
|
7206
|
+
try {
|
|
7207
|
+
result = fn(result);
|
|
7208
|
+
if (!result) {
|
|
7209
|
+
this._logger.info(`Event '${eventMessage.event}' was rejected in beforeSend function`);
|
|
7210
|
+
return null;
|
|
7211
|
+
}
|
|
7212
|
+
if (!result.properties || Object.keys(result.properties).length === 0) {
|
|
7213
|
+
const message = `Event '${result.event}' has no properties after beforeSend function, this is likely an error.`;
|
|
7214
|
+
this._logger.warn(message);
|
|
7215
|
+
}
|
|
7216
|
+
} catch (error) {
|
|
7217
|
+
this._logger.error(`Error in before_send function for event '${eventMessage.event}':`, error);
|
|
5375
7218
|
return null;
|
|
5376
7219
|
}
|
|
5377
|
-
if (!result.properties || Object.keys(result.properties).length === 0) {
|
|
5378
|
-
const message = `Event '${result.event}' has no properties after beforeSend function, this is likely an error.`;
|
|
5379
|
-
this._logger.warn(message);
|
|
5380
|
-
}
|
|
5381
|
-
}
|
|
5382
7220
|
return result;
|
|
5383
7221
|
}
|
|
5384
7222
|
}
|
|
5385
7223
|
|
|
5386
|
-
// ../../../node_modules/.bun/posthog-node@5.
|
|
7224
|
+
// ../../../node_modules/.bun/posthog-node@5.49.2/node_modules/posthog-node/dist/extensions/context/context.mjs
|
|
5387
7225
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
5388
7226
|
|
|
5389
7227
|
class PostHogContext {
|
|
@@ -5414,7 +7252,24 @@ class PostHogContext {
|
|
|
5414
7252
|
}
|
|
5415
7253
|
}
|
|
5416
7254
|
|
|
5417
|
-
// ../../../node_modules/.bun/posthog-node@5.
|
|
7255
|
+
// ../../../node_modules/.bun/posthog-node@5.49.2/node_modules/posthog-node/dist/gzip.node.mjs
|
|
7256
|
+
import { gzip } from "node:zlib";
|
|
7257
|
+
import { promisify } from "node:util";
|
|
7258
|
+
var gzipAsync = promisify(gzip);
|
|
7259
|
+
async function gzipCompress2(input, isDebug = true) {
|
|
7260
|
+
try {
|
|
7261
|
+
const compressed = await gzipAsync(input);
|
|
7262
|
+
return new Blob([
|
|
7263
|
+
new Uint8Array(compressed)
|
|
7264
|
+
]);
|
|
7265
|
+
} catch (error) {
|
|
7266
|
+
if (isDebug)
|
|
7267
|
+
console.error("Failed to gzip compress data", error);
|
|
7268
|
+
return null;
|
|
7269
|
+
}
|
|
7270
|
+
}
|
|
7271
|
+
|
|
7272
|
+
// ../../../node_modules/.bun/posthog-node@5.49.2/node_modules/posthog-node/dist/extensions/sentry-integration.mjs
|
|
5418
7273
|
var NAME = "posthog-node";
|
|
5419
7274
|
function createEventProcessor(_posthog, { organization, projectId, prefix, severityAllowList = [
|
|
5420
7275
|
"error"
|
|
@@ -5454,6 +7309,9 @@ function createEventProcessor(_posthog, { organization, projectId, prefix, sever
|
|
|
5454
7309
|
$sentry_exception_type: exceptions[0]?.type,
|
|
5455
7310
|
$sentry_tags: event.tags
|
|
5456
7311
|
};
|
|
7312
|
+
const injectedReleaseId = exports_error_tracking.getInjectedReleaseId();
|
|
7313
|
+
if (injectedReleaseId)
|
|
7314
|
+
properties.$release_id = injectedReleaseId;
|
|
5457
7315
|
if (organization && projectId)
|
|
5458
7316
|
properties["$sentry_url"] = (prefix || "https://sentry.io/organizations/") + organization + "/issues/?project=" + projectId + "&query=" + event.event_id;
|
|
5459
7317
|
if (sendExceptionsToPostHog)
|
|
@@ -5482,11 +7340,14 @@ class PostHogSentryIntegration {
|
|
|
5482
7340
|
};
|
|
5483
7341
|
}
|
|
5484
7342
|
}
|
|
5485
|
-
// ../../../node_modules/.bun/posthog-node@5.
|
|
7343
|
+
// ../../../node_modules/.bun/posthog-node@5.49.2/node_modules/posthog-node/dist/entrypoints/index.node.mjs
|
|
5486
7344
|
class PostHog extends PostHogBackendClient {
|
|
5487
7345
|
getLibraryId() {
|
|
5488
7346
|
return "posthog-node";
|
|
5489
7347
|
}
|
|
7348
|
+
compressPayload(payload) {
|
|
7349
|
+
return gzipCompress2(payload, this.isDebug);
|
|
7350
|
+
}
|
|
5490
7351
|
initializeContext() {
|
|
5491
7352
|
return new PostHogContext;
|
|
5492
7353
|
}
|
|
@@ -5499,7 +7360,7 @@ class PostHog extends PostHogBackendClient {
|
|
|
5499
7360
|
new exports_error_tracking.PrimitiveCoercer
|
|
5500
7361
|
], exports_error_tracking.createStackParser("node:javascript", exports_error_tracking.nodeStackLineParser), [
|
|
5501
7362
|
createModulerModifier(),
|
|
5502
|
-
addSourceContext,
|
|
7363
|
+
(frames) => addSourceContext(frames, undefined, this._logger),
|
|
5503
7364
|
createRelativePathModifier()
|
|
5504
7365
|
]);
|
|
5505
7366
|
}
|
|
@@ -5884,12 +7745,12 @@ function parseHookInput(raw) {
|
|
|
5884
7745
|
}
|
|
5885
7746
|
}
|
|
5886
7747
|
function isCodexSessionStartInput(value) {
|
|
5887
|
-
return
|
|
7748
|
+
return isRecord3(value) && value["hook_event_name"] === "SessionStart" && typeof value["session_id"] === "string" && isStringOrNull(value["transcript_path"]) && typeof value["cwd"] === "string" && typeof value["model"] === "string" && typeof value["permission_mode"] === "string" && typeof value["source"] === "string";
|
|
5888
7749
|
}
|
|
5889
7750
|
function isStringOrNull(value) {
|
|
5890
7751
|
return typeof value === "string" || value === null;
|
|
5891
7752
|
}
|
|
5892
|
-
function
|
|
7753
|
+
function isRecord3(value) {
|
|
5893
7754
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
5894
7755
|
}
|
|
5895
7756
|
function readStdin() {
|