pax_global_header 0000666 0000000 0000000 00000000064 13515533562 0014522 g ustar 00root root 0000000 0000000 52 comment=6e7a2ae1cd053465e0dd2b8653f8c90d712c66c6
package-json-6.5.0/ 0000775 0000000 0000000 00000000000 13515533562 0014074 5 ustar 00root root 0000000 0000000 package-json-6.5.0/.editorconfig 0000664 0000000 0000000 00000000257 13515533562 0016555 0 ustar 00root root 0000000 0000000 root = 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/.gitattributes 0000664 0000000 0000000 00000000023 13515533562 0016762 0 ustar 00root root 0000000 0000000 * text=auto eol=lf
package-json-6.5.0/.github/ 0000775 0000000 0000000 00000000000 13515533562 0015434 5 ustar 00root root 0000000 0000000 package-json-6.5.0/.github/funding.yml 0000664 0000000 0000000 00000000166 13515533562 0017614 0 ustar 00root root 0000000 0000000 github: sindresorhus
open_collective: sindresorhus
tidelift: npm/package-json
custom: https://sindresorhus.com/donate
package-json-6.5.0/.github/security.md 0000664 0000000 0000000 00000000263 13515533562 0017626 0 ustar 00root root 0000000 0000000 # 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/.gitignore 0000664 0000000 0000000 00000000027 13515533562 0016063 0 ustar 00root root 0000000 0000000 node_modules
yarn.lock
package-json-6.5.0/.npmrc 0000664 0000000 0000000 00000000427 13515533562 0015217 0 ustar 00root root 0000000 0000000 package-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.yml 0000664 0000000 0000000 00000000065 13515533562 0016206 0 ustar 00root root 0000000 0000000 language: node_js
node_js:
- '12'
- '10'
- '8'
package-json-6.5.0/index.d.ts 0000664 0000000 0000000 00000013561 13515533562 0016003 0 ustar 00root root 0000000 0000000 ///
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.js 0000664 0000000 0000000 00000005345 13515533562 0015550 0 ustar 00root root 0000000 0000000 '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.ts 0000664 0000000 0000000 00000002431 13515533562 0016752 0 ustar 00root root 0000000 0000000 import {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/license 0000664 0000000 0000000 00000002125 13515533562 0015441 0 ustar 00root root 0000000 0000000 MIT 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.json 0000664 0000000 0000000 00000001455 13515533562 0016367 0 ustar 00root root 0000000 0000000 {
"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.md 0000664 0000000 0000000 00000006755 13515533562 0015670 0 ustar 00root root 0000000 0000000 # package-json [](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
---
package-json-6.5.0/test.js 0000664 0000000 0000000 00000006511 13515533562 0015414 0 ustar 00root root 0000000 0000000 import {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();
});