import * as crypto from 'node:crypto'; import type { IPackument, IPublishRequest, INpmVersion } from './interfaces.npm.js'; function getTarballFileName(packageName: string, version: string): string { const safeName = packageName.replace('@', '').replace('/', '-'); return `${safeName}-${version}.tgz`; } export function createNewPackument( packageName: string, body: IPublishRequest, timestamp: string ): IPackument { return { _id: packageName, name: packageName, description: body.description, 'dist-tags': body['dist-tags'] || { latest: Object.keys(body.versions)[0] }, versions: {}, time: { created: timestamp, modified: timestamp, }, maintainers: body.maintainers || [], readme: body.readme, }; } export function getAttachmentForVersion( body: IPublishRequest, version: string ): IPublishRequest['_attachments'][string] | null { const attachmentKey = Object.keys(body._attachments).find((key) => key.includes(version)); return attachmentKey ? body._attachments[attachmentKey] : null; } export function preparePublishedVersion(options: { packageName: string; version: string; versionData: INpmVersion; attachment: IPublishRequest['_attachments'][string]; registryUrl: string; userId?: string; }): { tarballBuffer: Buffer; versionData: INpmVersion } { const tarballBuffer = Buffer.from(options.attachment.data, 'base64'); const shasum = crypto.createHash('sha1').update(tarballBuffer).digest('hex'); const integrity = `sha512-${crypto.createHash('sha512').update(tarballBuffer).digest('base64')}`; const tarballFileName = getTarballFileName(options.packageName, options.version); return { tarballBuffer, versionData: { ...options.versionData, dist: { ...options.versionData.dist, tarball: `${options.registryUrl}/${options.packageName}/-/${tarballFileName}`, shasum, integrity, fileCount: 0, unpackedSize: tarballBuffer.length, }, _id: `${options.packageName}@${options.version}`, ...(options.userId ? { _npmUser: { name: options.userId, email: '' } } : {}), }, }; } export function recordPublishedVersion( packument: IPackument, version: string, versionData: INpmVersion, timestamp: string ): void { packument.versions[version] = versionData; if (packument.time) { packument.time[version] = timestamp; packument.time.modified = timestamp; } }