Compare commits
22 Commits
server-202
...
increase-t
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
afd23abd1d | ||
|
|
5e6d68123a | ||
|
|
6e4c46143f | ||
|
|
f419b39b09 | ||
|
|
fe5d4514ee | ||
|
|
60e75963a8 | ||
|
|
e965324911 | ||
|
|
781aedc353 | ||
|
|
3cf154053f | ||
|
|
8bf34a2307 | ||
|
|
d251b481f4 | ||
|
|
dc06b445c9 | ||
|
|
667a609b6e | ||
|
|
1f2ba9eba6 | ||
|
|
c07d0f901a | ||
|
|
bcdc02510d | ||
|
|
45331d1d1f | ||
|
|
a2376d1d21 | ||
|
|
7b40bd78d5 | ||
|
|
2960f3a30b | ||
|
|
888d47253c | ||
|
|
0a26450f7a |
13
cypress.config.js
Normal file
13
cypress.config.js
Normal file
@@ -0,0 +1,13 @@
|
||||
import { defineConfig } from 'cypress'
|
||||
|
||||
export default defineConfig({
|
||||
fixturesFolder: false,
|
||||
env: {
|
||||
backend_url: 'http://localhost:8080',
|
||||
},
|
||||
e2e: {
|
||||
setupNodeEvents(on, config) {},
|
||||
baseUrl: 'http://localhost:3000',
|
||||
supportFile: false,
|
||||
},
|
||||
})
|
||||
@@ -1,9 +0,0 @@
|
||||
{
|
||||
"baseUrl": "http://localhost:3000",
|
||||
"fixturesFolder": false,
|
||||
"pluginsFile": false,
|
||||
"supportFile": false,
|
||||
"env": {
|
||||
"backend_url": "http://localhost:8080"
|
||||
}
|
||||
}
|
||||
1186
package-lock.json
generated
1186
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
24
package.json
24
package.json
@@ -24,11 +24,11 @@
|
||||
"@fontsource/lato": "^4.5.8",
|
||||
"@fontsource/lekton": "^4.5.9",
|
||||
"@renovate/pep440": "^1.0.0",
|
||||
"@sentry/node": "^6.19.7",
|
||||
"@sentry/node": "^7.1.1",
|
||||
"@shields_io/camp": "^18.1.1",
|
||||
"badge-maker": "file:badge-maker",
|
||||
"bytes": "^3.1.2",
|
||||
"camelcase": "^6.3.0",
|
||||
"camelcase": "^7.0.0",
|
||||
"chalk": "^5.0.1",
|
||||
"check-node-version": "^4.2.1",
|
||||
"cloudflare-middleware": "^1.0.4",
|
||||
@@ -37,13 +37,13 @@
|
||||
"decamelize": "^3.2.0",
|
||||
"emojic": "^1.1.17",
|
||||
"escape-string-regexp": "^4.0.0",
|
||||
"fast-xml-parser": "^4.0.7",
|
||||
"fast-xml-parser": "^4.0.8",
|
||||
"glob": "^8.0.3",
|
||||
"global-agent": "^3.0.0",
|
||||
"got": "^12.1.0",
|
||||
"graphql": "^15.6.1",
|
||||
"graphql-tag": "^2.12.6",
|
||||
"ioredis": "5.0.5",
|
||||
"ioredis": "5.0.6",
|
||||
"joi": "17.6.0",
|
||||
"joi-extension-semver": "5.0.0",
|
||||
"js-yaml": "^4.1.0",
|
||||
@@ -58,7 +58,7 @@
|
||||
"pretty-bytes": "^6.0.0",
|
||||
"priorityqueuejs": "^2.0.0",
|
||||
"prom-client": "^14.0.1",
|
||||
"qs": "^6.10.3",
|
||||
"qs": "^6.10.5",
|
||||
"query-string": "^7.1.1",
|
||||
"semver": "~7.3.7",
|
||||
"simple-icons": "6.23.0",
|
||||
@@ -155,8 +155,8 @@
|
||||
"@types/react-modal": "^3.13.1",
|
||||
"@types/react-select": "^4.0.17",
|
||||
"@types/styled-components": "5.1.25",
|
||||
"@typescript-eslint/eslint-plugin": "^5.26.0",
|
||||
"@typescript-eslint/parser": "^5.15.0",
|
||||
"@typescript-eslint/eslint-plugin": "^5.27.1",
|
||||
"@typescript-eslint/parser": "^5.27.0",
|
||||
"babel-plugin-inline-react-svg": "^2.0.1",
|
||||
"babel-preset-gatsby": "^2.14.0",
|
||||
"c8": "^7.11.3",
|
||||
@@ -168,7 +168,7 @@
|
||||
"child-process-promise": "^2.2.1",
|
||||
"clipboard-copy": "^4.0.1",
|
||||
"concurrently": "^7.2.1",
|
||||
"cypress": "^9.7.0",
|
||||
"cypress": "^10.0.3",
|
||||
"danger": "^11.0.7",
|
||||
"danger-plugin-no-test-shortcuts": "^2.0.0",
|
||||
"deepmerge": "^4.2.2",
|
||||
@@ -203,7 +203,7 @@
|
||||
"is-svg": "^4.3.2",
|
||||
"js-yaml-loader": "^1.2.2",
|
||||
"jsdoc": "^3.6.10",
|
||||
"lint-staged": "^12.4.2",
|
||||
"lint-staged": "^13.0.1",
|
||||
"lodash.debounce": "^4.0.8",
|
||||
"lodash.difference": "^4.5.0",
|
||||
"minimist": "^1.2.6",
|
||||
@@ -211,7 +211,7 @@
|
||||
"mocha-env-reporter": "^4.0.0",
|
||||
"mocha-junit-reporter": "^2.0.2",
|
||||
"mocha-yaml-loader": "^1.0.3",
|
||||
"nock": "13.2.4",
|
||||
"nock": "13.2.6",
|
||||
"node-mocks-http": "^1.11.0",
|
||||
"nodemon": "^2.0.16",
|
||||
"npm-run-all": "^4.1.5",
|
||||
@@ -229,7 +229,7 @@
|
||||
"redis-server": "^1.2.2",
|
||||
"rimraf": "^3.0.2",
|
||||
"sazerac": "^2.0.0",
|
||||
"simple-git-hooks": "^2.7.0",
|
||||
"simple-git-hooks": "^2.8.0",
|
||||
"sinon": "^14.0.0",
|
||||
"sinon-chai": "^3.7.0",
|
||||
"snap-shot-it": "^7.9.6",
|
||||
@@ -237,7 +237,7 @@
|
||||
"styled-components": "^5.3.5",
|
||||
"ts-mocha": "^10.0.0",
|
||||
"tsd": "^0.20.0",
|
||||
"typescript": "^4.7.2",
|
||||
"typescript": "^4.7.3",
|
||||
"url": "^0.11.0"
|
||||
},
|
||||
"engines": {
|
||||
|
||||
@@ -1,22 +1,54 @@
|
||||
/**
|
||||
* Common functions and utilities for tasks related to dynamic badges.
|
||||
*
|
||||
* @module
|
||||
*/
|
||||
|
||||
import Joi from 'joi'
|
||||
import toArray from '../core/base-service/to-array.js'
|
||||
import validate from '../core/base-service/validate.js'
|
||||
import { InvalidResponse } from './index.js'
|
||||
|
||||
/**
|
||||
* Map of error codes and their corresponding error messages.
|
||||
*
|
||||
* @type {object}
|
||||
*/
|
||||
const errorMessages = {
|
||||
404: 'resource not found',
|
||||
}
|
||||
|
||||
/**
|
||||
* Joi schema for validating individual value.
|
||||
* Checks if the individual value is of type string or number.
|
||||
*
|
||||
* @type {object}
|
||||
*/
|
||||
const individualValueSchema = Joi.alternatives()
|
||||
.try(Joi.string(), Joi.number())
|
||||
.required()
|
||||
|
||||
/**
|
||||
* Joi schema for validating compound value.
|
||||
* Checks if the compound value is of type individualValueSchema, array of individualValueSchema or empty array.
|
||||
*
|
||||
* @type {object}
|
||||
*/
|
||||
const compoundValueSchema = Joi.alternatives().try(
|
||||
individualValueSchema,
|
||||
Joi.array().items(individualValueSchema).required(),
|
||||
Joi.array().length(0)
|
||||
)
|
||||
|
||||
/**
|
||||
* Look up the value in the data object by key and validate the value against compoundValueSchema.
|
||||
*
|
||||
* @param {object} attrs Refer to individual attributes
|
||||
* @param {object} attrs.data Object containing the data for validation
|
||||
* @param {string} attrs.key Key to retrieve the data from object for validation
|
||||
* @throws {InvalidResponse|Error} Error if Joi validation fails due to invalid or no schema
|
||||
* @returns {object} Value if Joi validation is success
|
||||
*/
|
||||
function transformAndValidate({ data, key }) {
|
||||
return validate(
|
||||
{
|
||||
@@ -30,6 +62,20 @@ function transformAndValidate({ data, key }) {
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles rendering concerns of dynamic badges.
|
||||
* Determines the label of the badge according to the tag and defaultLabel.
|
||||
* Determines the message of the badge according to the prefix, suffix and value.
|
||||
* Sets the color of the badge to blue.
|
||||
*
|
||||
* @param {object} attrs Refer to individual attributes
|
||||
* @param {string} attrs.defaultLabel default badge label
|
||||
* @param {string} [attrs.tag] If provided then this value will be appended to the badge label, e.g. `foobar@v1.23`
|
||||
* @param {any} attrs.value Value or array of value to be used for the badge message
|
||||
* @param {string} [attrs.prefix] If provided then the badge message will use this value as a prefix
|
||||
* @param {string} [attrs.suffix] If provided then the badge message will use this value as a suffix
|
||||
* @returns {object} Badge with label, message and color properties
|
||||
*/
|
||||
function renderDynamicBadge({
|
||||
defaultLabel,
|
||||
tag,
|
||||
|
||||
89
services/gitlab/gitlab-license.service.js
Normal file
89
services/gitlab/gitlab-license.service.js
Normal file
@@ -0,0 +1,89 @@
|
||||
import Joi from 'joi'
|
||||
import { optionalUrl } from '../validators.js'
|
||||
import { renderLicenseBadge } from '../licenses.js'
|
||||
import GitLabBase from './gitlab-base.js'
|
||||
|
||||
const schema = Joi.object({
|
||||
license: Joi.object({
|
||||
name: Joi.string().required(),
|
||||
}).allow(null),
|
||||
}).required()
|
||||
|
||||
const queryParamSchema = Joi.object({
|
||||
gitlab_url: optionalUrl,
|
||||
}).required()
|
||||
|
||||
const documentation = `
|
||||
<p>
|
||||
You may use your GitLab Project Id (e.g. 13083) or your Project Path (e.g. gitlab-org/gitlab-foss )
|
||||
</p>
|
||||
`
|
||||
const commonProps = {
|
||||
namedParams: {
|
||||
project: 'gitlab-org/gitlab-foss',
|
||||
},
|
||||
documentation,
|
||||
}
|
||||
|
||||
export default class GitlabLicense extends GitLabBase {
|
||||
static category = 'license'
|
||||
|
||||
static route = {
|
||||
base: 'gitlab/v/license',
|
||||
pattern: ':project+',
|
||||
queryParamSchema,
|
||||
}
|
||||
|
||||
static examples = [
|
||||
{
|
||||
title: 'GitLab',
|
||||
...commonProps,
|
||||
staticPreview: {
|
||||
label: 'license',
|
||||
message: 'MIT License',
|
||||
color: 'green',
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'GitLab (custom server)',
|
||||
...commonProps,
|
||||
queryParams: { gitlab_url: 'https://jihulab.com' },
|
||||
staticPreview: {
|
||||
label: 'license',
|
||||
message: 'MIT License',
|
||||
color: 'green',
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
static defaultBadgeData = { label: 'license' }
|
||||
|
||||
static render({ license }) {
|
||||
if (license) {
|
||||
return renderLicenseBadge({ license })
|
||||
} else {
|
||||
return { message: 'not specified' }
|
||||
}
|
||||
}
|
||||
|
||||
async fetch({ project, baseUrl }) {
|
||||
// https://docs.gitlab.com/ee/api/projects.html#get-single-project
|
||||
return super.fetch({
|
||||
schema,
|
||||
url: `${baseUrl}/api/v4/projects/${encodeURIComponent(project)}`,
|
||||
options: { searchParams: { license: '1' } },
|
||||
errorMessages: {
|
||||
404: 'repo not found',
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
async handle({ project }, { gitlab_url: baseUrl = 'https://gitlab.com' }) {
|
||||
const { license: licenseObject } = await this.fetch({
|
||||
project,
|
||||
baseUrl,
|
||||
})
|
||||
const license = licenseObject ? licenseObject.name : undefined
|
||||
return this.constructor.render({ license })
|
||||
}
|
||||
}
|
||||
57
services/gitlab/gitlab-license.tester.js
Normal file
57
services/gitlab/gitlab-license.tester.js
Normal file
@@ -0,0 +1,57 @@
|
||||
import { licenseToColor } from '../licenses.js'
|
||||
import { createServiceTester } from '../tester.js'
|
||||
export const t = await createServiceTester()
|
||||
|
||||
const publicDomainLicenseColor = licenseToColor('MIT License')
|
||||
const unknownLicenseColor = licenseToColor()
|
||||
|
||||
t.create('License')
|
||||
.get('/guoxudong.io/shields-test/licenced-test.json')
|
||||
.expectBadge({
|
||||
label: 'license',
|
||||
message: 'MIT License',
|
||||
color: `${publicDomainLicenseColor}`,
|
||||
})
|
||||
|
||||
t.create('License for repo without a license')
|
||||
.get('/guoxudong.io/shields-test/no-license-test.json')
|
||||
.expectBadge({
|
||||
label: 'license',
|
||||
message: 'not specified',
|
||||
color: 'lightgrey',
|
||||
})
|
||||
|
||||
t.create('Other license').get('/gitlab-org/gitlab-foss.json').expectBadge({
|
||||
label: 'license',
|
||||
message: 'Other',
|
||||
color: unknownLicenseColor,
|
||||
})
|
||||
|
||||
t.create('License for unknown repo')
|
||||
.get('/user1/gitlab-does-not-have-this-repo.json')
|
||||
.expectBadge({
|
||||
label: 'license',
|
||||
message: 'repo not found',
|
||||
color: 'red',
|
||||
})
|
||||
|
||||
t.create('Mocking License')
|
||||
.get('/group/project.json')
|
||||
.intercept(nock =>
|
||||
nock('https://gitlab.com')
|
||||
.get('/api/v4/projects/group%2Fproject?license=1')
|
||||
.reply(200, {
|
||||
license: {
|
||||
key: 'apache-2.0',
|
||||
name: 'Apache License 2.0',
|
||||
nickname: '',
|
||||
html_url: 'http://choosealicense.com/licenses/apache-2.0/',
|
||||
source_url: '',
|
||||
},
|
||||
})
|
||||
)
|
||||
.expectBadge({
|
||||
label: 'license',
|
||||
message: 'Apache License 2.0',
|
||||
color: unknownLicenseColor,
|
||||
})
|
||||
@@ -31,7 +31,7 @@ export default class JitPackVersion extends BaseJsonService {
|
||||
static defaultBadgeData = { label: 'jitpack' }
|
||||
|
||||
async fetch({ vcs, user, repo }) {
|
||||
const url = `https://jitpack.io/api/builds/com.${vcs}.${user}/${repo}/latest`
|
||||
const url = `https://jitpack.io/api/builds/com.${vcs}.${user}/${repo}/latestOk`
|
||||
|
||||
return this._requestJson({
|
||||
schema,
|
||||
|
||||
@@ -62,7 +62,10 @@ t.create('valid repo -- unregistered')
|
||||
color: COLOR_MAP.unregistered,
|
||||
})
|
||||
|
||||
t.create('invalid repo').get('/github.com/repo/invalid-repo.json').expectBadge({
|
||||
label: 'reuse',
|
||||
message: 'Not a Git repository',
|
||||
})
|
||||
t.create('invalid repo')
|
||||
.timeout(10000)
|
||||
.get('/github.com/repo/invalid-repo.json')
|
||||
.expectBadge({
|
||||
label: 'reuse',
|
||||
message: 'Not a Git repository',
|
||||
})
|
||||
|
||||
@@ -31,7 +31,7 @@ export default class SpackVersion extends BaseJsonService {
|
||||
async fetch({ packageName }) {
|
||||
return this._requestJson({
|
||||
schema,
|
||||
url: `https://spack.github.io/packages/data/packages/${packageName}.json`,
|
||||
url: `https://packages.spack.io/data/packages/${packageName}.json`,
|
||||
errorMessages: {
|
||||
404: 'package not found',
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user