diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d8334f5ff3..700b5681ff 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -26,7 +26,7 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: - node-version: 18.14.0 + node-version: 18.17.0 - uses: actions/cache@v4 with: path: | @@ -135,7 +135,7 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: - node-version: 18.14.0 + node-version: 18.17.0 - name: Restore dependencies from cache uses: actions/cache/restore@v4 with: @@ -177,7 +177,7 @@ jobs: persist-credentials: false # GITHUB_TOKEN must not be set for the semantic release - uses: actions/setup-node@v4 with: - node-version: 18.14.0 + node-version: 18.17.0 - name: Restore dependencies from cache uses: actions/cache/restore@v4 with: diff --git a/global.d.ts b/global.d.ts index d2e9294d20..b6f0171df2 100644 --- a/global.d.ts +++ b/global.d.ts @@ -1,4 +1,3 @@ /// declare module 'forest-ip-utils'; -declare module 'eventsource'; diff --git a/packages/forestadmin-client/package.json b/packages/forestadmin-client/package.json index 39e21a799a..2e1be60d4c 100644 --- a/packages/forestadmin-client/package.json +++ b/packages/forestadmin-client/package.json @@ -12,12 +12,13 @@ "directory": "packages/forestadmin-client" }, "dependencies": { - "eventsource": "2.0.2", + "eventsource": "3.0.1", "json-api-serializer": "^2.6.6", "jsonwebtoken": "^9.0.0", "object-hash": "^3.0.0", "openid-client": "^5.6.4", - "superagent": "^8.0.6" + "superagent": "^8.0.6", + "undici": "^6.0.0" }, "files": [ "dist/**/*.js", @@ -36,4 +37,4 @@ "@types/jsonwebtoken": "^9.0.1", "@types/superagent": "^4.1.16" } -} +} \ No newline at end of file diff --git a/packages/forestadmin-client/src/events-subscription/index.ts b/packages/forestadmin-client/src/events-subscription/index.ts index e8e1484c30..da013e70e0 100644 --- a/packages/forestadmin-client/src/events-subscription/index.ts +++ b/packages/forestadmin-client/src/events-subscription/index.ts @@ -1,4 +1,5 @@ -import EventSource from 'eventsource'; +import { EventSource } from 'eventsource'; +import { Agent, fetch } from 'undici'; import { BaseEventsSubscriptionService, @@ -30,24 +31,27 @@ export default class EventsSubscriptionService implements BaseEventsSubscription const eventSourceConfig = { // forest-secret-key act as the credential withCredentials: false, - headers: { 'forest-secret-key': this.options.envSecret }, - https: { - rejectUnauthorized: process.env.NODE_TLS_REJECT_UNAUTHORIZED !== '0', - }, + fetch: (input, init) => + fetch(input, { + ...init, + headers: { ...init.headers, 'forest-secret-key': this.options.envSecret }, + dispatcher: new Agent({ + connect: { + rejectUnauthorized: false, + }, + }), + }), }; const url = new URL('/liana/v4/subscribe-to-events', this.options.forestServerUrl).toString(); const eventSource = new EventSource(url, eventSourceConfig); // Override reconnect interval to 5 seconds - eventSource.reconnectInterval = 5000; + // eventSource.reconnectInterval = 5000; eventSource.addEventListener('error', this.onEventError.bind(this)); // Only listen after first open - eventSource.once('open', () => - eventSource.addEventListener('open', () => this.onEventOpenAgain()), - ); - + eventSource.addEventListener('open', () => this.onEventOpenAgain()); eventSource.addEventListener(ServerEventType.RefreshUsers, async () => this.refreshEventsHandlerService.refreshUsers(), ); diff --git a/packages/forestadmin-client/test/events-subscription/index.test.ts b/packages/forestadmin-client/test/events-subscription/index.test.ts index 1ca0ea51e3..f89b3ad07f 100644 --- a/packages/forestadmin-client/test/events-subscription/index.test.ts +++ b/packages/forestadmin-client/test/events-subscription/index.test.ts @@ -7,17 +7,12 @@ const addEventListener = jest.fn((event, callback) => { events[event] = callback; }); -const once = jest.fn((event, callback) => { - events[event] = callback; -}); - const close = jest.fn(); jest.mock('eventsource', () => ({ __esModule: true, - default: jest.fn().mockImplementation(() => ({ + EventSource: jest.fn().mockImplementation(() => ({ addEventListener, - once, close, })), })); @@ -35,7 +30,6 @@ describe('EventsSubscriptionService', () => { eventsSubscriptionService.subscribeEvents(); expect(addEventListener).toHaveBeenCalledWith('error', expect.any(Function)); - expect(once).toHaveBeenCalledWith('open', expect.any(Function)); expect(addEventListener).toHaveBeenCalledWith( ServerEventType.RefreshUsers, @@ -191,22 +185,6 @@ describe('EventsSubscriptionService', () => { }); describe('onEventOpenAgain', () => { - test('should add new open listener on first open event', () => { - const eventsSubscriptionService = new EventsSubscriptionService( - options, - refreshEventsHandlerService, - ); - - eventsSubscriptionService.subscribeEvents(); - - // eslint-disable-next-line @typescript-eslint/dot-notation - events['open'](); - - expect(addEventListener).toHaveBeenCalledWith('open', expect.any(Function)); - - expect(refreshEventsHandlerService.refreshEverything).not.toHaveBeenCalled(); - }); - test('should refreshEverything using refreshEventsHandlerService on re-open', () => { const eventsSubscriptionService = new EventsSubscriptionService( options, diff --git a/packages/forestadmin-client/test/events-subscription/native-refresh-events-handler-service.test.ts b/packages/forestadmin-client/test/events-subscription/native-refresh-events-handler-service.test.ts index fcc8d558c3..8e76f20194 100644 --- a/packages/forestadmin-client/test/events-subscription/native-refresh-events-handler-service.test.ts +++ b/packages/forestadmin-client/test/events-subscription/native-refresh-events-handler-service.test.ts @@ -8,7 +8,7 @@ const addEventListener = jest.fn((event, callback) => { jest.mock('eventsource', () => ({ __esModule: true, - default: jest.fn().mockImplementation(() => ({ + EventSource: jest.fn().mockImplementation(() => ({ addEventListener, })), })); diff --git a/yarn.lock b/yarn.lock index 29359ee915..26951febd0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7177,10 +7177,17 @@ events@^3.0.0, events@^3.3.0: resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== -eventsource@2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/eventsource/-/eventsource-2.0.2.tgz#76dfcc02930fb2ff339520b6d290da573a9e8508" - integrity sha512-IzUmBGPR3+oUG9dUeXynyNmf91/3zUSJg1lCktzKw47OXuhco54U3r9B7O4XX+Rb1Itm9OZ2b0RkTs10bICOxA== +eventsource-parser@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/eventsource-parser/-/eventsource-parser-3.0.0.tgz#9303e303ef807d279ee210a17ce80f16300d9f57" + integrity sha512-T1C0XCUimhxVQzW4zFipdx0SficT651NnkR0ZSH3yQwh+mFMdLfgjABVi4YtMTtaL4s168593DaoaRLMqryavA== + +eventsource@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/eventsource/-/eventsource-3.0.1.tgz#5d17cdcc6509e7f32089066d32024dd33a5b42af" + integrity sha512-tyGtsrTc9fi+N5qFU6G2MLjcBbsdCOQ/QE9Cc96Mt6q02YkQrIJGOaNMg6qiXRJDzxecN7BntJYNRE/j0OIhMQ== + dependencies: + eventsource-parser "^3.0.0" excel4node@^1.8.0: version "1.8.2" @@ -15206,6 +15213,11 @@ undici-types@~5.26.4: resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617" integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== +undici@^6.0.0: + version "6.21.0" + resolved "https://registry.yarnpkg.com/undici/-/undici-6.21.0.tgz#4b3d3afaef984e07b48e7620c34ed8a285ed4cd4" + integrity sha512-BUgJXc752Kou3oOIuU1i+yZZypyZRqNPW0vqoMPl8VaoalSfeR0D8/t4iAS3yirs79SSMTxTag+ZC86uswv+Cw== + unified@^9.0.0: version "9.2.2" resolved "https://registry.yarnpkg.com/unified/-/unified-9.2.2.tgz#67649a1abfc3ab85d2969502902775eb03146975"