@speedkit/cli 2.14.3 → 2.16.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 +16 -0
- package/README.md +5 -2
- package/dist/commands/generate-pop-config.js +6 -5
- package/dist/dummy.spec.js +4 -4
- package/dist/helpers/build-query-helper.js +49 -35
- package/dist/helpers/file-helper.d.ts +2 -8
- package/dist/helpers/file-helper.js +6 -41
- package/dist/helpers/get-parsed-config.js +7 -7
- package/dist/helpers/getChromePath.js +11 -7
- package/dist/helpers/isDirectory.js +1 -1
- package/dist/helpers/isFile.js +1 -1
- package/dist/helpers/normalize.d.ts +2 -0
- package/dist/helpers/normalize.js +14 -12
- package/dist/helpers/race.js +3 -1
- package/dist/helpers/scrape.js +3 -2
- package/dist/helpers/speedKitRuleToRegExp.js +2 -2
- package/dist/models/cli-parameters.d.ts +2 -2
- package/dist/models/cli-parameters.js +8 -2
- package/dist/models/files.js +13 -13
- package/dist/services/athena/athena-service-factory.d.ts +13 -0
- package/dist/services/athena/athena-service-factory.js +40 -0
- package/dist/services/athena/athena-service-model.d.ts +4 -0
- package/dist/services/athena/athena-service-model.js +7 -0
- package/dist/services/{athena-service.d.ts → athena/athena-service.d.ts} +4 -8
- package/dist/services/{athena-service.js → athena/athena-service.js} +12 -36
- package/dist/services/athena/error/fetch-credentials-error.d.ts +2 -0
- package/dist/services/athena/error/fetch-credentials-error.js +6 -0
- package/dist/services/athena/index.d.ts +4 -0
- package/dist/services/athena/index.js +7 -0
- package/dist/services/bundler/bundle-service-factory.d.ts +1 -1
- package/dist/services/bundler/bundle-service.d.ts +2 -2
- package/dist/services/bundler/bundle-service.js +29 -23
- package/dist/services/bundler/index.d.ts +2 -2
- package/dist/services/cli/cli-service.js +5 -5
- package/dist/services/cli/hooks.js +2 -2
- package/dist/services/cli/index.d.ts +3 -3
- package/dist/services/config-api/client.d.ts +1 -1
- package/dist/services/config-api/client.js +9 -7
- package/dist/services/config-api/config-api-service.js +20 -8
- package/dist/services/config-api/factory/config-api-service-factory.js +1 -1
- package/dist/services/config-api/interface/request-extension-interface.d.ts +2 -2
- package/dist/services/customer-config/customer-config-service-context.js +1 -1
- package/dist/services/customer-config/customer-config-service.d.ts +1 -0
- package/dist/services/customer-config/customer-config-service.js +68 -57
- package/dist/services/customer-config/index.d.ts +4 -4
- package/dist/services/deploy/builder/install-resource-builder.js +9 -7
- package/dist/services/deploy/checks/post-deploy/revalidated-module-check.js +2 -2
- package/dist/services/deploy/checks/post-deploy/save-files-check.js +2 -2
- package/dist/services/deploy/deploy-service.js +7 -7
- package/dist/services/deploy/handler/customer-config-handler.js +12 -11
- package/dist/services/deploy/handler/install-resource-handler.js +14 -12
- package/dist/services/deploy/handler/install-resource-modifier/deleted-file-check.js +10 -10
- package/dist/services/deploy/handler/module-handler.js +9 -9
- package/dist/services/deploy/handler/module-modifier/deployment-detection-modifier.js +2 -2
- package/dist/services/deploy/handler/server-config-handler.js +4 -4
- package/dist/services/deploy/interface/install.d.ts +1 -1
- package/dist/services/document-handler-runtime/context/document-handler-runtime-context.js +37 -18
- package/dist/services/document-handler-runtime/document-handler-runtime-service.js +45 -35
- package/dist/services/document-handler-runtime/document-handler-server.js +56 -33
- package/dist/services/document-handler-runtime/error/handler/required-file-not-found-handler.js +1 -1
- package/dist/services/document-handler-runtime/factory/document-handler-runtime-service-factory.js +20 -16
- package/dist/services/document-handler-runtime/templates/abstract-template.d.ts +1 -1
- package/dist/services/document-handler-runtime/templates/abstract-template.js +1 -1
- package/dist/services/error-handling/abstract/abstract-async-error-handling-factory.js +1 -1
- package/dist/services/error-handling/abstract/abstract-async-error-handling-service.js +1 -1
- package/dist/services/error-handling/abstract/abstract-error-handling-factory.js +1 -1
- package/dist/services/error-handling/abstract/abstract-error-handling-service.js +1 -1
- package/dist/services/error-handling/error/handler/default-error-handler.d.ts +1 -1
- package/dist/services/error-handling/error/handler/default-error-handler.js +1 -1
- package/dist/services/error-handling/error-handling-service.js +2 -2
- package/dist/services/integration-api/context/integration-api-context.js +1 -1
- package/dist/services/integration-api/external/external-file-reader.js +1 -1
- package/dist/services/integration-api/factory/integration-api-service-factory.js +3 -3
- package/dist/services/integration-api/file-list.js +6 -4
- package/dist/services/integration-api/file-reader.js +17 -12
- package/dist/services/integration-api/handler/file-handler.d.ts +1 -1
- package/dist/services/integration-api/handler/file-handler.js +8 -4
- package/dist/services/integration-api/handler/install-resource-handler.js +21 -20
- package/dist/services/integration-api/handler/server-config-handler.js +1 -3
- package/dist/services/integration-api/integration-api-model.d.ts +2 -2
- package/dist/services/integration-api/integration-api-service.js +10 -7
- package/dist/services/integration-api/struct/customer-config.js +3 -2
- package/dist/services/integration-api/struct/file.js +4 -4
- package/dist/services/integration-api/struct/module-file.d.ts +1 -1
- package/dist/services/integration-api/struct/module-file.js +3 -1
- package/dist/services/integration-api/struct/server-config-file.d.ts +1 -1
- package/dist/services/integration-api/validator/customer-config-validator.js +13 -4
- package/dist/services/integration-api/validator/mandatory-files-validator.js +9 -5
- package/dist/services/integration-api/virtual/virtual-file-handler.js +1 -1
- package/dist/services/onboarding/dashboard/frontend-dist/assets/{index-87b53ed4.css → index-e3bd4f6e.css} +1 -1
- package/dist/services/onboarding/dashboard/frontend-dist/assets/{main-274b5625.js → main-215271c2.js} +3 -3
- package/dist/services/onboarding/dashboard/frontend-dist/index.html +2 -2
- package/dist/services/onboarding/dashboard/index.d.ts +2 -1
- package/dist/services/onboarding/dashboard/index.js +6 -5
- package/dist/services/onboarding/dashboard/request-diff-service.d.ts +4 -2
- package/dist/services/onboarding/dashboard/request-diff-service.js +23 -14
- package/dist/services/onboarding/fetch-events/speed-kit-asset-request.d.ts +1 -0
- package/dist/services/onboarding/fetch-events/speed-kit-asset-request.js +18 -1
- package/dist/services/onboarding/onboarding-service-factory.d.ts +0 -1
- package/dist/services/onboarding/onboarding-service-factory.js +9 -34
- package/dist/services/pop-config/index.d.ts +3 -0
- package/dist/services/pop-config/index.js +6 -0
- package/dist/services/pop-config/pop-config-factory.d.ts +4 -0
- package/dist/services/pop-config/pop-config-factory.js +12 -0
- package/dist/services/pop-config/pop-config-model.d.ts +6 -0
- package/dist/services/pop-config/pop-config-model.js +2 -0
- package/dist/services/pop-config/pop-config-service.d.ts +7 -0
- package/dist/services/pop-config/pop-config-service.js +39 -0
- package/dist/services/prewarm-service.js +22 -16
- package/oclif.manifest.json +1 -1
- package/package.json +2 -4
- package/dist/services/onboarding/dashboard/athena-service.d.ts +0 -11
- package/dist/services/onboarding/dashboard/athena-service.js +0 -75
|
@@ -27,12 +27,12 @@ class CustomerConfigService {
|
|
|
27
27
|
return this._outputDirPath;
|
|
28
28
|
}
|
|
29
29
|
templates = [
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
30
|
+
"config_customer.js.hbs",
|
|
31
|
+
"config_documentHandler.js.hbs",
|
|
32
|
+
"config_dynamicBlocks.es6.hbs",
|
|
33
|
+
"config_dynamicStyles.css.hbs",
|
|
34
|
+
"config_loadHandler.js.hbs",
|
|
35
|
+
"config_SpeedKit.js.hbs",
|
|
36
36
|
];
|
|
37
37
|
constructor(context, cli) {
|
|
38
38
|
this.context = context;
|
|
@@ -40,11 +40,11 @@ class CustomerConfigService {
|
|
|
40
40
|
this.appName = appName;
|
|
41
41
|
this.cli = cli;
|
|
42
42
|
}
|
|
43
|
-
getOutputDirPath(dirName =
|
|
43
|
+
getOutputDirPath(dirName = "") {
|
|
44
44
|
return path.join(process.cwd(), this.context.customersDir, dirName);
|
|
45
45
|
}
|
|
46
46
|
getHandlebarsOutputFileName(fileName) {
|
|
47
|
-
return fileName.replace(
|
|
47
|
+
return fileName.replace(".hbs", "");
|
|
48
48
|
}
|
|
49
49
|
getPathWithChangedDir(dirPath, newDir) {
|
|
50
50
|
return path.join(path.dirname(dirPath), newDir);
|
|
@@ -52,32 +52,38 @@ class CustomerConfigService {
|
|
|
52
52
|
isDirNotEmpty(dirPath) {
|
|
53
53
|
return fs.existsSync(dirPath) && fs.readdirSync(dirPath).length > 0;
|
|
54
54
|
}
|
|
55
|
+
async chooseNewOutputDirectoryName(dirPath) {
|
|
56
|
+
const dirName = path.basename(dirPath);
|
|
57
|
+
let proposedNewDirName;
|
|
58
|
+
const regExFollowingNumber = /-(\d+)$/;
|
|
59
|
+
const match = dirName.match(regExFollowingNumber);
|
|
60
|
+
if (match && match.length > 1) {
|
|
61
|
+
const numberAtTheEndOfDirName = Number(match[1]);
|
|
62
|
+
proposedNewDirName = dirName.replace(regExFollowingNumber, `-${String(numberAtTheEndOfDirName + 1)}`);
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
proposedNewDirName = `${dirName}-2`;
|
|
66
|
+
}
|
|
67
|
+
const newDirName = await this.cli.prompt(`Please enter new output directory name:`, {
|
|
68
|
+
defaultAnswer: proposedNewDirName,
|
|
69
|
+
});
|
|
70
|
+
return this.selectOutputDirectory(this.getPathWithChangedDir(dirPath, newDirName));
|
|
71
|
+
}
|
|
55
72
|
async selectOutputDirectory(dirPath) {
|
|
56
73
|
// protect output directory if already existing and not empty:
|
|
57
74
|
if (this.isDirNotEmpty(dirPath)) {
|
|
58
75
|
this.cli.spacer();
|
|
59
|
-
const selectedDirectoryOverwriteOption = await this.cli.select(`Output directory ${dirPath} is not empty. How to proceed?`, Object.values(customer_config_service_model_1.DirectoryOverwriteOption).map(option => ({
|
|
76
|
+
const selectedDirectoryOverwriteOption = await this.cli.select(`Output directory ${dirPath} is not empty. How to proceed?`, Object.values(customer_config_service_model_1.DirectoryOverwriteOption).map((option) => ({
|
|
77
|
+
name: option,
|
|
78
|
+
value: option,
|
|
79
|
+
})));
|
|
60
80
|
switch (selectedDirectoryOverwriteOption) {
|
|
61
81
|
case customer_config_service_model_1.DirectoryOverwriteOption.OVERWRITE_COMPLETELY:
|
|
62
82
|
fs.rmSync(dirPath, { recursive: true, force: true });
|
|
63
83
|
fs.mkdirSync(dirPath, { recursive: true });
|
|
64
84
|
break;
|
|
65
85
|
case customer_config_service_model_1.DirectoryOverwriteOption.NEW_NAME:
|
|
66
|
-
|
|
67
|
-
let proposedNewDirName;
|
|
68
|
-
const regExFollowingNumber = /-(\d+)$/;
|
|
69
|
-
const match = dirName.match(regExFollowingNumber);
|
|
70
|
-
if (match && match.length > 1) {
|
|
71
|
-
const numberAtTheEndOfDirName = Number(match[1]);
|
|
72
|
-
proposedNewDirName = dirName.replace(regExFollowingNumber, `-${String(numberAtTheEndOfDirName + 1)}`);
|
|
73
|
-
}
|
|
74
|
-
else {
|
|
75
|
-
proposedNewDirName = `${dirName}-2`;
|
|
76
|
-
}
|
|
77
|
-
const newDirName = await this.cli.prompt(`Please enter new output directory name:`, {
|
|
78
|
-
defaultAnswer: proposedNewDirName
|
|
79
|
-
});
|
|
80
|
-
return this.selectOutputDirectory(this.getPathWithChangedDir(dirPath, newDirName));
|
|
86
|
+
return await this.chooseNewOutputDirectoryName(dirPath);
|
|
81
87
|
}
|
|
82
88
|
}
|
|
83
89
|
return dirPath;
|
|
@@ -92,12 +98,12 @@ class CustomerConfigService {
|
|
|
92
98
|
this.cli.startAction(`Adding ${outputFileName}`);
|
|
93
99
|
try {
|
|
94
100
|
const outputFilePath = path.join(this.outputDirPath, outputFileName);
|
|
95
|
-
if (!await this.shouldFileBeOverwritten(outputFilePath)) {
|
|
101
|
+
if (!(await this.shouldFileBeOverwritten(outputFilePath))) {
|
|
96
102
|
this.cli.endAction(cli_1.CliActionStatus.SKIPPED);
|
|
97
103
|
continue;
|
|
98
104
|
}
|
|
99
|
-
const filePath = path.join(__dirname,
|
|
100
|
-
const content = fs.readFileSync(filePath,
|
|
105
|
+
const filePath = path.join(__dirname, "./templates", templateFile);
|
|
106
|
+
const content = fs.readFileSync(filePath, "utf8");
|
|
101
107
|
const template = Handlebars.compile(content);
|
|
102
108
|
const result = template(configSettings);
|
|
103
109
|
fs.mkdirSync(path.dirname(outputFilePath), { recursive: true });
|
|
@@ -112,12 +118,12 @@ class CustomerConfigService {
|
|
|
112
118
|
}
|
|
113
119
|
async getEnvironmentConfig(environmentType, defaultHost) {
|
|
114
120
|
const host = await this.cli.prompt(`Enter ${environmentType.toUpperCase()} Host (without https://):`, {
|
|
115
|
-
defaultAnswer: defaultHost
|
|
121
|
+
defaultAnswer: defaultHost,
|
|
116
122
|
});
|
|
117
123
|
const forceInstall = !(await this.cli.confirm(`Is the install.js already present on ${environmentType.toUpperCase()}?`, false));
|
|
118
124
|
return {
|
|
119
125
|
host,
|
|
120
|
-
forceInstall
|
|
126
|
+
forceInstall,
|
|
121
127
|
};
|
|
122
128
|
}
|
|
123
129
|
async shouldFileBeOverwritten(outputFilePath) {
|
|
@@ -131,16 +137,16 @@ class CustomerConfigService {
|
|
|
131
137
|
async downloadAndSaveFile(url, outputFilePath) {
|
|
132
138
|
this.cli.startAction(`Adding ${path.basename(outputFilePath)}`);
|
|
133
139
|
try {
|
|
134
|
-
if (!await this.shouldFileBeOverwritten(outputFilePath)) {
|
|
140
|
+
if (!(await this.shouldFileBeOverwritten(outputFilePath))) {
|
|
135
141
|
this.cli.endAction(cli_1.CliActionStatus.SKIPPED);
|
|
136
142
|
return;
|
|
137
143
|
}
|
|
138
|
-
const response = await axios_1.default.get(url, { responseType:
|
|
144
|
+
const response = await axios_1.default.get(url, { responseType: "text" });
|
|
139
145
|
const date = new Date();
|
|
140
|
-
const day = String(date.getDate()).padStart(2,
|
|
141
|
-
const month = String(date.getMonth() + 1).padStart(2,
|
|
146
|
+
const day = String(date.getDate()).padStart(2, "0");
|
|
147
|
+
const month = String(date.getMonth() + 1).padStart(2, "0"); // Months are 0-indexed
|
|
142
148
|
const year = date.getFullYear();
|
|
143
|
-
const time = date.toLocaleTimeString(
|
|
149
|
+
const time = date.toLocaleTimeString("de-DE");
|
|
144
150
|
const formattedDate = `${day}.${month}.${year}, ${time}`;
|
|
145
151
|
// Add timestamp banner to the file
|
|
146
152
|
const banner = `/**\n * Downloaded from:\n * ${url}\n * \n * Date: ${formattedDate}\n */\n\n`;
|
|
@@ -153,12 +159,15 @@ class CustomerConfigService {
|
|
|
153
159
|
}
|
|
154
160
|
}
|
|
155
161
|
async getConfigSettings() {
|
|
156
|
-
let { production, staging, includeServiceWorker, activateImageOptimisation, removeLazyLoading, addPreRendering, activateRumTracking, useGATracking, withGoogleOptimize, activateCfRocketLoaderWorkaround, isShopify, isShopware, isSalesforce, isPlentymarkets, shopifyId } = {};
|
|
162
|
+
let { production, staging, includeServiceWorker, activateImageOptimisation, removeLazyLoading, addPreRendering, activateRumTracking, useGATracking, withGoogleOptimize, activateCfRocketLoaderWorkaround, isShopify, isShopware, isSalesforce, isPlentymarkets, shopifyId, } = {};
|
|
157
163
|
this.appName = await this.cli.prompt(`Enter SK App Name:`, {
|
|
158
|
-
validator: (input) => /^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(input) ?
|
|
159
|
-
defaultAnswer: this.appName
|
|
164
|
+
validator: (input) => /^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(input) ? "" : "No valid kebab-case",
|
|
165
|
+
defaultAnswer: this.appName,
|
|
160
166
|
});
|
|
161
|
-
const selectedShopSystem = await this.cli.select(
|
|
167
|
+
const selectedShopSystem = await this.cli.select("Which Shop System is in use?", Object.values(customer_config_service_model_1.ShopSystem).map((option) => ({
|
|
168
|
+
name: option,
|
|
169
|
+
value: option,
|
|
170
|
+
})));
|
|
162
171
|
switch (selectedShopSystem) {
|
|
163
172
|
case customer_config_service_model_1.ShopSystem.SHOPIFY:
|
|
164
173
|
isShopify = true;
|
|
@@ -174,32 +183,34 @@ class CustomerConfigService {
|
|
|
174
183
|
}
|
|
175
184
|
production = await this.getEnvironmentConfig(customer_config_service_model_1.EnvironmentType.PRODUCTION, `www.${this.appName}.de`);
|
|
176
185
|
if (isShopify) {
|
|
177
|
-
shopifyId = await this.cli.prompt(`Enter Shopify ID:`, {
|
|
186
|
+
shopifyId = await this.cli.prompt(`Enter Shopify ID:`, {
|
|
187
|
+
defaultAnswer: this.appName,
|
|
188
|
+
});
|
|
178
189
|
}
|
|
179
190
|
else {
|
|
180
191
|
const withStaging = await this.cli.confirm(`Add Config for ${customer_config_service_model_1.EnvironmentType.STAGING.toUpperCase()} Environment?`, false);
|
|
181
192
|
if (withStaging) {
|
|
182
|
-
staging = await this.getEnvironmentConfig(customer_config_service_model_1.EnvironmentType.STAGING, production.host.replace(
|
|
193
|
+
staging = await this.getEnvironmentConfig(customer_config_service_model_1.EnvironmentType.STAGING, production.host.replace("www", "stg"));
|
|
183
194
|
}
|
|
184
195
|
}
|
|
185
|
-
if (await this.cli.confirm(
|
|
186
|
-
includeServiceWorker = await this.cli.prompt(
|
|
196
|
+
if (await this.cli.confirm("Is there a Service Worker which needs to be included?", false)) {
|
|
197
|
+
includeServiceWorker = await this.cli.prompt("Enter path of Service Worker to be included:", { defaultAnswer: "/sw.js" });
|
|
187
198
|
}
|
|
188
|
-
activateImageOptimisation = await this.cli.confirm(
|
|
189
|
-
removeLazyLoading = await this.cli.confirm(
|
|
190
|
-
addPreRendering = await this.cli.confirm(
|
|
191
|
-
activateRumTracking = await this.cli.confirm(
|
|
199
|
+
activateImageOptimisation = await this.cli.confirm("Activate Image Optimisation?", false);
|
|
200
|
+
removeLazyLoading = await this.cli.confirm("Remove Lazy-Loading?");
|
|
201
|
+
addPreRendering = await this.cli.confirm("Add Pre-Rendering? This requires a set-up Lambda function to work. Also requires a DOM-based DocumentHandler.", false);
|
|
202
|
+
activateRumTracking = await this.cli.confirm("Activate RUM Tracking?");
|
|
192
203
|
if (activateRumTracking) {
|
|
193
204
|
if (!isShopify) {
|
|
194
|
-
useGATracking = await this.cli.confirm(
|
|
205
|
+
useGATracking = await this.cli.confirm("Add Tracking based on Google Analytics' DataLayer?");
|
|
195
206
|
}
|
|
196
207
|
}
|
|
197
|
-
withGoogleOptimize = await this.cli.confirm(
|
|
208
|
+
withGoogleOptimize = await this.cli.confirm("Is Google Optimize being used?", false);
|
|
198
209
|
if (isShopify) {
|
|
199
210
|
activateCfRocketLoaderWorkaround = true;
|
|
200
211
|
}
|
|
201
212
|
else {
|
|
202
|
-
activateCfRocketLoaderWorkaround = await this.cli.confirm(
|
|
213
|
+
activateCfRocketLoaderWorkaround = await this.cli.confirm("Activate Workaround for Cloudflare's Rocket Loader?", false);
|
|
203
214
|
}
|
|
204
215
|
return {
|
|
205
216
|
appName: this.appName,
|
|
@@ -217,7 +228,7 @@ class CustomerConfigService {
|
|
|
217
228
|
isShopware,
|
|
218
229
|
isSalesforce,
|
|
219
230
|
isPlentymarkets,
|
|
220
|
-
shopifyId
|
|
231
|
+
shopifyId,
|
|
221
232
|
};
|
|
222
233
|
}
|
|
223
234
|
async handleDocumentHandler({ addPreRendering }) {
|
|
@@ -227,8 +238,8 @@ class CustomerConfigService {
|
|
|
227
238
|
and can be controlled/activated by the DocumentHandler Config properly
|
|
228
239
|
*/
|
|
229
240
|
if (addPreRendering) {
|
|
230
|
-
const documentHandlerBranchName =
|
|
231
|
-
const customDocumentHandlerOutputPath = path.join(this.outputDirPath,
|
|
241
|
+
const documentHandlerBranchName = "dom-parser/develop";
|
|
242
|
+
const customDocumentHandlerOutputPath = path.join(this.outputDirPath, "custom_documentHandler.js");
|
|
232
243
|
this.cli.writeWarning(`
|
|
233
244
|
⚠️ MANUAL ACTION NEEDED ⚠️
|
|
234
245
|
|
|
@@ -246,18 +257,18 @@ class CustomerConfigService {
|
|
|
246
257
|
}
|
|
247
258
|
}
|
|
248
259
|
async generateConfig() {
|
|
249
|
-
this.cli.write(
|
|
260
|
+
this.cli.write("\nLet's generate a config...\n");
|
|
250
261
|
const configSettings = await this.getConfigSettings();
|
|
251
262
|
if (configSettings.isSalesforce) {
|
|
252
|
-
this.templates.push(
|
|
263
|
+
this.templates.push("deploymentDetection.es6.hbs");
|
|
253
264
|
}
|
|
254
|
-
const addDowntimeDetection = await this.cli.confirm(
|
|
265
|
+
const addDowntimeDetection = await this.cli.confirm("Add Downtime Detection?", false);
|
|
255
266
|
if (addDowntimeDetection) {
|
|
256
|
-
this.templates.push(
|
|
267
|
+
this.templates.push("downtimeDetection.js.hbs");
|
|
257
268
|
}
|
|
258
269
|
await this.compileHandlebarsFiles(configSettings);
|
|
259
270
|
await this.handleDocumentHandler(configSettings);
|
|
260
|
-
this.cli.writeSuccess(
|
|
271
|
+
this.cli.writeSuccess("\nConfig generation completed 👏\n");
|
|
261
272
|
}
|
|
262
273
|
}
|
|
263
274
|
exports.CustomerConfigService = CustomerConfigService;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export * from
|
|
2
|
-
export * from
|
|
3
|
-
export * from
|
|
4
|
-
export * from
|
|
1
|
+
export * from "./customer-config-service";
|
|
2
|
+
export * from "./customer-config-service-context";
|
|
3
|
+
export * from "./customer-config-service-model";
|
|
4
|
+
export * from "./customer-config-service-factory";
|
|
@@ -13,11 +13,13 @@ class InstallResourceBuilder {
|
|
|
13
13
|
if (this.resource !== undefined) {
|
|
14
14
|
return this.resource;
|
|
15
15
|
}
|
|
16
|
-
this.resource =
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
16
|
+
this.resource =
|
|
17
|
+
(await this.configApi.getActiveInstall(configName)) ||
|
|
18
|
+
{
|
|
19
|
+
domain: configName,
|
|
20
|
+
origins: [],
|
|
21
|
+
configVersion: 1,
|
|
22
|
+
};
|
|
21
23
|
return this.resource;
|
|
22
24
|
}
|
|
23
25
|
merge(installParams) {
|
|
@@ -30,7 +32,7 @@ class InstallResourceBuilder {
|
|
|
30
32
|
this.resource.id = remoteParams.id;
|
|
31
33
|
this.resource.version = remoteParams.version;
|
|
32
34
|
this.resource.configVersion = remoteParams.configVersion;
|
|
33
|
-
this.resource.status =
|
|
35
|
+
this.resource.status = "inactive";
|
|
34
36
|
return this.resource;
|
|
35
37
|
}
|
|
36
38
|
hasChanges() {
|
|
@@ -41,7 +43,7 @@ class InstallResourceBuilder {
|
|
|
41
43
|
}
|
|
42
44
|
deepMerge(object1, object2) {
|
|
43
45
|
return (0, deepmerge_1.default)(object1, object2, {
|
|
44
|
-
arrayMerge: (destinationArray, sourceArray,
|
|
46
|
+
arrayMerge: (destinationArray, sourceArray, _options) => sourceArray,
|
|
45
47
|
});
|
|
46
48
|
}
|
|
47
49
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const REVALIDATED_MODULE_NAME =
|
|
3
|
+
const REVALIDATED_MODULE_NAME = "speedKit.Revalidated";
|
|
4
4
|
class RevalidatedModuleCheck {
|
|
5
5
|
configApi;
|
|
6
6
|
cli;
|
|
@@ -23,7 +23,7 @@ class RevalidatedModuleCheck {
|
|
|
23
23
|
}
|
|
24
24
|
showMessage() {
|
|
25
25
|
this.cli.writeError(`it seems ${REVALIDATED_MODULE_NAME} does not exists in the app ${this.app}`);
|
|
26
|
-
this.cli.write(
|
|
26
|
+
this.cli.write("please execute:");
|
|
27
27
|
this.cli.code(`sk generate-pop-config ${this.app}`);
|
|
28
28
|
}
|
|
29
29
|
}
|
|
@@ -15,10 +15,10 @@ class SaveFilesCheck {
|
|
|
15
15
|
return;
|
|
16
16
|
}
|
|
17
17
|
if (await this.cli.confirm(`Changes to localFiles will be saved now. Proceed?`)) {
|
|
18
|
-
fileList.forEach((
|
|
18
|
+
fileList.forEach((file) => {
|
|
19
19
|
file.updateIfChanged();
|
|
20
20
|
this.cli.writeSuccess(`${file.name} saved`);
|
|
21
|
-
})
|
|
21
|
+
});
|
|
22
22
|
}
|
|
23
23
|
}
|
|
24
24
|
}
|
|
@@ -20,18 +20,18 @@ class DeployService extends abstract_async_error_handling_service_1.default {
|
|
|
20
20
|
const types = this.fileList.getTypes();
|
|
21
21
|
this.cli.spacer();
|
|
22
22
|
this.cli.write(`App: "${this.fileList.getCustomerConfig().config.app}", Install: "${this.fileList.getCustomerConfig().config.name}"`);
|
|
23
|
-
this.cli.write(
|
|
23
|
+
this.cli.write("Preparing deployment...");
|
|
24
24
|
this.cli.spacer();
|
|
25
25
|
for (let iterator = 0; iterator < types.length; iterator++) {
|
|
26
|
-
|
|
26
|
+
const type = types[iterator];
|
|
27
27
|
await this.handleType(type);
|
|
28
28
|
}
|
|
29
29
|
if (this.dryRun) {
|
|
30
|
-
this.cli.comment(
|
|
30
|
+
this.cli.comment("dryRunFlag -d is set, skip upload");
|
|
31
31
|
}
|
|
32
32
|
else {
|
|
33
33
|
for (let iterator = 0; iterator < types.length; iterator++) {
|
|
34
|
-
|
|
34
|
+
const type = types[iterator];
|
|
35
35
|
await this.uploadType(type);
|
|
36
36
|
}
|
|
37
37
|
}
|
|
@@ -39,7 +39,7 @@ class DeployService extends abstract_async_error_handling_service_1.default {
|
|
|
39
39
|
}
|
|
40
40
|
async handleType(type) {
|
|
41
41
|
for (let iterator = 0; iterator < this.deployHandler.length; iterator++) {
|
|
42
|
-
|
|
42
|
+
const handler = this.deployHandler[iterator];
|
|
43
43
|
if (handler.canHandle(type)) {
|
|
44
44
|
await handler.handle(this.fileList.getByType(type));
|
|
45
45
|
}
|
|
@@ -47,7 +47,7 @@ class DeployService extends abstract_async_error_handling_service_1.default {
|
|
|
47
47
|
}
|
|
48
48
|
async uploadType(type) {
|
|
49
49
|
for (let iterator = 0; iterator < this.deployHandler.length; iterator++) {
|
|
50
|
-
|
|
50
|
+
const handler = this.deployHandler[iterator];
|
|
51
51
|
if (handler.canHandle(type)) {
|
|
52
52
|
await handler.upload(this.fileList.getByType(type));
|
|
53
53
|
}
|
|
@@ -55,7 +55,7 @@ class DeployService extends abstract_async_error_handling_service_1.default {
|
|
|
55
55
|
}
|
|
56
56
|
async runPostDeployChecks() {
|
|
57
57
|
for (let iterator = 0; iterator < this.postDeployChecks.length; iterator++) {
|
|
58
|
-
|
|
58
|
+
const check = this.postDeployChecks[iterator];
|
|
59
59
|
await check.check();
|
|
60
60
|
}
|
|
61
61
|
}
|
|
@@ -27,37 +27,38 @@ class CustomerConfigHandler {
|
|
|
27
27
|
const config = file.config;
|
|
28
28
|
if (!installResource) {
|
|
29
29
|
await this.handleMissingRemoteInstallResource(config);
|
|
30
|
-
this.cli.write(
|
|
30
|
+
this.cli.write("with origins:", true);
|
|
31
31
|
this.cli.code(JSON.stringify(config.origins), true);
|
|
32
32
|
return;
|
|
33
33
|
}
|
|
34
34
|
if (!installResource.origins || installResource.origins.length < 1) {
|
|
35
|
-
this.cli.write(
|
|
35
|
+
this.cli.write("with origins:", true);
|
|
36
36
|
this.cli.code(JSON.stringify(config.origins), true);
|
|
37
37
|
return;
|
|
38
38
|
}
|
|
39
39
|
const isEqual = this.diffService.isContentEqual(JSON.stringify(config.origins.sort()), JSON.stringify(installResource.origins.sort(), null, `\t`));
|
|
40
40
|
if (isEqual) {
|
|
41
|
-
this.cli.writeWarning(
|
|
41
|
+
this.cli.writeWarning("skipped origins (identical with remote)");
|
|
42
42
|
file.skipFile();
|
|
43
43
|
return;
|
|
44
44
|
}
|
|
45
45
|
// todo: only diff origins update local file if tmp file was changed
|
|
46
46
|
// todo: add changedThrowable, let the handler catch and decide what to do with it
|
|
47
|
-
const { changedFile
|
|
47
|
+
const { changedFile } = await this.diffService.diffContent(file.name, file.getContent(), this.prepareOriginDiff(installResource));
|
|
48
48
|
file.setContent(changedFile);
|
|
49
|
-
if (!(await this.cli.confirm(
|
|
49
|
+
if (!(await this.cli.confirm("Update origins?", true))) {
|
|
50
50
|
file.skipFile();
|
|
51
51
|
return;
|
|
52
52
|
}
|
|
53
|
-
this.cli.write(
|
|
53
|
+
this.cli.write("will update origins to:", true);
|
|
54
54
|
this.cli.code(JSON.stringify(config.origins), true);
|
|
55
55
|
return;
|
|
56
56
|
}
|
|
57
57
|
async upload(files) {
|
|
58
58
|
const file = files[0];
|
|
59
|
-
|
|
60
|
-
if (file.shouldSkipFile()) {
|
|
59
|
+
const installResource = await this.builder.init(this.configName);
|
|
60
|
+
if (file.shouldSkipFile()) {
|
|
61
|
+
// if installResource already exists its possible to skip the origin update
|
|
61
62
|
return;
|
|
62
63
|
}
|
|
63
64
|
installResource.origins = file.config.origins;
|
|
@@ -67,9 +68,9 @@ class CustomerConfigHandler {
|
|
|
67
68
|
const configName = config?.name || this.configName;
|
|
68
69
|
const { app: appName } = this.customer;
|
|
69
70
|
this.cli.spacer();
|
|
70
|
-
this.cli.writeWarning(`No ${chalk_1.default.underline(
|
|
71
|
+
this.cli.writeWarning(`No ${chalk_1.default.underline("active")} remote config named ${chalk_1.default.bold(configName)} found in app ${chalk_1.default.bold(appName)}`);
|
|
71
72
|
this.cli.spacer();
|
|
72
|
-
if (await this.cli.confirm(
|
|
73
|
+
if (await this.cli.confirm("Continue creating a new config?")) {
|
|
73
74
|
this.cli.write(`New configuration named ${chalk_1.default.bold(configName)} will be created in app ${chalk_1.default.bold(appName)}`, true);
|
|
74
75
|
}
|
|
75
76
|
else {
|
|
@@ -77,7 +78,7 @@ class CustomerConfigHandler {
|
|
|
77
78
|
}
|
|
78
79
|
}
|
|
79
80
|
prepareOriginDiff(installResource) {
|
|
80
|
-
|
|
81
|
+
const remoteConfig = {};
|
|
81
82
|
remoteConfig[this.configName] = { origins: installResource.origins };
|
|
82
83
|
return JSON.stringify(remoteConfig, null, 4);
|
|
83
84
|
}
|
|
@@ -25,17 +25,17 @@ class InstallResourceHandler {
|
|
|
25
25
|
async handle(files) {
|
|
26
26
|
const installResource = await this.configApi.getActiveInstall(this.configName);
|
|
27
27
|
for (let iterator = 0; iterator < files.length; iterator++) {
|
|
28
|
-
|
|
28
|
+
const file = files[iterator];
|
|
29
29
|
await this.processFile(file, installResource);
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
async upload(files) {
|
|
33
33
|
for (let iterator = 0; iterator < files.length; iterator++) {
|
|
34
|
-
|
|
34
|
+
const file = files[iterator];
|
|
35
35
|
if (file.shouldSkipFile()) {
|
|
36
36
|
continue;
|
|
37
37
|
}
|
|
38
|
-
|
|
38
|
+
const resource = {};
|
|
39
39
|
resource[file.remoteKey] = file.getContent();
|
|
40
40
|
this.builder.merge(resource);
|
|
41
41
|
}
|
|
@@ -43,16 +43,16 @@ class InstallResourceHandler {
|
|
|
43
43
|
if (!this.builder.hasChanges()) {
|
|
44
44
|
return;
|
|
45
45
|
}
|
|
46
|
-
this.cli.write(
|
|
47
|
-
this.cli.write(
|
|
46
|
+
this.cli.write("");
|
|
47
|
+
this.cli.write("Summary");
|
|
48
48
|
this.cli.writeBuffer();
|
|
49
|
-
if (!await this.cli.confirm(
|
|
49
|
+
if (!(await this.cli.confirm("InstallResource will be created now. Proceed?"))) {
|
|
50
50
|
this.cli.exit();
|
|
51
51
|
}
|
|
52
|
-
|
|
52
|
+
const install = await this.getInstallResource();
|
|
53
53
|
await this.deletedFilesChecker.checkForDeletedLocalFiles(install);
|
|
54
54
|
await this.configApi.setInstall(install);
|
|
55
|
-
if (await this.cli.confirm(
|
|
55
|
+
if (await this.cli.confirm("Activate new installation?")) {
|
|
56
56
|
await this.configApi.activateInstall(install);
|
|
57
57
|
}
|
|
58
58
|
}
|
|
@@ -71,7 +71,7 @@ class InstallResourceHandler {
|
|
|
71
71
|
await this.confirm(file);
|
|
72
72
|
}
|
|
73
73
|
async confirm(file, isNew = false) {
|
|
74
|
-
const confirm = await this.cli.confirm(`${isNew ?
|
|
74
|
+
const confirm = await this.cli.confirm(`${isNew ? "Create" : "Update"} ${file.name}?`);
|
|
75
75
|
if (!confirm) {
|
|
76
76
|
file.skipFile();
|
|
77
77
|
}
|
|
@@ -88,9 +88,11 @@ class InstallResourceHandler {
|
|
|
88
88
|
let install = await this.builder.init(this.configName);
|
|
89
89
|
const remoteClone = await this.prepareRemoteInstallResource(install);
|
|
90
90
|
install = this.builder.updateFromRemote(remoteClone);
|
|
91
|
-
install.description = await this.cli.prompt(
|
|
92
|
-
defaultAnswer: install.description
|
|
93
|
-
|
|
91
|
+
install.description = await this.cli.prompt("Describe new configuration:", {
|
|
92
|
+
defaultAnswer: install.description
|
|
93
|
+
? install.description
|
|
94
|
+
: this.configName,
|
|
95
|
+
validator: (input) => (input.trim() ? "" : "Please enter something"),
|
|
94
96
|
});
|
|
95
97
|
return install;
|
|
96
98
|
}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const INSTALL_RESOURCE_FILE_KEYS = [
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
4
|
+
"custom",
|
|
5
|
+
"sw",
|
|
6
|
+
"loader",
|
|
7
|
+
"dynamicFetcher",
|
|
8
|
+
"dynamicFetcherConfig",
|
|
9
|
+
"documentHandler",
|
|
10
|
+
"documentHandlerConfig",
|
|
11
|
+
"customStyle",
|
|
12
12
|
];
|
|
13
13
|
class DeletedFileCheck {
|
|
14
14
|
cli;
|
|
@@ -23,7 +23,7 @@ class DeletedFileCheck {
|
|
|
23
23
|
return;
|
|
24
24
|
}
|
|
25
25
|
const installResource = builder.resource;
|
|
26
|
-
for (
|
|
26
|
+
for (const key of INSTALL_RESOURCE_FILE_KEYS) {
|
|
27
27
|
const file = this.getFileByRemoteKey(key, files);
|
|
28
28
|
if (!file && installResource[key]?.length > 0) {
|
|
29
29
|
const deleteResource = await this.cli.confirm(`Do you want to delete ${key} on installResource?`);
|
|
@@ -35,7 +35,7 @@ class DeletedFileCheck {
|
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
37
|
async checkForDeletedLocalFiles(installResource) {
|
|
38
|
-
this.keysToDelete.forEach(key => {
|
|
38
|
+
this.keysToDelete.forEach((key) => {
|
|
39
39
|
installResource[key] = null;
|
|
40
40
|
});
|
|
41
41
|
}
|
|
@@ -18,10 +18,10 @@ class ModuleHandler {
|
|
|
18
18
|
}
|
|
19
19
|
async handle(files) {
|
|
20
20
|
for (let iterator = 0; iterator < files.length; iterator++) {
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
const file = files[iterator];
|
|
22
|
+
const remote = await this.configApi.getModule(file.name);
|
|
23
23
|
for (let iterator = 0; iterator < this.modifiers.length; iterator++) {
|
|
24
|
-
|
|
24
|
+
const modifier = this.modifiers[iterator];
|
|
25
25
|
if (modifier.canModify(file)) {
|
|
26
26
|
modifier.modify(file);
|
|
27
27
|
}
|
|
@@ -30,7 +30,7 @@ class ModuleHandler {
|
|
|
30
30
|
await this.confirm(file, true);
|
|
31
31
|
continue;
|
|
32
32
|
}
|
|
33
|
-
|
|
33
|
+
const { changedFile, diff } = await this.diffService.diffContent(file.name, file.getContent(), remote);
|
|
34
34
|
file.setContent(changedFile);
|
|
35
35
|
if (diff) {
|
|
36
36
|
this.cli.writeWarning(`skipped ${file.name} (identical with remote)`);
|
|
@@ -47,15 +47,15 @@ class ModuleHandler {
|
|
|
47
47
|
if (filesToUpload.length === 0) {
|
|
48
48
|
return;
|
|
49
49
|
}
|
|
50
|
-
this.cli.write(
|
|
51
|
-
this.cli.write(
|
|
50
|
+
this.cli.write("");
|
|
51
|
+
this.cli.write("Summary");
|
|
52
52
|
this.cli.writeBuffer();
|
|
53
53
|
if (await this.cli.confirm(`${filesToUpload.length} Module(s) will be uploaded now. Proceed?`)) {
|
|
54
54
|
for (let iterator = 0; iterator < files.length; iterator++) {
|
|
55
|
-
|
|
55
|
+
const file = files[iterator];
|
|
56
56
|
await this.configApi.setModule(file.getContent(), file.name);
|
|
57
57
|
for (let iterator = 0; iterator < this.modifiers.length; iterator++) {
|
|
58
|
-
|
|
58
|
+
const modifier = this.modifiers[iterator];
|
|
59
59
|
if (modifier.canModify(file)) {
|
|
60
60
|
modifier.revert(file);
|
|
61
61
|
}
|
|
@@ -64,7 +64,7 @@ class ModuleHandler {
|
|
|
64
64
|
}
|
|
65
65
|
}
|
|
66
66
|
async confirm(file, isNew = false) {
|
|
67
|
-
const confirm = await this.cli.confirm(`${isNew ?
|
|
67
|
+
const confirm = await this.cli.confirm(`${isNew ? "Create" : "Update"} ${file.name}?`);
|
|
68
68
|
if (!confirm) {
|
|
69
69
|
file.skipFile();
|
|
70
70
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const FILE =
|
|
4
|
-
const SLACK_TOKEN_PLACEHOLDER =
|
|
3
|
+
const FILE = "deploymentDetection";
|
|
4
|
+
const SLACK_TOKEN_PLACEHOLDER = "<1Password deployment token>";
|
|
5
5
|
class DeploymentDetectionModifier {
|
|
6
6
|
slackToken;
|
|
7
7
|
constructor(slackToken) {
|
|
@@ -15,8 +15,8 @@ class ServerConfigHandler {
|
|
|
15
15
|
return type === server_config_file_1.default;
|
|
16
16
|
}
|
|
17
17
|
async handle(files) {
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
const file = files[0];
|
|
19
|
+
const remote = await this.configApi.getServerConfig();
|
|
20
20
|
if (!remote) {
|
|
21
21
|
this.cli.writeError(`${file.name} could not be found on remote`);
|
|
22
22
|
await this.confirm(file, true);
|
|
@@ -38,8 +38,8 @@ class ServerConfigHandler {
|
|
|
38
38
|
if (file.shouldSkipFile()) {
|
|
39
39
|
return;
|
|
40
40
|
}
|
|
41
|
-
this.cli.write(
|
|
42
|
-
this.cli.write(
|
|
41
|
+
this.cli.write("");
|
|
42
|
+
this.cli.write("Summary");
|
|
43
43
|
this.cli.writeBuffer();
|
|
44
44
|
if (await this.cli.confirm(`ServerConfig will be uploaded now. Proceed?`)) {
|
|
45
45
|
await this.configApi.setServerConfig(file.getContent(), file.config.revision.version);
|