Add ability to format bytes as metric or IEC; affects [bundlejs bundlephobia ChromeWebStoreSize CratesSize DockerSize GithubRepoSize GithubCodeSize GithubSize NpmUnpackedSize SpigetDownloadSize steam VisualStudioAppCenterReleasesSize whatpulse] (#10547)
* add renderSizeBadge helper, use it everywhere - switch from pretty-bytes to byte-size - add renderSizeBadge() helper function - match upstream conventions for metric/IEC units - add new test helpers and use them in service tests * unrelated: fix npm unpacked size query param schema not strictly related to this PR but I noticed it was broken * chromewebstore: reformat size string, test against isIecFileSize
This commit is contained in:
21
package-lock.json
generated
21
package-lock.json
generated
@@ -15,6 +15,7 @@
|
|||||||
"@shields_io/camp": "^18.1.2",
|
"@shields_io/camp": "^18.1.2",
|
||||||
"@xmldom/xmldom": "0.9.5",
|
"@xmldom/xmldom": "0.9.5",
|
||||||
"badge-maker": "file:badge-maker",
|
"badge-maker": "file:badge-maker",
|
||||||
|
"byte-size": "^9.0.0",
|
||||||
"bytes": "^3.1.2",
|
"bytes": "^3.1.2",
|
||||||
"camelcase": "^8.0.0",
|
"camelcase": "^8.0.0",
|
||||||
"chalk": "^5.3.0",
|
"chalk": "^5.3.0",
|
||||||
@@ -45,7 +46,6 @@
|
|||||||
"parse-link-header": "^2.0.0",
|
"parse-link-header": "^2.0.0",
|
||||||
"path-to-regexp": "^6.3.0",
|
"path-to-regexp": "^6.3.0",
|
||||||
"pg": "^8.13.1",
|
"pg": "^8.13.1",
|
||||||
"pretty-bytes": "^6.1.1",
|
|
||||||
"priorityqueuejs": "^2.0.0",
|
"priorityqueuejs": "^2.0.0",
|
||||||
"prom-client": "^15.1.3",
|
"prom-client": "^15.1.3",
|
||||||
"qs": "^6.13.1",
|
"qs": "^6.13.1",
|
||||||
@@ -8132,6 +8132,14 @@
|
|||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/byte-size": {
|
||||||
|
"version": "9.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/byte-size/-/byte-size-9.0.0.tgz",
|
||||||
|
"integrity": "sha512-xrJ8Hki7eQ6xew55mM6TG9zHI852OoAHcPfduWWtR6yxk2upTuIZy13VioRBDyHReHDdbeDPifUboeNkK/sXXA==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12.17"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/bytes": {
|
"node_modules/bytes": {
|
||||||
"version": "3.1.2",
|
"version": "3.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
|
||||||
@@ -24578,17 +24586,6 @@
|
|||||||
"url": "https://github.com/prettier/prettier?sponsor=1"
|
"url": "https://github.com/prettier/prettier?sponsor=1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/pretty-bytes": {
|
|
||||||
"version": "6.1.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-6.1.1.tgz",
|
|
||||||
"integrity": "sha512-mQUvGU6aUFQ+rNvTIAcZuWGRT9a6f6Yrg9bHs4ImKF+HZCEK+plBvnAZYSIQztknZF2qnzNtr6F8s0+IuptdlQ==",
|
|
||||||
"engines": {
|
|
||||||
"node": "^14.13.1 || >=16.0.0"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/sponsors/sindresorhus"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/pretty-error": {
|
"node_modules/pretty-error": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-4.0.0.tgz",
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
"@shields_io/camp": "^18.1.2",
|
"@shields_io/camp": "^18.1.2",
|
||||||
"@xmldom/xmldom": "0.9.5",
|
"@xmldom/xmldom": "0.9.5",
|
||||||
"badge-maker": "file:badge-maker",
|
"badge-maker": "file:badge-maker",
|
||||||
|
"byte-size": "^9.0.0",
|
||||||
"bytes": "^3.1.2",
|
"bytes": "^3.1.2",
|
||||||
"camelcase": "^8.0.0",
|
"camelcase": "^8.0.0",
|
||||||
"chalk": "^5.3.0",
|
"chalk": "^5.3.0",
|
||||||
@@ -57,7 +58,6 @@
|
|||||||
"parse-link-header": "^2.0.0",
|
"parse-link-header": "^2.0.0",
|
||||||
"path-to-regexp": "^6.3.0",
|
"path-to-regexp": "^6.3.0",
|
||||||
"pg": "^8.13.1",
|
"pg": "^8.13.1",
|
||||||
"pretty-bytes": "^6.1.1",
|
|
||||||
"priorityqueuejs": "^2.0.0",
|
"priorityqueuejs": "^2.0.0",
|
||||||
"prom-client": "^15.1.3",
|
"prom-client": "^15.1.3",
|
||||||
"qs": "^6.13.1",
|
"qs": "^6.13.1",
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
import Joi from 'joi'
|
import Joi from 'joi'
|
||||||
import { BaseJsonService, pathParam, queryParam } from '../index.js'
|
import { BaseJsonService, pathParam, queryParam } from '../index.js'
|
||||||
|
import { renderSizeBadge } from '../size.js'
|
||||||
|
import { nonNegativeInteger } from '../validators.js'
|
||||||
|
|
||||||
const schema = Joi.object({
|
const schema = Joi.object({
|
||||||
size: Joi.object({
|
size: Joi.object({
|
||||||
compressedSize: Joi.string().required(),
|
rawCompressedSize: nonNegativeInteger,
|
||||||
}).required(),
|
}).required(),
|
||||||
}).required()
|
}).required()
|
||||||
|
|
||||||
@@ -76,13 +78,6 @@ export default class BundlejsPackage extends BaseJsonService {
|
|||||||
|
|
||||||
static defaultBadgeData = { label: 'bundlejs', color: 'informational' }
|
static defaultBadgeData = { label: 'bundlejs', color: 'informational' }
|
||||||
|
|
||||||
static render({ size }) {
|
|
||||||
return {
|
|
||||||
label: 'minified size (gzip)',
|
|
||||||
message: size,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async fetch({ scope, packageName, exports }) {
|
async fetch({ scope, packageName, exports }) {
|
||||||
const searchParams = {
|
const searchParams = {
|
||||||
q: `${scope ? `${scope}/` : ''}${packageName}`,
|
q: `${scope ? `${scope}/` : ''}${packageName}`,
|
||||||
@@ -110,7 +105,7 @@ export default class BundlejsPackage extends BaseJsonService {
|
|||||||
|
|
||||||
async handle({ scope, packageName }, { exports }) {
|
async handle({ scope, packageName }, { exports }) {
|
||||||
const json = await this.fetch({ scope, packageName, exports })
|
const json = await this.fetch({ scope, packageName, exports })
|
||||||
const size = json.size.compressedSize
|
const size = json.size.rawCompressedSize
|
||||||
return this.constructor.render({ size })
|
return renderSizeBadge(size, 'metric', 'minified size (gzip)')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,26 +1,26 @@
|
|||||||
import { isFileSize } from '../test-validators.js'
|
import { isMetricFileSize } from '../test-validators.js'
|
||||||
import { createServiceTester } from '../tester.js'
|
import { createServiceTester } from '../tester.js'
|
||||||
export const t = await createServiceTester()
|
export const t = await createServiceTester()
|
||||||
|
|
||||||
t.create('bundlejs/package (packageName)')
|
t.create('bundlejs/package (packageName)')
|
||||||
.get('/jquery.json')
|
.get('/jquery.json')
|
||||||
.expectBadge({ label: 'minified size (gzip)', message: isFileSize })
|
.expectBadge({ label: 'minified size (gzip)', message: isMetricFileSize })
|
||||||
|
|
||||||
t.create('bundlejs/package (version)')
|
t.create('bundlejs/package (version)')
|
||||||
.get('/react@18.2.0.json')
|
.get('/react@18.2.0.json')
|
||||||
.expectBadge({ label: 'minified size (gzip)', message: isFileSize })
|
.expectBadge({ label: 'minified size (gzip)', message: isMetricFileSize })
|
||||||
|
|
||||||
t.create('bundlejs/package (scoped)')
|
t.create('bundlejs/package (scoped)')
|
||||||
.get('/@cycle/rx-run.json')
|
.get('/@cycle/rx-run.json')
|
||||||
.expectBadge({ label: 'minified size (gzip)', message: isFileSize })
|
.expectBadge({ label: 'minified size (gzip)', message: isMetricFileSize })
|
||||||
|
|
||||||
t.create('bundlejs/package (select exports)')
|
t.create('bundlejs/package (select exports)')
|
||||||
.get('/value-enhancer.json?exports=isVal,val')
|
.get('/value-enhancer.json?exports=isVal,val')
|
||||||
.expectBadge({ label: 'minified size (gzip)', message: isFileSize })
|
.expectBadge({ label: 'minified size (gzip)', message: isMetricFileSize })
|
||||||
|
|
||||||
t.create('bundlejs/package (scoped version select exports)')
|
t.create('bundlejs/package (scoped version select exports)')
|
||||||
.get('/@ngneat/falso@6.4.0.json?exports=randEmail,randFullName')
|
.get('/@ngneat/falso@6.4.0.json?exports=randEmail,randFullName')
|
||||||
.expectBadge({ label: 'minified size (gzip)', message: isFileSize })
|
.expectBadge({ label: 'minified size (gzip)', message: isMetricFileSize })
|
||||||
|
|
||||||
t.create('bundlejs/package (not found)')
|
t.create('bundlejs/package (not found)')
|
||||||
.get('/react@18.2.0.json')
|
.get('/react@18.2.0.json')
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import Joi from 'joi'
|
import Joi from 'joi'
|
||||||
import prettyBytes from 'pretty-bytes'
|
import { renderSizeBadge } from '../size.js'
|
||||||
import { nonNegativeInteger } from '../validators.js'
|
import { nonNegativeInteger } from '../validators.js'
|
||||||
import { BaseJsonService, pathParams } from '../index.js'
|
import { BaseJsonService, pathParams } from '../index.js'
|
||||||
|
|
||||||
@@ -112,10 +112,7 @@ export default class Bundlephobia extends BaseJsonService {
|
|||||||
|
|
||||||
static render({ format, size }) {
|
static render({ format, size }) {
|
||||||
const label = format === 'min' ? 'minified size' : 'minzipped size'
|
const label = format === 'min' ? 'minified size' : 'minzipped size'
|
||||||
return {
|
return renderSizeBadge(size, 'iec', label)
|
||||||
label,
|
|
||||||
message: prettyBytes(size),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async fetch({ scope, packageName, version }) {
|
async fetch({ scope, packageName, version }) {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { isFileSize } from '../test-validators.js'
|
import { isIecFileSize } from '../test-validators.js'
|
||||||
import { createServiceTester } from '../tester.js'
|
import { createServiceTester } from '../tester.js'
|
||||||
export const t = await createServiceTester()
|
export const t = await createServiceTester()
|
||||||
|
|
||||||
@@ -13,42 +13,42 @@ const data = [
|
|||||||
{
|
{
|
||||||
format: formats.A,
|
format: formats.A,
|
||||||
get: '/min/preact.json',
|
get: '/min/preact.json',
|
||||||
expect: { label: 'minified size', message: isFileSize },
|
expect: { label: 'minified size', message: isIecFileSize },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
format: formats.B,
|
format: formats.B,
|
||||||
get: '/min/preact/8.0.0.json',
|
get: '/min/preact/8.0.0.json',
|
||||||
expect: { label: 'minified size', message: isFileSize },
|
expect: { label: 'minified size', message: isIecFileSize },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
format: formats.C,
|
format: formats.C,
|
||||||
get: '/min/@cycle/core.json',
|
get: '/min/@cycle/core.json',
|
||||||
expect: { label: 'minified size', message: isFileSize },
|
expect: { label: 'minified size', message: isIecFileSize },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
format: formats.D,
|
format: formats.D,
|
||||||
get: '/min/@cycle/core/7.0.0.json',
|
get: '/min/@cycle/core/7.0.0.json',
|
||||||
expect: { label: 'minified size', message: isFileSize },
|
expect: { label: 'minified size', message: isIecFileSize },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
format: formats.A,
|
format: formats.A,
|
||||||
get: '/minzip/preact.json',
|
get: '/minzip/preact.json',
|
||||||
expect: { label: 'minzipped size', message: isFileSize },
|
expect: { label: 'minzipped size', message: isIecFileSize },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
format: formats.B,
|
format: formats.B,
|
||||||
get: '/minzip/preact/8.0.0.json',
|
get: '/minzip/preact/8.0.0.json',
|
||||||
expect: { label: 'minzipped size', message: isFileSize },
|
expect: { label: 'minzipped size', message: isIecFileSize },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
format: formats.C,
|
format: formats.C,
|
||||||
get: '/minzip/@cycle/core.json',
|
get: '/minzip/@cycle/core.json',
|
||||||
expect: { label: 'minzipped size', message: isFileSize },
|
expect: { label: 'minzipped size', message: isIecFileSize },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
format: formats.D,
|
format: formats.D,
|
||||||
get: '/minzip/@cycle/core/7.0.0.json',
|
get: '/minzip/@cycle/core/7.0.0.json',
|
||||||
expect: { label: 'minzipped size', message: isFileSize },
|
expect: { label: 'minzipped size', message: isIecFileSize },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
format: formats.A,
|
format: formats.A,
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { NotFound, pathParams } from '../index.js'
|
import { InvalidResponse, NotFound, pathParams } from '../index.js'
|
||||||
import BaseChromeWebStoreService from './chrome-web-store-base.js'
|
import BaseChromeWebStoreService from './chrome-web-store-base.js'
|
||||||
|
|
||||||
export default class ChromeWebStoreSize extends BaseChromeWebStoreService {
|
export default class ChromeWebStoreSize extends BaseChromeWebStoreService {
|
||||||
@@ -22,6 +22,17 @@ export default class ChromeWebStoreSize extends BaseChromeWebStoreService {
|
|||||||
color: 'blue',
|
color: 'blue',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
transform(sizeStr) {
|
||||||
|
const match = sizeStr.match(/^(\d+)([a-zA-Z]+)$/)
|
||||||
|
if (!match) {
|
||||||
|
throw new InvalidResponse({
|
||||||
|
prettyMessage: 'size does not match expected format',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
const [, size, units] = match
|
||||||
|
return `${size} ${units}`
|
||||||
|
}
|
||||||
|
|
||||||
async handle({ storeId }) {
|
async handle({ storeId }) {
|
||||||
const chromeWebStore = await this.fetch({ storeId })
|
const chromeWebStore = await this.fetch({ storeId })
|
||||||
const size = chromeWebStore.size()
|
const size = chromeWebStore.size()
|
||||||
@@ -30,6 +41,6 @@ export default class ChromeWebStoreSize extends BaseChromeWebStoreService {
|
|||||||
throw new NotFound({ prettyMessage: 'not found' })
|
throw new NotFound({ prettyMessage: 'not found' })
|
||||||
}
|
}
|
||||||
|
|
||||||
return { message: size }
|
return { message: this.transform(size) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import { createServiceTester } from '../tester.js'
|
import { createServiceTester } from '../tester.js'
|
||||||
|
import { isIecFileSize } from '../test-validators.js'
|
||||||
|
|
||||||
export const t = await createServiceTester()
|
export const t = await createServiceTester()
|
||||||
const isFileSize = /^\d+(\.\d+)?(MiB|KiB)$/
|
|
||||||
|
|
||||||
t.create('Size').get('/nccfelhkfpbnefflolffkclhenplhiab.json').expectBadge({
|
t.create('Size').get('/nccfelhkfpbnefflolffkclhenplhiab.json').expectBadge({
|
||||||
label: 'extension size',
|
label: 'extension size',
|
||||||
message: isFileSize,
|
message: isIecFileSize,
|
||||||
})
|
})
|
||||||
|
|
||||||
t.create('Size (not found)')
|
t.create('Size (not found)')
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import prettyBytes from 'pretty-bytes'
|
|
||||||
import { pathParams } from '../index.js'
|
import { pathParams } from '../index.js'
|
||||||
|
import { renderSizeBadge } from '../size.js'
|
||||||
import { BaseCratesService, description } from './crates-base.js'
|
import { BaseCratesService, description } from './crates-base.js'
|
||||||
|
|
||||||
export default class CratesSize extends BaseCratesService {
|
export default class CratesSize extends BaseCratesService {
|
||||||
@@ -38,17 +38,9 @@ export default class CratesSize extends BaseCratesService {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
render({ size }) {
|
|
||||||
return {
|
|
||||||
label: 'size',
|
|
||||||
message: prettyBytes(size),
|
|
||||||
color: 'blue',
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async handle({ crate, version }) {
|
async handle({ crate, version }) {
|
||||||
const json = await this.fetch({ crate, version })
|
const json = await this.fetch({ crate, version })
|
||||||
const size = this.constructor.getVersionObj(json).crate_size
|
const size = this.constructor.getVersionObj(json).crate_size
|
||||||
return this.render({ size })
|
return renderSizeBadge(size, 'iec')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
import { createServiceTester } from '../tester.js'
|
import { createServiceTester } from '../tester.js'
|
||||||
import { isFileSize } from '../test-validators.js'
|
import { isIecFileSize } from '../test-validators.js'
|
||||||
export const t = await createServiceTester()
|
export const t = await createServiceTester()
|
||||||
|
|
||||||
t.create('size')
|
t.create('size')
|
||||||
.get('/tokio.json')
|
.get('/tokio.json')
|
||||||
.expectBadge({ label: 'size', message: isFileSize })
|
.expectBadge({ label: 'size', message: isIecFileSize })
|
||||||
|
|
||||||
t.create('size (with version)')
|
t.create('size (with version)')
|
||||||
.get('/tokio/1.32.0.json')
|
.get('/tokio/1.32.0.json')
|
||||||
.expectBadge({ label: 'size', message: '725 kB' })
|
.expectBadge({ label: 'size', message: '708 KiB' })
|
||||||
|
|
||||||
t.create('size (not found)')
|
t.create('size (not found)')
|
||||||
.get('/not-a-crate.json')
|
.get('/not-a-crate.json')
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import Joi from 'joi'
|
import Joi from 'joi'
|
||||||
import prettyBytes from 'pretty-bytes'
|
import { renderSizeBadge } from '../size.js'
|
||||||
import { nonNegativeInteger } from '../validators.js'
|
import { nonNegativeInteger } from '../validators.js'
|
||||||
import { latest } from '../version.js'
|
import { latest } from '../version.js'
|
||||||
import { BaseJsonService, NotFound, pathParams, queryParams } from '../index.js'
|
import { BaseJsonService, NotFound, pathParams, queryParams } from '../index.js'
|
||||||
@@ -124,10 +124,6 @@ export default class DockerSize extends BaseJsonService {
|
|||||||
|
|
||||||
static defaultBadgeData = { label: 'image size', color: 'blue' }
|
static defaultBadgeData = { label: 'image size', color: 'blue' }
|
||||||
|
|
||||||
static render({ size }) {
|
|
||||||
return { message: prettyBytes(size) }
|
|
||||||
}
|
|
||||||
|
|
||||||
async fetch({ user, repo, tag, page }) {
|
async fetch({ user, repo, tag, page }) {
|
||||||
page = page ? `&page=${page}` : ''
|
page = page ? `&page=${page}` : ''
|
||||||
return await fetch(this, {
|
return await fetch(this, {
|
||||||
@@ -233,6 +229,6 @@ export default class DockerSize extends BaseJsonService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const { size } = await this.transform({ tag, sort, data, arch })
|
const { size } = await this.transform({ tag, sort, data, arch })
|
||||||
return this.constructor.render({ size })
|
return renderSizeBadge(size, 'iec', 'image size')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { isFileSize } from '../test-validators.js'
|
import { isIecFileSize } from '../test-validators.js'
|
||||||
import { createServiceTester } from '../tester.js'
|
import { createServiceTester } from '../tester.js'
|
||||||
export const t = await createServiceTester()
|
export const t = await createServiceTester()
|
||||||
|
|
||||||
@@ -6,35 +6,35 @@ t.create('docker image size (valid, library)')
|
|||||||
.get('/_/alpine.json')
|
.get('/_/alpine.json')
|
||||||
.expectBadge({
|
.expectBadge({
|
||||||
label: 'image size',
|
label: 'image size',
|
||||||
message: isFileSize,
|
message: isIecFileSize,
|
||||||
})
|
})
|
||||||
|
|
||||||
t.create('docker image size (valid, library, arch parameter )')
|
t.create('docker image size (valid, library, arch parameter )')
|
||||||
.get('/_/mysql.json?arch=amd64')
|
.get('/_/mysql.json?arch=amd64')
|
||||||
.expectBadge({
|
.expectBadge({
|
||||||
label: 'image size',
|
label: 'image size',
|
||||||
message: isFileSize,
|
message: isIecFileSize,
|
||||||
})
|
})
|
||||||
|
|
||||||
t.create('docker image size (valid, library with tag)')
|
t.create('docker image size (valid, library with tag)')
|
||||||
.get('/_/alpine/latest.json')
|
.get('/_/alpine/latest.json')
|
||||||
.expectBadge({
|
.expectBadge({
|
||||||
label: 'image size',
|
label: 'image size',
|
||||||
message: isFileSize,
|
message: isIecFileSize,
|
||||||
})
|
})
|
||||||
|
|
||||||
t.create('docker image size (valid, user)')
|
t.create('docker image size (valid, user)')
|
||||||
.get('/jrottenberg/ffmpeg.json')
|
.get('/jrottenberg/ffmpeg.json')
|
||||||
.expectBadge({
|
.expectBadge({
|
||||||
label: 'image size',
|
label: 'image size',
|
||||||
message: isFileSize,
|
message: isIecFileSize,
|
||||||
})
|
})
|
||||||
|
|
||||||
t.create('docker image size (valid, user with tag)')
|
t.create('docker image size (valid, user with tag)')
|
||||||
.get('/jrottenberg/ffmpeg/3.2-alpine.json')
|
.get('/jrottenberg/ffmpeg/3.2-alpine.json')
|
||||||
.expectBadge({
|
.expectBadge({
|
||||||
label: 'image size',
|
label: 'image size',
|
||||||
message: isFileSize,
|
message: isIecFileSize,
|
||||||
})
|
})
|
||||||
|
|
||||||
t.create('docker image size (invalid, incorrect tag)')
|
t.create('docker image size (invalid, incorrect tag)')
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import prettyBytes from 'pretty-bytes'
|
|
||||||
import { pathParams } from '../index.js'
|
import { pathParams } from '../index.js'
|
||||||
|
import { renderSizeBadge } from '../size.js'
|
||||||
import { BaseGithubLanguage } from './github-languages-base.js'
|
import { BaseGithubLanguage } from './github-languages-base.js'
|
||||||
import { documentation } from './github-helpers.js'
|
import { documentation } from './github-helpers.js'
|
||||||
|
|
||||||
@@ -31,15 +31,8 @@ export default class GithubCodeSize extends BaseGithubLanguage {
|
|||||||
|
|
||||||
static defaultBadgeData = { label: 'code size' }
|
static defaultBadgeData = { label: 'code size' }
|
||||||
|
|
||||||
static render({ size }) {
|
|
||||||
return {
|
|
||||||
message: prettyBytes(size),
|
|
||||||
color: 'blue',
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async handle({ user, repo }) {
|
async handle({ user, repo }) {
|
||||||
const data = await this.fetch({ user, repo })
|
const data = await this.fetch({ user, repo })
|
||||||
return this.constructor.render({ size: this.getTotalSize(data) })
|
return renderSizeBadge(this.getTotalSize(data), 'iec', 'code size')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { isFileSize } from '../test-validators.js'
|
import { isIecFileSize } from '../test-validators.js'
|
||||||
import { createServiceTester } from '../tester.js'
|
import { createServiceTester } from '../tester.js'
|
||||||
export const t = await createServiceTester()
|
export const t = await createServiceTester()
|
||||||
|
|
||||||
@@ -6,7 +6,7 @@ t.create('code size in bytes for all languages')
|
|||||||
.get('/badges/shields.json')
|
.get('/badges/shields.json')
|
||||||
.expectBadge({
|
.expectBadge({
|
||||||
label: 'code size',
|
label: 'code size',
|
||||||
message: isFileSize,
|
message: isIecFileSize,
|
||||||
})
|
})
|
||||||
|
|
||||||
t.create('code size in bytes for all languages (empty repo)')
|
t.create('code size in bytes for all languages (empty repo)')
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import Joi from 'joi'
|
import Joi from 'joi'
|
||||||
import prettyBytes from 'pretty-bytes'
|
|
||||||
import { pathParams } from '../index.js'
|
import { pathParams } from '../index.js'
|
||||||
|
import { renderSizeBadge } from '../size.js'
|
||||||
import { nonNegativeInteger } from '../validators.js'
|
import { nonNegativeInteger } from '../validators.js'
|
||||||
import { GithubAuthV3Service } from './github-auth-service.js'
|
import { GithubAuthV3Service } from './github-auth-service.js'
|
||||||
import { documentation, httpErrorsFor } from './github-helpers.js'
|
import { documentation, httpErrorsFor } from './github-helpers.js'
|
||||||
@@ -33,14 +33,6 @@ export default class GithubRepoSize extends GithubAuthV3Service {
|
|||||||
|
|
||||||
static defaultBadgeData = { label: 'repo size' }
|
static defaultBadgeData = { label: 'repo size' }
|
||||||
|
|
||||||
static render({ size }) {
|
|
||||||
return {
|
|
||||||
// note the GH API returns size in Kb
|
|
||||||
message: prettyBytes(size * 1024),
|
|
||||||
color: 'blue',
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async fetch({ user, repo }) {
|
async fetch({ user, repo }) {
|
||||||
return this._requestJson({
|
return this._requestJson({
|
||||||
url: `/repos/${user}/${repo}`,
|
url: `/repos/${user}/${repo}`,
|
||||||
@@ -51,6 +43,8 @@ export default class GithubRepoSize extends GithubAuthV3Service {
|
|||||||
|
|
||||||
async handle({ user, repo }) {
|
async handle({ user, repo }) {
|
||||||
const { size } = await this.fetch({ user, repo })
|
const { size } = await this.fetch({ user, repo })
|
||||||
return this.constructor.render({ size })
|
// note the GH API returns size in KiB
|
||||||
|
// so we multiply by 1024 to get a size in bytes and then format that in IEC bytes
|
||||||
|
return renderSizeBadge(size * 1024, 'iec', 'repo size')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import { isFileSize } from '../test-validators.js'
|
import { isIecFileSize } from '../test-validators.js'
|
||||||
import { createServiceTester } from '../tester.js'
|
import { createServiceTester } from '../tester.js'
|
||||||
export const t = await createServiceTester()
|
export const t = await createServiceTester()
|
||||||
|
|
||||||
t.create('repository size').get('/badges/shields.json').expectBadge({
|
t.create('repository size').get('/badges/shields.json').expectBadge({
|
||||||
label: 'repo size',
|
label: 'repo size',
|
||||||
message: isFileSize,
|
message: isIecFileSize,
|
||||||
})
|
})
|
||||||
|
|
||||||
t.create('repository size (repo not found)')
|
t.create('repository size (repo not found)')
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import Joi from 'joi'
|
import Joi from 'joi'
|
||||||
import prettyBytes from 'pretty-bytes'
|
import { renderSizeBadge } from '../size.js'
|
||||||
import { nonNegativeInteger } from '../validators.js'
|
import { nonNegativeInteger } from '../validators.js'
|
||||||
import { NotFound, pathParam, queryParam } from '../index.js'
|
import { NotFound, pathParam, queryParam } from '../index.js'
|
||||||
import { GithubAuthV3Service } from './github-auth-service.js'
|
import { GithubAuthV3Service } from './github-auth-service.js'
|
||||||
@@ -44,13 +44,6 @@ export default class GithubSize extends GithubAuthV3Service {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
static render({ size }) {
|
|
||||||
return {
|
|
||||||
message: prettyBytes(size),
|
|
||||||
color: 'blue',
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async fetch({ user, repo, path, branch }) {
|
async fetch({ user, repo, path, branch }) {
|
||||||
if (branch) {
|
if (branch) {
|
||||||
return this._requestJson({
|
return this._requestJson({
|
||||||
@@ -73,6 +66,6 @@ export default class GithubSize extends GithubAuthV3Service {
|
|||||||
if (Array.isArray(body)) {
|
if (Array.isArray(body)) {
|
||||||
throw new NotFound({ prettyMessage: 'not a regular file' })
|
throw new NotFound({ prettyMessage: 'not a regular file' })
|
||||||
}
|
}
|
||||||
return this.constructor.render({ size: body.size })
|
return renderSizeBadge(body.size, 'iec')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import { isFileSize } from '../test-validators.js'
|
import { isIecFileSize } from '../test-validators.js'
|
||||||
import { createServiceTester } from '../tester.js'
|
import { createServiceTester } from '../tester.js'
|
||||||
export const t = await createServiceTester()
|
export const t = await createServiceTester()
|
||||||
|
|
||||||
t.create('File size')
|
t.create('File size')
|
||||||
.get('/webcaetano/craft/build/phaser-craft.min.js.json')
|
.get('/webcaetano/craft/build/phaser-craft.min.js.json')
|
||||||
.expectBadge({ label: 'size', message: isFileSize })
|
.expectBadge({ label: 'size', message: isIecFileSize })
|
||||||
|
|
||||||
t.create('File size 404')
|
t.create('File size 404')
|
||||||
.get('/webcaetano/craft/build/does-not-exist.min.js.json')
|
.get('/webcaetano/craft/build/does-not-exist.min.js.json')
|
||||||
@@ -20,12 +20,12 @@ t.create('File size for "not a regular file"')
|
|||||||
|
|
||||||
t.create('File size for a specified branch')
|
t.create('File size for a specified branch')
|
||||||
.get('/webcaetano/craft/build/craft.min.js.json?branch=version-2')
|
.get('/webcaetano/craft/build/craft.min.js.json?branch=version-2')
|
||||||
.expectBadge({ label: 'size', message: isFileSize })
|
.expectBadge({ label: 'size', message: isIecFileSize })
|
||||||
|
|
||||||
t.create('File size for a specified tag')
|
t.create('File size for a specified tag')
|
||||||
.get('/webcaetano/craft/build/phaser-craft.min.js.json?branch=2.1.2')
|
.get('/webcaetano/craft/build/phaser-craft.min.js.json?branch=2.1.2')
|
||||||
.expectBadge({ label: 'size', message: isFileSize })
|
.expectBadge({ label: 'size', message: isIecFileSize })
|
||||||
|
|
||||||
t.create('File size for a specified commit')
|
t.create('File size for a specified commit')
|
||||||
.get('/webcaetano/craft/build/phaser-craft.min.js.json?branch=b848dbb')
|
.get('/webcaetano/craft/build/phaser-craft.min.js.json?branch=b848dbb')
|
||||||
.expectBadge({ label: 'size', message: isFileSize })
|
.expectBadge({ label: 'size', message: isIecFileSize })
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
import Joi from 'joi'
|
import Joi from 'joi'
|
||||||
import prettyBytes from 'pretty-bytes'
|
|
||||||
import { pathParam, queryParam } from '../index.js'
|
import { pathParam, queryParam } from '../index.js'
|
||||||
|
import { renderSizeBadge } from '../size.js'
|
||||||
import { optionalNonNegativeInteger } from '../validators.js'
|
import { optionalNonNegativeInteger } from '../validators.js'
|
||||||
import NpmBase, { packageNameDescription } from './npm-base.js'
|
import NpmBase, {
|
||||||
|
packageNameDescription,
|
||||||
|
queryParamSchema,
|
||||||
|
} from './npm-base.js'
|
||||||
|
|
||||||
const schema = Joi.object({
|
const schema = Joi.object({
|
||||||
dist: Joi.object({
|
dist: Joi.object({
|
||||||
@@ -16,6 +19,7 @@ export default class NpmUnpackedSize extends NpmBase {
|
|||||||
static route = {
|
static route = {
|
||||||
base: 'npm/unpacked-size',
|
base: 'npm/unpacked-size',
|
||||||
pattern: ':scope(@[^/]+)?/:packageName/:version*',
|
pattern: ':scope(@[^/]+)?/:packageName/:version*',
|
||||||
|
queryParamSchema,
|
||||||
}
|
}
|
||||||
|
|
||||||
static openApi = {
|
static openApi = {
|
||||||
@@ -78,10 +82,13 @@ export default class NpmUnpackedSize extends NpmBase {
|
|||||||
})
|
})
|
||||||
const { unpackedSize } = dist
|
const { unpackedSize } = dist
|
||||||
|
|
||||||
|
if (unpackedSize) {
|
||||||
|
return renderSizeBadge(unpackedSize, 'metric', 'unpacked size')
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
label: 'unpacked size',
|
label: 'unpacked size',
|
||||||
message: unpackedSize ? prettyBytes(unpackedSize) : 'unknown',
|
message: 'unknown',
|
||||||
color: unpackedSize ? 'blue' : 'lightgray',
|
color: 'lightgray',
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import { isFileSize } from '../test-validators.js'
|
import { isMetricFileSize } from '../test-validators.js'
|
||||||
import { createServiceTester } from '../tester.js'
|
import { createServiceTester } from '../tester.js'
|
||||||
|
|
||||||
export const t = await createServiceTester()
|
export const t = await createServiceTester()
|
||||||
|
|
||||||
t.create('Latest unpacked size')
|
t.create('Latest unpacked size')
|
||||||
.get('/firereact.json')
|
.get('/firereact.json')
|
||||||
.expectBadge({ label: 'unpacked size', message: isFileSize })
|
.expectBadge({ label: 'unpacked size', message: isMetricFileSize })
|
||||||
|
|
||||||
t.create('Nonexistent unpacked size with version')
|
t.create('Nonexistent unpacked size with version')
|
||||||
.get('/express/4.16.0.json')
|
.get('/express/4.16.0.json')
|
||||||
@@ -13,15 +13,15 @@ t.create('Nonexistent unpacked size with version')
|
|||||||
|
|
||||||
t.create('Unpacked size with version')
|
t.create('Unpacked size with version')
|
||||||
.get('/firereact/0.7.0.json')
|
.get('/firereact/0.7.0.json')
|
||||||
.expectBadge({ label: 'unpacked size', message: '147 kB' })
|
.expectBadge({ label: 'unpacked size', message: '147.2 kB' })
|
||||||
|
|
||||||
t.create('Unpacked size for scoped package')
|
t.create('Unpacked size for scoped package')
|
||||||
.get('/@testing-library/react.json')
|
.get('/@testing-library/react.json')
|
||||||
.expectBadge({ label: 'unpacked size', message: isFileSize })
|
.expectBadge({ label: 'unpacked size', message: isMetricFileSize })
|
||||||
|
|
||||||
t.create('Unpacked size for scoped package with version')
|
t.create('Unpacked size for scoped package with version')
|
||||||
.get('/@testing-library/react/14.2.1.json')
|
.get('/@testing-library/react/14.2.1.json')
|
||||||
.expectBadge({ label: 'unpacked size', message: '5.41 MB' })
|
.expectBadge({ label: 'unpacked size', message: '5.4 MB' })
|
||||||
|
|
||||||
t.create('Nonexistent unpacked size for scoped package with version')
|
t.create('Nonexistent unpacked size for scoped package with version')
|
||||||
.get('/@cycle/rx-run/7.2.0.json')
|
.get('/@cycle/rx-run/7.2.0.json')
|
||||||
|
|||||||
25
services/size.js
Normal file
25
services/size.js
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
/**
|
||||||
|
* @module
|
||||||
|
*/
|
||||||
|
|
||||||
|
import byteSize from 'byte-size'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a badge object that displays information about a size in bytes number.
|
||||||
|
* It should usually be used to output a size badge.
|
||||||
|
*
|
||||||
|
* @param {number} bytes - Raw number of bytes to be formatted
|
||||||
|
* @param {'metric'|'iec'} units - Either 'metric' (multiples of 1000) or 'iec' (multiples of 1024).
|
||||||
|
* This should align with how the upstream displays sizes.
|
||||||
|
* @param {string} [label='size'] - Custom label
|
||||||
|
* @returns {object} A badge object that has three properties: label, message, and color
|
||||||
|
*/
|
||||||
|
function renderSizeBadge(bytes, units, label = 'size') {
|
||||||
|
return {
|
||||||
|
label,
|
||||||
|
message: byteSize(bytes, { units }).toString(),
|
||||||
|
color: 'blue',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export { renderSizeBadge }
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
import { isFileSize } from '../test-validators.js'
|
import { isMetricFileSize } from '../test-validators.js'
|
||||||
import { createServiceTester } from '../tester.js'
|
import { createServiceTester } from '../tester.js'
|
||||||
export const t = await createServiceTester()
|
export const t = await createServiceTester()
|
||||||
|
|
||||||
t.create('EssentialsX (hosted resource)')
|
t.create('EssentialsX (hosted resource)')
|
||||||
.get('/771.json')
|
.get('/771.json')
|
||||||
.expectBadge({ label: 'size', message: isFileSize })
|
.expectBadge({ label: 'size', message: isMetricFileSize })
|
||||||
|
|
||||||
t.create('external resource').get('/9089.json').expectBadge({
|
t.create('external resource').get('/9089.json').expectBadge({
|
||||||
label: 'size',
|
label: 'size',
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import Joi from 'joi'
|
import Joi from 'joi'
|
||||||
import prettyBytes from 'pretty-bytes'
|
|
||||||
import { renderDateBadge } from '../date.js'
|
import { renderDateBadge } from '../date.js'
|
||||||
|
import { renderSizeBadge } from '../size.js'
|
||||||
import { renderDownloadsBadge } from '../downloads.js'
|
import { renderDownloadsBadge } from '../downloads.js'
|
||||||
import { metric } from '../text-formatters.js'
|
import { metric } from '../text-formatters.js'
|
||||||
import { NotFound, pathParams } from '../index.js'
|
import { NotFound, pathParams } from '../index.js'
|
||||||
@@ -208,12 +208,8 @@ class SteamFileSize extends SteamFileService {
|
|||||||
label: 'size',
|
label: 'size',
|
||||||
}
|
}
|
||||||
|
|
||||||
static render({ fileSize }) {
|
|
||||||
return { message: prettyBytes(fileSize), color: 'informational' }
|
|
||||||
}
|
|
||||||
|
|
||||||
async onRequest({ response }) {
|
async onRequest({ response }) {
|
||||||
return this.constructor.render({ fileSize: response.file_size })
|
return renderSizeBadge(response.file_size, 'metric')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
import { ServiceTester } from '../tester.js'
|
import { ServiceTester } from '../tester.js'
|
||||||
import { isMetric, isFileSize, isFormattedDate } from '../test-validators.js'
|
import {
|
||||||
|
isMetric,
|
||||||
|
isMetricFileSize,
|
||||||
|
isFormattedDate,
|
||||||
|
} from '../test-validators.js'
|
||||||
|
|
||||||
export const t = new ServiceTester({
|
export const t = new ServiceTester({
|
||||||
id: 'steam',
|
id: 'steam',
|
||||||
@@ -12,7 +16,7 @@ t.create('Collection Files')
|
|||||||
|
|
||||||
t.create('File Size')
|
t.create('File Size')
|
||||||
.get('/size/1523924535.json')
|
.get('/size/1523924535.json')
|
||||||
.expectBadge({ label: 'size', message: isFileSize })
|
.expectBadge({ label: 'size', message: isMetricFileSize })
|
||||||
|
|
||||||
t.create('Release Date')
|
t.create('Release Date')
|
||||||
.get('/release-date/1523924535.json')
|
.get('/release-date/1523924535.json')
|
||||||
|
|||||||
@@ -106,9 +106,12 @@ const isPercentage = Joi.alternatives().try(
|
|||||||
isDecimalPercentageNegative,
|
isDecimalPercentageNegative,
|
||||||
)
|
)
|
||||||
|
|
||||||
const isFileSize = withRegex(
|
const isMetricFileSize = withRegex(
|
||||||
/^[0-9]*[.]?[0-9]+\s(B|kB|KB|MB|GB|TB|PB|EB|ZB|YB)$/,
|
/^[0-9]*[.]?[0-9]+\s(B|kB|KB|MB|GB|TB|PB|EB|ZB|YB)$/,
|
||||||
)
|
)
|
||||||
|
const isIecFileSize = withRegex(
|
||||||
|
/^[0-9]*[.]?[0-9]+\s(B|KiB|MiB|GiB|TiB|PiB|EiB|ZiB|YiB)$/,
|
||||||
|
)
|
||||||
|
|
||||||
const isFormattedDate = Joi.alternatives().try(
|
const isFormattedDate = Joi.alternatives().try(
|
||||||
Joi.equal('today', 'yesterday'),
|
Joi.equal('today', 'yesterday'),
|
||||||
@@ -202,7 +205,8 @@ export {
|
|||||||
isPercentage,
|
isPercentage,
|
||||||
isIntegerPercentage,
|
isIntegerPercentage,
|
||||||
isDecimalPercentage,
|
isDecimalPercentage,
|
||||||
isFileSize,
|
isMetricFileSize,
|
||||||
|
isIecFileSize,
|
||||||
isFormattedDate,
|
isFormattedDate,
|
||||||
isRelativeFormattedDate,
|
isRelativeFormattedDate,
|
||||||
isDependencyState,
|
isDependencyState,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import Joi from 'joi'
|
import Joi from 'joi'
|
||||||
import prettyBytes from 'pretty-bytes'
|
|
||||||
import { pathParams } from '../index.js'
|
import { pathParams } from '../index.js'
|
||||||
|
import { renderSizeBadge } from '../size.js'
|
||||||
import { nonNegativeInteger } from '../validators.js'
|
import { nonNegativeInteger } from '../validators.js'
|
||||||
import {
|
import {
|
||||||
BaseVisualStudioAppCenterService,
|
BaseVisualStudioAppCenterService,
|
||||||
@@ -47,14 +47,8 @@ export default class VisualStudioAppCenterReleasesSize extends BaseVisualStudioA
|
|||||||
color: 'blue',
|
color: 'blue',
|
||||||
}
|
}
|
||||||
|
|
||||||
static render({ size }) {
|
|
||||||
return {
|
|
||||||
message: prettyBytes(size),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async handle({ owner, app, token }) {
|
async handle({ owner, app, token }) {
|
||||||
const { size } = await this.fetch({ owner, app, token, schema })
|
const { size } = await this.fetch({ owner, app, token, schema })
|
||||||
return this.constructor.render({ size })
|
return renderSizeBadge(size, 'metric')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { createServiceTester } from '../tester.js'
|
import { createServiceTester } from '../tester.js'
|
||||||
import { isFileSize } from '../test-validators.js'
|
import { isMetricFileSize } from '../test-validators.js'
|
||||||
export const t = await createServiceTester()
|
export const t = await createServiceTester()
|
||||||
|
|
||||||
t.create('8368844 bytes to 8.37 megabytes')
|
t.create('8368844 bytes to 8.37 megabytes')
|
||||||
@@ -13,7 +13,7 @@ t.create('8368844 bytes to 8.37 megabytes')
|
|||||||
)
|
)
|
||||||
.expectBadge({
|
.expectBadge({
|
||||||
label: 'size',
|
label: 'size',
|
||||||
message: '8.37 MB',
|
message: '8.4 MB',
|
||||||
})
|
})
|
||||||
|
|
||||||
t.create('Valid Release')
|
t.create('Valid Release')
|
||||||
@@ -22,7 +22,7 @@ t.create('Valid Release')
|
|||||||
)
|
)
|
||||||
.expectBadge({
|
.expectBadge({
|
||||||
label: 'size',
|
label: 'size',
|
||||||
message: isFileSize,
|
message: isMetricFileSize,
|
||||||
})
|
})
|
||||||
|
|
||||||
t.create('Valid user, invalid project, valid API token')
|
t.create('Valid user, invalid project, valid API token')
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { createServiceTester } from '../tester.js'
|
import { createServiceTester } from '../tester.js'
|
||||||
import {
|
import {
|
||||||
isFileSize,
|
isMetricFileSize,
|
||||||
isHumanized,
|
isHumanized,
|
||||||
isMetric,
|
isMetric,
|
||||||
isOrdinalNumber,
|
isOrdinalNumber,
|
||||||
@@ -21,11 +21,11 @@ t.create('WhatPulse team as team id, clicks')
|
|||||||
|
|
||||||
t.create('WhatPulse team as team id, download')
|
t.create('WhatPulse team as team id, download')
|
||||||
.get('/download/team/1295.json')
|
.get('/download/team/1295.json')
|
||||||
.expectBadge({ label: 'download', message: isFileSize })
|
.expectBadge({ label: 'download', message: isMetricFileSize })
|
||||||
|
|
||||||
t.create('WhatPulse team as team id, upload')
|
t.create('WhatPulse team as team id, upload')
|
||||||
.get('/upload/team/1295.json')
|
.get('/upload/team/1295.json')
|
||||||
.expectBadge({ label: 'upload', message: isFileSize })
|
.expectBadge({ label: 'upload', message: isMetricFileSize })
|
||||||
|
|
||||||
t.create('WhatPulse team as team name, keys - from Ranks')
|
t.create('WhatPulse team as team name, keys - from Ranks')
|
||||||
.get('/keys/team/dutch power cows.json?rank')
|
.get('/keys/team/dutch power cows.json?rank')
|
||||||
|
|||||||
Reference in New Issue
Block a user