UNPKG

query-registry

Version:

Query the npm registry for packuments, manifests, packages and download counts

1,235 lines (1,145 loc) 30.9 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var validatePackageName = require('validate-npm-package-name'); var makeError = require('make-error'); var unfetch = require('isomorphic-unfetch'); var lru = require('tiny-lru'); var gitUrlParse = require('git-url-parse'); function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } function _interopNamespace(e) { if (e && e.__esModule) return e; var n = Object.create(null); if (e) { Object.keys(e).forEach(function (k) { if (k !== 'default') { var d = Object.getOwnPropertyDescriptor(e, k); Object.defineProperty(n, k, d.get ? d : { enumerable: true, get: function () { return e[k]; } }); } }); } n["default"] = e; return n; } var validatePackageName__default = /*#__PURE__*/_interopDefaultLegacy(validatePackageName); var makeError__default = /*#__PURE__*/_interopDefaultLegacy(makeError); var unfetch__default = /*#__PURE__*/_interopDefaultLegacy(unfetch); var lru__default = /*#__PURE__*/_interopDefaultLegacy(lru); var gitUrlParse__default = /*#__PURE__*/_interopDefaultLegacy(gitUrlParse); /** * npm registry * * @see {@link https://registry.npmjs.org} */ const npmRegistry = 'https://registry.npmjs.org'; /** * npm registry mirror by Cloudflare * * @remarks * This registry has CORS enabled and can be used to retrieve * package manifests and packuments in the browser. * * @see {@link https://npmjs.cf} * @see {@link https://registry.npmjs.cf} */ const cloudflareRegistry = 'https://registry.npmjs.cf'; /** * npm registry mirror by Yarn * * @see {@link https://registry.yarnpkg.com} */ const yarnRegistry = 'https://registry.yarnpkg.com'; /** * Mirrors of the npm registry. * * @see {@link cloudflareRegistry} * @see {@link yarnRegistry} */ const npmRegistryMirrors = [cloudflareRegistry, yarnRegistry]; /** * Downloads API for the npm registry * * @see {@link https://api.npmjs.org} */ const npmRegistryDownloadsAPI = 'https://api.npmjs.org'; function normalizeRawAbbreviatedPackument({ rawAbbreviatedPackument }) { const { 'dist-tags': distTags, name: id, modified: modifiedAt } = rawAbbreviatedPackument; return { ...rawAbbreviatedPackument, id, distTags, modifiedAt }; } /** * `FetchError` represents an error that happened when fetching a URL. * * The `instanceof` operator can be used to check for this error. */ class FetchError extends makeError.BaseError { constructor( /** URL originally fetched */ url, /** Response received */ response) { super(`fetch: request to ${url} failed with status ${response.statusText}`); this.url = void 0; this.response = void 0; this.url = url; this.response = response; } } /** * `InvalidPackageNameError` is thrown when the name of a package * is not valid according to the npm registry naming rules. * * The `instanceof` operator can be used to check for this error. * * @see {@link https://www.npmjs.com/package/validate-npm-package-name} */ const InvalidPackageNameError = /*#__PURE__*/makeError__default["default"]('InvalidPackageNameError'); /** * `InvalidPackageVersionError` is thrown when a package's version does not exist. * * The `instanceof` operator can be used to check for this error. */ const InvalidPackageVersionError = /*#__PURE__*/makeError__default["default"]('InvalidPackageVersionError'); async function log(formatter, ...args) { { try { const { debug } = await Promise.resolve().then(function () { return /*#__PURE__*/_interopNamespace(require('debug')); }); const logger = debug('query-registry'); logger(formatter, args); } catch {} } } function assertValidPackageName({ name }) { const { validForOldPackages, validForNewPackages } = validatePackageName__default["default"](name); const valid = validForOldPackages || validForNewPackages; if (!valid) { log('assertValidPackageName: invalid package name: %O', { name }); throw new InvalidPackageNameError(`invalid package name: '${name}'`); } } const maxItems = 250; const fiveMinutesTTL = 5 * 60 * 1000; const cache = /*#__PURE__*/lru__default["default"](maxItems, fiveMinutesTTL); async function fetch({ url, headers, cached = true }) { const cacheKey = `headers=${JSON.stringify(headers)};url=${url}`; const cachedJSON = cache.get(cacheKey); if (cached && cachedJSON) { log('fetch: returning cached response: %O', { cacheKey, url, cachedJSON }); return cachedJSON; } const response = await unfetch__default["default"](url, { headers }); if (!response.ok) { log('fetch: request failed: %O', { url, headers, status: response.statusText, response }); throw new FetchError(url, response); } const json = await response.json(); if (cached) { cache.set(cacheKey, json); } log('fetch: returning fresh response: %O', { url, json }); return json; } async function fetchFromRegistry({ endpoint, headers, query, registry = npmRegistry, mirrors = npmRegistryMirrors, cached }) { const urls = [registry, ...mirrors].map(host => { const url = new URL(endpoint, host); url.search = query != null ? query : ''; return url.href; }); let lastError; for (const url of urls) { try { const json = await fetch({ url, headers, cached }); return json; } catch (err) { // Keep last fetch error lastError = err; } } log('fetchFromRegistry: cannot retrieve data from registry or mirrors: %O', { endpoint, headers, query, registry, mirrors, lastError }); throw lastError; } /** * `getRawAbbreviatedPackument` returns the abbreviated packument (package document) * containing only the metadata necessary to install a package present on the registry. * * Note: the abbreviated packument is returned as retrieved from the registry. * * @param name - package name * @param registry - URL of the registry (default: npm registry) * @param mirrors - URLs of the registry mirrors (default: npm registry mirrors) * @param cached - accept cached responses (default: `true`) * * @example * Get the abbreviated packument for package `query-registry` from the npm registry: * * ```typescript * import { getRawAbbreviatedPackument } from 'query-registry'; * * (async () => { * const packument = await getRawAbbreviatedPackument({ name: 'query-registry' }); * * // Output: 'query-registry' * console.log(packument.name); * })(); * ``` * * @see {@link RawAbbreviatedPackument} * @see {@link npmRegistry} * @see {@link npmRegistryMirrors} */ async function getRawAbbreviatedPackument({ name, registry, mirrors, cached }) { assertValidPackageName({ name }); const endpoint = `/${name}`; const headers = { Accept: 'application/vnd.npm.install-v1+json' }; return fetchFromRegistry({ endpoint, headers, registry, mirrors, cached }); } /** * `getAbbreviatedPackument` returns the abbreviated packument (package document) * containing only the metadata necessary to install a package present on the registry. * * @remarks * To get all the metadata (full packument) about a package see {@link getPackument}. * * @param name - package name * @param registry - URL of the registry (default: npm registry) * @param mirrors - URLs of the registry mirrors (default: npm registry mirrors) * @param cached - accept cached responses (default: `true`) * * @example * Get the abbreviated packument for package `query-registry` from the npm registry: * * ```typescript * import { getAbbreviatedPackument } from 'query-registry'; * * (async () => { * const packument = await getAbbreviatedPackument({ name: 'query-registry' }); * * // Output: 'query-registry' * console.log(packument.name); * })(); * ``` * * @see {@link AbbreviatedPackument} * @see {@link RawAbbreviatedPackument} * @see {@link npmRegistry} * @see {@link npmRegistryMirrors} */ async function getAbbreviatedPackument({ name, registry, mirrors, cached }) { const rawAbbreviatedPackument = await getRawAbbreviatedPackument({ name, registry, mirrors, cached }); return normalizeRawAbbreviatedPackument({ rawAbbreviatedPackument }); } async function fetchDownloadsFromRegistry({ endpoint, registryDownloadsAPI = npmRegistryDownloadsAPI, cached }) { return fetchFromRegistry({ endpoint, registry: registryDownloadsAPI, mirrors: [], cached }); } function normalizeRawDownloadPeriod({ rawDownloadPeriod = 'last-week' }) { if (typeof rawDownloadPeriod === 'string') { return rawDownloadPeriod; } if (rawDownloadPeriod instanceof Date) { return getDay(rawDownloadPeriod); } const { start, end } = rawDownloadPeriod; return `${getDay(start)}:${getDay(end)}`; } function getDay(date) { return date.toISOString().split('T')[0]; } /** * `getDailyPackageDownloads` returns the number of downloads for a package * for each day in a given time period. * * @param name - package name * @param period - time period in which downloads happened (default: `last-week`) * @param registryDownloadsAPI - URL of the registry's downloads API (default: npm registry) * @param cached - accept cached responses (default: `true`) * * @example * Get the day by day weekly downloads for package `query-registry` from the npm registry: * * ```typescript * import { getDailyPackageDownloads } from 'query-registry'; * * (async () => { * const downloads = await getDailyPackageDownloads({ name: 'query-registry' }); * * // Output: 'query-registry' * console.log(downloads.package); * * // Output: 'number' * console.log(typeof downloads.downloads[0].downloads); * })(); * ``` * * @example * Get the day by day monthly downloads for package `query-registry` from the npm registry: * * ```typescript * import { getDailyPackageDownloads } from 'query-registry'; * * (async () => { * const downloads = await getDailyPackageDownloads({ name: 'query-registry', period: 'last-month' }); * * // Output: 'query-registry' * console.log(downloads.package); * * // Output: 'number' * console.log(typeof downloads.downloads[0].downloads); * })(); * ``` * * @see {@link DailyPackageDownloads} * @see {@link DownloadPeriod} * @see {@link npmRegistryDownloadsAPI} * @see {@link https://github.com/npm/registry/blob/master/docs/download-counts.md#ranges} */ async function getDailyPackageDownloads({ name, period: rawDownloadPeriod, registryDownloadsAPI, cached }) { assertValidPackageName({ name }); const period = normalizeRawDownloadPeriod({ rawDownloadPeriod }); const endpoint = `/downloads/range/${period}/${name}`; return fetchDownloadsFromRegistry({ endpoint, registryDownloadsAPI, cached }); } /** * `getDailyRegistryDownloads` returns the number of downloads for all registry packages * for each day in a given time period. * * @param period - time period in which downloads happened (default: `last-week`) * @param registryDownloadsAPI - URL of the registry's downloads API (default: npm registry) * @param cached - accept cached responses (default: `true`) * * @example * Get the day by day weekly downloads for the npm registry: * * ```typescript * import { getDailyRegistryDownloads } from 'query-registry'; * * (async () => { * const downloads = await getDailyRegistryDownloads(); * * // Output: 'number' * console.log(typeof downloads.downloads[0].downloads); * })(); * ``` * * @example * Get the day by day monthly downloads for the npm registry: * * ```typescript * import { getDailyRegistryDownloads } from 'query-registry'; * * (async () => { * const downloads = await getDailyRegistryDownloads({ period: 'last-month' }); * * // Output: 'number' * console.log(typeof downloads.downloads[0].downloads); * })(); * ``` * * @see {@link DailyRegistryDownloads} * @see {@link DownloadPeriod} * @see {@link npmRegistryDownloadsAPI} * @see {@link https://github.com/npm/registry/blob/master/docs/download-counts.md#ranges} */ async function getDailyRegistryDownloads({ period: rawDownloadPeriod, registryDownloadsAPI, cached } = {}) { const period = normalizeRawDownloadPeriod({ rawDownloadPeriod }); const endpoint = `/downloads/range/${period}`; return fetchDownloadsFromRegistry({ endpoint, registryDownloadsAPI, cached }); } /** * `getPackageDownloads` returns the number of downloads for a package * in a given time period. * * @param name - package name * @param period - time period in which downloads happened (default: `last-week`) * @param registryDownloadsAPI - URL of the registry's downloads API (default: npm registry) * @param cached - accept cached responses (default: `true`) * * @example * Get the weekly downloads for package `query-registry` from the npm registry: * * ```typescript * import { getPackageDownloads } from 'query-registry'; * * (async () => { * const downloads = await getPackageDownloads({ name: 'query-registry' }); * * // Output: 'query-registry' * console.log(downloads.package); * * // Output: 'number' * console.log(typeof downloads.downloads); * })(); * ``` * * @example * Get the monthly downloads for package `query-registry` from the npm registry: * * ```typescript * import { getPackageDownloads } from 'query-registry'; * * (async () => { * const downloads = await getPackageDownloads({ name: 'query-registry', period: 'last-month' }); * * // Output: 'query-registry' * console.log(downloads.package); * * // Output: 'number' * console.log(typeof downloads.downloads); * })(); * ``` * * @see {@link PackageDownloads} * @see {@link DownloadPeriod} * @see {@link npmRegistryDownloadsAPI} * @see {@link https://github.com/npm/registry/blob/master/docs/download-counts.md#point-values} */ async function getPackageDownloads({ name, period: rawDownloadPeriod, registryDownloadsAPI, cached }) { assertValidPackageName({ name }); const period = normalizeRawDownloadPeriod({ rawDownloadPeriod }); const endpoint = `/downloads/point/${period}/${name}`; return fetchDownloadsFromRegistry({ endpoint, registryDownloadsAPI, cached }); } function extractRawPackageManifest({ rawPackument, version = 'latest' }) { var _distTags$version; const { name, 'dist-tags': distTags, versions } = rawPackument; const versionNumber = (_distTags$version = distTags[version]) != null ? _distTags$version : version; const manifest = versions[versionNumber]; if (!manifest) { log('getPackageManifest: invalid package version: %O', { name, version }); throw new InvalidPackageVersionError(`invalid package version: '${name}@${version}'`); } return manifest; } /** * `getRawPackument` returns the packument (package document) containing * all the metadata about a package present on the registry. * * Note: the packument is returned as retrieved from the registry. * * @param name - package name * @param registry - URL of the registry (default: npm registry) * @param mirrors - URLs of the registry mirrors (default: npm registry mirrors) * @param cached - accept cached responses (default: `true`) * * @example * Get the packument for package `query-registry` from the npm registry: * * ```typescript * import { getRawPackument } from 'query-registry'; * * (async () => { * const packument = await getRawPackument({ name: 'query-registry' }); * * // Output: 'query-registry' * console.log(packument.name); * })(); * ``` * * @see {@link RawPackument} * @see {@link npmRegistry} * @see {@link npmRegistryMirrors} */ async function getRawPackument({ name, registry, mirrors, cached }) { assertValidPackageName({ name }); const endpoint = `/${name}`; return fetchFromRegistry({ endpoint, registry, mirrors, cached }); } /** * `getRawPackageManifest` returns the manifest describing * a specific version of a package. * * Note: the manifest is returned as retrieved from the registry. * * @param name - package name * @param version - package version (default: `latest`) * @param registry - URL of the registry (default: npm registry) * @param mirrors - URLs of the registry mirrors (default: npm registry mirrors) * @param cached - accept cached responses (default: `true`) * * @example * Get the latest manifest for package `query-registry` from the npm registry: * * ```typescript * import { getRawPackageManifest } from 'query-registry'; * * (async () => { * const manifest = await getRawPackageManifest({ name: 'query-registry' }); * * // Output: 'query-registry' * console.log(manifest.name); * })(); * ``` * * @example * Get the manifest for package `query-registry@1.0.0` from the npm registry: * * ```typescript * import { getRawPackageManifest } from 'query-registry'; * * (async () => { * const manifest = await getRawPackageManifest({ name: 'query-registry', version: '1.0.0' }); * * // Output: 'query-registry' * console.log(manifest.name); * * // Output: '1.0.0' * console.log(manifest.version); * })(); * ``` * * @see {@link RawPackageManifest} * @see {@link npmRegistry} * @see {@link npmRegistryMirrors} */ async function getRawPackageManifest({ name, version, registry, mirrors, cached }) { const rawPackument = await getRawPackument({ name, registry, mirrors, cached }); return extractRawPackageManifest({ rawPackument, version }); } async function getDefinitelyTypedName({ rawPackageManifest, registry, mirrors, cached }) { const { name, types, typings } = rawPackageManifest; const definitelyTypedName = toDefinitelyTypedName({ name }); const alreadyTyped = name === definitelyTypedName || !!types || !!typings; if (alreadyTyped) { return undefined; } let ok = false; try { const { deprecated } = await getRawPackageManifest({ name: definitelyTypedName, registry, mirrors, cached }); ok = deprecated === undefined; } catch {} return ok ? definitelyTypedName : undefined; } /** * `toDefinitelyTypedName` returns the name of the corresponding * DefinitelyTyped package (for example, * `foo` => `@types/foo`, * `@bar/baz` => `@types/bar__baz`). */ function toDefinitelyTypedName({ name }) { return name.startsWith('@types/') ? name : `@types/${name.replace('@', '').replace('/', '__')}`; } /** * `getUntypedName` returns the name of the normal package * corresponding to a DefinitelyTyped package. */ function getUntypedName({ name }) { if (!name.startsWith('@types/')) { return undefined; } // ['foo', undefined] or ['@bar', 'baz'] const [scopeOrName, scopedName] = name.replace('@types/', '').split('__'); return scopedName ? `@${scopeOrName}/${scopedName}` : scopeOrName; } function normalizeRawLicense({ rawLicense }) { if (!rawLicense) { return undefined; } if (typeof rawLicense !== 'string') { return undefined; } return rawLicense; } function normalizeRawRepository({ rawRepository }) { if (isRepository(rawRepository)) { return normalizeRepository({ rawRepository }); } if (typeof rawRepository === 'string') { return normalizeRepository({ rawRepository: { url: rawRepository } }); } return undefined; } function isRepository(rawRepository) { return rawRepository && typeof rawRepository === 'object' && typeof rawRepository['url'] === 'string' && ['string', 'undefined'].includes(typeof rawRepository['type']) && ['string', 'undefined'].includes(typeof rawRepository['directory']); } function normalizeRepository({ rawRepository }) { const { url, directory: repositoryDir } = rawRepository; const info = parseGitURL({ url }); if (!info) { return undefined; } const { source, full_name: repositoryID, filepath } = info; // Add domain to sources derived from npm-style shortcuts const host = source.replace(/^$/, 'github.com').replace(/^github$/, 'github.com').replace(/^gitlab$/, 'gitlab.com').replace(/^bitbucket$/, 'bitbucket.org'); const parsedDir = filepath !== '' ? filepath : undefined; return { type: 'git', url: `https://${host}/${repositoryID}`, directory: repositoryDir != null ? repositoryDir : parsedDir }; } function parseGitURL({ url }) { let info; try { info = gitUrlParse__default["default"](url); } catch {} return info; } async function normalizeRawPackageManifest({ rawPackageManifest, rawPackument, registry, mirrors, cached }) { const { _id: id, name, version, license: rawLicense, repository: rawRepository, _npmUser: publisher } = rawPackageManifest; const createdAt = rawPackument.time[version]; const license = normalizeRawLicense({ rawLicense }); const gitRepository = normalizeRawRepository({ rawRepository }); const definitelyTypedName = await getDefinitelyTypedName({ rawPackageManifest, registry, mirrors, cached }); const untypedName = getUntypedName({ name }); return { ...rawPackageManifest, id, createdAt, publisher, license, gitRepository, definitelyTypedName, untypedName }; } /** * `getPackageManifest` returns the manifest describing * a specific version of a package. * * @param name - package name * @param version - package version (default: `latest`) * @param registry - URL of the registry (default: npm registry) * @param mirrors - URLs of the registry mirrors (default: npm registry mirrors) * @param cached - accept cached responses (default: `true`) * * @example * Get the latest manifest for package `query-registry` from the npm registry: * * ```typescript * import { getPackageManifest } from 'query-registry'; * * (async () => { * const manifest = await getPackageManifest({ name: 'query-registry' }); * * // Output: 'query-registry' * console.log(manifest.name); * })(); * ``` * * @example * Get the manifest for package `query-registry@1.0.0` from the npm registry: * * ```typescript * import { getPackageManifest } from 'query-registry'; * * (async () => { * const manifest = await getPackageManifest({ name: 'query-registry', version: '1.0.0' }); * * // Output: 'query-registry' * console.log(manifest.name); * * // Output: '1.0.0' * console.log(manifest.version); * })(); * ``` * * @see {@link PackageManifest} * @see {@link RawPackageManifest} * @see {@link npmRegistry} * @see {@link npmRegistryMirrors} */ async function getPackageManifest({ name, version, registry, mirrors, cached }) { const rawPackument = await getRawPackument({ name, registry, mirrors, cached }); const rawPackageManifest = extractRawPackageManifest({ rawPackument, version }); const packageManifest = await normalizeRawPackageManifest({ rawPackageManifest, rawPackument, registry, mirrors, cached }); return packageManifest; } function normalizeRawPackument({ rawPackument }) { const { _id: id, 'dist-tags': distTags, time, license: rawLicense, repository: rawRepository } = rawPackument; const license = normalizeRawLicense({ rawLicense }); const gitRepository = normalizeRawRepository({ rawRepository }); const versionsToTimestamps = Object.fromEntries(Object.entries(time).filter(([key]) => { return !['created', 'modified'].includes(key); })); return { ...rawPackument, id, distTags, versionsToTimestamps, license, gitRepository }; } /** * `getPackument` returns the packument (package document) containing * all the metadata about a package present on the registry. * * @param name - package name * @param registry - URL of the registry (default: npm registry) * @param mirrors - URLs of the registry mirrors (default: npm registry mirrors) * @param cached - accept cached responses (default: `true`) * * @example * Get the packument for package `query-registry` from the npm registry: * * ```typescript * import { getPackument } from 'query-registry'; * * (async () => { * const packument = await getPackument({ name: 'query-registry' }); * * // Output: 'query-registry' * console.log(packument.name); * })(); * ``` * * @see {@link Packument} * @see {@link RawPackument} * @see {@link npmRegistry} * @see {@link npmRegistryMirrors} */ async function getPackument({ name, registry, mirrors, cached }) { const rawPackument = await getRawPackument({ name, registry, mirrors, cached }); return normalizeRawPackument({ rawPackument }); } /** * `getRegistryDownloads` returns the number of downloads for all registry packages * in a given time period. * * @param period - time period in which downloads happened (default: `last-week`) * @param registryDownloadsAPI - URL of the registry's downloads API (default: npm registry) * @param cached - accept cached responses (default: `true`) * * @example * Get the weekly downloads for the npm registry: * * ```typescript * import { getRegistryDownloads } from 'query-registry'; * * (async () => { * const downloads = await getRegistryDownloads(); * * // Output: 'number' * console.log(typeof downloads.downloads); * })(); * ``` * * @example * Get the monthly downloads for the npm registry: * * ```typescript * import { getRegistryDownloads } from 'query-registry'; * * (async () => { * const downloads = await getRegistryDownloads({ period: 'last-month' }); * * // Output: 'number' * console.log(typeof downloads.downloads); * })(); * ``` * * @see {@link RegistryDownloads} * @see {@link DownloadPeriod} * @see {@link npmRegistryDownloadsAPI} * @see {@link https://github.com/npm/registry/blob/master/docs/download-counts.md#point-values} */ async function getRegistryDownloads({ period: rawDownloadPeriod, registryDownloadsAPI, cached } = {}) { const period = normalizeRawDownloadPeriod({ rawDownloadPeriod }); const endpoint = `/downloads/point/${period}`; return fetchDownloadsFromRegistry({ endpoint, registryDownloadsAPI, cached }); } /** * `getRegistryMetadata` returns the metadata describing the registry itself. * * @param registry - URL of the registry (default: npm registry) * @param cached - accept cached responses (default: `true`) * * @example * Get the metadata for the npm registry: * * ```typescript * import { getRegistryMetadata } from 'query-registry'; * * (async () => { * const metadata = await getRegistryMetadata(); * * // Output: 'registry' * console.log(metadata.db_name); * })(); * ``` * * @example * Get the metadata for a custom registry: * * ```typescript * import { getRegistryMetadata } from 'query-registry'; * * (async () => { * const metadata = await getRegistryMetadata({ registry: 'https://example.com' }); * })(); * ``` * * @see {@link RegistryMetadata} * @see {@link npmRegistry} */ async function getRegistryMetadata({ registry, cached } = {}) { const endpoint = '/'; return fetchFromRegistry({ registry, mirrors: [], endpoint, cached }); } function normalizeRawSearchCriteria({ rawSearchCriteria }) { // Convert SearchCriteria to a URL query string return Object.entries(rawSearchCriteria).filter(([, value]) => ['string', 'number'].includes(typeof value)).map(([key, value]) => `${key}=${value}`).join('&'); } /** * `searchPackages` returns the packages corresponding to a given query. * * @param query - one or more search criteria * @param registry - URL of the registry (default: npm registry) * @param mirrors - URLs of the registry mirrors (default: npm registry mirrors) * @param cached - accept cached responses (default: `true`) * * @example * Get the search results for text query `query-registry` from the npm registry: * * ```typescript * import { searchPackages } from 'query-registry'; * * (async () => { * const results = await searchPackages({ query: { text: 'query-registry' } }); * * // Output: 'query-registry' * console.log(results.objects[0].package.name); * })(); * ``` * * @see {@link SearchResults} * @see {@link SearchCriteria} * @see {@link npmRegistry} * @see {@link npmRegistryMirrors} */ async function searchPackages({ query: rawSearchCriteria, registry, mirrors, cached }) { const endpoint = '/-/v1/search'; const query = normalizeRawSearchCriteria({ rawSearchCriteria }); return fetchFromRegistry({ endpoint, query, registry, mirrors, cached }); } exports.FetchError = FetchError; exports.InvalidPackageNameError = InvalidPackageNameError; exports.InvalidPackageVersionError = InvalidPackageVersionError; exports.cloudflareRegistry = cloudflareRegistry; exports.getAbbreviatedPackument = getAbbreviatedPackument; exports.getDailyPackageDownloads = getDailyPackageDownloads; exports.getDailyRegistryDownloads = getDailyRegistryDownloads; exports.getPackageDownloads = getPackageDownloads; exports.getPackageManifest = getPackageManifest; exports.getPackument = getPackument; exports.getRawAbbreviatedPackument = getRawAbbreviatedPackument; exports.getRawPackageManifest = getRawPackageManifest; exports.getRawPackument = getRawPackument; exports.getRegistryDownloads = getRegistryDownloads; exports.getRegistryMetadata = getRegistryMetadata; exports.npmRegistry = npmRegistry; exports.npmRegistryDownloadsAPI = npmRegistryDownloadsAPI; exports.npmRegistryMirrors = npmRegistryMirrors; exports.searchPackages = searchPackages; exports.yarnRegistry = yarnRegistry; //# sourceMappingURL=query-registry.cjs.development.js.map