-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[NpmUnpackedSize] Unpacked Size Badge (#9954)
* init npm-unpacked-size service * add sample badge * fetch unpacked size from latest version * format unpacked size * parametrize unpacked size by package name * add optional version parameter * fix typo on test * rename test to tester * test against json endpoint instead of svg * test and impl version with undefined unpacked size * test version with defined unpacked size * change color to lightgray when unpackedSize is undefined * add openapi docs * extend NpmBase instead of BaseJsonService * use isFileSize validator * add schema to validate npm registry response body * add tests for scoped packages * impl scoped package route * change the type of schema.dist.unpackedSize to optionalNonNegativeInteger * add registry_uri query param * add default label to badge * unpack tag instead of version * revert back to versions instead of tags
- Loading branch information
Showing
2 changed files
with
115 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
import Joi from 'joi' | ||
import prettyBytes from 'pretty-bytes' | ||
import { pathParam, queryParam } from '../index.js' | ||
import { optionalNonNegativeInteger } from '../validators.js' | ||
import NpmBase, { packageNameDescription } from './npm-base.js' | ||
|
||
const schema = Joi.object({ | ||
dist: Joi.object({ | ||
unpackedSize: optionalNonNegativeInteger, | ||
}).required(), | ||
}).required() | ||
|
||
export default class NpmUnpackedSize extends NpmBase { | ||
static category = 'size' | ||
|
||
static route = { | ||
base: 'npm/unpacked-size', | ||
pattern: ':scope(@[^/]+)?/:packageName/:version*', | ||
} | ||
|
||
static openApi = { | ||
'/npm/unpacked-size/{packageName}': { | ||
get: { | ||
summary: 'NPM Unpacked Size', | ||
parameters: [ | ||
pathParam({ | ||
name: 'packageName', | ||
example: 'npm', | ||
description: packageNameDescription, | ||
}), | ||
queryParam({ | ||
name: 'registry_uri', | ||
example: 'https://registry.npmjs.com', | ||
}), | ||
], | ||
}, | ||
}, | ||
'/npm/unpacked-size/{packageName}/{version}': { | ||
get: { | ||
summary: 'NPM Unpacked Size (with version)', | ||
parameters: [ | ||
pathParam({ | ||
name: 'packageName', | ||
example: 'npm', | ||
description: packageNameDescription, | ||
}), | ||
pathParam({ | ||
name: 'version', | ||
example: '4.18.2', | ||
}), | ||
queryParam({ | ||
name: 'registry_uri', | ||
example: 'https://registry.npmjs.com', | ||
}), | ||
], | ||
}, | ||
}, | ||
} | ||
|
||
static defaultBadgeData = { label: 'unpacked size' } | ||
|
||
async fetch({ registryUrl, packageName, version }) { | ||
return this._requestJson({ | ||
schema, | ||
url: `${registryUrl}/${packageName}/${version}`, | ||
}) | ||
} | ||
|
||
async handle( | ||
{ scope, packageName, version }, | ||
{ registry_uri: registryUrl = 'https://registry.npmjs.org' }, | ||
) { | ||
const packageNameWithScope = scope ? `${scope}/${packageName}` : packageName | ||
const { dist } = await this.fetch({ | ||
registryUrl, | ||
packageName: packageNameWithScope, | ||
version: version ?? 'latest', | ||
}) | ||
const { unpackedSize } = dist | ||
|
||
return { | ||
label: 'unpacked size', | ||
message: unpackedSize ? prettyBytes(unpackedSize) : 'unknown', | ||
color: unpackedSize ? 'blue' : 'lightgray', | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import { isFileSize } from '../test-validators.js' | ||
import { createServiceTester } from '../tester.js' | ||
|
||
export const t = await createServiceTester() | ||
|
||
t.create('Latest unpacked size') | ||
.get('/firereact.json') | ||
.expectBadge({ label: 'unpacked size', message: isFileSize }) | ||
|
||
t.create('Nonexistent unpacked size with version') | ||
.get('/express/4.16.0.json') | ||
.expectBadge({ label: 'unpacked size', message: 'unknown' }) | ||
|
||
t.create('Unpacked size with version') | ||
.get('/firereact/0.7.0.json') | ||
.expectBadge({ label: 'unpacked size', message: '147 kB' }) | ||
|
||
t.create('Unpacked size for scoped package') | ||
.get('/@testing-library/react.json') | ||
.expectBadge({ label: 'unpacked size', message: isFileSize }) | ||
|
||
t.create('Unpacked size for scoped package with version') | ||
.get('/@testing-library/react/14.2.1.json') | ||
.expectBadge({ label: 'unpacked size', message: '5.41 MB' }) | ||
|
||
t.create('Nonexistent unpacked size for scoped package with version') | ||
.get('/@cycle/rx-run/7.2.0.json') | ||
.expectBadge({ label: 'unpacked size', message: 'unknown' }) |