From a6acd7d3b6f09f7610b94adb62db54b4c0ad4731 Mon Sep 17 00:00:00 2001 From: William Wong Date: Fri, 19 Jun 2026 01:12:18 +0000 Subject: [PATCH 1/3] Remove cross-fetch --- CHANGELOG.md | 13 +++++++ package-lock.json | 51 --------------------------- package.json | 1 - src/directLineStreaming.leaks.test.ts | 28 +++++++-------- src/directLineStreaming.ts | 1 - 5 files changed, 26 insertions(+), 68 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 08ead7f6..c3c8b707 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,8 +14,21 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Fix [#XXX](https://github.com/microsoft/BotFramework-DirectLineJS/issues/XXX). Patched something, by [@johndoe](https://github.com/johndoe) in PR [#XXX](https://github.com/microsoft/BotFramework-DirectLineJS/pull/XXX) --> +| Icon | Description | +| ---- | ------------------------------------------------- | +| 💢 | Breaking changes | +| 👷🏻 | Development experience (non-production impacting) | + ## [Unreleased] +### Changed + +- 👷🏻 Bumped GitHub Actions in CI/CD workflows, by [@orgads](https://github.com/orgads), in PR [#453](https://github.com/microsoft/BotFramework-DirectLineJS/pull/453) + +### Removed + +- 💢 Removed `fetch` polyfill `cross-fetch`, by [@orgads](https://github.com/orgads) and [@compulim](https://github.com/compulim), in PR [#456](https://github.com/microsoft/BotFramework-DirectLineJS/pull/456) and [#XXX](https://github.com/microsoft/BotFramework-DirectLineJS/pull/XXX) + ### Fixed - Fixed resource leaks in DirectLineStreaming after end() is called, by [@orgads](https://github.com/orgads), in PR [#452](https://github.com/microsoft/BotFramework-DirectLineJS/pull/452) diff --git a/package-lock.json b/package-lock.json index b17e09db..86cebc5d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,7 +13,6 @@ "botframework-streaming": "^4.23.3", "buffer": "6.0.3", "core-js": "^3.49.0", - "cross-fetch": "^3.1.5", "jwt-decode": "3.1.2", "rxjs": "5.5.12", "url-search-params-polyfill": "^8.2.5" @@ -4797,56 +4796,6 @@ "url": "https://opencollective.com/core-js" } }, - "node_modules/cross-fetch": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz", - "integrity": "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==", - "dependencies": { - "node-fetch": "2.6.7" - } - }, - "node_modules/cross-fetch/node_modules/node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", - "license": "MIT", - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, - "node_modules/cross-fetch/node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "license": "MIT" - }, - "node_modules/cross-fetch/node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", - "license": "BSD-2-Clause" - }, - "node_modules/cross-fetch/node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "license": "MIT", - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, "node_modules/cross-spawn": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", diff --git a/package.json b/package.json index 579ecac5..11929f01 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,6 @@ "botframework-streaming": "^4.23.3", "buffer": "6.0.3", "core-js": "^3.49.0", - "cross-fetch": "^3.1.5", "jwt-decode": "3.1.2", "rxjs": "5.5.12", "url-search-params-polyfill": "^8.2.5" diff --git a/src/directLineStreaming.leaks.test.ts b/src/directLineStreaming.leaks.test.ts index 738dbbe2..4ab5a3fc 100644 --- a/src/directLineStreaming.leaks.test.ts +++ b/src/directLineStreaming.leaks.test.ts @@ -1,3 +1,5 @@ +/// + /** * Tests for leak fixes in DirectLineStreaming after end() is called. * @@ -42,8 +44,7 @@ class MockWebSocketClient { statusCode: 200, streams: [ { - readAsString: async () => - JSON.stringify({ conversationId: 'conv-123' }) + readAsString: async () => JSON.stringify({ conversationId: 'conv-123' }) } ] })); @@ -74,16 +75,10 @@ jest.mock('./streaming/WebSocketClientWithNetworkInformation', () => ({ // Mock cross-fetch to prevent real network calls. // jest.mock is hoisted, so we use jest.fn() inline and retrieve it later. -jest.mock('cross-fetch', () => ({ - __esModule: true, - default: jest.fn() -})); +const mockFetch = jest.spyOn(globalThis, 'fetch').mockImplementation(); // Import after mocks. import { DirectLineStreaming } from './directLineStreaming'; -import _mockFetchImport from 'cross-fetch'; - -const mockFetch = _mockFetchImport as unknown as jest.Mock; beforeEach(() => { jest.useFakeTimers({ now: 0 }); @@ -94,7 +89,8 @@ beforeEach(() => { mockFetch.mockResolvedValue({ ok: true, json: async () => ({ token: 'new-token' }) - }); + // We only look for result we want. + } as Response); }); afterEach(() => { @@ -167,8 +163,9 @@ describe('refreshToken() abort checks', () => { // No refresh fetch yet (haven't advanced 15 minutes). const fetchCalls = mockFetch.mock.calls.filter( - ([url]: [string]) => typeof url === 'string' && url.includes('/tokens/refresh') + ([url]) => typeof url === 'string' && url.includes('/tokens/refresh') ); + expect(fetchCalls).toHaveLength(0); // Call end(). @@ -180,7 +177,7 @@ describe('refreshToken() abort checks', () => { // There should be no refresh calls. const refreshCallsAfterEnd = mockFetch.mock.calls.filter( - ([url]: [string]) => typeof url === 'string' && url.includes('/tokens/refresh') + ([url]) => typeof url === 'string' && url.includes('/tokens/refresh') ); expect(refreshCallsAfterEnd).toHaveLength(0); }); @@ -201,7 +198,7 @@ describe('refreshToken() abort checks', () => { // No token refresh should have been attempted. const refreshCalls = mockFetch.mock.calls.filter( - ([url]: [string]) => typeof url === 'string' && url.includes('/tokens/refresh') + ([url]) => typeof url === 'string' && url.includes('/tokens/refresh') ); expect(refreshCalls).toHaveLength(0); }); @@ -220,7 +217,8 @@ describe('refreshToken() on fatal 403', () => { status: 403, statusText: 'Forbidden', json: async () => ({}) - }); + // We only look for result we want. + } as Response); // Advance through the first refresh interval. await jest.advanceTimersByTimeAsync(15 * 60 * 1000); @@ -228,7 +226,7 @@ describe('refreshToken() on fatal 403', () => { // The first refresh attempt should have been made and returned 403. const refreshCalls = mockFetch.mock.calls.filter( - ([url]: [string]) => typeof url === 'string' && url.includes('/tokens/refresh') + ([url]) => typeof url === 'string' && url.includes('/tokens/refresh') ); expect(refreshCalls.length).toBeGreaterThanOrEqual(1); diff --git a/src/directLineStreaming.ts b/src/directLineStreaming.ts index 2134ba49..5e78a502 100644 --- a/src/directLineStreaming.ts +++ b/src/directLineStreaming.ts @@ -6,7 +6,6 @@ import { Observable } from 'rxjs/Observable'; import { Subscriber } from 'rxjs/Subscriber'; import * as BFSE from 'botframework-streaming'; import createDeferred from './createDeferred'; -import fetch from 'cross-fetch'; import { Activity, ConnectionStatus, Conversation, DirectLine, IBotConnection, Media, Message } from './directLine'; import WebSocketClientWithNetworkInformation from './streaming/WebSocketClientWithNetworkInformation'; From a4937195ebf2355306fce5837fb88953393ff4fb Mon Sep 17 00:00:00 2001 From: William Wong Date: Fri, 19 Jun 2026 01:13:26 +0000 Subject: [PATCH 2/3] Add entries --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c3c8b707..f944301d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -39,7 +39,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Migrated from obsoleted dependencies, by [@compulim](https://github.com/compulim), in PR [#457](https://github.com/microsoft/BotFramework-DirectLineJS/pull/457) - Migrated from `restify` to `express` + - Credits to [@orgads](https://github.com/orgads) in PR [#454](https://github.com/microsoft/BotFramework-DirectLineJS/pull/454) - Migrated from `p-defer` to `Promise.withResolvers()` + - Credits to [@orgads](https://github.com/orgads) in PR [#455](https://github.com/microsoft/BotFramework-DirectLineJS/pull/455) - Bumped dependencies, by [@compulim](https://github.com/compulim), in PR [#457](https://github.com/microsoft/BotFramework-DirectLineJS/pull/457) - Production dependencies - [`@babel/runtime@7.29.7`](https://npmjs.com/package/@babel/runtime/v/7.29.7) From 72c1fe52bff1c1bbff851197e6398f45c97afcd1 Mon Sep 17 00:00:00 2001 From: William Wong Date: Fri, 19 Jun 2026 01:15:24 +0000 Subject: [PATCH 3/3] Update PR number --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f944301d..683c1aa2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,7 +27,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ### Removed -- 💢 Removed `fetch` polyfill `cross-fetch`, by [@orgads](https://github.com/orgads) and [@compulim](https://github.com/compulim), in PR [#456](https://github.com/microsoft/BotFramework-DirectLineJS/pull/456) and [#XXX](https://github.com/microsoft/BotFramework-DirectLineJS/pull/XXX) +- 💢 Removed `fetch` polyfill `cross-fetch`, by [@orgads](https://github.com/orgads) and [@compulim](https://github.com/compulim), in PR [#456](https://github.com/microsoft/BotFramework-DirectLineJS/pull/456) and [#460](https://github.com/microsoft/BotFramework-DirectLineJS/pull/460) ### Fixed