@speedkit/cli 2.80.0 → 2.85.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 +63 -0
- package/README.md +1 -1
- package/dist/services/config-api/client.js +3 -1
- package/dist/services/config-api/config-api-model.d.ts +5 -0
- package/dist/services/config-api/config-api-service.d.ts +1 -0
- package/dist/services/config-api/config-api-service.js +7 -0
- package/dist/services/config-api/error/orestes-api-error.d.ts +8 -0
- package/dist/services/config-api/error/orestes-api-error.js +18 -0
- package/dist/services/customer-config/customer-config-service.js +5 -3
- package/dist/services/customer-config/templates/config_SpeedKit.js.hbs +40 -4
- package/dist/services/customer-config/templates/config_customer.js.hbs +1 -5
- package/dist/services/customer-config/templates/config_documentHandler.js.hbs +9 -7
- package/dist/services/customer-config/templates/config_dynamicBlocks.es6.hbs +0 -5
- package/dist/services/customer-config/templates/config_dynamicStyles.css.hbs +74 -64
- package/dist/services/customer-config/templates/config_loadHandler.js.hbs +15 -1
- package/dist/services/deploy/handler/install-resource-handler.js +22 -4
- package/dist/services/diff/diff-service.js +1 -1
- package/dist/services/diff-service.js +1 -1
- package/dist/services/onboarding/fetch-events/speed-kit-install-js.d.ts +5 -0
- package/dist/services/onboarding/fetch-events/speed-kit-install-js.js +20 -8
- package/dist/services/onboarding/templates/install-speed-kit-js-template.js +1 -0
- package/dist/services/onboarding/virtual-orestes-app/index.js +1 -1
- package/dist/services/pull/pull-service.js +2 -2
- package/dist/templates/speedKit.Revalidated.js +2 -5
- package/oclif.manifest.json +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,66 @@
|
|
|
1
|
+
## [2.85.1](https://gitlab.orestes.info/baqend/speed-kit-cli/compare/v2.85.0...v2.85.1) (2025-05-21)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* **onboarding:** force group a while starting onboarding ([4c5273d](https://gitlab.orestes.info/baqend/speed-kit-cli/commit/4c5273d1d1d72906a564d24986b9096426f89d83))
|
|
7
|
+
|
|
8
|
+
# [2.85.0](https://gitlab.orestes.info/baqend/speed-kit-cli/compare/v2.84.0...v2.85.0) (2025-05-20)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Features
|
|
12
|
+
|
|
13
|
+
* **customer-config:** extend default query parameter stripping ([4ce3bcf](https://gitlab.orestes.info/baqend/speed-kit-cli/commit/4ce3bcf72c5de9af95438eaf3a8e6ba05999b14f))
|
|
14
|
+
* **customer-config:** extend default query parameter stripping ([9e57ebc](https://gitlab.orestes.info/baqend/speed-kit-cli/commit/9e57ebcb73298984f3277e253e2c33925adf2b79))
|
|
15
|
+
* **customer-config:** extend default query parameter stripping ([5929cca](https://gitlab.orestes.info/baqend/speed-kit-cli/commit/5929ccac64387b745330f69f784ce9793bdafe6d))
|
|
16
|
+
|
|
17
|
+
# [2.84.0](https://gitlab.orestes.info/baqend/speed-kit-cli/compare/v2.83.1...v2.84.0) (2025-05-09)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
### Features
|
|
21
|
+
|
|
22
|
+
* **customer-config:** remove special config name for shopify ([4a5140f](https://gitlab.orestes.info/baqend/speed-kit-cli/commit/4a5140f9ec889cdbae3636b863363a6b4f1d69f0))
|
|
23
|
+
|
|
24
|
+
## [2.83.1](https://gitlab.orestes.info/baqend/speed-kit-cli/compare/v2.83.0...v2.83.1) (2025-04-15)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
### Bug Fixes
|
|
28
|
+
|
|
29
|
+
* support case-sensitive variations in pre-warming code ([4ff217b](https://gitlab.orestes.info/baqend/speed-kit-cli/commit/4ff217b662eb002cb7493bbea98a70fa6ca76809))
|
|
30
|
+
|
|
31
|
+
# [2.83.0](https://gitlab.orestes.info/baqend/speed-kit-cli/compare/v2.82.0...v2.83.0) (2025-04-14)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
### Features
|
|
35
|
+
|
|
36
|
+
* **deploy:** add more detailed orestest-api-error ([0c171ef](https://gitlab.orestes.info/baqend/speed-kit-cli/commit/0c171eff60a935506586ca75731c3143bd442055))
|
|
37
|
+
|
|
38
|
+
# [2.82.0](https://gitlab.orestes.info/baqend/speed-kit-cli/compare/v2.81.0...v2.82.0) (2025-04-02)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
### Bug Fixes
|
|
42
|
+
|
|
43
|
+
* **deploy:** on no remote content dont change file contents to dummy content ([5372033](https://gitlab.orestes.info/baqend/speed-kit-cli/commit/5372033a8d2dc8059ecc9463bee901370451dc07))
|
|
44
|
+
* **onboarding:** always try to get current configVersion from orestes ([126c157](https://gitlab.orestes.info/baqend/speed-kit-cli/commit/126c157b4cab3c884ff18e233491e76e329d9f24))
|
|
45
|
+
* **pull:** on no remote content dont delete local files but have empty content instead ([74181dd](https://gitlab.orestes.info/baqend/speed-kit-cli/commit/74181dddfaeea977aa0353cdbe1a1c10df5e4884))
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
### Features
|
|
49
|
+
|
|
50
|
+
* **customer-config:** remove df ignore list ([95e4e5a](https://gitlab.orestes.info/baqend/speed-kit-cli/commit/95e4e5ae26e825a07ef6ac123784cd6b790dceef))
|
|
51
|
+
* **customer-config:** switch to css nesting ([945d0c4](https://gitlab.orestes.info/baqend/speed-kit-cli/commit/945d0c4f0287c93703d55893747378e392521c6b))
|
|
52
|
+
* **deploy:** add support for activating testing installation ([f301ce1](https://gitlab.orestes.info/baqend/speed-kit-cli/commit/f301ce1d9d56424c962a28060dd82fac89aad625))
|
|
53
|
+
* **onboarding:** simplify extractConfigVersionRegex ([5dff39f](https://gitlab.orestes.info/baqend/speed-kit-cli/commit/5dff39f6b8c98f7c46fc9e70a25de560bf48a0cc))
|
|
54
|
+
* **wizard:** add hint to increase node memory limit for ssr setups ([f1612da](https://gitlab.orestes.info/baqend/speed-kit-cli/commit/f1612daf78dbd081f26afacd8bfcda3c3f651c6f))
|
|
55
|
+
* **wizard:** for plentymarkets reject not SSR htmls and track ([28f9f4e](https://gitlab.orestes.info/baqend/speed-kit-cli/commit/28f9f4ea64038dabbb55d27d70741665a6152f74))
|
|
56
|
+
|
|
57
|
+
# [2.81.0](https://gitlab.orestes.info/baqend/speed-kit-cli/compare/v2.80.0...v2.81.0) (2025-02-25)
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
### Features
|
|
61
|
+
|
|
62
|
+
* **wizard:** handle different use-cases of PredictivePreloading library ([3c6f10e](https://gitlab.orestes.info/baqend/speed-kit-cli/commit/3c6f10ebb74bdc5efed8872c9b3483bedd2851f0))
|
|
63
|
+
|
|
1
64
|
# [2.80.0](https://gitlab.orestes.info/baqend/speed-kit-cli/compare/v2.79.0...v2.80.0) (2025-02-19)
|
|
2
65
|
|
|
3
66
|
|
package/README.md
CHANGED
|
@@ -10,6 +10,7 @@ const json_response_error_1 = require("./error/json-response-error");
|
|
|
10
10
|
const connection_error_1 = require("../error-handling/error/connection-error");
|
|
11
11
|
const application_error_1 = tslib_1.__importDefault(require("../error-handling/error/application-error"));
|
|
12
12
|
const login_error_1 = require("./error/login-error");
|
|
13
|
+
const orestes_api_error_1 = require("./error/orestes-api-error");
|
|
13
14
|
const REQUEST_TIMEOUT = 10_000;
|
|
14
15
|
const CONTENT_TYPE = "application/json;charset=UTF-8";
|
|
15
16
|
class Client {
|
|
@@ -67,7 +68,8 @@ class Client {
|
|
|
67
68
|
}
|
|
68
69
|
const response = responseResult.data;
|
|
69
70
|
if (response.status !== 200) {
|
|
70
|
-
|
|
71
|
+
const errorBody = (await response.json());
|
|
72
|
+
throw new orestes_api_error_1.OrestesApiError(errorBody?.message || response.statusText, errorBody.reason, errorBody.status);
|
|
71
73
|
}
|
|
72
74
|
const jsonResponse = await (0, safe_1.safe)(response.json());
|
|
73
75
|
if (jsonResponse.success !== true) {
|
|
@@ -9,6 +9,7 @@ export declare class ConfigApiService {
|
|
|
9
9
|
setInstall(install: Install): Promise<Install | null>;
|
|
10
10
|
cloneInstall(install: Install): Promise<Install>;
|
|
11
11
|
activateInstall(install: Install): Promise<Install>;
|
|
12
|
+
activateInstallTesting(install: Install): Promise<Install>;
|
|
12
13
|
getModule(moduleName: string): Promise<string>;
|
|
13
14
|
setModule(moduleCode: string, moduleName: string): Promise<string>;
|
|
14
15
|
getServerConfig(): Promise<string>;
|
|
@@ -43,6 +43,13 @@ class ConfigApiService {
|
|
|
43
43
|
method: "POST",
|
|
44
44
|
}));
|
|
45
45
|
}
|
|
46
|
+
async activateInstallTesting(install) {
|
|
47
|
+
const activateUrl = `https://${this.app}.app.baqend.com/v1/speedkit/installation/${install.domain}/${install.configVersion}/activate?testing=true`;
|
|
48
|
+
return (await this.client.send(activateUrl, {
|
|
49
|
+
body: "{}",
|
|
50
|
+
method: "POST",
|
|
51
|
+
}));
|
|
52
|
+
}
|
|
46
53
|
async getModule(moduleName) {
|
|
47
54
|
return await this.client.getModule(moduleName);
|
|
48
55
|
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import ApplicationError from "../../error-handling/error/application-error";
|
|
2
|
+
export declare class OrestesApiError extends ApplicationError {
|
|
3
|
+
readonly message: string;
|
|
4
|
+
readonly reason: string;
|
|
5
|
+
readonly status: number;
|
|
6
|
+
readonly code = "ORESTES_API_ERROR";
|
|
7
|
+
constructor(message: string, reason: string, status: number);
|
|
8
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.OrestesApiError = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const application_error_1 = tslib_1.__importDefault(require("../../error-handling/error/application-error"));
|
|
6
|
+
class OrestesApiError extends application_error_1.default {
|
|
7
|
+
message;
|
|
8
|
+
reason;
|
|
9
|
+
status;
|
|
10
|
+
code = "ORESTES_API_ERROR";
|
|
11
|
+
constructor(message, reason, status) {
|
|
12
|
+
super(`${status}: ${reason} (${message})`);
|
|
13
|
+
this.message = message;
|
|
14
|
+
this.reason = reason;
|
|
15
|
+
this.status = status;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
exports.OrestesApiError = OrestesApiError;
|
|
@@ -188,12 +188,14 @@ class CustomerConfigService {
|
|
|
188
188
|
}
|
|
189
189
|
activateImageOptimisation = await this.cli.confirm("[IO] Should image optimisation be activated?", false);
|
|
190
190
|
removeLazyLoading = await this.cli.confirm("[Lazy-Loading] Does the shop require us to resolve lazy-loaded content?");
|
|
191
|
-
if (await this.cli.confirm("[
|
|
191
|
+
if (await this.cli.confirm("[Lambda-SSR] Add server-side-rendering? This requires a set-up Lambda function to work. Also requires usage of the DOM-based DocumentHandler.", false)) {
|
|
192
192
|
addPreRendering = true;
|
|
193
|
-
if (await this.cli.confirm("[
|
|
193
|
+
if (await this.cli.confirm("[Lambda-SSR] Does the customer utilize Shadow DOMs? If so additional handling for this will be added.", false)) {
|
|
194
194
|
supportShadowDomInPreRendering = true;
|
|
195
|
-
shadowDomCustomElementPrefix = await this.cli.prompt("[
|
|
195
|
+
shadowDomCustomElementPrefix = await this.cli.prompt("[Lambda-SSR] Please specify the prefix of the custom elements used (e.g. o2 uses tef-): ", { defaultAnswer: "custom-" });
|
|
196
196
|
}
|
|
197
|
+
await this.cli.confirm("Confirm that you increased the Node memory limit to at least 1024 as the SSR setup is memory intensive." +
|
|
198
|
+
' BBQ App -> Data -> App -> Search for App -> Addons -> "nodeMemLimit": 1024', false);
|
|
197
199
|
}
|
|
198
200
|
useScrapingBee = await this.cli.confirm("[ScrapingBee] Do customer responses differ geo-location-based which would require ScrapingBee API to fetch documents?", false);
|
|
199
201
|
activateRumTracking = true;
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
var CURRENT_HOST_CONFIG = getCurrentHostConfig(ENABLED_HOSTS_CONFIGS);
|
|
27
27
|
|
|
28
28
|
{{#if addPreRendering}}
|
|
29
|
-
//
|
|
29
|
+
// Lambda SSR specific: disable SK for tablets as they are not covered in lambda
|
|
30
30
|
function isTablet() {
|
|
31
31
|
var userAgent = window.navigator.userAgent.toLowerCase();
|
|
32
32
|
var tabletUAs = [
|
|
@@ -68,7 +68,7 @@
|
|
|
68
68
|
preloadDynamicBlocks: true,
|
|
69
69
|
rumTracking: {{activateRumTracking}},
|
|
70
70
|
{{#if addPreRendering}}
|
|
71
|
-
//
|
|
71
|
+
// Lambda SSR specific: detect device to cover different resolutions when rendered in lambda
|
|
72
72
|
userAgentDetection: true,
|
|
73
73
|
{{/if}}
|
|
74
74
|
split: CURRENT_HOST_CONFIG.split,
|
|
@@ -316,46 +316,82 @@
|
|
|
316
316
|
"_v",
|
|
317
317
|
/^pr_/i, // Product Recommendation
|
|
318
318
|
{{/if}}
|
|
319
|
+
{{#if isOxid}}
|
|
320
|
+
|
|
321
|
+
// OXID specific:
|
|
322
|
+
"cnid",
|
|
323
|
+
"ecmId",
|
|
324
|
+
"ecmUid",
|
|
325
|
+
"force_sid",
|
|
326
|
+
{{/if}}
|
|
319
327
|
|
|
320
328
|
// Default:
|
|
321
329
|
"_ga", // Google Analytics User ID (Universal Analytics)
|
|
322
330
|
"_gl", // Google Analytics User ID (GA 4+)
|
|
331
|
+
"_klaviyopid", // Klaviyo
|
|
323
332
|
"_kx", // klaviyo
|
|
333
|
+
"AdSet", // Meta Ads (Facebook)
|
|
334
|
+
"a8", // A8.net (affiliate marketing)
|
|
324
335
|
"ad_id",
|
|
336
|
+
"adid",
|
|
337
|
+
"adobe_mc", // Adobe Marketing Cloud
|
|
338
|
+
"adword",
|
|
339
|
+
"at_gd", // Urchin Tracking Module
|
|
325
340
|
"awc", // AWIN (former Zanox Affiliate Network)
|
|
326
341
|
"cjid",
|
|
342
|
+
"clickid",
|
|
343
|
+
"clickref",
|
|
344
|
+
"cstrackid", // ChannelSight
|
|
327
345
|
"cto_pld",
|
|
328
346
|
"dclid", // another Click ID
|
|
347
|
+
"dicbo",
|
|
329
348
|
"ds_rl",
|
|
349
|
+
"ef_id", // Adobe Advertising Cloud
|
|
330
350
|
"epik",
|
|
351
|
+
"fb_audience", // Facebook Ads
|
|
331
352
|
"fbclid", // Facebook Click ID
|
|
353
|
+
"gQT",
|
|
354
|
+
"gb_clk", // Click tracking
|
|
332
355
|
"gtm_debug", // Google Tag Manager
|
|
356
|
+
"irclickid",
|
|
333
357
|
"kgclid",
|
|
358
|
+
"kk", // Kelkoo Shopping Search Engine Key
|
|
334
359
|
"msclkid", // Microsoft Click ID
|
|
360
|
+
"nsctrid",
|
|
361
|
+
"ps_kw", // Paid Search Keyword Tracking
|
|
335
362
|
"rtbhc", // RTB House
|
|
363
|
+
"s_kwcid", // AMO ID, Adobe Advertising Cloud
|
|
336
364
|
"soluteclid", // Solute Click ID
|
|
337
365
|
"srsltid", // google search engine
|
|
338
366
|
"syclid",
|
|
339
367
|
"tduid", // Tradedoubler UID
|
|
368
|
+
"trackingtoken",
|
|
340
369
|
"ttclid", // TikTok Click ID
|
|
370
|
+
"ved",
|
|
341
371
|
"yclid", // Yandex Click ID
|
|
342
372
|
"zanpid", // AWIN (former Zanox Affiliate Network)
|
|
343
|
-
|
|
373
|
+
/^(mb|nb|nx|ny)$/,
|
|
374
|
+
/^WT\./, // WebTrends
|
|
344
375
|
/^[gw]braid$/, // Google's iOS web-to-app campaign measurement
|
|
376
|
+
/^bv(state|messageType|notificationId|recipientDomain)$/, // Bazaarvoice
|
|
345
377
|
/^campaign(_id)?$/,
|
|
346
378
|
/^cq_/,
|
|
379
|
+
/^dy(IsPreview|SmartId|IsDraft|ExperienceId|VariationId|pPreviewKey|PersistSession|Temp)$/, // Dynamic Yield
|
|
347
380
|
/^et_/,
|
|
348
|
-
/^gad(w|_source)?$/, // Google Ads
|
|
381
|
+
/^gad(w|_source|_campaignid)?$/, // Google Ads
|
|
349
382
|
/^gcl(id|src)$/, // Google Click ID + Source
|
|
383
|
+
/^judgeme_/, // Judge.me (review system)
|
|
350
384
|
/^klar_/, // getklar.com
|
|
351
385
|
/^neocom_/, // Neocom.ai
|
|
352
386
|
/^sc_/, // e.g. Adobe
|
|
387
|
+
/^sfmc_/, // Salesforce Marketing Cloud
|
|
353
388
|
/^sv(1|_campaign_id)$/,
|
|
354
389
|
/^trc_/, // Tracify
|
|
355
390
|
/^uslk_/, // Userlike Chatbot
|
|
356
391
|
/^utm[_-]/, // Urchin Tracking Module
|
|
357
392
|
/^vm(st|track)_id$/,
|
|
358
393
|
/^wg(u|expiry)$/, // Webgains Affiliate Network
|
|
394
|
+
/^wt_(mc|az|ref|t)$/, // Webtrekk/Mapp Intelligence
|
|
359
395
|
],
|
|
360
396
|
}],
|
|
361
397
|
};
|
|
@@ -55,11 +55,7 @@ module.exports = {
|
|
|
55
55
|
{{/if}}
|
|
56
56
|
production: {
|
|
57
57
|
...shared,
|
|
58
|
-
|
|
59
|
-
name: "{{production.host}}",
|
|
60
|
-
{{else}}
|
|
61
|
-
name: "production",
|
|
62
|
-
{{/if}}
|
|
58
|
+
name: "production",
|
|
63
59
|
forceInstall: {{production.forceInstall}}, // use when our setup is not present yet
|
|
64
60
|
// bypassDeactivation: false, // comment out when SK deactivation should not be bypassed
|
|
65
61
|
},
|
|
@@ -49,7 +49,15 @@
|
|
|
49
49
|
const config = {
|
|
50
50
|
rejectHTML({db, {{#if addPreRendering}}document{{else}}html{{/if}}, variation, url, headers}) {
|
|
51
51
|
/* Use to configure guards to prevent e.g. error and captcha pages from being cached */
|
|
52
|
-
|
|
52
|
+
{{#if isPlentymarkets}}
|
|
53
|
+
// we don't want to cache CSR pages
|
|
54
|
+
if (!html.includes('data-server-rendered="true"')) {
|
|
55
|
+
return `CSR Page delivered on url ${url}`;
|
|
56
|
+
}
|
|
57
|
+
return false;
|
|
58
|
+
{{else}}
|
|
59
|
+
return false;
|
|
60
|
+
{{/if}}
|
|
53
61
|
},
|
|
54
62
|
blacklistHTML({db, {{#if addPreRendering}}document{{else}}html{{/if}}, variation, url, headers}) {
|
|
55
63
|
/* Use to configure guards to black-list e.g. specific page types */
|
|
@@ -109,13 +117,7 @@ const config = {
|
|
|
109
117
|
{{#if isPlentymarkets}}
|
|
110
118
|
stripComments: false, // Plentymarkets specific
|
|
111
119
|
{{/if}}
|
|
112
|
-
{{#if addPreRendering}}
|
|
113
|
-
ignoreAssets: [
|
|
114
|
-
// keep aligned with dynamicBlockConfig.assetChangeDetection.ignoreAssets
|
|
115
|
-
],
|
|
116
|
-
{{else}}
|
|
117
120
|
ignoreAssets: [],
|
|
118
|
-
{{/if}}
|
|
119
121
|
{{#if isShopify}}
|
|
120
122
|
delayScriptPath: "/apps/speed-kit/speed-kit-dom-ready.js", // Shopify specific
|
|
121
123
|
{{else}}
|
|
@@ -5,11 +5,6 @@
|
|
|
5
5
|
window.dynamicBlockConfig = {
|
|
6
6
|
dynamicScriptExecution: true,
|
|
7
7
|
{{#if addPreRendering}}
|
|
8
|
-
assetChangeDetection: {
|
|
9
|
-
ignore: [
|
|
10
|
-
// keep aligned with DocumentHandler's config.ignoreAssets
|
|
11
|
-
],
|
|
12
|
-
},
|
|
13
8
|
// ssr container
|
|
14
9
|
prerendered: [{ selector: "body > .speed-kit-shadow-app-root" }],
|
|
15
10
|
{{/if}}
|
|
@@ -32,78 +32,88 @@ html > body {
|
|
|
32
32
|
}
|
|
33
33
|
{{/if}}
|
|
34
34
|
|
|
35
|
-
.speed-kit-dynamic-loading
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
35
|
+
.speed-kit-dynamic-loading {
|
|
36
|
+
{{#if addPreRendering}}
|
|
37
|
+
/* TODO: use the following wrapping selector if you want to apply those styles to the pre-rendered block instead: */
|
|
38
|
+
/* .speed-kit-pre-rendered-block-added */
|
|
39
|
+
{{/if}}
|
|
39
40
|
|
|
40
|
-
.
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
content: "";
|
|
45
|
-
width: 8px;
|
|
46
|
-
height: 8px;
|
|
47
|
-
display: block;
|
|
48
|
-
position: absolute;
|
|
49
|
-
top: calc(50% - 4px);
|
|
50
|
-
border-radius: 50%;
|
|
51
|
-
box-shadow:
|
|
52
|
-
8px 0 #c8c8cd,
|
|
53
|
-
20px 0 #dddde0,
|
|
54
|
-
32px 0 #ededee;
|
|
55
|
-
will-change: box-shadow;
|
|
56
|
-
animation: speed-kit-loading-dots 1.5s infinite both;
|
|
57
|
-
visibility: visible;
|
|
58
|
-
z-index: 1;
|
|
41
|
+
.dummy-price-class,
|
|
42
|
+
.dummy-availability-class {
|
|
43
|
+
visibility: hidden;
|
|
44
|
+
}
|
|
59
45
|
|
|
60
|
-
|
|
61
|
-
|
|
46
|
+
.dummy-price-class {
|
|
47
|
+
position: relative;
|
|
62
48
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
49
|
+
&::after {
|
|
50
|
+
content: "";
|
|
51
|
+
width: 8px;
|
|
52
|
+
height: 8px;
|
|
53
|
+
display: block;
|
|
54
|
+
position: absolute;
|
|
55
|
+
top: calc(50% - 4px);
|
|
56
|
+
border-radius: 50%;
|
|
57
|
+
box-shadow:
|
|
58
|
+
8px 0 #c8c8cd,
|
|
59
|
+
20px 0 #dddde0,
|
|
60
|
+
32px 0 #ededee;
|
|
61
|
+
will-change: box-shadow;
|
|
62
|
+
animation: speed-kit-loading-dots 1.5s infinite both;
|
|
63
|
+
visibility: visible;
|
|
64
|
+
z-index: 1;
|
|
66
65
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
}
|
|
66
|
+
/* --- align left --- */
|
|
67
|
+
left: -8px;
|
|
70
68
|
|
|
71
|
-
/*
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
}
|
|
69
|
+
/* --- align right --- */
|
|
70
|
+
/* left: auto; */
|
|
71
|
+
/* right: 32px; */
|
|
75
72
|
|
|
76
|
-
/*
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
.
|
|
89
|
-
.
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
73
|
+
/* --- align center --- */
|
|
74
|
+
/* left: calc(50% - 24px); */
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
/* Prevent Add2Cart clicks: */
|
|
80
|
+
.dummy-add2cart-class {
|
|
81
|
+
pointer-events: none !important;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/* Skeleton loading style: */
|
|
85
|
+
.dummy-add2cart-class,
|
|
86
|
+
.dummy-skeleton-container-class {
|
|
87
|
+
background-color: #ededed;
|
|
88
|
+
background-image: linear-gradient(90deg, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.8) 50%, rgba(255, 255, 255, 0) 100%);
|
|
89
|
+
background-repeat: no-repeat;
|
|
90
|
+
background-size: 200px 100%;
|
|
91
|
+
background-position: calc(-1 * 200px) 0;
|
|
92
|
+
animation: speed-kit-skeleton 1.5s 500ms infinite; /* works best with a container width of ~300-500 px */
|
|
93
|
+
will-change: background-position;
|
|
94
|
+
text-indent: -9999px;
|
|
95
|
+
|
|
96
|
+
> * {
|
|
97
|
+
visibility: hidden;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
.dummy-skeleton-container-class {
|
|
101
|
+
/* chunk skeleton background into smaller boxes: */
|
|
102
|
+
mask-size:
|
|
103
|
+
100% 98px,
|
|
104
|
+
100% 108px,
|
|
105
|
+
100% 98px;
|
|
106
|
+
mask-position:
|
|
107
|
+
0 0,
|
|
108
|
+
163px 123px,
|
|
109
|
+
0 259px;
|
|
110
|
+
mask-image: linear-gradient(#000, #000), linear-gradient(#000, #000), linear-gradient(#000, #000);
|
|
111
|
+
mask-repeat: no-repeat;
|
|
112
|
+
}
|
|
104
113
|
}
|
|
105
114
|
{{#if addPreRendering}}
|
|
106
|
-
|
|
115
|
+
|
|
116
|
+
/* Positioning for pre-rendered containers */
|
|
107
117
|
html.speed-kit-pre-rendered body > .speed-kit-shadow-app-root {
|
|
108
118
|
position: absolute;
|
|
109
119
|
top: 0;
|
|
@@ -476,6 +476,15 @@ import { PredictivePreloading } from 'predictive-preloading/predictivePreloading
|
|
|
476
476
|
});
|
|
477
477
|
},
|
|
478
478
|
},
|
|
479
|
+
{{/if}}
|
|
480
|
+
{{#if isPlentymarkets}}
|
|
481
|
+
{
|
|
482
|
+
on: "domInteractive",
|
|
483
|
+
track: function (controller) {
|
|
484
|
+
var SSR = document.querySelector('[data-server-rendered="true"]');
|
|
485
|
+
controller.trackCustomEvent("serverRendered", !!SSR);
|
|
486
|
+
},
|
|
487
|
+
},
|
|
479
488
|
{{/if}}
|
|
480
489
|
);
|
|
481
490
|
{{#if isShopify}}
|
|
@@ -617,7 +626,12 @@ import { PredictivePreloading } from 'predictive-preloading/predictivePreloading
|
|
|
617
626
|
}
|
|
618
627
|
{{/if}}
|
|
619
628
|
|
|
629
|
+
{{#if hasSoftNavigations}}
|
|
620
630
|
new PredictivePreloading({
|
|
621
|
-
// TODO: configure according to the needs of the customer
|
|
631
|
+
// TODO: configure according to the needs of the customer e.g. preload API-calls, soft-nav to hard-nav conversion...
|
|
622
632
|
});
|
|
633
|
+
{{else}}
|
|
634
|
+
// TODO: check if prerendering needs to be scoped to certain pages
|
|
635
|
+
new PredictivePreloading({ prerender: true });
|
|
636
|
+
{{/if}}
|
|
623
637
|
}();
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
3
4
|
const cli_1 = require("../../cli");
|
|
4
5
|
const integration_api_1 = require("../../integration-api");
|
|
5
6
|
const safe_1 = require("../../../helpers/safe");
|
|
6
|
-
const
|
|
7
|
+
const clipboardy_cjs_1 = tslib_1.__importDefault(require("clipboardy-cjs"));
|
|
7
8
|
class InstallResourceHandler {
|
|
8
9
|
customer;
|
|
9
10
|
configApi;
|
|
@@ -57,17 +58,34 @@ class InstallResourceHandler {
|
|
|
57
58
|
const updateResult = await (0, safe_1.safe)(this.configApi.setInstall(install));
|
|
58
59
|
if (updateResult.success === false) {
|
|
59
60
|
this.cli.endAction(cli_1.CliActionStatus.FAILED);
|
|
60
|
-
throw
|
|
61
|
+
throw updateResult.errorObj;
|
|
61
62
|
}
|
|
62
63
|
this.cli.endAction(cli_1.CliActionStatus.COMPLETED);
|
|
63
64
|
if (!(await this.cli.confirm("Activate new installation?"))) {
|
|
65
|
+
if (await this.cli.confirm("Activate as testing installation instead?")) {
|
|
66
|
+
this.cli.startAction("activate testing installResource");
|
|
67
|
+
const activateTestingResult = await (0, safe_1.safe)(this.configApi.activateInstallTesting(install));
|
|
68
|
+
if (activateTestingResult.success === false) {
|
|
69
|
+
this.cli.endAction(cli_1.CliActionStatus.FAILED);
|
|
70
|
+
throw activateTestingResult.errorObj;
|
|
71
|
+
}
|
|
72
|
+
this.cli.endAction(cli_1.CliActionStatus.COMPLETED);
|
|
73
|
+
const debugParameter = `?debugSpeedKit=${install.id.split("/").pop()}`;
|
|
74
|
+
try {
|
|
75
|
+
clipboardy_cjs_1.default.writeSync(debugParameter);
|
|
76
|
+
this.cli.writeSuccess("Query parameter to activate the testing installation has been copied to the clipboard 📋");
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
this.cli.writeSuccess(`Use the following parameter to active the testing installation in your browser: ${debugParameter}`);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
64
82
|
return;
|
|
65
83
|
}
|
|
66
84
|
this.cli.startAction("activate installResource");
|
|
67
85
|
const activateResult = await (0, safe_1.safe)(this.configApi.activateInstall(install));
|
|
68
86
|
if (activateResult.success === false) {
|
|
69
87
|
this.cli.endAction(cli_1.CliActionStatus.FAILED);
|
|
70
|
-
throw
|
|
88
|
+
throw activateResult.errorObj;
|
|
71
89
|
}
|
|
72
90
|
this.cli.endAction(cli_1.CliActionStatus.COMPLETED);
|
|
73
91
|
}
|
|
@@ -105,7 +123,7 @@ class InstallResourceHandler {
|
|
|
105
123
|
const result = await (0, safe_1.safe)(this.prepareRemoteInstallResource(install));
|
|
106
124
|
if (result.success === false) {
|
|
107
125
|
this.cli.endAction(cli_1.CliActionStatus.FAILED);
|
|
108
|
-
throw
|
|
126
|
+
throw result.errorObj;
|
|
109
127
|
}
|
|
110
128
|
this.cli.endAction(cli_1.CliActionStatus.COMPLETED);
|
|
111
129
|
const remoteClone = result.data;
|
|
@@ -45,7 +45,7 @@ class DiffService {
|
|
|
45
45
|
}
|
|
46
46
|
async writeContentToTemporalFile(temporaryFileName, content) {
|
|
47
47
|
if (!content) {
|
|
48
|
-
content = "
|
|
48
|
+
content = "";
|
|
49
49
|
}
|
|
50
50
|
const resolveFilePath = node_path_1.default.join((await this.getTemporalDirectoryPath()) + `/${temporaryFileName}`);
|
|
51
51
|
await promises_1.default.writeFile(resolveFilePath, content.replaceAll(/\r?\n/gm, "\n"));
|
|
@@ -33,7 +33,7 @@ class DiffService {
|
|
|
33
33
|
}
|
|
34
34
|
async writeContentToTemporalFile(temporaryFileName, content) {
|
|
35
35
|
if (!content) {
|
|
36
|
-
content = "
|
|
36
|
+
content = "";
|
|
37
37
|
}
|
|
38
38
|
const resolveFilePath = node_path_1.default.join((await this.getTemporalDirectoryPath()) + `/${temporaryFileName}`);
|
|
39
39
|
await fs.writeFile(resolveFilePath, content.replaceAll(/\r?\n/gm, "\n"));
|
|
@@ -15,6 +15,11 @@ export declare class SpeedKitInstallJs implements FetchRequestPausedEventHandler
|
|
|
15
15
|
readonly patterns: Protocol.Fetch.RequestPattern[];
|
|
16
16
|
constructor(customerConfig: CustomerConfig, installResource: VirtualFile);
|
|
17
17
|
handle(event: Protocol.Fetch.RequestPausedEvent, client: CDPSession): Promise<AbortResponse | Partial<Protocol.Fetch.FulfillRequestRequest> | void>;
|
|
18
|
+
/**
|
|
19
|
+
* fetch remote installResource
|
|
20
|
+
* extract all params from serviceWorkerUrl
|
|
21
|
+
* exampleEntry: `sw: "/wrapper-sw.js?r=365858ef-fce3-4c28-bdd1-805970d21a60&v=2.17.8"`
|
|
22
|
+
*/
|
|
18
23
|
private extractConfigVersion;
|
|
19
24
|
private getContent;
|
|
20
25
|
private isValidResponse;
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.SpeedKitInstallJs = void 0;
|
|
4
4
|
const abort_response_1 = require("../browser/abort-response");
|
|
5
5
|
const baqend_response_1 = require("../browser/baqend-response");
|
|
6
|
+
const safe_1 = require("../../../helpers/safe");
|
|
6
7
|
/**
|
|
7
8
|
* Intercepts the response for speedkit-install.js
|
|
8
9
|
* Returns a custom build install.js from local-files
|
|
@@ -32,17 +33,28 @@ class SpeedKitInstallJs {
|
|
|
32
33
|
return;
|
|
33
34
|
}
|
|
34
35
|
let installJs = this.installResource.getContent();
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
36
|
+
// extract configVersion from remote an append to localVersion
|
|
37
|
+
const configVersion = await this.extractConfigVersion(client, event);
|
|
38
|
+
if (configVersion) {
|
|
39
|
+
// append remote serviceWorkerParams to localVersion
|
|
40
|
+
installJs = installJs.replace(/sw:[^"]*"([^"]*)"/s, (matched, selected) => {
|
|
41
|
+
return matched.replace(selected, selected + configVersion);
|
|
42
|
+
});
|
|
41
43
|
}
|
|
42
44
|
return new baqend_response_1.BaqendResponse(installJs, "text/javascript; charset=utf-8", event.responseHeaders);
|
|
43
45
|
}
|
|
44
|
-
|
|
45
|
-
|
|
46
|
+
/**
|
|
47
|
+
* fetch remote installResource
|
|
48
|
+
* extract all params from serviceWorkerUrl
|
|
49
|
+
* exampleEntry: `sw: "/wrapper-sw.js?r=365858ef-fce3-4c28-bdd1-805970d21a60&v=2.17.8"`
|
|
50
|
+
*/
|
|
51
|
+
async extractConfigVersion(client, event) {
|
|
52
|
+
const originBodyResponse = await (0, safe_1.safe)(this.getContent(client, event));
|
|
53
|
+
if (originBodyResponse.success !== true) {
|
|
54
|
+
console.error(`could not fetch install resource: "${event.request.url}"`, originBodyResponse.error);
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
const [, configVersion] = originBodyResponse.data.match(/sw:[^?]*(\?[^"]*)"/s) || [];
|
|
46
58
|
return configVersion;
|
|
47
59
|
}
|
|
48
60
|
async getContent(client, event) {
|
|
@@ -12,6 +12,7 @@ class InstallSpeedKitJsTemplate extends abstract_template_1.default {
|
|
|
12
12
|
// Reset potential split test parameters
|
|
13
13
|
speedKit.split = 1.0;
|
|
14
14
|
speedKit.splitTestId = 'debug';
|
|
15
|
+
speedKit.group = 'A';
|
|
15
16
|
|
|
16
17
|
// Force installation on the Onboarding install resource
|
|
17
18
|
speedKit.disabled = speedKit.disabled && !location.pathname.includes('/speed-kit-install.html');
|
|
@@ -23,7 +23,7 @@ class VirtualOrestesApp {
|
|
|
23
23
|
const originUrl = this.getAssetUrl(event.request.url);
|
|
24
24
|
const UrlObject = new URL(event.request.url);
|
|
25
25
|
const variation = UrlObject.searchParams.has("bqvariation")
|
|
26
|
-
? UrlObject.searchParams.get("bqvariation").trim()
|
|
26
|
+
? UrlObject.searchParams.get("bqvariation").trim()
|
|
27
27
|
: "DEFAULT";
|
|
28
28
|
const cachedResponse = this.getCachedResponse(event.request.url);
|
|
29
29
|
if (cachedResponse instanceof baqend_response_1.BaqendResponse) {
|
|
@@ -62,8 +62,8 @@ class PullService {
|
|
|
62
62
|
// local file exists but remote is empty. delete
|
|
63
63
|
if (this.isEmpty(installResourceContent) &&
|
|
64
64
|
this.fileList.hasFile(fileName)) {
|
|
65
|
-
this.cli.writeError(`
|
|
66
|
-
|
|
65
|
+
this.cli.writeError(`empty: ${fileName}`);
|
|
66
|
+
file.setContent("");
|
|
67
67
|
return;
|
|
68
68
|
}
|
|
69
69
|
// same content, skip
|
|
@@ -12,11 +12,8 @@ const ORIGIN_PATHS = Object.keys(ORIGIN_POPS).filter((origin) =>
|
|
|
12
12
|
);
|
|
13
13
|
|
|
14
14
|
const fetchURL = async (ip, url, origin, variation, database) => {
|
|
15
|
-
if (variation && variation !== "DEFAULT") {
|
|
16
|
-
url =
|
|
17
|
-
url +
|
|
18
|
-
(url.includes("?") ? "&" : "?") +
|
|
19
|
-
`bqvariation=${variation.toLowerCase()}`;
|
|
15
|
+
if (variation && variation !== "DEFAULT" && variation !== "default") {
|
|
16
|
+
url = url + (url.includes("?") ? "&" : "?") + `bqvariation=${variation}`;
|
|
20
17
|
}
|
|
21
18
|
|
|
22
19
|
const app = database.connection.host;
|
package/oclif.manifest.json
CHANGED