Skip to content

Upgrade to express v5#442

Merged
corinagum merged 2 commits into
httpAdapterfrom
updateExpress
Feb 12, 2026
Merged

Upgrade to express v5#442
corinagum merged 2 commits into
httpAdapterfrom
updateExpress

Conversation

@heyitsaamir

@heyitsaamir heyitsaamir commented Jan 24, 2026

Copy link
Copy Markdown
Collaborator

This PR upgrades our systems from express v4 to express v5.
The changes applicable to us are fairly minimal

PR Dependency Tree

This tree was auto-generated by Charcoal

@corinagum
corinagum merged commit 8fa68c8 into httpAdapter Feb 12, 2026
6 checks passed
@corinagum
corinagum deleted the updateExpress branch February 12, 2026 20:18
heyitsaamir added a commit that referenced this pull request Mar 11, 2026
This PR upgrades our systems from express v4 to express v5.
The changes applicable to us are fairly minimal



#### PR Dependency Tree


* **PR #424**
  * **PR #433**
    * **PR #442** 👈

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)
heyitsaamir added a commit that referenced this pull request Mar 12, 2026
This PR upgrades our systems from express v4 to express v5.
The changes applicable to us are fairly minimal



#### PR Dependency Tree


* **PR #424**
  * **PR #433**
    * **PR #442** 👈

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)
heyitsaamir added a commit that referenced this pull request Mar 12, 2026
This PR upgrades our systems from express v4 to express v5.
The changes applicable to us are fairly minimal



#### PR Dependency Tree


* **PR #424**
  * **PR #433**
    * **PR #442** 👈

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)
heyitsaamir added a commit that referenced this pull request Mar 13, 2026
This PR upgrades our systems from express v4 to express v5.
The changes applicable to us are fairly minimal



#### PR Dependency Tree


* **PR #424**
  * **PR #433**
    * **PR #442** 👈

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)
heyitsaamir added a commit that referenced this pull request Mar 13, 2026
This PR upgrades our systems from express v4 to express v5.
The changes applicable to us are fairly minimal



#### PR Dependency Tree


* **PR #424**
  * **PR #433**
    * **PR #442** 👈

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)
heyitsaamir added a commit that referenced this pull request Mar 13, 2026
This PR upgrades our systems from express v4 to express v5.
The changes applicable to us are fairly minimal



#### PR Dependency Tree


* **PR #424**
  * **PR #433**
    * **PR #442** 👈

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)
heyitsaamir added a commit that referenced this pull request Mar 13, 2026
This PR upgrades our systems from express v4 to express v5.
The changes applicable to us are fairly minimal



#### PR Dependency Tree


* **PR #424**
  * **PR #433**
    * **PR #442** 👈

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)
heyitsaamir added a commit that referenced this pull request Mar 13, 2026
This PR upgrades our systems from express v4 to express v5.
The changes applicable to us are fairly minimal



#### PR Dependency Tree


* **PR #424**
  * **PR #433**
    * **PR #442** 👈

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)
heyitsaamir added a commit that referenced this pull request Mar 13, 2026
This PR upgrades our systems from express v4 to express v5.
The changes applicable to us are fairly minimal

* **PR #424**
  * **PR #433**
    * **PR #442** 👈

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)
heyitsaamir added a commit that referenced this pull request Mar 13, 2026
This PR upgrades our systems from express v4 to express v5.
The changes applicable to us are fairly minimal

* **PR #424**
  * **PR #433**
    * **PR #442** 👈

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)
heyitsaamir added a commit that referenced this pull request Mar 16, 2026
This PR upgrades our systems from express v4 to express v5.
The changes applicable to us are fairly minimal

* **PR #424**
  * **PR #433**
    * **PR #442** 👈

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)
heyitsaamir added a commit that referenced this pull request Mar 16, 2026
In this PR, we introduce a new object called HttpServer and begin to
deprecate HttpPlugin.

