@yanamiku/npm-user
Version:
Ambil detail pengguna NPM termasuk paket dan Gravatar
103 lines (84 loc) • 3.16 kB
JavaScript
import fetch from 'node-fetch';
import * as cheerio from 'cheerio'; // Perbaikan impor
import crypto from 'crypto';
async function getNpmEmail(username) {
try {
const npmEmail = (await import('npm-email')).default;
return await npmEmail(username);
} catch {
return undefined;
}
}
function getGravatarUrl(email, size = 512) {
if (!email) return "-";
const normalizedEmail = email.trim().toLowerCase();
const hash = crypto.createHash('md5').update(normalizedEmail).digest('hex');
return `https://www.gravatar.com/avatar/${hash}?s=${size}&d=identicon`;
}
async function getNpmPackages(username) {
const searchUrl = `https://registry.npmjs.org/-/v1/search?text=maintainer:${username}&size=100`;
try {
const response = await fetch(searchUrl);
const data = await response.json();
if (!data.objects || data.objects.length === 0) {
return [];
}
return await Promise.all(
data.objects.map(async (pkg) => {
const packageName = pkg.package.name;
const downloads = await getWeeklyDownloads(packageName);
return { name: packageName, weeklyDownloads: downloads };
})
);
} catch (error) {
console.error('Error fetching npm packages:', error);
return [];
}
}
async function getWeeklyDownloads(packageName) {
const statsUrl = `https://api.npmjs.org/downloads/point/last-week/${packageName}`;
try {
const response = await fetch(statsUrl);
const data = await response.json();
return data.downloads || 0;
} catch (error) {
console.error(`Gagal mengambil data downloads untuk ${packageName}:`, error);
return 0;
}
}
async function npmUser(username) {
if (typeof username !== 'string') {
throw new TypeError('Username required');
}
const url = `https://www.npmjs.com/~${username}`;
try {
const [profileResponse, email, packages] = await Promise.all([
fetch(url).then(res => res.text()),
getNpmEmail(username),
getNpmPackages(username)
]);
const $ = cheerio.load(profileResponse);
let avatar = $('img[src^="/npm-avatar"]')?.attr('src') || undefined;
if (avatar) {
avatar = `https://www.npmjs.com${avatar}`;
}
const $sidebar = $('[class^="_73a8e6f0"]');
return {
name: $sidebar.find('.eaac77a6.mv2').text() || undefined,
avatar,
email,
gravatar: getGravatarUrl(email),
github: $sidebar.find('a[href^="https://github.com/"]').text().slice(1) || undefined,
twitter: $sidebar.find('a[href^="https://twitter.com/"]').text().slice(1) || undefined,
packages
};
} catch (error) {
if (error?.response?.status === 404) {
const notFoundError = new Error(`User \`${username}\` could not be found`);
notFoundError.code = 'ERR_NO_NPM_USER';
throw notFoundError;
}
throw error;
}
}
export default npmUser;