UNPKG

@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

141 lines • 10.1 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.ExpressAdapter = void 0; const http_1 = __importDefault(require("http")); const express_1 = __importDefault(require("express")); const teams_common_1 = require("@microsoft/teams.common"); /** * Express adapter for HttpServer * * Handles Express-specific HTTP framework concerns: * - Express app creation and middleware setup * - Route registration via Express routing * - Request/response data extraction and sending * - Server lifecycle management */ class ExpressAdapter { // Expose Express methods for backwards compatibility get; post; patch; put; delete; route; use; express; server; logger; onError; constructor(serverOrApp, options) { if (serverOrApp instanceof http_1.default.Server) { // The adapter handles all requests on this server. Use the adapter's // methods (get, post, use, etc.) to add routes. If you need your own // Express app, pass it in instead and manage the server yourself. this.express = (0, express_1.default)(); this.server = serverOrApp; this.server.on('request', this.express); } else if (typeof serverOrApp === 'function') { this.express = serverOrApp; } else { this.express = (0, express_1.default)(); this.server = http_1.default.createServer(this.express); } this.logger = options?.logger ?? new teams_common_1.ConsoleLogger('ExpressAdapter'); this.onError = options?.onError; // Bind Express methods this.get = this.express.get.bind(this.express); this.post = this.express.post.bind(this.express); this.patch = this.express.patch.bind(this.express); this.put = this.express.put.bind(this.express); this.delete = this.express.delete.bind(this.express); this.route = this.express.route.bind(this.express); this.use = this.express.use.bind(this.express); } /** * Register a route handler for a given HTTP method and path */ registerRoute(method, path, handler) { if (method !== 'POST') { throw new Error(`Unsupported HTTP method: ${method}`); } const expressHandler = async (req, res, next) => { try { const response = await handler({ body: req.body, headers: req.headers }); res.status(response.status).send(response.body); } catch (err) { next(err); } }; this.express.post(path, express_1.default.json(), expressHandler); } /** * Start the server listening on the specified port */ async start(port) { const server = this.server; if (!server) { throw new Error('Cannot start: server lifecycle is managed externally. Call listen() on your Express app or http.Server directly.'); } return new Promise((resolve, reject) => { // Handle startup errors server.once('error', (err) => { if (this.onError) { this.onError(err); } reject(err); }); server.listen(port, () => { this.logger.info(`listening on port ${port} 🚀`); // Set up persistent error listener after startup if (this.onError) { server.on('error', this.onError); } resolve(); }); }); } /** * Serve static files from a directory. * * No CORS headers are set: Teams loads tab content inside an iframe (subject * to the page's CSP `frame-ancestors` directive), not via cross-origin * `fetch`/XHR, so a wildcard `Access-Control-Allow-Origin` was permissive * without a corresponding use case. Callers that need cross-origin reads of * the served assets should layer their own CORS middleware at the consuming * route. */ serveStatic(path, directory) { this.express.use(path, express_1.default.static(directory)); } /** * Stop the server and close all connections */ async stop() { const server = this.server; if (!server) { throw new Error('Cannot stop: server lifecycle is managed externally. Call close() on your Express app or http.Server directly.'); } return new Promise((resolve, reject) => { server.close((err) => { if (err) { reject(err); } else { this.logger.info('server stopped'); resolve(); } }); }); } } exports.ExpressAdapter = ExpressAdapter; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXhwcmVzcy1hZGFwdGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2h0dHAvZXhwcmVzcy1hZGFwdGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBLGdEQUF3QjtBQUV4QixzREFBOEI7QUFFOUIsMERBQWlFO0FBSWpFOzs7Ozs7OztHQVFHO0FBQ0gsTUFBYSxjQUFjO0lBQ3pCLHFEQUFxRDtJQUM1QyxHQUFHLENBQTZCO0lBQ2hDLElBQUksQ0FBOEI7SUFDbEMsS0FBSyxDQUErQjtJQUNwQyxHQUFHLENBQTZCO0lBQ2hDLE1BQU0sQ0FBZ0M7SUFDdEMsS0FBSyxDQUErQjtJQUNwQyxHQUFHLENBQTZCO0lBRS9CLE9BQU8sQ0FBc0I7SUFDN0IsTUFBTSxDQUFlO0lBQ3JCLE1BQU0sQ0FBVTtJQUNoQixPQUFPLENBQXdCO0lBRXpDLFlBQVksV0FBK0MsRUFBRSxPQUE4RDtRQUN6SCxJQUFJLFdBQVcsWUFBWSxjQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDdkMscUVBQXFFO1lBQ3JFLHFFQUFxRTtZQUNyRSxrRUFBa0U7WUFDbEUsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFBLGlCQUFPLEdBQUUsQ0FBQztZQUN6QixJQUFJLENBQUMsTUFBTSxHQUFHLFdBQVcsQ0FBQztZQUMxQixJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxTQUFTLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQzFDLENBQUM7YUFBTSxJQUFJLE9BQU8sV0FBVyxLQUFLLFVBQVUsRUFBRSxDQUFDO1lBQzdDLElBQUksQ0FBQyxPQUFPLEdBQUcsV0FBVyxDQUFDO1FBQzdCLENBQUM7YUFBTSxDQUFDO1lBQ04sSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFBLGlCQUFPLEdBQUUsQ0FBQztZQUN6QixJQUFJLENBQUMsTUFBTSxHQUFHLGNBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ2hE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