@speedkit/cli 3.32.0 → 3.33.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,20 @@
1
+ # [3.33.0](https://gitlab.orestes.info/baqend/speed-kit-cli/compare/v3.32.1...v3.33.0) (2026-03-25)
2
+
3
+
4
+ ### Features
5
+
6
+ * change formatLib add autoFormat for htmlDiffs ([8d29341](https://gitlab.orestes.info/baqend/speed-kit-cli/commit/8d293419d29a555196b57974a7917447154fd32c))
7
+ * implement htmlFormat for html-diff ([5e4524f](https://gitlab.orestes.info/baqend/speed-kit-cli/commit/5e4524fb920e4cb6fdeb45f5a712b8d3efdeba3f))
8
+ * **onboarding:** args ([572729d](https://gitlab.orestes.info/baqend/speed-kit-cli/commit/572729db87180ac7499945b1fadd9339f2d47064))
9
+ * **onboarding:** args ([1e76105](https://gitlab.orestes.info/baqend/speed-kit-cli/commit/1e761057b274a648b2fc62374857e9317995dd2a))
10
+
11
+ ## [3.32.1](https://gitlab.orestes.info/baqend/speed-kit-cli/compare/v3.32.0...v3.32.1) (2026-03-23)
12
+
13
+
14
+ ### Bug Fixes
15
+
16
+ * **customer-config:** prevent null pointer exception in soft2hard nav conversion ([9277a1c](https://gitlab.orestes.info/baqend/speed-kit-cli/commit/9277a1c0a188b5e0f8f143435712d84255d9ff8c))
17
+
1
18
  # [3.32.0](https://gitlab.orestes.info/baqend/speed-kit-cli/compare/v3.31.2...v3.32.0) (2026-03-11)
2
19
 
3
20
 
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/3.32.0 linux-x64 node-v20.20.1
24
+ @speedkit/cli/3.33.0 linux-x64 node-v20.20.1
25
25
  $ sk --help [COMMAND]
26
26
  USAGE
27
27
  $ sk COMMAND
@@ -382,7 +382,7 @@ Start a local dev environment for building and testing the Speed Kit configurati
382
382
 
383
383
  ```
384
384
  USAGE
385
- $ sk onboarding CUSTOMERPATH [-c <value>] [-t] [-d <value>] [-l] [-v] [-s]
385
+ $ sk onboarding CUSTOMERPATH [-c <value>] [-t] [-d <value>] [-l] [-p] [-v] [-s]
386
386
 
387
387
  ARGUMENTS
388
388
  CUSTOMERPATH The customer config path
@@ -391,6 +391,7 @@ FLAGS
391
391
  -c, --configName=<value> [default: production] The costumer config name
392
392
  -d, --domain=<value> Startup domain (optional)
393
393
  -l, --local Run with local documentHandler
394
+ -p, --debuggingPort Enable remote debugging port (disables speculation rules/prerendering)
394
395
  -s, --ignoreContentSecurityPolicy Removes header/meta "content-security-policy" for origin-responses
395
396
  -t, --useTestConfig Override app with configured testApp
396
397
  -v, --verboseLevel Show all messages
@@ -8,6 +8,7 @@ const cli_1 = require("../services/cli");
8
8
  const url = tslib_1.__importStar(require("node:url"));
9
9
  const diff_1 = require("../services/diff");
10
10
  const cli_config_1 = require("../helpers/cli-config");
11
+ const html_format_helper_1 = require("../helpers/html-format-helper");
11
12
  class DiffUrlParameters extends core_1.Command {
12
13
  cli;
13
14
  static description = "Shows difference in documents with query parameters on/off";
@@ -60,8 +61,8 @@ class DiffUrlParameters extends core_1.Command {
60
61
  const userConfig = new cli_config_1.CliConfig(this.config).load();
61
62
  const context = new diff_1.DiffContext(userConfig.diffExec, userConfig.diffExecTemplate);
62
63
  const diffService = new diff_1.DiffServiceFactory(context).getService();
63
- const originalFilePath = await diffService.writeContentToTemporalFile("original.html", originalData);
64
- const withoutAnyParametersFilePath = await diffService.writeContentToTemporalFile("without-any-params.html", withoutAnyParametersData);
64
+ const originalFilePath = await diffService.writeContentToTemporalFile("original.html", (0, html_format_helper_1.formatHtml)(originalData));
65
+ const withoutAnyParametersFilePath = await diffService.writeContentToTemporalFile("without-any-params.html", (0, html_format_helper_1.formatHtml)(withoutAnyParametersData));
65
66
  this.cli.spacer();
66
67
  this.cli.write(`Checking any parameter...`);
67
68
  this.cli.write(`- with: ${originalUrl}`);
@@ -89,7 +90,7 @@ class DiffUrlParameters extends core_1.Command {
89
90
  if (!withoutCurrentParameterData) {
90
91
  this.logError(`Failed to fetch document without "${parameter}" parameter`);
91
92
  }
92
- const withoutCurrentParameterFilePath = await diffService.writeContentToTemporalFile(`without-${parameter}-param.html`, withoutCurrentParameterData);
93
+ const withoutCurrentParameterFilePath = await diffService.writeContentToTemporalFile(`without-${parameter}-param.html`, (0, html_format_helper_1.formatHtml)(withoutCurrentParameterData));
93
94
  this.cli.spacer();
94
95
  this.cli.write(`Checking "${parameter}" parameter...`);
95
96
  this.cli.write(`- with: ${originalUrl}`);
@@ -13,8 +13,8 @@ class Onboarding extends core_1.Command {
13
13
  `$ sk onboarding ${cli_parameters_1.CLIParametersExample.CustomerPath} -${cli_parameters_1.CLIParametersChar.ConfigName} ${cli_parameters_1.CLIParametersExample.ConfigName} -${cli_parameters_1.CLIParametersChar.Domain} ${cli_parameters_1.CLIParametersExample.Domain}`,
14
14
  ];
15
15
  async run() {
16
- const { args: { customerPath }, flags: { configName, domain, local, verboseLevel, ignoreContentSecurityPolicy, useTestConfig, }, } = await this.parse(Onboarding);
17
- const service = await new onboarding_1.OnboardingServiceFactory(new onboarding_1.OnboardingContext(customerPath, configName, domain, local, ignoreContentSecurityPolicy, this.config.root, verboseLevel, useTestConfig), new cli_config_1.CliConfig(this.config).load(customerPath)).getService();
16
+ const { args: { customerPath }, flags: { configName, domain, local, verboseLevel, ignoreContentSecurityPolicy, useTestConfig, debuggingPort, }, } = await this.parse(Onboarding);
17
+ const service = await new onboarding_1.OnboardingServiceFactory(new onboarding_1.OnboardingContext(customerPath, configName, domain, local, ignoreContentSecurityPolicy, this.config.root, verboseLevel, useTestConfig, debuggingPort), new cli_config_1.CliConfig(this.config).load(customerPath)).getService();
18
18
  await service.run();
19
19
  }
20
20
  }
@@ -0,0 +1 @@
1
+ export declare function formatHtml(html: string): string;
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.formatHtml = formatHtml;
4
+ const htmlfy_1 = require("htmlfy");
5
+ function formatHtml(html) {
6
+ return (0, htmlfy_1.prettify)(html);
7
+ }
@@ -277,9 +277,9 @@ import { PredictivePreloading } from 'predictive-preloading/predictivePreloading
277
277
  track: () => {
278
278
  if (
279
279
  // check that dashboard is not disabled and user is in group A
280
- window?.SpeedKit.lastNavigate.disconnectCause.indexOf("DashboardDisabled") > -1 ||
280
+ window?.SpeedKit?.lastNavigate?.disconnectCause?.indexOf("DashboardDisabled") > -1 ||
281
281
  !window?.SpeedKit?.skSupported ||
282
- SpeedKit.group !== "A"
282
+ window?.SpeedKit?.group !== "A"
283
283
  ) {
284
284
  return;
285
285
  }
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.DiffAgainstCurrentPage = void 0;
4
4
  const cli_1 = require("../../cli");
5
+ const html_format_helper_1 = require("../../../helpers/html-format-helper");
5
6
  class DiffAgainstCurrentPage {
6
7
  diffService;
7
8
  documentHandlerRuntime;
@@ -13,10 +14,10 @@ class DiffAgainstCurrentPage {
13
14
  this.crawler = crawler;
14
15
  this.cli = cli;
15
16
  }
16
- async postDiff(currentHtml, currentUrl, variant = "DEFAULT", transform = false) {
17
+ async postDiff(currentHtml, currentUrl, variant = "default", transform = false) {
17
18
  this.cli.writeWarning(`received diff for url: ${currentUrl}`);
18
19
  this.cli.startAction(`fetch remote`);
19
- const originResponse = await this.crawler.fetchRemote(currentUrl, variant.toUpperCase());
20
+ const originResponse = await this.crawler.fetchRemote(currentUrl, variant);
20
21
  let originHtml = await originResponse?.text();
21
22
  if (!originHtml) {
22
23
  this.cli.endAction(cli_1.CliActionStatus.FAILED);
@@ -42,8 +43,8 @@ class DiffAgainstCurrentPage {
42
43
  originHtml = originResponse;
43
44
  }
44
45
  this.cli.endAction(cli_1.CliActionStatus.COMPLETED);
45
- const remoteFilePath = await this.diffService.writeContentToTemporalFile(`remote-${variant}.html`, originHtml);
46
- const localFilePath = await this.diffService.writeContentToTemporalFile("current.html", currentHtml);
46
+ const remoteFilePath = await this.diffService.writeContentToTemporalFile(`remote-${variant}.html`, (0, html_format_helper_1.formatHtml)(originHtml));
47
+ const localFilePath = await this.diffService.writeContentToTemporalFile("current.html", (0, html_format_helper_1.formatHtml)(currentHtml));
47
48
  return await this.diffService.executeDiff(remoteFilePath, localFilePath);
48
49
  }
49
50
  }
@@ -80,7 +80,7 @@ class Dashboard {
80
80
  const transform = data.transform || false;
81
81
  const diffResult = await (0, safe_1.safe)(this.currentPageDiff.postDiff(currentHtml, currentUrl, variant, transform));
82
82
  if (diffResult.success === true) {
83
- return this.createBaqendResponse(requestOrigin, JSON.stringify({ success: true }), "application/json; charset=UTF-8", [], 200);
83
+ return this.createBaqendResponse(requestOrigin, JSON.stringify({ success: diffResult.data }), "application/json; charset=UTF-8", [], 200);
84
84
  }
85
85
  return this.createBaqendResponse(requestOrigin, JSON.stringify({ success: false, error: diffResult.error }), "application/json; charset=UTF-8", [], 500);
86
86
  }
@@ -7,6 +7,7 @@ const safe_1 = require("../../../helpers/safe");
7
7
  const node_https_1 = require("node:https");
8
8
  const node_crypto_1 = tslib_1.__importDefault(require("node:crypto"));
9
9
  const node_fetch_1 = tslib_1.__importDefault(require("node-fetch"));
10
+ const html_format_helper_1 = require("../../../helpers/html-format-helper");
10
11
  class RequestDiffService {
11
12
  diffService;
12
13
  documentHandlerRuntime;
@@ -59,8 +60,8 @@ class RequestDiffService {
59
60
  if (checkIsEqual) {
60
61
  return this.diffService.isContentEqual(transformedHtmlWithParameter, transformedHtmlWithoutParameter);
61
62
  }
62
- const parametersFilePath = await this.diffService.writeContentToTemporalFile("params", transformedHtmlWithParameter);
63
- const pureFilePath = await this.diffService.writeContentToTemporalFile("pure", transformedHtmlWithoutParameter);
63
+ const parametersFilePath = await this.diffService.writeContentToTemporalFile("params", (0, html_format_helper_1.formatHtml)(transformedHtmlWithParameter));
64
+ const pureFilePath = await this.diffService.writeContentToTemporalFile("pure", (0, html_format_helper_1.formatHtml)(transformedHtmlWithoutParameter));
64
65
  return await this.diffService.executeDiff(parametersFilePath, pureFilePath);
65
66
  }
66
67
  async fetchHtml(url) {
@@ -36,9 +36,10 @@ export declare class BrowserContext {
36
36
  readonly chromeFlags?: string[];
37
37
  readonly userConfig?: UserCliConfig;
38
38
  userAgent?: string;
39
+ readonly debuggingPort: boolean;
39
40
  readonly browserArgs: string[];
40
41
  readonly chromePath: string;
41
- constructor(domain: string, browserVersionString?: string, chromeFlags?: string[], userConfig?: UserCliConfig, userAgent?: string);
42
+ constructor(domain: string, browserVersionString?: string, chromeFlags?: string[], userConfig?: UserCliConfig, userAgent?: string, debuggingPort?: boolean);
42
43
  private isChromeBrowser;
43
44
  private getBrowserExtensionPath;
44
45
  getPuppeteerLaunchOptions(): Parameters<VanillaPuppeteer["launch"]>[0];
@@ -56,12 +57,13 @@ export declare class OnboardingContext {
56
57
  readonly cliPath: string;
57
58
  readonly verboseLevel?: boolean;
58
59
  readonly useTestConfig: boolean;
60
+ readonly debuggingPort: boolean;
59
61
  static flags: FlagInput;
60
62
  readonly DEFAULT_DF_PATH = "https://www.baqend.com/speed-kit/latest/dynamic-fetcher.js";
61
63
  readonly DEFAULT_DOCUMENT_HANDLER_PATH = "https://www.baqend.com/speed-kit-handler/latest/DocumentHandler.js";
62
64
  readonly DEFAULT_SNIPPET_PATH = "https://www.baqend.com/speed-kit/latest/snippet.js";
63
65
  readonly DEFAULT_SW_PATH = "https://www.baqend.com/speed-kit/latest/sw.js";
64
- constructor(customerPath: string, configName: string, domain: string, local: boolean, ignoreContentSecurityPolicy: boolean, cliPath: string, verboseLevel?: boolean, useTestConfig?: boolean);
66
+ constructor(customerPath: string, configName: string, domain: string, local: boolean, ignoreContentSecurityPolicy: boolean, cliPath: string, verboseLevel?: boolean, useTestConfig?: boolean, debuggingPort?: boolean);
65
67
  }
66
68
  export type SpeedKitServerConfigAuthentication = {
67
69
  password: string;
@@ -44,14 +44,16 @@ class BrowserContext {
44
44
  chromeFlags;
45
45
  userConfig;
46
46
  userAgent;
47
+ debuggingPort;
47
48
  browserArgs;
48
49
  chromePath;
49
- constructor(domain, browserVersionString = "unknown", chromeFlags, userConfig, userAgent) {
50
+ constructor(domain, browserVersionString = "unknown", chromeFlags, userConfig, userAgent, debuggingPort = false) {
50
51
  this.domain = domain;
51
52
  this.browserVersionString = browserVersionString;
52
53
  this.chromeFlags = chromeFlags;
53
54
  this.userConfig = userConfig;
54
55
  this.userAgent = userAgent;
56
+ this.debuggingPort = debuggingPort;
55
57
  this.domain = domain;
56
58
  this.chromeFlags = chromeFlags || [];
57
59
  this.chromePath = (0, node_path_1.resolve)(userConfig.chromePath);
@@ -90,13 +92,17 @@ class BrowserContext {
90
92
  };
91
93
  if (this.userConfig?.chromeExtensionPaths) {
92
94
  if (this.isChromeBrowser()) {
93
- options["pipe"] = true;
94
95
  options["enableExtensions"] = this.getBrowserExtensionPath();
96
+ options["pipe"] = true;
97
+ options.args.push("--remote-debugging-pipe");
95
98
  }
96
99
  else {
97
- options.args.push(`--load-extension=${this.userConfig?.chromeExtensionPaths}`, "--remote-debugging-port=9222", `--disable-extensions-except=${this.userConfig?.chromeExtensionPaths}`);
100
+ options.args.push(`--load-extension=${this.userConfig?.chromeExtensionPaths}`, `--disable-extensions-except=${this.userConfig?.chromeExtensionPaths}`);
98
101
  }
99
102
  }
103
+ if (this.debuggingPort) {
104
+ options.args.push("--remote-debugging-port=9222");
105
+ }
100
106
  return options;
101
107
  }
102
108
  }
@@ -110,6 +116,7 @@ class OnboardingContext {
110
116
  cliPath;
111
117
  verboseLevel;
112
118
  useTestConfig;
119
+ debuggingPort;
113
120
  static flags = {
114
121
  ...cli_parameters_1.CLI_CONFIG_NAME,
115
122
  ...cli_parameters_1.CLI_CONFIG_IS_TEST,
@@ -122,6 +129,11 @@ class OnboardingContext {
122
129
  default: false,
123
130
  description: "Run with local documentHandler",
124
131
  }),
132
+ debuggingPort: core_1.Flags.boolean({
133
+ char: "p",
134
+ default: false,
135
+ description: "Enable remote debugging port (disables speculation rules/prerendering)",
136
+ }),
125
137
  verboseLevel: core_1.Flags.boolean({
126
138
  char: "v",
127
139
  default: false,
@@ -137,7 +149,7 @@ class OnboardingContext {
137
149
  DEFAULT_DOCUMENT_HANDLER_PATH = "https://www.baqend.com/speed-kit-handler/latest/DocumentHandler.js";
138
150
  DEFAULT_SNIPPET_PATH = "https://www.baqend.com/speed-kit/latest/snippet.js";
139
151
  DEFAULT_SW_PATH = "https://www.baqend.com/speed-kit/latest/sw.js";
140
- constructor(customerPath, configName, domain, local, ignoreContentSecurityPolicy = false, cliPath, verboseLevel, useTestConfig = false) {
152
+ constructor(customerPath, configName, domain, local, ignoreContentSecurityPolicy = false, cliPath, verboseLevel, useTestConfig = false, debuggingPort = false) {
141
153
  this.customerPath = customerPath;
142
154
  this.configName = configName;
143
155
  this.domain = domain;
@@ -146,6 +158,7 @@ class OnboardingContext {
146
158
  this.cliPath = cliPath;
147
159
  this.verboseLevel = verboseLevel;
148
160
  this.useTestConfig = useTestConfig;
161
+ this.debuggingPort = debuggingPort;
149
162
  }
150
163
  }
151
164
  exports.OnboardingContext = OnboardingContext;
@@ -75,7 +75,10 @@ class OnboardingServiceFactory {
75
75
  this.cliConfig.chromeExtensionPaths = extensionPaths.join(",");
76
76
  const browserValidator = new executable_validator_1.ExecutableValidator(this.cliConfig, cli);
77
77
  const browserVersionString = await browserValidator.validateOrInstall();
78
- const browserContext = new onboarding_model_1.BrowserContext(domainToStart, browserVersionString, customerConfig.chromeFlags || [], this.cliConfig);
78
+ const browserContext = new onboarding_model_1.BrowserContext(domainToStart, browserVersionString, customerConfig.chromeFlags || [], this.cliConfig, undefined, this.context.debuggingPort);
79
+ if (this.context.debuggingPort) {
80
+ cli.writeWarning("Chrome remote debugging enabled on port 9222.");
81
+ }
79
82
  const fileWatcher = new file_watcher_1.FileWatcher(cli, customerConfig, files, documentHandler, browserContext, cache);
80
83
  const athenaClient = (await this.getAthenaClient()) || null;
81
84
  const fetchHandler = await this.getFetchEventHandler(files, customerConfig, documentHandler, cache, cli, browserContext, athenaClient);
@@ -486,6 +486,13 @@
486
486
  "allowNo": false,
487
487
  "type": "boolean"
488
488
  },
489
+ "debuggingPort": {
490
+ "char": "p",
491
+ "description": "Enable remote debugging port (disables speculation rules/prerendering)",
492
+ "name": "debuggingPort",
493
+ "allowNo": false,
494
+ "type": "boolean"
495
+ },
489
496
  "verboseLevel": {
490
497
  "char": "v",
491
498
  "description": "Show all messages",
@@ -731,5 +738,5 @@
731
738
  ]
732
739
  }
733
740
  },
734
- "version": "3.32.0"
741
+ "version": "3.33.0"
735
742
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@speedkit/cli",
3
3
  "description": "Speed Kit CLI",
4
- "version": "3.32.0",
4
+ "version": "3.33.0",
5
5
  "author": {
6
6
  "name": "Baqend.com",
7
7
  "email": "info@baqend.com"
@@ -90,6 +90,7 @@
90
90
  "fluent-ffmpeg": "^2.1.3",
91
91
  "fs-extra": "^11.2.0",
92
92
  "handlebars": "^4.7.8",
93
+ "htmlfy": "^1.0.1",
93
94
  "htmlparser2": "8.0.2",
94
95
  "iconv-lite": "^0.7.2",
95
96
  "json2csv": "^6.0.0-alpha.2",