@slack/bolt 4.0.0-nextGen.9 → 4.0.0-rc.2

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.
Files changed (218) hide show
  1. package/README.md +22 -16
  2. package/dist/App.d.ts +39 -80
  3. package/dist/App.d.ts.map +1 -1
  4. package/dist/App.js +223 -234
  5. package/dist/App.js.map +1 -1
  6. package/dist/CustomFunction.d.ts +58 -0
  7. package/dist/CustomFunction.d.ts.map +1 -0
  8. package/dist/CustomFunction.js +144 -0
  9. package/dist/CustomFunction.js.map +1 -0
  10. package/dist/WorkflowStep.d.ts +89 -36
  11. package/dist/WorkflowStep.d.ts.map +1 -1
  12. package/dist/WorkflowStep.js +29 -8
  13. package/dist/WorkflowStep.js.map +1 -1
  14. package/dist/conversation-store.d.ts +1 -1
  15. package/dist/conversation-store.d.ts.map +1 -1
  16. package/dist/conversation-store.js +3 -3
  17. package/dist/conversation-store.js.map +1 -1
  18. package/dist/errors.d.ts +12 -7
  19. package/dist/errors.d.ts.map +1 -1
  20. package/dist/errors.js +42 -53
  21. package/dist/errors.js.map +1 -1
  22. package/dist/helpers.d.ts +16 -3
  23. package/dist/helpers.d.ts.map +1 -1
  24. package/dist/helpers.js +43 -11
  25. package/dist/helpers.js.map +1 -1
  26. package/dist/index.d.ts +4 -5
  27. package/dist/index.d.ts.map +1 -1
  28. package/dist/index.js +16 -11
  29. package/dist/index.js.map +1 -1
  30. package/dist/middleware/builtin.d.ts +20 -23
  31. package/dist/middleware/builtin.d.ts.map +1 -1
  32. package/dist/middleware/builtin.js +93 -110
  33. package/dist/middleware/builtin.js.map +1 -1
  34. package/dist/middleware/process.d.ts +3 -3
  35. package/dist/middleware/process.d.ts.map +1 -1
  36. package/dist/middleware/process.js +1 -1
  37. package/dist/middleware/process.js.map +1 -1
  38. package/dist/receivers/AwsLambdaReceiver.d.ts +77 -16
  39. package/dist/receivers/AwsLambdaReceiver.d.ts.map +1 -1
  40. package/dist/receivers/AwsLambdaReceiver.js +53 -25
  41. package/dist/receivers/AwsLambdaReceiver.js.map +1 -1
  42. package/dist/receivers/BufferedIncomingMessage.d.ts +2 -1
  43. package/dist/receivers/BufferedIncomingMessage.d.ts.map +1 -1
  44. package/dist/receivers/ExpressReceiver.d.ts +13 -13
  45. package/dist/receivers/ExpressReceiver.d.ts.map +1 -1
  46. package/dist/receivers/ExpressReceiver.js +70 -70
  47. package/dist/receivers/ExpressReceiver.js.map +1 -1
  48. package/dist/receivers/HTTPModuleFunctions.d.ts +18 -20
  49. package/dist/receivers/HTTPModuleFunctions.d.ts.map +1 -1
  50. package/dist/receivers/HTTPModuleFunctions.js +189 -171
  51. package/dist/receivers/HTTPModuleFunctions.js.map +1 -1
  52. package/dist/receivers/HTTPReceiver.d.ts +14 -14
  53. package/dist/receivers/HTTPReceiver.d.ts.map +1 -1
  54. package/dist/receivers/HTTPReceiver.js +102 -48
  55. package/dist/receivers/HTTPReceiver.js.map +1 -1
  56. package/dist/receivers/HTTPResponseAck.d.ts +7 -7
  57. package/dist/receivers/HTTPResponseAck.d.ts.map +1 -1
  58. package/dist/receivers/HTTPResponseAck.js +37 -5
  59. package/dist/receivers/HTTPResponseAck.js.map +1 -1
  60. package/dist/receivers/ParamsIncomingMessage.d.ts +14 -0
  61. package/dist/receivers/ParamsIncomingMessage.d.ts.map +1 -0
  62. package/dist/{types/block-suggestion/index.js → receivers/ParamsIncomingMessage.js} +1 -1
  63. package/dist/receivers/ParamsIncomingMessage.js.map +1 -0
  64. package/dist/receivers/SocketModeFunctions.d.ts +3 -5
  65. package/dist/receivers/SocketModeFunctions.d.ts.map +1 -1
  66. package/dist/receivers/SocketModeFunctions.js +14 -23
  67. package/dist/receivers/SocketModeFunctions.js.map +1 -1
  68. package/dist/receivers/SocketModeReceiver.d.ts +10 -9
  69. package/dist/receivers/SocketModeReceiver.d.ts.map +1 -1
  70. package/dist/receivers/SocketModeReceiver.js +41 -25
  71. package/dist/receivers/SocketModeReceiver.js.map +1 -1
  72. package/dist/receivers/custom-routes.d.ts +4 -3
  73. package/dist/receivers/custom-routes.d.ts.map +1 -1
  74. package/dist/receivers/custom-routes.js +10 -9
  75. package/dist/receivers/custom-routes.js.map +1 -1
  76. package/dist/receivers/verify-redirect-opts.d.ts +1 -1
  77. package/dist/receivers/verify-redirect-opts.d.ts.map +1 -1
  78. package/dist/receivers/verify-redirect-opts.js +3 -3
  79. package/dist/receivers/verify-redirect-opts.js.map +1 -1
  80. package/dist/receivers/verify-request.d.ts +1 -12
  81. package/dist/receivers/verify-request.d.ts.map +1 -1
  82. package/dist/receivers/verify-request.js +4 -18
  83. package/dist/receivers/verify-request.js.map +1 -1
  84. package/dist/types/actions/block-action.d.ts +41 -22
  85. package/dist/types/actions/block-action.d.ts.map +1 -1
  86. package/dist/types/actions/dialog-action.d.ts +0 -4
  87. package/dist/types/actions/dialog-action.d.ts.map +1 -1
  88. package/dist/types/actions/index.d.ts +25 -11
  89. package/dist/types/actions/index.d.ts.map +1 -1
  90. package/dist/types/actions/index.js +1 -0
  91. package/dist/types/actions/index.js.map +1 -1
  92. package/dist/types/actions/interactive-message.d.ts +3 -3
  93. package/dist/types/actions/interactive-message.d.ts.map +1 -1
  94. package/dist/types/actions/workflow-step-edit.d.ts +7 -7
  95. package/dist/types/actions/workflow-step-edit.d.ts.map +1 -1
  96. package/dist/types/command/index.d.ts +1 -2
  97. package/dist/types/command/index.d.ts.map +1 -1
  98. package/dist/types/events/index.d.ts +26 -24
  99. package/dist/types/events/index.d.ts.map +1 -1
  100. package/dist/types/events/index.js +4 -15
  101. package/dist/types/events/index.js.map +1 -1
  102. package/dist/types/index.d.ts +0 -2
  103. package/dist/types/index.d.ts.map +1 -1
  104. package/dist/types/index.js +0 -2
  105. package/dist/types/index.js.map +1 -1
  106. package/dist/types/middleware.d.ts +30 -30
  107. package/dist/types/middleware.d.ts.map +1 -1
  108. package/dist/types/middleware.js +3 -0
  109. package/dist/types/middleware.js.map +1 -1
  110. package/dist/types/options/index.d.ts +23 -59
  111. package/dist/types/options/index.d.ts.map +1 -1
  112. package/dist/types/receiver.d.ts +3 -3
  113. package/dist/types/receiver.d.ts.map +1 -1
  114. package/dist/types/shortcuts/global-shortcut.d.ts.map +1 -1
  115. package/dist/types/shortcuts/index.d.ts +14 -9
  116. package/dist/types/shortcuts/index.d.ts.map +1 -1
  117. package/dist/types/shortcuts/message-shortcut.d.ts.map +1 -1
  118. package/dist/types/utilities.d.ts +23 -13
  119. package/dist/types/utilities.d.ts.map +1 -1
  120. package/dist/types/utilities.js +7 -0
  121. package/dist/types/utilities.js.map +1 -1
  122. package/dist/types/view/index.d.ts +148 -12
  123. package/dist/types/view/index.d.ts.map +1 -1
  124. package/package.json +32 -61
  125. package/dist/Manifest.d.ts +0 -5
  126. package/dist/Manifest.d.ts.map +0 -1
  127. package/dist/Manifest.js +0 -16
  128. package/dist/Manifest.js.map +0 -1
  129. package/dist/SlackFunction.d.ts +0 -190
  130. package/dist/SlackFunction.d.ts.map +0 -1
  131. package/dist/SlackFunction.js +0 -441
  132. package/dist/SlackFunction.js.map +0 -1
  133. package/dist/Subscription.d.ts +0 -61
  134. package/dist/Subscription.d.ts.map +0 -1
  135. package/dist/Subscription.js +0 -169
  136. package/dist/Subscription.js.map +0 -1
  137. package/dist/cli/check-update.d.ts +0 -3
  138. package/dist/cli/check-update.d.ts.map +0 -1
  139. package/dist/cli/check-update.js +0 -13
  140. package/dist/cli/check-update.js.map +0 -1
  141. package/dist/cli/get-hooks.d.ts +0 -2
  142. package/dist/cli/get-hooks.d.ts.map +0 -1
  143. package/dist/cli/get-hooks.js +0 -19
  144. package/dist/cli/get-hooks.js.map +0 -1
  145. package/dist/cli/get-manifest.d.ts +0 -3
  146. package/dist/cli/get-manifest.d.ts.map +0 -1
  147. package/dist/cli/get-manifest.js +0 -16
  148. package/dist/cli/get-manifest.js.map +0 -1
  149. package/dist/cli/hook-utils/get-check-update-data.d.ts +0 -49
  150. package/dist/cli/hook-utils/get-check-update-data.d.ts.map +0 -1
  151. package/dist/cli/hook-utils/get-check-update-data.js +0 -252
  152. package/dist/cli/hook-utils/get-check-update-data.js.map +0 -1
  153. package/dist/cli/hook-utils/get-check-update-data.spec.d.ts +0 -2
  154. package/dist/cli/hook-utils/get-check-update-data.spec.d.ts.map +0 -1
  155. package/dist/cli/hook-utils/get-check-update-data.spec.js +0 -266
  156. package/dist/cli/hook-utils/get-check-update-data.spec.js.map +0 -1
  157. package/dist/cli/hook-utils/get-manifest-data.d.ts +0 -7
  158. package/dist/cli/hook-utils/get-manifest-data.d.ts.map +0 -1
  159. package/dist/cli/hook-utils/get-manifest-data.js +0 -30
  160. package/dist/cli/hook-utils/get-manifest-data.js.map +0 -1
  161. package/dist/cli/hook-utils/get-manifest-data.spec.d.ts +0 -2
  162. package/dist/cli/hook-utils/get-manifest-data.spec.d.ts.map +0 -1
  163. package/dist/cli/hook-utils/get-manifest-data.spec.js +0 -113
  164. package/dist/cli/hook-utils/get-manifest-data.spec.js.map +0 -1
  165. package/dist/cli/hook-utils/manifest.d.ts +0 -30
  166. package/dist/cli/hook-utils/manifest.d.ts.map +0 -1
  167. package/dist/cli/hook-utils/manifest.js +0 -103
  168. package/dist/cli/hook-utils/manifest.js.map +0 -1
  169. package/dist/cli/hook-utils/manifest.spec.d.ts +0 -2
  170. package/dist/cli/hook-utils/manifest.spec.d.ts.map +0 -1
  171. package/dist/cli/hook-utils/manifest.spec.js +0 -79
  172. package/dist/cli/hook-utils/manifest.spec.js.map +0 -1
  173. package/dist/cli/run.d.ts +0 -2
  174. package/dist/cli/run.d.ts.map +0 -1
  175. package/dist/cli/run.js +0 -37
  176. package/dist/cli/run.js.map +0 -1
  177. package/dist/cli/start.d.ts +0 -3
  178. package/dist/cli/start.d.ts.map +0 -1
  179. package/dist/cli/start.js +0 -40
  180. package/dist/cli/start.js.map +0 -1
  181. package/dist/receivers/http-utils.d.ts +0 -5
  182. package/dist/receivers/http-utils.d.ts.map +0 -1
  183. package/dist/receivers/http-utils.js +0 -19
  184. package/dist/receivers/http-utils.js.map +0 -1
  185. package/dist/receivers/render-html-for-install-path.d.ts +0 -3
  186. package/dist/receivers/render-html-for-install-path.d.ts.map +0 -1
  187. package/dist/receivers/render-html-for-install-path.js +0 -32
  188. package/dist/receivers/render-html-for-install-path.js.map +0 -1
  189. package/dist/types/block-suggestion/index.d.ts +0 -97
  190. package/dist/types/block-suggestion/index.d.ts.map +0 -1
  191. package/dist/types/block-suggestion/index.js.map +0 -1
  192. package/dist/types/events/base-events.d.ts +0 -1135
  193. package/dist/types/events/base-events.d.ts.map +0 -1
  194. package/dist/types/events/base-events.js +0 -5
  195. package/dist/types/events/base-events.js.map +0 -1
  196. package/dist/types/events/message-events.d.ts +0 -348
  197. package/dist/types/events/message-events.d.ts.map +0 -1
  198. package/dist/types/events/message-events.js +0 -3
  199. package/dist/types/events/message-events.js.map +0 -1
  200. package/dist/types/functions/index.d.ts +0 -26
  201. package/dist/types/functions/index.d.ts.map +0 -1
  202. package/dist/types/functions/index.js +0 -3
  203. package/dist/types/functions/index.js.map +0 -1
  204. package/dist/types/helpers.d.ts +0 -17
  205. package/dist/types/helpers.d.ts.map +0 -1
  206. package/dist/types/helpers.js +0 -3
  207. package/dist/types/helpers.js.map +0 -1
  208. package/dist/types/subscription/index.d.ts +0 -80
  209. package/dist/types/subscription/index.d.ts.map +0 -1
  210. package/dist/types/subscription/index.js +0 -3
  211. package/dist/types/subscription/index.js.map +0 -1
  212. package/src/cli/check-update.js +0 -13
  213. package/src/cli/get-hooks.js +0 -17
  214. package/src/cli/get-manifest.js +0 -16
  215. package/src/cli/hook-utils/get-check-update-data.js +0 -292
  216. package/src/cli/hook-utils/get-manifest-data.js +0 -39
  217. package/src/cli/hook-utils/manifest.js +0 -108
  218. package/src/cli/start.js +0 -43
