@vercel/slack-bolt 1.3.1 → 1.4.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/README.md +84 -8
- package/dist/cli.d.mts +1 -1
- package/dist/cli.d.ts +1 -1
- package/dist/cli.js +357 -507
- package/dist/cli.js.map +1 -1
- package/dist/cli.mjs +385 -497
- package/dist/cli.mjs.map +1 -1
- package/dist/index.d.mts +181 -90
- package/dist/index.d.ts +181 -90
- package/dist/index.js +491 -367
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +489 -365
- package/dist/index.mjs.map +1 -1
- package/dist/preview-DAWKwXt1.mjs +689 -0
- package/dist/preview-DAWKwXt1.mjs.map +1 -0
- package/dist/preview-DeqpNNn_.js +794 -0
- package/dist/preview-DeqpNNn_.js.map +1 -0
- package/dist/preview.d.mts +47 -44
- package/dist/preview.d.ts +47 -44
- package/dist/preview.js +3 -13
- package/dist/preview.mjs +2 -6
- package/package.json +9 -8
- package/dist/chunk-B5E7QPZP.mjs +0 -11
- package/dist/chunk-B5E7QPZP.mjs.map +0 -1
- package/dist/chunk-F7WJK2MS.mjs +0 -980
- package/dist/chunk-F7WJK2MS.mjs.map +0 -1
- package/dist/chunk-QHMZVK6J.js +0 -14
- package/dist/chunk-QHMZVK6J.js.map +0 -1
- package/dist/chunk-VI33CCYY.js +0 -1003
- package/dist/chunk-VI33CCYY.js.map +0 -1
- package/dist/preview.js.map +0 -1
- package/dist/preview.mjs.map +0 -1
package/dist/cli.mjs
CHANGED
|
@@ -1,518 +1,406 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
-
|
|
8
|
-
|
|
2
|
+
import { _ as deleteSlackApp, a as log, b as __commonJSMin, c as cancelDeployment, d as getActiveBranches, f as getEnvironmentVariable, g as authTest, h as init_vercel, i as init_logger, l as createDeployment, m as getProject, n as preview, o as startMessage, p as getEnvironmentVariables, r as enableFetchDebugLogging, s as addEnvironmentVariables, t as init_preview, u as deleteEnvironmentVariable, v as init_slack, x as __esmMin, y as rotateConfigToken } from "./preview-DAWKwXt1.mjs";
|
|
3
|
+
import fs from "node:fs";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import { Command } from "commander";
|
|
6
|
+
import { z } from "zod";
|
|
7
|
+
//#region src/internal/schemas.ts
|
|
9
8
|
function formatMissingKeys(error) {
|
|
10
|
-
|
|
9
|
+
return error.issues.map((i) => i.path.join(".")).join(", ");
|
|
11
10
|
}
|
|
12
11
|
function validateAndBuildParams(env) {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
commitMessage: systemResult.data.VERCEL_GIT_COMMIT_MESSAGE,
|
|
47
|
-
commitAuthor: systemResult.data.VERCEL_GIT_COMMIT_AUTHOR_LOGIN,
|
|
48
|
-
deploymentId: systemResult.data.VERCEL_DEPLOYMENT_ID,
|
|
49
|
-
automationBypassSecret: systemResult.data.VERCEL_AUTOMATION_BYPASS_SECRET,
|
|
50
|
-
slackAppId: slackResult.data.SLACK_APP_ID,
|
|
51
|
-
slackConfigurationToken: slackResult.data.SLACK_CONFIGURATION_TOKEN,
|
|
52
|
-
slackConfigRefreshToken: slackResult.data.SLACK_CONFIG_REFRESH_TOKEN,
|
|
53
|
-
slackServiceToken: slackResult.data.SLACK_SERVICE_TOKEN,
|
|
54
|
-
manifestPath: slackResult.data.MANIFEST_PATH,
|
|
55
|
-
vercelApiToken: vercelResult.data.VERCEL_API_TOKEN
|
|
56
|
-
};
|
|
12
|
+
const systemResult = systemEnvSchema.safeParse(env);
|
|
13
|
+
if (!systemResult.success) {
|
|
14
|
+
const missing = formatMissingKeys(systemResult.error);
|
|
15
|
+
throw new Error(`Missing Vercel system environment variables: ${missing}\nEnable 'Automatically expose System Environment Variables' in your Vercel project settings:\nhttps://vercel.com/docs/projects/environment-variables/system-environment-variables`);
|
|
16
|
+
}
|
|
17
|
+
const slackResult = slackEnvSchema.safeParse(env);
|
|
18
|
+
if (!slackResult.success) {
|
|
19
|
+
const missing = formatMissingKeys(slackResult.error);
|
|
20
|
+
throw new Error(`Missing Slack environment variables: ${missing}\nAdd them as environment variables in your Vercel project.`);
|
|
21
|
+
}
|
|
22
|
+
const vercelResult = vercelEnvSchema.safeParse(env);
|
|
23
|
+
if (!vercelResult.success) {
|
|
24
|
+
const missing = formatMissingKeys(vercelResult.error);
|
|
25
|
+
throw new Error(`Missing Vercel environment variables: ${missing}\nCreate a new token and add it as VERCEL_API_TOKEN in your Vercel project:\nhttps://vercel.com/account/settings/tokens`);
|
|
26
|
+
}
|
|
27
|
+
return {
|
|
28
|
+
branch: systemResult.data.VERCEL_GIT_COMMIT_REF,
|
|
29
|
+
projectId: systemResult.data.VERCEL_PROJECT_ID,
|
|
30
|
+
deploymentUrl: systemResult.data.VERCEL_URL,
|
|
31
|
+
branchUrl: systemResult.data.VERCEL_BRANCH_URL,
|
|
32
|
+
teamId: systemResult.data.VERCEL_TEAM_ID,
|
|
33
|
+
commitSha: systemResult.data.VERCEL_GIT_COMMIT_SHA,
|
|
34
|
+
commitMessage: systemResult.data.VERCEL_GIT_COMMIT_MESSAGE,
|
|
35
|
+
commitAuthor: systemResult.data.VERCEL_GIT_COMMIT_AUTHOR_LOGIN,
|
|
36
|
+
deploymentId: systemResult.data.VERCEL_DEPLOYMENT_ID,
|
|
37
|
+
automationBypassSecret: systemResult.data.VERCEL_AUTOMATION_BYPASS_SECRET,
|
|
38
|
+
slackAppId: slackResult.data.SLACK_APP_ID,
|
|
39
|
+
slackConfigurationToken: slackResult.data.SLACK_CONFIGURATION_TOKEN,
|
|
40
|
+
slackConfigRefreshToken: slackResult.data.SLACK_CONFIG_REFRESH_TOKEN,
|
|
41
|
+
slackServiceToken: slackResult.data.SLACK_SERVICE_TOKEN,
|
|
42
|
+
manifestPath: slackResult.data.MANIFEST_PATH,
|
|
43
|
+
vercelApiToken: vercelResult.data.VERCEL_API_TOKEN
|
|
44
|
+
};
|
|
57
45
|
}
|
|
58
46
|
var systemEnvSchema, slackEnvSchema, vercelEnvSchema;
|
|
59
|
-
var init_schemas =
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
async function cleanupOrphanedApps({
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
} else {
|
|
142
|
-
log.warning(`Failed to delete app ${appId}: ${msg}`);
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
for (const env of envs) {
|
|
147
|
-
if (env.id && env.gitBranch === branch && SLACK_ENV_VAR_KEYS.includes(env.key)) {
|
|
148
|
-
try {
|
|
149
|
-
await deleteEnvironmentVariable({
|
|
150
|
-
projectId,
|
|
151
|
-
envId: env.id,
|
|
152
|
-
token: vercelApiToken,
|
|
153
|
-
teamId
|
|
154
|
-
});
|
|
155
|
-
} catch (error) {
|
|
156
|
-
log.warning(
|
|
157
|
-
`Failed to delete env var ${env.key} for branch ${branch}: ${error instanceof Error ? error.message : error}`
|
|
158
|
-
);
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
log.success("Orphan cleanup completed");
|
|
47
|
+
var init_schemas = __esmMin((() => {
|
|
48
|
+
systemEnvSchema = z.object({
|
|
49
|
+
VERCEL_ENV: z.enum([
|
|
50
|
+
"production",
|
|
51
|
+
"preview",
|
|
52
|
+
"development"
|
|
53
|
+
]),
|
|
54
|
+
VERCEL_GIT_COMMIT_REF: z.string(),
|
|
55
|
+
VERCEL_PROJECT_ID: z.string(),
|
|
56
|
+
VERCEL_URL: z.string(),
|
|
57
|
+
VERCEL_BRANCH_URL: z.string().optional(),
|
|
58
|
+
VERCEL_TEAM_ID: z.string().optional(),
|
|
59
|
+
VERCEL_GIT_COMMIT_SHA: z.string().optional(),
|
|
60
|
+
VERCEL_GIT_COMMIT_MESSAGE: z.string().optional(),
|
|
61
|
+
VERCEL_GIT_COMMIT_AUTHOR_LOGIN: z.string().optional(),
|
|
62
|
+
VERCEL_DEPLOYMENT_ID: z.string().optional(),
|
|
63
|
+
VERCEL_AUTOMATION_BYPASS_SECRET: z.string().optional()
|
|
64
|
+
});
|
|
65
|
+
slackEnvSchema = z.object({
|
|
66
|
+
SLACK_APP_ID: z.string().optional(),
|
|
67
|
+
SLACK_CONFIGURATION_TOKEN: z.string(),
|
|
68
|
+
SLACK_SERVICE_TOKEN: z.string().optional(),
|
|
69
|
+
SLACK_CONFIG_REFRESH_TOKEN: z.string().optional(),
|
|
70
|
+
MANIFEST_PATH: z.string().default("manifest.json")
|
|
71
|
+
});
|
|
72
|
+
vercelEnvSchema = z.object({ VERCEL_API_TOKEN: z.string() });
|
|
73
|
+
}));
|
|
74
|
+
//#endregion
|
|
75
|
+
//#region src/cleanup.ts
|
|
76
|
+
async function cleanupOrphanedApps({ projectId, currentBranch, vercelApiToken, teamId, slackConfigurationToken }) {
|
|
77
|
+
const activeBranches = await getActiveBranches({
|
|
78
|
+
projectId,
|
|
79
|
+
token: vercelApiToken,
|
|
80
|
+
teamId
|
|
81
|
+
});
|
|
82
|
+
const envs = await getEnvironmentVariables({
|
|
83
|
+
projectId,
|
|
84
|
+
token: vercelApiToken,
|
|
85
|
+
teamId
|
|
86
|
+
});
|
|
87
|
+
const staleBranches = /* @__PURE__ */ new Map();
|
|
88
|
+
for (const env of envs) if (env.key === "SLACK_APP_ID" && env.gitBranch && env.gitBranch !== currentBranch && !activeBranches.has(env.gitBranch)) staleBranches.set(env.gitBranch, env.id);
|
|
89
|
+
if (staleBranches.size === 0) {
|
|
90
|
+
log.info("No orphaned preview apps found");
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
log.step(`Found ${staleBranches.size} orphaned ${staleBranches.size === 1 ? "branch" : "branches"}`);
|
|
94
|
+
for (const [branch, envId] of staleBranches) {
|
|
95
|
+
let appId = null;
|
|
96
|
+
try {
|
|
97
|
+
appId = await getEnvironmentVariable({
|
|
98
|
+
projectId,
|
|
99
|
+
envId,
|
|
100
|
+
token: vercelApiToken,
|
|
101
|
+
teamId
|
|
102
|
+
});
|
|
103
|
+
} catch {
|
|
104
|
+
log.warning(`Failed to decrypt SLACK_APP_ID for branch ${branch}`);
|
|
105
|
+
}
|
|
106
|
+
if (appId) try {
|
|
107
|
+
await deleteSlackApp({
|
|
108
|
+
token: slackConfigurationToken,
|
|
109
|
+
appId
|
|
110
|
+
});
|
|
111
|
+
log.info(`${appId} deleted (branch: ${branch})`);
|
|
112
|
+
} catch (error) {
|
|
113
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
114
|
+
if (msg.includes("app_not_found")) log.info(`${appId} already deleted (branch: ${branch})`);
|
|
115
|
+
else log.warning(`Failed to delete app ${appId}: ${msg}`);
|
|
116
|
+
}
|
|
117
|
+
for (const env of envs) if (env.id && env.gitBranch === branch && SLACK_ENV_VAR_KEYS.includes(env.key)) try {
|
|
118
|
+
await deleteEnvironmentVariable({
|
|
119
|
+
projectId,
|
|
120
|
+
envId: env.id,
|
|
121
|
+
token: vercelApiToken,
|
|
122
|
+
teamId
|
|
123
|
+
});
|
|
124
|
+
} catch (error) {
|
|
125
|
+
log.warning(`Failed to delete env var ${env.key} for branch ${branch}: ${error instanceof Error ? error.message : error}`);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
log.success("Orphan cleanup completed");
|
|
164
129
|
}
|
|
165
130
|
var SLACK_ENV_VAR_KEYS;
|
|
166
|
-
var init_cleanup =
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
131
|
+
var init_cleanup = __esmMin((() => {
|
|
132
|
+
init_slack();
|
|
133
|
+
init_vercel();
|
|
134
|
+
init_logger();
|
|
135
|
+
SLACK_ENV_VAR_KEYS = [
|
|
136
|
+
"SLACK_APP_ID",
|
|
137
|
+
"SLACK_CLIENT_ID",
|
|
138
|
+
"SLACK_CLIENT_SECRET",
|
|
139
|
+
"SLACK_SIGNING_SECRET",
|
|
140
|
+
"SLACK_BOT_TOKEN"
|
|
141
|
+
];
|
|
142
|
+
}));
|
|
143
|
+
//#endregion
|
|
144
|
+
//#region src/cli/build.ts
|
|
180
145
|
async function executeBuild(params, options) {
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
currentBranch: params.branch,
|
|
270
|
-
vercelApiToken: params.vercelApiToken,
|
|
271
|
-
teamId: params.teamId,
|
|
272
|
-
slackConfigurationToken: params.slackConfigurationToken
|
|
273
|
-
});
|
|
274
|
-
} catch (error) {
|
|
275
|
-
log.warning(
|
|
276
|
-
`Orphan cleanup failed: ${error instanceof Error ? error.message : error}`
|
|
277
|
-
);
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
|
-
const result = await preview(params, "cli");
|
|
281
|
-
if (result.isNew && params.deploymentId) {
|
|
282
|
-
log.step("Creating new deployment to pick up new environment variables");
|
|
283
|
-
const { id, url } = await createDeployment({
|
|
284
|
-
deploymentId: params.deploymentId,
|
|
285
|
-
projectId: params.projectId,
|
|
286
|
-
token: params.vercelApiToken,
|
|
287
|
-
teamId: params.teamId
|
|
288
|
-
});
|
|
289
|
-
log.success(`New deployment created: ${url} (${id})`);
|
|
290
|
-
log.step("Cancelling current deployment");
|
|
291
|
-
await cancelDeployment({
|
|
292
|
-
deploymentId: params.deploymentId,
|
|
293
|
-
token: params.vercelApiToken,
|
|
294
|
-
teamId: params.teamId
|
|
295
|
-
});
|
|
296
|
-
}
|
|
146
|
+
if (!params.slackConfigurationToken) throw new Error("Slack Configuration Token is not set. Generate a configuration token and add it as SLACK_CONFIGURATION_TOKEN in your Vercel project:\nhttps://api.slack.com/apps");
|
|
147
|
+
try {
|
|
148
|
+
await authTest({ token: params.slackConfigurationToken });
|
|
149
|
+
} catch (error) {
|
|
150
|
+
if (!params.slackConfigRefreshToken) throw new Error("Slack configuration token is invalid or expired. Provide SLACK_CONFIG_REFRESH_TOKEN for automatic rotation, or generate a new token:\nhttps://api.slack.com/apps", { cause: error });
|
|
151
|
+
log.step("Refreshing SLACK_CONFIGURATION_TOKEN");
|
|
152
|
+
try {
|
|
153
|
+
const rotated = await rotateConfigToken({ refreshToken: params.slackConfigRefreshToken });
|
|
154
|
+
params.slackConfigurationToken = rotated.token;
|
|
155
|
+
params.slackConfigRefreshToken = rotated.refreshToken;
|
|
156
|
+
await addEnvironmentVariables({
|
|
157
|
+
projectId: params.projectId,
|
|
158
|
+
token: params.vercelApiToken,
|
|
159
|
+
teamId: params.teamId,
|
|
160
|
+
envs: [{
|
|
161
|
+
key: "SLACK_CONFIGURATION_TOKEN",
|
|
162
|
+
value: rotated.token,
|
|
163
|
+
type: "encrypted",
|
|
164
|
+
target: [
|
|
165
|
+
"production",
|
|
166
|
+
"preview",
|
|
167
|
+
"development"
|
|
168
|
+
]
|
|
169
|
+
}, {
|
|
170
|
+
key: "SLACK_CONFIG_REFRESH_TOKEN",
|
|
171
|
+
value: rotated.refreshToken,
|
|
172
|
+
type: "encrypted",
|
|
173
|
+
target: [
|
|
174
|
+
"production",
|
|
175
|
+
"preview",
|
|
176
|
+
"development"
|
|
177
|
+
]
|
|
178
|
+
}]
|
|
179
|
+
});
|
|
180
|
+
log.success("Configuration token rotated and persisted");
|
|
181
|
+
} catch (rotateError) {
|
|
182
|
+
throw new Error("Failed to rotate configuration token — refresh token may be invalid. Generate new tokens:\nhttps://api.slack.com/apps", { cause: rotateError });
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
if (params.slackServiceToken) try {
|
|
186
|
+
await authTest({ token: params.slackServiceToken });
|
|
187
|
+
} catch (error) {
|
|
188
|
+
log.warning("SLACK_SERVICE_TOKEN is invalid — app must be installed manually");
|
|
189
|
+
log.info("https://docs.slack.dev/authentication/tokens/#service");
|
|
190
|
+
log.debug(error);
|
|
191
|
+
}
|
|
192
|
+
if (!params.branch) throw new Error("VERCEL_GIT_COMMIT_REF is not set — connect your Git repository in your Vercel project settings.\nhttps://vercel.com/docs/git");
|
|
193
|
+
try {
|
|
194
|
+
await getProject({
|
|
195
|
+
projectId: params.projectId,
|
|
196
|
+
token: params.vercelApiToken,
|
|
197
|
+
teamId: params.teamId
|
|
198
|
+
});
|
|
199
|
+
} catch (error) {
|
|
200
|
+
throw new Error("Vercel API token cannot access this project. Ensure VERCEL_API_TOKEN is valid and has access to this team:\nhttps://vercel.com/account/settings/tokens", { cause: error });
|
|
201
|
+
}
|
|
202
|
+
const manifestFullPath = path.join(process.cwd(), params.manifestPath);
|
|
203
|
+
if (!fs.existsSync(manifestFullPath)) throw new Error(`No manifest found at ${params.manifestPath}. Create a manifest.json (or manifest.yaml) file with your Slack app configuration:\nhttps://docs.slack.dev/reference/manifests`);
|
|
204
|
+
if (options?.cleanup) {
|
|
205
|
+
log.step("Cleaning up orphaned preview apps");
|
|
206
|
+
try {
|
|
207
|
+
await cleanupOrphanedApps({
|
|
208
|
+
projectId: params.projectId,
|
|
209
|
+
currentBranch: params.branch,
|
|
210
|
+
vercelApiToken: params.vercelApiToken,
|
|
211
|
+
teamId: params.teamId,
|
|
212
|
+
slackConfigurationToken: params.slackConfigurationToken
|
|
213
|
+
});
|
|
214
|
+
} catch (error) {
|
|
215
|
+
log.warning(`Orphan cleanup failed: ${error instanceof Error ? error.message : error}`);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
if ((await preview(params, "cli")).isNew && params.deploymentId) {
|
|
219
|
+
log.step("Creating new deployment to pick up new environment variables");
|
|
220
|
+
const { id, url } = await createDeployment({
|
|
221
|
+
deploymentId: params.deploymentId,
|
|
222
|
+
projectId: params.projectId,
|
|
223
|
+
token: params.vercelApiToken,
|
|
224
|
+
teamId: params.teamId
|
|
225
|
+
});
|
|
226
|
+
log.success(`New deployment created: ${url} (${id})`);
|
|
227
|
+
log.step("Cancelling current deployment");
|
|
228
|
+
await cancelDeployment({
|
|
229
|
+
deploymentId: params.deploymentId,
|
|
230
|
+
token: params.vercelApiToken,
|
|
231
|
+
teamId: params.teamId
|
|
232
|
+
});
|
|
233
|
+
}
|
|
297
234
|
}
|
|
298
|
-
var init_build =
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
// src/cli/env.ts
|
|
235
|
+
var init_build = __esmMin((() => {
|
|
236
|
+
init_cleanup();
|
|
237
|
+
init_slack();
|
|
238
|
+
init_vercel();
|
|
239
|
+
init_logger();
|
|
240
|
+
init_preview();
|
|
241
|
+
}));
|
|
242
|
+
//#endregion
|
|
243
|
+
//#region src/cli/env.ts
|
|
309
244
|
function envKeyToFlag(key) {
|
|
310
|
-
|
|
245
|
+
return key.toLowerCase().replace(/_/g, "-");
|
|
311
246
|
}
|
|
312
247
|
function flagToCamelCase(flag) {
|
|
313
|
-
|
|
248
|
+
return flag.replace(/-([a-z])/g, (_, c) => c.toUpperCase());
|
|
314
249
|
}
|
|
315
250
|
function resolveEnv(options) {
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
251
|
+
const overrides = {};
|
|
252
|
+
for (const key of ENV_KEYS) {
|
|
253
|
+
const value = options[flagToCamelCase(envKeyToFlag(key))];
|
|
254
|
+
if (typeof value === "string") overrides[key] = value;
|
|
255
|
+
}
|
|
256
|
+
return {
|
|
257
|
+
...process.env,
|
|
258
|
+
...overrides
|
|
259
|
+
};
|
|
325
260
|
}
|
|
326
261
|
var ENV_KEYS;
|
|
327
|
-
var init_env =
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
262
|
+
var init_env = __esmMin((() => {
|
|
263
|
+
ENV_KEYS = [
|
|
264
|
+
"VERCEL_ENV",
|
|
265
|
+
"VERCEL_GIT_COMMIT_REF",
|
|
266
|
+
"VERCEL_PROJECT_ID",
|
|
267
|
+
"VERCEL_URL",
|
|
268
|
+
"VERCEL_BRANCH_URL",
|
|
269
|
+
"VERCEL_TEAM_ID",
|
|
270
|
+
"VERCEL_GIT_COMMIT_SHA",
|
|
271
|
+
"VERCEL_GIT_COMMIT_MESSAGE",
|
|
272
|
+
"VERCEL_GIT_COMMIT_AUTHOR_LOGIN",
|
|
273
|
+
"VERCEL_DEPLOYMENT_ID",
|
|
274
|
+
"VERCEL_AUTOMATION_BYPASS_SECRET",
|
|
275
|
+
"SLACK_APP_ID",
|
|
276
|
+
"SLACK_CONFIGURATION_TOKEN",
|
|
277
|
+
"SLACK_SERVICE_TOKEN",
|
|
278
|
+
"SLACK_CONFIG_REFRESH_TOKEN",
|
|
279
|
+
"MANIFEST_PATH",
|
|
280
|
+
"VERCEL_API_TOKEN"
|
|
281
|
+
];
|
|
282
|
+
}));
|
|
283
|
+
//#endregion
|
|
284
|
+
//#region src/cli/index.ts
|
|
350
285
|
function run(version) {
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
env.SLACK_APP_ID
|
|
378
|
-
)
|
|
379
|
-
);
|
|
380
|
-
const isLocal = !env.VERCEL_ENV;
|
|
381
|
-
const isDev = env.VERCEL_ENV === "development" || env.NODE_ENV === "development";
|
|
382
|
-
const isProd = env.VERCEL_ENV === "production";
|
|
383
|
-
if (isLocal || isDev || isProd) {
|
|
384
|
-
const reason = isLocal ? "local" : isDev ? "development" : "production";
|
|
385
|
-
log.info(`Environment: ${reason} (skipped)
|
|
386
|
-
`);
|
|
387
|
-
return;
|
|
388
|
-
}
|
|
389
|
-
const params = validateAndBuildParams(env);
|
|
390
|
-
await executeBuild(params, { cleanup });
|
|
391
|
-
});
|
|
392
|
-
program.parseAsync().catch((error) => {
|
|
393
|
-
log.error(error instanceof Error ? error.message : String(error));
|
|
394
|
-
console.log();
|
|
395
|
-
});
|
|
286
|
+
const program = new Command().name("vercel-slack").description("Build and configure Slack apps for Vercel preview deployments").version(version).option("--debug", "Enable verbose debug logging for all HTTP requests");
|
|
287
|
+
const cmd = program.command("build").description("Build and configure the Slack app for a Vercel preview deployment");
|
|
288
|
+
for (const key of ENV_KEYS) cmd.option(`--${envKeyToFlag(key)} <value>`, `Override ${key}`);
|
|
289
|
+
cmd.option("--cleanup", "Clean up Slack apps and env vars for inactive preview branches");
|
|
290
|
+
cmd.action(async (options) => {
|
|
291
|
+
if (program.opts().debug === true || process.env.VERCEL_SLACK_DEBUG === "1" || process.env.VERCEL_SLACK_DEBUG === "true") {
|
|
292
|
+
process.env.VERCEL_SLACK_DEBUG = "1";
|
|
293
|
+
enableFetchDebugLogging();
|
|
294
|
+
}
|
|
295
|
+
const cleanup = options.cleanup === true;
|
|
296
|
+
const env = resolveEnv(options);
|
|
297
|
+
console.log(startMessage(version, env.VERCEL_GIT_COMMIT_REF, env.VERCEL_GIT_COMMIT_SHA, env.SLACK_APP_ID));
|
|
298
|
+
const isLocal = !env.VERCEL_ENV;
|
|
299
|
+
const isDev = env.VERCEL_ENV === "development" || env.NODE_ENV === "development";
|
|
300
|
+
const isProd = env.VERCEL_ENV === "production";
|
|
301
|
+
if (isLocal || isDev || isProd) {
|
|
302
|
+
const reason = isLocal ? "local" : isDev ? "development" : "production";
|
|
303
|
+
log.info(`Environment: ${reason} (skipped)\n`);
|
|
304
|
+
return;
|
|
305
|
+
}
|
|
306
|
+
await executeBuild(validateAndBuildParams(env), { cleanup });
|
|
307
|
+
});
|
|
308
|
+
program.parseAsync().catch((error) => {
|
|
309
|
+
log.error(error instanceof Error ? error.message : String(error));
|
|
310
|
+
console.log();
|
|
311
|
+
});
|
|
396
312
|
}
|
|
397
|
-
var init_cli =
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
"@slack/bolt": "^4.4.0"
|
|
490
|
-
},
|
|
491
|
-
peerDependenciesMeta: {
|
|
492
|
-
"@slack/bolt": {
|
|
493
|
-
optional: false
|
|
494
|
-
}
|
|
495
|
-
},
|
|
496
|
-
engines: {
|
|
497
|
-
node: ">=20.0.0"
|
|
498
|
-
},
|
|
499
|
-
publishConfig: {
|
|
500
|
-
access: "public"
|
|
501
|
-
}
|
|
502
|
-
};
|
|
503
|
-
}
|
|
504
|
-
});
|
|
505
|
-
|
|
506
|
-
// src/cli.ts
|
|
507
|
-
var require_cli = __commonJS({
|
|
508
|
-
"src/cli.ts"() {
|
|
509
|
-
init_cli();
|
|
510
|
-
var { version } = require_package();
|
|
511
|
-
run(version);
|
|
512
|
-
}
|
|
513
|
-
});
|
|
514
|
-
var cli = require_cli();
|
|
313
|
+
var init_cli = __esmMin((() => {
|
|
314
|
+
init_schemas();
|
|
315
|
+
init_logger();
|
|
316
|
+
init_build();
|
|
317
|
+
init_env();
|
|
318
|
+
}));
|
|
319
|
+
//#endregion
|
|
320
|
+
//#region package.json
|
|
321
|
+
var require_package = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
322
|
+
module.exports = {
|
|
323
|
+
"name": "@vercel/slack-bolt",
|
|
324
|
+
"version": "1.4.1",
|
|
325
|
+
"description": "A Vercel receiver for building Slack apps with Bolt and deploying them to Vercel",
|
|
326
|
+
"main": "./dist/index.js",
|
|
327
|
+
"types": "./dist/index.d.ts",
|
|
328
|
+
"type": "commonjs",
|
|
329
|
+
"bin": { "vercel-slack": "./bin/vercel-slack.js" },
|
|
330
|
+
"exports": {
|
|
331
|
+
".": {
|
|
332
|
+
"types": {
|
|
333
|
+
"import": "./dist/index.d.mts",
|
|
334
|
+
"require": "./dist/index.d.ts"
|
|
335
|
+
},
|
|
336
|
+
"import": "./dist/index.mjs",
|
|
337
|
+
"require": "./dist/index.js"
|
|
338
|
+
},
|
|
339
|
+
"./preview": {
|
|
340
|
+
"types": {
|
|
341
|
+
"import": "./dist/preview.d.mts",
|
|
342
|
+
"require": "./dist/preview.d.ts"
|
|
343
|
+
},
|
|
344
|
+
"import": "./dist/preview.mjs",
|
|
345
|
+
"require": "./dist/preview.js"
|
|
346
|
+
}
|
|
347
|
+
},
|
|
348
|
+
"typesVersions": { "*": { "preview": ["./dist/preview.d.ts"] } },
|
|
349
|
+
"files": ["bin", "dist"],
|
|
350
|
+
"repository": {
|
|
351
|
+
"type": "git",
|
|
352
|
+
"url": "https://github.com/vercel-labs/slack-bolt"
|
|
353
|
+
},
|
|
354
|
+
"bugs": { "url": "https://github.com/vercel-labs/slack-bolt/issues" },
|
|
355
|
+
"scripts": {
|
|
356
|
+
"build": "tsdown",
|
|
357
|
+
"dev": "tsdown --watch",
|
|
358
|
+
"test": "vitest run",
|
|
359
|
+
"test:watch": "vitest watch",
|
|
360
|
+
"lint": "biome check .",
|
|
361
|
+
"lint:fix": "biome check . --write",
|
|
362
|
+
"attw": "attw --pack ."
|
|
363
|
+
},
|
|
364
|
+
"keywords": [
|
|
365
|
+
"vercel",
|
|
366
|
+
"bolt",
|
|
367
|
+
"slack"
|
|
368
|
+
],
|
|
369
|
+
"author": "Vercel",
|
|
370
|
+
"license": "MIT",
|
|
371
|
+
"dependencies": {
|
|
372
|
+
"@slack/logger": "^4.0.1",
|
|
373
|
+
"@slack/oauth": "3.0.5",
|
|
374
|
+
"@vercel/functions": "^3.4.3",
|
|
375
|
+
"commander": "^14.0.3",
|
|
376
|
+
"yaml": "^2.8.3",
|
|
377
|
+
"zod": "^4.3.6"
|
|
378
|
+
},
|
|
379
|
+
"devDependencies": {
|
|
380
|
+
"@arethetypeswrong/cli": "^0.18.2",
|
|
381
|
+
"@biomejs/biome": "2.2.2",
|
|
382
|
+
"@types/node": "^20.19.35",
|
|
383
|
+
"@vitest/coverage-v8": "4.1.2",
|
|
384
|
+
"tsdown": "^0.21.7",
|
|
385
|
+
"tsx": "^4.21.0",
|
|
386
|
+
"typescript": "^5.9.3",
|
|
387
|
+
"vitest": "^4.1.2"
|
|
388
|
+
},
|
|
389
|
+
"peerDependencies": { "@slack/bolt": "^4.4.0" },
|
|
390
|
+
"peerDependenciesMeta": { "@slack/bolt": { "optional": false } },
|
|
391
|
+
"engines": { "node": ">=20.0.0" },
|
|
392
|
+
"publishConfig": { "access": "public" }
|
|
393
|
+
};
|
|
394
|
+
}));
|
|
395
|
+
//#endregion
|
|
396
|
+
//#region src/cli.ts
|
|
397
|
+
var require_cli = /* @__PURE__ */ __commonJSMin((() => {
|
|
398
|
+
init_cli();
|
|
399
|
+
const { version } = require_package();
|
|
400
|
+
run(version);
|
|
401
|
+
}));
|
|
402
|
+
//#endregion
|
|
403
|
+
export default require_cli();
|
|
404
|
+
export {};
|
|
515
405
|
|
|
516
|
-
export { cli as default };
|
|
517
|
-
//# sourceMappingURL=cli.mjs.map
|
|
518
406
|
//# sourceMappingURL=cli.mjs.map
|