gologin 3.0.5 → 3.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,19 @@
2
2
 
3
3
  Combined changelog for GoLogin node.js SDK
4
4
 
5
+ ## [3.0.7] 2026-10-15
6
+
7
+ ### Fixes
8
+
9
+ * Keep IndexedDB in the profile when `storage.indexedDb` is enabled
10
+
11
+ ## [3.0.6] 2026-10-06
12
+
13
+ ### Fixes
14
+
15
+ * Pass user-defined timezone and language to browser start when they are not filled from IP
16
+ * Removed the macOS override that forced the browser language to en-US
17
+
5
18
  ## [3.0.4] 2026-09-04
6
19
 
7
20
  ### Fixes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gologin",
3
- "version": "3.0.5",
3
+ "version": "3.0.7",
4
4
  "description": "A high-level API to control Orbita browser over GoLogin API",
5
5
  "types": "./index.d.ts",
6
6
  "main": "./src/index.js",
package/src/gologin.js CHANGED
@@ -10,6 +10,7 @@ import {
10
10
  downloadCookies, setExtPathsAndRemoveDeleted, setOriginalExtPaths, uploadCookies,
11
11
  } from './browser/browser-user-data-manager.js';
12
12
  import { getProfileChromeExtensions } from './extensions/get-extensions.js';
13
+ import { INDEXED_DB_DIRECTORY } from './profile/profile-directories-to-remove.js';
13
14
  import { checkAutoLang, getIntlProfileConfig, securedOrbitaOpts } from './utils/browser.js';
14
15
  import { API_URL, ensureDirectoryExists, FALLBACK_API_URL, getOsAdvanced } from './utils/common.js';
15
16
  import { STORAGE_GATEWAY_BASE_URL } from './utils/constants.js';
