@@ -13,6 +13,7 @@ import {
13
13
} from "compare-versions" ;
14
14
import { UAParser } from "ua-parser-js" ;
15
15
import { ParsedUserAgent } from "../types/types" ;
16
+ import { RUNTIME_IDS_WITH_PATCH_VERSIONING } from "./constants" ;
16
17
17
18
/**
18
19
* Returns the major version from a given version string.
@@ -110,7 +111,12 @@ const parseUA = (userAgent: string, browsers: Browsers): ParsedUserAgent => {
110
111
}
111
112
112
113
data . fullVersion = data . fullVersion || ua . browser . version || "0" ;
113
- data . version = getMajorMinorVersion ( data . fullVersion ) ;
114
+
115
+ if ( RUNTIME_IDS_WITH_PATCH_VERSIONING . has ( data . browser . id ) ) {
116
+ data . version = data . fullVersion ;
117
+ } else {
118
+ data . version = getMajorMinorVersion ( data . fullVersion ) ;
119
+ }
114
120
115
121
if ( ! ( data . browser . id in browsers ) ) {
116
122
return data ;
@@ -150,36 +156,46 @@ const parseUA = (userAgent: string, browsers: Browsers): ParsedUserAgent => {
150
156
// with this, find the pair of versions in |versions| that sandwiches
151
157
// |version|, and use the first of this pair. For example, given |version|
152
158
// "10.1" and |versions| entries "10.0" and "10.2", return "10.0".
153
- for ( let i = 0 ; i < versions . length - 1 ; i ++ ) {
154
- const current = versions [ i ] ;
155
- const next = versions [ i + 1 ] ;
156
- if (
157
- compareVersions ( data . version , current , ">=" ) &&
158
- compareVersions ( data . version , next , "<" )
159
- ) {
159
+ // However, for Bun, we need exact version matches because patch versions can add features.
160
+ if ( RUNTIME_IDS_WITH_PATCH_VERSIONING . has ( data . browser . id ) ) {
161
+ // For Bun, only mark as inBcd if exact version exists
162
+ if ( versions . includes ( data . version ) ) {
160
163
data . inBcd = true ;
161
- data . version = current ;
162
- break ;
164
+ }
165
+ } else {
166
+ for ( let i = 0 ; i < versions . length - 1 ; i ++ ) {
167
+ const current = versions [ i ] ;
168
+ const next = versions [ i + 1 ] ;
169
+ if (
170
+ compareVersions ( data . version , current , ">=" ) &&
171
+ compareVersions ( data . version , next , "<" )
172
+ ) {
173
+ data . inBcd = true ;
174
+ data . version = current ;
175
+ break ;
176
+ }
163
177
}
164
178
}
165
179
166
180
// We reached the last entry in |versions|. With no |next| to compare against
167
181
// we have to check if it looks like a significant release or not. By default
168
182
// that means a new major version, but for Safari and Samsung Internet the
169
183
// major and minor version are significant.
170
- let normalize = getMajorVersion ;
171
- if (
172
- data . browser . id . startsWith ( "safari" ) ||
173
- data . browser . id === "samsunginternet_android"
174
- ) {
175
- normalize = getMajorMinorVersion ;
176
- }
177
- if (
178
- data . inBcd == false &&
179
- normalize ( data . version ) === normalize ( versions [ versions . length - 1 ] )
180
- ) {
181
- data . inBcd = true ;
182
- data . version = versions [ versions . length - 1 ] ;
184
+ if ( ! RUNTIME_IDS_WITH_PATCH_VERSIONING . has ( data . browser . id ) ) {
185
+ let normalize = getMajorVersion ;
186
+ if (
187
+ data . browser . id . startsWith ( "safari" ) ||
188
+ data . browser . id === "samsunginternet_android"
189
+ ) {
190
+ normalize = getMajorMinorVersion ;
191
+ }
192
+ if (
193
+ data . inBcd == false &&
194
+ normalize ( data . version ) === normalize ( versions [ versions . length - 1 ] )
195
+ ) {
196
+ data . inBcd = true ;
197
+ data . version = versions [ versions . length - 1 ] ;
198
+ }
183
199
}
184
200
185
201
return data ;
0 commit comments