From d6e44a4c18f32ad3063718d3316aebe462fd250e Mon Sep 17 00:00:00 2001 From: Juan Picado Date: Sat, 12 Jun 2021 18:24:54 +0200 Subject: [PATCH] chore: replace node-fetch by undici hook package (#2292) * chore: replace node-fetch by undici hook package * fix types * test something * test 12 * add flag * restore fail fast * remove 12 from tests --- .github/workflows/ci.yml | 2 +- packages/hooks/jest.config.js | 4 +- packages/hooks/package.json | 9 ++-- packages/hooks/src/notify-request.ts | 11 +++-- packages/hooks/src/notify.ts | 4 +- packages/hooks/test/notify-request.spec.ts | 55 ++++++++++++---------- pnpm-lock.yaml | 31 ++++++------ 7 files changed, 62 insertions(+), 54 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c0e2e7240..6bf8dcf8a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -116,7 +116,7 @@ jobs: fail-fast: true matrix: os: [ubuntu-latest] - node_version: [12, 14] + node_version: [14] name: ${{ matrix.os }} / Node ${{ matrix.node_version }} runs-on: ${{ matrix.os }} steps: diff --git a/packages/hooks/jest.config.js b/packages/hooks/jest.config.js index 7da7d2da8..1fdd30d29 100644 --- a/packages/hooks/jest.config.js +++ b/packages/hooks/jest.config.js @@ -1,3 +1,5 @@ const config = require('../../jest/config'); -module.exports = Object.assign({}, config, {}); +module.exports = Object.assign({}, config, { + testEnvironment: 'node', +}); diff --git a/packages/hooks/package.json b/packages/hooks/package.json index 7a87d4c7b..7410e61b7 100644 --- a/packages/hooks/package.json +++ b/packages/hooks/package.json @@ -26,7 +26,7 @@ "verdaccio" ], "engines": { - "node": ">=10", + "node": ">=12", "npm": ">=6" }, "dependencies": { @@ -34,15 +34,14 @@ "@verdaccio/logger": "workspace:6.0.0-6-next.4", "debug": "^4.2.0", "handlebars": "4.5.3", - "node-fetch": "^2.6.1", - "request": "2.87.0" + "undici": "^4.0.0-rc.1", + "undici-fetch": "^1.0.0-rc.1" }, "devDependencies": { "@verdaccio/auth": "workspace:6.0.0-6-next.9", "@verdaccio/commons-api": "workspace:11.0.0-alpha.3", "@verdaccio/config": "workspace:6.0.0-6-next.7", - "@verdaccio/types": "workspace:11.0.0-6-next.7", - "nock": "^13.0.4" + "@verdaccio/types": "workspace:11.0.0-6-next.7" }, "scripts": { "clean": "rimraf ./build", diff --git a/packages/hooks/src/notify-request.ts b/packages/hooks/src/notify-request.ts index bddcd2a1d..50367da08 100644 --- a/packages/hooks/src/notify-request.ts +++ b/packages/hooks/src/notify-request.ts @@ -1,13 +1,18 @@ -import fetch, { RequestInit } from 'node-fetch'; import buildDebug from 'debug'; import { logger } from '@verdaccio/logger'; import { HTTP_STATUS } from '@verdaccio/commons-api'; const debug = buildDebug('verdaccio:hooks:request'); -export type NotifyRequestOptions = RequestInit; +const fetch = require('undici-fetch'); -export async function notifyRequest(url: string, options: NotifyRequestOptions): Promise { +export type FetchOptions = { + body: string; + headers?: {}; + method?: string; +}; + +export async function notifyRequest(url: string, options: FetchOptions): Promise { let response; try { debug('uri %o', url); diff --git a/packages/hooks/src/notify.ts b/packages/hooks/src/notify.ts index 3c861f3e0..1c2c5bbcb 100644 --- a/packages/hooks/src/notify.ts +++ b/packages/hooks/src/notify.ts @@ -5,7 +5,7 @@ import Handlebars from 'handlebars'; import buildDebug from 'debug'; import { Config, Package, RemoteUser, Notification } from '@verdaccio/types'; import { logger } from '@verdaccio/logger'; -import { notifyRequest, NotifyRequestOptions } from './notify-request'; +import { notifyRequest, FetchOptions } from './notify-request'; const debug = buildDebug('verdaccio:hooks'); @@ -50,7 +50,7 @@ export async function handleNotify( content = await compileTemplate(notifyEntry.content, metadata); } - const options: NotifyRequestOptions = { + const options: FetchOptions = { body: JSON.stringify(content), }; diff --git a/packages/hooks/test/notify-request.spec.ts b/packages/hooks/test/notify-request.spec.ts index d530f106d..300b6255c 100644 --- a/packages/hooks/test/notify-request.spec.ts +++ b/packages/hooks/test/notify-request.spec.ts @@ -1,4 +1,4 @@ -import nock from 'nock'; +import { setup } from '@verdaccio/logger'; import { Config } from '@verdaccio/types'; import { parseConfigFile, createRemoteUser } from '@verdaccio/config'; import { notify } from '../src/notify'; @@ -12,36 +12,33 @@ const singleHeaderNotificationConfig = parseConfigFile( ); const multiNotificationConfig = parseConfigFile(parseConfigurationNotifyFile('multiple.notify')); -const mockInfo = jest.fn(); -jest.mock('@verdaccio/logger', () => ({ - setup: jest.fn(), - logger: { - child: jest.fn(), - debug: jest.fn(), - trace: jest.fn(), - warn: jest.fn(), - info: () => mockInfo(), - error: jest.fn(), - fatal: jest.fn(), - }, -})); +setup([]); const domain = 'http://slack-service'; +const { MockAgent } = require('undici'); +const { setGlobalDispatcher } = require('undici-fetch'); + +const options = { + path: '/foo?auth_token=mySecretToken', + method: 'POST', +}; describe('Notifications:: notifyRequest', () => { - beforeEach(() => { - nock.cleanAll(); - }); - test('when sending a empty notification', async () => { - nock(domain).post('/foo?auth_token=mySecretToken').reply(200, { body: 'test' }); + const mockAgent = new MockAgent({ connections: 1 }); + setGlobalDispatcher(mockAgent); + const mockClient = mockAgent.get(domain); + mockClient.intercept(options).reply(200, { body: 'test' }); const notificationResponse = await notify({}, {}, createRemoteUser('foo', []), 'bar'); expect(notificationResponse).toEqual([false]); }); test('when sending a single notification', async () => { - nock(domain).post('/foo?auth_token=mySecretToken').reply(200, { body: 'test' }); + const mockAgent = new MockAgent({ connections: 1 }); + setGlobalDispatcher(mockAgent); + const mockClient = mockAgent.get(domain); + mockClient.intercept(options).reply(200, { body: 'test' }); const notificationResponse = await notify( {}, @@ -50,10 +47,14 @@ describe('Notifications:: notifyRequest', () => { 'bar' ); expect(notificationResponse).toEqual([true]); + await mockClient.close(); }); test('when notification endpoint is missing', async () => { - nock(domain).post('/foo?auth_token=mySecretToken').reply(200, { body: 'test' }); + const mockAgent = new MockAgent({ connections: 1 }); + setGlobalDispatcher(mockAgent); + const mockClient = mockAgent.get(domain); + mockClient.intercept(options).reply(200, { body: 'test' }); const name = 'package'; const config: Partial = { // @ts-ignore @@ -68,14 +69,16 @@ describe('Notifications:: notifyRequest', () => { }); test('when multiple notifications', async () => { - nock(domain).post('/foo?auth_token=mySecretToken').reply(200, { body: 'test' }); - nock(domain).post('/foo?auth_token=mySecretToken').reply(400, {}); - nock(domain) - .post('/foo?auth_token=mySecretToken') - .reply(500, { message: 'Something bad happened' }); + const mockAgent = new MockAgent({ connections: 1 }); + setGlobalDispatcher(mockAgent); + const mockClient = mockAgent.get(domain); + mockClient.intercept(options).reply(200, { body: 'test' }); + mockClient.intercept(options).reply(400, {}); + mockClient.intercept(options).reply(500, { message: 'Something bad happened' }); const name = 'package'; const responses = await notify({ name }, multiNotificationConfig, { name: 'foo' }, 'bar'); expect(responses).toEqual([true, false, false]); + await mockClient.close(); }); }); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8c9e2bcab..37602b6b7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -504,21 +504,19 @@ importers: '@verdaccio/types': workspace:11.0.0-6-next.7 debug: ^4.2.0 handlebars: 4.5.3 - nock: ^13.0.4 - node-fetch: ^2.6.1 - request: 2.87.0 + undici: ^4.0.0-rc.1 + undici-fetch: ^1.0.0-rc.1 dependencies: '@verdaccio/commons-api': link:../core/commons-api '@verdaccio/logger': link:../logger debug: 4.2.0 handlebars: 4.5.3 - node-fetch: 2.6.1 - request: 2.87.0 + undici: 4.0.0-rc.7 + undici-fetch: 1.0.0-rc.1 devDependencies: '@verdaccio/auth': link:../auth '@verdaccio/config': link:../config '@verdaccio/types': link:../core/types - nock: 13.0.4 packages/loaders: specifiers: @@ -13500,16 +13498,6 @@ packages: - supports-color dev: true - /nock/13.0.4: - resolution: {integrity: sha512-alqTV8Qt7TUbc74x1pKRLSENzfjp4nywovcJgi/1aXDiUxXdt7TkruSTF5MDWPP7UoPVgea4F9ghVdmX0xxnSA==} - engines: {node: '>= 10.13'} - dependencies: - debug: 4.1.1 - json-stringify-safe: 5.0.1 - lodash.set: 4.3.2 - propagate: 2.0.1 - dev: true - /node-abi/2.19.1: resolution: {integrity: sha512-HbtmIuByq44yhAzK7b9j/FelKlHYISKQn0mtvcBrU5QBkhoCMp5bu8Hv5AI34DcKfOAcJBcOEMwLlwO62FFu9A==} dependencies: @@ -18095,6 +18083,17 @@ packages: debug: 2.6.9 dev: true + /undici-fetch/1.0.0-rc.1: + resolution: {integrity: sha512-VPMBog6ke/hSABltjVrcq+xc0RSnqfgmufn+5hfKBoIEJJq5nkKWQcWzW/uGlesSC2eKFQ6sPCQesFc7LfqGAg==} + dependencies: + undici: 4.0.0-rc.7 + dev: false + + /undici/4.0.0-rc.7: + resolution: {integrity: sha512-8vhF9REAH/O+eGh1K942bTznr47JOZHlHMTh9/5XiJvcBk3GqV2qzeRPxwDfAeHNWjm1BZ4EsSgAotHV2EOxeA==} + engines: {node: '>=12.18'} + dev: false + /unicode-canonical-property-names-ecmascript/1.0.4: resolution: {integrity: sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ==} engines: {node: '>=4'}