@@ -66,6 +67,7 @@ export class GoLogin {
66
67
  this.waitWebsocket = options.waitWebsocket ?? true;
67
68
  this.isEmptyFonts = false;
68
69
  this.isFirstSession = false;
70
+ this.keepIndexedDb = false;
69
71
  this.isCloudHeadless = options.isCloudHeadless ?? true;
70
72
  this.storageGatewayUrl = `${STORAGE_GATEWAY_BASE_URL}/upload`;
71
73
 
@@ -490,6 +492,7 @@ export class GoLogin {
490
492
  throw new Error('Error fetching profile data');
491
493
  }
492
494
 
495
+ this.keepIndexedDb = profile.storage?.indexedDb === true;
493
496
  this.profileLaunchArguments = (profile.launchArguments || '').split(' ').filter(Boolean);
494
497
 
495
498
  const { navigator = {}, fonts, os: profileOs } = profile;
@@ -539,6 +542,7 @@ export class GoLogin {
539
542
  }
540
543
 
541
544
  this.proxy = proxy;
545
+ this.applyProfileLocale(profile);
542
546
 
543
547
  await Promise.all([
544
548
  withTiming({ name: 'resolveProfileBrowserVersion', promise: this.resolveProfileBrowserVersion(profile) }),
@@ -603,6 +607,13 @@ export class GoLogin {
603
607
  preferences.gologin = {};
604
608
  }
605
609
 
610
+ if (this.userTimezone && !this.timezone) {
611
+ this._tz = {
612
+ ...(this._tz || {}),
613
+ timezone: this.userTimezone,
614
+ };
615
+ }
616
+
606
617
  const gologin = this.getGologinPreferences(profile);
607
618
 
608
619
  debug(`Writing profile for screenWidth ${profilePath}`, JSON.stringify(gologin));
@@ -610,11 +621,14 @@ export class GoLogin {
610
621
  gologin.screenHeight = this.resolution.height;
611
622
  debug('writeCookiesFromServer', this.writeCookiesFromServer);
612
623
 
613
- const isMAC = OS_PLATFORM === 'darwin';
614
624
  const checkAutoLangResult = checkAutoLang(gologin, this._tz, profile.autoLang);
615
625
  const intlConfig = getIntlProfileConfig(profile, this._tz, profile.autoLang);
616
626
 
617
- this.browserLang = isMAC ? 'en-US' : checkAutoLangResult;
627
+ if (this.userBrowserLang) {
628
+ this.browserLang = this.userBrowserLang;
629
+ } else {
630
+ this.browserLang = checkAutoLangResult;
631
+ }
618
632
  const prefsToWrite = Object.assign(preferences, { gologin });
619
633
  if (this.customChromeFrame === false) {
620
634
  prefsToWrite.browser = {
@@ -863,6 +877,38 @@ export class GoLogin {
863
877
  return port;
864
878
  }
865
879
 
880
+ applyProfileLocale(profile) {
881
+ const timezoneConfig = profile.timezone || {};
882
+ const language = profile.navigator?.language || '';
883
+ const hasUserTimezone = timezoneConfig.fillBasedOnIp === false && Boolean(timezoneConfig.timezone);
884
+ const hasUserLanguage = profile.autoLang === false && Boolean(language);
885
+ const geolocation = profile.geolocation || {};
886
+ const geolocationFromIp = geolocation.fillBasedOnIp !== false;
887
+
888
+ if (hasUserTimezone) {
889
+ this.userTimezone = timezoneConfig.timezone;
890
+ }
891
+
892
+ if (hasUserLanguage) {
893
+ const primaryLanguage = language.split(',')[0] || '';
894
+ const browserLang = primaryLanguage.split(';')[0].trim();
895
+ if (browserLang) {
896
+ this.userBrowserLang = browserLang;
897
+ }
898
+ }
899
+
900
+ const canSkipTimezoneCheck = hasUserTimezone && hasUserLanguage && !geolocationFromIp;
901
+ if (!canSkipTimezoneCheck || this.timezone) {
902
+ return;
903
+ }
904
+
905
+ this.timezone = {
906
+ timezone: timezoneConfig.timezone,
907
+ ll: [geolocation.latitude, geolocation.longitude],
908
+ accuracy: geolocation.accuracy,
909
+ };
910
+ }
911
+
866
912
  async getTimeZone(proxy) {
867
913
  debug('getting timeZone proxy=', proxy);
868
914
 
@@ -1124,7 +1170,7 @@ export class GoLogin {
1124
1170
  params.push(`--host-resolver-rules=${hr_rules}`);
1125
1171
  }
1126
1172
 
1127
- if (proxy && Number(this.browserMajorVersion) < this.newProxyOrbitaMajorVersion) {
1173
+ if (proxy) {
1128
1174
  params.push(`--proxy-server=${proxy}`);
1129
1175
  }
1130
1176
 
@@ -1288,7 +1334,6 @@ export class GoLogin {
1288
1334
  `${SEPARATOR}Default${SEPARATOR}Code Cache`,
1289
1335
  `${SEPARATOR}Default${SEPARATOR}GPUCache`,
1290
1336
  `${SEPARATOR}Default${SEPARATOR}Extensions`,
1291
- `${SEPARATOR}Default${SEPARATOR}IndexedDB`,
1292
1337
  `${SEPARATOR}Default${SEPARATOR}GPUCache`,
1293
1338
  `${SEPARATOR}Default${SEPARATOR}DawnCache`,
1294
1339
  `${SEPARATOR}Default${SEPARATOR}fonts_config`,
@@ -1307,6 +1352,10 @@ export class GoLogin {
1307
1352
  `${SEPARATOR}BrowserMetrics-spare.pma`,
1308
1353
  ];
1309
1354
 
1355
+ if (!this.keepIndexedDb) {
1356
+ remove_dirs.push(`${SEPARATOR}Default${SEPARATOR}${INDEXED_DB_DIRECTORY}`);
1357
+ }
1358
+
1310
1359
  const that = this;
1311
1360
 
1312
1361
  await Promise.all(remove_dirs.map(d => {
@@ -1328,7 +1377,7 @@ export class GoLogin {
1328
1377
 
1329
1378
  const profilePath = this.profilePath();
1330
1379
  const { archiveProfile } = await loadProfileArchiver();
1331
- const fileBuff = await archiveProfile(profilePath);
1380
+ const fileBuff = await archiveProfile(profilePath, { keepIndexedDb: this.keepIndexedDb });
1332
1381
 
1333
1382
  debug('PROFILE ZIP CREATED', profilePath, zipPath);
1334
1383
 
@@ -13,7 +13,7 @@ const loadAdmZip = () => {
13
13
  return admZipPromise;
14
14
  };
15
15
 
16
- export const archiveProfile = async (profileFolder = '') => {
16
+ export const archiveProfile = async (profileFolder = '', { keepIndexedDb = false } = {}) => {
17
17
  const AdmZip = await loadAdmZip();
18
18
  const folderExists = await access(profileFolder).then(() => true, () => false);
19
19
  if (!folderExists) {
@@ -28,7 +28,7 @@ export const archiveProfile = async (profileFolder = '') => {
28
28
  archive.addFile('First Run', Buffer.from(''));
29
29
  }
30
30
 
31
- const dirsToRemove = getDirectoriesForArchiver();
31
+ const dirsToRemove = getDirectoriesForArchiver({ keepIndexedDb });
32
32
  dirsToRemove.forEach(entry => archive.deleteFile(entry));
33
33
 
34
34
  const archiveIsValid = checkProfileArchiveIsValid(archive);
@@ -1,3 +1,5 @@
1
+ export const INDEXED_DB_DIRECTORY = 'IndexedDB';
2
+
1
3
  const DEFAULT_FOLDER_USELESS_FILE = [
2
4
  {
3
5
  name: 'Cache',
@@ -25,7 +27,7 @@ const DEFAULT_FOLDER_USELESS_FILE = [
25
27
  isDirectory: true,
26
28
  },
27
29
  {
28
- name: 'IndexedDB',
30
+ name: INDEXED_DB_DIRECTORY,
29
31
  subs: [],
30
32
  isDirectory: true,
31
33
  },
@@ -51,8 +53,16 @@ const DEFAULT_FOLDER_USELESS_FILE = [
51
53
  },
52
54
  ];
53
55
 
54
- export const getDirectoriesToDeleteForNode = (routerSlash = '/') =>
55
- DEFAULT_FOLDER_USELESS_FILE.reduce((res, el) => {
56
+ const getFoldersToRemove = ({ keepIndexedDb = false } = {}) => {
57
+ if (!keepIndexedDb) {
58
+ return DEFAULT_FOLDER_USELESS_FILE;
59
+ }
60
+
61
+ return DEFAULT_FOLDER_USELESS_FILE.filter((folder) => folder.name !== INDEXED_DB_DIRECTORY);
62
+ };
63
+
64
+ export const getDirectoriesToDeleteForNode = (routerSlash = '/', { keepIndexedDb = false } = {}) =>
65
+ getFoldersToRemove({ keepIndexedDb }).reduce((res, el) => {
56
66
  const basePath = routerSlash + 'Default' + routerSlash + el.name;
57
67
  if (el.subs.length) {
58
68
  el.subs.forEach(sub => res.push(basePath + routerSlash + sub));
@@ -63,7 +73,7 @@ export const getDirectoriesToDeleteForNode = (routerSlash = '/') =>
63
73
  return res;
64
74
  }, []);
65
75
 
66
- export const getDirectoriesForArchiver = () => DEFAULT_FOLDER_USELESS_FILE.reduce((res, el) => {
76
+ export const getDirectoriesForArchiver = ({ keepIndexedDb = false } = {}) => getFoldersToRemove({ keepIndexedDb }).reduce((res, el) => {
67
77
  const { name, subs, isDirectory } = el;
68
78
  const basePath = 'Default/' + name;
69
79
 
File without changes