@slack/bolt 4.0.0-nextGen.7 → 4.0.0-nextGen.8
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@slack/bolt",
|
|
3
|
-
"version": "4.0.0-nextGen.
|
|
3
|
+
"version": "4.0.0-nextGen.8",
|
|
4
4
|
"description": "A framework for building Slack apps, fast.",
|
|
5
5
|
"author": "Slack Technologies, LLC",
|
|
6
6
|
"license": "MIT",
|
|
@@ -41,7 +41,8 @@
|
|
|
41
41
|
"slack-cli-start": "./src/cli/start.js",
|
|
42
42
|
"slack-cli-hook-utils": "./src/cli/hook-utils/manifest.js",
|
|
43
43
|
"slack-cli-hook-utils-get-manifest-data": "./src/cli/hook-utils/get-manifest-data.js",
|
|
44
|
-
"slack-cli-check-update": "./src/cli/check-update.js"
|
|
44
|
+
"slack-cli-check-update": "./src/cli/check-update.js",
|
|
45
|
+
"slack-cli-hook-utils-get-check-update-data": "./src/cli/hook-utils/get-check-update-data.js"
|
|
45
46
|
},
|
|
46
47
|
"repository": "slackapi/bolt",
|
|
47
48
|
"homepage": "https://slack.dev/bolt-js",
|
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const util = require('util');
|
|
4
|
+
const exec = util.promisify(require('child_process').exec);
|
|
5
|
+
|
|
6
|
+
const SLACK_BOLT_SDK = '@slack/bolt';
|
|
7
|
+
let checkUpdateExports = {};
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Wraps and parses the output of the exec() function
|
|
11
|
+
* @param command the command being run by the exec() function
|
|
12
|
+
*/
|
|
13
|
+
async function execWrapper (command) {
|
|
14
|
+
const { stdout } = await exec(command);
|
|
15
|
+
return stdout.trim();
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Checks for available SDK updates for specified dependencies, creates a version map,
|
|
20
|
+
* and then wraps everything up into a response to be passed to the CLI.
|
|
21
|
+
* @param cwd the current working directory
|
|
22
|
+
*/
|
|
23
|
+
async function checkForSDKUpdates(cwd) {
|
|
24
|
+
const { versionMap, inaccessibleFiles } = await createVersionMap(cwd);
|
|
25
|
+
const updateResp = createUpdateResp(versionMap, inaccessibleFiles);
|
|
26
|
+
return updateResp;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Create a version map that contains each (Slack) dependency, detailing info about
|
|
31
|
+
* current and latest versions, as well as if breaking changes are present or if there
|
|
32
|
+
* were any errors with getting version retrieval.
|
|
33
|
+
* @param cwd the current working directory of the CLI project
|
|
34
|
+
*/
|
|
35
|
+
async function createVersionMap(cwd) {
|
|
36
|
+
const { versionMap, inaccessibleFiles } = await readProjectDependencies(cwd);
|
|
37
|
+
|
|
38
|
+
if (versionMap && versionMap[SLACK_BOLT_SDK]) {
|
|
39
|
+
const current = versionMap[SLACK_BOLT_SDK].current || '';
|
|
40
|
+
let latest = '',
|
|
41
|
+
error = null;
|
|
42
|
+
|
|
43
|
+
try {
|
|
44
|
+
latest = await fetchLatestModuleVersion(SLACK_BOLT_SDK);
|
|
45
|
+
} catch (err) {
|
|
46
|
+
error = err;
|
|
47
|
+
}
|
|
48
|
+
const update = !!current && !!latest && current !== latest;
|
|
49
|
+
const breaking = hasBreakingChange(current, latest);
|
|
50
|
+
|
|
51
|
+
versionMap[SLACK_BOLT_SDK] = {
|
|
52
|
+
...versionMap[SLACK_BOLT_SDK],
|
|
53
|
+
latest,
|
|
54
|
+
update,
|
|
55
|
+
breaking,
|
|
56
|
+
error,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return { versionMap, inaccessibleFiles };
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Reads project dependencies - cycles through project dependency files, extracts
|
|
65
|
+
* the listed dependencies, and adds it in to the version map with version info.
|
|
66
|
+
* @param cwd the current working directory of the CLI project
|
|
67
|
+
*/
|
|
68
|
+
async function readProjectDependencies(cwd) {
|
|
69
|
+
const versionMap = {};
|
|
70
|
+
const { dependencyFile, inaccessibleFiles } = await gatherDependencyFiles(
|
|
71
|
+
cwd
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
try {
|
|
75
|
+
const [sdk, value] =
|
|
76
|
+
await checkUpdateExports.extractDependencies(dependencyFile.body, dependencyFile.name);
|
|
77
|
+
|
|
78
|
+
if (sdk !== '' && sdk === SLACK_BOLT_SDK) {
|
|
79
|
+
versionMap[SLACK_BOLT_SDK] = {
|
|
80
|
+
name: sdk,
|
|
81
|
+
current: value.version,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
} catch (err) {
|
|
85
|
+
inaccessibleFiles.push({ name: dependencyFile.name, error: err });
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return { versionMap, inaccessibleFiles };
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Reads and parses JSON file - if it works, returns the file contents.
|
|
93
|
+
* If not, returns an empty object
|
|
94
|
+
* @param filePath the path of the file being read
|
|
95
|
+
*/
|
|
96
|
+
async function getJSON(filePath) {
|
|
97
|
+
let fileContents = {};
|
|
98
|
+
try {
|
|
99
|
+
if (fs.existsSync(filePath)) {
|
|
100
|
+
fileContents = JSON.parse(fs.readFileSync(filePath, 'utf8'));
|
|
101
|
+
} else {
|
|
102
|
+
throw new Error('Cannot find a file at path ' + filePath);
|
|
103
|
+
}
|
|
104
|
+
} catch (err) {
|
|
105
|
+
throw new Error(err);
|
|
106
|
+
}
|
|
107
|
+
return fileContents;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Gathers all related dependency files for the CLI project (package.json).
|
|
112
|
+
* @param cwd the current working directory of the CLI project
|
|
113
|
+
*/
|
|
114
|
+
async function gatherDependencyFiles(cwd) {
|
|
115
|
+
const { jsonDepFile, inaccessibleFiles } = await getJSONFiles(cwd);
|
|
116
|
+
const dependencyFile = jsonDepFile;
|
|
117
|
+
return { dependencyFile, inaccessibleFiles };
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Gets the needed files that contain dependency info (package.json).
|
|
122
|
+
* @param cwd the current working directory of the CLI project
|
|
123
|
+
*/
|
|
124
|
+
async function getJSONFiles(cwd) {
|
|
125
|
+
const packageJSON = 'package.json';
|
|
126
|
+
const jsonDepFile = {};
|
|
127
|
+
const inaccessibleFiles = [];
|
|
128
|
+
|
|
129
|
+
try {
|
|
130
|
+
const jsonFile = await getJSON(`${cwd}/${packageJSON}`);
|
|
131
|
+
const jsonIsParsable =
|
|
132
|
+
jsonFile &&
|
|
133
|
+
typeof jsonFile === 'object' &&
|
|
134
|
+
!Array.isArray(jsonFile) &&
|
|
135
|
+
jsonFile.dependencies;
|
|
136
|
+
|
|
137
|
+
if (jsonIsParsable) {
|
|
138
|
+
jsonDepFile.name = packageJSON;
|
|
139
|
+
jsonDepFile.body= jsonFile;
|
|
140
|
+
}
|
|
141
|
+
} catch (err) {
|
|
142
|
+
inaccessibleFiles.push({ name: packageJSON, error: err });
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
return { jsonDepFile, inaccessibleFiles };
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Pulls dependencies from a given file and JSON structure.
|
|
150
|
+
* @param json JSON information that includes dependencies
|
|
151
|
+
* @param fileName name of the file that the dependency list is coming from
|
|
152
|
+
*/
|
|
153
|
+
checkUpdateExports.extractDependencies = async (json, fileName) => {
|
|
154
|
+
// Determine if the JSON passed is an object
|
|
155
|
+
const jsonIsParsable =
|
|
156
|
+
json !== null && typeof json === 'object' && !Array.isArray(json);
|
|
157
|
+
|
|
158
|
+
if (jsonIsParsable) {
|
|
159
|
+
let boltCurrentVersion = '';
|
|
160
|
+
if (json['dependencies']['@slack/bolt']) {
|
|
161
|
+
const boltCurrentVersionOutput = JSON.parse(
|
|
162
|
+
await checkUpdateExports.getBoltCurrentVersion()
|
|
163
|
+
);
|
|
164
|
+
|
|
165
|
+
if (boltCurrentVersionOutput !== '') {
|
|
166
|
+
boltCurrentVersion =
|
|
167
|
+
boltCurrentVersionOutput['dependencies']['@slack/bolt']['version'];
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
return [
|
|
172
|
+
'@slack/bolt',
|
|
173
|
+
{
|
|
174
|
+
version: boltCurrentVersion,
|
|
175
|
+
},
|
|
176
|
+
];
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
return [];
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Gets the latest module version.
|
|
184
|
+
* @param moduleName the module that the latest version is being queried for
|
|
185
|
+
*/
|
|
186
|
+
async function fetchLatestModuleVersion(moduleName) {
|
|
187
|
+
let command = '';
|
|
188
|
+
if (moduleName === '@slack/bolt') {
|
|
189
|
+
command = `npm info ${moduleName} version --tag next-gen`;
|
|
190
|
+
} else if (moduleName === '@slack/deno-slack-sdk') {
|
|
191
|
+
command = `npm info ${moduleName} version --tag latest`;
|
|
192
|
+
}
|
|
193
|
+
const stdout = await execWrapper(command);
|
|
194
|
+
|
|
195
|
+
return stdout;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Checks if a dependency's upgrade from a current to the latest version will cause a
|
|
200
|
+
* breaking change.
|
|
201
|
+
* @param current current dependency version in project
|
|
202
|
+
* @param latest most up-to-date dependency version available on NPM
|
|
203
|
+
*/
|
|
204
|
+
function hasBreakingChange(current, latest) {
|
|
205
|
+
return current !== latest;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Creates the update response - returns an object in the expected response format.
|
|
210
|
+
* @param versionMap version map of checked dependencies, current versions, and info on upgrade + breaking changes
|
|
211
|
+
* @param inaccessibleFiles array of files that could not be read or accessed
|
|
212
|
+
*/
|
|
213
|
+
function createUpdateResp(versionMap, inaccessibleFiles) {
|
|
214
|
+
const name = 'the Slack SDK';
|
|
215
|
+
const releases = [];
|
|
216
|
+
const url = 'https://api.slack.com/future/changelog';
|
|
217
|
+
const fileErrorMsg = createFileErrorMsg(inaccessibleFiles);
|
|
218
|
+
|
|
219
|
+
let error = null;
|
|
220
|
+
let errorMsg = '';
|
|
221
|
+
let message = '';
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
// Output information for each dependency
|
|
225
|
+
for (const sdk of Object.values(versionMap)) {
|
|
226
|
+
// Dependency has an update OR the fetch of update failed
|
|
227
|
+
if (sdk) {
|
|
228
|
+
releases.push(sdk);
|
|
229
|
+
|
|
230
|
+
// Add the dependency that failed to be fetched to the top-level error message
|
|
231
|
+
if (sdk.error && sdk.error.message) {
|
|
232
|
+
errorMsg += errorMsg
|
|
233
|
+
? `, ${sdk}`
|
|
234
|
+
: `An error occurred fetching updates for the following packages: ${sdk.name}`;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
// Surface release notes for breaking changes
|
|
240
|
+
if (releases && releases[0] && releases[0].breaking) {
|
|
241
|
+
message = `Learn more about the breaking change at https://github.com/slackapi/bolt-js/releases/tag/@slack/bolt@${releases[0].latest}`
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// If there were issues accessing dependency files, append error message(s)
|
|
245
|
+
if (inaccessibleFiles.length) {
|
|
246
|
+
errorMsg += errorMsg ? `\n\n ${fileErrorMsg}` : fileErrorMsg;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
if (errorMsg) {
|
|
250
|
+
error = { message: errorMsg };
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
return {
|
|
254
|
+
name,
|
|
255
|
+
message,
|
|
256
|
+
releases,
|
|
257
|
+
url,
|
|
258
|
+
error,
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Returns error when dependency files cannot be read.
|
|
264
|
+
* @param inaccessibleFiles array of files that could not be read or accessed
|
|
265
|
+
*/
|
|
266
|
+
function createFileErrorMsg(inaccessibleFiles) {
|
|
267
|
+
let fileErrorMsg = '';
|
|
268
|
+
|
|
269
|
+
// There were issues with reading some of the files that were found
|
|
270
|
+
for (const file of inaccessibleFiles) {
|
|
271
|
+
fileErrorMsg += fileErrorMsg
|
|
272
|
+
? `\n ${file.name}: ${file.error.message}`
|
|
273
|
+
: `An error occurred while reading the following files: \n\n ${file.name}: ${file.error.message}`;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
return fileErrorMsg;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* Queries for current Bolt version of the project.
|
|
281
|
+
*/
|
|
282
|
+
checkUpdateExports.getBoltCurrentVersion = async () => {
|
|
283
|
+
const stdout = await execWrapper('npm list @slack/bolt --depth=0 --json');
|
|
284
|
+
return stdout;
|
|
285
|
+
};
|
|
286
|
+
|
|
287
|
+
module.exports = {
|
|
288
|
+
checkForSDKUpdates,
|
|
289
|
+
getJSON,
|
|
290
|
+
getJSONFiles,
|
|
291
|
+
checkUpdateExports,
|
|
292
|
+
};
|