gologin 2.2.9 → 3.0.1

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.
@@ -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
  });
@@ -1,5 +1,3 @@
1
- import puppeteer from 'puppeteer-core';
2
-
3
1
  import GoLogin from './gologin.js';
4
2
  import { API_URL, FALLBACK_API_URL, getOsAdvanced } from './utils/common.js';
5
3
  import { makeRequest } from './utils/http.js';
@@ -7,6 +5,20 @@ import { makeRequest } from './utils/http.js';
7
5
  const trafficLimitMessage =
8
6
  'You dont have free traffic to use the proxy. Please go to app https://app.gologin.com/ and buy some traffic if you want to use the proxy';
9
7
 
8
+ let puppeteerModulePromise = null;
9
+
10
+ const loadPuppeteer = () => {
11
+ puppeteerModulePromise ||= import('puppeteer-core').then((module) => module.default ?? module);
12
+
13
+ return puppeteerModulePromise;
14
+ };
15
+
16
+ const connectToBrowser = async (options) => {
17
+ const puppeteer = await loadPuppeteer();
18
+
19
+ return puppeteer.connect(options);
20
+ };
21
+
10
22
  export const getDefaultParams = () => ({
11
23
  token: process.env.GOLOGIN_API_TOKEN,
12
24
  profile_id: process.env.GOLOGIN_PROFILE_ID,
@@ -48,7 +60,7 @@ export const GologinApi = ({ token }) => {
48
60
 
49
61
  const startedProfile = await legacyGologin.start();
50
62
 
51
- const browser = await puppeteer.connect({
63
+ const browser = await connectToBrowser({
52
64
  browserWSEndpoint: startedProfile.wsUrl,
53
65
  ignoreHTTPSErrors: true,
54
66
  defaultViewport: null,
@@ -75,7 +87,7 @@ export const GologinApi = ({ token }) => {
75
87
  legacyGls.push(legacyGologin);
76
88
 
77
89
  const browserWSEndpoint = `https://cloudbrowser.gologin.com/connect?token=${token}&profile=${params.profileId}`;
78
- const browser = await puppeteer.connect({
90
+ const browser = await connectToBrowser({
79
91
  browserWSEndpoint,
80
92
  ignoreHTTPSErrors: true,
81
93
  });
package/src/gologin.js CHANGED
@@ -1,39 +1,32 @@
1
- import * as Sentry from '@sentry/node';
2
1
  import { execFile, spawn } from 'child_process';
3
2
  import debugDefault from 'debug';
4
- import decompress from 'decompress';
5
- import decompressUnzip from 'decompress-unzip';
6
3
  import { existsSync, mkdirSync, promises as _promises } from 'fs';
7
4
  import { tmpdir } from 'os';
8
5
  import { join, resolve as _resolve, sep } from 'path';
9
- import rimraf from 'rimraf';
10
- import { SocksProxyAgent } from 'socks-proxy-agent';
11
6
 
12
- import { fontsCollection } from '../fonts.js';
13
7
  import { getCurrentProfileBookmarks } from './bookmarks/utils.js';
14
8
  import { updateProfileBookmarks, updateProfileProxy, updateProfileResolution, updateProfileUserAgent } from './browser/browser-api.js';
15
- import BrowserChecker from './browser/browser-checker.js';
16
9
  import {
17
- composeFonts, downloadCookies, setExtPathsAndRemoveDeleted, setOriginalExtPaths, uploadCookies,
10
+ downloadCookies, setExtPathsAndRemoveDeleted, setOriginalExtPaths, uploadCookies,
18
11
  } from './browser/browser-user-data-manager.js';
19
- import {
20
- createDBFile,
21
- getChunckedInsertValues,
22
- getCookiesFilePath,
23
- getDB,
24
- getUniqueCookies,
25
- loadCookiesFromFile,
26
- } from './cookies/cookies-manager.js';
27
- import ExtensionsManager from './extensions/extensions-manager.js';
28
- import { archiveProfile } from './profile/profile-archiver.js';
12
+ import { getProfileChromeExtensions } from './extensions/get-extensions.js';
29
13
  import { checkAutoLang, getIntlProfileConfig, securedOrbitaOpts } from './utils/browser.js';
30
14
  import { API_URL, ensureDirectoryExists, FALLBACK_API_URL, getOsAdvanced } from './utils/common.js';
31
15
  import { STORAGE_GATEWAY_BASE_URL } from './utils/constants.js';
32
- import { get, isPortReachable } from './utils/utils.js';
33
- export { exitAll, GologinApi } from './gologin-api.js';
34
- import { getProfileChromeExtensions } from './extensions/get-extensions.js';
35
16
  import { checkSocksProxy, makeRequest } from './utils/http.js';
36
- import { captureGroupedSentryError } from './utils/sentry.js';
17
+ import {
18
+ // ensureSentryInitialized,
19
+ loadBrowserChecker,
20
+ loadCookiesManager,
21
+ loadDecompress,
22
+ loadExtensionsManager,
23
+ loadProfileArchiver,
24
+ loadSocksProxyAgent,
25
+ preloadStartupDeps,
26
+ removePath,
27
+ } from './utils/lazy-deps.js';
28
+ import { get, isPortReachable } from './utils/utils.js';
29
+ // import { captureGroupedSentryError } from './utils/sentry.js';
37
30
  import { zeroProfileBookmarks } from './utils/zero-profile-bookmarks.js';
38
31
  import { zeroProfilePreferences } from './utils/zero-profile-preferences.js';
39
32
 
@@ -70,7 +63,8 @@ export class GoLogin {
70
63
  this.tmpdir = tmpdir();
71
64
  this.autoUpdateBrowser = !!options.autoUpdateBrowser;
72
65
  this.checkBrowserUpdate = options.checkBrowserUpdate ?? true;
73
- this.browserChecker = new BrowserChecker(options.skipOrbitaHashChecking);
66
+ this._skipOrbitaHashChecking = options.skipOrbitaHashChecking;
67
+ this._browserChecker = null;
74
68
  this.uploadCookiesToServer = options.uploadCookiesToServer || false;
75
69
  this.writeCookiesFromServer = options.writeCookiesFromServer ?? true;
76
70
  this.remote_debugging_port = options.remote_debugging_port || 0;
@@ -85,15 +79,6 @@ export class GoLogin {
85
79
  this.proxyCheckTimeout = options.proxyCheckTimeout || 13 * 1000;
86
80
  this.proxyCheckAttempts = options.proxyCheckAttempts || 3;
87
81
 
88
- if (process.env.DISABLE_TELEMETRY !== 'true') {
89
- Sentry.init({
90
- dsn: 'https://a13d5939a60ae4f6583e228597f1f2a0@sentry-new.amzn.pro/24',
91
- tracesSampleRate: 1.0,
92
- defaultIntegrations: false,
93
- release: process.env.npm_package_version || '2.1.34',
94
- });
95
- }
96
-
97
82
  if (options.tmpdir) {
98
83
  this.tmpdir = options.tmpdir;
99
84
  if (!existsSync(this.tmpdir)) {
@@ -107,8 +92,18 @@ export class GoLogin {
107
92
  debug('INIT GOLOGIN', this.profile_id);
108
93
  }
109
94
 
95
+ async getBrowserChecker() {
96
+ if (!this._browserChecker) {
97
+ const BrowserChecker = await loadBrowserChecker();
98
+ this._browserChecker = new BrowserChecker(this._skipOrbitaHashChecking);
99
+ }
100
+
101
+ return this._browserChecker;
102
+ }
103
+
110
104
  async checkBrowser(majorVersion) {
111
- this.executablePath = await this.browserChecker.checkBrowser({
105
+ const browserChecker = await this.getBrowserChecker();
106
+ this.executablePath = await browserChecker.checkBrowser({
112
107
  autoUpdateBrowser: this.autoUpdateBrowser,
113
108
  checkBrowserUpdate: this.checkBrowserUpdate,
114
109
  majorVersion,
@@ -130,7 +125,8 @@ export class GoLogin {
130
125
  }
131
126
 
132
127
  for (const majorVersion of versionsToDownload) {
133
- await this.browserChecker.checkBrowser({
128
+ const browserChecker = await this.getBrowserChecker();
129
+ await browserChecker.checkBrowser({
134
130
  autoUpdateBrowser: true,
135
131
  checkBrowserUpdate: true,
136
132
  majorVersion,
@@ -141,7 +137,8 @@ export class GoLogin {
141
137
  }
142
138
 
143
139
  async getLatestBrowserVersion() {
144
- const { latestVersion: browserLatestVersion } = await this.browserChecker.getLatestBrowserVersion();
140
+ const browserChecker = await this.getBrowserChecker();
141
+ const { latestVersion: browserLatestVersion } = await browserChecker.getLatestBrowserVersion();
145
142
  const [latestBrowserMajorVersion] = browserLatestVersion.split('.');
146
143
 
147
144
  return Number(latestBrowserMajorVersion);
@@ -149,6 +146,7 @@ export class GoLogin {
149
146
 
150
147
  async setProfileId(profile_id) {
151
148
  this.profile_id = profile_id;
149
+ const { getCookiesFilePath } = await loadCookiesManager();
152
150
  this.cookiesFilePath = await getCookiesFilePath(profile_id, this.tmpdir);
153
151
  this.profile_zip_path = join(this.tmpdir, `gologin_${this.profile_id}.zip`);
154
152
  this.bookmarksFilePath = join(this.tmpdir, `gologin_profile_${this.profile_id}`, 'Default', 'Bookmarks');
@@ -359,10 +357,11 @@ export class GoLogin {
359
357
  async createBrowserExtension() {
360
358
  const that = this;
361
359
  debug('start createBrowserExtension');
362
- await rimraf(this.orbitaExtensionPath(), () => null);
360
+ await removePath(this.orbitaExtensionPath());
363
361
  const extPath = this.orbitaExtensionPath();
364
362
  debug('extension folder sanitized');
365
363
  const extension_source = _resolve(__dirname, 'gologin-browser-ext.zip');
364
+ const { decompress, decompressUnzip } = await loadDecompress();
366
365
  await decompress(extension_source, extPath,
367
366
  {
368
367
  plugins: [decompressUnzip()],
@@ -383,8 +382,9 @@ export class GoLogin {
383
382
  debug('createBrowserExtension done');
384
383
  }
385
384
 
386
- extractProfile(path, zipfile) {
385
+ async extractProfile(path, zipfile) {
387
386
  debug(`extactProfile ${zipfile}, ${path}`);
387
+ const { decompress, decompressUnzip } = await loadDecompress();
388
388
 
389
389
  return decompress(zipfile, path,
390
390
  {
@@ -402,15 +402,19 @@ export class GoLogin {
402
402
 
403
403
  if (!(local && profileZipExists)) {
404
404
  try {
405
- profile_folder = await this.getProfileS3();
405
+ const [, profileData] = await Promise.all([
406
+ loadDecompress(),
407
+ this.getProfileS3(),
408
+ ]);
409
+
410
+ profile_folder = profileData;
406
411
  } catch (e) {
407
412
  debug('Cannot get profile - using empty', e);
413
+ await loadDecompress();
408
414
  }
409
415
 
410
416
  debug('FILE READY', this.profile_zip_path);
411
-
412
417
  await writeFile(this.profile_zip_path, profile_folder);
413
-
414
418
  debug('PROFILE LENGTH', profile_folder.length);
415
419
  } else {
416
420
  debug('PROFILE LOCAL HAVING', this.profile_zip_path);
@@ -436,6 +440,7 @@ export class GoLogin {
436
440
  }
437
441
 
438
442
  async createZeroProfile(createCookiesTableQuery) {
443
+ const { createDBFile } = await loadCookiesManager();
439
444
  const profilePath = join(this.tmpdir, `gologin_profile_${this.profile_id}`);
440
445
  const defaultFilePath = _resolve(profilePath, 'Default');
441
446
  const preferencesFilePath = _resolve(defaultFilePath, 'Preferences');
@@ -458,10 +463,12 @@ export class GoLogin {
458
463
 
459
464
  async createStartup(local = false) {
460
465
  const profilePath = join(this.tmpdir, `gologin_profile_${this.profile_id}`);
466
+ const startupDepsPromise = preloadStartupDeps();
461
467
 
462
468
  const [profile] = await Promise.all([
463
469
  this.getProfile(),
464
- new Promise((resolve) => rimraf(profilePath, resolve)).then(() => debug('-', profilePath, 'dropped')),
470
+ startupDepsPromise.then(() => removePath(profilePath)
471
+ .then(() => debug('-', profilePath, 'dropped'))),
465
472
  ]);
466
473
 
467
474
  if (!profile) {
@@ -544,7 +551,9 @@ export class GoLogin {
544
551
  const allExtensions = [...chromeExtensions, ...userChromeExtensions];
545
552
 
546
553
  const [, orbitaParamsToken] = await Promise.all([
547
- this.setupProfileExtensions({ preferences, allExtensions, userChromeExtensions, profilePath }),
554
+ this.setupProfileExtensions({
555
+ preferences, allExtensions, userChromeExtensions, profilePath,
556
+ }),
548
557
  this.fetchOrbitaParamsToken(profile),
549
558
  ]);
550
559
 
@@ -553,13 +562,6 @@ export class GoLogin {
553
562
  if (!families.length) {
554
563
  this.isEmptyFonts = true;
555
564
  }
556
-
557
- try {
558
- // TODO: uncomment this when fonts will be fixed
559
- // await composeFonts(families, profilePath, this.differentOs);
560
- } catch (e) {
561
- console.trace(e);
562
- }
563
565
  }
564
566
 
565
567
  if (preferences.gologin === null) {
@@ -626,8 +628,13 @@ export class GoLogin {
626
628
 
627
629
  if (!this.browserMajorVersion) {
628
630
  const { userAgent } = profile.navigator;
629
- const [browserMajorVersion] = userAgent.split('Chrome/')[1].split('.');
630
- this.browserMajorVersion = Number(browserMajorVersion);
631
+ try {
632
+ const [browserMajorVersion] = userAgent.split('Chrome/')[1].split('.');
633
+ this.browserMajorVersion = Number(browserMajorVersion);
634
+ } catch (e) {
635
+ const latestVersionNumber = await this.getLatestBrowserVersion();
636
+ this.browserMajorVersion = latestVersionNumber;
637
+ }
631
638
 
632
639
  let executableDir = join(this.executablePath, '..');
633
640
  if (OS_PLATFORM === 'darwin') {
@@ -663,6 +670,7 @@ export class GoLogin {
663
670
  }
664
671
 
665
672
  async initCookiesFile(profile) {
673
+ const { getCookiesFilePath } = await loadCookiesManager();
666
674
  this.cookiesFilePath = await getCookiesFilePath(this.profile_id, this.tmpdir);
667
675
  if (this.writeCookiesFromServer) {
668
676
  await this.writeCookiesToFile(profile.cookies?.cookies);
@@ -674,6 +682,7 @@ export class GoLogin {
674
682
  return;
675
683
  }
676
684
 
685
+ const ExtensionsManager = await loadExtensionsManager();
677
686
  const ExtensionsManagerInst = new ExtensionsManager();
678
687
  ExtensionsManagerInst.apiUrl = API_URL;
679
688
  await ExtensionsManagerInst.init()
@@ -890,6 +899,7 @@ export class GoLogin {
890
899
  }
891
900
 
892
901
  proxy += host + ':' + port;
902
+ const SocksProxyAgent = await loadSocksProxyAgent();
893
903
  const agent = new SocksProxyAgent(proxy);
894
904
 
895
905
  const checkData = await checkSocksProxy(agent).catch((e) => {
@@ -976,7 +986,12 @@ export class GoLogin {
976
986
 
977
987
  this.port = remote_debugging_port;
978
988
 
979
- const ORBITA_BROWSER = this.executablePath || this.browserChecker.getOrbitaPath;
989
+ let ORBITA_BROWSER = this.executablePath;
990
+ if (!ORBITA_BROWSER) {
991
+ const browserChecker = await this.getBrowserChecker();
992
+ ORBITA_BROWSER = browserChecker.getOrbitaPath;
993
+ }
994
+
980
995
  debug(`ORBITA_BROWSER=${ORBITA_BROWSER}`);
981
996
 
982
997
  const env = {};
@@ -1069,7 +1084,7 @@ export class GoLogin {
1069
1084
  debug('GETTING WS URL FROM BROWSER');
1070
1085
  const data = await makeRequest(
1071
1086
  `http://127.0.0.1:${remote_debugging_port}/json/version`,
1072
- { json: true, maxAttempts: 30, retryDelay: 400, method: 'GET' },
1087
+ { json: true, maxAttempts: 60, retryDelay: 100, method: 'GET' },
1073
1088
  );
1074
1089
 
1075
1090
  debug('WS IS', get(data, 'webSocketDebuggerUrl', ''));
@@ -1082,8 +1097,8 @@ export class GoLogin {
1082
1097
  }
1083
1098
 
1084
1099
  async clearProfileFiles() {
1085
- await rimraf(join(this.tmpdir, `gologin_profile_${this.profile_id}`), () => null);
1086
- await rimraf(join(this.tmpdir, `gologin_${this.profile_id}_upload.zip`), () => null);
1100
+ await removePath(join(this.tmpdir, `gologin_profile_${this.profile_id}`));
1101
+ await removePath(join(this.tmpdir, `gologin_${this.profile_id}_upload.zip`));
1087
1102
  }
1088
1103
 
1089
1104
  async stopAndCommit(options, local = false) {
@@ -1113,7 +1128,7 @@ export class GoLogin {
1113
1128
  await this.clearProfileFiles();
1114
1129
 
1115
1130
  if (!local) {
1116
- await rimraf(join(this.tmpdir, `gologin_${this.profile_id}.zip`), () => null);
1131
+ await removePath(join(this.tmpdir, `gologin_${this.profile_id}.zip`));
1117
1132
  }
1118
1133
 
1119
1134
  debug(`PROFILE ${this.profile_id} STOPPED AND CLEAR`);
@@ -1122,6 +1137,7 @@ export class GoLogin {
1122
1137
  }
1123
1138
 
1124
1139
  async uploadProfileDataToServer() {
1140
+ const { loadCookiesFromFile } = await loadCookiesManager();
1125
1141
  const cookies = await loadCookiesFromFile(this.cookiesFilePath, false, this.profile_id, this.tmpdir);
1126
1142
  const bookmarks = await getCurrentProfileBookmarks(this.bookmarksFilePath);
1127
1143
  const profilePreferencesPath = join(this.profilePath(), 'Default', 'Preferences');
@@ -1180,7 +1196,7 @@ export class GoLogin {
1180
1196
  debug('browser killed');
1181
1197
  } catch (error) {
1182
1198
  console.error(error);
1183
- captureGroupedSentryError(error, { method: 'killBrowser', profileId: this.profile_id });
1199
+ // captureGroupedSentryError(error, { method: 'killBrowser', profileId: this.profile_id });
1184
1200
  }
1185
1201
  }
1186
1202
 
@@ -1221,13 +1237,7 @@ export class GoLogin {
1221
1237
  await Promise.all(remove_dirs.map(d => {
1222
1238
  const path_to_remove = `${that.profilePath()}${d}`;
1223
1239
 
1224
- return new Promise(resolve => {
1225
- debug('DROPPING', path_to_remove);
1226
- rimraf(path_to_remove, { maxBusyTries: 100 }, (e) => {
1227
- // debug('DROPPING RESULT', e);
1228
- resolve();
1229
- });
1230
- });
1240
+ return removePath(path_to_remove, { maxBusyTries: 100 });
1231
1241
  }));
1232
1242
  }
1233
1243
 
@@ -1242,6 +1252,7 @@ export class GoLogin {
1242
1252
  debug('profile sanitized');
1243
1253
 
1244
1254
  const profilePath = this.profilePath();
1255
+ const { archiveProfile } = await loadProfileArchiver();
1245
1256
  const fileBuff = await archiveProfile(profilePath);
1246
1257
 
1247
1258
  debug('PROFILE ZIP CREATED', profilePath, zipPath);
@@ -1431,6 +1442,13 @@ export class GoLogin {
1431
1442
  return;
1432
1443
  }
1433
1444
 
1445
+ const {
1446
+ createDBFile,
1447
+ getChunckedInsertValues,
1448
+ getDB,
1449
+ getUniqueCookies,
1450
+ } = await loadCookiesManager();
1451
+
1434
1452
  const resultCookies = cookies.map((el) => ({ ...el, value: Buffer.from(el.value) }));
1435
1453
  let db;
1436
1454
  const profilePath = join(this.tmpdir, `gologin_profile_${this.profile_id}`);
@@ -1463,7 +1481,7 @@ export class GoLogin {
1463
1481
  }
1464
1482
 
1465
1483
  console.error(error.message);
1466
- captureGroupedSentryError(error, { method: 'writeCookiesToFile', profileId: this.profile_id });
1484
+ // captureGroupedSentryError(error, { method: 'writeCookiesToFile', profileId: this.profile_id });
1467
1485
  } finally {
1468
1486
  db && await db.close();
1469
1487
  await ensureDirectoryExists(cookiesPaths.primary);
@@ -1481,16 +1499,17 @@ export class GoLogin {
1481
1499
  }
1482
1500
 
1483
1501
  async start() {
1484
- try {
1485
- await this.createStartup();
1486
- const startResponse = await this.spawnBrowser();
1487
- this.setActive(true);
1502
+ // ensureSentryInitialized({ release: process.env.npm_package_version || '2.1.34' });
1488
1503
 
1489
- return { status: 'success', wsUrl: startResponse.wsUrl, resolution: startResponse.resolution };
1490
- } catch (error) {
1491
- captureGroupedSentryError(error, { method: 'start', profileId: this.profile_id });
1492
- throw error;
1493
- }
1504
+ await this.createStartup();
1505
+ const startResponse = await this.spawnBrowser();
1506
+ this.setActive(true);
1507
+
1508
+ return {
1509
+ status: 'success',
1510
+ wsUrl: startResponse.wsUrl,
1511
+ resolution: startResponse.resolution,
1512
+ };
1494
1513
  }
1495
1514
 
1496
1515
  async startLocal() {
@@ -1570,12 +1589,6 @@ export class GoLogin {
1570
1589
  return updateProfileResolution(this.profile_id, this.access_token, resolution);
1571
1590
  }
1572
1591
 
1573
- getAvailableFonts() {
1574
- return fontsCollection
1575
- .filter(elem => elem.fileNames)
1576
- .map(elem => elem.name);
1577
- }
1578
-
1579
1592
  async quickCreateProfile(name = '') {
1580
1593
  const osInfo = await getOsAdvanced();
1581
1594
  const { os, osSpec } = osInfo;
package/src/index.js ADDED
@@ -0,0 +1,2 @@
1
+ export { GoLogin, default } from './gologin.js';
2
+ export { GologinApi, getDefaultParams, exitAll } from './gologin-api.js';
@@ -1,4 +1,3 @@
1
- import AdmZip from 'adm-zip';
2
1
  import { promises as _promises } from 'fs';
3
2
  import path from 'path';
4
3
 
@@ -6,7 +5,16 @@ import { getDirectoriesForArchiver } from './profile-directories-to-remove.js';
6
5
 
7
6
  const { access } = _promises;
8
7
 
8
+ let admZipPromise = null;
9
+
10
+ const loadAdmZip = () => {
11
+ admZipPromise ||= import('adm-zip').then((module) => module.default ?? module);
12
+
13
+ return admZipPromise;
14
+ };
15
+
9
16
  export const archiveProfile = async (profileFolder = '') => {
17
+ const AdmZip = await loadAdmZip();
10
18
  const folderExists = await access(profileFolder).then(() => true, () => false);
11
19
  if (!folderExists) {
12
20
  throw new Error('Invalid profile folder path: ' + profileFolder);
@@ -32,6 +40,7 @@ export const archiveProfile = async (profileFolder = '') => {
32
40
  };
33
41
 
34
42
  export const decompressProfile = async (zipPath = '', profileFolder = '') => {
43
+ const AdmZip = await loadAdmZip();
35
44
  const zipExists = await access(zipPath).then(() => true, () => false);
36
45
  if (!zipExists) {
37
46
  throw new Error('Invalid zip path: ' + zipPath);
@@ -44,6 +44,11 @@ const DEFAULT_FOLDER_USELESS_FILE = [
44
44
  subs: [],
45
45
  isDirectory: true,
46
46
  },
47
+ {
48
+ name: 'Shared Dictionary',
49
+ subs: ['cache'],
50
+ isDirectory: true,
51
+ },
47
52
  ];
48
53
 
49
54
  export const getDirectoriesToDeleteForNode = (routerSlash = '/') =>