Skip to content

Commit

Permalink
Merge branch 'master' into chrome-webstore-size-last-updated
Browse files Browse the repository at this point in the history
  • Loading branch information
aiden2480 committed Oct 21, 2024
2 parents 527f405 + 04f4fbd commit dec74c4
Show file tree
Hide file tree
Showing 14 changed files with 191 additions and 109 deletions.
4 changes: 4 additions & 0 deletions fly.toml
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,7 @@ processes = []
interval = "15s"
restart_limit = 0
timeout = "2s"

[[vm]]
size = "shared-cpu-1x"
memory = "256mb"
2 changes: 1 addition & 1 deletion services/archlinux/archlinux.tester.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { createServiceTester } from '../tester.js'
export const t = await createServiceTester()

t.create('Arch Linux package (valid)')
.get('/core/x86_64/pacman.json')
.get('/core/x86_64/iptables.json')
.expectBadge({
label: 'arch linux',
message: isVPlusDottedVersionNClausesWithOptionalSuffixAndEpoch,
Expand Down
5 changes: 3 additions & 2 deletions services/aur/aur.service.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@ import {
age as ageColor,
} from '../color-formatters.js'
import { renderLicenseBadge } from '../licenses.js'
import { addv, metric, formatDate } from '../text-formatters.js'
import { metric, formatDate } from '../text-formatters.js'
import { nonNegativeInteger } from '../validators.js'
import {
BaseJsonService,
NotFound,
InvalidResponse,
pathParams,
} from '../index.js'
import { renderVersionBadge } from '../version.js'

const aurSchema = Joi.object({
resultcount: nonNegativeInteger,
Expand Down Expand Up @@ -170,7 +171,7 @@ class AurVersion extends BaseAurService {

static render({ version, outOfDate }) {
const color = outOfDate === null ? 'blue' : 'orange'
return { message: addv(version), color }
return renderVersionBadge({ version, versionFormatter: () => color })
}

async handle({ packageName }) {
Expand Down
2 changes: 2 additions & 0 deletions services/aur/aur.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@ describe('AurVersion', function () {
given({ version: '1:1.1.42.622-1', outOfDate: 1 }).expect({
color: 'orange',
message: 'v1:1.1.42.622-1',
label: undefined,
})

given({ version: '7', outOfDate: null }).expect({
color: 'blue',
message: 'v7',
label: undefined,
})
})
})
17 changes: 4 additions & 13 deletions services/conda/conda-version.service.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { pathParams } from '../index.js'
import { addv as versionText } from '../text-formatters.js'
import { version as versionColor } from '../color-formatters.js'
import { renderVersionBadge } from '../version.js'
import BaseCondaService from './conda-base.js'

export default class CondaVersion extends BaseCondaService {
Expand Down Expand Up @@ -33,20 +32,12 @@ export default class CondaVersion extends BaseCondaService {
},
}

static render({ variant, channel, version }) {
return {
label: variant === 'vn' ? channel : `conda | ${channel}`,
message: versionText(version),
color: versionColor(version),
}
}

async handle({ variant, channel, packageName }) {
const json = await this.fetch({ channel, packageName })
return this.constructor.render({
variant,
channel,
const defaultLabel = variant === 'vn' ? channel : `conda | ${channel}`
return renderVersionBadge({
version: json.latest_version,
defaultLabel,
})
}
}
30 changes: 29 additions & 1 deletion services/crates/crates-base.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,21 @@ const versionResponseSchema = Joi.object({
version: versionSchema.required(),
}).required()

const userStatsSchema = Joi.object({
total_downloads: nonNegativeInteger.required(),
}).required()

class BaseCratesService extends BaseJsonService {
static defaultBadgeData = { label: 'crates.io' }

/**
* Fetches data from the crates.io API.
*
* @param {object} options - The options for the request
* @param {string} options.crate - The crate name.
* @param {string} [options.version] - The crate version number (optional).
* @returns {Promise<object>} the JSON response from the API.
*/
async fetch({ crate, version }) {
const url = version
? `https://crates.io/api/v1/crates/${crate}/${version}`
Expand Down Expand Up @@ -54,7 +66,23 @@ class BaseCratesService extends BaseJsonService {
}
}

class BaseCratesUserService extends BaseJsonService {
static defaultBadgeData = { label: 'crates.io' }

/**
* Fetches data from the crates.io API.
*
* @param {object} options - The options for the request
* @param {string} options.userId - The user ID.
* @returns {Promise<object>} the JSON response from the API.
*/
async fetch({ userId }) {
const url = `https://crates.io/api/v1/users/${userId}/stats`
return this._requestJson({ schema: userStatsSchema, url })
}
}

const description =
'[Crates.io](https://crates.io/) is a package registry for Rust.'

export { BaseCratesService, description }
export { BaseCratesService, BaseCratesUserService, description }
32 changes: 32 additions & 0 deletions services/crates/crates-user-downloads.service.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { renderDownloadsBadge } from '../downloads.js'
import { pathParams } from '../index.js'
import { BaseCratesUserService, description } from './crates-base.js'

export default class CratesUserDownloads extends BaseCratesUserService {
static category = 'downloads'
static route = {
base: 'crates',
pattern: 'udt/:userId',
}

static openApi = {
'/crates/udt/{userId}': {
get: {
summary: 'Crates.io User Total Downloads',
description,
parameters: pathParams({
name: 'userId',
example: '3027',
description:
'The user ID can be found using `https://crates.io/api/v1/users/{username}`',
}),
},
},
}

async handle({ userId }) {
const json = await this.fetch({ userId })
const { total_downloads: downloads } = json
return renderDownloadsBadge({ downloads, labelOverride: 'downloads' })
}
}
16 changes: 16 additions & 0 deletions services/crates/crates-user-downloads.tester.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { isMetric } from '../test-validators.js'
import { createServiceTester } from '../tester.js'
export const t = await createServiceTester()

t.create('total user downloads')
.get('/udt/3027.json')
.expectBadge({ label: 'downloads', message: isMetric })

// non-existent user returns 0 downloads with 200 OK status code rather than 404.
t.create('total user downloads (user not found)')
.get('/udt/2147483647.json') // 2147483647 is the maximum valid user id as API uses i32
.expectBadge({ label: 'downloads', message: '0' })

t.create('total user downloads (invalid)')
.get('/udt/999999999999999999999999.json')
.expectBadge({ label: 'crates.io', message: 'invalid' })
53 changes: 8 additions & 45 deletions services/hackage/hackage-deps.service.js
Original file line number Diff line number Diff line change
@@ -1,48 +1,11 @@
import { BaseService, pathParams } from '../index.js'
import { deprecatedService } from '../index.js'

export default class HackageDeps extends BaseService {
static category = 'dependencies'

static route = {
export const HackageDeps = deprecatedService({
category: 'dependencies',
route: {
base: 'hackage-deps/v',
pattern: ':packageName',
}

static openApi = {
'/hackage-deps/v/{packageName}': {
get: {
summary: 'Hackage Dependencies',
parameters: pathParams({
name: 'packageName',
example: 'lens',
}),
},
},
}

static defaultBadgeData = { label: 'dependencies' }

static render({ isOutdated }) {
if (isOutdated) {
return { message: 'outdated', color: 'orange' }
} else {
return { message: 'up to date', color: 'brightgreen' }
}
}

async handle({ packageName }) {
const reverseUrl = `http://packdeps.haskellers.com/licenses/${packageName}`
const feedUrl = `http://packdeps.haskellers.com/feed/${packageName}`

// first call /reverse to check if the package exists
// this will throw a 404 if it doesn't
await this._request({ url: reverseUrl })

// if the package exists, then query /feed to check the dependencies
const { buffer } = await this._request({ url: feedUrl })

const outdatedStr = `Outdated dependencies for ${packageName} `
const isOutdated = buffer.includes(outdatedStr)
return this.constructor.render({ isOutdated })
}
}
},
label: 'hackagedeps',
dateAdded: new Date('2024-10-18'),
})
22 changes: 9 additions & 13 deletions services/hackage/hackage-deps.tester.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
import Joi from 'joi'
import { createServiceTester } from '../tester.js'
export const t = await createServiceTester()
import { ServiceTester } from '../tester.js'
export const t = new ServiceTester({
id: 'hackagedeps',
title: 'Hackage Dependencies',
pathPrefix: '/hackage-deps/v',
})

t.create('hackage deps (valid)')
.get('/lens.json')
.expectBadge({
label: 'dependencies',
message: Joi.string().regex(/^(up to date|outdated)$/),
})

t.create('hackage deps (not found)')
.get('/not-a-package.json')
.expectBadge({ label: 'dependencies', message: 'not found' })
t.create('hackage deps (deprecated)')
.get('/package.json')
.expectBadge({ label: 'hackagedeps', message: 'no longer available' })
2 changes: 1 addition & 1 deletion services/npm/npm-base.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ describe('npm', function () {
await NpmVersion.invoke(defaultContext, config, { packageName: 'npm' }),
).to.deep.equal({
color: 'orange',
label: undefined,
label: 'npm',
message: 'v0.1.0',
})

Expand Down
10 changes: 8 additions & 2 deletions services/version.js
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,8 @@ function rangeStart(v) {
* @param {string} options.version - The version number to display on the badge
* @param {string} [options.tag] - The tag to display on the badge, such as "alpha" or "beta"
* @param {string} [options.defaultLabel] - The default label to display on the badge, such as "npm" or "github"
* @param {string} [options.prefix] - The prefix to display on the message, such as ">=", "v", overrides the default behavior of using addv
* @param {string} [options.postfix] - The postfix to display on the message, such as "tested"
* @param {Function} [options.versionFormatter=versionColor] - The function to use to format the color of the badge based on the version number
* @returns {object} A badge object that has three properties: label, message, and color
* @example
Expand All @@ -245,11 +247,15 @@ function renderVersionBadge({
version,
tag,
defaultLabel,
prefix,
postfix,
versionFormatter = versionColor,
}) {
return {
label: tag ? `${defaultLabel}@${tag}` : undefined,
message: addv(version),
label: tag ? `${defaultLabel}@${tag}` : defaultLabel,
message:
(prefix ? `${prefix}${version}` : addv(version)) +
(postfix ? ` ${postfix}` : ''),
color: versionFormatter(version),
}
}
Expand Down
64 changes: 64 additions & 0 deletions services/version.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -150,5 +150,69 @@ describe('Version helpers', function () {
message: 'v1.2.3',
color: 'blue',
})
given({ version: '1.2.3', defaultLabel: 'npm' }).expect({
label: 'npm',
message: 'v1.2.3',
color: 'blue',
})
given({ version: '1.2.3', postfix: 'tested' }).expect({
label: undefined,
message: 'v1.2.3 tested',
color: 'blue',
})
given({
version: '1.2.3',
tag: 'beta',
defaultLabel: 'github',
postfix: 'tested',
}).expect({
label: 'github@beta',
message: 'v1.2.3 tested',
color: 'blue',
})
given({ version: '1.2.3', prefix: '^' }).expect({
label: undefined,
message: '^1.2.3',
color: 'blue',
})
given({
version: '1.2.3',
tag: 'alpha',
defaultLabel: 'npm',
prefix: '^',
}).expect({
label: 'npm@alpha',
message: '^1.2.3',
color: 'blue',
})
given({
version: '1.2.3',
defaultLabel: 'npm',
prefix: '^',
}).expect({
label: 'npm',
message: '^1.2.3',
color: 'blue',
})
given({
version: '1.2.3',
prefix: '^',
postfix: 'tested',
}).expect({
label: undefined,
message: '^1.2.3 tested',
color: 'blue',
})
given({
version: '1.2.3',
tag: 'beta',
defaultLabel: 'github',
prefix: '^',
postfix: 'tested',
}).expect({
label: 'github@beta',
message: '^1.2.3 tested',
color: 'blue',
})
})
})
Loading

0 comments on commit dec74c4

Please sign in to comment.