@speedkit/cli 2.69.1 → 2.70.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/README.md +2 -2
- package/dist/services/prewarm/assets/asset-api-client.d.ts +16 -0
- package/dist/services/prewarm/assets/asset-api-client.js +31 -4
- package/dist/services/prewarm/pre-warm-model.d.ts +1 -0
- package/dist/services/prewarm/pre-warm-model.js +3 -2
- package/dist/templates/speedKit.Revalidated.js +43 -36
- package/oclif.manifest.json +1 -1
- package/package.json +6 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
## [2.70.1](https://gitlab.orestes.info/baqend/speed-kit-cli/compare/v2.70.0...v2.70.1) (2024-12-12)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* **prewarm:** set variationString in correct case ([627959d](https://gitlab.orestes.info/baqend/speed-kit-cli/commit/627959d1d997601840c13a679a304b573c985e6f))
|
|
7
|
+
|
|
8
|
+
# [2.70.0](https://gitlab.orestes.info/baqend/speed-kit-cli/compare/v2.69.1...v2.70.0) (2024-12-12)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Features
|
|
12
|
+
|
|
13
|
+
* prepare CLI to support dictionary compression [@edge](https://gitlab.orestes.info/edge) ([c7c4353](https://gitlab.orestes.info/baqend/speed-kit-cli/commit/c7c4353ca48dcaf00af481b98c329f37768c0aea))
|
|
14
|
+
|
|
1
15
|
## [2.69.1](https://gitlab.orestes.info/baqend/speed-kit-cli/compare/v2.69.0...v2.69.1) (2024-12-11)
|
|
2
16
|
|
|
3
17
|
|
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.
|
|
24
|
+
@speedkit/cli/2.70.1 linux-x64 node-v20.18.1
|
|
25
25
|
$ sk --help [COMMAND]
|
|
26
26
|
USAGE
|
|
27
27
|
$ sk COMMAND
|
|
@@ -353,7 +353,7 @@ DESCRIPTION
|
|
|
353
353
|
Display help for sk.
|
|
354
354
|
```
|
|
355
355
|
|
|
356
|
-
_See code: [@oclif/plugin-help](https://github.com/oclif/plugin-help/blob/v6.2.
|
|
356
|
+
_See code: [@oclif/plugin-help](https://github.com/oclif/plugin-help/blob/v6.2.19/src/commands/help.ts)_
|
|
357
357
|
|
|
358
358
|
## `sk login [APP]`
|
|
359
359
|
|
|
@@ -14,4 +14,20 @@ export declare class AssetApiClient {
|
|
|
14
14
|
increaseMaxRequestsPerSecond(): void;
|
|
15
15
|
private isValidUrl;
|
|
16
16
|
private setRateLimit;
|
|
17
|
+
/**
|
|
18
|
+
* handle parameter "bqvariation"
|
|
19
|
+
* reflect behaviour of SpeedKit.
|
|
20
|
+
* - do not send default variation
|
|
21
|
+
* - send mobile/tablet/tv as lowercase
|
|
22
|
+
* - send customVariations as they are
|
|
23
|
+
*
|
|
24
|
+
* As orestes will always make variations uppercase and does not care for caseSensitivity,
|
|
25
|
+
* a caseMissMatch on fastly will also resolve in a cacheMiss.
|
|
26
|
+
* That is why we need to preWarm in the correct case always.
|
|
27
|
+
*
|
|
28
|
+
* @param variation
|
|
29
|
+
* @param assetUrl
|
|
30
|
+
* @private
|
|
31
|
+
*/
|
|
32
|
+
private setVariationParameter;
|
|
17
33
|
}
|
|
@@ -27,16 +27,15 @@ class AssetApiClient {
|
|
|
27
27
|
async fetchURL(url, variation) {
|
|
28
28
|
this.isValidUrl(url);
|
|
29
29
|
const assetUrl = new node_url_1.URL((0, normalize_1.normalize)(url, this.sortParameters));
|
|
30
|
-
|
|
31
|
-
assetUrl.searchParams.set("bqvariation", variation.toLowerCase());
|
|
32
|
-
}
|
|
30
|
+
this.setVariationParameter(variation, assetUrl);
|
|
33
31
|
assetUrl.searchParams.set("bqpass", "1");
|
|
34
32
|
return (0, node_fetch_1.default)(`https://${this.app}.app.baqend.com/v1/asset/${assetUrl.toString()}`, {
|
|
35
33
|
agent: this.agent,
|
|
36
34
|
headers: {
|
|
37
|
-
"Accept-Encoding": "gzip, deflate, br",
|
|
35
|
+
"Accept-Encoding": "gzip, deflate, br, dcb",
|
|
38
36
|
Origin: assetUrl.origin,
|
|
39
37
|
authorization: `BAT ${this.authenticationToken}`,
|
|
38
|
+
"baqend-choose-dictionary": "1",
|
|
40
39
|
},
|
|
41
40
|
method: "HEAD",
|
|
42
41
|
});
|
|
@@ -67,5 +66,33 @@ class AssetApiClient {
|
|
|
67
66
|
setRateLimit(limit) {
|
|
68
67
|
this.rateLimit = limit > 1 ? Math.floor(limit) : 1;
|
|
69
68
|
}
|
|
69
|
+
/**
|
|
70
|
+
* handle parameter "bqvariation"
|
|
71
|
+
* reflect behaviour of SpeedKit.
|
|
72
|
+
* - do not send default variation
|
|
73
|
+
* - send mobile/tablet/tv as lowercase
|
|
74
|
+
* - send customVariations as they are
|
|
75
|
+
*
|
|
76
|
+
* As orestes will always make variations uppercase and does not care for caseSensitivity,
|
|
77
|
+
* a caseMissMatch on fastly will also resolve in a cacheMiss.
|
|
78
|
+
* That is why we need to preWarm in the correct case always.
|
|
79
|
+
*
|
|
80
|
+
* @param variation
|
|
81
|
+
* @param assetUrl
|
|
82
|
+
* @private
|
|
83
|
+
*/
|
|
84
|
+
setVariationParameter(variation, assetUrl) {
|
|
85
|
+
// on default or desktop do net set variationParam
|
|
86
|
+
if (variation === "default" || variation === "desktop") {
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
// on tv|tablet|mobile set variation as lowerCase
|
|
90
|
+
if (__1.DEFAULT_VARIATIONS.includes(variation.toLowerCase())) {
|
|
91
|
+
assetUrl.searchParams.set("bqvariation", variation.toLowerCase());
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
// on any other customVariation set variation as it is
|
|
95
|
+
assetUrl.searchParams.set("bqvariation", variation);
|
|
96
|
+
}
|
|
70
97
|
}
|
|
71
98
|
exports.AssetApiClient = AssetApiClient;
|
|
@@ -37,3 +37,4 @@ export declare const TIMING_HEADER_KEY = "server-timing";
|
|
|
37
37
|
export declare const PROGRESS_BAR_FORMAT = "[{bar}] {percentage}% | ETA: {eta}s | {value}/{total} | error:{errors} | rate: {rate} | retry: {retry}";
|
|
38
38
|
export declare const VARIATION_SEPARATOR = ",";
|
|
39
39
|
export declare const DEFAULT_VARIATION: string[];
|
|
40
|
+
export declare const DEFAULT_VARIATIONS: string[];
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.DEFAULT_VARIATION = exports.VARIATION_SEPARATOR = exports.PROGRESS_BAR_FORMAT = exports.TIMING_HEADER_KEY = exports.TIMING_HEADER_ERROR_CODE_SELECTOR = exports.RATE_LIMIT_CODES = exports.RATE_LIMIT_MULTIPLICATOR = exports.MAX_REQUESTS_PER_SECOND = exports.DEFAULT_REQUESTS_PER_SECOND = exports.TIMOUT_AFTER_DETECTED_RATE_LIMIT = exports.FETCH_TIMEOUT = exports.MIN_TIME_TO_FETCH_BATCH = exports.ItemStatus = exports.PreWarmContext = void 0;
|
|
3
|
+
exports.DEFAULT_VARIATIONS = exports.DEFAULT_VARIATION = exports.VARIATION_SEPARATOR = exports.PROGRESS_BAR_FORMAT = exports.TIMING_HEADER_KEY = exports.TIMING_HEADER_ERROR_CODE_SELECTOR = exports.RATE_LIMIT_CODES = exports.RATE_LIMIT_MULTIPLICATOR = exports.MAX_REQUESTS_PER_SECOND = exports.DEFAULT_REQUESTS_PER_SECOND = exports.TIMOUT_AFTER_DETECTED_RATE_LIMIT = exports.FETCH_TIMEOUT = exports.MIN_TIME_TO_FETCH_BATCH = exports.ItemStatus = exports.PreWarmContext = void 0;
|
|
4
4
|
class PreWarmContext {
|
|
5
5
|
app;
|
|
6
6
|
path;
|
|
@@ -36,4 +36,5 @@ exports.TIMING_HEADER_ERROR_CODE_SELECTOR = /errorcode;desc=([^,]*),/;
|
|
|
36
36
|
exports.TIMING_HEADER_KEY = "server-timing";
|
|
37
37
|
exports.PROGRESS_BAR_FORMAT = "[{bar}] {percentage}% | ETA: {eta}s | {value}/{total} | error:{errors} | rate: {rate} | retry: {retry}";
|
|
38
38
|
exports.VARIATION_SEPARATOR = ",";
|
|
39
|
-
exports.DEFAULT_VARIATION = ["
|
|
39
|
+
exports.DEFAULT_VARIATION = ["default"];
|
|
40
|
+
exports.DEFAULT_VARIATIONS = ["mobile", "tablet", "tv"];
|
|
@@ -1,48 +1,54 @@
|
|
|
1
|
-
const fetch = require(
|
|
2
|
-
const https = require(
|
|
1
|
+
const fetch = require("node-fetch");
|
|
2
|
+
const https = require("node:https");
|
|
3
3
|
|
|
4
4
|
/* global Abort, ORIGIN_POPS */
|
|
5
5
|
|
|
6
|
-
const agent = new https.Agent({rejectUnauthorized: false})
|
|
6
|
+
const agent = new https.Agent({ rejectUnauthorized: false });
|
|
7
7
|
|
|
8
8
|
{{config}} // eslint-disable-line
|
|
9
9
|
|
|
10
|
-
const ORIGIN_PATHS = Object.keys(ORIGIN_POPS).filter(origin =>
|
|
10
|
+
const ORIGIN_PATHS = Object.keys(ORIGIN_POPS).filter((origin) =>
|
|
11
|
+
origin.endsWith("/"),
|
|
12
|
+
);
|
|
11
13
|
|
|
12
|
-
const fetchURL = async (ip, url, origin, variation,
|
|
13
|
-
if (variation && variation !==
|
|
14
|
-
url =
|
|
14
|
+
const fetchURL = async (ip, url, origin, variation, database) => {
|
|
15
|
+
if (variation && variation !== "DEFAULT") {
|
|
16
|
+
url =
|
|
17
|
+
url +
|
|
18
|
+
(url.includes("?") ? "&" : "?") +
|
|
19
|
+
`bqvariation=${variation.toLowerCase()}`;
|
|
15
20
|
}
|
|
16
21
|
|
|
17
|
-
const app =
|
|
22
|
+
const app = database.connection.host;
|
|
18
23
|
try {
|
|
19
24
|
await fetch(`https://${ip}/v1/asset/${url}`, {
|
|
20
25
|
agent,
|
|
21
26
|
headers: {
|
|
22
|
-
|
|
27
|
+
"Accept-Encoding": "gzip, deflate, br, dcb",
|
|
23
28
|
Host: `${app}.app.baqend.com`,
|
|
24
29
|
Origin: origin,
|
|
25
|
-
authorization: `BAT ${
|
|
26
|
-
|
|
30
|
+
authorization: `BAT ${database.token}`,
|
|
31
|
+
"baqend-prewarm": "1",
|
|
32
|
+
"baqend-choose-dictionary": "1",
|
|
27
33
|
},
|
|
28
|
-
method:
|
|
34
|
+
method: "HEAD",
|
|
29
35
|
timeout: 3000,
|
|
30
|
-
})
|
|
36
|
+
});
|
|
31
37
|
} catch (error) {
|
|
32
|
-
console.log(`error fetching https://${ip}/v1/asset/${url}`, error)
|
|
38
|
+
console.log(`error fetching https://${ip}/v1/asset/${url}`, error);
|
|
33
39
|
}
|
|
34
|
-
}
|
|
40
|
+
};
|
|
35
41
|
|
|
36
|
-
const fetchAssets = async (ip, assets,
|
|
37
|
-
const fetches = []
|
|
42
|
+
const fetchAssets = async (ip, assets, database) => {
|
|
43
|
+
const fetches = [];
|
|
38
44
|
for (const asset of assets) {
|
|
39
|
-
let {extendedURL, origin, url, variation} = asset
|
|
40
|
-
url +=
|
|
41
|
-
fetches.push(fetchURL(ip, url, origin, variation,
|
|
45
|
+
let { extendedURL, origin, url, variation } = asset;
|
|
46
|
+
url += extendedURL || "";
|
|
47
|
+
fetches.push(fetchURL(ip, url, origin, variation, database));
|
|
42
48
|
}
|
|
43
49
|
|
|
44
|
-
await Promise.all(fetches)
|
|
45
|
-
}
|
|
50
|
+
await Promise.all(fetches);
|
|
51
|
+
};
|
|
46
52
|
|
|
47
53
|
/**
|
|
48
54
|
*
|
|
@@ -50,37 +56,38 @@ const fetchAssets = async (ip, assets, db) => {
|
|
|
50
56
|
* @param {Array<{ extendedURL: string, origin: string, url: string, variation: string }>} assets - list of assets to prewar
|
|
51
57
|
* @return {Promise<void>}
|
|
52
58
|
*/
|
|
53
|
-
exports.call = async (
|
|
54
|
-
if (!
|
|
55
|
-
throw new Abort(
|
|
59
|
+
exports.call = async (database, assets) => {
|
|
60
|
+
if (!database.User.me || database.User.me.key !== "1") {
|
|
61
|
+
throw new Abort("Not logged in.");
|
|
56
62
|
}
|
|
57
63
|
|
|
58
|
-
const originBuckets = {}
|
|
64
|
+
const originBuckets = {};
|
|
59
65
|
for (const asset of assets) {
|
|
60
|
-
let bucket =
|
|
66
|
+
let bucket = "DEFAULT";
|
|
61
67
|
|
|
62
68
|
if (ORIGIN_POPS[asset.origin]) {
|
|
63
|
-
bucket = asset.origin
|
|
69
|
+
bucket = asset.origin;
|
|
64
70
|
}
|
|
65
71
|
|
|
66
72
|
// if there is a path specific prewarm list, overwrite the default prewarm list.
|
|
67
|
-
const path = ORIGIN_PATHS.find(path => asset.url.startsWith(path))
|
|
73
|
+
const path = ORIGIN_PATHS.find((path) => asset.url.startsWith(path));
|
|
68
74
|
if (path) {
|
|
69
|
-
bucket = path
|
|
75
|
+
bucket = path;
|
|
70
76
|
}
|
|
71
77
|
|
|
72
|
-
originBuckets[bucket] = originBuckets[bucket] || []
|
|
73
|
-
originBuckets[bucket].push(asset)
|
|
78
|
+
originBuckets[bucket] = originBuckets[bucket] || [];
|
|
79
|
+
originBuckets[bucket].push(asset);
|
|
74
80
|
}
|
|
75
81
|
|
|
76
82
|
// wait for fastly purge
|
|
77
83
|
setTimeout(async () => {
|
|
78
84
|
for (const bucket of Object.keys(originBuckets)) {
|
|
79
85
|
for (const pop of ORIGIN_POPS[bucket]) {
|
|
80
|
-
if (pop) {
|
|
81
|
-
|
|
86
|
+
if (pop) {
|
|
87
|
+
// prevent np when the pop is not defined
|
|
88
|
+
await fetchAssets(pop, originBuckets[bucket], database);
|
|
82
89
|
}
|
|
83
90
|
}
|
|
84
91
|
}
|
|
85
|
-
}, 5000)
|
|
86
|
-
}
|
|
92
|
+
}, 5000);
|
|
93
|
+
};
|
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": "2.
|
|
4
|
+
"version": "2.70.1",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Baqend.com",
|
|
7
7
|
"email": "info@baqend.com"
|
|
@@ -69,9 +69,9 @@
|
|
|
69
69
|
"@inquirer/prompts": "^3.3.2",
|
|
70
70
|
"@oclif/core": "^3.23",
|
|
71
71
|
"@oclif/plugin-autocomplete": "^3.0",
|
|
72
|
-
"@oclif/plugin-help": "^6.2.
|
|
73
|
-
"@oclif/plugin-not-found": "^3.2.
|
|
74
|
-
"@oclif/plugin-warn-if-update-available": "^3.1.
|
|
72
|
+
"@oclif/plugin-help": "^6.2.19",
|
|
73
|
+
"@oclif/plugin-not-found": "^3.2.30",
|
|
74
|
+
"@oclif/plugin-warn-if-update-available": "^3.1.26",
|
|
75
75
|
"baqend": "^4.1.0",
|
|
76
76
|
"chalk": "^4.1.2",
|
|
77
77
|
"clipboardy-cjs": "^3.0.0",
|
|
@@ -81,7 +81,7 @@
|
|
|
81
81
|
"dom-serializer": "2.0.0",
|
|
82
82
|
"domhandler": "5.0.3",
|
|
83
83
|
"domutils": "^3.1",
|
|
84
|
-
"dotenv": "^16.4.
|
|
84
|
+
"dotenv": "^16.4.7",
|
|
85
85
|
"extract-zip": "^2.0.1",
|
|
86
86
|
"fs-extra": "^11.2.0",
|
|
87
87
|
"handlebars": "^4.7.8",
|
|
@@ -123,7 +123,7 @@
|
|
|
123
123
|
"mocha": "^10.1.0",
|
|
124
124
|
"mocha-junit-reporter": "^2.2.1",
|
|
125
125
|
"mock-fs": "^5.2.0",
|
|
126
|
-
"nock": "^13.5.
|
|
126
|
+
"nock": "^13.5.6",
|
|
127
127
|
"nyc": "^15.1.0",
|
|
128
128
|
"oclif": "^4.8.8",
|
|
129
129
|
"shx": "^0.3.4",
|