@speedkit/cli 2.12.0 → 2.14.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 +1 -1
- package/dist/commands/document-handler.d.ts +1 -1
- package/dist/commands/document-handler.js +4 -4
- package/dist/commands/find-pops.d.ts +1 -1
- package/dist/commands/find-pops.js +21 -18
- package/dist/commands/login.d.ts +1 -1
- package/dist/commands/login.js +4 -4
- package/dist/commands/onboarding.d.ts +1 -1
- package/dist/commands/onboarding.js +12 -4
- package/dist/commands/param-diff.d.ts +2 -2
- package/dist/commands/param-diff.js +16 -16
- package/dist/commands/pop-prewarm.d.ts +2 -2
- package/dist/commands/pop-prewarm.js +20 -13
- package/dist/commands/prewarm.d.ts +2 -2
- package/dist/commands/prewarm.js +35 -19
- package/dist/commands/pull.d.ts +1 -1
- package/dist/commands/pull.js +2 -2
- package/dist/commands/wpt-launcher.d.ts +2 -2
- package/dist/commands/wpt-launcher.js +35 -19
- package/dist/helpers/CustomerConfig.d.ts +1 -1
- package/dist/helpers/CustomerConfig.js +36 -35
- package/dist/helpers/file-helper.js +6 -6
- package/dist/services/athena-service.js +16 -12
- package/dist/services/config-api-service.d.ts +3 -3
- package/dist/services/config-api-service.js +29 -17
- package/dist/services/diff/diff-service.js +26 -18
- package/dist/services/diff/index.d.ts +3 -3
- package/dist/services/diff-service.d.ts +1 -1
- package/dist/services/diff-service.js +12 -12
- package/dist/services/onboarding/config-renderer/speed-kit-install-context.d.ts +1 -1
- package/dist/services/onboarding/config-renderer/speed-kit-install-context.js +20 -20
- package/dist/services/pull/index.d.ts +3 -3
- package/dist/services/pull/pull-service-model.js +13 -10
- package/dist/services/pull/pull-service.js +12 -6
- package/oclif.manifest.json +1 -1
- package/package.json +1 -1
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
3
4
|
const core_1 = require("@oclif/core");
|
|
4
5
|
const core_2 = require("@oclif/core");
|
|
6
|
+
const node_fetch_1 = tslib_1.__importDefault(require("node-fetch"));
|
|
5
7
|
const cli_parameters_1 = require("../models/cli-parameters");
|
|
6
8
|
const logging_helper_1 = require("../helpers/logging-helper");
|
|
7
|
-
const fetch = require('node-fetch');
|
|
8
9
|
class WptLauncher extends core_1.Command {
|
|
9
|
-
static description =
|
|
10
|
+
static description = "Analyze the performance impact that Speed Kit has compared to the original version.";
|
|
10
11
|
static args = {
|
|
11
12
|
[cli_parameters_1.CLIParameters.Urls]: core_1.Args.string({
|
|
12
13
|
name: cli_parameters_1.CLIParameters.Urls, // name of arg to show in help and reference with args[name]
|
|
@@ -18,17 +19,26 @@ class WptLauncher extends core_1.Command {
|
|
|
18
19
|
}),
|
|
19
20
|
};
|
|
20
21
|
static flags = {
|
|
21
|
-
[cli_parameters_1.CLIParameters.Cookies]: core_1.Flags.string({
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
[cli_parameters_1.CLIParameters.Cookies]: core_1.Flags.string({
|
|
23
|
+
default: "",
|
|
24
|
+
char: cli_parameters_1.CLIParametersChar.Cookies,
|
|
25
|
+
}),
|
|
26
|
+
[cli_parameters_1.CLIParameters.Mobile]: core_1.Flags.string({
|
|
27
|
+
default: "no",
|
|
28
|
+
char: cli_parameters_1.CLIParametersChar.Mobile,
|
|
29
|
+
}),
|
|
30
|
+
[cli_parameters_1.CLIParameters.Group]: core_1.Flags.string({
|
|
31
|
+
default: "A",
|
|
32
|
+
char: cli_parameters_1.CLIParametersChar.Group,
|
|
33
|
+
}),
|
|
24
34
|
};
|
|
25
35
|
static examples = [
|
|
26
36
|
`$ sk wpt-launcher <${cli_parameters_1.CLIParameters.Urls}> <${cli_parameters_1.CLIParameters.TestId}> -${cli_parameters_1.CLIParametersChar.Group} <${cli_parameters_1.CLIParameters.Group}> -${cli_parameters_1.CLIParametersChar.Mobile} <${cli_parameters_1.CLIParameters.Mobile}> -${cli_parameters_1.CLIParametersChar.Cookies} <${cli_parameters_1.CLIParameters.Cookies}>`,
|
|
27
37
|
`$ sk wpt-launcher ${cli_parameters_1.CLIParametersExample.Urls} ${cli_parameters_1.CLIParametersExample.TestId} -${cli_parameters_1.CLIParametersChar.Group} ${cli_parameters_1.CLIParametersExample.Group} -${cli_parameters_1.CLIParametersChar.Mobile} ${cli_parameters_1.CLIParametersExample.Mobile} -${cli_parameters_1.CLIParametersChar.Cookies} ${cli_parameters_1.CLIParametersExample.Cookies}`,
|
|
28
38
|
];
|
|
29
|
-
static localhostUrl =
|
|
39
|
+
static localhostUrl = "http://localhost:8888/orange.html";
|
|
30
40
|
async run() {
|
|
31
|
-
const { args: { urls, testId }, flags: { group, mobile, cookies } } = await this.parse(WptLauncher);
|
|
41
|
+
const { args: { urls, testId }, flags: { group, mobile, cookies }, } = await this.parse(WptLauncher);
|
|
32
42
|
const resourceOrigin = this.getResourceOrigin(this.allResourceUrls(urls));
|
|
33
43
|
let script = `setViewportSize ${this.getViewPortSize(this.isMobile(mobile))}
|
|
34
44
|
navigate ${resourceOrigin}/wrapper-sw.js
|
|
@@ -36,43 +46,49 @@ class WptLauncher extends core_1.Command {
|
|
|
36
46
|
exec localStorage.setItem('baqend-speedkit-ab-test-info', encodeURIComponent(JSON.stringify({group:${group},testId:${testId})));
|
|
37
47
|
navigate ${resourceOrigin}
|
|
38
48
|
navigate ${WptLauncher.localhostUrl}`;
|
|
39
|
-
this.allResourceUrls(urls).forEach(url => {
|
|
49
|
+
this.allResourceUrls(urls).forEach((url) => {
|
|
40
50
|
script += `\n navigate ${url}`;
|
|
41
51
|
});
|
|
42
|
-
const postscript = await this.postScript(script);
|
|
52
|
+
const postscript = (await this.postScript(script));
|
|
43
53
|
const currentTestIdUrl = `http://wpt.baqend.com/results.php?test=${postscript.wptTestId}`;
|
|
44
54
|
if (!currentTestIdUrl) {
|
|
45
|
-
(0, logging_helper_1.logError)(
|
|
55
|
+
(0, logging_helper_1.logError)("Getting testId failed, " + currentTestIdUrl);
|
|
46
56
|
core_2.ux.exit(1);
|
|
47
57
|
}
|
|
48
|
-
this.log(
|
|
58
|
+
this.log("testUrl: ", currentTestIdUrl);
|
|
49
59
|
core_2.ux.exit(0);
|
|
50
60
|
}
|
|
51
61
|
// ---------------------- services----------------
|
|
52
62
|
isMobile(mobile) {
|
|
53
|
-
return mobile ===
|
|
63
|
+
return (mobile === "y" ||
|
|
64
|
+
mobile === "Y" ||
|
|
65
|
+
mobile === "yes" ||
|
|
66
|
+
mobile === "Yes" ||
|
|
67
|
+
mobile === "YES");
|
|
54
68
|
}
|
|
55
69
|
getViewPortSize(isMobile) {
|
|
56
70
|
if (isMobile) {
|
|
57
|
-
return
|
|
71
|
+
return "375 667"; // mobile
|
|
58
72
|
}
|
|
59
|
-
return
|
|
73
|
+
return "1500 1300"; // desktop
|
|
60
74
|
}
|
|
61
75
|
allResourceUrls(urls) {
|
|
62
|
-
const urlsArr = urls.split(
|
|
76
|
+
const urlsArr = urls.split(",");
|
|
63
77
|
if (urlsArr.length > 0) {
|
|
64
78
|
return urlsArr;
|
|
65
79
|
}
|
|
66
|
-
|
|
67
|
-
throw new Error('urls must not be null');
|
|
80
|
+
throw new Error("urls must not be null");
|
|
68
81
|
}
|
|
69
82
|
getResourceOrigin(urlsArr) {
|
|
70
83
|
return new URL(urlsArr[0]).origin;
|
|
71
84
|
}
|
|
72
85
|
// ---------------- wpt launcher --------------------------
|
|
73
86
|
async postScript(script) {
|
|
74
|
-
const urlPath =
|
|
75
|
-
const res = await
|
|
87
|
+
const urlPath = "https://makefast.app.baqend.com/v1/code/testAPI";
|
|
88
|
+
const res = await (0, node_fetch_1.default)(urlPath, {
|
|
89
|
+
body: JSON.stringify({ script }),
|
|
90
|
+
method: "POST",
|
|
91
|
+
});
|
|
76
92
|
return res.json();
|
|
77
93
|
}
|
|
78
94
|
}
|
|
@@ -6,17 +6,17 @@ const path_1 = tslib_1.__importDefault(require("path"));
|
|
|
6
6
|
const isFile_1 = require("./isFile");
|
|
7
7
|
const promises_1 = require("fs/promises");
|
|
8
8
|
const logging_helper_1 = require("./logging-helper");
|
|
9
|
-
exports.SPEED_KIT_INSTALL_PATH =
|
|
10
|
-
const CUSTOMER_CONFIG_BASENAME =
|
|
11
|
-
const SK_CONFIG =
|
|
12
|
-
const RUM_CONFIG =
|
|
13
|
-
const DF_CONFIG =
|
|
14
|
-
const DF_STYLES_BASENAME =
|
|
15
|
-
const DOCUMENT_HANDLER_CONFIG =
|
|
16
|
-
const CUSTOM_LOADER =
|
|
17
|
-
const CUSTOM_SERVICE_WORKER =
|
|
18
|
-
const CUSTOM_DOCUMENT_HANDLER =
|
|
19
|
-
const CUSTOM_DYNAMIC_FETCHER =
|
|
9
|
+
exports.SPEED_KIT_INSTALL_PATH = "/speed-kit-install.js";
|
|
10
|
+
const CUSTOMER_CONFIG_BASENAME = "config_customer.js";
|
|
11
|
+
const SK_CONFIG = "config_SpeedKit.js";
|
|
12
|
+
const RUM_CONFIG = "config_loadHandler.js";
|
|
13
|
+
const DF_CONFIG = "config_dynamicBlocks.js";
|
|
14
|
+
const DF_STYLES_BASENAME = "config_dynamicStyles.css";
|
|
15
|
+
const DOCUMENT_HANDLER_CONFIG = "config_documentHandler.js";
|
|
16
|
+
const CUSTOM_LOADER = "custom_loader.js";
|
|
17
|
+
const CUSTOM_SERVICE_WORKER = "custom_sw.js";
|
|
18
|
+
const CUSTOM_DOCUMENT_HANDLER = "custom_documentHandler.js";
|
|
19
|
+
const CUSTOM_DYNAMIC_FETCHER = "custom_dynamicFetcher.js";
|
|
20
20
|
exports.INSTALLATION_PROPERTIES = {
|
|
21
21
|
config: SK_CONFIG,
|
|
22
22
|
custom: RUM_CONFIG,
|
|
@@ -38,16 +38,16 @@ function optional(check, params, name, defaultValue = null) {
|
|
|
38
38
|
if (check(params[name])) {
|
|
39
39
|
return params[name];
|
|
40
40
|
}
|
|
41
|
-
if (typeof params[name] ===
|
|
41
|
+
if (typeof params[name] === "undefined" || params[name] === null) {
|
|
42
42
|
return defaultValue;
|
|
43
43
|
}
|
|
44
44
|
throw new TypeError(`Property "${name}" must be a ${check.name.substring(2)}.`);
|
|
45
45
|
}
|
|
46
46
|
function isString(value) {
|
|
47
|
-
return typeof value ===
|
|
47
|
+
return typeof value === "string";
|
|
48
48
|
}
|
|
49
49
|
function isBoolean(value) {
|
|
50
|
-
return typeof value ===
|
|
50
|
+
return typeof value === "boolean";
|
|
51
51
|
}
|
|
52
52
|
class CustomerConfig {
|
|
53
53
|
name;
|
|
@@ -79,6 +79,7 @@ class CustomerConfig {
|
|
|
79
79
|
if (!mainConfig) {
|
|
80
80
|
throw new Error(`Could not find customer config file "${CUSTOMER_CONFIG_BASENAME}".`);
|
|
81
81
|
}
|
|
82
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
82
83
|
return require(mainConfig.filePath);
|
|
83
84
|
}
|
|
84
85
|
static async loadCustomer(dir, configName) {
|
|
@@ -88,37 +89,37 @@ class CustomerConfig {
|
|
|
88
89
|
params = customerConfig[configName];
|
|
89
90
|
}
|
|
90
91
|
else {
|
|
91
|
-
(0, logging_helper_1.logWarning)(
|
|
92
|
-
(0, logging_helper_1.logWarning)(
|
|
93
|
-
(0, logging_helper_1.logWarning)(
|
|
92
|
+
(0, logging_helper_1.logWarning)("Use legacy customer config loading format.");
|
|
93
|
+
(0, logging_helper_1.logWarning)("Make sure to export the different app configs under their config names like:");
|
|
94
|
+
(0, logging_helper_1.logWarning)("module.exports = { production, staging }");
|
|
94
95
|
params = customerConfig;
|
|
95
96
|
}
|
|
96
97
|
const configs = {};
|
|
97
98
|
for (const [key, path] of Object.entries(exports.INSTALLATION_PROPERTIES)) {
|
|
98
|
-
configs[key] = await ConfigFile.loadFile(dir, path, path.replace(
|
|
99
|
+
configs[key] = await ConfigFile.loadFile(dir, path, path.replace(".js", ".es6"));
|
|
99
100
|
}
|
|
100
101
|
// Parse config
|
|
101
102
|
return new CustomerConfig({ name: configName, ...params }, {
|
|
102
103
|
...configs,
|
|
103
|
-
popConfig: await ConfigFile.loadFile(dir,
|
|
104
|
-
globalWhitelist: await ConfigFile.loadFile(dir,
|
|
105
|
-
globalBlacklist: await ConfigFile.loadFile(dir,
|
|
104
|
+
popConfig: await ConfigFile.loadFile(dir, "config_pops.js"),
|
|
105
|
+
globalWhitelist: await ConfigFile.loadFile(dir, "../../rules/global-whitelist.js"),
|
|
106
|
+
globalBlacklist: await ConfigFile.loadFile(dir, "../../rules/global-blacklist.js"),
|
|
106
107
|
});
|
|
107
108
|
}
|
|
108
109
|
constructor(params, configFiles) {
|
|
109
|
-
this.domain = required(isString, params,
|
|
110
|
-
this.name = optional(isString, params,
|
|
111
|
-
this.swPath = optional(isString, params,
|
|
112
|
-
this.app = optional(isString, params,
|
|
113
|
-
this.appDomain = optional(isString, params,
|
|
114
|
-
this.chromeFlags = optional(Array.isArray, params,
|
|
115
|
-
this.installPath = optional(isString, params,
|
|
116
|
-
const scope = optional(isString, params,
|
|
117
|
-
this.scope = scope + (scope.endsWith(
|
|
118
|
-
this.origins = optional(Array.isArray, params,
|
|
119
|
-
this.installParams = optional(isString, params,
|
|
120
|
-
this.forceInstall = optional(isBoolean, params,
|
|
121
|
-
this.bypassDeactivation = optional(isBoolean, params,
|
|
110
|
+
this.domain = required(isString, params, "domain");
|
|
111
|
+
this.name = optional(isString, params, "name");
|
|
112
|
+
this.swPath = optional(isString, params, "swPath", "/wrapper-sw.js");
|
|
113
|
+
this.app = optional(isString, params, "app");
|
|
114
|
+
this.appDomain = optional(isString, params, "appDomain", "*.app.baqend.com");
|
|
115
|
+
this.chromeFlags = optional(Array.isArray, params, "chromeFlags", []);
|
|
116
|
+
this.installPath = optional(isString, params, "installPath", exports.SPEED_KIT_INSTALL_PATH);
|
|
117
|
+
const scope = optional(isString, params, "scope", "/");
|
|
118
|
+
this.scope = scope + (scope.endsWith("/") ? "" : "/");
|
|
119
|
+
this.origins = optional(Array.isArray, params, "origins", []);
|
|
120
|
+
this.installParams = optional(isString, params, "installParams", 'async crossorigin="anonymous"');
|
|
121
|
+
this.forceInstall = optional(isBoolean, params, "forceInstall", false);
|
|
122
|
+
this.bypassDeactivation = optional(isBoolean, params, "bypassDeactivation", true);
|
|
122
123
|
// Assign Config Files
|
|
123
124
|
Object.assign(this, configFiles);
|
|
124
125
|
}
|
|
@@ -144,7 +145,7 @@ class ConfigFile {
|
|
|
144
145
|
this.name = name;
|
|
145
146
|
}
|
|
146
147
|
async readContent() {
|
|
147
|
-
return (0, promises_1.readFile)(this.filePath,
|
|
148
|
+
return (0, promises_1.readFile)(this.filePath, "utf-8");
|
|
148
149
|
}
|
|
149
150
|
}
|
|
150
151
|
exports.ConfigFile = ConfigFile;
|
|
@@ -11,19 +11,19 @@ const CustomerConfig_1 = require("./CustomerConfig");
|
|
|
11
11
|
const logging_helper_1 = require("./logging-helper");
|
|
12
12
|
async function createTemporalDir() {
|
|
13
13
|
try {
|
|
14
|
-
return fs.mkdtemp(path.join(os.tmpdir(),
|
|
14
|
+
return fs.mkdtemp(path.join(os.tmpdir(), "speed-kit-cli-"));
|
|
15
15
|
}
|
|
16
16
|
catch (error) {
|
|
17
|
-
console.error(
|
|
17
|
+
console.error("Error creating temp folder", error);
|
|
18
18
|
return null;
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
21
|
exports.createTemporalDir = createTemporalDir;
|
|
22
22
|
async function createEmptyFile() {
|
|
23
23
|
const tempDir = await createTemporalDir();
|
|
24
|
-
const filePath = path.join(tempDir,
|
|
24
|
+
const filePath = path.join(tempDir, "/empty_FilePath.js");
|
|
25
25
|
const writeFilePromise = new Promise((resolve, reject) => {
|
|
26
|
-
fs.writeFile(filePath,
|
|
26
|
+
fs.writeFile(filePath, "No file was found", (err) => {
|
|
27
27
|
if (err) {
|
|
28
28
|
return reject(err);
|
|
29
29
|
}
|
|
@@ -35,7 +35,7 @@ async function createEmptyFile() {
|
|
|
35
35
|
}
|
|
36
36
|
exports.createEmptyFile = createEmptyFile;
|
|
37
37
|
function trimFileExtension(str) {
|
|
38
|
-
return str.replace(
|
|
38
|
+
return str.replace(".js", "").replace(".es6", "");
|
|
39
39
|
}
|
|
40
40
|
exports.trimFileExtension = trimFileExtension;
|
|
41
41
|
async function readLocalFile(basePath, fileName) {
|
|
@@ -52,7 +52,7 @@ exports.readLocalFile = readLocalFile;
|
|
|
52
52
|
* Returns the local path to the sk-onboarding project.
|
|
53
53
|
*/
|
|
54
54
|
function getLocalPath(path) {
|
|
55
|
-
const fullCustomerPath = path_1.default.resolve(path,
|
|
55
|
+
const fullCustomerPath = path_1.default.resolve(path, "");
|
|
56
56
|
// Check if path is a valid path or not
|
|
57
57
|
if (!fs.existsSync(fullCustomerPath)) {
|
|
58
58
|
(0, logging_helper_1.logError)(`The given path: ${fullCustomerPath} is not a valid path`);
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.AthenaService = void 0;
|
|
4
4
|
const client_athena_1 = require("@aws-sdk/client-athena");
|
|
5
5
|
class AthenaService {
|
|
6
|
-
client = new client_athena_1.AthenaClient({ region:
|
|
6
|
+
client = new client_athena_1.AthenaClient({ region: "eu-central-1" });
|
|
7
7
|
async getUsedPopsPerOrigin(app, useRum) {
|
|
8
8
|
const query = `
|
|
9
9
|
with data as (
|
|
@@ -13,7 +13,7 @@ class AthenaService {
|
|
|
13
13
|
from fastly.logs
|
|
14
14
|
where date between ? and ?
|
|
15
15
|
and app = ?
|
|
16
|
-
and ${useRum ?
|
|
16
|
+
and ${useRum ? "ispibeacon" : "isassetrequest and isnavigaterequest"}
|
|
17
17
|
and client.bot is null
|
|
18
18
|
and origin not in('Unknown', '')
|
|
19
19
|
)
|
|
@@ -34,13 +34,13 @@ class AthenaService {
|
|
|
34
34
|
const start = startDate.toISOString().slice(0, 10);
|
|
35
35
|
const end = endDate.toISOString().slice(0, 10);
|
|
36
36
|
const queryId = await this.runQuery(query, [start, end, app], 12 * 60);
|
|
37
|
-
return await this.fetchResult(queryId);
|
|
37
|
+
return (await this.fetchResult(queryId));
|
|
38
38
|
}
|
|
39
39
|
castValueToType(value, type) {
|
|
40
40
|
if (value === null)
|
|
41
41
|
return null;
|
|
42
42
|
switch (type) {
|
|
43
|
-
case
|
|
43
|
+
case "bigint": {
|
|
44
44
|
return Number(value);
|
|
45
45
|
}
|
|
46
46
|
default: {
|
|
@@ -61,10 +61,13 @@ class AthenaService {
|
|
|
61
61
|
do {
|
|
62
62
|
// Max Results can be set but if its not set,
|
|
63
63
|
// it will choose the maximum page size.
|
|
64
|
-
const command = new client_athena_1.GetQueryResultsCommand({
|
|
64
|
+
const command = new client_athena_1.GetQueryResultsCommand({
|
|
65
|
+
NextToken,
|
|
66
|
+
QueryExecutionId: queryId,
|
|
67
|
+
});
|
|
65
68
|
const result = await this.client.send(command);
|
|
66
|
-
const columns = result.ResultSet.ResultSetMetadata.ColumnInfo.map(info => info.Name);
|
|
67
|
-
const types = result.ResultSet.ResultSetMetadata.ColumnInfo.map(info => info.Type);
|
|
69
|
+
const columns = result.ResultSet.ResultSetMetadata.ColumnInfo.map((info) => info.Name);
|
|
70
|
+
const types = result.ResultSet.ResultSetMetadata.ColumnInfo.map((info) => info.Type);
|
|
68
71
|
for (const rowRaw of result.ResultSet.Rows) {
|
|
69
72
|
if (first) {
|
|
70
73
|
first = false;
|
|
@@ -90,11 +93,11 @@ class AthenaService {
|
|
|
90
93
|
* @return The query id which can be used to fetch the query results
|
|
91
94
|
*/
|
|
92
95
|
async runQuery(sql, parameters, useCacheTTLMinutes = 60) {
|
|
93
|
-
const ExecutionParameters = parameters.map(value => typeof value ===
|
|
96
|
+
const ExecutionParameters = parameters.map((value) => typeof value === "string" ? `'${value}'` : String(value));
|
|
94
97
|
const command = new client_athena_1.StartQueryExecutionCommand({
|
|
95
98
|
ExecutionParameters,
|
|
96
99
|
QueryExecutionContext: {
|
|
97
|
-
Catalog:
|
|
100
|
+
Catalog: "live",
|
|
98
101
|
},
|
|
99
102
|
QueryString: sql,
|
|
100
103
|
ResultReuseConfiguration: {
|
|
@@ -109,7 +112,7 @@ class AthenaService {
|
|
|
109
112
|
return response.QueryExecutionId;
|
|
110
113
|
}
|
|
111
114
|
async sleep(sleep) {
|
|
112
|
-
return new Promise(resolve => {
|
|
115
|
+
return new Promise((resolve) => {
|
|
113
116
|
setTimeout(resolve, sleep);
|
|
114
117
|
});
|
|
115
118
|
}
|
|
@@ -120,10 +123,11 @@ class AthenaService {
|
|
|
120
123
|
const status = result.QueryExecution.Status;
|
|
121
124
|
switch (status.State) {
|
|
122
125
|
case client_athena_1.QueryExecutionState.FAILED: {
|
|
123
|
-
throw new Error(
|
|
126
|
+
throw new Error("The Amazon Athena query failed to run with error message: " +
|
|
127
|
+
status.StateChangeReason);
|
|
124
128
|
}
|
|
125
129
|
case client_athena_1.QueryExecutionState.CANCELLED: {
|
|
126
|
-
throw new Error(
|
|
130
|
+
throw new Error("The Amazon Athena query was cancelled.");
|
|
127
131
|
}
|
|
128
132
|
case client_athena_1.QueryExecutionState.SUCCEEDED: {
|
|
129
133
|
return;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { EntityManager } from
|
|
2
|
-
import Install from
|
|
1
|
+
import { EntityManager } from "baqend";
|
|
2
|
+
import Install from "../models/install";
|
|
3
3
|
export default class ConfigApiService {
|
|
4
4
|
private db;
|
|
5
5
|
private readonly app;
|
|
@@ -14,5 +14,5 @@ export default class ConfigApiService {
|
|
|
14
14
|
saveRemoteModule(moduleCode: string, moduleName: string): Promise<string>;
|
|
15
15
|
getRemoteServerConfig(): Promise<string>;
|
|
16
16
|
saveRemoteServerConfig(localPath: string, configurationVersion: string): Promise<void>;
|
|
17
|
-
fetchAndGetBody(url: string, requestInit?:
|
|
17
|
+
fetchAndGetBody(url: string, requestInit?: NonNullable<unknown>): Promise<any>;
|
|
18
18
|
}
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const tslib_1 = require("tslib");
|
|
4
4
|
const fs = tslib_1.__importStar(require("fs-extra"));
|
|
5
|
-
const
|
|
6
|
-
const
|
|
7
|
-
const agent = new
|
|
5
|
+
const node_fetch_1 = tslib_1.__importDefault(require("node-fetch"));
|
|
6
|
+
const https_1 = tslib_1.__importDefault(require("https"));
|
|
7
|
+
const agent = new https_1.default.Agent({
|
|
8
8
|
rejectUnauthorized: false,
|
|
9
9
|
keepAlive: true,
|
|
10
10
|
});
|
|
@@ -18,11 +18,11 @@ class ConfigApiService {
|
|
|
18
18
|
this.app = app;
|
|
19
19
|
this.requestInit = {
|
|
20
20
|
agent,
|
|
21
|
-
method:
|
|
21
|
+
method: "GET",
|
|
22
22
|
headers: {
|
|
23
23
|
Host: `${this.app}.app.baqend.com`,
|
|
24
24
|
authorization: `BAT ${this.db.token}`,
|
|
25
|
-
|
|
25
|
+
"Content-Type": "application/json;charset=UTF-8",
|
|
26
26
|
},
|
|
27
27
|
timeout: 10_000,
|
|
28
28
|
};
|
|
@@ -34,58 +34,70 @@ class ConfigApiService {
|
|
|
34
34
|
}
|
|
35
35
|
async activateInstall(install) {
|
|
36
36
|
const activateUrl = `https://${this.app}.app.baqend.com/v1/speedkit/installation/${install.domain}/${install.configVersion}/activate`;
|
|
37
|
-
const postInit = Object.assign({}, this.requestInit, {
|
|
37
|
+
const postInit = Object.assign({}, this.requestInit, {
|
|
38
|
+
body: "{}",
|
|
39
|
+
method: "POST",
|
|
40
|
+
});
|
|
38
41
|
return (await this.fetchAndGetBody(activateUrl, postInit));
|
|
39
42
|
}
|
|
40
43
|
// Update live version with the osk local body
|
|
41
44
|
async updateInstall(install) {
|
|
42
|
-
const postInit = Object.assign({}, this.requestInit, {
|
|
45
|
+
const postInit = Object.assign({}, this.requestInit, {
|
|
46
|
+
body: JSON.stringify(install),
|
|
47
|
+
method: "PUT",
|
|
48
|
+
});
|
|
43
49
|
const updateUrl = `https://${this.app}.app.baqend.com/v1/speedkit/installation/${install.domain}/${install.configVersion}`;
|
|
44
50
|
return (await this.fetchAndGetBody(updateUrl, postInit));
|
|
45
51
|
}
|
|
46
52
|
async createNewInstall(domain, origins) {
|
|
47
|
-
const postInit = Object.assign({}, this.requestInit, {
|
|
53
|
+
const postInit = Object.assign({}, this.requestInit, {
|
|
54
|
+
body: `{origins: ${JSON.stringify(origins)}}`,
|
|
55
|
+
method: "POST",
|
|
56
|
+
});
|
|
48
57
|
const updateUrl = `https://${this.app}.app.baqend.com/v1/speedkit/installation/${domain}`;
|
|
49
58
|
const body = await this.fetchAndGetBody(updateUrl, postInit);
|
|
50
59
|
return body;
|
|
51
60
|
}
|
|
52
61
|
async cloneInstall(install) {
|
|
53
|
-
const postInit = Object.assign({}, this.requestInit, {
|
|
62
|
+
const postInit = Object.assign({}, this.requestInit, {
|
|
63
|
+
body: "{}",
|
|
64
|
+
method: "POST",
|
|
65
|
+
});
|
|
54
66
|
const cloneUrl = `https://${this.app}.app.baqend.com/v1/speedkit/installation/${install.domain}/${install.configVersion}/clone`;
|
|
55
67
|
const body = await this.fetchAndGetBody(cloneUrl, postInit);
|
|
56
68
|
return body;
|
|
57
69
|
}
|
|
58
70
|
async getRemoteModule(moduleName) {
|
|
59
|
-
return await this.db.code.loadCode(moduleName,
|
|
71
|
+
return await this.db.code.loadCode(moduleName, "module");
|
|
60
72
|
}
|
|
61
73
|
async saveRemoteModule(moduleCode, moduleName) {
|
|
62
|
-
return await this.db.code.saveCode(moduleName,
|
|
74
|
+
return await this.db.code.saveCode(moduleName, "module", moduleCode);
|
|
63
75
|
}
|
|
64
76
|
async getRemoteServerConfig() {
|
|
65
77
|
const urlPath = `https://${this.app}.app.baqend.com/v1/config`;
|
|
66
78
|
const body = await this.fetchAndGetBody(urlPath);
|
|
67
|
-
return JSON.stringify(body, null,
|
|
79
|
+
return JSON.stringify(body, null, "\t");
|
|
68
80
|
}
|
|
69
81
|
async saveRemoteServerConfig(localPath, configurationVersion) {
|
|
70
|
-
const localServerConfigContent = fs.readFileSync(localPath,
|
|
82
|
+
const localServerConfigContent = fs.readFileSync(localPath, "utf-8");
|
|
71
83
|
const localServerConfig = JSON.parse(localServerConfigContent);
|
|
72
84
|
localServerConfig.revision.version = configurationVersion;
|
|
73
85
|
const urlPath = `https://${this.app}.app.baqend.com/v1/config`;
|
|
74
86
|
const putInit = Object.assign({}, this.requestInit, {
|
|
75
87
|
body: JSON.stringify(localServerConfig),
|
|
76
|
-
method:
|
|
88
|
+
method: "PUT",
|
|
77
89
|
headers: {
|
|
78
90
|
Host: `${this.app}.app.baqend.com`,
|
|
79
91
|
// Origin: "origin",
|
|
80
92
|
authorization: `BAT ${this.db.token}`,
|
|
81
|
-
|
|
82
|
-
|
|
93
|
+
"Content-Type": "application/json",
|
|
94
|
+
"If-Match": configurationVersion,
|
|
83
95
|
},
|
|
84
96
|
});
|
|
85
97
|
await this.fetchAndGetBody(urlPath, putInit);
|
|
86
98
|
}
|
|
87
99
|
async fetchAndGetBody(url, requestInit = this.requestInit) {
|
|
88
|
-
const res = await
|
|
100
|
+
const res = await (0, node_fetch_1.default)(url, requestInit);
|
|
89
101
|
const body = await res.json();
|
|
90
102
|
if (res.status !== 200) {
|
|
91
103
|
throw new Error(body.message);
|
|
@@ -17,14 +17,14 @@ class DiffService {
|
|
|
17
17
|
this.diffExecutableTemplate = diffExecutableTemplate;
|
|
18
18
|
}
|
|
19
19
|
async diff(localPath, fileName, tmpContent) {
|
|
20
|
-
|
|
20
|
+
const tmpFilePath = await this.writeContentToTemporalFile(fileName, tmpContent);
|
|
21
21
|
return await this.executeDiff(tmpFilePath, localPath);
|
|
22
22
|
}
|
|
23
23
|
async diffContent(fileName, localContent, remoteContent) {
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
const tmpLocalFilePath = await this.writeContentToTemporalFile(`${fileName}-local`, localContent);
|
|
25
|
+
const tmpRemoteFilePath = await this.writeContentToTemporalFile(`${fileName}-remote`, remoteContent);
|
|
26
26
|
const diff = await this.executeDiff(tmpLocalFilePath, tmpRemoteFilePath);
|
|
27
|
-
const changedFile = await (0, promises_1.readFile)(tmpLocalFilePath,
|
|
27
|
+
const changedFile = await (0, promises_1.readFile)(tmpLocalFilePath, "utf-8");
|
|
28
28
|
return { changedFile, diff };
|
|
29
29
|
}
|
|
30
30
|
/**
|
|
@@ -36,17 +36,17 @@ class DiffService {
|
|
|
36
36
|
this.tempPath = await (0, file_helper_1.createTemporalDir)();
|
|
37
37
|
}
|
|
38
38
|
if (!this.tempPath) {
|
|
39
|
-
this.cli.writeError(
|
|
39
|
+
this.cli.writeError("No temporary Directory found and unable to create a new temporary Directory");
|
|
40
40
|
this.cli.exit(1);
|
|
41
41
|
}
|
|
42
42
|
return this.tempPath;
|
|
43
43
|
}
|
|
44
44
|
async writeContentToTemporalFile(tempFileName, content) {
|
|
45
45
|
if (!content) {
|
|
46
|
-
content =
|
|
46
|
+
content = "No file was found";
|
|
47
47
|
}
|
|
48
|
-
const resolveFilePath = path_1.default.join(await this.getTemporalDirectoryPath() + `/${tempFileName}`);
|
|
49
|
-
await promises_1.default.writeFile(resolveFilePath, content.replace(/\r?\n/gm,
|
|
48
|
+
const resolveFilePath = path_1.default.join((await this.getTemporalDirectoryPath()) + `/${tempFileName}`);
|
|
49
|
+
await promises_1.default.writeFile(resolveFilePath, content.replace(/\r?\n/gm, "\n"));
|
|
50
50
|
return resolveFilePath;
|
|
51
51
|
}
|
|
52
52
|
/**
|
|
@@ -55,9 +55,9 @@ class DiffService {
|
|
|
55
55
|
* @description removes whitespaces, newlines and compares both params content for equality.
|
|
56
56
|
* @return returns true if both localContent and remoteContent are equal otherwise returns false.
|
|
57
57
|
*/
|
|
58
|
-
isContentEqual(localContent =
|
|
59
|
-
const trimLocalContent = localContent.replace(/[\n\r\s]/g,
|
|
60
|
-
const trimRemoteContent = remoteContent.replace(/[\n\r\s]/g,
|
|
58
|
+
isContentEqual(localContent = "", remoteContent = "") {
|
|
59
|
+
const trimLocalContent = localContent.replace(/[\n\r\s]/g, "");
|
|
60
|
+
const trimRemoteContent = remoteContent.replace(/[\n\r\s]/g, "");
|
|
61
61
|
return trimLocalContent === trimRemoteContent;
|
|
62
62
|
}
|
|
63
63
|
/**
|
|
@@ -72,13 +72,19 @@ class DiffService {
|
|
|
72
72
|
let localContent;
|
|
73
73
|
let remoteContent;
|
|
74
74
|
try {
|
|
75
|
-
localContent = await promises_1.default.readFile(localPath, {
|
|
75
|
+
localContent = await promises_1.default.readFile(localPath, {
|
|
76
|
+
encoding: "utf8",
|
|
77
|
+
flag: "r",
|
|
78
|
+
});
|
|
76
79
|
}
|
|
77
80
|
catch (error) {
|
|
78
81
|
return false;
|
|
79
82
|
}
|
|
80
83
|
try {
|
|
81
|
-
remoteContent = await promises_1.default.readFile(remotePath, {
|
|
84
|
+
remoteContent = await promises_1.default.readFile(remotePath, {
|
|
85
|
+
encoding: "utf8",
|
|
86
|
+
flag: "r",
|
|
87
|
+
});
|
|
82
88
|
}
|
|
83
89
|
catch (error) {
|
|
84
90
|
this.cli.writeError(`Error reading remote file ${remoteContent}: ${error.message}`);
|
|
@@ -92,20 +98,22 @@ class DiffService {
|
|
|
92
98
|
return false;
|
|
93
99
|
}
|
|
94
100
|
// try custom diff tool
|
|
95
|
-
if (this.diffExecutablePath !== null &&
|
|
101
|
+
if (this.diffExecutablePath !== null &&
|
|
102
|
+
this.diffExecutablePath.length > 0 &&
|
|
103
|
+
this.diffExecutableTemplate !== null) {
|
|
96
104
|
try {
|
|
97
105
|
const command = this.diffExecutableTemplate
|
|
98
106
|
.replace("$exec", this.diffExecutablePath)
|
|
99
107
|
.replace("$file1", localPath)
|
|
100
108
|
.replace("$file2", remotePath);
|
|
101
|
-
(0, child_process_1.execSync)(command, { stdio:
|
|
109
|
+
(0, child_process_1.execSync)(command, { stdio: "pipe" });
|
|
102
110
|
}
|
|
103
111
|
catch (error) {
|
|
104
112
|
this.cli.code(error.stdout.toString());
|
|
105
113
|
}
|
|
106
114
|
return false;
|
|
107
115
|
}
|
|
108
|
-
|
|
116
|
+
const isWindows = process.platform.startsWith("win");
|
|
109
117
|
let ideaCommandAvailable;
|
|
110
118
|
try {
|
|
111
119
|
(0, child_process_1.execSync)(`idea diff "${localPath}" "${remotePath}"`);
|
|
@@ -117,10 +125,10 @@ class DiffService {
|
|
|
117
125
|
try {
|
|
118
126
|
if (!ideaCommandAvailable) {
|
|
119
127
|
if (isWindows) {
|
|
120
|
-
(0, child_process_1.execSync)(`"%IDEA_INITIAL_DIRECTORY%\\idea" diff ${localPath} ${remotePath}`, { stdio:
|
|
128
|
+
(0, child_process_1.execSync)(`"%IDEA_INITIAL_DIRECTORY%\\idea" diff ${localPath} ${remotePath}`, { stdio: "pipe" });
|
|
121
129
|
}
|
|
122
130
|
else {
|
|
123
|
-
(0, child_process_1.execSync)(`"$IDEA_INITIAL_DIRECTORY/idea" diff ${localPath} ${remotePath}`, { stdio:
|
|
131
|
+
(0, child_process_1.execSync)(`"$IDEA_INITIAL_DIRECTORY/idea" diff ${localPath} ${remotePath}`, { stdio: "pipe" });
|
|
124
132
|
}
|
|
125
133
|
}
|
|
126
134
|
return false;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export * from
|
|
2
|
-
export * from
|
|
3
|
-
export * from
|
|
1
|
+
export * from "./diff-service";
|
|
2
|
+
export * from "./diff-service-factory";
|
|
3
|
+
export * from "./diff-model";
|