@speedkit/cli 2.67.0 → 2.69.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
@@ -1,3 +1,31 @@
1
+ # [2.69.0](https://gitlab.orestes.info/baqend/speed-kit-cli/compare/v2.68.0...v2.69.0) (2024-12-11)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * createProfileFolder if not exists ([e820a45](https://gitlab.orestes.info/baqend/speed-kit-cli/commit/e820a45f6c4398b646f609c6d072d8d7775e4ac9))
7
+
8
+
9
+ ### Features
10
+
11
+ * create dynamic browserProfile from last session ([cce0f99](https://gitlab.orestes.info/baqend/speed-kit-cli/commit/cce0f995fb6ee8d9c84818d93ef1db50a6bd7820))
12
+ * **diff:** add .html-extension so idea can have syntaxHighlighting ([748bc25](https://gitlab.orestes.info/baqend/speed-kit-cli/commit/748bc2541a7d6b6a521b2eecf8e22666aefe68b4))
13
+ * load last browserConfig and create a fresh profile with it ([878a420](https://gitlab.orestes.info/baqend/speed-kit-cli/commit/878a42027b15a43d59f438bc34a88f8b10a652e6))
14
+ * **onboarding:** filter unwanted configKeys from previous configs ([b3f08a0](https://gitlab.orestes.info/baqend/speed-kit-cli/commit/b3f08a09d05fe6689fd826a03e5702559c5c6a68))
15
+
16
+ # [2.68.0](https://gitlab.orestes.info/baqend/speed-kit-cli/compare/v2.67.0...v2.68.0) (2024-12-11)
17
+
18
+
19
+ ### Bug Fixes
20
+
21
+ * do not set forceInstall to true by default ([4cd7138](https://gitlab.orestes.info/baqend/speed-kit-cli/commit/4cd7138e2deb44a8a33920c3fa888a77401dcd2c))
22
+
23
+
24
+ ### Features
25
+
26
+ * **onboarding:** add current DBToken to local docHandlerRuntime ([bd7d164](https://gitlab.orestes.info/baqend/speed-kit-cli/commit/bd7d16420dd3bab22f76d34878ddfdfc2a0edc03))
27
+ * **wizard:** remove custom doc-handler creation on lambda server-side rendering usage ([a4f5bff](https://gitlab.orestes.info/baqend/speed-kit-cli/commit/a4f5bff6591e376a089c6f9acb70239fce133eac))
28
+
1
29
  # [2.67.0](https://gitlab.orestes.info/baqend/speed-kit-cli/compare/v2.66.0...v2.67.0) (2024-12-10)
2
30
 
3
31
 
package/README.md CHANGED
@@ -21,7 +21,7 @@ $ npm install -g @speedkit/cli
21
21
  $ sk COMMAND
22
22
  running command...
23
23
  $ sk (--version)
24
- @speedkit/cli/2.67.0 linux-x64 node-v20.18.1
24
+ @speedkit/cli/2.69.0 linux-x64 node-v20.18.1
25
25
  $ sk --help [COMMAND]
26
26
  USAGE
27
27
  $ sk COMMAND
@@ -8,6 +8,7 @@ export type UserCliConfig = {
8
8
  ideaDirectory: string;
9
9
  slackToken: string;
10
10
  testApp: string;
11
+ tempFolder: string;
11
12
  };
12
13
  export declare class CliConfig {
13
14
  private config;
@@ -28,6 +28,7 @@ class CliConfig {
28
28
  ideaDirectory: "",
29
29
  slackToken: "",
30
30
  testApp: "",
31
+ tempFolder: "/tmp",
31
32
  };
32
33
  constructor(config) {
33
34
  this.config = config;
@@ -38,6 +39,7 @@ class CliConfig {
38
39
  // override config from environment
39
40
  this.loadConfigFromEnvironment();
40
41
  this.resolveExtensionConfigPaths();
42
+ this.userCliConfig.tempFolder = this.config.cacheDir;
41
43
  return this.userCliConfig;
42
44
  }
43
45
  createEmptyConfigFile() {
@@ -23,7 +23,6 @@ export declare class CustomerConfigService {
23
23
  private shouldFileBeOverwritten;
24
24
  private downloadAndSaveFile;
25
25
  private getConfigSettings;
26
- handleDocumentHandler({ addPreRendering }: CustomerConfigSettings): Promise<void>;
27
26
  logWarnings(configSettings: CustomerConfigSettings): Promise<void>;
28
27
  generateConfig(): Promise<void>;
29
28
  }
@@ -207,7 +207,7 @@ class CustomerConfigService {
207
207
  }
208
208
  activateImageOptimisation = await this.cli.confirm("Activate Image Optimisation?", false);
209
209
  removeLazyLoading = await this.cli.confirm("Remove Lazy-Loading?");
210
- if (await this.cli.confirm("Add Pre-Rendering? This requires a set-up Lambda function to work. Also requires a DOM-based DocumentHandler.", false)) {
210
+ if (await this.cli.confirm("Add Pre-Rendering? This requires a set-up Lambda function to work. Also requires usage of the DOM-based DocumentHandler.", false)) {
211
211
  addPreRendering = true;
212
212
  if (await this.cli.confirm("Does the customer utilize Shadow DOMs? If so additional handling for this will be added.", false)) {
213
213
  supportShadowDomInPreRendering = true;
@@ -250,31 +250,6 @@ class CustomerConfigService {
250
250
  shopifyId,
251
251
  };
252
252
  }
253
- async handleDocumentHandler({ addPreRendering }) {
254
- /*
255
- TODO:
256
- remove this custom DocumentHandler handling as soon as the DOM-parsing DocumentHandler has been released
257
- and can be controlled/activated by the DocumentHandler Config properly
258
- */
259
- if (addPreRendering) {
260
- const documentHandlerBranchName = "dom-parser/develop";
261
- const customDocumentHandlerOutputPath = path.join(this.outputDirPath, "custom_documentHandler.js");
262
- this.cli.writeWarning(`
263
- ⚠️ MANUAL ACTION NEEDED ⚠️
264
-
265
- Your config needs the DOM-parsing DocumentHandler which has not been publicly released yet.
266
-
267
- Working Branch: ${this.cli.codeStyle(documentHandlerBranchName)} (https://gitlab.orestes.info/baqend/document-handler/-/tree/${documentHandlerBranchName})
268
-
269
- Please add it to your newly created config directory manually:
270
-
271
- 1. ${this.cli.codeStyle(`git clone -b ${documentHandlerBranchName} git@vm.orestes.info:baqend/document-handler.git`)}
272
- 2. ${this.cli.codeStyle(`cd ./document-handler`)}
273
- 3. ${this.cli.codeStyle(`npm ci && npm run build`)}
274
- 4. ${this.cli.codeStyle(`cp ./dist/DocumentHandler.js ${customDocumentHandlerOutputPath}`)}
275
- `);
276
- }
277
- }
278
253
  async logWarnings(configSettings) {
279
254
  if (configSettings.useScrapingBee) {
280
255
  this.cli.writeWarning(`
@@ -293,7 +268,6 @@ class CustomerConfigService {
293
268
  this.templates.push("downtimeDetection.js.hbs");
294
269
  }
295
270
  await this.compileHandlebarsFiles(configSettings);
296
- await this.handleDocumentHandler(configSettings);
297
271
  await this.logWarnings(configSettings);
298
272
  this.cli.writeSuccess("\nConfig generation completed 👏\n");
299
273
  }
@@ -172,7 +172,7 @@ const config = {
172
172
  {{/unless}}
173
173
  }
174
174
 
175
- const documentHandler = new DocumentHandler({
175
+ const documentHandler = new {{#if addPreRendering}}DomDocumentHandler{{else}}DocumentHandler{{/if}}({
176
176
  ...config,
177
177
  app: APP,
178
178
  dynamicFetcher: DYNAMIC_FETCHER,
@@ -1,6 +1,7 @@
1
1
  import { BundleService } from "../bundler";
2
2
  import { CliService } from "../cli";
3
3
  import { CustomerConfig, FileListInterface } from "../integration-api";
4
+ import { EntityManager } from "baqend";
4
5
  import { DocumentHandlerResponse } from "./server/document-handler-response";
5
6
  export declare class DocumentHandlerServer {
6
7
  private customerConfig;
@@ -8,10 +9,11 @@ export declare class DocumentHandlerServer {
8
9
  private bundler;
9
10
  private cli;
10
11
  private verboseLevel;
12
+ private entityManager?;
11
13
  private documentHandlerCode;
12
14
  private documentHandlerConfigCode;
13
15
  private database;
14
- constructor(customerConfig: CustomerConfig, files: FileListInterface, bundler: BundleService, cli: CliService, verboseLevel?: boolean);
16
+ constructor(customerConfig: CustomerConfig, files: FileListInterface, bundler: BundleService, cli: CliService, verboseLevel?: boolean, entityManager?: EntityManager);
15
17
  transform(html: string, variation: string, url: string, headers: {
16
18
  [name: string]: string;
17
19
  }): Promise<DocumentHandlerResponse>;
@@ -21,15 +21,17 @@ class DocumentHandlerServer {
21
21
  bundler;
22
22
  cli;
23
23
  verboseLevel;
24
+ entityManager;
24
25
  documentHandlerCode;
25
26
  documentHandlerConfigCode;
26
27
  database;
27
- constructor(customerConfig, files, bundler, cli, verboseLevel = false) {
28
+ constructor(customerConfig, files, bundler, cli, verboseLevel = false, entityManager) {
28
29
  this.customerConfig = customerConfig;
29
30
  this.files = files;
30
31
  this.bundler = bundler;
31
32
  this.cli = cli;
32
33
  this.verboseLevel = verboseLevel;
34
+ this.entityManager = entityManager;
33
35
  }
34
36
  async transform(html, variation, url, headers) {
35
37
  if (!this.documentHandlerCode) {
@@ -160,6 +162,9 @@ class DocumentHandlerServer {
160
162
  const vmContext = { console: vmConsole, module: { exports: {} } };
161
163
  vm.runInNewContext(databaseCode, vmContext);
162
164
  this.database = vmContext.module.exports;
165
+ if (this.entityManager) {
166
+ this.database.token = this.entityManager.token;
167
+ }
163
168
  }
164
169
  return this.database;
165
170
  }
@@ -8,6 +8,8 @@ const cli_1 = require("../../cli");
8
8
  const required_file_not_found_error_1 = tslib_1.__importDefault(require("../error/required-file-not-found-error"));
9
9
  const document_handler_server_1 = require("../document-handler-server");
10
10
  const bundler_1 = require("../../bundler");
11
+ const entity_manager_factory_1 = require("../../config-api/entity-manager-factory");
12
+ const safe_1 = require("../../../helpers/safe");
11
13
  class DocumentHandlerRuntimeServiceFactory {
12
14
  context;
13
15
  cliConfig;
@@ -35,7 +37,8 @@ class DocumentHandlerRuntimeServiceFactory {
35
37
  const customerConfig = this.getCustomerConfig(files);
36
38
  const bundler = new bundler_1.BundleServiceFactory().buildService();
37
39
  const cliService = new cli_1.CliServiceFactory().getService();
38
- return new document_handler_server_1.DocumentHandlerServer(customerConfig, files, bundler, cliService, this.context.verboseLevel);
40
+ const entityManagerResult = await (0, safe_1.safe)(new entity_manager_factory_1.EntityManagerFactory().getEntityManager(customerConfig.app));
41
+ return new document_handler_server_1.DocumentHandlerServer(customerConfig, files, bundler, cliService, this.context.verboseLevel, entityManagerResult.success ? entityManagerResult.data : null);
39
42
  }
40
43
  prepareIntegrationApi() {
41
44
  const integrationApiContext = new integration_api_1.IntegrationApiContext(this.context.customerPath, this.context.configName, this.context.fileDependencies, [".git", ".idea", "node_modules"]);
@@ -33,7 +33,7 @@ class CustomerConfig {
33
33
  static createFrom(configFile, configName) {
34
34
  const { app, origins, domain, swPath, scope, appDomain, installPath, installParams, name, forceInstall, chromeFlags, dependencies, } = configFile;
35
35
  return new CustomerConfig(new RequiredParameter("app", app).isString().getValue(), new RequiredParameter("origins", origins).isArray().getValue(), domain, new RequiredParameter("swPath", swPath).isString().getValue(), new RequiredParameter("scope", scope).isString().getValue(), appDomain || `${app}.app.baqend.com`, installPath ||
36
- `https://${app}.app.baqend.com/v1/speedkit/install.js?d=${name || configName}`, installParams || 'async="" crossorigin="anonymous"', name, forceInstall || true, chromeFlags, dependencies || {});
36
+ `https://${app}.app.baqend.com/v1/speedkit/install.js?d=${name || configName}`, installParams || 'async="" crossorigin="anonymous"', name, forceInstall || false, chromeFlags, dependencies || {});
37
37
  }
38
38
  }
39
39
  exports.CustomerConfig = CustomerConfig;
@@ -0,0 +1,27 @@
1
+ import { UserCliConfig } from "../../../../helpers/cli-config";
2
+ /**
3
+ * this class makes sure you always start skOnboarding with a fresh browser,
4
+ * but still keep your window/devtools-configuration
5
+ */
6
+ export declare class BrowserConfig {
7
+ private userConfig;
8
+ constructor(userConfig: UserCliConfig);
9
+ /**
10
+ * create a new temporary profileFolder
11
+ * load browserConfigJsonFile from last profileFolder
12
+ * delete older profiles
13
+ */
14
+ loadProfileTempDir(): string;
15
+ /**
16
+ * load latest browserConfig and put it into newly created profilePath
17
+ */
18
+ private createProfileDirWithLatestConfig;
19
+ private sortFoldersByDate;
20
+ /**
21
+ * remove keys we don't need
22
+ *
23
+ * @param configString
24
+ * @private
25
+ */
26
+ private cleanUpLastConfig;
27
+ }
@@ -0,0 +1,102 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BrowserConfig = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const node_path_1 = tslib_1.__importDefault(require("node:path"));
6
+ const node_fs_1 = tslib_1.__importDefault(require("node:fs"));
7
+ const chromeProfilesParentFolder = "chrome_profile";
8
+ const keysToRemove = new Set([
9
+ "sessions",
10
+ "extensions",
11
+ "in_product_help",
12
+ "history_clusters",
13
+ "media",
14
+ "profile",
15
+ "protection",
16
+ ]);
17
+ /**
18
+ * this class makes sure you always start skOnboarding with a fresh browser,
19
+ * but still keep your window/devtools-configuration
20
+ */
21
+ class BrowserConfig {
22
+ userConfig;
23
+ constructor(userConfig) {
24
+ this.userConfig = userConfig;
25
+ }
26
+ /**
27
+ * create a new temporary profileFolder
28
+ * load browserConfigJsonFile from last profileFolder
29
+ * delete older profiles
30
+ */
31
+ loadProfileTempDir() {
32
+ const chromeProfilePath = node_path_1.default.resolve(this.userConfig.tempFolder, chromeProfilesParentFolder, String(Date.now()));
33
+ const chromeProfilesParentFolderPath = node_path_1.default.resolve(this.userConfig.tempFolder, chromeProfilesParentFolder);
34
+ // create parentFolder if not exists
35
+ if (!node_fs_1.default.existsSync(chromeProfilesParentFolderPath)) {
36
+ node_fs_1.default.mkdirSync(chromeProfilesParentFolderPath, { recursive: true });
37
+ }
38
+ // load older profiles
39
+ const chromeProfileFolders = node_fs_1.default.readdirSync(chromeProfilesParentFolderPath);
40
+ if (!chromeProfileFolders || chromeProfileFolders.length === 0) {
41
+ return chromeProfilePath;
42
+ }
43
+ const sortedFolders = this.sortFoldersByDate(chromeProfileFolders);
44
+ this.createProfileDirWithLatestConfig(sortedFolders, chromeProfilesParentFolderPath, chromeProfilePath);
45
+ return chromeProfilePath;
46
+ }
47
+ /**
48
+ * load latest browserConfig and put it into newly created profilePath
49
+ */
50
+ createProfileDirWithLatestConfig(sortedFolders, chromeTemporaryFolderPath, chromeProfilePath) {
51
+ let foundLatestFolder = false;
52
+ for (const folderName of sortedFolders) {
53
+ const preferencesPath = node_path_1.default.resolve(chromeTemporaryFolderPath, folderName, "Default", "Preferences");
54
+ // look for chrome preferences in latest profileFolder
55
+ // delete folders not containing any profiles
56
+ // delete all older folders after we found latest profile
57
+ if (!node_fs_1.default.existsSync(preferencesPath) || foundLatestFolder) {
58
+ node_fs_1.default.rmSync(node_path_1.default.resolve(chromeTemporaryFolderPath, folderName), {
59
+ recursive: true,
60
+ force: true,
61
+ });
62
+ continue;
63
+ }
64
+ // return latest found config
65
+ const lastConfigString = this.cleanUpLastConfig(node_fs_1.default.readFileSync(preferencesPath, "utf8"));
66
+ node_fs_1.default.mkdirSync(node_path_1.default.resolve(chromeProfilePath, "Default"), {
67
+ recursive: true,
68
+ });
69
+ node_fs_1.default.writeFileSync(node_path_1.default.resolve(chromeProfilePath, "Default", "Preferences"), lastConfigString, { encoding: "utf-8" });
70
+ // after adding latest profile to new profile
71
+ // delete folder where we got the latest config from
72
+ node_fs_1.default.rmSync(node_path_1.default.resolve(chromeTemporaryFolderPath, folderName), {
73
+ recursive: true,
74
+ force: true,
75
+ });
76
+ foundLatestFolder = true;
77
+ }
78
+ }
79
+ sortFoldersByDate(chromeProfileFolders) {
80
+ return chromeProfileFolders.sort((a, b) => {
81
+ return Number.parseInt(b) - Number.parseInt(a);
82
+ });
83
+ }
84
+ /**
85
+ * remove keys we don't need
86
+ *
87
+ * @param configString
88
+ * @private
89
+ */
90
+ cleanUpLastConfig(configString) {
91
+ const config = JSON.parse(configString);
92
+ const newConfig = {};
93
+ for (const key in config) {
94
+ if (keysToRemove.has(key)) {
95
+ continue;
96
+ }
97
+ newConfig[key] = config[key];
98
+ }
99
+ return JSON.stringify(newConfig);
100
+ }
101
+ }
102
+ exports.BrowserConfig = BrowserConfig;
@@ -32,8 +32,8 @@ class DiffAgainstCurrentPage {
32
32
  originHtml = originDocumentHandlerResponse.body;
33
33
  }
34
34
  this.cli.endAction(cli_1.CliActionStatus.COMPLETED);
35
- const remoteFilePath = await this.diffService.writeContentToTemporalFile(`remote-${variant}`, originHtml);
36
- const localFilePath = await this.diffService.writeContentToTemporalFile("current", currentHtml);
35
+ const remoteFilePath = await this.diffService.writeContentToTemporalFile(`remote-${variant}.html`, originHtml);
36
+ const localFilePath = await this.diffService.writeContentToTemporalFile("current.html", currentHtml);
37
37
  return await this.diffService.executeDiff(localFilePath, remoteFilePath);
38
38
  }
39
39
  }
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.SpeedKitInstallRegex = exports.USER_AGENT = exports.OnboardingContext = exports.BrowserContext = exports.CDP_SESSION = exports.BROWSER_EVENTS = void 0;
4
4
  const core_1 = require("@oclif/core");
5
5
  const cli_parameters_1 = require("../../models/cli-parameters");
6
+ const browser_config_1 = require("./browser/config/browser-config");
6
7
  const DEFAULT_BROWSER_ARGS = [
7
8
  "--enable-features=Translate,NetworkService",
8
9
  "--no-first-run",
@@ -57,6 +58,11 @@ class BrowserContext {
57
58
  if (userConfig?.chromeUserProfilePath) {
58
59
  browserArguments.push(`--user-data-dir=${userConfig?.chromeUserProfilePath}`);
59
60
  }
61
+ else {
62
+ const browserConfig = new browser_config_1.BrowserConfig(this.userConfig);
63
+ const temporaryProfileDirectory = browserConfig.loadProfileTempDir();
64
+ browserArguments.push(`--user-data-dir=${temporaryProfileDirectory}`);
65
+ }
60
66
  this.browserArgs = [
61
67
  ...browserArguments,
62
68
  `--unsafely-treat-insecure-origin-as-secure=${domain}`,
@@ -712,5 +712,5 @@
712
712
  ]
713
713
  }
714
714
  },
715
- "version": "2.67.0"
715
+ "version": "2.69.0"
716
716
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@speedkit/cli",
3
3
  "description": "Speed Kit CLI",
4
- "version": "2.67.0",
4
+ "version": "2.69.0",
5
5
  "author": {
6
6
  "name": "Baqend.com",
7
7
  "email": "info@baqend.com"
@@ -92,9 +92,7 @@
92
92
  "parse5": "7.1",
93
93
  "parse5-htmlparser2-tree-adapter": "7.0.0",
94
94
  "puppeteer": "^22.6.5",
95
- "puppeteer-core": "^22.6.5",
96
95
  "puppeteer-extra": "^3.3.6",
97
- "puppeteer-extra-plugin-user-preferences": "^2.4.1",
98
96
  "strip-comments": "^2.0.1",
99
97
  "uuid": "^9.0.1",
100
98
  "esbuild": "^0.20.2",