@speedkit/cli 2.38.0 → 2.39.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 +15 -0
- package/README.md +5 -5
- package/dist/commands/build-parameter-query.d.ts +1 -1
- package/dist/commands/build-prewarm-query.d.ts +1 -1
- package/dist/commands/deploy.d.ts +1 -1
- package/dist/commands/document-handler.d.ts +1 -1
- package/dist/commands/find-pops.js +0 -1
- package/dist/commands/onboarding.d.ts +1 -1
- package/dist/commands/onboarding.js +1 -1
- package/dist/commands/prewarm.d.ts +1 -1
- package/dist/commands/pull.d.ts +1 -1
- package/dist/dummy.spec.js +2 -3
- package/dist/helpers/build-query-helper.js +5 -6
- package/dist/helpers/file-helper.js +2 -3
- package/dist/helpers/get-parsed-config.js +3 -4
- package/dist/helpers/is-directory.js +1 -2
- package/dist/helpers/is-file.js +1 -2
- package/dist/helpers/logging-helper.js +3 -4
- package/dist/helpers/normalize.d.ts +0 -1
- package/dist/helpers/normalize.js +4 -5
- package/dist/helpers/race.js +1 -2
- package/dist/helpers/safe.js +1 -2
- package/dist/helpers/scrape.js +1 -1
- package/dist/helpers/speed-kit-rule-to-reg-exp.js +1 -2
- package/dist/models/cli-parameters.d.ts +1 -1
- package/dist/services/athena/athena-service-factory.js +1 -1
- package/dist/services/athena/athena-service.d.ts +3 -1
- package/dist/services/athena/athena-service.js +14 -2
- package/dist/services/config-api-service.d.ts +1 -1
- package/dist/services/config-api-service.js +1 -0
- package/dist/services/integration-api/file-reader.d.ts +0 -1
- package/dist/services/onboarding/browser/extension/devtools-extension-api.d.ts +7 -0
- package/dist/services/onboarding/browser/extension/devtools-extension-api.js +16 -0
- package/dist/services/onboarding/browser/extension/extension-validator.d.ts +10 -0
- package/dist/services/onboarding/browser/extension/extension-validator.js +71 -0
- package/dist/services/onboarding/dashboard/index.d.ts +1 -0
- package/dist/services/onboarding/dashboard/index.js +23 -22
- package/dist/services/onboarding/dashboard/request-diff-service.d.ts +2 -1
- package/dist/services/onboarding/dashboard/request-diff-service.js +34 -6
- package/dist/services/onboarding/error/browser-extension-error.d.ts +5 -0
- package/dist/services/onboarding/error/browser-extension-error.js +12 -0
- package/dist/services/onboarding/fetch-event-handler.js +13 -14
- package/dist/services/onboarding/onboarding-model.d.ts +33 -3
- package/dist/services/onboarding/onboarding-model.js +32 -5
- package/dist/services/onboarding/onboarding-service-factory.d.ts +1 -0
- package/dist/services/onboarding/onboarding-service-factory.js +22 -4
- package/dist/services/onboarding/onboarding-service.d.ts +3 -3
- package/dist/services/onboarding/onboarding-service.js +35 -30
- package/dist/services/onboarding/todo-collector.d.ts +2 -2
- package/dist/services/onboarding/todo-collector.js +1 -1
- package/dist/services/prewarm/assets/asset-api-client.js +0 -1
- package/oclif.manifest.json +1 -1
- package/package.json +19 -19
- package/dist/services/onboarding/dashboard/frontend-dist/assets/index-e3bd4f6e.css +0 -1
- package/dist/services/onboarding/dashboard/frontend-dist/assets/main-215271c2.js +0 -9
- package/dist/services/onboarding/dashboard/frontend-dist/index.html +0 -18
|
@@ -3,8 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.Dashboard = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const baqend_response_1 = require("../browser/baqend-response");
|
|
6
|
-
const node_fs_1 = require("node:fs");
|
|
7
|
-
const node_path_1 = tslib_1.__importDefault(require("node:path"));
|
|
8
6
|
const safe_1 = require("../../../helpers/safe");
|
|
9
7
|
const json2csv_1 = tslib_1.__importDefault(require("json2csv"));
|
|
10
8
|
class Dashboard {
|
|
@@ -23,31 +21,24 @@ class Dashboard {
|
|
|
23
21
|
}
|
|
24
22
|
async getResponse(request) {
|
|
25
23
|
const url = new URL(request.url);
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
return new baqend_response_1.BaqendResponse(content);
|
|
24
|
+
const requestOrigin = request.headers["Origin"] || "*";
|
|
25
|
+
if ("Access-Control-Request-Method" in request.headers) {
|
|
26
|
+
return this.createBaqendResponse(requestOrigin, "preflight");
|
|
30
27
|
}
|
|
31
|
-
if (
|
|
32
|
-
|
|
33
|
-
const content = (0, node_fs_1.readFileSync)(filePath, { encoding: "utf-8" });
|
|
34
|
-
let contentType = "application/javascript; charset=UTF-8";
|
|
35
|
-
if (url.pathname.includes(".css")) {
|
|
36
|
-
contentType = "text/css";
|
|
37
|
-
}
|
|
38
|
-
return new baqend_response_1.BaqendResponse(content, contentType);
|
|
28
|
+
if (request.method !== "POST" && request.method !== "GET") {
|
|
29
|
+
return this.createBaqendResponse(requestOrigin, "unsupported method");
|
|
39
30
|
}
|
|
40
31
|
if (url.pathname.startsWith("/query/create")) {
|
|
41
|
-
return
|
|
32
|
+
return this.createBaqendResponse(requestOrigin, JSON.stringify({ query: this.parameterQueryBuilder.getQuery() }), "application/json; charset=UTF-8");
|
|
42
33
|
}
|
|
43
34
|
if (url.pathname.startsWith("/query/execute")) {
|
|
44
35
|
const postData = request.postData;
|
|
45
36
|
const data = JSON.parse(postData);
|
|
46
37
|
const response = await (0, safe_1.safe)(this.athenaClient.getResult(data.query, []));
|
|
47
38
|
if (response.success === true) {
|
|
48
|
-
return
|
|
39
|
+
return this.createBaqendResponse(requestOrigin, JSON.stringify(response.data), "application/json; charset=UTF-8");
|
|
49
40
|
}
|
|
50
|
-
return
|
|
41
|
+
return this.createBaqendResponse(requestOrigin, response.error, null, [{ name: "x-error", value: response.error }], 500);
|
|
51
42
|
}
|
|
52
43
|
// @todo reImplement getLastResult
|
|
53
44
|
if (url.pathname.startsWith("/query/download")) {
|
|
@@ -63,7 +54,7 @@ class Dashboard {
|
|
|
63
54
|
"example3",
|
|
64
55
|
],
|
|
65
56
|
});
|
|
66
|
-
return
|
|
57
|
+
return this.createBaqendResponse(requestOrigin, csv, "application/csv", [
|
|
67
58
|
{
|
|
68
59
|
name: "Content-disposition",
|
|
69
60
|
value: `attachment; filename=parameter-${this.customerConfig.app}.csv`,
|
|
@@ -71,21 +62,31 @@ class Dashboard {
|
|
|
71
62
|
]);
|
|
72
63
|
}
|
|
73
64
|
if (url.pathname.startsWith("/api/config")) {
|
|
74
|
-
return
|
|
65
|
+
return this.createBaqendResponse(requestOrigin, JSON.stringify(this.customerConfig), "application/json; charset=UTF-8");
|
|
75
66
|
}
|
|
76
67
|
if (url.pathname.startsWith("/diff")) {
|
|
77
68
|
const postData = request.postData;
|
|
78
69
|
const data = JSON.parse(postData);
|
|
79
|
-
return
|
|
70
|
+
return this.requestDiffService.postDiff(requestOrigin, data.url, data.paramKeys, data.autoDiff);
|
|
80
71
|
}
|
|
81
72
|
if (url.pathname.startsWith("/cache/get")) {
|
|
82
73
|
const response = [];
|
|
83
74
|
for (const [url, baqendResponse] of this.cache.getAll()) {
|
|
84
75
|
response.push({ url, response: baqendResponse });
|
|
85
76
|
}
|
|
86
|
-
return
|
|
77
|
+
return this.createBaqendResponse(requestOrigin, JSON.stringify(response), "application/json; charset=UTF-8");
|
|
87
78
|
}
|
|
88
|
-
return
|
|
79
|
+
return this.createBaqendResponse(requestOrigin, "Not implemented");
|
|
80
|
+
}
|
|
81
|
+
createBaqendResponse(origin, body, contentType, headers = [], status) {
|
|
82
|
+
headers.push({
|
|
83
|
+
name: "Access-Control-Allow-Origin",
|
|
84
|
+
value: origin,
|
|
85
|
+
}, {
|
|
86
|
+
name: "Access-Control-Allow-Headers",
|
|
87
|
+
value: "Content-Type,Access-Control-Allow-Origin,origin",
|
|
88
|
+
});
|
|
89
|
+
return new baqend_response_1.BaqendResponse(body, contentType, headers, status);
|
|
89
90
|
}
|
|
90
91
|
}
|
|
91
92
|
exports.Dashboard = Dashboard;
|
|
@@ -5,9 +5,10 @@ export declare class RequestDiffService {
|
|
|
5
5
|
private diffService;
|
|
6
6
|
private documentHandlerRuntime;
|
|
7
7
|
constructor(diffService: DiffService, documentHandlerRuntime: DocumentHandlerServer);
|
|
8
|
-
postDiff(url: string, parametersString: string, autoCheck?: boolean): Promise<BaqendResponse>;
|
|
8
|
+
postDiff(requestOrigin: string, url: string, parametersString: string, autoCheck?: boolean): Promise<BaqendResponse>;
|
|
9
9
|
private diffLocal;
|
|
10
10
|
private doOriginVsContentDiff;
|
|
11
11
|
private fetchHtml;
|
|
12
12
|
private createUrlsForDiff;
|
|
13
|
+
private createBaqendResponse;
|
|
13
14
|
}
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.RequestDiffService = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
4
5
|
const baqend_response_1 = require("../browser/baqend-response");
|
|
5
6
|
const safe_1 = require("../../../helpers/safe");
|
|
7
|
+
const node_https_1 = require("node:https");
|
|
8
|
+
const node_crypto_1 = tslib_1.__importDefault(require("node:crypto"));
|
|
9
|
+
const node_fetch_1 = tslib_1.__importDefault(require("node-fetch"));
|
|
6
10
|
class RequestDiffService {
|
|
7
11
|
diffService;
|
|
8
12
|
documentHandlerRuntime;
|
|
@@ -10,7 +14,7 @@ class RequestDiffService {
|
|
|
10
14
|
this.diffService = diffService;
|
|
11
15
|
this.documentHandlerRuntime = documentHandlerRuntime;
|
|
12
16
|
}
|
|
13
|
-
async postDiff(url, parametersString, autoCheck = false) {
|
|
17
|
+
async postDiff(requestOrigin, url, parametersString, autoCheck = false) {
|
|
14
18
|
const parameters = parametersString
|
|
15
19
|
.replace("[", "")
|
|
16
20
|
.replace("]", "")
|
|
@@ -21,15 +25,15 @@ class RequestDiffService {
|
|
|
21
25
|
const { urlWithParam, urlWithoutParam } = this.createUrlsForDiff(url, parameters);
|
|
22
26
|
const result = await (0, safe_1.safe)(this.diffLocal(urlWithParam, urlWithoutParam, autoCheck));
|
|
23
27
|
if (result.success === true) {
|
|
24
|
-
return
|
|
28
|
+
return this.createBaqendResponse(requestOrigin, JSON.stringify({
|
|
25
29
|
status: "success",
|
|
26
30
|
isIdentical: result.data,
|
|
27
31
|
}), "application/json; charset=UTF-8");
|
|
28
32
|
}
|
|
29
|
-
return
|
|
33
|
+
return this.createBaqendResponse(requestOrigin, JSON.stringify({
|
|
30
34
|
status: "error",
|
|
31
35
|
error: result.error,
|
|
32
|
-
}), "application/json; charset=UTF-8",
|
|
36
|
+
}), "application/json; charset=UTF-8", [], 500);
|
|
33
37
|
}
|
|
34
38
|
async diffLocal(urlWithParameter, urlWithoutParameter, checkIsEqual = false) {
|
|
35
39
|
const htmlWithParameter = await this.fetchHtml(urlWithParameter);
|
|
@@ -56,8 +60,22 @@ class RequestDiffService {
|
|
|
56
60
|
return await this.diffService.executeDiff(local, origin);
|
|
57
61
|
}
|
|
58
62
|
async fetchHtml(url) {
|
|
59
|
-
const
|
|
60
|
-
|
|
63
|
+
const agent = new node_https_1.Agent({
|
|
64
|
+
rejectUnauthorized: false,
|
|
65
|
+
keepAlive: true,
|
|
66
|
+
secureOptions: node_crypto_1.default.constants.SSL_OP_LEGACY_SERVER_CONNECT,
|
|
67
|
+
});
|
|
68
|
+
const response = await (0, safe_1.safe)((0, node_fetch_1.default)(url, {
|
|
69
|
+
agent: agent,
|
|
70
|
+
headers: {
|
|
71
|
+
"user-agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.79 Safari/537.36 SpeedKitCrawler/1.0",
|
|
72
|
+
},
|
|
73
|
+
}));
|
|
74
|
+
if (response.success !== true) {
|
|
75
|
+
console.log(response.errorObj);
|
|
76
|
+
throw response.errorObj;
|
|
77
|
+
}
|
|
78
|
+
return response.data.text();
|
|
61
79
|
}
|
|
62
80
|
createUrlsForDiff(urlWithParameter, parameters) {
|
|
63
81
|
const url = new URL(urlWithParameter);
|
|
@@ -72,5 +90,15 @@ class RequestDiffService {
|
|
|
72
90
|
urlWithoutParam: urlWithoutParameter,
|
|
73
91
|
};
|
|
74
92
|
}
|
|
93
|
+
createBaqendResponse(requestOrigin, body, contentType, headers = [], status) {
|
|
94
|
+
headers.push({
|
|
95
|
+
name: "Access-Control-Allow-Origin",
|
|
96
|
+
value: requestOrigin,
|
|
97
|
+
}, {
|
|
98
|
+
name: "Access-Control-Allow-Headers",
|
|
99
|
+
value: "Content-Type,Access-Control-Allow-Origin,origin",
|
|
100
|
+
});
|
|
101
|
+
return new baqend_response_1.BaqendResponse(body, contentType, headers, status);
|
|
102
|
+
}
|
|
75
103
|
}
|
|
76
104
|
exports.RequestDiffService = RequestDiffService;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.BrowserExtensionError = void 0;
|
|
4
|
+
class BrowserExtensionError extends Error {
|
|
5
|
+
code = "BROWSER_EXTENSION_ERROR";
|
|
6
|
+
suggestions = [
|
|
7
|
+
"check paths in env $CHROME_EXTENSION_PATHS",
|
|
8
|
+
"or",
|
|
9
|
+
`"chromeExtensionPaths:" in .config/speed-kit-cli/config.js`,
|
|
10
|
+
];
|
|
11
|
+
}
|
|
12
|
+
exports.BrowserExtensionError = BrowserExtensionError;
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.FetchEventHandler = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
|
+
const onboarding_model_1 = require("./onboarding-model");
|
|
5
6
|
const puppeteer_core_1 = require("puppeteer-core");
|
|
6
7
|
const abort_response_1 = require("./browser/abort-response");
|
|
7
8
|
const cli_1 = require("../cli");
|
|
@@ -19,8 +20,8 @@ class FetchEventHandler {
|
|
|
19
20
|
this.client = client;
|
|
20
21
|
}
|
|
21
22
|
async handleRequestFetchEvents(target) {
|
|
22
|
-
const
|
|
23
|
-
await
|
|
23
|
+
const cdpSession = await target.createCDPSession();
|
|
24
|
+
await (0, safe_1.safe)(cdpSession.send("Fetch.enable", {
|
|
24
25
|
handleAuthRequests: true,
|
|
25
26
|
//see: https://chromedevtools.github.io/devtools-protocol/tot/Fetch#type-RequestPattern
|
|
26
27
|
patterns: [
|
|
@@ -29,16 +30,16 @@ class FetchEventHandler {
|
|
|
29
30
|
}),
|
|
30
31
|
...this.getAuthPattern(),
|
|
31
32
|
],
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
const response = await (0, safe_1.safe)(this.onFetchAuthRequired(event,
|
|
33
|
+
}));
|
|
34
|
+
cdpSession.on(onboarding_model_1.BROWSER_EVENTS.FETCH_AUTH_REQUIRED, async (event) => {
|
|
35
|
+
const response = await (0, safe_1.safe)(this.onFetchAuthRequired(event, cdpSession));
|
|
35
36
|
if (response.success === true) {
|
|
36
37
|
return response.data;
|
|
37
38
|
}
|
|
38
39
|
this.cli.writeError(response.error);
|
|
39
40
|
});
|
|
40
|
-
|
|
41
|
-
const response = await (0, safe_1.safe)(this.onFetchRequestPaused(event,
|
|
41
|
+
cdpSession.on(onboarding_model_1.BROWSER_EVENTS.FETCH_REQUEST_PAUSED, async (event) => {
|
|
42
|
+
const response = await (0, safe_1.safe)(this.onFetchRequestPaused(event, cdpSession));
|
|
42
43
|
if (response.success === true) {
|
|
43
44
|
return;
|
|
44
45
|
}
|
|
@@ -62,32 +63,30 @@ class FetchEventHandler {
|
|
|
62
63
|
return !pattern.resourceType || pattern.resourceType === resourceType;
|
|
63
64
|
});
|
|
64
65
|
}
|
|
65
|
-
async onFetchRequestPaused(event,
|
|
66
|
+
async onFetchRequestPaused(event, cdpSession) {
|
|
66
67
|
const requestId = event.requestId;
|
|
67
68
|
for (const fetchEvent of this.browserFetchEvents) {
|
|
68
69
|
// check if current request could be handled
|
|
69
70
|
if (!this.canHandlePattern(fetchEvent, event.request.url, event.resourceType, event.responseHeaders ? "Response" : "Request")) {
|
|
70
71
|
continue;
|
|
71
72
|
}
|
|
72
|
-
const response = await fetchEvent.handle(event,
|
|
73
|
+
const response = await fetchEvent.handle(event, cdpSession);
|
|
73
74
|
if (!response) {
|
|
74
75
|
continue;
|
|
75
76
|
}
|
|
76
77
|
if (response instanceof abort_response_1.AbortResponse) {
|
|
77
|
-
|
|
78
|
+
return cdpSession.send("Fetch.failRequest", {
|
|
78
79
|
requestId: requestId,
|
|
79
80
|
errorReason: response.errorReason,
|
|
80
81
|
});
|
|
81
|
-
return;
|
|
82
82
|
}
|
|
83
|
-
|
|
83
|
+
return cdpSession.send("Fetch.fulfillRequest", {
|
|
84
84
|
...response,
|
|
85
85
|
requestId,
|
|
86
86
|
});
|
|
87
|
-
return;
|
|
88
87
|
}
|
|
89
88
|
//see: https://chromedevtools.github.io/devtools-protocol/tot/Fetch#method-continueRequest
|
|
90
|
-
|
|
89
|
+
return cdpSession.send("Fetch.continueRequest", {
|
|
91
90
|
requestId: requestId,
|
|
92
91
|
});
|
|
93
92
|
}
|
|
@@ -3,6 +3,32 @@ import { Protocol } from "puppeteer-core";
|
|
|
3
3
|
import { UserCliConfig } from "../../helpers/cli-config";
|
|
4
4
|
import { AbortResponse } from "./browser/abort-response";
|
|
5
5
|
import { FlagInput } from "@oclif/core/lib/interfaces/parser";
|
|
6
|
+
export declare const BROWSER_EVENTS: {
|
|
7
|
+
DISCONNECTED: string;
|
|
8
|
+
FETCH_AUTH_REQUIRED: string;
|
|
9
|
+
FETCH_REQUEST_PAUSED: string;
|
|
10
|
+
};
|
|
11
|
+
export declare const CDP_SESSION: {
|
|
12
|
+
EVENTS: {
|
|
13
|
+
SERVICE_WORKER: {
|
|
14
|
+
REGISTRATION_UPDATED: string;
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
MESSAGE: {
|
|
18
|
+
SERVICE_WORKER: {
|
|
19
|
+
ENABLE: string;
|
|
20
|
+
UNREGISTER: string;
|
|
21
|
+
};
|
|
22
|
+
STORAGE: {
|
|
23
|
+
CLEAR_COOKIES: string;
|
|
24
|
+
CLEAR_DATA: string;
|
|
25
|
+
};
|
|
26
|
+
EMULATION: {
|
|
27
|
+
CLEAR_DEVICE: string;
|
|
28
|
+
CLEAR_GEOLOCATION: string;
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
};
|
|
6
32
|
export declare class BrowserContext {
|
|
7
33
|
readonly domain: string;
|
|
8
34
|
readonly chromeFlags?: string[];
|
|
@@ -10,7 +36,6 @@ export declare class BrowserContext {
|
|
|
10
36
|
userAgent?: string;
|
|
11
37
|
readonly browserArgs: string[];
|
|
12
38
|
readonly chromePath: string;
|
|
13
|
-
startParameterDashboard: boolean;
|
|
14
39
|
constructor(domain: string, chromeFlags?: string[], userConfig?: UserCliConfig, userAgent?: string);
|
|
15
40
|
}
|
|
16
41
|
export interface FetchRequestPausedEventHandler {
|
|
@@ -22,14 +47,15 @@ export declare class OnboardingContext {
|
|
|
22
47
|
readonly configName: string;
|
|
23
48
|
readonly domain: string;
|
|
24
49
|
readonly local: boolean;
|
|
25
|
-
readonly verboseLevel?: boolean;
|
|
26
50
|
readonly ignoreContentSecurityPolicy: boolean;
|
|
51
|
+
readonly cliPath: string;
|
|
52
|
+
readonly verboseLevel?: boolean;
|
|
27
53
|
static flags: FlagInput;
|
|
28
54
|
readonly DEFAULT_DF_PATH = "https://www.baqend.com/speed-kit/latest/dynamic-fetcher.js";
|
|
29
55
|
readonly DEFAULT_DOCUMENT_HANDLER_PATH = "https://www.baqend.com/speed-kit-handler/latest/DocumentHandler.js";
|
|
30
56
|
readonly DEFAULT_SNIPPET_PATH = "https://www.baqend.com/speed-kit/latest/snippet.js";
|
|
31
57
|
readonly DEFAULT_SW_PATH = "https://www.baqend.com/speed-kit/latest/sw.js";
|
|
32
|
-
constructor(customerPath: string, configName: string, domain: string, local: boolean,
|
|
58
|
+
constructor(customerPath: string, configName: string, domain: string, local: boolean, ignoreContentSecurityPolicy: boolean, cliPath: string, verboseLevel?: boolean);
|
|
33
59
|
}
|
|
34
60
|
export type SpeedKitServerConfigAuthentication = {
|
|
35
61
|
password: string;
|
|
@@ -69,6 +95,10 @@ export type SpeedKitServerConfig = {
|
|
|
69
95
|
variations: SpeedKitServerConfigVariation;
|
|
70
96
|
};
|
|
71
97
|
};
|
|
98
|
+
export type DevelopmentToolsMessage = {
|
|
99
|
+
id: string;
|
|
100
|
+
data: any;
|
|
101
|
+
};
|
|
72
102
|
export declare const USER_AGENT: {
|
|
73
103
|
DESKTOP: string;
|
|
74
104
|
MOBILE: string;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.SpeedKitInstallRegex = exports.USER_AGENT = exports.OnboardingContext = exports.BrowserContext = void 0;
|
|
3
|
+
exports.SpeedKitInstallRegex = exports.USER_AGENT = exports.OnboardingContext = exports.BrowserContext = exports.CDP_SESSION = exports.BROWSER_EVENTS = void 0;
|
|
4
4
|
const core_1 = require("@oclif/core");
|
|
5
5
|
const cli_parameters_1 = require("../../models/cli-parameters");
|
|
6
6
|
const DEFAULT_BROWSER_ARGS = [
|
|
@@ -8,6 +8,32 @@ const DEFAULT_BROWSER_ARGS = [
|
|
|
8
8
|
"--no-first-run",
|
|
9
9
|
"--disable-infobars",
|
|
10
10
|
];
|
|
11
|
+
exports.BROWSER_EVENTS = {
|
|
12
|
+
DISCONNECTED: "disconnected",
|
|
13
|
+
FETCH_AUTH_REQUIRED: "Fetch.authRequired",
|
|
14
|
+
FETCH_REQUEST_PAUSED: "Fetch.requestPaused",
|
|
15
|
+
};
|
|
16
|
+
exports.CDP_SESSION = {
|
|
17
|
+
EVENTS: {
|
|
18
|
+
SERVICE_WORKER: {
|
|
19
|
+
REGISTRATION_UPDATED: "ServiceWorker.workerRegistrationUpdated",
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
MESSAGE: {
|
|
23
|
+
SERVICE_WORKER: {
|
|
24
|
+
ENABLE: "ServiceWorker.enable",
|
|
25
|
+
UNREGISTER: "ServiceWorker.unregister",
|
|
26
|
+
},
|
|
27
|
+
STORAGE: {
|
|
28
|
+
CLEAR_COOKIES: "Storage.clearCookies",
|
|
29
|
+
CLEAR_DATA: "Storage.clearDataForOrigin",
|
|
30
|
+
},
|
|
31
|
+
EMULATION: {
|
|
32
|
+
CLEAR_DEVICE: "Emulation.clearDeviceMetricsOverride",
|
|
33
|
+
CLEAR_GEOLOCATION: "Emulation.clearGeolocationOverride",
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
};
|
|
11
37
|
class BrowserContext {
|
|
12
38
|
domain;
|
|
13
39
|
chromeFlags;
|
|
@@ -15,7 +41,6 @@ class BrowserContext {
|
|
|
15
41
|
userAgent;
|
|
16
42
|
browserArgs;
|
|
17
43
|
chromePath;
|
|
18
|
-
startParameterDashboard = false;
|
|
19
44
|
constructor(domain, chromeFlags, userConfig, userAgent) {
|
|
20
45
|
this.domain = domain;
|
|
21
46
|
this.chromeFlags = chromeFlags;
|
|
@@ -44,8 +69,9 @@ class OnboardingContext {
|
|
|
44
69
|
configName;
|
|
45
70
|
domain;
|
|
46
71
|
local;
|
|
47
|
-
verboseLevel;
|
|
48
72
|
ignoreContentSecurityPolicy;
|
|
73
|
+
cliPath;
|
|
74
|
+
verboseLevel;
|
|
49
75
|
static flags = {
|
|
50
76
|
...cli_parameters_1.CLI_CONFIG_NAME,
|
|
51
77
|
[cli_parameters_1.CLIParameters.Domain]: core_1.Flags.string({
|
|
@@ -72,13 +98,14 @@ class OnboardingContext {
|
|
|
72
98
|
DEFAULT_DOCUMENT_HANDLER_PATH = "https://www.baqend.com/speed-kit-handler/latest/DocumentHandler.js";
|
|
73
99
|
DEFAULT_SNIPPET_PATH = "https://www.baqend.com/speed-kit/latest/snippet.js";
|
|
74
100
|
DEFAULT_SW_PATH = "https://www.baqend.com/speed-kit/latest/sw.js";
|
|
75
|
-
constructor(customerPath, configName, domain, local,
|
|
101
|
+
constructor(customerPath, configName, domain, local, ignoreContentSecurityPolicy = false, cliPath, verboseLevel) {
|
|
76
102
|
this.customerPath = customerPath;
|
|
77
103
|
this.configName = configName;
|
|
78
104
|
this.domain = domain;
|
|
79
105
|
this.local = local;
|
|
80
|
-
this.verboseLevel = verboseLevel;
|
|
81
106
|
this.ignoreContentSecurityPolicy = ignoreContentSecurityPolicy;
|
|
107
|
+
this.cliPath = cliPath;
|
|
108
|
+
this.verboseLevel = verboseLevel;
|
|
82
109
|
}
|
|
83
110
|
}
|
|
84
111
|
exports.OnboardingContext = OnboardingContext;
|
|
@@ -6,6 +6,7 @@ export declare class OnboardingServiceFactory {
|
|
|
6
6
|
private cliConfig;
|
|
7
7
|
constructor(context: OnboardingContext, cliConfig: UserCliConfig);
|
|
8
8
|
getService(): Promise<OnboardingService>;
|
|
9
|
+
private prepareMessagehandler;
|
|
9
10
|
private buildInstallResource;
|
|
10
11
|
private getAthenaClient;
|
|
11
12
|
private getConfigApi;
|
|
@@ -32,6 +32,9 @@ const onboarding_service_1 = require("./onboarding-service");
|
|
|
32
32
|
const cache_1 = require("./request-cache/cache");
|
|
33
33
|
const install_speed_kit_html_template_1 = require("./templates/install-speed-kit-html-template");
|
|
34
34
|
const install_speed_kit_js_template_1 = require("./templates/install-speed-kit-js-template");
|
|
35
|
+
// import { TodoCollector } from "./todo-collector";
|
|
36
|
+
const extension_validator_1 = require("./browser/extension/extension-validator");
|
|
37
|
+
const devtools_extension_api_1 = require("./browser/extension/devtools-extension-api");
|
|
35
38
|
const todo_collector_1 = require("./todo-collector");
|
|
36
39
|
const crawler_1 = require("./virtual-orestes-app/crawler");
|
|
37
40
|
const virtual_orestes_app_1 = require("./virtual-orestes-app");
|
|
@@ -60,11 +63,27 @@ class OnboardingServiceFactory {
|
|
|
60
63
|
const skTemplate = new install_speed_kit_js_template_1.InstallSpeedKitJsTemplate();
|
|
61
64
|
const speedKitInstallContext = new speed_kit_install_context_1.SpeedKitInstallContext(customerConfig, this.context.configName, files, bundler, skTemplate, this.context.local);
|
|
62
65
|
await this.buildInstallResource(speedKitInstallContext, files, cli);
|
|
66
|
+
const extensionPaths = await new extension_validator_1.ExtensionValidator(this.cliConfig, this.context.cliPath, cli).getValidBrowserExtensionPaths();
|
|
67
|
+
this.cliConfig.chromeExtensionPaths = extensionPaths.join(",");
|
|
63
68
|
const browserContext = new onboarding_model_1.BrowserContext(domainToStart, customerConfig.chromeFlags || [], this.cliConfig);
|
|
64
69
|
const fileWatcher = new file_watcher_1.FileWatcher(cli, customerConfig, files, documentHandler, browserContext, cache);
|
|
65
|
-
const
|
|
70
|
+
const athenaClient = (await this.getAthenaClient()) || null;
|
|
71
|
+
const fetchHandler = await this.getFetchEventHandler(files, customerConfig, documentHandler, cache, cli, browserContext, athenaClient);
|
|
72
|
+
const messageHandler = this.prepareMessagehandler(athenaClient, files);
|
|
73
|
+
return new onboarding_service_1.OnboardingService(browserContext, customerConfig, fetchHandler, fileWatcher, cli, messageHandler);
|
|
74
|
+
}
|
|
75
|
+
prepareMessagehandler(athenaClient, files) {
|
|
76
|
+
const messageHandler = new devtools_extension_api_1.DevtoolsExtensionApi();
|
|
77
|
+
messageHandler.addMessage({
|
|
78
|
+
id: "athena",
|
|
79
|
+
data: { client: !!athenaClient },
|
|
80
|
+
});
|
|
66
81
|
const fileTodoCollector = new todo_collector_1.TodoCollector(files.getInstallResources());
|
|
67
|
-
|
|
82
|
+
messageHandler.addMessage({
|
|
83
|
+
id: "todo",
|
|
84
|
+
data: [...fileTodoCollector.getOpenTasks()],
|
|
85
|
+
});
|
|
86
|
+
return messageHandler;
|
|
68
87
|
}
|
|
69
88
|
async buildInstallResource(speedKitInstallContext, files, cli) {
|
|
70
89
|
cli.startAction("build file install_resource");
|
|
@@ -89,7 +108,7 @@ class OnboardingServiceFactory {
|
|
|
89
108
|
const configApiContext = new config_api_context_1.default(app);
|
|
90
109
|
return new config_api_service_factory_1.default(configApiContext).getService();
|
|
91
110
|
}
|
|
92
|
-
async getFetchEventHandler(files, customerConfig, documentHandler, cache, cli, browserContext) {
|
|
111
|
+
async getFetchEventHandler(files, customerConfig, documentHandler, cache, cli, browserContext, athenaClient) {
|
|
93
112
|
const configApi = this.getConfigApi(customerConfig.app);
|
|
94
113
|
const serverConfig = await this.getSpeedKitServerConfig(configApi, cli);
|
|
95
114
|
const parameterQueryBuilder = new parameter_query_builder_1.ParameterQueryBuilder(customerConfig, files.getByName(files_1.INTEGRATION_FILES.CONFIG.SPEED_KIT));
|
|
@@ -107,7 +126,6 @@ class OnboardingServiceFactory {
|
|
|
107
126
|
const orestesApp = new virtual_orestes_app_1.VirtualOrestesApp(customerConfig, crawler, documentHandler, cache, cli);
|
|
108
127
|
handlers.push(new speed_kit_asset_request_1.SpeedKitAssetRequest(customerConfig, orestesApp), new speed_kit_rum_pi_request_1.SpeedKitRumPiRequest(customerConfig, cache, cli));
|
|
109
128
|
}
|
|
110
|
-
const athenaClient = await this.getAthenaClient();
|
|
111
129
|
if (athenaClient) {
|
|
112
130
|
handlers.push(new dashboard_request_1.DashboardRequest(new dashboard_1.Dashboard(customerConfig, parameterQueryBuilder, athenaClient, requestDiffService, cache)));
|
|
113
131
|
}
|
|
@@ -3,7 +3,7 @@ import { BrowserContext } from "./onboarding-model";
|
|
|
3
3
|
import { FetchEventHandler } from "./fetch-event-handler";
|
|
4
4
|
import { FileWatcher } from "./file-events/file-watcher";
|
|
5
5
|
import { CliService } from "../cli";
|
|
6
|
-
import {
|
|
6
|
+
import { DevtoolsExtensionApi } from "./browser/extension/devtools-extension-api";
|
|
7
7
|
/**
|
|
8
8
|
* Represents the OnboardingService which is responsible for setting up the browser to test a config using Puppeteer.
|
|
9
9
|
*/
|
|
@@ -13,9 +13,9 @@ export declare class OnboardingService {
|
|
|
13
13
|
private fetchEventHandler;
|
|
14
14
|
private fileWatcher;
|
|
15
15
|
private cli;
|
|
16
|
-
private
|
|
16
|
+
private developmentToolsMessages;
|
|
17
17
|
private reinstallOnNextNavigate;
|
|
18
|
-
constructor(browserContext: BrowserContext, customerConfig: CustomerConfig, fetchEventHandler: FetchEventHandler, fileWatcher: FileWatcher, cli: CliService,
|
|
18
|
+
constructor(browserContext: BrowserContext, customerConfig: CustomerConfig, fetchEventHandler: FetchEventHandler, fileWatcher: FileWatcher, cli: CliService, developmentToolsMessages: DevtoolsExtensionApi);
|
|
19
19
|
/**
|
|
20
20
|
* prepare puppeteerBrowser, add eventListeners and start
|
|
21
21
|
*/
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.OnboardingService = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const puppeteer_extra_1 = tslib_1.__importDefault(require("puppeteer-extra"));
|
|
6
|
-
const
|
|
6
|
+
const onboarding_model_1 = require("./onboarding-model");
|
|
7
7
|
const cli_1 = require("../cli");
|
|
8
8
|
const safe_1 = require("../../helpers/safe");
|
|
9
9
|
/**
|
|
@@ -15,15 +15,15 @@ class OnboardingService {
|
|
|
15
15
|
fetchEventHandler;
|
|
16
16
|
fileWatcher;
|
|
17
17
|
cli;
|
|
18
|
-
|
|
18
|
+
developmentToolsMessages;
|
|
19
19
|
reinstallOnNextNavigate = false;
|
|
20
|
-
constructor(browserContext, customerConfig, fetchEventHandler, fileWatcher, cli,
|
|
20
|
+
constructor(browserContext, customerConfig, fetchEventHandler, fileWatcher, cli, developmentToolsMessages) {
|
|
21
21
|
this.browserContext = browserContext;
|
|
22
22
|
this.customerConfig = customerConfig;
|
|
23
23
|
this.fetchEventHandler = fetchEventHandler;
|
|
24
24
|
this.fileWatcher = fileWatcher;
|
|
25
25
|
this.cli = cli;
|
|
26
|
-
this.
|
|
26
|
+
this.developmentToolsMessages = developmentToolsMessages;
|
|
27
27
|
}
|
|
28
28
|
/**
|
|
29
29
|
* prepare puppeteerBrowser, add eventListeners and start
|
|
@@ -33,10 +33,6 @@ class OnboardingService {
|
|
|
33
33
|
const browser = await this.prepareBrowser();
|
|
34
34
|
const page = await this.preparePage(browser);
|
|
35
35
|
this.cli.endAction(cli_1.CliActionStatus.COMPLETED);
|
|
36
|
-
if (this.browserContext.startParameterDashboard) {
|
|
37
|
-
const { goto } = await browser.newPage();
|
|
38
|
-
await goto("http://skonboarding.local/");
|
|
39
|
-
}
|
|
40
36
|
await this.navigate(page, `${this.customerConfig.scope}speed-kit-install.html?url=${this.customerConfig.scope}`);
|
|
41
37
|
}
|
|
42
38
|
async prepareBrowser() {
|
|
@@ -52,7 +48,7 @@ class OnboardingService {
|
|
|
52
48
|
await this.fetchEventHandler.handleRequestFetchEvents(target);
|
|
53
49
|
}
|
|
54
50
|
}
|
|
55
|
-
browser.on(
|
|
51
|
+
browser.on(onboarding_model_1.BROWSER_EVENTS.DISCONNECTED, () => {
|
|
56
52
|
this.cli.writeError("Browser disconnected, shutting down");
|
|
57
53
|
process.exit(-1);
|
|
58
54
|
});
|
|
@@ -60,14 +56,18 @@ class OnboardingService {
|
|
|
60
56
|
}
|
|
61
57
|
async preparePage(browser) {
|
|
62
58
|
const page = await this.findPage(browser);
|
|
63
|
-
await this.prepareCleanState(page);
|
|
59
|
+
await (0, safe_1.safe)(this.prepareCleanState(page));
|
|
64
60
|
this.registerFileWatcher(page);
|
|
65
61
|
this.registerReinstallSpeedKitOnNavigate(page);
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
await (0, safe_1.safe)(page.evaluate(`window.skOnboarding = ${JSON.stringify(tasks)}`));
|
|
62
|
+
this.developmentToolsMessages.addMessage({
|
|
63
|
+
id: "cli",
|
|
64
|
+
data: `config loaded for app "${this.customerConfig.app}"`,
|
|
70
65
|
});
|
|
66
|
+
const messages = this.developmentToolsMessages.messages;
|
|
67
|
+
await page.evaluateOnNewDocument((messages) => {
|
|
68
|
+
// @ts-expect-error unknown method getSkCliMessages
|
|
69
|
+
window.skCliMessages = messages;
|
|
70
|
+
}, messages);
|
|
71
71
|
return page;
|
|
72
72
|
}
|
|
73
73
|
async findPage(browser) {
|
|
@@ -80,27 +80,33 @@ class OnboardingService {
|
|
|
80
80
|
return browser.newPage();
|
|
81
81
|
}
|
|
82
82
|
async prepareCleanState(page) {
|
|
83
|
-
const
|
|
84
|
-
pageClient.on("ServiceWorker.workerRegistrationUpdated", ({ registrations, }) => {
|
|
85
|
-
for (const registration of registrations) {
|
|
86
|
-
if (registration.isDeleted) {
|
|
87
|
-
this.cli.writeWarning((0, chalk_1.default) `{yellow Unregistered Service Worker} at {bold ${registration.scopeURL}} (${registration.registrationId})`);
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
});
|
|
83
|
+
const cdpSession = await page.target().createCDPSession();
|
|
91
84
|
// cleanUp old serviceWorkers
|
|
92
|
-
await
|
|
93
|
-
await
|
|
85
|
+
await cdpSession.send("ServiceWorker.enable");
|
|
86
|
+
await cdpSession.send("ServiceWorker.unregister", {
|
|
94
87
|
scopeURL: this.browserContext.domain,
|
|
95
88
|
});
|
|
96
89
|
// clear storage for a clean start
|
|
97
|
-
await
|
|
98
|
-
await
|
|
90
|
+
await cdpSession.send("Storage.clearCookies");
|
|
91
|
+
await cdpSession.send("Storage.clearDataForOrigin", {
|
|
99
92
|
origin: this.browserContext.domain,
|
|
100
93
|
storageTypes: "all",
|
|
101
94
|
});
|
|
102
|
-
await
|
|
103
|
-
await
|
|
95
|
+
await cdpSession.send("Emulation.clearDeviceMetricsOverride");
|
|
96
|
+
await cdpSession.send("Emulation.clearGeolocationOverride");
|
|
97
|
+
(0, safe_1.safe)(() => {
|
|
98
|
+
cdpSession.on(onboarding_model_1.CDP_SESSION.EVENTS.SERVICE_WORKER.REGISTRATION_UPDATED, ({ registrations, }) => {
|
|
99
|
+
for (const registration of registrations) {
|
|
100
|
+
if (registration.isDeleted) {
|
|
101
|
+
this.developmentToolsMessages.addMessage({
|
|
102
|
+
id: "serviceWorker",
|
|
103
|
+
data: `Unregistered Service Worker at ${registration.scopeURL} id: ${registration.registrationId}`,
|
|
104
|
+
});
|
|
105
|
+
this.cli.writeWarning(`${this.cli.style.yellow("Unregistered Service Worker")} at ${this.cli.style.bold(registration.scopeURL)} (${registration.registrationId})`);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
});
|
|
104
110
|
}
|
|
105
111
|
async reinstallSpeedKit(page, pathname) {
|
|
106
112
|
const url = new URL(page.url());
|
|
@@ -129,8 +135,7 @@ class OnboardingService {
|
|
|
129
135
|
}
|
|
130
136
|
async navigate(page, pathname) {
|
|
131
137
|
const goto = new URL(pathname, `${this.browserContext.domain}`);
|
|
132
|
-
await page.goto(goto.toString());
|
|
133
|
-
await page.bringToFront();
|
|
138
|
+
await (0, safe_1.safe)(page.goto(goto.toString()));
|
|
134
139
|
}
|
|
135
140
|
}
|
|
136
141
|
exports.OnboardingService = OnboardingService;
|