@microsoft/teams.apps
Version:
<p> <a href="https://www.npmjs.com/package/@microsoft/teams.apps" target="_blank"> <img src="https://img.shields.io/npm/v/@microsoft/teams.apps/latest" /> </a> <a href="https://www.npmjs.com/package/@microsoft/teams.apps?activeTab=code
713 lines • 55.1 kB
JavaScript
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.App = void 0;
const axios_1 = require("axios");
const teams_api_1 = require("@microsoft/teams.api");
const teams_common_1 = require("@microsoft/teams.common");
const package_json_1 = __importDefault(require("../package.json"));
const activity_sender_1 = require("./activity-sender");
const api_1 = require("./api");
const app_events_1 = require("./app.events");
const app_plugins_1 = require("./app.plugins");
const app_process_1 = require("./app.process");
const container_1 = require("./container");
const contexts_1 = require("./contexts");
const http_1 = require("./http");
const http_server_1 = require("./http/http-server");
const middleware = __importStar(require("./middleware"));
const remote_function_validator_1 = require("./middleware/auth/remote-function-validator");
const oauth_1 = require("./oauth");
const registry_1 = require("./oauth/registry");
const router_1 = require("./router");
const socket_mode_1 = require("./socket-mode");
const state_1 = require("./state");
const loader_1 = require("./state/loader");
const token_manager_1 = require("./token-manager");
const token_provider_1 = require("./token-provider");
const env_1 = require("./utils/env");
function isAppSendOptions(value) {
if (typeof value === 'string')
return false;
return !('type' in value);
}
/**
* The orchestrator for receiving/sending activities
*/
class App {
options;
api;
cloud;
graph;
log;
server;
/**
* **Experimental.** The Socket Mode inbound transport, present only when the
* app was constructed with `socketMode` enabled. It is the same
* {@link IHttpServerAdapter} instance {@link App.server} runs on. Use it to
* observe the socket lifecycle
* (`app.socketMode.status`, `app.socketMode.geoStatuses`, `app.socketMode.events`).
* WebSocket is only recommended for use when developing agents.
*
* @experimental This API is in preview and may change in the future.
*/
socketMode;
http;
client;
/**
* The app's legacy shared storage instance.
*
* @deprecated Use `ctx.state` for turn state. Applications that need general
* persistence should own and use their storage provider directly.
*/
storage;
entraTokenValidator;
/**
* Graph API base URL derived from the configured cloud's `graphScope`.
* Undefined when the scope isn't a URL — `GraphClient` then uses its public-cloud default.
* Shared across every `GraphClient` the app constructs (`app.graph`, `ctx.appGraph`, `ctx.userGraph`)
* so sovereign customers get consistent routing.
*/
graphBaseUrl;
/**
* the apps credentials
*/
get credentials() {
return this.tokenManager.credentials;
}
/**
* The app's token source, for acquiring a token for something the SDK does not
* call for you, such as an OpenTelemetry exporter.
*/
get tokenProvider() {
return this._tokenProvider;
}
/**
* the apps id
*/
get id() {
return this.credentials?.clientId;
}
get oauth() {
return {
...oauth_1.DEFAULT_OAUTH_SETTINGS,
...this.options.oauth,
};
}
container = new container_1.Container();
pluginManager;
router = new router_1.Router();
tenantTokens = new teams_common_1.LocalStorage({}, { max: 20000 });
events;
isInitialized = false;
port;
activitySender;
/**
* The concrete token machinery: MSAL clients, credential resolution, and the
* per-grant acquisition logic. Private because {@link App.tokenProvider} is
* the supported way in.
*/
tokenManager;
_tokenProvider;
stateLoader;
eventManager;
activityProcessor;
oauthFlowRegistry;
_userAgent = `teams.ts[apps]/${package_json_1.default.version}`;
constructor(options = {}) {
this.options = options;
this.log = this.options.logger || new teams_common_1.ConsoleLogger('@teams/app');
this.events = new teams_common_1.EventEmitter(this.log.child('events'));
this.storage = this.options.storage || new teams_common_1.LocalStorage();
const hasConfiguredOAuthFlows = (this.options.oauthFlows?.length ?? 0) > 0;
if (hasConfiguredOAuthFlows &&
this.options.oauth?.defaultConnectionName !== undefined) {
throw new Error('oauth.defaultConnectionName cannot be combined with registered OAuth flows. ' +
'Remove defaultConnectionName and name the connection when calling OAuth helpers.');
}
this.stateLoader = (0, state_1.createStateLoader)(this.options.state, this.log);
// Resolve cloud environment from options or CLOUD env var
const cloudEnvName = typeof process !== 'undefined' ? process.env.CLOUD : undefined;
this.cloud = this.options.cloud ?? (cloudEnvName ? (0, teams_api_1.cloudFromName)(cloudEnvName) : teams_api_1.PUBLIC);
if (!options.client) {
this.client = new teams_common_1.Client({
headers: {
'User-Agent': this._userAgent,
},
});
}
else if (typeof options.client === 'function') {
this.client = options.client().clone({
headers: {
'User-Agent': this._userAgent,
},
});
}
else if ('request' in options.client) {
this.client = options.client.clone({
headers: {
'User-Agent': this._userAgent,
},
});
}
else {
this.client = new teams_common_1.Client(options.client).clone({
headers: {
'User-Agent': this._userAgent,
},
});
}
// Derive Graph API base URL from the cloud's graphScope (e.g. "https://graph.microsoft.us/.default"
// -> "https://graph.microsoft.us"). Falls back to the public Graph endpoint inside GraphClient if
// the scope isn't a URL (custom delegated scope, empty, etc.).
const graphUrlMatch = /^(https?:\/\/[^/]+)/i.exec((this.cloud.graphScope ?? '').trim());
this.graphBaseUrl = graphUrlMatch?.[1];
if (!this.graphBaseUrl && this.cloud.graphScope) {
this.log.warn(`graphScope "${this.cloud.graphScope}" is not a URL; Graph calls will route to the public cloud. ` +
'Set graphScope to an "https://<host>/.default" value to route to the correct Graph endpoint.');
}
this.graph = new api_1.GraphClient(this.client.clone({ token: async () => (await this.getAppGraphToken()) ?? undefined }), { baseUrlRoot: this.graphBaseUrl });
this.tokenManager = new token_manager_1.TokenManager({
clientId: this.options.clientId,
clientSecret: this.options.clientSecret,
tenantId: this.options.tenantId,
token: this.options.token,
managedIdentityClientId: this.options.managedIdentityClientId,
cloud: this.cloud,
}, this.log);
this._tokenProvider = new token_provider_1.AppTokenProvider(this.tokenManager, this.cloud);
const serviceUrl = (this.options.serviceUrl ?? process.env.SERVICE_URL ??
'https://smba.trafficmanager.net/teams').replace(/\/+$/, '');
const settings = {
...this.options.apiClientSettings,
cloud: this.cloud,
tokenProvider: this.tokenProvider,
};
this.api = new api_1.ApiClient(serviceUrl, this.client.clone(), settings);
// initialize ActivitySender for sending activities
this.activitySender = new activity_sender_1.ActivitySender(this.log, (senderServiceUrl, agenticIdentity) => this.api.clone({
serviceUrl: senderServiceUrl,
agenticIdentity,
}));
// initialize the activity pipeline collaborators. App owns these and passes
// in what they need (rather than them reaching into App via `this`), which
// keeps the primitives above private.
this.pluginManager = new app_plugins_1.PluginManager({
container: this.container,
log: this.log,
handlers: {
onError: (event) => this.eventManager.onError(event),
onActivity: (event) => this.onActivity(event),
emit: (name, event) => this.events.emit(name, event),
},
});
this.eventManager = new app_events_1.EventManager(this.events, this.pluginManager.plugins);
this.activityProcessor = new app_process_1.ActivityProcessor({
router: this.router,
plugins: this.pluginManager.plugins,
eventManager: this.eventManager,
getAppGraphToken: (tenantId) => this.getAppGraphToken(tenantId),
getAgenticGraphToken: (identity, tenantId) => this.getAgenticGraphToken(identity, tenantId),
activitySender: this.activitySender,
api: this.api,
client: this.client,
storage: this.storage,
getStateLoader: () => this.stateLoader,
log: this.log,
getId: () => this.id,
getConnectionName: () => this.oauth.defaultConnectionName,
shouldFetchUserToken: () => this.shouldFetchUserToken(),
validateOAuthConnection: (connectionName, connectionNameProvided) => this.oauthFlowRegistry.validate(connectionName, connectionNameProvided),
onOAuthSignInInitiated: (context, connectionName, supportsSso) => this.oauthFlowRegistry.recordPending(context, connectionName, supportsSso),
getOAuthConnectionStatus: context => this.oauthFlowRegistry.getConnectionStatus(context),
apiClientSettings: this.options.apiClientSettings,
graphBaseUrl: this.graphBaseUrl,
agent365Baggage: this.options.telemetry?.agent365,
});
if (this.credentials?.clientId) {
this.entraTokenValidator = middleware.createEntraTokenValidator(this.credentials.tenantId || 'common', this.credentials.clientId, { applicationIdUri: this.options.applicationIdUri, loginEndpoint: this.cloud.loginEndpoint, logger: this.log });
}
// Determine HTTP server
const plugins = this.options.plugins || [];
const httpPlugin = app_plugins_1.PluginManager.findHttpPlugin(plugins);
// Error if both httpServerAdapter and http plugin are provided
if (this.options.httpServerAdapter && httpPlugin) {
throw new Error('Cannot provide both httpServerAdapter option and HttpPlugin in plugins array. ' +
'Use either:\n' +
' - new App({ httpServerAdapter: new ExpressAdapter() }) (recommended)\n' +
' - new App({ plugins: [new HttpPlugin()] }) (deprecated)');
}
// The deprecated HttpPlugin is a full HTTP server and can't coexist with
// Socket Mode, which is the app's exclusive inbound transport when enabled.
if (this.options.socketMode && httpPlugin) {
throw new Error('Cannot provide both socketMode and an HttpPlugin: Socket Mode manages its own ' +
'inbound transport. Enable one or the other.');
}
let server;
// HttpPlugin in plugins array (backwards compatibility)
if (httpPlugin) {
this.log.warn('[DEPRECATED] HttpPlugin in plugins array will be deprecated. Use httpServerAdapter option instead:\n' +
' new App({ httpServerAdapter: new ExpressAdapter() })');
this.http = httpPlugin;
// Extract internal server and always set this.server
server = httpPlugin.asServer?.();
if (!server) {
throw new Error('HttpPlugin.asServer() returned undefined');
}
}
else if (this.options.socketMode) {
const built = this.buildSocketMode();
server = built.server;
this.socketMode = built.socketMode;
}
else {
let dangerouslyAllowUnauthenticatedRequests = this.options.dangerouslyAllowUnauthenticatedRequests;
if (dangerouslyAllowUnauthenticatedRequests === undefined && this.options.skipAuth !== undefined) {
this.log.warn('[DEPRECATED] skipAuth is deprecated. Use dangerouslyAllowUnauthenticatedRequests instead.');
dangerouslyAllowUnauthenticatedRequests = this.options.skipAuth;
}
if (dangerouslyAllowUnauthenticatedRequests === undefined) {
const unauthenticatedRequestsEnvValue = (0, env_1.getBooleanEnvValue)('DANGEROUSLY_ALLOW_UNAUTHENTICATED_REQUESTS');
if (unauthenticatedRequestsEnvValue !== undefined) {
this.log.warn('DANGEROUSLY_ALLOW_UNAUTHENTICATED_REQUESTS is set. ' +
'Unauthenticated request behavior is configured by the environment.');
dangerouslyAllowUnauthenticatedRequests = unauthenticatedRequestsEnvValue;
}
}
dangerouslyAllowUnauthenticatedRequests ??= false;
server = new http_server_1.HttpServer(this.options.httpServerAdapter ?? new http_1.ExpressAdapter(undefined, {
logger: this.log,
onError: (err) => this.eventManager.onError({ error: err })
}), {
dangerouslyAllowUnauthenticatedRequests,
logger: this.log,
messagingEndpoint: this.options.messagingEndpoint ?? '/api/messages',
});
}
// Always set this.server
this.server = server;
// Set callback for handling activities
server.onRequest = (event) => this.onActivity(event);
// add injectable items to container
this.container.register('ILogger', { useValue: this.log });
this.container.register('IStorage', { useValue: this.storage });
// Register HTTP server for plugins that need HTTP capabilities
this.container.register('IHttpServer', { useValue: server });
// Register all plugins (including HttpPlugin if using old way)
for (const plugin of plugins) {
this.plugin(plugin);
}
if (this.options.activity?.mentions?.stripText) {
const options = this.options.activity?.mentions?.stripText;
this.use(middleware.stripMentionsText(typeof options === 'boolean' ? {} : options));
}
this.oauthFlowRegistry = new registry_1.OAuthFlowRegistry({
defaultConnectionName: hasConfiguredOAuthFlows
? undefined
: this.oauth.defaultConnectionName,
router: this.router,
client: this.client,
events: this.events,
graphBaseUrl: this.graphBaseUrl,
});
for (const connectionName of this.options.oauthFlows ?? []) {
this.addOAuthFlow(connectionName);
}
this.event('error', ({ error }) => {
this.log.error(error.message);
if (error instanceof axios_1.AxiosError) {
this.log.error(error.request.path);
this.log.error(error.response?.data);
}
});
}
/**
* initialize the app.
*/
async initialize() {
if (this.isInitialized) {
return;
}
// initialize plugins
await this.pluginManager.init();
// initialize server
await this.server.initialize({
credentials: this.credentials,
cloud: this.cloud,
});
this.isInitialized = true;
}
/**
* start the server after initialization
* @param port port to listen on
*/
async start(port) {
this.port = port || process.env.PORT || 3978;
try {
await this.initialize();
// Start plugins
await this.pluginManager.start({ port: this.port });
this.events.emit('start', this.log);
// Start HTTP server
await this.server.start(this.port);
}
catch (error) {
await this.stop();
const reportError = this.eventManager.onError({ error });
if (this.socketMode) {
await reportError;
throw error;
}
}
}
/**
* stop the app
*/
async stop() {
try {
// Stop plugins
await this.pluginManager.stop();
// Stop HTTP server
await this.server.stop();
}
catch (error) {
this.eventManager.onError({ error });
}
}
async send(conversationId, activity, options) {
return this.sendActivity(conversationId, activity, options);
}
// Implementation shared by the three-argument form and the legacy two-argument form.
async reply(conversationId, messageId, activity, options) {
if (typeof messageId === 'string' && activity !== undefined && !isAppSendOptions(activity)) {
if (!conversationId || conversationId.trim() === '') {
throw new Error('conversationId must be a non-empty string');
}
if (messageId.trim() === '') {
throw new Error('messageId must be a non-empty string');
}
return this.sendActivity(conversationId, activity, options, messageId);
}
const opts = activity && isAppSendOptions(activity) ? activity : options;
return this.send(conversationId, messageId, opts);
}
/**
* Create an AgenticIdentity for scoped proactive sends and API clients.
*
* AgenticIdentity is the SDK operation/request scope for Agent 365. This
* helper fills the required blueprint and tenant identifiers from app
* configuration while allowing app/user IDs to be omitted or set to `null`
* when the operation is not scoped to a concrete agentic app or user.
*
* @param options identity fields and optional overrides
*/
getAgenticIdentity(options = {}) {
const tenantId = options.tenantId ?? this.credentials?.tenantId ?? this.options.tenantId;
if (!tenantId) {
throw new Error('tenantId is required to get an AgenticIdentity');
}
const agenticAppBlueprintId = options.agenticAppBlueprintId ?? this.id;
if (!agenticAppBlueprintId) {
throw new Error('agenticAppBlueprintId is required to get an AgenticIdentity');
}
return {
agenticAppBlueprintId,
agenticAppId: options.agenticAppId,
agenticUserId: options.agenticUserId,
tenantId,
};
}
/**
* Registers an OAuth flow for one Bot Framework OAuth connection.
*
* Connection names are matched case-insensitively. Registering the same
* connection more than once throws. The first registration removes
* the implicit legacy default. This method cannot be used when
* `oauth.defaultConnectionName` was configured.
*
* @param connectionName OAuth connection name.
* @param options Optional card defaults for the flow.
* @returns The registered flow so callbacks can be chained.
*/
addOAuthFlow(connectionName, options = {}) {
if (this.options.oauth?.defaultConnectionName !== undefined) {
throw new Error('oauth.defaultConnectionName cannot be combined with registered OAuth flows. ' +
'Remove defaultConnectionName and name the connection when calling OAuth helpers.');
}
const flow = new oauth_1.OAuthFlow(connectionName, options);
this.enableOAuthState();
this.oauthFlowRegistry.add(flow);
return flow;
}
/**
* Gets the OAuth flow for a connection.
*
* The implicit legacy default is available only until the first flow
* is registered.
*
* @param connectionName Connection to resolve.
* @throws When the connection name is blank or no matching flow is registered.
*/
getOAuthFlow(connectionName) {
return this.oauthFlowRegistry.get(connectionName);
}
/**
* subscribe to an event
* @param name event to subscribe to
* @param cb callback to invoke
*/
on(name, cb) {
this.router.on(name, cb);
return this;
}
/**
* subscribe to a message event for a specific pattern
* @param pattern pattern to match against message text
* @param cb callback to invoke
*/
message(pattern, cb) {
this.router.register({
type: 'user',
select: (activity) => {
if (activity.type !== 'message') {
return false;
}
return new RegExp(pattern).test(activity.text);
},
callback: cb,
});
return this;
}
/**
* register a middleware
* @param cb callback to invoke
*/
use(cb) {
this.router.use(cb);
return this;
}
/**
* subscribe to an event
* @param name the event to subscribe to
* @param cb the callback to invoke
*/
event(name, cb) {
this.events.on(name, cb);
return this;
}
/**
* add a plugin
* @param plugin plugin to add
*/
plugin(plugin) {
this.pluginManager.add(plugin);
return this;
}
/**
* get a plugin
*/
getPlugin(name) {
return this.pluginManager.get(name);
}
function(name, cb) {
const log = this.log.child('functions').child(name);
// Create the remote function validator once
const validator = this.entraTokenValidator
? new remote_function_validator_1.RemoteFunctionValidator(this.entraTokenValidator, log)
: null;
this.server.registerRoute('POST', `/api/functions/${name}`, async ({ body, headers }) => {
// Validate JWT token and extract context
if (!validator) {
log.debug('unauthorized - no token validator configured');
return { status: 401, body: 'unauthorized' };
}
const context = await validator.check(headers);
if (!context) {
return { status: 401, body: 'unauthorized' };
}
const ctx = new contexts_1.FunctionContext({
...context,
log,
api: this.api,
appGraph: this.graph,
data: body,
activitySender: this.activitySender,
botId: this.id,
});
const data = await cb(ctx);
return { status: 200, body: data };
});
return this;
}
/**
* add/update a static tab.
* the tab will be hosted at
* `http://localhost:{{PORT}}/tabs/{{name}}` or `https://{{BOT_DOMAIN}}/tabs/{{name}}`
* @remark scopes default to `personal`
* @param name A unique identifier for the entity which the tab displays.
* @param path The path to the web `dist` folder.
*/
tab(name, path) {
this.server.serveStatic(`/tabs/${name}`, path);
return this;
}
/**
* whether any registered route matches the inbound activity
*
* Useful for hosts that embed the app behind their own pipeline (e.g. the
* Microsoft 365 Extension and need to decide whether to hand a turn
* to this app or let it fall through, without running the activity.
* @param activity the inbound activity to test against registered routes
*/
hasMatchingRoute(activity) {
return this.router.select(activity).length > 0;
}
/**
* activity handler called when an inbound activity is received
* @param event the received activity event
*/
process(event) {
return this.activityProcessor.process(event);
}
async onActivity(event) {
this.eventManager.onActivity(event);
return await this.process(event);
}
///
/// Token
///
async getBotToken() {
return await this.tokenProvider.getAppToken();
}
/**
* Acquires a Graph token for an Agentic User, via the federated identity exchange the token manager already performs.
*
* Separate from {@link getAppGraphToken} because the identity differs, not merely the scope: this reads as the agent, so it sees what was shared with the agent rather than everything the app may read.
*/
async getAgenticGraphToken(identity, tenantId) {
if (!identity.agenticAppId || !identity.agenticUserId) {
return null;
}
return await this.tokenProvider.getAgenticUserToken(this.cloud.graphScope, identity.agenticAppId, identity.agenticUserId,
// The identity's own tenant wins when the platform sends one, then the tenant the activity arrived from.
// The fallback to the app's configured tenant is deliberately not repeated here: `TokenManager.resolveAgenticTenantId` already applies it, and throws when neither is available, which is a better failure than silently acquiring in the wrong directory.
identity.tenantId || tenantId);
}
async getAppGraphToken(tenantId) {
// Graph falls back to the `common` tenant rather than the cloud's login
// tenant, so the tenant is resolved here instead of letting the provider
// apply its own default.
return await this.tokenProvider.getAppToken(this.cloud.graphScope, tenantId || this.credentials?.tenantId || token_manager_1.DEFAULT_TENANT_FOR_GRAPH_TOKEN);
}
/**
* Whether deprecated context OAuth fields require an eager token lookup.
*
* Registered flows never enable this behavior. An explicit legacy
* `oauth.fetchUserToken` wins; otherwise lookup is enabled only when the
* legacy default connection was explicitly configured.
*
* @deprecated Registered flows fetch tokens only through `OAuthFlow` methods.
*/
shouldFetchUserToken() {
const explicit = this.options.oauth?.fetchUserToken;
if (explicit !== undefined) {
return explicit;
}
return this.options.oauth?.defaultConnectionName !== undefined;
}
async sendActivity(conversationId, activity, options, replyChainId) {
if (!this.id) {
throw new Error('App has no credentials set up');
}
const params = (0, teams_api_1.toActivityParams)(activity);
const ref = {
channelId: 'msteams',
serviceUrl: this.api.serviceUrl,
bot: {
id: this.id,
role: 'bot',
},
conversation: {
id: conversationId,
},
};
const senderOptions = options?.agenticIdentity || replyChainId
? { agenticIdentity: options?.agenticIdentity, replyChainId }
: undefined;
return this.activitySender.send(params, ref, senderOptions);
}
/**
* Build the Socket Mode inbound transport and the {@link HttpServer} that runs
* it. The {@link SocketModeAdapter} is constructed internally so it can reuse
* the app's credentials, and token provider.
*
* Socket Mode is the server's only adapter. A supplied `httpServerAdapter` is
* intentionally unused, and no HTTP listener or route is created.
*/
buildSocketMode() {
if (this.cloud.tokenIssuer !== teams_api_1.PUBLIC.tokenIssuer) {
throw new Error(`Socket Mode is not supported in this cloud environment (tokenIssuer=${this.cloud.tokenIssuer}). ` +
'Socket Mode currently supports only regular production clouds. ' +
'Use the HTTP inbound transport instead.');
}
const options = this.options.socketMode === true ? {} : this.options.socketMode;
const messagingEndpoint = this.options.messagingEndpoint ?? '/api/messages';
const socketAdapter = new socket_mode_1.SocketModeAdapter(options, {
credentials: this.credentials,
client: this.client,
tokenProvider: this.tokenProvider,
processActivity: (event) => this.onActivity(event),
messagingEndpoint,
onError: (err) => this.eventManager.onError({ error: err }),
logger: this.log,
});
const server = new http_server_1.HttpServer(socketAdapter, {
logger: this.log,
messagingEndpoint,
});
return { server, socketMode: socketAdapter };
}
enableOAuthState() {
if (this.options.state === false || this.stateLoader) {
return;
}
this.stateLoader = (0, loader_1.createOAuthStateLoader)(this.log);
}
}
exports.App = App;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBwLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2FwcC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSxpQ0FBbUM7QUFFbkMsb0RBYThCO0FBQzlCLDBEQVFpQztBQUVqQyxtRUFBa0M7QUFFbEMsdURBQW1EO0FBQ25ELCtCQUErQztBQUMvQyw2Q0FBNEM7QUFjNUMsK0NBQThDO0FBQzlDLCtDQUFrRDtBQUNsRCwyQ0FBd0M7QUFDeEMseUNBQWlGO0FBRWpGLGlDQUF3QztBQUN4QyxvREFBZ0Q7QUFDaEQseURBQTJDO0FBQzNDLDJGQUFzRjtBQUN0RixtQ0FBNEQ7QUFFNUQsK0NBQXFEO0FBRXJELHFDQUFrQztBQUVsQywrQ0FBcUU7QUFDckUsbUNBQTZEO0FBQzdELDJDQUF3RDtBQUN4RCxtREFBK0U7QUFDL0UscURBQXVFO0FBR3ZFLHFDQUFpRDtBQUVqRCxTQUFTLGdCQUFnQixDQUFDLEtBQThEO0lBQ3RGLElBQUksT0FBTyxLQUFLLEtBQUssUUFBUTtRQUFFLE9BQU8sS0FBSyxDQUFDO0lBQzVDLE9BQU8sQ0FBQyxDQUFDLE1BQU0sSUFBSSxLQUFLLENBQUMsQ0FBQztBQUM1QixDQUFDO0FBRUQ7O0dBRUc7QUFDSCxNQUFhLEdBQUc7SUEyRk87SUExRlosR0FBRyxDQUFZO0lBQ2YsS0FBSyxDQUFtQjtJQUN4QixLQUFLLENBQWM7SUFDbkIsR0FBRyxDQUFVO0lBQ2IsTUFBTSxDQUFhO0lBRTVCOzs7Ozs7Ozs7T0FTRztJQUNNLFVBQVUsQ0FBcUI7SUFDL0IsSUFBSSxDQUFjO0lBQ2xCLE1BQU0sQ0FBYTtJQUM1Qjs7Ozs7T0FLRztJQUNNLE9BQU8sQ0FBVztJQUNsQixtQkFBbUIsQ0FBMkI7SUFFdkQ7Ozs7O09BS0c7SUFDTSxZQUFZLENBQVU7SUFFL0I7O09BRUc7SUFDSCxJQUFJLFdBQVc7UUFDYixPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsV0FB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