## Main changes
1. Create `HttpServer` internal class. It accepts an
`IHttpServerAdapter` which is the server implementation.
2. Pulled out the express implementation as an `IHttpServerAdapter`
3. Deprecated HttpPlugin, and made it use HttpServer + ExpressAdapter.
4. Changed BotBuilder/A2A/Mcp plugins to depend on HttpServer vs.
HttpPlugin.
5. Added examples to show how powerful IHttpServerAdapter can be with
different types of servers (hono, fastify).
6. Minor refactor of the jwt middleware such that we can reuse it in
HttpServer and app.embed.

## Why:
HTTP is a core part of our sdk. Our App object uses HTTP to set up a
server, perform auth validations, and pipe the request to the handlers
that are attached, and then return the response. Key part is that Http
is a *core* part of App, not a plugin, since core functionality is
dependent on it.
Even inside the App object, we were doing special casing for this
Http"Plugin" whereas it should never have really been a plugin to begin
with. By making it a plugin, we were exposing many non-plugin essential
things to the plugin system in general.

So what should it have been? Well, HTTP Plugin had these
responsibilities
1. Set up the express server
2. Perform validations if credentials were present
3. Pass the incoming request to App
4. Once App handlers have had a chance to process this incoming request,
pass the response back to the server.

So, we introduce a new object called `HttpServer` whose responsibilities
are essentially that ^. This object is not a plugin, but an object
that's created by App itself.

## Customization

Now this idealogical shift doesn't really warrant us doing this
refactor, but we started seeing requests from folks who wanted to hook
Teams functionality into existing servers, or replace the underlying
server infra with a non-express server. Our recommendation was to
rebuild a new HttpPlugin. But rebuilding this plugin is not simple
(since we don't really document it anywhere, and didn't expect folks to
build their own).
So `HttpServer` exposes an `IHttpServerAdapter` concept. To build the
adapter, one simply needs to build out a handler for extracting request
data, and a handler for responses. This means that you can build simple
custom adapters for your own _existing_ servers. (And if you don't pass
one in, we'll build a default express one.) Examples of servers are in
the http-adapters folder under examples/.

## Adapter Interface

The `IHttpServerAdapter` interface adapters need to implement:

```typescript
interface IHttpServerAdapter {
  registerRoute(method: HttpMethod, path: string, handler: HttpRouteHandler): void;
  serveStatic?(path: string, directory: string): void;
  start?(port: number): Promise<void>;
  stop?(): Promise<void>;
}
```

Handlers are pure functions — `({ body, headers }) → { status, body }`.
No framework-specific request/response objects leak through the
abstraction.

### Why `registerRoute`?

Some adapter patterns have the adapter own routing internally and just
receive a single callback. But our SDK creates routes dynamically —
`app.function('myFunc')` registers `/api/functions/myFunc` at runtime,
in addition to the core `/api/messages` endpoint. The adapter needs a
`registerRoute` method so that both `HttpServer` and `app.function()`
can tell it what paths to listen on.

### Optional methods

`start`/`stop` are optional — serverless adapters (Vercel, Lambda) don't
need them. `serveStatic` is optional — only needed for tab hosting.

`HttpMethod` is currently just `'POST'` (the only method the Teams
protocol uses). It may expand to a union if needed.

## Backward Compat

We've updated `HttpPlugin` to basically use `HttpServer` with an
`ExpressAdapter` internally for backward compat. I don't think this
should lead to any breaking changes (even if someone passes in their own
`HttpPlugin`). (Tested BotBuilderPlugin, from examples, and it worked
without any changes).
However, it should be noted that I marked HttpPlugin as deprecated in
this PR, so it should be discouraged going forward, and after the next
few versions, it'll be removed.

## Testing

I tested by running the following examples:

1. Echo bot
2. Devtools
3. BotBuilder
4. HttpPlugin
5. Tabs
6. AI (streaming and regular completions)



skip-test-verification (added manifest for tabs)



#### PR Dependency Tree


* **PR #424**
  * **PR #433** 👈
    * **PR #442**


#### PR Dependency Tree


* **PR #424**
  * **PR #433** 👈

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)

