Socket
Socket
Sign inDemoInstall

query-registry

Package Overview
Dependencies
9
Maintainers
1
Versions
24
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 2.6.0 to 3.0.0-0

572

dist/index.js

@@ -0,8 +1,568 @@

// src/index.ts
import { PackageJson as PackageJson4 } from "zod-package-json";
'use strict'
// src/cache.ts
import QuickLRU from "quick-lru";
var cache = new QuickLRU({
// 100 items.
maxSize: 100,
// 5 minutes.
maxAge: 5 * 60 * 1e3
});
if (process.env.NODE_ENV === 'production') {
module.exports = require('./query-registry.cjs.production.min.js')
} else {
module.exports = require('./query-registry.cjs.development.js')
}
// src/download-period.ts
import { z } from "zod";
var DownloadPeriod = z.union([
z.literal("last-day"),
z.literal("last-week"),
z.literal("last-month"),
z.literal("last-year"),
z.string().regex(/^\d{4}-\d{2}-\d{2}(:\d{4}-\d{2}-\d{2})?$/)
]);
// src/get-abbreviated-packument.ts
import urlJoin2 from "url-join";
import { z as z4 } from "zod";
// src/assert-valid-package-name.ts
import validatePackageName from "validate-npm-package-name";
var assertValidPackageName = (name) => {
const { validForOldPackages, validForNewPackages, warnings, errors } = validatePackageName(name);
const isValid = validForOldPackages || validForNewPackages;
if (!isValid) {
throw new Error("invalid package name", { cause: { name, warnings, errors } });
}
};
// src/dist-tags.ts
import { z as z2 } from "zod";
var DistTags = z2.object({
/** Latest semver version number. */
latest: z2.string(),
// The following tags have no special meaning for the npm registry
// but they are commonly used by packages.
next: z2.string().optional(),
alpha: z2.string().optional(),
beta: z2.string().optional(),
rc: z2.string().optional(),
canary: z2.string().optional(),
dev: z2.string().optional()
}).catchall(z2.string());
// src/fetch-data.ts
var fetchData = async (schema, url, headers) => {
const cacheKey = JSON.stringify({ url, headers });
const cachedJson = cache.get(cacheKey);
if (cachedJson) {
return schema.parse(cachedJson);
}
const response = await fetch(url, { headers });
const json = await response.json();
cache.set(cacheKey, json);
return schema.parse(json);
};
// src/get-package-manifest.ts
import urlJoin from "url-join";
import { z as z3 } from "zod";
import { PackageJson } from "zod-package-json";
// src/npm-registry.ts
var npmRegistryUrl = "https://registry.npmjs.org";
var npmRegistryDownloadsApiUrl = "https://api.npmjs.org";
// src/get-package-manifest.ts
var Dist = z3.object({
/** Tarball URL. */
tarball: z3.string(),
/** SHA1 sum of the tarball. */
shasum: z3.string(),
/** String in the format `<hashAlgorithm>-<base64-hash>`. */
integrity: z3.string().optional(),
/** Number of files in the tarball. */
fileCount: z3.number().optional(),
/** Total unpacked size in bytes of the files in the tarball. */
unpackedSize: z3.number().optional(),
/**
PGP signature in the format `<package>@<version>:<integrity>`.
@deprecated {@link https://docs.npmjs.com/about-registry-signatures#migrating-from-pgp-to-ecdsa-signatures}
*/
"npm-signature": z3.string().optional(),
/**
ECDSA registry signatures.
@see {@link https://docs.npmjs.com/about-registry-signatures}
*/
signatures: z3.array(
z3.object({
keyid: z3.string(),
sig: z3.string()
})
).optional()
});
var PackageManifest = PackageJson.extend({
/** Package version ID in the format `<name>@<version>` (e.g., `foo@1.0.0`). */
_id: z3.string(),
/** Distribution metadata generated by the registry. */
dist: Dist,
/** Text extracted from the README file. */
readme: z3.string().optional(),
/** Name of the README file. */
readmeFilename: z3.string().optional(),
/** Commit corresponding to the published package version. */
gitHead: z3.string().optional(),
/** True if the package contains a shrinkwrap file. */
_hasShrinkwrap: z3.boolean().optional(),
/** Node.js version used to publish the package. */
_nodeVersion: z3.string().optional(),
/** npm CLI version used to publish the package. */
_npmVersion: z3.string().optional(),
/** npm user who published the specific version of the package. */
_npmUser: PackageJson.shape.author.optional(),
/** Internal npm registry data. */
_npmOperationalInternal: z3.object({
host: z3.string().optional(),
tmp: z3.string().optional()
}).optional(),
/**
Runtime systems supported by the package.
@remarks
In some old packages (like `lodash@0.1.0`) the `engines` property is an array of strings
instead of an object and with catch it becomes an empty object.
*/
engines: z3.record(z3.string()).catch({}).optional(),
/**
SPDX license expression or a custom license.
@remarks
In some old packages (like `eslint@0.0.6`) the `license` property is an object
and with catch `license` becomes an empty string.
*/
license: z3.string().catch("").optional(),
/**
URL of the package's homepage.
@remarks
In some old packages (like `fs-extra@0.0.1`) the `homepage` property is an array
of strings and with coercion it correctly becomes a string.
*/
homepage: z3.coerce.string().optional(),
/**
Deprecation message.
@remarks
In some old packages (like `react@16.14.0`) the `deprecated` property is a boolean
and with coercion it becomes either `"true"` or `"false"`.
*/
deprecated: z3.coerce.string().optional()
});
var getPackageManifest = async (name, versionOrTag = "latest", registry = npmRegistryUrl) => {
assertValidPackageName(name);
return fetchData(PackageManifest, urlJoin(registry, name, versionOrTag));
};
// src/get-abbreviated-packument.ts
var AbbreviatedPackument = z4.object({
/** Package name. */
name: z4.string(),
/** Timestamp of when the package was last modified in ISO 8601 format (e.g., `2021-11-23T19:12:24.006Z`). */
modified: z4.string(),
/** Mapping of distribution tags to semver version numbers e.g., `{ "latest": "1.0.0" }`). */
"dist-tags": DistTags,
/** Mapping of semver version numbers to the required metadata for installing a package version. */
versions: z4.record(
z4.string(),
PackageManifest.pick({
name: true,
version: true,
dist: true,
deprecated: true,
dependencies: true,
optionalDependencies: true,
devDependencies: true,
bundleDependencies: true,
peerDependencies: true,
peerDependenciesMeta: true,
bin: true,
directories: true,
engines: true,
cpu: true,
os: true,
_hasShrinkwrap: true
}).extend({
/** True if the package contains an `install` script. */
hasInstallScript: z4.boolean().optional()
})
)
});
var getAbbreviatedPackument = async (name, registry = npmRegistryUrl) => {
assertValidPackageName(name);
return fetchData(AbbreviatedPackument, urlJoin2(registry, name), {
Accept: "application/vnd.npm.install-v1+json"
});
};
// src/get-bulk-daily-package-downloads.ts
import urlJoin5 from "url-join";
import { z as z7 } from "zod";
// src/get-daily-package-downloads.ts
import urlJoin4 from "url-join";
import { z as z6 } from "zod";
// src/get-daily-registry-downloads.ts
import urlJoin3 from "url-join";
import { z as z5 } from "zod";
var DailyRegistryDownloads = z5.object({
/** Date of the first day (inclusive) in the format `YYYY-MM-DD`. */
start: z5.string(),
/** Date of the last day (inclusive) in the format `YYYY-MM-DD`. */
end: z5.string(),
/** Download counts for each day. */
downloads: z5.array(
z5.object({
/** Total number of downloads for the day. */
downloads: z5.number(),
/** Date of the day in the format `YYYY-MM-DD`. */
day: z5.string()
})
)
});
var getDailyRegistryDownloads = async (period, registry = npmRegistryDownloadsApiUrl) => fetchData(DailyRegistryDownloads, urlJoin3(registry, `/downloads/range/${period}`));
// src/get-daily-package-downloads.ts
var DailyPackageDownloads = DailyRegistryDownloads.extend({
/** Package name. */
package: z6.string()
});
var getDailyPackageDownloads = async (name, period, registry = npmRegistryDownloadsApiUrl) => {
assertValidPackageName(name);
return fetchData(DailyPackageDownloads, urlJoin4(registry, `/downloads/range/${period}/${name}`));
};
// src/get-bulk-daily-package-downloads.ts
var BulkDailyPackageDownloads = z7.record(z7.union([z7.null(), DailyPackageDownloads]));
var getBulkDailyPackageDownloads = async (names, period, registry = npmRegistryDownloadsApiUrl) => {
for (const name of names) {
assertValidPackageName(name);
}
return fetchData(
BulkDailyPackageDownloads,
urlJoin5(registry, `/downloads/range/${period}/${names.join(",")}`)
);
};
// src/get-bulk-package-downloads.ts
import urlJoin8 from "url-join";
import { z as z10 } from "zod";
// src/get-package-downloads.ts
import urlJoin7 from "url-join";
import { z as z9 } from "zod";
// src/get-registry-downloads.ts
import urlJoin6 from "url-join";
import { z as z8 } from "zod";
var RegistryDownloads = z8.object({
/** Total number of downloads. */
downloads: z8.number(),
/** Date of the first day (inclusive) in the format `YYYY-MM-DD`. */
start: z8.string(),
/** Date of the last day (inclusive) in the format `YYYY-MM-DD`. */
end: z8.string()
});
var getRegistryDownloads = async (period, registry = npmRegistryDownloadsApiUrl) => fetchData(RegistryDownloads, urlJoin6(registry, `/downloads/point/${period}`));
// src/get-package-downloads.ts
var PackageDownloads = RegistryDownloads.extend({
/** Package name. */
package: z9.string()
});
var getPackageDownloads = async (name, period, registry = npmRegistryDownloadsApiUrl) => {
assertValidPackageName(name);
return fetchData(PackageDownloads, urlJoin7(registry, `/downloads/point/${period}/${name}`));
};
// src/get-bulk-package-downloads.ts
var BulkPackageDownloads = z10.record(z10.union([z10.null(), PackageDownloads]));
var getBulkPackageDownloads = async (names, period, registry = npmRegistryDownloadsApiUrl) => {
for (const name of names) {
assertValidPackageName(name);
}
return fetchData(
BulkPackageDownloads,
urlJoin8(registry, `/downloads/point/${period}/${names.join(",")}`)
);
};
// src/get-package-versions-downloads.ts
import urlJoin9 from "url-join";
import { z as z11 } from "zod";
var PackageVersionsDownloads = z11.object({
/** Package name. */
package: z11.string(),
/** Mapping of semver version numbers to total number of downloads. */
downloads: z11.record(z11.number())
});
var getPackageVersionsDownloads = async (name, registry = npmRegistryDownloadsApiUrl) => {
assertValidPackageName(name);
return fetchData(
PackageVersionsDownloads,
urlJoin9(registry, `/versions/${encodeURIComponent(name)}/last-week`)
);
};
// src/get-packument.ts
import urlJoin10 from "url-join";
import { z as z12 } from "zod";
import { PackageJson as PackageJson2 } from "zod-package-json";
var Time = z12.object({
/** Timestamp of when the package was created in ISO 8601 format (e.g., `2021-11-23T19:12:24.006Z`). */
created: z12.string(),
/** Timestamp of when the package was last modified in ISO 8601 format (e.g., `2021-11-23T19:12:24.006Z`). */
modified: z12.string()
}).catchall(z12.string());
var Packument = PackageJson2.pick({
author: true,
bugs: true,
contributors: true,
description: true,
homepage: true,
keywords: true,
license: true,
maintainers: true,
repository: true
}).extend({
/** Package name used as the ID in CouchDB. */
_id: z12.string(),
/** Package name. */
name: z12.string(),
/** Mapping of distribution tags to semver version numbers e.g., `{ "latest": "1.0.0" }`). */
"dist-tags": DistTags,
/**
Mapping of semver version numbers to timestamps in ISO 8601 format representing
the publishing time (e.g., `{ "1.0.0": "2021-11-23T19:12:24.006Z" }`).
Also includes the timestamps of when the package was `created` and last `modified`.
*/
time: Time,
/**
Mapping of semver version numbers to package manifests.
@see {@link PackageManifest}
*/
versions: z12.record(PackageManifest),
/** Revision ID of the document in CouchDB. */
_rev: z12.coerce.string().optional(),
/** Mapping of npm usernames of users who starred the package to `true`. */
users: z12.record(z12.boolean()).optional(),
/** Text extracted from the README file. */
readme: z12.string().optional(),
/** Name of the README file. */
readmeFilename: z12.string().optional()
});
var getPackument = async (name, registry = npmRegistryUrl) => {
assertValidPackageName(name);
return fetchData(Packument, urlJoin10(registry, name));
};
// src/get-registry-metadata.ts
import { z as z13 } from "zod";
var RegistryMetadata = z13.object({
/** Database name, usually `registry` */
db_name: z13.string().optional(),
doc_count: z13.number().optional(),
doc_del_count: z13.number().optional(),
update_seq: z13.number().optional(),
purge_seq: z13.number().optional(),
compact_running: z13.boolean().optional(),
disk_size: z13.number().optional(),
data_size: z13.number().optional(),
instance_start_time: z13.string().optional(),
disk_format_version: z13.number().optional(),
committed_update_seq: z13.number().optional(),
compacted_seq: z13.number().optional(),
uuid: z13.string().optional(),
other: z13.object({ data_size: z13.number().optional() }).optional(),
sizes: z13.object({
file: z13.number().optional(),
active: z13.number().optional(),
external: z13.number().optional()
}).optional()
});
var getRegistryMetadata = async (registry = npmRegistryUrl) => fetchData(RegistryMetadata, registry);
// src/get-registry-signing-keys.ts
import urlJoin11 from "url-join";
import { z as z14 } from "zod";
var RegistrySigningKeys = z14.object({
keys: z14.array(
z14.object({
/**
String in the simplified extended ISO 8601 format
(e.g., `YYYY-MM-DDTHH:mm:ss.sssZ`) or `null`.
*/
expires: z14.string().nullable(),
/** SHA256 fingerprint of the public key. */
keyid: z14.string(),
/** Key type; only `ecdsa-sha2-nistp256` is currently supported by the npm CLI. */
keytype: z14.string(),
/** Key scheme; only `ecdsa-sha2-nistp256` is currently supported by the npm CLI. */
scheme: z14.string(),
/** Public key encoded in base64. */
key: z14.string()
})
)
});
var getRegistrySigningKeys = async (registry = npmRegistryUrl) => fetchData(RegistrySigningKeys, urlJoin11(registry, "-/npm/v1/keys"));
// src/search-packages.ts
import queryString from "query-string";
import urlJoin12 from "url-join";
import { z as z15 } from "zod";
import { PackageJson as PackageJson3 } from "zod-package-json";
var SearchCriteria = z15.object({
/**
Query text.
@remarks
The following special text attributes can be used to refine results:
- `author:<name>`: show packages from the given author (e.g., `author:someone`)
- `maintainer:<name>`: show packages with the given maintainer (e.g., `maintainer:someone`)
- `keywords:<keyword list>`: show packages matching the given keyword(s);
separators `,`, `+` and `,-` act respectively as `OR`, `AND` and `NOT`
(e.g., use `keywords:foo,bar+baz,-quux` to include keywords `foo` OR (`bar` AND `baz`) but NOT `quux`)
- `not:unstable`: exclude unstable packages (semver version `<1.0.0`)
- `not:insecure`: exclude insecure packages
- `is:unstable`: include only unstable packages (semver version `<1.0.0`)
- `is:insecure`: include only insecure packages
- `boost-exact:<true/false>`: boost packages with exact name match (default: `true`)
*/
text: z15.string().optional(),
/** Number of results to return (the npm registry accepts a maximum of `250` with a default of `20`). */
size: z15.number().optional(),
/** Return results from this offset. */
from: z15.number().optional(),
/** Package quality weight (from `0.0` to `1.0`). */
quality: z15.number().optional(),
/** Package popularity weight (from `0.0` to `1.0`). */
popularity: z15.number().optional(),
/** Package maintenance weight (from `0.0` to `1.0`). */
maintenance: z15.number().optional()
});
var SearchResult = z15.object({
/** Package metadata. */
package: PackageJson3.pick({
name: true,
version: true,
description: true,
keywords: true
}).extend({
/**
Either `unscoped` for unscoped packages (e.g., `foo` -> `unscoped`) or
the package's scope for scoped packages (e.g., `@foo/bar` -> `foo`).
*/
scope: z15.string(),
/**
Timestamp of when the `latest` version of the package was published
in ISO 8601 format (e.g., `2021-11-23T19:12:24.006Z`).
*/
date: z15.string(),
/** Author of the package. */
author: z15.object({
username: z15.string().optional(),
name: z15.string().optional(),
email: z15.string().optional(),
url: z15.string().optional()
}).optional(),
/** User who published the `latest` version of the package. */
publisher: z15.object({
username: z15.string(),
email: z15.string()
}),
/** Maintainers of the `latest` version of the package. */
maintainers: z15.array(
z15.object({
username: z15.string(),
email: z15.string()
})
),
/** Links to resources associated to the package. */
links: z15.object({
/** Page for the package on npmjs.com. */
npm: z15.string().optional(),
/** Homepage for the package. */
homepage: z15.string().optional(),
/** Repository for the package. */
repository: z15.string().optional(),
/** Issue tracker for the package. */
bugs: z15.string().optional()
})
}),
/** Final and detailed search score values. */
score: z15.object({
/** Final search score value (from `0.0` to `1.0`), computed from the detailed scores. */
final: z15.number(),
/** Detailed search score values. */
detail: z15.object({
/** Quality search score value (from `0.0` to `1.0`). */
quality: z15.number(),
/** Popularity search score value (from `0.0` to `1.0`). */
popularity: z15.number(),
/** Maintenance search score value (from `0.0` to `1.0`). */
maintenance: z15.number()
})
}),
/** Search score value; may be different from `score.final`. */
searchScore: z15.number(),
/** Flag attributes for the package. */
flags: z15.object({
/** True if the package semver version number is `<1.0.0`. */
unstable: z15.coerce.boolean().optional(),
/** True if the package is insecure or has vulnerable dependencies. */
insecure: z15.coerce.boolean().optional()
}).optional()
});
var SearchResults = z15.object({
objects: z15.array(SearchResult),
/**
Total number of corresponding search results available;
may be higher than the number of `objects` returned.
*/
total: z15.number(),
/** Date at which the search happened. */
time: z15.string()
});
var searchPackages = async (criteria, registry = npmRegistryUrl) => fetchData(SearchResults, urlJoin12(registry, "-/v1/search", `?${queryString.stringify(criteria)}`));
export {
AbbreviatedPackument,
BulkDailyPackageDownloads,
BulkPackageDownloads,
DailyPackageDownloads,
DailyRegistryDownloads,
DownloadPeriod,
PackageDownloads,
PackageJson4 as PackageJson,
PackageManifest,
PackageVersionsDownloads,
Packument,
RegistryDownloads,
RegistryMetadata,
RegistrySigningKeys,
SearchCriteria,
SearchResults,
cache,
getAbbreviatedPackument,
getBulkDailyPackageDownloads,
getBulkPackageDownloads,
getDailyPackageDownloads,
getDailyRegistryDownloads,
getPackageDownloads,
getPackageManifest,
getPackageVersionsDownloads,
getPackument,
getRegistryDownloads,
getRegistryMetadata,
getRegistrySigningKeys,
npmRegistryDownloadsApiUrl,
npmRegistryUrl,
searchPackages
};

