@vercel/slack-bolt 1.3.0 → 1.4.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/README.md +84 -8
- package/dist/{chunk-JFHLS5RC.js → chunk-DYB6RJG4.js} +40 -3
- package/dist/chunk-DYB6RJG4.js.map +1 -0
- package/dist/{chunk-VNXFT255.mjs → chunk-LARZABX3.mjs} +40 -3
- package/dist/chunk-LARZABX3.mjs.map +1 -0
- package/dist/cli.js +46 -45
- package/dist/cli.js.map +1 -1
- package/dist/cli.mjs +3 -2
- package/dist/cli.mjs.map +1 -1
- package/dist/index.d.mts +77 -2
- package/dist/index.d.ts +77 -2
- package/dist/index.js +164 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +164 -1
- package/dist/index.mjs.map +1 -1
- package/dist/preview.js +3 -3
- package/dist/preview.mjs +2 -2
- package/package.json +2 -1
- package/dist/chunk-JFHLS5RC.js.map +0 -1
- package/dist/chunk-VNXFT255.mjs.map +0 -1
package/dist/index.mjs
CHANGED
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
import './chunk-B5E7QPZP.mjs';
|
|
2
2
|
import { ReceiverAuthenticityError, verifySlackRequest, ReceiverMultipleAckError } from '@slack/bolt';
|
|
3
3
|
import { ConsoleLogger, LogLevel } from '@slack/logger';
|
|
4
|
+
import { InstallProvider } from '@slack/oauth';
|
|
4
5
|
import { waitUntil } from '@vercel/functions';
|
|
6
|
+
import { IncomingMessage, ServerResponse } from 'http';
|
|
7
|
+
import { Socket } from 'net';
|
|
5
8
|
|
|
6
9
|
// src/errors.ts
|
|
7
10
|
var ERROR_MESSAGES = {
|
|
8
11
|
// VercelReceiver errors
|
|
9
12
|
SIGNING_SECRET_REQUIRED: "SLACK_SIGNING_SECRET is required for VercelReceiver",
|
|
10
13
|
APP_NOT_INITIALIZED: "App not initialized",
|
|
14
|
+
OAUTH_NOT_CONFIGURED: "OAuth is not configured. Provide clientId, clientSecret, and stateSecret to enable OAuth.",
|
|
11
15
|
REQUEST_TIMEOUT: "Request timeout",
|
|
12
16
|
EVENT_NOT_ACKNOWLEDGED: "Event not acknowledged within timeout period",
|
|
13
17
|
// Header validation errors
|
|
@@ -76,6 +80,80 @@ function getErrorType(error) {
|
|
|
76
80
|
}
|
|
77
81
|
return ERROR_MESSAGES.TYPES.UNEXPECTED_ERROR;
|
|
78
82
|
}
|
|
83
|
+
function toIncomingMessage(req) {
|
|
84
|
+
const url = new URL(req.url);
|
|
85
|
+
const msg = new IncomingMessage(new Socket());
|
|
86
|
+
msg.url = url.pathname + url.search;
|
|
87
|
+
msg.method = req.method;
|
|
88
|
+
for (const [key, value] of req.headers.entries()) {
|
|
89
|
+
msg.headers[key.toLowerCase()] = value;
|
|
90
|
+
}
|
|
91
|
+
if (req.body) {
|
|
92
|
+
req.arrayBuffer().then((buf) => {
|
|
93
|
+
msg.push(Buffer.from(buf));
|
|
94
|
+
msg.push(null);
|
|
95
|
+
}).catch(() => msg.destroy());
|
|
96
|
+
} else {
|
|
97
|
+
msg.push(null);
|
|
98
|
+
}
|
|
99
|
+
return msg;
|
|
100
|
+
}
|
|
101
|
+
function createResponseCapture() {
|
|
102
|
+
let statusCode = 200;
|
|
103
|
+
const capturedHeaders = {};
|
|
104
|
+
const chunks = [];
|
|
105
|
+
const res = new ServerResponse(new IncomingMessage(new Socket()));
|
|
106
|
+
const originalSetHeader = res.setHeader.bind(res);
|
|
107
|
+
res.setHeader = (name, value) => {
|
|
108
|
+
const key = name.toLowerCase();
|
|
109
|
+
if (Array.isArray(value)) {
|
|
110
|
+
capturedHeaders[key] = [...value];
|
|
111
|
+
} else {
|
|
112
|
+
capturedHeaders[key] = String(value);
|
|
113
|
+
}
|
|
114
|
+
return originalSetHeader(name, value);
|
|
115
|
+
};
|
|
116
|
+
const originalGetHeader = res.getHeader.bind(res);
|
|
117
|
+
res.getHeader = (name) => {
|
|
118
|
+
const val = capturedHeaders[name.toLowerCase()];
|
|
119
|
+
if (val !== void 0) return val;
|
|
120
|
+
return originalGetHeader(name);
|
|
121
|
+
};
|
|
122
|
+
const originalWriteHead = res.writeHead.bind(res);
|
|
123
|
+
res.writeHead = (code, ...args) => {
|
|
124
|
+
statusCode = code;
|
|
125
|
+
const headersArg = args.find(
|
|
126
|
+
(a) => a !== void 0 && typeof a === "object" && !Array.isArray(a)
|
|
127
|
+
);
|
|
128
|
+
if (headersArg) {
|
|
129
|
+
for (const [key, value] of Object.entries(headersArg)) {
|
|
130
|
+
const lower = key.toLowerCase();
|
|
131
|
+
capturedHeaders[lower] = value;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
return originalWriteHead(code, ...args);
|
|
135
|
+
};
|
|
136
|
+
const originalEnd = res.end.bind(res);
|
|
137
|
+
res.end = (chunk, ...args) => {
|
|
138
|
+
if (chunk !== void 0 && chunk !== null) {
|
|
139
|
+
chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk)));
|
|
140
|
+
}
|
|
141
|
+
return originalEnd(chunk, ...args);
|
|
142
|
+
};
|
|
143
|
+
res.toResponse = () => {
|
|
144
|
+
const body = chunks.length > 0 ? Buffer.concat(chunks).toString() : null;
|
|
145
|
+
const webHeaders = new Headers();
|
|
146
|
+
for (const [key, value] of Object.entries(capturedHeaders)) {
|
|
147
|
+
if (Array.isArray(value)) {
|
|
148
|
+
for (const v of value) webHeaders.append(key, v);
|
|
149
|
+
} else {
|
|
150
|
+
webHeaders.set(key, value);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
return new Response(body, { status: statusCode, headers: webHeaders });
|
|
154
|
+
};
|
|
155
|
+
return res;
|
|
156
|
+
}
|
|
79
157
|
|
|
80
158
|
// src/index.ts
|
|
81
159
|
var LOG_PREFIX = "[@vercel/slack-bolt]";
|
|
@@ -91,6 +169,11 @@ var VercelReceiver = class {
|
|
|
91
169
|
customPropertiesExtractor;
|
|
92
170
|
ackTimeoutMs;
|
|
93
171
|
app;
|
|
172
|
+
installer;
|
|
173
|
+
installUrlOptions;
|
|
174
|
+
installCallbackOptions;
|
|
175
|
+
installPathOptions;
|
|
176
|
+
stateVerification;
|
|
94
177
|
/**
|
|
95
178
|
* Gets the logger instance used by this receiver.
|
|
96
179
|
* @returns The logger instance
|
|
@@ -115,7 +198,14 @@ var VercelReceiver = class {
|
|
|
115
198
|
logger,
|
|
116
199
|
logLevel = LogLevel.INFO,
|
|
117
200
|
customPropertiesExtractor,
|
|
118
|
-
ackTimeoutMs = ACK_TIMEOUT_MS
|
|
201
|
+
ackTimeoutMs = ACK_TIMEOUT_MS,
|
|
202
|
+
clientId = process.env.SLACK_CLIENT_ID,
|
|
203
|
+
clientSecret = process.env.SLACK_CLIENT_SECRET,
|
|
204
|
+
stateSecret = process.env.SLACK_STATE_SECRET,
|
|
205
|
+
scopes,
|
|
206
|
+
redirectUri,
|
|
207
|
+
installationStore,
|
|
208
|
+
installerOptions = {}
|
|
119
209
|
} = {}) {
|
|
120
210
|
if (!signingSecret) {
|
|
121
211
|
throw new VercelReceiverError(ERROR_MESSAGES.SIGNING_SECRET_REQUIRED);
|
|
@@ -128,6 +218,35 @@ var VercelReceiver = class {
|
|
|
128
218
|
);
|
|
129
219
|
this.customPropertiesExtractor = customPropertiesExtractor;
|
|
130
220
|
this.ackTimeoutMs = ackTimeoutMs;
|
|
221
|
+
this.stateVerification = installerOptions.stateVerification;
|
|
222
|
+
if (clientId !== void 0 && clientSecret !== void 0 && (installerOptions.stateVerification === false || stateSecret !== void 0 || installerOptions.stateStore !== void 0)) {
|
|
223
|
+
this.installer = new InstallProvider({
|
|
224
|
+
clientId,
|
|
225
|
+
clientSecret,
|
|
226
|
+
stateSecret,
|
|
227
|
+
installationStore,
|
|
228
|
+
logger,
|
|
229
|
+
logLevel,
|
|
230
|
+
directInstall: installerOptions.directInstall,
|
|
231
|
+
stateStore: installerOptions.stateStore,
|
|
232
|
+
stateVerification: installerOptions.stateVerification,
|
|
233
|
+
legacyStateVerification: installerOptions.legacyStateVerification,
|
|
234
|
+
stateCookieName: installerOptions.stateCookieName,
|
|
235
|
+
stateCookieExpirationSeconds: installerOptions.stateCookieExpirationSeconds,
|
|
236
|
+
renderHtmlForInstallPath: installerOptions.renderHtmlForInstallPath,
|
|
237
|
+
authVersion: installerOptions.authVersion ?? "v2",
|
|
238
|
+
clientOptions: installerOptions.clientOptions,
|
|
239
|
+
authorizationUrl: installerOptions.authorizationUrl
|
|
240
|
+
});
|
|
241
|
+
this.installUrlOptions = {
|
|
242
|
+
scopes: scopes ?? [],
|
|
243
|
+
userScopes: installerOptions.userScopes,
|
|
244
|
+
metadata: installerOptions.metadata,
|
|
245
|
+
redirectUri
|
|
246
|
+
};
|
|
247
|
+
this.installCallbackOptions = installerOptions.callbackOptions ?? {};
|
|
248
|
+
this.installPathOptions = installerOptions.installPathOptions ?? {};
|
|
249
|
+
}
|
|
131
250
|
this.logger.debug("VercelReceiver initialized");
|
|
132
251
|
}
|
|
133
252
|
/**
|
|
@@ -156,6 +275,50 @@ var VercelReceiver = class {
|
|
|
156
275
|
async stop() {
|
|
157
276
|
this.logger.debug("VercelReceiver stopped");
|
|
158
277
|
}
|
|
278
|
+
/**
|
|
279
|
+
* Handles requests to the OAuth install path.
|
|
280
|
+
* Renders an "Add to Slack" page or redirects directly to Slack's authorize URL.
|
|
281
|
+
*/
|
|
282
|
+
handleInstall = async (req) => {
|
|
283
|
+
if (!this.installer) {
|
|
284
|
+
throw new VercelReceiverError(ERROR_MESSAGES.OAUTH_NOT_CONFIGURED);
|
|
285
|
+
}
|
|
286
|
+
const nodeReq = toIncomingMessage(req);
|
|
287
|
+
const capture = createResponseCapture();
|
|
288
|
+
await this.installer.handleInstallPath(
|
|
289
|
+
nodeReq,
|
|
290
|
+
capture,
|
|
291
|
+
this.installPathOptions,
|
|
292
|
+
this.installUrlOptions
|
|
293
|
+
);
|
|
294
|
+
return capture.toResponse();
|
|
295
|
+
};
|
|
296
|
+
/**
|
|
297
|
+
* Handles the OAuth redirect callback from Slack.
|
|
298
|
+
* Exchanges the authorization code for tokens and stores the installation.
|
|
299
|
+
*/
|
|
300
|
+
handleCallback = async (req) => {
|
|
301
|
+
if (!this.installer) {
|
|
302
|
+
throw new VercelReceiverError(ERROR_MESSAGES.OAUTH_NOT_CONFIGURED);
|
|
303
|
+
}
|
|
304
|
+
const nodeReq = toIncomingMessage(req);
|
|
305
|
+
const capture = createResponseCapture();
|
|
306
|
+
if (this.stateVerification === false) {
|
|
307
|
+
await this.installer.handleCallback(
|
|
308
|
+
nodeReq,
|
|
309
|
+
capture,
|
|
310
|
+
this.installCallbackOptions,
|
|
311
|
+
this.installUrlOptions
|
|
312
|
+
);
|
|
313
|
+
} else {
|
|
314
|
+
await this.installer.handleCallback(
|
|
315
|
+
nodeReq,
|
|
316
|
+
capture,
|
|
317
|
+
this.installCallbackOptions
|
|
318
|
+
);
|
|
319
|
+
}
|
|
320
|
+
return capture.toResponse();
|
|
321
|
+
};
|
|
159
322
|
/**
|
|
160
323
|
* Creates a handler function that processes incoming Slack requests.
|
|
161
324
|
* This is the main entry point for handling Slack events in Vercel.
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/errors.ts","../src/index.ts"],"names":["body"],"mappings":"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","file":"index.mjs","sourcesContent":["// Error messages constants\nexport const ERROR_MESSAGES = {\n // VercelReceiver errors\n SIGNING_SECRET_REQUIRED:\n \"SLACK_SIGNING_SECRET is required for VercelReceiver\",\n APP_NOT_INITIALIZED: \"App not initialized\",\n REQUEST_TIMEOUT: \"Request timeout\",\n EVENT_NOT_ACKNOWLEDGED: \"Event not acknowledged within timeout period\",\n\n // Header validation errors\n MISSING_REQUIRED_HEADER: (header: string) =>\n `Missing required header: ${header}`,\n\n // Generic fallback errors\n REQUEST_VERIFICATION_FAILED: \"Request verification failed\",\n INTERNAL_SERVER_ERROR: \"Internal server error\",\n INTERNAL_SERVER_ERROR_HANDLER: \"Internal Server Error\",\n ACKNOWLEDGMENT_ERROR: \"Error in acknowledgment handler\",\n CREATE_HANDLER_ERROR: \"Error in createHandler:\",\n\n // Error type names\n TYPES: {\n VERCEL_RECEIVER_ERROR: \"VercelReceiverError\",\n SIGNATURE_VERIFICATION_ERROR: \"SignatureVerificationError\",\n REQUEST_PARSING_ERROR: \"RequestParsingError\",\n UNEXPECTED_ERROR: \"UnexpectedError\",\n HANDLER_ERROR: \"HandlerError\",\n },\n} as const;\n\nexport class VercelReceiverError extends Error {\n constructor(\n message: string,\n public readonly statusCode: number = 500,\n ) {\n super(message);\n this.name = ERROR_MESSAGES.TYPES.VERCEL_RECEIVER_ERROR;\n }\n}\n\nexport class RequestParsingError extends VercelReceiverError {\n constructor(message: string = \"Failed to parse request\") {\n super(message, 400);\n this.name = ERROR_MESSAGES.TYPES.REQUEST_PARSING_ERROR;\n }\n}\n\n/**\n * Determines the appropriate HTTP status code for a given error.\n * @param error The error to get status code for\n * @returns HTTP status code\n */\nexport function getStatusCode(error: unknown): number {\n if (error instanceof VercelReceiverError) {\n return error.statusCode;\n }\n\n // External error types from @slack/bolt\n if (error && typeof error === \"object\") {\n const errorName =\n error.constructor?.name || (error as { name?: string }).name;\n switch (errorName) {\n case \"ReceiverAuthenticityError\":\n return 401;\n case \"ReceiverMultipleAckError\":\n return 500;\n case \"RequestParsingError\":\n return 400;\n case \"SignatureVerificationError\":\n return 400;\n default:\n return 500;\n }\n }\n\n return 500;\n}\n\n/**\n * Gets the error message for response.\n * @param error The error to get message for\n * @returns Error message string\n */\nexport function getErrorMessage(error: unknown): string {\n if (error && typeof error === \"object\" && \"message\" in error) {\n return String(error.message);\n }\n return ERROR_MESSAGES.INTERNAL_SERVER_ERROR;\n}\n\n/**\n * Gets the error type for response.\n * @param error The error to get type for\n * @returns Error type string\n */\nexport function getErrorType(error: unknown): string {\n if (error && typeof error === \"object\") {\n const ctorName = (error as { constructor?: { name?: string } }).constructor\n ?.name;\n const nameProp = (error as { name?: string }).name;\n const errorName =\n ctorName ?? nameProp ?? ERROR_MESSAGES.TYPES.UNEXPECTED_ERROR;\n // Use \"UnexpectedError\" for generic Error instances, otherwise use the actual name\n return errorName === \"Error\"\n ? ERROR_MESSAGES.TYPES.UNEXPECTED_ERROR\n : errorName;\n }\n return ERROR_MESSAGES.TYPES.UNEXPECTED_ERROR;\n}\n","import {\n type AckFn,\n type App,\n type Receiver,\n ReceiverAuthenticityError,\n type ReceiverEvent,\n ReceiverMultipleAckError,\n type StringIndexed,\n verifySlackRequest,\n} from \"@slack/bolt\";\nimport { ConsoleLogger, type Logger, LogLevel } from \"@slack/logger\";\nimport { waitUntil } from \"@vercel/functions\";\nimport {\n ERROR_MESSAGES,\n getErrorMessage,\n getErrorType,\n getStatusCode,\n RequestParsingError,\n VercelReceiverError,\n} from \"./errors\";\n\n// Types\n/**\n * A function to handle the request from the Slack app.\n * @param req - The request from the Slack app.\n * @returns A response object.\n */\nexport type VercelHandler = (req: Request) => Promise<Response>;\n\n/**\n * Configuration options for the VercelReceiver.\n * @property signingSecret - The signing secret for the Slack app.\n * @property signatureVerification - If true, verifies the Slack request signature.\n * @property logger - The logger to use for the VercelReceiver.\n * @property logLevel - The log level to use for the VercelReceiver.\n * @property customPropertiesExtractor - A function to extract custom properties from the request.\n */\nexport interface VercelReceiverOptions {\n /**\n * The signing secret for the Slack app.\n * @default process.env.SLACK_SIGNING_SECRET\n */\n signingSecret?: string;\n /**\n * If true, verifies the Slack request signature.\n * @default true\n */\n signatureVerification?: boolean;\n /**\n * The logger to use for the VercelReceiver.\n * @default new ConsoleLogger()\n */\n logger?: Logger;\n /**\n * The log level to use for the VercelReceiver.\n * @default LogLevel.INFO\n */\n logLevel?: LogLevel;\n /**\n * A function to extract custom properties from incoming events.\n * @default undefined\n * @returns An object with custom properties.\n */\n customPropertiesExtractor?: (req: Request) => StringIndexed;\n /**\n * The timeout in milliseconds for event acknowledgment.\n * @default 3001\n */\n ackTimeoutMs?: number;\n}\n\nconst LOG_PREFIX = \"[@vercel/slack-bolt]\";\nconst ACK_TIMEOUT_MS = 3001;\nconst SLACK_RETRY_NUM_HEADER = \"x-slack-retry-num\";\nconst SLACK_RETRY_REASON_HEADER = \"x-slack-retry-reason\";\nconst SLACK_TIMESTAMP_HEADER = \"x-slack-request-timestamp\";\nconst SLACK_SIGNATURE_HEADER = \"x-slack-signature\";\n\n/**\n * A Slack Bolt receiver implementation designed for Vercel's serverless environment.\n * Handles Slack events, interactions, and slash commands with automatic request verification,\n * background processing, and timeout management.\n *\n * @example\n * ```typescript\n * import { App } from '@slack/bolt';\n * import { VercelReceiver, createHandler } from '@vercel/slack-bolt';\n *\n * const receiver = new VercelReceiver();\n *\n * const app = new App({\n * receiver,\n * token: process.env.SLACK_BOT_TOKEN,\n * signingSecret: process.env.SLACK_SIGNING_SECRET,\n * });\n * ```\n *\n */\nexport class VercelReceiver implements Receiver {\n private readonly signingSecret: string;\n private readonly signatureVerification: boolean;\n private readonly logger: Logger;\n private readonly customPropertiesExtractor?: (req: Request) => StringIndexed;\n private readonly ackTimeoutMs: number;\n private app?: App;\n\n /**\n * Gets the logger instance used by this receiver.\n * @returns The logger instance\n */\n public getLogger(): Logger {\n return this.logger;\n }\n\n /**\n * Creates a new VercelReceiver instance.\n *\n * @param options - Configuration options for the receiver\n * @throws {VercelReceiverError} When signing secret is not provided\n *\n * @example\n * ```typescript\n * const receiver = new VercelReceiver();\n * ```\n */\n public constructor({\n signingSecret = process.env.SLACK_SIGNING_SECRET,\n signatureVerification = true,\n logger,\n logLevel = LogLevel.INFO,\n customPropertiesExtractor,\n ackTimeoutMs = ACK_TIMEOUT_MS,\n }: VercelReceiverOptions = {}) {\n if (!signingSecret) {\n throw new VercelReceiverError(ERROR_MESSAGES.SIGNING_SECRET_REQUIRED);\n }\n\n this.signingSecret = signingSecret;\n this.signatureVerification = signatureVerification;\n this.logger = this.createScopedLogger(\n logger ?? new ConsoleLogger(),\n logLevel,\n );\n this.customPropertiesExtractor = customPropertiesExtractor;\n this.ackTimeoutMs = ackTimeoutMs;\n\n this.logger.debug(\"VercelReceiver initialized\");\n }\n\n /**\n * Initializes the receiver with a Slack Bolt app instance.\n * This method is called automatically by the Bolt framework.\n *\n * @param app - The Slack Bolt app instance\n */\n public init(app: App): void {\n this.app = app;\n this.logger.debug(\"App initialized in VercelReceiver\");\n }\n\n /**\n * Starts the receiver and returns a handler function for processing requests.\n * This method is called automatically by the Bolt framework.\n *\n * @returns A handler function that processes incoming Slack requests\n */\n public async start(): Promise<VercelHandler> {\n this.logger.debug(\"VercelReceiver started\");\n return this.toHandler();\n }\n\n /**\n * Stops the receiver. This method is called automatically by the Bolt framework.\n */\n public async stop(): Promise<void> {\n this.logger.debug(\"VercelReceiver stopped\");\n }\n\n /**\n * Creates a handler function that processes incoming Slack requests.\n * This is the main entry point for handling Slack events in Vercel.\n * It is called automatically by the Bolt framework in the start() method.\n *\n * @returns A handler function compatible with Vercel's function signature\n */\n public toHandler(): VercelHandler {\n return async (req: Request): Promise<Response> => {\n try {\n const rawBody = await req.text();\n\n if (this.signatureVerification) {\n this.verifyRequest(req, rawBody);\n }\n\n const body = await this.parseRequestBody(req, rawBody);\n\n if (body.type === \"url_verification\") {\n this.logger.debug(\"Handling URL verification challenge\");\n return Response.json({ challenge: body.challenge });\n }\n\n return await this.handleSlackEvent(req, body);\n } catch (error) {\n return this.handleError(error);\n }\n };\n }\n\n private async parseRequestBody(\n req: Request,\n rawBody: string,\n ): Promise<StringIndexed> {\n const contentType = req.headers.get(\"content-type\");\n\n try {\n if (contentType === \"application/x-www-form-urlencoded\") {\n const parsedBody: StringIndexed = {};\n const params = new URLSearchParams(rawBody);\n\n for (const [key, value] of params.entries()) {\n parsedBody[key] = value;\n }\n\n if (typeof parsedBody.payload === \"string\") {\n return JSON.parse(parsedBody.payload);\n }\n return parsedBody;\n }\n if (contentType === \"application/json\") {\n return JSON.parse(rawBody);\n }\n\n this.logger.warn(`Unexpected content-type detected: ${contentType}`);\n\n return JSON.parse(rawBody);\n } catch (e) {\n throw new RequestParsingError(\n `Failed to parse body as JSON data for content-type: ${contentType}. Error: ${\n e instanceof Error ? e.message : String(e)\n }`,\n );\n }\n }\n\n private async handleSlackEvent(\n req: Request,\n body: StringIndexed,\n ): Promise<Response> {\n if (!this.app) {\n throw new VercelReceiverError(ERROR_MESSAGES.APP_NOT_INITIALIZED, 500);\n }\n\n let isAcknowledged = false;\n let responseResolver: (value: Response) => void;\n let responseRejecter: (error: Error) => void;\n\n const responsePromise = new Promise<Response>((resolve, reject) => {\n responseResolver = resolve;\n responseRejecter = reject;\n });\n\n // Slack requires an acknowledgment from your app within 3 seconds\n const timeoutId = setTimeout(() => {\n if (!isAcknowledged) {\n isAcknowledged = true;\n this.logger.error(ERROR_MESSAGES.EVENT_NOT_ACKNOWLEDGED);\n const error = new VercelReceiverError(\n ERROR_MESSAGES.REQUEST_TIMEOUT,\n 408,\n );\n responseRejecter(error);\n }\n }, this.ackTimeoutMs);\n\n // Create acknowledgment function\n const ackFn: AckFn<StringIndexed> = async (responseBody) => {\n this.logger.debug(`ack() call begins (body: ${responseBody})`);\n if (isAcknowledged) {\n throw new ReceiverMultipleAckError();\n }\n\n isAcknowledged = true;\n clearTimeout(timeoutId);\n\n try {\n let body: string | undefined;\n if (typeof responseBody === \"undefined\") {\n body = undefined;\n } else if (typeof responseBody === \"string\") {\n body = responseBody;\n } else {\n body = JSON.stringify(responseBody);\n }\n const response = new Response(body, {\n status: 200,\n headers: {\n \"Content-Type\": \"application/json\",\n },\n });\n\n responseResolver(response);\n } catch (error) {\n this.logger.error(ERROR_MESSAGES.ACKNOWLEDGMENT_ERROR, error);\n responseRejecter(\n error instanceof Error ? error : new Error(String(error)),\n );\n }\n };\n\n const event = this.createSlackReceiverEvent({\n body,\n headers: req.headers,\n ack: ackFn,\n request: req,\n });\n\n // Process event in background using waitUntil from Vercel Functions\n // https://vercel.com/docs/functions/functions-api-reference/vercel-functions-package#waituntil\n waitUntil(\n this.app.processEvent(event).catch((error) => {\n return this.handleError(error);\n }),\n );\n\n try {\n return await responsePromise;\n } catch (error) {\n return this.handleError(error);\n }\n }\n\n private verifyRequest(req: Request, body: string): void {\n const timestamp = req.headers.get(SLACK_TIMESTAMP_HEADER);\n const signature = req.headers.get(SLACK_SIGNATURE_HEADER);\n\n if (!signature) {\n throw new ReceiverAuthenticityError(\n ERROR_MESSAGES.MISSING_REQUIRED_HEADER(SLACK_SIGNATURE_HEADER),\n );\n }\n\n if (!timestamp) {\n throw new ReceiverAuthenticityError(\n ERROR_MESSAGES.MISSING_REQUIRED_HEADER(SLACK_TIMESTAMP_HEADER),\n );\n }\n\n try {\n verifySlackRequest({\n signingSecret: this.signingSecret,\n body,\n headers: {\n \"x-slack-signature\": signature,\n \"x-slack-request-timestamp\": Number.parseInt(timestamp, 10),\n },\n logger: this.logger,\n });\n } catch (error) {\n throw new ReceiverAuthenticityError(\n error instanceof Error\n ? error.message\n : \"Failed to verify request signature\",\n );\n }\n }\n\n private createSlackReceiverEvent({\n body,\n headers,\n ack,\n request,\n }: {\n body: StringIndexed;\n headers: Headers;\n ack: AckFn<StringIndexed>;\n request: Request;\n }): ReceiverEvent {\n const customProperties = this.customPropertiesExtractor\n ? this.customPropertiesExtractor(request)\n : {};\n\n const retryNum = headers.get(SLACK_RETRY_NUM_HEADER) || \"0\";\n\n const retryReason = headers.get(SLACK_RETRY_REASON_HEADER) || \"\";\n\n return {\n body,\n ack,\n retryNum: Number(retryNum),\n retryReason,\n customProperties,\n };\n }\n\n public handleError(error: unknown): Response {\n const errorMessage = getErrorMessage(error);\n const errorType = getErrorType(error);\n const errorStatusCode = getStatusCode(error);\n\n this.logger.error(error);\n return new Response(\n JSON.stringify({\n error: errorMessage,\n type: errorType,\n }),\n {\n status: errorStatusCode,\n headers: { \"content-type\": \"application/json\" },\n },\n );\n }\n\n private createScopedLogger(logger: Logger, logLevel: LogLevel): Logger {\n logger.setLevel(logLevel);\n\n return {\n ...logger,\n error: (...args) => logger.error?.(LOG_PREFIX, ...args),\n warn: (...args) => logger.warn?.(LOG_PREFIX, ...args),\n info: (...args) => logger.info?.(LOG_PREFIX, ...args),\n debug: (...args) => logger.debug?.(LOG_PREFIX, ...args),\n setLevel: logger.setLevel,\n getLevel: logger.getLevel,\n };\n }\n}\n\n/**\n * Creates a Vercel-compatible handler function for a Slack Bolt app.\n * This is the recommended way to create handlers for deployment on Vercel.\n *\n * @param {App} app - The initialized Slack Bolt app instance.\n * @param {VercelReceiver} receiver - The VercelReceiver instance.\n * @returns {VercelHandler} A handler function compatible with Vercel's function signature.\n *\n * @example\n * ```typescript\n * // api/events.ts\n * import { createHandler } from '@vercel/slack-bolt';\n * import { app, receiver } from '../app';\n *\n * const handler = createHandler(app, receiver);\n *\n * export const POST = async (req: Request) => {\n * return handler(req);\n * };\n * ```\n *\n * @throws {Error} If app initialization fails.\n * @throws {VercelReceiverError} If request processing fails.\n */\nexport function createHandler(\n app: App,\n receiver: VercelReceiver,\n): VercelHandler {\n let initPromise: Promise<void> | null = null;\n\n return async (req: Request) => {\n try {\n if (!initPromise) {\n initPromise = app.init().catch((error) => {\n // Reset initPromise so subsequent requests can retry initialization\n initPromise = null;\n throw error;\n });\n }\n await initPromise;\n\n receiver.init(app);\n const handler = await receiver.start();\n return handler(req);\n } catch (error) {\n // if app.init fails, we use console.error instead of logger.error because the logger is not available\n console.error(ERROR_MESSAGES.CREATE_HANDLER_ERROR, error);\n return new Response(\n JSON.stringify({\n error: ERROR_MESSAGES.INTERNAL_SERVER_ERROR_HANDLER,\n type: ERROR_MESSAGES.TYPES.HANDLER_ERROR,\n }),\n { status: 500, headers: { \"content-type\": \"application/json\" } },\n );\n }\n };\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/errors.ts","../src/oauth-adapters.ts","../src/index.ts"],"names":["body"],"mappings":"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","file":"index.mjs","sourcesContent":["// Error messages constants\nexport const ERROR_MESSAGES = {\n // VercelReceiver errors\n SIGNING_SECRET_REQUIRED:\n \"SLACK_SIGNING_SECRET is required for VercelReceiver\",\n APP_NOT_INITIALIZED: \"App not initialized\",\n OAUTH_NOT_CONFIGURED:\n \"OAuth is not configured. Provide clientId, clientSecret, and stateSecret to enable OAuth.\",\n REQUEST_TIMEOUT: \"Request timeout\",\n EVENT_NOT_ACKNOWLEDGED: \"Event not acknowledged within timeout period\",\n\n // Header validation errors\n MISSING_REQUIRED_HEADER: (header: string) =>\n `Missing required header: ${header}`,\n\n // Generic fallback errors\n REQUEST_VERIFICATION_FAILED: \"Request verification failed\",\n INTERNAL_SERVER_ERROR: \"Internal server error\",\n INTERNAL_SERVER_ERROR_HANDLER: \"Internal Server Error\",\n ACKNOWLEDGMENT_ERROR: \"Error in acknowledgment handler\",\n CREATE_HANDLER_ERROR: \"Error in createHandler:\",\n\n // Error type names\n TYPES: {\n VERCEL_RECEIVER_ERROR: \"VercelReceiverError\",\n SIGNATURE_VERIFICATION_ERROR: \"SignatureVerificationError\",\n REQUEST_PARSING_ERROR: \"RequestParsingError\",\n UNEXPECTED_ERROR: \"UnexpectedError\",\n HANDLER_ERROR: \"HandlerError\",\n },\n} as const;\n\nexport class VercelReceiverError extends Error {\n constructor(\n message: string,\n public readonly statusCode: number = 500,\n ) {\n super(message);\n this.name = ERROR_MESSAGES.TYPES.VERCEL_RECEIVER_ERROR;\n }\n}\n\nexport class RequestParsingError extends VercelReceiverError {\n constructor(message: string = \"Failed to parse request\") {\n super(message, 400);\n this.name = ERROR_MESSAGES.TYPES.REQUEST_PARSING_ERROR;\n }\n}\n\n/**\n * Determines the appropriate HTTP status code for a given error.\n * @param error The error to get status code for\n * @returns HTTP status code\n */\nexport function getStatusCode(error: unknown): number {\n if (error instanceof VercelReceiverError) {\n return error.statusCode;\n }\n\n // External error types from @slack/bolt\n if (error && typeof error === \"object\") {\n const errorName =\n error.constructor?.name || (error as { name?: string }).name;\n switch (errorName) {\n case \"ReceiverAuthenticityError\":\n return 401;\n case \"ReceiverMultipleAckError\":\n return 500;\n case \"RequestParsingError\":\n return 400;\n case \"SignatureVerificationError\":\n return 400;\n default:\n return 500;\n }\n }\n\n return 500;\n}\n\n/**\n * Gets the error message for response.\n * @param error The error to get message for\n * @returns Error message string\n */\nexport function getErrorMessage(error: unknown): string {\n if (error && typeof error === \"object\" && \"message\" in error) {\n return String(error.message);\n }\n return ERROR_MESSAGES.INTERNAL_SERVER_ERROR;\n}\n\n/**\n * Gets the error type for response.\n * @param error The error to get type for\n * @returns Error type string\n */\nexport function getErrorType(error: unknown): string {\n if (error && typeof error === \"object\") {\n const ctorName = (error as { constructor?: { name?: string } }).constructor\n ?.name;\n const nameProp = (error as { name?: string }).name;\n const errorName =\n ctorName ?? nameProp ?? ERROR_MESSAGES.TYPES.UNEXPECTED_ERROR;\n // Use \"UnexpectedError\" for generic Error instances, otherwise use the actual name\n return errorName === \"Error\"\n ? ERROR_MESSAGES.TYPES.UNEXPECTED_ERROR\n : errorName;\n }\n return ERROR_MESSAGES.TYPES.UNEXPECTED_ERROR;\n}\n","/**\n * Minimal Web <-> Node HTTP adapters for @slack/oauth InstallProvider.\n *\n * These do NOT implement the full IncomingMessage/ServerResponse contract.\n * Only the methods actually called by InstallProvider are intercepted.\n * Do not reuse for other Node libraries without verifying which methods\n * they call.\n *\n * Targets @slack/oauth\\@3.0.5 InstallProvider internals.\n * Do not upgrade without running the integration tests.\n */\n\nimport { IncomingMessage, ServerResponse } from \"node:http\";\nimport { Socket } from \"node:net\";\n\nexport type ResponseCapture = ServerResponse & { toResponse(): Response };\n\n/**\n * Wraps a Web API Request as a minimal Node.js IncomingMessage\n * so it can be passed to @slack/oauth's InstallProvider methods.\n */\nexport function toIncomingMessage(req: Request): IncomingMessage {\n const url = new URL(req.url);\n // Dummy socket — satisfies the IncomingMessage constructor but is never connected.\n const msg = new IncomingMessage(new Socket());\n msg.url = url.pathname + url.search;\n msg.method = req.method;\n for (const [key, value] of req.headers.entries()) {\n msg.headers[key.toLowerCase()] = value;\n }\n\n if (req.body) {\n req\n .arrayBuffer()\n .then((buf) => {\n msg.push(Buffer.from(buf));\n msg.push(null);\n })\n .catch(() => msg.destroy());\n } else {\n msg.push(null);\n }\n\n return msg;\n}\n\n/**\n * Creates a fake ServerResponse that captures setHeader/writeHead/end calls\n * and converts them into a Web API Response.\n *\n * InstallProvider uses res.setHeader() for Location, Set-Cookie, Content-Type\n * and res.getHeader() to read back Set-Cookie before appending.\n */\nexport function createResponseCapture(): ResponseCapture {\n let statusCode = 200;\n const capturedHeaders: Record<string, string | string[]> = {};\n const chunks: Buffer[] = [];\n\n // Dummy socket/message pair — never connected, just satisfies the constructor.\n const res = new ServerResponse(new IncomingMessage(new Socket()));\n\n const originalSetHeader = res.setHeader.bind(res);\n res.setHeader = (\n name: string,\n value: string | number | readonly string[],\n ) => {\n const key = name.toLowerCase();\n if (Array.isArray(value)) {\n capturedHeaders[key] = [...value];\n } else {\n capturedHeaders[key] = String(value);\n }\n return originalSetHeader(name, value);\n };\n\n const originalGetHeader = res.getHeader.bind(res);\n res.getHeader = (name: string): string | number | string[] | undefined => {\n const val = capturedHeaders[name.toLowerCase()];\n if (val !== undefined) return val;\n return originalGetHeader(name);\n };\n\n const originalWriteHead = res.writeHead.bind(res);\n // writeHead has four overloads: (code), (code, message), (code, headers),\n // and (code, message, headers). We sniff for the first non-array object arg\n // to find the headers object in all cases.\n // biome-ignore lint/suspicious/noExplicitAny: writeHead has many overloads\n res.writeHead = (code: number, ...args: any[]) => {\n statusCode = code;\n const headersArg = args.find(\n (a) => a !== undefined && typeof a === \"object\" && !Array.isArray(a),\n ) as Record<string, string | string[]> | undefined;\n if (headersArg) {\n for (const [key, value] of Object.entries(headersArg)) {\n const lower = key.toLowerCase();\n capturedHeaders[lower] = value;\n }\n }\n return originalWriteHead(code, ...args);\n };\n\n const originalEnd = res.end.bind(res);\n // biome-ignore lint/suspicious/noExplicitAny: end has many overloads\n res.end = (chunk?: any, ...args: any[]) => {\n if (chunk !== undefined && chunk !== null) {\n chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk)));\n }\n return originalEnd(chunk, ...args);\n };\n\n (res as ResponseCapture).toResponse = () => {\n const body = chunks.length > 0 ? Buffer.concat(chunks).toString() : null;\n const webHeaders = new Headers();\n for (const [key, value] of Object.entries(capturedHeaders)) {\n if (Array.isArray(value)) {\n for (const v of value) webHeaders.append(key, v);\n } else {\n webHeaders.set(key, value);\n }\n }\n return new Response(body, { status: statusCode, headers: webHeaders });\n };\n\n return res as ResponseCapture;\n}\n","import {\n type AckFn,\n type App,\n type HTTPReceiverOptions,\n type Receiver,\n ReceiverAuthenticityError,\n type ReceiverEvent,\n ReceiverMultipleAckError,\n type StringIndexed,\n verifySlackRequest,\n} from \"@slack/bolt\";\nimport { ConsoleLogger, type Logger, LogLevel } from \"@slack/logger\";\nimport {\n type CallbackOptions,\n type InstallPathOptions,\n InstallProvider,\n type InstallProviderOptions,\n type InstallURLOptions,\n type StateStore,\n} from \"@slack/oauth\";\nimport { waitUntil } from \"@vercel/functions\";\nimport {\n ERROR_MESSAGES,\n getErrorMessage,\n getErrorType,\n getStatusCode,\n RequestParsingError,\n VercelReceiverError,\n} from \"./errors\";\nimport { createResponseCapture, toIncomingMessage } from \"./oauth-adapters\";\n\n// Types\n/**\n * A function to handle the request from the Slack app.\n * @param req - The request from the Slack app.\n * @returns A response object.\n */\nexport type VercelHandler = (req: Request) => Promise<Response>;\n\n/**\n * Configuration options for the VercelReceiver.\n * @property signingSecret - The signing secret for the Slack app.\n * @property signatureVerification - If true, verifies the Slack request signature.\n * @property logger - The logger to use for the VercelReceiver.\n * @property logLevel - The log level to use for the VercelReceiver.\n * @property customPropertiesExtractor - A function to extract custom properties from the request.\n */\n/**\n * Options for customizing the OAuth installer behavior.\n * Mirrors the relevant subset of HTTPReceiverInstallerOptions,\n * excluding path-related options (serverless uses file-based routing).\n */\nexport interface VercelInstallerOptions {\n directInstall?: boolean;\n renderHtmlForInstallPath?: (url: string) => string;\n stateStore?: StateStore;\n stateVerification?: boolean;\n legacyStateVerification?: boolean;\n stateCookieName?: string;\n stateCookieExpirationSeconds?: number;\n authVersion?: \"v1\" | \"v2\";\n clientOptions?: InstallProviderOptions[\"clientOptions\"];\n authorizationUrl?: string;\n metadata?: string;\n userScopes?: string[];\n installPathOptions?: InstallPathOptions;\n callbackOptions?: CallbackOptions;\n}\n\n/**\n * Configuration options for the VercelReceiver.\n */\nexport interface VercelReceiverOptions {\n /**\n * The signing secret for the Slack app.\n * @default process.env.SLACK_SIGNING_SECRET\n */\n signingSecret?: string;\n /**\n * If true, verifies the Slack request signature.\n * @default true\n */\n signatureVerification?: boolean;\n /**\n * The logger to use for the VercelReceiver.\n * @default new ConsoleLogger()\n */\n logger?: Logger;\n /**\n * The log level to use for the VercelReceiver.\n * @default LogLevel.INFO\n */\n logLevel?: LogLevel;\n /**\n * A function to extract custom properties from incoming events.\n * @default undefined\n * @returns An object with custom properties.\n */\n customPropertiesExtractor?: (req: Request) => StringIndexed;\n /**\n * The timeout in milliseconds for event acknowledgment.\n * @default 3001\n */\n ackTimeoutMs?: number;\n /**\n * Your app's client ID, found under Basic Information on api.slack.com.\n * Required for OAuth.\n * @default process.env.SLACK_CLIENT_ID\n */\n clientId?: string;\n /**\n * Your app's client secret, found under Basic Information on api.slack.com.\n * Required for OAuth.\n * @default process.env.SLACK_CLIENT_SECRET\n */\n clientSecret?: string;\n /**\n * Secret used to generate and verify the state parameter for OAuth CSRF protection.\n * Required unless a custom stateStore or stateVerification: false is provided.\n * @default process.env.SLACK_STATE_SECRET\n */\n stateSecret?: string;\n /**\n * The bot scopes to request during the OAuth flow.\n */\n scopes?: string[];\n /**\n * The redirect URI registered with your Slack app for OAuth callbacks.\n */\n redirectUri?: string;\n /**\n * Storage backend for OAuth installations (tokens, team info, etc.).\n * Required for OAuth in serverless -- the default in-memory store does not persist.\n */\n installationStore?: InstallProviderOptions[\"installationStore\"];\n /**\n * Advanced options for the OAuth installer.\n */\n installerOptions?: VercelInstallerOptions;\n}\n\n// ---------------------------------------------------------------------------\n// Compile-time shape assertions\n// Verify our types match Bolt's underlying shapes without coupling optionality.\n// If Bolt changes a type upstream, tsc breaks here -- not in user-land at runtime.\n// ---------------------------------------------------------------------------\ntype AssertShape<Source, Target> =\n NonNullable<Source> extends NonNullable<Target> ? true : never;\n\ntype _S1 = AssertShape<\n VercelReceiverOptions[\"clientId\"],\n HTTPReceiverOptions[\"clientId\"]\n>;\ntype _S2 = AssertShape<\n VercelReceiverOptions[\"clientSecret\"],\n HTTPReceiverOptions[\"clientSecret\"]\n>;\ntype _S3 = AssertShape<\n VercelReceiverOptions[\"stateSecret\"],\n HTTPReceiverOptions[\"stateSecret\"]\n>;\ntype _S4 = AssertShape<\n VercelReceiverOptions[\"scopes\"],\n HTTPReceiverOptions[\"scopes\"]\n>;\ntype _S5 = AssertShape<\n VercelReceiverOptions[\"redirectUri\"],\n HTTPReceiverOptions[\"redirectUri\"]\n>;\ntype _S6 = AssertShape<\n VercelReceiverOptions[\"installationStore\"],\n HTTPReceiverOptions[\"installationStore\"]\n>;\ntype _S7 = AssertShape<\n VercelInstallerOptions[\"stateVerification\"],\n InstallProviderOptions[\"stateVerification\"]\n>;\ntype _S8 = AssertShape<\n VercelInstallerOptions[\"callbackOptions\"],\n CallbackOptions\n>;\ntype _S9 = AssertShape<\n VercelInstallerOptions[\"stateStore\"],\n InstallProviderOptions[\"stateStore\"]\n>;\ntype _S10 = AssertShape<\n VercelInstallerOptions[\"authVersion\"],\n InstallProviderOptions[\"authVersion\"]\n>;\ntype _S11 = AssertShape<\n VercelInstallerOptions[\"userScopes\"],\n InstallURLOptions[\"userScopes\"]\n>;\ntype _S12 = AssertShape<\n VercelInstallerOptions[\"metadata\"],\n InstallURLOptions[\"metadata\"]\n>;\n\nconst LOG_PREFIX = \"[@vercel/slack-bolt]\";\nconst ACK_TIMEOUT_MS = 3001;\nconst SLACK_RETRY_NUM_HEADER = \"x-slack-retry-num\";\nconst SLACK_RETRY_REASON_HEADER = \"x-slack-retry-reason\";\nconst SLACK_TIMESTAMP_HEADER = \"x-slack-request-timestamp\";\nconst SLACK_SIGNATURE_HEADER = \"x-slack-signature\";\n\n/**\n * A Slack Bolt receiver implementation designed for Vercel's serverless environment.\n * Handles Slack events, interactions, and slash commands with automatic request verification,\n * background processing, and timeout management.\n *\n * @example\n * ```typescript\n * import { App } from '@slack/bolt';\n * import { VercelReceiver, createHandler } from '@vercel/slack-bolt';\n *\n * const receiver = new VercelReceiver();\n *\n * const app = new App({\n * receiver,\n * token: process.env.SLACK_BOT_TOKEN,\n * signingSecret: process.env.SLACK_SIGNING_SECRET,\n * });\n * ```\n *\n */\nexport class VercelReceiver implements Receiver {\n private readonly signingSecret: string;\n private readonly signatureVerification: boolean;\n private readonly logger: Logger;\n private readonly customPropertiesExtractor?: (req: Request) => StringIndexed;\n private readonly ackTimeoutMs: number;\n private app?: App;\n\n public installer?: InstallProvider;\n private installUrlOptions?: InstallURLOptions;\n private installCallbackOptions?: CallbackOptions;\n private installPathOptions?: InstallPathOptions;\n private stateVerification?: boolean;\n\n /**\n * Gets the logger instance used by this receiver.\n * @returns The logger instance\n */\n public getLogger(): Logger {\n return this.logger;\n }\n\n /**\n * Creates a new VercelReceiver instance.\n *\n * @param options - Configuration options for the receiver\n * @throws {VercelReceiverError} When signing secret is not provided\n *\n * @example\n * ```typescript\n * const receiver = new VercelReceiver();\n * ```\n */\n public constructor({\n signingSecret = process.env.SLACK_SIGNING_SECRET,\n signatureVerification = true,\n logger,\n logLevel = LogLevel.INFO,\n customPropertiesExtractor,\n ackTimeoutMs = ACK_TIMEOUT_MS,\n clientId = process.env.SLACK_CLIENT_ID,\n clientSecret = process.env.SLACK_CLIENT_SECRET,\n stateSecret = process.env.SLACK_STATE_SECRET,\n scopes,\n redirectUri,\n installationStore,\n installerOptions = {},\n }: VercelReceiverOptions = {}) {\n if (!signingSecret) {\n throw new VercelReceiverError(ERROR_MESSAGES.SIGNING_SECRET_REQUIRED);\n }\n\n this.signingSecret = signingSecret;\n this.signatureVerification = signatureVerification;\n this.logger = this.createScopedLogger(\n logger ?? new ConsoleLogger(),\n logLevel,\n );\n this.customPropertiesExtractor = customPropertiesExtractor;\n this.ackTimeoutMs = ackTimeoutMs;\n\n this.stateVerification = installerOptions.stateVerification;\n\n if (\n clientId !== undefined &&\n clientSecret !== undefined &&\n (installerOptions.stateVerification === false ||\n stateSecret !== undefined ||\n installerOptions.stateStore !== undefined)\n ) {\n this.installer = new InstallProvider({\n clientId,\n clientSecret,\n stateSecret,\n installationStore,\n logger,\n logLevel,\n directInstall: installerOptions.directInstall,\n stateStore: installerOptions.stateStore,\n stateVerification: installerOptions.stateVerification,\n legacyStateVerification: installerOptions.legacyStateVerification,\n stateCookieName: installerOptions.stateCookieName,\n stateCookieExpirationSeconds:\n installerOptions.stateCookieExpirationSeconds,\n renderHtmlForInstallPath: installerOptions.renderHtmlForInstallPath,\n authVersion: installerOptions.authVersion ?? \"v2\",\n clientOptions: installerOptions.clientOptions,\n authorizationUrl: installerOptions.authorizationUrl,\n });\n\n this.installUrlOptions = {\n scopes: scopes ?? [],\n userScopes: installerOptions.userScopes,\n metadata: installerOptions.metadata,\n redirectUri,\n };\n this.installCallbackOptions = installerOptions.callbackOptions ?? {};\n this.installPathOptions = installerOptions.installPathOptions ?? {};\n }\n\n this.logger.debug(\"VercelReceiver initialized\");\n }\n\n /**\n * Initializes the receiver with a Slack Bolt app instance.\n * This method is called automatically by the Bolt framework.\n *\n * @param app - The Slack Bolt app instance\n */\n public init(app: App): void {\n this.app = app;\n this.logger.debug(\"App initialized in VercelReceiver\");\n }\n\n /**\n * Starts the receiver and returns a handler function for processing requests.\n * This method is called automatically by the Bolt framework.\n *\n * @returns A handler function that processes incoming Slack requests\n */\n public async start(): Promise<VercelHandler> {\n this.logger.debug(\"VercelReceiver started\");\n return this.toHandler();\n }\n\n /**\n * Stops the receiver. This method is called automatically by the Bolt framework.\n */\n public async stop(): Promise<void> {\n this.logger.debug(\"VercelReceiver stopped\");\n }\n\n /**\n * Handles requests to the OAuth install path.\n * Renders an \"Add to Slack\" page or redirects directly to Slack's authorize URL.\n */\n public handleInstall = async (req: Request): Promise<Response> => {\n if (!this.installer) {\n throw new VercelReceiverError(ERROR_MESSAGES.OAUTH_NOT_CONFIGURED);\n }\n\n const nodeReq = toIncomingMessage(req);\n const capture = createResponseCapture();\n\n await this.installer.handleInstallPath(\n nodeReq,\n capture,\n this.installPathOptions,\n this.installUrlOptions,\n );\n\n return capture.toResponse();\n };\n\n /**\n * Handles the OAuth redirect callback from Slack.\n * Exchanges the authorization code for tokens and stores the installation.\n */\n public handleCallback = async (req: Request): Promise<Response> => {\n if (!this.installer) {\n throw new VercelReceiverError(ERROR_MESSAGES.OAUTH_NOT_CONFIGURED);\n }\n\n const nodeReq = toIncomingMessage(req);\n const capture = createResponseCapture();\n\n if (this.stateVerification === false) {\n await this.installer.handleCallback(\n nodeReq,\n capture,\n this.installCallbackOptions,\n this.installUrlOptions,\n );\n } else {\n await this.installer.handleCallback(\n nodeReq,\n capture,\n this.installCallbackOptions,\n );\n }\n\n return capture.toResponse();\n };\n\n /**\n * Creates a handler function that processes incoming Slack requests.\n * This is the main entry point for handling Slack events in Vercel.\n * It is called automatically by the Bolt framework in the start() method.\n *\n * @returns A handler function compatible with Vercel's function signature\n */\n public toHandler(): VercelHandler {\n return async (req: Request): Promise<Response> => {\n try {\n const rawBody = await req.text();\n\n if (this.signatureVerification) {\n this.verifyRequest(req, rawBody);\n }\n\n const body = await this.parseRequestBody(req, rawBody);\n\n if (body.type === \"url_verification\") {\n this.logger.debug(\"Handling URL verification challenge\");\n return Response.json({ challenge: body.challenge });\n }\n\n return await this.handleSlackEvent(req, body);\n } catch (error) {\n return this.handleError(error);\n }\n };\n }\n\n private async parseRequestBody(\n req: Request,\n rawBody: string,\n ): Promise<StringIndexed> {\n const contentType = req.headers.get(\"content-type\");\n\n try {\n if (contentType === \"application/x-www-form-urlencoded\") {\n const parsedBody: StringIndexed = {};\n const params = new URLSearchParams(rawBody);\n\n for (const [key, value] of params.entries()) {\n parsedBody[key] = value;\n }\n\n if (typeof parsedBody.payload === \"string\") {\n return JSON.parse(parsedBody.payload);\n }\n return parsedBody;\n }\n if (contentType === \"application/json\") {\n return JSON.parse(rawBody);\n }\n\n this.logger.warn(`Unexpected content-type detected: ${contentType}`);\n\n return JSON.parse(rawBody);\n } catch (e) {\n throw new RequestParsingError(\n `Failed to parse body as JSON data for content-type: ${contentType}. Error: ${\n e instanceof Error ? e.message : String(e)\n }`,\n );\n }\n }\n\n private async handleSlackEvent(\n req: Request,\n body: StringIndexed,\n ): Promise<Response> {\n if (!this.app) {\n throw new VercelReceiverError(ERROR_MESSAGES.APP_NOT_INITIALIZED, 500);\n }\n\n let isAcknowledged = false;\n let responseResolver: (value: Response) => void;\n let responseRejecter: (error: Error) => void;\n\n const responsePromise = new Promise<Response>((resolve, reject) => {\n responseResolver = resolve;\n responseRejecter = reject;\n });\n\n // Slack requires an acknowledgment from your app within 3 seconds\n const timeoutId = setTimeout(() => {\n if (!isAcknowledged) {\n isAcknowledged = true;\n this.logger.error(ERROR_MESSAGES.EVENT_NOT_ACKNOWLEDGED);\n const error = new VercelReceiverError(\n ERROR_MESSAGES.REQUEST_TIMEOUT,\n 408,\n );\n responseRejecter(error);\n }\n }, this.ackTimeoutMs);\n\n // Create acknowledgment function\n const ackFn: AckFn<StringIndexed> = async (responseBody) => {\n this.logger.debug(`ack() call begins (body: ${responseBody})`);\n if (isAcknowledged) {\n throw new ReceiverMultipleAckError();\n }\n\n isAcknowledged = true;\n clearTimeout(timeoutId);\n\n try {\n let body: string | undefined;\n if (typeof responseBody === \"undefined\") {\n body = undefined;\n } else if (typeof responseBody === \"string\") {\n body = responseBody;\n } else {\n body = JSON.stringify(responseBody);\n }\n const response = new Response(body, {\n status: 200,\n headers: {\n \"Content-Type\": \"application/json\",\n },\n });\n\n responseResolver(response);\n } catch (error) {\n this.logger.error(ERROR_MESSAGES.ACKNOWLEDGMENT_ERROR, error);\n responseRejecter(\n error instanceof Error ? error : new Error(String(error)),\n );\n }\n };\n\n const event = this.createSlackReceiverEvent({\n body,\n headers: req.headers,\n ack: ackFn,\n request: req,\n });\n\n // Process event in background using waitUntil from Vercel Functions\n // https://vercel.com/docs/functions/functions-api-reference/vercel-functions-package#waituntil\n waitUntil(\n this.app.processEvent(event).catch((error) => {\n return this.handleError(error);\n }),\n );\n\n try {\n return await responsePromise;\n } catch (error) {\n return this.handleError(error);\n }\n }\n\n private verifyRequest(req: Request, body: string): void {\n const timestamp = req.headers.get(SLACK_TIMESTAMP_HEADER);\n const signature = req.headers.get(SLACK_SIGNATURE_HEADER);\n\n if (!signature) {\n throw new ReceiverAuthenticityError(\n ERROR_MESSAGES.MISSING_REQUIRED_HEADER(SLACK_SIGNATURE_HEADER),\n );\n }\n\n if (!timestamp) {\n throw new ReceiverAuthenticityError(\n ERROR_MESSAGES.MISSING_REQUIRED_HEADER(SLACK_TIMESTAMP_HEADER),\n );\n }\n\n try {\n verifySlackRequest({\n signingSecret: this.signingSecret,\n body,\n headers: {\n \"x-slack-signature\": signature,\n \"x-slack-request-timestamp\": Number.parseInt(timestamp, 10),\n },\n logger: this.logger,\n });\n } catch (error) {\n throw new ReceiverAuthenticityError(\n error instanceof Error\n ? error.message\n : \"Failed to verify request signature\",\n );\n }\n }\n\n private createSlackReceiverEvent({\n body,\n headers,\n ack,\n request,\n }: {\n body: StringIndexed;\n headers: Headers;\n ack: AckFn<StringIndexed>;\n request: Request;\n }): ReceiverEvent {\n const customProperties = this.customPropertiesExtractor\n ? this.customPropertiesExtractor(request)\n : {};\n\n const retryNum = headers.get(SLACK_RETRY_NUM_HEADER) || \"0\";\n\n const retryReason = headers.get(SLACK_RETRY_REASON_HEADER) || \"\";\n\n return {\n body,\n ack,\n retryNum: Number(retryNum),\n retryReason,\n customProperties,\n };\n }\n\n public handleError(error: unknown): Response {\n const errorMessage = getErrorMessage(error);\n const errorType = getErrorType(error);\n const errorStatusCode = getStatusCode(error);\n\n this.logger.error(error);\n return new Response(\n JSON.stringify({\n error: errorMessage,\n type: errorType,\n }),\n {\n status: errorStatusCode,\n headers: { \"content-type\": \"application/json\" },\n },\n );\n }\n\n private createScopedLogger(logger: Logger, logLevel: LogLevel): Logger {\n logger.setLevel(logLevel);\n\n return {\n ...logger,\n error: (...args) => logger.error?.(LOG_PREFIX, ...args),\n warn: (...args) => logger.warn?.(LOG_PREFIX, ...args),\n info: (...args) => logger.info?.(LOG_PREFIX, ...args),\n debug: (...args) => logger.debug?.(LOG_PREFIX, ...args),\n setLevel: logger.setLevel,\n getLevel: logger.getLevel,\n };\n }\n}\n\n/**\n * Creates a Vercel-compatible handler function for a Slack Bolt app.\n * This is the recommended way to create handlers for deployment on Vercel.\n *\n * @param {App} app - The initialized Slack Bolt app instance.\n * @param {VercelReceiver} receiver - The VercelReceiver instance.\n * @returns {VercelHandler} A handler function compatible with Vercel's function signature.\n *\n * @example\n * ```typescript\n * // api/events.ts\n * import { createHandler } from '@vercel/slack-bolt';\n * import { app, receiver } from '../app';\n *\n * const handler = createHandler(app, receiver);\n *\n * export const POST = async (req: Request) => {\n * return handler(req);\n * };\n * ```\n *\n * @throws {Error} If app initialization fails.\n * @throws {VercelReceiverError} If request processing fails.\n */\nexport function createHandler(\n app: App,\n receiver: VercelReceiver,\n): VercelHandler {\n let initPromise: Promise<void> | null = null;\n\n return async (req: Request) => {\n try {\n if (!initPromise) {\n initPromise = app.init().catch((error) => {\n // Reset initPromise so subsequent requests can retry initialization\n initPromise = null;\n throw error;\n });\n }\n await initPromise;\n\n receiver.init(app);\n const handler = await receiver.start();\n return handler(req);\n } catch (error) {\n // if app.init fails, we use console.error instead of logger.error because the logger is not available\n console.error(ERROR_MESSAGES.CREATE_HANDLER_ERROR, error);\n return new Response(\n JSON.stringify({\n error: ERROR_MESSAGES.INTERNAL_SERVER_ERROR_HANDLER,\n type: ERROR_MESSAGES.TYPES.HANDLER_ERROR,\n }),\n { status: 500, headers: { \"content-type\": \"application/json\" } },\n );\n }\n };\n}\n"]}
|
package/dist/preview.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkDYB6RJG4_js = require('./chunk-DYB6RJG4.js');
|
|
4
4
|
require('./chunk-QHMZVK6J.js');
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
chunkDYB6RJG4_js.init_preview();
|
|
7
7
|
|
|
8
8
|
Object.defineProperty(exports, "preview", {
|
|
9
9
|
enumerable: true,
|
|
10
|
-
get: function () { return
|
|
10
|
+
get: function () { return chunkDYB6RJG4_js.preview; }
|
|
11
11
|
});
|
|
12
12
|
//# sourceMappingURL=preview.js.map
|
|
13
13
|
//# sourceMappingURL=preview.js.map
|
package/dist/preview.mjs
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vercel/slack-bolt",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
4
4
|
"description": "A Vercel receiver for building Slack apps with Bolt and deploying them to Vercel",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -53,6 +53,7 @@
|
|
|
53
53
|
"license": "MIT",
|
|
54
54
|
"dependencies": {
|
|
55
55
|
"@slack/logger": "^4.0.0",
|
|
56
|
+
"@slack/oauth": "3.0.5",
|
|
56
57
|
"@vercel/functions": "^3.4.3",
|
|
57
58
|
"commander": "^14.0.3",
|
|
58
59
|
"yaml": "^2.8.2",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/internal/manifest/index.ts","../src/internal/manifest/parse.ts","../src/internal/vercel/errors.ts","../src/internal/slack/errors.ts","../src/internal/slack/index.ts","../src/internal/vercel/index.ts","../src/logger.ts","../src/preview.ts"],"names":["__esm","path","parseYaml","stringifyYaml","init_errors","app","crypto","log","startMessage","preview","fs"],"mappings":"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","file":"chunk-JFHLS5RC.js","sourcesContent":["import type { Manifest } from \"./types\";\n\nexport function rewriteUrl(\n originalUrl: string,\n branchUrl: string,\n bypassSecret?: string,\n): string {\n const pathStart = originalUrl.indexOf(\"/\", originalUrl.indexOf(\"//\") + 2);\n const pathAndQuery = pathStart !== -1 ? originalUrl.slice(pathStart) : \"/\";\n\n const url = new URL(pathAndQuery, `https://${branchUrl}`);\n if (bypassSecret) {\n url.searchParams.set(\"x-vercel-protection-bypass\", bypassSecret);\n }\n return url.toString();\n}\n\nfunction createManifestDescription(params: {\n existingDescription: string;\n existingName: string;\n branchUrl: string;\n branch: string;\n commitSha?: string;\n commitMessage?: string;\n commitAuthor?: string;\n}): { longDescription: string; displayName: string } {\n const shortSha = params.commitSha?.slice(0, 7) ?? \"unknown\";\n const safeCommitMsg = params.commitMessage ?? \"\";\n const safeCommitAuthor = params.commitAuthor ?? \"unknown\";\n\n const deploymentInfo = `\\n:globe_with_meridians: *Deployment URL:* ${params.branchUrl}\\n:seedling: *Branch:* ${params.branch}\\n:technologist: *Commit:* ${shortSha} ${safeCommitMsg}\\n:bust_in_silhouette: *Last updated by:* ${safeCommitAuthor}\\n\\n_Automatically created by ▲ Vercel_\\n`;\n\n const maxLongDesc = 4000;\n const combined = params.existingDescription + deploymentInfo;\n let longDescription: string;\n if (combined.length > maxLongDesc) {\n const available = Math.max(0, maxLongDesc - deploymentInfo.length);\n longDescription = (\n params.existingDescription.slice(0, available) + deploymentInfo\n ).slice(0, maxLongDesc);\n } else {\n longDescription = combined;\n }\n\n const maxDisplayName = 35;\n const cleanBranch = params.branch\n .replace(/^refs\\/heads\\//, \"\")\n .replace(/\\//g, \"-\");\n\n let displayName = `${params.existingName} (${cleanBranch})`;\n if (displayName.length > maxDisplayName) {\n const prefix = `${params.existingName} (`;\n const suffix = \")\";\n const availableForBranch = maxDisplayName - prefix.length - suffix.length;\n displayName =\n availableForBranch > 0\n ? `${prefix}${cleanBranch.slice(0, availableForBranch)}${suffix}`\n : displayName.slice(0, maxDisplayName);\n }\n\n return { longDescription, displayName };\n}\n\nexport function createNewManifest(params: {\n originalManifest: Manifest;\n branchUrl: string;\n bypassSecret: string;\n branch: string;\n commitSha?: string;\n commitMessage?: string;\n commitAuthor?: string;\n}): Manifest {\n const manifest = structuredClone(params.originalManifest);\n\n if (manifest.settings?.event_subscriptions?.request_url) {\n manifest.settings.event_subscriptions.request_url = rewriteUrl(\n manifest.settings.event_subscriptions.request_url,\n params.branchUrl,\n params.bypassSecret,\n );\n }\n\n if (manifest.settings?.interactivity?.request_url) {\n manifest.settings.interactivity.request_url = rewriteUrl(\n manifest.settings.interactivity.request_url,\n params.branchUrl,\n params.bypassSecret,\n );\n }\n\n if (manifest.features?.slash_commands) {\n for (const cmd of manifest.features.slash_commands) {\n if (cmd.url) {\n cmd.url = rewriteUrl(cmd.url, params.branchUrl, params.bypassSecret);\n }\n }\n }\n\n if (manifest.oauth_config?.redirect_urls) {\n manifest.oauth_config.redirect_urls =\n manifest.oauth_config.redirect_urls.map((originalUrl) =>\n rewriteUrl(originalUrl, params.branchUrl),\n );\n }\n\n const { longDescription, displayName } = createManifestDescription({\n existingDescription: manifest.display_information.long_description ?? \"\",\n existingName:\n manifest.features?.bot_user?.display_name ??\n manifest.display_information.name,\n branchUrl: params.branchUrl,\n branch: params.branch,\n commitSha: params.commitSha,\n commitMessage: params.commitMessage,\n commitAuthor: params.commitAuthor,\n });\n\n manifest.display_information.long_description = longDescription;\n manifest.display_information.name = displayName;\n if (manifest.features?.bot_user) {\n manifest.features.bot_user.display_name = displayName;\n }\n\n return manifest;\n}\n","import path from \"node:path\";\nimport { parse as parseYaml, stringify as stringifyYaml } from \"yaml\";\nimport type { Manifest } from \"./types\";\n\nfunction isYaml(filePath: string): boolean {\n const ext = path.extname(filePath).toLowerCase();\n return ext === \".yaml\" || ext === \".yml\";\n}\n\nexport function parseManifest(raw: string, filePath: string): Manifest {\n if (isYaml(filePath)) {\n return parseYaml(raw) as Manifest;\n }\n return JSON.parse(raw) as Manifest;\n}\n\nexport function stringifyManifest(\n manifest: Manifest,\n filePath: string,\n): string {\n if (isYaml(filePath)) {\n return stringifyYaml(manifest);\n }\n return JSON.stringify(manifest, null, 2);\n}\n","export class HTTPError extends Error {\n constructor(\n message: string,\n public status: number,\n public statusText: string,\n public body?: string,\n ) {\n const parts = [`${message}: ${status} ${statusText}`];\n if (body) parts.push(body);\n super(parts.join(\" - \"));\n }\n\n static async fromResponse(\n message: string,\n response: Response,\n ): Promise<HTTPError> {\n let body: string | undefined;\n try {\n const text = await response.text();\n if (text) body = text;\n } catch {\n // body unreadable, that's fine\n }\n return new HTTPError(message, response.status, response.statusText, body);\n }\n}\n","export class SlackManifestCreateError extends Error {\n constructor(\n message: string,\n public errors?: { message: string; pointer: string }[],\n ) {\n super(message);\n }\n}\n\nexport class SlackManifestUpdateError extends Error {\n constructor(\n message: string,\n public errors?: { message: string; pointer: string }[],\n ) {\n super(message);\n }\n}\n\nexport class SlackManifestExportError extends Error {}\n","import type { Manifest } from \"../manifest/types\";\nimport { HTTPError } from \"../vercel/errors\";\nimport {\n SlackManifestCreateError,\n SlackManifestExportError,\n SlackManifestUpdateError,\n} from \"./errors\";\nimport type {\n InstallResponse,\n InstallResult,\n SlackManifestCreateResponse,\n SlackManifestExportResponse,\n SlackManifestUpdateResponse,\n} from \"./types\";\n\nexport {\n SlackManifestCreateError,\n SlackManifestExportError,\n SlackManifestUpdateError,\n} from \"./errors\";\nexport type {\n InstallResult,\n SlackManifestCreateResponse,\n SlackManifestExportResponse,\n SlackManifestUpdateResponse,\n} from \"./types\";\n\nexport async function createSlackApp({\n token,\n manifest,\n}: {\n token: string;\n manifest: Manifest;\n}): Promise<SlackManifestCreateResponse> {\n const response = await fetch(\"https://slack.com/api/apps.manifest.create\", {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${token}`,\n \"Content-Type\": \"application/json; charset=utf-8\",\n },\n body: JSON.stringify({ manifest: JSON.stringify(manifest) }),\n });\n\n if (!response.ok) {\n throw new HTTPError(\n \"Failed to create Slack app\",\n response.status,\n response.statusText,\n );\n }\n\n const data = (await response.json()) as SlackManifestCreateResponse;\n\n if (!data.ok) {\n throw new SlackManifestCreateError(\n data?.error ?? \"Unknown error\",\n data?.errors,\n );\n }\n\n return data;\n}\n\nexport async function updateSlackApp({\n token,\n appId,\n manifest,\n}: {\n token: string;\n appId: string;\n manifest: Manifest;\n}): Promise<SlackManifestUpdateResponse> {\n const response = await fetch(\"https://slack.com/api/apps.manifest.update\", {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${token}`,\n \"Content-Type\": \"application/json; charset=utf-8\",\n },\n body: JSON.stringify({\n app_id: appId,\n manifest: JSON.stringify(manifest),\n }),\n });\n\n if (!response.ok) {\n throw new HTTPError(\n \"Failed to update Slack app\",\n response.status,\n response.statusText,\n );\n }\n\n const data = (await response.json()) as SlackManifestUpdateResponse;\n\n if (!data.ok) {\n throw new SlackManifestUpdateError(\n data?.error ?? \"Unknown error\",\n data?.errors,\n );\n }\n\n return data;\n}\n\nexport async function exportSlackApp({\n token,\n appId,\n}: {\n token: string;\n appId: string;\n}): Promise<SlackManifestExportResponse> {\n const response = await fetch(\"https://slack.com/api/apps.manifest.export\", {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${token}`,\n \"Content-Type\": \"application/json; charset=utf-8\",\n },\n body: JSON.stringify({ app_id: appId }),\n });\n\n if (!response.ok) {\n throw new HTTPError(\n \"Failed to export Slack app\",\n response.status,\n response.statusText,\n );\n }\n\n const data = (await response.json()) as SlackManifestExportResponse;\n\n if (!data.ok) {\n throw new SlackManifestExportError(data?.error ?? \"Unknown error\");\n }\n\n return data;\n}\n\nexport async function upsertSlackApp({\n token,\n appId,\n manifest,\n}: {\n token: string;\n appId?: string;\n manifest: Manifest;\n}): Promise<\n | { isNew: true; app: SlackManifestCreateResponse }\n | { isNew: false; app: SlackManifestUpdateResponse }\n> {\n if (appId) {\n try {\n await exportSlackApp({ token, appId });\n const app = await updateSlackApp({ token, appId, manifest });\n return { isNew: false, app };\n } catch {\n // App doesn't exist or isn't accessible — fall through to create\n }\n }\n\n const app = await createSlackApp({ token, manifest });\n return { isNew: true, app };\n}\n\nexport async function deleteSlackApp({\n token,\n appId,\n}: {\n token: string;\n appId: string;\n}): Promise<void> {\n const response = await fetch(\"https://slack.com/api/apps.manifest.delete\", {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${token}`,\n \"Content-Type\": \"application/json; charset=utf-8\",\n },\n body: JSON.stringify({ app_id: appId }),\n });\n\n if (!response.ok) {\n throw new HTTPError(\n \"Failed to delete Slack app\",\n response.status,\n response.statusText,\n );\n }\n\n const data = (await response.json()) as { ok: boolean; error?: string };\n\n if (!data.ok) {\n throw new Error(data.error ?? \"Unknown error\");\n }\n}\n\nexport type RotateTokenResult = {\n token: string;\n refreshToken: string;\n exp: number;\n};\n\nexport async function rotateConfigToken({\n refreshToken,\n}: {\n refreshToken: string;\n}): Promise<RotateTokenResult> {\n const response = await fetch(\"https://slack.com/api/tooling.tokens.rotate\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n body: new URLSearchParams({ refresh_token: refreshToken }),\n });\n\n if (!response.ok) {\n throw new HTTPError(\n \"Failed to rotate configuration token\",\n response.status,\n response.statusText,\n );\n }\n\n const data = (await response.json()) as {\n ok: boolean;\n error?: string;\n token?: string;\n refresh_token?: string;\n exp?: number;\n };\n\n if (!data.ok || !data.token || !data.refresh_token) {\n throw new Error(data.error ?? \"Unknown error rotating token\");\n }\n\n return {\n token: data.token,\n refreshToken: data.refresh_token,\n exp: data.exp ?? 0,\n };\n}\n\nexport async function authTest({ token }: { token: string }): Promise<void> {\n const response = await fetch(\"https://slack.com/api/auth.test\", {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${token}`,\n \"Content-Type\": \"application/json; charset=utf-8\",\n },\n });\n\n if (!response.ok) {\n throw new HTTPError(\n \"Auth test failed\",\n response.status,\n response.statusText,\n );\n }\n\n const data = (await response.json()) as { ok: boolean; error?: string };\n\n if (!data.ok) {\n throw new Error(data.error ?? \"Unknown error\");\n }\n}\n\nexport async function installApp(params: {\n serviceToken?: string;\n appId: string;\n botScopes: string[];\n outgoingDomains?: string[];\n}): Promise<InstallResult> {\n const { serviceToken, appId, botScopes, outgoingDomains } = params;\n\n if (!serviceToken) {\n return {\n status: \"missing_service_token\",\n };\n }\n\n const response = await fetch(\"https://slack.com/api/apps.developerInstall\", {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${serviceToken}`,\n \"Content-Type\": \"application/json; charset=utf-8\",\n },\n body: JSON.stringify({\n app_id: appId,\n bot_scopes: botScopes,\n outgoing_domains: outgoingDomains ?? [],\n }),\n });\n\n if (!response.ok) {\n return {\n status: \"slack_api_error\",\n error: response.statusText,\n };\n }\n\n const data = (await response.json()) as InstallResponse;\n\n if (data.error) {\n switch (data.error) {\n case \"app_approval_request_eligible\":\n return {\n status: \"app_approval_request_eligible\",\n };\n case \"app_approval_request_pending\":\n return {\n status: \"app_approval_request_pending\",\n };\n case \"app_approval_request_denied\":\n return {\n status: \"app_approval_request_denied\",\n };\n default:\n return {\n status: \"unknown_error\",\n };\n }\n }\n\n return {\n status: \"installed\",\n botToken: data.api_access_tokens?.bot,\n appLevelToken: data.api_access_tokens?.app_level,\n userToken: data.api_access_tokens?.user,\n };\n}\n","import crypto from \"node:crypto\";\nimport { HTTPError } from \"./errors\";\nimport type {\n AddEnvironmentVariablesResult,\n CreateProjectEnv,\n EnvironmentVariable,\n} from \"./types\";\n\nexport async function getProject({\n projectId,\n token,\n teamId,\n}: {\n projectId: string;\n token: string;\n teamId?: string;\n}): Promise<void> {\n const url = new URL(\n `https://api.vercel.com/v9/projects/${encodeURIComponent(projectId)}`,\n );\n if (teamId) url.searchParams.set(\"teamId\", teamId);\n\n const response = await fetch(url, {\n method: \"GET\",\n headers: {\n Authorization: `Bearer ${token}`,\n },\n });\n\n if (!response.ok) {\n throw await HTTPError.fromResponse(\n \"Failed to access Vercel project\",\n response,\n );\n }\n}\n\nexport async function updateProtectionBypass({\n projectId,\n token,\n teamId,\n}: {\n projectId: string;\n token: string;\n teamId?: string;\n}): Promise<string> {\n const newSecret = crypto.randomBytes(16).toString(\"hex\");\n const note = \"Created by @vercel/slack-bolt\";\n\n const url = new URL(\n `https://api.vercel.com/v1/projects/${encodeURIComponent(projectId)}/protection-bypass`,\n );\n if (teamId) url.searchParams.set(\"teamId\", teamId);\n\n const response = await fetch(url, {\n method: \"PATCH\",\n headers: {\n Authorization: `Bearer ${token}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n generate: {\n secret: newSecret,\n note: note,\n },\n }),\n });\n\n if (!response.ok) {\n throw await HTTPError.fromResponse(\n \"Failed to update protection bypass\",\n response,\n );\n }\n\n return newSecret;\n}\n\nexport async function addEnvironmentVariables({\n projectId,\n token,\n teamId,\n envs,\n upsert = true,\n}: {\n projectId: string;\n token: string;\n teamId?: string;\n envs: CreateProjectEnv | CreateProjectEnv[];\n upsert?: boolean;\n}): Promise<AddEnvironmentVariablesResult> {\n const url = new URL(\n `https://api.vercel.com/v10/projects/${encodeURIComponent(projectId)}/env`,\n );\n if (teamId) url.searchParams.set(\"teamId\", teamId);\n if (upsert) url.searchParams.set(\"upsert\", \"true\");\n\n const response = await fetch(url, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${token}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(envs),\n });\n\n if (!response.ok) {\n throw await HTTPError.fromResponse(\n \"Failed to create environment variables\",\n response,\n );\n }\n\n return response.json();\n}\n\nexport async function cancelDeployment({\n deploymentId,\n token,\n teamId,\n}: {\n deploymentId: string;\n token: string;\n teamId?: string;\n}): Promise<void> {\n const url = new URL(\n `https://api.vercel.com/v12/deployments/${encodeURIComponent(deploymentId)}/cancel`,\n );\n if (teamId) url.searchParams.set(\"teamId\", teamId);\n\n const response = await fetch(url, {\n method: \"PATCH\",\n headers: { Authorization: `Bearer ${token}` },\n });\n\n if (!response.ok) {\n throw await HTTPError.fromResponse(\"Failed to cancel deployment\", response);\n }\n}\n\nexport async function createDeployment({\n deploymentId,\n projectId,\n token,\n teamId,\n}: {\n deploymentId: string;\n projectId: string;\n token: string;\n teamId?: string;\n}): Promise<{ id: string; url: string }> {\n const url = new URL(\"https://api.vercel.com/v13/deployments\");\n if (teamId) url.searchParams.set(\"teamId\", teamId);\n url.searchParams.set(\"forceNew\", \"1\");\n\n const response = await fetch(url, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${token}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n deploymentId,\n name: projectId,\n project: projectId,\n }),\n });\n\n if (!response.ok) {\n throw await HTTPError.fromResponse(\"Failed to create deployment\", response);\n }\n\n const data = await response.json();\n return { id: data.id, url: data.url };\n}\n\nexport async function getActiveBranches({\n projectId,\n token,\n teamId,\n}: {\n projectId: string;\n token: string;\n teamId?: string;\n}): Promise<Set<string>> {\n const params = new URLSearchParams({ active: \"1\", limit: \"100\" });\n if (teamId) params.set(\"teamId\", teamId);\n\n const response = await fetch(\n `https://api.vercel.com/v5/projects/${encodeURIComponent(projectId)}/branches?${params}`,\n { headers: { Authorization: `Bearer ${token}` } },\n );\n\n if (!response.ok) {\n throw await HTTPError.fromResponse(\n \"Failed to fetch active branches\",\n response,\n );\n }\n\n const data: { branches?: { branch: string }[] } = await response.json();\n return new Set(data.branches?.map((b) => b.branch) ?? []);\n}\n\nexport async function getEnvironmentVariables({\n projectId,\n token,\n teamId,\n}: {\n projectId: string;\n token: string;\n teamId?: string;\n}): Promise<EnvironmentVariable[]> {\n const url = new URL(\n `https://api.vercel.com/v9/projects/${encodeURIComponent(projectId)}/env`,\n );\n if (teamId) url.searchParams.set(\"teamId\", teamId);\n\n const response = await fetch(url, {\n headers: { Authorization: `Bearer ${token}` },\n });\n\n if (!response.ok) {\n throw await HTTPError.fromResponse(\n \"Failed to fetch environment variables\",\n response,\n );\n }\n\n const data: { envs: EnvironmentVariable[] } = await response.json();\n return data.envs ?? [];\n}\n\nexport async function getEnvironmentVariable({\n projectId,\n envId,\n token,\n teamId,\n}: {\n projectId: string;\n envId: string;\n token: string;\n teamId?: string;\n}): Promise<string | null> {\n const url = new URL(\n `https://api.vercel.com/v9/projects/${encodeURIComponent(projectId)}/env/${encodeURIComponent(envId)}`,\n );\n if (teamId) url.searchParams.set(\"teamId\", teamId);\n\n const response = await fetch(url, {\n headers: { Authorization: `Bearer ${token}` },\n });\n\n if (!response.ok) {\n throw await HTTPError.fromResponse(\n \"Failed to fetch environment variable\",\n response,\n );\n }\n\n const data: { value?: string } = await response.json();\n return data.value ?? null;\n}\n\nexport async function deleteEnvironmentVariable({\n projectId,\n envId,\n token,\n teamId,\n}: {\n projectId: string;\n envId: string;\n token: string;\n teamId?: string;\n}): Promise<void> {\n const url = new URL(\n `https://api.vercel.com/v9/projects/${encodeURIComponent(projectId)}/env/${encodeURIComponent(envId)}`,\n );\n if (teamId) url.searchParams.set(\"teamId\", teamId);\n\n const response = await fetch(url, {\n method: \"DELETE\",\n headers: { Authorization: `Bearer ${token}` },\n });\n\n if (!response.ok) {\n throw await HTTPError.fromResponse(\n \"Failed to delete environment variable\",\n response,\n );\n }\n}\n","function isDebug(): boolean {\n return (\n process.env.VERCEL_SLACK_DEBUG === \"1\" ||\n process.env.VERCEL_SLACK_DEBUG === \"true\"\n );\n}\n\nconst BOLD = \"\\x1b[1m\";\nconst RESET = \"\\x1b[0m\";\nconst DIM = \"\\x1b[2m\";\nconst GREEN = \"\\x1b[32m\";\nconst YELLOW = \"\\x1b[33m\";\n\ntype PatchedFetch = typeof globalThis.fetch & { __debugPatched?: boolean };\n\nexport const log = {\n step: (msg: string) => console.log(` ${msg} ...`),\n success: (msg: string) => console.log(`${GREEN}✓${RESET} ${msg}`),\n info: (msg: string) => console.log(` ${msg}`),\n warning: (msg: string) => console.log(`${YELLOW}⚠${RESET} ${msg}`),\n error: (...args: unknown[]) => console.error(...args),\n debug: (...args: unknown[]) => {\n if (isDebug()) {\n const msg = args\n .map((a) => (typeof a === \"string\" ? a : String(a)))\n .join(\" \");\n console.debug(`${DIM}${msg}${RESET}`);\n }\n },\n};\n\nconst REDACTED_HEADERS = new Set([\"authorization\"]);\n\n/**\n * Keys whose values should be redacted when logging request/response bodies.\n * Matches are case-insensitive and checked against the lowercased key.\n */\nconst SENSITIVE_BODY_KEYS = new Set([\n \"token\",\n \"bot\",\n \"app_level\",\n \"user\",\n \"secret\",\n \"client_secret\",\n \"signing_secret\",\n \"verification_token\",\n \"bot_token\",\n \"user_token\",\n \"app_level_token\",\n \"value\",\n \"access_token\",\n \"refresh_token\",\n \"password\",\n]);\n\n/**\n * Key name fragments — if any of these appear in a key name (case-insensitive),\n * the value is redacted.\n */\nconst SENSITIVE_KEY_PATTERNS = [\"token\", \"secret\", \"password\", \"credential\"];\n\nfunction isSensitiveKey(key: string): boolean {\n const lower = key.toLowerCase();\n if (SENSITIVE_BODY_KEYS.has(lower)) return true;\n return SENSITIVE_KEY_PATTERNS.some((pattern) => lower.includes(pattern));\n}\n\nfunction redactValue(value: string): string {\n if (value.length <= 4) return \"****\";\n return `****${value.slice(-4)}`;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction redactSensitiveFields(obj: any): any {\n if (Array.isArray(obj)) {\n return obj.map((item) => redactSensitiveFields(item));\n }\n if (obj !== null && typeof obj === \"object\") {\n const result: Record<string, unknown> = {};\n for (const [key, val] of Object.entries(obj)) {\n if (isSensitiveKey(key) && typeof val === \"string\") {\n result[key] = redactValue(val);\n } else {\n result[key] = redactSensitiveFields(val);\n }\n }\n return result;\n }\n return obj;\n}\n\nfunction redactBody(body: string): string {\n try {\n const parsed = JSON.parse(body) as unknown;\n const redacted = redactSensitiveFields(parsed);\n return JSON.stringify(redacted);\n } catch {\n // Not JSON — redact entirely to be safe since we can't inspect the structure\n return `<non-JSON body, ${body.length} bytes>`;\n }\n}\n\nfunction formatHeaders(headers?: HeadersInit): string {\n const entries =\n headers instanceof Headers\n ? [...headers.entries()]\n : Object.entries(headers ?? {});\n const redacted = entries.map(([k, v]) =>\n REDACTED_HEADERS.has(k.toLowerCase()) ? [k, `****${v.slice(-4)}`] : [k, v],\n );\n return JSON.stringify(Object.fromEntries(redacted));\n}\n\nexport function enableFetchDebugLogging(): void {\n if ((globalThis.fetch as PatchedFetch).__debugPatched) return;\n\n const originalFetch = globalThis.fetch;\n const patched: PatchedFetch = async (input, init) => {\n const method = init?.method ?? \"GET\";\n const url = input instanceof Request ? input.url : input.toString();\n const start = performance.now();\n log.debug(`-> ${method} ${url}`);\n log.debug(` headers: ${formatHeaders(init?.headers)}`);\n if (typeof init?.body === \"string\")\n log.debug(` body: ${redactBody(init.body)}`);\n\n const response = await originalFetch(input, init);\n\n const ms = (performance.now() - start).toFixed(0);\n log.debug(`<- ${response.status} ${response.statusText} (${ms}ms)`);\n log.debug(` headers: ${formatHeaders(response.headers)}`);\n\n const clone = response.clone();\n try {\n const body = await clone.text();\n if (body) log.debug(` body: ${redactBody(body)}`);\n } catch {}\n\n return response;\n };\n patched.__debugPatched = true;\n globalThis.fetch = patched;\n}\n\nexport const startMessage = (\n version?: string,\n branch?: string,\n commit?: string,\n appId?: string,\n) => {\n const lines = [`▲ @vercel/slack-bolt ${version ?? \"\"}`];\n if (branch) lines.push(` - Branch: ${branch}`);\n if (commit) lines.push(` - Commit: ${commit.slice(0, 7)}`);\n if (appId) lines.push(` - App ID: ${appId}`);\n return `${BOLD}${lines.join(\"\\n\")}${RESET}\\n`;\n};\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { createNewManifest } from \"./internal/manifest\";\nimport { parseManifest, stringifyManifest } from \"./internal/manifest/parse\";\nimport { installApp, upsertSlackApp } from \"./internal/slack\";\nimport type {\n SlackManifestCreateResponse,\n SlackManifestUpdateResponse,\n} from \"./internal/slack/types\";\nimport {\n addEnvironmentVariables,\n updateProtectionBypass,\n} from \"./internal/vercel\";\nimport type { CreateProjectEnv } from \"./internal/vercel/types\";\nimport { log } from \"./logger\";\n\nexport type PreviewParams = {\n slackConfigRefreshToken?: string;\n automationBypassSecret?: string;\n branch: string;\n branchUrl?: string;\n commitAuthor?: string;\n commitMessage?: string;\n commitSha?: string;\n deploymentId?: string;\n deploymentUrl: string;\n manifestPath: string;\n projectId: string;\n slackAppId?: string;\n slackConfigurationToken: string;\n slackServiceToken?: string;\n teamId?: string;\n vercelApiToken: string;\n};\n\nexport type PreviewResult = {\n isNew: boolean;\n installStatus: string;\n app: SlackManifestCreateResponse | SlackManifestUpdateResponse;\n};\n\nexport const preview = async (\n params: PreviewParams,\n context?: \"cli\",\n): Promise<PreviewResult> => {\n const {\n branch,\n projectId,\n deploymentUrl,\n teamId,\n commitAuthor,\n commitMessage: commitMsg,\n commitSha,\n slackAppId,\n slackConfigurationToken,\n slackServiceToken,\n manifestPath,\n vercelApiToken,\n } = params;\n\n const cli = context === \"cli\";\n const branchUrl = params.branchUrl ?? deploymentUrl;\n let bypassSecret = params.automationBypassSecret;\n\n if (!bypassSecret) {\n if (cli) log.step(\"Generating automation bypass secret\");\n bypassSecret = await updateProtectionBypass({\n projectId,\n token: vercelApiToken,\n teamId,\n });\n if (cli) log.success(\"Automation bypass secret generated\");\n }\n\n if (cli) log.step(`Reading manifest from ${manifestPath}`);\n const rawFileManifest = fs.readFileSync(\n path.join(process.cwd(), manifestPath),\n \"utf8\",\n );\n const manifest = parseManifest(rawFileManifest, manifestPath);\n\n const newManifest = createNewManifest({\n originalManifest: manifest,\n branchUrl,\n bypassSecret,\n branch,\n commitSha,\n commitMessage: commitMsg,\n commitAuthor,\n });\n\n // write new manifest so user-land imports of manifest.json see the updated version\n fs.writeFileSync(\n path.join(process.cwd(), manifestPath),\n stringifyManifest(newManifest, manifestPath),\n \"utf8\",\n );\n if (cli) log.success(`Manifest updated for ${branchUrl}`);\n\n if (cli) log.step(\"Creating or updating Slack app\");\n const { isNew, app } = await upsertSlackApp({\n token: slackConfigurationToken,\n appId: slackAppId,\n manifest: newManifest,\n });\n\n if (isNew) {\n const credentialEnvs: CreateProjectEnv[] = [];\n if (app.app_id) {\n credentialEnvs.push({\n key: \"SLACK_APP_ID\",\n value: app.app_id,\n type: \"encrypted\",\n target: [\"preview\"],\n gitBranch: branch,\n comment: `Created by @vercel/slack-bolt for app ${app.app_id} on branch ${branch}`,\n });\n }\n if (app.credentials?.client_id) {\n credentialEnvs.push({\n key: \"SLACK_CLIENT_ID\",\n value: app.credentials.client_id,\n type: \"encrypted\",\n target: [\"preview\"],\n gitBranch: branch,\n comment: `Created by @vercel/slack-bolt for app ${app.app_id} on branch ${branch}`,\n });\n }\n if (app.credentials?.client_secret) {\n credentialEnvs.push({\n key: \"SLACK_CLIENT_SECRET\",\n value: app.credentials.client_secret,\n type: \"encrypted\",\n target: [\"preview\"],\n gitBranch: branch,\n comment: `Created by @vercel/slack-bolt for app ${app.app_id} on branch ${branch}`,\n });\n }\n if (app.credentials?.signing_secret) {\n credentialEnvs.push({\n key: \"SLACK_SIGNING_SECRET\",\n value: app.credentials.signing_secret,\n type: \"encrypted\",\n target: [\"preview\"],\n gitBranch: branch,\n comment: `Created by @vercel/slack-bolt for app ${app.app_id} on branch ${branch}`,\n });\n }\n if (credentialEnvs.length > 0) {\n await addEnvironmentVariables({\n projectId,\n token: vercelApiToken,\n teamId,\n envs: credentialEnvs,\n });\n }\n }\n\n if (cli)\n log.success(`${isNew ? \"Created\" : \"Updated\"} Slack app ${app.app_id}`);\n\n if (cli) log.step(\"Installing Slack app\");\n const { status, botToken, appLevelToken, userToken } = await installApp({\n serviceToken: slackServiceToken,\n appId: app.app_id,\n botScopes: manifest.oauth_config?.scopes?.bot ?? [],\n });\n\n if (isNew) {\n const tokenEnvs: CreateProjectEnv[] = [];\n if (botToken) {\n tokenEnvs.push({\n key: \"SLACK_BOT_TOKEN\",\n value: botToken,\n type: \"encrypted\",\n target: [\"preview\"],\n gitBranch: branch,\n comment: `Created by @vercel/slack-bolt for app ${app.app_id} on branch ${branch}`,\n });\n }\n if (appLevelToken) {\n tokenEnvs.push({\n key: \"SLACK_APP_LEVEL_TOKEN\",\n value: appLevelToken,\n type: \"encrypted\",\n target: [\"preview\"],\n gitBranch: branch,\n comment: `Created by @vercel/slack-bolt for app ${app.app_id} on branch ${branch}`,\n });\n }\n if (userToken) {\n tokenEnvs.push({\n key: \"SLACK_USER_TOKEN\",\n value: userToken,\n type: \"encrypted\",\n target: [\"preview\"],\n gitBranch: branch,\n comment: `Created by @vercel/slack-bolt for app ${app.app_id} on branch ${branch}`,\n });\n }\n if (tokenEnvs.length > 0) {\n await addEnvironmentVariables({\n projectId,\n token: vercelApiToken,\n teamId,\n envs: tokenEnvs,\n });\n }\n }\n\n if (cli) {\n switch (status) {\n case \"missing_service_token\":\n log.warning(\n \"SLACK_SERVICE_TOKEN is not set — app must be installed manually\",\n );\n log.info(\"https://docs.slack.dev/authentication/tokens/#service\");\n break;\n case \"installed\":\n log.success(`Installed Slack app ${app.app_id}`);\n break;\n case \"app_approval_request_eligible\":\n log.warning(\"App requires approval before it can be installed\");\n break;\n case \"app_approval_request_pending\":\n log.warning(\"App is pending approval before it can be installed\");\n break;\n case \"app_approval_request_denied\":\n log.warning(\"App approval request was denied\");\n break;\n case \"slack_api_error\":\n log.warning(\"Slack API error while installing the app\");\n break;\n case \"unknown_error\":\n log.warning(\"Unknown error while installing the app\");\n break;\n }\n console.log();\n if (app.app_id) {\n log.info(`View app: https://api.slack.com/apps/${app.app_id}`);\n }\n if (isNew && app.oauth_authorize_url) {\n log.info(`Install URL: ${app.oauth_authorize_url}`);\n }\n console.log();\n }\n\n return {\n isNew,\n installStatus: status,\n app,\n };\n};\n"]}
|