---------

Co-authored-by: Claude Opus 4.6 <[email protected]>
corinagum added a commit that referenced this pull request May 27, 2026
## Summary

Brings `origin/main` into `release` for the **2.0.12** release. **No
carve-outs this time** — Quoted Replies is included.

`version.json`: `2.0.12-preview.{height}` → `2.0.12`.

Aligns with teams.py 2.0.12 (PR #442 already on PyPI / pending publish).

## What's in this release (delta from 2.0.11)

**Features**
- Quoted Replies + new quotes features — previously held back via the
2.0.11 carve-out (#576)
- SuggestedActionSubmitActivity for `suggestedAction/submit` invoke
(#591)
- Default targeted replies for targeted inbound messages (#592)
- Filter colliding keys before `Object.assign` in `ActivityContext`
(#596)
- Prompt Preview support (#536)
- A2A sample (#584)
- AI/MCPClient (#572)
- Allow passing custom HTTP client via `AppOptions`-equivalent
- Reactions API marked GA (#575), Rename `ReactionClient.remove()` →
`delete()` (#567)

**Security & fixes**
- Security hardening: tighten cross-origin policies (#595)
- Lock JsonWebToken trust-boundary contract (#586)
- `fix(deps)`: npm audit fix — clears all high-severity advisories
(#599)
- `fix(apps)`: log inbound activities at info, warn on missing
Authorization (#568)
- `fix`: App user-agent merging (#573)
- `fix`: Add null checks in `local-memory.ts` to prevent role crash
(#438)
- `fix`: `@microsoft/teams.client` import error in webpack 5 (#566)
- Switch to named imports without subpaths (#561)

**Deprecations / package changes**
- Deprecate `DevtoolsPlugin` in favor of Microsoft 365 Agents Playground
(#593)
- Remove in-repo Teams CLI package (#580) — moved to
`teams-sdk/packages/cli`
- Deprecate AI Libraries (#588)
- Correct imports + return types in misc. packages (#589)

**Dependency bumps**
- turbo 2.8.11 → 2.9.14 (#587)
- qs 6.15.0 → 6.15.2 (#594)
- hono 4.12.14 → 4.12.16 (#562)
- npm audit fix bundle (#599): axios 1.13.5 → 1.16.1, fast-uri 3.1.0 →
3.1.2, ws 8.19.0 → 8.21.0, @azure/msal-node hoisted 5.2.2, uuid 11.1.0 →
11.1.1, @azure/identity 4.13.0 → 4.13.1, express-rate-limit, ip-address,
brace-expansion, etc.

## Quoted Replies inclusion notes

- Teams client rendering is in-sync with the wire format as of
2026-05-06.
- APX QR rollout completed: Public 2026-04-10, GCCH/DoD/Gallatin
2026-04-14.
- No SDK-side carve-outs needed; this matches the teams.py 2.0.12 (PR
#442) decision.

## Branch structure note

`prep-release/2.0.12` is reset to `origin/main` + a one-line
`version.json` bump. Diff against `release` (this PR) shows the full
delta from 2.0.11. We deliberately did not use a 2-parent merge commit —
the auto-merge tried to interleave non-overlapping hunks from main's QR
additions with release's QR carve-outs in `activity.ts`, producing a
semantically broken file. Reset-to-main + version bump is the clean way
to express "release should equal main."

## Test plan

- [x] `npm install` clean (post-audit-fix lockfile)
- [x] `npm run build` — 33/33 targets clean
- [x] `npm test` — 14/14 task targets, 279+ tests pass
- [x] E2E echo bot smoke test against `cg-test-bot-py` via canary ABS —
done on `cg/audit-deps-ts` (now merged); covers axios + msal-node code
paths
- [ ] Pipeline Build + Test stages green on `release` after merge
- [ ] Publish pipeline run with **Public** → ESRP → npm
`@microsoft/teams.*@2.0.12`
- [ ] Smoke install: `npm view @microsoft/teams[email protected]` after
publish
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants