@speedkit/cli 3.42.0 → 3.43.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.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,19 @@
1
+ ## [3.43.1](https://gitlab.orestes.info/baqend/speed-kit-cli/compare/v3.43.0...v3.43.1) (2026-04-23)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * make queryBuilder compatible to plugins ([14374d0](https://gitlab.orestes.info/baqend/speed-kit-cli/commit/14374d00d48da1b1316dc69fd5949022acb62ede))
7
+
8
+ # [3.43.0](https://gitlab.orestes.info/baqend/speed-kit-cli/compare/v3.42.0...v3.43.0) (2026-04-23)
9
+
10
+
11
+ ### Features
12
+
13
+ * **deploy-checks:** polyfill setTimeout and addEventListener in sandboxed config evaluation ([4dac3f0](https://gitlab.orestes.info/baqend/speed-kit-cli/commit/4dac3f04fab2d2f60077a5a301aefef016d57b0f))
14
+ * **onboarding:** hide Chrome automation signals to avoid WAF blocks ([6065442](https://gitlab.orestes.info/baqend/speed-kit-cli/commit/60654424e7a980fd4f8858bdb656ab482b0b9ef1))
15
+ * **onboarding:** serve empty service worker for ?empty=1 requests ([403ad50](https://gitlab.orestes.info/baqend/speed-kit-cli/commit/403ad50bfe953868e63b9a2cd101503fdd1b0c56))
16
+
1
17
  # [3.42.0](https://gitlab.orestes.info/baqend/speed-kit-cli/compare/v3.41.0...v3.42.0) (2026-04-23)
2
18
 
3
19
 
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.42.0 linux-x64 node-v20.20.2
24
+ @speedkit/cli/3.43.1 linux-x64 node-v20.20.2
25
25
  $ sk --help [COMMAND]
26
26
  USAGE
27
27
  $ sk COMMAND
@@ -1,4 +1,10 @@
1
1
  import { InstallResourceFile } from "../services/integration-api";
2
+ export declare function evaluateLocalSpeedKitConfig(app: string, origin: string, speedKitConfigFile: InstallResourceFile): Promise<{
3
+ split: any;
4
+ splitTestId: any;
5
+ detectDevice: () => void;
6
+ customVariation: any[];
7
+ }>;
2
8
  export declare function evaluateLocalAndRemoteSpeedKit(app: string, origin: string, speedKitConfigFile: InstallResourceFile, activeSpeedKitConfig: string): Promise<{
3
9
  localSpeedKit: {
4
10
  split: any;
@@ -1,10 +1,24 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.evaluateLocalSpeedKitConfig = evaluateLocalSpeedKitConfig;
3
4
  exports.evaluateLocalAndRemoteSpeedKit = evaluateLocalAndRemoteSpeedKit;
4
5
  const tslib_1 = require("tslib");
5
6
  const evaluate_sk_config_error_1 = require("../services/deploy/error/evaluate-sk-config-error");
6
7
  const vm = tslib_1.__importStar(require("node:vm"));
7
8
  const bundler_1 = require("../services/bundler");
9
+ async function evaluateLocalSpeedKitConfig(app, origin, speedKitConfigFile) {
10
+ const localBrowserContext = buildBrowserMock(origin, app);
11
+ const localFileContent = safeFileContentWrapper(await bundle(speedKitConfigFile.getContent(), app));
12
+ vm.runInNewContext(localFileContent, localBrowserContext, {
13
+ filename: speedKitConfigFile.path,
14
+ displayErrors: false,
15
+ breakOnSigint: true,
16
+ });
17
+ if (localBrowserContext.vmError !== null) {
18
+ throw new evaluate_sk_config_error_1.EvaluateSkConfigError(`[config_Speedkit.js] ${localBrowserContext.vmError?.message}`);
19
+ }
20
+ return localBrowserContext.window.speedKit;
21
+ }
8
22
  async function evaluateLocalAndRemoteSpeedKit(app, origin, speedKitConfigFile, activeSpeedKitConfig) {
9
23
  const localBrowserContext = buildBrowserMock(origin, app);
10
24
  const localFileContent = safeFileContentWrapper(await bundle(speedKitConfigFile.getContent(), app));
@@ -44,7 +58,10 @@ function buildBrowserMock(origin, app) {
44
58
  serviceWorkerUrl: "",
45
59
  screen: { width: 0, height: 0 },
46
60
  devicePixelRatio: 1,
47
- setTimeout: (callBack, time) => setTimeout(callBack, time),
61
+ setTimeout: () => { },
62
+ clearTimeout: () => { },
63
+ addEventListener: () => { },
64
+ removeEventListener: () => { },
48
65
  navigator: {
49
66
  userAgent: "",
50
67
  connection: {},
@@ -61,6 +78,7 @@ function buildBrowserMock(origin, app) {
61
78
  querySelectorAll: () => { },
62
79
  createElement: () => { },
63
80
  addEventListener: () => { },
81
+ removeEventListener: () => { },
64
82
  head: {},
65
83
  body: {},
66
84
  };
@@ -10,5 +10,5 @@ export declare class CustomerServiceWorkerJs implements FetchRequestPausedEventH
10
10
  private customerConfig;
11
11
  get patterns(): Protocol.Fetch.RequestPattern[];
12
12
  constructor(customerConfig: CustomerConfig);
13
- handle(): Promise<Partial<Protocol.Fetch.FulfillRequestRequest>>;
13
+ handle(event: Protocol.Fetch.RequestPausedEvent): Promise<Partial<Protocol.Fetch.FulfillRequestRequest>>;
14
14
  }
@@ -22,7 +22,13 @@ class CustomerServiceWorkerJs {
22
22
  constructor(customerConfig) {
23
23
  this.customerConfig = customerConfig;
24
24
  }
25
- async handle() {
25
+ async handle(event) {
26
+ // When the SW is registered with `?empty=1`, the caller wants a no-op
27
+ // service worker on that scope — serve an empty script instead of the
28
+ // skonboarding wrapper that imports Speed Kit's sw.js.
29
+ if (new URL(event.request.url).searchParams.get("empty") === "1") {
30
+ return new baqend_response_1.BaqendResponse("// skonboarding empty sw", "text/javascript; charset=utf-8");
31
+ }
26
32
  const wrapperSwCode = `importScripts(\`https://${this.customerConfig.appDomain}/v1/speedkit/sw.js\${location.search}\`); // skonboarding`;
27
33
  return new baqend_response_1.BaqendResponse(wrapperSwCode, "text/javascript; charset=utf-8");
28
34
  }
@@ -9,8 +9,11 @@ const DEFAULT_BROWSER_ARGS = [
9
9
  "--enable-features=Translate,NetworkService",
10
10
  "--no-first-run",
11
11
  "--no-default-browser-check",
12
- "--disable-infobars",
13
- // "--enable-automation",
12
+ // Hides the `navigator.webdriver` fingerprint so customer CDN/WAF rules don't treat the session as a bot.
13
+ "--disable-blink-features=AutomationControlled",
14
+ // Signals a test environment so Chrome suppresses the "unsupported command-line flag" infobar
15
+ // triggered by the flag above. Value is arbitrary and only used as an identifier.
16
+ "--test-type=speed-kit-cli",
14
17
  ];
15
18
  exports.BROWSER_EVENTS = {
16
19
  DISCONNECTED: "disconnected",
@@ -91,6 +94,9 @@ class BrowserContext {
91
94
  headless: this.headless,
92
95
  executablePath: this.chromePath,
93
96
  args: this.browserArgs,
97
+ // Strip Puppeteer's default `--enable-automation` so Chrome doesn't show
98
+ // the "Chrome is being controlled by automated test software" infobar.
99
+ ignoreDefaultArgs: ["--enable-automation"],
94
100
  };
95
101
  if (this.userConfig?.chromeExtensionPaths) {
96
102
  if (this.isChromeBrowser()) {
@@ -4,10 +4,10 @@ exports.QueryBuilderFactory = void 0;
4
4
  const query_builder_service_1 = require("./query-builder-service");
5
5
  const integration_api_1 = require("../integration-api");
6
6
  const files_1 = require("../../models/files");
7
- const get_parsed_config_1 = require("../../helpers/get-parsed-config");
8
7
  const cli_1 = require("../cli");
9
8
  const safe_1 = require("../../helpers/safe");
10
9
  const parse_config_speed_kit_error_1 = require("./error/parse-config-speed-kit-error");
10
+ const evaluate_speed_kit_config_1 = require("../../helpers/evaluate-speed-kit-config");
11
11
  class QueryBuilderFactory {
12
12
  context;
13
13
  userConfig;
@@ -18,9 +18,11 @@ class QueryBuilderFactory {
18
18
  async buildService(queryType) {
19
19
  const cli = new cli_1.CliServiceFactory().getService();
20
20
  const files = await this.getIntegrationFiles();
21
- const app = files.getCustomerConfig().config.app;
21
+ const customerConfig = files.getCustomerConfig().config;
22
+ const app = customerConfig.app;
23
+ const origin = customerConfig.origins[0];
22
24
  const speedKitConfigFile = files.getByName(files_1.INTEGRATION_FILES.CONFIG.SPEED_KIT);
23
- const speedKitConfig = this.getSpeedKitConfig(speedKitConfigFile.getContent());
25
+ const speedKitConfig = await this.getSpeedKitConfig(app, origin, speedKitConfigFile);
24
26
  const serviceContext = {
25
27
  app,
26
28
  queryType,
@@ -34,11 +36,9 @@ class QueryBuilderFactory {
34
36
  const integrationApi = new integration_api_1.IntegrationApiFactory(integrationApiContext, this.userConfig).buildService();
35
37
  return await integrationApi.run();
36
38
  }
37
- // todo create a customService to exchange parseSpeedKitConfig()
38
- // this service then can also be used in: deploy/checks/pre-deploy
39
- getSpeedKitConfig(fileContentString) {
39
+ getSpeedKitConfig(app, origin, speedKitConfigFile) {
40
40
  const result = (0, safe_1.safe)(() => {
41
- return (0, get_parsed_config_1.parseSpeedKitConfig)(fileContentString);
41
+ return (0, evaluate_speed_kit_config_1.evaluateLocalSpeedKitConfig)(app, origin, speedKitConfigFile);
42
42
  });
43
43
  if (result.success !== true) {
44
44
  throw new parse_config_speed_kit_error_1.ParseConfigSpeedKitError(result.error);
@@ -9,6 +9,7 @@ const query_builder_model_1 = require("./query-builder-model");
9
9
  const prewarm_1 = require("./query/prewarm");
10
10
  const parameter_1 = require("./query/parameter");
11
11
  const cli_1 = require("../cli");
12
+ const safe_1 = require("../../helpers/safe");
12
13
  class QueryBuilderService {
13
14
  context;
14
15
  speedKitConfig;
@@ -20,22 +21,29 @@ class QueryBuilderService {
20
21
  }
21
22
  async run() {
22
23
  this.cli.startAction(`build ${this.context.queryType}-query`);
24
+ console.log(this.speedKitConfig);
23
25
  const parameters = (0, build_query_helper_1.getStrippedParameters)(this.speedKitConfig);
24
26
  const parameterReplaceFilter = (0, build_query_helper_1.getParameterReplaceFilter)(parameters, (0, get_parsed_config_1.getSpeedKitConfigVersion)(this.speedKitConfig));
25
27
  const whitelistedFilter = (0, build_query_helper_1.getWhitelistedFilter)(this.speedKitConfig);
26
28
  const blacklistedFilter = (0, build_query_helper_1.getBlacklistedFilter)(this.speedKitConfig);
27
29
  const skConfigVersion = (0, get_parsed_config_1.getSpeedKitConfigVersion)(this.speedKitConfig);
28
30
  const parameterFilter = (0, build_query_helper_1.getParameterFilter)(parameters, skConfigVersion);
29
- const result = this.buildQuery(this.context.app, parameterFilter, whitelistedFilter, blacklistedFilter, parameterReplaceFilter);
31
+ const result = (0, safe_1.safe)(() => this.buildQuery(this.context.app, parameterFilter, whitelistedFilter, blacklistedFilter, parameterReplaceFilter));
32
+ if (result.success !== true) {
33
+ this.cli.endAction(cli_1.CliActionStatus.FAILED);
34
+ this.cli.writeError(result.error);
35
+ console.error(result.errorObj);
36
+ return;
37
+ }
30
38
  this.cli.endAction(cli_1.CliActionStatus.COMPLETED);
31
39
  if (this.context.quiet) {
32
- process.stdout.write(result);
40
+ process.stdout.write(result.data);
33
41
  return;
34
42
  }
35
43
  if (!this.context.isWindows) {
36
- clipboardy_cjs_1.default.writeSync(result);
44
+ clipboardy_cjs_1.default.writeSync(result.data);
37
45
  }
38
- this.cli.write(this.cli.style.dim.italic(result));
46
+ this.cli.write(this.cli.style.dim.italic(result.data));
39
47
  if (!this.context.isWindows) {
40
48
  this.cli.writeSuccess("Result has been copied to the clipboard 📋");
41
49
  }
@@ -751,5 +751,5 @@
751
751
  ]
752
752
  }
753
753
  },
754
- "version": "3.42.0"
754
+ "version": "3.43.1"
755
755
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@speedkit/cli",
3
3
  "description": "Speed Kit CLI",
4
- "version": "3.42.0",
4
+ "version": "3.43.1",
5
5
  "author": {
6
6
  "name": "Baqend.com",
7
7
  "email": "info@baqend.com"