@speedkit/cli 2.10.0 → 2.12.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 +21 -0
- package/README.md +41 -62
- package/dist/commands/build-parameter-query.d.ts +4 -4
- package/dist/commands/build-parameter-query.js +38 -38
- package/dist/commands/build-prewarm-query.d.ts +4 -4
- package/dist/commands/build-prewarm-query.js +33 -34
- package/dist/commands/deploy.d.ts +4 -4
- package/dist/commands/deploy.js +14 -15
- package/dist/helpers/cli-config.d.ts +8 -7
- package/dist/helpers/cli-config.js +50 -44
- package/dist/services/cli/cli-service.d.ts +1 -1
- package/dist/services/deploy/context/deploy-context.d.ts +1 -4
- package/dist/services/deploy/context/deploy-context.js +6 -7
- package/dist/services/deploy/deploy-service-factory.d.ts +4 -5
- package/dist/services/deploy/deploy-service-factory.js +19 -18
- package/dist/services/integration-api/handler/customer-config-handler.d.ts +3 -3
- package/dist/services/integration-api/handler/customer-config-handler.js +20 -14
- package/dist/services/integration-api/struct/customer-config-file.d.ts +4 -3
- package/dist/services/integration-api/struct/customer-config-file.js +7 -5
- package/dist/services/onboarding/browser/abort-response.js +1 -1
- package/dist/services/onboarding/browser/baqend-response.d.ts +4 -4
- package/dist/services/onboarding/browser/baqend-response.js +33 -25
- package/dist/services/onboarding/browser/origin-response.d.ts +1 -1
- package/dist/services/onboarding/browser/origin-response.js +2 -3
- package/dist/services/onboarding/config-renderer/speed-kit-install-context.d.ts +4 -4
- package/dist/services/onboarding/config-renderer/speed-kit-install-context.js +44 -32
- package/dist/services/onboarding/dashboard/athena-service.d.ts +2 -2
- package/dist/services/onboarding/dashboard/athena-service.js +28 -23
- package/dist/services/onboarding/dashboard/index.d.ts +3 -3
- package/dist/services/onboarding/dashboard/index.js +48 -36
- package/dist/services/onboarding/dashboard/param-query-builder.d.ts +2 -2
- package/dist/services/onboarding/dashboard/param-query-builder.js +2 -2
- package/dist/services/onboarding/dashboard/request-diff-service.d.ts +1 -1
- package/dist/services/onboarding/dashboard/request-diff-service.js +32 -28
- package/dist/services/onboarding/fetch-event-handler.d.ts +6 -6
- package/dist/services/onboarding/fetch-event-handler.js +72 -62
- package/dist/services/onboarding/fetch-events/customer-domain-document-response.d.ts +8 -8
- package/dist/services/onboarding/fetch-events/customer-domain-document-response.js +51 -49
- package/dist/services/onboarding/fetch-events/customer-service-worker-js.d.ts +3 -3
- package/dist/services/onboarding/fetch-events/customer-service-worker-js.js +6 -6
- package/dist/services/onboarding/fetch-events/dashboard-request.d.ts +2 -2
- package/dist/services/onboarding/fetch-events/dashboard-request.js +3 -3
- package/dist/services/onboarding/fetch-events/speed-kit-asset-request.d.ts +7 -7
- package/dist/services/onboarding/fetch-events/speed-kit-asset-request.js +76 -59
- package/dist/services/onboarding/fetch-events/speed-kit-install-html.d.ts +3 -3
- package/dist/services/onboarding/fetch-events/speed-kit-install-html.js +14 -14
- package/dist/services/onboarding/fetch-events/speed-kit-install-js.d.ts +6 -6
- package/dist/services/onboarding/fetch-events/speed-kit-install-js.js +12 -10
- package/dist/services/onboarding/fetch-events/speed-kit-rum-pi-request.d.ts +7 -7
- package/dist/services/onboarding/fetch-events/speed-kit-rum-pi-request.js +3 -3
- package/dist/services/onboarding/fetch-events/speed-kit-service-worker-js.d.ts +4 -4
- package/dist/services/onboarding/fetch-events/speed-kit-service-worker-js.js +6 -4
- package/dist/services/onboarding/file-events/{fileWatcher.d.ts → file-watcher.d.ts} +9 -8
- package/dist/services/onboarding/file-events/{fileWatcher.js → file-watcher.js} +74 -56
- package/dist/services/onboarding/index.d.ts +3 -3
- package/dist/services/onboarding/onboarding-model.d.ts +36 -34
- package/dist/services/onboarding/onboarding-model.js +19 -19
- package/dist/services/onboarding/onboarding-service-factory.d.ts +6 -6
- package/dist/services/onboarding/onboarding-service-factory.js +80 -75
- package/dist/services/onboarding/onboarding-service.d.ts +7 -7
- package/dist/services/onboarding/onboarding-service.js +54 -48
- package/dist/services/onboarding/request-cache/cache.d.ts +3 -3
- package/dist/services/onboarding/request-cache/cache.js +7 -7
- package/dist/services/onboarding/server-config/index.js +2 -2
- package/dist/services/onboarding/todo-collector.d.ts +1 -1
- package/dist/services/onboarding/todo-collector.js +8 -6
- package/oclif.manifest.json +9 -9
- package/package.json +12 -5
|
@@ -10,45 +10,45 @@ class CustomerDomainDocumentResponse {
|
|
|
10
10
|
customerConfig;
|
|
11
11
|
configDynamicBlock;
|
|
12
12
|
configDynamicStyles;
|
|
13
|
+
constructor(customerConfig, configDynamicBlock, configDynamicStyles) {
|
|
14
|
+
this.customerConfig = customerConfig;
|
|
15
|
+
this.configDynamicBlock = configDynamicBlock;
|
|
16
|
+
this.configDynamicStyles = configDynamicStyles;
|
|
17
|
+
}
|
|
13
18
|
get patterns() {
|
|
14
|
-
|
|
19
|
+
const result = [];
|
|
15
20
|
for (const origin of this.customerConfig.origins) {
|
|
16
21
|
const pattern = [
|
|
17
22
|
{
|
|
23
|
+
requestStage: "Response",
|
|
24
|
+
resourceType: "Document",
|
|
18
25
|
urlPattern: `${origin}*`,
|
|
19
|
-
resourceType: 'Document',
|
|
20
|
-
requestStage: "Response"
|
|
21
26
|
},
|
|
22
27
|
{
|
|
28
|
+
requestStage: "Response",
|
|
29
|
+
resourceType: "Fetch",
|
|
23
30
|
urlPattern: `${origin}*`,
|
|
24
|
-
resourceType: 'Fetch',
|
|
25
|
-
requestStage: "Response"
|
|
26
31
|
},
|
|
27
32
|
{
|
|
33
|
+
requestStage: "Response",
|
|
34
|
+
resourceType: "XHR",
|
|
28
35
|
urlPattern: `${origin}*`,
|
|
29
|
-
resourceType: 'XHR',
|
|
30
|
-
requestStage: "Response"
|
|
31
36
|
},
|
|
32
37
|
{
|
|
38
|
+
requestStage: "Response",
|
|
39
|
+
resourceType: "Fetch",
|
|
33
40
|
urlPattern: `https://${this.customerConfig.appDomain}/v1/asset/${origin}*`,
|
|
34
|
-
resourceType: 'Fetch',
|
|
35
|
-
requestStage: "Response"
|
|
36
41
|
},
|
|
37
42
|
{
|
|
38
|
-
|
|
43
|
+
requestStage: "Response",
|
|
39
44
|
resourceType: "XHR",
|
|
40
|
-
|
|
41
|
-
}
|
|
45
|
+
urlPattern: `https://${this.customerConfig.appDomain}/v1/asset/${origin}*`,
|
|
46
|
+
},
|
|
42
47
|
];
|
|
43
48
|
result.push(...pattern);
|
|
44
49
|
}
|
|
45
50
|
return result;
|
|
46
51
|
}
|
|
47
|
-
constructor(customerConfig, configDynamicBlock, configDynamicStyles) {
|
|
48
|
-
this.customerConfig = customerConfig;
|
|
49
|
-
this.configDynamicBlock = configDynamicBlock;
|
|
50
|
-
this.configDynamicStyles = configDynamicStyles;
|
|
51
|
-
}
|
|
52
52
|
async handle(event, client) {
|
|
53
53
|
if (!this.isValidResponse(event)) {
|
|
54
54
|
return;
|
|
@@ -68,51 +68,53 @@ class CustomerDomainDocumentResponse {
|
|
|
68
68
|
}
|
|
69
69
|
return new origin_response_1.OriginResponse(text, event.responseHeaders, event.responseStatusCode);
|
|
70
70
|
}
|
|
71
|
-
isValidHtmlContent(text) {
|
|
72
|
-
return text.includes('<html');
|
|
73
|
-
}
|
|
74
|
-
isValidResponse(event) {
|
|
75
|
-
return event.responseHeaders &&
|
|
76
|
-
event.responseStatusCode &&
|
|
77
|
-
event.responseStatusCode > 199 &&
|
|
78
|
-
event.responseStatusCode < 300;
|
|
79
|
-
}
|
|
80
|
-
isHtmlContentHeader(responseHeaders) {
|
|
81
|
-
const contentType = responseHeaders.filter(headerRecord => {
|
|
82
|
-
return headerRecord.name.toLowerCase() === 'content-type';
|
|
83
|
-
})?.[0]?.['value'];
|
|
84
|
-
return contentType && contentType.includes('text/html');
|
|
85
|
-
}
|
|
86
71
|
async getHtmlContent(client, event) {
|
|
87
|
-
const contentType = event.responseHeaders.
|
|
88
|
-
return headerRecord.name.toLowerCase() ===
|
|
89
|
-
})?.
|
|
90
|
-
const charset = contentType.split(
|
|
91
|
-
const {
|
|
72
|
+
const contentType = event.responseHeaders.find((headerRecord) => {
|
|
73
|
+
return headerRecord.name.toLowerCase() === "content-type";
|
|
74
|
+
})?.value || "";
|
|
75
|
+
const charset = contentType.split("charset=")?.[1];
|
|
76
|
+
const { base64Encoded, body } = await client.send("Fetch.getResponseBody", {
|
|
77
|
+
requestId: event.requestId,
|
|
78
|
+
});
|
|
92
79
|
if (base64Encoded) {
|
|
93
80
|
// todo get encodingHeader for target encoding
|
|
94
|
-
return Buffer.from(body,
|
|
81
|
+
return Buffer.from(body, "base64").toString(charset || "utf8");
|
|
95
82
|
}
|
|
96
83
|
return body;
|
|
97
84
|
}
|
|
85
|
+
isHtmlContentHeader(responseHeaders) {
|
|
86
|
+
const contentType = responseHeaders.find((headerRecord) => {
|
|
87
|
+
return headerRecord.name.toLowerCase() === "content-type";
|
|
88
|
+
})?.value;
|
|
89
|
+
return contentType && contentType.includes("text/html");
|
|
90
|
+
}
|
|
98
91
|
isSpeedKitResponse(text) {
|
|
99
|
-
return text.includes(
|
|
92
|
+
return text.includes("speed-kit-dynamic");
|
|
100
93
|
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
94
|
+
isValidHtmlContent(text) {
|
|
95
|
+
return text.includes("<html");
|
|
96
|
+
}
|
|
97
|
+
isValidResponse(event) {
|
|
98
|
+
return (event.responseHeaders &&
|
|
99
|
+
event.responseStatusCode &&
|
|
100
|
+
event.responseStatusCode > 199 &&
|
|
101
|
+
event.responseStatusCode < 300);
|
|
106
102
|
}
|
|
107
103
|
rewriteHtmlToLocalConfig(html) {
|
|
108
|
-
const DF_CONFIG_PATTERN = /(<script[^>]* id="speed-kit-df-config"[^>]*>)([\s
|
|
109
|
-
const DF_STYLES_PATTERN = /(<style[^>]* id="speed-kit-df-styles"[^>]*>)(?:(?!<\/style>)[\s
|
|
110
|
-
html = html.
|
|
111
|
-
const injectedConfig = body.match(/window\.dynamicBlockConfig\.appName\s=.*$/s) ?? [
|
|
104
|
+
const DF_CONFIG_PATTERN = /(<script[^>]* id="speed-kit-df-config"[^>]*>)([\S\s]*?)(<\/script>)/g;
|
|
105
|
+
const DF_STYLES_PATTERN = /(<style[^>]* id="speed-kit-df-styles"[^>]*>)(?:(?!<\/style>)[\S\s])*(<\/style>)/g;
|
|
106
|
+
html = html.replaceAll(DF_CONFIG_PATTERN, (_, tag, body, end) => {
|
|
107
|
+
const injectedConfig = body.match(/window\.dynamicBlockConfig\.appName\s=.*$/s) ?? [""];
|
|
112
108
|
return `${tag}${this.configDynamicBlock.getContent()}${injectedConfig[0]}${end}`;
|
|
113
109
|
});
|
|
114
|
-
html = html.
|
|
110
|
+
html = html.replaceAll(DF_STYLES_PATTERN, (_, tag, end) => `${tag}${this.configDynamicStyles.getContent()}${end}`);
|
|
115
111
|
return html;
|
|
116
112
|
}
|
|
113
|
+
rewriteInstallResource(text) {
|
|
114
|
+
text = text.replace(/<script(?:.(?!<\/script>))*app\.baqend\.com\/v1\/speedkit\/install.js(?:.|(?!<\/script>))*<\/script>/, "");
|
|
115
|
+
return text.replace(/<\s*head\b[^>]*>/, (head) => {
|
|
116
|
+
return `${head}\n<script src="${this.customerConfig.installPath}" ${this.customerConfig.installParams}></script>`;
|
|
117
|
+
});
|
|
118
|
+
}
|
|
117
119
|
}
|
|
118
120
|
exports.CustomerDomainDocumentResponse = CustomerDomainDocumentResponse;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import Protocol from
|
|
2
|
-
import { FetchRequestPausedEventHandler } from "../onboarding-model";
|
|
1
|
+
import Protocol from "devtools-protocol";
|
|
3
2
|
import CustomerConfig from "../../integration-api/struct/customer-config";
|
|
3
|
+
import { FetchRequestPausedEventHandler } from "../onboarding-model";
|
|
4
4
|
/**
|
|
5
5
|
* Intercepts request to /wrapper-sw.js
|
|
6
6
|
*
|
|
@@ -8,7 +8,7 @@ import CustomerConfig from "../../integration-api/struct/customer-config";
|
|
|
8
8
|
*/
|
|
9
9
|
export declare class CustomerServiceWorkerJs implements FetchRequestPausedEventHandler {
|
|
10
10
|
private customerConfig;
|
|
11
|
-
get patterns(): Protocol.Fetch.RequestPattern[];
|
|
12
11
|
constructor(customerConfig: CustomerConfig);
|
|
12
|
+
get patterns(): Protocol.Fetch.RequestPattern[];
|
|
13
13
|
handle(): Promise<Partial<Protocol.Fetch.FulfillRequestRequest>>;
|
|
14
14
|
}
|
|
@@ -9,22 +9,22 @@ const baqend_response_1 = require("../browser/baqend-response");
|
|
|
9
9
|
*/
|
|
10
10
|
class CustomerServiceWorkerJs {
|
|
11
11
|
customerConfig;
|
|
12
|
+
constructor(customerConfig) {
|
|
13
|
+
this.customerConfig = customerConfig;
|
|
14
|
+
}
|
|
12
15
|
get patterns() {
|
|
13
|
-
|
|
16
|
+
const result = [];
|
|
14
17
|
for (const origin of this.customerConfig.origins) {
|
|
15
18
|
result.push({
|
|
19
|
+
requestStage: "Request",
|
|
16
20
|
urlPattern: `${origin}${this.customerConfig.swPath}*`,
|
|
17
|
-
requestStage: "Request"
|
|
18
21
|
});
|
|
19
22
|
}
|
|
20
23
|
return result;
|
|
21
24
|
}
|
|
22
|
-
constructor(customerConfig) {
|
|
23
|
-
this.customerConfig = customerConfig;
|
|
24
|
-
}
|
|
25
25
|
async handle() {
|
|
26
26
|
const wrapperSwCode = `importScripts(\`https://${this.customerConfig.appDomain}/v1/speedkit/sw.js\${location.search}\`); // skonboarding`;
|
|
27
|
-
return new baqend_response_1.BaqendResponse(wrapperSwCode,
|
|
27
|
+
return new baqend_response_1.BaqendResponse(wrapperSwCode, "text/javascript; charset=utf-8");
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
30
|
exports.CustomerServiceWorkerJs = CustomerServiceWorkerJs;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import Protocol from
|
|
2
|
-
import { FetchRequestPausedEventHandler } from "../onboarding-model";
|
|
1
|
+
import Protocol from "devtools-protocol";
|
|
3
2
|
import { Dashboard } from "../dashboard";
|
|
3
|
+
import { FetchRequestPausedEventHandler } from "../onboarding-model";
|
|
4
4
|
/**
|
|
5
5
|
* The DashboardRequest class represents a request handler for the dashboard.
|
|
6
6
|
* Handle all the requests on the secondTab(http://skonboarding.local)
|
|
@@ -11,19 +11,19 @@ class DashboardRequest {
|
|
|
11
11
|
dashboard;
|
|
12
12
|
patterns = [
|
|
13
13
|
{
|
|
14
|
+
requestStage: "Request",
|
|
14
15
|
urlPattern: `http://skonboarding.local*`,
|
|
15
|
-
requestStage: "Request"
|
|
16
16
|
},
|
|
17
17
|
{
|
|
18
|
+
requestStage: "Request",
|
|
18
19
|
urlPattern: `https://skonboarding.local*`,
|
|
19
|
-
requestStage: "Request"
|
|
20
20
|
},
|
|
21
21
|
];
|
|
22
22
|
constructor(dashboard) {
|
|
23
23
|
this.dashboard = dashboard;
|
|
24
24
|
}
|
|
25
25
|
async handle(event) {
|
|
26
|
-
return
|
|
26
|
+
return this.dashboard.getResponse(event.request);
|
|
27
27
|
}
|
|
28
28
|
}
|
|
29
29
|
exports.DashboardRequest = DashboardRequest;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import Protocol from "devtools-protocol";
|
|
2
|
-
import {
|
|
3
|
-
import CustomerConfig from "../../integration-api/struct/customer-config";
|
|
2
|
+
import { CliService } from "../../cli";
|
|
4
3
|
import { DocumentHandlerServer } from "../../document-handler-runtime/document-handler-server";
|
|
4
|
+
import CustomerConfig from "../../integration-api/struct/customer-config";
|
|
5
5
|
import { AbortResponse } from "../browser/abort-response";
|
|
6
|
+
import { FetchRequestPausedEventHandler, SpeedKitServerConfig } from "../onboarding-model";
|
|
6
7
|
import { Cache } from "../request-cache/cache";
|
|
7
|
-
import { CliService } from "../../cli";
|
|
8
8
|
/**
|
|
9
9
|
* Handles fetch requests for Speed Kit assets and returns customized responses.
|
|
10
10
|
*/
|
|
@@ -14,15 +14,15 @@ export declare class SpeedKitAssetRequest implements FetchRequestPausedEventHand
|
|
|
14
14
|
private cache;
|
|
15
15
|
private cli;
|
|
16
16
|
private speedKitServerConfig?;
|
|
17
|
-
get patterns(): Protocol.Fetch.RequestPattern[];
|
|
18
17
|
constructor(customerConfig: CustomerConfig, documentHandler: DocumentHandlerServer, cache: Cache, cli: CliService, speedKitServerConfig?: SpeedKitServerConfig);
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
get patterns(): Protocol.Fetch.RequestPattern[];
|
|
19
|
+
handle(event: Protocol.Fetch.RequestPausedEvent): Promise<AbortResponse | Partial<Protocol.Fetch.FulfillRequestRequest>>;
|
|
21
20
|
private buildCustomHeaders;
|
|
22
21
|
private createResponseFromLocalDocumentHandler;
|
|
23
22
|
private getAssetUrl;
|
|
23
|
+
private getCachedResponse;
|
|
24
24
|
private isHtmlContentHeader;
|
|
25
25
|
private isValidHtmlContent;
|
|
26
|
-
private rewriteInstallResource;
|
|
27
26
|
private prepareOriginRequest;
|
|
27
|
+
private rewriteInstallResource;
|
|
28
28
|
}
|
|
@@ -11,54 +11,58 @@ class SpeedKitAssetRequest {
|
|
|
11
11
|
cache;
|
|
12
12
|
cli;
|
|
13
13
|
speedKitServerConfig;
|
|
14
|
+
constructor(customerConfig, documentHandler, cache, cli, speedKitServerConfig) {
|
|
15
|
+
this.customerConfig = customerConfig;
|
|
16
|
+
this.documentHandler = documentHandler;
|
|
17
|
+
this.cache = cache;
|
|
18
|
+
this.cli = cli;
|
|
19
|
+
this.speedKitServerConfig = speedKitServerConfig;
|
|
20
|
+
}
|
|
14
21
|
get patterns() {
|
|
15
|
-
|
|
22
|
+
const result = [];
|
|
16
23
|
for (const origin of this.customerConfig.origins) {
|
|
17
24
|
const pattern = [
|
|
18
25
|
{
|
|
26
|
+
requestStage: "Request",
|
|
27
|
+
resourceType: "Fetch",
|
|
19
28
|
urlPattern: `https://${this.customerConfig.appDomain}/v1/asset/${origin}*`,
|
|
20
|
-
resourceType: 'Fetch',
|
|
21
|
-
requestStage: "Request"
|
|
22
29
|
},
|
|
23
30
|
{
|
|
24
|
-
|
|
31
|
+
requestStage: "Request",
|
|
25
32
|
resourceType: "XHR",
|
|
26
|
-
|
|
27
|
-
}
|
|
33
|
+
urlPattern: `https://${this.customerConfig.appDomain}/v1/asset/${origin}*`,
|
|
34
|
+
},
|
|
28
35
|
];
|
|
29
36
|
result.push(...pattern);
|
|
30
37
|
}
|
|
31
38
|
return result;
|
|
32
39
|
}
|
|
33
|
-
constructor(customerConfig, documentHandler, cache, cli, speedKitServerConfig) {
|
|
34
|
-
this.customerConfig = customerConfig;
|
|
35
|
-
this.documentHandler = documentHandler;
|
|
36
|
-
this.cache = cache;
|
|
37
|
-
this.cli = cli;
|
|
38
|
-
this.speedKitServerConfig = speedKitServerConfig;
|
|
39
|
-
}
|
|
40
40
|
async handle(event) {
|
|
41
41
|
const originUrl = this.getAssetUrl(event.request.url);
|
|
42
42
|
const UrlObject = new URL(event.request.url);
|
|
43
|
-
const variation = UrlObject.searchParams.has(
|
|
43
|
+
const variation = UrlObject.searchParams.has("bqvariation")
|
|
44
|
+
? UrlObject.searchParams.get("bqvariation")
|
|
45
|
+
: "DEFAULT";
|
|
44
46
|
const cachedResponse = this.getCachedResponse(event.request.url);
|
|
45
47
|
if (cachedResponse instanceof baqend_response_1.BaqendResponse) {
|
|
46
48
|
return cachedResponse;
|
|
47
49
|
}
|
|
48
|
-
const response = await fetch(originUrl, this.prepareOriginRequest(variation, { headers:
|
|
50
|
+
const response = await fetch(originUrl, this.prepareOriginRequest(variation, { headers: event.request.headers }));
|
|
49
51
|
const customHeaders = this.buildCustomHeaders(originUrl);
|
|
50
|
-
if (response.headers.get(
|
|
52
|
+
if (response.headers.get("Content-Type").includes("image") ||
|
|
53
|
+
response.headers.get("Content-Type").includes("font")) {
|
|
51
54
|
return;
|
|
52
55
|
}
|
|
53
56
|
const responseContent = await response.text();
|
|
54
|
-
if (!this.isHtmlContentHeader(response.headers) ||
|
|
55
|
-
|
|
57
|
+
if (!this.isHtmlContentHeader(response.headers) ||
|
|
58
|
+
!this.isValidHtmlContent(responseContent)) {
|
|
59
|
+
const customResponse = new baqend_response_1.BaqendResponse(responseContent, response.headers.get("Content-Type") || null, customHeaders);
|
|
56
60
|
this.cache.addEntry(event.request.url, customResponse);
|
|
57
61
|
return customResponse;
|
|
58
62
|
}
|
|
59
63
|
try {
|
|
60
64
|
let customResponse = await this.createResponseFromLocalDocumentHandler(responseContent, variation, originUrl, event.request.headers);
|
|
61
|
-
customResponse = customResponse.replace(
|
|
65
|
+
customResponse = customResponse.replace("speed-kit-dynamic-load", "skonboarding speed-kit-dynamic-load");
|
|
62
66
|
if (this.customerConfig.forceInstall) {
|
|
63
67
|
customResponse = this.rewriteInstallResource(customResponse);
|
|
64
68
|
}
|
|
@@ -67,48 +71,50 @@ class SpeedKitAssetRequest {
|
|
|
67
71
|
return response;
|
|
68
72
|
}
|
|
69
73
|
catch (error) {
|
|
70
|
-
let message =
|
|
74
|
+
let message = "could not transform html";
|
|
71
75
|
if (error instanceof Error) {
|
|
72
76
|
message = error.message;
|
|
73
77
|
}
|
|
74
78
|
this.cli.writeError(message);
|
|
75
|
-
customHeaders.push({ name:
|
|
79
|
+
customHeaders.push({ name: "x-error", value: message });
|
|
76
80
|
return new baqend_response_1.BaqendResponse(message, null, customHeaders, 500);
|
|
77
81
|
}
|
|
78
82
|
}
|
|
79
|
-
getCachedResponse(requestUrl) {
|
|
80
|
-
const response = this.cache.getEntry(requestUrl);
|
|
81
|
-
if (!(response instanceof baqend_response_1.BaqendResponse)) {
|
|
82
|
-
return;
|
|
83
|
-
}
|
|
84
|
-
response.setHeader('x-cache', 'POP, HIT');
|
|
85
|
-
response.setHeader('x-served-by', 'cache-local');
|
|
86
|
-
response.setHeader('server-timing', 'pop;desc=LOCAL;dur=1,cache;desc=CACHE,hotness;desc=1,proto;desc=h3');
|
|
87
|
-
return response;
|
|
88
|
-
}
|
|
89
83
|
buildCustomHeaders(originUrl) {
|
|
90
84
|
const time = new Date().toUTCString();
|
|
91
85
|
const originDomain = new URL(originUrl).origin;
|
|
92
86
|
return [
|
|
93
|
-
{ name:
|
|
94
|
-
{ name:
|
|
87
|
+
{ name: "origin", value: originDomain },
|
|
88
|
+
{ name: "Access-Control-Allow-Credentials", value: "true" },
|
|
89
|
+
{
|
|
90
|
+
name: "Access-Control-Expose-Headers",
|
|
91
|
+
value: "Location, ETag, Baqend-Authorization-Token, Baqend-Acl, Baqend-Size, Baqend-SW-Control, Baqend-Created-At, Date, Age, Baqend-Speed-Kit, Baqend-Custom-Headers, X-Served-By, X-Cache, X-Timer, Access-Control-Allow-Origin, Fastly-Io-Info, Server-Timing",
|
|
92
|
+
},
|
|
95
93
|
{
|
|
96
|
-
name:
|
|
97
|
-
value:
|
|
94
|
+
name: "strict-transport-security",
|
|
95
|
+
value: "max-age=31536000; includeSubDomains",
|
|
98
96
|
},
|
|
99
|
-
{ name:
|
|
100
|
-
{
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
{
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
{
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
97
|
+
{ name: "timing-allow-origin", value: originDomain },
|
|
98
|
+
{
|
|
99
|
+
name: "Cache-Control",
|
|
100
|
+
value: "public,browser-ttl=0,sw-max-age=31536000,max-age=31469674",
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
name: "server-timing",
|
|
104
|
+
value: "pop;desc=LOCAL;dur=1,cache;desc=STREAM,hotness;desc=1,proto;desc=h3",
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
name: "Alt-Svc",
|
|
108
|
+
value: 'h3=":443";ma=86400,h3-29=":443";ma=86400,h3-27=":443";ma=86400',
|
|
109
|
+
},
|
|
110
|
+
{ name: "x-frame-options", value: "SAMEORIGIN" },
|
|
111
|
+
{ name: "x-cache", value: "STREAM, HIT" },
|
|
112
|
+
{ name: "x-cache-hits", value: "1" },
|
|
113
|
+
{ name: "x-served-by", value: "stream-local" },
|
|
114
|
+
{ name: "Date", value: time },
|
|
115
|
+
{ name: "last-modified", value: time },
|
|
116
|
+
{ name: "Baqend-Created-At", value: time },
|
|
117
|
+
{ name: "Age", value: "0" },
|
|
112
118
|
];
|
|
113
119
|
}
|
|
114
120
|
async createResponseFromLocalDocumentHandler(html, variation, url, headers) {
|
|
@@ -116,25 +122,30 @@ class SpeedKitAssetRequest {
|
|
|
116
122
|
}
|
|
117
123
|
getAssetUrl(requestUrl) {
|
|
118
124
|
const url = new URL(requestUrl);
|
|
119
|
-
url.searchParams.
|
|
125
|
+
for (const [name] of url.searchParams.entries()) {
|
|
120
126
|
if (name.startsWith("bq") || name === "bqsk") {
|
|
121
|
-
searchParams.delete(name);
|
|
127
|
+
url.searchParams.delete(name);
|
|
122
128
|
}
|
|
123
|
-
}
|
|
129
|
+
}
|
|
124
130
|
const cleanedUrl = url.toString();
|
|
125
131
|
return cleanedUrl.split("app.baqend.com/v1/asset/")[1];
|
|
126
132
|
}
|
|
133
|
+
getCachedResponse(requestUrl) {
|
|
134
|
+
const response = this.cache.getEntry(requestUrl);
|
|
135
|
+
if (!(response instanceof baqend_response_1.BaqendResponse)) {
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
response.setHeader("x-cache", "POP, HIT");
|
|
139
|
+
response.setHeader("x-served-by", "cache-local");
|
|
140
|
+
response.setHeader("server-timing", "pop;desc=LOCAL;dur=1,cache;desc=CACHE,hotness;desc=1,proto;desc=h3");
|
|
141
|
+
return response;
|
|
142
|
+
}
|
|
127
143
|
isHtmlContentHeader(responseHeaders) {
|
|
128
|
-
return responseHeaders.has(
|
|
144
|
+
return (responseHeaders.has("content-type") &&
|
|
145
|
+
responseHeaders.get("content-type").includes("text/html"));
|
|
129
146
|
}
|
|
130
147
|
isValidHtmlContent(text) {
|
|
131
|
-
return text.includes(
|
|
132
|
-
}
|
|
133
|
-
rewriteInstallResource(text) {
|
|
134
|
-
text = text.replace(/<script(?:.(?!<\/script>))*app\.baqend\.com\/v1\/speedkit\/install.js(?:.|(?!<\/script>))*<\/script>/, '');
|
|
135
|
-
return text.replace(/<\s*head\b[^>]*>/, (head) => {
|
|
136
|
-
return `${head}\n<script src="${this.customerConfig.installPath}" ${this.customerConfig.installParams}></script>`;
|
|
137
|
-
});
|
|
148
|
+
return text.includes("<html");
|
|
138
149
|
}
|
|
139
150
|
prepareOriginRequest(variationParam, init) {
|
|
140
151
|
if (!this.speedKitServerConfig || !variationParam) {
|
|
@@ -148,5 +159,11 @@ class SpeedKitAssetRequest {
|
|
|
148
159
|
init.headers = { ...init.headers, ...variationConfig.headers };
|
|
149
160
|
return init;
|
|
150
161
|
}
|
|
162
|
+
rewriteInstallResource(text) {
|
|
163
|
+
text = text.replace(/<script(?:.(?!<\/script>))*app\.baqend\.com\/v1\/speedkit\/install.js(?:.|(?!<\/script>))*<\/script>/, "");
|
|
164
|
+
return text.replace(/<\s*head\b[^>]*>/, (head) => {
|
|
165
|
+
return `${head}\n<script src="${this.customerConfig.installPath}" ${this.customerConfig.installParams}></script>`;
|
|
166
|
+
});
|
|
167
|
+
}
|
|
151
168
|
}
|
|
152
169
|
exports.SpeedKitAssetRequest = SpeedKitAssetRequest;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import Protocol from
|
|
2
|
-
import { BrowserContext, FetchRequestPausedEventHandler } from "../onboarding-model";
|
|
1
|
+
import Protocol from "devtools-protocol";
|
|
3
2
|
import CustomerConfig from "../../integration-api/struct/customer-config";
|
|
3
|
+
import { BrowserContext, FetchRequestPausedEventHandler } from "../onboarding-model";
|
|
4
4
|
import { InstallSpeedKitHtmlTemplate } from "../templates/install-speed-kit-html-template";
|
|
5
5
|
/**
|
|
6
6
|
* Represents a class that handles the installation of Speed Kit HTML.
|
|
@@ -9,7 +9,7 @@ export declare class SpeedKitInstallHtml implements FetchRequestPausedEventHandl
|
|
|
9
9
|
private customerConfig;
|
|
10
10
|
private browserContext;
|
|
11
11
|
private speedKitInstallHtmlTemplate;
|
|
12
|
-
get patterns(): Protocol.Fetch.RequestPattern[];
|
|
13
12
|
constructor(customerConfig: CustomerConfig, browserContext: BrowserContext, speedKitInstallHtmlTemplate: InstallSpeedKitHtmlTemplate);
|
|
13
|
+
get patterns(): Protocol.Fetch.RequestPattern[];
|
|
14
14
|
handle(): Promise<Partial<Protocol.Fetch.FulfillRequestRequest>>;
|
|
15
15
|
}
|
|
@@ -9,39 +9,39 @@ class SpeedKitInstallHtml {
|
|
|
9
9
|
customerConfig;
|
|
10
10
|
browserContext;
|
|
11
11
|
speedKitInstallHtmlTemplate;
|
|
12
|
+
constructor(customerConfig, browserContext, speedKitInstallHtmlTemplate) {
|
|
13
|
+
this.customerConfig = customerConfig;
|
|
14
|
+
this.browserContext = browserContext;
|
|
15
|
+
this.speedKitInstallHtmlTemplate = speedKitInstallHtmlTemplate;
|
|
16
|
+
}
|
|
12
17
|
get patterns() {
|
|
13
|
-
|
|
18
|
+
const result = [];
|
|
14
19
|
for (const origin of this.customerConfig.origins) {
|
|
15
20
|
const pattern = [
|
|
16
21
|
{
|
|
22
|
+
requestStage: "Request",
|
|
23
|
+
resourceType: "Document",
|
|
17
24
|
urlPattern: `${origin}${this.customerConfig.scope}speed-kit-install.html*`,
|
|
18
|
-
resourceType: 'Document',
|
|
19
|
-
requestStage: "Request"
|
|
20
25
|
},
|
|
21
26
|
{
|
|
27
|
+
requestStage: "Request",
|
|
28
|
+
resourceType: "XHR",
|
|
22
29
|
urlPattern: `${origin}${this.customerConfig.scope}speed-kit-install.html*`,
|
|
23
|
-
resourceType: 'XHR',
|
|
24
|
-
requestStage: "Request"
|
|
25
30
|
},
|
|
26
31
|
{
|
|
32
|
+
requestStage: "Request",
|
|
33
|
+
resourceType: "Fetch",
|
|
27
34
|
urlPattern: `${origin}${this.customerConfig.scope}speed-kit-install.html*`,
|
|
28
|
-
|
|
29
|
-
requestStage: "Request"
|
|
30
|
-
}
|
|
35
|
+
},
|
|
31
36
|
];
|
|
32
37
|
result.push(...pattern);
|
|
33
38
|
}
|
|
34
39
|
return result;
|
|
35
40
|
}
|
|
36
|
-
constructor(customerConfig, browserContext, speedKitInstallHtmlTemplate) {
|
|
37
|
-
this.customerConfig = customerConfig;
|
|
38
|
-
this.browserContext = browserContext;
|
|
39
|
-
this.speedKitInstallHtmlTemplate = speedKitInstallHtmlTemplate;
|
|
40
|
-
}
|
|
41
41
|
async handle() {
|
|
42
42
|
return new baqend_response_1.BaqendResponse(this.speedKitInstallHtmlTemplate.render({
|
|
43
|
-
installPath: this.customerConfig.installPath,
|
|
44
43
|
domain: this.browserContext.domain,
|
|
44
|
+
installPath: this.customerConfig.installPath,
|
|
45
45
|
swPath: this.customerConfig.swPath,
|
|
46
46
|
}));
|
|
47
47
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import Protocol from
|
|
2
|
-
import { CDPSession } from
|
|
3
|
-
import CustomerConfig from
|
|
4
|
-
import { VirtualFile } from
|
|
5
|
-
import { AbortResponse } from
|
|
6
|
-
import { FetchRequestPausedEventHandler } from
|
|
1
|
+
import Protocol from "devtools-protocol";
|
|
2
|
+
import { CDPSession } from "puppeteer";
|
|
3
|
+
import CustomerConfig from "../../integration-api/struct/customer-config";
|
|
4
|
+
import { VirtualFile } from "../../integration-api/struct/virtual-file";
|
|
5
|
+
import { AbortResponse } from "../browser/abort-response";
|
|
6
|
+
import { FetchRequestPausedEventHandler } from "../onboarding-model";
|
|
7
7
|
/**
|
|
8
8
|
* Intercepts the response for speedkit-install.js
|
|
9
9
|
* Returns a custom build install.js from local-files
|
|
@@ -18,15 +18,15 @@ class SpeedKitInstallJs {
|
|
|
18
18
|
this.installResource = installResource;
|
|
19
19
|
this.patterns = [
|
|
20
20
|
{
|
|
21
|
-
requestStage:
|
|
21
|
+
requestStage: "Response",
|
|
22
22
|
urlPattern: `https://${this.customerConfig.appDomain}/v1/speedkit/install*`,
|
|
23
23
|
},
|
|
24
24
|
];
|
|
25
25
|
}
|
|
26
26
|
async handle(event, client) {
|
|
27
27
|
if (!event.request.url.includes(this.customerConfig.appDomain)) {
|
|
28
|
-
console.log(
|
|
29
|
-
return new abort_response_1.AbortResponse(
|
|
28
|
+
console.log("abort:", event.request.url);
|
|
29
|
+
return new abort_response_1.AbortResponse("Aborted");
|
|
30
30
|
}
|
|
31
31
|
if (!this.isValidResponse(event)) {
|
|
32
32
|
return;
|
|
@@ -39,24 +39,26 @@ class SpeedKitInstallJs {
|
|
|
39
39
|
installJs = installJs.replace(this.customerConfig.swPath, this.customerConfig.swPath + configVersion);
|
|
40
40
|
}
|
|
41
41
|
}
|
|
42
|
-
return new baqend_response_1.BaqendResponse(installJs,
|
|
42
|
+
return new baqend_response_1.BaqendResponse(installJs, "text/javascript; charset=utf-8", event.responseHeaders);
|
|
43
43
|
}
|
|
44
44
|
extractConfigVersion(originBody) {
|
|
45
45
|
const [, configVersion] = originBody.match(/sw:.*?(\?[^"]*)/) || [];
|
|
46
46
|
return configVersion;
|
|
47
47
|
}
|
|
48
48
|
async getContent(client, event) {
|
|
49
|
-
const { base64Encoded, body } = await client.send(
|
|
49
|
+
const { base64Encoded, body } = await client.send("Fetch.getResponseBody", {
|
|
50
|
+
requestId: event.requestId,
|
|
51
|
+
});
|
|
50
52
|
if (base64Encoded) {
|
|
51
|
-
return Buffer.from(body,
|
|
53
|
+
return Buffer.from(body, "base64").toString("utf8");
|
|
52
54
|
}
|
|
53
55
|
return body;
|
|
54
56
|
}
|
|
55
57
|
isValidResponse(event) {
|
|
56
|
-
return event.responseHeaders
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
58
|
+
return (event.responseHeaders &&
|
|
59
|
+
event.responseStatusCode &&
|
|
60
|
+
event.responseStatusCode > 199 &&
|
|
61
|
+
event.responseStatusCode < 300);
|
|
60
62
|
}
|
|
61
63
|
}
|
|
62
64
|
exports.SpeedKitInstallJs = SpeedKitInstallJs;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { CDPSession } from
|
|
2
|
-
import { Protocol } from
|
|
3
|
-
import { CliService } from
|
|
4
|
-
import CustomerConfig from
|
|
5
|
-
import { AbortResponse } from
|
|
6
|
-
import { FetchRequestPausedEventHandler } from
|
|
7
|
-
import { Cache } from
|
|
1
|
+
import { CDPSession } from "puppeteer";
|
|
2
|
+
import { Protocol } from "puppeteer-core";
|
|
3
|
+
import { CliService } from "../../cli";
|
|
4
|
+
import CustomerConfig from "../../integration-api/struct/customer-config";
|
|
5
|
+
import { AbortResponse } from "../browser/abort-response";
|
|
6
|
+
import { FetchRequestPausedEventHandler } from "../onboarding-model";
|
|
7
|
+
import { Cache } from "../request-cache/cache";
|
|
8
8
|
/**
|
|
9
9
|
* Intercepts v1/rum/pi requests,
|
|
10
10
|
* if request contains changeDetection, clear dh-cache for respective url
|