Skip to content

Commit

Permalink
Omit deprecated versions by default (#77)
Browse files Browse the repository at this point in the history
  • Loading branch information
tommy-mitchell authored Feb 21, 2024
1 parent b4ee1c7 commit 2238f3f
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 7 deletions.
9 changes: 9 additions & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,15 @@ export type Options = {
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;

/**
Whether or not to omit deprecated versions of a package.
If set, versions marked as deprecated on the registry are omitted from results. Providing a dist tag or a specific version will still return that version, even if it's deprecated. If no version can be found once deprecated versions are omitted, a `VersionNotFoundError` is thrown.
@default true
*/
readonly omitDeprecated?: boolean;
};

export type FullMetadataOptions = {
Expand Down
13 changes: 12 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export class VersionNotFoundError extends Error {
export default async function packageJson(packageName, options) {
options = {
version: 'latest',
omitDeprecated: true,
...options,
};

Expand Down Expand Up @@ -63,7 +64,17 @@ export default async function packageJson(packageName, options) {
data = data.versions[data['dist-tags'][version]];
data.time = time;
} else if (version) {
if (!data.versions[version]) {
const versionExists = Boolean(data.versions[version]);

if (options.omitDeprecated && !versionExists) {
for (const [metadataVersion, metadata] of Object.entries(data.versions)) {
if (metadata.deprecated) {
delete data.versions[metadataVersion];
}
}
}

if (!versionExists) {
const versions = Object.keys(data.versions);
version = semver.maxSatisfying(versions, version);

Expand Down
9 changes: 9 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,15 @@ 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.

##### omitDeprecated

Type: `boolean`\
Default: `true`

Whether or not to omit deprecated versions of a package.

If set, versions marked as deprecated on the registry are omitted from results. Providing a dist tag or a specific version will still return that version, even if it's deprecated. If no version can be found once deprecated versions are omitted, a [`VersionNotFoundError`](#versionnotfounderror) is thrown.

### PackageNotFoundError

The error thrown when the given package name cannot be found.
Expand Down
61 changes: 55 additions & 6 deletions test.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,14 @@ test('incomplete version x', async t => {
t.is(json.version.slice(0, 2), '0.');
});

// TODO: Find an alternative npm instance.
// test.failing('custom registry url', async t => {
// const json = await packageJson('ava', {registryUrl: 'https://npm.open-registry.dev/'});
// t.is(json.name, 'ava');
// t.falsy(json.versions);
// });
test('custom registry url', async t => {
const json = await packageJson('ava', {registryUrl: 'https://registry.yarnpkg.com'});

t.like(json, {
name: 'ava',
versions: undefined,
});
});

test('scoped - latest version', async t => {
const json = await packageJson('@sindresorhus/df');
Expand Down Expand Up @@ -164,3 +166,50 @@ test('private registry (basic token)', async t => {

server.close();
});

test('omits deprecated versions by default', async t => {
const json = await packageJson('ng-packagr', {version: '14'});

t.like(json, {
name: 'ng-packagr',
version: '14.2.2',
deprecated: undefined,
});
});

test('optionally includes deprecated versions', async t => {
const json = await packageJson('ng-packagr', {version: '14', omitDeprecated: false});

t.like(json, {
name: 'ng-packagr',
version: '14.3.0',
deprecated: 'this package version has been deprecated as it was released by mistake',
});
});

test('errors if all versions are deprecated', async t => {
await t.throwsAsync(
packageJson('querystring', {version: '0'}),
{instanceOf: VersionNotFoundError},
);
});

test('does not omit specific deprecated dist tags', async t => {
const json = await packageJson('querystring', {version: 'latest'});

t.like(json, {
name: 'querystring',
version: '0.2.1',
deprecated: 'The querystring API is considered Legacy. new code should use the URLSearchParams API instead.',
});
});

test('does not omit specific deprecated versions', async t => {
const json = await packageJson('ng-packagr', {version: '14.3.0'});

t.like(json, {
name: 'ng-packagr',
version: '14.3.0',
deprecated: 'this package version has been deprecated as it was released by mistake',
});
});

0 comments on commit 2238f3f

Please sign in to comment.