Big News: Socket raises $60M Series C at a $1B valuation to secure software supply chains for AI-driven development.Announcement
Sign In

@posthog/core

Package Overview
Dependencies
Maintainers
20
Versions
104
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@posthog/core - npm Package Compare versions

Comparing version
1.29.15
to
1.30.0
+16
-2
dist/utils/user-agent-utils.d.ts
/**
* Hints from sources outside the User-Agent string. These let us identify Brave
* on desktop / Android — Chromium-based with no UA marker, but it exposes
* `navigator.brave`. (Brave on iOS is detected via its `Brave/X` UA marker —
* WebKit doesn't expose `navigator.brave` — so no hint is needed there.)
*/
export interface BrowserDetectionHints {
brave?: boolean;
}
/**
* This function detects which browser is running this script.
* The order of the checks are important since many user agents
* include keywords used in later checks.
*
* `hints` is an optional bag of out-of-band signals (`navigator.brave`) used to
* detect browsers that intentionally do not identify themselves in the UA
* string. When omitted, only UA-string detection runs — preserving the previous
* behaviour.
*/
export declare const detectBrowser: (user_agent: string, vendor: string | undefined) => string;
export declare const detectBrowser: (user_agent: string, vendor: string | undefined, hints?: BrowserDetectionHints) => string;
/**

@@ -15,3 +29,3 @@ * This function detects which browser version is running this script,

*/
export declare const detectBrowserVersion: (userAgent: string, vendor: string | undefined) => number | null;
export declare const detectBrowserVersion: (userAgent: string, vendor: string | undefined, hints?: BrowserDetectionHints) => number | null;
export declare const detectOS: (user_agent: string) => [string, string];

@@ -18,0 +32,0 @@ export declare const detectDevice: (user_agent: string) => string;

+1
-1

@@ -1,1 +0,1 @@

{"version":3,"file":"user-agent-utils.d.ts","sourceRoot":"","sources":["../../src/utils/user-agent-utils.ts"],"names":[],"mappings":"AAsFA;;;;GAIG;AACH,eAAO,MAAM,aAAa,GAAa,YAAY,MAAM,EAAE,QAAQ,MAAM,GAAG,SAAS,KAAG,MAmDvF,CAAA;AAuBD;;;;;;;GAOG;AACH,eAAO,MAAM,oBAAoB,GAAa,WAAW,MAAM,EAAE,QAAQ,MAAM,GAAG,SAAS,KAAG,MAAM,GAAG,IAetG,CAAA;AA0FD,eAAO,MAAM,QAAQ,GAAa,YAAY,MAAM,KAAG,CAAC,MAAM,EAAE,MAAM,CAUrE,CAAA;AAED,eAAO,MAAM,YAAY,GAAa,YAAY,MAAM,KAAG,MAuD1D,CAAA;AAED,eAAO,MAAM,gBAAgB,GAC3B,YAAY,MAAM,EAClB,UAAU;IACR,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAC1B,KACA,MA4BF,CAAA"}
{"version":3,"file":"user-agent-utils.d.ts","sourceRoot":"","sources":["../../src/utils/user-agent-utils.ts"],"names":[],"mappings":"AA+DA;;;;;GAKG;AACH,MAAM,WAAW,qBAAqB;IAGpC,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB;AAuCD;;;;;;;;;GASG;AACH,eAAO,MAAM,aAAa,GACxB,YAAY,MAAM,EAClB,QAAQ,MAAM,GAAG,SAAS,EAC1B,QAAQ,qBAAqB,KAC5B,MAmFF,CAAA;AAkCD;;;;;;;GAOG;AACH,eAAO,MAAM,oBAAoB,GAC/B,WAAW,MAAM,EACjB,QAAQ,MAAM,GAAG,SAAS,EAC1B,QAAQ,qBAAqB,KAC5B,MAAM,GAAG,IAmBX,CAAA;AA0FD,eAAO,MAAM,QAAQ,GAAa,YAAY,MAAM,KAAG,CAAC,MAAM,EAAE,MAAM,CAUrE,CAAA;AAED,eAAO,MAAM,YAAY,GAAa,YAAY,MAAM,KAAG,MAuD1D,CAAA;AAED,eAAO,MAAM,gBAAgB,GAC3B,YAAY,MAAM,EAClB,UAAU;IACR,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAC1B,KACA,MA4BF,CAAA"}

