pax_global_header00006660000000000000000000000064135155335620014522gustar00rootroot0000000000000052 comment=6e7a2ae1cd053465e0dd2b8653f8c90d712c66c6 package-json-6.5.0/000077500000000000000000000000001351553356200140745ustar00rootroot00000000000000package-json-6.5.0/.editorconfig000066400000000000000000000002571351553356200165550ustar00rootroot00000000000000root = true [*] indent_style = tab end_of_line = lf charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true [*.yml] indent_style = space indent_size = 2 package-json-6.5.0/.gitattributes000066400000000000000000000000231351553356200167620ustar00rootroot00000000000000* text=auto eol=lf package-json-6.5.0/.github/000077500000000000000000000000001351553356200154345ustar00rootroot00000000000000package-json-6.5.0/.github/funding.yml000066400000000000000000000001661351553356200176140ustar00rootroot00000000000000github: sindresorhus open_collective: sindresorhus tidelift: npm/package-json custom: https://sindresorhus.com/donate package-json-6.5.0/.github/security.md000066400000000000000000000002631351553356200176260ustar00rootroot00000000000000# Security Policy To report a security vulnerability, please use the [Tidelift security contact](https://tidelift.com/security). Tidelift will coordinate the fix and disclosure. package-json-6.5.0/.gitignore000066400000000000000000000000271351553356200160630ustar00rootroot00000000000000node_modules yarn.lock package-json-6.5.0/.npmrc000066400000000000000000000004271351553356200152170ustar00rootroot00000000000000package-lock=false @mockscope:registry=http://localhost:63142 //localhost:63142/:_authToken=MySecretToken @mockscope2:registry=http://localhost:63143 //localhost:63143/:username=Aladdin //localhost:63143/:_password=T3BlblNlc2FtZQ== @mockscope3:registry=http://localhost:63144 package-json-6.5.0/.travis.yml000066400000000000000000000000651351553356200162060ustar00rootroot00000000000000language: node_js node_js: - '12' - '10' - '8' package-json-6.5.0/index.d.ts000066400000000000000000000135611351553356200160030ustar00rootroot00000000000000/// import {Agent as HttpAgent} from 'http'; import {Agent as HttpsAgent} from 'https'; declare class VersionNotFoundErrorClass extends Error { readonly name: 'VersionNotFoundError'; constructor(packageName: string, version: string); } declare class PackageNotFoundErrorClass extends Error { readonly name: 'PackageNotFoundError'; constructor(packageName: string); } declare namespace packageJson { interface Agents { http?: HttpAgent; https?: HttpsAgent; } interface Options { /** Package version such as `1.0.0` or a [dist tag](https://docs.npmjs.com/cli/dist-tag) such as `latest`. The version can also be in any format supported by the [semver](https://github.com/npm/node-semver) module. For example: - `1` - Get the latest `1.x.x` - `1.2` - Get the latest `1.2.x` - `^1.2.3` - Get the latest `1.x.x` but at least `1.2.3` - `~1.2.3` - Get the latest `1.2.x` but at least `1.2.3` @default 'latest' */ readonly version?: string; /** By default, only an abbreviated metadata object is returned for performance reasons. [Read more.](https://github.com/npm/registry/blob/master/docs/responses/package-metadata.md) @default false */ readonly fullMetadata?: boolean; /** Return the [main entry](https://registry.npmjs.org/ava) containing all versions. @default false */ readonly allVersions?: boolean; /** The registry URL is by default inferred from the npm defaults and `.npmrc`. This is beneficial as `package-json` and any project using it will work just like npm. This option is*only** intended for internal tools. You should*not** use this option in reusable packages. Prefer just using `.npmrc` whenever possible. */ readonly registryUrl?: string; /** Overwrite the `agent` option that is passed down to [`got`](https://github.com/sindresorhus/got#agent). This might be useful to add [proxy support](https://github.com/sindresorhus/got#proxies). */ readonly agent?: HttpAgent | HttpsAgent | Agents | false; } interface FullMetadataOptions extends Options { /** By default, only an abbreviated metadata object is returned for performance reasons. [Read more.](https://github.com/npm/registry/blob/master/docs/responses/package-metadata.md) @default false */ readonly fullMetadata: true; } interface DistTags { readonly latest: string; readonly [tagName: string]: string; } interface AbbreviatedMetadata { readonly 'dist-tags': DistTags; readonly modified: string; readonly name: string; readonly versions: {readonly [version: string]: AbbreviatedVersion}; readonly [key: string]: unknown; } interface AbbreviatedVersion { readonly name: string; readonly version: string; readonly dist: { readonly shasum: string; readonly tarball: string; readonly integrity?: string; }; readonly deprecated?: string; readonly dependencies?: {readonly [name: string]: string}; readonly optionalDependencies?: {readonly [name: string]: string}; readonly devDependencies?: {readonly [name: string]: string}; readonly bundleDependencies?: {readonly [name: string]: string}; readonly peerDependencies?: {readonly [name: string]: string}; readonly bin?: {readonly [key: string]: string}; readonly directories?: readonly string[]; readonly engines?: {readonly [type: string]: string}; readonly _hasShrinkwrap?: boolean; readonly [key: string]: unknown; } interface Person { readonly name?: string; readonly email?: string; readonly url?: string; } interface HoistedData { readonly author?: Person; readonly bugs?: | {readonly url: string; readonly email?: string} | {readonly url?: string; readonly email: string}; readonly contributors?: readonly Person[]; readonly description?: string; readonly homepage?: string; readonly keywords?: readonly string[]; readonly license?: string; readonly maintainers?: readonly Person[]; readonly readme?: string; readonly readmeFilename?: string; readonly repository?: {readonly type: string; readonly url: string}; } interface FullMetadata extends AbbreviatedMetadata, HoistedData { readonly _id: string; readonly _rev: string; readonly time: { readonly created: string; readonly modified: string; readonly [version: string]: string; }; readonly users?: {readonly [user: string]: boolean}; readonly versions: {readonly [version: string]: FullVersion}; readonly [key: string]: unknown; } interface FullVersion extends AbbreviatedVersion, HoistedData { readonly _id: string; readonly _nodeVersion: string; readonly _npmUser: string; readonly _npmVersion: string; readonly main?: string; readonly files?: readonly string[]; readonly man?: readonly string[]; readonly scripts?: {readonly [scriptName: string]: string}; readonly gitHead?: string; readonly types?: string; readonly typings?: string; readonly [key: string]: unknown; } type VersionNotFoundError = VersionNotFoundErrorClass; type PackageNotFoundError = PackageNotFoundErrorClass; } declare const packageJson: { /** Get metadata of a package from the npm registry. @param packageName - Name of the package. @example ``` import packageJson = require('package-json'); (async () => { console.log(await packageJson('ava')); //=> {name: 'ava', ...} // Also works with scoped packages console.log(await packageJson('@sindresorhus/df')); })(); ``` */ (packageName: string, options: packageJson.FullMetadataOptions): Promise< packageJson.FullMetadata >; (packageName: string, options?: packageJson.Options): Promise< packageJson.AbbreviatedMetadata >; /** The error thrown when the given package version cannot be found. */ VersionNotFoundError: typeof VersionNotFoundErrorClass; /** The error thrown when the given package name cannot be found. */ PackageNotFoundError: typeof PackageNotFoundErrorClass; // TODO: remove this in the next major version default: typeof packageJson; }; export = packageJson; package-json-6.5.0/index.js000066400000000000000000000053451351553356200155500ustar00rootroot00000000000000'use strict'; const {URL} = require('url'); const {Agent: HttpAgent} = require('http'); const {Agent: HttpsAgent} = require('https'); const got = require('got'); const registryUrl = require('registry-url'); const registryAuthToken = require('registry-auth-token'); const semver = require('semver'); // These agent options are chosen to match the npm client defaults and help with performance // See: `npm config get maxsockets` and #50 const agentOptions = { keepAlive: true, maxSockets: 50 }; const httpAgent = new HttpAgent(agentOptions); const httpsAgent = new HttpsAgent(agentOptions); class PackageNotFoundError extends Error { constructor(packageName) { super(`Package \`${packageName}\` could not be found`); this.name = 'PackageNotFoundError'; } } class VersionNotFoundError extends Error { constructor(packageName, version) { super(`Version \`${version}\` for package \`${packageName}\` could not be found`); this.name = 'VersionNotFoundError'; } } const packageJson = async (packageName, options) => { options = { version: 'latest', ...options }; const scope = packageName.split('/')[0]; const registryUrl_ = options.registryUrl || registryUrl(scope); const packageUrl = new URL(encodeURIComponent(packageName).replace(/^%40/, '@'), registryUrl_); const authInfo = registryAuthToken(registryUrl_.toString(), {recursive: true}); const headers = { accept: 'application/vnd.npm.install-v1+json; q=1.0, application/json; q=0.8, */*' }; if (options.fullMetadata) { delete headers.accept; } if (authInfo) { headers.authorization = `${authInfo.type} ${authInfo.token}`; } const gotOptions = { json: true, headers, agent: { http: httpAgent, https: httpsAgent } }; if (options.agent) { gotOptions.agent = options.agent; } let response; try { response = await got(packageUrl, gotOptions); } catch (error) { if (error.statusCode === 404) { throw new PackageNotFoundError(packageName); } throw error; } let data = response.body; if (options.allVersions) { return data; } let {version} = options; const versionError = new VersionNotFoundError(packageName, version); if (data['dist-tags'][version]) { data = data.versions[data['dist-tags'][version]]; } else if (version) { if (!data.versions[version]) { const versions = Object.keys(data.versions); version = semver.maxSatisfying(versions, version); if (!version) { throw versionError; } } data = data.versions[version]; if (!data) { throw versionError; } } return data; }; module.exports = packageJson; // TODO: remove this in the next major version module.exports.default = packageJson; module.exports.PackageNotFoundError = PackageNotFoundError; module.exports.VersionNotFoundError = VersionNotFoundError; package-json-6.5.0/index.test-d.ts000066400000000000000000000024311351553356200167520ustar00rootroot00000000000000import {expectType} from 'tsd'; import packageJson = require('.'); import { FullMetadata, FullVersion, AbbreviatedMetadata, AbbreviatedVersion, PackageNotFoundError, VersionNotFoundError } from '.'; expectType>(packageJson('package-json')); expectType>( packageJson('package-json', {version: '1.2.3'}) ); expectType>( packageJson('package-json', {allVersions: true}) ); expectType>( packageJson('package-json', {fullMetadata: true}) ); const abbreviatedMetadata = await packageJson('package-json'); expectType(abbreviatedMetadata.versions['1.2.3']); const fullMetadata = await packageJson('package-json', {fullMetadata: true}); expectType(fullMetadata.versions['1.2.3']); expectType(PackageNotFoundError); expectType(VersionNotFoundError); const packageNotFoundError = new PackageNotFoundError('foo'); packageNotFoundError instanceof PackageNotFoundError; expectType(packageNotFoundError); const versionNotFoundError = new VersionNotFoundError('foo', 'bar'); versionNotFoundError instanceof VersionNotFoundError; expectType(versionNotFoundError); package-json-6.5.0/license000066400000000000000000000021251351553356200154410ustar00rootroot00000000000000MIT License Copyright (c) Sindre Sorhus (sindresorhus.com) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. package-json-6.5.0/package.json000066400000000000000000000014551351553356200163670ustar00rootroot00000000000000{ "name": "package-json", "version": "6.5.0", "description": "Get metadata of a package from the npm registry", "license": "MIT", "repository": "sindresorhus/package-json", "author": { "name": "Sindre Sorhus", "email": "sindresorhus@gmail.com", "url": "sindresorhus.com" }, "engines": { "node": ">=8" }, "scripts": { "test": "xo && ava && tsd" }, "files": [ "index.js", "index.d.ts" ], "keywords": [ "npm", "registry", "package", "pkg", "package.json", "json", "module", "scope", "scoped" ], "dependencies": { "got": "^9.6.0", "registry-auth-token": "^4.0.0", "registry-url": "^5.0.0", "semver": "^6.2.0" }, "devDependencies": { "@types/node": "^12.6.8", "ava": "^2.2.0", "mock-private-registry": "^1.1.2", "tsd": "^0.7.4", "xo": "^0.24.0" } } package-json-6.5.0/readme.md000066400000000000000000000067551351553356200156700ustar00rootroot00000000000000# package-json [![Build Status](https://travis-ci.org/sindresorhus/package-json.svg?branch=master)](https://travis-ci.org/sindresorhus/package-json) > Get metadata of a package from the npm registry ## Install ``` $ npm install package-json ``` ## Usage ```js const packageJson = require('package-json'); (async () => { console.log(await packageJson('ava')); //=> {name: 'ava', ...} // Also works with scoped packages console.log(await packageJson('@sindresorhus/df')); })(); ``` ## API ### packageJson(packageName, options?) #### packageName Type: `string` Name of the package. #### options Type: `object` ##### version Type: `string`
Default: `latest` Package version such as `1.0.0` or a [dist tag](https://docs.npmjs.com/cli/dist-tag) such as `latest`. The version can also be in any format supported by the [semver](https://github.com/npm/node-semver) module. For example: - `1` - Get the latest `1.x.x` - `1.2` - Get the latest `1.2.x` - `^1.2.3` - Get the latest `1.x.x` but at least `1.2.3` - `~1.2.3` - Get the latest `1.2.x` but at least `1.2.3` ##### fullMetadata Type: `boolean`
Default: `false` By default, only an abbreviated metadata object is returned for performance reasons. [Read more.](https://github.com/npm/registry/blob/master/docs/responses/package-metadata.md) ##### allVersions Type: `boolean`
Default: `false` Return the [main entry](https://registry.npmjs.org/ava) containing all versions. ##### registryUrl Type: `string`
Default: Auto-detected The registry URL is by default inferred from the npm defaults and `.npmrc`. This is beneficial as `package-json` and any project using it will work just like npm. This option is **only** intended for internal tools. You should **not** use this option in reusable packages. Prefer just using `.npmrc` whenever possible. ##### agent Type: `http.Agent | https.Agent | object | false` Overwrite the `agent` option that is passed down to [`got`](https://github.com/sindresorhus/got#agent). This might be useful to add [proxy support](https://github.com/sindresorhus/got#proxies). ### packageJson.PackageNotFoundError The error thrown when the given package name cannot be found. ### packageJson.VersionNotFoundError The error thrown when the given package version cannot be found. ## Authentication Both public and private registries are supported, for both scoped and unscoped packages, as long as the registry uses either bearer tokens or basic authentication. ## Related - [package-json-cli](https://github.com/sindresorhus/package-json-cli) - CLI for this module - [latest-version](https://github.com/sindresorhus/latest-version) - Get the latest version of an npm package - [pkg-versions](https://github.com/sindresorhus/pkg-versions) - Get the version numbers of a package from the npm registry - [npm-keyword](https://github.com/sindresorhus/npm-keyword) - Get a list of npm packages with a certain keyword - [npm-user](https://github.com/sindresorhus/npm-user) - Get user info of an npm user - [npm-email](https://github.com/sindresorhus/npm-email) - Get the email of an npm user ---
Get professional support for this package with a Tidelift subscription
Tidelift helps make open source sustainable for maintainers while giving companies
assurances about security, maintenance, and licensing for their dependencies.
package-json-6.5.0/test.js000066400000000000000000000065111351553356200154140ustar00rootroot00000000000000import {promisify} from 'util'; import http from 'http'; import test from 'ava'; import privateRegistry from 'mock-private-registry/promise'; import packageJson from '.'; test('latest version', async t => { const json = await packageJson('ava'); t.is(json.name, 'ava'); t.falsy(json.versions); }); test('full metadata', async t => { const json = await packageJson('pageres', { fullMetadata: true, version: '4.4.0' }); t.is(json.name, 'pageres'); t.is(json._id, 'pageres@4.4.0'); }); test('all version', async t => { const json = await packageJson('pageres', {allVersions: true}); t.is(json.name, 'pageres'); t.is(json.versions['0.1.0'].name, 'pageres'); }); test('specific version', async t => { const json = await packageJson('pageres', {version: '0.1.0'}); t.is(json.version, '0.1.0'); }); test('incomplete version x', async t => { const json = await packageJson('pageres', {version: '0'}); t.is(json.version.substr(0, 2), '0.'); }); test.failing('custom registry url', async t => { const json = await packageJson('ava', {registryUrl: 'http://registry.node-modules.io/'}); t.is(json.name, 'ava'); t.falsy(json.versions); }); test('scoped - latest version', async t => { const json = await packageJson('@sindresorhus/df'); t.is(json.name, '@sindresorhus/df'); }); test('scoped - full metadata', async t => { const json = await packageJson('@sindresorhus/df', { fullMetadata: true, version: '1.0.1' }); t.is(json.name, '@sindresorhus/df'); t.is(json._id, '@sindresorhus/df@1.0.1'); }); test('scoped - all version', async t => { const json = await packageJson('@sindresorhus/df', {allVersions: true}); t.is(json.name, '@sindresorhus/df'); t.is(json.versions['1.0.1'].name, '@sindresorhus/df'); }); test('scoped - specific version', async t => { const json = await packageJson('@sindresorhus/df', {version: '1.0.1'}); t.is(json.version, '1.0.1'); }); test('scoped - dist tag', async t => { const json = await packageJson('@rexxars/npmtest', {version: 'next'}); t.is(json.version, '2.0.0'); }); test('reject when package doesn\'t exist', async t => { await t.throwsAsync(packageJson('nnnope'), {instanceOf: packageJson.PackageNotFoundError}); }); test('reject when version doesn\'t exist', async t => { await t.throwsAsync(packageJson('hapi', {version: '6.6.6'}), {instanceOf: packageJson.VersionNotFoundError}); }); test('does not send any auth token for unconfigured registries', async t => { const server = http.createServer((request, response) => { response.end(JSON.stringify({headers: request.headers, 'dist-tags': {}})); }); await promisify(server.listen.bind(server))(63144, '127.0.0.1'); const json = await packageJson('@mockscope3/foobar', {allVersions: true}); t.is(json.headers.host, 'localhost:63144'); t.is(json.headers.authorization, undefined); await promisify(server.close.bind(server))(); }); test('private registry (bearer token)', async t => { const server = await privateRegistry(); const json = await packageJson('@mockscope/foobar'); t.is(json.name, '@mockscope/foobar'); server.close(); }); test('private registry (basic token)', async t => { const server = await privateRegistry({ port: 63143, pkgName: '@mockscope2/foobar', token: 'QWxhZGRpbjpPcGVuU2VzYW1l', tokenType: 'Basic' }); const json = await packageJson('@mockscope2/foobar'); t.is(json.name, '@mockscope2/foobar'); server.close(); });