package/dist/App.js CHANGED
@@ -4,29 +4,24 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.LogLevel = void 0;
7
- const util_1 = __importDefault(require("util"));
8
- const web_api_1 = require("@slack/web-api");
7
+ const node_util_1 = __importDefault(require("node:util"));
9
8
  const logger_1 = require("@slack/logger");
9
+ const web_api_1 = require("@slack/web-api");
10
10
  const axios_1 = __importDefault(require("axios"));
11
- const SocketModeReceiver_1 = __importDefault(require("./receivers/SocketModeReceiver"));
12
- const HTTPReceiver_1 = __importDefault(require("./receivers/HTTPReceiver"));
13
- const builtin_1 = require("./middleware/builtin");
14
- const process_1 = __importDefault(require("./middleware/process"));
11
+ const CustomFunction_1 = require("./CustomFunction");
15
12
  const conversation_store_1 = require("./conversation-store");
16
- const Subscription_1 = require("./Subscription");
17
- const helpers_1 = require("./helpers");
18
13
  const errors_1 = require("./errors");
14
+ const helpers_1 = require("./helpers");
15
+ const builtin_1 = require("./middleware/builtin");
16
+ const process_1 = __importDefault(require("./middleware/process"));
17
+ const HTTPReceiver_1 = __importDefault(require("./receivers/HTTPReceiver"));
18
+ const SocketModeReceiver_1 = __importDefault(require("./receivers/SocketModeReceiver"));
19
19
  const middleware_1 = require("./types/middleware");
