gologin 2.2.9 → 3.0.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/CHANGELOG.md CHANGED
@@ -2,6 +2,14 @@
2
2
 
3
3
  Combined changelog for GoLogin node.js SDK
4
4
 
5
+ ## [3.0.0] 2026-06-24
6
+
7
+ ### Features
8
+
9
+ * Impoved package initialization speed and profile start speed
10
+ * Replaced request npm package with native fetch
11
+
12
+
5
13
  ## [2.2.9] 2026-06-08
6
14
 
7
15
  ### Fixes
package/api.d.ts ADDED
@@ -0,0 +1,105 @@
1
+ import { Browser } from 'puppeteer-core/lib/Browser';
2
+
3
+ import { CreateCustomBrowserValidation, BrowserProxyCreateValidation } from './types/profile-params';
4
+
5
+ export declare const OPERATING_SYSTEMS: {
6
+ readonly win: 'win';
7
+ readonly lin: 'lin';
8
+ readonly mac: 'mac';
9
+ readonly android: 'android';
10
+ };
11
+ export type OsType = (typeof OPERATING_SYSTEMS)[keyof typeof OPERATING_SYSTEMS];
12
+
13
+ type CloudLaunchParams = {
14
+ cloud: true;
15
+ geolocation?: string;
16
+ };
17
+ type LocalLaunchParams = {
18
+ cloud: false;
19
+ headless: boolean;
20
+ };
21
+
22
+ type ExistingProfileLaunchParams = {
23
+ profileId: string;
24
+ };
25
+ type NewProfileLaunchParams = {
26
+ proxyGeolocation: string;
27
+ };
28
+
29
+ type LaunchParams =
30
+ | CloudLaunchParams
31
+ | LocalLaunchParams
32
+ | ExistingProfileLaunchParams
33
+ | NewProfileLaunchParams
34
+ | {
35
+ defaultDelay: number;
36
+ os: OsType;
37
+ };
38
+
39
+ type Cookie = {
40
+ name: string;
41
+ value: string;
42
+ domain: string;
43
+ path: string;
44
+ expirationDate?: number;
45
+ creationDate?: number;
46
+ hostOnly?: boolean;
47
+ httpOnly?: boolean;
48
+ sameSite?: 'no_restriction' | 'lax' | 'strict';
49
+ secure?: boolean;
50
+ session?: boolean;
51
+ url?: string;
52
+ };
53
+
54
+ type TrafficData = {
55
+ trafficUsedBytes: number;
56
+ trafficLimitBytes: number;
57
+ };
58
+
59
+ type AvailableTrafficData = {
60
+ mobileTrafficData: TrafficData;
61
+ residentialTrafficData: TrafficData;
62
+ dataCenterTrafficData: TrafficData;
63
+ };
64
+
65
+ type ProxyType = 'mobile' | 'resident' | 'dataCenter';
66
+
67
+ type ProxyResponse = {
68
+ trafficLimitBytes: number;
69
+ trafficUsedBytes: number;
70
+ };
71
+
72
+ type ProfileResponse = {
73
+ id: string;
74
+ };
75
+
76
+ type GologinApiType = {
77
+ launch: (params?: LaunchParams) => Promise<{ browser: Browser }>;
78
+ createProfileWithCustomParams: (options: CreateCustomBrowserValidation) => Promise<string>;
79
+ refreshProfilesFingerprint: (profileIds: string[]) => Promise<Record<string, unknown>>;
80
+ createProfileRandomFingerprint: (name?: string) => Promise<ProfileResponse>;
81
+ updateUserAgentToLatestBrowser: (profileIds: string[], workspaceId?: string) => Promise<Record<string, unknown>>;
82
+ changeProfileProxy: (profileId: string, proxyData: BrowserProxyCreateValidation) => Promise<number>;
83
+ getAvailableType: (availableTrafficData: AvailableTrafficData) => ProxyType | 'none';
84
+ addGologinProxyToProfile: (profileId: string, countryCode: string, proxyType?: ProxyType | '') => Promise<ProxyResponse>;
85
+ addCookiesToProfile: (profileId: string, cookies: Cookie[]) => Promise<number>;
86
+ deleteProfile: (profileId: string) => Promise<number>;
87
+ exit: () => Promise<void>;
88
+ createCustom: (params: CreateCustomBrowserValidation) => Promise<string>;
89
+ updateProfileFingerprint: (profileId: string[]) => Promise<void>;
90
+ updateProfileProxy: (profileId: string, proxyData: BrowserProxyCreateValidation) => Promise<void>;
91
+ };
92
+
93
+ type GologinApiParams = {
94
+ token: string;
95
+ };
96
+
97
+ export declare function getDefaultParams(): {
98
+ token: string | undefined;
99
+ profile_id: string | undefined;
100
+ executablePath: string | undefined;
101
+ };
102
+
103
+ export declare function GologinApi(params: GologinApiParams): GologinApiType;
104
+
105
+ export declare function exitAll(): Promise<void>;
package/index.d.ts CHANGED
@@ -1,100 +1,3 @@
1
- import { Browser } from 'puppeteer-core/lib/Browser';
2
-
3
- import { CreateCustomBrowserValidation, BrowserProxyCreateValidation } from './types/profile-params';
4
-
5
- export declare const OPERATING_SYSTEMS: {
6
- readonly win: 'win';
7
- readonly lin: 'lin';
8
- readonly mac: 'mac';
9
- readonly android: 'android';
10
- };
11
- export type OsType = (typeof OPERATING_SYSTEMS)[keyof typeof OPERATING_SYSTEMS];
12
-
13
- type CloudLaunchParams = {
14
- cloud: true;
15
- geolocation?: string;
16
- };
17
- type LocalLaunchParams = {
18
- cloud: false;
19
- headless: boolean;
20
- };
21
-
22
- type ExistingProfileLaunchParams = {
23
- profileId: string;
24
- };
25
- type NewProfileLaunchParams = {
26
- proxyGeolocation: string;
27
- };
28
-
29
- type LaunchParams =
30
- | CloudLaunchParams
31
- | LocalLaunchParams
32
- | ExistingProfileLaunchParams
33
- | NewProfileLaunchParams
34
- | {
35
- defaultDelay: number;
36
- os: OsType;
37
- };
38
-
39
- type Cookie = {
40
- name: string;
41
- value: string;
42
- domain: string;
43
- path: string;
44
- expirationDate?: number;
45
- creationDate?: number;
46
- hostOnly?: boolean;
47
- httpOnly?: boolean;
48
- sameSite?: 'no_restriction' | 'lax' | 'strict';
49
- secure?: boolean;
50
- session?: boolean;
51
- url?: string;
52
- };
53
-
54
- type TrafficData = {
55
- trafficUsedBytes: number;
56
- trafficLimitBytes: number;
57
- };
58
-
59
- type AvailableTrafficData = {
60
- mobileTrafficData: TrafficData;
61
- residentialTrafficData: TrafficData;
62
- dataCenterTrafficData: TrafficData;
63
- };
64
-
65
- type ProxyType = 'mobile' | 'resident' | 'dataCenter';
66
-
67
- type ProxyResponse = {
68
- trafficLimitBytes: number;
69
- trafficUsedBytes: number;
70
- };
71
-
72
- type ProfileResponse = {
73
- id: string;
74
- };
75
-
76
- type GologinApiType = {
77
- launch: (params?: LaunchParams) => Promise<{ browser: Browser }>;
78
- createProfileWithCustomParams: (options: CreateCustomBrowserValidation) => Promise<string>;
79
- refreshProfilesFingerprint: (profileIds: string[]) => Promise<any>;
80
- createProfileRandomFingerprint: (name?: string) => Promise<ProfileResponse>;
81
- updateUserAgentToLatestBrowser: (profileIds: string[], workspaceId?: string) => Promise<any>;
82
- changeProfileProxy: (profileId: string, proxyData: BrowserProxyCreateValidation) => Promise<number>;
83
- getAvailableType: (availableTrafficData: AvailableTrafficData) => ProxyType | 'none';
84
- addGologinProxyToProfile: (profileId: string, countryCode: string, proxyType?: ProxyType | '') => Promise<ProxyResponse>;
85
- addCookiesToProfile: (profileId: string, cookies: Cookie[]) => Promise<number>;
86
- deleteProfile: (profileId: string) => Promise<number>;
87
- exit: () => Promise<void>;
88
- createCustom: (params: CreateCustomBrowserValidation) => Promise<string>;
89
- updateProfileFingerprint: (profileId: string[]) => Promise<void>;
90
- updateProfileProxy: (profileId: string, proxyData: BrowserProxyCreateValidation) => Promise<void>;
91
- };
92
-
93
- type GologinApiParams = {
94
- token: string;
95
- };
96
-
97
- /** Options for the GoLogin class constructor (advanced usage, custom wrappers). */
98
1
  export type GoLoginOptions = {
99
2
  token?: string;
100
3
  profile_id?: string;
@@ -109,7 +12,7 @@ export type GoLoginOptions = {
109
12
  uploadCookiesToServer?: boolean;
110
13
  writeCookiesFromServer?: boolean;
111
14
  remote_debugging_port?: number;
112
- timezone?: { timezone: string; country?: string; city?: string; ip?: string; ll?: [number, number]; accuracy?: number, stateProv?: string, languages?: string };
15
+ timezone?: { timezone: string; country?: string; city?: string; ip?: string; ll?: [number, number]; accuracy?: number, stateProv?: string, languages?: string };
113
16
  args?: string[];
114
17
  restoreLastSession?: boolean;
115
18
  browserMajorVersion?: number;
@@ -119,25 +22,14 @@ export type GoLoginOptions = {
119
22
  checkBrowserUpdate?: boolean;
120
23
  };
121
24
 
122
- /** Return type of GoLogin#start() — use wsUrl to connect with Puppeteer. */
123
25
  export type GoLoginStartResult = {
124
26
  status: 'success';
125
27
  wsUrl: string;
126
28
  resolution?: { width: number; height: number };
127
29
  };
128
30
 
129
- /**
130
- * GoLogin class for advanced usage and custom wrappers.
131
- * Use when you need direct control over the browser lifecycle (e.g. custom launchLocal,
132
- * multiple instances, or access to wsUrl from start() for Puppeteer).
133
- *
134
- * @example
135
- * import { GoLogin } from 'gologin';
136
- * const gologin = new GoLogin({ token: 'YOUR_TOKEN', profile_id: 'PROFILE_ID' });
137
- * const { wsUrl } = await gologin.start();
138
- * // connect with puppeteer.connect({ browserWSEndpoint: wsUrl })
139
- * await gologin.stop();
140
- */
31
+ export { GologinApi, getDefaultParams, exitAll } from './api.d.ts';
32
+
141
33
  export declare class GoLogin {
142
34
  constructor(options?: GoLoginOptions);
143
35
  start(): Promise<GoLoginStartResult>;
@@ -151,12 +43,4 @@ export declare class GoLogin {
151
43
  commitProfile(): Promise<void>;
152
44
  }
153
45
 
154
- export declare function getDefaultParams(): {
155
- token: string | undefined;
156
- profile_id: string | undefined;
157
- executablePath: string | undefined;
158
- };
159
-
160
- export declare function GologinApi(params: GologinApiParams): GologinApiType;
161
-
162
- export declare function exitAll(): Promise<void>;
46
+ export default GoLogin;
package/package.json CHANGED
@@ -1,9 +1,19 @@
1
1
  {
2
2
  "name": "gologin",
3
- "version": "2.2.9",
3
+ "version": "3.0.0",
4
4
  "description": "A high-level API to control Orbita browser over GoLogin API",
5
5
  "types": "./index.d.ts",
6
- "main": "./src/gologin.js",
6
+ "main": "./src/index.js",
7
+ "exports": {
8
+ ".": {
9
+ "types": "./index.d.ts",
10
+ "import": "./src/index.js"
11
+ },
12
+ "./api": {
13
+ "types": "./api.d.ts",
14
+ "import": "./src/gologin-api.js"
15
+ }
16
+ },
7
17
  "repository": {
8
18
  "type": "git",
9
19
  "url": "git+https://github.com/gologinapp/gologin.git"
@@ -14,6 +24,9 @@
14
24
  "type": "module",
15
25
  "author": "The GoLogin Authors",
16
26
  "license": "GPL-3.0",
27
+ "overrides": {
28
+ "https-proxy-agent": "$https-proxy-agent"
29
+ },
17
30
  "dependencies": {
18
31
  "@sentry/node": "^9.24.0",
19
32
  "adm-zip": "^0.5.1",
@@ -22,10 +35,9 @@
22
35
  "decompress": "^4.2.1",
23
36
  "decompress-unzip": "^4.0.1",
24
37
  "form-data": "^3.0.0",
38
+ "https-proxy-agent": "^7.0.6",
25
39
  "progress": "^2.0.3",
26
40
  "puppeteer-core": "^2.1.1",
27
- "request": "^2.88.2",
28
- "requestretry": "^4.1.0",
29
41
  "rimraf": "^3.0.2",
30
42
  "socks-proxy-agent": "^8.0.3",
31
43
  "sqlite": "^4.0.23",
@@ -1,6 +1,4 @@
1
1
  import { exec as execNonPromise } from 'child_process';
2
- import decompress from 'decompress';
3
- import decompressUnzip from 'decompress-unzip';
4
2
  import { createWriteStream, promises as _promises } from 'fs';
5
3
  import { get } from 'https';
6
4
  import { homedir } from 'os';
@@ -10,6 +8,7 @@ import util from 'util';
10
8
 
11
9
  import { API_URL, getOS } from '../utils/common.js';
12
10
  import { makeRequest } from '../utils/http.js';
11
+ import { loadDecompress } from '../utils/lazy-deps.js';
13
12
  import BrowserDownloadLockManager from './browser-download-manager.js';
14
13
 
15
14
  const exec = util.promisify(execNonPromise);
@@ -202,6 +201,8 @@ export class BrowserChecker {
202
201
  console.log('Extracting Orbita');
203
202
  await mkdir(join(this.browserPath, EXTRACTED_FOLDER), { recursive: true });
204
203
  if (PLATFORM === 'win32') {
204
+ const { decompress, decompressUnzip } = await loadDecompress();
205
+
205
206
  return decompress(join(this.browserPath, BROWSER_ARCHIVE_NAME), join(this.browserPath, EXTRACTED_FOLDER),
206
207
  {
207
208
  plugins: [decompressUnzip()],
@@ -1,24 +1,13 @@
1
1
  import { createHash } from 'crypto';
2
- import { createWriteStream, promises as _promises, rmdirSync } from 'fs';
3
- import { homedir, tmpdir } from 'os';
4
- import { dirname, join, resolve, sep } from 'path';
5
- import { fileURLToPath } from 'url';
2
+ import { promises as _promises } from 'fs';
3
+ import { tmpdir } from 'os';
4
+ import { join, sep } from 'path';
6
5
 
7
- import { fontsCollection } from '../../fonts.js';
8
6
  import { FALLBACK_API_URL } from '../utils/common.js';
9
7
  import { makeRequest } from '../utils/http.js';
10
8
 
11
- const { access, readFile, writeFile, mkdir, readdir, copyFile, rename } = _promises;
9
+ const { readFile, readdir, rename } = _promises;
12
10
 
13
- const __filename = fileURLToPath(import.meta.url);
14
- const __dirname = dirname(__filename);
15
-
16
- const FONTS_URL = 'https://fonts.gologin.com/';
17
- const FONTS_DIR_NAME = 'fonts';
18
-
19
- const HOMEDIR = homedir();
20
- const BROWSER_PATH = join(HOMEDIR, '.gologin', 'browser');
21
- const OS_PLATFORM = process.platform;
22
11
  const DEFAULT_ORBITA_EXTENSIONS_NAMES = ['Google Hangouts', 'Chromium PDF Viewer', 'CryptoTokenExtension', 'Web Store'];
23
12
  const GOLOGIN_BASE_FOLDER_NAME = '.gologin';
24
13
  const GOLOGIN_TEST_FOLDER_NAME = '.gologin_test';
@@ -56,80 +45,6 @@ export const uploadCookies = ({ cookies = [], profileId, ACCESS_TOKEN, API_BASE_
56
45
  return e;
57
46
  });
58
47
 
59
- export const downloadFonts = async (fontsList = [], profilePath) => {
60
- if (!fontsList.length) {
61
- return;
62
- }
63
-
64
- const browserFontsPath = join(BROWSER_PATH, FONTS_DIR_NAME);
65
- await mkdir(browserFontsPath, { recursive: true });
66
-
67
- const files = await readdir(browserFontsPath);
68
- const fontsToDownload = fontsList.filter(font => !files.includes(font));
69
-
70
- let promises = fontsToDownload.map(async font => {
71
- const body = await makeRequest(FONTS_URL + font, {
72
- maxAttempts: 5,
73
- retryDelay: 2000,
74
- timeout: 30 * 1000,
75
- });
76
-
77
- await writeFile(join(browserFontsPath, font), body);
78
- });
79
-
80
- if (promises.length) {
81
- await Promise.all(promises);
82
- }
83
-
84
- promises = fontsList.map((font) =>
85
- copyFile(join(browserFontsPath, font), join(profilePath, FONTS_DIR_NAME, font)));
86
-
87
- await Promise.all(promises);
88
- };
89
-
90
- export const composeFonts = async (fontsList = [], profilePath, differentOs = false) => {
91
- if (!(fontsList.length && profilePath)) {
92
- return;
93
- }
94
-
95
- const fontsToDownload = fontsCollection
96
- .filter(elem => fontsList.includes(elem.value))
97
- .reduce((res, elem) => res.concat(elem.fileNames || []), []);
98
-
99
- if (differentOs && !fontsToDownload.length) {
100
- throw new Error('No fonts to download found. Use getAvailableFonts() method and set some fonts from this list');
101
- }
102
-
103
- fontsToDownload.push('LICENSE.txt');
104
- fontsToDownload.push('OFL.txt');
105
-
106
- const pathToFontsDir = join(profilePath, FONTS_DIR_NAME);
107
- const fontsDirExists = await access(pathToFontsDir).then(() => true, () => false);
108
- if (fontsDirExists) {
109
- rmdirSync(pathToFontsDir, { recursive: true });
110
- }
111
-
112
- await mkdir(pathToFontsDir, { recursive: true });
113
- await downloadFonts(fontsToDownload, profilePath);
114
-
115
- if (OS_PLATFORM === 'linux') {
116
- await copyFontsConfigFile(profilePath);
117
- }
118
- };
119
-
120
- export const copyFontsConfigFile = async (profilePath) => {
121
- if (!profilePath) {
122
- return;
123
- }
124
-
125
- const fileContent = await readFile(resolve(__dirname, '..', '..', 'fonts_config'), 'utf-8');
126
- const result = fileContent.replace(/\$\$GOLOGIN_FONTS\$\$/g, join(profilePath, FONTS_DIR_NAME));
127
-
128
- const defaultFolderPath = join(profilePath, 'Default');
129
- await mkdir(defaultFolderPath, { recursive: true });
130
- await writeFile(join(defaultFolderPath, 'fonts_config'), result);
131
- };
132
-
133
48
  export const setExtPathsAndRemoveDeleted = (settings = {}, profileExtensionsCheckRes = [], profileId = '') => {
134
49
  const formattedLocalExtArray = profileExtensionsCheckRes.map((el) => {
135
50
  const [extFolderName = ''] = el.split(sep).reverse();
@@ -1,12 +1,9 @@
1
1
  import { promises as fsPromises } from 'fs';
2
2
  import { join } from 'path';
3
- import { open } from 'sqlite';
4
- import sqlite3 from 'sqlite3';
5
3
 
6
4
  import { ensureDirectoryExists } from '../utils/common.js';
7
5
 
8
6
  const { access } = fsPromises;
9
- const { Database, OPEN_READONLY } = sqlite3;
10
7
 
11
8
  const MAX_SQLITE_VARIABLES = 76;
12
9
 
@@ -17,7 +14,27 @@ const SAME_SITE = {
17
14
  2: 'strict',
18
15
  };
19
16
 
20
- export const getDB = (filePath, readOnly = true) => {
17
+ let sqliteModulePromise = null;
18
+
19
+ const loadSqlite = () => {
20
+ sqliteModulePromise ||= Promise.all([
21
+ import('sqlite'),
22
+ import('sqlite3'),
23
+ ]).then(([sqliteModule, sqlite3Module]) => {
24
+ const sqlite3 = sqlite3Module.default ?? sqlite3Module;
25
+
26
+ return {
27
+ open: sqliteModule.open,
28
+ Database: sqlite3.Database,
29
+ OPEN_READONLY: sqlite3.OPEN_READONLY,
30
+ };
31
+ });
32
+
33
+ return sqliteModulePromise;
34
+ };
35
+
36
+ export const getDB = async (filePath, readOnly = true) => {
37
+ const { open, Database, OPEN_READONLY } = await loadSqlite();
21
38
  const connectionOpts = {
22
39
  filename: filePath,
23
40
  driver: Database,
@@ -35,11 +52,12 @@ export const createDBFile = async ({
35
52
  cookiesFileSecondPath,
36
53
  createCookiesTableQuery,
37
54
  }) => {
55
+ const { open, Database } = await loadSqlite();
38
56
  await fsPromises.writeFile(cookiesFilePath, '', { mode: 0o666 });
39
57
 
40
58
  const connectionOpts = {
41
59
  filename: cookiesFilePath,
42
- driver: sqlite3.Database,
60
+ driver: Database,
43
61
  };
44
62
 
45
63
  const db = await open(connectionOpts);
@@ -77,7 +95,6 @@ export const getChunckedInsertValues = (cookiesArr) => {
77
95
 
78
96
  const sourceScheme = isSecure === 1 ? 2 : 1;
79
97
  const sourcePort = isSecure === 1 ? 443 : 80;
80
- // eslint-disable-next-line no-undefined
81
98
  let isPersistent = [undefined, null].includes(cookie.session)
82
99
  ? Number(expirationDate !== 0)
83
100
  : Number(!cookie.session);
@@ -90,23 +107,23 @@ export const getChunckedInsertValues = (cookiesArr) => {
90
107
  return [
91
108
  creationDate,
92
109
  cookie.domain,
93
- '', // top_frame_site_key
110
+ '',
94
111
  cookie.name,
95
- '', // value
112
+ '',
96
113
  encryptedValue,
97
114
  cookie.path,
98
115
  expirationDate,
99
116
  isSecure,
100
117
  Number(cookie.httpOnly),
101
- 0, // last_access_utc
102
- expirationDate === 0 ? 0 : 1, // has_expires
118
+ 0,
119
+ expirationDate === 0 ? 0 : 1,
103
120
  isPersistent,
104
- 1, // default priority value (https://github.com/chromium/chromium/blob/main/net/cookies/cookie_constants.h)
121
+ 1,
105
122
  samesite,
106
123
  sourceScheme,
107
124
  sourcePort,
108
- 0, // is_same_party
109
- 0, // last_update_utc
125
+ 0,
126
+ 0,
110
127
  ];
111
128
  });
112
129
 
@@ -1,14 +1,16 @@
1
- import decompress from 'decompress';
2
- import decompressUnzip from 'decompress-unzip';
3
1
  import { promises } from 'fs';
4
2
 
3
+ import { loadDecompress } from '../utils/lazy-deps.js';
4
+
5
5
  const { access, unlink } = promises;
6
6
 
7
- export const extractExtension = (source, dest) => {
7
+ export const extractExtension = async (source, dest) => {
8
8
  if (!(source && dest)) {
9
9
  throw new Error('Missing parameter');
10
10
  }
11
11
 
12
+ const { decompress, decompressUnzip } = await loadDecompress();
13
+
12
14
  return access(source)
13
15
  .then(() =>
14
16
  withRetry({
@@ -20,7 +22,7 @@ export const extractExtension = (source, dest) => {
20
22
  },
21
23
  }),
22
24
  );
23
- }
25
+ };
24
26
 
25
27
  export const deleteExtensionArchive = (dest) => {
26
28
  if (!dest) {
@@ -32,7 +34,7 @@ export const deleteExtensionArchive = (dest) => {
32
34
  () => unlink(dest),
33
35
  () => Promise.resolve(),
34
36
  );
35
- }
37
+ };
36
38
 
37
39
  const withRetry = optionsOrUndefined => {
38
40
  const opts = optionsOrUndefined || {};
@@ -1,10 +1,9 @@
1
1
  import { createWriteStream, promises as _promises } from 'fs';
2
2
  import { join, sep } from 'path';
3
- import request from 'requestretry';
4
3
 
5
4
  import { CHROME_EXTENSIONS_PATH, composeExtractionPromises, USER_EXTENSIONS_PATH } from '../utils/common.js';
6
5
  import UserExtensionsManager from './user-extensions-manager.js';
7
- import { makeRequest } from '../utils/http.js';
6
+ import { fetchBufferWithRetry, fetchHeadWithRetry, makeRequest } from '../utils/http.js';
8
7
  import { FALLBACK_API_URL } from '../utils/common.js';
9
8
 
10
9
  const { mkdir, readdir, rmdir, unlink } = _promises;
@@ -134,19 +133,11 @@ export class ExtensionsManager extends UserExtensionsManager {
134
133
  const reqPath = uploadedProfileMetadata.req.path;
135
134
  const extVer = getExtVersion(reqPath);
136
135
 
137
- const buffer = await new Promise((res) => {
138
- const chunks = [];
139
- console.log('extUrl', extUrl);
140
- request.get(extUrl, {
141
- maxAttempts: 3,
142
- retryDelay: 1000,
143
- timeout: 8 * 1000,
144
- fullResponse: false,
145
- })
146
- .on('data', (data) => chunks.push(data))
147
- .on('end', () => res(Buffer.concat(chunks)));
136
+ const buffer = await fetchBufferWithRetry(extUrl, {
137
+ maxAttempts: 3,
138
+ retryDelay: 1000,
139
+ timeout: 8 * 1000,
148
140
  });
149
- console.log('buffer', buffer);
150
141
  let zipExt;
151
142
  try {
152
143
  zipExt = crxToZip(buffer);
@@ -357,14 +348,11 @@ const calcLength = (a, b, c, d) => {
357
348
  return length;
358
349
  };
359
350
 
360
- const getExtMetadata = (extUrl) => (
361
- request.head(extUrl, {
362
- maxAttempts: 3,
363
- retryDelay: 2000,
364
- timeout: 2 * 1000,
365
- fullResponse: true,
366
- })
367
- );
351
+ const getExtMetadata = (extUrl) => fetchHeadWithRetry(extUrl, {
352
+ maxAttempts: 3,
353
+ retryDelay: 2000,
354
+ timeout: 2 * 1000,
355
+ });
368
356
 
369
357
  const getExtVersion = (metadata) => {
370
358
  const [extFullName = ''] = metadata.split('/').reverse();
@@ -1,9 +1,8 @@
1
1
  import { createWriteStream, promises as _promises } from 'fs';
2
2
  import { join, sep } from 'path';
3
- import request from 'requestretry';
4
3
 
5
4
  import { CHROME_EXTENSIONS_PATH, composeExtractionPromises, FALLBACK_API_URL, USER_EXTENSIONS_PATH } from '../utils/common.js';
6
- import { makeRequest } from '../utils/http.js';
5
+ import { fetchToWriteStream, makeRequest } from '../utils/http.js';
7
6
 
8
7
  const { readdir, readFile, stat, mkdir, copyFile } = _promises;
9
8
 
@@ -105,12 +104,10 @@ export class UserExtensionsManager {
105
104
  const zipPath = `${join(USER_EXTENSIONS_PATH, extId)}.zip`;
106
105
  const archiveZip = createWriteStream(zipPath);
107
106
 
108
- await request(awsPath, {
107
+ await fetchToWriteStream(awsPath, archiveZip, {
109
108
  retryDelay: 2 * 1000,
110
109
  maxAttempts: 3,
111
- }).pipe(archiveZip);
112
-
113
- await new Promise(r => archiveZip.on('close', () => r()));
110
+ });
114
111
 
115
112
  return zipPath;
116
113
  });