@@ -74,4 +74,15 @@ "use strict";

const OCULUS_BROWSER = 'Oculus Browser';
const VIVALDI = 'Vivaldi';
const YANDEX = 'Yandex';
const WHALE = 'Whale';
const DUCKDUCKGO = 'DuckDuckGo';
const PALE_MOON = 'Pale Moon';
const WATERFOX = 'Waterfox';
const BRAVE = 'Brave';
const BROWSER_VERSION_REGEX_SUFFIX = '(\\d+(\\.\\d+)?)';
const DEFAULT_BROWSER_VERSION_REGEX = new RegExp('Version/' + BROWSER_VERSION_REGEX_SUFFIX);
function browserFromHints(hints) {
if (hints?.brave) return BRAVE;
return null;
}
const XBOX_REGEX = new RegExp(XBOX, 'i');

@@ -98,4 +109,6 @@ const PLAYSTATION_REGEX = new RegExp(PLAYSTATION + ' \\w+', 'i');

const safariCheck = (ua, vendor)=>vendor && (0, external_string_utils_js_namespaceObject.includes)(vendor, APPLE) || isSafari(ua);
const detectBrowser = function(user_agent, vendor) {
const detectBrowser = function(user_agent, vendor, hints) {
vendor = vendor || '';
const fromHints = browserFromHints(hints);
if (fromHints) return fromHints;
if ((0, external_string_utils_js_namespaceObject.includes)(user_agent, ' OPR/') && (0, external_string_utils_js_namespaceObject.includes)(user_agent, 'Mini')) return OPERA_MINI;

@@ -108,2 +121,6 @@ if ((0, external_string_utils_js_namespaceObject.includes)(user_agent, ' OPR/')) return OPERA;

else if ((0, external_string_utils_js_namespaceObject.includes)(user_agent, EDGE) || (0, external_string_utils_js_namespaceObject.includes)(user_agent, 'Edg/')) return MICROSOFT_EDGE;
else if ((0, external_string_utils_js_namespaceObject.includes)(user_agent, VIVALDI + '/')) return VIVALDI;
else if ((0, external_string_utils_js_namespaceObject.includes)(user_agent, 'YaBrowser/')) return YANDEX;
else if ((0, external_string_utils_js_namespaceObject.includes)(user_agent, WHALE + '/')) return WHALE;
else if ((0, external_string_utils_js_namespaceObject.includes)(user_agent, DUCKDUCKGO + '/') || (0, external_string_utils_js_namespaceObject.includes)(user_agent, 'Ddg/')) return DUCKDUCKGO;
else if ((0, external_string_utils_js_namespaceObject.includes)(user_agent, 'FBIOS')) return FACEBOOK + ' ' + MOBILE;

@@ -117,3 +134,6 @@ else if ((0, external_string_utils_js_namespaceObject.includes)(user_agent, 'UCWEB') || (0, external_string_utils_js_namespaceObject.includes)(user_agent, 'UCBrowser')) return 'UC Browser';

else if ((0, external_string_utils_js_namespaceObject.includes)(user_agent.toLowerCase(), KONQUEROR.toLowerCase())) return KONQUEROR;
else if ((0, external_string_utils_js_namespaceObject.includes)(user_agent, BRAVE + '/')) return BRAVE;
else if (safariCheck(user_agent, vendor)) return (0, external_string_utils_js_namespaceObject.includes)(user_agent, MOBILE) ? MOBILE_SAFARI : SAFARI;
else if ((0, external_string_utils_js_namespaceObject.includes)(user_agent, 'PaleMoon/')) return PALE_MOON;
else if ((0, external_string_utils_js_namespaceObject.includes)(user_agent, WATERFOX + '/')) return WATERFOX;
else if ((0, external_string_utils_js_namespaceObject.includes)(user_agent, FIREFOX)) return FIREFOX;

@@ -171,2 +191,23 @@ else if ((0, external_string_utils_js_namespaceObject.includes)(user_agent, 'MSIE') || (0, external_string_utils_js_namespaceObject.includes)(user_agent, 'Trident/')) return INTERNET_EXPLORER;

],
[VIVALDI]: [
new RegExp(VIVALDI + '\\/' + BROWSER_VERSION_REGEX_SUFFIX)
],
[YANDEX]: [
new RegExp('YaBrowser\\/' + BROWSER_VERSION_REGEX_SUFFIX)
],
[WHALE]: [
new RegExp(WHALE + '\\/' + BROWSER_VERSION_REGEX_SUFFIX)
],
[BRAVE]: [
new RegExp(BRAVE + '\\/' + BROWSER_VERSION_REGEX_SUFFIX)
],
[DUCKDUCKGO]: [
new RegExp('(DuckDuckGo|Ddg)\\/' + BROWSER_VERSION_REGEX_SUFFIX)
],
[PALE_MOON]: [
new RegExp('PaleMoon\\/' + BROWSER_VERSION_REGEX_SUFFIX)
],
[WATERFOX]: [
new RegExp(WATERFOX + '\\/' + BROWSER_VERSION_REGEX_SUFFIX)
],
[INTERNET_EXPLORER]: [

@@ -179,4 +220,4 @@ new RegExp('(rv:|MSIE )' + BROWSER_VERSION_REGEX_SUFFIX)

};
const detectBrowserVersion = function(userAgent, vendor) {
const browser = detectBrowser(userAgent, vendor);
const detectBrowserVersion = function(userAgent, vendor, hints) {
const browser = detectBrowser(userAgent, vendor, hints);
const regexes = versionRegexes[browser];

@@ -183,0 +224,0 @@ if ((0, external_type_utils_js_namespaceObject.isUndefined)(regexes)) return null;

@@ -42,4 +42,15 @@ import { includes } from "./string-utils.mjs";

const OCULUS_BROWSER = 'Oculus Browser';
const VIVALDI = 'Vivaldi';
const YANDEX = 'Yandex';
const WHALE = 'Whale';
const DUCKDUCKGO = 'DuckDuckGo';
const PALE_MOON = 'Pale Moon';
const WATERFOX = 'Waterfox';
const BRAVE = 'Brave';
const BROWSER_VERSION_REGEX_SUFFIX = '(\\d+(\\.\\d+)?)';
const DEFAULT_BROWSER_VERSION_REGEX = new RegExp('Version/' + BROWSER_VERSION_REGEX_SUFFIX);
function browserFromHints(hints) {
if (hints?.brave) return BRAVE;
return null;
}
const XBOX_REGEX = new RegExp(XBOX, 'i');

@@ -66,4 +77,6 @@ const PLAYSTATION_REGEX = new RegExp(PLAYSTATION + ' \\w+', 'i');

const safariCheck = (ua, vendor)=>vendor && includes(vendor, APPLE) || isSafari(ua);
const detectBrowser = function(user_agent, vendor) {
const detectBrowser = function(user_agent, vendor, hints) {
vendor = vendor || '';
const fromHints = browserFromHints(hints);
if (fromHints) return fromHints;
if (includes(user_agent, ' OPR/') && includes(user_agent, 'Mini')) return OPERA_MINI;

@@ -76,2 +89,6 @@ if (includes(user_agent, ' OPR/')) return OPERA;

else if (includes(user_agent, EDGE) || includes(user_agent, 'Edg/')) return MICROSOFT_EDGE;
else if (includes(user_agent, VIVALDI + '/')) return VIVALDI;
else if (includes(user_agent, 'YaBrowser/')) return YANDEX;
else if (includes(user_agent, WHALE + '/')) return WHALE;
else if (includes(user_agent, DUCKDUCKGO + '/') || includes(user_agent, 'Ddg/')) return DUCKDUCKGO;
else if (includes(user_agent, 'FBIOS')) return FACEBOOK + ' ' + MOBILE;

@@ -85,3 +102,6 @@ else if (includes(user_agent, 'UCWEB') || includes(user_agent, 'UCBrowser')) return 'UC Browser';

else if (includes(user_agent.toLowerCase(), KONQUEROR.toLowerCase())) return KONQUEROR;
else if (includes(user_agent, BRAVE + '/')) return BRAVE;
else if (safariCheck(user_agent, vendor)) return includes(user_agent, MOBILE) ? MOBILE_SAFARI : SAFARI;
else if (includes(user_agent, 'PaleMoon/')) return PALE_MOON;
else if (includes(user_agent, WATERFOX + '/')) return WATERFOX;
else if (includes(user_agent, FIREFOX)) return FIREFOX;

@@ -139,2 +159,23 @@ else if (includes(user_agent, 'MSIE') || includes(user_agent, 'Trident/')) return INTERNET_EXPLORER;

],
[VIVALDI]: [
new RegExp(VIVALDI + '\\/' + BROWSER_VERSION_REGEX_SUFFIX)
],
[YANDEX]: [
new RegExp('YaBrowser\\/' + BROWSER_VERSION_REGEX_SUFFIX)
],
[WHALE]: [
new RegExp(WHALE + '\\/' + BROWSER_VERSION_REGEX_SUFFIX)
],
[BRAVE]: [
new RegExp(BRAVE + '\\/' + BROWSER_VERSION_REGEX_SUFFIX)
],
[DUCKDUCKGO]: [
new RegExp('(DuckDuckGo|Ddg)\\/' + BROWSER_VERSION_REGEX_SUFFIX)
],
[PALE_MOON]: [
new RegExp('PaleMoon\\/' + BROWSER_VERSION_REGEX_SUFFIX)
],
[WATERFOX]: [
new RegExp(WATERFOX + '\\/' + BROWSER_VERSION_REGEX_SUFFIX)
],
[INTERNET_EXPLORER]: [

@@ -147,4 +188,4 @@ new RegExp('(rv:|MSIE )' + BROWSER_VERSION_REGEX_SUFFIX)

};
const detectBrowserVersion = function(userAgent, vendor) {
const browser = detectBrowser(userAgent, vendor);
const detectBrowserVersion = function(userAgent, vendor, hints) {
const browser = detectBrowser(userAgent, vendor, hints);
const regexes = versionRegexes[browser];

@@ -151,0 +192,0 @@ if (isUndefined(regexes)) return null;

{
"name": "@posthog/core",
"version": "1.29.15",
"version": "1.30.0",
"license": "MIT",

@@ -70,3 +70,3 @@ "main": "dist/index.js",

"dependencies": {
"@posthog/types": "1.376.6"
"@posthog/types": "1.377.0"
},

@@ -73,0 +73,0 @@ "devDependencies": {

@@ -53,2 +53,9 @@ import { includes } from './string-utils'

const OCULUS_BROWSER = 'Oculus Browser'
const VIVALDI = 'Vivaldi'
const YANDEX = 'Yandex'
const WHALE = 'Whale'
const DUCKDUCKGO = 'DuckDuckGo'
const PALE_MOON = 'Pale Moon'
const WATERFOX = 'Waterfox'
const BRAVE = 'Brave'

@@ -58,2 +65,21 @@ const BROWSER_VERSION_REGEX_SUFFIX = '(\\d+(\\.\\d+)?)'

/**
* Hints from sources outside the User-Agent string. These let us identify Brave
* on desktop / Android — Chromium-based with no UA marker, but it exposes
* `navigator.brave`. (Brave on iOS is detected via its `Brave/X` UA marker —
* WebKit doesn't expose `navigator.brave` — so no hint is needed there.)
*/
export interface BrowserDetectionHints {
// Set to `true` when `navigator.brave` exists. This is the sync detection
// signal Brave recommends. Not available on iOS — see UA fallback below.
brave?: boolean
}
function browserFromHints(hints: BrowserDetectionHints | undefined): string | null {
if (hints?.brave) {
return BRAVE
}
return null
}
const XBOX_REGEX = new RegExp(XBOX, 'i')

@@ -93,6 +119,23 @@ const PLAYSTATION_REGEX = new RegExp(PLAYSTATION + ' \\w+', 'i')

* include keywords used in later checks.
*
* `hints` is an optional bag of out-of-band signals (`navigator.brave`) used to
* detect browsers that intentionally do not identify themselves in the UA
* string. When omitted, only UA-string detection runs — preserving the previous
* behaviour.
*/
export const detectBrowser = function (user_agent: string, vendor: string | undefined): string {
export const detectBrowser = function (
user_agent: string,
vendor: string | undefined,
hints?: BrowserDetectionHints
): string {
vendor = vendor || '' // vendor is undefined for at least IE9
// Out-of-band signals win over UA sniffing because desktop Brave is
// deliberately invisible in the UA string and would otherwise be
// misdetected as Chrome.
const fromHints = browserFromHints(hints)
if (fromHints) {
return fromHints
}
if (includes(user_agent, ' OPR/') && includes(user_agent, 'Mini')) {

@@ -119,2 +162,13 @@ return OPERA_MINI

return MICROSOFT_EDGE
}
// Chromium forks that DO stamp themselves into the UA. These must be
// checked before Chrome because their UA also contains `Chrome/`.
else if (includes(user_agent, VIVALDI + '/')) {
return VIVALDI
} else if (includes(user_agent, 'YaBrowser/')) {
return YANDEX
} else if (includes(user_agent, WHALE + '/')) {
return WHALE
} else if (includes(user_agent, DUCKDUCKGO + '/') || includes(user_agent, 'Ddg/')) {
return DUCKDUCKGO
} else if (includes(user_agent, 'FBIOS')) {

@@ -136,4 +190,17 @@ return FACEBOOK + ' ' + MOBILE

return KONQUEROR
}
// Brave on iOS does stamp itself into the UA as `Brave/X` — desktop and
// Android Brave intentionally do not. Must come before the Safari branch
// because iOS Brave's UA otherwise looks like Mobile Safari.
else if (includes(user_agent, BRAVE + '/')) {
return BRAVE
} else if (safariCheck(user_agent, vendor)) {
return includes(user_agent, MOBILE) ? MOBILE_SAFARI : SAFARI
}
// Firefox forks that stamp themselves into the UA. Must precede the
// generic Firefox check because they also include `Firefox/` (or `Gecko`).
else if (includes(user_agent, 'PaleMoon/')) {
return PALE_MOON
} else if (includes(user_agent, WATERFOX + '/')) {
return WATERFOX
} else if (includes(user_agent, FIREFOX)) {

@@ -167,2 +234,13 @@ return FIREFOX

[OCULUS_BROWSER]: [new RegExp('OculusBrowser\\/' + BROWSER_VERSION_REGEX_SUFFIX)],
[VIVALDI]: [new RegExp(VIVALDI + '\\/' + BROWSER_VERSION_REGEX_SUFFIX)],
[YANDEX]: [new RegExp('YaBrowser\\/' + BROWSER_VERSION_REGEX_SUFFIX)],
[WHALE]: [new RegExp(WHALE + '\\/' + BROWSER_VERSION_REGEX_SUFFIX)],
// Brave on iOS exposes itself as `Brave/X.X` in the UA. Desktop / Android
// Brave don't, which is why hint-based Brave detection returns a null
// version: we have no UA marker to parse.
[BRAVE]: [new RegExp(BRAVE + '\\/' + BROWSER_VERSION_REGEX_SUFFIX)],
// DuckDuckGo on iOS uses `Ddg/`, on Android/desktop preview it uses `DuckDuckGo/`.
[DUCKDUCKGO]: [new RegExp('(DuckDuckGo|Ddg)\\/' + BROWSER_VERSION_REGEX_SUFFIX)],
[PALE_MOON]: [new RegExp('PaleMoon\\/' + BROWSER_VERSION_REGEX_SUFFIX)],
[WATERFOX]: [new RegExp(WATERFOX + '\\/' + BROWSER_VERSION_REGEX_SUFFIX)],
[INTERNET_EXPLORER]: [new RegExp('(rv:|MSIE )' + BROWSER_VERSION_REGEX_SUFFIX)],

@@ -180,4 +258,12 @@ Mozilla: [new RegExp('rv:' + BROWSER_VERSION_REGEX_SUFFIX)],

*/
export const detectBrowserVersion = function (userAgent: string, vendor: string | undefined): number | null {
const browser = detectBrowser(userAgent, vendor)
export const detectBrowserVersion = function (
userAgent: string,
vendor: string | undefined,
hints?: BrowserDetectionHints
): number | null {
const browser = detectBrowser(userAgent, vendor, hints)
// Desktop / Android Brave has no parseable UA version, so it returns null
// below: its `versionRegexes` entry only matches the iOS `Brave/` marker
// (absent from a desktop Chrome UA).
const regexes: RegExp[] | undefined = versionRegexes[browser as keyof typeof versionRegexes]

@@ -184,0 +270,0 @@ if (isUndefined(regexes)) {