20
- // eslint-disable-next-line import/order
21
- const allSettled = require("promise.allsettled"); // eslint-disable-line @typescript-eslint/no-require-imports
22
- // eslint-disable-next-line @typescript-eslint/no-require-imports, import/no-commonjs
23
- const packageJson = require('../package.json'); // eslint-disable-line @typescript-eslint/no-var-requires
24
- // ----------------------------
25
- // For CLI local run use case
26
- const cliAppTokenOverride = process.env.SLACK_CLI_XAPP;
27
- const cliBotTokenOverride = process.env.SLACK_CLI_XOXB;
20
+ const utilities_1 = require("./types/utilities");
21
+ const packageJson = require('../package.json');
28
22
  // ----------------------------
29
23
  // For listener registration methods
24
+ // TODO: we have types for this... consolidate
30
25
  const validViewTypes = ['view_closed', 'view_submission'];
31
26
  // ----------------------------
32
27
  // For the constructor
@@ -35,9 +30,7 @@ const tokenUsage = 'Apps used in a single workspace can be initialized with a to
35
30
  var logger_2 = require("@slack/logger");
36
31
  Object.defineProperty(exports, "LogLevel", { enumerable: true, get: function () { return logger_2.LogLevel; } });
37
32
  class WebClientPool {
38
- constructor() {
39
- this.pool = {};
40
- }
33
+ pool = {};
41
34
  getOrCreate(token, clientOptions) {
42
35
  const cachedClient = this.pool[token];
43
36
  if (typeof cachedClient !== 'undefined') {
@@ -52,22 +45,53 @@ class WebClientPool {
52
45
  * A Slack App
53
46
  */
54
47
  class App {
55
- constructor({ signingSecret = undefined, endpoints = undefined, port = undefined, customRoutes = undefined, agent = undefined, clientTls = undefined, receiver = undefined, convoStore = undefined, token = undefined, appToken = undefined, botId = undefined, botUserId = undefined, authorize = undefined, logger = undefined, logLevel = undefined, ignoreSelf = true, clientOptions = undefined, processBeforeResponse = false, signatureVerification = true, clientId = undefined, clientSecret = undefined, stateSecret = undefined, redirectUri = undefined, installationStore = undefined, scopes = undefined, installerOptions = undefined, socketMode = undefined, developerMode = false, tokenVerificationEnabled = true, extendedErrorHandler = false, deferInitialization = false, } = {}) {
56
- // Some payloads don't have teamId anymore. So we use EnterpriseId in those scenarios
57
- this.clients = {};
48
+ /** Slack Web API client */
49
+ client;
50
+ clientOptions;
51
+ // Some payloads don't have teamId anymore. So we use EnterpriseId in those scenarios
52
+ clients = {};
53
+ /** Receiver - ingests events from the Slack platform */
54
+ receiver;
55
+ /** Logger */
56
+ logger;
57
+ /** Log Level */
58
+ logLevel;
59
+ /** Authorize */
60
+ authorize;
61
+ /** Global middleware chain */
62
+ middleware;
63
+ /** Listener middleware chains */
64
+ listeners;
65
+ errorHandler;
66
+ axios;
67
+ installerOptions;
68
+ socketMode;
69
+ developerMode;
70
+ extendedErrorHandler;
71
+ hasCustomErrorHandler;
72
+ // used when deferInitialization is true
73
+ argToken;
74
+ // used when deferInitialization is true
75
+ argAuthorize;
76
+ // used when deferInitialization is true
77
+ argAuthorization;
78
+ tokenVerificationEnabled;
79
+ initialized;
80
+ attachFunctionToken;
81
+ constructor({ signingSecret = undefined, endpoints = undefined, port = undefined, customRoutes = undefined, agent = undefined, clientTls = undefined, receiver = undefined, convoStore = undefined, token = undefined, appToken = undefined, botId = undefined, botUserId = undefined, authorize = undefined, logger = undefined, logLevel = undefined, ignoreSelf = true, clientOptions = undefined, processBeforeResponse = false, signatureVerification = true, clientId = undefined, clientSecret = undefined, stateSecret = undefined, redirectUri = undefined, installationStore = undefined, scopes = undefined, installerOptions = undefined, socketMode = undefined, developerMode = false, tokenVerificationEnabled = true, extendedErrorHandler = false, deferInitialization = false, attachFunctionToken = true, } = {}) {
58
82
  /* ------------------------ Developer mode ----------------------------- */
59
83
  this.developerMode = developerMode;
60
- if (developerMode || cliAppTokenOverride) {
84
+ if (developerMode) {
61
85
  // Set logLevel to Debug in Developer Mode if one wasn't passed in
62
- this.logLevel = logLevel !== null && logLevel !== void 0 ? logLevel : logger_1.LogLevel.DEBUG;
86
+ this.logLevel = logLevel ?? logger_1.LogLevel.DEBUG;
63
87
  // Set SocketMode to true if one wasn't passed in
64
- this.socketMode = socketMode !== null && socketMode !== void 0 ? socketMode : true;
88
+ this.socketMode = socketMode ?? true;
65
89
  }
66
90
  else {
67
91
  // If devs aren't using Developer Mode or Socket Mode, set it to false
68
- this.socketMode = socketMode !== null && socketMode !== void 0 ? socketMode : false;
92
+ this.socketMode = socketMode ?? false;
69
93
  // Set logLevel to Info if one wasn't passed in
70
- this.logLevel = logLevel !== null && logLevel !== void 0 ? logLevel : logger_1.LogLevel.INFO;
94
+ this.logLevel = logLevel ?? logger_1.LogLevel.INFO;
71
95
  }
72
96
  /* ------------------------ Set logger ----------------------------- */
73
97
  if (typeof logger === 'undefined') {
@@ -86,6 +110,8 @@ class App {
86
110
  this.hasCustomErrorHandler = false;
87
111
  this.errorHandler = defaultErrorHandler(this.logger);
88
112
  this.extendedErrorHandler = extendedErrorHandler;
113
+ // Override token with functionBotAccessToken in function-related handlers
114
+ this.attachFunctionToken = attachFunctionToken;
89
115
  /* ------------------------ Set client options ------------------------*/
90
116
  this.clientOptions = clientOptions !== undefined ? clientOptions : {};
91
117
  if (agent !== undefined && this.clientOptions.agent === undefined) {
@@ -104,7 +130,7 @@ class App {
104
130
  }
105
131
  // The public WebClient instance (app.client)
106
132
  // Since v3.4, it can have the passed token in the case of single workspace installation.
107
- this.client = new web_api_1.WebClient(cliBotTokenOverride || token, this.clientOptions);
133
+ this.client = new web_api_1.WebClient(token, this.clientOptions);
108
134
  this.axios = axios_1.default.create({
109
135
  httpAgent: agent,
110
136
  httpsAgent: agent,
@@ -138,11 +164,11 @@ class App {
138
164
  failure: (error, _installOptions, _req, res) => {
139
165
  this.logger.debug(error);
140
166
  res.writeHead(500, { 'Content-Type': 'text/html' });
141
- res.end(`<html><body><h1>OAuth failed!</h1><div>${error}</div></body></html>`);
167
+ res.end(`<html><body><h1>OAuth failed!</h1><div>${escapeHtml(error.code)}</div></body></html>`);
142
168
  },
143
169
  };
144
170
  }
145
- this.receiver = this.initReceiver(receiver, signingSecret, endpoints, port, customRoutes, processBeforeResponse, signatureVerification, clientId, clientSecret, stateSecret, redirectUri, installationStore, scopes, cliAppTokenOverride || appToken, logger);
171
+ this.receiver = this.initReceiver(receiver, signingSecret, endpoints, port, customRoutes, processBeforeResponse, signatureVerification, clientId, clientSecret, stateSecret, redirectUri, installationStore, scopes, appToken, logger);
146
172
  /* ------------------------ Set authorize ----------------------------- */
147
173
  this.tokenVerificationEnabled = tokenVerificationEnabled;
148
174
  let argAuthorization;
@@ -153,15 +179,7 @@ class App {
153
179
  botToken: token,
154
180
  };
155
181
  }
156
- if (cliBotTokenOverride !== undefined) {
157
- argAuthorization = {
158
- botId,
159
- botUserId,
160
- botToken: cliBotTokenOverride,
161
- };
162
- }
163
182
  if (deferInitialization) {
164
- // TODO: Deal with this
165
183
  this.argToken = token;
166
184
  this.argAuthorize = authorize;
167
185
  this.argAuthorization = argAuthorization;
@@ -169,12 +187,12 @@ class App {
169
187
  // You need to run `await app.init();` on your own
170
188
  }
171
189
  else {
172
- this.authorize = this.initAuthorizeInConstructor(cliBotTokenOverride || token, authorize, argAuthorization);
190
+ this.authorize = this.initAuthorizeInConstructor(token, authorize, argAuthorization);
173
191
  this.initialized = true;
174
192
  }
175
193
  // Conditionally use a global middleware that ignores events (including messages) that are sent from this app
176
194
  if (ignoreSelf) {
177
- this.use((0, builtin_1.ignoreSelf)());
195
+ this.use(builtin_1.ignoreSelf);
178
196
  }
179
197
  // Use conversation state global middleware
180
198
  if (convoStore !== false) {
@@ -220,6 +238,9 @@ class App {
220
238
  throw e;
221
239
  }
222
240
  }
241
+ get webClientOptions() {
242
+ return this.clientOptions;
243
+ }
223
244
  /**
224
245
  * Register a new middleware, processed in the order registered.
225
246
  *
@@ -229,6 +250,27 @@ class App {
229
250
  this.middleware.push(m);
230
251
  return this;
231
252
  }
253
+ /**
254
+ * Register WorkflowStep middleware
255
+ *
256
+ * @param workflowStep global workflow step middleware function
257
+ * @deprecated Steps from Apps are no longer supported and support for them will be removed in the next major bolt-js
258
+ * version.
259
+ */
260
+ step(workflowStep) {
261
+ const m = workflowStep.getMiddleware();
262
+ this.middleware.push(m);
263
+ return this;
264
+ }
265
+ /**
266
+ * Register CustomFunction middleware
267
+ */
268
+ function(callbackId, ...listeners) {
269
+ const fn = new CustomFunction_1.CustomFunction(callbackId, listeners, this.webClientOptions);
270
+ const m = fn.getMiddleware();
271
+ this.middleware.push(m);
272
+ return this;
273
+ }
232
274
  /**
233
275
  * Convenience method to call start on the receiver
234
276
  *
@@ -243,38 +285,10 @@ class App {
243
285
  // TODO: HTTPReceiver['start'] should be the actual receiver's return type
244
286
  return this.receiver.start(...args);
245
287
  }
246
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
288
+ // biome-ignore lint/suspicious/noExplicitAny: receivers could accept anything as arguments for stop
247
289
  stop(...args) {
248
290
  return this.receiver.stop(...args);
249
291
  }
250
- /**
251
- * Register WorkflowStep middleware
252
- *
253
- * Not to be confused with next-gen platform Workflows + Functions
254
- *
255
- * @param workflowStep global workflow step middleware function
256
- */
257
- step(workflowStep) {
258
- const m = workflowStep.getMiddleware();
259
- this.middleware.push(m);
260
- return this;
261
- }
262
- /**
263
- * Process a subscription event
264
- *
265
- * @param listeners middleware that process and react to subscription payloads
266
- */
267
- subscription(options) {
268
- /*
269
- * TODO If it becomes possible for users to set a custom unique resource id,
270
- * custom id should be supplied in place of the default.
271
- * */
272
- const defaultId = 'DEFAULTID';
273
- const s = new Subscription_1.Subscription(defaultId, options);
274
- const m = s.getMiddleware();
275
- this.middleware.push(m);
276
- return this;
277
- }
278
292
  event(eventNameOrPattern, ...listeners) {
279
293
  let invalidEventName = false;
280
294
  if (typeof eventNameOrPattern === 'string') {
@@ -286,36 +300,25 @@ class App {
286
300
  invalidEventName = name.startsWith('message\\.');
287
301
  }
288
302
  if (invalidEventName) {
289
- throw new errors_1.AppInitializationError(`Although the document mentions "${eventNameOrPattern}",` +
290
- 'it is not a valid event type. Use "message" instead. ' +
291
- 'If you want to filter message events, you can use event.channel_type for it.');
303
+ throw new errors_1.AppInitializationError(`Although the document mentions "${eventNameOrPattern}", it is not a valid event type. Use "message" instead. If you want to filter message events, you can use event.channel_type for it.`);
292
304
  }
293
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
294
- const _listeners = listeners; // FIXME: workaround for TypeScript 4.7 breaking changes
305
+ // biome-ignore lint/suspicious/noExplicitAny: FIXME: workaround for TypeScript 4.7 breaking changes
306
+ const _listeners = listeners;
295
307
  this.listeners.push([
296
308
  builtin_1.onlyEvents,
297
309
  (0, builtin_1.matchEventType)(eventNameOrPattern),
298
310
  ..._listeners,
299
311
  ]);
300
312
  }
301
- /**
302
- * Register a Slack Function
303
- *
304
- * @param slackFn a main function to register
305
- *
306
- * */
307
- function(slackFn) {
308
- const m = slackFn.getMiddleware();
309
- this.middleware.push(m);
310
- }
313
+ // TODO: expose a type parameter for overriding the MessageEvent type (just like shortcut() and action() does) https://github.com/slackapi/bolt-js/issues/796
311
314
  message(...patternsOrMiddleware) {
312
315
  const messageMiddleware = patternsOrMiddleware.map((patternOrMiddleware) => {
313
- if (typeof patternOrMiddleware === 'string' || util_1.default.types.isRegExp(patternOrMiddleware)) {
316
+ if (typeof patternOrMiddleware === 'string' || node_util_1.default.types.isRegExp(patternOrMiddleware)) {
314
317
  return (0, builtin_1.matchMessage)(patternOrMiddleware);
315
318
  }
316
319
  return patternOrMiddleware;
317
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
318
- }); // FIXME: workaround for TypeScript 4.7 breaking changes
320
+ // biome-ignore lint/suspicious/noExplicitAny: FIXME: workaround for TypeScript 4.7 breaking changes
321
+ });
319
322
  this.listeners.push([
320
323
  builtin_1.onlyEvents,
321
324
  (0, builtin_1.matchEventType)('message'),
@@ -323,17 +326,18 @@ class App {
323
326
  ]);
324
327
  }
325
328
  shortcut(callbackIdOrConstraints, ...listeners) {
326
- const constraints = typeof callbackIdOrConstraints === 'string' || util_1.default.types.isRegExp(callbackIdOrConstraints) ?
327
- { callback_id: callbackIdOrConstraints } :
328
- callbackIdOrConstraints;
329
+ const constraints = typeof callbackIdOrConstraints === 'string' || node_util_1.default.types.isRegExp(callbackIdOrConstraints)
330
+ ? { callback_id: callbackIdOrConstraints }
331
+ : callbackIdOrConstraints;
329
332
  // Fail early if the constraints contain invalid keys
330
333
  const unknownConstraintKeys = Object.keys(constraints).filter((k) => k !== 'callback_id' && k !== 'type');
331
334
  if (unknownConstraintKeys.length > 0) {
335
+ // TODO:event() will throw an error if you provide an invalid event name; we should align this behaviour.
332
336
  this.logger.error(`Slack listener cannot be attached using unknown constraint keys: ${unknownConstraintKeys.join(', ')}`);
333
337
  return;
334
338
  }
335
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
336
- const _listeners = listeners; // FIXME: workaround for TypeScript 4.7 breaking changes
339
+ // biome-ignore lint/suspicious/noExplicitAny: FIXME: workaround for TypeScript 4.7 breaking changes
340
+ const _listeners = listeners;
337
341
  this.listeners.push([
338
342
  builtin_1.onlyShortcuts,
339
343
  (0, builtin_1.matchConstraints)(constraints),
@@ -342,22 +346,23 @@ class App {
342
346
  }
343
347
  action(actionIdOrConstraints, ...listeners) {
344
348
  // Normalize Constraints
345
- const constraints = typeof actionIdOrConstraints === 'string' || util_1.default.types.isRegExp(actionIdOrConstraints) ?
346
- { action_id: actionIdOrConstraints } :
347
- actionIdOrConstraints;
349
+ const constraints = typeof actionIdOrConstraints === 'string' || node_util_1.default.types.isRegExp(actionIdOrConstraints)
350
+ ? { action_id: actionIdOrConstraints }
351
+ : actionIdOrConstraints;
348
352
  // Fail early if the constraints contain invalid keys
349
353
  const unknownConstraintKeys = Object.keys(constraints).filter((k) => k !== 'action_id' && k !== 'block_id' && k !== 'callback_id' && k !== 'type');
350
354
  if (unknownConstraintKeys.length > 0) {
355
+ // TODO:event() will throw an error if you provide an invalid event name; we should align this behaviour.
351
356
  this.logger.error(`Action listener cannot be attached using unknown constraint keys: ${unknownConstraintKeys.join(', ')}`);
352
357
  return;
353
358
  }
354
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
355
- const _listeners = listeners; // FIXME: workaround for TypeScript 4.7 breaking changes
359
+ // biome-ignore lint/suspicious/noExplicitAny: FIXME: workaround for TypeScript 4.7 breaking changes
360
+ const _listeners = listeners;
356
361
  this.listeners.push([builtin_1.onlyActions, (0, builtin_1.matchConstraints)(constraints), ..._listeners]);
357
362
  }
358
363
  command(commandName, ...listeners) {
359
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
360
- const _listeners = listeners; // FIXME: workaround for TypeScript 4.7 breaking changes
364
+ // biome-ignore lint/suspicious/noExplicitAny: FIXME: workaround for TypeScript 4.7 breaking changes
365
+ const _listeners = listeners;
361
366
  this.listeners.push([
362
367
  builtin_1.onlyCommands,
363
368
  (0, builtin_1.matchCommandName)(commandName),
@@ -366,17 +371,17 @@ class App {
366
371
  }
367
372
  // TODO: reflect the type in constraints to Source
368
373
  options(actionIdOrConstraints, ...listeners) {
369
- const constraints = typeof actionIdOrConstraints === 'string' || util_1.default.types.isRegExp(actionIdOrConstraints) ?
370
- { action_id: actionIdOrConstraints } :
371
- actionIdOrConstraints;
372
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
373
- const _listeners = listeners; // FIXME: workaround for TypeScript 4.7 breaking changes
374
+ const constraints = typeof actionIdOrConstraints === 'string' || node_util_1.default.types.isRegExp(actionIdOrConstraints)
375
+ ? { action_id: actionIdOrConstraints }
376
+ : actionIdOrConstraints;
377
+ // biome-ignore lint/suspicious/noExplicitAny: FIXME: workaround for TypeScript 4.7 breaking changes
378
+ const _listeners = listeners;
374
379
  this.listeners.push([builtin_1.onlyOptions, (0, builtin_1.matchConstraints)(constraints), ..._listeners]);
375
380
  }
376
381
  view(callbackIdOrConstraints, ...listeners) {
377
- const constraints = typeof callbackIdOrConstraints === 'string' || util_1.default.types.isRegExp(callbackIdOrConstraints) ?
378
- { callback_id: callbackIdOrConstraints, type: 'view_submission' } :
379
- callbackIdOrConstraints;
382
+ const constraints = typeof callbackIdOrConstraints === 'string' || node_util_1.default.types.isRegExp(callbackIdOrConstraints)
383
+ ? { callback_id: callbackIdOrConstraints, type: 'view_submission' }
384
+ : callbackIdOrConstraints;
380
385
  // Fail early if the constraints contain invalid keys
381
386
  const unknownConstraintKeys = Object.keys(constraints).filter((k) => k !== 'callback_id' && k !== 'type');
382
387
  if (unknownConstraintKeys.length > 0) {
@@ -387,8 +392,8 @@ class App {
387
392
  this.logger.error(`View listener cannot be attached using unknown view event type: ${constraints.type}`);
388
393
  return;
389
394
  }
390
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
391
- const _listeners = listeners; // FIXME: workaround for TypeScript 4.7 breaking changes
395
+ // biome-ignore lint/suspicious/noExplicitAny: FIXME: workaround for TypeScript 4.7 breaking changes
396
+ const _listeners = listeners;
392
397
  this.listeners.push([
393
398
  builtin_1.onlyViewActions,
394
399
  (0, builtin_1.matchConstraints)(constraints),
@@ -422,11 +427,10 @@ class App {
422
427
  // From this point on, we assume that body is not just a key-value map, but one of the types of bodies we expect
423
428
  const bodyArg = body;
424
429
  // Check if type event with the authorizations object or if it has a top level is_enterprise_install property
425
- const isEnterpriseInstall = isBodyWithTypeEnterpriseInstall(bodyArg, type);
430
+ const isEnterpriseInstall = (0, helpers_1.isBodyWithTypeEnterpriseInstall)(bodyArg, type);
426
431
  const source = buildSource(type, conversationId, bodyArg, isEnterpriseInstall);
427
- // Get the result of any custom authorize provided
428
432
  let authorizeResult;
429
- if (type === helpers_1.IncomingEventType.Event && isEventTypeToSkipAuthorize(event.body.event.type)) {
433
+ if (type === helpers_1.IncomingEventType.Event && (0, helpers_1.isEventTypeToSkipAuthorize)(event)) {
430
434
  authorizeResult = {
431
435
  enterpriseId: source.enterpriseId,
432
436
  teamId: source.teamId,
@@ -437,12 +441,10 @@ class App {
437
441
  authorizeResult = await this.authorize(source, bodyArg);
438
442
  }
439
443
  catch (error) {
440
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
444
+ // biome-ignore lint/suspicious/noExplicitAny: errors can be anything
441
445
  const e = error;
442
446
  this.logger.warn('Authorization of incoming event did not succeed. No listeners will be called.');
443
447
  e.code = errors_1.ErrorCode.AuthorizationError;
444
- // disabling due to https://github.com/typescript-eslint/typescript-eslint/issues/1277
445
- // eslint-disable-next-line consistent-return
446
448
  return this.handleError({
447
449
  error: e,
448
450
  logger: this.logger,
@@ -453,6 +455,10 @@ class App {
453
455
  });
454
456
  }
455
457
  }
458
+ // Try to set userId from AuthorizeResult before using one from source
459
+ if (authorizeResult.userId === undefined && source.userId !== undefined) {
460
+ authorizeResult.userId = source.userId;
461
+ }
456
462
  // Try to set teamId from AuthorizeResult before using one from source
457
463
  if (authorizeResult.teamId === undefined && source.teamId !== undefined) {
458
464
  authorizeResult.teamId = source.teamId;
@@ -461,7 +467,6 @@ class App {
461
467
  if (authorizeResult.enterpriseId === undefined && source.enterpriseId !== undefined) {
462
468
  authorizeResult.enterpriseId = source.enterpriseId;
463
469
  }
464
- // Try to set custom properties if they exist
465
470
  if (typeof event.customProperties !== 'undefined') {
466
471
  const customProps = event.customProperties;
467
472
  const builtinKeyDetected = middleware_1.contextBuiltinKeys.find((key) => key in customProps);
@@ -469,49 +474,45 @@ class App {
469
474
  throw new errors_1.InvalidCustomPropertyError('customProperties cannot have the same names with the built-in ones');
470
475
  }
471
476
  }
472
- /**
473
- * Set the Slack Function Bot Access Token if it exists in event payload to the context.
474
- *
475
- * A bot_access_token will exist in any payload that has been generated
476
- * in the context of a Slack Function execution. This includes function_execution
477
- * events themselves, as well as interactivity payloads (e.g. block_actions, views).
478
- *
479
- * This token must be used for further Slack API calls which are relevant to this
480
- * Slack Function execution in order for any interactivity context data to be
481
- * properly sent by Slack.
482
- *
483
- * Bolt will set this value in the event Context and
484
- * use this token in place of any other token (for example the token
485
- * that the App was configured with) to initialize the Web Client.
486
- *
487
- * Sometimes the bot_access_token is located in the event
488
- * Sometimes it is located directly in the body.
489
- */
490
- let slackFunctionBotAccessToken = body.bot_access_token;
491
- if (slackFunctionBotAccessToken === undefined && 'event' in body) {
492
- slackFunctionBotAccessToken = body.event.bot_access_token;
493
- }
494
- // Declare the event context
495
477
  const context = {
496
478
  ...authorizeResult,
497
479
  ...event.customProperties,
498
- slackFunctionBotAccessToken,
499
480
  isEnterpriseInstall,
500
481
  retryNum: event.retryNum,
501
482
  retryReason: event.retryReason,
502
483
  };
484
+ // Extract function-related information and augment context
485
+ const { functionExecutionId, functionBotAccessToken, functionInputs } = extractFunctionContext(body);
486
+ if (functionExecutionId) {
487
+ context.functionExecutionId = functionExecutionId;
488
+ if (functionInputs) {
489
+ context.functionInputs = functionInputs;
490
+ }
491
+ }
492
+ // Attach and make available the JIT/function-related token on context
493
+ if (this.attachFunctionToken) {
494
+ if (functionBotAccessToken) {
495
+ context.functionBotAccessToken = functionBotAccessToken;
496
+ }
497
+ }
503
498
  // Factory for say() utility
504
499
  const createSay = (channelId) => {
505
500
  const token = selectToken(context);
506
501
  return (message) => {
507
- const postMessageArguments = typeof message === 'string' ?
508
- { token, text: message, channel: channelId } :
509
- { ...message, token, channel: channelId };
502
+ let postMessageArguments;
503
+ if (typeof message === 'string') {
504
+ postMessageArguments = { token, text: message, channel: channelId };
505
+ }
506
+ else {
507
+ postMessageArguments = { ...message, token, channel: channelId };
508
+ }
510
509
  return this.client.chat.postMessage(postMessageArguments);
511
510
  };
512
511
  };
513
512
  // Set body and payload
514
513
  // TODO: this value should eventually conform to AnyMiddlewareArgs
514
+ // TODO: remove workflow step stuff in bolt v5
515
+ // 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
515
516
  let payload;
516
517
  switch (type) {
517
518
  case helpers_1.IncomingEventType.Event:
@@ -523,8 +524,7 @@ class App {
523
524
  case helpers_1.IncomingEventType.Shortcut:
524
525
  payload = bodyArg;
525
526
  break;
526
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
527
- // @ts-ignore: Fallthrough case in switch
527
+ // biome-ignore lint/suspicious/noFallthroughSwitchClause: usually not great, but we do it here
528
528
  case helpers_1.IncomingEventType.Action:
529
529
  if (isBlockActionOrInteractiveMessageBody(bodyArg)) {
530
530
  const { actions } = bodyArg;
@@ -536,10 +536,13 @@ class App {
536
536
  payload = bodyArg;
537
537
  break;
538
538
  }
539
+ // NOTE: the following doesn't work because... distributive?
540
+ // const listenerArgs: Partial<AnyMiddlewareArgs> = {
539
541
  const listenerArgs = {
540
542
  body: bodyArg,
541
543
  payload,
542
544
  };
545
+ // 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
543
546
  // Set aliases
544
547
  if (type === helpers_1.IncomingEventType.Event) {
545
548
  const eventListenerArgs = listenerArgs;
@@ -589,16 +592,24 @@ class App {
589
592
  // Events API requests are acknowledged right away, since there's no data expected
590
593
  await ack();
591
594
  }
592
- // Get or create the client
595
+ // Get the client arg
593
596
  let { client } = this;
594
- const token = selectToken(context);
597
+ // If functionBotAccessToken exists on context, the incoming event is function-related *and* the
598
+ // user has `attachFunctionToken` enabled. In that case, subsequent calls with the client should
599
+ // use the function-related/JIT token in lieu of the botToken or userToken.
600
+ const token = context.functionBotAccessToken ? context.functionBotAccessToken : selectToken(context);
601
+ // Add complete() and fail() utilities for function-related interactivity
602
+ if (type === helpers_1.IncomingEventType.Action && context.functionExecutionId !== undefined) {
603
+ listenerArgs.complete = CustomFunction_1.CustomFunction.createFunctionComplete(context, client);
604
+ listenerArgs.fail = CustomFunction_1.CustomFunction.createFunctionFail(context, client);
605
+ listenerArgs.inputs = context.functionInputs;
606
+ }
595
607
  if (token !== undefined) {
596
- let pool;
608
+ let pool = undefined;
597
609
  const clientOptionsCopy = { ...this.clientOptions };
598
610
  if (authorizeResult.teamId !== undefined) {
599
611
  pool = this.clients[authorizeResult.teamId];
600
612
  if (pool === undefined) {
601
- // eslint-disable-next-line no-multi-assign
602
613
  pool = this.clients[authorizeResult.teamId] = new WebClientPool();
603
614
  }
604
615
  // Add teamId to clientOptions so it can be automatically added to web-api calls
@@ -607,7 +618,6 @@ class App {
607
618
  else if (authorizeResult.enterpriseId !== undefined) {
608
619
  pool = this.clients[authorizeResult.enterpriseId];
609
620
  if (pool === undefined) {
610
- // eslint-disable-next-line no-multi-assign
611
621
  pool = this.clients[authorizeResult.enterpriseId] = new WebClientPool();
612
622
  }
613
623
  }
@@ -623,26 +633,27 @@ class App {
623
633
  const listenerResults = this.listeners.map(async (origListenerMiddleware) => {
624
634
  // Copy the array so modifications don't affect the original
625
635
  const listenerMiddleware = [...origListenerMiddleware];
626
- // Don't process the last item in the listenerMiddleware array - it shouldn't get a next fn
636
+ // Don't process the last item in the listenerMiddleware array - it will be passed a no-op next fn
627
637
  const listener = listenerMiddleware.pop();
628
638
  if (listener === undefined) {
629
639
  return undefined;
630
640
  }
631
641
  return (0, process_1.default)(listenerMiddleware, listenerArgs, context, client, this.logger,
632
642
  // When all the listener middleware are done processing,
633
- // `listener` here will be called without a `next` execution
643
+ // `listener` here will be called with a noop `next` fn
634
644
  async () => listener({
635
645
  ...listenerArgs,
636
646
  context,
637
647
  client,
638
648
  logger: this.logger,
639
- // `next` is already set in the outer processMiddleware
649
+ next: () => { },
640
650
  }));
641
651
  });
642
- const settledListenerResults = await allSettled(listenerResults);
643
- const rejectedListenerResults = settledListenerResults.filter((lr) => lr.status === 'rejected');
652
+ const settledListenerResults = await Promise.allSettled(listenerResults);
653
+ const rejectedListenerResults = settledListenerResults.filter(utilities_1.isRejected);
644
654
  if (rejectedListenerResults.length === 1) {
645
655
  throw rejectedListenerResults[0].reason;
656
+ // biome-ignore lint/style/noUselessElse: I think this is a biome issue actually...
646
657
  }
647
658
  else if (rejectedListenerResults.length > 1) {
648
659
  throw new errors_1.MultipleListenerError(rejectedListenerResults.map((rlr) => rlr.reason));
@@ -650,10 +661,8 @@ class App {
650
661
  });
651
662
  }
652
663
  catch (error) {
653
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
664
+ // biome-ignore lint/suspicious/noExplicitAny: errors can be anything
654
665
  const e = error;
655
- // disabling due to https://github.com/typescript-eslint/typescript-eslint/issues/1277
656
- // eslint-disable-next-line consistent-return
657
666
  return this.handleError({
658
667
  context,
659
668
  error: e,
@@ -667,9 +676,9 @@ class App {
667
676
  */
668
677
  handleError(args) {
669
678
  const { error, ...rest } = args;
670
- return this.extendedErrorHandler && this.hasCustomErrorHandler ?
671
- this.errorHandler({ error: (0, errors_1.asCodedError)(error), ...rest }) :
672
- this.errorHandler((0, errors_1.asCodedError)(error));
679
+ return this.extendedErrorHandler && this.hasCustomErrorHandler
680
+ ? this.errorHandler({ error: (0, errors_1.asCodedError)(error), ...rest })
681
+ : this.errorHandler((0, errors_1.asCodedError)(error));
673
682
  }
674
683
  // ---------------------
675
684
  // Private methods for initialization
@@ -677,35 +686,29 @@ class App {
677
686
  initReceiver(receiver, signingSecret, endpoints, port, customRoutes, processBeforeResponse, signatureVerification, clientId, clientSecret, stateSecret, redirectUri, installationStore, scopes, appToken, logger) {
678
687
  if (receiver !== undefined) {
679
688
  // Custom receiver supplied
680
- if (this.socketMode === true) {
681
- // socketMode = true should result in SocketModeReceiver being used as receiver
682
- // TODO: Add case for when socketMode = true and receiver = SocketModeReceiver
683
- // as this should not result in an error
689
+ if (this.socketMode === true && !(receiver instanceof SocketModeReceiver_1.default)) {
684
690
  throw new errors_1.AppInitializationError('You cannot supply a custom receiver when socketMode is set to true.');
685
691
  }
686
692
  return receiver;
687
693
  }
688
694
  if (this.socketMode === true) {
689
- if (cliAppTokenOverride === undefined && appToken === undefined) {
695
+ if (appToken === undefined) {
690
696
  throw new errors_1.AppInitializationError('You must provide an appToken when socketMode is set to true. To generate an appToken see: https://api.slack.com/apis/connections/socket#token');
691
697
  }
692
698
  this.logger.debug('Initializing SocketModeReceiver');
693
- const xaxpToken = cliAppTokenOverride || appToken;
694
- if (xaxpToken !== undefined) {
695
- return new SocketModeReceiver_1.default({
696
- appToken: xaxpToken,
697
- clientId,
698
- clientSecret,
699
- stateSecret,
700
- redirectUri,
701
- installationStore,
702
- scopes,
703
- logger,
704
- logLevel: this.logLevel,
705
- installerOptions: this.installerOptions,
706
- customRoutes,
707
- });
708
- }
699
+ return new SocketModeReceiver_1.default({
700
+ appToken,
701
+ clientId,
702
+ clientSecret,
703
+ stateSecret,
704
+ redirectUri,
705
+ installationStore,
706
+ scopes,
707
+ logger,
708
+ logLevel: this.logLevel,
709
+ installerOptions: this.installerOptions,
710
+ customRoutes,
711
+ });
709
712
  }
710
713
  if (signatureVerification === true && signingSecret === undefined) {
711
714
  // Using default receiver HTTPReceiver, signature verification enabled, missing signingSecret
@@ -734,8 +737,7 @@ class App {
734
737
  initAuthorizeIfNoTokenIsGiven(token, authorize) {
735
738
  let usingOauth = false;
736
739
  const httpReceiver = this.receiver;
737
- if (httpReceiver.installer !== undefined &&
738
- httpReceiver.installer.authorize !== undefined) {
740
+ if (httpReceiver.installer !== undefined && httpReceiver.installer.authorize !== undefined) {
739
741
  // This supports using the built-in HTTPReceiver, declaring your own HTTPReceiver
740
742
  // and theoretically, doing a fully custom (non-Express.js) receiver that implements OAuth
741
743
  usingOauth = true;
@@ -747,14 +749,17 @@ class App {
747
749
  return undefined;
748
750
  }
749
751
  if (authorize === undefined && !usingOauth) {
750
- 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`);
752
+ 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`);
753
+ // biome-ignore lint/style/noUselessElse: I think this is a biome issue actually...
751
754
  }
752
755
  else if (authorize !== undefined && usingOauth) {
753
756
  throw new errors_1.AppInitializationError(`You cannot provide both authorize and oauth installer options. ${tokenUsage}`);
757
+ // biome-ignore lint/style/noUselessElse: I think this is a biome issue actually...
754
758
  }
755
759
  else if (authorize === undefined && usingOauth) {
756
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
760
+ // biome-ignore lint/style/noNonNullAssertion: we know installer is truthy here
757
761
  return httpReceiver.installer.authorize;
762
+ // biome-ignore lint/style/noUselessElse: I think this is a biome issue actually...
758
763
  }
759
764
  else if (authorize !== undefined && !usingOauth) {
760
765
  return authorize;
@@ -786,9 +791,9 @@ function defaultErrorHandler(logger) {
786
791
  // singleAuthorization
787
792
  function runAuthTestForBotToken(client, authorization) {
788
793
  // TODO: warn when something needed isn't found
789
- return authorization.botUserId !== undefined && authorization.botId !== undefined ?
790
- Promise.resolve({ botUserId: authorization.botUserId, botId: authorization.botId }) :
791
- client.auth.test({ token: authorization.botToken }).then((result) => ({
794
+ return authorization.botUserId !== undefined && authorization.botId !== undefined
795
+ ? Promise.resolve({ botUserId: authorization.botUserId, botId: authorization.botId })
796
+ : client.auth.test({ token: authorization.botToken }).then((result) => ({
792
797
  botUserId: result.user_id,
793
798
  botId: result.bot_id,
794
799
  }));
@@ -832,10 +837,6 @@ function buildSource(type, channelId, body, isEnterpriseInstall) {
832
837
  if (type === helpers_1.IncomingEventType.Command) {
833
838
  return body.team_id;
834
839
  }
835
- if (type === helpers_1.IncomingEventType.Subscription) {
836
- const bodyAsSubscriptionInteraction = body;
837
- return bodyAsSubscriptionInteraction.team.id;
838
- }
839
840
  const parseTeamId = (bodyAs) => {
840
841
  // When the app is installed using org-wide deployment, team property will be null
841
842
  if (typeof bodyAs.team !== 'undefined' && bodyAs.team !== null) {
@@ -874,10 +875,6 @@ function buildSource(type, channelId, body, isEnterpriseInstall) {
874
875
  if (type === helpers_1.IncomingEventType.Command) {
875
876
  return body.enterprise_id;
876
877
  }
877
- if (type === helpers_1.IncomingEventType.Subscription) {
878
- const bodyAsSubscriptionInteraction = body;
879
- return bodyAsSubscriptionInteraction.team.enterprise_id;
880
- }
881
878
  if (type === helpers_1.IncomingEventType.Action ||
882
879
  type === helpers_1.IncomingEventType.Options ||
883
880
  type === helpers_1.IncomingEventType.ViewAction ||
@@ -917,10 +914,6 @@ function buildSource(type, channelId, body, isEnterpriseInstall) {
917
914
  }
918
915
  return undefined;
919
916
  }
920
- if (type === helpers_1.IncomingEventType.Subscription) {
921
- const bodyAsSubscriptionInteraction = body;
922
- return bodyAsSubscriptionInteraction.user.id;
923
- }
924
917
  if (type === helpers_1.IncomingEventType.Action ||
925
918
  type === helpers_1.IncomingEventType.Options ||
926
919
  type === helpers_1.IncomingEventType.ViewAction ||
@@ -942,38 +935,12 @@ function buildSource(type, channelId, body, isEnterpriseInstall) {
942
935
  conversationId: channelId,
943
936
  };
944
937
  }
945
- function isBodyWithTypeEnterpriseInstall(body, type) {
946
- if (type === helpers_1.IncomingEventType.Event) {
947
- const bodyAsEvent = body;
948
- if (Array.isArray(bodyAsEvent.authorizations) && bodyAsEvent.authorizations[0] !== undefined) {
949
- return !!bodyAsEvent.authorizations[0].is_enterprise_install;
950
- }
951
- }
952
- if (type === helpers_1.IncomingEventType.Subscription) {
953
- return body.team.enterprise_id !== undefined;
954
- }
955
- if ('is_enterprise_install' in body) {
956
- // command payloads have this property set as a string
957
- if (typeof body.is_enterprise_install === 'string') {
958
- return body.is_enterprise_install === 'true';
959
- }
960
- // all remaining types have a boolean property
961
- if (body.is_enterprise_install !== undefined) {
962
- return body.is_enterprise_install;
963
- }
964
- }
965
- // as a fallback we assume it's a single team installation (but this should never happen)
966
- return false;
967
- }
968
938
  function isBlockActionOrInteractiveMessageBody(body) {
969
939
  return body.actions !== undefined;
970
940
  }
971
- /**
972
- * Returns in order of preference, a bot token, bot access token or user token for client, say()
973
- * */
941
+ // Returns either a bot token or a user token for client, say()
974
942
  function selectToken(context) {
975
- var _a, _b;
976
- return (_b = (_a = context.slackFunctionBotAccessToken) !== null && _a !== void 0 ? _a : context.botToken) !== null && _b !== void 0 ? _b : context.userToken;
943
+ return context.botToken !== undefined ? context.botToken : context.userToken;
977
944
  }
978
945
  function buildRespondFn(axiosInstance, responseUrl) {
979
946
  return async (message) => {
@@ -981,11 +948,33 @@ function buildRespondFn(axiosInstance, responseUrl) {
981
948
  return axiosInstance.post(responseUrl, normalizedArgs);
982
949
  };
983
950
  }
984
- // token revocation use cases
985
- // https://github.com/slackapi/bolt-js/issues/674
986
- const eventTypesToSkipAuthorize = ['app_uninstalled', 'tokens_revoked'];
987
- function isEventTypeToSkipAuthorize(eventType) {
988
- return eventTypesToSkipAuthorize.includes(eventType);
951
+ function escapeHtml(input) {
952
+ if (input) {
953
+ return input
954
+ .replace(/&/g, '&amp;')
955
+ .replace(/</g, '&lt;')
956
+ .replace(/>/g, '&gt;')
957
+ .replace(/"/g, '&quot;')
958
+ .replace(/'/g, '&#x27;');
959
+ }
960
+ return '';
961
+ }
962
+ function extractFunctionContext(body) {
963
+ let functionExecutionId = undefined;
964
+ let functionBotAccessToken = undefined;
965
+ let functionInputs = undefined;
966
+ // function_executed event
967
+ if (body.event && body.event.type === 'function_executed' && body.event.function_execution_id) {
968
+ functionExecutionId = body.event.function_execution_id;
969
+ functionBotAccessToken = body.event.bot_access_token;
970
+ }
971
+ // interactivity (block_actions)
972
+ if (body.function_data) {
973
+ functionExecutionId = body.function_data.execution_id;
974
+ functionBotAccessToken = body.bot_access_token;
975
+ functionInputs = body.function_data.inputs;
976
+ }
977
+ return { functionExecutionId, functionBotAccessToken, functionInputs };
989
978
  }
990
979
  // ----------------------------
991
980
  // Instrumentation