@slack/bolt
Advanced tools
Comparing version 4.2.0-autoack.1 to 4.2.0
@@ -8,3 +8,3 @@ /// <reference types="node" /> | ||
import type { Assistant } from './Assistant'; | ||
import { type SlackCustomFunctionMiddlewareArgs } from './CustomFunction'; | ||
import { type CustomFunctionMiddleware } from './CustomFunction'; | ||
import type { WorkflowStep } from './WorkflowStep'; | ||
@@ -15,3 +15,3 @@ import { type ConversationStore } from './conversation-store'; | ||
import SocketModeReceiver from './receivers/SocketModeReceiver'; | ||
import type { ActionConstraints, AnyMiddlewareArgs, Context, Middleware, OptionsConstraints, OptionsSource, Receiver, ReceiverEvent, ShortcutConstraints, SlackAction, SlackActionMiddlewareArgs, SlackCommandMiddlewareArgs, SlackEventMiddlewareArgs, SlackEventMiddlewareArgsOptions, SlackOptionsMiddlewareArgs, SlackShortcut, SlackShortcutMiddlewareArgs, SlackViewAction, SlackViewMiddlewareArgs, ViewConstraints } from './types'; | ||
import type { ActionConstraints, AnyMiddlewareArgs, Context, Middleware, OptionsConstraints, OptionsSource, Receiver, ReceiverEvent, ShortcutConstraints, SlackAction, SlackActionMiddlewareArgs, SlackCommandMiddlewareArgs, SlackEventMiddlewareArgs, SlackOptionsMiddlewareArgs, SlackShortcut, SlackShortcutMiddlewareArgs, SlackViewAction, SlackViewMiddlewareArgs, ViewConstraints } from './types'; | ||
import { type StringIndexed } from './types/utilities'; | ||
@@ -101,3 +101,3 @@ export type { ActionConstraints, OptionsConstraints, ShortcutConstraints, ViewConstraints } from './types'; | ||
/** Logger */ | ||
private logger; | ||
logger: Logger; | ||
/** Log Level */ | ||
@@ -132,5 +132,3 @@ private logLevel; | ||
*/ | ||
use<MiddlewareCustomContext extends StringIndexed = StringIndexed>(m: Middleware<AnyMiddlewareArgs<{ | ||
autoAcknowledge: false; | ||
}>, AppCustomContext & MiddlewareCustomContext>): this; | ||
use<MiddlewareCustomContext extends StringIndexed = StringIndexed>(m: Middleware<AnyMiddlewareArgs, AppCustomContext & MiddlewareCustomContext>): this; | ||
/** | ||
@@ -153,8 +151,3 @@ * Register Assistant middleware | ||
*/ | ||
function<Options extends SlackEventMiddlewareArgsOptions = { | ||
autoAcknowledge: true; | ||
}>(callbackId: string, options: Options, ...listeners: Middleware<SlackCustomFunctionMiddlewareArgs<Options>>[]): this; | ||
function<Options extends SlackEventMiddlewareArgsOptions = { | ||
autoAcknowledge: true; | ||
}>(callbackId: string, ...listeners: Middleware<SlackCustomFunctionMiddlewareArgs<Options>>[]): this; | ||
function(callbackId: string, ...listeners: CustomFunctionMiddleware): this; | ||
/** | ||
@@ -161,0 +154,0 @@ * Convenience method to call start on the receiver |
118
dist/App.js
@@ -19,3 +19,3 @@ "use strict"; | ||
const SocketModeReceiver_1 = __importDefault(require("./receivers/SocketModeReceiver")); | ||
const middleware_1 = require("./types/middleware"); | ||
const types_1 = require("./types"); | ||
const utilities_1 = require("./types/utilities"); | ||
@@ -276,12 +276,9 @@ const packageJson = require('../package.json'); | ||
} | ||
function(callbackId, ...optionOrListeners) { | ||
// TODO: fix this casting; edge case is if dev specifically sets AutoAck generic as false, this true assignment is invalid according to TS. | ||
const options = (0, builtin_1.isSlackEventMiddlewareArgsOptions)(optionOrListeners[0]) | ||
? optionOrListeners[0] | ||
: { autoAcknowledge: true }; | ||
const listeners = optionOrListeners.filter((optionOrListener) => { | ||
return !(0, builtin_1.isSlackEventMiddlewareArgsOptions)(optionOrListener); | ||
}); | ||
const fn = new CustomFunction_1.CustomFunction(callbackId, listeners, options); | ||
this.listeners.push(fn.getListeners()); | ||
/** | ||
* Register CustomFunction middleware | ||
*/ | ||
function(callbackId, ...listeners) { | ||
const fn = new CustomFunction_1.CustomFunction(callbackId, listeners, this.webClientOptions); | ||
const m = fn.getMiddleware(); | ||
this.middleware.push(m); | ||
return this; | ||
@@ -487,3 +484,3 @@ } | ||
const customProps = event.customProperties; | ||
const builtinKeyDetected = middleware_1.contextBuiltinKeys.find((key) => key in customProps); | ||
const builtinKeyDetected = types_1.contextBuiltinKeys.find((key) => key in customProps); | ||
if (typeof builtinKeyDetected !== 'undefined') { | ||
@@ -516,3 +513,3 @@ throw new errors_1.InvalidCustomPropertyError('customProperties cannot have the same names with the built-in ones'); | ||
const createSay = (channelId) => { | ||
const token = selectToken(context, this.attachFunctionToken); | ||
const token = selectToken(context); | ||
return (message) => { | ||
@@ -560,33 +557,7 @@ let postMessageArguments; | ||
body: bodyArg, | ||
ack, | ||
payload, | ||
}; | ||
// Get the client arg | ||
let { client } = this; | ||
const token = selectToken(context, this.attachFunctionToken); | ||
if (token !== undefined) { | ||
let pool = undefined; | ||
const clientOptionsCopy = { ...this.clientOptions }; | ||
if (authorizeResult.teamId !== undefined) { | ||
pool = this.clients[authorizeResult.teamId]; | ||
if (pool === undefined) { | ||
pool = this.clients[authorizeResult.teamId] = new WebClientPool(); | ||
} | ||
// Add teamId to clientOptions so it can be automatically added to web-api calls | ||
clientOptionsCopy.teamId = authorizeResult.teamId; | ||
} | ||
else if (authorizeResult.enterpriseId !== undefined) { | ||
pool = this.clients[authorizeResult.enterpriseId]; | ||
if (pool === undefined) { | ||
pool = this.clients[authorizeResult.enterpriseId] = new WebClientPool(); | ||
} | ||
} | ||
if (pool !== undefined) { | ||
client = pool.getOrCreate(token, clientOptionsCopy); | ||
} | ||
} | ||
// TODO: can we instead use type predicates in these switch cases to allow for narrowing of the body simultaneously? we have isEvent, isView, isShortcut, isAction already in types/utilities / helpers | ||
// Set aliases | ||
if (type === helpers_1.IncomingEventType.Event) { | ||
// TODO: assigning eventListenerArgs by reference to set properties of listenerArgs is error prone, there should be a better way to do this! | ||
const eventListenerArgs = listenerArgs; | ||
@@ -598,12 +569,2 @@ eventListenerArgs.event = eventListenerArgs.payload; | ||
} | ||
if (eventListenerArgs.event.type === 'function_executed') { | ||
listenerArgs.complete = (0, CustomFunction_1.createFunctionComplete)(context, client); | ||
listenerArgs.fail = (0, CustomFunction_1.createFunctionFail)(context, client); | ||
listenerArgs.inputs = eventListenerArgs.event.inputs; | ||
} | ||
else { | ||
// Events API requests are acknowledged right away, since there's no data expected | ||
// Except function_executed events | ||
await listenerArgs.ack(); | ||
} | ||
} | ||
@@ -613,8 +574,2 @@ else if (type === helpers_1.IncomingEventType.Action) { | ||
actionListenerArgs.action = actionListenerArgs.payload; | ||
// Add complete() and fail() utilities for function-related interactivity | ||
if (context.functionExecutionId !== undefined) { | ||
listenerArgs.complete = (0, CustomFunction_1.createFunctionComplete)(context, client); | ||
listenerArgs.fail = (0, CustomFunction_1.createFunctionFail)(context, client); | ||
listenerArgs.inputs = context.functionInputs; | ||
} | ||
} | ||
@@ -649,2 +604,43 @@ else if (type === helpers_1.IncomingEventType.Command) { | ||
} | ||
// Set ack() utility | ||
if (type !== helpers_1.IncomingEventType.Event) { | ||
listenerArgs.ack = ack; | ||
} | ||
else { | ||
// Events API requests are acknowledged right away, since there's no data expected | ||
await ack(); | ||
} | ||
// Get the client arg | ||
let { client } = this; | ||
// If functionBotAccessToken exists on context, the incoming event is function-related *and* the | ||
// user has `attachFunctionToken` enabled. In that case, subsequent calls with the client should | ||
// use the function-related/JIT token in lieu of the botToken or userToken. | ||
const token = context.functionBotAccessToken ? context.functionBotAccessToken : selectToken(context); | ||
// Add complete() and fail() utilities for function-related interactivity | ||
if (type === helpers_1.IncomingEventType.Action && context.functionExecutionId !== undefined) { | ||
listenerArgs.complete = CustomFunction_1.CustomFunction.createFunctionComplete(context, client); | ||
listenerArgs.fail = CustomFunction_1.CustomFunction.createFunctionFail(context, client); | ||
listenerArgs.inputs = context.functionInputs; | ||
} | ||
if (token !== undefined) { | ||
let pool = undefined; | ||
const clientOptionsCopy = { ...this.clientOptions }; | ||
if (authorizeResult.teamId !== undefined) { | ||
pool = this.clients[authorizeResult.teamId]; | ||
if (pool === undefined) { | ||
pool = this.clients[authorizeResult.teamId] = new WebClientPool(); | ||
} | ||
// Add teamId to clientOptions so it can be automatically added to web-api calls | ||
clientOptionsCopy.teamId = authorizeResult.teamId; | ||
} | ||
else if (authorizeResult.enterpriseId !== undefined) { | ||
pool = this.clients[authorizeResult.enterpriseId]; | ||
if (pool === undefined) { | ||
pool = this.clients[authorizeResult.enterpriseId] = new WebClientPool(); | ||
} | ||
} | ||
if (pool !== undefined) { | ||
client = pool.getOrCreate(token, clientOptionsCopy); | ||
} | ||
} | ||
// Dispatch event through the global middleware chain | ||
@@ -774,3 +770,3 @@ try { | ||
if (authorize === undefined && !usingOauth) { | ||
throw new errors_1.AppInitializationError(`${tokenUsage} \n\nSince you have not provided a token or authorize, you might be missing one or more required oauth installer options. See https://slack.dev/bolt-js/concepts/authenticating-oauth for these required fields.\n`); | ||
throw new errors_1.AppInitializationError(`${tokenUsage} \n\nSince you have not provided a token or authorize, you might be missing one or more required oauth installer options. See https://tools.slack.dev/bolt-js/concepts/authenticating-oauth/ for these required fields.\n`); | ||
// biome-ignore lint/style/noUselessElse: I think this is a biome issue actually... | ||
@@ -965,11 +961,3 @@ } | ||
// Returns either a bot token or a user token for client, say() | ||
function selectToken(context, attachFunctionToken) { | ||
if (attachFunctionToken) { | ||
// If functionBotAccessToken exists on context, the incoming event is function-related *and* the | ||
// user has `attachFunctionToken` enabled. In that case, subsequent calls with the client should | ||
// use the function-related/JIT token in lieu of the botToken or userToken. | ||
if (context.functionBotAccessToken) { | ||
return context.functionBotAccessToken; | ||
} | ||
} | ||
function selectToken(context) { | ||
return context.botToken !== undefined ? context.botToken : context.userToken; | ||
@@ -976,0 +964,0 @@ } |
import type { FunctionExecutedEvent } from '@slack/types'; | ||
import type { FunctionsCompleteErrorResponse, FunctionsCompleteSuccessResponse, WebClient } from '@slack/web-api'; | ||
import type { AnyMiddlewareArgs, Context, Middleware, SlackEventMiddlewareArgs, SlackEventMiddlewareArgsOptions } from './types'; | ||
import { type FunctionsCompleteErrorResponse, type FunctionsCompleteSuccessResponse, WebClient, type WebClientOptions } from '@slack/web-api'; | ||
import type { AllMiddlewareArgs, AnyMiddlewareArgs, Context, Middleware, SlackEventMiddlewareArgs } from './types'; | ||
/** Interfaces */ | ||
@@ -8,3 +8,2 @@ interface FunctionCompleteArguments { | ||
} | ||
/** Types */ | ||
export type FunctionCompleteFn = (params?: FunctionCompleteArguments) => Promise<FunctionsCompleteSuccessResponse>; | ||
@@ -15,34 +14,47 @@ interface FunctionFailArguments { | ||
export type FunctionFailFn = (params: FunctionFailArguments) => Promise<FunctionsCompleteErrorResponse>; | ||
export type SlackCustomFunctionMiddlewareArgs<Options extends SlackEventMiddlewareArgsOptions = { | ||
autoAcknowledge: true; | ||
}> = SlackEventMiddlewareArgs<'function_executed', Options> & { | ||
export interface CustomFunctionExecuteMiddlewareArgs extends SlackEventMiddlewareArgs<'function_executed'> { | ||
inputs: FunctionExecutedEvent['inputs']; | ||
complete: FunctionCompleteFn; | ||
fail: FunctionFailFn; | ||
}; | ||
export declare function matchCallbackId(callbackId: string): Middleware<SlackCustomFunctionMiddlewareArgs>; | ||
} | ||
/** Types */ | ||
export type SlackCustomFunctionMiddlewareArgs = CustomFunctionExecuteMiddlewareArgs; | ||
type CustomFunctionExecuteMiddleware = Middleware<CustomFunctionExecuteMiddlewareArgs>[]; | ||
export type CustomFunctionMiddleware = Middleware<CustomFunctionExecuteMiddlewareArgs>[]; | ||
export type AllCustomFunctionMiddlewareArgs<T extends SlackCustomFunctionMiddlewareArgs = SlackCustomFunctionMiddlewareArgs> = T & AllMiddlewareArgs; | ||
/** Class */ | ||
export declare class CustomFunction<Options extends SlackEventMiddlewareArgsOptions = { | ||
autoAcknowledge: true; | ||
}> { | ||
export declare class CustomFunction { | ||
/** Function callback_id */ | ||
callbackId: string; | ||
private listeners; | ||
private options; | ||
constructor(callbackId: string, listeners: Middleware<SlackCustomFunctionMiddlewareArgs<Options>>[], options: Options); | ||
getListeners(): Middleware<AnyMiddlewareArgs>[]; | ||
private appWebClientOptions; | ||
private middleware; | ||
constructor(callbackId: string, middleware: CustomFunctionExecuteMiddleware, clientOptions: WebClientOptions); | ||
getMiddleware(): Middleware<AnyMiddlewareArgs>; | ||
private matchesConstraints; | ||
private processEvent; | ||
private getFunctionMiddleware; | ||
/** | ||
* Factory for `complete()` utility | ||
*/ | ||
static createFunctionComplete(context: Context, client: WebClient): FunctionCompleteFn; | ||
/** | ||
* Factory for `fail()` utility | ||
*/ | ||
static createFunctionFail(context: Context, client: WebClient): FunctionFailFn; | ||
} | ||
/** Helper Functions */ | ||
export declare function validate<Options extends SlackEventMiddlewareArgsOptions = { | ||
autoAcknowledge: true; | ||
}>(callbackId: string, middleware: Middleware<SlackCustomFunctionMiddlewareArgs<Options>>[]): void; | ||
export declare function validate(callbackId: string, middleware: CustomFunctionExecuteMiddleware): void; | ||
/** | ||
* Factory for `complete()` utility | ||
* `processFunctionMiddleware()` invokes each listener middleware | ||
*/ | ||
export declare function createFunctionComplete(context: Context, client: WebClient): FunctionCompleteFn; | ||
export declare function processFunctionMiddleware(args: AllCustomFunctionMiddlewareArgs, middleware: CustomFunctionMiddleware): Promise<void>; | ||
export declare function isFunctionEvent(args: AnyMiddlewareArgs): args is AllCustomFunctionMiddlewareArgs; | ||
/** | ||
* Factory for `fail()` utility | ||
*/ | ||
export declare function createFunctionFail(context: Context, client: WebClient): FunctionFailFn; | ||
* `enrichFunctionArgs()` takes in a function's args and: | ||
* 1. removes the next() passed in from App-level middleware processing | ||
* - events will *not* continue down global middleware chain to subsequent listeners | ||
* 2. augments args with step lifecycle-specific properties/utilities | ||
* */ | ||
export declare function enrichFunctionArgs(args: AllCustomFunctionMiddlewareArgs, webClientOptions: WebClientOptions): AllCustomFunctionMiddlewareArgs; | ||
export {}; | ||
//# sourceMappingURL=CustomFunction.d.ts.map |
"use strict"; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.createFunctionFail = exports.createFunctionComplete = exports.validate = exports.CustomFunction = exports.matchCallbackId = void 0; | ||
exports.enrichFunctionArgs = exports.isFunctionEvent = exports.processFunctionMiddleware = exports.validate = exports.CustomFunction = void 0; | ||
const web_api_1 = require("@slack/web-api"); | ||
const errors_1 = require("./errors"); | ||
const builtin_1 = require("./middleware/builtin"); | ||
/* | ||
* Middleware that filters out function scoped events that do not match the provided callback ID | ||
*/ | ||
function matchCallbackId(callbackId) { | ||
return async ({ payload, next }) => { | ||
if (payload.function.callback_id === callbackId) { | ||
await next(); | ||
} | ||
}; | ||
} | ||
exports.matchCallbackId = matchCallbackId; | ||
const process_1 = __importDefault(require("./middleware/process")); | ||
/** Constants */ | ||
const VALID_PAYLOAD_TYPES = new Set(['function_executed']); | ||
/** Class */ | ||
@@ -21,27 +16,64 @@ class CustomFunction { | ||
callbackId; | ||
listeners; | ||
options; | ||
constructor(callbackId, listeners, options) { | ||
validate(callbackId, listeners); | ||
appWebClientOptions; | ||
middleware; | ||
constructor(callbackId, middleware, clientOptions) { | ||
validate(callbackId, middleware); | ||
this.appWebClientOptions = clientOptions; | ||
this.callbackId = callbackId; | ||
this.listeners = listeners; | ||
this.options = options; | ||
this.middleware = middleware; | ||
} | ||
getListeners() { | ||
if (this.options.autoAcknowledge) { | ||
return [ | ||
builtin_1.onlyEvents, | ||
(0, builtin_1.matchEventType)('function_executed'), | ||
matchCallbackId(this.callbackId), | ||
builtin_1.autoAcknowledge, | ||
...this.listeners, | ||
]; | ||
getMiddleware() { | ||
return async (args) => { | ||
if (isFunctionEvent(args) && this.matchesConstraints(args)) { | ||
return this.processEvent(args); | ||
} | ||
return args.next(); | ||
}; | ||
} | ||
matchesConstraints(args) { | ||
return args.payload.function.callback_id === this.callbackId; | ||
} | ||
async processEvent(args) { | ||
const functionArgs = enrichFunctionArgs(args, this.appWebClientOptions); | ||
const functionMiddleware = this.getFunctionMiddleware(); | ||
return processFunctionMiddleware(functionArgs, functionMiddleware); | ||
} | ||
getFunctionMiddleware() { | ||
return this.middleware; | ||
} | ||
/** | ||
* Factory for `complete()` utility | ||
*/ | ||
static createFunctionComplete(context, client) { | ||
const token = selectToken(context); | ||
const { functionExecutionId } = context; | ||
if (!functionExecutionId) { | ||
const errorMsg = 'No function_execution_id found'; | ||
throw new errors_1.CustomFunctionCompleteSuccessError(errorMsg); | ||
} | ||
return [ | ||
builtin_1.onlyEvents, | ||
(0, builtin_1.matchEventType)('function_executed'), | ||
matchCallbackId(this.callbackId), | ||
...this.listeners, | ||
]; | ||
return (params = {}) => client.functions.completeSuccess({ | ||
token, | ||
outputs: params.outputs || {}, | ||
function_execution_id: functionExecutionId, | ||
}); | ||
} | ||
/** | ||
* Factory for `fail()` utility | ||
*/ | ||
static createFunctionFail(context, client) { | ||
const token = selectToken(context); | ||
const { functionExecutionId } = context; | ||
if (!functionExecutionId) { | ||
const errorMsg = 'No function_execution_id found'; | ||
throw new errors_1.CustomFunctionCompleteFailError(errorMsg); | ||
} | ||
return (params) => { | ||
const { error } = params ?? {}; | ||
return client.functions.completeError({ | ||
token, | ||
error, | ||
function_execution_id: functionExecutionId, | ||
}); | ||
}; | ||
} | ||
} | ||
@@ -73,34 +105,42 @@ exports.CustomFunction = CustomFunction; | ||
/** | ||
* Factory for `complete()` utility | ||
* `processFunctionMiddleware()` invokes each listener middleware | ||
*/ | ||
function createFunctionComplete(context, client) { | ||
const { functionExecutionId } = context; | ||
if (!functionExecutionId) { | ||
const errorMsg = 'No function_execution_id found'; | ||
throw new errors_1.CustomFunctionCompleteSuccessError(errorMsg); | ||
async function processFunctionMiddleware(args, middleware) { | ||
const { context, client, logger } = args; | ||
const callbacks = [...middleware]; | ||
const lastCallback = callbacks.pop(); | ||
if (lastCallback !== undefined) { | ||
await (0, process_1.default)(callbacks, args, context, client, logger, async () => lastCallback({ ...args, context, client, logger })); | ||
} | ||
return (params = {}) => client.functions.completeSuccess({ | ||
outputs: params.outputs || {}, | ||
function_execution_id: functionExecutionId, | ||
}); | ||
} | ||
exports.createFunctionComplete = createFunctionComplete; | ||
exports.processFunctionMiddleware = processFunctionMiddleware; | ||
function isFunctionEvent(args) { | ||
return VALID_PAYLOAD_TYPES.has(args.payload.type); | ||
} | ||
exports.isFunctionEvent = isFunctionEvent; | ||
function selectToken(context) { | ||
// If attachFunctionToken = false, fallback to botToken or userToken | ||
return context.functionBotAccessToken ? context.functionBotAccessToken : context.botToken || context.userToken; | ||
} | ||
/** | ||
* Factory for `fail()` utility | ||
*/ | ||
function createFunctionFail(context, client) { | ||
const { functionExecutionId } = context; | ||
if (!functionExecutionId) { | ||
const errorMsg = 'No function_execution_id found'; | ||
throw new errors_1.CustomFunctionCompleteFailError(errorMsg); | ||
} | ||
return (params) => { | ||
const { error } = params ?? {}; | ||
return client.functions.completeError({ | ||
error, | ||
function_execution_id: functionExecutionId, | ||
}); | ||
}; | ||
* `enrichFunctionArgs()` takes in a function's args and: | ||
* 1. removes the next() passed in from App-level middleware processing | ||
* - events will *not* continue down global middleware chain to subsequent listeners | ||
* 2. augments args with step lifecycle-specific properties/utilities | ||
* */ | ||
function enrichFunctionArgs(args, webClientOptions) { | ||
const { next: _next, ...functionArgs } = args; | ||
const enrichedArgs = { ...functionArgs }; | ||
const token = selectToken(functionArgs.context); | ||
// Making calls with a functionBotAccessToken establishes continuity between | ||
// a function_executed event and subsequent interactive events (actions) | ||
const client = new web_api_1.WebClient(token, webClientOptions); | ||
enrichedArgs.client = client; | ||
// Utility args | ||
enrichedArgs.inputs = enrichedArgs.event.inputs; | ||
enrichedArgs.complete = CustomFunction.createFunctionComplete(enrichedArgs.context, client); | ||
enrichedArgs.fail = CustomFunction.createFunctionFail(enrichedArgs.context, client); | ||
return enrichedArgs; // TODO: dangerous casting as it obfuscates missing `next()` | ||
} | ||
exports.createFunctionFail = createFunctionFail; | ||
exports.enrichFunctionArgs = enrichFunctionArgs; | ||
//# sourceMappingURL=CustomFunction.js.map |
import type { ActionConstraints, OptionsConstraints, ShortcutConstraints, ViewConstraints } from '../App'; | ||
import type { AnyMiddlewareArgs, EventTypePattern, Middleware, SlackActionMiddlewareArgs, SlackCommandMiddlewareArgs, SlackEventMiddlewareArgs, SlackEventMiddlewareArgsOptions, SlackOptionsMiddlewareArgs, SlackViewMiddlewareArgs } from '../types'; | ||
export declare function isEventArgs(args: AnyMiddlewareArgs): args is SlackEventMiddlewareArgs; | ||
export declare function isSlackEventMiddlewareArgsOptions<Options extends SlackEventMiddlewareArgsOptions, EventMiddlewareArgs extends SlackEventMiddlewareArgs>(optionOrListener: Options | Middleware<EventMiddlewareArgs>): optionOrListener is Options; | ||
import type { AnyMiddlewareArgs, EventTypePattern, Middleware, SlackActionMiddlewareArgs, SlackCommandMiddlewareArgs, SlackEventMiddlewareArgs, SlackOptionsMiddlewareArgs, SlackViewMiddlewareArgs } from '../types'; | ||
/** | ||
@@ -30,6 +28,2 @@ * Middleware that filters out any event that isn't an action | ||
/** | ||
* Middleware that auto acknowledges the request received | ||
*/ | ||
export declare const autoAcknowledge: Middleware<AnyMiddlewareArgs>; | ||
/** | ||
* Middleware that checks for matches given constraints | ||
@@ -36,0 +30,0 @@ */ |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.directMention = exports.subtype = exports.ignoreSelf = exports.matchEventType = exports.matchCommandName = exports.matchMessage = exports.matchConstraints = exports.autoAcknowledge = exports.onlyViewActions = exports.onlyEvents = exports.onlyOptions = exports.onlyCommands = exports.onlyShortcuts = exports.onlyActions = exports.isSlackEventMiddlewareArgsOptions = exports.isEventArgs = void 0; | ||
exports.directMention = exports.subtype = exports.ignoreSelf = exports.matchEventType = exports.matchCommandName = exports.matchMessage = exports.matchConstraints = exports.onlyViewActions = exports.onlyEvents = exports.onlyOptions = exports.onlyCommands = exports.onlyShortcuts = exports.onlyActions = void 0; | ||
const errors_1 = require("../errors"); | ||
@@ -22,10 +22,5 @@ /** Type predicate that can narrow payloads block action or suggestion payloads */ | ||
} | ||
exports.isEventArgs = isEventArgs; | ||
function isMessageEventArgs(args) { | ||
return isEventArgs(args) && 'message' in args; | ||
} | ||
function isSlackEventMiddlewareArgsOptions(optionOrListener) { | ||
return typeof optionOrListener !== 'function' && 'autoAcknowledge' in optionOrListener; | ||
} | ||
exports.isSlackEventMiddlewareArgsOptions = isSlackEventMiddlewareArgsOptions; | ||
/** | ||
@@ -88,12 +83,2 @@ * Middleware that filters out any event that isn't an action | ||
/** | ||
* Middleware that auto acknowledges the request received | ||
*/ | ||
const autoAcknowledge = async (args) => { | ||
if ('ack' in args && args.ack !== undefined) { | ||
await args.ack(); | ||
} | ||
await args.next(); | ||
}; | ||
exports.autoAcknowledge = autoAcknowledge; | ||
/** | ||
* Middleware that checks for matches given constraints | ||
@@ -100,0 +85,0 @@ */ |
import type { SlackEvent } from '@slack/types'; | ||
import type { AckFn, SayFn, StringIndexed } from '../utilities'; | ||
export type SlackEventMiddlewareArgsOptions = { | ||
autoAcknowledge: boolean; | ||
}; | ||
import type { SayFn, StringIndexed } from '../utilities'; | ||
/** | ||
* Arguments which listeners and middleware receive to process an event from Slack's Events API. | ||
*/ | ||
export type SlackEventMiddlewareArgs<EventType extends string = string, Options extends SlackEventMiddlewareArgsOptions = { | ||
autoAcknowledge: true; | ||
}> = { | ||
export type SlackEventMiddlewareArgs<EventType extends string = string> = { | ||
payload: EventFromType<EventType>; | ||
event: EventFromType<EventType>; | ||
body: EnvelopedEvent<EventFromType<EventType>>; | ||
ack?: undefined; | ||
} & (EventType extends 'message' ? { | ||
@@ -25,5 +21,3 @@ message: EventFromType<EventType>; | ||
say: SayFn; | ||
} : unknown) & (Options['autoAcknowledge'] extends true ? unknown : { | ||
ack: AckFn<void>; | ||
}); | ||
} : unknown); | ||
export interface BaseSlackEvent<T extends string = string> { | ||
@@ -30,0 +24,0 @@ type: T; |
import type { Logger } from '@slack/logger'; | ||
import type { WebClient } from '@slack/web-api'; | ||
import type { SlackCustomFunctionMiddlewareArgs } from '../CustomFunction'; | ||
import type { SlackActionMiddlewareArgs } from './actions'; | ||
import type { SlackCommandMiddlewareArgs } from './command'; | ||
import type { FunctionInputs, SlackEventMiddlewareArgs, SlackEventMiddlewareArgsOptions } from './events'; | ||
import type { FunctionInputs, SlackEventMiddlewareArgs } from './events'; | ||
import type { SlackOptionsMiddlewareArgs } from './options'; | ||
@@ -11,5 +10,3 @@ import type { SlackShortcutMiddlewareArgs } from './shortcuts'; | ||
import type { SlackViewMiddlewareArgs } from './view'; | ||
export type AnyMiddlewareArgs<Options extends SlackEventMiddlewareArgsOptions = { | ||
autoAcknowledge: true; | ||
}> = SlackEventMiddlewareArgs<string, Options> | SlackActionMiddlewareArgs | SlackCommandMiddlewareArgs | SlackOptionsMiddlewareArgs | SlackViewMiddlewareArgs | SlackShortcutMiddlewareArgs | SlackCustomFunctionMiddlewareArgs<Options>; | ||
export type AnyMiddlewareArgs = SlackEventMiddlewareArgs | SlackActionMiddlewareArgs | SlackCommandMiddlewareArgs | SlackOptionsMiddlewareArgs | SlackViewMiddlewareArgs | SlackShortcutMiddlewareArgs; | ||
export interface AllMiddlewareArgs<CustomContext = StringIndexed> { | ||
@@ -16,0 +13,0 @@ context: Context & CustomContext; |
{ | ||
"name": "@slack/bolt", | ||
"version": "4.2.0-autoack.1", | ||
"version": "4.2.0", | ||
"description": "A framework for building Slack apps, fast.", | ||
@@ -31,3 +31,4 @@ "author": "Slack Technologies, LLC", | ||
"build:clean": "shx rm -rf ./dist ./coverage", | ||
"lint": "npx @biomejs/biome check --write docs src test examples", | ||
"lint": "npx @biomejs/biome check docs src test examples", | ||
"lint:fix": "npx @biomejs/biome check --write docs src test examples", | ||
"test": "npm run build && npm run lint && npm run test:types && npm run test:coverage", | ||
@@ -39,4 +40,4 @@ "test:unit": "TS_NODE_PROJECT=tsconfig.json mocha --config test/unit/.mocharc.json", | ||
}, | ||
"repository": "slackapi/bolt", | ||
"homepage": "https://slack.dev/bolt-js", | ||
"repository": "slackapi/bolt-js", | ||
"homepage": "https://tools.slack.dev/bolt-js", | ||
"bugs": { | ||
@@ -47,8 +48,7 @@ "url": "https://github.com/slackapi/bolt-js/issues" | ||
"@slack/logger": "^4.0.0", | ||
"@slack/oauth": "^3", | ||
"@slack/socket-mode": "^2.0.2", | ||
"@slack/oauth": "^3.0.2", | ||
"@slack/socket-mode": "^2.0.3", | ||
"@slack/types": "^2.13.0", | ||
"@slack/web-api": "^7", | ||
"@types/express": "^4.17.21", | ||
"axios": "^1.7.4", | ||
"@slack/web-api": "^7.8.0", | ||
"axios": "^1.7.8", | ||
"express": "^5.0.0", | ||
@@ -63,4 +63,5 @@ "path-to-regexp": "^8.1.0", | ||
"@types/chai": "^4.1.7", | ||
"@types/express": "^5.0.0", | ||
"@types/mocha": "^10.0.1", | ||
"@types/node": "22.9.0", | ||
"@types/node": "22.10.2", | ||
"@types/sinon": "^7.0.11", | ||
@@ -67,0 +68,0 @@ "@types/tsscmp": "^1.0.0", |
@@ -6,3 +6,3 @@ # Bolt <img src="https://raw.githubusercontent.com/slackapi/bolt-js/main/docs/static/img/bolt.svg" alt="Bolt logo" width="32"/> for JavaScript | ||
A JavaScript framework to build Slack apps in a flash with the latest platform features. Read the [getting started guide](https://tools.slack.dev/bolt-js/tutorial/getting-started) to set-up and run your first Bolt app. | ||
A JavaScript framework to build Slack apps in a flash with the latest platform features. Read the [getting started guide](https://tools.slack.dev/bolt-js/getting-started) to set-up and run your first Bolt app. | ||
@@ -9,0 +9,0 @@ Read [the documentation](https://tools.slack.dev/bolt-js) to explore the basic and advanced concepts of Bolt for JavaScript. |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
515485
10
6899
0
18
- Removed@types/express@^4.17.21
- Removed@types/body-parser@1.19.5(transitive)
- Removed@types/connect@3.4.38(transitive)
- Removed@types/express@4.17.21(transitive)
- Removed@types/express-serve-static-core@4.19.6(transitive)
- Removed@types/http-errors@2.0.4(transitive)
- Removed@types/mime@1.3.5(transitive)
- Removed@types/qs@6.9.18(transitive)
- Removed@types/range-parser@1.2.7(transitive)
- Removed@types/send@0.17.4(transitive)
- Removed@types/serve-static@1.15.7(transitive)
Updated@slack/oauth@^3.0.2
Updated@slack/socket-mode@^2.0.3
Updated@slack/web-api@^7.8.0
Updatedaxios@^1.7.8