@speedkit/cli 2.27.0 → 2.29.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.
Files changed (40) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/README.md +1 -1
  3. package/dist/helpers/get-parsed-config.d.ts +4 -0
  4. package/dist/helpers/get-parsed-config.js +4 -0
  5. package/dist/helpers/is-directory.d.ts +4 -0
  6. package/dist/helpers/is-directory.js +7 -1
  7. package/dist/helpers/is-file.d.ts +4 -0
  8. package/dist/helpers/is-file.js +7 -1
  9. package/dist/helpers/logging-helper.d.ts +6 -3
  10. package/dist/helpers/logging-helper.js +3 -0
  11. package/dist/services/customer-config/customer-config-service.js +0 -3
  12. package/dist/services/customer-config/templates/config_documentHandler.js.hbs +0 -4
  13. package/dist/services/deploy/interface/deploy-handler-interface.d.ts +4 -4
  14. package/dist/services/document-handler-runtime/document-handler-server.d.ts +2 -1
  15. package/dist/services/document-handler-runtime/document-handler-server.js +9 -8
  16. package/dist/services/document-handler-runtime/server/document-handler-response.d.ts +10 -0
  17. package/dist/services/document-handler-runtime/server/document-handler-response.js +19 -0
  18. package/dist/services/document-handler-runtime/server/request.d.ts +14 -0
  19. package/dist/services/document-handler-runtime/server/request.js +19 -0
  20. package/dist/services/onboarding/browser/baqend-response.d.ts +2 -2
  21. package/dist/services/onboarding/browser/baqend-response.js +10 -1
  22. package/dist/services/onboarding/dashboard/request-diff-service.js +4 -2
  23. package/dist/services/onboarding/fetch-events/speed-kit-asset-request.d.ts +4 -18
  24. package/dist/services/onboarding/fetch-events/speed-kit-asset-request.js +4 -153
  25. package/dist/services/onboarding/file-events/file-watcher.js +2 -1
  26. package/dist/services/onboarding/onboarding-model.d.ts +6 -1
  27. package/dist/services/onboarding/onboarding-model.js +8 -2
  28. package/dist/services/onboarding/onboarding-service-factory.d.ts +1 -0
  29. package/dist/services/onboarding/onboarding-service-factory.js +17 -8
  30. package/dist/services/onboarding/onboarding-service.js +1 -1
  31. package/dist/services/onboarding/request-cache/cache.js +9 -1
  32. package/dist/services/onboarding/virtual-orestes-app/crawler.d.ts +10 -0
  33. package/dist/services/onboarding/virtual-orestes-app/crawler.js +58 -0
  34. package/dist/services/onboarding/virtual-orestes-app/index.d.ts +26 -0
  35. package/dist/services/onboarding/virtual-orestes-app/index.js +190 -0
  36. package/oclif.manifest.json +1 -1
  37. package/package.json +1 -1
  38. package/dist/services/customer-config/templates/deploymentDetection.es6.hbs +0 -303
  39. package/dist/services/prewarm-service.d.ts +0 -5
  40. package/dist/services/prewarm-service.js +0 -64
