@mushi-mushi/core 1.27.2 → 1.28.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -1
- package/dist/index.cjs +168 -15
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +122 -1
- package/dist/index.d.ts +122 -1
- package/dist/index.js +155 -16
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.cts
CHANGED
|
@@ -46,6 +46,31 @@ interface MushiConfig {
|
|
|
46
46
|
* when omitted (legacy Vercel Analytics wiring).
|
|
47
47
|
*/
|
|
48
48
|
appVersion?: string;
|
|
49
|
+
/**
|
|
50
|
+
* Same-origin (or absolute) ingest proxy. When set, every SDK HTTP call
|
|
51
|
+
* goes here instead of `apiEndpoint` so ad blockers that drop third-party
|
|
52
|
+
* `*.supabase.co/functions` hosts cannot silently eat reports.
|
|
53
|
+
* Relative URLs resolve against the page origin — that is the recommended
|
|
54
|
+
* form (no CORS preflight; matches Sentry `tunnel`).
|
|
55
|
+
*
|
|
56
|
+
* @example
|
|
57
|
+
* tunnel: '/api/mushi-tunnel'
|
|
58
|
+
*/
|
|
59
|
+
tunnel?: string;
|
|
60
|
+
/**
|
|
61
|
+
* Drop automatic error reports whose message matches any string (substring)
|
|
62
|
+
* or RegExp. Never applied to user-submitted widget feedback.
|
|
63
|
+
*/
|
|
64
|
+
ignoreErrors?: Array<string | RegExp>;
|
|
65
|
+
/**
|
|
66
|
+
* Drop automatic error reports whose script URL / stack filename matches.
|
|
67
|
+
*/
|
|
68
|
+
denyUrls?: Array<string | RegExp>;
|
|
69
|
+
/**
|
|
70
|
+
* When set, drop automatic error reports unless the script URL matches
|
|
71
|
+
* at least one entry.
|
|
72
|
+
*/
|
|
73
|
+
allowUrls?: Array<string | RegExp>;
|
|
49
74
|
/**
|
|
50
75
|
* Probabilistic sampling rate for session-replay recording (rrweb/lite).
|
|
51
76
|
* Range 0–1, default 1 (record all sessions). The sampling decision is made
|
|
@@ -59,6 +84,13 @@ interface MushiConfig {
|
|
|
59
84
|
* replaySampleRate: 0.2 // record replay for ~20% of sessions
|
|
60
85
|
*/
|
|
61
86
|
replaySampleRate?: number;
|
|
87
|
+
/**
|
|
88
|
+
* When session replay was sampled out, still start the rolling buffer for
|
|
89
|
+
* this fraction of sessions (0–1, default 0) so an error/feedback report
|
|
90
|
+
* can attach replay. Keep at 0 unless you have accepted the CPU/egress
|
|
91
|
+
* cost — do not set to 1 with `capture.replay: 'rrweb'`.
|
|
92
|
+
*/
|
|
93
|
+
replaysOnErrorSampleRate?: number;
|
|
62
94
|
/**
|
|
63
95
|
* Probabilistic sampling rate for automatic (non-user-initiated) error
|
|
64
96
|
* reports. Range 0–1, default 1 (send all). User-initiated feedback reports
|
|
@@ -1711,6 +1743,8 @@ interface MushiTesterReputation {
|
|
|
1711
1743
|
total_points: number;
|
|
1712
1744
|
}
|
|
1713
1745
|
|
|
1746
|
+
/** Replay the last POST via keepalive/beacon during pagehide. */
|
|
1747
|
+
declare function flushLastOutboundOnUnload(): boolean;
|
|
1714
1748
|
/** Header carrying the signed end-user identity token (verified server-side). */
|
|
1715
1749
|
declare const MUSHI_USER_TOKEN_HEADER = "X-Mushi-User-Token";
|
|
1716
1750
|
/** Project scope header — paired with the API key on every SDK request. */
|
|
@@ -1759,14 +1793,101 @@ interface ApiClientOptions {
|
|
|
1759
1793
|
* backend can verify it and scope identity-bound features to that user.
|
|
1760
1794
|
*/
|
|
1761
1795
|
getUserToken?: () => string | null | undefined;
|
|
1796
|
+
/**
|
|
1797
|
+
* Same-origin (or absolute) proxy. When set, replaces `apiEndpoint` as the
|
|
1798
|
+
* request base so browser calls stay first-party. See `MushiConfig.tunnel`.
|
|
1799
|
+
*/
|
|
1800
|
+
tunnel?: string;
|
|
1762
1801
|
}
|
|
1763
1802
|
declare const DEFAULT_API_ENDPOINT = "https://dxptnwrhwsqckaftyymj.supabase.co/functions/v1/api";
|
|
1764
1803
|
declare const MUSHI_INTERNAL_HEADER = "X-Mushi-Internal";
|
|
1765
1804
|
declare const MUSHI_INTERNAL_INIT_MARKER = "__mushiInternal";
|
|
1766
1805
|
type MushiInternalRequestKind = 'sdk-config' | 'report-submit' | 'report-status' | 'reporter-poll' | 'diagnose' | 'discovery' | 'community';
|
|
1806
|
+
/** Resolve the HTTP base: tunnel wins so ingest stays first-party. */
|
|
1807
|
+
declare function resolveRequestBaseUrl(apiEndpoint: string | undefined, tunnel?: string): string;
|
|
1767
1808
|
declare const DEFAULT_TIMEOUT = 10000;
|
|
1768
1809
|
declare const DEFAULT_MAX_RETRIES = 2;
|
|
1769
1810
|
declare function createApiClient(options: ApiClientOptions): MushiApiClient;
|
|
1811
|
+
declare function getBackoffDelay(attempt: number): number;
|
|
1812
|
+
/**
|
|
1813
|
+
* Parse a `Retry-After` header into a delay in milliseconds. The header comes
|
|
1814
|
+
* in two shapes (RFC 9110): delta-seconds, or an HTTP-date to wait until.
|
|
1815
|
+
* Returns null when the header is absent, malformed, or negative, so the
|
|
1816
|
+
* caller falls back to its own backoff curve.
|
|
1817
|
+
*/
|
|
1818
|
+
declare function parseRetryAfter(value: string | null | undefined, now?: number): number | null;
|
|
1819
|
+
|
|
1820
|
+
/**
|
|
1821
|
+
* FILE: packages/core/src/error-filters.ts
|
|
1822
|
+
* PURPOSE: Sentry-grade drop filters for automatic error capture.
|
|
1823
|
+
*
|
|
1824
|
+
* OVERVIEW:
|
|
1825
|
+
* - ignoreErrors — drop when the error message matches a string or RegExp
|
|
1826
|
+
* - denyUrls — drop when the script URL / stack frame matches
|
|
1827
|
+
* - allowUrls — when set, drop unless the script URL matches at least one
|
|
1828
|
+
*
|
|
1829
|
+
* USAGE:
|
|
1830
|
+
* - captureException / window.onerror / unhandledrejection only
|
|
1831
|
+
* - Never applied to user-submitted widget feedback
|
|
1832
|
+
*
|
|
1833
|
+
* NOTES:
|
|
1834
|
+
* - String matchers are case-sensitive substrings (Sentry JS semantics)
|
|
1835
|
+
* - Invalid RegExp sources are treated as non-matches, not throws
|
|
1836
|
+
*/
|
|
1837
|
+
type MushiErrorFilter = string | RegExp;
|
|
1838
|
+
declare function matchesErrorFilter(value: string | undefined | null, filters: readonly MushiErrorFilter[] | undefined): boolean;
|
|
1839
|
+
declare function shouldDropCapturedError(input: {
|
|
1840
|
+
message: string;
|
|
1841
|
+
filename?: string | null;
|
|
1842
|
+
ignoreErrors?: readonly MushiErrorFilter[];
|
|
1843
|
+
denyUrls?: readonly MushiErrorFilter[];
|
|
1844
|
+
allowUrls?: readonly MushiErrorFilter[];
|
|
1845
|
+
}): boolean;
|
|
1846
|
+
|
|
1847
|
+
/**
|
|
1848
|
+
* FILE: packages/core/src/unload-transport.ts
|
|
1849
|
+
* PURPOSE: Pagehide-safe report delivery (fetch keepalive + sendBeacon).
|
|
1850
|
+
*
|
|
1851
|
+
* OVERVIEW:
|
|
1852
|
+
* - fetch({ keepalive: true }) keeps custom X-Mushi-* headers (Sentry 2024+ primary)
|
|
1853
|
+
* - sendBeacon cannot set headers, so it wraps credentials in a beacon envelope
|
|
1854
|
+
* that only the same-origin tunnel unwraps
|
|
1855
|
+
*
|
|
1856
|
+
* NOTES:
|
|
1857
|
+
* - Beacon payloads over 60 KiB are skipped (browser sendBeacon limit ~64 KiB)
|
|
1858
|
+
* - Never put the API key in the query string
|
|
1859
|
+
*/
|
|
1860
|
+
declare const MUSHI_BEACON_MAX_BYTES: number;
|
|
1861
|
+
interface MushiBeaconEnvelope {
|
|
1862
|
+
mushiBeacon: true;
|
|
1863
|
+
path: string;
|
|
1864
|
+
headers: Record<string, string>;
|
|
1865
|
+
body: unknown;
|
|
1866
|
+
}
|
|
1867
|
+
declare function isMushiBeaconEnvelope(value: unknown): value is MushiBeaconEnvelope;
|
|
1868
|
+
declare function buildBeaconEnvelope(opts: {
|
|
1869
|
+
path: string;
|
|
1870
|
+
headers: Record<string, string>;
|
|
1871
|
+
body: unknown;
|
|
1872
|
+
}): MushiBeaconEnvelope;
|
|
1873
|
+
/** True when the URL is same-origin or relative (safe for sendBeacon + tunnel). */
|
|
1874
|
+
declare function isSameOriginOrRelative(url: string, origin?: string): boolean;
|
|
1875
|
+
declare function extractTunnelPath(url: string): string;
|
|
1876
|
+
interface SendOnUnloadOptions {
|
|
1877
|
+
url: string;
|
|
1878
|
+
headers: Record<string, string>;
|
|
1879
|
+
body: string;
|
|
1880
|
+
path?: string;
|
|
1881
|
+
fetchImpl?: typeof fetch;
|
|
1882
|
+
sendBeacon?: (url: string, data: Blob) => boolean;
|
|
1883
|
+
}
|
|
1884
|
+
/**
|
|
1885
|
+
* Deliver one JSON POST during pagehide. Prefers fetch keepalive (headers).
|
|
1886
|
+
* Falls back to sendBeacon with a credential envelope on same-origin URLs.
|
|
1887
|
+
*/
|
|
1888
|
+
declare function sendOnUnload(opts: SendOnUnloadOptions): boolean;
|
|
1889
|
+
declare function markPageUnloading(): void;
|
|
1890
|
+
declare function isPageUnloading(): boolean;
|
|
1770
1891
|
|
|
1771
1892
|
/**
|
|
1772
1893
|
* C7: Data residency region resolution.
|
|
@@ -2632,4 +2753,4 @@ declare function projectInitialsThemeIndex(projectId: string): number;
|
|
|
2632
2753
|
*/
|
|
2633
2754
|
declare function readPageFaviconHref(): string | null;
|
|
2634
2755
|
|
|
2635
|
-
export { type ApiClientOptions, type BreadcrumbBuffer, type BreadcrumbBufferOptions, DEFAULT_API_ENDPOINT, DEFAULT_MAX_RETRIES, DEFAULT_TIMEOUT, type EnvConfigDiagnostics, type EnvNearMiss, type LogEntry, type LogFormat, type LogLevel, type Logger, type LoggerOptions, MAX_REPORT_PAYLOAD_BYTES, MAX_SCREENSHOT_DATA_URL_BYTES, MUSHI_ACCENT_SHADOW, MUSHI_BANNER_BRAND_BORDER, MUSHI_BANNER_NEON, MUSHI_BORDER, MUSHI_COLORS_DARK, MUSHI_COLORS_LIGHT, MUSHI_CONTROL_DISABLED, MUSHI_COPY, MUSHI_DURATION, MUSHI_GEOMETRY, MUSHI_IDENTITY_TOKEN_PREFIX, MUSHI_INTERNAL_HEADER, MUSHI_INTERNAL_INIT_MARKER, MUSHI_INVERSE, MUSHI_LETTER_SPACING, MUSHI_MOTION, MUSHI_ON_ACCENT, MUSHI_OPACITY, MUSHI_PROJECT_HEADER, MUSHI_RADIUS, MUSHI_REPORTER_STATUS, MUSHI_SDK_PACKAGE_HEADER, MUSHI_SDK_VERSION_HEADER, MUSHI_SHADOW_INK, MUSHI_SPACING, MUSHI_TIER_COLORS, MUSHI_TYPE, MUSHI_USER_TOKEN_HEADER, MUSHI_Z, type MushiActivityEvent, type MushiApiCascadeConfig, type MushiApiClient, type MushiApiResponse, type MushiAssistantConfig, type MushiAssistantReply, type MushiAssistantStep, type MushiBannerConfig, type MushiBannerLink, type MushiBetaChangelogEntry, type MushiBetaModeConfig, type MushiBreadcrumb, type MushiCaptureConfig, type MushiCaptureEventInput, type MushiCaptureExceptionOptions, type MushiColorPalette, type MushiConfig, type MushiConsoleEntry, type MushiCooldownConfig, type MushiCrossAppReport, type MushiCustomCategory, type MushiDiagnosticsResult, type MushiDiscoverInventoryConfig, type MushiDiscoveryEventPayload, type MushiEnvironment, type MushiEventHandler, type MushiEventType, type MushiHallOfFameEntry, type MushiIdentityClaims, type MushiIntegrationsConfig, type MushiInternalRequestKind, type MushiLeaderboardEntry, type MushiNetworkEntry, type MushiOfflineConfig, type MushiOnDeviceClassifier, type MushiOnDeviceClassifierInput, type MushiOnDeviceClassifierResult, type MushiPageContext, type MushiPerformanceMetrics, type MushiPreFilterConfig, type MushiPreset, type MushiPrivacyConfig, type MushiProactiveConfig, type MushiRegion, type MushiReport, type MushiReportBuilder, type MushiReportCategory, type MushiReportStatus, type MushiReporterComment, type MushiReporterReport, type MushiReputationResult, type MushiRewardsConfig, type MushiRuntimeSdkConfig, type MushiSDKInstance, type MushiSdkVersionInfo, type MushiSelectedElement, type MushiSentryConfig, type MushiSentryContext, type MushiSessionEventPayload, type MushiTesterReputation, type MushiThemeMode, type MushiTierResult, type MushiTimelineEntry, type MushiTimelineKind, type MushiTokenSnapshot, type MushiTracePropagationConfig, type MushiUrlMatcher, type MushiWidgetAnchor, type MushiWidgetConfig, type NormalisedException, type OfflineQueue, type PayloadGuardResult, type PiiScrubberConfig, type PreFilterResult, type ProjectFaviconSource, REGION_ENDPOINTS, type RateLimiter, type RateLimiterConfig, type ResolvedEnvConfig, type SessionTrackerOptions, buildIdentityClaims, buildSdkIngestHeaders, captureEnvironment, checkReportPayloadSize, createApiClient, createBreadcrumbBuffer, createLogger, createOfflineQueue, createPiiScrubber, createPreFilter, createRateLimiter, destroySessionTracker, diagnoseEnvConfig, estimateJsonBytes, expandPreset, faviconUrlCandidates, formatBytes, getDeviceFingerprintHash, getReporterToken, getSessionId, githubRepoDomainHint, hmacSha256Hex, initSessionTracker, isLikelyGenericFavicon, isUntrustedFaviconUrl, mushiPalette, mushiTokens, newUuid, noopLogger, normaliseThrown, originToDomain, parseIdentityToken, projectFaviconUrlCandidates, projectInitials, projectInitialsThemeIndex, readPageFaviconHref, resolveEnvConfig, resolveProjectDomain, resolveProjectFaviconDomains, resolveRegionEndpoint, resolveWidgetAccent, safeWidgetHex, scrubPii, scrubUrl, sha256Hex, trackPageView, updateSessionIdentity, validateConfig };
|
|
2756
|
+
export { type ApiClientOptions, type BreadcrumbBuffer, type BreadcrumbBufferOptions, DEFAULT_API_ENDPOINT, DEFAULT_MAX_RETRIES, DEFAULT_TIMEOUT, type EnvConfigDiagnostics, type EnvNearMiss, type LogEntry, type LogFormat, type LogLevel, type Logger, type LoggerOptions, MAX_REPORT_PAYLOAD_BYTES, MAX_SCREENSHOT_DATA_URL_BYTES, MUSHI_ACCENT_SHADOW, MUSHI_BANNER_BRAND_BORDER, MUSHI_BANNER_NEON, MUSHI_BEACON_MAX_BYTES, MUSHI_BORDER, MUSHI_COLORS_DARK, MUSHI_COLORS_LIGHT, MUSHI_CONTROL_DISABLED, MUSHI_COPY, MUSHI_DURATION, MUSHI_GEOMETRY, MUSHI_IDENTITY_TOKEN_PREFIX, MUSHI_INTERNAL_HEADER, MUSHI_INTERNAL_INIT_MARKER, MUSHI_INVERSE, MUSHI_LETTER_SPACING, MUSHI_MOTION, MUSHI_ON_ACCENT, MUSHI_OPACITY, MUSHI_PROJECT_HEADER, MUSHI_RADIUS, MUSHI_REPORTER_STATUS, MUSHI_SDK_PACKAGE_HEADER, MUSHI_SDK_VERSION_HEADER, MUSHI_SHADOW_INK, MUSHI_SPACING, MUSHI_TIER_COLORS, MUSHI_TYPE, MUSHI_USER_TOKEN_HEADER, MUSHI_Z, type MushiActivityEvent, type MushiApiCascadeConfig, type MushiApiClient, type MushiApiResponse, type MushiAssistantConfig, type MushiAssistantReply, type MushiAssistantStep, type MushiBannerConfig, type MushiBannerLink, type MushiBeaconEnvelope, type MushiBetaChangelogEntry, type MushiBetaModeConfig, type MushiBreadcrumb, type MushiCaptureConfig, type MushiCaptureEventInput, type MushiCaptureExceptionOptions, type MushiColorPalette, type MushiConfig, type MushiConsoleEntry, type MushiCooldownConfig, type MushiCrossAppReport, type MushiCustomCategory, type MushiDiagnosticsResult, type MushiDiscoverInventoryConfig, type MushiDiscoveryEventPayload, type MushiEnvironment, type MushiErrorFilter, type MushiEventHandler, type MushiEventType, type MushiHallOfFameEntry, type MushiIdentityClaims, type MushiIntegrationsConfig, type MushiInternalRequestKind, type MushiLeaderboardEntry, type MushiNetworkEntry, type MushiOfflineConfig, type MushiOnDeviceClassifier, type MushiOnDeviceClassifierInput, type MushiOnDeviceClassifierResult, type MushiPageContext, type MushiPerformanceMetrics, type MushiPreFilterConfig, type MushiPreset, type MushiPrivacyConfig, type MushiProactiveConfig, type MushiRegion, type MushiReport, type MushiReportBuilder, type MushiReportCategory, type MushiReportStatus, type MushiReporterComment, type MushiReporterReport, type MushiReputationResult, type MushiRewardsConfig, type MushiRuntimeSdkConfig, type MushiSDKInstance, type MushiSdkVersionInfo, type MushiSelectedElement, type MushiSentryConfig, type MushiSentryContext, type MushiSessionEventPayload, type MushiTesterReputation, type MushiThemeMode, type MushiTierResult, type MushiTimelineEntry, type MushiTimelineKind, type MushiTokenSnapshot, type MushiTracePropagationConfig, type MushiUrlMatcher, type MushiWidgetAnchor, type MushiWidgetConfig, type NormalisedException, type OfflineQueue, type PayloadGuardResult, type PiiScrubberConfig, type PreFilterResult, type ProjectFaviconSource, REGION_ENDPOINTS, type RateLimiter, type RateLimiterConfig, type ResolvedEnvConfig, type SessionTrackerOptions, buildBeaconEnvelope, buildIdentityClaims, buildSdkIngestHeaders, captureEnvironment, checkReportPayloadSize, createApiClient, createBreadcrumbBuffer, createLogger, createOfflineQueue, createPiiScrubber, createPreFilter, createRateLimiter, destroySessionTracker, diagnoseEnvConfig, estimateJsonBytes, expandPreset, extractTunnelPath, faviconUrlCandidates, flushLastOutboundOnUnload, formatBytes, getBackoffDelay, getDeviceFingerprintHash, getReporterToken, getSessionId, githubRepoDomainHint, hmacSha256Hex, initSessionTracker, isLikelyGenericFavicon, isMushiBeaconEnvelope, isPageUnloading, isSameOriginOrRelative, isUntrustedFaviconUrl, markPageUnloading, matchesErrorFilter, mushiPalette, mushiTokens, newUuid, noopLogger, normaliseThrown, originToDomain, parseIdentityToken, parseRetryAfter, projectFaviconUrlCandidates, projectInitials, projectInitialsThemeIndex, readPageFaviconHref, resolveEnvConfig, resolveProjectDomain, resolveProjectFaviconDomains, resolveRegionEndpoint, resolveRequestBaseUrl, resolveWidgetAccent, safeWidgetHex, scrubPii, scrubUrl, sendOnUnload, sha256Hex, shouldDropCapturedError, trackPageView, updateSessionIdentity, validateConfig };
|
package/dist/index.d.ts
CHANGED
|
@@ -46,6 +46,31 @@ interface MushiConfig {
|
|
|
46
46
|
* when omitted (legacy Vercel Analytics wiring).
|
|
47
47
|
*/
|
|
48
48
|
appVersion?: string;
|
|
49
|
+
/**
|
|
50
|
+
* Same-origin (or absolute) ingest proxy. When set, every SDK HTTP call
|
|
51
|
+
* goes here instead of `apiEndpoint` so ad blockers that drop third-party
|
|
52
|
+
* `*.supabase.co/functions` hosts cannot silently eat reports.
|
|
53
|
+
* Relative URLs resolve against the page origin — that is the recommended
|
|
54
|
+
* form (no CORS preflight; matches Sentry `tunnel`).
|
|
55
|
+
*
|
|
56
|
+
* @example
|
|
57
|
+
* tunnel: '/api/mushi-tunnel'
|
|
58
|
+
*/
|
|
59
|
+
tunnel?: string;
|
|
60
|
+
/**
|
|
61
|
+
* Drop automatic error reports whose message matches any string (substring)
|
|
62
|
+
* or RegExp. Never applied to user-submitted widget feedback.
|
|
63
|
+
*/
|
|
64
|
+
ignoreErrors?: Array<string | RegExp>;
|
|
65
|
+
/**
|
|
66
|
+
* Drop automatic error reports whose script URL / stack filename matches.
|
|
67
|
+
*/
|
|
68
|
+
denyUrls?: Array<string | RegExp>;
|
|
69
|
+
/**
|
|
70
|
+
* When set, drop automatic error reports unless the script URL matches
|
|
71
|
+
* at least one entry.
|
|
72
|
+
*/
|
|
73
|
+
allowUrls?: Array<string | RegExp>;
|
|
49
74
|
/**
|
|
50
75
|
* Probabilistic sampling rate for session-replay recording (rrweb/lite).
|
|
51
76
|
* Range 0–1, default 1 (record all sessions). The sampling decision is made
|
|
@@ -59,6 +84,13 @@ interface MushiConfig {
|
|
|
59
84
|
* replaySampleRate: 0.2 // record replay for ~20% of sessions
|
|
60
85
|
*/
|
|
61
86
|
replaySampleRate?: number;
|
|
87
|
+
/**
|
|
88
|
+
* When session replay was sampled out, still start the rolling buffer for
|
|
89
|
+
* this fraction of sessions (0–1, default 0) so an error/feedback report
|
|
90
|
+
* can attach replay. Keep at 0 unless you have accepted the CPU/egress
|
|
91
|
+
* cost — do not set to 1 with `capture.replay: 'rrweb'`.
|
|
92
|
+
*/
|
|
93
|
+
replaysOnErrorSampleRate?: number;
|
|
62
94
|
/**
|
|
63
95
|
* Probabilistic sampling rate for automatic (non-user-initiated) error
|
|
64
96
|
* reports. Range 0–1, default 1 (send all). User-initiated feedback reports
|
|
@@ -1711,6 +1743,8 @@ interface MushiTesterReputation {
|
|
|
1711
1743
|
total_points: number;
|
|
1712
1744
|
}
|
|
1713
1745
|
|
|
1746
|
+
/** Replay the last POST via keepalive/beacon during pagehide. */
|
|
1747
|
+
declare function flushLastOutboundOnUnload(): boolean;
|
|
1714
1748
|
/** Header carrying the signed end-user identity token (verified server-side). */
|
|
1715
1749
|
declare const MUSHI_USER_TOKEN_HEADER = "X-Mushi-User-Token";
|
|
1716
1750
|
/** Project scope header — paired with the API key on every SDK request. */
|
|
@@ -1759,14 +1793,101 @@ interface ApiClientOptions {
|
|
|
1759
1793
|
* backend can verify it and scope identity-bound features to that user.
|
|
1760
1794
|
*/
|
|
1761
1795
|
getUserToken?: () => string | null | undefined;
|
|
1796
|
+
/**
|
|
1797
|
+
* Same-origin (or absolute) proxy. When set, replaces `apiEndpoint` as the
|
|
1798
|
+
* request base so browser calls stay first-party. See `MushiConfig.tunnel`.
|
|
1799
|
+
*/
|
|
1800
|
+
tunnel?: string;
|
|
1762
1801
|
}
|
|
1763
1802
|
declare const DEFAULT_API_ENDPOINT = "https://dxptnwrhwsqckaftyymj.supabase.co/functions/v1/api";
|
|
1764
1803
|
declare const MUSHI_INTERNAL_HEADER = "X-Mushi-Internal";
|
|
1765
1804
|
declare const MUSHI_INTERNAL_INIT_MARKER = "__mushiInternal";
|
|
1766
1805
|
type MushiInternalRequestKind = 'sdk-config' | 'report-submit' | 'report-status' | 'reporter-poll' | 'diagnose' | 'discovery' | 'community';
|
|
1806
|
+
/** Resolve the HTTP base: tunnel wins so ingest stays first-party. */
|
|
1807
|
+
declare function resolveRequestBaseUrl(apiEndpoint: string | undefined, tunnel?: string): string;
|
|
1767
1808
|
declare const DEFAULT_TIMEOUT = 10000;
|
|
1768
1809
|
declare const DEFAULT_MAX_RETRIES = 2;
|
|
1769
1810
|
declare function createApiClient(options: ApiClientOptions): MushiApiClient;
|
|
1811
|
+
declare function getBackoffDelay(attempt: number): number;
|
|
1812
|
+
/**
|
|
1813
|
+
* Parse a `Retry-After` header into a delay in milliseconds. The header comes
|
|
1814
|
+
* in two shapes (RFC 9110): delta-seconds, or an HTTP-date to wait until.
|
|
1815
|
+
* Returns null when the header is absent, malformed, or negative, so the
|
|
1816
|
+
* caller falls back to its own backoff curve.
|
|
1817
|
+
*/
|
|
1818
|
+
declare function parseRetryAfter(value: string | null | undefined, now?: number): number | null;
|
|
1819
|
+
|
|
1820
|
+
/**
|
|
1821
|
+
* FILE: packages/core/src/error-filters.ts
|
|
1822
|
+
* PURPOSE: Sentry-grade drop filters for automatic error capture.
|
|
1823
|
+
*
|
|
1824
|
+
* OVERVIEW:
|
|
1825
|
+
* - ignoreErrors — drop when the error message matches a string or RegExp
|
|
1826
|
+
* - denyUrls — drop when the script URL / stack frame matches
|
|
1827
|
+
* - allowUrls — when set, drop unless the script URL matches at least one
|
|
1828
|
+
*
|
|
1829
|
+
* USAGE:
|
|
1830
|
+
* - captureException / window.onerror / unhandledrejection only
|
|
1831
|
+
* - Never applied to user-submitted widget feedback
|
|
1832
|
+
*
|
|
1833
|
+
* NOTES:
|
|
1834
|
+
* - String matchers are case-sensitive substrings (Sentry JS semantics)
|
|
1835
|
+
* - Invalid RegExp sources are treated as non-matches, not throws
|
|
1836
|
+
*/
|
|
1837
|
+
type MushiErrorFilter = string | RegExp;
|
|
1838
|
+
declare function matchesErrorFilter(value: string | undefined | null, filters: readonly MushiErrorFilter[] | undefined): boolean;
|
|
1839
|
+
declare function shouldDropCapturedError(input: {
|
|
1840
|
+
message: string;
|
|
1841
|
+
filename?: string | null;
|
|
1842
|
+
ignoreErrors?: readonly MushiErrorFilter[];
|
|
1843
|
+
denyUrls?: readonly MushiErrorFilter[];
|
|
1844
|
+
allowUrls?: readonly MushiErrorFilter[];
|
|
1845
|
+
}): boolean;
|
|
1846
|
+
|
|
1847
|
+
/**
|
|
1848
|
+
* FILE: packages/core/src/unload-transport.ts
|
|
1849
|
+
* PURPOSE: Pagehide-safe report delivery (fetch keepalive + sendBeacon).
|
|
1850
|
+
*
|
|
1851
|
+
* OVERVIEW:
|
|
1852
|
+
* - fetch({ keepalive: true }) keeps custom X-Mushi-* headers (Sentry 2024+ primary)
|
|
1853
|
+
* - sendBeacon cannot set headers, so it wraps credentials in a beacon envelope
|
|
1854
|
+
* that only the same-origin tunnel unwraps
|
|
1855
|
+
*
|
|
1856
|
+
* NOTES:
|
|
1857
|
+
* - Beacon payloads over 60 KiB are skipped (browser sendBeacon limit ~64 KiB)
|
|
1858
|
+
* - Never put the API key in the query string
|
|
1859
|
+
*/
|
|
1860
|
+
declare const MUSHI_BEACON_MAX_BYTES: number;
|
|
1861
|
+
interface MushiBeaconEnvelope {
|
|
1862
|
+
mushiBeacon: true;
|
|
1863
|
+
path: string;
|
|
1864
|
+
headers: Record<string, string>;
|
|
1865
|
+
body: unknown;
|
|
1866
|
+
}
|
|
1867
|
+
declare function isMushiBeaconEnvelope(value: unknown): value is MushiBeaconEnvelope;
|
|
1868
|
+
declare function buildBeaconEnvelope(opts: {
|
|
1869
|
+
path: string;
|
|
1870
|
+
headers: Record<string, string>;
|
|
1871
|
+
body: unknown;
|
|
1872
|
+
}): MushiBeaconEnvelope;
|
|
1873
|
+
/** True when the URL is same-origin or relative (safe for sendBeacon + tunnel). */
|
|
1874
|
+
declare function isSameOriginOrRelative(url: string, origin?: string): boolean;
|
|
1875
|
+
declare function extractTunnelPath(url: string): string;
|
|
1876
|
+
interface SendOnUnloadOptions {
|
|
1877
|
+
url: string;
|
|
1878
|
+
headers: Record<string, string>;
|
|
1879
|
+
body: string;
|
|
1880
|
+
path?: string;
|
|
1881
|
+
fetchImpl?: typeof fetch;
|
|
1882
|
+
sendBeacon?: (url: string, data: Blob) => boolean;
|
|
1883
|
+
}
|
|
1884
|
+
/**
|
|
1885
|
+
* Deliver one JSON POST during pagehide. Prefers fetch keepalive (headers).
|
|
1886
|
+
* Falls back to sendBeacon with a credential envelope on same-origin URLs.
|
|
1887
|
+
*/
|
|
1888
|
+
declare function sendOnUnload(opts: SendOnUnloadOptions): boolean;
|
|
1889
|
+
declare function markPageUnloading(): void;
|
|
1890
|
+
declare function isPageUnloading(): boolean;
|
|
1770
1891
|
|
|
1771
1892
|
/**
|
|
1772
1893
|
* C7: Data residency region resolution.
|
|
@@ -2632,4 +2753,4 @@ declare function projectInitialsThemeIndex(projectId: string): number;
|
|
|
2632
2753
|
*/
|
|
2633
2754
|
declare function readPageFaviconHref(): string | null;
|
|
2634
2755
|
|
|
2635
|
-
export { type ApiClientOptions, type BreadcrumbBuffer, type BreadcrumbBufferOptions, DEFAULT_API_ENDPOINT, DEFAULT_MAX_RETRIES, DEFAULT_TIMEOUT, type EnvConfigDiagnostics, type EnvNearMiss, type LogEntry, type LogFormat, type LogLevel, type Logger, type LoggerOptions, MAX_REPORT_PAYLOAD_BYTES, MAX_SCREENSHOT_DATA_URL_BYTES, MUSHI_ACCENT_SHADOW, MUSHI_BANNER_BRAND_BORDER, MUSHI_BANNER_NEON, MUSHI_BORDER, MUSHI_COLORS_DARK, MUSHI_COLORS_LIGHT, MUSHI_CONTROL_DISABLED, MUSHI_COPY, MUSHI_DURATION, MUSHI_GEOMETRY, MUSHI_IDENTITY_TOKEN_PREFIX, MUSHI_INTERNAL_HEADER, MUSHI_INTERNAL_INIT_MARKER, MUSHI_INVERSE, MUSHI_LETTER_SPACING, MUSHI_MOTION, MUSHI_ON_ACCENT, MUSHI_OPACITY, MUSHI_PROJECT_HEADER, MUSHI_RADIUS, MUSHI_REPORTER_STATUS, MUSHI_SDK_PACKAGE_HEADER, MUSHI_SDK_VERSION_HEADER, MUSHI_SHADOW_INK, MUSHI_SPACING, MUSHI_TIER_COLORS, MUSHI_TYPE, MUSHI_USER_TOKEN_HEADER, MUSHI_Z, type MushiActivityEvent, type MushiApiCascadeConfig, type MushiApiClient, type MushiApiResponse, type MushiAssistantConfig, type MushiAssistantReply, type MushiAssistantStep, type MushiBannerConfig, type MushiBannerLink, type MushiBetaChangelogEntry, type MushiBetaModeConfig, type MushiBreadcrumb, type MushiCaptureConfig, type MushiCaptureEventInput, type MushiCaptureExceptionOptions, type MushiColorPalette, type MushiConfig, type MushiConsoleEntry, type MushiCooldownConfig, type MushiCrossAppReport, type MushiCustomCategory, type MushiDiagnosticsResult, type MushiDiscoverInventoryConfig, type MushiDiscoveryEventPayload, type MushiEnvironment, type MushiEventHandler, type MushiEventType, type MushiHallOfFameEntry, type MushiIdentityClaims, type MushiIntegrationsConfig, type MushiInternalRequestKind, type MushiLeaderboardEntry, type MushiNetworkEntry, type MushiOfflineConfig, type MushiOnDeviceClassifier, type MushiOnDeviceClassifierInput, type MushiOnDeviceClassifierResult, type MushiPageContext, type MushiPerformanceMetrics, type MushiPreFilterConfig, type MushiPreset, type MushiPrivacyConfig, type MushiProactiveConfig, type MushiRegion, type MushiReport, type MushiReportBuilder, type MushiReportCategory, type MushiReportStatus, type MushiReporterComment, type MushiReporterReport, type MushiReputationResult, type MushiRewardsConfig, type MushiRuntimeSdkConfig, type MushiSDKInstance, type MushiSdkVersionInfo, type MushiSelectedElement, type MushiSentryConfig, type MushiSentryContext, type MushiSessionEventPayload, type MushiTesterReputation, type MushiThemeMode, type MushiTierResult, type MushiTimelineEntry, type MushiTimelineKind, type MushiTokenSnapshot, type MushiTracePropagationConfig, type MushiUrlMatcher, type MushiWidgetAnchor, type MushiWidgetConfig, type NormalisedException, type OfflineQueue, type PayloadGuardResult, type PiiScrubberConfig, type PreFilterResult, type ProjectFaviconSource, REGION_ENDPOINTS, type RateLimiter, type RateLimiterConfig, type ResolvedEnvConfig, type SessionTrackerOptions, buildIdentityClaims, buildSdkIngestHeaders, captureEnvironment, checkReportPayloadSize, createApiClient, createBreadcrumbBuffer, createLogger, createOfflineQueue, createPiiScrubber, createPreFilter, createRateLimiter, destroySessionTracker, diagnoseEnvConfig, estimateJsonBytes, expandPreset, faviconUrlCandidates, formatBytes, getDeviceFingerprintHash, getReporterToken, getSessionId, githubRepoDomainHint, hmacSha256Hex, initSessionTracker, isLikelyGenericFavicon, isUntrustedFaviconUrl, mushiPalette, mushiTokens, newUuid, noopLogger, normaliseThrown, originToDomain, parseIdentityToken, projectFaviconUrlCandidates, projectInitials, projectInitialsThemeIndex, readPageFaviconHref, resolveEnvConfig, resolveProjectDomain, resolveProjectFaviconDomains, resolveRegionEndpoint, resolveWidgetAccent, safeWidgetHex, scrubPii, scrubUrl, sha256Hex, trackPageView, updateSessionIdentity, validateConfig };
|
|
2756
|
+
export { type ApiClientOptions, type BreadcrumbBuffer, type BreadcrumbBufferOptions, DEFAULT_API_ENDPOINT, DEFAULT_MAX_RETRIES, DEFAULT_TIMEOUT, type EnvConfigDiagnostics, type EnvNearMiss, type LogEntry, type LogFormat, type LogLevel, type Logger, type LoggerOptions, MAX_REPORT_PAYLOAD_BYTES, MAX_SCREENSHOT_DATA_URL_BYTES, MUSHI_ACCENT_SHADOW, MUSHI_BANNER_BRAND_BORDER, MUSHI_BANNER_NEON, MUSHI_BEACON_MAX_BYTES, MUSHI_BORDER, MUSHI_COLORS_DARK, MUSHI_COLORS_LIGHT, MUSHI_CONTROL_DISABLED, MUSHI_COPY, MUSHI_DURATION, MUSHI_GEOMETRY, MUSHI_IDENTITY_TOKEN_PREFIX, MUSHI_INTERNAL_HEADER, MUSHI_INTERNAL_INIT_MARKER, MUSHI_INVERSE, MUSHI_LETTER_SPACING, MUSHI_MOTION, MUSHI_ON_ACCENT, MUSHI_OPACITY, MUSHI_PROJECT_HEADER, MUSHI_RADIUS, MUSHI_REPORTER_STATUS, MUSHI_SDK_PACKAGE_HEADER, MUSHI_SDK_VERSION_HEADER, MUSHI_SHADOW_INK, MUSHI_SPACING, MUSHI_TIER_COLORS, MUSHI_TYPE, MUSHI_USER_TOKEN_HEADER, MUSHI_Z, type MushiActivityEvent, type MushiApiCascadeConfig, type MushiApiClient, type MushiApiResponse, type MushiAssistantConfig, type MushiAssistantReply, type MushiAssistantStep, type MushiBannerConfig, type MushiBannerLink, type MushiBeaconEnvelope, type MushiBetaChangelogEntry, type MushiBetaModeConfig, type MushiBreadcrumb, type MushiCaptureConfig, type MushiCaptureEventInput, type MushiCaptureExceptionOptions, type MushiColorPalette, type MushiConfig, type MushiConsoleEntry, type MushiCooldownConfig, type MushiCrossAppReport, type MushiCustomCategory, type MushiDiagnosticsResult, type MushiDiscoverInventoryConfig, type MushiDiscoveryEventPayload, type MushiEnvironment, type MushiErrorFilter, type MushiEventHandler, type MushiEventType, type MushiHallOfFameEntry, type MushiIdentityClaims, type MushiIntegrationsConfig, type MushiInternalRequestKind, type MushiLeaderboardEntry, type MushiNetworkEntry, type MushiOfflineConfig, type MushiOnDeviceClassifier, type MushiOnDeviceClassifierInput, type MushiOnDeviceClassifierResult, type MushiPageContext, type MushiPerformanceMetrics, type MushiPreFilterConfig, type MushiPreset, type MushiPrivacyConfig, type MushiProactiveConfig, type MushiRegion, type MushiReport, type MushiReportBuilder, type MushiReportCategory, type MushiReportStatus, type MushiReporterComment, type MushiReporterReport, type MushiReputationResult, type MushiRewardsConfig, type MushiRuntimeSdkConfig, type MushiSDKInstance, type MushiSdkVersionInfo, type MushiSelectedElement, type MushiSentryConfig, type MushiSentryContext, type MushiSessionEventPayload, type MushiTesterReputation, type MushiThemeMode, type MushiTierResult, type MushiTimelineEntry, type MushiTimelineKind, type MushiTokenSnapshot, type MushiTracePropagationConfig, type MushiUrlMatcher, type MushiWidgetAnchor, type MushiWidgetConfig, type NormalisedException, type OfflineQueue, type PayloadGuardResult, type PiiScrubberConfig, type PreFilterResult, type ProjectFaviconSource, REGION_ENDPOINTS, type RateLimiter, type RateLimiterConfig, type ResolvedEnvConfig, type SessionTrackerOptions, buildBeaconEnvelope, buildIdentityClaims, buildSdkIngestHeaders, captureEnvironment, checkReportPayloadSize, createApiClient, createBreadcrumbBuffer, createLogger, createOfflineQueue, createPiiScrubber, createPreFilter, createRateLimiter, destroySessionTracker, diagnoseEnvConfig, estimateJsonBytes, expandPreset, extractTunnelPath, faviconUrlCandidates, flushLastOutboundOnUnload, formatBytes, getBackoffDelay, getDeviceFingerprintHash, getReporterToken, getSessionId, githubRepoDomainHint, hmacSha256Hex, initSessionTracker, isLikelyGenericFavicon, isMushiBeaconEnvelope, isPageUnloading, isSameOriginOrRelative, isUntrustedFaviconUrl, markPageUnloading, matchesErrorFilter, mushiPalette, mushiTokens, newUuid, noopLogger, normaliseThrown, originToDomain, parseIdentityToken, parseRetryAfter, projectFaviconUrlCandidates, projectInitials, projectInitialsThemeIndex, readPageFaviconHref, resolveEnvConfig, resolveProjectDomain, resolveProjectFaviconDomains, resolveRegionEndpoint, resolveRequestBaseUrl, resolveWidgetAccent, safeWidgetHex, scrubPii, scrubUrl, sendOnUnload, sha256Hex, shouldDropCapturedError, trackPageView, updateSessionIdentity, validateConfig };
|
package/dist/index.js
CHANGED
|
@@ -84,7 +84,92 @@ async function hmacSha256Hex(secret, value) {
|
|
|
84
84
|
return bytesToHex(result);
|
|
85
85
|
}
|
|
86
86
|
|
|
87
|
+
// src/unload-transport.ts
|
|
88
|
+
var MUSHI_BEACON_MAX_BYTES = 60 * 1024;
|
|
89
|
+
function isMushiBeaconEnvelope(value) {
|
|
90
|
+
if (!value || typeof value !== "object") return false;
|
|
91
|
+
const rec = value;
|
|
92
|
+
return rec.mushiBeacon === true && typeof rec.path === "string" && rec.headers !== null && typeof rec.headers === "object";
|
|
93
|
+
}
|
|
94
|
+
function buildBeaconEnvelope(opts) {
|
|
95
|
+
return {
|
|
96
|
+
mushiBeacon: true,
|
|
97
|
+
path: opts.path,
|
|
98
|
+
headers: opts.headers,
|
|
99
|
+
body: opts.body
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
function isSameOriginOrRelative(url, origin = typeof location !== "undefined" ? location.origin : "") {
|
|
103
|
+
if (!url) return false;
|
|
104
|
+
if (url.startsWith("/")) return true;
|
|
105
|
+
if (!origin) return false;
|
|
106
|
+
try {
|
|
107
|
+
return new URL(url, origin).origin === origin;
|
|
108
|
+
} catch {
|
|
109
|
+
return false;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
function extractTunnelPath(url) {
|
|
113
|
+
try {
|
|
114
|
+
const parsed = url.startsWith("/") ? new URL(url, "https://tunnel.local") : new URL(url);
|
|
115
|
+
return `${parsed.pathname}${parsed.search}`;
|
|
116
|
+
} catch {
|
|
117
|
+
return url;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
function sendOnUnload(opts) {
|
|
121
|
+
const fetchImpl = opts.fetchImpl ?? (typeof fetch === "function" ? fetch : void 0);
|
|
122
|
+
if (fetchImpl) {
|
|
123
|
+
try {
|
|
124
|
+
void fetchImpl(opts.url, {
|
|
125
|
+
method: "POST",
|
|
126
|
+
headers: {
|
|
127
|
+
"Content-Type": "application/json",
|
|
128
|
+
...opts.headers
|
|
129
|
+
},
|
|
130
|
+
body: opts.body,
|
|
131
|
+
keepalive: true
|
|
132
|
+
});
|
|
133
|
+
return true;
|
|
134
|
+
} catch {
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
const beacon = opts.sendBeacon ?? (typeof navigator !== "undefined" ? navigator.sendBeacon?.bind(navigator) : void 0);
|
|
138
|
+
if (!beacon || !isSameOriginOrRelative(opts.url)) return false;
|
|
139
|
+
let parsedBody = opts.body;
|
|
140
|
+
try {
|
|
141
|
+
parsedBody = JSON.parse(opts.body);
|
|
142
|
+
} catch {
|
|
143
|
+
parsedBody = opts.body;
|
|
144
|
+
}
|
|
145
|
+
const envelope = JSON.stringify(
|
|
146
|
+
buildBeaconEnvelope({
|
|
147
|
+
path: opts.path ?? extractTunnelPath(opts.url),
|
|
148
|
+
headers: opts.headers,
|
|
149
|
+
body: parsedBody
|
|
150
|
+
})
|
|
151
|
+
);
|
|
152
|
+
if (envelope.length > MUSHI_BEACON_MAX_BYTES) return false;
|
|
153
|
+
try {
|
|
154
|
+
return beacon(opts.url, new Blob([envelope], { type: "application/json" }));
|
|
155
|
+
} catch {
|
|
156
|
+
return false;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
var pageUnloading = false;
|
|
160
|
+
function markPageUnloading() {
|
|
161
|
+
pageUnloading = true;
|
|
162
|
+
}
|
|
163
|
+
function isPageUnloading() {
|
|
164
|
+
return pageUnloading;
|
|
165
|
+
}
|
|
166
|
+
|
|
87
167
|
// src/api-client.ts
|
|
168
|
+
var lastOutbound = null;
|
|
169
|
+
function flushLastOutboundOnUnload() {
|
|
170
|
+
if (!lastOutbound) return false;
|
|
171
|
+
return sendOnUnload(lastOutbound);
|
|
172
|
+
}
|
|
88
173
|
var _credWarningEmitted = false;
|
|
89
174
|
var MUSHI_USER_TOKEN_HEADER = "X-Mushi-User-Token";
|
|
90
175
|
var MUSHI_PROJECT_HEADER = "X-Mushi-Project";
|
|
@@ -105,6 +190,11 @@ function buildSdkIngestHeaders(opts) {
|
|
|
105
190
|
var DEFAULT_API_ENDPOINT = "https://dxptnwrhwsqckaftyymj.supabase.co/functions/v1/api";
|
|
106
191
|
var MUSHI_INTERNAL_HEADER = "X-Mushi-Internal";
|
|
107
192
|
var MUSHI_INTERNAL_INIT_MARKER = "__mushiInternal";
|
|
193
|
+
function resolveRequestBaseUrl(apiEndpoint, tunnel) {
|
|
194
|
+
const trimmedTunnel = tunnel?.trim();
|
|
195
|
+
if (trimmedTunnel) return trimmedTunnel.replace(/\/$/, "");
|
|
196
|
+
return (apiEndpoint ?? DEFAULT_API_ENDPOINT).replace(/\/$/, "");
|
|
197
|
+
}
|
|
108
198
|
var DEFAULT_TIMEOUT = 1e4;
|
|
109
199
|
var DEFAULT_MAX_RETRIES = 2;
|
|
110
200
|
var DEFAULT_CIRCUIT_THRESHOLD = 4;
|
|
@@ -115,6 +205,7 @@ function createApiClient(options) {
|
|
|
115
205
|
projectId,
|
|
116
206
|
apiKey,
|
|
117
207
|
apiEndpoint = DEFAULT_API_ENDPOINT,
|
|
208
|
+
tunnel,
|
|
118
209
|
timeout = DEFAULT_TIMEOUT,
|
|
119
210
|
maxRetries = DEFAULT_MAX_RETRIES,
|
|
120
211
|
getUserToken,
|
|
@@ -122,7 +213,7 @@ function createApiClient(options) {
|
|
|
122
213
|
sdkVersion,
|
|
123
214
|
circuitBreaker
|
|
124
215
|
} = options;
|
|
125
|
-
let baseUrl = apiEndpoint
|
|
216
|
+
let baseUrl = resolveRequestBaseUrl(apiEndpoint, tunnel);
|
|
126
217
|
const cbEnabled = circuitBreaker?.enabled !== false;
|
|
127
218
|
const cbThreshold = Math.max(1, circuitBreaker?.threshold ?? DEFAULT_CIRCUIT_THRESHOLD);
|
|
128
219
|
const cbCooldownMs = Math.max(1e3, circuitBreaker?.cooldownMs ?? DEFAULT_CIRCUIT_COOLDOWN_MS);
|
|
@@ -146,21 +237,27 @@ function createApiClient(options) {
|
|
|
146
237
|
const controller = new AbortController();
|
|
147
238
|
const timer = setTimeout(() => controller.abort(), timeout);
|
|
148
239
|
const userToken = getUserToken?.() ?? null;
|
|
240
|
+
const headers = {
|
|
241
|
+
...buildSdkIngestHeaders({
|
|
242
|
+
apiKey,
|
|
243
|
+
projectId,
|
|
244
|
+
sdkPackage,
|
|
245
|
+
sdkVersion,
|
|
246
|
+
userToken,
|
|
247
|
+
internalKind
|
|
248
|
+
}),
|
|
249
|
+
...extraHeaders
|
|
250
|
+
};
|
|
251
|
+
const serialized = body ? JSON.stringify(body) : void 0;
|
|
252
|
+
if (serialized && method !== "GET") {
|
|
253
|
+
lastOutbound = { url, headers, body: serialized, path };
|
|
254
|
+
}
|
|
149
255
|
try {
|
|
150
256
|
const response = await fetch(url, {
|
|
151
257
|
method,
|
|
152
|
-
headers
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
projectId,
|
|
156
|
-
sdkPackage,
|
|
157
|
-
sdkVersion,
|
|
158
|
-
userToken,
|
|
159
|
-
internalKind
|
|
160
|
-
}),
|
|
161
|
-
...extraHeaders
|
|
162
|
-
},
|
|
163
|
-
body: body ? JSON.stringify(body) : void 0,
|
|
258
|
+
headers,
|
|
259
|
+
body: serialized,
|
|
260
|
+
keepalive: isPageUnloading(),
|
|
164
261
|
signal: controller.signal,
|
|
165
262
|
...internalKind ? { [MUSHI_INTERNAL_INIT_MARKER]: internalKind } : {}
|
|
166
263
|
});
|
|
@@ -241,6 +338,7 @@ function createApiClient(options) {
|
|
|
241
338
|
"X-Reporter-Hmac": hmac
|
|
242
339
|
},
|
|
243
340
|
body: body ? JSON.stringify(body) : void 0,
|
|
341
|
+
keepalive: isPageUnloading(),
|
|
244
342
|
[MUSHI_INTERNAL_INIT_MARKER]: "reporter-poll"
|
|
245
343
|
});
|
|
246
344
|
if (!response.ok) {
|
|
@@ -516,6 +614,32 @@ function isRetryable(error) {
|
|
|
516
614
|
return false;
|
|
517
615
|
}
|
|
518
616
|
|
|
617
|
+
// src/error-filters.ts
|
|
618
|
+
function matchesErrorFilter(value, filters) {
|
|
619
|
+
if (!value || !filters || filters.length === 0) return false;
|
|
620
|
+
for (const filter of filters) {
|
|
621
|
+
if (typeof filter === "string") {
|
|
622
|
+
if (value.includes(filter)) return true;
|
|
623
|
+
continue;
|
|
624
|
+
}
|
|
625
|
+
try {
|
|
626
|
+
if (filter.test(value)) return true;
|
|
627
|
+
} catch {
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
return false;
|
|
631
|
+
}
|
|
632
|
+
function shouldDropCapturedError(input) {
|
|
633
|
+
if (matchesErrorFilter(input.message, input.ignoreErrors)) return true;
|
|
634
|
+
const filename = input.filename?.trim() || "";
|
|
635
|
+
if (filename && matchesErrorFilter(filename, input.denyUrls)) return true;
|
|
636
|
+
if (input.allowUrls && input.allowUrls.length > 0) {
|
|
637
|
+
if (!filename) return true;
|
|
638
|
+
if (!matchesErrorFilter(filename, input.allowUrls)) return true;
|
|
639
|
+
}
|
|
640
|
+
return false;
|
|
641
|
+
}
|
|
642
|
+
|
|
519
643
|
// src/region.ts
|
|
520
644
|
var REGION_ENDPOINTS = {
|
|
521
645
|
us: DEFAULT_API_ENDPOINT,
|
|
@@ -694,6 +818,7 @@ var KNOWN_CONFIG_KEYS = [
|
|
|
694
818
|
"projectId",
|
|
695
819
|
"apiKey",
|
|
696
820
|
"apiEndpoint",
|
|
821
|
+
"tunnel",
|
|
697
822
|
"timeout",
|
|
698
823
|
"maxRetries",
|
|
699
824
|
"circuitBreaker",
|
|
@@ -713,8 +838,13 @@ var KNOWN_CONFIG_KEYS = [
|
|
|
713
838
|
"enabled",
|
|
714
839
|
"appVersion",
|
|
715
840
|
"sampleRate",
|
|
841
|
+
"replaySampleRate",
|
|
842
|
+
"replaysOnErrorSampleRate",
|
|
716
843
|
"beforeSend",
|
|
717
844
|
"beforeSendFeedback",
|
|
845
|
+
"ignoreErrors",
|
|
846
|
+
"denyUrls",
|
|
847
|
+
"allowUrls",
|
|
718
848
|
"onCrashedLastRun"
|
|
719
849
|
];
|
|
720
850
|
function presetDefaults(preset) {
|
|
@@ -2484,13 +2614,22 @@ var SLUG_DOMAIN_HINTS = {
|
|
|
2484
2614
|
"glot-it": "glot.it",
|
|
2485
2615
|
glotit: "glot.it",
|
|
2486
2616
|
"solo-boss-cloud": "solo-boss.kensaur.us",
|
|
2487
|
-
"mushi-mushi": "kensaur.us"
|
|
2617
|
+
"mushi-mushi": "kensaur.us",
|
|
2618
|
+
"how-to-talk-to-girls": "talk.kensaur.us",
|
|
2619
|
+
htttg: "talk.kensaur.us",
|
|
2620
|
+
tsumagoi: "tsumagoi.kensaur.us"
|
|
2488
2621
|
};
|
|
2489
2622
|
var SLUG_ICON_URL_HINTS = {
|
|
2490
2623
|
"mushi-mushi": "https://kensaur.us/mushi-mushi/admin/favicon.svg",
|
|
2491
2624
|
"solo-boss-cloud": "https://solo-boss.kensaur.us/favicon.svg",
|
|
2492
2625
|
"glot-it": "https://kensaur.us/glot-it/apple-touch-icon.png",
|
|
2493
|
-
glotit: "https://kensaur.us/glot-it/apple-touch-icon.png"
|
|
2626
|
+
glotit: "https://kensaur.us/glot-it/apple-touch-icon.png",
|
|
2627
|
+
"the-wanting-mind": "https://kensaur.us/the-wanting-mind/pwa-512x512.png",
|
|
2628
|
+
"how-to-talk-to-girls": "https://talk.kensaur.us/pwa-192.png",
|
|
2629
|
+
htttg: "https://talk.kensaur.us/pwa-192.png",
|
|
2630
|
+
tsumagoi: "https://tsumagoi.kensaur.us/apple-touch-icon.png",
|
|
2631
|
+
"help-her-take-photo": "https://kensaur.us/help-her-take-photo/assets/apple-touch-icon.png",
|
|
2632
|
+
"yen-yen": "https://kensaur.us/yen-yen/icon.svg"
|
|
2494
2633
|
};
|
|
2495
2634
|
var UNTRUSTED_FAVICON_HOSTS = [
|
|
2496
2635
|
"www.google.com",
|
|
@@ -2662,6 +2801,6 @@ function isSafeFaviconHref(href) {
|
|
|
2662
2801
|
}
|
|
2663
2802
|
}
|
|
2664
2803
|
|
|
2665
|
-
export { DEFAULT_API_ENDPOINT, DEFAULT_MAX_RETRIES, DEFAULT_TIMEOUT, MAX_REPORT_PAYLOAD_BYTES, MAX_SCREENSHOT_DATA_URL_BYTES, MUSHI_ACCENT_SHADOW, MUSHI_BANNER_BRAND_BORDER, MUSHI_BANNER_NEON, MUSHI_BORDER, MUSHI_COLORS_DARK, MUSHI_COLORS_LIGHT, MUSHI_CONTROL_DISABLED, MUSHI_COPY, MUSHI_DURATION, MUSHI_GEOMETRY, MUSHI_IDENTITY_TOKEN_PREFIX, MUSHI_INTERNAL_HEADER, MUSHI_INTERNAL_INIT_MARKER, MUSHI_INVERSE, MUSHI_LETTER_SPACING, MUSHI_MOTION, MUSHI_ON_ACCENT, MUSHI_OPACITY, MUSHI_PROJECT_HEADER, MUSHI_RADIUS, MUSHI_REPORTER_STATUS, MUSHI_SDK_PACKAGE_HEADER, MUSHI_SDK_VERSION_HEADER, MUSHI_SHADOW_INK, MUSHI_SPACING, MUSHI_TIER_COLORS, MUSHI_TYPE, MUSHI_USER_TOKEN_HEADER, MUSHI_Z, REGION_ENDPOINTS, buildIdentityClaims, buildSdkIngestHeaders, captureEnvironment, checkReportPayloadSize, createApiClient, createBreadcrumbBuffer, createLogger, createOfflineQueue, createPiiScrubber, createPreFilter, createRateLimiter, destroySessionTracker, diagnoseEnvConfig, estimateJsonBytes, expandPreset, faviconUrlCandidates, formatBytes, getDeviceFingerprintHash, getReporterToken, getSessionId, githubRepoDomainHint, hmacSha256Hex, initSessionTracker, isLikelyGenericFavicon, isUntrustedFaviconUrl, mushiPalette, mushiTokens, newUuid, noopLogger, normaliseThrown, originToDomain, parseIdentityToken, projectFaviconUrlCandidates, projectInitials, projectInitialsThemeIndex, readPageFaviconHref, resolveEnvConfig, resolveProjectDomain, resolveProjectFaviconDomains, resolveRegionEndpoint, resolveWidgetAccent, safeWidgetHex, scrubPii, scrubUrl, sha256Hex, trackPageView, updateSessionIdentity, validateConfig };
|
|
2804
|
+
export { DEFAULT_API_ENDPOINT, DEFAULT_MAX_RETRIES, DEFAULT_TIMEOUT, MAX_REPORT_PAYLOAD_BYTES, MAX_SCREENSHOT_DATA_URL_BYTES, MUSHI_ACCENT_SHADOW, MUSHI_BANNER_BRAND_BORDER, MUSHI_BANNER_NEON, MUSHI_BEACON_MAX_BYTES, MUSHI_BORDER, MUSHI_COLORS_DARK, MUSHI_COLORS_LIGHT, MUSHI_CONTROL_DISABLED, MUSHI_COPY, MUSHI_DURATION, MUSHI_GEOMETRY, MUSHI_IDENTITY_TOKEN_PREFIX, MUSHI_INTERNAL_HEADER, MUSHI_INTERNAL_INIT_MARKER, MUSHI_INVERSE, MUSHI_LETTER_SPACING, MUSHI_MOTION, MUSHI_ON_ACCENT, MUSHI_OPACITY, MUSHI_PROJECT_HEADER, MUSHI_RADIUS, MUSHI_REPORTER_STATUS, MUSHI_SDK_PACKAGE_HEADER, MUSHI_SDK_VERSION_HEADER, MUSHI_SHADOW_INK, MUSHI_SPACING, MUSHI_TIER_COLORS, MUSHI_TYPE, MUSHI_USER_TOKEN_HEADER, MUSHI_Z, REGION_ENDPOINTS, buildBeaconEnvelope, buildIdentityClaims, buildSdkIngestHeaders, captureEnvironment, checkReportPayloadSize, createApiClient, createBreadcrumbBuffer, createLogger, createOfflineQueue, createPiiScrubber, createPreFilter, createRateLimiter, destroySessionTracker, diagnoseEnvConfig, estimateJsonBytes, expandPreset, extractTunnelPath, faviconUrlCandidates, flushLastOutboundOnUnload, formatBytes, getBackoffDelay, getDeviceFingerprintHash, getReporterToken, getSessionId, githubRepoDomainHint, hmacSha256Hex, initSessionTracker, isLikelyGenericFavicon, isMushiBeaconEnvelope, isPageUnloading, isSameOriginOrRelative, isUntrustedFaviconUrl, markPageUnloading, matchesErrorFilter, mushiPalette, mushiTokens, newUuid, noopLogger, normaliseThrown, originToDomain, parseIdentityToken, parseRetryAfter, projectFaviconUrlCandidates, projectInitials, projectInitialsThemeIndex, readPageFaviconHref, resolveEnvConfig, resolveProjectDomain, resolveProjectFaviconDomains, resolveRegionEndpoint, resolveRequestBaseUrl, resolveWidgetAccent, safeWidgetHex, scrubPii, scrubUrl, sendOnUnload, sha256Hex, shouldDropCapturedError, trackPageView, updateSessionIdentity, validateConfig };
|
|
2666
2805
|
//# sourceMappingURL=index.js.map
|
|
2667
2806
|
//# sourceMappingURL=index.js.map
|