diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index d50ada6..a768beb 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -10,12 +10,12 @@ jobs: fail-fast: false matrix: node-version: + - 21 + - 20 - 18 - - 16 - - 14 steps: - - uses: actions/checkout@v3 - - uses: actions/setup-node@v3 + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 with: node-version: ${{ matrix.node-version }} - run: npm install diff --git a/index.d.ts b/index.d.ts index ca2c38c..470e55d 100644 --- a/index.d.ts +++ b/index.d.ts @@ -37,8 +37,10 @@ import npmUser from 'npm-user'; console.log(await npmUser('sindresorhus')); // { // name: 'Sindre Sorhus', -// avatar: 'https://gravatar.com/avatar/d36a92237c75c5337c17b60d90686bf9?size=496', -// email: 'sindresorhus@gmail.com' +// avatar: 'https://www.npmjs.com/npm-avatar/…', +// email: 'sindresorhus@gmail.com', +// github: 'sindresorhus', +// twitter: 'sindresorhus' // } ``` */ diff --git a/index.js b/index.js index 757b5c5..8485bb4 100644 --- a/index.js +++ b/index.js @@ -1,5 +1,5 @@ -import got from 'got'; -import cheerio from 'cheerio'; +import ky from 'ky'; +import {load as cheerioLoad} from 'cheerio'; import npmEmail from 'npm-email'; export default async function npmUser(username) { @@ -9,10 +9,12 @@ export default async function npmUser(username) { const url = `https://www.npmjs.com/~${username}`; try { - const [profile, email] = await Promise.all([got(url), npmEmail(username)]); - const $ = cheerio.load(profile.body); + const [profile, email] = await Promise.all([ky(url).text(), npmEmail(username)]); + const $ = cheerioLoad(profile); + + let avatar = $('img[src^="/npm-avatar"]')?.attr('src') || undefined; + avatar &&= `https://www.npmjs.com${avatar}`; - const avatar = $('img[src^="/npm-avatar"]')?.attr('src') || undefined; const $sidebar = $('[class^="_73a8e6f0"]'); return { @@ -23,8 +25,10 @@ export default async function npmUser(username) { twitter: $sidebar.find('a[href^="https://twitter.com/"]').text().slice(1) || undefined, }; } catch (error) { - if (error.statusCode === 404) { - error.message = 'User doesn\'t exist'; + if (error?.response?.status === 404) { + const notFoundError = new Error(`User \`${username}\` could not be found`, {cause: error}); + notFoundError.code = 'ERR_NO_NPM_USER'; + throw notFoundError; } throw error; diff --git a/package.json b/package.json index 1dc829d..9e7b338 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "npm-user", - "version": "5.0.1", + "version": "6.1.1", "description": "Get user info of an npm user", "license": "MIT", "repository": "sindresorhus/npm-user", @@ -11,10 +11,13 @@ "url": "https://sindresorhus.com" }, "type": "module", - "exports": "./index.js", - "types": "./index.d.ts", + "exports": { + "types": "./index.d.ts", + "default": "./index.js" + }, + "sideEffects": false, "engines": { - "node": ">=14.16" + "node": ">=18" }, "scripts": { "test": "xo && ava && tsd" @@ -36,13 +39,13 @@ "profile" ], "dependencies": { - "cheerio": "^0.22.0", - "got": "^12.5.3", - "npm-email": "^4.0.1" + "cheerio": "1.0.0-rc.12", + "ky": "^1.2.1", + "npm-email": "^5.0.0" }, "devDependencies": { - "ava": "^5.2.0", - "tsd": "^0.25.0", - "xo": "^0.53.1" + "ava": "^6.1.1", + "tsd": "^0.30.7", + "xo": "^0.57.0" } } diff --git a/readme.md b/readme.md index 88f68c4..9232a8b 100644 --- a/readme.md +++ b/readme.md @@ -21,8 +21,10 @@ console.log(await npmUser('sindresorhus')); /* { name: 'Sindre Sorhus', - avatar: 'https://gravatar.com/avatar/d36a92237c75c5337c17b60d90686bf9?size=496', - email: 'sindresorhus@gmail.com' + avatar: 'https://www.npmjs.com/npm-avatar/…', + email: 'sindresorhus@gmail.com', + github: 'sindresorhus', + twitter: 'sindresorhus' } */ ``` @@ -35,4 +37,3 @@ console.log(await npmUser('sindresorhus')); - [npm-email](https://github.com/sindresorhus/npm-email) - Get the email of an npm user - [npm-keyword](https://github.com/sindresorhus/npm-keyword) - Get a list of npm packages with a certain keyword - [package-json](https://github.com/sindresorhus/package-json) - Get the package.json of a package from the npm registry -- [npm-user-packages](https://github.com/kevva/npm-user-packages) - Get packages by an npm user diff --git a/test.js b/test.js index e1b9ce1..8fed3a5 100644 --- a/test.js +++ b/test.js @@ -1,25 +1,48 @@ import test from 'ava'; import npmUser from './index.js'; +const avatarRegex = /^https:\/\/www\.npmjs\.com\/npm-avatar\//m; + test('user: sindresorhus', async t => { const user = await npmUser('sindresorhus'); - t.is(user.name, 'Sindre Sorhus'); - t.regex(user.avatar, /npm-avatar/); - t.is(user.email, 'sindresorhus@gmail.com'); + + t.like(user, { + name: 'Sindre Sorhus', + email: 'sindresorhus@gmail.com', + github: 'sindresorhus', + twitter: 'sindresorhus', + }); + + t.regex(user.avatar, avatarRegex); }); test('user: npm', async t => { const user = await npmUser('npm'); - t.is(user.name, 'No Problem, Meatbag'); - t.regex(user.avatar, /npm-avatar/); - t.is(user.email, 'npm@npmjs.com'); + + t.like(user, { + name: 'No Problem, Meatbag', + email: 'npm@npmjs.com', + }); + + t.regex(user.avatar, avatarRegex); }); test('user: tj', async t => { const user = await npmUser('tj'); - t.is(user.name, undefined); - t.regex(user.avatar, /npm-avatar/); - t.is(user.email, 'tj@vision-media.ca'); - t.is(user.github, undefined); - t.is(user.twitter, undefined); + + t.like(user, { + name: undefined, + email: 'tj@vision-media.ca', + github: undefined, + twitter: undefined, + }); + + t.regex(user.avatar, avatarRegex); +}); + +test('handles non-existent user', async t => { + await t.throwsAsync( + npmUser('nnnope'), + {message: 'User `nnnope` could not be found', code: 'ERR_NO_NPM_USER'}, + ); });