package/CHANGELOG.md CHANGED
@@ -1,3 +1,28 @@
1
+ # [2.29.0](https://gitlab.orestes.info/baqend/speed-kit-cli/compare/v2.28.0...v2.29.0) (2024-05-23)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * **onboarding:** add missing method header on internal response ([02ef83c](https://gitlab.orestes.info/baqend/speed-kit-cli/commit/02ef83c8dde676e7018713b62abf749173cecde7))
7
+ * **onboarding:** set correct response headers ([c670622](https://gitlab.orestes.info/baqend/speed-kit-cli/commit/c67062206a51388f831784be9b8d779f060e5f0b))
8
+ * **onboarding:** set correct response headers ([c923977](https://gitlab.orestes.info/baqend/speed-kit-cli/commit/c9239770846a61d25eb8c6e0eaa325e9c075429f))
9
+
10
+
11
+ ### Features
12
+
13
+ * **onboarding:** refactor assetRequestFetchEventHandler ([94f2ea6](https://gitlab.orestes.info/baqend/speed-kit-cli/commit/94f2ea6c3e46bda5b84f2020c91501db25e38b3e))
14
+ * **onboarding:** remove use browsersUserAgent ([5d781a5](https://gitlab.orestes.info/baqend/speed-kit-cli/commit/5d781a5c4b1c2e126e9ab69ce3e7991059729b0c))
15
+ * **onboarding:** respect redirects ([ce96851](https://gitlab.orestes.info/baqend/speed-kit-cli/commit/ce96851bfd706d7b8128693cfb0e8b7c12494537))
16
+ * **onboarding:** use serverConfig to fetch correct remoteHeaders ([2dc8d4e](https://gitlab.orestes.info/baqend/speed-kit-cli/commit/2dc8d4e775c3bc882e3e2933a5cc8ee0d958e706))
17
+ * **onboarding:** wrap fetchOriginRequest to display correct error ([19f1b50](https://gitlab.orestes.info/baqend/speed-kit-cli/commit/19f1b5033fd91bd64b6b1778b19fcc0d01b4312e))
18
+
19
+ # [2.28.0](https://gitlab.orestes.info/baqend/speed-kit-cli/compare/v2.27.0...v2.28.0) (2024-05-22)
20
+
21
+
22
+ ### Features
23
+
24
+ * **customer-config:** remove old deployment detection ([a3661c7](https://gitlab.orestes.info/baqend/speed-kit-cli/commit/a3661c7db68ade9907b15caaa1edf370e51783ca))
25
+
1
26
  # [2.27.0](https://gitlab.orestes.info/baqend/speed-kit-cli/compare/v2.26.0...v2.27.0) (2024-05-03)
2
27
 
3
28
 
package/README.md CHANGED
@@ -21,7 +21,7 @@ $ npm install -g @speedkit/cli
21
21
  $ sk COMMAND
22
22
  running command...
23
23
  $ sk (--version)
24
- @speedkit/cli/2.27.0 linux-x64 node-v20.12.2
24
+ @speedkit/cli/2.29.0 linux-x64 node-v20.13.1
25
25
  $ sk --help [COMMAND]
26
26
  USAGE
27
27
  $ sk COMMAND
@@ -5,6 +5,10 @@ interface SpeedKitConfig {
5
5
  };
6
6
  [key: string]: any;
7
7
  }
8
+ /**
9
+ * @deprecated
10
+ * @param config
11
+ */
8
12
  export declare function parseSpeedKitConfig(config: string): SpeedKitConfig;
9
13
  export declare function getParsedConfig(configFile: ConfigFile): Promise<SpeedKitConfig>;
10
14
  export declare function getSpeedKitConfigVersion(config: SpeedKitConfig): number;
@@ -3,6 +3,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getSpeedKitConfigVersion = exports.getParsedConfig = exports.parseSpeedKitConfig = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const vm = tslib_1.__importStar(require("node:vm"));
6
+ /**
7
+ * @deprecated
8
+ * @param config
9
+ */
6
10
  function parseSpeedKitConfig(config) {
7
11
  // Replace all properties that use function calls or that are related to other objects like window
8
12
  const window = {};
@@ -1 +1,5 @@
1
+ /**
2
+ * @deprecated
3
+ * @param directory
4
+ */
1
5
  export declare function isDirectory(directory: string): Promise<boolean>;
@@ -2,13 +2,19 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.isDirectory = void 0;
4
4
  const promises_1 = require("node:fs/promises");
5
+ /**
6
+ * @deprecated
7
+ * @param directory
8
+ */
5
9
  async function isDirectory(directory) {
6
10
  try {
7
11
  const stats = await (0, promises_1.stat)(directory);
8
12
  return stats.isDirectory();
9
13
  }
10
14
  catch (error) {
11
- if (error.code === "ENOENT") {
15
+ if (typeof error === "object" &&
16
+ "code" in error &&
17
+ error.code === "ENOENT") {
12
18
  return false;
13
19
  }
14
20
  throw error;
@@ -1 +1,5 @@
1
+ /**
2
+ * @deprecated
3
+ * @param filename
4
+ */
1
5
  export declare function isFile(filename: string): Promise<boolean>;
@@ -2,13 +2,19 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.isFile = void 0;
4
4
  const promises_1 = require("node:fs/promises");
5
+ /**
6
+ * @deprecated
7
+ * @param filename
8
+ */
5
9
  async function isFile(filename) {
6
10
  try {
7
11
  const stats = await (0, promises_1.stat)(filename);
8
12
  return stats.isFile();
9
13
  }
10
14
  catch (error) {
11
- if (error.code === "ENOENT") {
15
+ if (typeof error === "object" &&
16
+ "code" in error &&
17
+ error.code === "ENOENT") {
12
18
  return false;
13
19
  }
14
20
  throw error;
@@ -1,12 +1,15 @@
1
1
  /**
2
2
  * Logs the given message 'green' in the console.
3
+ * @deprecated
3
4
  */
4
- export declare function logInfo(message: string, ...optionalParameters: any[]): void;
5
+ export declare function logInfo(message: string, ...optionalParameters: unknown[]): void;
5
6
  /**
6
7
  * Logs the given message 'red' in the console.
8
+ * @deprecated
7
9
  */
8
- export declare function logError(message: string, ...optionalParameters: any[]): void;
10
+ export declare function logError(message: string, ...optionalParameters: unknown[]): void;
9
11
  /**
10
12
  * Logs the given message 'yellow' in the console.
13
+ * @deprecated
11
14
  */
12
- export declare function logWarning(message: string, ...optionalParameters: any[]): void;
15
+ export declare function logWarning(message: string, ...optionalParameters: unknown[]): void;
@@ -6,6 +6,7 @@ const chalk_1 = tslib_1.__importDefault(require("chalk"));
6
6
  // TODO: use CliService instead
7
7
  /**
8
8
  * Logs the given message 'green' in the console.
9
+ * @deprecated
9
10
  */
10
11
  function logInfo(message, ...optionalParameters) {
11
12
  console.log(chalk_1.default.green(message), ...optionalParameters);
@@ -13,6 +14,7 @@ function logInfo(message, ...optionalParameters) {
13
14
  exports.logInfo = logInfo;
14
15
  /**
15
16
  * Logs the given message 'red' in the console.
17
+ * @deprecated
16
18
  */
17
19
  function logError(message, ...optionalParameters) {
18
20
  console.log(chalk_1.default.red(message), ...optionalParameters);
@@ -20,6 +22,7 @@ function logError(message, ...optionalParameters) {
20
22
  exports.logError = logError;
21
23
  /**
22
24
  * Logs the given message 'yellow' in the console.
25
+ * @deprecated
23
26
  */
24
27
  function logWarning(message, ...optionalParameters) {
25
28
  console.log(chalk_1.default.yellow(message), ...optionalParameters);
@@ -264,9 +264,6 @@ class CustomerConfigService {
264
264
  async generateConfig() {
265
265
  this.cli.write("\nLet's generate a config...\n");
266
266
  const configSettings = await this.getConfigSettings();
267
- if (configSettings.isSalesforce) {
268
- this.templates.push("deploymentDetection.es6.hbs");
269
- }
270
267
  const addDowntimeDetection = await this.cli.confirm("Add Downtime Detection?", false);
271
268
  if (addDowntimeDetection) {
272
269
  this.templates.push("downtimeDetection.js.hbs");
@@ -87,11 +87,7 @@ const config = {
87
87
  {{else}}
88
88
  delayScriptPath: "/speed-kit-dom-ready.js",
89
89
  {{/if}}
90
- {{#if isSalesforce}}
91
- executeDeploymentDetection: false, // Salesforce specific => deploymentDetection.es6 is being used instead
92
- {{else}}
93
90
  executeDeploymentDetection: true,
94
- {{/if}}
95
91
  {{#unless addPreRendering}}
96
92
  {{#if removeLazyLoading}}
97
93
  lazyLoadList,
@@ -1,6 +1,6 @@
1
- import { FileInterface } from "../../integration-api/integration-api-model";
1
+ import { FILE_TYPE, FileInterface } from "../../integration-api";
2
2
  export default interface DeployHandlerInterface {
3
- canHandle(type: any): boolean;
4
- handle(files: FileInterface[]): Promise<any>;
5
- upload(files: FileInterface[]): Promise<any>;
3
+ canHandle(type: FILE_TYPE): boolean;
4
+ handle(files: FileInterface[]): Promise<void>;
5
+ upload(files: FileInterface[]): Promise<void>;
6
6
  }
@@ -1,6 +1,7 @@
1
1
  import { BundleService } from "../bundler";
2
2
  import { CliService } from "../cli";
3
3
  import { CustomerConfig, FileListInterface } from "../integration-api";
4
+ import { DocumentHandlerResponse } from "./server/document-handler-response";
4
5
  export declare class DocumentHandlerServer {
5
6
  private customerConfig;
6
7
  private files;
@@ -13,7 +14,7 @@ export declare class DocumentHandlerServer {
13
14
  constructor(customerConfig: CustomerConfig, files: FileListInterface, bundler: BundleService, cli: CliService, verboseLevel?: boolean);
14
15
  transform(html: string, variation: string, url: string, headers: {
15
16
  [name: string]: string;
16
- }): Promise<string>;
17
+ }): Promise<DocumentHandlerResponse>;
17
18
  private getTransformFunctionWrapper;
18
19
  buildDocumentHandler(): Promise<void>;
19
20
  private createDocumentHandlerConfigFile;
@@ -11,6 +11,8 @@ const node_path_1 = tslib_1.__importDefault(require("node:path"));
11
11
  const files_1 = require("../../models/files");
12
12
  // documentHandlerDependencies
13
13
  const node_fetch_1 = tslib_1.__importDefault(require("node-fetch"));
14
+ const request_1 = require("./server/request");
15
+ const document_handler_response_1 = require("./server/document-handler-response");
14
16
  class DocumentHandlerServer {
15
17
  customerConfig;
16
18
  files;
@@ -31,13 +33,12 @@ class DocumentHandlerServer {
31
33
  if (!this.documentHandlerCode) {
32
34
  await this.buildDocumentHandler();
33
35
  }
34
- const skInternalRequest = {
35
- query: { variation, headers: JSON.stringify(headers), url },
36
- body: html,
37
- };
36
+ const skInternalRequest = new request_1.Request(url, html, variation, headers);
37
+ const skInternalResponse = new document_handler_response_1.DocumentHandlerResponse();
38
38
  const vmContext = {
39
39
  db: await this.createDataBaseMock(),
40
40
  skInternalRequest,
41
+ skInternalResponse,
41
42
  skInternalHtml: "",
42
43
  skInternalError: {},
43
44
  Abort: Error,
@@ -62,16 +63,16 @@ class DocumentHandlerServer {
62
63
  filename: this.files.getByName("config_documentHandler").path,
63
64
  });
64
65
  try {
65
- return await (async () => {
66
+ const documentHandlerResponse = await (async () => {
66
67
  return await new Promise((resolve, reject) => {
67
- // @ts-expect-error resolve is unknown
68
- vmContext.resolve = resolve;
68
+ vmContext.skInternalResponse.resolve = resolve;
69
69
  // @ts-expect-error reject is unknown
70
70
  vmContext.reject = reject;
71
71
  const context = vm.createContext(vmContext);
72
72
  script.runInContext(context, { displayErrors: true });
73
73
  });
74
74
  })();
75
+ return documentHandlerResponse;
75
76
  }
76
77
  catch (error) {
77
78
  if (error instanceof Error) {
@@ -81,7 +82,7 @@ class DocumentHandlerServer {
81
82
  }
82
83
  }
83
84
  getTransformFunctionWrapper() {
84
- return `\n\ndocumentHandler.transform(db, skInternalRequest).then(result => {resolve(result);}).catch((err)=>{reject(err);});`;
85
+ return `\n\npost(db, skInternalRequest, skInternalResponse).catch((err)=>{reject(err);});`;
85
86
  }
86
87
  async buildDocumentHandler() {
87
88
  this.documentHandlerCode = await this.getDocumentHandler();
@@ -0,0 +1,10 @@
1
+ export declare class DocumentHandlerResponse {
2
+ headers: {
3
+ [name: string]: string;
4
+ };
5
+ body: string;
6
+ resolve: (resolvable: unknown) => void;
7
+ header(key: string, value: string): void;
8
+ set(key: string, value: string): void;
9
+ send(html: string): void;
10
+ }
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DocumentHandlerResponse = void 0;
4
+ class DocumentHandlerResponse {
5
+ headers = {};
6
+ body = "";
7
+ resolve;
8
+ header(key, value) {
9
+ this.set(key, value);
10
+ }
11
+ set(key, value) {
12
+ this.headers[key] = value;
13
+ }
14
+ send(html) {
15
+ this.body = html;
16
+ this.resolve(this);
17
+ }
18
+ }
19
+ exports.DocumentHandlerResponse = DocumentHandlerResponse;
@@ -0,0 +1,14 @@
1
+ type query = {
2
+ url: string;
3
+ variation: string;
4
+ headers: string;
5
+ };
6
+ export declare class Request {
7
+ query: query;
8
+ body: string;
9
+ constructor(url: string, body: string, variation: string, headers: {
10
+ [name: string]: string;
11
+ });
12
+ get(key: string): string | null;
13
+ }
14
+ export {};
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Request = void 0;
4
+ class Request {
5
+ query;
6
+ body;
7
+ constructor(url, body, variation, headers) {
8
+ this.query = { variation, headers: JSON.stringify(headers), url };
9
+ this.body = body;
10
+ }
11
+ get(key) {
12
+ const headers = JSON.parse(this.query.headers);
13
+ const foundKey = Object.keys(headers).find((headerKey) => {
14
+ return headerKey.toLowerCase().includes(key.toLowerCase());
15
+ });
16
+ return this.query.headers[foundKey];
17
+ }
18
+ }
19
+ exports.Request = Request;
@@ -4,8 +4,8 @@ export declare class BaqendResponse implements Partial<Protocol.Fetch.FulfillReq
4
4
  readonly responseCode: number;
5
5
  readonly body: string;
6
6
  responseHeaders: Protocol.Fetch.HeaderEntry[];
7
- private contentType;
8
- private contentLength;
7
+ private readonly contentType;
8
+ private readonly contentLength;
9
9
  constructor(body: string, contentType?: string, headers?: Protocol.Fetch.HeaderEntry[], status?: number);
10
10
  setHeader(name: string, value: string): void;
11
11
  protected addCustomHeaders(headers?: Protocol.Fetch.HeaderEntry[]): Protocol.Fetch.HeaderEntry[];
@@ -17,11 +17,11 @@ class BaqendResponse {
17
17
  constructor(body, contentType, headers, status) {
18
18
  this.responseCode = status || DEFAULT_STATUS;
19
19
  this.contentType = contentType || DEFAULT_CONTENT_TYPE;
20
+ this.contentLength = body.length;
20
21
  this.responseHeaders = this.addCustomHeaders([
21
22
  ...DEFAULT_HEADERS,
22
23
  ...(headers || []),
23
24
  ]);
24
- this.contentLength = body.length;
25
25
  this.body = Buffer.from(body).toString("base64");
26
26
  }
27
27
  setHeader(name, value) {
@@ -54,6 +54,15 @@ class BaqendResponse {
54
54
  headers.push({ name: "Content-Type", value: String(this.contentType) });
55
55
  }
56
56
  headers.push({ name: "via", value: "sk-onboarding" }, { name: "Service-Worker-Allowed", value: "/" });
57
+ const exposeHeaders = headers
58
+ .map((header) => {
59
+ return header.name;
60
+ })
61
+ .join(", ") + ", Access-Control-Expose-Headers";
62
+ headers.push({
63
+ name: "Access-Control-Expose-Headers",
64
+ value: exposeHeaders,
65
+ });
57
66
  return headers;
58
67
  }
59
68
  }
@@ -36,9 +36,11 @@ class RequestDiffService {
36
36
  const htmlWithoutParameter = await this.fetchHtml(urlWithoutParameter);
37
37
  const replaceRegEx = /<meta[^>]*name="baqend:asset_url"[^>]*>/;
38
38
  // <meta name="baqend:asset_url" content="https://www.kik.de/c/damen/damen-bekleidung-shirts-tops?page=7">
39
- let transformedHtmlWithParameter = await this.documentHandlerRuntime.transform(htmlWithParameter, "", urlWithParameter, {});
39
+ const transformedHtmlWithParameterResponse = await this.documentHandlerRuntime.transform(htmlWithParameter, "", urlWithParameter, {});
40
+ let transformedHtmlWithParameter = transformedHtmlWithParameterResponse.body;
40
41
  transformedHtmlWithParameter = transformedHtmlWithParameter.replace(replaceRegEx, "");
41
- let transformedHtmlWithoutParameter = await this.documentHandlerRuntime.transform(htmlWithoutParameter, "", urlWithParameter, {});
42
+ const transformedHtmlWithoutParameterResponse = await this.documentHandlerRuntime.transform(htmlWithoutParameter, "", urlWithParameter, {});
43
+ let transformedHtmlWithoutParameter = transformedHtmlWithoutParameterResponse.body;
42
44
  transformedHtmlWithoutParameter = transformedHtmlWithoutParameter.replace(replaceRegEx, "");
43
45
  if (checkIsEqual) {
44
46
  return this.diffService.isContentEqual(transformedHtmlWithParameter, transformedHtmlWithoutParameter);
@@ -1,29 +1,15 @@
1
1
  import Protocol from "devtools-protocol";
2
- import { FetchRequestPausedEventHandler, SpeedKitServerConfig } from "../onboarding-model";
2
+ import { FetchRequestPausedEventHandler } from "../onboarding-model";
3
3
  import { CustomerConfig } from "../../integration-api";
4
- import { DocumentHandlerServer } from "../../document-handler-runtime/document-handler-server";
5
4
  import { AbortResponse } from "../browser/abort-response";
6
- import { Cache } from "../request-cache/cache";
7
- import { CliService } from "../../cli";
5
+ import { VirtualOrestesApp } from "../virtual-orestes-app";
8
6
  /**
9
7
  * Handles fetch requests for Speed Kit assets and returns customized responses.
10
8
  */
11
9
  export declare class SpeedKitAssetRequest implements FetchRequestPausedEventHandler {
12
10
  private customerConfig;
13
- private documentHandler;
14
- private cache;
15
- private cli;
16
- private speedKitServerConfig?;
11
+ private virtualOrestesApp;
17
12
  get patterns(): Protocol.Fetch.RequestPattern[];
18
- constructor(customerConfig: CustomerConfig, documentHandler: DocumentHandlerServer, cache: Cache, cli: CliService, speedKitServerConfig?: SpeedKitServerConfig);
13
+ constructor(customerConfig: CustomerConfig, virtualOrestesApp: VirtualOrestesApp);
19
14
  handle(event: Protocol.Fetch.RequestPausedEvent): Promise<Partial<Protocol.Fetch.FulfillRequestRequest> | AbortResponse>;
20
- private fetchAsset;
21
- private getCachedResponse;
22
- private buildCustomHeaders;
23
- private createResponseFromLocalDocumentHandler;
24
- private getAssetUrl;
25
- private isHtmlContentHeader;
26
- private isValidHtmlContent;
27
- private rewriteInstallResource;
28
- private prepareOriginRequest;
29
15
  }
@@ -1,25 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.SpeedKitAssetRequest = void 0;
4
- const tslib_1 = require("tslib");
5
- const baqend_response_1 = require("../browser/baqend-response");
6
- const node_https_1 = require("node:https");
7
- const node_crypto_1 = tslib_1.__importDefault(require("node:crypto"));
8
- const node_fetch_1 = tslib_1.__importDefault(require("node-fetch"));
9
- const agent = new node_https_1.Agent({
10
- rejectUnauthorized: false,
11
- keepAlive: true,
12
- secureOptions: node_crypto_1.default.constants.SSL_OP_LEGACY_SERVER_CONNECT,
13
- });
14
4
  /**
15
5
  * Handles fetch requests for Speed Kit assets and returns customized responses.
16
6
  */
17
7
  class SpeedKitAssetRequest {
18
8
  customerConfig;
19
- documentHandler;
20
- cache;
21
- cli;
22
- speedKitServerConfig;
9
+ virtualOrestesApp;
23
10
  get patterns() {
24
11
  const result = [];
25
12
  for (const origin of this.customerConfig.origins) {
@@ -39,148 +26,12 @@ class SpeedKitAssetRequest {
39
26
  }
40
27
  return result;
41
28
  }
42
- constructor(customerConfig, documentHandler, cache, cli, speedKitServerConfig) {
29
+ constructor(customerConfig, virtualOrestesApp) {
43
30
  this.customerConfig = customerConfig;
44
- this.documentHandler = documentHandler;
45
- this.cache = cache;
46
- this.cli = cli;
47
- this.speedKitServerConfig = speedKitServerConfig;
31
+ this.virtualOrestesApp = virtualOrestesApp;
48
32
  }
49
33
  async handle(event) {
50
- const originUrl = this.getAssetUrl(event.request.url);
51
- const UrlObject = new URL(event.request.url);
52
- const variation = UrlObject.searchParams.has("bqvariation")
53
- ? UrlObject.searchParams.get("bqvariation").toUpperCase()
54
- : "DEFAULT";
55
- const cachedResponse = this.getCachedResponse(event.request.url);
56
- if (cachedResponse instanceof baqend_response_1.BaqendResponse) {
57
- return cachedResponse;
58
- }
59
- const response = await this.fetchAsset(originUrl, variation, event);
60
- const customHeaders = this.buildCustomHeaders(originUrl);
61
- if (response.headers.get("Content-Type").includes("image") ||
62
- response.headers.get("Content-Type").includes("font")) {
63
- return;
64
- }
65
- const responseContent = await response.text();
66
- if (!this.isHtmlContentHeader(response.headers) ||
67
- !this.isValidHtmlContent(responseContent)) {
68
- const customResponse = new baqend_response_1.BaqendResponse(responseContent, response.headers.get("Content-Type") || null, customHeaders);
69
- this.cache.addEntry(event.request.url, customResponse);
70
- return customResponse;
71
- }
72
- try {
73
- let customResponse = await this.createResponseFromLocalDocumentHandler(responseContent, variation, originUrl, event.request.headers);
74
- customResponse = customResponse.replace("speed-kit-dynamic-load", "skonboarding speed-kit-dynamic-load");
75
- if (this.customerConfig.forceInstall) {
76
- customResponse = this.rewriteInstallResource(customResponse);
77
- }
78
- const response = new baqend_response_1.BaqendResponse(customResponse, null, customHeaders);
79
- this.cache.addEntry(event.request.url, response);
80
- return response;
81
- }
82
- catch (error) {
83
- let message = "could not transform html";
84
- if (error instanceof Error) {
85
- message = error.message;
86
- }
87
- this.cli.writeError(message);
88
- customHeaders.push({ name: "x-error", value: message });
89
- return new baqend_response_1.BaqendResponse(message, null, customHeaders, 500);
90
- }
91
- }
92
- fetchAsset(originUrl, variation, event) {
93
- return (0, node_fetch_1.default)(originUrl, {
94
- ...this.prepareOriginRequest(variation, {
95
- headers: event.request.headers,
96
- }),
97
- agent,
98
- });
99
- }
100
- getCachedResponse(requestUrl) {
101
- const response = this.cache.getEntry(requestUrl);
102
- if (!(response instanceof baqend_response_1.BaqendResponse)) {
103
- return;
104
- }
105
- response.setHeader("x-cache", "POP, HIT");
106
- response.setHeader("x-served-by", "cache-local");
107
- response.setHeader("server-timing", "pop;desc=LOCAL;dur=1,cache;desc=CACHE,hotness;desc=1,proto;desc=h3");
108
- return response;
109
- }
110
- buildCustomHeaders(originUrl) {
111
- const time = new Date().toUTCString();
112
- const originDomain = new URL(originUrl).origin;
113
- return [
114
- { name: "origin", value: originDomain },
115
- { name: "Access-Control-Allow-Credentials", value: "true" },
116
- {
117
- name: "Access-Control-Expose-Headers",
118
- 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",
119
- },
120
- {
121
- name: "strict-transport-security",
122
- value: "max-age=31536000; includeSubDomains",
123
- },
124
- { name: "timing-allow-origin", value: originDomain },
125
- {
126
- name: "Cache-Control",
127
- value: "public,browser-ttl=0,sw-max-age=31536000,max-age=31469674",
128
- },
129
- {
130
- name: "server-timing",
131
- value: "pop;desc=LOCAL;dur=1,cache;desc=STREAM,hotness;desc=1,proto;desc=h3",
132
- },
133
- {
134
- name: "Alt-Svc",
135
- value: 'h3=":443";ma=86400,h3-29=":443";ma=86400,h3-27=":443";ma=86400',
136
- },
137
- { name: "x-frame-options", value: "SAMEORIGIN" },
138
- { name: "x-cache", value: "STREAM, HIT" },
139
- { name: "x-cache-hits", value: "1" },
140
- { name: "x-served-by", value: "stream-local" },
141
- { name: "Date", value: time },
142
- { name: "last-modified", value: time },
143
- { name: "Baqend-Created-At", value: time },
144
- { name: "Age", value: "0" },
145
- ];
146
- }
147
- async createResponseFromLocalDocumentHandler(html, variation, url, headers) {
148
- return this.documentHandler.transform(html, variation, url, headers);
149
- }
150
- getAssetUrl(requestUrl) {
151
- const url = new URL(requestUrl);
152
- for (const [name] of url.searchParams.entries()) {
153
- if (name.startsWith("bq") || name === "bqsk") {
154
- url.searchParams.delete(name);
155
- }
156
- }
157
- const cleanedUrl = url.toString();
158
- return cleanedUrl.split("app.baqend.com/v1/asset/")[1];
159
- }
160
- isHtmlContentHeader(responseHeaders) {
161
- return (responseHeaders.has("content-type") &&
162
- responseHeaders.get("content-type").includes("text/html"));
163
- }
164
- isValidHtmlContent(text) {
165
- return text.includes("<html");
166
- }
167
- rewriteInstallResource(text) {
168
- text = text.replace(/<script(?:.(?!<\/script>))*app\.baqend\.com\/v1\/speedkit\/install.js(?:.|(?!<\/script>))*<\/script>/, "");
169
- return text.replace(/<\s*head\b[^>]*>/, (head) => {
170
- return `${head}\n<script src="${this.customerConfig.installPath}" ${this.customerConfig.installParams}></script>`;
171
- });
172
- }
173
- prepareOriginRequest(variationParameter, init) {
174
- if (!this.speedKitServerConfig || !variationParameter) {
175
- return init;
176
- }
177
- const variation = variationParameter.toUpperCase();
178
- if (!(variation in this.speedKitServerConfig.speedKit.variations)) {
179
- return init;
180
- }
181
- const variationConfig = this.speedKitServerConfig.speedKit.variations[variation];
182
- init.headers = { ...init.headers, ...variationConfig.headers };
183
- return init;
34
+ return this.virtualOrestesApp.fetchAssetResponse(event);
184
35
  }
185
36
  }
186
37
  exports.SpeedKitAssetRequest = SpeedKitAssetRequest;
@@ -142,9 +142,10 @@ class FileWatcher {
142
142
  }
143
143
  async clearServiceWorker(page) {
144
144
  const client = await page.target().createCDPSession();
145
+ const currentOrigin = new URL(page.url()).origin;
145
146
  await client.send("ServiceWorker.enable");
146
147
  await client.send("ServiceWorker.unregister", {
147
- scopeURL: `https://${this.customerConfig.domain}`,
148
+ scopeURL: currentOrigin,
148
149
  });
149
150
  }
150
151
  }
@@ -7,10 +7,11 @@ export declare class BrowserContext {
7
7
  readonly domain: string;
8
8
  readonly chromeFlags?: string[];
9
9
  readonly userConfig?: UserCliConfig;
10
+ userAgent?: string;
10
11
  readonly browserArgs: string[];
11
12
  readonly chromePath: string;
12
13
  startParameterDashboard: boolean;
13
- constructor(domain: string, chromeFlags?: string[], userConfig?: UserCliConfig);
14
+ constructor(domain: string, chromeFlags?: string[], userConfig?: UserCliConfig, userAgent?: string);
14
15
  }
15
16
  export interface FetchRequestPausedEventHandler {
16
17
  handle(event: Protocol.Fetch.RequestPausedEvent, client: CDPSession): Promise<AbortResponse | Partial<Protocol.Fetch.FulfillRequestRequest> | void>;
@@ -67,3 +68,7 @@ export type SpeedKitServerConfig = {
67
68
  variations: SpeedKitServerConfigVariation;
68
69
  };
69
70
  };
71
+ export declare const USER_AGENT: {
72
+ DESKTOP: string;
73
+ MOBILE: string;
74
+ };