@speedkit/cli 4.23.3 → 4.24.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/.env.sample +7 -0
- package/CHANGELOG.md +14 -0
- package/README.md +1 -1
- package/dist/helpers/origin-proxy.d.ts +89 -0
- package/dist/helpers/origin-proxy.js +207 -0
- package/dist/helpers/origin-proxy.spec.d.ts +1 -0
- package/dist/helpers/origin-proxy.spec.js +167 -0
- package/dist/helpers/scrape.js +2 -2
- package/dist/helpers/site-analyzer.js +2 -2
- package/dist/services/bundler/bundle-service-factory.d.ts +2 -1
- package/dist/services/bundler/bundle-service-factory.js +4 -2
- package/dist/services/bundler/bundle-service.d.ts +30 -2
- package/dist/services/bundler/bundle-service.js +81 -6
- package/dist/services/bundler/bundle-service.spec.js +124 -0
- package/dist/services/document-handler-runtime/document-handler-server.d.ts +23 -3
- package/dist/services/document-handler-runtime/document-handler-server.js +66 -43
- package/dist/services/document-handler-runtime/factory/document-handler-runtime-service-factory.js +7 -2
- package/dist/services/onboarding/dashboard/request-diff-service.js +5 -11
- package/dist/services/onboarding/onboarding-service-factory.d.ts +0 -2
- package/dist/services/onboarding/onboarding-service-factory.js +5 -43
- package/dist/services/onboarding/virtual-orestes-app/crawler.d.ts +1 -3
- package/dist/services/onboarding/virtual-orestes-app/crawler.js +6 -10
- package/dist/services/onboarding/virtual-orestes-app/crawler.spec.d.ts +1 -0
- package/dist/services/onboarding/virtual-orestes-app/crawler.spec.js +49 -0
- package/dist/services/origin-request/origin-request-service-factory.js +5 -1
- package/dist/services/origin-request/origin-request-service.js +2 -1
- package/oclif.manifest.json +1 -1
- package/package.json +2 -1
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
import { safe } from "../../../helpers/safe.js";
|
|
2
2
|
import { resolveRequest, UndefinedVariationError, } from "../../origin-request/index.js";
|
|
3
|
+
import { originFetch } from "../../../helpers/origin-proxy.js";
|
|
3
4
|
import { randomUUID } from "node:crypto";
|
|
4
5
|
export class Crawler {
|
|
5
6
|
cli;
|
|
6
|
-
agentConfig;
|
|
7
7
|
speedKitServerConfig;
|
|
8
8
|
/** Warnings already shown, so a per-fetch condition is reported once per session. */
|
|
9
9
|
warned = new Set();
|
|
10
|
-
constructor(cli,
|
|
10
|
+
constructor(cli, speedKitServerConfig) {
|
|
11
11
|
this.cli = cli;
|
|
12
|
-
this.agentConfig = agentConfig;
|
|
13
12
|
this.speedKitServerConfig = speedKitServerConfig;
|
|
14
13
|
}
|
|
15
14
|
warnOnce(key, message) {
|
|
@@ -22,13 +21,9 @@ export class Crawler {
|
|
|
22
21
|
// origin URL with the variation's query params applied — returned so callers compare it
|
|
23
22
|
// (not the bare originUrl) against response.url for redirect detection
|
|
24
23
|
const { url, init } = this.prepareOriginRequest(originUrl, variation);
|
|
25
|
-
const requestInit = {
|
|
26
|
-
...init,
|
|
27
|
-
agent: this.agentConfig,
|
|
28
|
-
};
|
|
29
24
|
const uuid = randomUUID();
|
|
30
25
|
this.cli.startAction(`DOCUMENTHANDLER:FETCH:${uuid}`, `[documentHandler:fetch]: ${url}`);
|
|
31
|
-
const fetchResponse = await safe(
|
|
26
|
+
const fetchResponse = await safe(originFetch(url, init));
|
|
32
27
|
if (fetchResponse.success === true) {
|
|
33
28
|
this.cli.successAction(`DOCUMENTHANDLER:FETCH:${uuid}`);
|
|
34
29
|
return { response: fetchResponse.data, url };
|
|
@@ -79,8 +74,9 @@ export class Crawler {
|
|
|
79
74
|
return { url: resolved.url, init };
|
|
80
75
|
}
|
|
81
76
|
prepareAuthRequest(originUrl) {
|
|
82
|
-
|
|
83
|
-
|
|
77
|
+
// A missing `authentications` has to leave through the same door as an empty one. Comparing
|
|
78
|
+
// `undefined < 1` yields false, so the previous guard fell through and iterated undefined.
|
|
79
|
+
if (!this.speedKitServerConfig?.speedKit?.authentications?.length) {
|
|
84
80
|
return;
|
|
85
81
|
}
|
|
86
82
|
const origin = new URL(originUrl).origin;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { expect } from "chai";
|
|
2
|
+
import { describe, beforeEach, afterEach, it } from "mocha";
|
|
3
|
+
import http from "node:http";
|
|
4
|
+
import { Crawler } from "./crawler.js";
|
|
5
|
+
/** Records the lines the crawler reports, so a spec can assert on them. */
|
|
6
|
+
function stubCli() {
|
|
7
|
+
const warnings = [];
|
|
8
|
+
const errors = [];
|
|
9
|
+
const actions = [];
|
|
10
|
+
return {
|
|
11
|
+
warnings,
|
|
12
|
+
errors,
|
|
13
|
+
actions,
|
|
14
|
+
cli: {
|
|
15
|
+
startAction: (name) => actions.push(name),
|
|
16
|
+
successAction: (name) => actions.push(`${name}:ok`),
|
|
17
|
+
failAction: (name) => actions.push(`${name}:fail`),
|
|
18
|
+
writeWarning: (message) => warnings.push(message),
|
|
19
|
+
writeError: (message) => errors.push(message),
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
describe("Crawler.fetchRemote", () => {
|
|
24
|
+
let server;
|
|
25
|
+
let url;
|
|
26
|
+
beforeEach(async () => {
|
|
27
|
+
server = http.createServer((_request, response) => response.end("origin"));
|
|
28
|
+
await new Promise((resolve) => server.listen(0, "127.0.0.1", resolve));
|
|
29
|
+
url = `http://127.0.0.1:${server.address().port}/`;
|
|
30
|
+
});
|
|
31
|
+
afterEach(() => server.close());
|
|
32
|
+
it("fetches an origin whose runtime config carries no authentications", async () => {
|
|
33
|
+
const { cli } = stubCli();
|
|
34
|
+
// The config API omits the key for an app without origin auth. Comparing `undefined < 1`
|
|
35
|
+
// yielded false, so the crawler used to iterate undefined and throw on every fetch.
|
|
36
|
+
const serverConfig = {
|
|
37
|
+
speedKit: { variations: { "*": { headers: {} } } },
|
|
38
|
+
};
|
|
39
|
+
const result = await new Crawler(cli, serverConfig).fetchRemote(url, "DEFAULT");
|
|
40
|
+
expect(result).to.not.equal(undefined);
|
|
41
|
+
expect(await result.response.text()).to.equal("origin");
|
|
42
|
+
});
|
|
43
|
+
it("fetches an origin when no runtime config loaded at all", async () => {
|
|
44
|
+
const { cli, warnings } = stubCli();
|
|
45
|
+
const result = await new Crawler(cli, undefined).fetchRemote(url, "DEFAULT");
|
|
46
|
+
expect(await result.response.text()).to.equal("origin");
|
|
47
|
+
expect(warnings.join(" ")).to.contain("no variations available");
|
|
48
|
+
});
|
|
49
|
+
});
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { CliServiceFactory } from "../cli/index.js";
|
|
2
2
|
import { ConfigApiContext, ConfigApiServiceFactory, } from "../config-api/index.js";
|
|
3
3
|
import { IntegrationApiContext, IntegrationApiFactory, } from "../integration-api/index.js";
|
|
4
|
+
import { applyOriginProxy } from "../../helpers/origin-proxy.js";
|
|
4
5
|
import { OriginRequestService } from "./origin-request-service.js";
|
|
5
6
|
export class OriginRequestServiceFactory {
|
|
6
7
|
context;
|
|
@@ -19,7 +20,10 @@ export class OriginRequestServiceFactory {
|
|
|
19
20
|
async build() {
|
|
20
21
|
const files = await this.getIntegrationFiles();
|
|
21
22
|
const customer = files.getCustomerConfig().config;
|
|
22
|
-
|
|
23
|
+
const cli = new CliServiceFactory().getService();
|
|
24
|
+
// `--json` owns stdout, so the proxy line stays out of a machine-readable run.
|
|
25
|
+
applyOriginProxy(customer.chromeFlags, this.context.json ? undefined : cli);
|
|
26
|
+
this.service = new OriginRequestService(this.context, cli, this.getConfigApi(customer.app));
|
|
23
27
|
}
|
|
24
28
|
async getIntegrationFiles() {
|
|
25
29
|
const integrationApiContext = new IntegrationApiContext(this.context.customerPath, this.context.configName, []);
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { readFile, writeFile } from "node:fs/promises";
|
|
2
2
|
import { safe } from "../../helpers/safe.js";
|
|
3
|
+
import { originFetch } from "../../helpers/origin-proxy.js";
|
|
3
4
|
import { DEFAULT_TYPE, resolveRequest, toCurl, UndefinedVariationError, } from "./asset-variations.js";
|
|
4
5
|
/**
|
|
5
6
|
* Fetches a page from origin with exactly the headers Speed Kit's server would send for a cache
|
|
@@ -43,7 +44,7 @@ export class OriginRequestService {
|
|
|
43
44
|
}
|
|
44
45
|
throw error;
|
|
45
46
|
}
|
|
46
|
-
const response = await
|
|
47
|
+
const response = await originFetch(resolved.url, {
|
|
47
48
|
headers: resolved.headers,
|
|
48
49
|
redirect: "manual",
|
|
49
50
|
});
|
package/oclif.manifest.json
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@speedkit/cli",
|
|
3
3
|
"description": "Speed Kit CLI",
|
|
4
|
-
"version": "4.
|
|
4
|
+
"version": "4.24.0",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Baqend.com",
|
|
7
7
|
"email": "info@baqend.com"
|
|
@@ -124,6 +124,7 @@
|
|
|
124
124
|
"strip-comments": "^2.0.1",
|
|
125
125
|
"tsx": "^4.21.0",
|
|
126
126
|
"tty-table": "^5.0.0",
|
|
127
|
+
"undici": "^8.1.0",
|
|
127
128
|
"uuid": "^13.0.0"
|
|
128
129
|
},
|
|
129
130
|
"devDependencies": {
|