From c5a6dc41737772155e2fd079a308a1bdc0b89ccb Mon Sep 17 00:00:00 2001 From: Raine Revere Date: Thu, 23 Nov 2023 23:10:56 +0000 Subject: [PATCH] npm/fetchPackageInfo: Use json.stream for better performance. --- src/package-managers/npm.ts | 37 +++++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/src/package-managers/npm.ts b/src/package-managers/npm.ts index 67893133..d629de72 100644 --- a/src/package-managers/npm.ts +++ b/src/package-managers/npm.ts @@ -47,7 +47,7 @@ const isExactVersion = (version: Version) => /** Fetches a packument or dist-tag from the npm registry. */ const fetchPackageInfo = async ( name: string, - tag: string | null = 'latest', + tag: string | null, opts: npmRegistryFetch.FetchOptions = {}, ): Promise => { const corgiDoc = 'application/vnd.npm.install-v1+json; q=1.0, application/json; q=0.8, */*' @@ -62,20 +62,33 @@ const fetchPackageInfo = async ( ...opts.headers, } const url = path.join(registry, name) + const fetchOptions = { + ...opts, + headers, + spec: name, + } try { - const result = await npmRegistryFetch.json(url, { - ...opts, - headers, - spec: name, - }) - return opts.fullMetadata - ? result - : { - name, - 'dist-tags': result['dist-tags'], - versions: result.versions, + if (opts.fullMetadata) { + return npmRegistryFetch.json(url, fetchOptions) + } else { + tag = tag || 'latest' + // typescript does not type async iteratable stream correctly + const stream = npmRegistryFetch.json.stream(url, '$*', fetchOptions) as any + + const partialPackument: Partial = { name } + + for await (const { key, value } of stream) { + if (key === 'dist-tags') { + partialPackument['dist-tags'] = value + } else if (key === 'versions') { + partialPackument.versions = value + break } + } + + return partialPackument + } } catch (err: any) { if (err.code !== 'E404' || opts.fullMetadata) { throw err