@speedkit/cli 2.65.0 → 2.65.2

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,17 @@
1
+ ## [2.65.2](https://gitlab.orestes.info/baqend/speed-kit-cli/compare/v2.65.1...v2.65.2) (2024-11-12)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * **speed-kit-cli:** missing opening tag in force install ([dbee840](https://gitlab.orestes.info/baqend/speed-kit-cli/commit/dbee840057c2ebbd00d032bf482297592025a818))
7
+
8
+ ## [2.65.1](https://gitlab.orestes.info/baqend/speed-kit-cli/compare/v2.65.0...v2.65.1) (2024-11-08)
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * **onboarding:** remove reference to defaultLocalDevtools ([c2c3128](https://gitlab.orestes.info/baqend/speed-kit-cli/commit/c2c3128069169488a2cc5e1da85ea77676f55e8e))
14
+
1
15
  # [2.65.0](https://gitlab.orestes.info/baqend/speed-kit-cli/compare/v2.64.0...v2.65.0) (2024-11-01)
2
16
 
3
17
 
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.65.0 linux-x64 node-v20.18.0
24
+ @speedkit/cli/2.65.2 linux-x64 node-v20.18.0
25
25
  $ sk --help [COMMAND]
26
26
  USAGE
27
27
  $ sk COMMAND
@@ -353,7 +353,7 @@ DESCRIPTION
353
353
  Display help for sk.
354
354
  ```
355
355
 
356
- _See code: [@oclif/plugin-help](https://github.com/oclif/plugin-help/blob/v6.2.3/src/commands/help.ts)_
356
+ _See code: [@oclif/plugin-help](https://github.com/oclif/plugin-help/blob/v6.2.16/src/commands/help.ts)_
357
357
 
358
358
  ## `sk login [APP]`
359
359
 
@@ -1,43 +1,9 @@
1
1
  (function() {
2
- {{#if addPreRendering}}
3
- {{#unless supportShadowDomInPreRendering}}
4
- const PRERENDER_TIMEOUT = 30_000; // 30s
5
- const PRERENDER_CHECK_INTERVAL = 300; // 300ms
6
- const preRenderedRootConfig = [
7
- // TODO: adjust/replace this exemplary list
8
- {
9
- selector: "body > #app, #speed-kit-pre-rendered-app",
10
- detectChanges: [
11
- {
12
- // header area
13
- find: "#page-root > div > .aem-container > div:nth-of-type(1)",
14
- detectChanges: [
15
- // main categories
16
- {
17
- find: 'button[id^="menu-button"] p',
18
- compare: ["text"],
19
- },
20
- // logo
21
- {
22
- find: "img[src]",
23
- compare: ["src"],
24
- },
25
- ],
26
- },
27
- ],
28
- },
29
- ];
30
-
31
- {{/unless}}
32
- {{/if}}
33
2
  /**
34
3
  * @type {DynamicBlockConfig}
35
4
  */
36
5
  window.dynamicBlockConfig = {
37
- {{#if isShopify}}
38
- dynamicScriptExecution: true, // Shopify specific
39
- // => as some async external scripts are injected more or less randomly into the html, destroying the order of local & remote scripts
40
- {{/if}}
6
+ dynamicScriptExecution: true,
41
7
  {{#if addPreRendering}}
42
8
  assetChangeDetection: {
43
9
  ignore: [
@@ -62,31 +28,30 @@
62
28
  {{/unless}}
63
29
  {{/if}}
64
30
  // TODO: adjust/replace this exemplary list
65
-
66
31
  {
67
32
  {{#if addPreRendering}}
68
- selector: '#main',
33
+ selector: ".prerendered-top-level-element",
69
34
  {{else}}
70
- selector: 'body',
35
+ selector: "body",
71
36
  {{/if}}
72
37
  detectChanges: [
73
38
  // Main Headline:
74
39
  {
75
- find: 'h1',
76
- compare: ['text'],
40
+ find: "h1",
41
+ compare: ["text"],
77
42
  },
78
43
 
79
44
  // Home:
80
45
  {
81
- find: '.stage-teaser source',
82
- compare: ['srcset'],
46
+ find: ".stage-teaser source",
47
+ compare: ["srcset"],
83
48
  },
84
49
 
85
50
  // PLP:
86
51
  {
87
- find: '.product-grid .product img',
52
+ find: ".product-grid .product img",
88
53
  limit: 9, // only compare the first 9 products
89
- compare: ['src'],
54
+ compare: ["src"],
90
55
  },
91
56
  // ...
92
57
 
@@ -95,7 +60,6 @@
95
60
  ],
96
61
  },
97
62
  {{#if isShopify}}
98
-
99
63
  // Shopify specific:
100
64
  {
101
65
  selector: "#shopify-section-announcement-bar",
@@ -135,11 +99,11 @@
135
99
 
136
100
  // Workaround for Cloudflare's Rocket Loader (e.g. needed for Shopify)
137
101
  {
138
- selector: 'script[data-cf-settings]',
102
+ selector: "script[data-cf-settings]",
139
103
  mergeFunction: function (localBlock, remoteBlock) {
140
- let cFHash = remoteBlock.getAttribute('data-cf-settings');
141
- localBlock.setAttribute('data-cf-settings', cFHash);
142
- let deferScripts = document.querySelectorAll('script[src][defer]');
104
+ let cFHash = remoteBlock.getAttribute("data-cf-settings");
105
+ localBlock.setAttribute("data-cf-settings", cFHash);
106
+ let deferScripts = document.querySelectorAll("script[src][defer]");
143
107
  deferScripts.forEach((deferScript) => {
144
108
  let type = deferScript.type;
145
109
  type = type.replace(/[a-f0-9]{24}/, cFHash.split('-')[0]);
@@ -150,327 +114,36 @@
150
114
  {{/if}}
151
115
 
152
116
  // default entries
153
- {selector: 'link[rel="canonical"]'},
154
- {selector: 'meta[name]', idAttribute: 'name'},
155
- {selector: 'meta[property]', idAttribute: 'property'},
156
- {selector: 'script[type="application/ld+json"]'},
117
+ { selector: 'link[rel="canonical"]'},
118
+ { selector: "meta[name]", idAttribute: "name"},
119
+ { selector: 'meta[property]', idAttribute: "property"},
120
+ { selector: 'script[type="application/ld+json"]'},
157
121
  ],
158
- };
159
-
160
- //================================================================================
161
- // Utility Functions
162
- //================================================================================
163
-
164
- {{#if addPreRendering}}
165
- {{#if supportShadowDomInPreRendering}}
166
- const preRenderedRootConfig = [
167
- // TODO: adjust/replace this exemplary list
168
- // TODO: accessing elements within a shadow-dom, nested detectChanges is needed on that level
169
- {
170
- selector: ".sk-container",
171
- remote: "body > #app",
122
+ {{#if addPreRendering}}
123
+ preRenderedRootConfig: [
124
+ // TODO: adjust/replace this exemplary list
125
+ {
126
+ selector: ".prerendered-top-level-element",
172
127
  detectChanges: [
173
128
  {
174
- find: "tef-carousel",
129
+ // header area
130
+ find: "#page-root > div > .aem-container > div:nth-of-type(1)",
175
131
  detectChanges: [
132
+ // main categories
133
+ {
134
+ find: 'button[id^="menu-button"] p',
135
+ compare: ["text"],
136
+ },
137
+ // logo
176
138
  {
177
- find: ".slide tef-stage-teaser",
178
- detectChanges: [
179
- {
180
- find: '[slot="visual"] source',
181
- compare: ["srcset"],
182
- },
183
- {
184
- find: '[slot="overline"]',
185
- compare: ["text"],
186
- },
187
- ],
139
+ find: "img[src]",
140
+ compare: ["src"],
188
141
  },
189
142
  ],
190
143
  },
191
- ],
192
- },
193
- ];
194
-
195
- document.addEventListener("dynamic-fetcher-data-ready", function () {
196
- setTimeout(() => {
197
- registerRemoteRenderObserver();
198
- }, 500);
199
- });
200
-
201
- function registerRemoteRenderObserver() {
202
- window?.performance?.mark("sk-prerender-observe-start");
203
-
204
- let promises = [];
205
- for (const preRenderedRoot of preRenderedRootConfig) {
206
- const remoteSelector = preRenderedRoot.remote;
207
- const remoteRootElement = document.querySelector(remoteSelector);
208
- if (!remoteRootElement) {
209
- continue;
210
- }
211
- promises = [...promises, ...collectWaitForEvents(remoteRootElement)];
212
- }
213
- removePlaceholderWhenResolved(promises);
214
- }
215
-
216
- function collectWaitForEvents(remoteRootElement) {
217
- const undefinedElements =
218
- remoteRootElement.querySelectorAll(":not(:defined)");
219
- return [...undefinedElements]
220
- .filter((element) => element.localName.startsWith("{{shadowDomCustomElementPrefix}}"))
221
- .map((element) => {
222
- return customElements.whenDefined(element.localName);
223
- });
224
- }
225
-
226
- /**
227
- * checks for all webComponents to be ready before switching to origin
228
- *
229
- * @param remoteRootElement
230
- */
231
- function removePlaceholderWhenResolved(promises) {
232
- const preRenderedPlaceHolders = document.querySelectorAll(
233
- ".speed-kit-shadow-app-root",
234
- );
235
- Promise.race([
236
- Promise.all(promises),
237
- new Promise((resolve) => {
238
- setTimeout(resolve, 5000);
239
- }),
240
- ])
241
- .catch((error) => {})
242
- .then(() => {
243
- try {
244
- detectChanges();
245
- } catch (error) {}
246
- preRenderedPlaceHolders.forEach((localRootElement) =>
247
- localRootElement.remove(),
248
- );
249
- dispatchReadyEvent(window.dynamicBlockConfig.preRenderWaitFor);
250
- });
251
- }
252
- {{else}}
253
- function handlePreRenderBlock(localBlock, remoteBlock) {
254
- // handle preRendering by inserting pre-rendered #app before initial #app
255
- if (
256
- window.dynamicBlockConfig.preRenderWaitFor &&
257
- window.dynamicBlockConfig.preRenderWaitFor.length > 0
258
- ) {
259
- localBlock.classList.add("speed-kit-shadow-app-root");
260
- localBlock.before(remoteBlock);
261
- return;
262
- }
263
- SpeedKit.replaceBlock(localBlock, remoteBlock);
264
- }
265
-
266
- document.addEventListener("dynamic-fetcher-data-ready", () => {
267
- function registerRemoteRenderObserver() {
268
- window?.performance?.mark("sk-prerender-observe-start");
269
-
270
- for (const preRenderedRoot of preRenderedRootConfig) {
271
- const selector = preRenderedRoot.selector
272
- .split(",")
273
- .map((selector) => {
274
- return selector + ".speed-kit-pre-rendered-block-added";
275
- })
276
- .join(",");
277
-
278
- const localRootElement = document.querySelector(selector);
279
-
280
- if (!localRootElement) {
281
- continue;
282
- }
283
- removePlaceholder(localRootElement);
284
- }
285
- }
286
- registerRemoteRenderObserver();
287
- });
288
-
289
- /**
290
- * checks for all webComponents to be ready before switching to origin
291
- *
292
- * @param localRootElement
293
- */
294
- function removePlaceholder(localRootElement) {
295
- let waitFor = [];
296
- for (let selector of window.dynamicBlockConfig.preRenderWaitFor) {
297
- waitFor.push(
298
- querySelectorWithRetry(
299
- document,
300
- selector,
301
- PRERENDER_CHECK_INTERVAL,
302
- Math.floor(PRERENDER_TIMEOUT / PRERENDER_CHECK_INTERVAL),
303
- ),
304
- );
305
- }
306
-
307
- const promises = [...waitFor];
308
-
309
- Promise.race([
310
- Promise.all(promises),
311
- new Promise((resolve) => {
312
- setTimeout(resolve, PRERENDER_TIMEOUT);
313
- }),
314
- ])
315
- .catch((error) => {})
316
- .then(() => {
317
- try {
318
- detectChanges(
319
- localRootElement,
320
- window.dynamicBlockConfig.preRenderWaitFor,
321
- );
322
- } catch (error) {}
323
- localRootElement.remove();
324
- dispatchReadyEvent(window.dynamicBlockConfig.preRenderWaitFor);
325
- });
326
- }
327
-
328
- async function sleep(interval = 100) {
329
- return new Promise((resolve) => setTimeout(resolve, interval));
330
- }
331
-
332
- /**
333
- * retry searching for a given selector in the actual app root
334
- * @param root
335
- * @param selector
336
- * @param retryInterval
337
- * @param maxAttempts
338
- * @returns {Promise<*>}
339
- */
340
- async function querySelectorWithRetry(
341
- root,
342
- selector,
343
- retryInterval = 100,
344
- maxAttempts = 50,
345
- ) {
346
- for (let i = 0; i < maxAttempts; i++) {
347
- const element = root.querySelector(selector);
348
- if (element) {
349
- return element;
350
- }
351
- await sleep(retryInterval);
352
- }
353
- }
354
- {{/if}}
355
- /**
356
- * dispatch prerender ready event after shadow app root was removed
357
- */
358
- function dispatchReadyEvent(preRenderWaitForElement) {
359
- window?.performance?.mark("sk-prerender-observe-end");
360
- document.dispatchEvent(
361
- new CustomEvent("speed-kit-prerender-ready", {
362
- detail: { element: preRenderWaitForElement },
363
- }),
364
- );
365
- document.querySelector("html").classList.add("sk-prerender-ready");
366
- }
367
-
368
- function detectChanges() {
369
- window?.performance?.mark("sk-prerender-change-detection-start");
370
-
371
- for (const config of preRenderedRootConfig) {
372
- const localRootElement = document.querySelector(
373
- `${config.selector}.speed-kit-pre-rendered-block-added`,
374
- );
375
- const remoteRootElement = document.querySelector(
376
- `${config.selector}:not(.speed-kit-pre-rendered-block-added)`,
377
- );
378
-
379
- if (!localRootElement || !remoteRootElement) {
380
- continue;
381
- }
382
- if (config.detectChanges && config.detectChanges.length > 0) {
383
- for (const detect of config.detectChanges) {
384
- detectChangesInBlock(localRootElement, remoteRootElement, detect);
385
- }
386
- }
387
- }
388
- window?.performance?.mark("sk-prerender-change-detection-end");
389
- }
390
-
391
- function detectChangesInBlock(
392
- parentLocalElement,
393
- parentRemoteElement,
394
- config,
395
- ) {
396
- const localRootElement = parentLocalElement.querySelector(config.find);
397
- const remoteRootElement = parentRemoteElement.querySelector(config.find);
398
-
399
- if (!localRootElement) {
400
- return;
401
- }
402
-
403
- if (!remoteRootElement) {
404
- sendRevalidation(config.find, "remote block not found");
405
- }
406
-
407
- // on next subElement search for changes
408
- if (config.detectChanges && config.detectChanges.length > 0) {
409
- for (const detect of config.detectChanges) {
410
- detectChangesInBlock(localRootElement, remoteRootElement, detect);
411
- }
412
- return;
413
- }
414
-
415
- if (!config.compare || config.compare.length === 0) {
416
- return;
417
- }
418
-
419
- for (const compare of config.compare) {
420
- if (
421
- compare === "text" &&
422
- localRootElement.innerHTML !== remoteRootElement.innerHTML
423
- ) {
424
- sendRevalidation(config.find, "content diffs");
425
- continue;
426
- }
427
-
428
- if (
429
- localRootElement.hasAttribute(compare) &&
430
- remoteRootElement.hasAttribute(compare) &&
431
- localRootElement.getAttribute(compare) !==
432
- remoteRootElement.getAttribute(compare)
433
- ) {
434
- sendRevalidation(config.find, `${compare} diffs`);
435
- }
436
- }
437
- }
438
-
439
- /**
440
- * @param selector {string}
441
- * @param reason {string}
442
- */
443
- function sendRevalidation(selector, reason) {
444
- let baqendAssetUrl = location.href;
445
- let userId = window.SpeedKit.userId || "";
446
- let sessionId = window.SpeedKit.sessionId || "";
447
- let navigateId = window.SpeedKit.navigateId;
448
-
449
- let detectedChanges = {
450
- url: baqendAssetUrl,
451
- triggeredBy: { [selector]: [reason] },
452
- };
453
-
454
- let beaconUrl =
455
- "https://" +
456
- window.dynamicBlockConfig.appName +
457
- ".app.baqend.com/v1/rum/pi";
458
- let data = {
459
- piId: navigateId,
460
- userId: userId,
461
- sessionId: sessionId,
462
- changeDetection: detectedChanges,
463
- debug: true,
464
- };
465
-
466
- if (navigator.sendBeacon) {
467
- navigator.sendBeacon(beaconUrl, JSON.stringify(data));
468
- return;
469
- }
470
-
471
- let xhr = new XMLHttpRequest();
472
- xhr.open("POST", beaconUrl, true);
473
- xhr.send(JSON.stringify(data));
474
- }
475
- {{/if}}
144
+ ],
145
+ },
146
+ ],
147
+ {{/if}}
148
+ };
476
149
  })();
@@ -8,7 +8,6 @@ const cli_1 = require("../../../cli");
8
8
  const safe_1 = require("../../../../helpers/safe");
9
9
  const node_fs_1 = require("node:fs");
10
10
  const browser_extension_error_1 = require("../../error/browser-extension-error");
11
- const SPEED_KIT_EXTENSION_NAME = "Speed Kit DevTools Extension";
12
11
  class ExtensionValidator {
13
12
  cliConfig;
14
13
  cliBasePath;
@@ -21,7 +20,6 @@ class ExtensionValidator {
21
20
  async getValidBrowserExtensionPaths() {
22
21
  const validExtensions = [];
23
22
  const validPaths = [];
24
- let addIncludedExtension = true;
25
23
  this.cli.startAction("resolve browserExtensions");
26
24
  const browserExtensions = this.cliConfig.chromeExtensionPaths
27
25
  .split(",")
@@ -34,9 +32,6 @@ class ExtensionValidator {
34
32
  if (!manifestConfig) {
35
33
  continue;
36
34
  }
37
- if (manifestConfig.name.includes(SPEED_KIT_EXTENSION_NAME)) {
38
- addIncludedExtension = false;
39
- }
40
35
  validExtensions.push({
41
36
  path: cleanedExtensionPath,
42
37
  name: manifestConfig.name,
@@ -48,9 +43,6 @@ class ExtensionValidator {
48
43
  if (validExtensions.length > 0) {
49
44
  this.cli.table(validExtensions, { name: {}, version: {}, path: {} });
50
45
  }
51
- if (addIncludedExtension) {
52
- validPaths.push(node_path_1.default.resolve(this.cliBasePath, "chrome-dist", "devtools"));
53
- }
54
46
  return validPaths;
55
47
  }
56
48
  async getManifestConfig(cleanedExtensionPath) {
@@ -113,9 +113,19 @@ class CustomerDomainDocumentResponse {
113
113
  }
114
114
  rewriteInstallResource(text) {
115
115
  text = text.replace(onboarding_model_1.SpeedKitInstallRegex, "");
116
- return text.replace(/<\s*head\b[^>]*>/, (head) => {
117
- return `${head}\n<script src="${this.customerConfig.installPath}" ${this.customerConfig.installParams}></script>`;
118
- });
116
+ const matchOpeningHead = /<\s*head\b[^>]*>/;
117
+ const matchClosingHead = /<\/\s*head\s*>/;
118
+ if (matchOpeningHead.test(text)) {
119
+ return text.replace(matchOpeningHead, (head) => {
120
+ return `${head}\n<script src="${this.customerConfig.installPath}" ${this.customerConfig.installParams}></script>`;
121
+ });
122
+ }
123
+ if (matchClosingHead.test(text)) {
124
+ return text.replace(matchClosingHead, (head) => {
125
+ return `<script src="${this.customerConfig.installPath}" ${this.customerConfig.installParams}></script>${head}\n`;
126
+ });
127
+ }
128
+ return text;
119
129
  }
120
130
  rewriteHtmlToLocalConfig(html) {
121
131
  const DF_CONFIG_PATTERN = /(<script[^>]* id="speed-kit-df-config"[^>]*>)([\S\s]*?)(<\/script>)/g;
@@ -712,5 +712,5 @@
712
712
  ]
713
713
  }
714
714
  },
715
- "version": "2.65.0"
715
+ "version": "2.65.2"
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.65.0",
4
+ "version": "2.65.2",
5
5
  "author": {
6
6
  "name": "Baqend.com",
7
7
  "email": "info@baqend.com"
@@ -66,27 +66,27 @@
66
66
  "type": "commonjs",
67
67
  "dependencies": {
68
68
  "@aws-sdk/client-athena": "^3.529",
69
- "@inquirer/prompts": "^3.0",
69
+ "@inquirer/prompts": "^3.3.2",
70
70
  "@oclif/core": "^3.23",
71
71
  "@oclif/plugin-autocomplete": "^3.0",
72
- "@oclif/plugin-help": "^6.0",
73
- "@oclif/plugin-not-found": "^3.0",
74
- "@oclif/plugin-warn-if-update-available": "^3.0",
72
+ "@oclif/plugin-help": "^6.2.16",
73
+ "@oclif/plugin-not-found": "^3.2.25",
74
+ "@oclif/plugin-warn-if-update-available": "^3.1.21",
75
75
  "axios": "^1.6",
76
76
  "baqend": "^3.4",
77
- "chalk": "^4",
77
+ "chalk": "^4.1.2",
78
78
  "clipboardy-cjs": "^3.0.0",
79
79
  "css-select": "5.1.0",
80
- "deepmerge": "^4.2.2",
80
+ "deepmerge": "^4.3.1",
81
81
  "diff": "^5.1.0",
82
82
  "dom-serializer": "2.0.0",
83
83
  "domhandler": "5.0.3",
84
84
  "domutils": "^3.1",
85
- "dotenv": "^16.4",
85
+ "dotenv": "^16.4.5",
86
86
  "extract-zip": "^2.0.1",
87
87
  "fs-extra": "^11.2.0",
88
88
  "handlebars": "^4.7.8",
89
- "htmlparser2": "8.0",
89
+ "htmlparser2": "8.0.2",
90
90
  "json2csv": "^6.0.0-alpha.2",
91
91
  "node-fetch": "^2.7.0",
92
92
  "parse5": "7.1",
@@ -101,8 +101,8 @@
101
101
  "ts-node": "^10.9.2"
102
102
  },
103
103
  "devDependencies": {
104
- "@commitlint/cli": "^17.7.1",
105
- "@commitlint/config-conventional": "^17.7.0",
104
+ "@commitlint/cli": "^17.8.1",
105
+ "@commitlint/config-conventional": "^17.8.1",
106
106
  "@istanbuljs/nyc-config-typescript": "^1.0.2",
107
107
  "@oclif/prettier-config": "^0.2.1",
108
108
  "@oclif/test": "^3",
@@ -115,18 +115,18 @@
115
115
  "@typescript-eslint/eslint-plugin": "^7.2.0",
116
116
  "chai": "^4.4.1",
117
117
  "copyfiles": "^2.4.1",
118
- "eslint": "^8.57",
118
+ "eslint": "^8.57.1",
119
119
  "eslint-config-prettier": "^9.1",
120
120
  "eslint-plugin-prettier": "^5.1",
121
121
  "eslint-plugin-unicorn": "^51.0.1",
122
- "globby": "^11",
122
+ "globby": "^11.1.0",
123
123
  "husky": "^8.0.3",
124
124
  "lint-staged": "^14.0.1",
125
125
  "memfs": "^4.8.0",
126
126
  "mocha": "^10.1.0",
127
127
  "mocha-junit-reporter": "^2.2.1",
128
128
  "mock-fs": "^5.2.0",
129
- "nock": "^13.5",
129
+ "nock": "^13.5.5",
130
130
  "nyc": "^15.1.0",
131
131
  "oclif": "^4.8.8",
132
132
  "shx": "^0.3.4",