168

package.json
{
"name": "query-registry",
"description": "Query the npm registry for packuments, manifests, packages and download counts",
"version": "2.6.0",
"author": "Edoardo Scibona (velut)",
"license": "MIT",
"source": "./src/index.ts",
"main": "./dist/index.js",
"module": "./dist/query-registry.esm.js",
"types": "./dist/index.d.ts",
"sideEffects": false,
"exports": {
".": {
"require": "./dist/index.js",
"import": "./dist/query-registry.esm.js",
"default": "./dist/index.js"
},
"./package.json": "./package.json"
},
"files": [
"src",
"dist"
],
"engines": {
"node": ">=12"
},
"scripts": {
"start": "dts watch --target node",
"build:check": "tsc --noEmit",
"build": "tsc --noEmit && dts build --target node",
"test": "dts test --runInBand",
"test:cov": "dts test --runInBand --coverage",
"test:watch": "dts test --runInBand --watchAll --coverage",
"test:ci": "dts test --runInBand --ci --coverage",
"lint": "dts lint src test",
"lint:fix": "dts lint src test --fix",
"prepare": "husky install && dts build --target node",
"pre-push": "yarn && yarn lint && yarn build && yarn test:cov",
"release": "np"
},
"repository": {
"type": "git",
"url": "https://github.com/velut/node-query-registry.git"
},
"bugs": {
"url": "https://github.com/velut/node-query-registry/issues"
},
"keywords": [
"query",
"registry",
"npm",
"client",
"api",
"packument",
"package",
"downloads",
"search",
"manifest",
"typescript"
],
"dependencies": {
"isomorphic-unfetch": "^3.1.0",
"make-error": "^1.3.6",
"tiny-lru": "^8.0.2",
"url-join": "4.0.1",
"validate-npm-package-name": "^4.0.0"
},
"devDependencies": {
"@commitlint/cli": "17.0.3",
"@commitlint/config-conventional": "17.0.3",
"@pollyjs/adapter-node-http": "6.0.5",
"@pollyjs/core": "6.0.5",
"@pollyjs/persister-fs": "6.0.5",
"@types/debug": "4.1.7",
"@types/git-url-parse": "9.0.1",
"@types/pollyjs__adapter-node-http": "2.0.1",
"@types/pollyjs__core": "4.3.3",
"@types/pollyjs__persister-fs": "2.0.1",
"@types/setup-polly-jest": "0.5.1",
"@types/url-join": "4.0.1",
"@types/validate-npm-package-name": "4.0.0",
"debug": "4.3.4",
"dts-cli": "1.5.2",
"eslint-plugin-prettier": "4.2.1",
"husky": "8.0.1",
"nock": "13.2.9",
"np": "7.6.2",
"prettier": "2.7.1",
"setup-polly-jest": "0.11.0",
"ts-jest": "28.0.7",
"tslib": "2.4.0",
"typescript": "4.7.4"
}
"name": "query-registry",
"version": "3.0.0-0",
"description": "Query the npm registry for packuments, manifests, packages and download counts",
"license": "MIT",
"author": {
"name": "Edoardo Scibona",
"url": "https://github.com/velut"
},
"repository": {
"type": "git",
"url": "https://github.com/velut/query-registry.git"
},
"bugs": {
"url": "https://github.com/velut/query-registry/issues"
},
"keywords": [
"query",
"registry",
"npm",
"client",
"api",
"packument",
"package",
"downloads",
"search",
"manifest",
"typescript"
],
"sideEffects": false,
"type": "module",
"types": "./dist/index.d.ts",
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.js"
},
"./package.json": "./package.json"
},
"files": [
"dist"
],
"engines": {
"node": ">=20"
},
"scripts": {
"check": "tsc --noEmit",
"build": "tsc --noEmit && tsup",
"attw": "attw --pack . --ignore-rules cjs-resolves-to-esm",
"test": "vitest",
"test:update-db": "bun run scripts/update-test-db.ts",
"test:ci": "vitest run --coverage --bail 1",
"lint": "prettier --check .",
"format": "prettier --write .",
"pre-push": "bun install && bun run lint && bun run build && bun run test:ci && bun run attw",
"release": "np"
},
"dependencies": {
"query-string": "^9.0.0",
"quick-lru": "^7.0.0",
"url-join": "^5.0.0",
"validate-npm-package-name": "^5.0.0",
"zod": "^3.22.5",
"zod-package-json": "^1.0.1"
},
"devDependencies": {
"@arethetypeswrong/cli": "^0.15.3",
"@types/bun": "^1.1.0",
"@types/validate-npm-package-name": "^4.0.2",
"@vitest/coverage-v8": "^1.5.0",
"fflate": "^0.8.2",
"np": "^10.0.5",
"prettier": "^3.2.5",
"tsup": "^8.0.2",
"typescript": "^5.4.5",
"vitest": "^1.5.0"
}
}
# query-registry
[![Build status](https://img.shields.io/github/workflow/status/velut/node-query-registry/CI)](https://github.com/velut/node-query-registry/actions?query=workflow%3ACI)
[![Coverage](https://img.shields.io/codecov/c/gh/velut/node-query-registry)](https://codecov.io/gh/velut/node-query-registry)
[![Build status](https://img.shields.io/github/actions/workflow/status/velut/query-registry/main.yml?branch=main)](https://github.com/velut/query-registry/actions?query=workflow%3ACI)
[![Coverage](https://img.shields.io/codecov/c/gh/velut/query-registry)](https://codecov.io/gh/velut/query-registry)
[![jsDocs.io](https://img.shields.io/badge/jsDocs.io-reference-blue)](https://www.jsdocs.io/package/query-registry)
![Language](https://img.shields.io/github/languages/top/velut/node-query-registry)
![Language](https://img.shields.io/github/languages/top/velut/query-registry)
[![npm bundle size](https://img.shields.io/bundlephobia/min/query-registry)](https://bundlephobia.com/result?p=query-registry)
[![npm](https://img.shields.io/npm/v/query-registry)](https://www.npmjs.com/package/query-registry)
[![License](https://img.shields.io/github/license/velut/node-query-registry)](https://github.com/velut/node-query-registry/blob/main/LICENSE)
[![License](https://img.shields.io/github/license/velut/query-registry)](https://github.com/velut/query-registry/blob/main/LICENSE)
This package exports several functions to query the [npm registry](https://www.npmjs.com) (or one of its mirrors) through one of its [endpoints](https://github.com/npm/registry/blob/master/docs/REGISTRY-API.md).
`query-registry` is an API wrapper for the [npm registry API](https://github.com/npm/registry/blob/master/docs/REGISTRY-API.md).
## Features
- Provides functions to:
- Get registry metadata
- Get packuments (package documents) and their abbreviated form
- Get package manifests
- Get download counts (packages and registry)
- Search packages
- Usable in the browser
- Fully typed API and response data
- Supports mirrors of the npm registry
- Supports caching network requests
- Well documented and tested
- Provides functions to:
- Get registry metadata.
- Get registry public keys.
- Get packuments (package documents) with full package metadata.
- Get abbreviated packuments with installation data only.
- Get package manifests for each version of a package.
- Get download counts for the registry and for packages.
- Search packages by name and other specific criteria.
- Works in the browser.
- Validates registry responses with [zod](https://www.npmjs.com/package/zod).
- Automatically caches registry responses for a short time.
- Supports third-party npm-compatible registries.
## API & Package Info
## Useful resources
- [**Explore the API on jsDocs.io**](https://www.jsdocs.io/package/query-registry)
- View package contents on [**unpkg**](https://unpkg.com/query-registry/)
- View repository on [**GitHub**](https://github.com/velut/node-query-registry)
- Read the changelog on [**GitHub**](https://github.com/velut/node-query-registry/blob/main/CHANGELOG.md)
- [**Explore the API on jsDocs.io**](https://www.jsdocs.io/package/query-registry)
- View package contents on [**unpkg**](https://unpkg.com/query-registry/)
- View repository on [**GitHub**](https://github.com/velut/query-registry)
- Read the changelog on [**GitHub**](https://github.com/velut/query-registry/blob/main/CHANGELOG.md)

@@ -39,3 +40,3 @@ ## Install

```
npm i query-registry
npm add query-registry
```

@@ -49,90 +50,120 @@

## Usage Examples
Using `pnpm`:
Get the metadata for the npm registry:
```
pnpm add query-registry
```
Using `bun`:
```
bun add query-registry
```
## Usage examples
### Registry
Get the metadata about the npm registry itself, if available:
```typescript
import { getRegistryMetadata } from 'query-registry';
import { getRegistryMetadata } from "query-registry";
(async () => {
const metadata = await getRegistryMetadata();
const metadata = await getRegistryMetadata();
```
// Output: 'registry'
console.log(metadata.db_name);
})();
Get the public signing keys for the npm registry:
```typescript
import { getRegistrySigningKeys } from "query-registry";
const { keys } = await getRegistrySigningKeys();
```
Get the latest manifest for package `query-registry` from the npm registry:
### Packuments (Package documents)
Get the abbreviated packument containing only the necessary data to install the `react` package:
```typescript
import { getPackageManifest } from 'query-registry';
import { getAbbreviatedPackument } from "query-registry";
(async () => {
const manifest = await getPackageManifest({ name: 'query-registry' });
const abbrPackument = await getAbbreviatedPackument("react");
```
// Output: 'query-registry'
console.log(manifest.name);
})();
Get the full packument containing all the data available about the `react` package:
```typescript
import { getPackument } from "query-registry";
const packument = await getPackument("react");
```
Get the abbreviated packument for package `query-registry` from the npm registry:
### Package manifests
Get the manifest containing the original `package.json` data plus additional registry metadata for the `latest` version of the `react` package:
```typescript
import { getAbbreviatedPackument } from 'query-registry';
import { getPackageManifest } from "query-registry";
(async () => {
const packument = await getAbbreviatedPackument({ name: 'query-registry' });
const manifest = await getPackageManifest("react");
```
// Output: 'query-registry'
console.log(packument.name);
})();
Get the manifest for `react@18.2.0` (semver version):
```typescript
import { getPackageManifest } from "query-registry";
const manifest = await getPackageManifest("react", "18.2.0");
```
Get the weekly downloads for package `query-registry` from the npm registry:
Get the manifest for `react@next` (distribution tag):
```typescript
import { getPackageDownloads } from 'query-registry';
import { getPackageManifest } from "query-registry";
(async () => {
const downloads = await getPackageDownloads({ name: 'query-registry' });
const manifest = await getPackageManifest("react", "next");
```
// Output: 'query-registry'
console.log(downloads.package);
### Search packages
// Output: 'number'
console.log(typeof downloads.downloads);
})();
Search packages related to `react` (e.g., `react`, `react-dom`, ...):
```typescript
import { searchPackages } from "query-registry";
const results = await searchPackages({ text: "react" });
```
Get the search results for text query `query-registry` from the npm registry:
### Download counts
Get the total number of downloads for package `react` for the last month:
```typescript
import { searchPackages } from 'query-registry';
import { getPackageDownloads } from "query-registry";
(async () => {
const results = await searchPackages({
query: { text: 'query-registry' },
});
// Output: 'query-registry'
console.log(results.objects[0].package.name);
})();
const { downloads } = await getPackageDownloads("react", "last-month");
```
## Debug
There are also these other download counts functions available: `getBulkDailyPackageDownloads`, `getBulkPackageDownloads`, `getDailyPackageDownloads`, `getDailyRegistryDownloads` and `getPackageVersionsDownloads`.
Debug messages are available in non production environments when the `DEBUG` environment variable is set to `query-registry`:
### Cache
```bash
DEBUG="query-registry"
Clear the internal cache.
```typescript
import { cache } from "query-registry";
cache.clear();
```
For more information, see the [debug package](https://www.npmjs.com/package/debug).
See the [quick-lru](https://www.npmjs.com/package/quick-lru) package for the cache API.
## License
MIT License
```
MIT
```
Copyright (c) 2021 Edoardo Scibona
Copyright (c) 2024 Edoardo Scibona
See LICENSE file.
See [LICENSE](./LICENSE) file.

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc